Commit ed9bc271 authored by William Skaggs's avatar William Skaggs
Browse files

Bill Skaggs <weskaggs@primate.ucdavis.edu>

	* libgimpwidgets/gimpsizeentry.[ch]: added function
	gimp_size_entry_show_unit_menu() for convenience.

	* app/tools/gimprectangleoptions.[ch]
	* app/tools/gimprectangletool.[ch]:  more work on
	controls in Tool Options.  Can now resize rectangle
	by dragging any corner or edge -- move rectangle by
	clicking inside and dragging.
parent 73bfd572
2005-03-09 Bill Skaggs <weskaggs@primate.ucdavis.edu>
* libgimpwidgets/gimpsizeentry.[ch]: added function
gimp_size_entry_show_unit_menu() for convenience.
* app/tools/gimprectangleoptions.[ch]
* app/tools/gimprectangletool.[ch]: more work on
controls in Tool Options. Can now resize rectangle
by dragging any corner or edge -- move rectangle by
clicking inside and dragging.
2005-03-09 Sven Neumann <sven@gimp.org>
* app/widgets/gimpcontainerview.c
......
......@@ -43,10 +43,16 @@ enum
{
PROP_0,
PROP_HIGHLIGHT,
PROP_CONSTRAINT,
PROP_FIXED_WIDTH,
PROP_WIDTH,
PROP_FIXED_HEIGHT,
PROP_HEIGHT,
PROP_FIXED_ASPECT,
PROP_ASPECT,
PROP_FIXED_CENTER,
PROP_CENTER_X,
PROP_CENTER_Y,
PROP_UNIT
};
......@@ -109,18 +115,45 @@ gimp_rectangle_options_class_init (GimpRectangleOptionsClass *klass)
TRUE,
0);
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_FIXED_WIDTH,
"fixed-width", N_("Fixed width"),
FALSE, 0);
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_WIDTH,
"width", N_("Width"),
0.0, GIMP_MAX_IMAGE_SIZE, 1.0,
0);
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_FIXED_HEIGHT,
"fixed-height", N_("Fixed height"),
FALSE, 0);
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_HEIGHT,
"height", N_("Height"),
0.0, GIMP_MAX_IMAGE_SIZE, 1.0,
0);
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_FIXED_ASPECT,
"fixed-aspect", N_("Fixed aspect"),
FALSE, 0);
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_ASPECT,
"aspect", N_("Aspect"),
0.0, GIMP_MAX_IMAGE_SIZE, 1.0,
0);
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_FIXED_CENTER,
"fixed-center", N_("Fixed center"),
FALSE, 0);
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_CENTER_X,
"center-x", N_("Center X"),
0.0, GIMP_MAX_IMAGE_SIZE, 1.0,
0);
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_CENTER_Y,
"center-y", N_("Center Y"),
0.0, GIMP_MAX_IMAGE_SIZE, 1.0,
0);
GIMP_CONFIG_INSTALL_PROP_UNIT (object_class, PROP_UNIT,
"unit", NULL,
TRUE, FALSE, GIMP_UNIT_PIXEL, 0);
}
static void
......@@ -136,19 +169,36 @@ gimp_rectangle_options_set_property (GObject *object,
case PROP_HIGHLIGHT:
options->highlight = g_value_get_boolean (value);
break;
case PROP_FIXED_WIDTH:
options->fixed_width = g_value_get_boolean (value);
break;
case PROP_WIDTH:
options->width = g_value_get_double (value);
break;
case PROP_FIXED_HEIGHT:
options->fixed_height = g_value_get_boolean (value);
break;
case PROP_HEIGHT:
options->height = g_value_get_double (value);
break;
case PROP_FIXED_ASPECT:
options->fixed_aspect = g_value_get_boolean (value);
break;
case PROP_ASPECT:
options->aspect = g_value_get_double (value);
break;
case PROP_FIXED_CENTER:
options->fixed_center = g_value_get_boolean (value);
break;
case PROP_CENTER_X:
options->center_x = g_value_get_double (value);
break;
case PROP_CENTER_Y:
options->center_y = g_value_get_double (value);
break;
case PROP_UNIT:
options->unit = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
......@@ -168,19 +218,36 @@ gimp_rectangle_options_get_property (GObject *object,
case PROP_HIGHLIGHT:
g_value_set_boolean (value, options->highlight);
break;
case PROP_FIXED_WIDTH:
g_value_set_boolean (value, options->fixed_width);
break;
case PROP_WIDTH:
g_value_set_double (value, options->width);
break;
case PROP_FIXED_HEIGHT:
g_value_set_boolean (value, options->fixed_height);
break;
case PROP_HEIGHT:
g_value_set_double (value, options->height);
break;
case PROP_FIXED_ASPECT:
g_value_set_boolean (value, options->fixed_aspect);
break;
case PROP_ASPECT:
g_value_set_double (value, options->aspect);
break;
case PROP_FIXED_CENTER:
g_value_set_boolean (value, options->fixed_center);
break;
case PROP_CENTER_X:
g_value_set_double (value, options->center_x);
break;
case PROP_CENTER_Y:
g_value_set_double (value, options->center_y);
break;
case PROP_UNIT:
g_value_set_int (value, options->unit);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
......@@ -194,6 +261,11 @@ gimp_rectangle_options_gui (GimpToolOptions *tool_options)
GtkWidget *vbox;
GtkWidget *button;
GtkWidget *controls_container;
GtkWidget *table;
GtkWidget *entry;
GtkWidget *hbox;
GtkWidget *label;
GtkWidget *spinbutton;
vbox = gimp_selection_options_gui (tool_options);
......@@ -203,6 +275,63 @@ gimp_rectangle_options_gui (GimpToolOptions *tool_options)
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
table = gtk_table_new (6, 3, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 5);
gtk_box_pack_start (GTK_BOX (hbox), table, FALSE, FALSE, 0);
label = gtk_label_new (_("Fix"));
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 0, 1);
gtk_widget_show (label);
button = gimp_prop_check_button_new (config, "fixed-width",
_("Width"));
gtk_widget_show (button);
gtk_table_attach_defaults (GTK_TABLE (table), button, 0, 1, 1, 2);
entry = gimp_prop_size_entry_new (config, "width", "unit", "%a",
GIMP_SIZE_ENTRY_UPDATE_SIZE, 300);
gimp_size_entry_show_unit_menu (GIMP_SIZE_ENTRY (entry), FALSE);
gtk_table_attach_defaults (GTK_TABLE (table), entry, 1, 2, 1, 2);
gtk_widget_show (entry);
button = gimp_prop_check_button_new (config, "fixed-height",
_("Height"));
gtk_widget_show (button);
gtk_table_attach_defaults (GTK_TABLE (table), button, 0, 1, 2, 3);
entry = gimp_prop_size_entry_new (config, "height", "unit", "%a",
GIMP_SIZE_ENTRY_UPDATE_SIZE, 300);
gimp_size_entry_show_unit_menu (GIMP_SIZE_ENTRY (entry), FALSE);
gtk_table_attach_defaults (GTK_TABLE (table), entry, 1, 2, 2, 3);
gtk_widget_show (entry);
button = gimp_prop_check_button_new (config, "fixed-aspect",
_("Aspect"));
gtk_widget_show (button);
gtk_table_attach_defaults (GTK_TABLE (table), button, 0, 1, 3, 4);
spinbutton = gimp_prop_spin_button_new (config, "aspect", 0.01, 0.1, 4);
gtk_table_attach_defaults (GTK_TABLE (table), spinbutton, 1, 2, 3, 4);
gtk_widget_show (spinbutton);
button = gimp_prop_check_button_new (config, "fixed-center",
_("Center"));
gtk_widget_show (button);
gtk_table_attach_defaults (GTK_TABLE (table), button, 0, 1, 4, 6);
entry = gimp_prop_size_entry_new (config, "center-x", "unit", "%a",
GIMP_SIZE_ENTRY_UPDATE_SIZE, 300);
gimp_size_entry_show_unit_menu (GIMP_SIZE_ENTRY (entry), FALSE);
gtk_table_attach_defaults (GTK_TABLE (table), entry, 1, 2, 4, 5);
gtk_widget_show (entry);
entry = gimp_prop_size_entry_new (config, "center-y", "unit", "%a",
GIMP_SIZE_ENTRY_UPDATE_SIZE, 300);
gimp_size_entry_show_unit_menu (GIMP_SIZE_ENTRY (entry), FALSE);
gtk_table_attach_defaults (GTK_TABLE (table), entry, 1, 2, 5, 6);
gtk_widget_show (entry);
gtk_widget_show (table);
controls_container = gtk_vbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), controls_container, FALSE, FALSE, 0);
gtk_widget_show (controls_container);
......
......@@ -40,22 +40,20 @@ struct _GimpRectangleOptions
gboolean highlight;
gdouble x1;
gdouble y1;
gdouble x2;
gdouble y2;
gboolean fixed_width;
gdouble width;
gdouble xresolution;
gdouble yresolution;
gboolean fixed_height;
gdouble height;
gint image_width;
gint image_height;
gboolean fixed_aspect;
gdouble aspect;
GimpUnit unit;
gboolean fixed_center;
gdouble center_x;
gdouble center_y;
gdouble width;
gdouble height;
gdouble aspect;
GimpUnit unit;
};
......
......@@ -433,30 +433,67 @@ gimp_rectangle_tool_motion (GimpTool *tool,
rectangle->change_aspect_ratio = TRUE;
break;
case RECT_RESIZING_UPPER_LEFT:
case RECT_RESIZING_LOWER_LEFT:
case RECT_RESIZING_LEFT:
x1 = rectangle->x1 + inc_x;
y1 = rectangle->y1 + inc_y;
x2 = MAX (x1, rectangle->x2);
y2 = MAX (y1, rectangle->y2);
rectangle->startx = curx;
rectangle->starty = cury;
break;
case RECT_RESIZING_UPPER_RIGHT:
case RECT_RESIZING_LOWER_RIGHT:
case RECT_RESIZING_RIGHT:
x2 = rectangle->x2 + inc_x;
y2 = rectangle->y2 + inc_y;
x1 = MIN (rectangle->x1, x2);
y1 = MIN (rectangle->y1, y2);
rectangle->startx = curx;
rectangle->starty = cury;
break;
case RECT_RESIZING_BOTTOM:
case RECT_RESIZING_TOP:
x1 = rectangle->x1;
x2 = rectangle->x2;
rectangle->startx = curx;
break;
case RECT_MOVING:
x1 = rectangle->x1 + inc_x;
x2 = rectangle->x2 + inc_x;
rectangle->startx = curx;
break;
}
switch (rectangle->function)
{
case RECT_CREATING:
break;
case RECT_RESIZING_UPPER_LEFT:
case RECT_RESIZING_UPPER_RIGHT:
case RECT_RESIZING_TOP:
y1 = rectangle->y1 + inc_y;
y2 = MAX (y1, rectangle->y2);
rectangle->starty = cury;
break;
case RECT_RESIZING_LOWER_LEFT:
case RECT_RESIZING_LOWER_RIGHT:
case RECT_RESIZING_BOTTOM:
y2 = rectangle->y2 + inc_y;
y1 = MIN (rectangle->y1, y2);
rectangle->starty = cury;
break;
case RECT_RESIZING_RIGHT:
case RECT_RESIZING_LEFT:
y1 = rectangle->y1;
y2 = rectangle->y2;
rectangle->starty = cury;
break;
case RECT_MOVING:
y1 = rectangle->y1 + inc_y;
y2 = rectangle->y2 + inc_y;
rectangle->startx = curx;
rectangle->starty = cury;
break;
}
......@@ -475,20 +512,54 @@ gimp_rectangle_tool_motion (GimpTool *tool,
switch (rectangle->function)
{
case RECT_RESIZING_LEFT:
case RECT_RESIZING_UPPER_LEFT:
gimp_tool_control_set_snap_offsets (tool->control,
rectangle->x1 - coords->x,
rectangle->y1 - coords->y,
0, 0);
break;
case RECT_RESIZING_RIGHT:
case RECT_RESIZING_UPPER_RIGHT:
gimp_tool_control_set_snap_offsets (tool->control,
rectangle->x2 - coords->x,
rectangle->y1 - coords->y,
0, 0);
break;
case RECT_RESIZING_LOWER_LEFT:
gimp_tool_control_set_snap_offsets (tool->control,
rectangle->x1 - coords->x,
rectangle->y2 - coords->y,
0, 0);
break;
case RECT_RESIZING_LOWER_RIGHT:
gimp_tool_control_set_snap_offsets (tool->control,
rectangle->x2 - coords->x,
rectangle->y2 - coords->y,
0, 0);
break;
case RECT_RESIZING_LEFT:
gimp_tool_control_set_snap_offsets (tool->control,
rectangle->x1 - coords->x, 0, 0, 0);
break;
case RECT_RESIZING_RIGHT:
gimp_tool_control_set_snap_offsets (tool->control,
rectangle->x2 - coords->x, 0, 0, 0);
break;
case RECT_RESIZING_TOP:
gimp_tool_control_set_snap_offsets (tool->control,
0, rectangle->y1 - coords->y, 0, 0);
break;
case RECT_RESIZING_BOTTOM:
gimp_tool_control_set_snap_offsets (tool->control,
0, rectangle->y2 - coords->y, 0, 0);
break;
case RECT_MOVING:
gimp_tool_control_set_snap_offsets (tool->control,
rectangle->x1 - coords->x,
......@@ -504,8 +575,8 @@ gimp_rectangle_tool_motion (GimpTool *tool,
gimp_rectangle_tool_update_options (rectangle, gdisp);
if (rectangle->function == RECT_CREATING ||
rectangle->function == RECT_RESIZING_LEFT ||
rectangle->function == RECT_RESIZING_RIGHT)
rectangle->function == RECT_RESIZING_UPPER_LEFT ||
rectangle->function == RECT_RESIZING_LOWER_RIGHT)
{
gimp_tool_pop_status (tool);
......@@ -604,10 +675,15 @@ gimp_rectangle_tool_oper_update (GimpTool *tool,
{
GimpRectangleTool *rectangle = GIMP_RECTANGLE_TOOL (tool);
GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);
gboolean inside_x;
gboolean inside_y;
if (tool->gdisp != gdisp)
return;
inside_x = coords->x > rectangle->x1 && coords->x < rectangle->x2;
inside_y = coords->y > rectangle->y1 && coords->y < rectangle->y2;
/* If the cursor is in either the upper left or lower right boxes,
* The new function will be to resize the current rectangle area
*/
......@@ -619,7 +695,7 @@ gimp_rectangle_tool_oper_update (GimpTool *tool,
GTK_ANCHOR_NORTH_WEST,
FALSE))
{
rectangle->function = RECT_RESIZING_LEFT;
rectangle->function = RECT_RESIZING_UPPER_LEFT;
gimp_tool_control_set_snap_offsets (tool->control,
rectangle->x1 - coords->x,
......@@ -634,7 +710,7 @@ gimp_rectangle_tool_oper_update (GimpTool *tool,
GTK_ANCHOR_SOUTH_EAST,
FALSE))
{
rectangle->function = RECT_RESIZING_RIGHT;
rectangle->function = RECT_RESIZING_LOWER_RIGHT;
gimp_tool_control_set_snap_offsets (tool->control,
rectangle->x2 - coords->x,
......@@ -650,34 +726,68 @@ gimp_rectangle_tool_oper_update (GimpTool *tool,
rectangle->x2, rectangle->y1,
rectangle->dcw, rectangle->dch,
GTK_ANCHOR_NORTH_EAST,
FALSE) ||
gimp_draw_tool_on_handle (draw_tool, gdisp,
coords->x, coords->y,
GIMP_HANDLE_SQUARE,
rectangle->x1, rectangle->y2,
rectangle->dcw, rectangle->dch,
GTK_ANCHOR_SOUTH_WEST,
FALSE))
{
rectangle->function = RECT_MOVING;
rectangle->function = RECT_RESIZING_UPPER_RIGHT;
gimp_tool_control_set_snap_offsets (tool->control,
rectangle->x1 - coords->x,
rectangle->x2 - coords->x,
rectangle->y1 - coords->y,
rectangle->x2 - rectangle->x1,
rectangle->y2 - rectangle->y1);
0, 0);
}
/* If the pointer is in the rectangular region, execute or resize it!
*/
else if (coords->x > rectangle->x1 &&
coords->x < rectangle->x2 &&
coords->y > rectangle->y1 &&
coords->y < rectangle->y2)
else if (gimp_draw_tool_on_handle (draw_tool, gdisp,
coords->x, coords->y,
GIMP_HANDLE_SQUARE,
rectangle->x1, rectangle->y2,
rectangle->dcw, rectangle->dch,
GTK_ANCHOR_SOUTH_WEST,
FALSE))
{
rectangle->function = RECT_RESIZING_LOWER_LEFT;
gimp_tool_control_set_snap_offsets (tool->control,
rectangle->x1 - coords->x,
rectangle->y2 - coords->y,
0, 0);
}
else if ( (fabs (coords->x - rectangle->x1) < rectangle->dcw) && inside_y)
{
rectangle->function = RECT_EXECUTING;
rectangle->function = RECT_RESIZING_LEFT;
gimp_tool_control_set_snap_offsets (tool->control,
rectangle->x1 - coords->x, 0, 0, 0);
}
else if ( (fabs (coords->x - rectangle->x2) < rectangle->dcw) && inside_y)
{
rectangle->function = RECT_RESIZING_RIGHT;
gimp_tool_control_set_snap_offsets (tool->control,
rectangle->x2 - coords->x, 0, 0, 0);
}
else if ( (fabs (coords->y - rectangle->y1) < rectangle->dch) && inside_x)
{
rectangle->function = RECT_RESIZING_TOP;
gimp_tool_control_set_snap_offsets (tool->control,
0, rectangle->y1 - coords->y, 0, 0);
}
else if ( (fabs (coords->y - rectangle->y2) < rectangle->dch) && inside_x)
{
rectangle->function = RECT_RESIZING_BOTTOM;
gimp_tool_control_set_snap_offsets (tool->control,
0, rectangle->y2 - coords->y, 0, 0);
}
else if (inside_x && inside_y)
{
rectangle->function = RECT_MOVING;
}
/* otherwise, the new function will be creating, since we want
* to start a new
* to start a new rectangle
*/
else
{
......@@ -708,8 +818,14 @@ gimp_rectangle_tool_cursor_update (GimpTool *tool,
modifier = GIMP_CURSOR_MODIFIER_MOVE;
break;
case RECT_RESIZING_UPPER_LEFT:
case RECT_RESIZING_UPPER_RIGHT:
case RECT_RESIZING_LOWER_LEFT:
case RECT_RESIZING_LOWER_RIGHT:
case RECT_RESIZING_LEFT:
case RECT_RESIZING_RIGHT:
case RECT_RESIZING_TOP:
case RECT_RESIZING_BOTTOM:
modifier = GIMP_CURSOR_MODIFIER_RESIZE;
break;
......@@ -736,16 +852,16 @@ gimp_rectangle_tool_draw (GimpDrawTool *draw)
gimp_canvas_draw_line (canvas, GIMP_CANVAS_STYLE_XOR,
rectangle->dx1, rectangle->dy1,
shell->disp_width, rectangle->dy1);
rectangle->dx2, rectangle->dy1);
gimp_canvas_draw_line (canvas, GIMP_CANVAS_STYLE_XOR,
rectangle->dx1, rectangle->dy1,
rectangle->dx1, shell->disp_height);
rectangle->dx1, rectangle->dy2);
gimp_canvas_draw_line (canvas, GIMP_CANVAS_STYLE_XOR,
rectangle->dx2, rectangle->dy2,
0, rectangle->dy2);
rectangle->dx1, rectangle->dy2);
gimp_canvas_draw_line (canvas, GIMP_CANVAS_STYLE_XOR,
rectangle->dx2, rectangle->dy2,
rectangle->dx2, 0);
rectangle->dx2, rectangle->dy1);
gimp_draw_tool_draw_handle (draw,
GIMP_HANDLE_FILLED_SQUARE,
......@@ -1086,27 +1202,22 @@ gimp_rectangle_tool_update_options (GimpRectangleTool *rectangle,
gdouble width;
gdouble height;
gdouble aspect;
gdouble center_x, center_y;
GimpSizeEntry *entry = GIMP_SIZE_ENTRY (rectangle->dimensions_entry);
shell = GIMP_DISPLAY_SHELL (gdisp->shell);
width = fabs (rectangle->x2 - rectangle->x1);
height = fabs (rectangle->y2 - rectangle->y1);
if (! shell->unit == GIMP_UNIT_PIXEL)
{
GimpImage *image = gdisp->gimage;
width *= _gimp_unit_get_factor (image->gimp,
shell->unit) / image->xresolution;
height *= _gimp_unit_get_factor (image->gimp,
shell->unit) / image->yresolution;
}
width = rectangle->x2 - rectangle->x1;
height = rectangle->y2 - rectangle->y1;
if (width > 0.01)
aspect = height / width;
else
aspect = 0;
center_x = (rectangle->x1 + rectangle->x2) / 2;
center_y = (rectangle->y1 + rectangle->y2) / 2;
g_signal_handlers_block_by_func (rectangle->dimensions_entry,
rectangle_dimensions_changed,
rectangle);
......@@ -1116,6 +1227,14 @@ gimp_rectangle_tool_update_options (GimpRectangleTool *rectangle,
gimp_size_entry_set_refval (entry, 2, rectangle->x1);
gimp_size_entry_set_refval (entry, 3, rectangle->y1);
g_object_set (GIMP_TOOL (rectangle)->tool_info->tool_options,