Merge remote-tracking branch 'origin/rustify' into worktree-agent-afe80868604fef704
# Conflicts: # IRIS.md # RUST.md
This commit is contained in:
commit
62199aa3a7
7 files changed
+485
-78
No files matched your search
@@ -30,6 +30,49 @@ let (screen, tree) = transcript_ui::build_tree(rsc, rows);
|
||||
some_widget_ptr(rsc).set(tree);
|
||||
```
|
||||
|
||||
|
||||
## 2026-09-05: `DragArbiter`, pan-vs-select for one shared touch gesture (RUST.md's I5)
|
||||
|
||||
New public type, `iris::sense::DragArbiter`. Why: a widget author who
|
||||
registers both a list-level pan and a row-level drag-to-select on the same
|
||||
touch gesture has no way to arbitrate between them — `core/src/sense.rs`'s
|
||||
`run_sensors` always gives the innermost layer first refusal, so the inner
|
||||
one wins every frame it is pressed, not just the frame the press started
|
||||
(this is exactly what left transcript-ui's touch-drag panning unreachable
|
||||
until now). `DragArbiter` is one small state machine, one instance per
|
||||
gesture surface (a whole list, not per row), that a caller drives with its
|
||||
own `press_start`/`update`/`release` calls and a caller-supplied `Instant`
|
||||
(so it is unit-testable without a real clock or a render harness). It
|
||||
decides the way Android itself does: an ordinary vertical drag pans
|
||||
immediately; a stationary press held `LONG_PRESS` (500ms) starts a
|
||||
selection, which any further drag then extends; a horizontal drag while
|
||||
something is already selected extends it immediately, skipping the wait.
|
||||
|
||||
```rust
|
||||
// One per list, held alongside whatever state coordinates the rows:
|
||||
let mut arbiter = DragArbiter::new();
|
||||
|
||||
// On press-down:
|
||||
arbiter.press_start(pos, Instant::now(), already_selected);
|
||||
// Every frame the button/finger stays down:
|
||||
match arbiter.update(pos, Instant::now()) {
|
||||
DragOutcome::Pan(dy) => list.scroll(-dy),
|
||||
DragOutcome::SelectStart => selection.begin(...),
|
||||
DragOutcome::SelectExtend => selection.extend(...),
|
||||
DragOutcome::Undecided => {}
|
||||
}
|
||||
// On release:
|
||||
arbiter.release();
|
||||
```
|
||||
|
||||
`transcript-ui`'s `Selection::drag` (`transcript-ui/src/selection.rs`) is
|
||||
the reference caller: every row's `CursorSense::click_or_drag() |
|
||||
CursorSense::unclick()` handler routes through one `Selection`-owned
|
||||
arbiter instead of calling `begin`/`extend` directly, so a drag that starts
|
||||
on a row's own rendered text now pans the list correctly instead of
|
||||
always starting a selection. 8 new unit tests in `iris/src/sense.rs`'s
|
||||
`drag_arbiter_tests` module.
|
||||
|
||||
## 2026-09-05: `SpanStyle`, per-range text styling (RUST.md's I5)
|
||||
|
||||
A `TextBuffer` used to have exactly one style (`TextAttrs`: colour, size,
|
||||
|
||||
Reference in new issue
Block a user