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(min: Size, max: Size, compress: Size<bool>) -> Self {
28 Limits {
29 min,
30 max,
31 compression: compress,
32 }
33 }
34
35 pub fn min(&self) -> Size {
37 self.min
38 }
39
40 pub fn max(&self) -> Size {
42 self.max
43 }
44
45 pub fn compression(&self) -> Size<bool> {
47 self.compression
48 }
49
50 pub fn width(mut self, width: impl Into<Length>) -> Limits {
52 match width.into() {
53 Length::Shrink => {
54 self.compression.width = true;
55 }
56 Length::Fixed(amount) => {
57 let new_width = amount.min(self.max.width).max(self.min.width);
58
59 self.min.width = new_width;
60 self.max.width = new_width;
61 self.compression.width = false;
62 }
63 Length::Fill | Length::FillPortion(_) => {}
64 }
65
66 self
67 }
68
69 pub fn height(mut self, height: impl Into<Length>) -> Limits {
71 match height.into() {
72 Length::Shrink => {
73 self.compression.height = true;
74 }
75 Length::Fixed(amount) => {
76 let new_height = amount.min(self.max.height).max(self.min.height);
77
78 self.min.height = new_height;
79 self.max.height = new_height;
80 self.compression.height = false;
81 }
82 Length::Fill | Length::FillPortion(_) => {}
83 }
84
85 self
86 }
87
88 pub fn min_width(mut self, min_width: f32) -> Limits {
90 self.min.width = self.min.width.max(min_width).min(self.max.width);
91
92 self
93 }
94
95 pub fn max_width(mut self, max_width: f32) -> Limits {
97 self.max.width = self.max.width.min(max_width).max(self.min.width);
98
99 self
100 }
101
102 pub fn min_height(mut self, min_height: f32) -> Limits {
104 self.min.height = self.min.height.max(min_height).min(self.max.height);
105
106 self
107 }
108
109 pub fn max_height(mut self, max_height: f32) -> Limits {
111 self.max.height = self.max.height.min(max_height).max(self.min.height);
112
113 self
114 }
115
116 pub fn shrink(&self, size: impl Into<Size>) -> Limits {
118 let size = size.into();
119
120 let min = Size::new(
121 (self.min().width - size.width).max(0.0),
122 (self.min().height - size.height).max(0.0),
123 );
124
125 let max = Size::new(
126 (self.max().width - size.width).max(0.0),
127 (self.max().height - size.height).max(0.0),
128 );
129
130 Limits {
131 min,
132 max,
133 compression: self.compression,
134 }
135 }
136
137 pub fn loose(&self) -> Limits {
139 Limits {
140 min: Size::ZERO,
141 max: self.max,
142 compression: self.compression,
143 }
144 }
145
146 pub fn resolve(
150 &self,
151 width: impl Into<Length>,
152 height: impl Into<Length>,
153 intrinsic_size: Size,
154 ) -> Size {
155 let width = match width.into() {
156 Length::Fill | Length::FillPortion(_) if !self.compression.width => self.max.width,
157 Length::Fixed(amount) => amount.min(self.max.width).max(self.min.width),
158 _ => intrinsic_size.width.min(self.max.width).max(self.min.width),
159 };
160
161 let height = match height.into() {
162 Length::Fill | Length::FillPortion(_) if !self.compression.height => self.max.height,
163 Length::Fixed(amount) => amount.min(self.max.height).max(self.min.height),
164 _ => intrinsic_size
165 .height
166 .min(self.max.height)
167 .max(self.min.height),
168 };
169
170 Size::new(width, height)
171 }
172}