Expand description
Pointer and keyboard focus tracking for interactive widgets, without a retained widget tree.
ListState answers “where is this list scrolled to
and what’s selected”; this module answers the sibling question, “what
did the user just do to this widget” (hover, click, drag, focus,
scroll) for widgets that don’t have a natural selection index of their
own (buttons, tabs, draggable panes, …). Four independently usable
pieces, composed by Interaction the way ListState
composes with crate::widget::Table:
Pointer: raw mouse position/button/scroll state from a stream ofEvents.HitTester: resolves a pointer position to the topmost registered widget id.FocusRing: which id holds keyboard focus, plus Tab/Shift+Tab cycling.Response: whatInteraction::interactreports back to a widget call site, gated by what it asked for viaSense.
§Example
use retroglyph_core::backend::{Backend, Headless};
use retroglyph_core::grid::Rect;
use retroglyph_core::terminal::Terminal;
use retroglyph_ui::{Interaction, Sense};
#[derive(Clone, Copy, PartialEq, Eq)]
enum WidgetId {
SaveButton,
}
fn draw<B: Backend>(
term: &mut Terminal<B>,
interaction: &mut Interaction<WidgetId>,
) -> bool {
let area = Rect::new(0, 0, 10, 1);
let response = interaction.interact(area, WidgetId::SaveButton, Sense::click());
// ... draw the button, using response.hovered()/focused() to pick a style ...
response.clicked()
}
let mut term = Terminal::new(Headless::new(20, 10));
let mut interaction = Interaction::<WidgetId>::new();
interaction.begin_frame();
let saved = draw(&mut term, &mut interaction);
interaction.end_frame();
assert!(!saved); // nothing clicked yet: no input was fed inStructs§
- Focus
Ring - Which id currently holds keyboard focus, plus Tab/Shift+Tab cycling
through the ids
registered as focusable. - HitTester
- A per-frame registry of
(Rect, Id)pairs, queried by pointer position to find the topmost widget under a point. - Interaction
- Ties
Pointer,HitTester, andFocusRingtogether into the one piece of state a draw pass needs to make its widgets interactive. - Pointer
- Cell-grid pointer position and per-button state, updated by feeding it
every
Eventyou receive. - Response
- What happened to a widget this frame, as reported by
Interaction::interact. - Sense
- Which of a
Response’s fieldsInteraction::interactshould actually populate for a given widget call. - Shortcuts
- Maps key combinations to app-defined
Actions, the same wayHitTestermaps a pointer position to a widget id.
Enums§
- Consumed
- Whether an
Interactionclaimed an event. - Density
- How much room an interactive widget’s hit target should claim.