Send commitlog mailing list submissions to
        commitlog@lists.openmoko.org

To subscribe or unsubscribe via the World Wide Web, visit
        http://lists.openmoko.org/mailman/listinfo/commitlog
or, via email, send a message with subject or body 'help' to
        commitlog-requ...@lists.openmoko.org

You can reach the person managing the list at
        commitlog-ow...@lists.openmoko.org

When replying, please edit your Subject line so it is more specific
than "Re: Contents of commitlog digest..."
Today's Topics:

   1. r5364 - developers/werner/fped (wer...@docs.openmoko.org)
   2. r5365 - developers/werner/fped (wer...@docs.openmoko.org)
--- Begin Message ---
Author: werner
Date: 2009-08-02 01:12:30 +0200 (Sun, 02 Aug 2009)
New Revision: 5364

Modified:
   developers/werner/fped/README
   developers/werner/fped/TODO
   developers/werner/fped/fpd.l
   developers/werner/fped/fpd.y
   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/gui_util.c
   developers/werner/fped/gui_util.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 text renderer
- non-filled arrows are now open
- added measurements (syntax: meas <point-a> <point-b> <offset>)
- we now draw frame titles



Modified: developers/werner/fped/README
===================================================================
--- developers/werner/fped/README       2009-08-01 20:13:04 UTC (rev 5363)
+++ developers/werner/fped/README       2009-08-01 23:12:30 UTC (rev 5364)
@@ -167,6 +167,29 @@
 pad "1" @ .
 
 
+Measurements
+- - - - - -
+
+Measurements show the distance between two points:
+
+meas <point-a> <point-b> <offset>
+
+The offset is the distance from the imaginary line connecting points A
+and B the measurement line is draw:
+
+- if the offset is 0mm, the line will connect A and B
+- if the offset is positive, the line would be on the left-hand side when
+  traveling from A to B
+- if the offset is negative , the line would be on the right-hand side when
+  traveling from A to B
+
+Example:
+
+a: vec @(-1mm, 1mm)
+b: vec @(1mm, 1mm)
+meas a b 0.2 mm
+
+
 Frames
 - - -
 

Modified: developers/werner/fped/TODO
===================================================================
--- developers/werner/fped/TODO 2009-08-01 20:13:04 UTC (rev 5363)
+++ developers/werner/fped/TODO 2009-08-01 23:12:30 UTC (rev 5364)
@@ -6,7 +6,8 @@
 - add table/var/loop editor (missing: add col/row, add/del var/table/loop)
 - add default unit (combine with grid unit selection ?)
 - consider adding auto/mm/mil selection for each dimension
-- add measurements
+- add measurements (partly done. still needed: find out how to define
+  non-trivial endpoints, e.g., some vector in last iteration of loop)
 - add KiCad output
 - add postscript output
 - add option to include/omit helper vecs and frames (display and postscript)

Modified: developers/werner/fped/fpd.l
===================================================================
--- developers/werner/fped/fpd.l        2009-08-01 20:13:04 UTC (rev 5363)
+++ developers/werner/fped/fpd.l        2009-08-01 23:12:30 UTC (rev 5364)
@@ -90,6 +90,8 @@
                                  return TOK_CIRC; }
 <INITIAL>"arc"                 { BEGIN(NOKEYWORD);
                                  return TOK_ARC; }
+<INITIAL>"meas"                        { BEGIN(NOKEYWORD);
+                                 return TOK_MEAS; }
 
 [a-zA-Z_][a-zA-Z_0-9]*:                { *strchr(yytext, ':') = 0;
                                  yylval.id = unique(yytext);

Modified: developers/werner/fped/fpd.y
===================================================================
--- developers/werner/fped/fpd.y        2009-08-01 20:13:04 UTC (rev 5363)
+++ developers/werner/fped/fpd.y        2009-08-01 23:12:30 UTC (rev 5364)
@@ -139,7 +139,7 @@
 
 %token         START_FPD START_EXPR
 %token         TOK_SET TOK_LOOP TOK_FRAME TOK_TABLE TOK_VEC
-%token         TOK_PAD TOK_RECT TOK_LINE TOK_CIRC TOK_ARC
+%token         TOK_PAD TOK_RECT TOK_LINE TOK_CIRC TOK_ARC TOK_MEAS
 
 %token <num>   NUMBER
 %token <str>   STRING
@@ -409,6 +409,13 @@
                        $$->u.arc.start = $3;
                        $$->u.arc.end = $4;
                }
