summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Seguin <guillaume@segu.in>2007-12-08 20:00:58 +0100
committerGuillaume Seguin <guillaume@segu.in>2007-12-08 20:00:58 +0100
commita495aa8e353e7de43d19a699c5796cdf2a81b9b8 (patch)
tree0dd803f98099d941a1479c19814b83b74f51e8a8
parent16ca2d8d6b7c620d0d9d7d553d2b81dc861a86ea (diff)
downloadgmathlib-a495aa8e353e7de43d19a699c5796cdf2a81b9b8.tar.gz
gmathlib-a495aa8e353e7de43d19a699c5796cdf2a81b9b8.tar.bz2
* Add basic (untested) code for handling undo/redo in gMathView
-rw-r--r--gmathview/CMakeLists.txt6
-rw-r--r--gmathview/gmathview.c19
-rw-r--r--gmathview/gmathview_internal.h17
-rw-r--r--gmathview/gmathview_mod_stack.c211
-rw-r--r--gmathview/gmathview_mod_stack.h68
-rw-r--r--include/gmathview.h25
6 files changed, 330 insertions, 16 deletions
diff --git a/gmathview/CMakeLists.txt b/gmathview/CMakeLists.txt
index 5501def..9b8737f 100644
--- a/gmathview/CMakeLists.txt
+++ b/gmathview/CMakeLists.txt
@@ -9,7 +9,11 @@ link_directories (
${GTK_LINK_DIRS}
)
-add_library (gmathview SHARED gmathview.c gmathview_utils.c)
+add_library (
+ gmathview SHARED gmathview.c
+ gmathview_mod_stack.c
+ gmathview_utils.c
+)
target_link_libraries (
gmathview ${GLIB_LIBRARIES} ${GTK_LIBRARIES} gmathcairo
)
diff --git a/gmathview/gmathview.c b/gmathview/gmathview.c
index 84375cf..ccea3a5 100644
--- a/gmathview/gmathview.c
+++ b/gmathview/gmathview.c
@@ -26,11 +26,28 @@
#include <gmathview.h>
#include "gmathview_internal.h"
+#include "gmathview_mod_stack.h"
#include <gdk/gdkkeysyms.h>
G_DEFINE_TYPE (GMathView, g_math_view, GTK_TYPE_DRAWING_AREA)
static void
+g_math_view_force_redraw (GMathView *mathview);
+
+static gboolean
+g_math_view_do_expose (GtkWidget *widget, GdkEventExpose *event);
+
+static gboolean
+g_math_view_do_destroy (GtkWidget *widget, GdkEventAny *event);
+
+static gboolean
+g_math_view_on_key_press (GtkWidget *widget, GdkEventKey *event);
+
+static gboolean
+g_math_view_on_button_press (GtkWidget *widget, GdkEventButton *event);
+
+
+static void
g_math_view_class_init (GMathViewClass *class)
{
GObjectClass *object_class;
@@ -63,6 +80,8 @@ g_math_view_init (GMathView *mathview)
priv->current_boxed = NULL;
priv->selection_type = GMathSelectionNone;
+ priv->mod_stack = NULL;
+
gtk_widget_add_events (GTK_WIDGET (mathview),
GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK);
diff --git a/gmathview/gmathview_internal.h b/gmathview/gmathview_internal.h
index 0788fb8..054a5db 100644
--- a/gmathview/gmathview_internal.h
+++ b/gmathview/gmathview_internal.h
@@ -43,21 +43,8 @@ struct _GMathViewPrivate
GMathBoxed *current_boxed;
GMathSelectionType selection_type;
-};
-
-static void
-g_math_view_force_redraw (GMathView *mathview);
-
-static gboolean
-g_math_view_do_expose (GtkWidget *widget, GdkEventExpose *event);
-static gboolean
-g_math_view_do_destroy (GtkWidget *widget, GdkEventAny *event);
-
-static gboolean
-g_math_view_on_key_press (GtkWidget *widget, GdkEventKey *event);
-
-static gboolean
-g_math_view_on_button_press (GtkWidget *widget, GdkEventButton *event);
+ GList *mod_stack;
+};
#endif
diff --git a/gmathview/gmathview_mod_stack.c b/gmathview/gmathview_mod_stack.c
new file mode 100644
index 0000000..31e5091
--- /dev/null
+++ b/gmathview/gmathview_mod_stack.c
@@ -0,0 +1,211 @@
+/*
+ * gMathView, mathematic expressions viewing & editing widget
+ *
+ * # Modification stack source
+ *
+ * Author : Guillaume Seguin
+ * Email : guillaume@segu.in
+ *
+ * Copyright (c) 2007 Guillaume Seguin <guillaume@segu.in>
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gmathview.h>
+#include "gmathview_internal.h"
+#include "gmathview_mod_stack.h"
+
+static GMathMod*
+gmathmod_new (GMathModType type);
+
+static void
+g_math_view_push_to_mod_stack (GMathView *mathview, GMathMod *mod);
+
+static void
+g_math_view_destroy_mod_stack (GList *stack);
+
+void
+g_math_view_undo (GMathView *mathview)
+{
+ GMathViewPrivate *priv;
+ GMathMod *mod;
+
+ priv = G_MATH_VIEW_GET_PRIVATE (mathview);
+
+ if (!priv->mod_stack || !priv->mod_stack->data)
+ return;
+
+ mod = (GMathMod *) priv->mod_stack->data;
+
+ switch (mod->type)
+ {
+ case GMathModUpdateParent:
+ ((GMathSymbol *) mod->data1)->parent = mod->data2;
+ break;
+ case GMathModUpdateValue:
+ ((GMathSymbol *) mod->data1)->value = mod->data2;
+ break;
+ case GMathModUpdateRoot:
+ priv->formula->root = ((GMathSymbol *) mod->data1);
+ break;
+ }
+
+ priv->mod_stack = priv->mod_stack->next;
+}
+
+void
+g_math_view_redo (GMathView *mathview)
+{
+ GMathViewPrivate *priv;
+ GMathMod *mod;
+
+ priv = G_MATH_VIEW_GET_PRIVATE (mathview);
+
+ if (!priv->mod_stack || !priv->mod_stack->prev)
+ return;
+
+ mod = (GMathMod *) priv->mod_stack->prev->data;
+
+ if (!mod)
+ return;
+
+ switch (mod->type)
+ {
+ case GMathModUpdateParent:
+ ((GMathSymbol *) mod->data1)->parent = mod->data3;
+ break;
+ case GMathModUpdateValue:
+ ((GMathSymbol *) mod->data1)->value = mod->data3;
+ break;
+ case GMathModUpdateRoot:
+ priv->formula->root = ((GMathSymbol *) mod->data2);
+ break;
+ }
+
+ priv->mod_stack = priv->mod_stack->prev;
+}
+
+gboolean
+g_math_view_can_undo (GMathView *mathview)
+{
+ GMathViewPrivate *priv;
+
+ priv = G_MATH_VIEW_GET_PRIVATE (mathview);
+
+ return (priv->mod_stack && priv->mod_stack->data);
+}
+
+gboolean
+g_math_view_can_redo (GMathView *mathview)
+{
+ GMathViewPrivate *priv;
+
+ priv = G_MATH_VIEW_GET_PRIVATE (mathview);
+
+ return (priv->mod_stack && priv->mod_stack->prev);
+}
+
+void
+g_math_view_update_parent (GMathView *mathview, GMathSymbol *symbol,
+ GMathSymbol *new_parent)
+{
+ GMathMod *mod;
+
+ mod = gmathmod_new (GMathModUpdateParent);
+
+ mod->data1 = (gpointer) symbol;
+ mod->data2 = (gpointer) symbol->parent;
+ mod->data3 = (gpointer) new_parent;
+
+ symbol->parent = new_parent;
+
+ g_math_view_push_to_mod_stack (mathview, mod);
+}
+
+void
+g_math_view_update_value (GMathView *mathview, GMathSymbol *symbol,
+ gpointer new_value)
+{
+ GMathMod *mod;
+
+ mod = gmathmod_new (GMathModUpdateParent);
+
+ mod->data1 = (gpointer) symbol;
+ mod->data2 = (gpointer) symbol->value;
+ mod->data3 = (gpointer) new_value;
+
+ symbol->value = new_value;
+
+ g_math_view_push_to_mod_stack (mathview, mod);
+}
+
+void
+g_math_view_update_root (GMathView *mathview, GMathSymbol *new_root)
+{
+ GMathMod *mod;
+ GMathViewPrivate *priv;
+
+ priv = G_MATH_VIEW_GET_PRIVATE (mathview);
+ mod = gmathmod_new (GMathModUpdateRoot);
+
+ mod->data1 = (gpointer) priv->formula->root;
+ mod->data2 = (gpointer) new_root;
+
+ priv->formula->root = new_root;
+
+ g_math_view_push_to_mod_stack (mathview, mod);
+}
+
+static GMathMod*
+gmathmod_new (GMathModType type)
+{
+ GMathMod *mod = g_new0 (GMathMod, 1);
+ mod->type = type;
+ return mod;
+}
+
+static void
+g_math_view_push_to_mod_stack (GMathView *mathview, GMathMod *mod)
+{
+ GMathViewPrivate *priv;
+ GList *stack;
+
+ priv = G_MATH_VIEW_GET_PRIVATE (mathview);
+
+ if (!priv->mod_stack || !priv->mod_stack->prev)
+ {
+ priv->mod_stack = g_list_prepend (priv->mod_stack, mod);
+ return;
+ }
+
+ stack = priv->mod_stack->prev;
+ priv->mod_stack->prev = NULL;
+ stack->next = NULL;
+ priv->mod_stack = g_list_prepend (priv->mod_stack, mod);
+
+ g_math_view_destroy_mod_stack (g_list_first (stack));
+}
+
+static void
+g_math_view_destroy_mod_stack (GList *stack)
+{
+ if (!stack)
+ return;
+
+ stack = g_list_remove (stack, stack->data);
+
+ g_math_view_destroy_mod_stack (stack);
+}
diff --git a/gmathview/gmathview_mod_stack.h b/gmathview/gmathview_mod_stack.h
new file mode 100644
index 0000000..7871260
--- /dev/null
+++ b/gmathview/gmathview_mod_stack.h
@@ -0,0 +1,68 @@
+/*
+ * gMathView, mathematic expressions viewing & editing widget
+ *
+ * # Modifications stack header
+ *
+ * Author : Guillaume Seguin
+ * Email : guillaume@segu.in
+ *
+ * Copyright (c) 2007 Guillaume Seguin <guillaume@segu.in>
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _GMATHVIEW_MODSTACK_H
+#define _GMATHVIEW_MODSTACK_H
+
+#include <gmathview.h>
+
+typedef struct _GMathMod GMathMod;
+
+typedef enum
+{
+ GMathModUpdateParent,
+ GMathModUpdateValue,
+ GMathModUpdateRoot,
+} GMathModType;
+
+struct _GMathMod
+{
+ GMathModType type;
+ gpointer data1;
+ gpointer data2;
+ gpointer data3;
+};
+
+/*
+ * Meaning of data* pointers for each modification type:
+ *
+ * UpdateParent:
+ * o data1: symbol
+ * o data2: old parent
+ * o data3: new parent
+ *
+ * UpdateParent:
+ * o data1: symbol
+ * o data2: old value
+ * o data3: new value
+ *
+ * UpdateRoot:
+ * o data1: old root
+ * o data2: new root
+ * o data3: none
+ */
+
+#endif
diff --git a/include/gmathview.h b/include/gmathview.h
index 03ec875..ca9c59a 100644
--- a/include/gmathview.h
+++ b/include/gmathview.h
@@ -88,12 +88,37 @@ g_math_view_get_formula (GMathView *mathview);
void
g_math_view_set_formula (GMathView *mathview, GMathFormula *formula);
+/* Editor methods */
+
gboolean
g_math_view_get_editor_mode (GMathView *mathview);
void
g_math_view_set_editor_mode (GMathView *mathview, gboolean editor_mode);
+void
+g_math_view_undo (GMathView *mathview);
+
+void
+g_math_view_redo (GMathView *mathview);
+
+gboolean
+g_math_view_can_undo (GMathView *mathview);
+
+gboolean
+g_math_view_can_redo (GMathView *mathview);
+
+void
+g_math_view_update_parent (GMathView *mathview, GMathSymbol *symbol,
+ GMathSymbol *new_parent);
+
+void
+g_math_view_update_value (GMathView *mathview, GMathSymbol *symbol,
+ gpointer new_value);
+
+void
+g_math_view_update_root (GMathView *mathview, GMathSymbol *new_root);
+
G_END_DECLS
/* Helper functions */