lock attribute for rectangles: work the same as for instances (can only double click to reset attributes, not selectable until lock reset to 0), add commands "xschem selected_set rect" and "xschem select_inside x1 y1 x2 y2"

This commit is contained in:
stefan schippers 2023-10-12 11:15:12 +02:00
parent a5545c3dbf
commit 676ce4fe3d
4 changed files with 73 additions and 15 deletions

View File

@ -507,6 +507,9 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
@ -638,9 +641,11 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
xschem expandlabel {2*A[3:0]} --> A[3],A[2],A[1],A[0],A[3],A[2],A[1],A[0] 8
last field is the number of bits
since [ and ] are TCL special characters argument must be quoted with { and } </pre>
<li><kbd> find_nth string sep n</kbd></li><pre>
<li><kbd> find_nth string sep quote keep_quote n</kbd></li><pre>
Find n-th field string separated by characters in sep. 1st field is in position 1
xschem find_nth {aaa,bbb,ccc,ddd} {,} 2 --&gt; bbb </pre>
do not split quoted fields (if quote characters are given) and return unquoted.
xschem find_nth {aaa,bbb,ccc,ddd} {,} 2 --&gt; bbb
xschem find_nth {aaa, "bbb, ccc" , ddd} { ,} {"} 2 --&gt; bbb, ccc</pre>
<li><kbd> flip [x0 y0]</kbd></li><pre>
Flip selection horizontally around point x0 y0.
if x0, y0 not given use mouse coordinates </pre>
@ -663,6 +668,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
<li><kbd> currsch </kbd> hierarchy level of current schematic (start at 0) </li>
<li><kbd> debug_var </kbd> debug level (0 = no debug, 1, 2, 3,...) </li>
<li><kbd> draw_window </kbd> direct draw into window </li>
<li><kbd> first_sel </kbd> get data about first selected object </li>
<li><kbd> fix_broken_tiled_fill </kbd> get drawing method setting (for broken GPUs) </li>
<li><kbd> format </kbd> alternate format attribute to use in netlist (or NULL) </li>
<li><kbd> graph_lastsel </kbd> number of last graph that was clicked </li>
@ -741,7 +747,8 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
Get value of attribute 'sym_attr' of symbol 'sym_name'
'with_quotes' (default:0) is an integer passed to get_tok_value()
getprop rect layer num attr
getprop rect layer num attr [with_quotes]
if '1' is given as 'keep' return backslashes and unescaped quotes if present in value
Get attribute 'attr' of rectangle number 'num' on layer 'layer'
getprop text num attr
@ -912,6 +919,8 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
if kissing is given add nets to pins that touch other instances or nets
if stretch is given stretch connected nets to follow instace pins
if dx and dy are given move by that amount. </pre>
<li><kbd> my_strtok_r str delim quote keep_quote</kbd></li><pre>
test for my_strtok_r() function </pre>
<li><kbd> net_label [type]</kbd></li><pre>
Place a new net label
'type': 1: place a 'lab_pin.sym' label
@ -1138,8 +1147,13 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
Returns number of selected items (wires,labels) if danglings found, 0 otherwise </pre>
<li><kbd> select_hilight_net</kbd></li><pre>
Select all highlight objects (wires, labels, pins, instances) </pre>
<li><kbd> selected_set</kbd></li><pre>
Return a list of selected instance names </pre>
<li><kbd> select_inside x1 y1 x2 y2 [sel]</kbd></li><pre>
Select all objects inside the indicated area
if [sel] is set to '0' do an unselect operation </pre>
<li><kbd> selected_set [what]</kbd></li><pre>
Return a list of selected instance names
If what is not given or set to 'inst' return list of selected instance names
If what set to 'rect' return list of selected rectangles with their coordinates </pre>
<li><kbd> selected_wire</kbd></li><pre>
Return list of selected nets </pre>
<li><kbd> send_to_viewer</kbd></li><pre>
@ -1277,6 +1291,8 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
Translate string 'str' replacing @xxx tokens with values in instance 'n' attributes
Example: xschem translate vref {the voltage is @value}
the voltage is 1.8 </pre>
<li><kbd> trim_chars str sep</kbd></li><pre>
Remove leading and trailing chars matching any character in 'sep' from str </pre>
<li><kbd> trim_wires</kbd></li><pre>
Remove operlapping wires, join lines, trim wires at intersections </pre>
<li><kbd> undo</kbd></li><pre>

View File

@ -223,7 +223,7 @@ static void find_closest_arc(double mx,double my)
}
static void find_closest_box(double mx,double my)
static void find_closest_box(double mx,double my, int override_lock)
{
double tmp;
int i,c,r=-1, col = 0;
@ -244,8 +244,7 @@ static void find_closest_box(double mx,double my)
} /* end for i */
} /* end for c */
dbg(1, "find_closest_box(): distance=%.16g\n", distance);
if( r!=-1)
{
if( r!=-1 && (override_lock || strboolcmp(get_tok_value(xctx->rect[col][r].prop_ptr, "lock", 0), "true"))) {
sel.n = r; sel.type = xRECT; sel.col = col;
}
}
@ -319,7 +318,7 @@ Selected find_closest_obj(double mx,double my, int override_lock)
find_closest_line(mx,my);
find_closest_polygon(mx,my);
/* dbg(1, "1 find_closest_obj(): sel.n=%d, sel.col=%d, sel.type=%d\n", sel.n, sel.col, sel.type); */
find_closest_box(mx,my);
find_closest_box(mx,my, override_lock);
find_closest_arc(mx,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);

