// src/modes/handlers/mode_manager.rs use crate::state::app::state::AppState; use crate::modes::handlers::event::EventHandler; use crate::state::pages::add_logic::AddLogicFocus; use crate::state::pages::admin::AdminState; use canvas::AppMode as CanvasMode; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum AppMode { General, // For intro and admin screens ReadOnly, // Canvas read-only mode Edit, // Canvas edit mode Highlight, // Canvas highlight/visual mode Command, // Command mode overlay } impl From for AppMode { fn from(mode: canvas::AppMode) -> Self { match mode { canvas::AppMode::General => AppMode::General, canvas::AppMode::ReadOnly => AppMode::ReadOnly, canvas::AppMode::Edit => AppMode::Edit, canvas::AppMode::Highlight => AppMode::Highlight, canvas::AppMode::Command => AppMode::Command, } } } pub struct ModeManager; impl ModeManager { /// Determine current mode based on app state pub fn derive_mode( app_state: &AppState, event_handler: &EventHandler, admin_state: &AdminState, ) -> AppMode { // Navigation palette always forces General if event_handler.navigation_state.active { return AppMode::General; } // Explicit command mode flag if event_handler.command_mode { return AppMode::Command; } // ✅ Always trust the FormEditor when a form is active if let Some(editor) = &app_state.form_editor { return AppMode::from(editor.mode()); } // --- Non-form views (add_logic, add_table, etc.) --- if app_state.ui.show_add_logic { match admin_state.add_logic_state.current_focus { AddLogicFocus::InputLogicName | AddLogicFocus::InputTargetColumn | AddLogicFocus::InputDescription => { if event_handler.is_edit_mode { AppMode::Edit } else { AppMode::ReadOnly } } _ => AppMode::General, } } else if app_state.ui.show_add_table { if app_state.ui.focus_outside_canvas { AppMode::General } else if event_handler.is_edit_mode { AppMode::Edit } else { AppMode::ReadOnly } } else if app_state.ui.show_login || app_state.ui.show_register { // login/register still use the old flag if event_handler.is_edit_mode { AppMode::Edit } else { AppMode::ReadOnly } } else { AppMode::General } } // Mode transition rules pub fn can_enter_command_mode(current_mode: AppMode) -> bool { !matches!(current_mode, AppMode::Edit) } pub fn can_enter_edit_mode(current_mode: AppMode) -> bool { matches!(current_mode, AppMode::ReadOnly) } pub fn can_enter_read_only_mode(current_mode: AppMode) -> bool { matches!( current_mode, AppMode::Edit | AppMode::Command | AppMode::Highlight ) } pub fn can_enter_highlight_mode(current_mode: AppMode) -> bool { matches!(current_mode, AppMode::ReadOnly) } }