Expand description
The window’s text selection outside an editor: what a selectable
node scopes, what a press-drag across it produces, and what a copy
reads.
A view opts text in with NodeSpec::selectable on a container; the
core then handles the drag, Shift-arrows, double and triple clicks and
Select All. An app reads the result with Core::selection (a
Selection) or Core::cell_selection (a CellSelection inside a
cells grid), and asks for the text with Core::request_copy, which
answers a CopyRequest. There is one selection per window, and an
editor’s own selection is the other half of that: starting one clears
the other.
A selection is two addresses, a node key and a byte inside that node’s own text, never an index into a frame’s vectors. A frame that no longer builds the node resolves it to nothing; a frame that builds it again resolves it again.
use kui_core::{CellEnd, CellSelection, Endpoint, Key, Selection};
// A drag from byte 3 of one label back to byte 1 of an earlier one.
let scope = Key::ROOT.str("card");
let sel = Selection::new(
scope,
Endpoint::new(scope.str("second"), 3),
Endpoint::new(scope.str("first"), 1),
);
assert!(!sel.is_empty());
// Inside a terminal grid, ends are absolute lines and columns.
let grid = CellSelection::new(Key::ROOT.str("term"), CellEnd::new(10, 3), CellEnd::new(12, 5));
assert_eq!(grid.cols_on(11, 80), Some((0, 80))); // a middle line, edge to edge
assert_eq!(grid.block(true).cols_on(11, 80), Some((3, 5))); // a block: same columnsStructs§
- CellEnd
- One end of a selection in a cell grid: an absolute line (the grid’s
origin_lineplus the row) and a column. Absolute because a grid is one screenful of an app’s own history, so a row number means a different line after every scroll. - Cell
Selection - A selection inside one
cellsgrid. - Endpoint
- One end of a selection: the node whose text it lands in, and a byte offset into that node’s content (not into the scope’s).
- Range
End - One end of the range an app is asked to fill in
(
Core::selection_range): the data index of the row it is in, and the byte inside that row’s own text. An end outside every virtualised row has no index — it is text the core built and can answer for itself. - Selection
- The window’s selection: a scope and two ends of it.
anchoris where the press landed andfocusis where the pointer is now, so the pair is directed — dragging back past the anchor selects the other way without the two swapping, which is what keeps a drag from feeling like it jumps when it crosses its own start.
Enums§
- Copy
Request - What asking for a copy answered (
Core::request_copy). - Grain
- What a drag-select moves by. A press sets it from the click count the driver counted, the way every text UI does: one click drags by characters, two by words, three by whole runs.
Constants§
- ROW_END
- A
bytethat means “the end of the row, whatever its length”: what a Select All puts on the last row of aselectablevirtual list the frame did not build, since the core never laid that row out and cannot know where it ends. Aselectionrangeask carries it as written, past any row’s length, and the app cuts it to the row.u32::MAXrather thanusize::MAXso it survives a wire that spells bytes as numbers. - TINT
- What a selection is painted under when nothing else says — the dark
base’s tint, and what kui painted before there were themes. The live
value is
theme.selection, which both aselectablescope and an editor read, because a selection over a label and one over a field sitting side by side must not be two different blues. This constant stays as the floor ancrate::edit::EditOptionsthe core never stamped falls back to.