#![allow(dead_code, unused_variables)] use anyhow::Result; use log::trace; use ratatui::crossterm::event::{Event, KeyEvent, MouseEvent}; pub enum Action { /// Exit the application. Quit, /// The input was checked by the Component and had no effect. Noop, /// Pass input to another component or external handler. /// Similar to Noop with the added context that externally handled input may have had an impact. Pass, /// Save the current file. Save, /// The input was handled by a Component and should not be passed to the next component. Handled, OpenTab, } pub trait Component { fn handle_event(&mut self, event: Event) -> Result { match event { Event::Key(key_event) => self.handle_key_events(key_event), _ => Ok(Action::Noop), } } fn handle_key_events(&mut self, key: KeyEvent) -> Result { Ok(Action::Noop) } fn handle_mouse_events(&mut self, mouse: MouseEvent) -> Result { Ok(Action::Noop) } fn update(&mut self, action: Action) -> Result { Ok(Action::Noop) } /// Override this method for creating components that conditionally handle input. fn is_active(&self) -> bool { true } } #[derive(Debug, Clone, Default)] pub struct ComponentState { pub(crate) focus: Focus, pub(crate) help_text: String, } impl ComponentState { pub fn id() -> &'static str { "ComponentState" } fn new() -> Self { trace!(target:Self::id(), "Building {}", Self::id()); Self { focus: Focus::Active, help_text: String::new(), } } pub(crate) fn with_help_text(mut self, help_text: &str) -> Self { self.help_text = help_text.into(); self } } #[derive(Debug, Clone, Copy, Default, PartialEq)] pub enum Focus { Active, #[default] Inactive, } pub trait FocusState { fn with_focus(self, focus: Focus) -> Self; fn set_focus(&mut self, focus: Focus); fn toggle_focus(&mut self); } impl FocusState for ComponentState { fn with_focus(self, focus: Focus) -> Self { Self { focus, help_text: self.help_text, } } fn set_focus(&mut self, focus: Focus) { self.focus = focus; } fn toggle_focus(&mut self) { match self.focus { Focus::Active => self.set_focus(Focus::Inactive), Focus::Inactive => self.set_focus(Focus::Active), } } }