~ubuntu-branches/ubuntu/hoary/gimp/hoary

« back to all changes in this revision

Viewing changes to app/tools/gimpvectortool.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2005-04-04 14:51:23 UTC
  • Revision ID: james.westby@ubuntu.com-20050404145123-9py049eeelfymur8
Tags: upstream-2.2.2
ImportĀ upstreamĀ versionĀ 2.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* The GIMP -- an 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 2 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, write to the Free Software
 
19
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
20
 */
 
21
 
 
22
#include "config.h"
 
23
 
 
24
#include <stdlib.h>
 
25
#include <string.h>
 
26
 
 
27
#include <gtk/gtk.h>
 
28
#include <gdk/gdkkeysyms.h>
 
29
 
 
30
#include "libgimpmath/gimpmath.h"
 
31
#include "libgimpbase/gimpbase.h"
 
32
#include "libgimpwidgets/gimpwidgets.h"
 
33
 
 
34
#include "tools-types.h"
 
35
 
 
36
#include "core/gimp.h"
 
37
#include "core/gimpcontext.h"
 
38
#include "core/gimpchannel-select.h"
 
39
#include "core/gimpimage.h"
 
40
#include "core/gimpimage-undo-push.h"
 
41
#include "core/gimplist.h"
 
42
#include "core/gimptoolinfo.h"
 
43
#include "core/gimpundo.h"
 
44
#include "core/gimpundostack.h"
 
45
 
 
46
#include "vectors/gimpanchor.h"
 
47
#include "vectors/gimpvectors.h"
 
48
#include "vectors/gimpbezierstroke.h"
 
49
 
 
50
#include "widgets/gimphelp-ids.h"
 
51
 
 
52
#include "display/gimpdisplay.h"
 
53
#include "display/gimpdisplayshell.h"
 
54
#include "display/gimpdisplayshell-scale.h"
 
55
 
 
56
#include "gimptoolcontrol.h"
 
57
#include "gimpvectoroptions.h"
 
58
#include "gimpvectortool.h"
 
59
 
 
60
#include "dialogs/stroke-dialog.h"
 
61
 
 
62
#include "gimp-intl.h"
 
63
 
 
64
 
 
65
#define TARGET 9
 
66
 
 
67
#define TOGGLE_MASK GDK_SHIFT_MASK
 
68
#define MOVE_MASK   GDK_MOD1_MASK
 
69
#define INSDEL_MASK GDK_CONTROL_MASK
 
70
 
 
71
 
 
72
/*  local function prototypes  */
 
73
 
 
74
static void     gimp_vector_tool_class_init      (GimpVectorToolClass *klass);
 
75
static void     gimp_vector_tool_init            (GimpVectorTool      *tool);
 
76
 
 
77
static void     gimp_vector_tool_control         (GimpTool        *tool,
 
78
                                                  GimpToolAction   action,
 
79
                                                  GimpDisplay     *gdisp);
 
80
static void     gimp_vector_tool_button_press    (GimpTool        *tool,
 
81
                                                  GimpCoords      *coords,
 
82
                                                  guint32          time,
 
83
                                                  GdkModifierType  state,
 
84
                                                  GimpDisplay     *gdisp);
 
85
static void     gimp_vector_tool_button_release  (GimpTool        *tool,
 
86
                                                  GimpCoords      *coords,
 
87
                                                  guint32          time,
 
88
                                                  GdkModifierType  state,
 
89
                                                  GimpDisplay     *gdisp);
 
90
static void     gimp_vector_tool_motion          (GimpTool        *tool,
 
91
                                                  GimpCoords      *coords,
 
92
                                                  guint32          time,
 
93
                                                  GdkModifierType  state,
 
94
                                                  GimpDisplay     *gdisp);
 
95
static gboolean gimp_vector_tool_key_press       (GimpTool        *tool,
 
96
                                                  GdkEventKey     *kevent,
 
97
                                                  GimpDisplay     *gdisp);
 
98
static void     gimp_vector_tool_modifier_key    (GimpTool        *tool,
 
99
                                                  GdkModifierType  key,
 
100
                                                  gboolean         press,
 
101
                                                  GdkModifierType  state,
 
102
                                                  GimpDisplay     *gdisp);
 
103
static void     gimp_vector_tool_oper_update     (GimpTool        *tool,
 
104
                                                  GimpCoords      *coords,
 
105
                                                  GdkModifierType  state,
 
106
                                                  GimpDisplay     *gdisp);
 
107
static void     gimp_vector_tool_status_update   (GimpTool        *tool,
 
108
                                                  GimpDisplay     *gdisp);
 
109
static void     gimp_vector_tool_status_set      (GimpTool        *tool,
 
110
                                                  GimpDisplay     *gdisp,
 
111
                                                  const gchar     *message);
 
112
static void     gimp_vector_tool_cursor_update   (GimpTool        *tool,
 
113
                                                  GimpCoords      *coords,
 
114
                                                  GdkModifierType  state,
 
115
                                                  GimpDisplay     *gdisp);
 
116
 
 
117
static void     gimp_vector_tool_draw            (GimpDrawTool    *draw_tool);
 
118
 
 
119
static void     gimp_vector_tool_vectors_changed (GimpImage       *gimage,
 
120
                                                  GimpVectorTool  *vector_tool);
 
121
static void     gimp_vector_tool_vectors_removed (GimpVectors     *vectors,
 
122
                                                  GimpVectorTool  *vector_tool);
 
123
static void     gimp_vector_tool_vectors_visible (GimpVectors     *vectors,
 
124
                                                  GimpVectorTool  *vector_tool);
 
125
static void     gimp_vector_tool_vectors_freeze  (GimpVectors     *vectors,
 
126
                                                  GimpVectorTool  *vector_tool);
 
127
static void     gimp_vector_tool_vectors_thaw    (GimpVectors     *vectors,
 
128
                                                  GimpVectorTool  *vector_tool);
 
129
 
 
130
static void     gimp_vector_tool_move_selected_anchors
 
131
                                                 (GimpVectorTool  *vector_tool,
 
132
                                                  gdouble          x,
 
133
                                                  gdouble          y);
 
134
static void     gimp_vector_tool_delete_selected_anchors
 
135
                                                 (GimpVectorTool  *vector_tool);
 
136
static void     gimp_vector_tool_verify_state    (GimpVectorTool  *vector_tool);
 
137
static void     gimp_vector_tool_undo_push       (GimpVectorTool  *vector_tool,
 
138
                                                  const gchar     *desc);
 
139
 
 
140
static void     gimp_vector_tool_to_selection    (GimpVectorTool  *vector_tool);
 
141
static void     gimp_vector_tool_to_selection_extended
 
142
                                                 (GimpVectorTool  *vector_tool,
 
143
                                                  gint             state);
 
144
static void     gimp_vector_tool_stroke_vectors  (GimpVectorTool  *vector_tool,
 
145
                                                  GtkWidget       *button);
 
146
 
 
147
 
 
148
static GimpDrawToolClass *parent_class = NULL;
 
149
 
 
150
 
 
151
void
 
152
gimp_vector_tool_register (GimpToolRegisterCallback callback,
 
153
                           gpointer                 data)
 
154
{
 
155
  (* callback) (GIMP_TYPE_VECTOR_TOOL,
 
156
                GIMP_TYPE_VECTOR_OPTIONS,
 
157
                gimp_vector_options_gui,
 
158
                0,
 
159
                "gimp-vector-tool",
 
160
                _("Paths"),
 
161
                _("Create and edit paths"),
 
162
                N_("_Paths"), "b",
 
163
                NULL, GIMP_HELP_TOOL_PATH,
 
164
                GIMP_STOCK_TOOL_PATH,
 
165
                data);
 
166
}
 
167
 
 
168
GType
 
169
gimp_vector_tool_get_type (void)
 
170
{
 
171
  static GType tool_type = 0;
 
172
 
 
173
  if (! tool_type)
 
174
    {
 
175
      static const GTypeInfo tool_info =
 
176
      {
 
177
        sizeof (GimpVectorToolClass),
 
178
        (GBaseInitFunc) NULL,
 
179
        (GBaseFinalizeFunc) NULL,
 
180
        (GClassInitFunc) gimp_vector_tool_class_init,
 
181
        NULL,           /* class_finalize */
 
182
        NULL,           /* class_data     */
 
183
        sizeof (GimpVectorTool),
 
184
        0,              /* n_preallocs    */
 
185
        (GInstanceInitFunc) gimp_vector_tool_init,
 
186
      };
 
187
 
 
188
      tool_type = g_type_register_static (GIMP_TYPE_DRAW_TOOL,
 
189
                                          "GimpVectorTool",
 
190
                                          &tool_info, 0);
 
191
    }
 
192
 
 
193
  return tool_type;
 
194
}
 
195
 
 
196
static void
 
197
gimp_vector_tool_class_init (GimpVectorToolClass *klass)
 
198
{
 
199
  GObjectClass      *object_class;
 
200
  GimpToolClass     *tool_class;
 
201
  GimpDrawToolClass *draw_tool_class;
 
202
 
 
203
  object_class    = G_OBJECT_CLASS (klass);
 
204
  tool_class      = GIMP_TOOL_CLASS (klass);
 
205
  draw_tool_class = GIMP_DRAW_TOOL_CLASS (klass);
 
206
 
 
207
  parent_class = g_type_class_peek_parent (klass);
 
208
 
 
209
  tool_class->control        = gimp_vector_tool_control;
 
210
  tool_class->button_press   = gimp_vector_tool_button_press;
 
211
  tool_class->button_release = gimp_vector_tool_button_release;
 
212
  tool_class->motion         = gimp_vector_tool_motion;
 
213
  tool_class->key_press      = gimp_vector_tool_key_press;
 
214
  tool_class->modifier_key   = gimp_vector_tool_modifier_key;
 
215
  tool_class->oper_update    = gimp_vector_tool_oper_update;
 
216
  tool_class->cursor_update  = gimp_vector_tool_cursor_update;
 
217
 
 
218
  draw_tool_class->draw      = gimp_vector_tool_draw;
 
219
}
 
220
 
 
221
static void
 
222
gimp_vector_tool_init (GimpVectorTool *vector_tool)
 
