add tcl command "xschem change_elem_order n" add optional x0 and y0 coordinates as additional parameters to "xschem flip" and "xschem rotate" commands, add command "move_instance inst x y rot flip"

This commit is contained in:
stefan schippers 2023-09-17 00:13:52 +02:00
parent f99eb07e23
commit 978d575e22
5 changed files with 116 additions and 30 deletions

View File

@ -504,6 +504,8 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
@ -538,6 +540,8 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
Invoke the callback event dispatcher with a software event </pre>
<li><kbd> case_insensitive 1|0</kbd></li><pre>
Set case insensitive symbol lookup. Use only on case insensitive filesystems </pre>
<li><kbd> change_elem_order n</kbd></li><pre>
set selected object (instance, wire, line, rect, ...) to position 'n' in its respective array </pre>
<li><kbd> check_symbols</kbd></li><pre>
List all used symbols in current schematic and warn if some symbol is newer </pre>
<li><kbd> check_unique_names [1|0]</kbd></li><pre>
@ -631,8 +635,9 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
<li><kbd> find_nth string sep 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>
<li><kbd> flip</kbd></li><pre>
Flip selection horizontally </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>
<li><kbd> flip_in_place</kbd></li><pre>
Flip selection horizontally, each object around its center </pre>
<li><kbd> fullscreen</kbd></li><pre>
@ -880,6 +885,10 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
to deduce symbol interface pins. </pre>
<li><kbd> merge [f]</kbd></li><pre>
Merge another file. if 'f' not given prompt user. </pre>
<li><kbd> move_instance inst x y rot flip [nodraw] [noundo]</kbd></li><pre>
resets instance coordinates, and rotaton/flip. A dash will keep existing value
if 'nodraw' is given do not draw the moved instance
if 'noundo' is given operation is not undoable </pre>
<li><kbd> move_objects [dx dy]</kbd></li><pre>
Start a move operation on selection and let user terminate the operation in the GUI
if dx and dy are given move by that amount. </pre>
@ -1041,8 +1050,9 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
if 'net' is given return its topmost full hierarchy name
else returns the topmost full hierarchy name of selected net/pin/label.
Nets connected to I/O ports are mapped to upper level recursively </pre>
<li><kbd> rotate</kbd></li><pre>
Rotate selected objects around their centers </pre>
<li><kbd> rotate [x0 y0]</kbd></li><pre>
Rotate selection around point x0 y0.
if x0, y0 not given use mouse coordinates </pre>
<li><kbd> save</kbd></li><pre>
Save schematic if modified. Does not ask confirmation! </pre>
<li><kbd> saveas [file] [type]</kbd></li><pre>
@ -1293,6 +1303,9 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"

View File

@ -1913,7 +1913,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
if(key=='S' && state == ShiftMask) /* change element order */
{
if(xctx->semaphore >= 2) break;
change_elem_order();
change_elem_order(-1);
break;
}
if(key=='k' && state==Mod1Mask) /* select whole net (all attached wires/labels/pins) */
@ -2106,8 +2106,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;
move_objects(START,0,0,0);
if(xctx->lastsel>1) move_objects(FLIP,0,0,0);
else move_objects(FLIP|ROTATELOCAL,0,0,0);
move_objects(FLIP,0,0,0);
move_objects(END,0,0,0);
}
break;
@ -2142,8 +2141,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;
move_objects(START,0,0,0);
if(xctx->lastsel>1) move_objects(ROTATE,0,0,0);
else move_objects(ROTATE|ROTATELOCAL,0,0,0);
move_objects(ROTATE,0,0,0);
move_objects(END,0,0,0);
}

View File

