mirror of
git://projects.qi-hardware.com/fped.git
synced 2024-11-25 19:02:29 +02: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:
parent
5c3921db16
commit
751e845250
2
Makefile
2
Makefile
@ -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
2
README
@ -445,7 +445,7 @@ Known issues:
|
||||
|
||||
Syntax:
|
||||
|
||||
<type> [<label>] <from> <op> <to> <offset>
|
||||
<type> [<label>] <from> <op> <to> [<offset>]
|
||||
|
||||
Types:
|
||||
- measxy: measure diagonally
|
||||
|
6
coord.h
6
coord.h
@ -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
2
fpd.y
@ -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
337
gui_meas.c
Normal 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
22
gui_meas.h
Normal 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 */
|
112
gui_tools.c
112
gui_tools.c
@ -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)
|
||||
|
24
gui_tools.h
24
gui_tools.h
@ -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
29
inst.c
@ -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
4
inst.h
@ -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
32
meas.c
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user