Skip to main content

stynx_code_tui/layout/
main_layout.rs

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