[gimp] app: integrate transform tool undo with normal image undo
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: integrate transform tool undo with normal image undo
- Date: Thu, 23 May 2013 14:05:14 +0000 (UTC)
commit fdfa2c782d9c88ff34083c3a15545f9fce3a35df
Author: Michael Natterer <mitch gimp org>
Date: Thu May 23 16:02:42 2013 +0200
app: integrate transform tool undo with normal image undo
Also clean up formatting a bit, and add gimp_transform_tool_halt()
which really cleans the tool's state, so we don't end up with wrong
undo/redo actions in a new tool interaction.
app/tools/gimptransformtool.c | 309 ++++++++++++++++++++++++++++-------------
app/tools/gimptransformtool.h | 11 +-
2 files changed, 221 insertions(+), 99 deletions(-)
---
diff --git a/app/tools/gimptransformtool.c b/app/tools/gimptransformtool.c
index 30bb64d..f875ec6 100644
--- a/app/tools/gimptransformtool.c
+++ b/app/tools/gimptransformtool.c
@@ -68,8 +68,6 @@
#define RESPONSE_RESET 1
-#define RESPONSE_UNDO 2
-#define RESPONSE_REDO 3
#define MIN_HANDLE_SIZE 6
@@ -115,6 +113,14 @@ static void gimp_transform_tool_cursor_update (GimpTool
const GimpCoords *coords,
GdkModifierType state,
GimpDisplay *display);
+const gchar * gimp_transform_tool_get_undo_desc (GimpTool *tool,
+ GimpDisplay *display);
+const gchar * gimp_transform_tool_get_redo_desc (GimpTool *tool,
+ GimpDisplay *display);
+gboolean gimp_transform_tool_undo (GimpTool *tool,
+ GimpDisplay *display);
+gboolean gimp_transform_tool_redo (GimpTool *tool,
+ GimpDisplay *display);
static void gimp_transform_tool_options_notify (GimpTool *tool,
GimpToolOptions *options,
const GParamSpec *pspec);
@@ -140,6 +146,7 @@ static TransformAction
GdkModifierType state,
GimpDisplay *display);
+static void gimp_transform_tool_halt (GimpTransformTool *tr_tool);
static void gimp_transform_tool_set_function (GimpTransformTool *tr_tool,
TransformAction function);
static void gimp_transform_tool_bounds (GimpTransformTool *tr_tool,
@@ -159,8 +166,8 @@ static void gimp_transform_tool_response (GtkWidget
gint response_id,
GimpTransformTool *tr_tool);
-static void free_trans (gpointer data);
-static void update_sensitivity (GimpTransformTool *tr_tool);
+static void gimp_transform_tool_free_trans (gpointer data);
+static void gimp_transform_tool_update_sensitivity (GimpTransformTool *tr_tool);
G_DEFINE_TYPE (GimpTransformTool, gimp_transform_tool, GIMP_TYPE_DRAW_TOOL)
@@ -187,6 +194,10 @@ gimp_transform_tool_class_init (GimpTransformToolClass *klass)
tool_class->active_modifier_key = gimp_transform_tool_modifier_key;
tool_class->oper_update = gimp_transform_tool_oper_update;
tool_class->cursor_update = gimp_transform_tool_cursor_update;
+ tool_class->get_undo_desc = gimp_transform_tool_get_undo_desc;
+ tool_class->get_redo_desc = gimp_transform_tool_get_redo_desc;
+ tool_class->undo = gimp_transform_tool_undo;
+ tool_class->redo = gimp_transform_tool_redo;
tool_class->options_notify = gimp_transform_tool_options_notify;
draw_class->draw = gimp_transform_tool_draw;
@@ -237,9 +248,6 @@ gimp_transform_tool_finalize (GObject *object)
tr_tool->dialog = NULL;
}
- g_list_free_full (tr_tool->redo_list, free_trans);
- g_list_free_full (tr_tool->undo_list, free_trans);
-
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -282,6 +290,8 @@ gimp_transform_tool_initialize (GimpTool *tool,
{
gint i;
+ gimp_transform_tool_halt (tr_tool);
+
/* Set the pointer to the active display */
tool->display = display;
tool->drawable = drawable;
@@ -313,7 +323,7 @@ gimp_transform_tool_initialize (GimpTool *tool,
tr_tool->redo_list = NULL;
tr_tool->old_trans_info = g_list_last (tr_tool->undo_list)->data;
tr_tool->prev_trans_info = g_list_first (tr_tool->undo_list)->data;
- update_sensitivity (tr_tool);
+ gimp_transform_tool_update_sensitivity (tr_tool);
/* Save the current transformation info */
for (i = 0; i < TRANS_INFO_SIZE; i++)
@@ -343,13 +353,8 @@ gimp_transform_tool_control (GimpTool *tool,
break;
case GIMP_TOOL_ACTION_HALT:
- tr_tool->function = TRANSFORM_CREATING;
-
- if (tr_tool->dialog)
- gimp_dialog_factory_hide_dialog (tr_tool->dialog);
-
- tool->drawable = NULL;
- break;
+ gimp_transform_tool_halt (tr_tool);
+ break;
}
GIMP_TOOL_CLASS (parent_class)->control (tool, action, display);
@@ -374,10 +379,13 @@ gimp_transform_tool_button_press (GimpTool *tool,
gimp_tool_control_activate (tool->control);
}
-void gimp_transform_tool_push_internal_undo (GimpTransformTool *tr_tool)
+void
+gimp_transform_tool_push_internal_undo (GimpTransformTool *tr_tool)
{
gint i;
+ g_return_if_fail (GIMP_IS_TRANSFORM_TOOL (tr_tool));
+
/* push current state on the undo list and set this state as the
* current state, but avoid doing this if there were no changes
*/
@@ -396,10 +404,13 @@ void gimp_transform_tool_push_internal_undo (GimpTransformTool *tr_tool)
/* If we undid anything and started interacting, we have to
* discard the redo history
*/
- g_list_free_full (tr_tool->redo_list, free_trans);
+ g_list_free_full (tr_tool->redo_list, gimp_transform_tool_free_trans);
tr_tool->redo_list = NULL;
- update_sensitivity (tr_tool);
+ gimp_transform_tool_update_sensitivity (tr_tool);
+
+ /* update the undo actions / menu items */
+ gimp_image_flush (gimp_display_get_image (GIMP_TOOL (tr_tool)->display));
}
}
@@ -486,8 +497,8 @@ gimp_transform_tool_key_press (GimpTool *tool,
GdkEventKey *kevent,
GimpDisplay *display)
{
- GimpTransformTool *trans_tool = GIMP_TRANSFORM_TOOL (tool);
- GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);
+ GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool);
+ GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);
if (display == draw_tool->display)
{
@@ -496,19 +507,15 @@ gimp_transform_tool_key_press (GimpTool *tool,
case GDK_KEY_Return:
case GDK_KEY_KP_Enter:
case GDK_KEY_ISO_Enter:
- gimp_transform_tool_response (NULL, GTK_RESPONSE_OK, trans_tool);
+ gimp_transform_tool_response (NULL, GTK_RESPONSE_OK, tr_tool);
return TRUE;
case GDK_KEY_BackSpace:
- gimp_transform_tool_response (NULL, RESPONSE_UNDO, trans_tool);
- return TRUE;
-
- case GDK_KEY_space:
- gimp_transform_tool_response (NULL, RESPONSE_REDO, trans_tool);
+ gimp_transform_tool_response (NULL, RESPONSE_RESET, tr_tool);
return TRUE;
case GDK_KEY_Escape:
- gimp_transform_tool_response (NULL, GTK_RESPONSE_CANCEL, trans_tool);
+ gimp_transform_tool_response (NULL, GTK_RESPONSE_CANCEL, tr_tool);
return TRUE;
}
}
@@ -670,7 +677,10 @@ gimp_transform_tool_oper_update (GimpTool *tool,
return;
}
- function = GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->pick_function (tr_tool, coords, state, display);
+ function = GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->pick_function (tr_tool,
+ coords,
+ state,
+ display);
gimp_transform_tool_set_function (tr_tool, function);
}
@@ -738,7 +748,9 @@ gimp_transform_tool_cursor_update (GimpTool *tool,
if (GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->cursor_update)
{
- GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->cursor_update (tr_tool, &cursor, &modifier);
+ GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->cursor_update (tr_tool,
+ &cursor,
+ &modifier);
}
switch (options->type)
@@ -772,6 +784,113 @@ gimp_transform_tool_cursor_update (GimpTool *tool,
GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
}
+const gchar *
+gimp_transform_tool_get_undo_desc (GimpTool *tool,
+ GimpDisplay *display)
+{
+ GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool);
+ GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);
+
+ if (display != draw_tool->display || ! tr_tool->undo_list ||
+ ! tr_tool->undo_list->next)
+ return NULL;
+
+ return _("Transform Step");
+}
+
+const gchar *
+gimp_transform_tool_get_redo_desc (GimpTool *tool,
+ GimpDisplay *display)
+{
+ GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool);
+ GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);
+
+ if (display != draw_tool->display || ! tr_tool->redo_list)
+ return NULL;
+
+ return _("Transform Step");
+}
+
+gboolean
+gimp_transform_tool_undo (GimpTool *tool,
+ GimpDisplay *display)
+{
+ GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool);
+ GList *item;
+ gint i;
+
+ if (! gimp_transform_tool_get_undo_desc (tool, display))
+ return FALSE;
+
+ item = g_list_next (tr_tool->undo_list);
+
+ /* Move prev_trans_info from undo_list to redo_list */
+ tr_tool->redo_list = g_list_prepend (tr_tool->redo_list,
+ tr_tool->prev_trans_info);
+ tr_tool->undo_list = g_list_remove (tr_tool->undo_list,
+ tr_tool->prev_trans_info);
+
+ tr_tool->prev_trans_info = item->data;
+
+ gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
+
+ /* Restore the previous transformation info */
+ for (i = 0; i < TRANS_INFO_SIZE; i++)
+ {
+ tr_tool->trans_info[i] = (*tr_tool->prev_trans_info)[i];
+ }
+
+ /* reget the selection bounds */
+ gimp_transform_tool_bounds (tr_tool, tool->display);
+
+ /* recalculate the tool's transformation matrix */
+ gimp_transform_tool_recalc_matrix (tr_tool);
+
+ gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
+
+ return TRUE;
+}
+
+gboolean
+gimp_transform_tool_redo (GimpTool *tool,
+ GimpDisplay *display)
+{
+ GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tool);
+ GList *item;
+ gint i;
+
+ if (! gimp_transform_tool_get_redo_desc (tool, display))
+ return FALSE;
+
+ item = tr_tool->redo_list;
+
+ /* Move prev_trans_info from redo_list to undo_list */
+ tr_tool->prev_trans_info = item->data;
+
+ tr_tool->undo_list = g_list_prepend (tr_tool->undo_list,
+ tr_tool->prev_trans_info);
+ tr_tool->redo_list = g_list_remove (tr_tool->redo_list,
+ tr_tool->prev_trans_info);
+
+ gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
+
+ /* Restore the previous transformation info */
+ for (i = 0; i < TRANS_INFO_SIZE; i++)
+ {
+ tr_tool->trans_info[i] = (*tr_tool->prev_trans_info)[i];
+ }
+
+ /* reget the selection bounds */
+ gimp_transform_tool_bounds (tr_tool, tool->display);
+
+ /* recalculate the tool's transformation matrix */
+ gimp_transform_tool_recalc_matrix (tr_tool);
+
+ gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
+
+ return TRUE;
+}
+
static void
gimp_transform_tool_options_notify (GimpTool *tool,
GimpToolOptions *options,
@@ -819,7 +938,9 @@ gimp_transform_tool_options_notify (GimpTool *tool,
}
static void
-gimp_transform_tool_real_draw_gui (GimpTransformTool *tr_tool, gint handle_w, gint handle_h)
+gimp_transform_tool_real_draw_gui (GimpTransformTool *tr_tool,
+ gint handle_w,
+ gint handle_h)
{
GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tr_tool);
@@ -1391,6 +1512,36 @@ gimp_transform_tool_transform (GimpTransformTool *tr_tool,
}
static void
+gimp_transform_tool_halt (GimpTransformTool *tr_tool)
+{
+ GimpTool *tool = GIMP_TOOL (tr_tool);
+
+ if (gimp_draw_tool_is_active (GIMP_DRAW_TOOL (tr_tool)))
+ gimp_draw_tool_stop (GIMP_DRAW_TOOL (tr_tool));
+
+ tr_tool->function = TRANSFORM_CREATING;
+
+ if (tr_tool->dialog)
+ gimp_dialog_factory_hide_dialog (tr_tool->dialog);
+
+ if (tr_tool->redo_list)
+ {
+ g_list_free_full (tr_tool->redo_list, gimp_transform_tool_free_trans);
+ tr_tool->redo_list = NULL;
+ }
+
+ if (tr_tool->undo_list)
+ {
+ g_list_free_full (tr_tool->undo_list, gimp_transform_tool_free_trans);
+ tr_tool->undo_list = NULL;
+ tr_tool->prev_trans_info = NULL;
+ }
+
+ tool->display = NULL;
+ tool->drawable = NULL;
+ }
+
+static void
gimp_transform_tool_set_function (GimpTransformTool *tr_tool,
TransformAction function)
{
@@ -1543,8 +1694,6 @@ gimp_transform_tool_dialog (GimpTransformTool *tr_tool)
gimp_display_get_shell (tool->display),
tool_info->blurb,
GIMP_STOCK_RESET, RESPONSE_RESET,
- GTK_STOCK_UNDO, RESPONSE_UNDO,
- GTK_STOCK_REDO, RESPONSE_REDO,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
stock_id, GTK_RESPONSE_OK,
NULL);
@@ -1552,8 +1701,6 @@ gimp_transform_tool_dialog (GimpTransformTool *tr_tool)
GTK_RESPONSE_OK);
gtk_dialog_set_alternative_button_order (GTK_DIALOG (tr_tool->dialog),
RESPONSE_RESET,
- RESPONSE_UNDO,
- RESPONSE_REDO,
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-1);
@@ -1608,70 +1755,43 @@ gimp_transform_tool_response (GtkWidget *widget,
GimpTransformTool *tr_tool)
{
GimpTool *tool = GIMP_TOOL (tr_tool);
- GList *it = tr_tool->redo_list;
gint i;
switch (response_id)
{
- case RESPONSE_UNDO:
- {
- it = g_list_next (tr_tool->undo_list);
-
- case RESPONSE_REDO:
- if (it)
- {
case RESPONSE_RESET:
- if (response_id == RESPONSE_UNDO)
- {
- /* Move prev_trans_info from undo_list to redo_list */
- tr_tool->redo_list = g_list_prepend (tr_tool->redo_list,
- tr_tool->prev_trans_info);
- tr_tool->undo_list = g_list_remove (tr_tool->undo_list,
- tr_tool->prev_trans_info);
- tr_tool->prev_trans_info = it->data;
- }
- else if (response_id == RESPONSE_REDO)
- {
- /* And the opposite */
- tr_tool->prev_trans_info = it->data;
- tr_tool->undo_list = g_list_prepend (tr_tool->undo_list,
- tr_tool->prev_trans_info);
- tr_tool->redo_list = g_list_remove (tr_tool->redo_list,
- tr_tool->prev_trans_info);
- }
- else if (response_id == RESPONSE_RESET)
- {
- /* Move all undo events to redo, and pop off the first
- * one as that's the current one, which always sits on
- * the undo_list
- */
- tr_tool->redo_list =
- g_list_remove (g_list_concat (g_list_reverse (tr_tool->undo_list),
- tr_tool->redo_list),
- tr_tool->old_trans_info);
- tr_tool->prev_trans_info = tr_tool->old_trans_info;
- tr_tool->undo_list = g_list_prepend (NULL,
- tr_tool->prev_trans_info);
- }
- update_sensitivity (tr_tool);
+ /* Move all undo events to redo, and pop off the first
+ * one as that's the current one, which always sits on
+ * the undo_list
+ */
+ tr_tool->redo_list =
+ g_list_remove (g_list_concat (g_list_reverse (tr_tool->undo_list),
+ tr_tool->redo_list),
+ tr_tool->old_trans_info);
+ tr_tool->prev_trans_info = tr_tool->old_trans_info;
+ tr_tool->undo_list = g_list_prepend (NULL,
+ tr_tool->prev_trans_info);
- gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
+ gimp_transform_tool_update_sensitivity (tr_tool);
- /* Restore the previous transformation info */
- for (i = 0; i < TRANS_INFO_SIZE; i++)
- {
- tr_tool->trans_info[i] = (*tr_tool->prev_trans_info)[i];
- }
+ gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
- /* reget the selection bounds */
- gimp_transform_tool_bounds (tr_tool, tool->display);
+ /* Restore the previous transformation info */
+ for (i = 0; i < TRANS_INFO_SIZE; i++)
+ {
+ tr_tool->trans_info[i] = (*tr_tool->prev_trans_info)[i];
+ }
- /* recalculate the tool's transformation matrix */
- gimp_transform_tool_recalc_matrix (tr_tool);
+ /* reget the selection bounds */
+ gimp_transform_tool_bounds (tr_tool, tool->display);
- gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
- }
- }
+ /* recalculate the tool's transformation matrix */
+ gimp_transform_tool_recalc_matrix (tr_tool);
+
+ gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
+
+ /* update the undo actions / menu items */
+ gimp_image_flush (gimp_display_get_image (tool->display));
break;
case GTK_RESPONSE_OK:
@@ -1681,26 +1801,25 @@ gimp_transform_tool_response (GtkWidget *widget,
default:
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, tool->display);
+
+ /* update the undo actions / menu items */
+ gimp_image_flush (gimp_display_get_image (tool->display));
break;
}
}
static void
-free_trans (gpointer data)
+gimp_transform_tool_free_trans (gpointer data)
{
g_slice_free (TransInfo, data);
}
static void
-update_sensitivity (GimpTransformTool *tr_tool)
+gimp_transform_tool_update_sensitivity (GimpTransformTool *tr_tool)
{
if (!tr_tool->dialog)
return;
- gtk_dialog_set_response_sensitive (GTK_DIALOG (tr_tool->dialog), RESPONSE_UNDO,
- g_list_next (tr_tool->undo_list) != NULL);
- gtk_dialog_set_response_sensitive (GTK_DIALOG (tr_tool->dialog), RESPONSE_REDO,
- tr_tool->redo_list != NULL);
gtk_dialog_set_response_sensitive (GTK_DIALOG (tr_tool->dialog), RESPONSE_RESET,
- g_list_next (tr_tool->undo_list) != NULL);
+ g_list_next (tr_tool->undo_list) != NULL);
}
diff --git a/app/tools/gimptransformtool.h b/app/tools/gimptransformtool.h
index e2d86d3..9696262 100644
--- a/app/tools/gimptransformtool.h
+++ b/app/tools/gimptransformtool.h
@@ -49,8 +49,11 @@ typedef enum
TRANSFORM_HANDLE_NUM /* keep this last so *handles[] is the right size */
} TransformAction;
-/* This is not the number of items in the enum above, but the max size of the
- * enums at the top of each transformation tool, stored in trans_info and related */
+
+/* This is not the number of items in the enum above, but the max size
+ * of the enums at the top of each transformation tool, stored in
+ * trans_info and related
+ */
#define TRANS_INFO_SIZE 10
typedef gdouble TransInfo[TRANS_INFO_SIZE];
@@ -153,9 +156,9 @@ struct _GimpTransformToolClass
};
-GType gimp_transform_tool_get_type (void) G_GNUC_CONST;
+GType gimp_transform_tool_get_type (void) G_GNUC_CONST;
-void gimp_transform_tool_recalc_matrix (GimpTransformTool *tr_tool);
+void gimp_transform_tool_recalc_matrix (GimpTransformTool *tr_tool);
void gimp_transform_tool_push_internal_undo (GimpTransformTool *tr_tool);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]