gimppainttool.c 19.9 KB
Newer Older
Elliot Lee's avatar
Elliot Lee committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/* The GIMP -- an image manipulation program
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
 * 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
#include "config.h"

Elliot Lee's avatar
Elliot Lee committed
21 22
#include <stdlib.h>
#include <string.h>
23

24
#include <gtk/gtk.h>
Sven Neumann's avatar
Sven Neumann committed
25

26
#include "libgimpcolor/gimpcolor.h"
27
#include "libgimpbase/gimpbase.h"
28

Michael Natterer's avatar
Michael Natterer committed
29
#include "tools-types.h"
Sven Neumann's avatar
Sven Neumann committed
30

Michael Natterer's avatar
Michael Natterer committed
31
#include "core/gimp.h"
32 33 34
#include "core/gimpcontext.h"
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
35
#include "core/gimpimage-pick-color.h"
36
#include "core/gimptoolinfo.h"
37

38 39
#include "paint/gimppaintcore.h"

40 41
#include "widgets/gimpdevices.h"

42
#include "display/gimpdisplay.h"
43
#include "display/gimpdisplay-foreach.h"
Michael Natterer's avatar
Michael Natterer committed
44
#include "display/gimpdisplayshell.h"
45
#include "display/gimpstatusbar.h"
46

47
#include "gimpcolorpickertool.h"
48
#include "gimppainttool.h"
49
#include "tool_manager.h"
50

51
#include "app_procs.h"
Michael Natterer's avatar
Michael Natterer committed
52 53 54
#include "gimprc.h"
#include "undo.h"

55 56
#include "libgimp/gimpintl.h"

57

58 59
#define TARGET_SIZE    15
#define STATUSBAR_SIZE 128
Elliot Lee's avatar
Elliot Lee committed
60

61

62 63 64 65 66
static void   gimp_paint_tool_class_init     (GimpPaintToolClass  *klass);
static void   gimp_paint_tool_init           (GimpPaintTool       *paint_tool);

static void   gimp_paint_tool_finalize       (GObject             *object);

67 68
static void   gimp_paint_tool_control        (GimpTool	          *tool,
					      GimpToolAction       action,
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
					      GimpDisplay         *gdisp);
static void   gimp_paint_tool_button_press   (GimpTool            *tool,
                                              GimpCoords          *coords,
                                              guint32              time,
					      GdkModifierType      state,
					      GimpDisplay         *gdisp);
static void   gimp_paint_tool_button_release (GimpTool            *tool,
                                              GimpCoords          *coords,
                                              guint32              time,
					      GdkModifierType      state,
					      GimpDisplay         *gdisp);
static void   gimp_paint_tool_motion         (GimpTool            *tool,
                                              GimpCoords          *coords,
                                              guint32              time,
					      GdkModifierType      state,
					      GimpDisplay         *gdisp);
static void   gimp_paint_tool_cursor_update  (GimpTool            *tool,
                                              GimpCoords          *coords,
					      GdkModifierType      state,
					      GimpDisplay         *gdisp);

static void   gimp_paint_tool_draw           (GimpDrawTool        *draw_tool);

static void   gimp_paint_tool_sample_color   (GimpDrawable        *drawable,
                                              gint                 x,
                                              gint                 y,
                                              gint                 state);
Elliot Lee's avatar
Elliot Lee committed
96 97


98 99
static GimpDrawToolClass *parent_class = NULL;

100

101
GType
102 103
gimp_paint_tool_get_type (void)
{
104
  static GType tool_type = 0;
105 106 107

  if (! tool_type)
    {
108
      static const GTypeInfo tool_info =
109 110
      {
        sizeof (GimpPaintToolClass),
111 112 113 114 115 116 117 118
	(GBaseInitFunc) NULL,
	(GBaseFinalizeFunc) NULL,
	(GClassInitFunc) gimp_paint_tool_class_init,
	NULL,           /* class_finalize */
	NULL,           /* class_data     */
	sizeof (GimpPaintTool),
	0,              /* n_preallocs    */
	(GInstanceInitFunc) gimp_paint_tool_init,
