[gimp] app: implement the crop tool using GimpToolRectangle



commit 87e6de78ad27e6f4c1db285827e061dab86a592e
Author: Michael Natterer <mitch gimp org>
Date:   Mon Jun 26 19:18:17 2017 +0200

    app: implement the crop tool using GimpToolRectangle
    
    GimpRectangleTool users down by one...

 app/tools/gimpcroptool.c |  529 +++++++++++++++++++++++++++++++++++-----------
 app/tools/gimpcroptool.h |    7 +-
 2 files changed, 406 insertions(+), 130 deletions(-)
---
diff --git a/app/tools/gimpcroptool.c b/app/tools/gimpcroptool.c
index e2810d8..ace1c6b 100644
--- a/app/tools/gimpcroptool.c
+++ b/app/tools/gimpcroptool.c
@@ -33,18 +33,17 @@
 #include "widgets/gimphelp-ids.h"
 
 #include "display/gimpdisplay.h"
+#include "display/gimpdisplayshell.h"
+#include "display/gimptoolrectangle.h"
 
-#include "gimprectangleoptions.h"
-#include "gimprectangletool.h"
 #include "gimpcropoptions.h"
 #include "gimpcroptool.h"
+#include "gimprectangleoptions.h"
 #include "gimptoolcontrol.h"
 
 #include "gimp-intl.h"
 
 