+       | TOK_MEAS base base expr
+               {
+                       $$ = new_obj(ot_meas);
+                       $$->base = $2;
+                       $$->u.meas.other = $3;
+                       $$->u.meas.offset = $4;
+               }
        | TOK_FRAME ID base
                {
                        $$ = new_obj(ot_frame);

Modified: developers/werner/fped/gui_inst.c
===================================================================
--- developers/werner/fped/gui_inst.c   2009-08-01 20:13:04 UTC (rev 5363)
+++ developers/werner/fped/gui_inst.c   2009-08-01 23:12:30 UTC (rev 5364)
@@ -15,8 +15,10 @@
 #include <math.h>
 #include <gtk/gtk.h>
 
+#include "util.h"
 #include "inst.h"
 #include "gui.h"
+#include "gui_util.h"
 #include "gui_style.h"
 #include "gui_inst.h"
 
@@ -96,7 +98,12 @@
                gp[i].x = points[i].x;
                gp[i].y = points[i].y;
        }
-       gdk_draw_polygon(DA, gc, fill, gp, n_points);
+       if (fill)
+               gdk_draw_polygon(DA, gc, fill, gp, n_points);
+       else {
+               gdk_draw_line(DA, gc, gp[0].x, gp[0].y, gp[1].x, gp[1].y);
+               gdk_draw_line(DA, gc, gp[1].x, gp[1].y, gp[2].x, gp[2].y);
+       }
 }
 
 
@@ -106,10 +113,10 @@
        struct coord p[3];
        struct coord side;
 
-       side = normalize(sub_vec(to, from), VEC_ARROW_LEN);
-       p[0] = to;
-       p[1] = add_vec(to, rotate(side, 180-VEC_ARROW_ANGLE));
-       p[2] = add_vec(to, rotate(side, 180+VEC_ARROW_ANGLE));
+       side = normalize(sub_vec(to, from), len);
+       p[0] = add_vec(to, rotate(side, 180-angle));
+       p[1] = to;
+       p[2] = add_vec(to, rotate(side, 180+angle));
        draw_poly(ctx, gc, fill, p, 3);
 }
 
@@ -246,6 +253,68 @@
 }
 
 
+/* ----- meas -------------------------------------------------------------- */
+
+
+static struct coord offset_vec(const struct inst *self)
+{
+       struct coord a, b, res;
+       double f;
+
+       a = self->base;
+       b = self->u.meas.end;
+       res.x = a.y-b.y;
+       res.y = b.x-a.x;
+       if (res.x == 0 && res.y == 0)
+               return res;
+       f = self->u.meas.offset/hypot(res.x, res.y);
+       res.x *= f;
+       res.y *= f;
+       return res;
+}
+
+
+unit_type gui_dist_meas(struct inst *self, struct coord pos, unit_type scale)
+{
+       struct coord a, b, off;
+       unit_type d;
+
+       off = offset_vec(self);
+       a = add_vec(self->base, off);
+       b = add_vec(self->u.meas.end, off);
+       d = dist_line(pos, a, b)/scale;
+       return d > SELECT_R ? -1 : d+VEC_EYE_R;
+}
+
+
+void gui_draw_meas(struct inst *self, struct draw_ctx *ctx)
+{
+       struct coord a0, b0, a1, b1, off, c, d;
+       GdkGC *gc;
+       char *s;
+
+       off = offset_vec(self);
+       a0 = translate(ctx, self->base);
+       b0 = translate(ctx, self->u.meas.end);
+       a1 = translate(ctx, add_vec(self->base, off));
+       b1 = translate(ctx, add_vec(self->u.meas.end, off));
+       gc = gc_meas[get_mode(self)];
+       gdk_draw_line(DA, gc, a0.x, a0.y, a1.x, a1.y);
+       gdk_draw_line(DA, gc, b0.x, b0.y, b1.x, b1.y);
+       gdk_draw_line(DA, gc, a1.x, a1.y, b1.x, b1.y);
+       draw_arrow(ctx, gc, FALSE, a1, b1, MEAS_ARROW_LEN, MEAS_ARROW_ANGLE);
+       draw_arrow(ctx, gc, FALSE, b1, a1, MEAS_ARROW_LEN, MEAS_ARROW_ANGLE);
+
+       c = add_vec(a1, b1);
+       d = sub_vec(b0, a0);
+       s = stralloc_printf("%lgmm",
+           units_to_mm(dist_point(self->base, self->u.meas.end)));
+       render_text(DA, gc, c.x/2, c.y/2, -atan2(d.y, d.x)/M_PI*180, s,
+           MEAS_FONT, 0.5, -MEAS_BASELINE_OFFSET);
+       free(s);
+}
+
+
 /* ----- frame ------------------------------------------------------------- */
 
 
@@ -262,6 +331,10 @@
        corner = translate(ctx, corner);
        corner.x -= FRAME_CLEARANCE;
        corner.y -= FRAME_CLEARANCE;
-       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);
+       gdk_draw_line(DA, gc, corner.x, corner.y,
+           corner.x+FRAME_SHORT_X, corner.y);
+       gdk_draw_line(DA, gc, corner.x, corner.y,
+           corner.x, corner.y+FRAME_SHORT_Y);
+       render_text(DA, gc, corner.x, corner.y, 0, self->u.frame.ref->name,
+           FRAME_FONT, 0, -FRAME_BASELINE_OFFSET);
 }

