r5341 - developers/werner/fped

werner at docs.openmoko.org werner at docs.openmoko.org
Thu Jul 30 16:11:25 CEST 2009


Author: werner
Date: 2009-07-30 16:11:24 +0200 (Thu, 30 Jul 2009)
New Revision: 5341

Modified:
   developers/werner/fped/TODO
   developers/werner/fped/coord.c
   developers/werner/fped/coord.h
   developers/werner/fped/fpd.y
   developers/werner/fped/gui_canvas.c
   developers/werner/fped/gui_inst.c
   developers/werner/fped/gui_inst.h
   developers/werner/fped/gui_style.c
   developers/werner/fped/gui_style.h
   developers/werner/fped/inst.c
   developers/werner/fped/inst.h
   developers/werner/fped/obj.c
   developers/werner/fped/obj.h
   developers/werner/fped/qfn.fpd
Log:
- added limit for loop iterations
- added structures for marking active instances 
- added selection and the corresponding markup (on-going)
- lines were drawn with the wrong y0 coordinate
- reorganized gui_style and changed color scheme
- changed qfp.fpd to generate objects only once



Modified: developers/werner/fped/TODO
===================================================================
--- developers/werner/fped/TODO	2009-07-29 22:27:00 UTC (rev 5340)
+++ developers/werner/fped/TODO	2009-07-30 14:11:24 UTC (rev 5341)
@@ -24,3 +24,5 @@
 - add postscript output
 - add option to include/omit helper vecs and frames (display and postscript)
 - Q: how do we handle stacks of objects ?
+- consider using cairo instead of gdk
+- Q: add frame arguments ? (e.g., .frame pad(pin_num_offset) ...)

Modified: developers/werner/fped/coord.c
===================================================================
--- developers/werner/fped/coord.c	2009-07-29 22:27:00 UTC (rev 5340)
+++ developers/werner/fped/coord.c	2009-07-30 14:11:24 UTC (rev 5341)
@@ -77,3 +77,88 @@
 	v.y = -v.y;
 	return v;
 }
+
+
+/* ----- distance calculations --------------------------------------------- */
+
+
+unit_type dist_point(struct coord a, struct coord b)
+{
+	return hypot(a.x-b.x, a.y-b.y);
+}
+
+#include <stdio.h>
+static unit_type dist_line_xy(unit_type px, unit_type py,
+    unit_type ax, unit_type ay, unit_type bx, unit_type by)
+{
+	unit_type d_min, d;
+	double a, f;
+
+	d_min = hypot(ax-px, ay-py);
+	d = hypot(bx-px, by-py);
+	if (d < d_min)
+		d_min = d;
+	if (ax != bx || ay != by) {
+		/*
+		 * We make a the line vector from point B and b the vector from
+		 * B to point P. The we calculate the projection of b on a.
+		 */
+		ax -= bx;
+		ay -= by;
+		bx = px-bx;
+		by = py-by;
+		a = hypot(ax, ay);
+		f = (ax*bx+ay*by)/a/a;
+		if (f >= 0 && f <= 1) {
+			bx -= f*ax;
+			by -= f*ay;
+			d = hypot(bx, by);
+			if (d < d_min)
+				d_min = d;
+		}
+	}
+	return d_min;
+}
+
+
+unit_type dist_line(struct coord p, struct coord a, struct coord b)
+{
+	return dist_line_xy(p.x, p.y, a.x, a.y, b.x, b.y);
+}
+
+
+unit_type dist_rect(struct coord p, struct coord min, struct coord max)
+{
+	unit_type d_min, d;
+
+	d_min = dist_line_xy(p.x, p.y, min.x, min.y, max.x, min.y);
+	d = dist_line_xy(p.x, p.y, min.x, min.y, min.x, max.y);
+	if (d < d_min)
+		d_min = d;
+	d = dist_line_xy(p.x, p.y, min.x, max.y, max.x, max.y);
+	if (d < d_min)
+		d_min = d;
+	d = dist_line_xy(p.x, p.y, max.x, min.y, max.x, max.y);
+	if (d < d_min)
+		d_min = d;
+	return d_min;
+}
+
+
+int inside_rect(struct coord p, struct coord min, struct coord max)
+{
+	if (p.x < min.x || p.x > max.x)
+		return 0;
+	if (p.y < min.y || p.y > max.y)
+		return 0;
+	return 1;
+}
+
+
+unit_type dist_circle(struct coord p, struct coord c, unit_type r)
+{
+	unit_type d;
+
+	d = hypot(p.x-c.x, p.y-c.y);
+        return fabs(d-r);
+}

