stynx_code_tui/layout/
main_layout.rs1use 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}