223
{
 
224
  GimpTool *tool = GIMP_TOOL (vector_tool);
 
225
 
 
226
  gimp_tool_control_set_scroll_lock (tool->control, TRUE);
 
227
  gimp_tool_control_set_motion_mode (tool->control, GIMP_MOTION_MODE_COMPRESS);
 
228
  gimp_tool_control_set_tool_cursor (tool->control, GIMP_TOOL_CURSOR_PATHS);
 
229
 
 
230
  vector_tool->status_msg     = NULL;
 
231
 
 
232
  vector_tool->function       = VECTORS_CREATE_VECTOR;
 
233
  vector_tool->restriction    = GIMP_ANCHOR_FEATURE_NONE;
 
234
  vector_tool->modifier_lock  = FALSE;
 
235
  vector_tool->last_x         = 0.0;
 
236
  vector_tool->last_y         = 0.0;
 
237
  vector_tool->undo_motion    = FALSE;
 
238
  vector_tool->have_undo      = FALSE;
 
239
 
 
240
  vector_tool->cur_anchor     = NULL;
 
241
  vector_tool->cur_anchor2    = NULL;
 
242
  vector_tool->cur_stroke     = NULL;
 
243
  vector_tool->cur_position   = 0.0;
 
244
  vector_tool->cur_vectors    = NULL;
 
245
  vector_tool->vectors        = NULL;
 
246
 
 
247
  vector_tool->sel_count      = 0;
 
248
  vector_tool->sel_anchor     = NULL;
 
249
  vector_tool->sel_stroke     = NULL;
 
250
 
 
251
  vector_tool->saved_mode     = GIMP_VECTOR_MODE_DESIGN;
 
252
}
 
253
 
 
254
 
 
255
static void
 
256
gimp_vector_tool_control (GimpTool       *tool,
 
257
                          GimpToolAction  action,
 
258
                          GimpDisplay    *gdisp)
 
259
{
 
260
  GimpVectorTool *vector_tool = GIMP_VECTOR_TOOL (tool);
 
261
 
 
262
  switch (action)
 
263
    {
 
264
    case PAUSE:
 
265
      break;
 
266
 
 
267
    case RESUME:
 
268
      break;
 
269
 
 
270
    case HALT:
 
271
      gimp_vector_tool_set_vectors (vector_tool, NULL);
 
272
      gimp_vector_tool_status_set (tool, NULL, NULL);
 
273
      break;
 
274
 
 
275
    default:
 
276
      break;
 
277
    }
 
278
 
 
279
  GIMP_TOOL_CLASS (parent_class)->control (tool, action, gdisp);
 
280
}
 
281
 
 
282
static void
 
283
gimp_vector_tool_button_press (GimpTool        *tool,
 
284
                               GimpCoords      *coords,
 
285
                               guint32          time,
 
286
                               GdkModifierType  state,
 
287
                               GimpDisplay     *gdisp)
 
288
{
 
289
  GimpDrawTool      *draw_tool;
 
290
  GimpVectorTool    *vector_tool;
 
291
  GimpVectorOptions *options;
 
292
  GimpVectors       *vectors;
 
293
 
 
294
  draw_tool   = GIMP_DRAW_TOOL (tool);
 
295
  vector_tool = GIMP_VECTOR_TOOL (tool);
 
296
  options     = GIMP_VECTOR_OPTIONS (tool->tool_info->tool_options);
 
297
 
 
298
  /* do nothing if we are an FINISHED state */
 
299
  if (vector_tool->function == VECTORS_FINISHED)
 
300
    return;
 
301
 
 
302
  g_return_if_fail (vector_tool->vectors  != NULL                  ||
 
303
                    vector_tool->function == VECTORS_SELECT_VECTOR ||
 
304
                    vector_tool->function == VECTORS_CREATE_VECTOR);
 
305
 
 
306
  vector_tool->undo_motion = FALSE;
 
307
 
 
308
  /* Save the current modifier state */
 
309
 
 
310
  vector_tool->saved_state = state;
 
311
 
 
312
  gimp_draw_tool_pause (draw_tool);
 
313
 
 
314
  if (gimp_draw_tool_is_active (draw_tool) && draw_tool->gdisp != gdisp)
 
315
    {
 
316
      gimp_draw_tool_stop (draw_tool);
 
317
    }
 
318
 
 
319
  gimp_tool_control_activate (tool->control);
 
320
  tool->gdisp = gdisp;
 
321
 
 
322
  /* select a vectors object */
 
323
 
 
324
  if (vector_tool->function == VECTORS_SELECT_VECTOR)
 
325
    {
 
326
      if (gimp_draw_tool_on_vectors (draw_tool, gdisp, coords, TARGET, TARGET,
 
327
                                     NULL, NULL, NULL, NULL, NULL, &vectors))
 
328
        {
 
329
          gimp_vector_tool_set_vectors (vector_tool, vectors);
 
330
          gimp_image_set_active_vectors (gdisp->gimage, vectors);
 
331
        }
 
332
      vector_tool->function = VECTORS_FINISHED;
 
333
    }
 
334
 
 
335
  /* create a new vector from scratch */
 
336
 
 
337
  if (vector_tool->function == VECTORS_CREATE_VECTOR)
 
338
    {
 
339
      vectors = gimp_vectors_new (gdisp->gimage, _("Unnamed"));
 
340
 
 
341
      /* Undo step gets added implicitely */
 
342
      vector_tool->have_undo = TRUE;
 
343
 
 
344
      vector_tool->undo_motion = TRUE;
 
345
 
 
346
      gimp_image_add_vectors (gdisp->gimage, vectors, -1);
 
347
      gimp_image_flush (gdisp->gimage);
 
348
 
 
349
      gimp_vector_tool_set_vectors (vector_tool, vectors);
 
350
 
 
351
      vector_tool->function = VECTORS_CREATE_STROKE;
 
352
 
 
353
    }
 
354
 
 
355
  gimp_vectors_freeze (vector_tool->vectors);
 
356
 
 
357
  /* create a new stroke */
 
358
 
 
359
  if (vector_tool->function == VECTORS_CREATE_STROKE)
 
360
    {
 
361
      g_return_if_fail (vector_tool->vectors != NULL);
 
362
 
 
363
      gimp_vector_tool_undo_push (vector_tool, _("Add Stroke"));
 
364
 
 
365
      vector_tool->cur_stroke = gimp_bezier_stroke_new ();
 
366
      gimp_vectors_stroke_add (vector_tool->vectors, vector_tool->cur_stroke);
 
367
 
 
368
      vector_tool->undo_motion = TRUE;
 
369
 
 
370
      vector_tool->sel_stroke = vector_tool->cur_stroke;
 
371
      vector_tool->cur_anchor = NULL;
 
372
      vector_tool->sel_anchor = NULL;
 
373
      vector_tool->function = VECTORS_ADD_ANCHOR;
 
374
    }
 
375
 
 
376
 
 
377
  /* add an anchor to an existing stroke */
 
378
 
 
379
  if (vector_tool->function == VECTORS_ADD_ANCHOR)
 
380
    {
 
381
      gimp_vector_tool_undo_push (vector_tool, _("Add Anchor"));
 
382
 
 
383
      vector_tool->undo_motion = TRUE;
 
384
 
 
385
      vector_tool->cur_anchor =
 
386
                     gimp_bezier_stroke_extend (vector_tool->sel_stroke, coords,
 
387
                                                vector_tool->sel_anchor,
 
388
                                                EXTEND_EDITABLE);
 
389
 
 
390
      vector_tool->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC;
 
391
 
 
392
      if (!options->polygonal)
 
393
        vector_tool->function = VECTORS_MOVE_HANDLE;
 
394
      else
 
395
        vector_tool->function = VECTORS_MOVE_ANCHOR;
 
396
      vector_tool->cur_stroke = vector_tool->sel_stroke;
 
397
    }
 
398
 
 
399
 
 
400
  /* Insertion of an anchor in a curve segment */
 
401
 
 
402
  if (vector_tool->function == VECTORS_INSERT_ANCHOR)
 
403
    {
 
404
      gimp_vector_tool_undo_push (vector_tool, _("Insert Anchor"));
 
405
 
 
406
      vector_tool->undo_motion = TRUE;
 
407
 
 
408
      vector_tool->cur_anchor =
 
409
                         gimp_stroke_anchor_insert (vector_tool->cur_stroke,
 
410
                                                    vector_tool->cur_anchor,
 
411
                                                    vector_tool->cur_position);
 
412
      if (vector_tool->cur_anchor)
 
413
        {
 
414
          if (options->polygonal)
 
415
            {
 
416
              gimp_stroke_anchor_convert (vector_tool->cur_stroke,
 
417
                                          vector_tool->cur_anchor,
 
418
                                          GIMP_ANCHOR_FEATURE_EDGE);
 
419
            }
 
420
          vector_tool->function = VECTORS_MOVE_ANCHOR;
 
421
        }
 
422
      else
 
423
        {
 
424
          vector_tool->function = VECTORS_FINISHED;
 
425
        }
 
426
    }
 
427
 
 
428
 
 
429
  /* move a handle */
 
430
 
 
431
  if (vector_tool->function == VECTORS_MOVE_HANDLE)
 
432
    {
 
433
      gimp_vector_tool_undo_push (vector_tool, _("Drag Handle"));
 
434
 
 
435
      if (vector_tool->cur_anchor->type == GIMP_ANCHOR_ANCHOR)
 
436
        {
 
437
          if (!vector_tool->cur_anchor->selected)
 
438
            {
 
439
              gimp_vectors_anchor_select (vector_tool->vectors,
 
440
                                          vector_tool->cur_stroke,
 
441
                                          vector_tool->cur_anchor,
 
442
                                          TRUE, TRUE);
 
443
              vector_tool->undo_motion = TRUE;
 
444
            }
 
445
 
 
446
          gimp_draw_tool_on_vectors_handle (GIMP_DRAW_TOOL (tool), gdisp,
 
447
                                            vector_tool->vectors, coords,
 
448
                                            TARGET, TARGET,
 
449
                                            GIMP_ANCHOR_CONTROL, TRUE,
 
450
                                            &vector_tool->cur_anchor,
 
451
                                            &vector_tool->cur_stroke);
 
452
          if (!vector_tool->cur_anchor)
 
453
            vector_tool->function = VECTORS_FINISHED;
 
454
        }
 
455
    }
 
456
 
 
457
 
 
458
  /* move an anchor */
 
459
 
 
460
  if (vector_tool->function == VECTORS_MOVE_ANCHOR)
 
461
    {
 
462
      gimp_vector_tool_undo_push (vector_tool, _("Drag Anchor"));
 
463
 
 
464
      if (!vector_tool->cur_anchor->selected)
 
465
        {
 
466
          gimp_vectors_anchor_select (vector_tool->vectors,
 
467
                                      vector_tool->cur_stroke,
 
468
                                      vector_tool->cur_anchor,
 
469
                                      TRUE, TRUE);
 
470
          vector_tool->undo_motion = TRUE;
 
471
        }
 
472
    }
 
473
 
 
474
 
 
475
  /* move multiple anchors */
 
476
 
 
477
  if (vector_tool->function == VECTORS_MOVE_ANCHORSET)
 
478
    {
 
479
      gimp_vector_tool_undo_push (vector_tool, _("Drag Anchors"));
 
480
 
 
481
      if (state & TOGGLE_MASK)
 
482
        {
 
483
          gimp_vectors_anchor_select (vector_tool->vectors,
 
484
                                      vector_tool->cur_stroke,
 
485
                                      vector_tool->cur_anchor,
 
486
                                      !vector_tool->cur_anchor->selected,
 
487
                                      FALSE);
 
488
          vector_tool->undo_motion = TRUE;
 
489
          if (vector_tool->cur_anchor->selected == FALSE)
 
490
            vector_tool->function = VECTORS_FINISHED;
 
491
        }
 
492
    }
 
493
 
 
494
 
 
495
  /* move a curve segment directly */
 
496
 
 
497
  if (vector_tool->function == VECTORS_MOVE_CURVE)
 
498
    {
 
499
      gimp_vector_tool_undo_push (vector_tool, _("Drag Curve"));
 
500
 
 
501
      /* the magic numbers are taken from the "feel good" parameter
 
502
       * from gimp_bezier_stroke_point_move_relative in gimpbezierstroke.c. */
 
503
      if (vector_tool->cur_position < 5.0 / 6.0)
 
504
        {
 
505
          gimp_vectors_anchor_select (vector_tool->vectors,
 
506
                                      vector_tool->cur_stroke,
 
507
                                      vector_tool->cur_anchor, TRUE, TRUE);
 
508
          vector_tool->undo_motion = TRUE;
 
509
        }
 
510
 
 
511
      if (vector_tool->cur_position > 1.0 / 6.0)
 
512
        {
 
513
          gimp_vectors_anchor_select (vector_tool->vectors,
 
514
                                      vector_tool->cur_stroke,
 
515
                                      vector_tool->cur_anchor2, TRUE,
 
516
                                      (vector_tool->cur_position >= 5.0 / 6.0));
 
517
          vector_tool->undo_motion = TRUE;
 
518
        }
 
519
 
 
520
    }
 
521
 
 
522
 
 
523
  /* connect two strokes */
 
524
 
 
525
  if (vector_tool->function == VECTORS_CONNECT_STROKES)
 
526
    {
 
527
      gimp_vector_tool_undo_push (vector_tool, _("Connect Strokes"));
 
528
 
 
529
      gimp_stroke_connect_stroke (vector_tool->sel_stroke,
 
530
                                  vector_tool->sel_anchor,
 
531
                                  vector_tool->cur_stroke,
 
532
                                  vector_tool->cur_anchor);
 
533
      vector_tool->undo_motion = TRUE;
 
534
 
 
535
      if (vector_tool->cur_stroke != vector_tool->sel_stroke &&
 
536
          gimp_stroke_is_empty (vector_tool->cur_stroke))
 
537
        {
 
538
          gimp_vectors_stroke_remove (vector_tool->vectors,
 
539
                                      vector_tool->cur_stroke);
 
540
        }
 
541
      vector_tool->sel_anchor = vector_tool->cur_anchor;
 
542
      vector_tool->cur_stroke = vector_tool->sel_stroke;
 
543
 
 
544
      gimp_vectors_anchor_select (vector_tool->vectors,
 
545
                                  vector_tool->sel_stroke,
 
546
                                  vector_tool->sel_anchor, TRUE, TRUE);
 
547
 
 
548
      vector_tool->function = VECTORS_FINISHED;
 
549
    }
 
550
 
 
551
 
 
552
  /* move a stroke or all strokes of a vectors object */
 
553
 
 
554
  if (vector_tool->function == VECTORS_MOVE_STROKE ||
 
555
      vector_tool->function == VECTORS_MOVE_VECTORS)
 
556
    {
 
557
      gimp_vector_tool_undo_push (vector_tool, _("Drag Path"));
 
558
 
 
559
      /* Work is being done in gimp_vector_tool_motion ()... */
 
560
    }
 
561
 
 
562
 
 
563
  /* convert an anchor to something that looks like an edge */
 
564
 
 
565
  if (vector_tool->function == VECTORS_CONVERT_EDGE)
 
566
    {
 
567
      gimp_vector_tool_undo_push (vector_tool, _("Convert Edge"));
 
568
 
 
569
      gimp_stroke_anchor_convert (vector_tool->cur_stroke,
 
570
                                  vector_tool->cur_anchor,
 
571
                                  GIMP_ANCHOR_FEATURE_EDGE);
 
572
      vector_tool->undo_motion = TRUE;
 
573
 
 
574
      if (vector_tool->cur_anchor->type == GIMP_ANCHOR_ANCHOR)
 
575
        {
 
576
          gimp_vectors_anchor_select (vector_tool->vectors,
 
577
                                      vector_tool->cur_stroke,
 
578
                                      vector_tool->cur_anchor, TRUE, TRUE);
 
579
 
 
580
          vector_tool->function = VECTORS_MOVE_ANCHOR;
 
581
        }
 
582
      else
 
583
        {
 
584
          vector_tool->cur_stroke = NULL;
 
585
          vector_tool->cur_anchor = NULL;
 
586
 
 
587
          /* avoid doing anything stupid */
 
588
          vector_tool->function = VECTORS_FINISHED;
 
589
        }
 
590
    }
 
591
 
 
592
 
 
593
  /* removal of a node in a stroke */
 
594
 
 
595
  if (vector_tool->function == VECTORS_DELETE_ANCHOR)
 
596
    {
 
597
      gimp_vector_tool_undo_push (vector_tool, _("Delete Anchor"));
 
598
 
 
599
      gimp_stroke_anchor_delete (vector_tool->cur_stroke,
 
600
                                 vector_tool->cur_anchor);
 
601
      vector_tool->undo_motion = TRUE;
 
602
 
 
603
      if (gimp_stroke_is_empty (vector_tool->cur_stroke))
 
604
        gimp_vectors_stroke_remove (vector_tool->vectors,
 
605
                                    vector_tool->cur_stroke);
 
606
 
 
607
      vector_tool->cur_stroke = NULL;
 
608
      vector_tool->cur_anchor = NULL;
 
609
      vector_tool->function = VECTORS_FINISHED;
 
610
    }
 
611
 
 
612
 
 
613
  /* deleting a segment (opening up a stroke) */
 
614
 
 
615
  if (vector_tool->function == VECTORS_DELETE_SEGMENT)
 
616
    {
 
617
      GimpStroke *new_stroke;
 
618
 
 
619
      gimp_vector_tool_undo_push (vector_tool, _("Delete Segment"));
 
620
 
 
621
      new_stroke = gimp_stroke_open (vector_tool->cur_stroke,
 
622
                                     vector_tool->cur_anchor);
 
623
      if (new_stroke)
 
624
        gimp_vectors_stroke_add (vector_tool->vectors, new_stroke);
 
625
 
 
626
      vector_tool->undo_motion = TRUE;
 
627
      vector_tool->cur_stroke = NULL;
 
628
      vector_tool->cur_anchor = NULL;
 
629
      vector_tool->function = VECTORS_FINISHED;
 
630
    }
 
631
 
 
632
  vector_tool->last_x = coords->x;
 
633
  vector_tool->last_y = coords->y;
 
634
 
 
635
  gimp_vectors_thaw (vector_tool->vectors);
 
636
 
 
637
  if (! gimp_draw_tool_is_active (draw_tool))
 
638
    {
 
639
      gimp_draw_tool_start (draw_tool, gdisp);
 
640
    }
 
641
 
 
642
  gimp_draw_tool_resume (draw_tool);
 
643
}
 
