1#![allow(dead_code)]
2mod utils;
5use utils::*;
6
7use bevy::prelude::*;
8use haalka::prelude::*;
9
10fn main() {
11 App::new()
12 .add_plugins(examples_plugin)
13 .add_systems(
14 Startup,
15 (
16 |world: &mut World| {
17 ui_root().spawn(world);
18 },
19 camera,
20 ),
21 )
22 .run();
23}
24
25#[derive(Component)]
26struct Counter(Mutable<i32>);
27
28fn ui_root() -> impl Element {
29 let counter = Mutable::new(0);
30 El::<Node>::new()
31 .with_node(|mut node| {
32 node.height = Val::Percent(100.);
33 node.width = Val::Percent(100.);
34 })
35 .cursor(CursorIcon::default())
36 .align_content(Align::center())
37 .child(
38 Row::<Node>::new()
39 .with_node(|mut node| node.column_gap = Val::Px(15.0))
40 .item(counter_button(counter.clone(), "-", -1))
41 .item(
42 El::<Text>::new()
43 .text_font(TextFont::from_font_size(25.))
44 .text_signal(counter.signal_ref(ToString::to_string).map(Text)),
45 )
46 .item(counter_button(counter.clone(), "+", 1))
47 .update_raw_el(move |raw_el| raw_el.insert(Counter(counter))),
48 )
49}
50
51fn counter_button(counter: Mutable<i32>, label: &str, step: i32) -> impl Element {
52 let hovered = Mutable::new(false);
53 El::<Node>::new()
54 .with_node(|mut node| node.width = Val::Px(45.0))
55 .align_content(Align::center())
56 .border_radius(BorderRadius::MAX)
57 .cursor(CursorIcon::System(SystemCursorIcon::Pointer))
58 .background_color_signal(
59 hovered
60 .signal()
61 .map_bool(|| Color::hsl(300., 0.75, 0.85), || Color::hsl(300., 0.75, 0.75))
62 .map(BackgroundColor),
63 )
64 .hovered_sync(hovered)
65 .on_click(move || *counter.lock_mut() += step)
66 .child(
67 El::<Text>::new()
68 .text_font(TextFont::from_font_size(25.))
69 .text(Text::new(label)),
70 )
71}
72
73fn camera(mut commands: Commands) {
74 commands.spawn(Camera2d);
75}