Modified: developers/werner/fped/coord.h
===================================================================
--- developers/werner/fped/coord.h	2009-07-29 22:27:00 UTC (rev 5340)
+++ developers/werner/fped/coord.h	2009-07-30 14:11:24 UTC (rev 5341)
@@ -69,4 +69,10 @@
 struct coord sub_vec(struct coord a, struct coord b);
 struct coord neg_vec(struct coord v);
 
+unit_type dist_point(struct coord a, struct coord b);
+unit_type dist_line(struct coord p, struct coord a, struct coord b);
+unit_type dist_rect(struct coord p, struct coord min, struct coord max);
+int inside_rect(struct coord p, struct coord min, struct coord max);
+unit_type dist_circle(struct coord p, struct coord c, unit_type r);
+
 #endif /* !COORD_H */

Modified: developers/werner/fped/fpd.y
===================================================================
--- developers/werner/fped/fpd.y	2009-07-29 22:27:00 UTC (rev 5340)
+++ developers/werner/fped/fpd.y	2009-07-30 14:11:24 UTC (rev 5341)
@@ -87,6 +87,7 @@
 	loop->from = from;
 	loop->to = to;
 	loop->next = NULL;
+	loop->active = 0;
 	*next_loop = loop;
 	next_loop = &loop->next;
 }
@@ -217,6 +218,7 @@
 			$$ = $<table>2;
 			$$->vars = $4;
 			$$->rows = $6;
+			$$->active = 0;
 			next_table = &$$->next;
 		}
 	;