Modified: developers/werner/fped/gui_inst.h
===================================================================
--- developers/werner/fped/gui_inst.h   2009-08-01 20:13:04 UTC (rev 5363)
+++ developers/werner/fped/gui_inst.h   2009-08-01 23:12:30 UTC (rev 5364)
@@ -35,12 +35,14 @@
 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);
+unit_type gui_dist_meas(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);
 void gui_draw_pad(struct inst *self, struct draw_ctx *ctx);
 void gui_draw_arc(struct inst *self, struct draw_ctx *ctx);
+void gui_draw_meas(struct inst *self, struct draw_ctx *ctx);
 void gui_draw_frame(struct inst *self, struct draw_ctx *ctx);
 
 #endif /* !GUI_INST_H */

Modified: developers/werner/fped/gui_style.c
===================================================================
--- developers/werner/fped/gui_style.c  2009-08-01 20:13:04 UTC (rev 5363)
+++ developers/werner/fped/gui_style.c  2009-08-01 23:12:30 UTC (rev 5364)
@@ -26,6 +26,7 @@
 GdkGC *gc_vec[mode_n];
 GdkGC *gc_obj[mode_n];
 GdkGC *gc_pad[mode_n];
+GdkGC *gc_meas[mode_n];
 GdkGC *gc_frame[mode_n];
 
 
@@ -61,5 +62,6 @@
        style(gc_vec,   "#202000", "#404020", "#909040", "#c0c080", "#ffff80");
        style(gc_obj,   "#006060", INVALID,   "#00ffff", INVALID,   "#ffff80");
        style(gc_pad,   "#400000", INVALID,   "#ff0000", INVALID,   "#ffff80");
+       style(gc_meas,  "#280040", INVALID,   "#ff00ff", INVALID,   "#ffff80");
        style(gc_frame, "#004000", "#205020", "#00ff00", INVALID,   INVALID);
 }

Modified: developers/werner/fped/gui_style.h
===================================================================
--- developers/werner/fped/gui_style.h  2009-08-01 20:13:04 UTC (rev 5363)
+++ developers/werner/fped/gui_style.h  2009-08-01 23:12:30 UTC (rev 5364)
@@ -28,6 +28,15 @@
 #define        VEC_ARROW_ANGLE         20
 #define        VEC_EYE_R               5
 
+#define        MEAS_FONT               "Sans 8"
+#define        MEAS_BASELINE_OFFSET    0.1
+#define        MEAS_ARROW_LEN          9
+#define MEAS_ARROW_ANGLE       30
+
+#define        FRAME_FONT              "Sans 8"
+#define        FRAME_BASELINE_OFFSET   0.1
+#define        FRAME_SHORT_X           100
+#define        FRAME_SHORT_Y           20
 #define        FRAME_CLEARANCE         5
 #define        FRAME_EYE_R1            3
 #define        FRAME_EYE_R2            5
@@ -67,6 +76,7 @@
 extern GdkGC *gc_vec[mode_n];
 extern GdkGC *gc_obj[mode_n];
 extern GdkGC *gc_pad[mode_n];
+extern GdkGC *gc_meas[mode_n];
 extern GdkGC *gc_frame[mode_n];
 
 

Modified: developers/werner/fped/gui_util.c
===================================================================
--- developers/werner/fped/gui_util.c   2009-08-01 20:13:04 UTC (rev 5363)
+++ developers/werner/fped/gui_util.c   2009-08-01 23:12:30 UTC (rev 5364)
@@ -12,12 +12,16 @@
 
 
 #include <stdlib.h>
+#include <math.h>
 #include <gtk/gtk.h>
 
 #include "gui.h"
 #include "gui_util.h"
 
 
+/* ----- look up a color --------------------------------------------------- */
+
+
 GdkColor get_color(const char *spec)
 {
        GdkColormap *cmap;
@@ -32,6 +36,9 @@
 }
 
 
+/* ----- labels in a box --------------------------------------------------- */
+
+
 GtkWidget *label_in_box_new(const char *s)
 {
        GtkWidget *evbox, *label;
@@ -60,6 +67,66 @@
 }
 
 
