gimptransformtool.c 46.6 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 111 112
static void    gimp_transform_tool_destroy     (GtkObject              *object);

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 139 140
static TranInfo           old_trans_info;
InfoDialog               *transform_info        = NULL;
static gboolean           transform_info_inited = FALSE;
static GimpDrawToolClass *parent_class          = NULL;
static guint gimp_transform_tool_signals[LAST_SIGNAL] = { 0 };
Nate Summers's avatar
Nate Summers committed
141

142

Nate Summers's avatar
Nate Summers committed
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
GtkType
gimp_transform_tool_get_type (void)
{
  static GtkType tool_type = 0;

  if (! tool_type)
    {
      GtkTypeInfo tool_info =
      {
        "GimpTransformTool",
        sizeof (GimpTransformTool),
        sizeof (GimpTransformToolClass),
        (GtkClassInitFunc) gimp_transform_tool_class_init,
        (GtkObjectInitFunc) gimp_transform_tool_init,
        /* reserved_1 */ NULL,
        /* reserved_2 */ NULL,
        NULL /* (GtkClassInitFunc) gimp_tool_class_init, */
      };

      tool_type = gtk_type_unique (GIMP_TYPE_DRAW_TOOL, &tool_info);
    }

  return tool_type;
}

static void
gimp_transform_tool_class_init (GimpTransformToolClass *klass)
{
Nate Summers's avatar
Nate Summers committed
171 172 173
  GtkObjectClass    *object_class;
  GimpToolClass     *tool_class;
  GimpDrawToolClass *draw_class;
Nate Summers's avatar
Nate Summers committed
174 175 176

  object_class = (GtkObjectClass *) klass;
  tool_class   = (GimpToolClass *) klass;
Nate Summers's avatar
Nate Summers committed
177
  draw_class   = (GimpDrawToolClass *) klass;
Nate Summers's avatar
Nate Summers committed
178 179 180 181 182

  parent_class = gtk_type_class (GIMP_TYPE_DRAW_TOOL);

  gimp_transform_tool_signals[TRANSFORM] =
    gtk_signal_new ("transform",
Nate Summers's avatar
Nate Summers committed
183
    		    GTK_RUN_LAST,
Nate Summers's avatar
Nate Summers committed
184 185 186
    		    object_class->type,
    		    GTK_SIGNAL_OFFSET (GimpTransformToolClass,
    		    		       transform),
Nate Summers's avatar
Nate Summers committed
187
    		    gimp_marshal_POINTER__POINTER_INT,
Nate Summers's avatar
Nate Summers committed
188 189 190 191 192 193 194
    		    GTK_TYPE_POINTER, 2,
    		    GTK_TYPE_POINTER,
    		    GTK_TYPE_INT);

  gtk_object_class_add_signals (object_class, gimp_transform_tool_signals,
				LAST_SIGNAL);

Nate Summers's avatar
Nate Summers committed
195
  object_class->destroy      = gimp_transform_tool_destroy;
Nate Summers's avatar
Nate Summers committed
196 197 198 199 200 201

  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
202 203

  draw_class->draw           = gimp_transform_tool_draw;
Nate Summers's avatar
Nate Summers committed
204 205 206
}

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

  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;

222 223 224
  /* FIXME */
  tr_tool->interactive = TRUE;

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

Nate Summers's avatar
Nate Summers committed
228 229
}

Nate Summers's avatar
Nate Summers committed
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
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);

  gtk_signal_emit (GTK_OBJECT (tool), gimp_transform_tool_signals[TRANSFORM],
                   gdisp, state, &retval);

  return retval;
}

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

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

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

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

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

  /*  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
275
  gimp_transform_tool_recalc (tool, GIMP_TOOL(tool)->gdisp);
Nate Summers's avatar
Nate Summers committed
276 277

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

281 282
static void
gimp_transform_tool_destroy (GtkObject *object)
Nate Summers's avatar
Nate Summers committed
283
{
284 285
  GimpTransformTool *tr_tool;
  GimpTool          *tool;
Nate Summers's avatar
Nate Summers committed
286

287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
  tr_tool = GIMP_TRANSFORM_TOOL (object);
  tool    = GIMP_TOOL           (tr_tool);

  /*  Free up the original selection if it exists  */
  if (tr_tool->original)
    tile_manager_destroy (tr_tool->original);

  /*  If there is an information dialog, free it up  */
  if (transform_info)
    info_dialog_free (transform_info);

  transform_info        = NULL;
  transform_info_inited = FALSE;

  /*  Free the grid line endpoint arrays if they exist */
  if (tr_tool->grid_coords != NULL)
    g_free (tr_tool->grid_coords);

  if (tr_tool->tgrid_coords != NULL)
    g_free (tr_tool->tgrid_coords);

  if (GTK_OBJECT_CLASS (parent_class)->destroy)
    GTK_OBJECT_CLASS (parent_class)->destroy (object);
}

