Created
October 15, 2023 01:31
-
-
Save PsichiX/14ecda91a0e5929b8db4860613071d72 to your computer and use it in GitHub Desktop.
RAUI immediate mode - states and effects
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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