[gimp] app: improve usability of the handle transform tool



commit 81cf8aa60138797307d18a0d5baa00dd1c0f0242
Author: Michael Natterer <mitch gimp org>
Date:   Thu Apr 2 23:31:41 2015 +0200

    app: improve usability of the handle transform tool
    
    Reorganize tool modes to be { ADD_TRANSFORM, MOVE, REMOVE }, where
    ADD_TRANSFORM is the default and allows to add handles *and* transform
    the image in one click-drag. MOVE moves handles without transforming
    (shift) and REMOVE removes handles (control). Also improve cursors to
    accurately show the result of a click.

 app/tools/gimphandletransformoptions.c |   18 ++--
 app/tools/gimphandletransformtool.c    |  218 +++++++++++++++++++-------------
 app/tools/tools-enums.c                |    8 +-
 app/tools/tools-enums.h                |    6 +-
 4 files changed, 146 insertions(+), 104 deletions(-)
---
diff --git a/app/tools/gimphandletransformoptions.c b/app/tools/gimphandletransformoptions.c
index 78ce7c6..4d50a47 100644
--- a/app/tools/gimphandletransformoptions.c
+++ b/app/tools/gimphandletransformoptions.c
@@ -72,7 +72,7 @@ gimp_handle_transform_options_class_init (GimpHandleTransformOptionsClass *klass
                                  "handle-mode",
                                  N_("Handle mode"),
                                  GIMP_TYPE_TRANSFORM_HANDLE_MODE,
-                                 GIMP_HANDLE_MODE_TRANSFORM,
+                                 GIMP_HANDLE_MODE_ADD_TRANSFORM,
                                  GIMP_PARAM_STATIC_STRINGS);
 }
 
@@ -161,19 +161,19 @@ gimp_handle_transform_options_gui (GimpToolOptions *tool_options)
 
           switch (i)
             {
-            case GIMP_HANDLE_MODE_ADD_MOVE:
+            case GIMP_HANDLE_MODE_ADD_TRANSFORM:
+              modifier = 0;
+              tooltip  = _("Add handles and transform the image");
+              break;
+
+            case GIMP_HANDLE_MODE_MOVE:
               modifier = shift;
-              tooltip  = "Add or move transform handles";
+              tooltip  = _("Move transform handles");
               break;
 
             case GIMP_HANDLE_MODE_REMOVE:
               modifier = ctrl;
-              tooltip  = "Remove transform handles";
-              break;
-
-            case GIMP_HANDLE_MODE_TRANSFORM:
-              modifier = 0;
-              tooltip  = "Transform image by moving handles";
+              tooltip  = _("Remove transform handles");
               break;
             }
 
diff --git a/app/tools/gimphandletransformtool.c b/app/tools/gimphandletransformtool.c
index e66c2a7..b82e034 100644
--- a/app/tools/gimphandletransformtool.c
+++ b/app/tools/gimphandletransformtool.c
@@ -201,7 +201,7 @@ gimp_handle_transform_tool_init (GimpHandleTransformTool *ht_tool)
 
   tr_tool->does_perspective = TRUE;
 
-  ht_tool->saved_handle_mode = GIMP_HANDLE_MODE_TRANSFORM;
+  ht_tool->saved_handle_mode = GIMP_HANDLE_MODE_ADD_TRANSFORM;
 }
 
 static void