119 120
      };

121 122 123
      tool_type = g_type_register_static (GIMP_TYPE_DRAW_TOOL,
					  "GimpPaintTool", 
                                          &tool_info, 0);
124 125 126 127 128
    }

  return tool_type;
}

129 130
static void
gimp_paint_tool_class_init (GimpPaintToolClass *klass)
131
{
132
  GObjectClass      *object_class;
133 134 135
  GimpToolClass     *tool_class;
  GimpDrawToolClass *draw_tool_class;

136
  object_class    = G_OBJECT_CLASS (klass);
137 138
  tool_class      = GIMP_TOOL_CLASS (klass);
  draw_tool_class = GIMP_DRAW_TOOL_CLASS (klass);
139

140
  parent_class = g_type_class_peek_parent (klass);
141

142 143
  object_class->finalize     = gimp_paint_tool_finalize;

144
  tool_class->control        = gimp_paint_tool_control;
145 146 147 148 149 150
  tool_class->button_press   = gimp_paint_tool_button_press;
  tool_class->button_release = gimp_paint_tool_button_release;
  tool_class->motion         = gimp_paint_tool_motion;
  tool_class->cursor_update  = gimp_paint_tool_cursor_update;

  draw_tool_class->draw      = gimp_paint_tool_draw;
151
}
Elliot Lee's avatar
Elliot Lee committed
152

153
static void
154
gimp_paint_tool_init (GimpPaintTool *paint_tool)
155
{
156 157 158 159
  GimpTool *tool;

  tool = GIMP_TOOL (paint_tool);

160
  tool->perfectmouse      = TRUE;
161

162 163
  paint_tool->pick_colors = FALSE;
  paint_tool->pick_state  = FALSE;
164 165 166 167 168 169 170 171 172
}

static void
gimp_paint_tool_finalize (GObject *object)
{
  GimpPaintTool *paint_tool;

  paint_tool = GIMP_PAINT_TOOL (object);

173
  if (paint_tool->core)
174
    {
175 176
      g_object_unref (G_OBJECT (paint_tool->core));
      paint_tool->core = NULL;
177 178 179
    }

  G_OBJECT_CLASS (parent_class)->finalize (object);
180
}
Elliot Lee's avatar
Elliot Lee committed
181

182
static void
183 184 185
gimp_paint_tool_control (GimpTool       *tool,
			 GimpToolAction  action,
			 GimpDisplay    *gdisp)
186 187 188 189 190 191 192 193
{
  GimpPaintTool *paint_tool;
  GimpDrawable  *drawable;

  paint_tool = GIMP_PAINT_TOOL (tool);
  drawable   = gimp_image_active_drawable (gdisp->gimage);

  switch (action)
194
    {
195 196
    case PAUSE:
      break;
197

198 199
    case RESUME:
      break;
200

201
    case HALT:
202 203
      gimp_paint_core_paint (paint_tool->core,
                             drawable,
204 205 206
                             (PaintOptions *) tool->tool_info->tool_options,
                             FINISH_PAINT);
      gimp_paint_core_cleanup (paint_tool->core);
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231

#if 0
      /*  evil hack i'm thinking about...  --mitch  */
      {
        /*  HALT means the current display is going to go away (TM),
         *  so try to find another display of the same image to make
         *  straight line drawing continue to work...
         */

        GSList *list;

        for (list = display_list; list; list = g_slist_next (list))
          {
            GimpDisplay *tmp_disp;

            tmp_disp = (GimpDisplay *) list->data;

            if (tmp_disp != gdisp && tmp_disp->gimage == gdisp->gimage)
              {
                tool->gdisp = tmp_disp;
                break;
              }
          }
      }
#endif
232 233 234 235
      break;

    default:
      break;
236 237
    }

Michael Natterer's avatar
Michael Natterer committed
238
  GIMP_TOOL_CLASS (parent_class)->control (tool, action, gdisp);
239
}
240

