47
49
#include "vectors/gimpstroke.h"
49
51
#include "widgets/gimpdialogfactory.h"
50
#include "widgets/gimpviewabledialog.h"
52
#include "widgets/gimptooldialog.h"
52
54
#include "display/gimpdisplay.h"
53
55
#include "display/gimpdisplayshell.h"
54
56
#include "display/gimpdisplayshell-appearance.h"
55
57
#include "display/gimpdisplayshell-transform.h"
58
#warning FIXME #include "dialogs/dialogs-types.h"
60
#include "dialogs/dialogs-types.h"
61
#include "dialogs/info-dialog.h"
63
59
#include "gimptoolcontrol.h"
64
60
#include "gimptransformoptions.h"
65
61
#include "gimptransformtool.h"
66
#include "gimptransformtool-undo.h"
62
#include "gimptransformtoolundo.h"
68
64
#include "gimp-intl.h"
71
#define HANDLE_SIZE 10
67
#define HANDLE_SIZE 25
68
#define MIN_HANDLE_SIZE 6
74
71
/* local function prototypes */
76
static void gimp_transform_tool_init (GimpTransformTool *tool);
77
static void gimp_transform_tool_class_init (GimpTransformToolClass *tool);
79
static GObject * gimp_transform_tool_constructor (GType type,
81
GObjectConstructParam *params);
82
static void gimp_transform_tool_finalize (GObject *object);
84
static gboolean gimp_transform_tool_initialize (GimpTool *tool,
86
static void gimp_transform_tool_control (GimpTool *tool,
87
GimpToolAction action,
89
static void gimp_transform_tool_button_press (GimpTool *tool,
92
GdkModifierType state,
94
static void gimp_transform_tool_button_release (GimpTool *tool,
97
GdkModifierType state,
99
static void gimp_transform_tool_motion (GimpTool *tool,
102
GdkModifierType state,
104
static gboolean gimp_transform_tool_key_press (GimpTool *tool,
107
static void gimp_transform_tool_modifier_key (GimpTool *tool,
110
GdkModifierType state,
112
static void gimp_transform_tool_oper_update (GimpTool *tool,
114
GdkModifierType state,
116
static void gimp_transform_tool_cursor_update (GimpTool *tool,
118
GdkModifierType state,
121
static void gimp_transform_tool_draw (GimpDrawTool *draw_tool);
73
static GObject * gimp_transform_tool_constructor (GType type,
75
GObjectConstructParam *params);
76
static void gimp_transform_tool_finalize (GObject *object);
78
static gboolean gimp_transform_tool_initialize (GimpTool *tool,
81
static void gimp_transform_tool_control (GimpTool *tool,
82
GimpToolAction action,
83
GimpDisplay *display);
84
static void gimp_transform_tool_button_press (GimpTool *tool,
87
GdkModifierType state,
88
GimpDisplay *display);
89
static void gimp_transform_tool_button_release (GimpTool *tool,
92
GdkModifierType state,
93
GimpButtonReleaseType release_type,
94
GimpDisplay *display);
95
static void gimp_transform_tool_motion (GimpTool *tool,
98
GdkModifierType state,
99
GimpDisplay *display);
100
static gboolean gimp_transform_tool_key_press (GimpTool *tool,
102
GimpDisplay *display);
103
static void gimp_transform_tool_modifier_key (GimpTool *tool,
106
GdkModifierType state,
107
GimpDisplay *display);
108
static void gimp_transform_tool_oper_update (GimpTool *tool,
110
GdkModifierType state,
112
GimpDisplay *display);
113
static void gimp_transform_tool_cursor_update (GimpTool *tool,
115
GdkModifierType state,
116
GimpDisplay *display);
118
static void gimp_transform_tool_draw (GimpDrawTool *draw_tool);
120
static void gimp_transform_tool_dialog_update (GimpTransformTool *tr_tool);
123
122
static TileManager *
124
gimp_transform_tool_real_transform (GimpTransformTool *tr_tool,
129
static void gimp_transform_tool_halt (GimpTransformTool *tr_tool);
130
static void gimp_transform_tool_bounds (GimpTransformTool *tr_tool,
132
static void gimp_transform_tool_dialog (GimpTransformTool *tr_tool);
133
static void gimp_transform_tool_prepare (GimpTransformTool *tr_tool,
135
static void gimp_transform_tool_doit (GimpTransformTool *tr_tool,
137
static void gimp_transform_tool_transform_bounding_box (GimpTransformTool *tr_tool);
138
static void gimp_transform_tool_grid_recalc (GimpTransformTool *tr_tool);
140
static void gimp_transform_tool_force_expose_preview (GimpTransformTool *tr_tool);
142
static void gimp_transform_tool_response (GtkWidget *widget,
144
GimpTransformTool *tr_tool);
146
static void gimp_transform_tool_notify_type (GimpTransformOptions *options,
148
GimpTransformTool *tr_tool);
149
static void gimp_transform_tool_notify_preview (GimpTransformOptions *options,
151
GimpTransformTool *tr_tool);
153
static GimpDrawToolClass *parent_class = NULL;
157
gimp_transform_tool_get_type (void)
159
static GType tool_type = 0;
163
static const GTypeInfo tool_info =
165
sizeof (GimpTransformToolClass),
166
(GBaseInitFunc) NULL,
167
(GBaseFinalizeFunc) NULL,
168
(GClassInitFunc) gimp_transform_tool_class_init,
169
NULL, /* class_finalize */
170
NULL, /* class_data */
171
sizeof (GimpTransformTool),
173
(GInstanceInitFunc) gimp_transform_tool_init,
176
tool_type = g_type_register_static (GIMP_TYPE_DRAW_TOOL,
123
gimp_transform_tool_real_transform (GimpTransformTool *tr_tool,
126
GimpDisplay *display);
128
static void gimp_transform_tool_halt (GimpTransformTool *tr_tool);
129
static void gimp_transform_tool_bounds (GimpTransformTool *tr_tool,
130
GimpDisplay *display);
131
static void gimp_transform_tool_dialog (GimpTransformTool *tr_tool);
132
static void gimp_transform_tool_prepare (GimpTransformTool *tr_tool,
133
GimpDisplay *display);
134
static void gimp_transform_tool_doit (GimpTransformTool *tr_tool,
135
GimpDisplay *display);
136
static void gimp_transform_tool_transform_bounding_box (GimpTransformTool *tr_tool);
137
static void gimp_transform_tool_grid_recalc (GimpTransformTool *tr_tool);
139
static void gimp_transform_tool_handles_recalc (GimpTransformTool *tr_tool,
140
GimpDisplay *display);
141
static void gimp_transform_tool_force_expose_preview (GimpTransformTool *tr_tool);
143
static void gimp_transform_tool_response (GtkWidget *widget,
145
GimpTransformTool *tr_tool);
147
static void gimp_transform_tool_notify_type (GimpTransformOptions *options,
149
GimpTransformTool *tr_tool);
150
static void gimp_transform_tool_notify_preview (GimpTransformOptions *options,
152
GimpTransformTool *tr_tool);
155
G_DEFINE_TYPE (GimpTransformTool, gimp_transform_tool, GIMP_TYPE_DRAW_TOOL)
157
#define parent_class gimp_transform_tool_parent_class
185
161
gimp_transform_tool_class_init (GimpTransformToolClass *klass)
260
242
GObjectConstructParam *params)
264
GimpTransformTool *tr_tool;
246
GimpTransformTool *tr_tool;
247
GimpTransformOptions *options;
266
249
object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
268
251
tool = GIMP_TOOL (object);
269
252
tr_tool = GIMP_TRANSFORM_TOOL (object);
271
g_assert (GIMP_IS_TOOL_INFO (tool->tool_info));
253
options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tool);
273
255
if (tr_tool->use_grid)
276
GIMP_TRANSFORM_OPTIONS (tool->tool_info->tool_options)->type;
278
GIMP_TRANSFORM_OPTIONS (tool->tool_info->tool_options)->direction;
280
g_signal_connect_object (tool->tool_info->tool_options,
282
G_CALLBACK (gimp_transform_tool_notify_type),
284
g_signal_connect_object (tool->tool_info->tool_options,
286
G_CALLBACK (gimp_transform_tool_notify_preview),
288
g_signal_connect_object (tool->tool_info->tool_options,
290
G_CALLBACK (gimp_transform_tool_notify_type),
292
g_signal_connect_object (tool->tool_info->tool_options,
294
G_CALLBACK (gimp_transform_tool_notify_preview),
296
g_signal_connect_object (tool->tool_info->tool_options,
297
"notify::preview-type",
298
G_CALLBACK (gimp_transform_tool_notify_preview),
300
g_signal_connect_object (tool->tool_info->tool_options,
302
G_CALLBACK (gimp_transform_tool_notify_preview),
304
g_signal_connect_object (tool->tool_info->tool_options,
257
tr_tool->type = options->type;
258
tr_tool->direction = options->direction;
260
g_signal_connect_object (options, "notify::type",
261
G_CALLBACK (gimp_transform_tool_notify_type),
263
g_signal_connect_object (options, "notify::type",
264
G_CALLBACK (gimp_transform_tool_notify_preview),
267
g_signal_connect_object (options, "notify::direction",
268
G_CALLBACK (gimp_transform_tool_notify_type),
270
g_signal_connect_object (options, "notify::direction",
271
G_CALLBACK (gimp_transform_tool_notify_preview),
274
g_signal_connect_object (options, "notify::preview-type",
275
G_CALLBACK (gimp_transform_tool_notify_preview),
277
g_signal_connect_object (options, "notify::grid-type",
278
G_CALLBACK (gimp_transform_tool_notify_preview),
280
g_signal_connect_object (options, "notify::grid-size",
306
281
G_CALLBACK (gimp_transform_tool_notify_preview),
285
g_signal_connect_object (options, "notify::constrain",
286
G_CALLBACK (gimp_transform_tool_dialog_update),
287
tr_tool, G_CONNECT_SWAPPED);
553
529
GdkModifierType key,
555
531
GdkModifierType state,
532
GimpDisplay *display)
558
GimpTransformOptions *options;
560
options = GIMP_TRANSFORM_OPTIONS (tool->tool_info->tool_options);
534
GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tool);
562
536
if (key == GDK_CONTROL_MASK)
564
g_object_set (options,
565
"constrain-1", ! options->constrain_1,
568
else if (key == GDK_MOD1_MASK)
570
g_object_set (options,
571
"constrain-2", ! options->constrain_2,
537
g_object_set (options,
538
"constrain", ! options->constrain,
577
543
gimp_transform_tool_oper_update (GimpTool *tool,
578
544
GimpCoords *coords,
579
545
GdkModifierType state,
547
GimpDisplay *display)
582
549
GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool);
583
550
GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);
585
if (! tr_tool->use_grid)
552
tr_tool->function = TRANSFORM_HANDLE_NONE;
554
if (display != tool->display)
588
if (gdisp == tool->gdisp)
557
if (tr_tool->use_handles)
590
559
gdouble closest_dist;
593
closest_dist = gimp_draw_tool_calc_distance (draw_tool, gdisp,
594
coords->x, coords->y,
595
tr_tool->tx1, tr_tool->ty1);
596
tr_tool->function = TRANSFORM_HANDLE_1;
598
dist = gimp_draw_tool_calc_distance (draw_tool, gdisp,
599
coords->x, coords->y,
600
tr_tool->tx2, tr_tool->ty2);
601
if (dist < closest_dist)
604
tr_tool->function = TRANSFORM_HANDLE_2;
607
dist = gimp_draw_tool_calc_distance (draw_tool, gdisp,
608
coords->x, coords->y,
609
tr_tool->tx3, tr_tool->ty3);
610
if (dist < closest_dist)
613
tr_tool->function = TRANSFORM_HANDLE_3;
616
dist = gimp_draw_tool_calc_distance (draw_tool, gdisp,
617
coords->x, coords->y,
618
tr_tool->tx4, tr_tool->ty4);
619
if (dist < closest_dist)
622
tr_tool->function = TRANSFORM_HANDLE_4;
625
if (gimp_draw_tool_on_handle (draw_tool, gdisp,
626
coords->x, coords->y,
628
tr_tool->tcx, tr_tool->tcy,
629
HANDLE_SIZE, HANDLE_SIZE,
633
tr_tool->function = TRANSFORM_HANDLE_CENTER;
562
dist = gimp_draw_tool_calc_distance_square (draw_tool, display,
563
coords->x, coords->y,
564
tr_tool->tx1, tr_tool->ty1);
566
tr_tool->function = TRANSFORM_HANDLE_NW;
568
dist = gimp_draw_tool_calc_distance_square (draw_tool, display,
569
coords->x, coords->y,
570
tr_tool->tx2, tr_tool->ty2);
571
if (dist < closest_dist)
574
tr_tool->function = TRANSFORM_HANDLE_NE;
577
dist = gimp_draw_tool_calc_distance_square (draw_tool, display,
578
coords->x, coords->y,
579
tr_tool->tx3, tr_tool->ty3);
580
if (dist < closest_dist)
583
tr_tool->function = TRANSFORM_HANDLE_SW;
586
dist = gimp_draw_tool_calc_distance_square (draw_tool, display,
587
coords->x, coords->y,
588
tr_tool->tx4, tr_tool->ty4);
589
if (dist < closest_dist)
592
tr_tool->function = TRANSFORM_HANDLE_SE;
595
if (tr_tool->use_mid_handles)
599
x = (tr_tool->tx1 + tr_tool->tx2) / 2.0;
600
y = (tr_tool->ty1 + tr_tool->ty2) / 2.0;
602
if (gimp_draw_tool_on_handle (draw_tool, display,
603
coords->x, coords->y,
606
tr_tool->handle_w, tr_tool->handle_h,
610
tr_tool->function = TRANSFORM_HANDLE_N;
613
x = (tr_tool->tx2 + tr_tool->tx4) / 2.0;
614
y = (tr_tool->ty2 + tr_tool->ty4) / 2.0;
616
if (gimp_draw_tool_on_handle (draw_tool, display,
617
coords->x, coords->y,
620
tr_tool->handle_w, tr_tool->handle_h,
624
tr_tool->function = TRANSFORM_HANDLE_E;
627
x = (tr_tool->tx3 + tr_tool->tx4) / 2.0;
628
y = (tr_tool->ty3 + tr_tool->ty4) / 2.0;
630
if (gimp_draw_tool_on_handle (draw_tool, display,
631
coords->x, coords->y,
634
tr_tool->handle_w, tr_tool->handle_h,
638
tr_tool->function = TRANSFORM_HANDLE_S;
641
x = (tr_tool->tx3 + tr_tool->tx1) / 2.0;
642
y = (tr_tool->ty3 + tr_tool->ty1) / 2.0;
644
if (gimp_draw_tool_on_handle (draw_tool, display,
645
coords->x, coords->y,
648
tr_tool->handle_w, tr_tool->handle_h,
652
tr_tool->function = TRANSFORM_HANDLE_W;
657
if (tr_tool->use_center &&
658
gimp_draw_tool_on_handle (draw_tool, display,
659
coords->x, coords->y,
661
tr_tool->tcx, tr_tool->tcy,
662
MIN (tr_tool->handle_w, tr_tool->handle_h),
663
MIN (tr_tool->handle_w, tr_tool->handle_h),
667
tr_tool->function = TRANSFORM_HANDLE_CENTER;
639
672
gimp_transform_tool_cursor_update (GimpTool *tool,
640
673
GimpCoords *coords,
641
674
GdkModifierType state,
675
GimpDisplay *display)
644
677
GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool);
645
GimpTransformOptions *options;
647
options = GIMP_TRANSFORM_OPTIONS (tool->tool_info->tool_options);
649
if (tr_tool->use_grid)
651
GimpChannel *selection = gimp_image_get_mask (gdisp->gimage);
652
GimpCursorType cursor = GDK_TOP_LEFT_ARROW;
653
GimpCursorModifier modifier = GIMP_CURSOR_MODIFIER_NONE;
655
switch (options->type)
657
case GIMP_TRANSFORM_TYPE_LAYER:
658
if (gimp_image_coords_in_active_drawable (gdisp->gimage, coords))
660
if (gimp_channel_is_empty (selection) ||
661
gimp_channel_value (selection, coords->x, coords->y))
663
cursor = GIMP_CURSOR_MOUSE;
668
case GIMP_TRANSFORM_TYPE_SELECTION:
669
if (gimp_channel_is_empty (selection) ||
670
gimp_channel_value (selection, coords->x, coords->y))
672
cursor = GIMP_CURSOR_MOUSE;
676
case GIMP_TRANSFORM_TYPE_PATH:
677
if (gimp_image_get_active_vectors (gdisp->gimage))
678
cursor = GIMP_CURSOR_MOUSE;
680
cursor = GIMP_CURSOR_BAD;
684
if (tr_tool->use_center && tr_tool->function == TRANSFORM_HANDLE_CENTER)
686
modifier = GIMP_CURSOR_MODIFIER_MOVE;
689
gimp_tool_control_set_cursor (tool->control, cursor);
690
gimp_tool_control_set_cursor_modifier (tool->control, modifier);
693
GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, gdisp);
678
GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tool);
679
GimpCursorType cursor;
680
GimpCursorModifier modifier = GIMP_CURSOR_MODIFIER_NONE;
682
cursor = gimp_tool_control_get_cursor (tool->control);
684
if (tr_tool->use_handles)
686
switch (tr_tool->function)
688
case TRANSFORM_HANDLE_NW:
689
cursor = GIMP_CURSOR_CORNER_TOP_LEFT;
692
case TRANSFORM_HANDLE_NE:
693
cursor = GIMP_CURSOR_CORNER_TOP_RIGHT;
696
case TRANSFORM_HANDLE_SW:
697
cursor = GIMP_CURSOR_CORNER_BOTTOM_LEFT;
700
case TRANSFORM_HANDLE_SE:
701
cursor = GIMP_CURSOR_CORNER_BOTTOM_RIGHT;
704
case TRANSFORM_HANDLE_N:
705
cursor = GIMP_CURSOR_SIDE_TOP;
708
case TRANSFORM_HANDLE_E:
709
cursor = GIMP_CURSOR_SIDE_RIGHT;
712
case TRANSFORM_HANDLE_S:
713
cursor = GIMP_CURSOR_SIDE_BOTTOM;
716
case TRANSFORM_HANDLE_W:
717
cursor = GIMP_CURSOR_SIDE_LEFT;
721
cursor = GIMP_CURSOR_CROSSHAIR_SMALL;
726
if (tr_tool->use_center && tr_tool->function == TRANSFORM_HANDLE_CENTER)
728
modifier = GIMP_CURSOR_MODIFIER_MOVE;
731
switch (options->type)
733
case GIMP_TRANSFORM_TYPE_LAYER:
734
case GIMP_TRANSFORM_TYPE_SELECTION:
737
case GIMP_TRANSFORM_TYPE_PATH:
738
if (! gimp_image_get_active_vectors (display->image))
739
modifier = GIMP_CURSOR_MODIFIER_BAD;
743
gimp_tool_control_set_cursor (tool->control, cursor);
744
gimp_tool_control_set_cursor_modifier (tool->control, modifier);
746
GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
697
750
gimp_transform_tool_draw (GimpDrawTool *draw_tool)
699
GimpTool *tool = GIMP_TOOL (draw_tool);
700
GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (draw_tool);
701
GimpTransformOptions *options;
702
gdouble z1, z2, z3, z4;
704
if (! tr_tool->use_grid)
707
options = GIMP_TRANSFORM_OPTIONS (tool->tool_info->tool_options);
709
/* draw the bounding box */
710
gimp_draw_tool_draw_line (draw_tool,
711
tr_tool->tx1, tr_tool->ty1,
712
tr_tool->tx2, tr_tool->ty2,
714
gimp_draw_tool_draw_line (draw_tool,
715
tr_tool->tx2, tr_tool->ty2,
716
tr_tool->tx4, tr_tool->ty4,
718
gimp_draw_tool_draw_line (draw_tool,
719
tr_tool->tx3, tr_tool->ty3,
720
tr_tool->tx4, tr_tool->ty4,
722
gimp_draw_tool_draw_line (draw_tool,
723
tr_tool->tx3, tr_tool->ty3,
724
tr_tool->tx1, tr_tool->ty1,
727
/* We test if the transformed polygon is convex.
728
* if z1 and z2 have the same sign as well as z3 and z4
729
* the polygon is convex.
731
z1 = ((tr_tool->tx2 - tr_tool->tx1) * (tr_tool->ty4 - tr_tool->ty1) -
732
(tr_tool->tx4 - tr_tool->tx1) * (tr_tool->ty2 - tr_tool->ty1));
733
z2 = ((tr_tool->tx4 - tr_tool->tx1) * (tr_tool->ty3 - tr_tool->ty1) -
734
(tr_tool->tx3 - tr_tool->tx1) * (tr_tool->ty4 - tr_tool->ty1));
735
z3 = ((tr_tool->tx4 - tr_tool->tx2) * (tr_tool->ty3 - tr_tool->ty2) -
736
(tr_tool->tx3 - tr_tool->tx2) * (tr_tool->ty4 - tr_tool->ty2));
737
z4 = ((tr_tool->tx3 - tr_tool->tx2) * (tr_tool->ty1 - tr_tool->ty2) -
738
(tr_tool->tx1 - tr_tool->tx2) * (tr_tool->ty3 - tr_tool->ty2));
740
/* Draw the grid (not for path transform since it looks ugly) */
742
if (tr_tool->type != GIMP_TRANSFORM_TYPE_PATH &&
743
tr_tool->grid_coords &&
744
tr_tool->tgrid_coords &&
750
k = tr_tool->ngx + tr_tool->ngy;
752
for (i = 0, gci = 0; i < k; i++, gci += 4)
754
gimp_draw_tool_draw_line (draw_tool,
755
tr_tool->tgrid_coords[gci],
756
tr_tool->tgrid_coords[gci + 1],
757
tr_tool->tgrid_coords[gci + 2],
758
tr_tool->tgrid_coords[gci + 3],
763
/* draw the tool handles */
764
gimp_draw_tool_draw_handle (draw_tool,
766
tr_tool->tx1, tr_tool->ty1,
767
HANDLE_SIZE, HANDLE_SIZE,
770
gimp_draw_tool_draw_handle (draw_tool,
772
tr_tool->tx2, tr_tool->ty2,
773
HANDLE_SIZE, HANDLE_SIZE,
776
gimp_draw_tool_draw_handle (draw_tool,
778
tr_tool->tx3, tr_tool->ty3,
779
HANDLE_SIZE, HANDLE_SIZE,
782
gimp_draw_tool_draw_handle (draw_tool,
784
tr_tool->tx4, tr_tool->ty4,
785
HANDLE_SIZE, HANDLE_SIZE,
752
GimpTool *tool = GIMP_TOOL (draw_tool);
753
GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (draw_tool);
754
gdouble z1, z2, z3, z4;
756
if (tr_tool->use_grid)
758
/* draw the bounding box */
759
gimp_draw_tool_draw_line (draw_tool,
760
tr_tool->tx1, tr_tool->ty1,
761
tr_tool->tx2, tr_tool->ty2,
763
gimp_draw_tool_draw_line (draw_tool,
764
tr_tool->tx2, tr_tool->ty2,
765
tr_tool->tx4, tr_tool->ty4,
767
gimp_draw_tool_draw_line (draw_tool,
768
tr_tool->tx3, tr_tool->ty3,
769
tr_tool->tx4, tr_tool->ty4,
771
gimp_draw_tool_draw_line (draw_tool,
772
tr_tool->tx3, tr_tool->ty3,
773
tr_tool->tx1, tr_tool->ty1,
776
/* We test if the transformed polygon is convex.
777
* if z1 and z2 have the same sign as well as z3 and z4
778
* the polygon is convex.
780
z1 = ((tr_tool->tx2 - tr_tool->tx1) * (tr_tool->ty4 - tr_tool->ty1) -
781
(tr_tool->tx4 - tr_tool->tx1) * (tr_tool->ty2 - tr_tool->ty1));
782
z2 = ((tr_tool->tx4 - tr_tool->tx1) * (tr_tool->ty3 - tr_tool->ty1) -
783
(tr_tool->tx3 - tr_tool->tx1) * (tr_tool->ty4 - tr_tool->ty1));
784
z3 = ((tr_tool->tx4 - tr_tool->tx2) * (tr_tool->ty3 - tr_tool->ty2) -
785
(tr_tool->tx3 - tr_tool->tx2) * (tr_tool->ty4 - tr_tool->ty2));
786
z4 = ((tr_tool->tx3 - tr_tool->tx2) * (tr_tool->ty1 - tr_tool->ty2) -
787
(tr_tool->tx1 - tr_tool->tx2) * (tr_tool->ty3 - tr_tool->ty2));
790
if (tr_tool->grid_coords &&
791
tr_tool->tgrid_coords &&
797
k = tr_tool->ngx + tr_tool->ngy;
799
for (i = 0, gci = 0; i < k; i++, gci += 4)
801
gimp_draw_tool_draw_line (draw_tool,
802
tr_tool->tgrid_coords[gci],
803
tr_tool->tgrid_coords[gci + 1],
804
tr_tool->tgrid_coords[gci + 2],
805
tr_tool->tgrid_coords[gci + 3],
811
gimp_transform_tool_handles_recalc (tr_tool, tool->display);
813
if (tr_tool->use_handles)
815
/* draw the tool handles */
816
gimp_draw_tool_draw_handle (draw_tool,
818
tr_tool->tx1, tr_tool->ty1,
819
tr_tool->handle_w, tr_tool->handle_h,
822
gimp_draw_tool_draw_handle (draw_tool,
824
tr_tool->tx2, tr_tool->ty2,
825
tr_tool->handle_w, tr_tool->handle_h,
828
gimp_draw_tool_draw_handle (draw_tool,
830
tr_tool->tx3, tr_tool->ty3,
831
tr_tool->handle_w, tr_tool->handle_h,
834
gimp_draw_tool_draw_handle (draw_tool,
836
tr_tool->tx4, tr_tool->ty4,
837
tr_tool->handle_w, tr_tool->handle_h,
841
if (tr_tool->use_mid_handles)
845
x = (tr_tool->tx1 + tr_tool->tx2) / 2.0;
846
y = (tr_tool->ty1 + tr_tool->ty2) / 2.0;
848
gimp_draw_tool_draw_handle (draw_tool,
851
tr_tool->handle_w, tr_tool->handle_h,
855
x = (tr_tool->tx2 + tr_tool->tx4) / 2.0;
856
y = (tr_tool->ty2 + tr_tool->ty4) / 2.0;
858
gimp_draw_tool_draw_handle (draw_tool,
861
tr_tool->handle_w, tr_tool->handle_h,
865
x = (tr_tool->tx3 + tr_tool->tx4) / 2.0;
866
y = (tr_tool->ty3 + tr_tool->ty4) / 2.0;
868
gimp_draw_tool_draw_handle (draw_tool,
871
tr_tool->handle_w, tr_tool->handle_h,
875
x = (tr_tool->tx3 + tr_tool->tx1) / 2.0;
876
y = (tr_tool->ty3 + tr_tool->ty1) / 2.0;
878
gimp_draw_tool_draw_handle (draw_tool,
881
tr_tool->handle_w, tr_tool->handle_h,
789
887
/* draw the center */
790
888
if (tr_tool->use_center)
792
gimp_draw_tool_draw_handle (draw_tool,
793
GIMP_HANDLE_FILLED_CIRCLE,
794
tr_tool->tcx, tr_tool->tcy,
795
HANDLE_SIZE, HANDLE_SIZE,
800
if (tr_tool->type == GIMP_TRANSFORM_TYPE_PATH)
890
gint d = MIN (tr_tool->handle_w, tr_tool->handle_h);
892
gimp_draw_tool_draw_handle (draw_tool,
894
tr_tool->tcx, tr_tool->tcy,
898
gimp_draw_tool_draw_handle (draw_tool,
900
tr_tool->tcx, tr_tool->tcy,
906
if (tr_tool->type == GIMP_TRANSFORM_TYPE_SELECTION)
908
GimpMatrix3 matrix = tr_tool->transform;
909
const BoundSeg *orig_in;
910
const BoundSeg *orig_out;
918
gimp_channel_boundary (gimp_image_get_mask (tool->display->image),
920
&num_segs_in, &num_segs_out,
923
segs_in = boundary_sort (orig_in, num_segs_in, &num_groups);
924
num_segs_in += num_groups;
926
segs_out = boundary_sort (orig_out, num_segs_out, &num_groups);
927
num_segs_out += num_groups;
931
for (i = 0; i < num_segs_in; i++)
935
if (segs_in[i].x1 != -1 &&
936
segs_in[i].y1 != -1 &&
937
segs_in[i].x2 != -1 &&
940
gimp_matrix3_transform_point (&matrix,
941
segs_in[i].x1, segs_in[i].y1,
943
segs_in[i].x1 = RINT (tx);
944
segs_in[i].y1 = RINT (ty);
946
gimp_matrix3_transform_point (&matrix,
947
segs_in[i].x2, segs_in[i].y2,
949
segs_in[i].x2 = RINT (tx);
950
segs_in[i].y2 = RINT (ty);
954
gimp_draw_tool_draw_boundary (draw_tool,
955
segs_in, num_segs_in,
963
for (i = 0; i < num_segs_out; i++)
967
if (segs_out[i].x1 != -1 &&
968
segs_out[i].y1 != -1 &&
969
segs_out[i].x2 != -1 &&
970
segs_out[i].y2 != -1)
972
gimp_matrix3_transform_point (&matrix,
973
segs_out[i].x1, segs_out[i].y1,
975
segs_out[i].x1 = RINT (tx);
976
segs_out[i].y1 = RINT (ty);
978
gimp_matrix3_transform_point (&matrix,
979
segs_out[i].x2, segs_out[i].y2,
981
segs_out[i].x2 = RINT (tx);
982
segs_out[i].y2 = RINT (ty);
986
gimp_draw_tool_draw_boundary (draw_tool,
987
segs_out, num_segs_out,
993
else if (tr_tool->type == GIMP_TRANSFORM_TYPE_PATH)
802
995
GimpVectors *vectors;
803
996
GimpStroke *stroke = NULL;
804
997
GimpMatrix3 matrix = tr_tool->transform;
806
vectors = gimp_image_get_active_vectors (tool->gdisp->gimage);
999
vectors = gimp_image_get_active_vectors (tool->display->image);
1617
gimp_transform_tool_handles_recalc (GimpTransformTool *tr_tool,
1618
GimpDisplay *display)
1627
gimp_display_shell_transform_xy (GIMP_DISPLAY_SHELL (display->shell),
1628
tr_tool->tx1, tr_tool->ty1,
1631
gimp_display_shell_transform_xy (GIMP_DISPLAY_SHELL (display->shell),
1632
tr_tool->tx2, tr_tool->ty2,
1635
gimp_display_shell_transform_xy (GIMP_DISPLAY_SHELL (display->shell),
1636
tr_tool->tx3, tr_tool->ty3,
1639
gimp_display_shell_transform_xy (GIMP_DISPLAY_SHELL (display->shell),
1640
tr_tool->tx4, tr_tool->ty4,
1644
x1 = MIN (MIN (dx1, dx2), MIN (dx3, dx4));
1645
y1 = MIN (MIN (dy1, dy2), MIN (dy3, dy4));
1646
x2 = MAX (MAX (dx1, dx2), MAX (dx3, dx4));
1647
y2 = MAX (MAX (dy1, dy2), MAX (dy3, dy4));
1649
tr_tool->handle_w = CLAMP ((x2 - x1) / 3, MIN_HANDLE_SIZE, HANDLE_SIZE);
1650
tr_tool->handle_h = CLAMP ((y2 - y1) / 3, MIN_HANDLE_SIZE, HANDLE_SIZE);
1413
1654
gimp_transform_tool_dialog (GimpTransformTool *tr_tool)
1415
GimpTool *tool = GIMP_TOOL (tr_tool);
1416
GimpToolInfo *tool_info;
1656
GimpTool *tool = GIMP_TOOL (tr_tool);
1657
GimpToolInfo *tool_info = tool->tool_info;
1417
1658
const gchar *stock_id;
1420
1660
if (! GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->dialog)
1423
tool_info = tool->tool_info;
1425
1663
stock_id = gimp_viewable_get_stock_id (GIMP_VIEWABLE (tool_info));
1427
tr_tool->info_dialog = info_dialog_new (NULL,
1665
tr_tool->dialog = gimp_tool_dialog_new (tool_info,
1666
NULL /* tool->display->shell */,
1428
1667
tool_info->blurb,
1429
GIMP_OBJECT (tool_info)->name,
1431
tr_tool->shell_desc,
1432
NULL /* tool->gdisp->shell */,
1433
gimp_standard_help_func,
1434
tool_info->help_id);
1436
gtk_dialog_add_buttons (GTK_DIALOG (tr_tool->info_dialog->shell),
1437
GIMP_STOCK_RESET, RESPONSE_RESET,
1438
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1439
stock_id, GTK_RESPONSE_OK,
1441
gtk_dialog_set_default_response (GTK_DIALOG (tr_tool->info_dialog->shell),
1668
GIMP_STOCK_RESET, RESPONSE_RESET,
1669
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1670
stock_id, GTK_RESPONSE_OK,
1672
gtk_dialog_set_default_response (GTK_DIALOG (tr_tool->dialog),
1442
1673
GTK_RESPONSE_OK);
1674
gtk_dialog_set_alternative_button_order (GTK_DIALOG (tr_tool->dialog),
1677
GTK_RESPONSE_CANCEL,
1444
g_signal_connect (tr_tool->info_dialog->shell, "response",
1680
g_signal_connect (tr_tool->dialog, "response",
1445
1681
G_CALLBACK (gimp_transform_tool_response),
1448
1684
GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->dialog (tr_tool);
1450
identifier = g_strconcat (GIMP_OBJECT (tool_info)->name, "-dialog", NULL);
1452
gimp_dialog_factory_add_foreign (gimp_dialog_factory_from_name ("toplevel"),
1454
tr_tool->info_dialog->shell);
1456
g_free (identifier);
1460
1688
gimp_transform_tool_prepare (GimpTransformTool *tr_tool,
1689
GimpDisplay *display)
1463
GimpTransformOptions *options;
1466
GIMP_TRANSFORM_OPTIONS (GIMP_TOOL (tr_tool)->tool_info->tool_options);
1691
GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
1468
1693
if ((options->preview_type == GIMP_TRANSFORM_PREVIEW_TYPE_IMAGE ||
1469
1694
options->preview_type == GIMP_TRANSFORM_PREVIEW_TYPE_IMAGE_GRID) &&
1470
1695
options->type == GIMP_TRANSFORM_TYPE_LAYER &&
1471
1696
options->direction == GIMP_TRANSFORM_FORWARD)
1472
gimp_display_shell_set_show_transform (GIMP_DISPLAY_SHELL (gdisp->shell),
1697
gimp_display_shell_set_show_transform (GIMP_DISPLAY_SHELL (display->shell),
1475
gimp_display_shell_set_show_transform (GIMP_DISPLAY_SHELL (gdisp->shell),
1700
gimp_display_shell_set_show_transform (GIMP_DISPLAY_SHELL (display->shell),
1478
if (tr_tool->info_dialog)
1703
if (tr_tool->dialog)
1480
gimp_viewable_dialog_set_viewable (GIMP_VIEWABLE_DIALOG (tr_tool->info_dialog->shell),
1481
GIMP_VIEWABLE (gimp_image_active_drawable (gdisp->gimage)));
1705
gimp_viewable_dialog_set_viewable (GIMP_VIEWABLE_DIALOG (tr_tool->dialog),
1706
GIMP_VIEWABLE (gimp_image_active_drawable (display->image)),
1707
GIMP_CONTEXT (options));
1483
gtk_widget_set_sensitive (GTK_WIDGET (tr_tool->info_dialog->shell), TRUE);
1709
gtk_widget_set_sensitive (tr_tool->dialog, TRUE);
1486
1712
if (GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->prepare)
1487
GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->prepare (tr_tool, gdisp);
1713
GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->prepare (tr_tool, display);
1491
1717
gimp_transform_tool_recalc (GimpTransformTool *tr_tool,
1718
GimpDisplay *display)
1720
g_return_if_fail (GIMP_IS_DISPLAY (display));
1494
1722
if (GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->recalc)
1495
GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->recalc (tr_tool, gdisp);
1723
GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->recalc (tr_tool, display);
1497
1725
gimp_transform_tool_transform_bounding_box (tr_tool);
1499
if (GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->dialog_update)
1500
GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->dialog_update (tr_tool);
1727
gimp_transform_tool_dialog_update (tr_tool);
1729
if (tr_tool->dialog)
1730
gtk_widget_show (tr_tool->dialog);