diff options
author | Guillaume Seguin <guillaume@segu.in> | 2007-12-08 20:00:58 +0100 |
---|---|---|
committer | Guillaume Seguin <guillaume@segu.in> | 2007-12-08 20:00:58 +0100 |
commit | a495aa8e353e7de43d19a699c5796cdf2a81b9b8 (patch) | |
tree | 0dd803f98099d941a1479c19814b83b74f51e8a8 | |
parent | 16ca2d8d6b7c620d0d9d7d553d2b81dc861a86ea (diff) | |
download | gmathlib-a495aa8e353e7de43d19a699c5796cdf2a81b9b8.tar.gz gmathlib-a495aa8e353e7de43d19a699c5796cdf2a81b9b8.tar.bz2 |
* Add basic (untested) code for handling undo/redo in gMathView
-rw-r--r-- | gmathview/CMakeLists.txt | 6 | ||||
-rw-r--r-- | gmathview/gmathview.c | 19 | ||||
-rw-r--r-- | gmathview/gmathview_internal.h | 17 | ||||
-rw-r--r-- | gmathview/gmathview_mod_stack.c | 211 | ||||
-rw-r--r-- | gmathview/gmathview_mod_stack.h | 68 | ||||
-rw-r--r-- | include/gmathview.h | 25 |
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 */ |