diff --git a/TODO b/TODO index 5425f2a..b7ed09e 100644 --- a/TODO +++ b/TODO @@ -2,8 +2,6 @@ Major missing features: - populate input area (still needed: mm/mil, rezoom) - add default unit (combine with grid unit selection ?) - consider adding auto/mm/mil selection for each dimension -- 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 (done for display, still @@ -35,6 +33,9 @@ Code cleanup: - merge edit_unique with edit_name - merge find_var_in_frame with similar mechanisms in expr.c and fpd.y - add regression tests +- the drag logic is too complex. Better: let tool/instance just generate the + list of points at each stage, then handle the highlighting and hovering + inside a dragging module. Open decisions: - Q: should loop be (start, last) or (start, iterations) ? or start ... last ? diff --git a/fped.c b/fped.c index d07e669..8485bd9 100644 --- a/fped.c +++ b/fped.c @@ -11,6 +11,8 @@ */ +#include +#include #include "cpp.h" #include "util.h" @@ -23,6 +25,8 @@ extern void scan_empty(void); extern int yyparse(void); +char *save_file = NULL; + static void load_file(const char *name) { @@ -32,20 +36,34 @@ static void load_file(const char *name) } +static void usage(const char *name) +{ + fprintf(stderr, "usage: %s [in_file [out_file]]\n", name); + exit(1); +} + + int main(int argc, char **argv) { + const char *name = *argv; int error; error = gui_init(&argc, &argv); if (error) return error; - if (argc == 1) { + switch (argc) { + case 1: scan_empty(); (void) yyparse(); - } else { + break; + case 3: + save_file = argv[2]; + /* fall through */ + case 2: load_file(argv[1]); - argc--; - argv++; + break; + default: + usage(name); } if (!part_name) diff --git a/gui.c b/gui.c index a658f1c..b214d83 100644 --- a/gui.c +++ b/gui.c @@ -11,6 +11,7 @@ */ +#include #include #include "inst.h" @@ -30,6 +31,8 @@ #include "icons/meas_off.xpm" +extern char *save_file; + GtkWidget *root; int show_stuff = 1; int show_meas = 1; @@ -45,7 +48,22 @@ static GtkWidget *stuff_image[2], *meas_image[2]; static void menu_save(GtkWidget *widget, gpointer user) { - dump(stdout); + FILE *file; + + if (!save_file) { + if (!dump(stdout)) + perror("stdout"); + return; + } + file = fopen(save_file, "w"); + if (!file) { + perror(save_file); + return; + } + if (!dump(file)) + perror(save_file); + if (fclose(file) == EOF) + perror(save_file); } diff --git a/gui_canvas.c b/gui_canvas.c index b3f213c..ac86b72 100644 --- a/gui_canvas.c +++ b/gui_canvas.c @@ -27,6 +27,13 @@ #include "gui_canvas.h" +#if 0 +#define DPRINTF(fmt, ...) fprintf(stderr, fmt "\n", ##__VA_ARGS__) +#else +#define DPRINTF(fmt, ...) +#endif + + void (*highlight)(void) = NULL; static struct coord curr_pos; @@ -139,6 +146,7 @@ static gboolean motion_notify_event(GtkWidget *widget, GdkEventMotion *event, { struct coord pos = canvas_to_coord(event->x, event->y); + DPRINTF("--- motion ---"); curr_pos.x = event->x; curr_pos.y = event->y; tool_hover(pos); @@ -161,6 +169,7 @@ static gboolean button_press_event(GtkWidget *widget, GdkEventButton *event, const struct inst *prev; int res; + DPRINTF("--- button press ---"); gtk_widget_grab_focus(widget); switch (event->button) { case 1: @@ -206,6 +215,7 @@ static gboolean button_release_event(GtkWidget *widget, GdkEventButton *event, { struct coord pos = canvas_to_coord(event->x, event->y); + DPRINTF("--- button release ---"); switch (event->button) { case 1: if (!dragging) @@ -291,6 +301,7 @@ static gboolean key_press_event(GtkWidget *widget, GdkEventKey *event, { struct coord pos = canvas_to_coord(curr_pos.x, curr_pos.y); + DPRINTF("--- key press ---"); switch (event->keyval) { case ' ': user_origin = pos; @@ -350,10 +361,13 @@ static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data) { static int first = 1; + + DPRINTF("--- expose ---"); if (first) { init_canvas(); first = 0; } + tool_dehover(); redraw(); return TRUE; } @@ -373,6 +387,7 @@ static gboolean enter_notify_event(GtkWidget *widget, GdkEventCrossing *event, static gboolean leave_notify_event(GtkWidget *widget, GdkEventCrossing *event, gpointer data) { + DPRINTF("--- leave ---"); if (dragging) tool_cancel_drag(); tool_dehover(); diff --git a/gui_meas.c b/gui_meas.c index 6e47eda..8f1b40b 100644 --- a/gui_meas.c +++ b/gui_meas.c @@ -12,7 +12,9 @@ #include "util.h" +#include "coord.h" #include "meas.h" +#include "inst.h" #include "gui_canvas.h" #include "gui_tool.h" #include "gui_meas.h" @@ -153,7 +155,10 @@ static int meas_pick_vec_b(struct inst *inst, void *ctx) 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); + if (!is_min(meas_dsc->lt, inst)) + return 0; + return is_next(meas_dsc->lt, a, inst); +// return is_min_of_next(meas_dsc->lt, inst, a); default: abort(); } @@ -222,10 +227,10 @@ static void tool_deselected_meas(void) } -/* ----- find point ------------------------------------------------------- */ +/* ----- find start point (new measurement) -------------------------------- */ -static struct inst *find_point_meas(struct coord pos) +static struct inst *find_point_meas_new(struct coord pos) { if (meas_inst) return inst_find_vec(pos, meas_pick_vec_b, meas_inst); @@ -260,6 +265,7 @@ static int end_new_meas(struct inst *from, struct inst *to) struct meas *meas; meas_inst = NULL; + highlight = NULL; if (from == to) return 0; /* it's safe to pass "from" here, but we may change it later */ @@ -290,9 +296,9 @@ static int end_new_meas(struct inst *from, struct inst *to) abort(); } meas->inverted = - mode == min_to_next_or_max && is_min(meas_dsc->lt, to) ? 0 : - meas_dsc->lt(from->u.rect.end, to->u.rect.end) != - (mode == min_to_next_or_max); + mode == min_to_next_or_max && is_min(meas_dsc->lt, to) ? 0 : + 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" }; @@ -305,9 +311,36 @@ sm[mode], st[meas->type], meas->inverted); } +static void cancel_drag_new_meas(void) +{ + meas_inst = NULL; + highlight = NULL; + redraw(); +} + + /* ----- begin dragging existing measurement ------------------------------- */ +/* + * We didn't record which instance provided the vector we're using here, so we + * have to search for it now. + */ + +static struct inst *vec_at(const struct vec *vec, struct coord pos) +{ + struct inst *inst; + const struct sample *s; + + for (inst = insts_ip_vec(); inst; inst = inst->next) + if (inst->vec == vec) + for (s = vec->samples; s; s = s->next) + if (coord_eq(s->pos, pos)) + return inst; + abort(); +} + + void begin_drag_move_meas(struct inst *inst, int i) { const struct meas *meas = &inst->obj->u.meas; @@ -328,49 +361,93 @@ void begin_drag_move_meas(struct inst *inst, int i) default: abort(); } + highlight = meas_highlight_b; switch (i) { case 0: - highlight = meas_highlight_a; mode = meas->type < 3 ? next_to_min : max_to_min; + meas_inst = vec_at(inst->obj->u.meas.high, inst->u.meas.end); break; case 1: - highlight = meas_highlight_b; mode = min_to_next_or_max; + meas_inst = vec_at(inst->obj->base, inst->base); break; default: abort(); } +// redraw(); +} + + +/* ----- find end point (existing measurement) ----------------------------- */ + + +struct inst *find_point_meas_move(struct inst *inst, struct coord pos) +{ + return inst_find_vec(pos, meas_pick_vec_b, meas_inst); +} + + +/* ----- end dragging existing measurements -------------------------------- */ + + +void end_drag_move_meas(void) +{ + highlight = NULL; redraw(); } -/* ----- operations ------------------------------------------------------- */ +void do_move_to_meas(struct inst *inst, struct inst *to, int i) +{ + struct meas *meas = &inst->obj->u.meas; + + switch (i) { + case 0: + inst->obj->base = inst_get_vec(to); + break; + case 1: + meas->high = inst_get_vec(to); + if (is_max(meas_dsc->lt, to)) + meas->type = (meas->type % 3)+3; + else + meas->type = (meas->type % 3); + break; + default: + abort(); + } +} + + +/* ----- operations -------------------------------------------------------- */ struct tool_ops tool_meas_ops = { .tool_selected = tool_selected_meas_xy, .tool_deselected= tool_deselected_meas, - .find_point = find_point_meas, + .find_point = find_point_meas_new, .begin_drag_new = begin_drag_new_meas, .drag_new = drag_new_line, .end_new = end_new_meas, + .cancel_drag_new= cancel_drag_new_meas, }; struct tool_ops tool_meas_ops_x = { .tool_selected = tool_selected_meas_x, .tool_deselected= tool_deselected_meas, - .find_point = find_point_meas, + .find_point = find_point_meas_new, .begin_drag_new = begin_drag_new_meas, .drag_new = drag_new_line, .end_new = end_new_meas, + .cancel_drag_new= cancel_drag_new_meas, }; struct tool_ops tool_meas_ops_y = { .tool_selected = tool_selected_meas_y, .tool_deselected= tool_deselected_meas, - .find_point = find_point_meas, + .find_point = find_point_meas_new, .begin_drag_new = begin_drag_new_meas, .drag_new = drag_new_line, .end_new = end_new_meas, + .cancel_drag_new= cancel_drag_new_meas, }; diff --git a/gui_meas.h b/gui_meas.h index 23b903a..e626221 100644 --- a/gui_meas.h +++ b/gui_meas.h @@ -23,5 +23,8 @@ extern struct tool_ops tool_meas_ops_y; void begin_drag_move_meas(struct inst *inst, int i); +struct inst *find_point_meas_move(struct inst *inst, struct coord pos); +void end_drag_move_meas(void); +void do_move_to_meas(struct inst *inst, struct inst *to, int i); #endif /* !GUI_MEAS_H */ diff --git a/gui_tool.c b/gui_tool.c index 5255cc5..a8eb998 100644 --- a/gui_tool.c +++ b/gui_tool.c @@ -457,8 +457,9 @@ struct pix_buf *draw_move_arc(struct inst *inst, struct coord pos, int i) } -void do_move_to_arc(struct inst *inst, struct vec *vec, int i) +void do_move_to_arc(struct inst *inst, struct inst *to, int i) { + struct vec *vec = inst_get_vec(to); struct obj *obj = inst->obj; int is_circle; @@ -591,6 +592,7 @@ static struct tool_ops frame_ops = { /* ----- moving references ------------------------------------------------- */ +#if 0 static int may_move(struct inst *curr) { if (!selected_inst) @@ -605,6 +607,7 @@ static int may_move(struct inst *curr) drag.anchors_n = 0; return 0; } +#endif static int would_be_equal(const struct drag_state *state, @@ -642,7 +645,7 @@ static int may_move_to(const struct drag_state *state, struct inst *curr) static void do_move_to(struct drag_state *state, struct inst *curr) { - assert(may_move_to(state, curr)); + assert(state->inst->ops->find_point || may_move_to(state, curr)); *state->anchors[state->anchor_i] = inst_get_vec(curr); } @@ -665,14 +668,60 @@ void tool_dehover(void) } +/* + * When hovering, we have to consider the following states: + * + * selected (selected_inst != NULL) + * | dragging new (drag.new != NULL) + * | | dragging existing (drag.anchors_n != 0) + * | | | tool selected (active_ops) + * | | | | + * Y N N N highlight if inst_find_point_selected else don't + * Y N N Y highlight if inst_find_point_selected else fall over to tool + * - Y N - highlight if inst_find_point / active_ops->find_point else don't + * - N Y - highlight if may_move_to else don't + * - Y Y - invalid state + * N N N Y highlight if inst_find_point / active_ops->find_point else don't + * N N N N don't highlight + */ + +static struct inst *get_hover_inst(struct coord pos) +{ + struct inst *inst; + int i; + + if (drag.new) { + if (active_ops->find_point) + return active_ops->find_point(pos); + return inst_find_point(pos); + } + if (drag.anchors_n) { + if (drag.inst->ops->find_point) + return drag.inst->ops->find_point(drag.inst, pos); + inst = inst_find_point(pos); + if (!inst) + return NULL; + return may_move_to(&drag, inst) ? inst : NULL; + } + if (selected_inst) { + i = inst_find_point_selected(pos, &inst); + if (i != -1) + return inst; + } + if (!active_ops) + return NULL; + if (active_ops->find_point) + return active_ops->find_point(pos); + return inst_find_point(pos); +} + + void tool_hover(struct coord pos) { - struct inst *curr; + struct inst *curr = NULL; - if (active_ops && active_ops->find_point) - curr = active_ops->find_point(pos); - else - curr = inst_find_point(pos); + curr = get_hover_inst(pos); +#if 0 if ((drag.new && curr == drag.new) || (drag.inst && curr == drag.inst)) return; if (curr && !active_ops) { @@ -685,6 +734,9 @@ void tool_hover(struct coord pos) drag.anchors_n = 0; } } +got: +#endif + if (curr == hover_inst) return; if (hover_inst) { @@ -712,6 +764,17 @@ static struct pix_buf *drag_save_and_draw(void *user, struct coord to) } +/* + * When considering dragging, we have the following states: + * + * selected (selected_inst != NULL) + * | tool selected (active_ops) + * | | + * N N don't + * Y - if we could drag, drag_new/end_new, else fall over to tool + * N Y click, else single-click creation, else drag_new/end_new + */ + int tool_consider_drag(struct coord pos) { struct inst *curr; @@ -719,41 +782,51 @@ int tool_consider_drag(struct coord pos) assert(!drag.new); assert(!drag.anchors_n); last_canvas_pos = translate(pos); - if (active_ops && active_ops->click) { + + if (!selected_inst && !active_ops) + return 0; + if (selected_inst) { + drag.anchor_i = inst_find_point_selected(pos, NULL); + if (drag.anchor_i != -1) { + tool_dehover(); + drag.inst = selected_inst; + drag.new = NULL; + drag.anchors_n = + inst_anchors(selected_inst, drag.anchors); + over_begin(drag_save_and_draw, NULL, pos); + inst_begin_drag_move(selected_inst, drag.anchor_i); + return 1; + } + } + if (!active_ops) + return 0; + if (active_ops->click) { active_ops->click(pos); return 0; } - if (active_ops && active_ops->find_point) - curr = active_ops->find_point(pos); - else - curr = inst_find_point(pos); + + curr = get_hover_inst(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); - return 1; - } else { - /* object is created without dragging */ - if (active_ops->end_new(curr, NULL)) { - tool_cancel_drag(); - return -1; - } - return 0; - } + + 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); + return 1; } - if (!may_move(curr)) - return 0; - drag.inst = selected_inst; - drag.new = NULL; - inst_begin_drag_move(selected_inst, drag.anchor_i); - over_begin(drag_save_and_draw, NULL, pos); - return 1; + + /* object is created without dragging */ + if (active_ops->end_new(curr, NULL)) { + tool_cancel_drag(); + return -1; + } + return 0; + } @@ -766,12 +839,15 @@ void tool_drag(struct coord to) void tool_cancel_drag(void) { - over_end(); - tool_dehover(); - tool_reset(); + if (drag.anchors_n && drag.inst->ops->end_drag_move) + if (drag.anchors_n && drag.inst->ops->end_drag_move) + drag.inst->ops->end_drag_move(); drag.new = NULL; active_ops = NULL; drag.anchors_n = 0; + over_end(); + tool_dehover(); + tool_reset(); } @@ -784,17 +860,26 @@ 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); - if (ops->find_point) + if (state.new && ops->find_point) end = ops->find_point(to); - else - end = inst_find_point(to); - if (!end) + else { + if (state.inst && state.inst->ops->find_point) + end = state.inst->ops->find_point(state.inst, to); + else + end = inst_find_point(to); + } + if (!end) { + if (state.new && ops->cancel_drag_new) + ops->cancel_drag_new(); return 0; + } if (state.new) return ops->end_new(state.new, end); - if (!may_move_to(&state, end)) + + /* if we got the point from find_point, it's authoritative */ + if (!state.inst->ops->find_point && !may_move_to(&state, end)) return 0; - if (!inst_do_move_to(drag.inst, inst_get_vec(end), state.anchor_i)) + if (!inst_do_move_to(state.inst, end, state.anchor_i)) do_move_to(&state, end); return 1; } @@ -802,12 +887,15 @@ int tool_end_drag(struct coord to) void tool_redraw(void) { + struct coord pos; + over_reset(); + hover_inst = NULL; if (!drag.new && !drag.anchors_n) return; - tool_hover(last_canvas_pos); - over_begin(drag_save_and_draw, NULL, - canvas_to_coord(last_canvas_pos.x, last_canvas_pos.y)); + pos = canvas_to_coord(last_canvas_pos.x, last_canvas_pos.y); + tool_hover(pos); + over_begin(drag_save_and_draw, NULL, pos); } @@ -837,6 +925,7 @@ static void tool_select(GtkWidget *evbox, struct tool_ops *ops) void tool_reset(void) { over_reset(); + hover_inst = NULL; tool_select(ev_point, NULL); } diff --git a/gui_tool.h b/gui_tool.h index 061cc20..66bfc92 100644 --- a/gui_tool.h +++ b/gui_tool.h @@ -28,6 +28,7 @@ struct tool_ops { 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); + void (*cancel_drag_new)(void); }; @@ -42,7 +43,7 @@ struct pix_buf *draw_move_frame(struct inst *inst, struct coord pos, int i); struct pix_buf *gui_hover_vec(struct inst *self); struct pix_buf *gui_hover_frame(struct inst *self); -void do_move_to_arc(struct inst *inst, struct vec *vec, int i); +void do_move_to_arc(struct inst *inst, struct inst *to, int i); void tool_dehover(void); void tool_hover(struct coord pos); diff --git a/inst.c b/inst.c index aaafacb..71afb84 100644 --- a/inst.c +++ b/inst.c @@ -29,22 +29,6 @@ #include "inst.h" -struct inst_ops { - void (*debug)(struct inst *self); - void (*save)(FILE *file, struct inst *self); - void (*draw)(struct inst *self); - struct pix_buf *(*hover)(struct inst *self); - unit_type (*distance)(struct inst *self, struct coord pos, - unit_type scale); - void (*select)(struct inst *self); - int (*anchors)(struct inst *self, struct vec ***anchors); - void (*begin_drag_move)(struct inst *from, int i); - struct pix_buf *(*draw_move)(struct inst *inst, - struct coord pos, int i); - /* arcs and measurements need this special override */ - void (*do_move_to)(struct inst *inst, struct vec *vec, int i); -}; - enum inst_prio { ip_frame, /* frames have their own selection */ ip_pad, /* pads also accept clicks inside */ @@ -235,6 +219,49 @@ struct inst *inst_find_point(struct coord pos) } +int inst_find_point_selected(struct coord pos, struct inst **res) +{ + struct vec **anchors[3]; + int n, best_i, i; + struct inst *best = NULL; + struct inst *inst; + int d_min, d; + + assert(selected_inst); + n = inst_anchors(selected_inst, anchors); + for (i = 0; i != n; i++) { + if (*anchors[i]) { + for (inst = insts[ip_vec]; inst; inst = inst->next) { + if (inst->vec != *anchors[i]) + continue; + d = gui_dist_vec(inst, pos, draw_ctx.scale); + if (d != -1 && (!best || d < d_min)) { + best = inst; + best_i = i; + d_min = d; + } + } + } else { + for (inst = insts[ip_frame]; inst; inst = inst->next) { + if (inst != selected_inst->outer) + continue; + d = gui_dist_frame(inst, pos, draw_ctx.scale); + if (d != -1 && (!best || d < d_min)) { + best = inst; + best_i = i; + d_min = d; + } + } + } + } + if (!best) + return -1; + if (res) + *res = best; + return best_i; +} + + struct coord inst_get_point(const struct inst *inst) { if (inst->ops == &vec_ops) @@ -317,7 +344,6 @@ static void update_bbox(struct bbox *bbox, struct coord coord) static void propagate_bbox(const struct inst *inst) { - /* @@@ for new-style measurements */ struct inst *frame = curr_frame ? curr_frame : insts[ip_frame]; update_bbox(&frame->bbox, inst->bbox.min); @@ -388,6 +414,30 @@ static void vec_op_select(struct inst *self) } +/* + * @@@ The logic of gui_find_point_vec isn't great. Instead of selecting a + * point and then filtering, we should filter the candidates, so that a point + * that's close end eligible can win against one that's closer but not + * eligible. + */ + +static struct inst *find_point_vec(struct inst *self, struct coord pos) +{ + struct inst *inst; + const struct vec *vec; + + inst = inst_find_point(pos); + if (!inst) + return NULL; + if (inst->ops == &frame_ops) + return inst; + for (vec = inst->vec; vec; vec = vec->base) + if (vec == self->vec) + return NULL; + return inst; +} + + static int vec_op_anchors(struct inst *inst, struct vec ***anchors) { anchors[0] = &inst->vec->base; @@ -401,6 +451,7 @@ static struct inst_ops vec_ops = { .hover = gui_hover_vec, .distance = gui_dist_vec, .select = vec_op_select, + .find_point = find_point_vec, .anchors = vec_op_anchors, .draw_move = draw_move_vec, }; @@ -669,8 +720,6 @@ static void meas_op_select(struct inst *self) rect_status(self->bbox.min, self->bbox.max, -1); status_set_type_entry("offset ="); status_set_name("%5.2f mm", units_to_mm(self->u.meas.offset)); - if (!self->obj) - return; /* @@@ new-style measurements */ edit_expr(&self->obj->u.meas.offset); } @@ -692,7 +741,10 @@ static struct inst_ops meas_ops = { .select = meas_op_select, .anchors = meas_op_anchors, .begin_drag_move= begin_drag_move_meas, + .find_point = find_point_meas_move, .draw_move = draw_move_meas, + .end_drag_move = end_drag_move_meas, + .do_move_to = do_move_to_meas, }; @@ -911,11 +963,11 @@ 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) +int inst_do_move_to(struct inst *inst, struct inst *to, int i) { if (!inst->ops->do_move_to) return 0; - inst->ops->do_move_to(inst, vec, i); + inst->ops->do_move_to(inst, to, i); return 1; } diff --git a/inst.h b/inst.h index 033a03c..7471201 100644 --- a/inst.h +++ b/inst.h @@ -36,7 +36,25 @@ struct bbox { struct coord max; }; -struct inst_ops; +struct inst; + +struct inst_ops { + void (*debug)(struct inst *self); + void (*save)(FILE *file, struct inst *self); + void (*draw)(struct inst *self); + struct pix_buf *(*hover)(struct inst *self); + unit_type (*distance)(struct inst *self, struct coord pos, + unit_type scale); + void (*select)(struct inst *self); + int (*anchors)(struct inst *self, struct vec ***anchors); + void (*begin_drag_move)(struct inst *from, int i); + struct inst *(*find_point)(struct inst *self, struct coord pos); + struct pix_buf *(*draw_move)(struct inst *inst, + struct coord pos, int i); + void (*end_drag_move)(void); + /* arcs and measurements need this special override */ + void (*do_move_to)(struct inst *inst, struct inst *to, int i); +}; struct inst { const struct inst_ops *ops; @@ -85,6 +103,7 @@ int inst_select(struct coord pos); void inst_deselect(void); struct inst *inst_find_point(struct coord pos); +int inst_find_point_selected(struct coord pos, struct inst **res); struct coord inst_get_point(const struct inst *inst); int inst_anchors(struct inst *inst, struct vec ***anchors); struct vec *inst_get_vec(const struct inst *inst); @@ -119,7 +138,7 @@ struct inst *inst_find_vec(struct coord pos, 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); +int inst_do_move_to(struct inst *inst, struct inst *to, int i); struct pix_buf *inst_hover(struct inst *inst); void inst_begin_drag_move(struct inst *inst, int i); void inst_delete(struct inst *inst); diff --git a/meas.c b/meas.c index 79f8e08..51e6282 100644 --- a/meas.c +++ b/meas.c @@ -23,11 +23,6 @@ struct num eval_unit(const struct expr *expr, const struct frame *frame); -struct sample { - struct coord pos; - struct sample *next; -}; - static void reset_samples(struct sample **samples) { diff --git a/meas.h b/meas.h index b32142b..5ff7913 100644 --- a/meas.h +++ b/meas.h @@ -41,7 +41,10 @@ struct meas { struct expr *offset; }; -struct sample; +struct sample { + struct coord pos; + struct sample *next; +}; int lt_x(struct coord a, struct coord b);