241
static void
242 243 244 245 246
gimp_paint_tool_button_press (GimpTool        *tool,
                              GimpCoords      *coords,
                              guint32          time,
			      GdkModifierType  state,
			      GimpDisplay     *gdisp)
Elliot Lee's avatar
Elliot Lee committed
247
{
248
  GimpDrawTool  *draw_tool;
249
  GimpPaintTool *paint_tool;
250 251
  GimpPaintCore *core;
  PaintOptions  *paint_options;
252 253
  GimpBrush     *current_brush;
  GimpDrawable  *drawable;
254
  GimpCoords     curr_coords;
255
  gboolean       draw_line = FALSE;
256

257
  draw_tool  = GIMP_DRAW_TOOL (tool);
258
  paint_tool = GIMP_PAINT_TOOL (tool);
259

260 261 262 263
  core = paint_tool->core;

  paint_options = (PaintOptions *) tool->tool_info->tool_options;

264
  drawable = gimp_image_active_drawable (gdisp->gimage);
Elliot Lee's avatar
Elliot Lee committed
265

266 267
  curr_coords = *coords;

268 269 270 271
  {
    gint off_x, off_y;

    gimp_drawable_offsets (drawable, &off_x, &off_y);
272

273 274 275
    curr_coords.x -= off_x;
    curr_coords.y -= off_y;
  }
276

277 278 279
  if (draw_tool->gdisp)
    gimp_draw_tool_stop (draw_tool);

280 281 282 283 284 285 286 287 288 289 290 291 292
  if (tool->gdisp          &&
      tool->gdisp != gdisp &&
      tool->gdisp->gimage == gdisp->gimage)
    {
      /*  if this is a different display, but the same image, HACK around
       *  in tool internals AFTER stopping the current draw_tool, so
       *  straight line drawing works across different views of the
       *  same image.
       */

      tool->gdisp = gdisp;
    }

293 294 295 296 297 298 299 300 301 302
  if (gimp_devices_get_current (gdisp->gimage->gimp) ==
      gdk_device_get_core_pointer ())
    {
      core->use_pressure = FALSE;
    }
  else
    {
      core->use_pressure = TRUE;
    }

303
  if (! gimp_paint_core_start (core, drawable, &curr_coords))
Elliot Lee's avatar
Elliot Lee committed
304 305
    return;

306
  if ((gdisp != tool->gdisp) || ! (state & GDK_SHIFT_MASK))
Elliot Lee's avatar
Elliot Lee committed
307
    {
308 309
      /*  if this is a new image, reinit the core vals  */

310 311
      core->start_coords = core->cur_coords;
      core->last_coords  = core->cur_coords;
Elliot Lee's avatar
Elliot Lee committed
312
    }
313
  else if (state & GDK_SHIFT_MASK)
Elliot Lee's avatar
Elliot Lee committed
314
    {
315 316 317 318
      /*  If shift is down and this is not the first paint
       *  stroke, then draw a line from the last coords to the pointer
       */

319
      draw_line = TRUE;
320

321
      core->start_coords = core->last_coords;
322

323
      if (state & GDK_CONTROL_MASK)
324
	{
325
          /* Restrict to multiples of 15 degrees if ctrl is pressed */
326

327
          gimp_paint_core_constrain (core);
328
	}
Elliot Lee's avatar
Elliot Lee committed
329 330
    }

331 332
  tool->state = ACTIVE;
  tool->gdisp = gdisp;
Elliot Lee's avatar
Elliot Lee committed
333

334
  /*  pause the current selection  */
335
  gimp_image_selection_control (gdisp->gimage, GIMP_SELECTION_PAUSE);
Elliot Lee's avatar
Elliot Lee committed
336 337

  /*  Let the specific painting function initialize itself  */
338
  gimp_paint_core_paint (core, drawable, paint_options, INIT_PAINT);
Elliot Lee's avatar
Elliot Lee committed
339

340 341 342
  if (paint_tool->pick_colors    &&
      ! (state & GDK_SHIFT_MASK) &&
      (state & (GDK_CONTROL_MASK | GDK_MOD1_MASK)))
343
    {
344
      gimp_paint_tool_sample_color (drawable,
345 346
                                    coords->x,
                                    coords->y,
347
                                    state);
348

349
      paint_tool->pick_state = TRUE;
350 351 352

      gimp_draw_tool_start (draw_tool, gdisp);

353 354
      return;
    }
355
  else
356 357 358
    {
      paint_tool->pick_state = FALSE;
    }
359

360
  /*  store the current brush pointer  */
361
  current_brush = core->brush;
362

363 364
  if (core->flags & CORE_TRACES_ON_WINDOW)
    gimp_paint_core_paint (core, drawable, paint_options, PRETRACE_PAINT);
365

Elliot Lee's avatar
Elliot Lee committed
366 367 368
  /*  Paint to the image  */
  if (draw_line)
    {
369
      gimp_paint_core_interpolate (core, drawable, paint_options);
370

371
      core->last_coords = core->cur_coords;
Elliot Lee's avatar
Elliot Lee committed
372 373
    }
  else
374
    {
375
      gimp_paint_core_paint (core, drawable, paint_options, MOTION_PAINT);
376
    }
Sven Neumann's avatar
Sven Neumann committed
377

378
  gimp_display_flush_now (gdisp);
Sven Neumann's avatar
Sven Neumann committed
379

380 381
  if (core->flags & CORE_TRACES_ON_WINDOW)
    gimp_paint_core_paint (core, drawable, paint_options, POSTTRACE_PAINT);
382 383

  /*  restore the current brush pointer  */
384
  core->brush = current_brush;
Elliot Lee's avatar
Elliot Lee committed
385 386
}

