You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
Emil Ernerfeldt b7d1584f44 Simplify how fonts are defined in FontDefinitions 4 years ago
.github/workflows egui_web: Implement copy, cut and paste 4 years ago
demo_glium actually take path for `FileStorage::from_path` 4 years ago
demo_web Add `example_web` app 4 years ago
docs [egui_web] Update demo and example wasm 4 years ago
egui Simplify how fonts are defined in FontDefinitions 4 years ago
egui_glium Allow user to check for Key::Space 4 years ago
egui_web Allow user to check for Key::Space 4 years ago
example_glium actually take path for `FileStorage::from_path` 4 years ago
example_web cargo update 4 years ago
media New example code 4 years ago
.gitignore Add /.vscode and /.*.json to .gitignore 4 years ago
CHANGELOG.md Simplify how fonts are defined in FontDefinitions 4 years ago
Cargo.lock cargo update 4 years ago
Cargo.toml Add `example_web` app 4 years ago
LICENSE-APACHE [license] licence under MIT or Apache-2.0 5 years ago
LICENSE-MIT [license] licence under MIT or Apache-2.0 5 years ago
README.md Add a second emoji font: emoji-icon-font 4 years ago
TODO.md Update CHANGELOG.md and TODO.md 4 years ago
build_demo_web.sh egui_web: Add simple fetch API and demostrate it in example_web 4 years ago
build_example_web.sh Add `example_web` app 4 years ago
build_glium.sh fix build_glium.sh 4 years ago
check.sh Add `example_web` app 4 years ago
lint.sh No typescript. Just one index.html + wasm. 6 years ago
start_server.sh Update wasm/web example 5 years ago

README.md

Egui

Latest version Documentation unsafe forbidden dependency status Build Status MIT Apache

Highly portable immediate mode GUI library for Rust.

Simple, fast, work in progress

Made for games or for anyone who want to make their own GUI and share it easily on a web page or compile it natively.

Egui can be used anywhere you can draw textured triangles.

Sections:

Demo

Click to run Egui web demo. Partial demo source: https://github.com/emilk/egui/blob/master/egui/src/demos/app.rs

Hobogo: A small game I made using Egui. Source: https://github.com/emilk/hobogo

Example

ui.heading("My Egui Application");
ui.horizontal(|ui| {
    ui.label("Your name: ");
    ui.text_edit(&mut name);
});
ui.add(egui::Slider::u32(&mut age, 0..=120).text("age"));
if ui.button("Click each year").clicked {
    age += 1;
}
ui.label(format!("Hello '{}', age {}", name, age));

Goals

  • API: Simple and convenient (e.g. no lifetime arguments for Ui).
  • Responsive: target 60 Hz in debug build
  • Friendly: difficult to make mistakes
  • Portable: the same code works on the web and as a native app
  • Easy to integrate into any environment
  • A simple 2D graphics API for custom painting
  • No callbacks
  • Pure immediate mode
  • Extensible: easy to write your own widgets for Egui
  • Modular: You should be able to use small parts of Egui and combine them in new ways
  • Safe: there is no unsafe code in Egui
  • Minimal dependencies

Egui is not a framework. Egui is a library you call into, not an environment you program for.

NOTE: Egui does not claim to have reached all these goals yet! Egui is still work in progress.

Why Egui?

Egui is written for Rust game engines. 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 stable that doesn't break when you upgrade it, Egui isn't for you (yet).

But if you are writing something interactive in Rust that needs a simple GUI, Egui may be for you.

The obvious alternative to Egui is imgui-rs, the Rust wrapper around the C++ library Dear ImGui. Dear ImGui is a great library, which a lot more features and polish compared to Egui. However, Egui provides some benefits for Rust users:

  • Egui is pure Rust
  • Egui is easily compiled to WASM
  • Egui lets you use native Rust String types (imgui-rs forces you to use annoying macros and wrappers for zero-terminated strings)
  • Writing your own widgets in Egui is simple

Egui also tries to improve your experience in other small ways:

  • Windows are automatically sized based on their contents
  • Windows are automatically positioned to not overlap with each other
  • Some subtle animations make Egui come alive

So in summary:

  • Egui: pure Rust, new, exciting, work in progress
  • Dear ImGui: feature rich, well tested, cumbersome Rust integration

State

Alpha state. 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.

Features

  • Widgets: label, text button, hyperlink, checkbox, radio button, slider, draggable value, text editing, combo box, color picker
  • Layouts: horizontal, vertical, columns
  • Text input: very basic, multiline, copy/paste
  • Windows: move, resize, name, minimize and close. Automatically sized and positioned.
  • Regions: resizing, vertical scrolling, collapsing headers (sections)
  • Rendering: Anti-aliased rendering of lines, circles, text and convex polygons.
  • Tooltips on hover

How it works

Loop:

  • Gather input (mouse, touches, keyboard, screen size, etc) and give it to Egui
  • Run application code (Immediate Mode GUI)
  • Tell Egui to tesselate the frame graphics to a triangle mesh
  • Render the triangle mesh with your favorite graphics API (see OpenGL example)

Integrations

Egui is build to be easy to integrate into any existing game engine or platform you are working on. 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. The integration needs to do two things:

  • IO: Supply Egui with input (mouse position, keyboard presses, ...) and handle Egui output (cursor changes, copy-paste integration, ...).
  • Painting: Render the textured triangles that Egui outputs.

Official

I maintain two official Egui integrations:

The same code can be compiled to a native app or a web app.

3rd party

Writing your own Egui integration

You need to collect egui::RawInput, paint egui::PaintJobs and handle egui::Output. The basic structure is this:

let mut egui_ctx = egui::Context::new();

// Game loop:
loop {
    let raw_input: egui::RawInput = my_integration.gather_input();
    egui_ctx.begin_frame(raw_input);
    my_app.ui(&mut egui_ctx); // add panels, windows and widgets to `egui_ctx` here
    let (output, paint_commands) = egui_ctx.end_frame();
    let paint_jobs = self.ctx.tesselate(paint_commands); // create triangles to paint
    my_integration.paint(paint_jobs);
    my_integration.set_cursor_icon(output.cursor_icon);
    // Also see `egui::Output` for more
}

For a reference OpenGL backend, see the egui_glium painter.

Debugging your integration

My text is blurry

  • Make sure you set the proper pixels_per_point in the input to Egui.
  • Make sure the texture sampler is not off by half a pixel. Try nearest-neighbor sampler to check.

My windows are too transparent or too dark

  • Make sure your texture sampler is clamped.
  • Make sure you consider sRGB (gamma) in your shaders.
  • Egui uses premultiplied alpha, so make sure your blending function is (ONE, ONE_MINUS_SRC_ALPHA)

Other

Conventions and design choices

All coordinates are in screen space coordinates, with (0, 0) in the top left corner

All coordinates are in locial "points" which may consist of many physical pixels.

All colors have premultiplied alpha.

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");.

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.

Inspiration

The one and only Dear 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.

Name

The name of the library and the project is "Egui" and pronounced as "e-gooey".

The library was originally called "Emigui", but was renamed to Egui in 2020.

Credits / Licenses

Egui author: Emil Ernerfeldt

Egui is under MIT OR Apache-2.0 license.

Fonts: