ui/
ui.rs

1use glam::{Quat, Vec3};
2use rhachis::{
3    camera::SimpleProjection,
4    game_data, graphics,
5    graphics::SamplerType,
6    model::{Model, Transform},
7    renderers::{SimpleRenderer, SimpleRendererBuilder},
8    run,
9    ui::{Button, ButtonElement, Image, Label, UiRenderer},
10    Game, GameExt,
11};
12
13#[run]
14struct Main {
15    renderer: SimpleRenderer,
16    count: i8,
17
18    button_id: usize,
19    counter_id: usize,
20}
21
22impl Game for Main {
23    fn init() -> Self {
24        let mut ui_renderer = UiRenderer::new(
25            Box::new(|size| SimpleProjection::center_height(size.as_vec2(), 2.0)),
26            true,
27            4,
28        );
29        let button_id = ui_renderer.push(Button {
30            child: Image {
31                transforms: vec![
32                    Transform::scale(Vec3::splat(16.0)).with_translation([-0.75, -0.5, 0.0]),
33                    Transform::scale(Vec3::splat(16.0)).with_translation([0.75, -0.5, 0.0]),
34                ],
35                ..Image::from_image(
36                    &image::open("examples/click.png").unwrap().into_rgba8(),
37                    SamplerType::NEAREST,
38                )
39                .unwrap()
40            },
41            bounds: None,
42        });
43        let counter_id = ui_renderer.push(Image {
44            transforms: counter_transforms(4),
45            ..Image::from_image(
46                &image::open("examples/counter.png").unwrap().into_rgba8(),
47                SamplerType::NEAREST,
48            )
49            .unwrap()
50        });
51        ui_renderer.push(Label {
52            transforms: vec![Transform::default().with_z(1.0)],
53            text: "Ui Demo".to_owned(),
54            font: None,
55            size: 24.0,
56            color: wgpu::Color::RED,
57            ..Default::default()
58        });
59
60        let mut simple_renderer = SimpleRendererBuilder {
61            sample_count: 4,
62            child: Some(Box::new(ui_renderer)),
63            ..SimpleRendererBuilder::projection_builder(Box::new(|_| {
64                SimpleProjection::new_perspective(game_data().get_window_size().as_vec2())
65            }))
66        }
67        .build();
68        simple_renderer
69            .models
70            .push(Model::cube(vec![Transform::translation([0.0, 0.0, -5.0])]));
71        simple_renderer.scene_lighting[0].ambient_lighting = Vec3::splat(0.1);
72
73        Self {
74            renderer: simple_renderer,
75            count: 3,
76            button_id,
77            counter_id,
78        }
79    }
80
81    fn update(&mut self) {
82        self.renderer.models[0].transforms[0].rotation =
83            Quat::from_rotation_y(game_data().start_time().elapsed().as_secs_f32());
84
85        let ui_renderer = self
86            .renderer
87            .child
88            .as_mut()
89            .unwrap()
90            .downcast_mut::<UiRenderer>()
91            .unwrap();
92        let button = ui_renderer.get::<ButtonElement>(self.button_id).unwrap();
93        let mut changed = false;
94        match button.click() {
95            Some(0) => {
96                self.count -= 1;
97                changed = true;
98            }
99            Some(1) => {
100                self.count += 1;
101                changed = true;
102            }
103            _ => {}
104        }
105        if changed {
106            self.count = (self.count + 5) % 5;
107
108            ui_renderer.replace(
109                self.counter_id,
110                Image {
111                    transforms: counter_transforms(self.count + 1),
112                    ..Image::from_image(
113                        &image::open("examples/counter.png").unwrap().into_rgba8(),
114                        SamplerType::NEAREST,
115                    )
116                    .unwrap()
117                },
118            );
119        }
120    }
121
122    fn get_renderer(&mut self) -> &mut dyn graphics::Renderer {
123        &mut self.renderer
124    }
125}
126
127fn counter_transforms(count: i8) -> Vec<Transform> {
128    let mut to_ret = Vec::new();
129    let step = 0.5;
130    for i in 0..count {
131        let x = f32::from(i) * step - 2.0 * step;
132        to_ret.push(Transform::translation([x, 0.5, 0.0]).with_scale(Vec3::splat(16.0)));
133    }
134
135    to_ret
136}