+/* ----- render a text string ---------------------------------------------- */
+
+
+void render_text(GdkDrawable *da, GdkGC *gc, int x, int y, double angle,
+    const char *s, const char *font, double xalign, double yalign)
+{
+       GdkScreen *screen;
+       PangoRenderer *renderer;
+       PangoContext *context;
+       PangoLayout *layout;
+       PangoFontDescription *desc;
+       int width, height;
+       PangoMatrix m = PANGO_MATRIX_INIT;
+
+       /* set up the renderer */
+
+       screen = gdk_drawable_get_screen(da);
+       renderer = gdk_pango_renderer_get_default(screen);
+       gdk_pango_renderer_set_drawable(GDK_PANGO_RENDERER(renderer), da);
+       gdk_pango_renderer_set_gc(GDK_PANGO_RENDERER(renderer), gc);
+
+       /* start preparing the layout */
+
+       context = gdk_pango_context_get_for_screen(screen);
+       layout = pango_layout_new(context);
+       pango_layout_set_text(layout, s, -1);
+
+       /* apply the font */
+
+       desc = pango_font_description_from_string(font);
+       pango_layout_set_font_description(layout, desc);
+       pango_font_description_free(desc);
+
+       /* align and position the text */
+
+       pango_layout_get_size(layout, &width, &height);
+       pango_matrix_translate(&m, x, y);
+       pango_matrix_rotate(&m, angle);
+       pango_matrix_translate(&m,
+           -xalign*width/PANGO_SCALE, (yalign-1)*height/PANGO_SCALE);
+
+       pango_context_set_matrix(context, &m);
+       pango_layout_context_changed(layout);
+       pango_renderer_draw_layout(renderer, layout, 0, 0);
+
+       /* clean up renderer */
+
+       gdk_pango_renderer_set_drawable(GDK_PANGO_RENDERER(renderer), NULL);
+       gdk_pango_renderer_set_gc(GDK_PANGO_RENDERER(renderer), NULL);
+
+       /* free objects */
+
+       g_object_unref(layout);
+       g_object_unref(context);
+}
+
+
+/* ----- kill the content of a container ----------------------------------- */
+
+
 static void destroy_callback(GtkWidget *widget, gpointer data)
 {
        gtk_widget_destroy(widget);

Modified: developers/werner/fped/gui_util.h
===================================================================
--- developers/werner/fped/gui_util.h   2009-08-01 20:13:04 UTC (rev 5363)
+++ developers/werner/fped/gui_util.h   2009-08-01 23:12:30 UTC (rev 5364)
@@ -18,9 +18,14 @@
 
 
 GdkColor get_color(const char *spec);
+
 GtkWidget *label_in_box_new(const char *s);
 GtkWidget *box_of_label(GtkWidget *label);
 void label_in_box_bg(GtkWidget *box, const char *color);
+
+void render_text(GdkDrawable *da, GdkGC *gc, int x, int y, double angle,
+    const char *s, const char *font, double xalign, double yalign);
+
 void destroy_all_children(GtkContainer *container);
 
 #endif /* !GUI_UTIL_H */

Modified: developers/werner/fped/inst.c
===================================================================
--- developers/werner/fped/inst.c       2009-08-01 20:13:04 UTC (rev 5363)
+++ developers/werner/fped/inst.c       2009-08-01 23:12:30 UTC (rev 5364)
@@ -420,6 +420,49 @@
 }
 
 
+/* ----- measurement ------------------------------------------------------- */
+
+
+static void meas_op_debug(struct inst *self)
+{
+       printf("meas %lg, %lg / %lg, %lg offset %lg\n",
+           units_to_mm(self->base.x), units_to_mm(self->base.y),
+           units_to_mm(self->u.meas.end.x), units_to_mm(self->u.meas.end.y),
+           units_to_mm(self->u.meas.offset));
+}
+
+
+static void meas_op_select(struct inst *self)
+{
+       rect_status(self->bbox.min, self->bbox.max);
+       edit_expr(&self->obj->u.meas.offset);
+}
+
+
+static struct inst_ops meas_ops = {
+       .debug          = meas_op_debug,
+       .draw           = gui_draw_meas,
+       .distance       = gui_dist_meas,
+       .select         = meas_op_select,
+};
+
+
+int inst_meas(struct obj *obj, struct coord from, struct coord to,
+    unit_type offset)
+{
+       struct inst *inst;
+
+       inst = add_inst(&meas_ops, from);
+       inst->obj = obj;
+       inst->u.meas.end = to;
+       inst->u.meas.offset = offset;
+       /* @@@ our bbox is actually a bit more complex than this */
+       update_bbox(&inst->bbox, to);
+       propagate_bbox(inst);
+       return 1;
+}
+
+
 /* ----- active instance --------------------------------------------------- */
 
 

Modified: developers/werner/fped/inst.h
===================================================================
--- developers/werner/fped/inst.h       2009-08-01 20:13:04 UTC (rev 5363)
+++ developers/werner/fped/inst.h       2009-08-01 23:12:30 UTC (rev 5364)
@@ -66,6 +66,10 @@
                        unit_type r;
                        double a1, a2;
                } arc;
+               struct {
+                       struct coord end;
+                       double offset;
+               } meas;
        } u;
        struct inst *next;
 };
@@ -84,6 +88,8 @@
 int inst_pad(struct obj *obj, const char *name, struct coord a, struct coord 
b);
 int inst_arc(struct obj *obj, struct coord center, struct coord start,
     struct coord stop);