Modified: developers/werner/fped/gui_canvas.c
===================================================================
--- developers/werner/fped/gui_canvas.c	2009-07-29 22:27:00 UTC (rev 5340)
+++ developers/werner/fped/gui_canvas.c	2009-07-30 14:11:24 UTC (rev 5341)
@@ -139,7 +139,9 @@
 
 	switch (event->button) {
 	case 1:
-		/* select */ ;
+		inst_deselect();
+		if (inst_select(&ctx, pos))
+			redraw();
 		break;
 	case 2:
 		ctx.center = pos;

Modified: developers/werner/fped/gui_inst.c
===================================================================
--- developers/werner/fped/gui_inst.c	2009-07-29 22:27:00 UTC (rev 5340)
+++ developers/werner/fped/gui_inst.c	2009-07-30 14:11:24 UTC (rev 5341)
@@ -12,6 +12,7 @@
 
 
 #include <stdlib.h>
+#include <math.h>
 #include <gtk/gtk.h>
 
 #include "inst.h"
@@ -23,6 +24,9 @@
 #define DA	GDK_DRAWABLE(ctx->widget->window)
 
 
+/* ----- coordinate translation -------------------------------------------- */
+
+
 struct coord translate(const struct draw_ctx *ctx, struct coord pos)
 {
 	pos.x -= ctx->center.x;
@@ -110,42 +114,84 @@
 }
 
 
+static enum mode get_mode(struct inst *self)
+{
+	if (selected_inst == self)
+		return mode_selected;
+	if (self->active)
+		return self->in_path ? mode_active_in_path : mode_active;
+	return self->in_path ? mode_inactive_in_path : mode_inactive;
+}
+
+
 /* ----- vec --------------------------------------------------------------- */
 
 
+unit_type gui_dist_vec(struct inst *self, struct coord pos, unit_type scale)
+{
+	unit_type d;
+
+	d = dist_point(pos, self->u.end)/scale;
+	return d > VEC_EYE_R ? -1 : d;
+}
+
+
 void gui_draw_vec(struct inst *self, struct draw_ctx *ctx)
 {
 	struct coord from = translate(ctx, self->base);
 	struct coord to = translate(ctx, self->u.end);
+	GdkGC *gc;
 
-	draw_arrow(ctx, gc_vec_bg, TRUE, from, to,
-	  VEC_ARROW_LEN, VEC_ARROW_ANGLE);
-	gdk_draw_line(DA, gc_vec_bg, from.x, from.y, to.x, to.y);
-	draw_circle(ctx, gc_vec_bg, FALSE, to.x, to.y, VEC_EYE_R);
+	gc = gc_vec[get_mode(self)];
+	draw_arrow(ctx, gc, TRUE, from, to, VEC_ARROW_LEN, VEC_ARROW_ANGLE);
+	gdk_draw_line(DA, gc, from.x, from.y, to.x, to.y);
+	draw_circle(ctx, gc, FALSE, to.x, to.y, VEC_EYE_R);
 }
 
 
 /* ----- line -------------------------------------------------------------- */
 
 
+unit_type gui_dist_line(struct inst *self, struct coord pos, unit_type scale)
+{
+	unit_type d;
+
+	d = dist_line(pos, self->bbox.min, self->bbox.max)/scale;
+	return d > SELECT_R ? -1 : d+VEC_EYE_R;
+}
+
+
 void gui_draw_line(struct inst *self, struct draw_ctx *ctx)
 {
 	struct coord min = translate(ctx, self->bbox.min);
 	struct coord max = translate(ctx, self->bbox.max);
+	GdkGC *gc;
 
-	gdk_draw_line(DA, gc_line_bg, min.x, min.x, max.x, max.y);
+	gc = gc_obj[get_mode(self)];
+	gdk_draw_line(DA, gc, min.x, min.y, max.x, max.y);
 }
 
 
 /* ----- rect -------------------------------------------------------------- */
 
 
+unit_type gui_dist_rect(struct inst *self, struct coord pos, unit_type scale)
+{
+	unit_type d;
+
+	d = dist_rect(pos, self->bbox.min, self->bbox.max)/scale;
+	return d > SELECT_R ? -1 : d+VEC_EYE_R;
+}
+
+
 void gui_draw_rect(struct inst *self, struct draw_ctx *ctx)
 {
 	struct coord min = translate(ctx, self->bbox.min);
 	struct coord max = translate(ctx, self->bbox.max);
+	GdkGC *gc;
 
-	gdk_draw_rectangle(DA, gc_rect_bg, FALSE,
+	gc = gc_obj[get_mode(self)];
+	gdk_draw_rectangle(DA, gc, FALSE,
 	    min.x, max.y, max.x-min.x, min.y-max.y);
 }
 
@@ -153,13 +199,26 @@
 /* ----- pad --------------------------------------------------------------- */
 
 
+unit_type gui_dist_pad(struct inst *self, struct coord pos, unit_type scale)
+{
+	unit_type d;
+
+	if (inside_rect(pos, self->bbox.min, self->bbox.max))
+		return VEC_EYE_R;
+	d = dist_rect(pos, self->bbox.min, self->bbox.max)/scale;
+	return d > SELECT_R ? -1 : d+VEC_EYE_R;
+}
+
+
 void gui_draw_pad(struct inst *self, struct draw_ctx *ctx)
 {
 	struct coord min = translate(ctx, self->bbox.min);
 	struct coord max = translate(ctx, self->bbox.max);
+	GdkGC *gc;
 
+	gc = gc_pad[get_mode(self)];
 	/* @@@ name */
-	gdk_draw_rectangle(DA, gc_pad_bg, TRUE,
+	gdk_draw_rectangle(DA, gc, TRUE,
 	    min.x, max.y, max.x-min.x, min.y-max.y);
 }
 
@@ -167,11 +226,22 @@
 /* ----- arc --------------------------------------------------------------- */
 
 
+unit_type gui_dist_arc(struct inst *self, struct coord pos, unit_type scale)
+{
+	unit_type d;
+
+	d = dist_circle(pos, self->base, self->u.arc.r)/scale;
+	return d > SELECT_R ? -1 : d+VEC_EYE_R;
+}
+
+
 void gui_draw_arc(struct inst *self, struct draw_ctx *ctx)
 {
 	struct coord center = translate(ctx, self->base);
+	GdkGC *gc;
 
-	draw_arc(ctx, gc_arc_bg, FALSE, center.x, center.y,
+	gc = gc_obj[get_mode(self)];
+	draw_arc(ctx, gc, FALSE, center.x, center.y,
 	    self->u.arc.r/ctx->scale, self->u.arc.a1, self->u.arc.a2);
 }
 
@@ -183,15 +253,15 @@
 {
 	struct coord center = translate(ctx, self->base);
 	struct coord corner = { self->bbox.min.x, self->bbox.max.y };
+	GdkGC *gc;
 
-	draw_eye(ctx, gc_frame_bg, center, FRAME_EYE_R1, FRAME_EYE_R2);
+	gc = gc_frame[get_mode(self)];
+	draw_eye(ctx, gc, center, FRAME_EYE_R1, FRAME_EYE_R2);
 	if (!self->u.frame.ref->name)
 		return;
 	corner = translate(ctx, corner);
 	corner.x -= FRAME_CLEARANCE;
 	corner.y -= FRAME_CLEARANCE;
-	gdk_draw_line(DA, gc_frame_bg,
-	    corner.x, corner.y, corner.x+100, corner.y);
-	gdk_draw_line(DA, gc_frame_bg,
-	    corner.x, corner.y, corner.x, corner.y+20);
+	gdk_draw_line(DA, gc, corner.x, corner.y, corner.x+100, corner.y);
+	gdk_draw_line(DA, gc, corner.x, corner.y, corner.x, corner.y+20);
 }

Modified: developers/werner/fped/gui_inst.h
===================================================================
--- developers/werner/fped/gui_inst.h	2009-07-29 22:27:00 UTC (rev 5340)
+++ developers/werner/fped/gui_inst.h	2009-07-30 14:11:24 UTC (rev 5341)
@@ -30,6 +30,12 @@
 struct coord translate(const struct draw_ctx *ctx, struct coord pos);
 struct coord canvas_to_coord(const struct draw_ctx *ctx, int x, int y);
 
+unit_type gui_dist_vec(struct inst *self, struct coord pos, unit_type scale);
+unit_type gui_dist_line(struct inst *self, struct coord pos, unit_type scale);
+unit_type gui_dist_rect(struct inst *self, struct coord pos, unit_type scale);
+unit_type gui_dist_pad(struct inst *self, struct coord pos, unit_type scale);
+unit_type gui_dist_arc(struct inst *self, struct coord pos, unit_type scale);
+
 void gui_draw_vec(struct inst *self, struct draw_ctx *ctx);
 void gui_draw_line(struct inst *self, struct draw_ctx *ctx);
 void gui_draw_rect(struct inst *self, struct draw_ctx *ctx);

Modified: developers/werner/fped/gui_style.c
===================================================================
--- developers/werner/fped/gui_style.c	2009-07-29 22:27:00 UTC (rev 5340)
+++ developers/werner/fped/gui_style.c	2009-07-30 14:11:24 UTC (rev 5341)
@@ -13,36 +13,46 @@
 
 #include <gtk/gtk.h>
 
+#include "inst.h"
 #include "gui_util.h"
 #include "gui.h"
 #include "gui_style.h"
 
 
-static GdkGC *gc(const char *spec)
+#define	INVALID	"#00ffff"
+
+
+static GdkGC *gc(const char *spec, int width)
 {
 	GdkGCValues gc_values = {
 		.background = get_color("black"),
 		.foreground = get_color(spec),
+		.line_width = width,
 	};
 
 	return gdk_gc_new_with_values(root->window, &gc_values,
-	     GDK_GC_FOREGROUND | GDK_GC_BACKGROUND);
+	     GDK_GC_FOREGROUND | GDK_GC_BACKGROUND | GDK_GC_LINE_WIDTH);
 }
 
 
+static void style(GdkGC *gcs[mode_n],
+    const char *in, const char *in_path, const char *act, const char *act_path,
+    const char *sel)
+{
+	gcs[mode_inactive]		= gc(in, 1);
+	gcs[mode_inactive_in_path]	= gc(in_path, 1);
+	gcs[mode_active]		= gc(act, 1);
+	gcs[mode_active_in_path]	= gc(act_path, 1);
+	gcs[mode_selected]		= gc(sel, 2);
+}
+
+
 void gui_setup_style(GdkDrawable *drawable)
 {
-	gc_bg = gc("#000000");
-	gc_vec_bg = gc("#ffff00");
-	gc_vec_fg = gc("#ffff00");
-	gc_line_bg = gc("#ffffff");
-	gc_line_fg = gc("#ffffff");
-	gc_rect_bg = gc_line_bg;
-	gc_rect_fg = gc_line_fg;
-	gc_pad_bg = gc("#ff0000");
-	gc_pad_fg = gc("#ff0000");
-	gc_arc_bg = gc_line_bg;
-	gc_arc_fg = gc_line_fg;
-	gc_frame_bg = gc("#00ff00");
-	gc_frame_fg = gc("#00ff00");
+	gc_bg = gc("#000000", 0);
+	/*		inactive   in+path    active     act+path   selected */
+	style(gc_vec,	"#202000", "#404020", "#808040", "#c0c080", "#ffff80");
+	style(gc_obj,	"#003030", INVALID,   "#00e0e0", INVALID,   "#ffff80");
+	style(gc_pad,	"#300000", INVALID,   "#ff0000", INVALID,   "#ffff80");
+	style(gc_frame,	"#003000", "#205020", "#00ff00", INVALID,   INVALID);
 }

Modified: developers/werner/fped/gui_style.h
===================================================================
--- developers/werner/fped/gui_style.h	2009-07-29 22:27:00 UTC (rev 5340)
+++ developers/werner/fped/gui_style.h	2009-07-30 14:11:24 UTC (rev 5341)
@@ -16,7 +16,9 @@
 
 #include <gtk/gtk.h>
 
+#include "inst.h"
 
+
 #define	CANVAS_CLEARANCE	10
 
 #define	VEC_ARROW_LEN		10
@@ -27,14 +29,14 @@
 #define	FRAME_EYE_R1		3
 #define	FRAME_EYE_R2		5
 
+#define	SELECT_R		6	/* pixels within which we select */
 
+
 GdkGC *gc_bg;
-GdkGC *gc_vec_bg, *gc_vec_fg;
-GdkGC *gc_line_bg, *gc_line_fg;
-GdkGC *gc_rect_bg, *gc_rect_fg;
-GdkGC *gc_pad_bg, *gc_pad_fg;
-GdkGC *gc_arc_bg, *gc_arc_fg;
-GdkGC *gc_frame_bg, *gc_frame_fg;
+GdkGC *gc_vec[mode_n];
+GdkGC *gc_obj[mode_n];
+GdkGC *gc_pad[mode_n];
+GdkGC *gc_frame[mode_n];
 
 
 void gui_setup_style(GdkDrawable *drawable);

Modified: developers/werner/fped/inst.c
===================================================================
--- developers/werner/fped/inst.c	2009-07-29 22:27:00 UTC (rev 5340)
+++ developers/werner/fped/inst.c	2009-07-30 14:11:24 UTC (rev 5341)
@@ -24,8 +24,69 @@
 
 static struct inst *insts = NULL, **next_inst;
 struct inst *curr_frame = NULL;
+struct inst *selected_inst = NULL;
 
+static int active = 0;
 
+
+/* ----- selection --------------------------------------------------------- */
+
+
+static struct inst_ops vec_ops;
+static struct inst_ops frame_ops;
+
+
+static void set_path(int on)
+{
+	struct inst *inst;
+return;
+	if (inst->ops != &vec_ops && inst->ops != &frame_ops)
+		return;
+/* @@@ wrong */
+	for (inst = selected_inst; inst; inst = inst->outer) {
+		if (inst->ops != &vec_ops && inst->ops != &frame_ops)
+			break;
+		inst->in_path = on;
+	}
+}
+
+
+int inst_select(const struct draw_ctx *ctx, struct coord pos)
+{
+	struct inst *inst;
+	const struct inst *prev = selected_inst;
+	int best_dist, dist;
+
+	selected_inst = NULL;
+	for (inst = insts; inst; inst = inst->next) {
+		if (!inst->active || !inst->ops->distance)
+			continue;
+		dist = inst->ops->distance(inst, pos, ctx->scale);
+		if (dist >= 0 && (!selected_inst || best_dist > dist)) {
+			selected_inst = inst;
+			best_dist = dist;
+		}
+	}
+	if (selected_inst) {
+		set_path(1);
+		if (selected_inst->ops->select)
+			selected_inst->ops->select(selected_inst);
+	}
+	return prev != selected_inst;
+}
+
+
+void inst_deselect(void)
+{
+	if (selected_inst)
+		set_path(0);
+	selected_inst = NULL;
+}
+
+
+/* ----- helper functions for instance creation ---------------------------- */
+
+
 static void update_bbox(struct bbox *bbox, struct coord coord)
 {
 	if (bbox->min.x > coord.x)
@@ -45,7 +106,6 @@
 	update_bbox(&curr_frame->bbox, inst->bbox.max);
 }
 
-
 static struct inst *add_inst(const struct inst_ops *ops, struct coord base)
 {
 	struct inst *inst;
@@ -54,6 +114,8 @@
 	inst->ops = ops;
 	inst->base = inst->bbox.min = inst->bbox.max = base;
 	inst->outer = curr_frame;
+	inst->active = active;
+	inst->in_path = 0;
 	inst->next = NULL;
 	*next_inst = inst;
 	next_inst = &inst->next;
@@ -73,8 +135,9 @@
 
 
 static struct inst_ops vec_ops = {
-	.debug	= vec_op_debug,
-	.draw	= gui_draw_vec,
+	.debug		= vec_op_debug,
+	.draw		= gui_draw_vec,
+	.distance	= gui_dist_vec,
 };
 
 
@@ -103,8 +166,9 @@
 
 
 static struct inst_ops line_ops = {
-	.debug	= line_op_debug,
-	.draw	= gui_draw_line,
+	.debug		= line_op_debug,
+	.draw		= gui_draw_line,
+	.distance	= gui_dist_line,
 };
 
 
@@ -133,8 +197,9 @@
 
 
 static struct inst_ops rect_ops = {
-	.debug	= rect_op_debug,
-	.draw	= gui_draw_rect,
+	.debug		= rect_op_debug,
+	.draw		= gui_draw_rect,
+	.distance	= gui_dist_rect,
 };
 
 
@@ -163,8 +228,9 @@
 
 
 static struct inst_ops pad_ops = {
-	.debug	= pad_op_debug,
-	.draw	= gui_draw_pad,
+	.debug		= pad_op_debug,
+	.draw		= gui_draw_pad,
+	.distance	= gui_dist_pad,
 };
 
 
@@ -193,8 +259,9 @@
 
 
 static struct inst_ops arc_ops = {
-	.debug	= arc_op_debug,
-	.draw	= gui_draw_arc,
+	.debug		= arc_op_debug,
+	.draw		= gui_draw_arc,
+	.distance	= gui_dist_arc,
 };
 
 
@@ -225,6 +292,21 @@
 }
 
 
+/* ----- active instance --------------------------------------------------- */
+
+
+void inst_begin_active(void)
+{
+	active = 1;
+}
+
+
+void inst_end_active(void)
+{
+	active = 0;
+}
+
+
 /* ----- frame ------------------------------------------------------------- */
 
 

Modified: developers/werner/fped/inst.h
===================================================================
--- developers/werner/fped/inst.h	2009-07-29 22:27:00 UTC (rev 5340)
+++ developers/werner/fped/inst.h	2009-07-30 14:11:24 UTC (rev 5341)
@@ -20,6 +20,15 @@
 #include "obj.h"
 
 
+enum mode {
+	mode_inactive,		/* on inactive frame */
+	mode_inactive_in_path,	/* inactive but is in path to selected */
+	mode_active,		/* on active frame */
+	mode_active_in_path,	/* active and is in path to selected */
+	mode_selected,		/* item is selected */
+	mode_n			/* number of modes */
+};
+
 struct bbox {
 	struct coord min;
 	struct coord max;
@@ -32,15 +41,21 @@
 	void (*debug)(struct inst *self);
 	void (*save)(FILE *file, struct inst *self);
 	void (*draw)(struct inst *self, struct draw_ctx *ctx);
+	unit_type (*distance)(struct inst *self, struct coord pos, 
+            unit_type scale);
+	void (*select)(struct inst *self);
 };
 
 struct inst {
 	const struct inst_ops *ops;
 	struct coord base;
+//	struct inst *base_inst; /* frame or vector leading to this item */
 	struct bbox bbox;
 	struct vec *vec; /* undefined if not vector */
 	struct obj *obj; /* undefined if not object */
 	struct inst *outer; /* frame containing this item */
+	int active;
+	int in_path;
 	union {
 		struct {
 			const struct frame *ref;
@@ -56,6 +71,12 @@
 };
 
 
+extern struct inst *selected_inst;
+
+
+int inst_select(const struct draw_ctx *ctx, struct coord pos);
+void inst_deselect(void);
+
 int inst_vec(struct vec *vec, struct coord base);
 int inst_line(struct obj *obj, struct coord a, struct coord b);
 int inst_rect(struct obj *obj, struct coord a, struct coord b);
@@ -63,6 +84,9 @@
 int inst_arc(struct obj *obj, struct coord center, struct coord start,
     struct coord stop);
 
+void inst_begin_active(void);
+void inst_end_active(void);
+
 void inst_begin_frame(const struct frame *frame, struct coord base); 
 void inst_end_frame(const struct frame *frame);
 

Modified: developers/werner/fped/obj.c
===================================================================
--- developers/werner/fped/obj.c	2009-07-29 22:27:00 UTC (rev 5340)
+++ developers/werner/fped/obj.c	2009-07-30 14:11:24 UTC (rev 5341)
@@ -21,6 +21,11 @@
 #include "obj.h"
 
 
+#define	MAX_ITERATIONS	1000	/* abort "loop"s at this limit */
+
+#define active_frame frames
+
+
 struct frame *frames = NULL;
 
 
@@ -101,14 +106,11 @@
 }
 
 
-static int generate_objects(struct frame *frame, struct coord base)
+static int generate_vecs(struct frame *frame, struct coord base)
 {
 	struct coord vec_base;
 	struct vec *vec;
-	struct obj *obj;
 	struct num x, y;
-	char *name;
-	int res;
 
 	for (vec = frame->vecs; vec; vec = vec->next) {
 		x = eval_num(vec->x, frame);
@@ -128,6 +130,16 @@
 		if (!inst_vec(vec, vec_base))
 			return 0;
 	}
+	return 1;
+}
+
+
+static int generate_objs(struct frame *frame, struct coord base)
+{
+	struct obj *obj;
+	char *name;
+	int res;
+
 	for (obj = frame->objs; obj; obj = obj->next)
 		switch (obj->type) {
 		case ot_frame:
@@ -169,13 +181,27 @@
 }
 
 
+static int generate_items(struct frame *frame, struct coord base, int active)
+{
+	int res;
+
+	if (active)
+		inst_begin_active();
+	res = generate_vecs(frame, base) && generate_objs(frame, base);
+	if (active)
+		inst_end_active();
+	return res;
+}
+
+
 static int run_loops(struct frame *frame, struct loop *loop,
-    struct coord base)
+    struct coord base, int active)
 {
 	struct num from, to;
+	int n;
 
 	if (!loop)
-		return generate_objects(frame, base);
+		return generate_items(frame, base, active);
 	from = eval_num(loop->from, frame);
 	if (is_undef(from)) {
 		fail_expr(loop->from);
@@ -196,23 +222,38 @@
 		fail_expr(loop->to);
 		return 0;
 	}
+	n = 0;
 	for (loop->curr_value = from.n; loop->curr_value <= to.n;
-	    loop->curr_value += 1)
-		if (!run_loops(frame, loop->next, base))
+	    loop->curr_value += 1) {
+		if (n >= MAX_ITERATIONS) {
+			fail("%s: too many iterations (%d)", loop->var,
+			    MAX_ITERATIONS);
 			return 0;
+		}
+		if (!run_loops(frame, loop->next, base,
+		    active && loop->active == n))
+			return 0;
+		n++;
+	}
 	return 1;
 }
 
 
 static int iterate_tables(struct frame *frame, struct table *table,
-    struct coord base)
+    struct coord base, int active)
 {
+	int n;
+
 	if (!table)
-		return run_loops(frame, frame->loops, base);
+		return run_loops(frame, frame->loops, base, active);
+	n = 0;
 	for (table->curr_row = table->rows; table->curr_row;
-	    table->curr_row = table->curr_row->next)
-		if (!iterate_tables(frame, table->next, base))
+	    table->curr_row = table->curr_row->next) {
+		if (!iterate_tables(frame, table->next, base,
+		    active && table->active == n))
 			return 0;
+		n++;
+	}
 	return 1;
 }
 
@@ -227,7 +268,7 @@
 	 */
 	inst_begin_frame(frame, base);
 	frame->curr_parent = parent;
-	res = iterate_tables(frame, frame->tables, base);
+	res = iterate_tables(frame, frame->tables, base, frame == active_frame);
 	inst_end_frame(frame);
 	return res;
 }