@ -1520,7 +1520,7 @@ static int edit_symbol_property(int x, int first_sel)
return modified;
}
void change_elem_order(void)
void change_elem_order(int n)
{
xInstance tmpinst;
xRect tmpbox;
@ -1531,20 +1531,30 @@ void change_elem_order(void)
rebuild_selected_array();
if(xctx->lastsel==1)
{
my_snprintf(tmp_txt, S(tmp_txt), "%d",xctx->sel_array[0].n);
tclsetvar("retval",tmp_txt);
xctx->semaphore++;
tcleval("text_line {Object Sequence number} 0");
xctx->semaphore--;
if(strcmp(tclgetvar("rcode"),"") )
{
if(n < 0) {
my_snprintf(tmp_txt, S(tmp_txt), "%d",xctx->sel_array[0].n);
tclsetvar("retval",tmp_txt);
xctx->semaphore++;
tcleval("text_line {Object Sequence number} 0");
xctx->semaphore--;
if(strcmp(tclgetvar("rcode"),"") )
{
xctx->push_undo();
modified = 1;
xctx->prep_hash_inst=0;
xctx->prep_net_structs=0;
xctx->prep_hi_structs=0;
}
sscanf(tclgetvar("retval"), "%d",&new_n);
if(new_n < 0) new_n = 0;
} else {
new_n = n;
xctx->push_undo();
modified = 1;
xctx->prep_hash_inst=0;
xctx->prep_net_structs=0;
xctx->prep_hi_structs=0;
}
sscanf(tclgetvar("retval"), "%d",&new_n);
if(xctx->sel_array[0].type==ELEMENT)
{

View File

@ -366,6 +366,16 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
}
}
/* change_elem_order n
* set selected object (instance, wire, line, rect, ...) to position 'n' in its respective array */
else if(!strcmp(argv[1], "change_elem_order"))
{
if(argc > 2) {
int n = atoi(argv[2]);
if(n >= 0) change_elem_order(n);
}
}
/* check_symbols
* List all used symbols in current schematic and warn if some symbol is newer */
else if(!strcmp(argv[1], "check_symbols"))
@ -822,19 +832,23 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
}
}
/* flip
* Flip selection horizontally */
/* flip [x0 y0]
* Flip selection horizontally around point x0 y0.
* if x0, y0 not given use mouse coordinates */
else if(!strcmp(argv[1], "flip"))
{
double x0 = xctx->mousex_snap;
double y0 = xctx->mousey_snap;
if(argc > 3) {
x0 = atof(argv[2]);
y0 = atof(argv[3]);
}
if(! (xctx->ui_state & (STARTMOVE | STARTCOPY) ) ) {
rebuild_selected_array();
xctx->mx_double_save=xctx->mousex_snap;
xctx->my_double_save=xctx->mousey_snap;
xctx->mx_double_save = xctx->mousex_snap = x0;
xctx->my_double_save = xctx->mousey_snap = y0;
move_objects(START,0,0,0);
if(xctx->lastsel>1) move_objects(FLIP,0, 0, 0);
else move_objects(FLIP|ROTATELOCAL,0,0,0);
xctx->deltax = -xctx->mx_double_save;
xctx->deltay = 0;
move_objects(FLIP,0, 0, 0);
move_objects(END,0,0,0);
}
Tcl_ResetResult(interp);
@ -2249,6 +2263,48 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
Tcl_ResetResult(interp);
}
/* move_instance inst x y rot flip [nodraw] [noundo]
* resets instance coordinates, and rotaton/flip. A dash will keep existing value
* if 'nodraw' is given do not draw the moved instance
* if 'noundo' is given operation is not undoable */
else if(!strcmp(argv[1], "move_instance"))
{
int undo = 1, dr = 1;
if(argc > 7) {
int i;
for(i = 7; i < argc; i++) {
if(!strcmp(argv[i], "nodraw")) dr = 0;
if(!strcmp(argv[i], "noundo")) undo = 0;
}
}
if(argc > 6) {
int i;
if((i = get_instance(argv[2])) < 0 ) {
Tcl_SetResult(interp, "xschem pinlist: instance not found", TCL_STATIC);
return TCL_ERROR;
}
if(undo) xctx->push_undo();
if(dr) {
bbox(START,0.0,0.0,0.0,0.0);
bbox(ADD, xctx->inst[i].x1, xctx->inst[i].y1, xctx->inst[i].x2, xctx->inst[i].y2);
}
if(strcmp(argv[3], "-")) xctx->inst[i].x0 = atof(argv[3]);
if(strcmp(argv[4], "-")) xctx->inst[i].y0 = atof(argv[4]);
if(strcmp(argv[5], "-")) xctx->inst[i].rot = (unsigned short)atoi(argv[5]);
if(strcmp(argv[6], "-")) xctx->inst[i].flip = (unsigned short)atoi(argv[6]);
symbol_bbox(i, &xctx->inst[i].x1, &xctx->inst[i].y1, &xctx->inst[i].x2, &xctx->inst[i].y2);
if(dr) {
bbox(ADD, xctx->inst[i].x1, xctx->inst[i].y1, xctx->inst[i].x2, xctx->inst[i].y2);
bbox(SET,0.0,0.0,0.0,0.0);
draw();
bbox(END,0.0,0.0,0.0,0.0);
}
set_modify(1);
xctx->prep_hash_inst=0;
xctx->prep_net_structs=0;
xctx->prep_hi_structs=0;
}
}
/* move_objects [dx dy]
* Start a move operation on selection and let user terminate the operation in the GUI
* if dx and dy are given move by that amount. */
@ -3118,14 +3174,23 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
my_free(_ALLOC_ID_, &rn);
}
/* rotate
* Rotate selected objects around their centers */
/* rotate [x0 y0]
* Rotate selection around point x0 y0.
* if x0, y0 not given use mouse coordinates */
else if(!strcmp(argv[1], "rotate"))
{
double x0 = xctx->mousex_snap;
double y0 = xctx->mousey_snap;
if(argc > 3) {
x0 = atof(argv[2]);
y0 = atof(argv[3]);
}
if(! (xctx->ui_state & (STARTMOVE | STARTCOPY) ) ) {
rebuild_selected_array();
xctx->mx_double_save = xctx->mousex_snap = x0;
xctx->my_double_save = xctx->mousey_snap = y0;
move_objects(START,0,0,0);
move_objects(ROTATE|ROTATELOCAL,0,0,0);
move_objects(ROTATE,0,0,0);
move_objects(END,0,0,0);
}
Tcl_ResetResult(interp);

View File

@ -1556,7 +1556,7 @@ extern void hilight_child_pins(void);
extern void hilight_parent_pins(void);
extern void hilight_net_pin_mismatches(void);
extern Node_hashentry **get_node_table_ptr(void);
extern void change_elem_order(void);
extern void change_elem_order(int n);
extern int is_generator(const char *name);
extern char *str_chars_replace(const char *str, const char *replace_set, const char with);
extern char *str_replace(const char *str, const char *rep, const char *with, int escape);