+int inst_meas(struct obj *obj, struct coord from, struct coord to,
+    unit_type offset);
 
 void inst_begin_active(int active);
 void inst_end_active(void);

Modified: developers/werner/fped/obj.c
===================================================================
--- developers/werner/fped/obj.c        2009-08-01 20:13:04 UTC (rev 5363)
+++ developers/werner/fped/obj.c        2009-08-01 23:12:30 UTC (rev 5364)
@@ -66,6 +66,7 @@
        struct obj *obj;
        char *name;
        int ok;
+       struct num offset;
 
        for (obj = frame->objs; obj; obj = obj->next)
                switch (obj->type) {
@@ -101,6 +102,17 @@
                            obj->u.arc.end ? obj->u.arc.end->pos : base))
                                return 0;
                        break;
+               case ot_meas:
+                       offset = eval_num(obj->u.meas.offset, frame);
+                       if (is_undef(offset) || !to_unit(&offset)) {
+                               fail_expr(obj->u.meas.offset);
+                               return 0;
+                       }
+                       if (!inst_meas(obj, obj->base ? obj->base->pos : base,
+                           obj->u.meas.other ? obj->u.meas.other->pos : base,
+                           offset.n))
+                               return 0;
+                       break;
                default:
                        abort();
                }

Modified: developers/werner/fped/obj.h
===================================================================
--- developers/werner/fped/obj.h        2009-08-01 20:13:04 UTC (rev 5363)
+++ developers/werner/fped/obj.h        2009-08-01 23:12:30 UTC (rev 5364)
@@ -112,6 +112,7 @@
        ot_pad,
        ot_line,
        ot_arc,
+       ot_meas,
 };
 
 struct rect {
@@ -128,6 +129,11 @@
        struct vec *end; /* NULL if this is a circle */
 };
 
+struct meas {
+       struct vec *other; /* NULL if frame origin */
+       struct expr *offset;
+};
+
 struct obj {
        enum obj_type type;
        union {
@@ -136,6 +142,7 @@
                struct rect line;
                struct pad pad;
                struct arc arc;
+               struct meas meas;
        } u;
        struct vec *base;
        struct obj *next;

Modified: developers/werner/fped/qfn.fpd
===================================================================
--- developers/werner/fped/qfn.fpd      2009-08-01 20:13:04 UTC (rev 5363)
+++ developers/werner/fped/qfn.fpd      2009-08-01 23:12:30 UTC (rev 5364)
@@ -9,7 +9,9 @@
 
 frame pad_up {
        c: vec @(-D/2, 0mm)
-       vec .(D, C)
+       vec .(0mm, C)
+       meas c . 0.2mm
+       vec c(D, C)
        set pad = n+1
        pad "$pad" c .
 }




--- End Message ---
--- Begin Message ---
Author: werner
Date: 2009-08-02 07:17:39 +0200 (Sun, 02 Aug 2009)
New Revision: 5365

Modified:
   developers/werner/fped/TODO
   developers/werner/fped/gui_icons.c
   developers/werner/fped/gui_inst.c
   developers/werner/fped/inst.c
   developers/werner/fped/inst.h
Log:
- implemented radio buttons for icon bar, but don't like them
- removed excessive paranoia in inst_get_bbox
- instances are now stacked by drawing/selection priority
- struct inst_ops is only used inside inst.c, moved it there
- no longer need "magic" VEC_EYE_R in gui_inst.c to give vectors selection 
  priority
- when selecting an arc now only consider the part drawn, not the whole circle



Modified: developers/werner/fped/TODO
===================================================================
--- developers/werner/fped/TODO 2009-08-01 23:12:30 UTC (rev 5364)
+++ developers/werner/fped/TODO 2009-08-02 05:17:39 UTC (rev 5365)
@@ -16,13 +16,9 @@
 - detect recursive evaluation (through variables)
 - eliminate duplicate instances
 
-Bugs:
-- when selecting an arc only consider the part drawn, not the whole circle
-
 Style:
-- stack elements (1): frames, pads, silk, vecs
-- stack elements (2): all unselected below all selected
-- stack elements (3): circle on top of vec
+- stack elements (2a): all inactive below all active
+- stack elements (2b): unselected below selected
 - make column of entry field greedily consume all unallocated space
 
 Code cleanup:

Modified: developers/werner/fped/gui_icons.c
===================================================================
--- developers/werner/fped/gui_icons.c  2009-08-01 23:12:30 UTC (rev 5364)
+++ developers/werner/fped/gui_icons.c  2009-08-02 05:17:39 UTC (rev 5365)
@@ -28,8 +28,8 @@
 #include "icons/vec.xpm"
 
 
-static GtkWidget *icon_button(GtkWidget *bar, GdkDrawable *drawable,
-     char **xpm)
+static GtkToolItem *icon_button(GtkWidget *bar, GdkDrawable *drawable,
+     char **xpm, GtkToolItem *last)
 {
        GdkPixmap *pixmap;
        GtkWidget *image;       
@@ -38,19 +38,34 @@
        pixmap = gdk_pixmap_create_from_xpm_d(drawable, NULL, NULL, xpm);
        image = gtk_image_new_from_pixmap(pixmap, NULL);
 
+/*
+ * gtk_radio_tool_button_new_from_widget is *huge*. we try to do things in a
+ * more compact way.
+ */
+#if 0
+       if (last)
+               item = gtk_radio_tool_button_new_from_widget(
+                   GTK_RADIO_TOOL_BUTTON(last));
+       else
+               item = gtk_radio_tool_button_new(NULL);
+       gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(item), image);
+#else
        item = gtk_tool_item_new();
        gtk_container_add(GTK_CONTAINER(item), image);
 
        gtk_container_set_border_width(GTK_CONTAINER(item), 1);
+#endif
+
        gtk_toolbar_insert(GTK_TOOLBAR(bar), item, -1);
 
-       return NULL;
+       return item;
 }
 
 
 GtkWidget *gui_setup_icons(GdkDrawable *drawable)
 {
        GtkWidget *bar;
+       GtkToolItem *last;
 
        bar = gtk_toolbar_new();
        gtk_toolbar_set_style(GTK_TOOLBAR(bar), GTK_TOOLBAR_ICONS);
@@ -58,15 +73,15 @@
            GTK_ORIENTATION_VERTICAL);
 //gtk_container_set_border_width(GTK_CONTAINER(bar), 5);
 
