r5387 - trunk/eda/fped

werner at docs.openmoko.org werner at docs.openmoko.org
Wed Aug 5 02:32:39 CEST 2009


Author: werner
Date: 2009-08-05 02:32:38 +0200 (Wed, 05 Aug 2009)
New Revision: 5387

Added:
   trunk/eda/fped/delete.c
   trunk/eda/fped/delete.h
Modified:
   trunk/eda/fped/Makefile
   trunk/eda/fped/README
   trunk/eda/fped/TODO
   trunk/eda/fped/fpd.y
   trunk/eda/fped/gui_canvas.c
   trunk/eda/fped/inst.c
   trunk/eda/fped/inst.h
   trunk/eda/fped/obj.c
   trunk/eda/fped/obj.h
Log:
Added delete/undelete.

- when moving a point, we no longer restrict the area around the original
  position once the drag radius has been left
- objects can now be deleted by selecting them and pressing Delete
- deleted objects can be restored by pressing "u"



Modified: trunk/eda/fped/Makefile
===================================================================
--- trunk/eda/fped/Makefile	2009-08-04 21:45:33 UTC (rev 5386)
+++ trunk/eda/fped/Makefile	2009-08-05 00:32:38 UTC (rev 5387)
@@ -10,7 +10,7 @@
 # (at your option) any later version.
 #
 
-OBJS = fped.o expr.o coord.o obj.o inst.o util.o error.o \
+OBJS = fped.o expr.o coord.o obj.o delete.o inst.o util.o error.o \
        unparse.o \
        cpp.o lex.yy.o y.tab.o \
        gui.o gui_util.o gui_style.o gui_inst.o gui_status.o gui_canvas.o \

Modified: trunk/eda/fped/README
===================================================================
--- trunk/eda/fped/README	2009-08-04 21:45:33 UTC (rev 5386)
+++ trunk/eda/fped/README	2009-08-05 00:32:38 UTC (rev 5387)
@@ -348,9 +348,11 @@
 
 Keys:
 
-space	reset user coordinates
+Space	reset user coordinates
 +, =	zoom in (like mouse wheel forward)
 -	zoom out (like mouse wheel backward)
 .	cursor position to screen center (like middle click)
 *	zoom and center to extents
 #	zoom and center to currently active frame instance
+Delete	delete the currently selected object
+U	undelete the previously deleted object

Modified: trunk/eda/fped/TODO
===================================================================
--- trunk/eda/fped/TODO	2009-08-04 21:45:33 UTC (rev 5386)
+++ trunk/eda/fped/TODO	2009-08-05 00:32:38 UTC (rev 5387)
@@ -19,6 +19,7 @@
 Bugs:
 - default silk width has no business being hard-coded in obj.c
 - after moving, arc sometimes wrap the wrong way
+- undelete only works if not much has changed since the deletion
 
 Code cleanup:
 - merge edit_unique with edit_name
@@ -26,7 +27,6 @@
 - add regression tests
 
 Open decisions:
-- decide on table presentation (merge frame and vars into single entity ?)
 - Q: should loop be (start, last) or (start, iterations) ? or start ... last ?
 - change vector circle color ? (also, highlight on hover ?)
 - Q: allow reassignment of vector names ?

