ailloli_ui_core/style/
layout_style.rs

1//! Declarative per-widget dimensions, bounds, margin, and padding.
2
3use crate::geometry::EdgeInsets;
4
5use super::Length;
6
7/// Per-widget layout: dimensions, min/max, margin, and padding.
8///
9/// # Examples
10///
11/// ```
12/// use ailloli_ui_core::style::{LayoutStyle, Length};
13/// let layout = LayoutStyle::new().width(120.0).fill_height().padding(8.0);
14/// assert_eq!(layout.width, Length::Px(120.0));
15/// ```
16#[derive(Debug, Clone, Copy, PartialEq)]
17pub struct LayoutStyle {
18    /// Preferred width; [`Length::Auto`] uses intrinsic width.
19    pub width: Length,
20    /// Preferred height; [`Length::Auto`] uses intrinsic height.
21    pub height: Length,
22    /// Optional minimum width; [`Length::Auto`] means no explicit minimum.
23    pub min_width: Length,
24    /// Optional maximum width; [`Length::Auto`] means no explicit maximum.
25    pub max_width: Length,
26    /// Optional minimum height; [`Length::Auto`] means no explicit minimum.
27    pub min_height: Length,
28    /// Optional maximum height; [`Length::Auto`] means no explicit maximum.
29    pub max_height: Length,
30    /// Space outside the widget border in logical pixels.
31    pub margin: EdgeInsets,
32    /// Space between border and content in logical pixels.
33    pub padding: EdgeInsets,
34}
35
36impl Default for LayoutStyle {
37    fn default() -> Self {
38        Self {
39            width: Length::Auto,
40            height: Length::Auto,
41            min_width: Length::Auto,
42            max_width: Length::Auto,
43            min_height: Length::Auto,
44            max_height: Length::Auto,
45            margin: EdgeInsets::default(),
46            padding: EdgeInsets::default(),
47        }
48    }
49}
50
51impl LayoutStyle {
52    /// Creates an entirely automatic layout with zero margin and padding.
53    ///
54    /// # Examples
55    ///
56    /// ```
57    /// use ailloli_ui_core::style::{LayoutStyle, Length};
58    /// assert_eq!(LayoutStyle::new().width, Length::Auto);
59    /// ```
60    pub fn new() -> Self {
61        Self::default()
62    }
63
64    /// Replaces the preferred width.
65    ///
66    /// # Examples
67    ///
68    /// ```
69    /// use ailloli_ui_core::style::{LayoutStyle, Length};
70    /// assert_eq!(LayoutStyle::new().width(20.0).width, Length::Px(20.0));
71    /// ```
72    pub fn width(mut self, width: impl Into<Length>) -> Self {
73        self.width = width.into();
74        self
75    }
76
77    /// Replaces the preferred height.
78    ///
79    /// # Examples
80    ///
81    /// ```
82    /// use ailloli_ui_core::style::{LayoutStyle, Length};
83    /// assert_eq!(LayoutStyle::new().height(20.0).height, Length::Px(20.0));
84    /// ```
85    pub fn height(mut self, height: impl Into<Length>) -> Self {
86        self.height = height.into();
87        self
88    }
89
90    /// Sets both preferred axes to [`Length::Fill`].
91    ///
92    /// # Examples
93    ///
94    /// ```
95    /// use ailloli_ui_core::style::{LayoutStyle, Length};
96    /// let layout = LayoutStyle::new().fill();
97    /// assert_eq!((layout.width, layout.height), (Length::Fill, Length::Fill));
98    /// ```
99    pub fn fill(mut self) -> Self {
100        self.width = Length::Fill;
101        self.height = Length::Fill;
102        self
103    }
104
105    /// Sets only preferred width to [`Length::Fill`].
106    ///
107    /// # Examples
108    ///
109    /// ```
110    /// use ailloli_ui_core::style::{LayoutStyle, Length};
111    /// assert_eq!(LayoutStyle::new().fill_width().width, Length::Fill);
112    /// ```
113    pub fn fill_width(mut self) -> Self {
114        self.width = Length::Fill;
115        self
116    }
117
118    /// Sets only preferred height to [`Length::Fill`].
119    ///
120    /// # Examples
121    ///
122    /// ```
123    /// use ailloli_ui_core::style::{LayoutStyle, Length};
124    /// assert_eq!(LayoutStyle::new().fill_height().height, Length::Fill);
125    /// ```
126    pub fn fill_height(mut self) -> Self {
127        self.height = Length::Fill;
128        self
129    }
130
131    /// Replaces the minimum-width declaration.
132    ///
133    /// # Examples
134    ///
135    /// ```
136    /// use ailloli_ui_core::style::{LayoutStyle, Length};
137    /// assert_eq!(LayoutStyle::new().min_width(10.0).min_width, Length::Px(10.0));
138    /// ```
139    pub fn min_width(mut self, value: impl Into<Length>) -> Self {
140        self.min_width = value.into();
141        self
142    }
143
144    /// Replaces the maximum-width declaration.
145    ///
146    /// # Examples
147    ///
148    /// ```
149    /// use ailloli_ui_core::style::{LayoutStyle, Length};
150    /// assert_eq!(LayoutStyle::new().max_width(10.0).max_width, Length::Px(10.0));
151    /// ```
152    pub fn max_width(mut self, value: impl Into<Length>) -> Self {
153        self.max_width = value.into();
154        self
155    }
156
157    /// Replaces the minimum-height declaration.
158    ///
159    /// # Examples
160    ///
161    /// ```
162    /// use ailloli_ui_core::style::{LayoutStyle, Length};
163    /// assert_eq!(LayoutStyle::new().min_height(10.0).min_height, Length::Px(10.0));
164    /// ```
165    pub fn min_height(mut self, value: impl Into<Length>) -> Self {
166        self.min_height = value.into();
167        self
168    }
169
170    /// Replaces the maximum-height declaration.
171    ///
172    /// # Examples
173    ///
174    /// ```
175    /// use ailloli_ui_core::style::{LayoutStyle, Length};
176    /// assert_eq!(LayoutStyle::new().max_height(10.0).max_height, Length::Px(10.0));
177    /// ```
178    pub fn max_height(mut self, value: impl Into<Length>) -> Self {
179        self.max_height = value.into();
180        self
181    }
182
183    /// Replaces all four padding edges with `value` logical pixels.
184    ///
185    /// The value is stored verbatim, including negative or non-finite input.
186    ///
187    /// # Examples
188    ///
189    /// ```
190    /// use ailloli_ui_core::style::LayoutStyle;
191    /// assert_eq!(LayoutStyle::new().padding(8.0).padding.left, 8.0);
192    /// ```
193    pub fn padding(mut self, value: f32) -> Self {
194        self.padding = EdgeInsets::all(value);
195        self
196    }
197
198    /// Replaces all four margin edges with `value` logical pixels.
199    ///
200    /// The value is stored verbatim, including negative or non-finite input.
201    ///
202    /// # Examples
203    ///
204    /// ```
205    /// use ailloli_ui_core::style::LayoutStyle;
206    /// assert_eq!(LayoutStyle::new().margin(8.0).margin.top, 8.0);
207    /// ```
208    pub fn margin(mut self, value: f32) -> Self {
209        self.margin = EdgeInsets::all(value);
210        self
211    }
212}