644
 
 
645
static void
 
646
gimp_vector_tool_button_release (GimpTool        *tool,
 
647
                                 GimpCoords      *coords,
 
648
                                 guint32          time,
 
649
                                 GdkModifierType  state,
 
650
                                 GimpDisplay     *gdisp)
 
651
{
 
652
  GimpVectorTool *vector_tool = GIMP_VECTOR_TOOL (tool);
 
653
 
 
654
  vector_tool->function = VECTORS_FINISHED;
 
655
 
 
656
  if (vector_tool->have_undo &&
 
657
      (! vector_tool->undo_motion || (state & GDK_BUTTON3_MASK)))
 
658
    {
 
659
      GimpUndo            *undo;
 
660
      GimpUndoAccumulator  accum = { 0, };
 
661
 
 
662
      undo = gimp_undo_stack_pop_undo (gdisp->gimage->undo_stack,
 
663
                                       GIMP_UNDO_MODE_UNDO, &accum);
 
664
 
 
665
      gimp_image_undo_event (gdisp->gimage, GIMP_UNDO_EVENT_UNDO_EXPIRED, undo);
 
666
 
 
667
      gimp_undo_free (undo, GIMP_UNDO_MODE_UNDO);
 
668
      g_object_unref (undo);
 
669
    }
 
670
 
 
671
  vector_tool->have_undo = FALSE;
 
672
  vector_tool->undo_motion = FALSE;
 
673
 
 
674
  gimp_tool_control_halt (tool->control);
 
675
  gimp_image_flush (gdisp->gimage);
 
676
}
 
677
 
 
678
static void
 
679
gimp_vector_tool_motion (GimpTool        *tool,
 
680
                         GimpCoords      *coords,
 
681
                         guint32          time,
 
682
                         GdkModifierType  state,
 
683
                         GimpDisplay     *gdisp)
 
