Crop tool: Enter crops to the selection's frame (#1806)

With a selection, the Crop tool's untouched default frame frames the selection's bounds, but
Enter on it did nothing (it was always treated as the no-op whole-canvas frame). It now only
skips the commit when the frame is the whole canvas. Tested at 8 and 16 bits. Fixes #1789.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
David MannandClaude Opus 5.5 authored and GitHub committed 2026-10-09 12:27:22 -04:00
1 parent dcf8ceef85
commit a42f7f0004
2 files changed
+29 -2

No files matched your search

+6 -2
View File
@@ -3857,9 +3857,13 @@ pub fn commit_polygon(app: &mut PhotocraftApp) {
/// Apply the crop tool's rectangle.
pub fn commit_crop(app: &mut PhotocraftApp) {
let Some(r) = app.ui.crop_rect.take() else { return };
// The untouched default frame crops nothing (Photoshop's ↵ on it does nothing).
// The untouched default frame around the whole canvas crops nothing (Photoshop's ↵ on it does
// nothing); one framing the selection's bounds crops to them (#1789).
if std::mem::take(&mut app.crop.default_frame) {
return;
let whole = app.session.active().map(|st| st.doc.bounds()).map(|b| [f64::from(b.x0), f64::from(b.y0), f64::from(b.x1), f64::from(b.y1)]);
if whole.is_none_or(|b| b == r) {
return;
}
}
let (x, y) = (r[0].round(), r[1].round());
let (w, h) = ((r[2] - r[0]).round().max(1.0), (r[3] - r[1]).round().max(1.0));
+23
View File
@@ -375,6 +375,29 @@ mod tests {
assert_eq!(app.ui.crop_rect, None);
}
#[test]
fn enter_on_the_selection_frame_crops_to_it_at_8_and_16_bit() {
// #1789: selection, C, ↵ did nothing, as the untouched frame was always treated as a no-op.
for depth in [SampleType::U8, SampleType::U16] {
let mut app = app(depth);
app.run("select.rect", json!({"x": 10, "y": 20, "width": 30, "height": 40})).unwrap();
ensure_frame(&mut app);
assert_eq!(app.ui.crop_rect, Some([10.0, 20.0, 40.0, 60.0]));
crate::canvas::commit_crop(&mut app);
let doc = &app.session.active().unwrap().doc;
assert_eq!(doc.size, Size::new(30, 40), "{depth:?}");
assert_eq!(doc.depth, depth);
assert!(doc.selection.is_none(), "cropping to the selection deselects, as in Photoshop");
// The new default frame is the whole (cropped) canvas: ↵ on it does nothing.
ensure_frame(&mut app);
assert_eq!(app.ui.crop_rect, Some([0.0, 0.0, 30.0, 40.0]));
let steps = app.session.active().unwrap().history.past_len();
crate::canvas::commit_crop(&mut app);
let st = app.session.active().unwrap();
assert_eq!((st.doc.size, st.history.past_len()), (Size::new(30, 40), steps), "{depth:?}");
}
}
#[test]
fn the_frame_is_edited_from_a_press_until_commit_cancel_or_another_tool() {
let mut app = app(SampleType::U8);