mirror of https://github.com/GNOME/gimp.git
app: in GimpTransformGridTool, allow linking forward/backward transforms
Add a GimpTransformGridTool::matrix_to_info() virtual function, which should extract the tool-specific transformation parameters given a transformation matrix, and the old parameter set (which is needed in some tools, to derive the parameters that aren't encoded in the matrix, such as the pivot point). The transformation matrix can be any combination of matrices calculated by the tool, and their inverses. Subclasses should only implement this function if every such matrix can be mapped back to transformation parameters. This is currently the case for all the transform-grid tools, except for the shear tool (since it only supports shearing along one of the horizontal or the vertical directions, however, the combined matrix may require shearing in both directions). When a transform-grid tool implements this function, show a chain- button between the two transform-direction radio-buttons in the tool options. When the chain-button is linked, whenever the transform corresponding to the active direction is modified, adjust the transform corresponding to the non-active direction such that the overall transform remains the same. One notable workflow that this enables is transforming a layer while adjusting a different area than its boundary, by first defining the area while the transform-directions are linked, and then transforming the area while the transform-directions are unlinked.
This commit is contained in:
parent
de8e81f81f
commit
39e23267f7
|
@ -83,6 +83,8 @@ static void gimp_handle_transform_tool_modifier_key (GimpTool
|
|||
GdkModifierType state,
|
||||
GimpDisplay *display);
|
||||
|
||||
static void gimp_handle_transform_tool_matrix_to_info (GimpTransformGridTool *tg_tool,
|
||||
const GimpMatrix3 *transform);
|
||||
static void gimp_handle_transform_tool_prepare (GimpTransformGridTool *tg_tool);
|
||||
static GimpToolWidget * gimp_handle_transform_tool_get_widget (GimpTransformGridTool *tg_tool);
|
||||
static void gimp_handle_transform_tool_update_widget (GimpTransformGridTool *tg_tool);
|
||||
|
@ -125,6 +127,7 @@ gimp_handle_transform_tool_class_init (GimpHandleTransformToolClass *klass)
|
|||
|
||||
tool_class->modifier_key = gimp_handle_transform_tool_modifier_key;
|
||||
|
||||
tg_class->matrix_to_info = gimp_handle_transform_tool_matrix_to_info;
|
||||
tg_class->prepare = gimp_handle_transform_tool_prepare;
|
||||
tg_class->get_widget = gimp_handle_transform_tool_get_widget;
|
||||
tg_class->update_widget = gimp_handle_transform_tool_update_widget;
|
||||
|
@ -196,6 +199,32 @@ gimp_handle_transform_tool_modifier_key (GimpTool *tool,
|
|||
state, display);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_handle_transform_tool_matrix_to_info (GimpTransformGridTool *tg_tool,
|
||||
const GimpMatrix3 *transform)
|
||||
{
|
||||
gimp_matrix3_transform_point (transform,
|
||||
tg_tool->trans_info[OX0],
|
||||
tg_tool->trans_info[OY0],
|
||||
&tg_tool->trans_info[X0],
|
||||
&tg_tool->trans_info[Y0]);
|
||||
gimp_matrix3_transform_point (transform,
|
||||
tg_tool->trans_info[OX1],
|
||||
tg_tool->trans_info[OY1],
|
||||
&tg_tool->trans_info[X1],
|
||||
&tg_tool->trans_info[Y1]);
|
||||
gimp_matrix3_transform_point (transform,
|
||||
tg_tool->trans_info[OX2],
|
||||
tg_tool->trans_info[OY2],
|
||||
&tg_tool->trans_info[X2],
|
||||
&tg_tool->trans_info[Y2]);
|
||||
gimp_matrix3_transform_point (transform,
|
||||
tg_tool->trans_info[OX3],
|
||||
tg_tool->trans_info[OY3],
|
||||
&tg_tool->trans_info[X3],
|
||||
&tg_tool->trans_info[Y3]);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_handle_transform_tool_prepare (GimpTransformGridTool *tg_tool)
|
||||
{
|
||||
|
|
|
@ -54,6 +54,8 @@ enum
|
|||
|
||||
/* local function prototypes */
|
||||
|
||||
static void gimp_perspective_tool_matrix_to_info (GimpTransformGridTool *tg_tool,
|
||||
const GimpMatrix3 *transform);
|
||||
static void gimp_perspective_tool_prepare (GimpTransformGridTool *tg_tool);
|
||||
static GimpToolWidget * gimp_perspective_tool_get_widget (GimpTransformGridTool *tg_tool);
|
||||
static void gimp_perspective_tool_update_widget (GimpTransformGridTool *tg_tool);
|
||||
|
@ -93,6 +95,7 @@ gimp_perspective_tool_class_init (GimpPerspectiveToolClass *klass)
|
|||
GimpTransformGridToolClass *tg_class = GIMP_TRANSFORM_GRID_TOOL_CLASS (klass);
|
||||
GimpGenericTransformToolClass *generic_class = GIMP_GENERIC_TRANSFORM_TOOL_CLASS (klass);
|
||||
|
||||
tg_class->matrix_to_info = gimp_perspective_tool_matrix_to_info;
|
||||
tg_class->prepare = gimp_perspective_tool_prepare;
|
||||
tg_class->get_widget = gimp_perspective_tool_get_widget;
|
||||
tg_class->update_widget = gimp_perspective_tool_update_widget;
|
||||
|
@ -113,6 +116,34 @@ gimp_perspective_tool_init (GimpPerspectiveTool *perspective_tool)
|
|||
GIMP_TOOL_CURSOR_PERSPECTIVE);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_perspective_tool_matrix_to_info (GimpTransformGridTool *tg_tool,
|
||||
const GimpMatrix3 *transform)
|
||||
{
|
||||
GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool);
|
||||
|
||||
gimp_matrix3_transform_point (transform,
|
||||
tr_tool->x1,
|
||||
tr_tool->y1,
|
||||
&tg_tool->trans_info[X0],
|
||||
&tg_tool->trans_info[Y0]);
|
||||
gimp_matrix3_transform_point (transform,
|
||||
tr_tool->x2,
|
||||
tr_tool->y1,
|
||||
&tg_tool->trans_info[X1],
|
||||
&tg_tool->trans_info[Y1]);
|
||||
gimp_matrix3_transform_point (transform,
|
||||
tr_tool->x1,
|
||||
tr_tool->y2,
|
||||
&tg_tool->trans_info[X2],
|
||||
&tg_tool->trans_info[Y2]);
|
||||
gimp_matrix3_transform_point (transform,
|
||||
tr_tool->x2,
|
||||
tr_tool->y2,
|
||||
&tg_tool->trans_info[X3],
|
||||
&tg_tool->trans_info[Y3]);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_perspective_tool_prepare (GimpTransformGridTool *tg_tool)
|
||||
{
|
||||
|
|
|
@ -53,6 +53,7 @@ enum
|
|||
|
||||
|
||||
#define SB_WIDTH 10
|
||||
#define EPSILON 1e-6
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
|
@ -63,6 +64,8 @@ static gboolean gimp_rotate_tool_key_press (GimpTool *
|
|||
|
||||
static gboolean gimp_rotate_tool_info_to_matrix (GimpTransformGridTool *tg_tool,
|
||||
GimpMatrix3 *transform);
|
||||
static void gimp_rotate_tool_matrix_to_info (GimpTransformGridTool *tg_tool,
|
||||
const GimpMatrix3 *transform);
|
||||
static gchar * gimp_rotate_tool_get_undo_desc (GimpTransformGridTool *tg_tool);
|
||||
static void gimp_rotate_tool_dialog (GimpTransformGridTool *tg_tool);
|
||||
static void gimp_rotate_tool_dialog_update (GimpTransformGridTool *tg_tool);
|
||||
|
@ -109,6 +112,7 @@ gimp_rotate_tool_class_init (GimpRotateToolClass *klass)
|
|||
tool_class->key_press = gimp_rotate_tool_key_press;
|
||||
|
||||
tg_class->info_to_matrix = gimp_rotate_tool_info_to_matrix;
|
||||
tg_class->matrix_to_info = gimp_rotate_tool_matrix_to_info;
|
||||
tg_class->get_undo_desc = gimp_rotate_tool_get_undo_desc;
|
||||
tg_class->dialog = gimp_rotate_tool_dialog;
|
||||
tg_class->dialog_update = gimp_rotate_tool_dialog_update;
|
||||
|
@ -181,6 +185,46 @@ gimp_rotate_tool_info_to_matrix (GimpTransformGridTool *tg_tool,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_rotate_tool_matrix_to_info (GimpTransformGridTool *tg_tool,
|
||||
const GimpMatrix3 *transform)
|
||||
{
|
||||
gdouble c;
|
||||
gdouble s;
|
||||
gdouble x;
|
||||
gdouble y;
|
||||
gdouble q;
|
||||
|
||||
c = transform->coeff[0][0];
|
||||
s = transform->coeff[1][0];
|
||||
x = transform->coeff[0][2];
|
||||
y = transform->coeff[1][2];
|
||||
|
||||
tg_tool->trans_info[ANGLE] = atan2 (s, c);
|
||||
|
||||
q = 2.0 * (1.0 - transform->coeff[0][0]);
|
||||
|
||||
if (q > EPSILON)
|
||||
{
|
||||
tg_tool->trans_info[PIVOT_X] = ((1.0 - c) * x - s * y) / q;
|
||||
tg_tool->trans_info[PIVOT_Y] = (s * x + (1.0 - c) * y) / q;
|
||||
}
|
||||
else
|
||||
{
|
||||
GimpMatrix3 transfer;
|
||||
|
||||
gimp_transform_grid_tool_info_to_matrix (tg_tool, &transfer);
|
||||
gimp_matrix3_invert (&transfer);
|
||||
gimp_matrix3_mult (transform, &transfer);
|
||||
|
||||
gimp_matrix3_transform_point (&transfer,
|
||||
tg_tool->trans_info[PIVOT_X],
|
||||
tg_tool->trans_info[PIVOT_Y],
|
||||
&tg_tool->trans_info[PIVOT_X],
|
||||
&tg_tool->trans_info[PIVOT_Y]);
|
||||
}
|
||||
}
|
||||
|
||||
static gchar *
|
||||
gimp_rotate_tool_get_undo_desc (GimpTransformGridTool *tg_tool)
|
||||
{
|
||||
|
|
|
@ -62,6 +62,8 @@ enum
|
|||
|
||||
static gboolean gimp_scale_tool_info_to_matrix (GimpTransformGridTool *tg_tool,
|
||||
GimpMatrix3 *transform);
|
||||
static void gimp_scale_tool_matrix_to_info (GimpTransformGridTool *tg_tool,
|
||||
const GimpMatrix3 *transform);
|
||||
static gchar * gimp_scale_tool_get_undo_desc (GimpTransformGridTool *tg_tool);
|
||||
static void gimp_scale_tool_dialog (GimpTransformGridTool *tg_tool);
|
||||
static void gimp_scale_tool_dialog_update (GimpTransformGridTool *tg_tool);
|
||||
|
@ -104,6 +106,7 @@ gimp_scale_tool_class_init (GimpScaleToolClass *klass)
|
|||
GimpTransformGridToolClass *tg_class = GIMP_TRANSFORM_GRID_TOOL_CLASS (klass);
|
||||
|
||||
tg_class->info_to_matrix = gimp_scale_tool_info_to_matrix;
|
||||
tg_class->matrix_to_info = gimp_scale_tool_matrix_to_info;
|
||||
tg_class->get_undo_desc = gimp_scale_tool_get_undo_desc;
|
||||
tg_class->dialog = gimp_scale_tool_dialog;
|
||||
tg_class->dialog_update = gimp_scale_tool_dialog_update;
|
||||
|
@ -145,6 +148,29 @@ gimp_scale_tool_info_to_matrix (GimpTransformGridTool *tg_tool,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_scale_tool_matrix_to_info (GimpTransformGridTool *tg_tool,
|
||||
const GimpMatrix3 *transform)
|
||||
{
|
||||
GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool);
|
||||
gdouble x;
|
||||
gdouble y;
|
||||
gdouble w;
|
||||
gdouble h;
|
||||
|
||||
x = transform->coeff[0][2];
|
||||
y = transform->coeff[1][2];
|
||||
w = transform->coeff[0][0];
|
||||
h = transform->coeff[1][1];
|
||||
|
||||
tg_tool->trans_info[X0] = x + w * tr_tool->x1;
|
||||
tg_tool->trans_info[Y0] = y + h * tr_tool->y1;
|
||||
tg_tool->trans_info[X1] = tg_tool->trans_info[X0] +
|
||||
w * (tr_tool->x2 - tr_tool->x1);
|
||||
tg_tool->trans_info[Y1] = tg_tool->trans_info[Y0] +
|
||||
h * (tr_tool->y2 - tr_tool->y1);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
gimp_scale_tool_get_undo_desc (GimpTransformGridTool *tg_tool)
|
||||
{
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "gimpunifiedtransformtool.h"
|
||||
#include "gimptooloptions-gui.h"
|
||||
#include "gimptransformgridoptions.h"
|
||||
#include "gimptransformgridtool.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
|
@ -45,6 +46,7 @@ enum
|
|||
{
|
||||
PROP_0,
|
||||
PROP_DIRECTION,
|
||||
PROP_DIRECTION_LINKED,
|
||||
PROP_SHOW_PREVIEW,
|
||||
PROP_PREVIEW_OPACITY,
|
||||
PROP_GRID_TYPE,
|
||||
|
@ -94,6 +96,12 @@ gimp_transform_grid_options_class_init (GimpTransformGridOptionsClass *klass)
|
|||
g_object_class_override_property (object_class, PROP_DIRECTION,
|
||||
"direction");
|
||||
|
||||
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_DIRECTION_LINKED,
|
||||
"direction-linked",
|
||||
NULL, NULL,
|
||||
FALSE,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_PREVIEW,
|
||||
"show-preview",
|
||||
_("Show image preview"),
|
||||
|
@ -212,6 +220,9 @@ gimp_transform_grid_options_set_property (GObject *object,
|
|||
transform_options->direction != GIMP_TRANSFORM_BACKWARD,
|
||||
NULL);
|
||||
break;
|
||||
case PROP_DIRECTION_LINKED:
|
||||
options->direction_linked = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_SHOW_PREVIEW:
|
||||
options->show_preview = g_value_get_boolean (value);
|
||||
break;
|
||||
|
@ -274,6 +285,9 @@ gimp_transform_grid_options_get_property (GObject *object,
|
|||
case PROP_DIRECTION:
|
||||
g_value_set_enum (value, transform_options->direction);
|
||||
break;
|
||||
case PROP_DIRECTION_LINKED:
|
||||
g_value_set_boolean (value, options->direction_linked);
|
||||
break;
|
||||
case PROP_SHOW_PREVIEW:
|
||||
g_value_set_boolean (value, options->show_preview);
|
||||
break;
|
||||
|
@ -333,17 +347,53 @@ gimp_transform_grid_options_get_property (GObject *object,
|
|||
GtkWidget *
|
||||
gimp_transform_grid_options_gui (GimpToolOptions *tool_options)
|
||||
{
|
||||
GObject *config = G_OBJECT (tool_options);
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *combo;
|
||||
GtkWidget *scale;
|
||||
GtkWidget *grid_box;
|
||||
GdkModifierType extend_mask = gimp_get_extend_selection_mask ();
|
||||
GdkModifierType constrain_mask = gimp_get_constrain_behavior_mask ();
|
||||
GObject *config = G_OBJECT (tool_options);
|
||||
GimpTransformGridToolClass *tg_class;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *combo;
|
||||
GtkWidget *scale;
|
||||
GtkWidget *grid_box;
|
||||
GdkModifierType extend_mask = gimp_get_extend_selection_mask ();
|
||||
GdkModifierType constrain_mask = gimp_get_constrain_behavior_mask ();
|
||||
|
||||
vbox = gimp_transform_options_gui (tool_options, TRUE, TRUE, TRUE);
|
||||
|
||||
tg_class = g_type_class_ref (tool_options->tool_info->tool_type);
|
||||
|
||||
/* the direction-link button */
|
||||
if (tg_class->matrix_to_info)
|
||||
{
|
||||
GimpTransformOptions *tr_options = GIMP_TRANSFORM_OPTIONS (tool_options);
|
||||
GtkWidget *vbox2;
|
||||
GtkWidget *hbox;
|
||||
GtkWidget *button;
|
||||
|
||||
vbox2 = gtk_bin_get_child (GTK_BIN (tr_options->direction_frame));
|
||||
g_object_ref (vbox2);
|
||||
gtk_container_remove (GTK_CONTAINER (tr_options->direction_frame), vbox2);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 1);
|
||||
gtk_container_add (GTK_CONTAINER (tr_options->direction_frame), hbox);
|
||||
gtk_widget_show (hbox);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 0);
|
||||
g_object_unref (vbox2);
|
||||
|
||||
button = gimp_chain_button_new (GIMP_CHAIN_RIGHT);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
|
||||
gimp_chain_button_set_icon_size (GIMP_CHAIN_BUTTON (button),
|
||||
GTK_ICON_SIZE_MENU);
|
||||
gtk_widget_show (button);
|
||||
|
||||
g_object_bind_property (config, "direction-linked",
|
||||
button, "active",
|
||||
G_BINDING_BIDIRECTIONAL |
|
||||
G_BINDING_SYNC_CREATE);
|
||||
}
|
||||
|
||||
g_type_class_unref (tg_class);
|
||||
|
||||
/* the preview frame */
|
||||
scale = gimp_prop_spin_scale_new (config, "preview-opacity", NULL,
|
||||
0.01, 0.1, 0);
|
||||
|
|
|
@ -37,6 +37,7 @@ struct _GimpTransformGridOptions
|
|||
{
|
||||
GimpTransformOptions parent_instance;
|
||||
|
||||
gboolean direction_linked;
|
||||
gboolean show_preview;
|
||||
gdouble preview_opacity;
|
||||
GimpGuidesType grid_type;
|
||||
|
|
|
@ -205,6 +205,7 @@ gimp_transform_grid_tool_class_init (GimpTransformGridToolClass *klass)
|
|||
tr_class->transform = gimp_transform_grid_tool_transform;
|
||||
|
||||
klass->info_to_matrix = NULL;
|
||||
klass->matrix_to_info = NULL;
|
||||
klass->get_undo_desc = gimp_transform_grid_tool_real_get_undo_desc;
|
||||
klass->dialog = NULL;
|
||||
klass->dialog_update = NULL;
|
||||
|
@ -753,32 +754,76 @@ gimp_transform_grid_tool_draw (GimpDrawTool *draw_tool)
|
|||
static void
|
||||
gimp_transform_grid_tool_recalc_matrix (GimpTransformTool *tr_tool)
|
||||
{
|
||||
GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (tr_tool);
|
||||
GimpTransformOptions *tr_options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
|
||||
GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (tr_tool);
|
||||
GimpTransformOptions *tr_options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
|
||||
GimpTransformGridOptions *tg_options = GIMP_TRANSFORM_GRID_TOOL_GET_OPTIONS (tr_tool);
|
||||
|
||||
if (GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->info_to_matrix)
|
||||
{
|
||||
GimpMatrix3 forward_transform;
|
||||
GimpMatrix3 backward_transform;
|
||||
|
||||
tr_tool->transform_valid = TRUE;
|
||||
gboolean forward_transform_valid;
|
||||
gboolean backward_transform_valid;
|
||||
|
||||
tg_tool->trans_info = tg_tool->trans_infos[GIMP_TRANSFORM_FORWARD];
|
||||
tr_tool->transform_valid = tr_tool->transform_valid &&
|
||||
gimp_transform_grid_tool_info_to_matrix (
|
||||
forward_transform_valid = gimp_transform_grid_tool_info_to_matrix (
|
||||
tg_tool, &forward_transform);
|
||||
|
||||
tg_tool->trans_info = tg_tool->trans_infos[GIMP_TRANSFORM_BACKWARD];
|
||||
tr_tool->transform_valid = tr_tool->transform_valid &&
|
||||
gimp_transform_grid_tool_info_to_matrix (
|
||||
backward_transform_valid = gimp_transform_grid_tool_info_to_matrix (
|
||||
tg_tool, &backward_transform);
|
||||
|
||||
if (tr_tool->transform_valid)
|
||||
if (GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->matrix_to_info &&
|
||||
tg_options->direction_linked)
|
||||
{
|
||||
GimpMatrix3 transform = tr_tool->transform;
|
||||
|
||||
switch (tr_options->direction)
|
||||
{
|
||||
case GIMP_TRANSFORM_FORWARD:
|
||||
if (forward_transform_valid)
|
||||
{
|
||||
gimp_matrix3_invert (&transform);
|
||||
|
||||
backward_transform = forward_transform;
|
||||
gimp_matrix3_mult (&transform, &backward_transform);
|
||||
|
||||
tg_tool->trans_info =
|
||||
tg_tool->trans_infos[GIMP_TRANSFORM_BACKWARD];
|
||||
gimp_transform_grid_tool_matrix_to_info (tg_tool,
|
||||
&backward_transform);
|
||||
backward_transform_valid =
|
||||
gimp_transform_grid_tool_info_to_matrix (
|
||||
tg_tool, &backward_transform);
|
||||
}
|
||||
break;
|
||||
|
||||
case GIMP_TRANSFORM_BACKWARD:
|
||||
if (backward_transform_valid)
|
||||
{
|
||||
forward_transform = backward_transform;
|
||||
gimp_matrix3_mult (&transform, &forward_transform);
|
||||
|
||||
tg_tool->trans_info =
|
||||
tg_tool->trans_infos[GIMP_TRANSFORM_FORWARD];
|
||||
gimp_transform_grid_tool_matrix_to_info (tg_tool,
|
||||
&forward_transform);
|
||||
forward_transform_valid =
|
||||
gimp_transform_grid_tool_info_to_matrix (
|
||||
tg_tool, &forward_transform);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (forward_transform_valid && backward_transform_valid)
|
||||
{
|
||||
tr_tool->transform = backward_transform;
|
||||
gimp_matrix3_invert (&tr_tool->transform);
|
||||
gimp_matrix3_mult (&forward_transform, &tr_tool->transform);
|
||||
}
|
||||
|
||||
tr_tool->transform_valid = forward_transform_valid &&
|
||||
backward_transform_valid;
|
||||
}
|
||||
|
||||
tg_tool->trans_info = tg_tool->trans_infos[tr_options->direction];
|
||||
|
@ -799,8 +844,19 @@ gimp_transform_grid_tool_get_undo_desc (GimpTransformTool *tr_tool)
|
|||
GimpTransformOptions *tr_options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
|
||||
gchar *result;
|
||||
|
||||
if (! memcmp (tg_tool->trans_infos[GIMP_TRANSFORM_BACKWARD],
|
||||
tg_tool->init_trans_info, sizeof (TransInfo)))
|
||||
if (GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->matrix_to_info)
|
||||
{
|
||||
TransInfo trans_info;
|
||||
|
||||
memcpy (&trans_info, &tg_tool->init_trans_info, sizeof (TransInfo));
|
||||
|
||||
tg_tool->trans_info = trans_info;
|
||||
gimp_transform_grid_tool_matrix_to_info (tg_tool, &tr_tool->transform);
|
||||
result = GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->get_undo_desc (
|
||||
tg_tool);
|
||||
}
|
||||
else if (! memcmp (tg_tool->trans_infos[GIMP_TRANSFORM_BACKWARD],
|
||||
tg_tool->init_trans_info, sizeof (TransInfo)))
|
||||
{
|
||||
tg_tool->trans_info = tg_tool->trans_infos[GIMP_TRANSFORM_FORWARD];
|
||||
result = GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->get_undo_desc (
|
||||
|
@ -1345,6 +1401,20 @@ gimp_transform_grid_tool_info_to_matrix (GimpTransformGridTool *tg_tool,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_transform_grid_tool_matrix_to_info (GimpTransformGridTool *tg_tool,
|
||||
const GimpMatrix3 *transform)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_TRANSFORM_GRID_TOOL (tg_tool));
|
||||
g_return_if_fail (transform != NULL);
|
||||
|
||||
if (GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->matrix_to_info)
|
||||
{
|
||||
return GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->matrix_to_info (
|
||||
tg_tool, transform);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gimp_transform_grid_tool_push_internal_undo (GimpTransformGridTool *tg_tool)
|
||||
{
|
||||
|
|
|
@ -76,6 +76,8 @@ struct _GimpTransformGridToolClass
|
|||
/* virtual functions */
|
||||
gboolean (* info_to_matrix) (GimpTransformGridTool *tg_tool,
|
||||
GimpMatrix3 *transform);
|
||||
void (* matrix_to_info) (GimpTransformGridTool *tg_tool,
|
||||
const GimpMatrix3 *transform);
|
||||
gchar * (* get_undo_desc) (GimpTransformGridTool *tg_tool);
|
||||
void (* dialog) (GimpTransformGridTool *tg_tool);
|
||||
void (* dialog_update) (GimpTransformGridTool *tg_tool);
|
||||
|
@ -100,6 +102,8 @@ GType gimp_transform_grid_tool_get_type (void) G_GNUC_CONST;
|
|||
|
||||
gboolean gimp_transform_grid_tool_info_to_matrix (GimpTransformGridTool *tg_tool,
|
||||
GimpMatrix3 *transform);
|
||||
void gimp_transform_grid_tool_matrix_to_info (GimpTransformGridTool *tg_tool,
|
||||
const GimpMatrix3 *transform);
|
||||
|
||||
void gimp_transform_grid_tool_push_internal_undo (GimpTransformGridTool *tg_tool);
|
||||
|
||||
|
|
|
@ -243,6 +243,8 @@ gimp_transform_options_gui (GimpToolOptions *tool_options,
|
|||
0, 0);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
|
||||
gtk_widget_show (frame);
|
||||
|
||||
options->direction_frame = frame;
|
||||
}
|
||||
|
||||
/* the interpolation menu */
|
||||
|
|
|
@ -44,6 +44,7 @@ struct _GimpTransformOptions
|
|||
|
||||
/* options gui */
|
||||
GtkWidget *type_box;
|
||||
GtkWidget *direction_frame;
|
||||
};
|
||||
|
||||
struct _GimpTransformOptionsClass
|
||||
|
|
|
@ -56,6 +56,8 @@ enum
|
|||
|
||||
/* local function prototypes */
|
||||
|
||||
static void gimp_unified_transform_tool_matrix_to_info (GimpTransformGridTool *tg_tool,
|
||||
const GimpMatrix3 *transform);
|
||||
static void gimp_unified_transform_tool_prepare (GimpTransformGridTool *tg_tool);
|
||||
static GimpToolWidget * gimp_unified_transform_tool_get_widget (GimpTransformGridTool *tg_tool);
|
||||
static void gimp_unified_transform_tool_update_widget (GimpTransformGridTool *tg_tool);
|
||||
|
@ -95,6 +97,7 @@ gimp_unified_transform_tool_class_init (GimpUnifiedTransformToolClass *klass)
|
|||
GimpTransformGridToolClass *tg_class = GIMP_TRANSFORM_GRID_TOOL_CLASS (klass);
|
||||
GimpGenericTransformToolClass *generic_class = GIMP_GENERIC_TRANSFORM_TOOL_CLASS (klass);
|
||||
|
||||
tg_class->matrix_to_info = gimp_unified_transform_tool_matrix_to_info;
|
||||
tg_class->prepare = gimp_unified_transform_tool_prepare;
|
||||
tg_class->get_widget = gimp_unified_transform_tool_get_widget;
|
||||
tg_class->update_widget = gimp_unified_transform_tool_update_widget;
|
||||
|
@ -111,6 +114,45 @@ gimp_unified_transform_tool_init (GimpUnifiedTransformTool *unified_tool)
|
|||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_unified_transform_tool_matrix_to_info (GimpTransformGridTool *tg_tool,
|
||||
const GimpMatrix3 *transform)
|
||||
{
|
||||
GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool);
|
||||
GimpMatrix3 transfer;
|
||||
|
||||
gimp_transform_grid_tool_info_to_matrix (tg_tool, &transfer);
|
||||
gimp_matrix3_invert (&transfer);
|
||||
gimp_matrix3_mult (transform, &transfer);
|
||||
|
||||
gimp_matrix3_transform_point (&transfer,
|
||||
tg_tool->trans_info[PIVOT_X],
|
||||
tg_tool->trans_info[PIVOT_Y],
|
||||
&tg_tool->trans_info[PIVOT_X],
|
||||
&tg_tool->trans_info[PIVOT_Y]);
|
||||
|
||||
gimp_matrix3_transform_point (transform,
|
||||
tr_tool->x1,
|
||||
tr_tool->y1,
|
||||
&tg_tool->trans_info[X0],
|
||||
&tg_tool->trans_info[Y0]);
|
||||
gimp_matrix3_transform_point (transform,
|
||||
tr_tool->x2,
|
||||
tr_tool->y1,
|
||||
&tg_tool->trans_info[X1],
|
||||
&tg_tool->trans_info[Y1]);
|
||||
gimp_matrix3_transform_point (transform,
|
||||
tr_tool->x1,
|
||||
tr_tool->y2,
|
||||
&tg_tool->trans_info[X2],
|
||||
&tg_tool->trans_info[Y2]);
|
||||
gimp_matrix3_transform_point (transform,
|
||||
tr_tool->x2,
|
||||
tr_tool->y2,
|
||||
&tg_tool->trans_info[X3],
|
||||
&tg_tool->trans_info[Y3]);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_unified_transform_tool_prepare (GimpTransformGridTool *tg_tool)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue