code_mesh_tui/components/
status_bar.rs1use ratatui::{
2 layout::Rect,
3 widgets::Paragraph,
4 style::Style,
5 text::{Line, Span},
6};
7use anyhow::Result;
8
9use crate::{
10 app::AppState,
11 renderer::Renderer,
12 theme::Theme,
13};
14
15pub struct StatusBar {
17 theme: Box<dyn Theme + Send + Sync>,
18 mode: String,
19 file_path: Option<String>,
20 cursor_position: (u16, u16),
21 selection_info: Option<String>,
22}
23
24impl StatusBar {
25 pub fn new(theme: &dyn Theme) -> Self {
27 Self {
28 theme: Box::new(crate::theme::DefaultTheme), mode: "NORMAL".to_string(),
30 file_path: None,
31 cursor_position: (0, 0),
32 selection_info: None,
33 }
34 }
35
36 pub async fn update(&mut self, state: &AppState) -> Result<()> {
38 self.mode = match state {
39 AppState::Running => "NORMAL".to_string(),
40 AppState::Chat => "CHAT".to_string(),
41 AppState::FileViewer => "FILE".to_string(),
42 AppState::CommandPalette => "COMMAND".to_string(),
43 AppState::Dialog => "DIALOG".to_string(),
44 AppState::Help => "HELP".to_string(),
45 AppState::Quitting => "QUIT".to_string(),
46 };
47 Ok(())
48 }
49
50 pub fn set_file_path(&mut self, path: Option<String>) {
52 self.file_path = path;
53 }
54
55 pub fn set_cursor_position(&mut self, x: u16, y: u16) {
57 self.cursor_position = (x, y);
58 }
59
60 pub fn set_selection_info(&mut self, info: Option<String>) {
62 self.selection_info = info;
63 }
64
65 pub fn update_theme(&mut self, theme: &dyn Theme) {
67 }
70
71 pub fn render(&self, renderer: &mut Renderer, area: Rect) {
73 let mode_style = Style::default()
74 .fg(self.theme.background())
75 .bg(self.theme.primary());
76
77 let file_style = Style::default()
78 .fg(self.theme.text())
79 .bg(self.theme.background_panel());
80
81 let cursor_style = Style::default()
82 .fg(self.theme.text_muted())
83 .bg(self.theme.background_panel());
84
85 let mut spans = vec![
87 Span::styled(format!(" {} ", self.mode), mode_style),
88 Span::raw(" "),
89 ];
90
91 if let Some(ref path) = self.file_path {
92 spans.push(Span::styled(format!(" {} ", path), file_style));
93 spans.push(Span::raw(" "));
94 }
95
96 spans.push(Span::styled(
98 format!(" {}:{} ", self.cursor_position.0, self.cursor_position.1),
99 cursor_style,
100 ));
101
102 if let Some(ref selection) = self.selection_info {
103 spans.push(Span::raw(" "));
104 spans.push(Span::styled(format!(" {} ", selection), cursor_style));
105 }
106
107 let status_line = Line::from(spans);
108
109 let paragraph = Paragraph::new(vec![status_line])
110 .style(Style::default().bg(self.theme.background_panel()));
111
112 renderer.render_widget(paragraph, area);
113 }
114}