diff --git a/src/actions.c b/src/actions.c index 58df511e..44a890db 100644 --- a/src/actions.c +++ b/src/actions.c @@ -298,7 +298,9 @@ void set_snap(double newsnap) /* 20161212 set new snap factor and just notify n tclvareval(xctx->top_path, ".statusbar.3 configure -background OrangeRed", NULL); } } + xctx->cadhalfdotsize = CADHALFDOTSIZE * (cs < 10. ? cs : 10.) / 10.; tclsetdoublevar("cadsnap", cs); + draw(); } void set_grid(double newgrid) @@ -2485,11 +2487,11 @@ void calc_drawing_bbox(xRect *boundbox, int selected) !xctx->wire[i].node[0] || !bus_hilight_hash_lookup(xctx->wire[i].node, 0,XLOOKUP)) continue; } if(xctx->wire[i].bus){ - ov = INT_BUS_WIDTH(xctx->lw)> cadhalfdotsize ? INT_BUS_WIDTH(xctx->lw) : CADHALFDOTSIZE; + ov = INT_BUS_WIDTH(xctx->lw)> xctx->cadhalfdotsize ? INT_BUS_WIDTH(xctx->lw) : CADHALFDOTSIZE; if(xctx->wire[i].y1 < xctx->wire[i].y2) { y1 = xctx->wire[i].y1-ov; y2 = xctx->wire[i].y2+ov; } else { y1 = xctx->wire[i].y1+ov; y2 = xctx->wire[i].y2-ov; } } else { - ov = cadhalfdotsize; + ov = xctx->cadhalfdotsize; if(xctx->wire[i].y1 < xctx->wire[i].y2) { y1 = xctx->wire[i].y1-ov; y2 = xctx->wire[i].y2+ov; } else { y1 = xctx->wire[i].y1+ov; y2 = xctx->wire[i].y2-ov; } } @@ -2597,8 +2599,8 @@ void zoom_full(int dr, int sel, int flags, double shrink) dbg(1, "zoom_full(): dr=%d sel=%d flags=%d areaw=%d, areah=%d\n", sel, dr, flags, xctx->areaw, xctx->areah); if(flags & 1) change_linewidth(-1.); /* we do this here since change_linewidth may not be called if flags & 1 == 0*/ - /* cadhalfdotsize = CADHALFDOTSIZE + 0.04 * (tclgetdoublevar("cadsnap")-10); */ - cadhalfdotsize = 4.0 * (cs < 10. ? cs : 10.) / 10.; + /* xctx->cadhalfdotsize = CADHALFDOTSIZE + 0.04 * (tclgetdoublevar("cadsnap")-10); */ + xctx->cadhalfdotsize = 4.0 * (cs < 10. ? cs : 10.) / 10.; if(dr && has_x) { draw(); redraw_w_a_l_r_p_rubbers(); diff --git a/src/callback.c b/src/callback.c index 9d2edff9..67be0ad4 100644 --- a/src/callback.c +++ b/src/callback.c @@ -1305,6 +1305,7 @@ int rstate; /* (reduced state, without ShiftMask) */ break; } + dbg(1, "ui_state=%d deltax=%g\n", xctx->ui_state, xctx->deltax); if(xctx->ui_state) { if(abs(mx-xctx->mx_save) > 8 || abs(my-xctx->my_save) > 8 ) { my_snprintf(str, S(str), "mouse = %.16g %.16g - selected: %d w=%.16g h=%.16g", @@ -1316,11 +1317,15 @@ int rstate; /* (reduced state, without ShiftMask) */ } } if(xctx->ui_state & STARTZOOM) zoom_rectangle(RUBBER); + + /* determine direction of a rectangle selection (or unselection with ALT key) */ if(xctx->ui_state & STARTSELECT && !(xctx->ui_state & (PLACE_SYMBOL | STARTPAN | PLACE_TEXT)) ) { - if( (state & Button1Mask) && SET_MODMASK) { /* 20171026 added unselect by area */ + /* Unselect by area : determine direction */ + if( (state & Button1Mask) && SET_MODMASK) { if(mx >= xctx->mx_save) xctx->nl_dir = 0; else xctx->nl_dir = 1; select_rect(RUBBER,0); + /* select by area : determine direction */ } else if(state & Button1Mask) { if(mx >= xctx->mx_save) xctx->nl_dir = 0; else xctx->nl_dir = 1; @@ -1339,12 +1344,13 @@ int rstate; /* (reduced state, without ShiftMask) */ } redraw_w_a_l_r_p_rubbers(); - /* start of a mouse area select. No shift pressed */ + /* start of a mouse area select. Button1 pressed. No shift pressed */ if(!(xctx->ui_state & STARTPOLYGON) && (state&Button1Mask) && !(xctx->ui_state & STARTWIRE) && !(xctx->ui_state & STARTPAN) && !(SET_MODMASK) && !(state & ShiftMask) && !(xctx->ui_state & (PLACE_SYMBOL | PLACE_TEXT))) { - if(mx != xctx->mx_save || my != xctx->my_save) { + + if(!xctx->poly_point_selected && (mx != xctx->mx_save || my != xctx->my_save)) { if( !(xctx->ui_state & STARTSELECT)) { select_rect(START,1); xctx->onetime=1; @@ -3128,13 +3134,45 @@ int rstate; /* (reduced state, without ShiftMask) */ if( !(xctx->ui_state & STARTSELECT) && !(xctx->ui_state & STARTWIRE) && !(xctx->ui_state & STARTLINE) ) { Selected sel; int prev_last_sel = xctx->lastsel; + int polygon_n = -1, polygon_c = -1; + xctx->poly_point_selected = 0; xctx->mx_save = mx; xctx->my_save = my; xctx->mx_double_save=xctx->mousex_snap; xctx->my_double_save=xctx->mousey_snap; + + if(xctx->lastsel == 1 && xctx->sel_array[0].type==POLYGON) { + dbg(1, "1 Polygon selected\n"); + polygon_n = xctx->sel_array[0].n; + polygon_c = xctx->sel_array[0].col; + } if( !(state & ShiftMask) && !(SET_MODMASK) ) { unselect_all(1); } - sel = select_object(xctx->mousex, xctx->mousey, SELECTED, 0); + /* Check is user is clicking a control point of a polygon */ + if(polygon_n >= 0) { + int i; + double ds = xctx->cadhalfdotsize; + xPoly *p = &xctx->poly[polygon_c][polygon_n]; + for(i = 0; i < p->points; i++) { + if( + POINTINSIDE(xctx->mousex, xctx->mousey, p->x[i] - ds, p->y[i] - ds, + p->x[i] + ds, p->y[i] + ds) + ) { + dbg(1, "selecting point %d\n", i); + xctx->poly[polygon_c][polygon_n].selected_point[i] = 1; + xctx->poly_point_selected = 1; + } + } + if(xctx->poly_point_selected) { + /* select_polygon(polygon_c, polygon_n, SELECTED1,1); */ + xctx->poly[polygon_c][polygon_n].sel = SELECTED1; + xctx->need_reb_sel_arr=1; + move_objects(START,0,0,0); + } + } + if(!xctx->poly_point_selected) { + sel = select_object(xctx->mousex, xctx->mousey, SELECTED, 0); + } rebuild_selected_array(); #ifndef __unix__ draw_selection(xctx->gc[SELLAYER], 0); @@ -3164,6 +3202,23 @@ int rstate; /* (reduced state, without ShiftMask) */ } /* button==Button1 */ break; case ButtonRelease: + + /* if a polygon/bezier control point was clicked, end point move operation + * and set polygon state back to SELECTED from SELECTED1 */ + if((xctx->ui_state & (STARTMOVE | SELECTION)) && xctx->poly_point_selected) { + if(xctx->lastsel == 1 && xctx->sel_array[0].type==POLYGON) { + int k; + int n = xctx->sel_array[0].n; + int c = xctx->sel_array[0].col; + move_objects(END,0,0,0); + xctx->poly[c][n].sel = SELECTED; + for(k=0; kpoly[c][n].points; ++k) { + xctx->poly[c][n].selected_point[k] = 0; + } + xctx->need_reb_sel_arr=1; + } + } + if(waves_selected(event, key, state, button)) { waves_callback(event, mx, my, key, button, aux, state); break; @@ -3186,8 +3241,11 @@ int rstate; /* (reduced state, without ShiftMask) */ tclsetboolvar("enable_stretch", es); break; } else { - /* 20150927 filter out button4 and button5 events */ - if(!(state&(Button4Mask|Button5Mask) ) ) select_rect(END,-1); + /* Button1 release: end of rectangle select */ + if(!(state & (Button4Mask|Button5Mask) ) ) { + + select_rect(END,-1); + } } if(draw_xhair) draw_crosshair(0); rebuild_selected_array(); diff --git a/src/check.c b/src/check.c index 1b0b12c1..5ed485c8 100644 --- a/src/check.c +++ b/src/check.c @@ -58,7 +58,7 @@ void update_conn_cues(int layer, int draw_cues, int dr_win) hash_wires(); /* must be done also if wires==0 to clear wire_spatial_table */ if(!xctx->wires) return; if(!xctx->draw_dots) return; - if(cadhalfdotsize*xctx->mooz<0.7) return; + if(xctx->cadhalfdotsize*xctx->mooz<0.7) return; x1 = X_TO_XSCHEM(xctx->areax1); y1 = Y_TO_XSCHEM(xctx->areay1); x2 = X_TO_XSCHEM(xctx->areax2); @@ -107,10 +107,10 @@ void update_conn_cues(int layer, int draw_cues, int dr_win) if(LINE_OUTSIDE(wire[i].x1, wire[i].y1, wire[i].x2, wire[i].y2, x1, y1, x2, y2)) continue; if( wire[i].end1 >1 ) { - filledarc(layer, ADD, wire[i].x1, wire[i].y1, cadhalfdotsize, 0, 360); + filledarc(layer, ADD, wire[i].x1, wire[i].y1, xctx->cadhalfdotsize, 0, 360); } if( wire[i].end2 >1 ) { - filledarc(layer, ADD, wire[i].x2, wire[i].y2, cadhalfdotsize, 0, 360); + filledarc(layer, ADD, wire[i].x2, wire[i].y2, xctx->cadhalfdotsize, 0, 360); } } filledarc(layer, END, 0.0, 0.0, 0.0, 0.0, 0.0); @@ -527,7 +527,7 @@ void break_wires_at_point(double x0, double y0, int align) draw(); xctx->draw_window = 1; xctx->draw_pixmap = 0; - filledarc(PINLAYER, NOW, x0, y0, cadhalfdotsize, 0, 360); + filledarc(PINLAYER, NOW, x0, y0, xctx->cadhalfdotsize, 0, 360); xctx->draw_window = w; xctx->draw_pixmap = p; diff --git a/src/draw.c b/src/draw.c index f92a229d..fa5d34f2 100644 --- a/src/draw.c +++ b/src/draw.c @@ -1735,7 +1735,7 @@ void drawbezier(Drawable w, GC gc, int c, double *x, double *y, int points, int #if 0 if(points == 4) { if(gc == xctx->gc[SELLAYER]) for(i = 0; i < points; i++) { - drawtemparc(gc, NOW, x[i], y[i], cadhalfdotsize, 0., 360.); + drawtemparc(gc, NOW, x[i], y[i], xctx->cadhalfdotsize, 0., 360.); } i = 0; for(t = 0; t <= 1.0; t += bez_steps) { @@ -1839,14 +1839,14 @@ void drawtemppolygon(GC gc, int what, double *x, double *y, int points, int flag bezier = flags && (points > 2); if((fix_broken_tiled_fill || !_unix) && gc == xctx->gctiled) { MyXCopyAreaDouble(display, xctx->save_pixmap, xctx->window, xctx->gc[0], - x1 - cadhalfdotsize, y1 - cadhalfdotsize, - x2 + cadhalfdotsize, y2 + cadhalfdotsize, - x1 - cadhalfdotsize, y1 - cadhalfdotsize, xctx->lw); + x1 - xctx->cadhalfdotsize, y1 - xctx->cadhalfdotsize, + x2 + xctx->cadhalfdotsize, y2 + xctx->cadhalfdotsize, + x1 - xctx->cadhalfdotsize, y1 - xctx->cadhalfdotsize, xctx->lw); } else { if(gc == xctx->gc[SELLAYER]) for(i = 0; i < points; i++) { if( POINTINSIDE(X_TO_SCREEN(x[i]), Y_TO_SCREEN(y[i]), xctx->areax1, xctx->areay1, xctx->areax2, xctx->areay2)) { - drawtemparc(gc, NOW, x[i], y[i], cadhalfdotsize, 0., 360.); + drawtemparc(gc, NOW, x[i], y[i], xctx->cadhalfdotsize, 0., 360.); } } if(bezier) { @@ -4158,13 +4158,17 @@ void draw(void) int cc, c, i = 0 /*, floaters = 0 */; xSymbol *symptr; int textlayer; + double cs; #if HAS_CAIRO==1 const char *textfont; #endif dbg(1, "draw()\n"); + if(!xctx || xctx->no_draw) return; + cs = tclgetdoublevar("cadsnap"); + xctx->cadhalfdotsize = 4.0 * (cs < 10. ? cs : 10.) / 10.; xctx->crosshair_layer = tclgetintvar("crosshair_layer"); if(xctx->crosshair_layer < 0 ) xctx->crosshair_layer = 2; if(xctx->crosshair_layer >= cadlayers ) xctx->crosshair_layer = 2; diff --git a/src/editprop.c b/src/editprop.c index 1046f2ad..7c91cba4 100644 --- a/src/editprop.c +++ b/src/editprop.c @@ -1036,7 +1036,7 @@ static int edit_wire_property(void) bus_ptr = get_tok_value(xctx->wire[k].prop_ptr,"bus",0); if(!strboolcmp(bus_ptr, "true")) { double ov, y1, y2; - ov = INT_BUS_WIDTH(xctx->lw) > cadhalfdotsize ? INT_BUS_WIDTH(xctx->lw) : CADHALFDOTSIZE; + ov = INT_BUS_WIDTH(xctx->lw) > xctx->cadhalfdotsize ? INT_BUS_WIDTH(xctx->lw) : CADHALFDOTSIZE; if(xctx->wire[k].y1 < xctx->wire[k].y2) { y1 = xctx->wire[k].y1-ov; y2 = xctx->wire[k].y2+ov; } else { y1 = xctx->wire[k].y1+ov; y2 = xctx->wire[k].y2-ov; } bbox(ADD, xctx->wire[k].x1-ov, y1 , xctx->wire[k].x2+ov , y2 ); @@ -1044,7 +1044,7 @@ static int edit_wire_property(void) } else { if(oldbus){ double ov, y1, y2; - ov = INT_BUS_WIDTH(xctx->lw)> cadhalfdotsize ? INT_BUS_WIDTH(xctx->lw) : CADHALFDOTSIZE; + ov = INT_BUS_WIDTH(xctx->lw)> xctx->cadhalfdotsize ? INT_BUS_WIDTH(xctx->lw) : CADHALFDOTSIZE; if(xctx->wire[k].y1 < xctx->wire[k].y2) { y1 = xctx->wire[k].y1-ov; y2 = xctx->wire[k].y2+ov; } else { y1 = xctx->wire[k].y1+ov; y2 = xctx->wire[k].y2-ov; } bbox(ADD, xctx->wire[k].x1-ov, y1 , xctx->wire[k].x2+ov , y2 ); @@ -1190,7 +1190,8 @@ static int edit_polygon_property(void) if(k==0 || xctx->poly[c][i].x[k] > x2) x2 = xctx->poly[c][i].x[k]; if(k==0 || xctx->poly[c][i].y[k] > y2) y2 = xctx->poly[c][i].y[k]; } - bbox(ADD, x1-cadhalfdotsize, y1-cadhalfdotsize, x2+cadhalfdotsize, y2+cadhalfdotsize); + bbox(ADD, x1-xctx->cadhalfdotsize, y1-xctx->cadhalfdotsize, + x2+xctx->cadhalfdotsize, y2+xctx->cadhalfdotsize); } } if(drw) { diff --git a/src/globals.c b/src/globals.c index 9519b918..7a5b04ee 100644 --- a/src/globals.c +++ b/src/globals.c @@ -179,7 +179,6 @@ char pwd_dir[PATH_MAX]; /* obtained via getcwd() */ int tcp_port = 0; int text_svg=1; /* use svg element for text instead of xschem's internal vector font */ int text_ps=1; /* use ps font for text instead of xschem's internal vector font */ -double cadhalfdotsize = CADHALFDOTSIZE; char bus_char[3] = {0, 0, 0}; int yyparse_error = 0; char *xschem_executable=NULL; diff --git a/src/hilight.c b/src/hilight.c index 975a976c..c9506269 100644 --- a/src/hilight.c +++ b/src/hilight.c @@ -2045,12 +2045,14 @@ void draw_hilight_net(int on_window) else drawline(get_color(entry->value), NOW, xctx->wire[i].x1, xctx->wire[i].y1, xctx->wire[i].x2, xctx->wire[i].y2, 0, NULL); - if(cadhalfdotsize*xctx->mooz>=0.7) { + if(xctx->cadhalfdotsize*xctx->mooz>=0.7) { if( xctx->wire[i].end1 >1 ) { - filledarc(get_color(entry->value), NOW, xctx->wire[i].x1, xctx->wire[i].y1, cadhalfdotsize, 0, 360); + filledarc(get_color(entry->value), NOW, xctx->wire[i].x1, xctx->wire[i].y1, + xctx->cadhalfdotsize, 0, 360); } if( xctx->wire[i].end2 >1 ) { - filledarc(get_color(entry->value), NOW, xctx->wire[i].x2, xctx->wire[i].y2, cadhalfdotsize, 0, 360); + filledarc(get_color(entry->value), NOW, xctx->wire[i].x2, xctx->wire[i].y2, + xctx->cadhalfdotsize, 0, 360); } } } diff --git a/src/move.c b/src/move.c index 19a2b707..7b3c62b2 100644 --- a/src/move.c +++ b/src/move.c @@ -882,6 +882,7 @@ void move_objects(int what, int merge, double dx, double dy) xLine ** const line = xctx->line; xWire * const wire = xctx->wire; + dbg(1, "move_objects: what=%d, dx=%g, dy=%g\n", what, dx, dy); if(what & START) { xctx->rotatelocal=0; diff --git a/src/psprint.c b/src/psprint.c index 1b266f5e..24a901c2 100644 --- a/src/psprint.c +++ b/src/psprint.c @@ -1306,10 +1306,10 @@ void create_ps(char **psfile, int what, int fullzoom, int eps) } i = wireptr->n; if( xctx->wire[i].end1 >1 ) { - ps_drawarc(WIRELAYER, 1, xctx->wire[i].x1, xctx->wire[i].y1, cadhalfdotsize, 0, 360, 0); + ps_drawarc(WIRELAYER, 1, xctx->wire[i].x1, xctx->wire[i].y1, xctx->cadhalfdotsize, 0, 360, 0); } if( xctx->wire[i].end2 >1 ) { - ps_drawarc(WIRELAYER, 1, xctx->wire[i].x2, xctx->wire[i].y2, cadhalfdotsize, 0, 360, 0); + ps_drawarc(WIRELAYER, 1, xctx->wire[i].x2, xctx->wire[i].y2, xctx->cadhalfdotsize, 0, 360, 0); } } } diff --git a/src/svgdraw.c b/src/svgdraw.c index 6513661f..c9e3980b 100644 --- a/src/svgdraw.c +++ b/src/svgdraw.c @@ -878,10 +878,10 @@ void svg_draw(void) color = get_color(entry->value); } if( xctx->wire[i].end1 >1 ) { - svg_drawcircle(color, 1, xctx->wire[i].x1, xctx->wire[i].y1, cadhalfdotsize, 0, 360); + svg_drawcircle(color, 1, xctx->wire[i].x1, xctx->wire[i].y1, xctx->cadhalfdotsize, 0, 360); } if( xctx->wire[i].end2 >1 ) { - svg_drawcircle(color, 1, xctx->wire[i].x2, xctx->wire[i].y2, cadhalfdotsize, 0, 360); + svg_drawcircle(color, 1, xctx->wire[i].x2, xctx->wire[i].y2, xctx->cadhalfdotsize, 0, 360); } } } diff --git a/src/xinit.c b/src/xinit.c index 0847f03e..396f62f6 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -579,6 +579,7 @@ static void alloc_xschem_data(const char *top_path, const char *win_path) xctx->nl_sel = xctx->nl_sem = xctx->nl_dir = 0; xctx->hilight_time = 0; /* timestamp for sims */ + xctx->poly_point_selected = 0; xctx->hilight_nets = 0; xctx->hilight_color = 0; for(i=0;ilw=xctx->mooz * 0.09 * cs; - cadhalfdotsize = CADHALFDOTSIZE * (cs < 10. ? cs : 10.) / 10.; - /* cadhalfdotsize = CADHALFDOTSIZE + 0.04 * (cs-10); */ + xctx->cadhalfdotsize = CADHALFDOTSIZE * (cs < 10. ? cs : 10.) / 10.; + /* xctx->cadhalfdotsize = CADHALFDOTSIZE + 0.04 * (cs-10); */ } /* explicitly set line width */ } else { diff --git a/src/xschem.h b/src/xschem.h index a5716dbb..976de503 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -983,7 +983,7 @@ typedef struct { Int_hashtable floater_inst_table; Node_hashentry **node_table; Hilight_hashentry **hilight_table; - + int poly_point_selected; int hilight_nets; int hilight_color; int hilight_time; /* timestamp for sims */ @@ -1123,6 +1123,7 @@ typedef struct { int draw_pixmap; /* pixmap used as 2nd buffer */ int draw_window; /* MIRRORED IN TCL */ int do_copy_area; + double cadhalfdotsize; time_t time_last_modify; int undo_type; /* 0: on disk, 1: in memory */ void (*push_undo)(void);