dialog movement fixed

This commit is contained in:
filipriec
2025-04-10 14:13:39 +02:00
parent 5da9f5aaf4
commit 0d1a0be1a0
3 changed files with 77 additions and 51 deletions

View File

@@ -1,2 +1,3 @@
// src/client/modes/general.rs // src/client/modes/general.rs
pub mod navigation; pub mod navigation;
pub mod dialog;

View File

@@ -0,0 +1,71 @@
// src/modes/general/dialog.rs
use crossterm::event::{Event, KeyCode, KeyEvent};
use crate::config::binds::config::Config;
use crate::state::state::AppState;
use crate::modes::handlers::event::EventOutcome; // Use EventOutcome from event handler
/// Handles key events specifically when a dialog is active.
/// Returns Some(Result<EventOutcome, Error>) if the event was handled (consumed),
/// otherwise returns None.
pub async fn handle_dialog_event(
event: &Event,
config: &Config,
app_state: &mut AppState,
) -> Option<Result<EventOutcome, Box<dyn std::error::Error>>> {
if let Event::Key(key) = event {
// Always allow Esc to dismiss
if key.code == KeyCode::Esc {
app_state.hide_dialog();
return Some(Ok(EventOutcome::Ok("Dialog dismissed".to_string())));
}
// Check general bindings for dialog actions
if let Some(action) = config.get_general_action(key.code, key.modifiers) {
match action {
"move_up" | "previous_option" => {
let current_index = app_state.ui.dialog.dialog_active_button_index;
let num_buttons = app_state.ui.dialog.dialog_buttons.len();
if num_buttons > 0 && current_index < num_buttons - 1 {
app_state.ui.dialog.dialog_active_button_index += 1;
}
return Some(Ok(EventOutcome::Ok(String::new())));
}
"move_down" | "next_option" => {
let current_index = app_state.ui.dialog.dialog_active_button_index;
if current_index > 0 {
app_state.ui.dialog.dialog_active_button_index -= 1;
}
return Some(Ok(EventOutcome::Ok(String::new())));
}
"select" => {
let selected_index = app_state.ui.dialog.dialog_active_button_index;
let selected_label = app_state.get_active_dialog_button_label().unwrap_or("").to_string();
let mut message = format!("Dialog '{}' selected", selected_label);
// --- Add specific actions based on button index or label ---
if selected_label.eq_ignore_ascii_case("menu") {
app_state.ui.show_login = false;
app_state.ui.show_intro = true;
// focus_outside_canvas is handled by hide_dialog
message = "Returning to menu".to_string();
} else if selected_label.eq_ignore_ascii_case("exit") {
app_state.hide_dialog();
return Some(Ok(EventOutcome::Exit("Exiting via dialog".to_string())));
}
// --- End specific actions ---
app_state.hide_dialog(); // Hide dialog after processing selection
return Some(Ok(EventOutcome::Ok(message))); // Consume event
}
_ => {} // Ignore other general actions when dialog is shown
}
}
// If it was a key event but not handled above, consume it
Some(Ok(EventOutcome::Ok(String::new())))
} else {
// If it wasn't a key event, consume it too while dialog is active
Some(Ok(EventOutcome::Ok(String::new())))
}
}

View File

@@ -17,7 +17,7 @@ use crate::tui::functions::{intro, admin};
use crate::modes::{ use crate::modes::{
common::command_mode, common::command_mode,
canvas::{edit, read_only, common_mode}, canvas::{edit, read_only, common_mode},
general::navigation, general::{navigation, dialog},
}; };
use crate::config::binds::key_sequences::KeySequenceTracker; use crate::config::binds::key_sequences::KeySequenceTracker;
use crate::modes::handlers::mode_manager::{ModeManager, AppMode}; use crate::modes::handlers::mode_manager::{ModeManager, AppMode};
@@ -72,58 +72,12 @@ impl EventHandler {
let current_mode = ModeManager::derive_mode(app_state, self); let current_mode = ModeManager::derive_mode(app_state, self);
app_state.update_mode(current_mode); app_state.update_mode(current_mode);
// --- DIALOG MODALITY CHECK --- // --- DIALOG MODALITY ---
// If a dialog is showing, intercept and handle ONLY dialog inputs. // If a dialog is showing, intercept and handle ONLY dialog inputs.
if app_state.ui.dialog.dialog_show { if app_state.ui.dialog.dialog_show {
if let Event::Key(key) = event { if let Some(dialog_result) = dialog::handle_dialog_event(&event, config, app_state).await {
// Always allow Esc to dismiss return dialog_result;
if key.code == KeyCode::Esc { }
app_state.hide_dialog();
return Ok(EventOutcome::Ok("Dialog dismissed".to_string()));
}
// Check general bindings for dialog actions
if let Some(action) = config.get_general_action(key.code, key.modifiers) {
match action {
"move_down" | "move_right" => {
let current_index = app_state.ui.dialog.dialog_active_button_index;
let num_buttons = app_state.ui.dialog.dialog_buttons.len();
if num_buttons > 0 && current_index < num_buttons - 1 {
app_state.ui.dialog.dialog_active_button_index += 1;
}
return Ok(EventOutcome::Ok(String::new())); // Consume event
}
"move_up" | "move_left" => {
let current_index = app_state.ui.dialog.dialog_active_button_index;
if current_index > 0 {
app_state.ui.dialog.dialog_active_button_index -= 1;
}
return Ok(EventOutcome::Ok(String::new())); // Consume event
}
"select" => {
let selected_index = app_state.ui.dialog.dialog_active_button_index;
let selected_label = app_state.get_active_dialog_button_label().unwrap_or("").to_string();
let mut message = format!("Dialog '{}' selected", selected_label);
// --- Add specific actions based on button index or label ---
if selected_label.eq_ignore_ascii_case("menu") {
app_state.ui.show_login = false;
app_state.ui.show_intro = true;
// focus_outside_canvas is handled by hide_dialog
message = "Returning to menu".to_string();
} else if selected_label.eq_ignore_ascii_case("exit") {
app_state.hide_dialog();
return Ok(EventOutcome::Exit("Exiting via dialog".to_string()));
}
// --- End specific actions ---
app_state.hide_dialog(); // Hide dialog after processing selection
return Ok(EventOutcome::Ok(message)); // Consume event
}
_ => {} // Ignore other general actions when dialog is shown
}
}
}
// If dialog is shown, consume any event not handled above
return Ok(EventOutcome::Ok(String::new())); return Ok(EventOutcome::Ok(String::new()));
} }
// --- END DIALOG MODALITY CHECK --- // --- END DIALOG MODALITY CHECK ---