pixcil/
widget.rs

1use crate::{app::App, event::Event};
2use orfail::{OrFail, Result};
3use pagurus::image::Canvas;
4use pagurus::spatial::{Position, Region, Size};
5
6pub mod block;
7pub mod bottom_bar;
8pub mod button;
9pub mod color_config;
10pub mod color_palette;
11pub mod color_selector;
12pub mod config;
13pub mod frame_size;
14pub mod hsv_selector;
15pub mod manipulate;
16pub mod manipulate_tool;
17pub mod move_camera;
18pub mod move_frame;
19pub mod number_box;
20pub mod pixel_canvas;
21pub mod pixel_size;
22pub mod preview;
23pub mod rgb_selector;
24pub mod save_load;
25pub mod select_box;
26pub mod side_bar;
27pub mod size_box;
28pub mod slider;
29pub mod toggle;
30pub mod tool_box;
31pub mod undo_redo;
32pub mod zoom;
33
34pub trait Widget: std::fmt::Debug + 'static {
35    fn region(&self) -> Region;
36    fn render(&self, app: &App, canvas: &mut Canvas);
37    fn handle_event(&mut self, app: &mut App, event: &mut Event) -> Result<()>;
38    fn children(&mut self) -> Vec<&mut dyn Widget>;
39
40    fn handle_event_before(&mut self, app: &mut App) -> Result<()> {
41        for child in self.children() {
42            child.handle_event_before(app).or_fail()?;
43        }
44        Ok(())
45    }
46
47    fn handle_event_after(&mut self, app: &mut App) -> Result<()> {
48        for child in self.children() {
49            child.handle_event_after(app).or_fail()?;
50        }
51        Ok(())
52    }
53
54    fn render_if_need(&self, app: &App, canvas: &mut Canvas) {
55        if !self
56            .region()
57            .intersection(canvas.drawing_region())
58            .is_empty()
59        {
60            self.render(app, canvas);
61        }
62    }
63}
64
65pub trait FixedSizeWidget: Widget {
66    fn requiring_size(&self, app: &App) -> Size;
67    fn set_position(&mut self, app: &App, position: Position);
68}
69
70pub trait VariableSizeWidget: Widget {
71    fn set_region(&mut self, app: &App, region: Region);
72}