zng_wgt_grid/
column.rs

1use super::*;
2
3/// Grid column definition.
4///
5/// This widget is layout to define the actual column width, it is not the parent
6/// of the cells, only the `width` and `align` properties affect the cells.
7///
8/// See the [`Grid::columns`] property for more details.
9///
10/// # Shorthand
11///
12/// The `Column!` macro provides a shorthand init that sets the width, `grid::Column!(1.lft())` instantiates
13/// a column with width of *1 leftover*.
14#[widget($crate::Column { ($width:expr) => { width = $width; }; })]
15pub struct Column(WidgetBase);
16impl Column {
17    widget_impl! {
18        /// Column max width.
19        pub max_width(max: impl IntoVar<Length>);
20
21        /// Column min width.
22        pub min_width(min: impl IntoVar<Length>);
23
24        /// Column width.
25        pub width(width: impl IntoVar<Length>);
26    }
27
28    fn widget_intrinsic(&mut self) {
29        widget_set! {
30            self;
31            access_role = AccessRole::Column;
32        }
33    }
34}
35
36static_id! {
37    /// Column index, total in the parent widget set by the parent.
38    pub(super) static ref INDEX_ID: StateId<(usize, usize)>;
39}
40
41/// If the column index is even.
42///
43/// Column index is zero-based, so the first column is even, the next [`is_odd`].
44///
45/// [`is_odd`]: fn@is_odd
46#[property(CONTEXT, widget_impl(Column))]
47pub fn is_even(child: impl IntoUiNode, state: impl IntoVar<bool>) -> UiNode {
48    widget_state_is_state(child, |w| w.get(*INDEX_ID).copied().unwrap_or((0, 0)).0 % 2 == 0, |_| false, state)
49}
50
51/// If the column index is odd.
52///
53/// Column index is zero-based, so the first column [`is_even`], the next one is odd.
54///
55/// [`is_even`]: fn@is_even
56#[property(CONTEXT, widget_impl(Column))]
57pub fn is_odd(child: impl IntoUiNode, state: impl IntoVar<bool>) -> UiNode {
58    widget_state_is_state(child, |w| w.get(*INDEX_ID).copied().unwrap_or((0, 0)).0 % 2 != 0, |_| false, state)
59}
60
61/// If the column is the first.
62#[property(CONTEXT, widget_impl(Column))]
63pub fn is_first(child: impl IntoUiNode, state: impl IntoVar<bool>) -> UiNode {
64    widget_state_is_state(
65        child,
66        |w| {
67            let (i, l) = w.get(*INDEX_ID).copied().unwrap_or((0, 0));
68            i == 0 && l > 0
69        },
70        |_| false,
71        state,
72    )
73}
74
75/// If the column is the last.
76#[property(CONTEXT, widget_impl(Column))]
77pub fn is_last(child: impl IntoUiNode, state: impl IntoVar<bool>) -> UiNode {
78    widget_state_is_state(
79        child,
80        |w| {
81            let (i, l) = w.get(*INDEX_ID).copied().unwrap_or((0, 0));
82            i < l && i == l - 1
83        },
84        |_| false,
85        state,
86    )
87}
88
89/// Get the column index.
90///
91/// The column index is zero-based.
92#[property(CONTEXT, widget_impl(Column))]
93pub fn get_index(child: impl IntoUiNode, state: impl IntoVar<usize>) -> UiNode {
94    widget_state_get_state(
95        child,
96        |w, &i| {
97            let a = w.get(*INDEX_ID).copied().unwrap_or((0, 0)).0;
98            if a != i { Some(a) } else { None }
99        },
100        |_, &i| if i != 0 { Some(0) } else { None },
101        state,
102    )
103}
104
105/// Get the column index and number of columns.
106#[property(CONTEXT, widget_impl(Column))]
107pub fn get_index_len(child: impl IntoUiNode, state: impl IntoVar<(usize, usize)>) -> UiNode {
108    widget_state_get_state(
109        child,
110        |w, &i| {
111            let a = w.get(*INDEX_ID).copied().unwrap_or((0, 0));
112            if a != i { Some(a) } else { None }
113        },
114        |_, &i| if i != (0, 0) { Some((0, 0)) } else { None },
115        state,
116    )
117}
118
119/// Get the column index, starting from the last column at `0`.
120#[property(CONTEXT, widget_impl(Column))]
121pub fn get_rev_index(child: impl IntoUiNode, state: impl IntoVar<usize>) -> UiNode {
122    widget_state_get_state(
123        child,
124        |w, &i| {
125            let a = w.get(*INDEX_ID).copied().unwrap_or((0, 0));
126            let a = a.1 - a.0;
127            if a != i { Some(a) } else { None }
128        },
129        |_, &i| if i != 0 { Some(0) } else { None },
130        state,
131    )
132}