static void
Nate Summers's avatar
Nate Summers committed
313
gimp_transform_tool_button_press (GimpTool           *tool,
Nate Summers's avatar
Nate Summers committed
314 315 316
                                  GdkEventButton     *bevent,
			          GDisplay           *gdisp)
{
Nate Summers's avatar
Nate Summers committed
317 318 319 320 321 322 323
  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
324

325
  gt_tool = GIMP_TRANSFORM_TOOL (tool);
Nate Summers's avatar
Nate Summers committed
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344

  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...  */
345 346
      gimp_draw_tool_start (GIMP_DRAW_TOOL (gt_tool), gdisp->canvas->window);

Nate Summers's avatar
Nate Summers committed
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
      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;
	}

374 375
      if ((SQR (x - gt_tool->scx) +
	   SQR (y - gt_tool->scy)) <= 100)
Nate Summers's avatar
Nate Summers committed
376 377 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
	{
	  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)))
408 409 410 411 412 413 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 446 447 448 449 450 451 452 453 454 455 456 457
    {
      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)
	    {
	      GtkType tool_type;

	      tool_type =
Michael Natterer's avatar
Michael Natterer committed
458
		gimp_context_get_tool (gimp_get_user_context (gdisp->gimage->gimp))->tool_type;
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

	      gimp_dialog_create_action_area
		(GTK_DIALOG (transform_info->shell),

		 /* 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
488 489
}

490
static void
Nate Summers's avatar
Nate Summers committed
491 492 493
gimp_transform_tool_button_release (GimpTool         *tool,
			            GdkEventButton   *bevent,
			            GDisplay         *gdisp)
Nate Summers's avatar
Nate Summers committed
494
{
Nate Summers's avatar
Nate Summers committed
495 496
  GimpTransformTool *gt_tool;
  gint               i;
Nate Summers's avatar
Nate Summers committed
497

498
  gt_tool = GIMP_TRANSFORM_TOOL (tool);
Nate Summers's avatar
Nate Summers committed
499 500 501 502

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

  /*  if we are creating, there is nothing to be done...exit  */
503
  if (gt_tool->function == TRANSFORM_CREATING && gt_tool->interactive)
Nate Summers's avatar
Nate Summers committed
504 505 506 507 508 509 510 511 512 513
    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  */
514
      if ((bevent->state & GDK_SHIFT_MASK) || GIMP_IS_FLIP_TOOL (tool))
Nate Summers's avatar
Nate Summers committed
515
	{
Nate Summers's avatar
Nate Summers committed
516
	  gimp_transform_tool_doit (gt_tool, gdisp);
Nate Summers's avatar
Nate Summers committed
517 518 519 520 521 522 523 524 525 526 527
	}
      else
	{
	  /*  Only update the paths preview */
	  path_transform_current_path (gdisp->gimage,
				       gt_tool->transform, TRUE);
	}
    }
  else
    {
      /*  stop the current tool drawing process  */
528
      gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
Nate Summers's avatar
Nate Summers committed
529 530 531 532 533 534 535 536 537

      /*  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  */
538
      gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
Nate Summers's avatar
Nate Summers committed
539 540 541 542 543 544 545 546 547 548 549

      /* 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;
}

550
static void
Nate Summers's avatar
Nate Summers committed
551 552 553 554 555 556 557 558 559 560
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;

561
  gimp_set_busy (gdisp->gimage->gimp);
Nate Summers's avatar
Nate Summers committed
562

563
  tool = GIMP_TOOL (gt_tool);
Nate Summers's avatar
Nate Summers committed
564 565

  /* undraw the tool before we muck around with the transform matrix */
566
  gimp_draw_tool_pause (GIMP_DRAW_TOOL (gt_tool));
Nate Summers's avatar
Nate Summers committed
567 568 569 570 571 572 573 574 575

  /*  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);

576 577 578
  /* 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
579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594
  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
595
  new_tiles = gimp_transform_tool_transform (gt_tool, gdisp,
596
					     TRANSFORM_FINISH);
Nate Summers's avatar
Nate Summers committed
597

Nate Summers's avatar
Nate Summers committed
598
  gimp_transform_tool_transform (gt_tool, gdisp, TRANSFORM_INIT);
Nate Summers's avatar
Nate Summers committed
599 600 601 602 603 604 605 606 607 608

  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,
609
				 new_tiles, new_layer);
Nate Summers's avatar
Nate Summers committed
610 611

      /*  create and initialize the transform_undo structure  */
612 613 614
      tu = g_new0 (TransformUndo, 1);
      tu->tool_ID   = tool->ID;
      tu->tool_type = GTK_OBJECT (tool)->klass->type;
Nate Summers's avatar
Nate Summers committed
615

Nate Summers's avatar
Nate Summers committed
616 617
      for (i = 0; i < TRAN_INFO_SIZE; i++)
	tu->trans_info[i] = old_trans_info[i];
618 619

      tu->original  = NULL;
Nate Summers's avatar
Nate Summers committed
620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657
      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)
    {
      gdk_window_get_size (gdisp->canvas->window, &x, &y);
      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);
	}
    }

