TUI #1

Merged
shaunrd0 merged 73 commits from ui into master 2026-01-25 20:57:37 +00:00
7 changed files with 57 additions and 20 deletions
Showing only changes of commit 6c2f3f9005 - Show all commits

View File

@ -121,8 +121,23 @@ impl<'a> App<'a> {
.render(area, buf); .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) { fn change_focus(&mut self, focus: AppComponent) {
info!(target:Self::id(), "Changing widget focus to {:?}", focus); info!(target:Self::id(), "Changing widget focus to {:?}", focus);
self.clear_focus();
match focus { match focus {
AppEditor => match self.editor_tabs.current_editor_mut() { AppEditor => match self.editor_tabs.current_editor_mut() {
None => { None => {

View File

@ -3,6 +3,7 @@
use anyhow::Result; use anyhow::Result;
use log::trace; use log::trace;
use ratatui::crossterm::event::{Event, KeyEvent, MouseEvent}; use ratatui::crossterm::event::{Event, KeyEvent, MouseEvent};
use ratatui::style::Color;
pub enum Action { pub enum Action {
/// Exit the application. /// Exit the application.
@ -81,10 +82,20 @@ pub enum Focus {
Inactive, Inactive,
} }
impl Focus {
pub(crate) fn get_active_color(&self) -> Color {
match self {
Focus::Active => Color::LightYellow,
Focus::Inactive => Color::White,
}
}
}
pub trait FocusState { pub trait FocusState {
fn with_focus(self, focus: Focus) -> Self; fn with_focus(self, focus: Focus) -> Self;
fn set_focus(&mut self, focus: Focus); fn set_focus(&mut self, focus: Focus);
fn toggle_focus(&mut self); fn toggle_focus(&mut self);
fn get_active_color(&self) -> Color;
} }
impl FocusState for ComponentState { impl FocusState for ComponentState {
@ -105,4 +116,8 @@ impl FocusState for ComponentState {
Focus::Inactive => self.set_focus(Focus::Active), Focus::Inactive => self.set_focus(Focus::Active),
} }
} }
fn get_active_color(&self) -> Color {
self.focus.get_active_color()
}
} }

View File

@ -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 anyhow::{Context, Result, bail};
use edtui::{ use edtui::{
EditorEventHandler, EditorState, EditorTheme, EditorView, LineNumbers, Lines, SyntaxHighlighter, EditorEventHandler, EditorState, EditorTheme, EditorView, LineNumbers, Lines, SyntaxHighlighter,
@ -86,7 +86,8 @@ impl Widget for &mut Editor {
.title_style(Style::default().fg(Color::Yellow)) .title_style(Style::default().fg(Color::Yellow))
.title_alignment(Alignment::Right) .title_alignment(Alignment::Right)
.borders(Borders::ALL) .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()) .syntax_highlighter(SyntaxHighlighter::new("dracula", lang).ok())

View File

@ -84,6 +84,7 @@ impl EditorTab {
.map(|f| f.to_string_lossy().to_string()) .map(|f| f.to_string_lossy().to_string())
.unwrap_or("Unknown".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) Tabs::new(tab_titles)
.select(self.current_editor) .select(self.current_editor)
.divider("|") .divider("|")

View File

@ -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 anyhow::{Context, Result, bail};
use log::trace; use log::trace;
use ratatui::buffer::Buffer; use ratatui::buffer::Buffer;
@ -101,11 +101,11 @@ impl<'a> Widget for &mut Explorer<'a> {
if let Ok(tree) = Tree::new(&self.tree_items.children()) { if let Ok(tree) = Tree::new(&self.tree_items.children()) {
let file_name = self.root_path.file_name().unwrap_or("Unknown".as_ref()); let file_name = self.root_path.file_name().unwrap_or("Unknown".as_ref());
StatefulWidget::render( StatefulWidget::render(
tree.style(Style::default()) tree.block(
.block(
Block::default() Block::default()
.borders(Borders::ALL) .borders(Borders::ALL)
.title(file_name.to_string_lossy()) .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_style(Style::default().fg(Color::Green))
.title_alignment(Alignment::Center), .title_alignment(Alignment::Center),
) )

View File

@ -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 log::{LevelFilter, trace};
use ratatui::buffer::Buffer; use ratatui::buffer::Buffer;
use ratatui::crossterm::event::{Event, KeyCode, KeyEvent}; use ratatui::crossterm::event::{Event, KeyCode, KeyEvent};
@ -42,6 +42,7 @@ impl Widget for &Logger {
Self: Sized, Self: Sized,
{ {
TuiLoggerSmartWidget::default() TuiLoggerSmartWidget::default()
.border_style(Style::default().fg(self.component_state.get_active_color()))
.style_error(Style::default().fg(Color::Red)) .style_error(Style::default().fg(Color::Red))
.style_debug(Style::default().fg(Color::Green)) .style_debug(Style::default().fg(Color::Green))
.style_warn(Style::default().fg(Color::Yellow)) .style_warn(Style::default().fg(Color::Yellow))

View File

@ -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::{ use crate::tui::menu_bar::MenuBarItemOption::{
About, Exit, Reload, Save, ShowHideExplorer, ShowHideLogger, About, Exit, Reload, Save, ShowHideExplorer, ShowHideLogger,
}; };
@ -108,7 +108,11 @@ impl MenuBar {
}; };
Tabs::new(titles) Tabs::new(titles)
.style(tabs_style) .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) .highlight_style(highlight_style)
.select(self.selected as usize) .select(self.selected as usize)
.render(area, buf); .render(area, buf);