TBO undo and redo stack and test.
authordanigm <danigm@wadobo.com>
Thu, 2 Jun 2011 19:15:20 +0000 (21:15 +0200)
committerdanigm <danigm@wadobo.com>
Thu, 2 Jun 2011 19:15:20 +0000 (21:15 +0200)
src/Makefile.am
src/tbo-undo.c [new file with mode: 0644]
src/tbo-undo.h [new file with mode: 0644]
src/undotest.c [new file with mode: 0644]

index b0ddf4b..ffbfecd 100644 (file)
@@ -5,7 +5,7 @@ AM_CPPFLAGS = -I$(top_srcdir) -I$(includedir) $(GNOME_INCLUDEDIR) \
          -DG_LOG_DOMAIN=\"tbo\"
 
 bin_PROGRAMS = tbo
-noinst_PROGRAMS = typestest
+noinst_PROGRAMS = typestest undotest
 
 SOURCES = \
        tbo-window.c \
@@ -68,7 +68,9 @@ SOURCES = \
        tbo-toolbar.c \
        tbo-drawing.h \
        tbo-drawing.c \
-       custom-stock.h
+       custom-stock.h \
+       tbo-undo.h \
+       tbo-undo.c
 
 AM_CFLAGS = @GTK_CFLAGS@ \
                         $(PACKAGE_CFLAGS) \
@@ -78,8 +80,11 @@ tbo_LDADD = @GTK_LIBS@ \
                        $(PACKAGE_LIBS)
 typestest_LDADD = @GTK_LIBS@ \
                                $(PACKAGE_LIBS)
+undotest_LDADD = @GTK_LIBS@ \
+                               $(PACKAGE_LIBS)
 
 typestest_SOURCES = $(SOURCES) typestest.c
+undotest_SOURCES = $(SOURCES) undotest.c
 tbo_SOURCES = $(SOURCES) tbo.c
 
 CLEANFILES = *~
