diff --git a/src/tui/app.rs b/src/tui/app.rs index 0371a32..9d0d220 100644 --- a/src/tui/app.rs +++ b/src/tui/app.rs @@ -121,8 +121,23 @@ impl<'a> App<'a> { .render(area, buf); } + fn clear_focus(&mut self) { + info!(target:Self::id(), "Clearing all widget focus"); + self.explorer.component_state.set_focus(Focus::Inactive); + self.explorer.component_state.set_focus(Focus::Inactive); + self.logger.component_state.set_focus(Focus::Inactive); + self.menu_bar.component_state.set_focus(Focus::Inactive); + match self.editor_tabs.current_editor_mut() { + None => { + error!(target:Self::id(), "Failed to get current Editor while clearing focus") + } + Some(editor) => editor.component_state.set_focus(Focus::Inactive), + } + } + fn change_focus(&mut self, focus: AppComponent) { info!(target:Self::id(), "Changing widget focus to {:?}", focus); + self.clear_focus(); match focus { AppEditor => match self.editor_tabs.current_editor_mut() { None => { diff --git a/src/tui/component.rs b/src/tui/component.rs index 8eca3ed..eb8bd14 100644 --- a/src/tui/component.rs +++ b/src/tui/component.rs @@ -3,6 +3,7 @@ use anyhow::Result; use log::trace; use ratatui::crossterm::event::{Event, KeyEvent, MouseEvent}; +use ratatui::style::Color; pub enum Action { /// Exit the application. @@ -81,10 +82,20 @@ pub enum Focus { Inactive, } +impl Focus { + pub(crate) fn get_active_color(&self) -> Color { + match self { + Focus::Active => Color::LightYellow, + Focus::Inactive => Color::White, + } + } +} + pub trait FocusState { fn with_focus(self, focus: Focus) -> Self; fn set_focus(&mut self, focus: Focus); fn toggle_focus(&mut self); + fn get_active_color(&self) -> Color; } impl FocusState for ComponentState { @@ -105,4 +116,8 @@ impl FocusState for ComponentState { Focus::Inactive => self.set_focus(Focus::Active), } } + + fn get_active_color(&self) -> Color { + self.focus.get_active_color() + } } diff --git a/src/tui/editor.rs b/src/tui/editor.rs index 9d1d0d3..76f772c 100644 --- a/src/tui/editor.rs +++ b/src/tui/editor.rs @@ -1,4 +1,4 @@ -use crate::tui::component::{Action, Component, ComponentState, Focus}; +use crate::tui::component::{Action, Component, ComponentState, Focus, FocusState}; use anyhow::{Context, Result, bail}; use edtui::{ EditorEventHandler, EditorState, EditorTheme, EditorView, LineNumbers, Lines, SyntaxHighlighter, @@ -86,7 +86,8 @@ impl Widget for &mut Editor { .title_style(Style::default().fg(Color::Yellow)) .title_alignment(Alignment::Right) .borders(Borders::ALL) - .padding(Padding::new(0, 0, 0, 1)), + .padding(Padding::new(0, 0, 0, 1)) + .style(Style::default().fg(self.component_state.get_active_color())), ), ) .syntax_highlighter(SyntaxHighlighter::new("dracula", lang).ok()) diff --git a/src/tui/editor_tab.rs b/src/tui/editor_tab.rs index 1864487..24d7ae5 100644 --- a/src/tui/editor_tab.rs +++ b/src/tui/editor_tab.rs @@ -84,6 +84,7 @@ impl EditorTab { .map(|f| f.to_string_lossy().to_string()) .unwrap_or("Unknown".to_string()) }); + // Don't set border color based on ComponentState::focus, the Editor renders the border. Tabs::new(tab_titles) .select(self.current_editor) .divider("|") diff --git a/src/tui/explorer.rs b/src/tui/explorer.rs index 63f4e5a..14a5585 100644 --- a/src/tui/explorer.rs +++ b/src/tui/explorer.rs @@ -1,4 +1,4 @@ -use crate::tui::component::{Action, Component, ComponentState, Focus}; +use crate::tui::component::{Action, Component, ComponentState, Focus, FocusState}; use anyhow::{Context, Result, bail}; use log::trace; use ratatui::buffer::Buffer; @@ -101,20 +101,20 @@ impl<'a> Widget for &mut Explorer<'a> { if let Ok(tree) = Tree::new(&self.tree_items.children()) { let file_name = self.root_path.file_name().unwrap_or("Unknown".as_ref()); StatefulWidget::render( - tree.style(Style::default()) - .block( - Block::default() - .borders(Borders::ALL) - .title(file_name.to_string_lossy()) - .title_style(Style::default().fg(Color::Green)) - .title_alignment(Alignment::Center), - ) - .highlight_style( - Style::new() - .fg(Color::Black) - .bg(Color::Rgb(57, 59, 64)) - .add_modifier(Modifier::BOLD), - ), + tree.block( + Block::default() + .borders(Borders::ALL) + .title(file_name.to_string_lossy()) + .border_style(Style::default().fg(self.component_state.get_active_color())) + .title_style(Style::default().fg(Color::Green)) + .title_alignment(Alignment::Center), + ) + .highlight_style( + Style::new() + .fg(Color::Black) + .bg(Color::Rgb(57, 59, 64)) + .add_modifier(Modifier::BOLD), + ), area, buf, &mut self.tree_state, diff --git a/src/tui/logger.rs b/src/tui/logger.rs index f82f9f4..a0d2403 100644 --- a/src/tui/logger.rs +++ b/src/tui/logger.rs @@ -1,4 +1,4 @@ -use crate::tui::component::{Action, Component, ComponentState, Focus}; +use crate::tui::component::{Action, Component, ComponentState, Focus, FocusState}; use log::{LevelFilter, trace}; use ratatui::buffer::Buffer; use ratatui::crossterm::event::{Event, KeyCode, KeyEvent}; @@ -42,6 +42,7 @@ impl Widget for &Logger { Self: Sized, { TuiLoggerSmartWidget::default() + .border_style(Style::default().fg(self.component_state.get_active_color())) .style_error(Style::default().fg(Color::Red)) .style_debug(Style::default().fg(Color::Green)) .style_warn(Style::default().fg(Color::Yellow)) diff --git a/src/tui/menu_bar.rs b/src/tui/menu_bar.rs index b3ee35d..d99fe5c 100644 --- a/src/tui/menu_bar.rs +++ b/src/tui/menu_bar.rs @@ -1,4 +1,4 @@ -use crate::tui::component::{Action, Component, ComponentState}; +use crate::tui::component::{Action, Component, ComponentState, FocusState}; use crate::tui::menu_bar::MenuBarItemOption::{ About, Exit, Reload, Save, ShowHideExplorer, ShowHideLogger, }; @@ -108,7 +108,11 @@ impl MenuBar { }; Tabs::new(titles) .style(tabs_style) - .block(Block::default().borders(Borders::ALL)) + .block( + Block::default() + .borders(Borders::ALL) + .border_style(Style::default().fg(self.component_state.get_active_color())), + ) .highlight_style(highlight_style) .select(self.selected as usize) .render(area, buf);