Index: app/tools/gimprectangletool.c =================================================================== RCS file: /cvs/gnome/gimp/app/tools/gimprectangletool.c,v retrieving revision 1.53 diff -u -p -r1.53 gimprectangletool.c --- app/tools/gimprectangletool.c 5 Jun 2006 11:18:43 -0000 1.53 +++ app/tools/gimprectangletool.c 5 Jun 2006 16:49:22 -0000 @@ -744,7 +744,7 @@ gimp_rectangle_tool_control (GimpTool break; case GIMP_TOOL_ACTION_HALT: - gimp_rectangle_tool_response (NULL, GTK_RESPONSE_CANCEL, rectangle); + gimp_rectangle_tool_halt (rectangle); break; default: @@ -854,8 +854,8 @@ gimp_rectangle_tool_button_release (Gimp NULL); if (private->lastx == pressx && private->lasty == pressy) { - gimp_rectangle_tool_response (NULL, GIMP_RECTANGLE_MODE_EXECUTE, - rectangle); + if (gimp_rectangle_tool_execute (rectangle)) + gimp_rectangle_tool_halt (rectangle); } g_signal_emit_by_name (rectangle, "rectangle-changed", NULL); @@ -1403,13 +1403,13 @@ gimp_rectangle_tool_key_press (GimpTool case GDK_KP_Enter: case GDK_Return: - gimp_rectangle_tool_response (NULL, - GIMP_RECTANGLE_MODE_EXECUTE, rectangle); + if (gimp_rectangle_tool_execute (rectangle)) + gimp_rectangle_tool_halt (rectangle); return TRUE; case GDK_Escape: - gimp_rectangle_tool_response (NULL, - GTK_RESPONSE_CANCEL, rectangle); + gimp_rectangle_tool_cancel (rectangle); + gimp_rectangle_tool_halt (rectangle); return TRUE; default: @@ -1779,53 +1779,25 @@ rectangle_tool_start (GimpRectangleTool } void -gimp_rectangle_tool_response (GtkWidget *widget, - gint response_id, - GimpRectangleTool *rectangle) +gimp_rectangle_tool_halt (GimpRectangleTool *rectangle) { - GimpTool *tool = GIMP_TOOL (rectangle); - gboolean finish = TRUE; - gint x1, y1, x2, y2; - - if (response_id == GIMP_RECTANGLE_MODE_EXECUTE) - { - g_object_get (rectangle, - "x1", &x1, - "y1", &y1, - "x2", &x2, - "y2", &y2, - NULL); - - gimp_draw_tool_pause (GIMP_DRAW_TOOL (rectangle)); - - finish = gimp_rectangle_tool_execute (GIMP_RECTANGLE_TOOL (tool), - x1, y1, - x2 - x1, - y2 - y1); - - gimp_rectangle_tool_configure (rectangle); - - gimp_draw_tool_resume (GIMP_DRAW_TOOL (rectangle)); - } + GimpTool *tool = GIMP_TOOL (rectangle); - if (finish) - { - gimp_display_shell_set_highlight (GIMP_DISPLAY_SHELL (tool->display->shell), - NULL); + gimp_display_shell_set_highlight (GIMP_DISPLAY_SHELL (tool->display->shell), + NULL); - if (gimp_draw_tool_is_active (GIMP_DRAW_TOOL (rectangle))) - gimp_draw_tool_stop (GIMP_DRAW_TOOL (rectangle)); + if (gimp_draw_tool_is_active (GIMP_DRAW_TOOL (rectangle))) + gimp_draw_tool_stop (GIMP_DRAW_TOOL (rectangle)); - if (gimp_tool_control_is_active (tool->control)) - gimp_tool_control_halt (tool->control); + if (gimp_tool_control_is_active (tool->control)) + gimp_tool_control_halt (tool->control); - gimp_image_flush (tool->display->image); + gimp_image_flush (tool->display->image); - tool->display = NULL; - tool->drawable = NULL; + tool->display = NULL; + tool->drawable = NULL; - g_object_set (rectangle, "function", RECT_INACTIVE, NULL); - } + g_object_set (rectangle, "function", RECT_INACTIVE, NULL); } static void @@ -1920,26 +1892,45 @@ rectangle_automatic_callback (GtkWidget } gboolean -gimp_rectangle_tool_execute (GimpRectangleTool *rectangle, - gint x, - gint y, - gint w, - gint h) +gimp_rectangle_tool_execute (GimpRectangleTool *rectangle) { - GimpRectangleToolInterface *iface = GIMP_RECTANGLE_TOOL_GET_INTERFACE (rectangle); - gint rx1, ry1, rx2, ry2; + GimpRectangleToolInterface *iface; + gboolean retval = FALSE; - g_return_val_if_fail (iface->execute, FALSE); + iface = GIMP_RECTANGLE_TOOL_GET_INTERFACE (rectangle); - /* FIXME: why are we doing this instead of using x, y, w, h? */ - g_object_get (rectangle, - "x1", &rx1, - "y1", &ry1, - "x2", &rx2, - "y2", &ry2, - NULL); + if (iface->execute) + { + gint x1, y1, x2, y2; + + g_object_get (rectangle, + "x1", &x1, + "y1", &y1, + "x2", &x2, + "y2", &y2, + NULL); + + gimp_draw_tool_pause (GIMP_DRAW_TOOL (rectangle)); + + retval = iface->execute (rectangle, x1, y1, x2 - x1, y2 - y1); + + 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); - return iface->execute (rectangle, rx1, ry1, rx2 - rx1, ry2 - ry1); + if (iface->cancel) + iface->cancel (rectangle); } static void Index: app/tools/gimprectangletool.h =================================================================== RCS file: /cvs/gnome/gimp/app/tools/gimprectangletool.h,v retrieving revision 1.16 diff -u -p -r1.16 gimprectangletool.h --- app/tools/gimprectangletool.h 4 Jun 2006 17:08:26 -0000 1.16 +++ app/tools/gimprectangletool.h 5 Jun 2006 16:49:22 -0000 @@ -74,6 +74,7 @@ struct _GimpRectangleToolInterface gint y, gint w, gint h); + void (* cancel) (GimpRectangleTool *rect_tool); gboolean (* rectangle_changed) (GimpRectangleTool *rect_tool); }; @@ -122,14 +123,9 @@ void gimp_rectangle_tool_cursor_u GdkModifierType state, GimpDisplay *display); void gimp_rectangle_tool_draw (GimpDrawTool *draw); -gboolean gimp_rectangle_tool_execute (GimpRectangleTool *rect_tool, - gint x, - gint y, - gint w, - gint h); -void gimp_rectangle_tool_response (GtkWidget *widget, - gint response_id, - GimpRectangleTool *rectangle); +gboolean gimp_rectangle_tool_execute (GimpRectangleTool *rect_tool); +void gimp_rectangle_tool_cancel (GimpRectangleTool *rect_tool); +void gimp_rectangle_tool_halt (GimpRectangleTool *rectangle); void gimp_rectangle_tool_configure (GimpRectangleTool *rectangle); void gimp_rectangle_tool_set_constrain (GimpRectangleTool *rectangle, gboolean constrain); Index: app/tools/gimpnewrectselecttool.c =================================================================== RCS file: /cvs/gnome/gimp/app/tools/gimpnewrectselecttool.c,v retrieving revision 1.40 diff -u -p -r1.40 gimpnewrectselecttool.c --- app/tools/gimpnewrectselecttool.c 4 Jun 2006 20:34:45 -0000 1.40 +++ app/tools/gimpnewrectselecttool.c 5 Jun 2006 16:49:22 -0000 @@ -92,11 +92,17 @@ static void gimp_new_rect_select_too GimpCoords *coords, GdkModifierType state, GimpDisplay *display); +static void gimp_new_rect_select_tool_rect_select (GimpRectangleTool *rect_tool, + gint x, + gint y, + gint w, + gint h); static gboolean gimp_new_rect_select_tool_execute (GimpRectangleTool *rect_tool, gint x, gint y, gint w, gint h); +static void gimp_new_rect_select_tool_cancel (GimpRectangleTool *rect_tool); static gboolean gimp_new_rect_select_tool_rectangle_changed (GimpRectangleTool *rect_tool); static void gimp_new_rect_select_tool_real_rect_select (GimpNewRectSelectTool *rect_select, gint x, @@ -173,7 +179,8 @@ gimp_new_rect_select_tool_init (GimpNewR static void gimp_new_rect_select_tool_rectangle_tool_iface_init (GimpRectangleToolInterface *iface) { - iface->execute = gimp_new_rect_select_tool_execute; + iface->execute = gimp_new_rect_select_tool_execute; + iface->cancel = gimp_new_rect_select_tool_cancel; iface->rectangle_changed = gimp_new_rect_select_tool_rectangle_changed; } @@ -234,8 +241,7 @@ gimp_new_rect_select_tool_button_press ( /* } */ if (tool->display && display != tool->display) - gimp_rectangle_tool_response (NULL, GTK_RESPONSE_CANCEL, - GIMP_RECTANGLE_TOOL (tool)); + gimp_rectangle_tool_cancel (GIMP_RECTANGLE_TOOL (tool)); g_object_get (tool, "function", &function, NULL); @@ -336,38 +342,27 @@ gimp_new_rect_select_tool_cursor_update * 4) If there is no rectangle and we are outside the selection, * we clear the selection. */ -static gboolean -gimp_new_rect_select_tool_execute (GimpRectangleTool *rectangle, - gint x, - gint y, - gint w, - gint h) +static void +gimp_new_rect_select_tool_rect_select (GimpRectangleTool *rectangle, + gint x, + gint y, + gint w, + gint h) { GimpTool *tool = GIMP_TOOL (rectangle); GimpNewRectSelectTool *rect_select = GIMP_NEW_RECT_SELECT_TOOL (rectangle); GimpSelectionOptions *options; GimpImage *image; - gint max_x, max_y; gboolean rectangle_exists; gboolean auto_shrink; - gboolean selected; - gint val; - GimpChannel *selection_mask; - gint x1, y1; - gint x2, y2; - gint pressx, pressy; - guchar *val_ptr; options = GIMP_SELECTION_OPTIONS (tool->tool_info->tool_options); gimp_tool_pop_status (tool, tool->display); image = tool->display->image; - max_x = image->width; - max_y = image->height; - selection_mask = gimp_image_get_mask (image); - rectangle_exists = (x <= max_x && y <= max_y && + rectangle_exists = (x <= image->width && y <= image->height && x + w >= 0 && y + h >= 0 && w > 0 && h > 0); @@ -376,146 +371,170 @@ gimp_new_rect_select_tool_execute (GimpR NULL); if (auto_shrink) - { - if (x < 0) - { - w += x; - x = 0; - } - - if (y < 0) - { - h += y; - y = 0; - } - - if (x + w > max_x) - w = max_x - x; - - if (y + h > max_y) - h = max_y - y; - } + { + /* FIXME */ + } /* if rectangle exists, turn it into a selection */ if (rectangle_exists) - { - GIMP_NEW_RECT_SELECT_TOOL_GET_CLASS (rect_select)->rect_select (rect_select, x, y, w, h); + GIMP_NEW_RECT_SELECT_TOOL_GET_CLASS (rect_select)->rect_select (rect_select, + x, y, w, h); +} - return TRUE; - } +static void +gimp_new_rect_select_tool_real_rect_select (GimpNewRectSelectTool *rect_select, + gint x, + gint y, + gint w, + gint h) +{ + GimpTool *tool = GIMP_TOOL (rect_select); + GimpSelectionOptions *options; - g_object_get (rectangle, - "pressx", &pressx, - "pressy", &pressy, - NULL); + options = GIMP_SELECTION_OPTIONS (tool->tool_info->tool_options); - if ((val_ptr = gimp_pickable_get_color_at (GIMP_PICKABLE (selection_mask), - pressx, - pressy))) - val = *val_ptr; - else - val = 0; + gimp_channel_select_rectangle (gimp_image_get_mask (tool->display->image), + x, y, w, h, + options->operation, + options->feather, + options->feather_radius, + options->feather_radius); +} - selected = (val > 127); +static gboolean +gimp_new_rect_select_tool_execute (GimpRectangleTool *rectangle, + gint x, + gint y, + gint w, + gint h) +{ + GimpNewRectSelectTool *rect_select = GIMP_NEW_RECT_SELECT_TOOL (rectangle); - /* if point clicked is inside selection, set rectangle to */ - /* edges of marching ants. */ - if (selected) + /* don't keep the undo step across separate rectangles */ + rect_select->undo = NULL; + + if (w == 0 && h == 0) { - GimpChannel *selection_mask = gimp_image_get_mask (image); - const BoundSeg *segs_in; - const BoundSeg *segs_out; - gint n_segs_in; - gint n_segs_out; - - if (gimp_channel_boundary (selection_mask, &segs_in, &segs_out, - &n_segs_in, &n_segs_out, - 0, 0, 0, 0)) - { - x1 = y1 = x2 = y2 = 0; + GimpImage *image = GIMP_TOOL (rectangle)->display->image; + GimpChannel *selection = gimp_image_get_mask (image);; + gint pressx, pressy; - if (n_segs_in > 0) - { - gint i; + g_object_get (rectangle, + "pressx", &pressx, + "pressy", &pressy, + NULL); - x1 = segs_in[0].x1; - x2 = segs_in[0].x1; - y1 = segs_in[0].y1; - y2 = segs_in[0].y1; + /* if the click was inside the marching ants */ + if (gimp_pickable_get_opacity_at (GIMP_PICKABLE (selection), + pressx, pressy) > 127) + { + const BoundSeg *segs_in; + const BoundSeg *segs_out; + gint n_segs_in; + gint n_segs_out; + + if (gimp_channel_boundary (selection, + &segs_in, &segs_out, + &n_segs_in, &n_segs_out, + 0, 0, 0, 0)) + { + gint x1 = 0; + gint y1 = 0; + gint x2 = 0; + gint y2 = 0; - for (i = 1; i < n_segs_in; i++) + if (n_segs_in > 0) { - x1 = MIN (x1, segs_in[i].x1); - x2 = MAX (x2, segs_in[i].x1); - y1 = MIN (y1, segs_in[i].y1); - y2 = MAX (y2, segs_in[i].y1); + gint i; + + x1 = segs_in[0].x1; + x2 = segs_in[0].x1; + y1 = segs_in[0].y1; + y2 = segs_in[0].y1; + + for (i = 1; i < n_segs_in; i++) + { + x1 = MIN (x1, segs_in[i].x1); + x2 = MAX (x2, segs_in[i].x1); + y1 = MIN (y1, segs_in[i].y1); + y2 = MAX (y2, segs_in[i].y1); + } } + + g_object_set (rectangle, + "x1", x1, + "y1", y1, + "x2", x2, + "y2", y2, + NULL); + } + else + { + g_object_set (rectangle, + "x1", 0, + "y1", 0, + "x2", image->width, + "y2", image->height, + NULL); } - g_object_set (rectangle, - "x1", x1, - "y1", y1, - "x2", x2, - "y2", y2, - NULL); + g_object_set (rectangle, "function", RECT_MOVING, NULL); + + return FALSE; } else { - g_object_set (rectangle, - "x1", 0, - "y1", 0, - "x2", image->width, - "y2", image->height, - NULL); + /* otherwise clear the selection */ + gimp_channel_clear (selection, NULL, TRUE); } - - g_object_set (rectangle, "function", RECT_MOVING, NULL); - - return FALSE; } - /* otherwise clear the selection */ - gimp_channel_clear (selection_mask, NULL, TRUE); - return TRUE; } static void -gimp_new_rect_select_tool_real_rect_select (GimpNewRectSelectTool *rect_select, - gint x, - gint y, - gint w, - gint h) +gimp_new_rect_select_tool_cancel (GimpRectangleTool *rectangle) { - GimpTool *tool = GIMP_TOOL (rect_select); - GimpSelectionOptions *options; + GimpTool *tool = GIMP_TOOL (rectangle); - options = GIMP_SELECTION_OPTIONS (tool->tool_info->tool_options); + if (tool->display) + { + GimpNewRectSelectTool *rect_select = GIMP_NEW_RECT_SELECT_TOOL (tool); + GimpImage *image = tool->display->image; + GimpUndo *undo; - gimp_channel_select_rectangle (gimp_image_get_mask (tool->display->image), - x, y, w, h, - options->operation, - options->feather, - options->feather_radius, - options->feather_radius); + /* if we have an existing rectangle in the current display, then + * we have already "executed", and need to undo at this point, + * unless the user has done something in the meantime + */ + undo = gimp_undo_stack_peek (image->undo_stack); + + if (undo && rect_select->undo == undo) + { + gimp_image_undo (image); + rect_select->undo = NULL; + } + } } static gboolean gimp_new_rect_select_tool_rectangle_changed (GimpRectangleTool *rectangle) { - GimpTool *tool = GIMP_TOOL (rectangle); + GimpTool *tool = GIMP_TOOL (rectangle); if (tool->display) { - gint x1, y1, x2, y2; - GimpNewRectSelectTool *rect_select = GIMP_NEW_RECT_SELECT_TOOL (tool); - GimpImage *image = tool->display->image; + GimpNewRectSelectTool *rect_select = GIMP_NEW_RECT_SELECT_TOOL (tool); + GimpImage *image = tool->display->image; GimpUndo *undo; + gint x1, y1, x2, y2; /* if we have an existing rectangle in the current display, then - we have already "executed", and need to undo at this point, unless - the user has done something in the meantime */ + * we have already "executed", and need to undo at this point, + * unless the user has done something in the meantime + */ undo = gimp_undo_stack_peek (image->undo_stack); + if (undo && rect_select->undo == undo) { gimp_image_undo (image); @@ -529,10 +548,10 @@ gimp_new_rect_select_tool_rectangle_chan "y2", &y2, NULL); - gimp_rectangle_tool_execute (rectangle, - x1, y1, - x2 - x1, - y2 - y1); + gimp_new_rect_select_tool_rect_select (rectangle, + x1, y1, + x2 - x1, + y2 - y1); /* save the undo that we got when executing */ rect_select->undo = gimp_undo_stack_peek (image->undo_stack); Index: app/tools/gimpcroptool.c =================================================================== RCS file: /cvs/gnome/gimp/app/tools/gimpcroptool.c,v retrieving revision 1.224 diff -u -p -r1.224 gimpcroptool.c --- app/tools/gimpcroptool.c 31 May 2006 19:45:37 -0000 1.224 +++ app/tools/gimpcroptool.c 5 Jun 2006 16:49:22 -0000 @@ -182,8 +182,7 @@ gimp_crop_tool_button_press (GimpTool GimpDisplay *display) { if (tool->display && display != tool->display) - gimp_rectangle_tool_response (NULL, GTK_RESPONSE_CANCEL, - GIMP_RECTANGLE_TOOL (tool)); + gimp_rectangle_tool_cancel (GIMP_RECTANGLE_TOOL (tool)); gimp_rectangle_tool_button_press (tool, coords, time, state, display); }