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