2023-01-05 18:51:48 +01:00
|
|
|
#![allow(clippy::manual_clamp)]
|
2020-11-23 17:19:21 +00:00
|
|
|
use crate::{Length, Padding, Size};
|
2019-11-10 06:05:20 +01:00
|
|
|
|
2019-11-22 19:36:57 +01:00
|
|
|
/// A set of size constraints for layouting.
|
2023-09-12 14:51:00 +02:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
2019-11-10 06:05:20 +01:00
|
|
|
pub struct Limits {
|
|
|
|
|
min: Size,
|
|
|
|
|
max: Size,
|
|
|
|
|
fill: Size,
|
|
|
|
|
}
|
2019-11-10 01:55:32 +01:00
|
|
|
|
|
|
|
|
impl Limits {
|
2019-11-22 19:36:57 +01:00
|
|
|
/// No limits
|
2019-11-10 06:05:20 +01:00
|
|
|
pub const NONE: Limits = Limits {
|
|
|
|
|
min: Size::ZERO,
|
|
|
|
|
max: Size::INFINITY,
|
|
|
|
|
fill: Size::INFINITY,
|
|
|
|
|
};
|
|
|
|
|
|
2019-11-22 19:36:57 +01:00
|
|
|
/// Creates new [`Limits`] with the given minimum and maximum [`Size`].
|
2019-11-29 21:24:52 -05:00
|
|
|
pub const fn new(min: Size, max: Size) -> Limits {
|
2019-11-10 06:05:20 +01:00
|
|
|
Limits {
|
|
|
|
|
min,
|
|
|
|
|
max,
|
|
|
|
|
fill: Size::INFINITY,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-22 19:36:57 +01:00
|
|
|
/// Returns the minimum [`Size`] of the [`Limits`].
|
2019-11-11 05:26:08 +01:00
|
|
|
pub fn min(&self) -> Size {
|
|
|
|
|
self.min
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-22 19:36:57 +01:00
|
|
|
/// Returns the maximum [`Size`] of the [`Limits`].
|
2019-11-11 05:26:08 +01:00
|
|
|
pub fn max(&self) -> Size {
|
|
|
|
|
self.max
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-10 04:58:13 +01:00
|
|
|
/// Returns the fill [`Size`] of the [`Limits`].
|
|
|
|
|
pub fn fill(&self) -> Size {
|
|
|
|
|
self.fill
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-22 19:36:57 +01:00
|
|
|
/// Applies a width constraint to the current [`Limits`].
|
2023-02-04 12:24:13 +01:00
|
|
|
pub fn width(mut self, width: impl Into<Length>) -> Limits {
|
|
|
|
|
match width.into() {
|
2019-11-10 06:05:20 +01:00
|
|
|
Length::Shrink => {
|
|
|
|
|
self.fill.width = self.min.width;
|
|
|
|
|
}
|
2019-12-30 18:37:13 +01:00
|
|
|
Length::Fill | Length::FillPortion(_) => {
|
2019-11-10 06:05:20 +01:00
|
|
|
self.fill.width = self.fill.width.min(self.max.width);
|
|
|
|
|
}
|
2023-02-04 12:24:13 +01:00
|
|
|
Length::Fixed(amount) => {
|
|
|
|
|
let new_width = amount.min(self.max.width).max(self.min.width);
|
2019-11-10 06:05:20 +01:00
|
|
|
|
|
|
|
|
self.min.width = new_width;
|
|
|
|
|
self.max.width = new_width;
|
|
|
|
|
self.fill.width = new_width;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-22 19:36:57 +01:00
|
|
|
/// Applies a height constraint to the current [`Limits`].
|
2023-02-04 12:24:13 +01:00
|
|
|
pub fn height(mut self, height: impl Into<Length>) -> Limits {
|
|
|
|
|
match height.into() {
|
2019-11-10 06:05:20 +01:00
|
|
|
Length::Shrink => {
|
|
|
|
|
self.fill.height = self.min.height;
|
|
|
|
|
}
|
2019-12-30 18:37:13 +01:00
|
|
|
Length::Fill | Length::FillPortion(_) => {
|
2019-11-10 06:05:20 +01:00
|
|
|
self.fill.height = self.fill.height.min(self.max.height);
|
|
|
|
|
}
|
2023-02-04 12:24:13 +01:00
|
|
|
Length::Fixed(amount) => {
|
2019-11-10 06:05:20 +01:00
|
|
|
let new_height =
|
2023-02-04 12:24:13 +01:00
|
|
|
amount.min(self.max.height).max(self.min.height);
|
2019-11-10 06:05:20 +01:00
|
|
|
|
|
|
|
|
self.min.height = new_height;
|
|
|
|
|
self.max.height = new_height;
|
|
|
|
|
self.fill.height = new_height;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-22 19:36:57 +01:00
|
|
|
/// Applies a minimum width constraint to the current [`Limits`].
|
2023-02-04 12:24:13 +01:00
|
|
|
pub fn min_width(mut self, min_width: f32) -> Limits {
|
|
|
|
|
self.min.width = self.min.width.max(min_width).min(self.max.width);
|
2019-11-10 06:05:20 +01:00
|
|
|
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-22 19:36:57 +01:00
|
|
|
/// Applies a maximum width constraint to the current [`Limits`].
|
2023-02-04 12:24:13 +01:00
|
|
|
pub fn max_width(mut self, max_width: f32) -> Limits {
|
|
|
|
|
self.max.width = self.max.width.min(max_width).max(self.min.width);
|
2019-11-10 06:05:20 +01:00
|
|
|
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-22 19:36:57 +01:00
|
|
|
/// Applies a minimum height constraint to the current [`Limits`].
|
2023-02-04 12:24:13 +01:00
|
|
|
pub fn min_height(mut self, min_height: f32) -> Limits {
|
|
|
|
|
self.min.height = self.min.height.max(min_height).min(self.max.height);
|
2019-11-22 19:36:57 +01:00
|
|
|
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Applies a maximum height constraint to the current [`Limits`].
|
2023-02-04 12:24:13 +01:00
|
|
|
pub fn max_height(mut self, max_height: f32) -> Limits {
|
|
|
|
|
self.max.height = self.max.height.min(max_height).max(self.min.height);
|
2019-11-10 06:05:20 +01:00
|
|
|
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-22 19:36:57 +01:00
|
|
|
/// Shrinks the current [`Limits`] to account for the given padding.
|
2020-11-23 17:19:21 +00:00
|
|
|
pub fn pad(&self, padding: Padding) -> Limits {
|
2023-02-17 16:09:49 +01:00
|
|
|
self.shrink(Size::new(padding.horizontal(), padding.vertical()))
|
2019-11-10 06:05:20 +01:00
|
|
|
}
|
|
|
|
|
|
2019-11-22 19:36:57 +01:00
|
|
|
/// Shrinks the current [`Limits`] by the given [`Size`].
|
2019-11-10 06:05:20 +01:00
|
|
|
pub fn shrink(&self, size: Size) -> Limits {
|
|
|
|
|
let min = Size::new(
|
|
|
|
|
(self.min().width - size.width).max(0.0),
|
|
|
|
|
(self.min().height - size.height).max(0.0),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
let max = Size::new(
|
|
|
|
|
(self.max().width - size.width).max(0.0),
|
|
|
|
|
(self.max().height - size.height).max(0.0),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
let fill = Size::new(
|
|
|
|
|
(self.fill.width - size.width).max(0.0),
|
|
|
|
|
(self.fill.height - size.height).max(0.0),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
Limits { min, max, fill }
|
|
|
|
|
}
|
2019-11-11 05:26:08 +01:00
|
|
|
|
2019-11-22 19:36:57 +01:00
|
|
|
/// Removes the minimum width constraint for the current [`Limits`].
|
2019-11-11 05:26:08 +01:00
|
|
|
pub fn loose(&self) -> Limits {
|
|
|
|
|
Limits {
|
|
|
|
|
min: Size::ZERO,
|
|
|
|
|
max: self.max,
|
|
|
|
|
fill: self.fill,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-22 19:36:57 +01:00
|
|
|
/// Computes the resulting [`Size`] that fits the [`Limits`] given the
|
|
|
|
|
/// intrinsic size of some content.
|
2019-11-11 05:26:08 +01:00
|
|
|
pub fn resolve(&self, intrinsic_size: Size) -> Size {
|
|
|
|
|
Size::new(
|
2023-01-05 16:40:45 +01:00
|
|
|
intrinsic_size
|
|
|
|
|
.width
|
|
|
|
|
.min(self.max.width)
|
|
|
|
|
.max(self.fill.width),
|
2019-11-11 05:26:08 +01:00
|
|
|
intrinsic_size
|
|
|
|
|
.height
|
2023-01-05 16:40:45 +01:00
|
|
|
.min(self.max.height)
|
|
|
|
|
.max(self.fill.height),
|
2019-11-11 05:26:08 +01:00
|
|
|
)
|
|
|
|
|
}
|
2019-11-10 01:55:32 +01:00
|
|
|
}
|