gimptransformtool.c 46.3 KB
Newer Older
Nate Summers's avatar
Nate Summers committed
1
/* The GIMP -- an image manipulation program
Nate Summers's avatar
Nate Summers committed
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 27
 * 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 <stdlib.h>

#include <gtk/gtk.h>

#include "libgimpmath/gimpmath.h"
#include "libgimpwidgets/gimpwidgets.h"

Michael Natterer's avatar
Michael Natterer committed
28
#include "tools-types.h"
Nate Summers's avatar
Nate Summers committed
29

Michael Natterer's avatar
Michael Natterer committed
30 31 32 33 34 35
#include "base/base-config.h"
#include "base/pixel-region.h"
#include "base/pixel-surround.h"
#include "base/tile-manager.h"
#include "base/tile.h"

36 37
#include "paint-funcs/paint-funcs.h"

Michael Natterer's avatar
Michael Natterer committed
38
#include "core/gimp.h"
39 40 41 42 43 44 45
#include "core/gimpchannel.h"
#include "core/gimpcontext.h"
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
#include "core/gimpimage-mask.h"
#include "core/gimplayer.h"
#include "core/gimpmarshal.h"
Michael Natterer's avatar
Michael Natterer committed
46
#include "core/gimptoolinfo.h"
47

48 49
#include "gui/info-dialog.h"
#include "gdisplay.h"
Nate Summers's avatar
Nate Summers committed
50

51 52 53 54
#include "tool_manager.h"
#include "tool_options.h"
#include "transform_options.h"
#include "gimptransformtool.h"
Michael Natterer's avatar
Michael Natterer committed
55 56 57 58 59
#include "gimpperspectivetool.h"
#include "gimprotatetool.h"
#include "gimpscaletool.h"
#include "gimpsheartool.h"
#include "gimpfliptool.h"
60

Michael Natterer's avatar
Michael Natterer committed
61 62 63 64
#include "app_procs.h"
#include "floating_sel.h"
#include "undo.h"
#include "path_transform.h"
Nate Summers's avatar
Nate Summers committed
65 66 67

#include "libgimp/gimpintl.h"

68

Nate Summers's avatar
Nate Summers committed
69 70 71 72
enum
{
  TRANSFORM,
  LAST_SIGNAL
Nate Summers's avatar
Nate Summers committed
73
};
Nate Summers's avatar
Nate Summers committed
74 75 76 77 78 79 80

#define BILINEAR(jk,j1k,jk1,j1k1,dx,dy) \
                ((1-dy) * (jk + dx * (j1k - jk)) + \
		    dy  * (jk1 + dx * (j1k1 - jk1)))

/* access interleaved pixels */
#define CUBIC_ROW(dx, row, step) \
Nate Summers's avatar
Nate Summers committed
81
  gimp_transform_tool_cubic(dx, (row)[0], (row)[step], (row)[step+step], (row)[step+step+step])
Nate Summers's avatar
Nate Summers committed
82
#define CUBIC_SCALED_ROW(dx, row, step, i) \
Nate Summers's avatar
Nate Summers committed
83
  gimp_transform_tool_cubic(dx, (row)[0] * (row)[i], \
Nate Summers's avatar
Nate Summers committed
84 85 86 87 88 89 90 91
            (row)[step] * (row)[step + i], \
            (row)[step+step]* (row)[step+step + i], \
            (row)[step+step+step] * (row)[step+step+step + i])

#define REF_TILE(i,x,y) \
     tile[i] = tile_manager_get_tile (float_tiles, x, y, TRUE, FALSE); \
     src[i] = tile_data_pointer (tile[i], (x) % TILE_WIDTH, (y) % TILE_HEIGHT);

92

Nate Summers's avatar
Nate Summers committed
93
/*  forward function declarations  */
Nate Summers's avatar
Nate Summers committed
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
static void      gimp_transform_tool_bounds    (GimpTransformTool      *tool,
                                                GDisplay               *gdisp);
static void      gimp_transform_tool_recalc    (GimpTransformTool      *tool,
					        GDisplay               *gdisp);
static void      gimp_transform_tool_doit      (GimpTransformTool      *tool,
					        GDisplay               *gdisp);
static gdouble   gimp_transform_tool_cubic     (gdouble                 dx,
					        gint                    jm1,
					        gint                    j,
					        gint                    jp1,
					        gint                    jp2);
static void    gimp_transform_tool_setup_grid  (GimpTransformTool      *tool);
static void    gimp_transform_tool_grid_recalc (GimpTransformTool      *gimp_transform_tool);
static void    gimp_transform_tool_init        (GimpTransformTool      *tool);
static void    gimp_transform_tool_class_init  (GimpTransformToolClass *tool);
Nate Summers's avatar
Nate Summers committed
109

110
static void    gimp_transform_tool_finalize    (GObject                *object);
111 112

static void   gimp_transform_tool_button_press (GimpTool               *tool,
Nate Summers's avatar
Nate Summers committed
113 114 115
                                                GdkEventButton         *bevent,
			                        GDisplay               *gdisp);
			          
116
static void gimp_transform_tool_button_release (GimpTool               *tool,
Nate Summers's avatar
Nate Summers committed
117 118 119
			                        GdkEventButton         *bevent,
			                        GDisplay               *gdisp);
			                        
120
static void    gimp_transform_tool_motion      (GimpTool               *tool,
Nate Summers's avatar
Nate Summers committed
121 122 123
		                                GdkEventMotion         *mevent,
		                                GDisplay               *gdisp);
		                                
124
static void  gimp_transform_tool_cursor_update (GimpTool               *tool,
Nate Summers's avatar
Nate Summers committed
125 126 127
	                 		        GdkEventMotion         *mevent,
			                        GDisplay               *gdisp);
			                        
128
static void    gimp_transform_tool_control     (GimpTool               *tool,
Nate Summers's avatar
Nate Summers committed
129 130
			                        ToolAction              action,
			                        GDisplay               *gdisp);
131 132 133 134

static void    gimp_transform_tool_draw        (GimpDrawTool           *draw_tool);


Nate Summers's avatar
Nate Summers committed
135
/*  variables  */
Nate Summers's avatar
Nate Summers committed
136 137 138
static TranInfo           old_trans_info;
InfoDialog               *transform_info        = NULL;
static gboolean           transform_info_inited = FALSE;
Nate Summers's avatar
Nate Summers committed
139

