movement in the add_table now fixed

This commit is contained in:
filipriec
2025-05-25 12:40:19 +02:00
parent 0ab11a9bf9
commit b82f50b76b

View File

@@ -1,7 +1,7 @@
// src/functions/modes/read_only/add_table_ro.rs // src/functions/modes/read_only/add_table_ro.rs
use crate::config::binds::key_sequences::KeySequenceTracker; use crate::config::binds::key_sequences::KeySequenceTracker;
use crate::state::pages::add_table::AddTableState; use crate::state::pages::add_table::AddTableState;
use crate::state::pages::canvas_state::CanvasState; // Use trait for common actions use crate::state::pages::canvas_state::CanvasState;
use crate::state::app::state::AppState; use crate::state::app::state::AppState;
use anyhow::Result; use anyhow::Result;
@@ -80,41 +80,36 @@ pub async fn execute_action(
"move_up" => { "move_up" => {
key_sequence_tracker.reset(); key_sequence_tracker.reset();
let num_fields = AddTableState::INPUT_FIELD_COUNT; let num_fields = AddTableState::INPUT_FIELD_COUNT;
if num_fields == 0 { return Ok("No fields.".to_string()); } if num_fields == 0 {
*command_message = "No fields.".to_string();
return Ok(command_message.clone());
}
let current_field = state.current_field(); // Gets the index (0, 1, or 2) let current_field = state.current_field(); // Gets the index (0, 1, or 2)
if current_field > 0 { if current_field > 0 {
// This handles moving from field 2 -> 1, or 1 -> 0 // This handles moving from field 2 -> 1, or 1 -> 0
let new_field = current_field - 1; let new_field = current_field - 1;
state.set_current_field(new_field); state.set_current_field(new_field);
// ... (rest of the logic to set cursor position) ... let current_input = state.get_current_input();
let max_cursor_pos = current_input.len(); // Allow cursor at end
let new_pos = (*ideal_cursor_column).min(max_cursor_pos);
state.set_current_cursor_pos(new_pos);
*ideal_cursor_column = new_pos; // Update ideal column as cursor moved
*command_message = "".to_string(); // Clear message for successful internal navigation
} else { } else {
// --- THIS IS WHERE THE FIX GOES ---
// current_field is 0 (InputTableName), and user pressed Up. // current_field is 0 (InputTableName), and user pressed Up.
// We need to move focus *outside* the canvas. // Forbid moving up. Do not change focus or cursor.
*command_message = "At top of form.".to_string();
// Set the flag to indicate focus is leaving the canvas
app_state.ui.focus_outside_canvas = true;
// Decide which element gets focus. Based on your layout and the
// downward navigation (CancelButton wraps to InputTableName),
// moving up from InputTableName should likely go to CancelButton.
state.current_focus = crate::state::pages::add_table::AddTableFocus::CancelButton;
// Reset the sequence tracker as the action is complete
key_sequence_tracker.reset();
// Return a message indicating the focus change
return Ok("Focus moved above canvas".to_string());
// --- END FIX ---
} }
// If we moved within the canvas (e.g., 1 -> 0), return empty string Ok(command_message.clone())
Ok("".to_string())
} }
"move_down" => { "move_down" => {
key_sequence_tracker.reset(); key_sequence_tracker.reset();
let num_fields = AddTableState::INPUT_FIELD_COUNT; let num_fields = AddTableState::INPUT_FIELD_COUNT;
if num_fields == 0 { return Ok("No fields.".to_string()); } if num_fields == 0 {
*command_message = "No fields.".to_string();
return Ok(command_message.clone());
}
let current_field = state.current_field(); let current_field = state.current_field();
let last_field_index = num_fields - 1; let last_field_index = num_fields - 1;
@@ -125,16 +120,19 @@ pub async fn execute_action(
let max_cursor_pos = current_input.len(); // Allow cursor at end let max_cursor_pos = current_input.len(); // Allow cursor at end
let new_pos = (*ideal_cursor_column).min(max_cursor_pos); let new_pos = (*ideal_cursor_column).min(max_cursor_pos);
state.set_current_cursor_pos(new_pos); state.set_current_cursor_pos(new_pos);
*ideal_cursor_column = new_pos; // Update ideal column
*command_message = "".to_string();
} else { } else {
// Move focus outside canvas when moving down from the last field // Move focus outside canvas when moving down from the last field
app_state.ui.focus_outside_canvas = true; app_state.ui.focus_outside_canvas = true;
// Set focus to the first element outside canvas (AddColumnButton) // Set focus to the first element outside canvas (AddColumnButton)
state.current_focus = crate::state::pages::add_table::AddTableFocus::AddColumnButton; state.current_focus =
key_sequence_tracker.reset(); crate::state::pages::add_table::AddTableFocus::AddColumnButton;
return Ok("Focus moved below canvas".to_string()); *command_message = "Focus moved below canvas".to_string();
} }
Ok("".to_string()) Ok(command_message.clone())
} }
// ... (other actions like "move_first_line", "move_left", etc. remain the same) ...
"move_first_line" => { "move_first_line" => {
key_sequence_tracker.reset(); key_sequence_tracker.reset();
if AddTableState::INPUT_FIELD_COUNT > 0 { if AddTableState::INPUT_FIELD_COUNT > 0 {
@@ -145,7 +143,8 @@ pub async fn execute_action(
state.set_current_cursor_pos(new_pos); state.set_current_cursor_pos(new_pos);
*ideal_cursor_column = new_pos; // Update ideal column *ideal_cursor_column = new_pos; // Update ideal column
} }
Ok("".to_string()) *command_message = "".to_string();
Ok(command_message.clone())
} }
"move_last_line" => { "move_last_line" => {
key_sequence_tracker.reset(); key_sequence_tracker.reset();
@@ -159,14 +158,16 @@ pub async fn execute_action(
state.set_current_cursor_pos(new_pos); state.set_current_cursor_pos(new_pos);
*ideal_cursor_column = new_pos; // Update ideal column *ideal_cursor_column = new_pos; // Update ideal column
} }
Ok("".to_string()) *command_message = "".to_string();
Ok(command_message.clone())
} }
"move_left" => { "move_left" => {
let current_pos = state.current_cursor_pos(); let current_pos = state.current_cursor_pos();
let new_pos = current_pos.saturating_sub(1); let new_pos = current_pos.saturating_sub(1);
state.set_current_cursor_pos(new_pos); state.set_current_cursor_pos(new_pos);
*ideal_cursor_column = new_pos; *ideal_cursor_column = new_pos;
Ok("".to_string()) *command_message = "".to_string();
Ok(command_message.clone())
} }
"move_right" => { "move_right" => {
let current_input = state.get_current_input(); let current_input = state.get_current_input();
@@ -177,68 +178,90 @@ pub async fn execute_action(
state.set_current_cursor_pos(new_pos); state.set_current_cursor_pos(new_pos);
*ideal_cursor_column = new_pos; *ideal_cursor_column = new_pos;
} }
Ok("".to_string()) *command_message = "".to_string();
Ok(command_message.clone())
} }
"move_word_next" => { "move_word_next" => {
let current_input = state.get_current_input(); let current_input = state.get_current_input();
let new_pos = find_next_word_start(current_input, state.current_cursor_pos()); let new_pos = find_next_word_start(
current_input,
state.current_cursor_pos(),
);
let final_pos = new_pos.min(current_input.len()); // Allow cursor at end let final_pos = new_pos.min(current_input.len()); // Allow cursor at end
state.set_current_cursor_pos(final_pos); state.set_current_cursor_pos(final_pos);
*ideal_cursor_column = final_pos; *ideal_cursor_column = final_pos;
Ok("".to_string()) *command_message = "".to_string();
Ok(command_message.clone())
} }
"move_word_end" => { "move_word_end" => {
let current_input = state.get_current_input(); let current_input = state.get_current_input();
let current_pos = state.current_cursor_pos(); let current_pos = state.current_cursor_pos();
let new_pos = find_word_end(current_input, current_pos); let new_pos = find_word_end(current_input, current_pos);
// If find_word_end returns current_pos, try starting search from next char // If find_word_end returns current_pos, try starting search from next char
let final_pos = if new_pos == current_pos && current_pos < current_input.len() { let final_pos =
find_word_end(current_input, current_pos + 1) if new_pos == current_pos && current_pos < current_input.len() {
} else { find_word_end(current_input, current_pos + 1)
new_pos } else {
}; new_pos
};
let max_valid_index = current_input.len(); // Allow cursor at end let max_valid_index = current_input.len(); // Allow cursor at end
let clamped_pos = final_pos.min(max_valid_index); let clamped_pos = final_pos.min(max_valid_index);
state.set_current_cursor_pos(clamped_pos); state.set_current_cursor_pos(clamped_pos);
*ideal_cursor_column = clamped_pos; *ideal_cursor_column = clamped_pos;
Ok("".to_string()) *command_message = "".to_string();
Ok(command_message.clone())
} }
"move_word_prev" => { "move_word_prev" => {
let current_input = state.get_current_input(); let current_input = state.get_current_input();
let new_pos = find_prev_word_start(current_input, state.current_cursor_pos()); let new_pos = find_prev_word_start(
current_input,
state.current_cursor_pos(),
);
state.set_current_cursor_pos(new_pos); state.set_current_cursor_pos(new_pos);
*ideal_cursor_column = new_pos; *ideal_cursor_column = new_pos;
Ok("".to_string()) *command_message = "".to_string();
Ok(command_message.clone())
} }
"move_word_end_prev" => { "move_word_end_prev" => {
let current_input = state.get_current_input(); let current_input = state.get_current_input();
let new_pos = find_prev_word_end(current_input, state.current_cursor_pos()); let new_pos = find_prev_word_end(
current_input,
state.current_cursor_pos(),
);
state.set_current_cursor_pos(new_pos); state.set_current_cursor_pos(new_pos);
*ideal_cursor_column = new_pos; *ideal_cursor_column = new_pos;
Ok("".to_string()) *command_message = "".to_string();
Ok(command_message.clone())
} }
"move_line_start" => { "move_line_start" => {
state.set_current_cursor_pos(0); state.set_current_cursor_pos(0);
*ideal_cursor_column = 0; *ideal_cursor_column = 0;
Ok("".to_string()) *command_message = "".to_string();
Ok(command_message.clone())
} }
"move_line_end" => { "move_line_end" => {
let current_input = state.get_current_input(); let current_input = state.get_current_input();
let new_pos = current_input.len(); // Allow cursor at end let new_pos = current_input.len(); // Allow cursor at end
state.set_current_cursor_pos(new_pos); state.set_current_cursor_pos(new_pos);
*ideal_cursor_column = new_pos; *ideal_cursor_column = new_pos;
Ok("".to_string()) *command_message = "".to_string();
Ok(command_message.clone())
} }
// Actions handled by main event loop (mode changes) // Actions handled by main event loop (mode changes)
"enter_edit_mode_before" | "enter_edit_mode_after" | "enter_command_mode" | "exit_highlight_mode" => { "enter_edit_mode_before" | "enter_edit_mode_after"
key_sequence_tracker.reset(); | "enter_command_mode" | "exit_highlight_mode" => {
Ok("Mode change handled by main loop".to_string()) key_sequence_tracker.reset();
// These actions are primarily mode changes handled by the main event loop.
// The message here might be overridden by the main loop's message for mode change.
*command_message = "Mode change initiated".to_string();
Ok(command_message.clone())
} }
_ => { _ => {
key_sequence_tracker.reset(); key_sequence_tracker.reset();
command_message.clear(); // Clear message for unhandled actions *command_message =
Ok(format!("Unknown read-only action: {}", action)) format!("Unknown read-only action: {}", action);
}, Ok(command_message.clone())
}
} }
} }