diff --git a/src/callback.c b/src/callback.c index 643db9dd..e5d3fde2 100644 --- a/src/callback.c +++ b/src/callback.c @@ -2925,6 +2925,16 @@ int draw_xhair = tclgetboolvar("draw_crosshair"); if(xctx->semaphore >= 2) break; dbg(1, "callback(): DoubleClick ui_state=%d state=%d\n",xctx->ui_state,state); if(button==Button1) { + int sel; + if(!xctx->lastsel) { + /* Following 5 lines do again a selection overriding lock, + * so locked instance attrs can be edited */ + sel = select_object(xctx->mousex, xctx->mousey, SELECTED, 1); + if(sel) { + xctx->ui_state = SELECTION; + rebuild_selected_array(); + } + } if(xctx->ui_state == 0 || xctx->ui_state == SELECTION) { edit_property(0); } else { diff --git a/src/findnet.c b/src/findnet.c index f1f7794a..78bd239b 100644 --- a/src/findnet.c +++ b/src/findnet.c @@ -250,7 +250,7 @@ static void find_closest_box(double mx,double my) } } -static void find_closest_element(double mx,double my) +static void find_closest_element(double mx,double my, int override_lock) { double tmp; int i,r=-1; @@ -268,7 +268,7 @@ static void find_closest_element(double mx,double my) dbg(2, "find_closest_element(): finding closest element, instances=%d, dist=%.16g\n",i,tmp); } } /* end for i */ - if( r!=-1 && strboolcmp(get_tok_value(xctx->inst[r].prop_ptr, "lock", 0), "true") ) { + if( r!=-1 && (override_lock || strboolcmp(get_tok_value(xctx->inst[r].prop_ptr, "lock", 0), "true")) ) { sel.n = r; sel.type = ELEMENT; } } @@ -312,7 +312,7 @@ static void find_closest_text(double mx,double my) } } -Selected find_closest_obj(double mx,double my) +Selected find_closest_obj(double mx,double my, int override_lock) { sel.n = 0L; sel.col = 0; sel.type = 0; distance = DBL_MAX; @@ -324,7 +324,7 @@ Selected find_closest_obj(double mx,double my) /* dbg(1, "2 find_closest_obj(): sel.n=%d, sel.col=%d, sel.type=%d\n", sel.n, sel.col, sel.type); */ find_closest_text(mx,my); find_closest_net(mx,my); - find_closest_element(mx,my); + find_closest_element(mx,my, override_lock); return sel; /*sel.type = 0 if nothing found */ } diff --git a/src/select.c b/src/select.c index 11a1242d..b6aeaa7a 100644 --- a/src/select.c +++ b/src/select.c @@ -1201,7 +1201,7 @@ void select_line(int c, int i, unsigned short select_mode, int fast ) unsigned short select_object(double mx,double my, unsigned short select_mode, int override_lock) { Selected sel; - sel = find_closest_obj(mx, my); + sel = find_closest_obj(mx, my, override_lock); dbg(1, "select_object(): sel.n=%d, sel.col=%d, sel.type=%d\n", sel.n, sel.col, sel.type); @@ -1359,121 +1359,127 @@ void select_inside(double x1,double y1, double x2, double y2, int sel) /*added u if(RECT_INSIDE(xctx->inst[i].xx1, xctx->inst[i].yy1, xctx->inst[i].xx2, xctx->inst[i].yy2, x1,y1,x2,y2)) { xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */ - sel ? select_element(i,SELECTED,1, 1): select_element(i,0,1, 0); + if(sel) { + if(strboolcmp(get_tok_value(xctx->inst[i].prop_ptr, "lock", 0), "true")) { + select_element(i, SELECTED, 1, 1); + } + } else { + select_element(i, 0, 1, 0); + } } } for(c=0;cenable_layer[c]) continue; - for(i=0;ipolygons[c]; ++i) { - int k, selected_points, flag; - - polygon_bbox(xctx->poly[c][i].x, xctx->poly[c][i].y, xctx->poly[c][i].points, &xa, &ya, &xb, &yb); - if(OUTSIDE(xa, ya, xb, yb, x1, y1, x2, y2)) continue; - selected_points = 0; - flag=0; - for(k=0; kpoly[c][i].points; ++k) { - if(xctx->poly[c][i].sel==SELECTED) xctx->poly[c][i].selected_point[k] = 1; - if( POINTINSIDE(xctx->poly[c][i].x[k],xctx->poly[c][i].y[k], x1,y1,x2,y2)) { - flag=1; - xctx->poly[c][i].selected_point[k] = (short)sel; - } - if(xctx->poly[c][i].selected_point[k]) selected_points++; + if(!xctx->enable_layer[c]) continue; + for(i=0;ipolygons[c]; ++i) { + int k, selected_points, flag; + + polygon_bbox(xctx->poly[c][i].x, xctx->poly[c][i].y, xctx->poly[c][i].points, &xa, &ya, &xb, &yb); + if(OUTSIDE(xa, ya, xb, yb, x1, y1, x2, y2)) continue; + selected_points = 0; + flag=0; + for(k=0; kpoly[c][i].points; ++k) { + if(xctx->poly[c][i].sel==SELECTED) xctx->poly[c][i].selected_point[k] = 1; + if( POINTINSIDE(xctx->poly[c][i].x[k],xctx->poly[c][i].y[k], x1,y1,x2,y2)) { + flag=1; + xctx->poly[c][i].selected_point[k] = (short)sel; + } + if(xctx->poly[c][i].selected_point[k]) selected_points++; + } + if(flag) { + if(selected_points==0) { + select_polygon(c, i, 0, 1); + } + if(selected_points==xctx->poly[c][i].points) { + xctx->ui_state |= SELECTION; + select_polygon(c, i, SELECTED, 1); + } else if(selected_points) { + /* for polygon, SELECTED1 means partial sel */ + if(sel && en_s) select_polygon(c, i, SELECTED1,1); + } + } + + } + for(i=0;ilines[c]; ++i) + { + if(RECT_INSIDE(xctx->line[c][i].x1,xctx->line[c][i].y1,xctx->line[c][i].x2,xctx->line[c][i].y2, x1,y1,x2,y2)) + { + xctx->ui_state |= SELECTION; + sel? select_line(c,i,SELECTED,1): select_line(c,i,0,1); } - if(flag) { - if(selected_points==0) { - select_polygon(c, i, 0, 1); - } - if(selected_points==xctx->poly[c][i].points) { - xctx->ui_state |= SELECTION; - select_polygon(c, i, SELECTED, 1); - } else if(selected_points) { - /* for polygon, SELECTED1 means partial sel */ - if(sel && en_s) select_polygon(c, i, SELECTED1,1); - } + else if( sel && en_s && POINTINSIDE(xctx->line[c][i].x1,xctx->line[c][i].y1, x1,y1,x2,y2) ) + { + xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */ + select_line(c, i,SELECTED1,1); + } + else if( sel && en_s && POINTINSIDE(xctx->line[c][i].x2,xctx->line[c][i].y2, x1,y1,x2,y2) ) + { + xctx->ui_state |= SELECTION; + select_line(c, i,SELECTED2,1); } - - } - for(i=0;ilines[c]; ++i) - { - if(RECT_INSIDE(xctx->line[c][i].x1,xctx->line[c][i].y1,xctx->line[c][i].x2,xctx->line[c][i].y2, x1,y1,x2,y2)) - { - xctx->ui_state |= SELECTION; - sel? select_line(c,i,SELECTED,1): select_line(c,i,0,1); } - else if( sel && en_s && POINTINSIDE(xctx->line[c][i].x1,xctx->line[c][i].y1, x1,y1,x2,y2) ) - { - xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */ - select_line(c, i,SELECTED1,1); + for(i=0;iarcs[c]; ++i) { + x = xctx->arc[c][i].x; + y = xctx->arc[c][i].y; + a = xctx->arc[c][i].a; + b = xctx->arc[c][i].b; + r = xctx->arc[c][i].r; + xa = x + r * cos(a * XSCH_PI/180.); + ya = y - r * sin(a * XSCH_PI/180.); + xb = x + r * cos((a+b) * XSCH_PI/180.); + yb = y - r * sin((a+b) * XSCH_PI/180.); + arc_bbox(x, y, r, a, b, &tmp.x1, &tmp.y1, &tmp.x2, &tmp.y2); + if(RECT_INSIDE(tmp.x1, tmp.y1, tmp.x2, tmp.y2, x1,y1,x2,y2)) { + xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */ + sel? select_arc(c, i, SELECTED,1): select_arc(c, i, 0,1); + } + else if( sel && en_s && POINTINSIDE(x, y, x1, y1, x2, y2) ) + { + xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */ + select_arc(c, i,SELECTED1,1); + } + else if( sel && en_s && POINTINSIDE(xb, yb, x1, y1, x2, y2) ) + { + xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */ + select_arc(c, i,SELECTED3,1); + } + else if( sel && en_s && POINTINSIDE(xa, ya, x1, y1, x2, y2) ) + { + xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */ + select_arc(c, i,SELECTED2,1); + } } - else if( sel && en_s && POINTINSIDE(xctx->line[c][i].x2,xctx->line[c][i].y2, x1,y1,x2,y2) ) + for(i=0;irects[c]; ++i) { - xctx->ui_state |= SELECTION; - select_line(c, i,SELECTED2,1); - } - } - for(i=0;iarcs[c]; ++i) { - x = xctx->arc[c][i].x; - y = xctx->arc[c][i].y; - a = xctx->arc[c][i].a; - b = xctx->arc[c][i].b; - r = xctx->arc[c][i].r; - xa = x + r * cos(a * XSCH_PI/180.); - ya = y - r * sin(a * XSCH_PI/180.); - xb = x + r * cos((a+b) * XSCH_PI/180.); - yb = y - r * sin((a+b) * XSCH_PI/180.); - arc_bbox(x, y, r, a, b, &tmp.x1, &tmp.y1, &tmp.x2, &tmp.y2); - if(RECT_INSIDE(tmp.x1, tmp.y1, tmp.x2, tmp.y2, x1,y1,x2,y2)) { + if(RECT_INSIDE(xctx->rect[c][i].x1,xctx->rect[c][i].y1,xctx->rect[c][i].x2,xctx->rect[c][i].y2, x1,y1,x2,y2)) + { xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */ - sel? select_arc(c, i, SELECTED,1): select_arc(c, i, 0,1); + sel? select_box(c,i, SELECTED, 1, 1): select_box(c,i, 0, 1, 0); } - else if( sel && en_s && POINTINSIDE(x, y, x1, y1, x2, y2) ) - { - xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */ - select_arc(c, i,SELECTED1,1); + else if(c != GRIDLAYER || !(xctx->rect[c][i].flags & 2048)){ /* no stretch on unscaled images */ + if( sel && en_s && POINTINSIDE(xctx->rect[c][i].x1,xctx->rect[c][i].y1, x1,y1,x2,y2) ) + { /*20070302 added stretch select */ + xctx->ui_state |= SELECTION; + select_box(c, i,SELECTED1,1, 0); + } + if( sel && en_s && POINTINSIDE(xctx->rect[c][i].x2,xctx->rect[c][i].y1, x1,y1,x2,y2) ) + { + xctx->ui_state |= SELECTION; + select_box(c, i,SELECTED2,1, 0); + } + if( sel && en_s && POINTINSIDE(xctx->rect[c][i].x1,xctx->rect[c][i].y2, x1,y1,x2,y2) ) + { + xctx->ui_state |= SELECTION; + select_box(c, i,SELECTED3,1, 0); + } + if( sel && en_s && POINTINSIDE(xctx->rect[c][i].x2,xctx->rect[c][i].y2, x1,y1,x2,y2) ) + { + xctx->ui_state |= SELECTION; + select_box(c, i,SELECTED4,1, 0); + } } - else if( sel && en_s && POINTINSIDE(xb, yb, x1, y1, x2, y2) ) - { - xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */ - select_arc(c, i,SELECTED3,1); - } - else if( sel && en_s && POINTINSIDE(xa, ya, x1, y1, x2, y2) ) - { - xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */ - select_arc(c, i,SELECTED2,1); - } - } - for(i=0;irects[c]; ++i) - { - if(RECT_INSIDE(xctx->rect[c][i].x1,xctx->rect[c][i].y1,xctx->rect[c][i].x2,xctx->rect[c][i].y2, x1,y1,x2,y2)) - { - xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */ - sel? select_box(c,i, SELECTED, 1, 1): select_box(c,i, 0, 1, 0); - } - else if(c != GRIDLAYER || !(xctx->rect[c][i].flags & 2048)){ /* no stretch on unscaled images */ - if( sel && en_s && POINTINSIDE(xctx->rect[c][i].x1,xctx->rect[c][i].y1, x1,y1,x2,y2) ) - { /*20070302 added stretch select */ - xctx->ui_state |= SELECTION; - select_box(c, i,SELECTED1,1, 0); - } - if( sel && en_s && POINTINSIDE(xctx->rect[c][i].x2,xctx->rect[c][i].y1, x1,y1,x2,y2) ) - { - xctx->ui_state |= SELECTION; - select_box(c, i,SELECTED2,1, 0); - } - if( sel && en_s && POINTINSIDE(xctx->rect[c][i].x1,xctx->rect[c][i].y2, x1,y1,x2,y2) ) - { - xctx->ui_state |= SELECTION; - select_box(c, i,SELECTED3,1, 0); - } - if( sel && en_s && POINTINSIDE(xctx->rect[c][i].x2,xctx->rect[c][i].y2, x1,y1,x2,y2) ) - { - xctx->ui_state |= SELECTION; - select_box(c, i,SELECTED4,1, 0); - } - } - - } /* end for i */ + + } /* end for i */ } /* end for c */ drawtemparc(xctx->gc[SELLAYER], END, 0.0, 0.0, 0.0, 0.0, 0.0); drawtemprect(xctx->gc[SELLAYER], END, 0.0, 0.0, 0.0, 0.0); diff --git a/src/xschem.h b/src/xschem.h index 7c1a8573..add74f37 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -966,7 +966,7 @@ typedef struct { int nl_points, nl_maxpoints; /* select_rect */ double nl_xr, nl_yr, nl_xr2, nl_yr2; - int nl_sel, nl_sem; + int nl_sel, nl_sem; /* nl_sel is the select mode (select) the select_rect() was called with */ /* compare_schematics */ char sch_to_compare[PATH_MAX]; /* pan */ @@ -1277,7 +1277,7 @@ extern void draw_crosshair(int del); extern int callback(const char *winpath, int event, int mx, int my, KeySym key, int button, int aux, int state); extern void resetwin(int create_pixmap, int clear_pixmap, int force, int w, int h); -extern Selected find_closest_obj(double mx,double my); +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);