gimp/app/tools/gimpsheartool.c
Michael Natterer 7ee99ea3a3 Transform tool cleanup:
2002-11-14  Michael Natterer  <mitch@gimp.org>

	Transform tool cleanup:

	* libgimptool/gimptoolenums.[ch]: removed the TransformState enum.

	* app/tools/gimptransformtool.[ch]: don't dispatch everything
	through the transform() virtual function. Added new vitrual
	functions dialog(), prepare(), motion() and recalc(). Do only the
	actual transform in transform(). Moved lots of logic which was
	duplicated in each subclass' transform() here. Cleanup.

	* app/tools/gimpfliptool.c
	* app/tools/gimpperspectivetool.c
	* app/tools/gimprotatetool.c
	* app/tools/gimpscaletool.c
	* app/tools/gimpsheartool.c: changed accordingly: moved code from
	transform() to the other method imlementations. Removed duplicated
	logic which is now done by our parent class. Makes everything
	smaller and more readable.

	InfoDialog cleanup:

	* app/gui/info-dialog.c: removed the "delete_event" callback so
	InfoDialog users can decide themselves what to do.

	* app/gui/info-window.c
	* app/tools/gimpmeasuretool.c: changed accordingly.

	* app/tools/gimpcolorpickertool.c: ditto. Moved info_dialog
	creation to a utility function to improve code readbility.

	* app/tools/gimpcroptool.c: ditto. Added a "Cancel" button which
	really cancels the tool instead of just hiding the dialog.

	* app/tools/gimptransformtool.c: added a "Cancel" button here too.
2002-11-14 11:54:57 +00:00

364 lines
10 KiB
C

