[gimp/gimp-2-10] app: allow moving an intersecting pair of guides with the Move tool



commit 38e954ba253f5816749603851441b2221d92a6d8
Author: Ell <ell_se yahoo com>
Date:   Thu May 30 01:39:26 2019 -0400

    app: allow moving an intersecting pair of guides with the Move tool
    
    This commit adds support for moving together an intersecting pair
    of guides using the Move tool, by dragging the guides at their
    point of intersection.  This is useful when the guides are used to
    mark a point, rather than a pair of lines (e.g., as is the case for
    the mandala symmetry guides, which mark the symmetry's point of
    origin).
    
    Add gimp_image_pick_guides(), which can return a set of guides,
    rather than a single guide.  The API allows an arbitrary set of
    guides to be returned, but, in practice, at most two intersecting
    guides are returned, as per the above.
    
    In GimpMoveTool and GimpGuideTool, add support for moving multiple
    guides together, and, in GimpMoveTool, use gimp_image_pick_guides()
    to potentially pick multiple guides.
    
    (cherry picked from commit 1e95481feb432afc0589b264a3d1635f8caf3883)

 app/core/gimpimage-pick-item.c |  83 +++++++--
 app/core/gimpimage-pick-item.h |   6 +
 app/tools/gimpguidetool.c      | 410 ++++++++++++++++++++++++++++-------------
 app/tools/gimpguidetool.h      |  37 ++--
 app/tools/gimpmovetool.c       |  63 ++++---
 app/tools/gimpmovetool.h       |   2 +-
 6 files changed, 415 insertions(+), 186 deletions(-)
---
diff --git a/app/core/gimpimage-pick-item.c b/app/core/gimpimage-pick-item.c
index bdfa75bc89..b2257f37ab 100644
--- a/app/core/gimpimage-pick-item.c
+++ b/app/core/gimpimage-pick-item.c
@@ -235,20 +235,18 @@ gimp_image_pick_vectors (GimpImage *image,
   return ret;
 }
 
-GimpGuide *
-gimp_image_pick_guide (GimpImage *image,
-                       gdouble    x,
-                       gdouble    y,
-                       gdouble    epsilon_x,
-                       gdouble    epsilon_y)
+static GimpGuide *
+gimp_image_pick_guide_internal (GimpImage           *image,
+                                gdouble              x,
+                                gdouble              y,
+                                gdouble              epsilon_x,
+                                gdouble              epsilon_y,
+                                GimpOrientationType  orientation)
 {
   GList     *list;
   GimpGuide *ret     = NULL;
   gdouble    mindist = G_MAXDOUBLE;
 
-  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
-  g_return_val_if_fail (epsilon_x > 0 && epsilon_y > 0, NULL);
-
   for (list = GIMP_IMAGE_GET_PRIVATE (image)->guides;
        list;
        list = g_list_next (list))
@@ -260,33 +258,82 @@ gimp_image_pick_guide (GimpImage *image,
       switch (gimp_guide_get_orientation (guide))
         {
         case GIMP_ORIENTATION_HORIZONTAL:
-          dist = ABS (position - y);
-          if (dist < MIN (epsilon_y, mindist))
+          if (orientation == GIMP_ORIENTATION_HORIZONTAL ||
+              orientation == GIMP_ORIENTATION_UNKNOWN)
             {
-              mindist = dist;
-              ret = guide;
+              dist = ABS (position - y);
+              if (dist < MIN (epsilon_y, mindist))
+                {
+                  mindist = dist;
+                  ret = guide;
+                }
             }
           break;
 
         /* mindist always is in vertical resolution to make it comparable */
         case GIMP_ORIENTATION_VERTICAL:
-          dist = ABS (position - x);
-          if (dist < MIN (epsilon_x, mindist / epsilon_y * epsilon_x))
+          if (orientation == GIMP_ORIENTATION_VERTICAL ||
+              orientation == GIMP_ORIENTATION_UNKNOWN)
             {
-              mindist = dist * epsilon_y / epsilon_x;
-              ret = guide;
+              dist = ABS (position - x);
+              if (dist < MIN (epsilon_x, mindist / epsilon_y * epsilon_x))
+                {
+                  mindist = dist * epsilon_y / epsilon_x;
+                  ret = guide;
+                }
             }
           break;
 
         default:
           continue;
         }
-
     }
 
   return ret;
 }
 
