[gimp/soc-2012-unified-transformation: 5/25] transformtool: add old "new" unified transformation tool
- From: Mikael Magnusson <mikachu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/soc-2012-unified-transformation: 5/25] transformtool: add old "new" unified transformation tool
- Date: Tue, 10 Jul 2012 20:34:14 +0000 (UTC)
commit ccc940e06de45e79792385573a763174b43f5652
Author: Mikael Magnusson <mikachu src gnome org>
Date: Sat Aug 6 00:00:35 2011 +0200
transformtool: add old "new" unified transformation tool
This is the proof of concept code I wrote before gsoc, with very naive
behaviour and simple interface.
app/dialogs/dialogs.c | 1 +
app/tools/Makefile.am | 2 +
app/tools/gimp-tools.c | 2 +
app/tools/gimptransformoptions.c | 34 ++
app/tools/gimptransformoptions.h | 1 +
app/tools/gimptransformtool.c | 19 +-
app/tools/gimptransformtool.h | 8 +-
app/tools/gimpunifiedtransformationtool.c | 440 ++++++++++++++++++++
app/tools/gimpunifiedtransformationtool.h | 55 +++
app/widgets/gimphelp-ids.h | 1 +
app/widgets/widgets-enums.h | 1 +
libgimpwidgets/gimpstock.c | 3 +
libgimpwidgets/gimpstock.h | 1 +
themes/Default/images/Makefile.am | 2 +
.../tools/stock-tool-unified-transformation-16.png | Bin 0 -> 586 bytes
.../tools/stock-tool-unified-transformation-22.png | Bin 0 -> 914 bytes
.../tools/stock-tool-unified-transformation-22.xcf | Bin 0 -> 3778 bytes
17 files changed, 562 insertions(+), 8 deletions(-)
---
diff --git a/app/dialogs/dialogs.c b/app/dialogs/dialogs.c
index b121708..9a74d7d 100644
--- a/app/dialogs/dialogs.c
+++ b/app/dialogs/dialogs.c
@@ -240,6 +240,7 @@ static const GimpDialogFactoryEntry entries[] =
FOREIGN ("gimp-text-tool-dialog", TRUE, TRUE),
FOREIGN ("gimp-threshold-tool-dialog", TRUE, FALSE),
FOREIGN ("gimp-perspective-tool-dialog", TRUE, FALSE),
+ FOREIGN ("gimp-unified-transformation-tool-dialog", TRUE, FALSE),
FOREIGN ("gimp-toolbox-color-dialog", TRUE, FALSE),
FOREIGN ("gimp-gradient-editor-color-dialog", TRUE, FALSE),
diff --git a/app/tools/Makefile.am b/app/tools/Makefile.am
index ba4ba83..1e80cca 100644
--- a/app/tools/Makefile.am
+++ b/app/tools/Makefile.am
@@ -194,6 +194,8 @@ libapptools_a_sources = \
gimptransformtool.h \
gimptransformtoolundo.c \
gimptransformtoolundo.h \
+ gimpunifiedtransformationtool.c \
+ gimpunifiedtransformationtool.h \
gimpvectoroptions.c \
gimpvectoroptions.h \
gimpvectortool.c \
diff --git a/app/tools/gimp-tools.c b/app/tools/gimp-tools.c
index ca01aed..60342e9 100644
--- a/app/tools/gimp-tools.c
+++ b/app/tools/gimp-tools.c
@@ -82,6 +82,7 @@
#include "gimpsheartool.h"
#include "gimpsmudgetool.h"
#include "gimptexttool.h"
+#include "gimpunifiedtransformationtool.h"
#include "gimpvectortool.h"
#include "gimp-intl.h"
@@ -156,6 +157,7 @@ gimp_tools_init (Gimp *gimp)
gimp_shear_tool_register,
gimp_scale_tool_register,
gimp_rotate_tool_register,
+ gimp_unified_transformation_tool_register,
gimp_crop_tool_register,
gimp_align_tool_register,
gimp_move_tool_register,
diff --git a/app/tools/gimptransformoptions.c b/app/tools/gimptransformoptions.c
index 6e47e93..5dc9422 100644
--- a/app/tools/gimptransformoptions.c
+++ b/app/tools/gimptransformoptions.c
@@ -35,6 +35,7 @@
#include "gimprotatetool.h"
#include "gimpscaletool.h"
+#include "gimpunifiedtransformationtool.h"
#include "gimptooloptions-gui.h"
#include "gimptransformoptions.h"
@@ -53,6 +54,7 @@ enum
PROP_GRID_TYPE,
PROP_GRID_SIZE,
PROP_CONSTRAIN,
+ PROP_ALTERNATE,
};
@@ -139,6 +141,11 @@ gimp_transform_options_class_init (GimpTransformOptionsClass *klass)
NULL,
FALSE,
GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_ALTERNATE,
+ "alternate",
+ N_("Use alternate set of controls"),
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
}
static void
@@ -184,6 +191,9 @@ gimp_transform_options_set_property (GObject *object,
case PROP_CONSTRAIN:
options->constrain = g_value_get_boolean (value);
break;
+ case PROP_ALTERNATE:
+ options->alternate = g_value_get_boolean (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -227,6 +237,9 @@ gimp_transform_options_get_property (GObject *object,
case PROP_CONSTRAIN:
g_value_set_boolean (value, options->constrain);
break;
+ case PROP_ALTERNATE:
+ g_value_set_boolean (value, options->alternate);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -270,6 +283,7 @@ gimp_transform_options_gui (GimpToolOptions *tool_options)
GtkWidget *grid_box;
const gchar *constrain_label = NULL;
const gchar *constrain_tip = NULL;
+ const gchar *alternate = NULL;
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
@@ -352,6 +366,26 @@ gimp_transform_options_gui (GimpToolOptions *tool_options)
constrain_label = _("Keep aspect (%s)");
constrain_tip = _("Keep the original aspect ratio");
}
+ else if (tool_options->tool_info->tool_type == GIMP_TYPE_UNIFIED_TRANSFORMATION_TOOL)
+ {
+ alternate = (_("Move points (%s)"));
+ constrain_label = constrain_tip = (_("Keep aspect when scaling (%s)"));
+ }
+
+ if (alternate)
+ {
+ GtkWidget *button;
+ gchar *label;
+
+ label = g_strdup_printf (alternate,
+ gimp_get_mod_string (GDK_MOD1_MASK));
+
+ button = gimp_prop_check_button_new (config, "alternate", label);
+ gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+ gtk_widget_show (button);
+
+ g_free (label);
+ }
if (constrain_label)
{
diff --git a/app/tools/gimptransformoptions.h b/app/tools/gimptransformoptions.h
index 18196b8..e9d2698 100644
--- a/app/tools/gimptransformoptions.h
+++ b/app/tools/gimptransformoptions.h
@@ -47,6 +47,7 @@ struct _GimpTransformOptions
GimpGuidesType grid_type;
gint grid_size;
gboolean constrain;
+ gboolean alternate;
};
diff --git a/app/tools/gimptransformtool.c b/app/tools/gimptransformtool.c
index 06a2007..4068e38 100644
--- a/app/tools/gimptransformtool.c
+++ b/app/tools/gimptransformtool.c
@@ -59,6 +59,7 @@
#include "gimptoolcontrol.h"
#include "gimpperspectivetool.h"
+#include "gimpunifiedtransformationtool.h"
#include "gimptransformoptions.h"
#include "gimptransformtool.h"
#include "gimptransformtoolundo.h"
@@ -208,10 +209,9 @@ gimp_transform_tool_init (GimpTransformTool *tr_tool)
GIMP_CURSOR_PRECISION_SUBPIXEL);
tr_tool->function = TRANSFORM_CREATING;
+ tr_tool->progress_text = _("Transforming");
gimp_matrix3_identity (&tr_tool->transform);
-
- tr_tool->progress_text = _("Transforming");
}
static void
@@ -499,6 +499,11 @@ gimp_transform_tool_modifier_key (GimpTool *tool,
g_object_set (options,
"constrain", ! options->constrain,
NULL);
+
+ if (key == GDK_MOD1_MASK)
+ g_object_set (options,
+ "alternate", ! options->alternate,
+ NULL);
}
static void
@@ -723,7 +728,7 @@ gimp_transform_tool_options_notify (GimpTool *tool,
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tr_tool));
}
- if (! strcmp (pspec->name, "constrain"))
+ if (! strcmp (pspec->name, "constrain") || ! strcmp (pspec->name, "alternate"))
{
gimp_transform_tool_dialog_update (tr_tool);
}
@@ -754,7 +759,7 @@ gimp_transform_tool_draw (GimpDrawTool *draw_tool)
tr_tool->y1,
tr_tool->x2,
tr_tool->y2,
- GIMP_IS_PERSPECTIVE_TOOL (tr_tool),
+ GIMP_IS_PERSPECTIVE_TOOL (tr_tool) || GIMP_IS_UNIFIED_TRANSFORMATION_TOOL (tr_tool),
options->preview_opacity);
}
@@ -851,7 +856,7 @@ gimp_transform_tool_draw (GimpDrawTool *draw_tool)
if (tr_tool->use_pivot)
{
GimpCanvasGroup *stroke_group;
- gint d = MIN (handle_w, handle_h);
+ gint d = MIN (handle_w, handle_h) * 2; /* so you can grab it from under the center handle */
stroke_group = gimp_draw_tool_add_stroke_group (draw_tool);
@@ -1310,11 +1315,11 @@ gimp_transform_tool_transform_bounding_box (GimpTransformTool *tr_tool)
gimp_matrix3_transform_point (&tr_tool->transform,
tr_tool->x2, tr_tool->y2,
&tr_tool->tx4, &tr_tool->ty4);
-
- /* don't transform these */
gimp_matrix3_transform_point (&tr_tool->transform,
tr_tool->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;
diff --git a/app/tools/gimptransformtool.h b/app/tools/gimptransformtool.h
index d8dacf1..03166e1 100644
--- a/app/tools/gimptransformtool.h
+++ b/app/tools/gimptransformtool.h
@@ -22,7 +22,7 @@
#include "gimpdrawtool.h"
-#define TRANS_INFO_SIZE 8
+#define TRANS_INFO_SIZE 10
typedef enum
{
@@ -65,6 +65,12 @@ struct _GimpTransformTool
gdouble lastx; /* last x coord */
gdouble lasty; /* last y coord */
+ gdouble previousx; /* previous x coord */
+ gdouble previousy; /* previous y coord */
+
+ gdouble mousex; /* x coord where mouse was clicked */
+ gdouble mousey; /* y coord where mouse was clicked */
+
gint x1, y1; /* upper left hand coordinate */
gint x2, y2; /* lower right hand coords */
gdouble cx, cy; /* center point (for moving) */
diff --git a/app/tools/gimpunifiedtransformationtool.c b/app/tools/gimpunifiedtransformationtool.c
new file mode 100644
index 0000000..347da02
--- /dev/null
+++ b/app/tools/gimpunifiedtransformationtool.c
@@ -0,0 +1,440 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <gegl.h>
+#include <gtk/gtk.h>
+
+#include "libgimpmath/gimpmath.h"
+#include "libgimpwidgets/gimpwidgets.h"
+
+#include "tools-types.h"
+
+#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 "gimpunifiedtransformationtool.h"
+#include "gimptoolcontrol.h"
+#include "gimptransformoptions.h"
+
+#include "gimp-intl.h"
+
+
+/* index into trans_info array */
+enum
+{
+ X0,
+ Y0,
+ X1,
+ Y1,
+ X2,
+ Y2,
+ X3,
+ Y3,
+ PIVOT_X,
+ PIVOT_Y,
+};
+
+
+/* local function prototypes */
+
+static void gimp_unified_transformation_tool_dialog (GimpTransformTool *tr_tool);
+static void gimp_unified_transformation_tool_dialog_update (GimpTransformTool *tr_tool);
+static void gimp_unified_transformation_tool_prepare (GimpTransformTool *tr_tool);
+static void gimp_unified_transformation_tool_motion (GimpTransformTool *tr_tool);
+static void gimp_unified_transformation_tool_recalc_matrix (GimpTransformTool *tr_tool);
+static gchar * gimp_unified_transformation_tool_get_undo_desc (GimpTransformTool *tr_tool);
+
+
+G_DEFINE_TYPE (GimpUnifiedTransformationTool, gimp_unified_transformation_tool,
+ GIMP_TYPE_TRANSFORM_TOOL)
+
+
+void
+gimp_unified_transformation_tool_register (GimpToolRegisterCallback callback,
+ gpointer data)
+{
+ (* callback) (GIMP_TYPE_UNIFIED_TRANSFORMATION_TOOL,
+ GIMP_TYPE_TRANSFORM_OPTIONS,
+ gimp_transform_options_gui,
+ GIMP_CONTEXT_BACKGROUND_MASK,
+ "gimp-unified-transformation-tool",
+ _("Unified Transformation"),
+ _("Unified Transformation Tool: "
+ "Transform the layer, selection or path"),
+ N_("_Unified Transformation"), "<shift>U",
+ NULL, GIMP_HELP_TOOL_UNIFIED_TRANSFORMATION,
+ GIMP_STOCK_TOOL_UNIFIED_TRANSFORMATION,
+ data);
+}
+
+static void
+gimp_unified_transformation_tool_class_init (GimpUnifiedTransformationToolClass *klass)
+{
+ GimpTransformToolClass *trans_class = GIMP_TRANSFORM_TOOL_CLASS (klass);
+
+ trans_class->dialog = gimp_unified_transformation_tool_dialog;
+ trans_class->dialog_update = gimp_unified_transformation_tool_dialog_update;
+ trans_class->prepare = gimp_unified_transformation_tool_prepare;
+ trans_class->motion = gimp_unified_transformation_tool_motion;
+ trans_class->recalc_matrix = gimp_unified_transformation_tool_recalc_matrix;
+ trans_class->get_undo_desc = gimp_unified_transformation_tool_get_undo_desc;
+}
+
+static void
+gimp_unified_transformation_tool_init (GimpUnifiedTransformationTool *unified_tool)
+{
+ GimpTool *tool = GIMP_TOOL (unified_tool);
+ GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (unified_tool);
+
+ gimp_tool_control_set_tool_cursor (tool->control,
+ GIMP_TOOL_CURSOR_UNIFIED_TRANSFORMATION);
+
+ tr_tool->progress_text = _("Unified transformation");
+
+ tr_tool->use_grid = TRUE;
+ tr_tool->use_handles = TRUE;
+ tr_tool->use_center = TRUE;
+ tr_tool->use_mid_handles = TRUE;
+ tr_tool->use_pivot = TRUE;
+}
+
+static void
+gimp_unified_transformation_tool_dialog (GimpTransformTool *tr_tool)
+{
+ GimpUnifiedTransformationTool *unified = GIMP_UNIFIED_TRANSFORMATION_TOOL (tr_tool);
+ GtkWidget *content_area;
+ GtkWidget *frame;
+ GtkWidget *table;
+ gint x, y;
+
+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (tr_tool->dialog));
+
+ frame = gimp_frame_new (_("Transformation Matrix"));
+ gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
+ gtk_box_pack_start (GTK_BOX (content_area), frame, FALSE, FALSE, 0);
+ gtk_widget_show (frame);
+
+ table = gtk_table_new (3, 3, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 2);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 2);
+ gtk_container_add (GTK_CONTAINER (frame), table);
+ gtk_widget_show (table);
+
+ for (y = 0; y < 3; y++)
+ for (x = 0; x < 3; x++)
+ {
+ GtkWidget *label = gtk_label_new (" ");
+
+ gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.0);
+ gtk_label_set_width_chars (GTK_LABEL (label), 12);
+ gtk_table_attach (GTK_TABLE (table), label,
+ x, x + 1, y, y + 1, GTK_EXPAND, GTK_FILL, 0, 0);
+ gtk_widget_show (label);
+
+ unified->label[y][x] = label;
+ }
+}
+
+static void
+gimp_unified_transformation_tool_dialog_update (GimpTransformTool *tr_tool)
+{
+ GimpUnifiedTransformationTool *unified = GIMP_UNIFIED_TRANSFORMATION_TOOL (tr_tool);
+ gint x, y;
+
+ for (y = 0; y < 3; y++)
+ for (x = 0; x < 3; x++)
+ {
+ gchar buf[32];
+
+ g_snprintf (buf, sizeof (buf),
+ "%10.5f", tr_tool->transform.coeff[y][x]);
+
+ gtk_label_set_text (GTK_LABEL (unified->label[y][x]), buf);
+ }
+}
+
+static void
+gimp_unified_transformation_tool_prepare (GimpTransformTool *tr_tool)
+{
+ 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;
+
+ tr_tool->trans_info[X0] = (gdouble) tr_tool->x1;
+ tr_tool->trans_info[Y0] = (gdouble) tr_tool->y1;
+ tr_tool->trans_info[X1] = (gdouble) tr_tool->x2;
+ tr_tool->trans_info[Y1] = (gdouble) tr_tool->y1;
+ tr_tool->trans_info[X2] = (gdouble) tr_tool->x1;
+ tr_tool->trans_info[Y2] = (gdouble) tr_tool->y2;
+ tr_tool->trans_info[X3] = (gdouble) tr_tool->x2;
+ tr_tool->trans_info[Y3] = (gdouble) tr_tool->y2;
+}
+
+
+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;
+}
+
+/* finds the clockwise angle between the vectors given, 0-2Ï */
+static inline gdouble calcangle(GimpVector2 a, GimpVector2 b) {
+ gdouble angle, angle2, 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.) ? 2*G_PI-angle : 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 shearvector(GimpVector2 p, gdouble factor) {
+ GimpVector2 ret;
+ ret.x = p.x + p.y * factor;
+ ret.y = p.y;
+ return ret;
+}
+
+static void
+gimp_unified_transformation_tool_motion (GimpTransformTool *transform_tool)
+{
+ gdouble diff_x = transform_tool->curx - transform_tool->lastx,
+ diff_y = transform_tool->cury - transform_tool->lasty;
+ gdouble *x[4], *y[4], px[4], py[4], *pivot_x, *pivot_y;
+ gint i;
+ gboolean horizontal = FALSE;
+ GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (transform_tool);
+
+ x[0] = &transform_tool->trans_info[X0];
+ x[1] = &transform_tool->trans_info[X1];
+ x[2] = &transform_tool->trans_info[X2];
+ x[3] = &transform_tool->trans_info[X3];
+ y[0] = &transform_tool->trans_info[Y0];
+ y[1] = &transform_tool->trans_info[Y1];
+ y[2] = &transform_tool->trans_info[Y2];
+ y[3] = &transform_tool->trans_info[Y3];
+
+ px[0] = (*transform_tool->prev_trans_info)[X0];
+ px[1] = (*transform_tool->prev_trans_info)[X1];
+ px[2] = (*transform_tool->prev_trans_info)[X2];
+ px[3] = (*transform_tool->prev_trans_info)[X3];
+ py[0] = (*transform_tool->prev_trans_info)[Y0];
+ py[1] = (*transform_tool->prev_trans_info)[Y1];
+ py[2] = (*transform_tool->prev_trans_info)[Y2];
+ py[3] = (*transform_tool->prev_trans_info)[Y3];
+
+ pivot_x = &transform_tool->trans_info[PIVOT_X];
+ pivot_y = &transform_tool->trans_info[PIVOT_Y];
+
+ if (options->alternate)
+ {
+ gdouble *x0, *x1, *y0, *y1;
+ gboolean moveedge = FALSE;
+
+ switch (transform_tool->function)
+ {
+ case TRANSFORM_HANDLE_W:
+ x0 = x[0]; y0 = y[0];
+ x1 = x[2]; y1 = y[2];
+ moveedge = TRUE;
+ break;
+
+ case TRANSFORM_HANDLE_S:
+ x0 = x[2]; y0 = y[2];
+ x1 = x[3]; y1 = y[3];
+ moveedge = TRUE;
+ break;
+
+ case TRANSFORM_HANDLE_N:
+ x0 = x[0]; y0 = y[0];
+ x1 = x[1]; y1 = y[1];
+ moveedge = TRUE;
+ break;
+
+ case TRANSFORM_HANDLE_E:
+ x0 = x[1]; y0 = y[1];
+ x1 = x[3]; y1 = y[3];
+ moveedge = TRUE;
+ break;
+
+ case TRANSFORM_HANDLE_NW:
+ *x[0] += diff_x;
+ *y[0] += diff_y;
+ return;
+
+ case TRANSFORM_HANDLE_NE:
+ *x[1] += diff_x;
+ *y[1] += diff_y;
+ return;
+
+ case TRANSFORM_HANDLE_SW:
+ *x[2] += diff_x;
+ *y[2] += diff_y;
+ return;
+
+ case TRANSFORM_HANDLE_SE:
+ *x[3] += diff_x;
+ *y[3] += diff_y;
+ return;
+
+ default:
+ break;
+ }
+ if (moveedge)
+ {
+ *x0 += diff_x;
+ *x1 += diff_x;
+ *y0 += diff_y;
+ *y1 += diff_y;
+ return;
+ }
+ }
+
+ switch (transform_tool->function)
+ {
+ case TRANSFORM_HANDLE_NW:
+ case TRANSFORM_HANDLE_NE:
+ case TRANSFORM_HANDLE_SW:
+ case TRANSFORM_HANDLE_SE:
+ {
+ GimpVector2 m = { .x = transform_tool->curx, .y = transform_tool->cury };
+ GimpVector2 p = { .x = transform_tool->mousex, .y = transform_tool->mousey };
+ GimpVector2 c = { .x = *pivot_x, .y = *pivot_y };
+ gdouble angle = calcangle(vectorsubtract(m, c), vectorsubtract(p, c));
+ for (i = 0; i < 4; i++) {
+ p.x = px[i]; p.y = py[i];
+ m = vectoradd(c, rotate2d(vectorsubtract(p, c), angle));
+ *x[i] = m.x;
+ *y[i] = m.y;
+ }
+ return;
+ }
+ case TRANSFORM_HANDLE_CENTER:
+ *x[0] += diff_x;
+ *y[0] += diff_y;
+ *x[1] += diff_x;
+ *y[1] += diff_y;
+ *x[2] += diff_x;
+ *y[2] += diff_y;
+ *x[3] += diff_x;
+ *y[3] += diff_y;
+ break;
+
+ case TRANSFORM_HANDLE_PIVOT:
+ *pivot_x += diff_x;
+ *pivot_y += diff_y;
+ break;
+
+ case TRANSFORM_HANDLE_E:
+ case TRANSFORM_HANDLE_W:
+ horizontal = TRUE;
+ case TRANSFORM_HANDLE_N:
+ case TRANSFORM_HANDLE_S:
+ if (! options->constrain)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ if (horizontal)
+ *x[i] = *pivot_x + (*pivot_x-transform_tool->curx)/(*pivot_x-transform_tool->mousex)*(px[i]-*pivot_x);
+ else
+ *y[i] = *pivot_y + (*pivot_y-transform_tool->cury)/(*pivot_y-transform_tool->mousey)*(py[i]-*pivot_y);
+ }
+ } else {
+ GimpVector2 m = { .x = transform_tool->curx, .y = transform_tool->cury };
+ GimpVector2 p = { .x = transform_tool->mousex, .y = transform_tool->mousey };
+ GimpVector2 c = { .x = *pivot_x, .y = *pivot_y };
+ gdouble onorm = 1./norm(vectorsubtract(c, p));
+ gdouble distance = norm(vectorsubtract(c, m)) * onorm;
+ for (i = 0; i < 4; i++) {
+ p.x = px[i]; p.y = py[i];
+ m = vectoradd(c, scalemult(vectorsubtract(p, c), distance));
+ *x[i] = m.x;
+ *y[i] = m.y;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void
+gimp_unified_transformation_tool_recalc_matrix (GimpTransformTool *tr_tool)
+{
+ 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,
+ tr_tool->y1,
+ tr_tool->x2 - tr_tool->x1,
+ tr_tool->y2 - tr_tool->y1,
+ tr_tool->trans_info[X0],
+ tr_tool->trans_info[Y0],
+ tr_tool->trans_info[X1],
+ tr_tool->trans_info[Y1],
+ tr_tool->trans_info[X2],
+ tr_tool->trans_info[Y2],
+ tr_tool->trans_info[X3],
+ tr_tool->trans_info[Y3]);
+}
+
+static gchar *
+gimp_unified_transformation_tool_get_undo_desc (GimpTransformTool *tr_tool)
+{
+ return g_strdup (C_("undo-type", "Unified Transform"));
+}
diff --git a/app/tools/gimpunifiedtransformationtool.h b/app/tools/gimpunifiedtransformationtool.h
new file mode 100644
index 0000000..1d9b02e
--- /dev/null
+++ b/app/tools/gimpunifiedtransformationtool.h
@@ -0,0 +1,55 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GIMP_UNIFIED_TRANSFORMATION_TOOL_H__
+#define __GIMP_UNIFIED_TRANSFORMATION_TOOL_H__
+
+
+#include "gimptransformtool.h"
+
+
+#define GIMP_TYPE_UNIFIED_TRANSFORMATION_TOOL (gimp_unified_transformation_tool_get_type ())
+#define GIMP_UNIFIED_TRANSFORMATION_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_UNIFIED_TRANSFORMATION_TOOL, GimpUnifiedTransformationTool))
+#define GIMP_UNIFIED_TRANSFORMATION_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_UNIFIED_TRANSFORMATION_TOOL, GimpUnifiedTransformationToolClass))
+#define GIMP_IS_UNIFIED_TRANSFORMATION_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_UNIFIED_TRANSFORMATION_TOOL))
+#define GIMP_IS_UNIFIED_TRANSFORMATION_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_UNIFIED_TRANSFORMATION_TOOL))
+#define GIMP_UNIFIED_TRANSFORMATION_TOOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_UNIFIED_TRANSFORMATION_TOOL, GimpUnifiedTransformationToolClass))
+
+
+typedef struct _GimpUnifiedTransformationTool GimpUnifiedTransformationTool;
+typedef struct _GimpUnifiedTransformationToolClass GimpUnifiedTransformationToolClass;
+
+struct _GimpUnifiedTransformationTool
+{
+ GimpTransformTool parent_instance;
+
+ GtkWidget *label[3][3];
+};
+
+struct _GimpUnifiedTransformationToolClass
+{
+ GimpTransformToolClass parent_class;
+};
+
+
+void gimp_unified_transformation_tool_register (GimpToolRegisterCallback callback,
+ gpointer data);
+
+GType gimp_unified_transformation_tool_get_type (void) G_GNUC_CONST;
+
+
+#endif /* __GIMP_UNIFIED_TRANSFORMATION_TOOL_H__ */
diff --git a/app/widgets/gimphelp-ids.h b/app/widgets/gimphelp-ids.h
index 92d722d..26ad596 100644
--- a/app/widgets/gimphelp-ids.h
+++ b/app/widgets/gimphelp-ids.h
@@ -285,6 +285,7 @@
#define GIMP_HELP_TOOL_SMUDGE "gimp-tool-smudge"
#define GIMP_HELP_TOOL_TEXT "gimp-tool-text"
#define GIMP_HELP_TOOL_THRESHOLD "gimp-tool-threshold"
+#define GIMP_HELP_TOOL_UNIFIED_TRANSFORMATION "gimp-tool-unified-transformation"
#define GIMP_HELP_TOOL_VECTORS "gimp-tool-vectors"
#define GIMP_HELP_TOOL_ZOOM "gimp-tool-zoom"
diff --git a/app/widgets/widgets-enums.h b/app/widgets/widgets-enums.h
index ae8f5ae..c3935a0 100644
--- a/app/widgets/widgets-enums.h
+++ b/app/widgets/widgets-enums.h
@@ -221,6 +221,7 @@ typedef enum /*< skip >*/
GIMP_TOOL_CURSOR_ROTATE,
GIMP_TOOL_CURSOR_SHEAR,
GIMP_TOOL_CURSOR_PERSPECTIVE,
+ GIMP_TOOL_CURSOR_UNIFIED_TRANSFORMATION,
GIMP_TOOL_CURSOR_FLIP_HORIZONTAL,
GIMP_TOOL_CURSOR_FLIP_VERTICAL,
GIMP_TOOL_CURSOR_TEXT,
diff --git a/libgimpwidgets/gimpstock.c b/libgimpwidgets/gimpstock.c
index 4e6b5ab..c3aa848 100644
--- a/libgimpwidgets/gimpstock.c
+++ b/libgimpwidgets/gimpstock.c
@@ -342,6 +342,7 @@ static const GtkStockItem gimp_stock_items[] =
{ GIMP_STOCK_TOOL_SMUDGE, NULL, 0, 0, LIBGIMP_DOMAIN },
{ GIMP_STOCK_TOOL_TEXT, NULL, 0, 0, LIBGIMP_DOMAIN },
{ GIMP_STOCK_TOOL_THRESHOLD, NULL, 0, 0, LIBGIMP_DOMAIN },
+ { GIMP_STOCK_TOOL_UNIFIED_TRANSFORMATION, N_("_Transform"), 0, 0, LIBGIMP_DOMAIN },
{ GIMP_STOCK_TOOL_ZOOM, NULL, 0, 0, LIBGIMP_DOMAIN }
};
@@ -497,6 +498,7 @@ gimp_stock_button_pixbufs[] =
{ GIMP_STOCK_TOOL_SMUDGE, stock_tool_smudge_22 },
{ GIMP_STOCK_TOOL_TEXT, stock_tool_text_22 },
{ GIMP_STOCK_TOOL_THRESHOLD, stock_tool_threshold_22 },
+ { GIMP_STOCK_TOOL_UNIFIED_TRANSFORMATION, stock_tool_unified_transformation_22 },
{ GIMP_STOCK_TOOL_ZOOM, stock_tool_zoom_22 },
{ GIMP_STOCK_INFO, stock_info_24 },
@@ -664,6 +666,7 @@ gimp_stock_menu_pixbufs[] =
{ GIMP_STOCK_TOOL_SMUDGE, stock_tool_smudge_16 },
{ GIMP_STOCK_TOOL_TEXT, stock_tool_text_16 },
{ GIMP_STOCK_TOOL_THRESHOLD, stock_tool_threshold_16 },
+ { GIMP_STOCK_TOOL_UNIFIED_TRANSFORMATION, stock_tool_unified_transformation_16 },
{ GIMP_STOCK_TOOL_ZOOM, stock_tool_zoom_16 },
{ GIMP_STOCK_INFO, stock_info_16 },
diff --git a/libgimpwidgets/gimpstock.h b/libgimpwidgets/gimpstock.h
index cdb4423..b471d1d 100644
--- a/libgimpwidgets/gimpstock.h
+++ b/libgimpwidgets/gimpstock.h
@@ -142,6 +142,7 @@ G_BEGIN_DECLS
#define GIMP_STOCK_TOOL_SMUDGE "gimp-tool-smudge"
#define GIMP_STOCK_TOOL_TEXT "gimp-tool-text"
#define GIMP_STOCK_TOOL_THRESHOLD "gimp-tool-threshold"
+#define GIMP_STOCK_TOOL_UNIFIED_TRANSFORMATION "gimp-tool-unified-transformation"
#define GIMP_STOCK_TOOL_ZOOM "gimp-tool-zoom"
diff --git a/themes/Default/images/Makefile.am b/themes/Default/images/Makefile.am
index bf854d2..2cd5b84 100644
--- a/themes/Default/images/Makefile.am
+++ b/themes/Default/images/Makefile.am
@@ -347,6 +347,8 @@ STOCK_TOOL_IMAGES = \
tools/stock-tool-text-22.png \
tools/stock-tool-threshold-16.png \
tools/stock-tool-threshold-22.png \
+ tools/stock-tool-unified-transformation-16.png \
+ tools/stock-tool-unified-transformation-22.png \
tools/stock-tool-zoom-16.png \
tools/stock-tool-zoom-22.png
diff --git a/themes/Default/images/tools/stock-tool-unified-transformation-16.png b/themes/Default/images/tools/stock-tool-unified-transformation-16.png
new file mode 100644
index 0000000..9aa1f7e
Binary files /dev/null and b/themes/Default/images/tools/stock-tool-unified-transformation-16.png differ
diff --git a/themes/Default/images/tools/stock-tool-unified-transformation-22.png b/themes/Default/images/tools/stock-tool-unified-transformation-22.png
new file mode 100644
index 0000000..ef3430d
Binary files /dev/null and b/themes/Default/images/tools/stock-tool-unified-transformation-22.png differ
diff --git a/themes/Default/images/tools/stock-tool-unified-transformation-22.xcf b/themes/Default/images/tools/stock-tool-unified-transformation-22.xcf
new file mode 100644
index 0000000..e7101bb
Binary files /dev/null and b/themes/Default/images/tools/stock-tool-unified-transformation-22.xcf differ
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]