Drag a collection onto another to nest it

The tree could be built nested but never rearranged: `set_parent` existed,
with its cycle check and its tests, and nothing in the UI called it. A
collection created in the wrong place stayed there.

Each row is already a drop target, so it becomes a `DragArea` too —
wrapped at the instantiation site the way the grid's cells are, which
keeps the row's own TouchArea nested underneath and a click still
selecting. `allow-move`, not copy: a collection has one parent, unlike a
photograph, which is filed in as many collections as you like.

The drop is handed only the target's id, so the source is remembered from
the press that precedes the drag — Slint builds the payload through a
`pure` binding, which must not have side effects. An image drag always
fills `dragging`, so an empty payload with a remembered row is
unambiguously a rearrangement; the row is taken rather than read, or a
later empty drop would move a collection nobody touched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-17 22:54:50 +02:00
co-authored by Claude Opus 5
parent edcaf42ded
commit 6acc73a9fa
4 changed files with 88 additions and 1 deletions
+5
View File
@@ -3747,8 +3747,13 @@ pub fn wire<F>(
{
let weak = window.as_weak();
let ctl = ctl.clone();
let coll_for_press = coll_ctl.clone();
window.on_collection_row_press(move |id, down| {
let Some(w) = weak.upgrade() else { return };
// A drag of this row, if one follows, carries this collection.
if down {
coll_for_press.note_row_press(dr_types::CollectionId(id as u64));
}
if !down {
*ctl.row_hold_timer.borrow_mut() = None;
return;