Skip to main content

Module interact

Module interact 

Source
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 of Events.
  • HitTester: resolves a pointer position to the topmost registered widget id.
  • FocusRing: which id holds keyboard focus, plus Tab/Shift+Tab cycling.
  • Response: what Interaction::interact reports back to a widget call site, gated by what it asked for via Sense.

§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 in

Structs§

FocusRing
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, and FocusRing together 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 Event you receive.
Response
What happened to a widget this frame, as reported by Interaction::interact.
Sense
Which of a Response’s fields Interaction::interact should actually populate for a given widget call.
Shortcuts
Maps key combinations to app-defined Actions, the same way HitTester maps a pointer position to a widget id.

Enums§

Consumed
Whether an Interaction claimed an event.
Density
How much room an interactive widget’s hit target should claim.

Constants§

DEFAULT_DOUBLE_CLICK_WINDOW
Default Interaction::with_double_click_window.
DEFAULT_DRAG_THRESHOLD
Default Interaction::with_drag_threshold.