[tbo] Undo and Redo form movements
- From: Daniel Garcia Moreno <danigm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tbo] Undo and Redo form movements
- Date: Sat, 4 Jun 2011 09:25:35 +0000 (UTC)
commit 969b192c8256c6061624110e013390978514399a
Author: danigm <danigm wadobo com>
Date: Sat Jun 4 11:23:50 2011 +0200
Undo and Redo form movements
data/ui/tbo-menu-ui.xml | 2 +
data/ui/tbo-toolbar-ui.xml | 3 +
src/tbo-tool-selector.c | 93 ++++++++++++++++++++++++++++++++++++++++++++
src/tbo-tool-selector.h | 30 ++++++++++++++
src/tbo-toolbar.c | 20 +++++++++-
src/tbo-undo.c | 16 +++++++-
src/tbo-undo.h | 5 ++-
src/tbo-window.c | 21 ++++++++++
src/tbo-window.h | 5 ++
src/ui-menu.c | 13 ++++++
10 files changed, 204 insertions(+), 4 deletions(-)
---
diff --git a/data/ui/tbo-menu-ui.xml b/data/ui/tbo-menu-ui.xml
index fb85d6f..ac81215 100644
--- a/data/ui/tbo-menu-ui.xml
+++ b/data/ui/tbo-menu-ui.xml
@@ -11,6 +11,8 @@
<menuitem name="Quit" action="Quit" />
</menu>
<menu name="EditMenu" action="Edit">
+ <menuitem name="undo" action="Undo" />
+ <menuitem name="redo" action="Redo" />
<menuitem name="clone" action="CloneObj" />
<menuitem name="delete" action="DeleteObj" />
<menuitem name="fliph" action="FlipHObj" />
diff --git a/data/ui/tbo-toolbar-ui.xml b/data/ui/tbo-toolbar-ui.xml
index 9d1cc1f..a8d6b2b 100644
--- a/data/ui/tbo-toolbar-ui.xml
+++ b/data/ui/tbo-toolbar-ui.xml
@@ -6,6 +6,9 @@
<toolitem name="OpenTool" action="OpenFileTool"/>
<toolitem name="SaveTool" action="SaveFileTool"/>
<separator/>
+ <toolitem name="undo" action="Undo" />
+ <toolitem name="redo" action="Redo" />
+ <separator/>
<toolitem name="newpage" action="NewPage"/>
<toolitem name="delpage" action="DelPage"/>
<toolitem name="ppage" action="PrevPage"/>
diff --git a/src/tbo-tool-selector.c b/src/tbo-tool-selector.c
index 9b50517..ba498c7 100644
--- a/src/tbo-tool-selector.c
+++ b/src/tbo-tool-selector.c
@@ -30,6 +30,7 @@
#include "tbo-object-group.h"
#include "ui-menu.h"
#include "tbo-tooltip.h"
+#include "tbo-undo.h"
G_DEFINE_TYPE (TboToolSelector, tbo_tool_selector, TBO_TYPE_TOOL_BASE);
@@ -228,6 +229,20 @@ over_rotater_obj (TboToolSelector *self, TboObjectBase *obj, int x, int y)
}
}
+static gboolean
+moved_frame (TboToolSelector *tool)
+{
+ Frame *obj = tool->selected_frame;
+ return (tool->start_m_x != obj->x || tool->start_m_y != obj->y);
+}
+
+static gboolean
+moved_object (TboToolSelector *tool)
+{
+ TboObjectBase *obj = tool->selected_object;
+ return (tool->start_m_x != obj->x || tool->start_m_y != obj->y);
+}
+
/* tool signal */
static void
on_move (TboToolBase *tool, GtkWidget *widget, GdkEventMotion *event)
@@ -259,6 +274,24 @@ static void
on_release (TboToolBase *tool, GtkWidget *widget, GdkEventButton *event)
{
TboToolSelector *self = TBO_TOOL_SELECTOR (tool);
+ TboWindow *tbo = tool->tbo;
+ // TODO create undo actions for movements / resizing and rotating
+ if (self->selected_object && moved_object (self)) {
+ tbo_undo_stack_insert (tbo->undo_stack,
+ tbo_action_object_move_new (self->selected_object,
+ self->start_m_x,
+ self->start_m_y,
+ self->selected_object->x,
+ self->selected_object->y));
+ }
+ else if (self->selected_frame && moved_frame (self)) {
+ tbo_undo_stack_insert (tbo->undo_stack,
+ tbo_action_frame_move_new (self->selected_frame,
+ self->start_m_x,
+ self->start_m_y,
+ self->selected_frame->x,
+ self->selected_frame->y));
+ }
self->start_x = 0;
self->start_y = 0;
self->clicked = FALSE;
@@ -867,3 +900,63 @@ tbo_tool_selector_set_selected_obj (TboToolSelector *self, TboObjectBase *obj)
update_menubar (TBO_TOOL_BASE (self)->tbo);
}
+
+static void
+frame_move_do (TboAction *act)
+{
+ TboActionFrameMove *action = (TboActionFrameMove*)act;
+ action->frame->x = action->x2;
+ action->frame->y = action->y2;
+}
+
+static void
+frame_move_undo (TboAction *act)
+{
+ TboActionFrameMove *action = (TboActionFrameMove*)act;
+ action->frame->x = action->x1;
+ action->frame->y = action->y1;
+}
+
+TboAction *
+tbo_action_frame_move_new (Frame *frame, int x1, int y1, int x2, int y2)
+{
+ TboActionFrameMove *action = (TboActionFrameMove*)tbo_action_new (TboActionFrameMove);
+ action->frame = frame;
+ action->x1 = x1;
+ action->x2 = x2;
+ action->y1 = y1;
+ action->y2 = y2;
+ action->action_do = frame_move_do;
+ action->action_undo = frame_move_undo;
+ return (TboAction*)action;
+}
+
+static void
+obj_move_do (TboAction *act)
+{
+ TboActionObjMove *action = (TboActionObjMove*)act;
+ action->obj->x = action->x2;
+ action->obj->y = action->y2;
+}
+
+static void
+obj_move_undo (TboAction *act)
+{
+ TboActionObjMove *action = (TboActionObjMove*)act;
+ action->obj->x = action->x1;
+ action->obj->y = action->y1;
+}
+
+TboAction *
+tbo_action_object_move_new (TboObjectBase *object, int x1, int y1, int x2, int y2)
+{
+ TboActionObjMove *action = (TboActionObjMove*)tbo_action_new (TboActionObjMove);
+ action->obj = object;
+ action->x1 = x1;
+ action->x2 = x2;
+ action->y1 = y1;
+ action->y2 = y2;
+ action->action_do = obj_move_do;
+ action->action_undo = obj_move_undo;
+ return (TboAction*)action;
+}
diff --git a/src/tbo-tool-selector.h b/src/tbo-tool-selector.h
index 367905f..49aaef2 100644
--- a/src/tbo-tool-selector.h
+++ b/src/tbo-tool-selector.h
@@ -26,6 +26,7 @@
#include "tbo-object-base.h"
#include "tbo-tool-base.h"
#include "tbo-types.h"
+#include "tbo-undo.h"
#define TBO_TYPE_TOOL_SELECTOR (tbo_tool_selector_get_type ())
#define TBO_TOOL_SELECTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TBO_TYPE_TOOL_SELECTOR, TboToolSelector))
@@ -85,5 +86,34 @@ void tbo_tool_selector_set_selected_obj (TboToolSelector *self, TboObjectBase *o
GObject * tbo_tool_selector_new ();
GObject * tbo_tool_selector_new_with_params (TboWindow *tbo);
+/*
+ * TboActionFrameMove for undo and redo frame movements
+ */
+typedef struct _TboActionFrameMove TboActionFrameMove;
+typedef struct _TboActionObjMove TboActionObjMove;
+
+struct _TboActionFrameMove {
+ void (*action_do) (TboAction *action);
+ void (*action_undo) (TboAction *action);
+ Frame *frame;
+ int x1;
+ int y1;
+ int x2;
+ int y2;
+};
+TboAction * tbo_action_frame_move_new (Frame *frame, int x1, int y1, int x2, int y2);
+
+struct _TboActionObjMove {
+ void (*action_do) (TboAction *action);
+ void (*action_undo) (TboAction *action);
+ TboObjectBase *obj;
+ int x1;
+ int y1;
+ int x2;
+ int y2;
+};
+TboAction * tbo_action_object_move_new (TboObjectBase *object, int x1, int y1, int x2, int y2);
+
+
#endif /* __TBO_TOOL_SELECTOR_H__ */
diff --git a/src/tbo-toolbar.c b/src/tbo-toolbar.c
index 0ac2b85..71f44f0 100644
--- a/src/tbo-toolbar.c
+++ b/src/tbo-toolbar.c
@@ -34,6 +34,7 @@
#include "tbo-tool-bubble.h"
#include "tbo-tool-text.h"
#include "ui-menu.h"
+#include "tbo-undo.h"
G_DEFINE_TYPE (TboToolbar, tbo_toolbar, G_TYPE_OBJECT);
@@ -41,7 +42,6 @@ G_DEFINE_TYPE (TboToolbar, tbo_toolbar, G_TYPE_OBJECT);
static gboolean select_tool (GtkAction *action, TboToolbar *toolbar);
/* callbacks */
-
static gboolean
add_new_page (GtkAction *action, TboWindow *tbo)
{
@@ -172,6 +172,14 @@ static const GtkActionEntry tbo_tools_entries [] = {
N_("Save current document"),
G_CALLBACK (tbo_comic_save_dialog) },
+ // Undo and Redo
+ { "Undo", GTK_STOCK_UNDO, N_("_Undo"), "<control>Z",
+ N_("Undo the last action"),
+ G_CALLBACK (tbo_window_undo_cb) },
+ { "Redo", GTK_STOCK_REDO, N_("_Redo"), "<control>Y",
+ N_("Undo the last action"),
+ G_CALLBACK (tbo_window_redo_cb) },
+
// Page tools
{ "NewPage", GTK_STOCK_ADD, N_("New Page"), "<control>P",
N_("New page"),
@@ -448,6 +456,10 @@ tbo_toolbar_update (TboToolbar *self)
GtkAction *text;
GtkAction *new_frame;
GtkAction *pix;
+
+ GtkAction *undo;
+ GtkAction *redo;
+
if (!self)
return;
@@ -456,6 +468,12 @@ tbo_toolbar_update (TboToolbar *self)
if (!self->action_group)
return;
+ undo = gtk_action_group_get_action (self->action_group, "Undo");
+ redo = gtk_action_group_get_action (self->action_group, "Redo");
+
+ gtk_action_set_sensitive (undo, tbo_undo_active_undo (tbo->undo_stack));
+ gtk_action_set_sensitive (redo, tbo_undo_active_redo (tbo->undo_stack));
+
// Page next, prev and delete button sensitive
prev = gtk_action_group_get_action (self->action_group, "PrevPage");
next = gtk_action_group_get_action (self->action_group, "NextPage");
diff --git a/src/tbo-undo.c b/src/tbo-undo.c
index ae5fad2..2346309 100644
--- a/src/tbo-undo.c
+++ b/src/tbo-undo.c
@@ -48,8 +48,7 @@ tbo_undo_stack_new ()
TboUndoStack *stack = malloc (sizeof (TboUndoStack));
stack->first = NULL;
stack->list = NULL;
- stack->last_flag = FALSE;
- stack->first_flag = FALSE;
+ stack->last_flag = TRUE;
return stack;
}
@@ -115,3 +114,16 @@ tbo_undo_stack_del (TboUndoStack *stack)
g_list_foreach (stack->first, (GFunc)tbo_action_del_data, NULL);
free (stack);
}
+
+
+gboolean
+tbo_undo_active_undo (TboUndoStack *stack)
+{
+ return !stack->last_flag;
+}
+
+gboolean
+tbo_undo_active_redo (TboUndoStack *stack)
+{
+ return stack->first != stack->list;
+}
diff --git a/src/tbo-undo.h b/src/tbo-undo.h
index 9348e9a..e03c97d 100644
--- a/src/tbo-undo.h
+++ b/src/tbo-undo.h
@@ -22,6 +22,7 @@
#define __TBO_UNDO__
#include <glib.h>
+#include <stdlib.h>
#define tbo_action_new(action_type) (TboAction*) malloc (sizeof (action_type))
#define tbo_action_do(action) ((TboAction*) action)->action_do ((TboAction*)action)
@@ -43,7 +44,6 @@ struct _TboUndoStack {
GList *first;
GList *list;
gboolean last_flag;
- gboolean first_flag;
};
TboUndoStack * tbo_undo_stack_new ();
@@ -52,4 +52,7 @@ void tbo_undo_stack_insert (TboUndoStack *stack, TboAction *action);
void tbo_undo_stack_undo (TboUndoStack *stack);
void tbo_undo_stack_redo (TboUndoStack *stack);
+gboolean tbo_undo_active_undo (TboUndoStack *stack);
+gboolean tbo_undo_active_redo (TboUndoStack *stack);
+
#endif
diff --git a/src/tbo-window.c b/src/tbo-window.c
index bb7f489..8b93bd4 100644
--- a/src/tbo-window.c
+++ b/src/tbo-window.c
@@ -129,6 +129,8 @@ tbo_window_new (GtkWidget *window, GtkWidget *dw_scroll,
tbo->comic = comic;
tbo->toolarea = toolarea;
tbo->notebook = notebook;
+
+ tbo->undo_stack = tbo_undo_stack_new ();
tbo->path = NULL;
return tbo;
@@ -141,6 +143,7 @@ tbo_window_free (TboWindow *tbo)
gtk_widget_destroy (tbo->window);
if (tbo->path)
free (tbo->path);
+ tbo_undo_stack_del (tbo->undo_stack);
free (tbo);
}
@@ -326,3 +329,21 @@ tbo_window_set_current_tab_page (TboWindow *tbo, gboolean setit)
tbo_tool_selector_set_selected (TBO_TOOL_SELECTOR (tbo->toolbar->selected_tool), NULL);
tbo_tool_selector_set_selected_obj (TBO_TOOL_SELECTOR (tbo->toolbar->selected_tool), NULL);
}
+
+gboolean
+tbo_window_undo_cb (GtkAction *action, TboWindow *tbo) {
+ tbo_undo_stack_undo (tbo->undo_stack);
+
+ tbo_drawing_update (TBO_DRAWING (tbo->drawing));
+ tbo_toolbar_update (tbo->toolbar);
+ return FALSE;
+}
+
+gboolean
+tbo_window_redo_cb (GtkAction *action, TboWindow *tbo) {
+ tbo_undo_stack_redo (tbo->undo_stack);
+
+ tbo_drawing_update (TBO_DRAWING (tbo->drawing));
+ tbo_toolbar_update (tbo->toolbar);
+ return FALSE;
+}
diff --git a/src/tbo-window.h b/src/tbo-window.h
index 61fa152..e64fa49 100644
--- a/src/tbo-window.h
+++ b/src/tbo-window.h
@@ -23,6 +23,7 @@
#include <gtk/gtk.h>
#include "tbo-toolbar.h"
#include "tbo-types.h"
+#include "tbo-undo.h"
struct _TboWindow
{
@@ -35,6 +36,7 @@ struct _TboWindow
GtkWidget *status;
GtkWidget *vbox;
TboToolbar *toolbar;
+ TboUndoStack *undo_stack;
Comic *comic;
char *path;
};
@@ -50,5 +52,8 @@ void tbo_window_set_path (TboWindow *tbo, const char *path);
void tbo_window_set_current_tab_page (TboWindow *tbo, gboolean setit);
GtkWidget *create_darea (TboWindow *tbo);
void tbo_window_set_key_binder (TboWindow *tbo, gboolean keyb);
+gboolean tbo_window_undo_cb (GtkAction *action, TboWindow *tbo);
+gboolean tbo_window_redo_cb (GtkAction *action, TboWindow *tbo);
+
#endif
diff --git a/src/ui-menu.c b/src/ui-menu.c
index 1a3bfe1..b381ecf 100644
--- a/src/ui-menu.c
+++ b/src/ui-menu.c
@@ -34,6 +34,7 @@
#include "frame.h"
#include "page.h"
#include "tbo-object-base.h"
+#include "tbo-undo.h"
static GtkActionGroup *MENU_ACTION_GROUP = NULL;
static GtkAccelGroup *ACCEL = NULL;
@@ -83,6 +84,12 @@ update_menubar (TboWindow *tbo)
gtk_action_set_sensitive (action, FALSE);
}
}
+
+ // undo and redo
+ action = gtk_action_group_get_action (MENU_ACTION_GROUP, "Undo");
+ gtk_action_set_sensitive (action, tbo_undo_active_undo (tbo->undo_stack));
+ action = gtk_action_group_get_action (MENU_ACTION_GROUP, "Redo");
+ gtk_action_set_sensitive (action, tbo_undo_active_redo (tbo->undo_stack));
}
gboolean
@@ -274,6 +281,12 @@ static const GtkActionEntry tbo_menu_entries [] = {
G_CALLBACK (close_cb) },
/* edit menu */
+ { "Undo", GTK_STOCK_UNDO, N_("_Undo"), "<control>Z",
+ N_("Undo the last action"),
+ G_CALLBACK (tbo_window_undo_cb) },
+ { "Redo", GTK_STOCK_REDO, N_("_Redo"), "<control>Y",
+ N_("Undo the last action"),
+ G_CALLBACK (tbo_window_redo_cb) },
{ "CloneObj", GTK_STOCK_COPY, N_("Clone"), "<control>d",
N_("Clone"),
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]