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/segmented-control/root_view.rs
1use strato_ui::color::ColorU;
2use strato_ui::elements::{
3 Align, Container, CornerRadius, CrossAxisAlignment, Fill, Flex, ParentElement, Radius, Text,
4};
5use strato_ui::fonts::FamilyId;
6use strato_ui::presenter::ChildView;
7use strato_ui::ui_components::components::{Coords, UiComponentStyles};
8use strato_ui::ui_components::segmented_control::{
9 LabelConfig, RenderableOptionConfig, SegmentedControl, SegmentedControlEvent,
10};
11use strato_ui::SingletonEntity as _;
12use strato_ui::{AppContext, Element, Entity, TypedActionView, View, ViewContext, ViewHandle};
13 
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum DisplayMode {
16 Rendered,
17 Raw,
18}
19 
20pub struct RootView {
21 font_family: FamilyId,
22 segmented_control: ViewHandle<SegmentedControl<DisplayMode>>,
23 selected_mode: DisplayMode,
24}
25 
26impl RootView {
27 pub fn new(ctx: &mut ViewContext<Self>) -> Self {
28 let font_family = strato_ui::fonts::Cache::handle(ctx)
29 .update(ctx, |cache, _| cache.load_system_font("Arial").unwrap());
30 
31 let segmented_control = ctx.add_typed_action_view(move |_ctx| {
32 SegmentedControl::new(
33 vec![DisplayMode::Rendered, DisplayMode::Raw],
34 move |mode, is_selected, _app| {
35 Some(RenderableOptionConfig {
36 icon_path: "",
37 icon_color: ColorU::white(),
38 label: Some(LabelConfig {
39 label: match mode {
40 DisplayMode::Rendered => "Rendered".into(),
41 DisplayMode::Raw => "Raw".into(),
42 },
43 width_override: Some(55.0),
44 color: if is_selected {
45 ColorU::new(100, 200, 255, 255) // accent color
46 } else {
47 ColorU::white()
48 },
49 }),
50 tooltip: None,
51 background: if is_selected {
52 Fill::Solid(ColorU::new(60, 60, 60, 255)) // surface_3
53 } else {
54 Fill::None
55 },
56 })
57 },
58 DisplayMode::Rendered,
59 segmented_control_styles(font_family),
60 )
61 });
62 
63 ctx.subscribe_to_view(&segmented_control, |me, _, event, ctx| {
64 let SegmentedControlEvent::OptionSelected(mode) = event;
65 me.selected_mode = *mode;
66 ctx.notify();
67 });
68 
69 Self {
70 font_family,
71 segmented_control,
72 selected_mode: DisplayMode::Rendered,
73 }
74 }
75}
76 
77fn segmented_control_styles(font_family: FamilyId) -> UiComponentStyles {
78 UiComponentStyles {
79 font_family_id: Some(font_family),
80 font_size: Some(12.0),
81 border_radius: Some(CornerRadius::with_all(Radius::Pixels(4.0))),
82 border_width: Some(1.0),
83 border_color: Some(Fill::Solid(ColorU::new(60, 60, 60, 255))), // surface_3
84 background: Some(Fill::Solid(ColorU::new(30, 30, 30, 255))), // background
85 height: Some(20.0),
86 padding: Some(Coords::uniform(2.0)),
87 margin: Some(Coords {
88 top: 0.0,
89 bottom: 0.0,
90 left: 0.0,
91 right: 8.0,
92 }),
93 ..Default::default()
94 }
95}
96 
97impl Entity for RootView {
98 type Event = ();
99}
100 
101impl View for RootView {
102 fn ui_name() -> &'static str {
103 "RootView"
104 }
105 
106 fn render(&self, _app: &AppContext) -> Box<dyn Element> {
107 let status_text = format!("Selected: {:?}", self.selected_mode);
108 
109 let content = Flex::column()
110 .with_spacing(20.0)
111 .with_cross_axis_alignment(CrossAxisAlignment::Center)
112 .with_child(
113 Text::new_inline("Segmented Control Example", self.font_family, 20.0)
114 .with_color(ColorU::white())
115 .finish(),
116 )
117 .with_child(ChildView::new(&self.segmented_control).finish())
118 .with_child(
119 Text::new_inline(status_text, self.font_family, 14.0)
120 .with_color(ColorU::new(150, 150, 150, 255))
121 .finish(),
122 )
123 .finish();
124 
125 Container::new(Align::new(content).finish())
126 .with_background_color(ColorU::new(20, 20, 20, 255))
127 .finish()
128 }
129}
130 
131impl TypedActionView for RootView {
132 type Action = ();
133}
134