2006-12-10 05:33:38 +08:00
|
|
|
|
/* GIMP - The GNU Image Manipulation Program
|
2005-03-03 02:18:19 +08:00
|
|
|
|
* 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"
|
|
|
|
|
|
2006-11-05 06:39:37 +08:00
|
|
|
|
#include <string.h>
|
|
|
|
|
|
2005-03-03 02:18:19 +08:00
|
|
|
|
#include <gtk/gtk.h>
|
|
|
|
|
#include <gdk/gdkkeysyms.h>
|
|
|
|
|
|
2005-09-04 03:48:22 +08:00
|
|
|
|
#include "libgimpbase/gimpbase.h"
|
2007-03-09 21:00:01 +08:00
|
|
|
|
#include "libgimpmath/gimpmath.h"
|
2005-03-03 02:18:19 +08:00
|
|
|
|
#include "libgimpwidgets/gimpwidgets.h"
|
|
|
|
|
|
|
|
|
|
#include "tools-types.h"
|
|
|
|
|
|
|
|
|
|
#include "core/gimpchannel.h"
|
|
|
|
|
#include "core/gimpimage.h"
|
2006-09-24 04:45:06 +08:00
|
|
|
|
#include "core/gimpimage-crop.h"
|
2005-07-12 03:21:52 +08:00
|
|
|
|
#include "core/gimppickable.h"
|
2006-06-05 01:08:26 +08:00
|
|
|
|
#include "core/gimpmarshal.h"
|
2006-08-08 19:51:04 +08:00
|
|
|
|
|
2005-03-03 02:18:19 +08:00
|
|
|
|
#include "display/gimpdisplay.h"
|
|
|
|
|
#include "display/gimpdisplayshell.h"
|
|
|
|
|
#include "display/gimpdisplayshell-transform.h"
|
|
|
|
|
|
2005-08-15 22:23:28 +08:00
|
|
|
|
#include "gimpdrawtool.h"
|
2005-03-03 02:18:19 +08:00
|
|
|
|
#include "gimprectangleoptions.h"
|
2005-08-15 22:23:28 +08:00
|
|
|
|
#include "gimprectangletool.h"
|
2005-03-03 02:18:19 +08:00
|
|
|
|
#include "gimptoolcontrol.h"
|
|
|
|
|
|
|
|
|
|
#include "gimp-intl.h"
|
|
|
|
|
|
2006-11-05 03:21:15 +08:00
|
|
|
|
|
2006-06-05 01:08:26 +08:00
|
|
|
|
enum
|
|
|
|
|
{
|
|
|
|
|
RECTANGLE_CHANGED,
|
|
|
|
|
LAST_SIGNAL
|
|
|
|
|
};
|
|
|
|
|
|
2005-03-03 02:18:19 +08:00
|
|
|
|
/* speed of key movement */
|
2006-11-06 16:16:31 +08:00
|
|
|
|
#define ARROW_VELOCITY 25
|
|
|
|
|
|
2007-07-11 13:09:50 +08:00
|
|
|
|
#define MAX_HANDLE_SIZE 50
|
2006-11-06 16:16:31 +08:00
|
|
|
|
#define MIN_HANDLE_SIZE 6
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
2007-03-30 17:26:48 +08:00
|
|
|
|
#define SQRT5 2.236067977
|
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
typedef enum
|
|
|
|
|
{
|
|
|
|
|
CLAMPED_NONE = 0,
|
|
|
|
|
CLAMPED_LEFT = (1 << 0),
|
|
|
|
|
CLAMPED_RIGHT = (1 << 1),
|
|
|
|
|
CLAMPED_TOP = (1 << 2),
|
|
|
|
|
CLAMPED_BOTTOM = (1 << 3)
|
|
|
|
|
} ClampedSide;
|
|
|
|
|
|
|
|
|
|
typedef enum
|
|
|
|
|
{
|
2007-07-11 13:09:50 +08:00
|
|
|
|
SIDE_TO_RESIZE_NONE,
|
|
|
|
|
SIDE_TO_RESIZE_LEFT,
|
|
|
|
|
SIDE_TO_RESIZE_RIGHT,
|
|
|
|
|
SIDE_TO_RESIZE_TOP,
|
|
|
|
|
SIDE_TO_RESIZE_BOTTOM,
|
|
|
|
|
SIDE_TO_RESIZE_LEFT_AND_RIGHT_SYMMETRICALLY,
|
|
|
|
|
SIDE_TO_RESIZE_TOP_AND_BOTTOM_SYMMETRICALLY,
|
2007-07-09 05:57:22 +08:00
|
|
|
|
} SideToResize;
|
|
|
|
|
|
2005-08-15 22:23:28 +08:00
|
|
|
|
|
2006-06-05 19:18:43 +08:00
|
|
|
|
#define GIMP_RECTANGLE_TOOL_GET_PRIVATE(obj) \
|
2006-11-05 03:21:15 +08:00
|
|
|
|
(gimp_rectangle_tool_get_private (GIMP_RECTANGLE_TOOL (obj)))
|
2006-06-05 19:18:43 +08:00
|
|
|
|
|
2005-09-04 03:48:22 +08:00
|
|
|
|
|
|
|
|
|
typedef struct _GimpRectangleToolPrivate GimpRectangleToolPrivate;
|
|
|
|
|
|
|
|
|
|
struct _GimpRectangleToolPrivate
|
|
|
|
|
{
|
2007-06-30 00:37:50 +08:00
|
|
|
|
/* The following members are "constants", that is, variables that are setup
|
|
|
|
|
* during gimp_rectangle_tool_button_press and then only read.
|
|
|
|
|
*/
|
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
/* Holds coordinate where button was pressed when rectangle adjustment was
|
|
|
|
|
* initiated.
|
|
|
|
|
*/
|
|
|
|
|
gint pressx;
|
|
|
|
|
gint pressy;
|
2005-09-04 03:48:22 +08:00
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
/* Holds the coordinate that should be used as the "other side" when
|
|
|
|
|
* fixed-center is turned off.
|
|
|
|
|
*/
|
2007-06-30 00:37:50 +08:00
|
|
|
|
gint other_side_x;
|
|
|
|
|
gint other_side_y;
|
2005-09-04 03:48:22 +08:00
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
/* Holds the coordinate to be used as center when fixed-center is used. */
|
2007-05-02 17:14:35 +08:00
|
|
|
|
gint center_x_on_fixed_center;
|
|
|
|
|
gint center_y_on_fixed_center;
|
|
|
|
|
|
2007-06-30 00:37:50 +08:00
|
|
|
|
/* The rest of the members are internal state variables, that is, variables
|
|
|
|
|
* that might change during the manipulation session of the rectangle. Make
|
|
|
|
|
* sure these variables are in consistent states.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
gint x1, y1; /* upper left hand coordinate */
|
|
|
|
|
gint x2, y2; /* lower right hand coords */
|
|
|
|
|
|
2006-11-05 03:21:15 +08:00
|
|
|
|
guint function; /* moving or resizing */
|
2006-06-01 03:45:38 +08:00
|
|
|
|
|
2006-09-07 06:51:54 +08:00
|
|
|
|
GimpRectangleConstraint constraint; /* how to constrain rectangle */
|
2006-06-03 06:24:55 +08:00
|
|
|
|
|
2006-11-05 03:21:15 +08:00
|
|
|
|
gint lastx; /* previous x coord */
|
|
|
|
|
gint lasty; /* previous y coord */
|
2006-06-03 06:24:55 +08:00
|
|
|
|
|
2006-11-07 19:09:51 +08:00
|
|
|
|
gint handle_w; /* handle width */
|
|
|
|
|
gint handle_h; /* handle height */
|
2006-06-05 04:34:46 +08:00
|
|
|
|
|
2007-07-01 02:13:41 +08:00
|
|
|
|
/* Top and bottom side handle
|
|
|
|
|
* width.
|
|
|
|
|
*/
|
|
|
|
|
gint top_and_bottom_handle_w;
|
|
|
|
|
/* Left and right side handle
|
|
|
|
|
* height.
|
|
|
|
|
*/
|
|
|
|
|
gint left_and_right_handle_h;
|
|
|
|
|
|
2006-11-05 03:21:15 +08:00
|
|
|
|
gint saved_x1; /* for saving in case action */
|
|
|
|
|
gint saved_y1; /* is canceled */
|
|
|
|
|
gint saved_x2;
|
|
|
|
|
gint saved_y2;
|
|
|
|
|
gdouble saved_center_x;
|
|
|
|
|
gdouble saved_center_y;
|
2006-06-07 05:06:06 +08:00
|
|
|
|
|
2007-01-24 16:40:24 +08:00
|
|
|
|
gint suppress_updates;
|
|
|
|
|
|
2006-11-05 03:21:15 +08:00
|
|
|
|
GimpRectangleGuide guide; /* synced with options->guide, only exists for drawing */
|
2005-09-04 03:48:22 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2006-03-22 01:37:24 +08:00
|
|
|
|
static void gimp_rectangle_tool_iface_base_init (GimpRectangleToolInterface *iface);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
2005-09-04 03:48:22 +08:00
|
|
|
|
static GimpRectangleToolPrivate *
|
2006-11-06 00:36:15 +08:00
|
|
|
|
gimp_rectangle_tool_get_private (GimpRectangleTool *rectangle);
|
2006-03-22 01:37:24 +08:00
|
|
|
|
|
2006-09-07 06:51:54 +08:00
|
|
|
|
GimpRectangleConstraint
|
2006-11-06 00:36:15 +08:00
|
|
|
|
gimp_rectangle_tool_get_constraint (GimpRectangleTool *rectangle);
|
2006-03-22 01:37:24 +08:00
|
|
|
|
|
2005-03-03 02:18:19 +08:00
|
|
|
|
/* Rectangle helper functions */
|
2007-03-15 17:21:47 +08:00
|
|
|
|
static void gimp_rectangle_tool_start (GimpRectangleTool *rectangle,
|
|
|
|
|
GimpDisplay *display);
|
2006-11-06 00:36:15 +08:00
|
|
|
|
static void gimp_rectangle_tool_halt (GimpRectangleTool *rectangle);
|
|
|
|
|
static void gimp_rectangle_tool_draw_guides (GimpDrawTool *draw_tool);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
|
|
|
|
/* Rectangle dialog functions */
|
2006-11-06 00:36:15 +08:00
|
|
|
|
static void gimp_rectangle_tool_update_options (GimpRectangleTool *rectangle,
|
|
|
|
|
GimpDisplay *display);
|
2006-03-26 21:50:13 +08:00
|
|
|
|
|
2006-11-06 00:36:15 +08:00
|
|
|
|
static void gimp_rectangle_tool_options_notify (GimpRectangleOptions *options,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
GimpRectangleTool *rectangle);
|
2006-11-05 06:39:37 +08:00
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
static void gimp_rectangle_tool_check_function (GimpRectangleTool *rectangle);
|
2007-05-02 17:14:35 +08:00
|
|
|
|
|
2007-02-28 21:08:09 +08:00
|
|
|
|
static void gimp_rectangle_tool_rectangle_changed (GimpRectangleTool *rectangle);
|
2007-03-01 00:05:52 +08:00
|
|
|
|
|
2006-11-06 00:36:15 +08:00
|
|
|
|
static void gimp_rectangle_tool_auto_shrink (GimpRectangleTool *rectangle);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
2007-07-01 02:13:41 +08:00
|
|
|
|
static GtkAnchorType gimp_rectangle_tool_get_anchor (GimpRectangleToolPrivate *private);
|
2007-02-09 07:19:57 +08:00
|
|
|
|
static void gimp_rectangle_tool_set_highlight (GimpRectangleTool *rectangle);
|
2006-11-07 00:40:09 +08:00
|
|
|
|
|
2007-06-30 00:37:50 +08:00
|
|
|
|
static void gimp_rectangle_tool_get_other_side (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
const gchar **other_x,
|
|
|
|
|
const gchar **other_y);
|
|
|
|
|
static void gimp_rectangle_tool_get_other_side_coord
|
|
|
|
|
(GimpRectangleTool *rectangle_tool,
|
|
|
|
|
gint *other_side_x,
|
|
|
|
|
gint *other_side_y);
|
|
|
|
|
static void gimp_rectangle_tool_set_other_side_coord
|
|
|
|
|
(GimpRectangleTool *rectangle_tool,
|
|
|
|
|
gint other_side_x,
|
|
|
|
|
gint other_side_y);
|
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
static void gimp_rectangle_tool_apply_coord (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
gint coord_x,
|
|
|
|
|
gint coord_y);
|
|
|
|
|
|
|
|
|
|
static void gimp_rectangle_tool_clamp (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
ClampedSide *clamped_sides,
|
|
|
|
|
GimpRectangleConstraint constraint,
|
|
|
|
|
gboolean symmetrically);
|
|
|
|
|
static void gimp_rectangle_tool_clamp_width (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
ClampedSide *clamped_sides,
|
|
|
|
|
GimpRectangleConstraint constraint,
|
|
|
|
|
gboolean symmetrically);
|
|
|
|
|
static void gimp_rectangle_tool_clamp_height (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
ClampedSide *clamped_sides,
|
|
|
|
|
GimpRectangleConstraint constraint,
|
|
|
|
|
gboolean symmetrically);
|
|
|
|
|
|
|
|
|
|
static void gimp_rectangle_tool_keep_inside (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
GimpRectangleConstraint constraint);
|
|
|
|
|
static void gimp_rectangle_tool_keep_inside_horizontally
|
|
|
|
|
(GimpRectangleTool *rectangle_tool,
|
|
|
|
|
GimpRectangleConstraint constraint);
|
|
|
|
|
static void gimp_rectangle_tool_keep_inside_vertically
|
|
|
|
|
(GimpRectangleTool *rectangle_tool,
|
|
|
|
|
GimpRectangleConstraint constraint);
|
|
|
|
|
|
|
|
|
|
static void gimp_rectangle_tool_apply_fixed_width (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
GimpRectangleConstraint constraint);
|
|
|
|
|
static void gimp_rectangle_tool_apply_fixed_height (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
GimpRectangleConstraint constraint);
|
|
|
|
|
|
|
|
|
|
static void gimp_rectangle_tool_apply_aspect (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
gdouble aspect,
|
|
|
|
|
gint clamped_sides);
|
|
|
|
|
|
|
|
|
|
static void gimp_rectangle_tool_update_with_coord (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
gint new_x,
|
|
|
|
|
gint new_y);
|
|
|
|
|
|
|
|
|
|
static void gimp_rectangle_tool_get_constraints (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
gint *min_x,
|
|
|
|
|
gint *min_y,
|
|
|
|
|
gint *max_x,
|
|
|
|
|
gint *max_y,
|
|
|
|
|
GimpRectangleConstraint constraint);
|
|
|
|
|
|
|
|
|
|
static void gimp_rectangle_tool_handle_general_clamping
|
|
|
|
|
(GimpRectangleTool *rectangle_tool);
|
|
|
|
|
|
2006-11-05 03:21:15 +08:00
|
|
|
|
|
2006-06-05 19:18:43 +08:00
|
|
|
|
static guint gimp_rectangle_tool_signals[LAST_SIGNAL] = { 0 };
|
|
|
|
|
|
|
|
|
|
|
2005-03-03 02:18:19 +08:00
|
|
|
|
GType
|
2005-08-15 22:23:28 +08:00
|
|
|
|
gimp_rectangle_tool_interface_get_type (void)
|
2005-03-03 02:18:19 +08:00
|
|
|
|
{
|
2006-08-08 19:51:04 +08:00
|
|
|
|
static GType iface_type = 0;
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
2006-10-18 21:17:50 +08:00
|
|
|
|
if (! iface_type)
|
2005-03-03 02:18:19 +08:00
|
|
|
|
{
|
2006-10-18 21:17:50 +08:00
|
|
|
|
const GTypeInfo iface_info =
|
2005-03-03 02:18:19 +08:00
|
|
|
|
{
|
2005-08-15 22:23:28 +08:00
|
|
|
|
sizeof (GimpRectangleToolInterface),
|
2005-09-04 03:48:22 +08:00
|
|
|
|
(GBaseInitFunc) gimp_rectangle_tool_iface_base_init,
|
|
|
|
|
(GBaseFinalizeFunc) NULL,
|
2005-03-03 02:18:19 +08:00
|
|
|
|
};
|
|
|
|
|
|
2006-08-08 19:51:04 +08:00
|
|
|
|
iface_type = g_type_register_static (G_TYPE_INTERFACE,
|
|
|
|
|
"GimpRectangleToolInterface",
|
|
|
|
|
&iface_info, 0);
|
|
|
|
|
|
|
|
|
|
g_type_interface_add_prerequisite (iface_type, GIMP_TYPE_DRAW_TOOL);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
2006-08-08 19:51:04 +08:00
|
|
|
|
return iface_type;
|
2005-03-03 02:18:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2006-02-04 03:29:11 +08:00
|
|
|
|
gimp_rectangle_tool_iface_base_init (GimpRectangleToolInterface *iface)
|
2005-08-15 22:23:28 +08:00
|
|
|
|
{
|
|
|
|
|
static gboolean initialized = FALSE;
|
|
|
|
|
|
|
|
|
|
if (! initialized)
|
|
|
|
|
{
|
2006-06-05 01:08:26 +08:00
|
|
|
|
gimp_rectangle_tool_signals[RECTANGLE_CHANGED] =
|
|
|
|
|
g_signal_new ("rectangle-changed",
|
|
|
|
|
G_TYPE_FROM_INTERFACE (iface),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
2006-08-08 19:51:04 +08:00
|
|
|
|
G_STRUCT_OFFSET (GimpRectangleToolInterface,
|
|
|
|
|
rectangle_changed),
|
2006-06-05 01:08:26 +08:00
|
|
|
|
NULL, NULL,
|
|
|
|
|
gimp_marshal_VOID__VOID,
|
|
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
|
|
2006-02-04 03:29:11 +08:00
|
|
|
|
g_object_interface_install_property (iface,
|
2006-01-19 04:29:40 +08:00
|
|
|
|
g_param_spec_int ("x1",
|
|
|
|
|
NULL, NULL,
|
|
|
|
|
-GIMP_MAX_IMAGE_SIZE,
|
|
|
|
|
GIMP_MAX_IMAGE_SIZE,
|
|
|
|
|
0,
|
|
|
|
|
GIMP_PARAM_READWRITE));
|
|
|
|
|
|
2006-02-04 03:29:11 +08:00
|
|
|
|
g_object_interface_install_property (iface,
|
2006-01-19 04:29:40 +08:00
|
|
|
|
g_param_spec_int ("y1",
|
|
|
|
|
NULL, NULL,
|
|
|
|
|
-GIMP_MAX_IMAGE_SIZE,
|
|
|
|
|
GIMP_MAX_IMAGE_SIZE,
|
|
|
|
|
0,
|
|
|
|
|
GIMP_PARAM_READWRITE));
|
|
|
|
|
|
2006-02-04 03:29:11 +08:00
|
|
|
|
g_object_interface_install_property (iface,
|
2006-01-19 04:29:40 +08:00
|
|
|
|
g_param_spec_int ("x2",
|
|
|
|
|
NULL, NULL,
|
|
|
|
|
-GIMP_MAX_IMAGE_SIZE,
|
|
|
|
|
GIMP_MAX_IMAGE_SIZE,
|
|
|
|
|
0,
|
|
|
|
|
GIMP_PARAM_READWRITE));
|
|
|
|
|
|
2006-02-04 03:29:11 +08:00
|
|
|
|
g_object_interface_install_property (iface,
|
2006-01-19 04:29:40 +08:00
|
|
|
|
g_param_spec_int ("y2",
|
|
|
|
|
NULL, NULL,
|
|
|
|
|
-GIMP_MAX_IMAGE_SIZE,
|
|
|
|
|
GIMP_MAX_IMAGE_SIZE,
|
|
|
|
|
0,
|
|
|
|
|
GIMP_PARAM_READWRITE));
|
2005-09-04 03:48:22 +08:00
|
|
|
|
|
2006-06-01 03:45:38 +08:00
|
|
|
|
g_object_interface_install_property (iface,
|
2006-12-14 05:49:09 +08:00
|
|
|
|
g_param_spec_enum ("constraint",
|
2006-09-07 06:51:54 +08:00
|
|
|
|
NULL, NULL,
|
2006-12-14 05:49:09 +08:00
|
|
|
|
GIMP_TYPE_RECTANGLE_CONSTRAINT,
|
2006-09-07 06:51:54 +08:00
|
|
|
|
GIMP_RECTANGLE_CONSTRAIN_NONE,
|
|
|
|
|
GIMP_PARAM_READWRITE));
|
2006-06-01 03:45:38 +08:00
|
|
|
|
|
2006-11-05 20:35:59 +08:00
|
|
|
|
iface->execute = NULL;
|
|
|
|
|
iface->cancel = NULL;
|
2006-06-05 01:08:26 +08:00
|
|
|
|
iface->rectangle_changed = NULL;
|
|
|
|
|
|
2005-08-15 22:23:28 +08:00
|
|
|
|
initialized = TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-09-04 03:48:22 +08:00
|
|
|
|
static void
|
|
|
|
|
gimp_rectangle_tool_private_finalize (GimpRectangleToolPrivate *private)
|
|
|
|
|
{
|
2007-05-23 21:49:06 +08:00
|
|
|
|
g_slice_free (GimpRectangleToolPrivate, private);
|
2005-09-04 03:48:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static GimpRectangleToolPrivate *
|
|
|
|
|
gimp_rectangle_tool_get_private (GimpRectangleTool *tool)
|
|
|
|
|
{
|
|
|
|
|
static GQuark private_key = 0;
|
|
|
|
|
|
2006-06-05 19:18:43 +08:00
|
|
|
|
GimpRectangleToolPrivate *private;
|
2005-09-04 03:48:22 +08:00
|
|
|
|
|
2006-06-05 19:18:43 +08:00
|
|
|
|
if (G_UNLIKELY (private_key == 0))
|
2005-09-04 03:48:22 +08:00
|
|
|
|
private_key = g_quark_from_static_string ("gimp-rectangle-tool-private");
|
|
|
|
|
|
2006-06-05 19:18:43 +08:00
|
|
|
|
private = g_object_get_qdata (G_OBJECT (tool), private_key);
|
2005-09-04 03:48:22 +08:00
|
|
|
|
|
|
|
|
|
if (! private)
|
|
|
|
|
{
|
2007-05-23 21:49:06 +08:00
|
|
|
|
private = g_slice_new0 (GimpRectangleToolPrivate);
|
2005-09-04 03:48:22 +08:00
|
|
|
|
|
2006-06-05 19:18:43 +08:00
|
|
|
|
g_object_set_qdata_full (G_OBJECT (tool), private_key, private,
|
2006-06-07 03:14:25 +08:00
|
|
|
|
(GDestroyNotify)
|
|
|
|
|
gimp_rectangle_tool_private_finalize);
|
2005-09-04 03:48:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return private;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* gimp_rectangle_tool_install_properties:
|
|
|
|
|
* @klass: the class structure for a type deriving from #GObject
|
|
|
|
|
*
|
|
|
|
|
* Installs the necessary properties for a class implementing
|
|
|
|
|
* #GimpToolOptions. A #GimpRectangleToolProp property is installed
|
|
|
|
|
* for each property, using the values from the #GimpRectangleToolProp
|
|
|
|
|
* enumeration. The caller must make sure itself that the enumeration
|
|
|
|
|
* values don't collide with some other property values they
|
|
|
|
|
* are using (that's what %GIMP_RECTANGLE_TOOL_PROP_LAST is good for).
|
|
|
|
|
**/
|
|
|
|
|
void
|
|
|
|
|
gimp_rectangle_tool_install_properties (GObjectClass *klass)
|
|
|
|
|
{
|
|
|
|
|
g_object_class_override_property (klass,
|
|
|
|
|
GIMP_RECTANGLE_TOOL_PROP_X1,
|
|
|
|
|
"x1");
|
|
|
|
|
g_object_class_override_property (klass,
|
|
|
|
|
GIMP_RECTANGLE_TOOL_PROP_Y1,
|
|
|
|
|
"y1");
|
|
|
|
|
g_object_class_override_property (klass,
|
|
|
|
|
GIMP_RECTANGLE_TOOL_PROP_X2,
|
|
|
|
|
"x2");
|
|
|
|
|
g_object_class_override_property (klass,
|
|
|
|
|
GIMP_RECTANGLE_TOOL_PROP_Y2,
|
|
|
|
|
"y2");
|
2006-06-01 03:45:38 +08:00
|
|
|
|
g_object_class_override_property (klass,
|
2006-09-07 06:51:54 +08:00
|
|
|
|
GIMP_RECTANGLE_TOOL_PROP_CONSTRAINT,
|
|
|
|
|
"constraint");
|
2005-09-04 03:48:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
2006-06-01 03:45:38 +08:00
|
|
|
|
void
|
2006-09-07 06:51:54 +08:00
|
|
|
|
gimp_rectangle_tool_set_constraint (GimpRectangleTool *tool,
|
|
|
|
|
GimpRectangleConstraint constraint)
|
2006-06-01 03:45:38 +08:00
|
|
|
|
{
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_RECTANGLE_TOOL (tool));
|
|
|
|
|
|
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (tool);
|
|
|
|
|
|
2006-09-07 06:51:54 +08:00
|
|
|
|
private->constraint = constraint;
|
2006-06-05 19:18:43 +08:00
|
|
|
|
|
2006-09-07 06:51:54 +08:00
|
|
|
|
g_object_notify (G_OBJECT (tool), "constraint");
|
2006-06-01 03:45:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
2006-09-07 06:51:54 +08:00
|
|
|
|
GimpRectangleConstraint
|
|
|
|
|
gimp_rectangle_tool_get_constraint (GimpRectangleTool *tool)
|
2006-06-01 03:45:38 +08:00
|
|
|
|
{
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (GIMP_IS_RECTANGLE_TOOL (tool), 0);
|
|
|
|
|
|
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (tool);
|
|
|
|
|
|
2006-09-07 06:51:54 +08:00
|
|
|
|
return private->constraint;
|
2006-06-01 03:45:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
2006-09-24 05:22:33 +08:00
|
|
|
|
void
|
|
|
|
|
gimp_rectangle_tool_get_press_coords (GimpRectangleTool *rectangle,
|
|
|
|
|
gint *pressx_ptr,
|
|
|
|
|
gint *pressy_ptr)
|
|
|
|
|
{
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
|
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (rectangle);
|
|
|
|
|
|
|
|
|
|
*pressx_ptr = private->pressx;
|
|
|
|
|
*pressy_ptr = private->pressy;
|
|
|
|
|
}
|
|
|
|
|
|
2005-09-04 03:48:22 +08:00
|
|
|
|
void
|
|
|
|
|
gimp_rectangle_tool_set_property (GObject *object,
|
|
|
|
|
guint property_id,
|
|
|
|
|
const GValue *value,
|
|
|
|
|
GParamSpec *pspec)
|
|
|
|
|
{
|
2006-09-24 05:22:33 +08:00
|
|
|
|
GimpRectangleTool *rectangle = GIMP_RECTANGLE_TOOL (object);
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
|
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (rectangle);
|
2005-09-04 03:48:22 +08:00
|
|
|
|
|
|
|
|
|
switch (property_id)
|
|
|
|
|
{
|
|
|
|
|
case GIMP_RECTANGLE_TOOL_PROP_X1:
|
2006-09-24 05:22:33 +08:00
|
|
|
|
private->x1 = g_value_get_int (value);
|
2005-09-04 03:48:22 +08:00
|
|
|
|
break;
|
|
|
|
|
case GIMP_RECTANGLE_TOOL_PROP_Y1:
|
2006-09-24 05:22:33 +08:00
|
|
|
|
private->y1 = g_value_get_int (value);
|
2005-09-04 03:48:22 +08:00
|
|
|
|
break;
|
|
|
|
|
case GIMP_RECTANGLE_TOOL_PROP_X2:
|
2006-09-24 05:22:33 +08:00
|
|
|
|
private->x2 = g_value_get_int (value);
|
2005-09-04 03:48:22 +08:00
|
|
|
|
break;
|
|
|
|
|
case GIMP_RECTANGLE_TOOL_PROP_Y2:
|
2006-09-24 05:22:33 +08:00
|
|
|
|
private->y2 = g_value_get_int (value);
|
2005-09-04 03:48:22 +08:00
|
|
|
|
break;
|
2006-09-07 06:51:54 +08:00
|
|
|
|
case GIMP_RECTANGLE_TOOL_PROP_CONSTRAINT:
|
2006-12-14 05:49:09 +08:00
|
|
|
|
gimp_rectangle_tool_set_constraint (rectangle, g_value_get_enum (value));
|
2006-06-01 03:45:38 +08:00
|
|
|
|
break;
|
2005-09-04 03:48:22 +08:00
|
|
|
|
default:
|
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
gimp_rectangle_tool_get_property (GObject *object,
|
|
|
|
|
guint property_id,
|
|
|
|
|
GValue *value,
|
|
|
|
|
GParamSpec *pspec)
|
|
|
|
|
{
|
2006-09-24 05:22:33 +08:00
|
|
|
|
GimpRectangleTool *rectangle = GIMP_RECTANGLE_TOOL (object);
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
|
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (rectangle);
|
2005-09-04 03:48:22 +08:00
|
|
|
|
|
|
|
|
|
switch (property_id)
|
|
|
|
|
{
|
|
|
|
|
case GIMP_RECTANGLE_TOOL_PROP_X1:
|
2006-09-24 05:22:33 +08:00
|
|
|
|
g_value_set_int (value, private->x1);
|
2005-09-04 03:48:22 +08:00
|
|
|
|
break;
|
|
|
|
|
case GIMP_RECTANGLE_TOOL_PROP_Y1:
|
2006-09-24 05:22:33 +08:00
|
|
|
|
g_value_set_int (value, private->y1);
|
2005-09-04 03:48:22 +08:00
|
|
|
|
break;
|
|
|
|
|
case GIMP_RECTANGLE_TOOL_PROP_X2:
|
2006-09-24 05:22:33 +08:00
|
|
|
|
g_value_set_int (value, private->x2);
|
2005-09-04 03:48:22 +08:00
|
|
|
|
break;
|
|
|
|
|
case GIMP_RECTANGLE_TOOL_PROP_Y2:
|
2006-09-24 05:22:33 +08:00
|
|
|
|
g_value_set_int (value, private->y2);
|
2005-09-04 03:48:22 +08:00
|
|
|
|
break;
|
2006-09-07 06:51:54 +08:00
|
|
|
|
case GIMP_RECTANGLE_TOOL_PROP_CONSTRAINT:
|
2006-12-14 05:53:19 +08:00
|
|
|
|
g_value_set_enum (value, gimp_rectangle_tool_get_constraint (rectangle));
|
2006-06-01 03:45:38 +08:00
|
|
|
|
break;
|
2005-09-04 03:48:22 +08:00
|
|
|
|
default:
|
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2005-08-15 22:23:28 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
gimp_rectangle_tool_constructor (GObject *object)
|
|
|
|
|
{
|
2006-11-05 22:11:34 +08:00
|
|
|
|
GimpRectangleTool *rectangle = GIMP_RECTANGLE_TOOL (object);
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
GimpRectangleOptions *options;
|
2005-03-09 07:17:19 +08:00
|
|
|
|
|
2006-11-05 22:11:34 +08:00
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (object);
|
|
|
|
|
options = GIMP_RECTANGLE_TOOL_GET_OPTIONS (object);
|
2005-03-09 07:17:19 +08:00
|
|
|
|
|
2006-06-07 06:24:36 +08:00
|
|
|
|
g_object_get (options,
|
2006-09-27 04:55:40 +08:00
|
|
|
|
"guide", &private->guide,
|
2006-06-07 06:24:36 +08:00
|
|
|
|
NULL);
|
2005-03-09 07:17:19 +08:00
|
|
|
|
|
2006-11-05 22:11:34 +08:00
|
|
|
|
g_signal_connect_object (options, "notify",
|
|
|
|
|
G_CALLBACK (gimp_rectangle_tool_options_notify),
|
|
|
|
|
rectangle, 0);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
2006-05-24 01:37:18 +08:00
|
|
|
|
void
|
|
|
|
|
gimp_rectangle_tool_control (GimpTool *tool,
|
|
|
|
|
GimpToolAction action,
|
|
|
|
|
GimpDisplay *display)
|
|
|
|
|
{
|
|
|
|
|
GimpRectangleTool *rectangle = GIMP_RECTANGLE_TOOL (tool);
|
|
|
|
|
|
|
|
|
|
switch (action)
|
|
|
|
|
{
|
|
|
|
|
case GIMP_TOOL_ACTION_PAUSE:
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GIMP_TOOL_ACTION_RESUME:
|
|
|
|
|
gimp_rectangle_tool_configure (rectangle);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GIMP_TOOL_ACTION_HALT:
|
2006-06-06 01:14:16 +08:00
|
|
|
|
gimp_rectangle_tool_halt (rectangle);
|
2006-05-24 01:37:18 +08:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-08-15 22:23:28 +08:00
|
|
|
|
void
|
2005-03-03 02:18:19 +08:00
|
|
|
|
gimp_rectangle_tool_button_press (GimpTool *tool,
|
|
|
|
|
GimpCoords *coords,
|
|
|
|
|
guint32 time,
|
|
|
|
|
GdkModifierType state,
|
2006-03-29 01:55:52 +08:00
|
|
|
|
GimpDisplay *display)
|
2005-03-03 02:18:19 +08:00
|
|
|
|
{
|
2007-04-01 00:38:55 +08:00
|
|
|
|
GimpRectangleTool *rectangle;
|
|
|
|
|
GimpDrawTool *draw_tool;
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
GimpRectangleOptions *options;
|
|
|
|
|
GimpRectangleOptionsPrivate *options_private;
|
|
|
|
|
gint x, y;
|
|
|
|
|
gint snap_x, snap_y;
|
2006-06-11 00:49:07 +08:00
|
|
|
|
|
2005-08-15 22:23:28 +08:00
|
|
|
|
g_return_if_fail (GIMP_IS_RECTANGLE_TOOL (tool));
|
|
|
|
|
|
2007-04-01 00:38:55 +08:00
|
|
|
|
rectangle = GIMP_RECTANGLE_TOOL (tool);
|
|
|
|
|
draw_tool = GIMP_DRAW_TOOL (tool);
|
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (tool);
|
|
|
|
|
options = GIMP_RECTANGLE_TOOL_GET_OPTIONS (tool);
|
|
|
|
|
options_private = GIMP_RECTANGLE_OPTIONS_GET_PRIVATE (options);
|
2006-11-05 22:11:34 +08:00
|
|
|
|
|
|
|
|
|
x = ROUND (coords->x);
|
|
|
|
|
y = ROUND (coords->y);
|
2006-06-11 00:49:07 +08:00
|
|
|
|
|
2007-04-01 00:38:55 +08:00
|
|
|
|
gimp_draw_tool_pause (draw_tool);
|
2006-11-05 03:21:15 +08:00
|
|
|
|
|
2006-03-29 01:55:52 +08:00
|
|
|
|
if (display != tool->display)
|
2005-03-03 02:18:19 +08:00
|
|
|
|
{
|
|
|
|
|
if (gimp_draw_tool_is_active (draw_tool))
|
|
|
|
|
gimp_draw_tool_stop (draw_tool);
|
|
|
|
|
|
2006-11-16 04:45:43 +08:00
|
|
|
|
gimp_rectangle_tool_set_function (rectangle, RECT_CREATING);
|
|
|
|
|
|
2006-11-05 03:21:15 +08:00
|
|
|
|
g_object_set (rectangle,
|
2006-11-16 04:45:43 +08:00
|
|
|
|
"x1", x,
|
|
|
|
|
"y1", y,
|
|
|
|
|
"x2", x,
|
|
|
|
|
"y2", y,
|
2006-06-05 04:34:46 +08:00
|
|
|
|
NULL);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
2007-03-15 17:21:47 +08:00
|
|
|
|
gimp_rectangle_tool_start (rectangle, display);
|
2006-06-03 00:12:31 +08:00
|
|
|
|
}
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
2006-06-05 04:34:46 +08:00
|
|
|
|
/* save existing shape in case of cancellation */
|
2006-11-05 03:21:15 +08:00
|
|
|
|
private->saved_x1 = private->x1;
|
|
|
|
|
private->saved_y1 = private->y1;
|
|
|
|
|
private->saved_x2 = private->x2;
|
|
|
|
|
private->saved_y2 = private->y2;
|
|
|
|
|
|
2007-04-01 00:38:55 +08:00
|
|
|
|
private->saved_center_x = options_private->center_x;
|
|
|
|
|
private->saved_center_y = options_private->center_y;
|
2006-06-05 04:34:46 +08:00
|
|
|
|
|
2006-11-05 03:21:15 +08:00
|
|
|
|
switch (private->function)
|
2006-06-03 00:12:31 +08:00
|
|
|
|
{
|
2006-11-05 03:21:15 +08:00
|
|
|
|
case RECT_CREATING:
|
2006-06-11 00:49:07 +08:00
|
|
|
|
g_object_set (options,
|
|
|
|
|
"center-x", (gdouble) x,
|
|
|
|
|
"center-y", (gdouble) y,
|
|
|
|
|
NULL);
|
|
|
|
|
|
2005-09-04 03:48:22 +08:00
|
|
|
|
g_object_set (rectangle,
|
2006-06-11 00:49:07 +08:00
|
|
|
|
"x1", x,
|
|
|
|
|
"y1", y,
|
|
|
|
|
"x2", x,
|
|
|
|
|
"y2", y,
|
2006-01-22 02:20:26 +08:00
|
|
|
|
NULL);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
2006-11-05 03:21:15 +08:00
|
|
|
|
gimp_tool_control_set_snap_offsets (tool->control, 0, 0, 0, 0);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_UPPER_LEFT:
|
|
|
|
|
gimp_tool_control_set_snap_offsets (tool->control,
|
|
|
|
|
private->x1 - coords->x,
|
|
|
|
|
private->y1 - coords->y,
|
|
|
|
|
0, 0);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_UPPER_RIGHT:
|
|
|
|
|
gimp_tool_control_set_snap_offsets (tool->control,
|
|
|
|
|
private->x2 - coords->x,
|
|
|
|
|
private->y1 - coords->y,
|
|
|
|
|
0, 0);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_LOWER_LEFT:
|
|
|
|
|
gimp_tool_control_set_snap_offsets (tool->control,
|
|
|
|
|
private->x1 - coords->x,
|
|
|
|
|
private->y2 - coords->y,
|
|
|
|
|
0, 0);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_LOWER_RIGHT:
|
|
|
|
|
gimp_tool_control_set_snap_offsets (tool->control,
|
|
|
|
|
private->x2 - coords->x,
|
|
|
|
|
private->y2 - coords->y,
|
|
|
|
|
0, 0);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_LEFT:
|
|
|
|
|
gimp_tool_control_set_snap_offsets (tool->control,
|
|
|
|
|
private->x1 - coords->x, 0,
|
|
|
|
|
0, 0);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_RIGHT:
|
|
|
|
|
gimp_tool_control_set_snap_offsets (tool->control,
|
|
|
|
|
private->x2 - coords->x, 0,
|
|
|
|
|
0, 0);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_TOP:
|
|
|
|
|
gimp_tool_control_set_snap_offsets (tool->control,
|
|
|
|
|
0, private->y1 - coords->y,
|
|
|
|
|
0, 0);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_BOTTOM:
|
|
|
|
|
gimp_tool_control_set_snap_offsets (tool->control,
|
|
|
|
|
0, private->y2 - coords->y,
|
|
|
|
|
0, 0);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_MOVING:
|
|
|
|
|
gimp_tool_control_set_snap_offsets (tool->control,
|
|
|
|
|
private->x1 - coords->x,
|
|
|
|
|
private->y1 - coords->y,
|
|
|
|
|
private->x2 - private->x1,
|
|
|
|
|
private->y2 - private->y1);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
2005-03-03 02:18:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
2006-11-05 03:21:15 +08:00
|
|
|
|
gimp_tool_control_get_snap_offsets (tool->control,
|
|
|
|
|
&snap_x, &snap_y, NULL, NULL);
|
|
|
|
|
|
|
|
|
|
x += snap_x;
|
|
|
|
|
y += snap_y;
|
|
|
|
|
|
2006-09-24 05:22:33 +08:00
|
|
|
|
private->pressx = x;
|
|
|
|
|
private->pressy = y;
|
2006-06-03 06:24:55 +08:00
|
|
|
|
|
2006-11-05 03:21:15 +08:00
|
|
|
|
private->lastx = x;
|
|
|
|
|
private->lasty = y;
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
2007-05-02 17:14:35 +08:00
|
|
|
|
/* If the rectangle is being modified we want the center on fixed_center to be
|
|
|
|
|
* at the center of the currently existing rectangle, otherwise we want the
|
|
|
|
|
* point where the user clicked to be the center on fixed_center.
|
|
|
|
|
*/
|
|
|
|
|
if (private->function == RECT_CREATING)
|
|
|
|
|
{
|
|
|
|
|
private->center_x_on_fixed_center = private->pressx;
|
|
|
|
|
private->center_y_on_fixed_center = private->pressy;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
private->center_x_on_fixed_center = options_private->center_x;
|
|
|
|
|
private->center_y_on_fixed_center = options_private->center_y;
|
|
|
|
|
}
|
|
|
|
|
|
2007-06-30 00:37:50 +08:00
|
|
|
|
/* When the user toggles modifier keys, we want to keep track of what
|
|
|
|
|
* coordinates the "other side" should have. If we are creating a rectangle,
|
|
|
|
|
* use the current mouse coordinates as the coordinate of the "other side",
|
|
|
|
|
* otherwise use the immidiate "other side" for that.
|
|
|
|
|
*/
|
|
|
|
|
if (private->function == RECT_CREATING)
|
|
|
|
|
{
|
|
|
|
|
private->other_side_x = private->pressx;
|
|
|
|
|
private->other_side_y = private->pressy;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
gint other_side_x = 0;
|
|
|
|
|
gint other_side_y = 0;
|
|
|
|
|
|
|
|
|
|
gimp_rectangle_tool_get_other_side_coord (rectangle,
|
|
|
|
|
&other_side_x,
|
|
|
|
|
&other_side_y);
|
|
|
|
|
private->other_side_x = other_side_x;
|
|
|
|
|
private->other_side_y = other_side_y;
|
|
|
|
|
}
|
|
|
|
|
|
2005-03-03 02:18:19 +08:00
|
|
|
|
gimp_tool_control_activate (tool->control);
|
2006-11-05 03:21:15 +08:00
|
|
|
|
|
2007-04-01 00:38:55 +08:00
|
|
|
|
gimp_draw_tool_resume (draw_tool);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
2005-08-15 22:23:28 +08:00
|
|
|
|
void
|
2007-02-28 02:55:12 +08:00
|
|
|
|
gimp_rectangle_tool_button_release (GimpTool *tool,
|
|
|
|
|
GimpCoords *coords,
|
|
|
|
|
guint32 time,
|
|
|
|
|
GdkModifierType state,
|
|
|
|
|
GimpButtonReleaseType release_type,
|
|
|
|
|
GimpDisplay *display)
|
2005-03-03 02:18:19 +08:00
|
|
|
|
{
|
2006-11-05 22:11:34 +08:00
|
|
|
|
GimpRectangleTool *rectangle;
|
2006-06-03 06:24:55 +08:00
|
|
|
|
GimpRectangleToolPrivate *private;
|
2006-06-11 00:49:07 +08:00
|
|
|
|
GimpRectangleOptions *options;
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
2005-08-15 22:23:28 +08:00
|
|
|
|
g_return_if_fail (GIMP_IS_RECTANGLE_TOOL (tool));
|
|
|
|
|
|
2006-11-05 22:11:34 +08:00
|
|
|
|
rectangle = GIMP_RECTANGLE_TOOL (tool);
|
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (tool);
|
|
|
|
|
options = GIMP_RECTANGLE_TOOL_GET_OPTIONS (tool);
|
2006-06-11 00:49:07 +08:00
|
|
|
|
|
2006-11-05 03:21:15 +08:00
|
|
|
|
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
|
|
|
|
|
|
2005-03-03 02:18:19 +08:00
|
|
|
|
gimp_tool_control_halt (tool->control);
|
2006-06-03 06:24:55 +08:00
|
|
|
|
|
2006-11-05 03:21:15 +08:00
|
|
|
|
if (private->function == RECT_EXECUTING)
|
2006-03-29 01:55:52 +08:00
|
|
|
|
gimp_tool_pop_status (tool, display);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
2007-03-10 23:27:47 +08:00
|
|
|
|
switch (release_type)
|
2006-06-05 04:34:46 +08:00
|
|
|
|
{
|
2007-03-10 23:27:47 +08:00
|
|
|
|
case GIMP_BUTTON_RELEASE_NORMAL:
|
|
|
|
|
gimp_rectangle_tool_rectangle_changed (rectangle);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GIMP_BUTTON_RELEASE_CANCEL:
|
2006-06-11 00:49:07 +08:00
|
|
|
|
g_object_set (options,
|
2006-08-14 22:06:38 +08:00
|
|
|
|
"center-x", private->saved_center_x,
|
|
|
|
|
"center-y", private->saved_center_y,
|
|
|
|
|
NULL);
|
2006-06-11 00:49:07 +08:00
|
|
|
|
|
2006-06-05 04:34:46 +08:00
|
|
|
|
g_object_set (rectangle,
|
2006-08-14 22:06:38 +08:00
|
|
|
|
"x1", private->saved_x1,
|
|
|
|
|
"y1", private->saved_y1,
|
|
|
|
|
"x2", private->saved_x2,
|
|
|
|
|
"y2", private->saved_y2,
|
|
|
|
|
NULL);
|
2007-03-10 23:27:47 +08:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GIMP_BUTTON_RELEASE_CLICK:
|
|
|
|
|
if (gimp_rectangle_tool_execute (rectangle))
|
|
|
|
|
gimp_rectangle_tool_halt (rectangle);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GIMP_BUTTON_RELEASE_NO_MOTION:
|
|
|
|
|
break;
|
2006-06-05 04:34:46 +08:00
|
|
|
|
}
|
2006-11-05 03:21:15 +08:00
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
/* We must update this. */
|
|
|
|
|
private->center_x_on_fixed_center = (private->x1 + private->x2) / 2;
|
|
|
|
|
private->center_y_on_fixed_center = (private->y1 + private->y2) / 2;
|
|
|
|
|
|
2006-11-05 03:21:15 +08:00
|
|
|
|
gimp_tool_control_set_snap_offsets (tool->control, 0, 0, 0, 0);
|
|
|
|
|
|
|
|
|
|
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
|
2005-03-03 02:18:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
|
2005-08-15 22:23:28 +08:00
|
|
|
|
void
|
2005-03-03 02:18:19 +08:00
|
|
|
|
gimp_rectangle_tool_motion (GimpTool *tool,
|
|
|
|
|
GimpCoords *coords,
|
|
|
|
|
guint32 time,
|
|
|
|
|
GdkModifierType state,
|
2006-03-29 01:55:52 +08:00
|
|
|
|
GimpDisplay *display)
|
2005-03-03 02:18:19 +08:00
|
|
|
|
{
|
2007-04-01 00:38:55 +08:00
|
|
|
|
GimpRectangleTool *rectangle;
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
GimpRectangleOptions *options;
|
|
|
|
|
GimpRectangleOptionsPrivate *options_private;
|
2007-07-09 05:57:22 +08:00
|
|
|
|
gint current_x;
|
|
|
|
|
gint current_y;
|
2007-04-01 00:38:55 +08:00
|
|
|
|
gint snap_x, snap_y;
|
2005-08-15 22:23:28 +08:00
|
|
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_RECTANGLE_TOOL (tool));
|
|
|
|
|
|
2007-04-01 00:38:55 +08:00
|
|
|
|
rectangle = GIMP_RECTANGLE_TOOL (tool);
|
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (tool);
|
|
|
|
|
options = GIMP_RECTANGLE_TOOL_GET_OPTIONS (tool);
|
|
|
|
|
options_private = GIMP_RECTANGLE_OPTIONS_GET_PRIVATE (options);
|
2006-06-03 06:24:55 +08:00
|
|
|
|
|
2006-06-07 03:25:53 +08:00
|
|
|
|
/* This is the only case when the motion events should be ignored --
|
|
|
|
|
* we're just waiting for the button release event to execute.
|
|
|
|
|
*/
|
2006-11-05 03:21:15 +08:00
|
|
|
|
if (private->function == RECT_EXECUTING)
|
2005-03-03 02:18:19 +08:00
|
|
|
|
return;
|
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
current_x = ROUND (coords->x);
|
|
|
|
|
current_y = ROUND (coords->y);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
/* Handle snapping. */
|
2006-11-05 03:21:15 +08:00
|
|
|
|
gimp_tool_control_get_snap_offsets (tool->control,
|
|
|
|
|
&snap_x, &snap_y, NULL, NULL);
|
2007-07-09 05:57:22 +08:00
|
|
|
|
current_x += snap_x;
|
|
|
|
|
current_y += snap_y;
|
2006-11-05 03:21:15 +08:00
|
|
|
|
|
2006-11-05 03:50:13 +08:00
|
|
|
|
/* If there have been no changes... return */
|
2007-07-09 05:57:22 +08:00
|
|
|
|
if (private->lastx == current_x && private->lasty == current_y)
|
2006-11-05 03:50:13 +08:00
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
|
|
|
|
|
|
2007-01-27 06:21:20 +08:00
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
/* This is the core rectangle shape updating function: */
|
|
|
|
|
gimp_rectangle_tool_update_with_coord (rectangle,
|
|
|
|
|
current_x,
|
|
|
|
|
current_y);
|
2006-06-05 19:18:43 +08:00
|
|
|
|
|
2005-03-03 02:18:19 +08:00
|
|
|
|
/* recalculate the coordinates for rectangle_draw based on the new values */
|
2005-10-20 05:13:25 +08:00
|
|
|
|
gimp_rectangle_tool_configure (rectangle);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
2006-11-05 03:21:15 +08:00
|
|
|
|
if (private->function != RECT_MOVING &&
|
|
|
|
|
private->function != RECT_EXECUTING)
|
2005-03-03 02:18:19 +08:00
|
|
|
|
{
|
2006-08-14 22:17:18 +08:00
|
|
|
|
gint w, h;
|
2006-06-01 03:45:38 +08:00
|
|
|
|
|
2006-03-29 01:55:52 +08:00
|
|
|
|
gimp_tool_pop_status (tool, display);
|
2006-08-14 22:17:18 +08:00
|
|
|
|
|
2006-11-06 00:36:15 +08:00
|
|
|
|
w = private->x2 - private->x1;
|
|
|
|
|
h = private->y2 - private->y1;
|
2006-08-14 22:17:18 +08:00
|
|
|
|
|
|
|
|
|
if (w > 0 && h > 0)
|
|
|
|
|
gimp_tool_push_status_coords (tool, display,
|
2007-01-21 09:24:51 +08:00
|
|
|
|
_("Rectangle: "), w, " × ", h, NULL);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
2006-11-05 03:21:15 +08:00
|
|
|
|
if (private->function == RECT_CREATING)
|
2005-06-03 06:48:43 +08:00
|
|
|
|
{
|
2006-11-16 04:45:43 +08:00
|
|
|
|
GimpRectangleFunction function = RECT_CREATING;
|
2007-07-09 05:57:22 +08:00
|
|
|
|
gint dx = current_x - private->lastx;
|
|
|
|
|
gint dy = current_y - private->lasty;
|
2006-11-05 03:21:15 +08:00
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
/* When the user starts to move the cursor, set the current function to
|
|
|
|
|
* one of the corner-grabbed functions, depending on in what direction
|
|
|
|
|
* the user starts dragging the rectangle.
|
|
|
|
|
*/
|
|
|
|
|
if (dx < 0)
|
|
|
|
|
{
|
|
|
|
|
function = dy < 0 ?
|
|
|
|
|
RECT_RESIZING_UPPER_LEFT :
|
|
|
|
|
RECT_RESIZING_LOWER_LEFT;
|
|
|
|
|
}
|
|
|
|
|
else if (dx > 0)
|
|
|
|
|
{
|
|
|
|
|
function = dy < 0 ?
|
|
|
|
|
RECT_RESIZING_UPPER_RIGHT :
|
|
|
|
|
RECT_RESIZING_LOWER_RIGHT;
|
|
|
|
|
}
|
|
|
|
|
else if (dy < 0)
|
|
|
|
|
{
|
|
|
|
|
function = dx < 0 ?
|
|
|
|
|
RECT_RESIZING_UPPER_LEFT :
|
|
|
|
|
RECT_RESIZING_UPPER_RIGHT;
|
|
|
|
|
}
|
|
|
|
|
else if (dy > 0)
|
|
|
|
|
{
|
|
|
|
|
function = dx < 0 ?
|
|
|
|
|
RECT_RESIZING_LOWER_LEFT :
|
|
|
|
|
RECT_RESIZING_LOWER_RIGHT;
|
|
|
|
|
}
|
2007-02-28 21:08:09 +08:00
|
|
|
|
|
2006-11-16 04:45:43 +08:00
|
|
|
|
gimp_rectangle_tool_set_function (rectangle, function);
|
2005-06-03 06:48:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
gimp_rectangle_tool_update_options (rectangle, display);
|
|
|
|
|
|
|
|
|
|
private->lastx = current_x;
|
|
|
|
|
private->lasty = current_y;
|
|
|
|
|
|
2005-03-03 02:18:19 +08:00
|
|
|
|
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
|
|
|
|
|
}
|
|
|
|
|
|
2006-09-24 06:32:35 +08:00
|
|
|
|
void
|
2007-07-09 05:57:22 +08:00
|
|
|
|
|
2006-09-24 06:32:35 +08:00
|
|
|
|
gimp_rectangle_tool_active_modifier_key (GimpTool *tool,
|
|
|
|
|
GdkModifierType key,
|
|
|
|
|
gboolean press,
|
|
|
|
|
GdkModifierType state,
|
|
|
|
|
GimpDisplay *display)
|
|
|
|
|
{
|
2007-07-09 05:57:22 +08:00
|
|
|
|
GimpDrawTool *draw_tool;
|
2007-04-01 00:38:55 +08:00
|
|
|
|
GimpRectangleTool *rectangle;
|
|
|
|
|
GimpRectangleOptions *options;
|
|
|
|
|
GimpRectangleOptionsPrivate *options_private;
|
2007-06-30 00:37:50 +08:00
|
|
|
|
GimpRectangleToolPrivate *private;
|
2006-11-05 22:11:34 +08:00
|
|
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_RECTANGLE_TOOL (tool));
|
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
draw_tool = GIMP_DRAW_TOOL (tool);
|
2007-04-01 00:38:55 +08:00
|
|
|
|
rectangle = GIMP_RECTANGLE_TOOL (tool);
|
2007-06-30 00:37:50 +08:00
|
|
|
|
private = gimp_rectangle_tool_get_private (rectangle);
|
2007-04-01 00:38:55 +08:00
|
|
|
|
options = GIMP_RECTANGLE_TOOL_GET_OPTIONS (tool);
|
|
|
|
|
options_private = GIMP_RECTANGLE_OPTIONS_GET_PRIVATE (options);
|
2006-09-24 06:32:35 +08:00
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
gimp_draw_tool_pause (draw_tool);
|
|
|
|
|
|
2006-09-24 06:32:35 +08:00
|
|
|
|
if (key == GDK_SHIFT_MASK)
|
|
|
|
|
{
|
2007-07-08 21:38:58 +08:00
|
|
|
|
/* Here we want to handle manualy when to update the rectangle, so we
|
|
|
|
|
* don't want gimp_rectangle_tool_options_notify to do anything.
|
|
|
|
|
*/
|
|
|
|
|
g_signal_handlers_block_by_func (options,
|
|
|
|
|
gimp_rectangle_tool_options_notify,
|
|
|
|
|
rectangle);
|
|
|
|
|
|
2006-09-24 06:32:35 +08:00
|
|
|
|
g_object_set (options,
|
2007-04-01 00:38:55 +08:00
|
|
|
|
"fixed-aspect", ! options_private->fixed_aspect,
|
2006-09-24 06:32:35 +08:00
|
|
|
|
NULL);
|
2007-07-08 21:38:58 +08:00
|
|
|
|
|
|
|
|
|
g_signal_handlers_unblock_by_func (options,
|
|
|
|
|
gimp_rectangle_tool_options_notify,
|
|
|
|
|
rectangle);
|
2006-09-24 06:32:35 +08:00
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
/* Only change the shape if the mouse is still down (i.e. the user is
|
|
|
|
|
* still editing the rectangle.
|
2007-06-30 00:37:50 +08:00
|
|
|
|
*/
|
2007-07-09 05:57:22 +08:00
|
|
|
|
if (state & GDK_BUTTON1_MASK)
|
2007-06-30 00:37:50 +08:00
|
|
|
|
{
|
2007-07-09 05:57:22 +08:00
|
|
|
|
gimp_rectangle_tool_update_with_coord (rectangle,
|
|
|
|
|
private->lastx,
|
|
|
|
|
private->lasty);
|
2007-06-30 00:37:50 +08:00
|
|
|
|
|
|
|
|
|
gimp_rectangle_tool_configure (rectangle);
|
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
gimp_rectangle_tool_rectangle_changed (rectangle);
|
2007-06-30 00:37:50 +08:00
|
|
|
|
}
|
2007-07-09 05:57:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (key == GDK_CONTROL_MASK)
|
|
|
|
|
{
|
2007-06-30 00:37:50 +08:00
|
|
|
|
|
2006-09-24 06:32:35 +08:00
|
|
|
|
g_object_set (options,
|
2007-04-01 00:38:55 +08:00
|
|
|
|
"fixed-center", ! options_private->fixed_center,
|
2006-09-24 06:32:35 +08:00
|
|
|
|
NULL);
|
|
|
|
|
|
2007-04-01 00:38:55 +08:00
|
|
|
|
if (options_private->fixed_center)
|
2006-09-24 06:32:35 +08:00
|
|
|
|
{
|
|
|
|
|
g_object_set (options,
|
2007-07-09 05:57:22 +08:00
|
|
|
|
"center-x", (gdouble) private->center_x_on_fixed_center,
|
|
|
|
|
"center-y", (gdouble) private->center_y_on_fixed_center,
|
2006-09-24 06:32:35 +08:00
|
|
|
|
NULL);
|
2007-07-09 05:57:22 +08:00
|
|
|
|
|
|
|
|
|
gimp_rectangle_tool_update_with_coord (rectangle,
|
|
|
|
|
private->lastx,
|
|
|
|
|
private->lasty);
|
|
|
|
|
|
|
|
|
|
gimp_rectangle_tool_configure (rectangle);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gimp_rectangle_tool_rectangle_changed (rectangle);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (state & GDK_BUTTON1_MASK)
|
|
|
|
|
{
|
|
|
|
|
/* If we are leaving fixed_center mode we want to set the "other side"
|
|
|
|
|
* where it should be. Don't do anything if we came here by a mouse-click
|
|
|
|
|
* though, since then the user has confirmed the shape and we don't want
|
|
|
|
|
* to modify it afterwards.
|
|
|
|
|
*/
|
|
|
|
|
gimp_rectangle_tool_set_other_side_coord (rectangle,
|
|
|
|
|
private->other_side_x,
|
|
|
|
|
private->other_side_y);
|
|
|
|
|
|
|
|
|
|
gimp_rectangle_tool_rectangle_changed (rectangle);
|
|
|
|
|
|
2006-09-24 06:32:35 +08:00
|
|
|
|
}
|
2007-07-09 05:57:22 +08:00
|
|
|
|
|
2006-09-24 06:32:35 +08:00
|
|
|
|
}
|
2007-07-09 05:57:22 +08:00
|
|
|
|
|
|
|
|
|
gimp_draw_tool_resume (draw_tool);
|
2006-09-24 06:32:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
2007-01-27 06:21:20 +08:00
|
|
|
|
static void swap_ints (gint *i,
|
|
|
|
|
gint *j)
|
|
|
|
|
{
|
|
|
|
|
gint tmp;
|
|
|
|
|
|
|
|
|
|
tmp = *i;
|
|
|
|
|
*i = *j;
|
|
|
|
|
*j = tmp;
|
|
|
|
|
}
|
|
|
|
|
|
2007-04-01 00:38:55 +08:00
|
|
|
|
/* gimp_rectangle_tool_check_function() is needed to deal with
|
2006-06-12 07:59:33 +08:00
|
|
|
|
* situations where the user drags a corner or edge across one of the
|
|
|
|
|
* existing edges, thereby changing its function. Ugh.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
2007-07-09 05:57:22 +08:00
|
|
|
|
gimp_rectangle_tool_check_function (GimpRectangleTool *rectangle)
|
|
|
|
|
|
2006-06-12 07:59:33 +08:00
|
|
|
|
{
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
2006-11-16 04:45:43 +08:00
|
|
|
|
GimpRectangleFunction function;
|
2006-06-12 07:59:33 +08:00
|
|
|
|
|
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (rectangle);
|
|
|
|
|
|
2006-11-05 03:21:15 +08:00
|
|
|
|
function = private->function;
|
2006-06-12 07:59:33 +08:00
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
if (private->x2 < private->x1)
|
2006-06-12 07:59:33 +08:00
|
|
|
|
{
|
2007-07-09 05:57:22 +08:00
|
|
|
|
swap_ints (&private->x1, &private->x2);
|
2007-01-27 06:21:20 +08:00
|
|
|
|
switch (function)
|
2006-06-12 07:59:33 +08:00
|
|
|
|
{
|
2007-01-27 06:21:20 +08:00
|
|
|
|
case RECT_RESIZING_UPPER_LEFT:
|
|
|
|
|
function = RECT_RESIZING_UPPER_RIGHT;
|
|
|
|
|
break;
|
|
|
|
|
case RECT_RESIZING_UPPER_RIGHT:
|
|
|
|
|
function = RECT_RESIZING_UPPER_LEFT;
|
|
|
|
|
break;
|
|
|
|
|
case RECT_RESIZING_LOWER_LEFT:
|
|
|
|
|
function = RECT_RESIZING_LOWER_RIGHT;
|
|
|
|
|
break;
|
|
|
|
|
case RECT_RESIZING_LOWER_RIGHT:
|
|
|
|
|
function = RECT_RESIZING_LOWER_LEFT;
|
|
|
|
|
break;
|
|
|
|
|
case RECT_RESIZING_LEFT:
|
|
|
|
|
function = RECT_RESIZING_RIGHT;
|
|
|
|
|
break;
|
|
|
|
|
case RECT_RESIZING_RIGHT:
|
|
|
|
|
function = RECT_RESIZING_LEFT;
|
|
|
|
|
break;
|
|
|
|
|
/* avoid annoying warnings about unhandled enums */
|
|
|
|
|
default:
|
|
|
|
|
break;
|
2006-06-12 07:59:33 +08:00
|
|
|
|
}
|
2007-01-27 06:21:20 +08:00
|
|
|
|
}
|
2006-06-12 07:59:33 +08:00
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
if (private->y2 < private->y1)
|
2007-01-27 06:21:20 +08:00
|
|
|
|
{
|
2007-07-09 05:57:22 +08:00
|
|
|
|
swap_ints (&private->y1, &private->y2);
|
2007-01-27 06:21:20 +08:00
|
|
|
|
switch (function)
|
2006-06-12 07:59:33 +08:00
|
|
|
|
{
|
2007-01-27 06:21:20 +08:00
|
|
|
|
case RECT_RESIZING_UPPER_LEFT:
|
|
|
|
|
function = RECT_RESIZING_LOWER_LEFT;
|
|
|
|
|
break;
|
|
|
|
|
case RECT_RESIZING_UPPER_RIGHT:
|
|
|
|
|
function = RECT_RESIZING_LOWER_RIGHT;
|
|
|
|
|
break;
|
|
|
|
|
case RECT_RESIZING_LOWER_LEFT:
|
|
|
|
|
function = RECT_RESIZING_UPPER_LEFT;
|
|
|
|
|
break;
|
|
|
|
|
case RECT_RESIZING_LOWER_RIGHT:
|
|
|
|
|
function = RECT_RESIZING_UPPER_RIGHT;
|
|
|
|
|
break;
|
|
|
|
|
case RECT_RESIZING_TOP:
|
|
|
|
|
function = RECT_RESIZING_BOTTOM;
|
|
|
|
|
break;
|
|
|
|
|
case RECT_RESIZING_BOTTOM:
|
|
|
|
|
function = RECT_RESIZING_TOP;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
2006-06-12 07:59:33 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-11-16 04:45:43 +08:00
|
|
|
|
gimp_rectangle_tool_set_function (rectangle, function);
|
2006-06-12 07:59:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
2005-08-15 22:23:28 +08:00
|
|
|
|
gboolean
|
2005-03-03 02:18:19 +08:00
|
|
|
|
gimp_rectangle_tool_key_press (GimpTool *tool,
|
|
|
|
|
GdkEventKey *kevent,
|
2006-03-29 01:55:52 +08:00
|
|
|
|
GimpDisplay *display)
|
2005-03-03 02:18:19 +08:00
|
|
|
|
{
|
2006-11-05 03:21:15 +08:00
|
|
|
|
GimpRectangleTool *rectangle;
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
2007-01-24 16:40:24 +08:00
|
|
|
|
gint dx = 0;
|
|
|
|
|
gint dy = 0;
|
2007-07-09 05:57:22 +08:00
|
|
|
|
gint new_x = 0;
|
|
|
|
|
gint new_y = 0;
|
2005-08-15 22:23:28 +08:00
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (GIMP_IS_RECTANGLE_TOOL (tool), FALSE);
|
|
|
|
|
|
2006-03-29 01:55:52 +08:00
|
|
|
|
if (display != tool->display)
|
2005-03-03 02:18:19 +08:00
|
|
|
|
return FALSE;
|
|
|
|
|
|
2007-01-24 16:40:24 +08:00
|
|
|
|
rectangle = GIMP_RECTANGLE_TOOL (tool);
|
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (tool);
|
|
|
|
|
|
2005-03-03 02:18:19 +08:00
|
|
|
|
switch (kevent->keyval)
|
|
|
|
|
{
|
|
|
|
|
case GDK_Up:
|
2007-01-24 16:40:24 +08:00
|
|
|
|
dy = -1;
|
2005-03-03 02:18:19 +08:00
|
|
|
|
break;
|
|
|
|
|
case GDK_Left:
|
2007-01-24 16:40:24 +08:00
|
|
|
|
dx = -1;
|
2005-03-03 02:18:19 +08:00
|
|
|
|
break;
|
|
|
|
|
case GDK_Right:
|
2007-01-24 16:40:24 +08:00
|
|
|
|
dx = 1;
|
2005-03-03 02:18:19 +08:00
|
|
|
|
break;
|
|
|
|
|
case GDK_Down:
|
2007-01-24 16:40:24 +08:00
|
|
|
|
dy = 1;
|
2005-03-03 02:18:19 +08:00
|
|
|
|
break;
|
2007-01-24 15:12:42 +08:00
|
|
|
|
|
2005-03-03 02:18:19 +08:00
|
|
|
|
case GDK_KP_Enter:
|
|
|
|
|
case GDK_Return:
|
2006-06-06 01:14:16 +08:00
|
|
|
|
if (gimp_rectangle_tool_execute (rectangle))
|
|
|
|
|
gimp_rectangle_tool_halt (rectangle);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
|
|
case GDK_Escape:
|
2006-06-06 01:14:16 +08:00
|
|
|
|
gimp_rectangle_tool_cancel (rectangle);
|
|
|
|
|
gimp_rectangle_tool_halt (rectangle);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If the shift key is down, move by an accelerated increment */
|
2007-01-24 15:12:42 +08:00
|
|
|
|
if (kevent->state & GDK_SHIFT_MASK)
|
2005-03-03 02:18:19 +08:00
|
|
|
|
{
|
2007-01-24 16:40:24 +08:00
|
|
|
|
dx *= ARROW_VELOCITY;
|
|
|
|
|
dy *= ARROW_VELOCITY;
|
|
|
|
|
}
|
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
gimp_tool_control_set_snap_offsets (GIMP_TOOL (rectangle)->control,
|
|
|
|
|
0, 0, 0, 0);
|
|
|
|
|
|
2007-01-24 16:40:24 +08:00
|
|
|
|
/* Resize the rectangle if the mouse is over a handle, otherwise move it */
|
|
|
|
|
switch (private->function)
|
|
|
|
|
{
|
2007-07-09 05:57:22 +08:00
|
|
|
|
case RECT_MOVING:
|
2007-01-24 16:40:24 +08:00
|
|
|
|
case RECT_RESIZING_UPPER_LEFT:
|
2007-07-09 05:57:22 +08:00
|
|
|
|
new_x = private->x1 + dx;
|
|
|
|
|
new_y = private->y1 + dy;
|
|
|
|
|
private->lastx = new_x;
|
|
|
|
|
private->lasty = new_y;
|
2007-01-24 16:40:24 +08:00
|
|
|
|
break;
|
|
|
|
|
case RECT_RESIZING_UPPER_RIGHT:
|
2007-07-09 05:57:22 +08:00
|
|
|
|
new_x = private->x2 + dx;
|
|
|
|
|
new_y = private->y1 + dy;
|
|
|
|
|
private->lastx = new_x;
|
|
|
|
|
private->lasty = new_y;
|
2007-01-24 16:40:24 +08:00
|
|
|
|
break;
|
|
|
|
|
case RECT_RESIZING_LOWER_LEFT:
|
2007-07-09 05:57:22 +08:00
|
|
|
|
new_x = private->x1 + dx;
|
|
|
|
|
new_y = private->y2 + dy;
|
|
|
|
|
private->lastx = new_x;
|
|
|
|
|
private->lasty = new_y;
|
2007-01-24 16:40:24 +08:00
|
|
|
|
break;
|
|
|
|
|
case RECT_RESIZING_LOWER_RIGHT:
|
2007-07-09 05:57:22 +08:00
|
|
|
|
new_x = private->x2 + dx;
|
|
|
|
|
new_y = private->y2 + dy;
|
|
|
|
|
private->lastx = new_x;
|
|
|
|
|
private->lasty = new_y;
|
2007-01-24 16:40:24 +08:00
|
|
|
|
break;
|
|
|
|
|
case RECT_RESIZING_LEFT:
|
2007-07-09 05:57:22 +08:00
|
|
|
|
new_x = private->x1 + dx;
|
|
|
|
|
private->lastx = new_x;
|
2007-01-24 16:40:24 +08:00
|
|
|
|
break;
|
|
|
|
|
case RECT_RESIZING_RIGHT:
|
2007-07-09 05:57:22 +08:00
|
|
|
|
new_x = private->x2 + dx;
|
|
|
|
|
private->lastx = new_x;
|
2007-01-24 16:40:24 +08:00
|
|
|
|
break;
|
|
|
|
|
case RECT_RESIZING_TOP:
|
2007-07-09 05:57:22 +08:00
|
|
|
|
new_y = private->y1 + dy;
|
|
|
|
|
private->lasty = new_y;
|
2007-01-24 16:40:24 +08:00
|
|
|
|
break;
|
|
|
|
|
case RECT_RESIZING_BOTTOM:
|
2007-07-09 05:57:22 +08:00
|
|
|
|
new_y = private->y2 + dy;
|
|
|
|
|
private->lasty = new_y;
|
2007-01-24 16:40:24 +08:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
2007-07-09 05:57:22 +08:00
|
|
|
|
return TRUE;
|
2005-03-03 02:18:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
|
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
gimp_rectangle_tool_update_with_coord (rectangle,
|
|
|
|
|
new_x,
|
|
|
|
|
new_y);
|
2007-01-27 06:21:20 +08:00
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
private->center_x_on_fixed_center = (private->x1 + private->x2) / 2;
|
|
|
|
|
private->center_y_on_fixed_center = (private->y1 + private->y2) / 2;
|
2007-01-27 06:21:20 +08:00
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
/* g_object_set (rectangle, */
|
|
|
|
|
/* "x1", private->x1, */
|
|
|
|
|
/* "y1", private->y1, */
|
|
|
|
|
/* "x2", private->x2, */
|
|
|
|
|
/* "y2", private->y2, */
|
|
|
|
|
/* NULL); */
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
2005-10-20 05:13:25 +08:00
|
|
|
|
gimp_rectangle_tool_configure (rectangle);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
gimp_rectangle_tool_update_options (rectangle, tool->display);
|
2007-03-09 15:16:18 +08:00
|
|
|
|
|
2005-03-03 02:18:19 +08:00
|
|
|
|
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
|
|
|
|
|
|
2007-03-08 14:52:41 +08:00
|
|
|
|
gimp_rectangle_tool_rectangle_changed (rectangle);
|
|
|
|
|
|
2007-01-24 16:40:24 +08:00
|
|
|
|
/* Evil hack to suppress oper updates. We do this because we don't
|
|
|
|
|
* want the rectangle tool to change function while the rectangle
|
|
|
|
|
* is being resized or moved using the keyboard.
|
|
|
|
|
*/
|
|
|
|
|
private->suppress_updates = 2;
|
|
|
|
|
|
2005-03-03 02:18:19 +08:00
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2005-08-15 22:23:28 +08:00
|
|
|
|
void
|
2005-03-03 02:18:19 +08:00
|
|
|
|
gimp_rectangle_tool_oper_update (GimpTool *tool,
|
|
|
|
|
GimpCoords *coords,
|
|
|
|
|
GdkModifierType state,
|
2006-03-25 22:23:09 +08:00
|
|
|
|
gboolean proximity,
|
2006-03-29 01:55:52 +08:00
|
|
|
|
GimpDisplay *display)
|
2005-03-03 02:18:19 +08:00
|
|
|
|
{
|
2006-06-03 06:24:55 +08:00
|
|
|
|
GimpRectangleToolPrivate *private;
|
2006-11-05 03:21:15 +08:00
|
|
|
|
GimpDrawTool *draw_tool;
|
|
|
|
|
gint function;
|
2005-08-15 22:23:28 +08:00
|
|
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_RECTANGLE_TOOL (tool));
|
2006-06-05 19:18:43 +08:00
|
|
|
|
|
2006-11-05 03:21:15 +08:00
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (tool);
|
|
|
|
|
draw_tool = GIMP_DRAW_TOOL (tool);
|
2005-08-15 22:23:28 +08:00
|
|
|
|
|
2006-03-29 01:55:52 +08:00
|
|
|
|
if (tool->display != display)
|
2006-11-16 04:45:43 +08:00
|
|
|
|
return;
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
2007-01-24 16:40:24 +08:00
|
|
|
|
if (private->suppress_updates)
|
|
|
|
|
{
|
|
|
|
|
private->suppress_updates--;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2006-11-08 15:22:42 +08:00
|
|
|
|
if (coords->x > private->x1 && coords->x < private->x2 &&
|
|
|
|
|
coords->y > private->y1 && coords->y < private->y2)
|
2005-03-10 06:22:38 +08:00
|
|
|
|
{
|
2007-07-01 02:13:41 +08:00
|
|
|
|
GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (tool->display->shell);
|
|
|
|
|
gint w = private->x2 - private->x1;
|
|
|
|
|
gint h = private->y2 - private->y1;
|
|
|
|
|
gint tw = w * shell->scale_x;
|
|
|
|
|
gint th = h * shell->scale_y;
|
2006-11-08 06:07:22 +08:00
|
|
|
|
|
|
|
|
|
if (gimp_draw_tool_on_handle (draw_tool, display,
|
|
|
|
|
coords->x, coords->y,
|
|
|
|
|
GIMP_HANDLE_SQUARE,
|
|
|
|
|
private->x1, private->y1,
|
|
|
|
|
private->handle_w, private->handle_h,
|
|
|
|
|
GTK_ANCHOR_NORTH_WEST,
|
|
|
|
|
FALSE))
|
|
|
|
|
{
|
|
|
|
|
function = RECT_RESIZING_UPPER_LEFT;
|
|
|
|
|
}
|
|
|
|
|
else if (gimp_draw_tool_on_handle (draw_tool, display,
|
|
|
|
|
coords->x, coords->y,
|
|
|
|
|
GIMP_HANDLE_SQUARE,
|
|
|
|
|
private->x2, private->y2,
|
|
|
|
|
private->handle_w, private->handle_h,
|
|
|
|
|
GTK_ANCHOR_SOUTH_EAST,
|
|
|
|
|
FALSE))
|
|
|
|
|
{
|
|
|
|
|
function = RECT_RESIZING_LOWER_RIGHT;
|
|
|
|
|
}
|
|
|
|
|
else if (gimp_draw_tool_on_handle (draw_tool, display,
|
|
|
|
|
coords->x, coords->y,
|
|
|
|
|
GIMP_HANDLE_SQUARE,
|
|
|
|
|
private->x2, private->y1,
|
|
|
|
|
private->handle_w, private->handle_h,
|
|
|
|
|
GTK_ANCHOR_NORTH_EAST,
|
|
|
|
|
FALSE))
|
|
|
|
|
{
|
|
|
|
|
function = RECT_RESIZING_UPPER_RIGHT;
|
|
|
|
|
}
|
|
|
|
|
else if (gimp_draw_tool_on_handle (draw_tool, display,
|
|
|
|
|
coords->x, coords->y,
|
|
|
|
|
GIMP_HANDLE_SQUARE,
|
|
|
|
|
private->x1, private->y2,
|
|
|
|
|
private->handle_w, private->handle_h,
|
|
|
|
|
GTK_ANCHOR_SOUTH_WEST,
|
|
|
|
|
FALSE))
|
|
|
|
|
{
|
|
|
|
|
function = RECT_RESIZING_LOWER_LEFT;
|
|
|
|
|
}
|
2007-07-01 02:13:41 +08:00
|
|
|
|
else if (gimp_draw_tool_on_handle (draw_tool, display,
|
|
|
|
|
coords->x, coords->y,
|
|
|
|
|
GIMP_HANDLE_SQUARE,
|
|
|
|
|
private->x1, private->y1 + h / 2,
|
|
|
|
|
private->handle_w, private->left_and_right_handle_h,
|
|
|
|
|
GTK_ANCHOR_WEST,
|
|
|
|
|
FALSE))
|
2006-11-08 06:07:22 +08:00
|
|
|
|
{
|
|
|
|
|
function = RECT_RESIZING_LEFT;
|
|
|
|
|
}
|
2007-07-01 02:13:41 +08:00
|
|
|
|
else if (gimp_draw_tool_on_handle (draw_tool, display,
|
|
|
|
|
coords->x, coords->y,
|
|
|
|
|
GIMP_HANDLE_SQUARE,
|
|
|
|
|
private->x2, private->y1 + h / 2,
|
|
|
|
|
private->handle_w, private->left_and_right_handle_h,
|
|
|
|
|
GTK_ANCHOR_EAST,
|
|
|
|
|
FALSE))
|
2006-11-08 06:07:22 +08:00
|
|
|
|
{
|
|
|
|
|
function = RECT_RESIZING_RIGHT;
|
|
|
|
|
}
|
2007-07-01 02:13:41 +08:00
|
|
|
|
else if (gimp_draw_tool_on_handle (draw_tool, display,
|
|
|
|
|
coords->x, coords->y,
|
|
|
|
|
GIMP_HANDLE_SQUARE,
|
|
|
|
|
private->x1 + w / 2, private->y1,
|
|
|
|
|
private->top_and_bottom_handle_w, private->handle_h,
|
|
|
|
|
GTK_ANCHOR_NORTH,
|
|
|
|
|
FALSE))
|
2006-11-08 06:07:22 +08:00
|
|
|
|
{
|
|
|
|
|
function = RECT_RESIZING_TOP;
|
|
|
|
|
}
|
2007-07-01 02:13:41 +08:00
|
|
|
|
else if (gimp_draw_tool_on_handle (draw_tool, display,
|
|
|
|
|
coords->x, coords->y,
|
|
|
|
|
GIMP_HANDLE_SQUARE,
|
|
|
|
|
private->x1 + w / 2, private->y2,
|
|
|
|
|
private->top_and_bottom_handle_w, private->handle_h,
|
|
|
|
|
GTK_ANCHOR_SOUTH,
|
|
|
|
|
FALSE))
|
2006-11-08 06:07:22 +08:00
|
|
|
|
{
|
|
|
|
|
function = RECT_RESIZING_BOTTOM;
|
|
|
|
|
}
|
2007-07-01 02:13:41 +08:00
|
|
|
|
else if (gimp_draw_tool_on_handle (draw_tool, display,
|
|
|
|
|
coords->x, coords->y,
|
|
|
|
|
GIMP_HANDLE_SQUARE,
|
|
|
|
|
private->x1 + w / 2,
|
|
|
|
|
private->y1 + h / 2,
|
|
|
|
|
tw - private->handle_w * 2,
|
|
|
|
|
th - private->handle_h * 2,
|
|
|
|
|
GTK_ANCHOR_CENTER,
|
|
|
|
|
FALSE))
|
2006-11-08 06:07:22 +08:00
|
|
|
|
{
|
|
|
|
|
function = RECT_MOVING;
|
|
|
|
|
}
|
2007-07-01 02:13:41 +08:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* FIXME: This is currently the only measure done to make this area
|
|
|
|
|
* dead. In the final code the concrete rectangle tools will have to
|
|
|
|
|
* be written to handle this state.
|
|
|
|
|
*/
|
|
|
|
|
function = RECT_DEAD;
|
|
|
|
|
}
|
2005-03-03 02:18:19 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2006-11-05 03:21:15 +08:00
|
|
|
|
/* otherwise, the new function will be creating, since we want
|
|
|
|
|
* to start a new rectangle
|
|
|
|
|
*/
|
|
|
|
|
function = RECT_CREATING;
|
2005-03-03 02:18:19 +08:00
|
|
|
|
}
|
2006-11-05 03:21:15 +08:00
|
|
|
|
|
2006-11-16 04:45:43 +08:00
|
|
|
|
gimp_rectangle_tool_set_function (GIMP_RECTANGLE_TOOL (tool), function);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
2005-08-15 22:23:28 +08:00
|
|
|
|
void
|
2005-03-03 02:18:19 +08:00
|
|
|
|
gimp_rectangle_tool_cursor_update (GimpTool *tool,
|
|
|
|
|
GimpCoords *coords,
|
|
|
|
|
GdkModifierType state,
|
2006-03-29 01:55:52 +08:00
|
|
|
|
GimpDisplay *display)
|
2005-03-03 02:18:19 +08:00
|
|
|
|
{
|
2006-11-05 03:21:15 +08:00
|
|
|
|
GimpRectangleTool *rectangle;
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
2006-11-16 06:43:24 +08:00
|
|
|
|
GimpCursorType cursor = GIMP_CURSOR_CROSSHAIR_SMALL;
|
2005-08-15 22:23:28 +08:00
|
|
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_RECTANGLE_TOOL (tool));
|
|
|
|
|
|
2006-06-02 23:23:47 +08:00
|
|
|
|
rectangle = GIMP_RECTANGLE_TOOL (tool);
|
2006-11-05 03:21:15 +08:00
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (tool);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
2006-09-12 16:33:30 +08:00
|
|
|
|
if (tool->display == display)
|
2005-03-03 02:18:19 +08:00
|
|
|
|
{
|
2006-11-05 03:21:15 +08:00
|
|
|
|
switch (private->function)
|
2005-03-03 02:18:19 +08:00
|
|
|
|
{
|
2005-03-15 04:44:18 +08:00
|
|
|
|
case RECT_CREATING:
|
2006-06-02 23:23:47 +08:00
|
|
|
|
cursor = GIMP_CURSOR_CROSSHAIR_SMALL;
|
2005-03-15 04:44:18 +08:00
|
|
|
|
break;
|
2005-03-03 02:18:19 +08:00
|
|
|
|
case RECT_MOVING:
|
2006-11-16 06:43:24 +08:00
|
|
|
|
cursor = GIMP_CURSOR_MOVE;
|
2005-03-03 02:18:19 +08:00
|
|
|
|
break;
|
2005-03-10 06:22:38 +08:00
|
|
|
|
case RECT_RESIZING_UPPER_LEFT:
|
2006-06-02 23:23:47 +08:00
|
|
|
|
cursor = GIMP_CURSOR_CORNER_TOP_LEFT;
|
2005-03-15 04:44:18 +08:00
|
|
|
|
break;
|
2005-03-10 06:22:38 +08:00
|
|
|
|
case RECT_RESIZING_UPPER_RIGHT:
|
2006-06-02 23:23:47 +08:00
|
|
|
|
cursor = GIMP_CURSOR_CORNER_TOP_RIGHT;
|
2005-03-15 04:44:18 +08:00
|
|
|
|
break;
|
2005-03-10 06:22:38 +08:00
|
|
|
|
case RECT_RESIZING_LOWER_LEFT:
|
2006-06-02 23:23:47 +08:00
|
|
|
|
cursor = GIMP_CURSOR_CORNER_BOTTOM_LEFT;
|
2005-03-15 04:44:18 +08:00
|
|
|
|
break;
|
2005-03-10 06:22:38 +08:00
|
|
|
|
case RECT_RESIZING_LOWER_RIGHT:
|
2006-06-02 23:23:47 +08:00
|
|
|
|
cursor = GIMP_CURSOR_CORNER_BOTTOM_RIGHT;
|
2005-03-15 04:44:18 +08:00
|
|
|
|
break;
|
2005-03-03 02:18:19 +08:00
|
|
|
|
case RECT_RESIZING_LEFT:
|
2006-06-02 23:23:47 +08:00
|
|
|
|
cursor = GIMP_CURSOR_SIDE_LEFT;
|
2005-03-15 04:44:18 +08:00
|
|
|
|
break;
|
2005-03-03 02:18:19 +08:00
|
|
|
|
case RECT_RESIZING_RIGHT:
|
2006-06-02 23:23:47 +08:00
|
|
|
|
cursor = GIMP_CURSOR_SIDE_RIGHT;
|
2005-03-15 04:44:18 +08:00
|
|
|
|
break;
|
2005-03-10 06:22:38 +08:00
|
|
|
|
case RECT_RESIZING_TOP:
|
2006-06-02 23:23:47 +08:00
|
|
|
|
cursor = GIMP_CURSOR_SIDE_TOP;
|
2005-03-15 04:44:18 +08:00
|
|
|
|
break;
|
2005-03-10 06:22:38 +08:00
|
|
|
|
case RECT_RESIZING_BOTTOM:
|
2006-06-02 23:23:47 +08:00
|
|
|
|
cursor = GIMP_CURSOR_SIDE_BOTTOM;
|
2005-03-03 02:18:19 +08:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-11-16 06:43:24 +08:00
|
|
|
|
gimp_tool_control_set_cursor (tool->control, cursor);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
2005-08-15 22:23:28 +08:00
|
|
|
|
void
|
2006-06-05 02:21:56 +08:00
|
|
|
|
gimp_rectangle_tool_draw (GimpDrawTool *draw_tool)
|
2005-03-03 02:18:19 +08:00
|
|
|
|
{
|
2006-11-05 03:21:15 +08:00
|
|
|
|
GimpTool *tool;
|
2006-06-03 06:24:55 +08:00
|
|
|
|
GimpRectangleToolPrivate *private;
|
2005-08-15 22:23:28 +08:00
|
|
|
|
|
2006-06-06 04:48:58 +08:00
|
|
|
|
g_return_if_fail (GIMP_IS_RECTANGLE_TOOL (draw_tool));
|
|
|
|
|
|
2006-11-05 03:21:15 +08:00
|
|
|
|
tool = GIMP_TOOL (draw_tool);
|
2006-11-07 00:40:09 +08:00
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (tool);
|
2006-06-05 02:21:56 +08:00
|
|
|
|
|
2006-11-05 03:21:15 +08:00
|
|
|
|
if (private->function == RECT_INACTIVE)
|
2006-06-05 02:21:56 +08:00
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
gimp_draw_tool_draw_rectangle (draw_tool, FALSE,
|
2006-11-05 03:50:13 +08:00
|
|
|
|
private->x1,
|
|
|
|
|
private->y1,
|
|
|
|
|
private->x2 - private->x1,
|
|
|
|
|
private->y2 - private->y1,
|
|
|
|
|
FALSE);
|
2006-06-06 04:48:58 +08:00
|
|
|
|
|
2006-11-07 01:09:07 +08:00
|
|
|
|
switch (private->function)
|
2006-09-15 08:01:59 +08:00
|
|
|
|
{
|
2006-11-07 01:09:07 +08:00
|
|
|
|
case RECT_MOVING:
|
2006-11-07 22:08:14 +08:00
|
|
|
|
if (gimp_tool_control_is_active (tool->control))
|
|
|
|
|
break;
|
|
|
|
|
/* else fallthrough */
|
|
|
|
|
|
2007-07-01 02:13:41 +08:00
|
|
|
|
case RECT_DEAD:
|
2006-11-07 22:08:14 +08:00
|
|
|
|
case RECT_CREATING:
|
2006-11-07 00:31:11 +08:00
|
|
|
|
gimp_draw_tool_draw_corner (draw_tool, FALSE,
|
2006-11-05 03:50:13 +08:00
|
|
|
|
private->x1, private->y1,
|
2006-11-07 00:31:11 +08:00
|
|
|
|
private->x2, private->y2,
|
2007-07-05 19:49:00 +08:00
|
|
|
|
private->handle_w,
|
|
|
|
|
private->handle_h,
|
2006-09-15 08:01:59 +08:00
|
|
|
|
GTK_ANCHOR_NORTH_WEST, FALSE);
|
2006-11-07 00:31:11 +08:00
|
|
|
|
gimp_draw_tool_draw_corner (draw_tool, FALSE,
|
|
|
|
|
private->x1, private->y1,
|
|
|
|
|
private->x2, private->y2,
|
2007-07-05 19:49:00 +08:00
|
|
|
|
private->handle_w,
|
|
|
|
|
private->handle_h,
|
2006-09-15 08:01:59 +08:00
|
|
|
|
GTK_ANCHOR_NORTH_EAST, FALSE);
|
2006-11-07 00:31:11 +08:00
|
|
|
|
gimp_draw_tool_draw_corner (draw_tool, FALSE,
|
|
|
|
|
private->x1, private->y1,
|
|
|
|
|
private->x2, private->y2,
|
2007-07-05 19:49:00 +08:00
|
|
|
|
private->handle_w,
|
|
|
|
|
private->handle_h,
|
2006-09-15 08:01:59 +08:00
|
|
|
|
GTK_ANCHOR_SOUTH_WEST, FALSE);
|
2006-11-07 00:31:11 +08:00
|
|
|
|
gimp_draw_tool_draw_corner (draw_tool, FALSE,
|
|
|
|
|
private->x1, private->y1,
|
2006-11-05 03:50:13 +08:00
|
|
|
|
private->x2, private->y2,
|
2007-07-05 19:49:00 +08:00
|
|
|
|
private->handle_w,
|
|
|
|
|
private->handle_h,
|
2006-09-15 08:01:59 +08:00
|
|
|
|
GTK_ANCHOR_SOUTH_EAST, FALSE);
|
2006-11-07 01:09:07 +08:00
|
|
|
|
break;
|
|
|
|
|
|
2007-07-01 02:13:41 +08:00
|
|
|
|
case RECT_RESIZING_TOP:
|
|
|
|
|
case RECT_RESIZING_BOTTOM:
|
|
|
|
|
gimp_draw_tool_draw_corner (draw_tool,
|
2007-07-05 19:49:00 +08:00
|
|
|
|
! gimp_tool_control_is_active (tool->control),
|
2007-07-01 02:13:41 +08:00
|
|
|
|
private->x1, private->y1,
|
|
|
|
|
private->x2, private->y2,
|
2007-07-05 19:49:00 +08:00
|
|
|
|
private->top_and_bottom_handle_w,
|
|
|
|
|
private->handle_h,
|
2007-07-01 02:13:41 +08:00
|
|
|
|
gimp_rectangle_tool_get_anchor (private),
|
|
|
|
|
FALSE);
|
|
|
|
|
break;
|
2006-11-14 00:13:37 +08:00
|
|
|
|
|
2007-07-01 02:13:41 +08:00
|
|
|
|
case RECT_RESIZING_LEFT:
|
|
|
|
|
case RECT_RESIZING_RIGHT:
|
|
|
|
|
gimp_draw_tool_draw_corner (draw_tool,
|
2007-07-05 19:49:00 +08:00
|
|
|
|
! gimp_tool_control_is_active (tool->control),
|
2007-07-01 02:13:41 +08:00
|
|
|
|
private->x1, private->y1,
|
|
|
|
|
private->x2, private->y2,
|
2007-07-05 19:49:00 +08:00
|
|
|
|
private->handle_w,
|
|
|
|
|
private->left_and_right_handle_h,
|
2007-07-01 02:13:41 +08:00
|
|
|
|
gimp_rectangle_tool_get_anchor (private),
|
|
|
|
|
FALSE);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
gimp_draw_tool_draw_corner (draw_tool,
|
2007-07-05 19:49:00 +08:00
|
|
|
|
! gimp_tool_control_is_active (tool->control),
|
2007-07-01 02:13:41 +08:00
|
|
|
|
private->x1, private->y1,
|
|
|
|
|
private->x2, private->y2,
|
2007-07-05 19:49:00 +08:00
|
|
|
|
private->handle_w,
|
|
|
|
|
private->handle_h,
|
2007-07-01 02:13:41 +08:00
|
|
|
|
gimp_rectangle_tool_get_anchor (private),
|
|
|
|
|
FALSE);
|
2006-11-07 01:09:07 +08:00
|
|
|
|
break;
|
2006-09-15 08:01:59 +08:00
|
|
|
|
}
|
2006-11-07 01:09:07 +08:00
|
|
|
|
|
|
|
|
|
gimp_rectangle_tool_draw_guides (draw_tool);
|
2006-06-07 03:14:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gimp_rectangle_tool_draw_guides (GimpDrawTool *draw_tool)
|
|
|
|
|
{
|
|
|
|
|
GimpTool *tool;
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
gint x1, x2, y1, y2;
|
|
|
|
|
|
|
|
|
|
tool = GIMP_TOOL (draw_tool);
|
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (draw_tool);
|
|
|
|
|
|
|
|
|
|
x1 = private->x1;
|
|
|
|
|
x2 = private->x2;
|
|
|
|
|
y1 = private->y1;
|
|
|
|
|
y2 = private->y2;
|
2006-06-07 03:25:53 +08:00
|
|
|
|
|
2006-06-07 05:06:06 +08:00
|
|
|
|
switch (private->guide)
|
2006-06-06 02:50:13 +08:00
|
|
|
|
{
|
|
|
|
|
case GIMP_RECTANGLE_GUIDE_NONE:
|
|
|
|
|
break;
|
2006-06-06 04:48:58 +08:00
|
|
|
|
|
2006-06-06 02:50:13 +08:00
|
|
|
|
case GIMP_RECTANGLE_GUIDE_CENTER_LINES:
|
2006-06-06 04:48:58 +08:00
|
|
|
|
gimp_draw_tool_draw_line (draw_tool,
|
|
|
|
|
x1, (y1 + y2) / 2,
|
|
|
|
|
x2, (y1 + y2) / 2, FALSE);
|
|
|
|
|
gimp_draw_tool_draw_line (draw_tool,
|
|
|
|
|
(x1 + x2) / 2, y1,
|
|
|
|
|
(x1 + x2) / 2, y2, FALSE);
|
2006-06-06 02:50:13 +08:00
|
|
|
|
break;
|
2006-06-06 04:48:58 +08:00
|
|
|
|
|
2006-06-06 02:50:13 +08:00
|
|
|
|
case GIMP_RECTANGLE_GUIDE_THIRDS:
|
2006-06-06 04:48:58 +08:00
|
|
|
|
gimp_draw_tool_draw_line (draw_tool,
|
|
|
|
|
x1, (2 * y1 + y2) / 3,
|
|
|
|
|
x2, (2 * y1 + y2) / 3, FALSE);
|
|
|
|
|
gimp_draw_tool_draw_line (draw_tool,
|
|
|
|
|
x1, (y1 + 2 * y2) / 3,
|
|
|
|
|
x2, (y1 + 2 * y2) / 3, FALSE);
|
|
|
|
|
gimp_draw_tool_draw_line (draw_tool,
|
|
|
|
|
(2 * x1 + x2) / 3, y1,
|
|
|
|
|
(2 * x1 + x2) / 3, y2, FALSE);
|
|
|
|
|
gimp_draw_tool_draw_line (draw_tool,
|
|
|
|
|
(x1 + 2 * x2) / 3, y1,
|
|
|
|
|
(x1 + 2 * x2) / 3, y2, FALSE);
|
2006-06-06 02:50:13 +08:00
|
|
|
|
break;
|
2006-06-06 04:48:58 +08:00
|
|
|
|
|
2006-06-06 02:50:13 +08:00
|
|
|
|
case GIMP_RECTANGLE_GUIDE_GOLDEN:
|
2006-06-06 04:48:58 +08:00
|
|
|
|
gimp_draw_tool_draw_line (draw_tool,
|
2006-06-07 03:25:53 +08:00
|
|
|
|
x1,
|
2007-03-30 17:26:48 +08:00
|
|
|
|
(2 * y1 + (1 + SQRT5) * y2) / (3 + SQRT5),
|
2006-06-07 03:25:53 +08:00
|
|
|
|
x2,
|
2007-03-30 17:26:48 +08:00
|
|
|
|
(2 * y1 + (1 + SQRT5) * y2) / (3 + SQRT5),
|
2006-06-07 03:25:53 +08:00
|
|
|
|
FALSE);
|
2006-06-06 04:48:58 +08:00
|
|
|
|
gimp_draw_tool_draw_line (draw_tool,
|
2006-06-07 03:25:53 +08:00
|
|
|
|
x1,
|
2007-03-30 17:26:48 +08:00
|
|
|
|
((1 + SQRT5) * y1 + 2 * y2) / (3 + SQRT5),
|
2006-06-07 03:25:53 +08:00
|
|
|
|
x2,
|
2007-03-30 17:26:48 +08:00
|
|
|
|
((1 + SQRT5) * y1 + 2 * y2) / (3 + SQRT5),
|
2006-06-07 03:25:53 +08:00
|
|
|
|
FALSE);
|
2006-06-06 04:48:58 +08:00
|
|
|
|
gimp_draw_tool_draw_line (draw_tool,
|
2007-03-30 17:26:48 +08:00
|
|
|
|
(2 * x1 + (1 + SQRT5) * x2) / (3 + SQRT5),
|
2006-06-07 03:25:53 +08:00
|
|
|
|
y1,
|
2007-03-30 17:26:48 +08:00
|
|
|
|
(2 * x1 + (1 + SQRT5) * x2) / (3 + SQRT5),
|
2006-06-07 03:25:53 +08:00
|
|
|
|
y2,
|
|
|
|
|
FALSE);
|
2006-06-06 04:48:58 +08:00
|
|
|
|
gimp_draw_tool_draw_line (draw_tool,
|
2007-03-30 17:26:48 +08:00
|
|
|
|
((1 + SQRT5) * x1 + 2 * x2) / (3 + SQRT5),
|
2006-06-07 03:25:53 +08:00
|
|
|
|
y1,
|
2007-03-30 17:26:48 +08:00
|
|
|
|
((1 + SQRT5) * x1 + 2 * x2) / (3 + SQRT5),
|
2006-06-07 03:25:53 +08:00
|
|
|
|
y2, FALSE);
|
2006-06-06 02:50:13 +08:00
|
|
|
|
break;
|
|
|
|
|
}
|
2005-03-03 02:18:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
2005-10-20 05:13:25 +08:00
|
|
|
|
void
|
|
|
|
|
gimp_rectangle_tool_configure (GimpRectangleTool *rectangle)
|
2005-03-03 02:18:19 +08:00
|
|
|
|
{
|
2006-09-06 02:25:31 +08:00
|
|
|
|
GimpTool *tool = GIMP_TOOL (rectangle);
|
2006-06-03 06:24:55 +08:00
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
GimpRectangleOptions *options;
|
2006-09-06 02:25:31 +08:00
|
|
|
|
GimpDisplayShell *shell;
|
2006-11-05 03:21:15 +08:00
|
|
|
|
gint dx1, dx2;
|
|
|
|
|
gint dy1, dy2;
|
2007-07-01 02:13:41 +08:00
|
|
|
|
gint tw, th;
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
2006-09-06 02:25:31 +08:00
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (tool);
|
|
|
|
|
options = GIMP_RECTANGLE_TOOL_GET_OPTIONS (tool);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
2006-03-29 01:55:52 +08:00
|
|
|
|
if (! tool->display)
|
2005-03-03 02:18:19 +08:00
|
|
|
|
return;
|
|
|
|
|
|
2007-02-09 07:19:57 +08:00
|
|
|
|
gimp_rectangle_tool_set_highlight (rectangle);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
2007-02-09 07:19:57 +08:00
|
|
|
|
shell = GIMP_DISPLAY_SHELL (tool->display->shell);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
|
|
|
|
gimp_display_shell_transform_xy (shell,
|
2006-11-05 03:21:15 +08:00
|
|
|
|
private->x1, private->y1,
|
2005-08-15 22:23:28 +08:00
|
|
|
|
&dx1, &dy1,
|
2005-03-03 02:18:19 +08:00
|
|
|
|
FALSE);
|
|
|
|
|
gimp_display_shell_transform_xy (shell,
|
2006-11-05 03:21:15 +08:00
|
|
|
|
private->x2, private->y2,
|
2005-08-15 22:23:28 +08:00
|
|
|
|
&dx2, &dy2,
|
2005-03-03 02:18:19 +08:00
|
|
|
|
FALSE);
|
|
|
|
|
|
2007-07-01 02:13:41 +08:00
|
|
|
|
tw = dx2 - dx1;
|
|
|
|
|
th = dy2 - dy1;
|
|
|
|
|
|
|
|
|
|
private->handle_w = tw / 4;
|
|
|
|
|
private->handle_h = th / 4;
|
2006-11-07 19:09:51 +08:00
|
|
|
|
|
2007-07-11 13:09:50 +08:00
|
|
|
|
private->handle_w =
|
|
|
|
|
CLAMP (private->handle_w, MIN_HANDLE_SIZE, MAX_HANDLE_SIZE);
|
|
|
|
|
private->handle_h =
|
|
|
|
|
CLAMP (private->handle_h, MIN_HANDLE_SIZE, MAX_HANDLE_SIZE);
|
2007-07-01 02:13:41 +08:00
|
|
|
|
|
|
|
|
|
private->top_and_bottom_handle_w = tw - 3 * private->handle_w;
|
|
|
|
|
private->left_and_right_handle_h = th - 3 * private->handle_h;
|
|
|
|
|
|
|
|
|
|
private->top_and_bottom_handle_w =
|
|
|
|
|
CLAMP (private->top_and_bottom_handle_w, MIN_HANDLE_SIZE, G_MAXINT);
|
|
|
|
|
private->left_and_right_handle_h =
|
|
|
|
|
CLAMP (private->left_and_right_handle_h, MIN_HANDLE_SIZE, G_MAXINT);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2007-03-15 17:21:47 +08:00
|
|
|
|
gimp_rectangle_tool_start (GimpRectangleTool *rectangle,
|
|
|
|
|
GimpDisplay *display)
|
2005-03-03 02:18:19 +08:00
|
|
|
|
{
|
2007-04-01 00:38:55 +08:00
|
|
|
|
GimpTool *tool = GIMP_TOOL (rectangle);
|
|
|
|
|
GimpRectangleOptionsPrivate *options_private;
|
|
|
|
|
|
|
|
|
|
options_private =
|
|
|
|
|
GIMP_RECTANGLE_OPTIONS_GET_PRIVATE (gimp_tool_get_options (tool));
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
2007-03-15 17:21:47 +08:00
|
|
|
|
tool->display = display;
|
2005-10-20 05:13:25 +08:00
|
|
|
|
gimp_rectangle_tool_configure (rectangle);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
|
|
|
|
/* initialize the statusbar display */
|
2006-03-29 01:55:52 +08:00
|
|
|
|
gimp_tool_push_status_coords (tool, tool->display,
|
2007-01-21 09:24:51 +08:00
|
|
|
|
_("Rectangle: "), 0, " x ", 0, NULL);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
2006-03-29 01:55:52 +08:00
|
|
|
|
gimp_draw_tool_start (GIMP_DRAW_TOOL (tool), tool->display);
|
2007-04-01 00:38:55 +08:00
|
|
|
|
|
|
|
|
|
if (options_private->auto_shrink_button)
|
|
|
|
|
{
|
|
|
|
|
g_signal_connect_swapped (options_private->auto_shrink_button, "clicked",
|
|
|
|
|
G_CALLBACK (gimp_rectangle_tool_auto_shrink),
|
|
|
|
|
rectangle);
|
|
|
|
|
|
|
|
|
|
gtk_widget_set_sensitive (options_private->auto_shrink_button, TRUE);
|
|
|
|
|
}
|
2005-03-03 02:18:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
2006-11-06 00:36:15 +08:00
|
|
|
|
static void
|
2006-06-06 01:14:16 +08:00
|
|
|
|
gimp_rectangle_tool_halt (GimpRectangleTool *rectangle)
|
2005-03-03 02:18:19 +08:00
|
|
|
|
{
|
2007-04-01 00:38:55 +08:00
|
|
|
|
GimpTool *tool = GIMP_TOOL (rectangle);
|
|
|
|
|
GimpRectangleOptionsPrivate *options_private;
|
|
|
|
|
|
|
|
|
|
options_private =
|
|
|
|
|
GIMP_RECTANGLE_OPTIONS_GET_PRIVATE (gimp_tool_get_options (tool));
|
2005-04-10 02:08:47 +08:00
|
|
|
|
|
2007-03-15 17:21:47 +08:00
|
|
|
|
if (tool->display)
|
|
|
|
|
gimp_display_shell_set_highlight (GIMP_DISPLAY_SHELL (tool->display->shell),
|
|
|
|
|
NULL);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
2006-06-06 01:14:16 +08:00
|
|
|
|
if (gimp_draw_tool_is_active (GIMP_DRAW_TOOL (rectangle)))
|
|
|
|
|
gimp_draw_tool_stop (GIMP_DRAW_TOOL (rectangle));
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
2006-06-06 01:14:16 +08:00
|
|
|
|
if (gimp_tool_control_is_active (tool->control))
|
|
|
|
|
gimp_tool_control_halt (tool->control);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
|
2006-06-06 01:14:16 +08:00
|
|
|
|
tool->display = NULL;
|
|
|
|
|
tool->drawable = NULL;
|
2005-03-09 07:17:19 +08:00
|
|
|
|
|
2006-11-16 04:45:43 +08:00
|
|
|
|
gimp_rectangle_tool_set_function (rectangle, RECT_INACTIVE);
|
2007-04-01 00:38:55 +08:00
|
|
|
|
|
|
|
|
|
if (options_private->auto_shrink_button)
|
|
|
|
|
{
|
|
|
|
|
gtk_widget_set_sensitive (options_private->auto_shrink_button, FALSE);
|
|
|
|
|
|
|
|
|
|
g_signal_handlers_disconnect_by_func (options_private->auto_shrink_button,
|
|
|
|
|
gimp_rectangle_tool_auto_shrink,
|
|
|
|
|
rectangle);
|
|
|
|
|
}
|
2005-03-03 02:18:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
2005-08-15 22:23:28 +08:00
|
|
|
|
gboolean
|
2006-06-06 01:14:16 +08:00
|
|
|
|
gimp_rectangle_tool_execute (GimpRectangleTool *rectangle)
|
2005-03-03 02:18:19 +08:00
|
|
|
|
{
|
2006-06-06 01:14:16 +08:00
|
|
|
|
GimpRectangleToolInterface *iface;
|
|
|
|
|
gboolean retval = FALSE;
|
2005-08-15 22:23:28 +08:00
|
|
|
|
|
2006-06-06 01:14:16 +08:00
|
|
|
|
iface = GIMP_RECTANGLE_TOOL_GET_INTERFACE (rectangle);
|
2005-09-04 03:48:22 +08:00
|
|
|
|
|
2006-06-06 01:14:16 +08:00
|
|
|
|
if (iface->execute)
|
|
|
|
|
{
|
2006-11-05 03:21:15 +08:00
|
|
|
|
GimpRectangleToolPrivate *private;
|
2006-06-06 01:14:16 +08:00
|
|
|
|
|
2006-11-05 03:21:15 +08:00
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (rectangle);
|
2006-06-06 01:14:16 +08:00
|
|
|
|
|
|
|
|
|
gimp_draw_tool_pause (GIMP_DRAW_TOOL (rectangle));
|
|
|
|
|
|
2006-11-05 03:21:15 +08:00
|
|
|
|
retval = iface->execute (rectangle,
|
|
|
|
|
private->x1,
|
|
|
|
|
private->y1,
|
|
|
|
|
private->x2 - private->x1,
|
|
|
|
|
private->y2 - private->y1);
|
2006-06-06 01:14:16 +08:00
|
|
|
|
|
|
|
|
|
gimp_rectangle_tool_configure (rectangle);
|
|
|
|
|
|
|
|
|
|
gimp_draw_tool_resume (GIMP_DRAW_TOOL (rectangle));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
gimp_rectangle_tool_cancel (GimpRectangleTool *rectangle)
|
|
|
|
|
{
|
|
|
|
|
GimpRectangleToolInterface *iface;
|
|
|
|
|
|
|
|
|
|
iface = GIMP_RECTANGLE_TOOL_GET_INTERFACE (rectangle);
|
2005-04-10 02:08:47 +08:00
|
|
|
|
|
2006-06-06 01:14:16 +08:00
|
|
|
|
if (iface->cancel)
|
|
|
|
|
iface->cancel (rectangle);
|
2005-03-03 02:18:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
2005-03-09 07:17:19 +08:00
|
|
|
|
static void
|
|
|
|
|
gimp_rectangle_tool_update_options (GimpRectangleTool *rectangle,
|
2006-03-29 01:55:52 +08:00
|
|
|
|
GimpDisplay *display)
|
2005-03-09 07:17:19 +08:00
|
|
|
|
{
|
2007-04-01 00:38:55 +08:00
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
GimpRectangleOptions *options;
|
|
|
|
|
GimpRectangleOptionsPrivate *options_private;
|
|
|
|
|
gdouble x;
|
|
|
|
|
gdouble y;
|
|
|
|
|
gdouble width;
|
|
|
|
|
gdouble height;
|
|
|
|
|
gdouble center_x, center_y;
|
|
|
|
|
|
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (rectangle);
|
|
|
|
|
options = GIMP_RECTANGLE_TOOL_GET_OPTIONS (rectangle);
|
|
|
|
|
options_private = GIMP_RECTANGLE_OPTIONS_GET_PRIVATE (options);
|
2005-03-11 07:55:24 +08:00
|
|
|
|
|
2006-11-05 03:21:15 +08:00
|
|
|
|
x = private->x1;
|
|
|
|
|
y = private->y1;
|
|
|
|
|
width = private->x2 - private->x1;
|
|
|
|
|
height = private->y2 - private->y1;
|
2005-03-09 07:17:19 +08:00
|
|
|
|
|
2006-11-05 03:21:15 +08:00
|
|
|
|
center_x = (private->x1 + private->x2) / 2.0;
|
|
|
|
|
center_y = (private->y1 + private->y2) / 2.0;
|
2005-03-10 06:22:38 +08:00
|
|
|
|
|
2006-11-05 06:39:37 +08:00
|
|
|
|
g_signal_handlers_block_by_func (options,
|
|
|
|
|
gimp_rectangle_tool_options_notify,
|
|
|
|
|
rectangle);
|
2006-09-23 02:27:21 +08:00
|
|
|
|
|
|
|
|
|
g_object_set (options,
|
|
|
|
|
"x0", x,
|
|
|
|
|
"y0", y,
|
|
|
|
|
NULL);
|
2005-03-11 07:55:24 +08:00
|
|
|
|
|
2007-04-01 00:38:55 +08:00
|
|
|
|
if (! options_private->fixed_width)
|
2005-11-30 07:32:55 +08:00
|
|
|
|
g_object_set (options,
|
|
|
|
|
"width", width,
|
|
|
|
|
NULL);
|
|
|
|
|
|
2007-04-01 00:38:55 +08:00
|
|
|
|
if (! options_private->fixed_height)
|
2005-11-30 07:32:55 +08:00
|
|
|
|
g_object_set (options,
|
|
|
|
|
"height", height,
|
|
|
|
|
NULL);
|
|
|
|
|
|
2005-09-04 03:48:22 +08:00
|
|
|
|
g_object_set (options,
|
|
|
|
|
"center-x", center_x,
|
|
|
|
|
"center-y", center_y,
|
|
|
|
|
NULL);
|
2007-07-09 05:57:22 +08:00
|
|
|
|
|
|
|
|
|
g_signal_handlers_unblock_by_func (options,
|
|
|
|
|
gimp_rectangle_tool_options_notify,
|
|
|
|
|
rectangle);
|
|
|
|
|
|
2005-03-09 07:17:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
2006-09-23 02:27:21 +08:00
|
|
|
|
static void
|
2007-04-01 00:38:55 +08:00
|
|
|
|
gimp_rectangle_tool_synthesize_motion (GimpRectangleTool *rectangle,
|
|
|
|
|
gint function,
|
2007-07-09 05:57:22 +08:00
|
|
|
|
gint new_x,
|
|
|
|
|
gint new_y)
|
2006-09-23 02:27:21 +08:00
|
|
|
|
{
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
2006-12-31 02:18:53 +08:00
|
|
|
|
GimpRectangleFunction old_function;
|
2006-09-23 02:27:21 +08:00
|
|
|
|
|
2007-04-01 00:38:55 +08:00
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (rectangle);
|
2006-09-23 02:27:21 +08:00
|
|
|
|
|
2006-12-31 02:18:53 +08:00
|
|
|
|
old_function = private->function;
|
|
|
|
|
|
2007-04-01 00:38:55 +08:00
|
|
|
|
gimp_draw_tool_pause (GIMP_DRAW_TOOL (rectangle));
|
2006-11-16 04:45:43 +08:00
|
|
|
|
|
2007-04-01 00:38:55 +08:00
|
|
|
|
gimp_rectangle_tool_set_function (rectangle, function);
|
2006-12-31 02:18:53 +08:00
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
gimp_rectangle_tool_update_with_coord (rectangle,
|
|
|
|
|
new_x,
|
|
|
|
|
new_y);
|
2006-11-05 03:21:15 +08:00
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
/* We must update this. */
|
|
|
|
|
private->center_x_on_fixed_center = (private->x1 + private->x2) / 2;
|
|
|
|
|
private->center_y_on_fixed_center = (private->y1 + private->y2) / 2;
|
2006-09-23 02:27:21 +08:00
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
gimp_rectangle_tool_update_options (rectangle,
|
|
|
|
|
GIMP_TOOL (rectangle)->display);
|
|
|
|
|
|
|
|
|
|
gimp_rectangle_tool_set_function (rectangle, old_function);
|
|
|
|
|
|
|
|
|
|
gimp_rectangle_tool_configure (rectangle);
|
|
|
|
|
|
|
|
|
|
gimp_draw_tool_resume (GIMP_DRAW_TOOL (rectangle));
|
|
|
|
|
|
|
|
|
|
gimp_rectangle_tool_rectangle_changed (rectangle);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2006-11-05 06:39:37 +08:00
|
|
|
|
gimp_rectangle_tool_options_notify (GimpRectangleOptions *options,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
GimpRectangleTool *rectangle)
|
2006-09-23 02:27:21 +08:00
|
|
|
|
{
|
2007-04-01 00:38:55 +08:00
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
GimpRectangleOptionsPrivate *options_private;
|
2006-09-23 02:27:21 +08:00
|
|
|
|
|
2007-04-01 00:38:55 +08:00
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (rectangle);
|
|
|
|
|
options_private = GIMP_RECTANGLE_OPTIONS_GET_PRIVATE (options);
|
2006-09-23 02:27:21 +08:00
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
|
2006-11-05 06:39:37 +08:00
|
|
|
|
if (! strcmp (pspec->name, "guide"))
|
|
|
|
|
{
|
|
|
|
|
gimp_draw_tool_pause (GIMP_DRAW_TOOL (rectangle));
|
2006-09-23 02:27:21 +08:00
|
|
|
|
|
2007-04-01 00:38:55 +08:00
|
|
|
|
private->guide = options_private->guide;
|
2006-09-23 02:27:21 +08:00
|
|
|
|
|
2006-11-05 06:39:37 +08:00
|
|
|
|
gimp_draw_tool_resume (GIMP_DRAW_TOOL (rectangle));
|
2006-06-03 06:24:55 +08:00
|
|
|
|
|
2006-11-05 06:39:37 +08:00
|
|
|
|
return;
|
|
|
|
|
}
|
2005-10-22 04:17:19 +08:00
|
|
|
|
|
2007-04-01 00:38:55 +08:00
|
|
|
|
if (! GIMP_TOOL (rectangle)->display)
|
2005-11-29 06:30:24 +08:00
|
|
|
|
return;
|
|
|
|
|
|
2006-11-05 06:39:37 +08:00
|
|
|
|
if (! strcmp (pspec->name, "x0"))
|
|
|
|
|
{
|
2007-07-09 05:57:22 +08:00
|
|
|
|
if (private->x1 != options_private->x0)
|
|
|
|
|
gimp_rectangle_tool_synthesize_motion (rectangle,
|
|
|
|
|
RECT_MOVING,
|
|
|
|
|
options_private->x0,
|
|
|
|
|
private->y1);
|
2006-11-05 06:39:37 +08:00
|
|
|
|
}
|
|
|
|
|
else if (! strcmp (pspec->name, "y0"))
|
|
|
|
|
{
|
2007-07-09 05:57:22 +08:00
|
|
|
|
if (private->y1 != options_private->y0)
|
|
|
|
|
gimp_rectangle_tool_synthesize_motion (rectangle,
|
|
|
|
|
RECT_MOVING,
|
|
|
|
|
private->x1,
|
|
|
|
|
options_private->y0);
|
2006-11-05 06:39:37 +08:00
|
|
|
|
}
|
|
|
|
|
else if (! strcmp (pspec->name, "width"))
|
|
|
|
|
{
|
2007-07-09 05:57:22 +08:00
|
|
|
|
/* Calculate x2, y2 that will create a rectangle of given width, for the
|
|
|
|
|
* current options.
|
|
|
|
|
*/
|
|
|
|
|
gint x2;
|
2005-10-22 04:17:19 +08:00
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
if (private->x2 - private->x1 != options_private->width)
|
|
|
|
|
{
|
|
|
|
|
if (options_private->fixed_center)
|
|
|
|
|
{
|
|
|
|
|
x2 = private->center_x_on_fixed_center +
|
|
|
|
|
options_private->width / 2;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
x2 = private->x1 + options_private->width;
|
|
|
|
|
}
|
2006-06-05 01:08:26 +08:00
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
gimp_rectangle_tool_synthesize_motion (rectangle,
|
|
|
|
|
RECT_RESIZING_RIGHT,
|
|
|
|
|
x2,
|
|
|
|
|
private->y2);
|
|
|
|
|
}
|
2006-11-05 06:39:37 +08:00
|
|
|
|
}
|
|
|
|
|
else if (! strcmp (pspec->name, "height"))
|
|
|
|
|
{
|
2007-07-09 05:57:22 +08:00
|
|
|
|
/* Calculate x2, y2 that will create a rectangle of given height, for the
|
|
|
|
|
* current options.
|
|
|
|
|
*/
|
|
|
|
|
gint y2;
|
2006-03-25 17:38:59 +08:00
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
if (private->y2 - private->y1 != options_private->height)
|
|
|
|
|
{
|
|
|
|
|
if (options_private->fixed_center)
|
|
|
|
|
{
|
|
|
|
|
y2 = private->center_y_on_fixed_center +
|
|
|
|
|
options_private->height / 2;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
y2 = private->y1 + options_private->height;
|
|
|
|
|
}
|
2006-05-17 01:21:07 +08:00
|
|
|
|
|
2007-07-09 05:57:22 +08:00
|
|
|
|
gimp_rectangle_tool_synthesize_motion (rectangle,
|
|
|
|
|
RECT_RESIZING_BOTTOM,
|
|
|
|
|
private->x2,
|
|
|
|
|
y2);
|
|
|
|
|
}
|
2006-11-05 06:39:37 +08:00
|
|
|
|
}
|
|
|
|
|
else if (! strcmp (pspec->name, "fixed-aspect") ||
|
|
|
|
|
! strcmp (pspec->name, "aspect-numerator") ||
|
|
|
|
|
! strcmp (pspec->name, "aspect-denominator"))
|
|
|
|
|
{
|
2007-04-01 00:38:55 +08:00
|
|
|
|
if (options_private->fixed_aspect)
|
2006-11-05 06:39:37 +08:00
|
|
|
|
{
|
2007-04-01 00:38:55 +08:00
|
|
|
|
gimp_rectangle_tool_synthesize_motion (rectangle,
|
2007-07-09 05:57:22 +08:00
|
|
|
|
RECT_RESIZING_LOWER_RIGHT,
|
2006-11-05 06:39:37 +08:00
|
|
|
|
private->x2,
|
2007-07-09 05:57:22 +08:00
|
|
|
|
private->y2);
|
2006-11-05 06:39:37 +08:00
|
|
|
|
}
|
2006-03-25 17:38:59 +08:00
|
|
|
|
}
|
2006-11-05 06:39:37 +08:00
|
|
|
|
else if (! strcmp (pspec->name, "highlight"))
|
2006-06-07 02:07:04 +08:00
|
|
|
|
{
|
2007-02-09 07:19:57 +08:00
|
|
|
|
gimp_rectangle_tool_set_highlight (rectangle);
|
2006-11-05 06:39:37 +08:00
|
|
|
|
}
|
2006-06-07 05:06:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
2006-11-16 04:45:43 +08:00
|
|
|
|
GimpRectangleFunction
|
|
|
|
|
gimp_rectangle_tool_get_function (GimpRectangleTool *rectangle)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (GIMP_IS_RECTANGLE_TOOL (rectangle), RECT_INACTIVE);
|
|
|
|
|
|
|
|
|
|
return GIMP_RECTANGLE_TOOL_GET_PRIVATE (rectangle)->function;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
gimp_rectangle_tool_set_function (GimpRectangleTool *rectangle,
|
|
|
|
|
GimpRectangleFunction function)
|
|
|
|
|
{
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_RECTANGLE_TOOL (rectangle));
|
|
|
|
|
|
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (rectangle);
|
|
|
|
|
|
|
|
|
|
/* redraw the tool when the function changes */
|
|
|
|
|
/* FIXME: should also update the cursor */
|
|
|
|
|
if (private->function != function)
|
|
|
|
|
{
|
|
|
|
|
GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (rectangle);
|
|
|
|
|
|
|
|
|
|
gimp_draw_tool_pause (draw_tool);
|
|
|
|
|
|
|
|
|
|
private->function = function;
|
|
|
|
|
|
|
|
|
|
gimp_draw_tool_resume (draw_tool);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-02-28 21:08:09 +08:00
|
|
|
|
static void
|
|
|
|
|
gimp_rectangle_tool_rectangle_changed (GimpRectangleTool *rectangle)
|
|
|
|
|
{
|
|
|
|
|
g_signal_emit (rectangle,
|
|
|
|
|
gimp_rectangle_tool_signals[RECTANGLE_CHANGED], 0);
|
|
|
|
|
}
|
|
|
|
|
|
2006-09-24 04:45:06 +08:00
|
|
|
|
static void
|
|
|
|
|
gimp_rectangle_tool_auto_shrink (GimpRectangleTool *rectangle)
|
|
|
|
|
{
|
2006-11-05 03:21:15 +08:00
|
|
|
|
GimpTool *tool = GIMP_TOOL (rectangle);
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
GimpDisplay *display = tool->display;
|
|
|
|
|
gint width;
|
|
|
|
|
gint height;
|
|
|
|
|
gint offset_x = 0;
|
|
|
|
|
gint offset_y = 0;
|
|
|
|
|
gint x1, y1;
|
|
|
|
|
gint x2, y2;
|
|
|
|
|
gint shrunk_x1;
|
|
|
|
|
gint shrunk_y1;
|
|
|
|
|
gint shrunk_x2;
|
|
|
|
|
gint shrunk_y2;
|
|
|
|
|
gboolean shrink_merged;
|
|
|
|
|
|
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (rectangle);
|
2006-09-24 04:45:06 +08:00
|
|
|
|
|
|
|
|
|
if (! display)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
width = display->image->width;
|
|
|
|
|
height = display->image->height;
|
|
|
|
|
|
|
|
|
|
g_object_get (gimp_tool_get_options (tool),
|
|
|
|
|
"shrink-merged", &shrink_merged,
|
|
|
|
|
NULL);
|
|
|
|
|
|
2006-11-05 03:21:15 +08:00
|
|
|
|
x1 = private->x1 - offset_x > 0 ? private->x1 - offset_x : 0;
|
|
|
|
|
x2 = private->x2 - offset_x < width ? private->x2 - offset_x : width;
|
|
|
|
|
y1 = private->y1 - offset_y > 0 ? private->y1 - offset_y : 0;
|
|
|
|
|
y2 = private->y2 - offset_y < height ? private->y2 - offset_y : height;
|
2006-09-24 04:45:06 +08:00
|
|
|
|
|
|
|
|
|
if (gimp_image_crop_auto_shrink (display->image,
|
|
|
|
|
x1, y1, x2, y2,
|
|
|
|
|
! shrink_merged,
|
|
|
|
|
&shrunk_x1,
|
|
|
|
|
&shrunk_y1,
|
|
|
|
|
&shrunk_x2,
|
|
|
|
|
&shrunk_y2))
|
|
|
|
|
{
|
|
|
|
|
gimp_draw_tool_pause (GIMP_DRAW_TOOL (rectangle));
|
|
|
|
|
|
|
|
|
|
g_object_set (rectangle,
|
|
|
|
|
"x1", offset_x + shrunk_x1,
|
|
|
|
|
"y1", offset_y + shrunk_y1,
|
|
|
|
|
"x2", offset_x + shrunk_x2,
|
|
|
|
|
"y2", offset_y + shrunk_y2,
|
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
gimp_rectangle_tool_configure (rectangle);
|
|
|
|
|
|
|
|
|
|
gimp_draw_tool_resume (GIMP_DRAW_TOOL (rectangle));
|
|
|
|
|
}
|
|
|
|
|
}
|
2006-11-07 00:40:09 +08:00
|
|
|
|
|
|
|
|
|
static GtkAnchorType
|
2007-07-01 02:13:41 +08:00
|
|
|
|
gimp_rectangle_tool_get_anchor (GimpRectangleToolPrivate *private)
|
2006-11-07 00:40:09 +08:00
|
|
|
|
{
|
|
|
|
|
switch (private->function)
|
|
|
|
|
{
|
|
|
|
|
case RECT_RESIZING_UPPER_LEFT:
|
|
|
|
|
return GTK_ANCHOR_NORTH_WEST;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_UPPER_RIGHT:
|
|
|
|
|
return GTK_ANCHOR_NORTH_EAST;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_LOWER_LEFT:
|
|
|
|
|
return GTK_ANCHOR_SOUTH_WEST;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_LOWER_RIGHT:
|
|
|
|
|
return GTK_ANCHOR_SOUTH_EAST;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_LEFT:
|
|
|
|
|
return GTK_ANCHOR_WEST;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_RIGHT:
|
|
|
|
|
return GTK_ANCHOR_EAST;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_TOP:
|
|
|
|
|
return GTK_ANCHOR_NORTH;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_BOTTOM:
|
|
|
|
|
return GTK_ANCHOR_SOUTH;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return GTK_ANCHOR_CENTER;
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-02-09 07:19:57 +08:00
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gimp_rectangle_tool_set_highlight (GimpRectangleTool *rectangle)
|
|
|
|
|
{
|
|
|
|
|
GimpTool *tool = GIMP_TOOL (rectangle);
|
|
|
|
|
GimpRectangleOptions *options = GIMP_RECTANGLE_TOOL_GET_OPTIONS (tool);
|
|
|
|
|
GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (tool->display->shell);
|
|
|
|
|
gboolean highlight = FALSE;
|
|
|
|
|
|
|
|
|
|
g_object_get (options, "highlight", &highlight, NULL);
|
|
|
|
|
|
|
|
|
|
if (highlight)
|
|
|
|
|
{
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
GdkRectangle rect;
|
|
|
|
|
|
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (tool);
|
|
|
|
|
|
|
|
|
|
rect.x = private->x1;
|
|
|
|
|
rect.y = private->y1;
|
|
|
|
|
rect.width = private->x2 - private->x1;
|
|
|
|
|
rect.height = private->y2 - private->y1;
|
|
|
|
|
|
|
|
|
|
gimp_display_shell_set_highlight (shell, &rect);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
gimp_display_shell_set_highlight (shell, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-06-30 00:37:50 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* gimp_rectangle_tool_get_other_side:
|
|
|
|
|
* @rectangle_tool: A #GimpRectangleTool.
|
|
|
|
|
* @other_x: Pointer to where to set the other-x string.
|
|
|
|
|
* @other_y: Pointer to where to set the other-y string.
|
|
|
|
|
*
|
|
|
|
|
* Calculates what property variables that hold the coordinates of the opposite
|
|
|
|
|
* side (either the opposite corner or literally the opposite side), based on
|
|
|
|
|
* the current function. The opposite of a corner needs two coordinates, the
|
|
|
|
|
* opposite of a side only needs one.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
gimp_rectangle_tool_get_other_side (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
const gchar **other_x,
|
|
|
|
|
const gchar **other_y)
|
|
|
|
|
{
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
|
|
|
|
|
private = gimp_rectangle_tool_get_private (GIMP_RECTANGLE_TOOL (rectangle_tool));
|
|
|
|
|
|
|
|
|
|
switch (private->function)
|
|
|
|
|
{
|
|
|
|
|
case RECT_RESIZING_UPPER_RIGHT:
|
|
|
|
|
case RECT_RESIZING_LOWER_RIGHT:
|
|
|
|
|
case RECT_RESIZING_RIGHT:
|
|
|
|
|
*other_x = "x1";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_UPPER_LEFT:
|
|
|
|
|
case RECT_RESIZING_LOWER_LEFT:
|
|
|
|
|
case RECT_RESIZING_LEFT:
|
|
|
|
|
*other_x = "x2";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_TOP:
|
|
|
|
|
case RECT_RESIZING_BOTTOM:
|
|
|
|
|
default:
|
|
|
|
|
*other_x = NULL;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (private->function)
|
|
|
|
|
{
|
|
|
|
|
case RECT_RESIZING_LOWER_RIGHT:
|
|
|
|
|
case RECT_RESIZING_LOWER_LEFT:
|
|
|
|
|
case RECT_RESIZING_BOTTOM:
|
|
|
|
|
*other_y = "y1";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_UPPER_RIGHT:
|
|
|
|
|
case RECT_RESIZING_UPPER_LEFT:
|
|
|
|
|
case RECT_RESIZING_TOP:
|
|
|
|
|
*other_y = "y2";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_LEFT:
|
|
|
|
|
case RECT_RESIZING_RIGHT:
|
|
|
|
|
default:
|
|
|
|
|
*other_y = NULL;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gimp_rectangle_tool_get_other_side_coord (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
gint *other_side_x,
|
|
|
|
|
gint *other_side_y)
|
|
|
|
|
{
|
|
|
|
|
const gchar *other_x = NULL;
|
|
|
|
|
const gchar *other_y = NULL;
|
|
|
|
|
|
|
|
|
|
gimp_rectangle_tool_get_other_side (GIMP_RECTANGLE_TOOL (rectangle_tool),
|
|
|
|
|
&other_x,
|
|
|
|
|
&other_y);
|
|
|
|
|
if (other_x)
|
|
|
|
|
g_object_get (rectangle_tool,
|
|
|
|
|
other_x, other_side_x,
|
|
|
|
|
NULL);
|
|
|
|
|
if (other_y)
|
|
|
|
|
g_object_get (rectangle_tool,
|
|
|
|
|
other_y, other_side_y,
|
|
|
|
|
NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
gimp_rectangle_tool_set_other_side_coord (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
gint other_side_x,
|
|
|
|
|
gint other_side_y)
|
|
|
|
|
{
|
|
|
|
|
const gchar *other_x = NULL;
|
|
|
|
|
const gchar *other_y = NULL;
|
|
|
|
|
|
|
|
|
|
gimp_rectangle_tool_get_other_side (GIMP_RECTANGLE_TOOL (rectangle_tool),
|
|
|
|
|
&other_x,
|
|
|
|
|
&other_y);
|
|
|
|
|
if (other_x)
|
|
|
|
|
g_object_set (rectangle_tool,
|
|
|
|
|
other_x, other_side_x,
|
|
|
|
|
NULL);
|
|
|
|
|
if (other_y)
|
|
|
|
|
g_object_set (rectangle_tool,
|
|
|
|
|
other_y, other_side_y,
|
|
|
|
|
NULL);
|
|
|
|
|
}
|
2007-07-09 05:57:22 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* gimp_rectangle_tool_apply_coord:
|
|
|
|
|
* @param: A #GimpRectangleTool.
|
|
|
|
|
* @coord_x: X of coord.
|
|
|
|
|
* @coord_y: Y of coord.
|
|
|
|
|
*
|
|
|
|
|
* Adjust the rectangle to the new position specified by passed coordinate,
|
|
|
|
|
* taking fixed_center into account, which means it expands the rectagle around
|
|
|
|
|
* the center point.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
gimp_rectangle_tool_apply_coord (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
gint coord_x,
|
|
|
|
|
gint coord_y)
|
|
|
|
|
{
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
GimpRectangleOptions *options;
|
|
|
|
|
GimpRectangleOptionsPrivate *options_private;
|
|
|
|
|
|
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (rectangle_tool);
|
|
|
|
|
options = GIMP_RECTANGLE_TOOL_GET_OPTIONS (rectangle_tool);
|
|
|
|
|
options_private = GIMP_RECTANGLE_OPTIONS_GET_PRIVATE (options);
|
|
|
|
|
|
|
|
|
|
if (private->function == RECT_INACTIVE)
|
|
|
|
|
g_warning ("function is RECT_INACTIVE while mouse is moving");
|
|
|
|
|
|
|
|
|
|
if (private->function == RECT_MOVING)
|
|
|
|
|
{
|
|
|
|
|
/* Preserve width and height while moving the grab-point to where the
|
|
|
|
|
* cursor is.
|
|
|
|
|
*/
|
|
|
|
|
gint w = private->x2 - private->x1;
|
|
|
|
|
gint h = private->y2 - private->y1;
|
|
|
|
|
|
|
|
|
|
private->x1 = coord_x;
|
|
|
|
|
private->y1 = coord_y;
|
|
|
|
|
|
|
|
|
|
private->x2 = private->x1 + w;
|
|
|
|
|
private->y2 = private->y1 + h;
|
|
|
|
|
|
|
|
|
|
/* We are done already. */
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (private->function)
|
|
|
|
|
{
|
|
|
|
|
case RECT_RESIZING_UPPER_LEFT:
|
|
|
|
|
case RECT_RESIZING_LOWER_LEFT:
|
|
|
|
|
case RECT_RESIZING_LEFT:
|
|
|
|
|
private->x1 = coord_x;
|
|
|
|
|
|
|
|
|
|
if (options_private->fixed_center)
|
|
|
|
|
private->x2 = 2 * private->center_x_on_fixed_center - private->x1;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_UPPER_RIGHT:
|
|
|
|
|
case RECT_RESIZING_LOWER_RIGHT:
|
|
|
|
|
case RECT_RESIZING_RIGHT:
|
|
|
|
|
private->x2 = coord_x;
|
|
|
|
|
|
|
|
|
|
if (options_private->fixed_center)
|
|
|
|
|
private->x1 = 2 * private->center_x_on_fixed_center - private->x2;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (private->function)
|
|
|
|
|
{
|
|
|
|
|
case RECT_RESIZING_UPPER_LEFT:
|
|
|
|
|
case RECT_RESIZING_UPPER_RIGHT:
|
|
|
|
|
case RECT_RESIZING_TOP:
|
|
|
|
|
private->y1 = coord_y;
|
|
|
|
|
|
|
|
|
|
if (options_private->fixed_center)
|
|
|
|
|
private->y2 = 2 * private->center_y_on_fixed_center - private->y1;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_LOWER_LEFT:
|
|
|
|
|
case RECT_RESIZING_LOWER_RIGHT:
|
|
|
|
|
case RECT_RESIZING_BOTTOM:
|
|
|
|
|
private->y2 = coord_y;
|
|
|
|
|
|
|
|
|
|
if (options_private->fixed_center)
|
|
|
|
|
private->y1 = 2 * private->center_y_on_fixed_center - private->y2;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* gimp_rectangle_tool_clamp_width:
|
|
|
|
|
* @rectangle_tool: A #GimpRectangleTool.
|
|
|
|
|
* @clamped_sides: Where to put contrainment information.
|
|
|
|
|
* @constraint: Constraint to use.
|
|
|
|
|
* @symmetrically: Whether or not to clamp symmetrically.
|
|
|
|
|
*
|
|
|
|
|
* Clamps rectangle inside specified bounds, providing information of where
|
|
|
|
|
* clamping was done. Can also clamp symmetrically.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
gimp_rectangle_tool_clamp (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
ClampedSide *clamped_sides,
|
|
|
|
|
GimpRectangleConstraint constraint,
|
|
|
|
|
gboolean symmetrically)
|
|
|
|
|
{
|
|
|
|
|
gimp_rectangle_tool_clamp_width (rectangle_tool,
|
|
|
|
|
clamped_sides,
|
|
|
|
|
constraint,
|
|
|
|
|
symmetrically);
|
|
|
|
|
|
|
|
|
|
gimp_rectangle_tool_clamp_height (rectangle_tool,
|
|
|
|
|
clamped_sides,
|
|
|
|
|
constraint,
|
|
|
|
|
symmetrically);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* gimp_rectangle_tool_clamp_width:
|
|
|
|
|
* @rectangle_tool: A #GimpRectangleTool.
|
|
|
|
|
* @clamped_sides: Where to put contrainment information.
|
|
|
|
|
* @constraint: Constraint to use.
|
|
|
|
|
* @symmetrically: Whether or not to clamp symmetrically.
|
|
|
|
|
*
|
|
|
|
|
* Clamps height of rectangle. Set symmetrically to true when using for
|
|
|
|
|
* fixed_center:ed rectangles, since that will clamp symmetrically which is just
|
|
|
|
|
* what is needed.
|
|
|
|
|
*
|
|
|
|
|
* When this function constrains, it puts what it constrains in
|
|
|
|
|
* @constraint. This information is essential when an aspect ratio is to be
|
|
|
|
|
* applied.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
gimp_rectangle_tool_clamp_width (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
ClampedSide *clamped_sides,
|
|
|
|
|
GimpRectangleConstraint constraint,
|
|
|
|
|
gboolean symmetrically)
|
|
|
|
|
{
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
gint min_x;
|
|
|
|
|
gint max_x;
|
|
|
|
|
|
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (rectangle_tool);
|
|
|
|
|
|
|
|
|
|
gimp_rectangle_tool_get_constraints (rectangle_tool,
|
|
|
|
|
&min_x,
|
|
|
|
|
NULL,
|
|
|
|
|
&max_x,
|
|
|
|
|
NULL,
|
|
|
|
|
constraint);
|
|
|
|
|
if (private->x1 < min_x)
|
|
|
|
|
{
|
|
|
|
|
gint dx = min_x - private->x1;
|
|
|
|
|
|
|
|
|
|
private->x1 += dx;
|
|
|
|
|
|
|
|
|
|
if (symmetrically)
|
|
|
|
|
{
|
|
|
|
|
private->x2 -= dx;
|
|
|
|
|
|
|
|
|
|
if (private->x2 < min_x)
|
|
|
|
|
private->x1 = private->x2 = min_x;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (clamped_sides != NULL)
|
|
|
|
|
*clamped_sides |= CLAMPED_LEFT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (private->x2 > max_x)
|
|
|
|
|
{
|
|
|
|
|
gint dx = max_x - private->x2;
|
|
|
|
|
|
|
|
|
|
private->x2 += dx;
|
|
|
|
|
|
|
|
|
|
if (symmetrically)
|
|
|
|
|
{
|
|
|
|
|
private->x1 -= dx;
|
|
|
|
|
|
|
|
|
|
if (private->x1 > max_x)
|
|
|
|
|
private->x1 = max_x;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (clamped_sides != NULL)
|
|
|
|
|
*clamped_sides |= CLAMPED_RIGHT;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* gimp_rectangle_tool_clamp_height:
|
|
|
|
|
* @rectangle_tool: A #GimpRectangleTool.
|
|
|
|
|
* @clamped_sides: Where to put contrainment information.
|
|
|
|
|
* @constraint: Constraint to use.
|
|
|
|
|
* @symmetrically: Whether or not to clamp symmetrically.
|
|
|
|
|
*
|
|
|
|
|
* Clamps height of rectangle. Set symmetrically to true when using for
|
|
|
|
|
* fixed_center:ed rectangles, since that will clamp symmetrically which is just
|
|
|
|
|
* what is needed.
|
|
|
|
|
*
|
|
|
|
|
* When this function constrains, it puts what it constrains in
|
|
|
|
|
* @constraint. This information is essential when an aspect ratio is to be
|
|
|
|
|
* applied.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
gimp_rectangle_tool_clamp_height (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
ClampedSide *clamped_sides,
|
|
|
|
|
GimpRectangleConstraint constraint,
|
|
|
|
|
gboolean symmetrically)
|
|
|
|
|
{
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
gint min_y;
|
|
|
|
|
gint max_y;
|
|
|
|
|
|
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (rectangle_tool);
|
|
|
|
|
|
|
|
|
|
gimp_rectangle_tool_get_constraints (rectangle_tool,
|
|
|
|
|
NULL,
|
|
|
|
|
&min_y,
|
|
|
|
|
NULL,
|
|
|
|
|
&max_y,
|
|
|
|
|
constraint);
|
|
|
|
|
if (private->y1 < min_y)
|
|
|
|
|
{
|
|
|
|
|
gint dy = min_y - private->y1;
|
|
|
|
|
|
|
|
|
|
private->y1 += dy;
|
|
|
|
|
|
|
|
|
|
if (symmetrically)
|
|
|
|
|
{
|
|
|
|
|
private->y2 -= dy;
|
|
|
|
|
|
|
|
|
|
if (private->y2 < min_y)
|
|
|
|
|
private->y1 = private->y2 = min_y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (clamped_sides != NULL)
|
|
|
|
|
*clamped_sides |= CLAMPED_TOP;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (private->y2 > max_y)
|
|
|
|
|
{
|
|
|
|
|
gint dy = max_y - private->y2;
|
|
|
|
|
|
|
|
|
|
private->y2 += dy;
|
|
|
|
|
|
|
|
|
|
if (symmetrically)
|
|
|
|
|
{
|
|
|
|
|
private->y1 -= dy;
|
|
|
|
|
|
|
|
|
|
if (private->y1 > max_y)
|
|
|
|
|
private->y1 = private->y2 = max_y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (clamped_sides != NULL)
|
|
|
|
|
*clamped_sides |= CLAMPED_BOTTOM;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* gimp_rectangle_tool_keep_inside:
|
|
|
|
|
* @rectangle_tool: A #GimpRectangleTool.
|
|
|
|
|
*
|
|
|
|
|
* If the rectangle is outside of the canvas, move it into it. If the rectangle is
|
|
|
|
|
* larger than the canvas in any direction, make it fill the canvas in that direction.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
gimp_rectangle_tool_keep_inside (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
GimpRectangleConstraint constraint)
|
|
|
|
|
{
|
|
|
|
|
gimp_rectangle_tool_keep_inside_horizontally (rectangle_tool,
|
|
|
|
|
constraint);
|
|
|
|
|
|
|
|
|
|
gimp_rectangle_tool_keep_inside_vertically (rectangle_tool,
|
|
|
|
|
constraint);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* gimp_rectangle_tool_keep_inside_horizontally:
|
|
|
|
|
* @rectangle_tool: A #GimpRectangleTool.
|
|
|
|
|
* @constraint: Constraint to use.
|
|
|
|
|
*
|
|
|
|
|
* If the rectangle is outside of the given constraint horizontally, move it
|
|
|
|
|
* inside. If it is too big to fit inside, make it just as big as the width
|
|
|
|
|
* limit.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
gimp_rectangle_tool_keep_inside_horizontally (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
GimpRectangleConstraint constraint)
|
|
|
|
|
{
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
gint min_x;
|
|
|
|
|
gint max_x;
|
|
|
|
|
|
|
|
|
|
gimp_rectangle_tool_get_constraints (rectangle_tool,
|
|
|
|
|
&min_x,
|
|
|
|
|
NULL,
|
|
|
|
|
&max_x,
|
|
|
|
|
NULL,
|
|
|
|
|
constraint);
|
|
|
|
|
|
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (rectangle_tool);
|
|
|
|
|
|
|
|
|
|
if (max_x - min_x < private->x2 - private->x1)
|
|
|
|
|
{
|
|
|
|
|
private->x1 = min_x;
|
|
|
|
|
private->x2 = max_x;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (private->x1 < min_x)
|
|
|
|
|
{
|
|
|
|
|
gint dx = min_x - private->x1;
|
|
|
|
|
|
|
|
|
|
private->x1 += dx;
|
|
|
|
|
private->x2 += dx;
|
|
|
|
|
}
|
|
|
|
|
if (private->x2 > max_x)
|
|
|
|
|
{
|
|
|
|
|
gint dx = max_x - private->x2;
|
|
|
|
|
|
|
|
|
|
private->x1 += dx;
|
|
|
|
|
private->x2 += dx;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* gimp_rectangle_tool_keep_inside_vertically:
|
|
|
|
|
* @rectangle_tool: A #GimpRectangleTool.
|
|
|
|
|
* @constraint: Constraint to use.
|
|
|
|
|
*
|
|
|
|
|
* If the rectangle is outside of the given constraint vertically, move it
|
|
|
|
|
* inside. If it is too big to fit inside, make it just as big as the width
|
|
|
|
|
* limit.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
gimp_rectangle_tool_keep_inside_vertically (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
GimpRectangleConstraint constraint)
|
|
|
|
|
{
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
gint min_y;
|
|
|
|
|
gint max_y;
|
|
|
|
|
|
|
|
|
|
gimp_rectangle_tool_get_constraints (rectangle_tool,
|
|
|
|
|
NULL,
|
|
|
|
|
&min_y,
|
|
|
|
|
NULL,
|
|
|
|
|
&max_y,
|
|
|
|
|
constraint);
|
|
|
|
|
|
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (rectangle_tool);
|
|
|
|
|
|
|
|
|
|
if (max_y - min_y < private->y2 - private->y1)
|
|
|
|
|
{
|
|
|
|
|
private->y1 = min_y;
|
|
|
|
|
private->y2 = max_y;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (private->y1 < min_y)
|
|
|
|
|
{
|
|
|
|
|
gint dy = min_y - private->y1;
|
|
|
|
|
|
|
|
|
|
private->y1 += dy;
|
|
|
|
|
private->y2 += dy;
|
|
|
|
|
}
|
|
|
|
|
if (private->y2 > max_y)
|
|
|
|
|
{
|
|
|
|
|
gint dy = max_y - private->y2;
|
|
|
|
|
|
|
|
|
|
private->y1 += dy;
|
|
|
|
|
private->y2 += dy;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* gimp_rectangle_tool_apply_fixed_width:
|
|
|
|
|
* @rectangle_tool: A #GimpRectangleTool.
|
|
|
|
|
* @constraint: Constraint to use.
|
|
|
|
|
*
|
|
|
|
|
* Makes the rectangle have a fixed_width, following the constrainment rules
|
|
|
|
|
* of fixed widths as well. Please refer to the rectangle tools spec.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
gimp_rectangle_tool_apply_fixed_width (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
GimpRectangleConstraint constraint)
|
|
|
|
|
{
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
GimpRectangleOptions *options;
|
|
|
|
|
GimpRectangleOptionsPrivate *options_private;
|
|
|
|
|
|
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (rectangle_tool);
|
|
|
|
|
options = GIMP_RECTANGLE_TOOL_GET_OPTIONS (rectangle_tool);
|
|
|
|
|
options_private = GIMP_RECTANGLE_OPTIONS_GET_PRIVATE (options);
|
|
|
|
|
|
|
|
|
|
switch (private->function)
|
|
|
|
|
{
|
|
|
|
|
case RECT_RESIZING_LOWER_LEFT:
|
|
|
|
|
case RECT_RESIZING_UPPER_LEFT:
|
|
|
|
|
case RECT_RESIZING_LEFT:
|
|
|
|
|
|
|
|
|
|
/* We always want to center around fixed_center here, since we want the
|
|
|
|
|
* anchor point to be directly on the opposite side.
|
|
|
|
|
*/
|
|
|
|
|
private->x1 = private->center_x_on_fixed_center -
|
|
|
|
|
options_private->width / 2;
|
|
|
|
|
private->x2 = private->x1 + options_private->width;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_LOWER_RIGHT:
|
|
|
|
|
case RECT_RESIZING_UPPER_RIGHT:
|
|
|
|
|
case RECT_RESIZING_RIGHT:
|
|
|
|
|
|
|
|
|
|
/* We always want to center around fixed_center here, since we want the
|
|
|
|
|
* anchor point to be directly on the opposite side.
|
|
|
|
|
*/
|
|
|
|
|
private->x1 = private->center_x_on_fixed_center -
|
|
|
|
|
options_private->width / 2;
|
|
|
|
|
private->x2 = private->x1 + options_private->width;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Width shall be kept even after constraints, so we move the
|
|
|
|
|
* rectangle sideways rather than adjusting a side.
|
|
|
|
|
*/
|
|
|
|
|
gimp_rectangle_tool_keep_inside_horizontally (rectangle_tool,
|
|
|
|
|
constraint);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* gimp_rectangle_tool_apply_fixed_height:
|
|
|
|
|
* @rectangle_tool: A #GimpRectangleTool.
|
|
|
|
|
* @constraint: Constraint to use.
|
|
|
|
|
*
|
|
|
|
|
* Makes the rectangle have a fixed_height, following the constrainment rules
|
|
|
|
|
* of fixed heights as well. Please refer to the rectangle tools spec.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
gimp_rectangle_tool_apply_fixed_height (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
GimpRectangleConstraint constraint)
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
GimpRectangleOptions *options;
|
|
|
|
|
GimpRectangleOptionsPrivate *options_private;
|
|
|
|
|
|
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (rectangle_tool);
|
|
|
|
|
options = GIMP_RECTANGLE_TOOL_GET_OPTIONS (rectangle_tool);
|
|
|
|
|
options_private = GIMP_RECTANGLE_OPTIONS_GET_PRIVATE (options);
|
|
|
|
|
|
|
|
|
|
switch (private->function)
|
|
|
|
|
{
|
|
|
|
|
case RECT_RESIZING_UPPER_LEFT:
|
|
|
|
|
case RECT_RESIZING_UPPER_RIGHT:
|
|
|
|
|
case RECT_RESIZING_TOP:
|
|
|
|
|
|
|
|
|
|
/* We always want to center around fixed_center here, since we want the
|
|
|
|
|
* anchor point to be directly on the opposite side.
|
|
|
|
|
*/
|
|
|
|
|
private->y1 = private->center_y_on_fixed_center -
|
|
|
|
|
options_private->height / 2;
|
|
|
|
|
private->y2 = private->y1 + options_private->height;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_LOWER_LEFT:
|
|
|
|
|
case RECT_RESIZING_LOWER_RIGHT:
|
|
|
|
|
case RECT_RESIZING_BOTTOM:
|
|
|
|
|
|
|
|
|
|
/* We always want to center around fixed_center here, since we want the
|
|
|
|
|
* anchor point to be directly on the opposite side.
|
|
|
|
|
*/
|
|
|
|
|
private->y1 = private->center_y_on_fixed_center -
|
|
|
|
|
options_private->height / 2;
|
|
|
|
|
private->y2 = private->y1 + options_private->height;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Width shall be kept even after constraints, so we move the
|
|
|
|
|
* rectangle sideways rather than adjusting a side.
|
|
|
|
|
*/
|
|
|
|
|
gimp_rectangle_tool_keep_inside_vertically (rectangle_tool,
|
|
|
|
|
constraint);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* gimp_rectangle_tool_apply_aspect:
|
|
|
|
|
* @rectangle_tool: A #GimpRectangleTool.
|
|
|
|
|
* @aspect: The desired aspect.
|
|
|
|
|
* @clamped_sides: Bitfield of sides that have been clamped.
|
|
|
|
|
*
|
|
|
|
|
* Adjust the rectangle to the desired aspect.
|
|
|
|
|
*
|
|
|
|
|
* Sometimes, a side must not be moved outwards, for example if a the RIGHT side
|
|
|
|
|
* has been clamped previously, we must not move the RIGHT side to the right,
|
|
|
|
|
* since that would violate the constraint again. The clamped_sides bitfield
|
|
|
|
|
* keeps track of sides that have previously been clamped.
|
|
|
|
|
*
|
|
|
|
|
* If fixed_center is used, the function adjusts the aspect by symmetrically
|
|
|
|
|
* adjusting the left and right, or top and bottom side.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
gimp_rectangle_tool_apply_aspect (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
gdouble aspect,
|
|
|
|
|
gint clamped_sides)
|
|
|
|
|
{
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
GimpRectangleOptions *options;
|
|
|
|
|
GimpRectangleOptionsPrivate *options_private;
|
|
|
|
|
gint current_w;
|
|
|
|
|
gint current_h;
|
|
|
|
|
gdouble current_aspect;
|
|
|
|
|
SideToResize side_to_resize = SIDE_TO_RESIZE_NONE;
|
|
|
|
|
|
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (rectangle_tool);
|
|
|
|
|
options = GIMP_RECTANGLE_TOOL_GET_OPTIONS (rectangle_tool);
|
|
|
|
|
options_private = GIMP_RECTANGLE_OPTIONS_GET_PRIVATE (options);
|
|
|
|
|
|
|
|
|
|
current_w = private->x2 - private->x1;
|
|
|
|
|
current_h = private->y2 - private->y1;
|
|
|
|
|
|
|
|
|
|
current_aspect = current_w / (gdouble) current_h;
|
|
|
|
|
|
|
|
|
|
/* Do we have to do anything? */
|
|
|
|
|
if (current_aspect == aspect)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (options_private->fixed_center)
|
|
|
|
|
{
|
|
|
|
|
/* We may only adjust the sides symmetrically to get desired aspect. */
|
|
|
|
|
if (current_aspect > aspect)
|
|
|
|
|
{
|
|
|
|
|
/* We prefer to use top and bottom (since that will make the cursor
|
|
|
|
|
* remain on the rectangle edge), unless that is what the user has
|
|
|
|
|
* grabbed.
|
|
|
|
|
*/
|
|
|
|
|
switch (private->function)
|
|
|
|
|
{
|
|
|
|
|
case RECT_RESIZING_LEFT:
|
|
|
|
|
case RECT_RESIZING_RIGHT:
|
|
|
|
|
case RECT_RESIZING_UPPER_LEFT:
|
|
|
|
|
case RECT_RESIZING_UPPER_RIGHT:
|
|
|
|
|
case RECT_RESIZING_LOWER_LEFT:
|
|
|
|
|
case RECT_RESIZING_LOWER_RIGHT:
|
|
|
|
|
if (!(clamped_sides & CLAMPED_TOP) &&
|
|
|
|
|
!(clamped_sides & CLAMPED_BOTTOM))
|
|
|
|
|
{
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_TOP_AND_BOTTOM_SYMMETRICALLY;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_LEFT_AND_RIGHT_SYMMETRICALLY;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_TOP:
|
|
|
|
|
case RECT_RESIZING_BOTTOM:
|
|
|
|
|
default:
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_LEFT_AND_RIGHT_SYMMETRICALLY;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else /* (current_aspect < aspect) */
|
|
|
|
|
{
|
|
|
|
|
/* We prefer to use left and right (since that will make the cursor
|
|
|
|
|
* remain on the rectangle edge), unless that is what the user has
|
|
|
|
|
* grabbed.
|
|
|
|
|
*/
|
|
|
|
|
switch (private->function)
|
|
|
|
|
{
|
|
|
|
|
case RECT_RESIZING_TOP:
|
|
|
|
|
case RECT_RESIZING_BOTTOM:
|
|
|
|
|
case RECT_RESIZING_UPPER_LEFT:
|
|
|
|
|
case RECT_RESIZING_UPPER_RIGHT:
|
|
|
|
|
case RECT_RESIZING_LOWER_LEFT:
|
|
|
|
|
case RECT_RESIZING_LOWER_RIGHT:
|
|
|
|
|
if (!(clamped_sides & CLAMPED_LEFT) &&
|
|
|
|
|
!(clamped_sides & CLAMPED_RIGHT))
|
|
|
|
|
{
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_LEFT_AND_RIGHT_SYMMETRICALLY;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_TOP_AND_BOTTOM_SYMMETRICALLY;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_LEFT:
|
|
|
|
|
case RECT_RESIZING_RIGHT:
|
|
|
|
|
default:
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_TOP_AND_BOTTOM_SYMMETRICALLY;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (current_aspect > aspect)
|
|
|
|
|
{
|
|
|
|
|
/* We can safely pick LEFT or RIGHT, since using those sides will make the
|
|
|
|
|
* rectangle smaller, so we don't need to check for clamped_sides. We may
|
|
|
|
|
* only use TOP and BOTTOM if not those sides have been clamped, since
|
|
|
|
|
* using them will make the rectangle bigger.
|
|
|
|
|
*/
|
|
|
|
|
switch (private->function)
|
|
|
|
|
{
|
|
|
|
|
case RECT_RESIZING_UPPER_LEFT:
|
|
|
|
|
if (!(clamped_sides & CLAMPED_TOP))
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_TOP;
|
|
|
|
|
else
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_LEFT;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_UPPER_RIGHT:
|
|
|
|
|
if (!(clamped_sides & CLAMPED_TOP))
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_TOP;
|
|
|
|
|
else
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_RIGHT;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_LOWER_LEFT:
|
|
|
|
|
if (!(clamped_sides & CLAMPED_BOTTOM))
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_BOTTOM;
|
|
|
|
|
else
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_LEFT;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_LOWER_RIGHT:
|
|
|
|
|
if (!(clamped_sides & CLAMPED_BOTTOM))
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_BOTTOM;
|
|
|
|
|
else
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_RIGHT;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_LEFT:
|
|
|
|
|
if (!(clamped_sides & CLAMPED_TOP) && !(clamped_sides & CLAMPED_BOTTOM))
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_TOP_AND_BOTTOM_SYMMETRICALLY;
|
|
|
|
|
else
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_LEFT;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_RIGHT:
|
|
|
|
|
if (!(clamped_sides & CLAMPED_TOP) && !(clamped_sides & CLAMPED_BOTTOM))
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_TOP_AND_BOTTOM_SYMMETRICALLY;
|
|
|
|
|
else
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_RIGHT;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_BOTTOM:
|
|
|
|
|
case RECT_RESIZING_TOP:
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_LEFT_AND_RIGHT_SYMMETRICALLY;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_MOVING:
|
|
|
|
|
default:
|
|
|
|
|
if (!(clamped_sides & CLAMPED_BOTTOM))
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_BOTTOM;
|
|
|
|
|
else if (!(clamped_sides & CLAMPED_RIGHT))
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_RIGHT;
|
|
|
|
|
else if (!(clamped_sides & CLAMPED_TOP))
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_TOP;
|
|
|
|
|
else if (!(clamped_sides & CLAMPED_LEFT))
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_LEFT;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else /* (current_aspect < aspect) */
|
|
|
|
|
{
|
|
|
|
|
/* We can safely pick TOP or BOTTOM, since using those sides will make the
|
|
|
|
|
* rectangle smaller, so we don't need to check for clamped_sides. We may
|
|
|
|
|
* only use LEFT and RIGHT if not those sides have been clamped, since
|
|
|
|
|
* using them will make the rectangle bigger.
|
|
|
|
|
*/
|
|
|
|
|
switch (private->function)
|
|
|
|
|
{
|
|
|
|
|
case RECT_RESIZING_UPPER_LEFT:
|
|
|
|
|
if (!(clamped_sides & CLAMPED_LEFT))
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_LEFT;
|
|
|
|
|
else
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_TOP;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_UPPER_RIGHT:
|
|
|
|
|
if (!(clamped_sides & CLAMPED_RIGHT))
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_RIGHT;
|
|
|
|
|
else
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_TOP;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_LOWER_LEFT:
|
|
|
|
|
if (!(clamped_sides & CLAMPED_LEFT))
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_LEFT;
|
|
|
|
|
else
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_BOTTOM;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_LOWER_RIGHT:
|
|
|
|
|
if (!(clamped_sides & CLAMPED_RIGHT))
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_RIGHT;
|
|
|
|
|
else
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_BOTTOM;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_TOP:
|
|
|
|
|
if (!(clamped_sides & CLAMPED_LEFT) && !(clamped_sides & CLAMPED_RIGHT))
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_LEFT_AND_RIGHT_SYMMETRICALLY;
|
|
|
|
|
else
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_TOP;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_BOTTOM:
|
|
|
|
|
if (!(clamped_sides & CLAMPED_LEFT) && !(clamped_sides & CLAMPED_RIGHT))
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_LEFT_AND_RIGHT_SYMMETRICALLY;
|
|
|
|
|
else
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_BOTTOM;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_RESIZING_LEFT:
|
|
|
|
|
case RECT_RESIZING_RIGHT:
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_TOP_AND_BOTTOM_SYMMETRICALLY;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RECT_MOVING:
|
|
|
|
|
default:
|
|
|
|
|
if (!(clamped_sides & CLAMPED_BOTTOM))
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_BOTTOM;
|
|
|
|
|
else if (!(clamped_sides & CLAMPED_RIGHT))
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_RIGHT;
|
|
|
|
|
else if (!(clamped_sides & CLAMPED_TOP))
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_TOP;
|
|
|
|
|
else if (!(clamped_sides & CLAMPED_LEFT))
|
|
|
|
|
side_to_resize = SIDE_TO_RESIZE_LEFT;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* We now know what side(s) we should resize, so now we just solve the
|
|
|
|
|
* aspect equation for that side(s).
|
|
|
|
|
*/
|
|
|
|
|
switch (side_to_resize)
|
|
|
|
|
{
|
|
|
|
|
case SIDE_TO_RESIZE_NONE:
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
case SIDE_TO_RESIZE_LEFT:
|
|
|
|
|
private->x1 = private->x2 - aspect * current_h;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SIDE_TO_RESIZE_RIGHT:
|
|
|
|
|
private->x2 = private->x1 + aspect * current_h;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SIDE_TO_RESIZE_TOP:
|
|
|
|
|
private->y1 = private->y2 - current_w / aspect;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SIDE_TO_RESIZE_BOTTOM:
|
|
|
|
|
private->y2 = private->y1 + current_w / aspect;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SIDE_TO_RESIZE_TOP_AND_BOTTOM_SYMMETRICALLY:
|
|
|
|
|
{
|
|
|
|
|
gint correct_h = current_w / aspect;
|
|
|
|
|
|
|
|
|
|
private->y1 = private->center_y_on_fixed_center - correct_h / 2;
|
|
|
|
|
private->y2 = private->y1 + correct_h;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SIDE_TO_RESIZE_LEFT_AND_RIGHT_SYMMETRICALLY:
|
|
|
|
|
{
|
|
|
|
|
gint correct_w = current_h * aspect;
|
|
|
|
|
|
|
|
|
|
private->x1 = private->center_x_on_fixed_center - correct_w / 2;
|
|
|
|
|
private->x2 = private->x1 + correct_w;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* gimp_rectangle_tool_update_with_coord:
|
|
|
|
|
* @rectangle_tool: A #GimpRectangleTool.
|
|
|
|
|
* @new_x: New X-coordinate in the context of the current function.
|
|
|
|
|
* @new_y: New Y-coordinate in the context of the current function.
|
|
|
|
|
*
|
|
|
|
|
* The core rectangle adjustment function. It updates the rectangle for the
|
|
|
|
|
* passed cursor coordinate, taking current function and tool options into
|
|
|
|
|
* account. It also updates the current private->function if necessary.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
gimp_rectangle_tool_update_with_coord (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
gint new_x,
|
|
|
|
|
gint new_y)
|
|
|
|
|
{
|
|
|
|
|
GimpTool *tool;
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
GimpRectangleOptions *options;
|
|
|
|
|
GimpRectangleOptionsPrivate *options_private;
|
|
|
|
|
GimpRectangleConstraint constraint_to_use;
|
|
|
|
|
|
|
|
|
|
tool = GIMP_TOOL (rectangle_tool);
|
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (rectangle_tool);
|
|
|
|
|
options = GIMP_RECTANGLE_TOOL_GET_OPTIONS (rectangle_tool);
|
|
|
|
|
options_private = GIMP_RECTANGLE_OPTIONS_GET_PRIVATE (options);
|
|
|
|
|
|
|
|
|
|
/* Move the corner or edge the user currently has grabbed. */
|
|
|
|
|
gimp_rectangle_tool_apply_coord (rectangle_tool,
|
|
|
|
|
new_x,
|
|
|
|
|
new_y);
|
|
|
|
|
|
|
|
|
|
/* Update private->function. The function changes if the user "flips" the
|
|
|
|
|
* rectangle.
|
|
|
|
|
*/
|
|
|
|
|
gimp_rectangle_tool_check_function (rectangle_tool);
|
|
|
|
|
|
|
|
|
|
/* E.g. the crop tool will set up clamping always to be used, and this
|
|
|
|
|
* function handles that.
|
|
|
|
|
*/
|
|
|
|
|
gimp_rectangle_tool_handle_general_clamping (rectangle_tool);
|
|
|
|
|
|
|
|
|
|
/* Calculate what constraint to use when needed. */
|
|
|
|
|
constraint_to_use = gimp_rectangle_tool_get_constraint (rectangle_tool);
|
|
|
|
|
if (constraint_to_use == GIMP_RECTANGLE_CONSTRAIN_NONE)
|
|
|
|
|
constraint_to_use = GIMP_RECTANGLE_CONSTRAIN_IMAGE;
|
|
|
|
|
|
|
|
|
|
/* fixed_aspect and fixed_width/height are mutually exclusive. */
|
|
|
|
|
if (options_private->fixed_aspect)
|
|
|
|
|
{
|
|
|
|
|
gdouble aspect;
|
|
|
|
|
|
|
|
|
|
aspect = CLAMP (options_private->aspect_numerator /
|
|
|
|
|
options_private->aspect_denominator,
|
|
|
|
|
1.0 / tool->display->image->height,
|
|
|
|
|
tool->display->image->width);
|
|
|
|
|
|
|
|
|
|
if (private->function != RECT_MOVING)
|
|
|
|
|
{
|
|
|
|
|
ClampedSide clamped_sides = CLAMPED_NONE;
|
|
|
|
|
|
|
|
|
|
gimp_rectangle_tool_apply_aspect (rectangle_tool,
|
|
|
|
|
aspect,
|
|
|
|
|
clamped_sides);
|
|
|
|
|
|
|
|
|
|
/* After we have applied aspect, we might have taken the rectangle
|
|
|
|
|
* outside of constraint, so clamp and apply aspect again. We will get
|
|
|
|
|
* the right result this time, since 'clamped_sides' will be setup
|
|
|
|
|
* correctly now.
|
|
|
|
|
*/
|
|
|
|
|
gimp_rectangle_tool_clamp (rectangle_tool,
|
|
|
|
|
&clamped_sides,
|
|
|
|
|
constraint_to_use,
|
|
|
|
|
options_private->fixed_center);
|
|
|
|
|
|
|
|
|
|
gimp_rectangle_tool_apply_aspect (rectangle_tool,
|
|
|
|
|
aspect,
|
|
|
|
|
clamped_sides);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
gimp_rectangle_tool_apply_aspect (rectangle_tool,
|
|
|
|
|
aspect,
|
|
|
|
|
CLAMPED_NONE);
|
|
|
|
|
|
|
|
|
|
/* When fixed ratio is used, we always want the rectangle inside the
|
|
|
|
|
* canvas.
|
|
|
|
|
*/
|
|
|
|
|
gimp_rectangle_tool_keep_inside (rectangle_tool,
|
|
|
|
|
constraint_to_use);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else /* !options_private->fixed_aspect */
|
|
|
|
|
{
|
|
|
|
|
if (options_private->fixed_width)
|
|
|
|
|
{
|
|
|
|
|
gimp_rectangle_tool_apply_fixed_width (rectangle_tool,
|
|
|
|
|
constraint_to_use);
|
|
|
|
|
}
|
|
|
|
|
if (options_private->fixed_height)
|
|
|
|
|
{
|
|
|
|
|
gimp_rectangle_tool_apply_fixed_height (rectangle_tool,
|
|
|
|
|
constraint_to_use);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* gimp_rectangle_tool_get_constraints:
|
|
|
|
|
* @rectangle_tool: A #GimpRectagnelTool.
|
|
|
|
|
* @min_x:
|
|
|
|
|
* @min_y:
|
|
|
|
|
* @max_x:
|
|
|
|
|
* @max_y: Pointers of where to put constraints. NULL allowed.
|
|
|
|
|
* @constraint: Wether to return image or layer constraints.
|
|
|
|
|
*
|
|
|
|
|
* Calculates constraint coordinates for image or layer.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
gimp_rectangle_tool_get_constraints (GimpRectangleTool *rectangle_tool,
|
|
|
|
|
gint *min_x,
|
|
|
|
|
gint *min_y,
|
|
|
|
|
gint *max_x,
|
|
|
|
|
gint *max_y,
|
|
|
|
|
GimpRectangleConstraint constraint)
|
|
|
|
|
{
|
|
|
|
|
GimpTool *tool;
|
|
|
|
|
gint min_x_dummy;
|
|
|
|
|
gint min_y_dummy;
|
|
|
|
|
gint max_x_dummy;
|
|
|
|
|
gint max_y_dummy;
|
|
|
|
|
|
|
|
|
|
if (min_x == NULL)
|
|
|
|
|
min_x = &min_x_dummy;
|
|
|
|
|
if (min_y == NULL)
|
|
|
|
|
min_y = &min_y_dummy;
|
|
|
|
|
if (max_x == NULL)
|
|
|
|
|
max_x = &max_x_dummy;
|
|
|
|
|
if (max_y == NULL)
|
|
|
|
|
max_y = &max_y_dummy;
|
|
|
|
|
|
|
|
|
|
tool = GIMP_TOOL (rectangle_tool);
|
|
|
|
|
|
|
|
|
|
switch (constraint)
|
|
|
|
|
{
|
|
|
|
|
case GIMP_RECTANGLE_CONSTRAIN_IMAGE:
|
|
|
|
|
*min_x = 0;
|
|
|
|
|
*min_y = 0;
|
|
|
|
|
*max_x = tool->display->image->width;
|
|
|
|
|
*max_y = tool->display->image->height;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GIMP_RECTANGLE_CONSTRAIN_DRAWABLE:
|
|
|
|
|
{
|
|
|
|
|
GimpItem *item = GIMP_ITEM (tool->drawable);
|
|
|
|
|
|
|
|
|
|
gimp_item_offsets (item, min_x, min_y);
|
|
|
|
|
*max_x = *min_x + gimp_item_width (item);
|
|
|
|
|
*max_y = *min_y + gimp_item_height (item);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
g_warning ("Invalid rectangle constraint.\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* gimp_rectangle_tool_handle_general_clamping:
|
|
|
|
|
* @rectangle_tool: A #GimpRectangleTool.
|
|
|
|
|
*
|
|
|
|
|
* Make sure that contraints are applied to the rectangle, either by manually
|
|
|
|
|
* doing it, or by looking at the rectangle tool options and concluding it will
|
|
|
|
|
* be done later.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
gimp_rectangle_tool_handle_general_clamping (GimpRectangleTool *rectangle_tool)
|
|
|
|
|
{
|
|
|
|
|
GimpRectangleToolPrivate *private;
|
|
|
|
|
GimpRectangleOptions *options;
|
|
|
|
|
GimpRectangleOptionsPrivate *options_private;
|
|
|
|
|
GimpRectangleConstraint constraint;
|
|
|
|
|
|
|
|
|
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (rectangle_tool);
|
|
|
|
|
options = GIMP_RECTANGLE_TOOL_GET_OPTIONS (rectangle_tool);
|
|
|
|
|
options_private = GIMP_RECTANGLE_OPTIONS_GET_PRIVATE (options);
|
|
|
|
|
|
|
|
|
|
constraint = gimp_rectangle_tool_get_constraint (rectangle_tool);
|
|
|
|
|
|
|
|
|
|
/* fixed_aspect takes care of clamping by it self, so just return in case that
|
|
|
|
|
* is in use. Also return if no constraints should be enforced.
|
|
|
|
|
*/
|
|
|
|
|
if (options_private->fixed_aspect ||
|
|
|
|
|
(constraint != GIMP_RECTANGLE_CONSTRAIN_IMAGE &&
|
|
|
|
|
constraint != GIMP_RECTANGLE_CONSTRAIN_DRAWABLE))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* fixed_width and fixed_height takes care of clamping if they are turned on,
|
|
|
|
|
* so we only need to care if they are not on.
|
|
|
|
|
*/
|
|
|
|
|
if (!options_private->fixed_width)
|
|
|
|
|
{
|
|
|
|
|
/* Never clamp a moved rect; it causes the rectangle to get "consumed". */
|
|
|
|
|
if (private->function == RECT_MOVING)
|
|
|
|
|
{
|
|
|
|
|
gimp_rectangle_tool_keep_inside_horizontally (rectangle_tool,
|
|
|
|
|
constraint);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
gimp_rectangle_tool_clamp_width (rectangle_tool,
|
|
|
|
|
NULL,
|
|
|
|
|
constraint,
|
|
|
|
|
options_private->fixed_center);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!options_private->fixed_height)
|
|
|
|
|
{
|
|
|
|
|
/* Never clamp a moved rect; it causes the rectangle to get "consumed". */
|
|
|
|
|
if (private->function == RECT_MOVING)
|
|
|
|
|
{
|
|
|
|
|
gimp_rectangle_tool_keep_inside_vertically (rectangle_tool,
|
|
|
|
|
constraint);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
gimp_rectangle_tool_clamp_height (rectangle_tool,
|
|
|
|
|
NULL,
|
|
|
|
|
constraint,
|
|
|
|
|
options_private->fixed_center);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|