~ubuntu-branches/ubuntu/maverick/gimp/maverick-updates

« back to all changes in this revision

Viewing changes to app/widgets/gimpselectioneditor.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2005-12-09 19:44:52 UTC
  • Revision ID: james.westby@ubuntu.com-20051209194452-yggpemjlofpjqyf4
Tags: upstream-2.2.9
ImportĀ upstreamĀ versionĀ 2.2.9

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
 * This program is free software; you can redistribute it and/or modify
 
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
 
7
 * (at your option) any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
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.
 
17
 */
 
18
 
 
19
#include "config.h"
 
20
 
 
21
#include <gtk/gtk.h>
 
22
 
 
23
#include "libgimpcolor/gimpcolor.h"
 
24
#include "libgimpmath/gimpmath.h"
 
25
#include "libgimpwidgets/gimpwidgets.h"
 
26
 
 
27
#include "widgets-types.h"
 
28
 
 
29
#include "config/gimpcoreconfig.h"
 
30
 
 
31
#include "core/gimp.h"
 
32
#include "core/gimpchannel-select.h"
 
33
#include "core/gimpcontainer.h"
 
34
#include "core/gimpimage.h"
 
35
#include "core/gimpimage-pick-color.h"
 
36
#include "core/gimpselection.h"
 
37
#include "core/gimptoolinfo.h"
 
38
 
 
39
#ifdef __GNUC__
 
40
#warning #include "tools/tools-types.h"
 
41
#endif
 
42
#include "tools/tools-types.h"
 
43
#include "tools/gimpselectionoptions.h"
 
44
 
 
45
#include "gimpselectioneditor.h"
 
46
#include "gimpdnd.h"
 
47
#include "gimpmenufactory.h"
 
48
#include "gimpview.h"
 
49
#include "gimpviewrenderer.h"
 
50
#include "gimpwidgets-utils.h"
 
51
 
 
52
#include "gimp-intl.h"
 
53
 
 
54
 
 
55
static void   gimp_selection_editor_class_init (GimpSelectionEditorClass *klass);
 
56
static void   gimp_selection_editor_init       (GimpSelectionEditor      *selection_editor);
 
57
 
 
58
static GObject * gimp_selection_editor_constructor (GType                type,
 
59
                                                    guint                n_params,
 
60
                                                    GObjectConstructParam *params);
 
61
 
 
62
static void   gimp_selection_editor_set_image      (GimpImageEditor     *editor,
 
63
                                                    GimpImage           *gimage);
 
64
 
 
65
static gboolean gimp_selection_preview_button_press(GtkWidget           *widget,
 
66
                                                    GdkEventButton      *bevent,
 
67
                                                    GimpSelectionEditor *editor);
 
68
static void   gimp_selection_editor_drop_color     (GtkWidget           *widget,
 
69
                                                    const GimpRGB       *color,
 
70
                                                    gpointer             data);
 
71
 
 
72
static void   gimp_selection_editor_mask_changed   (GimpImage           *gimage,
 
73
                                                    GimpSelectionEditor *editor);
 
74
 
 
75
 
 
76
static GimpImageEditorClass *parent_class = NULL;
 
77
 
 
78
 
 
79
GType
 
80
gimp_selection_editor_get_type (void)
 
81
{
 
82
  static GType editor_type = 0;
 
83
 
 
84
  if (! editor_type)
 
85
    {
 
86
      static const GTypeInfo editor_info =
 
87
      {
 
88
        sizeof (GimpSelectionEditorClass),
 
89
        (GBaseInitFunc) NULL,
 
90
        (GBaseFinalizeFunc) NULL,
 
91
        (GClassInitFunc) gimp_selection_editor_class_init,
 
92
        NULL,           /* class_finalize */
 
93
        NULL,           /* class_data     */
 
94
        sizeof (GimpSelectionEditor),
 
95
        0,              /* n_preallocs    */
 
96
        (GInstanceInitFunc) gimp_selection_editor_init,
 
97
      };
 
98
 
 
99
      editor_type = g_type_register_static (GIMP_TYPE_IMAGE_EDITOR,
 
100
                                            "GimpSelectionEditor",
 
101
                                            &editor_info, 0);
 
102
    }
 
103
 
 
104
  return editor_type;
 
105
}
 
106
 
 
107
static void
 
108
gimp_selection_editor_class_init (GimpSelectionEditorClass* klass)
 
109
{
 
110
  GObjectClass         *object_class       = G_OBJECT_CLASS (klass);
 
111
  GimpImageEditorClass *image_editor_class = GIMP_IMAGE_EDITOR_CLASS (klass);
 
112
 
 
113
  parent_class = g_type_class_peek_parent (klass);
 
114
 
 
115
  object_class->constructor     = gimp_selection_editor_constructor;
 
116
 
 
117
  image_editor_class->set_image = gimp_selection_editor_set_image;
 
118
}
 
119
 
 
120
static void
 
121
gimp_selection_editor_init (GimpSelectionEditor *editor)
 