@@ -220,68 +220,102 @@ gimp_handle_transform_tool_button_press (GimpTool            *tool,
 
   options = GIMP_HANDLE_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
 
+  GIMP_TOOL_CLASS (parent_class)->button_press (tool, coords, time, state,
+                                                press_type, display);
+
   n_handles     = (gint) tr_tool->trans_info[N_HANDLES];
   active_handle = tr_tool->function - TRANSFORM_HANDLE_N;
 
-  /* There is nothing to be done on creation */
-  if (tr_tool->function == TRANSFORM_CREATING)
-    {
-      GIMP_TOOL_CLASS (parent_class)->button_press (tool, coords, time,
-                                                    state, press_type, display);
-      return;
-    }
-
-  if (options->handle_mode == GIMP_HANDLE_MODE_ADD_MOVE)
+  switch (options->handle_mode)
     {
-      /* add handle */
-
+    case GIMP_HANDLE_MODE_ADD_TRANSFORM:
       if (n_handles < 4 && tr_tool->function == TRANSFORM_HANDLE_NONE)
         {
-          tr_tool->trans_info[X0 + 2 * n_handles] = coords->x;
-          tr_tool->trans_info[Y0 + 2 * n_handles] = coords->y;
-          tr_tool->function = TRANSFORM_HANDLE_N + n_handles;
+          /* add handle */
+
+          GimpMatrix3 matrix;
+
+          gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
+
+          active_handle = n_handles;
+
+          tr_tool->trans_info[X0 + 2 * active_handle] = coords->x;
+          tr_tool->trans_info[Y0 + 2 * active_handle] = coords->y;
           tr_tool->trans_info[N_HANDLES]++;
 
-          /* check for valid position and calculating of OX0...OY3 is
-           * done on button release
+          if (! is_handle_position_valid (tr_tool, active_handle))
+            {
+              handle_micro_move (tr_tool, active_handle);
+            }
+
+          /* handle was added, calculate new original position */
+          matrix = tr_tool->transform;
+          gimp_matrix3_invert (&matrix);
+          gimp_matrix3_transform_point (&matrix,
+                                        tr_tool->trans_info[X0 + 2 * active_handle],
+                                        tr_tool->trans_info[Y0 + 2 * active_handle],
+                                        &tr_tool->trans_info[OX0 + 2 * active_handle],
+                                        &tr_tool->trans_info[OY0 + 2 * active_handle]);
+
+          /*  this is disgusting: we put the new handle's coordinates
+           *  into the prev_trans_info array, because our motion
+           *  handler needs them for doing the actual transform; we
+           *  can only do this because the values will be ignored by
+           *  anything but our motion handler because we don't
+           *  increase the N_HANDLES value in prev_trans_info.
            */
+          (*tr_tool->prev_trans_info)[X0 + 2 * active_handle] = tr_tool->trans_info[X0 + 2 * active_handle];
+          (*tr_tool->prev_trans_info)[Y0 + 2 * active_handle] = tr_tool->trans_info[Y0 + 2 * active_handle];
+
+          (*tr_tool->prev_trans_info)[OX0 + 2 * active_handle] = tr_tool->trans_info[OX0 + 2 * 
active_handle];
+          (*tr_tool->prev_trans_info)[OY0 + 2 * active_handle] = tr_tool->trans_info[OY0 + 2 * 
active_handle];
+
+          gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
+
+          tr_tool->function = TRANSFORM_HANDLE_N + active_handle;
         }
+      break;
+
+    case GIMP_HANDLE_MODE_MOVE:
+      /* check for valid position and calculating of OX0...OY3 is
+       * done on button release
+       */
 
       /* move handles without changing the transformation matrix */
       ht->matrix_recalculation = FALSE;
-    }
-  else if (options->handle_mode == GIMP_HANDLE_MODE_REMOVE &&
-           n_handles > 0      &&
-           active_handle >= 0 &&
-           active_handle < 4)
-    {
-      /* remove handle */
+      break;
 
-      gdouble tempx  = tr_tool->trans_info[X0  + 2 * active_handle];
-      gdouble tempy  = tr_tool->trans_info[Y0  + 2 * active_handle];
-      gdouble tempox = tr_tool->trans_info[OX0 + 2 * active_handle];
-      gdouble tempoy = tr_tool->trans_info[OY0 + 2 * active_handle];
-      gint    i;
+    case GIMP_HANDLE_MODE_REMOVE:
+      if (n_handles > 0      &&
+          active_handle >= 0 &&
+          active_handle < 4)
+        {
+          /* remove handle */
 
-      n_handles--;
-      tr_tool->trans_info[N_HANDLES]--;
+          gdouble tempx  = tr_tool->trans_info[X0  + 2 * active_handle];
+          gdouble tempy  = tr_tool->trans_info[Y0  + 2 * active_handle];
+          gdouble tempox = tr_tool->trans_info[OX0 + 2 * active_handle];
+          gdouble tempoy = tr_tool->trans_info[OY0 + 2 * active_handle];
+          gint    i;
 
-      for (i = active_handle; i < n_handles; i++)
-        {
-          tr_tool->trans_info[X0  + 2 * i] = tr_tool->trans_info[X1  + 2 * i];
-          tr_tool->trans_info[Y0  + 2 * i] = tr_tool->trans_info[Y1  + 2 * i];
-          tr_tool->trans_info[OX0 + 2 * i] = tr_tool->trans_info[OX1 + 2 * i];
-          tr_tool->trans_info[OY0 + 2 * i] = tr_tool->trans_info[OY1 + 2 * i];
-        }
+          n_handles--;
+          tr_tool->trans_info[N_HANDLES]--;
 
-      tr_tool->trans_info[X0  + 2 * n_handles] = tempx;
-      tr_tool->trans_info[Y0  + 2 * n_handles] = tempy;
-      tr_tool->trans_info[OX0 + 2 * n_handles] = tempox;
-      tr_tool->trans_info[OY0 + 2 * n_handles] = tempoy;
-    }
+          for (i = active_handle; i < n_handles; i++)
+            {
+              tr_tool->trans_info[X0  + 2 * i] = tr_tool->trans_info[X1  + 2 * i];
+              tr_tool->trans_info[Y0  + 2 * i] = tr_tool->trans_info[Y1  + 2 * i];
+              tr_tool->trans_info[OX0 + 2 * i] = tr_tool->trans_info[OX1 + 2 * i];
+              tr_tool->trans_info[OY0 + 2 * i] = tr_tool->trans_info[OY1 + 2 * i];
+            }
 
-  GIMP_TOOL_CLASS (parent_class)->button_press (tool, coords, time,
-                                                state, press_type, display);
+          tr_tool->trans_info[X0  + 2 * n_handles] = tempx;
+          tr_tool->trans_info[Y0  + 2 * n_handles] = tempy;
+          tr_tool->trans_info[OX0 + 2 * n_handles] = tempox;
+          tr_tool->trans_info[OY0 + 2 * n_handles] = tempoy;
+        }
+      break;
+    }
 }
 
 static void
