gimpcolortool.c 11.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
/* The GIMP -- an image manipulation program
 * Copyright (C) 1995-2001 Spencer Kimball, Peter Mattis, and others
 *
 * 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
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include "config.h"

#include <gtk/gtk.h>

#include "libgimpwidgets/gimpwidgets.h"

#include "tools-types.h"

Sven Neumann's avatar
Sven Neumann committed
27 28
#include "config/gimpconfig-types.h"

29
#include "core/gimpimage.h"
Sven Neumann's avatar
Sven Neumann committed
30
#include "core/gimpimage-pick-color.h"
31
#include "core/gimpitem.h"
Sven Neumann's avatar
Sven Neumann committed
32
#include "core/gimpmarshal.h"
33 34 35 36 37 38 39 40 41 42 43
#include "core/gimptoolinfo.h"

#include "display/gimpdisplay.h"

#include "gimpcoloroptions.h"
#include "gimpcolortool.h"
#include "gimptoolcontrol.h"

#include "gimp-intl.h"


Sven Neumann's avatar
Sven Neumann committed
44 45 46 47 48 49 50
enum
{
  PICKED,
  LAST_SIGNAL
};


51 52 53 54
/*  local function prototypes  */

static void 	  gimp_color_tool_class_init  (GimpColorToolClass *klass);
static void       gimp_color_tool_init        (GimpColorTool      *color_tool);
Sven Neumann's avatar
Sven Neumann committed
55
static void       gimp_color_tool_finalize    (GObject            *object);
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78

static void       gimp_color_tool_button_press   (GimpTool        *tool,
						  GimpCoords      *coords,
						  guint32          time,
						  GdkModifierType  state,
						  GimpDisplay     *gdisp);
static void       gimp_color_tool_button_release (GimpTool        *tool,
						  GimpCoords      *coords,
						  guint32          time,
						  GdkModifierType  state,
						  GimpDisplay     *gdisp);
static void       gimp_color_tool_motion         (GimpTool        *tool,
						  GimpCoords      *coords,
						  guint32          time,
						  GdkModifierType  state,
						  GimpDisplay     *gdisp);
static void       gimp_color_tool_cursor_update  (GimpTool        *tool,
						  GimpCoords      *coords,
						  GdkModifierType  state,
						  GimpDisplay     *gdisp);

static void       gimp_color_tool_draw           (GimpDrawTool    *draw_tool);

Sven Neumann's avatar
Sven Neumann committed
79 80 81 82 83 84 85 86 87 88
static gboolean   gimp_color_tool_real_pick      (GimpColorTool   *color_tool,
                                                  gint             x,
                                                  gint             y,
                                                  GimpImageType   *sample_type,
                                                  GimpRGB         *color,
                                                  gint            *color_index);
static void       gimp_color_tool_pick           (GimpColorTool   *tool,
                                                  gint             x,
                                                  gint             y);

89

Sven Neumann's avatar
Sven Neumann committed
90
static guint gimp_color_tool_signals[LAST_SIGNAL] = { 0 };
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125

static GimpDrawToolClass *parent_class = NULL;


GtkType
gimp_color_tool_get_type (void)
{
  static GtkType tool_type = 0;

  if (! tool_type)
    {
      static const GTypeInfo tool_info =
      {
        sizeof (GimpColorToolClass),
	(GBaseInitFunc) NULL,
	(GBaseFinalizeFunc) NULL,
	(GClassInitFunc) gimp_color_tool_class_init,
	NULL,           /* class_finalize */
	NULL,           /* class_data     */
	sizeof (GimpColorTool),
	0,              /* n_preallocs    */
	(GInstanceInitFunc) gimp_color_tool_init,
      };

      tool_type = g_type_register_static (GIMP_TYPE_DRAW_TOOL,
					  "GimpColorTool", 
                                          &tool_info, 0);
    }

  return tool_type;
}