684
{
 
685
  GimpVectorTool    *vector_tool;
 
686
  GimpVectorOptions *options;
 
687
  GimpAnchor        *anchor;
 
688
 
 
689
  vector_tool = GIMP_VECTOR_TOOL (tool);
 
690
  options     = GIMP_VECTOR_OPTIONS (tool->tool_info->tool_options);
 
691
 
 
692
  if (vector_tool->function == VECTORS_FINISHED)
 
693
    return;
 
694
 
 
695
  gimp_vectors_freeze (vector_tool->vectors);
 
696
 
 
697
  if ((vector_tool->saved_state & TOGGLE_MASK) != (state & TOGGLE_MASK))
 
698
    vector_tool->modifier_lock = FALSE;
 
699
 
 
700
  if (!vector_tool->modifier_lock)
 
701
    {
 
702
      if (state & TOGGLE_MASK)
 
703
        {
 
704
          vector_tool->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC;
 
705
        }
 
706
      else
 
707
        {
 
708
          vector_tool->restriction = GIMP_ANCHOR_FEATURE_NONE;
 
709
        }
 
710
    }
 
711
 
 
712
  switch (vector_tool->function)
 
713
    {
 
714
    case VECTORS_MOVE_ANCHOR:
 
715
    case VECTORS_MOVE_HANDLE:
 
716
      anchor = vector_tool->cur_anchor;
 
717
 
 
718
      if (anchor)
 
719
        {
 
720
          gimp_stroke_anchor_move_absolute (vector_tool->cur_stroke,
 
721
                                            vector_tool->cur_anchor,
 
722
                                            coords, vector_tool->restriction);
 
723
          vector_tool->undo_motion = TRUE;
 
724
        }
 
725
      break;
 
726
 
 
727
    case VECTORS_MOVE_CURVE:
 
728
      if (options->polygonal)
 
729
        {
 
730
          gimp_vector_tool_move_selected_anchors (vector_tool,
 
731
                                               coords->x - vector_tool->last_x,
 
732
                                               coords->y - vector_tool->last_y);
 
733
          vector_tool->undo_motion = TRUE;
 
734
        }
 
735
      else
 
736
        {
 
737
          gimp_stroke_point_move_absolute (vector_tool->cur_stroke,
 
738
                                           vector_tool->cur_anchor,
 
739
                                           vector_tool->cur_position,
 
740
                                           coords, vector_tool->restriction);
 
741
          vector_tool->undo_motion = TRUE;
 
742
        }
 
743
      break;
 
744
 
 
745
    case VECTORS_MOVE_ANCHORSET:
 
746
      gimp_vector_tool_move_selected_anchors (vector_tool,
 
747
                                              coords->x - vector_tool->last_x,
 
748
                                              coords->y - vector_tool->last_y);
 
749
      vector_tool->undo_motion = TRUE;
 
750
      break;
 
751
 
 
752
    case VECTORS_MOVE_STROKE:
 
753
      if (vector_tool->cur_stroke)
 
754
        {
 
755
          gimp_stroke_translate (vector_tool->cur_stroke,
 
756
                                 coords->x - vector_tool->last_x,
 
757
                                 coords->y - vector_tool->last_y);
 
758
          vector_tool->undo_motion = TRUE;
 
759
        }
 
760
      else if (vector_tool->sel_stroke)
 
761
        {
 
762
          gimp_stroke_translate (vector_tool->sel_stroke,
 
763
                                 coords->x - vector_tool->last_x,
 
764
                                 coords->y - vector_tool->last_y);
 
765
          vector_tool->undo_motion = TRUE;
 
766
        }
 
767
      break;
 
768
 
 
769
    case VECTORS_MOVE_VECTORS:
 
770
      gimp_item_translate (GIMP_ITEM (vector_tool->vectors),
 
771
                           coords->x - vector_tool->last_x,
 
772
                           coords->y - vector_tool->last_y, FALSE);
 
773
      vector_tool->undo_motion = TRUE;
 
774
      break;
 
775
 
 
776
    default:
 
777
      break;
 
778
    }
 
779
 
 
780
  vector_tool->last_x = coords->x;
 
781
  vector_tool->last_y = coords->y;
 
782
 
 
783
  gimp_vectors_thaw (vector_tool->vectors);
 
784
}
 
785
 
 
786
static gboolean
 
787
gimp_vector_tool_key_press (GimpTool     *tool,
 
788
                            GdkEventKey  *kevent,
 
789
                            GimpDisplay  *gdisp)
 
790
{
 
791
  GimpVectorTool    *vector_tool = GIMP_VECTOR_TOOL (tool);
 
792
  GimpDrawTool      *draw_tool   = GIMP_DRAW_TOOL (tool);
 
793
  GimpVectorOptions *options;
 
794
 
 
795
  GimpDisplayShell  *shell;
 
796
  gdouble            xdist, ydist;
 
797
  gdouble            pixels = 1.0;
 
798
 
 
799
  if (! vector_tool->vectors)
 
800
    return FALSE;
 
801
 
 
802
  shell = GIMP_DISPLAY_SHELL (draw_tool->gdisp->shell);
 
803
 
 
804
  if (kevent->state & GDK_SHIFT_MASK)
 
805
    pixels = 10.0;
 
806
 
 
807
  if (kevent->state & GDK_CONTROL_MASK)
 
808
    pixels = 50.0;
 
809
 
 
810
  if (gdisp == draw_tool->gdisp)
 
811
    {
 
812
      switch (kevent->keyval)
 
813
        {
 
814
        case GDK_KP_Enter:
 
815
        case GDK_Return:
 
816
          gimp_vector_tool_to_selection_extended (vector_tool, kevent->state);
 
817
          break;
 
818
 
 
819
        case GDK_BackSpace:
 
820
        case GDK_Delete:
 
821
          gimp_vector_tool_delete_selected_anchors (vector_tool);
 
822
          break;
 
823
 
 
824
        case GDK_Left:
 
825
        case GDK_Right:
 
826
        case GDK_Up:
 
827
        case GDK_Down:
 
828
          xdist = FUNSCALEX (shell, pixels);
 
829
          ydist = FUNSCALEY (shell, pixels);
 
830
 
 
831
          gimp_vector_tool_undo_push (vector_tool, _("Move Anchors"));
 
832
 
 
833
          gimp_vectors_freeze (vector_tool->vectors);
 
834
 
 
835
          switch (kevent->keyval)
 
836
            {
 
837
            case GDK_Left:
 
838
              gimp_vector_tool_move_selected_anchors (vector_tool, -xdist, 0);
 
839
              break;
 
840
 
 
841
            case GDK_Right:
 
842
              gimp_vector_tool_move_selected_anchors (vector_tool, xdist, 0);
 
843
              break;
 
844
 
 
845
            case GDK_Up:
 
846
              gimp_vector_tool_move_selected_anchors (vector_tool, 0, -ydist);
 
847
              break;
 
848
 
 
849
            case GDK_Down:
 
850
              gimp_vector_tool_move_selected_anchors (vector_tool, 0, ydist);
 
851
              break;
 
852
 
 
853
            default:
 
854
              break;
 
855
            }
 
856
 
 
857
          gimp_vectors_thaw (vector_tool->vectors);
 
858
          vector_tool->have_undo = FALSE;
 
859
          break;
 
860
 
 
861
        case GDK_Escape:
 
862
          options = GIMP_VECTOR_OPTIONS (tool->tool_info->tool_options);
 
863
 
 
864
          if (options->edit_mode != GIMP_VECTOR_MODE_DESIGN)
 
865
            g_object_set (options, "vectors-edit-mode",
 
866
                          GIMP_VECTOR_MODE_DESIGN, NULL);
 
867
          break;
 
868
 
 
869
        default:
 
870
          return FALSE;
 
871
        }
 
872
 
 
873
      gimp_image_flush (gdisp->gimage);
 
874
    }
 
875
 
 
876
  return TRUE;
 
877
}
 
878
 
 
879
static void
 
880
gimp_vector_tool_modifier_key (GimpTool        *tool,
 
881
                               GdkModifierType  key,
 
882
                               gboolean         press,
 
883
                               GdkModifierType  state,
 
884
                               GimpDisplay     *gdisp)
 
885
{
 
886
  GimpVectorTool    *vector_tool = GIMP_VECTOR_TOOL (tool);
 
887
  GimpVectorOptions *options;
 
888
 
 
889
  options = GIMP_VECTOR_OPTIONS (tool->tool_info->tool_options);
 
890
 
 
891
  if (key == TOGGLE_MASK)
 
892
    return;
 
893
 
 
894
  if (key == INSDEL_MASK || key == MOVE_MASK)
 
895
    {
 
896
      GimpVectorMode button_mode;
 
897
 
 
898
      button_mode = options->edit_mode;
 
899
 
 
900
      if (press)
 
901
        {
 
902
          if (key == (state & (INSDEL_MASK | MOVE_MASK)))
 
903
            {
 
904
              /*  first modifier pressed  */
 
905
 
 
906
              vector_tool->saved_mode = options->edit_mode;
 
907
            }
 
908
        }
 
909
      else
 
910
        {
 
911
          if (! (state & (INSDEL_MASK | MOVE_MASK)))
 
912
            {
 
913
              /*  last modifier released  */
 
914
 
 
915
              button_mode = vector_tool->saved_mode;
 
916
            }
 
917
        }
 
918
 
 
919
      if (state & MOVE_MASK)
 
920
        {
 
921
          button_mode = GIMP_VECTOR_MODE_MOVE;
 
922
        }
 
923
      else if (state & INSDEL_MASK)
 
924
        {
 
925
          button_mode = GIMP_VECTOR_MODE_EDIT;
 
926
        }
 
927
 
 
928
      if (button_mode != options->edit_mode)
 
929
        {
 
930
          g_object_set (options, "vectors-edit-mode", button_mode, NULL);
 
931
        }
 
932
    }
 
933
}
 
934
 
 
935
static void
 
936
gimp_vector_tool_oper_update (GimpTool        *tool,
 
937
                              GimpCoords      *coords,
 
938
                              GdkModifierType  state,
 
939
                              GimpDisplay     *gdisp)
 