387
static void
388 389 390 391 392
gimp_paint_tool_button_release (GimpTool        *tool,
                                GimpCoords      *coords,
                                guint32          time,
				GdkModifierType  state,
				GimpDisplay     *gdisp)
Elliot Lee's avatar
Elliot Lee committed
393
{
394
  GimpPaintTool *paint_tool;
395 396
  GimpPaintCore *core;
  PaintOptions  *paint_options;
Michael Natterer's avatar
Michael Natterer committed
397
  GimpDrawable  *drawable;
Elliot Lee's avatar
Elliot Lee committed
398

399
  paint_tool = GIMP_PAINT_TOOL (tool);
Elliot Lee's avatar
Elliot Lee committed
400

401 402 403 404
  core = paint_tool->core;

  paint_options = (PaintOptions *) tool->tool_info->tool_options;

Michael Natterer's avatar
Michael Natterer committed
405 406
  drawable = gimp_image_active_drawable (gdisp->gimage);

407 408 409 410 411 412 413
  if (paint_tool->pick_state)
    {
      gimp_draw_tool_stop (GIMP_DRAW_TOOL (tool));

      paint_tool->pick_state = FALSE;
    }

Elliot Lee's avatar
Elliot Lee committed
414
  /*  Let the specific painting function finish up  */
415
  gimp_paint_core_paint (core, drawable, paint_options, FINISH_PAINT);
Elliot Lee's avatar
Elliot Lee committed
416

417 418 419
  /*  resume the current selection  */
  gimp_image_selection_control (gdisp->gimage, GIMP_SELECTION_RESUME);

Michael Natterer's avatar
Michael Natterer committed
420
  /*  Set tool state to inactive -- no longer painting */
Elliot Lee's avatar
Elliot Lee committed
421 422
  tool->state = INACTIVE;

423
  gimp_paint_core_finish (core, drawable);
424

Elliot Lee's avatar
Elliot Lee committed
425 426 427
  gdisplays_flush ();
}

