Commit 844a3481 authored by Sven Neumann's avatar Sven Neumann

Applied the transform tool UI patch from Tor Lillqvist <tml@iki.fi>.

It still has a few problems, but I guess there are easier to solve, if the
patch is applied.


--Sven
parent fb8a4ebe
Thu Aug 13 22:16:42 MEST 1998 Sven Neumann <sven@gimp.org>
Applied the patch from Tor Lillqvist <tml@iki.fi>:
* app/transform_core.c app/transform_core.h: Further changes in
the look-and-feel. Now we have a info_dialog window for each
transformation tool, with an action and cancel button. The use of
shift-clicking to approve the transform introduced in
gimp-tml-980724-1 is still there. The old immediate transformation
on button release is gone.
For use by the rotate tool we have a center-of-rotation point
which is draggable. Its coordinates are kept in the TransformCore
struct.
As there no longer are several related transformations done after
each other as in the old look-and-feel, we don't need the _first_
field in TransformUndo.
Added the function _transform_core_grid_density_changed_ called
from transform_tool.c when the grid density spinbutton has been
changed. The grid is instantaneously redrawn in the new
density. Neat, huh?
* transform_tool.c transform_tool.h: More options: a toggle to
clip the result of a perspective transform, and a spinbutton for
the rubber-band grid density. The toggle for "new" vs. "old" UI is
now for "corrective" vs. "traditional" paradigm.
* rotate_tool.c: Show also the center point coordinates in the
info dialog. If dragging the center point, update TransformCore
accordingly. Use the center point coordinates from TransformCore
where appropriate.
* perspective_tool.c: Show the transformation matrix in the info
dialog.
* undo.c: TransformUndo no longed has the _first_ field, code
simplified thusly.
Thu Aug 13 20:48:48 MEST 1998 Sven Neumann <sven@gimp.org>
* app/color_area.c: Add event-masks so the tooltip is shown.
......
......@@ -937,21 +937,17 @@ undo_pop_transform (GImage *gimage,
tc->trans_info[i] = d;
}
/* if this is the first transform in a string, swap the
* original buffer--the source buffer for repeated transforms
/* swap the original buffer--the source buffer for repeated transforms
*/
if (tu->first)
{
temp = tu->original;
tu->original = tc->original;
tc->original = temp;
temp = tu->original;
tu->original = tc->original;
tc->original = temp;
/* If we're re-implementing the first transform, reactivate tool */
if (state == REDO && tc->original)
{
active_tool->state = ACTIVE;
draw_core_resume (tc->core, active_tool);
}
/* If we're re-implementing the first transform, reactivate tool */
if (state == REDO && tc->original)
{
active_tool->state = ACTIVE;
draw_core_resume (tc->core, active_tool);
}
return TRUE;
......
......@@ -16,6 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <stdlib.h>
#include <stdio.h>
#include "appenv.h"
#include "drawable.h"
#include "gdisplay.h"
......@@ -40,9 +41,7 @@
#define Y3 7
/* storage for information dialog fields */
char matrix_row1_buf [256];
char matrix_row2_buf [256];
char matrix_row3_buf [256];
static char matrix_row_buf [3][MAX_INFO_BUF];
/* forward function declarations */
static void * perspective_tool_perspective (GImage *, GimpDrawable *, TileManager *, int, Matrix);
......@@ -67,7 +66,16 @@ perspective_tool_transform (tool, gdisp_ptr, state)
switch (state)
{
case INIT :
transform_info = NULL;
if (!transform_info)
{
transform_info = info_dialog_new ("Perspective Transform Information");
info_dialog_add_field (transform_info, "Matrix: ",
matrix_row_buf[0]);
info_dialog_add_field (transform_info, " ",
matrix_row_buf[1]);
info_dialog_add_field (transform_info, " ",
matrix_row_buf[2]);
}
transform_core->trans_info [X0] = (double) transform_core->x1;
transform_core->trans_info [Y0] = (double) transform_core->y1;
......@@ -143,6 +151,25 @@ static void
perspective_info_update (tool)
Tool * tool;
{
TransformCore * transform_core;
int i;
transform_core = (TransformCore *) tool->private;
for (i = 0; i < 3; i++)
{
char *p = matrix_row_buf[i];
int j;
for (j = 0; j < 3; j++)
{
p += sprintf (p, "%10.3g", transform_core->transform[i][j]);
}
}
info_dialog_update (transform_info);
info_dialog_popup (transform_info);
return;
}
......
......@@ -40,11 +40,16 @@
/* index into trans_info array */
#define ANGLE 0
#define REAL_ANGLE 1
#define CENTER_X 2
#define CENTER_Y 3
#define EPSILON 0.018 /* ~ 1 degree */
#define FIFTEEN_DEG (M_PI / 12.0)
/* variables local to this file */
char angle_buf [MAX_INFO_BUF];
static char angle_buf [MAX_INFO_BUF];
static char center_x_buf [MAX_INFO_BUF];
static char center_y_buf [MAX_INFO_BUF];
/* forward function declarations */
static void * rotate_tool_rotate (GImage *, GimpDrawable *, double, TileManager *, int, Matrix);
......@@ -72,10 +77,16 @@ rotate_tool_transform (tool, gdisp_ptr, state)
{
transform_info = info_dialog_new ("Rotation Information");
info_dialog_add_field (transform_info, "Angle: ", angle_buf);
info_dialog_add_field (transform_info, "Center X: ", center_x_buf);
info_dialog_add_field (transform_info, "Center Y: ", center_y_buf);
}
transform_core->trans_info[ANGLE] = 0.0;
transform_core->trans_info[REAL_ANGLE] = 0.0;
transform_core->trans_info[CENTER_X] =
(transform_core->x1 + transform_core->x2) / 2;
transform_core->trans_info[CENTER_Y] =
(transform_core->y1 + transform_core->y2) / 2;
return NULL;
break;
......@@ -114,6 +125,8 @@ tools_new_rotate_tool ()
private->trans_func = rotate_tool_transform;
private->trans_info[ANGLE] = 0.0;
private->trans_info[REAL_ANGLE] = 0.0;
private->trans_info[CENTER_X] = (private->x1 + private->x2) / 2;
private->trans_info[CENTER_Y] = (private->y1 + private->y2) / 2;
/* assemble the transformation matrix */
identity_matrix (private->transform);
......@@ -135,13 +148,18 @@ rotate_info_update (tool)
GDisplay * gdisp;
TransformCore * transform_core;
double angle;
int cx, cy;
gdisp = (GDisplay *) tool->gdisp_ptr;
transform_core = (TransformCore *) tool->private;
angle = (transform_core->trans_info[ANGLE] * 180.0) / M_PI;
cx = transform_core->cx;
cy = transform_core->cy;
sprintf (angle_buf, "%0.2f", angle);
sprintf (center_x_buf, "%d", cx);
sprintf (center_y_buf, "%d", cy);
info_dialog_update (transform_info);
info_dialog_popup (transform_info);
......@@ -159,8 +177,16 @@ rotate_tool_motion (tool, gdisp_ptr)
transform_core = (TransformCore *) tool->private;
cx = (transform_core->x1 + transform_core->x2) / 2.0;
cy = (transform_core->y1 + transform_core->y2) / 2.0;
if (transform_core->function == HANDLE_CENTER)
{
transform_core->cx = transform_core->curx;
transform_core->cy = transform_core->cury;
return;
}
cx = transform_core->cx;
cy = transform_core->cy;
x1 = transform_core->curx - cx;
x2 = transform_core->lastx - cx;
......@@ -209,8 +235,8 @@ rotate_tool_recalc (tool, gdisp_ptr)
gdisp = (GDisplay *) tool->gdisp_ptr;
transform_core = (TransformCore *) tool->private;
cx = (transform_core->x1 + transform_core->x2) / 2.0;
cy = (transform_core->y1 + transform_core->y2) / 2.0;
cx = transform_core->cx;
cy = transform_core->cy;
/* assemble the transformation matrix */
identity_matrix (transform_core->transform);
......
......@@ -16,6 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <stdlib.h>
#include <stdio.h>
#include "appenv.h"
#include "drawable.h"
#include "gdisplay.h"
......@@ -40,9 +41,7 @@
#define Y3 7
/* storage for information dialog fields */
char matrix_row1_buf [256];
char matrix_row2_buf [256];
char matrix_row3_buf [256];
static char matrix_row_buf [3][MAX_INFO_BUF];
/* forward function declarations */
static void * perspective_tool_perspective (GImage *, GimpDrawable *, TileManager *, int, Matrix);
......@@ -67,7 +66,16 @@ perspective_tool_transform (tool, gdisp_ptr, state)
switch (state)
{
case INIT :
transform_info = NULL;
if (!transform_info)
{
transform_info = info_dialog_new ("Perspective Transform Information");
info_dialog_add_field (transform_info, "Matrix: ",
matrix_row_buf[0]);
info_dialog_add_field (transform_info, " ",
matrix_row_buf[1]);
info_dialog_add_field (transform_info, " ",
matrix_row_buf[2]);
}
transform_core->trans_info [X0] = (double) transform_core->x1;
transform_core->trans_info [Y0] = (double) transform_core->y1;
......@@ -143,6 +151,25 @@ static void
perspective_info_update (tool)
Tool * tool;
{
TransformCore * transform_core;
int i;
transform_core = (TransformCore *) tool->private;
for (i = 0; i < 3; i++)
{
char *p = matrix_row_buf[i];
int j;
for (j = 0; j < 3; j++)
{
p += sprintf (p, "%10.3g", transform_core->transform[i][j]);
}
}
info_dialog_update (transform_info);
info_dialog_popup (transform_info);
return;
}
......
......@@ -40,11 +40,16 @@
/* index into trans_info array */
#define ANGLE 0
#define REAL_ANGLE 1
#define CENTER_X 2
#define CENTER_Y 3
#define EPSILON 0.018 /* ~ 1 degree */
#define FIFTEEN_DEG (M_PI / 12.0)
/* variables local to this file */
char angle_buf [MAX_INFO_BUF];
static char angle_buf [MAX_INFO_BUF];
static char center_x_buf [MAX_INFO_BUF];
static char center_y_buf [MAX_INFO_BUF];
/* forward function declarations */
static void * rotate_tool_rotate (GImage *, GimpDrawable *, double, TileManager *, int, Matrix);
......@@ -72,10 +77,16 @@ rotate_tool_transform (tool, gdisp_ptr, state)
{
transform_info = info_dialog_new ("Rotation Information");
info_dialog_add_field (transform_info, "Angle: ", angle_buf);
info_dialog_add_field (transform_info, "Center X: ", center_x_buf);
info_dialog_add_field (transform_info, "Center Y: ", center_y_buf);
}
transform_core->trans_info[ANGLE] = 0.0;
transform_core->trans_info[REAL_ANGLE] = 0.0;
transform_core->trans_info[CENTER_X] =
(transform_core->x1 + transform_core->x2) / 2;
transform_core->trans_info[CENTER_Y] =
(transform_core->y1 + transform_core->y2) / 2;
return NULL;
break;
......@@ -114,6 +125,8 @@ tools_new_rotate_tool ()
private->trans_func = rotate_tool_transform;
private->trans_info[ANGLE] = 0.0;
private->trans_info[REAL_ANGLE] = 0.0;
private->trans_info[CENTER_X] = (private->x1 + private->x2) / 2;
private->trans_info[CENTER_Y] = (private->y1 + private->y2) / 2;
/* assemble the transformation matrix */
identity_matrix (private->transform);
......@@ -135,13 +148,18 @@ rotate_info_update (tool)
GDisplay * gdisp;
TransformCore * transform_core;
double angle;
int cx, cy;
gdisp = (GDisplay *) tool->gdisp_ptr;
transform_core = (TransformCore *) tool->private;
angle = (transform_core->trans_info[ANGLE] * 180.0) / M_PI;
cx = transform_core->cx;
cy = transform_core->cy;
sprintf (angle_buf, "%0.2f", angle);
sprintf (center_x_buf, "%d", cx);
sprintf (center_y_buf, "%d", cy);
info_dialog_update (transform_info);
info_dialog_popup (transform_info);
......@@ -159,8 +177,16 @@ rotate_tool_motion (tool, gdisp_ptr)
transform_core = (TransformCore *) tool->private;
cx = (transform_core->x1 + transform_core->x2) / 2.0;
cy = (transform_core->y1 + transform_core->y2) / 2.0;
if (transform_core->function == HANDLE_CENTER)
{
transform_core->cx = transform_core->curx;
transform_core->cy = transform_core->cury;
return;
}
cx = transform_core->cx;
cy = transform_core->cy;
x1 = transform_core->curx - cx;
x2 = transform_core->lastx - cx;
......@@ -209,8 +235,8 @@ rotate_tool_recalc (tool, gdisp_ptr)
gdisp = (GDisplay *) tool->gdisp_ptr;
transform_core = (TransformCore *) tool->private;
cx = (transform_core->x1 + transform_core->x2) / 2.0;
cy = (transform_core->y1 + transform_core->y2) / 2.0;
cx = transform_core->cx;
cy = transform_core->cy;
/* assemble the transformation matrix */
identity_matrix (transform_core->transform);
......
......@@ -16,6 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <stdlib.h>
#include <stdio.h>
#include "appenv.h"
#include "drawable.h"
#include "gdisplay.h"
......@@ -40,9 +41,7 @@
#define Y3 7
/* storage for information dialog fields */
char matrix_row1_buf [256];
char matrix_row2_buf [256];
char matrix_row3_buf [256];
static char matrix_row_buf [3][MAX_INFO_BUF];
/* forward function declarations */
static void * perspective_tool_perspective (GImage *, GimpDrawable *, TileManager *, int, Matrix);
......@@ -67,7 +66,16 @@ perspective_tool_transform (tool, gdisp_ptr, state)
switch (state)
{
case INIT :
transform_info = NULL;
if (!transform_info)
{
transform_info = info_dialog_new ("Perspective Transform Information");
info_dialog_add_field (transform_info, "Matrix: ",
matrix_row_buf[0]);
info_dialog_add_field (transform_info, " ",
matrix_row_buf[1]);
info_dialog_add_field (transform_info, " ",
matrix_row_buf[2]);
}
transform_core->trans_info [X0] = (double) transform_core->x1;
transform_core->trans_info [Y0] = (double) transform_core->y1;
......@@ -143,6 +151,25 @@ static void
perspective_info_update (tool)
Tool * tool;
{
TransformCore * transform_core;
int i;
transform_core = (TransformCore *) tool->private;
for (i = 0; i < 3; i++)
{
char *p = matrix_row_buf[i];
int j;
for (j = 0; j < 3; j++)
{
p += sprintf (p, "%10.3g", transform_core->transform[i][j]);
}
}
info_dialog_update (transform_info);
info_dialog_popup (transform_info);
return;
}
......
......@@ -40,11 +40,16 @@
/* index into trans_info array */
#define ANGLE 0
#define REAL_ANGLE 1
#define CENTER_X 2
#define CENTER_Y 3
#define EPSILON 0.018 /* ~ 1 degree */
#define FIFTEEN_DEG (M_PI / 12.0)
/* variables local to this file */
char angle_buf [MAX_INFO_BUF];
static char angle_buf [MAX_INFO_BUF];
static char center_x_buf [MAX_INFO_BUF];
static char center_y_buf [MAX_INFO_BUF];
/* forward function declarations */
static void * rotate_tool_rotate (GImage *, GimpDrawable *, double, TileManager *, int, Matrix);
......@@ -72,10 +77,16 @@ rotate_tool_transform (tool, gdisp_ptr, state)
{
transform_info = info_dialog_new ("Rotation Information");
info_dialog_add_field (transform_info, "Angle: ", angle_buf);
info_dialog_add_field (transform_info, "Center X: ", center_x_buf);
info_dialog_add_field (transform_info, "Center Y: ", center_y_buf);
}
transform_core->trans_info[ANGLE] = 0.0;
transform_core->trans_info[REAL_ANGLE] = 0.0;
transform_core->trans_info[CENTER_X] =
(transform_core->x1 + transform_core->x2) / 2;
transform_core->trans_info[CENTER_Y] =
(transform_core->y1 + transform_core->y2) / 2;
return NULL;
break;
......@@ -114,6 +125,8 @@ tools_new_rotate_tool ()
private->trans_func = rotate_tool_transform;
private->trans_info[ANGLE] = 0.0;
private->trans_info[REAL_ANGLE] = 0.0;
private->trans_info[CENTER_X] = (private->x1 + private->x2) / 2;
private->trans_info[CENTER_Y] = (private->y1 + private->y2) / 2;
/* assemble the transformation matrix */
identity_matrix (private->transform);
......@@ -135,13 +148,18 @@ rotate_info_update (tool)
GDisplay * gdisp;
TransformCore * transform_core;
double angle;
int cx, cy;
gdisp = (GDisplay *) tool->gdisp_ptr;
transform_core = (TransformCore *) tool->private;
angle = (transform_core->trans_info[ANGLE] * 180.0) / M_PI;
cx = transform_core->cx;
cy = transform_core->cy;
sprintf (angle_buf, "%0.2f", angle);
sprintf (center_x_buf, "%d", cx);
sprintf (center_y_buf, "%d", cy);
info_dialog_update (transform_info);
info_dialog_popup (transform_info);
......@@ -159,8 +177,16 @@ rotate_tool_motion (tool, gdisp_ptr)
transform_core = (TransformCore *) tool->private;
cx = (transform_core->x1 + transform_core->x2) / 2.0;
cy = (transform_core->y1 + transform_core->y2) / 2.0;
if (transform_core->function == HANDLE_CENTER)
{
transform_core->cx = transform_core->curx;
transform_core->cy = transform_core->cury;
return;
}
cx = transform_core->cx;
cy = transform_core->cy;
x1 = transform_core->curx - cx;
x2 = transform_core->lastx - cx;
......@@ -209,8 +235,8 @@ rotate_tool_recalc (tool, gdisp_ptr)
gdisp = (GDisplay *) tool->gdisp_ptr;
transform_core = (TransformCore *) tool->private;
cx = (transform_core->x1 + transform_core->x2) / 2.0;
cy = (transform_core->y1 + transform_core->y2) / 2.0;
cx = transform_core->cx;
cy = transform_core->cy;
/* assemble the transformation matrix */
identity_matrix (transform_core->transform);
......
......@@ -18,6 +18,7 @@
#include <stdlib.h>
#include <math.h>
#include "appenv.h"
#include "actionarea.h"
#include "drawable.h"
#include "errors.h"
#include "floating_sel.h"
......@@ -48,7 +49,6 @@
/* variables */
static TranInfo old_trans_info;
static int new_ui;
InfoDialog * transform_info = NULL;
/* forward function declarations */
......@@ -68,6 +68,52 @@ static void invert (Matrix, Matrix);
src[i] = tile_data_pointer (tile[i], (x) % TILE_WIDTH, (y) % TILE_HEIGHT);
static void
transform_ok_callback (GtkWidget *w,
gpointer client_data)
{
Tool *tool;
tool = (Tool *) client_data;
transform_core_doit (tool, tool->gdisp_ptr);
}
static void
transform_cancel_callback (GtkWidget *w,
gpointer client_data)
{
Tool *tool;
TransformCore *transform_core;
int i;
tool = (Tool *) client_data;
transform_core = (TransformCore *) tool->private;
/* stop the current tool drawing process */
draw_core_pause (transform_core->core, tool);
/* Restore the previous transformation info */
for (i = 0; i < TRAN_INFO_SIZE; i++)
transform_core->trans_info [i] = old_trans_info [i];
/* recalculate the tool's transformation matrix */
transform_core_recalc (tool, tool->gdisp_ptr);
/* resume drawing the current tool */
draw_core_resume (transform_core->core, tool);
}
static ActionAreaItem action_items[2] =
{
{ NULL, transform_ok_callback, NULL, NULL },
{ "Cancel", transform_cancel_callback, NULL, NULL },
};
static char *action_labels[4] =
{
"Rotate", "Scale", "Shear", "Transform"
};
void
transform_core_button_press (tool, bevent, gdisp_ptr)
Tool *tool;
......@@ -90,7 +136,7 @@ transform_core_button_press (tool, bevent, gdisp_ptr)
tool->drawable = gimage_active_drawable (gdisp->gimage);
if (transform_core->function == CREATING)
if (transform_core->function == CREATING && tool->state == ACTIVE)
{
/* Save the current transformation info */
for (i = 0; i < TRAN_INFO_SIZE; i++)
......@@ -105,6 +151,9 @@ transform_core_button_press (tool, bevent, gdisp_ptr)
if ((transform_core->function >= CREATING) && (gdisp_ptr == tool->gdisp_ptr) &&
transform_core->interactive)
{
/* start drawing the bounding box and handles... */
draw_core_start (transform_core->core, gdisp->canvas->window, tool);
x = bevent->x;
y = bevent->y;
......@@ -132,6 +181,13 @@ transform_core_button_press (tool, bevent, gdisp_ptr)
transform_core->function = HANDLE_4;
}