[Snap Cursor (WIP)]: Experimental feature 'snap_cursor' is updated. It can be selected from the Options menu (disabled by default) and will take effect when the wire-drawing mode is active. This is a work in progress and needs a lot more polishing to be properly usable. Currently only supports snapping to nearest component-endpoint. Cursor to snap to nearest grid point is pending.
This commit is contained in:
parent
73789df48c
commit
7f613294f4
|
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
|
||||
#include "xschem.h"
|
||||
#include <X11/X.h>
|
||||
|
||||
/* allow to use the Windows keys as alternate for Alt */
|
||||
#define SET_MODMASK ( (rstate & Mod1Mask) || (rstate & Mod4Mask) )
|
||||
|
|
@ -1393,9 +1394,9 @@ 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 */
|
||||
/* cursor_type == 0 : erase and draw a new cursor
|
||||
* cursor_type == 1 : erase the cursor
|
||||
* cursor_type == 2 : draw a diamond-shaped cursor that snaps to a component endpoint */
|
||||
void draw_snap_cursor(int cursor_type)
|
||||
{
|
||||
int sdw, sdp;
|
||||
|
|
@ -1406,33 +1407,27 @@ void draw_snap_cursor(int cursor_type)
|
|||
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 != 2) {
|
||||
if(fix_broken_tiled_fill || !_unix) {
|
||||
MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], 0, 0, xctx->xrect[0].width, xctx->xrect[0].height, 0, 0);
|
||||
} else {
|
||||
double prev_x = xctx->prev_crossx;
|
||||
double prev_y = xctx->prev_crossy;
|
||||
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};
|
||||
drawtemppolygon(xctx->gctiled, NOW, points_x, points_y, 5, 0);
|
||||
}
|
||||
}
|
||||
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);
|
||||
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);
|
||||
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;
|
||||
}
|
||||
draw_selection(xctx->gc[SELLAYER], 0);
|
||||
|
||||
xctx->draw_window = sdw;
|
||||
xctx->draw_pixmap = sdp;
|
||||
|
|
@ -2264,6 +2259,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
|
|||
int draw_xhair = tclgetboolvar("draw_crosshair");
|
||||
int infix_interface = tclgetboolvar("infix_interface");
|
||||
int snap_cursor = tclgetboolvar("snap_cursor");
|
||||
int wire_draw_active = (xctx->ui_state & STARTWIRE) || (xctx->ui_state2 & MENUSTARTWIRE) || (tclgetboolvar("persistent_command") && (xctx->last_command & STARTWIRE));
|
||||
int rstate; /* (reduced state, without ShiftMask) */
|
||||
|
||||
/* this fix uses an alternative method for getting mouse coordinates on KeyPress/KeyRelease
|
||||
|
|
@ -2298,7 +2294,7 @@ int rstate; /* (reduced state, without ShiftMask) */
|
|||
}
|
||||
#endif
|
||||
|
||||
if((xctx->ui_state & STARTWIRE) || (xctx->ui_state2 & MENUSTARTWIRE) || (tclgetboolvar("persistent_command") && (xctx->last_command & STARTWIRE))) {
|
||||
if(wire_draw_active) {
|
||||
tclvareval(xctx->top_path, ".statusbar.10 configure -state active -text {DRAW WIRE! }", NULL);
|
||||
} else {
|
||||
tclvareval(xctx->top_path, ".statusbar.10 configure -state normal -text { }", NULL);
|
||||
|
|
@ -2381,7 +2377,7 @@ int rstate; /* (reduced state, without ShiftMask) */
|
|||
|
||||
case LeaveNotify:
|
||||
if(draw_xhair) draw_crosshair(1);
|
||||
if(snap_cursor) draw_snap_cursor(0);
|
||||
if(snap_cursor && wire_draw_active) draw_snap_cursor(1);
|
||||
tclvareval(xctx->top_path, ".drw configure -cursor {}" , NULL);
|
||||
xctx->mouse_inside = 0;
|
||||
break;
|
||||
|
|
@ -2450,13 +2446,13 @@ int rstate; /* (reduced state, without ShiftMask) */
|
|||
if(draw_xhair) {
|
||||
draw_crosshair(1);
|
||||
}
|
||||
if(snap_cursor) draw_snap_cursor(0);
|
||||
if(snap_cursor && wire_draw_active) draw_snap_cursor(1);
|
||||
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);
|
||||
if(snap_cursor && wire_draw_active) draw_snap_cursor(2);
|
||||
break;
|
||||
}
|
||||
dbg(1, "ui_state=%d deltax=%g\n", xctx->ui_state, xctx->deltax);
|
||||
|
|
@ -2551,7 +2547,7 @@ int rstate; /* (reduced state, without ShiftMask) */
|
|||
if(draw_xhair) {
|
||||
draw_crosshair(2);
|
||||
}
|
||||
if(snap_cursor) draw_snap_cursor(2);
|
||||
if(snap_cursor && wire_draw_active) draw_snap_cursor(2);
|
||||
break;
|
||||
|
||||
case KeyRelease:
|
||||
|
|
@ -2792,7 +2788,7 @@ int rstate; /* (reduced state, without ShiftMask) */
|
|||
hilight_net_pin_mismatches();
|
||||
break;
|
||||
}
|
||||
if(key== 'W' /* && !xctx->ui_state */ && rstate == 0) { /* create wire snapping to closest instance pin */
|
||||
if(key== 's' /* && !xctx->ui_state */ && rstate == 0) { /* create wire snapping to closest instance pin */
|
||||
if(xctx->semaphore >= 2) break;
|
||||
snapped_wire(c_snap);
|
||||
break;
|
||||
|
|
@ -3034,7 +3030,7 @@ int rstate; /* (reduced state, without ShiftMask) */
|
|||
draw(); /* needed to ungrey or grey out components due to *_ignore attribute */
|
||||
break;
|
||||
}
|
||||
if(key=='s' && rstate == 0 ) /* simulate */
|
||||
if(key=='r' && rstate == ControlMask ) /* simulate */
|
||||
{
|
||||
if(xctx->semaphore >= 2) break;
|
||||
if(waves_selected(event, key, state, button)) {
|
||||
|
|
@ -4309,7 +4305,7 @@ int rstate; /* (reduced state, without ShiftMask) */
|
|||
statusmsg(str,1);
|
||||
}
|
||||
if(draw_xhair) draw_crosshair(0);
|
||||
if(snap_cursor) draw_snap_cursor(2);
|
||||
if(snap_cursor && wire_draw_active) draw_snap_cursor(0);
|
||||
break;
|
||||
case -3: /* double click : edit prop */
|
||||
if( waves_selected(event, key, state, button)) {
|
||||
|
|
|
|||
98
src/draw.c
98
src/draw.c
|
|
@ -1601,104 +1601,6 @@ 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)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue