1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3 *
4 * Vector tool
5 * Copyright (C) 2003 Simon Budig <simon@gimp.org>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21 #include "config.h"
22
23 #include <gegl.h>
24 #include <gtk/gtk.h>
25
26 #include "libgimpconfig/gimpconfig.h"
27 #include "libgimpwidgets/gimpwidgets.h"
28
29 #include "tools-types.h"
30
31 #include "config/gimpdialogconfig.h"
32
33 #include "core/gimp.h"
34 #include "core/gimpimage.h"
35 #include "core/gimpimage-pick-item.h"
36 #include "core/gimpimage-undo.h"
37 #include "core/gimpimage-undo-push.h"
38 #include "core/gimptoolinfo.h"
39 #include "core/gimpundostack.h"
40
41 #include "paint/gimppaintoptions.h" /* GIMP_PAINT_OPTIONS_CONTEXT_MASK */
42
43 #include "vectors/gimpvectors.h"
44
45 #include "widgets/gimphelp-ids.h"
46 #include "widgets/gimpwidgets-utils.h"
47
48 #include "display/gimpdisplay.h"
49 #include "display/gimpdisplayshell.h"
50 #include "display/gimptoolpath.h"
51
52 #include "gimptoolcontrol.h"
53 #include "gimpvectoroptions.h"
54 #include "gimpvectortool.h"
55
56 #include "dialogs/fill-dialog.h"
57 #include "dialogs/stroke-dialog.h"
58
59 #include "gimp-intl.h"
60
61
62 #define TOGGLE_MASK gimp_get_extend_selection_mask ()
63 #define MOVE_MASK GDK_MOD1_MASK
64 #define INSDEL_MASK gimp_get_toggle_behavior_mask ()
65
66
67 /* local function prototypes */
68
69 static void gimp_vector_tool_dispose (GObject *object);
70
71 static void gimp_vector_tool_control (GimpTool *tool,
72 GimpToolAction action,
73 GimpDisplay *display);
74 static void gimp_vector_tool_button_press (GimpTool *tool,
75 const GimpCoords *coords,
76 guint32 time,
77 GdkModifierType state,
78 GimpButtonPressType press_type,
79 GimpDisplay *display);
80 static void gimp_vector_tool_button_release (GimpTool *tool,
81 const GimpCoords *coords,
82 guint32 time,
83 GdkModifierType state,
84 GimpButtonReleaseType release_type,
85 GimpDisplay *display);
86 static void gimp_vector_tool_motion (GimpTool *tool,
87 const GimpCoords *coords,
88 guint32 time,
89 GdkModifierType state,
90 GimpDisplay *display);
91 static void gimp_vector_tool_modifier_key (GimpTool *tool,
92 GdkModifierType key,
93 gboolean press,
94 GdkModifierType state,
95 GimpDisplay *display);
96 static void gimp_vector_tool_cursor_update (GimpTool *tool,
97 const GimpCoords *coords,
98 GdkModifierType state,
99 GimpDisplay *display);
100
101 static void gimp_vector_tool_start (GimpVectorTool *vector_tool,
102 GimpDisplay *display);
103 static void gimp_vector_tool_halt (GimpVectorTool *vector_tool);
104
105 static void gimp_vector_tool_path_changed (GimpToolWidget *path,
106 GimpVectorTool *vector_tool);
107 static void gimp_vector_tool_path_begin_change
108 (GimpToolWidget *path,
109 const gchar *desc,
110 GimpVectorTool *vector_tool);
111 static void gimp_vector_tool_path_end_change (GimpToolWidget *path,
112 gboolean success,
113 GimpVectorTool *vector_tool);
114 static void gimp_vector_tool_path_activate (GimpToolWidget *path,
115 GdkModifierType state,
116 GimpVectorTool *vector_tool);
117
118 static void gimp_vector_tool_vectors_changed (GimpImage *image,
119 GimpVectorTool *vector_tool);
120 static void gimp_vector_tool_vectors_removed (GimpVectors *vectors,
121 GimpVectorTool *vector_tool);
122
123 static void gimp_vector_tool_to_selection (GimpVectorTool *vector_tool);
124 static void gimp_vector_tool_to_selection_extended
125 (GimpVectorTool *vector_tool,
126 GdkModifierType state);
127
128 static void gimp_vector_tool_fill_vectors (GimpVectorTool *vector_tool,
129 GtkWidget *button);
130 static void gimp_vector_tool_fill_callback (GtkWidget *dialog,
131 GimpItem *item,
132 GimpDrawable *drawable,
133 GimpContext *context,
134 GimpFillOptions *options,
135 gpointer data);
136
137 static void gimp_vector_tool_stroke_vectors (GimpVectorTool *vector_tool,
138 GtkWidget *button);
139 static void gimp_vector_tool_stroke_callback (GtkWidget *dialog,
140 GimpItem *item,
141 GimpDrawable *drawable,
142 GimpContext *context,
143 GimpStrokeOptions *options,
144 gpointer data);
145
146
G_DEFINE_TYPE(GimpVectorTool,gimp_vector_tool,GIMP_TYPE_DRAW_TOOL)147 G_DEFINE_TYPE (GimpVectorTool, gimp_vector_tool, GIMP_TYPE_DRAW_TOOL)
148
149 #define parent_class gimp_vector_tool_parent_class
150
151
152 void
153 gimp_vector_tool_register (GimpToolRegisterCallback callback,
154 gpointer data)
155 {
156 (* callback) (GIMP_TYPE_VECTOR_TOOL,
157 GIMP_TYPE_VECTOR_OPTIONS,
158 gimp_vector_options_gui,
159 GIMP_PAINT_OPTIONS_CONTEXT_MASK |
160 GIMP_CONTEXT_PROP_MASK_PATTERN |
161 GIMP_CONTEXT_PROP_MASK_GRADIENT, /* for stroking */
162 "gimp-vector-tool",
163 _("Paths"),
164 _("Paths Tool: Create and edit paths"),
165 N_("Pat_hs"), "b",
166 NULL, GIMP_HELP_TOOL_PATH,
167 GIMP_ICON_TOOL_PATH,
168 data);
169 }
170
171 static void
gimp_vector_tool_class_init(GimpVectorToolClass * klass)172 gimp_vector_tool_class_init (GimpVectorToolClass *klass)
173 {
174 GObjectClass *object_class = G_OBJECT_CLASS (klass);
175 GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass);
176
177 object_class->dispose = gimp_vector_tool_dispose;
178
179 tool_class->control = gimp_vector_tool_control;
180 tool_class->button_press = gimp_vector_tool_button_press;
181 tool_class->button_release = gimp_vector_tool_button_release;
182 tool_class->motion = gimp_vector_tool_motion;
183 tool_class->modifier_key = gimp_vector_tool_modifier_key;
184 tool_class->cursor_update = gimp_vector_tool_cursor_update;
185 }
186
187 static void
gimp_vector_tool_init(GimpVectorTool * vector_tool)188 gimp_vector_tool_init (GimpVectorTool *vector_tool)
189 {
190 GimpTool *tool = GIMP_TOOL (vector_tool);
191
192 gimp_tool_control_set_handle_empty_image (tool->control, TRUE);
193 gimp_tool_control_set_precision (tool->control,
194 GIMP_CURSOR_PRECISION_SUBPIXEL);
195 gimp_tool_control_set_tool_cursor (tool->control,
196 GIMP_TOOL_CURSOR_PATHS);
197
198 vector_tool->saved_mode = GIMP_VECTOR_MODE_DESIGN;
199 }
200
201 static void
gimp_vector_tool_dispose(GObject * object)202 gimp_vector_tool_dispose (GObject *object)
203 {
204 GimpVectorTool *vector_tool = GIMP_VECTOR_TOOL (object);
205
206 gimp_vector_tool_set_vectors (vector_tool, NULL);
207 g_clear_object (&vector_tool->widget);
208
209 G_OBJECT_CLASS (parent_class)->dispose (object);
210 }
211
212 static void
gimp_vector_tool_control(GimpTool * tool,GimpToolAction action,GimpDisplay * display)213 gimp_vector_tool_control (GimpTool *tool,
214 GimpToolAction action,
215 GimpDisplay *display)
216 {
217 GimpVectorTool *vector_tool = GIMP_VECTOR_TOOL (tool);
218
219 switch (action)
220 {
221 case GIMP_TOOL_ACTION_PAUSE:
222 case GIMP_TOOL_ACTION_RESUME:
223 break;
224
225 case GIMP_TOOL_ACTION_HALT:
226 gimp_vector_tool_halt (vector_tool);
227 break;
228
229 case GIMP_TOOL_ACTION_COMMIT:
230 break;
231 }
232
233 GIMP_TOOL_CLASS (parent_class)->control (tool, action, display);
234 }
235
236 static void
gimp_vector_tool_button_press(GimpTool * tool,const GimpCoords * coords,guint32 time,GdkModifierType state,GimpButtonPressType press_type,GimpDisplay * display)237 gimp_vector_tool_button_press (GimpTool *tool,
238 const GimpCoords *coords,
239 guint32 time,
240 GdkModifierType state,
241 GimpButtonPressType press_type,
242 GimpDisplay *display)
243 {
244 GimpVectorTool *vector_tool = GIMP_VECTOR_TOOL (tool);
245
246 if (tool->display && display != tool->display)
247 gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, tool->display);
248
249 if (! tool->display)
250 {
251 gimp_vector_tool_start (vector_tool, display);
252
253 gimp_tool_widget_hover (vector_tool->widget, coords, state, TRUE);
254 }
255
256 if (gimp_tool_widget_button_press (vector_tool->widget, coords, time, state,
257 press_type))
258 {
259 vector_tool->grab_widget = vector_tool->widget;
260 }
261
262 gimp_tool_control_activate (tool->control);
263 }
264
265 static void
gimp_vector_tool_button_release(GimpTool * tool,const GimpCoords * coords,guint32 time,GdkModifierType state,GimpButtonReleaseType release_type,GimpDisplay * display)266 gimp_vector_tool_button_release (GimpTool *tool,
267 const GimpCoords *coords,
268 guint32 time,
269 GdkModifierType state,
270 GimpButtonReleaseType release_type,
271 GimpDisplay *display)
272 {
273 GimpVectorTool *vector_tool = GIMP_VECTOR_TOOL (tool);
274
275 gimp_tool_control_halt (tool->control);
276
277 if (vector_tool->grab_widget)
278 {
279 gimp_tool_widget_button_release (vector_tool->grab_widget,
280 coords, time, state, release_type);
281 vector_tool->grab_widget = NULL;
282 }
283 }
284
285 static void
gimp_vector_tool_motion(GimpTool * tool,const GimpCoords * coords,guint32 time,GdkModifierType state,GimpDisplay * display)286 gimp_vector_tool_motion (GimpTool *tool,
287 const GimpCoords *coords,
288 guint32 time,
289 GdkModifierType state,
290 GimpDisplay *display)
291 {
292 GimpVectorTool *vector_tool = GIMP_VECTOR_TOOL (tool);
293
294 if (vector_tool->grab_widget)
295 {
296 gimp_tool_widget_motion (vector_tool->grab_widget, coords, time, state);
297 }
298 }
299
300 static void
gimp_vector_tool_modifier_key(GimpTool * tool,GdkModifierType key,gboolean press,GdkModifierType state,GimpDisplay * display)301 gimp_vector_tool_modifier_key (GimpTool *tool,
302 GdkModifierType key,
303 gboolean press,
304 GdkModifierType state,
305 GimpDisplay *display)
306 {
307 GimpVectorTool *vector_tool = GIMP_VECTOR_TOOL (tool);
308 GimpVectorOptions *options = GIMP_VECTOR_TOOL_GET_OPTIONS (tool);
309
310 if (key == TOGGLE_MASK)
311 return;
312
313 if (key == INSDEL_MASK || key == MOVE_MASK)
314 {
315 GimpVectorMode button_mode = options->edit_mode;
316
317 if (press)
318 {
319 if (key == (state & (INSDEL_MASK | MOVE_MASK)))
320 {
321 /* first modifier pressed */
322
323 vector_tool->saved_mode = options->edit_mode;
324 }
325 }
326 else
327 {
328 if (! (state & (INSDEL_MASK | MOVE_MASK)))
329 {
330 /* last modifier released */
331
332 button_mode = vector_tool->saved_mode;
333 }
334 }
335
336 if (state & MOVE_MASK)
337 {
338 button_mode = GIMP_VECTOR_MODE_MOVE;
339 }
340 else if (state & INSDEL_MASK)
341 {
342 button_mode = GIMP_VECTOR_MODE_EDIT;
343 }
344
345 if (button_mode != options->edit_mode)
346 {
347 g_object_set (options, "vectors-edit-mode", button_mode, NULL);
348 }
349 }
350 }
351
352 static void
gimp_vector_tool_cursor_update(GimpTool * tool,const GimpCoords * coords,GdkModifierType state,GimpDisplay * display)353 gimp_vector_tool_cursor_update (GimpTool *tool,
354 const GimpCoords *coords,
355 GdkModifierType state,
356 GimpDisplay *display)
357 {
358 GimpVectorTool *vector_tool = GIMP_VECTOR_TOOL (tool);
359 GimpDisplayShell *shell = gimp_display_get_shell (display);
360
361 if (display != tool->display || ! vector_tool->widget)
362 {
363 GimpToolCursorType tool_cursor = GIMP_TOOL_CURSOR_PATHS;
364
365 if (gimp_image_pick_vectors (gimp_display_get_image (display),
366 coords->x, coords->y,
367 FUNSCALEX (shell,
368 GIMP_TOOL_HANDLE_SIZE_CIRCLE / 2),
369 FUNSCALEY (shell,
370 GIMP_TOOL_HANDLE_SIZE_CIRCLE / 2)))
371 {
372 tool_cursor = GIMP_TOOL_CURSOR_HAND;
373 }
374
375 gimp_tool_control_set_tool_cursor (tool->control, tool_cursor);
376 }
377
378 GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
379 }
380
381 static void
gimp_vector_tool_start(GimpVectorTool * vector_tool,GimpDisplay * display)382 gimp_vector_tool_start (GimpVectorTool *vector_tool,
383 GimpDisplay *display)
384 {
385 GimpTool *tool = GIMP_TOOL (vector_tool);
386 GimpVectorOptions *options = GIMP_VECTOR_TOOL_GET_OPTIONS (tool);
387 GimpDisplayShell *shell = gimp_display_get_shell (display);
388 GimpToolWidget *widget;
389
390 tool->display = display;
391
392 vector_tool->widget = widget = gimp_tool_path_new (shell);
393
394 gimp_draw_tool_set_widget (GIMP_DRAW_TOOL (tool), widget);
395
396 g_object_bind_property (G_OBJECT (options), "vectors-edit-mode",
397 G_OBJECT (widget), "edit-mode",
398 G_BINDING_SYNC_CREATE |
399 G_BINDING_BIDIRECTIONAL);
400 g_object_bind_property (G_OBJECT (options), "vectors-polygonal",
401 G_OBJECT (widget), "polygonal",
402 G_BINDING_SYNC_CREATE |
403 G_BINDING_BIDIRECTIONAL);
404
405 gimp_tool_path_set_vectors (GIMP_TOOL_PATH (widget),
406 vector_tool->vectors);
407
408 g_signal_connect (widget, "changed",
409 G_CALLBACK (gimp_vector_tool_path_changed),
410 vector_tool);
411 g_signal_connect (widget, "begin-change",
412 G_CALLBACK (gimp_vector_tool_path_begin_change),
413 vector_tool);
414 g_signal_connect (widget, "end-change",
415 G_CALLBACK (gimp_vector_tool_path_end_change),
416 vector_tool);
417 g_signal_connect (widget, "activate",
418 G_CALLBACK (gimp_vector_tool_path_activate),
419 vector_tool);
420
421 gimp_draw_tool_start (GIMP_DRAW_TOOL (tool), display);
422 }
423
424 static void
gimp_vector_tool_halt(GimpVectorTool * vector_tool)425 gimp_vector_tool_halt (GimpVectorTool *vector_tool)
426 {
427 GimpTool *tool = GIMP_TOOL (vector_tool);
428
429 if (tool->display)
430 gimp_tool_pop_status (tool, tool->display);
431
432 gimp_vector_tool_set_vectors (vector_tool, NULL);
433
434 if (gimp_draw_tool_is_active (GIMP_DRAW_TOOL (tool)))
435 gimp_draw_tool_stop (GIMP_DRAW_TOOL (tool));
436
437 gimp_draw_tool_set_widget (GIMP_DRAW_TOOL (tool), NULL);
438 g_clear_object (&vector_tool->widget);
439
440 tool->display = NULL;
441 }
442
443 static void
gimp_vector_tool_path_changed(GimpToolWidget * path,GimpVectorTool * vector_tool)444 gimp_vector_tool_path_changed (GimpToolWidget *path,
445 GimpVectorTool *vector_tool)
446 {
447 GimpDisplayShell *shell = gimp_tool_widget_get_shell (path);
448 GimpImage *image = gimp_display_get_image (shell->display);
449 GimpVectors *vectors;
450
451 g_object_get (path,
452 "vectors", &vectors,
453 NULL);
454
455 if (vectors != vector_tool->vectors)
456 {
457 if (vectors && ! gimp_item_is_attached (GIMP_ITEM (vectors)))
458 {
459 gimp_image_add_vectors (image, vectors,
460 GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
461 gimp_image_flush (image);
462
463 gimp_vector_tool_set_vectors (vector_tool, vectors);
464 }
465 else
466 {
467 gimp_vector_tool_set_vectors (vector_tool, vectors);
468
469 if (vectors)
470 gimp_image_set_active_vectors (image, vectors);
471 }
472 }
473
474 if (vectors)
475 g_object_unref (vectors);
476 }
477
478 static void
gimp_vector_tool_path_begin_change(GimpToolWidget * path,const gchar * desc,GimpVectorTool * vector_tool)479 gimp_vector_tool_path_begin_change (GimpToolWidget *path,
480 const gchar *desc,
481 GimpVectorTool *vector_tool)
482 {
483 GimpDisplayShell *shell = gimp_tool_widget_get_shell (path);
484 GimpImage *image = gimp_display_get_image (shell->display);
485
486 gimp_image_undo_push_vectors_mod (image, desc, vector_tool->vectors);
487 }
488
489 static void
gimp_vector_tool_path_end_change(GimpToolWidget * path,gboolean success,GimpVectorTool * vector_tool)490 gimp_vector_tool_path_end_change (GimpToolWidget *path,
491 gboolean success,
492 GimpVectorTool *vector_tool)
493 {
494 GimpDisplayShell *shell = gimp_tool_widget_get_shell (path);
495 GimpImage *image = gimp_display_get_image (shell->display);
496
497 if (! success)
498 {
499 GimpUndo *undo;
500 GimpUndoAccumulator accum = { 0, };
501
502 undo = gimp_undo_stack_pop_undo (gimp_image_get_undo_stack (image),
503 GIMP_UNDO_MODE_UNDO, &accum);
504
505 gimp_image_undo_event (image, GIMP_UNDO_EVENT_UNDO_EXPIRED, undo);
506
507 gimp_undo_free (undo, GIMP_UNDO_MODE_UNDO);
508 g_object_unref (undo);
509 }
510
511 gimp_image_flush (image);
512 }
513
514 static void
gimp_vector_tool_path_activate(GimpToolWidget * path,GdkModifierType state,GimpVectorTool * vector_tool)515 gimp_vector_tool_path_activate (GimpToolWidget *path,
516 GdkModifierType state,
517 GimpVectorTool *vector_tool)
518 {
519 gimp_vector_tool_to_selection_extended (vector_tool, state);
520 }
521
522 static void
gimp_vector_tool_vectors_changed(GimpImage * image,GimpVectorTool * vector_tool)523 gimp_vector_tool_vectors_changed (GimpImage *image,
524 GimpVectorTool *vector_tool)
525 {
526 gimp_vector_tool_set_vectors (vector_tool,
527 gimp_image_get_active_vectors (image));
528 }
529
530 static void
gimp_vector_tool_vectors_removed(GimpVectors * vectors,GimpVectorTool * vector_tool)531 gimp_vector_tool_vectors_removed (GimpVectors *vectors,
532 GimpVectorTool *vector_tool)
533 {
534 gimp_vector_tool_set_vectors (vector_tool, NULL);
535 }
536
537 void
gimp_vector_tool_set_vectors(GimpVectorTool * vector_tool,GimpVectors * vectors)538 gimp_vector_tool_set_vectors (GimpVectorTool *vector_tool,
539 GimpVectors *vectors)
540 {
541 GimpTool *tool;
542 GimpItem *item = NULL;
543 GimpVectorOptions *options;
544
545 g_return_if_fail (GIMP_IS_VECTOR_TOOL (vector_tool));
546 g_return_if_fail (vectors == NULL || GIMP_IS_VECTORS (vectors));
547
548 tool = GIMP_TOOL (vector_tool);
549 options = GIMP_VECTOR_TOOL_GET_OPTIONS (vector_tool);
550
551 if (vectors)
552 item = GIMP_ITEM (vectors);
553
554 if (vectors == vector_tool->vectors)
555 return;
556
557 if (vector_tool->vectors)
558 {
559 GimpImage *old_image;
560
561 old_image = gimp_item_get_image (GIMP_ITEM (vector_tool->vectors));
562
563 g_signal_handlers_disconnect_by_func (old_image,
564 gimp_vector_tool_vectors_changed,
565 vector_tool);
566 g_signal_handlers_disconnect_by_func (vector_tool->vectors,
567 gimp_vector_tool_vectors_removed,
568 vector_tool);
569
570 g_clear_object (&vector_tool->vectors);
571
572 if (options->to_selection_button)
573 {
574 gtk_widget_set_sensitive (options->to_selection_button, FALSE);
575 g_signal_handlers_disconnect_by_func (options->to_selection_button,
576 gimp_vector_tool_to_selection,
577 tool);
578 g_signal_handlers_disconnect_by_func (options->to_selection_button,
579 gimp_vector_tool_to_selection_extended,
580 tool);
581 }
582
583 if (options->fill_button)
584 {
585 gtk_widget_set_sensitive (options->fill_button, FALSE);
586 g_signal_handlers_disconnect_by_func (options->fill_button,
587 gimp_vector_tool_fill_vectors,
588 tool);
589 }
590
591 if (options->stroke_button)
592 {
593 gtk_widget_set_sensitive (options->stroke_button, FALSE);
594 g_signal_handlers_disconnect_by_func (options->stroke_button,
595 gimp_vector_tool_stroke_vectors,
596 tool);
597 }
598 }
599
600 if (! vectors ||
601 (tool->display &&
602 gimp_display_get_image (tool->display) != gimp_item_get_image (item)))
603 {
604 gimp_vector_tool_halt (vector_tool);
605 }
606
607 if (! vectors)
608 return;
609
610 vector_tool->vectors = g_object_ref (vectors);
611
612 g_signal_connect_object (gimp_item_get_image (item), "active-vectors-changed",
613 G_CALLBACK (gimp_vector_tool_vectors_changed),
614 vector_tool, 0);
615 g_signal_connect_object (vectors, "removed",
616 G_CALLBACK (gimp_vector_tool_vectors_removed),
617 vector_tool, 0);
618
619 if (options->to_selection_button)
620 {
621 g_signal_connect_swapped (options->to_selection_button, "clicked",
622 G_CALLBACK (gimp_vector_tool_to_selection),
623 tool);
624 g_signal_connect_swapped (options->to_selection_button, "extended-clicked",
625 G_CALLBACK (gimp_vector_tool_to_selection_extended),
626 tool);
627 gtk_widget_set_sensitive (options->to_selection_button, TRUE);
628 }
629
630 if (options->fill_button)
631 {
632 g_signal_connect_swapped (options->fill_button, "clicked",
633 G_CALLBACK (gimp_vector_tool_fill_vectors),
634 tool);
635 gtk_widget_set_sensitive (options->fill_button, TRUE);
636 }
637
638 if (options->stroke_button)
639 {
640 g_signal_connect_swapped (options->stroke_button, "clicked",
641 G_CALLBACK (gimp_vector_tool_stroke_vectors),
642 tool);
643 gtk_widget_set_sensitive (options->stroke_button, TRUE);
644 }
645
646 if (tool->display)
647 {
648 gimp_tool_path_set_vectors (GIMP_TOOL_PATH (vector_tool->widget), vectors);
649 }
650 else
651 {
652 GimpContext *context = gimp_get_user_context (tool->tool_info->gimp);
653 GimpDisplay *display = gimp_context_get_display (context);
654
655 if (! display ||
656 gimp_display_get_image (display) != gimp_item_get_image (item))
657 {
658 GList *list;
659
660 display = NULL;
661
662 for (list = gimp_get_display_iter (gimp_item_get_image (item)->gimp);
663 list;
664 list = g_list_next (list))
665 {
666 display = list->data;
667
668 if (gimp_display_get_image (display) == gimp_item_get_image (item))
669 {
670 gimp_context_set_display (context, display);
671 break;
672 }
673
674 display = NULL;
675 }
676 }
677
678 if (display)
679 gimp_vector_tool_start (vector_tool, display);
680 }
681
682 if (options->edit_mode != GIMP_VECTOR_MODE_DESIGN)
683 g_object_set (options, "vectors-edit-mode",
684 GIMP_VECTOR_MODE_DESIGN, NULL);
685 }
686
687 static void
gimp_vector_tool_to_selection(GimpVectorTool * vector_tool)688 gimp_vector_tool_to_selection (GimpVectorTool *vector_tool)
689 {
690 gimp_vector_tool_to_selection_extended (vector_tool, 0);
691 }
692
693 static void
gimp_vector_tool_to_selection_extended(GimpVectorTool * vector_tool,GdkModifierType state)694 gimp_vector_tool_to_selection_extended (GimpVectorTool *vector_tool,
695 GdkModifierType state)
696 {
697 GimpImage *image;
698
699 if (! vector_tool->vectors)
700 return;
701
702 image = gimp_item_get_image (GIMP_ITEM (vector_tool->vectors));
703
704 gimp_item_to_selection (GIMP_ITEM (vector_tool->vectors),
705 gimp_modifiers_to_channel_op (state),
706 TRUE, FALSE, 0, 0);
707 gimp_image_flush (image);
708 }
709
710
711 static void
gimp_vector_tool_fill_vectors(GimpVectorTool * vector_tool,GtkWidget * button)712 gimp_vector_tool_fill_vectors (GimpVectorTool *vector_tool,
713 GtkWidget *button)
714 {
715 GimpDialogConfig *config;
716 GimpImage *image;
717 GimpDrawable *drawable;
718 GtkWidget *dialog;
719
720 if (! vector_tool->vectors)
721 return;
722
723 image = gimp_item_get_image (GIMP_ITEM (vector_tool->vectors));
724
725 config = GIMP_DIALOG_CONFIG (image->gimp->config);
726
727 drawable = gimp_image_get_active_drawable (image);
728
729 if (! drawable)
730 {
731 gimp_tool_message (GIMP_TOOL (vector_tool),
732 GIMP_TOOL (vector_tool)->display,
733 _("There is no active layer or channel to fill"));
734 return;
735 }
736
737 dialog = fill_dialog_new (GIMP_ITEM (vector_tool->vectors),
738 drawable,
739 GIMP_CONTEXT (GIMP_TOOL_GET_OPTIONS (vector_tool)),
740 _("Fill Path"),
741 GIMP_ICON_TOOL_BUCKET_FILL,
742 GIMP_HELP_PATH_FILL,
743 button,
744 config->fill_options,
745 gimp_vector_tool_fill_callback,
746 vector_tool);
747 gtk_widget_show (dialog);
748 }
749
750 static void
gimp_vector_tool_fill_callback(GtkWidget * dialog,GimpItem * item,GimpDrawable * drawable,GimpContext * context,GimpFillOptions * options,gpointer data)751 gimp_vector_tool_fill_callback (GtkWidget *dialog,
752 GimpItem *item,
753 GimpDrawable *drawable,
754 GimpContext *context,
755 GimpFillOptions *options,
756 gpointer data)
757 {
758 GimpDialogConfig *config = GIMP_DIALOG_CONFIG (context->gimp->config);
759 GimpImage *image = gimp_item_get_image (item);
760 GError *error = NULL;
761
762 gimp_config_sync (G_OBJECT (options),
763 G_OBJECT (config->fill_options), 0);
764
765 if (! gimp_item_fill (item, drawable, options,
766 TRUE, NULL, &error))
767 {
768 gimp_message_literal (context->gimp,
769 G_OBJECT (dialog),
770 GIMP_MESSAGE_WARNING,
771 error ? error->message : "NULL");
772
773 g_clear_error (&error);
774 return;
775 }
776
777 gimp_image_flush (image);
778
779 gtk_widget_destroy (dialog);
780 }
781
782
783 static void
gimp_vector_tool_stroke_vectors(GimpVectorTool * vector_tool,GtkWidget * button)784 gimp_vector_tool_stroke_vectors (GimpVectorTool *vector_tool,
785 GtkWidget *button)
786 {
787 GimpDialogConfig *config;
788 GimpImage *image;
789 GimpDrawable *drawable;
790 GtkWidget *dialog;
791
792 if (! vector_tool->vectors)
793 return;
794
795 image = gimp_item_get_image (GIMP_ITEM (vector_tool->vectors));
796
797 config = GIMP_DIALOG_CONFIG (image->gimp->config);
798
799 drawable = gimp_image_get_active_drawable (image);
800
801 if (! drawable)
802 {
803 gimp_tool_message (GIMP_TOOL (vector_tool),
804 GIMP_TOOL (vector_tool)->display,
805 _("There is no active layer or channel to stroke to"));
806 return;
807 }
808
809 dialog = stroke_dialog_new (GIMP_ITEM (vector_tool->vectors),
810 drawable,
811 GIMP_CONTEXT (GIMP_TOOL_GET_OPTIONS (vector_tool)),
812 _("Stroke Path"),
813 GIMP_ICON_PATH_STROKE,
814 GIMP_HELP_PATH_STROKE,
815 button,
816 config->stroke_options,
817 gimp_vector_tool_stroke_callback,
818 vector_tool);
819 gtk_widget_show (dialog);
820 }
821
822 static void
gimp_vector_tool_stroke_callback(GtkWidget * dialog,GimpItem * item,GimpDrawable * drawable,GimpContext * context,GimpStrokeOptions * options,gpointer data)823 gimp_vector_tool_stroke_callback (GtkWidget *dialog,
824 GimpItem *item,
825 GimpDrawable *drawable,
826 GimpContext *context,
827 GimpStrokeOptions *options,
828 gpointer data)
829 {
830 GimpDialogConfig *config = GIMP_DIALOG_CONFIG (context->gimp->config);
831 GimpImage *image = gimp_item_get_image (item);
832 GError *error = NULL;
833
834 gimp_config_sync (G_OBJECT (options),
835 G_OBJECT (config->stroke_options), 0);
836
837 if (! gimp_item_stroke (item, drawable, context, options, NULL,
838 TRUE, NULL, &error))
839 {
840 gimp_message_literal (context->gimp,
841 G_OBJECT (dialog),
842 GIMP_MESSAGE_WARNING,
843 error ? error->message : "NULL");
844
845 g_clear_error (&error);
846 return;
847 }
848
849 gimp_image_flush (image);
850
851 gtk_widget_destroy (dialog);
852 }
853