From f9546b6ebd00b72fd9aa70788488a7a9a0fc124b Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Mon, 17 Mar 2025 13:08:37 +0100 Subject: [PATCH 1/6] add ORDER() before storing new wires (manhattan mode) in move operation --- src/move.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/move.c b/src/move.c index 038856b7..19c451e4 100644 --- a/src/move.c +++ b/src/move.c @@ -1147,6 +1147,7 @@ void move_objects(int what, int merge, double dx, double dy) { wire[n].x2 = xctx->rx2; wire[n].y2 = xctx->ry1; + ORDER(xctx->rx2,xctx->ry1,xctx->rx2,xctx->ry2); storeobject(-1, xctx->rx2,xctx->ry1,xctx->rx2,xctx->ry2,WIRE,0,0,NULL); hash_wire(XINSERT, xctx->wires-1, 1); drawline(WIRELAYER,ADD, xctx->rx2,xctx->ry1,xctx->rx2,xctx->ry2, 0, NULL); @@ -1155,12 +1156,14 @@ void move_objects(int what, int merge, double dx, double dy) { wire[n].x2 = xctx->rx1; wire[n].y2 = xctx->ry2; + ORDER(xctx->rx1,xctx->ry2,xctx->rx2,xctx->ry2); storeobject(-1, xctx->rx1,xctx->ry2,xctx->rx2,xctx->ry2,WIRE,0,0,NULL); hash_wire(XINSERT, xctx->wires-1, 1); drawline(WIRELAYER,ADD, xctx->rx1,xctx->ry2,xctx->rx2,xctx->ry2, 0, NULL); } else { + /* no need for ordering coordinates - already done before */ wire[n].x2 = xctx->rx2; wire[n].y2 = xctx->ry2; } From abfa38b1e4204f484977b0ed2a71acb37ca5f34b Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Mon, 17 Mar 2025 19:23:55 +0100 Subject: [PATCH 2/6] make move of wires with `manhattan_lines` consistent, keep last wire segment selected. TBD: fix orthogonal_wiring modes --- src/move.c | 228 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 172 insertions(+), 56 deletions(-) diff --git a/src/move.c b/src/move.c index 19c451e4..d07ffe5c 100644 --- a/src/move.c +++ b/src/move.c @@ -377,26 +377,42 @@ void draw_selection(GC g, int interruptable) ORDER(xctx->rx1,xctx->ry1,xctx->rx2,xctx->ry2); if(xctx->wire[n].sel==SELECTED) { - if(xctx->wire[n].bus) - drawtemp_manhattanline(g, THICK, xctx->rx1+xctx->deltax, xctx->ry1+xctx->deltay, - xctx->rx2+xctx->deltax, xctx->ry2+xctx->deltay, 1); - else - drawtemp_manhattanline(g, ADD, xctx->rx1+xctx->deltax, xctx->ry1+xctx->deltay, - xctx->rx2+xctx->deltax, xctx->ry2+xctx->deltay, 1); + double x1 = xctx->rx1 + xctx->deltax; + double y1 = xctx->ry1 + xctx->deltay; + double x2 = xctx->rx2 + xctx->deltax; + double y2 = xctx->ry2 + xctx->deltay; + dbg(1, "draw_selection() wire: %g %g - %g %g manhattan=%d\n", x1, y1, x2, y2, xctx->manhattan_lines); + if(xctx->wire[n].bus) { + drawtemp_manhattanline(g, THICK, x1, y1, x2, y2, 1); + } else { + drawtemp_manhattanline(g, ADD, x1, y1, x2, y2, 1); + } } else if(xctx->wire[n].sel==SELECTED1) { - if(xctx->wire[n].bus) - drawtemp_manhattanline(g, THICK, xctx->rx1+xctx->deltax, xctx->ry1+xctx->deltay, xctx->rx2, xctx->ry2, 1); - else - drawtemp_manhattanline(g, ADD, xctx->rx1+xctx->deltax, xctx->ry1+xctx->deltay, xctx->rx2, xctx->ry2, 1); + double x1 = xctx->rx1 + xctx->deltax; + double y1 = xctx->ry1 + xctx->deltay; + double x2 = xctx->rx2; + double y2 = xctx->ry2; + dbg(1, "draw_selection() wire: %g %g - %g %g manhattan=%d\n", x1, y1, x2, y2, xctx->manhattan_lines); + if(xctx->wire[n].bus) { + drawtemp_manhattanline(g, THICK, x2, y2, x1, y1, 1); + } else { + drawtemp_manhattanline(g, ADD, x2, y2, x1, y1, 1); + } } else if(xctx->wire[n].sel==SELECTED2) { - if(xctx->wire[n].bus) - drawtemp_manhattanline(g, THICK, xctx->rx1, xctx->ry1, xctx->rx2+xctx->deltax, xctx->ry2+xctx->deltay, 1); - else - drawtemp_manhattanline(g, ADD, xctx->rx1, xctx->ry1, xctx->rx2+xctx->deltax, xctx->ry2+xctx->deltay, 1); + double x1 = xctx->rx1; + double y1 = xctx->ry1; + double x2 = xctx->rx2 + xctx->deltax; + double y2 = xctx->ry2 + xctx->deltay; + dbg(1, "draw_selection() wire: %g %g - %g %g manhattan=%d\n", x1, y1, x2, y2, xctx->manhattan_lines); + if(xctx->wire[n].bus) { + drawtemp_manhattanline(g, THICK, x1, y1, x2, y2, 1); + } else { + drawtemp_manhattanline(g, ADD, x1, y1, x2, y2, 1); + } } break; case LINE: @@ -991,6 +1007,145 @@ void copy_objects(int what) } +/* order wire points and swap SELECTED1 / SELECTED2 if needed */ +static void order_wire_points(int n) +{ + xWire * const wire = xctx->wire; + double x1, y1; + + x1=wire[n].x1; + y1=wire[n].y1; + ORDER(wire[n].x1, wire[n].y1, wire[n].x2, wire[n].y2); + if( x1 == wire[n].x2 && y1 == wire[n].y2) /* wire points reversed, so swap SELECTEDn */ + { + if(wire[n].sel == SELECTED1) wire[n].sel = SELECTED2; + else if(wire[n].sel == SELECTED2) wire[n].sel = SELECTED1; + } +} + +/* xctx->{rx1, ry1} and xctx->{rx2, ry2} are the two line points after the move. + * they are not guaranteed to be ordered (since only one of the two points may have changed) + * so this must be taken care for */ +static void place_moved_wire(int n, int orthogonal_wiring) +{ + xWire * const wire = xctx->wire; + + + /* FIXME: Chayan Deb: this needs to be updated + * If things get too complicated a place_moved_wire_orthogonal() can be created + */ + if((wire[n].sel & (SELECTED|SELECTED1)) && orthogonal_wiring) + { + if(xctx->manhattan_lines & 1) xctx->manhattan_lines=2; + else if(xctx->manhattan_lines & 2) xctx->manhattan_lines=1; + } + + /* wire x1,y1 point was moved + * + * x1,y1(old) rx2,ry2 + * -----------------o-----------------o + * | (H) + * selected |(V) + * | + * o + * rx1,ry1(new) + */ + if(wire[n].sel == SELECTED1 && (xctx->manhattan_lines & 1)) /* H - V */ + { + int last; + wire[n].x1 = xctx->rx1; + wire[n].y1 = xctx->ry1; + wire[n].x2 = xctx->rx1; + wire[n].y2 = xctx->ry2; + order_wire_points(n); + storeobject(-1, xctx->rx1,xctx->ry2,xctx->rx2,xctx->ry2,WIRE,0,0,NULL); + last = xctx->wires-1; + order_wire_points(last); + /* drawline(WIRELAYER,NOW, wire[last].x1, wire[last].y1, wire[last].x2, wire[last].y2, 0, NULL); */ + } + + /* wire x2,y2 point was moved + * + * rx1,ry1 x2,y2(old) + * o-----------------o----------------- + * (H) | + * (V)| selected + * | + * o + * rx2,ry2(new) + */ + else if(wire[n].sel == SELECTED2 && (xctx->manhattan_lines & 1)) /* H - V */ + { + int last; + wire[n].x1 = xctx->rx2; + wire[n].y1 = xctx->ry1; + wire[n].x2 = xctx->rx2; + wire[n].y2 = xctx->ry2; + order_wire_points(n); + storeobject(-1, xctx->rx1,xctx->ry1,xctx->rx2,xctx->ry1,WIRE,0,0,NULL); + last = xctx->wires-1; + order_wire_points(last); + /* drawline(WIRELAYER,NOW, wire[last].x1, wire[last].y1, wire[last].x2, wire[last].y2, 0, NULL); */ + } + + /* wire x1,y1 point was moved + * + * x1,y1(old) rx2,ry2 + * o-----------------o + * | + * (V)| + * (H) selected | + * o----------------------------------- + * rx1,ry1(new) + */ + else if(wire[n].sel == SELECTED1 && (xctx->manhattan_lines & 2)) /* V - H */ + { + int last; + wire[n].x1 = xctx->rx1; + wire[n].y1 = xctx->ry1; + wire[n].x2 = xctx->rx2; + wire[n].y2 = xctx->ry1; + order_wire_points(n); + storeobject(-1, xctx->rx2,xctx->ry1,xctx->rx2,xctx->ry2,WIRE,0,0,NULL); + last = xctx->wires-1; + order_wire_points(last); + /* drawline(WIRELAYER,NOW, wire[last].x1, wire[last].y1, wire[last].x2, wire[last].y2, 0, NULL); */ + } + + /* wire x2,y2 point was moved + * + * rx1,ry1 x2,y2(old) + * o-----------------o + * | + * |(V) + * | (H) selected + * -----------------------------------o + * rx2,ry2(new) + */ + else if(wire[n].sel == SELECTED2 && (xctx->manhattan_lines & 2)) /* V - H */ + { + int last; + wire[n].x1 = xctx->rx1; + wire[n].y1 = xctx->ry2; + wire[n].x2 = xctx->rx2; + wire[n].y2 = xctx->ry2; + order_wire_points(n); + storeobject(-1, xctx->rx1,xctx->ry1,xctx->rx1,xctx->ry2,WIRE,0,0,NULL); + last = xctx->wires-1; + order_wire_points(last); + /* drawline(WIRELAYER,NOW, wire[last].x1, wire[last].y1, wire[last].x2, wire[last].y2, 0, NULL); */ + } + + else /* no manhattan or traslation since both line points moved */ + { + wire[n].x1 = xctx->rx1; + wire[n].y1 = xctx->ry1; + wire[n].x2 = xctx->rx2; + wire[n].y2 = xctx->ry2; + order_wire_points(n); + } +} + /* merge param unused, RFU */ void move_objects(int what, int merge, double dx, double dy) { @@ -998,6 +1153,7 @@ void move_objects(int what, int merge, double dx, double dy) double angle, dtmp; double tx1,ty1; /* temporaries for swapping coordinates 20070302 */ char *estr = NULL; + int orthogonal_wiring = tclgetboolvar("orthogonal_wiring"); #if HAS_CAIRO==1 int customfont; #endif @@ -1127,46 +1283,8 @@ void move_objects(int what, int merge, double dx, double dy) xctx->rx2+=xctx->deltax; xctx->ry2+=xctx->deltay; } - wire[n].x1=xctx->rx1; - wire[n].y1=xctx->ry1; - ORDER(xctx->rx1,xctx->ry1,xctx->rx2,xctx->ry2); - if( wire[n].x1 == xctx->rx2 && wire[n].y1 == xctx->ry2) - { - if(wire[n].sel == SELECTED1) wire[n].sel = SELECTED2; - else if(wire[n].sel == SELECTED2) wire[n].sel = SELECTED1; - } - - if((wire[n].sel & (SELECTED|SELECTED1)) && tclgetboolvar("orthogonal_wiring")) - { - if(xctx->manhattan_lines & 1) xctx->manhattan_lines=2; - else if(xctx->manhattan_lines & 2) xctx->manhattan_lines=1; - } - wire[n].x1 = xctx->rx1; - wire[n].y1 = xctx->ry1; - if(xctx->manhattan_lines&1) - { - wire[n].x2 = xctx->rx2; - wire[n].y2 = xctx->ry1; - ORDER(xctx->rx2,xctx->ry1,xctx->rx2,xctx->ry2); - storeobject(-1, xctx->rx2,xctx->ry1,xctx->rx2,xctx->ry2,WIRE,0,0,NULL); - hash_wire(XINSERT, xctx->wires-1, 1); - drawline(WIRELAYER,ADD, xctx->rx2,xctx->ry1,xctx->rx2,xctx->ry2, 0, NULL); - } - else if(xctx->manhattan_lines&2) - { - wire[n].x2 = xctx->rx1; - wire[n].y2 = xctx->ry2; - ORDER(xctx->rx1,xctx->ry2,xctx->rx2,xctx->ry2); - storeobject(-1, xctx->rx1,xctx->ry2,xctx->rx2,xctx->ry2,WIRE,0,0,NULL); - hash_wire(XINSERT, xctx->wires-1, 1); - drawline(WIRELAYER,ADD, xctx->rx1,xctx->ry2,xctx->rx2,xctx->ry2, 0, NULL); - } - else - { - /* no need for ordering coordinates - already done before */ - wire[n].x2 = xctx->rx2; - wire[n].y2 = xctx->ry2; - } + + place_moved_wire(n, orthogonal_wiring); } break; @@ -1236,9 +1354,7 @@ void move_objects(int what, int merge, double dx, double dy) p->x[j] = xctx->rx1+xctx->deltax; p->y[j] = xctx->ry1+xctx->deltay; } - } - for(j=0; jpoints; ++j) { if(j==0 || p->x[j] < bx1) bx1 = p->x[j]; if(j==0 || p->y[j] < by1) by1 = p->y[j]; From b3484511608349898f4e3cfce9ffcbc73f7f5639 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Tue, 18 Mar 2025 00:53:46 +0100 Subject: [PATCH 3/6] new symbol browser: add Update button to refresh list of dirs and files; fix Alt-s (Reload) incorrectly moved in r keybind after handle_key_press() refactoring --- src/callback.c | 31 +++++++++++++++------------- src/xschem.tcl | 55 ++++++++++++++++++++++++++++---------------------- 2 files changed, 48 insertions(+), 38 deletions(-) diff --git a/src/callback.c b/src/callback.c index 278a5838..ab55319e 100644 --- a/src/callback.c +++ b/src/callback.c @@ -3434,19 +3434,6 @@ static void handle_key_press(int event, KeySym key, int state, int rstate, int m tcleval("[xschem get top_path].menubar invoke Simulate"); } } - else if(SET_MODMASK) { /* reload */ - if(xctx->semaphore >= 2) break; - tcleval("tk_messageBox -type okcancel -parent [xschem get topwindow] " - "-message {Are you sure you want to reload from disk?}"); - if(strcmp(tclresult(),"ok")==0) { - char filename[PATH_MAX]; - unselect_all(1); - remove_symbols(); - my_strncpy(filename, abs_sym_path(xctx->sch[xctx->currsch], ""), S(filename)); - load_schematic(1, filename, 1, 1); - draw(); - } - } else if(EQUAL_MODMASK) { /* rotate objects around their anchor points 20171208 */ if(xctx->ui_state & STARTMOVE) move_objects(ROTATE|ROTATELOCAL,0,0,0); else if(xctx->ui_state & STARTCOPY) copy_objects(ROTATE|ROTATELOCAL); @@ -3490,7 +3477,8 @@ static void handle_key_press(int event, KeySym key, int state, int rstate, int m tcleval("[xschem get top_path].menubar invoke Simulate"); } } - else if(/* !xctx->ui_state && */ (rstate == 0) && cadence_compat) { /* create wire snapping to closest instance pin (cadence keybind) */ + /* create wire snapping to closest instance pin (cadence keybind) */ + else if(/* !xctx->ui_state && */ (rstate == 0) && cadence_compat) { if(xctx->semaphore >= 2) break; snapped_wire(c_snap); } @@ -3507,6 +3495,21 @@ static void handle_key_press(int event, KeySym key, int state, int rstate, int m save(1, 0); } } + + else if(SET_MODMASK) { /* reload */ + if(xctx->semaphore >= 2) break; + tcleval("tk_messageBox -type okcancel -parent [xschem get topwindow] " + "-message {Are you sure you want to reload from disk?}"); + if(strcmp(tclresult(),"ok")==0) { + char filename[PATH_MAX]; + unselect_all(1); + remove_symbols(); + my_strncpy(filename, abs_sym_path(xctx->sch[xctx->currsch], ""), S(filename)); + load_schematic(1, filename, 1, 1); + draw(); + } + } + else if(SET_MODMASK && (state & ControlMask) ) { /* save as symbol */ if(xctx->semaphore >= 2) break; saveas(NULL, SYMBOL); diff --git a/src/xschem.tcl b/src/xschem.tcl index 428493e6..5303e18d 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -4878,9 +4878,34 @@ proc insert_symbol_preview {} { } } +proc insert_symbol_update_dirs {paths {maxdepth -1}} { + global insert_symbol new_symbol_browser_ext + # regenerate list of dirs + set insert_symbol(dirs) [get_list_of_dirs_with_symbols $paths $maxdepth $new_symbol_browser_ext] + set insert_symbol(dirtails) {} + foreach i $insert_symbol(dirs) { + lappend insert_symbol(dirtails) [file tail $i] + } + # sort dirs using dirtails as key + set files {} + foreach f $insert_symbol(dirtails) ff $insert_symbol(dirs) { + lappend files [list $f $ff] + } + set files [lsort -dictionary -index 0 $files] + set insert_symbol(dirtails) {} + set insert_symbol(dirs) {} + + foreach f $files { + lassign $f ff fff + lappend insert_symbol(dirtails) $ff + lappend insert_symbol(dirs) $fff + } +} + #### fill list of files matching pattern proc insert_symbol_filelist {paths {maxdepth -1}} { global insert_symbol new_symbol_browser_ext + set sel [.ins.center.leftdir.l curselection] if {![info exists insert_symbol(dirs)]} {return} if {$sel eq {}} { @@ -5012,7 +5037,10 @@ proc insert_symbol {{paths {}} {maxdepth -1} {ext {.*}}} { -readonlybackground [option get . background {}] -takefocus 0 label .ins.top.ext_l -text Ext: entry .ins.top.ext_e -width 15 -takefocus 0 -state normal -textvariable new_symbol_browser_ext - + button .ins.top.upd -takefocus 0 -text Update -command " + insert_symbol_update_dirs [list $paths] [list $maxdepth] + insert_symbol_filelist [list $paths] [list $maxdepth] + " bind .ins {.ins.bottom.dismiss invoke} bind .ins " if {{%K} eq {Tab} && {%W} eq {.ins.center.left.l}} { @@ -5048,33 +5076,12 @@ proc insert_symbol {{paths {}} {maxdepth -1} {ext {.*}}} { pack .ins.top.pat_e -side left pack .ins.top.dir_l -side left pack .ins.top.dir_e -side left + pack .ins.top.upd -side left pack .ins.top.ext_l -side left pack .ins.top.ext_e -side left - set insert_symbol(dirs) [get_list_of_dirs_with_symbols $paths $maxdepth $new_symbol_browser_ext] - set insert_symbol(dirtails) {} - foreach i $insert_symbol(dirs) { - lappend insert_symbol(dirtails) [file tail $i] - } + insert_symbol_update_dirs $paths $maxdepth - # sort dirs using dirtails as key - set files {} - foreach f $insert_symbol(dirtails) ff $insert_symbol(dirs) { - lappend files [list $f $ff] - } - set files [lsort -dictionary -index 0 $files] - set insert_symbol(dirtails) {} - set insert_symbol(dirs) {} - - foreach f $files { - lassign $f ff fff - lappend insert_symbol(dirtails) $ff - lappend insert_symbol(dirs) $fff - } - - # insert_symbol_filelist $paths $maxdepth - # tkwait window .ins - # xschem set semaphore [expr {[xschem get semaphore] -1}] if {[info exists insert_symbol(dirindex)]} {.ins.center.leftdir.l selection set $insert_symbol(dirindex)} if {[info exists insert_symbol(fileindex)]} {.ins.center.left.l selection set $insert_symbol(fileindex)} return {} From 4584c260bad24063e448a240641e1d9cc7b47a6c Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Tue, 18 Mar 2025 01:58:55 +0100 Subject: [PATCH 4/6] new insert symbol: low-pass filter (200ms) on preview rendering to speed up quick listbox select events (arrow key autorepeat) --- src/xschem.tcl | 52 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/src/xschem.tcl b/src/xschem.tcl index 5303e18d..99dc612d 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -4133,7 +4133,7 @@ namespace eval c_toolbar { set c_t($i,file) $f set c_t($i,command) " set file_dialog_retval {} - xschem abort_operation + if { \[xschem get ui_state\] & 8192 } { xschem abort_operation } file_dialog_display_preview {$f} xschem place_symbol {$f} " set c_t($i,text) [file tail [file rootname $f]] @@ -4357,7 +4357,9 @@ proc file_dialog_place_symbol {} { set file_dialog_retval $entry set sym [file_dialog_getresult 2 0] # puts "sym=$sym" - xschem abort_operation + if { [xschem get ui_state] & 8192 } { + xschem abort_operation + } if {$sym ne {}} { xschem place_symbol "$sym" } @@ -4836,11 +4838,25 @@ proc get_list_of_dirs_with_symbols {{paths {}} {levels -1} {ext {\.(sch|sym)$}} ####################################################################### #### Display preview of selected symbol and start sym placement -proc insert_symbol_preview {} { - # puts "insert_symbol_preview" +proc insert_symbol_draw_preview {f} { + # puts "insert_symbol_draw_preview" + .ins.center.right configure -bg {} + xschem preview_window create .ins.center.right {} + xschem preview_window draw .ins.center.right [list $f] + bind .ins.center.right "xschem preview_window draw .ins.center.right [list $f]" + bind .ins.center.right "xschem preview_window draw .ins.center.right [list $f]" + insert_symbol_place +} + + +proc insert_symbol_select_preview {} { + # puts "insert_symbol_select_preview" global insert_symbol + if {[info exists insert_symbol(f)]} { + after cancel "insert_symbol_draw_preview $insert_symbol(f)" + unset insert_symbol(f) + } xschem preview_window close .ins.center.right {} - .ins.center.right configure -bg white bind .ins.center.right {} bind .ins.center.right {} set sel [.ins.center.left.l curselection] @@ -4866,14 +4882,12 @@ proc insert_symbol_preview {} { .ins.top2.dir_e delete 0 end .ins.top2.dir_e insert 0 $f .ins.top2.dir_e configure -state readonly - - .ins.center.right configure -bg {} - xschem preview_window create .ins.center.right {} - xschem preview_window draw .ins.center.right [list $f] - bind .ins.center.right "xschem preview_window draw .ins.center.right [list $f]" - bind .ins.center.right "xschem preview_window draw .ins.center.right [list $f]" + # global used to cancel delayed script + set insert_symbol(f) $f + after 200 "insert_symbol_draw_preview $f" + } else { + .ins.center.right configure -bg white } - insert_symbol_place } } } @@ -4972,7 +4986,9 @@ proc insert_symbol_place {} { if {$f ne {}} { set type [is_xschem_file $f] if {$type ne {0}} { - xschem abort_operation + if { [xschem get ui_state] & 8192 } { + xschem abort_operation + } xschem place_symbol $f } } @@ -5045,18 +5061,22 @@ proc insert_symbol {{paths {}} {maxdepth -1} {ext {.*}}} { bind .ins " if {{%K} eq {Tab} && {%W} eq {.ins.center.left.l}} { insert_symbol_filelist [list $paths] [list $maxdepth] - insert_symbol_preview + insert_symbol_select_preview } elseif {{%K} eq {Tab} && {%W} eq {.ins.center.leftdir.l}} { insert_symbol_filelist [list $paths] [list $maxdepth] } " bind .ins.center.leftdir.l <> "insert_symbol_filelist [list $paths] [list $maxdepth]" - bind .ins.center.left.l <> "insert_symbol_preview" + bind .ins.center.left.l <> "insert_symbol_select_preview" bind .ins.center.left.l " xschem preview_window close .ins.center.right {} destroy .ins " - bind .ins.center.left.l "xschem abort_operation" + bind .ins.center.left.l " + if { \[xschem get ui_state\] & 8192 } { + xschem abort_operation + } + " label .ins.bottom.n -text { N. of items:} label .ins.bottom.nitems -textvariable insert_symbol(nitems) button .ins.bottom.dismiss -takefocus 0 -text Dismiss -command { From 172a0014256cbf8ca72d28f1dc52bf91863f88b3 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Tue, 18 Mar 2025 03:07:48 +0100 Subject: [PATCH 5/6] insert symbol preview. Fixed some race conditions --- src/actions.c | 4 +++- src/xschem.tcl | 24 +++++++++++++++--------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/actions.c b/src/actions.c index 7860c430..19becdd2 100644 --- a/src/actions.c +++ b/src/actions.c @@ -1599,7 +1599,8 @@ int place_symbol(int pos, const char *symbol_name, double x, double y, short rot } else { const char msg[]="scope_ammeter is being inserted but no selected ammeter device/vsource to link to\n"; dbg(0, "%s", msg); - if(has_x) tclvareval("alert_ {", msg, "} {}", NULL); + if(has_x) tclvareval("alert_ {", msg, "} {} 0", NULL); + #if 1 if(xctx->inst[n].instname) my_free(_ALLOC_ID_, &xctx->inst[n].instname); if(xctx->inst[n].name) my_free(_ALLOC_ID_, &xctx->inst[n].name); if(xctx->inst[n].prop_ptr) my_free(_ALLOC_ID_, &xctx->inst[n].prop_ptr); @@ -1607,6 +1608,7 @@ int place_symbol(int pos, const char *symbol_name, double x, double y, short rot if(prop) my_free(_ALLOC_ID_, &prop); xctx->instances--; return 0; + #endif } } else if(xctx->sym[i].rects[PINLAYER] == 1) { my_mstrcat(_ALLOC_ID_, &prop, diff --git a/src/xschem.tcl b/src/xschem.tcl index 99dc612d..17f6ed8e 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -4840,12 +4840,14 @@ proc get_list_of_dirs_with_symbols {{paths {}} {levels -1} {ext {\.(sch|sym)$}} #### Display preview of selected symbol and start sym placement proc insert_symbol_draw_preview {f} { # puts "insert_symbol_draw_preview" - .ins.center.right configure -bg {} - xschem preview_window create .ins.center.right {} - xschem preview_window draw .ins.center.right [list $f] - bind .ins.center.right "xschem preview_window draw .ins.center.right [list $f]" - bind .ins.center.right "xschem preview_window draw .ins.center.right [list $f]" - insert_symbol_place + if {[winfo exists .ins]} { + .ins.center.right configure -bg {} + xschem preview_window create .ins.center.right {} + xschem preview_window draw .ins.center.right [list $f] + bind .ins.center.right "xschem preview_window draw .ins.center.right [list $f]" + bind .ins.center.right "xschem preview_window draw .ins.center.right [list $f]" + insert_symbol_place + } } @@ -4853,6 +4855,7 @@ proc insert_symbol_select_preview {} { # puts "insert_symbol_select_preview" global insert_symbol if {[info exists insert_symbol(f)]} { + after cancel ".ins.center.right configure -bg white" after cancel "insert_symbol_draw_preview $insert_symbol(f)" unset insert_symbol(f) } @@ -4870,6 +4873,7 @@ proc insert_symbol_select_preview {} { .ins.center.left.l see $sel set f [lindex $insert_symbol(fullpathlist) $sel] if {$f ne {}} { + set insert_symbol(f) $f set type [is_xschem_file $f] if {$type ne {0}} { set dir [rel_sym_path $f] @@ -4883,10 +4887,9 @@ proc insert_symbol_select_preview {} { .ins.top2.dir_e insert 0 $f .ins.top2.dir_e configure -state readonly # global used to cancel delayed script - set insert_symbol(f) $f after 200 "insert_symbol_draw_preview $f" } else { - .ins.center.right configure -bg white + after 200 {.ins.center.right configure -bg white} } } } @@ -5103,7 +5106,10 @@ proc insert_symbol {{paths {}} {maxdepth -1} {ext {.*}}} { insert_symbol_update_dirs $paths $maxdepth if {[info exists insert_symbol(dirindex)]} {.ins.center.leftdir.l selection set $insert_symbol(dirindex)} - if {[info exists insert_symbol(fileindex)]} {.ins.center.left.l selection set $insert_symbol(fileindex)} + if {[info exists insert_symbol(fileindex)]} { + .ins.center.left.l selection set $insert_symbol(fileindex) + .ins.center.left.l see $insert_symbol(fileindex) + } return {} } ####################################################################### From 0f9d201f0aa5a4d9584aa0d8ca1b4718ed07da73 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Tue, 18 Mar 2025 03:31:37 +0100 Subject: [PATCH 6/6] (2) insert symbol preview. Fixed some race conditions --- src/actions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/actions.c b/src/actions.c index 19becdd2..9d5b67d9 100644 --- a/src/actions.c +++ b/src/actions.c @@ -1599,7 +1599,7 @@ int place_symbol(int pos, const char *symbol_name, double x, double y, short rot } else { const char msg[]="scope_ammeter is being inserted but no selected ammeter device/vsource to link to\n"; dbg(0, "%s", msg); - if(has_x) tclvareval("alert_ {", msg, "} {} 0", NULL); + if(has_x) tclvareval("alert_ {", msg, "} {} 1", NULL); #if 1 if(xctx->inst[n].instname) my_free(_ALLOC_ID_, &xctx->inst[n].instname); if(xctx->inst[n].name) my_free(_ALLOC_ID_, &xctx->inst[n].name);