An egui backend for godot-rust

Overview

Godot Egui

Latest version Documentation MIT

An egui backend for godot-rust.

Animated gif showcasing godot-egui

Rationale

Godot has a perfectly valid GUI system, so why egui? Here are my personal reasons:

  • Simplicity: No need to connect signals or manage complex scene graphs with dozens of tiny inter-related scripts. GUI logic is centralized. Everything is always up-to-date.
  • Better defaults: It currently takes a lot of effort to create a visually consistent UI theme for Godot (margins, font sizes, colors...). In contrast, egui's widgets only rely on a small set of themable properties.
  • Customizability: Creating new widgets with egui is far more simple.
  • Data driven: The immediate-mode paradigm fits a data-driven style of development: Your data is the source of truth, and the GUI is derived from it by navigating and updating the data itself.
  • IDE Support: Rust has excellent IDE support. Static typing helps you ensure your data model and their associated GUIs always stay in sync.

Usage

These are minimal usage instructions. See the example project in ./example_project/ for a more advanced project.

First, import the godot_egui crate as a library in your project.

Cargo.toml

[dependencies]
# ...
godot_egui = "0.1.1"

Next, register the custom Godot classes declared in godot_egui:

Somewhere in your lib.rs

fn init(handle: InitHandle) {
    godot_egui::register_classes(handle);
}

godot_init!(init);

You will also need to create a .gdns script and attach it to a Control-derived node.

GodotEgui.gdns

[gd_resource type="NativeScript" load_steps=2 format=2]

[ext_resource path="res://godot_egui.gdnlib" type="GDNativeLibrary" id=1]

[resource]
resource_name = "GodotEgui"
class_name = "GodotEgui"
library = ExtResource( 1 )

Finally, get a reference to that node as a RefInstance<GodotEgui, Shared> in your code and do this to draw the GUI using:

let gui : RefInstance<GodotEgui, Shared> = ...;
gui.map_mut(|gui, instance| {
    gui.update(instance, None, |ui| {
        ui.label("Hello world!");
    });
})

The draw code needs to be run constantly, so you should call it from a _process callback or similar.

Running the example