428
static void
429 430 431 432 433
gimp_paint_tool_motion (GimpTool        *tool,
                        GimpCoords      *coords,
                        guint32          time,
			GdkModifierType  state,
			GimpDisplay     *gdisp)
Elliot Lee's avatar
Elliot Lee committed
434
{
435
  GimpPaintTool *paint_tool;
436 437
  GimpPaintCore *core;
  PaintOptions  *paint_options;
Michael Natterer's avatar
Michael Natterer committed
438
  GimpDrawable  *drawable;
Elliot Lee's avatar
Elliot Lee committed
439

440
  paint_tool = GIMP_PAINT_TOOL (tool);
Elliot Lee's avatar
Elliot Lee committed
441

442 443 444 445
  core = paint_tool->core;

  paint_options = (PaintOptions *) tool->tool_info->tool_options;

Michael Natterer's avatar
Michael Natterer committed
446 447
  drawable = gimp_image_active_drawable (gdisp->gimage);

448 449 450 451 452
  if (paint_tool->pick_state)
    {
      gimp_draw_tool_pause (GIMP_DRAW_TOOL (paint_tool));
    }

453
  core->cur_coords = *coords;
454

455 456 457 458 459 460 461 462
  {
    gint off_x, off_y;
    
    gimp_drawable_offsets (drawable, &off_x, &off_y);

    core->cur_coords.x -= off_x;
    core->cur_coords.y -= off_y;
  }
463

464
  if (paint_tool->pick_state)
465
    {
Michael Natterer's avatar
Michael Natterer committed
466
      gimp_paint_tool_sample_color (drawable,
467 468
				    coords->x,
                                    coords->y,
469
				    state);
470 471 472

      gimp_draw_tool_resume (GIMP_DRAW_TOOL (paint_tool));

473 474
      return;
    }
475

476 477
  if (core->flags & CORE_TRACES_ON_WINDOW)
    gimp_paint_core_paint (core, drawable, paint_options, PRETRACE_PAINT);
Sven Neumann's avatar
Sven Neumann committed
478

479
  gimp_paint_core_interpolate (core, drawable, paint_options);
480

481
  gimp_display_flush_now (gdisp);
Sven Neumann's avatar
Sven Neumann committed
482

483 484
  if (core->flags & CORE_TRACES_ON_WINDOW)
    gimp_paint_core_paint (core, drawable, paint_options, POSTTRACE_PAINT);
485

486
  core->last_coords = core->cur_coords;
Elliot Lee's avatar
Elliot Lee committed
487 488
}

489
static void
490 491 492 493
gimp_paint_tool_cursor_update (GimpTool        *tool,
                               GimpCoords      *coords,
			       GdkModifierType  state,
			       GimpDisplay     *gdisp)
