rat_widget/layout/
layout_dialog.rs

1use crate::layout::GenericLayout;
2use ratatui::layout::{Constraint, Flex, Layout, Rect};
3use ratatui::widgets::Padding;
4
5#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
6pub enum DialogItem {
7    /// Area inside the border.
8    Inner,
9    /// Area where dialog content can be rendered.
10    Content,
11    /// Button area
12    Buttons,
13    /// Area for the nth button.
14    Button(usize),
15}
16
17/// Calculates a layout for a dialog with buttons.
18#[inline]
19pub fn layout_dialog<const N: usize>(
20    area: Rect,
21    padding: Padding,
22    buttons: [Constraint; N],
23    button_spacing: u16,
24    button_flex: Flex,
25) -> GenericLayout<DialogItem> {
26    let inner = Rect::new(
27        area.x + padding.left,
28        area.y + padding.top,
29        area.width.saturating_sub(padding.left + padding.right),
30        area.height.saturating_sub(padding.top + padding.bottom),
31    );
32
33    let l_content = Layout::vertical([
34        Constraint::Fill(1),
35        Constraint::Length(1),
36        Constraint::Length(1),
37    ])
38    .split(inner);
39
40    let l_buttons = Layout::horizontal(buttons)
41        .spacing(button_spacing)
42        .flex(button_flex)
43        .areas::<N>(l_content[2]);
44
45    let mut gen_layout = GenericLayout::new();
46    gen_layout.set_area(area);
47    gen_layout.set_page_size(area.as_size());
48    gen_layout.set_page_count(1);
49
50    gen_layout.add(DialogItem::Inner, inner, None, Rect::default());
51    gen_layout.add(DialogItem::Content, l_content[0], None, Rect::default());
52    gen_layout.add(DialogItem::Buttons, l_content[2], None, Rect::default());
53    for (n, area) in l_buttons.iter().enumerate() {
54        gen_layout.add(DialogItem::Button(n), *area, None, Rect::default());
55    }
56
57    gen_layout
58}