1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use crate::{api::prelude::*, proc_macros::*, theme::prelude::*, Stack};
#[derive(Default, AsAny)]
pub struct ItemsWidgetState {
builder: WidgetBuildContext,
count: usize,
}
impl ItemsWidgetState {
fn generate_items(&mut self, ctx: &mut Context) {
let count: usize = ctx.widget().clone_or_default("count");
let request_update: bool = *ctx.widget().get("request_update");
if count != self.count || request_update {
if let Some(builder) = &self.builder {
if let Some(items_panel) = ctx.entity_of_child("items_panel") {
ctx.clear_children_of(items_panel);
for i in 0..count {
let bctx = &mut ctx.build_context();
let child = builder(bctx, i);
bctx.append_child(items_panel, child);
}
}
}
self.count = count;
ctx.widget().set("request_update", false);
}
}
}
impl State for ItemsWidgetState {
fn init(&mut self, _: &mut Registry, ctx: &mut Context) {
self.generate_items(ctx);
}
fn update(&mut self, _: &mut Registry, ctx: &mut Context) {
self.generate_items(ctx);
}
}
widget!(
ItemsWidget<ItemsWidgetState> {
background: Brush,
border_radius: f64,
border_width: Thickness,
border_brush: Brush,
padding: Thickness,
orientation: Orientation,
count: usize,
request_update: bool
}
);
impl ItemsWidget {
pub fn items_builder<F: Fn(&mut BuildContext, usize) -> Entity + 'static>(
mut self,
builder: F,
) -> Self {
self.state_mut().builder = Some(Box::new(builder));
self
}
}
impl Template for ItemsWidget {
fn template(self, id: Entity, ctx: &mut BuildContext) -> Self {
self.name("ItemsWidget")
.style("items_widget")
.background(colors::LYNCH_COLOR)
.border_radius(2.0)
.border_width(1.0)
.border_brush(colors::BOMBAY_COLOR)
.padding(2.0)
.orientation("vertical")
.child(Stack::new().id("items_panel").orientation(id).build(ctx))
}
fn render_object(&self) -> Box<dyn RenderObject> {
Box::new(RectangleRenderObject)
}
fn layout(&self) -> Box<dyn Layout> {
Box::new(PaddingLayout::new())
}
}