zng_wgt_size_offset/
min.rs

1use zng_wgt::prelude::*;
2
3/// Minimum size of the widget.
4///
5/// The widget size can be larger then this but not smaller.
6/// Relative values are computed from the constraints maximum bounded size.
7///
8/// This property does not force the minimum constrained size, the `min_size` is only used
9/// in a dimension if it is greater then the constrained minimum.
10///
11/// This property disables inline layout for the widget.
12///
13/// # `min_width` and `min_height`
14///
15/// You can use the [`min_width`](fn@min_width) and [`min_height`](fn@crate::min_height) properties to only
16/// set the minimum size of one dimension.
17#[property(SIZE-2, default((0, 0)))]
18pub fn min_size(child: impl IntoUiNode, min_size: impl IntoVar<Size>) -> UiNode {
19    let min_size = min_size.into_var();
20    match_node(child, move |child, op| match op {
21        UiNodeOp::Init => {
22            WIDGET.sub_var_layout(&min_size);
23        }
24        UiNodeOp::Measure { wm, desired_size } => {
25            child.delegated();
26            let c = LAYOUT.constraints();
27            let min = LAYOUT.with_constraints(c.with_fill_vector(c.is_bounded()), || min_size.layout());
28            let size = LAYOUT.with_constraints(c.with_min_size(min), || wm.measure_block(child.node()));
29            *desired_size = size.max(min);
30        }
31        UiNodeOp::Layout { wl, final_size } => {
32            let c = LAYOUT.constraints();
33            let min = LAYOUT.with_constraints(c.with_fill_vector(c.is_bounded()), || min_size.layout());
34            let size = LAYOUT.with_constraints(c.with_min_size(min), || child.layout(wl));
35            *final_size = size.max(min);
36        }
37        _ => {}
38    })
39}
40
41/// Minimum width of the widget.
42///
43/// The widget width can be larger then this but not smaller.
44/// Relative values are computed from the constraints maximum bounded width.
45///
46/// This property does not force the minimum constrained width, the `min_width` is only used
47/// if it is greater then the constrained minimum.
48///
49/// This property disables inline layout for the widget.
50///
51/// # `min_size`
52///
53/// You can set both `min_width` and `min_height` at the same time using the [`min_size`](fn@crate::min_size) property.
54#[property(SIZE-2, default(0))]
55pub fn min_width(child: impl IntoUiNode, min_width: impl IntoVar<Length>) -> UiNode {
56    let min_width = min_width.into_var();
57    match_node(child, move |child, op| match op {
58        UiNodeOp::Init => {
59            WIDGET.sub_var_layout(&min_width);
60        }
61        UiNodeOp::Measure { wm, desired_size } => {
62            child.delegated();
63            let c = LAYOUT.constraints();
64            let min = LAYOUT.with_constraints(c.with_fill_vector(c.is_bounded()), || min_width.layout_x());
65            let mut size = LAYOUT.with_constraints(c.with_min_x(min), || wm.measure_block(child.node()));
66            size.width = size.width.max(min);
67            *desired_size = size;
68        }
69        UiNodeOp::Layout { wl, final_size } => {
70            let c = LAYOUT.constraints();
71            let min = LAYOUT.with_constraints(c.with_fill_vector(c.is_bounded()), || min_width.layout_x());
72            let mut size = LAYOUT.with_constraints(c.with_min_x(min), || child.layout(wl));
73            size.width = size.width.max(min);
74            *final_size = size;
75        }
76        _ => {}
77    })
78}
79
80/// Minimum height of the widget.
81///
82/// The widget height can be larger then this but not smaller.
83/// Relative values are computed from the constraints maximum bounded height.
84///
85/// This property does not force the minimum constrained height, the `min_height` is only used
86/// if it is greater then the constrained minimum.
87///
88/// This property disables inline layout for the widget.
89///
90/// # `min_size`
91///
92/// You can set both `min_width` and `min_height` at the same time using the [`min_size`](fn@crate::min_size) property.
93#[property(SIZE-2, default(0))]
94pub fn min_height(child: impl IntoUiNode, min_height: impl IntoVar<Length>) -> UiNode {
95    let min_height = min_height.into_var();
96    match_node(child, move |child, op| match op {
97        UiNodeOp::Init => {
98            WIDGET.sub_var_layout(&min_height);
99        }
100        UiNodeOp::Measure { wm, desired_size } => {
101            child.delegated();
102            let c = LAYOUT.constraints();
103            let min = LAYOUT.with_constraints(c.with_fill_vector(c.is_bounded()), || min_height.layout_y());
104            let mut size = LAYOUT.with_constraints(c.with_min_y(min), || wm.measure_block(child.node()));
105            size.height = size.height.max(min);
106            *desired_size = size;
107        }
108        UiNodeOp::Layout { wl, final_size } => {
109            let c = LAYOUT.constraints();
110            let min = LAYOUT.with_constraints(c.with_fill_vector(c.is_bounded()), || min_height.layout_y());
111            let mut size = LAYOUT.with_constraints(c.with_min_y(min), || child.layout(wl));
112            size.height = size.height.max(min);
113            *final_size = size;
114        }
115        _ => {}
116    })
117}