gimpcolorpickertool.c 15.8 KB
Newer Older
Elliot Lee's avatar
Elliot Lee committed
1
/* The GIMP -- an image manipulation program
2
 * Copyright (C) 1995-2001 Spencer Kimball, Peter Mattis, and others
Elliot Lee's avatar
Elliot Lee committed
3 4 5 6 7 8 9 10 11 12 13 14 15
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
16
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Elliot Lee's avatar
Elliot Lee committed
17
 */
Sven Neumann's avatar
Sven Neumann committed
18 19 20 21 22

#include "config.h"

#include <gtk/gtk.h>

23
#include "libgimpcolor/gimpcolor.h"
24
#include "libgimpconfig/gimpconfig.h"
25
#include "libgimpwidgets/gimpwidgets.h"
Sven Neumann's avatar
Sven Neumann committed
26

27 28
#include "tools-types.h"

29
#include "core/gimp.h"
30 31
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
32
#include "core/gimptoolinfo.h"
33

34
#include "widgets/gimpcolorframe.h"
35
#include "widgets/gimpcolormapeditor.h"
36
#include "widgets/gimpdialogfactory.h"
37
#include "widgets/gimpdockable.h"
38
#include "widgets/gimphelp-ids.h"
39
#include "widgets/gimppaletteeditor.h"
40
#include "widgets/gimpsessioninfo.h"
41
#include "widgets/gimptooldialog.h"
42
#include "widgets/gimpviewabledialog.h"
43

44 45
#include "display/gimpdisplay.h"

46
#include "gimpcolorpickeroptions.h"
47
#include "gimpcolorpickertool.h"
48
#include "gimptoolcontrol.h"
49

50
#include "gimp-intl.h"
51

52

53 54
/*  local function prototypes  */

55 56 57
static GObject * gimp_color_picker_tool_constructor  (GType            type,
                                                      guint            n_params,
                                                      GObjectConstructParam *params);
58 59 60 61 62 63 64 65 66 67 68 69 70
static void      gimp_color_picker_tool_finalize     (GObject         *object);

static void      gimp_color_picker_tool_control      (GimpTool        *tool,
                                                      GimpToolAction   action,
                                                      GimpDisplay     *gdisp);
static void      gimp_color_picker_tool_modifier_key (GimpTool        *tool,
                                                      GdkModifierType  key,
                                                      gboolean         press,
                                                      GdkModifierType  state,
                                                      GimpDisplay     *gdisp);
static void      gimp_color_picker_tool_oper_update  (GimpTool        *tool,
                                                      GimpCoords      *coords,
                                                      GdkModifierType  state,
71
                                                      gboolean         proximity,
72 73 74
                                                      GimpDisplay     *gdisp);

static void      gimp_color_picker_tool_picked       (GimpColorTool   *color_tool,
75
                                                      GimpColorPickState  pick_state,
76 77 78
                                                      GimpImageType    sample_type,
                                                      GimpRGB         *color,
                                                      gint             color_index);
Sven Neumann's avatar
Sven Neumann committed
79

80
static void   gimp_color_picker_tool_info_create (GimpColorPickerTool *picker_tool);
81 82
static void gimp_color_picker_tool_info_response (GtkWidget           *widget,
                                                  gint                 response_id,
83 84 85 86 87
                                                  GimpColorPickerTool *picker_tool);
static void   gimp_color_picker_tool_info_update (GimpColorPickerTool *picker_tool,
                                                  GimpImageType        sample_type,
                                                  GimpRGB             *color,
                                                  gint                 color_index);
Sven Neumann's avatar
Sven Neumann committed
88 89


90 91 92 93
G_DEFINE_TYPE (GimpColorPickerTool, gimp_color_picker_tool,
               GIMP_TYPE_COLOR_TOOL);

#define parent_class gimp_color_picker_tool_parent_class
94 95


