zng_wgt_size_offset/
sticky.rs1use zng_wgt::prelude::*;
2
3#[property(SIZE, default(false))]
8pub fn sticky_width(child: impl IntoUiNode, sticky: impl IntoVar<bool>) -> UiNode {
9 let sticky = sticky.into_var();
10 let mut sticky_after_layout = false;
11 match_node(child, move |child, op| match op {
12 UiNodeOp::Init => {
13 WIDGET.sub_var(&sticky);
14 }
15 UiNodeOp::Deinit => {
16 sticky_after_layout = false;
17 }
18 UiNodeOp::Update { .. } if sticky.is_new() => {
19 sticky_after_layout = false;
20 }
21 UiNodeOp::Measure { wm, desired_size } if sticky_after_layout && sticky.get() => {
22 child.delegated();
23 let min = WIDGET.bounds().inner_size().width;
24 let mut size = LAYOUT.with_constraints(LAYOUT.constraints().with_min_x(min), || wm.measure_block(child.node()));
25 size.width = size.width.max(min);
26 *desired_size = size;
27 }
28 UiNodeOp::Layout { wl, final_size } => {
29 let sticky = sticky.get();
30 if sticky_after_layout && sticky {
31 let min = WIDGET.bounds().inner_size().width;
32 let mut size = LAYOUT.with_constraints(LAYOUT.constraints().with_min_x(min), || child.layout(wl));
33 size.width = size.width.max(min);
34 *final_size = size;
35 }
36
37 sticky_after_layout = sticky;
39 }
40 _ => {}
41 })
42}
43
44#[property(SIZE, default(false))]
49pub fn sticky_height(child: impl IntoUiNode, sticky: impl IntoVar<bool>) -> UiNode {
50 let sticky = sticky.into_var();
51 let mut sticky_after_layout = false;
52 match_node(child, move |child, op| match op {
53 UiNodeOp::Init => {
54 WIDGET.sub_var(&sticky);
55 }
56 UiNodeOp::Deinit => {
57 sticky_after_layout = false;
58 }
59 UiNodeOp::Update { .. } if sticky.is_new() => {
60 sticky_after_layout = false;
61 }
62 UiNodeOp::Measure { wm, desired_size } if sticky_after_layout && sticky.get() => {
63 child.delegated();
64 let min = WIDGET.bounds().inner_size().height;
65 let mut size = LAYOUT.with_constraints(LAYOUT.constraints().with_min_y(min), || wm.measure_block(child.node()));
66 size.height = size.height.max(min);
67 *desired_size = size;
68 }
69 UiNodeOp::Layout { wl, final_size } => {
70 let sticky = sticky.get();
71 if sticky_after_layout && sticky {
72 let min = WIDGET.bounds().inner_size().height;
73 let mut size = LAYOUT.with_constraints(LAYOUT.constraints().with_min_y(min), || child.layout(wl));
74 size.height = size.height.max(min);
75 *final_size = size;
76 }
77
78 sticky_after_layout = sticky;
80 }
81 _ => {}
82 })
83}
84
85#[property(SIZE, default(false))]
90pub fn sticky_size(child: impl IntoUiNode, sticky: impl IntoVar<bool>) -> UiNode {
91 let sticky = sticky.into_var();
92 let mut sticky_after_layout = false;
93 match_node(child, move |child, op| match op {
94 UiNodeOp::Init => {
95 WIDGET.sub_var(&sticky);
96 }
97 UiNodeOp::Deinit => {
98 sticky_after_layout = false;
99 }
100 UiNodeOp::Update { .. } if sticky.is_new() => {
101 sticky_after_layout = false;
102 }
103 UiNodeOp::Update { .. } => {}
104 UiNodeOp::Measure { wm, desired_size } if sticky_after_layout && sticky.get() => {
105 child.delegated();
106 let min = WIDGET.bounds().inner_size();
107 let mut size = LAYOUT.with_constraints(LAYOUT.constraints().with_min_size(min), || wm.measure_block(child.node()));
108 size = size.max(min);
109 *desired_size = size;
110 }
111 UiNodeOp::Layout { wl, final_size } => {
112 let sticky = sticky.get();
113 if sticky_after_layout && sticky {
114 let min = WIDGET.bounds().inner_size();
115 let mut size = LAYOUT.with_constraints(LAYOUT.constraints().with_min_size(min), || child.layout(wl));
116 size = size.max(min);
117 *final_size = size;
118 }
119
120 sticky_after_layout = sticky;
122 }
123 _ => {}
124 })
125}