From 710f8577650e746fc2685758ab9d57110f4f25a0 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Thu, 23 Jan 2025 17:45:49 +0530 Subject: [PATCH] [Snap Cursor Update (WIP)]: Added keybind to activate snap_cursor + new tcl-command to adjust 'snap_cursor_size'. Added grid-coordinate checks for better performance using the 'find_closest_net_or_symbol_pin()' function (by only running the search when the grid-snap position changes). Fixed xctx->prev_crossx and xctx->prev_crossy conflict between draw_crosshair() and draw_snap_cursor() by using the new globally accesible variables 'xctx->prev_gridx' and 'xctx->prev_gridy' in draw_snap_cursor(). --- src/callback.c | 97 ++++++++++++++------------------------------------ src/xinit.c | 1 + src/xschem.h | 1 + src/xschem.tcl | 9 ++--- src/xschemrc | 3 ++ 5 files changed, 36 insertions(+), 75 deletions(-) diff --git a/src/callback.c b/src/callback.c index 30a2516e..3d7000e2 100644 --- a/src/callback.c +++ b/src/callback.c @@ -1355,7 +1355,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int /* what == 0 : delete and draw * what == 1 : delete * what == 2 : draw */ -void draw_crosshair_old(int what) +void draw_crosshair(int what) { int sdw, sdp; int xhair_size = tclgetintvar("crosshair_size"); @@ -1464,76 +1464,14 @@ void draw_crosshair_old(int what) xctx->draw_pixmap = sdp; } -/* what == 0 : delete and draw - * what == 1 : delete - * what == 2 : draw */ -void draw_crosshair(int what) /* For drawing the grid-snapping cursor with constant pixel-size */ -{ - int sdw, sdp; - int xhair_size = tclgetintvar("crosshair_size"); - dbg(1, "draw_crosshair_constpixel(): 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) { /* delete previous */ - if(fix_broken_tiled_fill || !_unix) { - if(xhair_size) { - MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], 0, 0, xctx->xrect[0].width, xctx->xrect[0].height, 0, 0); - } 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); - } - } else { - if(xhair_size) { - drawtemprect(xctx->gctiled, NOW, - xctx->prev_crossx - xhair_size, xctx->prev_crossy - xhair_size, - xctx->prev_crossx + xhair_size, xctx->prev_crossy + 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 new */ - if(xhair_size) { - drawrect(xctx->crosshair_layer, NOW, xctx->prev_crossx - xhair_size, xctx->prev_crossy - xhair_size, - xctx->prev_crossx + xhair_size, xctx->prev_crossy + xhair_size, - 0, -1, -1); - } 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; - xctx->prev_crossy = xctx->mousey_snap; - - xctx->draw_window = sdw; - xctx->draw_pixmap = sdp; -} - /* what == 0 : erase and draw a new cursor * what == 1 : erase the cursor * what == 2 : draw a diamond-shaped cursor that snaps to a component endpoint */ void draw_snap_cursor(int what) { int sdw, sdp; + int snapcursor_size = tclgetintvar("snap_cursor_size"); + int pos_changed = (xctx->mousex_snap - xctx->prev_gridx) || (xctx->mousey_snap - xctx->prev_gridy); dbg(1, "draw_snap_cursor(): what=%d\n", what); sdw = xctx->draw_window; sdp = xctx->draw_pixmap; @@ -1547,17 +1485,24 @@ void draw_snap_cursor(int what) } else { double prev_x = xctx->prev_snapx; double prev_y = xctx->prev_snapy; - double points_x[5] = {prev_x, prev_x+3, prev_x, prev_x-3, prev_x}; - double points_y[5] = {prev_y-3, prev_y, prev_y+3, prev_y, prev_y-3}; + double points_x[5] = {prev_x, prev_x+snapcursor_size, prev_x, prev_x-snapcursor_size, prev_x}; + double points_y[5] = {prev_y-snapcursor_size, prev_y, prev_y+snapcursor_size, prev_y, prev_y-snapcursor_size}; drawtemppolygon(xctx->gctiled, NOW, points_x, points_y, 5, 0); } } if(what != 1) { double x, y; - find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y); - double points_x[5] = {x, x+3, x, x-3, x}; - double points_y[5] = {y-3, y, y+3, y, y-3}; - drawpolygon(8, NOW, points_x, points_y, 5, 0, 0, 0); + if(!pos_changed) { + x = xctx->prev_snapx; + y = xctx->prev_snapy; + } else { /* Only search for nearest pin if the grid-snap-point has changed */ + find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y); + } + double points_x[5] = {x, x+snapcursor_size, x, x-snapcursor_size, x}; + double points_y[5] = {y-snapcursor_size, y, y+snapcursor_size, y, y-snapcursor_size}; + drawpolygon(xctx->crosshair_layer, NOW, points_x, points_y, 5, 0, 0, 0); + xctx->prev_gridx = xctx->mousex_snap; + xctx->prev_gridy = xctx->mousey_snap; xctx->prev_snapx = x; xctx->prev_snapy = y; } @@ -2988,6 +2933,16 @@ int rstate; /* (reduced state, without ShiftMask) */ { view_zoom(0.0); break; } + if(key=='z' && EQUAL_MODMASK) /* toggle snap-cursor option */ + { + if(tclgetboolvar("snap_cursor")) { + tclsetvar("snap_cursor", "0"); + draw_snap_cursor(1); + } else { + tclsetvar("snap_cursor", "1"); + if(wire_draw_active) draw_snap_cursor(0); + } + } if(key=='p' && EQUAL_MODMASK) /* add symbol pin */ { xctx->push_undo(); diff --git a/src/xinit.c b/src/xinit.c index 25d2f9f6..acb456ef 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_gridx = xctx->prev_gridy = 0.0; xctx->prev_snapx = xctx->prev_snapy = 0.0; xctx->mouse_inside = 0; xctx->pending_fullzoom = 0; diff --git a/src/xschem.h b/src/xschem.h index 04f80698..23d9d254 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1049,6 +1049,7 @@ typedef struct { double p_xx1,p_xx2,p_yy1,p_yy2; /* draw_crosshair */ double prev_crossx, prev_crossy; + double prev_gridx, prev_gridy; double prev_snapx, prev_snapy; int mouse_inside; /* set_modify */ diff --git a/src/xschem.tcl b/src/xschem.tcl index 34696455..fda04474 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 orthogonal_wiring snap_cursor 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 crosshair_size custom_label_prefix custom_token dark_colors dark_colorscheme + copy_cell crosshair_layer crosshair_size snap_cursor_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 @@ -8200,10 +8200,8 @@ proc build_widgets { {topwin {} } } { -selectcolor $selectcolor -accelerator Y $topwin.menubar.option add checkbutton -label "Enable infix-interface" -variable infix_interface \ -selectcolor $selectcolor - $topwin.menubar.option add checkbutton -label "Display snap cursor" -variable snap_cursor \ - -selectcolor $selectcolor $topwin.menubar.option add checkbutton -label "Enable orthogonal wiring" -variable orthogonal_wiring \ - -selectcolor $selectcolor -accelerator Shift+L + -selectcolor $selectcolor -accelerator Shift-L $topwin.menubar.option add checkbutton -label "Unsel. partial sel. wires after stretch move" \ -selectcolor $selectcolor -variable unselect_partial_sel_wires @@ -8222,6 +8220,8 @@ proc build_widgets { {topwin {} } } { $topwin.menubar.option add checkbutton -label "Draw crosshair" \ -variable draw_crosshair -selectcolor $selectcolor -accelerator {Alt-X} + $topwin.menubar.option add checkbutton -label "Draw persistent snap cursor" -variable snap_cursor \ + -selectcolor $selectcolor -accelerator {Alt-Z} $topwin.menubar.option add command -label "Replace \[ and \] for buses in SPICE netlist" \ -command { @@ -9106,6 +9106,7 @@ set_ne ps_page_title 1 ;# add a title in the top left page corner set_ne draw_crosshair 0 set_ne crosshair_layer 8 ;# Yellow set_ne crosshair_size 0 +set_ne snap_cursor_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 d6ff0abe..f7d7253e 100644 --- a/src/xschemrc +++ b/src/xschemrc @@ -285,6 +285,9 @@ #### set crosshair size; Default: 0 (full screen spanning crosshair) set crosshair_size 2 +#### set snap_cursor size; Default: 3 (Diamond-shaped cursor that snaps to nearest circuit endpoint) +# set snap_cursor size 3 + #### enable to scale grid point size as done with lines at close zoom, default: 0 # set big_grid_points 0