rat_widget/layout/
layout_outer.rs

1//!
2//! Constrains an area from its outside.
3//!
4use ratatui::layout::{Constraint, Layout, Position, Rect, Size};
5
6/// This lets you define the outer bounds of a target area.
7///
8/// The constraints are applied in this order.
9///
10/// * Constrain the left/right/top/bottom border outside the area.
11/// * Set a fixed position.
12/// * Constrain the width/height of the area.
13/// * Set a fixed size.
14///
15/// In the end it gives you the middle Rect.
16///
17#[derive(Debug, Default, Clone)]
18pub struct LayoutOuter {
19    pub left: Option<Constraint>,
20    pub top: Option<Constraint>,
21    pub right: Option<Constraint>,
22    pub bottom: Option<Constraint>,
23    pub position: Option<Position>,
24    pub width: Option<Constraint>,
25    pub height: Option<Constraint>,
26    pub size: Option<Size>,
27}
28
29impl LayoutOuter {
30    pub fn new() -> Self {
31        Self::default()
32    }
33
34    /// Margin constraint for the left side.
35    pub fn left(mut self, left: Constraint) -> Self {
36        self.left = Some(left);
37        self
38    }
39
40    /// Margin constraint for the top side.
41    pub fn top(mut self, top: Constraint) -> Self {
42        self.top = Some(top);
43        self
44    }
45
46    /// Margin constraint for the right side.
47    pub fn right(mut self, right: Constraint) -> Self {
48        self.right = Some(right);
49        self
50    }
51
52    /// Margin constraint for the bottom side.
53    pub fn bottom(mut self, bottom: Constraint) -> Self {
54        self.bottom = Some(bottom);
55        self
56    }
57
58    /// Put at a fixed position.
59    pub fn position(mut self, pos: Position) -> Self {
60        self.position = Some(pos);
61        self
62    }
63
64    /// Constraint for the width.
65    pub fn width(mut self, width: Constraint) -> Self {
66        self.width = Some(width);
67        self
68    }
69
70    /// Constraint for the height.
71    pub fn height(mut self, height: Constraint) -> Self {
72        self.height = Some(height);
73        self
74    }
75
76    /// Set at a fixed size.
77    pub fn size(mut self, size: Size) -> Self {
78        self.size = Some(size);
79        self
80    }
81
82    /// Calculate the area.
83    pub fn layout(&self, area: Rect) -> Rect {
84        let mut hor = [
85            Constraint::Length(0),
86            Constraint::Fill(1),
87            Constraint::Length(0),
88        ];
89        let mut ver = [
90            Constraint::Length(0),
91            Constraint::Fill(1),
92            Constraint::Length(0),
93        ];
94        if let Some(left) = self.left {
95            hor[0] = left;
96        }
97        if let Some(top) = self.top {
98            ver[0] = top;
99        }
100        if let Some(right) = self.right {
101            hor[2] = right;
102        }
103        if let Some(bottom) = self.bottom {
104            ver[2] = bottom;
105        }
106        if let Some(pos) = self.position {
107            ver[0] = Constraint::Length(pos.y);
108            hor[0] = Constraint::Length(pos.x);
109        }
110        if let Some(width) = self.width {
111            hor[1] = width;
112            hor[2] = Constraint::Fill(1);
113        }
114        if let Some(height) = self.height {
115            ver[1] = height;
116            ver[2] = Constraint::Fill(1);
117        }
118        if let Some(size) = self.size {
119            ver[1] = Constraint::Length(size.height);
120            ver[2] = Constraint::Fill(1);
121            hor[1] = Constraint::Length(size.width);
122            hor[2] = Constraint::Fill(1);
123        }
124
125        let h_layout = Layout::horizontal(hor).split(area);
126        let v_layout = Layout::vertical(ver).split(h_layout[1]);
127        v_layout[1]
128    }
129}