-static void      gimp_crop_tool_rectangle_tool_iface_init (GimpRectangleToolInterface *iface);
-
 static void      gimp_crop_tool_constructed               (GObject              *object);
 
 static void      gimp_crop_tool_control                   (GimpTool             *tool,
@@ -62,43 +61,75 @@ static void      gimp_crop_tool_button_release            (GimpTool
                                                            GdkModifierType       state,
                                                            GimpButtonReleaseType release_type,
                                                            GimpDisplay          *display);
+static void     gimp_crop_tool_motion                     (GimpTool             *tool,
+                                                           const GimpCoords     *coords,
+                                                           guint32               time,
+                                                           GdkModifierType       state,
+                                                           GimpDisplay          *display);
+static gboolean  gimp_crop_tool_key_press                 (GimpTool             *tool,
+                                                           GdkEventKey          *kevent,
+                                                           GimpDisplay          *display);
 static void      gimp_crop_tool_active_modifier_key       (GimpTool             *tool,
                                                            GdkModifierType       key,
                                                            gboolean              press,
                                                            GdkModifierType       state,
                                                            GimpDisplay          *display);
+static void      gimp_crop_tool_oper_update               (GimpTool             *tool,
+                                                           const GimpCoords     *coords,
+                                                           GdkModifierType       state,
+                                                           gboolean              proximity,
+                                                           GimpDisplay          *display);
 static void      gimp_crop_tool_cursor_update             (GimpTool             *tool,
                                                            const GimpCoords     *coords,
                                                            GdkModifierType       state,
                                                            GimpDisplay          *display);
+static void      gimp_crop_tool_options_notify            (GimpTool             *tool,
+                                                           GimpToolOptions      *options,
+                                                           const GParamSpec     *pspec);
 
 static void      gimp_crop_tool_draw                      (GimpDrawTool         *draw_tool);
 
-static gboolean  gimp_crop_tool_execute                   (GimpRectangleTool    *rectangle,
+static void      gimp_crop_tool_rectangle_changed         (GimpToolWidget       *rectangle,
+                                                           GimpCropTool         *crop_tool);
+static void      gimp_crop_tool_rectangle_response        (GimpToolWidget       *rectangle,
+                                                           gint                  response_id,
+                                                           GimpCropTool         *crop_tool);
+static void      gimp_crop_tool_rectangle_status          (GimpToolWidget       *rectangle,
+                                                           const gchar          *status,
+                                                           GimpCropTool         *crop_tool);
+static void      gimp_crop_tool_rectangle_status_coords   (GimpToolWidget       *rectangle,
+                                                           const gchar          *title,
+                                                           gdouble               x,
+                                                           const gchar          *separator,
+                                                           gdouble               y,
+                                                           const gchar          *help,
+                                                           GimpCropTool         *crop_tool);
+static void      gimp_crop_tool_rectangle_snap_offsets    (GimpToolRectangle    *rectangle,
                                                            gint                  x,
                                                            gint                  y,
-                                                           gint                  w,
-                                                           gint                  h);
+                                                           gint                  width,
+                                                           gint                  height,
+                                                           GimpCropTool         *crop_tool);
+static void      gimp_crop_tool_rectangle_change_complete (GimpToolRectangle    *rectangle,
+                                                           GimpCropTool         *crop_tool);
+
+static void      gimp_crop_tool_commit                    (GimpCropTool         *crop_tool);
+static void      gimp_crop_tool_halt                      (GimpCropTool         *crop_tool);
 
 static void      gimp_crop_tool_update_option_defaults    (GimpCropTool         *crop_tool,
                                                            gboolean              ignore_pending);
 static GimpRectangleConstraint
                  gimp_crop_tool_get_constraint            (GimpCropTool         *crop_tool);
 
-static void      gimp_crop_tool_options_notify            (GimpCropOptions      *options,
-                                                           GParamSpec           *pspec,
-                                                           GimpCropTool         *crop_tool);
 static void      gimp_crop_tool_image_changed             (GimpCropTool         *crop_tool,
                                                            GimpImage            *image,
                                                            GimpContext          *context);
 static void      gimp_crop_tool_image_size_changed        (GimpCropTool         *crop_tool);
-static void      gimp_crop_tool_cancel                    (GimpRectangleTool    *rect_tool);
-static gboolean  gimp_crop_tool_rectangle_change_complete (GimpRectangleTool    *rect_tool);
 
+static void      gimp_crop_tool_auto_shrink               (GimpCropTool         *crop_tool);
 
-G_DEFINE_TYPE_WITH_CODE (GimpCropTool, gimp_crop_tool, GIMP_TYPE_DRAW_TOOL,
-                         G_IMPLEMENT_INTERFACE (GIMP_TYPE_RECTANGLE_TOOL,
-                                                gimp_crop_tool_rectangle_tool_iface_init));
+
+G_DEFINE_TYPE (GimpCropTool, gimp_crop_tool, GIMP_TYPE_DRAW_TOOL)
 
 #define parent_class gimp_crop_tool_parent_class
 
@@ -130,29 +161,18 @@ gimp_crop_tool_class_init (GimpCropToolClass *klass)
   GimpDrawToolClass *draw_tool_class = GIMP_DRAW_TOOL_CLASS (klass);
 
   object_class->constructed       = gimp_crop_tool_constructed;
-  object_class->set_property      = gimp_rectangle_tool_set_property;
-  object_class->get_property      = gimp_rectangle_tool_get_property;
 
   tool_class->control             = gimp_crop_tool_control;
   tool_class->button_press        = gimp_crop_tool_button_press;
   tool_class->button_release      = gimp_crop_tool_button_release;
-  tool_class->motion              = gimp_rectangle_tool_motion;
-  tool_class->key_press           = gimp_rectangle_tool_key_press;
+  tool_class->motion              = gimp_crop_tool_motion;
+  tool_class->key_press           = gimp_crop_tool_key_press;
   tool_class->active_modifier_key = gimp_crop_tool_active_modifier_key;
-  tool_class->oper_update         = gimp_rectangle_tool_oper_update;
+  tool_class->oper_update         = gimp_crop_tool_oper_update;
   tool_class->cursor_update       = gimp_crop_tool_cursor_update;
+  tool_class->options_notify      = gimp_crop_tool_options_notify;
 
   draw_tool_class->draw           = gimp_crop_tool_draw;
-
-  gimp_rectangle_tool_install_properties (object_class);
-}
-
-static void
-gimp_crop_tool_rectangle_tool_iface_init (GimpRectangleToolInterface *iface)
-{
-  iface->execute                   = gimp_crop_tool_execute;
-  iface->cancel                    = gimp_crop_tool_cancel;
-  iface->rectangle_change_complete = gimp_crop_tool_rectangle_change_complete;
 }
 
 static void