96
void
Nate Summers's avatar
Nate Summers committed
97
gimp_color_picker_tool_register (GimpToolRegisterCallback  callback,
98
                                 gpointer                  data)
99
{
Nate Summers's avatar
Nate Summers committed
100
  (* callback) (GIMP_TYPE_COLOR_PICKER_TOOL,
101 102
                GIMP_TYPE_COLOR_PICKER_OPTIONS,
                gimp_color_picker_options_gui,
103
                0,
104
                "gimp-color-picker-tool",
105 106
                _("Color Picker"),
                _("Pick colors from the image"),
107
                N_("C_olor Picker"), "O",
108
                NULL, GIMP_HELP_TOOL_COLOR_PICKER,
Nate Summers's avatar
Nate Summers committed
109
                GIMP_STOCK_TOOL_COLOR_PICKER,
110
                data);
111 112 113
}

static void
114
gimp_color_picker_tool_class_init (GimpColorPickerToolClass *klass)
115
{
116 117 118
  GObjectClass       *object_class     = G_OBJECT_CLASS (klass);
  GimpToolClass      *tool_class       = GIMP_TOOL_CLASS (klass);
  GimpColorToolClass *color_tool_class = GIMP_COLOR_TOOL_CLASS (klass);
119

120 121
  object_class->constructor = gimp_color_picker_tool_constructor;
  object_class->finalize    = gimp_color_picker_tool_finalize;
122

123
  tool_class->control       = gimp_color_picker_tool_control;
124 125
  tool_class->modifier_key  = gimp_color_picker_tool_modifier_key;
  tool_class->oper_update   = gimp_color_picker_tool_oper_update;
126

127
  color_tool_class->picked  = gimp_color_picker_tool_picked;
128 129 130
}

static void
Sven Neumann's avatar
Sven Neumann committed
131
gimp_color_picker_tool_init (GimpColorPickerTool *tool)
132
{
133
  GimpColorTool *color_tool = GIMP_COLOR_TOOL (tool);
134

135
  color_tool->pick_mode = GIMP_COLOR_PICK_MODE_FOREGROUND;
136 137
}

138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
static GObject *
gimp_color_picker_tool_constructor (GType                  type,
                                    guint                  n_params,
                                    GObjectConstructParam *params)
{
  GObject  *object;
  GimpTool *tool;

  object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);

  tool = GIMP_TOOL (object);

  gimp_color_tool_enable (GIMP_COLOR_TOOL (object),
                          GIMP_COLOR_OPTIONS (tool->tool_info->tool_options));

  return object;
}

156
static void
157
gimp_color_picker_tool_finalize (GObject *object)
158
{
159 160 161
  GimpColorPickerTool *picker_tool = GIMP_COLOR_PICKER_TOOL (object);

  if (picker_tool->dialog)
162 163
    gimp_color_picker_tool_info_response (NULL, GTK_RESPONSE_CLOSE,
                                          picker_tool);
164

165
  G_OBJECT_CLASS (parent_class)->finalize (object);
166 167
}

Elliot Lee's avatar
Elliot Lee committed
168
static void
169
gimp_color_picker_tool_control (GimpTool       *tool,
170 171
                                GimpToolAction  action,
                                GimpDisplay    *gdisp)
Elliot Lee's avatar
Elliot Lee committed
172
{
173 174
  GimpColorPickerTool *picker_tool = GIMP_COLOR_PICKER_TOOL (tool);

175 176
  switch (action)
    {
177
    case HALT:
178
      if (picker_tool->dialog)
179 180
        gimp_color_picker_tool_info_response (NULL, GTK_RESPONSE_CLOSE,
                                              picker_tool);
181
      break;
182

183 184 185
    default:
      break;
    }
186

187
  GIMP_TOOL_CLASS (parent_class)->control (tool, action, gdisp);
Elliot Lee's avatar
Elliot Lee committed
188 189
}