Should be as simple as:

  1. Run cargo build
  2. Open `./example_project/ with the Godot Editor
  3. Hit play

Custom Fonts

Egui supports setting custom fonts out of the box:

Additionally, godot-egui supports registering custom fonts by directly from the Godot editor by exposing several script properties. Panel showcasing custom fonts

The fonts will be loaded into the egui::FontFamily::Proportional family in order. If you don't want egui's default fonts, the override_default_fonts boolean can be set so that only Custom fonts get loaded.

Maturity

The project is in a very early release stage. Breaking changes may occur, but only when absolutely necessary.

Use cases

This integration is being used in my own project, The Process.

If you use this library and enjoy it, please feel free to submit a PR and I will add it to the list!

Roadmap / TODO list

  • Initial integration and testing
  • Release on crates.io
  • Expose a GDScript API so this is useful even without godot-rust
Comments
  • Fixed `_input` being falsely detected when a Godot GUI element is on top of the other element.

    Fixed `_input` being falsely detected when a Godot GUI element is on top of the other element.

    This PR closes #7

    A note about the changes. As you noted in #7 the correct place to put the input is _gui_input as that respects the input propagation and resolves the issue when multiple elements are overlapping with one another.

    The one use-case this may break is anyone that expects two overlapping EGUI controls to both accept input will end up with broken behaviors between these UIs. This may break some expectations.

    In addition, it appears that _gui_input() doesn't require matching the mouse position offset from the screen, it seems to get the correct coordinates, so I removed that code. (it still needs to be mapped to egui::Vec2 though.

    Please let me know if you have any questions.

    opened by jacobsky 11
  • Theme editor support

    Theme editor support

    This contains a large number of changes to help integrate themes into Egui as per #5 . Currently it appears to be working but is definitely not ready to be merged.

    I wanted to submit this for feedback so that I can clean it up a bit more. Also, I think I still need to figure out how to switch which font is being used. That isn't in yet, oops.

    opened by jacobsky 10
  • Update master branch dependencies and associated bugfixes

    Update master branch dependencies and associated bugfixes

    Jumped forward to gdnative 0.10.0 thanks to @bromeon 's changes in #32 I also incorporated the necessary changes to work with egui-themes.

    Probably still some more minor things to wrap up before we can do a 0.2.0 release, but any additional testing that folks can do would be greatly appreciated.

    Note: At the time of opening this PR, the egui-theme and egui-stylist crates have not yet been published. I'm going to do that shortly.

    opened by jacobsky 6
  • Theme Support

    Theme Support

    @setzer22 I am creating an issue that we can use to track the idea of adding some theme support to GodotEgui as well as capture our dicussion from Discord in a more formalized way.

    based on capability of using EGUI directly as a tool script, PR #4 I was thinking about how we should proceed to get some kind of unified theming support.

    After spending some more time reviewing the egui styles module, I'm in agreement that it's probably best to not bother with Godot Theme support. It's probably far too much work to work on an abstraction layer.

    As PR #4 indicates that we have the capability to run EGUI directly in the Godot Editor, I think there's very little reason we shouldn't just work on a theme editor using EGUI. In addition to the benefits of not having to do any theme translation between Godot types and egui types, we can also get an active preview of the theme.

    From here, I think it would be useful to just determine some kind of serializable type that can be used to store the theme information such as json, ron, or a .tres (possibly supporting multiple) that contains the relevant EGUI Theme information. Being able to run this inside the editor would be a nice plus for the IDE experience :)

    Based on the above There are a couple of points that I'd like to consider as well.

    I have a few points I'd like to work on settling below.

    1. Theme Serialization/Deserialization (go for a more Rusty or more Godoty method?
    2. How do we want to proceed with creating the theme resource files?
    3. How should this be integrated with the GodotEgui class?
    4. Where should we develop the addon?
      1. Should the addon be included in this repository?
      2. Would it be worth splitting the theme editor off into it's own repository so that we can potentially support more targets than just Godot?
      3. If hosted in this repository should it be included in the main crate or a separate crate?

    Thanks again for getting the EGUI ball rolling!

    opened by jacobsky 6
  • Added the ability to configure pixels_per_point to allow for egui to properly scale the UI

    Added the ability to configure pixels_per_point to allow for egui to properly scale the UI

    This should fix the issue with pixels per point not properly being set by the UI. This allows the individual control nodes to properly scale egui as needed.

    Also made some minor changes to the function call of paint_shapes, since it is already using &mut self, rather than passing the texture into the method, the method queries for it directly.

    Also added some additional widgets to the example to test the mouse position is correct regardless of the pixels_per_point setting.

    Let me know if you have any questions about the changes.

    opened by jacobsky 5
  • Color test

    Color test

    This is the first steps towards resolving #14 I would like to give a chance for folks to give this a test for feedback before I finalize the PR. Any observations based on the color would be greatly appreciated. Also if there's a solution for the current blending issue, any advice would be welcome.

    opened by jacobsky 4
  • Blank windows and WARNING: _prefill_polygon: poly has too many indices to draw, increase batch buffer size

    Blank windows and WARNING: _prefill_polygon: poly has too many indices to draw, increase batch buffer size

    Doing

    Self {
        egui_test: egui_demo_lib::ColorTest::default()
    }
    
    //...
    
    Window::new("Color Test").scroll(true).show(ctx, |ui| {
        self.egui_test.ui(ui, &mut None);
    });
    
    Window::new("Settings").scroll(true).show(ctx, |ui| {
       ctx.settings_ui(ui);
    });
    

    shows a blank window. Clicking the (invisible) checkbox to turn off vertex gradients makes the content visible.

    Possibly a related issue: settings menu turns blank if the following settings are selected: Painting > debug > Coarse culling off, Paint text bounds on, then expand multiple menus.

    documentation 
    opened by derivator 4
  • Update gdnative to 0.10.0

    Update gdnative to 0.10.0

    Hadn't seen that you had already done most of this work here when I started this... Not sending this PR to step on your toes, but since that branch is kinda old and has merge conflicts maybe this can help someone...

    opened by derivator 3
  • Example Project Build Failure

    Example Project Build Failure

    Description

    I've just run rustup update and tried to build the example_project but receive an error on build.

    Error

    godot-egui/example_project on  main [!?] is 📦 v0.1.0 via 🦀 v1.56.1 on ☁️  (ap-southeast-2) 
    ❯ cargo build
       Compiling egui_demo_lib v0.15.0
       Compiling godot_egui v0.1.8 (/Users/rossmurray/dev/egui_test/godot-egui/godot_egui)
    error[E0277]: the trait bound `Arc<Style>: From<egui::style::Style>` is not satisfied
       --> godot_egui/src/lib.rs:230:47
        |
    230 | ...                   self.egui_ctx.set_style(style);
        |                                     ^^^^^^^^^ the trait `From<egui::style::Style>` is not implemented for `Arc<Style>`
        |
        = help: the following implementations were found:
                  <Arc<B> as From<Cow<'a, B>>>
                  <Arc<CStr> as From<&CStr>>
                  <Arc<CStr> as From<CString>>
                  <Arc<OsStr> as From<&OsStr>>
                and 9 others
        = note: required because of the requirements on the impl of `Into<Arc<Style>>` for `egui::style::Style`
    
    error[E0308]: mismatched types
       --> godot_egui/src/lib.rs:231:57
        |
    231 | ...                   self.egui_ctx.set_fonts(font_definitions);
        |                                               ^^^^^^^^^^^^^^^^ expected struct `FontDefinitions`, found struct `epaint::text::fonts::FontDefinitions`
        |
        = note: perhaps two different versions of crate `epaint` are being used?
    
    Some errors have detailed explanations: E0277, E0308.
    For more information about an error, try `rustc --explain E0277`.
    error: could not compile `godot_egui` due to 2 previous errors
    warning: build failed, waiting for other jobs to finish...
    error: build failed
    

    Context

    godot-egui/example_project on  main [!?] is 📦 v0.1.0 via 🦀 v1.56.1 on ☁️  (ap-southeast-2) 
    ❯ rustup show
    Default host: x86_64-apple-darwin
    rustup home:  /Users/rossmurray/.rustup
    
    installed toolchains
    --------------------
    
    stable-x86_64-apple-darwin (default)
    nightly-x86_64-apple-darwin
    1.54.0-x86_64-apple-darwin
    
    installed targets for active toolchain
    --------------------------------------
    
    thumbv7em-none-eabihf
    x86_64-apple-darwin
    
    active toolchain
    ----------------
    
    stable-x86_64-apple-darwin (default)
    rustc 1.56.1 (59eed8a2a 2021-11-01)
    
    godot-egui/example_project on  main [!?] is 📦 v0.1.0 via 🦀 v1.56.1 on ☁️  (ap-southeast-2) took 45s 
    ❯ rustc --version
    rustc 1.56.1 (59eed8a2a 2021-11-01)
    
    godot-egui/example_project on  main [!?] is 📦 v0.1.0 via 🦀 v1.56.1 on ☁️  (ap-southeast-2) 
    ❯ cargo --version
    cargo 1.56.0 (4ed5d137b 2021-10-04)
    

    Fix

    I was able to get it built by bumping the versions of egui and egui_demo_lib in the Cargo.toml:

    [dependencies]
    gdnative = "0.9.3"
    egui = "0.15.0"
    egui_demo_lib = "0.15.0"
    godot_egui = { path = "../godot_egui" }
    

    I was then able to cargo build with only a few deprecation messages received, and the project loaded and ran fine within Godot from that point.

    opened by RossMurr4y 3
  • Extension Traits for Godot

    Extension Traits for Godot

    Added extension traits for Ui to allow for simpler integration with Godot Input/InputMap. The individual extension traits are split up into several extensions so that we don't clutter up the functionality and users can use only the portion of the extensions that they need.

    This closes #23

    opened by jacobsky 3
  • Changes continuous mode to Reactive mode.

    Changes continuous mode to Reactive mode.

    After discussion, ensuring that continuous update is the default is more intuitive for getting started.

    This only changes the default behavior and the general semantics. Continuous is now the default with Reactive mode being opt in.

    The semantics makes it obvious that under normal circumstances godot-egui will update every frame like an immediate mode gui would be expected.

    opened by jacobsky 3
  • Ensure fonts are loaded after _ready by triggering an empty update.

    Ensure fonts are loaded after _ready by triggering an empty update.

    Egui only builds fonts at the start of the next frame, so if the theme is loaded on _ready, the font texture won't be updated until the first GodotEgui::update, which means that a GUI that draws their first frame after some time (e.g. when a menu is first shown) will cause a noticeable hiccup.

    This would also cause issues if you want to add some extra fonts after loading a theme. After calling _ready on a GodotEgui object, trying to access egui.fonts().definitions() would return the old value, not the one set by the theme.

    Triggering an empty update takes care of the problem with no noticeable side effects.

    opened by setzer22 4
  • Add a minimal CI

    Add a minimal CI

    Currently there are no CI or Publishing actions. While this is tentatively "fixed", I think it would be worthwhile to investigate and work in a more full featured CI so that we can make sure we understand the health of the project.

    I'm also less likely to miss something silly when merging PRs.

    opened by jacobsky 1
Owner
null
A CLI tool to manage your godot-rust projects

ftw A CLI tool to manage your godot-rust project! Table of contents General Information Setup Usage Contact General Information This is a tool to help

Michael Angelo Calimlim 77 Dec 13, 2022
compare gdnative rust based physics against Godot built-in physics

Godot vs. Rapier Rapier is an open source physics framework written in Rust. This project pits godots built-in physics against Rapier. It uses godot-r

Stephan Dilly 75 Nov 17, 2022
A tool to generate inbetweens for animated sprites, written in godot-rust

Bitmapflow is a tool to help you generate inbetweens for animated sprites. In other words, it makes your animations smoother. It uses optical flow to

null 411 Dec 21, 2022
jlang--godot bridge, built in rust

jlang-rs-gd J is an extremely high-level mathematical notation and programming language. Godot is a game / gui / multimedia engine. jlang-rs-gd lets y

tangentstorm 2 Feb 15, 2022
An artisanally made PSD Importer for Godot, written in Rust

PSD Importer for Godot Speed up your import workflow ✨ An artisanally made PSD Importer for Godot 3.5, written in Rust. ✨ Getting Started | ?? Documen

Bram Dingelstad 4 Jan 26, 2023
GDDB is a superfast in-memory database designed for use in Godot

GDDB GDDB is a superfast in-memory database designed for use in Godot. This database aims to provide an easy frontend to an efficient in-memory databa

Richard Patching 5 Dec 4, 2022
A Godot 3.4 binding for Live2D

godot-cubism A Godot 3.4 binding for cubism-rs which itself is a binding for the native cubism sdk. Usage var factory = load("path_to_your_native_scri

null 16 Dec 23, 2022
A crate for using Bevy with the Godot Engine.

bevy_godot A crate for using Bevy with the Godot Engine. This crate is in active development and is not ready for production use. Features Godot Scene

Abby Bryant 63 Dec 17, 2022
Plugin to generate flowfields from tilemaps in the Godot Engine!

Godot Tilemap Flowfields RTS-Style optimized path-finding for crowds of agents. Built for the Godot game engine, written with performance in mind in R

Arne Winter 18 Jan 10, 2023
A direct ecs to low-level server implementation for Godot 4.1

godot_ecs What if Godot 4.1 and Bevy got married? Well, you'd get one interesting duo of data driven goodness. In Development This crate is not produc

null 5 Oct 6, 2023
A plugin for Egui integration into Bevy

bevy_egui This crate provides a Egui integration for the Bevy game engine. Features: Desktop and web (bevy_webgl2) platforms support Clipboard (web su

Vladyslav Batyrenko 453 Jan 3, 2023
Show puffin profiler flamegraph in-game using egui

Show puffin profiler flamegraph in-game using egui puffin is an instrumentation profiler where you opt-in to profile parts of your code: fn my_functio

Emil Ernerfeldt 44 Jun 3, 2022
3d transformation gizmo built on top of the egui library.

egui-gizmo 3d transformation gizmo built on top of the egui library. Try it out in a web demo Usage let gizmo = Gizmo::new("My gizmo") .view_matri

Urho Laukkarinen 69 Dec 10, 2022
API tool,but egui style and rusty

WEAVER About Weaver is a simple,easy-to-use and cross-platform API tool.Inspired by hoppscotch . It uses the Rust egui GUI library. Features Get,Post

will 14 Dec 11, 2022
Generic and extensible egui widgets to create analog synthesizer-like UI with data-oriented API

egui_cable A generic and extensible data-oriented widget for connecting ports by cables. I create this for the visual programming editor of Hihaheho/D

Ryo Hirayama 44 Dec 30, 2022
Libium is the backend of Ferium. It helps manage Minecraft mods from Modrinth, CurseForge, and Github Releases

Libium Libium is the backend of Ferium. It helps manage Minecraft mods from Modrinth, CurseForge, and Github Releases There are 3 main components in L

Ilesh Thiada 14 Dec 13, 2022
Rust-raytracer - 🔭 A simple ray tracer in Rust 🦀

rust-raytracer An implementation of a very simple raytracer based on Ray Tracing in One Weekend by Peter Shirley in Rust. I used this project to learn

David Singleton 159 Nov 28, 2022
Rust-and-opengl-lessons - Collection of example code for learning OpenGL in Rust

rust-and-opengl-lessons Project requires Rust 1.31 Collection of example code for learning OpenGL in Rust 00 - Setup 01 - Window 02 - OpenGL Context 0

Nerijus Arlauskas 348 Dec 11, 2022
Simple retro game made using Rust bracket-lib by following "Herbert Wolverson's Hands on Rust" book.

Flappy Dragon Code from This program is a result of a tutorial i followed from Herbert Wolverson's Hands-on Rust Effective Learning through 2D Game De

Praneeth Chinthaka Ranasinghe 1 Feb 7, 2022