summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2020-11-25 20:36:03 +0200
committerManos Pitsidianakis <el13635@mail.ntua.gr>2020-11-25 21:19:22 +0200
commit6a5bb2e057d4c20ae12cc4488dc893d98cb6b2c9 (patch)
tree7a8549ac961ed37aa43a4276ec2db2391a1aac3b /src
parent311c1a8a9562232ada917854e2b4ccc67c2a08b9 (diff)
Add align_area() and Alignment enum
Diffstat (limited to 'src')
-rw-r--r--src/terminal/position.rs58
1 files changed, 58 insertions, 0 deletions
diff --git a/src/terminal/position.rs b/src/terminal/position.rs
index 0d38a8bc..6cdee508 100644
--- a/src/terminal/position.rs
+++ b/src/terminal/position.rs
@@ -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`
pub fn place_in_area(area: Area, (width, height): (usize, usize), upper: bool, left: bool) -> Area {
let (upper_x, upper_y) = upper_left!(area);