[gimp/soc-2012-unified-transformation: 3/25] transformtool: calculate center handle position correctly, add pivot handle



commit 0dc87775e050e96c9ec6e1bdf96207a2e410527a
Author: Mikael Magnusson <mikachu src gnome org>
Date:   Thu Aug 11 20:11:09 2011 +0200

    transformtool: calculate center handle position correctly, add pivot handle
    
    and use pivot handle in rotatetool so it works as before.

 app/tools/gimprotatetool.c    |   67 +++++++++++++++++++++--------------------
 app/tools/gimptransformtool.c |   57 ++++++++++++++++++++++++++++++----
 app/tools/gimptransformtool.h |    8 ++++-
 3 files changed, 90 insertions(+), 42 deletions(-)
---
diff --git a/app/tools/gimprotatetool.c b/app/tools/gimprotatetool.c
index 00e2cf5..8ac7294 100644
--- a/app/tools/gimprotatetool.c
+++ b/app/tools/gimprotatetool.c
@@ -48,8 +48,8 @@ enum
 {
   ANGLE,
   REAL_ANGLE,
-  CENTER_X,
-  CENTER_Y
+  PIVOT_X,
+  PIVOT_Y
 };
 
 #define FIFTEEN_DEG  (G_PI / 12.0)
@@ -125,7 +125,7 @@ gimp_rotate_tool_init (GimpRotateTool *rotate_tool)
   tr_tool->progress_text = _("Rotating");
 
   tr_tool->use_grid      = TRUE;
-  tr_tool->use_center    = TRUE;
+  tr_tool->use_pivot     = TRUE;
 }
 
 static gboolean
@@ -234,9 +234,9 @@ gimp_rotate_tool_dialog_update (GimpTransformTool *tr_tool)
                                    tr_tool);
 
   gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (rotate->sizeentry), 0,
-                              tr_tool->trans_info[CENTER_X]);
+                              tr_tool->trans_info[PIVOT_X]);
   gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (rotate->sizeentry), 1,
-                              tr_tool->trans_info[CENTER_Y]);
+                              tr_tool->trans_info[PIVOT_Y]);
 
   g_signal_handlers_unblock_by_func (rotate->sizeentry,
                                      rotate_center_changed,
@@ -252,10 +252,13 @@ gimp_rotate_tool_prepare (GimpTransformTool *tr_tool)
   gdouble         xres;
   gdouble         yres;
 
+  tr_tool->px = (gdouble) (tr_tool->x1 + tr_tool->x2) / 2.0;
+  tr_tool->py = (gdouble) (tr_tool->y1 + tr_tool->y2) / 2.0;
+
   tr_tool->trans_info[ANGLE]      = 0.0;
   tr_tool->trans_info[REAL_ANGLE] = 0.0;
-  tr_tool->trans_info[CENTER_X]   = tr_tool->cx;
-  tr_tool->trans_info[CENTER_Y]   = tr_tool->cy;
+  tr_tool->trans_info[PIVOT_X]    = tr_tool->px;
+  tr_tool->trans_info[PIVOT_Y]    = tr_tool->py;
 
   gimp_image_get_resolution (image, &xres, &yres);
 
@@ -295,26 +298,24 @@ gimp_rotate_tool_motion (GimpTransformTool *tr_tool)
 {
   GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
   gdouble               angle1, angle2, angle;
-  gdouble               cx, cy;
+  gdouble               px, py;
   gdouble               x1, y1, x2, y2;
 
-  if (tr_tool->function == TRANSFORM_HANDLE_CENTER)
+  if (tr_tool->function == TRANSFORM_HANDLE_PIVOT)
     {
-      tr_tool->trans_info[CENTER_X] = tr_tool->curx;
-      tr_tool->trans_info[CENTER_Y] = tr_tool->cury;
-      tr_tool->cx                   = tr_tool->curx;
-      tr_tool->cy                   = tr_tool->cury;
+      tr_tool->trans_info[PIVOT_X] = tr_tool->curx;
+      tr_tool->trans_info[PIVOT_Y] = tr_tool->cury;
 
       return;
     }
 
-  cx = tr_tool->trans_info[CENTER_X];
-  cy = tr_tool->trans_info[CENTER_Y];
+  px = tr_tool->trans_info[PIVOT_X];
+  py = tr_tool->trans_info[PIVOT_Y];
 
-  x1 = tr_tool->curx  - cx;
-  x2 = tr_tool->lastx - cx;
-  y1 = cy - tr_tool->cury;
-  y2 = cy - tr_tool->lasty;
+  x1 = tr_tool->curx  - px;
+  x2 = tr_tool->lastx - px;
+  y1 = py - tr_tool->cury;
+  y2 = py - tr_tool->lasty;
 
   /*  find the first angle  */
   angle1 = atan2 (y1, x1);
@@ -356,13 +357,13 @@ gimp_rotate_tool_motion (GimpTransformTool *tr_tool)
 static void
 gimp_rotate_tool_recalc_matrix (GimpTransformTool *tr_tool)
 {
-  tr_tool->cx = tr_tool->trans_info[CENTER_X];
-  tr_tool->cy = tr_tool->trans_info[CENTER_Y];
+  tr_tool->px = tr_tool->trans_info[PIVOT_X];
+  tr_tool->py = tr_tool->trans_info[PIVOT_Y];
 
   gimp_matrix3_identity (&tr_tool->transform);
   gimp_transform_matrix_rotate_center (&tr_tool->transform,
-                                       tr_tool->cx,
-                                       tr_tool->cy,
+                                       tr_tool->px,
+                                       tr_tool->py,
                                        tr_tool->trans_info[ANGLE]);
 }
 
@@ -372,8 +373,8 @@ 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[CENTER_X],
-                          tr_tool->trans_info[CENTER_Y]);
+                          tr_tool->trans_info[PIVOT_X],
+                          tr_tool->trans_info[PIVOT_Y]);
 }
 
 static void
