Files
pikl/crates/pikl-core/src/model/event.rs
J. Champagne d9ed49e7d9
Some checks failed
CI / Check (macos-latest) (push) Has been cancelled
CI / Check (ubuntu-latest) (push) Has been cancelled
CI / Clippy (strict) (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / Test (macos-latest) (push) Has been cancelled
CI / Test (ubuntu-latest) (push) Has been cancelled
feat(core): Add input modes and half-page cursor movement.
2026-03-13 22:56:30 -04:00

87 lines
2.1 KiB
Rust

//! Types that flow between the menu engine and frontends.
//!
//! - [`Action`]: commands sent into the menu (keypresses,
//! script actions).
//! - [`MenuEvent`]: notifications sent out to subscribers
//! (state changes, terminal events).
//! - [`ViewState`]: snapshot of what the frontend should
//! render right now.
use std::sync::Arc;
use serde_json::Value;
/// Input mode. Insert mode sends keystrokes to the filter,
/// normal mode uses vim-style navigation keybinds.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum Mode {
#[default]
Insert,
Normal,
}
/// A command the menu should process. Frontends and headless
/// scripts both produce these. The menu loop consumes them
/// sequentially.
#[derive(Debug, Clone, PartialEq)]
pub enum Action {
UpdateFilter(String),
MoveUp(usize),
MoveDown(usize),
MoveToTop,
MoveToBottom,
PageUp(usize),
PageDown(usize),
HalfPageUp(usize),
HalfPageDown(usize),
SetMode(Mode),
Confirm,
Cancel,
Resize { height: u16 },
AddItems(Vec<Value>),
}
/// Broadcast from the menu loop to all subscribers
/// (frontends, tests).
#[derive(Debug, Clone)]
pub enum MenuEvent {
StateChanged(ViewState),
Selected(Value),
Cancelled,
}
/// Snapshot of the menu's visible state. Sent on every state
/// change so frontends can render without querying back into
/// the engine.
#[must_use]
#[derive(Debug, Clone)]
pub struct ViewState {
pub visible_items: Vec<VisibleItem>,
/// Index of the cursor within `visible_items`
/// (not the full list).
pub cursor: usize,
pub filter_text: Arc<str>,
pub total_items: usize,
pub total_filtered: usize,
pub mode: Mode,
}
/// A single item in the current viewport window. Has the
/// display label pre-resolved and the position in the
/// filtered list.
#[must_use]
#[derive(Debug, Clone)]
pub struct VisibleItem {
pub label: String,
pub index: usize,
}
/// Final outcome of [`crate::menu::MenuRunner::run`]. The
/// user either picked something or bailed.
#[must_use]
#[derive(Debug)]
pub enum MenuResult {
Selected(Value),
Cancelled,
}