static void
gimp_color_tool_class_init (GimpColorToolClass *klass)
{
Sven Neumann's avatar
Sven Neumann committed
126
  GObjectClass      *object_class;
127 128 129
  GimpToolClass     *tool_class;
  GimpDrawToolClass *draw_class;

Sven Neumann's avatar
Sven Neumann committed
130 131 132
  object_class = G_OBJECT_CLASS (klass);
  tool_class   = GIMP_TOOL_CLASS (klass);
  draw_class   = GIMP_DRAW_TOOL_CLASS (klass);
133 134 135

  parent_class = g_type_class_peek_parent (klass);

Sven Neumann's avatar
Sven Neumann committed
136 137 138 139 140 141 142 143 144 145 146 147
  gimp_color_tool_signals[PICKED] =
    g_signal_new ("picked",
		  G_TYPE_FROM_CLASS (klass),
		  G_SIGNAL_RUN_FIRST,
		  G_STRUCT_OFFSET (GimpColorToolClass, picked),
		  NULL, NULL,
		  gimp_marshal_VOID__ENUM_BOXED_INT,
		  G_TYPE_NONE, 3,
                  GIMP_TYPE_IMAGE_TYPE,
                  GIMP_TYPE_COLOR | G_SIGNAL_TYPE_STATIC_SCOPE,
                  G_TYPE_INT);

Sven Neumann's avatar
Sven Neumann committed
148 149
  object_class->finalize     = gimp_color_tool_finalize;

150 151 152 153 154 155 156
  tool_class->button_press   = gimp_color_tool_button_press;
  tool_class->button_release = gimp_color_tool_button_release;
  tool_class->motion         = gimp_color_tool_motion;
  tool_class->cursor_update  = gimp_color_tool_cursor_update;

  draw_class->draw	     = gimp_color_tool_draw;

Sven Neumann's avatar
Sven Neumann committed
157 158
  klass->pick                = gimp_color_tool_real_pick;
  klass->picked              = NULL;
159 160 161
}

static void
Sven Neumann's avatar
Sven Neumann committed
162
gimp_color_tool_finalize (GObject *object)
163
{
Sven Neumann's avatar
Sven Neumann committed
164 165 166 167 168 169 170 171 172 173
  GimpColorTool *color_tool = GIMP_COLOR_TOOL (object);

  if (color_tool->options)
    {
      g_object_unref (color_tool->options);
      color_tool->options = NULL;
    }

  G_OBJECT_CLASS (parent_class)->finalize (object);
}
174

Sven Neumann's avatar
Sven Neumann committed
175 176 177
static void
gimp_color_tool_init (GimpColorTool *color_tool)
{
Sven Neumann's avatar
Sven Neumann committed
178 179 180
  color_tool->enabled  = FALSE;
  color_tool->center_x = 0;
  color_tool->center_y = 0;
Sven Neumann's avatar
Sven Neumann committed
181
  color_tool->options  = NULL;
182 183 184 185 186 187 188 189 190
}

static void
gimp_color_tool_button_press (GimpTool        *tool,
			      GimpCoords      *coords,
			      guint32          time,
			      GdkModifierType  state,
			      GimpDisplay     *gdisp)
{
Sven Neumann's avatar
Sven Neumann committed
191
  GimpColorTool *color_tool;
192 193 194 195 196 197

  /*  Make the tool active and set it's gdisplay & drawable  */
  tool->gdisp    = gdisp;
  tool->drawable = gimp_image_active_drawable (gdisp->gimage);
  gimp_tool_control_activate (tool->control);

Sven Neumann's avatar
Sven Neumann committed
198 199 200
  color_tool = GIMP_COLOR_TOOL (tool);

  if (color_tool->enabled)
201
    {
Sven Neumann's avatar
Sven Neumann committed
202 203
      gint off_x, off_y;

204 205 206
      /*  Keep the coordinates of the target  */
      gimp_item_offsets (GIMP_ITEM (tool->drawable), &off_x, &off_y);

Sven Neumann's avatar
Sven Neumann committed
207 208
      color_tool->center_x = coords->x - off_x;
      color_tool->center_y = coords->y - off_y;
209 210

      gimp_draw_tool_start (GIMP_DRAW_TOOL (tool), gdisp);
Sven Neumann's avatar
Sven Neumann committed
211 212

      gimp_color_tool_pick (color_tool, coords->x, coords->y);
213 214 215 216 217 218 219 220 221 222
    }
}

