mirror of
https://gitlab.gnome.org/GNOME/gimp
synced 2024-10-22 12:32:37 +00:00
Bill Skaggs <weskaggs@primate.ucdavis.edu>
* app/tools/tools-enums.[ch]: add GimpRectangleConstraint enum. * app/tools/gimprectangletool.[ch]: replace "constrain" boolean with "constraint" enum property. Implement constraints in motion handler -- the implementation is rather elegant but pretty tricky. * app/tools/gimpcroptool.c: constrain to image bounds, or to active drawable bounds if "current layer only" option is checked. * app/tools/gimpellipseselecttool.c * app/tools/gimprectangleselecttool.c: no constraint. This addresses bug #353936 -- I would say fixes it, but it probably needs some fine-tuning. Also perhaps fixes bug #329817 a bit better than before.
This commit is contained in:
parent
e077975358
commit
5e9dc3c0d8
21
ChangeLog
21
ChangeLog
|
@ -1,3 +1,24 @@
|
||||||
|
2006-09-06 Bill Skaggs <weskaggs@primate.ucdavis.edu>
|
||||||
|
|
||||||
|
* app/tools/tools-enums.[ch]: add GimpRectangleConstraint
|
||||||
|
enum.
|
||||||
|
|
||||||
|
* app/tools/gimprectangletool.[ch]: replace "constrain"
|
||||||
|
boolean with "constraint" enum property. Implement
|
||||||
|
constraints in motion handler -- the implementation
|
||||||
|
is rather elegant but pretty tricky.
|
||||||
|
|
||||||
|
* app/tools/gimpcroptool.c: constrain to image bounds,
|
||||||
|
or to active drawable bounds if "current layer only"
|
||||||
|
option is checked.
|
||||||
|
|
||||||
|
* app/tools/gimpellipseselecttool.c
|
||||||
|
* app/tools/gimprectangleselecttool.c: no constraint.
|
||||||
|
|
||||||
|
This addresses bug #353936 -- I would say fixes it, but it
|
||||||
|
probably needs some fine-tuning. Also perhaps fixes
|
||||||
|
bug #329817 a bit better than before.
|
||||||
|
|
||||||
2006-09-06 Sven Neumann <sven@gimp.org>
|
2006-09-06 Sven Neumann <sven@gimp.org>
|
||||||
|
|
||||||
* app/plug-in/gimppluginmanager-history.c
|
* app/plug-in/gimppluginmanager-history.c
|
||||||
|
|
|
@ -46,8 +46,10 @@ static GObject *
|
||||||
gimp_crop_tool_constructor (GType type,
|
gimp_crop_tool_constructor (GType type,
|
||||||
guint n_params,
|
guint n_params,
|
||||||
GObjectConstructParam *params);
|
GObjectConstructParam *params);
|
||||||
|
static void gimp_crop_tool_dispose (GObject *object);
|
||||||
static void gimp_crop_tool_finalize (GObject *object);
|
static void gimp_crop_tool_finalize (GObject *object);
|
||||||
|
static gboolean gimp_crop_tool_initialize (GimpTool *tool,
|
||||||
|
GimpDisplay *display);
|
||||||
static void gimp_crop_tool_control (GimpTool *tool,
|
static void gimp_crop_tool_control (GimpTool *tool,
|
||||||
GimpToolAction action,
|
GimpToolAction action,
|
||||||
GimpDisplay *display);
|
GimpDisplay *display);
|
||||||
|
@ -71,13 +73,14 @@ static void gimp_crop_tool_cursor_update (GimpTool *tool,
|
||||||
GimpCoords *coords,
|
GimpCoords *coords,
|
||||||
GdkModifierType state,
|
GdkModifierType state,
|
||||||
GimpDisplay *display);
|
GimpDisplay *display);
|
||||||
|
|
||||||
static gboolean gimp_crop_tool_execute (GimpRectangleTool *rectangle,
|
static gboolean gimp_crop_tool_execute (GimpRectangleTool *rectangle,
|
||||||
gint x,
|
gint x,
|
||||||
gint y,
|
gint y,
|
||||||
gint w,
|
gint w,
|
||||||
gint h);
|
gint h);
|
||||||
|
static void gimp_crop_tool_notify_layer_only (GimpCropOptions *options,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
GimpTool *tool);
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_CODE (GimpCropTool, gimp_crop_tool, GIMP_TYPE_DRAW_TOOL,
|
G_DEFINE_TYPE_WITH_CODE (GimpCropTool, gimp_crop_tool, GIMP_TYPE_DRAW_TOOL,
|
||||||
G_IMPLEMENT_INTERFACE (GIMP_TYPE_RECTANGLE_TOOL,
|
G_IMPLEMENT_INTERFACE (GIMP_TYPE_RECTANGLE_TOOL,
|
||||||
|
@ -113,13 +116,13 @@ gimp_crop_tool_class_init (GimpCropToolClass *klass)
|
||||||
GimpDrawToolClass *draw_tool_class = GIMP_DRAW_TOOL_CLASS (klass);
|
GimpDrawToolClass *draw_tool_class = GIMP_DRAW_TOOL_CLASS (klass);
|
||||||
|
|
||||||
object_class->constructor = gimp_crop_tool_constructor;
|
object_class->constructor = gimp_crop_tool_constructor;
|
||||||
object_class->dispose = gimp_rectangle_tool_dispose;
|
object_class->dispose = gimp_crop_tool_dispose;
|
||||||
object_class->finalize = gimp_crop_tool_finalize;
|
object_class->finalize = gimp_crop_tool_finalize;
|
||||||
object_class->set_property = gimp_rectangle_tool_set_property;
|
object_class->set_property = gimp_rectangle_tool_set_property;
|
||||||
object_class->get_property = gimp_rectangle_tool_get_property;
|
object_class->get_property = gimp_rectangle_tool_get_property;
|
||||||
gimp_rectangle_tool_install_properties (object_class);
|
gimp_rectangle_tool_install_properties (object_class);
|
||||||
|
|
||||||
tool_class->initialize = gimp_rectangle_tool_initialize;
|
tool_class->initialize = gimp_crop_tool_initialize;
|
||||||
tool_class->control = gimp_crop_tool_control;
|
tool_class->control = gimp_crop_tool_control;
|
||||||
tool_class->button_press = gimp_crop_tool_button_press;
|
tool_class->button_press = gimp_crop_tool_button_press;
|
||||||
tool_class->button_release = gimp_crop_tool_button_release;
|
tool_class->button_release = gimp_crop_tool_button_release;
|
||||||
|
@ -139,7 +142,7 @@ gimp_crop_tool_init (GimpCropTool *crop_tool)
|
||||||
GimpRectangleTool *rect_tool = GIMP_RECTANGLE_TOOL (crop_tool);
|
GimpRectangleTool *rect_tool = GIMP_RECTANGLE_TOOL (crop_tool);
|
||||||
|
|
||||||
gimp_tool_control_set_tool_cursor (tool->control, GIMP_TOOL_CURSOR_CROP);
|
gimp_tool_control_set_tool_cursor (tool->control, GIMP_TOOL_CURSOR_CROP);
|
||||||
gimp_rectangle_tool_set_constrain (rect_tool, TRUE);
|
gimp_rectangle_tool_set_constraint (rect_tool, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -162,12 +165,49 @@ gimp_crop_tool_constructor (GType type,
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gimp_crop_tool_initialize (GimpTool *tool,
|
||||||
|
GimpDisplay *display)
|
||||||
|
{
|
||||||
|
GimpRectangleTool *rectangle = GIMP_RECTANGLE_TOOL (tool);
|
||||||
|
GObject *options = G_OBJECT (gimp_tool_get_options (tool));
|
||||||
|
gboolean layer_only;
|
||||||
|
|
||||||
|
g_object_get (options,
|
||||||
|
"layer-only", &layer_only,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
g_signal_connect_object (options, "notify::layer-only",
|
||||||
|
G_CALLBACK (gimp_crop_tool_notify_layer_only),
|
||||||
|
tool, 0);
|
||||||
|
|
||||||
|
if (layer_only)
|
||||||
|
gimp_rectangle_tool_set_constraint (rectangle, GIMP_RECTANGLE_CONSTRAIN_DRAWABLE);
|
||||||
|
else
|
||||||
|
gimp_rectangle_tool_set_constraint (rectangle, GIMP_RECTANGLE_CONSTRAIN_IMAGE);
|
||||||
|
|
||||||
|
return gimp_rectangle_tool_initialize (tool, display);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gimp_crop_tool_finalize (GObject *object)
|
gimp_crop_tool_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_crop_tool_dispose (GObject *object)
|
||||||
|
{
|
||||||
|
GimpTool *tool = GIMP_TOOL (object);
|
||||||
|
GObject *options = G_OBJECT (gimp_tool_get_options (tool));
|
||||||
|
|
||||||
|
gimp_rectangle_tool_dispose (object);
|
||||||
|
|
||||||
|
g_signal_handlers_disconnect_by_func (options,
|
||||||
|
G_CALLBACK (gimp_crop_tool_notify_layer_only),
|
||||||
|
tool);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gimp_crop_tool_control (GimpTool *tool,
|
gimp_crop_tool_control (GimpTool *tool,
|
||||||
GimpToolAction action,
|
GimpToolAction action,
|
||||||
|
@ -286,3 +326,20 @@ gimp_crop_tool_execute (GimpRectangleTool *rectangle,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_crop_tool_notify_layer_only (GimpCropOptions *options,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
GimpTool *tool)
|
||||||
|
{
|
||||||
|
GimpRectangleTool *rectangle = GIMP_RECTANGLE_TOOL (tool);
|
||||||
|
gboolean layer_only;
|
||||||
|
|
||||||
|
g_object_get (options,
|
||||||
|
"layer-only", &layer_only,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (layer_only)
|
||||||
|
gimp_rectangle_tool_set_constraint (rectangle, GIMP_RECTANGLE_CONSTRAIN_DRAWABLE);
|
||||||
|
else
|
||||||
|
gimp_rectangle_tool_set_constraint (rectangle, GIMP_RECTANGLE_CONSTRAIN_IMAGE);
|
||||||
|
}
|
||||||
|
|
|
@ -98,11 +98,9 @@ static void
|
||||||
gimp_ellipse_select_tool_init (GimpEllipseSelectTool *ellipse_select)
|
gimp_ellipse_select_tool_init (GimpEllipseSelectTool *ellipse_select)
|
||||||
{
|
{
|
||||||
GimpTool *tool = GIMP_TOOL (ellipse_select);
|
GimpTool *tool = GIMP_TOOL (ellipse_select);
|
||||||
GimpRectangleTool *rect_tool = GIMP_RECTANGLE_TOOL (ellipse_select);
|
|
||||||
|
|
||||||
gimp_tool_control_set_tool_cursor (tool->control,
|
gimp_tool_control_set_tool_cursor (tool->control,
|
||||||
GIMP_TOOL_CURSOR_ELLIPSE_SELECT);
|
GIMP_TOOL_CURSOR_ELLIPSE_SELECT);
|
||||||
gimp_rectangle_tool_set_constrain (rect_tool, FALSE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -177,15 +177,12 @@ static void
|
||||||
gimp_rect_select_tool_init (GimpRectSelectTool *rect_select)
|
gimp_rect_select_tool_init (GimpRectSelectTool *rect_select)
|
||||||
{
|
{
|
||||||
GimpTool *tool = GIMP_TOOL (rect_select);
|
GimpTool *tool = GIMP_TOOL (rect_select);
|
||||||
GimpRectangleTool *rect_tool = GIMP_RECTANGLE_TOOL (rect_select);
|
|
||||||
|
|
||||||
gimp_tool_control_set_tool_cursor (tool->control, GIMP_TOOL_CURSOR_RECT_SELECT);
|
gimp_tool_control_set_tool_cursor (tool->control, GIMP_TOOL_CURSOR_RECT_SELECT);
|
||||||
gimp_tool_control_set_dirty_mask (tool->control,
|
gimp_tool_control_set_dirty_mask (tool->control,
|
||||||
GIMP_DIRTY_IMAGE_SIZE |
|
GIMP_DIRTY_IMAGE_SIZE |
|
||||||
GIMP_DIRTY_SELECTION);
|
GIMP_DIRTY_SELECTION);
|
||||||
|
|
||||||
gimp_rectangle_tool_set_constrain (rect_tool, TRUE);
|
|
||||||
|
|
||||||
rect_select->undo = NULL;
|
rect_select->undo = NULL;
|
||||||
rect_select->redo = NULL;
|
rect_select->redo = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,6 @@ enum
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* speed of key movement */
|
/* speed of key movement */
|
||||||
#define ARROW_VELOCITY 25
|
#define ARROW_VELOCITY 25
|
||||||
|
|
||||||
|
@ -70,7 +69,7 @@ struct _GimpRectangleToolPrivate
|
||||||
|
|
||||||
guint function; /* moving or resizing */
|
guint function; /* moving or resizing */
|
||||||
|
|
||||||
gboolean constrain; /* constrain to image bounds */
|
GimpRectangleConstraint constraint; /* how to constrain rectangle */
|
||||||
|
|
||||||
/* Internal state */
|
/* Internal state */
|
||||||
gint startx; /* starting x coord */
|
gint startx; /* starting x coord */
|
||||||
|
@ -123,7 +122,9 @@ gint gimp_rectangle_tool_get_y2 (GimpRectangleTool *tool);
|
||||||
void gimp_rectangle_tool_set_function (GimpRectangleTool *tool,
|
void gimp_rectangle_tool_set_function (GimpRectangleTool *tool,
|
||||||
guint function);
|
guint function);
|
||||||
guint gimp_rectangle_tool_get_function (GimpRectangleTool *tool);
|
guint gimp_rectangle_tool_get_function (GimpRectangleTool *tool);
|
||||||
gboolean gimp_rectangle_tool_get_constrain (GimpRectangleTool *tool);
|
|
||||||
|
GimpRectangleConstraint
|
||||||
|
gimp_rectangle_tool_get_constraint (GimpRectangleTool *tool);
|
||||||
|
|
||||||
/* Rectangle helper functions */
|
/* Rectangle helper functions */
|
||||||
static void rectangle_tool_start (GimpRectangleTool *rectangle);
|
static void rectangle_tool_start (GimpRectangleTool *rectangle);
|
||||||
|
@ -154,6 +155,12 @@ static void gimp_rectangle_tool_notify_dimensions (GimpRectangleOptions *op
|
||||||
static void gimp_rectangle_tool_check_function (GimpRectangleTool *rectangle,
|
static void gimp_rectangle_tool_check_function (GimpRectangleTool *rectangle,
|
||||||
gint curx,
|
gint curx,
|
||||||
gint cury);
|
gint cury);
|
||||||
|
gboolean gimp_rectangle_tool_constraint_violated (GimpRectangleTool *rectangle,
|
||||||
|
gint x1,
|
||||||
|
gint y1,
|
||||||
|
gint x2,
|
||||||
|
gint y2,
|
||||||
|
gdouble *alpha);
|
||||||
|
|
||||||
static guint gimp_rectangle_tool_signals[LAST_SIGNAL] = { 0 };
|
static guint gimp_rectangle_tool_signals[LAST_SIGNAL] = { 0 };
|
||||||
|
|
||||||
|
@ -254,9 +261,11 @@ gimp_rectangle_tool_iface_base_init (GimpRectangleToolInterface *iface)
|
||||||
GIMP_PARAM_READWRITE));
|
GIMP_PARAM_READWRITE));
|
||||||
|
|
||||||
g_object_interface_install_property (iface,
|
g_object_interface_install_property (iface,
|
||||||
g_param_spec_boolean ("constrain",
|
g_param_spec_uint ("constraint",
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
FALSE,
|
GIMP_RECTANGLE_CONSTRAIN_NONE,
|
||||||
|
GIMP_RECTANGLE_CONSTRAIN_DRAWABLE,
|
||||||
|
GIMP_RECTANGLE_CONSTRAIN_NONE,
|
||||||
GIMP_PARAM_READWRITE));
|
GIMP_PARAM_READWRITE));
|
||||||
|
|
||||||
iface->rectangle_changed = NULL;
|
iface->rectangle_changed = NULL;
|
||||||
|
@ -331,8 +340,8 @@ gimp_rectangle_tool_install_properties (GObjectClass *klass)
|
||||||
GIMP_RECTANGLE_TOOL_PROP_FUNCTION,
|
GIMP_RECTANGLE_TOOL_PROP_FUNCTION,
|
||||||
"function");
|
"function");
|
||||||
g_object_class_override_property (klass,
|
g_object_class_override_property (klass,
|
||||||
GIMP_RECTANGLE_TOOL_PROP_CONSTRAIN,
|
GIMP_RECTANGLE_TOOL_PROP_CONSTRAINT,
|
||||||
"constrain");
|
"constraint");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -525,8 +534,8 @@ gimp_rectangle_tool_get_function (GimpRectangleTool *tool)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gimp_rectangle_tool_set_constrain (GimpRectangleTool *tool,
|
gimp_rectangle_tool_set_constraint (GimpRectangleTool *tool,
|
||||||
gboolean constrain)
|
GimpRectangleConstraint constraint)
|
||||||
{
|
{
|
||||||
GimpRectangleToolPrivate *private;
|
GimpRectangleToolPrivate *private;
|
||||||
|
|
||||||
|
@ -534,13 +543,13 @@ gimp_rectangle_tool_set_constrain (GimpRectangleTool *tool,
|
||||||
|
|
||||||
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (tool);
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (tool);
|
||||||
|
|
||||||
private->constrain = constrain ? TRUE : FALSE;
|
private->constraint = constraint;
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (tool), "constrain");
|
g_object_notify (G_OBJECT (tool), "constraint");
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
GimpRectangleConstraint
|
||||||
gimp_rectangle_tool_get_constrain (GimpRectangleTool *tool)
|
gimp_rectangle_tool_get_constraint (GimpRectangleTool *tool)
|
||||||
{
|
{
|
||||||
GimpRectangleToolPrivate *private;
|
GimpRectangleToolPrivate *private;
|
||||||
|
|
||||||
|
@ -548,7 +557,7 @@ gimp_rectangle_tool_get_constrain (GimpRectangleTool *tool)
|
||||||
|
|
||||||
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (tool);
|
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (tool);
|
||||||
|
|
||||||
return private->constrain;
|
return private->constraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -582,8 +591,8 @@ gimp_rectangle_tool_set_property (GObject *object,
|
||||||
case GIMP_RECTANGLE_TOOL_PROP_FUNCTION:
|
case GIMP_RECTANGLE_TOOL_PROP_FUNCTION:
|
||||||
gimp_rectangle_tool_set_function (tool, g_value_get_uint (value));
|
gimp_rectangle_tool_set_function (tool, g_value_get_uint (value));
|
||||||
break;
|
break;
|
||||||
case GIMP_RECTANGLE_TOOL_PROP_CONSTRAIN:
|
case GIMP_RECTANGLE_TOOL_PROP_CONSTRAINT:
|
||||||
gimp_rectangle_tool_set_constrain (tool, g_value_get_boolean (value));
|
gimp_rectangle_tool_set_constraint (tool, g_value_get_uint (value));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
|
@ -622,8 +631,8 @@ gimp_rectangle_tool_get_property (GObject *object,
|
||||||
case GIMP_RECTANGLE_TOOL_PROP_FUNCTION:
|
case GIMP_RECTANGLE_TOOL_PROP_FUNCTION:
|
||||||
g_value_set_uint (value, gimp_rectangle_tool_get_function (tool));
|
g_value_set_uint (value, gimp_rectangle_tool_get_function (tool));
|
||||||
break;
|
break;
|
||||||
case GIMP_RECTANGLE_TOOL_PROP_CONSTRAIN:
|
case GIMP_RECTANGLE_TOOL_PROP_CONSTRAINT:
|
||||||
g_value_set_boolean (value, gimp_rectangle_tool_get_constrain (tool));
|
g_value_set_uint (value, gimp_rectangle_tool_get_constraint (tool));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
|
@ -660,6 +669,8 @@ gimp_rectangle_tool_constructor (GObject *object)
|
||||||
g_signal_connect_object (options, "notify::dimensions-entry",
|
g_signal_connect_object (options, "notify::dimensions-entry",
|
||||||
G_CALLBACK (gimp_rectangle_tool_notify_dimensions),
|
G_CALLBACK (gimp_rectangle_tool_notify_dimensions),
|
||||||
rectangle, 0);
|
rectangle, 0);
|
||||||
|
|
||||||
|
gimp_rectangle_tool_set_constraint (rectangle, GIMP_RECTANGLE_CONSTRAIN_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -912,7 +923,6 @@ gimp_rectangle_tool_motion (GimpTool *tool,
|
||||||
gint x1, y1, x2, y2;
|
gint x1, y1, x2, y2;
|
||||||
gint curx, cury;
|
gint curx, cury;
|
||||||
gint inc_x, inc_y;
|
gint inc_x, inc_y;
|
||||||
gint min_x, min_y, max_x, max_y;
|
|
||||||
gint rx1, ry1, rx2, ry2;
|
gint rx1, ry1, rx2, ry2;
|
||||||
gboolean fixed_width;
|
gboolean fixed_width;
|
||||||
gboolean fixed_height;
|
gboolean fixed_height;
|
||||||
|
@ -921,6 +931,7 @@ gimp_rectangle_tool_motion (GimpTool *tool,
|
||||||
gdouble width, height;
|
gdouble width, height;
|
||||||
gdouble center_x, center_y;
|
gdouble center_x, center_y;
|
||||||
gboolean aspect_square;
|
gboolean aspect_square;
|
||||||
|
gdouble alpha;
|
||||||
|
|
||||||
g_return_if_fail (GIMP_IS_RECTANGLE_TOOL (tool));
|
g_return_if_fail (GIMP_IS_RECTANGLE_TOOL (tool));
|
||||||
|
|
||||||
|
@ -956,12 +967,6 @@ gimp_rectangle_tool_motion (GimpTool *tool,
|
||||||
"aspect-square", &aspect_square,
|
"aspect-square", &aspect_square,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
|
|
||||||
|
|
||||||
min_x = min_y = 0;
|
|
||||||
max_x = display->image->width;
|
|
||||||
max_y = display->image->height;
|
|
||||||
|
|
||||||
g_object_get (options,
|
g_object_get (options,
|
||||||
"width", &width,
|
"width", &width,
|
||||||
"height", &height,
|
"height", &height,
|
||||||
|
@ -1075,7 +1080,9 @@ gimp_rectangle_tool_motion (GimpTool *tool,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_object_get (options, "aspect", &aspect, NULL);
|
g_object_get (options, "aspect", &aspect, NULL);
|
||||||
aspect = CLAMP (aspect, 1.0 / max_y, max_x);
|
aspect = CLAMP (aspect,
|
||||||
|
1.0 / display->image->height,
|
||||||
|
display->image->width);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (function)
|
switch (function)
|
||||||
|
@ -1186,6 +1193,88 @@ gimp_rectangle_tool_motion (GimpTool *tool,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private->lastx = curx;
|
||||||
|
private->lasty = cury;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check to see whether the new rectangle obeys the boundary constraints, if any.
|
||||||
|
* If not, see whether we can downscale the mouse movement and call this
|
||||||
|
* motion handler again recursively. The reason for the recursive call is
|
||||||
|
* to avoid leaving the rectangle edge hanging some pixels away from the
|
||||||
|
* constraining boundary if the user moves the pointer quickly.
|
||||||
|
*/
|
||||||
|
if (gimp_rectangle_tool_constraint_violated (rectangle, x1, y1, x2, y2, &alpha))
|
||||||
|
{
|
||||||
|
GimpCoords new_coords;
|
||||||
|
|
||||||
|
inc_x *= alpha;
|
||||||
|
inc_y *= alpha;
|
||||||
|
|
||||||
|
if (inc_x != 0 || inc_y != 0)
|
||||||
|
{
|
||||||
|
new_coords.x = private->startx + inc_x;
|
||||||
|
new_coords.y = private->starty + inc_y;
|
||||||
|
|
||||||
|
gimp_rectangle_tool_motion (tool, &new_coords, time, state, display);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set startx, starty according to function, to keep rect on cursor */
|
||||||
|
switch (function)
|
||||||
|
{
|
||||||
|
case RECT_RESIZING_UPPER_LEFT:
|
||||||
|
private->startx = x1;
|
||||||
|
private->starty = y1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RECT_RESIZING_UPPER_RIGHT:
|
||||||
|
private->startx = x2;
|
||||||
|
private->starty = y1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RECT_RESIZING_LOWER_LEFT:
|
||||||
|
private->startx = x1;
|
||||||
|
private->starty = y2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RECT_RESIZING_LOWER_RIGHT:
|
||||||
|
private->startx = x2;
|
||||||
|
private->starty = y2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RECT_RESIZING_TOP:
|
||||||
|
private->startx = curx;
|
||||||
|
private->starty = y1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RECT_RESIZING_LEFT:
|
||||||
|
private->startx = x1;
|
||||||
|
private->starty = cury;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RECT_RESIZING_BOTTOM:
|
||||||
|
private->startx = curx;
|
||||||
|
private->starty = y2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RECT_RESIZING_RIGHT:
|
||||||
|
private->startx = x2;
|
||||||
|
private->starty = cury;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RECT_MOVING:
|
||||||
|
private->startx = curx;
|
||||||
|
private->starty = cury;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
|
||||||
|
|
||||||
/* make sure that the coords are in bounds */
|
/* make sure that the coords are in bounds */
|
||||||
g_object_set (rectangle,
|
g_object_set (rectangle,
|
||||||
"x1", MIN (x1, x2),
|
"x1", MIN (x1, x2),
|
||||||
|
@ -1194,15 +1283,6 @@ gimp_rectangle_tool_motion (GimpTool *tool,
|
||||||
"y2", MAX (y1, y2),
|
"y2", MAX (y1, y2),
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (function != RECT_CREATING)
|
|
||||||
{
|
|
||||||
private->startx = curx;
|
|
||||||
private->starty = cury;
|
|
||||||
}
|
|
||||||
|
|
||||||
private->lastx = curx;
|
|
||||||
private->lasty = cury;
|
|
||||||
|
|
||||||
/* recalculate the coordinates for rectangle_draw based on the new values */
|
/* recalculate the coordinates for rectangle_draw based on the new values */
|
||||||
gimp_rectangle_tool_configure (rectangle);
|
gimp_rectangle_tool_configure (rectangle);
|
||||||
|
|
||||||
|
@ -1283,16 +1363,8 @@ gimp_rectangle_tool_motion (GimpTool *tool,
|
||||||
|
|
||||||
gimp_tool_pop_status (tool, display);
|
gimp_tool_pop_status (tool, display);
|
||||||
|
|
||||||
if (gimp_rectangle_tool_get_constrain (rectangle))
|
|
||||||
{
|
|
||||||
w = MIN (rx2, max_x) - MAX (rx1, min_x);
|
|
||||||
h = MIN (ry2, max_y) - MAX (ry1, min_y);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
w = rx2 - rx1;
|
w = rx2 - rx1;
|
||||||
h = ry2 - ry1;
|
h = ry2 - ry1;
|
||||||
}
|
|
||||||
|
|
||||||
if (w > 0 && h > 0)
|
if (w > 0 && h > 0)
|
||||||
gimp_tool_push_status_coords (tool, display,
|
gimp_tool_push_status_coords (tool, display,
|
||||||
|
@ -2450,3 +2522,102 @@ gimp_rectangle_tool_no_movement (GimpRectangleTool *rectangle)
|
||||||
|
|
||||||
return (private->lastx == pressx && private->lasty == pressy);
|
return (private->lastx == pressx && private->lasty == pressy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check whether the coordinates extend outside the bounds of the image
|
||||||
|
* or active drawable, if it is constrained not to. If it does,
|
||||||
|
* caculate how much the current movement needs to be downscaled in
|
||||||
|
* order to obey the constraint.
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gimp_rectangle_tool_constraint_violated (GimpRectangleTool *rectangle,
|
||||||
|
gint x1,
|
||||||
|
gint y1,
|
||||||
|
gint x2,
|
||||||
|
gint y2,
|
||||||
|
gdouble *alpha)
|
||||||
|
{
|
||||||
|
GimpRectangleConstraint constraint = gimp_rectangle_tool_get_constraint (rectangle);
|
||||||
|
GimpTool *tool = GIMP_TOOL (rectangle);
|
||||||
|
GimpImage *image = tool->display->image;
|
||||||
|
gint min_x, min_y;
|
||||||
|
gint max_x, max_y;
|
||||||
|
|
||||||
|
switch (constraint)
|
||||||
|
{
|
||||||
|
case GIMP_RECTANGLE_CONSTRAIN_NONE:
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
case GIMP_RECTANGLE_CONSTRAIN_IMAGE:
|
||||||
|
min_x = 0;
|
||||||
|
min_y = 0;
|
||||||
|
max_x = image->width;
|
||||||
|
max_y = 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 FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x1 < min_x)
|
||||||
|
{
|
||||||
|
gint rx1;
|
||||||
|
|
||||||
|
g_object_get (rectangle,
|
||||||
|
"x1", &rx1,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
*alpha = (rx1 - min_x) / (gdouble) (rx1 - x1);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (y1 < min_y)
|
||||||
|
{
|
||||||
|
gint ry1;
|
||||||
|
|
||||||
|
g_object_get (rectangle,
|
||||||
|
"y1", &ry1,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
*alpha = (ry1 - min_y) / (gdouble) (ry1 - y1);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x2 > max_x)
|
||||||
|
{
|
||||||
|
gint rx2;
|
||||||
|
|
||||||
|
g_object_get (rectangle,
|
||||||
|
"x2", &rx2,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
*alpha = (max_x - rx2) / (gdouble) (x2 - rx2);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y2 > max_y)
|
||||||
|
{
|
||||||
|
gint ry2;
|
||||||
|
|
||||||
|
g_object_get (rectangle,
|
||||||
|
"y2", &ry2,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
*alpha = (max_y - ry2) / (gdouble) (y2 - ry2);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
|
@ -35,8 +35,8 @@ typedef enum
|
||||||
GIMP_RECTANGLE_TOOL_PROP_X2,
|
GIMP_RECTANGLE_TOOL_PROP_X2,
|
||||||
GIMP_RECTANGLE_TOOL_PROP_Y2,
|
GIMP_RECTANGLE_TOOL_PROP_Y2,
|
||||||
GIMP_RECTANGLE_TOOL_PROP_FUNCTION,
|
GIMP_RECTANGLE_TOOL_PROP_FUNCTION,
|
||||||
GIMP_RECTANGLE_TOOL_PROP_CONSTRAIN,
|
GIMP_RECTANGLE_TOOL_PROP_CONSTRAINT,
|
||||||
GIMP_RECTANGLE_TOOL_PROP_LAST = GIMP_RECTANGLE_TOOL_PROP_CONSTRAIN
|
GIMP_RECTANGLE_TOOL_PROP_LAST = GIMP_RECTANGLE_TOOL_PROP_CONSTRAINT
|
||||||
} GimpRectangleToolProp;
|
} GimpRectangleToolProp;
|
||||||
|
|
||||||
|
|
||||||
|
@ -131,8 +131,8 @@ gboolean gimp_rectangle_tool_execute (GimpRectangleTool *rect_too
|
||||||
void gimp_rectangle_tool_cancel (GimpRectangleTool *rect_tool);
|
void gimp_rectangle_tool_cancel (GimpRectangleTool *rect_tool);
|
||||||
void gimp_rectangle_tool_halt (GimpRectangleTool *rectangle);
|
void gimp_rectangle_tool_halt (GimpRectangleTool *rectangle);
|
||||||
void gimp_rectangle_tool_configure (GimpRectangleTool *rectangle);
|
void gimp_rectangle_tool_configure (GimpRectangleTool *rectangle);
|
||||||
void gimp_rectangle_tool_set_constrain (GimpRectangleTool *rectangle,
|
void gimp_rectangle_tool_set_constraint (GimpRectangleTool *rectangle,
|
||||||
gboolean constrain);
|
GimpRectangleConstraint constraint);
|
||||||
gboolean gimp_rectangle_tool_no_movement (GimpRectangleTool *rectangle);
|
gboolean gimp_rectangle_tool_no_movement (GimpRectangleTool *rectangle);
|
||||||
|
|
||||||
/* convenience functions */
|
/* convenience functions */
|
||||||
|
|
|
@ -73,6 +73,36 @@ gimp_rectangle_guide_get_type (void)
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GType
|
||||||
|
gimp_rectangle_constraint_get_type (void)
|
||||||
|
{
|
||||||
|
static const GEnumValue values[] =
|
||||||
|
{
|
||||||
|
{ GIMP_RECTANGLE_CONSTRAIN_NONE, "GIMP_RECTANGLE_CONSTRAIN_NONE", "none" },
|
||||||
|
{ GIMP_RECTANGLE_CONSTRAIN_IMAGE, "GIMP_RECTANGLE_CONSTRAIN_IMAGE", "image" },
|
||||||
|
{ GIMP_RECTANGLE_CONSTRAIN_DRAWABLE, "GIMP_RECTANGLE_CONSTRAIN_DRAWABLE", "drawable" },
|
||||||
|
{ 0, NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const GimpEnumDesc descs[] =
|
||||||
|
{
|
||||||
|
{ GIMP_RECTANGLE_CONSTRAIN_NONE, N_("No constraint"), NULL },
|
||||||
|
{ GIMP_RECTANGLE_CONSTRAIN_IMAGE, N_("Image bounds"), NULL },
|
||||||
|
{ GIMP_RECTANGLE_CONSTRAIN_DRAWABLE, N_("Drawable bounds"), NULL },
|
||||||
|
{ 0, NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static GType type = 0;
|
||||||
|
|
||||||
|
if (! type)
|
||||||
|
{
|
||||||
|
type = g_enum_register_static ("GimpRectangleConstraint", values);
|
||||||
|
gimp_enum_set_value_descriptions (type, descs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
GType
|
GType
|
||||||
gimp_rect_select_mode_get_type (void)
|
gimp_rect_select_mode_get_type (void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -48,6 +48,15 @@ typedef enum
|
||||||
GIMP_RECTANGLE_GUIDE_GOLDEN /*< desc="Golden sections" >*/
|
GIMP_RECTANGLE_GUIDE_GOLDEN /*< desc="Golden sections" >*/
|
||||||
} GimpRectangleGuide;
|
} GimpRectangleGuide;
|
||||||
|
|
||||||
|
GType gimp_rectangle_constraint_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GIMP_RECTANGLE_CONSTRAIN_NONE, /*< desc="No constraint" >*/
|
||||||
|
GIMP_RECTANGLE_CONSTRAIN_IMAGE, /*< desc="Image bounds" >*/
|
||||||
|
GIMP_RECTANGLE_CONSTRAIN_DRAWABLE /*< desc="Drawable bounds" >*/
|
||||||
|
} GimpRectangleConstraint;
|
||||||
|
|
||||||
|
|
||||||
#define GIMP_TYPE_RECT_SELECT_MODE (gimp_rect_select_mode_get_type ())
|
#define GIMP_TYPE_RECT_SELECT_MODE (gimp_rect_select_mode_get_type ())
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue