~ubuntu-branches/ubuntu/vivid/gimp/vivid

« back to all changes in this revision

Viewing changes to app/tools/gimpaligntool.c

  • Committer: Package Import Robot
  • Author(s): Jordi Mallach
  • Date: 2012-05-08 18:50:03 UTC
  • mto: (1.1.26) (0.5.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 71.
  • Revision ID: package-import@ubuntu.com-20120508185003-tltkvbaysf8d2426
ImportĀ upstreamĀ versionĀ 2.8.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* GIMP - The GNU Image Manipulation Program
2
2
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3
3
 *
4
 
 * This program is free software; you can redistribute it and/or modify
 
4
 * This program is free software: you can redistribute it and/or modify
5
5
 * it under the terms of the GNU General Public License as published by
6
 
 * the Free Software Foundation; either version 2 of the License, or
 
6
 * the Free Software Foundation; either version 3 of the License, or
7
7
 * (at your option) any later version.
8
8
 *
9
9
 * This program is distributed in the hope that it will be useful,
12
12
 * GNU General Public License for more details.
13
13
 *
14
14
 * You should have received a copy of the GNU General Public License
15
 
 * along with this program; if not, write to the Free Software
16
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
15
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
16
 */
18
17
 
19
18
#include "config.h"
20
19
 
 
20
#include <gegl.h>
21
21
#include <gtk/gtk.h>
 
22
#include <gdk/gdkkeysyms.h>
22
23
 
23
24
#include "libgimpmath/gimpmath.h"
24
25
#include "libgimpwidgets/gimpwidgets.h"
32
33
#include "core/gimpimage.h"
33
34
#include "core/gimpimage-arrange.h"
34
35
#include "core/gimpimage-guides.h"
 
36
#include "core/gimpimage-pick-layer.h"
35
37
#include "core/gimpimage-undo.h"
36
38
#include "core/gimplayer.h"
37
 
#include "core/gimplist.h"
38
39
 
39
40
#include "vectors/gimpvectors.h"
40
41
 
51
52
 
52
53
#include "gimp-intl.h"
53
54
 
54
 
#define EPSILON      3   /* move distance after which we do a box-select */
55
 
#define MARKER_WIDTH 5   /* size (in pixels) of the square handles */
 
55
 
 
56
#define EPSILON  3   /* move distance after which we do a box-select */
 
57
 
56
58
 
57
59
/*  local function prototypes  */
58
60
 
59
 
static GObject * gimp_align_tool_constructor (GType                  type,
60
 
                                              guint                  n_params,
61
 
                                              GObjectConstructParam *params);
62
 
static gboolean gimp_align_tool_initialize   (GimpTool              *tool,
63
 
                                              GimpDisplay           *display,
64
 
                                              GError               **error);
65
 
static void   gimp_align_tool_finalize       (GObject               *object);
66
 
 
67
 
static void   gimp_align_tool_control        (GimpTool              *tool,
68
 
                                              GimpToolAction         action,
69
 
                                              GimpDisplay           *display);
70
 
static void   gimp_align_tool_button_press   (GimpTool              *tool,
71
 
                                              GimpCoords            *coords,
72
 
                                              guint32                time,
73
 
                                              GdkModifierType        state,
74
 
                                              GimpDisplay           *display);
75
 
static void   gimp_align_tool_button_release (GimpTool              *tool,
76
 
                                              GimpCoords            *coords,
77
 
                                              guint32                time,
78
 
                                              GdkModifierType        state,
79
 
                                              GimpButtonReleaseType  release_tyle,
80
 
                                              GimpDisplay           *display);
81
 
static void   gimp_align_tool_motion         (GimpTool              *tool,
82
 
                                              GimpCoords            *coords,
83
 
                                              guint32                time,
84
 
                                              GdkModifierType        state,
85
 
                                              GimpDisplay           *display);
86
 
static void   gimp_align_tool_oper_update    (GimpTool              *tool,
87
 
                                              GimpCoords            *coords,
88
 
                                              GdkModifierType        state,
89
 
                                              gboolean               proximity,
90
 
                                              GimpDisplay           *display);
91
 
static void   gimp_align_tool_status_update  (GimpTool              *tool,
92
 
                                              GimpDisplay           *display,
93
 
                                              GdkModifierType        state,
94
 
                                              gboolean               proximity);
95
 
static void   gimp_align_tool_cursor_update  (GimpTool              *tool,
96
 
                                              GimpCoords            *coords,
97
 
                                              GdkModifierType        state,
98
 
                                              GimpDisplay           *display);
99
 
 
100
 
static void   gimp_align_tool_draw           (GimpDrawTool          *draw_tool);
101
 
 
102
 
static GtkWidget *button_with_stock          (GimpAlignmentType      action,
103
 
                                              GimpAlignTool         *align_tool);
104
 
static GtkWidget *gimp_align_tool_controls   (GimpAlignTool         *align_tool);
105
 
static void   do_alignment                   (GtkWidget             *widget,
106
 
                                              gpointer               data);
107
 
static void   clear_selected_object          (GObject               *object,
108
 
                                              GimpAlignTool         *align_tool);
109
 
static void   clear_all_selected_objects     (GimpAlignTool         *align_tool);
110
 
static GimpLayer *select_layer_by_coords     (GimpImage             *image,
111
 
                                              gint                   x,
112
 
                                              gint                   y);
113
 
void          gimp_image_arrange_objects     (GimpImage             *image,
114
 
                                              GList                 *list,
115
 
                                              GimpAlignmentType      alignment,
116
 
                                              GObject               *reference,
117
 
                                              GimpAlignmentType      reference_alignment,
118
 
                                              gint                   offset);
 
61
static void     gimp_align_tool_constructed    (GObject               *object);
 
62
 
 
63
static void     gimp_align_tool_control        (GimpTool              *tool,
 
64
                                                GimpToolAction         action,
 
65
                                                GimpDisplay           *display);
 
66
static void     gimp_align_tool_button_press   (GimpTool              *tool,
 
67
                                                const GimpCoords      *coords,
 
68
                                                guint32                time,
 
69
                                                GdkModifierType        state,
 
70
                                                GimpButtonPressType    press_type,
 
71
                                                GimpDisplay           *display);
 
72
static void     gimp_align_tool_button_release (GimpTool              *tool,
 
73
                                                const GimpCoords      *coords,
 
74
                                                guint32                time,
 
75
                                                GdkModifierType        state,
 
76
                                                GimpButtonReleaseType  release_type,
 
77
                                                GimpDisplay           *display);
 
78
static void     gimp_align_tool_motion         (GimpTool              *tool,
 
79
                                                const GimpCoords      *coords,
 
80
                                                guint32                time,
 
81
                                                GdkModifierType        state,
 
82
                                                GimpDisplay           *display);
 
83
static gboolean gimp_align_tool_key_press      (GimpTool              *tool,
 
84
                                                GdkEventKey           *kevent,
 
85
                                                GimpDisplay           *display);
 
86
static void     gimp_align_tool_oper_update    (GimpTool              *tool,
 
87
                                                const GimpCoords      *coords,
 
88
                                                GdkModifierType        state,
 
89
                                                gboolean               proximity,
 
90
                                                GimpDisplay           *display);
 
91
static void     gimp_align_tool_status_update  (GimpTool              *tool,
 
92
                                                GimpDisplay           *display,
 
93
                                                GdkModifierType        state,
 
94
                                                gboolean               proximity);
 
95
static void     gimp_align_tool_cursor_update  (GimpTool              *tool,
 
96
                                                const GimpCoords      *coords,
 
97
                                                GdkModifierType        state,
 
98
                                                GimpDisplay           *display);
 
99
 
 
100
static void     gimp_align_tool_draw           (GimpDrawTool          *draw_tool);
 
101
 
 
102
static void     gimp_align_tool_align          (GimpAlignTool         *align_tool,
 
103
                                                GimpAlignmentType      align_type);
 
104
 
 
105
static void     gimp_align_tool_object_removed (GObject               *object,
 
106
                                                GimpAlignTool         *align_tool);
 
107
static void     gimp_align_tool_clear_selected (GimpAlignTool         *align_tool);
 
108
 
119
109
 
120
110
G_DEFINE_TYPE (GimpAlignTool, gimp_align_tool, GIMP_TYPE_DRAW_TOOL)
121
111
 
146
136
  GimpToolClass     *tool_class      = GIMP_TOOL_CLASS (klass);
147
137
  GimpDrawToolClass *draw_tool_class = GIMP_DRAW_TOOL_CLASS (klass);
148
138
 
149
 
  object_class->finalize     = gimp_align_tool_finalize;
150
 
  object_class->constructor  = gimp_align_tool_constructor;
 
139
  object_class->constructed  = gimp_align_tool_constructed;
151
140
 
152
 
  tool_class->initialize     = gimp_align_tool_initialize;
153
141
  tool_class->control        = gimp_align_tool_control;
154
142
  tool_class->button_press   = gimp_align_tool_button_press;
155
143
  tool_class->button_release = gimp_align_tool_button_release;
156
144
  tool_class->motion         = gimp_align_tool_motion;
 
145
  tool_class->key_press      = gimp_align_tool_key_press;
157
146
  tool_class->oper_update    = gimp_align_tool_oper_update;
158
147
  tool_class->cursor_update  = gimp_align_tool_cursor_update;
159
148
 
165
154
{
166
155
  GimpTool *tool = GIMP_TOOL (align_tool);
167
156
 
168
 
  align_tool->controls         = NULL;
169
 
 
170
 
  align_tool->function         = ALIGN_TOOL_IDLE;
171
 
  align_tool->selected_objects = NULL;
172
 
 
173
 
  align_tool->align_type  = GIMP_ALIGN_LEFT;
174
 
 
175
 
  align_tool->horz_offset = 0;
176
 
  align_tool->vert_offset = 0;
177
 
 
178
157
  gimp_tool_control_set_snap_to     (tool->control, FALSE);
179
158
  gimp_tool_control_set_precision   (tool->control,
180
159
                                     GIMP_CURSOR_PRECISION_PIXEL_BORDER);
181
160
  gimp_tool_control_set_tool_cursor (tool->control, GIMP_TOOL_CURSOR_MOVE);
182
161
 
183
 
}
184
 
 
185
 
static GObject *
186
 
gimp_align_tool_constructor (GType                  type,
187
 
                             guint                  n_params,
188
 
                             GObjectConstructParam *params)
189
 
{
190
 
  GObject       *object;
191
 
  GimpTool      *tool;
192
 
  GimpAlignTool *align_tool;
193
 
  GtkContainer  *container;
194
 
  GObject       *options;
195
 
 
196
 
  object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
197
 
 
198
 
  tool       = GIMP_TOOL (object);
199
 
  align_tool = GIMP_ALIGN_TOOL (object);
200
 
  options    = G_OBJECT (gimp_tool_get_options (tool));
201
 
 
202
 
  /* This line of code is evil because it relies on that the 'options'
203
 
   * object is fully constructed before we get here, which is not
204
 
   * guaranteed
205
 
   */
206
 
  container = GTK_CONTAINER (g_object_get_data (options,
207
 
                                                "controls-container"));
208
 
 
209
 
  if (container)
210
 
    {
211
 
      align_tool->controls = gimp_align_tool_controls (align_tool);
212
 
      gtk_container_add (container, align_tool->controls);
213
 
      gtk_widget_show (align_tool->controls);
214
 
    }
215
 
 
216
 
  return object;
 
162
  align_tool->function = ALIGN_TOOL_IDLE;
217
163
}
218
164
 
219
165
static void
220
 
gimp_align_tool_finalize (GObject *object)
221
 
{
222
 
  GimpTool      *tool       = GIMP_TOOL (object);
223
 
  GimpAlignTool *align_tool = GIMP_ALIGN_TOOL (object);
224
 
 
225
 
  if (gimp_draw_tool_is_active (GIMP_DRAW_TOOL (object)))
226
 
    gimp_draw_tool_stop (GIMP_DRAW_TOOL (object));
227
 
 
228
 
  if (gimp_tool_control_is_active (tool->control))
229
 
    gimp_tool_control_halt (tool->control);
230
 
 
231
 
  if (align_tool->controls)
232
 
    {
233
 
      gtk_widget_destroy (align_tool->controls);
234
 
      align_tool->controls = NULL;
235
 
    }
236
 
 
237
 
  G_OBJECT_CLASS (parent_class)->finalize (object);
238
 
}
239
 
 
240
 
static gboolean
241
 
gimp_align_tool_initialize (GimpTool     *tool,
242
 
                            GimpDisplay  *display,
243
 
                            GError      **error)
244
 
{
245
 
  if (tool->display != display)
246
 
    {
247
 
    }
248
 
 
249
 
  return TRUE;
 
166
gimp_align_tool_constructed (GObject *object)
 
167
{
 
168
  GimpAlignTool    *align_tool = GIMP_ALIGN_TOOL (object);
 
169
  GimpAlignOptions *options;
 
170
 
 
171
  if (G_OBJECT_CLASS (parent_class)->constructed)
 
172
    G_OBJECT_CLASS (parent_class)->constructed (object);
 
173
 
 
174
  options = GIMP_ALIGN_TOOL_GET_OPTIONS (align_tool);
 
175
 
 
176
  g_signal_connect_object (options, "align-button-clicked",
 
177
                           G_CALLBACK (gimp_align_tool_align),
 
178
                           align_tool, G_CONNECT_SWAPPED);
250
179
}
251
180
 
252
181
static void
263
192
      break;
264
193
 
265
194
    case GIMP_TOOL_ACTION_HALT:
266
 
      clear_all_selected_objects (align_tool);
 
195
      gimp_align_tool_clear_selected (align_tool);
267
196
      break;
268
197
    }
269
198
 
271
200
}
272
201
 
273
202
static void
274
 
gimp_align_tool_button_press (GimpTool        *tool,
275
 
                              GimpCoords      *coords,
276
 
                              guint32          time,
277
 
                              GdkModifierType  state,
278
 
                              GimpDisplay     *display)
 
203
gimp_align_tool_button_press (GimpTool            *tool,
 
204
                              const GimpCoords    *coords,
 
205
                              guint32              time,
 
206
                              GdkModifierType      state,
 
207
                              GimpButtonPressType  press_type,
 
208
                              GimpDisplay         *display)
279
209
{
280
 
  GimpAlignTool    *align_tool  = GIMP_ALIGN_TOOL (tool);
 
210
  GimpAlignTool *align_tool  = GIMP_ALIGN_TOOL (tool);
281
211
 
282
212
  gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
283
213
 
284
214
  /*  If the tool was being used in another image... reset it  */
285
 
 
286
215
  if (display != tool->display)
287
 
    {
288
 
      if (gimp_draw_tool_is_active (GIMP_DRAW_TOOL (tool)))
289
 
        gimp_draw_tool_stop (GIMP_DRAW_TOOL (tool));
290
 
 
291
 
      gimp_tool_pop_status (tool, display);
292
 
      clear_all_selected_objects (align_tool);
293
 
    }
294
 
 
295
 
  if (! gimp_tool_control_is_active (tool->control))
296
 
    gimp_tool_control_activate (tool->control);
 
216
    gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
297
217
 
298
218
  tool->display = display;
299
219
 
300
 
  align_tool->x1 = align_tool->x0 = coords->x;
301
 
  align_tool->y1 = align_tool->y0 = coords->y;
 
220
  gimp_tool_control_activate (tool->control);
 
221
 
 
222
  align_tool->x2 = align_tool->x1 = coords->x;
 
223
  align_tool->y2 = align_tool->y1 = coords->y;
302
224
 
303
225
  if (! gimp_draw_tool_is_active (GIMP_DRAW_TOOL (tool)))
304
226
    gimp_draw_tool_start (GIMP_DRAW_TOOL (tool), display);
306
228
  gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
307
229
}
308
230
 