@@ -164,29 +184,22 @@ gimp_crop_tool_init (GimpCropTool *crop_tool)
   gimp_tool_control_set_precision   (tool->control,
                                      GIMP_CURSOR_PRECISION_PIXEL_BORDER);
   gimp_tool_control_set_tool_cursor (tool->control, GIMP_TOOL_CURSOR_CROP);
-
-  gimp_rectangle_tool_init (GIMP_RECTANGLE_TOOL (crop_tool));
-
-  crop_tool->current_image = NULL;
 }
 
 static void
 gimp_crop_tool_constructed (GObject *object)
 {
   GimpCropTool    *crop_tool = GIMP_CROP_TOOL (object);
-  GimpCropOptions *options;
-  GimpContext     *gimp_context;
+  GimpContext     *context;
   GimpToolInfo    *tool_info;
 
   G_OBJECT_CLASS (parent_class)->constructed (object);
 
-  gimp_rectangle_tool_constructor (object);
-
   tool_info = GIMP_TOOL (crop_tool)->tool_info;
 
-  gimp_context = gimp_get_user_context (tool_info->gimp);
+  context = gimp_get_user_context (tool_info->gimp);
 
-  g_signal_connect_object (gimp_context, "image-changed",
+  g_signal_connect_object (context, "image-changed",
                            G_CALLBACK (gimp_crop_tool_image_changed),
                            crop_tool,
                            G_CONNECT_SWAPPED);
@@ -195,24 +208,8 @@ gimp_crop_tool_constructed (GObject *object)
    * image.
    */
   gimp_crop_tool_image_changed (crop_tool,
-                                gimp_context_get_image (gimp_context),
-                                gimp_context);
-
-
-  options = GIMP_CROP_TOOL_GET_OPTIONS (object);
-
-  g_signal_connect_object (options, "notify::layer-only",
-                           G_CALLBACK (gimp_crop_tool_options_notify),
-                           object, 0);
-
-  g_signal_connect_object (options, "notify::allow-growing",
-                           G_CALLBACK (gimp_crop_tool_options_notify),
-                           object, 0);
-
-  gimp_rectangle_tool_set_constraint (GIMP_RECTANGLE_TOOL (object),
-                                      gimp_crop_tool_get_constraint (crop_tool));
-
-  gimp_crop_tool_update_option_defaults (crop_tool, FALSE);
+                                gimp_context_get_image (context),
+                                context);
 }
 
 static void
@@ -220,7 +217,22 @@ gimp_crop_tool_control (GimpTool       *tool,
                         GimpToolAction  action,
                         GimpDisplay    *display)
 {
-  gimp_rectangle_tool_control (tool, action, display);
+  GimpCropTool *crop_tool = GIMP_CROP_TOOL (tool);
+
+  switch (action)
+    {
+    case GIMP_TOOL_ACTION_PAUSE:
+    case GIMP_TOOL_ACTION_RESUME:
+      break;
+
+    case GIMP_TOOL_ACTION_HALT:
+      gimp_crop_tool_halt (crop_tool);
+      break;
+
+    case GIMP_TOOL_ACTION_COMMIT:
+      gimp_crop_tool_commit (crop_tool);
+      break;
+    }
 
   GIMP_TOOL_CLASS (parent_class)->control (tool, action, display);
 }
