centralized general movement
This commit is contained in:
@@ -371,6 +371,58 @@ impl EventHandler {
|
||||
|
||||
match current_mode {
|
||||
AppMode::General => {
|
||||
// Map keys to MovementAction
|
||||
let movement_action = if let Some(act) =
|
||||
config.get_general_action(key_event.code, key_event.modifiers)
|
||||
{
|
||||
use crate::movement::MovementAction;
|
||||
match act {
|
||||
"up" => Some(MovementAction::Up),
|
||||
"down" => Some(MovementAction::Down),
|
||||
"left" => Some(MovementAction::Left),
|
||||
"right" => Some(MovementAction::Right),
|
||||
"next" => Some(MovementAction::Next),
|
||||
"previous" => Some(MovementAction::Previous),
|
||||
"select" => Some(MovementAction::Select),
|
||||
"esc" => Some(MovementAction::Esc),
|
||||
_ => None,
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Let the current page handle decoupled movement first
|
||||
if let Some(ma) = movement_action {
|
||||
match &mut router.current {
|
||||
Page::AddTable(state) => {
|
||||
if state.handle_movement(ma) {
|
||||
// Keep UI focus consistent with inputs vs. outer elements
|
||||
use crate::state::pages::add_table::AddTableFocus;
|
||||
let is_canvas_input = matches!(
|
||||
state.current_focus,
|
||||
AddTableFocus::InputTableName
|
||||
| AddTableFocus::InputColumnName
|
||||
| AddTableFocus::InputColumnType
|
||||
);
|
||||
app_state.ui.focus_outside_canvas = !is_canvas_input;
|
||||
return Ok(EventOutcome::Ok(String::new()));
|
||||
}
|
||||
}
|
||||
Page::Admin(state) => {
|
||||
if state.handle_movement(app_state, ma) {
|
||||
return Ok(EventOutcome::Ok(String::new()));
|
||||
}
|
||||
}
|
||||
Page::Intro(state) => {
|
||||
if state.handle_movement(ma) {
|
||||
return Ok(EventOutcome::Ok(String::new()));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
// Optional page-specific handlers (non-movement or rich actions)
|
||||
if let Page::Admin(admin_state) = &mut router.current {
|
||||
if auth_state.role.as_deref() == Some("admin") {
|
||||
if admin_nav::handle_admin_navigation(
|
||||
@@ -401,7 +453,7 @@ impl EventHandler {
|
||||
router,
|
||||
) {
|
||||
return Ok(EventOutcome::Ok(
|
||||
self.command_message.clone(),
|
||||
self.command_message.clone(),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -423,16 +475,25 @@ impl EventHandler {
|
||||
}
|
||||
}
|
||||
|
||||
let nav_outcome = navigation::handle_navigation_event(
|
||||
key_event,
|
||||
config,
|
||||
app_state,
|
||||
router,
|
||||
&mut self.command_mode,
|
||||
&mut self.command_input,
|
||||
&mut self.command_message,
|
||||
&mut self.navigation_state,
|
||||
).await;
|
||||
// Generic navigation for the rest (Intro/Login/Register/Form)
|
||||
let nav_outcome = if matches!(
|
||||
&router.current,
|
||||
Page::Admin(_) | Page::AddTable(_) | Page::AddLogic(_)
|
||||
) {
|
||||
Ok(EventOutcome::Ok(String::new()))
|
||||
} else {
|
||||
navigation::handle_navigation_event(
|
||||
key_event,
|
||||
config,
|
||||
app_state,
|
||||
router,
|
||||
&mut self.command_mode,
|
||||
&mut self.command_input,
|
||||
&mut self.command_message,
|
||||
&mut self.navigation_state,
|
||||
).await
|
||||
};
|
||||
|
||||
match nav_outcome {
|
||||
Ok(EventOutcome::ButtonSelected { context, index }) => {
|
||||
let message = match context {
|
||||
@@ -443,14 +504,8 @@ impl EventHandler {
|
||||
index,
|
||||
);
|
||||
if let Page::Admin(admin_state) = &mut router.current {
|
||||
if !app_state
|
||||
.profile_tree
|
||||
.profiles
|
||||
.is_empty()
|
||||
{
|
||||
admin_state
|
||||
.profile_list_state
|
||||
.select(Some(0));
|
||||
if !app_state.profile_tree.profiles.is_empty() {
|
||||
admin_state.profile_list_state.select(Some(0));
|
||||
}
|
||||
}
|
||||
format!("Intro Option {} selected", index)
|
||||
@@ -506,8 +561,9 @@ impl EventHandler {
|
||||
}
|
||||
format!("Admin Option {} selected", index)
|
||||
}
|
||||
UiContext::Dialog => "Internal error: Unexpected dialog state"
|
||||
.to_string(),
|
||||
UiContext::Dialog => {
|
||||
"Internal error: Unexpected dialog state".to_string()
|
||||
}
|
||||
};
|
||||
return Ok(EventOutcome::Ok(message));
|
||||
}
|
||||
@@ -515,37 +571,6 @@ impl EventHandler {
|
||||
}
|
||||
}
|
||||
|
||||
AppMode::General => {
|
||||
match &router.current {
|
||||
Page::Form(_)
|
||||
| Page::Login(_)
|
||||
| Page::Register(_)
|
||||
| Page::AddTable(_)
|
||||
| Page::AddLogic(_) => {
|
||||
if !app_state.ui.focus_outside_canvas {
|
||||
if let Some(editor) = &mut app_state.form_editor {
|
||||
editor.set_keymap(config.build_canvas_keymap());
|
||||
match editor.handle_key_event(key_event) {
|
||||
KeyEventOutcome::Consumed(Some(msg)) => {
|
||||
return Ok(EventOutcome::Ok(msg));
|
||||
}
|
||||
KeyEventOutcome::Consumed(None) => {
|
||||
return Ok(EventOutcome::Ok(String::new()));
|
||||
}
|
||||
KeyEventOutcome::Pending => {
|
||||
return Ok(EventOutcome::Ok(String::new()));
|
||||
}
|
||||
KeyEventOutcome::NotMatched => {
|
||||
// fall through to client actions
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
AppMode::Command => {
|
||||
if config.is_exit_command_mode(key_code, modifiers) {
|
||||
self.command_input.clear();
|
||||
|
||||
Reference in New Issue
Block a user