From 977a1949236119fb429eca92170dde762210be5a Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Sat, 20 Apr 2013 23:22:14 +0200 Subject: [PATCH] app: add a rotate dialog to rotate to exact degrees --- app/actions/view-actions.c | 7 + app/actions/view-commands.c | 14 ++ app/actions/view-commands.h | 2 + app/display/Makefile.am | 2 + app/display/gimpdisplayshell-rotate-dialog.c | 188 +++++++++++++++++++ app/display/gimpdisplayshell-rotate-dialog.h | 25 +++ app/display/gimpdisplayshell.h | 1 + app/widgets/gimphelp-ids.h | 1 + menus/image-menu.xml.in | 2 + po/POTFILES.in | 1 + 10 files changed, 243 insertions(+) create mode 100644 app/display/gimpdisplayshell-rotate-dialog.c create mode 100644 app/display/gimpdisplayshell-rotate-dialog.h diff --git a/app/actions/view-actions.c b/app/actions/view-actions.c index 8cb951b446..deec5246e3 100644 --- a/app/actions/view-actions.c +++ b/app/actions/view-actions.c @@ -110,6 +110,12 @@ static const GimpActionEntry view_actions[] = G_CALLBACK (view_rotate_reset_cmd_callback), GIMP_HELP_VIEW_ROTATE_RESET }, + { "view-rotate-other", NULL, + NC_("view-action", "Othe_r..."), NULL, + NC_("view-action", "Set a custom rotation angle"), + G_CALLBACK (view_rotate_other_cmd_callback), + GIMP_HELP_VIEW_ROTATE_OTHER }, + { "view-navigation-window", GIMP_STOCK_NAVIGATION, NC_("view-action", "Na_vigation Window"), NULL, NC_("view-action", "Show an overview window for this image"), @@ -669,6 +675,7 @@ view_actions_update (GimpActionGroup *group, 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) { diff --git a/app/actions/view-commands.c b/app/actions/view-commands.c index cc2889c0a4..07686a861b 100644 --- a/app/actions/view-commands.c +++ b/app/actions/view-commands.c @@ -46,6 +46,7 @@ #include "display/gimpdisplayshell-appearance.h" #include "display/gimpdisplayshell-filter-dialog.h" #include "display/gimpdisplayshell-rotate.h" +#include "display/gimpdisplayshell-rotate-dialog.h" #include "display/gimpdisplayshell-scale.h" #include "display/gimpdisplayshell-scale-dialog.h" #include "display/gimpdisplayshell-scroll.h" @@ -317,6 +318,19 @@ view_rotate_cmd_callback (GtkAction *action, gimp_display_shell_rotate (shell, delta); } +void +view_rotate_other_cmd_callback (GtkAction *action, + gpointer data) +{ + GimpDisplay *display; + GimpDisplayShell *shell; + return_if_no_display (display, data); + + shell = gimp_display_get_shell (display); + + gimp_display_shell_rotate_dialog (shell); +} + void view_scroll_horizontal_cmd_callback (GtkAction *action, gint value, diff --git a/app/actions/view-commands.h b/app/actions/view-commands.h index 810c33516e..a207ed3b89 100644 --- a/app/actions/view-commands.h +++ b/app/actions/view-commands.h @@ -53,6 +53,8 @@ void view_rotate_reset_cmd_callback (GtkAction *action, void view_rotate_cmd_callback (GtkAction *action, gint value, gpointer data); +void view_rotate_other_cmd_callback (GtkAction *action, + gpointer data); void view_navigation_window_cmd_callback (GtkAction *action, gpointer data); diff --git a/app/display/Makefile.am b/app/display/Makefile.am index 3539dc289f..336ccf36d6 100644 --- a/app/display/Makefile.am +++ b/app/display/Makefile.am @@ -115,6 +115,8 @@ libappdisplay_a_sources = \ gimpdisplayshell-render.h \ gimpdisplayshell-rotate.c \ gimpdisplayshell-rotate.h \ + gimpdisplayshell-rotate-dialog.c \ + gimpdisplayshell-rotate-dialog.h \ gimpdisplayshell-scale.c \ gimpdisplayshell-scale.h \ gimpdisplayshell-scale-dialog.c \ diff --git a/app/display/gimpdisplayshell-rotate-dialog.c b/app/display/gimpdisplayshell-rotate-dialog.c new file mode 100644 index 0000000000..7a4bdcf506 --- /dev/null +++ b/app/display/gimpdisplayshell-rotate-dialog.c @@ -0,0 +1,188 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "config.h" + +#include +#include + +#include "libgimpmath/gimpmath.h" +#include "libgimpwidgets/gimpwidgets.h" + +#include "display-types.h" + +#include "core/gimp.h" +#include "core/gimpviewable.h" + +#include "widgets/gimphelp-ids.h" +#include "widgets/gimpviewabledialog.h" + +#include "gimpdisplay.h" +#include "gimpdisplayshell.h" +#include "gimpdisplayshell-rotate.h" +#include "gimpdisplayshell-rotate-dialog.h" + +#include "gimp-intl.h" + + +typedef struct +{ + GimpDisplayShell *shell; + GtkAdjustment *rotate_adj; +} RotateDialogData; + + +/* local function prototypes */ + +static void gimp_display_shell_rotate_dialog_response (GtkWidget *widget, + gint response_id, + RotateDialogData *dialog); +static void gimp_display_shell_rotate_dialog_free (RotateDialogData *dialog); + +static void update_rotate (GtkAdjustment *adj, + RotateDialogData *dialog); + + + +/* public functions */ + +/** + * gimp_display_shell_rotate_dialog: + * @shell: the #GimpDisplayShell + * + * Constructs and displays a dialog allowing the user to enter a + * custom display rotate. + **/ +void +gimp_display_shell_rotate_dialog (GimpDisplayShell *shell) +{ + RotateDialogData *data; + GimpImage *image; + GtkWidget *toplevel; + GtkWidget *hbox; + GtkWidget *spin; + GtkWidget *label; + + g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); + + if (shell->rotate_dialog) + { + gtk_window_present (GTK_WINDOW (shell->rotate_dialog)); + return; + } + + image = gimp_display_get_image (shell->display); + + data = g_slice_new (RotateDialogData); + + data->shell = shell; + + shell->rotate_dialog = + gimp_viewable_dialog_new (GIMP_VIEWABLE (image), + gimp_get_user_context (shell->display->gimp), + _("Rotate View"), "display-rotate", + GIMP_STOCK_ROTATE_180, + _("Select Rotation Angle"), + GTK_WIDGET (shell), + gimp_standard_help_func, + GIMP_HELP_VIEW_ROTATE_OTHER, + + GTK_STOCK_OK, GTK_RESPONSE_OK, + + NULL); + + gtk_dialog_set_alternative_button_order (GTK_DIALOG (shell->rotate_dialog), + GTK_RESPONSE_OK, + -1); + + g_object_weak_ref (G_OBJECT (shell->rotate_dialog), + (GWeakNotify) gimp_display_shell_rotate_dialog_free, data); + + g_object_add_weak_pointer (G_OBJECT (shell->rotate_dialog), + (gpointer) &shell->rotate_dialog); + + toplevel = gtk_widget_get_toplevel (GTK_WIDGET (shell)); + + gtk_window_set_transient_for (GTK_WINDOW (shell->rotate_dialog), + GTK_WINDOW (toplevel)); + gtk_window_set_destroy_with_parent (GTK_WINDOW (shell->rotate_dialog), TRUE); + + g_signal_connect (shell->rotate_dialog, "response", + G_CALLBACK (gimp_display_shell_rotate_dialog_response), + data); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_container_set_border_width (GTK_CONTAINER (hbox), 12); + gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (shell->rotate_dialog))), + hbox, TRUE, TRUE, 0); + gtk_widget_show (hbox); + + label = gtk_label_new (_("Angle:")); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + gtk_widget_show (label); + + spin = gimp_spin_button_new ((GtkObject **) &data->rotate_adj, + shell->rotate_angle, + 0.0, 360.0, + 1, 15, 0, 1, 2); + gtk_entry_set_activates_default (GTK_ENTRY (spin), TRUE); + gtk_box_pack_start (GTK_BOX (hbox), spin, TRUE, TRUE, 0); + gtk_widget_show (spin); + + label = gtk_label_new (_("degrees")); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + gtk_widget_show (label); + + g_signal_connect (data->rotate_adj, "value-changed", + G_CALLBACK (update_rotate), data); + + gtk_widget_show (shell->rotate_dialog); +} + +static void +gimp_display_shell_rotate_dialog_response (GtkWidget *widget, + gint response_id, + RotateDialogData *dialog) +{ + if (response_id == GTK_RESPONSE_OK) + { + gdouble angle; + + angle = gtk_adjustment_get_value (dialog->rotate_adj); + + gimp_display_shell_rotate_to (dialog->shell, angle); + } + + gtk_widget_destroy (dialog->shell->rotate_dialog); +} + +static void +gimp_display_shell_rotate_dialog_free (RotateDialogData *dialog) +{ + g_slice_free (RotateDialogData, dialog); +} + +static void +update_rotate (GtkAdjustment *adj, + RotateDialogData *dialog) +{ + gdouble angle; + + angle = gtk_adjustment_get_value (dialog->rotate_adj); + + gimp_display_shell_rotate_to (dialog->shell, angle); +} diff --git a/app/display/gimpdisplayshell-rotate-dialog.h b/app/display/gimpdisplayshell-rotate-dialog.h new file mode 100644 index 0000000000..8d3c6b89db --- /dev/null +++ b/app/display/gimpdisplayshell-rotate-dialog.h @@ -0,0 +1,25 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __GIMP_DISPLAY_SHELL_ROTATE_DIALOG_H__ +#define __GIMP_DISPLAY_SHELL_ROTATE_DIALOG_H__ + + +void gimp_display_shell_rotate_dialog (GimpDisplayShell *shell); + + +#endif /* __GIMP_DISPLAY_SHELL_ROTATE_DIALOG_H__ */ diff --git a/app/display/gimpdisplayshell.h b/app/display/gimpdisplayshell.h index 640cfdfd2c..4038aba8b4 100644 --- a/app/display/gimpdisplayshell.h +++ b/app/display/gimpdisplayshell.h @@ -149,6 +149,7 @@ struct _GimpDisplayShell GtkWidget *close_dialog; /* close dialog */ GtkWidget *scale_dialog; /* scale (zoom) dialog */ + GtkWidget *rotate_dialog; /* rotate dialog */ GtkWidget *nav_popup; /* navigation popup */ GtkWidget *grid_dialog; /* grid configuration dialog */ diff --git a/app/widgets/gimphelp-ids.h b/app/widgets/gimphelp-ids.h index 00e98e5f53..3ffb8f536c 100644 --- a/app/widgets/gimphelp-ids.h +++ b/app/widgets/gimphelp-ids.h @@ -89,6 +89,7 @@ #define GIMP_HELP_VIEW_ROTATE_90 "gimp-view-rotate-90" #define GIMP_HELP_VIEW_ROTATE_180 "gimp-view-rotate-180" #define GIMP_HELP_VIEW_ROTATE_270 "gimp-view-rotate-270" +#define GIMP_HELP_VIEW_ROTATE_OTHER "gimp-view-rotate-other" #define GIMP_HELP_VIEW_SHOW_SELECTION "gimp-view-show-selection" #define GIMP_HELP_VIEW_SHOW_LAYER_BOUNDARY "gimp-view-show-layer-boundary" #define GIMP_HELP_VIEW_SHOW_GUIDES "gimp-view-show-guides" diff --git a/menus/image-menu.xml.in b/menus/image-menu.xml.in index 551e7658ec..b80ab39fdf 100644 --- a/menus/image-menu.xml.in +++ b/menus/image-menu.xml.in @@ -275,6 +275,8 @@ + + diff --git a/po/POTFILES.in b/po/POTFILES.in index 048d1dfb8c..b31dd3fd6b 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -218,6 +218,7 @@ app/display/gimpdisplayshell-dnd.c app/display/gimpdisplayshell-filter-dialog.c app/display/gimpdisplayshell-handlers.c app/display/gimpdisplayshell-layer-select.c +app/display/gimpdisplayshell-rotate-dialog.c app/display/gimpdisplayshell-scale-dialog.c app/display/gimpdisplayshell-title.c app/display/gimpnavigationeditor.c