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/comprehensive_test/src/main.rs
1use strato_core::inspector::{inspector, InspectorConfig};
2use strato_core::types::Color;
3use strato_platform::{application::Application, window::WindowBuilder};
4use strato_widgets::{
5 input::{InputType, TextInput},
6 layout::{CrossAxisAlignment, MainAxisAlignment},
7 text::FontWeight,
8 Button, ButtonStyle, Column, Container, Dropdown, Flex, InspectorOverlay, Row, Text, Widget,
9};
10use tracing::{info, warn};
11use tracing_subscriber::prelude::*;
12 
13// Theme Colors
14fn theme_bg() -> Color {
15 Color::rgba(0.09, 0.09, 0.11, 1.0)
16} // #17171C
17fn theme_surface() -> Color {
18 Color::rgba(0.13, 0.13, 0.16, 1.0)
19} // #212129
20fn theme_surface_hover() -> Color {
21 Color::rgba(0.16, 0.16, 0.20, 1.0)
22} // #292933
23fn theme_accent() -> Color {
24 Color::rgba(0.39, 0.35, 0.88, 1.0)
25} // #6459E1
26fn theme_text_primary() -> Color {
27 Color::rgba(0.95, 0.95, 0.97, 1.0)
28}
29fn theme_text_secondary() -> Color {
30 Color::rgba(0.60, 0.60, 0.65, 1.0)
31}
32const BORDER_RADIUS: f32 = 12.0;
33 
34fn main() -> anyhow::Result<()> {
35 // Setup logging to file
36 let file_appender = tracing_appender::rolling::daily("logs", "comprehensive_test.log");
37 let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender);
38 
39 tracing_subscriber::registry()
40 .with(
41 tracing_subscriber::fmt::layer()
42 .with_writer(non_blocking)
43 .with_ansi(false),
44 )
45 .with(tracing_subscriber::fmt::layer().with_writer(std::io::stdout))
46 .init();
47 
48 info!("Starting Comprehensive Test Example - Revolutionized UI");
49 
50 inspector().configure(InspectorConfig {
51 enabled: true,
52 ..Default::default()
53 });
54 
55 // Create application
56 let window_builder = WindowBuilder::new()
57 .with_title("StratoUI Dashboard")
58 .with_size(1280.0, 900.0)
59 .resizable(true);
60 
61 let mut app = Application::new("StratoUI Dashboard", window_builder);
62 
63 // Create UI structure
64 let main_container = InspectorOverlay::new(
65 Container::new().background(theme_bg()).padding(30.0).child(
66 Column::new()
67 .spacing(30.0)
68 .main_axis_alignment(MainAxisAlignment::Start)
69 .cross_axis_alignment(CrossAxisAlignment::Stretch)
70 .children(vec![
71 create_header(),
72 // Main Content Grid (simulated with Row/Column)
73 Box::new(
74 Row::new()
75 .spacing(30.0)
76 .cross_axis_alignment(CrossAxisAlignment::Start)
77 .children(vec![
78 // Left Column (Interactive)
79 Box::new(Flex::new(create_interactive_section()))
80 as Box<dyn Widget>,
81 // Right Column (Layouts/Cards)
82 Box::new(Flex::new(create_layout_section())) as Box<dyn Widget>,
83 ]),
84 ) as Box<dyn Widget>,
85 ]),
86 ),
87 );
88 
89 app.set_root(Box::new(main_container));
90 
91 info!("Application initialized, entering event loop");
92 app.run()
93}
94 
95fn create_header() -> Box<dyn Widget> {
96 Box::new(
97 Container::new()
98 .background(theme_surface())
99 .padding(25.0)
100 .border_radius(BORDER_RADIUS)
101 .child(
102 Row::new()
103 .main_axis_alignment(MainAxisAlignment::SpaceBetween)
104 .cross_axis_alignment(CrossAxisAlignment::Center)
105 .children(vec![
106 Box::new(Column::new().spacing(5.0).children(vec![
107 Box::new(
108 Text::new("StratoUI Dashboard")
109 .font_size(28.0)
110 .font_weight(FontWeight::Bold)
111 .color(theme_text_primary())
112 ) as Box<dyn Widget>,
113 Box::new(
114 Text::new("Next-gen Rust Native UI Framework")
115 .font_size(14.0)
116 .color(theme_text_secondary())
117 ) as Box<dyn Widget>,
118 ])) as Box<dyn Widget>,
119 Box::new(Row::new().spacing(15.0).children(vec![
120 Box::new(
121 Button::new("Documentation")
122 .outline()
123 .on_click(|| info!("Docs clicked"))
124 ) as Box<dyn Widget>,
125 Box::new(
126 Button::new("New Project")
127 .primary()
128 .on_click(|| info!("New Project clicked"))
129 ) as Box<dyn Widget>,
130 ])) as Box<dyn Widget>,
131 ]),
132 ),
133 )
134}
135 
136fn create_interactive_section() -> Box<dyn Widget> {
137 Box::new(Column::new().spacing(20.0).children(vec![
138 create_section_title("Controls & Inputs"),
139 Container::new()
140 .background(theme_surface())
141 .padding(20.0)
142 .border_radius(BORDER_RADIUS)
143 .child(
144 Column::new()
145 .spacing(25.0)
146 .cross_axis_alignment(CrossAxisAlignment::Stretch)
147 .children(vec![
148 // Buttons Group
149 Box::new(
150 Column::new().spacing(10.0).children(vec![
151 Box::new(
152 Text::new("Buttons")
153 .font_size(14.0)
154 .color(theme_text_secondary()),
155 ) as Box<dyn Widget>,
156 Box::new(
157 Row::new().spacing(10.0).children(vec![
158 Box::new(
159 Flex::new(Box::new(
160 Button::new("Primary").primary(),
161 ))
162 .flex(1.0),
163 )
164 as Box<dyn Widget>,
165 Box::new(
166 Flex::new(Box::new(
167 Button::new("Secondary").secondary(),
168 ))
169 .flex(1.0),
170 )
171 as Box<dyn Widget>,
172 Box::new(
173 Flex::new(Box::new(Button::new("Danger").danger()))
174 .flex(1.0),
175 )
176 as Box<dyn Widget>,
177 ]),
178 ) as Box<dyn Widget>,
179 ]),
180 ) as Box<dyn Widget>,
181 // Dropdown Group
182 Box::new(
183 Column::new().spacing(10.0).children(vec![
184 Box::new(
185 Text::new("Selection")
186 .font_size(14.0)
187 .color(theme_text_secondary()),
188 ) as Box<dyn Widget>,
189 Box::new(
190 Dropdown::new()
191 .add_value("Development".to_string())
192 .add_value("Staging".to_string())
193 .add_value("Production".to_string())
194 .placeholder("Select Environment".to_string()),
195 ) as Box<dyn Widget>,
196 ]),
197 ) as Box<dyn Widget>,
198 // Inputs Group
199 Box::new(
200 Column::new().spacing(15.0).children(vec![
201 Box::new(
202 Text::new("Authentication")
203 .font_size(14.0)
204 .color(theme_text_secondary()),
205 ) as Box<dyn Widget>,
206 Box::new(TextInput::new().placeholder("Username or Email"))
207 as Box<dyn Widget>,
208 Box::new(
209 TextInput::new()
210 .placeholder("Password")
211 .input_type(InputType::Password),
212 ) as Box<dyn Widget>,
213 ]),
214 ) as Box<dyn Widget>,
215 ]),
216 )
217 .into_boxed(),
218 ]))
219}
220 
221fn create_layout_section() -> Box<dyn Widget> {
222 Box::new(Column::new().spacing(20.0).children(vec![
223 create_section_title("Project Status"),
224 // Stats Row
225 Box::new(Row::new().spacing(20.0).children(vec![
226 create_stat_card("Active Users", "12.5k", "+15%", theme_accent()),
227 create_stat_card("Server Load", "42%", "-5%", Color::rgba(0.2, 0.8, 0.4, 1.0)),
228 create_stat_card("Errors", "0.01%", "-2%", Color::rgba(0.9, 0.3, 0.3, 1.0)),
229 ])) as Box<dyn Widget>,
230 // Detailed Cards
231 Box::new(
232 Container::new()
233 .background(theme_surface())
234 .padding(20.0)
235 .border_radius(BORDER_RADIUS)
236 .child(
237 Column::new().spacing(15.0).children(vec![
238 Box::new(
239 Text::new("Recent Activity")
240 .font_size(16.0)
241 .font_weight(FontWeight::SemiBold)
242 .color(theme_text_primary()),
243 ) as Box<dyn Widget>,
244 create_activity_item("Deployment #1024", "Successful", "2 mins ago"),
245 create_activity_item("Database Backup", "Processing", "15 mins ago"),
246 create_activity_item("User Registration", "New User", "1 hour ago"),
247 ]),
248 ),
249 ) as Box<dyn Widget>,
250 ]))
251}
252 
253fn create_section_title(title: &str) -> Box<dyn Widget> {
254 Box::new(
255 Text::new(title)
256 .font_size(18.0)
257 .font_weight(FontWeight::SemiBold)
258 .color(theme_text_primary()),
259 )
260}
261 
262fn create_stat_card(label: &str, value: &str, trend: &str, trend_color: Color) -> Box<dyn Widget> {
263 Box::new(Flex::new(Box::new(
264 Container::new()
265 .background(theme_surface())
266 .padding(20.0)
267 .border_radius(BORDER_RADIUS)
268 .child(Column::new().spacing(10.0).children(vec![
269 Box::new(
270 Text::new(label)
271 .font_size(14.0)
272 .color(theme_text_secondary()),
273 ) as Box<dyn Widget>,
274 Box::new(
275 Text::new(value)
276 .font_size(24.0)
277 .font_weight(FontWeight::Bold)
278 .color(theme_text_primary()),
279 ) as Box<dyn Widget>,
280 Box::new(Text::new(trend).font_size(12.0).color(trend_color))
281 as Box<dyn Widget>,
282 ])),
283 )))
284}
285 
286fn create_activity_item(title: &str, status: &str, time: &str) -> Box<dyn Widget> {
287 Box::new(
288 Container::new()
289 .background(theme_surface_hover())
290 .padding(12.0)
291 .border_radius(8.0)
292 .child(
293 Row::new()
294 .main_axis_alignment(MainAxisAlignment::SpaceBetween)
295 .cross_axis_alignment(CrossAxisAlignment::Center)
296 .children(vec![
297 Box::new(Column::new().spacing(4.0).children(vec![
298 Box::new(Text::new(title).font_size(14.0).color(theme_text_primary()))
299 as Box<dyn Widget>,
300 Box::new(Text::new(status).font_size(12.0).color(theme_accent()))
301 as Box<dyn Widget>,
302 ])) as Box<dyn Widget>,
303 Box::new(
304 Text::new(time)
305 .font_size(12.0)
306 .color(theme_text_secondary()),
307 ) as Box<dyn Widget>,
308 ]),
309 ),
310 )
311}
312 
313// Extension trait helper to box widgets easily
314trait WidgetExt {
315 fn into_boxed(self) -> Box<dyn Widget>;
316}
317 
318impl<T: Widget + 'static> WidgetExt for T {
319 fn into_boxed(self) -> Box<dyn Widget> {
320 Box::new(self)
321 }
322}
323