Add align_area() and Alignment enum

jmap-eventsource
Manos Pitsidianakis 2020-11-25 20:36:03 +02:00
parent 311c1a8a95
commit 6a5bb2e057
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
1 changed files with 58 additions and 0 deletions

View File

@ -157,6 +157,64 @@ pub fn center_area(area: Area, (width, height): (usize, usize)) -> Area {
) )
} }
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum Alignment {
/// Stretch to fill all space if possible, center if no meaningful way to stretch.
Fill,
/// Snap to left or top side, leaving space on right or bottom.
Start,
/// Snap to right or bottom side, leaving space on left or top.
End,
/// Center natural width of widget inside the allocation.
Center,
}
impl Default for Alignment {
fn default() -> Self {
Alignment::Center
}
}
/// Place given area of dimensions `(width, height)` inside `area` according to given alignment
pub fn align_area(
area: Area,
(width, height): (usize, usize),
vertical_alignment: Alignment,
horizontal_alignment: Alignment,
) -> Area {
let (top_x, width) = match horizontal_alignment {
Alignment::Center => (
{ std::cmp::max(width!(area) / 2, width / 2) - width / 2 },
width,
),
Alignment::Start => (0, width),
Alignment::End => (width!(area).saturating_sub(width), width!(area)),
Alignment::Fill => (0, width!(area)),
};
let (top_y, height) = match vertical_alignment {
Alignment::Center => (
{ std::cmp::max(height!(area) / 2, height / 2) - height / 2 },
height,
),
Alignment::Start => (0, height),
Alignment::End => (height!(area).saturating_sub(height), height!(area)),
Alignment::Fill => (0, height!(area)),
};
let (upper_x, upper_y) = upper_left!(area);
let (max_x, max_y) = bottom_right!(area);
(
(
std::cmp::min(max_x, upper_x + top_x),
std::cmp::min(max_y, upper_y + top_y),
),
(
std::cmp::min(max_x, upper_x + top_x + width),
std::cmp::min(max_y, upper_y + top_y + height),
),
)
}
/// Place box given by `(width, height)` in corner of `area` /// Place box given by `(width, height)` in corner of `area`
pub fn place_in_area(area: Area, (width, height): (usize, usize), upper: bool, left: bool) -> Area { pub fn place_in_area(area: Area, (width, height): (usize, usize), upper: bool, left: bool) -> Area {
let (upper_x, upper_y) = upper_left!(area); let (upper_x, upper_y) = upper_left!(area);