iced_core/layout/
limits.rs1#![allow(clippy::manual_clamp)]
2use crate::{Length, Size};
3
4#[derive(Debug, Clone, Copy, PartialEq)]
6pub struct Limits {
7 min: Size,
8 max: Size,
9 compression: Size<bool>,
10}
11
12impl Limits {
13 pub const NONE: Limits = Limits {
15 min: Size::ZERO,
16 max: Size::INFINITE,
17 compression: Size::new(false, false),
18 };
19
20 pub const fn new(min: Size, max: Size) -> Limits {
22 Limits::with_compression(min, max, Size::new(false, false))
23 }
24
25 pub const fn with_compression(
28 min: Size,
29 max: Size,
30 compress: Size<bool>,
31 ) -> Self {
32 Limits {
33 min,
34 max,
35 compression: compress,
36 }
37 }
38
39 pub fn min(&self) -> Size {
41 self.min
42 }
43
44 pub fn max(&self) -> Size {
46 self.max
47 }
48
49 pub fn compression(&self) -> Size<bool> {
51 self.compression
52 }
53
54 pub fn width(mut self, width: impl Into<Length>) -> Limits {
56 match width.into() {
57 Length::Shrink => {
58 self.compression.width = true;
59 }
60 Length::Fixed(amount) => {
61 let new_width = amount.min(self.max.width).max(self.min.width);
62
63 self.min.width = new_width;
64 self.max.width = new_width;
65 self.compression.width = false;
66 }
67 Length::Fill | Length::FillPortion(_) => {}
68 }
69
70 self
71 }
72
73 pub fn height(mut self, height: impl Into<Length>) -> Limits {
75 match height.into() {
76 Length::Shrink => {
77 self.compression.height = true;
78 }
79 Length::Fixed(amount) => {
80 let new_height =
81 amount.min(self.max.height).max(self.min.height);
82
83 self.min.height = new_height;
84 self.max.height = new_height;
85 self.compression.height = false;
86 }
87 Length::Fill | Length::FillPortion(_) => {}
88 }
89
90 self
91 }
92
93 pub fn min_width(mut self, min_width: f32) -> Limits {
95 self.min.width = self.min.width.max(min_width).min(self.max.width);
96
97 self
98 }
99
100 pub fn max_width(mut self, max_width: f32) -> Limits {
102 self.max.width = self.max.width.min(max_width).max(self.min.width);
103
104 self
105 }
106
107 pub fn min_height(mut self, min_height: f32) -> Limits {
109 self.min.height = self.min.height.max(min_height).min(self.max.height);
110
111 self
112 }
113
114 pub fn max_height(mut self, max_height: f32) -> Limits {
116 self.max.height = self.max.height.min(max_height).max(self.min.height);
117
118 self
119 }
120
121 pub fn shrink(&self, size: impl Into<Size>) -> Limits {
123 let size = size.into();
124
125 let min = Size::new(
126 (self.min().width - size.width).max(0.0),
127 (self.min().height - size.height).max(0.0),
128 );
129
130 let max = Size::new(
131 (self.max().width - size.width).max(0.0),
132 (self.max().height - size.height).max(0.0),
133 );
134
135 Limits {
136 min,
137 max,
138 compression: self.compression,
139 }
140 }
141
142 pub fn loose(&self) -> Limits {
144 Limits {
145 min: Size::ZERO,
146 max: self.max,
147 compression: self.compression,
148 }
149 }
150
151 pub fn resolve(
155 &self,
156 width: impl Into<Length>,
157 height: impl Into<Length>,
158 intrinsic_size: Size,
159 ) -> Size {
160 let width = match width.into() {
161 Length::Fill | Length::FillPortion(_)
162 if !self.compression.width =>
163 {
164 self.max.width
165 }
166 Length::Fixed(amount) => {
167 amount.min(self.max.width).max(self.min.width)
168 }
169 _ => intrinsic_size.width.min(self.max.width).max(self.min.width),
170 };
171
172 let height = match height.into() {
173 Length::Fill | Length::FillPortion(_)
174 if !self.compression.height =>
175 {
176 self.max.height
177 }
178 Length::Fixed(amount) => {
179 amount.min(self.max.height).max(self.min.height)
180 }
181 _ => intrinsic_size
182 .height
183 .min(self.max.height)
184 .max(self.min.height),
185 };
186
187 Size::new(width, height)
188 }
189}