[gimp] app: use the newly added tool widgets in the transform tools
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: use the newly added tool widgets in the transform tools
- Date: Sat, 17 Jun 2017 01:04:36 +0000 (UTC)
commit a5f3808505fc1157e0ff0732d9a68a48576bbedf
Author: Michael Natterer <mitch gimp org>
Date: Sat Jun 17 03:02:01 2017 +0200
app: use the newly added tool widgets in the transform tools
app/tools/gimphandletransformtool.c | 14 +-
app/tools/gimpperspectivetool.c | 157 +++--
app/tools/gimprotatetool.c | 195 +++---
app/tools/gimpscaletool.c | 246 +++-----
app/tools/gimpsheartool.c | 215 ++++---
app/tools/gimptransformoptions.c | 4 +-
app/tools/gimptransformtool.c | 680 +++++++------------
app/tools/gimptransformtool.h | 75 +--
app/tools/gimpunifiedtransformtool.c | 1240 +++-------------------------------
9 files changed, 800 insertions(+), 2026 deletions(-)
---
diff --git a/app/tools/gimphandletransformtool.c b/app/tools/gimphandletransformtool.c
index 7e12556..09e1502 100644
--- a/app/tools/gimphandletransformtool.c
+++ b/app/tools/gimphandletransformtool.c
@@ -105,7 +105,8 @@ static void gimp_handle_transform_tool_dialog (GimpTransformTool *tr_
static void gimp_handle_transform_tool_dialog_update (GimpTransformTool *tr_tool);
static void gimp_handle_transform_tool_prepare (GimpTransformTool *tr_tool);
static void gimp_handle_transform_tool_motion (GimpTransformTool *tr_tool);
-static void gimp_handle_transform_tool_recalc_matrix (GimpTransformTool *tr_tool);
+static void gimp_handle_transform_tool_recalc_matrix (GimpTransformTool *tr_tool,
+ GimpToolWidget *widget);
static gchar *gimp_handle_transform_tool_get_undo_desc (GimpTransformTool *tr_tool);
static TransformAction
gimp_handle_transform_tool_pick_function (GimpTransformTool *tr_tool,
@@ -115,9 +116,7 @@ static TransformAction
static void gimp_handle_transform_tool_cursor_update (GimpTransformTool *tr_tool,
GimpCursorType *cursor,
GimpCursorModifier *modifier);
-static void gimp_handle_transform_tool_draw_gui (GimpTransformTool *tr_tool,
- gint handle_w,
- gint handle_h);
+static void gimp_handle_transform_tool_draw_gui (GimpTransformTool *tr_tool);
static gboolean is_handle_position_valid (GimpTransformTool *tr_tool,
gint active_handle);
@@ -606,7 +605,8 @@ gimp_handle_transform_tool_motion (GimpTransformTool *tr_tool)
}
static void
-gimp_handle_transform_tool_recalc_matrix (GimpTransformTool *tr_tool)
+gimp_handle_transform_tool_recalc_matrix (GimpTransformTool *tr_tool,
+ GimpToolWidget *widget)
{
GimpHandleTransformTool *ht_tool = GIMP_HANDLE_TRANSFORM_TOOL (tr_tool);
gdouble coeff[8 * 9];
@@ -765,9 +765,7 @@ gimp_handle_transform_tool_cursor_update (GimpTransformTool *tr_tool,
}
static void
-gimp_handle_transform_tool_draw_gui (GimpTransformTool *tr_tool,
- gint handle_w,
- gint handle_h)
+gimp_handle_transform_tool_draw_gui (GimpTransformTool *tr_tool)
{
GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tr_tool);
gint i;
diff --git a/app/tools/gimpperspectivetool.c b/app/tools/gimpperspectivetool.c
index c912b52..baa8fe4 100644
--- a/app/tools/gimpperspectivetool.c
+++ b/app/tools/gimpperspectivetool.c
@@ -17,8 +17,6 @@
#include "config.h"
-#include <string.h>
-
#include <gegl.h>
#include <gtk/gtk.h>
@@ -29,12 +27,12 @@
#include "core/gimp-transform-utils.h"
#include "core/gimpimage.h"
-#include "core/gimpdrawable-transform.h"
#include "widgets/gimphelp-ids.h"
#include "display/gimpdisplay.h"
#include "display/gimptoolgui.h"
+#include "display/gimptooltransformgrid.h"
#include "gimpperspectivetool.h"
#include "gimptoolcontrol.h"
@@ -59,12 +57,16 @@ enum
/* local function prototypes */
-static void gimp_perspective_tool_dialog (GimpTransformTool *tr_tool);
-static void gimp_perspective_tool_dialog_update (GimpTransformTool *tr_tool);
-static void gimp_perspective_tool_prepare (GimpTransformTool *tr_tool);
-static void gimp_perspective_tool_motion (GimpTransformTool *tr_tool);
-static void gimp_perspective_tool_recalc_matrix (GimpTransformTool *tr_tool);
-static gchar * gimp_perspective_tool_get_undo_desc (GimpTransformTool *tr_tool);
+static void gimp_perspective_tool_dialog (GimpTransformTool *tr_tool);
+static void gimp_perspective_tool_dialog_update (GimpTransformTool *tr_tool);
+static void gimp_perspective_tool_prepare (GimpTransformTool *tr_tool);
+static GimpToolWidget * gimp_perspective_tool_get_widget (GimpTransformTool *tr_tool);
+static void gimp_perspective_tool_recalc_matrix (GimpTransformTool *tr_tool,
+ GimpToolWidget *widget);
+static gchar * gimp_perspective_tool_get_undo_desc (GimpTransformTool *tr_tool);
+
+static void gimp_perspective_tool_widget_changed (GimpToolWidget *widget,
+ GimpTransformTool *tr_tool);
G_DEFINE_TYPE (GimpPerspectiveTool, gimp_perspective_tool,
@@ -97,7 +99,7 @@ gimp_perspective_tool_class_init (GimpPerspectiveToolClass *klass)
trans_class->dialog = gimp_perspective_tool_dialog;
trans_class->dialog_update = gimp_perspective_tool_dialog_update;
trans_class->prepare = gimp_perspective_tool_prepare;
- trans_class->motion = gimp_perspective_tool_motion;
+ trans_class->get_widget = gimp_perspective_tool_get_widget;
trans_class->recalc_matrix = gimp_perspective_tool_recalc_matrix;
trans_class->get_undo_desc = gimp_perspective_tool_get_undo_desc;
}
@@ -111,13 +113,9 @@ gimp_perspective_tool_init (GimpPerspectiveTool *perspective_tool)
gimp_tool_control_set_tool_cursor (tool->control,
GIMP_TOOL_CURSOR_PERSPECTIVE);
- tr_tool->progress_text = _("Perspective transformation");
-
- tr_tool->use_grid = TRUE;
- tr_tool->use_corner_handles = TRUE;
- tr_tool->use_center_handle = TRUE;
-
- tr_tool->does_perspective = TRUE;
+ tr_tool->progress_text = _("Perspective transformation");
+ tr_tool->use_grid = TRUE;
+ tr_tool->does_perspective = TRUE;
}
static void
@@ -185,54 +183,50 @@ gimp_perspective_tool_prepare (GimpTransformTool *tr_tool)
tr_tool->trans_info[Y3] = (gdouble) tr_tool->y2;
}
-static void
-gimp_perspective_tool_motion (GimpTransformTool *transform_tool)
+static GimpToolWidget *
+gimp_perspective_tool_get_widget (GimpTransformTool *tr_tool)
{
- gdouble diff_x, diff_y;
-
- diff_x = transform_tool->curx - transform_tool->lastx;
- diff_y = transform_tool->cury - transform_tool->lasty;
-
- switch (transform_tool->function)
- {
- case TRANSFORM_HANDLE_NW:
- transform_tool->trans_info[X0] += diff_x;
- transform_tool->trans_info[Y0] += diff_y;
- break;
-
- case TRANSFORM_HANDLE_NE:
- transform_tool->trans_info[X1] += diff_x;
- transform_tool->trans_info[Y1] += diff_y;
- break;
-
- case TRANSFORM_HANDLE_SW:
- transform_tool->trans_info[X2] += diff_x;
- transform_tool->trans_info[Y2] += diff_y;
- break;
-
- case TRANSFORM_HANDLE_SE:
- transform_tool->trans_info[X3] += diff_x;
- transform_tool->trans_info[Y3] += diff_y;
- break;
-
- case TRANSFORM_HANDLE_CENTER:
- transform_tool->trans_info[X0] += diff_x;
- transform_tool->trans_info[Y0] += diff_y;
- transform_tool->trans_info[X1] += diff_x;
- transform_tool->trans_info[Y1] += diff_y;
- transform_tool->trans_info[X2] += diff_x;
- transform_tool->trans_info[Y2] += diff_y;
- transform_tool->trans_info[X3] += diff_x;
- transform_tool->trans_info[Y3] += diff_y;
- break;
-
- default:
- break;
- }
+ GimpTool *tool = GIMP_TOOL (tr_tool);
+ GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
+ GimpDisplayShell *shell = gimp_display_get_shell (tool->display);
+ GimpToolWidget *widget;
+
+ widget = gimp_tool_transform_grid_new (shell,
+ &tr_tool->transform,
+ tr_tool->x1,
+ tr_tool->y1,
+ tr_tool->x2,
+ tr_tool->y2,
+ options->grid_type,
+ options->grid_size);
+
+ g_object_set (widget,
+ "inside-function", GIMP_TRANSFORM_FUNCTION_PERSPECTIVE,
+ "outside-function", GIMP_TRANSFORM_FUNCTION_PERSPECTIVE,
+ "use-perspective-handles", TRUE,
+ "use-center-handle", TRUE,
+ "constrain-move", options->constrain_move,
+ "constrain-scale", options->constrain_scale,
+ "constrain-rotate", options->constrain_rotate,
+ "constrain-shear", options->constrain_shear,
+ "constrain-perspective", options->constrain_perspective,
+ "frompivot-scale", options->frompivot_scale,
+ "frompivot-shear", options->frompivot_shear,
+ "frompivot-perspective", options->frompivot_perspective,
+ "cornersnap", options->cornersnap,
+ "fixedpivot", options->fixedpivot,
+ NULL);
+
+ g_signal_connect (widget, "changed",
+ G_CALLBACK (gimp_perspective_tool_widget_changed),
+ tr_tool);
+
+ return widget;
}
static void
-gimp_perspective_tool_recalc_matrix (GimpTransformTool *tr_tool)
+gimp_perspective_tool_recalc_matrix (GimpTransformTool *tr_tool,
+ GimpToolWidget *widget)
{
gimp_matrix3_identity (&tr_tool->transform);
gimp_transform_matrix_perspective (&tr_tool->transform,
@@ -248,6 +242,15 @@ gimp_perspective_tool_recalc_matrix (GimpTransformTool *tr_tool)
tr_tool->trans_info[Y2],
tr_tool->trans_info[X3],
tr_tool->trans_info[Y3]);
+
+ if (widget)
+ g_object_set (widget,
+ "transform", &tr_tool->transform,
+ "x1", (gdouble) tr_tool->x1,
+ "y1", (gdouble) tr_tool->y1,
+ "x2", (gdouble) tr_tool->x2,
+ "y2", (gdouble) tr_tool->y2,
+ NULL);
}
static gchar *
@@ -255,3 +258,35 @@ gimp_perspective_tool_get_undo_desc (GimpTransformTool *tr_tool)
{
return g_strdup (C_("undo-type", "Perspective"));
}
+
+static void
+gimp_perspective_tool_widget_changed (GimpToolWidget *widget,
+ GimpTransformTool *tr_tool)
+{
+ GimpMatrix3 *transform;
+
+ g_object_get (widget,
+ "transform", &transform,
+ NULL);
+
+ gimp_matrix3_transform_point (transform,
+ tr_tool->x1, tr_tool->y1,
+ &tr_tool->trans_info[X0],
+ &tr_tool->trans_info[Y0]);
+ gimp_matrix3_transform_point (transform,
+ tr_tool->x2, tr_tool->y1,
+ &tr_tool->trans_info[X1],
+ &tr_tool->trans_info[Y1]);
+ gimp_matrix3_transform_point (transform,
+ tr_tool->x1, tr_tool->y2,
+ &tr_tool->trans_info[X2],
+ &tr_tool->trans_info[Y2]);
+ gimp_matrix3_transform_point (transform,
+ tr_tool->x2, tr_tool->y2,
+ &tr_tool->trans_info[X3],
+ &tr_tool->trans_info[Y3]);
+
+ g_free (transform);
+
+ gimp_transform_tool_recalc_matrix (tr_tool, NULL);
+}
diff --git a/app/tools/gimprotatetool.c b/app/tools/gimprotatetool.c
index ba76ccd..44dffff 100644
--- a/app/tools/gimprotatetool.c
+++ b/app/tools/gimprotatetool.c
@@ -17,8 +17,6 @@
#include "config.h"
-#include <string.h>
-
#include <gegl.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
@@ -36,6 +34,7 @@
#include "display/gimpdisplay.h"
#include "display/gimpdisplayshell.h"
#include "display/gimptoolgui.h"
+#include "display/gimptoolrotategrid.h"
#include "gimprotatetool.h"
#include "gimptoolcontrol.h"
@@ -48,33 +47,35 @@
enum
{
ANGLE,
- REAL_ANGLE,
PIVOT_X,
PIVOT_Y
};
-#define FIFTEEN_DEG (G_PI / 12.0)
-#define SB_WIDTH 10
+#define SB_WIDTH 10
/* local function prototypes */
-static gboolean gimp_rotate_tool_key_press (GimpTool *tool,
- GdkEventKey *kevent,
- GimpDisplay *display);
+static gboolean gimp_rotate_tool_key_press (GimpTool *tool,
+ GdkEventKey *kevent,
+ GimpDisplay *display);
+
+static void gimp_rotate_tool_dialog (GimpTransformTool *tr_tool);
+static void gimp_rotate_tool_dialog_update (GimpTransformTool *tr_tool);
+static void gimp_rotate_tool_prepare (GimpTransformTool *tr_tool);
+static GimpToolWidget * gimp_rotate_tool_get_widget (GimpTransformTool *tr_tool);
+static void gimp_rotate_tool_recalc_matrix (GimpTransformTool *tr_tool,
+ GimpToolWidget *widget);
+static gchar * gimp_rotate_tool_get_undo_desc (GimpTransformTool *tr_tool);
-static void gimp_rotate_tool_dialog (GimpTransformTool *tr_tool);
-static void gimp_rotate_tool_dialog_update (GimpTransformTool *tr_tool);
-static void gimp_rotate_tool_prepare (GimpTransformTool *tr_tool);
-static void gimp_rotate_tool_motion (GimpTransformTool *tr_tool);
-static void gimp_rotate_tool_recalc_matrix (GimpTransformTool *tr_tool);
-static gchar * gimp_rotate_tool_get_undo_desc (GimpTransformTool *tr_tool);
+static void gimp_rotate_tool_widget_changed (GimpToolWidget *widget,
+ GimpTransformTool *tr_tool);
-static void rotate_angle_changed (GtkAdjustment *adj,
- GimpTransformTool *tr_tool);
-static void rotate_center_changed (GtkWidget *entry,
- GimpTransformTool *tr_tool);
+static void rotate_angle_changed (GtkAdjustment *adj,
+ GimpTransformTool *tr_tool);
+static void rotate_center_changed (GtkWidget *entry,
+ GimpTransformTool *tr_tool);
G_DEFINE_TYPE (GimpRotateTool, gimp_rotate_tool, GIMP_TYPE_TRANSFORM_TOOL)
@@ -110,7 +111,7 @@ gimp_rotate_tool_class_init (GimpRotateToolClass *klass)
trans_class->dialog = gimp_rotate_tool_dialog;
trans_class->dialog_update = gimp_rotate_tool_dialog_update;
trans_class->prepare = gimp_rotate_tool_prepare;
- trans_class->motion = gimp_rotate_tool_motion;
+ trans_class->get_widget = gimp_rotate_tool_get_widget;
trans_class->recalc_matrix = gimp_rotate_tool_recalc_matrix;
trans_class->get_undo_desc = gimp_rotate_tool_get_undo_desc;
@@ -125,10 +126,8 @@ gimp_rotate_tool_init (GimpRotateTool *rotate_tool)
gimp_tool_control_set_tool_cursor (tool->control, GIMP_TOOL_CURSOR_ROTATE);
- tr_tool->progress_text = _("Rotating");
-
- tr_tool->use_grid = TRUE;
- tr_tool->use_pivot_handle = TRUE;
+ tr_tool->progress_text = _("Rotating");
+ tr_tool->use_grid = TRUE;
}
static gboolean
@@ -258,13 +257,9 @@ 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[PIVOT_X] = tr_tool->px;
- tr_tool->trans_info[PIVOT_Y] = tr_tool->py;
+ tr_tool->trans_info[ANGLE] = 0.0;
+ tr_tool->trans_info[PIVOT_X] = (gdouble) (tr_tool->x1 + tr_tool->x2) / 2.0;
+ tr_tool->trans_info[PIVOT_Y] = (gdouble) (tr_tool->y1 + tr_tool->y2) / 2.0;
gimp_image_get_resolution (image, &xres, &yres);
@@ -299,78 +294,65 @@ gimp_rotate_tool_prepare (GimpTransformTool *tr_tool)
tr_tool);
}
-static void
-gimp_rotate_tool_motion (GimpTransformTool *tr_tool)
+static GimpToolWidget *
+gimp_rotate_tool_get_widget (GimpTransformTool *tr_tool)
{
+ GimpTool *tool = GIMP_TOOL (tr_tool);
GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
- gdouble angle1, angle2, angle;
- gdouble px, py;
- gdouble x1, y1, x2, y2;
-
- if (tr_tool->function == TRANSFORM_HANDLE_PIVOT)
- {
- tr_tool->trans_info[PIVOT_X] = tr_tool->curx;
- tr_tool->trans_info[PIVOT_Y] = tr_tool->cury;
-
- return;
- }
-
- px = tr_tool->trans_info[PIVOT_X];
- py = tr_tool->trans_info[PIVOT_Y];
-
- 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);
-
- /* find the angle */
- angle2 = atan2 (y2, x2);
-
- angle = angle2 - angle1;
-
- if (angle > G_PI || angle < -G_PI)
- angle = angle2 - ((angle1 < 0) ? 2.0 * G_PI + angle1 : angle1 - 2.0 * G_PI);
-
- /* increment the transform tool's angle */
- tr_tool->trans_info[REAL_ANGLE] += angle;
-
- /* limit the angle to between -180 and 180 degrees */
- if (tr_tool->trans_info[REAL_ANGLE] < - G_PI)
- {
- tr_tool->trans_info[REAL_ANGLE] += 2.0 * G_PI;
- }
- else if (tr_tool->trans_info[REAL_ANGLE] > G_PI)
- {
- tr_tool->trans_info[REAL_ANGLE] -= 2.0 * G_PI;
- }
+ GimpDisplayShell *shell = gimp_display_get_shell (tool->display);
+ GimpToolWidget *widget;
+
+ widget = gimp_tool_rotate_grid_new (shell,
+ tr_tool->x1,
+ tr_tool->y1,
+ tr_tool->x2,
+ tr_tool->y2,
+ tr_tool->trans_info[PIVOT_X],
+ tr_tool->trans_info[PIVOT_Y],
+ tr_tool->trans_info[ANGLE]);
+
+ g_object_set (widget,
+ "guide-type", options->grid_type,
+ "n-guides", options->grid_size,
+ "inside-function", GIMP_TRANSFORM_FUNCTION_ROTATE,
+ "outside-function", GIMP_TRANSFORM_FUNCTION_ROTATE,
+ "use-pivot-handle", TRUE,
+ "constrain-move", options->constrain_move,
+ "constrain-scale", options->constrain_scale,
+ "constrain-rotate", options->constrain_rotate,
+ "constrain-shear", options->constrain_shear,
+ "constrain-perspective", options->constrain_perspective,
+ "frompivot-scale", options->frompivot_scale,
+ "frompivot-shear", options->frompivot_shear,
+ "frompivot-perspective", options->frompivot_perspective,
+ "cornersnap", options->cornersnap,
+ "fixedpivot", options->fixedpivot,
+ NULL);
+
+ g_signal_connect (widget, "changed",
+ G_CALLBACK (gimp_rotate_tool_widget_changed),
+ tr_tool);
- /* constrain the angle to 15-degree multiples if ctrl is held down */
- if (options->constrain_rotate)
- {
- tr_tool->trans_info[ANGLE] =
- FIFTEEN_DEG * (gint) ((tr_tool->trans_info[REAL_ANGLE] +
- FIFTEEN_DEG / 2.0) / FIFTEEN_DEG);
- }
- else
- {
- tr_tool->trans_info[ANGLE] = tr_tool->trans_info[REAL_ANGLE];
- }
+ return widget;
}
static void
-gimp_rotate_tool_recalc_matrix (GimpTransformTool *tr_tool)
+gimp_rotate_tool_recalc_matrix (GimpTransformTool *tr_tool,
+ GimpToolWidget *widget)
{
- 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->px,
- tr_tool->py,
+ tr_tool->trans_info[PIVOT_X],
+ tr_tool->trans_info[PIVOT_Y],
tr_tool->trans_info[ANGLE]);
+
+ if (widget)
+ g_object_set (widget,
+ "transform", &tr_tool->transform,
+ "angle", tr_tool->trans_info[ANGLE],
+ "pivot-x", tr_tool->trans_info[PIVOT_X],
+ "pivot-y", tr_tool->trans_info[PIVOT_Y],
+ NULL);
}
static gchar *
@@ -384,6 +366,19 @@ gimp_rotate_tool_get_undo_desc (GimpTransformTool *tr_tool)
}
static void
+gimp_rotate_tool_widget_changed (GimpToolWidget *widget,
+ GimpTransformTool *tr_tool)
+{
+ g_object_get (widget,
+ "angle", &tr_tool->trans_info[ANGLE],
+ "pivot-x", &tr_tool->trans_info[PIVOT_X],
+ "pivot-y", &tr_tool->trans_info[PIVOT_Y],
+ NULL);
+
+ gimp_transform_tool_recalc_matrix (tr_tool, NULL);
+}
+
+static void
rotate_angle_changed (GtkAdjustment *adj,
GimpTransformTool *tr_tool)
{
@@ -393,15 +388,11 @@ rotate_angle_changed (GtkAdjustment *adj,
if (ABS (value - tr_tool->trans_info[ANGLE]) > ANGLE_EPSILON)
{
- gimp_draw_tool_pause (GIMP_DRAW_TOOL (tr_tool));
-
- tr_tool->trans_info[REAL_ANGLE] = tr_tool->trans_info[ANGLE] = value;
+ tr_tool->trans_info[ANGLE] = value;
gimp_transform_tool_push_internal_undo (tr_tool);
- gimp_transform_tool_recalc_matrix (tr_tool);
-
- gimp_draw_tool_resume (GIMP_DRAW_TOOL (tr_tool));
+ gimp_transform_tool_recalc_matrix (tr_tool, tr_tool->widget);
}
#undef ANGLE_EPSILON
@@ -417,17 +408,11 @@ rotate_center_changed (GtkWidget *widget,
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[PIVOT_X] = px;
tr_tool->trans_info[PIVOT_Y] = py;
- tr_tool->px = px;
- tr_tool->py = py;
gimp_transform_tool_push_internal_undo (tr_tool);
- gimp_transform_tool_recalc_matrix (tr_tool);
-
- gimp_draw_tool_resume (GIMP_DRAW_TOOL (tr_tool));
+ gimp_transform_tool_recalc_matrix (tr_tool, tr_tool->widget);
}
}
diff --git a/app/tools/gimpscaletool.c b/app/tools/gimpscaletool.c
index c5cf5bd..320b694 100644
--- a/app/tools/gimpscaletool.c
+++ b/app/tools/gimpscaletool.c
@@ -29,7 +29,6 @@
#include "core/gimp-transform-utils.h"
#include "core/gimpimage.h"
-#include "core/gimpdrawable-transform.h"
#include "widgets/gimphelp-ids.h"
#include "widgets/gimpsizebox.h"
@@ -37,6 +36,7 @@
#include "display/gimpdisplay.h"
#include "display/gimpdisplayshell.h"
#include "display/gimptoolgui.h"
+#include "display/gimptooltransformgrid.h"
#include "gimpscaletool.h"
#include "gimptoolcontrol.h"
@@ -51,26 +51,26 @@ enum
X0,
Y0,
X1,
- Y1,
- X2,
- Y2,
- X3,
- Y3
+ Y1
};
/* local function prototypes */
-static void gimp_scale_tool_dialog (GimpTransformTool *tr_tool);
-static void gimp_scale_tool_dialog_update (GimpTransformTool *tr_tool);
-static void gimp_scale_tool_prepare (GimpTransformTool *tr_tool);
-static void gimp_scale_tool_motion (GimpTransformTool *tr_tool);
-static void gimp_scale_tool_recalc_matrix (GimpTransformTool *tr_tool);
-static gchar * gimp_scale_tool_get_undo_desc (GimpTransformTool *tr_tool);
+static void gimp_scale_tool_dialog (GimpTransformTool *tr_tool);
+static void gimp_scale_tool_dialog_update (GimpTransformTool *tr_tool);
+static void gimp_scale_tool_prepare (GimpTransformTool *tr_tool);
+static GimpToolWidget * gimp_scale_tool_get_widget (GimpTransformTool *tr_tool);
+static void gimp_scale_tool_recalc_matrix (GimpTransformTool *tr_tool,
+ GimpToolWidget *widget);
+static gchar * gimp_scale_tool_get_undo_desc (GimpTransformTool *tr_tool);
-static void gimp_scale_tool_size_notify (GtkWidget *box,
- GParamSpec *pspec,
- GimpTransformTool *tr_tool);
+static void gimp_scale_tool_widget_changed (GimpToolWidget *widget,
+ GimpTransformTool *tr_tool);
+
+static void gimp_scale_tool_size_notify (GtkWidget *box,
+ GParamSpec *pspec,
+ GimpTransformTool *tr_tool);
G_DEFINE_TYPE (GimpScaleTool, gimp_scale_tool, GIMP_TYPE_TRANSFORM_TOOL)
@@ -103,7 +103,7 @@ gimp_scale_tool_class_init (GimpScaleToolClass *klass)
trans_class->dialog = gimp_scale_tool_dialog;
trans_class->dialog_update = gimp_scale_tool_dialog_update;
trans_class->prepare = gimp_scale_tool_prepare;
- trans_class->motion = gimp_scale_tool_motion;
+ trans_class->get_widget = gimp_scale_tool_get_widget;
trans_class->recalc_matrix = gimp_scale_tool_recalc_matrix;
trans_class->get_undo_desc = gimp_scale_tool_get_undo_desc;
@@ -118,12 +118,8 @@ gimp_scale_tool_init (GimpScaleTool *scale_tool)
gimp_tool_control_set_tool_cursor (tool->control, GIMP_TOOL_CURSOR_RESIZE);
- tr_tool->progress_text = _("Scaling");
-
- tr_tool->use_grid = TRUE;
- tr_tool->use_corner_handles = TRUE;
- tr_tool->use_side_handles = TRUE;
- tr_tool->use_center_handle = TRUE;
+ tr_tool->progress_text = _("Scaling");
+ tr_tool->use_grid = TRUE;
}
static void
@@ -135,9 +131,11 @@ static void
gimp_scale_tool_dialog_update (GimpTransformTool *tr_tool)
{
GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
+ gint width;
+ gint height;
- gint width = ROUND (tr_tool->trans_info[X1] - tr_tool->trans_info[X0]);
- gint height = ROUND (tr_tool->trans_info[Y1] - tr_tool->trans_info[Y0]);
+ width = ROUND (tr_tool->trans_info[X1] - tr_tool->trans_info[X0]);
+ height = ROUND (tr_tool->trans_info[Y1] - tr_tool->trans_info[Y0]);
g_object_set (GIMP_SCALE_TOOL (tr_tool)->box,
"width", width,
@@ -193,131 +191,51 @@ gimp_scale_tool_prepare (GimpTransformTool *tr_tool)
tr_tool);
}
-static void
-gimp_scale_tool_motion (GimpTransformTool *tr_tool)
+static GimpToolWidget *
+gimp_scale_tool_get_widget (GimpTransformTool *tr_tool)
{
+ GimpTool *tool = GIMP_TOOL (tr_tool);
GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
- gdouble *x1;
- gdouble *y1;
- gdouble *x2;
- gdouble *y2;
- gint dir_x;
- gint dir_y;
- gdouble diff_x = tr_tool->curx - tr_tool->lastx;
- gdouble diff_y = tr_tool->cury - tr_tool->lasty;
-
- switch (tr_tool->function)
- {
- case TRANSFORM_HANDLE_N:
- diff_x = 0; /* and fall through */
- case TRANSFORM_HANDLE_NW:
- x1 = &tr_tool->trans_info[X0];
- y1 = &tr_tool->trans_info[Y0];
- x2 = &tr_tool->trans_info[X1];
- y2 = &tr_tool->trans_info[Y1];
- dir_x = dir_y = 1;
- break;
-
- case TRANSFORM_HANDLE_E:
- diff_y = 0; /* and fall through */
- case TRANSFORM_HANDLE_NE:
- x1 = &tr_tool->trans_info[X1];
- y1 = &tr_tool->trans_info[Y0];
- x2 = &tr_tool->trans_info[X0];
- y2 = &tr_tool->trans_info[Y1];
- dir_x = -1;
- dir_y = 1;
- break;
-
- case TRANSFORM_HANDLE_W:
- diff_y = 0; /* and fall through */
- case TRANSFORM_HANDLE_SW:
- x1 = &tr_tool->trans_info[X0];
- y1 = &tr_tool->trans_info[Y1];
- x2 = &tr_tool->trans_info[X1];
- y2 = &tr_tool->trans_info[Y0];
- dir_x = 1;
- dir_y = -1;
- break;
-
- case TRANSFORM_HANDLE_S:
- diff_x = 0; /* and fall through */
- case TRANSFORM_HANDLE_SE:
- x1 = &tr_tool->trans_info[X1];
- y1 = &tr_tool->trans_info[Y1];
- x2 = &tr_tool->trans_info[X0];
- y2 = &tr_tool->trans_info[Y0];
- dir_x = dir_y = -1;
- break;
-
- case TRANSFORM_HANDLE_CENTER:
- tr_tool->trans_info[X0] += diff_x;
- tr_tool->trans_info[Y0] += diff_y;
- tr_tool->trans_info[X1] += diff_x;
- tr_tool->trans_info[Y1] += diff_y;
- tr_tool->trans_info[X2] += diff_x;
- tr_tool->trans_info[Y2] += diff_y;
- tr_tool->trans_info[X3] += diff_x;
- tr_tool->trans_info[Y3] += diff_y;
- return;
-
- default:
- return;
- }
-
- *x1 += diff_x;
- *y1 += diff_y;
-
- /* if control is being held, constrain the aspect ratio */
- if (options->constrain_scale)
- {
- /* FIXME: improve this */
- gdouble h = tr_tool->trans_info[Y1] - tr_tool->trans_info[Y0];
-
- switch (tr_tool->function)
- {
- case TRANSFORM_HANDLE_NW:
- case TRANSFORM_HANDLE_SW:
- tr_tool->trans_info[X0] =
- tr_tool->trans_info[X1] - tr_tool->aspect * h;
- break;
-
- case TRANSFORM_HANDLE_NE:
- case TRANSFORM_HANDLE_SE:
- tr_tool->trans_info[X1] =
- tr_tool->trans_info[X0] + tr_tool->aspect * h;
- break;
-
- default:
- break;
- }
- }
+ GimpDisplayShell *shell = gimp_display_get_shell (tool->display);
+ GimpToolWidget *widget;
+
+ widget = gimp_tool_transform_grid_new (shell,
+ &tr_tool->transform,
+ tr_tool->x1,
+ tr_tool->y1,
+ tr_tool->x2,
+ tr_tool->y2,
+ options->grid_type,
+ options->grid_size);
+
+ g_object_set (widget,
+ "inside-function", GIMP_TRANSFORM_FUNCTION_SCALE,
+ "outside-function", GIMP_TRANSFORM_FUNCTION_SCALE,
+ "use-corner-handles", TRUE,
+ "use-side-handles", TRUE,
+ "use-center-handle", TRUE,
+ "constrain-move", options->constrain_move,
+ "constrain-scale", options->constrain_scale,
+ "constrain-rotate", options->constrain_rotate,
+ "constrain-shear", options->constrain_shear,
+ "constrain-perspective", options->constrain_perspective,
+ "frompivot-scale", options->frompivot_scale,
+ "frompivot-shear", options->frompivot_shear,
+ "frompivot-perspective", options->frompivot_perspective,
+ "cornersnap", options->cornersnap,
+ "fixedpivot", options->fixedpivot,
+ NULL);
- if (dir_x > 0)
- {
- if (*x1 >= *x2)
- *x1 = *x2 - 1;
- }
- else
- {
- if (*x1 <= *x2)
- *x1 = *x2 + 1;
- }
+ g_signal_connect (widget, "changed",
+ G_CALLBACK (gimp_scale_tool_widget_changed),
+ tr_tool);
- if (dir_y > 0)
- {
- if (*y1 >= *y2)
- *y1 = *y2 - 1;
- }
- else
- {
- if (*y1 <= *y2)
- *y1 = *y2 + 1;
- }
+ return widget;
}
static void
-gimp_scale_tool_recalc_matrix (GimpTransformTool *tr_tool)
+gimp_scale_tool_recalc_matrix (GimpTransformTool *tr_tool,
+ GimpToolWidget *widget)
{
gimp_matrix3_identity (&tr_tool->transform);
gimp_transform_matrix_scale (&tr_tool->transform,
@@ -329,6 +247,15 @@ gimp_scale_tool_recalc_matrix (GimpTransformTool *tr_tool)
tr_tool->trans_info[Y0],
tr_tool->trans_info[X1] - tr_tool->trans_info[X0],
tr_tool->trans_info[Y1] - tr_tool->trans_info[Y0]);
+
+ if (widget)
+ g_object_set (widget,
+ "transform", &tr_tool->transform,
+ "x1", (gdouble) tr_tool->x1,
+ "y1", (gdouble) tr_tool->y1,
+ "x2", (gdouble) tr_tool->x2,
+ "y2", (gdouble) tr_tool->y2,
+ NULL);
}
static gchar *
@@ -342,6 +269,30 @@ gimp_scale_tool_get_undo_desc (GimpTransformTool *tr_tool)
}
static void
+gimp_scale_tool_widget_changed (GimpToolWidget *widget,
+ GimpTransformTool *tr_tool)
+{
+ GimpMatrix3 *transform;
+
+ g_object_get (widget,
+ "transform", &transform,
+ NULL);
+
+ gimp_matrix3_transform_point (transform,
+ tr_tool->x1, tr_tool->y1,
+ &tr_tool->trans_info[X0],
+ &tr_tool->trans_info[Y0]);
+ gimp_matrix3_transform_point (transform,
+ tr_tool->x2, tr_tool->y2,
+ &tr_tool->trans_info[X1],
+ &tr_tool->trans_info[Y1]);
+
+ g_free (transform);
+
+ gimp_transform_tool_recalc_matrix (tr_tool, NULL);
+}
+
+static void
gimp_scale_tool_size_notify (GtkWidget *box,
GParamSpec *pspec,
GimpTransformTool *tr_tool)
@@ -366,16 +317,12 @@ gimp_scale_tool_size_notify (GtkWidget *box,
if ((width != old_width) || (height != old_height))
{
- gimp_draw_tool_pause (GIMP_DRAW_TOOL (tr_tool));
-
tr_tool->trans_info[X1] = tr_tool->trans_info[X0] + width;
tr_tool->trans_info[Y1] = tr_tool->trans_info[Y0] + height;
gimp_transform_tool_push_internal_undo (tr_tool);
- gimp_transform_tool_recalc_matrix (tr_tool);
-
- gimp_draw_tool_resume (GIMP_DRAW_TOOL (tr_tool));
+ gimp_transform_tool_recalc_matrix (tr_tool, tr_tool->widget);
}
}
else if (! strcmp (pspec->name, "keep-aspect"))
@@ -396,11 +343,6 @@ gimp_scale_tool_size_notify (GtkWidget *box,
"height", &height,
NULL);
- /* Take the aspect ratio from the size box when the user
- * activates the constraint by pressing the chain button.
- */
- tr_tool->aspect = (gdouble) width / (gdouble) height;
-
g_object_set (options,
"constrain-scale", constrain,
NULL);
diff --git a/app/tools/gimpsheartool.c b/app/tools/gimpsheartool.c
index 68f4620..6bd2118 100644
--- a/app/tools/gimpsheartool.c
+++ b/app/tools/gimpsheartool.c
@@ -17,9 +17,6 @@
#include "config.h"
-#include <stdlib.h>
-#include <string.h>
-
#include <gegl.h>
#include <gtk/gtk.h>
@@ -33,7 +30,9 @@
#include "widgets/gimphelp-ids.h"
#include "widgets/gimpspinscale.h"
+#include "display/gimpdisplay.h"
#include "display/gimptoolgui.h"
+#include "display/gimptoolsheargrid.h"
#include "gimpsheartool.h"
#include "gimptoolcontrol.h"
@@ -45,31 +44,33 @@
/* index into trans_info array */
enum
{
- HORZ_OR_VERT,
- XSHEAR,
- YSHEAR
+ ORIENTATION,
+ SHEAR_X,
+ SHEAR_Y
};
-/* the minimum movement before direction of shear can be determined (pixels) */
-#define MIN_MOVE 5
-#define SB_WIDTH 10
+#define SB_WIDTH 10
/* local function prototypes */
-static void gimp_shear_tool_dialog (GimpTransformTool *tr_tool);
-static void gimp_shear_tool_dialog_update (GimpTransformTool *tr_tool);
+static void gimp_shear_tool_dialog (GimpTransformTool *tr_tool);
+static void gimp_shear_tool_dialog_update (GimpTransformTool *tr_tool);
+
+static void gimp_shear_tool_prepare (GimpTransformTool *tr_tool);
+static GimpToolWidget * gimp_shear_tool_get_widget (GimpTransformTool *tr_tool);
+static void gimp_shear_tool_recalc_matrix (GimpTransformTool *tr_tool,
+ GimpToolWidget *widget);
+static gchar * gimp_shear_tool_get_undo_desc (GimpTransformTool *tr_tool);
-static void gimp_shear_tool_prepare (GimpTransformTool *tr_tool);
-static void gimp_shear_tool_motion (GimpTransformTool *tr_tool);
-static void gimp_shear_tool_recalc_matrix (GimpTransformTool *tr_tool);
-static gchar * gimp_shear_tool_get_undo_desc (GimpTransformTool *tr_tool);
+static void gimp_shear_tool_widget_changed (GimpToolWidget *widget,
+ GimpTransformTool *tr_tool);
-static void shear_x_mag_changed (GtkAdjustment *adj,
- GimpTransformTool *tr_tool);
-static void shear_y_mag_changed (GtkAdjustment *adj,
- GimpTransformTool *tr_tool);
+static void shear_x_mag_changed (GtkAdjustment *adj,
+ GimpTransformTool *tr_tool);
+static void shear_y_mag_changed (GtkAdjustment *adj,
+ GimpTransformTool *tr_tool);
G_DEFINE_TYPE (GimpShearTool, gimp_shear_tool, GIMP_TYPE_TRANSFORM_TOOL)
@@ -100,7 +101,7 @@ gimp_shear_tool_class_init (GimpShearToolClass *klass)
trans_class->dialog = gimp_shear_tool_dialog;
trans_class->dialog_update = gimp_shear_tool_dialog_update;
trans_class->prepare = gimp_shear_tool_prepare;
- trans_class->motion = gimp_shear_tool_motion;
+ trans_class->get_widget = gimp_shear_tool_get_widget;
trans_class->recalc_matrix = gimp_shear_tool_recalc_matrix;
trans_class->get_undo_desc = gimp_shear_tool_get_undo_desc;
@@ -116,7 +117,6 @@ gimp_shear_tool_init (GimpShearTool *shear_tool)
gimp_tool_control_set_tool_cursor (tool->control, GIMP_TOOL_CURSOR_SHEAR);
tr_tool->progress_text = _("Shearing");
-
tr_tool->use_grid = TRUE;
}
@@ -160,83 +160,75 @@ gimp_shear_tool_dialog_update (GimpTransformTool *tr_tool)
{
GimpShearTool *shear = GIMP_SHEAR_TOOL (tr_tool);
- gtk_adjustment_set_value (shear->x_adj, tr_tool->trans_info[XSHEAR]);
- gtk_adjustment_set_value (shear->y_adj, tr_tool->trans_info[YSHEAR]);
+ gtk_adjustment_set_value (shear->x_adj, tr_tool->trans_info[SHEAR_X]);
+ gtk_adjustment_set_value (shear->y_adj, tr_tool->trans_info[SHEAR_Y]);
}
static void
gimp_shear_tool_prepare (GimpTransformTool *tr_tool)
{
- tr_tool->trans_info[HORZ_OR_VERT] = GIMP_ORIENTATION_UNKNOWN;
- tr_tool->trans_info[XSHEAR] = 0.0;
- tr_tool->trans_info[YSHEAR] = 0.0;
+ tr_tool->trans_info[ORIENTATION] = GIMP_ORIENTATION_UNKNOWN;
+ tr_tool->trans_info[SHEAR_X] = 0.0;
+ tr_tool->trans_info[SHEAR_Y] = 0.0;
}
-static void
-gimp_shear_tool_motion (GimpTransformTool *tr_tool)
+static GimpToolWidget *
+gimp_shear_tool_get_widget (GimpTransformTool *tr_tool)
{
- gdouble diffx = tr_tool->curx - tr_tool->lastx;
- gdouble diffy = tr_tool->cury - tr_tool->lasty;
-
- /* If we haven't yet decided on which way to control shearing
- * decide using the maximum differential
- */
-
- if (tr_tool->trans_info[HORZ_OR_VERT] == GIMP_ORIENTATION_UNKNOWN)
- {
- if (ABS (diffx) > MIN_MOVE || ABS (diffy) > MIN_MOVE)
- {
- if (ABS (diffx) > ABS (diffy))
- {
- tr_tool->trans_info[HORZ_OR_VERT] = GIMP_ORIENTATION_HORIZONTAL;
- tr_tool->trans_info[XSHEAR] = 0.0;
- }
- else
- {
- tr_tool->trans_info[HORZ_OR_VERT] = GIMP_ORIENTATION_VERTICAL;
- tr_tool->trans_info[XSHEAR] = 0.0;
- }
- }
- /* set the current coords to the last ones */
- else
- {
- tr_tool->curx = tr_tool->lastx;
- tr_tool->cury = tr_tool->lasty;
- }
- }
+ GimpTool *tool = GIMP_TOOL (tr_tool);
+ GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
+ GimpDisplayShell *shell = gimp_display_get_shell (tool->display);
+ GimpToolWidget *widget;
+
+ widget = gimp_tool_shear_grid_new (shell,
+ tr_tool->x1,
+ tr_tool->y1,
+ tr_tool->x2,
+ tr_tool->y2,
+ tr_tool->trans_info[ORIENTATION],
+ tr_tool->trans_info[SHEAR_X],
+ tr_tool->trans_info[SHEAR_Y]);
+
+ g_object_set (widget,
+ "guide-type", options->grid_type,
+ "n-guides", options->grid_size,
+ "inside-function", GIMP_TRANSFORM_FUNCTION_SHEAR,
+ "outside-function", GIMP_TRANSFORM_FUNCTION_SHEAR,
+ "constrain-move", options->constrain_move,
+ "constrain-scale", options->constrain_scale,
+ "constrain-rotate", options->constrain_rotate,
+ "constrain-shear", options->constrain_shear,
+ "constrain-perspective", options->constrain_perspective,
+ "frompivot-scale", options->frompivot_scale,
+ "frompivot-shear", TRUE,
+ "frompivot-perspective", options->frompivot_perspective,
+ "cornersnap", options->cornersnap,
+ "fixedpivot", options->fixedpivot,
+ NULL);
+
+ g_signal_connect (widget, "changed",
+ G_CALLBACK (gimp_shear_tool_widget_changed),
+ tr_tool);
- /* if the direction is known, keep track of the magnitude */
- if (tr_tool->trans_info[HORZ_OR_VERT] == GIMP_ORIENTATION_HORIZONTAL)
- {
- if (tr_tool->cury > (tr_tool->ty1 + tr_tool->ty3) / 2)
- tr_tool->trans_info[XSHEAR] += diffx;
- else
- tr_tool->trans_info[XSHEAR] -= diffx;
- }
- else if (tr_tool->trans_info[HORZ_OR_VERT] == GIMP_ORIENTATION_VERTICAL)
- {
- if (tr_tool->curx > (tr_tool->tx1 + tr_tool->tx2) / 2)
- tr_tool->trans_info[YSHEAR] += diffy;
- else
- tr_tool->trans_info[YSHEAR] -= diffy;
- }
+ return widget;
}
static void
-gimp_shear_tool_recalc_matrix (GimpTransformTool *tr_tool)
+gimp_shear_tool_recalc_matrix (GimpTransformTool *tr_tool,
+ GimpToolWidget *widget)
{
gdouble amount;
- if (tr_tool->trans_info[XSHEAR] == 0.0 &&
- tr_tool->trans_info[YSHEAR] == 0.0)
+ if (tr_tool->trans_info[SHEAR_X] == 0.0 &&
+ tr_tool->trans_info[SHEAR_Y] == 0.0)
{
- tr_tool->trans_info[HORZ_OR_VERT] = GIMP_ORIENTATION_UNKNOWN;
+ tr_tool->trans_info[ORIENTATION] = GIMP_ORIENTATION_UNKNOWN;
}
- if (tr_tool->trans_info[HORZ_OR_VERT] == GIMP_ORIENTATION_HORIZONTAL)
- amount = tr_tool->trans_info[XSHEAR];
+ if (tr_tool->trans_info[ORIENTATION] == GIMP_ORIENTATION_HORIZONTAL)
+ amount = tr_tool->trans_info[SHEAR_X];
else
- amount = tr_tool->trans_info[YSHEAR];
+ amount = tr_tool->trans_info[SHEAR_Y];
gimp_matrix3_identity (&tr_tool->transform);
gimp_transform_matrix_shear (&tr_tool->transform,
@@ -244,17 +236,29 @@ gimp_shear_tool_recalc_matrix (GimpTransformTool *tr_tool)
tr_tool->y1,
tr_tool->x2 - tr_tool->x1,
tr_tool->y2 - tr_tool->y1,
- tr_tool->trans_info[HORZ_OR_VERT],
+ tr_tool->trans_info[ORIENTATION],
amount);
+
+ if (widget)
+ g_object_set (widget,
+ "transform", &tr_tool->transform,
+ "x1", (gdouble) tr_tool->x1,
+ "y1", (gdouble) tr_tool->y1,
+ "x2", (gdouble) tr_tool->x2,
+ "y2", (gdouble) tr_tool->y2,
+ "orientation", (gint) tr_tool->trans_info[ORIENTATION],
+ "shear-x", tr_tool->trans_info[SHEAR_X],
+ "shear-y", tr_tool->trans_info[SHEAR_Y],
+ NULL);
}
static gchar *
gimp_shear_tool_get_undo_desc (GimpTransformTool *tr_tool)
{
- gdouble x = tr_tool->trans_info[XSHEAR];
- gdouble y = tr_tool->trans_info[YSHEAR];
+ gdouble x = tr_tool->trans_info[SHEAR_X];
+ gdouble y = tr_tool->trans_info[SHEAR_Y];
- switch ((gint) tr_tool->trans_info[HORZ_OR_VERT])
+ switch ((gint) tr_tool->trans_info[ORIENTATION])
{
case GIMP_ORIENTATION_HORIZONTAL:
return g_strdup_printf (C_("undo-type", "Shear horizontally by %-3.3g"),
@@ -272,25 +276,38 @@ gimp_shear_tool_get_undo_desc (GimpTransformTool *tr_tool)
}
static void
+gimp_shear_tool_widget_changed (GimpToolWidget *widget,
+ GimpTransformTool *tr_tool)
+{
+ GimpOrientationType orientation;
+
+ g_object_get (widget,
+ "orientation", &orientation,
+ "shear-x", &tr_tool->trans_info[SHEAR_X],
+ "shear-y", &tr_tool->trans_info[SHEAR_Y],
+ NULL);
+
+ tr_tool->trans_info[ORIENTATION] = orientation;
+
+ gimp_transform_tool_recalc_matrix (tr_tool, NULL);
+}
+
+static void
shear_x_mag_changed (GtkAdjustment *adj,
GimpTransformTool *tr_tool)
{
gdouble value = gtk_adjustment_get_value (adj);
- if (value != tr_tool->trans_info[XSHEAR])
+ if (value != tr_tool->trans_info[SHEAR_X])
{
- gimp_draw_tool_pause (GIMP_DRAW_TOOL (tr_tool));
-
- if (tr_tool->trans_info[HORZ_OR_VERT] == GIMP_ORIENTATION_UNKNOWN)
- tr_tool->trans_info[HORZ_OR_VERT] = GIMP_ORIENTATION_HORIZONTAL;
+ if (tr_tool->trans_info[ORIENTATION] == GIMP_ORIENTATION_UNKNOWN)
+ tr_tool->trans_info[ORIENTATION] = GIMP_ORIENTATION_HORIZONTAL;
- tr_tool->trans_info[XSHEAR] = value;
+ tr_tool->trans_info[SHEAR_X] = value;
gimp_transform_tool_push_internal_undo (tr_tool);
- gimp_transform_tool_recalc_matrix (tr_tool);
-
- gimp_draw_tool_resume (GIMP_DRAW_TOOL (tr_tool));
+ gimp_transform_tool_recalc_matrix (tr_tool, tr_tool->widget);
}
}
@@ -300,19 +317,15 @@ shear_y_mag_changed (GtkAdjustment *adj,
{
gdouble value = gtk_adjustment_get_value (adj);
- if (value != tr_tool->trans_info[YSHEAR])
+ if (value != tr_tool->trans_info[SHEAR_Y])
{
- gimp_draw_tool_pause (GIMP_DRAW_TOOL (tr_tool));
-
- if (tr_tool->trans_info[HORZ_OR_VERT] == GIMP_ORIENTATION_UNKNOWN)
- tr_tool->trans_info[HORZ_OR_VERT] = GIMP_ORIENTATION_VERTICAL;
+ if (tr_tool->trans_info[ORIENTATION] == GIMP_ORIENTATION_UNKNOWN)
+ tr_tool->trans_info[ORIENTATION] = GIMP_ORIENTATION_VERTICAL;
- tr_tool->trans_info[YSHEAR] = value;
+ tr_tool->trans_info[SHEAR_Y] = value;
gimp_transform_tool_push_internal_undo (tr_tool);
- gimp_transform_tool_recalc_matrix (tr_tool);
-
- gimp_draw_tool_resume (GIMP_DRAW_TOOL (tr_tool));
+ gimp_transform_tool_recalc_matrix (tr_tool, tr_tool->widget);
}
}
diff --git a/app/tools/gimptransformoptions.c b/app/tools/gimptransformoptions.c
index bff81dd..7bc8237 100644
--- a/app/tools/gimptransformoptions.c
+++ b/app/tools/gimptransformoptions.c
@@ -617,8 +617,8 @@ gimp_transform_options_show_preview (GimpTransformOptions *options)
{
g_return_val_if_fail (GIMP_IS_TRANSFORM_OPTIONS (options), FALSE);
- return (options->show_preview &&
- options->type == GIMP_TRANSFORM_TYPE_LAYER);
+ return (options->show_preview &&
+ options->type == GIMP_TRANSFORM_TYPE_LAYER);
}
diff --git a/app/tools/gimptransformtool.c b/app/tools/gimptransformtool.c
index 22f2e07..e57bbd9 100644
--- a/app/tools/gimptransformtool.c
+++ b/app/tools/gimptransformtool.c
@@ -59,6 +59,7 @@
#include "display/gimpdisplayshell.h"
#include "display/gimpdisplayshell-transform.h"
#include "display/gimptoolgui.h"
+#include "display/gimptoolwidget.h"
#include "gimptoolcontrol.h"
#include "gimptransformoptions.h"
@@ -139,14 +140,18 @@ static GeglBuffer *
GimpColorProfile **buffer_profile,
gint *new_offset_x,
gint *new_offset_y);
-static void gimp_transform_tool_real_draw_gui (GimpTransformTool *tr_tool,
- gint handle_w,
- gint handle_h);
-static TransformAction
- gimp_transform_tool_real_pick_function (GimpTransformTool *tr_tool,
- const GimpCoords *coords,
- GdkModifierType state,
- GimpDisplay *display);
+
+static void gimp_transform_tool_widget_changed (GimpToolWidget *widget,
+ GimpTransformTool *tr_tool);
+static void gimp_transform_tool_widget_snap_offsets (GimpToolWidget *widget,
+ gint offset_x,
+ gint offset_y,
+ gint width,
+ gint height,
+ GimpTransformTool *tr_tool);
+static void gimp_transform_tool_widget_status (GimpToolWidget *widget,
+ const gchar *status,
+ GimpTransformTool *tr_tool);
static void gimp_transform_tool_halt (GimpTransformTool *tr_tool);
static void gimp_transform_tool_set_function (GimpTransformTool *tr_tool,
@@ -158,12 +163,7 @@ static void gimp_transform_tool_prepare (GimpTransformTool
GimpDisplay *display);
static void gimp_transform_tool_transform (GimpTransformTool *tr_tool,
GimpDisplay *display);
-static void gimp_transform_tool_transform_bounding_box (GimpTransformTool *tr_tool);
-static void gimp_transform_tool_handles_recalc (GimpTransformTool *tr_tool,
- GimpDisplay *display,
- gint *handle_w,
- gint *handle_h);
static void gimp_transform_tool_response (GimpToolGui *gui,
gint response_id,
GimpTransformTool *tr_tool);
@@ -222,8 +222,8 @@ gimp_transform_tool_class_init (GimpTransformToolClass *klass)
klass->recalc_matrix = NULL;
klass->get_undo_desc = NULL;
klass->transform = gimp_transform_tool_real_transform;
- klass->pick_function = gimp_transform_tool_real_pick_function;
- klass->draw_gui = gimp_transform_tool_real_draw_gui;
+ klass->pick_function = NULL;
+ klass->draw_gui = NULL;
klass->ok_button_label = _("_Transform");
}
@@ -316,7 +316,25 @@ gimp_transform_tool_initialize (GimpTool *tool,
gimp_transform_tool_prepare (tr_tool, display);
/* Recalculate the transform tool */
- gimp_transform_tool_recalc_matrix (tr_tool);
+ gimp_transform_tool_recalc_matrix (tr_tool, NULL);
+
+ /* Get the on-canvas gui */
+ if (GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->get_widget)
+ tr_tool->widget =
+ GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->get_widget (tr_tool);
+
+ if (tr_tool->widget)
+ {
+ g_signal_connect (tr_tool->widget, "changed",
+ G_CALLBACK (gimp_transform_tool_widget_changed),
+ tr_tool);
+ g_signal_connect (tr_tool->widget, "snap-offsets",
+ G_CALLBACK (gimp_transform_tool_widget_snap_offsets),
+ tr_tool);
+ g_signal_connect (tr_tool->widget, "status",
+ G_CALLBACK (gimp_transform_tool_widget_status),
+ tr_tool);
+ }
/* start drawing the bounding box and handles... */
gimp_draw_tool_start (GIMP_DRAW_TOOL (tool), display);
@@ -352,7 +370,7 @@ gimp_transform_tool_control (GimpTool *tool,
case GIMP_TOOL_ACTION_RESUME:
gimp_transform_tool_bounds (tr_tool, display);
- gimp_transform_tool_recalc_matrix (tr_tool);
+ gimp_transform_tool_recalc_matrix (tr_tool, tr_tool->widget);
break;
case GIMP_TOOL_ACTION_HALT:
@@ -377,6 +395,21 @@ gimp_transform_tool_button_press (GimpTool *tool,
{
GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool);
+ if (tr_tool->widget)
+ {
+ gimp_tool_widget_hover (tr_tool->widget, coords, state, TRUE);
+
+ if (gimp_tool_widget_button_press (tr_tool->widget, coords, time, state,
+ press_type))
+ {
+ tr_tool->grab_widget = tr_tool->widget;
+ }
+
+ gimp_tool_control_activate (tool->control);
+
+ return;
+ }
+
if (tr_tool->function == TRANSFORM_CREATING)
GIMP_TOOL_GET_CLASS (tool)->oper_update (tool, coords, state, TRUE, display);
@@ -447,9 +480,18 @@ gimp_transform_tool_button_release (GimpTool *tool,
gimp_tool_control_halt (tool->control);
- /* if we are creating, there is nothing to be done...exit */
- if (tr_tool->function == TRANSFORM_CREATING && tr_tool->use_grid)
- return;
+ if (tr_tool->grab_widget)
+ {
+ gimp_tool_widget_button_release (tr_tool->grab_widget,
+ coords, time, state, release_type);
+ tr_tool->grab_widget = NULL;
+ }
+ else
+ {
+ /* if we are creating, there is nothing to be done...exit */
+ if (tr_tool->function == TRANSFORM_CREATING && tr_tool->use_grid)
+ return;
+ }
if (release_type != GIMP_BUTTON_RELEASE_CANCEL)
{
@@ -465,7 +507,8 @@ gimp_transform_tool_button_release (GimpTool *tool,
}
else
{
- gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
+ if (! tr_tool->widget)
+ gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
/* Restore the last saved state */
memcpy (tr_tool->trans_info, tr_tool->prev_trans_info,
@@ -475,9 +518,10 @@ gimp_transform_tool_button_release (GimpTool *tool,
gimp_transform_tool_bounds (tr_tool, display);
/* recalculate the tool's transformation matrix */
- gimp_transform_tool_recalc_matrix (tr_tool);
+ gimp_transform_tool_recalc_matrix (tr_tool, tr_tool->widget);
- gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
+ if (! tr_tool->widget)
+ gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
}
}
@@ -490,6 +534,16 @@ gimp_transform_tool_motion (GimpTool *tool,
{
GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool);
+ if (tr_tool->widget)
+ {
+ if (tr_tool->grab_widget)
+ {
+ gimp_tool_widget_motion (tr_tool->grab_widget, coords, time, state);
+ }
+
+ return;
+ }
+
/* if we are creating, there is nothing to be done so exit. */
if (tr_tool->function == TRANSFORM_CREATING || ! tr_tool->use_grid)
return;
@@ -504,7 +558,7 @@ gimp_transform_tool_motion (GimpTool *tool,
{
GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->motion (tr_tool);
- gimp_transform_tool_recalc_matrix (tr_tool);
+ gimp_transform_tool_recalc_matrix (tr_tool, NULL);
}
tr_tool->lastx = tr_tool->curx;
@@ -590,99 +644,6 @@ gimp_transform_tool_modifier_key (GimpTool *tool,
}
}
-static TransformAction
-gimp_transform_tool_real_pick_function (GimpTransformTool *tr_tool,
- const GimpCoords *coords,
- GdkModifierType state,
- GimpDisplay *display)
-{
- GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tr_tool);
- TransformAction function = TRANSFORM_HANDLE_NONE;
-
- if (tr_tool->use_corner_handles)
- {
- gdouble closest_dist;
- gdouble dist;
-
- dist = gimp_draw_tool_calc_distance_square (draw_tool, display,
- coords->x, coords->y,
- tr_tool->tx1, tr_tool->ty1);
- closest_dist = dist;
- function = TRANSFORM_HANDLE_NW;
-
- dist = gimp_draw_tool_calc_distance_square (draw_tool, display,
- coords->x, coords->y,
- tr_tool->tx2, tr_tool->ty2);
- if (dist < closest_dist)
- {
- closest_dist = dist;
- function = TRANSFORM_HANDLE_NE;
- }
-
- dist = gimp_draw_tool_calc_distance_square (draw_tool, display,
- coords->x, coords->y,
- tr_tool->tx3, tr_tool->ty3);
- if (dist < closest_dist)
- {
- closest_dist = dist;
- function = TRANSFORM_HANDLE_SW;
- }
-
- dist = gimp_draw_tool_calc_distance_square (draw_tool, display,
- coords->x, coords->y,
- tr_tool->tx4, tr_tool->ty4);
- if (dist < closest_dist)
- {
- closest_dist = dist;
- function = TRANSFORM_HANDLE_SE;
- }
- }
-
- if (tr_tool->use_side_handles)
- {
- if (gimp_canvas_item_hit (tr_tool->handles[TRANSFORM_HANDLE_N],
- coords->x, coords->y))
- {
- function = TRANSFORM_HANDLE_N;
- }
- else if (gimp_canvas_item_hit (tr_tool->handles[TRANSFORM_HANDLE_E],
- coords->x, coords->y))
- {
- function = TRANSFORM_HANDLE_E;
- }
- else if (gimp_canvas_item_hit (tr_tool->handles[TRANSFORM_HANDLE_S],
- coords->x, coords->y))
- {
- function = TRANSFORM_HANDLE_S;
- }
- else if (gimp_canvas_item_hit (tr_tool->handles[TRANSFORM_HANDLE_W],
- coords->x, coords->y))
- {
- function = TRANSFORM_HANDLE_W;
- }
- }
-
- if (tr_tool->use_center_handle)
- {
- if (gimp_canvas_item_hit (tr_tool->handles[TRANSFORM_HANDLE_CENTER],
- coords->x, coords->y))
- {
- function = TRANSFORM_HANDLE_CENTER;
- }
- }
-
- if (tr_tool->use_pivot_handle)
- {
- if (gimp_canvas_item_hit (tr_tool->handles[TRANSFORM_HANDLE_PIVOT],
- coords->x, coords->y))
- {
- function = TRANSFORM_HANDLE_PIVOT;
- }
- }
-
- return function;
-}
-
static void
gimp_transform_tool_oper_update (GimpTool *tool,
const GimpCoords *coords,
@@ -694,16 +655,27 @@ gimp_transform_tool_oper_update (GimpTool *tool,
GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);
TransformAction function = TRANSFORM_HANDLE_NONE;
+ if (tr_tool->widget)
+ {
+ if (display == tool->display)
+ {
+ gimp_tool_widget_hover (tr_tool->widget, coords, state, proximity);
+ }
+
+ return;
+ }
+
if (display != tool->display || draw_tool->item == NULL)
{
gimp_transform_tool_set_function (tr_tool, function);
return;
}
- function = GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->pick_function (tr_tool,
- coords,
- state,
- display);
+ if (GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->pick_function)
+ function = GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->pick_function (tr_tool,
+ coords,
+ state,
+ display);
gimp_transform_tool_set_function (tr_tool, function);
}
@@ -714,71 +686,27 @@ gimp_transform_tool_cursor_update (GimpTool *tool,
GdkModifierType state,
GimpDisplay *display)
{
- GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool);
- GimpImage *image = gimp_display_get_image (display);
- GimpCursorType cursor = gimp_tool_control_get_cursor (tool->control);
- GimpCursorModifier modifier = GIMP_CURSOR_MODIFIER_NONE;
+ GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool);
+ GimpImage *image = gimp_display_get_image (display);
+ GimpCursorType cursor = GIMP_CURSOR_CROSSHAIR_SMALL;
+ GimpToolCursorType tool_cursor = GIMP_TOOL_CURSOR_NONE;
+ GimpCursorModifier modifier = GIMP_CURSOR_MODIFIER_NONE;
- if (tr_tool->use_corner_handles ||
- tr_tool->use_side_handles)
+ if (tr_tool->widget)
{
- switch (tr_tool->function)
+ if (display == tool->display)
{
- case TRANSFORM_HANDLE_NW:
- cursor = GIMP_CURSOR_CORNER_TOP_LEFT;
- break;
-
- case TRANSFORM_HANDLE_NE:
- cursor = GIMP_CURSOR_CORNER_TOP_RIGHT;
- break;
-
- case TRANSFORM_HANDLE_SW:
- cursor = GIMP_CURSOR_CORNER_BOTTOM_LEFT;
- break;
-
- case TRANSFORM_HANDLE_SE:
- cursor = GIMP_CURSOR_CORNER_BOTTOM_RIGHT;
- break;
-
- case TRANSFORM_HANDLE_N:
- cursor = GIMP_CURSOR_SIDE_TOP;
- break;
-
- case TRANSFORM_HANDLE_E:
- cursor = GIMP_CURSOR_SIDE_RIGHT;
- break;
-
- case TRANSFORM_HANDLE_S:
- cursor = GIMP_CURSOR_SIDE_BOTTOM;
- break;
-
- case TRANSFORM_HANDLE_W:
- cursor = GIMP_CURSOR_SIDE_LEFT;
- break;
-
- default:
- cursor = GIMP_CURSOR_CROSSHAIR_SMALL;
- break;
+ gimp_tool_widget_get_cursor (tr_tool->widget,
+ coords, state,
+ &cursor, &tool_cursor, &modifier);
}
}
- if (tr_tool->use_center_handle &&
- tr_tool->function == TRANSFORM_HANDLE_CENTER)
- {
- modifier = GIMP_CURSOR_MODIFIER_MOVE;
- }
-
- if (GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->cursor_update)
- {
- GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->cursor_update (tr_tool,
- &cursor,
- &modifier);
- }
-
if (! gimp_transform_tool_check_active_item (tr_tool, image, TRUE, NULL))
modifier = GIMP_CURSOR_MODIFIER_BAD;
gimp_tool_control_set_cursor (tool->control, cursor);
+ gimp_tool_control_set_tool_cursor (tool->control, tool_cursor);
gimp_tool_control_set_cursor_modifier (tool->control, modifier);
GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
@@ -831,7 +759,8 @@ gimp_transform_tool_undo (GimpTool *tool,
tr_tool->prev_trans_info = item->data;
- gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
+ if (! tr_tool->widget)
+ gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
/* Restore the previous transformation info */
memcpy (tr_tool->trans_info, tr_tool->prev_trans_info,
@@ -841,9 +770,10 @@ gimp_transform_tool_undo (GimpTool *tool,
gimp_transform_tool_bounds (tr_tool, tool->display);
/* recalculate the tool's transformation matrix */
- gimp_transform_tool_recalc_matrix (tr_tool);
+ gimp_transform_tool_recalc_matrix (tr_tool, tr_tool->widget);
- gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
+ if (! tr_tool->widget)
+ gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
return TRUE;
}
@@ -868,7 +798,8 @@ gimp_transform_tool_redo (GimpTool *tool,
tr_tool->redo_list = g_list_remove (tr_tool->redo_list,
tr_tool->prev_trans_info);
- gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
+ if (! tr_tool->widget)
+ gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
/* Restore the previous transformation info */
memcpy (tr_tool->trans_info, tr_tool->prev_trans_info,
@@ -878,9 +809,10 @@ gimp_transform_tool_redo (GimpTool *tool,
gimp_transform_tool_bounds (tr_tool, tool->display);
/* recalculate the tool's transformation matrix */
- gimp_transform_tool_recalc_matrix (tr_tool);
+ gimp_transform_tool_recalc_matrix (tr_tool, tr_tool->widget);
- gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
+ if (! tr_tool->widget)
+ gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
return TRUE;
}
@@ -890,7 +822,8 @@ gimp_transform_tool_options_notify (GimpTool *tool,
GimpToolOptions *options,
const GParamSpec *pspec)
{
- GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool);
+ GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool);
+ GimpTransformOptions *tr_options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tool);
GIMP_TOOL_CLASS (parent_class)->options_notify (tool, options, pspec);
@@ -900,166 +833,76 @@ gimp_transform_tool_options_notify (GimpTool *tool,
return;
}
- if (tr_tool->use_grid)
- {
- gimp_draw_tool_pause (GIMP_DRAW_TOOL (tr_tool));
+ if (! tr_tool->use_grid)
+ return;
+
+ if (! tr_tool->widget)
+ gimp_draw_tool_pause (GIMP_DRAW_TOOL (tr_tool));
- if (! strcmp (pspec->name, "direction"))
+ if (! strcmp (pspec->name, "direction"))
+ {
+ if (tr_tool->widget || tr_tool->function != TRANSFORM_CREATING)
{
- if (tr_tool->function != TRANSFORM_CREATING)
+ if (tool->display)
{
- if (tool->display)
- {
- /* reget the selection bounds */
- gimp_transform_tool_bounds (tr_tool, tool->display);
+ /* reget the selection bounds */
+ gimp_transform_tool_bounds (tr_tool, tool->display);
- /* recalculate the tool's transformation matrix */
- gimp_transform_tool_recalc_matrix (tr_tool);
- }
+ /* recalculate the tool's transformation matrix */
+ gimp_transform_tool_recalc_matrix (tr_tool, tr_tool->widget);
}
}
-
- if (tr_tool->function != TRANSFORM_CREATING)
- {
- gimp_transform_tool_transform_bounding_box (tr_tool);
- }
-
- gimp_draw_tool_resume (GIMP_DRAW_TOOL (tr_tool));
}
- if (g_str_has_prefix (pspec->name, "constrain-") ||
- g_str_has_prefix (pspec->name, "frompivot-") ||
- ! strcmp (pspec->name, "fixedpivot") ||
- ! strcmp (pspec->name, "cornersnap"))
+ if (! tr_tool->widget)
+ gimp_draw_tool_resume (GIMP_DRAW_TOOL (tr_tool));
+
+ if (! strcmp (pspec->name, "show-preview"))
{
- gimp_transform_tool_dialog_update (tr_tool);
+ if (tr_tool->widget && tr_tool->preview)
+ gimp_canvas_item_set_visible (tr_tool->preview,
+ tr_options->show_preview);
}
-}
-
-static void
-gimp_transform_tool_real_draw_gui (GimpTransformTool *tr_tool,
- gint handle_w,
- gint handle_h)
-{
- GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tr_tool);
-
- if (tr_tool->use_corner_handles)
+ else if (! strcmp (pspec->name, "preview-opacity"))
{
- tr_tool->handles[TRANSFORM_HANDLE_NW] =
- gimp_draw_tool_add_handle (draw_tool,
- GIMP_HANDLE_SQUARE,
- tr_tool->tx1, tr_tool->ty1,
- handle_w, handle_h,
- GIMP_HANDLE_ANCHOR_CENTER);
-
- tr_tool->handles[TRANSFORM_HANDLE_NE] =
- gimp_draw_tool_add_handle (draw_tool,
- GIMP_HANDLE_SQUARE,
- tr_tool->tx2, tr_tool->ty2,
- handle_w, handle_h,
- GIMP_HANDLE_ANCHOR_CENTER);
-
- tr_tool->handles[TRANSFORM_HANDLE_SW] =
- gimp_draw_tool_add_handle (draw_tool,
- GIMP_HANDLE_SQUARE,
- tr_tool->tx3, tr_tool->ty3,
- handle_w, handle_h,
- GIMP_HANDLE_ANCHOR_CENTER);
-
- tr_tool->handles[TRANSFORM_HANDLE_SE] =
- gimp_draw_tool_add_handle (draw_tool,
- GIMP_HANDLE_SQUARE,
- tr_tool->tx4, tr_tool->ty4,
- handle_w, handle_h,
- GIMP_HANDLE_ANCHOR_CENTER);
+ if (tr_tool->widget && tr_tool->preview)
+ g_object_set (tr_tool->preview,
+ "opacity", tr_options->preview_opacity,
+ NULL);
}
-
- if (tr_tool->use_side_handles)
+ else if (! strcmp (pspec->name, "grid-type"))
{
- tr_tool->handles[TRANSFORM_HANDLE_N] =
- gimp_draw_tool_add_handle (draw_tool,
- GIMP_HANDLE_SQUARE,
- (tr_tool->tx1 + tr_tool->tx2) / 2.0,
- (tr_tool->ty1 + tr_tool->ty2) / 2.0,
- handle_w, handle_h,
- GIMP_HANDLE_ANCHOR_CENTER);
-
- tr_tool->handles[TRANSFORM_HANDLE_E] =
- gimp_draw_tool_add_handle (draw_tool,
- GIMP_HANDLE_SQUARE,
- (tr_tool->tx2 + tr_tool->tx4) / 2.0,
- (tr_tool->ty2 + tr_tool->ty4) / 2.0,
- handle_w, handle_h,
- GIMP_HANDLE_ANCHOR_CENTER);
-
- tr_tool->handles[TRANSFORM_HANDLE_S] =
- gimp_draw_tool_add_handle (draw_tool,
- GIMP_HANDLE_SQUARE,
- (tr_tool->tx3 + tr_tool->tx4) / 2.0,
- (tr_tool->ty3 + tr_tool->ty4) / 2.0,
- handle_w, handle_h,
- GIMP_HANDLE_ANCHOR_CENTER);
-
- tr_tool->handles[TRANSFORM_HANDLE_W] =
- gimp_draw_tool_add_handle (draw_tool,
- GIMP_HANDLE_SQUARE,
- (tr_tool->tx3 + tr_tool->tx1) / 2.0,
- (tr_tool->ty3 + tr_tool->ty1) / 2.0,
- handle_w, handle_h,
- GIMP_HANDLE_ANCHOR_CENTER);
+ if (tr_tool->widget)
+ g_object_set (tr_tool->widget,
+ "guide-type", tr_options->grid_type,
+ NULL);
}
-
- if (tr_tool->use_pivot_handle)
+ else if (! strcmp (pspec->name, "grid-size"))
{
- GimpCanvasGroup *stroke_group;
- gint d = MIN (handle_w, handle_h);
-
- if (tr_tool->use_center_handle)
- d *= 2; /* so you can grab it from under the center handle */
-
- 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_CIRCLE,
- 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);
+ if (tr_tool->widget)
+ g_object_set (tr_tool->widget,
+ "n-guides", tr_options->grid_size,
+ NULL);
}
-
- if (tr_tool->use_center_handle)
+ else if (g_str_has_prefix (pspec->name, "constrain-") ||
+ g_str_has_prefix (pspec->name, "frompivot-") ||
+ ! strcmp (pspec->name, "fixedpivot") ||
+ ! strcmp (pspec->name, "cornersnap"))
{
- 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_CENTER] = GIMP_CANVAS_ITEM (stroke_group);
+ if (tr_tool->widget)
+ {
+ gboolean value;
- gimp_draw_tool_push_group (draw_tool, stroke_group);
+ g_object_get (options,
+ pspec->name, &value,
+ NULL);
- gimp_draw_tool_add_handle (draw_tool,
- GIMP_HANDLE_SQUARE,
- tr_tool->tcx, tr_tool->tcy,
- d, d,
- GIMP_HANDLE_ANCHOR_CENTER);
- gimp_draw_tool_add_handle (draw_tool,
- GIMP_HANDLE_CROSS,
- tr_tool->tcx, tr_tool->tcy,
- d, d,
- GIMP_HANDLE_ANCHOR_CENTER);
+ g_object_set (tr_tool->widget,
+ pspec->name, value,
+ NULL);
+ }
- gimp_draw_tool_pop_group (draw_tool);
+ gimp_transform_tool_dialog_update (tr_tool);
}
}
@@ -1070,29 +913,44 @@ gimp_transform_tool_draw (GimpDrawTool *draw_tool)
GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (draw_tool);
GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tool);
GimpImage *image = gimp_display_get_image (tool->display);
- gint handle_w;
- gint handle_h;
memset (tr_tool->handles, 0, sizeof (tr_tool->handles));
if (tr_tool->use_grid)
{
- if (gimp_transform_options_show_preview (options))
+ gboolean show_preview = gimp_transform_options_show_preview (options);
+
+ if (tr_tool->widget || show_preview)
{
GimpMatrix3 matrix = tr_tool->transform;
if (options->direction == GIMP_TRANSFORM_BACKWARD)
gimp_matrix3_invert (&matrix);
- gimp_draw_tool_add_transform_preview (draw_tool,
- tool->drawable,
- &matrix,
- tr_tool->x1,
- tr_tool->y1,
- tr_tool->x2,
- tr_tool->y2,
- tr_tool->does_perspective,
- options->preview_opacity);
+ tr_tool->preview =
+ gimp_draw_tool_add_transform_preview (draw_tool,
+ tool->drawable,
+ &matrix,
+ tr_tool->x1,
+ tr_tool->y1,
+ tr_tool->x2,
+ tr_tool->y2,
+ tr_tool->does_perspective,
+ options->preview_opacity);
+ g_object_add_weak_pointer (G_OBJECT (tr_tool->preview),
+ (gpointer) &tr_tool->preview);
+
+ if (tr_tool->widget)
+ gimp_canvas_item_set_visible (tr_tool->preview, show_preview);
+ }
+
+ if (tr_tool->widget)
+ {
+ GimpCanvasItem *item = gimp_tool_widget_get_item (tr_tool->widget);
+
+ gimp_draw_tool_add_item (draw_tool, item);
+
+ return;
}
gimp_draw_tool_add_transform_guides (draw_tool,
@@ -1105,10 +963,8 @@ gimp_transform_tool_draw (GimpDrawTool *draw_tool)
tr_tool->y2);
}
- gimp_transform_tool_handles_recalc (tr_tool, tool->display,
- &handle_w, &handle_h);
-
- GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->draw_gui (tr_tool, handle_w, handle_h);
+ if (GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->draw_gui)
+ GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->draw_gui (tr_tool);
if (tr_tool->handles[tr_tool->function])
{
@@ -1460,6 +1316,59 @@ gimp_transform_tool_transform (GimpTransformTool *tr_tool,
}
static void
+gimp_transform_tool_widget_changed (GimpToolWidget *widget,
+ GimpTransformTool *tr_tool)
+{
+ GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
+
+ if (tr_tool->preview)
+ {
+ GimpMatrix3 matrix = tr_tool->transform;
+
+ if (options->direction == GIMP_TRANSFORM_BACKWARD)
+ gimp_matrix3_invert (&matrix);
+
+ gimp_canvas_item_begin_change (tr_tool->preview);
+ g_object_set (tr_tool->preview,
+ "transform", &matrix,
+ NULL);
+ gimp_canvas_item_end_change (tr_tool->preview);
+ }
+}
+
+static void
+gimp_transform_tool_widget_snap_offsets (GimpToolWidget *widget,
+ gint offset_x,
+ gint offset_y,
+ gint width,
+ gint height,
+ GimpTransformTool *tr_tool)
+{
+ GimpTool *tool = GIMP_TOOL (tr_tool);
+
+ gimp_tool_control_set_snap_offsets (tool->control,
+ offset_x, offset_y,
+ width, height);
+}
+
+static void
+gimp_transform_tool_widget_status (GimpToolWidget *widget,
+ const gchar *status,
+ GimpTransformTool *tr_tool)
+{
+ GimpTool *tool = GIMP_TOOL (tr_tool);
+
+ if (status)
+ {
+ gimp_tool_replace_status (tool, tool->display, "%s", status);
+ }
+ else
+ {
+ gimp_tool_pop_status (tool, tool->display);
+ }
+}
+
+static void
gimp_transform_tool_halt (GimpTransformTool *tr_tool)
{
GimpTool *tool = GIMP_TOOL (tr_tool);
@@ -1467,6 +1376,8 @@ gimp_transform_tool_halt (GimpTransformTool *tr_tool)
if (gimp_draw_tool_is_active (GIMP_DRAW_TOOL (tr_tool)))
gimp_draw_tool_stop (GIMP_DRAW_TOOL (tr_tool));
+ g_clear_object (&tr_tool->widget);
+
tr_tool->function = TRANSFORM_CREATING;
if (tr_tool->gui)
@@ -1515,41 +1426,6 @@ gimp_transform_tool_set_function (GimpTransformTool *tr_tool,
}
}
-static void
-gimp_transform_tool_transform_bounding_box (GimpTransformTool *tr_tool)
-{
- g_return_if_fail (GIMP_IS_TRANSFORM_TOOL (tr_tool));
-
- gimp_matrix3_transform_point (&tr_tool->transform,
- tr_tool->x1, tr_tool->y1,
- &tr_tool->tx1, &tr_tool->ty1);
- gimp_matrix3_transform_point (&tr_tool->transform,
- tr_tool->x2, tr_tool->y1,
- &tr_tool->tx2, &tr_tool->ty2);
- gimp_matrix3_transform_point (&tr_tool->transform,
- tr_tool->x1, tr_tool->y2,
- &tr_tool->tx3, &tr_tool->ty3);
- gimp_matrix3_transform_point (&tr_tool->transform,
- tr_tool->x2, tr_tool->y2,
- &tr_tool->tx4, &tr_tool->ty4);
- gimp_matrix3_transform_point (&tr_tool->transform,
- tr_tool->px, tr_tool->py,
- &tr_tool->tpx, &tr_tool->tpy);
-
- /* don't transform these */
- 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 gboolean
gimp_transform_tool_bounds (GimpTransformTool *tr_tool,
GimpDisplay *display)
@@ -1630,50 +1506,10 @@ gimp_transform_tool_bounds (GimpTransformTool *tr_tool,
break;
}
- tr_tool->aspect = ((gdouble) (tr_tool->x2 - tr_tool->x1) /
- (gdouble) (tr_tool->y2 - tr_tool->y1));
-
return non_empty;
}
static void
-gimp_transform_tool_handles_recalc (GimpTransformTool *tr_tool,
- GimpDisplay *display,
- gint *handle_w,
- gint *handle_h)
-{
- gint dx1, dy1;
- gint dx2, dy2;
- gint dx3, dy3;
- gint dx4, dy4;
- gint x1, y1;
- gint x2, y2;
-
- gimp_display_shell_transform_xy (gimp_display_get_shell (display),
- tr_tool->tx1, tr_tool->ty1,
- &dx1, &dy1);
- gimp_display_shell_transform_xy (gimp_display_get_shell (display),
- tr_tool->tx2, tr_tool->ty2,
- &dx2, &dy2);
- gimp_display_shell_transform_xy (gimp_display_get_shell (display),
- tr_tool->tx3, tr_tool->ty3,
- &dx3, &dy3);
- gimp_display_shell_transform_xy (gimp_display_get_shell (display),
- tr_tool->tx4, tr_tool->ty4,
- &dx4, &dy4);
-
- x1 = MIN4 (dx1, dx2, dx3, dx4);
- y1 = MIN4 (dy1, dy2, dy3, dy4);
- x2 = MAX4 (dx1, dx2, dx3, dx4);
- y2 = MAX4 (dy1, dy2, dy3, dy4);
-
- *handle_w = CLAMP ((x2 - x1) / 3,
- MIN_HANDLE_SIZE, GIMP_TOOL_HANDLE_SIZE_LARGE);
- *handle_h = CLAMP ((y2 - y1) / 3,
- MIN_HANDLE_SIZE, GIMP_TOOL_HANDLE_SIZE_LARGE);
-}
-
-static void
gimp_transform_tool_dialog (GimpTransformTool *tr_tool)
{
GimpTool *tool = GIMP_TOOL (tr_tool);
@@ -1736,14 +1572,14 @@ gimp_transform_tool_prepare (GimpTransformTool *tr_tool,
}
void
-gimp_transform_tool_recalc_matrix (GimpTransformTool *tr_tool)
+gimp_transform_tool_recalc_matrix (GimpTransformTool *tr_tool,
+ GimpToolWidget *widget)
{
g_return_if_fail (GIMP_IS_TRANSFORM_TOOL (tr_tool));
+ g_return_if_fail (widget == NULL || GIMP_IS_TOOL_WIDGET (widget));
if (GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->recalc_matrix)
- GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->recalc_matrix (tr_tool);
-
- gimp_transform_tool_transform_bounding_box (tr_tool);
+ GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->recalc_matrix (tr_tool, widget);
gimp_transform_tool_dialog_update (tr_tool);
@@ -1776,7 +1612,8 @@ gimp_transform_tool_response (GimpToolGui *gui,
gimp_transform_tool_update_sensitivity (tr_tool);
- gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
+ if (! tr_tool->widget)
+ gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
/* Restore the previous transformation info */
memcpy (tr_tool->trans_info, tr_tool->prev_trans_info,
@@ -1786,9 +1623,10 @@ gimp_transform_tool_response (GimpToolGui *gui,
gimp_transform_tool_bounds (tr_tool, display);
/* recalculate the tool's transformation matrix */
- gimp_transform_tool_recalc_matrix (tr_tool);
+ gimp_transform_tool_recalc_matrix (tr_tool, tr_tool->widget);
- gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
+ if (! tr_tool->widget)
+ gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
/* update the undo actions / menu items */
gimp_image_flush (gimp_display_get_image (display));
diff --git a/app/tools/gimptransformtool.h b/app/tools/gimptransformtool.h
index df4e0e2..4e893da 100644
--- a/app/tools/gimptransformtool.h
+++ b/app/tools/gimptransformtool.h
@@ -89,16 +89,6 @@ struct _GimpTransformTool
gint x1, y1; /* upper left hand coordinate */
gint x2, y2; /* lower right hand coords */
- gdouble cx, cy; /* center point (for moving) */
- gdouble px, py; /* pivot point (for rotation/scaling) */
- gdouble aspect; /* original aspect ratio */
-
- gdouble tx1, ty1; /* transformed handle coords */
- gdouble tx2, ty2;
- gdouble tx3, ty3;
- gdouble tx4, ty4;
- gdouble tcx, tcy;
- gdouble tpx, tpy;
GimpMatrix3 transform; /* transformation matrix */
TransInfo trans_info; /* transformation info */
@@ -116,14 +106,14 @@ struct _GimpTransformTool
TransformAction function; /* current tool activity */
gboolean use_grid; /* does the tool use the grid */
- gboolean use_corner_handles; /* uses the corner handles */
- gboolean use_side_handles; /* use handles at midpoints of edges */
- gboolean use_center_handle; /* uses the center handle */
- gboolean use_pivot_handle; /* use the pivot point handle */
-
gboolean does_perspective; /* does the tool do non-affine
- transformations */
+ * transformations
+ */
+
+ GimpToolWidget *widget;
+ GimpToolWidget *grab_widget;
+ GimpCanvasItem *preview;
GimpCanvasItem *handles[TRANSFORM_HANDLE_NUM];
const gchar *progress_text;
@@ -136,30 +126,32 @@ struct _GimpTransformToolClass
GimpDrawToolClass parent_class;
/* virtual functions */
- void (* dialog) (GimpTransformTool *tool);
- void (* dialog_update) (GimpTransformTool *tool);
- void (* prepare) (GimpTransformTool *tool);
- void (* motion) (GimpTransformTool *tool);
- void (* recalc_matrix) (GimpTransformTool *tool);
- gchar * (* get_undo_desc) (GimpTransformTool *tool);
- TransformAction (* pick_function) (GimpTransformTool *tool,
- const GimpCoords *coords,
- GdkModifierType state,
- GimpDisplay *display);
- void (* cursor_update) (GimpTransformTool *tr_tool,
- GimpCursorType *cursor,
- GimpCursorModifier *modifier);
- void (* draw_gui) (GimpTransformTool *tool,
- gint handle_w,
- gint handle_h);
- GeglBuffer * (* transform) (GimpTransformTool *tool,
- GimpItem *item,
- GeglBuffer *orig_buffer,
- gint orig_offset_x,
- gint orig_offset_y,
- GimpColorProfile **buffer_profile,
- gint *new_offset_x,
- gint *new_offset_y);
+ void (* dialog) (GimpTransformTool *tool);
+ void (* dialog_update) (GimpTransformTool *tool);
+ void (* prepare) (GimpTransformTool *tool);
+
+ GimpToolWidget * (* get_widget) (GimpTransformTool *tool);
+
+ void (* motion) (GimpTransformTool *tool);
+ void (* recalc_matrix) (GimpTransformTool *tool,
+ GimpToolWidget *widget);
+ gchar * (* get_undo_desc) (GimpTransformTool *tool);
+ TransformAction (* pick_function) (GimpTransformTool *tool,
+ const GimpCoords *coords,
+ GdkModifierType state,
+ GimpDisplay *display);
+ void (* cursor_update) (GimpTransformTool *tr_tool,
+ GimpCursorType *cursor,
+ GimpCursorModifier *modifier);
+ void (* draw_gui) (GimpTransformTool *tool);
+ GeglBuffer * (* transform) (GimpTransformTool *tool,
+ GimpItem *item,
+ GeglBuffer *orig_buffer,
+ gint orig_offset_x,
+ gint orig_offset_y,
+ GimpColorProfile **buffer_profile,
+ gint *new_offset_x,
+ gint *new_offset_y);
const gchar *ok_button_label;
};
@@ -167,7 +159,8 @@ struct _GimpTransformToolClass
GType gimp_transform_tool_get_type (void) G_GNUC_CONST;
-void gimp_transform_tool_recalc_matrix (GimpTransformTool *tr_tool);
+void gimp_transform_tool_recalc_matrix (GimpTransformTool *tr_tool,
+ GimpToolWidget *widget);
void gimp_transform_tool_push_internal_undo (GimpTransformTool *tr_tool);
diff --git a/app/tools/gimpunifiedtransformtool.c b/app/tools/gimpunifiedtransformtool.c
index 7be8a40..ee87287 100644
--- a/app/tools/gimpunifiedtransformtool.c
+++ b/app/tools/gimpunifiedtransformtool.c
@@ -17,8 +17,6 @@
#include "config.h"
-#include <string.h>
-
#include <gegl.h>
#include <gtk/gtk.h>
@@ -28,22 +26,12 @@
#include "tools-types.h"
#include "core/gimp-transform-utils.h"
-#include "core/gimp-utils.h"
-#include "core/gimpchannel.h"
-#include "core/gimpdrawable-transform.h"
-#include "core/gimpimage.h"
-
-#include "vectors/gimpstroke.h"
-#include "vectors/gimpvectors.h"
#include "widgets/gimphelp-ids.h"
-#include "display/gimpcanvasgroup.h"
-#include "display/gimpcanvashandle.h"
#include "display/gimpdisplay.h"
-#include "display/gimpdisplayshell.h"
-#include "display/gimpdisplayshell-transform.h"
#include "display/gimptoolgui.h"
+#include "display/gimptooltransformgrid.h"
#include "gimptoolcontrol.h"
#include "gimptransformoptions.h"
@@ -70,22 +58,16 @@ enum
/* local function prototypes */
-static void gimp_unified_transform_tool_dialog (GimpTransformTool *tr_tool);
-static void gimp_unified_transform_tool_dialog_update (GimpTransformTool *tr_tool);
-static void gimp_unified_transform_tool_prepare (GimpTransformTool *tr_tool);
-static void gimp_unified_transform_tool_motion (GimpTransformTool *tr_tool);
-static void gimp_unified_transform_tool_recalc_matrix (GimpTransformTool *tr_tool);
-static gchar * gimp_unified_transform_tool_get_undo_desc (GimpTransformTool *tr_tool);
-static TransformAction gimp_unified_transform_tool_pick_function (GimpTransformTool *tr_tool,
- const GimpCoords *coords,
- GdkModifierType state,
- GimpDisplay *display);
-static void gimp_unified_transform_tool_cursor_update (GimpTransformTool *tr_tool,
- GimpCursorType *cursor,
- GimpCursorModifier *modifier);
-static void gimp_unified_transform_tool_draw_gui (GimpTransformTool *tr_tool,
- gint handle_w,
- gint handle_h);
+static void gimp_unified_transform_tool_dialog (GimpTransformTool *tr_tool);
+static void gimp_unified_transform_tool_dialog_update (GimpTransformTool *tr_tool);
+static void gimp_unified_transform_tool_prepare (GimpTransformTool *tr_tool);
+static GimpToolWidget * gimp_unified_transform_tool_get_widget (GimpTransformTool *tr_tool);
+static void gimp_unified_transform_tool_recalc_matrix (GimpTransformTool *tr_tool,
+ GimpToolWidget *widget);
+static gchar * gimp_unified_transform_tool_get_undo_desc (GimpTransformTool *tr_tool);
+
+static void gimp_unified_transform_tool_widget_changed (GimpToolWidget *widget,
+ GimpTransformTool *tr_tool);
G_DEFINE_TYPE (GimpUnifiedTransformTool, gimp_unified_transform_tool,
@@ -118,12 +100,9 @@ gimp_unified_transform_tool_class_init (GimpUnifiedTransformToolClass *klass)
trans_class->dialog = gimp_unified_transform_tool_dialog;
trans_class->dialog_update = gimp_unified_transform_tool_dialog_update;
trans_class->prepare = gimp_unified_transform_tool_prepare;
- trans_class->motion = gimp_unified_transform_tool_motion;
+ trans_class->get_widget = gimp_unified_transform_tool_get_widget;
trans_class->recalc_matrix = gimp_unified_transform_tool_recalc_matrix;
trans_class->get_undo_desc = gimp_unified_transform_tool_get_undo_desc;
- trans_class->pick_function = gimp_unified_transform_tool_pick_function;
- trans_class->cursor_update = gimp_unified_transform_tool_cursor_update;
- trans_class->draw_gui = gimp_unified_transform_tool_draw_gui;
}
static void
@@ -131,630 +110,9 @@ gimp_unified_transform_tool_init (GimpUnifiedTransformTool *unified_tool)
{
GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (unified_tool);
- tr_tool->progress_text = _("Unified transform");
-
- tr_tool->use_grid = TRUE;
- tr_tool->use_corner_handles = TRUE;
-
- tr_tool->does_perspective = TRUE;
-}
-
-static gboolean
-transform_is_convex (GimpVector2 *pos)
-{
- return gimp_transform_polygon_is_convex (pos[0].x, pos[0].y,
- pos[1].x, pos[1].y,
- pos[2].x, pos[2].y,
- pos[3].x, pos[3].y);
-}
-
-static inline gboolean
-vectorisnull (GimpVector2 v)
-{
- return ((v.x == 0.0) && (v.y == 0.0));
-}
-
-static inline gdouble
-dotprod (GimpVector2 a,
- GimpVector2 b)
-{
- return a.x * b.x + a.y * b.y;
-}
-
-static inline gdouble
-norm (GimpVector2 a)
-{
- return sqrt (dotprod (a, a));
-}
-
-static inline GimpVector2
-vectorsubtract (GimpVector2 a,
- GimpVector2 b)
-{
- GimpVector2 c;
-
- c.x = a.x - b.x;
- c.y = a.y - b.y;
-
- return c;
-}
-
-static inline GimpVector2
-vectoradd (GimpVector2 a,
- GimpVector2 b)
-{
- GimpVector2 c;
-
- c.x = a.x + b.x;
- c.y = a.y + b.y;
-
- return c;
-}
-
-static inline GimpVector2
-scalemult (GimpVector2 a,
- gdouble b)
-{
- GimpVector2 c;
-
- c.x = a.x * b;
- c.y = a.y * b;
-
- return c;
-}
-
-static inline GimpVector2
-vectorproject (GimpVector2 a,
- GimpVector2 b)
-{
- return scalemult (b, dotprod (a, b) / dotprod (b, b));
-}
-
-/* finds the clockwise angle between the vectors given, 0-2π */
-static inline gdouble
-calcangle (GimpVector2 a,
- GimpVector2 b)
-{
- gdouble angle, angle2;
- gdouble length;
-
- if (vectorisnull (a) || vectorisnull (b))
- return 0.0;
-
- length = norm (a) * norm (b);
-
- angle = acos (dotprod (a, b)/length);
- angle2 = b.y;
- b.y = -b.x;
- b.x = angle2;
- angle2 = acos (dotprod (a, b)/length);
-
- return ((angle2 > G_PI/2.) ? angle : 2*G_PI-angle);
-}
-
-static inline GimpVector2
-rotate2d (GimpVector2 p,
- gdouble angle)
-{
- GimpVector2 ret;
-
- ret.x = cos (angle) * p.x-sin (angle) * p.y;
- ret.y = sin (angle) * p.x+cos (angle) * p.y;
-
- return ret;
-}
-
-static inline GimpVector2
-lineintersect (GimpVector2 p1, GimpVector2 p2,
- GimpVector2 q1, GimpVector2 q2)
-{
- gdouble denom, u;
- GimpVector2 p;
-
- denom = (q2.y - q1.y) * (p2.x - p1.x) - (q2.x - q1.x) * (p2.y - p1.y);
- if (denom == 0.0)
- {
- p.x = (p1.x + p2.x + q1.x + q2.x) / 4;
- p.y = (p1.y + p2.y + q1.y + q2.y) / 4;
- }
- else
- {
- u = (q2.x - q1.x) * (p1.y - q1.y) - (q2.y - q1.y) * (p1.x - q1.x);
- u /= denom;
-
- p.x = p1.x + u * (p2.x - p1.x);
- p.y = p1.y + u * (p2.y - p1.y);
- }
-
- return p;
-}
-
-static inline GimpVector2
-get_pivot_delta (GimpTransformTool *tr_tool,
- GimpVector2 *oldpos,
- GimpVector2 *newpos,
- GimpVector2 pivot)
-{
- GimpMatrix3 transform_before, transform_after;
- GimpVector2 delta;
-
- gimp_matrix3_identity (&transform_before);
- gimp_matrix3_identity (&transform_after);
-
- gimp_transform_matrix_perspective (&transform_before,
- tr_tool->x1,
- tr_tool->y1,
- tr_tool->x2 - tr_tool->x1,
- tr_tool->y2 - tr_tool->y1,
- oldpos[0].x, oldpos[0].y,
- oldpos[1].x, oldpos[1].y,
- oldpos[2].x, oldpos[2].y,
- oldpos[3].x, oldpos[3].y);
- gimp_transform_matrix_perspective (&transform_after,
- tr_tool->x1,
- tr_tool->y1,
- tr_tool->x2 - tr_tool->x1,
- tr_tool->y2 - tr_tool->y1,
- newpos[0].x, newpos[0].y,
- newpos[1].x, newpos[1].y,
- newpos[2].x, newpos[2].y,
- newpos[3].x, newpos[3].y);
- gimp_matrix3_invert (&transform_before);
- gimp_matrix3_mult (&transform_after, &transform_before);
- gimp_matrix3_transform_point (&transform_before,
- pivot.x, pivot.y, &delta.x, &delta.y);
-
- delta = vectorsubtract (delta, pivot);
-
- return delta;
-}
-
-static gboolean
-point_is_inside_polygon (gint n,
- gdouble *x,
- gdouble *y,
- gdouble px,
- gdouble py)
-{
- gint i, j;
- gboolean odd = FALSE;
-
- for (i = 0, j = n - 1; i < n; j = i++)
- {
- if ((y[i] < py && y[j] >= py) ||
- (y[j] < py && y[i] >= py))
- {
- if (x[i] + (py - y[i]) / (y[j] - y[i]) * (x[j] - x[i]) < px)
- odd = !odd;
- }
- }
-
- return odd;
-}
-
-static gboolean
-point_is_inside_polygon_pos (GimpVector2 *pos,
- GimpVector2 point)
-{
- return point_is_inside_polygon (4,
- (gdouble[4]){ pos[0].x, pos[1].x,
- pos[3].x, pos[2].x },
- (gdouble[4]){ pos[0].y, pos[1].y,
- pos[3].y, pos[2].y },
- point.x, point.y);
-}
-
-static const gchar *
-get_friendly_operation_name (TransformAction op)
-{
- switch (op)
- {
- case TRANSFORM_HANDLE_NONE:
- return "";
- case TRANSFORM_HANDLE_NW_P:
- case TRANSFORM_HANDLE_NE_P:
- case TRANSFORM_HANDLE_SW_P:
- case TRANSFORM_HANDLE_SE_P:
- return "Change perspective";
- case TRANSFORM_HANDLE_NW:
- case TRANSFORM_HANDLE_NE:
- case TRANSFORM_HANDLE_SW:
- case TRANSFORM_HANDLE_SE:
- return "Scale";
- case TRANSFORM_HANDLE_N:
- case TRANSFORM_HANDLE_S:
- case TRANSFORM_HANDLE_E:
- case TRANSFORM_HANDLE_W:
- return "Scale";
- case TRANSFORM_HANDLE_CENTER:
- return "Move";
- case TRANSFORM_HANDLE_PIVOT:
- return "Move pivot";
- case TRANSFORM_HANDLE_N_S:
- case TRANSFORM_HANDLE_S_S:
- case TRANSFORM_HANDLE_E_S:
- case TRANSFORM_HANDLE_W_S:
- return "Shear";
- case TRANSFORM_HANDLE_ROTATION:
- return "Rotate";
- default:
- g_assert_not_reached ();
- }
-}
-
-static TransformAction
-gimp_unified_transform_tool_pick_function (GimpTransformTool *tr_tool,
- const GimpCoords *coords,
- GdkModifierType state,
- GimpDisplay *display)
-{
- GimpTool *tool = GIMP_TOOL (tr_tool);
- TransformAction ret = TRANSFORM_HANDLE_NONE;
- TransformAction i;
-
- for (i = TRANSFORM_HANDLE_NONE + 1; i < TRANSFORM_HANDLE_NUM; i++)
- {
- if (tr_tool->handles[i] &&
- gimp_canvas_item_hit (tr_tool->handles[i], coords->x, coords->y))
- {
- ret = i;
- break;
- }
- }
-
- if (ret == TRANSFORM_HANDLE_NONE)
- {
- /* points passed in clockwise order */
- if (point_is_inside_polygon (4,
- (gdouble[4]){ tr_tool->tx1, tr_tool->tx2,
- tr_tool->tx4, tr_tool->tx3 },
- (gdouble[4]){ tr_tool->ty1, tr_tool->ty2,
- tr_tool->ty4, tr_tool->ty3 },
- coords->x, coords->y))
- ret = TRANSFORM_HANDLE_CENTER;
- else
- ret = TRANSFORM_HANDLE_ROTATION;
- }
-
- gimp_tool_pop_status (tool, tool->display);
-
- if (ret != TRANSFORM_HANDLE_NONE)
- gimp_tool_push_status (tool, tool->display, "%s",
- get_friendly_operation_name (ret));
-
- return ret;
-}
-
-static void
-get_handle_geometry (GimpTransformTool *tr_tool,
- GimpVector2 *position,
- gdouble *angle)
-{
- GimpVector2 o[] = { { .x = tr_tool->tx1, .y = tr_tool->ty1 },
- { .x = tr_tool->tx2, .y = tr_tool->ty2 },
- { .x = tr_tool->tx3, .y = tr_tool->ty3 },
- { .x = tr_tool->tx4, .y = tr_tool->ty4 } };
- GimpVector2 right = { .x = 1.0, .y = 0.0 };
- GimpVector2 up = { .x = 0.0, .y = 1.0 };
-
- if (position)
- {
- position[0] = o[0];
- position[1] = o[1];
- position[2] = o[2];
- position[3] = o[3];
- }
-
- angle[0] = calcangle (vectorsubtract (o[1], o[0]), right);
- angle[1] = calcangle (vectorsubtract (o[3], o[2]), right);
- angle[2] = calcangle (vectorsubtract (o[3], o[1]), up);
- angle[3] = calcangle (vectorsubtract (o[2], o[0]), up);
-
- angle[4] = (angle[0] + angle[3]) / 2.0;
- angle[5] = (angle[0] + angle[2]) / 2.0;
- angle[6] = (angle[1] + angle[3]) / 2.0;
- angle[7] = (angle[1] + angle[2]) / 2.0;
-}
-
-static void
-gimp_unified_transform_tool_cursor_update (GimpTransformTool *tr_tool,
- GimpCursorType *cursor,
- GimpCursorModifier *modifier)
-{
- GimpToolCursorType tool_cursor = GIMP_TOOL_CURSOR_NONE;
- gdouble angle[8];
- gint i;
- GimpCursorType map[8];
- GimpVector2 pos[4], this, that;
- gboolean flip = FALSE;
- gboolean side = FALSE;
- gboolean set_cursor = TRUE;
-
- map[0] = GIMP_CURSOR_CORNER_TOP_LEFT;
- map[1] = GIMP_CURSOR_CORNER_TOP;
- map[2] = GIMP_CURSOR_CORNER_TOP_RIGHT;
- map[3] = GIMP_CURSOR_CORNER_RIGHT;
- map[4] = GIMP_CURSOR_CORNER_BOTTOM_RIGHT;
- map[5] = GIMP_CURSOR_CORNER_BOTTOM;
- map[6] = GIMP_CURSOR_CORNER_BOTTOM_LEFT;
- map[7] = GIMP_CURSOR_CORNER_LEFT;
-
- get_handle_geometry (tr_tool, pos, angle);
-
- for (i = 0; i < 8; i++)
- angle[i] = round (angle[i] * 180.0 / G_PI / 45.0);
-
- switch (tr_tool->function)
- {
- case TRANSFORM_HANDLE_NW_P:
- case TRANSFORM_HANDLE_NW:
- i = (gint) angle[4] + 0;
- this = pos[0];
- that = pos[3];
- break;
-
- case TRANSFORM_HANDLE_NE_P:
- case TRANSFORM_HANDLE_NE:
- i = (gint) angle[5] + 2;
- this = pos[1];
- that = pos[2];
- break;
-
- case TRANSFORM_HANDLE_SW_P:
- case TRANSFORM_HANDLE_SW:
- i = (gint) angle[6] + 6;
- this = pos[2];
- that = pos[1];
- break;
-
- case TRANSFORM_HANDLE_SE_P:
- case TRANSFORM_HANDLE_SE:
- i = (gint) angle[7] + 4;
- this = pos[3];
- that = pos[0];
- break;
-
- case TRANSFORM_HANDLE_N:
- case TRANSFORM_HANDLE_N_S:
- i = (gint) angle[0] + 1;
- this = vectoradd (pos[0], pos[1]);
- that = vectoradd (pos[2], pos[3]);
- side = TRUE;
- break;
-
- case TRANSFORM_HANDLE_S:
- case TRANSFORM_HANDLE_S_S:
- i = (gint) angle[1] + 5;
- this = vectoradd (pos[2], pos[3]);
- that = vectoradd (pos[0], pos[1]);
- side = TRUE;
- break;
-
- case TRANSFORM_HANDLE_E:
- case TRANSFORM_HANDLE_E_S:
- i = (gint) angle[2] + 3;
- this = vectoradd (pos[1], pos[3]);
- that = vectoradd (pos[0], pos[2]);
- side = TRUE;
- break;
-
- case TRANSFORM_HANDLE_W:
- case TRANSFORM_HANDLE_W_S:
- i = (gint) angle[3] + 7;
- this = vectoradd (pos[0], pos[2]);
- that = vectoradd (pos[1], pos[3]);
- side = TRUE;
- break;
-
- default:
- set_cursor = FALSE;
- break;
- }
-
- if (set_cursor)
- {
- i %= 8;
-
- switch (map[i])
- {
- case GIMP_CURSOR_CORNER_TOP_LEFT:
- if (this.x + this.y > that.x + that.y)
- flip = TRUE;
- break;
- case GIMP_CURSOR_CORNER_TOP:
- if (this.y > that.y)
- flip = TRUE;
- break;
- case GIMP_CURSOR_CORNER_TOP_RIGHT:
- if (this.x - this.y < that.x - that.y)
- flip = TRUE;
- break;
- case GIMP_CURSOR_CORNER_RIGHT:
- if (this.x < that.x)
- flip = TRUE;
- break;
- case GIMP_CURSOR_CORNER_BOTTOM_RIGHT:
- if (this.x + this.y < that.x + that.y)
- flip = TRUE;
- break;
- case GIMP_CURSOR_CORNER_BOTTOM:
- if (this.y < that.y)
- flip = TRUE;
- break;
- case GIMP_CURSOR_CORNER_BOTTOM_LEFT:
- if (this.x - this.y > that.x - that.y)
- flip = TRUE;
- break;
- case GIMP_CURSOR_CORNER_LEFT:
- if (this.x > that.x)
- flip = TRUE;
- break;
- default:
- g_assert_not_reached ();
- }
-
- if (flip)
- *cursor = map[(i + 4) % 8];
- else
- *cursor = map[i];
-
- if (side)
- *cursor += 8;
- }
-
- /* parent class handles *cursor and *modifier for most handles */
- switch (tr_tool->function)
- {
- case TRANSFORM_HANDLE_NONE:
- case TRANSFORM_CREATING:
- tool_cursor = GIMP_TOOL_CURSOR_NONE;
- break;
-
- case TRANSFORM_HANDLE_NW_P:
- case TRANSFORM_HANDLE_NE_P:
- case TRANSFORM_HANDLE_SW_P:
- case TRANSFORM_HANDLE_SE_P:
- tool_cursor = GIMP_TOOL_CURSOR_PERSPECTIVE;
- break;
-
- case TRANSFORM_HANDLE_NW:
- case TRANSFORM_HANDLE_NE:
- case TRANSFORM_HANDLE_SW:
- case TRANSFORM_HANDLE_SE:
- case TRANSFORM_HANDLE_N:
- case TRANSFORM_HANDLE_S:
- case TRANSFORM_HANDLE_E:
- case TRANSFORM_HANDLE_W:
- tool_cursor = GIMP_TOOL_CURSOR_RESIZE;
- break;
-
- case TRANSFORM_HANDLE_CENTER:
- tool_cursor = GIMP_TOOL_CURSOR_MOVE;
- break;
-
- case TRANSFORM_HANDLE_PIVOT:
- tool_cursor = GIMP_TOOL_CURSOR_ROTATE;
- *modifier = GIMP_CURSOR_MODIFIER_MOVE;
- break;
-
- case TRANSFORM_HANDLE_N_S:
- case TRANSFORM_HANDLE_S_S:
- case TRANSFORM_HANDLE_E_S:
- case TRANSFORM_HANDLE_W_S:
- tool_cursor = GIMP_TOOL_CURSOR_SHEAR;
- break;
-
- case TRANSFORM_HANDLE_ROTATION:
- tool_cursor = GIMP_TOOL_CURSOR_ROTATE;
- break;
-
- default:
- g_assert_not_reached ();
- }
-
- /* parent class sets cursor and cursor_modifier */
- gimp_tool_control_set_tool_cursor (GIMP_TOOL (tr_tool)->control, tool_cursor);
-}
-
-static void
-gimp_unified_transform_tool_draw_gui (GimpTransformTool *tr_tool,
- gint handle_w,
- gint handle_h)
-{
- GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tr_tool);
- GimpCanvasGroup *stroke_group;
- gint d, i;
- gdouble angle[8];
- GimpVector2 o[4], t[4];
-
- get_handle_geometry (tr_tool, o, angle);
-
- for (i = 0; i < 4; i++)
- {
- GimpCanvasItem *h;
-
- /* draw the scale handles */
- h = gimp_draw_tool_add_handle (draw_tool,
- GIMP_HANDLE_SQUARE,
- o[i].x, o[i].y,
- handle_w * 1.5, handle_h * 1.5,
- GIMP_HANDLE_ANCHOR_CENTER);
- gimp_canvas_handle_set_angles (h, angle[i + 4], 0.0);
- tr_tool->handles[TRANSFORM_HANDLE_NW + i] = h;
-
- /* draw the perspective handles */
- h = gimp_draw_tool_add_handle (draw_tool,
- GIMP_HANDLE_DIAMOND,
- o[i].x, o[i].y,
- handle_w * 0.8, handle_h * 0.8,
- GIMP_HANDLE_ANCHOR_CENTER);
- gimp_canvas_handle_set_angles (h, angle[i + 4], 0.0);
- tr_tool->handles[TRANSFORM_HANDLE_NW_P + i] = h;
- }
-
- /* draw the side handles */
- t[0] = scalemult (vectoradd (o[0], o[1]), 0.5);
- t[1] = scalemult (vectoradd (o[2], o[3]), 0.5);
- t[2] = scalemult (vectoradd (o[1], o[3]), 0.5);
- t[3] = scalemult (vectoradd (o[2], o[0]), 0.5);
-
- for (i = 0; i < 4; i++)
- {
- GimpCanvasItem *h;
-
- h = gimp_draw_tool_add_handle (draw_tool,
- GIMP_HANDLE_SQUARE,
- t[i].x, t[i].y,
- handle_w, handle_h,
- GIMP_HANDLE_ANCHOR_CENTER);
- gimp_canvas_handle_set_angles (h, angle[i], 0.0);
- tr_tool->handles[TRANSFORM_HANDLE_N + i] = h;
- }
-
- /* draw the shear handles */
- t[0] = scalemult (vectoradd ( o[0] , scalemult (o[1], 3.0)),
- 0.25);
- t[1] = scalemult (vectoradd (scalemult (o[2], 3.0), o[3] ),
- 0.25);
- t[2] = scalemult (vectoradd ( o[1] , scalemult (o[3], 3.0)),
- 0.25);
- t[3] = scalemult (vectoradd (scalemult (o[2], 3.0), o[0] ),
- 0.25);
-
- for (i = 0; i < 4; i++)
- {
- GimpCanvasItem *h;
-
- h = gimp_draw_tool_add_handle (draw_tool,
- GIMP_HANDLE_FILLED_DIAMOND,
- t[i].x, t[i].y,
- handle_w, handle_h,
- GIMP_HANDLE_ANCHOR_CENTER);
- gimp_canvas_handle_set_angles (h, angle[i], 0.0);
- tr_tool->handles[TRANSFORM_HANDLE_N_S + i] = h;
- }
-
- /* draw the rotation center axis handle */
- 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_CIRCLE,
- 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);
+ tr_tool->progress_text = _("Unified transform");
+ tr_tool->use_grid = TRUE;
+ tr_tool->does_perspective = TRUE;
}
static void
@@ -825,489 +183,56 @@ gimp_unified_transform_tool_prepare (GimpTransformTool *tr_tool)
tr_tool->trans_info[Y3] = (gdouble) tr_tool->y2;
}
-static void
-gimp_unified_transform_tool_motion (GimpTransformTool *transform_tool)
+static GimpToolWidget *
+gimp_unified_transform_tool_get_widget (GimpTransformTool *tr_tool)
{
- GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (transform_tool);
- gdouble *x[4], *y[4];
- gdouble *newpivot_x, *newpivot_y;
-
- GimpVector2 oldpos[5], newpos[4];
- GimpVector2 cur = { .x = transform_tool->curx,
- .y = transform_tool->cury };
- GimpVector2 mouse = { .x = transform_tool->mousex,
- .y = transform_tool->mousey };
- GimpVector2 d;
- GimpVector2 pivot;
-
- gint i;
-
- gboolean fixedpivot = options->fixedpivot;
-
- TransformAction function = transform_tool->function;
-
- for (i = 0; i < 4; i++)
- {
- x[i] = &transform_tool->trans_info[X0 + i * 2];
- y[i] = &transform_tool->trans_info[Y0 + i * 2];
- newpos[i].x = oldpos[i].x = transform_tool->prev_trans_info[0][X0 + i * 2];
- newpos[i].y = oldpos[i].y = transform_tool->prev_trans_info[0][Y0 + i * 2];
- }
-
- /* put center point in this array too */
- oldpos[4].x = (oldpos[0].x + oldpos[1].x + oldpos[2].x + oldpos[3].x) / 4.;
- oldpos[4].y = (oldpos[0].y + oldpos[1].y + oldpos[2].y + oldpos[3].y) / 4.;
-
- d = vectorsubtract (cur, mouse);
-
- newpivot_x = &transform_tool->trans_info[PIVOT_X];
- newpivot_y = &transform_tool->trans_info[PIVOT_Y];
-
- pivot.x = transform_tool->prev_trans_info[0][PIVOT_X];
- pivot.y = transform_tool->prev_trans_info[0][PIVOT_Y];
-
- /* move */
- if (function == TRANSFORM_HANDLE_CENTER)
- {
- if (options->constrain_move)
- {
- /* snap to 45 degree vectors from starting point */
- gdouble angle = 16.0 * calcangle ((GimpVector2) { 1.0, 0.0 },
- d) / (2.0 * G_PI);
- gdouble dist = norm (d) / sqrt (2);
-
- if (angle < 1. || angle >= 15.)
- d.y = 0;
- else if (angle < 3.)
- d.y = -(d.x = dist);
- else if (angle < 5.)
- d.x = 0;
- else if (angle < 7.)
- d.x = d.y = -dist;
- else if (angle < 9.)
- d.y = 0;
- else if (angle < 11.)
- d.x = -(d.y = dist);
- else if (angle < 13.)
- d.x = 0;
- else if (angle < 15.)
- d.x = d.y = dist;
- }
-
- for (i = 0; i < 4; i++)
- newpos[i] = vectoradd (oldpos[i], d);
- }
-
- /* rotate */
- if (function == TRANSFORM_HANDLE_ROTATION)
- {
- gdouble angle = calcangle (vectorsubtract (cur, pivot),
- vectorsubtract (mouse, pivot));
-
- if (options->constrain_rotate)
- {
- /* round to 15 degree multiple */
- angle /= 2*G_PI/24.;
- angle = round (angle);
- angle *= 2*G_PI/24.;
- }
-
- for (i = 0; i < 4; i++)
- newpos[i] = vectoradd (pivot,
- rotate2d (vectorsubtract (oldpos[i], pivot),
- angle));
-
- fixedpivot = TRUE;
- }
-
- /* move rotation axis */
- if (function == TRANSFORM_HANDLE_PIVOT)
- {
- pivot = vectoradd (pivot, d);
-
- if (options->cornersnap)
- {
- /* snap to corner points and center */
- gint closest = 0;
- gdouble closest_dist = G_MAXDOUBLE, dist;
-
- for (i = 0; i < 5; i++)
- {
- dist = norm (vectorsubtract (pivot, oldpos[i]));
- if (dist < closest_dist)
- {
- closest_dist = dist;
- closest = i;
- }
- }
-
- if (closest_dist *
- gimp_display_get_shell (GIMP_TOOL (transform_tool)->display)->scale_x < 50)
- {
- pivot = oldpos[closest];
- }
- }
-
- fixedpivot = TRUE;
- }
-
- /* scaling via corner */
- if (function == TRANSFORM_HANDLE_NW ||
- function == TRANSFORM_HANDLE_NE ||
- function == TRANSFORM_HANDLE_SE ||
- function == TRANSFORM_HANDLE_SW)
- {
- /* Scaling through scale handles means translating one corner point,
- * with all sides at constant angles.
- */
-
- gint this, left, right, opposite;
-
- /* 0: northwest, 1: northeast, 2: southwest, 3: southeast */
- if (function == TRANSFORM_HANDLE_NW)
- {
- this = 0; left = 1; right = 2; opposite = 3;
- }
- else if (function == TRANSFORM_HANDLE_NE)
- {
- this = 1; left = 3; right = 0; opposite = 2;
- }
- else if (function == TRANSFORM_HANDLE_SW)
- {
- this = 2; left = 0; right = 3; opposite = 1;
- }
- else if (function == TRANSFORM_HANDLE_SE)
- {
- this = 3; left = 2; right = 1; opposite = 0;
- }
- else
- g_assert_not_reached ();
-
- /* when the keep aspect transformation constraint is enabled,
- * the translation shall only be along the diagonal that runs
- * trough this corner point.
- */
- if (options->constrain_scale)
- {
- /* restrict to movement along the diagonal */
- GimpVector2 diag = vectorsubtract (oldpos[this], oldpos[opposite]);
-
- d = vectorproject (d, diag);
- }
-
- /* Move the corner being interacted with */
- /* rp---------tp
- * / /\ <- d, the interaction vector
- * / / tp
- * op----------/
- *
- */
- newpos[this] = vectoradd (oldpos[this], d);
-
- /* Where the corner to the right and left would go, need these to form
- * lines to intersect with the sides */
- /* rp----------/
- * /\ /\
- * / nr / nt
- * op----------lp
- * \
- * nl
- */
-
- newpos[right] = vectoradd (oldpos[right], d);
- newpos[left] = vectoradd (oldpos[left], d);
-
- /* Now we just need to find the intersection of op-rp and nr-nt.
- * rp----------/
- * / /
- * / nr==========nt
- * op----------/
- *
- */
- newpos[right] = lineintersect (newpos[right], newpos[this],
- oldpos[opposite], oldpos[right]);
- newpos[left] = lineintersect (newpos[left], newpos[this],
- oldpos[opposite], oldpos[left]);
- /* /-----------/
- * / /
- * rp============nt
- * op----------/
- *
- */
-
- /*
- *
- * /--------------/
- * /--------------/
- *
- */
-
- if (options->frompivot_scale &&
- transform_is_convex (newpos) &&
- transform_is_convex (oldpos))
- {
- /* transform the pivot point before the interaction and
- * after, and move everything by this difference
- */
- //TODO the handle doesn't actually end up where the mouse cursor is
- GimpVector2 delta = get_pivot_delta (transform_tool,
- oldpos, newpos, pivot);
- for (i = 0; i < 4; i++)
- newpos[i] = vectorsubtract (newpos[i], delta);
-
- fixedpivot = TRUE;
- }
- }
-
- /* scaling via sides */
- if (function == TRANSFORM_HANDLE_N ||
- function == TRANSFORM_HANDLE_E ||
- function == TRANSFORM_HANDLE_S ||
- function == TRANSFORM_HANDLE_W)
- {
- gint this_l, this_r, opp_l, opp_r;
- GimpVector2 side_l, side_r, midline;
-
- /* 0: northwest, 1: northeast, 2: southwest, 3: southeast */
- if (function == TRANSFORM_HANDLE_N)
- {
- this_l = 1; this_r = 0;
- }
- else if (function == TRANSFORM_HANDLE_E)
- {
- this_l = 3; this_r = 1;
- }
- else if (function == TRANSFORM_HANDLE_S)
- {
- this_l = 2; this_r = 3;
- }
- else if (function == TRANSFORM_HANDLE_W)
- {
- this_l = 0; this_r = 2;
- }
- else
- g_assert_not_reached ();
-
- opp_l = 3 - this_r; opp_r = 3 - this_l;
-
- side_l = vectorsubtract (oldpos[opp_l], oldpos[this_l]);
- side_r = vectorsubtract (oldpos[opp_r], oldpos[this_r]);
- midline = vectoradd (side_l, side_r);
-
- /* restrict to movement along the midline */
- d = vectorproject (d, midline);
-
- if (options->constrain_scale)
- {
- GimpVector2 before, after, effective_pivot = pivot;
- gdouble distance;
-
- if (! options->frompivot_scale)
- {
- /* center of the opposite side is pivot */
- effective_pivot = scalemult (vectoradd (oldpos[opp_l],
- oldpos[opp_r]), 0.5);
- }
-
- /* get the difference between the distance from the pivot to
- * where interaction started and the distance from the pivot
- * to where cursor is now, and scale all corners distance
- * from the pivot with this factor
- */
- before = vectorsubtract (effective_pivot, mouse);
- after = vectorsubtract (effective_pivot, cur);
- after = vectorproject (after, before);
-
- distance = 0.5 * (after.x / before.x + after.y / before.y);
-
- for (i = 0; i < 4; i++)
- newpos[i] = vectoradd (effective_pivot,
- scalemult (vectorsubtract (oldpos[i],
- effective_pivot),
- distance));
- }
- else
- {
- /* just move the side */
- newpos[this_l] = vectoradd (oldpos[this_l], d);
- newpos[this_r] = vectoradd (oldpos[this_r], d);
- }
-
- if (! options->constrain_scale &&
- options->frompivot_scale &&
- transform_is_convex (newpos) &&
- transform_is_convex (oldpos))
- {
- GimpVector2 delta = get_pivot_delta (transform_tool,
- oldpos, newpos, pivot);
- for (i = 0; i < 4; i++)
- newpos[i] = vectorsubtract (newpos[i], delta);
-
- fixedpivot = TRUE;
- }
- }
-
- /* shear */
- if (function == TRANSFORM_HANDLE_N_S ||
- function == TRANSFORM_HANDLE_E_S ||
- function == TRANSFORM_HANDLE_S_S ||
- function == TRANSFORM_HANDLE_W_S)
- {
- gint this_l, this_r;
-
- /* set up indices for this edge and the opposite edge */
- if (function == TRANSFORM_HANDLE_N_S)
- {
- this_l = 1; this_r = 0;
- }
- else if (function == TRANSFORM_HANDLE_W_S)
- {
- this_l = 0; this_r = 2;
- }
- else if (function == TRANSFORM_HANDLE_S_S)
- {
- this_l = 2; this_r = 3;
- }
- else if (function == TRANSFORM_HANDLE_E_S)
- {
- this_l = 3; this_r = 1;
- }
- else
- g_assert_not_reached ();
-
- if (options->constrain_shear)
- {
- /* restrict to movement along the side */
- GimpVector2 side = vectorsubtract (oldpos[this_r], oldpos[this_l]);
-
- d = vectorproject (d, side);
- }
-
- newpos[this_l] = vectoradd (oldpos[this_l], d);
- newpos[this_r] = vectoradd (oldpos[this_r], d);
-
- if (options->frompivot_shear &&
- transform_is_convex (newpos) &&
- transform_is_convex (oldpos))
- {
- GimpVector2 delta = get_pivot_delta (transform_tool,
- oldpos, newpos, pivot);
- for (i = 0; i < 4; i++)
- newpos[i] = vectorsubtract (newpos[i], delta);
-
- fixedpivot = TRUE;
- }
- }
-
- /* perspective transform */
- if (function == TRANSFORM_HANDLE_NW_P ||
- function == TRANSFORM_HANDLE_NE_P ||
- function == TRANSFORM_HANDLE_SE_P ||
- function == TRANSFORM_HANDLE_SW_P)
- {
- gint this, left, right, opposite;
-
- /* 0: northwest, 1: northeast, 2: southwest, 3: southeast */
- if (function == TRANSFORM_HANDLE_NW_P)
- {
- this = 0; left = 1; right = 2; opposite = 3;
- }
- else if (function == TRANSFORM_HANDLE_NE_P)
- {
- this = 1; left = 3; right = 0; opposite = 2;
- }
- else if (function == TRANSFORM_HANDLE_SW_P)
- {
- this = 2; left = 0; right = 3; opposite = 1;
- }
- else if (function == TRANSFORM_HANDLE_SE_P)
- {
- this = 3; left = 2; right = 1; opposite = 0;
- }
- else
- g_assert_not_reached ();
-
- if (options->constrain_perspective)
- {
- /* when the constrain transformation constraint is enabled,
- * the translation shall only be either along the side
- * angles of the two sides that run to this corner point, or
- * along the diagonal that runs trough this corner point.
- */
- GimpVector2 proj[4];
- gdouble rej[4];
-
- for (i = 0; i < 4; i++)
- {
- if (i == this)
- continue;
-
- /* get the vectors along the sides and the diagonal */
- proj[i] = vectorsubtract (oldpos[this], oldpos[i]);
-
- /* project d on each candidate vector and see which has
- * the shortest rejection
- */
- proj[i] = vectorproject (d, proj[i]);
- rej[i] = norm (vectorsubtract (d, proj[i]));
- }
-
- if (rej[left] < rej[right] && rej[left] < rej[opposite])
- d = proj[left];
- else if (rej[right] < rej[opposite])
- d = proj[right];
- else
- d = proj[opposite];
- }
-
- newpos[this] = vectoradd (oldpos[this], d);
-
- if (options->frompivot_perspective &&
- transform_is_convex (newpos) &&
- transform_is_convex (oldpos))
- {
- GimpVector2 delta = get_pivot_delta (transform_tool,
- oldpos, newpos, pivot);
-
- for (i = 0; i < 4; i++)
- newpos[i] = vectorsubtract (newpos[i], delta);
-
- fixedpivot = TRUE;
- }
- }
-
- for (i = 0; i < 4; i++)
- {
- *x[i] = newpos[i].x;
- *y[i] = newpos[i].y;
- }
-
- /* this will have been set to TRUE if an operation used the pivot in
- * addition to being a user option
- */
- if (! fixedpivot &&
- transform_is_convex (newpos) &&
- transform_is_convex (oldpos) &&
- point_is_inside_polygon_pos (oldpos, pivot))
- {
- GimpVector2 delta = get_pivot_delta (transform_tool,
- oldpos, newpos, pivot);
- pivot = vectoradd (pivot, delta);
- }
-
- /* set unconditionally: if options get toggled during operation, we
- * have to move pivot back
- */
- *newpivot_x = pivot.x;
- *newpivot_y = pivot.y;
+ GimpTool *tool = GIMP_TOOL (tr_tool);
+ GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
+ GimpDisplayShell *shell = gimp_display_get_shell (tool->display);
+ GimpToolWidget *widget;
+
+ widget = gimp_tool_transform_grid_new (shell,
+ &tr_tool->transform,
+ tr_tool->x1,
+ tr_tool->y1,
+ tr_tool->x2,
+ tr_tool->y2,
+ options->grid_type,
+ options->grid_size);
+
+ g_object_set (widget,
+ "pivot-x", (tr_tool->x1 + tr_tool->x2) / 2.0,
+ "pivot-y", (tr_tool->y1 + tr_tool->y2) / 2.0,
+ "inside-function", GIMP_TRANSFORM_FUNCTION_MOVE,
+ "outside-function", GIMP_TRANSFORM_FUNCTION_ROTATE,
+ "use-corner-handles", TRUE,
+ "use-perspective-handles", TRUE,
+ "use-side-handles", TRUE,
+ "use-shear-handles", TRUE,
+ "use-pivot-handle", TRUE,
+ "constrain-move", options->constrain_move,
+ "constrain-scale", options->constrain_scale,
+ "constrain-rotate", options->constrain_rotate,
+ "constrain-shear", options->constrain_shear,
+ "constrain-perspective", options->constrain_perspective,
+ "frompivot-scale", options->frompivot_scale,
+ "frompivot-shear", options->frompivot_shear,
+ "frompivot-perspective", options->frompivot_perspective,
+ "cornersnap", options->cornersnap,
+ "fixedpivot", options->fixedpivot,
+ NULL);
+
+ g_signal_connect (widget, "changed",
+ G_CALLBACK (gimp_unified_transform_tool_widget_changed),
+ tr_tool);
+
+ return widget;
}
static void
-gimp_unified_transform_tool_recalc_matrix (GimpTransformTool *tr_tool)
+gimp_unified_transform_tool_recalc_matrix (GimpTransformTool *tr_tool,
+ GimpToolWidget *widget)
{
- 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_perspective (&tr_tool->transform,
tr_tool->x1,
@@ -1322,6 +247,17 @@ gimp_unified_transform_tool_recalc_matrix (GimpTransformTool *tr_tool)
tr_tool->trans_info[Y2],
tr_tool->trans_info[X3],
tr_tool->trans_info[Y3]);
+
+ if (widget)
+ g_object_set (widget,
+ "transform", &tr_tool->transform,
+ "x1", (gdouble) tr_tool->x1,
+ "y1", (gdouble) tr_tool->y1,
+ "x2", (gdouble) tr_tool->x2,
+ "y2", (gdouble) tr_tool->y2,
+ "pivot-x", tr_tool->trans_info[PIVOT_X],
+ "pivot-y", tr_tool->trans_info[PIVOT_Y],
+ NULL);
}
static gchar *
@@ -1329,3 +265,37 @@ gimp_unified_transform_tool_get_undo_desc (GimpTransformTool *tr_tool)
{
return g_strdup (C_("undo-type", "Unified Transform"));
}
+
+static void
+gimp_unified_transform_tool_widget_changed (GimpToolWidget *widget,
+ GimpTransformTool *tr_tool)
+{
+ GimpMatrix3 *transform;
+
+ g_object_get (widget,
+ "transform", &transform,
+ "pivot-x", &tr_tool->trans_info[PIVOT_X],
+ "pivot-y", &tr_tool->trans_info[PIVOT_Y],
+ NULL);
+
+ gimp_matrix3_transform_point (transform,
+ tr_tool->x1, tr_tool->y1,
+ &tr_tool->trans_info[X0],
+ &tr_tool->trans_info[Y0]);
+ gimp_matrix3_transform_point (transform,
+ tr_tool->x2, tr_tool->y1,
+ &tr_tool->trans_info[X1],
+ &tr_tool->trans_info[Y1]);
+ gimp_matrix3_transform_point (transform,
+ tr_tool->x1, tr_tool->y2,
+ &tr_tool->trans_info[X2],
+ &tr_tool->trans_info[Y2]);
+ gimp_matrix3_transform_point (transform,
+ tr_tool->x2, tr_tool->y2,
+ &tr_tool->trans_info[X3],
+ &tr_tool->trans_info[Y3]);
+
+ g_free (transform);
+
+ gimp_transform_tool_recalc_matrix (tr_tool, NULL);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]