190 191 192 193 194 195 196 197 198 199 200
static void
gimp_color_picker_tool_modifier_key (GimpTool        *tool,
                                     GdkModifierType  key,
                                     gboolean         press,
                                     GdkModifierType  state,
                                     GimpDisplay     *gdisp)
{
  GimpColorPickerOptions *options;

  options = GIMP_COLOR_PICKER_OPTIONS (tool->tool_info->tool_options);

201 202
  if (key == GDK_SHIFT_MASK)
    {
203
      g_object_set (options, "use-info-window", ! options->use_info_window,
204 205 206
                    NULL);
    }
  else if (key == GDK_CONTROL_MASK)
207 208 209 210 211 212 213 214 215 216 217 218
    {
       switch (options->pick_mode)
        {
        case GIMP_COLOR_PICK_MODE_FOREGROUND:
          g_object_set (options, "pick-mode", GIMP_COLOR_PICK_MODE_BACKGROUND,
                        NULL);
          break;

        case GIMP_COLOR_PICK_MODE_BACKGROUND:
          g_object_set (options, "pick-mode", GIMP_COLOR_PICK_MODE_FOREGROUND,
                        NULL);
          break;
219 220 221

        default:
          break;
222 223 224 225 226 227 228 229 230
        }

    }
}

static void
gimp_color_picker_tool_oper_update (GimpTool        *tool,
                                    GimpCoords      *coords,
                                    GdkModifierType  state,
231
                                    gboolean         proximity,
232 233 234 235 236 237 238
                                    GimpDisplay     *gdisp)
{
  GimpColorPickerOptions *options;

  options = GIMP_COLOR_PICKER_OPTIONS (tool->tool_info->tool_options);

  GIMP_COLOR_TOOL (tool)->pick_mode = options->pick_mode;
239

240 241
  GIMP_TOOL_CLASS (parent_class)->oper_update (tool, coords, state, proximity,
                                               gdisp);
242 243
}

Elliot Lee's avatar
Elliot Lee committed
244
static void
245 246 247 248 249
gimp_color_picker_tool_picked (GimpColorTool      *color_tool,
                               GimpColorPickState  pick_state,
                               GimpImageType       sample_type,
                               GimpRGB            *color,
                               gint                color_index)
