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

This commit is contained in:
stefan schippers 2025-01-21 15:38:19 +01:00
parent 99b0bba5b8
commit 72d961aacd
5 changed files with 114 additions and 39 deletions

View File

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

View File

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

View File

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

View File

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

View File

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