140
static GimpDrawToolClass *parent_class = NULL;
141

142 143 144 145
static guint   gimp_transform_tool_signals[LAST_SIGNAL] = { 0 };


GType
Nate Summers's avatar
Nate Summers committed
146 147
gimp_transform_tool_get_type (void)
{
148
  static GType tool_type = 0;
Nate Summers's avatar
Nate Summers committed
149 150 151

  if (! tool_type)
    {
152
      static const GTypeInfo tool_info =
Nate Summers's avatar
Nate Summers committed
153 154
      {
        sizeof (GimpTransformToolClass),
155 156 157 158 159 160 161 162
	(GBaseInitFunc) NULL,
	(GBaseFinalizeFunc) NULL,
	(GClassInitFunc) gimp_transform_tool_class_init,
	NULL,           /* class_finalize */
	NULL,           /* class_data     */
	sizeof (GimpTransformTool),
	0,              /* n_preallocs    */
	(GInstanceInitFunc) gimp_transform_tool_init,
Nate Summers's avatar
Nate Summers committed
163 164
      };

165 166 167
      tool_type = g_type_register_static (GIMP_TYPE_DRAW_TOOL,
					  "GimpTransformTool", 
                                          &tool_info, 0);
Nate Summers's avatar
Nate Summers committed
168 169 170 171 172 173 174 175
    }

  return tool_type;
}

static void
gimp_transform_tool_class_init (GimpTransformToolClass *klass)
{
176
  GObjectClass      *object_class;
Nate Summers's avatar
Nate Summers committed
177 178
  GimpToolClass     *tool_class;
  GimpDrawToolClass *draw_class;
Nate Summers's avatar
Nate Summers committed
179

180 181 182
  object_class = G_OBJECT_CLASS (klass);
  tool_class   = GIMP_TOOL_CLASS (klass);
  draw_class   = GIMP_DRAW_TOOL_CLASS (klass);
Nate Summers's avatar
Nate Summers committed
183

184
  parent_class = g_type_class_peek_parent (klass);
Nate Summers's avatar
Nate Summers committed
185 186

  gimp_transform_tool_signals[TRANSFORM] =
187 188 189 190 191 192 193 194 195
    g_signal_new ("transform",
		  G_TYPE_FROM_CLASS (klass),
		  G_SIGNAL_RUN_LAST,
		  G_STRUCT_OFFSET (GimpTransformToolClass, transform),
		  NULL, NULL,
		  gimp_cclosure_marshal_POINTER__POINTER_INT,
		  G_TYPE_POINTER, 2,
		  G_TYPE_POINTER,
		  G_TYPE_INT);
Nate Summers's avatar
Nate Summers committed
196

197
  object_class->finalize     = gimp_transform_tool_finalize;
Nate Summers's avatar
Nate Summers committed
198 199 200 201 202 203

  tool_class->button_press   = gimp_transform_tool_button_press;
  tool_class->button_release = gimp_transform_tool_button_release;
  tool_class->motion         = gimp_transform_tool_motion;
  tool_class->cursor_update  = gimp_transform_tool_cursor_update;
  tool_class->control        = gimp_transform_tool_control;
Nate Summers's avatar
Nate Summers committed
204 205

  draw_class->draw           = gimp_transform_tool_draw;
Nate Summers's avatar
Nate Summers committed
206 207 208
}

static void
Nate Summers's avatar
Nate Summers committed
209
gimp_transform_tool_init (GimpTransformTool *tr_tool)
Nate Summers's avatar
Nate Summers committed
210
{
211 212
  GimpTool *tool = GIMP_TOOL (tr_tool);
  gint      i;
Nate Summers's avatar
Nate Summers committed
213 214 215 216 217 218 219 220 221 222 223

  tr_tool->function = TRANSFORM_CREATING;
  tr_tool->original = NULL;

  tr_tool->bpressed = FALSE;

  for (i = 0; i < TRAN_INFO_SIZE; i++)
    tr_tool->trans_info[i] = 0;

  tr_tool->grid_coords = tr_tool->tgrid_coords = NULL;

224 225 226
  /* FIXME */
  tr_tool->interactive = TRUE;

Nate Summers's avatar
Nate Summers committed
227 228
  tool->scroll_lock = TRUE;   /*  Disallow scrolling  */
  tool->preserve    = FALSE;  /*  Don't preserve on drawable change  */
229

Nate Summers's avatar
Nate Summers committed
230 231
}

Nate Summers's avatar
Nate Summers committed
232 233 234 235 236 237 238 239 240 241
TileManager *
gimp_transform_tool_transform (GimpTransformTool   *tool,
                               GDisplay            *gdisp,
			       TransformState       state)
{
  TileManager *retval;

  g_return_val_if_fail (tool, NULL);
  g_return_val_if_fail (GIMP_IS_TRANSFORM_TOOL (tool), NULL);

242 243
  g_signal_emit (G_OBJECT (tool), gimp_transform_tool_signals[TRANSFORM], 0,
                 gdisp, state, &retval);
Nate Summers's avatar
Nate Summers committed
244 245 246 247

  return retval;
}

Nate Summers's avatar
Nate Summers committed
248 249 250 251
static void
transform_ok_callback (GtkWidget *widget,
		       gpointer   data)
{
Nate Summers's avatar
Nate Summers committed
252
  GimpTool *tool;
Nate Summers's avatar
Nate Summers committed
253

Nate Summers's avatar
Nate Summers committed
254 255
  tool = GIMP_TOOL(data);
  gimp_transform_tool_doit (GIMP_TRANSFORM_TOOL(tool), tool->gdisp);
Nate Summers's avatar
Nate Summers committed
256 257 258 259 260 261 262 263 264 265
}

static void
transform_reset_callback (GtkWidget *widget,
			  gpointer   data)
{
  GimpTransformTool   *tool;
  GimpDrawTool        *dr_tool;
  gint                 i;

266 267
  tool    = GIMP_TRANSFORM_TOOL (data);
  dr_tool = GIMP_DRAW_TOOL (data);
Nate Summers's avatar
Nate Summers committed
268 269

  /*  stop the current tool drawing process  */
Nate Summers's avatar
Nate Summers committed
270
  gimp_draw_tool_pause (dr_tool);
Nate Summers's avatar
Nate Summers committed
271 272 273 274 275 276

  /*  Restore the previous transformation info  */
  for (i = 0; i < TRAN_INFO_SIZE; i++)
    tool->trans_info [i] = old_trans_info [i];

  /*  recalculate the tool's transformation matrix  */
Nate Summers's avatar
Nate Summers committed
277
  gimp_transform_tool_recalc (tool, GIMP_TOOL(tool)->gdisp);
Nate Summers's avatar
Nate Summers committed
278 279

  /*  resume drawing the current tool  */
Nate Summers's avatar
Nate Summers committed
280
  gimp_draw_tool_resume (dr_tool);
Nate Summers's avatar
Nate Summers committed
281 282
}