658
  gimp_unset_busy (gdisp->gimage->gimp);
Nate Summers's avatar
Nate Summers committed
659 660 661

  gdisplays_flush ();

662
  gimp_transform_tool_reset (gt_tool, gdisp);
Nate Summers's avatar
Nate Summers committed
663 664

  /*  if this tool is non-interactive, make it inactive after use  */
Nate Summers's avatar
Nate Summers committed
665
  if (!gt_tool->interactive)
Nate Summers's avatar
Nate Summers committed
666 667 668
    tool->state = INACTIVE;
}

669
static void
Nate Summers's avatar
Nate Summers committed
670 671 672
gimp_transform_tool_motion (GimpTool          *tool,
		            GdkEventMotion    *mevent,
		            GDisplay          *gdisp)
Nate Summers's avatar
Nate Summers committed
673
{
Nate Summers's avatar
Nate Summers committed
674
  GimpTransformTool *tr_tool;
Nate Summers's avatar
Nate Summers committed
675

676
  tr_tool = GIMP_TRANSFORM_TOOL (tool);
Nate Summers's avatar
Nate Summers committed
677

678
  if (! tr_tool->bpressed)
Nate Summers's avatar
Nate Summers committed
679 680 681 682 683
    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
684 685
  if (tr_tool->function == TRANSFORM_CREATING ||
      !tr_tool->interactive)
Nate Summers's avatar
Nate Summers committed
686 687 688
    return;

  /*  stop the current tool drawing process  */
689
  gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
Nate Summers's avatar
Nate Summers committed
690 691

  gdisplay_untransform_coords (gdisp, mevent->x, mevent->y,
Nate Summers's avatar
Nate Summers committed
692 693 694
			       &tr_tool->curx,
			       &tr_tool->cury, TRUE, 0);
  tr_tool->state = mevent->state;
Nate Summers's avatar
Nate Summers committed
695 696

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

Nate Summers's avatar
Nate Summers committed
699 700
  tr_tool->lastx = tr_tool->curx;
  tr_tool->lasty = tr_tool->cury;
Nate Summers's avatar
Nate Summers committed
701 702

  /*  resume drawing the current tool  */
703
  gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
Nate Summers's avatar
Nate Summers committed
704 705
}

706
static void
Nate Summers's avatar
Nate Summers committed
707
gimp_transform_tool_cursor_update (GimpTool           *tool,
Nate Summers's avatar
Nate Summers committed
708 709
			           GdkEventMotion     *mevent,
			           GDisplay           *gdisp)
