From 72d961aacdc439a72720531e37810c7a330c8b78 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Tue, 21 Jan 2025 15:38:19 +0100 Subject: [PATCH] fix a regression where a mouse wheel zoom or schematic pan unexpectedly end an ongoing wire placement. Add xschemrc variable crosshair_size; if set to 0 draw full crosshair, if set to a small integer draw a small square around the mouse snapped coordinate --- src/callback.c | 121 +++++++++++++++++++++++++++++++++++++++---------- src/draw.c | 24 +++++----- src/xschem.h | 2 +- src/xschem.tcl | 3 +- src/xschemrc | 3 ++ 5 files changed, 114 insertions(+), 39 deletions(-) diff --git a/src/callback.c b/src/callback.c index e2fd6371..dadf52e1 100644 --- a/src/callback.c +++ b/src/callback.c @@ -82,9 +82,11 @@ static int waves_selected(int event, KeySym key, int state, int button) if(!is_inside) { xctx->graph_master = -1; xctx->ui_state &= ~GRAPHPAN; /* terminate ongoing GRAPHPAN to avoid deadlocks */ - if(draw_xhair) - tclvareval(xctx->top_path, ".drw configure -cursor none" , NULL); - else + if(draw_xhair) { + if(tclgetintvar("crosshair_size") == 0) { + tclvareval(xctx->top_path, ".drw configure -cursor none" , NULL); + } + } else tclvareval(xctx->top_path, ".drw configure -cursor {}" , NULL); if(xctx->graph_flags & 64) { tcleval("graph_show_measure stop"); @@ -1338,36 +1340,103 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int void draw_crosshair(int what) { int sdw, sdp; + int xhair_size = tclgetintvar("crosshair_size");; dbg(1, "draw_crosshair(): what=%d\n", what); sdw = xctx->draw_window; sdp = xctx->draw_pixmap; if(!xctx->mouse_inside) return; + xctx->draw_pixmap = 0; xctx->draw_window = 1; - if(what != 2) { + if(what != 2) { /* delete previous */ if(fix_broken_tiled_fill || !_unix) { - MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], - 0, (int)Y_TO_SCREEN(xctx->prev_crossy) - 2 * INT_WIDTH(xctx->lw), - xctx->xrect[0].width, 4 * INT_WIDTH(xctx->lw), - 0, (int)Y_TO_SCREEN(xctx->prev_crossy) - 2 * INT_WIDTH(xctx->lw)); + if(xhair_size) { + MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], + (int)X_TO_SCREEN(xctx->prev_crossx) - 2 * INT_WIDTH(xctx->lw) - xhair_size, + (int)Y_TO_SCREEN(xctx->prev_crossy) - 2 * INT_WIDTH(xctx->lw) - xhair_size, + 4 * INT_WIDTH(xctx->lw) + 4 * xhair_size, + 4 * INT_WIDTH(xctx->lw) + 4 * xhair_size, + (int)X_TO_SCREEN(xctx->prev_crossx) - 2 * INT_WIDTH(xctx->lw) - xhair_size, + (int)Y_TO_SCREEN(xctx->prev_crossy) - 2 * INT_WIDTH(xctx->lw) - xhair_size); + MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], + (int)X_TO_SCREEN(xctx->prev_crossx) - 2 * INT_WIDTH(xctx->lw) - xhair_size, + (int)Y_TO_SCREEN(xctx->prev_crossy) - 2 * INT_WIDTH(xctx->lw) - xhair_size, + 4 * INT_WIDTH(xctx->lw) + 4 * xhair_size, + 4 * INT_WIDTH(xctx->lw) + 4 * xhair_size, + (int)X_TO_SCREEN(xctx->prev_crossx) - 2 * INT_WIDTH(xctx->lw) - xhair_size, + (int)Y_TO_SCREEN(xctx->prev_crossy) - 2 * INT_WIDTH(xctx->lw) - xhair_size); + } else { /* full screen span xhair */ + MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], + 0, (int)Y_TO_SCREEN(xctx->prev_crossy) - 2 * INT_WIDTH(xctx->lw), + xctx->xrect[0].width, 4 * INT_WIDTH(xctx->lw), + 0, (int)Y_TO_SCREEN(xctx->prev_crossy) - 2 * INT_WIDTH(xctx->lw)); + MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], + (int)X_TO_SCREEN(xctx->prev_crossx) - 2 * INT_WIDTH(xctx->lw), 0, + 4 * INT_WIDTH(xctx->lw), xctx->xrect[0].height, + (int)X_TO_SCREEN(xctx->prev_crossx) - 2 * INT_WIDTH(xctx->lw), 0); + } - MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], - (int)X_TO_SCREEN(xctx->prev_crossx) - 2 * INT_WIDTH(xctx->lw), 0, - 4 * INT_WIDTH(xctx->lw), xctx->xrect[0].height, - (int)X_TO_SCREEN(xctx->prev_crossx) - 2 * INT_WIDTH(xctx->lw), 0); } else { - drawtempline(xctx->gctiled, NOW, X_TO_XSCHEM(xctx->areax1), - xctx->prev_crossy, X_TO_XSCHEM(xctx->areax2), xctx->prev_crossy); - drawtempline(xctx->gctiled, NOW, xctx->prev_crossx, Y_TO_XSCHEM(xctx->areay1), - xctx->prev_crossx, Y_TO_XSCHEM(xctx->areay2)); + if(xhair_size) { + draw_xhair_line(xctx->gctiled, 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); + draw_xhair_line(xctx->gctiled, 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); + draw_xhair_line(xctx->gctiled, 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); + draw_xhair_line(xctx->gctiled, 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); + } else { /* full screen span xhair */ + drawtempline(xctx->gctiled, NOW, X_TO_XSCHEM(xctx->areax1), + xctx->prev_crossy, X_TO_XSCHEM(xctx->areax2), xctx->prev_crossy); + drawtempline(xctx->gctiled, NOW, xctx->prev_crossx, Y_TO_XSCHEM(xctx->areay1), + xctx->prev_crossx, Y_TO_XSCHEM(xctx->areay2)); + } } } - if(what != 1) { - draw_xhair_line(xctx->crosshair_layer, X_TO_XSCHEM( xctx->areax1), xctx->mousey_snap, - X_TO_XSCHEM(xctx->areax2), xctx->mousey_snap); - draw_xhair_line(xctx->crosshair_layer, xctx->mousex_snap, Y_TO_XSCHEM(xctx->areay1), - xctx->mousex_snap, Y_TO_XSCHEM(xctx->areay2)); + if(what != 1) { /* 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); + 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); + 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); + 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); + } 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)); + 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); + } } draw_selection(xctx->gc[SELLAYER], 0); xctx->prev_crossx = xctx->mousex_snap; @@ -2321,9 +2390,11 @@ int rstate; /* (reduced state, without ShiftMask) */ case EnterNotify: dbg(2, "callback(): Enter event, ui_state=%d\n", xctx->ui_state); xctx->mouse_inside = 1; - if(draw_xhair) - tclvareval(xctx->top_path, ".drw configure -cursor none" , NULL); - else + if(draw_xhair) { + if(tclgetintvar("crosshair_size") == 0) { + tclvareval(xctx->top_path, ".drw configure -cursor none" , NULL); + } + } else tclvareval(xctx->top_path, ".drw configure -cursor {}" , NULL); /* xschem window *sending* selected objects when the pointer comes back in abort copy operation since it has been done @@ -4171,7 +4242,7 @@ int rstate; /* (reduced state, without ShiftMask) */ } /* end wire creation when dragging in intuitive interface from an inst pin ow wire endpoint */ - else if(xctx->intuitive_interface && (xctx->ui_state & STARTWIRE)) { + else if(state == Button1Mask && xctx->intuitive_interface && (xctx->ui_state & STARTWIRE)) { if(end_place_move_copy_zoom()) break; } diff --git a/src/draw.c b/src/draw.c index 80e4b540..2165bd21 100644 --- a/src/draw.c +++ b/src/draw.c @@ -1178,33 +1178,33 @@ static void check_cairo_drawpoints(void *cr, int layer, XPoint *points, int npoi #endif -void draw_xhair_line(int c, double linex1, double liney1, double linex2, double liney2) +void draw_xhair_line(GC gc, int size, double linex1, double liney1, double linex2, double liney2) { int big_gr = tclgetboolvar("big_grid_points"); char dash_arr[2]; double x1, y1, x2, y2; - x1=X_TO_SCREEN(linex1); - y1=Y_TO_SCREEN(liney1); - x2=X_TO_SCREEN(linex2); - y2=Y_TO_SCREEN(liney2); + x1=/* X_TO_SCREEN */ (linex1); + y1=/* Y_TO_SCREEN */ (liney1); + x2=/* X_TO_SCREEN */ (linex2); + y2=/* Y_TO_SCREEN */ (liney2); if( clip(&x1,&y1,&x2,&y2) ) { dash_arr[0] = dash_arr[1] = (char) 3; - XSetDashes(display, xctx->gc[c], 0, dash_arr, 1); + XSetDashes(display, gc, 0, dash_arr, 1); if(!big_gr) { - XSetLineAttributes (display, xctx->gc[c], - 0, xDashType, xCap, xJoin); + XSetLineAttributes (display, gc, + 0, size ? LineSolid : xDashType, xCap, xJoin); } else { - XSetLineAttributes (display, xctx->gc[c], + XSetLineAttributes (display, gc, XLINEWIDTH(xctx->lw), xDashType, xCap, xJoin); } if(xctx->draw_window) - XDrawLine(display, xctx->window, xctx->gc[c], (int)x1, (int)y1, (int)x2, (int)y2); + XDrawLine(display, xctx->window, gc, (int)x1, (int)y1, (int)x2, (int)y2); if(xctx->draw_pixmap) - XDrawLine(display, xctx->save_pixmap, xctx->gc[c], (int)x1, (int)y1, (int)x2, (int)y2); + XDrawLine(display, xctx->save_pixmap, gc, (int)x1, (int)y1, (int)x2, (int)y2); if(!big_gr) { - XSetLineAttributes (display, xctx->gc[c], + XSetLineAttributes (display, gc, XLINEWIDTH(xctx->lw), LineSolid, LINECAP, LINEJOIN); } } diff --git a/src/xschem.h b/src/xschem.h index 942cf1a8..67dfc35d 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1404,7 +1404,7 @@ extern Selected find_closest_obj(double mx,double my, int override_lock); extern void find_closest_net_or_symbol_pin(double mx,double my, double *x, double *y); extern void drawline(int c, int what, double x1,double y1,double x2,double y2, int dash, void *ct); -extern void draw_xhair_line(int c, double linex1, double liney1, double linex2, double liney2); +extern void draw_xhair_line(GC gc, int size, double linex1, double liney1, double linex2, double liney2); extern void draw_string(int layer,int what, const char *str, short rot, short flip, int hcenter, int vcenter, double x1, double y1, double xscale, double yscale); extern void get_sym_text_size(int inst, int text_n, double *xscale, double *yscale); diff --git a/src/xschem.tcl b/src/xschem.tcl index ef71c0a4..a377c398 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -7656,7 +7656,7 @@ set tctx::global_list { add_all_windows_drives auto_hilight auto_hilight_graph_nodes autofocus_mainwindow autotrim_wires bespice_listen_port big_grid_points bus_replacement_char cadgrid cadlayers cadsnap cairo_font_name cairo_font_scale change_lw color_ps tctx::colors compare_sch constr_mv - copy_cell crosshair_layer custom_label_prefix custom_token dark_colors dark_colorscheme + copy_cell crosshair_layer crosshair_size custom_label_prefix custom_token dark_colors dark_colorscheme dark_gui_colorscheme delay_flag dim_bg dim_value disable_unique_names do_all_inst draw_crosshair draw_grid draw_grid_axes draw_window edit_prop_pos edit_prop_size @@ -9096,6 +9096,7 @@ set_ne netlist_show 0 set_ne color_ps 1 set_ne ps_page_title 1 ;# add a title in the top left page corner set_ne crosshair_layer 3 ;# TEXTLAYER +set_ne crosshair_size 3 set_ne ps_paper_size {a4 842 595} set_ne transparent_svg 0 set_ne only_probes 0 ; # 20110112 diff --git a/src/xschemrc b/src/xschemrc index fdc9b455..f32941cf 100644 --- a/src/xschemrc +++ b/src/xschemrc @@ -270,6 +270,9 @@ #### set crosshair layer; Default 3 (TEXTLAYER) # set crosshair_layer 3 +#### set crosshair size; Default: 0 (full screen spanning crosshair) +# set crosshair_size 5 + #### enable to scale grid point size as done with lines at close zoom, default: 0 # set big_grid_points 0