View File

@ -3795,15 +3795,50 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
Tcl_ResetResult(interp);
}
/* selected_set
* Return a list of selected instance names */
/* select_inside x1 y1 x2 y2 [sel]
* Select all objects inside the indicated area
if [sel] is set to '0' do an unselect operation */
else if(!strcmp(argv[1], "select_inside"))
{
int sel = SELECTED;
double x1, y1, x2, y2;
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
if(argc > 6 && argv[6][0] == '0') sel = 0;
x1 = atof(argv[2]);
y1 = atof(argv[3]);
x2 = atof(argv[4]);
y2 = atof(argv[5]);
select_inside(x1, y1, x2, y2, sel);
Tcl_ResetResult(interp);
}
/* selected_set [what]
* Return a list of selected instance names
* If what is not given or set to 'inst' return list of selected instance names
* If what set to 'rect' return list of selected rectangles with their coordinates */
else if(!strcmp(argv[1], "selected_set"))
{
int n, i, first = 1;
int what = ELEMENT;
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
if(argc > 2) {
if(!strcmp(argv[2], "rect")) what = xRECT;
}
rebuild_selected_array();
for(n=0; n < xctx->lastsel; ++n) {
if(xctx->sel_array[n].type == ELEMENT) {
if(what == xRECT && xctx->sel_array[n].type == xRECT) {
char col[30], num[30], coord[200];
int c = xctx->sel_array[n].col;
i = xctx->sel_array[n].n;
my_strncpy(col, my_itoa(c), S(col));
my_strncpy(num, my_itoa(i), S(num));
my_snprintf(coord, S(coord), "%g %g %g %g",
xctx->rect[c][i].x1, xctx->rect[c][i].y1, xctx->rect[c][i].x2, xctx->rect[c][i].y2);
if(first == 0) Tcl_AppendResult(interp, "\n", NULL);
first = 0;
Tcl_AppendResult(interp,col, " ", num, " ", coord , NULL);
} else if(what == ELEMENT && xctx->sel_array[n].type == ELEMENT) {
i = xctx->sel_array[n].n;
if(first == 0) Tcl_AppendResult(interp, " ", NULL);
Tcl_AppendResult(interp, "{", xctx->inst[i].instname, "}", NULL);
@ -4214,7 +4249,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
}
}
if(change_done) set_modify(1);
set_rect_flags(r); /* set cached .flags bitmask from on attributes */
set_rect_flags(r); /* set cached .flags bitmask from attributes */
if(!fast) {
bbox(ADD, r->x1, r->y1, r->x2, r->y2);
/* redraw rect with new props */

View File

@ -1243,7 +1243,7 @@ Selected select_object(double mx,double my, unsigned short select_mode, int over
select_polygon(sel.col, sel.n, select_mode,0);
break;
case xRECT:
select_box(sel.col,sel.n, select_mode,0, 0);
select_box(sel.col,sel.n, select_mode,0, override_lock);
break;
case ARC:
select_arc(sel.col,sel.n, select_mode,0);
@ -1478,7 +1478,15 @@ void select_inside(double x1,double y1, double x2, double y2, int sel) /*added u
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);
if(sel) {
if(strboolcmp(get_tok_value(xctx->rect[c][i].prop_ptr, "lock", 0), "true")) {
select_box(c,i, SELECTED, 1, 1);
}
} else {
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) )