static void
gimp_color_tool_button_release (GimpTool        *tool,
				GimpCoords      *coords,
				guint32          time,
				GdkModifierType  state,
				GimpDisplay     *gdisp)
{
Sven Neumann's avatar
Sven Neumann committed
223
  if (GIMP_COLOR_TOOL (tool)->enabled)
224 225 226 227 228 229 230
    gimp_draw_tool_stop (GIMP_DRAW_TOOL (tool));

  gimp_tool_control_halt (tool->control);
}

static void
gimp_color_tool_motion (GimpTool        *tool,
Sven Neumann's avatar
Sven Neumann committed
231 232 233 234
                        GimpCoords      *coords,
                        guint32          time,
                        GdkModifierType  state,
                        GimpDisplay     *gdisp)
235
{
Sven Neumann's avatar
Sven Neumann committed
236 237
  GimpColorTool *color_tool;
  gint           off_x, off_y;
238

Sven Neumann's avatar
Sven Neumann committed
239
  color_tool = GIMP_COLOR_TOOL (tool);
240

Sven Neumann's avatar
Sven Neumann committed
241 242
  if (! color_tool->enabled)
    return;
243 244 245 246 247

  gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));

  gimp_item_offsets (GIMP_ITEM (tool->drawable), &off_x, &off_y);

Sven Neumann's avatar
Sven Neumann committed
248 249
  color_tool->center_x = coords->x - off_x;
  color_tool->center_y = coords->y - off_y;
250 251

  gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
Sven Neumann's avatar
Sven Neumann committed
252 253

  gimp_color_tool_pick (color_tool, coords->x, coords->y);
254 255 256 257 258 259 260 261
}

static void
gimp_color_tool_cursor_update (GimpTool        *tool,
			       GimpCoords      *coords,
			       GdkModifierType  state,
			       GimpDisplay     *gdisp)
{
262 263 264
  GimpColorTool *color_tool = GIMP_COLOR_TOOL (tool);

  if (color_tool->enabled)
265
    {
266 267
      GdkCursorType cursor = GIMP_BAD_CURSOR;

Sven Neumann's avatar
Sven Neumann committed
268
      if (gdisp->gimage &&
269

Sven Neumann's avatar
Sven Neumann committed
270 271 272
          coords->x > 0 &&
          coords->x < gdisp->gimage->width &&
          coords->y > 0 &&
273 274 275 276
          coords->y < gdisp->gimage->height &&

          (color_tool->options->sample_merged ||
           gimp_display_coords_in_active_drawable (gdisp, coords)))
Sven Neumann's avatar
Sven Neumann committed
277
        {
278
          cursor = GIMP_COLOR_PICKER_CURSOR;
Sven Neumann's avatar
Sven Neumann committed
279
        }
Sven Neumann's avatar
Sven Neumann committed
280

281 282 283 284 285
      gimp_tool_set_cursor (tool, gdisp,
                            cursor,
                            GIMP_COLOR_PICKER_TOOL_CURSOR,
                            GIMP_CURSOR_MODIFIER_NONE);

Sven Neumann's avatar
Sven Neumann committed
286
      return;  /*  don't chain up  */
287 288 289 290 291 292 293 294
    }

  GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, gdisp);
}

static void
gimp_color_tool_draw (GimpDrawTool *draw_tool)
{
Sven Neumann's avatar
Sven Neumann committed
295
  GimpColorTool *color_tool;
296

Sven Neumann's avatar
Sven Neumann committed
297
  if (! GIMP_COLOR_TOOL (draw_tool)->enabled)
298 299
    return;

Sven Neumann's avatar
Sven Neumann committed
300
  color_tool = GIMP_COLOR_TOOL (draw_tool);
301

Sven Neumann's avatar
Sven Neumann committed
302
  if (color_tool->options->sample_average)
Sven Neumann's avatar
Sven Neumann committed
303
    {
Sven Neumann's avatar
Sven Neumann committed
304
      gdouble radius = color_tool->options->average_radius;
Sven Neumann's avatar
Sven Neumann committed
305 306 307

      gimp_draw_tool_draw_rectangle (draw_tool,
                                     FALSE,
Sven Neumann's avatar
Sven Neumann committed
308 309 310 311
                                     color_tool->center_x - radius,
                                     color_tool->center_y - radius,
                                     2 * radius + 1,
                                     2 * radius + 1,
Sven Neumann's avatar
Sven Neumann committed
312 313
                                     TRUE);
    }
314 315
}

