app/tools/gimpellipseselecttool.c applied a patch by Nils Bjorklund that

2005-03-07  Sven Neumann  <sven@gimp.org>

	* app/tools/gimpellipseselecttool.c
	* app/tools/gimprectselecttool.[ch]: applied a patch by Nils
	Bjorklund that should fix bug #143887 (selection rectangle "moves"
	when starting at the top-right corner).
This commit is contained in:
Sven Neumann 2005-03-07 21:31:22 +00:00 committed by Sven Neumann
parent 05f49ffc63
commit aa0f5fa634
4 changed files with 103 additions and 195 deletions

View File

@ -1,3 +1,11 @@
2005-03-07 Sven Neumann <sven@gimp.org>
* app/tools/gimpellipseselecttool.c
* app/tools/gimprectselecttool.[ch]: applied a patch by Nils
Bjorklund that should fix bug #143887 (selection rectangle "moves"
when starting at the top-right corner).
2005-03-07 Kevin Cozens <kcozens@cvs.gimp.org> 2005-03-07 Kevin Cozens <kcozens@cvs.gimp.org>
* plug-ins/script-fu/scripts/perspective-shadow.scm: Reverting previous * plug-ins/script-fu/scripts/perspective-shadow.scm: Reverting previous

View File

@ -136,18 +136,11 @@ static void
gimp_ellipse_select_tool_draw (GimpDrawTool *draw_tool) gimp_ellipse_select_tool_draw (GimpDrawTool *draw_tool)
{ {
GimpRectSelectTool *rect_sel = GIMP_RECT_SELECT_TOOL (draw_tool); GimpRectSelectTool *rect_sel = GIMP_RECT_SELECT_TOOL (draw_tool);
gint ix, iy;
gint iw, ih;
gimp_rect_select_tool_coords_to_integer (draw_tool->gdisp,
rect_sel->x, rect_sel->y,
rect_sel->w, rect_sel->h,
&ix, &iy,
&iw, &ih);
gimp_draw_tool_draw_arc (draw_tool, gimp_draw_tool_draw_arc (draw_tool,
FALSE, FALSE,
ix, iy, rect_sel->x, rect_sel->y,
iw, ih, rect_sel->w, rect_sel->h,
0, 23040, 0, 23040,
FALSE); FALSE);
} }

View File

