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
examples/hello_world/src/main.rs
1//! Hello World example for StratoSDK showing state management and modern UI
2use std::sync::{Arc, Mutex};
3use strato_sdk::prelude::*;
4use strato_sdk::strato_core::inspector::{inspector, InspectorConfig};
5use strato_sdk::strato_core::state::Signal;
6use strato_sdk::strato_core::types::Color;
7use strato_sdk::strato_platform::{
8 init::{InitBuilder, InitConfig},
9 ApplicationBuilder, WindowBuilder,
10};
11use strato_sdk::strato_widgets::{
12 layout::{CrossAxisAlignment, MainAxisAlignment},
13 text::TextAlign,
14 Button, Column, Container, InspectorOverlay, Text,
15};
16 
17#[derive(Clone, Debug)]
18struct HelloWorldState {
19 counter: Signal<i32>,
20 message: Signal<String>,
21}
22 
23impl Default for HelloWorldState {
24 fn default() -> Self {
25 Self {
26 counter: Signal::new(0),
27 message: Signal::new("Welcome to StratoSDK!".to_string()),
28 }
29 }
30}
31 
32impl HelloWorldState {
33 fn increment(&mut self) {
34 self.counter.update(|c| *c += 1);
35 let count = self.counter.get();
36 if count == 1 {
37 self.message.set("First click! Keep going!".to_string());
38 } else if count == 5 {
39 self.message
40 .set("You're getting the hang of it!".to_string());
41 } else if count == 10 {
42 self.message.set("Double digits! 🚀".to_string());
43 }
44 }
45}
46 
47fn main() -> anyhow::Result<()> {
48 // Initialize StratoSDK
49 InitBuilder::new()
50 .with_config(InitConfig {
51 enable_logging: true,
52 ..Default::default()
53 })
54 .init_all()?;
55 
56 // Keep the inspector available in all builds so the example showcases live debugging tools.
57 inspector().configure(InspectorConfig {
58 enabled: true,
59 ..Default::default()
60 });
61 
62 println!("Hello World - StratoSDK initialized!");
63 
64 ApplicationBuilder::new()
65 .title("Hello StratoSDK")
66 .window(WindowBuilder::new().with_size(500.0, 400.0).resizable(true))
67 .run(InspectorOverlay::new(build_ui()))
68}
69 
70fn build_ui() -> impl Widget {
71 let state = Arc::new(Mutex::new(HelloWorldState::default()));
72 
73 // Main Window Background
74 Container::new()
75 .background(Color::rgb(0.05, 0.05, 0.05)) // Deep dark background
76 .child(
77 // Center content using Column alignment
78 Column::new()
79 .main_axis_alignment(MainAxisAlignment::Center)
80 .cross_axis_alignment(CrossAxisAlignment::Center)
81 .children(vec![Box::new(create_interaction_card(state))]),
82 )
83}
84 
85fn create_interaction_card(state: Arc<Mutex<HelloWorldState>>) -> impl Widget {
86 let (counter_signal, message_signal) = {
87 let state = state.lock().unwrap();
88 (state.counter.clone(), state.message.clone())
89 };
90 
91 // Card Container
92 Container::new()
93 .background(Color::rgb(0.12, 0.12, 0.12)) // Slightly lighter card
94 .width(350.0)
95 // .border_radius(16.0) // If/when available
96 .padding(30.0)
97 .child(
98 Column::new()
99 .spacing(25.0)
100 .cross_axis_alignment(CrossAxisAlignment::Center) // Center children horizontally
101 .children(vec![
102 // Icon / Logo Placeholder (Circle)
103 // Centering inside a container via Column again if needed, or just container with size
104 Box::new(
105 Container::new()
106 .width(60.0)
107 .height(60.0)
108 .background(Color::rgb(0.25, 0.4, 0.9)), // Accent Blue
109 // .corner_radius(30.0) // Circle
110 ),
111 // Title
112 Box::new(
113 Text::new("Hello, StratoSDK")
114 .size(32.0)
115 .color(Color::WHITE)
116 .align(TextAlign::Center),
117 ),
118 // Dynamic Message
119 Box::new(
120 Text::new("")
121 .bind(message_signal)
122 .size(16.0)
123 .color(Color::rgb(0.7, 0.7, 0.7))
124 .align(TextAlign::Center),
125 ),
126 // Spacer
127 Box::new(Container::new().height(10.0)),
128 // Counter Display
129 Box::new(
130 Text::new("")
131 .bind(counter_signal.map(|c| format!("Clicks: {}", c)))
132 .size(48.0)
133 .color(Color::rgb(0.25, 0.8, 0.4)) // Green accent
134 .align(TextAlign::Center),
135 ),
136 // Interactive Button
137 Box::new(
138 Button::new("Increment Counter").on_click(move || {
139 let mut state = state.lock().unwrap();
140 state.increment();
141 }), // .style(...) // if we had style API on button directly
142 ),
143 ]),
144 )
145}
146