/ README.md
README.md
  1  # 🖌 egui: an easy-to-use GUI in pure Rust
  2  
  3  [<img alt="github" src="https://img.shields.io/badge/github-emilk/egui-8da0cb?logo=github" height="20">](https://github.com/emilk/egui)
  4  [![Latest version](https://img.shields.io/crates/v/egui.svg)](https://crates.io/crates/egui)
  5  [![Documentation](https://docs.rs/egui/badge.svg)](https://docs.rs/egui)
  6  [![unsafe forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance/)
  7  [![Build Status](https://github.com/emilk/egui/workflows/CI/badge.svg)](https://github.com/emilk/egui/actions?workflow=CI)
  8  [![MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/emilk/egui/blob/master/LICENSE-MIT)
  9  [![Apache](https://img.shields.io/badge/license-Apache-blue.svg)](https://github.com/emilk/egui/blob/master/LICENSE-APACHE)
 10  [![Discord](https://img.shields.io/discord/900275882684477440?label=egui%20discord)](https://discord.gg/JFcEma9bJq)
 11  
 12  👉 [Click to run the web demo](https://www.egui.rs/#demo) 👈
 13  
 14  egui is a simple, fast, and highly portable immediate mode GUI library for Rust. egui runs on the web, natively, and [in your favorite game engine](#integrations) (or will soon).
 15  
 16  egui aims to be the easiest-to-use Rust GUI library, and the simplest way to make a web app in Rust.
 17  
 18  egui can be used anywhere you can draw textured triangles, which means you can easily integrate it into your game engine of choice.
 19  
 20  Sections:
 21  
 22  * [Example](#example)
 23  * [Quick start](#quick-start)
 24  * [Demo](#demo)
 25  * [Goals](#goals)
 26  * [Who is egui for?](#who-is-egui-for)
 27  * [State / features](#state)
 28  * [Integrations](#integrations)
 29  * [Why immediate mode](#why-immediate-mode)
 30  * [FAQ](#faq)
 31  * [Other](#other)
 32  * [Credits](#credits)
 33  
 34  ## Example
 35  
 36  ``` rust
 37  ui.heading("My egui Application");
 38  ui.horizontal(|ui| {
 39      ui.label("Your name: ");
 40      ui.text_edit_singleline(&mut name);
 41  });
 42  ui.add(egui::Slider::new(&mut age, 0..=120).text("age"));
 43  if ui.button("Click each year").clicked() {
 44      age += 1;
 45  }
 46  ui.label(format!("Hello '{}', age {}", name, age));
 47  ```
 48  
 49  <img src="media/demo.gif">
 50  
 51  ## Quick start
 52  
 53  If you just want to write a GUI application in Rust (for the web or for native), go to <https://github.com/emilk/eframe_template/> and follow the instructions there! The official docs are at <https://docs.rs/egui>. For inspiration, check out the [the egui web demo](https://www.egui.rs/#demo) and follow the links in it to its source code. There is also an excellent tutorial video at <https://www.youtube.com/watch?v=NtUkr_z7l84>.
 54  
 55  If you want to integrate egui into an existing engine, go to the [Integrations](#integrations) section.
 56  
 57  If you have questions, use [GitHub Discussions](https://github.com/emilk/egui/discussions). There is also [an egui discord server](https://discord.gg/JFcEma9bJq). If you want to contribute to egui, please read the [Contributing Guidelines](https://github.com/emilk/egui/blob/master/CONTRIBUTING.md).
 58  
 59  ## Demo
 60  
 61  [Click to run egui web demo](https://www.egui.rs/#demo) (works in any browser with WASM and WebGL support). Uses [`egui_web`](https://github.com/emilk/egui/tree/master/egui_web).
 62  
 63  To test the demo app locally, run `cargo run --release -p egui_demo_app`.
 64  
 65  The native backend is [`egui_glow`](https://github.com/emilk/egui/tree/master/egui_glow) (using [`glow`](https://crates.io/crates/glow)) and should work out-of-the-box on Mac and Windows, but on Linux you need to first run:
 66  
 67  `sudo apt-get install libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev libspeechd-dev libxkbcommon-dev libssl-dev`
 68  
 69  On Fedora Rawhide you need to run:
 70  
 71  `dnf install clang clang-devel clang-tools-extra speech-dispatcher-devel libxkbcommon-devel pkg-config openssl-devel libxcb-devel`
 72  
 73  **NOTE**: This is just for the demo app - egui itself is completely platform agnostic!
 74  
 75  ## Goals
 76  
 77  * The easiest to use GUI library
 78  * Responsive: target 60 Hz in debug build
 79  * Friendly: difficult to make mistakes, and shouldn't panic
 80  * Portable: the same code works on the web and as a native app
 81  * Easy to integrate into any environment
 82  * A simple 2D graphics API for custom painting ([`epaint`](https://docs.rs/epaint)).
 83  * No callbacks
 84  * Pure immediate mode
 85  * Extensible: [easy to write your own widgets for egui](https://github.com/emilk/egui/blob/master/egui_demo_lib/src/apps/demo/toggle_switch.rs)
 86  * Modular: You should be able to use small parts of egui and combine them in new ways
 87  * Safe: there is no `unsafe` code in egui
 88  * Minimal dependencies: [`ab_glyph`](https://crates.io/crates/ab_glyph) [`ahash`](https://crates.io/crates/ahash) [`nohash-hasher`](https://crates.io/crates/nohash-hasher) [`parking_lot`](https://crates.io/crates/parking_lot)
 89  
 90  egui is *not* a framework. egui is a library you call into, not an environment you program for.
 91  
 92  **NOTE**: egui does not claim to have reached all these goals yet! egui is still work in progress.
 93  
 94  ### Non-goals
 95  
 96  * Become the most powerful GUI library
 97  * Native looking interface
 98  * Advanced and flexible layouts (that's fundamentally incompatible with immediate mode)
 99  
100  ## Who is egui for?
101  
102  egui aims to be the best choice when you want a simple way to create a GUI, or you want to add a GUI to a game engine.
103  
104  If you are not using Rust, egui is not for you. If you want a GUI that looks native, egui is not for you. If you want something that doesn't break when you upgrade it, egui isn't for you (yet).
105  
106  But if you are writing something interactive in Rust that needs a simple GUI, egui may be for you.
107  
108  ### egui vs Dear ImGui
109  
110  The obvious alternative to egui is [`imgui-rs`](https://github.com/Gekkio/imgui-rs), the Rust wrapper around the C++ library [Dear ImGui](https://github.com/ocornut/imgui). Dear ImGui is a great library (and the main inspiration for egui), with a lot more features and polish. However, egui provides some benefits for Rust users:
111  
112  * egui is pure Rust
113  * egui is easily compiled to WASM
114  * egui lets you use native Rust string types (`imgui-rs` forces you to use annoying macros and wrappers for zero-terminated strings)
115  * [Writing your own widgets in egui is simple](https://github.com/emilk/egui/blob/master/egui_demo_lib/src/apps/demo/toggle_switch.rs)
116  
117  egui also tries to improve your experience in other small ways:
118  
119  * Windows are automatically sized based on their contents
120  * Windows are automatically positioned to not overlap with each other
121  * Some subtle animations make egui come alive
122  
123  So in summary:
124  
125  * egui: pure Rust, new, exciting, work in progress
126  * Dear ImGui: feature rich, well tested, cumbersome Rust integration
127  
128  ## State
129  
130  egui is in active development. It works well for what it does, but it lacks many features and the interfaces are still in flux. New releases will have breaking changes.
131  
132  ### Features
133  
134  * Widgets: label, text button, hyperlink, checkbox, radio button, slider, draggable value, text editing, combo box, color picker
135  * Layouts: horizontal, vertical, columns, automatic wrapping
136  * Text editing: multiline, copy/paste, undo, emoji supports
137  * Windows: move, resize, name, minimize and close. Automatically sized and positioned.
138  * Regions: resizing, vertical scrolling, collapsing headers (sections)
139  * Rendering: Anti-aliased rendering of lines, circles, text and convex polygons.
140  * Tooltips on hover
141  * More
142  
143  <img src="media/widget_gallery.gif" width="50%">
144  
145  Light Theme:
146  
147  <img src="media/light_theme.png" width="50%">
148  
149  ## Integrations
150  
151  egui is built to be easy to integrate into any existing game engine or platform you are working on.
152  egui itself doesn't know or care on what OS it is running or how to render things to the screen - that is the job of the egui integration.
153  
154  An integration needs to do the following each frame:
155  
156  * **Input**: Gather input (mouse, touches, keyboard, screen size, etc) and give it to egui
157  * Run the application code
158  * **Output**: Handle egui output (cursor changes, paste, texture allocations, …)
159  * **Painting**: Render the triangle mesh egui produces (see [OpenGL example](https://github.com/emilk/egui/blob/master/egui_glium/src/painter.rs))
160  
161  ### Official integrations
162  
163  If you're making an app, your best bet is using [`eframe`](https://github.com/emilk/egui/tree/master/eframe), the official egui framework. It lets you write apps that work on both the web and native. `eframe` is just a thin wrapper over `egui_web` and `egui_glow` (see below).
164  
165  These are the official egui integrations:
166  
167  * [`egui_glium`](https://github.com/emilk/egui/tree/master/egui_glium) for compiling native apps with [Glium](https://github.com/glium/glium).
168  * [`egui_glow`](https://github.com/emilk/egui/tree/master/egui_glow) for compiling native apps with [glow](https://github.com/grovesNL/glow).
169  * [`egui_web`](https://github.com/emilk/egui/tree/master/egui_web) for making a web app. Compiles to WASM, renders with WebGL. [Click to run the egui demo](https://www.egui.rs/#demo). Uses `egui_glow`.
170  * [`egui-winit`](https://github.com/emilk/egui/tree/master/egui-winit) for integrating with [winit](https://github.com/rust-windowing/winit). `egui-winit` is used by `egui_glium` and `egui_glow`.
171  
172  ### 3rd party integrations
173  
174  * [`amethyst_egui`](https://github.com/jgraef/amethyst_egui) for [the Amethyst game engine](https://amethyst.rs/).
175  * [`bevy_egui`](https://github.com/mvlabat/bevy_egui) for [the Bevy game engine](https://bevyengine.org/).
176  * [`egui_glfw_gl`](https://github.com/cohaereo/egui_glfw_gl) for [GLFW](https://crates.io/crates/glfw).
177  * [`egui_sdl2_gl`](https://crates.io/crates/egui_sdl2_gl) for [SDL2](https://crates.io/crates/sdl2).
178  * [`egui_vulkano`](https://github.com/derivator/egui_vulkano) for [Vulkano](https://github.com/vulkano-rs/vulkano).
179  * [`egui_wgpu_backend`](https://crates.io/crates/egui_wgpu_backend) for [wgpu](https://crates.io/crates/wgpu) (WebGPU API).
180  * [`egui_winit_vulkano`](https://github.com/hakolao/egui_winit_vulkano) for [Vulkano](https://github.com/vulkano-rs/vulkano).
181  * [`egui-macroquad`](https://github.com/optozorax/egui-macroquad) for [macroquad](https://github.com/not-fl3/macroquad).
182  * [`egui-miniquad`](https://github.com/not-fl3/egui-miniquad) for [Miniquad](https://github.com/not-fl3/miniquad).
183  * [`egui-tetra`](https://crates.io/crates/egui-tetra) for [Tetra](https://crates.io/crates/tetra), a 2D game framework.
184  * [`egui-winit-ash-integration`](https://github.com/MatchaChoco010/egui-winit-ash-integration) for [winit](https://github.com/rust-windowing/winit) and [ash](https://github.com/MaikKlein/ash).
185  * [`fltk-egui`](https://crates.io/crates/fltk-egui) for [fltk-rs](https://github.com/fltk-rs/fltk-rs).
186  * [`ggez-egui`](https://github.com/NemuiSen/ggez-egui) for the [ggez](https://ggez.rs/) game framework.
187  * [`godot-egui`](https://github.com/setzer22/godot-egui) for [godot-rust](https://github.com/godot-rust/godot-rust).
188  * [`nannou_egui`](https://github.com/AlexEne/nannou_egui) for [nannou](https://nannou.cc).
189  * [`smithay-egui`](https://github.com/Smithay/smithay-egui) for [smithay](https://github.com/Smithay/smithay/).
190  
191  Missing an integration for the thing you're working on? Create one, it's easy!
192  
193  ### Writing your own egui integration
194  
195  You need to collect [`egui::RawInput`](https://docs.rs/egui/latest/egui/struct.RawInput.html) and handle [`egui::FullOutput`](https://docs.rs/egui/latest/egui/struct.FullOutput.html). The basic structure is this:
196  
197  ``` rust
198  let mut egui_ctx = egui::CtxRef::default();
199  
200  // Game loop:
201  loop {
202      // Gather input (mouse, touches, keyboard, screen size, etc):
203      let raw_input: egui::RawInput = my_integration.gather_input();
204      let full_output = egui_ctx.run(raw_input, |egui_ctx| {
205          my_app.ui(egui_ctx); // add panels, windows and widgets to `egui_ctx` here
206      });
207      let clipped_primitives = egui_ctx.tessellate(full_output.shapes); // creates triangles to paint
208  
209      my_integration.paint(&full_output.textures_delta, clipped_primitives);
210  
211      let platform_output = full_output.platform_output;
212      my_integration.set_cursor_icon(platform_output.cursor_icon);
213      if !platform_output.copied_text.is_empty() {
214          my_integration.set_clipboard_text(platform_output.copied_text);
215      }
216      // See `egui::FullOutput` and `egui::PlatformOutput` for more
217  }
218  ```
219  
220  For a reference OpenGL backend, see [the `egui_glium` painter](https://github.com/emilk/egui/blob/master/egui_glium/src/painter.rs), [the `egui_glow` painter](https://github.com/emilk/egui/blob/master/egui_glow/src/painter.rs), or [the `egui_web` `WebGL` painter](https://github.com/emilk/egui/blob/master/egui_web/src/webgl2.rs).
221  
222  ### Debugging your integration
223  
224  #### Things look jagged
225  
226  * Turn off backface culling.
227  
228  #### My text is blurry
229  
230  * Make sure you set the proper `pixels_per_point` in the input to egui.
231  * Make sure the texture sampler is not off by half a pixel. Try nearest-neighbor sampler to check.
232  
233  #### My windows are too transparent or too dark
234  
235  * egui uses premultiplied alpha, so make sure your blending function is `(ONE, ONE_MINUS_SRC_ALPHA)`.
236  * Make sure your texture sampler is clamped (`GL_CLAMP_TO_EDGE`).
237  * egui prefers linear color spaces for all blending so:
238    * Use an sRGBA-aware texture if available (e.g. `GL_SRGB8_ALPHA8`).
239      * Otherwise: remember to decode gamma in the fragment shader.
240    * Decode the gamma of the incoming vertex colors in your vertex shader.
241    * Turn on sRGBA/linear framebuffer if available (`GL_FRAMEBUFFER_SRGB`).
242      * Otherwise: gamma-encode the colors before you write them again.
243  
244  
245  ## Why immediate mode
246  
247  `egui` is an [immediate mode GUI library](https://en.wikipedia.org/wiki/Immediate_mode_GUI), as opposed to a *retained mode* GUI library. The difference between retained mode and immediate mode is best illustrated with the example of a button: In a retained GUI you create a button, add it to some UI and install some on-click handler (callback). The button is retained in the UI, and to change the text on it you need to store some sort of reference to it. By contrast, in immediate mode you show the button and interact with it immediately, and you do so every frame (e.g. 60 times per second). This means there is no need for any on-click handler, nor to store any reference to it. In `egui` this looks like this: `if ui.button("Save file").clicked() { save(file); }`.
248  
249  A more detailed description of immediate mode can be found [in the `egui` docs](https://docs.rs/egui/latest/egui/#understanding-immediate-mode).
250  
251  There are advantages and disadvantages to both systems.
252  
253  The short of it is this: immediate mode GUI libraries are easier to use, but less powerful.
254  
255  ### Advantages of immediate mode
256  #### Usability
257  The main advantage of immediate mode is that the application code becomes vastly simpler:
258  
259  * You never need to have any on-click handlers and callbacks that disrupts your code flow.
260  * You don't have to worry about a lingering callback calling something that is gone.
261  * Your GUI code can easily live in a simple function (no need for an object just for the UI).
262  * You don't have to worry about app state and GUI state being out-of-sync (i.e. the GUI showing something outdated), because the GUI isn't storing any state - it is showing the latest state *immediately*.
263  
264  In other words, a whole lot of code, complexity and bugs are gone, and you can focus your time on something more interesting than writing GUI code.
265  
266  ### Disadvantages of immediate mode
267  
268  #### Layout
269  The main disadvantage of immediate mode is it makes layout more difficult. Say you want to show a small dialog window in the center of the screen. To position the window correctly the GUI library must first know the size of it. To know the size of the window the GUI library must first layout the contents of the window. In retained mode this is easy: the GUI library does the window layout, positions the window, then checks for interaction ("was the OK button clicked?").
270  
271  In immediate mode you run into a paradox: to know the size of the window, we must do the layout, but the layout code also checks for interaction ("was the OK button clicked?") and so it needs to know the window position *before* showing the window contents. This means we must decide where to show the window *before* we know its size!
272  
273  This is a fundamental shortcoming of immediate mode GUIs, and any attempt to resolve it comes with its own downsides.
274  
275  One workaround is to store the size and use it the next frame. This produces a frame-delay for the correct layout, producing occasional flickering the first frame something shows up. `egui` does this for some things such as windows and grid layouts.
276  
277  You can also call the layout code twice (once to get the size, once to do the interaction), but that is not only more expensive, it's also complex to implement, and in some cases twice is not enough. `egui` never does this.
278  
279  For "atomic" widgets (e.g. a button) `egui` knows the size before showing it, so centering buttons, labels etc is possible in `egui` without any special workarounds.
280  
281  #### CPU usage
282  Since an immediate mode GUI does a full layout each frame, the layout code needs to be quick. If you have a very complex GUI this can tax the CPU. In particular, having a very large UI in a scroll area (with very long scrollback) can be slow, as the content needs to be layed out each frame.
283  
284  If you design the GUI with this in mind and refrain from huge scroll areas (or only lay out the part that is in view) then the performance hit is generally pretty small. For most cases you can expect `egui` to take up 1-2 ms per frame, but `egui` still has a lot of room for optimization (it's not something I've focused on yet). You can also set up `egui` to only repaint when there is interaction (e.g. mouse movement).
285  
286  If your GUI is highly interactive, then immediate mode may actually be more performant compared to retained mode. Go to any web page and resize the browser window, and you'll notice that the browser is very slow to do the layout and eats a lot of CPU doing it. Resize a window in `egui` by contrast, and you'll get smooth 60 FPS at no extra CPU cost.
287  
288  
289  #### IDs
290  There are some GUI state that you want the GUI library to retain, even in an immediate mode library such as `egui`. This includes position and sizes of windows and how far the user has scrolled in some UI. In these cases you need to provide `egui` with a seed of a unique identifier (unique within the parent UI). For instance: by default `egui` uses the window titles as unique IDs to store window positions. If you want two windows with the same name (or one window with a dynamic name) you must provide some other ID source to `egui` (some unique integer or string).
291  
292  `egui` also needs to track which widget is being interacted with (e.g. which slider is being dragged). `egui` uses unique id:s for this awell, but in this case the IDs are automatically generated, so there is no need for the user to worry about it. In particular, having two buttons with the same name is no problem (this is in contrast with [`Dear ImGui`](https://github.com/ocornut/imgui)).
293  
294  Overall, ID handling is a rare inconvenience, and not a big disadvantage.
295  
296  
297  ## FAQ
298  
299  Also see [GitHub Discussions](https://github.com/emilk/egui/discussions/categories/q-a).
300  
301  ### Can I use `egui` with non-latin characters?
302  Yes! But you need to install your own font (`.ttf` or `.otf`) using `Context::set_fonts`.
303  
304  ### Can I customize the look of egui?
305  Yes! You can customize the colors, spacing, fonts and sizes of everything using `Context::set_style`.
306  
307  Here is an example (from https://github.com/AlexxxRu/TinyPomodoro):
308  
309  <img src="media/pompodoro-skin.png" width="50%">
310  
311  ### How do I use egui with `async`?
312  If you call `.await` in your GUI code, the UI will freeze, with is very bad UX. Instead, keep the GUI thread non-blocking and communicate with any concurrent tasks (`async` tasks or other threads) with something like:
313  * Channels (e.g. [`std::sync::mpsc::channel`](https://doc.rust-lang.org/std/sync/mpsc/fn.channel.html)). Make sure to use [`try_recv`](https://doc.rust-lang.org/std/sync/mpsc/struct.Receiver.html#method.try_recv) so you don't block the gui thread!
314  * `Arc<Mutex<Value>>` (background thread sets a value; GUI thread reads it)
315  * [`poll_promise::Promise`](https://docs.rs/poll-promise) (example: [`eframe/examples/download_image.rs`](https://github.com/emilk/egui/blob/master/eframe/examples/download_image.rs))
316  * [`eventuals::Eventual`](https://docs.rs/eventuals/latest/eventuals/struct.Eventual.html)
317  * [`tokio::sync::watch::channel`](https://docs.rs/tokio/latest/tokio/sync/watch/fn.channel.html)
318  
319  ### What about accessibility, such as screen readers?
320  There is experimental support for a screen reader. In [the web demo](https://www.egui.rs/#demo) you can enable it in the "Backend" tab.
321  
322  Read more at <https://github.com/emilk/egui/issues/167>.
323  
324  ### What is the difference between [egui](https://docs.rs/egui) and [eframe](https://github.com/emilk/egui/tree/master/eframe)?
325  
326  `egui` is a 2D user interface library for laying out and interacting with buttons, sliders, etc.
327  `egui` has no idea if it is running on the web or natively, and does not know how to collect input or show things on screen.
328  That is the job of *the integration* or *backend*.
329  
330  It is common to use `egui` from a game engine (using e.g. [`bevy_egui`](https://docs.rs/bevy_egui)),
331  but you can also use `egui` stand-alone using `eframe`. `eframe` has integration for web and native, and handles input and rendering.
332  The _frame_ in `eframe` stands both for the frame in which your egui app resides and also for "framework" (`frame` is a framework, `egui` is a library).
333  
334  ### How do I render 3D stuff in an egui area?
335  There are multiple ways to combine egui with 3D. The simplest way is to use a 3D library and have egui sit on top of the 3D view. See for instance [`bevy_egui`](https://github.com/mvlabat/bevy_egui) or [`three-d`](https://github.com/asny/three-d).
336  
337  If you want to embed 3D into an egui view there are two options.
338  
339  #### `Shape::Callback`
340  Examples:
341  * <https://github.com/emilk/egui/blob/master/eframe/examples/custom_3d_three-d.rs>
342  * <https://github.com/emilk/egui/blob/master/eframe/examples/custom_3d_glow.rs>
343  
344  `Shape::Callback` will call your code when egui gets painted, to show anything using whatever the background rendering context is. When using [`eframe`](https://github.com/emilk/egui/tree/master/eframe) this will be [`glow`](https://github.com/grovesNL/glow). Other integrations will give you other rendering contexts, if they support `Shape::Callback` at all.
345  
346  #### Render-to-texture
347  You can also render your 3D scene to a texture and display it using [`ui.image(…)`](https://docs.rs/egui/latest/egui/struct.Ui.html#method.image). You first need to convert the native texture to an [`egui::TextureId`](https://docs.rs/egui/latest/egui/enum.TextureId.html), and how to do this depends on the integration you use.
348  
349  Examples:
350  * Using [`egui-miniquad`]( https://github.com/not-fl3/egui-miniquad): https://github.com/not-fl3/egui-miniquad/blob/master/examples/render_to_egui_image.rs
351  * Using [`egui_glium`](https://github.com/emilk/egui/tree/master/egui_glium): <https://github.com/emilk/egui/blob/master/egui_glium/examples/native_texture.rs>.
352  
353  
354  ## Other
355  
356  ### Conventions and design choices
357  
358  All coordinates are in screen space coordinates, with (0, 0) in the top left corner
359  
360  All coordinates are in "points" which may consist of many physical pixels.
361  
362  All colors have premultiplied alpha.
363  
364  egui uses the builder pattern for construction widgets. For instance: `ui.add(Label::new("Hello").text_color(RED));` I am not a big fan of the builder pattern (it is quite verbose both in implementation and in use) but until Rust has named, default arguments it is the best we can do. To alleviate some of the verbosity there are common-case helper functions, like `ui.label("Hello");`.
365  
366  Instead of using matching `begin/end` style function calls (which can be error prone) egui prefers to use `FnOnce` closures passed to a wrapping function. Lambdas are a bit ugly though, so I'd like to find a nicer solution to this. More discussion of this at <https://github.com/emilk/egui/issues/1004#issuecomment-1001650754>.
367  
368  ### Inspiration
369  
370  The one and only [Dear ImGui](https://github.com/ocornut/imgui) is a great Immediate Mode GUI for C++ which works with many backends. That library revolutionized how I think about GUI code and turned GUI programming from something I hated to do to something I now enjoy.
371  
372  ### Name
373  
374  The name of the library and the project is "egui" and pronounced as "e-gooey". Please don't write it as "EGUI".
375  
376  The library was originally called "Emigui", but was renamed to "egui" in 2020.
377  
378  ## Credits
379  
380  egui author and maintainer: Emil Ernerfeldt [(@emilk](https://github.com/emilk)).
381  
382  Notable contributions by:
383  
384  * [@n2](https://github.com/n2): [Mobile web input and IME support](https://github.com/emilk/egui/pull/253).
385  * [@optozorax](https://github.com/optozorax): [Arbitrary widget data storage](https://github.com/emilk/egui/pull/257).
386  * [@quadruple-output](https://github.com/quadruple-output): [Multitouch](https://github.com/emilk/egui/pull/306).
387  * [@EmbersArc](https://github.com/EmbersArc): [Plots](https://github.com/emilk/egui/pulls?q=+is%3Apr+author%3AEmbersArc).
388  * [@AsmPrgmC3](https://github.com/AsmPrgmC3): [Proper sRGBA blending in `egui_web`](https://github.com/emilk/egui/pull/650).
389  * [@AlexApps99](https://github.com/AlexApps99): [`egui_glow`](https://github.com/emilk/egui/pull/685).
390  * [@mankinskin](https://github.com/mankinskin): [Context menus](https://github.com/emilk/egui/pull/543).
391  * [@t18b219k](https://github.com/t18b219k): [Port glow painter to web](https://github.com/emilk/egui/pull/868).
392  * [@danielkeller](https://github.com/danielkeller): [`Context` refactor](https://github.com/emilk/egui/pull/1050).
393  * And [many more](https://github.com/emilk/egui/graphs/contributors?type=a).
394  
395  egui is licensed under [MIT](LICENSE-MIT) OR [Apache-2.0](LICENSE-APACHE).
396  
397  * The flattening algorithm for the cubic bezier curve and quadratic bezier curve is from [lyon_geom](https://docs.rs/lyon_geom/latest/lyon_geom/)
398  
399  Default fonts:
400  
401  * `emoji-icon-font.ttf`: [Copyright (c) 2014 John Slegers](https://github.com/jslegers/emoji-icon-font) , MIT License
402  * `Hack-Regular.ttf`: <https://github.com/source-foundry/Hack>, [MIT Licence](https://github.com/source-foundry/Hack/blob/master/LICENSE.md)
403  * `NotoEmoji-Regular.ttf`: [google.com/get/noto](https://google.com/get/noto), [SIL Open Font License](https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL)
404  * `Ubuntu-Light.ttf` by [Dalton Maag](http://www.daltonmaag.com/): [Ubuntu font licence](https://ubuntu.com/legal/font-licence)