1
0
mirror of git://projects.qi-hardware.com/fped.git synced 2024-06-26 04:29:49 +03:00

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



git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5407 99fdad57-331a-0410-800a-d7fa5415bdb3
This commit is contained in:
werner 2009-08-08 18:50:17 +00:00
parent 5c3921db16
commit 751e845250
11 changed files with 465 additions and 107 deletions

View File

@ -14,7 +14,7 @@ OBJS = fped.o expr.o coord.o obj.o delete.o inst.o util.o error.o \
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

2
README
View File

@ -445,7 +445,7 @@ Known issues:
Syntax:
<type> [<label>] <from> <op> <to> <offset>
<type> [<label>] <from> <op> <to> [<offset>]
Types:
- measxy: measure diagonally

View File

@ -60,6 +60,12 @@ static inline double units_to_kicad(unit_type u)
}
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);

2
fpd.y
View File

@ -493,7 +493,7 @@ measurements:
;
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;

337
gui_meas.c Normal file
View File

@ -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,
};

22
gui_meas.h Normal file
View File

@ -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 */

View File

@ -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 @@ static struct obj *new_obj(enum obj_type type, struct inst *base)
/* ----- 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 @@ static struct tool_ops vec_ops = {
/* ----- 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 @@ static struct tool_ops circ_ops = {
};
/* ----- 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 @@ void tool_hover(struct coord pos)
{
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 @@ int tool_consider_drag(struct coord pos)
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 @@ int tool_end_drag(struct coord to)
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)

View File

@ -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,7 +54,15 @@ void tool_cancel_drag(void);
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.

29
inst.c
View File

@ -852,6 +852,35 @@ 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 *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);

4
inst.h
View File

@ -115,6 +115,10 @@ void inst_revert(void);
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);

32
meas.c
View File

@ -75,6 +75,9 @@ void meas_post(struct vec *vec, struct coord pos)
}
/* ----- lt operators ------------------------------------------------------ */
int lt_x(struct coord a, struct coord b)
{
return a.x < b.x;
@ -93,6 +96,9 @@ int lt_xy(struct coord a, struct coord b)
}
/* ----- measurement type map ---------------------------------------------- */
static lt_op_type lt_op[mt_n] = {
lt_xy,
lt_x,
@ -109,8 +115,11 @@ static int is_next[mt_n] = {
};
/* ----- 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 @@ static int better_next(lt_op_type lt,
* 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 @@ struct coord meas_find_next(lt_op_type lt, const struct sample *s,
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 @@ struct coord meas_find_max(lt_op_type lt, const struct sample *s)
}
/* ----- instantiation ----------------------------------------------------- */
int instantiate_meas(void)
{
struct meas *meas;
@ -214,9 +226,13 @@ int instantiate_meas(void)
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);