@@ -233,12 +245,95 @@ gimp_crop_tool_button_press (GimpTool            *tool,
                              GimpButtonPressType  press_type,
                              GimpDisplay         *display)
 {
+  GimpCropTool *crop_tool = GIMP_CROP_TOOL (tool);
+
   if (tool->display && display != tool->display)
     gimp_tool_control (tool, GIMP_TOOL_ACTION_COMMIT, tool->display);
 
-  gimp_tool_control_activate (tool->control);
+  if (! tool->display)
+    {
+      static const gchar *properties[] =
+      {
+        "highlight",
+        "guide",
+        "x",
+        "y",
+        "width",
+        "height",
+        "fixed-rule-active",
+        "fixed-rule",
+        "desired-fixed-width",
+        "desired-fixed-height",
+        "desired-fixed-size-width",
+        "desired-fixed-size-height",
+        "aspect-numerator",
+        "aspect-denominator",
+        "fixed-center"
+      };
+
+      GimpDisplayShell *shell   = gimp_display_get_shell (display);
+      GimpCropOptions  *options = GIMP_CROP_TOOL_GET_OPTIONS (crop_tool);
+      GimpToolWidget   *widget;
+      gint              i;
+
+      tool->display = display;
+
+      crop_tool->rectangle = widget = gimp_tool_rectangle_new (shell);
+
+      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_crop_tool_rectangle_changed),
+                        crop_tool);
+      g_signal_connect (widget, "response",
+                        G_CALLBACK (gimp_crop_tool_rectangle_response),
+                        crop_tool);
+      g_signal_connect (widget, "status",
+                        G_CALLBACK (gimp_crop_tool_rectangle_status),
+                        crop_tool);
+      g_signal_connect (widget, "status-coords",
+                        G_CALLBACK (gimp_crop_tool_rectangle_status_coords),
+                        crop_tool);
+      g_signal_connect (widget, "snap-offsets",
+                        G_CALLBACK (gimp_crop_tool_rectangle_snap_offsets),
+                        crop_tool);
+      g_signal_connect (widget, "change-complete",
+                        G_CALLBACK (gimp_crop_tool_rectangle_change_complete),
+                        crop_tool);
+
+      gimp_rectangle_options_connect (GIMP_RECTANGLE_OPTIONS (options),
+                                      gimp_display_get_image (shell->display),
+                                      G_CALLBACK (gimp_crop_tool_auto_shrink),
+                                      crop_tool);
+
+      gimp_tool_rectangle_set_constraint (GIMP_TOOL_RECTANGLE (widget),
+                                          gimp_crop_tool_get_constraint (crop_tool));
+
+      gimp_crop_tool_update_option_defaults (crop_tool, FALSE);
+
+      gimp_tool_widget_hover (crop_tool->rectangle, coords, state, TRUE);
+
+      /* HACK: force CREATING on a newly created rectangle; otherwise,
+       * the above binding of properties would cause the rectangle to
+       * start with the size from tool options.
+       */
+      gimp_tool_rectangle_set_function (GIMP_TOOL_RECTANGLE (crop_tool->rectangle),
+                                        GIMP_TOOL_RECTANGLE_CREATING);
+
+      gimp_draw_tool_start (GIMP_DRAW_TOOL (tool), display);
+    }
 
-  gimp_rectangle_tool_button_press (tool, coords, time, state, display);
+  if (gimp_tool_widget_button_press (crop_tool->rectangle, coords, time, state,
+                                     press_type))
+    {
+      crop_tool->grab_widget = crop_tool->rectangle;
+    }
+
+  gimp_tool_control_activate (tool->control);
 }
 
 static void
@@ -249,16 +344,48 @@ gimp_crop_tool_button_release (GimpTool              *tool,
                                GimpButtonReleaseType  release_type,
                                GimpDisplay           *display)
 {
+  GimpCropTool *crop_tool = GIMP_CROP_TOOL (tool);
+
+  gimp_tool_control_halt (tool->control);
+
   gimp_tool_push_status (tool, display, _("Click or press Enter to crop"));
 
-  gimp_rectangle_tool_button_release (tool,
-                                      coords,
-                                      time,
-                                      state,
-                                      release_type,
-                                      display);
+  if (crop_tool->grab_widget)
+    {
+      gimp_tool_widget_button_release (crop_tool->grab_widget,
+                                       coords, time, state, release_type);
+      crop_tool->grab_widget = NULL;
+    }
+}
 
