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