Nate Summers's avatar
Nate Summers committed
710
{
Nate Summers's avatar
Nate Summers committed
711 712 713 714
  GimpTransformTool  *tr_tool;
  GimpDrawable       *drawable;
  GdkCursorType       ctype = GDK_TOP_LEFT_ARROW;
  gint                x, y;
Nate Summers's avatar
Nate Summers committed
715

716
  tr_tool = GIMP_TRANSFORM_TOOL (tool);
Nate Summers's avatar
Nate Summers committed
717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746

  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);
}

747 748 749 750
static void
gimp_transform_tool_control (GimpTool   *tool,
			     ToolAction  action,
			     GDisplay   *gdisp)
Nate Summers's avatar
Nate Summers committed
751
{
752 753
  GimpDrawTool      *dr_tool;
  GimpTransformTool *tr_tool;
Nate Summers's avatar
Nate Summers committed
754

755 756
  dr_tool = GIMP_DRAW_TOOL (tool);
  tr_tool = GIMP_TRANSFORM_TOOL (tool);
Nate Summers's avatar
Nate Summers committed
757 758 759 760 761 762 763

  switch (action)
    {
    case PAUSE:
      break;

    case RESUME:
Nate Summers's avatar
Nate Summers committed
764
      gimp_transform_tool_recalc (tr_tool, gdisp);
Nate Summers's avatar
Nate Summers committed
765 766 767
      break;

    case HALT:
Nate Summers's avatar
Nate Summers committed
768
      gimp_transform_tool_reset (tr_tool, gdisp);
Nate Summers's avatar
Nate Summers committed
769 770 771 772 773 774
      break;

    default:
      break;
    }

775 776
  if (GIMP_TOOL_CLASS (parent_class)->control)
    GIMP_TOOL_CLASS (parent_class)->control (tool, action, gdisp);
Nate Summers's avatar
Nate Summers committed
777 778
}