+GimpGuide *
+gimp_image_pick_guide (GimpImage *image,
+                       gdouble    x,
+                       gdouble    y,
+                       gdouble    epsilon_x,
+                       gdouble    epsilon_y)
+{
+  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
+  g_return_val_if_fail (epsilon_x > 0 && epsilon_y > 0, NULL);
+
+  return gimp_image_pick_guide_internal (image, x, y, epsilon_x, epsilon_y,
+                                         GIMP_ORIENTATION_UNKNOWN);
+}
+
+GList *
+gimp_image_pick_guides (GimpImage *image,
+                        gdouble    x,
+                        gdouble    y,
+                        gdouble    epsilon_x,
+                        gdouble    epsilon_y)
+{
+  GimpGuide *guide;
+  GList     *result = NULL;
+
+  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
+  g_return_val_if_fail (epsilon_x > 0 && epsilon_y > 0, NULL);
+
+  guide = gimp_image_pick_guide_internal (image, x, y, epsilon_x, epsilon_y,
+                                          GIMP_ORIENTATION_HORIZONTAL);
+
+  if (guide)
+    result = g_list_append (result, guide);
+
+  guide = gimp_image_pick_guide_internal (image, x, y, epsilon_x, epsilon_y,
+                                          GIMP_ORIENTATION_VERTICAL);
+
+  if (guide)
+    result = g_list_append (result, guide);
+
+  return result;
+}
+
 GimpSamplePoint *
 gimp_image_pick_sample_point (GimpImage *image,
                               gdouble    x,
diff --git a/app/core/gimpimage-pick-item.h b/app/core/gimpimage-pick-item.h
index bf0d322a84..46da4ef1ad 100644
--- a/app/core/gimpimage-pick-item.h
+++ b/app/core/gimpimage-pick-item.h
@@ -41,6 +41,12 @@ GimpGuide       * gimp_image_pick_guide           (GimpImage *image,
                                                    gdouble    y,
                                                    gdouble    epsilon_x,
                                                    gdouble    epsilon_y);
+GList           * gimp_image_pick_guides          (GimpImage *image,
+                                                   gdouble    x,
+                                                   gdouble    y,
+                                                   gdouble    epsilon_x,
+                                                   gdouble    epsilon_y);
+
 GimpSamplePoint * gimp_image_pick_sample_point    (GimpImage *image,
                                                    gdouble    x,
                                                    gdouble    y,
diff --git a/app/tools/gimpguidetool.c b/app/tools/gimpguidetool.c
index 12a4c631b7..f52f9d28ba 100644
--- a/app/tools/gimpguidetool.c
+++ b/app/tools/gimpguidetool.c
@@ -28,6 +28,7 @@
 #include "core/gimpguide.h"
 #include "core/gimpimage.h"
 #include "core/gimpimage-guides.h"
+#include "core/gimpimage-undo.h"
 
 #include "display/gimpdisplay.h"
 #include "display/gimpdisplayshell.h"
@@ -48,6 +49,8 @@
 
 /*  local function prototypes  */
 
+static void   gimp_guide_tool_finalize       (GObject               *object);
+
 static void   gimp_guide_tool_button_release (GimpTool              *tool,
                                               const GimpCoords      *coords,
                                               guint32                time,
@@ -64,9 +67,13 @@ static void   gimp_guide_tool_draw           (GimpDrawTool          *draw_tool);
 
 static void   gimp_guide_tool_start          (GimpTool              *parent_tool,
                                               GimpDisplay           *display,
-                                              GimpGuide             *guide,
+                                              GList                 *guides,
                                               GimpOrientationType    orientation);
 
+static void   gimp_guide_tool_push_status    (GimpGuideTool         *guide_tool,
+                                              GimpDisplay           *display,
+                                              gboolean               remove_guides);
+
 
 G_DEFINE_TYPE (GimpGuideTool, gimp_guide_tool, GIMP_TYPE_DRAW_TOOL)
 
@@ -76,9 +83,12 @@ G_DEFINE_TYPE (GimpGuideTool, gimp_guide_tool, GIMP_TYPE_DRAW_TOOL)
 static void
 gimp_guide_tool_class_init (GimpGuideToolClass *klass)
 {
+  GObjectClass      *object_class    = G_OBJECT_CLASS (klass);
   GimpToolClass     *tool_class      = GIMP_TOOL_CLASS (klass);
   GimpDrawToolClass *draw_tool_class = GIMP_DRAW_TOOL_CLASS (klass);
 
+  object_class->finalize     = gimp_guide_tool_finalize;
+
   tool_class->button_release = gimp_guide_tool_button_release;
   tool_class->motion         = gimp_guide_tool_motion;
 
@@ -98,9 +108,22 @@ gimp_guide_tool_init (GimpGuideTool *guide_tool)
   gimp_tool_control_set_precision          (tool->control,
                                             GIMP_CURSOR_PRECISION_PIXEL_BORDER);
 
-  guide_tool->guide             = NULL;
-  guide_tool->guide_position    = GIMP_GUIDE_POSITION_UNDEFINED;
-  guide_tool->guide_orientation = GIMP_ORIENTATION_UNKNOWN;
+  guide_tool->guides   = NULL;
+  guide_tool->n_guides = 0;
+}
+
+static void
+gimp_guide_tool_finalize (GObject *object)
+{
+  GimpGuideTool *guide_tool = GIMP_GUIDE_TOOL (object);
+  gint           i;
+
+  for (i = 0; i < guide_tool->n_guides; i++)
+    g_clear_object (&guide_tool->guides[i].guide);
+
+  g_free (guide_tool->guides);
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
 static void
@@ -114,6 +137,7 @@ gimp_guide_tool_button_release (GimpTool              *tool,
   GimpGuideTool    *guide_tool = GIMP_GUIDE_TOOL (tool);
   GimpDisplayShell *shell      = gimp_display_get_shell (display);
   GimpImage        *image      = gimp_display_get_image (display);
+  gint              i;
 
   gimp_tool_pop_status (tool, display);
 
@@ -123,71 +147,107 @@ gimp_guide_tool_button_release (GimpTool              *tool,
 
   if (release_type == GIMP_BUTTON_RELEASE_CANCEL)
     {
-      /* custom guides are moved live */
-      if (guide_tool->guide_custom)
-        gimp_image_move_guide (image, guide_tool->guide,
-                               guide_tool->guide_old_position, TRUE);
+      for (i = 0; i < guide_tool->n_guides; i++)
+        {
+          GimpGuideToolGuide *guide = &guide_tool->guides[i];
+
+          /* custom guides are moved live */
+          if (guide->custom)
+            {
+              gimp_image_move_guide (image, guide->guide, guide->old_position,
+                                     TRUE);
+            }
+        }
     }
   else
     {
-      gint max_position;
+      gint     n_non_custom_guides = 0;
+      gboolean remove_guides       = FALSE;
 
-      if (guide_tool->guide_orientation == GIMP_ORIENTATION_HORIZONTAL)
-        max_position = gimp_image_get_height (image);
-      else
-        max_position = gimp_image_get_width (image);
-
-      if (guide_tool->guide_position == GIMP_GUIDE_POSITION_UNDEFINED ||
-          guide_tool->guide_position <  0                             ||
-          guide_tool->guide_position > max_position)
+      for (i = 0; i < guide_tool->n_guides; i++)
         {
-          if (guide_tool->guide)
+          GimpGuideToolGuide *guide = &guide_tool->guides[i];
+          gint                max_position;
+
+          if (guide->orientation == GIMP_ORIENTATION_HORIZONTAL)
+            max_position = gimp_image_get_height (image);
+          else
+            max_position = gimp_image_get_width (image);
+
+          n_non_custom_guides += ! guide->custom;
+
+          if (guide->position == GIMP_GUIDE_POSITION_UNDEFINED ||
+              guide->position <  0                             ||
+              guide->position > max_position)
             {
-              gimp_image_remove_guide (image, guide_tool->guide, TRUE);
-              guide_tool->guide = NULL;
+              remove_guides = TRUE;
             }
         }
-      else
+
+      if (n_non_custom_guides > 1)
+        {
+          gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_GUIDE,
+                                       remove_guides ?
+                                         C_("undo-type", "Remove Guides") :
+                                         C_("undo-type", "Move Guides"));
+        }
+
+      for (i = 0; i < guide_tool->n_guides; i++)
         {
-          if (guide_tool->guide)
+          GimpGuideToolGuide *guide = &guide_tool->guides[i];
+
+          if (remove_guides)
             {
-              /* custom guides are moved live */
-              if (! guide_tool->guide_custom)
-                gimp_image_move_guide (image, guide_tool->guide,
-                                       guide_tool->guide_position, TRUE);
+              /* removing a guide can cause other guides to be removed as well
+               * (in particular, in case of symmetry guides).  these guides
+               * will be kept alive, since we hold a reference on them, but we
+               * need to make sure that they're still part of the image.
+               */
+              if (g_list_find (gimp_image_get_guides (image), guide->guide))
+                gimp_image_remove_guide (image, guide->guide, TRUE);
             }
           else
             {
-              switch (guide_tool->guide_orientation)
+              if (guide->guide)
+                {
+                  /* custom guides are moved live */
+                  if (! guide->custom)
+                    {
+                      gimp_image_move_guide (image, guide->guide,
+                                             guide->position, TRUE);
+                    }
+                }
+              else
                 {
-                case GIMP_ORIENTATION_HORIZONTAL:
-                  guide_tool->guide =
-                    gimp_image_add_hguide (image,
-                                           guide_tool->guide_position,
-                                           TRUE);
-                  break;
-
-                case GIMP_ORIENTATION_VERTICAL:
-                  guide_tool->guide =
-                    gimp_image_add_vguide (image,
-                                           guide_tool->guide_position,
-                                           TRUE);
-                  break;
-
-                default:
-                  gimp_assert_not_reached ();
+                  switch (guide->orientation)
+                    {
+                    case GIMP_ORIENTATION_HORIZONTAL:
+                      gimp_image_add_hguide (image,
+                                             guide->position,
+                                             TRUE);
+                      break;
+
+                    case GIMP_ORIENTATION_VERTICAL:
+                      gimp_image_add_vguide (image,
+                                             guide->position,
+                                             TRUE);
+                      break;
+
+                    default:
+                      gimp_assert_not_reached ();
+                    }
                 }
             }
         }
 
+      if (n_non_custom_guides > 1)
+        gimp_image_undo_group_end (image);
+
       gimp_image_flush (image);
     }
 
   gimp_display_shell_selection_resume (shell);
 
-  guide_tool->guide_position    = GIMP_GUIDE_POSITION_UNDEFINED;
-  guide_tool->guide_orientation = GIMP_ORIENTATION_UNKNOWN;
-
   tool_manager_pop_tool (display->gimp);
   g_object_unref (guide_tool);
 
@@ -215,12 +275,12 @@ gimp_guide_tool_motion (GimpTool         *tool,
                         GimpDisplay      *display)
 
 {
-  GimpGuideTool    *guide_tool   = GIMP_GUIDE_TOOL (tool);
-  GimpDisplayShell *shell        = gimp_display_get_shell (display);
-  GimpImage        *image        = gimp_display_get_image (display);
-  gboolean          delete_guide = FALSE;
-  gint              max_position;
+  GimpGuideTool    *guide_tool    = GIMP_GUIDE_TOOL (tool);
+  GimpDisplayShell *shell         = gimp_display_get_shell (display);
+  GimpImage        *image         = gimp_display_get_image (display);
+  gboolean          remove_guides = FALSE;
   gint              tx, ty;
+  gint              i;
 
   gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
 
@@ -228,29 +288,40 @@ gimp_guide_tool_motion (GimpTool         *tool,
                                    coords->x, coords->y,
                                    &tx, &ty);
 
-  if (guide_tool->guide_orientation == GIMP_ORIENTATION_HORIZONTAL)
-    max_position = gimp_image_get_height (image);
-  else
-    max_position = gimp_image_get_width (image);
-
-  if (tx < 0 || tx >= shell->disp_width ||
-      ty < 0 || ty >= shell->disp_height)
+  for (i = 0; i < guide_tool->n_guides; i++)
     {
-      guide_tool->guide_position = GIMP_GUIDE_POSITION_UNDEFINED;
+      GimpGuideToolGuide *guide = &guide_tool->guides[i];
+      gint                max_position;
 
-      delete_guide = TRUE;
-    }
-  else
-    {
-      if (guide_tool->guide_orientation == GIMP_ORIENTATION_HORIZONTAL)
-        guide_tool->guide_position = RINT (coords->y);
+      if (guide->orientation == GIMP_ORIENTATION_HORIZONTAL)
+        max_position = gimp_image_get_height (image);
       else
-        guide_tool->guide_position = RINT (coords->x);
+        max_position = gimp_image_get_width (image);
+
+      if (tx < 0 || tx >= shell->disp_width ||
+          ty < 0 || ty >= shell->disp_height)
+        {
+          guide->position = GIMP_GUIDE_POSITION_UNDEFINED;
 
-      if (guide_tool->guide_position <  0 ||
-          guide_tool->guide_position > max_position)
+          remove_guides = TRUE;
+        }
+      else
         {
-          delete_guide = TRUE;
+          if (guide->orientation == GIMP_ORIENTATION_HORIZONTAL)
+            guide->position = RINT (coords->y);
+          else
+            guide->position = RINT (coords->x);
+
+          if (guide->position < 0 || guide->position > max_position)
+            remove_guides = TRUE;
+
+          /* custom guides are moved live */
+          if (guide->custom)
+            {
+              gimp_image_move_guide (image, guide->guide,
+                                     CLAMP (guide->position, 0, max_position),
+                                     TRUE);
+            }
         }
     }
 
@@ -258,60 +329,37 @@ gimp_guide_tool_motion (GimpTool         *tool,
 
   gimp_tool_pop_status (tool, display);
 
-  /* custom guides are moved live */
-  if (guide_tool->guide_custom &&
-      guide_tool->guide_position != GIMP_GUIDE_POSITION_UNDEFINED)
-    {
-      gimp_image_move_guide (image, guide_tool->guide,
-                             CLAMP (guide_tool->guide_position,
-                                    0, max_position), TRUE);
-    }
-
-  if (delete_guide)
-    {
-      gimp_tool_push_status (tool, display,
-                             guide_tool->guide ?
-                             _("Remove Guide") : _("Cancel Guide"));
-    }
-  else if (guide_tool->guide)
-    {
-      gimp_tool_push_status_length (tool, display,
-                                    _("Move Guide: "),
-                                    SWAP_ORIENT (guide_tool->guide_orientation),
-                                    guide_tool->guide_position -
-                                    guide_tool->guide_old_position,
-                                    NULL);
-    }
-  else
-    {
-      gimp_tool_push_status_length (tool, display,
-                                    _("Add Guide: "),
-                                    SWAP_ORIENT (guide_tool->guide_orientation),
-                                    guide_tool->guide_position,
-                                    NULL);
-    }
+  gimp_guide_tool_push_status (guide_tool, display, remove_guides);
 }
 
 static void
 gimp_guide_tool_draw (GimpDrawTool *draw_tool)
 {
   GimpGuideTool *guide_tool = GIMP_GUIDE_TOOL (draw_tool);
+  gint           i;
 
-  if (guide_tool->guide_position != GIMP_GUIDE_POSITION_UNDEFINED)
+  for (i = 0; i < guide_tool->n_guides; i++)
     {
-      /* custom guides are moved live */
-      if (! guide_tool->guide_custom)
-        gimp_draw_tool_add_guide (draw_tool,
-                                  guide_tool->guide_orientation,
-                                  guide_tool->guide_position,
-                                  GIMP_GUIDE_STYLE_NONE);
+      GimpGuideToolGuide *guide = &guide_tool->guides[i];
+
+      if (guide->position != GIMP_GUIDE_POSITION_UNDEFINED)
+        {
+          /* custom guides are moved live */
+          if (! guide->custom)
+            {
+              gimp_draw_tool_add_guide (draw_tool,
+                                        guide->orientation,
+                                        guide->position,
+                                        GIMP_GUIDE_STYLE_NONE);
+            }
+        }
     }
 }
 
 static void
 gimp_guide_tool_start (GimpTool            *parent_tool,
                        GimpDisplay         *display,
-                       GimpGuide           *guide,
+                       GList               *guides,
                        GimpOrientationType  orientation)
 {
   GimpGuideTool *guide_tool;
@@ -325,21 +373,36 @@ gimp_guide_tool_start (GimpTool            *parent_tool,
 
   gimp_display_shell_selection_pause (gimp_display_get_shell (display));
 
-  if (guide)
+  if (guides)
     {
-      guide_tool->guide              = guide;
-      guide_tool->guide_old_position = gimp_guide_get_position (guide);
-      guide_tool->guide_position     = gimp_guide_get_position (guide);
-      guide_tool->guide_orientation  = gimp_guide_get_orientation (guide);
-      guide_tool->guide_custom       = gimp_guide_is_custom (guide);
+      gint i;
+
+      guide_tool->n_guides = g_list_length (guides);
+      guide_tool->guides   = g_new (GimpGuideToolGuide, guide_tool->n_guides);
+
+      for (i = 0; i < guide_tool->n_guides; i++)
+        {
+          GimpGuide *guide = guides->data;
+
+          guide_tool->guides[i].guide        = g_object_ref (guide);
+          guide_tool->guides[i].old_position = gimp_guide_get_position (guide);
+          guide_tool->guides[i].position     = gimp_guide_get_position (guide);
+          guide_tool->guides[i].orientation  = gimp_guide_get_orientation (guide);
+          guide_tool->guides[i].custom       = gimp_guide_is_custom (guide);
+
+          guides = g_list_next (guides);
+        }
     }
   else
     {
-      guide_tool->guide              = NULL;
-      guide_tool->guide_old_position = 0;
-      guide_tool->guide_position     = GIMP_GUIDE_POSITION_UNDEFINED;
-      guide_tool->guide_orientation  = orientation;
-      guide_tool->guide_custom       = FALSE;
+      guide_tool->n_guides = 1;
+      guide_tool->guides   = g_new (GimpGuideToolGuide, 1);
+
+      guide_tool->guides[0].guide        = NULL;
+      guide_tool->guides[0].old_position = 0;
+      guide_tool->guides[0].position     = GIMP_GUIDE_POSITION_UNDEFINED;
+      guide_tool->guides[0].orientation  = orientation;
+      guide_tool->guides[0].custom       = FALSE;
     }
 
   gimp_tool_set_cursor (tool, display,
@@ -354,22 +417,84 @@ gimp_guide_tool_start (GimpTool            *parent_tool,
 
   gimp_draw_tool_start (GIMP_DRAW_TOOL (guide_tool), display);
 
-  if (guide_tool->guide)
+  gimp_guide_tool_push_status (guide_tool, display, FALSE);
+}
+
+static void
+gimp_guide_tool_push_status (GimpGuideTool *guide_tool,
+                             GimpDisplay   *display,
+                             gboolean       remove_guides)
+{
+  GimpTool *tool = GIMP_TOOL (guide_tool);
+
+  if (remove_guides)
     {
-      gimp_tool_push_status_length (tool, display,
-                                    _("Move Guide: "),
-                                    SWAP_ORIENT (guide_tool->guide_orientation),
-                                    guide_tool->guide_position -
-                                    guide_tool->guide_old_position,
-                                    NULL);
+      gimp_tool_push_status (tool, display,
+                             guide_tool->n_guides > 1    ? _("Remove Guides") :
+                             guide_tool->guides[0].guide ? _("Remove Guide")  :
+                                                           _("Cancel Guide"));
     }
   else
     {
-      gimp_tool_push_status_length (tool, display,
-                                    _("Add Guide: "),
-                                    SWAP_ORIENT (guide_tool->guide_orientation),
-                                    guide_tool->guide_position,
-                                    NULL);
+      GimpGuideToolGuide *guides[2];
+      gint                n_guides = 0;
+      gint                i;
+
+      for (i = 0; i < guide_tool->n_guides; i++)
+        {
+          GimpGuideToolGuide *guide = &guide_tool->guides[i];
+
+          if (guide_tool->guides[i].guide)
+            {
+              if (n_guides == 0 || guide->orientation != guides[0]->orientation)
+                {
+                  guides[n_guides++] = guide;
+
+                  if (n_guides == 2)
+                    break;
+                }
+            }
+        }
+
+      if (n_guides == 2 &&
+          guides[0]->orientation == GIMP_ORIENTATION_HORIZONTAL)
+        {
+          GimpGuideToolGuide *temp;
+
+          temp      = guides[0];
+          guides[0] = guides[1];
+          guides[1] = temp;
+        }
+
+       if (n_guides == 1)
+        {
+          gimp_tool_push_status_length (tool, display,
+                                        _("Move Guide: "),
+                                        SWAP_ORIENT (guides[0]->orientation),
+                                        guides[0]->position -
+                                        guides[0]->old_position,
+                                        NULL);
+        }
+      else if (n_guides == 2)
+        {
+          gimp_tool_push_status_coords (tool, display,
+                                        GIMP_CURSOR_PRECISION_PIXEL_BORDER,
+                                        _("Move Guides: "),
+                                        guides[0]->position -
+                                        guides[0]->old_position,
+                                        ", ",
+                                        guides[1]->position -
+                                        guides[1]->old_position,
+                                        NULL);
+        }
+      else
+        {
+          gimp_tool_push_status_length (tool, display,
+                                        _("Add Guide: "),
+                                        SWAP_ORIENT (guide_tool->guides[0].orientation),
+                                        guide_tool->guides[0].position,
+                                        NULL);
+        }
     }
 }
 
@@ -394,10 +519,29 @@ gimp_guide_tool_start_edit (GimpTool    *parent_tool,
                             GimpDisplay *display,
                             GimpGuide   *guide)
 {
+  GList *guides = NULL;
+
   g_return_if_fail (GIMP_IS_TOOL (parent_tool));
   g_return_if_fail (GIMP_IS_DISPLAY (display));
   g_return_if_fail (GIMP_IS_GUIDE (guide));
 
+  guides = g_list_append (guides, guide);
+
+  gimp_guide_tool_start (parent_tool, display,
+                         guides, GIMP_ORIENTATION_UNKNOWN);
+
+  g_list_free (guides);
+}
+
+void
+gimp_guide_tool_start_edit_many (GimpTool    *parent_tool,
+                                 GimpDisplay *display,
+                                 GList       *guides)
+{
+  g_return_if_fail (GIMP_IS_TOOL (parent_tool));
+  g_return_if_fail (GIMP_IS_DISPLAY (display));
+  g_return_if_fail (guides != NULL);
+
   gimp_guide_tool_start (parent_tool, display,
-                         guide, GIMP_ORIENTATION_UNKNOWN);
+                         guides, GIMP_ORIENTATION_UNKNOWN);
 }
diff --git a/app/tools/gimpguidetool.h b/app/tools/gimpguidetool.h
index 351deb1d79..fa83b3664a 100644
--- a/app/tools/gimpguidetool.h
+++ b/app/tools/gimpguidetool.h
@@ -30,18 +30,26 @@
 #define GIMP_GUIDE_TOOL_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_GUIDE_TOOL, 
GimpGuideToolClass))
 
 
+typedef struct _GimpGuideToolGuide GimpGuideToolGuide;
 typedef struct _GimpGuideTool      GimpGuideTool;
 typedef struct _GimpGuideToolClass GimpGuideToolClass;
 
+struct _GimpGuideToolGuide
+{
+  GimpGuide           *guide;
+
+  gint                 old_position;
+  gint                 position;
+  GimpOrientationType  orientation;
+  gboolean             custom;
+};
+
 struct _GimpGuideTool
 {
-  GimpDrawTool         parent_instance;
+  GimpDrawTool        parent_instance;
 
-  GimpGuide           *guide;
-  gint                 guide_old_position;
-  gint                 guide_position;
-  GimpOrientationType  guide_orientation;
-  gboolean             guide_custom;
+  GimpGuideToolGuide *guides;
+  gint                n_guides;
 };
 
 struct _GimpGuideToolClass
@@ -50,14 +58,17 @@ struct _GimpGuideToolClass
 };
 
 
-GType   gimp_guide_tool_get_type   (void) G_GNUC_CONST;
+GType   gimp_guide_tool_get_type        (void) G_GNUC_CONST;
 
-void    gimp_guide_tool_start_new  (GimpTool            *parent_tool,
-                                    GimpDisplay         *display,
-                                    GimpOrientationType  orientation);
-void    gimp_guide_tool_start_edit (GimpTool            *parent_tool,
-                                    GimpDisplay         *display,
-                                    GimpGuide           *guide);
+void    gimp_guide_tool_start_new       (GimpTool            *parent_tool,
+                                         GimpDisplay         *display,
+                                         GimpOrientationType  orientation);
+void    gimp_guide_tool_start_edit      (GimpTool            *parent_tool,
+                                         GimpDisplay         *display,
+                                         GimpGuide           *guide);
+void    gimp_guide_tool_start_edit_many (GimpTool            *parent_tool,
+                                         GimpDisplay         *display,
+                                         GList               *guides);
 
 
 #endif  /*  __GIMP_GUIDE_TOOL_H__  */
diff --git a/app/tools/gimpmovetool.c b/app/tools/gimpmovetool.c
index 2d881f5367..266ee700c8 100644
--- a/app/tools/gimpmovetool.c
+++ b/app/tools/gimpmovetool.c
@@ -32,6 +32,7 @@
 
 #include "core/gimp.h"
 #include "core/gimp-cairo.h"
+#include "core/gimp-utils.h"
 #include "core/gimpguide.h"
 #include "core/gimpimage.h"
 #include "core/gimpimage-pick-item.h"
@@ -63,6 +64,8 @@
 
 /*  local function prototypes  */
 
+static void   gimp_move_tool_finalize       (GObject               *object);
+
 static void   gimp_move_tool_button_press   (GimpTool              *tool,
                                              const GimpCoords      *coords,
                                              guint32                time,
@@ -121,9 +124,12 @@ gimp_move_tool_register (GimpToolRegisterCallback  callback,
 static void
 gimp_move_tool_class_init (GimpMoveToolClass *klass)
 {
+  GObjectClass      *object_class    = G_OBJECT_CLASS (klass);
   GimpToolClass     *tool_class      = GIMP_TOOL_CLASS (klass);
   GimpDrawToolClass *draw_tool_class = GIMP_DRAW_TOOL_CLASS (klass);
 
+  object_class->finalize     = gimp_move_tool_finalize;
+
   tool_class->button_press   = gimp_move_tool_button_press;
   tool_class->button_release = gimp_move_tool_button_release;
   tool_class->key_press      = gimp_move_tool_key_press;
@@ -145,7 +151,7 @@ gimp_move_tool_init (GimpMoveTool *move_tool)
                                             GIMP_TOOL_CURSOR_MOVE);
 
   move_tool->floating_layer     = NULL;
-  move_tool->guide              = NULL;
+  move_tool->guides             = NULL;
 
   move_tool->saved_type         = GIMP_TRANSFORM_TYPE_LAYER;
 
@@ -153,6 +159,16 @@ gimp_move_tool_init (GimpMoveTool *move_tool)
   move_tool->old_active_vectors = NULL;
 }
 
+static void
+gimp_move_tool_finalize (GObject *object)
+{
+  GimpMoveTool *move = GIMP_MOVE_TOOL (object);
+
+  g_clear_pointer (&move->guides, g_list_free);
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
 static void
 gimp_move_tool_button_press (GimpTool            *tool,
                              const GimpCoords    *coords,
@@ -172,8 +188,9 @@ gimp_move_tool_button_press (GimpTool            *tool,
 
   tool->display = display;
 
-  move->floating_layer     = NULL;
-  move->guide              = NULL;
+  move->floating_layer = NULL;
+
+  g_clear_pointer (&move->guides, g_list_free);
 
   if (! options->move_current)
     {
@@ -202,18 +219,18 @@ gimp_move_tool_button_press (GimpTool            *tool,
         }
       else if (options->move_type == GIMP_TRANSFORM_TYPE_LAYER)
         {
-          GimpGuide  *guide;
-          GimpLayer  *layer;
+          GList     *guides;
+          GimpLayer *layer;
 
           if (gimp_display_shell_get_show_guides (shell) &&
-              (guide = gimp_image_pick_guide (image,
-                                              coords->x, coords->y,
-                                              FUNSCALEX (shell, snap_distance),
-                                              FUNSCALEY (shell, snap_distance))))
+              (guides = gimp_image_pick_guides (image,
+                                                coords->x, coords->y,
+                                                FUNSCALEX (shell, snap_distance),
+                                                FUNSCALEY (shell, snap_distance))))
             {
-              move->guide = guide;
+              move->guides = guides;
 
-              gimp_guide_tool_start_edit (tool, display, guide);
+              gimp_guide_tool_start_edit_many (tool, display, guides);
 
               return;
             }
@@ -481,7 +498,7 @@ gimp_move_tool_oper_update (GimpTool         *tool,
   GimpMoveOptions  *options = GIMP_MOVE_TOOL_GET_OPTIONS (tool);
   GimpDisplayShell *shell   = gimp_display_get_shell (display);
   GimpImage        *image   = gimp_display_get_image (display);
-  GimpGuide        *guide   = NULL;
+  GList            *guides  = NULL;
 
   if (options->move_type == GIMP_TRANSFORM_TYPE_LAYER &&
       ! options->move_current                         &&
@@ -490,12 +507,12 @@ gimp_move_tool_oper_update (GimpTool         *tool,
     {
       gint snap_distance = display->config->snap_distance;
 
-      guide = gimp_image_pick_guide (image, coords->x, coords->y,
-                                     FUNSCALEX (shell, snap_distance),
-                                     FUNSCALEY (shell, snap_distance));
+      guides = gimp_image_pick_guides (image, coords->x, coords->y,
+                                       FUNSCALEX (shell, snap_distance),
+                                       FUNSCALEY (shell, snap_distance));
     }
 
-  if (move->guide != guide)
+  if (gimp_list_compare (guides, move->guides))
     {
       GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);
 
@@ -505,7 +522,9 @@ gimp_move_tool_oper_update (GimpTool         *tool,
           draw_tool->display != display)
         gimp_draw_tool_stop (draw_tool);
 
-      move->guide = guide;
+      g_clear_pointer (&move->guides, g_list_free);
+
+      move->guides = guides;
 
       if (! gimp_draw_tool_is_active (draw_tool))
         gimp_draw_tool_start (draw_tool, display);
@@ -620,17 +639,19 @@ static void
 gimp_move_tool_draw (GimpDrawTool *draw_tool)
 {
   GimpMoveTool *move = GIMP_MOVE_TOOL (draw_tool);
+  GList        *iter;
 
-  if (move->guide)
+  for (iter = move->guides; iter; iter = g_list_next (iter))
     {
+      GimpGuide      *guide = iter->data;
       GimpCanvasItem *item;
       GimpGuideStyle  style;
 
-      style = gimp_guide_get_style (move->guide);
+      style = gimp_guide_get_style (guide);
 
       item = gimp_draw_tool_add_guide (draw_tool,
-                                       gimp_guide_get_orientation (move->guide),
-                                       gimp_guide_get_position (move->guide),
+                                       gimp_guide_get_orientation (guide),
+                                       gimp_guide_get_position (guide),
                                        style);
       gimp_canvas_item_set_highlight (item, TRUE);
     }
diff --git a/app/tools/gimpmovetool.h b/app/tools/gimpmovetool.h
index eb2a5a3b5b..a597e0124f 100644
--- a/app/tools/gimpmovetool.h
+++ b/app/tools/gimpmovetool.h
@@ -40,7 +40,7 @@ struct _GimpMoveTool
   GimpDrawTool         parent_instance;
 
   GimpLayer           *floating_layer;
-  GimpGuide           *guide;
+  GList               *guides;
 
   GimpTransformType    saved_type;
 


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