283
static void
284
gimp_transform_tool_finalize (GObject *object)
Nate Summers's avatar
Nate Summers committed
285
{
286
  GimpTransformTool *tr_tool;
Nate Summers's avatar
Nate Summers committed
287

288 289 290
  tr_tool = GIMP_TRANSFORM_TOOL (object);

  if (tr_tool->original)
291 292 293 294
    {
      tile_manager_destroy (tr_tool->original);
      tr_tool->original = NULL;
    }
295 296

  if (transform_info)
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327
    {
      info_dialog_free (transform_info);
      transform_info        = NULL;
      transform_info_inited = FALSE;
    }

  if (tr_tool->grid_coords)
    {
      g_free (tr_tool->grid_coords);
      tr_tool->grid_coords = NULL;
    }

  if (tr_tool->tgrid_coords)
    {
      g_free (tr_tool->tgrid_coords);
      tr_tool->tgrid_coords = NULL;
    }

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

static void
gimp_transform_tool_control (GimpTool   *tool,
			     ToolAction  action,
			     GDisplay   *gdisp)
{
  GimpDrawTool      *dr_tool;
  GimpTransformTool *tr_tool;

  dr_tool = GIMP_DRAW_TOOL (tool);
  tr_tool = GIMP_TRANSFORM_TOOL (tool);
328

329 330 331 332
  switch (action)
    {
    case PAUSE:
      break;
333

334 335 336
    case RESUME:
      gimp_transform_tool_recalc (tr_tool, gdisp);
      break;
337

338 339 340
    case HALT:
      gimp_transform_tool_reset (tr_tool, gdisp);
      break;
341

342 343 344 345 346 347
    default:
      break;
    }

  if (GIMP_TOOL_CLASS (parent_class)->control)
    GIMP_TOOL_CLASS (parent_class)->control (tool, action, gdisp);
348 349 350
}

static void
Nate Summers's avatar
Nate Summers committed
351
gimp_transform_tool_button_press (GimpTool           *tool,
Nate Summers's avatar
Nate Summers committed
352 353 354
                                  GdkEventButton     *bevent,
			          GDisplay           *gdisp)
{
Nate Summers's avatar
Nate Summers committed
355 356 357 358 359 360 361
  GimpTransformTool  *gt_tool;
  GimpDrawable       *drawable;
  gint                dist;
  gint                closest_dist;
  gint                x, y;
  gint                i;
  gint                off_x, off_y;
Nate Summers's avatar
Nate Summers committed
362

363
  gt_tool = GIMP_TRANSFORM_TOOL (tool);
Nate Summers's avatar
Nate Summers committed
364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382

  gt_tool->bpressed = TRUE; /* ALT */

  drawable = gimp_image_active_drawable (gdisp->gimage);

  if (gt_tool->function == TRANSFORM_CREATING && tool->state == ACTIVE)
    {
      /*  Save the current transformation info  */
      for (i = 0; i < TRAN_INFO_SIZE; i++)
	old_trans_info [i] = gt_tool->trans_info [i];
    }

  /*  if we have already displayed the bounding box and handles,
   *  check to make sure that the display which currently owns the
   *  tool is the one which just received the button pressed event
   */
  if ((gdisp == tool->gdisp) && gt_tool->interactive)
    {
      /*  start drawing the bounding box and handles...  */
383 384
      gimp_draw_tool_start (GIMP_DRAW_TOOL (gt_tool), gdisp->canvas->window);

Nate Summers's avatar
Nate Summers committed
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
      x = bevent->x;
      y = bevent->y;

      closest_dist = SQR (x - gt_tool->sx1) + SQR (y - gt_tool->sy1);
      gt_tool->function = TRANSFORM_HANDLE_1;

      dist = SQR (x - gt_tool->sx2) + SQR (y - gt_tool->sy2);
      if (dist < closest_dist)
	{
	  closest_dist = dist;
	  gt_tool->function = TRANSFORM_HANDLE_2;
	}

      dist = SQR (x - gt_tool->sx3) + SQR (y - gt_tool->sy3);
      if (dist < closest_dist)
	{
	  closest_dist = dist;
	  gt_tool->function = TRANSFORM_HANDLE_3;
	}

      dist = SQR (x - gt_tool->sx4) + SQR (y - gt_tool->sy4);
      if (dist < closest_dist)
	{
	  closest_dist = dist;
	  gt_tool->function = TRANSFORM_HANDLE_4;
	}

412 413
      if ((SQR (x - gt_tool->scx) +
	   SQR (y - gt_tool->scy)) <= 100)
Nate Summers's avatar
Nate Summers committed
414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445
	{
	  gt_tool->function = TRANSFORM_HANDLE_CENTER;
	}

      /*  Save the current pointer position  */
      gdisplay_untransform_coords (gdisp, bevent->x, bevent->y,
				   &gt_tool->startx,
				   &gt_tool->starty, TRUE, 0);
      gt_tool->lastx = gt_tool->startx;
      gt_tool->lasty = gt_tool->starty;

      gdk_pointer_grab (gdisp->canvas->window, FALSE,
			GDK_POINTER_MOTION_HINT_MASK |
			GDK_BUTTON1_MOTION_MASK |
			GDK_BUTTON_RELEASE_MASK,
			NULL, NULL, bevent->time);

      tool->state = ACTIVE;
      return;
    }


  /*  Initialisation stuff: if the cursor is clicked inside the current
   *  selection, show the bounding box and handles...
   */
  gdisplay_untransform_coords (gdisp, bevent->x, bevent->y, &x, &y,
			       FALSE, FALSE);

  gimp_drawable_offsets (drawable, &off_x, &off_y);
  if (x >= off_x && y >= off_y &&
      x < (off_x + gimp_drawable_width (drawable)) &&
      y < (off_y + gimp_drawable_height (drawable)))
446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492
    {
      if (gimage_mask_is_empty (gdisp->gimage) ||
	  gimage_mask_value (gdisp->gimage, x, y))
	{
	  if (GIMP_IS_LAYER (drawable) &&
	      gimp_layer_get_mask (GIMP_LAYER (drawable)))
	    {
	      g_message (_("Transformations do not work on\n"
			   "layers that contain layer masks."));
	      tool->state = INACTIVE;
	      return;
	    }

	  /*  If the tool is already active, clear the current state
	   *  and reset
	   */
	  if (tool->state == ACTIVE)
	    gimp_transform_tool_reset (gt_tool, gdisp);

	  /*  Set the pointer to the active display  */
	  tool->gdisp    = gdisp;
	  tool->drawable = drawable;
	  tool->state    = ACTIVE;

	  /*  Grab the pointer if we're in non-interactive mode  */
	  if (!gt_tool->interactive)
	    gdk_pointer_grab (gdisp->canvas->window, FALSE,
			      (GDK_POINTER_MOTION_HINT_MASK |
			       GDK_BUTTON1_MOTION_MASK |
			       GDK_BUTTON_RELEASE_MASK),
			      NULL, NULL, bevent->time);

	  /*  Find the transform bounds for some tools (like scale,
	   *  perspective) that actually need the bounds for
	   *  initializing
	   */
	  gimp_transform_tool_bounds (gt_tool, gdisp);

	  /*  Calculate the grid line endpoints  */
	  if (gimp_transform_tool_show_grid ())
	    gimp_transform_tool_setup_grid (gt_tool);

	  /*  Initialize the transform tool */
	  gimp_transform_tool_transform (gt_tool, gdisp, TRANSFORM_INIT);

	  if (transform_info && !transform_info_inited)
	    {
493
	      GType tool_type;
494 495

	      tool_type =
Michael Natterer's avatar
Michael Natterer committed
496
		gimp_context_get_tool (gimp_get_user_context (gdisp->gimage->gimp))->tool_type;
497 498

	      gimp_dialog_create_action_area
499
		(GIMP_DIALOG (transform_info->shell),
500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525

		 /* FIXME: this does not belong here */
		 (tool_type == GIMP_TYPE_ROTATE_TOOL)      ? _("Rotate")    :
		 (tool_type == GIMP_TYPE_SCALE_TOOL)       ? _("Scale")     :
		 (tool_type == GIMP_TYPE_SHEAR_TOOL)       ? _("Shear")     :
		 (tool_type == GIMP_TYPE_PERSPECTIVE_TOOL) ? _("Transform") :
		 "EEK",
		 transform_ok_callback,
		 tool, NULL, NULL, TRUE, FALSE,

		 _("Reset"), transform_reset_callback,
		 tool, NULL, NULL, FALSE, FALSE,

		 NULL);

	      transform_info_inited = TRUE;
	    }

	  /*  Recalculate the transform tool  */
	  gimp_transform_tool_recalc (gt_tool, gdisp);

	  /*  recall this function to find which handle we're dragging  */
	  if (gt_tool->interactive)
	    gimp_transform_tool_button_press (tool, bevent, gdisp);
	}
    }
Nate Summers's avatar
Nate Summers committed
526 527
}

528
static void
Nate Summers's avatar
Nate Summers committed
529 530 531
gimp_transform_tool_button_release (GimpTool         *tool,
			            GdkEventButton   *bevent,
			            GDisplay         *gdisp)
Nate Summers's avatar
Nate Summers committed
532
{
Nate Summers's avatar
Nate Summers committed
533 534
  GimpTransformTool *gt_tool;
  gint               i;
Nate Summers's avatar
Nate Summers committed
535

536
  gt_tool = GIMP_TRANSFORM_TOOL (tool);
Nate Summers's avatar
Nate Summers committed
537 538 539 540

  gt_tool->bpressed = FALSE; /* ALT */

  /*  if we are creating, there is nothing to be done...exit  */
541
  if (gt_tool->function == TRANSFORM_CREATING && gt_tool->interactive)
Nate Summers's avatar
Nate Summers committed
542 543 544 545 546 547 548 549 550 551
    return;

  /*  release of the pointer grab  */
  gdk_pointer_ungrab (bevent->time);
  gdk_flush ();

  /*  if the 3rd button isn't pressed, transform the selected mask  */
  if (! (bevent->state & GDK_BUTTON3_MASK))
    {
      /* Shift-clicking is another way to approve the transform  */
552
      if ((bevent->state & GDK_SHIFT_MASK) || GIMP_IS_FLIP_TOOL (tool))
Nate Summers's avatar
Nate Summers committed
553
	{
Nate Summers's avatar
Nate Summers committed
554
	  gimp_transform_tool_doit (gt_tool, gdisp);
Nate Summers's avatar
Nate Summers committed
555 556 557 558 559 560 561 562 563 564 565
	}
      else
	{
	  /*  Only update the paths preview */
	  path_transform_current_path (gdisp->gimage,
				       gt_tool->transform, TRUE);
	}
    }
  else
    {
      /*  stop the current tool drawing process  */
566
      gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
Nate Summers's avatar
Nate Summers committed
567 568 569 570 571 572 573 574 575

      /*  Restore the previous transformation info  */
      for (i = 0; i < TRAN_INFO_SIZE; i++)
	gt_tool->trans_info [i] = old_trans_info [i];

      /*  recalculate the tool's transformation matrix  */
      gimp_transform_tool_recalc (gt_tool, gdisp);

      /*  resume drawing the current tool  */
576
      gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
Nate Summers's avatar
Nate Summers committed
577 578 579 580 581 582 583 584 585 586 587

      /* Update the paths preview */
      path_transform_current_path (gdisp->gimage,
				   gt_tool->transform, TRUE);
    }

  /*  if this tool is non-interactive, make it inactive after use  */
  if (!gt_tool->interactive)
    tool->state = INACTIVE;
}

588
static void
Nate Summers's avatar
Nate Summers committed
589 590 591 592 593 594 595 596 597 598
gimp_transform_tool_doit (GimpTransformTool  *gt_tool,
		          GDisplay           *gdisp)
{
  GimpTool      *tool;
  TileManager   *new_tiles;
  TransformUndo *tu;
  PathUndo      *pundo;
  gboolean       new_layer;
  gint           i, x, y;

599
  gimp_set_busy (gdisp->gimage->gimp);
Nate Summers's avatar
Nate Summers committed
600

601
  tool = GIMP_TOOL (gt_tool);
Nate Summers's avatar
Nate Summers committed
602 603

  /* undraw the tool before we muck around with the transform matrix */
604
  gimp_draw_tool_pause (GIMP_DRAW_TOOL (gt_tool));
Nate Summers's avatar
Nate Summers committed
605 606 607 608 609 610 611 612 613

  /*  We're going to dirty this image, but we want to keep the tool
   *  around
   */
  tool->preserve = TRUE;

  /*  Start a transform undo group  */
  undo_push_group_start (gdisp->gimage, TRANSFORM_CORE_UNDO);

614 615 616
  /* With the old UI, if original is NULL, then this is the
   * first transformation. In the new UI, it is always so, right?
   */
Nate Summers's avatar
Nate Summers committed
617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632
  g_assert (gt_tool->original == NULL);

  /* If we're in interactive mode, we need to copy the current
   *  selection to the transform tool's private selection pointer, so
   *  that the original source can be repeatedly modified.
   */
  tool->drawable = gimp_image_active_drawable (gdisp->gimage);

  gt_tool->original = gimp_transform_tool_cut (gdisp->gimage,
					       tool->drawable,
					       &new_layer);

  pundo = path_transform_start_undo (gdisp->gimage);

  /*  Send the request for the transformation to the tool...
   */
Nate Summers's avatar
Nate Summers committed
633
  new_tiles = gimp_transform_tool_transform (gt_tool, gdisp,
634
					     TRANSFORM_FINISH);
Nate Summers's avatar
Nate Summers committed
635

Nate Summers's avatar
Nate Summers committed
636
  gimp_transform_tool_transform (gt_tool, gdisp, TRANSFORM_INIT);
Nate Summers's avatar
Nate Summers committed
637 638 639 640 641 642 643 644 645 646

  gimp_transform_tool_recalc (gt_tool, gdisp);

  if (new_tiles)
    {
      /*  paste the new transformed image to the gimage...also implement
       *  undo...
       */
      /*  FIXME: we should check if the drawable is still valid  */
      gimp_transform_tool_paste (gdisp->gimage, tool->drawable,
647
				 new_tiles, new_layer);
Nate Summers's avatar
Nate Summers committed
648 649

      /*  create and initialize the transform_undo structure  */
650 651
      tu = g_new0 (TransformUndo, 1);
      tu->tool_ID   = tool->ID;
652
      tu->tool_type = G_TYPE_FROM_INSTANCE (tool);
Nate Summers's avatar
Nate Summers committed
653

Nate Summers's avatar
Nate Summers committed
654 655
      for (i = 0; i < TRAN_INFO_SIZE; i++)
	tu->trans_info[i] = old_trans_info[i];
656 657

      tu->original  = NULL;
Nate Summers's avatar
Nate Summers committed
658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678
      tu->path_undo = pundo;

      /*  Make a note of the new current drawable (since we may have
       *  a floating selection, etc now.
       */
      tool->drawable = gimp_image_active_drawable (gdisp->gimage);

      undo_push_transform (gdisp->gimage, (void *) tu);
    }

  /*  push the undo group end  */
  undo_push_group_end (gdisp->gimage);

  /*  We're done dirtying the image, and would like to be restarted
   *  if the image gets dirty while the tool exists
   */
  tool->preserve = FALSE;

  /*  Flush the gdisplays  */
  if (gdisp->disp_xoffset || gdisp->disp_yoffset)
    {
679 680 681
      x = gdisp->canvas->allocation.width;
      y = gdisp->canvas->allocation.height;

Nate Summers's avatar
Nate Summers committed
682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697
      if (gdisp->disp_yoffset)
	{
	  gdisplay_expose_area (gdisp, 0, 0, gdisp->disp_width,
				gdisp->disp_yoffset);
	  gdisplay_expose_area (gdisp, 0, gdisp->disp_yoffset + y,
				gdisp->disp_width, gdisp->disp_height);
	}
      if (gdisp->disp_xoffset)
	{
	  gdisplay_expose_area (gdisp, 0, 0, gdisp->disp_xoffset,
				gdisp->disp_height);
	  gdisplay_expose_area (gdisp, gdisp->disp_xoffset + x, 0,
				gdisp->disp_width, gdisp->disp_height);
	}
    }

698
  gimp_unset_busy (gdisp->gimage->gimp);
Nate Summers's avatar
Nate Summers committed
699 700 701

  gdisplays_flush ();

702
  gimp_transform_tool_reset (gt_tool, gdisp);
Nate Summers's avatar
Nate Summers committed
703 704

  /*  if this tool is non-interactive, make it inactive after use  */
Nate Summers's avatar
Nate Summers committed
705
  if (!gt_tool->interactive)
Nate Summers's avatar
Nate Summers committed
706 707 708
    tool->state = INACTIVE;
}

709
static void
Nate Summers's avatar
Nate Summers committed
710 711 712
gimp_transform_tool_motion (GimpTool          *tool,
		            GdkEventMotion    *mevent,
		            GDisplay          *gdisp)
Nate Summers's avatar
Nate Summers committed
713
{
Nate Summers's avatar
Nate Summers committed
714
  GimpTransformTool *tr_tool;
Nate Summers's avatar
Nate Summers committed
715

716
  tr_tool = GIMP_TRANSFORM_TOOL (tool);
Nate Summers's avatar
Nate Summers committed
717

718
  if (! tr_tool->bpressed)
Nate Summers's avatar
Nate Summers committed
719 720 721 722 723
    return;

  /*  if we are creating or this tool is non-interactive, there is
   *  nothing to be done so exit.
   */
Nate Summers's avatar
Nate Summers committed
724 725
  if (tr_tool->function == TRANSFORM_CREATING ||
      !tr_tool->interactive)
Nate Summers's avatar
Nate Summers committed
726 727 728
    return;

  /*  stop the current tool drawing process  */
729
  gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
Nate Summers's avatar
Nate Summers committed
730 731

  gdisplay_untransform_coords (gdisp, mevent->x, mevent->y,
Nate Summers's avatar
Nate Summers committed
732 733 734
			       &tr_tool->curx,
			       &tr_tool->cury, TRUE, 0);
  tr_tool->state = mevent->state;
Nate Summers's avatar
Nate Summers committed
735 736

  /*  recalculate the tool's transformation matrix  */
Nate Summers's avatar
Nate Summers committed
737
  gimp_transform_tool_transform (tr_tool, gdisp, TRANSFORM_MOTION);
Nate Summers's avatar
Nate Summers committed
738

Nate Summers's avatar
Nate Summers committed
739 740
  tr_tool->lastx = tr_tool->curx;
  tr_tool->lasty = tr_tool->cury;
Nate Summers's avatar
Nate Summers committed
741 742

  /*  resume drawing the current tool  */
743
  gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
Nate Summers's avatar
Nate Summers committed
744 745
}

746
static void
Nate Summers's avatar
Nate Summers committed
747
gimp_transform_tool_cursor_update (GimpTool           *tool,
Nate Summers's avatar
Nate Summers committed
748 749
			           GdkEventMotion     *mevent,
			           GDisplay           *gdisp)
Nate Summers's avatar
Nate Summers committed
750
{
Nate Summers's avatar
Nate Summers committed
751 752 753 754
  GimpTransformTool  *tr_tool;
  GimpDrawable       *drawable;
  GdkCursorType       ctype = GDK_TOP_LEFT_ARROW;
  gint                x, y;
Nate Summers's avatar
Nate Summers committed
755

756
  tr_tool = GIMP_TRANSFORM_TOOL (tool);
Nate Summers's avatar
Nate Summers committed
757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786

  gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &x, &y,
			       FALSE, FALSE);

  if ((drawable = gimp_image_active_drawable (gdisp->gimage)))
    {
      if (GIMP_IS_LAYER (drawable) &&
	  gimp_layer_get_mask (GIMP_LAYER (drawable)))
	{
	  ctype = GIMP_BAD_CURSOR;
	}
      else if (x >= drawable->offset_x &&
	       y >= drawable->offset_y &&
	       x < (drawable->offset_x + drawable->width) &&
	       y < (drawable->offset_y + drawable->height))
	{
	  if (gimage_mask_is_empty (gdisp->gimage) ||
	      gimage_mask_value (gdisp->gimage, x, y))
	    {
	      ctype = GIMP_MOUSE_CURSOR;
	    }
	}
    }

  gdisplay_install_tool_cursor (gdisp,
				ctype,
				tool->tool_cursor,
				GIMP_CURSOR_MODIFIER_NONE);
}