-       icon_button(bar, drawable, xpm_point);
-       icon_button(bar, drawable, xpm_vec);
-       icon_button(bar, drawable, xpm_frame);
-       icon_button(bar, drawable, xpm_pad);
-       icon_button(bar, drawable, xpm_line);
-       icon_button(bar, drawable, xpm_rect);
-       icon_button(bar, drawable, xpm_circ);
-       icon_button(bar, drawable, xpm_arc);
-       icon_button(bar, drawable, xpm_meas);
+       last = icon_button(bar, drawable, xpm_point, NULL);
+       last = icon_button(bar, drawable, xpm_vec, last);
+       last = icon_button(bar, drawable, xpm_frame, last);
+       last = icon_button(bar, drawable, xpm_pad, last);
+       last = icon_button(bar, drawable, xpm_line, last);
+       last = icon_button(bar, drawable, xpm_rect, last);
+       last = icon_button(bar, drawable, xpm_circ, last);
+       last = icon_button(bar, drawable, xpm_arc, last);
+       last = icon_button(bar, drawable, xpm_meas, last);
 
        return bar;
 }

Modified: developers/werner/fped/gui_inst.c
===================================================================
--- developers/werner/fped/gui_inst.c   2009-08-01 23:12:30 UTC (rev 5364)
+++ developers/werner/fped/gui_inst.c   2009-08-02 05:17:39 UTC (rev 5365)
@@ -164,7 +164,7 @@
        unit_type d;
 
        d = dist_line(pos, self->bbox.min, self->bbox.max)/scale;
-       return d > SELECT_R ? -1 : d+VEC_EYE_R;
+       return d > SELECT_R ? -1 : d;
 }
 
 
@@ -187,7 +187,7 @@
        unit_type d;
 
        d = dist_rect(pos, self->bbox.min, self->bbox.max)/scale;
-       return d > SELECT_R ? -1 : d+VEC_EYE_R;
+       return d > SELECT_R ? -1 : d;
 }
 
 
@@ -211,9 +211,9 @@
        unit_type d;
 
        if (inside_rect(pos, self->bbox.min, self->bbox.max))
-               return VEC_EYE_R;
+               return SELECT_R;
        d = dist_rect(pos, self->bbox.min, self->bbox.max)/scale;
-       return d > SELECT_R ? -1 : d+VEC_EYE_R;
+       return d > SELECT_R ? -1 : d;
 }
 
 
@@ -233,12 +233,54 @@
 /* ----- arc --------------------------------------------------------------- */
 
 