Elliot Lee's avatar
Elliot Lee committed
250
{
251 252
  GimpTool               *tool        = GIMP_TOOL (color_tool);
  GimpColorPickerTool    *picker_tool = GIMP_COLOR_PICKER_TOOL (color_tool);
Sven Neumann's avatar
Sven Neumann committed
253
  GimpColorPickerOptions *options;
254
  GimpContext            *user_context;
Elliot Lee's avatar
Elliot Lee committed
255

256
  options = GIMP_COLOR_PICKER_OPTIONS (color_tool->options);
Elliot Lee's avatar
Elliot Lee committed
257

258
  if (options->use_info_window && ! picker_tool->dialog)
259
    gimp_color_picker_tool_info_create (picker_tool);
Elliot Lee's avatar
Elliot Lee committed
260

261 262 263
  if (picker_tool->dialog)
    gimp_color_picker_tool_info_update (picker_tool, sample_type,
                                        color, color_index);
264

265
  user_context = gimp_get_user_context (tool->gdisp->gimage->gimp);
266

267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
  if ((options->pick_mode == GIMP_COLOR_PICK_MODE_FOREGROUND ||
       options->pick_mode == GIMP_COLOR_PICK_MODE_BACKGROUND) &&
      GIMP_IMAGE_TYPE_IS_INDEXED (sample_type))
    {
      GimpDialogFactory *dialog_factory;
      GimpSessionInfo   *info;

      dialog_factory = gimp_dialog_factory_from_name ("dock");
      info = gimp_dialog_factory_find_session_info (dialog_factory,
                                                    "gimp-indexed-palette");

      if (info && info->widget)
        {
          GtkWidget *colormap_editor;

          colormap_editor = gtk_bin_get_child (GTK_BIN (info->widget));

          gtk_adjustment_set_value
            (GIMP_COLORMAP_EDITOR (colormap_editor)->index_adjustment,
             color_index);
        }
    }

290
  switch (options->pick_mode)
291
    {
292 293
    case GIMP_COLOR_PICK_MODE_NONE:
      break;
294

295 296 297
    case GIMP_COLOR_PICK_MODE_FOREGROUND:
      gimp_context_set_foreground (user_context, color);
      break;
298

299 300 301
    case GIMP_COLOR_PICK_MODE_BACKGROUND:
      gimp_context_set_background (user_context, color);
      break;
302

303 304 305 306 307
    case GIMP_COLOR_PICK_MODE_PALETTE:
      {
        GimpDialogFactory *dialog_factory;
        GdkScreen         *screen;
        GtkWidget         *dockable;
308

309
        dialog_factory = gimp_dialog_factory_from_name ("dock");
310 311
        screen = gtk_widget_get_screen (tool->gdisp->shell);
        dockable = gimp_dialog_factory_dialog_raise (dialog_factory, screen,
312 313
                                                     "gimp-palette-editor",
                                                     -1);
314

315 316 317 318
        if (dockable)
          {
            GtkWidget *palette_editor;
            GimpData  *data;
319

320 321 322
            /* don't blink like mad when updating */
            if (pick_state == GIMP_COLOR_PICK_STATE_UPDATE)
              gimp_dockable_blink_cancel (GIMP_DOCKABLE (dockable));
323

324
            palette_editor = gtk_bin_get_child (GTK_BIN (dockable));
325

326
            data = gimp_data_editor_get_data (GIMP_DATA_EDITOR (palette_editor));
327

328 329 330 331 332 333 334
            if (! data)
              {
                data = GIMP_DATA (gimp_context_get_palette (user_context));

                gimp_data_editor_set_data (GIMP_DATA_EDITOR (palette_editor),
                                           data);
              }
335

336 337 338
            gimp_palette_editor_pick_color (GIMP_PALETTE_EDITOR (palette_editor),
                                            color, pick_state);
          }
339
      }
340
      break;
341 342 343
    }
}

344 345
static void
gimp_color_picker_tool_info_create (GimpColorPickerTool *picker_tool)
Michael Natterer's avatar
Michael Natterer committed
346
{
347 348 349 350
  GimpTool  *tool = GIMP_TOOL (picker_tool);
  GtkWidget *hbox;
  GtkWidget *frame;
  GimpRGB    color;
Michael Natterer's avatar
Michael Natterer committed
351

352
  g_return_if_fail (tool->drawable != NULL);
Michael Natterer's avatar
Michael Natterer committed
353

354
  picker_tool->dialog = gimp_tool_dialog_new (tool->tool_info,
355
                                              NULL /* tool->gdisp->shell */,
356
                                              _("Color Picker Information"),
Michael Natterer's avatar
Michael Natterer committed
357

358
                                              GTK_STOCK_CLOSE,
359
                                              GTK_RESPONSE_CLOSE,
Michael Natterer's avatar
Michael Natterer committed
360

361 362
                                              NULL);

363 364
  gtk_window_set_focus_on_map (GTK_WINDOW (picker_tool->dialog), FALSE);

365 366
  gimp_viewable_dialog_set_viewable (GIMP_VIEWABLE_DIALOG (picker_tool->dialog),
                                     GIMP_VIEWABLE (tool->drawable));
Sven Neumann's avatar
Sven Neumann committed
367

368 369 370 371
  g_signal_connect (picker_tool->dialog, "response",
                    G_CALLBACK (gimp_color_picker_tool_info_response),
                    picker_tool);

372
  hbox = gtk_hbox_new (FALSE, 6);
373
  gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
374 375
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (picker_tool->dialog)->vbox), hbox,
                      FALSE, FALSE, 0);
