Say so when a crop leaves a mask outside the frame

Cropping tighter past a mask layer made it invisible without a word:
the layer stayed in the panel and the sidecar, and its adjustment went
on landing on pixels nobody would see again.

When a crop is let go, develop now measures what the gesture did to the
mask stack (dr_pipeline::orphan) and, if any layer is now entirely or
mostly outside the frame, shows a notice over the photograph: how many
layers, their names, "Undo crop" and "Keep crop". The crop is already
applied and nothing waits on the answer.

The crop overlay gains a release callback carrying the rect the press
began from, so the measurement runs once per gesture and never on the
drag's per-frame changes. Choosing a ratio is measured the same way,
being a crop committed in one click.

"Undo crop" is the ordinary undo, and the notice is tied to the history
revision it was raised at: the redraw that follows any history move
clears it, so the crop and its warning go back as one step. A second
drag folded into the same step is measured from where that step began.
A crop that strands nothing shows nothing.
This commit is contained in:
2026-09-24 21:52:03 -04:00
parent fc0ea8824d
commit c3d1f83b96
9 changed files with 432 additions and 46 deletions
+44
View File
@@ -53,7 +53,11 @@ A model's mask stops inside a shoulder and leaks into the hair, and no single ed
A whole drag is one step, so undo takes back a decision rather than a frame of a gesture. The list is there because arriving six steps back costs what arriving from one does.
<<<<<<< HEAD
<sub>`ui/dr-ui/ui/app.slint:2123`</sub>
=======
<sub>`ui/dr-ui/ui/app.slint:2116`</sub>
>>>>>>> 5b5164f (Say so when a crop leaves a mask outside the frame)
### Do it again after taking it back
@@ -61,7 +65,11 @@ A whole drag is one step, so undo takes back a decision rather than a frame of a
- **Pointer** — Click it, or press Redo in the History header
- **Keyboard** — Ctrl+Shift+Z
<<<<<<< HEAD
<sub>`ui/dr-ui/ui/app.slint:2136`</sub>
=======
<sub>`ui/dr-ui/ui/app.slint:2129`</sub>
>>>>>>> 5b5164f (Say so when a crop leaves a mask outside the frame)
### Copy the settings from this photograph
@@ -71,7 +79,11 @@ A whole drag is one step, so undo takes back a decision rather than a frame of a
The button is the copy that has to work: a tablet has no modifier key to hold and no menu bar to hang the action from. The shortcut is an accelerator for a control that is on screen either way.
<<<<<<< HEAD
<sub>`ui/dr-ui/ui/app.slint:2169`</sub>
=======
<sub>`ui/dr-ui/ui/app.slint:2162`</sub>
>>>>>>> 5b5164f (Say so when a crop leaves a mask outside the frame)
### Paste the settings onto this photograph
@@ -81,7 +93,11 @@ The button is the copy that has to work: a tablet has no modifier key to hold an
The button names what would be pasted — "3 adjustments", and whether the crop is coming with it — which the shortcut cannot say. Both paste the same scope.
<<<<<<< HEAD
<sub>`ui/dr-ui/ui/app.slint:2181`</sub>
=======
<sub>`ui/dr-ui/ui/app.slint:2174`</sub>
>>>>>>> 5b5164f (Say so when a crop leaves a mask outside the frame)
### Choose which kinds of edit a copy carries
@@ -91,7 +107,11 @@ The button names what would be pasted — "3 adjustments", and whether the crop
Lightroom's Copy Settings. Pasting a look across a shoot usually means leaving each frame's crop and rotation alone, and that is a choice to make at the moment of copying.
<<<<<<< HEAD
<sub>`ui/dr-ui/ui/app.slint:2198`</sub>
=======
<sub>`ui/dr-ui/ui/app.slint:2191`</sub>
>>>>>>> 5b5164f (Say so when a crop leaves a mask outside the frame)
### Export this photograph as the last one was
@@ -101,7 +121,11 @@ Lightroom's Copy Settings. Pasting a look across a shoot usually means leaving e
Every export runs on the defaults in Settings, so "as the last one was" is what the button already does. The chord is Lightroom's and darktable's, kept so hands that learned it there need not learn it again.
<<<<<<< HEAD
<sub>`ui/dr-ui/ui/app.slint:2227`</sub>
=======
<sub>`ui/dr-ui/ui/app.slint:2220`</sub>
>>>>>>> 5b5164f (Say so when a crop leaves a mask outside the frame)
### Choose how to export, then export
@@ -111,7 +135,11 @@ Every export runs on the defaults in Settings, so "as the last one was" is what
The export sheet is the export defaults alone with an Export button. What is chosen there is kept, so it is also what the next Ctrl+Shift+E uses.
<<<<<<< HEAD
<sub>`ui/dr-ui/ui/app.slint:2239`</sub>
=======
<sub>`ui/dr-ui/ui/app.slint:2232`</sub>
>>>>>>> 5b5164f (Say so when a crop leaves a mask outside the frame)
### Change which group of adjustments is on screen
@@ -121,7 +149,11 @@ The export sheet is the export defaults alone with an Export button. What is cho
The groups are whatever the operation set declares itself to be about, so there are as many as the pipeline has and no key can be assigned to one of them by name. Stepping is the binding that survives a node being added.
<<<<<<< HEAD
<sub>`ui/dr-ui/ui/app.slint:2264`</sub>
=======
<sub>`ui/dr-ui/ui/app.slint:2257`</sub>
>>>>>>> 5b5164f (Say so when a crop leaves a mask outside the frame)
### Look at the photograph at 1:1
@@ -131,7 +163,11 @@ The groups are whatever the operation set declares itself to be about, so there
Noise reduction and capture sharpening are judgements about single pixels, and a fitted view averages several of the file's into each one on screen — so the frame looks softer than it is and the correction goes too far. The point and the magnification survive opening the next photograph, which is what makes checking the same eye across forty portraits forty keystrokes rather than forty pans. From 1:1 on the photograph is drawn as its own pixels, each a hard-edged square, rather than smoothed into a blur.
<<<<<<< HEAD
<sub>`ui/dr-ui/ui/app.slint:2299`</sub>
=======
<sub>`ui/dr-ui/ui/app.slint:2292`</sub>
>>>>>>> 5b5164f (Say so when a crop leaves a mask outside the frame)
### Move to the next or previous photograph
@@ -141,7 +177,11 @@ Noise reduction and capture sharpening are judgements about single pixels, and a
The edit on screen is saved on the way out, so stepping through a folder is as much a departure as going back to the grid and loses nothing. A and D as well as the arrows, so the left hand steps along the roll while the right stays on the mouse. Unmodified only: Ctrl+D and Ctrl+A are not this.
<<<<<<< HEAD
<sub>`ui/dr-ui/ui/app.slint:2354`</sub>
=======
<sub>`ui/dr-ui/ui/app.slint:2344`</sub>
>>>>>>> 5b5164f (Say so when a crop leaves a mask outside the frame)
### See the photograph before you edited it
@@ -151,7 +191,11 @@ The edit on screen is saved on the way out, so stepping through a folder is as m
Held rather than toggled, and no split screen: a split halves the working image on the tablet the column was sized for, and the comparison photographers describe making is a flick back and forth. It takes no history step, so checking whether a frame is overcooked costs nothing to undo afterwards.
<<<<<<< HEAD
<sub>`ui/dr-ui/ui/app.slint:2487`</sub>
=======
<sub>`ui/dr-ui/ui/app.slint:2477`</sub>
>>>>>>> 5b5164f (Say so when a crop leaves a mask outside the frame)
### Put one control back to its default