From 75d9780131984fff3d01935fe8dc2f6564aef8b3 Mon Sep 17 00:00:00 2001 From: werner Date: Sun, 9 Aug 2009 01:51:20 +0000 Subject: [PATCH] - band-aid: make canvas grab focus on click and scroll, so that it's easy to get it back when we lose it - improved heuristics for measx/measy: instead of looking for "next" or "max" on secondary coordinate, pick the one that's closest. I.e., if there's a chance to just connect with x' = 0 or y' = 0, do it. - mouse wheel on loop value now selects next/previous value - corrected proximity calculation for measurements - vec/frame/meas toggle now deselects, so that we don't accidently leave a supposedly hidden item selected git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5413 99fdad57-331a-0410-800a-d7fa5415bdb3 --- TODO | 1 + gui.c | 2 ++ gui_canvas.c | 2 ++ gui_frame.c | 29 +++++++++++++++++++++++ gui_inst.c | 66 ++++++++++++++++++++++++++++++---------------------- gui_meas.c | 44 +++++++++++++++++++++++++++++++---- gui_meas.h | 13 +++++++---- gui_tool.c | 7 +++--- gui_tool.h | 2 -- inst.c | 12 +++++++++- inst.h | 1 + meas.c | 28 ++++++++++++++++++---- 12 files changed, 160 insertions(+), 47 deletions(-) diff --git a/TODO b/TODO index cc662e4..5425f2a 100644 --- a/TODO +++ b/TODO @@ -29,6 +29,7 @@ Style: Bugs: - default silk width has no business being hard-coded in obj.c - undelete only works if not much has changed since the deletion +- focus should return to canvas if nobody else wants it Code cleanup: - merge edit_unique with edit_name diff --git a/gui.c b/gui.c index d6b91f6..a658f1c 100644 --- a/gui.c +++ b/gui.c @@ -82,6 +82,7 @@ static gboolean toggle_stuff(GtkWidget *widget, GdkEventButton *event, case 1: show_stuff = !show_stuff; set_image(ev_stuff, stuff_image[show_stuff]); + inst_deselect(); redraw(); break; } @@ -96,6 +97,7 @@ static gboolean toggle_meas(GtkWidget *widget, GdkEventButton *event, case 1: show_meas = !show_meas; set_image(ev_meas, meas_image[show_meas]); + inst_deselect(); redraw(); break; } diff --git a/gui_canvas.c b/gui_canvas.c index 56fb9ae..b3f213c 100644 --- a/gui_canvas.c +++ b/gui_canvas.c @@ -161,6 +161,7 @@ static gboolean button_press_event(GtkWidget *widget, GdkEventButton *event, const struct inst *prev; int res; + gtk_widget_grab_focus(widget); switch (event->button) { case 1: if (dragging) { @@ -267,6 +268,7 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event, { struct coord pos = canvas_to_coord(event->x, event->y); + gtk_widget_grab_focus(widget); switch (event->direction) { case GDK_SCROLL_UP: zoom_in(pos); diff --git a/gui_frame.c b/gui_frame.c index 01e89b1..7cd4194 100644 --- a/gui_frame.c +++ b/gui_frame.c @@ -799,6 +799,31 @@ static gboolean loop_select_event(GtkWidget *widget, GdkEventButton *event, } +static gboolean loop_scroll_event(GtkWidget *widget, GdkEventScroll *event, + gpointer data) +{ + struct loop *loop = data; + + switch (event->direction) { + case GDK_SCROLL_UP: + if (loop->active < loop->iterations-1) { + loop->active++; + change_world(); + } + break; + case GDK_SCROLL_DOWN: + if (loop->active) { + loop->active--; + change_world(); + } + break; + default: + /* ignore */; + } + return TRUE; +} + + static void build_loop(GtkWidget *vbox, struct frame *frame, struct loop *loop) { @@ -851,6 +876,10 @@ static void build_loop(GtkWidget *vbox, struct frame *frame, loop_select_event, loop, "%d", i); gtk_object_set_data(GTK_OBJECT(box_of_label(label)), "value", (gpointer) (long) i); + + g_signal_connect(G_OBJECT(box_of_label(label)), + "scroll_event", + G_CALLBACK(loop_scroll_event), loop); } gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(")"), diff --git a/gui_inst.c b/gui_inst.c index eccc178..0539b2f 100644 --- a/gui_inst.c +++ b/gui_inst.c @@ -340,50 +340,60 @@ static struct coord offset_vec(struct coord a, struct coord b, } -unit_type gui_dist_meas(struct inst *self, struct coord pos, unit_type scale) +static void project_meas(struct inst *inst, struct coord *a1, struct coord *b1) { - struct coord a, b, off; - unit_type d; + const struct meas *meas = &inst->obj->u.meas; + struct coord off; - off = offset_vec(self->base, self->u.meas.end, self); - a = add_vec(self->base, off); - b = add_vec(self->u.meas.end, off); - d = dist_line(pos, a, b)/scale; - return d > SELECT_R ? -1 : d; -} - - -void gui_draw_meas(struct inst *self) -{ - struct coord a0, b0, a1, b1, off, c, d; - GdkGC *gc; - double len; - const struct meas *meas = &self->obj->u.meas; - char *s; - - a0 = translate(self->base); - b0 = translate(self->u.meas.end); - a1 = self->base; - b1 = self->u.meas.end; + *a1 = inst->base; + *b1 = inst->u.meas.end; switch (meas->type) { case mt_xy_next: case mt_xy_max: break; case mt_x_next: case mt_x_max: - b1.y = a1.y; + b1->y = a1->y; break; case mt_y_next: case mt_y_max: - b1.x = a1.x; + b1->x = a1->x; break; default: abort(); } - off = offset_vec(a1, b1, self); + off = offset_vec(*a1, *b1, inst); + *a1 = add_vec(*a1, off); + *b1 = add_vec(*b1, off); +} + + +unit_type gui_dist_meas(struct inst *self, struct coord pos, unit_type scale) +{ + struct coord a1, b1; + unit_type d; + + project_meas(self, &a1, &b1); + d = dist_line(pos, a1, b1)/scale; + return d > SELECT_R ? -1 : d; +} + + +void gui_draw_meas(struct inst *self) +{ + const struct meas *meas = &self->obj->u.meas; + struct coord a0, b0, a1, b1, c, d; + GdkGC *gc; + double len; + char *s; + + a0 = translate(self->base); + b0 = translate(self->u.meas.end); + project_meas(self, &a1, &b1); + len = units_to_mm(dist_point(a1, b1)); - a1 = translate(add_vec(a1, off)); - b1 = translate(add_vec(b1, off)); + a1 = translate(a1); + b1 = translate(b1); gc = gc_meas[get_mode(self)]; gdk_draw_line(DA, gc, a0.x, a0.y, a1.x, a1.y); gdk_draw_line(DA, gc, b0.x, b0.y, b1.x, b1.y); diff --git a/gui_meas.c b/gui_meas.c index 9083b95..6e47eda 100644 --- a/gui_meas.c +++ b/gui_meas.c @@ -1,5 +1,5 @@ /* - * gui_meas.c - GUI, canvas overlays + * gui_meas.c - GUI, measurements * * Written 2009 by Werner Almesberger * Copyright 2009 by Werner Almesberger @@ -308,10 +308,46 @@ sm[mode], st[meas->type], meas->inverted); /* ----- begin dragging existing measurement ------------------------------- */ +void begin_drag_move_meas(struct inst *inst, int i) +{ + const struct meas *meas = &inst->obj->u.meas; + + switch (meas->type) { + case mt_xy_next: + case mt_xy_max: + meas_dsc = &meas_dsc_xy; + break; + case mt_x_next: + case mt_x_max: + meas_dsc = &meas_dsc_x; + break; + case mt_y_next: + case mt_y_max: + meas_dsc = &meas_dsc_y; + break; + default: + abort(); + } + switch (i) { + case 0: + highlight = meas_highlight_a; + mode = meas->type < 3 ? next_to_min : max_to_min; + break; + case 1: + highlight = meas_highlight_b; + mode = min_to_next_or_max; + break; + default: + abort(); + } + redraw(); +} + + /* ----- operations ------------------------------------------------------- */ -struct tool_ops meas_ops = { +struct tool_ops tool_meas_ops = { .tool_selected = tool_selected_meas_xy, .tool_deselected= tool_deselected_meas, .find_point = find_point_meas, @@ -320,7 +356,7 @@ struct tool_ops meas_ops = { .end_new = end_new_meas, }; -struct tool_ops meas_ops_x = { +struct tool_ops tool_meas_ops_x = { .tool_selected = tool_selected_meas_x, .tool_deselected= tool_deselected_meas, .find_point = find_point_meas, @@ -330,7 +366,7 @@ struct tool_ops meas_ops_x = { }; -struct tool_ops meas_ops_y = { +struct tool_ops tool_meas_ops_y = { .tool_selected = tool_selected_meas_y, .tool_deselected= tool_deselected_meas, .find_point = find_point_meas, diff --git a/gui_meas.h b/gui_meas.h index f9b33bb..23b903a 100644 --- a/gui_meas.h +++ b/gui_meas.h @@ -1,5 +1,5 @@ /* - * gui_meas.c - GUI, canvas overlays + * gui_meas.c - GUI, measurements * * Written 2009 by Werner Almesberger * Copyright 2009 by Werner Almesberger @@ -14,9 +14,14 @@ #ifndef GUI_MEAS_H #define GUI_MEAS_H +#include "gui_tool.h" -struct tool_ops meas_ops; -struct tool_ops meas_ops_x; -struct tool_ops meas_ops_y; + +extern struct tool_ops tool_meas_ops; +extern struct tool_ops tool_meas_ops_x; +extern struct tool_ops tool_meas_ops_y; + + +void begin_drag_move_meas(struct inst *inst, int i); #endif /* !GUI_MEAS_H */ diff --git a/gui_tool.c b/gui_tool.c index 6553c0e..5255cc5 100644 --- a/gui_tool.c +++ b/gui_tool.c @@ -751,6 +751,7 @@ int tool_consider_drag(struct coord pos) 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; } @@ -890,11 +891,11 @@ GtkWidget *gui_setup_tools(GdkDrawable *drawable) tool_button_press_event, &circ_ops); tool_separator(bar); tool_button(bar, drawable, xpm_meas, - tool_button_press_event, &meas_ops); + tool_button_press_event, &tool_meas_ops); tool_button(bar, drawable, xpm_meas_x, - tool_button_press_event, &meas_ops_x); + tool_button_press_event, &tool_meas_ops_x); tool_button(bar, drawable, xpm_meas_y, - tool_button_press_event, &meas_ops_y); + tool_button_press_event, &tool_meas_ops_y); frame_image = gtk_widget_ref(make_image(drawable, xpm_frame)); frame_image_locked = diff --git a/gui_tool.h b/gui_tool.h index 1e89cbf..061cc20 100644 --- a/gui_tool.h +++ b/gui_tool.h @@ -25,8 +25,6 @@ struct tool_ops { 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); diff --git a/inst.c b/inst.c index 2596c6b..aaafacb 100644 --- a/inst.c +++ b/inst.c @@ -23,6 +23,7 @@ #include "gui_util.h" #include "gui_status.h" #include "gui_tool.h" +#include "gui_meas.h" #include "gui_inst.h" #include "gui.h" #include "inst.h" @@ -37,9 +38,10 @@ struct inst_ops { 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 need this special override */ + /* arcs and measurements need this special override */ void (*do_move_to)(struct inst *inst, struct vec *vec, int i); }; @@ -689,6 +691,7 @@ static struct inst_ops meas_ops = { .distance = gui_dist_meas, .select = meas_op_select, .anchors = meas_op_anchors, + .begin_drag_move= begin_drag_move_meas, .draw_move = draw_move_meas, }; @@ -925,6 +928,13 @@ struct pix_buf *inst_hover(struct inst *inst) } +void inst_begin_drag_move(struct inst *inst, int i) +{ + if (inst->ops->begin_drag_move) + inst->ops->begin_drag_move(inst, i); +} + + void inst_delete(struct inst *inst) { if (inst->ops == &vec_ops) diff --git a/inst.h b/inst.h index efc3c82..033a03c 100644 --- a/inst.h +++ b/inst.h @@ -121,6 +121,7 @@ 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); +void inst_begin_drag_move(struct inst *inst, int i); void inst_delete(struct inst *inst); void inst_debug(void); diff --git a/meas.c b/meas.c index d254b3b..79f8e08 100644 --- a/meas.c +++ b/meas.c @@ -116,8 +116,26 @@ static int is_next[mt_n] = { /* ----- search functions -------------------------------------------------- */ +static int closer(int da, int db) +{ + int abs_a, abs_b; + + abs_a = da < 0 ? -da : da; + abs_b = db < 0 ? -db : db; + if (abs_a < abs_b) + return 1; + if (abs_a > abs_b) + return 0; + /* + * Really *all* other things being equal, pick the one that protrudes + * in the positive direction. + */ + return da > db; +} + + static int better_next(lt_op_type lt, - struct coord a0, struct coord b0, struct coord b, int recursing) + struct coord a0, struct coord b0, struct coord b) { /* if we don't have any suitable point A0 < B0 yet, use this one */ if (!lt(a0, b0)) @@ -140,12 +158,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 || recursing) + if (lt == lt_xy) return 0; if (lt == lt_x) - return better_next(lt_y, a0, b0, b, 1); + return closer(b.y-a0.y, b0.y-a0.y); if (lt == lt_y) - return better_next(lt_x, a0, b0, b, 1); + return closer(b.x-a0.x, b0.x-a0.x); abort(); } @@ -180,7 +198,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, 0)) + if (better_next(lt, ref, next, s->pos)) next = s->pos; s = s->next; }