[gimp] app: add proximity-sensitive handles to the handle transform tool



commit 3b21c08b41b1ee480d27f42fb57c94d247bc0068
Author: Michael Natterer <mitch gimp org>
Date:   Mon Jun 19 08:02:12 2017 +0200

    app: add proximity-sensitive handles to the handle transform tool
    
    as known from the blend tool.

 app/display/gimptoolhandlegrid.c |   50 ++++++++++++++++++++++++++++++++++---
 1 files changed, 46 insertions(+), 4 deletions(-)
---
diff --git a/app/display/gimptoolhandlegrid.c b/app/display/gimptoolhandlegrid.c
index ad02946..4e09c13 100644
--- a/app/display/gimptoolhandlegrid.c
+++ b/app/display/gimptoolhandlegrid.c
@@ -40,7 +40,7 @@
 #include "gimp-intl.h"
 
 
-#define GIMP_TOOL_HANDLE_SIZE_CIRCLE    13
+#define GIMP_TOOL_HANDLE_SIZE_CIRCLE 13
 
 
 enum
@@ -81,6 +81,9 @@ struct _GimpToolHandleGridPrivate
   gdouble  last_x;
   gdouble  last_y;
 
+  gdouble  mouse_x;
+  gdouble  mouse_y;
+
   GimpCanvasItem *handles[5];
 };
 
@@ -686,6 +689,9 @@ gimp_tool_handle_grid_motion (GimpToolWidget   *widget,
   gdouble                    diff_x        = coords->x - private->last_x;
   gdouble                    diff_y        = coords->y - private->last_y;
 
+  private->mouse_x = coords->x;
+  private->mouse_y = coords->y;
+
   if (active_handle >= 0 && active_handle < 4)
     {
       if (private->handle_mode == GIMP_HANDLE_MODE_MOVE)
@@ -809,6 +815,9 @@ gimp_tool_handle_grid_hover (GimpToolWidget   *widget,
   GimpToolHandleGridPrivate *private = grid->private;
   gint                       i;
 
+  private->mouse_x = coords->x;
+  private->mouse_y = coords->y;
+
   private->handle = 0;
 
   for (i = 0; i < 4; i++)
@@ -888,6 +897,26 @@ gimp_tool_handle_grid_get_cursor (GimpToolWidget     *widget,
   return TRUE;
 }
 
+static gint
+calc_handle_diameter (gdouble distance)
+{
+#define HANDLE_DIAMETER             (2 * GIMP_TOOL_HANDLE_SIZE_CIRCLE)
+#define POINT_GRAB_THRESHOLD_SQ     (SQR (HANDLE_DIAMETER / 2))
+#define FULL_HANDLE_THRESHOLD_SQ    (POINT_GRAB_THRESHOLD_SQ * 9)
+#define PARTIAL_HANDLE_THRESHOLD_SQ (FULL_HANDLE_THRESHOLD_SQ * 5)
+
+  /* Calculate the handle size based on distance from the cursor
+   */
+  gdouble size = (1.0 - (distance - FULL_HANDLE_THRESHOLD_SQ) /
+                  (PARTIAL_HANDLE_THRESHOLD_SQ - FULL_HANDLE_THRESHOLD_SQ));
+
+  size = CLAMP (size, 0.0, 1.0);
+
+  return (gint) CLAMP ((size * HANDLE_DIAMETER),
+                       GIMP_TOOL_HANDLE_SIZE_CIRCLE,
+                       HANDLE_DIAMETER);
+}
+
 static void
 gimp_tool_handle_grid_update_hilight (GimpToolHandleGrid *grid)
 {
@@ -896,10 +925,23 @@ gimp_tool_handle_grid_update_hilight (GimpToolHandleGrid *grid)
 
   for (i = 0; i < 4; i++)
     {
-      if (private->handles[i + 1])
+      GimpCanvasItem *item = private->handles[i + 1];
+
+      if (item)
         {
-          gimp_canvas_item_set_highlight (private->handles[i + 1],
-                                          (i + 1) == private->handle);
+          gdouble x, y;
+          gdouble dist;
+          gdouble diameter;
+
+          gimp_canvas_handle_get_position (item, &x, &y);
+          dist = gimp_canvas_item_transform_distance_square (item,
+                                                             private->mouse_x,
+                                                             private->mouse_y,
+                                                             x, y);
+          diameter = calc_handle_diameter (dist);
+
+          gimp_canvas_handle_set_size (item, diameter, diameter);
+          gimp_canvas_item_set_highlight (item, (i + 1) == private->handle);
         }
     }
 }


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