122
{
 
123
  GtkWidget *frame;
 
124
 
 
125
  frame = gtk_frame_new (NULL);
 
126
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
 
127
  gtk_box_pack_start (GTK_BOX (editor), frame, TRUE, TRUE, 0);
 
128
  gtk_widget_show (frame);
 
129
 
 
130
  editor->preview = gimp_view_new_by_types (GIMP_TYPE_VIEW,
 
131
                                            GIMP_TYPE_SELECTION,
 
132
                                            GIMP_VIEW_SIZE_HUGE,
 
133
                                            0, TRUE);
 
134
  gimp_view_renderer_set_background (GIMP_VIEW (editor->preview)->renderer,
 
135
                                     GIMP_STOCK_TEXTURE);
 
136
  gtk_widget_set_size_request (editor->preview,
 
137
                               GIMP_VIEW_SIZE_HUGE, GIMP_VIEW_SIZE_HUGE);
 
138
  gimp_view_set_expand (GIMP_VIEW (editor->preview), TRUE);
 
139
  gtk_container_add (GTK_CONTAINER (frame), editor->preview);
 
140
  gtk_widget_show (editor->preview);
 
141
 
 
142
  g_signal_connect (editor->preview, "button_press_event",
 
143
                    G_CALLBACK (gimp_selection_preview_button_press),
 
144
                    editor);
 
145
 
 
146
  gimp_dnd_color_dest_add (editor->preview,
 
147
                           gimp_selection_editor_drop_color,
 
148
                           editor);
 
149
 
 
150
  gtk_widget_set_sensitive (GTK_WIDGET (editor), FALSE);
 
151
}
 
152
 
 
153
static GObject *
 
154
gimp_selection_editor_constructor (GType                  type,
 
155
                                   guint                  n_params,
 
156
                                   GObjectConstructParam *params)
 
157
{
 
158
  GObject             *object;
 
159
  GimpSelectionEditor *editor;
 
160
 
 
161
  object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
 
162
 
 
163
  editor = GIMP_SELECTION_EDITOR (object);
 
164
 
 
165
  editor->all_button =
 
166
    gimp_editor_add_action_button (GIMP_EDITOR (editor), "select",
 
167
                                   "select-all", NULL);
 
168
 
 
169
  editor->none_button =
 
170
    gimp_editor_add_action_button (GIMP_EDITOR (editor), "select",
 
171
                                   "select-none", NULL);
 
172
 
 
173
  editor->invert_button =
 
174
    gimp_editor_add_action_button (GIMP_EDITOR (editor), "select",
 
175
                                   "select-invert", NULL);
 
176
 
 
177
  editor->save_button =
 
178
    gimp_editor_add_action_button (GIMP_EDITOR (editor), "select",
 
179
                                   "select-save", NULL);
 
180
 
 
181
  editor->path_button =
 
182
    gimp_editor_add_action_button (GIMP_EDITOR (editor), "vectors",
 
183
                                   "vectors-selection-to-vectors",
 
184
                                   "vectors-selection-to-vectors-advanced",
 
185
                                   GDK_SHIFT_MASK,
 
186
                                   NULL);
 
187
 
 
188
  editor->stroke_button =
 
189
    gimp_editor_add_action_button (GIMP_EDITOR (editor), "select",
 
190
                                   "select-stroke",
 
191
                                   "select-stroke-last-values",
 
192
                                   GDK_SHIFT_MASK,
 
193
                                   NULL);
 
194
 
 
195
  return object;
 
196
}
 
197
 
 
198
static void
 
199
gimp_selection_editor_set_image (GimpImageEditor *image_editor,
 
200
                                 GimpImage       *gimage)
 
201
{
 
202
  GimpSelectionEditor *editor = GIMP_SELECTION_EDITOR (image_editor);
 
203
 
 
204
  if (image_editor->gimage)
 
205
    {
 
206
      g_signal_handlers_disconnect_by_func (image_editor->gimage,
 
207
                                            gimp_selection_editor_mask_changed,
 
208
                                            editor);
 
209
    }
 
210
 
 
211
  GIMP_IMAGE_EDITOR_CLASS (parent_class)->set_image (image_editor, gimage);
 
212
 
 
213
  if (gimage)
 
214
    {
 
215
      g_signal_connect (gimage, "mask_changed",
 
216
                        G_CALLBACK (gimp_selection_editor_mask_changed),
 
217
                        editor);
 
218
 
 
219
      gimp_view_set_viewable (GIMP_VIEW (editor->preview),
 
220
                              GIMP_VIEWABLE (gimp_image_get_mask (gimage)));
 
221
    }
 
222
  else
 
223
    {
 
224
      gimp_view_set_viewable (GIMP_VIEW (editor->preview), NULL);
 
225
    }
 
226
}
 
227
 
 
228
 
 
229
/*  public functions  */
 
230
 
 
231
GtkWidget *
 
232
gimp_selection_editor_new (GimpMenuFactory *menu_factory)
 
233
{
 
234
  g_return_val_if_fail (GIMP_IS_MENU_FACTORY (menu_factory), NULL);
 
235
 
 
236
  return g_object_new (GIMP_TYPE_SELECTION_EDITOR,
 
237
                       "menu-factory",    menu_factory,
 
238
                       "menu-identifier", "<SelectionEditor>",
 
239
                       "ui-path",         "/selection-editor-popup",
 
240
                       NULL);
 
241
}
 