Sven Neumann's avatar
Sven Neumann committed
316 317 318 319 320 321 322
static gboolean
gimp_color_tool_real_pick (GimpColorTool *color_tool,
                           gint           x,
                           gint           y,
                           GimpImageType *sample_type,
                           GimpRGB       *color,
                           gint          *color_index)
323
{
Sven Neumann's avatar
Sven Neumann committed
324
  GimpTool *tool = GIMP_TOOL (color_tool);
Sven Neumann's avatar
Sven Neumann committed
325 326 327 328

  g_return_val_if_fail (tool->gdisp != NULL, FALSE);
  g_return_val_if_fail (tool->drawable != NULL, FALSE);

329
  return gimp_image_pick_color (tool->gdisp->gimage, tool->drawable, x, y,
Sven Neumann's avatar
Sven Neumann committed
330 331 332
                                color_tool->options->sample_merged,
                                color_tool->options->sample_average,
                                color_tool->options->average_radius,
Sven Neumann's avatar
Sven Neumann committed
333 334 335 336 337 338 339 340 341 342 343 344 345 346
                                sample_type,
                                color,
                                color_index);
}

static void
gimp_color_tool_pick (GimpColorTool *tool,
		      gint           x,
		      gint           y)
{
  GimpColorToolClass *klass;
  GimpImageType       sample_type;
  GimpRGB             color;
  gint                color_index;
347 348 349

  klass = GIMP_COLOR_TOOL_GET_CLASS (tool);

Sven Neumann's avatar
Sven Neumann committed
350 351 352 353 354 355 356 357 358 359 360 361 362
  if (klass->pick &&
      klass->pick (tool, x, y, &sample_type, &color, &color_index))
    {
      g_signal_emit (tool,
                     gimp_color_tool_signals[PICKED], 0,
                     sample_type,
                     &color,
                     color_index);
    }
}


void
Sven Neumann's avatar
Sven Neumann committed
363 364
gimp_color_tool_enable (GimpColorTool    *color_tool,
                        GimpColorOptions *options)
Sven Neumann's avatar
Sven Neumann committed
365 366 367 368
{
  GimpTool *tool;

  g_return_if_fail (GIMP_IS_COLOR_TOOL (color_tool));
Sven Neumann's avatar
Sven Neumann committed
369
  g_return_if_fail (GIMP_IS_COLOR_OPTIONS (options));
Sven Neumann's avatar
Sven Neumann committed
370 371 372 373

  tool = GIMP_TOOL (color_tool);
  if (gimp_tool_control_is_active (tool->control))
    {
Sven Neumann's avatar
Sven Neumann committed
374
      g_warning ("Trying to enable GimpColorTool while it is active.");
Sven Neumann's avatar
Sven Neumann committed
375 376
      return;
    }
377

Sven Neumann's avatar
Sven Neumann committed
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414
  if (color_tool->options)
    {
      g_object_unref (color_tool->options);
      color_tool->options = NULL;
    }
  color_tool->options = g_object_ref (options);

  color_tool->enabled = TRUE;
}

void
gimp_color_tool_disable (GimpColorTool *color_tool)
{
  GimpTool *tool;

  g_return_if_fail (GIMP_IS_COLOR_TOOL (color_tool));

  tool = GIMP_TOOL (color_tool);
  if (gimp_tool_control_is_active (tool->control))
    {
      g_warning ("Trying to disable GimpColorTool while it is active.");
      return;
    }

  if (color_tool->options)
    {
      g_object_unref (color_tool->options);
      color_tool->options = NULL;
    }

  color_tool->enabled = FALSE;
}

gboolean
gimp_color_tool_is_enabled (GimpColorTool *color_tool)
{
  return color_tool->enabled;
415
}