@@ -402,18 +403,18 @@ static void
 rotate_center_changed (GtkWidget         *widget,
                        GimpTransformTool *tr_tool)
 {
-  gdouble cx = gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (widget), 0);
-  gdouble cy = gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (widget), 1);
+  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 ((cx != tr_tool->trans_info[CENTER_X]) ||
-      (cy != tr_tool->trans_info[CENTER_Y]))
+  if ((px != tr_tool->trans_info[PIVOT_X]) ||
+      (py != tr_tool->trans_info[PIVOT_Y]))
     {
       gimp_draw_tool_pause (GIMP_DRAW_TOOL (tr_tool));
 
-      tr_tool->trans_info[CENTER_X] = cx;
-      tr_tool->trans_info[CENTER_Y] = cy;
-      tr_tool->cx = cx;
-      tr_tool->cy = cy;
+      tr_tool->trans_info[PIVOT_X] = px;
+      tr_tool->trans_info[PIVOT_Y] = py;
+      tr_tool->px = px;
+      tr_tool->py = py;
 
       gimp_transform_tool_recalc_matrix (tr_tool);
 
diff --git a/app/tools/gimptransformtool.c b/app/tools/gimptransformtool.c
index 2d64f46..9220b88 100644
--- a/app/tools/gimptransformtool.c
+++ b/app/tools/gimptransformtool.c
@@ -330,8 +330,8 @@ gimp_transform_tool_button_press (GimpTool            *tool,
   if (tr_tool->function == TRANSFORM_CREATING)
     gimp_transform_tool_oper_update (tool, coords, state, TRUE, display);
 
-  tr_tool->lastx = coords->x;
-  tr_tool->lasty = coords->y;
+  tr_tool->lastx = tr_tool->mousex = coords->x;
+  tr_tool->lasty = tr_tool->mousey = coords->y;
 
   /*  Store current trans_info  */
   for (i = 0; i < TRANS_INFO_SIZE; i++)
@@ -541,6 +541,15 @@ gimp_transform_tool_oper_update (GimpTool         *tool,
         }
     }
 
+    if (tr_tool->use_pivot)
+      {
+        if (gimp_canvas_item_hit (tr_tool->handles[TRANSFORM_HANDLE_PIVOT],
+                                  coords->x, coords->y))
+          {
+            function = TRANSFORM_HANDLE_PIVOT;
+          }
+      }
+
   if (tr_tool->use_center &&
       gimp_canvas_item_hit (tr_tool->handles[TRANSFORM_HANDLE_CENTER],
                             coords->x, coords->y))
@@ -799,6 +808,31 @@ gimp_transform_tool_draw (GimpDrawTool *draw_tool)
         }
     }
 