779
static void
Nate Summers's avatar
Nate Summers committed
780
gimp_transform_tool_draw (GimpDrawTool *dr_tool)
Nate Summers's avatar
Nate Summers committed
781
{
Nate Summers's avatar
Nate Summers committed
782 783 784 785 786 787 788 789
  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;

790 791
  tr_tool = GIMP_TRANSFORM_TOOL (dr_tool);
  tool    = GIMP_TOOL (dr_tool);
Nate Summers's avatar
Nate Summers committed
792

793
  gdisp   = tool->gdisp;
Nate Summers's avatar
Nate Summers committed
794 795 796 797 798 799 800 801 802 803 804 805 806 807

  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
808 809 810 811 812 813

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

  /*  draw the bounding box  */
Nate Summers's avatar
Nate Summers committed
814
  gdk_draw_line (dr_tool->win, dr_tool->gc,
Nate Summers's avatar
Nate Summers committed
815
		 x1, y1, x2, y2);
Nate Summers's avatar
Nate Summers committed
816
  gdk_draw_line (dr_tool->win, dr_tool->gc,
Nate Summers's avatar
Nate Summers committed
817
		 x2, y2, x4, y4);
Nate Summers's avatar
Nate Summers committed
818
  gdk_draw_line (dr_tool->win, dr_tool->gc,
Nate Summers's avatar
Nate Summers committed
819
		 x3, y3, x4, y4);
Nate Summers's avatar
Nate Summers committed
820
  gdk_draw_line (dr_tool->win, dr_tool->gc,
Nate Summers's avatar
Nate Summers committed
821 822 823 824
		 x3, y3, x1, y1);

  /*  Draw the grid */

Nate Summers's avatar
Nate Summers committed
825
  if ((tr_tool->grid_coords != NULL) &&
Nate Summers's avatar
Nate Summers committed
826 827
      (tr_tool->tgrid_coords != NULL) /* FIXME!!! this doesn't belong here &&
      ((tool->type != PERSPECTIVE)  ||
Nate Summers's avatar
Nate Summers committed
828
       ((tr_tool->transform[0][0] >=0.0) &&
Nate Summers's avatar
Nate Summers committed
829
	(tr_tool->transform[1][1] >=0.0)) */ ) 
Nate Summers's avatar
Nate Summers committed
830 831
    {
      gci = 0;
Nate Summers's avatar
Nate Summers committed
832
      k = tr_tool->ngx + tr_tool->ngy;
833

Nate Summers's avatar
Nate Summers committed
834 835
      for (i = 0; i < k; i++)
	{
Nate Summers's avatar
Nate Summers committed
836 837
	  gdisplay_transform_coords (gdisp, tr_tool->tgrid_coords[gci],
				     tr_tool->tgrid_coords[gci+1],
Nate Summers's avatar
Nate Summers committed
838
				     &xa, &ya, FALSE);
Nate Summers's avatar
Nate Summers committed
839 840
	  gdisplay_transform_coords (gdisp, tr_tool->tgrid_coords[gci+2],
				     tr_tool->tgrid_coords[gci+3],
Nate Summers's avatar
Nate Summers committed
841 842
				     &xb, &yb, FALSE);

Nate Summers's avatar
Nate Summers committed
843
	  gdk_draw_line (dr_tool->win, dr_tool->gc,
Nate Summers's avatar
Nate Summers committed
844 845 846 847 848 849
			 xa, ya, xb, yb);
	  gci += 4;
	}
    }

  /*  draw the tool handles  */
Nate Summers's avatar
Nate Summers committed
850
  gdk_draw_rectangle (dr_tool->win, dr_tool->gc, 0,
Nate Summers's avatar
Nate Summers committed
851
		      x1 - (srw >> 1), y1 - (srh >> 1), srw, srh);
Nate Summers's avatar
Nate Summers committed
852
  gdk_draw_rectangle (dr_tool->win, dr_tool->gc, 0,
Nate Summers's avatar
Nate Summers committed
853
		      x2 - (srw >> 1), y2 - (srh >> 1), srw, srh);
Nate Summers's avatar
Nate Summers committed
854
  gdk_draw_rectangle (dr_tool->win, dr_tool->gc, 0,
Nate Summers's avatar
Nate Summers committed
855
		      x3 - (srw >> 1), y3 - (srh >> 1), srw, srh);
Nate Summers's avatar
Nate Summers committed
856
  gdk_draw_rectangle (dr_tool->win, dr_tool->gc, 0,
Nate Summers's avatar
Nate Summers committed
857 858 859
		      x4 - (srw >> 1), y4 - (srh >> 1), srw, srh);

  /*  draw the center  */
860 861 862
  gdisplay_transform_coords (gdisp,
			     tr_tool->tcx, tr_tool->tcy,
			     &tr_tool->scx, &tr_tool->scy, FALSE);
Nate Summers's avatar
Nate Summers committed
863

864 865 866 867 868 869
  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
870

871
  if (gimp_transform_tool_showpath ())
Nate Summers's avatar
Nate Summers committed
872 873 874
    {
      GimpMatrix3 tmp_matrix;

875
      if (gimp_transform_tool_direction () == TRANSFORM_CORRECTIVE)
Nate Summers's avatar
Nate Summers committed
876
	{
Nate Summers's avatar
Nate Summers committed
877
	  gimp_matrix3_invert (tr_tool->transform, tmp_matrix);
Nate Summers's avatar
Nate Summers committed
878 879 880
	}
      else
	{
Nate Summers's avatar
Nate Summers committed
881
	  gimp_matrix3_duplicate (tr_tool->transform, tmp_matrix);
Nate Summers's avatar
Nate Summers committed
882 883
	}

Nate Summers's avatar
Nate Summers committed
884
      path_transform_draw_current (gdisp, dr_tool, tmp_matrix);
Nate Summers's avatar
Nate Summers committed
885 886 887 888
    }
}