Added: trunk/eda/fped/delete.c
===================================================================
--- trunk/eda/fped/delete.c	                        (rev 0)
+++ trunk/eda/fped/delete.c	2009-08-05 00:32:38 UTC (rev 5387)
@@ -0,0 +1,286 @@
+/*
+ * delete.c - Object deletion
+ *
+ * Written 2009 by Werner Almesberger
+ * Copyright 2009 by Werner Almesberger
+ *
+ * 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.
+ */
+
+
+#include <stdlib.h>
+#include <assert.h>
+
+#include "util.h"
+#include "error.h"
+#include "expr.h"
+#include "obj.h"
+#include "delete.h"
+
+
+static struct deletion {
+	enum del_type {
+		dt_vec,
+		dt_obj,
+	} type;
+	union {
+		struct {
+			struct vec *ref;
+			struct vec *prev;
+		} vec;
+		struct {
+			struct obj *ref;
+			struct obj *prev;
+		} obj;
+	} u;
+	struct deletion *next;
+} *deletions = NULL;
+
+
+static struct deletion *new_deletion(enum del_type type)
+{
+	struct deletion *del;
+
+	del = alloc_type(struct deletion);
+	del->type = type;
+	del->next = deletions;
+	deletions = del;
+	return del;
+}
+
+
+/* ----- vectors ----------------------------------------------------------- */
+
+
+static void dereference_vec(struct vec *vec)
+{
+	assert(!vec->n_refs);
+	put_vec(vec->base);
+}
+
+
+static void destroy_vec(struct vec *vec)
+{
+	assert(!vec->n_refs);
+	free_expr(vec->x);
+	free_expr(vec->y);
+	free(vec);
+}
+
+
+static void rereference_vec(struct vec *vec)
+{
+	get_vec(vec->base);
+}
+
+
+int delete_vec(struct vec *vec)
+{
+	struct vec *walk, *prev;
+	struct deletion *del;
+
+	if (vec->n_refs) {
+		fail("vector has %d reference%s", vec->n_refs,
+		    vec->n_refs == 1 ? "" : "s");
+		return 0;
+	}
+	prev = NULL;
+	for (walk = vec->frame->vecs; walk != vec; walk = walk->next)
+		prev = walk;
+	if (prev)
+		prev->next = vec->next;
+	else
+		vec->frame->vecs = vec->next;
+	dereference_vec(vec);
+	del = new_deletion(dt_vec);
+	del->u.vec.ref = vec;
+	del->u.vec.prev = prev;
+	return 1;
+}
+
+
+static void undelete_vec(struct vec *vec, struct vec *prev)
+{
+	if (prev) {
+		assert(vec->next == prev->next);
+		prev->next = vec;
+	} else {
+		assert(vec->next == vec->frame->vecs);
+		vec->frame->vecs = vec;
+	}
+	rereference_vec(vec);
+}
+
+
+/* ----- objects ----------------------------------------------------------- */
+
+
+static void dereference_obj(struct obj *obj)
+{
+	switch (obj->type) {
+	case ot_frame:
+		/* nothing */
+		break;
+	case ot_pad:
+		put_vec(obj->u.pad.other);
+		break;
+	case ot_line:
+		put_vec(obj->u.line.other);
+		break;
+	case ot_rect:
+		put_vec(obj->u.rect.other);
+		break;
+	case ot_arc:
+		put_vec(obj->u.arc.start);
+		put_vec(obj->u.arc.end);
+		break;
+	case ot_meas:
+		put_vec(obj->u.meas.other);
+		break;
+	default:
+		abort();
+	}
+	put_vec(obj->base);
+}
+
+
+static void destroy_obj(struct obj *obj)
+{
+	switch (obj->type) {
+	case ot_frame:
+		/* nothing */
+		break;
+	case ot_pad:
+		free(obj->u.pad.name);
+		break;
+	case ot_line:
+		free_expr(obj->u.line.width);
+		break;
+	case ot_rect:
+		free_expr(obj->u.rect.width);
+		break;
+	case ot_arc:
+		free_expr(obj->u.arc.width);
+		break;
+	case ot_meas:
+		free_expr(obj->u.meas.offset);
+		break;
+	default:
+		abort();
+	}
+	free(obj);
+}
+
+
+static void rereference_obj(struct obj *obj)
+{
+	switch (obj->type) {
+	case ot_frame:
+		/* nothing */
+		break;
+	case ot_pad:
+		get_vec(obj->u.pad.other);
+		break;
+	case ot_line:
+		get_vec(obj->u.line.other);
+		break;
+	case ot_rect:
+		get_vec(obj->u.rect.other);
+		break;
+	case ot_arc:
+		get_vec(obj->u.arc.start);
+		get_vec(obj->u.arc.end);
+		break;
+	case ot_meas:
+		get_vec(obj->u.meas.other);
+		break;
+	default:
+		abort();
+	}
+	get_vec(obj->base);
+}
+
+
+int delete_obj(struct obj *obj)
+{
+	struct obj *walk, *prev;
+	struct deletion *del;
+
+	prev = NULL;
+	for (walk = obj->frame->objs; walk != obj; walk = walk->next)
+		prev = walk;
+	if (prev)
+		prev->next = obj->next;
+	else
+		obj->frame->objs = obj->next;
+	dereference_obj(obj);
+	del = new_deletion(dt_obj);
+	del->u.obj.ref = obj;
+	del->u.obj.prev = prev;
+	return 1;
+}
+
+
+static void undelete_obj(struct obj *obj, struct obj *prev)
+{
+	if (prev) {
+		assert(obj->next == prev->next);
+		prev->next = obj;
+	} else {
+		assert(obj->next == obj->frame->objs);
+		obj->frame->objs = obj;
+	}
+	rereference_obj(obj);
+}
+
+
+/* ----- destroy/undelete interface ---------------------------------------- */
+
+
+int destroy(void)
+{
+	struct deletion *del;
+
+	if (!deletions)
+		return 0;
+	del = deletions;
+	switch (del->type) {
+	case dt_vec:
+		destroy_vec(del->u.vec.ref);
+		break;
+	case dt_obj:
+		destroy_obj(del->u.obj.ref);
+		break;
+	default:
+		abort();
+	}
+	deletions = del->next;
+	free(del);
+	return 1;
+}
+
+
+int undelete(void)
+{
+	struct deletion *del;
+
+	if (!deletions)
+		return 0;
+	del = deletions;
+	switch (del->type) {
+	case dt_vec:
+		undelete_vec(del->u.vec.ref, del->u.vec.prev);
+		break;
+	case dt_obj:
+		undelete_obj(del->u.obj.ref, del->u.obj.prev);
+		break;
+	default:
+		abort();
+	}
+	deletions = del->next;
+	free(del);
+	return 1;
+}

