Skip to main content

rat_widget/layout/
layout_dialog.rs

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