Elliot Lee's avatar
Elliot Lee committed
494
{
Michael Natterer's avatar
Michael Natterer committed
495 496
  GimpPaintTool    *paint_tool;
  GimpDrawTool     *draw_tool;
497
  GimpPaintCore    *core;
Michael Natterer's avatar
Michael Natterer committed
498 499
  GimpDisplayShell *shell;
  GimpLayer        *layer;
Elliot Lee's avatar
Elliot Lee committed
500

501 502
  paint_tool = GIMP_PAINT_TOOL (tool);
  draw_tool  = GIMP_DRAW_TOOL (tool);
Elliot Lee's avatar
Elliot Lee committed
503

504 505
  core = paint_tool->core;

Michael Natterer's avatar
Michael Natterer committed
506 507
  shell = GIMP_DISPLAY_SHELL (gdisp->shell);

508 509 510
  /*  undraw the old line (if any)  */
  if (draw_tool->gdisp)
    gimp_draw_tool_stop (draw_tool);
511

512 513
  gimp_statusbar_pop (GIMP_STATUSBAR (shell->statusbar),
                      g_type_name (G_TYPE_FROM_INSTANCE (tool)));
514

515 516 517 518 519 520 521 522 523 524 525 526 527
  if (tool->gdisp          &&
      tool->gdisp != gdisp &&
      tool->gdisp->gimage == gdisp->gimage)
    {
      /*  if this is a different display, but the same image, HACK around
       *  in tool internals AFTER stopping the current draw_tool, so
       *  straight line drawing works across different views of the
       *  same image.
       */

      tool->gdisp = gdisp;
    }

528
  if ((layer = gimp_image_get_active_layer (gdisp->gimage)))
529
    {
530
      if (gdisp == tool->gdisp && (state & GDK_SHIFT_MASK))
531
	{
532 533 534 535 536 537 538
          /*  If shift is down and this is not the first paint stroke,
           *  draw a line
           */

	  gdouble dx, dy, dist;
          gchar   status_str[STATUSBAR_SIZE];

539
          core->cur_coords = *coords;
540

541 542 543 544 545 546 547 548
          {
            gint off_x, off_y;

            gimp_drawable_offsets (GIMP_DRAWABLE (layer), &off_x, &off_y);

            core->cur_coords.x -= off_x;
            core->cur_coords.y -= off_y;
          }
Sven Neumann's avatar
Sven Neumann committed
549

550
	  if (state & GDK_CONTROL_MASK)
551
	    {
552 553 554
              /*  Restrict to multiples of 15 degrees if ctrl is pressed  */

              gimp_paint_core_constrain (core);
555 556
	    }

557 558 559
	  dx = core->cur_coords.x - core->last_coords.x;
	  dy = core->cur_coords.y - core->last_coords.y;

560 561 562
	  /*  show distance in statusbar  */
	  if (gdisp->dot_for_dot)
	    {
563 564
	      dist = sqrt (SQR (dx) + SQR (dy));

565
	      g_snprintf (status_str, sizeof (status_str), "%.1f %s",
566
                          dist, _("pixels"));
567 568 569
	    }
	  else
	    {
570 571 572 573 574 575
	      gchar format_str[64];

              g_snprintf (format_str, sizeof (format_str), "%%.%df %s",
                          gimp_unit_get_digits (gdisp->gimage->unit),
                          gimp_unit_get_symbol (gdisp->gimage->unit));

576 577 578
	      dist = (gimp_unit_get_factor (gdisp->gimage->unit) *
                      sqrt (SQR (dx / gdisp->gimage->xresolution) +
                            SQR (dy / gdisp->gimage->yresolution)));
579

580 581
	      g_snprintf (status_str, sizeof (status_str), format_str,
                          dist);
582
	    }
583

584 585
	  gimp_statusbar_push (GIMP_STATUSBAR (shell->statusbar),
                               g_type_name (G_TYPE_FROM_INSTANCE (tool)),
586
                               status_str);
587

588
          gimp_draw_tool_start (draw_tool, gdisp);
589 590
	}
      else if (paint_tool->pick_colors &&
591 592
	       ! (state & GDK_SHIFT_MASK) &&
	       (state & (GDK_CONTROL_MASK | GDK_MOD1_MASK)))
593
        {
594 595 596 597 598 599 600
          /* If Ctrl or Mod1 is pressed, pick colors */

          gimp_tool_set_cursor (tool, gdisp,
                                GIMP_COLOR_PICKER_CURSOR,
                                GIMP_COLOR_PICKER_TOOL_CURSOR,
                                GIMP_CURSOR_MODIFIER_NONE);
          return;
601
	}
602
    }
Michael Natterer's avatar
Michael Natterer committed
603

604
  GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, gdisp);
Elliot Lee's avatar
Elliot Lee committed
605 606
}

