Bind the two develop gestures that were described and not bound

FR-DEV-16's book said resetting a control and hiding a mask layer were
reachable by pointer and by finger, and stopped there. The reason was
honest: the generated rows have no focus, so "reset the focused control"
named a thing the panel could not point at. But a photographer at the
keyboard means something narrower than focus. They mean the slider they
just dragged too far, and that is a thing the panel can remember.

So the Adjustments global keeps the last control moved — two indices,
written where the panel forwards the change and cleared when the next
photograph opens, so a reset cannot reach back into the previous edit
through an index that happens to be shared. R puts it back, through the
same callback the track's double-click takes, and is silent until
something has moved.

The mask layer needs no such notion, because the panel already has a
selection: the rows the edge controls point at. H hides or shows those,
through the path the ring at the head of the row takes, so it is an edit
and a history step exactly as the ring is. A mixed selection goes to
shown, since the layer nobody can see is the one being asked about.

Both tags now carry the key, and the book says so.
This commit is contained in:
2026-09-12 01:08:09 +02:00
parent 2836ec2881
commit 9cc52fd72b
10 changed files with 147 additions and 55 deletions
+28
View File
@@ -666,6 +666,34 @@ pub(crate) fn wire(
});
}
{
{
// TRACES: FR-DEV-16
// The keyboard's copy of the ring. A mixed selection goes to shown:
// a layer nobody can see is the one being asked about, and turning
// the rest off to match it would hide work in the name of hiding it.
let weak = window.as_weak();
let session = session.clone();
let redraw = redraw.clone();
window.global::<Masking>().on_selected_toggled(move || {
let Some(w) = weak.upgrade() else { return };
{
let mut slot = session.borrow_mut();
let Some(s) = slot.as_mut() else { return };
let ids: Vec<String> = s.active_masks().to_vec();
if ids.is_empty() {
return;
}
let all_shown = ids
.iter()
.all(|id| s.masks().get(id).is_some_and(|l| l.enabled));
for id in &ids {
s.set_mask_enabled(id, !all_shown);
}
}
sync(&w, &session);
redraw(&w);
});
}
let weak = window.as_weak();
let session = session.clone();
let redraw = redraw.clone();