r5407 - trunk/eda/fped
werner at docs.openmoko.org
werner at docs.openmoko.org
Sat Aug 8 20:50:17 CEST 2009
Author: werner
Date: 2009-08-08 20:50:17 +0200 (Sat, 08 Aug 2009)
New Revision: 5407
Added:
trunk/eda/fped/gui_meas.c
trunk/eda/fped/gui_meas.h
Modified:
trunk/eda/fped/Makefile
trunk/eda/fped/README
trunk/eda/fped/coord.h
trunk/eda/fped/fpd.y
trunk/eda/fped/gui_tools.c
trunk/eda/fped/gui_tools.h
trunk/eda/fped/inst.c
trunk/eda/fped/inst.h
trunk/eda/fped/meas.c
Log:
New-style measurements are coming to the GUI soon !
- moved measurement operations from gui_tools.c to new file gui_meas.c
- added support for creating new-style measurements through the GUI
- the offset is optional in new-style expressions
Modified: trunk/eda/fped/Makefile
===================================================================
--- trunk/eda/fped/Makefile 2009-08-08 14:17:23 UTC (rev 5406)
+++ trunk/eda/fped/Makefile 2009-08-08 18:50:17 UTC (rev 5407)
@@ -14,7 +14,7 @@
unparse.o dump.o meas.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 \
- gui_tools.o gui_over.o
+ gui_tools.o gui_over.o gui_meas.o
XPMS = point.xpm delete.xpm vec.xpm frame.xpm frame_locked.xpm frame_ready.xpm \
line.xpm rect.xpm pad.xpm circ.xpm meas.xpm meas_x.xpm meas_y.xpm
Modified: trunk/eda/fped/README
===================================================================
--- trunk/eda/fped/README 2009-08-08 14:17:23 UTC (rev 5406)
+++ trunk/eda/fped/README 2009-08-08 18:50:17 UTC (rev 5407)
@@ -445,7 +445,7 @@
Syntax:
-<type> [<label>] <from> <op> <to> <offset>
+<type> [<label>] <from> <op> <to> [<offset>]
Types:
- measxy: measure diagonally
Modified: trunk/eda/fped/coord.h
===================================================================
--- trunk/eda/fped/coord.h 2009-08-08 14:17:23 UTC (rev 5406)
+++ trunk/eda/fped/coord.h 2009-08-08 18:50:17 UTC (rev 5407)
@@ -60,6 +60,12 @@
}
+static inline int coord_eq(struct coord a, struct coord b)
+{
+ return a.x == b.x && a.y == b.y;
+}
+
+
double mm_to_mil(double mm, int exponent);
double mil_to_mm(double mil, int exponent);
Modified: trunk/eda/fped/fpd.y
===================================================================
--- trunk/eda/fped/fpd.y 2009-08-08 14:17:23 UTC (rev 5406)
+++ trunk/eda/fped/fpd.y 2009-08-08 18:50:17 UTC (rev 5407)
@@ -493,7 +493,7 @@
;
meas:
- meas_type opt_string qbase meas_op qbase expr
+ meas_type opt_string qbase meas_op qbase opt_expr
{
$$ = alloc_type(struct meas);
$$->type = $4.max ? $1+3 : $1;
Added: trunk/eda/fped/gui_meas.c
===================================================================
--- trunk/eda/fped/gui_meas.c (rev 0)
+++ trunk/eda/fped/gui_meas.c 2009-08-08 18:50:17 UTC (rev 5407)
@@ -0,0 +1,337 @@
+/*
+ * gui_meas.c - GUI, canvas overlays
+ *
+ * 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 "util.h"
+#include "meas.h"
+#include "gui_canvas.h"
+#include "gui_tools.h"
+#include "gui_meas.h"
+
+
+static struct inst *meas_inst; /* point from which we're dragging */
+
+static enum {
+ min_to_next_or_max,
+ max_to_min,
+ next_to_min,
+} mode;
+
+
+/* ----- measurement type characteristics ---------------------------------- */
+
+
+static struct meas_dsc {
+ lt_op_type lt;
+ enum meas_type type;
+} *meas_dsc;
+
+
+static struct meas_dsc meas_dsc_xy = {
+ .lt = lt_xy,
+ .type = mt_xy_next,
+};
+
+
+static struct meas_dsc meas_dsc_x = {
+ .lt = lt_x,
+ .type = mt_x_next,
+};
+
+
+static struct meas_dsc meas_dsc_y = {
+ .lt = lt_y,
+ .type = mt_y_next,
+};
+
+
+/* ----- min/next/max tester ----------------------------------------------- */
+
+
+static int is_min(lt_op_type lt, const struct inst *inst)
+{
+ struct coord min;
+
+ min = meas_find_min(lt, inst->vec->samples);
+ return coord_eq(inst->u.rect.end, min);
+}
+
+
+static int is_next(lt_op_type lt,
+ const struct inst *inst, const struct inst *ref)
+{
+ struct coord next;
+
+ next = meas_find_next(lt, inst->vec->samples, ref->u.rect.end);
+ return coord_eq(inst->u.rect.end, next);
+}
+
+
+static int is_max(lt_op_type lt, const struct inst *inst)
+{
+ struct coord max;
+
+ max = meas_find_max(lt, inst->vec->samples);
+ return coord_eq(inst->u.rect.end, max);
+}
+
+
+static int is_a_next(lt_op_type lt, struct inst *inst)
+{
+ struct inst *a;
+ struct coord min, next;
+
+ for (a = insts_ip_vec(); a; a = a->next) {
+ min = meas_find_min(lt, a->vec->samples);
+ next = meas_find_next(lt, inst->vec->samples, min);
+ if (coord_eq(next, inst->u.rect.end))
+ return 1;
+ }
+ return 0;
+}
+
+
+static int is_min_of_next(lt_op_type lt,
+ const struct inst *inst, const struct inst *ref)
+{
+ struct coord min, next;
+
+ min = meas_find_min(lt, inst->vec->samples);
+ next = meas_find_next(lt, ref->vec->samples, min);
+ return coord_eq(next, ref->u.rect.end);
+}
+
+
+/* ----- picker functions -------------------------------------------------- */
+
+
+static int meas_pick_vec_a(struct inst *inst, void *ctx)
+{
+ struct vec *vec = inst->vec;
+
+ if (!vec->samples)
+ return 0;
+ if (is_min(meas_dsc->lt, inst)) {
+ mode = min_to_next_or_max;
+ return 1;
+ }
+ if (is_max(meas_dsc->lt, inst)) {
+ mode = max_to_min;
+ return 1;
+ }
+ if (is_a_next(meas_dsc->lt, inst)) {
+ mode = next_to_min;
+ return 1;
+ }
+ return 0;
+}
+
+
+static int meas_pick_vec_b(struct inst *inst, void *ctx)
+{
+ struct vec *vec = inst->vec;
+ struct inst *a = ctx;
+
+ if (!vec->samples)
+ return 0;
+ switch (mode) {
+ case min_to_next_or_max:
+ if (is_max(meas_dsc->lt, inst))
+ return 1;
+ if (is_next(meas_dsc->lt, inst, a))
+ return 1;
+ return 0;
+ case max_to_min:
+ return is_min(meas_dsc->lt, inst);
+ case next_to_min:
+ return is_min_of_next(meas_dsc->lt, inst, a);
+ default:
+ abort();
+ }
+}
+
+
+/* ----- highlighting ------------------------------------------------------ */
+
+
+static void meas_highlight_a(void)
+{
+ inst_highlight_vecs(meas_pick_vec_a, NULL);
+}
+
+
+static void meas_highlight_b(void)
+{
+ inst_highlight_vecs(meas_pick_vec_b, meas_inst);
+}
+
+
+/* ----- meas -------------------------------------------------------------- */
+
+
+struct pix_buf *draw_move_meas(struct inst *inst, struct coord pos, int i)
+{
+ return draw_move_line_common(inst, inst->u.meas.end, pos, i);
+}
+
+
+/* ----- tool selection ---------------------------------------------------- */
+
+
+static void tool_selected_meas(void)
+{
+ highlight = meas_highlight_a;
+ redraw();
+}
+
+
+static void tool_selected_meas_xy(void)
+{
+ meas_dsc = &meas_dsc_xy;
+ tool_selected_meas();
+}
+
+
+static void tool_selected_meas_x(void)
+{
+ meas_dsc = &meas_dsc_x;
+ tool_selected_meas();
+}
+
+
+static void tool_selected_meas_y(void)
+{
+ meas_dsc = &meas_dsc_y;
+ tool_selected_meas();
+}
+
+
+static void tool_deselected_meas(void)
+{
+ highlight = NULL;
+ redraw();
+}
+
+
+/* ----- find point ------------------------------------------------------- */
+
+
+static struct inst *find_point_meas(struct coord pos)
+{
+ if (meas_inst)
+ return inst_find_vec(pos, meas_pick_vec_b, meas_inst);
+ else
+ return inst_find_vec(pos, meas_pick_vec_a, NULL);
+}
+
+
+/* ----- begin dragging new measurement ------------------------------------ */
+
+
+static void begin_drag_new_meas(struct inst *inst)
+{
+ highlight = meas_highlight_b;
+ meas_inst = inst;
+ if (is_min(meas_dsc->lt, inst))
+ mode = min_to_next_or_max;
+ else if (is_max(meas_dsc->lt, inst))
+ mode = max_to_min;
+ else
+ mode = next_to_min;
+ redraw();
+}
+
+
+/* ----- end dragging new measurement -------------------------------------- */
+
+
+static int end_new_meas(struct inst *from, struct inst *to)
+{
+ struct meas *meas;
+
+ meas_inst = NULL;
+ if (from == to)
+ return 0;
+ meas = alloc_type(struct meas);
+ meas->label = NULL;
+ switch (mode) {
+ case min_to_next_or_max:
+ if (!is_max(meas_dsc->lt, to)) {
+ meas->type = meas_dsc->type;
+ } else {
+ meas->type = meas_dsc->type+3;
+ }
+ meas->low = from->vec;
+ meas->high = to->vec;
+ break;
+ case next_to_min:
+ meas->type = meas_dsc->type;
+ meas->low = to->vec;
+ meas->high = from->vec;
+ break;
+ case max_to_min:
+ meas->type = meas_dsc->type+3;
+ meas->low = to->vec;
+ meas->high = from->vec;
+ break;
+ default:
+ abort();
+ }
+ meas->inverted = meas_dsc->lt(from->u.rect.end, to->u.rect.end) !=
+ (mode == min_to_next_or_max);
+{
+char *sm[] = { "min_to", "max_to", "next_to" };
+char *st[] = { "nxy", "nx", "ny", "mxy", "mx", "my" };
+fprintf(stderr, "mode %s type %s, inverted %d\n",
+sm[mode], st[meas->type], meas->inverted);
+}
+ meas->offset = parse_expr("0mm");
+ meas->next = measurements;
+ measurements = meas;
+ meas_dsc = NULL;
+ return 1;
+}
+
+
+/* ----- begin dragging existing measurement ------------------------------- */
+
+
+/* ----- operations ------------------------------------------------------- */
+
+
+struct tool_ops meas_ops = {
+ .tool_selected = tool_selected_meas_xy,
+ .tool_deselected= tool_deselected_meas,
+ .find_point = find_point_meas,
+ .begin_drag_new = begin_drag_new_meas,
+ .drag_new = drag_new_line,
+ .end_new = end_new_meas,
+};
+
+struct tool_ops meas_ops_x = {
+ .tool_selected = tool_selected_meas_x,
+ .tool_deselected= tool_deselected_meas,
+ .find_point = find_point_meas,
+ .begin_drag_new = begin_drag_new_meas,
+ .drag_new = drag_new_line,
+ .end_new = end_new_meas,
+};
+
+
+struct tool_ops meas_ops_y = {
+ .tool_selected = tool_selected_meas_y,
+ .tool_deselected= tool_deselected_meas,
+ .find_point = find_point_meas,
+ .begin_drag_new = begin_drag_new_meas,
+ .drag_new = drag_new_line,
+ .end_new = end_new_meas,
+};
Added: trunk/eda/fped/gui_meas.h
===================================================================
--- trunk/eda/fped/gui_meas.h (rev 0)
+++ trunk/eda/fped/gui_meas.h 2009-08-08 18:50:17 UTC (rev 5407)
@@ -0,0 +1,22 @@
+/*
+ * gui_meas.c - GUI, canvas overlays
+ *
+ * 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 GUI_MEAS_H
+#define GUI_MEAS_H
+
+
+struct tool_ops meas_ops;
+struct tool_ops meas_ops_x;
+struct tool_ops meas_ops_y;
+
+#endif /* !GUI_MEAS_H */
Modified: trunk/eda/fped/gui_tools.c
===================================================================
--- trunk/eda/fped/gui_tools.c 2009-08-08 14:17:23 UTC (rev 5406)
+++ trunk/eda/fped/gui_tools.c 2009-08-08 18:50:17 UTC (rev 5407)
@@ -26,6 +26,7 @@
#include "gui_canvas.h"
#include "gui_status.h"
#include "gui.h"
+#include "gui_meas.h"
#include "gui_tools.h"
@@ -44,16 +45,6 @@
#include "icons/vec.xpm"
-struct tool_ops {
- void (*tool_selected)(void);
- void (*tool_deselected)(void);
- void (*click)(struct coord pos);
- struct pix_buf *(*drag_new)(struct inst *from, struct coord to);
- int (*end_new_raw)(struct inst *from, struct coord to);
- int (*end_new)(struct inst *from, struct inst *to);
-};
-
-
static GtkWidget *ev_point, *ev_frame;
static GtkWidget *active_tool;
static struct tool_ops *active_ops = NULL;
@@ -109,7 +100,7 @@
/* ----- shared functions -------------------------------------------------- */
-static struct pix_buf *draw_move_line_common(struct inst *inst,
+struct pix_buf *draw_move_line_common(struct inst *inst,
struct coord end, struct coord pos, int i)
{
struct coord from, to;
@@ -270,7 +261,7 @@
/* ----- line -------------------------------------------------------------- */
-static struct pix_buf *drag_new_line(struct inst *from, struct coord to)
+struct pix_buf *drag_new_line(struct inst *from, struct coord to)
{
struct coord pos;
struct pix_buf *buf;
@@ -496,86 +487,6 @@
};
-/* ----- meas -------------------------------------------------------------- */
-
-
-struct pix_buf *draw_move_meas(struct inst *inst, struct coord pos, int i)
-{
- return draw_move_line_common(inst, inst->u.meas.end, pos, i);
-}
-
-
-static int end_new_meas(struct inst *from, struct inst *to)
-{
- struct obj *obj;
-
- if (from == to)
- return 0;
- obj = new_obj(ot_meas, from);
- obj->u.meas.other = inst_get_vec(to);
- obj->u.meas.offset = parse_expr("0mm");
- return 1;
-}
-
-
-static int meas_x_pick_vec(struct inst *inst, void *ctx)
-{
- struct vec *vec = inst->vec;
- struct coord min;
-
- if (!vec->samples)
- return 0;
- min = meas_find_min(lt_xy, vec->samples);
- return inst->u.rect.end.x == min.x && inst->u.rect.end.y == min.y;
-}
-
-
-static void highlight_vecs(void)
-{
- inst_highlight_vecs(meas_x_pick_vec, NULL);
-}
-
-
-static void tool_selected_meas_x(void)
-{
- highlight = highlight_vecs;
- redraw();
-}
-
-
-static void tool_selected_meas_y(void)
-{
- highlight = NULL;
- redraw();
-}
-
-
-static void tool_deselected_meas(void)
-{
- highlight = NULL;
- redraw();
-}
-
-
-static struct tool_ops meas_ops = {
- .drag_new = drag_new_line,
- .end_new = end_new_meas,
-};
-
-static struct tool_ops meas_ops_x = {
- .tool_selected = tool_selected_meas_x,
- .tool_deselected= tool_deselected_meas,
- .drag_new = drag_new_line,
- .end_new = end_new_meas,
-};
-static struct tool_ops meas_ops_y = {
- .tool_selected = tool_selected_meas_y,
- .tool_deselected= tool_deselected_meas,
- .drag_new = drag_new_line,
- .end_new = end_new_meas,
-};
-
-
/* ----- frame helper ------------------------------------------------------ */
@@ -766,7 +677,10 @@
{
struct inst *curr;
- curr = inst_find_point(pos);
+ if (active_ops && active_ops->find_point)
+ curr = active_ops->find_point(pos);
+ else
+ curr = inst_find_point(pos);
if ((drag.new && curr == drag.new) || (drag.inst && curr == drag.inst))
return;
if (curr && !active_ops) {
@@ -817,12 +731,17 @@
active_ops->click(pos);
return 0;
}
- curr = inst_find_point(pos);
+ if (active_ops && active_ops->find_point)
+ curr = active_ops->find_point(pos);
+ else
+ curr = inst_find_point(pos);
if (!curr)
return 0;
tool_dehover();
if (active_ops) {
if (active_ops->drag_new) {
+ if (active_ops->begin_drag_new)
+ active_ops->begin_drag_new(curr);
drag.inst = NULL;
drag.new = curr;
over_begin(drag_save_and_draw, NULL, pos);
@@ -872,7 +791,10 @@
tool_cancel_drag();
if (state.new && ops->end_new_raw)
return ops->end_new_raw(state.new, to);
- end = inst_find_point(to);
+ if (ops->find_point)
+ end = ops->find_point(to);
+ else
+ end = inst_find_point(to);
if (!end)
return 0;
if (state.new)
Modified: trunk/eda/fped/gui_tools.h
===================================================================
--- trunk/eda/fped/gui_tools.h 2009-08-08 14:17:23 UTC (rev 5406)
+++ trunk/eda/fped/gui_tools.h 2009-08-08 18:50:17 UTC (rev 5407)
@@ -19,6 +19,20 @@
#include "inst.h"
+struct tool_ops {
+ void (*tool_selected)(void);
+ void (*tool_deselected)(void);
+ struct inst *(*find_point)(struct coord pos);
+ void (*click)(struct coord pos);
+ void (*begin_drag_new)(struct inst *from);
+// in inst
+// void (*begin_drag_move)struct inst *from, int anchor_i);
+ struct pix_buf *(*drag_new)(struct inst *from, struct coord to);
+ int (*end_new_raw)(struct inst *from, struct coord to);
+ int (*end_new)(struct inst *from, struct inst *to);
+};
+
+
struct pix_buf *draw_move_vec(struct inst *inst, struct coord pos, int i);
struct pix_buf *draw_move_line(struct inst *inst, struct coord pos, int i);
struct pix_buf *draw_move_rect(struct inst *inst, struct coord pos, int i);
@@ -40,8 +54,16 @@
int tool_end_drag(struct coord to);
void tool_redraw(void);
-struct pix_buf *tool_drag_new(struct inst *inst, struct coord pos);
+/*
+ * The following functions are for measurements which are now in a separate
+ * compilation unit.
+ */
+struct pix_buf *draw_move_line_common(struct inst *inst,
+ struct coord end, struct coord pos, int i);
+struct pix_buf *drag_new_line(struct inst *from, struct coord to);
+
+
/*
* Cache the frame and track it.
*/
Modified: trunk/eda/fped/inst.c
===================================================================
--- trunk/eda/fped/inst.c 2009-08-08 14:17:23 UTC (rev 5406)
+++ trunk/eda/fped/inst.c 2009-08-08 18:50:17 UTC (rev 5407)
@@ -852,6 +852,35 @@
}
+struct inst *inst_find_vec(struct coord pos,
+ int (*pick)(struct inst *inst, void *user), void *user)
+{
+ struct inst *inst, *found;
+ int best_dist = 0; /* keep gcc happy */
+ int dist;
+
+ found = NULL;
+ for (inst = insts[ip_vec]; inst; inst = inst->next) {
+ if (!inst->ops->distance)
+ continue;
+ dist = inst->ops->distance(inst, pos, draw_ctx.scale);
+ if (dist < 0 || (found && best_dist <= dist))
+ continue;
+ if (!pick(inst, user))
+ continue;
+ found = inst;
+ best_dist = dist;
+ }
+ return found;
+}
+
+
+struct inst *insts_ip_vec(void)
+{
+ return insts[ip_vec];
+}
+
+
struct pix_buf *inst_draw_move(struct inst *inst, struct coord pos, int i)
{
return inst->ops->draw_move(inst, pos, i);
Modified: trunk/eda/fped/inst.h
===================================================================
--- trunk/eda/fped/inst.h 2009-08-08 14:17:23 UTC (rev 5406)
+++ trunk/eda/fped/inst.h 2009-08-08 18:50:17 UTC (rev 5407)
@@ -115,6 +115,10 @@
void inst_draw(void);
void inst_highlight_vecs(int (*pick)(struct inst *inst, void *user),
void *user);
+struct inst *inst_find_vec(struct coord pos,
+ int (*pick)(struct inst *inst, void *user), void *user);
+struct inst *insts_ip_vec(void);
+
struct pix_buf *inst_draw_move(struct inst *inst, struct coord pos, int i);
int inst_do_move_to(struct inst *inst, struct vec *vec, int i);
struct pix_buf *inst_hover(struct inst *inst);
Modified: trunk/eda/fped/meas.c
===================================================================
--- trunk/eda/fped/meas.c 2009-08-08 14:17:23 UTC (rev 5406)
+++ trunk/eda/fped/meas.c 2009-08-08 18:50:17 UTC (rev 5407)
@@ -75,6 +75,9 @@
}
+/* ----- lt operators ------------------------------------------------------ */
+
+
int lt_x(struct coord a, struct coord b)
{
return a.x < b.x;
@@ -93,6 +96,9 @@
}
+/* ----- measurement type map ---------------------------------------------- */
+
+
static lt_op_type lt_op[mt_n] = {
lt_xy,
lt_x,
@@ -109,8 +115,11 @@
};
+/* ----- search functions -------------------------------------------------- */
+
+
static int better_next(lt_op_type lt,
- struct coord a0, struct coord b0, struct coord b)
+ struct coord a0, struct coord b0, struct coord b, int recursing)
{
/* if we don't have any suitable point A0 < B0 yet, use this one */
if (!lt(a0, b0))
@@ -133,12 +142,12 @@
* coordinate a chance. This gives us a stable sort order and it
* makes meas/measx/measy usually select the same point.
*/
- if (lt == lt_xy)
+ if (lt == lt_xy || recursing)
return 0;
if (lt == lt_x)
- return better_next(lt_y, a0, b0, b);
+ return better_next(lt_y, a0, b0, b, 1);
if (lt == lt_y)
- return better_next(lt_x, a0, b0, b);
+ return better_next(lt_x, a0, b0, b, 1);
abort();
}
@@ -173,7 +182,7 @@
next = s->pos;
while (s) {
- if (better_next(lt, ref, next, s->pos))
+ if (better_next(lt, ref, next, s->pos, 0))
next = s->pos;
s = s->next;
}
@@ -196,6 +205,9 @@
}
+/* ----- instantiation ----------------------------------------------------- */
+
+
int instantiate_meas(void)
{
struct meas *meas;
@@ -214,9 +226,13 @@
else
b0 = meas_find_max(lt, meas->high->samples);
- offset = eval_unit(meas->offset, root_frame);
- if (is_undef(offset))
- return 0;
+ if (!meas->offset)
+ offset.n = 0;
+ else {
+ offset = eval_unit(meas->offset, root_frame);
+ if (is_undef(offset))
+ return 0;
+ }
inst_meas(NULL, meas,
meas->inverted ? b0 : a0, meas->inverted ? a0 : b0,
offset.n);
More information about the commitlog
mailing list