#macro-derive #egui #ui #gui #enums #bindings

enum2egui

enum2egui is a rust derive macro that creates a set of egui ui databindings from arbitrary data structures. Supports egui v0.29.1

19 releases

0.3.9 Oct 21, 2024
0.3.8 Sep 16, 2024
0.3.6 Aug 25, 2024
0.2.0 Feb 26, 2024
0.1.4 Aug 10, 2023

#377 in Data structures

Download history 332/week @ 2024-08-22 77/week @ 2024-08-29 171/week @ 2024-09-05 327/week @ 2024-09-12 67/week @ 2024-09-19 33/week @ 2024-09-26 30/week @ 2024-10-03 25/week @ 2024-10-10 128/week @ 2024-10-17 23/week @ 2024-10-24 21/week @ 2024-10-31 23/week @ 2024-11-07 250/week @ 2024-11-14 277/week @ 2024-11-21 376/week @ 2024-11-28 24/week @ 2024-12-05

932 downloads per month

MIT license

16KB
249 lines

enum2egui

github crates.io docs.rs

enum2egui is a rust derive macro that creates egui UI's from arbitrary structs and enums. This is useful for generating data bindings that can be modified and displayed in an egui ui.

Default and Display are required. enum2str is recommended for deriving Display on enums.

Usage

Add this to your Cargo.toml:

enum2egui = "0.3.9" # supports egui 0.29.1

Example

Declare your data:

use enum2egui::{Gui, GuiInspect};

#[derive(Gui, EnumStr, Debug, Clone, Default, serde::Deserialize, serde::Serialize, PartialEq)]
pub enum Color {
    #[default]
    Red,
    Green,

    #[enum2str("Custom")]
    Custom(u8, u8, u8),

    NamedCustom {
        red: u8,
        blue: u8,
        green: u8,
        metadata: Metadata,
    },

    #[enum2egui(skip)]
    SkippedGreen,

    #[enum2egui(skip)]
    #[enum2str("Skipped Custom")]
    SkippedCustom(u8, u8, u8),

}

#[derive(Gui, Clone, serde::Deserialize, serde::Serialize, Default)]
pub struct Data {
    string: String,
    i8: i8,
    i16: i16,
    i32: i32,
    i64: i64,
    bool: bool,
    u8: u8,
    u16: u16,
    u32: u32,
    f32: f32,
    f64: f64,
    nested_struct: SubData,
    unnamed_struct: TupleStruct,
    primary_color: Color,
    secondary_color: Color,
    optional: Option<SubData>,
}

#[derive(Gui, Clone, serde::Deserialize, serde::Serialize, PartialEq)]
pub struct TupleStruct(u8, u32, String, SubData);

impl Default for TupleStruct {
    fn default() -> Self {
        Self(3, 24, "Hello!".to_string(), SubData::default())
    }
}

#[derive(Gui, Clone, Default, serde::Deserialize, serde::Serialize, PartialEq, Debug)]
pub struct Metadata {
    message: String,
}

#[derive(Gui, Clone, Default, serde::Deserialize, serde::Serialize, PartialEq)]
pub struct SubData {
    value: String,
    number: u32,
}

Then render it with GuiInspect::ui(..) or GuiInspect::ui_mut(). For example, with eframe:

impl eframe::App for DemoApp {
    fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
        let Self { data } = self;

        egui::CentralPanel::default().show(ctx, |ui| {
            // Read-Only UI
            data.ui(ui):

            // Mutable UI
            data.ui_mut(ui);
        });
    }
}

image

Dependencies

~5–11MB
~122K SLoC