Seregon/StratoSDK

StratoSDK is a framework with a declarative approach similar to Flutter/React, written and designed entirely for Rust.

Rust/27.3 KB/No license
crates/strato-ui-renderer/examples/slider/root_view.rs
1use pathfinder_color::ColorU;
2use strato_ui::{
3 elements::{Align, Container},
4 presenter::ChildView,
5 ui_components::{
6 components::{UiComponent, UiComponentStyles},
7 slider::{Slider, SliderStateHandle},
8 },
9 AppContext, Element, Entity, TypedActionView, View, ViewContext, ViewHandle,
10};
11 
12/// Renders a center-aligned slider component against a black background. When the slider is
13/// dragged, the updated value is printed to stdout.
14#[derive(Default)]
15pub struct SliderExample {
16 slider_state: SliderStateHandle,
17}
18 
19impl SliderExample {
20 pub fn new() -> Self {
21 Self {
22 slider_state: Default::default(),
23 }
24 }
25}
26 
27impl View for SliderExample {
28 fn ui_name() -> &'static str {
29 "SliderExample"
30 }
31 
32 fn render(&self, _: &AppContext) -> Box<dyn Element> {
33 Slider::new(self.slider_state.clone())
34 .on_drag(|event_ctx, _app, new_value| {
35 event_ctx.dispatch_typed_action(SliderExampleAction::OnSliderDrag(new_value))
36 })
37 .on_change(|event_ctx, _app, new_value| {
38 event_ctx.dispatch_typed_action(SliderExampleAction::OnSliderValueChange(new_value))
39 })
40 // Set a custom value range.
41 .with_range(0.0..100.)
42 .with_style(UiComponentStyles {
43 width: Some(400.),
44 ..Default::default()
45 })
46 .build()
47 .finish()
48 }
49}
50 
51impl Entity for SliderExample {
52 type Event = ();
53}
54 
55#[derive(Debug)]
56pub enum SliderExampleAction {
57 OnSliderDrag(f32),
58 OnSliderValueChange(f32),
59}
60 
61impl TypedActionView for SliderExample {
62 type Action = SliderExampleAction;
63 
64 fn handle_action(&mut self, action: &Self::Action, ctx: &mut ViewContext<Self>) {
65 match action {
66 SliderExampleAction::OnSliderDrag(new_value) => {
67 println!("Slider dragged: {new_value:?}");
68 ctx.notify();
69 }
70 SliderExampleAction::OnSliderValueChange(new_value) => {
71 println!("Slider dropped: {new_value:?}");
72 ctx.notify();
73 }
74 }
75 }
76}
77 
78/// Create a wrapper view so [`SliderExample`] can be added as a [`TypedActionView`].
79pub struct RootView {
80 slider_example_view: ViewHandle<SliderExample>,
81}
82 
83impl RootView {
84 pub fn new(ctx: &mut ViewContext<Self>) -> Self {
85 let slider_example_view = ctx.add_typed_action_view(|_| SliderExample::new());
86 Self {
87 slider_example_view,
88 }
89 }
90}
91 
92impl Entity for RootView {
93 type Event = ();
94}
95 
96impl View for RootView {
97 fn ui_name() -> &'static str {
98 "RootView"
99 }
100 
101 fn render(&self, _app: &AppContext) -> Box<dyn Element> {
102 Container::new(Align::new(ChildView::new(&self.slider_example_view).finish()).finish())
103 .with_background_color(ColorU::black())
104 .finish()
105 }
106}
107 
108impl TypedActionView for RootView {
109 type Action = ();
110}
111