787
static void
Nate Summers's avatar
Nate Summers committed
788
gimp_transform_tool_draw (GimpDrawTool *dr_tool)
Nate Summers's avatar
Nate Summers committed
789
{
Nate Summers's avatar
Nate Summers committed
790 791 792 793 794 795 796 797
  GDisplay           *gdisp;
  GimpTransformTool  *tr_tool;
  GimpTool           *tool;
  gint                x1, y1, x2, y2, x3, y3, x4, y4;
  gint                srw, srh;
  gint                i, k, gci;
  gint                xa, ya, xb, yb;

798 799
  tr_tool = GIMP_TRANSFORM_TOOL (dr_tool);
  tool    = GIMP_TOOL (dr_tool);
Nate Summers's avatar
Nate Summers committed
800

801
  gdisp   = tool->gdisp;
Nate Summers's avatar
Nate Summers committed
802 803 804 805 806 807 808 809 810 811 812 813 814 815

  gdisplay_transform_coords (gdisp, tr_tool->tx1, tr_tool->ty1,
			     &tr_tool->sx1, &tr_tool->sy1, FALSE);
  gdisplay_transform_coords (gdisp, tr_tool->tx2, tr_tool->ty2,
			     &tr_tool->sx2, &tr_tool->sy2, FALSE);
  gdisplay_transform_coords (gdisp, tr_tool->tx3, tr_tool->ty3,
			     &tr_tool->sx3, &tr_tool->sy3, FALSE);
  gdisplay_transform_coords (gdisp, tr_tool->tx4, tr_tool->ty4,
			     &tr_tool->sx4, &tr_tool->sy4, FALSE);

  x1 = tr_tool->sx1;  y1 = tr_tool->sy1;
  x2 = tr_tool->sx2;  y2 = tr_tool->sy2;
  x3 = tr_tool->sx3;  y3 = tr_tool->sy3;
  x4 = tr_tool->sx4;  y4 = tr_tool->sy4;
Nate Summers's avatar
Nate Summers committed
816 817 818 819 820 821

  /*  find the handles' width and height  */
  srw = 10;
  srh = 10;

  /*  draw the bounding box  */
Nate Summers's avatar
Nate Summers committed
822
  gdk_draw_line (dr_tool->win, dr_tool->gc,
Nate Summers's avatar
Nate Summers committed
823
		 x1, y1, x2, y2);
Nate Summers's avatar
Nate Summers committed
824
  gdk_draw_line (dr_tool->win, dr_tool->gc,
Nate Summers's avatar
Nate Summers committed
825
		 x2, y2, x4, y4);
Nate Summers's avatar
Nate Summers committed
826
  gdk_draw_line (dr_tool->win, dr_tool->gc,
Nate Summers's avatar
Nate Summers committed
827
		 x3, y3, x4, y4);
Nate Summers's avatar
Nate Summers committed
828
  gdk_draw_line (dr_tool->win, dr_tool->gc,
Nate Summers's avatar
Nate Summers committed
829 830 831 832
		 x3, y3, x1, y1);

  /*  Draw the grid */

Nate Summers's avatar
Nate Summers committed
833
  if ((tr_tool->grid_coords != NULL) &&
Nate Summers's avatar
Nate Summers committed
834 835
      (tr_tool->tgrid_coords != NULL) /* FIXME!!! this doesn't belong here &&
      ((tool->type != PERSPECTIVE)  ||
Nate Summers's avatar
Nate Summers committed
836
       ((tr_tool->transform[0][0] >=0.0) &&
Nate Summers's avatar
Nate Summers committed
837
	(tr_tool->transform[1][1] >=0.0)) */ ) 
Nate Summers's avatar
Nate Summers committed
838 839
    {
      gci = 0;
Nate Summers's avatar
Nate Summers committed
840
      k = tr_tool->ngx + tr_tool->ngy;
841

Nate Summers's avatar
Nate Summers committed
842 843
      for (i = 0; i < k; i++)
	{
Nate Summers's avatar
Nate Summers committed
844 845
	  gdisplay_transform_coords (gdisp, tr_tool->tgrid_coords[gci],
				     tr_tool->tgrid_coords[gci+1],
Nate Summers's avatar
Nate Summers committed
846
				     &xa, &ya, FALSE);
Nate Summers's avatar
Nate Summers committed
847 848
	  gdisplay_transform_coords (gdisp, tr_tool->tgrid_coords[gci+2],
				     tr_tool->tgrid_coords[gci+3],
Nate Summers's avatar
Nate Summers committed
849 850
				     &xb, &yb, FALSE);

Nate Summers's avatar
Nate Summers committed
851
	  gdk_draw_line (dr_tool->win, dr_tool->gc,
Nate Summers's avatar
Nate Summers committed
852 853 854 855 856 857
			 xa, ya, xb, yb);
	  gci += 4;
	}
    }

  /*  draw the tool handles  */
Nate Summers's avatar
Nate Summers committed
858
  gdk_draw_rectangle (dr_tool->win, dr_tool->gc, 0,
Nate Summers's avatar
Nate Summers committed
859
		      x1 - (srw >> 1), y1 - (srh >> 1), srw, srh);
Nate Summers's avatar
Nate Summers committed
860
  gdk_draw_rectangle (dr_tool->win, dr_tool->gc, 0,
Nate Summers's avatar
Nate Summers committed
861
		      x2 - (srw >> 1), y2 - (srh >> 1), srw, srh);
Nate Summers's avatar
Nate Summers committed
862
  gdk_draw_rectangle (dr_tool->win, dr_tool->gc, 0,
Nate Summers's avatar
Nate Summers committed
863
		      x3 - (srw >> 1), y3 - (srh >> 1), srw, srh);
Nate Summers's avatar
Nate Summers committed
864
  gdk_draw_rectangle (dr_tool->win, dr_tool->gc, 0,
Nate Summers's avatar
Nate Summers committed
865 866 867
		      x4 - (srw >> 1), y4 - (srh >> 1), srw, srh);

  /*  draw the center  */
868 869 870
  gdisplay_transform_coords (gdisp,
			     tr_tool->tcx, tr_tool->tcy,
			     &tr_tool->scx, &tr_tool->scy, FALSE);
Nate Summers's avatar
Nate Summers committed
871

872 873 874 875 876 877
  gdk_draw_arc (dr_tool->win,
		dr_tool->gc,
		1,
		tr_tool->scx - (srw >> 1),
		tr_tool->scy - (srh >> 1),
		srw, srh, 0, 23040);
Nate Summers's avatar
Nate Summers committed
878

879
  if (gimp_transform_tool_showpath ())
Nate Summers's avatar
Nate Summers committed
880 881 882
    {
      GimpMatrix3 tmp_matrix;

883
      if (gimp_transform_tool_direction () == TRANSFORM_CORRECTIVE)
Nate Summers's avatar
Nate Summers committed
884
	{
Nate Summers's avatar
Nate Summers committed
885
	  gimp_matrix3_invert (tr_tool->transform, tmp_matrix);
Nate Summers's avatar
Nate Summers committed
886 887 888
	}
      else
	{
Nate Summers's avatar
Nate Summers committed
889
	  gimp_matrix3_duplicate (tr_tool->transform, tmp_matrix);
Nate Summers's avatar
Nate Summers committed
890 891
	}

Nate Summers's avatar
Nate Summers committed
892
      path_transform_draw_current (gdisp, dr_tool, tmp_matrix);
Nate Summers's avatar
Nate Summers committed
893 894 895 896
    }
}

