From 02a9f3a5fb625ed1957fe0ba64f77e982d4c327b Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Sat, 10 Oct 2026 03:52:53 -0400 Subject: [PATCH] LR-CROP-ASPECT: forget a remembered ratio the crop command refuses A bad remembered value (a hand-edited settings file) made begin_crop fail, which cancelled every crop drag on an untouched photo for good. Now the value is dropped with a status message and the drag goes ahead. Regression test in tests_masking.rs. Co-Authored-By: Claude Opus 5.5 --- crates/ui-egui/src/lib.rs | 6 +++++- crates/ui-egui/src/tests_masking.rs | 22 ++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs index 80dcf594f..bc38b1935 100644 --- a/crates/ui-egui/src/lib.rs +++ b/crates/ui-egui/src/lib.rs @@ -478,8 +478,12 @@ impl LightcraftApp { && self.session.active().and_then(|id| self.session.develop_of(id)).is_some_and(|d| d.crop == lightcraft_develop::Crop::default()) && let Some(aspect) = self.ui.crop_default_aspect.clone() && aspect != serde_json::json!("free") + && let Err(e) = self.session.execute("crop.aspect", &serde_json::json!({"aspect": aspect})) { - self.session.execute("crop.aspect", &serde_json::json!({"aspect": aspect})).map_err(|e| e.to_string())?; + // A remembered value the command refuses (a hand-edited settings file) would refuse + // every crop drag on an untouched photo: forget it and let this drag go ahead. + self.ui.crop_default_aspect = None; + self.ui.status = e.to_string(); } Ok(()) } diff --git a/crates/ui-egui/src/tests_masking.rs b/crates/ui-egui/src/tests_masking.rs index 57753bee1..36b9fecd1 100644 --- a/crates/ui-egui/src/tests_masking.rs +++ b/crates/ui-egui/src/tests_masking.rs @@ -468,6 +468,28 @@ fn crop_drag_activates_the_remembered_ratio_and_undo_restores_the_photo() { assert_eq!(develop(&h), before); } +/// A remembered ratio the crop command refuses (a hand-edited settings file) is forgotten, and the +/// drag still crops: it must not block every crop of an untouched photo. +#[test] +fn a_bad_remembered_ratio_is_dropped_and_the_drag_still_crops() { + let mut h = detail("panel.crop"); + h.app.ui.crop_default_aspect = Some(json!([0, -3])); + h.settle(SETTLE); + let before = develop(&h); + // a rotating drag outside the box (any crop drag starts cropping); the release on its own + for events in [ + json!([{"kind": "down", "x": -0.05, "y": 0.2}, {"kind": "drag", "x": -0.05, "y": 0.25}, {"kind": "drag", "x": -0.05, "y": 0.3}]), + json!([{"kind": "up", "x": -0.05, "y": 0.3}]), + ] { + let r = h.request("ui.pointer", json!({ "events": events }), T); + assert_eq!(r["ok"], true, "{r}"); + h.settle(SETTLE); + } + assert_eq!(h.app.ui.crop_default_aspect, None, "the bad value is forgotten"); + assert_ne!(develop(&h).crop, before.crop, "the drag cropped"); + assert_eq!(develop(&h).crop.aspect, None); +} + #[test] fn double_click_in_crop_box_applies_the_crop() { let mut h = detail("panel.crop");