From f2dc7861d9e4dcf73a0e0632aa624f1d7e42e99c Mon Sep 17 00:00:00 2001 From: Ross Andrews Date: Mon, 15 Jun 2026 11:44:18 -0500 Subject: [PATCH] input_mode_during --- kiln-tui/src/animation.rs | 13 +++++++++---- kiln-tui/src/input.rs | 11 ++++++----- kiln-tui/src/main.rs | 4 ++-- kiln-tui/src/menu.rs | 3 +++ 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/kiln-tui/src/animation.rs b/kiln-tui/src/animation.rs index a15130a..798d505 100644 --- a/kiln-tui/src/animation.rs +++ b/kiln-tui/src/animation.rs @@ -2,10 +2,12 @@ //! //! An animation encapsulates a time-bounded visual effect: it advances via //! [`update`](Animation::update), renders via [`draw`](Animation::draw), and -//! reports its layer and which [`InputMode`] to enter when it finishes. -//! -//! **While any animation is running, all input is ignored.** The front-end checks -//! [`Ui::active_animation`](crate::ui::Ui::active_animation) before dispatching events. +//! reports its layer, which [`InputMode`] is active while it runs +//! ([`input_mode_during`](Animation::input_mode_during)), and which mode to +//! enter when it finishes ([`input_mode_after`](Animation::input_mode_after)). +//! Most animations use the default `input_mode_during` ([`InputMode::Ignore`]), +//! but open animations may advertise an interactive mode so the overlay is +//! responsive before the animation completes. use ratatui::buffer::Buffer; use ratatui::layout::Rect; @@ -28,6 +30,9 @@ pub trait Animation { fn draw(&self, area: Rect, buf: &mut Buffer); /// Which region this animation draws to (board area vs. full overlay). fn layer(&self) -> AnimationLayer; + /// Which [`InputMode`] is active while this animation is running. + /// Defaults to [`InputMode::Ignore`] (all input discarded). + fn input_mode_during(&self) -> InputMode { InputMode::Ignore } /// Which [`InputMode`] to enter when the animation finishes. fn input_mode_after(&self) -> InputMode; } diff --git a/kiln-tui/src/input.rs b/kiln-tui/src/input.rs index d3af627..a9ddd2b 100644 --- a/kiln-tui/src/input.rs +++ b/kiln-tui/src/input.rs @@ -25,8 +25,8 @@ pub enum InputMode { Scroll, /// A menu overlay is active; all input is captured for menu navigation. Menu, - /// An animation is running; all input is discarded. - Animating, + /// 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. #[allow(dead_code)] Frozen, @@ -34,10 +34,11 @@ pub enum InputMode { /// Determines the current input mode from game and UI state. pub(crate) fn current_input_mode(game: &GameState, ui: &Ui) -> InputMode { - // Any active animation (or a pending transition waiting for its area) blocks input. - if ui.active_animation.is_some() || ui.pending_transition.is_some() { - return InputMode::Animating; + // 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 } } diff --git a/kiln-tui/src/main.rs b/kiln-tui/src/main.rs index c5a63d7..c8d7676 100644 --- a/kiln-tui/src/main.rs +++ b/kiln-tui/src/main.rs @@ -138,8 +138,8 @@ fn run( } InputMode::Menu => handle_menu_input(event, game, ui), InputMode::Scroll => handle_scroll_input(event, game, ui), - // Animation running — discard all events. - InputMode::Animating => {} + // Animation running and claiming no input mode — discard all events. + InputMode::Ignore => {} } } diff --git a/kiln-tui/src/menu.rs b/kiln-tui/src/menu.rs index 2eca7e9..a3cae48 100644 --- a/kiln-tui/src/menu.rs +++ b/kiln-tui/src/menu.rs @@ -144,6 +144,9 @@ impl Animation for MenuOpenAnimation { fn layer(&self) -> AnimationLayer { AnimationLayer::Overlay } + /// The menu is interactive from the first frame of the open animation. + fn input_mode_during(&self) -> InputMode { InputMode::Menu } + fn input_mode_after(&self) -> InputMode { InputMode::Menu } }