Expand description
Reflection-based helpers for dear-imgui-rs.
This crate provides traits, derive macros, and helpers to automatically generate Dear ImGui widgets for your Rust types, in the spirit of the C++ ImReflect library.
At a high level:
- derive
ImGuiReflectfor your structs/enums; - call
inputorImGuiReflectExt::input_reflecteach frame to render an editor for a value; - optionally customize container / numeric behavior via
ReflectSettingsandMemberSettings; - optionally collect structural change events with
input_with_response.
The goal is to let you build “data inspector” style UIs quickly without hand-writing widgets for every field.
§Quick start
Derive ImGuiReflect for your type and use input_reflect:
use dear_imgui_reflect as reflect;
use reflect::ImGuiReflectExt;
#[derive(reflect::ImGuiReflect, Default)]
struct Player {
#[imgui(slider, min = 0.0, max = 100.0)]
health: f32,
#[imgui(multiline, lines = 3)]
notes: String,
inventory: Vec<String>,
}
fn draw_ui(ui: &reflect::imgui::Ui, player: &mut Player) {
// Returns true if any field changed this frame.
if ui.input_reflect("Player", player) {
// React to edits (save, mark dirty, etc).
}
}§Supported patterns (what this crate is good at)
This crate is designed around a few common use cases:
- Configuration panels / settings windows:
derive
ImGuiReflectfor your config structs and callImGuiReflectExt::input_reflecteach frame to build a live editor. - Game/engine inspectors:
derive
ImGuiReflectfor components or resource types, then render inspectors for the currently selected entity/resource inside a docked window. - Collection-heavy UIs:
use the built-in support for
Vec<T>,[T; N],Option<T>,HashMap<String, V>andBTreeMap<String, V>to build list views, property bags and key/value editors with insertion/removal/reordering. - Tooling and data browsers:
combine
input_with_responseandReflectResponseto track when items are inserted/removed/reordered, and synchronize those changes back into your engine or persistence layer. - Math-heavy editors:
enable the
glamormintfeatures to edit vector, quaternion and matrix types using familiar ImGuiinput_float*widgets.
The derive macro understands a subset of field attributes inspired by ImReflect, such as:
#[imgui(skip)]– do not generate any UI for this field;#[imgui(name = "Custom Label")]– override the field label;- numeric helpers like
#[imgui(slider, min = 0.0, max = 1.0, format = "%.2f")],#[imgui(as_drag, speed = 0.1)],#[imgui(as_input, step = 1)]; - text helpers like
#[imgui(multiline, lines = 4, hint = "Search...")],#[imgui(read_only)],#[imgui(display_only)]; - tuple layout helpers such as
#[imgui(tuple_render = "grid", tuple_columns = 3)].
See the documentation on the re-exported [ImGuiReflect derive macro]
for the full list of supported attributes and validation rules.
§Settings and per-field overrides
The global ReflectSettings object controls how generic containers
are rendered (for example, whether Vec<T> is insertable/reorderable, or
how numeric sliders behave). You can adjust it at startup:
use dear_imgui_reflect as reflect;
fn configure_reflect() {
reflect::with_settings(|s| {
// Make all Vec<T> non-reorderable by default.
s.vec_mut().reorderable = false;
// Use a 0..1 slider for all f32 values by default.
let f32_settings = s.numerics_f32().clone().slider_0_to_1(2); // "%.2f"
*s.numerics_f32_mut() = f32_settings;
});
}For finer control, MemberSettings lets you override behavior for a
specific field, identified by type and field name:
#[derive(reflect::ImGuiReflect)]
struct Settings {
weights: Vec<f32>,
}
fn configure_per_field() {
reflect::with_settings(|s| {
// For Settings::weights, allow reordering only.
s.for_member::<Settings>("weights")
.vec_reorder_only()
.numerics_f32_slider_0_to_1(3);
});
}The with_settings_scope helper lets you temporarily override global
settings for a single panel or widget subtree and automatically restore
the previous configuration afterwards.
§Collecting structural change events
The input and ImGuiReflectExt::input_reflect helpers return a
simple bool indicating whether any field changed. If you also want to
react to container-structure changes (insert/remove/reorder/rename), use
input_with_response and inspect the resulting ReflectResponse:
use dear_imgui_reflect as reflect;
#[derive(reflect::ImGuiReflect, Default)]
struct AppState {
tags: Vec<String>,
}
fn draw_tags(ui: &reflect::imgui::Ui, state: &mut AppState) {
let mut resp = reflect::ReflectResponse::default();
let _changed = reflect::input_with_response(ui, "Tags", state, &mut resp);
for event in resp.events() {
match event {
reflect::ReflectEvent::VecInserted { path, index } => {
// path is "tags" when generated via the derive macro.
println!("Inserted element at {index} in {:?}", path);
}
_ => {}
}
}
}§Math integrations
When the glam feature is enabled, this crate implements ImGuiValue
for glam::Vec2/Vec3/Vec4, glam::Quat, and glam::Mat4, using the
corresponding input_float* widgets for inspection and editing.
When the mint feature is enabled, mint::Vector2/Vector3/Vector4<f32>
are also editable via input_float* controls. This is useful when your
engine uses mint as a math interop layer.
§Example: simple inspector-style UI
The following example shows how you might use dear-imgui-reflect to
build a small “inspector” for a list of game entities. Each entity is a
struct with nested fields, and the inspector lets you select an entity
from a list and edit its properties in place:
use dear_imgui_reflect as reflect;
use reflect::ImGuiReflectExt;
#[derive(reflect::ImGuiReflect, Default)]
struct Transform {
#[imgui(tuple_render = "grid", tuple_columns = 3)]
position: (f32, f32, f32),
#[imgui(tuple_render = "grid", tuple_columns = 3)]
rotation_euler: (f32, f32, f32),
#[imgui(slider, min = 0.1, max = 10.0)]
uniform_scale: f32,
}
#[derive(reflect::ImGuiReflect, Default)]
struct Enemy {
#[imgui(name = "Name")]
name: String,
#[imgui(slider, min = 0, max = 100)]
health: i32,
#[imgui(slider, min = 0.0, max = 1.0)]
aggression: f32,
#[imgui(name = "Waypoints")]
patrol_points: Vec<(f32, f32)>,
transform: Transform,
}
#[derive(Default)]
struct EnemyInspector {
enemies: Vec<Enemy>,
selected: usize,
}
impl EnemyInspector {
fn ui(&mut self, ui: &reflect::imgui::Ui) {
ui.window("Enemies").build(|| {
// Left side: list of enemies with selection.
ui.child_window("EnemyList")
.size([200.0, 0.0])
.build(ui, || {
for (i, enemy) in self.enemies.iter().enumerate() {
let label = format!("{i}: {}", enemy.name);
if ui.selectable_config(&label)
.selected(self.selected == i)
.build()
{
self.selected = i;
}
}
});
ui.same_line();
// Right side: reflected editor for the selected enemy.
ui.child_window("EnemyInspector")
.size([0.0, 0.0])
.build(ui, || {
if let Some(enemy) = self.enemies.get_mut(self.selected) {
ui.input_reflect("Enemy", enemy);
} else {
ui.text("No enemy selected");
}
});
});
}
}This pattern generalizes well to component-based engines, material
editors, and other data-driven UIs: derive ImGuiReflect for the
types you care about, then compose editors using input_reflect inside
whatever layout best fits your application.
Re-exports§
pub use dear_imgui_rs as imgui;
Structs§
- Array
Settings - Settings controlling how fixed-size arrays like
[T; N]are edited. - Bool
Settings - Settings controlling how
boolfields are edited when no per-field attributes are provided. - MapSettings
- Settings controlling how string-keyed maps like
HashMap<String, V>andBTreeMap<String, V>are edited. - Member
Settings - Per-member override settings layered on top of global
ReflectSettings. - Numeric
Type Settings - Type-level settings controlling how a particular numeric primitive type is rendered.
- Reflect
Response - High-level response information collected during a reflection-driven UI pass.
- Reflect
Settings - Settings that control how certain types are rendered by
dear-imgui-reflect. - Tuple
Settings - Settings controlling how tuple-like values such as
(A, B)and(A, B, C)are rendered. - VecSettings
- Settings controlling how
Vec<T>containers are edited.
Enums§
- Bool
Style - Preferred widget style for boolean fields.
- Numeric
Range - Range configuration for numeric sliders and drags.
- Numeric
Widget Kind - Preferred widget style for numeric fields of a given primitive type.
- Reflect
Event - A single structural change observed while rendering reflected UI.
- Tuple
Render Mode - Preferred render mode for tuple-like values.
Traits§
- ImGui
Reflect - Trait for complex types (structs/enums) that can generate ImGui controls for all of their fields.
- ImGui
Reflect Ext - Extension methods on
Uifor reflection-based widgets. - ImGui
Value - Trait for values that can render themselves as a single ImGui input widget.
- Numeric
Default Range - Trait providing a default numeric range for slider widgets when no explicit
min/maxare given.
Functions§
- current_
settings - Returns a clone of the current global
ReflectSettings. - imgui_
array_ with_ settings - Public helper for rendering fixed-size arrays using explicit
ArraySettings. - imgui_
btree_ map_ with_ settings - Public helper for rendering
BTreeMap<String, V>using explicitMapSettings. - imgui_
hash_ map_ with_ settings - Public helper for rendering
HashMap<String, V, S>using explicitMapSettings. - imgui_
tuple_ body - Tuple and pair-style values rendered in line or grid mode.
- imgui_
vec_ with_ settings - Public helper for rendering
Vec<T>using explicitVecSettings. - input
- Render ImGui controls for a value that implements
ImGuiReflect. - input_
with_ response - Variant of
inputthat additionally collects container-level change events into the providedReflectResponse. - with_
settings - Mutates the global
ReflectSettingsin place. - with_
settings_ scope - Executes a closure with a temporary modification of the global
ReflectSettings, restoring the previous settings afterwards.
Derive Macros§
- ImGui
Reflect - Derive macro for
ImGuiReflect, re-exported for convenience.