940
{
 
941
  GimpVectorTool    *vector_tool;
 
942
  GimpDrawTool      *draw_tool;
 
943
  GimpVectorOptions *options;
 
944
  GimpAnchor        *anchor     = NULL;
 
945
  GimpAnchor        *anchor2    = NULL;
 
946
  GimpStroke        *stroke     = NULL;
 
947
  gdouble            position   = -1;
 
948
  gboolean           on_handle  = FALSE;
 
949
  gboolean           on_curve   = FALSE;
 
950
  gboolean           on_vectors = FALSE;
 
951
 
 
952
  vector_tool = GIMP_VECTOR_TOOL (tool);
 
953
  options     = GIMP_VECTOR_OPTIONS (tool->tool_info->tool_options);
 
954
 
 
955
  draw_tool = GIMP_DRAW_TOOL (tool);
 
956
 
 
957
  vector_tool->modifier_lock = FALSE;
 
958
 
 
959
  /* are we hovering the current vectors on the current display? */
 
960
  if (vector_tool->vectors && GIMP_DRAW_TOOL (tool)->gdisp == gdisp)
 
961
    {
 
962
      on_handle = gimp_draw_tool_on_vectors_handle (GIMP_DRAW_TOOL (tool),
 
963
                                                    gdisp,
 
964
                                                    vector_tool->vectors,
 
965
                                                    coords,
 
966
                                                    TARGET, TARGET,
 
967
                                                    GIMP_ANCHOR_ANCHOR,
 
968
                                                    vector_tool->sel_count > 2,
 
969
                                                    &anchor, &stroke);
 
970
 
 
971
      if (! on_handle)
 
972
        on_curve = gimp_draw_tool_on_vectors_curve (GIMP_DRAW_TOOL (tool),
 
973
                                                    gdisp,
 
974
                                                    vector_tool->vectors,
 
975
                                                    coords,
 
976
                                                    TARGET, TARGET,
 
977
                                                    NULL,
 
978
                                                    &position, &anchor,
 
979
                                                    &anchor2, &stroke);
 
980
    }
 
981
 
 
982
  if (on_handle || on_curve)
 
983
    {
 
984
      vector_tool->cur_vectors = NULL;
 
985
    }
 
986
  else
 
987
    {
 
988
      on_vectors = gimp_draw_tool_on_vectors (draw_tool, gdisp, coords,
 
989
                                              TARGET, TARGET,
 
990
                                              NULL, NULL, NULL, NULL, NULL,
 
991
                                              &(vector_tool->cur_vectors));
 
992
    }
 
993
 
 
994
  vector_tool->cur_position   = position;
 
995
  vector_tool->cur_anchor     = anchor;
 
996
  vector_tool->cur_anchor2    = anchor2;
 
997
  vector_tool->cur_stroke     = stroke;
 
998
 
 
999
  switch (options->edit_mode)
 
1000
    {
 
1001
    case GIMP_VECTOR_MODE_DESIGN:
 
1002
      if (! vector_tool->vectors || GIMP_DRAW_TOOL (tool)->gdisp != gdisp)
 
1003
        {
 
1004
          if (on_vectors)
 
1005
            {
 
1006
              vector_tool->function = VECTORS_SELECT_VECTOR;
 
1007
            }
 
1008
          else
 
1009
            {
 
1010
              vector_tool->function = VECTORS_CREATE_VECTOR;
 
1011
              vector_tool->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC;
 
1012
              vector_tool->modifier_lock = TRUE;
 
1013
            }
 
1014
        }
 
1015
      else if (on_handle)
 
1016
        {
 
1017
          if (anchor->type == GIMP_ANCHOR_ANCHOR)
 
1018
            {
 
1019
              if (state & TOGGLE_MASK)
 
1020
                {
 
1021
                  vector_tool->function = VECTORS_MOVE_ANCHORSET;
 
1022
                }
 
1023
              else
 
1024
                {
 
1025
                  if (vector_tool->sel_count >= 2 && anchor->selected)
 
1026
                    vector_tool->function = VECTORS_MOVE_ANCHORSET;
 
1027
                  else
 
1028
                    vector_tool->function = VECTORS_MOVE_ANCHOR;
 
1029
                }
 
1030
            }
 
1031
          else
 
1032
            {
 
1033
              vector_tool->function = VECTORS_MOVE_HANDLE;
 
1034
              if (state & TOGGLE_MASK)
 
1035
                vector_tool->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC;
 
1036
              else
 
1037
                vector_tool->restriction = GIMP_ANCHOR_FEATURE_NONE;
 
1038
            }
 
1039
        }
 
1040
      else if (on_curve)
 
1041
        {
 
1042
          if (gimp_stroke_point_is_movable (stroke, anchor, position))
 
1043
            {
 
1044
              vector_tool->function = VECTORS_MOVE_CURVE;
 
1045
              if (state & TOGGLE_MASK)
 
1046
                vector_tool->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC;
 
1047
              else
 
1048
                vector_tool->restriction = GIMP_ANCHOR_FEATURE_NONE;
 
1049
            }
 
1050
          else
 
1051
            {
 
1052
              vector_tool->function = VECTORS_FINISHED;
 
1053
            }
 
1054
        }
 
1055
      else
 
1056
        {
 
1057
          if (vector_tool->sel_stroke && vector_tool->sel_anchor &&
 
1058
              gimp_stroke_is_extendable (vector_tool->sel_stroke,
 
1059
                                         vector_tool->sel_anchor) &&
 
1060
              !(state & TOGGLE_MASK))
 
1061
            vector_tool->function = VECTORS_ADD_ANCHOR;
 
1062
          else
 
1063
            vector_tool->function = VECTORS_CREATE_STROKE;
 
1064
 
 
1065
          vector_tool->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC;
 
1066
          vector_tool->modifier_lock = TRUE;
 
1067
        }
 
1068
 
 
1069
      break;
 
1070
 
 
1071
    case GIMP_VECTOR_MODE_EDIT:
 
1072
      if (! vector_tool->vectors || GIMP_DRAW_TOOL (tool)->gdisp != gdisp)
 
1073
        {
 
1074
          if (on_vectors)
 
1075
            {
 
1076
              vector_tool->function = VECTORS_SELECT_VECTOR;
 
1077
            }
 
1078
          else
 
1079
            {
 
1080
              vector_tool->function = VECTORS_FINISHED;
 
1081
            }
 
1082
        }
 
1083
      else if (on_handle)
 
1084
        {
 
1085
          if (anchor->type == GIMP_ANCHOR_ANCHOR)
 
1086
            {
 
1087
              if (!(state & TOGGLE_MASK) && vector_tool->sel_anchor &&
 
1088
                  vector_tool->sel_anchor != anchor &&
 
1089
                  gimp_stroke_is_extendable (vector_tool->sel_stroke,
 
1090
                                             vector_tool->sel_anchor) &&
 
1091
                  gimp_stroke_is_extendable (stroke, anchor))
 
1092
                {
 
1093
                  vector_tool->function = VECTORS_CONNECT_STROKES;
 
1094
                }
 
1095
              else
 
1096
                {
 
1097
                  if (state & TOGGLE_MASK)
 
1098
                    {
 
1099
                      vector_tool->function = VECTORS_DELETE_ANCHOR;
 
1100
                    }
 
1101
                  else
 
1102
                    {
 
1103
                      if (options->polygonal)
 
1104
                        vector_tool->function = VECTORS_MOVE_ANCHOR;
 
1105
                      else
 
1106
                        vector_tool->function = VECTORS_MOVE_HANDLE;
 
1107
                    }
 
1108
                }
 
1109
            }
 
1110
          else
 
1111
            {
 
1112
              if (state & TOGGLE_MASK)
 
1113
                vector_tool->function = VECTORS_CONVERT_EDGE;
 
1114
              else
 
1115
                vector_tool->function = VECTORS_MOVE_HANDLE;
 
1116
            }
 
1117
        }
 
1118
      else if (on_curve)
 
1119
        {
 
1120
          if (state & TOGGLE_MASK)
 
1121
            {
 
1122
              vector_tool->function = VECTORS_DELETE_SEGMENT;
 
1123
            }
 
1124
          else if (gimp_stroke_anchor_is_insertable (stroke, anchor, position))
 
1125
            {
 
1126
              vector_tool->function = VECTORS_INSERT_ANCHOR;
 
1127
            }
 
1128
          else
 
1129
            {
 
1130
              vector_tool->function = VECTORS_FINISHED;
 
1131
            }
 
1132
        }
 
1133
      else
 
1134
        {
 
1135
          vector_tool->function = VECTORS_FINISHED;
 
1136
        }
 
1137
 
 
1138
      break;
 
1139
 
 
1140
    case GIMP_VECTOR_MODE_MOVE:
 
1141
      if (! vector_tool->vectors || GIMP_DRAW_TOOL (tool)->gdisp != gdisp)
 
1142
        {
 
1143
          if (on_vectors)
 
1144
            {
 
1145
              vector_tool->function = VECTORS_SELECT_VECTOR;
 
1146
            }
 
1147
          else
 
1148
            {
 
1149
              vector_tool->function = VECTORS_FINISHED;
 
1150
            }
 
1151
        }
 
1152
      else if (on_handle || on_curve)
 
1153
        {
 
1154
          if (state & TOGGLE_MASK)
 
1155
            {
 
1156
              vector_tool->function = VECTORS_MOVE_VECTORS;
 
1157
            }
 
1158
          else
 
1159
            {
 
1160
              vector_tool->function = VECTORS_MOVE_STROKE;
 
1161
            }
 
1162
        }
 
1163
      else
 
1164
        {
 
1165
          if (on_vectors)
 
1166
            {
 
1167
              vector_tool->function = VECTORS_SELECT_VECTOR;
 
1168
            }
 
1169
          else
 
1170
            {
 
1171
              vector_tool->function = VECTORS_MOVE_VECTORS;
 
1172
            }
 
1173
        }
 
1174
      break;
 
1175
    }
 
1176
 
 
1177
  gimp_vector_tool_status_update (tool, gdisp);
 
1178
}
 
1179
 
 
1180
 
 
1181
static void
 
1182
gimp_vector_tool_status_update (GimpTool    *tool,
 
1183
                                GimpDisplay *gdisp)
 
1184
{
 
1185
  GimpVectorTool   *vector_tool = GIMP_VECTOR_TOOL (tool);
 
1186
  GimpDisplayShell *shell;
 
1187
  const gchar      *new_status  = NULL;
 
1188
 
 
1189
  shell = tool->gdisp ? GIMP_DISPLAY_SHELL (tool->gdisp->shell) : NULL;
 
1190
 
 
1191
  if (shell && shell->proximity)
 
1192
    {
 
1193
      switch (vector_tool->function)
 
1194
      {
 
1195
        case VECTORS_SELECT_VECTOR:
 
1196
          new_status = _("Click to pick path to edit.");
 
1197
          break;
 
1198
        case VECTORS_CREATE_VECTOR:
 
1199
          new_status = _("Click to create a new path.");
 
1200
          break;
 
1201
        case VECTORS_CREATE_STROKE:
 
1202
          new_status = _("Click to create a new component of the path.");
 
1203
          break;
 
1204
        case VECTORS_ADD_ANCHOR:
 
1205
          new_status = _("Click to create a new anchor. (try SHIFT)");
 
1206
          break;
 
1207
        case VECTORS_MOVE_ANCHOR:
 
1208
          new_status = _("Click-Drag to move the anchor around.");
 
1209
          break;
 
1210
        case VECTORS_MOVE_ANCHORSET:
 
1211
          new_status = _("Click-Drag to move the anchors around.");
 
1212
          break;
 
1213
        case VECTORS_MOVE_HANDLE:
 
1214
          new_status = _("Click-Drag to move the handle around. (try SHIFT)");
 
1215
          break;
 
1216
        case VECTORS_MOVE_CURVE:
 
1217
          new_status = _("Click-Drag to change the shape of the curve. "
 
1218
                         "(SHIFT: symmetrical)");
 
1219
          break;
 
1220
        case VECTORS_MOVE_STROKE:
 
1221
          new_status = _("Click-Drag to move the component around. "
 
1222
                         "(try SHIFT)");
 
1223
          break;
 
1224
        case VECTORS_MOVE_VECTORS:
 
1225
          new_status = _("Click-Drag to move the path around.");
 
1226
          break;
 
1227
        case VECTORS_INSERT_ANCHOR:
 
1228
          new_status = _("Click to insert an anchor on the path. (try SHIFT)");
 
1229
          break;
 
1230
        case VECTORS_DELETE_ANCHOR:
 
1231
          new_status = _("Click to delete this anchor.");
 
1232
          break;
 
1233
        case VECTORS_CONNECT_STROKES:
 
1234
          new_status = _("Click to connect this anchor "
 
1235
                          "with the selected endpoint.");
 
1236
          break;
 
1237
        case VECTORS_DELETE_SEGMENT:
 
1238
          new_status = _("Click to open up the path.");
 
1239
          break;
 
1240
        case VECTORS_CONVERT_EDGE:
 
1241
          new_status = _("Click to make this node angular.");
 
1242
          break;
 
1243
        case VECTORS_FINISHED:
 
1244
          new_status = " ";
 
1245
          break;
 
1246
      }
 
1247
    }
 
1248
 
 
1249
  gimp_vector_tool_status_set (tool, gdisp, new_status);
 
1250
}
 