@@ -301,7 +335,7 @@ gimp_handle_transform_tool_button_release (GimpTool              *tool,
 
   active_handle = tr_tool->function - TRANSFORM_HANDLE_N;
 
-  if (options->handle_mode == GIMP_HANDLE_MODE_ADD_MOVE &&
+  if (options->handle_mode == GIMP_HANDLE_MODE_MOVE &&
       active_handle >= 0 &&
       active_handle < 4)
     {
@@ -312,7 +346,7 @@ gimp_handle_transform_tool_button_release (GimpTool              *tool,
           handle_micro_move (tr_tool, active_handle);
         }
 
-      /* handle was added or moved. calculate new original position */
+      /* handle was moved, calculate new original position */
       matrix = tr_tool->transform;
       gimp_matrix3_invert (&matrix);
       gimp_matrix3_transform_point (&matrix,
@@ -322,13 +356,6 @@ gimp_handle_transform_tool_button_release (GimpTool              *tool,
                                     &tr_tool->trans_info[OY0 + 2 * active_handle]);
     }
 
-  if (release_type != GIMP_BUTTON_RELEASE_CANCEL)
-    {
-      /* force redraw */
-      gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
-      gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
-    }
-
   ht->matrix_recalculation = TRUE;
 
   GIMP_TOOL_CLASS (parent_class)->button_release (tool, coords, time,
@@ -371,7 +398,7 @@ gimp_handle_transform_tool_modifier_key (GimpTool        *tool,
 
   if (state & shift)
     {
-      handle_mode = GIMP_HANDLE_MODE_ADD_MOVE;
+      handle_mode = GIMP_HANDLE_MODE_MOVE;
     }
   else if (state & ctrl)
     {
@@ -483,17 +510,18 @@ gimp_handle_transform_tool_motion (GimpTransformTool *tr_tool)
 
   if (active_handle >= 0 && active_handle < 4)
     {
-      if (options->handle_mode == GIMP_HANDLE_MODE_ADD_MOVE)
+      if (options->handle_mode == GIMP_HANDLE_MODE_MOVE)
         {
           tr_tool->trans_info[X0 + 2 * active_handle] += tr_tool->curx - tr_tool->lastx;
           tr_tool->trans_info[Y0 + 2 * active_handle] += tr_tool->cury - tr_tool->lasty;
+
           /* check for valid position and calculating of OX0...OY3 is
            * done on button release hopefully this makes the code run
            * faster Moving could be even faster if there was caching
            * for the image preview
            */
         }
-      else if (options->handle_mode == GIMP_HANDLE_MODE_TRANSFORM)
+      else if (options->handle_mode == GIMP_HANDLE_MODE_ADD_TRANSFORM)
         {
           gdouble angle, angle_sin, angle_cos, scale;
           gdouble fixed_handles_x[3];
@@ -507,13 +535,13 @@ gimp_handle_transform_tool_motion (GimpTransformTool *tr_tool)
               /* Find all visible handles that are not being moved */
               if (i < n_handles && i != active_handle)
                 {
-                  fixed_handles_x[j] = tr_tool->prev_trans_info[0][X0 + i * 2];
-                  fixed_handles_y[j] = tr_tool->prev_trans_info[0][Y0 + i * 2];
+                  fixed_handles_x[j] = tr_tool->trans_info[X0 + i * 2];
+                  fixed_handles_y[j] = tr_tool->trans_info[Y0 + i * 2];
                   j++;
                 }
 
-              newpos_x[i] = oldpos_x[i] = tr_tool->prev_trans_info[0][X0 + i * 2];
-              newpos_y[i] = oldpos_y[i] = tr_tool->prev_trans_info[0][Y0 + i * 2];
+              newpos_x[i] = oldpos_x[i] = (*tr_tool->prev_trans_info)[X0 + i * 2];
+              newpos_y[i] = oldpos_y[i] = (*tr_tool->prev_trans_info)[Y0 + i * 2];
             }
 
           newpos_x[active_handle] = oldpos_x[active_handle] + tr_tool->curx - tr_tool->mousex;
@@ -570,8 +598,8 @@ gimp_handle_transform_tool_motion (GimpTransformTool *tr_tool)
 
           for (i = 0; i < 4; i++)
             {
-              tr_tool->trans_info[X0 + 2*i] = newpos_x[i];
-              tr_tool->trans_info[Y0 + 2*i] = newpos_y[i];
+              tr_tool->trans_info[X0 + 2 * i] = newpos_x[i];
+              tr_tool->trans_info[Y0 + 2 * i] = newpos_y[i];
             }
         }
     }
@@ -680,42 +708,56 @@ gimp_handle_transform_tool_cursor_update (GimpTransformTool  *tr_tool,
 
   options = GIMP_HANDLE_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
 
-  *cursor     = GIMP_CURSOR_CROSSHAIR_SMALL;
-  *modifier   = GIMP_CURSOR_MODIFIER_NONE;
+  *cursor   = GIMP_CURSOR_CROSSHAIR_SMALL;
+  *modifier = GIMP_CURSOR_MODIFIER_NONE;
 
   /* do not show modifiers when the tool isn't active */
   if (! gimp_draw_tool_is_active (GIMP_DRAW_TOOL (tr_tool)))
     return;
 
-  if (options->handle_mode == GIMP_HANDLE_MODE_TRANSFORM &&
-      tr_tool->function > TRANSFORM_HANDLE_NONE)
+  switch (options->handle_mode)
     {
-      switch ((gint) tr_tool->trans_info[N_HANDLES])
+    case GIMP_HANDLE_MODE_ADD_TRANSFORM:
+      if (tr_tool->function > TRANSFORM_HANDLE_NONE)
+        {
+          switch ((gint) tr_tool->trans_info[N_HANDLES])
+            {
+            case 1:
+              tool_cursor = GIMP_TOOL_CURSOR_MOVE;
+              break;
+            case 2:
+              tool_cursor = GIMP_TOOL_CURSOR_ROTATE;
+              break;
+            case 3:
+              tool_cursor = GIMP_TOOL_CURSOR_SHEAR;
+              break;
+            case 4:
+              tool_cursor = GIMP_TOOL_CURSOR_PERSPECTIVE;
+              break;
+            }
+        }
+      else
         {
-        case 1:
-          tool_cursor = GIMP_TOOL_CURSOR_MOVE;
-          break;
-        case 2:
-          tool_cursor = GIMP_TOOL_CURSOR_ROTATE;
-          break;
-        case 3:
-          tool_cursor = GIMP_TOOL_CURSOR_SHEAR;
-          break;
-        case 4:
-          tool_cursor = GIMP_TOOL_CURSOR_PERSPECTIVE;
-          break;
+          if ((gint) tr_tool->trans_info[N_HANDLES] < 4)
+            *modifier = GIMP_CURSOR_MODIFIER_PLUS;
+          else
+            *modifier = GIMP_CURSOR_MODIFIER_BAD;
         }
-    }
-  else if (options->handle_mode == GIMP_HANDLE_MODE_ADD_MOVE)
-    {
+      break;
+
+    case GIMP_HANDLE_MODE_MOVE:
       if (tr_tool->function > TRANSFORM_HANDLE_NONE)
         *modifier = GIMP_CURSOR_MODIFIER_MOVE;
       else
-        *modifier = GIMP_CURSOR_MODIFIER_PLUS;
-    }
-  else if (options->handle_mode == GIMP_HANDLE_MODE_REMOVE)
-    {
-      *modifier = GIMP_CURSOR_MODIFIER_MINUS;
+        *modifier = GIMP_CURSOR_MODIFIER_BAD;
+      break;
+
+    case GIMP_HANDLE_MODE_REMOVE:
+      if (tr_tool->function > TRANSFORM_HANDLE_NONE)
+        *modifier = GIMP_CURSOR_MODIFIER_MINUS;
+      else
+        *modifier = GIMP_CURSOR_MODIFIER_BAD;
+      break;
     }
 
   gimp_tool_control_set_tool_cursor (GIMP_TOOL (tr_tool)->control,
diff --git a/app/tools/tools-enums.c b/app/tools/tools-enums.c
index 77b5fb8..4cd12c8 100644
--- a/app/tools/tools-enums.c
+++ b/app/tools/tools-enums.c
@@ -78,17 +78,17 @@ gimp_transform_handle_mode_get_type (void)
 {
   static const GEnumValue values[] =
   {
-    { GIMP_HANDLE_MODE_ADD_MOVE, "GIMP_HANDLE_MODE_ADD_MOVE", "add-move" },
+    { GIMP_HANDLE_MODE_ADD_TRANSFORM, "GIMP_HANDLE_MODE_ADD_TRANSFORM", "add-transform" },
+    { GIMP_HANDLE_MODE_MOVE, "GIMP_HANDLE_MODE_MOVE", "move" },
     { GIMP_HANDLE_MODE_REMOVE, "GIMP_HANDLE_MODE_REMOVE", "remove" },
-    { GIMP_HANDLE_MODE_TRANSFORM, "GIMP_HANDLE_MODE_TRANSFORM", "transform" },
     { 0, NULL, NULL }
   };
 
   static const GimpEnumDesc descs[] =
   {
-    { GIMP_HANDLE_MODE_ADD_MOVE, NC_("transform-handle-mode", "Add/Move"), NULL },
+    { GIMP_HANDLE_MODE_ADD_TRANSFORM, NC_("transform-handle-mode", "Add / Transform"), NULL },
+    { GIMP_HANDLE_MODE_MOVE, NC_("transform-handle-mode", "Move"), NULL },
     { GIMP_HANDLE_MODE_REMOVE, NC_("transform-handle-mode", "Remove"), NULL },
-    { GIMP_HANDLE_MODE_TRANSFORM, NC_("transform-handle-mode", "Transform"), NULL },
     { 0, NULL, NULL }
   };
 
diff --git a/app/tools/tools-enums.h b/app/tools/tools-enums.h
index 60246ef..f7b3ff1 100644
--- a/app/tools/tools-enums.h
+++ b/app/tools/tools-enums.h
@@ -53,9 +53,9 @@ GType gimp_transform_handle_mode_get_type (void) G_GNUC_CONST;
 
 typedef enum
 {
-  GIMP_HANDLE_MODE_ADD_MOVE,   /*< desc="Add/Move"  >*/
-  GIMP_HANDLE_MODE_REMOVE,     /*< desc="Remove"    >*/
-  GIMP_HANDLE_MODE_TRANSFORM,  /*< desc="Transform" >*/
+  GIMP_HANDLE_MODE_ADD_TRANSFORM, /*< desc="Add / Transform" >*/
+  GIMP_HANDLE_MODE_MOVE,          /*< desc="Move"            >*/
+  GIMP_HANDLE_MODE_REMOVE         /*< desc="Remove"          >*/
 } GimpTransformHandleMode;
 
 


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