mirror of
git://projects.qi-hardware.com/fped.git
synced 2024-11-22 07:30:16 +02:00
- File>Save now saves to a file if a second name is given on the command line,
to stdout if not - there's no reason anymore to disallow editing the offset in new-style measurements - struct inst_ops is no longer opaque, so we can avoid adding even more silly little access functions and open-code straightforward callbacks - (re)stuctured hover/click/drag logic in gui_tool.c - added optional debugging output to gui_canvas.c - don't let a vector's base be dragged onto the vector's own end or onto one of its children - measurements can now be properly changed by dragging git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5414 99fdad57-331a-0410-800a-d7fa5415bdb3
This commit is contained in:
parent
75d9780131
commit
9c68c0de34
5
TODO
5
TODO
@ -2,8 +2,6 @@ Major missing features:
|
|||||||
- populate input area (still needed: mm/mil, rezoom)
|
- populate input area (still needed: mm/mil, rezoom)
|
||||||
- add default unit (combine with grid unit selection ?)
|
- add default unit (combine with grid unit selection ?)
|
||||||
- consider adding auto/mm/mil selection for each dimension
|
- 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 KiCad output
|
||||||
- add postscript output
|
- add postscript output
|
||||||
- add option to include/omit helper vecs and frames (done for display, still
|
- 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 edit_unique with edit_name
|
||||||
- merge find_var_in_frame with similar mechanisms in expr.c and fpd.y
|
- merge find_var_in_frame with similar mechanisms in expr.c and fpd.y
|
||||||
- add regression tests
|
- 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:
|
Open decisions:
|
||||||
- Q: should loop be (start, last) or (start, iterations) ? or start ... last ?
|
- Q: should loop be (start, last) or (start, iterations) ? or start ... last ?
|
||||||
|
26
fped.c
26
fped.c
@ -11,6 +11,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "cpp.h"
|
#include "cpp.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@ -23,6 +25,8 @@
|
|||||||
extern void scan_empty(void);
|
extern void scan_empty(void);
|
||||||
extern int yyparse(void);
|
extern int yyparse(void);
|
||||||
|
|
||||||
|
char *save_file = NULL;
|
||||||
|
|
||||||
|
|
||||||
static void load_file(const char *name)
|
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)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
const char *name = *argv;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
error = gui_init(&argc, &argv);
|
error = gui_init(&argc, &argv);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
if (argc == 1) {
|
switch (argc) {
|
||||||
|
case 1:
|
||||||
scan_empty();
|
scan_empty();
|
||||||
(void) yyparse();
|
(void) yyparse();
|
||||||
} else {
|
break;
|
||||||
|
case 3:
|
||||||
|
save_file = argv[2];
|
||||||
|
/* fall through */
|
||||||
|
case 2:
|
||||||
load_file(argv[1]);
|
load_file(argv[1]);
|
||||||
argc--;
|
break;
|
||||||
argv++;
|
default:
|
||||||
|
usage(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!part_name)
|
if (!part_name)
|
||||||
|
20
gui.c
20
gui.c
@ -11,6 +11,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
#include "inst.h"
|
#include "inst.h"
|
||||||
@ -30,6 +31,8 @@
|
|||||||
#include "icons/meas_off.xpm"
|
#include "icons/meas_off.xpm"
|
||||||
|
|
||||||
|
|
||||||
|
extern char *save_file;
|
||||||
|
|
||||||
GtkWidget *root;
|
GtkWidget *root;
|
||||||
int show_stuff = 1;
|
int show_stuff = 1;
|
||||||
int show_meas = 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)
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
15
gui_canvas.c
15
gui_canvas.c
@ -27,6 +27,13 @@
|
|||||||
#include "gui_canvas.h"
|
#include "gui_canvas.h"
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#define DPRINTF(fmt, ...) fprintf(stderr, fmt "\n", ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define DPRINTF(fmt, ...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void (*highlight)(void) = NULL;
|
void (*highlight)(void) = NULL;
|
||||||
|
|
||||||
static struct coord curr_pos;
|
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);
|
struct coord pos = canvas_to_coord(event->x, event->y);
|
||||||
|
|
||||||
|
DPRINTF("--- motion ---");
|
||||||
curr_pos.x = event->x;
|
curr_pos.x = event->x;
|
||||||
curr_pos.y = event->y;
|
curr_pos.y = event->y;
|
||||||
tool_hover(pos);
|
tool_hover(pos);
|
||||||
@ -161,6 +169,7 @@ static gboolean button_press_event(GtkWidget *widget, GdkEventButton *event,
|
|||||||
const struct inst *prev;
|
const struct inst *prev;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
DPRINTF("--- button press ---");
|
||||||
gtk_widget_grab_focus(widget);
|
gtk_widget_grab_focus(widget);
|
||||||
switch (event->button) {
|
switch (event->button) {
|
||||||
case 1:
|
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);
|
struct coord pos = canvas_to_coord(event->x, event->y);
|
||||||
|
|
||||||
|
DPRINTF("--- button release ---");
|
||||||
switch (event->button) {
|
switch (event->button) {
|
||||||
case 1:
|
case 1:
|
||||||
if (!dragging)
|
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);
|
struct coord pos = canvas_to_coord(curr_pos.x, curr_pos.y);
|
||||||
|
|
||||||
|
DPRINTF("--- key press ---");
|
||||||
switch (event->keyval) {
|
switch (event->keyval) {
|
||||||
case ' ':
|
case ' ':
|
||||||
user_origin = pos;
|
user_origin = pos;
|
||||||
@ -350,10 +361,13 @@ static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event,
|
|||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
static int first = 1;
|
static int first = 1;
|
||||||
|
|
||||||
|
DPRINTF("--- expose ---");
|
||||||
if (first) {
|
if (first) {
|
||||||
init_canvas();
|
init_canvas();
|
||||||
first = 0;
|
first = 0;
|
||||||
}
|
}
|
||||||
|
tool_dehover();
|
||||||
redraw();
|
redraw();
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -373,6 +387,7 @@ static gboolean enter_notify_event(GtkWidget *widget, GdkEventCrossing *event,
|
|||||||
static gboolean leave_notify_event(GtkWidget *widget, GdkEventCrossing *event,
|
static gboolean leave_notify_event(GtkWidget *widget, GdkEventCrossing *event,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
|
DPRINTF("--- leave ---");
|
||||||
if (dragging)
|
if (dragging)
|
||||||
tool_cancel_drag();
|
tool_cancel_drag();
|
||||||
tool_dehover();
|
tool_dehover();
|
||||||
|
95
gui_meas.c
95
gui_meas.c
@ -12,7 +12,9 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "coord.h"
|
||||||
#include "meas.h"
|
#include "meas.h"
|
||||||
|
#include "inst.h"
|
||||||
#include "gui_canvas.h"
|
#include "gui_canvas.h"
|
||||||
#include "gui_tool.h"
|
#include "gui_tool.h"
|
||||||
#include "gui_meas.h"
|
#include "gui_meas.h"
|
||||||
@ -153,7 +155,10 @@ static int meas_pick_vec_b(struct inst *inst, void *ctx)
|
|||||||
case max_to_min:
|
case max_to_min:
|
||||||
return is_min(meas_dsc->lt, inst);
|
return is_min(meas_dsc->lt, inst);
|
||||||
case next_to_min:
|
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:
|
default:
|
||||||
abort();
|
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)
|
if (meas_inst)
|
||||||
return inst_find_vec(pos, meas_pick_vec_b, 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;
|
struct meas *meas;
|
||||||
|
|
||||||
meas_inst = NULL;
|
meas_inst = NULL;
|
||||||
|
highlight = NULL;
|
||||||
if (from == to)
|
if (from == to)
|
||||||
return 0;
|
return 0;
|
||||||
/* it's safe to pass "from" here, but we may change it later */
|
/* it's safe to pass "from" here, but we may change it later */
|
||||||
@ -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 ------------------------------- */
|
/* ----- 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)
|
void begin_drag_move_meas(struct inst *inst, int i)
|
||||||
{
|
{
|
||||||
const struct meas *meas = &inst->obj->u.meas;
|
const struct meas *meas = &inst->obj->u.meas;
|
||||||
@ -328,49 +361,93 @@ void begin_drag_move_meas(struct inst *inst, int i)
|
|||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
highlight = meas_highlight_b;
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 0:
|
case 0:
|
||||||
highlight = meas_highlight_a;
|
|
||||||
mode = meas->type < 3 ? next_to_min : max_to_min;
|
mode = meas->type < 3 ? next_to_min : max_to_min;
|
||||||
|
meas_inst = vec_at(inst->obj->u.meas.high, inst->u.meas.end);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
highlight = meas_highlight_b;
|
|
||||||
mode = min_to_next_or_max;
|
mode = min_to_next_or_max;
|
||||||
|
meas_inst = vec_at(inst->obj->base, inst->base);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
abort();
|
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();
|
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 = {
|
struct tool_ops tool_meas_ops = {
|
||||||
.tool_selected = tool_selected_meas_xy,
|
.tool_selected = tool_selected_meas_xy,
|
||||||
.tool_deselected= tool_deselected_meas,
|
.tool_deselected= tool_deselected_meas,
|
||||||
.find_point = find_point_meas,
|
.find_point = find_point_meas_new,
|
||||||
.begin_drag_new = begin_drag_new_meas,
|
.begin_drag_new = begin_drag_new_meas,
|
||||||
.drag_new = drag_new_line,
|
.drag_new = drag_new_line,
|
||||||
.end_new = end_new_meas,
|
.end_new = end_new_meas,
|
||||||
|
.cancel_drag_new= cancel_drag_new_meas,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tool_ops tool_meas_ops_x = {
|
struct tool_ops tool_meas_ops_x = {
|
||||||
.tool_selected = tool_selected_meas_x,
|
.tool_selected = tool_selected_meas_x,
|
||||||
.tool_deselected= tool_deselected_meas,
|
.tool_deselected= tool_deselected_meas,
|
||||||
.find_point = find_point_meas,
|
.find_point = find_point_meas_new,
|
||||||
.begin_drag_new = begin_drag_new_meas,
|
.begin_drag_new = begin_drag_new_meas,
|
||||||
.drag_new = drag_new_line,
|
.drag_new = drag_new_line,
|
||||||
.end_new = end_new_meas,
|
.end_new = end_new_meas,
|
||||||
|
.cancel_drag_new= cancel_drag_new_meas,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct tool_ops tool_meas_ops_y = {
|
struct tool_ops tool_meas_ops_y = {
|
||||||
.tool_selected = tool_selected_meas_y,
|
.tool_selected = tool_selected_meas_y,
|
||||||
.tool_deselected= tool_deselected_meas,
|
.tool_deselected= tool_deselected_meas,
|
||||||
.find_point = find_point_meas,
|
.find_point = find_point_meas_new,
|
||||||
.begin_drag_new = begin_drag_new_meas,
|
.begin_drag_new = begin_drag_new_meas,
|
||||||
.drag_new = drag_new_line,
|
.drag_new = drag_new_line,
|
||||||
.end_new = end_new_meas,
|
.end_new = end_new_meas,
|
||||||
|
.cancel_drag_new= cancel_drag_new_meas,
|
||||||
};
|
};
|
||||||
|
@ -23,5 +23,8 @@ extern struct tool_ops tool_meas_ops_y;
|
|||||||
|
|
||||||
|
|
||||||
void begin_drag_move_meas(struct inst *inst, int i);
|
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 */
|
#endif /* !GUI_MEAS_H */
|
||||||
|
155
gui_tool.c
155
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;
|
struct obj *obj = inst->obj;
|
||||||
int is_circle;
|
int is_circle;
|
||||||
|
|
||||||
@ -591,6 +592,7 @@ static struct tool_ops frame_ops = {
|
|||||||
/* ----- moving references ------------------------------------------------- */
|
/* ----- moving references ------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
static int may_move(struct inst *curr)
|
static int may_move(struct inst *curr)
|
||||||
{
|
{
|
||||||
if (!selected_inst)
|
if (!selected_inst)
|
||||||
@ -605,6 +607,7 @@ static int may_move(struct inst *curr)
|
|||||||
drag.anchors_n = 0;
|
drag.anchors_n = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static int would_be_equal(const struct drag_state *state,
|
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)
|
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);
|
*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)
|
void tool_hover(struct coord pos)
|
||||||
{
|
{
|
||||||
struct inst *curr;
|
struct inst *curr = NULL;
|
||||||
|
|
||||||
if (active_ops && active_ops->find_point)
|
curr = get_hover_inst(pos);
|
||||||
curr = active_ops->find_point(pos);
|
#if 0
|
||||||
else
|
|
||||||
curr = inst_find_point(pos);
|
|
||||||
if ((drag.new && curr == drag.new) || (drag.inst && curr == drag.inst))
|
if ((drag.new && curr == drag.new) || (drag.inst && curr == drag.inst))
|
||||||
return;
|
return;
|
||||||
if (curr && !active_ops) {
|
if (curr && !active_ops) {
|
||||||
@ -685,6 +734,9 @@ void tool_hover(struct coord pos)
|
|||||||
drag.anchors_n = 0;
|
drag.anchors_n = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
got:
|
||||||
|
#endif
|
||||||
|
|
||||||
if (curr == hover_inst)
|
if (curr == hover_inst)
|
||||||
return;
|
return;
|
||||||
if (hover_inst) {
|
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)
|
int tool_consider_drag(struct coord pos)
|
||||||
{
|
{
|
||||||
struct inst *curr;
|
struct inst *curr;
|
||||||
@ -719,18 +782,35 @@ int tool_consider_drag(struct coord pos)
|
|||||||
assert(!drag.new);
|
assert(!drag.new);
|
||||||
assert(!drag.anchors_n);
|
assert(!drag.anchors_n);
|
||||||
last_canvas_pos = translate(pos);
|
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);
|
active_ops->click(pos);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (active_ops && active_ops->find_point)
|
|
||||||
curr = active_ops->find_point(pos);
|
curr = get_hover_inst(pos);
|
||||||
else
|
|
||||||
curr = inst_find_point(pos);
|
|
||||||
if (!curr)
|
if (!curr)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
tool_dehover();
|
tool_dehover();
|
||||||
if (active_ops) {
|
|
||||||
if (active_ops->drag_new) {
|
if (active_ops->drag_new) {
|
||||||
if (active_ops->begin_drag_new)
|
if (active_ops->begin_drag_new)
|
||||||
active_ops->begin_drag_new(curr);
|
active_ops->begin_drag_new(curr);
|
||||||
@ -738,22 +818,15 @@ int tool_consider_drag(struct coord pos)
|
|||||||
drag.new = curr;
|
drag.new = curr;
|
||||||
over_begin(drag_save_and_draw, NULL, pos);
|
over_begin(drag_save_and_draw, NULL, pos);
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
}
|
||||||
|
|
||||||
/* object is created without dragging */
|
/* object is created without dragging */
|
||||||
if (active_ops->end_new(curr, NULL)) {
|
if (active_ops->end_new(curr, NULL)) {
|
||||||
tool_cancel_drag();
|
tool_cancel_drag();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -766,12 +839,15 @@ void tool_drag(struct coord to)
|
|||||||
|
|
||||||
void tool_cancel_drag(void)
|
void tool_cancel_drag(void)
|
||||||
{
|
{
|
||||||
over_end();
|
if (drag.anchors_n && drag.inst->ops->end_drag_move)
|
||||||
tool_dehover();
|
if (drag.anchors_n && drag.inst->ops->end_drag_move)
|
||||||
tool_reset();
|
drag.inst->ops->end_drag_move();
|
||||||
drag.new = NULL;
|
drag.new = NULL;
|
||||||
active_ops = NULL;
|
active_ops = NULL;
|
||||||
drag.anchors_n = 0;
|
drag.anchors_n = 0;
|
||||||
|
over_end();
|
||||||
|
tool_dehover();
|
||||||
|
tool_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -784,17 +860,26 @@ int tool_end_drag(struct coord to)
|
|||||||
tool_cancel_drag();
|
tool_cancel_drag();
|
||||||
if (state.new && ops->end_new_raw)
|
if (state.new && ops->end_new_raw)
|
||||||
return ops->end_new_raw(state.new, to);
|
return ops->end_new_raw(state.new, to);
|
||||||
if (ops->find_point)
|
if (state.new && ops->find_point)
|
||||||
end = ops->find_point(to);
|
end = ops->find_point(to);
|
||||||
|
else {
|
||||||
|
if (state.inst && state.inst->ops->find_point)
|
||||||
|
end = state.inst->ops->find_point(state.inst, to);
|
||||||
else
|
else
|
||||||
end = inst_find_point(to);
|
end = inst_find_point(to);
|
||||||
if (!end)
|
}
|
||||||
|
if (!end) {
|
||||||
|
if (state.new && ops->cancel_drag_new)
|
||||||
|
ops->cancel_drag_new();
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
if (state.new)
|
if (state.new)
|
||||||
return ops->end_new(state.new, end);
|
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;
|
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);
|
do_move_to(&state, end);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -802,12 +887,15 @@ int tool_end_drag(struct coord to)
|
|||||||
|
|
||||||
void tool_redraw(void)
|
void tool_redraw(void)
|
||||||
{
|
{
|
||||||
|
struct coord pos;
|
||||||
|
|
||||||
over_reset();
|
over_reset();
|
||||||
|
hover_inst = NULL;
|
||||||
if (!drag.new && !drag.anchors_n)
|
if (!drag.new && !drag.anchors_n)
|
||||||
return;
|
return;
|
||||||
tool_hover(last_canvas_pos);
|
pos = canvas_to_coord(last_canvas_pos.x, last_canvas_pos.y);
|
||||||
over_begin(drag_save_and_draw, NULL,
|
tool_hover(pos);
|
||||||
canvas_to_coord(last_canvas_pos.x, last_canvas_pos.y));
|
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)
|
void tool_reset(void)
|
||||||
{
|
{
|
||||||
over_reset();
|
over_reset();
|
||||||
|
hover_inst = NULL;
|
||||||
tool_select(ev_point, NULL);
|
tool_select(ev_point, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ struct tool_ops {
|
|||||||
struct pix_buf *(*drag_new)(struct inst *from, struct coord to);
|
struct pix_buf *(*drag_new)(struct inst *from, struct coord to);
|
||||||
int (*end_new_raw)(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);
|
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_vec(struct inst *self);
|
||||||
struct pix_buf *gui_hover_frame(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_dehover(void);
|
||||||
void tool_hover(struct coord pos);
|
void tool_hover(struct coord pos);
|
||||||
|
94
inst.c
94
inst.c
@ -29,22 +29,6 @@
|
|||||||
#include "inst.h"
|
#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 {
|
enum inst_prio {
|
||||||
ip_frame, /* frames have their own selection */
|
ip_frame, /* frames have their own selection */
|
||||||
ip_pad, /* pads also accept clicks inside */
|
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)
|
struct coord inst_get_point(const struct inst *inst)
|
||||||
{
|
{
|
||||||
if (inst->ops == &vec_ops)
|
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)
|
static void propagate_bbox(const struct inst *inst)
|
||||||
{
|
{
|
||||||
/* @@@ for new-style measurements */
|
|
||||||
struct inst *frame = curr_frame ? curr_frame : insts[ip_frame];
|
struct inst *frame = curr_frame ? curr_frame : insts[ip_frame];
|
||||||
|
|
||||||
update_bbox(&frame->bbox, inst->bbox.min);
|
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)
|
static int vec_op_anchors(struct inst *inst, struct vec ***anchors)
|
||||||
{
|
{
|
||||||
anchors[0] = &inst->vec->base;
|
anchors[0] = &inst->vec->base;
|
||||||
@ -401,6 +451,7 @@ static struct inst_ops vec_ops = {
|
|||||||
.hover = gui_hover_vec,
|
.hover = gui_hover_vec,
|
||||||
.distance = gui_dist_vec,
|
.distance = gui_dist_vec,
|
||||||
.select = vec_op_select,
|
.select = vec_op_select,
|
||||||
|
.find_point = find_point_vec,
|
||||||
.anchors = vec_op_anchors,
|
.anchors = vec_op_anchors,
|
||||||
.draw_move = draw_move_vec,
|
.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);
|
rect_status(self->bbox.min, self->bbox.max, -1);
|
||||||
status_set_type_entry("offset =");
|
status_set_type_entry("offset =");
|
||||||
status_set_name("%5.2f mm", units_to_mm(self->u.meas.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);
|
edit_expr(&self->obj->u.meas.offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -692,7 +741,10 @@ static struct inst_ops meas_ops = {
|
|||||||
.select = meas_op_select,
|
.select = meas_op_select,
|
||||||
.anchors = meas_op_anchors,
|
.anchors = meas_op_anchors,
|
||||||
.begin_drag_move= begin_drag_move_meas,
|
.begin_drag_move= begin_drag_move_meas,
|
||||||
|
.find_point = find_point_meas_move,
|
||||||
.draw_move = draw_move_meas,
|
.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)
|
if (!inst->ops->do_move_to)
|
||||||
return 0;
|
return 0;
|
||||||
inst->ops->do_move_to(inst, vec, i);
|
inst->ops->do_move_to(inst, to, i);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
23
inst.h
23
inst.h
@ -36,7 +36,25 @@ struct bbox {
|
|||||||
struct coord max;
|
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 {
|
struct inst {
|
||||||
const struct inst_ops *ops;
|
const struct inst_ops *ops;
|
||||||
@ -85,6 +103,7 @@ int inst_select(struct coord pos);
|
|||||||
void inst_deselect(void);
|
void inst_deselect(void);
|
||||||
|
|
||||||
struct inst *inst_find_point(struct coord pos);
|
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);
|
struct coord inst_get_point(const struct inst *inst);
|
||||||
int inst_anchors(struct inst *inst, struct vec ***anchors);
|
int inst_anchors(struct inst *inst, struct vec ***anchors);
|
||||||
struct vec *inst_get_vec(const struct inst *inst);
|
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 inst *insts_ip_vec(void);
|
||||||
|
|
||||||
struct pix_buf *inst_draw_move(struct inst *inst, struct coord pos, int i);
|
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);
|
struct pix_buf *inst_hover(struct inst *inst);
|
||||||
void inst_begin_drag_move(struct inst *inst, int i);
|
void inst_begin_drag_move(struct inst *inst, int i);
|
||||||
void inst_delete(struct inst *inst);
|
void inst_delete(struct inst *inst);
|
||||||
|
5
meas.c
5
meas.c
@ -23,11 +23,6 @@
|
|||||||
|
|
||||||
struct num eval_unit(const struct expr *expr, const struct frame *frame);
|
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)
|
static void reset_samples(struct sample **samples)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user