From 5c312726057695cfde75842f03f348115059058b Mon Sep 17 00:00:00 2001 From: Sophie Herold Date: Sat, 21 Dec 2024 21:39:49 +0100 Subject: [PATCH] edit/crop: Support vertical mirroring --- Cargo.lock | 4 +- Cargo.toml | 2 +- build-aux/flatpak/org.gnome.Loupe.Devel.json | 2 +- src/editing/preview.rs | 15 ++++- src/widgets/edit/crop.rs | 58 +++++++++++--------- src/widgets/edit/crop.ui | 4 +- 6 files changed, 52 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 06ad381..8e6f4b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -898,7 +898,7 @@ dependencies = [ [[package]] name = "glycin" version = "2.0.1" -source = "git+https://gitlab.gnome.org/GNOME/glycin.git?rev=967abc701e9969936ecece4a9408663d0a67b1d5#967abc701e9969936ecece4a9408663d0a67b1d5" +source = "git+https://gitlab.gnome.org/GNOME/glycin.git?rev=a7922d4435d3d8db392b33f4733ea164bc78c77f#a7922d4435d3d8db392b33f4733ea164bc78c77f" dependencies = [ "async-fs", "async-io", @@ -929,7 +929,7 @@ dependencies = [ [[package]] name = "glycin-utils" version = "3.0.0" -source = "git+https://gitlab.gnome.org/GNOME/glycin.git?rev=967abc701e9969936ecece4a9408663d0a67b1d5#967abc701e9969936ecece4a9408663d0a67b1d5" +source = "git+https://gitlab.gnome.org/GNOME/glycin.git?rev=a7922d4435d3d8db392b33f4733ea164bc78c77f#a7922d4435d3d8db392b33f4733ea164bc78c77f" dependencies = [ "env_logger", "gufo-common", diff --git a/Cargo.toml b/Cargo.toml index 74f69fb..15348ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ gettext-sys = { version = "0.22.5", features = ["gettext-system"] } gio = { version = "0.20.0", features = ["v2_74"] } glycin = { version = "2.0.1", features = [ "gdk4", -], git = "https://gitlab.gnome.org/GNOME/glycin.git", rev = "967abc701e9969936ecece4a9408663d0a67b1d5" } +], git = "https://gitlab.gnome.org/GNOME/glycin.git", rev = "a7922d4435d3d8db392b33f4733ea164bc78c77f" } gtk = { package = "gtk4", version = "0.9.5", features = [ "v4_14", "xml_validation", diff --git a/build-aux/flatpak/org.gnome.Loupe.Devel.json b/build-aux/flatpak/org.gnome.Loupe.Devel.json index 0ee27b3..882add5 100644 --- a/build-aux/flatpak/org.gnome.Loupe.Devel.json +++ b/build-aux/flatpak/org.gnome.Loupe.Devel.json @@ -113,7 +113,7 @@ { "type": "git", "url": "https://gitlab.gnome.org/GNOME/glycin.git", - "commit": "967abc701e9969936ecece4a9408663d0a67b1d5" + "commit": "a7922d4435d3d8db392b33f4733ea164bc78c77f" } ] }, diff --git a/src/editing/preview.rs b/src/editing/preview.rs index 2c9017d..3a5de6f 100644 --- a/src/editing/preview.rs +++ b/src/editing/preview.rs @@ -58,8 +58,9 @@ impl OperationsSnapshot { for operation in operations.operations() { let operation_result = match operation { Operation::Clip(rect) => self.clip(*rect), - Operation::Rotate(rotation) => self.rotate(*rotation), Operation::MirrorHorizontally => self.mirror_horizontally(), + Operation::MirrorVertically => self.mirror_vertically(), + Operation::Rotate(rotation) => self.rotate(*rotation), unsupported_operation => { return Err(EditingError::UnsupportedOperation( unsupported_operation.clone(), @@ -116,6 +117,18 @@ impl OperationsSnapshot { Ok(()) } + fn mirror_vertically(&mut self) -> Result<(), OperationError> { + let snapshot = gtk::Snapshot::new(); + + snapshot.translate(&graphene::Point::new(0., self.height as f32 * self.scale)); + snapshot.scale(1., -1.); + snapshot.append_node(self.current_node.clone()); + + self.current_node = snapshot.to_node().ok_or(OperationError::EmptyNode)?; + + Ok(()) + } + fn rotate( &mut self, rotation: gufo_common::orientation::Rotation, diff --git a/src/widgets/edit/crop.rs b/src/widgets/edit/crop.rs index e0e555b..94681da 100644 --- a/src/widgets/edit/crop.rs +++ b/src/widgets/edit/crop.rs @@ -97,20 +97,23 @@ mod imp { klass.install_property_action("edit-crop.aspect-ratio", "aspect_ratio"); klass.install_property_action("edit-crop.orientation", "orientation"); - klass.install_action("edit-crop.mirror", None, |obj, _, _| { - obj.handle_error(obj.imp().apply_mirror()); + klass.install_action("edit-crop.mirror-horizontally", None, |obj, _, _| { + obj.imp().apply_mirror_horizontally(); + }); + klass.install_action("edit-crop.mirror-vertically", None, |obj, _, _| { + obj.imp().apply_mirror_vertically() }); klass.install_action("edit-crop.rotate-cw", None, |obj, _, _| { - obj.handle_error(obj.imp().apply_rotate_cw()); + obj.imp().apply_rotate_cw() }); klass.install_action("edit-crop.rotate-ccw", None, |obj, _, _| { - obj.handle_error(obj.imp().apply_rotate_ccw()); + obj.imp().apply_rotate_ccw() }); klass.install_action("edit-crop.reset", None, |obj, _, _| { - obj.handle_error(obj.imp().apply_reset()); + obj.handle_error(obj.imp().apply_reset()) }); klass.install_action("edit-crop.apply-crop", None, |obj, _, _| { - obj.handle_error(obj.imp().apply_crop()); + obj.imp().apply_crop() }); } @@ -241,38 +244,36 @@ mod imp { self.selection.reset(x, y, width, height); } - fn apply_crop(&self) -> Result<(), EditingError> { + fn apply_crop(&self) { if let Some(crop) = self.crop_area_image_coord() { - self.add_operation(Operation::Clip(crop))?; + self.add_operation(Operation::Clip(crop)); self.reset_selection(); } - - Ok(()) } - fn apply_mirror(&self) -> Result<(), EditingError> { - self.add_operation(Operation::MirrorHorizontally)?; + fn apply_mirror_horizontally(&self) { + self.add_operation(Operation::MirrorHorizontally); self.reset_selection(); - - Ok(()) } - fn apply_rotate_cw(&self) -> Result<(), EditingError> { - self.add_operation(Operation::Rotate(gufo_common::orientation::Rotation::_90))?; + fn apply_mirror_vertically(&self) { + self.add_operation(Operation::MirrorVertically); self.reset_selection(); - - Ok(()) } - fn apply_rotate_ccw(&self) -> Result<(), EditingError> { - self.add_operation(Operation::Rotate(gufo_common::orientation::Rotation::_270))?; + fn apply_rotate_cw(&self) { + self.add_operation(Operation::Rotate(gufo_common::orientation::Rotation::_90)); self.reset_selection(); + } - Ok(()) + fn apply_rotate_ccw(&self) { + self.add_operation(Operation::Rotate(gufo_common::orientation::Rotation::_270)); + + self.reset_selection(); } fn apply_reset(&self) -> Result<(), EditingError> { @@ -287,16 +288,21 @@ mod imp { Ok(()) } - fn add_operation(&self, operation: Operation) -> Result<(), EditingError> { + fn add_operation(&self, operation: Operation) { let obj = self.obj(); let edit_window = obj.edit_window(); + let previous_operiatons = edit_window.operations(); edit_window.add_operation(operation); - self.image.set_operations(edit_window.operations())?; + let res = self.image.set_operations(edit_window.operations()); - obj.action_set_enabled("edit-crop.reset", true); - - Ok(()) + if res.is_err() { + obj.handle_error(res); + // Reset to set of hopefully working operations + edit_window.set_operations(previous_operiatons); + } else { + obj.action_set_enabled("edit-crop.reset", true); + } } } } diff --git a/src/widgets/edit/crop.ui b/src/widgets/edit/crop.ui index 11afa8c..d98165e 100644 --- a/src/widgets/edit/crop.ui +++ b/src/widgets/edit/crop.ui @@ -245,13 +245,13 @@ edit-mirror-symbolic - edit-crop.mirror + edit-crop.mirror-horizontally edit-mirror-vertically-symbolic - edit-crop.mirror + edit-crop.mirror-vertically