feat(input): a cursor can be unselectable, for a host's readout marks

A host that draws the result of a computation as a cursor -- a ruler at a level
it measured, a marker at a time it found -- must not let the user drag it: the
value belongs to the measurement, not to the pointer. Parking it outside the
axis and re-placing it every frame does not achieve that, because a drag is held
for the gesture's life and the marker follows the pointer between frames, so the
readout *looks* draggable however often it is put back.

`Cursor::selectable` defaults true; the controller's hit test skips an
unselectable cursor, so it is neither hovered nor grabbed and its hit radius
goes to whatever is behind it. Set through `Plot::set_cursor_selectable()`.

Tested by `an_unselectable_cursor_is_neither_hovered_nor_grabbed` in
tests/test_controller.cpp.
This commit is contained in:
Martino Ferrari committed 2026-10-03 10:29:13 +02:00
1 parent 125cc1f64a
commit 211c5b97bc
5 files changed
+50 -1

No files matched your search

+6
View File
@@ -86,6 +86,12 @@ struct Cursor {
u32 axis_x = 0; ///< the x axis `x` is in. Dead for `Horizontal`.
u32 axis_y = 0; ///< the y axis `y` is in. Dead for `Vertical`.
bool visible = true;
/// Whether the pointer may hit this cursor at all: `false` for a *readout* -- a marker a
/// host keeps to show something it computed, which the user must not be able to drag. The
/// controller's `cursor_at()` skips it, so it is neither hovered nor grabbed, and the
/// hit radius it would have taken is left to whatever is behind it. Drawn exactly as a
/// visible one is: this is about the gesture, not the ink.
bool selectable = true;
/// True when this is a horizontal ruler (spans the axes' width, reads its `y`). The one
/// place the orientation becomes a branch, so every consumer takes the same decision and
+4
View File
@@ -484,6 +484,10 @@ class Plot {
/// be told apart from its neighbours, and its colour is how it says which readout it
/// belongs to. An id that names no cursor is ignored, like every other setter here.
void set_cursor_color(u32 id, Color color);
/// Makes a cursor unselectable (see `Cursor::selectable`): the pointer cannot hover or
/// grab it, which is what a host wants for a marker it draws as a *readout*. An id that
/// names no cursor is ignored, like every other setter here.
void set_cursor_selectable(u32 id, bool selectable);
/// The measurement for `id`. Re-evaluated only when a cursor moved, when the
/// measure was added, or when the series underneath it changed: a different