Added: trunk/eda/fped/delete.h
===================================================================
--- trunk/eda/fped/delete.h	                        (rev 0)
+++ trunk/eda/fped/delete.h	2009-08-05 00:32:38 UTC (rev 5387)
@@ -0,0 +1,26 @@
+/*
+ * delete.h - Object deletion
+ *
+ * Written 2009 by Werner Almesberger
+ * Copyright 2009 by Werner Almesberger
+ *
+ * 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.
+ */
+
+
+#ifndef DELETE_H
+#define DELETE_H
+
+
+#include "obj.h"
+
+
+int delete_vec(struct vec *vec);
+int delete_obj(struct obj *obj);
+int destroy(void);
+int undelete(void);
+
+#endif /* !OBJ_H */

Modified: trunk/eda/fped/fpd.y
===================================================================
--- trunk/eda/fped/fpd.y	2009-08-04 21:45:33 UTC (rev 5386)
+++ trunk/eda/fped/fpd.y	2009-08-05 00:32:38 UTC (rev 5387)
@@ -117,6 +117,7 @@
 
 	obj = alloc_type(struct obj);
 	obj->type = type;
+	obj->frame = curr_frame;
 	obj->next = NULL;
 	return obj;
 }

Modified: trunk/eda/fped/gui_canvas.c
===================================================================
--- trunk/eda/fped/gui_canvas.c	2009-08-04 21:45:33 UTC (rev 5386)
+++ trunk/eda/fped/gui_canvas.c	2009-08-05 00:32:38 UTC (rev 5387)
@@ -13,8 +13,10 @@
 
 #include <math.h>
 #include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
 
 #include "obj.h"
+#include "delete.h"
 #include "inst.h"
 #include "gui_inst.h"
 #include "gui_style.h"
@@ -29,6 +31,7 @@
 static struct coord user_origin = { 0, 0 };
 
 static int dragging = 0;
+static int drag_escaped = 0; /* 1 once we've made is out of the drag radius */
 static struct coord drag_start;
 
 
@@ -111,9 +114,11 @@
 {
 	if (!dragging)
 		return;
-	if (hypot(pos.x-drag_start.x, pos.y-drag_start.y)/ctx.scale <
+	if (!drag_escaped &&
+	    hypot(pos.x-drag_start.x, pos.y-drag_start.y)/ctx.scale <
 	    DRAG_MIN_R)
 		return;
+	drag_escaped = 1;
 	tool_drag(&ctx, pos);
 }
 
@@ -159,6 +164,7 @@
 		}
 		if (tool_consider_drag(&ctx, pos)) {
 			dragging = 1;
+			drag_escaped = 0;
 			drag_start = pos;
 			break;
 		}
@@ -283,6 +289,16 @@
 		ctx.center = pos;
 		redraw();
 		break;
+	case GDK_BackSpace:
+	case GDK_Delete:
+	case GDK_KP_Delete:
+		if (selected_inst && inst_delete(selected_inst))
+			change_world();
+		break;
+	case 'u':
+		if (undelete())
+			change_world();
+		break;
 	}
 	return TRUE;
 }

Modified: trunk/eda/fped/inst.c
===================================================================
--- trunk/eda/fped/inst.c	2009-08-04 21:45:33 UTC (rev 5386)
+++ trunk/eda/fped/inst.c	2009-08-05 00:32:38 UTC (rev 5387)
@@ -19,6 +19,7 @@
 #include "coord.h"
 #include "expr.h"
 #include "obj.h"
+#include "delete.h"
 #include "gui_status.h"
 #include "gui_tools.h"
 #include "gui_inst.h"
@@ -740,12 +741,13 @@
 };
 
 
