Give the drag a pick-up, so it stops losing to the scroll

Dragging a photograph out of the grid worked about half the time, and
nothing on the screen explained the other half.

`DragArea` and `Flickable` do arbitrate, but not evenly. The Flickable
claims any press that travels more than eight pixels along its own axis
within half a second of landing, and holds that claim until the finger
lifts. So a drag toward the sidebar only ever began two ways: a flick
sideways clean enough that the finger never wandered eight pixels
vertically, or a wait of half a second before moving at all. Both are
real gestures and neither was written down.

The wait is now the gesture, and it has a mark. The long press that
already turns on selection mode also picks the photograph up: a ring
opens around the cell and the grid stops scrolling under it, so from
that moment the drag is the only thing the finger can be doing. The cue
can only arrive after the ambiguity has passed, which is the right way
round — when the photograph lifts, dragging it works.

Two details worth naming. The hold is now armed even when selection mode
is already on; it used to be skipped there, on the grounds that there
was no mode left to switch on — but that is precisely the state a
forty-image drag starts from, so the one gesture that most needed a
pick-up was the one with none. And the ring is drawn after the cell
loop rather than on the cell: z-order inside a `for` is loop order, so a
cell grown past its bounds would stand over two neighbours and be cut
off by the other two.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-30 13:20:56 +02:00
co-authored by Claude Opus 5
parent 7b5f62019b
commit b34e786f01
6 changed files with 195 additions and 43 deletions
+18 -9
View File
@@ -5,7 +5,7 @@
Every entry here is extracted from the comment beside the code that implements it, so this file cannot describe a gesture the application does not have. Add one by writing a `GESTURE:` block next to the implementation; there is nowhere else to write it.
15 gestures, in 2 places.
16 gestures, in 2 places.
## People
@@ -73,6 +73,15 @@ While selecting, a tap never opens. That is the whole point of the mode: one mea
<sub>`ui/dr-ui/ui/library.slint:1291`</sub>
### Pick a photograph up to drag it
- **Touch** — Press and hold it until a ring opens around it, then drag
- **Pointer** — Drag it
A finger on a photograph might be starting a scroll, and for the first half-second the grid assumes it is. Holding says otherwise, and the ring is the grid saying it heard — from there the drag cannot be lost to a scroll. A mouse never waits: the cursor is precise enough that a sideways drag is unambiguous from the first pixel.
<sub>`ui/dr-ui/ui/library.slint:1321`</sub>
### Select a range
- **Touch** — While selecting, press "Select to…", then tap the last photograph of the run
@@ -80,7 +89,7 @@ While selecting, a tap never opens. That is the whole point of the mode: one mea
This replaced a double tap, which had no visible state and could take forty photographs by accident. The run is resolved by the catalog rather than by what is on screen, so the grid can scroll between the two taps — the ranges that hurt on a tablet are longer than a screenful, which is exactly where a finger sweep runs out.
<sub>`ui/dr-ui/ui/library.slint:1352`</sub>
<sub>`ui/dr-ui/ui/library.slint:1386`</sub>
### Find photographs with two people in them
@@ -89,7 +98,7 @@ This replaced a double tap, which had no visible state and could take forty phot
"Any of them" is a union and "all of them" is an intersection. The tray is where both terms and the choice between them live, because a filter belongs on the filter bar.
<sub>`ui/dr-ui/ui/library.slint:2107`</sub>
<sub>`ui/dr-ui/ui/library.slint:2141`</sub>
### Resize the thumbnails
@@ -98,7 +107,7 @@ This replaced a double tap, which had no visible state and could take forty phot
There is no wheel on a tablet, so without the pinch the cell size could only be changed by a control a finger cannot reach.
<sub>`ui/dr-ui/ui/library.slint:2733`</sub>
<sub>`ui/dr-ui/ui/library.slint:2783`</sub>
### File photographs in a collection
@@ -107,7 +116,7 @@ There is no wheel on a tablet, so without the pinch the cell size could only be
The selection is what the drag carries, which is why selecting several is worth the mode: forty photographs file in one gesture.
<sub>`ui/dr-ui/ui/library.slint:2892`</sub>
<sub>`ui/dr-ui/ui/library.slint:2942`</sub>
### Open a photograph
@@ -116,7 +125,7 @@ The selection is what the drag carries, which is why selecting several is worth
A tap opens; a tap that *moved* does not. Travel is what separates a deliberate tap from a hand brushing past, and it is the only thing that does: the two are the same length. An earlier version required the finger to dwell 120 ms instead, and that rejected ordinary taps — a real tap is often quicker than a brush.
<sub>`ui/dr-ui/ui/library.slint:3160`</sub>
<sub>`ui/dr-ui/ui/library.slint:3210`</sub>
### Rate a photograph without opening it
@@ -126,7 +135,7 @@ A tap opens; a tap that *moved* does not. Travel is what separates a deliberate
A star has to take the press without it also reaching the cell, or every rating throws the user into develop.
<sub>`ui/dr-ui/ui/library.slint:3272`</sub>
<sub>`ui/dr-ui/ui/library.slint:3330`</sub>
### Drop the selection but keep selecting
@@ -135,7 +144,7 @@ A star has to take the press without it also reaching the cell, or every rating
Distinct from Done, which leaves the mode entirely. Clearing keeps it, so the next selection can start straight away.
<sub>`ui/dr-ui/ui/library.slint:3835`</sub>
<sub>`ui/dr-ui/ui/library.slint:3938`</sub>
### Select everything the grid is showing
@@ -144,4 +153,4 @@ Distinct from Done, which leaves the mode entirely. Clearing keeps it, so the ne
A scoped grid of two hundred frames is two hundred taps otherwise, and "all of them, except those three" is a far more common shape than the taps it took to say it.
<sub>`ui/dr-ui/ui/library.slint:3852`</sub>
<sub>`ui/dr-ui/ui/library.slint:3955`</sub>
+19 -19
View File
File diff suppressed because one or more lines are too long