redraw_w_a_l_r_p_z_rubbers(): include zoom_rectangle(RUBBER), only execute if (snapped) coordinates changed, draw_crosshair(): only execute if (snapped) coordinates changed, find_closest_net_or_symbol_pin() is moved into draw_crosshair() so its calls are also minimized, do not allow z (zoom rectangle) if pending STARTWIRE, STARTLINE etc are in progress.

This commit is contained in:
stefan schippers 2025-01-26 15:19:22 +01:00
parent bbe8782bc0
commit 8086b5581e
6 changed files with 93 additions and 88 deletions

View File

@ -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);
}

View File

@ -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)) {

View File

@ -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) */
}

View File

@ -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) */
}

View File

@ -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));

View File

@ -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);