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 { .. } => {
19 if sticky.is_new() {
20 sticky_after_layout = false;
21 }
22 }
23 UiNodeOp::Measure { wm, desired_size } => {
24 if sticky_after_layout && sticky.get() {
25 child.delegated();
26 let min = WIDGET.bounds().inner_size().width;
27 let mut size = LAYOUT.with_constraints(LAYOUT.constraints().with_min_x(min), || wm.measure_block(child.node()));
28 size.width = size.width.max(min);
29 *desired_size = size;
30 }
31 }
32 UiNodeOp::Layout { wl, final_size } => {
33 let sticky = sticky.get();
34 if sticky_after_layout && sticky {
35 let min = WIDGET.bounds().inner_size().width;
36 let mut size = LAYOUT.with_constraints(LAYOUT.constraints().with_min_x(min), || child.layout(wl));
37 size.width = size.width.max(min);
38 *final_size = size;
39 }
40
41 sticky_after_layout = sticky;
43 }
44 _ => {}
45 })
46}
47
48#[property(SIZE, default(false))]
53pub fn sticky_height(child: impl IntoUiNode, sticky: impl IntoVar<bool>) -> UiNode {
54 let sticky = sticky.into_var();
55 let mut sticky_after_layout = false;
56 match_node(child, move |child, op| match op {
57 UiNodeOp::Init => {
58 WIDGET.sub_var(&sticky);
59 }
60 UiNodeOp::Deinit => {
61 sticky_after_layout = false;
62 }
63 UiNodeOp::Update { .. } => {
64 if sticky.is_new() {
65 sticky_after_layout = false;
66 }
67 }
68 UiNodeOp::Measure { wm, desired_size } => {
69 if sticky_after_layout && sticky.get() {
70 child.delegated();
71 let min = WIDGET.bounds().inner_size().height;
72 let mut size = LAYOUT.with_constraints(LAYOUT.constraints().with_min_y(min), || wm.measure_block(child.node()));
73 size.height = size.height.max(min);
74 *desired_size = size;
75 }
76 }
77 UiNodeOp::Layout { wl, final_size } => {
78 let sticky = sticky.get();
79 if sticky_after_layout && sticky {
80 let min = WIDGET.bounds().inner_size().height;
81 let mut size = LAYOUT.with_constraints(LAYOUT.constraints().with_min_y(min), || child.layout(wl));
82 size.height = size.height.max(min);
83 *final_size = size;
84 }
85
86 sticky_after_layout = sticky;
88 }
89 _ => {}
90 })
91}
92
93#[property(SIZE, default(false))]
98pub fn sticky_size(child: impl IntoUiNode, sticky: impl IntoVar<bool>) -> UiNode {
99 let sticky = sticky.into_var();
100 let mut sticky_after_layout = false;
101 match_node(child, move |child, op| match op {
102 UiNodeOp::Init => {
103 WIDGET.sub_var(&sticky);
104 }
105 UiNodeOp::Deinit => {
106 sticky_after_layout = false;
107 }
108 UiNodeOp::Update { .. } => {
109 if sticky.is_new() {
110 sticky_after_layout = false;
111 }
112 }
113 UiNodeOp::Measure { wm, desired_size } => {
114 if sticky_after_layout && sticky.get() {
115 child.delegated();
116 let min = WIDGET.bounds().inner_size();
117 let mut size = LAYOUT.with_constraints(LAYOUT.constraints().with_min_size(min), || wm.measure_block(child.node()));
118 size = size.max(min);
119 *desired_size = size;
120 }
121 }
122 UiNodeOp::Layout { wl, final_size } => {
123 let sticky = sticky.get();
124 if sticky_after_layout && sticky {
125 let min = WIDGET.bounds().inner_size();
126 let mut size = LAYOUT.with_constraints(LAYOUT.constraints().with_min_size(min), || child.layout(wl));
127 size = size.max(min);
128 *final_size = size;
129 }
130
131 sticky_after_layout = sticky;
133 }
134 _ => {}
135 })
136}