improve connect by kissing: now 3 move operations are present: 1) just move selection, 2) move adding wires to connected pins/wire endpoints, 3) move by stretching wires attached to pins/endpoints to follow moving objects
This commit is contained in:
parent
690486c848
commit
98ffd177ce
|
|
@ -168,8 +168,9 @@ alt+shift 'l' add lab_wire.sym to schematic
|
|||
alt 'l' add lab_pin.sym to schematic
|
||||
ctrl+shift 'o' Load most recent schematic
|
||||
ctrl 'o' Load schematic
|
||||
- 'm' Move selected obj.
|
||||
shift 'M' Move selected obj, insert wire when separating touching instance pins.
|
||||
- 'm' Move selected objects
|
||||
ctrl 'm' Move selected objects, stretching wires attached to them
|
||||
shift 'M' Move selected objects, insert wire when separating touching instance pins/wires
|
||||
Stretch wires that land on selected instance pins.
|
||||
shift 'N' Top level only netlist
|
||||
- 'n' Hierarchical Netlist
|
||||
|
|
|
|||
|
|
@ -965,6 +965,7 @@ void enable_layers(void)
|
|||
}
|
||||
}
|
||||
|
||||
/* Add wires when moving instances or wires */
|
||||
short connect_by_kissing(void)
|
||||
{
|
||||
xSymbol *symbol;
|
||||
|
|
@ -977,16 +978,22 @@ short connect_by_kissing(void)
|
|||
Wireentry *wptr;
|
||||
Instpinentry *iptr;
|
||||
int sqx, sqy;
|
||||
Str_hashtable coord_table = {NULL, 0}; /* hash table to add new wires at a given position only once */
|
||||
char coord[200]; /* string representation of 'x0 y0' or 'pinx0 piny0' */
|
||||
|
||||
str_hash_init(&coord_table, HASHSIZE);
|
||||
rebuild_selected_array();
|
||||
k = xctx->lastsel;
|
||||
prepare_netlist_structs(0);
|
||||
|
||||
/* add wires to moving instance pins */
|
||||
for(j=0;j<k; ++j) if(xctx->sel_array[j].type==ELEMENT) {
|
||||
x0 = xctx->inst[xctx->sel_array[j].n].x0;
|
||||
y0 = xctx->inst[xctx->sel_array[j].n].y0;
|
||||
rot = xctx->inst[xctx->sel_array[j].n].rot;
|
||||
flip = xctx->inst[xctx->sel_array[j].n].flip;
|
||||
symbol = xctx->sym + xctx->inst[xctx->sel_array[j].n].ptr;
|
||||
int inst = xctx->sel_array[j].n;
|
||||
x0 = xctx->inst[inst].x0;
|
||||
y0 = xctx->inst[inst].y0;
|
||||
rot = xctx->inst[inst].rot;
|
||||
flip = xctx->inst[inst].flip;
|
||||
symbol = xctx->sym + xctx->inst[inst].ptr;
|
||||
npin = symbol->rects[PINLAYER];
|
||||
rct=symbol->rect[PINLAYER];
|
||||
for(i=0;i<npin; ++i) {
|
||||
|
|
@ -1001,7 +1008,7 @@ short connect_by_kissing(void)
|
|||
kissing=0;
|
||||
while(iptr) {
|
||||
ii = iptr->n;
|
||||
if(ii == xctx->sel_array[j].n) {
|
||||
if(ii == inst) {
|
||||
iptr = iptr->next;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1018,7 +1025,7 @@ short connect_by_kissing(void)
|
|||
kissing=0;
|
||||
break;
|
||||
}
|
||||
else if( (pinx0 != w->x1 || piny0 != w->y1) && (pinx0 != w->x2 || piny0 != w->y2)) {
|
||||
else {
|
||||
kissing = 1;
|
||||
break;
|
||||
}
|
||||
|
|
@ -1027,17 +1034,85 @@ short connect_by_kissing(void)
|
|||
}
|
||||
if(kissing) {
|
||||
|
||||
dbg(1, "connect_by_kissing(): adding wire in %g %g, wires before = %d\n", pinx0, piny0, xctx->wires);
|
||||
if(!done_undo) {
|
||||
xctx->push_undo();
|
||||
done_undo = 1;
|
||||
}
|
||||
storeobject(-1, pinx0, piny0, pinx0, piny0, WIRE, 0, SELECTED1, NULL);
|
||||
changed = 1;
|
||||
xctx->need_reb_sel_arr = 1;
|
||||
my_snprintf(coord, S(coord), "%.16g %.16g", pinx0, piny0);
|
||||
if (str_hash_lookup(&coord_table, coord, "", XLOOKUP)==NULL) {
|
||||
dbg(1, "connect_by_kissing(): adding wire in %g %g, wires before = %d\n", pinx0, piny0, xctx->wires);
|
||||
str_hash_lookup(&coord_table, coord, "", XINSERT);
|
||||
storeobject(-1, pinx0, piny0, pinx0, piny0, WIRE, 0, SELECTED1, NULL);
|
||||
changed = 1;
|
||||
xctx->need_reb_sel_arr = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* add wires to moving wire endpoints */
|
||||
for(j=0; j < k; ++j) if(xctx->sel_array[j].type == WIRE) {
|
||||
int wire = xctx->sel_array[j].n;
|
||||
if(xctx->wire[wire].sel != SELECTED) continue; /* skip partially selected wires */
|
||||
for(i=0;i<2; ++i) {
|
||||
if(i == 0) {
|
||||
x0 = xctx->wire[wire].x1;
|
||||
y0 = xctx->wire[wire].y1;
|
||||
} else {
|
||||
x0 = xctx->wire[wire].x2;
|
||||
y0 = xctx->wire[wire].y2;
|
||||
}
|
||||
|
||||
get_square(x0, y0, &sqx, &sqy);
|
||||
iptr=xctx->instpin_spatial_table[sqx][sqy];
|
||||
wptr=xctx->wire_spatial_table[sqx][sqy];
|
||||
kissing=0;
|
||||
while(iptr) {
|
||||
ii = iptr->n;
|
||||
dbg(1, "connect_by_kissing(): ii=%d, x0=%g, y0=%g, iptr->x0=%g, iptr->y0=%g\n",
|
||||
ii, x0, y0, iptr->x0, iptr->y0);
|
||||
if( iptr->x0 == x0 && iptr->y0 == y0 && xctx->inst[ii].sel == 0) {
|
||||
kissing=1;
|
||||
break;
|
||||
}
|
||||
iptr = iptr->next;
|
||||
}
|
||||
while(wptr) {
|
||||
xWire *w = &xctx->wire[wptr->n];
|
||||
if(wire == wptr->n) {
|
||||
wptr = wptr->next;
|
||||
continue;
|
||||
}
|
||||
if( touch(w->x1, w->y1, w->x2, w->y2, x0, y0)) {
|
||||
if( w->sel) {
|
||||
kissing=0;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
kissing = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
wptr = wptr->next;
|
||||
}
|
||||
if(kissing) {
|
||||
if(!done_undo) {
|
||||
xctx->push_undo();
|
||||
done_undo = 1;
|
||||
}
|
||||
my_snprintf(coord, S(coord), "%.16g %.16g", x0, y0);
|
||||
if (str_hash_lookup(&coord_table, coord, "", XLOOKUP)==NULL) {
|
||||
dbg(1, "connect_by_kissing(): adding wire in %g %g, wires before = %d\n", x0, y0, xctx->wires);
|
||||
str_hash_lookup(&coord_table, coord, "", XINSERT);
|
||||
storeobject(-1, x0, y0, x0, y0, WIRE, 0, SELECTED1, NULL);
|
||||
changed = 1;
|
||||
xctx->need_reb_sel_arr = 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
str_hash_free(&coord_table);
|
||||
rebuild_selected_array();
|
||||
return changed;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2177,10 +2177,19 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
|
|||
xctx->mx_double_save=xctx->mousex_snap;
|
||||
xctx->my_double_save=xctx->mousey_snap;
|
||||
tclsetintvar("connect_by_kissing", 2); /* 2 will be used to reset var to 0 at end of move */
|
||||
select_attached_nets(); /* stretch nets that land on selected instance pins */
|
||||
/* select_attached_nets(); */ /* stretch nets that land on selected instance pins */
|
||||
move_objects(START,0,0,0);
|
||||
break;
|
||||
}
|
||||
if(key=='m' && state==ControlMask && !(xctx->ui_state & (STARTMOVE | STARTCOPY))) /* move selection */
|
||||
{
|
||||
xctx->mx_double_save=xctx->mousex_snap;
|
||||
xctx->my_double_save=xctx->mousey_snap;
|
||||
select_attached_nets(); /* stretch nets that land on selected instance pins */
|
||||
move_objects(START,0,0,0);
|
||||
break;
|
||||
}
|
||||
|
||||
if(key=='c' && state==0 && /* duplicate selection */
|
||||
!(xctx->ui_state & (STARTMOVE | STARTCOPY)))
|
||||
{
|
||||
|
|
@ -2636,7 +2645,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
|
|||
xctx->mx_double_save=xctx->mousex_snap;
|
||||
xctx->my_double_save=xctx->mousey_snap;
|
||||
/* stretch nets that land on selected instance pins if connect_by_kissing == 2 */
|
||||
select_attached_nets();
|
||||
/* select_attached_nets(); */
|
||||
move_objects(START,0,0,0);
|
||||
xctx->ui_state &=~MENUSTARTMOVE;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -128,8 +128,9 @@ alt+shift 'l' add lab_wire.sym to schematic
|
|||
alt 'l' add lab_pin.sym to schematic
|
||||
ctrl+shift 'o' Load most recent schematic
|
||||
ctrl 'o' Load schematic
|
||||
- 'm' Move selected obj.
|
||||
shift 'M' Move selected obj, insert wire when separating touching instance pins.
|
||||
- 'm' Move selected objects
|
||||
ctrl 'm' Move selected objects, stretching wires attached to them
|
||||
shift 'M' Move selected objects, insert wire when separating touching instance pins/wires
|
||||
Stretch wires that land on selected instance pins.
|
||||
shift 'N' Top level only netlist
|
||||
- 'n' Hierarchical Netlist
|
||||
|
|
|
|||
|
|
@ -2311,12 +2311,26 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
xctx->prep_hi_structs=0;
|
||||
}
|
||||
}
|
||||
/* move_objects [dx dy]
|
||||
/* move_objects [dx dy] [kissing] [stretch]
|
||||
* Start a move operation on selection and let user terminate the operation in the GUI
|
||||
* 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. */
|
||||
else if(!strcmp(argv[1], "move_objects"))
|
||||
{
|
||||
if(argc==4) {
|
||||
int kissing= 0;
|
||||
int stretch = 0;
|
||||
if(argc > 2) {
|
||||
int i;
|
||||
for(i = 2; i < argc; i++) {
|
||||
if(!strcmp(argv[i], "kissing")) kissing = 1;
|
||||
if(!strcmp(argv[i], "stretch")) stretch = 1;
|
||||
}
|
||||
}
|
||||
if(kissing | stretch) argc = 2;
|
||||
if(stretch) select_attached_nets();
|
||||
if(kissing) tclsetintvar("connect_by_kissing", 2);
|
||||
if(argc > 3) {
|
||||
move_objects(START,0,0,0);
|
||||
move_objects( END,0,atof(argv[2]), atof(argv[3]));
|
||||
}
|
||||
|
|
|
|||
71
src/select.c
71
src/select.c
|
|
@ -1239,48 +1239,21 @@ void select_attached_nets(void)
|
|||
int wire, inst, j, i, rects, r, sqx, sqy;
|
||||
double x0, y0;
|
||||
Wireentry *wptr;
|
||||
int cbk = (tclgetintvar("connect_by_kissing") == 2);
|
||||
|
||||
hash_wires();
|
||||
rebuild_selected_array();
|
||||
|
||||
if(cbk) {
|
||||
for(j=0;j<xctx->lastsel; ++j) {
|
||||
if(xctx->sel_array[j].type==ELEMENT) {
|
||||
inst = xctx->sel_array[j].n;
|
||||
if((xctx->inst[inst].ptr >= 0)) {
|
||||
rects = (xctx->inst[inst].ptr + xctx->sym)->rects[PINLAYER];
|
||||
for(r = 0; r < rects; r++)
|
||||
{
|
||||
get_inst_pin_coord(inst, r, &x0, &y0);
|
||||
get_square(x0, y0, &sqx, &sqy);
|
||||
for(wptr=xctx->wire_spatial_table[sqx][sqy]; wptr; wptr=wptr->next) {
|
||||
i = wptr->n;
|
||||
if(xctx->wire[i].x1 == x0 && xctx->wire[i].y1 == y0) {
|
||||
select_wire(i,SELECTED1, 1);
|
||||
}
|
||||
if(xctx->wire[i].x2 == x0 && xctx->wire[i].y2 == y0) {
|
||||
select_wire(i,SELECTED2, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(xctx->sel_array[j].type==WIRE) {
|
||||
wire = xctx->sel_array[j].n;
|
||||
for(r = 0; r < 2; r++)
|
||||
for(j=0;j<xctx->lastsel; ++j) {
|
||||
if(xctx->sel_array[j].type==ELEMENT) {
|
||||
inst = xctx->sel_array[j].n;
|
||||
if((xctx->inst[inst].ptr >= 0)) {
|
||||
rects = (xctx->inst[inst].ptr + xctx->sym)->rects[PINLAYER];
|
||||
for(r = 0; r < rects; r++)
|
||||
{
|
||||
if(r == 0) {
|
||||
x0 = xctx->wire[wire].x1;
|
||||
y0 = xctx->wire[wire].y1;
|
||||
} else {
|
||||
x0 = xctx->wire[wire].x2;
|
||||
y0 = xctx->wire[wire].y2;
|
||||
}
|
||||
get_inst_pin_coord(inst, r, &x0, &y0);
|
||||
get_square(x0, y0, &sqx, &sqy);
|
||||
for(wptr=xctx->wire_spatial_table[sqx][sqy]; wptr; wptr=wptr->next) {
|
||||
i = wptr->n;
|
||||
if(i == wire) continue;
|
||||
if(xctx->wire[i].x1 == x0 && xctx->wire[i].y1 == y0) {
|
||||
select_wire(i,SELECTED1, 1);
|
||||
}
|
||||
|
|
@ -1290,9 +1263,33 @@ void select_attached_nets(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
} /* for(j=0;j<xctx->lastsel; ++j) */
|
||||
rebuild_selected_array();
|
||||
} /* if(cbk) */
|
||||
}
|
||||
if(xctx->sel_array[j].type==WIRE) {
|
||||
wire = xctx->sel_array[j].n;
|
||||
for(r = 0; r < 2; r++)
|
||||
{
|
||||
if(r == 0) {
|
||||
x0 = xctx->wire[wire].x1;
|
||||
y0 = xctx->wire[wire].y1;
|
||||
} else {
|
||||
x0 = xctx->wire[wire].x2;
|
||||
y0 = xctx->wire[wire].y2;
|
||||
}
|
||||
get_square(x0, y0, &sqx, &sqy);
|
||||
for(wptr=xctx->wire_spatial_table[sqx][sqy]; wptr; wptr=wptr->next) {
|
||||
i = wptr->n;
|
||||
if(i == wire) continue;
|
||||
if(xctx->wire[i].x1 == x0 && xctx->wire[i].y1 == y0) {
|
||||
select_wire(i,SELECTED1, 1);
|
||||
}
|
||||
if(xctx->wire[i].x2 == x0 && xctx->wire[i].y2 == y0) {
|
||||
select_wire(i,SELECTED2, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* for(j=0;j<xctx->lastsel; ++j) */
|
||||
rebuild_selected_array();
|
||||
}
|
||||
|
||||
void select_inside(double x1,double y1, double x2, double y2, int sel) /*added unselect (sel param) */
|
||||
|
|
|
|||
|
|
@ -6043,7 +6043,9 @@ proc build_widgets { {topwin {} } } {
|
|||
toolbar_add EditDuplicate "xschem copy_objects" "Duplicate objects" $topwin
|
||||
$topwin.menubar.edit.menu add command -label "Move objects" -command "xschem move_objects" -accelerator M
|
||||
$topwin.menubar.edit.menu add command -label "Move objects stretching attached wires" \
|
||||
-command "set connect_by_kissing 2; xschem move_objects" -accelerator Shift+M
|
||||
-command "xschem move_objects stretch" -accelerator Control+M
|
||||
$topwin.menubar.edit.menu add command -label "Move objects adding wires to connected pins" \
|
||||
-command "xschem move_objects kissing" -accelerator Shift+M
|
||||
toolbar_add EditMove "xschem move_objects" "Move objects" $topwin
|
||||
$topwin.menubar.edit.menu add command -label "Flip selected objects" -command "xschem flip" -accelerator {Alt-F}
|
||||
$topwin.menubar.edit.menu add command -label "Rotate selected objects" -command "xschem rotate" -accelerator {Alt-R}
|
||||
|
|
|
|||
Loading…
Reference in New Issue