void
Nate Summers's avatar
Nate Summers committed
897
gimp_transform_tool_transform_bounding_box (GimpTransformTool *tr_tool)
Nate Summers's avatar
Nate Summers committed
898
{
Nate Summers's avatar
Nate Summers committed
899 900 901 902
  GimpTool  *tool;
  gint       i, k;
  gint       gci;

903
  tool = GIMP_TOOL (tr_tool);
Nate Summers's avatar
Nate Summers committed
904 905 906 907 908 909 910 911 912 913 914 915 916

  gimp_matrix3_transform_point (tr_tool->transform,
				tr_tool->x1, tr_tool->y1,
				&tr_tool->tx1, &tr_tool->ty1);
  gimp_matrix3_transform_point (tr_tool->transform,
				tr_tool->x2, tr_tool->y1,
				&tr_tool->tx2, &tr_tool->ty2);
  gimp_matrix3_transform_point (tr_tool->transform,
				tr_tool->x1, tr_tool->y2,
				&tr_tool->tx3, &tr_tool->ty3);
  gimp_matrix3_transform_point (tr_tool->transform,
				tr_tool->x2, tr_tool->y2,
				&tr_tool->tx4, &tr_tool->ty4);
Nate Summers's avatar
Nate Summers committed
917

918 919 920
  gimp_matrix3_transform_point (tr_tool->transform,
				tr_tool->cx, tr_tool->cy,
				&tr_tool->tcx, &tr_tool->tcy);
Nate Summers's avatar
Nate Summers committed
921

Nate Summers's avatar
Nate Summers committed
922 923
  if (tr_tool->grid_coords != NULL &&
      tr_tool->tgrid_coords != NULL)
Nate Summers's avatar
Nate Summers committed
924 925
    {
      gci = 0;
Nate Summers's avatar
Nate Summers committed
926
      k  = (tr_tool->ngx + tr_tool->ngy) * 2;
927

Nate Summers's avatar
Nate Summers committed
928 929
      for (i = 0; i < k; i++)
	{
Nate Summers's avatar
Nate Summers committed
930 931 932 933 934
	  gimp_matrix3_transform_point (tr_tool->transform,
					tr_tool->grid_coords[gci],
					tr_tool->grid_coords[gci+1],
					&(tr_tool->tgrid_coords[gci]),
					&(tr_tool->tgrid_coords[gci+1]));
Nate Summers's avatar
Nate Summers committed
935 936 937 938 939 940
	  gci += 2;
	}
    }
}

