Skip to main content

stynx_code_tui/layout/
main_layout.rs

1use ratatui::layout::{Constraint, Layout, Rect};
2
3pub struct LayoutResult {
4    pub sidebar: Option<Rect>,
5    pub messages: Rect,
6    pub thinking: Option<Rect>,
7    pub input: Rect,
8    pub footer: Rect,
9}
10
11pub struct MainLayout;
12
13impl MainLayout {
14    pub const SIDEBAR_WIDTH: u16 = 42;
15
16    pub fn split(
17        area: Rect,
18        sidebar_visible: bool,
19        input_lines: usize,
20        thinking_lines: usize,
21    ) -> LayoutResult {
22        let (sidebar, main) = if sidebar_visible && area.width > Self::SIDEBAR_WIDTH + 20 {
23            let chunks = Layout::horizontal([
24                Constraint::Length(Self::SIDEBAR_WIDTH),
25                Constraint::Min(1),
26            ])
27            .split(area);
28            (Some(chunks[0]), chunks[1])
29        } else {
30            (None, area)
31        };
32
33        let content = input_lines.clamp(1, 8) as u16;
34        let input_h = (content + 2).min(main.height.saturating_sub(4));
35        let thinking_h: u16 = if thinking_lines == 0 {
36            0
37        } else {
38            (1 + thinking_lines.min(4)) as u16
39        };
40
41        if thinking_h > 0 {
42            let rows = Layout::vertical([
43                Constraint::Min(1),
44                Constraint::Length(thinking_h),
45                Constraint::Length(input_h),
46                Constraint::Length(1),
47            ])
48            .split(main);
49            LayoutResult {
50                sidebar,
51                messages: rows[0],
52                thinking: Some(rows[1]),
53                input: rows[2],
54                footer: rows[3],
55            }
56        } else {
57            let rows = Layout::vertical([
58                Constraint::Min(1),
59                Constraint::Length(input_h),
60                Constraint::Length(1),
61            ])
62            .split(main);
63            LayoutResult {
64                sidebar,
65                messages: rows[0],
66                thinking: None,
67                input: rows[1],
68                footer: rows[2],
69            }
70        }
71    }
72}