mirror of https://github.com/GNOME/gimp.git
app: move undo/redo logic for GimpRectangleSelectTool to GimpSelectionTool
Move GimpRectangleSelectTool's image undo/redo logic to GimpSelectionTool, by adding a pair of gimp_selection_tool_{start,end}_change() functions. These functions should be called by subclasses before/after changing the selection, having the functions take care of undoing/redoing the existing selection as necessary. This allows us to reuse this logic in other selection tools, specifically, the free-select tool.
This commit is contained in:
parent
cf892ba2f0
commit
4612105e52
|
@ -28,17 +28,14 @@
|
|||
#include "core/gimpchannel-select.h"
|
||||
#include "core/gimpchannel.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimpimage-undo.h"
|
||||
#include "core/gimplayer-floating-selection.h"
|
||||
#include "core/gimppickable.h"
|
||||
#include "core/gimpundostack.h"
|
||||
|
||||
#include "widgets/gimphelp-ids.h"
|
||||
#include "widgets/gimpwidgets-utils.h"
|
||||
|
||||
#include "display/gimpdisplay.h"
|
||||
#include "display/gimpdisplayshell.h"
|
||||
#include "display/gimpdisplayshell-appearance.h"
|
||||
#include "display/gimptoolrectangle.h"
|
||||
|
||||
#include "gimpeditselectiontool.h"
|
||||
|
@ -54,9 +51,6 @@ struct _GimpRectangleSelectToolPrivate
|
|||
{
|
||||
GimpChannelOps operation; /* remember for use when modifying */
|
||||
gboolean use_saved_op; /* use operation or get from options */
|
||||
gboolean saved_show_selection; /* used to remember existing value */
|
||||
GimpUndo *undo;
|
||||
GimpUndo *redo;
|
||||
|
||||
gdouble press_x;
|
||||
gdouble press_y;
|
||||
|
@ -233,7 +227,6 @@ gimp_rectangle_select_tool_button_press (GimpTool *tool,
|
|||
{
|
||||
GimpRectangleSelectTool *rect_tool = GIMP_RECTANGLE_SELECT_TOOL (tool);
|
||||
GimpRectangleSelectToolPrivate *private = rect_tool->private;
|
||||
GimpDisplayShell *shell = gimp_display_get_shell (display);
|
||||
GimpRectangleFunction function;
|
||||
|
||||
if (tool->display && display != tool->display)
|
||||
|
@ -286,8 +279,6 @@ gimp_rectangle_select_tool_button_press (GimpTool *tool,
|
|||
GIMP_TOOL_RECTANGLE_CREATING);
|
||||
}
|
||||
|
||||
private->saved_show_selection = gimp_display_shell_get_show_selection (shell);
|
||||
|
||||
/* if the shift or ctrl keys are down, we don't want to adjust, we
|
||||
* want to create a new rectangle, regardless of pointer loc
|
||||
*/
|
||||
|
@ -315,42 +306,12 @@ gimp_rectangle_select_tool_button_press (GimpTool *tool,
|
|||
gimp_tool_rectangle_get_function (GIMP_TOOL_RECTANGLE (private->widget));
|
||||
|
||||
if (function == GIMP_TOOL_RECTANGLE_CREATING)
|
||||
{
|
||||
private->use_saved_op = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
GimpImage *image = gimp_display_get_image (tool->display);
|
||||
GimpUndoStack *undo_stack = gimp_image_get_undo_stack (image);
|
||||
GimpUndoStack *redo_stack = gimp_image_get_redo_stack (image);
|
||||
GimpUndo *undo;
|
||||
GimpChannelOps operation;
|
||||
|
||||
undo = gimp_undo_stack_peek (undo_stack);
|
||||
|
||||
if (undo && private->undo == undo)
|
||||
{
|
||||
/* prevent this change from halting the tool */
|
||||
gimp_tool_control_push_preserve (tool->control, TRUE);
|
||||
|
||||
gimp_image_undo (image);
|
||||
|
||||
gimp_tool_control_pop_preserve (tool->control);
|
||||
|
||||
/* we will need to redo if the user cancels or executes */
|
||||
private->redo = gimp_undo_stack_peek (redo_stack);
|
||||
}
|
||||
|
||||
/* if the operation is "Replace", turn off the marching ants,
|
||||
* because they are confusing
|
||||
*/
|
||||
operation = gimp_rectangle_select_tool_get_operation (rect_tool);
|
||||
|
||||
if (operation == GIMP_CHANNEL_OP_REPLACE)
|
||||
gimp_display_shell_set_show_selection (shell, FALSE);
|
||||
}
|
||||
|
||||
private->undo = NULL;
|
||||
gimp_selection_tool_start_change (
|
||||
GIMP_SELECTION_TOOL (tool),
|
||||
function == GIMP_TOOL_RECTANGLE_CREATING,
|
||||
gimp_rectangle_select_tool_get_operation (rect_tool));
|
||||
|
||||
gimp_tool_control_activate (tool->control);
|
||||
}
|
||||
|
@ -365,36 +326,17 @@ gimp_rectangle_select_tool_button_release (GimpTool *tool,
|
|||
{
|
||||
GimpRectangleSelectTool *rect_tool = GIMP_RECTANGLE_SELECT_TOOL (tool);
|
||||
GimpRectangleSelectToolPrivate *priv = rect_tool->private;
|
||||
GimpImage *image;
|
||||
|
||||
image = gimp_display_get_image (tool->display);
|
||||
|
||||
gimp_tool_control_halt (tool->control);
|
||||
|
||||
gimp_tool_pop_status (tool, display);
|
||||
gimp_display_shell_set_show_selection (gimp_display_get_shell (display),
|
||||
priv->saved_show_selection);
|
||||
|
||||
/*
|
||||
* if the user has not moved the mouse, we need to redo the operation
|
||||
* that was undone on button press.
|
||||
gimp_selection_tool_end_change (GIMP_SELECTION_TOOL (tool),
|
||||
/* if the user has not moved the mouse,
|
||||
* cancel the change
|
||||
*/
|
||||
if (release_type == GIMP_BUTTON_RELEASE_CLICK)
|
||||
{
|
||||
GimpUndoStack *redo_stack = gimp_image_get_redo_stack (image);
|
||||
GimpUndo *redo = gimp_undo_stack_peek (redo_stack);
|
||||
release_type == GIMP_BUTTON_RELEASE_CLICK ||
|
||||
release_type == GIMP_BUTTON_RELEASE_CANCEL);
|
||||
|
||||
if (redo && priv->redo == redo)
|
||||
{
|
||||
/* prevent this from halting the tool */
|
||||
gimp_tool_control_push_preserve (tool->control, TRUE);
|
||||
|
||||
gimp_image_redo (image);
|
||||
priv->redo = NULL;
|
||||
|
||||
gimp_tool_control_pop_preserve (tool->control);
|
||||
}
|
||||
}
|
||||
gimp_tool_pop_status (tool, display);
|
||||
|
||||
if (priv->grab_widget)
|
||||
{
|
||||
|
@ -402,23 +344,6 @@ gimp_rectangle_select_tool_button_release (GimpTool *tool,
|
|||
coords, time, state, release_type);
|
||||
priv->grab_widget = NULL;
|
||||
}
|
||||
|
||||
if (release_type == GIMP_BUTTON_RELEASE_CANCEL)
|
||||
{
|
||||
if (priv->redo)
|
||||
{
|
||||
/* prevent this from halting the tool */
|
||||
gimp_tool_control_push_preserve (tool->control, TRUE);
|
||||
|
||||
gimp_image_redo (image);
|
||||
|
||||
gimp_tool_control_pop_preserve (tool->control);
|
||||
}
|
||||
|
||||
priv->use_saved_op = TRUE; /* is this correct? */
|
||||
}
|
||||
|
||||
priv->redo = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -546,10 +471,19 @@ gimp_rectangle_select_tool_select (GimpRectangleSelectTool *rect_tool,
|
|||
|
||||
/* if rectangle exists, turn it into a selection */
|
||||
if (rectangle_exists)
|
||||
{
|
||||
gimp_selection_tool_start_change (GIMP_SELECTION_TOOL (rect_tool),
|
||||
FALSE,
|
||||
operation);
|
||||
|
||||
GIMP_RECTANGLE_SELECT_TOOL_GET_CLASS (rect_tool)->select (rect_tool,
|
||||
operation,
|
||||
x, y, w, h);
|
||||
|
||||
gimp_selection_tool_end_change (GIMP_SELECTION_TOOL (rect_tool),
|
||||
FALSE);
|
||||
}
|
||||
|
||||
return rectangle_exists;
|
||||
}
|
||||
|
||||
|
@ -606,7 +540,6 @@ gimp_rectangle_select_tool_rectangle_response (GimpToolWidget *widget,
|
|||
GimpRectangleSelectTool *rect_tool)
|
||||
{
|
||||
GimpTool *tool = GIMP_TOOL (rect_tool);
|
||||
GimpRectangleSelectToolPrivate *priv = rect_tool->private;
|
||||
|
||||
switch (response_id)
|
||||
{
|
||||
|
@ -644,31 +577,7 @@ gimp_rectangle_select_tool_rectangle_response (GimpToolWidget *widget,
|
|||
break;
|
||||
|
||||
case GIMP_TOOL_WIDGET_RESPONSE_CANCEL:
|
||||
{
|
||||
GimpImage *image = gimp_display_get_image (tool->display);
|
||||
GimpUndoStack *undo_stack = gimp_image_get_undo_stack (image);
|
||||
GimpUndo *undo = gimp_undo_stack_peek (undo_stack);
|
||||
|
||||
/* 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
|
||||
*/
|
||||
if (undo && priv->undo == undo)
|
||||
{
|
||||
/* prevent this change from halting the tool */
|
||||
gimp_tool_control_push_preserve (tool->control, TRUE);
|
||||
|
||||
gimp_image_undo (image);
|
||||
gimp_image_flush (image);
|
||||
|
||||
gimp_tool_control_pop_preserve (tool->control);
|
||||
}
|
||||
|
||||
priv->undo = NULL;
|
||||
priv->redo = NULL;
|
||||
|
||||
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, tool->display);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -857,10 +766,6 @@ gimp_rectangle_select_tool_commit (GimpRectangleSelectTool *rect_tool)
|
|||
|
||||
gimp_rectangle_select_tool_update_option_defaults (rect_tool, FALSE);
|
||||
}
|
||||
|
||||
/* Reset the automatic undo/redo mechanism */
|
||||
priv->undo = NULL;
|
||||
priv->redo = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -883,9 +788,6 @@ gimp_rectangle_select_tool_halt (GimpRectangleSelectTool *rect_tool)
|
|||
rect_tool);
|
||||
}
|
||||
|
||||
priv->undo = NULL;
|
||||
priv->redo = NULL;
|
||||
|
||||
if (gimp_draw_tool_is_active (GIMP_DRAW_TOOL (tool)))
|
||||
gimp_draw_tool_stop (GIMP_DRAW_TOOL (tool));
|
||||
|
||||
|
@ -976,33 +878,13 @@ gimp_rectangle_select_tool_update (GimpRectangleSelectTool *rect_tool)
|
|||
|
||||
if (tool->display && ! gimp_tool_control_is_active (tool->control))
|
||||
{
|
||||
GimpImage *image = gimp_display_get_image (tool->display);
|
||||
GimpUndoStack *undo_stack = gimp_image_get_undo_stack (image);
|
||||
GimpUndo *undo = gimp_undo_stack_peek (undo_stack);
|
||||
gdouble x1, y1, x2, y2;
|
||||
|
||||
/* if we got here via button release, we have already undone the
|
||||
* previous operation. But if we got here by some other means,
|
||||
* we need to undo it now.
|
||||
*/
|
||||
if (undo && priv->undo == undo)
|
||||
{
|
||||
gimp_image_undo (image);
|
||||
priv->undo = NULL;
|
||||
}
|
||||
|
||||
gimp_tool_rectangle_get_public_rect (GIMP_TOOL_RECTANGLE (priv->widget),
|
||||
&x1, &y1, &x2, &y2);
|
||||
|
||||
if (gimp_rectangle_select_tool_select (rect_tool,
|
||||
x1, y1, x2 - x1, y2 - y1))
|
||||
{
|
||||
/* save the undo that we got when executing, but only if
|
||||
* we actually selected something
|
||||
*/
|
||||
priv->undo = gimp_undo_stack_peek (undo_stack);
|
||||
priv->redo = NULL;
|
||||
}
|
||||
gimp_rectangle_select_tool_select (rect_tool,
|
||||
x1, y1, x2 - x1, y2 - y1);
|
||||
|
||||
if (! priv->use_saved_op)
|
||||
{
|
||||
|
@ -1014,8 +896,6 @@ gimp_rectangle_select_tool_update (GimpRectangleSelectTool *rect_tool)
|
|||
priv->operation = options->operation;
|
||||
priv->use_saved_op = TRUE;
|
||||
}
|
||||
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
|
||||
gimp_tool_control_pop_preserve (tool->control);
|
||||
|
|
|
@ -28,9 +28,12 @@
|
|||
#include "core/gimperror.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimpimage-pick-item.h"
|
||||
#include "core/gimpimage-undo.h"
|
||||
#include "core/gimppickable.h"
|
||||
#include "core/gimpundostack.h"
|
||||
|
||||
#include "display/gimpdisplay.h"
|
||||
#include "display/gimpdisplayshell-appearance.h"
|
||||
|
||||
#include "widgets/gimpwidgets-utils.h"
|
||||
|
||||
|
@ -43,7 +46,9 @@
|
|||
#include "gimp-intl.h"
|
||||
|
||||
|
||||
|
||||
static void gimp_selection_tool_control (GimpTool *tool,
|
||||
GimpToolAction action,
|
||||
GimpDisplay *display);
|
||||
static void gimp_selection_tool_modifier_key (GimpTool *tool,
|
||||
GdkModifierType key,
|
||||
gboolean press,
|
||||
|
@ -59,10 +64,17 @@ static void gimp_selection_tool_cursor_update (GimpTool *tool,
|
|||
GdkModifierType state,
|
||||
GimpDisplay *display);
|
||||
|
||||
static void gimp_selection_tool_commit (GimpSelectionTool *sel_tool);
|
||||
static void gimp_selection_tool_halt (GimpSelectionTool *sel_tool,
|
||||
GimpDisplay *dispaly);
|
||||
|
||||
static gboolean gimp_selection_tool_check (GimpSelectionTool *sel_tool,
|
||||
GimpDisplay *display,
|
||||
GError **error);
|
||||
|
||||
static void gimp_selection_tool_set_undo_ptr (GimpUndo **undo_ptr,
|
||||
GimpUndo *undo);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GimpSelectionTool, gimp_selection_tool, GIMP_TYPE_DRAW_TOOL)
|
||||
|
||||
|
@ -74,6 +86,7 @@ gimp_selection_tool_class_init (GimpSelectionToolClass *klass)
|
|||
{
|
||||
GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass);
|
||||
|
||||
tool_class->control = gimp_selection_tool_control;
|
||||
tool_class->modifier_key = gimp_selection_tool_modifier_key;
|
||||
tool_class->key_press = gimp_edit_selection_tool_key_press;
|
||||
tool_class->oper_update = gimp_selection_tool_oper_update;
|
||||
|
@ -86,9 +99,39 @@ gimp_selection_tool_init (GimpSelectionTool *selection_tool)
|
|||
selection_tool->function = SELECTION_SELECT;
|
||||
selection_tool->saved_operation = GIMP_CHANNEL_OP_REPLACE;
|
||||
|
||||
selection_tool->saved_show_selection = FALSE;
|
||||
selection_tool->undo = NULL;
|
||||
selection_tool->redo = NULL;
|
||||
selection_tool->idle_id = 0;
|
||||
|
||||
selection_tool->allow_move = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_selection_tool_control (GimpTool *tool,
|
||||
GimpToolAction action,
|
||||
GimpDisplay *display)
|
||||
{
|
||||
GimpSelectionTool *selection_tool = GIMP_SELECTION_TOOL (tool);
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case GIMP_TOOL_ACTION_PAUSE:
|
||||
case GIMP_TOOL_ACTION_RESUME:
|
||||
break;
|
||||
|
||||
case GIMP_TOOL_ACTION_HALT:
|
||||
gimp_selection_tool_halt (selection_tool, display);
|
||||
break;
|
||||
|
||||
case GIMP_TOOL_ACTION_COMMIT:
|
||||
gimp_selection_tool_commit (selection_tool);
|
||||
break;
|
||||
}
|
||||
|
||||
GIMP_TOOL_CLASS (parent_class)->control (tool, action, display);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_selection_tool_modifier_key (GimpTool *tool,
|
||||
GdkModifierType key,
|
||||
|
@ -396,6 +439,47 @@ gimp_selection_tool_cursor_update (GimpTool *tool,
|
|||
modifier);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_selection_tool_commit (GimpSelectionTool *sel_tool)
|
||||
{
|
||||
/* make sure gimp_selection_tool_halt() doesn't undo the change, if any */
|
||||
gimp_selection_tool_set_undo_ptr (&sel_tool->undo, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_selection_tool_halt (GimpSelectionTool *sel_tool,
|
||||
GimpDisplay *display)
|
||||
{
|
||||
g_warn_if_fail (sel_tool->change_count == 0);
|
||||
|
||||
if (display)
|
||||
{
|
||||
GimpTool *tool = GIMP_TOOL (sel_tool);
|
||||
GimpImage *image = gimp_display_get_image (display);
|
||||
GimpUndoStack *undo_stack = gimp_image_get_undo_stack (image);
|
||||
GimpUndo *undo = gimp_undo_stack_peek (undo_stack);
|
||||
|
||||
/* if we have an existing selection 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
|
||||
*/
|
||||
if (undo && sel_tool->undo == undo)
|
||||
{
|
||||
/* prevent this change from halting the tool */
|
||||
gimp_tool_control_push_preserve (tool->control, TRUE);
|
||||
|
||||
gimp_image_undo (image);
|
||||
gimp_image_flush (image);
|
||||
|
||||
gimp_tool_control_pop_preserve (tool->control);
|
||||
}
|
||||
|
||||
/* reset the automatic undo/redo mechanism */
|
||||
gimp_selection_tool_set_undo_ptr (&sel_tool->undo, NULL);
|
||||
gimp_selection_tool_set_undo_ptr (&sel_tool->redo, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_selection_tool_check (GimpSelectionTool *sel_tool,
|
||||
GimpDisplay *display,
|
||||
|
@ -466,6 +550,25 @@ gimp_selection_tool_check (GimpSelectionTool *sel_tool,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_selection_tool_set_undo_ptr (GimpUndo **undo_ptr,
|
||||
GimpUndo *undo)
|
||||
{
|
||||
if (*undo_ptr)
|
||||
{
|
||||
g_object_remove_weak_pointer (G_OBJECT (*undo_ptr),
|
||||
(gpointer *) undo_ptr);
|
||||
}
|
||||
|
||||
*undo_ptr = undo;
|
||||
|
||||
if (*undo_ptr)
|
||||
{
|
||||
g_object_add_weak_pointer (G_OBJECT (*undo_ptr),
|
||||
(gpointer *) undo_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
||||
|
@ -528,3 +631,165 @@ gimp_selection_tool_start_edit (GimpSelectionTool *sel_tool,
|
|||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_selection_tool_idle (GimpSelectionTool *sel_tool)
|
||||
{
|
||||
GimpTool *tool = GIMP_TOOL (sel_tool);
|
||||
GimpDisplayShell *shell = gimp_display_get_shell (tool->display);
|
||||
|
||||
gimp_display_shell_set_show_selection (shell, FALSE);
|
||||
|
||||
sel_tool->idle_id = 0;
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_selection_tool_start_change (GimpSelectionTool *sel_tool,
|
||||
gboolean create,
|
||||
GimpChannelOps operation)
|
||||
{
|
||||
GimpTool *tool;
|
||||
GimpDisplayShell *shell;
|
||||
GimpImage *image;
|
||||
GimpUndoStack *undo_stack;
|
||||
|
||||
g_return_if_fail (GIMP_IS_SELECTION_TOOL (sel_tool));
|
||||
|
||||
tool = GIMP_TOOL (sel_tool);
|
||||
|
||||
g_return_if_fail (tool->display != NULL);
|
||||
|
||||
if (sel_tool->change_count++ > 0)
|
||||
return;
|
||||
|
||||
shell = gimp_display_get_shell (tool->display);
|
||||
image = gimp_display_get_image (tool->display);
|
||||
undo_stack = gimp_image_get_undo_stack (image);
|
||||
|
||||
sel_tool->saved_show_selection =
|
||||
gimp_display_shell_get_show_selection (shell);
|
||||
|
||||
if (create)
|
||||
{
|
||||
gimp_selection_tool_set_undo_ptr (&sel_tool->undo, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
GimpUndoStack *redo_stack = gimp_image_get_redo_stack (image);
|
||||
GimpUndo *undo;
|
||||
|
||||
undo = gimp_undo_stack_peek (undo_stack);
|
||||
|
||||
if (undo && undo == sel_tool->undo)
|
||||
{
|
||||
/* prevent this change from halting the tool */
|
||||
gimp_tool_control_push_preserve (tool->control, TRUE);
|
||||
|
||||
gimp_image_undo (image);
|
||||
|
||||
gimp_tool_control_pop_preserve (tool->control);
|
||||
|
||||
gimp_selection_tool_set_undo_ptr (&sel_tool->undo, NULL);
|
||||
|
||||
/* we will need to redo if the user cancels or executes */
|
||||
gimp_selection_tool_set_undo_ptr (
|
||||
&sel_tool->redo,
|
||||
gimp_undo_stack_peek (redo_stack));
|
||||
}
|
||||
|
||||
/* if the operation is "Replace", turn off the marching ants,
|
||||
* because they are confusing ...
|
||||
*/
|
||||
if (operation == GIMP_CHANNEL_OP_REPLACE)
|
||||
{
|
||||
/* ... however, do this in an idle function, to avoid unnecessarily
|
||||
* restarting the selection if we don't visit the main loop between
|
||||
* the start_change() and end_change() calls.
|
||||
*/
|
||||
sel_tool->idle_id = g_idle_add (
|
||||
(GSourceFunc) gimp_selection_tool_idle,
|
||||
sel_tool);
|
||||
}
|
||||
}
|
||||
|
||||
gimp_selection_tool_set_undo_ptr (
|
||||
&sel_tool->undo,
|
||||
gimp_undo_stack_peek (undo_stack));
|
||||
}
|
||||
|
||||
void
|
||||
gimp_selection_tool_end_change (GimpSelectionTool *sel_tool,
|
||||
gboolean cancel)
|
||||
{
|
||||
GimpTool *tool;
|
||||
GimpDisplayShell *shell;
|
||||
GimpImage *image;
|
||||
GimpUndoStack *undo_stack;
|
||||
|
||||
g_return_if_fail (GIMP_IS_SELECTION_TOOL (sel_tool));
|
||||
g_return_if_fail (sel_tool->change_count > 0);
|
||||
|
||||
tool = GIMP_TOOL (sel_tool);
|
||||
|
||||
g_return_if_fail (tool->display != NULL);
|
||||
|
||||
if (--sel_tool->change_count > 0)
|
||||
return;
|
||||
|
||||
shell = gimp_display_get_shell (tool->display);
|
||||
image = gimp_display_get_image (tool->display);
|
||||
undo_stack = gimp_image_get_undo_stack (image);
|
||||
|
||||
if (cancel)
|
||||
{
|
||||
GimpUndoStack *redo_stack = gimp_image_get_redo_stack (image);
|
||||
GimpUndo *redo = gimp_undo_stack_peek (redo_stack);
|
||||
|
||||
if (redo && redo == sel_tool->redo)
|
||||
{
|
||||
/* prevent this from halting the tool */
|
||||
gimp_tool_control_push_preserve (tool->control, TRUE);
|
||||
|
||||
gimp_image_redo (image);
|
||||
|
||||
gimp_tool_control_pop_preserve (tool->control);
|
||||
|
||||
gimp_selection_tool_set_undo_ptr (
|
||||
&sel_tool->undo,
|
||||
gimp_undo_stack_peek (undo_stack));
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_selection_tool_set_undo_ptr (&sel_tool->undo, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GimpUndo *undo = gimp_undo_stack_peek (undo_stack);
|
||||
|
||||
/* save the undo that we got when executing, but only if
|
||||
* we actually selected something
|
||||
*/
|
||||
if (undo && undo != sel_tool->undo)
|
||||
gimp_selection_tool_set_undo_ptr (&sel_tool->undo, undo);
|
||||
else
|
||||
gimp_selection_tool_set_undo_ptr (&sel_tool->undo, NULL);
|
||||
}
|
||||
|
||||
gimp_selection_tool_set_undo_ptr (&sel_tool->redo, NULL);
|
||||
|
||||
if (sel_tool->idle_id)
|
||||
{
|
||||
g_source_remove (sel_tool->idle_id);
|
||||
sel_tool->idle_id = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_display_shell_set_show_selection (shell,
|
||||
sel_tool->saved_show_selection);
|
||||
}
|
||||
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,12 @@ struct _GimpSelectionTool
|
|||
SelectFunction function; /* selection function */
|
||||
GimpChannelOps saved_operation; /* saved tool options state */
|
||||
|
||||
gint change_count;
|
||||
gboolean saved_show_selection;
|
||||
GimpUndo *undo;
|
||||
GimpUndo *redo;
|
||||
gint idle_id;
|
||||
|
||||
gboolean allow_move;
|
||||
};
|
||||
|
||||
|
@ -58,5 +64,11 @@ gboolean gimp_selection_tool_start_edit (GimpSelectionTool *sel_tool,
|
|||
GimpDisplay *display,
|
||||
const GimpCoords *coords);
|
||||
|
||||
void gimp_selection_tool_start_change (GimpSelectionTool *sel_tool,
|
||||
gboolean create,
|
||||
GimpChannelOps operation);
|
||||
void gimp_selection_tool_end_change (GimpSelectionTool *sel_tool,
|
||||
gboolean cancel);
|
||||
|
||||
|
||||
#endif /* __GIMP_SELECTION_TOOL_H__ */
|
||||
|
|
Loading…
Reference in New Issue