agg_gui/widgets/
rebuilder.rs1use crate::draw_ctx::DrawCtx;
22use crate::event::{Event, EventResult};
23use crate::geometry::{Rect, Size};
24use crate::layout_props::{HAnchor, Insets, VAnchor, WidgetBase};
25use crate::widget::Widget;
26
27pub struct Rebuilder {
28 bounds: Rect,
29 children: Vec<Box<dyn Widget>>, base: WidgetBase,
31 version_fn: Box<dyn Fn() -> u64>,
32 builder: Box<dyn Fn() -> Box<dyn Widget>>,
33 version: Option<u64>,
34}
35
36impl Rebuilder {
37 pub fn new(
38 version_fn: impl Fn() -> u64 + 'static,
39 builder: impl Fn() -> Box<dyn Widget> + 'static,
40 ) -> Self {
41 Self {
42 bounds: Rect::default(),
43 children: Vec::new(),
44 base: WidgetBase::new(),
45 version_fn: Box::new(version_fn),
46 builder: Box::new(builder),
47 version: None,
48 }
49 }
50
51 pub fn with_margin(mut self, m: Insets) -> Self {
52 self.base.margin = m;
53 self
54 }
55 pub fn with_h_anchor(mut self, h: HAnchor) -> Self {
56 self.base.h_anchor = h;
57 self
58 }
59 pub fn with_v_anchor(mut self, v: VAnchor) -> Self {
60 self.base.v_anchor = v;
61 self
62 }
63}
64
65impl Widget for Rebuilder {
66 fn type_name(&self) -> &'static str {
67 "Rebuilder"
68 }
69 fn bounds(&self) -> Rect {
70 self.bounds
71 }
72 fn set_bounds(&mut self, b: Rect) {
73 self.bounds = b;
74 }
75 fn children(&self) -> &[Box<dyn Widget>] {
76 &self.children
77 }
78 fn children_mut(&mut self) -> &mut Vec<Box<dyn Widget>> {
79 &mut self.children
80 }
81
82 fn margin(&self) -> Insets {
83 self.base.margin
84 }
85 fn widget_base(&self) -> Option<&WidgetBase> {
86 Some(&self.base)
87 }
88 fn widget_base_mut(&mut self) -> Option<&mut WidgetBase> {
89 Some(&mut self.base)
90 }
91 fn h_anchor(&self) -> HAnchor {
92 self.base.h_anchor
93 }
94 fn v_anchor(&self) -> VAnchor {
95 self.base.v_anchor
96 }
97
98 fn layout(&mut self, available: Size) -> Size {
99 let version = (self.version_fn)();
100 if self.version != Some(version) {
101 self.children.clear();
102 self.children.push((self.builder)());
103 self.version = Some(version);
104 }
105 let Some(child) = self.children.first_mut() else {
106 return Size::new(0.0, 0.0);
107 };
108 let s = child.layout(available);
109 child.set_bounds(Rect::new(0.0, 0.0, s.width, s.height));
110 self.bounds = Rect::new(0.0, 0.0, s.width, s.height);
111 s
112 }
113
114 fn paint(&mut self, _ctx: &mut dyn DrawCtx) {}
115
116 fn on_event(&mut self, _e: &Event) -> EventResult {
117 EventResult::Ignored
118 }
119}