diff --git a/src/tbo-undo.c b/src/tbo-undo.c
new file mode 100644 (file)
index 0000000..d0fe4ba
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * This file is part of TBO, a gnome comic editor
+ * Copyright (C) 2011 Daniel Garcia <danigm@wadobo.com>
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify
+ * it under the terms of the GNU General Public License as published
+ * by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include "tbo-undo.h"
+
+TboAction *
+tbo_action_new (gpointer data,
+                gpointer action_do,
+                gpointer action_undo)
+{
+    TboAction *action = malloc (sizeof (TboAction));
+    action->data = data;
+    action->action_do = action_do;
+    action->action_undo = action_undo;
+    return action;
+}
+
+void
+tbo_action_del (TboAction *action)
+{
+    free (action);
+}
+
+void
+tbo_action_del_data (TboAction *action, gpointer user_data)
+{
+    free (action);
+}
+
+TboUndoStack *
+tbo_undo_stack_new ()
+{
+    TboUndoStack *stack = malloc (sizeof (TboUndoStack));
+    stack->first = NULL;
+    stack->list = NULL;
+    stack->last_flag = FALSE;
+    stack->first_flag = FALSE;
+    return stack;
+}
+
+void
+tbo_undo_stack_insert (TboUndoStack *stack, TboAction *action)
+{
+    // Removing each element before the actual one
+    if (stack->first) {
+        while (stack->first != stack->list) {
+            tbo_action_del ((TboAction*)((stack->first)->data));
+            stack->first = g_list_remove_link (stack->first, stack->first);
+        }
+    }
+
+    stack->last_flag = FALSE;
+    stack->list = g_list_prepend (stack->list, (gpointer)action);
+    stack->first = stack->list;
+}
+
+void
+tbo_undo_stack_undo (TboUndoStack *stack)
+{
+    if (!stack->list)
+        return;
+
+    if (stack->last_flag)
+        return;
+
+    // undo
+    TboAction *action = NULL;
+    action = (stack->list)->data;
+    action->action_undo (action);
+
+    if (stack->list->next)
+        stack->list = (stack->list)->next;
+    else
+        stack->last_flag = TRUE;
+}
+
+void
+tbo_undo_stack_redo (TboUndoStack *stack)
+{
+    if (!stack->list)
+        return;
+
+    if (stack->last_flag)
+        stack->last_flag = FALSE;
+    else if (stack->list != stack->first)
+        stack->list = (stack->list)->prev;
+    else
+        return;
+
+
+    // redo
+    TboAction *action = NULL;
+    action = (stack->list)->data;
+    action->action_do (action);
+}
+
+void
+tbo_undo_stack_del (TboUndoStack *stack)
+{
+    g_list_foreach (stack->first, (GFunc)tbo_action_del_data, NULL);
+    free (stack);
+}
diff --git a/src/tbo-undo.h b/src/tbo-undo.h
new file mode 100644 (file)
index 0000000..c3f9332
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * This file is part of TBO, a gnome comic editor
+ * Copyright (C) 2011 Daniel Garcia <danigm@wadobo.com>
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify
+ * it under the terms of the GNU General Public License as published
+ * by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __TBO_UNDO__
+#define __TBO_UNDO__
+
+#include <glib.h>
+
+typedef struct _TboAction TboAction;
+typedef struct _TboUndoStack TboUndoStack;
+
+struct _TboAction {
+    gpointer data;
+    void (*action_do) (TboAction *action);
+    void (*action_undo) (TboAction *action);
+};
+
+TboAction * tbo_action_new (gpointer data, gpointer action_do, gpointer action_undo);
+void tbo_action_del (TboAction *action);
+
+struct _TboUndoStack {
+    GList *first;
+    GList *list;
+    gboolean last_flag;
+    gboolean first_flag;
+};
+
+TboUndoStack * tbo_undo_stack_new ();
+void tbo_undo_stack_del ();
+void tbo_undo_stack_insert (TboUndoStack *stack, TboAction *action);
+void tbo_undo_stack_undo (TboUndoStack *stack);
+void tbo_undo_stack_redo (TboUndoStack *stack);
+
+#endif
diff --git a/src/undotest.c b/src/undotest.c
new file mode 100644 (file)
index 0000000..8595c68
--- /dev/null
@@ -0,0 +1,64 @@
+#include <stdio.h>
+#include "tbo-undo.h"
+
+void
+testdo (TboAction *action) {
+    printf (" + doing %s\n", action->data);
+}
+
+void
+testundo (TboAction *action) {
+    printf (" - UNdoing %s\n", action->data);
+}
+
+int
+main (int argc, char **argv)
+{
+    TboUndoStack *stack;
+    TboAction *action;
+
+    printf ("Testing TBO undo\n");
+
+    stack = tbo_undo_stack_new ();
+
+    action = tbo_action_new ("Test action1", testdo, testundo);
+    tbo_undo_stack_insert (stack, action);
+    action = tbo_action_new ("Test action2", testdo, testundo);
+    tbo_undo_stack_insert (stack, action);
+    action = tbo_action_new ("Test action3", testdo, testundo);
+    tbo_undo_stack_insert (stack, action);
+
+    tbo_undo_stack_undo (stack);
+    tbo_undo_stack_undo (stack);
+    tbo_undo_stack_undo (stack);
+
+    printf ("\nUndoing nothing\n");
+    printf ("problem?\n");
+    tbo_undo_stack_undo (stack);
+    printf ("problem?\n");
+    tbo_undo_stack_undo (stack);
+
+    printf ("\nNow redoing\n");
+    // redoing
+    tbo_undo_stack_redo (stack);
+    tbo_undo_stack_redo (stack);
+    tbo_undo_stack_redo (stack);
+
+    printf ("\nRedoing nothing\n");
+    printf ("problem?\n");
+    tbo_undo_stack_redo (stack);
+    printf ("problem?\n");
+    tbo_undo_stack_redo (stack);
+
+    printf ("\nNow undo and redo\n");
+    tbo_undo_stack_undo (stack);
+    action = tbo_action_new ("Test action4", testdo, testundo);
+    tbo_undo_stack_insert (stack, action);
+    tbo_undo_stack_redo (stack);
+    tbo_undo_stack_undo (stack);
+    tbo_undo_stack_undo (stack);
+    tbo_undo_stack_redo (stack);
+
+    printf ("All OK\n");
+    return 0;
+}