From 1dbe765905cd4e302f456b7bcaf252735432615a Mon Sep 17 00:00:00 2001 From: Ell Date: Sat, 9 Jun 2018 16:25:03 -0400 Subject: [PATCH] app: add GimpTransformGridTool; derive most transform tools from it While most of our transform tools use an interactive transform grid, and have similar behavior, the flip tool is an odd one out. The new "auto straighten" function of the measure tool introduces another tool that performs transformations, while not behaving like the rest of the transform tools. Factor out the parts of GimpTransformTool that handle user interaction into GimpTransformGridTool (with corresponding GimpTransformGridOptions, and GimpTransformGridToolUndo), and only leave the basic transform functionality and options in GimpTransformTool (and GimpTransformOptions). Derive all the transform tools (and transform-tool base classes) that previously derived from GimpTransformTool, from GimpTransformGridTool. The one exception is GimpFlipTool, which still derives from GimpTransformTool directly. The next commit will derive GimpMeasureTool from GimpTransformTool as well. --- app/core/core-enums.c | 4 +- app/core/core-enums.h | 2 +- app/tools/Makefile.am | 8 +- app/tools/gimpflipoptions.c | 20 +- app/tools/gimpfliptool.c | 133 +-- app/tools/gimpgenerictransformtool.c | 47 +- app/tools/gimpgenerictransformtool.h | 16 +- app/tools/gimphandletransformoptions.c | 4 +- app/tools/gimphandletransformoptions.h | 6 +- app/tools/gimphandletransformtool.c | 246 ++-- app/tools/gimpperspectivetool.c | 131 ++- app/tools/gimprotatetool.c | 215 ++-- app/tools/gimprotatetool.h | 12 +- app/tools/gimpscaletool.c | 184 +-- app/tools/gimpscaletool.h | 8 +- app/tools/gimpsheartool.c | 347 +++--- app/tools/gimpsheartool.h | 10 +- app/tools/gimptransformgridoptions.c | 548 +++++++++ app/tools/gimptransformgridoptions.h | 69 ++ app/tools/gimptransformgridtool.c | 1214 ++++++++++++++++++++ app/tools/gimptransformgridtool.h | 103 ++ app/tools/gimptransformgridtoolundo.c | 220 ++++ app/tools/gimptransformgridtoolundo.h | 56 + app/tools/gimptransformoptions.c | 450 +------- app/tools/gimptransformoptions.h | 33 +- app/tools/gimptransformtool.c | 1445 ++++-------------------- app/tools/gimptransformtool.h | 76 +- app/tools/gimptransformtoolundo.c | 220 ---- app/tools/gimptransformtoolundo.h | 56 - app/tools/gimpunifiedtransformtool.c | 141 +-- app/tools/tools-types.h | 1 + po/POTFILES.in | 2 + 32 files changed, 3269 insertions(+), 2758 deletions(-) create mode 100644 app/tools/gimptransformgridoptions.c create mode 100644 app/tools/gimptransformgridoptions.h create mode 100644 app/tools/gimptransformgridtool.c create mode 100644 app/tools/gimptransformgridtool.h create mode 100644 app/tools/gimptransformgridtoolundo.c create mode 100644 app/tools/gimptransformgridtoolundo.h delete mode 100644 app/tools/gimptransformtoolundo.c delete mode 100644 app/tools/gimptransformtoolundo.h diff --git a/app/core/core-enums.c b/app/core/core-enums.c index ce5781d468..75137ab66c 100644 --- a/app/core/core-enums.c +++ b/app/core/core-enums.c @@ -848,7 +848,7 @@ gimp_undo_type_get_type (void) { GIMP_UNDO_VECTORS_REMOVE, "GIMP_UNDO_VECTORS_REMOVE", "vectors-remove" }, { GIMP_UNDO_VECTORS_MOD, "GIMP_UNDO_VECTORS_MOD", "vectors-mod" }, { GIMP_UNDO_FS_TO_LAYER, "GIMP_UNDO_FS_TO_LAYER", "fs-to-layer" }, - { GIMP_UNDO_TRANSFORM, "GIMP_UNDO_TRANSFORM", "transform" }, + { GIMP_UNDO_TRANSFORM_GRID, "GIMP_UNDO_TRANSFORM_GRID", "transform-grid" }, { GIMP_UNDO_PAINT, "GIMP_UNDO_PAINT", "paint" }, { GIMP_UNDO_INK, "GIMP_UNDO_INK", "ink" }, { GIMP_UNDO_FOREGROUND_SELECT, "GIMP_UNDO_FOREGROUND_SELECT", "foreground-select" }, @@ -946,7 +946,7 @@ gimp_undo_type_get_type (void) { GIMP_UNDO_VECTORS_REMOVE, NC_("undo-type", "Delete path"), NULL }, { GIMP_UNDO_VECTORS_MOD, NC_("undo-type", "Path modification"), NULL }, { GIMP_UNDO_FS_TO_LAYER, NC_("undo-type", "Floating selection to layer"), NULL }, - { GIMP_UNDO_TRANSFORM, NC_("undo-type", "Transform"), NULL }, + { GIMP_UNDO_TRANSFORM_GRID, NC_("undo-type", "Transform grid"), NULL }, { GIMP_UNDO_PAINT, NC_("undo-type", "Paint"), NULL }, { GIMP_UNDO_INK, NC_("undo-type", "Ink"), NULL }, { GIMP_UNDO_FOREGROUND_SELECT, NC_("undo-type", "Select foreground"), NULL }, diff --git a/app/core/core-enums.h b/app/core/core-enums.h index 5b6a659068..68de446a1b 100644 --- a/app/core/core-enums.h +++ b/app/core/core-enums.h @@ -444,7 +444,7 @@ typedef enum /*< pdb-skip >*/ GIMP_UNDO_VECTORS_REMOVE, /*< desc="Delete path" >*/ GIMP_UNDO_VECTORS_MOD, /*< desc="Path modification" >*/ GIMP_UNDO_FS_TO_LAYER, /*< desc="Floating selection to layer" >*/ - GIMP_UNDO_TRANSFORM, /*< desc="Transform" >*/ + GIMP_UNDO_TRANSFORM_GRID, /*< desc="Transform grid" >*/ GIMP_UNDO_PAINT, /*< desc="Paint" >*/ GIMP_UNDO_INK, /*< desc="Ink" >*/ GIMP_UNDO_FOREGROUND_SELECT, /*< desc="Select foreground" >*/ diff --git a/app/tools/Makefile.am b/app/tools/Makefile.am index 46770cd7bd..23ce3b288b 100644 --- a/app/tools/Makefile.am +++ b/app/tools/Makefile.am @@ -206,12 +206,16 @@ libapptools_a_sources = \ gimptoolcontrol.h \ gimptooloptions-gui.c \ gimptooloptions-gui.h \ + gimptransformgridoptions.c \ + gimptransformgridoptions.h \ + gimptransformgridtool.c \ + gimptransformgridtool.h \ + gimptransformgridtoolundo.c \ + gimptransformgridtoolundo.h \ gimptransformoptions.c \ gimptransformoptions.h \ gimptransformtool.c \ gimptransformtool.h \ - gimptransformtoolundo.c \ - gimptransformtoolundo.h \ gimpunifiedtransformtool.c \ gimpunifiedtransformtool.h \ gimpvectoroptions.c \ diff --git a/app/tools/gimpflipoptions.c b/app/tools/gimpflipoptions.c index 8a80f5b5c9..b9910bd281 100644 --- a/app/tools/gimpflipoptions.c +++ b/app/tools/gimpflipoptions.c @@ -28,7 +28,6 @@ #include "widgets/gimpwidgets-utils.h" #include "gimpflipoptions.h" -#include "gimptooloptions-gui.h" #include "gimp-intl.h" @@ -120,30 +119,17 @@ gimp_flip_options_gui (GimpToolOptions *tool_options) GObject *config = G_OBJECT (tool_options); GimpFlipOptions *options = GIMP_FLIP_OPTIONS (tool_options); GimpTransformOptions *tr_options = GIMP_TRANSFORM_OPTIONS (tool_options); - GtkWidget *vbox = gimp_tool_options_gui (tool_options); - GtkWidget *hbox; - GtkWidget *box; - GtkWidget *label; + GtkWidget *vbox; GtkWidget *frame; GtkWidget *combo; gchar *str; GtkListStore *clip_model; GdkModifierType toggle_mask; + vbox = gimp_transform_options_gui (tool_options, FALSE, FALSE, FALSE); + toggle_mask = gimp_get_toggle_behavior_mask (); - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); - gtk_widget_show (hbox); - - label = gtk_label_new (_("Transform:")); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); - gtk_widget_show (label); - - box = gimp_prop_enum_icon_box_new (config, "type", "gimp", 0, 0); - gtk_box_pack_start (GTK_BOX (hbox), box, FALSE, FALSE, 0); - gtk_widget_show (box); - /* tool toggle */ str = g_strdup_printf (_("Direction (%s)"), gimp_get_mod_string (toggle_mask)); diff --git a/app/tools/gimpfliptool.c b/app/tools/gimpfliptool.c index 4eb52f791a..db5e5820af 100644 --- a/app/tools/gimpfliptool.c +++ b/app/tools/gimpfliptool.c @@ -54,37 +54,38 @@ /* local function prototypes */ -static GimpDisplay * gimp_flip_tool_has_image (GimpTool *tool, - GimpImage *image); -static gboolean gimp_flip_tool_initialize (GimpTool *tool, - GimpDisplay *display, - GError **error); -static void gimp_flip_tool_modifier_key (GimpTool *tool, - GdkModifierType key, - gboolean press, - GdkModifierType state, - GimpDisplay *display); -static void gimp_flip_tool_oper_update (GimpTool *tool, - const GimpCoords *coords, - GdkModifierType state, - gboolean proximity, - GimpDisplay *display); -static void gimp_flip_tool_cursor_update (GimpTool *tool, - const GimpCoords *coords, - GdkModifierType state, - GimpDisplay *display); +static void gimp_flip_tool_button_press (GimpTool *tool, + const GimpCoords *coords, + guint32 time, + GdkModifierType state, + GimpButtonPressType press_type, + GimpDisplay *display); +static void gimp_flip_tool_modifier_key (GimpTool *tool, + GdkModifierType key, + gboolean press, + GdkModifierType state, + GimpDisplay *display); +static void gimp_flip_tool_oper_update (GimpTool *tool, + const GimpCoords *coords, + GdkModifierType state, + gboolean proximity, + GimpDisplay *display); +static void gimp_flip_tool_cursor_update (GimpTool *tool, + const GimpCoords *coords, + GdkModifierType state, + GimpDisplay *display); -static void gimp_flip_tool_draw (GimpDrawTool *draw_tool); +static void gimp_flip_tool_draw (GimpDrawTool *draw_tool); -static gchar * gimp_flip_tool_get_undo_desc (GimpTransformTool *tool); -static GeglBuffer * gimp_flip_tool_transform (GimpTransformTool *tool, - GimpItem *item, - GeglBuffer *orig_buffer, - gint orig_offset_x, - gint orig_offset_y, - GimpColorProfile **buffer_profile, - gint *new_offset_x, - gint *new_offset_y); +static gchar * gimp_flip_tool_get_undo_desc (GimpTransformTool *tr_tool); +static GeglBuffer * gimp_flip_tool_transform (GimpTransformTool *tr_tool, + GimpItem *item, + GeglBuffer *orig_buffer, + gint orig_offset_x, + gint orig_offset_y, + GimpColorProfile **buffer_profile, + gint *new_offset_x, + gint *new_offset_y); static GimpOrientationType gimp_flip_tool_get_flip_type (GimpFlipTool *flip); @@ -117,20 +118,19 @@ gimp_flip_tool_class_init (GimpFlipToolClass *klass) { GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass); GimpDrawToolClass *draw_tool_class = GIMP_DRAW_TOOL_CLASS (klass); - GimpTransformToolClass *trans_class = GIMP_TRANSFORM_TOOL_CLASS (klass); + GimpTransformToolClass *tr_class = GIMP_TRANSFORM_TOOL_CLASS (klass); - tool_class->has_image = gimp_flip_tool_has_image; - tool_class->initialize = gimp_flip_tool_initialize; - tool_class->modifier_key = gimp_flip_tool_modifier_key; - tool_class->oper_update = gimp_flip_tool_oper_update; - tool_class->cursor_update = gimp_flip_tool_cursor_update; + tool_class->button_press = gimp_flip_tool_button_press; + tool_class->modifier_key = gimp_flip_tool_modifier_key; + tool_class->oper_update = gimp_flip_tool_oper_update; + tool_class->cursor_update = gimp_flip_tool_cursor_update; - draw_tool_class->draw = gimp_flip_tool_draw; + draw_tool_class->draw = gimp_flip_tool_draw; - trans_class->get_undo_desc = gimp_flip_tool_get_undo_desc; - trans_class->transform = gimp_flip_tool_transform; + tr_class->get_undo_desc = gimp_flip_tool_get_undo_desc; + tr_class->transform = gimp_flip_tool_transform; - trans_class->ok_button_label = _("_Flip"); + tr_class->progress_text = _("Flipping"); } static void @@ -151,26 +151,17 @@ gimp_flip_tool_init (GimpFlipTool *flip_tool) flip_tool->guide = NULL; } -static GimpDisplay * -gimp_flip_tool_has_image (GimpTool *tool, - GimpImage *image) +static void +gimp_flip_tool_button_press (GimpTool *tool, + const GimpCoords *coords, + guint32 time, + GdkModifierType state, + GimpButtonPressType press_type, + GimpDisplay *display) { - /* avoid committing, and hence flipping, when changing tools */ - return NULL; -} + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool); -static gboolean -gimp_flip_tool_initialize (GimpTool *tool, - GimpDisplay *display, - GError **error) -{ - GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool); - - /* let GimpTransformTool take control over the draw tool while it's active */ - if (gimp_draw_tool_is_active (draw_tool)) - gimp_draw_tool_stop (draw_tool); - - return GIMP_TOOL_CLASS (parent_class)->initialize (tool, display, error); + gimp_transform_tool_transform (tr_tool, display); } static void @@ -258,7 +249,17 @@ gimp_flip_tool_cursor_update (GimpTool *tool, GdkModifierType state, GimpDisplay *display) { - GimpFlipTool *flip = GIMP_FLIP_TOOL (tool); + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool); + GimpFlipTool *flip = GIMP_FLIP_TOOL (tool); + + if (! gimp_transform_tool_get_active_item (tr_tool, display, TRUE, NULL)) + { + gimp_tool_set_cursor (tool, display, + gimp_tool_control_get_cursor (tool->control), + gimp_tool_control_get_tool_cursor (tool->control), + GIMP_CURSOR_MODIFIER_BAD); + return; + } gimp_tool_control_set_toggled (tool->control, gimp_flip_tool_get_flip_type (flip) == @@ -309,7 +310,7 @@ gimp_flip_tool_get_undo_desc (GimpTransformTool *tr_tool) } static GeglBuffer * -gimp_flip_tool_transform (GimpTransformTool *trans_tool, +gimp_flip_tool_transform (GimpTransformTool *tr_tool, GimpItem *active_item, GeglBuffer *orig_buffer, gint orig_offset_x, @@ -318,9 +319,9 @@ gimp_flip_tool_transform (GimpTransformTool *trans_tool, gint *new_offset_x, gint *new_offset_y) { - GimpFlipTool *flip = GIMP_FLIP_TOOL (trans_tool); - GimpFlipOptions *options = GIMP_FLIP_TOOL_GET_OPTIONS (trans_tool); - GimpTransformOptions *tr_options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (trans_tool); + GimpFlipTool *flip = GIMP_FLIP_TOOL (tr_tool); + GimpFlipOptions *options = GIMP_FLIP_TOOL_GET_OPTIONS (tr_tool); + GimpTransformOptions *tr_options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool); GimpContext *context = GIMP_CONTEXT (options); GimpOrientationType flip_type = GIMP_ORIENTATION_UNKNOWN; gdouble axis = 0.0; @@ -338,13 +339,13 @@ gimp_flip_tool_transform (GimpTransformTool *trans_tool, switch (flip_type) { case GIMP_ORIENTATION_HORIZONTAL: - axis = ((gdouble) trans_tool->x1 + - (gdouble) (trans_tool->x2 - trans_tool->x1) / 2.0); + axis = ((gdouble) tr_tool->x1 + + (gdouble) (tr_tool->x2 - tr_tool->x1) / 2.0); break; case GIMP_ORIENTATION_VERTICAL: - axis = ((gdouble) trans_tool->y1 + - (gdouble) (trans_tool->y2 - trans_tool->y1) / 2.0); + axis = ((gdouble) tr_tool->y1 + + (gdouble) (tr_tool->y2 - tr_tool->y1) / 2.0); break; default: diff --git a/app/tools/gimpgenerictransformtool.c b/app/tools/gimpgenerictransformtool.c index 3f50f2f25e..d40254365d 100644 --- a/app/tools/gimpgenerictransformtool.c +++ b/app/tools/gimpgenerictransformtool.c @@ -35,33 +35,33 @@ #include "gimpgenerictransformtool.h" #include "gimptoolcontrol.h" -#include "gimptransformoptions.h" +#include "gimptransformgridoptions.h" #include "gimp-intl.h" /* local function prototypes */ -static void gimp_generic_transform_tool_dialog (GimpTransformTool *tr_tool); -static void gimp_generic_transform_tool_dialog_update (GimpTransformTool *tr_tool); -static void gimp_generic_transform_tool_prepare (GimpTransformTool *tr_tool); -static void gimp_generic_transform_tool_recalc_matrix (GimpTransformTool *tr_tool, - GimpToolWidget *widget); +static void gimp_generic_transform_tool_dialog (GimpTransformGridTool *tg_tool); +static void gimp_generic_transform_tool_dialog_update (GimpTransformGridTool *tg_tool); +static void gimp_generic_transform_tool_prepare (GimpTransformGridTool *tg_tool); +static void gimp_generic_transform_tool_recalc_matrix (GimpTransformGridTool *tg_tool, + GimpToolWidget *widget); G_DEFINE_TYPE (GimpGenericTransformTool, gimp_generic_transform_tool, - GIMP_TYPE_TRANSFORM_TOOL) + GIMP_TYPE_TRANSFORM_GRID_TOOL) static void gimp_generic_transform_tool_class_init (GimpGenericTransformToolClass *klass) { - GimpTransformToolClass *trans_class = GIMP_TRANSFORM_TOOL_CLASS (klass); + GimpTransformGridToolClass *tg_class = GIMP_TRANSFORM_GRID_TOOL_CLASS (klass); - trans_class->dialog = gimp_generic_transform_tool_dialog; - trans_class->dialog_update = gimp_generic_transform_tool_dialog_update; - trans_class->prepare = gimp_generic_transform_tool_prepare; - trans_class->recalc_matrix = gimp_generic_transform_tool_recalc_matrix; + tg_class->dialog = gimp_generic_transform_tool_dialog; + tg_class->dialog_update = gimp_generic_transform_tool_dialog_update; + tg_class->prepare = gimp_generic_transform_tool_prepare; + tg_class->recalc_matrix = gimp_generic_transform_tool_recalc_matrix; } static void @@ -70,9 +70,9 @@ gimp_generic_transform_tool_init (GimpGenericTransformTool *unified_tool) } static void -gimp_generic_transform_tool_dialog (GimpTransformTool *tr_tool) +gimp_generic_transform_tool_dialog (GimpTransformGridTool *tg_tool) { - GimpGenericTransformTool *generic = GIMP_GENERIC_TRANSFORM_TOOL (tr_tool); + GimpGenericTransformTool *generic = GIMP_GENERIC_TRANSFORM_TOOL (tg_tool); GtkWidget *frame; GtkWidget *vbox; GtkWidget *grid; @@ -81,7 +81,7 @@ gimp_generic_transform_tool_dialog (GimpTransformTool *tr_tool) gint x, y; frame = gimp_frame_new (_("Transform Matrix")); - gtk_box_pack_start (GTK_BOX (gimp_tool_gui_get_vbox (tr_tool->gui)), frame, + gtk_box_pack_start (GTK_BOX (gimp_tool_gui_get_vbox (tg_tool->gui)), frame, FALSE, FALSE, 0); gtk_widget_show (frame); @@ -121,9 +121,10 @@ gimp_generic_transform_tool_dialog (GimpTransformTool *tr_tool) } static void -gimp_generic_transform_tool_dialog_update (GimpTransformTool *tr_tool) +gimp_generic_transform_tool_dialog_update (GimpTransformGridTool *tg_tool) { - GimpGenericTransformTool *generic = GIMP_GENERIC_TRANSFORM_TOOL (tr_tool); + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + GimpGenericTransformTool *generic = GIMP_GENERIC_TRANSFORM_TOOL (tg_tool); if (tr_tool->transform_valid) { @@ -153,9 +154,10 @@ gimp_generic_transform_tool_dialog_update (GimpTransformTool *tr_tool) } static void -gimp_generic_transform_tool_prepare (GimpTransformTool *tr_tool) +gimp_generic_transform_tool_prepare (GimpTransformGridTool *tg_tool) { - GimpGenericTransformTool *generic = GIMP_GENERIC_TRANSFORM_TOOL (tr_tool); + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + GimpGenericTransformTool *generic = GIMP_GENERIC_TRANSFORM_TOOL (tg_tool); generic->input_points[0] = (GimpVector2) {tr_tool->x1, tr_tool->y1}; generic->input_points[1] = (GimpVector2) {tr_tool->x2, tr_tool->y1}; @@ -167,10 +169,11 @@ gimp_generic_transform_tool_prepare (GimpTransformTool *tr_tool) } static void -gimp_generic_transform_tool_recalc_matrix (GimpTransformTool *tr_tool, - GimpToolWidget *widget) +gimp_generic_transform_tool_recalc_matrix (GimpTransformGridTool *tg_tool, + GimpToolWidget *widget) { - GimpGenericTransformTool *generic = GIMP_GENERIC_TRANSFORM_TOOL (tr_tool); + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + GimpGenericTransformTool *generic = GIMP_GENERIC_TRANSFORM_TOOL (tg_tool); if (GIMP_GENERIC_TRANSFORM_TOOL_GET_CLASS (generic)->recalc_points) { diff --git a/app/tools/gimpgenerictransformtool.h b/app/tools/gimpgenerictransformtool.h index b02714f50c..14b5e64d5f 100644 --- a/app/tools/gimpgenerictransformtool.h +++ b/app/tools/gimpgenerictransformtool.h @@ -19,7 +19,7 @@ #define __GIMP_GENERIC_TRANSFORM_TOOL_H__ -#include "gimptransformtool.h" +#include "gimptransformgridtool.h" #define GIMP_TYPE_GENERIC_TRANSFORM_TOOL (gimp_generic_transform_tool_get_type ()) @@ -34,19 +34,19 @@ typedef struct _GimpGenericTransformToolClass GimpGenericTransformToolClass; struct _GimpGenericTransformTool { - GimpTransformTool parent_instance; + GimpTransformGridTool parent_instance; - GimpVector2 input_points[4]; - GimpVector2 output_points[4]; + GimpVector2 input_points[4]; + GimpVector2 output_points[4]; - GtkWidget *matrix_grid; - GtkWidget *matrix_labels[3][3]; - GtkWidget *invalid_label; + GtkWidget *matrix_grid; + GtkWidget *matrix_labels[3][3]; + GtkWidget *invalid_label; }; struct _GimpGenericTransformToolClass { - GimpTransformToolClass parent_class; + GimpTransformGridToolClass parent_class; /* virtual functions */ void (* recalc_points) (GimpGenericTransformTool *generic, diff --git a/app/tools/gimphandletransformoptions.c b/app/tools/gimphandletransformoptions.c index 2076e1c1d0..fcb6bf5e6e 100644 --- a/app/tools/gimphandletransformoptions.c +++ b/app/tools/gimphandletransformoptions.c @@ -55,7 +55,7 @@ static void gimp_handle_transform_options_get_property (GObject *objec G_DEFINE_TYPE (GimpHandleTransformOptions, gimp_handle_transform_options, - GIMP_TYPE_TRANSFORM_OPTIONS) + GIMP_TYPE_TRANSFORM_GRID_OPTIONS) #define parent_class gimp_handle_transform_options_parent_class @@ -134,7 +134,7 @@ GtkWidget * gimp_handle_transform_options_gui (GimpToolOptions *tool_options) { GObject *config = G_OBJECT (tool_options); - GtkWidget *vbox = gimp_transform_options_gui (tool_options); + GtkWidget *vbox = gimp_transform_grid_options_gui (tool_options); GtkWidget *frame; GtkWidget *button; gint i; diff --git a/app/tools/gimphandletransformoptions.h b/app/tools/gimphandletransformoptions.h index 34077404c9..9432ef8d27 100644 --- a/app/tools/gimphandletransformoptions.h +++ b/app/tools/gimphandletransformoptions.h @@ -19,7 +19,7 @@ #define __GIMP_HANDLE_TRANSFORM_OPTIONS_H__ -#include "gimptransformoptions.h" +#include "gimptransformgridoptions.h" #define GIMP_TYPE_HANDLE_TRANSFORM_OPTIONS (gimp_handle_transform_options_get_type ()) @@ -35,14 +35,14 @@ typedef struct _GimpHandleTransformOptionsClass GimpHandleTransformOptionsClass; struct _GimpHandleTransformOptions { - GimpTransformOptions parent_instance; + GimpTransformGridOptions parent_instance; GimpTransformHandleMode handle_mode; }; struct _GimpHandleTransformOptionsClass { - GimpTransformOptionsClass parent_class; + GimpTransformGridOptionsClass parent_class; }; diff --git a/app/tools/gimphandletransformtool.c b/app/tools/gimphandletransformtool.c index 7e4a843e0e..b3491b9d01 100644 --- a/app/tools/gimphandletransformtool.c +++ b/app/tools/gimphandletransformtool.c @@ -83,18 +83,19 @@ static void gimp_handle_transform_tool_modifier_key (GimpTool GdkModifierType state, GimpDisplay *display); -static void gimp_handle_transform_tool_prepare (GimpTransformTool *tr_tool); -static GimpToolWidget * - gimp_handle_transform_tool_get_widget (GimpTransformTool *tr_tool); -static void gimp_handle_transform_tool_recalc_matrix (GimpTransformTool *tr_tool, - GimpToolWidget *widget); static gchar *gimp_handle_transform_tool_get_undo_desc (GimpTransformTool *tr_tool); +static void gimp_handle_transform_tool_prepare (GimpTransformGridTool *tg_tool); +static GimpToolWidget * + gimp_handle_transform_tool_get_widget (GimpTransformGridTool *tg_tool); +static void gimp_handle_transform_tool_recalc_matrix (GimpTransformGridTool *tg_tool, + GimpToolWidget *widget); + static void gimp_handle_transform_tool_recalc_points (GimpGenericTransformTool *generic, GimpToolWidget *widget); static void gimp_handle_transform_tool_widget_changed (GimpToolWidget *widget, - GimpTransformTool *tr_tool); + GimpTransformGridTool *tg_tool); G_DEFINE_TYPE (GimpHandleTransformTool, gimp_handle_transform_tool, @@ -125,26 +126,26 @@ static void gimp_handle_transform_tool_class_init (GimpHandleTransformToolClass *klass) { GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass); - GimpTransformToolClass *trans_class = GIMP_TRANSFORM_TOOL_CLASS (klass); + GimpTransformToolClass *tr_class = GIMP_TRANSFORM_TOOL_CLASS (klass); + GimpTransformGridToolClass *tg_class = GIMP_TRANSFORM_GRID_TOOL_CLASS (klass); GimpGenericTransformToolClass *generic_class = GIMP_GENERIC_TRANSFORM_TOOL_CLASS (klass); tool_class->modifier_key = gimp_handle_transform_tool_modifier_key; - trans_class->prepare = gimp_handle_transform_tool_prepare; - trans_class->get_widget = gimp_handle_transform_tool_get_widget; - trans_class->recalc_matrix = gimp_handle_transform_tool_recalc_matrix; - trans_class->get_undo_desc = gimp_handle_transform_tool_get_undo_desc; + tr_class->get_undo_desc = gimp_handle_transform_tool_get_undo_desc; + + tg_class->prepare = gimp_handle_transform_tool_prepare; + tg_class->get_widget = gimp_handle_transform_tool_get_widget; + tg_class->recalc_matrix = gimp_handle_transform_tool_recalc_matrix; generic_class->recalc_points = gimp_handle_transform_tool_recalc_points; + + tr_class->progress_text = _("Handle transformation"); } static void gimp_handle_transform_tool_init (GimpHandleTransformTool *ht_tool) { - GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (ht_tool); - - tr_tool->progress_text = _("Handle transformation"); - ht_tool->saved_handle_mode = GIMP_HANDLE_MODE_ADD_TRANSFORM; } @@ -202,39 +203,48 @@ gimp_handle_transform_tool_modifier_key (GimpTool *tool, state, display); } -static void -gimp_handle_transform_tool_prepare (GimpTransformTool *tr_tool) +static gchar * +gimp_handle_transform_tool_get_undo_desc (GimpTransformTool *tr_tool) { - GIMP_TRANSFORM_TOOL_CLASS (parent_class)->prepare (tr_tool); + return g_strdup (C_("undo-type", "Handle transform")); +} - tr_tool->trans_info[X0] = (gdouble) tr_tool->x1; - tr_tool->trans_info[Y0] = (gdouble) tr_tool->y1; - tr_tool->trans_info[X1] = (gdouble) tr_tool->x2; - tr_tool->trans_info[Y1] = (gdouble) tr_tool->y1; - tr_tool->trans_info[X2] = (gdouble) tr_tool->x1; - tr_tool->trans_info[Y2] = (gdouble) tr_tool->y2; - tr_tool->trans_info[X3] = (gdouble) tr_tool->x2; - tr_tool->trans_info[Y3] = (gdouble) tr_tool->y2; - tr_tool->trans_info[OX0] = (gdouble) tr_tool->x1; - tr_tool->trans_info[OY0] = (gdouble) tr_tool->y1; - tr_tool->trans_info[OX1] = (gdouble) tr_tool->x2; - tr_tool->trans_info[OY1] = (gdouble) tr_tool->y1; - tr_tool->trans_info[OX2] = (gdouble) tr_tool->x1; - tr_tool->trans_info[OY2] = (gdouble) tr_tool->y2; - tr_tool->trans_info[OX3] = (gdouble) tr_tool->x2; - tr_tool->trans_info[OY3] = (gdouble) tr_tool->y2; - tr_tool->trans_info[N_HANDLES] = 0; +static void +gimp_handle_transform_tool_prepare (GimpTransformGridTool *tg_tool) +{ + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + + GIMP_TRANSFORM_GRID_TOOL_CLASS (parent_class)->prepare (tg_tool); + + tg_tool->trans_info[X0] = (gdouble) tr_tool->x1; + tg_tool->trans_info[Y0] = (gdouble) tr_tool->y1; + tg_tool->trans_info[X1] = (gdouble) tr_tool->x2; + tg_tool->trans_info[Y1] = (gdouble) tr_tool->y1; + tg_tool->trans_info[X2] = (gdouble) tr_tool->x1; + tg_tool->trans_info[Y2] = (gdouble) tr_tool->y2; + tg_tool->trans_info[X3] = (gdouble) tr_tool->x2; + tg_tool->trans_info[Y3] = (gdouble) tr_tool->y2; + tg_tool->trans_info[OX0] = (gdouble) tr_tool->x1; + tg_tool->trans_info[OY0] = (gdouble) tr_tool->y1; + tg_tool->trans_info[OX1] = (gdouble) tr_tool->x2; + tg_tool->trans_info[OY1] = (gdouble) tr_tool->y1; + tg_tool->trans_info[OX2] = (gdouble) tr_tool->x1; + tg_tool->trans_info[OY2] = (gdouble) tr_tool->y2; + tg_tool->trans_info[OX3] = (gdouble) tr_tool->x2; + tg_tool->trans_info[OY3] = (gdouble) tr_tool->y2; + tg_tool->trans_info[N_HANDLES] = 0; } static GimpToolWidget * -gimp_handle_transform_tool_get_widget (GimpTransformTool *tr_tool) +gimp_handle_transform_tool_get_widget (GimpTransformGridTool *tg_tool) { - GimpTool *tool = GIMP_TOOL (tr_tool); + GimpTool *tool = GIMP_TOOL (tg_tool); + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); GimpHandleTransformOptions *options; - GimpDisplayShell *shell = gimp_display_get_shell (tool->display); + GimpDisplayShell *shell = gimp_display_get_shell (tool->display); GimpToolWidget *widget; - options = GIMP_HANDLE_TRANSFORM_TOOL_GET_OPTIONS (tr_tool); + options = GIMP_HANDLE_TRANSFORM_TOOL_GET_OPTIONS (tg_tool); widget = gimp_tool_handle_grid_new (shell, tr_tool->x1, @@ -243,23 +253,23 @@ gimp_handle_transform_tool_get_widget (GimpTransformTool *tr_tool) tr_tool->y2); g_object_set (widget, - "n-handles", (gint) tr_tool->trans_info[N_HANDLES], - "orig-x1", tr_tool->trans_info[OX0], - "orig-y1", tr_tool->trans_info[OY0], - "orig-x2", tr_tool->trans_info[OX1], - "orig-y2", tr_tool->trans_info[OY1], - "orig-x3", tr_tool->trans_info[OX2], - "orig-y3", tr_tool->trans_info[OY2], - "orig-x4", tr_tool->trans_info[OX3], - "orig-y4", tr_tool->trans_info[OY3], - "trans-x1", tr_tool->trans_info[X0], - "trans-y1", tr_tool->trans_info[Y0], - "trans-x2", tr_tool->trans_info[X1], - "trans-y2", tr_tool->trans_info[Y1], - "trans-x3", tr_tool->trans_info[X2], - "trans-y3", tr_tool->trans_info[Y2], - "trans-x4", tr_tool->trans_info[X3], - "trans-y4", tr_tool->trans_info[Y3], + "n-handles", (gint) tg_tool->trans_info[N_HANDLES], + "orig-x1", tg_tool->trans_info[OX0], + "orig-y1", tg_tool->trans_info[OY0], + "orig-x2", tg_tool->trans_info[OX1], + "orig-y2", tg_tool->trans_info[OY1], + "orig-x3", tg_tool->trans_info[OX2], + "orig-y3", tg_tool->trans_info[OY2], + "orig-x4", tg_tool->trans_info[OX3], + "orig-y4", tg_tool->trans_info[OY3], + "trans-x1", tg_tool->trans_info[X0], + "trans-y1", tg_tool->trans_info[Y0], + "trans-x2", tg_tool->trans_info[X1], + "trans-y2", tg_tool->trans_info[Y1], + "trans-x3", tg_tool->trans_info[X2], + "trans-y3", tg_tool->trans_info[Y2], + "trans-x4", tg_tool->trans_info[X3], + "trans-y4", tg_tool->trans_info[Y3], NULL); g_object_bind_property (G_OBJECT (options), "handle-mode", @@ -269,99 +279,95 @@ gimp_handle_transform_tool_get_widget (GimpTransformTool *tr_tool) g_signal_connect (widget, "changed", G_CALLBACK (gimp_handle_transform_tool_widget_changed), - tr_tool); + tg_tool); return widget; } static void -gimp_handle_transform_tool_recalc_matrix (GimpTransformTool *tr_tool, - GimpToolWidget *widget) +gimp_handle_transform_tool_recalc_matrix (GimpTransformGridTool *tg_tool, + GimpToolWidget *widget) { - GIMP_TRANSFORM_TOOL_CLASS (parent_class)->recalc_matrix (tr_tool, widget); + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + + GIMP_TRANSFORM_GRID_TOOL_CLASS (parent_class)->recalc_matrix (tg_tool, widget); if (widget) g_object_set (widget, "transform", &tr_tool->transform, "show-guides", tr_tool->transform_valid, - "n-handles", (gint) tr_tool->trans_info[N_HANDLES], - "orig-x1", tr_tool->trans_info[OX0], - "orig-y1", tr_tool->trans_info[OY0], - "orig-x2", tr_tool->trans_info[OX1], - "orig-y2", tr_tool->trans_info[OY1], - "orig-x3", tr_tool->trans_info[OX2], - "orig-y3", tr_tool->trans_info[OY2], - "orig-x4", tr_tool->trans_info[OX3], - "orig-y4", tr_tool->trans_info[OY3], - "trans-x1", tr_tool->trans_info[X0], - "trans-y1", tr_tool->trans_info[Y0], - "trans-x2", tr_tool->trans_info[X1], - "trans-y2", tr_tool->trans_info[Y1], - "trans-x3", tr_tool->trans_info[X2], - "trans-y3", tr_tool->trans_info[Y2], - "trans-x4", tr_tool->trans_info[X3], - "trans-y4", tr_tool->trans_info[Y3], + "n-handles", (gint) tg_tool->trans_info[N_HANDLES], + "orig-x1", tg_tool->trans_info[OX0], + "orig-y1", tg_tool->trans_info[OY0], + "orig-x2", tg_tool->trans_info[OX1], + "orig-y2", tg_tool->trans_info[OY1], + "orig-x3", tg_tool->trans_info[OX2], + "orig-y3", tg_tool->trans_info[OY2], + "orig-x4", tg_tool->trans_info[OX3], + "orig-y4", tg_tool->trans_info[OY3], + "trans-x1", tg_tool->trans_info[X0], + "trans-y1", tg_tool->trans_info[Y0], + "trans-x2", tg_tool->trans_info[X1], + "trans-y2", tg_tool->trans_info[Y1], + "trans-x3", tg_tool->trans_info[X2], + "trans-y3", tg_tool->trans_info[Y2], + "trans-x4", tg_tool->trans_info[X3], + "trans-y4", tg_tool->trans_info[Y3], NULL); } -static gchar * -gimp_handle_transform_tool_get_undo_desc (GimpTransformTool *tr_tool) -{ - return g_strdup (C_("undo-type", "Handle transform")); -} - static void gimp_handle_transform_tool_recalc_points (GimpGenericTransformTool *generic, GimpToolWidget *widget) { - GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (generic); + GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (generic); - generic->input_points[0] = (GimpVector2) {tr_tool->trans_info[OX0], - tr_tool->trans_info[OY0]}; - generic->input_points[1] = (GimpVector2) {tr_tool->trans_info[OX1], - tr_tool->trans_info[OY1]}; - generic->input_points[2] = (GimpVector2) {tr_tool->trans_info[OX2], - tr_tool->trans_info[OY2]}; - generic->input_points[3] = (GimpVector2) {tr_tool->trans_info[OX3], - tr_tool->trans_info[OY3]}; + generic->input_points[0] = (GimpVector2) {tg_tool->trans_info[OX0], + tg_tool->trans_info[OY0]}; + generic->input_points[1] = (GimpVector2) {tg_tool->trans_info[OX1], + tg_tool->trans_info[OY1]}; + generic->input_points[2] = (GimpVector2) {tg_tool->trans_info[OX2], + tg_tool->trans_info[OY2]}; + generic->input_points[3] = (GimpVector2) {tg_tool->trans_info[OX3], + tg_tool->trans_info[OY3]}; - generic->output_points[0] = (GimpVector2) {tr_tool->trans_info[X0], - tr_tool->trans_info[Y0]}; - generic->output_points[1] = (GimpVector2) {tr_tool->trans_info[X1], - tr_tool->trans_info[Y1]}; - generic->output_points[2] = (GimpVector2) {tr_tool->trans_info[X2], - tr_tool->trans_info[Y2]}; - generic->output_points[3] = (GimpVector2) {tr_tool->trans_info[X3], - tr_tool->trans_info[Y3]}; + generic->output_points[0] = (GimpVector2) {tg_tool->trans_info[X0], + tg_tool->trans_info[Y0]}; + generic->output_points[1] = (GimpVector2) {tg_tool->trans_info[X1], + tg_tool->trans_info[Y1]}; + generic->output_points[2] = (GimpVector2) {tg_tool->trans_info[X2], + tg_tool->trans_info[Y2]}; + generic->output_points[3] = (GimpVector2) {tg_tool->trans_info[X3], + tg_tool->trans_info[Y3]}; } static void -gimp_handle_transform_tool_widget_changed (GimpToolWidget *widget, - GimpTransformTool *tr_tool) +gimp_handle_transform_tool_widget_changed (GimpToolWidget *widget, + GimpTransformGridTool *tg_tool) { gint n_handles; g_object_get (widget, "n-handles", &n_handles, - "orig-x1", &tr_tool->trans_info[OX0], - "orig-y1", &tr_tool->trans_info[OY0], - "orig-x2", &tr_tool->trans_info[OX1], - "orig-y2", &tr_tool->trans_info[OY1], - "orig-x3", &tr_tool->trans_info[OX2], - "orig-y3", &tr_tool->trans_info[OY2], - "orig-x4", &tr_tool->trans_info[OX3], - "orig-y4", &tr_tool->trans_info[OY3], - "trans-x1", &tr_tool->trans_info[X0], - "trans-y1", &tr_tool->trans_info[Y0], - "trans-x2", &tr_tool->trans_info[X1], - "trans-y2", &tr_tool->trans_info[Y1], - "trans-x3", &tr_tool->trans_info[X2], - "trans-y3", &tr_tool->trans_info[Y2], - "trans-x4", &tr_tool->trans_info[X3], - "trans-y4", &tr_tool->trans_info[Y3], + "orig-x1", &tg_tool->trans_info[OX0], + "orig-y1", &tg_tool->trans_info[OY0], + "orig-x2", &tg_tool->trans_info[OX1], + "orig-y2", &tg_tool->trans_info[OY1], + "orig-x3", &tg_tool->trans_info[OX2], + "orig-y3", &tg_tool->trans_info[OY2], + "orig-x4", &tg_tool->trans_info[OX3], + "orig-y4", &tg_tool->trans_info[OY3], + "trans-x1", &tg_tool->trans_info[X0], + "trans-y1", &tg_tool->trans_info[Y0], + "trans-x2", &tg_tool->trans_info[X1], + "trans-y2", &tg_tool->trans_info[Y1], + "trans-x3", &tg_tool->trans_info[X2], + "trans-y3", &tg_tool->trans_info[Y2], + "trans-x4", &tg_tool->trans_info[X3], + "trans-y4", &tg_tool->trans_info[Y3], NULL); - tr_tool->trans_info[N_HANDLES] = n_handles; + tg_tool->trans_info[N_HANDLES] = n_handles; - gimp_transform_tool_recalc_matrix (tr_tool, NULL); + gimp_transform_grid_tool_recalc_matrix (tg_tool, NULL); } diff --git a/app/tools/gimpperspectivetool.c b/app/tools/gimpperspectivetool.c index 97e24b8738..f7f238921f 100644 --- a/app/tools/gimpperspectivetool.c +++ b/app/tools/gimpperspectivetool.c @@ -33,7 +33,7 @@ #include "gimpperspectivetool.h" #include "gimptoolcontrol.h" -#include "gimptransformoptions.h" +#include "gimptransformgridoptions.h" #include "gimp-intl.h" @@ -54,17 +54,18 @@ enum /* local function prototypes */ -static void gimp_perspective_tool_prepare (GimpTransformTool *tr_tool); -static GimpToolWidget * gimp_perspective_tool_get_widget (GimpTransformTool *tr_tool); -static void gimp_perspective_tool_recalc_matrix (GimpTransformTool *tr_tool, - GimpToolWidget *widget); static gchar * gimp_perspective_tool_get_undo_desc (GimpTransformTool *tr_tool); +static void gimp_perspective_tool_prepare (GimpTransformGridTool *tg_tool); +static GimpToolWidget * gimp_perspective_tool_get_widget (GimpTransformGridTool *tg_tool); +static void gimp_perspective_tool_recalc_matrix (GimpTransformGridTool *tg_tool, + GimpToolWidget *widget); + static void gimp_perspective_tool_recalc_points (GimpGenericTransformTool *generic, GimpToolWidget *widget); static void gimp_perspective_tool_widget_changed (GimpToolWidget *widget, - GimpTransformTool *tr_tool); + GimpTransformGridTool *tg_tool); G_DEFINE_TYPE (GimpPerspectiveTool, gimp_perspective_tool, @@ -78,8 +79,8 @@ gimp_perspective_tool_register (GimpToolRegisterCallback callback, gpointer data) { (* callback) (GIMP_TYPE_PERSPECTIVE_TOOL, - GIMP_TYPE_TRANSFORM_OPTIONS, - gimp_transform_options_gui, + GIMP_TYPE_TRANSFORM_GRID_OPTIONS, + gimp_transform_grid_options_gui, GIMP_CONTEXT_PROP_MASK_BACKGROUND, "gimp-perspective-tool", _("Perspective"), @@ -94,50 +95,60 @@ gimp_perspective_tool_register (GimpToolRegisterCallback callback, static void gimp_perspective_tool_class_init (GimpPerspectiveToolClass *klass) { - GimpTransformToolClass *trans_class = GIMP_TRANSFORM_TOOL_CLASS (klass); + GimpTransformToolClass *tr_class = GIMP_TRANSFORM_TOOL_CLASS (klass); + GimpTransformGridToolClass *tg_class = GIMP_TRANSFORM_GRID_TOOL_CLASS (klass); GimpGenericTransformToolClass *generic_class = GIMP_GENERIC_TRANSFORM_TOOL_CLASS (klass); - trans_class->prepare = gimp_perspective_tool_prepare; - trans_class->get_widget = gimp_perspective_tool_get_widget; - trans_class->recalc_matrix = gimp_perspective_tool_recalc_matrix; - trans_class->get_undo_desc = gimp_perspective_tool_get_undo_desc; + tr_class->get_undo_desc = gimp_perspective_tool_get_undo_desc; + + tg_class->prepare = gimp_perspective_tool_prepare; + tg_class->get_widget = gimp_perspective_tool_get_widget; + tg_class->recalc_matrix = gimp_perspective_tool_recalc_matrix; generic_class->recalc_points = gimp_perspective_tool_recalc_points; + + tr_class->progress_text = _("Perspective transformation"); } static void gimp_perspective_tool_init (GimpPerspectiveTool *perspective_tool) { - GimpTool *tool = GIMP_TOOL (perspective_tool); - GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (perspective_tool); + GimpTool *tool = GIMP_TOOL (perspective_tool); gimp_tool_control_set_tool_cursor (tool->control, GIMP_TOOL_CURSOR_PERSPECTIVE); +} - tr_tool->progress_text = _("Perspective transformation"); +static gchar * +gimp_perspective_tool_get_undo_desc (GimpTransformTool *tr_tool) +{ + return g_strdup (C_("undo-type", "Perspective")); } static void -gimp_perspective_tool_prepare (GimpTransformTool *tr_tool) +gimp_perspective_tool_prepare (GimpTransformGridTool *tg_tool) { - GIMP_TRANSFORM_TOOL_CLASS (parent_class)->prepare (tr_tool); + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); - tr_tool->trans_info[X0] = (gdouble) tr_tool->x1; - tr_tool->trans_info[Y0] = (gdouble) tr_tool->y1; - tr_tool->trans_info[X1] = (gdouble) tr_tool->x2; - tr_tool->trans_info[Y1] = (gdouble) tr_tool->y1; - tr_tool->trans_info[X2] = (gdouble) tr_tool->x1; - tr_tool->trans_info[Y2] = (gdouble) tr_tool->y2; - tr_tool->trans_info[X3] = (gdouble) tr_tool->x2; - tr_tool->trans_info[Y3] = (gdouble) tr_tool->y2; + GIMP_TRANSFORM_GRID_TOOL_CLASS (parent_class)->prepare (tg_tool); + + tg_tool->trans_info[X0] = (gdouble) tr_tool->x1; + tg_tool->trans_info[Y0] = (gdouble) tr_tool->y1; + tg_tool->trans_info[X1] = (gdouble) tr_tool->x2; + tg_tool->trans_info[Y1] = (gdouble) tr_tool->y1; + tg_tool->trans_info[X2] = (gdouble) tr_tool->x1; + tg_tool->trans_info[Y2] = (gdouble) tr_tool->y2; + tg_tool->trans_info[X3] = (gdouble) tr_tool->x2; + tg_tool->trans_info[Y3] = (gdouble) tr_tool->y2; } static GimpToolWidget * -gimp_perspective_tool_get_widget (GimpTransformTool *tr_tool) +gimp_perspective_tool_get_widget (GimpTransformGridTool *tg_tool) { - GimpTool *tool = GIMP_TOOL (tr_tool); - GimpDisplayShell *shell = gimp_display_get_shell (tool->display); - GimpToolWidget *widget; + GimpTool *tool = GIMP_TOOL (tg_tool); + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + GimpDisplayShell *shell = gimp_display_get_shell (tool->display); + GimpToolWidget *widget; widget = gimp_tool_transform_grid_new (shell, &tr_tool->transform, @@ -155,16 +166,18 @@ gimp_perspective_tool_get_widget (GimpTransformTool *tr_tool) g_signal_connect (widget, "changed", G_CALLBACK (gimp_perspective_tool_widget_changed), - tr_tool); + tg_tool); return widget; } static void -gimp_perspective_tool_recalc_matrix (GimpTransformTool *tr_tool, - GimpToolWidget *widget) +gimp_perspective_tool_recalc_matrix (GimpTransformGridTool *tg_tool, + GimpToolWidget *widget) { - GIMP_TRANSFORM_TOOL_CLASS (parent_class)->recalc_matrix (tr_tool, widget); + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + + GIMP_TRANSFORM_GRID_TOOL_CLASS (parent_class)->recalc_matrix (tg_tool, widget); if (widget) g_object_set (widget, @@ -176,38 +189,34 @@ gimp_perspective_tool_recalc_matrix (GimpTransformTool *tr_tool, NULL); } -static gchar * -gimp_perspective_tool_get_undo_desc (GimpTransformTool *tr_tool) -{ - return g_strdup (C_("undo-type", "Perspective")); -} - static void gimp_perspective_tool_recalc_points (GimpGenericTransformTool *generic, GimpToolWidget *widget) { - GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (generic); + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (generic); + GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (generic); generic->input_points[0] = (GimpVector2) {tr_tool->x1, tr_tool->y1}; generic->input_points[1] = (GimpVector2) {tr_tool->x2, tr_tool->y1}; generic->input_points[2] = (GimpVector2) {tr_tool->x1, tr_tool->y2}; generic->input_points[3] = (GimpVector2) {tr_tool->x2, tr_tool->y2}; - generic->output_points[0] = (GimpVector2) {tr_tool->trans_info[X0], - tr_tool->trans_info[Y0]}; - generic->output_points[1] = (GimpVector2) {tr_tool->trans_info[X1], - tr_tool->trans_info[Y1]}; - generic->output_points[2] = (GimpVector2) {tr_tool->trans_info[X2], - tr_tool->trans_info[Y2]}; - generic->output_points[3] = (GimpVector2) {tr_tool->trans_info[X3], - tr_tool->trans_info[Y3]}; + generic->output_points[0] = (GimpVector2) {tg_tool->trans_info[X0], + tg_tool->trans_info[Y0]}; + generic->output_points[1] = (GimpVector2) {tg_tool->trans_info[X1], + tg_tool->trans_info[Y1]}; + generic->output_points[2] = (GimpVector2) {tg_tool->trans_info[X2], + tg_tool->trans_info[Y2]}; + generic->output_points[3] = (GimpVector2) {tg_tool->trans_info[X3], + tg_tool->trans_info[Y3]}; } static void -gimp_perspective_tool_widget_changed (GimpToolWidget *widget, - GimpTransformTool *tr_tool) +gimp_perspective_tool_widget_changed (GimpToolWidget *widget, + GimpTransformGridTool *tg_tool) { - GimpMatrix3 *transform; + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + GimpMatrix3 *transform; g_object_get (widget, "transform", &transform, @@ -215,22 +224,22 @@ gimp_perspective_tool_widget_changed (GimpToolWidget *widget, gimp_matrix3_transform_point (transform, tr_tool->x1, tr_tool->y1, - &tr_tool->trans_info[X0], - &tr_tool->trans_info[Y0]); + &tg_tool->trans_info[X0], + &tg_tool->trans_info[Y0]); gimp_matrix3_transform_point (transform, tr_tool->x2, tr_tool->y1, - &tr_tool->trans_info[X1], - &tr_tool->trans_info[Y1]); + &tg_tool->trans_info[X1], + &tg_tool->trans_info[Y1]); gimp_matrix3_transform_point (transform, tr_tool->x1, tr_tool->y2, - &tr_tool->trans_info[X2], - &tr_tool->trans_info[Y2]); + &tg_tool->trans_info[X2], + &tg_tool->trans_info[Y2]); gimp_matrix3_transform_point (transform, tr_tool->x2, tr_tool->y2, - &tr_tool->trans_info[X3], - &tr_tool->trans_info[Y3]); + &tg_tool->trans_info[X3], + &tg_tool->trans_info[Y3]); g_free (transform); - gimp_transform_tool_recalc_matrix (tr_tool, NULL); + gimp_transform_grid_tool_recalc_matrix (tg_tool, NULL); } diff --git a/app/tools/gimprotatetool.c b/app/tools/gimprotatetool.c index 4c49e777b9..44fdecc420 100644 --- a/app/tools/gimprotatetool.c +++ b/app/tools/gimprotatetool.c @@ -38,7 +38,7 @@ #include "gimprotatetool.h" #include "gimptoolcontrol.h" -#include "gimptransformoptions.h" +#include "gimptransformgridoptions.h" #include "gimp-intl.h" @@ -57,28 +57,29 @@ enum /* local function prototypes */ -static gboolean gimp_rotate_tool_key_press (GimpTool *tool, - GdkEventKey *kevent, - GimpDisplay *display); +static gboolean gimp_rotate_tool_key_press (GimpTool *tool, + GdkEventKey *kevent, + GimpDisplay *display); -static void gimp_rotate_tool_dialog (GimpTransformTool *tr_tool); -static void gimp_rotate_tool_dialog_update (GimpTransformTool *tr_tool); -static void gimp_rotate_tool_prepare (GimpTransformTool *tr_tool); -static GimpToolWidget * gimp_rotate_tool_get_widget (GimpTransformTool *tr_tool); -static void gimp_rotate_tool_recalc_matrix (GimpTransformTool *tr_tool, - GimpToolWidget *widget); -static gchar * gimp_rotate_tool_get_undo_desc (GimpTransformTool *tr_tool); +static gchar * gimp_rotate_tool_get_undo_desc (GimpTransformTool *tr_tool); -static void gimp_rotate_tool_widget_changed (GimpToolWidget *widget, - GimpTransformTool *tr_tool); +static void gimp_rotate_tool_dialog (GimpTransformGridTool *tg_tool); +static void gimp_rotate_tool_dialog_update (GimpTransformGridTool *tg_tool); +static void gimp_rotate_tool_prepare (GimpTransformGridTool *tg_tool); +static GimpToolWidget * gimp_rotate_tool_get_widget (GimpTransformGridTool *tg_tool); +static void gimp_rotate_tool_recalc_matrix (GimpTransformGridTool *tg_tool, + GimpToolWidget *widget); -static void rotate_angle_changed (GtkAdjustment *adj, - GimpTransformTool *tr_tool); -static void rotate_center_changed (GtkWidget *entry, - GimpTransformTool *tr_tool); +static void gimp_rotate_tool_widget_changed (GimpToolWidget *widget, + GimpTransformGridTool *tg_tool); + +static void rotate_angle_changed (GtkAdjustment *adj, + GimpTransformGridTool *tg_tool); +static void rotate_center_changed (GtkWidget *entry, + GimpTransformGridTool *tg_tool); -G_DEFINE_TYPE (GimpRotateTool, gimp_rotate_tool, GIMP_TYPE_TRANSFORM_TOOL) +G_DEFINE_TYPE (GimpRotateTool, gimp_rotate_tool, GIMP_TYPE_TRANSFORM_GRID_TOOL) #define parent_class gimp_rotate_tool_parent_class @@ -88,8 +89,8 @@ gimp_rotate_tool_register (GimpToolRegisterCallback callback, gpointer data) { (* callback) (GIMP_TYPE_ROTATE_TOOL, - GIMP_TYPE_TRANSFORM_OPTIONS, - gimp_transform_options_gui, + GIMP_TYPE_TRANSFORM_GRID_OPTIONS, + gimp_transform_grid_options_gui, GIMP_CONTEXT_PROP_MASK_BACKGROUND, "gimp-rotate-tool", _("Rotate"), @@ -103,30 +104,30 @@ gimp_rotate_tool_register (GimpToolRegisterCallback callback, static void gimp_rotate_tool_class_init (GimpRotateToolClass *klass) { - GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass); - GimpTransformToolClass *trans_class = GIMP_TRANSFORM_TOOL_CLASS (klass); + GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass); + GimpTransformToolClass *tr_class = GIMP_TRANSFORM_TOOL_CLASS (klass); + GimpTransformGridToolClass *tg_class = GIMP_TRANSFORM_GRID_TOOL_CLASS (klass); - tool_class->key_press = gimp_rotate_tool_key_press; + tool_class->key_press = gimp_rotate_tool_key_press; - trans_class->dialog = gimp_rotate_tool_dialog; - trans_class->dialog_update = gimp_rotate_tool_dialog_update; - trans_class->prepare = gimp_rotate_tool_prepare; - trans_class->get_widget = gimp_rotate_tool_get_widget; - trans_class->recalc_matrix = gimp_rotate_tool_recalc_matrix; - trans_class->get_undo_desc = gimp_rotate_tool_get_undo_desc; + tr_class->get_undo_desc = gimp_rotate_tool_get_undo_desc; - trans_class->ok_button_label = _("R_otate"); + tg_class->dialog = gimp_rotate_tool_dialog; + tg_class->dialog_update = gimp_rotate_tool_dialog_update; + tg_class->prepare = gimp_rotate_tool_prepare; + tg_class->get_widget = gimp_rotate_tool_get_widget; + tg_class->recalc_matrix = gimp_rotate_tool_recalc_matrix; + + tr_class->progress_text = _("Rotating"); + tg_class->ok_button_label = _("R_otate"); } static void gimp_rotate_tool_init (GimpRotateTool *rotate_tool) { - GimpTool *tool = GIMP_TOOL (rotate_tool); - GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (rotate_tool); + GimpTool *tool = GIMP_TOOL (rotate_tool); gimp_tool_control_set_tool_cursor (tool->control, GIMP_TOOL_CURSOR_ROTATE); - - tr_tool->progress_text = _("Rotating"); } static gboolean @@ -167,10 +168,22 @@ gimp_rotate_tool_key_press (GimpTool *tool, return GIMP_TOOL_CLASS (parent_class)->key_press (tool, kevent, display); } -static void -gimp_rotate_tool_dialog (GimpTransformTool *tr_tool) +static gchar * +gimp_rotate_tool_get_undo_desc (GimpTransformTool *tr_tool) { - GimpRotateTool *rotate = GIMP_ROTATE_TOOL (tr_tool); + GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (tr_tool); + + return g_strdup_printf (C_("undo-type", + "Rotate by %-3.3g° around (%g, %g)"), + gimp_rad_to_deg (tg_tool->trans_info[ANGLE]), + tg_tool->trans_info[PIVOT_X], + tg_tool->trans_info[PIVOT_Y]); +} + +static void +gimp_rotate_tool_dialog (GimpTransformGridTool *tg_tool) +{ + GimpRotateTool *rotate = GIMP_ROTATE_TOOL (tg_tool); GtkWidget *grid; GtkWidget *button; GtkWidget *scale; @@ -179,7 +192,7 @@ gimp_rotate_tool_dialog (GimpTransformTool *tr_tool) grid = gtk_grid_new (); gtk_grid_set_row_spacing (GTK_GRID (grid), 2); gtk_grid_set_column_spacing (GTK_GRID (grid), 6); - gtk_box_pack_start (GTK_BOX (gimp_tool_gui_get_vbox (tr_tool->gui)), grid, + gtk_box_pack_start (GTK_BOX (gimp_tool_gui_get_vbox (tg_tool->gui)), grid, FALSE, FALSE, 0); gtk_widget_show (grid); @@ -195,7 +208,7 @@ gimp_rotate_tool_dialog (GimpTransformTool *tr_tool) g_signal_connect (rotate->angle_adj, "value-changed", G_CALLBACK (rotate_angle_changed), - tr_tool); + tg_tool); scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, rotate->angle_adj); gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE); @@ -223,49 +236,50 @@ gimp_rotate_tool_dialog (GimpTransformTool *tr_tool) g_signal_connect (rotate->sizeentry, "value-changed", G_CALLBACK (rotate_center_changed), - tr_tool); + tg_tool); } static void -gimp_rotate_tool_dialog_update (GimpTransformTool *tr_tool) +gimp_rotate_tool_dialog_update (GimpTransformGridTool *tg_tool) { - GimpRotateTool *rotate = GIMP_ROTATE_TOOL (tr_tool); + GimpRotateTool *rotate = GIMP_ROTATE_TOOL (tg_tool); gtk_adjustment_set_value (rotate->angle_adj, - gimp_rad_to_deg (tr_tool->trans_info[ANGLE])); + gimp_rad_to_deg (tg_tool->trans_info[ANGLE])); g_signal_handlers_block_by_func (rotate->sizeentry, rotate_center_changed, - tr_tool); + tg_tool); gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (rotate->sizeentry), 0, - tr_tool->trans_info[PIVOT_X]); + tg_tool->trans_info[PIVOT_X]); gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (rotate->sizeentry), 1, - tr_tool->trans_info[PIVOT_Y]); + tg_tool->trans_info[PIVOT_Y]); g_signal_handlers_unblock_by_func (rotate->sizeentry, rotate_center_changed, - tr_tool); + tg_tool); } static void -gimp_rotate_tool_prepare (GimpTransformTool *tr_tool) +gimp_rotate_tool_prepare (GimpTransformGridTool *tg_tool) { - GimpRotateTool *rotate = GIMP_ROTATE_TOOL (tr_tool); - GimpDisplay *display = GIMP_TOOL (tr_tool)->display; - GimpImage *image = gimp_display_get_image (display); - gdouble xres; - gdouble yres; + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + GimpRotateTool *rotate = GIMP_ROTATE_TOOL (tg_tool); + GimpDisplay *display = GIMP_TOOL (tg_tool)->display; + GimpImage *image = gimp_display_get_image (display); + gdouble xres; + gdouble yres; - tr_tool->trans_info[ANGLE] = 0.0; - tr_tool->trans_info[PIVOT_X] = (gdouble) (tr_tool->x1 + tr_tool->x2) / 2.0; - tr_tool->trans_info[PIVOT_Y] = (gdouble) (tr_tool->y1 + tr_tool->y2) / 2.0; + tg_tool->trans_info[ANGLE] = 0.0; + tg_tool->trans_info[PIVOT_X] = (gdouble) (tr_tool->x1 + tr_tool->x2) / 2.0; + tg_tool->trans_info[PIVOT_Y] = (gdouble) (tr_tool->y1 + tr_tool->y2) / 2.0; gimp_image_get_resolution (image, &xres, &yres); g_signal_handlers_block_by_func (rotate->sizeentry, rotate_center_changed, - tr_tool); + tg_tool); gimp_size_entry_set_unit (GIMP_SIZE_ENTRY (rotate->sizeentry), gimp_display_get_shell (display)->unit); @@ -291,24 +305,25 @@ gimp_rotate_tool_prepare (GimpTransformTool *tr_tool) g_signal_handlers_unblock_by_func (rotate->sizeentry, rotate_center_changed, - tr_tool); + tg_tool); } static GimpToolWidget * -gimp_rotate_tool_get_widget (GimpTransformTool *tr_tool) +gimp_rotate_tool_get_widget (GimpTransformGridTool *tg_tool) { - GimpTool *tool = GIMP_TOOL (tr_tool); - GimpDisplayShell *shell = gimp_display_get_shell (tool->display); - GimpToolWidget *widget; + GimpTool *tool = GIMP_TOOL (tg_tool); + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + GimpDisplayShell *shell = gimp_display_get_shell (tool->display); + GimpToolWidget *widget; widget = gimp_tool_rotate_grid_new (shell, tr_tool->x1, tr_tool->y1, tr_tool->x2, tr_tool->y2, - tr_tool->trans_info[PIVOT_X], - tr_tool->trans_info[PIVOT_Y], - tr_tool->trans_info[ANGLE]); + tg_tool->trans_info[PIVOT_X], + tg_tool->trans_info[PIVOT_Y], + tg_tool->trans_info[ANGLE]); g_object_set (widget, "inside-function", GIMP_TRANSFORM_FUNCTION_ROTATE, @@ -318,88 +333,80 @@ gimp_rotate_tool_get_widget (GimpTransformTool *tr_tool) g_signal_connect (widget, "changed", G_CALLBACK (gimp_rotate_tool_widget_changed), - tr_tool); + tg_tool); return widget; } static void -gimp_rotate_tool_recalc_matrix (GimpTransformTool *tr_tool, - GimpToolWidget *widget) +gimp_rotate_tool_recalc_matrix (GimpTransformGridTool *tg_tool, + GimpToolWidget *widget) { + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + gimp_matrix3_identity (&tr_tool->transform); gimp_transform_matrix_rotate_center (&tr_tool->transform, - tr_tool->trans_info[PIVOT_X], - tr_tool->trans_info[PIVOT_Y], - tr_tool->trans_info[ANGLE]); + tg_tool->trans_info[PIVOT_X], + tg_tool->trans_info[PIVOT_Y], + tg_tool->trans_info[ANGLE]); if (widget) g_object_set (widget, "transform", &tr_tool->transform, - "angle", tr_tool->trans_info[ANGLE], - "pivot-x", tr_tool->trans_info[PIVOT_X], - "pivot-y", tr_tool->trans_info[PIVOT_Y], + "angle", tg_tool->trans_info[ANGLE], + "pivot-x", tg_tool->trans_info[PIVOT_X], + "pivot-y", tg_tool->trans_info[PIVOT_Y], NULL); } -static gchar * -gimp_rotate_tool_get_undo_desc (GimpTransformTool *tr_tool) -{ - return g_strdup_printf (C_("undo-type", - "Rotate by %-3.3g° around (%g, %g)"), - gimp_rad_to_deg (tr_tool->trans_info[ANGLE]), - tr_tool->trans_info[PIVOT_X], - tr_tool->trans_info[PIVOT_Y]); -} - static void -gimp_rotate_tool_widget_changed (GimpToolWidget *widget, - GimpTransformTool *tr_tool) +gimp_rotate_tool_widget_changed (GimpToolWidget *widget, + GimpTransformGridTool *tg_tool) { g_object_get (widget, - "angle", &tr_tool->trans_info[ANGLE], - "pivot-x", &tr_tool->trans_info[PIVOT_X], - "pivot-y", &tr_tool->trans_info[PIVOT_Y], + "angle", &tg_tool->trans_info[ANGLE], + "pivot-x", &tg_tool->trans_info[PIVOT_X], + "pivot-y", &tg_tool->trans_info[PIVOT_Y], NULL); - gimp_transform_tool_recalc_matrix (tr_tool, NULL); + gimp_transform_grid_tool_recalc_matrix (tg_tool, NULL); } static void -rotate_angle_changed (GtkAdjustment *adj, - GimpTransformTool *tr_tool) +rotate_angle_changed (GtkAdjustment *adj, + GimpTransformGridTool *tg_tool) { gdouble value = gimp_deg_to_rad (gtk_adjustment_get_value (adj)); #define ANGLE_EPSILON 0.0001 - if (ABS (value - tr_tool->trans_info[ANGLE]) > ANGLE_EPSILON) + if (ABS (value - tg_tool->trans_info[ANGLE]) > ANGLE_EPSILON) { - tr_tool->trans_info[ANGLE] = value; + tg_tool->trans_info[ANGLE] = value; - gimp_transform_tool_push_internal_undo (tr_tool); + gimp_transform_grid_tool_push_internal_undo (tg_tool); - gimp_transform_tool_recalc_matrix (tr_tool, tr_tool->widget); + gimp_transform_grid_tool_recalc_matrix (tg_tool, tg_tool->widget); } #undef ANGLE_EPSILON } static void -rotate_center_changed (GtkWidget *widget, - GimpTransformTool *tr_tool) +rotate_center_changed (GtkWidget *widget, + GimpTransformGridTool *tg_tool) { gdouble px = gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (widget), 0); gdouble py = gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (widget), 1); - if ((px != tr_tool->trans_info[PIVOT_X]) || - (py != tr_tool->trans_info[PIVOT_Y])) + if ((px != tg_tool->trans_info[PIVOT_X]) || + (py != tg_tool->trans_info[PIVOT_Y])) { - tr_tool->trans_info[PIVOT_X] = px; - tr_tool->trans_info[PIVOT_Y] = py; + tg_tool->trans_info[PIVOT_X] = px; + tg_tool->trans_info[PIVOT_Y] = py; - gimp_transform_tool_push_internal_undo (tr_tool); + gimp_transform_grid_tool_push_internal_undo (tg_tool); - gimp_transform_tool_recalc_matrix (tr_tool, tr_tool->widget); + gimp_transform_grid_tool_recalc_matrix (tg_tool, tg_tool->widget); } } diff --git a/app/tools/gimprotatetool.h b/app/tools/gimprotatetool.h index e7e02d1b62..290c4302f7 100644 --- a/app/tools/gimprotatetool.h +++ b/app/tools/gimprotatetool.h @@ -19,7 +19,7 @@ #define __GIMP_ROTATE_TOOL_H__ -#include "gimptransformtool.h" +#include "gimptransformgridtool.h" #define GIMP_TYPE_ROTATE_TOOL (gimp_rotate_tool_get_type ()) @@ -35,16 +35,16 @@ typedef struct _GimpRotateToolClass GimpRotateToolClass; struct _GimpRotateTool { - GimpTransformTool parent_instance; + GimpTransformGridTool parent_instance; - GtkAdjustment *angle_adj; - GtkWidget *angle_spin_button; - GtkWidget *sizeentry; + GtkAdjustment *angle_adj; + GtkWidget *angle_spin_button; + GtkWidget *sizeentry; }; struct _GimpRotateToolClass { - GimpTransformToolClass parent_class; + GimpTransformGridToolClass parent_class; }; diff --git a/app/tools/gimpscaletool.c b/app/tools/gimpscaletool.c index f01e4cfe09..9b75e50585 100644 --- a/app/tools/gimpscaletool.c +++ b/app/tools/gimpscaletool.c @@ -40,7 +40,7 @@ #include "gimpscaletool.h" #include "gimptoolcontrol.h" -#include "gimptransformoptions.h" +#include "gimptransformgridoptions.h" #include "gimp-intl.h" @@ -57,23 +57,24 @@ enum /* local function prototypes */ -static void gimp_scale_tool_dialog (GimpTransformTool *tr_tool); -static void gimp_scale_tool_dialog_update (GimpTransformTool *tr_tool); -static void gimp_scale_tool_prepare (GimpTransformTool *tr_tool); -static GimpToolWidget * gimp_scale_tool_get_widget (GimpTransformTool *tr_tool); -static void gimp_scale_tool_recalc_matrix (GimpTransformTool *tr_tool, - GimpToolWidget *widget); -static gchar * gimp_scale_tool_get_undo_desc (GimpTransformTool *tr_tool); +static gchar * gimp_scale_tool_get_undo_desc (GimpTransformTool *tr_tool); -static void gimp_scale_tool_widget_changed (GimpToolWidget *widget, - GimpTransformTool *tr_tool); +static void gimp_scale_tool_dialog (GimpTransformGridTool *tg_tool); +static void gimp_scale_tool_dialog_update (GimpTransformGridTool *tg_tool); +static void gimp_scale_tool_prepare (GimpTransformGridTool *tg_tool); +static GimpToolWidget * gimp_scale_tool_get_widget (GimpTransformGridTool *tg_tool); +static void gimp_scale_tool_recalc_matrix (GimpTransformGridTool *tg_tool, + GimpToolWidget *widget); -static void gimp_scale_tool_size_notify (GtkWidget *box, - GParamSpec *pspec, - GimpTransformTool *tr_tool); +static void gimp_scale_tool_widget_changed (GimpToolWidget *widget, + GimpTransformGridTool *tg_tool); + +static void gimp_scale_tool_size_notify (GtkWidget *box, + GParamSpec *pspec, + GimpTransformGridTool *tg_tool); -G_DEFINE_TYPE (GimpScaleTool, gimp_scale_tool, GIMP_TYPE_TRANSFORM_TOOL) +G_DEFINE_TYPE (GimpScaleTool, gimp_scale_tool, GIMP_TYPE_TRANSFORM_GRID_TOOL) #define parent_class gimp_scale_tool_parent_class @@ -83,8 +84,8 @@ gimp_scale_tool_register (GimpToolRegisterCallback callback, gpointer data) { (* callback) (GIMP_TYPE_SCALE_TOOL, - GIMP_TYPE_TRANSFORM_OPTIONS, - gimp_transform_options_gui, + GIMP_TYPE_TRANSFORM_GRID_OPTIONS, + gimp_transform_grid_options_gui, GIMP_CONTEXT_PROP_MASK_BACKGROUND, "gimp-scale-tool", _("Scale"), @@ -98,45 +99,59 @@ gimp_scale_tool_register (GimpToolRegisterCallback callback, static void gimp_scale_tool_class_init (GimpScaleToolClass *klass) { - GimpTransformToolClass *trans_class = GIMP_TRANSFORM_TOOL_CLASS (klass); + GimpTransformToolClass *tr_class = GIMP_TRANSFORM_TOOL_CLASS (klass); + GimpTransformGridToolClass *tg_class = GIMP_TRANSFORM_GRID_TOOL_CLASS (klass); - trans_class->dialog = gimp_scale_tool_dialog; - trans_class->dialog_update = gimp_scale_tool_dialog_update; - trans_class->prepare = gimp_scale_tool_prepare; - trans_class->get_widget = gimp_scale_tool_get_widget; - trans_class->recalc_matrix = gimp_scale_tool_recalc_matrix; - trans_class->get_undo_desc = gimp_scale_tool_get_undo_desc; + tr_class->get_undo_desc = gimp_scale_tool_get_undo_desc; - trans_class->ok_button_label = _("_Scale"); + tg_class->dialog = gimp_scale_tool_dialog; + tg_class->dialog_update = gimp_scale_tool_dialog_update; + tg_class->prepare = gimp_scale_tool_prepare; + tg_class->get_widget = gimp_scale_tool_get_widget; + tg_class->recalc_matrix = gimp_scale_tool_recalc_matrix; + + tr_class->progress_text = _("Scaling"); + tg_class->ok_button_label = _("_Scale"); } static void gimp_scale_tool_init (GimpScaleTool *scale_tool) { - GimpTool *tool = GIMP_TOOL (scale_tool); - GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (scale_tool); + GimpTool *tool = GIMP_TOOL (scale_tool); gimp_tool_control_set_tool_cursor (tool->control, GIMP_TOOL_CURSOR_RESIZE); +} - tr_tool->progress_text = _("Scaling"); +static gchar * +gimp_scale_tool_get_undo_desc (GimpTransformTool *tr_tool) +{ + GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (tr_tool); + gint width; + gint height; + + width = ROUND (tg_tool->trans_info[X1] - tg_tool->trans_info[X0]); + height = ROUND (tg_tool->trans_info[Y1] - tg_tool->trans_info[Y0]); + + return g_strdup_printf (C_("undo-type", "Scale to %d x %d"), + width, height); } static void -gimp_scale_tool_dialog (GimpTransformTool *tr_tool) +gimp_scale_tool_dialog (GimpTransformGridTool *tg_tool) { } static void -gimp_scale_tool_dialog_update (GimpTransformTool *tr_tool) +gimp_scale_tool_dialog_update (GimpTransformGridTool *tg_tool) { - GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool); - gint width; - gint height; + GimpTransformGridOptions *options = GIMP_TRANSFORM_GRID_TOOL_GET_OPTIONS (tg_tool); + gint width; + gint height; - width = ROUND (tr_tool->trans_info[X1] - tr_tool->trans_info[X0]); - height = ROUND (tr_tool->trans_info[Y1] - tr_tool->trans_info[Y0]); + width = ROUND (tg_tool->trans_info[X1] - tg_tool->trans_info[X0]); + height = ROUND (tg_tool->trans_info[Y1] - tg_tool->trans_info[Y0]); - g_object_set (GIMP_SCALE_TOOL (tr_tool)->box, + g_object_set (GIMP_SCALE_TOOL (tg_tool)->box, "width", width, "height", height, "keep-aspect", options->constrain_scale, @@ -144,18 +159,19 @@ gimp_scale_tool_dialog_update (GimpTransformTool *tr_tool) } static void -gimp_scale_tool_prepare (GimpTransformTool *tr_tool) +gimp_scale_tool_prepare (GimpTransformGridTool *tg_tool) { - GimpScaleTool *scale = GIMP_SCALE_TOOL (tr_tool); - GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool); - GimpDisplay *display = GIMP_TOOL (tr_tool)->display; - gdouble xres; - gdouble yres; + GimpScaleTool *scale = GIMP_SCALE_TOOL (tg_tool); + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + GimpTransformGridOptions *options = GIMP_TRANSFORM_GRID_TOOL_GET_OPTIONS (tg_tool); + GimpDisplay *display = GIMP_TOOL (tg_tool)->display; + gdouble xres; + gdouble yres; - tr_tool->trans_info[X0] = (gdouble) tr_tool->x1; - tr_tool->trans_info[Y0] = (gdouble) tr_tool->y1; - tr_tool->trans_info[X1] = (gdouble) tr_tool->x2; - tr_tool->trans_info[Y1] = (gdouble) tr_tool->y2; + tg_tool->trans_info[X0] = (gdouble) tr_tool->x1; + tg_tool->trans_info[Y0] = (gdouble) tr_tool->y1; + tg_tool->trans_info[X1] = (gdouble) tr_tool->x2; + tg_tool->trans_info[Y1] = (gdouble) tr_tool->y2; gimp_image_get_resolution (gimp_display_get_image (display), &xres, &yres); @@ -164,7 +180,7 @@ gimp_scale_tool_prepare (GimpTransformTool *tr_tool) { g_signal_handlers_disconnect_by_func (scale->box, gimp_scale_tool_size_notify, - tr_tool); + tg_tool); gtk_widget_destroy (scale->box); } @@ -181,21 +197,22 @@ gimp_scale_tool_prepare (GimpTransformTool *tr_tool) "yresolution", yres, NULL); - gtk_box_pack_start (GTK_BOX (gimp_tool_gui_get_vbox (tr_tool->gui)), + gtk_box_pack_start (GTK_BOX (gimp_tool_gui_get_vbox (tg_tool->gui)), scale->box, FALSE, FALSE, 0); gtk_widget_show (scale->box); g_signal_connect (scale->box, "notify", G_CALLBACK (gimp_scale_tool_size_notify), - tr_tool); + tg_tool); } static GimpToolWidget * -gimp_scale_tool_get_widget (GimpTransformTool *tr_tool) +gimp_scale_tool_get_widget (GimpTransformGridTool *tg_tool) { - GimpTool *tool = GIMP_TOOL (tr_tool); - GimpDisplayShell *shell = gimp_display_get_shell (tool->display); - GimpToolWidget *widget; + GimpTool *tool = GIMP_TOOL (tg_tool); + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + GimpDisplayShell *shell = gimp_display_get_shell (tool->display); + GimpToolWidget *widget; widget = gimp_tool_transform_grid_new (shell, &tr_tool->transform, @@ -216,25 +233,27 @@ gimp_scale_tool_get_widget (GimpTransformTool *tr_tool) g_signal_connect (widget, "changed", G_CALLBACK (gimp_scale_tool_widget_changed), - tr_tool); + tg_tool); return widget; } static void -gimp_scale_tool_recalc_matrix (GimpTransformTool *tr_tool, - GimpToolWidget *widget) +gimp_scale_tool_recalc_matrix (GimpTransformGridTool *tg_tool, + GimpToolWidget *widget) { + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + gimp_matrix3_identity (&tr_tool->transform); gimp_transform_matrix_scale (&tr_tool->transform, tr_tool->x1, tr_tool->y1, tr_tool->x2 - tr_tool->x1, tr_tool->y2 - tr_tool->y1, - tr_tool->trans_info[X0], - tr_tool->trans_info[Y0], - tr_tool->trans_info[X1] - tr_tool->trans_info[X0], - tr_tool->trans_info[Y1] - tr_tool->trans_info[Y0]); + tg_tool->trans_info[X0], + tg_tool->trans_info[Y0], + tg_tool->trans_info[X1] - tg_tool->trans_info[X0], + tg_tool->trans_info[Y1] - tg_tool->trans_info[Y0]); if (widget) g_object_set (widget, @@ -248,21 +267,12 @@ gimp_scale_tool_recalc_matrix (GimpTransformTool *tr_tool, NULL); } -static gchar * -gimp_scale_tool_get_undo_desc (GimpTransformTool *tr_tool) -{ - gint width = ROUND (tr_tool->trans_info[X1] - tr_tool->trans_info[X0]); - gint height = ROUND (tr_tool->trans_info[Y1] - tr_tool->trans_info[Y0]); - - return g_strdup_printf (C_("undo-type", "Scale to %d x %d"), - width, height); -} - static void -gimp_scale_tool_widget_changed (GimpToolWidget *widget, - GimpTransformTool *tr_tool) +gimp_scale_tool_widget_changed (GimpToolWidget *widget, + GimpTransformGridTool *tg_tool) { - GimpMatrix3 *transform; + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + GimpMatrix3 *transform; g_object_get (widget, "transform", &transform, @@ -270,24 +280,24 @@ gimp_scale_tool_widget_changed (GimpToolWidget *widget, gimp_matrix3_transform_point (transform, tr_tool->x1, tr_tool->y1, - &tr_tool->trans_info[X0], - &tr_tool->trans_info[Y0]); + &tg_tool->trans_info[X0], + &tg_tool->trans_info[Y0]); gimp_matrix3_transform_point (transform, tr_tool->x2, tr_tool->y2, - &tr_tool->trans_info[X1], - &tr_tool->trans_info[Y1]); + &tg_tool->trans_info[X1], + &tg_tool->trans_info[Y1]); g_free (transform); - gimp_transform_tool_recalc_matrix (tr_tool, NULL); + gimp_transform_grid_tool_recalc_matrix (tg_tool, NULL); } static void -gimp_scale_tool_size_notify (GtkWidget *box, - GParamSpec *pspec, - GimpTransformTool *tr_tool) +gimp_scale_tool_size_notify (GtkWidget *box, + GParamSpec *pspec, + GimpTransformGridTool *tg_tool) { - GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool); + GimpTransformGridOptions *options = GIMP_TRANSFORM_GRID_TOOL_GET_OPTIONS (tg_tool); if (! strcmp (pspec->name, "width") || ! strcmp (pspec->name, "height")) @@ -302,17 +312,17 @@ gimp_scale_tool_size_notify (GtkWidget *box, "height", &height, NULL); - old_width = ROUND (tr_tool->trans_info[X1] - tr_tool->trans_info[X0]); - old_height = ROUND (tr_tool->trans_info[Y1] - tr_tool->trans_info[Y0]); + old_width = ROUND (tg_tool->trans_info[X1] - tg_tool->trans_info[X0]); + old_height = ROUND (tg_tool->trans_info[Y1] - tg_tool->trans_info[Y0]); if ((width != old_width) || (height != old_height)) { - tr_tool->trans_info[X1] = tr_tool->trans_info[X0] + width; - tr_tool->trans_info[Y1] = tr_tool->trans_info[Y0] + height; + tg_tool->trans_info[X1] = tg_tool->trans_info[X0] + width; + tg_tool->trans_info[Y1] = tg_tool->trans_info[Y0] + height; - gimp_transform_tool_push_internal_undo (tr_tool); + gimp_transform_grid_tool_push_internal_undo (tg_tool); - gimp_transform_tool_recalc_matrix (tr_tool, tr_tool->widget); + gimp_transform_grid_tool_recalc_matrix (tg_tool, tg_tool->widget); } } else if (! strcmp (pspec->name, "keep-aspect")) diff --git a/app/tools/gimpscaletool.h b/app/tools/gimpscaletool.h index e0b5aaf3c6..5e6e3d3ae8 100644 --- a/app/tools/gimpscaletool.h +++ b/app/tools/gimpscaletool.h @@ -19,7 +19,7 @@ #define __GIMP_SCALE_TOOL_H__ -#include "gimptransformtool.h" +#include "gimptransformgridtool.h" #define GIMP_TYPE_SCALE_TOOL (gimp_scale_tool_get_type ()) @@ -34,14 +34,14 @@ typedef struct _GimpScaleToolClass GimpScaleToolClass; struct _GimpScaleTool { - GimpTransformTool parent_instance; + GimpTransformGridTool parent_instance; - GtkWidget *box; + GtkWidget *box; }; struct _GimpScaleToolClass { - GimpTransformToolClass parent_class; + GimpTransformGridToolClass parent_class; }; diff --git a/app/tools/gimpsheartool.c b/app/tools/gimpsheartool.c index 05ab933871..d74219c002 100644 --- a/app/tools/gimpsheartool.c +++ b/app/tools/gimpsheartool.c @@ -36,7 +36,7 @@ #include "gimpsheartool.h" #include "gimptoolcontrol.h" -#include "gimptransformoptions.h" +#include "gimptransformgridoptions.h" #include "gimp-intl.h" @@ -55,25 +55,25 @@ enum /* local function prototypes */ -static void gimp_shear_tool_dialog (GimpTransformTool *tr_tool); -static void gimp_shear_tool_dialog_update (GimpTransformTool *tr_tool); +static gchar * gimp_shear_tool_get_undo_desc (GimpTransformTool *tr_tool); -static void gimp_shear_tool_prepare (GimpTransformTool *tr_tool); -static GimpToolWidget * gimp_shear_tool_get_widget (GimpTransformTool *tr_tool); -static void gimp_shear_tool_recalc_matrix (GimpTransformTool *tr_tool, - GimpToolWidget *widget); -static gchar * gimp_shear_tool_get_undo_desc (GimpTransformTool *tr_tool); +static void gimp_shear_tool_dialog (GimpTransformGridTool *tg_tool); +static void gimp_shear_tool_dialog_update (GimpTransformGridTool *tg_tool); +static void gimp_shear_tool_prepare (GimpTransformGridTool *tg_tool); +static GimpToolWidget * gimp_shear_tool_get_widget (GimpTransformGridTool *tg_tool); +static void gimp_shear_tool_recalc_matrix (GimpTransformGridTool *tg_tool, + GimpToolWidget *widget); -static void gimp_shear_tool_widget_changed (GimpToolWidget *widget, - GimpTransformTool *tr_tool); +static void gimp_shear_tool_widget_changed (GimpToolWidget *widget, + GimpTransformGridTool *tg_tool); -static void shear_x_mag_changed (GtkAdjustment *adj, - GimpTransformTool *tr_tool); -static void shear_y_mag_changed (GtkAdjustment *adj, - GimpTransformTool *tr_tool); +static void shear_x_mag_changed (GtkAdjustment *adj, + GimpTransformGridTool *tg_tool); +static void shear_y_mag_changed (GtkAdjustment *adj, + GimpTransformGridTool *tg_tool); -G_DEFINE_TYPE (GimpShearTool, gimp_shear_tool, GIMP_TYPE_TRANSFORM_TOOL) +G_DEFINE_TYPE (GimpShearTool, gimp_shear_tool, GIMP_TYPE_TRANSFORM_GRID_TOOL) void @@ -81,8 +81,8 @@ gimp_shear_tool_register (GimpToolRegisterCallback callback, gpointer data) { (* callback) (GIMP_TYPE_SHEAR_TOOL, - GIMP_TYPE_TRANSFORM_OPTIONS, - gimp_transform_options_gui, + GIMP_TYPE_TRANSFORM_GRID_OPTIONS, + gimp_transform_grid_options_gui, 0, "gimp-shear-tool", _("Shear"), @@ -96,154 +96,37 @@ gimp_shear_tool_register (GimpToolRegisterCallback callback, static void gimp_shear_tool_class_init (GimpShearToolClass *klass) { - GimpTransformToolClass *trans_class = GIMP_TRANSFORM_TOOL_CLASS (klass); + GimpTransformToolClass *tr_class = GIMP_TRANSFORM_TOOL_CLASS (klass); + GimpTransformGridToolClass *tg_class = GIMP_TRANSFORM_GRID_TOOL_CLASS (klass); - trans_class->dialog = gimp_shear_tool_dialog; - trans_class->dialog_update = gimp_shear_tool_dialog_update; - trans_class->prepare = gimp_shear_tool_prepare; - trans_class->get_widget = gimp_shear_tool_get_widget; - trans_class->recalc_matrix = gimp_shear_tool_recalc_matrix; - trans_class->get_undo_desc = gimp_shear_tool_get_undo_desc; + tr_class->get_undo_desc = gimp_shear_tool_get_undo_desc; - trans_class->ok_button_label = _("_Shear"); + tg_class->dialog = gimp_shear_tool_dialog; + tg_class->dialog_update = gimp_shear_tool_dialog_update; + tg_class->prepare = gimp_shear_tool_prepare; + tg_class->get_widget = gimp_shear_tool_get_widget; + tg_class->recalc_matrix = gimp_shear_tool_recalc_matrix; + + tr_class->progress_text = _("Shearing"); + tg_class->ok_button_label = _("_Shear"); } static void gimp_shear_tool_init (GimpShearTool *shear_tool) { - GimpTool *tool = GIMP_TOOL (shear_tool); - GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (shear_tool); + GimpTool *tool = GIMP_TOOL (shear_tool); gimp_tool_control_set_tool_cursor (tool->control, GIMP_TOOL_CURSOR_SHEAR); - - tr_tool->progress_text = _("Shearing"); -} - -static void -gimp_shear_tool_dialog (GimpTransformTool *tr_tool) -{ - GimpShearTool *shear = GIMP_SHEAR_TOOL (tr_tool); - GtkWidget *vbox; - GtkWidget *scale; - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2); - gtk_box_pack_start (GTK_BOX (gimp_tool_gui_get_vbox (tr_tool->gui)), vbox, - FALSE, FALSE, 0); - gtk_widget_show (vbox); - - shear->x_adj = gtk_adjustment_new (0, -65536, 65536, 1, 10, 0); - scale = gimp_spin_scale_new (shear->x_adj, _("Shear magnitude _X"), 0); - gimp_spin_scale_set_scale_limits (GIMP_SPIN_SCALE (scale), -1000, 1000); - gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0); - gtk_widget_show (scale); - - g_signal_connect (shear->x_adj, "value-changed", - G_CALLBACK (shear_x_mag_changed), - tr_tool); - - shear->y_adj = gtk_adjustment_new (0, -65536, 65536, 1, 10, 0); - scale = gimp_spin_scale_new (shear->y_adj, _("Shear magnitude _Y"), 0); - gimp_spin_scale_set_scale_limits (GIMP_SPIN_SCALE (scale), -1000, 1000); - gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0); - gtk_widget_show (scale); - - g_signal_connect (shear->y_adj, "value-changed", - G_CALLBACK (shear_y_mag_changed), - tr_tool); -} - -static void -gimp_shear_tool_dialog_update (GimpTransformTool *tr_tool) -{ - GimpShearTool *shear = GIMP_SHEAR_TOOL (tr_tool); - - gtk_adjustment_set_value (shear->x_adj, tr_tool->trans_info[SHEAR_X]); - gtk_adjustment_set_value (shear->y_adj, tr_tool->trans_info[SHEAR_Y]); -} - -static void -gimp_shear_tool_prepare (GimpTransformTool *tr_tool) -{ - tr_tool->trans_info[ORIENTATION] = GIMP_ORIENTATION_UNKNOWN; - tr_tool->trans_info[SHEAR_X] = 0.0; - tr_tool->trans_info[SHEAR_Y] = 0.0; -} - -static GimpToolWidget * -gimp_shear_tool_get_widget (GimpTransformTool *tr_tool) -{ - GimpTool *tool = GIMP_TOOL (tr_tool); - GimpDisplayShell *shell = gimp_display_get_shell (tool->display); - GimpToolWidget *widget; - - widget = gimp_tool_shear_grid_new (shell, - tr_tool->x1, - tr_tool->y1, - tr_tool->x2, - tr_tool->y2, - tr_tool->trans_info[ORIENTATION], - tr_tool->trans_info[SHEAR_X], - tr_tool->trans_info[SHEAR_Y]); - - g_object_set (widget, - "inside-function", GIMP_TRANSFORM_FUNCTION_SHEAR, - "outside-function", GIMP_TRANSFORM_FUNCTION_SHEAR, - "frompivot-shear", TRUE, - NULL); - - g_signal_connect (widget, "changed", - G_CALLBACK (gimp_shear_tool_widget_changed), - tr_tool); - - return widget; -} - -static void -gimp_shear_tool_recalc_matrix (GimpTransformTool *tr_tool, - GimpToolWidget *widget) -{ - gdouble amount; - - if (tr_tool->trans_info[SHEAR_X] == 0.0 && - tr_tool->trans_info[SHEAR_Y] == 0.0) - { - tr_tool->trans_info[ORIENTATION] = GIMP_ORIENTATION_UNKNOWN; - } - - if (tr_tool->trans_info[ORIENTATION] == GIMP_ORIENTATION_HORIZONTAL) - amount = tr_tool->trans_info[SHEAR_X]; - else - amount = tr_tool->trans_info[SHEAR_Y]; - - gimp_matrix3_identity (&tr_tool->transform); - gimp_transform_matrix_shear (&tr_tool->transform, - tr_tool->x1, - tr_tool->y1, - tr_tool->x2 - tr_tool->x1, - tr_tool->y2 - tr_tool->y1, - tr_tool->trans_info[ORIENTATION], - amount); - - if (widget) - g_object_set (widget, - "transform", &tr_tool->transform, - "x1", (gdouble) tr_tool->x1, - "y1", (gdouble) tr_tool->y1, - "x2", (gdouble) tr_tool->x2, - "y2", (gdouble) tr_tool->y2, - "orientation", (gint) tr_tool->trans_info[ORIENTATION], - "shear-x", tr_tool->trans_info[SHEAR_X], - "shear-y", tr_tool->trans_info[SHEAR_Y], - NULL); } static gchar * gimp_shear_tool_get_undo_desc (GimpTransformTool *tr_tool) { - gdouble x = tr_tool->trans_info[SHEAR_X]; - gdouble y = tr_tool->trans_info[SHEAR_Y]; + GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (tr_tool); + gdouble x = tg_tool->trans_info[SHEAR_X]; + gdouble y = tg_tool->trans_info[SHEAR_Y]; - switch ((gint) tr_tool->trans_info[ORIENTATION]) + switch ((gint) tg_tool->trans_info[ORIENTATION]) { case GIMP_ORIENTATION_HORIZONTAL: return g_strdup_printf (C_("undo-type", "Shear horizontally by %-3.3g"), @@ -261,56 +144,176 @@ gimp_shear_tool_get_undo_desc (GimpTransformTool *tr_tool) } static void -gimp_shear_tool_widget_changed (GimpToolWidget *widget, - GimpTransformTool *tr_tool) +gimp_shear_tool_dialog (GimpTransformGridTool *tg_tool) +{ + GimpShearTool *shear = GIMP_SHEAR_TOOL (tg_tool); + GtkWidget *vbox; + GtkWidget *scale; + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2); + gtk_box_pack_start (GTK_BOX (gimp_tool_gui_get_vbox (tg_tool->gui)), vbox, + FALSE, FALSE, 0); + gtk_widget_show (vbox); + + shear->x_adj = gtk_adjustment_new (0, -65536, 65536, 1, 10, 0); + scale = gimp_spin_scale_new (shear->x_adj, _("Shear magnitude _X"), 0); + gimp_spin_scale_set_scale_limits (GIMP_SPIN_SCALE (scale), -1000, 1000); + gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0); + gtk_widget_show (scale); + + g_signal_connect (shear->x_adj, "value-changed", + G_CALLBACK (shear_x_mag_changed), + tg_tool); + + shear->y_adj = gtk_adjustment_new (0, -65536, 65536, 1, 10, 0); + scale = gimp_spin_scale_new (shear->y_adj, _("Shear magnitude _Y"), 0); + gimp_spin_scale_set_scale_limits (GIMP_SPIN_SCALE (scale), -1000, 1000); + gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0); + gtk_widget_show (scale); + + g_signal_connect (shear->y_adj, "value-changed", + G_CALLBACK (shear_y_mag_changed), + tg_tool); +} + +static void +gimp_shear_tool_dialog_update (GimpTransformGridTool *tg_tool) +{ + GimpShearTool *shear = GIMP_SHEAR_TOOL (tg_tool); + + gtk_adjustment_set_value (shear->x_adj, tg_tool->trans_info[SHEAR_X]); + gtk_adjustment_set_value (shear->y_adj, tg_tool->trans_info[SHEAR_Y]); +} + +static void +gimp_shear_tool_prepare (GimpTransformGridTool *tg_tool) +{ + tg_tool->trans_info[ORIENTATION] = GIMP_ORIENTATION_UNKNOWN; + tg_tool->trans_info[SHEAR_X] = 0.0; + tg_tool->trans_info[SHEAR_Y] = 0.0; +} + +static GimpToolWidget * +gimp_shear_tool_get_widget (GimpTransformGridTool *tg_tool) +{ + GimpTool *tool = GIMP_TOOL (tg_tool); + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + GimpDisplayShell *shell = gimp_display_get_shell (tool->display); + GimpToolWidget *widget; + + widget = gimp_tool_shear_grid_new (shell, + tr_tool->x1, + tr_tool->y1, + tr_tool->x2, + tr_tool->y2, + tg_tool->trans_info[ORIENTATION], + tg_tool->trans_info[SHEAR_X], + tg_tool->trans_info[SHEAR_Y]); + + g_object_set (widget, + "inside-function", GIMP_TRANSFORM_FUNCTION_SHEAR, + "outside-function", GIMP_TRANSFORM_FUNCTION_SHEAR, + "frompivot-shear", TRUE, + NULL); + + g_signal_connect (widget, "changed", + G_CALLBACK (gimp_shear_tool_widget_changed), + tg_tool); + + return widget; +} + +static void +gimp_shear_tool_recalc_matrix (GimpTransformGridTool *tg_tool, + GimpToolWidget *widget) +{ + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + gdouble amount; + + if (tg_tool->trans_info[SHEAR_X] == 0.0 && + tg_tool->trans_info[SHEAR_Y] == 0.0) + { + tg_tool->trans_info[ORIENTATION] = GIMP_ORIENTATION_UNKNOWN; + } + + if (tg_tool->trans_info[ORIENTATION] == GIMP_ORIENTATION_HORIZONTAL) + amount = tg_tool->trans_info[SHEAR_X]; + else + amount = tg_tool->trans_info[SHEAR_Y]; + + gimp_matrix3_identity (&tr_tool->transform); + gimp_transform_matrix_shear (&tr_tool->transform, + tr_tool->x1, + tr_tool->y1, + tr_tool->x2 - tr_tool->x1, + tr_tool->y2 - tr_tool->y1, + tg_tool->trans_info[ORIENTATION], + amount); + + if (widget) + g_object_set (widget, + "transform", &tr_tool->transform, + "x1", (gdouble) tr_tool->x1, + "y1", (gdouble) tr_tool->y1, + "x2", (gdouble) tr_tool->x2, + "y2", (gdouble) tr_tool->y2, + "orientation", (gint) tg_tool->trans_info[ORIENTATION], + "shear-x", tg_tool->trans_info[SHEAR_X], + "shear-y", tg_tool->trans_info[SHEAR_Y], + NULL); +} + +static void +gimp_shear_tool_widget_changed (GimpToolWidget *widget, + GimpTransformGridTool *tg_tool) { GimpOrientationType orientation; g_object_get (widget, "orientation", &orientation, - "shear-x", &tr_tool->trans_info[SHEAR_X], - "shear-y", &tr_tool->trans_info[SHEAR_Y], + "shear-x", &tg_tool->trans_info[SHEAR_X], + "shear-y", &tg_tool->trans_info[SHEAR_Y], NULL); - tr_tool->trans_info[ORIENTATION] = orientation; + tg_tool->trans_info[ORIENTATION] = orientation; - gimp_transform_tool_recalc_matrix (tr_tool, NULL); + gimp_transform_grid_tool_recalc_matrix (tg_tool, NULL); } static void -shear_x_mag_changed (GtkAdjustment *adj, - GimpTransformTool *tr_tool) +shear_x_mag_changed (GtkAdjustment *adj, + GimpTransformGridTool *tg_tool) { gdouble value = gtk_adjustment_get_value (adj); - if (value != tr_tool->trans_info[SHEAR_X]) + if (value != tg_tool->trans_info[SHEAR_X]) { - tr_tool->trans_info[ORIENTATION] = GIMP_ORIENTATION_HORIZONTAL; + tg_tool->trans_info[ORIENTATION] = GIMP_ORIENTATION_HORIZONTAL; - tr_tool->trans_info[SHEAR_X] = value; - tr_tool->trans_info[SHEAR_Y] = 0.0; /* can only shear in one axis */ + tg_tool->trans_info[SHEAR_X] = value; + tg_tool->trans_info[SHEAR_Y] = 0.0; /* can only shear in one axis */ - gimp_transform_tool_push_internal_undo (tr_tool); + gimp_transform_grid_tool_push_internal_undo (tg_tool); - gimp_transform_tool_recalc_matrix (tr_tool, tr_tool->widget); + gimp_transform_grid_tool_recalc_matrix (tg_tool, tg_tool->widget); } } static void -shear_y_mag_changed (GtkAdjustment *adj, - GimpTransformTool *tr_tool) +shear_y_mag_changed (GtkAdjustment *adj, + GimpTransformGridTool *tg_tool) { gdouble value = gtk_adjustment_get_value (adj); - if (value != tr_tool->trans_info[SHEAR_Y]) + if (value != tg_tool->trans_info[SHEAR_Y]) { - tr_tool->trans_info[ORIENTATION] = GIMP_ORIENTATION_VERTICAL; + tg_tool->trans_info[ORIENTATION] = GIMP_ORIENTATION_VERTICAL; - tr_tool->trans_info[SHEAR_Y] = value; - tr_tool->trans_info[SHEAR_X] = 0.0; /* can only shear in one axis */ + tg_tool->trans_info[SHEAR_Y] = value; + tg_tool->trans_info[SHEAR_X] = 0.0; /* can only shear in one axis */ - gimp_transform_tool_push_internal_undo (tr_tool); + gimp_transform_grid_tool_push_internal_undo (tg_tool); - gimp_transform_tool_recalc_matrix (tr_tool, tr_tool->widget); + gimp_transform_grid_tool_recalc_matrix (tg_tool, tg_tool->widget); } } diff --git a/app/tools/gimpsheartool.h b/app/tools/gimpsheartool.h index 32d278a02e..a26a4a0b83 100644 --- a/app/tools/gimpsheartool.h +++ b/app/tools/gimpsheartool.h @@ -19,7 +19,7 @@ #define __GIMP_SHEAR_TOOL_H__ -#include "gimptransformtool.h" +#include "gimptransformgridtool.h" #define GIMP_TYPE_SHEAR_TOOL (gimp_shear_tool_get_type ()) @@ -35,15 +35,15 @@ typedef struct _GimpShearToolClass GimpShearToolClass; struct _GimpShearTool { - GimpTransformTool parent_instance; + GimpTransformGridTool parent_instance; - GtkAdjustment *x_adj; - GtkAdjustment *y_adj; + GtkAdjustment *x_adj; + GtkAdjustment *y_adj; }; struct _GimpShearToolClass { - GimpTransformToolClass parent_class; + GimpTransformGridToolClass parent_class; }; diff --git a/app/tools/gimptransformgridoptions.c b/app/tools/gimptransformgridoptions.c new file mode 100644 index 0000000000..4e1802662d --- /dev/null +++ b/app/tools/gimptransformgridoptions.c @@ -0,0 +1,548 @@ +/* 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 "libgimpconfig/gimpconfig.h" +#include "libgimpwidgets/gimpwidgets.h" + +#include "tools-types.h" + +#include "core/gimp.h" +#include "core/gimptoolinfo.h" + +#include "widgets/gimppropwidgets.h" +#include "widgets/gimpspinscale.h" +#include "widgets/gimpwidgets-utils.h" + +#include "gimprotatetool.h" +#include "gimpscaletool.h" +#include "gimpunifiedtransformtool.h" +#include "gimptooloptions-gui.h" +#include "gimptransformgridoptions.h" + +#include "gimp-intl.h" + + +enum +{ + PROP_0, + PROP_DIRECTION, + PROP_SHOW_PREVIEW, + PROP_PREVIEW_OPACITY, + PROP_GRID_TYPE, + PROP_GRID_SIZE, + PROP_CONSTRAIN_MOVE, + PROP_CONSTRAIN_SCALE, + PROP_CONSTRAIN_ROTATE, + PROP_CONSTRAIN_SHEAR, + PROP_CONSTRAIN_PERSPECTIVE, + PROP_FROMPIVOT_SCALE, + PROP_FROMPIVOT_SHEAR, + PROP_FROMPIVOT_PERSPECTIVE, + PROP_CORNERSNAP, + PROP_FIXEDPIVOT, +}; + + +static void gimp_transform_grid_options_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void gimp_transform_grid_options_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); + +static gboolean gimp_transform_grid_options_sync_grid (GBinding *binding, + const GValue *source_value, + GValue *target_value, + gpointer user_data); + + +G_DEFINE_TYPE (GimpTransformGridOptions, gimp_transform_grid_options, + GIMP_TYPE_TRANSFORM_OPTIONS) + +#define parent_class gimp_transform_grid_options_parent_class + + +static void +gimp_transform_grid_options_class_init (GimpTransformGridOptionsClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = gimp_transform_grid_options_set_property; + object_class->get_property = gimp_transform_grid_options_get_property; + + g_object_class_override_property (object_class, PROP_DIRECTION, + "direction"); + + GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_PREVIEW, + "show-preview", + _("Show image preview"), + _("Show a preview of the transform_grided image"), + TRUE, + GIMP_PARAM_STATIC_STRINGS); + + GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_PREVIEW_OPACITY, + "preview-opacity", + _("Image opacity"), + _("Opacity of the preview image"), + 0.0, 1.0, 1.0, + GIMP_PARAM_STATIC_STRINGS); + + GIMP_CONFIG_PROP_ENUM (object_class, PROP_GRID_TYPE, + "grid-type", + _("Guides"), + _("Composition guides such as rule of thirds"), + GIMP_TYPE_GUIDES_TYPE, + GIMP_GUIDES_NONE, + GIMP_PARAM_STATIC_STRINGS); + + GIMP_CONFIG_PROP_INT (object_class, PROP_GRID_SIZE, + "grid-size", + NULL, + _("Size of a grid cell for variable number " + "of composition guides"), + 1, 128, 15, + GIMP_PARAM_STATIC_STRINGS); + + GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_CONSTRAIN_MOVE, + "constrain-move", + NULL, NULL, + FALSE, + GIMP_PARAM_STATIC_STRINGS); + + GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_CONSTRAIN_SCALE, + "constrain-scale", + NULL, NULL, + FALSE, + GIMP_PARAM_STATIC_STRINGS); + + GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_CONSTRAIN_ROTATE, + "constrain-rotate", + NULL, NULL, + FALSE, + GIMP_PARAM_STATIC_STRINGS); + + GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_CONSTRAIN_SHEAR, + "constrain-shear", + NULL, NULL, + TRUE, + GIMP_PARAM_STATIC_STRINGS); + + GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_CONSTRAIN_PERSPECTIVE, + "constrain-perspective", + NULL, NULL, + FALSE, + GIMP_PARAM_STATIC_STRINGS); + + GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_FROMPIVOT_SCALE, + "frompivot-scale", + NULL, NULL, + FALSE, + GIMP_PARAM_STATIC_STRINGS); + + GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_FROMPIVOT_SHEAR, + "frompivot-shear", + NULL, NULL, + FALSE, + GIMP_PARAM_STATIC_STRINGS); + + GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_FROMPIVOT_PERSPECTIVE, + "frompivot-perspective", + NULL, NULL, + FALSE, + GIMP_PARAM_STATIC_STRINGS); + + GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_CORNERSNAP, + "cornersnap", + NULL, NULL, + FALSE, + GIMP_PARAM_STATIC_STRINGS); + + GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_FIXEDPIVOT, + "fixedpivot", + NULL, NULL, + FALSE, + GIMP_PARAM_STATIC_STRINGS); +} + +static void +gimp_transform_grid_options_init (GimpTransformGridOptions *options) +{ +} + +static void +gimp_transform_grid_options_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GimpTransformGridOptions *options = GIMP_TRANSFORM_GRID_OPTIONS (object); + GimpTransformOptions *transform_options = GIMP_TRANSFORM_OPTIONS (object); + + switch (property_id) + { + case PROP_DIRECTION: + transform_options->direction = g_value_get_enum (value); + + /* Expected default for corrective transform_grid is to see the + * original image only. + */ + g_object_set (options, + "show-preview", + transform_options->direction != GIMP_TRANSFORM_BACKWARD, + NULL); + break; + case PROP_SHOW_PREVIEW: + options->show_preview = g_value_get_boolean (value); + break; + case PROP_PREVIEW_OPACITY: + options->preview_opacity = g_value_get_double (value); + break; + case PROP_GRID_TYPE: + options->grid_type = g_value_get_enum (value); + break; + case PROP_GRID_SIZE: + options->grid_size = g_value_get_int (value); + break; + case PROP_CONSTRAIN_MOVE: + options->constrain_move = g_value_get_boolean (value); + break; + case PROP_CONSTRAIN_SCALE: + options->constrain_scale = g_value_get_boolean (value); + break; + case PROP_CONSTRAIN_ROTATE: + options->constrain_rotate = g_value_get_boolean (value); + break; + case PROP_CONSTRAIN_SHEAR: + options->constrain_shear = g_value_get_boolean (value); + break; + case PROP_CONSTRAIN_PERSPECTIVE: + options->constrain_perspective = g_value_get_boolean (value); + break; + case PROP_FROMPIVOT_SCALE: + options->frompivot_scale = g_value_get_boolean (value); + break; + case PROP_FROMPIVOT_SHEAR: + options->frompivot_shear = g_value_get_boolean (value); + break; + case PROP_FROMPIVOT_PERSPECTIVE: + options->frompivot_perspective = g_value_get_boolean (value); + break; + case PROP_CORNERSNAP: + options->cornersnap = g_value_get_boolean (value); + break; + case PROP_FIXEDPIVOT: + options->fixedpivot = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gimp_transform_grid_options_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GimpTransformGridOptions *options = GIMP_TRANSFORM_GRID_OPTIONS (object); + GimpTransformOptions *transform_options = GIMP_TRANSFORM_OPTIONS (object); + + switch (property_id) + { + case PROP_DIRECTION: + g_value_set_enum (value, transform_options->direction); + break; + case PROP_SHOW_PREVIEW: + g_value_set_boolean (value, options->show_preview); + break; + case PROP_PREVIEW_OPACITY: + g_value_set_double (value, options->preview_opacity); + break; + case PROP_GRID_TYPE: + g_value_set_enum (value, options->grid_type); + break; + case PROP_GRID_SIZE: + g_value_set_int (value, options->grid_size); + break; + case PROP_CONSTRAIN_MOVE: + g_value_set_boolean (value, options->constrain_move); + break; + case PROP_CONSTRAIN_SCALE: + g_value_set_boolean (value, options->constrain_scale); + break; + case PROP_CONSTRAIN_ROTATE: + g_value_set_boolean (value, options->constrain_rotate); + break; + case PROP_CONSTRAIN_SHEAR: + g_value_set_boolean (value, options->constrain_shear); + break; + case PROP_CONSTRAIN_PERSPECTIVE: + g_value_set_boolean (value, options->constrain_perspective); + break; + case PROP_FROMPIVOT_SCALE: + g_value_set_boolean (value, options->frompivot_scale); + break; + case PROP_FROMPIVOT_SHEAR: + g_value_set_boolean (value, options->frompivot_shear); + break; + case PROP_FROMPIVOT_PERSPECTIVE: + g_value_set_boolean (value, options->frompivot_perspective); + break; + case PROP_CORNERSNAP: + g_value_set_boolean (value, options->cornersnap); + break; + case PROP_FIXEDPIVOT: + g_value_set_boolean (value, options->fixedpivot); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +/** + * gimp_transform_grid_options_gui: + * @tool_options: a #GimpToolOptions + * + * Build the TransformGrid Tool Options. + * + * Return value: a container holding the transform_grid tool options + **/ +GtkWidget * +gimp_transform_grid_options_gui (GimpToolOptions *tool_options) +{ + GObject *config = G_OBJECT (tool_options); + GtkWidget *vbox; + GtkWidget *frame; + GtkWidget *combo; + GtkWidget *scale; + GtkWidget *grid_box; + GdkModifierType extend_mask = gimp_get_extend_selection_mask (); + GdkModifierType constrain_mask = gimp_get_constrain_behavior_mask (); + + vbox = gimp_transform_options_gui (tool_options, TRUE, TRUE, TRUE); + + /* the preview frame */ + scale = gimp_prop_spin_scale_new (config, "preview-opacity", NULL, + 0.01, 0.1, 0); + gimp_prop_widget_set_factor (scale, 100.0, 0.0, 0.0, 1); + frame = gimp_prop_expanding_frame_new (config, "show-preview", NULL, + scale, NULL); + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + gtk_widget_show (frame); + + /* the guides frame */ + frame = gimp_frame_new (NULL); + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + gtk_widget_show (frame); + + /* the guides type menu */ + combo = gimp_prop_enum_combo_box_new (config, "grid-type", 0, 0); + gimp_int_combo_box_set_label (GIMP_INT_COMBO_BOX (combo), _("Guides")); + g_object_set (combo, "ellipsize", PANGO_ELLIPSIZE_END, NULL); + gtk_frame_set_label_widget (GTK_FRAME (frame), combo); + gtk_widget_show (combo); + + /* the grid density scale */ + scale = gimp_prop_spin_scale_new (config, "grid-size", NULL, + 1.8, 8.0, 0); + gimp_spin_scale_set_label (GIMP_SPIN_SCALE (scale), NULL); + gtk_container_add (GTK_CONTAINER (frame), scale); + + g_object_bind_property_full (config, "grid-type", + scale, "visible", + G_BINDING_SYNC_CREATE, + gimp_transform_grid_options_sync_grid, + NULL, + NULL, NULL); + + if (tool_options->tool_info->tool_type == GIMP_TYPE_ROTATE_TOOL) + { + GtkWidget *button; + gchar *label; + + label = g_strdup_printf (_("15 degrees (%s)"), + gimp_get_mod_string (extend_mask)); + + button = gimp_prop_check_button_new (config, "constrain-rotate", label); + gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); + gtk_widget_show (button); + + gimp_help_set_help_data (button, _("Limit rotation steps to 15 degrees"), + NULL); + + g_free (label); + } + else if (tool_options->tool_info->tool_type == GIMP_TYPE_SCALE_TOOL) + { + GtkWidget *button; + gchar *label; + + label = g_strdup_printf (_("Keep aspect (%s)"), + gimp_get_mod_string (extend_mask)); + + button = gimp_prop_check_button_new (config, "constrain-scale", label); + gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); + gtk_widget_show (button); + + gimp_help_set_help_data (button, _("Keep the original aspect ratio"), + NULL); + + g_free (label); + + label = g_strdup_printf (_("Around center (%s)"), + gimp_get_mod_string (constrain_mask)); + + button = gimp_prop_check_button_new (config, "frompivot-scale", label); + gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); + gtk_widget_show (button); + + gimp_help_set_help_data (button, _("Scale around the center point"), + NULL); + + g_free (label); + } + else if (tool_options->tool_info->tool_type == GIMP_TYPE_UNIFIED_TRANSFORM_TOOL) + { + struct + { + GdkModifierType mod; + gchar *name; + gchar *desc; + gchar *tip; + } + opt_list[] = + { + { extend_mask, NULL, N_("Constrain (%s)") }, + { extend_mask, "constrain-move", N_("Move"), + N_("Constrain movement to 45 degree angles from center (%s)") }, + { extend_mask, "constrain-scale", N_("Scale"), + N_("Maintain aspect ratio when scaling (%s)") }, + { extend_mask, "constrain-rotate", N_("Rotate"), + N_("Constrain rotation to 15 degree increments (%s)") }, + { extend_mask, "constrain-shear", N_("Shear"), + N_("Shear along edge direction only (%s)") }, + { extend_mask, "constrain-perspective", N_("Perspective"), + N_("Constrain perspective handles to move along edges and diagonal (%s)") }, + + { constrain_mask, NULL, + N_("From pivot (%s)") }, + { constrain_mask, "frompivot-scale", N_("Scale"), + N_("Scale from pivot point (%s)") }, + { constrain_mask, "frompivot-shear", N_("Shear"), + N_("Shear opposite edge by same amount (%s)") }, + { constrain_mask, "frompivot-perspective", N_("Perspective"), + N_("Maintain position of pivot while changing perspective (%s)") }, + + { 0, NULL, + N_("Pivot") }, + { extend_mask, "cornersnap", N_("Snap (%s)"), + N_("Snap pivot to corners and center (%s)") }, + { 0, "fixedpivot", N_("Lock"), + N_("Lock pivot position to canvas") }, + }; + + GtkWidget *button; + gchar *label; + gint i; + + frame = NULL; + + for (i = 0; i < G_N_ELEMENTS (opt_list); i++) + { + if (! opt_list[i].name && ! opt_list[i].desc) + { + frame = NULL; + continue; + } + + label = g_strdup_printf (gettext (opt_list[i].desc), + gimp_get_mod_string (opt_list[i].mod)); + + if (opt_list[i].name) + { + button = gimp_prop_check_button_new (config, opt_list[i].name, + label); + + gtk_box_pack_start (GTK_BOX (frame ? grid_box : vbox), + button, FALSE, FALSE, 0); + + gtk_widget_show (button); + + g_free (label); + label = g_strdup_printf (gettext (opt_list[i].tip), + gimp_get_mod_string (opt_list[i].mod)); + + gimp_help_set_help_data (button, label, NULL); + } + else + { + frame = gimp_frame_new (label); + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + gtk_widget_show (frame); + + grid_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2); + gtk_container_add (GTK_CONTAINER (frame), grid_box); + gtk_widget_show (grid_box); + } + + g_free (label); + } + } + + return vbox; +} + +gboolean +gimp_transform_grid_options_show_preview (GimpTransformGridOptions *options) +{ + GimpTransformOptions *transform_options; + + g_return_val_if_fail (GIMP_IS_TRANSFORM_GRID_OPTIONS (options), FALSE); + + transform_options = GIMP_TRANSFORM_OPTIONS (options); + + return (options->show_preview && + transform_options->type == GIMP_TRANSFORM_TYPE_LAYER); +} + + +/* private functions */ + +static gboolean +gimp_transform_grid_options_sync_grid (GBinding *binding, + const GValue *source_value, + GValue *target_value, + gpointer user_data) +{ + GimpGuidesType type = g_value_get_enum (source_value); + + g_value_set_boolean (target_value, + type == GIMP_GUIDES_N_LINES || + type == GIMP_GUIDES_SPACING); + + return TRUE; +} + diff --git a/app/tools/gimptransformgridoptions.h b/app/tools/gimptransformgridoptions.h new file mode 100644 index 0000000000..94664d349b --- /dev/null +++ b/app/tools/gimptransformgridoptions.h @@ -0,0 +1,69 @@ +/* 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_TRANSFORM_GRID_OPTIONS_H__ +#define __GIMP_TRANSFORM_GRID_OPTIONS_H__ + + +#include "gimptransformoptions.h" + + +#define GIMP_TYPE_TRANSFORM_GRID_OPTIONS (gimp_transform_grid_options_get_type ()) +#define GIMP_TRANSFORM_GRID_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_TRANSFORM_GRID_OPTIONS, GimpTransformGridOptions)) +#define GIMP_TRANSFORM_GRID_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_TRANSFORM_GRID_OPTIONS, GimpTransformGridOptionsClass)) +#define GIMP_IS_TRANSFORM_GRID_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_TRANSFORM_GRID_OPTIONS)) +#define GIMP_IS_TRANSFORM_GRID_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_TRANSFORM_GRID_OPTIONS)) +#define GIMP_TRANSFORM_GRID_OPTIONS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_TRANSFORM_GRID_OPTIONS, GimpTransformGridOptionsClass)) + + +typedef struct _GimpTransformGridOptions GimpTransformGridOptions; +typedef struct _GimpTransformGridOptionsClass GimpTransformGridOptionsClass; + +struct _GimpTransformGridOptions +{ + GimpTransformOptions parent_instance; + + gboolean show_preview; + gdouble preview_opacity; + GimpGuidesType grid_type; + gint grid_size; + gboolean constrain_move; + gboolean constrain_scale; + gboolean constrain_rotate; + gboolean constrain_shear; + gboolean constrain_perspective; + gboolean frompivot_scale; + gboolean frompivot_shear; + gboolean frompivot_perspective; + gboolean cornersnap; + gboolean fixedpivot; +}; + +struct _GimpTransformGridOptionsClass +{ + GimpTransformOptionsClass parent_class; +}; + + +GType gimp_transform_grid_options_get_type (void) G_GNUC_CONST; + +GtkWidget * gimp_transform_grid_options_gui (GimpToolOptions *tool_options); + +gboolean gimp_transform_grid_options_show_preview (GimpTransformGridOptions *options); + + +#endif /* __GIMP_TRANSFORM_GRID_OPTIONS_H__ */ diff --git a/app/tools/gimptransformgridtool.c b/app/tools/gimptransformgridtool.c new file mode 100644 index 0000000000..b30da58678 --- /dev/null +++ b/app/tools/gimptransformgridtool.c @@ -0,0 +1,1214 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995-2001 Spencer Kimball, Peter Mattis, and others + * + * 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 + +#include "libgimpmath/gimpmath.h" +#include "libgimpwidgets/gimpwidgets.h" + +#include "tools-types.h" + +#include "core/gimp.h" +#include "core/gimpboundary.h" +#include "core/gimperror.h" +#include "core/gimpimage.h" +#include "core/gimpimage-undo.h" +#include "core/gimpimage-undo-push.h" +#include "core/gimplayer.h" +#include "core/gimplayermask.h" +#include "core/gimpprojection.h" +#include "core/gimptoolinfo.h" + +#include "vectors/gimpvectors.h" +#include "vectors/gimpstroke.h" + +#include "widgets/gimpwidgets-utils.h" + +#include "display/gimpcanvasitem.h" +#include "display/gimpdisplay.h" +#include "display/gimptoolgui.h" +#include "display/gimptoolwidget.h" + +#include "gimptoolcontrol.h" +#include "gimptransformgridoptions.h" +#include "gimptransformgridtool.h" +#include "gimptransformgridtoolundo.h" +#include "gimptransformoptions.h" + +#include "gimp-intl.h" + + +#define RESPONSE_RESET 1 + + +static void gimp_transform_grid_tool_finalize (GObject *object); + +static gboolean gimp_transform_grid_tool_initialize (GimpTool *tool, + GimpDisplay *display, + GError **error); +static void gimp_transform_grid_tool_control (GimpTool *tool, + GimpToolAction action, + GimpDisplay *display); +static void gimp_transform_grid_tool_button_press (GimpTool *tool, + const GimpCoords *coords, + guint32 time, + GdkModifierType state, + GimpButtonPressType press_type, + GimpDisplay *display); +static void gimp_transform_grid_tool_button_release (GimpTool *tool, + const GimpCoords *coords, + guint32 time, + GdkModifierType state, + GimpButtonReleaseType release_type, + GimpDisplay *display); +static void gimp_transform_grid_tool_motion (GimpTool *tool, + const GimpCoords *coords, + guint32 time, + GdkModifierType state, + GimpDisplay *display); +static void gimp_transform_grid_tool_modifier_key (GimpTool *tool, + GdkModifierType key, + gboolean press, + GdkModifierType state, + GimpDisplay *display); +static void gimp_transform_grid_tool_cursor_update (GimpTool *tool, + const GimpCoords *coords, + GdkModifierType state, + GimpDisplay *display); +static const gchar * gimp_transform_grid_tool_can_undo (GimpTool *tool, + GimpDisplay *display); +static const gchar * gimp_transform_grid_tool_can_redo (GimpTool *tool, + GimpDisplay *display); +static gboolean gimp_transform_grid_tool_undo (GimpTool *tool, + GimpDisplay *display); +static gboolean gimp_transform_grid_tool_redo (GimpTool *tool, + GimpDisplay *display); +static void gimp_transform_grid_tool_options_notify (GimpTool *tool, + GimpToolOptions *options, + const GParamSpec *pspec); + +static void gimp_transform_grid_tool_draw (GimpDrawTool *draw_tool); + +static void gimp_transform_grid_tool_transform_recalc_matrix (GimpTransformTool *tr_tool); +static GeglBuffer * gimp_transform_grid_tool_transform (GimpTransformTool *tr_tool, + GimpItem *item, + GeglBuffer *orig_buffer, + gint orig_offset_x, + gint orig_offset_y, + GimpColorProfile **buffer_profile, + gint *new_offset_x, + gint *new_offset_y); + +static GeglBuffer * gimp_transform_grid_tool_real_transform (GimpTransformGridTool *tg_tool, + GimpItem *item, + GeglBuffer *orig_buffer, + gint orig_offset_x, + gint orig_offset_y, + GimpColorProfile **buffer_profile, + gint *new_offset_x, + gint *new_offset_y); + +static void gimp_transform_grid_tool_widget_changed (GimpToolWidget *widget, + GimpTransformGridTool *tg_tool); +static void gimp_transform_grid_tool_widget_response (GimpToolWidget *widget, + gint response_id, + GimpTransformGridTool *tg_tool); + +static void gimp_transform_grid_tool_halt (GimpTransformGridTool *tg_tool); +static void gimp_transform_grid_tool_commit (GimpTransformGridTool *tg_tool); + +static void gimp_transform_grid_tool_dialog (GimpTransformGridTool *tg_tool); +static void gimp_transform_grid_tool_dialog_update (GimpTransformGridTool *tg_tool); +static void gimp_transform_grid_tool_prepare (GimpTransformGridTool *tg_tool, + GimpDisplay *display); +static GimpToolWidget * gimp_transform_grid_tool_get_widget (GimpTransformGridTool *tg_tool); + +static void gimp_transform_grid_tool_response (GimpToolGui *gui, + gint response_id, + GimpTransformGridTool *tg_tool); + +static void gimp_transform_grid_tool_update_sensitivity (GimpTransformGridTool *tg_tool); +static void gimp_transform_grid_tool_hide_active_item (GimpTransformGridTool *tg_tool, + GimpItem *item); +static void gimp_transform_grid_tool_show_active_item (GimpTransformGridTool *tg_tool); + +static TransInfo * trans_info_new (void); +static void trans_info_free (TransInfo *info); + + +G_DEFINE_TYPE (GimpTransformGridTool, gimp_transform_grid_tool, GIMP_TYPE_TRANSFORM_TOOL) + +#define parent_class gimp_transform_grid_tool_parent_class + + +static void +gimp_transform_grid_tool_class_init (GimpTransformGridToolClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass); + GimpDrawToolClass *draw_class = GIMP_DRAW_TOOL_CLASS (klass); + GimpTransformToolClass *tr_class = GIMP_TRANSFORM_TOOL_CLASS (klass); + + object_class->finalize = gimp_transform_grid_tool_finalize; + + tool_class->initialize = gimp_transform_grid_tool_initialize; + tool_class->control = gimp_transform_grid_tool_control; + tool_class->button_press = gimp_transform_grid_tool_button_press; + tool_class->button_release = gimp_transform_grid_tool_button_release; + tool_class->motion = gimp_transform_grid_tool_motion; + tool_class->modifier_key = gimp_transform_grid_tool_modifier_key; + tool_class->cursor_update = gimp_transform_grid_tool_cursor_update; + tool_class->can_undo = gimp_transform_grid_tool_can_undo; + tool_class->can_redo = gimp_transform_grid_tool_can_redo; + tool_class->undo = gimp_transform_grid_tool_undo; + tool_class->redo = gimp_transform_grid_tool_redo; + tool_class->options_notify = gimp_transform_grid_tool_options_notify; + + draw_class->draw = gimp_transform_grid_tool_draw; + + tr_class->recalc_matrix = gimp_transform_grid_tool_transform_recalc_matrix; + tr_class->transform = gimp_transform_grid_tool_transform; + + klass->dialog = NULL; + klass->dialog_update = NULL; + klass->prepare = NULL; + klass->recalc_matrix = NULL; + klass->transform = gimp_transform_grid_tool_real_transform; + + klass->ok_button_label = _("_Transform"); +} + +static void +gimp_transform_grid_tool_init (GimpTransformGridTool *tg_tool) +{ + GimpTool *tool = GIMP_TOOL (tg_tool); + + gimp_tool_control_set_scroll_lock (tool->control, TRUE); + gimp_tool_control_set_preserve (tool->control, FALSE); + gimp_tool_control_set_dirty_mask (tool->control, + GIMP_DIRTY_IMAGE_SIZE | + GIMP_DIRTY_DRAWABLE | + GIMP_DIRTY_SELECTION | + GIMP_DIRTY_ACTIVE_DRAWABLE); + gimp_tool_control_set_active_modifiers (tool->control, + GIMP_TOOL_ACTIVE_MODIFIERS_SAME); + gimp_tool_control_set_precision (tool->control, + GIMP_CURSOR_PRECISION_SUBPIXEL); + gimp_tool_control_set_cursor (tool->control, + GIMP_CURSOR_CROSSHAIR_SMALL); + gimp_tool_control_set_action_opacity (tool->control, + "tools/tools-transform-preview-opacity-set"); + + tg_tool->strokes = g_ptr_array_new (); +} + +static void +gimp_transform_grid_tool_finalize (GObject *object) +{ + GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (object); + + g_clear_object (&tg_tool->gui); + g_clear_pointer (&tg_tool->strokes, g_ptr_array_unref); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static gboolean +gimp_transform_grid_tool_initialize (GimpTool *tool, + GimpDisplay *display, + GError **error) +{ + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool); + GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (tool); + GimpImage *image = gimp_display_get_image (display); + GimpDrawable *drawable = gimp_image_get_active_drawable (image); + GimpItem *item; + + item = gimp_transform_tool_get_active_item (tr_tool, display, FALSE, error); + + if (! item) + return FALSE; + + tool->display = display; + tool->drawable = drawable; + + /* Initialize the transform_grid tool dialog */ + if (! tg_tool->gui) + gimp_transform_grid_tool_dialog (tg_tool); + + /* Find the transform bounds for some tools (like scale, + * perspective) that actually need the bounds for initializing + */ + gimp_transform_tool_bounds (tr_tool, display); + + /* Initialize the tool-specific trans_info, and adjust the tool dialog */ + gimp_transform_grid_tool_prepare (tg_tool, display); + + /* Recalculate the transform_grid tool */ + gimp_transform_grid_tool_recalc_matrix (tg_tool, NULL); + + /* Get the on-canvas gui */ + tg_tool->widget = gimp_transform_grid_tool_get_widget (tg_tool); + + gimp_transform_grid_tool_hide_active_item (tg_tool, item); + + /* start drawing the bounding box and handles... */ + gimp_draw_tool_start (GIMP_DRAW_TOOL (tool), display); + + /* Initialize undo and redo lists */ + tg_tool->undo_list = g_list_prepend (NULL, trans_info_new ()); + tg_tool->redo_list = NULL; + tg_tool->old_trans_info = g_list_last (tg_tool->undo_list)->data; + tg_tool->prev_trans_info = g_list_first (tg_tool->undo_list)->data; + gimp_transform_grid_tool_update_sensitivity (tg_tool); + + /* Save the current transformation info */ + memcpy (tg_tool->prev_trans_info, tg_tool->trans_info, + sizeof (TransInfo)); + + return TRUE; +} + +static void +gimp_transform_grid_tool_control (GimpTool *tool, + GimpToolAction action, + GimpDisplay *display) +{ + GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (tool); + + switch (action) + { + case GIMP_TOOL_ACTION_PAUSE: + break; + + case GIMP_TOOL_ACTION_RESUME: + gimp_transform_grid_tool_recalc_matrix (tg_tool, tg_tool->widget); + break; + + case GIMP_TOOL_ACTION_HALT: + gimp_transform_grid_tool_halt (tg_tool); + break; + + case GIMP_TOOL_ACTION_COMMIT: + if (tool->display) + gimp_transform_grid_tool_commit (tg_tool); + break; + } + + GIMP_TOOL_CLASS (parent_class)->control (tool, action, display); +} + +static void +gimp_transform_grid_tool_button_press (GimpTool *tool, + const GimpCoords *coords, + guint32 time, + GdkModifierType state, + GimpButtonPressType press_type, + GimpDisplay *display) +{ + GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (tool); + + if (tg_tool->widget) + { + gimp_tool_widget_hover (tg_tool->widget, coords, state, TRUE); + + if (gimp_tool_widget_button_press (tg_tool->widget, coords, time, state, + press_type)) + { + tg_tool->grab_widget = tg_tool->widget; + } + } + + gimp_tool_control_activate (tool->control); +} + +static void +gimp_transform_grid_tool_button_release (GimpTool *tool, + const GimpCoords *coords, + guint32 time, + GdkModifierType state, + GimpButtonReleaseType release_type, + GimpDisplay *display) +{ + GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (tool); + + gimp_tool_control_halt (tool->control); + + if (tg_tool->grab_widget) + { + gimp_tool_widget_button_release (tg_tool->grab_widget, + coords, time, state, release_type); + tg_tool->grab_widget = NULL; + } + + if (release_type != GIMP_BUTTON_RELEASE_CANCEL) + { + /* This hack is to perform the flip immediately with the flip tool */ + if (! tg_tool->widget) + { + gimp_transform_grid_tool_response (NULL, GTK_RESPONSE_OK, tg_tool); + return; + } + + /* We're done with an interaction, save it on the undo list */ + gimp_transform_grid_tool_push_internal_undo (tg_tool); + } + else + { + /* Restore the last saved state */ + memcpy (tg_tool->trans_info, tg_tool->prev_trans_info, + sizeof (TransInfo)); + + /* recalculate the tool's transformation matrix */ + gimp_transform_grid_tool_recalc_matrix (tg_tool, tg_tool->widget); + } +} + +static void +gimp_transform_grid_tool_motion (GimpTool *tool, + const GimpCoords *coords, + guint32 time, + GdkModifierType state, + GimpDisplay *display) +{ + GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (tool); + + if (tg_tool->grab_widget) + { + gimp_tool_widget_motion (tg_tool->grab_widget, coords, time, state); + } +} + +static void +gimp_transform_grid_tool_modifier_key (GimpTool *tool, + GdkModifierType key, + gboolean press, + GdkModifierType state, + GimpDisplay *display) +{ + GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (tool); + + if (tg_tool->widget) + { + GIMP_TOOL_CLASS (parent_class)->modifier_key (tool, key, press, + state, display); + } + else + { + GimpTransformGridOptions *options = GIMP_TRANSFORM_GRID_TOOL_GET_OPTIONS (tool); + + if (key == gimp_get_constrain_behavior_mask ()) + { + g_object_set (options, + "frompivot-scale", ! options->frompivot_scale, + "frompivot-shear", ! options->frompivot_shear, + "frompivot-perspective", ! options->frompivot_perspective, + NULL); + } + else if (key == gimp_get_extend_selection_mask ()) + { + g_object_set (options, + "cornersnap", ! options->cornersnap, + "constrain-move", ! options->constrain_move, + "constrain-scale", ! options->constrain_scale, + "constrain-rotate", ! options->constrain_rotate, + "constrain-shear", ! options->constrain_shear, + "constrain-perspective", ! options->constrain_perspective, + NULL); + } + } +} + +static void +gimp_transform_grid_tool_cursor_update (GimpTool *tool, + const GimpCoords *coords, + GdkModifierType state, + GimpDisplay *display) +{ + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool); + + if (! gimp_transform_tool_get_active_item (tr_tool, display, TRUE, NULL)) + { + gimp_tool_set_cursor (tool, display, + gimp_tool_control_get_cursor (tool->control), + gimp_tool_control_get_tool_cursor (tool->control), + GIMP_CURSOR_MODIFIER_BAD); + return; + } + + GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display); +} + +static const gchar * +gimp_transform_grid_tool_can_undo (GimpTool *tool, + GimpDisplay *display) +{ + GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (tool); + + if (! tg_tool->undo_list || ! tg_tool->undo_list->next) + return NULL; + + return _("Transform Step"); +} + +static const gchar * +gimp_transform_grid_tool_can_redo (GimpTool *tool, + GimpDisplay *display) +{ + GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (tool); + + if (! tg_tool->redo_list) + return NULL; + + return _("Transform Step"); +} + +static gboolean +gimp_transform_grid_tool_undo (GimpTool *tool, + GimpDisplay *display) +{ + GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (tool); + GList *item; + + item = g_list_next (tg_tool->undo_list); + + /* Move prev_trans_info from undo_list to redo_list */ + tg_tool->redo_list = g_list_prepend (tg_tool->redo_list, + tg_tool->prev_trans_info); + tg_tool->undo_list = g_list_remove (tg_tool->undo_list, + tg_tool->prev_trans_info); + + tg_tool->prev_trans_info = item->data; + + /* Restore the previous transformation info */ + memcpy (tg_tool->trans_info, tg_tool->prev_trans_info, + sizeof (TransInfo)); + + /* recalculate the tool's transformation matrix */ + gimp_transform_grid_tool_recalc_matrix (tg_tool, tg_tool->widget); + + return TRUE; +} + +static gboolean +gimp_transform_grid_tool_redo (GimpTool *tool, + GimpDisplay *display) +{ + GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (tool); + GList *item; + + item = tg_tool->redo_list; + + /* Move prev_trans_info from redo_list to undo_list */ + tg_tool->prev_trans_info = item->data; + + tg_tool->undo_list = g_list_prepend (tg_tool->undo_list, + tg_tool->prev_trans_info); + tg_tool->redo_list = g_list_remove (tg_tool->redo_list, + tg_tool->prev_trans_info); + + /* Restore the previous transformation info */ + memcpy (tg_tool->trans_info, tg_tool->prev_trans_info, + sizeof (TransInfo)); + + /* recalculate the tool's transformation matrix */ + gimp_transform_grid_tool_recalc_matrix (tg_tool, tg_tool->widget); + + return TRUE; +} + +static void +gimp_transform_grid_tool_options_notify (GimpTool *tool, + GimpToolOptions *options, + const GParamSpec *pspec) +{ + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool); + GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (tool); + GimpTransformGridOptions *tg_options = GIMP_TRANSFORM_GRID_OPTIONS (options); + + GIMP_TOOL_CLASS (parent_class)->options_notify (tool, options, pspec); + + if (! strcmp (pspec->name, "type")) + { + gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, tool->display); + return; + } + + if (! tg_tool->widget) + return; + + if (! strcmp (pspec->name, "direction")) + { + /* recalculate the tool's transformation matrix */ + gimp_transform_grid_tool_recalc_matrix (tg_tool, tg_tool->widget); + } + else if (! strcmp (pspec->name, "show-preview")) + { + if (tg_tool->preview) + { + GimpDisplay *display; + GimpItem *item; + gboolean show_preview; + + show_preview = gimp_transform_grid_options_show_preview (tg_options) && + tr_tool->transform_valid; + + gimp_canvas_item_set_visible (tg_tool->preview, show_preview); + + display = tool->display; + item = gimp_transform_tool_get_active_item (tr_tool, + display, TRUE, NULL); + if (item) + { + if (show_preview) + gimp_transform_grid_tool_hide_active_item (tg_tool, item); + else + gimp_transform_grid_tool_show_active_item (tg_tool); + } + } + } + else if (g_str_has_prefix (pspec->name, "constrain-") || + g_str_has_prefix (pspec->name, "frompivot-") || + ! strcmp (pspec->name, "fixedpivot") || + ! strcmp (pspec->name, "cornersnap")) + { + gimp_transform_grid_tool_dialog_update (tg_tool); + } +} + +static void +gimp_transform_grid_tool_draw (GimpDrawTool *draw_tool) +{ + GimpTool *tool = GIMP_TOOL (draw_tool); + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (draw_tool); + GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (draw_tool); + GimpTransformGridOptions *options = GIMP_TRANSFORM_GRID_TOOL_GET_OPTIONS (tool); + GimpTransformOptions *tr_options = GIMP_TRANSFORM_OPTIONS (options); + GimpImage *image = gimp_display_get_image (tool->display); + GimpMatrix3 matrix = tr_tool->transform; + GimpCanvasItem *item; + + if (tr_options->direction == GIMP_TRANSFORM_BACKWARD) + gimp_matrix3_invert (&matrix); + + if (tg_tool->widget) + { + gboolean show_preview = gimp_transform_grid_options_show_preview (options) && + tr_tool->transform_valid; + + tg_tool->preview = + gimp_draw_tool_add_transform_preview (draw_tool, + tool->drawable, + &matrix, + tr_tool->x1, + tr_tool->y1, + tr_tool->x2, + tr_tool->y2); + g_object_add_weak_pointer (G_OBJECT (tg_tool->preview), + (gpointer) &tg_tool->preview); + + gimp_canvas_item_set_visible (tg_tool->preview, show_preview); + + g_object_bind_property (G_OBJECT (options), "preview-opacity", + G_OBJECT (tg_tool->preview), "opacity", + G_BINDING_SYNC_CREATE | + G_BINDING_BIDIRECTIONAL); + + GIMP_DRAW_TOOL_CLASS (parent_class)->draw (draw_tool); + } + + if (tr_options->type == GIMP_TRANSFORM_TYPE_SELECTION) + { + const GimpBoundSeg *segs_in; + const GimpBoundSeg *segs_out; + gint n_segs_in; + gint n_segs_out; + + gimp_channel_boundary (gimp_image_get_mask (image), + &segs_in, &segs_out, + &n_segs_in, &n_segs_out, + 0, 0, 0, 0); + + if (segs_in) + { + tg_tool->boundary_in = + gimp_draw_tool_add_boundary (draw_tool, + segs_in, n_segs_in, + &matrix, + 0, 0); + g_object_add_weak_pointer (G_OBJECT (tg_tool->boundary_in), + (gpointer) &tg_tool->boundary_in); + + gimp_canvas_item_set_visible (tg_tool->boundary_in, + tr_tool->transform_valid); + } + + if (segs_out) + { + tg_tool->boundary_out = + gimp_draw_tool_add_boundary (draw_tool, + segs_out, n_segs_out, + &matrix, + 0, 0); + g_object_add_weak_pointer (G_OBJECT (tg_tool->boundary_in), + (gpointer) &tg_tool->boundary_out); + + gimp_canvas_item_set_visible (tg_tool->boundary_out, + tr_tool->transform_valid); + } + } + else if (tr_options->type == GIMP_TRANSFORM_TYPE_PATH) + { + GimpVectors *vectors = gimp_image_get_active_vectors (image); + + if (vectors) + { + GimpStroke *stroke = NULL; + + while ((stroke = gimp_vectors_stroke_get_next (vectors, stroke))) + { + GArray *coords; + gboolean closed; + + coords = gimp_stroke_interpolate (stroke, 1.0, &closed); + + if (coords && coords->len) + { + item = + gimp_draw_tool_add_strokes (draw_tool, + &g_array_index (coords, + GimpCoords, 0), + coords->len, &matrix, FALSE); + + g_ptr_array_add (tg_tool->strokes, item); + g_object_weak_ref (G_OBJECT (item), + (GWeakNotify) g_ptr_array_remove, + tg_tool->strokes); + + gimp_canvas_item_set_visible (item, tr_tool->transform_valid); + } + + if (coords) + g_array_free (coords, TRUE); + } + } + } +} + +static void +gimp_transform_grid_tool_transform_recalc_matrix (GimpTransformTool *tr_tool) +{ + GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (tr_tool); + + gimp_transform_grid_tool_recalc_matrix (tg_tool, NULL); +} + +static GeglBuffer * +gimp_transform_grid_tool_transform (GimpTransformTool *tr_tool, + GimpItem *item, + GeglBuffer *orig_buffer, + gint orig_offset_x, + gint orig_offset_y, + GimpColorProfile **buffer_profile, + gint *new_offset_x, + gint *new_offset_y) +{ + GimpTool *tool = GIMP_TOOL (tr_tool); + GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (tr_tool); + GimpDisplay *display = tool->display; + GimpImage *image = gimp_display_get_image (display); + GeglBuffer *new_buffer; + + /* Send the request for the transformation to the tool... + */ + new_buffer = + GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->transform (tg_tool, + item, + orig_buffer, + orig_offset_x, + orig_offset_y, + buffer_profile, + new_offset_x, + new_offset_y); + + gimp_image_undo_push (image, GIMP_TYPE_TRANSFORM_GRID_TOOL_UNDO, + GIMP_UNDO_TRANSFORM_GRID, NULL, + 0, + "transform-tool", tg_tool, + NULL); + + return new_buffer; +} + +static GeglBuffer * +gimp_transform_grid_tool_real_transform (GimpTransformGridTool *tg_tool, + GimpItem *item, + GeglBuffer *orig_buffer, + gint orig_offset_x, + gint orig_offset_y, + GimpColorProfile **buffer_profile, + gint *new_offset_x, + gint *new_offset_y) +{ + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + + return GIMP_TRANSFORM_TOOL_CLASS (parent_class)->transform (tr_tool, + item, + orig_buffer, + orig_offset_x, + orig_offset_y, + buffer_profile, + new_offset_x, + new_offset_y); +} + +static void +gimp_transform_grid_tool_widget_changed (GimpToolWidget *widget, + GimpTransformGridTool *tg_tool) +{ + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + GimpTransformGridOptions *options = GIMP_TRANSFORM_GRID_TOOL_GET_OPTIONS (tg_tool); + GimpTransformOptions *tr_options = GIMP_TRANSFORM_OPTIONS (options); + GimpMatrix3 matrix = tr_tool->transform; + gint i; + + if (tr_options->direction == GIMP_TRANSFORM_BACKWARD) + gimp_matrix3_invert (&matrix); + + if (tg_tool->preview) + { + gboolean show_preview = gimp_transform_grid_options_show_preview (options) && + tr_tool->transform_valid; + + gimp_canvas_item_begin_change (tg_tool->preview); + gimp_canvas_item_set_visible (tg_tool->preview, show_preview); + g_object_set (tg_tool->preview, + "transform", &matrix, + NULL); + gimp_canvas_item_end_change (tg_tool->preview); + } + + if (tg_tool->boundary_in) + { + gimp_canvas_item_begin_change (tg_tool->boundary_in); + gimp_canvas_item_set_visible (tg_tool->boundary_in, + tr_tool->transform_valid); + g_object_set (tg_tool->boundary_in, + "transform", &matrix, + NULL); + gimp_canvas_item_end_change (tg_tool->boundary_in); + } + + if (tg_tool->boundary_out) + { + gimp_canvas_item_begin_change (tg_tool->boundary_out); + gimp_canvas_item_set_visible (tg_tool->boundary_out, + tr_tool->transform_valid); + g_object_set (tg_tool->boundary_out, + "transform", &matrix, + NULL); + gimp_canvas_item_end_change (tg_tool->boundary_out); + } + + for (i = 0; i < tg_tool->strokes->len; i++) + { + GimpCanvasItem *item = g_ptr_array_index (tg_tool->strokes, i); + + gimp_canvas_item_begin_change (item); + gimp_canvas_item_set_visible (item, tr_tool->transform_valid); + g_object_set (item, + "transform", &matrix, + NULL); + gimp_canvas_item_end_change (item); + } +} + +static void +gimp_transform_grid_tool_widget_response (GimpToolWidget *widget, + gint response_id, + GimpTransformGridTool *tg_tool) +{ + switch (response_id) + { + case GIMP_TOOL_WIDGET_RESPONSE_CONFIRM: + gimp_transform_grid_tool_response (NULL, GTK_RESPONSE_OK, tg_tool); + break; + + case GIMP_TOOL_WIDGET_RESPONSE_CANCEL: + gimp_transform_grid_tool_response (NULL, GTK_RESPONSE_CANCEL, tg_tool); + break; + + case GIMP_TOOL_WIDGET_RESPONSE_RESET: + gimp_transform_grid_tool_response (NULL, RESPONSE_RESET, tg_tool); + break; + } +} + +static void +gimp_transform_grid_tool_halt (GimpTransformGridTool *tg_tool) +{ + GimpTool *tool = GIMP_TOOL (tg_tool); + + if (gimp_draw_tool_is_active (GIMP_DRAW_TOOL (tg_tool))) + gimp_draw_tool_stop (GIMP_DRAW_TOOL (tg_tool)); + + gimp_draw_tool_set_widget (GIMP_DRAW_TOOL (tg_tool), NULL); + g_clear_object (&tg_tool->widget); + + if (tg_tool->gui) + gimp_tool_gui_hide (tg_tool->gui); + + if (tg_tool->redo_list) + { + g_list_free_full (tg_tool->redo_list, (GDestroyNotify) trans_info_free); + tg_tool->redo_list = NULL; + } + + if (tg_tool->undo_list) + { + g_list_free_full (tg_tool->undo_list, (GDestroyNotify) trans_info_free); + tg_tool->undo_list = NULL; + tg_tool->prev_trans_info = NULL; + } + + gimp_transform_grid_tool_show_active_item (tg_tool); + + tool->display = NULL; + tool->drawable = NULL; +} + +static void +gimp_transform_grid_tool_commit (GimpTransformGridTool *tg_tool) +{ + GimpTool *tool = GIMP_TOOL (tg_tool); + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + GimpDisplay *display = tool->display; + + /* undraw the tool before we muck around with the transform matrix */ + gimp_draw_tool_stop (GIMP_DRAW_TOOL (tg_tool)); + + gimp_transform_tool_transform (tr_tool, display); +} + +static void +gimp_transform_grid_tool_dialog (GimpTransformGridTool *tg_tool) +{ + GimpTool *tool = GIMP_TOOL (tg_tool); + GimpToolInfo *tool_info = tool->tool_info; + GimpDisplayShell *shell; + const gchar *ok_button_label; + + if (! GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->dialog) + return; + + g_return_if_fail (tool->display != NULL); + + shell = gimp_display_get_shell (tool->display); + + ok_button_label = GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->ok_button_label; + + tg_tool->gui = gimp_tool_gui_new (tool_info, + NULL, NULL, NULL, NULL, + gimp_widget_get_monitor (GTK_WIDGET (shell)), + TRUE, + + _("_Reset"), RESPONSE_RESET, + _("_Cancel"), GTK_RESPONSE_CANCEL, + ok_button_label, GTK_RESPONSE_OK, + + NULL); + + gimp_tool_gui_set_auto_overlay (tg_tool->gui, TRUE); + gimp_tool_gui_set_default_response (tg_tool->gui, GTK_RESPONSE_OK); + + gimp_tool_gui_set_alternative_button_order (tg_tool->gui, + RESPONSE_RESET, + GTK_RESPONSE_OK, + GTK_RESPONSE_CANCEL, + -1); + + g_signal_connect (tg_tool->gui, "response", + G_CALLBACK (gimp_transform_grid_tool_response), + tg_tool); + + GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->dialog (tg_tool); +} + +static void +gimp_transform_grid_tool_dialog_update (GimpTransformGridTool *tg_tool) +{ + if (tg_tool->gui && + GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->dialog_update) + { + GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->dialog_update (tg_tool); + } +} + +static void +gimp_transform_grid_tool_prepare (GimpTransformGridTool *tg_tool, + GimpDisplay *display) +{ + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + + if (tg_tool->gui) + { + GimpItem *item = gimp_transform_tool_get_active_item (tr_tool, + display, TRUE, NULL); + + g_return_if_fail (item != NULL); + + gimp_tool_gui_set_shell (tg_tool->gui, gimp_display_get_shell (display)); + gimp_tool_gui_set_viewable (tg_tool->gui, GIMP_VIEWABLE (item)); + } + + if (GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->prepare) + GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->prepare (tg_tool); +} + +static GimpToolWidget * +gimp_transform_grid_tool_get_widget (GimpTransformGridTool *tg_tool) +{ + static const gchar *properties[] = + { + "constrain-move", + "constrain-scale", + "constrain-rotate", + "constrain-shear", + "constrain-perspective", + "frompivot-scale", + "frompivot-shear", + "frompivot-perspective", + "cornersnap", + "fixedpivot" + }; + + GimpToolWidget *widget = NULL; + + if (GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->get_widget) + { + GimpTransformGridOptions *options = GIMP_TRANSFORM_GRID_TOOL_GET_OPTIONS (tg_tool); + gint i; + + widget = GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->get_widget (tg_tool); + + gimp_draw_tool_set_widget (GIMP_DRAW_TOOL (tg_tool), widget); + + g_object_bind_property (G_OBJECT (options), "grid-type", + G_OBJECT (widget), "guide-type", + G_BINDING_SYNC_CREATE | + G_BINDING_BIDIRECTIONAL); + g_object_bind_property (G_OBJECT (options), "grid-size", + G_OBJECT (widget), "n-guides", + G_BINDING_SYNC_CREATE | + G_BINDING_BIDIRECTIONAL); + + for (i = 0; i < G_N_ELEMENTS (properties); i++) + g_object_bind_property (G_OBJECT (options), properties[i], + G_OBJECT (widget), properties[i], + G_BINDING_SYNC_CREATE | + G_BINDING_BIDIRECTIONAL); + + g_signal_connect (widget, "changed", + G_CALLBACK (gimp_transform_grid_tool_widget_changed), + tg_tool); + g_signal_connect (widget, "response", + G_CALLBACK (gimp_transform_grid_tool_widget_response), + tg_tool); + } + + return widget; +} + +static void +gimp_transform_grid_tool_response (GimpToolGui *gui, + gint response_id, + GimpTransformGridTool *tg_tool) +{ + GimpTool *tool = GIMP_TOOL (tg_tool); + GimpDisplay *display = tool->display; + + switch (response_id) + { + case RESPONSE_RESET: + /* Move all undo events to redo, and pop off the first + * one as that's the current one, which always sits on + * the undo_list + */ + tg_tool->redo_list = + g_list_remove (g_list_concat (g_list_reverse (tg_tool->undo_list), + tg_tool->redo_list), + tg_tool->old_trans_info); + tg_tool->prev_trans_info = tg_tool->old_trans_info; + tg_tool->undo_list = g_list_prepend (NULL, + tg_tool->prev_trans_info); + + gimp_transform_grid_tool_update_sensitivity (tg_tool); + + /* Restore the previous transformation info */ + memcpy (tg_tool->trans_info, tg_tool->prev_trans_info, + sizeof (TransInfo)); + + /* recalculate the tool's transformtion matrix */ + gimp_transform_grid_tool_recalc_matrix (tg_tool, tg_tool->widget); + + /* update the undo actions / menu items */ + gimp_image_flush (gimp_display_get_image (display)); + break; + + case GTK_RESPONSE_OK: + g_return_if_fail (display != NULL); + gimp_tool_control (tool, GIMP_TOOL_ACTION_COMMIT, display); + break; + + default: + gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display); + + /* update the undo actions / menu items */ + if (display) + gimp_image_flush (gimp_display_get_image (display)); + break; + } +} + +static void +gimp_transform_grid_tool_update_sensitivity (GimpTransformGridTool *tg_tool) +{ + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + + if (! tg_tool->gui) + return; + + gimp_tool_gui_set_response_sensitive (tg_tool->gui, GTK_RESPONSE_OK, + tr_tool->transform_valid); + gimp_tool_gui_set_response_sensitive (tg_tool->gui, RESPONSE_RESET, + g_list_next (tg_tool->undo_list) != NULL); +} + +static void +gimp_transform_grid_tool_hide_active_item (GimpTransformGridTool *tg_tool, + GimpItem *item) +{ + GimpTransformGridOptions *options = GIMP_TRANSFORM_GRID_TOOL_GET_OPTIONS (tg_tool); + GimpTransformOptions *tr_options = GIMP_TRANSFORM_OPTIONS (options); + GimpDisplay *display = GIMP_TOOL (tg_tool)->display; + GimpImage *image = gimp_display_get_image (display); + + /* hide only complete layers and channels, not layer masks */ + if (tr_options->type == GIMP_TRANSFORM_TYPE_LAYER && + options->show_preview && + GIMP_IS_DRAWABLE (item) && + ! GIMP_IS_LAYER_MASK (item) && + gimp_item_get_visible (item) && + gimp_channel_is_empty (gimp_image_get_mask (image))) + { + tg_tool->hidden_item = item; + gimp_item_set_visible (item, FALSE, FALSE); + + gimp_projection_flush (gimp_image_get_projection (image)); + } +} + +static void +gimp_transform_grid_tool_show_active_item (GimpTransformGridTool *tg_tool) +{ + if (tg_tool->hidden_item) + { + GimpDisplay *display = GIMP_TOOL (tg_tool)->display; + GimpImage *image = gimp_display_get_image (display); + + gimp_item_set_visible (tg_tool->hidden_item, TRUE, FALSE); + tg_tool->hidden_item = NULL; + + gimp_image_flush (image); + } +} + +static TransInfo * +trans_info_new (void) +{ + return g_slice_new0 (TransInfo); +} + +static void +trans_info_free (TransInfo *info) +{ + g_slice_free (TransInfo, info); +} + +void +gimp_transform_grid_tool_recalc_matrix (GimpTransformGridTool *tg_tool, + GimpToolWidget *widget) +{ + GimpTool *tool; + GimpTransformTool *tr_tool; + + g_return_if_fail (GIMP_IS_TRANSFORM_GRID_TOOL (tg_tool)); + g_return_if_fail (widget == NULL || GIMP_IS_TOOL_WIDGET (widget)); + + tool = GIMP_TOOL (tg_tool); + tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + + gimp_transform_tool_bounds (tr_tool, tool->display); + + if (GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->recalc_matrix) + { + GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->recalc_matrix (tg_tool, + widget); + } + + gimp_transform_grid_tool_dialog_update (tg_tool); + gimp_transform_grid_tool_update_sensitivity (tg_tool); + + if (tg_tool->gui) + gimp_tool_gui_show (tg_tool->gui); +} + +void +gimp_transform_grid_tool_push_internal_undo (GimpTransformGridTool *tg_tool) +{ + g_return_if_fail (GIMP_IS_TRANSFORM_GRID_TOOL (tg_tool)); + g_return_if_fail (tg_tool->prev_trans_info != NULL); + + /* push current state on the undo list and set this state as the + * current state, but avoid doing this if there were no changes + */ + if (memcmp (tg_tool->prev_trans_info, tg_tool->trans_info, + sizeof (TransInfo)) != 0) + { + tg_tool->prev_trans_info = trans_info_new (); + memcpy (tg_tool->prev_trans_info, tg_tool->trans_info, + sizeof (TransInfo)); + + tg_tool->undo_list = g_list_prepend (tg_tool->undo_list, + tg_tool->prev_trans_info); + + /* If we undid anything and started interacting, we have to + * discard the redo history + */ + g_list_free_full (tg_tool->redo_list, (GDestroyNotify) trans_info_free); + tg_tool->redo_list = NULL; + + gimp_transform_grid_tool_update_sensitivity (tg_tool); + + /* update the undo actions / menu items */ + gimp_image_flush (gimp_display_get_image (GIMP_TOOL (tg_tool)->display)); + } +} diff --git a/app/tools/gimptransformgridtool.h b/app/tools/gimptransformgridtool.h new file mode 100644 index 0000000000..da383ddeec --- /dev/null +++ b/app/tools/gimptransformgridtool.h @@ -0,0 +1,103 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995-2001 Spencer Kimball, Peter Mattis, and others + * + * 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_TRANSFORM_GRID_TOOL_H__ +#define __GIMP_TRANSFORM_GRID_TOOL_H__ + + +#include "gimptransformtool.h" + + +/* This is not the number of items in the enum above, but the max size + * of the enums at the top of each transformation tool, stored in + * trans_info and related + */ +#define TRANS_INFO_SIZE 17 + +typedef gdouble TransInfo[TRANS_INFO_SIZE]; + + +#define GIMP_TYPE_TRANSFORM_GRID_TOOL (gimp_transform_grid_tool_get_type ()) +#define GIMP_TRANSFORM_GRID_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_TRANSFORM_GRID_TOOL, GimpTransformGridTool)) +#define GIMP_TRANSFORM_GRID_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_TRANSFORM_GRID_TOOL, GimpTransformGridToolClass)) +#define GIMP_IS_TRANSFORM_GRID_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_TRANSFORM_GRID_TOOL)) +#define GIMP_IS_TRANSFORM_GRID_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_TRANSFORM_GRID_TOOL)) +#define GIMP_TRANSFORM_GRID_TOOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_TRANSFORM_GRID_TOOL, GimpTransformGridToolClass)) + +#define GIMP_TRANSFORM_GRID_TOOL_GET_OPTIONS(t) (GIMP_TRANSFORM_GRID_OPTIONS (gimp_tool_get_options (GIMP_TOOL (t)))) + + +typedef struct _GimpTransformGridToolClass GimpTransformGridToolClass; + +struct _GimpTransformGridTool +{ + GimpTransformTool parent_instance; + + TransInfo trans_info; /* transformation info */ + TransInfo *old_trans_info; /* for resetting everything */ + TransInfo *prev_trans_info; /* the current finished state */ + GList *undo_list; /* list of all states, + head is current == prev_trans_info, + tail is original == old_trans_info */ + GList *redo_list; /* list of all undone states, + NULL when nothing undone */ + + GimpItem *hidden_item; /* the item that was hidden during + the transform */ + + GimpToolWidget *widget; + GimpToolWidget *grab_widget; + GimpCanvasItem *preview; + GimpCanvasItem *boundary_in; + GimpCanvasItem *boundary_out; + GPtrArray *strokes; + + GimpToolGui *gui; +}; + +struct _GimpTransformGridToolClass +{ + GimpTransformToolClass parent_class; + + /* virtual functions */ + void (* dialog) (GimpTransformGridTool *tg_tool); + void (* dialog_update) (GimpTransformGridTool *tg_tool); + void (* prepare) (GimpTransformGridTool *tg_tool); + GimpToolWidget * (* get_widget) (GimpTransformGridTool *tg_tool); + void (* recalc_matrix) (GimpTransformGridTool *tg_tool, + GimpToolWidget *widget); + GeglBuffer * (* transform) (GimpTransformGridTool *tg_tool, + GimpItem *item, + GeglBuffer *orig_buffer, + gint orig_offset_x, + gint orig_offset_y, + GimpColorProfile **buffer_profile, + gint *new_offset_x, + gint *new_offset_y); + + const gchar *ok_button_label; +}; + + +GType gimp_transform_grid_tool_get_type (void) G_GNUC_CONST; + +void gimp_transform_grid_tool_recalc_matrix (GimpTransformGridTool *tg_tool, + GimpToolWidget *widget); +void gimp_transform_grid_tool_push_internal_undo (GimpTransformGridTool *tg_tool); + + +#endif /* __GIMP_TRANSFORM_GRID_TOOL_H__ */ diff --git a/app/tools/gimptransformgridtoolundo.c b/app/tools/gimptransformgridtoolundo.c new file mode 100644 index 0000000000..3c9490c889 --- /dev/null +++ b/app/tools/gimptransformgridtoolundo.c @@ -0,0 +1,220 @@ +/* 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 "tools-types.h" + +#include "gimptoolcontrol.h" +#include "gimptransformgridtool.h" +#include "gimptransformgridtoolundo.h" + + +enum +{ + PROP_0, + PROP_TRANSFORM_TOOL +}; + + +static void gimp_transform_grid_tool_undo_constructed (GObject *object); +static void gimp_transform_grid_tool_undo_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void gimp_transform_grid_tool_undo_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); + +static void gimp_transform_grid_tool_undo_pop (GimpUndo *undo, + GimpUndoMode undo_mode, + GimpUndoAccumulator *accum); +static void gimp_transform_grid_tool_undo_free (GimpUndo *undo, + GimpUndoMode undo_mode); + + +G_DEFINE_TYPE (GimpTransformGridToolUndo, gimp_transform_grid_tool_undo, GIMP_TYPE_UNDO) + +#define parent_class gimp_transform_grid_tool_undo_parent_class + + +static void +gimp_transform_grid_tool_undo_class_init (GimpTransformGridToolUndoClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GimpUndoClass *undo_class = GIMP_UNDO_CLASS (klass); + + object_class->constructed = gimp_transform_grid_tool_undo_constructed; + object_class->set_property = gimp_transform_grid_tool_undo_set_property; + object_class->get_property = gimp_transform_grid_tool_undo_get_property; + + undo_class->pop = gimp_transform_grid_tool_undo_pop; + undo_class->free = gimp_transform_grid_tool_undo_free; + + g_object_class_install_property (object_class, PROP_TRANSFORM_TOOL, + g_param_spec_object ("transform-tool", + NULL, NULL, + GIMP_TYPE_TRANSFORM_GRID_TOOL, + GIMP_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); +} + +static void +gimp_transform_grid_tool_undo_init (GimpTransformGridToolUndo *undo) +{ +} + +static void +gimp_transform_grid_tool_undo_constructed (GObject *object) +{ + GimpTransformGridToolUndo *tg_tool_undo = GIMP_TRANSFORM_GRID_TOOL_UNDO (object); + GimpTransformGridTool *tg_tool; + gint i; + + G_OBJECT_CLASS (parent_class)->constructed (object); + + gimp_assert (GIMP_IS_TRANSFORM_GRID_TOOL (tg_tool_undo->tg_tool)); + + tg_tool = tg_tool_undo->tg_tool; + + for (i = 0; i < TRANS_INFO_SIZE; i++) + tg_tool_undo->trans_info[i] = (*tg_tool->old_trans_info)[i]; + +#if 0 + if (tg_tool->original) + tg_tool_undo->original = tile_manager_ref (tg_tool->original); +#endif + + g_object_add_weak_pointer (G_OBJECT (tg_tool_undo->tg_tool), + (gpointer) &tg_tool_undo->tg_tool); +} + +static void +gimp_transform_grid_tool_undo_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GimpTransformGridToolUndo *tg_tool_undo = GIMP_TRANSFORM_GRID_TOOL_UNDO (object); + + switch (property_id) + { + case PROP_TRANSFORM_TOOL: + tg_tool_undo->tg_tool = g_value_get_object (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gimp_transform_grid_tool_undo_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GimpTransformGridToolUndo *tg_tool_undo = GIMP_TRANSFORM_GRID_TOOL_UNDO (object); + + switch (property_id) + { + case PROP_TRANSFORM_TOOL: + g_value_set_object (value, tg_tool_undo->tg_tool); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gimp_transform_grid_tool_undo_pop (GimpUndo *undo, + GimpUndoMode undo_mode, + GimpUndoAccumulator *accum) +{ + GimpTransformGridToolUndo *tg_tool_undo = GIMP_TRANSFORM_GRID_TOOL_UNDO (undo); + + GIMP_UNDO_CLASS (parent_class)->pop (undo, undo_mode, accum); + + if (tg_tool_undo->tg_tool) + { + GimpTransformGridTool *tg_tool; +#if 0 + TileManager *temp; +#endif + gdouble d; + gint i; + + tg_tool = tg_tool_undo->tg_tool; + + /* swap the transformation information arrays */ + for (i = 0; i < TRANS_INFO_SIZE; i++) + { + d = tg_tool_undo->trans_info[i]; + tg_tool_undo->trans_info[i] = tg_tool->trans_info[i]; + tg_tool->trans_info[i] = d; + } + +#if 0 + /* swap the original buffer--the source buffer for repeated transform_grids + */ + temp = tg_tool_undo->original; + tg_tool_undo->original = tg_tool->original; + tg_tool->original = temp; +#endif + +#if 0 + /* If we're re-implementing the first transform_grid, reactivate tool */ + if (undo_mode == GIMP_UNDO_MODE_REDO && tg_tool->original) + { + gimp_tool_control_activate (GIMP_TOOL (tg_tool)->control); + + gimp_draw_tool_resume (GIMP_DRAW_TOOL (tg_tool)); + } +#endif + } + } + +static void +gimp_transform_grid_tool_undo_free (GimpUndo *undo, + GimpUndoMode undo_mode) +{ + GimpTransformGridToolUndo *tg_tool_undo = GIMP_TRANSFORM_GRID_TOOL_UNDO (undo); + + if (tg_tool_undo->tg_tool) + { + g_object_remove_weak_pointer (G_OBJECT (tg_tool_undo->tg_tool), + (gpointer) &tg_tool_undo->tg_tool); + tg_tool_undo->tg_tool = NULL; + } + +#if 0 + if (tg_tool_undo->original) + { + tile_manager_unref (tg_tool_undo->original); + tg_tool_undo->original = NULL; + } +#endif + + GIMP_UNDO_CLASS (parent_class)->free (undo, undo_mode); +} diff --git a/app/tools/gimptransformgridtoolundo.h b/app/tools/gimptransformgridtoolundo.h new file mode 100644 index 0000000000..d4fd99ab79 --- /dev/null +++ b/app/tools/gimptransformgridtoolundo.h @@ -0,0 +1,56 @@ +/* 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_TRANSFORM_GRID_TOOL_UNDO_H__ +#define __GIMP_TRANSFORM_GRID_TOOL_UNDO_H__ + + +#include "core/gimpundo.h" + + +#define GIMP_TYPE_TRANSFORM_GRID_TOOL_UNDO (gimp_transform_grid_tool_undo_get_type ()) +#define GIMP_TRANSFORM_GRID_TOOL_UNDO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_TRANSFORM_GRID_TOOL_UNDO, GimpTransformGridToolUndo)) +#define GIMP_TRANSFORM_GRID_TOOL_UNDO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_TRANSFORM_GRID_TOOL_UNDO, GimpTransformGridToolUndoClass)) +#define GIMP_IS_TRANSFORM_GRID_TOOL_UNDO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_TRANSFORM_GRID_TOOL_UNDO)) +#define GIMP_IS_TRANSFORM_GRID_TOOL_UNDO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_TRANSFORM_GRID_TOOL_UNDO)) +#define GIMP_TRANSFORM_GRID_TOOL_UNDO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_TRANSFORM_GRID_TOOL_UNDO, GimpTransformGridToolUndoClass)) + + +typedef struct _GimpTransformGridToolUndo GimpTransformGridToolUndo; +typedef struct _GimpTransformGridToolUndoClass GimpTransformGridToolUndoClass; + +struct _GimpTransformGridToolUndo +{ + GimpUndo parent_instance; + + GimpTransformGridTool *tg_tool; + TransInfo trans_info; +#if 0 + TileManager *original; +#endif +}; + +struct _GimpTransformGridToolUndoClass +{ + GimpUndoClass parent_class; +}; + + +GType gimp_transform_grid_tool_undo_get_type (void) G_GNUC_CONST; + + +#endif /* __GIMP_TRANSFORM_GRID_TOOL_UNDO_H__ */ diff --git a/app/tools/gimptransformoptions.c b/app/tools/gimptransformoptions.c index 5fd7a1e05f..a0366ee2f3 100644 --- a/app/tools/gimptransformoptions.c +++ b/app/tools/gimptransformoptions.c @@ -31,12 +31,8 @@ #include "core/gimptoolinfo.h" #include "widgets/gimppropwidgets.h" -#include "widgets/gimpspinscale.h" #include "widgets/gimpwidgets-utils.h" -#include "gimprotatetool.h" -#include "gimpscaletool.h" -#include "gimpunifiedtransformtool.h" #include "gimptooloptions-gui.h" #include "gimptransformoptions.h" @@ -49,21 +45,7 @@ enum PROP_TYPE, PROP_DIRECTION, PROP_INTERPOLATION, - PROP_CLIP, - PROP_SHOW_PREVIEW, - PROP_PREVIEW_OPACITY, - PROP_GRID_TYPE, - PROP_GRID_SIZE, - PROP_CONSTRAIN_MOVE, - PROP_CONSTRAIN_SCALE, - PROP_CONSTRAIN_ROTATE, - PROP_CONSTRAIN_SHEAR, - PROP_CONSTRAIN_PERSPECTIVE, - PROP_FROMPIVOT_SCALE, - PROP_FROMPIVOT_SHEAR, - PROP_FROMPIVOT_PERSPECTIVE, - PROP_CORNERSNAP, - PROP_FIXEDPIVOT, + PROP_CLIP }; @@ -80,12 +62,6 @@ static void gimp_transform_options_get_property (GObject *object, static void gimp_transform_options_reset (GimpConfig *config); -static gboolean gimp_transform_options_sync_grid (GBinding *binding, - const GValue *source_value, - GValue *target_value, - gpointer user_data); - - G_DEFINE_TYPE_WITH_CODE (GimpTransformOptions, gimp_transform_options, GIMP_TYPE_TOOL_OPTIONS, G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONFIG, @@ -134,96 +110,6 @@ gimp_transform_options_class_init (GimpTransformOptionsClass *klass) GIMP_TYPE_TRANSFORM_RESIZE, GIMP_TRANSFORM_RESIZE_ADJUST, GIMP_PARAM_STATIC_STRINGS); - - GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_PREVIEW, - "show-preview", - _("Show image preview"), - _("Show a preview of the transformed image"), - TRUE, - GIMP_PARAM_STATIC_STRINGS); - - GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_PREVIEW_OPACITY, - "preview-opacity", - _("Image opacity"), - _("Opacity of the preview image"), - 0.0, 1.0, 1.0, - GIMP_PARAM_STATIC_STRINGS); - - GIMP_CONFIG_PROP_ENUM (object_class, PROP_GRID_TYPE, - "grid-type", - _("Guides"), - _("Composition guides such as rule of thirds"), - GIMP_TYPE_GUIDES_TYPE, - GIMP_GUIDES_NONE, - GIMP_PARAM_STATIC_STRINGS); - - GIMP_CONFIG_PROP_INT (object_class, PROP_GRID_SIZE, - "grid-size", - NULL, - _("Size of a grid cell for variable number " - "of composition guides"), - 1, 128, 15, - GIMP_PARAM_STATIC_STRINGS); - - GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_CONSTRAIN_MOVE, - "constrain-move", - NULL, NULL, - FALSE, - GIMP_PARAM_STATIC_STRINGS); - - GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_CONSTRAIN_SCALE, - "constrain-scale", - NULL, NULL, - FALSE, - GIMP_PARAM_STATIC_STRINGS); - - GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_CONSTRAIN_ROTATE, - "constrain-rotate", - NULL, NULL, - FALSE, - GIMP_PARAM_STATIC_STRINGS); - - GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_CONSTRAIN_SHEAR, - "constrain-shear", - NULL, NULL, - TRUE, - GIMP_PARAM_STATIC_STRINGS); - - GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_CONSTRAIN_PERSPECTIVE, - "constrain-perspective", - NULL, NULL, - FALSE, - GIMP_PARAM_STATIC_STRINGS); - - GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_FROMPIVOT_SCALE, - "frompivot-scale", - NULL, NULL, - FALSE, - GIMP_PARAM_STATIC_STRINGS); - - GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_FROMPIVOT_SHEAR, - "frompivot-shear", - NULL, NULL, - FALSE, - GIMP_PARAM_STATIC_STRINGS); - - GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_FROMPIVOT_PERSPECTIVE, - "frompivot-perspective", - NULL, NULL, - FALSE, - GIMP_PARAM_STATIC_STRINGS); - - GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_CORNERSNAP, - "cornersnap", - NULL, NULL, - FALSE, - GIMP_PARAM_STATIC_STRINGS); - - GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_FIXEDPIVOT, - "fixedpivot", - NULL, NULL, - FALSE, - GIMP_PARAM_STATIC_STRINGS); } static void @@ -254,14 +140,6 @@ gimp_transform_options_set_property (GObject *object, break; case PROP_DIRECTION: options->direction = g_value_get_enum (value); - - /* Expected default for corrective transform is to see the - * original image only. - */ - g_object_set (options, - "show-preview", - options->direction != GIMP_TRANSFORM_BACKWARD, - NULL); break; case PROP_INTERPOLATION: options->interpolation = g_value_get_enum (value); @@ -269,48 +147,6 @@ gimp_transform_options_set_property (GObject *object, case PROP_CLIP: options->clip = g_value_get_enum (value); break; - case PROP_SHOW_PREVIEW: - options->show_preview = g_value_get_boolean (value); - break; - case PROP_PREVIEW_OPACITY: - options->preview_opacity = g_value_get_double (value); - break; - case PROP_GRID_TYPE: - options->grid_type = g_value_get_enum (value); - break; - case PROP_GRID_SIZE: - options->grid_size = g_value_get_int (value); - break; - case PROP_CONSTRAIN_MOVE: - options->constrain_move = g_value_get_boolean (value); - break; - case PROP_CONSTRAIN_SCALE: - options->constrain_scale = g_value_get_boolean (value); - break; - case PROP_CONSTRAIN_ROTATE: - options->constrain_rotate = g_value_get_boolean (value); - break; - case PROP_CONSTRAIN_SHEAR: - options->constrain_shear = g_value_get_boolean (value); - break; - case PROP_CONSTRAIN_PERSPECTIVE: - options->constrain_perspective = g_value_get_boolean (value); - break; - case PROP_FROMPIVOT_SCALE: - options->frompivot_scale = g_value_get_boolean (value); - break; - case PROP_FROMPIVOT_SHEAR: - options->frompivot_shear = g_value_get_boolean (value); - break; - case PROP_FROMPIVOT_PERSPECTIVE: - options->frompivot_perspective = g_value_get_boolean (value); - break; - case PROP_CORNERSNAP: - options->cornersnap = g_value_get_boolean (value); - break; - case PROP_FIXEDPIVOT: - options->fixedpivot = g_value_get_boolean (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -339,48 +175,6 @@ gimp_transform_options_get_property (GObject *object, case PROP_CLIP: g_value_set_enum (value, options->clip); break; - case PROP_SHOW_PREVIEW: - g_value_set_boolean (value, options->show_preview); - break; - case PROP_PREVIEW_OPACITY: - g_value_set_double (value, options->preview_opacity); - break; - case PROP_GRID_TYPE: - g_value_set_enum (value, options->grid_type); - break; - case PROP_GRID_SIZE: - g_value_set_int (value, options->grid_size); - break; - case PROP_CONSTRAIN_MOVE: - g_value_set_boolean (value, options->constrain_move); - break; - case PROP_CONSTRAIN_SCALE: - g_value_set_boolean (value, options->constrain_scale); - break; - case PROP_CONSTRAIN_ROTATE: - g_value_set_boolean (value, options->constrain_rotate); - break; - case PROP_CONSTRAIN_SHEAR: - g_value_set_boolean (value, options->constrain_shear); - break; - case PROP_CONSTRAIN_PERSPECTIVE: - g_value_set_boolean (value, options->constrain_perspective); - break; - case PROP_FROMPIVOT_SCALE: - g_value_set_boolean (value, options->frompivot_scale); - break; - case PROP_FROMPIVOT_SHEAR: - g_value_set_boolean (value, options->frompivot_shear); - break; - case PROP_FROMPIVOT_PERSPECTIVE: - g_value_set_boolean (value, options->frompivot_perspective); - break; - case PROP_CORNERSNAP: - g_value_set_boolean (value, options->cornersnap); - break; - case PROP_FIXEDPIVOT: - g_value_set_boolean (value, options->fixedpivot); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -405,14 +199,20 @@ gimp_transform_options_reset (GimpConfig *config) /** * gimp_transform_options_gui: - * @tool_options: a #GimpToolOptions + * @tool_options: a #GimpToolOptions + * @direction: whether to show the direction frame + * @interpolation: whether to show the interpolation menu + * @clipping: whether to show the clipping menu * * Build the Transform Tool Options. * * Return value: a container holding the transform tool options **/ GtkWidget * -gimp_transform_options_gui (GimpToolOptions *tool_options) +gimp_transform_options_gui (GimpToolOptions *tool_options, + gboolean direction, + gboolean interpolation, + gboolean clipping) { GObject *config = G_OBJECT (tool_options); GtkWidget *vbox = gimp_tool_options_gui (tool_options); @@ -421,10 +221,6 @@ gimp_transform_options_gui (GimpToolOptions *tool_options) GtkWidget *label; GtkWidget *frame; GtkWidget *combo; - GtkWidget *scale; - GtkWidget *grid_box; - GdkModifierType extend_mask = gimp_get_extend_selection_mask (); - GdkModifierType constrain_mask = gimp_get_constrain_behavior_mask (); hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); @@ -438,219 +234,33 @@ gimp_transform_options_gui (GimpToolOptions *tool_options) gtk_box_pack_start (GTK_BOX (hbox), box, FALSE, FALSE, 0); gtk_widget_show (box); - frame = gimp_prop_enum_radio_frame_new (config, "direction", NULL, - 0, 0); - gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); - gtk_widget_show (frame); + if (direction) + { + frame = gimp_prop_enum_radio_frame_new (config, "direction", NULL, + 0, 0); + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + gtk_widget_show (frame); + } /* the interpolation menu */ - combo = gimp_prop_enum_combo_box_new (config, "interpolation", 0, 0); - gimp_int_combo_box_set_label (GIMP_INT_COMBO_BOX (combo), _("Interpolation")); - g_object_set (combo, "ellipsize", PANGO_ELLIPSIZE_END, NULL); - gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, FALSE, 0); - gtk_widget_show (combo); + if (interpolation) + { + combo = gimp_prop_enum_combo_box_new (config, "interpolation", 0, 0); + gimp_int_combo_box_set_label (GIMP_INT_COMBO_BOX (combo), _("Interpolation")); + g_object_set (combo, "ellipsize", PANGO_ELLIPSIZE_END, NULL); + gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, FALSE, 0); + gtk_widget_show (combo); + } /* the clipping menu */ - combo = gimp_prop_enum_combo_box_new (config, "clip", 0, 0); - gimp_int_combo_box_set_label (GIMP_INT_COMBO_BOX (combo), _("Clipping")); - g_object_set (combo, "ellipsize", PANGO_ELLIPSIZE_END, NULL); - gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, FALSE, 0); - gtk_widget_show (combo); - - /* the preview frame */ - scale = gimp_prop_spin_scale_new (config, "preview-opacity", NULL, - 0.01, 0.1, 0); - gimp_prop_widget_set_factor (scale, 100.0, 0.0, 0.0, 1); - frame = gimp_prop_expanding_frame_new (config, "show-preview", NULL, - scale, NULL); - gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); - gtk_widget_show (frame); - - /* the guides frame */ - frame = gimp_frame_new (NULL); - gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); - gtk_widget_show (frame); - - /* the guides type menu */ - combo = gimp_prop_enum_combo_box_new (config, "grid-type", 0, 0); - gimp_int_combo_box_set_label (GIMP_INT_COMBO_BOX (combo), _("Guides")); - g_object_set (combo, "ellipsize", PANGO_ELLIPSIZE_END, NULL); - gtk_frame_set_label_widget (GTK_FRAME (frame), combo); - gtk_widget_show (combo); - - /* the grid density scale */ - scale = gimp_prop_spin_scale_new (config, "grid-size", NULL, - 1.8, 8.0, 0); - gimp_spin_scale_set_label (GIMP_SPIN_SCALE (scale), NULL); - gtk_container_add (GTK_CONTAINER (frame), scale); - - g_object_bind_property_full (config, "grid-type", - scale, "visible", - G_BINDING_SYNC_CREATE, - gimp_transform_options_sync_grid, - NULL, - NULL, NULL); - - if (tool_options->tool_info->tool_type == GIMP_TYPE_ROTATE_TOOL) + if (clipping) { - GtkWidget *button; - gchar *label; - - label = g_strdup_printf (_("15 degrees (%s)"), - gimp_get_mod_string (extend_mask)); - - button = gimp_prop_check_button_new (config, "constrain-rotate", label); - gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); - gtk_widget_show (button); - - gimp_help_set_help_data (button, _("Limit rotation steps to 15 degrees"), - NULL); - - g_free (label); - } - else if (tool_options->tool_info->tool_type == GIMP_TYPE_SCALE_TOOL) - { - GtkWidget *button; - gchar *label; - - label = g_strdup_printf (_("Keep aspect (%s)"), - gimp_get_mod_string (extend_mask)); - - button = gimp_prop_check_button_new (config, "constrain-scale", label); - gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); - gtk_widget_show (button); - - gimp_help_set_help_data (button, _("Keep the original aspect ratio"), - NULL); - - g_free (label); - - label = g_strdup_printf (_("Around center (%s)"), - gimp_get_mod_string (constrain_mask)); - - button = gimp_prop_check_button_new (config, "frompivot-scale", label); - gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); - gtk_widget_show (button); - - gimp_help_set_help_data (button, _("Scale around the center point"), - NULL); - - g_free (label); - } - else if (tool_options->tool_info->tool_type == GIMP_TYPE_UNIFIED_TRANSFORM_TOOL) - { - struct - { - GdkModifierType mod; - gchar *name; - gchar *desc; - gchar *tip; - } - opt_list[] = - { - { extend_mask, NULL, N_("Constrain (%s)") }, - { extend_mask, "constrain-move", N_("Move"), - N_("Constrain movement to 45 degree angles from center (%s)") }, - { extend_mask, "constrain-scale", N_("Scale"), - N_("Maintain aspect ratio when scaling (%s)") }, - { extend_mask, "constrain-rotate", N_("Rotate"), - N_("Constrain rotation to 15 degree increments (%s)") }, - { extend_mask, "constrain-shear", N_("Shear"), - N_("Shear along edge direction only (%s)") }, - { extend_mask, "constrain-perspective", N_("Perspective"), - N_("Constrain perspective handles to move along edges and diagonal (%s)") }, - - { constrain_mask, NULL, - N_("From pivot (%s)") }, - { constrain_mask, "frompivot-scale", N_("Scale"), - N_("Scale from pivot point (%s)") }, - { constrain_mask, "frompivot-shear", N_("Shear"), - N_("Shear opposite edge by same amount (%s)") }, - { constrain_mask, "frompivot-perspective", N_("Perspective"), - N_("Maintain position of pivot while changing perspective (%s)") }, - - { 0, NULL, - N_("Pivot") }, - { extend_mask, "cornersnap", N_("Snap (%s)"), - N_("Snap pivot to corners and center (%s)") }, - { 0, "fixedpivot", N_("Lock"), - N_("Lock pivot position to canvas") }, - }; - - GtkWidget *button; - gchar *label; - gint i; - - frame = NULL; - - for (i = 0; i < G_N_ELEMENTS (opt_list); i++) - { - if (! opt_list[i].name && ! opt_list[i].desc) - { - frame = NULL; - continue; - } - - label = g_strdup_printf (gettext (opt_list[i].desc), - gimp_get_mod_string (opt_list[i].mod)); - - if (opt_list[i].name) - { - button = gimp_prop_check_button_new (config, opt_list[i].name, - label); - - gtk_box_pack_start (GTK_BOX (frame ? grid_box : vbox), - button, FALSE, FALSE, 0); - - gtk_widget_show (button); - - g_free (label); - label = g_strdup_printf (gettext (opt_list[i].tip), - gimp_get_mod_string (opt_list[i].mod)); - - gimp_help_set_help_data (button, label, NULL); - } - else - { - frame = gimp_frame_new (label); - gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); - gtk_widget_show (frame); - - grid_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2); - gtk_container_add (GTK_CONTAINER (frame), grid_box); - gtk_widget_show (grid_box); - } - - g_free (label); - } + combo = gimp_prop_enum_combo_box_new (config, "clip", 0, 0); + gimp_int_combo_box_set_label (GIMP_INT_COMBO_BOX (combo), _("Clipping")); + g_object_set (combo, "ellipsize", PANGO_ELLIPSIZE_END, NULL); + gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, FALSE, 0); + gtk_widget_show (combo); } return vbox; } - -gboolean -gimp_transform_options_show_preview (GimpTransformOptions *options) -{ - g_return_val_if_fail (GIMP_IS_TRANSFORM_OPTIONS (options), FALSE); - - return (options->show_preview && - options->type == GIMP_TRANSFORM_TYPE_LAYER); -} - - -/* private functions */ - -static gboolean -gimp_transform_options_sync_grid (GBinding *binding, - const GValue *source_value, - GValue *target_value, - gpointer user_data) -{ - GimpGuidesType type = g_value_get_enum (source_value); - - g_value_set_boolean (target_value, - type == GIMP_GUIDES_N_LINES || - type == GIMP_GUIDES_SPACING); - - return TRUE; -} diff --git a/app/tools/gimptransformoptions.h b/app/tools/gimptransformoptions.h index 94c6b63c01..86cbdff396 100644 --- a/app/tools/gimptransformoptions.h +++ b/app/tools/gimptransformoptions.h @@ -35,26 +35,12 @@ typedef struct _GimpTransformOptionsClass GimpTransformOptionsClass; struct _GimpTransformOptions { - GimpToolOptions parent_instance; + GimpToolOptions parent_instance; - GimpTransformType type; - GimpTransformDirection direction; - GimpInterpolationType interpolation; - GimpTransformResize clip; - gboolean show_preview; - gdouble preview_opacity; - GimpGuidesType grid_type; - gint grid_size; - gboolean constrain_move; - gboolean constrain_scale; - gboolean constrain_rotate; - gboolean constrain_shear; - gboolean constrain_perspective; - gboolean frompivot_scale; - gboolean frompivot_shear; - gboolean frompivot_perspective; - gboolean cornersnap; - gboolean fixedpivot; + GimpTransformType type; + GimpTransformDirection direction; + GimpInterpolationType interpolation; + GimpTransformResize clip; }; struct _GimpTransformOptionsClass @@ -63,11 +49,12 @@ struct _GimpTransformOptionsClass }; -GType gimp_transform_options_get_type (void) G_GNUC_CONST; +GType gimp_transform_options_get_type (void) G_GNUC_CONST; -GtkWidget * gimp_transform_options_gui (GimpToolOptions *tool_options); - -gboolean gimp_transform_options_show_preview (GimpTransformOptions *options); +GtkWidget * gimp_transform_options_gui (GimpToolOptions *tool_options, + gboolean direction, + gboolean interpolation, + gboolean clipping); #endif /* __GIMP_TRANSFORM_OPTIONS_H__ */ diff --git a/app/tools/gimptransformtool.c b/app/tools/gimptransformtool.c index 1871b8aaa4..2b50e4594e 100644 --- a/app/tools/gimptransformtool.c +++ b/app/tools/gimptransformtool.c @@ -19,141 +19,40 @@ #include #include -#include #include "libgimpmath/gimpmath.h" -#include "libgimpwidgets/gimpwidgets.h" #include "tools-types.h" #include "core/gimp.h" -#include "core/gimpboundary.h" #include "core/gimpdrawable-transform.h" #include "core/gimperror.h" #include "core/gimpimage.h" #include "core/gimpimage-undo.h" -#include "core/gimpimage-undo-push.h" #include "core/gimpitem-linked.h" #include "core/gimplayer.h" #include "core/gimplayermask.h" #include "core/gimpprogress.h" -#include "core/gimpprojection.h" -#include "core/gimptoolinfo.h" #include "vectors/gimpvectors.h" -#include "vectors/gimpstroke.h" -#include "widgets/gimpwidgets-utils.h" - -#include "display/gimpcanvasitem.h" #include "display/gimpdisplay.h" -#include "display/gimptoolgui.h" -#include "display/gimptoolwidget.h" #include "gimptoolcontrol.h" #include "gimptransformoptions.h" #include "gimptransformtool.h" -#include "gimptransformtoolundo.h" #include "gimp-intl.h" -#define RESPONSE_RESET 1 - - -static void gimp_transform_tool_finalize (GObject *object); - -static gboolean gimp_transform_tool_initialize (GimpTool *tool, - GimpDisplay *display, - GError **error); -static void gimp_transform_tool_control (GimpTool *tool, - GimpToolAction action, - GimpDisplay *display); -static void gimp_transform_tool_button_press (GimpTool *tool, - const GimpCoords *coords, - guint32 time, - GdkModifierType state, - GimpButtonPressType press_type, - GimpDisplay *display); -static void gimp_transform_tool_button_release (GimpTool *tool, - const GimpCoords *coords, - guint32 time, - GdkModifierType state, - GimpButtonReleaseType release_type, - GimpDisplay *display); -static void gimp_transform_tool_motion (GimpTool *tool, - const GimpCoords *coords, - guint32 time, - GdkModifierType state, - GimpDisplay *display); -static void gimp_transform_tool_modifier_key (GimpTool *tool, - GdkModifierType key, - gboolean press, - GdkModifierType state, - GimpDisplay *display); -static void gimp_transform_tool_cursor_update (GimpTool *tool, - const GimpCoords *coords, - GdkModifierType state, - GimpDisplay *display); -static const gchar * gimp_transform_tool_can_undo (GimpTool *tool, - GimpDisplay *display); -static const gchar * gimp_transform_tool_can_redo (GimpTool *tool, - GimpDisplay *display); -static gboolean gimp_transform_tool_undo (GimpTool *tool, - GimpDisplay *display); -static gboolean gimp_transform_tool_redo (GimpTool *tool, - GimpDisplay *display); -static void gimp_transform_tool_options_notify (GimpTool *tool, - GimpToolOptions *options, - const GParamSpec *pspec); - -static void gimp_transform_tool_draw (GimpDrawTool *draw_tool); - -static GeglBuffer * - gimp_transform_tool_real_transform (GimpTransformTool *tr_tool, - GimpItem *item, - GeglBuffer *orig_buffer, - gint orig_offset_x, - gint orig_offset_y, - GimpColorProfile **buffer_profile, - gint *new_offset_x, - gint *new_offset_y); - -static void gimp_transform_tool_widget_changed (GimpToolWidget *widget, - GimpTransformTool *tr_tool); -static void gimp_transform_tool_widget_response (GimpToolWidget *widget, - gint response_id, - GimpTransformTool *tr_tool); - -static void gimp_transform_tool_halt (GimpTransformTool *tr_tool); -static void gimp_transform_tool_commit (GimpTransformTool *tr_tool); - -static gboolean gimp_transform_tool_bounds (GimpTransformTool *tr_tool, - GimpDisplay *display); -static void gimp_transform_tool_dialog (GimpTransformTool *tr_tool); -static void gimp_transform_tool_dialog_update (GimpTransformTool *tr_tool); -static void gimp_transform_tool_prepare (GimpTransformTool *tr_tool, - GimpDisplay *display); -static GimpToolWidget * - gimp_transform_tool_get_widget (GimpTransformTool *tr_tool); - -static void gimp_transform_tool_response (GimpToolGui *gui, - gint response_id, - GimpTransformTool *tr_tool); - -static void gimp_transform_tool_update_sensitivity (GimpTransformTool *tr_tool); -static GimpItem *gimp_transform_tool_get_active_item (GimpTransformTool *tr_tool, - GimpImage *image); -static GimpItem *gimp_transform_tool_check_active_item (GimpTransformTool *tr_tool, - GimpImage *display, - gboolean invisible_layer_ok, - GError **error); -static void gimp_transform_tool_hide_active_item (GimpTransformTool *tr_tool, - GimpItem *item); -static void gimp_transform_tool_show_active_item (GimpTransformTool *tr_tool); - -static TransInfo * trans_info_new (void); -static void trans_info_free (TransInfo *info); +static GeglBuffer * gimp_transform_tool_real_transform (GimpTransformTool *tr_tool, + GimpItem *item, + GeglBuffer *orig_buffer, + gint orig_offset_x, + gint orig_offset_y, + GimpColorProfile **buffer_profile, + gint *new_offset_x, + gint *new_offset_y); G_DEFINE_TYPE (GimpTransformTool, gimp_transform_tool, GIMP_TYPE_DRAW_TOOL) @@ -164,605 +63,18 @@ G_DEFINE_TYPE (GimpTransformTool, gimp_transform_tool, GIMP_TYPE_DRAW_TOOL) static void gimp_transform_tool_class_init (GimpTransformToolClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass); - GimpDrawToolClass *draw_class = GIMP_DRAW_TOOL_CLASS (klass); + klass->recalc_matrix = NULL; + klass->get_undo_desc = NULL; + klass->transform = gimp_transform_tool_real_transform; - object_class->finalize = gimp_transform_tool_finalize; - - tool_class->initialize = gimp_transform_tool_initialize; - tool_class->control = gimp_transform_tool_control; - tool_class->button_press = gimp_transform_tool_button_press; - tool_class->button_release = gimp_transform_tool_button_release; - tool_class->motion = gimp_transform_tool_motion; - tool_class->modifier_key = gimp_transform_tool_modifier_key; - tool_class->cursor_update = gimp_transform_tool_cursor_update; - tool_class->can_undo = gimp_transform_tool_can_undo; - tool_class->can_redo = gimp_transform_tool_can_redo; - tool_class->undo = gimp_transform_tool_undo; - tool_class->redo = gimp_transform_tool_redo; - tool_class->options_notify = gimp_transform_tool_options_notify; - - draw_class->draw = gimp_transform_tool_draw; - - klass->dialog = NULL; - klass->dialog_update = NULL; - klass->prepare = NULL; - klass->recalc_matrix = NULL; - klass->get_undo_desc = NULL; - klass->transform = gimp_transform_tool_real_transform; - - klass->ok_button_label = _("_Transform"); + klass->progress_text = _("Transforming"); } static void gimp_transform_tool_init (GimpTransformTool *tr_tool) { - GimpTool *tool = GIMP_TOOL (tr_tool); - - gimp_tool_control_set_scroll_lock (tool->control, TRUE); - gimp_tool_control_set_preserve (tool->control, FALSE); - gimp_tool_control_set_dirty_mask (tool->control, - GIMP_DIRTY_IMAGE_SIZE | - GIMP_DIRTY_DRAWABLE | - GIMP_DIRTY_SELECTION | - GIMP_DIRTY_ACTIVE_DRAWABLE); - gimp_tool_control_set_active_modifiers (tool->control, - GIMP_TOOL_ACTIVE_MODIFIERS_SAME); - gimp_tool_control_set_precision (tool->control, - GIMP_CURSOR_PRECISION_SUBPIXEL); - gimp_tool_control_set_cursor (tool->control, - GIMP_CURSOR_CROSSHAIR_SMALL); - gimp_tool_control_set_action_opacity (tool->control, - "tools/tools-transform-preview-opacity-set"); - - tr_tool->progress_text = _("Transforming"); - gimp_matrix3_identity (&tr_tool->transform); tr_tool->transform_valid = TRUE; - - tr_tool->strokes = g_ptr_array_new (); -} - -static void -gimp_transform_tool_finalize (GObject *object) -{ - GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (object); - - g_clear_object (&tr_tool->gui); - g_clear_pointer (&tr_tool->strokes, g_ptr_array_unref); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static gboolean -gimp_transform_tool_initialize (GimpTool *tool, - GimpDisplay *display, - GError **error) -{ - GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool); - GimpImage *image = gimp_display_get_image (display); - GimpDrawable *drawable = gimp_image_get_active_drawable (image); - GimpItem *item; - - item = gimp_transform_tool_check_active_item (tr_tool, image, FALSE, error); - - if (! item) - return FALSE; - - /* Find the transform bounds for some tools (like scale, - * perspective) that actually need the bounds for initializing - */ - if (! gimp_transform_tool_bounds (tr_tool, display)) - { - g_set_error (error, GIMP_ERROR, GIMP_FAILED, - _("The selection does not intersect with the layer.")); - return FALSE; - } - - tool->display = display; - tool->drawable = drawable; - - /* Initialize the transform tool dialog */ - if (! tr_tool->gui) - gimp_transform_tool_dialog (tr_tool); - - /* Initialize the tool-specific trans_info, and adjust the tool dialog */ - gimp_transform_tool_prepare (tr_tool, display); - - /* Recalculate the transform tool */ - gimp_transform_tool_recalc_matrix (tr_tool, NULL); - - /* Get the on-canvas gui */ - tr_tool->widget = gimp_transform_tool_get_widget (tr_tool); - - gimp_transform_tool_hide_active_item (tr_tool, item); - - /* start drawing the bounding box and handles... */ - gimp_draw_tool_start (GIMP_DRAW_TOOL (tool), display); - - /* Initialize undo and redo lists */ - tr_tool->undo_list = g_list_prepend (NULL, trans_info_new ()); - tr_tool->redo_list = NULL; - tr_tool->old_trans_info = g_list_last (tr_tool->undo_list)->data; - tr_tool->prev_trans_info = g_list_first (tr_tool->undo_list)->data; - gimp_transform_tool_update_sensitivity (tr_tool); - - /* Save the current transformation info */ - memcpy (tr_tool->prev_trans_info, tr_tool->trans_info, - sizeof (TransInfo)); - - return TRUE; -} - -static void -gimp_transform_tool_control (GimpTool *tool, - GimpToolAction action, - GimpDisplay *display) -{ - GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool); - - switch (action) - { - case GIMP_TOOL_ACTION_PAUSE: - break; - - case GIMP_TOOL_ACTION_RESUME: - gimp_transform_tool_bounds (tr_tool, display); - gimp_transform_tool_recalc_matrix (tr_tool, tr_tool->widget); - break; - - case GIMP_TOOL_ACTION_HALT: - gimp_transform_tool_halt (tr_tool); - break; - - case GIMP_TOOL_ACTION_COMMIT: - if (tool->display) - gimp_transform_tool_commit (tr_tool); - break; - } - - GIMP_TOOL_CLASS (parent_class)->control (tool, action, display); -} - -static void -gimp_transform_tool_button_press (GimpTool *tool, - const GimpCoords *coords, - guint32 time, - GdkModifierType state, - GimpButtonPressType press_type, - GimpDisplay *display) -{ - GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool); - - if (tr_tool->widget) - { - gimp_tool_widget_hover (tr_tool->widget, coords, state, TRUE); - - if (gimp_tool_widget_button_press (tr_tool->widget, coords, time, state, - press_type)) - { - tr_tool->grab_widget = tr_tool->widget; - } - } - - gimp_tool_control_activate (tool->control); -} - -void -gimp_transform_tool_push_internal_undo (GimpTransformTool *tr_tool) -{ - g_return_if_fail (GIMP_IS_TRANSFORM_TOOL (tr_tool)); - g_return_if_fail (tr_tool->prev_trans_info != NULL); - - /* push current state on the undo list and set this state as the - * current state, but avoid doing this if there were no changes - */ - if (memcmp (tr_tool->prev_trans_info, tr_tool->trans_info, - sizeof (TransInfo)) != 0) - { - tr_tool->prev_trans_info = trans_info_new (); - memcpy (tr_tool->prev_trans_info, tr_tool->trans_info, - sizeof (TransInfo)); - - tr_tool->undo_list = g_list_prepend (tr_tool->undo_list, - tr_tool->prev_trans_info); - - /* If we undid anything and started interacting, we have to - * discard the redo history - */ - g_list_free_full (tr_tool->redo_list, (GDestroyNotify) trans_info_free); - tr_tool->redo_list = NULL; - - gimp_transform_tool_update_sensitivity (tr_tool); - - /* update the undo actions / menu items */ - gimp_image_flush (gimp_display_get_image (GIMP_TOOL (tr_tool)->display)); - } -} - -static void -gimp_transform_tool_button_release (GimpTool *tool, - const GimpCoords *coords, - guint32 time, - GdkModifierType state, - GimpButtonReleaseType release_type, - GimpDisplay *display) -{ - GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool); - - gimp_tool_control_halt (tool->control); - - if (tr_tool->grab_widget) - { - gimp_tool_widget_button_release (tr_tool->grab_widget, - coords, time, state, release_type); - tr_tool->grab_widget = NULL; - } - - if (release_type != GIMP_BUTTON_RELEASE_CANCEL) - { - /* This hack is to perform the flip immediately with the flip tool */ - if (! tr_tool->widget) - { - gimp_transform_tool_response (NULL, GTK_RESPONSE_OK, tr_tool); - return; - } - - /* We're done with an interaction, save it on the undo list */ - gimp_transform_tool_push_internal_undo (tr_tool); - } - else - { - /* Restore the last saved state */ - memcpy (tr_tool->trans_info, tr_tool->prev_trans_info, - sizeof (TransInfo)); - - /* reget the selection bounds */ - gimp_transform_tool_bounds (tr_tool, display); - - /* recalculate the tool's transformation matrix */ - gimp_transform_tool_recalc_matrix (tr_tool, tr_tool->widget); - } -} - -static void -gimp_transform_tool_motion (GimpTool *tool, - const GimpCoords *coords, - guint32 time, - GdkModifierType state, - GimpDisplay *display) -{ - GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool); - - if (tr_tool->grab_widget) - { - gimp_tool_widget_motion (tr_tool->grab_widget, coords, time, state); - } -} - -static void -gimp_transform_tool_modifier_key (GimpTool *tool, - GdkModifierType key, - gboolean press, - GdkModifierType state, - GimpDisplay *display) -{ - GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool); - - if (tr_tool->widget) - { - GIMP_TOOL_CLASS (parent_class)->modifier_key (tool, key, press, - state, display); - } - else - { - GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tool); - - if (key == gimp_get_constrain_behavior_mask ()) - { - g_object_set (options, - "frompivot-scale", ! options->frompivot_scale, - "frompivot-shear", ! options->frompivot_shear, - "frompivot-perspective", ! options->frompivot_perspective, - NULL); - } - else if (key == gimp_get_extend_selection_mask ()) - { - g_object_set (options, - "cornersnap", ! options->cornersnap, - "constrain-move", ! options->constrain_move, - "constrain-scale", ! options->constrain_scale, - "constrain-rotate", ! options->constrain_rotate, - "constrain-shear", ! options->constrain_shear, - "constrain-perspective", ! options->constrain_perspective, - NULL); - } - } -} - -static void -gimp_transform_tool_cursor_update (GimpTool *tool, - const GimpCoords *coords, - GdkModifierType state, - GimpDisplay *display) -{ - GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool); - GimpImage *image = gimp_display_get_image (display); - - if (! gimp_transform_tool_check_active_item (tr_tool, image, TRUE, NULL)) - { - gimp_tool_set_cursor (tool, display, - gimp_tool_control_get_cursor (tool->control), - gimp_tool_control_get_tool_cursor (tool->control), - GIMP_CURSOR_MODIFIER_BAD); - return; - } - - GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display); -} - -static const gchar * -gimp_transform_tool_can_undo (GimpTool *tool, - GimpDisplay *display) -{ - GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool); - - if (! tr_tool->undo_list || ! tr_tool->undo_list->next) - return NULL; - - return _("Transform Step"); -} - -static const gchar * -gimp_transform_tool_can_redo (GimpTool *tool, - GimpDisplay *display) -{ - GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool); - - if (! tr_tool->redo_list) - return NULL; - - return _("Transform Step"); -} - -static gboolean -gimp_transform_tool_undo (GimpTool *tool, - GimpDisplay *display) -{ - GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool); - GList *item; - - item = g_list_next (tr_tool->undo_list); - - /* Move prev_trans_info from undo_list to redo_list */ - tr_tool->redo_list = g_list_prepend (tr_tool->redo_list, - tr_tool->prev_trans_info); - tr_tool->undo_list = g_list_remove (tr_tool->undo_list, - tr_tool->prev_trans_info); - - tr_tool->prev_trans_info = item->data; - - /* Restore the previous transformation info */ - memcpy (tr_tool->trans_info, tr_tool->prev_trans_info, - sizeof (TransInfo)); - - /* reget the selection bounds */ - gimp_transform_tool_bounds (tr_tool, tool->display); - - /* recalculate the tool's transformation matrix */ - gimp_transform_tool_recalc_matrix (tr_tool, tr_tool->widget); - - return TRUE; -} - -static gboolean -gimp_transform_tool_redo (GimpTool *tool, - GimpDisplay *display) -{ - GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool); - GList *item; - - item = tr_tool->redo_list; - - /* Move prev_trans_info from redo_list to undo_list */ - tr_tool->prev_trans_info = item->data; - - tr_tool->undo_list = g_list_prepend (tr_tool->undo_list, - tr_tool->prev_trans_info); - tr_tool->redo_list = g_list_remove (tr_tool->redo_list, - tr_tool->prev_trans_info); - - /* Restore the previous transformation info */ - memcpy (tr_tool->trans_info, tr_tool->prev_trans_info, - sizeof (TransInfo)); - - /* reget the selection bounds */ - gimp_transform_tool_bounds (tr_tool, tool->display); - - /* recalculate the tool's transformation matrix */ - gimp_transform_tool_recalc_matrix (tr_tool, tr_tool->widget); - - return TRUE; -} - -static void -gimp_transform_tool_options_notify (GimpTool *tool, - GimpToolOptions *options, - const GParamSpec *pspec) -{ - GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool); - GimpTransformOptions *tr_options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tool); - - GIMP_TOOL_CLASS (parent_class)->options_notify (tool, options, pspec); - - if (! strcmp (pspec->name, "type")) - { - gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, tool->display); - return; - } - - if (! tr_tool->widget) - return; - - if (! strcmp (pspec->name, "direction")) - { - /* reget the selection bounds */ - gimp_transform_tool_bounds (tr_tool, tool->display); - - /* recalculate the tool's transformation matrix */ - gimp_transform_tool_recalc_matrix (tr_tool, tr_tool->widget); - } - else if (! strcmp (pspec->name, "show-preview")) - { - if (tr_tool->preview) - { - GimpDisplay *display; - GimpImage *image; - GimpItem *item; - gboolean show_preview; - - show_preview = gimp_transform_options_show_preview (tr_options) && - tr_tool->transform_valid; - - gimp_canvas_item_set_visible (tr_tool->preview, show_preview); - - display = tool->display; - image = gimp_display_get_image (display); - item = gimp_transform_tool_check_active_item (tr_tool, image, TRUE, NULL); - if (item) - { - if (show_preview) - gimp_transform_tool_hide_active_item (tr_tool, item); - else - gimp_transform_tool_show_active_item (tr_tool); - } - } - } - else if (g_str_has_prefix (pspec->name, "constrain-") || - g_str_has_prefix (pspec->name, "frompivot-") || - ! strcmp (pspec->name, "fixedpivot") || - ! strcmp (pspec->name, "cornersnap")) - { - gimp_transform_tool_dialog_update (tr_tool); - } -} - -static void -gimp_transform_tool_draw (GimpDrawTool *draw_tool) -{ - GimpTool *tool = GIMP_TOOL (draw_tool); - GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (draw_tool); - GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tool); - GimpImage *image = gimp_display_get_image (tool->display); - GimpMatrix3 matrix = tr_tool->transform; - GimpCanvasItem *item; - - if (options->direction == GIMP_TRANSFORM_BACKWARD) - gimp_matrix3_invert (&matrix); - - if (tr_tool->widget) - { - gboolean show_preview = gimp_transform_options_show_preview (options) && - tr_tool->transform_valid; - - tr_tool->preview = - gimp_draw_tool_add_transform_preview (draw_tool, - tool->drawable, - &matrix, - tr_tool->x1, - tr_tool->y1, - tr_tool->x2, - tr_tool->y2); - g_object_add_weak_pointer (G_OBJECT (tr_tool->preview), - (gpointer) &tr_tool->preview); - - gimp_canvas_item_set_visible (tr_tool->preview, show_preview); - - g_object_bind_property (G_OBJECT (options), "preview-opacity", - G_OBJECT (tr_tool->preview), "opacity", - G_BINDING_SYNC_CREATE | - G_BINDING_BIDIRECTIONAL); - - GIMP_DRAW_TOOL_CLASS (parent_class)->draw (draw_tool); - } - - if (options->type == GIMP_TRANSFORM_TYPE_SELECTION) - { - const GimpBoundSeg *segs_in; - const GimpBoundSeg *segs_out; - gint n_segs_in; - gint n_segs_out; - - gimp_channel_boundary (gimp_image_get_mask (image), - &segs_in, &segs_out, - &n_segs_in, &n_segs_out, - 0, 0, 0, 0); - - if (segs_in) - { - tr_tool->boundary_in = - gimp_draw_tool_add_boundary (draw_tool, - segs_in, n_segs_in, - &matrix, - 0, 0); - g_object_add_weak_pointer (G_OBJECT (tr_tool->boundary_in), - (gpointer) &tr_tool->boundary_in); - - gimp_canvas_item_set_visible (tr_tool->boundary_in, - tr_tool->transform_valid); - } - - if (segs_out) - { - tr_tool->boundary_out = - gimp_draw_tool_add_boundary (draw_tool, - segs_out, n_segs_out, - &matrix, - 0, 0); - g_object_add_weak_pointer (G_OBJECT (tr_tool->boundary_in), - (gpointer) &tr_tool->boundary_out); - - gimp_canvas_item_set_visible (tr_tool->boundary_out, - tr_tool->transform_valid); - } - } - else if (options->type == GIMP_TRANSFORM_TYPE_PATH) - { - GimpVectors *vectors = gimp_image_get_active_vectors (image); - - if (vectors) - { - GimpStroke *stroke = NULL; - - while ((stroke = gimp_vectors_stroke_get_next (vectors, stroke))) - { - GArray *coords; - gboolean closed; - - coords = gimp_stroke_interpolate (stroke, 1.0, &closed); - - if (coords && coords->len) - { - item = - gimp_draw_tool_add_strokes (draw_tool, - &g_array_index (coords, - GimpCoords, 0), - coords->len, &matrix, FALSE); - - g_ptr_array_add (tr_tool->strokes, item); - g_object_weak_ref (G_OBJECT (item), - (GWeakNotify) g_ptr_array_remove, - tr_tool->strokes); - - gimp_canvas_item_set_visible (item, tr_tool->transform_valid); - } - - if (coords) - g_array_free (coords, TRUE); - } - } - } } static GeglBuffer * @@ -775,15 +87,16 @@ gimp_transform_tool_real_transform (GimpTransformTool *tr_tool, gint *new_offset_x, gint *new_offset_y) { - GimpTool *tool = GIMP_TOOL (tr_tool); - GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tool); - GimpContext *context = GIMP_CONTEXT (options); - GeglBuffer *ret = NULL; - GimpTransformResize clip = options->clip; - GimpProgress *progress; + GimpTransformToolClass *klass = GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool); + GimpTool *tool = GIMP_TOOL (tr_tool); + GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tool); + GimpContext *context = GIMP_CONTEXT (options); + GeglBuffer *ret = NULL; + GimpTransformResize clip = options->clip; + GimpProgress *progress; progress = gimp_progress_start (GIMP_PROGRESS (tool), FALSE, - "%s", tr_tool->progress_text); + "%s", klass->progress_text); if (orig_buffer) { @@ -847,272 +160,21 @@ gimp_transform_tool_real_transform (GimpTransformTool *tr_tool, return ret; } -static void -gimp_transform_tool_widget_changed (GimpToolWidget *widget, - GimpTransformTool *tr_tool) -{ - GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool); - GimpMatrix3 matrix = tr_tool->transform; - gint i; - - if (options->direction == GIMP_TRANSFORM_BACKWARD) - gimp_matrix3_invert (&matrix); - - if (tr_tool->preview) - { - gboolean show_preview = gimp_transform_options_show_preview (options) && - tr_tool->transform_valid; - - gimp_canvas_item_begin_change (tr_tool->preview); - gimp_canvas_item_set_visible (tr_tool->preview, show_preview); - g_object_set (tr_tool->preview, - "transform", &matrix, - NULL); - gimp_canvas_item_end_change (tr_tool->preview); - } - - if (tr_tool->boundary_in) - { - gimp_canvas_item_begin_change (tr_tool->boundary_in); - gimp_canvas_item_set_visible (tr_tool->boundary_in, - tr_tool->transform_valid); - g_object_set (tr_tool->boundary_in, - "transform", &matrix, - NULL); - gimp_canvas_item_end_change (tr_tool->boundary_in); - } - - if (tr_tool->boundary_out) - { - gimp_canvas_item_begin_change (tr_tool->boundary_out); - gimp_canvas_item_set_visible (tr_tool->boundary_out, - tr_tool->transform_valid); - g_object_set (tr_tool->boundary_out, - "transform", &matrix, - NULL); - gimp_canvas_item_end_change (tr_tool->boundary_out); - } - - for (i = 0; i < tr_tool->strokes->len; i++) - { - GimpCanvasItem *item = g_ptr_array_index (tr_tool->strokes, i); - - gimp_canvas_item_begin_change (item); - gimp_canvas_item_set_visible (item, tr_tool->transform_valid); - g_object_set (item, - "transform", &matrix, - NULL); - gimp_canvas_item_end_change (item); - } -} - -static void -gimp_transform_tool_widget_response (GimpToolWidget *widget, - gint response_id, - GimpTransformTool *tr_tool) -{ - switch (response_id) - { - case GIMP_TOOL_WIDGET_RESPONSE_CONFIRM: - gimp_transform_tool_response (NULL, GTK_RESPONSE_OK, tr_tool); - break; - - case GIMP_TOOL_WIDGET_RESPONSE_CANCEL: - gimp_transform_tool_response (NULL, GTK_RESPONSE_CANCEL, tr_tool); - break; - - case GIMP_TOOL_WIDGET_RESPONSE_RESET: - gimp_transform_tool_response (NULL, RESPONSE_RESET, tr_tool); - break; - } -} - -static void -gimp_transform_tool_halt (GimpTransformTool *tr_tool) -{ - GimpTool *tool = GIMP_TOOL (tr_tool); - - if (gimp_draw_tool_is_active (GIMP_DRAW_TOOL (tr_tool))) - gimp_draw_tool_stop (GIMP_DRAW_TOOL (tr_tool)); - - gimp_draw_tool_set_widget (GIMP_DRAW_TOOL (tr_tool), NULL); - g_clear_object (&tr_tool->widget); - - if (tr_tool->gui) - gimp_tool_gui_hide (tr_tool->gui); - - if (tr_tool->redo_list) - { - g_list_free_full (tr_tool->redo_list, (GDestroyNotify) trans_info_free); - tr_tool->redo_list = NULL; - } - - if (tr_tool->undo_list) - { - g_list_free_full (tr_tool->undo_list, (GDestroyNotify) trans_info_free); - tr_tool->undo_list = NULL; - tr_tool->prev_trans_info = NULL; - } - - gimp_transform_tool_show_active_item (tr_tool); - - tool->display = NULL; - tool->drawable = NULL; - } - -static void -gimp_transform_tool_commit (GimpTransformTool *tr_tool) -{ - GimpTool *tool = GIMP_TOOL (tr_tool); - GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tool); - GimpContext *context = GIMP_CONTEXT (options); - GimpDisplay *display = tool->display; - GimpImage *image = gimp_display_get_image (display); - GimpItem *active_item; - GeglBuffer *orig_buffer = NULL; - gint orig_offset_x = 0; - gint orig_offset_y = 0; - GeglBuffer *new_buffer; - gint new_offset_x; - gint new_offset_y; - GimpColorProfile *buffer_profile; - gchar *undo_desc = NULL; - gboolean new_layer = FALSE; - GError *error = NULL; - - active_item = gimp_transform_tool_check_active_item (tr_tool, image, - TRUE, &error); - - if (! active_item) - { - gimp_tool_message_literal (tool, display, error->message); - g_clear_error (&error); - return; - } - - if (! tr_tool->transform_valid) - { - gimp_tool_message_literal (tool, display, - _("The current transform is invalid")); - return; - } - - if (tr_tool->gui) - gimp_tool_gui_hide (tr_tool->gui); - - if (GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->recalc_matrix && - gimp_matrix3_is_identity (&tr_tool->transform)) - { - /* No need to commit an identity transformation! */ - return; - } - - gimp_set_busy (display->gimp); - - /* undraw the tool before we muck around with the transform matrix */ - gimp_draw_tool_stop (GIMP_DRAW_TOOL (tr_tool)); - - /* We're going to dirty this image, but we want to keep the tool around */ - gimp_tool_control_push_preserve (tool->control, TRUE); - - undo_desc = GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->get_undo_desc (tr_tool); - gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM, undo_desc); - g_free (undo_desc); - - switch (options->type) - { - case GIMP_TRANSFORM_TYPE_LAYER: - if (! gimp_viewable_get_children (GIMP_VIEWABLE (tool->drawable)) && - ! gimp_channel_is_empty (gimp_image_get_mask (image))) - { - orig_buffer = gimp_drawable_transform_cut (tool->drawable, - context, - &orig_offset_x, - &orig_offset_y, - &new_layer); - } - break; - - case GIMP_TRANSFORM_TYPE_SELECTION: - orig_buffer = g_object_ref (gimp_drawable_get_buffer (GIMP_DRAWABLE (active_item))); - break; - - case GIMP_TRANSFORM_TYPE_PATH: - break; - } - - /* Send the request for the transformation to the tool... - */ - new_buffer = GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->transform (tr_tool, - active_item, - orig_buffer, - orig_offset_x, - orig_offset_y, - &buffer_profile, - &new_offset_x, - &new_offset_y); - - if (orig_buffer) - g_object_unref (orig_buffer); - - switch (options->type) - { - case GIMP_TRANSFORM_TYPE_LAYER: - if (new_buffer) - { - /* paste the new transformed image to the image...also implement - * undo... - */ - gimp_drawable_transform_paste (tool->drawable, - new_buffer, buffer_profile, - new_offset_x, new_offset_y, - new_layer); - g_object_unref (new_buffer); - } - break; - - case GIMP_TRANSFORM_TYPE_SELECTION: - if (new_buffer) - { - gimp_channel_push_undo (GIMP_CHANNEL (active_item), NULL); - - gimp_drawable_set_buffer (GIMP_DRAWABLE (active_item), - FALSE, NULL, new_buffer); - g_object_unref (new_buffer); - } - break; - - case GIMP_TRANSFORM_TYPE_PATH: - /* Nothing to be done */ - break; - } - - gimp_image_undo_push (image, GIMP_TYPE_TRANSFORM_TOOL_UNDO, - GIMP_UNDO_TRANSFORM, NULL, - 0, - "transform-tool", tr_tool, - NULL); - - gimp_image_undo_group_end (image); - - /* We're done dirtying the image, and would like to be restarted if - * the image gets dirty while the tool exists - */ - gimp_tool_control_pop_preserve (tool->control); - - gimp_unset_busy (display->gimp); - - gimp_image_flush (image); -} - -static gboolean +gboolean gimp_transform_tool_bounds (GimpTransformTool *tr_tool, GimpDisplay *display) { - GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool); - GimpImage *image = gimp_display_get_image (display); + GimpTransformOptions *options; + GimpImage *image; gboolean non_empty = TRUE; + g_return_val_if_fail (GIMP_IS_TRANSFORM_TOOL (tr_tool), FALSE); + + options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool); + image = gimp_display_get_image (display); + + g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE); + switch (options->type) { case GIMP_TRANSFORM_TYPE_LAYER: @@ -1188,258 +250,45 @@ gimp_transform_tool_bounds (GimpTransformTool *tr_tool, return non_empty; } -static void -gimp_transform_tool_dialog (GimpTransformTool *tr_tool) -{ - GimpTool *tool = GIMP_TOOL (tr_tool); - GimpToolInfo *tool_info = tool->tool_info; - GimpDisplayShell *shell; - const gchar *ok_button_label; - - if (! GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->dialog) - return; - - g_return_if_fail (tool->display != NULL); - - shell = gimp_display_get_shell (tool->display); - - ok_button_label = GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->ok_button_label; - - tr_tool->gui = gimp_tool_gui_new (tool_info, - NULL, NULL, NULL, NULL, - gimp_widget_get_monitor (GTK_WIDGET (shell)), - TRUE, - - _("_Reset"), RESPONSE_RESET, - _("_Cancel"), GTK_RESPONSE_CANCEL, - ok_button_label, GTK_RESPONSE_OK, - - NULL); - - gimp_tool_gui_set_auto_overlay (tr_tool->gui, TRUE); - gimp_tool_gui_set_default_response (tr_tool->gui, GTK_RESPONSE_OK); - - gimp_tool_gui_set_alternative_button_order (tr_tool->gui, - RESPONSE_RESET, - GTK_RESPONSE_OK, - GTK_RESPONSE_CANCEL, - -1); - - g_signal_connect (tr_tool->gui, "response", - G_CALLBACK (gimp_transform_tool_response), - tr_tool); - - GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->dialog (tr_tool); -} - -static void -gimp_transform_tool_dialog_update (GimpTransformTool *tr_tool) -{ - if (tr_tool->gui && - GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->dialog_update) - { - GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->dialog_update (tr_tool); - } -} - -static void -gimp_transform_tool_prepare (GimpTransformTool *tr_tool, - GimpDisplay *display) -{ - if (tr_tool->gui) - { - GimpImage *image = gimp_display_get_image (display); - GimpItem *item = gimp_transform_tool_get_active_item (tr_tool, image); - - gimp_tool_gui_set_shell (tr_tool->gui, gimp_display_get_shell (display)); - gimp_tool_gui_set_viewable (tr_tool->gui, GIMP_VIEWABLE (item)); - } - - if (GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->prepare) - GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->prepare (tr_tool); -} - -static GimpToolWidget * -gimp_transform_tool_get_widget (GimpTransformTool *tr_tool) -{ - static const gchar *properties[] = - { - "constrain-move", - "constrain-scale", - "constrain-rotate", - "constrain-shear", - "constrain-perspective", - "frompivot-scale", - "frompivot-shear", - "frompivot-perspective", - "cornersnap", - "fixedpivot" - }; - - GimpToolWidget *widget = NULL; - - if (GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->get_widget) - { - GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool); - gint i; - - widget = GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->get_widget (tr_tool); - - gimp_draw_tool_set_widget (GIMP_DRAW_TOOL (tr_tool), widget); - - g_object_bind_property (G_OBJECT (options), "grid-type", - G_OBJECT (widget), "guide-type", - G_BINDING_SYNC_CREATE | - G_BINDING_BIDIRECTIONAL); - g_object_bind_property (G_OBJECT (options), "grid-size", - G_OBJECT (widget), "n-guides", - G_BINDING_SYNC_CREATE | - G_BINDING_BIDIRECTIONAL); - - for (i = 0; i < G_N_ELEMENTS (properties); i++) - g_object_bind_property (G_OBJECT (options), properties[i], - G_OBJECT (widget), properties[i], - G_BINDING_SYNC_CREATE | - G_BINDING_BIDIRECTIONAL); - - g_signal_connect (widget, "changed", - G_CALLBACK (gimp_transform_tool_widget_changed), - tr_tool); - g_signal_connect (widget, "response", - G_CALLBACK (gimp_transform_tool_widget_response), - tr_tool); - } - - return widget; -} - void gimp_transform_tool_recalc_matrix (GimpTransformTool *tr_tool, - GimpToolWidget *widget) + GimpDisplay *display) { g_return_if_fail (GIMP_IS_TRANSFORM_TOOL (tr_tool)); - g_return_if_fail (widget == NULL || GIMP_IS_TOOL_WIDGET (widget)); + g_return_if_fail (GIMP_IS_DISPLAY (display)); + + gimp_transform_tool_bounds (tr_tool, display); if (GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->recalc_matrix) - GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->recalc_matrix (tr_tool, widget); - - gimp_transform_tool_dialog_update (tr_tool); - gimp_transform_tool_update_sensitivity (tr_tool); - - if (tr_tool->gui) - gimp_tool_gui_show (tr_tool->gui); + GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->recalc_matrix (tr_tool); } -static void -gimp_transform_tool_response (GimpToolGui *gui, - gint response_id, - GimpTransformTool *tr_tool) +GimpItem * +gimp_transform_tool_get_active_item (GimpTransformTool *tr_tool, + GimpDisplay *display, + gboolean invisible_layer_ok, + GError **error) { - GimpTool *tool = GIMP_TOOL (tr_tool); - GimpDisplay *display = tool->display; - - switch (response_id) - { - case RESPONSE_RESET: - /* Move all undo events to redo, and pop off the first - * one as that's the current one, which always sits on - * the undo_list - */ - tr_tool->redo_list = - g_list_remove (g_list_concat (g_list_reverse (tr_tool->undo_list), - tr_tool->redo_list), - tr_tool->old_trans_info); - tr_tool->prev_trans_info = tr_tool->old_trans_info; - tr_tool->undo_list = g_list_prepend (NULL, - tr_tool->prev_trans_info); - - gimp_transform_tool_update_sensitivity (tr_tool); - - /* Restore the previous transformation info */ - memcpy (tr_tool->trans_info, tr_tool->prev_trans_info, - sizeof (TransInfo)); - - /* reget the selection bounds */ - gimp_transform_tool_bounds (tr_tool, display); - - /* recalculate the tool's transformation matrix */ - gimp_transform_tool_recalc_matrix (tr_tool, tr_tool->widget); - - /* update the undo actions / menu items */ - gimp_image_flush (gimp_display_get_image (display)); - break; - - case GTK_RESPONSE_OK: - g_return_if_fail (display != NULL); - gimp_tool_control (tool, GIMP_TOOL_ACTION_COMMIT, display); - break; - - default: - gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display); - - /* update the undo actions / menu items */ - if (display) - gimp_image_flush (gimp_display_get_image (display)); - break; - } -} - -static void -gimp_transform_tool_update_sensitivity (GimpTransformTool *tr_tool) -{ - if (! tr_tool->gui) - return; - - gimp_tool_gui_set_response_sensitive (tr_tool->gui, GTK_RESPONSE_OK, - tr_tool->transform_valid); - gimp_tool_gui_set_response_sensitive (tr_tool->gui, RESPONSE_RESET, - g_list_next (tr_tool->undo_list) != NULL); -} - -static GimpItem * -gimp_transform_tool_get_active_item (GimpTransformTool *tr_tool, - GimpImage *image) -{ - GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool); - - switch (options->type) - { - case GIMP_TRANSFORM_TYPE_LAYER: - return GIMP_ITEM (gimp_image_get_active_drawable (image)); - - case GIMP_TRANSFORM_TYPE_SELECTION: - { - GimpChannel *selection = gimp_image_get_mask (image); - - if (gimp_channel_is_empty (selection)) - return NULL; - else - return GIMP_ITEM (selection); - } - - case GIMP_TRANSFORM_TYPE_PATH: - return GIMP_ITEM (gimp_image_get_active_vectors (image)); - } - - return NULL; -} - -static GimpItem * -gimp_transform_tool_check_active_item (GimpTransformTool *tr_tool, - GimpImage *image, - gboolean invisible_layer_ok, - GError **error) -{ - GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool); - GimpItem *item; + GimpTransformOptions *options; + GimpImage *image; + GimpItem *item = NULL; const gchar *null_message = NULL; const gchar *locked_message = NULL; - item = gimp_transform_tool_get_active_item (tr_tool, image); + g_return_val_if_fail (GIMP_IS_TRANSFORM_TOOL (tr_tool), NULL); + g_return_val_if_fail (GIMP_IS_DISPLAY (display), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool); + + image = gimp_display_get_image (display); + + g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); switch (options->type) { case GIMP_TRANSFORM_TYPE_LAYER: + item = GIMP_ITEM (gimp_image_get_active_drawable (image)); null_message = _("There is no layer to transform."); if (item) @@ -1456,12 +305,23 @@ gimp_transform_tool_check_active_item (GimpTransformTool *tr_tool, _("The active layer is not visible.")); return NULL; } + + if (! gimp_transform_tool_bounds (tr_tool, display)) + { + g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, + _("The selection does not intersect with the layer.")); + return NULL; + } } break; case GIMP_TRANSFORM_TYPE_SELECTION: + item = GIMP_ITEM (gimp_image_get_mask (image)); null_message = _("There is no selection to transform."); + if (gimp_channel_is_empty (GIMP_CHANNEL (item))) + item = NULL; + if (item) { /* cannot happen, so don't translate these messages */ @@ -1473,6 +333,7 @@ gimp_transform_tool_check_active_item (GimpTransformTool *tr_tool, break; case GIMP_TRANSFORM_TYPE_PATH: + item = GIMP_ITEM (gimp_image_get_active_vectors (image)); null_message = _("There is no path to transform."); if (item) @@ -1502,53 +363,149 @@ gimp_transform_tool_check_active_item (GimpTransformTool *tr_tool, return item; } -static void -gimp_transform_tool_hide_active_item (GimpTransformTool *tr_tool, - GimpItem *item) +gboolean +gimp_transform_tool_transform (GimpTransformTool *tr_tool, + GimpDisplay *display) { - GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool); - GimpDisplay *display = GIMP_TOOL (tr_tool)->display; - GimpImage *image = gimp_display_get_image (display); + GimpTool *tool; + GimpTransformOptions *options; + GimpContext *context; + GimpImage *image; + GimpItem *active_item; + GeglBuffer *orig_buffer = NULL; + gint orig_offset_x = 0; + gint orig_offset_y = 0; + GeglBuffer *new_buffer; + gint new_offset_x; + gint new_offset_y; + GimpColorProfile *buffer_profile; + gchar *undo_desc = NULL; + gboolean new_layer = FALSE; + GError *error = NULL; - /* hide only complete layers and channels, not layer masks */ - if (options->type == GIMP_TRANSFORM_TYPE_LAYER && - options->show_preview && - tr_tool->widget /* not for flip */ && - GIMP_IS_DRAWABLE (item) && - ! GIMP_IS_LAYER_MASK (item) && - gimp_item_get_visible (item) && - gimp_channel_is_empty (gimp_image_get_mask (image))) + g_return_val_if_fail (GIMP_IS_TRANSFORM_TOOL (tr_tool), FALSE); + g_return_val_if_fail (GIMP_IS_DISPLAY (display), FALSE); + + tool = GIMP_TOOL (tr_tool); + options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tool); + context = GIMP_CONTEXT (options); + image = gimp_display_get_image (display); + + g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE); + + active_item = gimp_transform_tool_get_active_item (tr_tool, display, TRUE, + &error); + + if (! active_item) { - tr_tool->hidden_item = item; - gimp_item_set_visible (item, FALSE, FALSE); - - gimp_projection_flush (gimp_image_get_projection (image)); + gimp_tool_message_literal (tool, display, error->message); + g_clear_error (&error); + return FALSE; } -} -static void -gimp_transform_tool_show_active_item (GimpTransformTool *tr_tool) -{ - if (tr_tool->hidden_item) + gimp_transform_tool_recalc_matrix (tr_tool, display); + + if (! tr_tool->transform_valid) { - GimpDisplay *display = GIMP_TOOL (tr_tool)->display; - GimpImage *image = gimp_display_get_image (display); - - gimp_item_set_visible (tr_tool->hidden_item, TRUE, FALSE); - tr_tool->hidden_item = NULL; - - gimp_image_flush (image); + gimp_tool_message_literal (tool, display, + _("The current transform is invalid")); + return FALSE; } -} -static TransInfo * -trans_info_new (void) -{ - return g_slice_new0 (TransInfo); -} + if (GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->recalc_matrix && + gimp_matrix3_is_identity (&tr_tool->transform)) + { + /* No need to commit an identity transformation! */ + return TRUE; + } -static void -trans_info_free (TransInfo *info) -{ - g_slice_free (TransInfo, info); + gimp_set_busy (display->gimp); + + /* We're going to dirty this image, but we want to keep the tool around */ + gimp_tool_control_push_preserve (tool->control, TRUE); + + undo_desc = GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->get_undo_desc (tr_tool); + gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM, undo_desc); + g_free (undo_desc); + + switch (options->type) + { + case GIMP_TRANSFORM_TYPE_LAYER: + if (! gimp_viewable_get_children (GIMP_VIEWABLE (tool->drawable)) && + ! gimp_channel_is_empty (gimp_image_get_mask (image))) + { + orig_buffer = gimp_drawable_transform_cut (tool->drawable, + context, + &orig_offset_x, + &orig_offset_y, + &new_layer); + } + break; + + case GIMP_TRANSFORM_TYPE_SELECTION: + orig_buffer = g_object_ref (gimp_drawable_get_buffer (GIMP_DRAWABLE (active_item))); + break; + + case GIMP_TRANSFORM_TYPE_PATH: + break; + } + + /* Send the request for the transformation to the tool... + */ + new_buffer = GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->transform (tr_tool, + active_item, + orig_buffer, + orig_offset_x, + orig_offset_y, + &buffer_profile, + &new_offset_x, + &new_offset_y); + + if (orig_buffer) + g_object_unref (orig_buffer); + + switch (options->type) + { + case GIMP_TRANSFORM_TYPE_LAYER: + if (new_buffer) + { + /* paste the new transformed image to the image...also implement + * undo... + */ + gimp_drawable_transform_paste (tool->drawable, + new_buffer, buffer_profile, + new_offset_x, new_offset_y, + new_layer); + g_object_unref (new_buffer); + } + break; + + case GIMP_TRANSFORM_TYPE_SELECTION: + if (new_buffer) + { + gimp_channel_push_undo (GIMP_CHANNEL (active_item), NULL); + + gimp_drawable_set_buffer (GIMP_DRAWABLE (active_item), + FALSE, NULL, new_buffer); + g_object_unref (new_buffer); + } + break; + + case GIMP_TRANSFORM_TYPE_PATH: + /* Nothing to be done */ + break; + } + + gimp_image_undo_group_end (image); + + /* We're done dirtying the image, and would like to be restarted if + * the image gets dirty while the tool exists + */ + gimp_tool_control_pop_preserve (tool->control); + + gimp_unset_busy (display->gimp); + + gimp_image_flush (image); + + return TRUE; } diff --git a/app/tools/gimptransformtool.h b/app/tools/gimptransformtool.h index 6273d86ee5..8d0b6d3874 100644 --- a/app/tools/gimptransformtool.h +++ b/app/tools/gimptransformtool.h @@ -45,35 +45,13 @@ typedef struct _GimpTransformToolClass GimpTransformToolClass; struct _GimpTransformTool { - GimpDrawTool parent_instance; + GimpDrawTool parent_instance; - gint x1, y1; /* upper left hand coordinate */ - gint x2, y2; /* lower right hand coords */ + gint x1, y1; /* upper left hand coordinate */ + gint x2, y2; /* lower right hand coords */ - GimpMatrix3 transform; /* transformation matrix */ - gboolean transform_valid; /* whether the matrix is valid */ - TransInfo trans_info; /* transformation info */ - TransInfo *old_trans_info; /* for resetting everything */ - TransInfo *prev_trans_info; /* the current finished state */ - GList *undo_list; /* list of all states, - head is current == prev_trans_info, - tail is original == old_trans_info */ - GList *redo_list; /* list of all undone states, - NULL when nothing undone */ - - GimpItem *hidden_item; /* the item that was hidden during - the transform */ - - GimpToolWidget *widget; - GimpToolWidget *grab_widget; - GimpCanvasItem *preview; - GimpCanvasItem *boundary_in; - GimpCanvasItem *boundary_out; - GPtrArray *strokes; - - const gchar *progress_text; - - GimpToolGui *gui; + GimpMatrix3 transform; /* transformation matrix */ + gboolean transform_valid; /* whether the matrix is valid */ }; struct _GimpTransformToolClass @@ -81,31 +59,35 @@ struct _GimpTransformToolClass GimpDrawToolClass parent_class; /* virtual functions */ - void (* dialog) (GimpTransformTool *tool); - void (* dialog_update) (GimpTransformTool *tool); - void (* prepare) (GimpTransformTool *tool); - GimpToolWidget * (* get_widget) (GimpTransformTool *tool); - void (* recalc_matrix) (GimpTransformTool *tool, - GimpToolWidget *widget); - gchar * (* get_undo_desc) (GimpTransformTool *tool); - GeglBuffer * (* transform) (GimpTransformTool *tool, - GimpItem *item, - GeglBuffer *orig_buffer, - gint orig_offset_x, - gint orig_offset_y, - GimpColorProfile **buffer_profile, - gint *new_offset_x, - gint *new_offset_y); + void (* recalc_matrix) (GimpTransformTool *tr_tool); + gchar * (* get_undo_desc) (GimpTransformTool *tr_tool); + GeglBuffer * (* transform) (GimpTransformTool *tr_tool, + GimpItem *item, + GeglBuffer *orig_buffer, + gint orig_offset_x, + gint orig_offset_y, + GimpColorProfile **buffer_profile, + gint *new_offset_x, + gint *new_offset_y); - const gchar *ok_button_label; + const gchar *progress_text; }; -GType gimp_transform_tool_get_type (void) G_GNUC_CONST; +GType gimp_transform_tool_get_type (void) G_GNUC_CONST; -void gimp_transform_tool_recalc_matrix (GimpTransformTool *tr_tool, - GimpToolWidget *widget); -void gimp_transform_tool_push_internal_undo (GimpTransformTool *tr_tool); +GimpItem * gimp_transform_tool_get_active_item (GimpTransformTool *tr_tool, + GimpDisplay *display, + gboolean invisible_layer_ok, + GError **error); + +gboolean gimp_transform_tool_bounds (GimpTransformTool *tr_tool, + GimpDisplay *display); +void gimp_transform_tool_recalc_matrix (GimpTransformTool *tr_tool, + GimpDisplay *display); + +gboolean gimp_transform_tool_transform (GimpTransformTool *tr_tool, + GimpDisplay *display); #endif /* __GIMP_TRANSFORM_TOOL_H__ */ diff --git a/app/tools/gimptransformtoolundo.c b/app/tools/gimptransformtoolundo.c deleted file mode 100644 index 25830b91c9..0000000000 --- a/app/tools/gimptransformtoolundo.c +++ /dev/null @@ -1,220 +0,0 @@ -/* 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 "tools-types.h" - -#include "gimptoolcontrol.h" -#include "gimptransformtool.h" -#include "gimptransformtoolundo.h" - - -enum -{ - PROP_0, - PROP_TRANSFORM_TOOL -}; - - -static void gimp_transform_tool_undo_constructed (GObject *object); -static void gimp_transform_tool_undo_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec); -static void gimp_transform_tool_undo_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec); - -static void gimp_transform_tool_undo_pop (GimpUndo *undo, - GimpUndoMode undo_mode, - GimpUndoAccumulator *accum); -static void gimp_transform_tool_undo_free (GimpUndo *undo, - GimpUndoMode undo_mode); - - -G_DEFINE_TYPE (GimpTransformToolUndo, gimp_transform_tool_undo, GIMP_TYPE_UNDO) - -#define parent_class gimp_transform_tool_undo_parent_class - - -static void -gimp_transform_tool_undo_class_init (GimpTransformToolUndoClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - GimpUndoClass *undo_class = GIMP_UNDO_CLASS (klass); - - object_class->constructed = gimp_transform_tool_undo_constructed; - object_class->set_property = gimp_transform_tool_undo_set_property; - object_class->get_property = gimp_transform_tool_undo_get_property; - - undo_class->pop = gimp_transform_tool_undo_pop; - undo_class->free = gimp_transform_tool_undo_free; - - g_object_class_install_property (object_class, PROP_TRANSFORM_TOOL, - g_param_spec_object ("transform-tool", - NULL, NULL, - GIMP_TYPE_TRANSFORM_TOOL, - GIMP_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); -} - -static void -gimp_transform_tool_undo_init (GimpTransformToolUndo *undo) -{ -} - -static void -gimp_transform_tool_undo_constructed (GObject *object) -{ - GimpTransformToolUndo *transform_tool_undo = GIMP_TRANSFORM_TOOL_UNDO (object); - GimpTransformTool *transform_tool; - gint i; - - G_OBJECT_CLASS (parent_class)->constructed (object); - - gimp_assert (GIMP_IS_TRANSFORM_TOOL (transform_tool_undo->transform_tool)); - - transform_tool = transform_tool_undo->transform_tool; - - for (i = 0; i < TRANS_INFO_SIZE; i++) - transform_tool_undo->trans_info[i] = (*transform_tool->old_trans_info)[i]; - -#if 0 - if (transform_tool->original) - transform_tool_undo->original = tile_manager_ref (transform_tool->original); -#endif - - g_object_add_weak_pointer (G_OBJECT (transform_tool_undo->transform_tool), - (gpointer) &transform_tool_undo->transform_tool); -} - -static void -gimp_transform_tool_undo_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - GimpTransformToolUndo *transform_tool_undo = GIMP_TRANSFORM_TOOL_UNDO (object); - - switch (property_id) - { - case PROP_TRANSFORM_TOOL: - transform_tool_undo->transform_tool = g_value_get_object (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -gimp_transform_tool_undo_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - GimpTransformToolUndo *transform_tool_undo = GIMP_TRANSFORM_TOOL_UNDO (object); - - switch (property_id) - { - case PROP_TRANSFORM_TOOL: - g_value_set_object (value, transform_tool_undo->transform_tool); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -gimp_transform_tool_undo_pop (GimpUndo *undo, - GimpUndoMode undo_mode, - GimpUndoAccumulator *accum) -{ - GimpTransformToolUndo *transform_tool_undo = GIMP_TRANSFORM_TOOL_UNDO (undo); - - GIMP_UNDO_CLASS (parent_class)->pop (undo, undo_mode, accum); - - if (transform_tool_undo->transform_tool) - { - GimpTransformTool *transform_tool; -#if 0 - TileManager *temp; -#endif - gdouble d; - gint i; - - transform_tool = transform_tool_undo->transform_tool; - - /* swap the transformation information arrays */ - for (i = 0; i < TRANS_INFO_SIZE; i++) - { - d = transform_tool_undo->trans_info[i]; - transform_tool_undo->trans_info[i] = transform_tool->trans_info[i]; - transform_tool->trans_info[i] = d; - } - -#if 0 - /* swap the original buffer--the source buffer for repeated transforms - */ - temp = transform_tool_undo->original; - transform_tool_undo->original = transform_tool->original; - transform_tool->original = temp; -#endif - -#if 0 - /* If we're re-implementing the first transform, reactivate tool */ - if (undo_mode == GIMP_UNDO_MODE_REDO && transform_tool->original) - { - gimp_tool_control_activate (GIMP_TOOL (transform_tool)->control); - - gimp_draw_tool_resume (GIMP_DRAW_TOOL (transform_tool)); - } -#endif - } - } - -static void -gimp_transform_tool_undo_free (GimpUndo *undo, - GimpUndoMode undo_mode) -{ - GimpTransformToolUndo *transform_tool_undo = GIMP_TRANSFORM_TOOL_UNDO (undo); - - if (transform_tool_undo->transform_tool) - { - g_object_remove_weak_pointer (G_OBJECT (transform_tool_undo->transform_tool), - (gpointer) &transform_tool_undo->transform_tool); - transform_tool_undo->transform_tool = NULL; - } - -#if 0 - if (transform_tool_undo->original) - { - tile_manager_unref (transform_tool_undo->original); - transform_tool_undo->original = NULL; - } -#endif - - GIMP_UNDO_CLASS (parent_class)->free (undo, undo_mode); -} diff --git a/app/tools/gimptransformtoolundo.h b/app/tools/gimptransformtoolundo.h deleted file mode 100644 index ef5cc57e1c..0000000000 --- a/app/tools/gimptransformtoolundo.h +++ /dev/null @@ -1,56 +0,0 @@ -/* 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_TRANSFORM_TOOL_UNDO_H__ -#define __GIMP_TRANSFORM_TOOL_UNDO_H__ - - -#include "core/gimpundo.h" - - -#define GIMP_TYPE_TRANSFORM_TOOL_UNDO (gimp_transform_tool_undo_get_type ()) -#define GIMP_TRANSFORM_TOOL_UNDO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_TRANSFORM_TOOL_UNDO, GimpTransformToolUndo)) -#define GIMP_TRANSFORM_TOOL_UNDO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_TRANSFORM_TOOL_UNDO, GimpTransformToolUndoClass)) -#define GIMP_IS_TRANSFORM_TOOL_UNDO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_TRANSFORM_TOOL_UNDO)) -#define GIMP_IS_TRANSFORM_TOOL_UNDO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_TRANSFORM_TOOL_UNDO)) -#define GIMP_TRANSFORM_TOOL_UNDO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_TRANSFORM_TOOL_UNDO, GimpTransformToolUndoClass)) - - -typedef struct _GimpTransformToolUndo GimpTransformToolUndo; -typedef struct _GimpTransformToolUndoClass GimpTransformToolUndoClass; - -struct _GimpTransformToolUndo -{ - GimpUndo parent_instance; - - GimpTransformTool *transform_tool; - TransInfo trans_info; -#if 0 - TileManager *original; -#endif -}; - -struct _GimpTransformToolUndoClass -{ - GimpUndoClass parent_class; -}; - - -GType gimp_transform_tool_undo_get_type (void) G_GNUC_CONST; - - -#endif /* __GIMP_TRANSFORM_TOOL_UNDO_H__ */ diff --git a/app/tools/gimpunifiedtransformtool.c b/app/tools/gimpunifiedtransformtool.c index b76d2f7718..2d5bd98cf6 100644 --- a/app/tools/gimpunifiedtransformtool.c +++ b/app/tools/gimpunifiedtransformtool.c @@ -32,7 +32,7 @@ #include "display/gimptooltransformgrid.h" #include "gimptoolcontrol.h" -#include "gimptransformoptions.h" +#include "gimptransformgridoptions.h" #include "gimpunifiedtransformtool.h" #include "gimp-intl.h" @@ -56,17 +56,18 @@ enum /* local function prototypes */ -static void gimp_unified_transform_tool_prepare (GimpTransformTool *tr_tool); -static GimpToolWidget * gimp_unified_transform_tool_get_widget (GimpTransformTool *tr_tool); -static void gimp_unified_transform_tool_recalc_matrix (GimpTransformTool *tr_tool, - GimpToolWidget *widget); static gchar * gimp_unified_transform_tool_get_undo_desc (GimpTransformTool *tr_tool); +static void gimp_unified_transform_tool_prepare (GimpTransformGridTool *tg_tool); +static GimpToolWidget * gimp_unified_transform_tool_get_widget (GimpTransformGridTool *tg_tool); +static void gimp_unified_transform_tool_recalc_matrix (GimpTransformGridTool *tg_tool, + GimpToolWidget *widget); + static void gimp_unified_transform_tool_recalc_points (GimpGenericTransformTool *generic, GimpToolWidget *widget); static void gimp_unified_transform_tool_widget_changed (GimpToolWidget *widget, - GimpTransformTool *tr_tool); + GimpTransformGridTool *tg_tool); G_DEFINE_TYPE (GimpUnifiedTransformTool, gimp_unified_transform_tool, @@ -80,8 +81,8 @@ gimp_unified_transform_tool_register (GimpToolRegisterCallback callback, gpointer data) { (* callback) (GIMP_TYPE_UNIFIED_TRANSFORM_TOOL, - GIMP_TYPE_TRANSFORM_OPTIONS, - gimp_transform_options_gui, + GIMP_TYPE_TRANSFORM_GRID_OPTIONS, + gimp_transform_grid_options_gui, GIMP_CONTEXT_PROP_MASK_BACKGROUND, "gimp-unified-transform-tool", _("Unified Transform"), @@ -96,49 +97,59 @@ gimp_unified_transform_tool_register (GimpToolRegisterCallback callback, static void gimp_unified_transform_tool_class_init (GimpUnifiedTransformToolClass *klass) { - GimpTransformToolClass *trans_class = GIMP_TRANSFORM_TOOL_CLASS (klass); + GimpTransformToolClass *tr_class = GIMP_TRANSFORM_TOOL_CLASS (klass); + GimpTransformGridToolClass *tg_class = GIMP_TRANSFORM_GRID_TOOL_CLASS (klass); GimpGenericTransformToolClass *generic_class = GIMP_GENERIC_TRANSFORM_TOOL_CLASS (klass); - trans_class->prepare = gimp_unified_transform_tool_prepare; - trans_class->get_widget = gimp_unified_transform_tool_get_widget; - trans_class->recalc_matrix = gimp_unified_transform_tool_recalc_matrix; - trans_class->get_undo_desc = gimp_unified_transform_tool_get_undo_desc; + tr_class->get_undo_desc = gimp_unified_transform_tool_get_undo_desc; + + tg_class->prepare = gimp_unified_transform_tool_prepare; + tg_class->get_widget = gimp_unified_transform_tool_get_widget; + tg_class->recalc_matrix = gimp_unified_transform_tool_recalc_matrix; generic_class->recalc_points = gimp_unified_transform_tool_recalc_points; + + tr_class->progress_text = _("Unified transform"); } static void gimp_unified_transform_tool_init (GimpUnifiedTransformTool *unified_tool) { - GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (unified_tool); +} - tr_tool->progress_text = _("Unified transform"); +static gchar * +gimp_unified_transform_tool_get_undo_desc (GimpTransformTool *tr_tool) +{ + return g_strdup (C_("undo-type", "Unified Transform")); } static void -gimp_unified_transform_tool_prepare (GimpTransformTool *tr_tool) +gimp_unified_transform_tool_prepare (GimpTransformGridTool *tg_tool) { - GIMP_TRANSFORM_TOOL_CLASS (parent_class)->prepare (tr_tool); + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); - tr_tool->trans_info[PIVOT_X] = (gdouble) (tr_tool->x1 + tr_tool->x2) / 2.0; - tr_tool->trans_info[PIVOT_Y] = (gdouble) (tr_tool->y1 + tr_tool->y2) / 2.0; + GIMP_TRANSFORM_GRID_TOOL_CLASS (parent_class)->prepare (tg_tool); - tr_tool->trans_info[X0] = (gdouble) tr_tool->x1; - tr_tool->trans_info[Y0] = (gdouble) tr_tool->y1; - tr_tool->trans_info[X1] = (gdouble) tr_tool->x2; - tr_tool->trans_info[Y1] = (gdouble) tr_tool->y1; - tr_tool->trans_info[X2] = (gdouble) tr_tool->x1; - tr_tool->trans_info[Y2] = (gdouble) tr_tool->y2; - tr_tool->trans_info[X3] = (gdouble) tr_tool->x2; - tr_tool->trans_info[Y3] = (gdouble) tr_tool->y2; + tg_tool->trans_info[PIVOT_X] = (gdouble) (tr_tool->x1 + tr_tool->x2) / 2.0; + tg_tool->trans_info[PIVOT_Y] = (gdouble) (tr_tool->y1 + tr_tool->y2) / 2.0; + + tg_tool->trans_info[X0] = (gdouble) tr_tool->x1; + tg_tool->trans_info[Y0] = (gdouble) tr_tool->y1; + tg_tool->trans_info[X1] = (gdouble) tr_tool->x2; + tg_tool->trans_info[Y1] = (gdouble) tr_tool->y1; + tg_tool->trans_info[X2] = (gdouble) tr_tool->x1; + tg_tool->trans_info[Y2] = (gdouble) tr_tool->y2; + tg_tool->trans_info[X3] = (gdouble) tr_tool->x2; + tg_tool->trans_info[Y3] = (gdouble) tr_tool->y2; } static GimpToolWidget * -gimp_unified_transform_tool_get_widget (GimpTransformTool *tr_tool) +gimp_unified_transform_tool_get_widget (GimpTransformGridTool *tg_tool) { - GimpTool *tool = GIMP_TOOL (tr_tool); - GimpDisplayShell *shell = gimp_display_get_shell (tool->display); - GimpToolWidget *widget; + GimpTool *tool = GIMP_TOOL (tg_tool); + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + GimpDisplayShell *shell = gimp_display_get_shell (tool->display); + GimpToolWidget *widget; widget = gimp_tool_transform_grid_new (shell, &tr_tool->transform, @@ -161,16 +172,18 @@ gimp_unified_transform_tool_get_widget (GimpTransformTool *tr_tool) g_signal_connect (widget, "changed", G_CALLBACK (gimp_unified_transform_tool_widget_changed), - tr_tool); + tg_tool); return widget; } static void -gimp_unified_transform_tool_recalc_matrix (GimpTransformTool *tr_tool, - GimpToolWidget *widget) +gimp_unified_transform_tool_recalc_matrix (GimpTransformGridTool *tg_tool, + GimpToolWidget *widget) { - GIMP_TRANSFORM_TOOL_CLASS (parent_class)->recalc_matrix (tr_tool, widget); + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + + GIMP_TRANSFORM_GRID_TOOL_CLASS (parent_class)->recalc_matrix (tg_tool, widget); if (widget) g_object_set (widget, @@ -179,68 +192,64 @@ gimp_unified_transform_tool_recalc_matrix (GimpTransformTool *tr_tool, "y1", (gdouble) tr_tool->y1, "x2", (gdouble) tr_tool->x2, "y2", (gdouble) tr_tool->y2, - "pivot-x", tr_tool->trans_info[PIVOT_X], - "pivot-y", tr_tool->trans_info[PIVOT_Y], + "pivot-x", tg_tool->trans_info[PIVOT_X], + "pivot-y", tg_tool->trans_info[PIVOT_Y], NULL); } -static gchar * -gimp_unified_transform_tool_get_undo_desc (GimpTransformTool *tr_tool) -{ - return g_strdup (C_("undo-type", "Unified Transform")); -} - static void gimp_unified_transform_tool_recalc_points (GimpGenericTransformTool *generic, GimpToolWidget *widget) { - GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (generic); + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (generic); + GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (generic); generic->input_points[0] = (GimpVector2) {tr_tool->x1, tr_tool->y1}; generic->input_points[1] = (GimpVector2) {tr_tool->x2, tr_tool->y1}; generic->input_points[2] = (GimpVector2) {tr_tool->x1, tr_tool->y2}; generic->input_points[3] = (GimpVector2) {tr_tool->x2, tr_tool->y2}; - generic->output_points[0] = (GimpVector2) {tr_tool->trans_info[X0], - tr_tool->trans_info[Y0]}; - generic->output_points[1] = (GimpVector2) {tr_tool->trans_info[X1], - tr_tool->trans_info[Y1]}; - generic->output_points[2] = (GimpVector2) {tr_tool->trans_info[X2], - tr_tool->trans_info[Y2]}; - generic->output_points[3] = (GimpVector2) {tr_tool->trans_info[X3], - tr_tool->trans_info[Y3]}; + generic->output_points[0] = (GimpVector2) {tg_tool->trans_info[X0], + tg_tool->trans_info[Y0]}; + generic->output_points[1] = (GimpVector2) {tg_tool->trans_info[X1], + tg_tool->trans_info[Y1]}; + generic->output_points[2] = (GimpVector2) {tg_tool->trans_info[X2], + tg_tool->trans_info[Y2]}; + generic->output_points[3] = (GimpVector2) {tg_tool->trans_info[X3], + tg_tool->trans_info[Y3]}; } static void -gimp_unified_transform_tool_widget_changed (GimpToolWidget *widget, - GimpTransformTool *tr_tool) +gimp_unified_transform_tool_widget_changed (GimpToolWidget *widget, + GimpTransformGridTool *tg_tool) { - GimpMatrix3 *transform; + GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool); + GimpMatrix3 *transform; g_object_get (widget, "transform", &transform, - "pivot-x", &tr_tool->trans_info[PIVOT_X], - "pivot-y", &tr_tool->trans_info[PIVOT_Y], + "pivot-x", &tg_tool->trans_info[PIVOT_X], + "pivot-y", &tg_tool->trans_info[PIVOT_Y], NULL); gimp_matrix3_transform_point (transform, tr_tool->x1, tr_tool->y1, - &tr_tool->trans_info[X0], - &tr_tool->trans_info[Y0]); + &tg_tool->trans_info[X0], + &tg_tool->trans_info[Y0]); gimp_matrix3_transform_point (transform, tr_tool->x2, tr_tool->y1, - &tr_tool->trans_info[X1], - &tr_tool->trans_info[Y1]); + &tg_tool->trans_info[X1], + &tg_tool->trans_info[Y1]); gimp_matrix3_transform_point (transform, tr_tool->x1, tr_tool->y2, - &tr_tool->trans_info[X2], - &tr_tool->trans_info[Y2]); + &tg_tool->trans_info[X2], + &tg_tool->trans_info[Y2]); gimp_matrix3_transform_point (transform, tr_tool->x2, tr_tool->y2, - &tr_tool->trans_info[X3], - &tr_tool->trans_info[Y3]); + &tg_tool->trans_info[X3], + &tg_tool->trans_info[Y3]); g_free (transform); - gimp_transform_tool_recalc_matrix (tr_tool, NULL); + gimp_transform_grid_tool_recalc_matrix (tg_tool, NULL); } diff --git a/app/tools/tools-types.h b/app/tools/tools-types.h index 1986e57b24..aa9624afcb 100644 --- a/app/tools/tools-types.h +++ b/app/tools/tools-types.h @@ -36,6 +36,7 @@ typedef struct _GimpDrawTool GimpDrawTool; typedef struct _GimpFilterTool GimpFilterTool; typedef struct _GimpGenericTransformTool GimpGenericTransformTool; typedef struct _GimpPaintTool GimpPaintTool; +typedef struct _GimpTransformGridTool GimpTransformGridTool; typedef struct _GimpTransformTool GimpTransformTool; typedef struct _GimpColorOptions GimpColorOptions; diff --git a/po/POTFILES.in b/po/POTFILES.in index 784df9effc..7fc841798a 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -485,6 +485,8 @@ app/tools/gimptexttool.c app/tools/gimptexttool-editor.c app/tools/gimpthresholdtool.c app/tools/gimptool.c +app/tools/gimptransformgridoptions.c +app/tools/gimptransformgridtool.c app/tools/gimptransformoptions.c app/tools/gimptransformtool.c app/tools/gimpunifiedtransformtool.c