+static struct coord rotate_r(struct coord center, unit_type r, double angle)
+{
+       struct coord res;
+
+       angle = angle/180.0*M_PI;
+       res.x = center.x+r*cos(angle);
+       res.y = center.y+r*sin(angle);
+       return res;
+}
+
+
 unit_type gui_dist_arc(struct inst *self, struct coord pos, unit_type scale)
 {
-       unit_type d;
+       struct coord c = self->base;
+       struct coord p;
+       unit_type d_min, d;
+       double angle, a2;
 
-       d = dist_circle(pos, self->base, self->u.arc.r)/scale;
-       return d > SELECT_R ? -1 : d+VEC_EYE_R;
+       /* check endpoints */
+
+       p = rotate_r(c, self->u.arc.r, self->u.arc.a1);
+       d_min = hypot(pos.x-p.x, pos.y-p.y);
+
+       p = rotate_r(c, self->u.arc.r, self->u.arc.a2);
+       d = hypot(pos.x-p.x, pos.y-p.y);
+        if (d < d_min)
+                d_min = d;
+
+       if (d_min/scale <= SELECT_R)
+               return d;
+
+       /* distance from the circle containing the arc */
+
+       d = dist_circle(pos, c, self->u.arc.r)/scale;
+       if (d > SELECT_R)
+               return -1;
+       if (self->u.arc.a1 == self->u.arc.a2)
+               return d;
+
+       /* see if we're close to the part that's actually drawn */
+
+       angle = atan2(pos.y-c.y, pos.x-c.x)/M_PI*180.0;
+       if (angle < 0)
+               angle += 180;
+       a2 = self->u.arc.a2;
+       if (a2 < self->u.arc.a1)
+               a2 += 180;
+       return angle >= self->u.arc.a1 && angle <= a2 ? d : -1;
 }
 
 
@@ -283,7 +325,7 @@
        a = add_vec(self->base, off);
        b = add_vec(self->u.meas.end, off);
        d = dist_line(pos, a, b)/scale;
-       return d > SELECT_R ? -1 : d+VEC_EYE_R;
+       return d > SELECT_R ? -1 : d;
 }
 
 

Modified: developers/werner/fped/inst.c
===================================================================
--- developers/werner/fped/inst.c       2009-08-01 23:12:30 UTC (rev 5364)
+++ developers/werner/fped/inst.c       2009-08-02 05:17:39 UTC (rev 5365)
@@ -24,11 +24,48 @@
 #include "inst.h"
 
 
+struct inst_ops {
+       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);
+};
+
+enum inst_prio {
+       ip_frame,       /* frames have their own selection */
+       ip_pad,         /* pads also accept clicks inside */
+       ip_circ,        /* circles don't overlap easily */
+       ip_arc,         /* arc are like circles, just shorter */
+       ip_rect,        /* rectangles have plenty of sides */
+       ip_meas,        /* mesurements are like lines but set a bit apart */
+       ip_line,        /* lines are easly overlapped by other things */
+       ip_vec,         /* vectors only have the end point */
+       ip_n,           /* number of priorities */
+};
+
+
+#define FOR_INST_PRIOS_UP(prio)                                        \
+       for (prio = 0; prio != ip_n; prio++)
+
+#define FOR_INST_PRIOS_DOWN(prio)                              \
+       for (prio = ip_n-1; prio != (enum inst_prio) -1; prio--)
+
+#define        FOR_INSTS_UP(prio, inst)                                \
+       FOR_INST_PRIOS_UP(prio)                                 \
+               for (inst = insts[prio]; inst; inst = inst->next)
+
+#define        FOR_INSTS_DOWN(prio, inst)                              \
+       FOR_INST_PRIOS_DOWN(prio)                               \
+               for (inst = insts[prio]; inst; inst = inst->next)
+
+
 struct inst *curr_frame = NULL;
 struct inst *selected_inst = NULL;
 
-static struct inst *insts = NULL, **next_inst;
-static struct inst *prev_insts;
+static struct inst *insts[ip_n], **next_inst[ip_n];
+static struct inst *prev_insts[ip_n];
 
 static unsigned long active_set = 0;
 
@@ -86,27 +123,31 @@
 
 int inst_select(const struct draw_ctx *ctx, struct coord pos)
 {
+       enum inst_prio prio;
        struct inst *inst;
        int best_dist, dist;
 
        deselect_outside();
-       selected_inst = NULL;
        edit_nothing();
-       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;
+       FOR_INST_PRIOS_DOWN(prio) {
+               selected_inst = NULL;
+               for (inst = insts[prio]; 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 1;
+               }
        }
-       if (selected_inst) {
-               set_path(1);
-               if (selected_inst->ops->select)
-                       selected_inst->ops->select(selected_inst);
-       }
-       return selected_inst != NULL;
+       return 0;
 }
 
 
@@ -165,7 +206,8 @@
        update_bbox(&curr_frame->bbox, inst->bbox.max);
 }
 
-static struct inst *add_inst(const struct inst_ops *ops, struct coord base)
+static struct inst *add_inst(const struct inst_ops *ops, enum inst_prio prio,
+    struct coord base)
 {
        struct inst *inst;
 
@@ -176,8 +218,8 @@
        inst->active = IS_ACTIVE;
        inst->in_path = 0;
        inst->next = NULL;
-       *next_inst = inst;
-       next_inst = &inst->next;
+       *next_inst[prio] = inst;
+       next_inst[prio] = &inst->next;
        return inst;
 }
 