Modified: developers/werner/fped/obj.h
===================================================================
--- developers/werner/fped/obj.h	2009-07-29 22:27:00 UTC (rev 5340)
+++ developers/werner/fped/obj.h	2009-07-30 14:11:24 UTC (rev 5341)
@@ -40,6 +40,9 @@
 
 	/* used during generation and when editing */
 	struct row *curr_row;
+
+	/* GUI use */
+	int active;	/* n-th row is active, 0 based */
 };
 
 struct loop {
@@ -50,6 +53,9 @@
 
 	/* used during generation */
 	double curr_value;
+
+	/* GUI use */
+	int active;	/* n-th iteration is active, 0 based */
 };
 
 struct vec {

Modified: developers/werner/fped/qfn.fpd
===================================================================
--- developers/werner/fped/qfn.fpd	2009-07-29 22:27:00 UTC (rev 5340)
+++ developers/werner/fped/qfn.fpd	2009-07-30 14:11:24 UTC (rev 5341)
@@ -14,6 +14,15 @@
 	.pad "$pad" c .
 }
 
+.frame pads {
+	n = 0, N/4-1
+
+	.vec @ P*(n-(N/4-1)/2), -Ay/2
+	.frame pad_up .
+
+}
+
+
 N = 24
 
 /*
@@ -35,11 +44,8 @@
 g_x1y1 = .vec . Gx, Gy
 .rect g_x0y0 g_x1y1
 
-n = 0, N/4-1
+.frame pads @
 
-.vec @ P*(n-(N/4-1)/2), -Ay/2
-.frame pad_up .
-
 // ARC, just for testing
 
 c = .vec @ -1mm, 1mm




More information about the commitlog mailing list