initial editor mode
This commit is contained in:
+48
-6
@@ -1,7 +1,9 @@
|
||||
use ratatui::crossterm::event::{Event, KeyCode, MouseEventKind};
|
||||
use ratatui::crossterm::event::{Event, KeyCode, MouseButton, MouseEventKind};
|
||||
use kiln_core::Direction;
|
||||
use kiln_core::game::{GameState, ScrollLine};
|
||||
use crate::editor::{editor_menu_items, EditorState};
|
||||
use crate::menu::{MenuItem, MenuKey, pause_menu_items, ActionRc as MenuActionRc};
|
||||
use crate::mode::Mode;
|
||||
use crate::ui::Ui;
|
||||
|
||||
/// Moves the player and, if the move crosses a portal, captures both board Rcs
|
||||
@@ -25,6 +27,8 @@ pub enum InputMode {
|
||||
Scroll,
|
||||
/// A menu overlay is active; all input is captured for menu navigation.
|
||||
Menu,
|
||||
/// Editing a world: arrow keys move the cursor, the sidebar is shown.
|
||||
Editor,
|
||||
/// An animation is running and has not claimed any input mode; all input is discarded.
|
||||
Ignore,
|
||||
/// Reserved for a post-transition freeze; nothing currently produces this mode.
|
||||
@@ -32,15 +36,20 @@ pub enum InputMode {
|
||||
Frozen,
|
||||
}
|
||||
|
||||
/// Determines the current input mode from game and UI state.
|
||||
pub(crate) fn current_input_mode(game: &GameState, ui: &Ui) -> InputMode {
|
||||
/// Determines the current input mode from the active [`Mode`] and UI state.
|
||||
pub(crate) fn current_input_mode(mode: &Mode, ui: &Ui) -> InputMode {
|
||||
// An active animation declares its own input mode; pending transitions ignore input.
|
||||
if let Some(anim) = &ui.active_animation {
|
||||
return anim.input_mode_during();
|
||||
}
|
||||
if ui.pending_transition.is_some() { return InputMode::Ignore; }
|
||||
if ui.menu.is_some() { return InputMode::Menu; }
|
||||
if game.active_scroll.is_some() { InputMode::Scroll } else { InputMode::Board }
|
||||
match mode {
|
||||
Mode::Edit(_) => InputMode::Editor,
|
||||
Mode::Play(game) => {
|
||||
if game.active_scroll.is_some() { InputMode::Scroll } else { InputMode::Board }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Handles an input event in [`InputMode::Board`]. Returns `true` if the player quit.
|
||||
@@ -72,6 +81,39 @@ pub(crate) fn handle_board_input(event: Event, log_open: bool, terminal_h: u16,
|
||||
false
|
||||
}
|
||||
|
||||
/// Handles an input event in [`InputMode::Editor`].
|
||||
///
|
||||
/// Arrow keys move the cursor; `l` toggles the log; `Esc` opens the editor menu.
|
||||
/// A right-click jumps the cursor to the clicked board cell, and dragging the
|
||||
/// board/sidebar divider resizes the sidebar (the divider sits at `term_w -
|
||||
/// sidebar_width`, mirroring the log's bottom divider).
|
||||
pub(crate) fn handle_editor_input(
|
||||
event: Event,
|
||||
term_w: u16,
|
||||
ed: &mut EditorState,
|
||||
ui: &mut Ui,
|
||||
) {
|
||||
match event {
|
||||
Event::Key(key) => match key.code {
|
||||
KeyCode::Esc => ui.open_menu(editor_menu_items()),
|
||||
KeyCode::Up => ed.move_cursor(0, -1),
|
||||
KeyCode::Down => ed.move_cursor(0, 1),
|
||||
KeyCode::Left => ed.move_cursor(-1, 0),
|
||||
KeyCode::Right => ed.move_cursor(1, 0),
|
||||
KeyCode::Char('l') => ui.log.toggle(),
|
||||
_ => {}
|
||||
},
|
||||
Event::Mouse(m) => match m.kind {
|
||||
// Right-click moves the cursor to the clicked cell (if on the board).
|
||||
MouseEventKind::Down(MouseButton::Right) => ed.set_cursor_at_screen(m.column, m.row),
|
||||
// Dragging the divider resizes the sidebar.
|
||||
MouseEventKind::Drag(_) => ed.resize_sidebar(term_w.saturating_sub(m.column), term_w),
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the choice string for the given key character, scanning the scroll lines.
|
||||
fn resolve_choice(lines: &[ScrollLine], c: char) -> Option<String> {
|
||||
let mut letter = b'a';
|
||||
@@ -117,7 +159,7 @@ pub(crate) fn handle_scroll_input(event: Event, game: &mut GameState, ui: &mut U
|
||||
///
|
||||
/// Uses the clone-then-dispatch pattern: the action `Rc` is cloned to release
|
||||
/// the immutable borrow on `ui.menu`, then the action is called with full `&mut Ui`.
|
||||
pub(crate) fn handle_menu_input(event: Event, game: &mut GameState, ui: &mut Ui) {
|
||||
pub(crate) fn handle_menu_input(event: Event, ui: &mut Ui) {
|
||||
match event {
|
||||
Event::Key(key) => {
|
||||
let pressed = match key.code {
|
||||
@@ -133,7 +175,7 @@ pub(crate) fn handle_menu_input(event: Event, game: &mut GameState, ui: &mut Ui)
|
||||
.and_then(|m| m.items.iter().find(|i| i.key == mk))
|
||||
.map(|i| i.action_rc());
|
||||
if let Some(action) = action {
|
||||
MenuItem::call_action_rc(action, game, ui);
|
||||
MenuItem::call_action_rc(action, ui);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user