mirror of
https://github.com/storytold/lightcraft.git
synced 2026-10-27 19:47:35 -06:00
LR-CROP-STRAIGHTEN: a crop drag cut short leaves nothing behind
Closing the crop tool in the middle of a rotation (Return, Esc) left the rotate gesture set, as only the canvas's drag-stopped cleared it. Once the rotation pointer and angle readout were derived from it, reopening Crop showed both everywhere, over the side panels too, until the next drag. A crop gesture with no button held is now over. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
b83ba84a79
commit
f34c967900
@@ -1248,6 +1248,14 @@ fn crop_overlay(app: &mut LightcraftApp, ui: &mut egui::Ui, resp: &egui::Respons
|
||||
let s = to_straight(n, d.crop.geometry.angle, frame);
|
||||
d.crop.geometry.rect.contains(Point::new(s.x.clamp(-1.0, 2.0), s.y))
|
||||
};
|
||||
// a crop drag cut short (the tool closed before the release) leaves its gesture behind: with no
|
||||
// button held it is over
|
||||
if matches!(app.gesture, Some(Gesture::CropRotate { .. } | Gesture::CropHandle { .. }))
|
||||
&& !resp.drag_stopped()
|
||||
&& !ui.input(|i| i.pointer.any_down())
|
||||
{
|
||||
app.gesture = None;
|
||||
}
|
||||
// while rotating, the pointer may leave the canvas: it still shows rotation and the angle
|
||||
let rotating = matches!(app.gesture, Some(Gesture::CropRotate { .. }));
|
||||
let pointer = resp.hover_pos().or_else(|| if rotating { ui.input(|i| i.pointer.latest_pos()) } else { None });
|
||||
|
||||
@@ -300,3 +300,32 @@ fn moving_the_box_never_shows_rotation() {
|
||||
assert!(!has(&h, "cropRotateCursor"));
|
||||
assert_eq!(angle(&h), 0.0, "nothing rotated");
|
||||
}
|
||||
|
||||
/// Closing the crop tool in the middle of a rotation (Return) leaves nothing behind: reopened,
|
||||
/// the box shows the move pointer and no angle.
|
||||
#[test]
|
||||
fn a_rotation_cut_short_leaves_nothing_behind() {
|
||||
let mut h = crop_tool();
|
||||
let r = h.request(
|
||||
"ui.pointer",
|
||||
json!({"events": [{"kind": "down", "x": -0.05, "y": 0.2}, {"kind": "drag", "x": -0.05, "y": 0.25}, {"kind": "drag", "x": -0.05, "y": 0.3}]}),
|
||||
T,
|
||||
);
|
||||
assert_eq!(r["ok"], true, "{r}");
|
||||
h.settle(SETTLE);
|
||||
assert!(has(&h, "cropAngleReadout"), "rotating");
|
||||
for (method, params) in [
|
||||
("engine.execute", json!({"command": "tool.done"})),
|
||||
("ui.pointer", json!({"events": [{"kind": "up", "x": -0.05, "y": 0.3}]})),
|
||||
("engine.execute", json!({"command": "panel.crop"})),
|
||||
] {
|
||||
let r = h.request(method, params, T);
|
||||
assert_eq!(r["ok"], true, "{r}");
|
||||
h.settle(SETTLE);
|
||||
}
|
||||
let img = h.app.image_rect.expect("the photo on screen");
|
||||
hover(&mut h, img.center());
|
||||
assert_eq!(h.last_cursor, egui::CursorIcon::Move);
|
||||
assert!(!has(&h, "cropAngleReadout"), "no angle");
|
||||
assert!(!has(&h, "cropRotateCursor"), "no rotation glyph");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user