+  if (tr_tool->use_pivot)
+    {
+      GimpCanvasGroup *stroke_group;
+      gint d = MIN (handle_w, handle_h);
+
+      stroke_group = gimp_draw_tool_add_stroke_group (draw_tool);
+
+      tr_tool->handles[TRANSFORM_HANDLE_PIVOT] = GIMP_CANVAS_ITEM (stroke_group);
+
+      gimp_draw_tool_push_group (draw_tool, stroke_group);
+
+      gimp_draw_tool_add_handle (draw_tool,
+                                 GIMP_HANDLE_SQUARE,
+                                 tr_tool->tpx, tr_tool->tpy,
+                                 d, d,
+                                 GIMP_HANDLE_ANCHOR_CENTER);
+      gimp_draw_tool_add_handle (draw_tool,
+                                 GIMP_HANDLE_CROSS,
+                                 tr_tool->tpx, tr_tool->tpy,
+                                 d, d,
+                                 GIMP_HANDLE_ANCHOR_CENTER);
+
+      gimp_draw_tool_pop_group (draw_tool);
+    }
+
   /*  draw the center  */
   if (tr_tool->use_center)
     {
@@ -1237,9 +1271,21 @@ gimp_transform_tool_transform_bounding_box (GimpTransformTool *tr_tool)
                                 tr_tool->x2, tr_tool->y2,
                                 &tr_tool->tx4, &tr_tool->ty4);
 
+  /* don't transform these */
   gimp_matrix3_transform_point (&tr_tool->transform,
-                                tr_tool->cx, tr_tool->cy,
-                                &tr_tool->tcx, &tr_tool->tcy);
+                                tr_tool->px, tr_tool->py,
+                                &tr_tool->tpx, &tr_tool->tpy);
+  tr_tool->tpx = tr_tool->px;
+  tr_tool->tpy = tr_tool->py;
+
+  tr_tool->tcx = (tr_tool->tx1 +
+                  tr_tool->tx2 +
+                  tr_tool->tx3 +
+                  tr_tool->tx4) / 4.0;
+  tr_tool->tcy = (tr_tool->ty1 +
+                  tr_tool->ty2 +
+                  tr_tool->ty3 +
+                  tr_tool->ty4) / 4.0;
 }
 
 static void
@@ -1279,9 +1325,6 @@ gimp_transform_tool_bounds (GimpTransformTool *tr_tool,
       break;
     }
 
-  tr_tool->cx = (gdouble) (tr_tool->x1 + tr_tool->x2) / 2.0;
-  tr_tool->cy = (gdouble) (tr_tool->y1 + tr_tool->y2) / 2.0;
-
   tr_tool->aspect = ((gdouble) (tr_tool->x2 - tr_tool->x1) /
                      (gdouble) (tr_tool->y2 - tr_tool->y1));
 }
diff --git a/app/tools/gimptransformtool.h b/app/tools/gimptransformtool.h
index eff4bb2..95a4a45 100644
--- a/app/tools/gimptransformtool.h
+++ b/app/tools/gimptransformtool.h
@@ -36,7 +36,8 @@ typedef enum
   TRANSFORM_HANDLE_S,  /* south      */
   TRANSFORM_HANDLE_E,  /* east       */
   TRANSFORM_HANDLE_W,  /* west       */
-  TRANSFORM_HANDLE_CENTER
+  TRANSFORM_HANDLE_PIVOT, /* pivot for rotation and scaling */
+  TRANSFORM_HANDLE_CENTER /* for moving */
 } TransformAction;
 
 typedef gdouble TransInfo[TRANS_INFO_SIZE];
@@ -66,7 +67,8 @@ struct _GimpTransformTool
 
   gint            x1, y1;          /*  upper left hand coordinate        */
   gint            x2, y2;          /*  lower right hand coords           */
-  gdouble         cx, cy;          /*  center point (for rotation)       */
+  gdouble         cx, cy;          /*  center point (for moving)         */
+  gdouble         px, py;          /*  pivot point (for rotation)        */
   gdouble         aspect;          /*  original aspect ratio             */
 
   gdouble         tx1, ty1;        /*  transformed handle coords         */
@@ -74,6 +76,7 @@ struct _GimpTransformTool
   gdouble         tx3, ty3;
   gdouble         tx4, ty4;
   gdouble         tcx, tcy;
+  gdouble         tpx, tpy;
 
   GimpMatrix3     transform;       /*  transformation matrix             */
   TransInfo       trans_info;      /*  transformation info               */
@@ -86,6 +89,7 @@ struct _GimpTransformTool
   gboolean        use_handles;     /*  uses the corner handles           */
   gboolean        use_center;      /*  uses the center handle            */
   gboolean        use_mid_handles; /*  use handles at midpoints of edges */
+  gboolean        use_pivot;       /*  use pivot point                   */
 
   GimpCanvasItem *handles[TRANSFORM_HANDLE_CENTER + 1];
 



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