-  gimp_tool_control_halt (tool->control);
+static void
+gimp_crop_tool_motion (GimpTool         *tool,
+                       const GimpCoords *coords,
+                       guint32           time,
+                       GdkModifierType   state,
+                       GimpDisplay      *display)
+{
+  GimpCropTool *crop_tool = GIMP_CROP_TOOL (tool);
+
+  if (crop_tool->grab_widget)
+    {
+      gimp_tool_widget_motion (crop_tool->grab_widget, coords, time, state);
+    }
+}
+
+static gboolean
+gimp_crop_tool_key_press (GimpTool    *tool,
+                          GdkEventKey *kevent,
+                          GimpDisplay *display)
+{
+  GimpCropTool *crop_tool = GIMP_CROP_TOOL (tool);
+
+  if (crop_tool->rectangle && display == tool->display)
+    {
+      return gimp_tool_widget_key_press (crop_tool->rectangle, kevent);
+    }
+
+  return FALSE;
 }
 
 static void
@@ -268,10 +395,28 @@ gimp_crop_tool_active_modifier_key (GimpTool        *tool,
                                     GdkModifierType  state,
                                     GimpDisplay     *display)
 {
-  GIMP_TOOL_CLASS (parent_class)->active_modifier_key (tool, key, press, state,
-                                                       display);
+  GimpCropTool *crop_tool = GIMP_CROP_TOOL (tool);
 
-  gimp_rectangle_tool_active_modifier_key (tool, key, press, state, display);
+  if (crop_tool->rectangle)
+    {
+      gimp_tool_widget_motion_modifier (crop_tool->rectangle,
+                                        key, press, state);
+    }
+}
+
+static void
+gimp_crop_tool_oper_update (GimpTool         *tool,
+                            const GimpCoords *coords,
+                            GdkModifierType   state,
+                            gboolean          proximity,
+                            GimpDisplay      *display)
+{
+  GimpCropTool *crop_tool = GIMP_CROP_TOOL (tool);
+
+  if (crop_tool->rectangle && display == tool->display)
+    {
+      gimp_tool_widget_hover (crop_tool->rectangle, coords, state, proximity);
+    }
 }
 
 static void
@@ -280,27 +425,149 @@ gimp_crop_tool_cursor_update (GimpTool         *tool,
                               GdkModifierType   state,
                               GimpDisplay      *display)
 {
-  gimp_rectangle_tool_cursor_update (tool, coords, state, display);
+  GimpCropTool       *crop_tool = GIMP_CROP_TOOL (tool);
+  GimpCursorType      cursor    = GIMP_CURSOR_CROSSHAIR_SMALL;
+  GimpCursorModifier  modifier  = GIMP_CURSOR_MODIFIER_NONE;
+
+  if (crop_tool->rectangle && display == tool->display)
+    {
+      gimp_tool_widget_get_cursor (crop_tool->rectangle, coords, state,
+                                   &cursor, NULL, &modifier);
+    }
+
+  gimp_tool_control_set_cursor          (tool->control, cursor);
+  gimp_tool_control_set_cursor_modifier (tool->control, modifier);
 
   GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
 }
 
 static void
+gimp_crop_tool_options_notify (GimpTool         *tool,
+                               GimpToolOptions  *options,
+                               const GParamSpec *pspec)
+{
+  GimpCropTool *crop_tool = GIMP_CROP_TOOL (tool);
+
+  if (crop_tool->rectangle)
+    {
+      if (! strcmp (pspec->name, "layer-only") ||
+          ! strcmp (pspec->name, "allow-growing"))
+        {
+          gimp_tool_rectangle_set_constraint (GIMP_TOOL_RECTANGLE (crop_tool->rectangle),
+                                              gimp_crop_tool_get_constraint (crop_tool));
+        }
+    }
+}
+
+static void
 gimp_crop_tool_draw (GimpDrawTool *draw_tool)
 {
-  gimp_rectangle_tool_draw (draw_tool, NULL);
+  GimpCropTool *crop_tool = GIMP_CROP_TOOL (draw_tool);
+
+  if (crop_tool->rectangle)
+    {
+      GimpCanvasItem *item = gimp_tool_widget_get_item (crop_tool->rectangle);
+
+      gimp_draw_tool_add_item (draw_tool, item);
+    }
 }
 