void
941 942
gimp_transform_tool_reset (GimpTransformTool *tr_tool,
		           GDisplay          *gdisp)
Nate Summers's avatar
Nate Summers committed
943
{
Nate Summers's avatar
Nate Summers committed
944
  GimpTool *tool;
Nate Summers's avatar
Nate Summers committed
945

946
  tool = GIMP_TOOL (tr_tool);
Nate Summers's avatar
Nate Summers committed
947

Nate Summers's avatar
Nate Summers committed
948
  if (tr_tool->original)
949 950 951 952
    {
      tile_manager_destroy (tr_tool->original);
      tr_tool->original = NULL;
    }
Nate Summers's avatar
Nate Summers committed
953 954

  /*  inactivate the tool  */
Nate Summers's avatar
Nate Summers committed
955
  tr_tool->function = TRANSFORM_CREATING;
956
  gimp_draw_tool_stop (GIMP_DRAW_TOOL (tr_tool));
Nate Summers's avatar
Nate Summers committed
957 958 959 960 961 962 963 964
  info_dialog_popdown (transform_info);

  tool->state    = INACTIVE;
  tool->gdisp    = NULL;
  tool->drawable = NULL;
}

static void
965 966
gimp_transform_tool_bounds (GimpTransformTool *tr_tool,
		            GDisplay          *gdisp)