242
 
 
243
static gboolean
 
244
gimp_selection_preview_button_press (GtkWidget           *widget,
 
245
                                     GdkEventButton      *bevent,
 
246
                                     GimpSelectionEditor *editor)
 
247
{
 
248
  GimpImageEditor      *image_editor = GIMP_IMAGE_EDITOR (editor);
 
249
  GimpViewRenderer     *renderer;
 
250
  GimpToolInfo         *tool_info;
 
251
  GimpSelectionOptions *options;
 
252
  GimpDrawable         *drawable;
 
253
  SelectOps             operation = SELECTION_REPLACE;
 
254
  gint                  x, y;
 
255
  GimpRGB               color;
 
256
 
 
257
  if (! image_editor->gimage)
 
258
    return TRUE;
 
259
 
 
260
  renderer = GIMP_VIEW (editor->preview)->renderer;
 
261
 
 
262
  tool_info = (GimpToolInfo *)
 
263
    gimp_container_get_child_by_name (image_editor->gimage->gimp->tool_info_list,
 
264
                                      "gimp-by-color-select-tool");
 
265
 
 
266
  if (! tool_info)
 
267
    return TRUE;
 
268
 
 
269
  options = GIMP_SELECTION_OPTIONS (tool_info->tool_options);
 
270
 
 
271
  drawable = gimp_image_active_drawable (image_editor->gimage);
 
272
 
 
273
  if (! drawable)
 
274
    return TRUE;
 
275
 
 
276
  if (bevent->state & GDK_SHIFT_MASK)
 
277
    {
 
278
      if (bevent->state & GDK_CONTROL_MASK)
 
279
        {
 
280
          operation = SELECTION_INTERSECT;
 
281
        }
 
282
      else
 
283
        {
 
284
          operation = SELECTION_ADD;
 
285
        }
 
286
    }
 
287
  else if (bevent->state & GDK_CONTROL_MASK)
 
288
    {
 
289
      operation = SELECTION_SUBTRACT;
 
290
    }
 
291
 
 
292
  x = image_editor->gimage->width  * bevent->x / renderer->width;
 
293
  y = image_editor->gimage->height * bevent->y / renderer->height;
 
294
 
 
295
  if (gimp_image_pick_color (image_editor->gimage, drawable, x, y,
 
296
                             options->sample_merged,
 
297
                             FALSE, 0.0,
 
298
                             NULL,
 
299
                             &color, NULL))
 
300
    {
 
301
      gimp_channel_select_by_color (gimp_image_get_mask (image_editor->gimage),
 
302
                                    drawable,
 
303
                                    options->sample_merged,
 
304
                                    &color,
 
305
                                    options->threshold,
 
306
                                    options->select_transparent,
 
307
                                    operation,
 
308
                                    options->antialias,
 
309
                                    options->feather,
 
310
                                    options->feather_radius,
 
311
                                    options->feather_radius);
 
312
      gimp_image_flush (image_editor->gimage);
 
313
    }
 
314
 
 
315
  return TRUE;
 
316
}
 
317
 
 
318
static void
 
319
gimp_selection_editor_drop_color (GtkWidget     *widget,
 
320
                                  const GimpRGB *color,
 
321
                                  gpointer       data)
 
322
{
 
323
  GimpImageEditor      *editor = GIMP_IMAGE_EDITOR (data);
 
324
  GimpToolInfo         *tool_info;
 
325
  GimpSelectionOptions *options;
 
326
  GimpDrawable         *drawable;
 
327
 
 
328
  if (! editor->gimage)
 
329
    return;
 
330
 
 
331
  tool_info = (GimpToolInfo *)
 
332
    gimp_container_get_child_by_name (editor->gimage->gimp->tool_info_list,
 
333
                                      "gimp-by-color-select-tool");
 
334
 
 
335
  if (! tool_info)
 
336
    return;
 
337
 
 
338
  options = GIMP_SELECTION_OPTIONS (tool_info->tool_options);
 
339
 
 
340
  drawable = gimp_image_active_drawable (editor->gimage);
 
341
 
 
342
  if (! drawable)
 
343
    return;
 
344
 
 
345
  gimp_channel_select_by_color (gimp_image_get_mask (editor->gimage),
 
346
                                drawable,
 
347
                                options->sample_merged,
 
348
                                color,
 
349
                                options->threshold,
 
350
                                options->select_transparent,
 
351
                                options->operation,
 
352
                                options->antialias,
 
353
                                options->feather,
 
354
                                options->feather_radius,
 
355
                                options->feather_radius);
 
356
  gimp_image_flush (editor->gimage);
 
357
}
 
358
 
 
359
static void
 
360
gimp_selection_editor_mask_changed (GimpImage           *gimage,
 
361
                                    GimpSelectionEditor *editor)
 
362
{
 
363
  gimp_view_renderer_invalidate (GIMP_VIEW (editor->preview)->renderer);
 
364
}