1251
 
 
1252
static void
 
1253
gimp_vector_tool_status_set (GimpTool    *tool,
 
1254
                             GimpDisplay *gdisp,
 
1255
                             const gchar *message)
 
1256
{
 
1257
  GimpVectorTool *vector_tool = GIMP_VECTOR_TOOL (tool);
 
1258
 
 
1259
  if (tool->gdisp &&
 
1260
      vector_tool->status_msg != message)
 
1261
    {
 
1262
      if (vector_tool->status_msg)
 
1263
        {
 
1264
          gimp_tool_pop_status (tool);
 
1265
          vector_tool->status_msg = NULL;
 
1266
        }
 
1267
 
 
1268
      if (message)
 
1269
        {
 
1270
          gimp_tool_push_status (tool, message);
 
1271
          vector_tool->status_msg = message;
 
1272
        }
 
1273
    }
 
1274
}
 
1275
 
 
1276
static void
 
1277
gimp_vector_tool_cursor_update (GimpTool        *tool,
 
1278
                                GimpCoords      *coords,
 
1279
                                GdkModifierType  state,
 
1280
                                GimpDisplay     *gdisp)
 
1281
{
 
1282
  GimpVectorTool     *vector_tool;
 
1283
  GimpCursorType      cursor;
 
1284
  GimpToolCursorType  tool_cursor;
 
1285
  GimpCursorModifier  cmodifier;
 
1286
 
 
1287
  vector_tool = GIMP_VECTOR_TOOL (tool);
 
1288
 
 
1289
  cursor      = GIMP_CURSOR_MOUSE;
 
1290
  tool_cursor = GIMP_TOOL_CURSOR_PATHS;
 
1291
  cmodifier   = GIMP_CURSOR_MODIFIER_NONE;
 
1292
 
 
1293
  switch (vector_tool->function)
 
1294
    {
 
1295
    case VECTORS_SELECT_VECTOR:
 
1296
      cursor      = GDK_HAND2;
 
1297
      tool_cursor = GIMP_TOOL_CURSOR_HAND;
 
1298
      break;
 
1299
    case VECTORS_CREATE_VECTOR:
 
1300
    case VECTORS_CREATE_STROKE:
 
1301
      cmodifier = GIMP_CURSOR_MODIFIER_CONTROL;
 
1302
      break;
 
1303
    case VECTORS_ADD_ANCHOR:
 
1304
    case VECTORS_INSERT_ANCHOR:
 
1305
      cmodifier = GIMP_CURSOR_MODIFIER_PLUS;
 
1306
      break;
 
1307
    case VECTORS_DELETE_ANCHOR:
 
1308
    case VECTORS_DELETE_SEGMENT:
 
1309
      cmodifier = GIMP_CURSOR_MODIFIER_MINUS;
 
1310
      break;
 
1311
    case VECTORS_MOVE_HANDLE:
 
1312
    case VECTORS_CONVERT_EDGE:
 
1313
      cursor      = GDK_HAND2;
 
1314
      tool_cursor = GIMP_TOOL_CURSOR_HAND;
 
1315
      cmodifier   = GIMP_CURSOR_MODIFIER_CONTROL;
 
1316
      break;
 
1317
    case VECTORS_MOVE_ANCHOR:
 
1318
    case VECTORS_MOVE_CURVE:
 
1319
    case VECTORS_MOVE_STROKE:
 
1320
    case VECTORS_MOVE_VECTORS:
 
1321
    case VECTORS_MOVE_ANCHORSET:
 
1322
      cmodifier = GIMP_CURSOR_MODIFIER_MOVE;
 
1323
      break;
 
1324
    case VECTORS_CONNECT_STROKES:
 
1325
      cmodifier = GIMP_CURSOR_MODIFIER_INTERSECT;
 
1326
      break;
 
1327
    default:
 
1328
      cursor = GIMP_CURSOR_BAD;
 
1329
      break;
 
1330
    }
 
1331
 
 
1332
  gimp_tool_control_set_cursor          (tool->control, cursor);
 
1333
  gimp_tool_control_set_tool_cursor     (tool->control, tool_cursor);
 
1334
  gimp_tool_control_set_cursor_modifier (tool->control, cmodifier);
 
1335
 
 
1336
  GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, gdisp);
 
1337
}
 
1338
 
 
1339
static void
 
1340
gimp_vector_tool_draw (GimpDrawTool *draw_tool)
 
1341
{
 
1342
  GimpVectorTool  *vector_tool = GIMP_VECTOR_TOOL (draw_tool);
 
1343
  GimpAnchor      *cur_anchor  = NULL;
 
1344
  GimpStroke      *cur_stroke  = NULL;
 
1345
  GimpVectors     *vectors;
 
1346
  GArray          *coords;
 
1347
  gboolean         closed;
 
1348
  GList           *draw_anchors;
 
1349
  GList           *list;
 
1350
 
 
1351
  vectors = vector_tool->vectors;
 
1352
 
 
1353
  if (!vectors)
 
1354
    return;
 
1355
 
 
1356
  while ((cur_stroke = gimp_vectors_stroke_get_next (vectors, cur_stroke)))
 
1357
    {
 
1358
      /* anchor handles */
 
1359
      draw_anchors = gimp_stroke_get_draw_anchors (cur_stroke);
 
1360
 
 
1361
      for (list = draw_anchors; list; list = g_list_next (list))
 
1362
        {
 
1363
          cur_anchor = GIMP_ANCHOR (list->data);
 
1364
 
 
1365
          if (cur_anchor->type == GIMP_ANCHOR_ANCHOR)
 
1366
            {
 
1367
              gimp_draw_tool_draw_handle (draw_tool,
 
1368
                                          cur_anchor->selected ?
 
1369
                                          GIMP_HANDLE_CIRCLE :
 
1370
                                          GIMP_HANDLE_FILLED_CIRCLE,
 
1371
                                          cur_anchor->position.x,
 
1372
                                          cur_anchor->position.y,
 
1373
                                          TARGET,
 
1374
                                          TARGET,
 
1375
                                          GTK_ANCHOR_CENTER,
 
1376
                                          FALSE);
 
1377
            }
 
1378
        }
 
1379
 
 
1380
      g_list_free (draw_anchors);
 
1381
 
 
1382
      if (vector_tool->sel_count <= 2)
 
1383
        {
 
1384
          /* control handles */
 
1385
          draw_anchors = gimp_stroke_get_draw_controls (cur_stroke);
 
1386
 
 
1387
          for (list = draw_anchors; list; list = g_list_next (list))
 
1388
            {
 
1389
              cur_anchor = GIMP_ANCHOR (list->data);
 
1390
 
 
1391
              gimp_draw_tool_draw_handle (draw_tool,
 
1392
                                          GIMP_HANDLE_SQUARE,
 
1393
                                          cur_anchor->position.x,
 
1394
                                          cur_anchor->position.y,
 
1395
                                          TARGET - 3,
 
1396
                                          TARGET - 3,
 
1397
                                          GTK_ANCHOR_CENTER,
 
1398
                                          FALSE);
 
1399
            }
 
1400
 
 
1401
          g_list_free (draw_anchors);
 
1402
 
 
1403
          /* the lines to the control handles */
 
1404
          coords = gimp_stroke_get_draw_lines (cur_stroke);
 
1405
 
 
1406
          if (coords)
 
1407
            {
 
1408
              if (coords->len % 2 == 0)
 
1409
                {
 
1410
                  gint i;
 
1411
 
 
1412
                  for (i = 0; i < coords->len; i += 2)
 
1413
                    {
 
1414
                      gimp_draw_tool_draw_dashed_line (draw_tool,
 
1415
                                    g_array_index (coords, GimpCoords, i).x,
 
1416
                                    g_array_index (coords, GimpCoords, i).y,
 
1417
                                    g_array_index (coords, GimpCoords, i + 1).x,
 
1418
                                    g_array_index (coords, GimpCoords, i + 1).y,
 
1419
                                    FALSE);
 
1420
                    }
 
1421
                }
 
1422
 
 
1423
              g_array_free (coords, TRUE);
 
1424
            }
 
1425
        }
 
1426
 
 
1427
      /* the stroke itself */
 
1428
      if (! gimp_item_get_visible (GIMP_ITEM (vectors)))
 
1429
        {
 
1430
          coords = gimp_stroke_interpolate (cur_stroke, 1.0, &closed);
 
1431
 
 
1432
          if (coords)
 
1433
            {
 
1434
              if (coords->len)
 
1435
                gimp_draw_tool_draw_strokes (draw_tool,
 
1436
                                             &g_array_index (coords,
 
1437
                                                             GimpCoords, 0),
 
1438
                                             coords->len, FALSE, FALSE);
 
1439
 
 
1440
              g_array_free (coords, TRUE);
 
1441
            }
 
1442
        }
 
1443
    }
 
1444
}
 
1445
 
 
1446
static void
 
1447
gimp_vector_tool_vectors_changed (GimpImage      *gimage,
 
1448
                                  GimpVectorTool *vector_tool)
 
