[xiph-commits] r12236 - trunk/sushivision
xiphmont at svn.xiph.org
xiphmont at svn.xiph.org
Sun Dec 24 14:18:50 PST 2006
Author: xiphmont
Date: 2006-12-24 14:18:49 -0800 (Sun, 24 Dec 2006)
New Revision: 12236
Added:
trunk/sushivision/undo.c
Log:
Add undo module
Added: trunk/sushivision/undo.c
===================================================================
--- trunk/sushivision/undo.c 2006-12-24 22:18:10 UTC (rev 12235)
+++ trunk/sushivision/undo.c 2006-12-24 22:18:49 UTC (rev 12236)
@@ -0,0 +1,140 @@
+/*
+ *
+ * sushivision copyright (C) 2006 Monty <monty at xiph.org>
+ *
+ * sushivision 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, or (at your option)
+ * any later version.
+ *
+ * sushivision 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 sushivision; see the file COPYING. If not, write to the
+ * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ */
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "internal.h"
+
+/* encapsulates some amount of common undo/redo infrastructure */
+
+void _sushiv_panel_undo_suspend(sushiv_panel_t *p){
+ p->private->undo_suspend++;
+}
+
+void _sushiv_panel_undo_resume(sushiv_panel_t *p){
+ p->private->undo_suspend--;
+ if(p->private->undo_suspend<0){
+ fprintf(stderr,"Internal error: undo suspend refcount count < 0\n");
+ p->private->undo_suspend=0;
+ }
+
+ if(p->private->undo_suspend==0)
+ _sushiv_panel_undo_log(p);
+}
+
+void _sushiv_panel_undo_log(sushiv_panel_t *p){
+ sushiv_panel_undo_t *u;
+
+ if(!p->private->undo_stack)
+ p->private->undo_stack = calloc(2,sizeof(*p->private->undo_stack));
+
+ // alloc new undo
+ u = p->private->undo_stack[p->private->undo_level];
+ if(!u)
+ u = p->private->undo_stack[p->private->undo_level]= calloc(1,sizeof(*u));
+
+ // pass off actual populaiton to panel subtype
+ u->p = p;
+ p->private->undo_log(u);
+}
+
+void _sushiv_panel_undo_restore(sushiv_panel_t *p){
+ sushiv_panel_undo_t *u = p->private->undo_stack[p->private->undo_level];
+ int remap_flag=0;
+ int recomp_flag=0;
+
+ p->private->undo_restore(u, &remap_flag, &recomp_flag);
+
+ if(recomp_flag)
+ p->private->request_compute(p);
+ else if(remap_flag)
+ p->private->map_redraw(p);
+ else
+ plot_expose_request(PLOT(p->private->graph));
+}
+
+void _sushiv_panel_undo_push(sushiv_panel_t *p){
+ sushiv_panel_undo_t *u;
+ int i;
+
+ if(p->private->undo_suspend)return;
+
+ _sushiv_panel_undo_log(p);
+
+ if(p->private->undo_stack[p->private->undo_level+1]){
+ /* pop levels above this one */
+ i=p->private->undo_level+1;
+ while(p->private->undo_stack[i]){
+ u = p->private->undo_stack[i];
+ if(u->mappings) free(u->mappings);
+ if(u->scale_vals[0]) free(u->scale_vals[0]);
+ if(u->scale_vals[1]) free(u->scale_vals[1]);
+ if(u->scale_vals[2]) free(u->scale_vals[2]);
+ if(u->obj_vals[0]) free(u->obj_vals[0]);
+ if(u->obj_vals[1]) free(u->obj_vals[1]);
+ if(u->obj_vals[2]) free(u->obj_vals[2]);
+ if(u->dim_vals[0]) free(u->dim_vals[0]);
+ if(u->dim_vals[1]) free(u->dim_vals[1]);
+ if(u->dim_vals[2]) free(u->dim_vals[2]);
+ free(u);
+ p->private->undo_stack[i]= NULL;
+ i++;
+ }
+ }
+
+ // realloc stack
+ p->private->undo_stack = realloc(p->private->undo_stack,(p->private->undo_level+3)*sizeof(*p->private->undo_stack));
+ p->private->undo_level++;
+ p->private->undo_stack[p->private->undo_level]=0;
+ p->private->undo_stack[p->private->undo_level+1]=0;
+ p->private->update_menus(p);
+
+}
+
+void _sushiv_panel_undo_up(sushiv_panel_t *p){
+
+ if(!p->private->undo_stack)return;
+ if(!p->private->undo_stack[p->private->undo_level])return;
+ if(!p->private->undo_stack[p->private->undo_level+1])return;
+
+ p->private->undo_level++;
+ _sushiv_panel_undo_suspend(p);
+ _sushiv_panel_undo_restore(p);
+ _sushiv_panel_undo_resume(p);
+ p->private->update_menus(p);
+}
+
+void _sushiv_panel_undo_down(sushiv_panel_t *p){
+
+ if(!p->private->undo_stack)return;
+ if(!p->private->undo_level)return;
+
+ _sushiv_panel_undo_log(p);
+ p->private->undo_level--;
+
+ _sushiv_panel_undo_suspend(p);
+ _sushiv_panel_undo_restore(p);
+ _sushiv_panel_undo_resume(p);
+ p->private->update_menus(p);
+}
More information about the commits
mailing list