@ -157,8 +157,9 @@ gimp_rect_select_tool_init (GimpRectSelectTool *rect_select)
gimp_tool_control_set_tool_cursor (tool->control, gimp_tool_control_set_tool_cursor (tool->control,
GIMP_TOOL_CURSOR_RECT_SELECT); GIMP_TOOL_CURSOR_RECT_SELECT);
rect_select->x = rect_select->y = 0.0; rect_select->sx = rect_select->sy = 0;
rect_select->w = rect_select->h = 0.0; rect_select->x = rect_select->y = 0;
rect_select->w = rect_select->h = 0;
} }
static void static void
@ -176,14 +177,15 @@ gimp_rect_select_tool_button_press (GimpTool *tool,
options = GIMP_SELECTION_OPTIONS (tool->tool_info->tool_options); options = GIMP_SELECTION_OPTIONS (tool->tool_info->tool_options);
rect_sel->x = coords->x; rect_sel->sx = RINT(coords->x);
rect_sel->y = coords->y; rect_sel->sy = RINT(coords->y);
rect_sel->w = 0.0; rect_sel->x = 0;
rect_sel->h = 0.0; rect_sel->y = 0;
rect_sel->w = 0;
rect_sel->h = 0;
rect_sel->lx = RINT(coords->x);
rect_sel->ly = RINT(coords->y);
rect_sel->center = FALSE; rect_sel->center = FALSE;
rect_sel->moved = FALSE;
rect_sel->last_coords = *coords;
rect_sel->fixed_mode = options->fixed_mode; rect_sel->fixed_mode = options->fixed_mode;
rect_sel->fixed_width = options->fixed_width; rect_sel->fixed_width = options->fixed_width;
@ -247,10 +249,6 @@ gimp_rect_select_tool_button_release (GimpTool *tool,
GimpDisplay *gdisp) GimpDisplay *gdisp)
{ {
GimpRectSelectTool *rect_sel = GIMP_RECT_SELECT_TOOL (tool); GimpRectSelectTool *rect_sel = GIMP_RECT_SELECT_TOOL (tool);
gdouble x, y;
gdouble w, h;
gint ix, iy;
gint iw, ih;
gimp_tool_pop_status (tool); gimp_tool_pop_status (tool);
@ -261,18 +259,7 @@ gimp_rect_select_tool_button_release (GimpTool *tool,
/* First take care of the case where the user "cancels" the action */ /* First take care of the case where the user "cancels" the action */
if (! (state & GDK_BUTTON3_MASK)) if (! (state & GDK_BUTTON3_MASK))
{ {
x = (rect_sel->w < 0) ? rect_sel->x + rect_sel->w : rect_sel->x; if (rect_sel->w == 0 || rect_sel->h == 0)
y = (rect_sel->h < 0) ? rect_sel->y + rect_sel->h : rect_sel->y;
w = ABS (rect_sel->w);
h = ABS (rect_sel->h);
gimp_rect_select_tool_coords_to_integer (gdisp,
x, y, w, h,
&ix, &iy, &iw, &ih);
if ((!rect_sel->moved || !iw || !ih)
&& rect_sel->fixed_mode == GIMP_RECT_SELECT_MODE_FREE)
{ {
/* If there is a floating selection, anchor it */ /* If there is a floating selection, anchor it */
if (gimp_image_floating_sel (gdisp->gimage)) if (gimp_image_floating_sel (gdisp->gimage))
@ -287,7 +274,8 @@ gimp_rect_select_tool_button_release (GimpTool *tool,
} }
gimp_rect_select_tool_rect_select (rect_sel, gimp_rect_select_tool_rect_select (rect_sel,
ix, iy, iw, ih); rect_sel->x, rect_sel->y,
rect_sel->w, rect_sel->h);
/* show selection on all views */ /* show selection on all views */
gimp_image_flush (gdisp->gimage); gimp_image_flush (gdisp->gimage);
@ -303,15 +291,8 @@ gimp_rect_select_tool_motion (GimpTool *tool,
{ {
GimpRectSelectTool *rect_sel = GIMP_RECT_SELECT_TOOL (tool); GimpRectSelectTool *rect_sel = GIMP_RECT_SELECT_TOOL (tool);
GimpSelectionTool *sel_tool = GIMP_SELECTION_TOOL (tool); GimpSelectionTool *sel_tool = GIMP_SELECTION_TOOL (tool);
gdouble ox, oy; gint mx, my;
gdouble w, h;
gdouble tw, th;
gdouble ratio; gdouble ratio;
gint ix, iy;
gint iw, ih;
if (coords->x != rect_sel->x || coords->y != rect_sel->y)
rect_sel->moved = TRUE;
if (sel_tool->op == SELECTION_ANCHOR) if (sel_tool->op == SELECTION_ANCHOR)
{ {
@ -322,153 +303,118 @@ gimp_rect_select_tool_motion (GimpTool *tool,
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool)); gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
if (state & GDK_MOD1_MASK) if (state & GDK_MOD1_MASK)
{ {
/* Just move the selection rectangle around */ /* Just move the selection rectangle around */
rect_sel->x += coords->x - rect_sel->last_coords.x; mx = RINT(coords->x) - rect_sel->lx;
rect_sel->y += coords->y - rect_sel->last_coords.y; my = RINT(coords->y) - rect_sel->ly;
rect_sel->sx += mx;
rect_sel->sy += my;
rect_sel->x += mx;
rect_sel->y += my;
} }
else else
{ {
/* Change the selection rectangle's size */ /* Change the selection rectangle's size, first calculate absolute
* width and height, then take care of quadrants.
*/
/* Calculate starting point */ if (rect_sel->fixed_mode == GIMP_RECT_SELECT_MODE_FIXED_SIZE)
if (rect_sel->center)
{ {
ox = rect_sel->x + rect_sel->w / 2.0; rect_sel->w = RINT(rect_sel->fixed_width);
oy = rect_sel->y + rect_sel->h / 2.0; rect_sel->h = RINT(rect_sel->fixed_height);
} }
else else
{ {
ox = rect_sel->x; rect_sel->w = abs(RINT(coords->x) - rect_sel->sx);
oy = rect_sel->y; rect_sel->h = abs(RINT(coords->y) - rect_sel->sy);
} }
switch (rect_sel->fixed_mode) if (rect_sel->fixed_mode == GIMP_RECT_SELECT_MODE_FIXED_RATIO)
{ {
case GIMP_RECT_SELECT_MODE_FIXED_SIZE: ratio = rect_sel->fixed_height / rect_sel->fixed_width;
w = ((coords->x - ox) > 0 ? if ( ( (gdouble) rect_sel->h) / ( (gdouble) rect_sel->w ) > ratio)
rect_sel->fixed_width : -rect_sel->fixed_width);
h = ((coords->y - oy) > 0 ?
rect_sel->fixed_height : -rect_sel->fixed_height);
break;
case GIMP_RECT_SELECT_MODE_FIXED_RATIO:
ratio = ((gdouble) rect_sel->fixed_height /
(gdouble) rect_sel->fixed_width);
tw = (coords->x - ox);
th = (coords->y - oy);
/* This is probably an inefficient way to do it, but it gives
* nicer, more predictable results than the original algorithm
*/
if ((abs (th) < (ratio * abs (tw))) &&
(abs (tw) > (abs (th) / ratio)))
{ {
w = tw; rect_sel->w = RINT(rect_sel->h / ratio);
h = (tw * ratio);
/* h should have the sign of th */
if ((th < 0 && h > 0) || (th > 0 && h < 0))
h = -h;
} }
else else
{ {
h = th; rect_sel->h = RINT(rect_sel->w * ratio);
w = (th / ratio);
/* w should have the sign of tw */
if ((tw < 0 && w > 0) || (tw > 0 && w < 0))
w = -w;
} }
break;
default:
w = (coords->x - ox);
h = (coords->y - oy);
break;
} }
/* If the shift key is down, then make the rectangle square (or /* If the shift key is down, then make the rectangle square (or
* ellipse circular) * ellipse circular)
*/ */
if ((state & GDK_SHIFT_MASK) && if ((state & GDK_SHIFT_MASK) &&
rect_sel->fixed_mode == GIMP_RECT_SELECT_MODE_FREE) rect_sel->fixed_mode == GIMP_RECT_SELECT_MODE_FREE)
{ {
gint s = MAX (abs (w), abs (h)); if (rect_sel->w > rect_sel->h)
{
if (w < 0) rect_sel->h = rect_sel->w;
w = -s; }
else else
w = s; {
rect_sel->w = rect_sel->h;
if (h < 0) }
h = -s;
else
h = s;
} }
/* If the control key is down, create the selection from the center out
*/
if (state & GDK_CONTROL_MASK) if (state & GDK_CONTROL_MASK)
{ {
rect_sel->center = TRUE; /* If the control key is down, create the selection from the center out */
if (rect_sel->fixed_mode == GIMP_RECT_SELECT_MODE_FIXED_SIZE)
switch (rect_sel->fixed_mode)
{ {
case GIMP_RECT_SELECT_MODE_FIXED_SIZE: /* Fixed size selection is simply centered over start point */
rect_sel->x = ox - w / 2.0; rect_sel->x = RINT(rect_sel->sx - rect_sel->w / 2.0);
rect_sel->y = oy - h / 2.0; rect_sel->y = RINT(rect_sel->sy - rect_sel->h / 2.0);
rect_sel->w = w; }
rect_sel->h = h; else
break; {
/* Non-fixed size is mirrored over starting point */
case GIMP_RECT_SELECT_MODE_FIXED_RATIO: rect_sel->x = rect_sel->sx - rect_sel->w;
rect_sel->x = ox - w; rect_sel->y = rect_sel->sy - rect_sel->h;
rect_sel->y = oy - h; rect_sel->w = rect_sel->w * 2;
rect_sel->w = w * 2.0; rect_sel->h = rect_sel->h * 2;
rect_sel->h = h * 2.0;
break;
default:
w = abs (w);
h = abs (h);
rect_sel->x = ox - w;
rect_sel->y = oy - h;
rect_sel->w = 2.0 * w;
rect_sel->h = 2.0 * h;
break;
} }
} }
else else
{ {
rect_sel->center = FALSE; /* Make (rect->x, rect->y) upper left hand point of selection */
if (coords->x > rect_sel->sx)
rect_sel->x = ox; {
rect_sel->y = oy; rect_sel->x = rect_sel->sx;
rect_sel->w = w; }
rect_sel->h = h; else
{
rect_sel->x = rect_sel->sx - rect_sel->w;
}
if (coords->y > rect_sel->sy)
{
rect_sel->y = rect_sel->sy;
}
else
{
rect_sel->y = rect_sel->sy - rect_sel->h;
}
} }
} }
rect_sel->last_coords = *coords; rect_sel->lx = RINT(coords->x);
rect_sel->ly = RINT(coords->y);
gimp_rect_select_tool_update_options (rect_sel, gdisp); gimp_rect_select_tool_update_options (rect_sel, gdisp);
gimp_tool_pop_status (tool); gimp_tool_pop_status (tool);
gimp_rect_select_tool_coords_to_integer (gdisp,
rect_sel->x, rect_sel->y,
rect_sel->w, rect_sel->h,
&ix, &iy,
&iw, &ih);
gimp_tool_push_status_coords (tool, gimp_tool_push_status_coords (tool,
_("Selection: "), _("Selection: "),
iw, rect_sel->w,
" x ", " x ",
ih); rect_sel->h);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool)); gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
} }
@ -477,17 +423,11 @@ static void
gimp_rect_select_tool_draw (GimpDrawTool *draw_tool) gimp_rect_select_tool_draw (GimpDrawTool *draw_tool)
{ {
GimpRectSelectTool *rect_sel = GIMP_RECT_SELECT_TOOL (draw_tool); GimpRectSelectTool *rect_sel = GIMP_RECT_SELECT_TOOL (draw_tool);
gint ix, iy;
gint iw, ih;
gimp_rect_select_tool_coords_to_integer (draw_tool->gdisp,
rect_sel->x, rect_sel->y,
rect_sel->w, rect_sel->h,
&ix, &iy,
&iw, &ih);
gimp_draw_tool_draw_rectangle (draw_tool, gimp_draw_tool_draw_rectangle (draw_tool,
FALSE, FALSE,
ix, iy, iw, ih, rect_sel->x, rect_sel->y,
rect_sel->w, rect_sel->h,
FALSE); FALSE);
} }
@ -598,17 +538,17 @@ gimp_rect_select_tool_update_options (GimpRectSelectTool *rect_sel,
if (shell->unit == GIMP_UNIT_PIXEL) if (shell->unit == GIMP_UNIT_PIXEL)
{ {
width = fabs (rect_sel->w); width = rect_sel->w;
height = fabs (rect_sel->h); height = rect_sel->h;
} }
else else
{ {
GimpImage *image = gdisp->gimage; GimpImage *image = gdisp->gimage;
width = (fabs (rect_sel->w) * width = (rect_sel->w *
_gimp_unit_get_factor (image->gimp, _gimp_unit_get_factor (image->gimp,
shell->unit) / image->xresolution); shell->unit) / image->xresolution);
height = (fabs (rect_sel->h) * height = (rect_sel->h *
_gimp_unit_get_factor (image->gimp, _gimp_unit_get_factor (image->gimp,
shell->unit) / image->yresolution); shell->unit) / image->yresolution);
} }
@ -619,25 +559,3 @@ gimp_rect_select_tool_update_options (GimpRectSelectTool *rect_sel,
"fixed-unit", shell->unit, "fixed-unit", shell->unit,
NULL); NULL);
} }
void
gimp_rect_select_tool_coords_to_integer (GimpDisplay *gdisp,
gdouble x,
gdouble y,
gdouble w,
gdouble h,
gint *ix,
gint *iy,
gint *iw,
gint *ih)
{
x = MIN (x, x + w);
y = MIN (y, y + h);
w = ABS (w);
h = ABS (h);
*ix = RINT (x);
*iy = RINT (y);
*iw = RINT (w + (x - *ix));
*ih = RINT (h + (y - *iy));
}

View File

@ -38,14 +38,13 @@ struct _GimpRectSelectTool
{ {
GimpSelectionTool parent_instance; GimpSelectionTool parent_instance;
gdouble x, y; /* upper left hand coordinate */ gint sx, sy; /* start coordinate where the button is
gdouble w, h; /* width and height */ * first pressed */
gint x, y; /* upper left coordinate of selection */
gint w, h; /* width, height of selection always >=0 */
gint lx, ly; /* last coordinate of mouse cursor */
gboolean center; /* is the selection being created from the gboolean center; /* is the selection being created from the
* center out? */ * center out? */
gboolean moved; /* ever moved since button press? */
GimpCoords last_coords; /* last button_press/motion coords */
GimpRectSelectMode fixed_mode; GimpRectSelectMode fixed_mode;
gdouble fixed_width; gdouble fixed_width;
gdouble fixed_height; gdouble fixed_height;
@ -76,14 +75,4 @@ void gimp_rect_select_tool_rect_select (GimpRectSelectTool *rect_tool,
gint w, gint w,
gint h); gint h);
void gimp_rect_select_tool_coords_to_integer (GimpDisplay *display,
gdouble x,
gdouble y,
gdouble w,
gdouble h,
gint *ix,
gint *iy,
gint *iw,
gint *ih);
#endif /* __GIMP_RECT_SELECT_TOOL_H__ */ #endif /* __GIMP_RECT_SELECT_TOOL_H__ */