1449
{
 
1450
  gimp_vector_tool_set_vectors (vector_tool,
 
1451
                                gimp_image_get_active_vectors (gimage));
 
1452
}
 
1453
 
 
1454
static void
 
1455
gimp_vector_tool_vectors_removed (GimpVectors    *vectors,
 
1456
                                  GimpVectorTool *vector_tool)
 
1457
{
 
1458
  gimp_vector_tool_set_vectors (vector_tool, NULL);
 
1459
}
 
1460
 
 
1461
static void
 
1462
gimp_vector_tool_vectors_visible (GimpVectors    *vectors,
 
1463
                                  GimpVectorTool *vector_tool)
 
1464
{
 
1465
  GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (vector_tool);
 
1466
 
 
1467
  if (gimp_draw_tool_is_active (draw_tool) && draw_tool->paused_count == 0)
 
1468
    {
 
1469
      GimpStroke *stroke = NULL;
 
1470
 
 
1471
      while ((stroke = gimp_vectors_stroke_get_next (vectors, stroke)))
 
1472
        {
 
1473
          GArray   *coords;
 
1474
          gboolean  closed;
 
1475
 
 
1476
          coords = gimp_stroke_interpolate (stroke, 1.0, &closed);
 
1477
 
 
1478
          if (coords)
 
1479
            {
 
1480
              if (coords->len)
 
1481
                gimp_draw_tool_draw_strokes (draw_tool,
 
1482
                                             &g_array_index (coords,
 
1483
                                                             GimpCoords, 0),
 
1484
                                             coords->len, FALSE, FALSE);
 
1485
 
 
1486
              g_array_free (coords, TRUE);
 
1487
            }
 
1488
        }
 
1489
    }
 
1490
}
 
1491
 
 
1492
static void
 
1493
gimp_vector_tool_vectors_freeze (GimpVectors    *vectors,
 
1494
                                 GimpVectorTool *vector_tool)
 
1495
{
 
1496
  gimp_draw_tool_pause (GIMP_DRAW_TOOL (vector_tool));
 
1497
}
 
1498
 
 
1499
static void
 
1500
gimp_vector_tool_vectors_thaw (GimpVectors    *vectors,
 
1501
                               GimpVectorTool *vector_tool)
 
1502
{
 
1503
  /* Ok, the vector might have changed externally (e.g. Undo)
 
1504
   * we need to validate our internal state. */
 
1505
  gimp_vector_tool_verify_state (vector_tool);
 
1506
 
 
1507
  gimp_draw_tool_resume (GIMP_DRAW_TOOL (vector_tool));
 
1508
}
 
1509
 
 
1510
void
 
1511
gimp_vector_tool_set_vectors (GimpVectorTool *vector_tool,
 
1512
                              GimpVectors    *vectors)
 
1513
{
 
1514
  GimpDrawTool      *draw_tool;
 
1515
  GimpTool          *tool;
 
1516
  GimpItem          *item = NULL;
 
1517
  GtkWidget         *stroke_button;
 
1518
  GtkWidget         *sel_button;
 
1519
  GimpVectorOptions *options;
 
1520
 
 
1521
  g_return_if_fail (GIMP_IS_VECTOR_TOOL (vector_tool));
 
1522
  g_return_if_fail (vectors == NULL || GIMP_IS_VECTORS (vectors));
 
1523
 
 
1524
  draw_tool = GIMP_DRAW_TOOL (vector_tool);
 
1525
  tool      = GIMP_TOOL (vector_tool);
 
1526
  options   = GIMP_VECTOR_OPTIONS (tool->tool_info->tool_options);
 
1527
 
 
1528
  if (vectors)
 
1529
    item = GIMP_ITEM (vectors);
 
1530
 
 
1531
  if (vectors == vector_tool->vectors)
 
1532
    return;
 
1533
 
 
1534
  gimp_draw_tool_pause (draw_tool);
 
1535
 
 
1536
  if (gimp_draw_tool_is_active (draw_tool) &&
 
1537
      (! vectors || draw_tool->gdisp->gimage != item->gimage))
 
1538
    {
 
1539
      gimp_draw_tool_stop (draw_tool);
 
1540
    }
 
1541
 
 
1542
  stroke_button = g_object_get_data (G_OBJECT (options),
 
1543
                                     "gimp-stroke-vectors");
 
1544
  sel_button = g_object_get_data (G_OBJECT (options),
 
1545
                                  "gimp-vectors-to-selection");
 
1546
 
 
1547
  if (vector_tool->vectors)
 
1548
    {
 
1549
      GimpImage *old_gimage;
 
1550
 
 
1551
      old_gimage = gimp_item_get_image (GIMP_ITEM (vector_tool->vectors));
 
1552
 
 
1553
      g_signal_handlers_disconnect_by_func (old_gimage,
 
1554
                                            gimp_vector_tool_vectors_changed,
 
1555
                                            vector_tool);
 
1556
      g_signal_handlers_disconnect_by_func (vector_tool->vectors,
 
1557
                                            gimp_vector_tool_vectors_removed,
 
1558
                                            vector_tool);
 
1559
      g_signal_handlers_disconnect_by_func (vector_tool->vectors,
 
1560
                                            gimp_vector_tool_vectors_visible,
 
1561
                                            vector_tool);
 
1562
      g_signal_handlers_disconnect_by_func (vector_tool->vectors,
 
1563
                                            gimp_vector_tool_vectors_freeze,
 
1564
                                            vector_tool);
 
1565
      g_signal_handlers_disconnect_by_func (vector_tool->vectors,
 
1566
                                            gimp_vector_tool_vectors_thaw,
 
1567
                                            vector_tool);
 
1568
      g_object_unref (vector_tool->vectors);
 
1569
 
 
1570
      if (sel_button)
 
1571
        {
 
1572
          gtk_widget_set_sensitive (sel_button, FALSE);
 
1573
          g_signal_handlers_disconnect_by_func (sel_button,
 
1574
                                                gimp_vector_tool_to_selection,
 
1575
                                                tool);
 
1576
          g_signal_handlers_disconnect_by_func (sel_button,
 
1577
                                                gimp_vector_tool_to_selection_extended,
 
1578
                                                tool);
 
1579
        }
 
1580
 
 
1581
      if (stroke_button)
 
1582
        {
 
1583
          gtk_widget_set_sensitive (stroke_button, FALSE);
 
1584
          g_signal_handlers_disconnect_by_func (stroke_button,
 
1585
                                                gimp_vector_tool_stroke_vectors,
 
1586
                                                tool);
 
1587
        }
 
1588
    }
 
1589
 
 
1590
  vector_tool->vectors    = vectors;
 
1591
  vector_tool->function   = VECTORS_FINISHED;
 
1592
  gimp_vector_tool_verify_state (vector_tool);
 
1593
 
 
1594
  if (! vector_tool->vectors)
 
1595
    {
 
1596
      tool->gdisp = NULL;
 
1597
 
 
1598
      /* leave draw_tool->paused_count in a consistent state */
 
1599
      gimp_draw_tool_resume (draw_tool);
 
1600
 
 
1601
      vector_tool->function = VECTORS_CREATE_VECTOR;
 
1602
 
 
1603
      return;
 
1604
    }
 
1605
 
 
1606
  g_object_ref (vectors);
 
1607
 
 
1608
  g_signal_connect_object (item->gimage, "active_vectors_changed",
 
1609
                           G_CALLBACK (gimp_vector_tool_vectors_changed),
 
1610
                           vector_tool, 0);
 
1611
  g_signal_connect_object (vectors, "removed",
 
1612
                           G_CALLBACK (gimp_vector_tool_vectors_removed),
 
1613
                           vector_tool, 0);
 
1614
  g_signal_connect_object (vectors, "visibility_changed",
 
1615
                           G_CALLBACK (gimp_vector_tool_vectors_visible),
 
1616
                           vector_tool, 0);
 
1617
  g_signal_connect_object (vectors, "freeze",
 
1618
                           G_CALLBACK (gimp_vector_tool_vectors_freeze),
 
1619
                           vector_tool, 0);
 
1620
  g_signal_connect_object (vectors, "thaw",
 
1621
                           G_CALLBACK (gimp_vector_tool_vectors_thaw),
 
1622
                           vector_tool, 0);
 
1623
 
 
1624
  if (sel_button)
 
1625
    {
 
1626
      g_signal_connect_swapped (sel_button, "clicked",
 
1627
                                G_CALLBACK (gimp_vector_tool_to_selection),
 
1628
                                tool);
 
1629
      g_signal_connect_swapped (sel_button, "extended_clicked",
 
1630
                                G_CALLBACK (gimp_vector_tool_to_selection_extended),
 
1631
                                tool);
 
1632
      gtk_widget_set_sensitive (sel_button, TRUE);
 
1633
    }
 
1634
 
 
1635
  if (stroke_button)
 
1636
    {
 
1637
      g_signal_connect_swapped (stroke_button, "clicked",
 
1638
                                G_CALLBACK (gimp_vector_tool_stroke_vectors),
 
1639
                                tool);
 
1640
      gtk_widget_set_sensitive (stroke_button, TRUE);
 
1641
    }
 
1642
 
 
1643
  if (! gimp_draw_tool_is_active (draw_tool))
 
1644
    {
 
1645
      if (tool->gdisp && tool->gdisp->gimage == item->gimage)
 
1646
        {
 
1647
          gimp_draw_tool_start (draw_tool, tool->gdisp);
 
1648
        }
 
1649
      else
 
1650
        {
 
1651
          GimpContext *context;
 
1652
          GimpDisplay *gdisp;
 
1653
 
 
1654
          context = gimp_get_user_context (tool->tool_info->gimp);
 
1655
          gdisp   = gimp_context_get_display (context);
 
1656
 
 
1657
          if (! gdisp || gdisp->gimage != item->gimage)
 
1658
            {
 
1659
              GList *list;
 
1660
 
 
1661
              gdisp = NULL;
 
1662
 
 
1663
              for (list = GIMP_LIST (item->gimage->gimp->displays)->list;
 
1664
                   list;
 
1665
                   list = g_list_next (list))
 
1666
                {
 
1667
                  if (((GimpDisplay *) list->data)->gimage == item->gimage)
 
1668
                    {
 
1669
                      gimp_context_set_display (context,
 
1670
                                                (GimpDisplay *) list->data);
 
1671
 
 
1672
                      gdisp = gimp_context_get_display (context);
 
1673
                      break;
 
1674
                    }
 
1675
                }
 
1676
            }
 
1677
 
 
1678
          tool->gdisp = gdisp;
 
1679
 
 
1680
          if (tool->gdisp)
 
1681
            {
 
1682
              gimp_draw_tool_start (draw_tool, tool->gdisp);
 
1683
            }
 
1684
        }
 
1685
    }
 
1686
 
 
1687
  gimp_draw_tool_resume (draw_tool);
 
1688
}
 
