diff --git a/src/callback.c b/src/callback.c index 78d19a47..59dc6643 100644 --- a/src/callback.c +++ b/src/callback.c @@ -2427,7 +2427,11 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key, } else if(button == Button3 && state == Mod1Mask && xctx->semaphore <2) { - break_wires_at_point(xctx->mousex_snap, xctx->mousey_snap); + break_wires_at_point(xctx->mousex_snap, xctx->mousey_snap, 1); + } + else if(button == Button3 && state == (ShiftMask | Mod1Mask) && xctx->semaphore <2) + { + break_wires_at_point(xctx->mousex_snap, xctx->mousey_snap, 0); } else if(button == Button3 && state == ShiftMask && xctx->semaphore <2) { @@ -2637,10 +2641,15 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key, break; } if(xctx->ui_state & MENUSTARTWIRECUT) { - break_wires_at_point(xctx->mousex_snap, xctx->mousey_snap); + break_wires_at_point(xctx->mousex_snap, xctx->mousey_snap, 1); xctx->ui_state &=~MENUSTARTWIRECUT; break; } + if(xctx->ui_state & MENUSTARTWIRECUT2) { + break_wires_at_point(xctx->mousex_snap, xctx->mousey_snap, 0); + xctx->ui_state &=~MENUSTARTWIRECUT2; + break; + } if(xctx->ui_state & MENUSTARTMOVE) { xctx->mx_double_save=xctx->mousex_snap; xctx->my_double_save=xctx->mousey_snap; diff --git a/src/check.c b/src/check.c index e81b6871..34d6976a 100644 --- a/src/check.c +++ b/src/check.c @@ -401,7 +401,8 @@ static int touches_inst_pin(double x, double y, int inst) /* return 2 if x0, y0 is on the segment * return 1 if x0, y0 is less than cadsnap (10) from the segment * In this case x0, y0 are reset to the closest point on the segment */ -static int closest_point_calculation(double x1, double y1, double x2, double y2, double *x0, double *y0) +static int closest_point_calculation(double x1, double y1, double x2, double y2, + double *x0, double *y0, int align) { double projection, sq_distance, x3, y3; double cs = tclgetdoublevar("cadsnap"), sq_cs; @@ -425,15 +426,20 @@ static int closest_point_calculation(double x1, double y1, double x2, double y2, else if(sq_distance < sq_cs) ret = 1; } - dbg(0, "x3 = %g y3=%g dist=%g ret=%d\n", x3, y3, sqrt(sq_distance), ret); + dbg(1, "x3 = %g y3=%g dist=%g ret=%d\n", x3, y3, sqrt(sq_distance), ret); if(ret == 1) { - *x0 = my_round(x3 / cs) * cs; - *y0 = my_round(y3 / cs) * cs; + if(align) { + *x0 = my_round(x3 / cs) * cs; + *y0 = my_round(y3 / cs) * cs; + } else { + *x0 = x3; + *y0 = y3; + } } return ret; } -void break_wires_at_point(double x0, double y0) +void break_wires_at_point(double x0, double y0, int align) { int r, i, sqx, sqy; Wireentry *wptr; @@ -448,7 +454,7 @@ void break_wires_at_point(double x0, double y0) y1 = xctx->wire[i].y1; x2 = xctx->wire[i].x2; y2 = xctx->wire[i].y2; - r = closest_point_calculation(x1, y1, x2, y2, &x0, &y0); + r = closest_point_calculation(x1, y1, x2, y2, &x0, &y0, align); if( r == 1 || touch(x1, y1, x2, y2, x0,y0) ) { if( (x0 != x1 && x0 != x2) || (y0 != y1 && y0 != y2) ) { diff --git a/src/scheduler.c b/src/scheduler.c index f71762f2..1e2a5929 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -4393,16 +4393,23 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg } else xctx->ui_state |= MENUSTARTWIRE; } - /* wire_cut [x y] + /* wire_cut [x y] [noalign] * start a wire cut operation. Point the mouse in the middle of a wire and - * click left button. - * if x and y are given cut wire at given point */ + * Alt-click right button. + * if x and y are given cut wire at given point + * if noalign is given and is set to 'noalign' do not align the cut point to closest snap point */ else if(!strcmp(argv[1], "wire_cut")) - { + { + int i, align = 1; + + for(i = 2; i < argc; i++) { + if(!strcmp(argv[i], "noalign")) align = 0; + } if(argc > 3) { - break_wires_at_point(atof(argv[2]), atof(argv[3])); + break_wires_at_point(atof(argv[2]), atof(argv[3]), align); } else { - xctx->ui_state |= MENUSTARTWIRECUT; + if(align) xctx->ui_state |= MENUSTARTWIRECUT; + else xctx->ui_state |= MENUSTARTWIRECUT2; } Tcl_ResetResult(interp); } diff --git a/src/xschem.h b/src/xschem.h index 079d3118..361fb917 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -235,6 +235,7 @@ extern char win_temp_dir[PATH_MAX]; #define GRAPHPAN 16777216U /* bit 24 */ #define MENUSTARTMOVE 33554432U #define MENUSTARTWIRECUT 67108864U /* bit 26 */ +#define MENUSTARTWIRECUT2 134217728U /* bit 27 : do not align cut point to snap */ #define SELECTED 1U /* used in the .sel field for selected objs. */ #define SELECTED1 2U /* first point selected... */ #define SELECTED2 4U /* second point selected... */ @@ -1313,7 +1314,7 @@ extern int rectclip(int,int,int,int, double*,double*,double*,double*); extern void trim_wires(void); extern void update_conn_cues(int layer, int draw_cues, int dr_win); -extern void break_wires_at_point(double x0, double y0); +extern void break_wires_at_point(double x0, double y0, int align); extern void break_wires_at_pins(int remove); extern void check_touch(int i, int j, diff --git a/src/xschem.tcl b/src/xschem.tcl index 673ae6a8..c51969b8 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -6221,6 +6221,8 @@ proc build_widgets { {topwin {} } } { $topwin.menubar.tools.menu add command -label "Remove wires running through selected inst. pins" \ -command "xschem break_wires 1" -accelerator {Ctrl-!} $topwin.menubar.tools.menu add command -label "Break wires at mouse position" \ + -command "xschem wire_cut noalign" -accelerator {Alt-Shift-Right Butt.} + $topwin.menubar.tools.menu add command -label "Break wires at mouse position, align cut point" \ -command "xschem wire_cut" -accelerator {Alt-Right Butt.} toolbar_add ToolBreak "xschem break_wires" "Break wires at selected\ninstance pin intersections" $topwin $topwin.menubar.tools.menu add checkbutton -label "Auto Join/Trim Wires" -variable autotrim_wires \