-void inst_begin_frame(const struct frame *frame, struct coord base,
-    int active, int is_active_frame)
+void inst_begin_frame(struct obj *obj, const struct frame *frame,
+    struct coord base, int active, int is_active_frame)
 {
 	struct inst *inst;
 
 	inst = add_inst(&frame_ops, ip_frame, base);
+	inst->obj = obj;
 	inst->u.frame.ref = frame;
 	inst->u.frame.active = is_active_frame;
 	inst->active = active;
@@ -865,6 +867,13 @@
 }
 
 
+int inst_delete(struct inst *inst)
+{
+	return inst->ops == &vec_ops ?
+	    delete_vec(inst->vec) : delete_obj(inst->obj);
+}
+
+
 void inst_debug(void)
 {
 	enum inst_prio prio;

Modified: trunk/eda/fped/inst.h
===================================================================
--- trunk/eda/fped/inst.h	2009-08-04 21:45:33 UTC (rev 5386)
+++ trunk/eda/fped/inst.h	2009-08-05 00:32:38 UTC (rev 5387)
@@ -102,8 +102,8 @@
 void inst_begin_active(int active);
 void inst_end_active(void);
 
-void inst_begin_frame(const struct frame *frame, struct coord base,
-    int active, int is_active_frame);
+void inst_begin_frame(struct obj *obj, const struct frame *frame,
+    struct coord base, int active, int is_active_frame);
 void inst_end_frame(const struct frame *frame);
 
 struct bbox inst_get_bbox(void);
@@ -117,6 +117,7 @@
     struct coord pos, int i);
 int inst_do_move_to(struct inst *inst, struct vec *vec, int i);
 void inst_hover(struct inst *inst, struct draw_ctx *ctx, int on);
+int inst_delete(struct inst *inst);
 void inst_debug(void);
 
 #endif /* !INST_H */

Modified: trunk/eda/fped/obj.c
===================================================================
--- trunk/eda/fped/obj.c	2009-08-04 21:45:33 UTC (rev 5386)
+++ trunk/eda/fped/obj.c	2009-08-05 00:32:38 UTC (rev 5387)
@@ -33,7 +33,7 @@
 
 
 static int generate_frame(struct frame *frame, struct coord base,
-    const struct frame *parent, int active);
+    const struct frame *parent, struct obj *frame_ref, int active);
 
 
 static struct num eval_unit(const struct expr *expr, const struct frame *frame)
@@ -93,7 +93,7 @@
 		switch (obj->type) {
 		case ot_frame:
 			if (!generate_frame(obj->u.frame.ref,
-			    obj->base ? obj->base->pos : base, frame,
+			    obj->base ? obj->base->pos : base, frame, obj,
 			    active && obj->u.frame.ref->active_ref == obj))
 				return 0;
 			break;
@@ -237,14 +237,14 @@
 
 
 static int generate_frame(struct frame *frame, struct coord base,
-    const struct frame *parent, int active)
+    const struct frame *parent, struct obj *frame_ref, int active)
 {
 	int ok;
 
 	/*
 	 * We ensure during construction that frames can never recurse.
 	 */
-	inst_begin_frame(frame, base,
+	inst_begin_frame(frame_ref, frame, base,
 	    active && parent == active_frame,
 	    active && frame == active_frame);
 	frame->curr_parent = parent;
@@ -260,7 +260,7 @@
 	int ok;
 
 	inst_start();
-	ok = generate_frame(root_frame, zero, NULL, 1);
+	ok = generate_frame(root_frame, zero, NULL, NULL, 1);
 	if (ok)
 		inst_commit();
 	else

Modified: trunk/eda/fped/obj.h
===================================================================
--- trunk/eda/fped/obj.h	2009-08-04 21:45:33 UTC (rev 5386)
+++ trunk/eda/fped/obj.h	2009-08-05 00:32:38 UTC (rev 5387)
@@ -14,6 +14,7 @@
 #ifndef OBJ_H
 #define OBJ_H
 
+#include <assert.h>
 #include <gtk/gtk.h>
 
 #include "expr.h"
@@ -161,6 +162,7 @@
 		struct arc arc;
 		struct meas meas;
 	} u;
+	struct frame *frame;
 	struct vec *base;
 	struct obj *next;
 	int lineno;
@@ -180,6 +182,15 @@
 }
 
 
+static inline void put_vec(struct vec *vec)
+{
+	if (vec) {
+		assert(vec->n_refs);
+		vec->n_refs--;
+	}
+}
+
+
 int instantiate(void);
 
 #endif /* !OBJ_H */




More information about the commitlog mailing list