607 608
static void
gimp_paint_tool_draw (GimpDrawTool *draw_tool)
Elliot Lee's avatar
Elliot Lee committed
609
{
610 611 612 613 614 615 616 617
  GimpPaintTool *paint_tool;
  GimpPaintCore *core;

  paint_tool = GIMP_PAINT_TOOL (draw_tool);

  core = paint_tool->core;

  if (paint_tool->pick_state)
618
    {
619 620
      GimpToolInfo               *info;
      GimpColorPickerToolOptions *options;
621

622 623
      info = tool_manager_get_info_by_type (GIMP_TOOL (draw_tool)->tool_info->gimp,
                                            GIMP_TYPE_COLOR_PICKER_TOOL);
624

625
      options = (GimpColorPickerToolOptions *) info->tool_options;
626

627 628 629 630 631 632 633 634 635 636 637 638 639 640 641
      if (options->sample_average)
        {
          gimp_draw_tool_draw_rectangle (draw_tool,
                                         FALSE,
                                         (core->cur_coords.x -
                                          options->average_radius),
                                         (core->cur_coords.y -
                                          options->average_radius),
                                         2 * options->average_radius + 1,
                                         2 * options->average_radius + 1,
                                         TRUE);
        }
    }
  else
    {
642 643 644
      /*  Draw start target  */
      gimp_draw_tool_draw_handle (draw_tool,
                                  GIMP_HANDLE_CROSS,
645 646
                                  floor (core->last_coords.x) + 0.5,
                                  floor (core->last_coords.y) + 0.5,
647 648 649 650 651 652 653 654
                                  TARGET_SIZE,
                                  TARGET_SIZE,
                                  GTK_ANCHOR_CENTER,
                                  TRUE);

      /*  Draw end target  */
      gimp_draw_tool_draw_handle (draw_tool,
                                  GIMP_HANDLE_CROSS,
655 656
                                  floor (core->cur_coords.x) + 0.5,
                                  floor (core->cur_coords.y) + 0.5,
657 658 659 660 661 662 663
                                  TARGET_SIZE,
                                  TARGET_SIZE,
                                  GTK_ANCHOR_CENTER,
                                  TRUE);

      /*  Draw the line between the start and end coords  */
      gimp_draw_tool_draw_line (draw_tool,
664 665 666 667
                                floor (core->last_coords.x) + 0.5,
                                floor (core->last_coords.y) + 0.5,
                                floor (core->cur_coords.x) + 0.5,
                                floor (core->cur_coords.y) + 0.5,
668 669
                                TRUE);
    }
670
}
Elliot Lee's avatar
Elliot Lee committed
671

672
static void
673 674 675 676
gimp_paint_tool_sample_color (GimpDrawable *drawable,
			      gint          x,
			      gint          y,
			      gint          state)
677
{
678 679 680 681
  GimpToolInfo               *picker_info;
  GimpColorPickerToolOptions *picker_options;
  GimpImage                  *gimage;
  GimpRGB                     color;
Michael Natterer's avatar
Michael Natterer committed
682

683
  gimage = gimp_drawable_gimage (drawable);
Michael Natterer's avatar
Michael Natterer committed
684

685 686
  picker_info = tool_manager_get_info_by_type (gimage->gimp,
                                               GIMP_TYPE_COLOR_PICKER_TOOL);
687

688
  picker_options = (GimpColorPickerToolOptions *) picker_info->tool_options;
Elliot Lee's avatar
Elliot Lee committed
689

690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705
  if (gimp_image_pick_color (gimage,
                             drawable,
                             picker_options->sample_merged,
                             x, y,
                             picker_options->sample_average,
                             picker_options->average_radius,
                             &color,
                             NULL,
                             NULL))
    {
      if ((state & GDK_CONTROL_MASK))
        gimp_context_set_foreground (gimp_get_user_context (gimage->gimp),
                                     &color);
      else
        gimp_context_set_background (gimp_get_user_context (gimage->gimp),
                                     &color);
706
    }
Elliot Lee's avatar
Elliot Lee committed
707
}