-static gboolean
-gimp_crop_tool_execute (GimpRectangleTool  *rectangle,
-                        gint                x,
-                        gint                y,
-                        gint                w,
-                        gint                h)
+static void
+gimp_crop_tool_rectangle_changed (GimpToolWidget *rectangle,
+                                  GimpCropTool   *crop_tool)
+{
+}
+
+static void
+gimp_crop_tool_rectangle_response (GimpToolWidget *rectangle,
+                                   gint            response_id,
+                                   GimpCropTool   *crop_tool)
+{
+  GimpTool *tool = GIMP_TOOL (crop_tool);
+
+  switch (response_id)
+    {
+    case GIMP_TOOL_WIDGET_RESPONSE_CONFIRM:
+      gimp_tool_control (tool, GIMP_TOOL_ACTION_COMMIT, tool->display);
+      break;
+
+    case GIMP_TOOL_WIDGET_RESPONSE_CANCEL:
+      gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, tool->display);
+      break;
+    }
+}
+
+static void
+gimp_crop_tool_rectangle_status (GimpToolWidget *rectangle,
+                                 const gchar    *status,
+                                 GimpCropTool   *crop_tool)
 {
-  GimpTool        *tool    = GIMP_TOOL (rectangle);
+  GimpTool *tool = GIMP_TOOL (crop_tool);
+
+  if (status)
+    {
+      gimp_tool_replace_status (tool, tool->display, "%s", status);
+    }
+  else
+    {
+      gimp_tool_pop_status (tool, tool->display);
+    }
+}
+
+static void
+gimp_crop_tool_rectangle_status_coords (GimpToolWidget *rectangle,
+                                        const gchar    *title,
+                                        gdouble         x,
+                                        const gchar    *separator,
+                                        gdouble         y,
+                                        const gchar    *help,
+                                        GimpCropTool   *crop_tool)
+{
+  GimpTool *tool = GIMP_TOOL (crop_tool);
+
+  gimp_tool_pop_status (tool, tool->display);
+  gimp_tool_push_status_coords (tool, tool->display,
+                                gimp_tool_control_get_precision (tool->control),
+                                title, x, separator, y, help);
+}
+
+static void
+gimp_crop_tool_rectangle_snap_offsets (GimpToolRectangle *rectangle,
+                                       gint               offset_x,
+                                       gint               offset_y,
+                                       gint               width,
+                                       gint               height,
+                                       GimpCropTool      *crop_tool)
+{
+  GimpTool *tool = GIMP_TOOL (crop_tool);
+
+  gimp_tool_control_set_snap_offsets (tool->control,
+                                      offset_x, offset_y,
+                                      width, height);
+}
+
+static void
+gimp_crop_tool_rectangle_change_complete (GimpToolRectangle *rectangle,
+                                          GimpCropTool      *crop_tool)
+{
+  gimp_crop_tool_update_option_defaults (crop_tool, FALSE);
+}
+
+static void
+gimp_crop_tool_commit (GimpCropTool *crop_tool)
+{
+  GimpTool        *tool    = GIMP_TOOL (crop_tool);
   GimpCropOptions *options = GIMP_CROP_TOOL_GET_OPTIONS (tool);
   GimpImage       *image   = gimp_display_get_image (tool->display);
+  gdouble          x, y;
+  gdouble          x2, y2;
+  gint             w, h;
+
+  gimp_tool_rectangle_get_public_rect (GIMP_TOOL_RECTANGLE (crop_tool->rectangle),
+                                       &x, &y, &x2, &y2);
+
+  w = x2 - x;
+  h = y2 - y;
 
   gimp_tool_pop_status (tool, tool->display);
 
@@ -316,14 +583,14 @@ gimp_crop_tool_execute (GimpRectangleTool  *rectangle,
             {
               gimp_tool_message_literal (tool, tool->display,
                                          _("There is no active layer to crop."));
-              return FALSE;
+              return;
             }
 
           if (gimp_item_is_content_locked (GIMP_ITEM (layer)))
             {
               gimp_tool_message_literal (tool, tool->display,
                                          _("The active layer's pixels are locked."));
-              return FALSE;
+              return;
             }
 
           gimp_item_get_offset (GIMP_ITEM (layer), &off_x, &off_y);
@@ -343,25 +610,35 @@ gimp_crop_tool_execute (GimpRectangleTool  *rectangle,
         }
 
       gimp_image_flush (image);
-
-      return TRUE;
     }
 
-  return TRUE;
+  gimp_crop_tool_halt (crop_tool);
 }
 