Nate Summers's avatar
Nate Summers committed
967 968 969 970 971
{
  TileManager   *tiles;
  GimpDrawable  *drawable;
  gint           offset_x, offset_y;

972 973
  tiles    = tr_tool->original;
  drawable = gimp_image_active_drawable (gdisp->gimage);
Nate Summers's avatar
Nate Summers committed
974 975 976 977 978

  /*  find the boundaries  */
  if (tiles)
    {
      tile_manager_get_offsets (tiles,
Nate Summers's avatar
Nate Summers committed
979 980 981 982
				&tr_tool->x1, &tr_tool->y1);
				
      tr_tool->x2 = tr_tool->x1 + tile_manager_width (tiles);
      tr_tool->y2 = tr_tool->y1 + tile_manager_height (tiles);
Nate Summers's avatar
Nate Summers committed
983 984 985 986 987
    }
  else
    {
      gimp_drawable_offsets (drawable, &offset_x, &offset_y);
      gimp_drawable_mask_bounds (drawable,
Nate Summers's avatar
Nate Summers committed
988 989 990 991 992 993
				 &tr_tool->x1, &tr_tool->y1,
				 &tr_tool->x2, &tr_tool->y2);
      tr_tool->x1 += offset_x;
      tr_tool->y1 += offset_y;
      tr_tool->x2 += offset_x;
      tr_tool->y2 += offset_y;
Nate Summers's avatar
Nate Summers committed
994
    }
Nate Summers's avatar
Nate Summers committed
995 996 997

  tr_tool->cx = (tr_tool->x1 + tr_tool->x2) / 2;
  tr_tool->cy = (tr_tool->y1 + tr_tool->y2) / 2;
Nate Summers's avatar
Nate Summers committed
998 999

  /*  changing the bounds invalidates any grid we may have  */
Nate Summers's avatar
Nate Summers committed
1000
  gimp_transform_tool_grid_recalc (tr_tool);
Nate Summers's avatar
Nate Summers committed
1001 1002 1003 1004 1005
}

