diff --git a/src/actions.c b/src/actions.c index b80f9f9a..5eecc23b 100644 --- a/src/actions.c +++ b/src/actions.c @@ -2781,7 +2781,7 @@ void zoom_full(int dr, int sel, int flags, double shrink) xctx->cadhalfdotsize = CADHALFDOTSIZE * (cs < 20. ? cs : 20.) / 10.; if(dr && has_x) { draw(); - redraw_w_a_l_r_p_rubbers(); + redraw_w_a_l_r_p_z_rubbers(1); } } @@ -2797,7 +2797,7 @@ void view_zoom(double z) change_linewidth(-1.); draw(); - redraw_w_a_l_r_p_rubbers(); + redraw_w_a_l_r_p_z_rubbers(1); } void view_unzoom(double z) @@ -2818,7 +2818,7 @@ void view_unzoom(double z) } change_linewidth(-1.); draw(); - redraw_w_a_l_r_p_rubbers(); + redraw_w_a_l_r_p_z_rubbers(1); } void set_viewport_size(int w, int h, double lw) @@ -2900,7 +2900,7 @@ void zoom_rectangle(int what) xctx->mooz = 1 / xctx->zoom; change_linewidth(-1.); draw(); - redraw_w_a_l_r_p_rubbers(); + redraw_w_a_l_r_p_z_rubbers(1); dbg(1, "zoom_rectangle(): coord: %.16g %.16g %.16g %.16g zoom=%.16g\n", xctx->nl_x1, xctx->nl_y1, xctx->mousex_snap, xctx->mousey_snap, xctx->zoom); } diff --git a/src/callback.c b/src/callback.c index 57cc3212..9683d003 100644 --- a/src/callback.c +++ b/src/callback.c @@ -74,7 +74,7 @@ static int waves_selected(int event, KeySym key, int state, int button) if(! (xctx->ui_state & GRAPHPAN) ) { xctx->graph_master = i; } - if(draw_xhair) draw_crosshair(1); /* remove crosshair, re-enable mouse cursor */ + if(draw_xhair) draw_crosshair(1, 0); /* remove crosshair, re-enable mouse cursor */ tclvareval(xctx->top_path, ".drw configure -cursor tcross" , NULL); break; } @@ -95,29 +95,38 @@ static int waves_selected(int event, KeySym key, int state, int button) return is_inside; } -void redraw_w_a_l_r_p_rubbers(void) +/* do nothing if coordinates not changed unless force is given */ +void redraw_w_a_l_r_p_z_rubbers(int force) { + double mx = xctx->mousex_snap; + double my = xctx->mousey_snap; + + if(!force && xctx->mousex_snap == xctx->prev_rubberx && xctx->mousey_snap == xctx->prev_rubbery) return; + + if(xctx->ui_state & STARTZOOM) zoom_rectangle(RUBBER); if(xctx->ui_state & STARTWIRE) { - if(xctx->constr_mv == 1) xctx->mousey_snap = xctx->my_double_save; - if(xctx->constr_mv == 2) xctx->mousex_snap = xctx->mx_double_save; - new_wire(RUBBER, xctx->mousex_snap, xctx->mousey_snap); + if(xctx->constr_mv == 1) my = xctx->my_double_save; + if(xctx->constr_mv == 2) mx = xctx->mx_double_save; + new_wire(RUBBER, mx, my); } if(xctx->ui_state & STARTARC) { - if(xctx->constr_mv == 1) xctx->mousey_snap = xctx->my_double_save; - if(xctx->constr_mv == 2) xctx->mousex_snap = xctx->mx_double_save; - new_arc(RUBBER, 0, xctx->mousex_snap, xctx->mousey_snap); + if(xctx->constr_mv == 1) my = xctx->my_double_save; + if(xctx->constr_mv == 2) mx = xctx->mx_double_save; + new_arc(RUBBER, 0, mx, my); } if(xctx->ui_state & STARTLINE) { - if(xctx->constr_mv == 1) xctx->mousey_snap = xctx->my_double_save; - if(xctx->constr_mv == 2) xctx->mousex_snap = xctx->mx_double_save; - new_line(RUBBER, xctx->mousex_snap, xctx->mousey_snap); + if(xctx->constr_mv == 1) my = xctx->my_double_save; + if(xctx->constr_mv == 2) mx = xctx->mx_double_save; + new_line(RUBBER, mx, my); } - if(xctx->ui_state & STARTRECT) new_rect(RUBBER,xctx->mousex_snap, xctx->mousey_snap); + if(xctx->ui_state & STARTRECT) new_rect(RUBBER,mx, my); if(xctx->ui_state & STARTPOLYGON) { - if(xctx->constr_mv == 1) xctx->mousey_snap = xctx->my_double_save; - if(xctx->constr_mv == 2) xctx->mousex_snap = xctx->mx_double_save; - new_polygon(RUBBER, xctx->mousex_snap, xctx->mousey_snap); + if(xctx->constr_mv == 1) my = xctx->my_double_save; + if(xctx->constr_mv == 2) mx = xctx->mx_double_save; + new_polygon(RUBBER, mx, my); } + xctx->prev_rubberx = xctx->mousex_snap; + xctx->prev_rubbery = xctx->mousey_snap; } /* resets UI state, unselect all and abort any pending operation */ @@ -130,7 +139,7 @@ void abort_operation(void) if(xctx->last_command && xctx->ui_state & (STARTWIRE | STARTLINE)) { if(xctx->ui_state & STARTWIRE) new_wire(RUBBER|CLEAR, xctx->mousex_snap, xctx->mousey_snap); if(xctx->ui_state & STARTLINE) new_line(RUBBER|CLEAR, xctx->mousex_snap, xctx->mousey_snap); - if(tclgetboolvar("draw_crosshair")) draw_crosshair(2); + if(tclgetboolvar("draw_crosshair")) draw_crosshair(2, 0); xctx->ui_state = 0; return; } @@ -1335,19 +1344,27 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int return 0; } -/* what == 3 : delete and draw - * what == 1 : delete - * what == 2 : draw */ -void draw_crosshair(int what) +/* what == 3 (+4) : delete and draw (force) + * what == 1 (+4) : delete (force) + * what == 2 (+4) : draw (force) + * what == 4 : force (re)clear and/or (re)draw even if on same point */ +void draw_crosshair(int what, int state) { int sdw, sdp; int xhair_size = tclgetintvar("crosshair_size"); + double mx, my; dbg(1, "draw_crosshair(): what=%d\n", what); sdw = xctx->draw_window; sdp = xctx->draw_pixmap; if(!xctx->mouse_inside) return; - + mx = xctx->mousex_snap; + my = xctx->mousey_snap; + if( ( (xctx->ui_state & (MENUSTART | STARTWIRE) ) || xctx->ui_state == 0 ) && + (state == ShiftMask) ) { + find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &mx, &my); + } + if(!(what & 4) && mx == xctx->prev_crossx && my == xctx->prev_crossy) return; xctx->draw_pixmap = 0; xctx->draw_window = 1; if(what & 1) { /* delete previous */ @@ -1411,37 +1428,39 @@ void draw_crosshair(int what) if(what & 2) { /* draw new */ if(xhair_size) { draw_xhair_line(xctx->gc[xctx->crosshair_layer], xhair_size, - X_TO_SCREEN(xctx->mousex_snap) - xhair_size, - Y_TO_SCREEN(xctx->mousey_snap) - xhair_size, - X_TO_SCREEN(xctx->mousex_snap) + xhair_size, - Y_TO_SCREEN(xctx->mousey_snap) - xhair_size); + X_TO_SCREEN(mx) - xhair_size, + Y_TO_SCREEN(my) - xhair_size, + X_TO_SCREEN(mx) + xhair_size, + Y_TO_SCREEN(my) - xhair_size); draw_xhair_line(xctx->gc[xctx->crosshair_layer], xhair_size, - X_TO_SCREEN(xctx->mousex_snap) - xhair_size, - Y_TO_SCREEN(xctx->mousey_snap) + xhair_size, - X_TO_SCREEN(xctx->mousex_snap) + xhair_size, - Y_TO_SCREEN(xctx->mousey_snap) + xhair_size); + X_TO_SCREEN(mx) - xhair_size, + Y_TO_SCREEN(my) + xhair_size, + X_TO_SCREEN(mx) + xhair_size, + Y_TO_SCREEN(my) + xhair_size); draw_xhair_line(xctx->gc[xctx->crosshair_layer], xhair_size, - X_TO_SCREEN(xctx->mousex_snap) - xhair_size, - Y_TO_SCREEN(xctx->mousey_snap) - xhair_size, - X_TO_SCREEN(xctx->mousex_snap) - xhair_size, - Y_TO_SCREEN(xctx->mousey_snap) + xhair_size); + X_TO_SCREEN(mx) - xhair_size, + Y_TO_SCREEN(my) - xhair_size, + X_TO_SCREEN(mx) - xhair_size, + Y_TO_SCREEN(my) + xhair_size); draw_xhair_line(xctx->gc[xctx->crosshair_layer], xhair_size, - X_TO_SCREEN(xctx->mousex_snap) + xhair_size, - Y_TO_SCREEN(xctx->mousey_snap) - xhair_size, - X_TO_SCREEN(xctx->mousex_snap) + xhair_size, - Y_TO_SCREEN(xctx->mousey_snap) + xhair_size); + X_TO_SCREEN(mx) + xhair_size, + Y_TO_SCREEN(my) - xhair_size, + X_TO_SCREEN(mx) + xhair_size, + Y_TO_SCREEN(my) + xhair_size); } else { /* full screen span xhair */ draw_xhair_line(xctx->gc[xctx->crosshair_layer], xhair_size, - xctx->areax1, Y_TO_SCREEN(xctx->mousey_snap), - xctx->areax2, Y_TO_SCREEN(xctx->mousey_snap)); + xctx->areax1, Y_TO_SCREEN(my), + xctx->areax2, Y_TO_SCREEN(my)); draw_xhair_line(xctx->gc[xctx->crosshair_layer], xhair_size, - X_TO_SCREEN(xctx->mousex_snap), xctx->areay1, - X_TO_SCREEN(xctx->mousex_snap), xctx->areay2); + X_TO_SCREEN(mx), xctx->areay1, + X_TO_SCREEN(mx), xctx->areay2); } } if(what) draw_selection(xctx->gc[SELLAYER], 0); - xctx->prev_crossx = xctx->mousex_snap; - xctx->prev_crossy = xctx->mousey_snap; + if(what & 2) { + xctx->prev_crossx = mx; + xctx->prev_crossy = my; + } xctx->draw_window = sdw; xctx->draw_pixmap = sdp; @@ -2034,7 +2053,7 @@ static int handle_mouse_wheel(int event, int mx, int my, KeySym key, int button, } xctx->xorigin+=-CADMOVESTEP*xctx->zoom/2.; draw(); - redraw_w_a_l_r_p_rubbers(); + redraw_w_a_l_r_p_z_rubbers(1); } else if(button==Button5 && (state & ShiftMask) && !(state & Button2Mask)) { if(waves_selected(event, key, state, button)) { @@ -2043,17 +2062,17 @@ static int handle_mouse_wheel(int event, int mx, int my, KeySym key, int button, } xctx->xorigin-=-CADMOVESTEP*xctx->zoom/2.; draw(); - redraw_w_a_l_r_p_rubbers(); + redraw_w_a_l_r_p_z_rubbers(1); } else if(button==Button4 && (state & ControlMask) && !(state & Button2Mask)) { xctx->yorigin+=-CADMOVESTEP*xctx->zoom/2.; draw(); - redraw_w_a_l_r_p_rubbers(); + redraw_w_a_l_r_p_z_rubbers(1); } else if(button==Button5 && (state & ControlMask) && !(state & Button2Mask)) { xctx->yorigin-=-CADMOVESTEP*xctx->zoom/2.; draw(); - redraw_w_a_l_r_p_rubbers(); + redraw_w_a_l_r_p_z_rubbers(1); } } return 0; @@ -2373,7 +2392,7 @@ int rstate; /* (reduced state, without ShiftMask) */ { case LeaveNotify: - if(draw_xhair) draw_crosshair(1); /* clear crosshair when exiting window */ + if(draw_xhair) draw_crosshair(1, state); /* clear crosshair when exiting window */ tclvareval(xctx->top_path, ".drw configure -cursor {}" , NULL); xctx->mouse_inside = 0; break; @@ -2442,14 +2461,14 @@ int rstate; /* (reduced state, without ShiftMask) */ break; } if(draw_xhair) { - draw_crosshair(1); /* when moving mouse: first action is delete crosshair, will be drawn later */ + draw_crosshair(1, state); /* when moving mouse: first action is delete crosshair, will be drawn later */ } /* pan schematic */ if(xctx->ui_state & STARTPAN) pan(RUBBER, mx, my); if(xctx->semaphore >= 2) { if(draw_xhair) { - draw_crosshair(2); /* locked UI: draw new crosshair and break out */ + draw_crosshair(2, state); /* locked UI: draw new crosshair and break out */ } break; } @@ -2467,9 +2486,6 @@ int rstate; /* (reduced state, without ShiftMask) */ } } - /* update zoom rectangle drag */ - if(xctx->ui_state & STARTZOOM) zoom_rectangle(RUBBER); - /* determine direction of a rectangle selection (or unselection with ALT key) */ if(xctx->ui_state & STARTSELECT && !(xctx->ui_state & (PLACE_SYMBOL | STARTPAN | PLACE_TEXT)) ) { /* Unselect by area : determine direction */ @@ -2497,10 +2513,9 @@ int rstate; /* (reduced state, without ShiftMask) */ if(xctx->constr_mv == 2) xctx->mousex_snap = xctx->mx_double_save; copy_objects(RUBBER); } - - /* draw moving objects being inserted, wires, arcs, lines, rectangles, polygons */ - redraw_w_a_l_r_p_rubbers(); + /* draw moving objects being inserted, wires, arcs, lines, rectangles, polygons or zoom box */ + redraw_w_a_l_r_p_z_rubbers(0); /* start of a mouse area select. Button1 pressed. No shift pressed * Do not start an area select if user is dragging a polygon/bezier point */ @@ -2552,22 +2567,8 @@ int rstate; /* (reduced state, without ShiftMask) */ } } } - /* snap crosshair to closest pin or net endpoint */ if(draw_xhair) { - if( ( (xctx->ui_state & (MENUSTART | STARTWIRE) ) || xctx->ui_state == 0 ) && - (state == ShiftMask) ) { - double x, y, sx, sy; - sx = xctx->mousex_snap; - sy = xctx->mousey_snap; - find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y); - xctx->mousex_snap = x; - xctx->mousey_snap = y; - draw_crosshair(2); - xctx->mousex_snap = sx; - xctx->mousey_snap = sy; - } else { - draw_crosshair(2); - } + draw_crosshair(2, state); /* what = 2(draw) */ } break; @@ -2850,7 +2851,8 @@ int rstate; /* (reduced state, without ShiftMask) */ tclsetvar("tclstop", "1"); /* stop simulation if any running */ break; } - if(key=='z' && rstate == 0) /* zoom box */ + if(key=='z' && rstate == 0 && + !(xctx->ui_state & (STARTRECT | STARTLINE | STARTWIRE | STARTPOLYGON | STARTARC))) /* zoom box */ { dbg(1, "callback(): zoom_rectangle call\n"); zoom_rectangle(START);break; @@ -2891,7 +2893,7 @@ int rstate; /* (reduced state, without ShiftMask) */ xctx->xorigin=-xctx->mousex_snap+xctx->areaw*xctx->zoom/2.0; xctx->yorigin=-xctx->mousey_snap+xctx->areah*xctx->zoom/2.0; draw(); - redraw_w_a_l_r_p_rubbers(); + redraw_w_a_l_r_p_z_rubbers(1); break; } if(key=='5' && rstate == 0) { /* 20110112 display only probes */ @@ -2954,7 +2956,7 @@ int rstate; /* (reduced state, without ShiftMask) */ } xctx->xorigin+=-CADMOVESTEP*xctx->zoom; draw(); - redraw_w_a_l_r_p_rubbers(); + redraw_w_a_l_r_p_z_rubbers(1); break; } if(key==XK_Left && !(state & ControlMask)) /* right */ @@ -2965,7 +2967,7 @@ int rstate; /* (reduced state, without ShiftMask) */ } xctx->xorigin-=-CADMOVESTEP*xctx->zoom; draw(); - redraw_w_a_l_r_p_rubbers(); + redraw_w_a_l_r_p_z_rubbers(1); break; } if(key==XK_Down) /* down */ @@ -2976,7 +2978,7 @@ int rstate; /* (reduced state, without ShiftMask) */ } xctx->yorigin+=-CADMOVESTEP*xctx->zoom; draw(); - redraw_w_a_l_r_p_rubbers(); + redraw_w_a_l_r_p_z_rubbers(1); break; } if(key==XK_Up) /* up */ @@ -2987,7 +2989,7 @@ int rstate; /* (reduced state, without ShiftMask) */ } xctx->yorigin-=-CADMOVESTEP*xctx->zoom; draw(); - redraw_w_a_l_r_p_rubbers(); + redraw_w_a_l_r_p_z_rubbers(1); break; } if(key=='w' && rstate == ControlMask) /* close current schematic */ @@ -4337,7 +4339,7 @@ int rstate; /* (reduced state, without ShiftMask) */ /* xctx->mx_save = mx; xctx->my_save = my; */ /* xctx->mx_double_save=xctx->mousex_snap; */ /* xctx->my_double_save=xctx->mousey_snap; */ - redraw_w_a_l_r_p_rubbers(); + redraw_w_a_l_r_p_z_rubbers(1); break; } dbg(1, "callback(): ButtonRelease ui_state=%d state=%d\n",xctx->ui_state,state); @@ -4362,7 +4364,7 @@ int rstate; /* (reduced state, without ShiftMask) */ xctx->ui_state &= ~MENUSTART; break; } - if(draw_xhair) draw_crosshair(3); /* restore crosshair when selecting / unselecting */ + if(draw_xhair) draw_crosshair(3, state); /* restore crosshair when selecting / unselecting */ break; case -3: /* double click : edit prop */ if( waves_selected(event, key, state, button)) { diff --git a/src/draw.c b/src/draw.c index b92f9312..f38b6b1a 100644 --- a/src/draw.c +++ b/src/draw.c @@ -5137,7 +5137,7 @@ void draw(void) } else { draw_selection(xctx->gc[SELLAYER], 0); /* 20181009 moved outside of cadlayers loop */ } - if(tclgetboolvar("draw_crosshair")) draw_crosshair(3); + if(tclgetboolvar("draw_crosshair")) draw_crosshair(3, 0); /* what = 1(clear) + 2(draw) */ } /* if(has_x) */ } diff --git a/src/move.c b/src/move.c index 317ab661..9ceb9177 100644 --- a/src/move.c +++ b/src/move.c @@ -907,7 +907,7 @@ void copy_objects(int what) xctx->rotatelocal=0; } /* if(what & END) */ draw_selection(xctx->gc[SELLAYER], 0); - if(tclgetboolvar("draw_crosshair")) draw_crosshair(3); + if(tclgetboolvar("draw_crosshair")) draw_crosshair(3, 0); /* what = 1(clear) + 2(draw) */ } @@ -1361,5 +1361,5 @@ void move_objects(int what, int merge, double dx, double dy) xctx->rotatelocal=0; } /* what & end */ draw_selection(xctx->gc[SELLAYER], 0); - if(tclgetboolvar("draw_crosshair")) draw_crosshair(3); + if(tclgetboolvar("draw_crosshair")) draw_crosshair(3, 0); /* what = 1(clear) + 2(draw) */ } diff --git a/src/xinit.c b/src/xinit.c index 18dd4315..cc129ea7 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -646,6 +646,7 @@ static void alloc_xschem_data(const char *top_path, const char *win_path) xctx->enable_drill = 0; xctx->prev_set_modify = -1; xctx->prev_crossx = xctx->prev_crossy = 0.0; + xctx->prev_rubberx = xctx->prev_rubbery = 0.0; xctx->mouse_inside = 0; xctx->pending_fullzoom = 0; my_strncpy(xctx->hiersep, ".", S(xctx->hiersep)); diff --git a/src/xschem.h b/src/xschem.h index be4edd09..7087da37 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1020,6 +1020,8 @@ typedef struct { short move_rot; /* connect by kissing enable flag */ int connect_by_kissing; + /* redraw_w_a_l_r_p_z_rubbers() */ + double prev_rubberx, prev_rubbery; /* a wire was created while separating a component frm a net or another component */ int kissing; short move_flip; @@ -1389,7 +1391,7 @@ extern int select_dangling_nets(void); extern void tclmainloop(void); extern int Tcl_AppInit(Tcl_Interp *interp); extern void abort_operation(void); -extern void draw_crosshair(int what); +extern void draw_crosshair(int what, int state); extern void backannotate_at_cursor_b_pos(xRect *r, Graph_ctx *gr); /* extern void snapped_wire(double c_snap); */ extern int callback(const char *winpath, int event, int mx, int my, KeySym key, @@ -1538,7 +1540,7 @@ extern void arc_3_points(double x1, double y1, double x2, double y2, double x3, double *x, double *y, double *r, double *a, double *b); extern void move_objects(int what,int merge, double dx, double dy); extern void check_collapsing_objects(); -extern void redraw_w_a_l_r_p_rubbers(void); /* redraw wire, arcs, line, polygon rubbers */ +extern void redraw_w_a_l_r_p_z_rubbers(int force); /* redraw wire, arcs, line, polygon rubbers */ extern void copy_objects(int what); extern void find_inst_to_be_redrawn(int what); extern void pan(int what, int mx, int my);