@@ -227,7 +269,7 @@
 {
        struct inst *inst;
 
-       inst = add_inst(&vec_ops, base);
+       inst = add_inst(&vec_ops, ip_vec, base);
        inst->vec = vec;
        inst->u.end = vec->pos;
        update_bbox(&inst->bbox, vec->pos);
@@ -265,7 +307,7 @@
 {
        struct inst *inst;
 
-       inst = add_inst(&line_ops, a);
+       inst = add_inst(&line_ops, ip_line, a);
        inst->obj = obj;
        inst->u.end = b;
        update_bbox(&inst->bbox, b);
@@ -303,7 +345,7 @@
 {
        struct inst *inst;
 
-       inst = add_inst(&rect_ops, a);
+       inst = add_inst(&rect_ops, ip_rect, a);
        inst->obj = obj;
        inst->u.end = b;
        update_bbox(&inst->bbox, b);
@@ -355,7 +397,7 @@
 {
        struct inst *inst;
 
-       inst = add_inst(&pad_ops, a);
+       inst = add_inst(&pad_ops, ip_pad, a);
        inst->obj = obj;
        inst->u.name = stralloc(name);
        update_bbox(&inst->bbox, b);
@@ -399,7 +441,7 @@
        struct inst *inst;
        double r, a1, a2;
 
-       inst = add_inst(&arc_ops, center);
+       inst = add_inst(&arc_ops, ip_arc, center);
        inst->obj = obj;
        r = hypot(start.x-center.x, start.y-center.y);
        a1 = atan2(start.y-center.y, start.x-center.x)/M_PI*180.0;
@@ -452,7 +494,7 @@
 {
        struct inst *inst;
 
-       inst = add_inst(&meas_ops, from);
+       inst = add_inst(&meas_ops, ip_meas, from);
        inst->obj = obj;
        inst->u.meas.end = to;
        inst->u.meas.offset = offset;
@@ -499,7 +541,7 @@
 {
        struct inst *inst;
 
-       inst = add_inst(&frame_ops, base);
+       inst = add_inst(&frame_ops, ip_frame, base);
        inst->u.frame.ref = frame;
        inst->active = active;
        curr_frame = inst;
@@ -521,29 +563,33 @@
 
 struct bbox inst_get_bbox(void)
 {
-       static struct bbox bbox_zero;
-
-       return insts ? insts->bbox : bbox_zero;
+       return insts[ip_frame]->bbox;
 }
 
 
-static void inst_free(struct inst *list)
+static void inst_free(struct inst *list[ip_n])
 {
+       enum inst_prio prio;
        struct inst *next;
 
-       while (list) {
-               next = list->next;
-               free(list);
-               list = next;
-       }
+       FOR_INST_PRIOS_UP(prio)
+               while (list[prio]) {
+                       next = list[prio]->next;
+                       free(list[prio]);
+                       list[prio] = next;
+               }
 }
 
 
 void inst_start(void)
 {
-       prev_insts = insts;
-       insts = NULL;
-       next_inst = &insts;
+       enum inst_prio prio;
+
+       FOR_INST_PRIOS_UP(prio) {
+               prev_insts[prio] = insts[prio];
+               insts[prio] = NULL;
+               next_inst[prio] = &insts[prio];
+       }
 }
 
 
@@ -555,25 +601,30 @@
 
 void inst_revert(void)
 {
+       enum inst_prio prio;
+
        inst_free(insts);
-       insts = prev_insts;
+       FOR_INST_PRIOS_UP(prio)
+               insts[prio] = prev_insts[prio];
 }
 
 
 void inst_draw(struct draw_ctx *ctx)
 {
-       struct inst *walk;
+       enum inst_prio prio;
+       struct inst *inst;
 
-       for (walk = insts; walk; walk = walk->next)
-               if (walk->ops->draw)
-                       walk->ops->draw(walk, ctx);
+       FOR_INSTS_UP(prio, inst)
+               if (inst->ops->draw)
+                       inst->ops->draw(inst, ctx);
 }
 
 
 void inst_debug(void)
 {
-       struct inst *walk;
+       enum inst_prio prio;
+       struct inst *inst;
 
-       for (walk = insts; walk; walk = walk->next)
-               walk->ops->debug(walk);
+       FOR_INSTS_UP(prio, inst)
+               inst->ops->debug(inst);
 }

Modified: developers/werner/fped/inst.h
===================================================================
--- developers/werner/fped/inst.h       2009-08-01 23:12:30 UTC (rev 5364)
+++ developers/werner/fped/inst.h       2009-08-02 05:17:39 UTC (rev 5365)
@@ -34,18 +34,9 @@
        struct coord max;
 };
 
-struct inst;
+struct inst_ops;
 struct draw_ctx;
 
-struct inst_ops {
-       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;




--- End Message ---
_______________________________________________
commitlog mailing list
commitlog@lists.openmoko.org
http://lists.openmoko.org/mailman/listinfo/commitlog

Reply via email to