Michael Natterer's avatar
Michael Natterer committed
376 377
  gtk_widget_show (hbox);

378 379 380 381 382 383 384 385 386 387 388 389 390
  picker_tool->color_frame1 = gimp_color_frame_new ();
  gimp_color_frame_set_mode (GIMP_COLOR_FRAME (picker_tool->color_frame1),
                             GIMP_COLOR_FRAME_MODE_PIXEL);
  gtk_box_pack_start (GTK_BOX (hbox), picker_tool->color_frame1,
                      FALSE, FALSE, 0);
  gtk_widget_show (picker_tool->color_frame1);

  picker_tool->color_frame2 = gimp_color_frame_new ();
  gimp_color_frame_set_mode (GIMP_COLOR_FRAME (picker_tool->color_frame2),
                             GIMP_COLOR_FRAME_MODE_RGB);
  gtk_box_pack_start (GTK_BOX (hbox), picker_tool->color_frame2,
                      FALSE, FALSE, 0);
  gtk_widget_show (picker_tool->color_frame2);
Michael Natterer's avatar
Michael Natterer committed
391 392 393

  frame = gtk_frame_new (NULL);
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
394
  gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
395
  gtk_widget_show (frame);
Michael Natterer's avatar
Michael Natterer committed
396 397

  gimp_rgba_set (&color, 0.0, 0.0, 0.0, 0.0);
398 399 400 401 402 403 404 405 406 407
  picker_tool->color_area =
    gimp_color_area_new (&color,
                         gimp_drawable_has_alpha (tool->drawable) ?
                         GIMP_COLOR_AREA_LARGE_CHECKS :
                         GIMP_COLOR_AREA_FLAT,
                         GDK_BUTTON1_MASK | GDK_BUTTON2_MASK);
  gtk_widget_set_size_request (picker_tool->color_area, 48, -1);
  gtk_drag_dest_unset (picker_tool->color_area);
  gtk_container_add (GTK_CONTAINER (frame), picker_tool->color_area);
  gtk_widget_show (picker_tool->color_area);
Michael Natterer's avatar
Michael Natterer committed
408 409 410
}

static void
411 412 413
gimp_color_picker_tool_info_response (GtkWidget           *widget,
                                      gint                 response_id,
                                      GimpColorPickerTool *picker_tool)
Michael Natterer's avatar
Michael Natterer committed
414
{
415
  gtk_widget_destroy (picker_tool->dialog);
416

417 418 419 420
  picker_tool->dialog       = NULL;
  picker_tool->color_area   = NULL;
  picker_tool->color_frame1 = NULL;
  picker_tool->color_frame2 = NULL;
Michael Natterer's avatar
Michael Natterer committed
421 422
}

Elliot Lee's avatar
Elliot Lee committed
423
static void
424 425 426 427
gimp_color_picker_tool_info_update (GimpColorPickerTool *picker_tool,
                                    GimpImageType        sample_type,
                                    GimpRGB             *color,
                                    gint                 color_index)
Elliot Lee's avatar
Elliot Lee committed
428
{
429 430
  gimp_color_area_set_color (GIMP_COLOR_AREA (picker_tool->color_area),
                             color);
431

432 433 434 435
  gimp_color_frame_set_color (GIMP_COLOR_FRAME (picker_tool->color_frame1),
                              sample_type, color, color_index);
  gimp_color_frame_set_color (GIMP_COLOR_FRAME (picker_tool->color_frame2),
                              sample_type, color, color_index);
Sven Neumann's avatar
Sven Neumann committed
436

437 438 439 440
  if (GTK_WIDGET_VISIBLE (picker_tool->dialog))
    gdk_window_show (picker_tool->dialog->window);
  else
    gtk_widget_show (picker_tool->dialog);
Elliot Lee's avatar
Elliot Lee committed
441
}