Skip to content

Instantly share code, notes, and snippets.

@PsichiX
Created October 15, 2023 01:31
Show Gist options
  • Save PsichiX/14ecda91a0e5929b8db4860613071d72 to your computer and use it in GitHub Desktop.
Save PsichiX/14ecda91a0e5929b8db4860613071d72 to your computer and use it in GitHub Desktop.
RAUI immediate mode - states and effects
// Make sure you have seen `immediate_mode` code example first, because this is a continuation of that.
use raui_immediate::{make_widgets, ImmediateContext};
use raui_quick_start::RauiQuickStartBuilder;
const FONT: &str = "./demos/hello-world/resources/verdana.ttf";
mod gui {
use raui_immediate::*;
use raui_immediate_widgets::prelude::*;
pub fn app() {
let props = WrapBoxProps {
margin: 20.0.into(),
fill: true,
};
wrap_box(props, || {
nav_vertical_box((), || {
// `use_state` allows to keep persistent state across
// multiple frames, as long as order of calls and types
// match between frames.
let flag = use_state(|| false);
let mut flag = flag.write().unwrap();
let counter = use_state(|| 0usize);
let counter_mount = counter.clone();
if text_button("Toggle").trigger_start() {
*flag = !*flag;
}
if *flag {
// effects are passed as props, these are callbacks
// that get executed whenever RAUI widget gets mounted,
// unmounted or changed.
// There is also `ImmediateHooks` props that allow to
// apply RAUI hooks to rendered widget, useful for example
// to render effects widget with any custom behavior.
let effects = (
ImmediateOnMount::new(move || {
println!("Mounted!");
*counter_mount.write().unwrap() += 1;
}),
ImmediateOnUnmount::new(|| {
println!("Unmounted!");
}),
);
use_effects(effects, || {
label(format!("Mounted {} times!", *counter.read().unwrap()));
});
}
});
});
}
fn label(text: impl ToString) {
text_box(TextBoxProps {
text: text.to_string(),
font: TextBoxFont {
name: crate::FONT.to_owned(),
size: 32.0,
},
color: Color {
r: 0.0,
g: 0.0,
b: 0.0,
a: 1.0,
},
..Default::default()
});
}
fn text_button(text: &str) -> ImmediateButton {
button(NavItemActive, |state| {
content_box((), || {
image_box(ImageBoxProps::colored(Color {
r: if state.state.selected { 1.0 } else { 0.75 },
g: if state.state.trigger { 1.0 } else { 0.75 },
b: if state.state.context { 1.0 } else { 0.75 },
a: 1.0,
}));
text_box(TextBoxProps {
text: text.to_string(),
font: TextBoxFont {
name: crate::FONT.to_owned(),
size: 32.0,
},
color: Color {
r: 0.0,
g: 0.0,
b: 0.0,
a: 1.0,
},
..Default::default()
});
});
})
}
}
fn main() {
use raui_core::prelude::*;
let context = ImmediateContext::default();
RauiQuickStartBuilder::default()
.window_title("Immediate mode UI".to_owned())
.build()
.unwrap()
.on_update(move |_, ui| {
raui_immediate::reset();
let widgets = make_widgets(&context, || gui::app());
ui.application.apply(
make_widget!(content_box)
.listed_slots(widgets.into_iter())
.into(),
);
true
})
.run()
.unwrap();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment