pixcil/widget/
side_bar.rs

1use super::{
2    FixedSizeWidget, VariableSizeWidget, Widget, save_load::SaveLoadWidget,
3    undo_redo::UndoRedoWidget, zoom::ZoomWidget,
4};
5use crate::{app::App, event::Event};
6use orfail::{OrFail, Result};
7use pagurus::image::Canvas;
8use pagurus::spatial::{Position, Region, Size};
9
10const MARGIN: u32 = 16;
11
12#[derive(Debug, Default)]
13pub struct SideBarWidget {
14    region: Region,
15    save_load: SaveLoadWidget,
16    undo_redo: UndoRedoWidget,
17    zoom: ZoomWidget,
18}
19
20impl Widget for SideBarWidget {
21    fn region(&self) -> Region {
22        self.region
23    }
24
25    fn render(&self, app: &App, canvas: &mut Canvas) {
26        self.save_load.render_if_need(app, canvas);
27        self.undo_redo.render_if_need(app, canvas);
28        self.zoom.render_if_need(app, canvas);
29    }
30
31    fn handle_event(&mut self, app: &mut App, event: &mut Event) -> Result<()> {
32        self.save_load.handle_event(app, event).or_fail()?;
33        self.undo_redo.handle_event(app, event).or_fail()?;
34        self.zoom.handle_event(app, event).or_fail()?;
35        Ok(())
36    }
37
38    fn children(&mut self) -> Vec<&mut dyn Widget> {
39        vec![&mut self.save_load, &mut self.undo_redo, &mut self.zoom]
40    }
41}
42
43impl VariableSizeWidget for SideBarWidget {
44    fn set_region(&mut self, app: &App, region: Region) {
45        self.region.position.x = MARGIN as i32;
46
47        let save_load_size = self.save_load.requiring_size(app);
48        let save_load_position = Position::from_xy(
49            MARGIN as i32,
50            region.size.height as i32 / 4 - save_load_size.height as i32 / 2,
51        );
52        self.save_load.set_position(app, save_load_position);
53
54        let undo_redo_size = self.undo_redo.requiring_size(app);
55        let undo_redo_position = Position::from_xy(
56            MARGIN as i32,
57            region.size.height as i32 / 2 - undo_redo_size.height as i32 / 2,
58        );
59        self.undo_redo.set_position(app, undo_redo_position);
60
61        let zoom_size = self.zoom.requiring_size(app);
62        let zoom_position = Position::from_xy(
63            MARGIN as i32,
64            region.size.height as i32 * 3 / 4 - zoom_size.height as i32 / 2,
65        );
66        self.zoom.set_position(app, zoom_position);
67
68        self.region.size = Size::from_wh(undo_redo_size.width, region.size.height);
69    }
70}