[gimp] Bug 758049 - Please add canvas flipping
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] Bug 758049 - Please add canvas flipping
- Date: Fri, 13 Nov 2015 17:52:57 +0000 (UTC)
commit c6b6031f316c7a371d626578d4d4f9dd4ef034a9
Author: Michael Natterer <mitch gimp org>
Date: Fri Nov 13 18:51:32 2015 +0100
Bug 758049 - Please add canvas flipping
Enable flipping in the canvas rotate transform matrix, and add some
menu items to control it. Rename the "Rotate" menu to "Flip & Rotate".
app/actions/view-actions.c | 154 ++++++++++++++++++++----------
app/actions/view-commands.c | 41 ++++++++
app/actions/view-commands.h | 5 +
app/display/gimpdisplayshell-rotate.c | 36 +++++++-
app/display/gimpdisplayshell-rotate.h | 4 +
app/display/gimpdisplayshell-transform.h | 9 +-
app/display/gimpdisplayshell.c | 4 +-
app/display/gimpdisplayshell.h | 2 +
app/widgets/gimphelp-ids.h | 1 +
menus/image-menu.xml.in | 3 +
10 files changed, 201 insertions(+), 58 deletions(-)
---
diff --git a/app/actions/view-actions.c b/app/actions/view-actions.c
index 6efcd9d..a9533a0 100644
--- a/app/actions/view-actions.c
+++ b/app/actions/view-actions.c
@@ -68,7 +68,7 @@ static const GimpActionEntry view_actions[] =
{
{ "view-menu", NULL, NC_("view-action", "_View") },
{ "view-zoom-menu", NULL, NC_("view-action", "_Zoom") },
- { "view-rotate-menu", NULL, NC_("view-action", "_Rotate") },
+ { "view-rotate-menu", NULL, NC_("view-action", "_Flip & Rotate") },
{ "view-padding-color-menu", NULL, NC_("view-action", "_Padding Color") },
{ "view-move-to-screen-menu", GIMP_STOCK_MOVE_TO_SCREEN,
NC_("view-action", "Move to Screen"), NULL, NULL, NULL,
@@ -394,6 +394,21 @@ static const GimpRadioActionEntry view_zoom_explicit_actions[] =
GIMP_HELP_VIEW_ZOOM_OTHER }
};
+static const GimpToggleActionEntry view_flip_actions[] =
+{
+ { "view-flip-horizontally", GIMP_STOCK_FLIP_HORIZONTAL,
+ NC_("view-action", "Flip Horizontally"), NULL, NULL,
+ G_CALLBACK (view_flip_horizontally_cmd_callback),
+ FALSE,
+ GIMP_HELP_VIEW_FLIP },
+
+ { "view-flip-vertically", GIMP_STOCK_FLIP_VERTICAL,
+ NC_("view-action", "Flip Vertically"), NULL, NULL,
+ G_CALLBACK (view_flip_vertically_cmd_callback),
+ FALSE,
+ GIMP_HELP_VIEW_FLIP }
+};
+
static const GimpEnumActionEntry view_rotate_absolute_actions[] =
{
{ "view-rotate-set-absolute", NULL,
@@ -402,8 +417,9 @@ static const GimpEnumActionEntry view_rotate_absolute_actions[] =
NULL },
{ "view-rotate-reset", GIMP_STOCK_RESET,
- NC_("view-action", "_Reset to 0°"), "exclam",
- NC_("view-action", "Reset the angle of rotation to 0°"),
+ NC_("view-action", "_Reset Flip & Rotate"), "exclam",
+ NC_("view-action",
+ "Reset flipping to unflipped and the angle of rotation to 0°"),
GIMP_ACTION_SELECT_SET_TO_DEFAULT, FALSE,
GIMP_HELP_VIEW_ROTATE_RESET },
};
@@ -577,6 +593,10 @@ view_actions_setup (GimpActionGroup *group)
10000,
G_CALLBACK (view_zoom_explicit_cmd_callback));
+ gimp_action_group_add_toggle_actions (group, "view-action",
+ view_flip_actions,
+ G_N_ELEMENTS (view_flip_actions));
+
gimp_action_group_add_enum_actions (group, "view-action",
view_rotate_absolute_actions,
G_N_ELEMENTS (view_rotate_absolute_actions),
@@ -633,13 +653,15 @@ void
view_actions_update (GimpActionGroup *group,
gpointer data)
{
- GimpDisplay *display = action_data_get_display (data);
- GimpImage *image = NULL;
- GimpDisplayShell *shell = NULL;
- GimpDisplayOptions *options = NULL;
- gchar *label = NULL;
- gboolean fullscreen = FALSE;
- gboolean revert_enabled = FALSE; /* able to revert zoom? */
+ GimpDisplay *display = action_data_get_display (data);
+ GimpImage *image = NULL;
+ GimpDisplayShell *shell = NULL;
+ GimpDisplayOptions *options = NULL;
+ gchar *label = NULL;
+ gboolean fullscreen = FALSE;
+ gboolean revert_enabled = FALSE; /* able to revert zoom? */
+ gboolean flip_horizontally = FALSE;
+ gboolean flip_vertically = FALSE;
if (display)
{
@@ -657,6 +679,9 @@ view_actions_update (GimpActionGroup *group,
shell->no_image_options);
revert_enabled = gimp_display_shell_scale_can_revert (shell);
+
+ flip_horizontally = shell->flip_horizontally;
+ flip_vertically = shell->flip_vertically;
}
#define SET_ACTIVE(action,condition) \
@@ -686,44 +711,50 @@ view_actions_update (GimpActionGroup *group,
_("Re_vert Zoom"));
}
- SET_SENSITIVE ("view-zoom", image);
- SET_SENSITIVE ("view-zoom-minimum", image);
- SET_SENSITIVE ("view-zoom-maximum", image);
- SET_SENSITIVE ("view-zoom-in", image);
- SET_SENSITIVE ("view-zoom-in-accel", image);
- SET_SENSITIVE ("view-zoom-in-skip", image);
- SET_SENSITIVE ("view-zoom-out", image);
- SET_SENSITIVE ("view-zoom-out-accel", image);
- SET_SENSITIVE ("view-zoom-out-skip", image);
-
- SET_SENSITIVE ("view-zoom-fit-in", image);
- SET_SENSITIVE ("view-zoom-fill", image);
- SET_SENSITIVE ("view-zoom-selection", image);
- SET_SENSITIVE ("view-zoom-revert", image);
-
- SET_SENSITIVE ("view-zoom-16-1", image);
- SET_SENSITIVE ("view-zoom-16-1-accel", image);
- SET_SENSITIVE ("view-zoom-8-1", image);
- SET_SENSITIVE ("view-zoom-8-1-accel", image);
- SET_SENSITIVE ("view-zoom-4-1", image);
- SET_SENSITIVE ("view-zoom-4-1-accel", image);
- SET_SENSITIVE ("view-zoom-2-1", image);
- SET_SENSITIVE ("view-zoom-2-1-accel", image);
- SET_SENSITIVE ("view-zoom-1-1", image);
- SET_SENSITIVE ("view-zoom-1-1-accel", image);
- SET_SENSITIVE ("view-zoom-1-2", image);
- SET_SENSITIVE ("view-zoom-1-4", image);
- SET_SENSITIVE ("view-zoom-1-8", image);
- SET_SENSITIVE ("view-zoom-1-16", image);
- SET_SENSITIVE ("view-zoom-other", image);
-
- SET_SENSITIVE ("view-rotate-reset", image);
- SET_SENSITIVE ("view-rotate-15", image);
- SET_SENSITIVE ("view-rotate-345", image);
- SET_SENSITIVE ("view-rotate-90", image);
- SET_SENSITIVE ("view-rotate-180", image);
- SET_SENSITIVE ("view-rotate-270", image);
- SET_SENSITIVE ("view-rotate-other", image);
+ SET_SENSITIVE ("view-zoom", image);
+ SET_SENSITIVE ("view-zoom-minimum", image);
+ SET_SENSITIVE ("view-zoom-maximum", image);
+ SET_SENSITIVE ("view-zoom-in", image);
+ SET_SENSITIVE ("view-zoom-in-accel", image);
+ SET_SENSITIVE ("view-zoom-in-skip", image);
+ SET_SENSITIVE ("view-zoom-out", image);
+ SET_SENSITIVE ("view-zoom-out-accel", image);
+ SET_SENSITIVE ("view-zoom-out-skip", image);
+
+ SET_SENSITIVE ("view-zoom-fit-in", image);
+ SET_SENSITIVE ("view-zoom-fill", image);
+ SET_SENSITIVE ("view-zoom-selection", image);
+ SET_SENSITIVE ("view-zoom-revert", image);
+
+ SET_SENSITIVE ("view-zoom-16-1", image);
+ SET_SENSITIVE ("view-zoom-16-1-accel", image);
+ SET_SENSITIVE ("view-zoom-8-1", image);
+ SET_SENSITIVE ("view-zoom-8-1-accel", image);
+ SET_SENSITIVE ("view-zoom-4-1", image);
+ SET_SENSITIVE ("view-zoom-4-1-accel", image);
+ SET_SENSITIVE ("view-zoom-2-1", image);
+ SET_SENSITIVE ("view-zoom-2-1-accel", image);
+ SET_SENSITIVE ("view-zoom-1-1", image);
+ SET_SENSITIVE ("view-zoom-1-1-accel", image);
+ SET_SENSITIVE ("view-zoom-1-2", image);
+ SET_SENSITIVE ("view-zoom-1-4", image);
+ SET_SENSITIVE ("view-zoom-1-8", image);
+ SET_SENSITIVE ("view-zoom-1-16", image);
+ SET_SENSITIVE ("view-zoom-other", image);
+
+ SET_SENSITIVE ("view-flip-horizontally", image);
+ SET_ACTIVE ("view-flip-horizontally", flip_horizontally);
+
+ SET_SENSITIVE ("view-flip-vertically", image);
+ SET_ACTIVE ("view-flip-vertically", flip_vertically);
+
+ SET_SENSITIVE ("view-rotate-reset", image);
+ SET_SENSITIVE ("view-rotate-15", image);
+ SET_SENSITIVE ("view-rotate-345", image);
+ SET_SENSITIVE ("view-rotate-90", image);
+ SET_SENSITIVE ("view-rotate-180", image);
+ SET_SENSITIVE ("view-rotate-270", image);
+ SET_SENSITIVE ("view-rotate-other", image);
if (image)
{
@@ -866,9 +897,32 @@ static void
view_actions_set_rotate (GimpActionGroup *group,
GimpDisplayShell *shell)
{
- gchar *label;
+ const gchar *flip;
+ gchar *label;
+
+ if (shell->flip_horizontally &&
+ shell->flip_vertically)
+ {
+ /* please preserve the trailing space */
+ flip = _("(H+V) ");
+ }
+ else if (shell->flip_horizontally)
+ {
+ /* please preserve the trailing space */
+ flip = _("(H) ");
+ }
+ else if (shell->flip_vertically)
+ {
+ /* please preserve the trailing space */
+ flip = _("(V) ");
+ }
+ else
+ {
+ flip = "";
+ }
- label = g_strdup_printf (_("_Rotate (%d°)"), (gint) shell->rotate_angle);
+ label = g_strdup_printf (_("_Flip %s& Rotate (%d°)"),
+ flip, (gint) shell->rotate_angle);
gimp_action_group_set_action_label (group, "view-rotate-menu", label);
g_free (label);
}
diff --git a/app/actions/view-commands.c b/app/actions/view-commands.c
index 8662696..08e0a41 100644
--- a/app/actions/view-commands.c
+++ b/app/actions/view-commands.c
@@ -306,6 +306,44 @@ view_dot_for_dot_cmd_callback (GtkAction *action,
}
void
+view_flip_horizontally_cmd_callback (GtkAction *action,
+ gpointer data)
+{
+ GimpDisplay *display;
+ GimpDisplayShell *shell;
+ gboolean active;
+ return_if_no_display (display, data);
+
+ shell = gimp_display_get_shell (display);
+
+ active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+
+ if (active != shell->flip_horizontally)
+ {
+ gimp_display_shell_flip (shell, active, shell->flip_vertically);
+ }
+}
+
+void
+view_flip_vertically_cmd_callback (GtkAction *action,
+ gpointer data)
+{
+ GimpDisplay *display;
+ GimpDisplayShell *shell;
+ gboolean active;
+ return_if_no_display (display, data);
+
+ shell = gimp_display_get_shell (display);
+
+ active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+
+ if (active != shell->flip_vertically)
+ {
+ gimp_display_shell_flip (shell, shell->flip_horizontally, active);
+ }
+}
+
+void
view_rotate_absolute_cmd_callback (GtkAction *action,
gint value,
gpointer data)
@@ -324,6 +362,9 @@ view_rotate_absolute_cmd_callback (GtkAction *action,
TRUE);
gimp_display_shell_rotate_to (shell, angle);
+
+ if (value == GIMP_ACTION_SELECT_SET_TO_DEFAULT)
+ gimp_display_shell_flip (shell, FALSE, FALSE);
}
void
diff --git a/app/actions/view-commands.h b/app/actions/view-commands.h
index df79065..91b3a3a 100644
--- a/app/actions/view-commands.h
+++ b/app/actions/view-commands.h
@@ -50,6 +50,11 @@ void view_scroll_vertical_cmd_callback (GtkAction *action,
gint value,
gpointer data);
+void view_flip_horizontally_cmd_callback (GtkAction *action,
+ gpointer data);
+void view_flip_vertically_cmd_callback (GtkAction *action,
+ gpointer data);
+
void view_rotate_absolute_cmd_callback (GtkAction *action,
gint value,
gpointer data);
diff --git a/app/display/gimpdisplayshell-rotate.c b/app/display/gimpdisplayshell-rotate.c
index 676c5bd..e928843 100644
--- a/app/display/gimpdisplayshell-rotate.c
+++ b/app/display/gimpdisplayshell-rotate.c
@@ -34,6 +34,24 @@
/* public functions */
void
+gimp_display_shell_flip (GimpDisplayShell *shell,
+ gboolean flip_horizontally,
+ gboolean flip_vertically)
+{
+ g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
+
+ if (flip_horizontally != shell->flip_horizontally ||
+ flip_vertically != shell->flip_vertically)
+ {
+ shell->flip_horizontally = flip_horizontally ? TRUE : FALSE;
+ shell->flip_vertically = flip_vertically ? TRUE : FALSE;
+
+ gimp_display_shell_rotated (shell);
+ gimp_display_shell_expose_full (shell);
+ }
+}
+
+void
gimp_display_shell_rotate (GimpDisplayShell *shell,
gdouble delta)
{
@@ -119,7 +137,10 @@ gimp_display_shell_rotate_update_transform (GimpDisplayShell *shell)
g_free (shell->rotate_transform);
g_free (shell->rotate_untransform);
- if (shell->rotate_angle != 0.0 && gimp_display_get_image (shell->display))
+ if ((shell->rotate_angle != 0.0 ||
+ shell->flip_horizontally ||
+ shell->flip_vertically) &&
+ gimp_display_get_image (shell->display))
{
gint image_width, image_height;
gdouble cx, cy;
@@ -134,8 +155,17 @@ gimp_display_shell_rotate_update_transform (GimpDisplayShell *shell)
cy = -shell->offset_y + image_height / 2;
cairo_matrix_init_translate (shell->rotate_transform, cx, cy);
- cairo_matrix_rotate (shell->rotate_transform,
- shell->rotate_angle / 180.0 * G_PI);
+
+ if (shell->rotate_angle != 0.0)
+ cairo_matrix_rotate (shell->rotate_transform,
+ shell->rotate_angle / 180.0 * G_PI);
+
+ if (shell->flip_horizontally)
+ cairo_matrix_scale (shell->rotate_transform, -1.0, 1.0);
+
+ if (shell->flip_vertically)
+ cairo_matrix_scale (shell->rotate_transform, 1.0, -1.0);
+
cairo_matrix_translate (shell->rotate_transform, -cx, -cy);
*shell->rotate_untransform = *shell->rotate_transform;
diff --git a/app/display/gimpdisplayshell-rotate.h b/app/display/gimpdisplayshell-rotate.h
index 82d3cb1..4d2b09c 100644
--- a/app/display/gimpdisplayshell-rotate.h
+++ b/app/display/gimpdisplayshell-rotate.h
@@ -19,6 +19,10 @@
#define __GIMP_DISPLAY_SHELL_ROTATE_H__
+void gimp_display_shell_flip (GimpDisplayShell *shell,
+ gboolean flip_horizontally,
+ gboolean flip_vertically);
+
void gimp_display_shell_rotate (GimpDisplayShell *shell,
gdouble delta);
void gimp_display_shell_rotate_to (GimpDisplayShell *shell,
diff --git a/app/display/gimpdisplayshell-transform.h b/app/display/gimpdisplayshell-transform.h
index f365236..d263cbd 100644
--- a/app/display/gimpdisplayshell-transform.h
+++ b/app/display/gimpdisplayshell-transform.h
@@ -61,8 +61,8 @@ void gimp_display_shell_zoom_segments (const GimpDisplayShell *shell,
gdouble offset_y);
-/* rotate: functions to transform from unrotated but zoomed display
- * space to rotated display space and back
+/* rotate: functions to transform from unrotated and unflipped but
+ * zoomed display space to rotated and filpped display space and back
*/
void gimp_display_shell_rotate_coords (const GimpDisplayShell *shell,
@@ -114,8 +114,9 @@ void gimp_display_shell_unrotate_bounds (GimpDisplayShell *shell,
gdouble *ny2);
-/* transform: functions to transform from image space to rotated display
- * space and back, taking into account scroll offset, scale, and rotation
+/* transform: functions to transform from image space to rotated
+ * display space and back, taking into account scroll offset, scale,
+ * rotation and flipping
*/
void gimp_display_shell_transform_coords (const GimpDisplayShell *shell,
diff --git a/app/display/gimpdisplayshell.c b/app/display/gimpdisplayshell.c
index f256810..58f4b4b 100644
--- a/app/display/gimpdisplayshell.c
+++ b/app/display/gimpdisplayshell.c
@@ -1472,7 +1472,9 @@ gimp_display_shell_empty (GimpDisplayShell *shell)
gimp_statusbar_empty (GIMP_STATUSBAR (shell->statusbar));
- shell->rotate_angle = 0.0;
+ shell->flip_horizontally = FALSE;
+ shell->flip_vertically = FALSE;
+ shell->rotate_angle = 0.0;
gimp_display_shell_rotate_update_transform (shell);
gimp_display_shell_expose_full (shell);
diff --git a/app/display/gimpdisplayshell.h b/app/display/gimpdisplayshell.h
index 6419d19..cf09fa7 100644
--- a/app/display/gimpdisplayshell.h
+++ b/app/display/gimpdisplayshell.h
@@ -67,6 +67,8 @@ struct _GimpDisplayShell
gdouble scale_x; /* horizontal scale factor */
gdouble scale_y; /* vertical scale factor */
+ gboolean flip_horizontally;
+ gboolean flip_vertically;
gdouble rotate_angle;
cairo_matrix_t *rotate_transform;
cairo_matrix_t *rotate_untransform;
diff --git a/app/widgets/gimphelp-ids.h b/app/widgets/gimphelp-ids.h
index e0e9423..6187064 100644
--- a/app/widgets/gimphelp-ids.h
+++ b/app/widgets/gimphelp-ids.h
@@ -88,6 +88,7 @@
#define GIMP_HELP_VIEW_ZOOM_FILL "gimp-view-zoom-fill"
#define GIMP_HELP_VIEW_ZOOM_SELECTION "gimp-view-zoom-selection"
#define GIMP_HELP_VIEW_ZOOM_OTHER "gimp-view-zoom-other"
+#define GIMP_HELP_VIEW_FLIP "gimp-view-flip"
#define GIMP_HELP_VIEW_ROTATE_RESET "gimp-view-rotate-reset"
#define GIMP_HELP_VIEW_ROTATE_15 "gimp-view-rotate-15"
#define GIMP_HELP_VIEW_ROTATE_90 "gimp-view-rotate-90"
diff --git a/menus/image-menu.xml.in b/menus/image-menu.xml.in
index 5777f06..bd7eaae 100644
--- a/menus/image-menu.xml.in
+++ b/menus/image-menu.xml.in
@@ -277,6 +277,9 @@
<menu action="view-rotate-menu" name="Rotate">
<menuitem action="view-rotate-reset" />
<separator />
+ <menuitem action="view-flip-horizontally" />
+ <menuitem action="view-flip-vertically" />
+ <separator />
<menuitem action="view-rotate-15" />
<menuitem action="view-rotate-345" />
<menuitem action="view-rotate-90" />
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]