[Snap Cursor (WIP)]: Experimental feature 'snap_cursor' is now available to be selected from the Options menu (disabled by default). This is a work in progress and needs a lot more polishing to be properly usable. Currently only supports snapping to nearest component-endpoint.
This commit is contained in:
parent
ed1a471f5d
commit
320b8efc4b
|
|
@ -1393,6 +1393,51 @@ void draw_crosshair(int what)
|
|||
xctx->draw_pixmap = sdp;
|
||||
}
|
||||
|
||||
/* cursor_type == 0 : only erase drawn cursor
|
||||
* cursor_type == 1 : erase and draw a normal grid-snapping cursor
|
||||
* cursor_type == 2 : erase and draw a diamond-shaped cursor that snaps to a component endpoint */
|
||||
void draw_snap_cursor(int cursor_type)
|
||||
{
|
||||
int sdw, sdp;
|
||||
dbg(1, "draw_snap_cursor(): cursor_type=%d\n", cursor_type);
|
||||
sdw = xctx->draw_window;
|
||||
sdp = xctx->draw_pixmap;
|
||||
|
||||
if(!xctx->mouse_inside) return;
|
||||
xctx->draw_pixmap = 0;
|
||||
xctx->draw_window = 1;
|
||||
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));
|
||||
|
||||
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 {
|
||||
drawtemparc(xctx->gctiled, NOW, xctx->prev_crossx, xctx->prev_crossy, 1, 0, 360);
|
||||
}
|
||||
if(cursor_type != 1) {
|
||||
/*drawline(xctx->crosshair_layer, NOW, xctx->mousex_snap, xctx->mousey_snap, xctx->mousex_snap, xctx->mousey_snap, 0, NULL);*/
|
||||
double x, y;
|
||||
find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y);
|
||||
drawarc(xctx->crosshair_layer, NOW, x, y, 1, 1, 360, 1, 0);
|
||||
draw_selection(xctx->gc[SELLAYER], 0);
|
||||
xctx->prev_crossx = x;
|
||||
xctx->prev_crossy = y;
|
||||
} else {
|
||||
drawarc(xctx->crosshair_layer, NOW, xctx->mousex_snap, xctx->mousey_snap, 1, 1, 360, 1, 0);
|
||||
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;
|
||||
}
|
||||
|
||||
/* complete the STARTWIRE, STARTRECT, STARTZOOM, STARTCOPY ... operations */
|
||||
static int end_place_move_copy_zoom()
|
||||
{
|
||||
|
|
@ -2218,6 +2263,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
|
|||
#endif
|
||||
int draw_xhair = tclgetboolvar("draw_crosshair");
|
||||
int infix_interface = tclgetboolvar("infix_interface");
|
||||
int snap_cursor = tclgetboolvar("snap_cursor");
|
||||
int rstate; /* (reduced state, without ShiftMask) */
|
||||
|
||||
/* this fix uses an alternative method for getting mouse coordinates on KeyPress/KeyRelease
|
||||
|
|
@ -2335,6 +2381,7 @@ int rstate; /* (reduced state, without ShiftMask) */
|
|||
|
||||
case LeaveNotify:
|
||||
if(draw_xhair) draw_crosshair(1);
|
||||
if(snap_cursor) draw_snap_cursor(0);
|
||||
tclvareval(xctx->top_path, ".drw configure -cursor {}" , NULL);
|
||||
xctx->mouse_inside = 0;
|
||||
break;
|
||||
|
|
@ -2403,11 +2450,13 @@ int rstate; /* (reduced state, without ShiftMask) */
|
|||
if(draw_xhair) {
|
||||
draw_crosshair(1);
|
||||
}
|
||||
if(snap_cursor) draw_snap_cursor(0);
|
||||
if(xctx->ui_state & STARTPAN) pan(RUBBER, mx, my);
|
||||
if(xctx->semaphore >= 2) {
|
||||
if(draw_xhair) {
|
||||
draw_crosshair(2);
|
||||
}
|
||||
if(snap_cursor) draw_snap_cursor(2);
|
||||
break;
|
||||
}
|
||||
dbg(1, "ui_state=%d deltax=%g\n", xctx->ui_state, xctx->deltax);
|
||||
|
|
@ -2502,6 +2551,7 @@ int rstate; /* (reduced state, without ShiftMask) */
|
|||
if(draw_xhair) {
|
||||
draw_crosshair(2);
|
||||
}
|
||||
if(snap_cursor) draw_snap_cursor(2);
|
||||
break;
|
||||
|
||||
case KeyRelease:
|
||||
|
|
@ -4259,6 +4309,7 @@ int rstate; /* (reduced state, without ShiftMask) */
|
|||
statusmsg(str,1);
|
||||
}
|
||||
if(draw_xhair) draw_crosshair(0);
|
||||
if(snap_cursor) draw_snap_cursor(2);
|
||||
break;
|
||||
case -3: /* double click : edit prop */
|
||||
if( waves_selected(event, key, state, button)) {
|
||||
|
|
|
|||
98
src/draw.c
98
src/draw.c
|
|
@ -1601,6 +1601,104 @@ void drawarc(int c, int what, double x, double y, double r, double a, double b,
|
|||
}
|
||||
}
|
||||
|
||||
void draw_snap_point(int c, int what, double x, double y, double r, double a, double b, int arc_fill, int dash)
|
||||
{
|
||||
static int i=0;
|
||||
static XArc xarc[CADDRAWBUFFERSIZE];
|
||||
double x1, y1, x2, y2; /* arc bbox */
|
||||
double xx1, yy1, xx2, yy2; /* complete circle bbox in screen coords */
|
||||
GC gc;
|
||||
|
||||
if(arc_fill || dash) what = NOW;
|
||||
|
||||
if(!has_x) return;
|
||||
if(what & ADD)
|
||||
{
|
||||
if(i>=CADDRAWBUFFERSIZE)
|
||||
{
|
||||
if(xctx->draw_window) XDrawArcs(display, xctx->window, xctx->gc[c], xarc,i);
|
||||
if(xctx->draw_pixmap) XDrawArcs(display, xctx->save_pixmap, xctx->gc[c], xarc,i);
|
||||
i=0;
|
||||
}
|
||||
xx1=X_TO_SCREEN(x-r);
|
||||
yy1=Y_TO_SCREEN(y-r);
|
||||
xx2=X_TO_SCREEN(x+r);
|
||||
yy2=Y_TO_SCREEN(y+r);
|
||||
arc_bbox(x, y, r, a, b, &x1,&y1,&x2,&y2);
|
||||
x1=X_TO_SCREEN(x1);
|
||||
y1=Y_TO_SCREEN(y1);
|
||||
x2=X_TO_SCREEN(x2);
|
||||
y2=Y_TO_SCREEN(y2);
|
||||
if( rectclip(xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2,&x1,&y1,&x2,&y2) )
|
||||
{
|
||||
xarc[i].x=(short)xx1;
|
||||
xarc[i].y=(short)yy1;
|
||||
xarc[i].width =(unsigned short)(xx2 - xx1);
|
||||
xarc[i].height=(unsigned short)(yy2 - yy1);
|
||||
xarc[i].angle1 = (short)(a*64);
|
||||
xarc[i].angle2 = (short)(b*64);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
else if(what & NOW)
|
||||
{
|
||||
xx1=X_TO_SCREEN(x-r);
|
||||
yy1=Y_TO_SCREEN(y-r);
|
||||
xx2=X_TO_SCREEN(x+r);
|
||||
yy2=Y_TO_SCREEN(y+r);
|
||||
if(arc_fill)
|
||||
arc_bbox(x, y, r, 0, 360, &x1,&y1,&x2,&y2);
|
||||
else
|
||||
arc_bbox(x, y, r, a, b, &x1,&y1,&x2,&y2);
|
||||
x1=X_TO_SCREEN(x1);
|
||||
y1=Y_TO_SCREEN(y1);
|
||||
x2=X_TO_SCREEN(x2);
|
||||
y2=Y_TO_SCREEN(y2);
|
||||
if( rectclip(xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2,&x1,&y1,&x2,&y2) )
|
||||
{
|
||||
if(dash) {
|
||||
char dash_arr[2];
|
||||
dash_arr[0] = dash_arr[1] = (char)dash;
|
||||
XSetDashes(display, xctx->gc[c], 0, dash_arr, 1);
|
||||
XSetLineAttributes (display, xctx->gc[c], XLINEWIDTH(xctx->lw), xDashType, xCap, xJoin);
|
||||
}
|
||||
|
||||
if(xctx->draw_window) {
|
||||
XDrawArc(display, xctx->window, xctx->gc[c], (int)xx1, (int)yy1,
|
||||
(int)(xx2-xx1), (int)(yy2-yy1), (int)(a*64), (int)(b*64));
|
||||
}
|
||||
if(xctx->draw_pixmap) {
|
||||
XDrawArc(display, xctx->save_pixmap, xctx->gc[c], (int)xx1, (int)yy1,
|
||||
(int)(xx2-xx1), (int)(yy2-yy1), (int)(a*64), (int)(b*64));
|
||||
}
|
||||
|
||||
if(xctx->fill_pattern && (xctx->fill_type[c] || arc_fill == 3) ){
|
||||
|
||||
if(arc_fill & 2) gc = xctx->gc[c];
|
||||
else gc = xctx->gcstipple[c];
|
||||
if(arc_fill) {
|
||||
if(xctx->draw_window)
|
||||
XFillArc(display, xctx->window, gc, (int)xx1, (int)yy1,
|
||||
(int)(xx2-xx1), (int)(yy2-yy1), (int)(a*64), (int)(b*64));
|
||||
if(xctx->draw_pixmap)
|
||||
XFillArc(display, xctx->save_pixmap, gc, (int)xx1, (int)yy1,
|
||||
(int)(xx2-xx1), (int)(yy2-yy1), (int)(a*64), (int)(b*64));
|
||||
}
|
||||
}
|
||||
if(dash) {
|
||||
XSetLineAttributes (display, xctx->gc[c], XLINEWIDTH(xctx->lw) ,LineSolid, LINECAP , LINEJOIN);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if((what & END) && i)
|
||||
{
|
||||
if(xctx->draw_window) XDrawArcs(display, xctx->window, xctx->gc[c], xarc,i);
|
||||
if(xctx->draw_pixmap) XDrawArcs(display, xctx->save_pixmap, xctx->gc[c], xarc,i);
|
||||
i=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void filledrect(int c, int what, double rectx1,double recty1,double rectx2,double recty2, int fill,
|
||||
int e_a, int e_b)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7622,7 +7622,7 @@ set tctx::global_list {
|
|||
PDK_ROOT PDK SKYWATER_MODELS SKYWATER_STDCELLS
|
||||
INITIALINSTDIR INITIALLOADDIR INITIALPROPDIR INITIALTEXTDIR XSCHEM_LIBRARY_PATH
|
||||
add_all_windows_drives auto_hilight auto_hilight_graph_nodes autofocus_mainwindow
|
||||
autotrim_wires infix_interface orthogonal_wiring bespice_listen_port big_grid_points bus_replacement_char cadgrid cadlayers
|
||||
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 custom_label_prefix custom_token dark_colors dark_colorscheme
|
||||
dark_gui_colorscheme delay_flag dim_bg dim_value disable_unique_names
|
||||
|
|
@ -8042,7 +8042,7 @@ proc build_widgets { {topwin {} } } {
|
|||
global recentfile color_ps transparent_svg menu_debug_var enable_stretch
|
||||
global netlist_show flat_netlist split_files compare_sch intuitive_interface
|
||||
global draw_grid big_grid_points sym_txt change_lw incr_hilight symbol_width
|
||||
global cadsnap cadgrid draw_window toolbar_visible hide_symbols undo_type
|
||||
global cadsnap cadgrid draw_window toolbar_visible hide_symbols undo_type snap_cursor
|
||||
global disable_unique_names persistent_command autotrim_wires infix_interface orthogonal_wiring en_hilight_conn_inst
|
||||
global local_netlist_dir editor netlist_type netlist_dir spiceprefix initial_geometry
|
||||
if { $dark_gui_colorscheme} {
|
||||
|
|
@ -8168,6 +8168,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 "Enable snap cursor" -variable snap_cursor \
|
||||
-selectcolor $selectcolor
|
||||
$topwin.menubar.option add checkbutton -label "Enable orthogonal wiring" -variable orthogonal_wiring \
|
||||
-selectcolor $selectcolor -accelerator Shift+L
|
||||
$topwin.menubar.option add checkbutton -label "Unsel. partial sel. wires after stretch move" \
|
||||
|
|
@ -9101,6 +9103,7 @@ set_ne persistent_command 0
|
|||
set_ne intuitive_interface 1
|
||||
set_ne autotrim_wires 0
|
||||
set_ne infix_interface 0
|
||||
set_ne snap_cursor 0
|
||||
set_ne orthogonal_wiring 1
|
||||
set_ne compare_sch 0
|
||||
set_ne disable_unique_names 0
|
||||
|
|
|
|||
Loading…
Reference in New Issue