1689
 
 
1690
static void
 
1691
gimp_vector_tool_move_selected_anchors (GimpVectorTool *vector_tool,
 
1692
                                        gdouble         x,
 
1693
                                        gdouble         y)
 
1694
{
 
1695
  GimpAnchor *cur_anchor;
 
1696
  GimpStroke *cur_stroke = NULL;
 
1697
  GList *anchors;
 
1698
  GList *list;
 
1699
  GimpCoords offset = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
 
1700
 
 
1701
  offset.x = x;
 
1702
  offset.y = y;
 
1703
 
 
1704
  while ((cur_stroke = gimp_vectors_stroke_get_next (vector_tool->vectors,
 
1705
                                                     cur_stroke)))
 
1706
    {
 
1707
      /* anchors */
 
1708
      anchors = gimp_stroke_get_draw_anchors (cur_stroke);
 
1709
 
 
1710
      for (list = anchors; list; list = g_list_next (list))
 
1711
        {
 
1712
          cur_anchor = GIMP_ANCHOR (list->data);
 
1713
 
 
1714
          if (cur_anchor->selected)
 
1715
            gimp_stroke_anchor_move_relative (cur_stroke,
 
1716
                                              cur_anchor,
 
1717
                                              &offset,
 
1718
                                              GIMP_ANCHOR_FEATURE_NONE);
 
1719
        }
 
1720
 
 
1721
      g_list_free (anchors);
 
1722
    }
 
1723
}
 
1724
 
 
1725
static void
 
1726
gimp_vector_tool_delete_selected_anchors (GimpVectorTool *vector_tool)
 
1727
{
 
1728
  GimpAnchor *cur_anchor;
 
1729
  GimpStroke *cur_stroke = NULL;
 
1730
  GList      *anchors;
 
1731
  GList      *list;
 
1732
  gboolean    have_undo = FALSE;
 
1733
 
 
1734
  gimp_draw_tool_pause (GIMP_DRAW_TOOL (vector_tool));
 
1735
  gimp_vectors_freeze (vector_tool->vectors);
 
1736
 
 
1737
  while ((cur_stroke = gimp_vectors_stroke_get_next (vector_tool->vectors,
 
1738
                                                     cur_stroke)))
 
1739
    {
 
1740
      /* anchors */
 
1741
      anchors = gimp_stroke_get_draw_anchors (cur_stroke);
 
1742
 
 
1743
      for (list = anchors; list; list = g_list_next (list))
 
1744
        {
 
1745
          cur_anchor = GIMP_ANCHOR (list->data);
 
1746
 
 
1747
          if (cur_anchor->selected)
 
1748
            {
 
1749
              if (! have_undo)
 
1750
                {
 
1751
                  gimp_vector_tool_undo_push (vector_tool, _("Delete Anchors"));
 
1752
                  have_undo = TRUE;
 
1753
                }
 
1754
 
 
1755
              gimp_stroke_anchor_delete (cur_stroke, cur_anchor);
 
1756
 
 
1757
              if (gimp_stroke_is_empty (cur_stroke))
 
1758
                gimp_vectors_stroke_remove (vector_tool->vectors, cur_stroke);
 
1759
            }
 
1760
        }
 
1761
 
 
1762
      g_list_free (anchors);
 
1763
    }
 
1764
 
 
1765
  gimp_vectors_thaw (vector_tool->vectors);
 
1766
  gimp_draw_tool_resume (GIMP_DRAW_TOOL (vector_tool));
 
1767
}
 
1768
 
 
1769
static void
 
1770
gimp_vector_tool_verify_state (GimpVectorTool *vector_tool)
 
1771
{
 
1772
  GimpStroke *cur_stroke = NULL;
 
1773
  GimpAnchor *cur_anchor;
 
1774
  GList      *anchors;
 
1775
  GList      *list;
 
1776
  gboolean    cur_anchor_valid;
 
1777
  gboolean    cur_stroke_valid;
 
1778
 
 
1779
  cur_anchor_valid = FALSE;
 
1780
  cur_stroke_valid = FALSE;
 
1781
 
 
1782
  vector_tool->sel_count  = 0;
 
1783
  vector_tool->sel_anchor = NULL;
 
1784
  vector_tool->sel_stroke = NULL;
 
1785
 
 
1786
  if (!vector_tool->vectors)
 
1787
    {
 
1788
      vector_tool->cur_position = -1;
 
1789
      vector_tool->cur_anchor   = NULL;
 
1790
      vector_tool->cur_stroke   = NULL;
 
1791
      return;
 
1792
    }
 
1793
 
 
1794
  while ((cur_stroke = gimp_vectors_stroke_get_next (vector_tool->vectors,
 
1795
                                                     cur_stroke)))
 
1796
    {
 
1797
      /* anchor handles */
 
1798
      anchors = gimp_stroke_get_draw_anchors (cur_stroke);
 
1799
 
 
1800
      if (cur_stroke == vector_tool->cur_stroke)
 
1801
        cur_stroke_valid = TRUE;
 
1802
 
 
1803
      for (list = anchors; list; list = g_list_next (list))
 
1804
        {
 
1805
          cur_anchor = GIMP_ANCHOR (list->data);
 
1806
 
 
1807
          if (cur_anchor == vector_tool->cur_anchor)
 
1808
            cur_anchor_valid = TRUE;
 
1809
 
 
1810
          if (cur_anchor->type == GIMP_ANCHOR_ANCHOR &&
 
1811
              cur_anchor->selected)
 
1812
            {
 
1813
              vector_tool->sel_count++;
 
1814
              if (vector_tool->sel_count == 1)
 
1815
                {
 
1816
                  vector_tool->sel_anchor = cur_anchor;
 
1817
                  vector_tool->sel_stroke = cur_stroke;
 
1818
                }
 
1819
              else
 
1820
                {
 
1821
                  vector_tool->sel_anchor = NULL;
 
1822
                  vector_tool->sel_stroke = NULL;
 
1823
                }
 
1824
            }
 
1825
        }
 
1826
 
 
1827
      anchors = gimp_stroke_get_draw_controls (cur_stroke);
 
1828
 
 
1829
      for (list = anchors; list; list = g_list_next (list))
 
1830
        {
 
1831
          cur_anchor = GIMP_ANCHOR (list->data);
 
1832
 
 
1833
          if (cur_anchor == vector_tool->cur_anchor)
 
1834
            cur_anchor_valid = TRUE;
 
1835
        }
 
1836
    }
 
1837
 
 
1838
  if (!cur_stroke_valid)
 
1839
    vector_tool->cur_stroke = NULL;
 
1840
 
 
1841
  if (!cur_anchor_valid)
 
1842
    vector_tool->cur_anchor = NULL;
 
1843
 
 
1844
}
 
1845
 
 
1846
static void
 
1847
gimp_vector_tool_undo_push (GimpVectorTool *vector_tool, const gchar *desc)
 
1848
{
 
1849
  g_return_if_fail (vector_tool->vectors != NULL);
 
1850
 
 
1851
  /* don't push two undos */
 
1852
  if (vector_tool->have_undo)
 
1853
    return;
 
1854
 
 
1855
  gimp_image_undo_push_vectors_mod (GIMP_ITEM (vector_tool->vectors)->gimage,
 
1856
                                    desc, vector_tool->vectors);
 
1857
  vector_tool->have_undo = TRUE;
 
1858
}
 
1859
 
 
1860
 
 
1861
static void
 
1862
gimp_vector_tool_to_selection (GimpVectorTool *vector_tool)
 
1863
{
 
1864
  gimp_vector_tool_to_selection_extended (vector_tool, 0);
 
1865
}
 
1866
 
 
1867
 
 
1868
static void
 
1869
gimp_vector_tool_to_selection_extended (GimpVectorTool *vector_tool,
 
1870
                                        gint            state)
 
1871
{
 
1872
  GimpImage    *gimage;
 
1873
  GimpChannelOps operation = GIMP_CHANNEL_OP_REPLACE;
 
1874
 
 
1875
  if (! vector_tool->vectors)
 
1876
    return;
 
1877
 
 
1878
  gimage = gimp_item_get_image (GIMP_ITEM (vector_tool->vectors));
 
1879
 
 
1880
  if (state & GDK_SHIFT_MASK)
 
1881
    {
 
1882
      if (state & GDK_CONTROL_MASK)
 
1883
        operation = GIMP_CHANNEL_OP_INTERSECT;
 
1884
      else
 
1885
        operation = GIMP_CHANNEL_OP_ADD;
 
1886
    }
 
1887
  else if (state & GDK_CONTROL_MASK)
 
1888
    {
 
1889
      operation = GIMP_CHANNEL_OP_SUBTRACT;
 
1890
    }
 
1891
 
 
1892
  gimp_channel_select_vectors (gimp_image_get_mask (gimage),
 
1893
                               _("Path to selection"),
 
1894
                               vector_tool->vectors,
 
1895
                               operation,
 
1896
                               TRUE, FALSE, 0, 0);
 
1897
  gimp_image_flush (gimage);
 
1898
}
 
1899
 
 
1900
 
 
1901
static void
 
1902
gimp_vector_tool_stroke_vectors (GimpVectorTool *vector_tool,
 
1903
                                 GtkWidget      *button)
 
1904
{
 
1905
  GimpImage    *gimage;
 
1906
  GimpDrawable *active_drawable;
 
1907
  GtkWidget    *dialog;
 
1908
 
 
1909
  if (! vector_tool->vectors)
 
1910
    return;
 
1911
 
 
1912
  gimage = gimp_item_get_image (GIMP_ITEM (vector_tool->vectors));
 
1913
 
 
1914
  active_drawable = gimp_image_active_drawable (gimage);
 
1915
 
 
1916
  if (! active_drawable)
 
1917
    {
 
1918
      g_message (_("There is no active layer or channel to stroke to"));
 
1919
      return;
 
1920
    }
 
1921
 
 
1922
  dialog = stroke_dialog_new (GIMP_ITEM (vector_tool->vectors),
 
1923
                              _("Stroke Path"),
 
1924
                              GIMP_STOCK_PATH_STROKE,
 
1925
                              GIMP_HELP_PATH_STROKE,
 
1926
                              button);
 
1927
  gtk_widget_show (dialog);
 
1928
}
 
1929