-/**
- * gimp_crop_tool_rectangle_change_complete:
- * @rectangle:
- *
- * Returns:
- **/
-static gboolean
-gimp_crop_tool_rectangle_change_complete (GimpRectangleTool *rectangle)
+static void
+gimp_crop_tool_halt (GimpCropTool *crop_tool)
 {
-  gimp_crop_tool_update_option_defaults (GIMP_CROP_TOOL (rectangle), FALSE);
+  GimpTool         *tool    = GIMP_TOOL (crop_tool);
+  GimpCropOptions  *options = GIMP_CROP_TOOL_GET_OPTIONS (crop_tool);
 
-  return TRUE;
+  if (tool->display)
+    {
+      GimpDisplayShell *shell = gimp_display_get_shell (tool->display);
+
+      gimp_display_shell_set_highlight (shell, NULL);
+
+      gimp_rectangle_options_disconnect (GIMP_RECTANGLE_OPTIONS (options),
+                                         G_CALLBACK (gimp_crop_tool_auto_shrink),
+                                         crop_tool);
+    }
+
+  if (gimp_draw_tool_is_active (GIMP_DRAW_TOOL (tool)))
+    gimp_draw_tool_stop (GIMP_DRAW_TOOL (tool));
+
+  g_clear_object (&crop_tool->rectangle);
+
+  tool->display  = NULL;
+  tool->drawable = NULL;
 }
 
 /**
@@ -376,27 +653,28 @@ static void
 gimp_crop_tool_update_option_defaults (GimpCropTool *crop_tool,
                                        gboolean      ignore_pending)
 {
-  GimpTool             *tool;
-  GimpRectangleTool    *rectangle_tool;
-  GimpRectangleOptions *rectangle_options;
+  GimpTool             *tool      = GIMP_TOOL (crop_tool);
+  GimpToolRectangle    *rectangle = GIMP_TOOL_RECTANGLE (crop_tool->rectangle);
+  GimpRectangleOptions *options;
+
+  options = GIMP_RECTANGLE_OPTIONS (GIMP_TOOL_GET_OPTIONS (tool));
 
-  tool              = GIMP_TOOL (crop_tool);
-  rectangle_tool    = GIMP_RECTANGLE_TOOL (tool);
-  rectangle_options = GIMP_RECTANGLE_TOOL_GET_OPTIONS (rectangle_tool);
+  if (! rectangle)
+    return;
 
-  if (tool->display != NULL && !ignore_pending)
+  if (tool->display && ! ignore_pending)
     {
       /* There is a pending rectangle and we should not ignore it, so
        * set default Fixed: Aspect ratio to the same as the current
        * pending rectangle width/height.
        */
 
