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