Crop away the corners a straighten exposed, once the slider is let go
Turning a rectangle inside its own bounds exposes its corners: there is no source pixel out there, and the shader renders it black. Nothing in the render prevents that, deliberately — a free angle does not change the output size, which is what leaves the frame where the user put it while the slider moves. Correct during the drag; four black wedges on the finished photograph. Letting go of the slider now pulls the crop inside the area the angle leaves defined. `Framing::max_inscribed_crop` already computed that bound and had no caller; this is the caller its doc comment described. **Once, at the end of the gesture.** Applied per frame it would shrink the crop on every step of the slider and never grow it back, so a user who overshot to 20° and came back to 3° would be left with a crop ratcheted down by the excursion rather than by the angle they settled on. Per gesture it is bounded by the angles actually rested at, and undo steps back through them. **The crop is fitted into the bound, not replaced by it.** A crop placed deliberately off-centre is a decision, and an automatic correction that recentred it would undo the user's work to fix a problem they did not have. `CropRect::fitted_into` scales only as far as the bound demands and then slides the rect the shortest distance needed to be inside — so a ratio locked in the crop panel survives the straighten too, since the shape is never touched. It returns the rect unchanged, bit for bit, when nothing needed to move. That matters more than it looks: this runs on every release of the slider, including releases at zero, and a rect that drifted by a rounding error each time would be an edit recorded for no reason. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -512,6 +512,10 @@ export component GeometryPanel inherits Rectangle {
|
||||
callback flip-h-toggled();
|
||||
callback flip-v-toggled();
|
||||
callback angle-changed(float);
|
||||
/// The straightening gesture began or ended. What the auto-crop hangs
|
||||
/// off — see `DevelopSession::auto_crop_to_angle` for why it must be the
|
||||
/// end of the drag and not every frame of it.
|
||||
callback angle-drag-changed(bool);
|
||||
callback angle-reset();
|
||||
callback aspect-picked(int);
|
||||
callback portrait-toggled();
|
||||
@@ -604,6 +608,7 @@ export component GeometryPanel inherits Rectangle {
|
||||
maximum: root.max-straighten;
|
||||
unit: "°";
|
||||
changed(v) => { root.angle-changed(v); }
|
||||
drag-changed(on) => { root.angle-drag-changed(on); }
|
||||
reset => { root.angle-reset(); }
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user