-      gimp_rectangle_tool_pending_size_set (rectangle_tool,
-                                            G_OBJECT (rectangle_options),
+      gimp_tool_rectangle_pending_size_set (rectangle,
+                                            G_OBJECT (options),
                                             "default-aspect-numerator",
                                             "default-aspect-denominator");
 
-      g_object_set (G_OBJECT (rectangle_options),
+      g_object_set (G_OBJECT (options),
                     "use-string-current", TRUE,
                     NULL);
     }
@@ -406,12 +684,12 @@ gimp_crop_tool_update_option_defaults (GimpCropTool *crop_tool,
        * ratio to that of the current image/layer.
        */
 
-      gimp_rectangle_tool_constraint_size_set (rectangle_tool,
-                                               G_OBJECT (rectangle_options),
+      gimp_tool_rectangle_constraint_size_set (rectangle,
+                                               G_OBJECT (options),
                                                "default-aspect-numerator",
                                                "default-aspect-denominator");
 
-      g_object_set (G_OBJECT (rectangle_options),
+      g_object_set (G_OBJECT (options),
                     "use-string-current", FALSE,
                     NULL);
     }
@@ -434,15 +712,6 @@ gimp_crop_tool_get_constraint (GimpCropTool *crop_tool)
 }
 
 static void
-gimp_crop_tool_options_notify (GimpCropOptions *options,
-                               GParamSpec      *pspec,
-                               GimpCropTool    *crop_tool)
-{
-  gimp_rectangle_tool_set_constraint (GIMP_RECTANGLE_TOOL (crop_tool),
-                                      gimp_crop_tool_get_constraint (crop_tool));
-}
-
-static void
 gimp_crop_tool_image_changed (GimpCropTool *crop_tool,
                               GimpImage    *image,
                               GimpContext  *context)
@@ -454,30 +723,34 @@ gimp_crop_tool_image_changed (GimpCropTool *crop_tool,
                                             NULL);
     }
 
-  if (image)
+  crop_tool->current_image = image;
+
+  if (crop_tool->current_image)
     {
-      g_signal_connect_object (image, "size-changed",
+      g_signal_connect_object (crop_tool->current_image, "size-changed",
                                G_CALLBACK (gimp_crop_tool_image_size_changed),
                                crop_tool,
                                G_CONNECT_SWAPPED);
     }
 
-  crop_tool->current_image = image;
-
-  gimp_crop_tool_update_option_defaults (GIMP_CROP_TOOL (crop_tool),
-                                         FALSE);
+  gimp_crop_tool_update_option_defaults (GIMP_CROP_TOOL (crop_tool), FALSE);
 }
 
 static void
 gimp_crop_tool_image_size_changed (GimpCropTool *crop_tool)
 {
-  gimp_crop_tool_update_option_defaults (crop_tool,
-                                         FALSE);
+  gimp_crop_tool_update_option_defaults (crop_tool, FALSE);
 }
 
 static void
-gimp_crop_tool_cancel (GimpRectangleTool *rect_tool)
+gimp_crop_tool_auto_shrink (GimpCropTool *crop_tool)
 {
-  gimp_crop_tool_update_option_defaults (GIMP_CROP_TOOL (rect_tool),
-                                         TRUE);
+  gboolean shrink_merged ;
+
+  g_object_get (gimp_tool_get_options (GIMP_TOOL (crop_tool)),
+                "shrink-merged", &shrink_merged,
+                NULL);
+
+  gimp_tool_rectangle_auto_shrink (GIMP_TOOL_RECTANGLE (crop_tool->rectangle),
+                                   shrink_merged);
 }
diff --git a/app/tools/gimpcroptool.h b/app/tools/gimpcroptool.h
index bd7dc34..3ba8422 100644
--- a/app/tools/gimpcroptool.h
+++ b/app/tools/gimpcroptool.h
@@ -37,9 +37,12 @@ typedef struct _GimpCropToolClass GimpCropToolClass;
 
 struct _GimpCropTool
 {
-  GimpDrawTool  parent_instance;
+  GimpDrawTool    parent_instance;
 
-  GimpImage    *current_image;
+  GimpImage      *current_image;
+
+  GimpToolWidget *rectangle;
+  GimpToolWidget *grab_widget;
 };
 
 struct _GimpCropToolClass


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]