void
Nate Summers's avatar
Nate Summers committed
889
gimp_transform_tool_transform_bounding_box (GimpTransformTool *tr_tool)
Nate Summers's avatar
Nate Summers committed
890
{
Nate Summers's avatar
Nate Summers committed
891 892 893 894
  GimpTool  *tool;
  gint       i, k;
  gint       gci;

895
  tool = GIMP_TOOL (tr_tool);
Nate Summers's avatar
Nate Summers committed
896 897 898 899 900 901 902 903 904 905 906 907 908

  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
909

910 911 912
  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
913

Nate Summers's avatar
Nate Summers committed
914 915
  if (tr_tool->grid_coords != NULL &&
      tr_tool->tgrid_coords != NULL)
Nate Summers's avatar
Nate Summers committed
916 917
    {
      gci = 0;
Nate Summers's avatar
Nate Summers committed
918
      k  = (tr_tool->ngx + tr_tool->ngy) * 2;
919

Nate Summers's avatar
Nate Summers committed
920 921
      for (i = 0; i < k; i++)
	{
Nate Summers's avatar
Nate Summers committed
922 923 924 925 926
	  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
927 928 929 930 931 932
	  gci += 2;
	}
    }
}

void
933 934
gimp_transform_tool_reset (GimpTransformTool *tr_tool,
		           GDisplay          *gdisp)