309
 
/*
310
 
 * some rather complex logic here.  If the user clicks without modifiers,
 
231
/* some rather complex logic here.  If the user clicks without modifiers,
311
232
 * then we start a new list, and use the first object in it as reference.
312
233
 * If the user clicks using Shift, or draws a rubber-band box, then
313
234
 * we add objects to the list, but do not specify which one should
315
236
 */
316
237
static void
317
238
gimp_align_tool_button_release (GimpTool              *tool,
318
 
                                GimpCoords            *coords,
 
239
                                const GimpCoords      *coords,
319
240
                                guint32                time,
320
241
                                GdkModifierType        state,
321
242
                                GimpButtonReleaseType  release_type,
322
243
                                GimpDisplay           *display)
323
244
{
324
245
  GimpAlignTool    *align_tool = GIMP_ALIGN_TOOL (tool);
325
 
  GimpDisplayShell *shell      = GIMP_DISPLAY_SHELL (display->shell);
 
246
  GimpAlignOptions *options    = GIMP_ALIGN_TOOL_GET_OPTIONS (tool);
 
247
  GimpDisplayShell *shell      = gimp_display_get_shell (display);
326
248
  GObject          *object     = NULL;
327
 
  GimpImage        *image      = display->image;
 
249
  GimpImage        *image      = gimp_display_get_image (display);
 
250
  GdkModifierType   extend_mask;
328
251
  gint              i;
329
252
 
 
253
  extend_mask = gimp_get_extend_selection_mask ();
 
254
 
330
255
  gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
331
256
 
 
257
  gimp_tool_control_halt (tool->control);
 
258
 
332
259
  if (release_type == GIMP_BUTTON_RELEASE_CANCEL)
333
260
    {
334
 
      align_tool->x1 = align_tool->x0;
335
 
      align_tool->y1 = align_tool->y0;
 
261
      align_tool->x2 = align_tool->x1;
 
262
      align_tool->y2 = align_tool->y1;
336
263
 
337
264
      gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
338
265
      return;
339
266
    }
340
267
 
341
 
  if (! (state & GDK_SHIFT_MASK)) /* start a new list */
 
268
  if (! (state & extend_mask)) /* start a new list */
342
269
    {
343
 
      clear_all_selected_objects (align_tool);
 
270
      gimp_align_tool_clear_selected (align_tool);
344
271
      align_tool->set_reference = FALSE;
345
272
    }
346
273
 
347
 
  /* if mouse has moved less than EPSILON pixels since button press, select
348
 
     the nearest thing, otherwise make a rubber-band rectangle */
349
 
  if (hypot (coords->x - align_tool->x0, coords->y - align_tool->y0) < EPSILON)
 
274
  /* if mouse has moved less than EPSILON pixels since button press,
 
275
   * select the nearest thing, otherwise make a rubber-band rectangle
 
276
   */
 
277
  if (hypot (coords->x - align_tool->x1,
 
278
             coords->y - align_tool->y1) < EPSILON)
350
279
    {
351
280
      GimpVectors *vectors;
352
281
      GimpGuide   *guide;
353
282
      GimpLayer   *layer;
354
 
      gint         snap_distance;
355
 
 
356
 
      snap_distance =
357
 
        GIMP_DISPLAY_CONFIG (display->image->gimp->config)->snap_distance;
 
283
      gint         snap_distance = display->config->snap_distance;
358
284
 
359
285
      if (gimp_draw_tool_on_vectors (GIMP_DRAW_TOOL (tool), display,
360
286
                                     coords, snap_distance, snap_distance,
364
290
          object = G_OBJECT (vectors);
365
291
        }
366
292
      else if (gimp_display_shell_get_show_guides (shell) &&
367
 
               (guide = gimp_image_find_guide (display->image,
 
293
               (guide = gimp_image_find_guide (image,
368
294
                                               coords->x, coords->y,
369
295
                                               FUNSCALEX (shell, snap_distance),
370
296
                                               FUNSCALEY (shell, snap_distance))))
373
299
        }
374
300
      else
375
301
        {
376
 
          if ((layer = select_layer_by_coords (display->image,
377
 
                                               coords->x, coords->y)))
 
302
          if ((layer = gimp_image_pick_layer_by_bounds (image,
 
303
                                                        coords->x, coords->y)))
378
304
            {
379
305
              object = G_OBJECT (layer);
380
306
            }
384
310
        {
385
311
          if (! g_list_find (align_tool->selected_objects, object))
386
312
            {
387
 
              align_tool->selected_objects
388
 
                = g_list_append (align_tool->selected_objects, object);
 
313
              align_tool->selected_objects =
 
314
                g_list_append (align_tool->selected_objects, object);
 
315
 
389
316
              g_signal_connect (object, "removed",
390
 
                                G_CALLBACK (clear_selected_object),
391
 
                                (gpointer) align_tool);
 
317
                                G_CALLBACK (gimp_align_tool_object_removed),
 
318
                                align_tool);
392
319
 
393
320
              /* if an object has been selected using unmodified click,
394
321
               * it should be used as the reference
395
322
               */
396
 
              if (! (state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)))
 
323
              if (! (state & extend_mask))
397
324
                align_tool->set_reference = TRUE;
398
325
            }
399
326
        }
400
327
    }
401
328
  else  /* FIXME: look for vectors too */
402
329
    {
403
 
      gint   X0    = MIN (coords->x, align_tool->x0);
404
 
      gint   X1    = MAX (coords->x, align_tool->x0);
405
 
      gint   Y0    = MIN (coords->y, align_tool->y0);
406
 
      gint   Y1    = MAX (coords->y, align_tool->y0);
 
330
      gint   X0 = MIN (coords->x, align_tool->x1);
 
331
      gint   X1 = MAX (coords->x, align_tool->x1);
 
332
      gint   Y0 = MIN (coords->y, align_tool->y1);
 
333
      gint   Y1 = MAX (coords->y, align_tool->y1);
 
334
      GList *all_layers;
407
335
      GList *list;
408
336
 
409
 
      for (list = GIMP_LIST (image->layers)->list;
410
 
           list;
411
 
           list = g_list_next (list))
 
337
      all_layers = gimp_image_get_layer_list (image);
 
338
 
 
339
      for (list = all_layers; list; list = g_list_next (list))
412
340
        {
413
341
          GimpLayer *layer = list->data;
414
342
          gint       x0, y0, x1, y1;
416
344
          if (! gimp_item_get_visible (GIMP_ITEM (layer)))
417
345
            continue;
418
346
 
419
 
          gimp_item_offsets (GIMP_ITEM (layer), &x0, &y0);
420
 
          x1 = x0 + gimp_item_width (GIMP_ITEM (layer));
421
 
          y1 = y0 + gimp_item_height (GIMP_ITEM (layer));
 
347
          gimp_item_get_offset (GIMP_ITEM (layer), &x0, &y0);
 
348
          x1 = x0 + gimp_item_get_width  (GIMP_ITEM (layer));
 
349
          y1 = y0 + gimp_item_get_height (GIMP_ITEM (layer));
422
350
 
423
351
          if (x0 < X0 || y0 < Y0 || x1 > X1 || y1 > Y1)
424
352
            continue;
426
354
          if (g_list_find (align_tool->selected_objects, layer))
427
355
            continue;
428
356
 
429
 
          align_tool->selected_objects
430
 
            = g_list_append (align_tool->selected_objects, layer);
431
 
          g_signal_connect (layer, "removed", G_CALLBACK (clear_selected_object),
432
 
                            (gpointer) align_tool);
 
357
          align_tool->selected_objects =
 
358
            g_list_append (align_tool->selected_objects, layer);
 
359
 
 
360
          g_signal_connect (layer, "removed",
 
361
                            G_CALLBACK (gimp_align_tool_object_removed),
 
362
                            align_tool);
433
363
        }
 
364
 
 
365
      g_list_free (all_layers);
434
366
    }
435
367
 
436
 
  for (i = 0; i < ALIGN_TOOL_NUM_BUTTONS; i++)
 
368
  for (i = 0; i < ALIGN_OPTIONS_N_BUTTONS; i++)
437
369
    {
438
 
      if (align_tool->button[i])
439
 
        {
440
 
          gtk_widget_set_sensitive (align_tool->button[i],
441
 
                                    (align_tool->selected_objects != NULL));
442
 
        }
 
370
      if (options->button[i])
 
371
        gtk_widget_set_sensitive (options->button[i],
 
372
                                  align_tool->selected_objects != NULL);
443
373
    }
444
374
 
445
 
  align_tool->x1 = align_tool->x0;
446
 
  align_tool->y1 = align_tool->y0;
 
375
  align_tool->x2 = align_tool->x1;
 
376
  align_tool->y2 = align_tool->y1;
447
377
 
448
378
  gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
449
379
}
450
380
 
451
381
static void
452
 
gimp_align_tool_motion (GimpTool        *tool,
453
 
                        GimpCoords      *coords,
454
 
                        guint32          time,
455
 
                        GdkModifierType  state,
456
 
                        GimpDisplay     *display)
 
382
gimp_align_tool_motion (GimpTool         *tool,
 
383
                        const GimpCoords *coords,
 
384
                        guint32           time,
 
385
                        GdkModifierType   state,
 
386
                        GimpDisplay      *display)
457
387
{
458
388
  GimpAlignTool *align_tool = GIMP_ALIGN_TOOL (tool);
459
389
 
460
390
  gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
461
391
 
462
 
  align_tool->x1 = coords->x;
463
 
  align_tool->y1 = coords->y;
 
392
  align_tool->x2 = coords->x;
 
393
  align_tool->y2 = coords->y;
464
394
 
465
395
  gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
466
396
}
467
397
 
 
398
static gboolean
 
399
gimp_align_tool_key_press (GimpTool    *tool,
 
400
                           GdkEventKey *kevent,
 
401
                           GimpDisplay *display)
 
402
{
 
403
  if (display == tool->display)
 
404
    {
 
405
      switch (kevent->keyval)
 
406
        {
 
407
        case GDK_KEY_Escape:
 
408
          gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
 
409
          return TRUE;
 
410
 
 
411
        default:
 
412
          break;
 
413
        }
 
414
    }
 
415
 
 
416
  return FALSE;
 
417
}
 
418
 
468
419
static void
469
 
gimp_align_tool_oper_update (GimpTool        *tool,
470
 
                             GimpCoords      *coords,
471
 
                             GdkModifierType  state,
472
 
                             gboolean         proximity,
473
 
                             GimpDisplay     *display)
 
420
gimp_align_tool_oper_update (GimpTool         *tool,
 
421
                             const GimpCoords *coords,
 
422
                             GdkModifierType   state,
 
423
                             gboolean          proximity,
 
424
                             GimpDisplay      *display)
474
425
{
475
 
  GimpAlignTool      *align_tool  = GIMP_ALIGN_TOOL (tool);
476
 
  GimpDisplayShell   *shell       = GIMP_DISPLAY_SHELL (display->shell);
477
 
  gint                snap_distance;
 
426
  GimpAlignTool    *align_tool    = GIMP_ALIGN_TOOL (tool);
 
427
  GimpDisplayShell *shell         = gimp_display_get_shell (display);
 
428
  GimpImage        *image         = gimp_display_get_image (display);
 
429
  gint              snap_distance = display->config->snap_distance;
 
430
  gboolean          add;
478
431
 
479
 
  snap_distance =
480
 
    GIMP_DISPLAY_CONFIG (display->image->gimp->config)->snap_distance;
 
432
  add = ((state & gimp_get_extend_selection_mask ()) &&
 
433
         align_tool->selected_objects);
481
434
 
482
435
  if (gimp_draw_tool_on_vectors (GIMP_DRAW_TOOL (tool), display,
483
436
                                 coords, snap_distance, snap_distance,
484
437
                                 NULL, NULL, NULL, NULL, NULL, NULL))
485
438
    {
486
 
      if ((state & GDK_SHIFT_MASK) && align_tool->selected_objects)
 
439
      if (add)
487
440
        align_tool->function = ALIGN_TOOL_ADD_PATH;
488
441
      else
489
442
        align_tool->function = ALIGN_TOOL_PICK_PATH;
490
443
    }
491
444
  else if (gimp_display_shell_get_show_guides (shell) &&
492
 
           (NULL != gimp_image_find_guide (display->image,
493
 
                                           coords->x, coords->y,
494
 
                                           FUNSCALEX (shell, snap_distance),
495
 
                                           FUNSCALEY (shell, snap_distance))))
 
445
           gimp_image_find_guide (image,
 
446
                                  coords->x, coords->y,
 
447
                                  FUNSCALEX (shell, snap_distance),
 
448
                                  FUNSCALEY (shell, snap_distance)))
496
449
    {
497
 
      if ((state & GDK_SHIFT_MASK) && align_tool->selected_objects)
 
450
      if (add)
498
451
        align_tool->function = ALIGN_TOOL_ADD_GUIDE;
499
452
      else
500
453
        align_tool->function = ALIGN_TOOL_PICK_GUIDE;
501
454
    }
502
455
  else
503
456
    {
504
 
      GimpLayer *layer = select_layer_by_coords (display->image,
505
 
                                                 coords->x, coords->y);
 
457
      GimpLayer *layer;
 
458
 
 
459
      layer = gimp_image_pick_layer_by_bounds (image, coords->x, coords->y);
506
460
 
507
461
      if (layer)
508
462
        {
509
 
          if ((state & GDK_SHIFT_MASK) && align_tool->selected_objects)
 
463
          if (add)
510
464
            align_tool->function = ALIGN_TOOL_ADD_LAYER;
511
465
          else
512
466
            align_tool->function = ALIGN_TOOL_PICK_LAYER;
521
475
}
522
476
 
523
477
static void
524
 
gimp_align_tool_cursor_update (GimpTool        *tool,
525
 
                               GimpCoords      *coords,
526
 
                               GdkModifierType  state,
527
 
                               GimpDisplay     *display)
 
478
gimp_align_tool_cursor_update (GimpTool         *tool,
 
479
                               const GimpCoords *coords,
 
480
                               GdkModifierType   state,
 
481
                               GimpDisplay      *display)
528
482
{
529
483
  GimpAlignTool      *align_tool  = GIMP_ALIGN_TOOL (tool);
530
484
  GimpToolCursorType  tool_cursor = GIMP_TOOL_CURSOR_NONE;
531
485
  GimpCursorModifier  modifier    = GIMP_CURSOR_MODIFIER_NONE;
532
486
 
533
 
  if (state & GDK_SHIFT_MASK)
534
 
    {
535
 
      /* always add '+' when Shift is pressed, even if nothing is selected */
536
 
      modifier = GIMP_CURSOR_MODIFIER_PLUS;
537
 
    }
 
487
  /* always add '+' when Shift is pressed, even if nothing is selected */
 
488
  if (state & gimp_get_extend_selection_mask ())
 
489
    modifier = GIMP_CURSOR_MODIFIER_PLUS;
538
490
 
539
491
  switch (align_tool->function)
540
492
    {
558
510
      break;
559
511
 
560
512
    case ALIGN_TOOL_DRAG_BOX:
561
 
      /* FIXME: it would be nice to add something here, but we cannot easily
562
 
         detect when the tool is in this mode (the draw tool is always active)
563
 
         so this state is not used for the moment.
564
 
      */
565
513
      break;
566
514
    }
567
515
 
578
526
                               GdkModifierType  state,
579
527
                               gboolean         proximity)
580
528
{
581
 
  GimpAlignTool *align_tool = GIMP_ALIGN_TOOL (tool);
 
529
  GimpAlignTool   *align_tool = GIMP_ALIGN_TOOL (tool);
 
530
  GdkModifierType  extend_mask;
 
531
 
 
532
  extend_mask = gimp_get_extend_selection_mask ();
582
533
 
583
534
  gimp_tool_pop_status (tool, display);
584
535
 
585
536
  if (proximity)
586
537
    {
587
 
      const gchar *status      = NULL;
588
 
      gboolean     free_status = FALSE;
 
538
      gchar *status = NULL;
589
539
 
590
540
      if (! align_tool->selected_objects)
591
541
        {
592
542
          /* no need to suggest Shift if nothing is selected */
593
 
          state |= GDK_SHIFT_MASK;
 
543
          state |= extend_mask;
594
544
        }
595
545
 
596
546
      switch (align_tool->function)
599
549
          status = gimp_suggest_modifiers (_("Click on a layer, path or guide, "
600
550
                                             "or Click-Drag to pick several "
601
551
                                             "layers"),
602
 
                                           GDK_SHIFT_MASK & ~state,
 
552
                                           extend_mask & ~state,
603
553
                                           NULL, NULL, NULL);
604
 
          free_status = TRUE;
605
554
          break;
606
555
 
607
556
        case ALIGN_TOOL_PICK_LAYER:
608
557
          status = gimp_suggest_modifiers (_("Click to pick this layer as "
609
558
                                             "first item"),
610
 
                                           GDK_SHIFT_MASK & ~state,
 
559
                                           extend_mask & ~state,
611
560
                                           NULL, NULL, NULL);
612
 
          free_status = TRUE;
613
561
          break;
614
562
 
615
563
        case ALIGN_TOOL_ADD_LAYER:
616
 
          status = _("Click to add this layer to the list");
 
564
          status = g_strdup (_("Click to add this layer to the list"));
617
565
          break;
618
566
 
619
567
        case ALIGN_TOOL_PICK_GUIDE:
620
568
          status = gimp_suggest_modifiers (_("Click to pick this guide as "
621
569
                                             "first item"),
622
 
                                           GDK_SHIFT_MASK & ~state,
 
570
                                           extend_mask & ~state,
623
571
                                           NULL, NULL, NULL);
624
 
          free_status = TRUE;
625
572
          break;
626
573
 
627
574
        case ALIGN_TOOL_ADD_GUIDE:
628
 
          status = _("Click to add this guide to the list");
 
575
          status = g_strdup (_("Click to add this guide to the list"));
629
576
          break;
630
577
 
631
578
        case ALIGN_TOOL_PICK_PATH:
632
579
          status = gimp_suggest_modifiers (_("Click to pick this path as "
633
580
                                             "first item"),
634
 
                                           GDK_SHIFT_MASK & ~state,
 
581
                                           extend_mask & ~state,
635
582
                                           NULL, NULL, NULL);
636
 
          free_status = TRUE;
637
583
          break;
638
584
 
639
585
        case ALIGN_TOOL_ADD_PATH:
640
 
          status = _("Click to add this path to the list");
 
586
          status = g_strdup (_("Click to add this path to the list"));
641
587
          break;
642
588
 
643
589
        case ALIGN_TOOL_DRAG_BOX:
645
591
        }
646
592
 
647
593
      if (status)
648
 
        gimp_tool_push_status (tool, display, "%s", status);
649
 
 
650
 
      if (free_status)
651
 
        g_free ((gchar *) status);
 
594
        {
 
595
          gimp_tool_push_status (tool, display, "%s", status);
 
596
          g_free (status);
 
597
        }
652
598
    }
653
599
}
654
600
 
660
606
  gint           x, y, w, h;
661
607
 
662
608
  /* draw rubber-band rectangle */
663
 
  x = MIN (align_tool->x1, align_tool->x0);
664
 
  y = MIN (align_tool->y1, align_tool->y0);
665
 
  w = MAX (align_tool->x1, align_tool->x0) - x;
666
 
  h = MAX (align_tool->y1, align_tool->y0) - y;
667
 
 
668
 
  gimp_draw_tool_draw_rectangle (draw_tool,
669
 
                                 FALSE,
670
 
                                 x, y,w, h,
671
 
                                 FALSE);
672
 
 
673
 
  for (list = g_list_first (align_tool->selected_objects); list;
 
609
  x = MIN (align_tool->x2, align_tool->x1);
 
610
  y = MIN (align_tool->y2, align_tool->y1);
 
611
  w = MAX (align_tool->x2, align_tool->x1) - x;
 
612
  h = MAX (align_tool->y2, align_tool->y1) - y;
 
613
 
 
614
  gimp_draw_tool_add_rectangle (draw_tool, FALSE, x, y, w, h);
 
615
 
 
616
  for (list = align_tool->selected_objects;
 
617
       list;
674
618
       list = g_list_next (list))
675
619
    {
676
620
      if (GIMP_IS_ITEM (list->data))
677
621
        {
678
 
          GimpItem *item = GIMP_ITEM (list->data);
 
622
          GimpItem *item = list->data;
679
623
 
680
 
          if (GIMP_IS_VECTORS (list->data))
 
624
          if (GIMP_IS_VECTORS (item))
681
625
            {
682
626
              gdouble x1_f, y1_f, x2_f, y2_f;
683
627
 
691
635
            }
692
636
          else
693
637
            {
694
 
              gimp_item_offsets (item, &x, &y);
 
638
              gimp_item_get_offset (item, &x, &y);
695
639
 
696
 
              w = gimp_item_width (item);
697
 
              h = gimp_item_height (item);
 
640
              w = gimp_item_get_width  (item);
 
641
              h = gimp_item_get_height (item);
698
642
            }
699
643
 
700
 
          gimp_draw_tool_draw_handle (draw_tool, GIMP_HANDLE_FILLED_SQUARE,
701
 
                                      x, y, MARKER_WIDTH, MARKER_WIDTH,
702
 
                                      GTK_ANCHOR_NORTH_WEST, FALSE);
703
 
          gimp_draw_tool_draw_handle (draw_tool, GIMP_HANDLE_FILLED_SQUARE,
704
 
                                      x + w, y, MARKER_WIDTH, MARKER_WIDTH,
705
 
                                      GTK_ANCHOR_NORTH_EAST, FALSE);
706
 
          gimp_draw_tool_draw_handle (draw_tool, GIMP_HANDLE_FILLED_SQUARE,
707
 
                                      x, y + h, MARKER_WIDTH, MARKER_WIDTH,
708
 
                                      GTK_ANCHOR_SOUTH_WEST, FALSE);
709
 
          gimp_draw_tool_draw_handle (draw_tool, GIMP_HANDLE_FILLED_SQUARE,
710
 
                                      x + w, y + h, MARKER_WIDTH, MARKER_WIDTH,
711
 
                                      GTK_ANCHOR_SOUTH_EAST, FALSE);
 
644
          gimp_draw_tool_add_handle (draw_tool, GIMP_HANDLE_FILLED_SQUARE,
 
645
                                     x, y,
 
646
                                     GIMP_TOOL_HANDLE_SIZE_SMALL,
 
647
                                     GIMP_TOOL_HANDLE_SIZE_SMALL,
 
648
                                     GIMP_HANDLE_ANCHOR_NORTH_WEST);
 
649
          gimp_draw_tool_add_handle (draw_tool, GIMP_HANDLE_FILLED_SQUARE,
 
650
                                     x + w, y,
 
651
                                     GIMP_TOOL_HANDLE_SIZE_SMALL,
 
652
                                     GIMP_TOOL_HANDLE_SIZE_SMALL,
 
653
                                     GIMP_HANDLE_ANCHOR_NORTH_EAST);
 
654
          gimp_draw_tool_add_handle (draw_tool, GIMP_HANDLE_FILLED_SQUARE,
 
655
                                     x, y + h,
 
656
                                     GIMP_TOOL_HANDLE_SIZE_SMALL,
 
657
                                     GIMP_TOOL_HANDLE_SIZE_SMALL,
 
658
                                     GIMP_HANDLE_ANCHOR_SOUTH_WEST);
 
659
          gimp_draw_tool_add_handle (draw_tool, GIMP_HANDLE_FILLED_SQUARE,
 
660
                                     x + w, y + h,
 
661
                                     GIMP_TOOL_HANDLE_SIZE_SMALL,
 
662
                                     GIMP_TOOL_HANDLE_SIZE_SMALL,
 
663
                                     GIMP_HANDLE_ANCHOR_SOUTH_EAST);
712
664
        }
713
665
      else if (GIMP_IS_GUIDE (list->data))
714
666
        {
715
 
          GimpGuide *guide = GIMP_GUIDE (list->data);
716
 
          GimpImage *image = GIMP_TOOL (draw_tool)->display->image;
 
667
          GimpGuide *guide = list->data;
 
668
          GimpImage *image = gimp_display_get_image (GIMP_TOOL (draw_tool)->display);
717
669
          gint       x, y;
718
670
          gint       w, h;
719
671
 
722
674
            case GIMP_ORIENTATION_VERTICAL:
723
675
              x = gimp_guide_get_position (guide);
724
676
              h = gimp_image_get_height (image);
725
 
              gimp_draw_tool_draw_handle (draw_tool, GIMP_HANDLE_FILLED_SQUARE,
726
 
                                          x, h, MARKER_WIDTH, MARKER_WIDTH,
727
 
                                          GTK_ANCHOR_SOUTH, FALSE);
728
 
              gimp_draw_tool_draw_handle (draw_tool, GIMP_HANDLE_FILLED_SQUARE,
729
 
                                          x, 0, MARKER_WIDTH, MARKER_WIDTH,
730
 
                                          GTK_ANCHOR_NORTH, FALSE);
 
677
              gimp_draw_tool_add_handle (draw_tool, GIMP_HANDLE_FILLED_SQUARE,
 
678
                                         x, h,
 
679
                                         GIMP_TOOL_HANDLE_SIZE_SMALL,
 
680
                                         GIMP_TOOL_HANDLE_SIZE_SMALL,
 
681
                                         GIMP_HANDLE_ANCHOR_SOUTH);
 
682
              gimp_draw_tool_add_handle (draw_tool, GIMP_HANDLE_FILLED_SQUARE,
 
683
                                         x, 0,
 
684
                                         GIMP_TOOL_HANDLE_SIZE_SMALL,
 
685
                                         GIMP_TOOL_HANDLE_SIZE_SMALL,
 
686
                                         GIMP_HANDLE_ANCHOR_NORTH);
731
687
              break;
732
688
 
733
689
            case GIMP_ORIENTATION_HORIZONTAL:
734
690
              y = gimp_guide_get_position (guide);
735
691
              w = gimp_image_get_width (image);
736
 
              gimp_draw_tool_draw_handle (draw_tool, GIMP_HANDLE_FILLED_SQUARE,
737
 
                                          w, y, MARKER_WIDTH, MARKER_WIDTH,
738
 
                                          GTK_ANCHOR_EAST, FALSE);
739
 
              gimp_draw_tool_draw_handle (draw_tool, GIMP_HANDLE_FILLED_SQUARE,
740
 
                                          0, y, MARKER_WIDTH, MARKER_WIDTH,
741
 
                                          GTK_ANCHOR_WEST, FALSE);
 
692
              gimp_draw_tool_add_handle (draw_tool, GIMP_HANDLE_FILLED_SQUARE,
 
693
                                         w, y,
 
694
                                         GIMP_TOOL_HANDLE_SIZE_SMALL,
 
695
                                         GIMP_TOOL_HANDLE_SIZE_SMALL,
 
696
                                         GIMP_HANDLE_ANCHOR_EAST);
 
697
              gimp_draw_tool_add_handle (draw_tool, GIMP_HANDLE_FILLED_SQUARE,
 
698
                                         0, y,
 
699
                                         GIMP_TOOL_HANDLE_SIZE_SMALL,
 
700
                                         GIMP_TOOL_HANDLE_SIZE_SMALL,
 
701
                                         GIMP_HANDLE_ANCHOR_WEST);
742
702
              break;
743
703
 
744
704
            default:
748
708
    }
749
709
}
750
710
 
751
 
static GtkWidget *
752
 
gimp_align_tool_controls (GimpAlignTool *align_tool)
753
 
{
754
 
  GtkWidget *main_vbox;
755
 
  GtkWidget *vbox;
756
 
  GtkWidget *hbox;
757
 
  GtkWidget *frame;
758
 
  GtkWidget *label;
759
 
  GtkWidget *button;
760
 
  GtkWidget *spinbutton;
761
 
  GtkWidget *combo;
762
 
  gint       n = 0;
763
 
 
764
 
  main_vbox = gtk_vbox_new (FALSE, 12);
765
 
 
766
 
  frame = gimp_frame_new (_("Align"));
767
 
  gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
768
 
  gtk_widget_show (frame);
769
 
 
770
 
  vbox = gtk_vbox_new (FALSE, 6);
771
 
  gtk_container_add (GTK_CONTAINER (frame), vbox);
772
 
  gtk_widget_show (vbox);
773
 
 
774
 
  hbox = gtk_hbox_new (FALSE, 6);
775
 
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
776
 
  gtk_widget_show (hbox);
777
 
 
778
 
  frame = gimp_frame_new (_("Relative to:"));
779
 
  gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
780
 
  gtk_widget_show (frame);
781
 
 
782
 
  combo = gimp_enum_combo_box_new (GIMP_TYPE_ALIGN_REFERENCE);
783
 
  gtk_container_add (GTK_CONTAINER (frame), combo);
784
 
  gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo),
785
 
                              GIMP_ALIGN_REFERENCE_FIRST,
786
 
                              G_CALLBACK (gimp_int_combo_box_get_active),
787
 
                              &align_tool->align_reference_type);
788
 
  gtk_widget_show (combo);
789
 
 
790
 
  hbox = gtk_hbox_new (FALSE, 6);
791
 
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
792
 
  gtk_widget_show (hbox);
793
 
 
794
 
  button = button_with_stock (GIMP_ALIGN_LEFT, align_tool);
795
 
  align_tool->button[n++] = button;
796
 
  gimp_help_set_help_data (button, _("Align left edge of target"), NULL);
797
 
  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
798
 
  gtk_widget_show (button);
799
 
 
800
 
  button = button_with_stock (GIMP_ALIGN_HCENTER, align_tool);
801
 
  align_tool->button[n++] = button;
802
 
  gimp_help_set_help_data (button, _("Align center of target"), NULL);
803
 
  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
804
 
  gtk_widget_show (button);
805
 
 
806
 
  button = button_with_stock (GIMP_ALIGN_RIGHT, align_tool);
807
 
  align_tool->button[n++] = button;
808
 
  gimp_help_set_help_data (button, _("Align right edge of target"), NULL);
809
 
  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
810
 
  gtk_widget_show (button);
811
 
 
812
 
  hbox = gtk_hbox_new (FALSE, 6);
813
 
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
814
 
  gtk_widget_show (hbox);
815
 
 
816
 
  button = button_with_stock (GIMP_ALIGN_TOP, align_tool);
817
 
  align_tool->button[n++] = button;
818
 
  gimp_help_set_help_data (button, _("Align top edge of target"), NULL);
819
 
  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
820
 
  gtk_widget_show (button);
821
 
 
822
 
  button = button_with_stock (GIMP_ALIGN_VCENTER, align_tool);
823
 
  align_tool->button[n++] = button;
824
 
  gimp_help_set_help_data (button, _("Align middle of target"), NULL);
825
 
  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
826
 
  gtk_widget_show (button);
827
 
 
828
 
  button = button_with_stock (GIMP_ALIGN_BOTTOM, align_tool);
829
 
  align_tool->button[n++] = button;
830
 
  gimp_help_set_help_data (button, _("Align bottom of target"), NULL);
831
 
  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
832
 
  gtk_widget_show (button);
833
 
 
834
 
  frame = gimp_frame_new (_("Distribute"));
835
 
  gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
836
 
  gtk_widget_show (frame);
837
 
 
838
 
  vbox = gtk_vbox_new (FALSE, 6);
839
 
  gtk_container_add (GTK_CONTAINER (frame), vbox);
840
 
  gtk_widget_show (vbox);
841
 
 
842
 
  hbox = gtk_hbox_new (FALSE, 6);
843
 
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
844
 
  gtk_widget_show (hbox);
845
 
 
846
 
  button = button_with_stock (GIMP_ARRANGE_LEFT, align_tool);
847
 
  align_tool->button[n++] = button;
848
 
  gimp_help_set_help_data (button, _("Distribute left edges of targets"), NULL);
849
 
  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
850
 
  gtk_widget_show (button);
851
 
 
852
 
  button = button_with_stock (GIMP_ARRANGE_HCENTER, align_tool);
853
 
  align_tool->button[n++] = button;
854
 
  gimp_help_set_help_data (button,
855
 
                           _("Distribute horizontal centers of targets"), NULL);
856
 
  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
857
 
  gtk_widget_show (button);
858
 
 
859
 
  button = button_with_stock (GIMP_ARRANGE_RIGHT, align_tool);
860
 
  align_tool->button[n++] = button;
861
 
  gimp_help_set_help_data (button,
862
 
                           _("Distribute right edges of targets"), NULL);
863
 
  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
864
 
  gtk_widget_show (button);
865
 
 
866
 
  hbox = gtk_hbox_new (FALSE, 6);
867
 
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
868
 
  gtk_widget_show (hbox);
869
 
 
870
 
  button = button_with_stock (GIMP_ARRANGE_TOP, align_tool);
871
 
  align_tool->button[n++] = button;
872
 
  gimp_help_set_help_data (button, _("Distribute top edges of targets"), NULL);
873
 
  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
874
 
  gtk_widget_show (button);
875
 
 
876
 
  button = button_with_stock (GIMP_ARRANGE_VCENTER, align_tool);
877
 
  align_tool->button[n++] = button;
878
 
  gimp_help_set_help_data (button,
879
 
                           _("Distribute vertical centers of targets"), NULL);
880
 
  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
881
 
  gtk_widget_show (button);
882
 
 
883
 
  button = button_with_stock (GIMP_ARRANGE_BOTTOM, align_tool);
884
 
  align_tool->button[n++] = button;
885
 
  gimp_help_set_help_data (button, _("Distribute bottoms of targets"), NULL);
886
 
  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
887
 
  gtk_widget_show (button);
888
 
 
889
 
  hbox = gtk_hbox_new (FALSE, 6);
890
 
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
891
 
  gtk_widget_show (hbox);
892
 
 
893
 
  label = gtk_label_new (_("Offset:"));
894
 
  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
895
 
  gtk_widget_show (label);
896
 
 
897
 
  spinbutton = gimp_spin_button_new (&align_tool->horz_offset_adjustment,
898
 
                                     0,
899
 
                                     -100000,
900
 
                                     100000,
901
 
                                     1, 20, 0, 1, 0);
902
 
  gtk_box_pack_start (GTK_BOX (hbox), spinbutton, FALSE, FALSE, 0);
903
 
  g_signal_connect (align_tool->horz_offset_adjustment, "value-changed",
904
 
                    G_CALLBACK (gimp_double_adjustment_update),
905
 
                    &align_tool->horz_offset);
906
 
  gtk_widget_show (spinbutton);
907
 
 
908
 
  return main_vbox;
909
 
}
910
 
 
911
 
 
912
711
static void
913
 
