From b6c4d3308dd4a36b41408d690ef7c35132bfadff Mon Sep 17 00:00:00 2001 From: filipriec Date: Wed, 16 Apr 2025 00:11:41 +0200 Subject: [PATCH] its now using enum fully for the highlight mode --- client/src/components/auth/login.rs | 9 +-- client/src/components/auth/register.rs | 9 +-- client/src/components/form/form.rs | 9 +-- client/src/components/handlers/canvas.rs | 88 +++++++++++++---------- client/src/modes/handlers/event.rs | 29 +++----- client/src/modes/handlers/mode_manager.rs | 3 +- client/src/state/app.rs | 1 + client/src/state/app/highlight.rs | 20 ++++++ client/src/state/pages/form.rs | 9 +-- client/src/ui/handlers/render.rs | 17 ++--- client/src/ui/handlers/ui.rs | 4 +- 11 files changed, 103 insertions(+), 95 deletions(-) create mode 100644 client/src/state/app/highlight.rs diff --git a/client/src/components/auth/login.rs b/client/src/components/auth/login.rs index e8bb761..e4509fc 100644 --- a/client/src/components/auth/login.rs +++ b/client/src/components/auth/login.rs @@ -12,6 +12,7 @@ use ratatui::{ widgets::{Block, BorderType, Borders, Paragraph}, Frame, }; +use crate::state::app::highlight::HighlightState; pub fn render_login( f: &mut Frame, @@ -20,9 +21,7 @@ pub fn render_login( login_state: &LoginState, app_state: &AppState, is_edit_mode: bool, - is_highlight_mode: bool, - is_linewise_highlight: bool, - highlight_anchor: Option<(usize, usize)>, + highlight_state: &HighlightState, ) { // Main container let block = Block::default() @@ -59,9 +58,7 @@ pub fn render_login( &[&login_state.username, &login_state.password], theme, is_edit_mode, - is_highlight_mode, - is_linewise_highlight, - highlight_anchor, + highlight_state, ); // --- ERROR MESSAGE --- diff --git a/client/src/components/auth/register.rs b/client/src/components/auth/register.rs index 9898aa5..f7dee7b 100644 --- a/client/src/components/auth/register.rs +++ b/client/src/components/auth/register.rs @@ -14,6 +14,7 @@ use ratatui::{ widgets::{Block, BorderType, Borders, Paragraph}, Frame, }; +use crate::state::app::highlight::HighlightState; pub fn render_register( f: &mut Frame, @@ -22,9 +23,7 @@ pub fn render_register( state: &RegisterState, // Use RegisterState app_state: &AppState, is_edit_mode: bool, - is_highlight_mode: bool, - is_linewise_highlight: bool, - highlight_anchor: Option<(usize, usize)>, + highlight_state: &HighlightState, ) { let block = Block::default() .borders(Borders::ALL) @@ -67,9 +66,7 @@ pub fn render_register( &state.inputs().iter().map(|s| *s).collect::>(), // Pass inputs directly theme, is_edit_mode, - is_highlight_mode, - is_linewise_highlight, - highlight_anchor, + highlight_state, ); // --- HELP TEXT --- diff --git a/client/src/components/form/form.rs b/client/src/components/form/form.rs index c60825d..2210945 100644 --- a/client/src/components/form/form.rs +++ b/client/src/components/form/form.rs @@ -7,6 +7,7 @@ use ratatui::{ }; use crate::config::colors::themes::Theme; use crate::state::pages::canvas_state::CanvasState; +use crate::state::app::highlight::HighlightState; use crate::components::handlers::canvas::render_canvas; pub fn render_form( @@ -18,9 +19,7 @@ pub fn render_form( inputs: &[&String], theme: &Theme, is_edit_mode: bool, - is_highlight_mode: bool, - is_linewise_highlight: bool, - highlight_anchor: Option<(usize, usize)>, + highlight_state: &HighlightState, total_count: u64, current_position: u64, ) { @@ -65,8 +64,6 @@ pub fn render_form( inputs, theme, is_edit_mode, - is_highlight_mode, - is_linewise_highlight, - highlight_anchor, + highlight_state, ); } diff --git a/client/src/components/handlers/canvas.rs b/client/src/components/handlers/canvas.rs index 73cb818..e69d129 100644 --- a/client/src/components/handlers/canvas.rs +++ b/client/src/components/handlers/canvas.rs @@ -9,6 +9,7 @@ use ratatui::{ }; use crate::config::colors::themes::Theme; use crate::state::pages::canvas_state::CanvasState; +use crate::state::app::highlight::HighlightState; // Ensure correct import path use std::cmp::{min, max}; pub fn render_canvas( @@ -20,10 +21,9 @@ pub fn render_canvas( inputs: &[&String], theme: &Theme, is_edit_mode: bool, - is_highlight_mode: bool, - is_linewise_highlight: bool, - highlight_anchor: Option<(usize, usize)>, + highlight_state: &HighlightState, // Using the enum state ) -> Option { + // ... (column split, container styling, block dimensions - unchanged) ... let columns = Layout::default() .direction(Direction::Horizontal) .constraints([Constraint::Percentage(30), Constraint::Percentage(70)]) @@ -72,6 +72,7 @@ pub fn render_canvas( }); } + // Render inputs and cursor for (i, input) in inputs.iter().enumerate() { let is_active = i == *current_field_idx; @@ -81,28 +82,20 @@ pub fn render_canvas( let line: Line; - if is_highlight_mode && highlight_anchor.is_some() { - let (anchor_field, anchor_char) = highlight_anchor.unwrap(); - let start_field = min(anchor_field, *current_field_idx); - let end_field = max(anchor_field, *current_field_idx); - - let highlight_style = Style::default() - .fg(theme.highlight) - .bg(theme.highlight_bg) - .add_modifier(Modifier::BOLD); - let normal_style_in_highlight = Style::default().fg(theme.highlight); - let normal_style_outside = Style::default().fg(theme.fg); - - if is_linewise_highlight { - if i >= start_field && i <= end_field { - line = Line::from(Span::styled(text, highlight_style)); - } else { - line = Line::from(Span::styled( - text, - if is_active { normal_style_in_highlight } else { normal_style_outside } - )); - } - } else { + // --- Use match on the highlight_state enum --- + match highlight_state { + HighlightState::Off => { + // Not in highlight mode, render normally + line = Line::from(Span::styled( + text, + if is_active { Style::default().fg(theme.highlight) } else { Style::default().fg(theme.fg) } + )); + } + HighlightState::Characterwise { anchor } => { + // --- Character-wise Highlight Logic --- + let (anchor_field, anchor_char) = *anchor; // Dereference the tuple from the enum + let start_field = min(anchor_field, *current_field_idx); + let end_field = max(anchor_field, *current_field_idx); let (start_char, end_char) = if anchor_field == *current_field_idx { (min(anchor_char, current_cursor_pos), max(anchor_char, current_cursor_pos)) } else if anchor_field < *current_field_idx { @@ -111,8 +104,13 @@ pub fn render_canvas( (current_cursor_pos, anchor_char) }; + let highlight_style = Style::default().fg(theme.highlight).bg(theme.highlight_bg).add_modifier(Modifier::BOLD); + let normal_style_in_highlight = Style::default().fg(theme.highlight); + let normal_style_outside = Style::default().fg(theme.fg); + if i >= start_field && i <= end_field { - if start_field == end_field { + // This line is within the character-wise highlight range + if start_field == end_field { // Case 1: Single Line Highlight let safe_start = start_char.min(text_len); let safe_end = end_char.min(text_len); let before: String = text.chars().take(safe_start).collect(); @@ -123,7 +121,7 @@ pub fn render_canvas( Span::styled(highlighted, highlight_style), Span::styled(after, normal_style_in_highlight), ]); - } else if i == start_field { + } else if i == start_field { // Case 2: Multi-Line Highlight - Start Line let safe_start = start_char.min(text_len); let before: String = text.chars().take(safe_start).collect(); let highlighted: String = text.chars().skip(safe_start).collect(); @@ -131,7 +129,7 @@ pub fn render_canvas( Span::styled(before, normal_style_in_highlight), Span::styled(highlighted, highlight_style), ]); - } else if i == end_field { + } else if i == end_field { // Case 4: Multi-Line Highlight - End Line let safe_end = end_char.min(text_len); let highlighted: String = text.chars().take(safe_end).collect(); let after: String = text.chars().skip(safe_end).collect(); @@ -139,22 +137,37 @@ pub fn render_canvas( Span::styled(highlighted, highlight_style), Span::styled(after, normal_style_in_highlight), ]); - } else { - line = Line::from(Span::styled(text, highlight_style)); + } else { // Case 3: Multi-Line Highlight - Middle Line + line = Line::from(Span::styled(text, highlight_style)); // Highlight whole line } - } else { + } else { // Case 5: Line Outside Character-wise Highlight Range line = Line::from(Span::styled( text, if is_active { normal_style_in_highlight } else { normal_style_outside } )); } } - } else { - line = Line::from(Span::styled( - text, - if is_active { Style::default().fg(theme.highlight) } else { Style::default().fg(theme.fg) } - )); - }; + HighlightState::Linewise { anchor_line } => { + // --- Linewise Highlight Logic --- + let start_field = min(*anchor_line, *current_field_idx); // Dereference anchor_line + let end_field = max(*anchor_line, *current_field_idx); // Dereference anchor_line + let highlight_style = Style::default().fg(theme.highlight).bg(theme.highlight_bg).add_modifier(Modifier::BOLD); + let normal_style_in_highlight = Style::default().fg(theme.highlight); + let normal_style_outside = Style::default().fg(theme.fg); + + if i >= start_field && i <= end_field { + // Highlight the entire line + line = Line::from(Span::styled(text, highlight_style)); + } else { + // Line outside linewise highlight range + line = Line::from(Span::styled( + text, + // Use normal styling (active or inactive) + if is_active { normal_style_in_highlight } else { normal_style_outside } + )); + } + } + } // End match highlight_state let input_display = Paragraph::new(line).alignment(Alignment::Left); f.render_widget(input_display, input_rows[i]); @@ -169,3 +182,4 @@ pub fn render_canvas( active_field_input_rect } + diff --git a/client/src/modes/handlers/event.rs b/client/src/modes/handlers/event.rs index 5021510..5a1b040 100644 --- a/client/src/modes/handlers/event.rs +++ b/client/src/modes/handlers/event.rs @@ -20,6 +20,7 @@ use crate::tui::{ }; use crate::state::{ app::{ + highlight::HighlightState, state::AppState, buffer::{AppView, BufferState}, }, @@ -53,9 +54,7 @@ pub struct EventHandler { pub command_input: String, pub command_message: String, pub is_edit_mode: bool, - pub is_highlight_mode: bool, - pub is_linewise_highlight: bool, - pub highlight_anchor: Option<(usize, usize)>, + pub highlight_state: HighlightState, pub edit_mode_cooldown: bool, pub ideal_cursor_column: usize, pub key_sequence_tracker: KeySequenceTracker, @@ -69,9 +68,7 @@ impl EventHandler { command_input: String::new(), command_message: String::new(), is_edit_mode: false, - is_highlight_mode: false, - is_linewise_highlight: false, - highlight_anchor: None, + highlight_state: HighlightState::Off, edit_mode_cooldown: false, ideal_cursor_column: 0, key_sequence_tracker: KeySequenceTracker::new(800), @@ -220,29 +217,27 @@ impl EventHandler { AppMode::ReadOnly => { // Check for Linewise highlight first if config.get_read_only_action_for_key(key_code, modifiers) == Some("enter_highlight_mode_linewise") - && ModeManager::can_enter_highlight_mode(current_mode) { - self.is_highlight_mode = true; - self.is_linewise_highlight = true; // Set linewise flag + && ModeManager::can_enter_highlight_mode(current_mode) + { let current_field_index = if app_state.ui.show_login { login_state.current_field() } else if app_state.ui.show_register { register_state.current_field() } else { form_state.current_field() }; - // For linewise, anchor char doesn't matter, use 0 - self.highlight_anchor = Some((current_field_index, 0)); + self.highlight_state = HighlightState::Linewise { anchor_line: current_field_index }; self.command_message = "-- LINE HIGHLIGHT --".to_string(); return Ok(EventOutcome::Ok(self.command_message.clone())); } // Check for Character-wise highlight else if config.get_read_only_action_for_key(key_code, modifiers) == Some("enter_highlight_mode") - && ModeManager::can_enter_highlight_mode(current_mode) { - self.is_highlight_mode = true; - self.is_linewise_highlight = false; // Ensure linewise is false + && ModeManager::can_enter_highlight_mode(current_mode) + { let current_field_index = if app_state.ui.show_login { login_state.current_field() } else if app_state.ui.show_register { register_state.current_field() } else { form_state.current_field() }; let current_cursor_pos = if app_state.ui.show_login { login_state.current_cursor_pos() } else if app_state.ui.show_register { register_state.current_cursor_pos() } else { form_state.current_cursor_pos() }; - self.highlight_anchor = Some((current_field_index, current_cursor_pos)); + let anchor = (current_field_index, current_cursor_pos); + self.highlight_state = HighlightState::Characterwise { anchor }; self.command_message = "-- HIGHLIGHT --".to_string(); return Ok(EventOutcome::Ok(self.command_message.clone())); } @@ -337,9 +332,7 @@ impl EventHandler { AppMode::Highlight => { if config.get_highlight_action_for_key(key_code, modifiers) == Some("exit_highlight_mode") { - self.is_highlight_mode = false; - self.highlight_anchor = None; - self.command_message = "Exited highlight mode".to_string(); + self.highlight_state = HighlightState::Off; terminal.set_cursor_style(SetCursorStyle::SteadyBlock)?; return Ok(EventOutcome::Ok(self.command_message.clone())); } diff --git a/client/src/modes/handlers/mode_manager.rs b/client/src/modes/handlers/mode_manager.rs index 2114e9c..4af0f30 100644 --- a/client/src/modes/handlers/mode_manager.rs +++ b/client/src/modes/handlers/mode_manager.rs @@ -1,6 +1,7 @@ // src/modes/handlers/mode_manager.rs use crate::state::app::state::AppState; use crate::modes::handlers::event::EventHandler; +use crate::state::app::highlight::HighlightState; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum AppMode { @@ -20,7 +21,7 @@ impl ModeManager { return AppMode::Command; } - if event_handler.is_highlight_mode { + if !matches!(event_handler.highlight_state, HighlightState::Off) { return AppMode::Highlight; } diff --git a/client/src/state/app.rs b/client/src/state/app.rs index bf37c84..caf30f1 100644 --- a/client/src/state/app.rs +++ b/client/src/state/app.rs @@ -2,3 +2,4 @@ pub mod state; pub mod buffer; +pub mod highlight; diff --git a/client/src/state/app/highlight.rs b/client/src/state/app/highlight.rs new file mode 100644 index 0000000..28f9968 --- /dev/null +++ b/client/src/state/app/highlight.rs @@ -0,0 +1,20 @@ +// src/state/app/highlight.rs + +/// Represents the different states of text highlighting. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum HighlightState { + /// Highlighting is inactive. + Off, + /// Highlighting character by character. Stores the anchor point (line index, char index). + Characterwise { anchor: (usize, usize) }, + /// Highlighting line by line. Stores the anchor line index. + Linewise { anchor_line: usize }, +} + +impl Default for HighlightState { + /// The default state is no highlighting. + fn default() -> Self { + HighlightState::Off + } +} + diff --git a/client/src/state/pages/form.rs b/client/src/state/pages/form.rs index 4d3647c..000649e 100644 --- a/client/src/state/pages/form.rs +++ b/client/src/state/pages/form.rs @@ -2,6 +2,7 @@ use crate::config::colors::themes::Theme; use ratatui::layout::Rect; use ratatui::Frame; +use crate::state::app::highlight::HighlightState; use crate::state::pages::canvas_state::CanvasState; pub struct FormState { @@ -33,9 +34,7 @@ impl FormState { area: Rect, theme: &Theme, is_edit_mode: bool, - is_highlight_mode: bool, - is_linewise_highlight: bool, - highlight_anchor: Option<(usize, usize)>, + highlight_state: &HighlightState, total_count: u64, current_position: u64, ) { @@ -51,9 +50,7 @@ impl FormState { &values, theme, is_edit_mode, - is_highlight_mode, - is_linewise_highlight, - highlight_anchor, + highlight_state, total_count, current_position, ); diff --git a/client/src/ui/handlers/render.rs b/client/src/ui/handlers/render.rs index 13b9f94..8909d6e 100644 --- a/client/src/ui/handlers/render.rs +++ b/client/src/ui/handlers/render.rs @@ -21,6 +21,7 @@ use crate::state::pages::intro::IntroState; use crate::state::app::buffer::BufferState; use crate::state::app::state::AppState; use crate::state::pages::admin::AdminState; +use crate::state::app::highlight::HighlightState; pub fn render_ui( f: &mut Frame, @@ -33,9 +34,7 @@ pub fn render_ui( buffer_state: &BufferState, theme: &Theme, is_edit_mode: bool, - is_highlight_mode: bool, - is_linewise_highlight: bool, - highlight_anchor: Option<(usize, usize)>, + highlight_state: &HighlightState, total_count: u64, current_position: u64, current_dir: &str, @@ -95,9 +94,7 @@ pub fn render_ui( register_state, app_state, register_state.current_field < 4, - is_highlight_mode, - is_linewise_highlight, - highlight_anchor, + highlight_state, ); } else if app_state.ui.show_login { render_login( @@ -107,9 +104,7 @@ pub fn render_ui( login_state, app_state, login_state.current_field < 2, - is_highlight_mode, - is_linewise_highlight, - highlight_anchor, + highlight_state, ); } else if app_state.ui.show_admin { crate::components::admin::admin_panel::render_admin_panel( @@ -174,9 +169,7 @@ pub fn render_ui( &values, theme, is_edit_mode, - is_highlight_mode, - is_linewise_highlight, - highlight_anchor, + highlight_state, total_count, current_position, ); diff --git a/client/src/ui/handlers/ui.rs b/client/src/ui/handlers/ui.rs index a59f14d..b8a4dc0 100644 --- a/client/src/ui/handlers/ui.rs +++ b/client/src/ui/handlers/ui.rs @@ -91,9 +91,7 @@ pub async fn run_ui() -> Result<(), Box> { &buffer_state, &theme, is_edit_mode, - event_handler.is_highlight_mode, - event_handler.is_linewise_highlight, - event_handler.highlight_anchor, + &event_handler.highlight_state, app_state.total_count, app_state.current_position, &app_state.current_dir,