28
28
#include "core/gimpchannel.h"
29
29
#include "core/gimpimage.h"
30
#include "core/gimptoolinfo.h"
30
#include "core/gimppickable.h"
32
32
#include "display/gimpdisplay.h"
34
#include "widgets/gimpwidgets-utils.h"
34
36
#include "gimpeditselectiontool.h"
35
37
#include "gimpselectiontool.h"
36
38
#include "gimpselectionoptions.h"
37
39
#include "gimptoolcontrol.h"
41
#include "gimp-intl.h"
40
static void gimp_selection_tool_class_init (GimpSelectionToolClass *klass);
41
static void gimp_selection_tool_init (GimpSelectionTool *sel_tool);
43
44
static void gimp_selection_tool_modifier_key (GimpTool *tool,
44
45
GdkModifierType key,
46
47
GdkModifierType state,
48
GimpDisplay *display);
48
49
static void gimp_selection_tool_oper_update (GimpTool *tool,
49
50
GimpCoords *coords,
50
51
GdkModifierType state,
53
GimpDisplay *display);
52
54
static void gimp_selection_tool_cursor_update (GimpTool *tool,
53
55
GimpCoords *coords,
54
56
GdkModifierType state,
58
static GimpDrawToolClass *parent_class = NULL;
62
gimp_selection_tool_get_type (void)
64
static GType tool_type = 0;
68
static const GTypeInfo tool_info =
70
sizeof (GimpSelectionToolClass),
72
(GBaseFinalizeFunc) NULL,
73
(GClassInitFunc) gimp_selection_tool_class_init,
74
NULL, /* class_finalize */
75
NULL, /* class_data */
76
sizeof (GimpSelectionTool),
78
(GInstanceInitFunc) gimp_selection_tool_init,
81
tool_type = g_type_register_static (GIMP_TYPE_DRAW_TOOL,
57
GimpDisplay *display);
60
G_DEFINE_TYPE (GimpSelectionTool, gimp_selection_tool, GIMP_TYPE_DRAW_TOOL)
62
#define parent_class gimp_selection_tool_parent_class
90
66
gimp_selection_tool_class_init (GimpSelectionToolClass *klass)
92
68
GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass);
94
parent_class = g_type_class_peek_parent (klass);
96
70
tool_class->modifier_key = gimp_selection_tool_modifier_key;
97
71
tool_class->key_press = gimp_edit_selection_tool_key_press;
98
72
tool_class->oper_update = gimp_selection_tool_oper_update;
111
87
GdkModifierType key,
113
89
GdkModifierType state,
116
92
GimpSelectionTool *selection_tool = GIMP_SELECTION_TOOL (tool);
117
93
GimpSelectionOptions *options;
119
options = GIMP_SELECTION_OPTIONS (tool->tool_info->tool_options);
95
options = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);
121
if (key == GDK_SHIFT_MASK || key == GDK_CONTROL_MASK)
97
if (key == GDK_SHIFT_MASK ||
98
key == GDK_CONTROL_MASK ||
123
SelectOps button_op = options->operation;
101
GimpChannelOps button_op = options->operation;
127
if (key == (state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)))
105
if (key == (state & (GDK_SHIFT_MASK |
129
109
/* first modifier pressed */
131
selection_tool->saved_op = options->operation;
111
selection_tool->saved_operation = options->operation;
136
if (! (state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)))
116
if (! (state & (GDK_SHIFT_MASK |
138
120
/* last modifier released */
140
button_op = selection_tool->saved_op;
122
button_op = selection_tool->saved_operation;
144
if ((state & GDK_CONTROL_MASK) && (state & GDK_SHIFT_MASK))
146
button_op = SELECTION_INTERSECT;
126
if (state & GDK_MOD1_MASK)
128
/* if alt is down, pretend that neither
129
* shift nor control are down
131
button_op = selection_tool->saved_operation;
133
else if ((state & GDK_CONTROL_MASK) && (state & GDK_SHIFT_MASK))
135
button_op = GIMP_CHANNEL_OP_INTERSECT;
148
137
else if (state & GDK_SHIFT_MASK)
150
button_op = SELECTION_ADD;
139
button_op = GIMP_CHANNEL_OP_ADD;
152
141
else if (state & GDK_CONTROL_MASK)
154
button_op = SELECTION_SUBTRACT;
143
button_op = GIMP_CHANNEL_OP_SUBTRACT;
157
146
if (button_op != options->operation)
165
154
gimp_selection_tool_oper_update (GimpTool *tool,
166
155
GimpCoords *coords,
167
156
GdkModifierType state,
158
GimpDisplay *display)
170
160
GimpSelectionTool *selection_tool = GIMP_SELECTION_TOOL (tool);
171
161
GimpSelectionOptions *options;
172
162
GimpChannel *selection;
163
GimpDrawable *drawable;
173
164
GimpLayer *layer;
174
165
GimpLayer *floating_sel;
175
166
gboolean move_layer = FALSE;
176
167
gboolean move_floating_sel = FALSE;
178
options = GIMP_SELECTION_OPTIONS (tool->tool_info->tool_options);
180
selection = gimp_image_get_mask (gdisp->gimage);
181
layer = gimp_image_pick_correlate_layer (gdisp->gimage,
168
gboolean selection_empty;
170
options = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);
172
selection = gimp_image_get_mask (display->image);
173
drawable = gimp_image_active_drawable (display->image);
174
layer = gimp_image_pick_correlate_layer (display->image,
182
175
coords->x, coords->y);
183
floating_sel = gimp_image_floating_sel (gdisp->gimage);
176
floating_sel = gimp_image_floating_sel (display->image);
187
180
if (floating_sel)
189
182
if (layer == floating_sel)
190
183
move_floating_sel = TRUE;
192
else if (gimp_channel_value (selection, coords->x, coords->y))
185
else if (gimp_drawable_mask_intersect (drawable,
186
NULL, NULL, NULL, NULL))
194
188
move_layer = TRUE;
198
if ((state & GDK_MOD1_MASK) && (state & GDK_CONTROL_MASK) && move_layer)
200
selection_tool->op = SELECTION_MOVE_COPY; /* move a copy of the selection */
202
else if ((state & GDK_MOD1_MASK) && ! gimp_channel_is_empty (selection))
204
selection_tool->op = SELECTION_MOVE_MASK; /* move the selection mask */
206
else if (! (state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) &&
207
(move_layer || move_floating_sel))
209
selection_tool->op = SELECTION_MOVE; /* move the selection */
211
else if ((state & GDK_CONTROL_MASK) && (state & GDK_SHIFT_MASK))
213
selection_tool->op = SELECTION_INTERSECT; /* intersect with selection */
215
else if (state & GDK_SHIFT_MASK)
217
selection_tool->op = SELECTION_ADD; /* add to the selection */
219
else if (state & GDK_CONTROL_MASK)
221
selection_tool->op = SELECTION_SUBTRACT; /* subtract from the selection */
192
selection_empty = gimp_channel_is_empty (selection);
194
selection_tool->function = SELECTION_SELECT;
196
if (selection_tool->allow_move &&
197
(state & GDK_MOD1_MASK) && (state & GDK_CONTROL_MASK) && move_layer)
199
/* move the selection */
200
selection_tool->function = SELECTION_MOVE;
202
else if (selection_tool->allow_move &&
203
(state & GDK_MOD1_MASK) && (state & GDK_SHIFT_MASK) && move_layer)
205
/* move a copy of the selection */
206
selection_tool->function = SELECTION_MOVE_COPY;
208
else if (selection_tool->allow_move &&
209
(state & GDK_MOD1_MASK) && ! selection_empty)
211
/* move the selection mask */
212
selection_tool->function = SELECTION_MOVE_MASK;
214
else if (selection_tool->allow_move &&
215
! (state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) &&
218
/* move the selection */
219
selection_tool->function = SELECTION_MOVE;
221
else if ((state & GDK_CONTROL_MASK) || (state & GDK_SHIFT_MASK))
224
selection_tool->function = SELECTION_SELECT;
223
226
else if (floating_sel)
225
selection_tool->op = SELECTION_ANCHOR; /* anchor the selection */
228
/* anchor the selection */
229
selection_tool->function = SELECTION_ANCHOR;
232
gimp_tool_pop_status (tool, display);
229
selection_tool->op = options->operation;
236
gchar *status = NULL;
237
gboolean free_status = FALSE;
238
GdkModifierType modifiers = (GDK_SHIFT_MASK | GDK_CONTROL_MASK);
240
if (! selection_empty)
241
modifiers |= GDK_MOD1_MASK;
243
switch (selection_tool->function)
245
case SELECTION_SELECT:
246
switch (options->operation)
248
case GIMP_CHANNEL_OP_REPLACE:
249
if (! selection_empty)
251
status = gimp_suggest_modifiers (_("Click-Drag to replace the "
252
"current selection"),
259
status = _("Click-Drag to create a new selection");
263
case GIMP_CHANNEL_OP_ADD:
264
status = gimp_suggest_modifiers (_("Click-Drag to add to the "
265
"current selection"),
267
& ~(state | GDK_SHIFT_MASK),
272
case GIMP_CHANNEL_OP_SUBTRACT:
273
status = gimp_suggest_modifiers (_("Click-Drag to subtract from the "
274
"current selection"),
276
& ~(state | GDK_CONTROL_MASK),
281
case GIMP_CHANNEL_OP_INTERSECT:
282
status = gimp_suggest_modifiers (_("Click-Drag to intersect with "
283
"the current selection"),
291
case SELECTION_MOVE_MASK:
292
status = gimp_suggest_modifiers (_("Click-Drag to move the "
300
status = _("Click-Drag to move the selected pixels");
303
case SELECTION_MOVE_COPY:
304
status = _("Click-Drag to move a copy of the selected pixels");
307
case SELECTION_ANCHOR:
308
status = _("Click to anchor the floating selection");
312
g_return_if_reached ();
316
gimp_tool_push_status (tool, display, status);
234
324
gimp_selection_tool_cursor_update (GimpTool *tool,
235
325
GimpCoords *coords,
236
326
GdkModifierType state,
327
GimpDisplay *display)
239
GimpSelectionTool *selection_tool = GIMP_SELECTION_TOOL (tool);
240
GimpToolCursorType tool_cursor;
241
GimpCursorModifier cmodifier;
329
GimpSelectionTool *selection_tool = GIMP_SELECTION_TOOL (tool);
330
GimpSelectionOptions *options;
331
GimpToolCursorType tool_cursor;
332
GimpCursorModifier modifier;
334
options = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);
243
336
tool_cursor = gimp_tool_control_get_tool_cursor (tool->control);
244
cmodifier = GIMP_CURSOR_MODIFIER_NONE;
337
modifier = GIMP_CURSOR_MODIFIER_NONE;
246
switch (selection_tool->op)
339
switch (selection_tool->function)
249
cmodifier = GIMP_CURSOR_MODIFIER_PLUS;
251
case SELECTION_SUBTRACT:
252
cmodifier = GIMP_CURSOR_MODIFIER_MINUS;
254
case SELECTION_INTERSECT:
255
cmodifier = GIMP_CURSOR_MODIFIER_INTERSECT;
257
case SELECTION_REPLACE:
341
case SELECTION_SELECT:
342
switch (options->operation)
344
case GIMP_CHANNEL_OP_REPLACE:
346
case GIMP_CHANNEL_OP_ADD:
347
modifier = GIMP_CURSOR_MODIFIER_PLUS;
349
case GIMP_CHANNEL_OP_SUBTRACT:
350
modifier = GIMP_CURSOR_MODIFIER_MINUS;
352
case GIMP_CHANNEL_OP_INTERSECT:
353
modifier = GIMP_CURSOR_MODIFIER_INTERSECT;
259
358
case SELECTION_MOVE_MASK:
260
cmodifier = GIMP_CURSOR_MODIFIER_MOVE;
359
modifier = GIMP_CURSOR_MODIFIER_MOVE;
262
362
case SELECTION_MOVE:
263
363
case SELECTION_MOVE_COPY:
264
364
tool_cursor = GIMP_TOOL_CURSOR_MOVE;
266
367
case SELECTION_ANCHOR:
267
cmodifier = GIMP_CURSOR_MODIFIER_ANCHOR;
368
modifier = GIMP_CURSOR_MODIFIER_ANCHOR;
271
gimp_tool_set_cursor (tool, gdisp,
272
GIMP_CURSOR_MOUSE, tool_cursor, cmodifier);
372
/* we don't set the bad modifier ourselves, so a subclass has set
373
* it, always leave it there since it's more important than what we
376
if (gimp_tool_control_get_cursor_modifier (tool->control) ==
377
GIMP_CURSOR_MODIFIER_BAD)
379
modifier = GIMP_CURSOR_MODIFIER_BAD;
382
gimp_tool_set_cursor (tool, display,
383
gimp_tool_control_get_cursor (tool->control),
287
400
tool = GIMP_TOOL (sel_tool);
289
g_return_val_if_fail (GIMP_IS_DISPLAY (tool->gdisp), FALSE);
402
g_return_val_if_fail (GIMP_IS_DISPLAY (tool->display), FALSE);
290
403
g_return_val_if_fail (gimp_tool_control_is_active (tool->control), FALSE);
292
switch (sel_tool->op)
405
switch (sel_tool->function)
294
407
case SELECTION_MOVE_MASK:
295
gimp_edit_selection_tool_start (tool, tool->gdisp, coords,
408
gimp_edit_selection_tool_start (tool, tool->display, coords,
296
409
GIMP_TRANSLATE_MODE_MASK, FALSE);
299
412
case SELECTION_MOVE:
300
gimp_edit_selection_tool_start (tool, tool->gdisp, coords,
413
gimp_edit_selection_tool_start (tool, tool->display, coords,
301
414
GIMP_TRANSLATE_MODE_MASK_TO_LAYER, FALSE);
304
417
case SELECTION_MOVE_COPY:
305
gimp_edit_selection_tool_start (tool, tool->gdisp, coords,
418
gimp_edit_selection_tool_start (tool, tool->display, coords,
306
419
GIMP_TRANSLATE_MODE_MASK_COPY_TO_LAYER,