do_alignment (GtkWidget *widget,
914
 
              gpointer   data)
 
712
gimp_align_tool_align (GimpAlignTool     *align_tool,
 
713
                       GimpAlignmentType  align_type)
915
714
{
916
 
  GimpAlignTool     *align_tool       = GIMP_ALIGN_TOOL (data);
917
 
  GimpAlignmentType  action;
918
 
  GimpImage         *image;
919
 
  GObject           *reference_object = NULL;
920
 
  GList             *list;
921
 
  gint               offset;
922
 
 
923
 
  image  = GIMP_TOOL (align_tool)->display->image;
924
 
  action = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "action"));
925
 
  offset = align_tool->horz_offset;
926
 
 
927
 
  switch (action)
 
715
  GimpAlignOptions *options = GIMP_ALIGN_TOOL_GET_OPTIONS (align_tool);
 
716
  GimpImage        *image;
 
717
  GObject          *reference_object = NULL;
 
718
  GList            *list;
 
719
  gint              offset = 0;
 
720
 
 
721
  /* if nothing is selected, just return */
 
722
  if (! align_tool->selected_objects)
 
723
    return;
 
724
 
 
725
  image  = gimp_display_get_image (GIMP_TOOL (align_tool)->display);
 
726
 
 
727
  switch (align_type)