/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* 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"
#include "tools-types.h"
#ifdef __GNUC__
#warning FIXME #include "gui/gui-types.h"
#endif
#include "gui/gui-types.h"
#include "core/gimpimage.h"
#include "core/gimpdrawable-transform.h"
#include "core/gimpdrawable-transform-utils.h"
#include "core/gimptoolinfo.h"
#include "display/gimpdisplay.h"
#include "gui/info-dialog.h"
#include "gimpsheartool.h"
#include "transform_options.h"
#include "libgimp/gimpintl.h"
/* index into trans_info array */
#define HORZ_OR_VERT 0
#define XSHEAR 1
#define YSHEAR 2
/* the minimum movement before direction of shear can be determined (pixels) */
#define MIN_MOVE 5
/* forward function declarations */
static void gimp_shear_tool_class_init (GimpShearToolClass *klass);
static void gimp_shear_tool_init (GimpShearTool *shear_tool);
static void gimp_shear_tool_dialog (GimpTransformTool *tr_tool);
static void gimp_shear_tool_prepare (GimpTransformTool *tr_tool,
GimpDisplay *gdisp);
static void gimp_shear_tool_motion (GimpTransformTool *tr_tool,
GimpDisplay *gdisp);
static void gimp_shear_tool_recalc (GimpTransformTool *tr_tool,
GimpDisplay *gdisp);
static TileManager * gimp_shear_tool_transform (GimpTransformTool *tr_tool,
GimpDisplay *gdisp);
static void shear_info_update (GimpTransformTool *tr_tool);
static void shear_x_mag_changed (GtkWidget *widget,
gpointer data);
static void shear_y_mag_changed (GtkWidget *widget,
gpointer data);
/* variables local to this file */
static gdouble xshear_val;
static gdouble yshear_val;
static GimpTransformToolClass *parent_class = NULL;
/* Public functions */
void
gimp_shear_tool_register (GimpToolRegisterCallback callback,
gpointer data)
{
(* callback) (GIMP_TYPE_SHEAR_TOOL,
transform_options_new,
FALSE,
"gimp-shear-tool",
_("Shear"),
_("Shear the layer or selection"),
N_("/Tools/Transform Tools/Shear"), "<shift>S",
NULL, "tools/shear.html",
GIMP_STOCK_TOOL_SHEAR,
data);
}
GType
gimp_shear_tool_get_type (void)
{
static GType tool_type = 0;
if (! tool_type)
{
static const GTypeInfo tool_info =
{
sizeof (GimpShearToolClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gimp_shear_tool_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GimpShearTool),
0, /* n_preallocs */
(GInstanceInitFunc) gimp_shear_tool_init,
};
tool_type = g_type_register_static (GIMP_TYPE_TRANSFORM_TOOL,
"GimpShearTool",
&tool_info, 0);
}
return tool_type;
}
static void
gimp_shear_tool_class_init (GimpShearToolClass *klass)
{
GimpTransformToolClass *trans_class;
trans_class = GIMP_TRANSFORM_TOOL_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
trans_class->dialog = gimp_shear_tool_dialog;
trans_class->prepare = gimp_shear_tool_prepare;
trans_class->motion = gimp_shear_tool_motion;
trans_class->recalc = gimp_shear_tool_recalc;
trans_class->transform = gimp_shear_tool_transform;
}
static void
gimp_shear_tool_init (GimpShearTool *shear_tool)
{
GimpTool *tool;
GimpTransformTool *tr_tool;
tool = GIMP_TOOL (shear_tool);
tr_tool = GIMP_TRANSFORM_TOOL (shear_tool);
gimp_tool_control_set_tool_cursor (tool->control, GIMP_SHEAR_TOOL_CURSOR);
tr_tool->use_center = FALSE;
tr_tool->shell_desc = _("Shearing Information");
}
static void
gimp_shear_tool_dialog (GimpTransformTool *tr_tool)
{
info_dialog_add_spinbutton (tr_tool->info_dialog,
_("Shear Magnitude X:"),
&xshear_val,
-65536, 65536, 1, 15, 1, 1, 0,
G_CALLBACK (shear_x_mag_changed),
tr_tool);
info_dialog_add_spinbutton (tr_tool->info_dialog,
_("Y:"),
&yshear_val,
-65536, 65536, 1, 15, 1, 1, 0,
G_CALLBACK (shear_y_mag_changed),
tr_tool);
}
static void
gimp_shear_tool_prepare (GimpTransformTool *tr_tool,
GimpDisplay *gdisp)
{
tr_tool->trans_info[HORZ_OR_VERT] = ORIENTATION_UNKNOWN;
tr_tool->trans_info[XSHEAR] = 0.0;
tr_tool->trans_info[YSHEAR] = 0.0;
}
static void
gimp_shear_tool_motion (GimpTransformTool *tr_tool,
GimpDisplay *gdisp)
{
gdouble diffx, diffy;
gint dir;
diffx = tr_tool->curx - tr_tool->lastx;
diffy = tr_tool->cury - tr_tool->lasty;
/* If we haven't yet decided on which way to control shearing
* decide using the maximum differential
*/
if (tr_tool->trans_info[HORZ_OR_VERT] == ORIENTATION_UNKNOWN)
{
if (abs (diffx) > MIN_MOVE || abs (diffy) > MIN_MOVE)
{
if (abs (diffx) > abs (diffy))
{
tr_tool->trans_info[HORZ_OR_VERT] = ORIENTATION_HORIZONTAL;
tr_tool->trans_info[ORIENTATION_VERTICAL] = 0.0;
}
else
{
tr_tool->trans_info[HORZ_OR_VERT] = ORIENTATION_VERTICAL;
tr_tool->trans_info[ORIENTATION_HORIZONTAL] = 0.0;
}
}
/* set the current coords to the last ones */
else
{
tr_tool->curx = tr_tool->lastx;
tr_tool->cury = tr_tool->lasty;
}
}
/* if the direction is known, keep track of the magnitude */
if (tr_tool->trans_info[HORZ_OR_VERT] != ORIENTATION_UNKNOWN)
{
dir = tr_tool->trans_info[HORZ_OR_VERT];
switch (tr_tool->function)
{
case TRANSFORM_HANDLE_1:
if (dir == ORIENTATION_HORIZONTAL)
tr_tool->trans_info[XSHEAR] -= diffx;
else
tr_tool->trans_info[YSHEAR] -= diffy;
break;
case TRANSFORM_HANDLE_2:
if (dir == ORIENTATION_HORIZONTAL)
tr_tool->trans_info[XSHEAR] -= diffx;
else
tr_tool->trans_info[YSHEAR] += diffy;
break;
case TRANSFORM_HANDLE_3:
if (dir == ORIENTATION_HORIZONTAL)
tr_tool->trans_info[XSHEAR] += diffx;
else
tr_tool->trans_info[YSHEAR] -= diffy;
break;
case TRANSFORM_HANDLE_4:
if (dir == ORIENTATION_HORIZONTAL)
tr_tool->trans_info[XSHEAR] += diffx;
else
tr_tool->trans_info[YSHEAR] += diffy;
break;
default:
break;
}
}
}
static void
gimp_shear_tool_recalc (GimpTransformTool *tr_tool,
GimpDisplay *gdisp)
{
gdouble amount;
if (tr_tool->trans_info[HORZ_OR_VERT] == ORIENTATION_HORIZONTAL)
amount = tr_tool->trans_info[XSHEAR];
else
amount = tr_tool->trans_info[YSHEAR];
gimp_drawable_transform_matrix_shear (tr_tool->x1,
tr_tool->y1,
tr_tool->x2,
tr_tool->y2,
tr_tool->trans_info[HORZ_OR_VERT],
amount,
tr_tool->transform);
/* transform the bounding box */
gimp_transform_tool_transform_bounding_box (tr_tool);
/* update the information dialog */
shear_info_update (tr_tool);
}
static TileManager *
gimp_shear_tool_transform (GimpTransformTool *tr_tool,
GimpDisplay *gdisp)
{
return gimp_transform_tool_transform_tiles (tr_tool,
_("Shearing..."));
}
static void
shear_info_update (GimpTransformTool *tr_tool)
{
xshear_val = tr_tool->trans_info[XSHEAR];
yshear_val = tr_tool->trans_info[YSHEAR];
info_dialog_update (tr_tool->info_dialog);
info_dialog_popup (tr_tool->info_dialog);
}
static void
shear_x_mag_changed (GtkWidget *widget,
gpointer data)
{
GimpTool *tool;
GimpTransformTool *tr_tool;
gdouble value;
tool = GIMP_TOOL (data);
tr_tool = GIMP_TRANSFORM_TOOL (data);
value = GTK_ADJUSTMENT (widget)->value;
if (value != tr_tool->trans_info[XSHEAR])
{
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
tr_tool->trans_info[XSHEAR] = value;
gimp_shear_tool_recalc (tr_tool, tool->gdisp);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
}
}
static void
shear_y_mag_changed (GtkWidget *widget,
gpointer data)
{
GimpTool *tool;
GimpTransformTool *tr_tool;
gdouble value;
tool = GIMP_TOOL (data);
tr_tool = GIMP_TRANSFORM_TOOL (data);
value = GTK_ADJUSTMENT (widget)->value;
if (value != tr_tool->trans_info[YSHEAR])
{
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
tr_tool->trans_info[YSHEAR] = value;
gimp_shear_tool_recalc (tr_tool, tool->gdisp);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
}
}