57
#define EPSILON 0.018 /* ~ 1 degree */
58
49
#define FIFTEEN_DEG (G_PI / 12.0)
61
54
/* local function prototypes */
63
static void gimp_rotate_tool_class_init (GimpRotateToolClass *klass);
64
static void gimp_rotate_tool_init (GimpRotateTool *rotate_tool);
66
56
static void gimp_rotate_tool_dialog (GimpTransformTool *tr_tool);
67
57
static void gimp_rotate_tool_dialog_update (GimpTransformTool *tr_tool);
68
58
static void gimp_rotate_tool_prepare (GimpTransformTool *tr_tool,
59
GimpDisplay *display);
70
60
static void gimp_rotate_tool_motion (GimpTransformTool *tr_tool,
61
GimpDisplay *display);
72
62
static void gimp_rotate_tool_recalc (GimpTransformTool *tr_tool,
63
GimpDisplay *display);
75
static void rotate_angle_changed (GtkWidget *entry,
65
static void rotate_angle_changed (GtkAdjustment *adj,
76
66
GimpTransformTool *tr_tool);
77
67
static void rotate_center_changed (GtkWidget *entry,
78
68
GimpTransformTool *tr_tool);
81
/* private variables */
83
static GimpTransformToolClass *parent_class = NULL;
86
/* public functions */
71
G_DEFINE_TYPE (GimpRotateTool, gimp_rotate_tool, GIMP_TYPE_TRANSFORM_TOOL)
73
#define parent_class gimp_rotate_tool_parent_class
89
77
gimp_rotate_tool_register (GimpToolRegisterCallback callback,
96
84
"gimp-rotate-tool",
98
_("Rotate the layer or selection"),
86
_("Rotate Tool: Rotate the layer, selection or path"),
99
87
N_("_Rotate"), "<shift>R",
100
88
NULL, GIMP_HELP_TOOL_ROTATE,
101
89
GIMP_STOCK_TOOL_ROTATE,
106
gimp_rotate_tool_get_type (void)
108
static GType tool_type = 0;
112
static const GTypeInfo tool_info =
114
sizeof (GimpRotateToolClass),
115
(GBaseInitFunc) NULL,
116
(GBaseFinalizeFunc) NULL,
117
(GClassInitFunc) gimp_rotate_tool_class_init,
118
NULL, /* class_finalize */
119
NULL, /* class_data */
120
sizeof (GimpRotateTool),
122
(GInstanceInitFunc) gimp_rotate_tool_init,
125
tool_type = g_type_register_static (GIMP_TYPE_TRANSFORM_TOOL,
134
/* private functions */
137
94
gimp_rotate_tool_class_init (GimpRotateToolClass *klass)
139
96
GimpTransformToolClass *trans_class = GIMP_TRANSFORM_TOOL_CLASS (klass);
141
parent_class = g_type_class_peek_parent (klass);
143
trans_class->dialog = gimp_rotate_tool_dialog;
144
trans_class->dialog_update = gimp_rotate_tool_dialog_update;
145
trans_class->prepare = gimp_rotate_tool_prepare;
146
trans_class->motion = gimp_rotate_tool_motion;
147
trans_class->recalc = gimp_rotate_tool_recalc;
98
trans_class->dialog = gimp_rotate_tool_dialog;
99
trans_class->dialog_update = gimp_rotate_tool_dialog_update;
100
trans_class->prepare = gimp_rotate_tool_prepare;
101
trans_class->motion = gimp_rotate_tool_motion;
102
trans_class->recalc = gimp_rotate_tool_recalc;
156
111
gimp_tool_control_set_tool_cursor (tool->control, GIMP_TOOL_CURSOR_ROTATE);
158
tr_tool->shell_desc = _("Rotation Information");
159
tr_tool->progress_text = _("Rotating...");
113
tr_tool->undo_desc = Q_("command|Rotate");
114
tr_tool->progress_text = _("Rotating");
116
tr_tool->use_grid = TRUE;
117
tr_tool->use_center = TRUE;
163
121
gimp_rotate_tool_dialog (GimpTransformTool *tr_tool)
165
123
GimpRotateTool *rotate = GIMP_ROTATE_TOOL (tr_tool);
167
GtkWidget *spinbutton2;
169
widget = info_dialog_add_spinbutton (tr_tool->info_dialog, _("Angle:"),
171
-180, 180, 1, 15, 1, 1, 2,
172
G_CALLBACK (rotate_angle_changed),
174
gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (widget), TRUE);
176
/* this looks strange (-180, 181), but it works */
177
widget = info_dialog_add_scale (tr_tool->info_dialog, "",
179
-180, 181, 0.01, 0.1, 1, -1,
180
G_CALLBACK (rotate_angle_changed),
182
gtk_widget_set_size_request (widget, 180, -1);
184
spinbutton2 = info_dialog_add_spinbutton (tr_tool->info_dialog,
187
-1, 1, 1, 10, 1, 1, 2,
189
rotate->sizeentry = info_dialog_add_sizeentry (tr_tool->info_dialog,
191
rotate->center_vals, 1,
192
GIMP_UNIT_PIXEL, "%a",
194
GIMP_SIZE_ENTRY_UPDATE_SIZE,
195
G_CALLBACK (rotate_center_changed),
129
table = gtk_table_new (4, 2, FALSE);
130
gtk_container_set_border_width (GTK_CONTAINER (table), 6);
131
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
132
gtk_table_set_col_spacings (GTK_TABLE (table), 6);
133
gtk_table_set_row_spacing (GTK_TABLE (table), 1, 6);
134
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (tr_tool->dialog)->vbox), table,
136
gtk_widget_show (table);
138
button = gimp_spin_button_new (&rotate->angle_adj,
139
0, -180, 180, 0.1, 15, 0, 2, 2);
140
gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (button), TRUE);
141
gtk_entry_set_width_chars (GTK_ENTRY (button), SB_WIDTH);
142
gimp_table_attach_aligned (GTK_TABLE (table), 0, 0, _("_Angle:"),
143
0.0, 0.5, button, 1, TRUE);
145
g_signal_connect (rotate->angle_adj, "value-changed",
146
G_CALLBACK (rotate_angle_changed),
149
scale = gtk_hscale_new (GTK_ADJUSTMENT (rotate->angle_adj));
150
gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE);
151
gtk_table_attach (GTK_TABLE (table), scale, 1, 2, 1, 2,
152
GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0);
153
gtk_widget_show (scale);
155
button = gimp_spin_button_new (&adj, 0, -1, 1, 1, 10, 1, 1, 2);
156
gtk_entry_set_width_chars (GTK_ENTRY (button), SB_WIDTH);
157
gimp_table_attach_aligned (GTK_TABLE (table), 0, 2, _("Center _X:"),
158
0.0, 0.5, button, 1, TRUE);
160
rotate->sizeentry = gimp_size_entry_new (1, GIMP_UNIT_PIXEL, "%a",
161
TRUE, TRUE, FALSE, SB_WIDTH,
162
GIMP_SIZE_ENTRY_UPDATE_SIZE);
198
163
gimp_size_entry_add_field (GIMP_SIZE_ENTRY (rotate->sizeentry),
199
GTK_SPIN_BUTTON (spinbutton2), NULL);
164
GTK_SPIN_BUTTON (button), NULL);
165
gimp_size_entry_set_pixel_digits (GIMP_SIZE_ENTRY (rotate->sizeentry), 2);
166
gimp_table_attach_aligned (GTK_TABLE (table), 0, 3, _("Center _Y:"),
167
0.0, 0.5, rotate->sizeentry, 1, TRUE);
201
gtk_table_set_row_spacing (GTK_TABLE (tr_tool->info_dialog->info_table),
203
gtk_table_set_row_spacing (GTK_TABLE (tr_tool->info_dialog->info_table),
169
g_signal_connect (rotate->sizeentry, "value-changed",
170
G_CALLBACK (rotate_center_changed),
210
177
GimpRotateTool *rotate = GIMP_ROTATE_TOOL (tr_tool);
212
rotate->angle_val = gimp_rad_to_deg (tr_tool->trans_info[ANGLE]);
213
rotate->center_vals[0] = tr_tool->trans_info[CENTER_X];
214
rotate->center_vals[1] = tr_tool->trans_info[CENTER_Y];
216
info_dialog_update (tr_tool->info_dialog);
217
info_dialog_show (tr_tool->info_dialog);
179
gtk_adjustment_set_value (GTK_ADJUSTMENT (rotate->angle_adj),
180
gimp_rad_to_deg (tr_tool->trans_info[ANGLE]));
182
g_signal_handlers_block_by_func (rotate->sizeentry,
183
rotate_center_changed,
186
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (rotate->sizeentry), 0,
187
tr_tool->trans_info[CENTER_X]);
188
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (rotate->sizeentry), 1,
189
tr_tool->trans_info[CENTER_Y]);
191
g_signal_handlers_unblock_by_func (rotate->sizeentry,
192
rotate_center_changed,
221
197
gimp_rotate_tool_prepare (GimpTransformTool *tr_tool,
198
GimpDisplay *display)
224
200
GimpRotateTool *rotate = GIMP_ROTATE_TOOL (tr_tool);
226
rotate->angle_val = 0.0;
227
rotate->center_vals[0] = tr_tool->cx;
228
rotate->center_vals[1] = tr_tool->cy;
202
tr_tool->trans_info[ANGLE] = 0.0;
203
tr_tool->trans_info[REAL_ANGLE] = 0.0;
204
tr_tool->trans_info[CENTER_X] = tr_tool->cx;
205
tr_tool->trans_info[CENTER_Y] = tr_tool->cy;
230
207
g_signal_handlers_block_by_func (rotate->sizeentry,
231
208
rotate_center_changed,
234
211
gimp_size_entry_set_unit (GIMP_SIZE_ENTRY (rotate->sizeentry),
235
GIMP_DISPLAY_SHELL (gdisp->shell)->unit);
212
GIMP_DISPLAY_SHELL (display->shell)->unit);
237
214
gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (rotate->sizeentry), 0,
238
gdisp->gimage->xresolution, FALSE);
215
display->image->xresolution, FALSE);
239
216
gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (rotate->sizeentry), 1,
240
gdisp->gimage->yresolution, FALSE);
217
display->image->yresolution, FALSE);
242
219
gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (rotate->sizeentry), 0,
244
65536 + gdisp->gimage->width);
221
65536 + display->image->width);
245
222
gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (rotate->sizeentry), 1,
247
65536 + gdisp->gimage->height);
224
65536 + display->image->height);
249
226
gimp_size_entry_set_size (GIMP_SIZE_ENTRY (rotate->sizeentry), 0,
250
227
tr_tool->x1, tr_tool->x2);
251
228
gimp_size_entry_set_size (GIMP_SIZE_ENTRY (rotate->sizeentry), 1,
252
229
tr_tool->y1, tr_tool->y2);
254
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (rotate->sizeentry), 0,
255
rotate->center_vals[0]);
256
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (rotate->sizeentry), 1,
257
rotate->center_vals[1]);
259
231
g_signal_handlers_unblock_by_func (rotate->sizeentry,
260
232
rotate_center_changed,
263
tr_tool->trans_info[ANGLE] = rotate->angle_val;
264
tr_tool->trans_info[REAL_ANGLE] = rotate->angle_val;
265
tr_tool->trans_info[CENTER_X] = rotate->center_vals[0];
266
tr_tool->trans_info[CENTER_Y] = rotate->center_vals[1];
270
237
gimp_rotate_tool_motion (GimpTransformTool *tr_tool,
238
GimpDisplay *display)
273
GimpTransformOptions *options;
240
GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
274
241
gdouble angle1, angle2, angle;
276
243
gdouble x1, y1, x2, y2;
310
274
/* increment the transform tool's angle */
311
275
tr_tool->trans_info[REAL_ANGLE] += angle;
313
/* limit the angle to between 0 and 360 degrees */
277
/* limit the angle to between -180 and 180 degrees */
314
278
if (tr_tool->trans_info[REAL_ANGLE] < - G_PI)
315
tr_tool->trans_info[REAL_ANGLE] =
316
2.0 * G_PI - tr_tool->trans_info[REAL_ANGLE];
280
tr_tool->trans_info[REAL_ANGLE] =
281
2.0 * G_PI + tr_tool->trans_info[REAL_ANGLE];
317
283
else if (tr_tool->trans_info[REAL_ANGLE] > G_PI)
318
tr_tool->trans_info[REAL_ANGLE] =
319
tr_tool->trans_info[REAL_ANGLE] - 2.0 * G_PI;
285
tr_tool->trans_info[REAL_ANGLE] =
286
tr_tool->trans_info[REAL_ANGLE] - 2.0 * G_PI;
321
289
/* constrain the angle to 15-degree multiples if ctrl is held down */
322
if (options->constrain_1)
290
if (options->constrain)
324
292
tr_tool->trans_info[ANGLE] =
325
293
FIFTEEN_DEG * (int) ((tr_tool->trans_info[REAL_ANGLE] +
294
FIFTEEN_DEG / 2.0) / FIFTEEN_DEG);