11 releases (7 breaking)

0.8.0 Feb 18, 2025
0.7.0 Dec 19, 2024
0.6.0 Oct 14, 2024
0.5.1 Jul 9, 2024
0.2.0 Feb 7, 2024

#947 in Procedural macros

Download history 54/week @ 2024-12-27 102/week @ 2025-01-03 132/week @ 2025-01-10 123/week @ 2025-01-17 244/week @ 2025-01-24 132/week @ 2025-01-31 399/week @ 2025-02-07 244/week @ 2025-02-14 213/week @ 2025-02-21 133/week @ 2025-02-28 147/week @ 2025-03-07 275/week @ 2025-03-14 231/week @ 2025-03-21 497/week @ 2025-03-28 98/week @ 2025-04-04 100/week @ 2025-04-11

950 downloads per month
Used in 3 crates (via egui-probe)

MIT/Apache

30KB
664 lines

Egui Probe

docs.rs Crates.io Total Downloads Discord

Effortlessly create UI widgets to display and modify value types using a derive macro with rich customization via attributes. This library is exclusively for the egui UI framework.

Features

  • 🪄 Derive Macro: Automatically generate UI widgets for your types.
  • 🎨 Rich Customization: Customize the generated widgets using attributes.
  • 🚀 Seamless Integration: Designed to work seamlessly with egui.

Getting Started

Add egui_probe to your Cargo.toml:

[dependencies]
egui_probe = "0.5.2"

Usage

Derive EguiProbe for your types. Use attributes to customize the UI:

Simple Example

#[derive(EguiProbe)]
struct SimpleValue {
    boolean: bool,
    integer: i32,
    float: f32,
}

And this is what you get:

Simple

Advanced Example

struct Foo;

fn custom_probe(_: &mut Foo, ui: &mut egui::Ui, _: &egui_probe::Style) -> egui::Response {
    ui.label("This is custom probe")
}

#[derive(EguiProbe)]
#[egui_probe(transparent)]
struct UpTo7(#[egui_probe(range = ..=7)] u32);

#[derive(EguiProbe)]
#[egui_probe(tags inlined)]
enum InlinedTags {
    Empty,

    #[egui_probe(transparent)]
    InlinedFloat(f32),

    Text {
        #[egui_probe(multiline)]
        text: String,
    },
}

#[derive(EguiProbe)]
#[egui_probe(tags combobox)]
enum ComboBoxTags {
    Empty,

    Num { value: usize },
}

impl Default for ComboBoxTags {
    fn default() -> Self {
        ComboBoxTags::Empty
    }
}

#[derive(Default, EguiProbe)]
#[egui_probe(rename_all = Train-Case)]
struct InnerValue {
    line: String,

    #[egui_probe(multiline)]
    multi_line: String,

    #[cfg(feature = "smallvec1")]
    small_vec_1: smallvec1::SmallVec<[String; 4]>,

    #[cfg(feature = "smallvec2")]
    small_vec_2: smallvec2::SmallVec<f32, 4>,

    #[cfg(feature = "hashbrown")]
    hash_brown: hashbrown::HashMap<u8, f32>,
}

#[derive(EguiProbe)]
struct DemoValue {
    boolean: bool,

    #[egui_probe(toggle_switch)]
    boolean_toggle: bool,

    float: f32,

    #[egui_probe(range = 22..=55)]
    range: usize,

    range_to: UpTo7,

    #[egui_probe(range = 50..)]
    range_from: u8,

    #[egui_probe(as angle)]
    angle: f32,

    #[egui_probe(with custom_probe)]
    custom: Foo,

    #[egui_probe(name = "renamed ^_^")]
    renamed: u8,

    maybe_boolean: Option<bool>,

    inner: InnerValue,

    inlined_tags: InlinedTags,

    option_combobox_tags: Option<ComboBoxTags>,

    array: [u8; 3],

    vector: Vec<bool>,

    #[egui_probe(frozen)]
    frozen_vector: Vec<bool>,

    map: HashMap<String, u32>,

    #[egui_probe(frozen)]
    frozen_map: HashMap<String, u32>,
}

And this is what you get:

Demo

Attributes

Type Attributes

  • #[egui_probe(rename_all = kebab-case)]: Changes default name of all fields into specified case. Available cases are:

    • snake_case
    • camelCase
    • kebab-case
    • PascalCase
    • SCREAMING_SNAKE_CASE or UPPER_SNAKE_CASE
    • Train-Case
  • #[egui_probe(where TypeA: TraitB)]: Adds where clause to the EguiProbe implementation. Predicates follow Rust syntax.

  • #[egui_probe(transparent)]: Renders entire type as its only field. Won't compile if the type doesn't have exactly one non-skipped field.

  • #[egui_probe(tags kind)]: Controls how enum variants are rendered. If kind is combobox, a combobox is used to select the variant. If kind is inlined, the variant is rendered inline using radio buttons.

Variant Attributes

  • #[egui_probe(name = "custom name")]: Rename the variant in the UI.
  • #[egui_probe(transparent)]: Renders the variant as its only field. Won't compile if the variant doesn't have exactly one non-skipped field.

Field Attributes

  • #[egui_probe(skip)]: Skip the field in the UI. No other attributes should be used with this attribute.

  • #[egui_probe(name = "custom name")]: Rename the field in the UI.

  • #[egui_probe(with probe_fn)]: Render a filed using specified probe function with signature fn(&mut FieldType, &mut Ui, &egui_probe::Style) -> egui::Response. Node that probe_fn can be an expression, so closure can be used.

  • #[egui_probe(as probe_fn)]: Render a filed using specified probe function with signature fn(&mut FieldType) -> impl EguiProbe. i.e. wrapping the field into type that implements EguiProbe.

  • #[egui_probe(range = 22..=55)]: Specify a range for numeric values. Works on optionals too.

  • #[egui_probe(multiline)]: Render a string as a multiline text box. Field must be of type String or &str. Or an option of those.

  • #[egui_probe(toggle_switch)]: Render a boolean as a toggle switch. Field must be of type bool or an optional of bool.

  • #[egui_probe(frozen)]: Renders a collection without controls to add or remove elements.

  • #[egui_probe(rgb)]: Render opaque color picker in RGB space. Field must be of type egui::Color32, egui::Rgba, [u8; 3] or [f32; 3].

  • #[egui_probe(rgba)]: Render color picker in RGB space with alpha. Field must be of type egui::Color32, egui::Rgba.

  • #[egui_probe(rgba_premultiplied)]: Render color picker in RGB space with premultiplied alpha. For egui::Color32 and egui::Rgba it is the same as #[egui_probe(rgba)]. But it can be used on [u8; 4] and [f32; 4].

  • #[egui_probe(rgba_unmultiplied)]: Render color picker in RGB space with unmultiplied alpha. It can't be used with egui::Color32 and egui::Rgba, as those are always premultiplied. But it can be used on [u8; 4] and [f32; 4].

License

This project is licensed under either of

  • MIT License
  • Apache License, Version 2.0

at your option.

Contributing

Contributions are welcome! Please open an issue or submit a pull request.

Enjoy building your UI with Egui Probe! 🚀

Dependencies

~0.7–1.1MB
~22K SLoC