void
gimp_transform_tool_grid_density_changed (void)
{
Nate Summers's avatar
Nate Summers committed
1006 1007
  GimpTransformTool *tr_tool;
  GimpDrawTool      *dr_tool;
Nate Summers's avatar
Nate Summers committed
1008

1009 1010 1011
  /* EEEK!!! */ 
  tr_tool = GIMP_TRANSFORM_TOOL (tool_manager_get_active (the_gimp));

1012
  dr_tool = GIMP_DRAW_TOOL (tr_tool);
Nate Summers's avatar
Nate Summers committed
1013

Nate Summers's avatar
Nate Summers committed
1014
  if (tr_tool->function == TRANSFORM_CREATING)
Nate Summers's avatar
Nate Summers committed
1015 1016
    return;

Nate Summers's avatar
Nate Summers committed
1017
  gimp_draw_tool_pause (dr_tool);
1018

Nate Summers's avatar
Nate Summers committed
1019 1020
  gimp_transform_tool_grid_recalc (tr_tool);
  gimp_transform_tool_transform_bounding_box (tr_tool);
1021

Nate Summers's avatar
Nate Summers committed
1022
  gimp_draw_tool_resume (dr_tool);
Nate Summers's avatar
Nate Summers committed
1023 1024 1025
}

void
Nate Summers's avatar
Nate Summers committed
1026
gimp_transform_tool_showpath_changed (gint type /* a truly undescriptive name */)
Nate Summers's avatar
Nate Summers committed
1027
{
Nate Summers's avatar
Nate Summers committed
1028
  GimpTransformTool *tr_tool;
Nate Summers's avatar
Nate Summers committed
1029

1030 1031
  /* EEEEEEEK!!! */ 
  tr_tool = GIMP_TRANSFORM_TOOL (tool_manager_get_active (the_gimp));
Nate Summers's avatar
Nate Summers committed
1032

Nate Summers's avatar
Nate Summers committed
1033
  if (tr_tool->function == TRANSFORM_CREATING)
Nate Summers's avatar
Nate Summers committed
1034 1035 1036
    return;

  if (type)
1037
    gimp_draw_tool_pause (GIMP_DRAW_TOOL (tr_tool));
Nate Summers's avatar
Nate Summers committed
1038
  else
1039
    gimp_draw_tool_resume (GIMP_DRAW_TOOL (tr_tool));
Nate Summers's avatar
Nate Summers committed
1040 1041 1042
}

static void
Nate Summers's avatar
Nate Summers committed
1043
gimp_transform_tool_grid_recalc (GimpTransformTool *tr_tool)
Nate Summers's avatar
Nate Summers committed
1044
{
Nate Summers's avatar
Nate Summers committed
1045
  if (tr_tool->grid_coords != NULL)
Nate Summers's avatar
Nate Summers committed
1046
    {
Nate Summers's avatar
Nate Summers committed
1047 1048
      g_free (tr_tool->grid_coords);
      tr_tool->grid_coords = NULL;
Nate Summers's avatar
Nate Summers committed
1049
    }
1050

Nate Summers's avatar
Nate Summers committed
1051
  if (tr_tool->tgrid_coords != NULL)
Nate Summers's avatar
Nate Summers committed
1052
    {
Nate Summers's avatar
Nate Summers committed
1053 1054
      g_free (tr_tool->tgrid_coords);
      tr_tool->tgrid_coords = NULL;
Nate Summers's avatar
Nate Summers committed
1055
    }
Michael Natterer's avatar