Nate Summers's avatar
Nate Summers committed
935
{
Nate Summers's avatar
Nate Summers committed
936
  GimpTool *tool;
Nate Summers's avatar
Nate Summers committed
937

938
  tool = GIMP_TOOL (tr_tool);
Nate Summers's avatar
Nate Summers committed
939

Nate Summers's avatar
Nate Summers committed
940
  if (tr_tool->original)
941 942 943 944
    {
      tile_manager_destroy (tr_tool->original);
      tr_tool->original = NULL;
    }
Nate Summers's avatar
Nate Summers committed
945 946

  /*  inactivate the tool  */
Nate Summers's avatar
Nate Summers committed
947
  tr_tool->function = TRANSFORM_CREATING;
948
  gimp_draw_tool_stop (GIMP_DRAW_TOOL (tr_tool));
Nate Summers's avatar
Nate Summers committed
949 950 951 952 953 954 955 956
  info_dialog_popdown (transform_info);

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

static void
957 958
gimp_transform_tool_bounds (GimpTransformTool *tr_tool,
		            GDisplay          *gdisp)
Nate Summers's avatar
Nate Summers committed
959 960 961 962 963
{
  TileManager   *tiles;
  GimpDrawable  *drawable;
  gint           offset_x, offset_y;

964 965
  tiles    = tr_tool->original;
  drawable = gimp_image_active_drawable (gdisp->gimage);
Nate Summers's avatar
Nate Summers committed
966 967 968 969 970

  /*  find the boundaries  */
  if (tiles)
    {
      tile_manager_get_offsets (tiles,
Nate Summers's avatar
Nate Summers committed
971 972 973 974
				&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
975 976 977 978 979
    }
  else
    {
      gimp_drawable_offsets (drawable, &offset_x, &offset_y);
      gimp_drawable_mask_bounds (drawable,
Nate Summers's avatar
Nate Summers committed
980 981 982 983 984 985
				 &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
986
    }
Nate Summers's avatar
Nate Summers committed
987 988 989

  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
990 991

  /*  changing the bounds invalidates any grid we may have  */
Nate Summers's avatar
Nate Summers committed
992
  gimp_transform_tool_grid_recalc (tr_tool);
Nate Summers's avatar
Nate Summers committed
993 994 995 996 997
}

void
gimp_transform_tool_grid_density_changed (void)
{
Nate Summers's avatar
Nate Summers committed
998 999
  GimpTransformTool *tr_tool;
  GimpDrawTool      *dr_tool;
Nate Summers's avatar
Nate Summers committed
1000

1001 1002 1003
  /* EEEK!!! */ 
  tr_tool = GIMP_TRANSFORM_TOOL (tool_manager_get_active (the_gimp));

1004
  dr_tool = GIMP_DRAW_TOOL (tr_tool);
Nate Summers's avatar
Nate Summers committed
1005

Nate Summers's avatar
Nate Summers committed
1006
  if (tr_tool->function == TRANSFORM_CREATING)
Nate Summers's avatar
Nate Summers committed
1007 1008
    return;

Nate Summers's avatar
Nate Summers committed
1009
  gimp_draw_tool_pause (dr_tool);
1010

Nate Summers's avatar
Nate Summers committed
1011 1012
  gimp_transform_tool_grid_recalc (tr_tool);
  gimp_transform_tool_transform_bounding_box (tr_tool);
1013

Nate Summers's avatar
Nate Summers committed
1014
  gimp_draw_tool_resume (dr_tool);
Nate Summers's avatar
Nate Summers committed
1015 1016 1017
}

void
Nate Summers's avatar
Nate Summers committed
1018
gimp_transform_tool_showpath_changed (gint type /* a truly undescriptive name */)
Nate Summers's avatar
Nate Summers committed
1019
{
Nate Summers's avatar
Nate Summers committed
1020
  GimpTransformTool *tr_tool;
Nate Summers's avatar
Nate Summers committed
1021

1022 1023
  /* EEEEEEEK!!! */ 
  tr_tool = GIMP_TRANSFORM_TOOL (tool_manager_get_active (the_gimp));
Nate Summers's avatar
Nate Summers committed
1024

Nate Summers's avatar
Nate Summers committed
1025
  if (tr_tool->function == TRANSFORM_CREATING)
Nate Summers's avatar
Nate Summers committed
1026 1027 1028
    return;

  if (type)
1029
    gimp_draw_tool_pause (GIMP_DRAW_TOOL (tr_tool));
Nate Summers's avatar
Nate Summers committed
1030
  else
1031
    gimp_draw_tool_resume (GIMP_DRAW_TOOL (tr_tool));
Nate Summers's avatar
Nate Summers committed
1032 1033 1034
}

static void
Nate Summers's avatar
Nate Summers committed
1035
gimp_transform_tool_grid_recalc (GimpTransformTool *tr_tool)
Nate Summers's avatar
Nate Summers committed
1036
{
Nate Summers's avatar
Nate Summers committed
1037
  if (tr_tool->grid_coords != NULL)
Nate Summers's avatar
Nate Summers committed
1038
    {
Nate Summers's avatar
Nate Summers committed
1039 1040
      g_free (tr_tool->grid_coords);
      tr_tool->grid_coords = NULL;
Nate Summers's avatar
Nate Summers committed
1041
    }
1042

Nate Summers's avatar
Nate Summers committed
1043
  if (tr_tool->tgrid_coords != NULL)
Nate Summers's avatar
Nate Summers committed
1044
    {
Nate Summers's avatar
Nate Summers committed
1045 1046
      g_free (tr_tool->tgrid_coords);
      tr_tool->tgrid_coords = NULL;
Nate Summers's avatar
Nate Summers committed
1047
    }
1048

1049
  if (gimp_transform_tool_show_grid ())
1050 1051 1052 1053
    {
      /* EEEEEEK!!! */ 
      gimp_transform_tool_setup_grid (GIMP_TRANSFORM_TOOL (tool_manager_get_active (the_gimp)));
    }
Nate Summers's avatar
Nate Summers committed
1054 1055 1056
}

static void
Nate Summers's avatar
Nate Summers committed
1057
gimp_transform_tool_setup_grid (GimpTransformTool *tr_tool)
Nate Summers's avatar
Nate Summers committed
1058
{
1059 1060 1061
  GimpTool *tool;
  gint      i, gci;
  gdouble  *coords;
Nate Summers's avatar
Nate Summers committed
1062

1063
  tool = GIMP_TOOL (tr_tool);
Nate Summers's avatar
Nate Summers committed
1064

Nate Summers's avatar
Nate Summers committed
1065
  /*  We use the gimp_transform_tool_grid_size function only here, even
Nate Summers's avatar
Nate Summers committed
1066 1067 1068
   *  if the user changes the grid size in the middle of an
   *  operation, nothing happens.
   */
1069
  tr_tool->ngx = (tr_tool->x2 - tr_tool->x1) / gimp_transform_tool_grid_size ();
Nate Summers's avatar
Nate Summers committed
1070 1071
  if (tr_tool->ngx > 0)
    tr_tool->ngx--;
Nate Summers's avatar
Nate Summers committed
1072

1073
  tr_tool->ngy = (tr_tool->y2 - tr_tool->y1) / gimp_transform_tool_grid_size ();
Nate Summers's avatar
Nate Summers committed
1074 1075