928
728
    {
929
729
    case GIMP_ALIGN_LEFT:
930
730
    case GIMP_ALIGN_HCENTER:
934
734
    case GIMP_ALIGN_BOTTOM:
935
735
      offset = 0;
936
736
      break;
 
737
 
937
738
    case GIMP_ARRANGE_LEFT:
938
739
    case GIMP_ARRANGE_HCENTER:
939
740
    case GIMP_ARRANGE_RIGHT:
940
741
    case GIMP_ARRANGE_TOP:
941
742
    case GIMP_ARRANGE_VCENTER:
942
743
    case GIMP_ARRANGE_BOTTOM:
943
 
      offset = align_tool->horz_offset;
 
744
      offset = options->offset_x;
944
745
      break;
945
746
    }
946
747
 
947
 
  /* if nothing is selected, just return */
948
 
  if (g_list_length (align_tool->selected_objects) == 0)
949
 
    return;
950
 
 
951
748
  /* if only one object is selected, use the image as reference
952
749
   * if multiple objects are selected, use the first one as reference if
953
750
   * "set_reference" is TRUE, otherwise use NULL.
955
752
 
956
753
  list = align_tool->selected_objects;
957
754
 
958
 
  switch (align_tool->align_reference_type)
 
755
  switch (options->align_reference)
959
756
    {
960
757
    case GIMP_ALIGN_REFERENCE_IMAGE:
961
758
      reference_object = G_OBJECT (image);
962
759
      break;
963
760
 
964
761
    case GIMP_ALIGN_REFERENCE_FIRST:
965
 
      if (g_list_length (align_tool->selected_objects) == 1)
 
762
      if (g_list_length (list) == 1)
966
763
        {
967
764
          reference_object = G_OBJECT (image);
968
765
        }
970
767
        {
971
768
          if (align_tool->set_reference)
972
769
            {
973
 
              reference_object = G_OBJECT (align_tool->selected_objects->data);
974
 
              list = g_list_next (align_tool->selected_objects);
 
770
              reference_object = G_OBJECT (list->data);
 
771
              list = g_list_next (list);
975
772
            }
976
773
          else
977
774
            {
1003
800
  gimp_draw_tool_pause (GIMP_DRAW_TOOL (align_tool));
1004
801
 
1005
802
  gimp_image_arrange_objects (image, list,
1006
 
                              action,
 
803
                              align_type,
1007
804
                              reference_object,
1008
 
                              action,
 
805
                              align_type,
1009
806
                              offset);
1010
807
 
1011
808
  gimp_draw_tool_resume (GIMP_DRAW_TOOL (align_tool));
1013
810
  gimp_image_flush (image);
1014
811
}
1015
812
 
1016
 
static GtkWidget *
1017
 
button_with_stock (GimpAlignmentType  action,
1018
 
                   GimpAlignTool     *align_tool)
1019
 
{
1020
 
  GtkWidget   *button;
1021
 
  GtkWidget   *image;
1022
 
  const gchar *stock_id = NULL;
1023
 
 
1024
 
  switch (action)
1025
 
    {
1026
 
    case GIMP_ALIGN_LEFT:
1027
 
      stock_id = GIMP_STOCK_GRAVITY_WEST;
1028
 
      break;
1029
 
    case GIMP_ALIGN_HCENTER:
1030
 
      stock_id = GIMP_STOCK_HCENTER;
1031
 
      break;
1032
 
    case GIMP_ALIGN_RIGHT:
1033
 
      stock_id = GIMP_STOCK_GRAVITY_EAST;
1034
 
      break;
1035
 
    case GIMP_ALIGN_TOP:
1036
 
      stock_id = GIMP_STOCK_GRAVITY_NORTH;
1037
 
      break;
1038
 
    case GIMP_ALIGN_VCENTER:
1039
 
      stock_id = GIMP_STOCK_VCENTER;
1040
 
      break;
1041
 
    case GIMP_ALIGN_BOTTOM:
1042
 
      stock_id = GIMP_STOCK_GRAVITY_SOUTH;
1043
 
      break;
1044
 
    case GIMP_ARRANGE_LEFT:
1045
 
      stock_id = GIMP_STOCK_GRAVITY_WEST;
1046
 
      break;
1047
 
    case GIMP_ARRANGE_HCENTER:
1048
 
      stock_id = GIMP_STOCK_HCENTER;
1049
 
      break;
1050
 
    case GIMP_ARRANGE_RIGHT:
1051
 
      stock_id = GIMP_STOCK_GRAVITY_EAST;
1052
 
      break;
1053
 
    case GIMP_ARRANGE_TOP:
1054
 
      stock_id = GIMP_STOCK_GRAVITY_NORTH;
1055
 
      break;
1056
 
    case GIMP_ARRANGE_VCENTER:
1057
 
      stock_id = GIMP_STOCK_VCENTER;
1058
 
      break;
1059
 
    case GIMP_ARRANGE_BOTTOM:
1060
 
      stock_id = GIMP_STOCK_GRAVITY_SOUTH;
1061
 
      break;
1062
 
    default:
1063
 
      g_return_val_if_reached (NULL);
1064
 
      break;
1065
 
    }
1066
 
 
1067
 
  button = gtk_button_new ();
1068
 
  g_object_set_data (G_OBJECT (button), "action", GINT_TO_POINTER (action));
1069
 
 
1070
 
  image = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_BUTTON);
1071
 
  gtk_misc_set_padding (GTK_MISC (image), 2, 2);
1072
 
  gtk_container_add (GTK_CONTAINER (button), image);
1073
 
  gtk_widget_show (image);
1074
 
 
1075
 
  g_signal_connect (button, "clicked",
1076
 
                    G_CALLBACK (do_alignment),
1077
 
                    align_tool);
1078
 
 
1079
 
  gtk_widget_set_sensitive (button, FALSE);
1080
 
  gtk_widget_show (button);
1081
 
 
1082
 
  return button;
1083
 
}
1084
 
 
1085
813
static void
1086
 
clear_selected_object (GObject       *object,
1087
 
                       GimpAlignTool *align_tool)
 
814
gimp_align_tool_object_removed (GObject       *object,
 
815
                                GimpAlignTool *align_tool)
1088
816
{
1089
817
  gimp_draw_tool_pause (GIMP_DRAW_TOOL (align_tool));
1090
818
 
1091
819
  if (align_tool->selected_objects)
1092
820
    g_signal_handlers_disconnect_by_func (object,
1093
 
                                          G_CALLBACK (clear_selected_object),
1094
 
                                          (gpointer) align_tool);
 
821
                                          gimp_align_tool_object_removed,
 
822
                                          align_tool);
1095
823
 
1096
824
  align_tool->selected_objects = g_list_remove (align_tool->selected_objects,
1097
825
                                                object);
1100
828
}
1101
829
 
1102
830
static void
1103
 
clear_all_selected_objects (GimpAlignTool *align_tool)
 
831
gimp_align_tool_clear_selected (GimpAlignTool *align_tool)
1104
832
{
1105
 
  GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (align_tool);
1106
 
 
1107
 
  if (gimp_draw_tool_is_active (draw_tool))
1108
 
    gimp_draw_tool_pause (draw_tool);
 
833
  gimp_draw_tool_pause (GIMP_DRAW_TOOL (align_tool));
1109
834
 
1110
835
  while (align_tool->selected_objects)
1111
 
    {
1112
 
      GObject *object = G_OBJECT (g_list_first (align_tool->selected_objects)->data);
1113
 
 
1114
 
      g_signal_handlers_disconnect_by_func (object,
1115
 
                                            G_CALLBACK (clear_selected_object),
1116
 
                                            (gpointer) align_tool);
1117
 
 
1118
 
      align_tool->selected_objects = g_list_remove (align_tool->selected_objects,
1119
 
                                                    object);
1120
 
    }
1121
 
 
1122
 
  if (gimp_draw_tool_is_active (draw_tool))
1123
 
    gimp_draw_tool_resume (draw_tool);
1124
 
}
1125
 
 
1126
 
static GimpLayer *
1127
 
select_layer_by_coords (GimpImage *image,
1128
 
                        gint       x,
1129
 
                        gint       y)
1130
 
{
1131
 
  GList *list;
1132
 
 
1133
 
  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
1134
 
 
1135
 
  for (list = GIMP_LIST (image->layers)->list;
1136
 
       list;
1137
 
       list = g_list_next (list))
1138
 
    {
1139
 
      GimpLayer *layer = list->data;
1140
 
      gint       off_x, off_y;
1141
 
      gint       width, height;
1142
 
 
1143
 
      if (! gimp_item_get_visible (GIMP_ITEM (layer)))
1144
 
        continue;
1145
 
 
1146
 
      gimp_item_offsets (GIMP_ITEM (layer), &off_x, &off_y);
1147
 
      width = gimp_item_width (GIMP_ITEM (layer));
1148
 
      height = gimp_item_height (GIMP_ITEM (layer));
1149
 
 
1150
 
      if (off_x <= x &&
1151
 
          off_y <= y &&
1152
 
          x < off_x + width &&
1153
 
          y < off_y + height)
1154
 
        {
1155
 
          return layer;
1156
 
        }
1157
 
    }
1158
 
 
1159
 
  return NULL;
 
836
    gimp_align_tool_object_removed (align_tool->selected_objects->data,
 
837
                                    align_tool);
 
838
 
 
839
  gimp_draw_tool_resume (GIMP_DRAW_TOOL (align_tool));
1160
840
}