Merge pull request #14 from TheSUPERCD/upstream-clone

Integrate upstream changes
This commit is contained in:
Chayan Deb 2025-03-11 05:54:54 +00:00 committed by GitHub
commit 244fc59672
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
29 changed files with 1363 additions and 670 deletions

View File

@ -229,6 +229,7 @@ ctrl+alt 's' Save-as symbol
- 't' Place text
shift 'T' Toggle *_ignore flag on selected instances
alt 'u' Align to current grid selected objects
ctrl 'u' Unselect attached floater objects
shift 'U' Redo
- 'u' Undo
- 'v' Constrained vertical move/copy of objects

View File

@ -138,6 +138,11 @@ name="mchanged_name" model=\"nmos\" w="20u" l="3u" m="10"
<li><kbd>text_layer_&lt;n&gt;</kbd></li>
<p> This attribute sets the layer of symbol text item number <kbd>n</kbd>. This allows
instance based symbol text color customization.</p>
<li><kbd>attach</kbd></li>
<p> An attribute <kbd>attach="x1 g3 p4"</kbd> will "attach" specified objects that have a matching <kbd>name=...</kbd>
attribute. These objects can be any xschem objects, like other elements, wires, rectangles, polygons, texts etc.<br>
Attached objects will be selected when selecting the component with this attribute set.
This allows to create "object groups"</p>
<li><kbd>highlight</kbd></li>
<p>If set to <kbd>true</kbd> the symbol will be highlighted when one of the nets attached to its pins are highlighted.</p>
<li><kbd>net_name</kbd></li>

View File

@ -551,7 +551,6 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
<li><kbd> abort_operation</kbd></li><pre>
@ -828,6 +827,15 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
return result of get_cell function </pre>
<li><kbd> get_cell_w_ext cell n_dirs</kbd></li><pre>
return result of get_cell_w_ext function </pre>
<li><kbd> get_fqdevice instname param modelparam</kbd></li><pre>
get the full pathname of "instname" device
modelparam:
0: current, 1: modelparam, 2: modelvoltage
param: device parameter, like ib, gm, vth
set param to {} (empty str) for just branch current of 2 terminal device
for parameters like "vth" modelparam must be 2
for parameters like "ib" modelparam must be 0
for parameters like "gm" modelparam must be 1</pre>
<li><kbd> getprop instance|instance_pin|symbol|text ref</kbd></li><pre>
getprop instance inst
@ -1192,8 +1200,9 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
<li><kbd> push_undo</kbd></li><pre>
Push current state on undo stack </pre>
<li><kbd> raw what ...</kbd></li><pre>
what = add | clear | datasets | index | info | loaded | list | new | points | rawfile | del |
read | set | sim_type | switch | switch_back | table_read | value | values | pos_at | vars |
what = add | clear | datasets | index | info | loaded | list |
new | points | rawfile | del | read | set | rename |
sim_type | switch | switch_back | table_read | value | values | pos_at | vars |
xschem raw read filename [type [sweep1 sweep2]]
if sweep1, sweep2 interval is given in 'read' subcommand load only the interval
@ -1208,6 +1217,9 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
xschem raw del name
delete named vector from current raw file
xschem raw rename old_name new_name
rename a node in the loaded raw file.
xschem raw info
print information about loaded raw files and show the currently active one.
@ -1284,7 +1296,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
new dataset do not start with a header row.
Lines beginning with '#' are comments and ignored
time var_a var_b var_c
time var_a var_b var_cnode in the loaded raw file.
# this is a comment, ignored
0.0 0.0 1.8 0.3
&lt;single empty line: ignored&gt;
@ -1634,6 +1646,9 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
Unhighlight selected nets/pins </pre>
<li><kbd> unselect_all [draw]</kbd></li><pre>
Unselect everything. If draw is given and set to '0' no drawing is done </pre>
<li><kbd> unselect_attached_floaters</kbd></li><pre>
Unselect objects (not symbol instances) attached to some instance with a
non empty name=... attribute </pre>
<li><kbd> update_all_sym_bboxes</kbd></li><pre>
Update all symbol bounding boxes </pre>
<li><kbd> update_op</kbd></li><pre>
@ -1732,6 +1747,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
</ul>

View File

@ -551,6 +551,19 @@ verilog_format="xnor #(@risedel , @falldel ) @name ( @@Z , @@A , @@B );"
</ul>
<h3>PREDEFINED SYMBOL VALUES</h3>
<ul>
<li><kbd>@name</kbd></li>
<p> This expands to the instance name of the symbol (like C1, R2, X3, ...)
It is replaced with the value of the <kbd>name=...</kbd> attribute given when placing an instance of the symbol
in a schematic.</p>
<li><kbd>#pattern#@name</kbd></li>
<p> This is a variation of the above where <kbd>pattern</kbd> is prefixed to all substituted <kbd>@name</kbd>
patterns. The difference with <kbd>pattern@name</kbd> is that in case of vector instances (this means
a placement of an instance with <kbd>name=R2[3:0]</kbd>, for example) the <kbd>pattern</kbd> string
is added to all single instances when expanding the name. see below examples.<br>
<kbd>pattern@name</kbd> where <kbd>name=R2[2:0]</kbd> is given in the instance placement,
expands to <kbd>patternR2[2],R2[1],R2[0]</kbd><br>
<kbd>#pattern#@name</kbd> where <kbd>name=R2[2:0]</kbd> is given in the instance placement,
expands to <kbd>patternR2[2],patternR2[1],patternR2[0]</kbd><br>
<li><kbd>@symname</kbd></li>
<p> This expands to the name of the symbol</p>
<li><kbd>@symref</kbd></li>

View File

@ -1066,7 +1066,7 @@ void clear_partial_selected_wires(void)
rebuild_selected_array();
for(j=0; j < xctx->lastsel; ++j) if(xctx->sel_array[j].type == WIRE) {
int wire = xctx->sel_array[j].n;
select_wire(wire, 0, 1);
select_wire(wire, 0, 1, 1);
}
xctx->need_reb_sel_arr = 1;
rebuild_selected_array();
@ -1229,7 +1229,7 @@ int unselect_partial_sel_wires(void)
while(wptr) {
xWire *w = &xctx->wire[wptr->n];
if(touch(w->x1, w->y1, w->x2, w->y2, pinx0, piny0) && w->sel && w->sel != SELECTED) {
select_wire(wptr->n, 0, 1);
select_wire(wptr->n, 0, 1, 1);
changed = 1;
}
wptr = wptr->next;
@ -1258,7 +1258,7 @@ int unselect_partial_sel_wires(void)
}
if(touch(w->x1, w->y1, w->x2, w->y2, x0, y0) && w->sel && w->sel != SELECTED) {
xctx->wire[wptr->n].sel = 0;
select_wire(wptr->n, 0, 1);
select_wire(wptr->n, 0, 1, 1);
changed = 1;
}
wptr = wptr->next;
@ -1450,7 +1450,6 @@ void delete_files(void)
void place_net_label(int type)
{
unselect_all(1);
if(type == 1) {
const char *lab = tcleval("rel_sym_path [find_file_first lab_pin.sym]");
place_symbol(-1, lab, xctx->mousex_snap, xctx->mousey_snap, 0, 0, NULL, 4, 1, 1/*to_push_undo*/);
@ -1478,13 +1477,14 @@ int place_symbol(int pos, const char *symbol_name, double x, double y, short rot
char name[PATH_MAX];
char name1[PATH_MAX];
char tclev = 0;
if(symbol_name==NULL) {
tcleval("load_file_dialog {Choose symbol} *.\\{sym,tcl\\} INITIALINSTDIR");
my_strncpy(name1, tclresult(), S(name1));
} else {
my_strncpy(name1, trim_chars(symbol_name, " \t\n"), S(name1));
}
if(!name1[0]) return 0;
dbg(1, "place_symbol(): 1: name1=%s first_call=%d\n",name1, first_call);
/* remove tcleval( given in file selector, if any ... */
if(strstr(name1, "tcleval(")) {
@ -1562,7 +1562,11 @@ int place_symbol(int pos, const char *symbol_name, double x, double y, short rot
/* After having assigned prop_ptr to new instance translate symbol reference
* to resolve @params --> res.tcl(@value\) --> res.tcl(100) */
my_strncpy(name, translate(n, name), S(name));
i = match_symbol(name);
/* parameters like res.tcl(@value\) have been resolved, so reload symbol removing previous */
if(strcmp(name, name1)) {
remove_symbol(i);
i = match_symbol(name);
}
xctx->inst[n].ptr = i;
set_inst_flags(&xctx->inst[n]);
hash_names(n, XINSERT);
@ -1576,6 +1580,50 @@ int place_symbol(int pos, const char *symbol_name, double x, double y, short rot
if(xctx->prep_hash_inst) hash_inst(XINSERT, n); /* no need to rehash, add item */
/* xctx->prep_hash_inst=0; */
/* embed a (locked) graph object floater inside the symbol */
if(xctx->sym[i].type && !strcmp(xctx->sym[i].type, "scope")) {
char *prop = NULL;
my_strdup(_ALLOC_ID_, &xctx->inst[n].prop_ptr,
subst_token(xctx->inst[n].prop_ptr, "attach", xctx->inst[n].instname));
my_mstrcat(_ALLOC_ID_, &prop, "name=", xctx->inst[n].instname, "\n", NULL);
my_mstrcat(_ALLOC_ID_, &prop, "flags=graph,unlocked\n", NULL);
my_mstrcat(_ALLOC_ID_, &prop, "lock=1\n", NULL);
my_mstrcat(_ALLOC_ID_, &prop, "color=8\n", NULL);
if(xctx->sym[i].rects[PINLAYER] == 0) {
if(xctx->lastsel == 1 && xctx->sel_array[0].type==ELEMENT) {
my_mstrcat(_ALLOC_ID_, &prop, "node=\"tcleval([xschem get_fqdevice [xschem translate ",
xctx->inst[n].instname, " @device]])\"\n", NULL);
my_strdup(_ALLOC_ID_, &xctx->inst[n].prop_ptr,
subst_token(xctx->inst[n].prop_ptr, "device", xctx->inst[xctx->sel_array[0].n].instname));
} 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(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);
if(xctx->inst[n].lab) my_free(_ALLOC_ID_, &xctx->inst[n].lab);
if(prop) my_free(_ALLOC_ID_, &prop);
xctx->instances--;
return 0;
}
} else if(xctx->sym[i].rects[PINLAYER] == 1) {
my_mstrcat(_ALLOC_ID_, &prop,
"node=\"tcleval(",
"[xschem translate ", xctx->inst[n].instname, " @#0:net_name]",
")\"\n", NULL);
} else {
my_mstrcat(_ALLOC_ID_, &prop,
"node=\"tcleval(",
"[xschem translate ", xctx->inst[n].instname, " @#0:net_name] ",
"[xschem translate ", xctx->inst[n].instname, " @#1:net_name] -",
")\"\n", NULL);
}
storeobject(-1, x + 20, y-125, x + 130 , y - 25, xRECT, 2, SELECTED, prop);
my_free(_ALLOC_ID_, &prop);
}
if(draw_sym & 3) {
bbox(ADD, xctx->inst[n].x1, xctx->inst[n].y1, xctx->inst[n].x2, xctx->inst[n].y2);
}
@ -1587,6 +1635,7 @@ int place_symbol(int pos, const char *symbol_name, double x, double y, short rot
/* hilight new element 24122002 */
if(draw_sym & 4 ) {
unselect_all(1);
select_element(n, SELECTED,0, 1);
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);
@ -2214,7 +2263,7 @@ int change_sch_path(int instnumber, int dr)
char *ptr;
size_t pathlen;
int res = 0;
if(level <= 0 ) return 0;
if(level < 0 ) return 0;
my_strdup2(_ALLOC_ID_, &instname, get_tok_value(xctx->hier_attr[level].prop_ptr, "name", 0));
my_strdup2(_ALLOC_ID_, &expanded_instname, expandlabel(instname, &inst_mult));
my_strdup2(_ALLOC_ID_, &path, xctx->sch_path[xctx->currsch]);
@ -2261,6 +2310,7 @@ int descend_schematic(int instnumber, int fallback, int alert, int set_title)
int inst_mult, inst_number;
int save_ok = 0;
int i, n = 0;
int descend_ok = 1;
if(xctx->currsch + 1 >= CADMAXHIER) {
dbg(0, "descend_schematic(): max hierarchy depth reached: %d", CADMAXHIER);
@ -2416,24 +2466,25 @@ int descend_schematic(int instnumber, int fallback, int alert, int set_title)
dbg(1, "descend_schematic(): filename=%s\n", filename);
/* we are descending from a parent schematic downloaded from the web */
if(!tclgetboolvar("keep_symbols")) remove_symbols();
load_schematic(1, filename, (set_title & 1), alert);
if(xctx->hilight_nets) {
prepare_netlist_structs(0);
propagate_hilights(1, 0, XINSERT_NOREPLACE);
}
dbg(1, "descend_schematic(): before zoom(): prep_hash_inst=%d\n", xctx->prep_hash_inst);
if(xctx->rects[GRIDLAYER] > 0 && tcleval("info exists ngspice::ngspice_data")[0] == '0') {
Graph_ctx *gr = &xctx->graph_struct;
xRect *r = &xctx->rect[GRIDLAYER][0];
if(r->flags & 1) {
backannotate_at_cursor_b_pos(r, gr);
descend_ok = load_schematic(1, filename, (set_title & 1), alert);
if(descend_ok) {
if(xctx->hilight_nets) {
prepare_netlist_structs(0);
propagate_hilights(1, 0, XINSERT_NOREPLACE);
}
dbg(1, "descend_schematic(): before zoom(): prep_hash_inst=%d\n", xctx->prep_hash_inst);
if(xctx->rects[GRIDLAYER] > 0 && tcleval("info exists ngspice::ngspice_data")[0] == '0') {
Graph_ctx *gr = &xctx->graph_struct;
xRect *r = &xctx->rect[GRIDLAYER][0];
if(r->flags & 1) {
backannotate_at_cursor_b_pos(r, gr);
}
}
}
zoom_full(1, 0, 1 + 2 * tclgetboolvar("zoom_full_center"), 0.97);
}
return 1;
return descend_ok;
}
/*
@ -2449,7 +2500,7 @@ void go_back(int what)
char filename[PATH_MAX];
int prev_sch_type;
int confirm = what & 1;
int set_title = !(confirm & 2);
int set_title = !(what & 2);
save_ok=1;
dbg(1,"go_back(): sch[xctx->currsch]=%s\n", xctx->sch[xctx->currsch]);
@ -3830,7 +3881,7 @@ int place_text(int draw_text, double mx, double my)
dbg(1,"props=%s, txt=%s\n", props, txt);
create_text(draw_text, mx, my, 0, 0, txt, props, atof(hsize), atof(vsize));
select_text(xctx->texts - 1, SELECTED, 0);
select_text(xctx->texts - 1, SELECTED, 0, 1);
rebuild_selected_array(); /* sets xctx->ui_state |= SELECTION */
drawtemprect(xctx->gc[SELLAYER], END, 0.0, 0.0, 0.0, 0.0);
drawtempline(xctx->gc[SELLAYER], END, 0.0, 0.0, 0.0, 0.0);

View File

@ -50,16 +50,21 @@ static int waves_selected(int event, KeySym key, int state, int button)
else if(event == ButtonRelease && button == Button2) skip = 1;
/* else if(event == KeyPress && (state & ShiftMask)) skip = 1; */
else if(!skip) for(i=0; i< xctx->rects[GRIDLAYER]; ++i) {
double lmargin;
xRect *r;
r = &xctx->rect[GRIDLAYER][i];
lmargin = (r->x2 - r->x1) / 20.;
lmargin = lmargin < 3. ? 3. : lmargin;
lmargin = lmargin > 20. ? 20. : lmargin;
if(!(r->flags & 1) ) continue;
if(!strboolcmp(get_tok_value(xctx->rect[GRIDLAYER][i].prop_ptr, "lock", 0), "true")) continue;
if( !graph_use_ctrl_key && !(state & ControlMask) &&
!strboolcmp(get_tok_value(xctx->rect[GRIDLAYER][i].prop_ptr, "lock", 0), "true")) continue;
check =
(xctx->ui_state & GRAPHPAN) ||
(event != -3 &&
(
POINTINSIDE(xctx->mousex, xctx->mousey, r->x1 + 20, r->y1 + 8, r->x2 - 20, r->y2 - 8) ||
POINTINSIDE(xctx->mousex, xctx->mousey, r->x1 + lmargin, r->y1 + 8, r->x2 - 20, r->y2 - 8) ||
POINTINSIDE(xctx->mousex, xctx->mousey, r->x1, r->y1, r->x1 + 20, r->y1 + 8) ||
POINTINSIDE(xctx->mousex, xctx->mousey, r->x2 - 20, r->y2 - 8, r->x2, r->y2)
)
@ -198,7 +203,6 @@ static void start_place_symbol(void)
tclvareval("set INITIALINSTDIR [file dirname {",
abs_sym_path(tcl_hook2(xctx->inst[xctx->sel_array[0].n].name), ""), "}]", NULL);
}
unselect_all(1);
xctx->mx_double_save = xctx->mousex_snap;
xctx->my_double_save = xctx->mousey_snap;
if(place_symbol(-1,NULL,xctx->mousex_snap, xctx->mousey_snap, 0, 0, NULL, 4, 1, 1/* to_push_undo */) ) {
@ -427,7 +431,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
int access_cond = !graph_use_ctrl_key || (state & ControlMask);
dbg(1, "uistate=%d, graph_flags=%d\n", xctx->ui_state, xctx->graph_flags);
if(event != -3 && !xctx->raw) return 0;
/* if(event != -3 && !xctx->raw) return 0; */
rstate = state; /* rstate does not have ShiftMask bit, so easier to test for KeyPress events */
rstate &= ~ShiftMask; /* don't use ShiftMask, identifying characters is sufficient */
#if HAS_CAIRO==1
@ -921,7 +925,9 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
if(gr->dataset >= 0 /* && gr->dataset < xctx->raw->datasets */) dataset =gr->dataset;
else dataset = -1;
if(!strcmp(curr_sim_type,
/* if master graph has unlocked X axis do not zoom/pan any other graphs: same_sim_type = 0 */
if(!(xctx->rect[GRIDLAYER][xctx->graph_master].flags & 2) &&
!strcmp(curr_sim_type,
get_tok_value(xctx->rect[GRIDLAYER][xctx->graph_master].prop_ptr, "sim_type", 0))) {
same_sim_type = 1;
}
@ -1379,245 +1385,6 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
return 0;
}
/* what == 3 (+4) : delete and draw (force)
* what == 1 (+4) : delete (force)
* what == 2 (+4) : draw (force)
* what == 4 : force (re)clear and/or (re)draw even if on same point */
void draw_crosshair(int what, int state)
{
int sdw, sdp;
int xhair_size = tclgetintvar("crosshair_size");
double mx, my;
int changed = 0;
dbg(1, "draw_crosshair(): what=%d\n", what);
sdw = xctx->draw_window;
sdp = xctx->draw_pixmap;
if(!xctx->mouse_inside) return;
mx = xctx->mousex_snap;
my = xctx->mousey_snap;
if( ( (xctx->ui_state & (MENUSTART | STARTWIRE) ) || xctx->ui_state == 0 ) &&
(state == ShiftMask) ) {
/* mouse not changed so closest net or symbol pin unchanged too */
if(mx == xctx->prev_m_crossx && my == xctx->prev_m_crossy) {
mx = xctx->prev_crossx; /* get previous one */
my = xctx->prev_crossy;
} else {
/* mouse position changed, so find new closest net or pin */
find_closest_net_or_symbol_pin(xctx->mousex_snap, xctx->mousey_snap, &mx, &my);
changed = 1; /* we force a cursor redraw */
dbg(1, "find\n");
}
}
/* no changed closest pin/net, no force, mx,my is not changed. --> do nothing
| _____________| |
| | _____________________|____________________________ */
if(!changed && !(what & 4) && mx == xctx->prev_crossx && my == xctx->prev_crossy) {
return;
}
dbg(1, "draw %d\n", what);
xctx->draw_pixmap = 0;
xctx->draw_window = 1;
if(what & 1) { /* delete previous */
if(fix_broken_tiled_fill || !_unix) {
if(xhair_size) {
MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0],
(int)X_TO_SCREEN(xctx->prev_crossx) - 1 * INT_WIDTH(xctx->lw) - xhair_size,
(int)Y_TO_SCREEN(xctx->prev_crossy) - 1 * INT_WIDTH(xctx->lw) - xhair_size,
2 * INT_WIDTH(xctx->lw) + 2 * xhair_size,
2 * INT_WIDTH(xctx->lw) + 2 * xhair_size,
(int)X_TO_SCREEN(xctx->prev_crossx) - 1 * INT_WIDTH(xctx->lw) - xhair_size,
(int)Y_TO_SCREEN(xctx->prev_crossy) - 1 * INT_WIDTH(xctx->lw) - xhair_size);
MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0],
(int)X_TO_SCREEN(xctx->prev_crossx) - 1 * INT_WIDTH(xctx->lw) - xhair_size,
(int)Y_TO_SCREEN(xctx->prev_crossy) - 1 * INT_WIDTH(xctx->lw) - xhair_size,
2 * INT_WIDTH(xctx->lw) + 2 * xhair_size,
2 * INT_WIDTH(xctx->lw) + 2 * xhair_size,
(int)X_TO_SCREEN(xctx->prev_crossx) - 1 * INT_WIDTH(xctx->lw) - xhair_size,
(int)Y_TO_SCREEN(xctx->prev_crossy) - 1 * INT_WIDTH(xctx->lw) - xhair_size);
} else { /* full screen span xhair */
MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0],
0, (int)Y_TO_SCREEN(xctx->prev_crossy) - 1 * INT_WIDTH(xctx->lw),
xctx->xrect[0].width, 2 * INT_WIDTH(xctx->lw),
0, (int)Y_TO_SCREEN(xctx->prev_crossy) - 1 * INT_WIDTH(xctx->lw));
MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0],
(int)X_TO_SCREEN(xctx->prev_crossx) - 1 * INT_WIDTH(xctx->lw), 0,
2 * INT_WIDTH(xctx->lw), xctx->xrect[0].height,
(int)X_TO_SCREEN(xctx->prev_crossx) - 1 * INT_WIDTH(xctx->lw), 0);
}
} else {
if(xhair_size) {
draw_xhair_line(xctx->gctiled, xhair_size,
X_TO_SCREEN(xctx->prev_crossx) - xhair_size,
Y_TO_SCREEN(xctx->prev_crossy) - xhair_size,
X_TO_SCREEN(xctx->prev_crossx) + xhair_size,
Y_TO_SCREEN(xctx->prev_crossy) - xhair_size);
draw_xhair_line(xctx->gctiled, xhair_size,
X_TO_SCREEN(xctx->prev_crossx) - xhair_size,
Y_TO_SCREEN(xctx->prev_crossy) + xhair_size,
X_TO_SCREEN(xctx->prev_crossx) + xhair_size,
Y_TO_SCREEN(xctx->prev_crossy) + xhair_size);
draw_xhair_line(xctx->gctiled, xhair_size,
X_TO_SCREEN(xctx->prev_crossx) - xhair_size,
Y_TO_SCREEN(xctx->prev_crossy) - xhair_size,
X_TO_SCREEN(xctx->prev_crossx) - xhair_size,
Y_TO_SCREEN(xctx->prev_crossy) + xhair_size);
draw_xhair_line(xctx->gctiled, xhair_size,
X_TO_SCREEN(xctx->prev_crossx) + xhair_size,
Y_TO_SCREEN(xctx->prev_crossy) - xhair_size,
X_TO_SCREEN(xctx->prev_crossx) + xhair_size,
Y_TO_SCREEN(xctx->prev_crossy) + xhair_size);
} else { /* full screen span xhair */
drawtempline(xctx->gctiled, NOW, X_TO_XSCHEM(xctx->areax1),
xctx->prev_crossy, X_TO_XSCHEM(xctx->areax2), xctx->prev_crossy);
drawtempline(xctx->gctiled, NOW, xctx->prev_crossx, Y_TO_XSCHEM(xctx->areay1),
xctx->prev_crossx, Y_TO_XSCHEM(xctx->areay2));
}
}
}
if(what & 2) { /* draw new */
if(xhair_size) {
draw_xhair_line(xctx->gc[xctx->crosshair_layer], xhair_size,
X_TO_SCREEN(mx) - xhair_size,
Y_TO_SCREEN(my) - xhair_size,
X_TO_SCREEN(mx) + xhair_size,
Y_TO_SCREEN(my) - xhair_size);
draw_xhair_line(xctx->gc[xctx->crosshair_layer], xhair_size,
X_TO_SCREEN(mx) - xhair_size,
Y_TO_SCREEN(my) + xhair_size,
X_TO_SCREEN(mx) + xhair_size,
Y_TO_SCREEN(my) + xhair_size);
draw_xhair_line(xctx->gc[xctx->crosshair_layer], xhair_size,
X_TO_SCREEN(mx) - xhair_size,
Y_TO_SCREEN(my) - xhair_size,
X_TO_SCREEN(mx) - xhair_size,
Y_TO_SCREEN(my) + xhair_size);
draw_xhair_line(xctx->gc[xctx->crosshair_layer], xhair_size,
X_TO_SCREEN(mx) + xhair_size,
Y_TO_SCREEN(my) - xhair_size,
X_TO_SCREEN(mx) + xhair_size,
Y_TO_SCREEN(my) + xhair_size);
} else { /* full screen span xhair */
draw_xhair_line(xctx->gc[xctx->crosshair_layer], xhair_size,
xctx->areax1, Y_TO_SCREEN(my),
xctx->areax2, Y_TO_SCREEN(my));
draw_xhair_line(xctx->gc[xctx->crosshair_layer], xhair_size,
X_TO_SCREEN(mx), xctx->areay1,
X_TO_SCREEN(mx), xctx->areay2);
}
}
if(what) draw_selection(xctx->gc[SELLAYER], 0);
if(what & 2) {
/* previous closest pin or net position (if snap wire or Shift pressed) */
xctx->prev_crossx = mx;
xctx->prev_crossy = my;
/* previous mouse_snap position */
xctx->prev_m_crossx = xctx->mousex_snap;
xctx->prev_m_crossy = xctx->mousey_snap;
}
xctx->draw_window = sdw;
xctx->draw_pixmap = sdp;
}
/* what == 3 : erase and draw a new cursor
* what == 1 : erase the cursor
* what == 2 : draw a diamond-shaped cursor that snaps to a component endpoint */
void draw_snap_cursor(int what)
{
int sdw, sdp;
int snapcursor_size = tclgetintvar("snap_cursor_size");
int pos_changed = (xctx->mousex_snap - xctx->prev_gridx) || (xctx->mousey_snap - xctx->prev_gridy);
double prev_x = xctx->prev_snapx;
double prev_y = xctx->prev_snapy;
dbg(1, "draw_snap_cursor(): what=%d\n", what);
sdw = xctx->draw_window;
sdp = xctx->draw_pixmap;
if(!xctx->mouse_inside) return;
xctx->draw_pixmap = 0;
xctx->draw_window = 1;
if(what & 1) {
if(fix_broken_tiled_fill || !_unix) {
MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0],
(int)X_TO_SCREEN(prev_x) - 1 * INT_WIDTH(xctx->lw) - snapcursor_size,
(int)Y_TO_SCREEN(prev_y) - 1 * INT_WIDTH(xctx->lw) - snapcursor_size,
2 * INT_WIDTH(xctx->lw) + 2 * snapcursor_size,
2 * INT_WIDTH(xctx->lw) + 2 * snapcursor_size,
(int)X_TO_SCREEN(prev_x) - 1 * INT_WIDTH(xctx->lw) - snapcursor_size,
(int)Y_TO_SCREEN(prev_y) - 1 * INT_WIDTH(xctx->lw) - snapcursor_size);
MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0],
(int)X_TO_SCREEN(prev_x) - 1 * INT_WIDTH(xctx->lw) - snapcursor_size,
(int)Y_TO_SCREEN(prev_y) - 1 * INT_WIDTH(xctx->lw) - snapcursor_size,
2 * INT_WIDTH(xctx->lw) + 2 * snapcursor_size,
2 * INT_WIDTH(xctx->lw) + 2 * snapcursor_size,
(int)X_TO_SCREEN(prev_x) - 1 * INT_WIDTH(xctx->lw) - snapcursor_size,
(int)Y_TO_SCREEN(prev_y) - 1 * INT_WIDTH(xctx->lw) - snapcursor_size);
} else {
draw_xhair_line(xctx->gctiled, snapcursor_size,
X_TO_SCREEN(prev_x),
Y_TO_SCREEN(prev_y) - snapcursor_size,
X_TO_SCREEN(prev_x) + snapcursor_size,
Y_TO_SCREEN(prev_y));
draw_xhair_line(xctx->gctiled, snapcursor_size,
X_TO_SCREEN(prev_x) + snapcursor_size,
Y_TO_SCREEN(prev_y),
X_TO_SCREEN(prev_x),
Y_TO_SCREEN(prev_y) + snapcursor_size);
draw_xhair_line(xctx->gctiled, snapcursor_size,
X_TO_SCREEN(prev_x),
Y_TO_SCREEN(prev_y) + snapcursor_size,
X_TO_SCREEN(prev_x) - snapcursor_size,
Y_TO_SCREEN(prev_y));
draw_xhair_line(xctx->gctiled, snapcursor_size,
X_TO_SCREEN(prev_x) - snapcursor_size,
Y_TO_SCREEN(prev_y),
X_TO_SCREEN(prev_x),
Y_TO_SCREEN(prev_y) - snapcursor_size);
}
}
if(what & 1) {
double x, y;
if(!pos_changed) {
x = xctx->prev_snapx;
y = xctx->prev_snapy;
} else { /* Only search for nearest pin if the grid-snap-point has changed */
xctx->closest_pin_found = find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y);
}
draw_xhair_line(xctx->gc[xctx->crosshair_layer], snapcursor_size,
X_TO_SCREEN(x),
Y_TO_SCREEN(y) - snapcursor_size,
X_TO_SCREEN(x) + snapcursor_size,
Y_TO_SCREEN(y));
draw_xhair_line(xctx->gc[xctx->crosshair_layer], snapcursor_size,
X_TO_SCREEN(x) + snapcursor_size,
Y_TO_SCREEN(y),
X_TO_SCREEN(x),
Y_TO_SCREEN(y) + snapcursor_size);
draw_xhair_line(xctx->gc[xctx->crosshair_layer], snapcursor_size,
X_TO_SCREEN(x),
Y_TO_SCREEN(y) + snapcursor_size,
X_TO_SCREEN(x) - snapcursor_size,
Y_TO_SCREEN(y));
draw_xhair_line(xctx->gc[xctx->crosshair_layer], snapcursor_size,
X_TO_SCREEN(x) - snapcursor_size,
Y_TO_SCREEN(y),
X_TO_SCREEN(x),
Y_TO_SCREEN(y) - snapcursor_size);
xctx->prev_gridx = xctx->mousex_snap;
xctx->prev_gridy = xctx->mousey_snap;
xctx->prev_snapx = x;
xctx->prev_snapy = y;
}
draw_selection(xctx->gc[SELLAYER], 0);
xctx->draw_window = sdw;
xctx->draw_pixmap = sdp;
}
/* complete the STARTWIRE, STARTRECT, STARTZOOM, STARTCOPY ... operations */
static int end_place_move_copy_zoom()
{
@ -1699,6 +1466,195 @@ static int end_place_move_copy_zoom()
return 0;
}
static void draw_snap_cursor_shape(GC gc, double x, double y, int snapcursor_size) {
/* Convert coordinates to screen space */
double screen_x = X_TO_SCREEN(x);
double screen_y = Y_TO_SCREEN(y);
double left = screen_x - snapcursor_size;
double right = screen_x + snapcursor_size;
double top = screen_y - snapcursor_size;
double bottom = screen_y + snapcursor_size;
int i;
/* Define crosshair lines */
double lines[4][4];
lines[0][0] = screen_x; lines[0][1] = top; lines[0][2] = right; lines[0][3] = screen_y;
lines[1][0] = right; lines[1][1] = screen_y; lines[1][2] = screen_x; lines[1][3] = bottom;
lines[2][0] = screen_x; lines[2][1] = bottom; lines[2][2] = left; lines[2][3] = screen_y;
lines[3][0] = left; lines[3][1] = screen_y; lines[3][2] = screen_x; lines[3][3] = top;
/* Draw crosshair lines */
for (i = 0; i < 4; i++) {
draw_xhair_line(gc, snapcursor_size, lines[i][0], lines[i][1], lines[i][2], lines[i][3]);
}
}
static void erase_snap_cursor(double prev_x, double prev_y, int snapcursor_size) {
if (fix_broken_tiled_fill || !_unix) {
MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0],
(int)X_TO_SCREEN(prev_x) - INT_WIDTH(xctx->lw) - snapcursor_size,
(int)Y_TO_SCREEN(prev_y) - INT_WIDTH(xctx->lw) - snapcursor_size,
2 * INT_WIDTH(xctx->lw) + 2 * snapcursor_size,
2 * INT_WIDTH(xctx->lw) + 2 * snapcursor_size,
(int)X_TO_SCREEN(prev_x) - INT_WIDTH(xctx->lw) - snapcursor_size,
(int)Y_TO_SCREEN(prev_y) - INT_WIDTH(xctx->lw) - snapcursor_size);
} else {
draw_snap_cursor_shape(xctx->gctiled, prev_x, prev_y, snapcursor_size);
}
}
static void find_snap_position(double *x, double *y, int pos_changed) {
if (!pos_changed) {
*x = xctx->prev_snapx;
*y = xctx->prev_snapy;
} else {
xctx->closest_pin_found = find_closest_net_or_symbol_pin(
xctx->mousex, xctx->mousey, x, y);
}
}
/* action == 3 : delete and draw
* action == 1 : delete
* action == 2 : draw
* action == 5 : delete even if pos not changed
*/
static void draw_snap_cursor(int action) {
int snapcursor_size;
int pos_changed;
int prev_draw_window = xctx->draw_window;
int prev_draw_pixmap = xctx->draw_pixmap;
if (!xctx->mouse_inside) return; /* Early exit if mouse is outside */
snapcursor_size = tclgetintvar("snap_cursor_size");
pos_changed = (xctx->mousex_snap != xctx->prev_gridx) || (xctx->mousey_snap != xctx->prev_gridy);
/* Save current drawing context */
xctx->draw_pixmap = 0;
xctx->draw_window = 1;
if(pos_changed || action == 5) {
/* Erase the cursor */
if (action & 1) {
erase_snap_cursor(xctx->prev_snapx, xctx->prev_snapy, snapcursor_size);
draw_selection(xctx->gc[SELLAYER], 0);
}
/* Redraw the cursor */
if (action & 2) {
double new_x, new_y;
find_snap_position(&new_x, &new_y, pos_changed);
draw_snap_cursor_shape(xctx->gc[xctx->crosshair_layer],new_x, new_y, snapcursor_size);
/* Update previous position tracking */
xctx->prev_gridx = xctx->mousex_snap;
xctx->prev_gridy = xctx->mousey_snap;
xctx->prev_snapx = new_x;
xctx->prev_snapy = new_y;
}
}
/* Restore previous drawing context */
xctx->draw_window = prev_draw_window;
xctx->draw_pixmap = prev_draw_pixmap;
}
static void erase_crosshair(int size) {
int prev_cr_x = (int)X_TO_SCREEN(xctx->prev_crossx);
int prev_cr_y = (int)Y_TO_SCREEN(xctx->prev_crossy);
int lw = INT_WIDTH(xctx->lw);
if(size) {
MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0],
prev_cr_x - 1 * lw - size, prev_cr_y - 1 * lw - size, 2 * lw + 2 * size, 2 * lw + 2 * size,
prev_cr_x - 1 * lw - size, prev_cr_y - 1 * lw - size);
MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0],
prev_cr_x - 1 * lw - size, prev_cr_y - 1 * lw - size, 2 * lw + 2 * size, 2 * lw + 2 * size,
prev_cr_x - 1 * lw - size, prev_cr_y - 1 * lw - size);
} else { /* full screen span xhair */
MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0],
0, prev_cr_y - 1 * lw, xctx->xrect[0].width, 2 * lw, 0, prev_cr_y - 1 * lw);
MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0],
prev_cr_x - 1 * lw, 0, 2 * lw, xctx->xrect[0].height, prev_cr_x - 1 * lw, 0);
}
}
static void draw_crosshair_shape(GC gc, double x, double y, int size)
{
double screen_x = X_TO_SCREEN(x);
double screen_y = Y_TO_SCREEN(y);
if(size) {
draw_xhair_line(gc, size, screen_x - size, screen_y - size, screen_x + size, screen_y - size);
draw_xhair_line(gc, size, screen_x - size, screen_y + size, screen_x + size, screen_y + size);
draw_xhair_line(gc, size, screen_x - size, screen_y - size, screen_x - size, screen_y + size);
draw_xhair_line(gc, size, screen_x + size, screen_y - size, screen_x + size, screen_y + size);
} else { /* full screen span xhair */
draw_xhair_line(gc, size, xctx->areax1, screen_y, xctx->areax2, screen_y);
draw_xhair_line(gc, size, screen_x, xctx->areay1, screen_x, xctx->areay2);
}
}
/* what == 3 (+4) : delete and draw (force)
* what == 1 (+4) : delete (force)
* what == 2 (+4) : draw (force)
* what == 4 : force (re)clear and/or (re)draw even if on same point */
void draw_crosshair(int what, int state)
{
int sdw, sdp;
int xhair_size = tclgetintvar("crosshair_size");
int snap_cursor = tclgetintvar("snap_cursor");
double mx, my;
int changed = 0;
dbg(1, "draw_crosshair(): what=%d\n", what);
sdw = xctx->draw_window;
sdp = xctx->draw_pixmap;
if(!xctx->mouse_inside) return;
mx = xctx->mousex_snap;
my = xctx->mousey_snap;
if( ( (xctx->ui_state & (MENUSTART | STARTWIRE) ) || xctx->ui_state == 0 ) &&
(state == ShiftMask)) {
if(!snap_cursor) {
/* mouse not changed so closest net or symbol pin unchanged too */
if(mx == xctx->prev_m_crossx && my == xctx->prev_m_crossy) {
mx = xctx->prev_crossx; /* get previous one */
my = xctx->prev_crossy;
} else {
/* mouse position changed, so find new closest net or pin */
find_closest_net_or_symbol_pin(xctx->mousex_snap, xctx->mousey_snap, &mx, &my);
changed = 1; /* we force a cursor redraw */
dbg(1, "find\n");
}
} else {
/* draw_snap_cursor(what); */
}
}
/* no changed closest pin/net, no force, mx,my is not changed. --> do nothing
| _____________| |
| | _____________________|____________________________ */
if(!changed && !(what & 4) && mx == xctx->prev_crossx && my == xctx->prev_crossy) {
return;
}
dbg(1, "draw %d\n", what);
xctx->draw_pixmap = 0;
xctx->draw_window = 1;
if(what & 1) { /* delete previous */
if(fix_broken_tiled_fill || !_unix) {
erase_crosshair(xhair_size);
} else {
draw_crosshair_shape(xctx->gctiled, xctx->prev_crossx, xctx->prev_crossy, xhair_size);
}
}
if(what & 2) { /* draw new */
draw_crosshair_shape(xctx->gc[xctx->crosshair_layer], mx, my, xhair_size);
}
if(what) draw_selection(xctx->gc[SELLAYER], 0);
if(what & 2) {
/* previous closest pin or net position (if snap wire or Shift pressed) */
xctx->prev_crossx = mx;
xctx->prev_crossy = my;
/* previous mouse_snap position */
xctx->prev_m_crossx = xctx->mousex_snap;
xctx->prev_m_crossy = xctx->mousey_snap;
}
xctx->draw_window = sdw;
xctx->draw_pixmap = sdp;
}
static void unselect_at_mouse_pos(int mx, int my)
{
xctx->last_command = 0;
@ -1709,13 +1665,14 @@ static void unselect_at_mouse_pos(int mx, int my)
rebuild_selected_array(); /* sets or clears xctx->ui_state SELECTION flag */
}
void snapped_wire(double c_snap)
static void snapped_wire(double c_snap)
{
double x, y;
if(!(xctx->ui_state & STARTWIRE)){
find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y);
xctx->mx_double_save = my_round(x / c_snap) * c_snap;
xctx->my_double_save = my_round(y / c_snap) * c_snap;
xctx->manhattan_lines = 1;
new_wire(PLACE, x, y);
new_wire(RUBBER, xctx->mousex_snap,xctx->mousey_snap);
}
@ -1729,7 +1686,7 @@ void snapped_wire(double c_snap)
}
}
static int check_menu_start_commands(double c_snap, int mx, int my)
static int check_menu_start_commands(int state, double c_snap, int mx, int my)
{
dbg(1, "check_menu_start_commands(): ui_state=%x, ui_state2=%x last_command=%d\n",
xctx->ui_state, xctx->ui_state2, xctx->last_command);
@ -1770,10 +1727,14 @@ static int check_menu_start_commands(double c_snap, int mx, int my)
else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTWIRE)) {
int prev_state = xctx->ui_state;
if(xctx->semaphore >= 2) return 0;
start_wire(xctx->mousex_snap, xctx->mousey_snap);
if(prev_state == STARTWIRE) {
tcleval("set constr_mv 0" );
xctx->constr_mv=0;
if( state & ShiftMask) {
snapped_wire(c_snap);
} else {
start_wire(xctx->mousex_snap, xctx->mousey_snap);
if(prev_state == STARTWIRE) {
tcleval("set constr_mv 0" );
xctx->constr_mv=0;
}
}
/*
@ -2433,6 +2394,54 @@ static int grabscreen(const char *win_path, int event, int mx, int my, KeySym ke
}
#endif
void unselect_attached_floaters(void)
{
int c, i, found = 0;
for(c = 0; c < cadlayers; c++) {
for(i = 0; i < xctx->rects[c]; i++) {
if(get_tok_value(xctx->rect[c][i].prop_ptr, "name", 0)[0]) {
found = 1;
select_box(c, i, 0, 1, 1);
}
}
for(i = 0; i < xctx->lines[c]; i++) {
if(get_tok_value(xctx->line[c][i].prop_ptr, "name", 0)[0]) {
found = 1;
select_line(c, i, 0, 1, 1);
}
}
for(i = 0; i < xctx->polygons[c]; i++) {
if(get_tok_value(xctx->poly[c][i].prop_ptr, "name", 0)[0]) {
found = 1;
select_polygon(c, i, 0, 1, 1);
}
}
for(i = 0; i < xctx->arcs[c]; i++) {
if(get_tok_value(xctx->arc[c][i].prop_ptr, "name", 0)[0]) {
found = 1;
select_arc(c, i, 0, 1, 1);
}
}
}
for(i = 0; i < xctx->wires; i++) {
if(get_tok_value(xctx->wire[i].prop_ptr, "name", 0)[0]) {
found = 1;
select_wire(i, 0, 1, 1);
}
}
for(i = 0; i < xctx->texts; i++) {
if(get_tok_value(xctx->text[i].prop_ptr, "name", 0)[0]) {
found = 1;
select_text(i, 0, 1, 1);
}
}
if(found) {
rebuild_selected_array();
draw_selection(xctx->gc[SELLAYER],0);
}
}
static void handle_enter_notify(int draw_xhair, int crosshair_size)
{
struct stat buf;
@ -2463,7 +2472,7 @@ static void handle_enter_notify(int draw_xhair, int crosshair_size)
xctx->mousey_snap = -340;
merge_file(1, ".sch");
}
return;
}
@ -2477,9 +2486,8 @@ static void handle_motion_notify(int event, KeySym key, int state, int rstate, i
}
if(draw_xhair) {
draw_crosshair(1, state); /* when moving mouse: first action is delete crosshair, will be drawn later */
if(snap_cursor && wire_draw_active) draw_snap_cursor(1);
}
if(snap_cursor && wire_draw_active) draw_snap_cursor(1);
if(snap_cursor) draw_snap_cursor(1); /* clear */
/* pan schematic */
if(xctx->ui_state & STARTPAN) pan(RUBBER, mx, my);
@ -2487,7 +2495,7 @@ static void handle_motion_notify(int event, KeySym key, int state, int rstate, i
if(draw_xhair) {
draw_crosshair(2, state); /* locked UI: draw new crosshair and break out */
}
if(snap_cursor && wire_draw_active) draw_snap_cursor(2);
if(snap_cursor && ((state == ShiftMask) || wire_draw_active)) draw_snap_cursor(2); /* redraw */
return;
}
@ -2588,7 +2596,7 @@ static void handle_motion_notify(int event, KeySym key, int state, int rstate, i
if(draw_xhair) {
draw_crosshair(2, state); /* what = 2(draw) */
}
if(snap_cursor && wire_draw_active) draw_snap_cursor(2);
if(snap_cursor && ((state == ShiftMask) || wire_draw_active)) draw_snap_cursor(2); /* redraw */
return;
}
@ -2827,20 +2835,23 @@ static void handle_key_press(int event, KeySym key, int state, int rstate, int m
draw();
return;
}
if(key == 'X' && rstate == 0) /* highlight discrepanciens between selected instance pin and net names */
/* highlight discrepanciens between selected instance pin and net names */
if(key == 'X' && rstate == 0)
{
hilight_net_pin_mismatches();
return;
}
if(key== 'W' /* && !xctx->ui_state */ && rstate == 0 && !cadence_compat) { /* create wire snapping to closest instance pin (original keybind) */
/* create wire snapping to closest instance pin */
if(key== 'W' /* && !xctx->ui_state */ && rstate == 0 && !cadence_compat) {
if(xctx->semaphore >= 2) return;
snapped_wire(c_snap);
return;
}
if(key== 's' /* && !xctx->ui_state */ && rstate == 0 && cadence_compat) { /* create wire snapping to closest instance pin (cadence keybind) */
if(xctx->semaphore >= 2) return;
snapped_wire(c_snap);
return;
/* create wire snapping to closest instance pin (cadence keybind) */
if(key== 's' /* && !xctx->ui_state */ && rstate == 0 && cadence_compat) {
if(xctx->semaphore >= 2) return;
snapped_wire(c_snap);
return;
}
if(key == 'w' /* && !xctx->ui_state */ && rstate==0) /* place wire. */
{
@ -2875,9 +2886,9 @@ static void handle_key_press(int event, KeySym key, int state, int rstate, int m
if(xctx->ui_state2 & MENUSTARTWIRE) {
xctx->ui_state2 &= ~MENUSTARTWIRE;
}
if(snap_cursor) draw_snap_cursor(1); /* erase */
if(tclgetboolvar("persistent_command") && (xctx->last_command & STARTWIRE) && cadence_compat) {
xctx->last_command &= ~STARTWIRE;
if(snap_cursor) draw_snap_cursor(1);
}
return;
}
@ -3394,6 +3405,9 @@ static void handle_key_press(int event, KeySym key, int state, int rstate, int m
{
if(xctx->semaphore >= 2) return;
ask_new_file();
xctx->semaphore--;
tcleval("load_additional_files");
xctx->semaphore++;
return;
}
if(key=='S' && rstate == 0) /* change element order */
@ -3530,7 +3544,11 @@ static void handle_key_press(int event, KeySym key, int state, int rstate, int m
draw();
return;
}
if(0 && (key=='u') && rstate==ControlMask) /* testmode */
if(key=='u' && rstate==ControlMask) /* unselect attached floater elements */
{
unselect_attached_floaters();
}
if(0 && (key=='|') && rstate==ControlMask) /* testmode */
{
static int x = 0;
@ -4036,21 +4054,6 @@ static void handle_key_press(int event, KeySym key, int state, int rstate, int m
check_unique_names(1);
return;
}
if( 0 && (key==';') && (state & ControlMask) ) /* testmode */
{
return;
}
if(0 && key=='~' && (state & ControlMask)) { /* testmode */
return;
}
if(0 && key=='|' && !(state & ControlMask)) { /* testmode */
return;
}
if(0 && key=='|' && (state & ControlMask)) /* testmode */
{
return;
}
if(key=='f' && rstate == ControlMask) /* search */
{
if(xctx->semaphore >= 2) return;
@ -4215,7 +4218,7 @@ static void handle_button_press(int event, int state, int rstate, KeySym key, in
return;
}
/* handle all object insertions started from Tools/Edit menu */
if(check_menu_start_commands(c_snap, mx, my)) return;
if(check_menu_start_commands(state, c_snap, mx, my)) return;
/* complete the pending STARTWIRE, STARTRECT, STARTZOOM, STARTCOPY ... operations */
if(end_place_move_copy_zoom()) return;
@ -4382,6 +4385,7 @@ static void handle_button_release(int event, KeySym key, int state, int button,
int savesem = xctx->semaphore;
move_objects(ABORT, 0, 0.0, 0.0);
unselect_all(1);
xctx->drag_elements = 0; /* after ctrl-Button1Press on a launcher need to clear this */
select_object(xctx->mousex, xctx->mousey, SELECTED, 0, NULL);
rebuild_selected_array();
xctx->semaphore = 0;
@ -4442,13 +4446,12 @@ static void handle_button_release(int event, KeySym key, int state, int button,
}
/* clear start from menu flag or infix_interface=0 start commands */
if(xctx->ui_state & MENUSTART) {
if( state == Button1Mask && xctx->ui_state & MENUSTART) {
xctx->ui_state &= ~MENUSTART;
return;
}
if(draw_xhair) draw_crosshair(3, state); /* restore crosshair when selecting / unselecting */
if(snap_cursor && wire_draw_active) draw_snap_cursor(3);
if(snap_cursor && ((state == ShiftMask) || wire_draw_active)) draw_snap_cursor(3); /* erase & redraw */
return;
}
@ -4634,7 +4637,7 @@ int wire_draw_active = (xctx->ui_state & STARTWIRE) ||
case LeaveNotify:
if(draw_xhair) draw_crosshair(1, state); /* clear crosshair when exiting window */
if(snap_cursor && wire_draw_active) draw_snap_cursor(1);
if(snap_cursor) draw_snap_cursor(1); /* erase */
tclvareval(xctx->top_path, ".drw configure -cursor {}" , NULL);
xctx->mouse_inside = 0;
break;
@ -4678,6 +4681,8 @@ int wire_draw_active = (xctx->ui_state & STARTWIRE) ||
break;
case KeyRelease:
/* force clear (even if mouse pos not changed) */
/* if(snap_cursor && (key == XK_Shift_L || key == XK_Shift_R) ) draw_snap_cursor(5); */
break;
case KeyPress:

View File

@ -930,10 +930,14 @@ static void drawgrid()
double mult;
#if DRAW_ALL_CAIRO==0
int i=0;
const char *psize_ptr;
int big_gr = tclgetboolvar("big_grid_points");
int grid_point_size = -1;
char dash_arr[2];
int axes = tclgetboolvar("draw_grid_axes");
psize_ptr = tclgetvar("grid_point_size");
if(psize_ptr[0]) grid_point_size = atoi(psize_ptr);
if(axes) {
dash_arr[0] = dash_arr[1] = (char) 3;
XSetDashes(display, xctx->gc[GRIDLAYER], 0, dash_arr, 1);
@ -959,9 +963,8 @@ static void drawgrid()
delta = delta * pow(CADGRIDMULTIPLY, mult);
}
/* while(delta < CADGRIDTHRESHOLD) delta *= CADGRIDMULTIPLY; */ /* <-- to be improved,but works */
/* ************************ Draw axes ****************** */
#if DRAW_ALL_CAIRO==1
xax =floor(xctx->xorigin*xctx->mooz) + 0.5; yax = floor(xctx->yorigin*xctx->mooz) + 0.5;
#else
@ -1007,26 +1010,36 @@ static void drawgrid()
#endif
}
}
/* ************************ /Draw axes ****************** */
#if DRAW_ALL_CAIRO==0
if(axes) {
if(grid_point_size != -1) {
XSetLineAttributes (display, xctx->gc[GRIDLAYER],
grid_point_size, LineSolid, CapProjecting, LINEJOIN);
} else if(!big_gr) {
XSetLineAttributes (display, xctx->gc[GRIDLAYER],
0, LineSolid, LINECAP, LINEJOIN);
} else {
XSetLineAttributes (display, xctx->gc[GRIDLAYER],
XLINEWIDTH(xctx->lw), LineSolid, LINECAP, LINEJOIN);
}
#endif
if(grid_point_size >= 0) big_gr = 1;
tmp = floor((xctx->areay1+1)/delta)*delta-fmod(-xctx->yorigin*xctx->mooz, delta);
for(x=floor((xctx->areax1+1)/delta)*delta-fmod(-xctx->xorigin*xctx->mooz, delta); x < xctx->areax2; x += delta) {
xx = x;
#if DRAW_ALL_CAIRO==1
xx = floor(x) + 0.5;
#endif
if((int)xx == (int)xax) continue;
if(axes && (int)xx == (int)xax) continue;
for(y=tmp; y < xctx->areay2; y += delta) {
yy = y;
#if DRAW_ALL_CAIRO==1
yy = floor(y) + 0.5;
#endif
if((int)yy == (int)yax) continue;
if(axes && (int)yy == (int)yax) continue;
#if DRAW_ALL_CAIRO==1
if(xctx->draw_window) {
cairo_move_to(xctx->cairo_ctx, xx, yy) ;
@ -1087,6 +1100,12 @@ static void drawgrid()
if(xctx->draw_pixmap) cairo_stroke(xctx->cairo_save_ctx);
if(xctx->draw_window) cairo_stroke(xctx->cairo_ctx);
#endif
#if DRAW_ALL_CAIRO==0
XSetLineAttributes (display, xctx->gc[GRIDLAYER],
XLINEWIDTH(xctx->lw), LineSolid, LINECAP, LINEJOIN);
#endif
}
#if !defined(__unix__) && HAS_CAIRO==1
@ -2838,7 +2857,7 @@ static void draw_graph_grid(Graph_ctx *gr, void *ct)
/* background */
filledrect(0, NOW, gr->rx1, gr->ry1, gr->rx2, gr->ry2, 2, -1, -1);
/* graph bounding box */
drawrect(GRIDLAYER, NOW, gr->rx1, gr->ry1, gr->rx2, gr->ry2, 0, -1, -1);
drawrect(GRIDLAYER, NOW, gr->rx1, gr->ry1, gr->rx2, gr->ry2, 2, -1, -1);
bbox(START, 0.0, 0.0, 0.0, 0.0);
bbox(ADD, gr->rx1, gr->ry1, gr->rx2, gr->ry2);
@ -3055,10 +3074,9 @@ void setup_graph_data(int i, int skip, Graph_ctx *gr)
gr->gh = gr->gy2 - gr->gy1;
/* set margins */
tmp = gr->rw * 0.14;
gr->marginx = tmp < 50 ? 50 : tmp;
gr->marginx = tmp;
tmp = gr->rh * 0.14;
gr->marginy = tmp < 40 ? 40 : tmp;
gr->marginy = tmp;
/* calculate graph bounding box (container - margin)
* This is the box where plot is done */
gr->x1 = gr->rx1 + gr->marginx;
@ -3083,14 +3101,15 @@ void setup_graph_data(int i, int skip, Graph_ctx *gr)
/* x axis, y axis text sizes */
gr->txtsizey = gr->h / gr->divy * 0.0095;
tmp = gr->marginx * 0.003;
if(tmp < gr->txtsizey) gr->txtsizey = tmp;
tmp = gr->marginy * 0.02;
tmp = gr->marginx * 0.004;
if(tmp < gr->txtsizey) gr->txtsizey = tmp;
/* tmp = gr->marginy * 0.02;
* if(tmp < gr->txtsizey) gr->txtsizey = tmp;
*/
gr->txtsizey *= gr->magy;
gr->txtsizex = gr->w / gr->divx * 0.0033;
tmp = gr->marginy * 0.0063;
gr->txtsizex = gr->w / gr->divx * 0.0070;
tmp = gr->marginy * 0.0065;
if(tmp < gr->txtsizex) gr->txtsizex = tmp;
gr->txtsizex *= gr->magx;
@ -3258,7 +3277,7 @@ static void draw_graph_variables(int wcnt, int wave_color, int n_nodes, int swee
if(gr->unitx != 1.0) my_snprintf(tmpstr, S(tmpstr), "%s[%c]", stok ? stok : "" , gr->unitx_suffix);
else my_snprintf(tmpstr, S(tmpstr), "%s", stok ? stok : "");
draw_string(wave_color, NOW, tmpstr, 2, 1, 0, 0,
gr->rx1 + 2 + gr->rw / n_nodes * wcnt, gr->ry2-5, gr->txtsizelab, gr->txtsizelab);
gr->rx1 + 2 + gr->rw / n_nodes * wcnt, gr->ry2-2, gr->txtsizelab, gr->txtsizelab);
}
if(gr->legend || gr->digital) {
@ -3782,7 +3801,7 @@ int find_closest_wave(int i, Graph_ctx *gr)
* 8: all drawing, if not set do only XCopyArea / x-cursor if specified
* ct is a pointer used in windows for cairo
*/
void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
void draw_graph(int i, int flags, Graph_ctx *gr, void *ct)
{
int wc = 4, wave_color = 4;
char *node = NULL, *color = NULL, *sweep = NULL;
@ -3804,7 +3823,6 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
int save_extra_idx = -1;
double cursor1, cursor2;
if(xctx->only_probes) return;
if(RECT_OUTSIDE( gr->sx1, gr->sy1, gr->sx2, gr->sy2,
xctx->areax1, xctx->areay1, xctx->areax2, xctx->areay2)) return;
@ -4089,7 +4107,7 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
if((gr->mode == 2) || (xxfollowing >= start && xxprevious <= end)) {
if(first == -1) first = p;
/* Build poly x array. Translate from graph coordinates to screen coords */
point[poly_npoints].x = (short)S_X(xx);
point[poly_npoints].x = (short)CLIP(S_X(xx), -30000, 30000);
if(dataset == -1 || dataset == sweepvar_wrap) {
/* cursor1: show measurements on nodes in graph */
if(flags & 2 && measure_p == -1 && cnt) {
@ -4770,8 +4788,11 @@ static void draw_images_all(void)
#endif
}
void svg_embedded_graph(FILE *fd, xRect *r, double rx1, double ry1, double rx2, double ry2)
void svg_embedded_graph(FILE *fd, int i, double rx1, double ry1, double rx2, double ry2)
{
#ifndef __unix__
xRect *r = &xctx->rect[GRIDLAYER][i];
#endif
#if HAS_CAIRO==1
Zoom_info zi;
char *ptr = NULL;
@ -4821,7 +4842,9 @@ void svg_embedded_graph(FILE *fd, xRect *r, double rx1, double ry1, double rx2,
xctx->draw_pixmap=1;
save = xctx->do_copy_area;
xctx->do_copy_area=0;
draw();
setup_graph_data(i, 0, &xctx->graph_struct);
draw_graph(i, 8 + (xctx->graph_flags & (4 | 2 | 128 | 256)), &xctx->graph_struct, NULL);
#ifdef __unix__
png_sfc = cairo_xlib_surface_create(display, xctx->save_pixmap, visual,
xctx->xrect[0].width, xctx->xrect[0].height);
@ -4834,12 +4857,9 @@ void svg_embedded_graph(FILE *fd, xRect *r, double rx1, double ry1, double rx2,
cairo_set_source_surface(ct, xctx->cairo_save_sfc, 0, 0);
cairo_set_operator(ct, CAIRO_OPERATOR_SOURCE);
cairo_paint(ct);
for(int i = 0; i < xctx->rects[GRIDLAYER]; ++i) {
xRect *r = &xctx->rect[GRIDLAYER][i];
if(r->flags & 1) {
setup_graph_data(i, 0, &xctx->graph_struct);
draw_graph(i, 8 + (xctx->graph_flags & (4 | 2 | 128 | 256)), &xctx->graph_struct, (void *)ct);
}
if(r->flags & 1) {
setup_graph_data(i, 0, &xctx->graph_struct);
draw_graph(i, 8 + (xctx->graph_flags & (4 | 2 | 128 | 256)), &xctx->graph_struct, (void *)ct);
}
#endif
closure.buffer = NULL;

View File

@ -594,7 +594,11 @@ FILE *my_fopen(const char *f, const char *m)
st = stat(f, &buf);
if(st) return NULL; /* not existing or error */
#ifdef __unix__
if(!S_ISREG(buf.st_mode)) return NULL; /* not a regular file/symlink to a regular file */
#else
/* TBD */
#endif
fd = fopen(f, m);
return fd;
}
@ -1637,6 +1641,7 @@ static int update_symbol(const char *result, int x, int selected_inst)
/* preserve backslashes in name ---------0---------------------------------->. */
my_strdup(_ALLOC_ID_, &name, get_tok_value(xctx->inst[*ii].prop_ptr, "name", 1));
if(name && name[0] ) {
char *old_name = NULL;
dbg(1, "update_symbol(): prefix!='\\0', name=%s\n", name);
/* change prefix if changing symbol type; */
if(prefix && old_prefix && old_prefix != prefix) {
@ -1650,10 +1655,13 @@ static int update_symbol(const char *result, int x, int selected_inst)
if(!k) hash_names(-1, XINSERT);
hash_names(*ii, XDELETE);
dbg(1, "update_symbol(): delete %s\n", xctx->inst[*ii].instname);
my_strdup2(_ALLOC_ID_, &old_name, xctx->inst[*ii].instname);
new_prop_string(*ii, ptr, /* sets also inst[].instname */
tclgetboolvar("disable_unique_names")); /* set new prop_ptr */
hash_names(*ii, XINSERT);
update_attached_floaters(old_name, *ii, 1);
dbg(1, "update_symbol(): insert %s\n", xctx->inst[*ii].instname);
my_free(_ALLOC_ID_, &old_name);
}
set_inst_flags(&xctx->inst[*ii]);
} /* end for(k=0;k<xctx->lastsel; ++k) */

View File

@ -274,10 +274,11 @@ static int kklex()
while (c != 0 && isalnum(c) && i < length);
str--;
symbuf[i] = '\0';
s = getsym (symbuf);
s = getsym(symbuf);
kklval.tptr = s;
dbg(dbglev, "ylex: FNCT=%s\n", symbuf);
return FNCT;
if(s) return FNCT;
return 0; /* error : undefined identifier */
}
/* Any other character is a token by itself. */
return c;

View File

@ -25,7 +25,7 @@
static double distance; /* safe to keep even with multiple schematics */
static Selected sel; /* safe to keep even with multiple schematics */
static void find_closest_wire(double mx, double my)
static void find_closest_wire(double mx, double my, int override_lock)
/* returns the net that is closest to the mouse pointer */
/* if there are nets and distance < CADWIREMINDIST */
{
@ -42,14 +42,15 @@ static void find_closest_wire(double mx, double my)
w = i; d = tmp;
}
}
if( d <= threshold && w!=-1)
if( w != -1 && d <= threshold &&
(override_lock || strboolcmp(get_tok_value(xctx->wire[w].prop_ptr, "lock", 0), "true")) )
{
sel.n = w; sel.type = WIRE;
distance = d;
}
}
static void find_closest_bezier(double mx, double my, int c, int i, int *l, int *col)
static double find_closest_bezier(double mx, double my, double d, int c, int i, int *l, int *col)
{
const double bez_steps = 1.0/8.0; /* divide the t = [0,1] interval into 8 steps */
int b;
@ -97,16 +98,17 @@ static void find_closest_bezier(double mx, double my, int c, int i, int *l, int
xp1 = (1 - t1) * (1 - t1) * x0 + 2 * (1 - t1) * t1 * x1 + t1 * t1 * x2;
yp1 = (1 - t1) * (1 - t1) * y0 + 2 * (1 - t1) * t1 * y1 + t1 * t1 * y2;
ORDER(xp, yp, xp1, yp1);
if( (tmp = dist(xp, yp, xp1, yp1, mx, my)) < distance )
if( (tmp = dist(xp, yp, xp1, yp1, mx, my)) < d )
{
*l = i; distance = tmp; *col = c;
dbg(1, "find_closest_bezier(): distance=%.16g n=%d\n", distance, i);
*l = i; d = tmp; *col = c;
}
}
}
dbg(1, "find_closest_bezier(): d=%.16g n=%d\n", d, i);
return d;
}
static void find_closest_polygon(double mx, double my)
static void find_closest_polygon(double mx, double my, int override_lock)
/* returns the polygon that is closest to the mouse pointer */
/* if there are lines and distance < CADWIREMINDIST */
{
@ -126,15 +128,7 @@ static void find_closest_polygon(double mx, double my)
bezier = bezier && (p->points > 2);
if(bezier) {
double ds = xctx->cadhalfdotsize;
find_closest_bezier(mx, my, c, i, &l, &col);
for(j = 0; j < p->points; j++) {
if( POINTINSIDE(mx, my, p->x[j] - ds, p->y[j] - ds, p->x[j] + ds, p->y[j] + ds)) {
l = i; d = 0.0;col = c;
break;
}
}
d = find_closest_bezier(mx, my, d, c, i, &l, &col);
} else {
for(j=0; j<xctx->poly[c][i].points-1; ++j) {
x1 = p->x[j];
@ -145,13 +139,14 @@ static void find_closest_polygon(double mx, double my)
if( (tmp = dist(x1, y1, x2, y2, mx, my)) < d )
{
l = i; d = tmp;col = c;
dbg(1, "find_closest_polygon(): d=%.16g n=%d\n", d, i);
}
}
dbg(1, "find_closest_polygon(): d=%.16g n=%d\n", d, i);
}
} /* end for i */
} /* end for c */
if( d <= threshold && l!=-1)
if( d <= threshold && l!=-1 &&
(override_lock || strboolcmp(get_tok_value(xctx->poly[col][l].prop_ptr, "lock", 0), "true")))
{
sel.n = l; sel.type = POLYGON; sel.col = col;
distance = d;
@ -159,7 +154,7 @@ static void find_closest_polygon(double mx, double my)
}
static void find_closest_line(double mx, double my)
static void find_closest_line(double mx, double my, int override_lock)
/* returns the line that is closest to the mouse pointer */
/* if there are lines and distance < CADWIREMINDIST */
{
@ -181,7 +176,8 @@ static void find_closest_line(double mx, double my)
}
} /* end for i */
} /* end for c */
if( d <= threshold && l!=-1)
if( d <= threshold && l!=-1 &&
(override_lock || strboolcmp(get_tok_value(xctx->line[col][l].prop_ptr, "lock", 0), "true")))
{
sel.n = l; sel.type = LINE; sel.col = col;
distance = d;
@ -326,7 +322,7 @@ void xfind_closest_net_or_symbol_pin(double mx, double my, double *x, double *y)
}
#endif
static void find_closest_arc(double mx, double my)
static void find_closest_arc(double mx, double my, int override_lock)
{
double dist, angle, angle1, angle2;
int i, c, r=-1, col;
@ -371,7 +367,8 @@ static void find_closest_arc(double mx, double my)
}
} /* end for i */
} /* end for c */
if( r!=-1 && d <= threshold ) /* * pow(xctx->arc[col][r].r, 2)) */
if(r!=-1 && d <= threshold &&
strboolcmp(get_tok_value(xctx->arc[col][r].prop_ptr, "lock", 0), "true"))
{
sel.n = r; sel.type = ARC; sel.col = col;
distance = d;
@ -439,7 +436,7 @@ static void find_closest_element(double mx, double my, int override_lock)
}
}
static void find_closest_text(double mx, double my)
static void find_closest_text(double mx, double my, int override_lock)
{
short rot, flip;
double xx1, xx2, yy1, yy2;
@ -476,7 +473,9 @@ static void find_closest_text(double mx, double my)
dbg(2, "find_closest_text(): finding closest text, texts=%d, dist=%.16g\n", i, d);
}
} /* end for i */
if( d <= threshold && r!=-1)
if( r != -1 && d <= threshold &&
(override_lock || strboolcmp(get_tok_value(xctx->text[r].prop_ptr, "lock", 0), "true")) )
{
sel.n = r; sel.type = xTEXT;
distance = d;
@ -487,14 +486,14 @@ Selected find_closest_obj(double mx, double my, int override_lock)
{
sel.n = 0L; sel.col = 0; sel.type = 0;
distance = DBL_MAX;
find_closest_line(mx, my);
find_closest_polygon(mx, my);
find_closest_line(mx, my, override_lock);
find_closest_polygon(mx, my, override_lock);
/* 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, override_lock);
find_closest_arc(mx, my);
find_closest_arc(mx, my, override_lock);
/* 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_wire(mx, my);
find_closest_text(mx, my, override_lock);
find_closest_wire(mx, my, override_lock);
find_closest_element(mx, my, override_lock);
return sel; /*sel.type = 0 if nothing found */
}

View File

@ -169,6 +169,7 @@ ctrl+alt 's' Save-as symbol
- 't' Place text
shift 'T' Toggle *_ignore flag on selected instances
alt 'u' Align to current grid selected objects
ctrl 'u' Unselect attached floater objects
shift 'U' Redo
- 'u' Undo
- 'v' Constrained vertical move/copy of objects

View File

@ -513,6 +513,82 @@ void draw_selection(GC g, int interruptable)
xctx->movelastsel = i;
}
/* sel: if set to 1 change references only on selected items, like in a copy operation.
* If set to 0 operate on all objects with matching name=... attribute */
void update_attached_floaters(const char *from_name, int inst, int sel)
{
int i, c;
char *to_name = xctx->inst[inst].instname;
const char *attach = get_tok_value(xctx->inst[inst].prop_ptr, "attach", 0);
char *new_attach;
if(!from_name || !from_name[0]) return;
if(!to_name || !to_name[0]) return;
if(!attach[0]) return;
new_attach = str_replace(attach, from_name, to_name, 1, 1);
my_strdup(_ALLOC_ID_, &xctx->inst[inst].prop_ptr,
subst_token(xctx->inst[inst].prop_ptr, "attach", new_attach) );
for(c = 0; c < cadlayers; c++) {
for(i = 0; i < xctx->rects[c]; i++) {
if(!sel || xctx->rect[c][i].sel == SELECTED) {
if( !strcmp(from_name, get_tok_value(xctx->rect[c][i].prop_ptr, "name", 0))) {
my_strdup(_ALLOC_ID_, &xctx->rect[c][i].prop_ptr,
subst_token(xctx->rect[c][i].prop_ptr, "name", to_name) );
}
if(c == GRIDLAYER) {
const char *node = get_tok_value(xctx->rect[c][i].prop_ptr, "node", 2);
if(node && node[0]) {
const char *new_node = str_replace(node, from_name, to_name, 1, -1);
my_strdup(_ALLOC_ID_, &xctx->rect[c][i].prop_ptr,
subst_token(xctx->rect[c][i].prop_ptr, "node", new_node));
}
}
}
}
for(i = 0; i < xctx->lines[c]; i++) {
if((!sel || xctx->line[c][i].sel == SELECTED) &&
!strcmp(from_name, get_tok_value(xctx->line[c][i].prop_ptr, "name", 0))) {
my_strdup(_ALLOC_ID_, &xctx->line[c][i].prop_ptr,
subst_token(xctx->line[c][i].prop_ptr, "name", to_name) );
}
}
for(i = 0; i < xctx->polygons[c]; i++) {
if((!sel || xctx->poly[c][i].sel == SELECTED) &&
!strcmp(from_name, get_tok_value(xctx->poly[c][i].prop_ptr, "name", 0))) {
my_strdup(_ALLOC_ID_, &xctx->poly[c][i].prop_ptr,
subst_token(xctx->poly[c][i].prop_ptr, "name", to_name) );
}
}
for(i = 0; i < xctx->arcs[c]; i++) {
if((!sel || xctx->arc[c][i].sel == SELECTED) &&
!strcmp(from_name, get_tok_value(xctx->arc[c][i].prop_ptr, "name", 0))) {
my_strdup(_ALLOC_ID_, &xctx->arc[c][i].prop_ptr,
subst_token(xctx->arc[c][i].prop_ptr, "name", to_name) );
}
}
}
for(i = 0; i < xctx->wires; i++) {
if((!sel || xctx->wire[i].sel == SELECTED) &&
!strcmp(from_name, get_tok_value(xctx->wire[i].prop_ptr, "name", 0))) {
my_strdup(_ALLOC_ID_, &xctx->wire[i].prop_ptr,
subst_token(xctx->wire[i].prop_ptr, "name", to_name) );
}
}
for(i = 0; i < xctx->texts; i++) {
if((!sel || xctx->text[i].sel == SELECTED) &&
!strcmp(from_name, get_tok_value(xctx->text[i].prop_ptr, "name", 0))) {
my_strdup(_ALLOC_ID_, &xctx->text[i].prop_ptr,
subst_token(xctx->text[i].prop_ptr, "name", to_name) );
set_text_flags(&xctx->text[i]);
}
}
}
void copy_objects(int what)
{
int tmpi, c, i, n, k /*, tmp */ ;
@ -881,6 +957,9 @@ void copy_objects(int what)
newpropcnt++;
new_prop_string(xctx->instances, xctx->inst[n].prop_ptr, /* sets also inst[].instname */
tclgetboolvar("disable_unique_names"));
update_attached_floaters(xctx->inst[n].instname, xctx->instances, 1);
hash_names(xctx->instances, XINSERT);
xctx->instances++; /* symbol_bbox calls translate and translate must have updated xctx->instances */
symbol_bbox(xctx->instances-1,

View File

@ -678,7 +678,7 @@ static void print_wires(void)
ptr=xctx->wire_spatial_table[0][1];
while(ptr)
{
select_wire(ptr->n,SELECTED, 1);
select_wire(ptr->n,SELECTED, 1, 1);
rebuild_selected_array();
ptr=ptr->next;
}

View File

@ -48,7 +48,7 @@ static void merge_text(FILE *fd)
xctx->text[i].sel=0;
load_ascii_string(&xctx->text[i].prop_ptr,fd);
set_text_flags(&xctx->text[i]);
select_text(i,SELECTED, 1);
select_text(i,SELECTED, 1, 1);
xctx->texts++;
}
@ -66,7 +66,7 @@ static void merge_wire(FILE *fd)
load_ascii_string( &ptr, fd);
storeobject(-1, x1,y1,x2,y2,WIRE,0,SELECTED,ptr);
my_free(_ALLOC_ID_, &ptr);
select_wire(i, SELECTED, 1);
select_wire(i, SELECTED, 1, 1);
}
static void merge_box(FILE *fd)
@ -172,7 +172,7 @@ static void merge_arc(FILE *fd)
ptr[i].dash = 0;
}
select_arc(c,i, SELECTED, 1);
select_arc(c,i, SELECTED, 1, 1);
xctx->arcs[c]++;
}
@ -232,7 +232,7 @@ static void merge_polygon(FILE *fd)
ptr[i].dash = 0;
}
select_polygon(c,i, SELECTED, 1);
select_polygon(c,i, SELECTED, 1, 1);
xctx->polygons[c]++;
}
@ -271,7 +271,7 @@ static void merge_line(FILE *fd)
ptr[i].bus = 1;
else
ptr[i].bus = 0;
select_line(c,i, SELECTED, 1);
select_line(c,i, SELECTED, 1, 1);
xctx->lines[c]++;
}

View File

@ -250,8 +250,9 @@ static int ps_embedded_image(xRect* r, double x1, double y1, double x2, double y
return 1;
}
static int ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, double ry2)
static int ps_embedded_graph(int i, double rx1, double ry1, double rx2, double ry2)
{
xRect *r = &xctx->rect[GRIDLAYER][i];
#if defined(HAS_LIBJPEG) && HAS_CAIRO==1
Zoom_info zi;
double rw, rh, scale;
@ -269,7 +270,7 @@ static int ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, doubl
int quality=40;
const char *quality_attr;
size_t oLength;
int i;
int j;
double sx1, sy1, sx2, sy2;
/* screen position */
@ -323,7 +324,9 @@ static int ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, doubl
d_c = tclgetboolvar("dark_colorscheme");
tclsetboolvar("dark_colorscheme", 0);
build_colors(0, 0);
draw();
setup_graph_data(i, 0, &xctx->graph_struct);
draw_graph(i, 8 + (xctx->graph_flags & (4 | 2 | 128 | 256)), &xctx->graph_struct, NULL);
dbg(1, "width=%d, rwi=%d height=%d rhi=%d\n", xctx->xrect[0].width, rwi, xctx->xrect[0].height, rhi);
#ifdef __unix__
png_sfc = cairo_xlib_surface_create(display, xctx->save_pixmap, visual,
@ -337,13 +340,8 @@ static int ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, doubl
cairo_set_source_surface(ct, xctx->cairo_save_sfc, 0, 0);
cairo_set_operator(ct, CAIRO_OPERATOR_SOURCE);
cairo_paint(ct);
for (i = 0; i < xctx->rects[GRIDLAYER]; ++i) {
xRect* r2 = &xctx->rect[GRIDLAYER][i];
if (r2->flags & 1) {
setup_graph_data(i, 0, &xctx->graph_struct);
draw_graph(i, 8 + (xctx->graph_flags & (4 | 2 | 128 | 256)), &xctx->graph_struct, (void *)ct);
}
}
setup_graph_data(i, 0, &xctx->graph_struct);
draw_graph(i, 8 + (xctx->graph_flags & (4 | 2 | 128 | 256)), &xctx->graph_struct, (void *)ct);
#endif
cairo_image_surface_write_to_jpeg_mem(png_sfc, &jpgData, &fileSize, quality);
@ -382,10 +380,10 @@ static int ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, doubl
fprintf(fd, "} exec\n");
#if 1 /* break lines */
for (i = 0; i < oLength; ++i)
for (j = 0; j < oLength; ++j)
{
fputc(ascii85EncodedJpeg[i],fd);
if(i > 0 && (i % 64) == 0)
fputc(ascii85EncodedJpeg[j],fd);
if(j > 0 && (j % 64) == 0)
{
fputc('\n',fd);
/* if (ascii85Encode[i+1]=='%') idx=63; imageMagic does this for some reason?!
@ -1449,8 +1447,8 @@ void create_ps(char **psfile, int what, int fullzoom, int eps)
continue;
}
if (c == GRIDLAYER && (xctx->rect[c][i].flags & 1)) { /* graph */
xRect* r = &xctx->rect[c][i];
ps_embedded_graph(r, r->x1, r->y1, r->x2, r->y2);
xRect *r = &xctx->rect[c][i];
ps_embedded_graph(i, r->x1, r->y1, r->x2, r->y2);
}
if(c != GRIDLAYER || !(xctx->rect[c][i].flags & 1) ) {
ps_filledrect(c, xctx->rect[c][i].x1, xctx->rect[c][i].y1,

View File

@ -1014,17 +1014,16 @@ int raw_read(const char *f, Raw **rawptr, const char *type, int no_warning, doub
return res;
}
dbg(1, "raw_read(): type=%s\n", type ? type : "<NULL>");
*rawptr = my_calloc(_ALLOC_ID_, 1, sizeof(Raw));
raw = *rawptr;
raw->level = -1;
raw->annot_p = -1;
raw->sweep1 = sweep1;
raw->sweep2 = sweep2;
raw->annot_sweep_idx = -1;
int_hash_init(&raw->table, HASHSIZE);
fd = my_fopen(f, fopen_read_mode);
if(fd) {
*rawptr = my_calloc(_ALLOC_ID_, 1, sizeof(Raw));
raw = *rawptr;
raw->level = -1;
raw->annot_p = -1;
raw->sweep1 = sweep1;
raw->sweep2 = sweep2;
raw->annot_sweep_idx = -1;
int_hash_init(&raw->table, HASHSIZE);
if((res = read_dataset(fd, rawptr, type, no_warning)) == 1) {
int i;
set_modify(-2); /* clear text floater caches */
@ -1044,12 +1043,13 @@ int raw_read(const char *f, Raw **rawptr, const char *type, int no_warning, doub
xRect *r;
r = &xctx->rect[GRIDLAYER][0];
if(r->flags & 1) {
setup_graph_data(0, 0, &xctx->graph_struct);
backannotate_at_cursor_b_pos(r, &xctx->graph_struct);
/* don't overwrite xctx->graph_struct, being used in draw_graph() which calls raw_read() */
Graph_ctx gr_ctx;
setup_graph_data(0, 0, &gr_ctx);
backannotate_at_cursor_b_pos(r, &gr_ctx);
}
}
}
} else {
/* free_rawfile(rawptr, 0, 0); */ /* do not free: already done in read_dataset()->extra_rawfile() */
if(!no_warning) {
@ -1074,6 +1074,22 @@ int raw_read(const char *f, Raw **rawptr, const char *type, int no_warning, doub
return 0;
}
int raw_renamevar(const char *old_name, const char *new_name)
{
int n, ret = 0;
Raw *raw = xctx->raw;
Int_hashentry *entry;
n = get_raw_index(old_name, &entry);
if(n < 0) return ret;
dbg(1, "n=%d, %s \n", n, entry->token);
int_hash_lookup(&raw->table, entry->token, 0, XDELETE);
my_strdup2(_ALLOC_ID_, &raw->names[n], new_name);
int_hash_lookup(&raw->table, raw->names[n], n, XINSERT); /* update hash table */
ret = 1;
return ret;
}
int raw_deletevar(const char *name)
{
int ret = 0;
@ -1206,6 +1222,7 @@ int extra_rawfile(int what, const char *file, const char *type, double sweep1, d
if(what == 0) return 0;
/* if not already done insert base raw file (if there is one) into xctx->extra_raw_arr[0] */
if(xctx->raw && xctx->extra_raw_n == 0) {
dbg(1, "insert extra_raw_arr[0]\n");
xctx->extra_raw_arr[xctx->extra_raw_n] = xctx->raw;
xctx->extra_raw_n++;
}
@ -1277,7 +1294,8 @@ int extra_rawfile(int what, const char *file, const char *type, double sweep1, d
if(!no_warning) {
dbg(0, "extra_rawfile() read: %s not found or no \"%s\" analysis\n", f, type ? type : "<unspecified>");
}
if(xctx->extra_raw_n) { /* only restore if raw wiles were not deleted due to a failure in read_raw() */
if(xctx->extra_raw_n) { /* only restore if raw files were not deleted due to a failure in read_raw() */
dbg(1, "extra_rawfile(): read: restore previous, extra_idx=%d\n", xctx->extra_idx);
xctx->raw = save; /* restore */
xctx->extra_prev_idx = xctx->extra_idx;
}
@ -2783,7 +2801,8 @@ static void load_inst(int k, FILE *fd)
if(name[0] == '/') my_strdup2(_ALLOC_ID_, &xctx->inst[i].name, rel_sym_path(name));
else my_strdup2(_ALLOC_ID_, &xctx->inst[i].name, name);
#else
my_strdup2(_ALLOC_ID_, &xctx->inst[i].name, rel_sym_path(name));
if(isupper(name[0]) && name[1] == ':' && name[1] == '/') my_strdup2(_ALLOC_ID_, &xctx->inst[i].name, rel_sym_path(name));
else my_strdup2(_ALLOC_ID_, &xctx->inst[i].name, name);
#endif
my_free(_ALLOC_ID_, &tmp);
if(fscanf(fd, "%lf %lf %hd %hd", &xctx->inst[i].x0, &xctx->inst[i].y0,

View File

@ -1798,8 +1798,34 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
Tcl_SetResult(interp, (char *)get_cell_w_ext(argv[2], atoi(argv[3])), TCL_VOLATILE);
}
}
/************ end xschem get subcommands *************/
/* get_fqdevice instname param modelparam
* get the full pathname of "instname" device
* modelparam:
* 0: current, 1: modelparam, 2: modelvoltage
* param: device parameter, like ib, gm, vth
* set param to {} (empty str) for just branch current of 2 terminal device
* for parameters like "vth" modelparam must be 2
* for parameters like "ib" modelparam must be 0
* for parameters like "gm" modelparam must be 1
*/
else if(!strcmp(argv[1], "get_fqdevice"))
{
char *fqdev;
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
if(argc > 4) {
fqdev = get_fqdevice(argv[3], atoi(argv[4]), argv[2]);
Tcl_SetResult(interp, fqdev, TCL_VOLATILE);
my_free(_ALLOC_ID_, &fqdev);
} else if(argc > 2) {
fqdev = get_fqdevice("", 0, argv[2]);
Tcl_SetResult(interp, fqdev, TCL_VOLATILE);
my_free(_ALLOC_ID_, &fqdev);
}
}
/* getprop instance|instance_pin|symbol|text ref
*
* getprop instance inst
@ -2103,6 +2129,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
my_snprintf(res, S(res), "semaphore=%d\n", xctx->semaphore); Tcl_AppendResult(interp, res, NULL);
my_snprintf(res, S(res), "ui_state=%d\n", xctx->ui_state); Tcl_AppendResult(interp, res, NULL);
my_snprintf(res, S(res), "ui_state2=%d\n", xctx->ui_state2); Tcl_AppendResult(interp, res, NULL);
my_snprintf(res, S(res), "drag_elements=%d\n", xctx->drag_elements); Tcl_AppendResult(interp, res, NULL);
my_snprintf(res, S(res), "last_command=%d\n", xctx->last_command); Tcl_AppendResult(interp, res, NULL);
my_snprintf(res, S(res), "prep_net_structs=%d\n", xctx->prep_net_structs); Tcl_AppendResult(interp, res, NULL);
my_snprintf(res, S(res), "prep_hi_structs=%d\n", xctx->prep_hi_structs); Tcl_AppendResult(interp, res, NULL);
@ -2888,11 +2915,10 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
else if(!strcmp(argv[1], "load") )
{
int load_symbols = 1, force = 1, undo_reset = 1, nofullzoom = 0, nodraw = 0;
int keep_symbols = 0;
size_t i;
int keep_symbols = 0, first;
int i;
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
for(i = 2; i < argc; i++) {
if(argv[i][0] == '-') {
if(!strcmp(argv[i], "-nosymbols")) {
@ -2912,8 +2938,12 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
break;
}
}
if(argc>i) {
first = i;
if(argc==2) {
ask_new_file();
tcleval("load_additional_files");
} else
for(i = first; i < argc; i++) {
char f[PATH_MAX + 100];
my_snprintf(f, S(f),"regsub {^~/} {%s} {%s/}", argv[i], home_dir);
tcleval(f);
@ -2940,34 +2970,41 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
unselect_all(1);
/* no implicit undo: if needed do it before loading */
/* if(!undo_reset) xctx->push_undo(); */
if(undo_reset) xctx->currsch = 0;
if(!keep_symbols) remove_symbols();
if(!nofullzoom) {
xctx->zoom=CADINITIALZOOM;
xctx->mooz=1/CADINITIALZOOM;
xctx->xorigin=CADINITIALX;
xctx->yorigin=CADINITIALY;
if(i == first) {
if(undo_reset) xctx->currsch = 0;
if(!keep_symbols) remove_symbols();
if(!nofullzoom) {
xctx->zoom=CADINITIALZOOM;
xctx->mooz=1/CADINITIALZOOM;
xctx->xorigin=CADINITIALX;
xctx->yorigin=CADINITIALY;
}
}
dbg(1, "scheduler: undo_reset=%d\n", undo_reset);
ret = load_schematic(load_symbols, f, undo_reset, !force);
dbg(1, "xschem load: ret=%d\n", ret);
if(undo_reset) {
tclvareval("update_recent_file {", f, "}", NULL);
my_strdup(_ALLOC_ID_, &xctx->sch_path[xctx->currsch], ".");
if(xctx->portmap[xctx->currsch].table) str_hash_free(&xctx->portmap[xctx->currsch]);
str_hash_init(&xctx->portmap[xctx->currsch], HASHSIZE);
xctx->sch_path_hash[xctx->currsch] = 0;
xctx->sch_inst_number[xctx->currsch] = 1;
if(i > first) {
ret = new_schematic("create", "noconfirm", f, 1);
if(undo_reset) {
tclvareval("update_recent_file {", f, "}", NULL);
}
} else {
ret = load_schematic(load_symbols, f, undo_reset, !force);
dbg(1, "xschem load: f=%s, ret=%d\n", f, ret);
if(undo_reset) {
tclvareval("update_recent_file {", f, "}", NULL);
my_strdup(_ALLOC_ID_, &xctx->sch_path[xctx->currsch], ".");
if(xctx->portmap[xctx->currsch].table) str_hash_free(&xctx->portmap[xctx->currsch]);
str_hash_init(&xctx->portmap[xctx->currsch], HASHSIZE);
xctx->sch_path_hash[xctx->currsch] = 0;
xctx->sch_inst_number[xctx->currsch] = 1;
}
if(nofullzoom) {
if(!nodraw) draw();
} else zoom_full(1, 0, 1 + 2 * tclgetboolvar("zoom_full_center"), 0.97);
}
if(nofullzoom) {
if(!nodraw) draw();
} else zoom_full(1, 0, 1 + 2 * tclgetboolvar("zoom_full_center"), 0.97);
}
}
}
else if(argc==2) {
ask_new_file();
}
Tcl_SetResult(interp, xctx->sch[xctx->currsch], TCL_STATIC);
}
@ -2980,13 +3017,32 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
int cancel = 0;
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
if(argc > 2) {
if(!is_from_web(argv[2])) {
my_snprintf(f, S(f),"regsub {^~/} {%s} {%s/}", argv[2], home_dir);
tcleval(f);
/* tclvareval("file normalize {", tclresult(), "}", NULL); */
my_strncpy(f, abs_sym_path(tclresult(), ""), S(f));
} else {
my_strncpy(f, argv[2], S(f));
int i;
for(i = 2; i < argc; i++) {
if(!is_from_web(argv[i])) {
my_snprintf(f, S(f),"regsub {^~/} {%s} {%s/}", argv[i], home_dir);
tcleval(f);
/* tclvareval("file normalize {", tclresult(), "}", NULL); */
my_strncpy(f, abs_sym_path(tclresult(), ""), S(f));
} else {
my_strncpy(f, argv[i], S(f));
}
if(f[0]) {
char win_path[WINDOW_PATH_SIZE];
dbg(1, "f=%s\n", f);
if(check_loaded(f, win_path)) {
char msg[PATH_MAX + 100];
my_snprintf(msg, S(msg),
"tk_messageBox -type okcancel -icon warning -parent [xschem get topwindow] "
"-message {Warning: %s already open.}", f);
tcleval(msg);
if(strcmp(tclresult(), "ok")) continue;
}
new_schematic("create", "noconfirm", f, 1);
tclvareval("update_recent_file {", f, "}", NULL);
} else {
new_schematic("create", NULL, NULL, 1);
}
}
} else {
tcleval("load_file_dialog {Load file} *.\\{sch,sym,tcl\\} INITIALLOADDIR");
@ -2995,14 +3051,14 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
} else {
cancel = 1;
}
}
if(!cancel) {
if(f[0]) {
dbg(1, "f=%s\n", f);
new_schematic("create", "noconfirm", f, 1);
tclvareval("update_recent_file {", f, "}", NULL);
} else {
new_schematic("create", NULL, NULL, 1);
if(!cancel) {
if(f[0]) {
dbg(1, "f=%s\n", f);
new_schematic("create", "noconfirm", f, 1);
tclvareval("update_recent_file {", f, "}", NULL);
} else {
new_schematic("create", NULL, NULL, 1);
}
}
}
Tcl_ResetResult(interp);
@ -3604,7 +3660,6 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
tclvareval("set INITIALINSTDIR [file dirname {",
abs_sym_path(tcl_hook2(xctx->inst[xctx->sel_array[0].n].name), ""), "}]", NULL);
}
unselect_all(1);
xctx->mx_double_save = xctx->mousex_snap;
xctx->my_double_save = xctx->mousey_snap;
if(argc > 3) {
@ -3969,8 +4024,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
case 'r': /*----------------------------------------------*/
/* raw what ...
* what = add | clear | datasets | index | info | loaded | list | new | points | rawfile | del |
* read | set | sim_type | switch | switch_back | table_read | value | values | pos_at | vars |
* what = add | clear | datasets | index | info | loaded | list |
* new | points | rawfile | del | read | set | rename |
* sim_type | switch | switch_back | table_read | value | values | pos_at | vars |
*
* xschem raw read filename [type [sweep1 sweep2]]
* if sweep1, sweep2 interval is given in 'read' subcommand load only the interval
@ -3985,6 +4041,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
* xschem raw del name
* delete named vector from current raw file
*
* xschem raw rename old_name new_name
* rename a node in the loaded raw file.
*
* xschem raw info
* print information about loaded raw files and show the currently active one.
*
@ -4061,7 +4120,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
* new dataset do not start with a header row.
* Lines beginning with '#' are comments and ignored
*
* time var_a var_b var_c
* time var_a var_b var_cnode in the loaded raw file.
* # this is a comment, ignored
* 0.0 0.0 1.8 0.3
* <single empty line: ignored>
@ -4129,9 +4188,6 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
update_op();
}
Tcl_SetResult(interp, my_itoa(ret), TCL_VOLATILE);
} else if(argc > 3 && !strcmp(argv[2], "del")) {
ret = raw_deletevar(argv[3]);
Tcl_SetResult(interp, my_itoa(ret), TCL_VOLATILE);
} else if(argc > 2 && !strcmp(argv[2], "clear")) {
if(argc > 4) {
ret = extra_rawfile(3, argv[3], argv[4], -1.0, -1.0);
@ -4164,6 +4220,12 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
Tcl_SetResult(interp, dtoa(val), TCL_VOLATILE);
}
}
} else if(argc > 3 && !strcmp(argv[2], "del")) {
ret = raw_deletevar(argv[3]);
Tcl_SetResult(interp, my_itoa(ret), TCL_VOLATILE);
} else if(argc > 4 && !strcmp(argv[2], "rename")) {
ret = raw_renamevar(argv[3], argv[4]);
Tcl_SetResult(interp, my_itoa(ret), TCL_VOLATILE);
} else if(argc > 3 && !strcmp(argv[2], "index")) {
/* xschem raw index v(ldcp) */
int idx;
@ -4960,7 +5022,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
int n=atoi(argv[3]);
int valid = n < xctx->wires && n >= 0;
if(valid) {
select_wire(n, sel, fast);
select_wire(n, sel, fast, 1);
xctx->ui_state |= SELECTION;
}
Tcl_SetResult(interp, valid ? "1" : "0" , TCL_STATIC);
@ -4970,7 +5032,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
int n=atoi(argv[4]);
int valid = n < xctx->lines[c] && n >= 0 && c < cadlayers && c >= 0;
if(valid) {
select_line(c, n, sel, fast);
select_line(c, n, sel, fast, 0);
xctx->ui_state |= SELECTION;
}
Tcl_SetResult(interp, valid ? "1" : "0" , TCL_STATIC);
@ -4990,7 +5052,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
int n=atoi(argv[4]);
int valid = n < xctx->arcs[c] && n >= 0 && c < cadlayers && c >= 0;
if(valid) {
select_arc(c, n, sel, fast);
select_arc(c, n, sel, fast, 0);
xctx->ui_state |= SELECTION;
}
Tcl_SetResult(interp, valid ? "1" : "0" , TCL_STATIC);
@ -5000,7 +5062,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
int n=atoi(argv[4]);
int valid = n < xctx->polygons[c] && n >= 0 && c < cadlayers && c >= 0;
if(valid) {
select_polygon(c, n, sel, fast);
select_polygon(c, n, sel, fast, 0);
xctx->ui_state |= SELECTION;
}
Tcl_SetResult(interp, valid ? "1" : "0" , TCL_STATIC);
@ -5009,7 +5071,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
int n=atoi(argv[3]);
int valid = n < xctx->texts && n >= 0;
if(valid) {
select_text(n, sel, fast);
select_text(n, sel, fast, 0);
xctx->ui_state |= SELECTION;
}
Tcl_SetResult(interp, valid ? "1" : "0" , TCL_STATIC);
@ -5461,7 +5523,8 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
} else {
char *translated_sym = NULL;
int sym_number = -1;
char *subst = NULL;
char *subst = NULL, *old_name = NULL;;
if(!fast) {
symbol_bbox(inst, &xctx->inst[inst].x1, &xctx->inst[inst].y1, &xctx->inst[inst].x2, &xctx->inst[inst].y2);
xctx->push_undo();
@ -5469,7 +5532,12 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
xctx->prep_hash_inst=0;
xctx->prep_net_structs=0;
xctx->prep_hi_structs=0;
if(argc > 4 && !strcmp(argv[4], "name") && fast == 0) hash_names(-1, XINSERT);
if(argc > 4 && !strcmp(argv[4], "name")) {
if(fast == 0) {
hash_names(-1, XINSERT);
}
my_strdup2(_ALLOC_ID_, &old_name, xctx->inst[inst].instname);
}
if(argc > 5) {
if(!strcmp(argv[4], "allprops")) {
hash_names(-1, XINSERT);
@ -5486,7 +5554,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
}
hash_names(inst, XDELETE);
new_prop_string(inst, subst, tclgetboolvar("disable_unique_names"));
if(old_name) {
update_attached_floaters(old_name, inst, 0);
}
my_strdup2(_ALLOC_ID_, &translated_sym, translate(inst, xctx->inst[inst].name));
sym_number=match_symbol(translated_sym);
@ -5495,6 +5565,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
xctx->inst[inst].ptr=sym_number;
}
if(subst) my_free(_ALLOC_ID_, &subst);
if(old_name) my_free(_ALLOC_ID_, &old_name);
set_inst_flags(&xctx->inst[inst]);
hash_names(inst, XINSERT);
if(!fast) {
@ -5927,22 +5998,22 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
select_element(n, SELECTED, 1, 1);
break;
case WIRE:
select_wire(n, SELECTED, 1);
select_wire(n, SELECTED, 1, 1);
break;
case xTEXT:
select_text(n, SELECTED, 1);
select_text(n, SELECTED, 1, 1);
break;
case xRECT:
select_box(c, n, SELECTED, 1, 0);
select_box(c, n, SELECTED, 1, 1);
break;
case LINE:
select_line(c, n, SELECTED, 1);
select_line(c, n, SELECTED, 1, 1);
break;
case POLYGON:
select_polygon(c, n, SELECTED, 1);
select_polygon(c, n, SELECTED, 1, 1);
break;
case ARC:
select_arc(c, n, SELECTED, 1);
select_arc(c, n, SELECTED, 1, 1);
break;
}
}
@ -6215,6 +6286,14 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
Tcl_ResetResult(interp);
}
/* unselect_attached_floaters
* Unselect objects (not symbol instances) attached to some instance with a
* non empty name=... attribute */
else if(!strcmp(argv[1], "unselect_attached_floaters"))
{
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
unselect_attached_floaters();
}
/* update_all_sym_bboxes
* Update all symbol bounding boxes */
else if(!strcmp(argv[1], "update_all_sym_bboxes"))

View File

@ -735,7 +735,7 @@ void bbox(int what,double x1,double y1, double x2, double y2)
/* n = -1 : clear first selected info
* n = -2 : return first selected element if still selected, or get first from
* selected list. Id no elements selected return first selected item (j = 0)
* selected list. If no elements selected return first selected item (j = 0)
* n >= 0 : store indicated element as first selected
*/
int set_first_sel(unsigned short type, int n, unsigned int col)
@ -896,10 +896,12 @@ void unselect_all(int dr)
}
}
void select_wire(int i,unsigned short select_mode, int fast)
void select_wire(int i,unsigned short select_mode, int fast, int override_lock)
{
char str[1024]; /* overflow safe */
/*my_strncpy(s,xctx->wire[i].prop_ptr!=NULL?xctx->wire[i].prop_ptr:"<NULL>",256); */
if(!strboolcmp(get_tok_value(xctx->wire[i].prop_ptr, "lock", 0), "true") &&
select_mode == SELECTED && !override_lock) return;
if( !fast )
{
my_snprintf(str, S(str), "Info: selected wire: n=%d end1=%d end2=%d\nnode=%s",i,
@ -937,6 +939,68 @@ void select_wire(int i,unsigned short select_mode, int fast)
xctx->need_reb_sel_arr=1;
}
static int select_attached_floaters(int inst, const char *name)
{
int i, c;
int found = 0;
char *attach = NULL;
char *att_save, *att_ptr;
if(!name || !name[0]) return found;
my_strdup2(_ALLOC_ID_, &attach, name);
att_ptr = attach;
while( (name = my_strtok_r(att_ptr, " \n", "\"", 0, &att_save)) ) {
att_ptr = NULL;
for(c = 0; c < cadlayers; c++) {
for(i = 0; i < xctx->rects[c]; i++) {
if(!strcmp(name, get_tok_value(xctx->rect[c][i].prop_ptr, "name", 0))) {
found = 1;
select_box(c, i, SELECTED, 1, 1);
}
}
for(i = 0; i < xctx->lines[c]; i++) {
if(!strcmp(name, get_tok_value(xctx->line[c][i].prop_ptr, "name", 0))) {
found = 1;
select_line(c, i, SELECTED, 1, 1);
}
}
for(i = 0; i < xctx->polygons[c]; i++) {
if(!strcmp(name, get_tok_value(xctx->poly[c][i].prop_ptr, "name", 0))) {
found = 1;
select_polygon(c, i, SELECTED, 1, 1);
}
}
for(i = 0; i < xctx->arcs[c]; i++) {
if(!strcmp(name, get_tok_value(xctx->arc[c][i].prop_ptr, "name", 0))) {
found = 1;
select_arc(c, i, SELECTED, 1, 1);
}
}
}
for(i = 0; i < xctx->wires; i++) {
if(!strcmp(name, get_tok_value(xctx->wire[i].prop_ptr, "name", 0))) {
found = 1;
select_wire(i, SELECTED, 1, 1);
}
}
for(i = 0; i < xctx->texts; i++) {
if(!strcmp(name, get_tok_value(xctx->text[i].prop_ptr, "name", 0))) {
found = 1;
select_text(i, SELECTED, 1, 1);
}
}
for(i = 0; i < xctx->instances; i++) {
if(i != inst && !strcmp(name, xctx->inst[i].instname)) {
found = 1;
select_element(i, SELECTED, 1, 0);
}
}
}
my_free(_ALLOC_ID_, &attach);
return found;
}
/* fast == 1: do not update status line
* fast == 2: do not draw / undraw selected elements
* fast == 3: 1 + 2
@ -991,16 +1055,21 @@ void select_element(int i,unsigned short select_mode, int fast, int override_loc
}
}
}
if(!fast && select_mode == SELECTED) {
select_attached_floaters(i, get_tok_value(xctx->inst[i].prop_ptr, "attach", 0));
}
xctx->need_reb_sel_arr=1;
}
void select_text(int i,unsigned short select_mode, int fast)
void select_text(int i, unsigned short select_mode, int fast, int override_lock)
{
char str[1024]; /* overflow safe */
char s[256]; /* overflow safe */
#if HAS_CAIRO==1
int customfont;
#endif
if(!strboolcmp(get_tok_value(xctx->text[i].prop_ptr, "lock", 0), "true") &&
select_mode == SELECTED && !override_lock) return;
if(!fast) {
my_strncpy(s,xctx->text[i].prop_ptr!=NULL?xctx->text[i].prop_ptr:"<NULL>",S(s));
my_snprintf(str, S(str), "Info: selected text %d: properties: %s", i,s);
@ -1075,7 +1144,7 @@ void select_box(int c, int i, unsigned short select_mode, int fast, int override
void select_arc(int c, int i, unsigned short select_mode, int fast)
void select_arc(int c, int i, unsigned short select_mode, int fast, int override_lock)
{
char str[1024]; /* overflow safe */
char s[256]; /* overflow safe */
@ -1105,11 +1174,14 @@ void select_arc(int c, int i, unsigned short select_mode, int fast)
xctx->need_reb_sel_arr=1;
}
void select_polygon(int c, int i, unsigned short select_mode, int fast )
void select_polygon(int c, int i, unsigned short select_mode, int fast, int override_lock )
{
char str[1024]; /* overflow safe */
char s[256]; /* overflow safe */
int bezier;
if(!strboolcmp(get_tok_value(xctx->poly[c][i].prop_ptr, "lock", 0), "true") &&
select_mode == SELECTED && !override_lock) return;
if(!fast)
{
my_strncpy(s,xctx->poly[c][i].prop_ptr!=NULL?xctx->poly[c][i].prop_ptr:"<NULL>",S(s));
@ -1134,10 +1206,13 @@ void select_polygon(int c, int i, unsigned short select_mode, int fast )
xctx->need_reb_sel_arr=1;
}
void select_line(int c, int i, unsigned short select_mode, int fast )
void select_line(int c, int i, unsigned short select_mode, int fast, int override_lock )
{
char str[1024]; /* overflow safe */
char s[256]; /* overflow safe */
if(!strboolcmp(get_tok_value(xctx->line[c][i].prop_ptr, "lock", 0), "true") &&
select_mode == SELECTED && !override_lock) return;
if(!fast)
{
my_strncpy(s,xctx->line[c][i].prop_ptr!=NULL?xctx->line[c][i].prop_ptr:"<NULL>",S(s));
@ -1193,19 +1268,19 @@ Selected select_object(double mx,double my, unsigned short select_mode,
{
case WIRE:
if(xctx->wire[sel.n].sel) xctx->already_selected = 1;
select_wire(sel.n, select_mode, 0);
select_wire(sel.n, select_mode, 0, override_lock);
break;
case xTEXT:
if(xctx->text[sel.n].sel) xctx->already_selected = 1;
select_text(sel.n, select_mode, 0);
select_text(sel.n, select_mode, 0, override_lock);
break;
case LINE:
if(xctx->line[sel.col][sel.n].sel) xctx->already_selected = 1;
select_line(sel.col, sel.n, select_mode,0);
select_line(sel.col, sel.n, select_mode,0, override_lock);
break;
case POLYGON:
if(xctx->poly[sel.col][sel.n].sel) xctx->already_selected = 1;
select_polygon(sel.col, sel.n, select_mode,0);
select_polygon(sel.col, sel.n, select_mode,0, override_lock);
break;
case xRECT:
if(xctx->rect[sel.col][sel.n].sel) xctx->already_selected = 1;
@ -1213,11 +1288,11 @@ Selected select_object(double mx,double my, unsigned short select_mode,
break;
case ARC:
if(xctx->arc[sel.col][sel.n].sel) xctx->already_selected = 1;
select_arc(sel.col,sel.n, select_mode,0);
select_arc(sel.col,sel.n, select_mode,0, override_lock);
break;
case ELEMENT:
if(xctx->inst[sel.n].sel) xctx->already_selected = 1;
select_element(sel.n,select_mode,0, override_lock);
select_element(sel.n, select_mode,0, override_lock);
break;
default:
break;
@ -1260,10 +1335,10 @@ void select_attached_nets(void)
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);
select_wire(i,SELECTED1, 1, 0);
}
if(xctx->wire[i].x2 == x0 && xctx->wire[i].y2 == y0) {
select_wire(i,SELECTED2, 1);
select_wire(i,SELECTED2, 1, 0);
}
}
}
@ -1286,10 +1361,10 @@ void select_attached_nets(void)
i = wptr->n;
if(i == wire) continue;
if(xctx->wire[i].x1 == x0 && xctx->wire[i].y1 == y0) {
select_wire(i,SELECTED1, 1);
select_wire(i,SELECTED1, 1, 0);
}
if(xctx->wire[i].x2 == x0 && xctx->wire[i].y2 == y0) {
select_wire(i,SELECTED2, 1);
select_wire(i,SELECTED2, 1, 0);
}
}
}
@ -1316,23 +1391,23 @@ void select_inside(int stretch, double x1,double y1, double x2, double y2, int s
if(RECT_INSIDE(xctx->wire[i].x1,xctx->wire[i].y1,xctx->wire[i].x2,xctx->wire[i].y2, x1,y1,x2,y2))
{
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
select_wire(i, SELECTED, 1);
select_wire(i, SELECTED, 1, 0);
}
else if(stretch && POINTINSIDE(xctx->wire[i].x1,xctx->wire[i].y1, x1,y1,x2,y2) )
{
xctx->ui_state |= SELECTION;
select_wire(i, SELECTED1, 1);
select_wire(i, SELECTED1, 1, 0);
}
else if(stretch && POINTINSIDE(xctx->wire[i].x2,xctx->wire[i].y2, x1,y1,x2,y2) )
{
xctx->ui_state |= SELECTION;
select_wire(i, SELECTED2, 1);
select_wire(i, SELECTED2, 1, 0);
}
} else {
if(RECT_INSIDE(xctx->wire[i].x1,xctx->wire[i].y1,xctx->wire[i].x2,xctx->wire[i].y2, x1,y1,x2,y2))
{
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
select_wire(i, 0, 1);
select_wire(i, 0, 1, 0);
}
}
}
@ -1358,7 +1433,7 @@ void select_inside(int stretch, double x1,double y1, double x2, double y2, int s
if(RECT_INSIDE(xx1,yy1, xx2, yy2,x1,y1,x2,y2))
{
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
sel ? select_text(i, SELECTED, 1): select_text(i, 0, 1);
sel ? select_text(i, SELECTED, 1, 0): select_text(i, 0, 1, 0);
}
}
for(i=0;i<xctx->instances; ++i)
@ -1367,9 +1442,7 @@ void select_inside(int stretch, double x1,double y1, double x2, double y2, int s
{
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
if(sel) {
if(strboolcmp(get_tok_value(xctx->inst[i].prop_ptr, "lock", 0), "true")) {
select_element(i, SELECTED, 1, 1);
}
select_element(i, SELECTED, 1, 0);
} else {
select_element(i, 0, 1, 0);
}
@ -1403,14 +1476,14 @@ void select_inside(int stretch, double x1,double y1, double x2, double y2, int s
}
if(flag) {
if(selected_points==0) {
select_polygon(c, i, 0, 1);
select_polygon(c, i, 0, 1, 0);
}
if(selected_points==xctx->poly[c][i].points) {
xctx->ui_state |= SELECTION;
select_polygon(c, i, SELECTED, 1);
select_polygon(c, i, SELECTED, 1, 0);
} else if(selected_points) {
/* for polygon, SELECTED1 means partial sel */
if(sel && stretch) select_polygon(c, i, SELECTED1,1);
if(sel && stretch) select_polygon(c, i, SELECTED1, 1, 0);
}
}
@ -1421,23 +1494,23 @@ void select_inside(int stretch, double x1,double y1, double x2, double y2, int s
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;
select_line(c,i,SELECTED,1);
select_line(c, i, SELECTED, 1, 0);
}
else if(stretch && 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);
select_line(c, i, SELECTED1, 1, 0);
}
else if(stretch && 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);
select_line(c, i, SELECTED2, 1, 0);
}
} else {
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;
select_line(c,i,0,1);
select_line(c, i, 0, 1, 0);
}
}
}
@ -1454,22 +1527,22 @@ void select_inside(int stretch, double x1,double y1, double x2, double y2, int s
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);
sel? select_arc(c, i, SELECTED,1, 0): select_arc(c, i, 0,1, 0);
}
else if( sel && stretch && 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);
select_arc(c, i,SELECTED1,1, 0);
}
else if( sel && stretch && 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);
select_arc(c, i,SELECTED3,1, 0);
}
else if( sel && stretch && 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);
select_arc(c, i,SELECTED2,1, 0);
}
}
for(i=0;i<xctx->rects[c]; ++i)
@ -1480,9 +1553,7 @@ void select_inside(int stretch, double x1,double y1, double x2, double y2, int s
if(sel) {
if(strboolcmp(get_tok_value(xctx->rect[c][i].prop_ptr, "lock", 0), "true")) {
select_box(c,i, SELECTED, 1, 1);
}
select_box(c,i, SELECTED, 1, 0);
} else {
select_box(c,i, 0, 1, 0);
}
@ -1544,7 +1615,7 @@ void select_touch(double x1,double y1, double x2, double y2, int sel) /*added un
ly2 = xctx->wire[i].y2;
if(lineclip(&lx1, &ly1, &lx2, &ly2, x1,y1,x2,y2)) {
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
sel ? select_wire(i,SELECTED, 1): select_wire(i,0, 1);
sel ? select_wire(i,SELECTED, 1, 0): select_wire(i,0, 1, 0);
}
}
for(i=0;i<xctx->texts; ++i)
@ -1570,7 +1641,7 @@ void select_touch(double x1,double y1, double x2, double y2, int sel) /*added un
if(RECT_TOUCH(xx1, yy1, xx2, yy2,x1,y1,x2,y2))
{
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
sel ? select_text(i, SELECTED, 1): select_text(i, 0, 1);
sel ? select_text(i, SELECTED, 1, 0): select_text(i, 0, 1, 0);
}
}
for(i=0;i<xctx->instances; ++i)
@ -1579,9 +1650,7 @@ void select_touch(double x1,double y1, double x2, double y2, int sel) /*added un
{
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
if(sel) {
if(strboolcmp(get_tok_value(xctx->inst[i].prop_ptr, "lock", 0), "true")) {
select_element(i, SELECTED, 1, 1);
}
select_element(i, SELECTED, 1, 0);
} else {
select_element(i, 0, 1, 0);
}
@ -1605,7 +1674,7 @@ void select_touch(double x1,double y1, double x2, double y2, int sel) /*added un
}
}
if(flag) {
sel ? select_polygon(c, i, SELECTED, 1): select_polygon(c, i, 0, 1);
sel ? select_polygon(c, i, SELECTED, 1, 0): select_polygon(c, i, 0, 1, 0);
}
}
for(i=0;i<xctx->lines[c]; ++i)
@ -1617,7 +1686,7 @@ void select_touch(double x1,double y1, double x2, double y2, int sel) /*added un
ly2 = xctx->line[c][i].y2;
if(lineclip(&lx1, &ly1, &lx2, &ly2, x1,y1,x2,y2)) {
xctx->ui_state |= SELECTION;
sel? select_line(c,i,SELECTED,1): select_line(c,i,0,1);
sel? select_line(c, i, SELECTED, 1, 0): select_line(c, i, 0, 1, 0);
}
}
for(i=0;i<xctx->arcs[c]; ++i) {
@ -1633,7 +1702,7 @@ void select_touch(double x1,double y1, double x2, double y2, int sel) /*added un
arc_bbox(x, y, r, a, b, &tmp.x1, &tmp.y1, &tmp.x2, &tmp.y2);
if(RECT_TOUCH(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);
sel? select_arc(c, i, SELECTED,1, 0): select_arc(c, i, 0,1, 0);
}
}
for(i=0;i<xctx->rects[c]; ++i)
@ -1642,9 +1711,7 @@ void select_touch(double x1,double y1, double x2, double y2, int sel) /*added un
{
xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
if(sel) {
if(strboolcmp(get_tok_value(xctx->rect[c][i].prop_ptr, "lock", 0), "true")) {
select_box(c,i, SELECTED, 1, 1);
}
select_box(c,i, SELECTED, 1, 0);
} else {
select_box(c,i, 0, 1, 0);
}
@ -1688,6 +1755,8 @@ int floaters_from_selected_inst()
}
my_strdup2(_ALLOC_ID_, &xctx->inst[i].prop_ptr,
subst_token(xctx->inst[i].prop_ptr, "hide_texts", "true"));
my_strdup2(_ALLOC_ID_, &xctx->inst[i].prop_ptr,
subst_token(xctx->inst[i].prop_ptr, "attach", xctx->inst[i].instname));
set_inst_flags(&xctx->inst[i]);
for(t = 0; t < sym->texts; t++) {
double txtx0, txty0;
@ -1730,33 +1799,35 @@ void select_all(void)
for(i=0;i<xctx->wires; ++i)
{
select_wire(i,SELECTED, 1);
select_wire(i,SELECTED, 1, 0);
}
for(i=0;i<xctx->texts; ++i)
{
select_text(i, SELECTED, 1);
select_text(i, SELECTED, 1, 0);
}
for(i=0;i<xctx->instances; ++i)
{
select_element(i,SELECTED,1, 0);
select_element(i, SELECTED, 1, 0);
/* following not done in select_element() due to fast=1 argument */
select_attached_floaters(i, get_tok_value(xctx->inst[i].prop_ptr, "attach", 0));
}
for(c=0;c<cadlayers; ++c)
{
for(i=0;i<xctx->polygons[c]; ++i)
{
select_polygon(c,i,SELECTED,1);
select_polygon(c, i, SELECTED, 1, 0);
}
for(i=0;i<xctx->lines[c]; ++i)
{
select_line(c,i,SELECTED,1);
select_line(c, i, SELECTED, 1, 0);
}
for(i=0;i<xctx->arcs[c]; ++i)
{
select_arc(c,i, SELECTED, 1);
select_arc(c, i, SELECTED, 1, 0);
}
for(i=0;i<xctx->rects[c]; ++i)
{
select_box(c,i, SELECTED, 1, 0);
select_box(c, i, SELECTED, 1, 0);
}
} /* end for c */
drawtemparc(xctx->gc[SELLAYER], END, 0.0, 0.0, 0.0, 0.0, 0.0);

View File

@ -1035,7 +1035,7 @@ void svg_draw(void)
{
if(xctx->rect[c][i].flags & 1) { /* graph */
xRect *r = &xctx->rect[c][i];
svg_embedded_graph(fd, r, r->x1, r->y1, r->x2, r->y2);
svg_embedded_graph(fd, i, r->x1, r->y1, r->x2, r->y2);
}
}
}

View File

@ -184,6 +184,7 @@ int match_symbol(const char *name) /* never returns -1, if symbol not found loa
int i,found;
found=0;
dbg(1, "match_symbol(): name=%s\n", name);
for(i=0;i<xctx->symbols; ++i) {
/* dbg(1, "match_symbol(): name=%s, sym[i].name=%s\n",name, xctx->sym[i].name);*/
if(xctx->x_strcmp(name, xctx->sym[i].name) == 0)
@ -1198,8 +1199,8 @@ static void print_vhdl_primitive(FILE *fd, int inst) /* netlist primitives, 200
}
}
my_strdup2(_ALLOC_ID_, &result, tcl_hook2(result)); /* tcl evaluation if tcleval(....) */
if(strstr(result, "expr(") ) {
result = eval_expr(result);
if(strstr(result, "expr(")) {
my_strdup2(_ALLOC_ID_, &result, eval_expr(result));
}
dbg(1, "print_vhdl_primitive(): after translate3() result=%s\n", result);
}
@ -2152,7 +2153,8 @@ int print_spice_element(FILE *fd, int inst)
const char *str_ptr=NULL;
register int c, state=TOK_BEGIN, space;
char *template=NULL,*format=NULL, *s, *name=NULL, *token=NULL;
const char *lab, *value = NULL;
const char *lab;
const char *value = NULL;
/* char *translatedvalue = NULL; */
size_t sizetok=0;
size_t token_pos=0;
@ -2462,8 +2464,8 @@ int print_spice_element(FILE *fd, int inst)
value = spiceprefixtag;
}
if(strstr(value, "expr(") ) {
value = eval_expr(value);
if(strstr(value, "expr(")) {
value = eval_expr(value);
}
/* token=%xxxx and xxxx is not defined in prop_ptr or template: return xxxx */
if(!token_exists && token[0] =='%') {
@ -2517,8 +2519,8 @@ int print_spice_element(FILE *fd, int inst)
if(result) {
my_strdup(_ALLOC_ID_, &result, tcl_hook2(result));
}
if(strstr(result, "expr(") ) {
result = eval_expr(result);
if(strstr(result, "expr(")) {
my_strdup2(_ALLOC_ID_, &result, eval_expr(result));
}
if(result) fprintf(fd, "%s", result);
dbg(1, "print_spice_element(): returning |%s|\n", result);
@ -3154,8 +3156,8 @@ static void print_verilog_primitive(FILE *fd, int inst) /* netlist switch level
}
}
my_strdup2(_ALLOC_ID_, &result, tcl_hook2(result)); /* tcl evaluation if tcleval(....) */
if(strstr(result, "expr(") ) {
result = eval_expr(result);
if(strstr(result, "expr(")) {
my_strdup2(_ALLOC_ID_, &result, eval_expr(result));
}
dbg(1, "print_verilog_primitive(): after translate3() result=%s\n", result);
}
@ -3779,6 +3781,99 @@ const char *spice_get_node(const char *token)
}
/* caller must free returned value
* get the full pathname of "instname" device
* modelparam:
* 0: current, 1: modelparam, 2: modelvoltage
* param: device parameter, like "ib", "gm", "vth"
* set param to {} (empty str) for just branch current of 2 terminal device
* for parameters like "vth" modelparam must be 2
* for parameters like "ib" modelparam must be 0
* for parameters like "gm" modelparam must be 1
*/
char *get_fqdevice(const char *param, int modelparam, const char *instname)
{
int start_level; /* hierarchy level where waves were loaded */
char *fqdev = NULL;
const char *path = xctx->sch_path[xctx->currsch] + 1;
char *dev = NULL;
size_t len;
int idx;
int sim_is_xyce = tcleval("sim_is_xyce")[0] == '1' ? 1 : 0;
int skip = 0;
char *iprefix = modelparam == 0 ? "i(" : modelparam == 1 ? "" : "v(";
char *ipostfix = modelparam == 1 ? "" : ")";
int prefix;
start_level = sch_waves_loaded();
/* skip path components that are above the level where raw file was loaded */
while(*path && skip < start_level) {
if(*path == '.') skip++;
++path;
}
my_strdup2(_ALLOC_ID_, &dev, instname);
strtolower(dev);
prefix=dev[0];
len = strlen(path) + strlen(dev) + 40; /* some extra chars for i(..) wrapper */
fqdev = my_malloc(_ALLOC_ID_, len);
if(!sim_is_xyce) {
int vsource = (prefix == 'v') || (prefix == 'e');
if(path[0]) {
if(vsource) {
my_snprintf(fqdev, len, "i(%c.%s%s)", prefix, path, dev);
} else if(prefix=='q') {
my_snprintf(fqdev, len, "%s@%c.%s%s[%s]%s",
iprefix, prefix, path, dev, param ? param : "ic", ipostfix);
} else if(prefix=='d' || prefix == 'm') {
my_snprintf(fqdev, len, "%s@%c.%s%s[%s]%s",
iprefix, prefix, path, dev, param ? param : "id", ipostfix);
} else if(prefix=='i') {
my_snprintf(fqdev, len, "i(@%c.%s%s[current])", prefix, path, dev);
} else {
my_snprintf(fqdev, len, "i(@%c.%s%s[i])", prefix, path, dev);
}
} else {
if(vsource) {
my_snprintf(fqdev, len, "i(%s)", dev);
} else if(prefix == 'q') {
my_snprintf(fqdev, len, "%s@%s[%s]%s", iprefix, dev, param ? param : "ic", ipostfix);
} else if(prefix == 'd' || prefix == 'm') {
my_snprintf(fqdev, len, "%s@%s[%s]%s", iprefix, dev, param ? param : "id", ipostfix);
} else if(prefix == 'i') {
my_snprintf(fqdev, len, "i(@%s[current])", dev);
} else {
my_snprintf(fqdev, len, "i(@%s[i])", dev);
}
}
} else {
my_snprintf(fqdev, len, "i(%s%s)", path, dev);
}
dbg(1, "fqdev=%s\n", fqdev);
strtolower(fqdev);
idx = get_raw_index(fqdev, NULL);
/* special handling for resistors that are converted to b sources:
* i(@r.x4.r1[i]) --> i(@b.x4.br1[i])
*/
if(idx < 0 && !strncmp(fqdev, "i(@r", 4)) {
if(path[0]) {
my_snprintf(fqdev, len, "i(@b.%sb%s[i])", path, dev);
} else {
my_snprintf(fqdev, len, "i(@b%s[i])", dev);
}
dbg(1, "fqdev=%s\n", fqdev);
}
my_free(_ALLOC_ID_, &dev);
return fqdev;
}
/* substitute given tokens in a string with their corresponding values */
/* ex.: name=@name w=@w l=@l ---> name=m112 w=3e-6 l=0.8e-6 */
/* if s==NULL return emty string */

View File

@ -2060,6 +2060,7 @@ void change_linewidth(double w)
double cs = tclgetdoublevar("cadsnap");
if(tclgetboolvar("change_lw")) {
xctx->lw=xctx->mooz * 0.09 * cs;
if(xctx->lw > 100.) xctx->lw = 100.;
xctx->cadhalfdotsize = CADHALFDOTSIZE * (cs < 20. ? cs : 20.) / 10.;
}
/* explicitly set line width */

View File

@ -163,8 +163,8 @@ extern char win_temp_dir[PATH_MAX];
#define CADINITIALY -870
#define CADZOOMSTEP 1.2
#define CADMOVESTEP 200
#define CADMAXZOOM 1000000.0
#define CADMINZOOM 0.000001
#define CADMAXZOOM 10000.0
#define CADMINZOOM 0.005
#define CADHALFDOTSIZE 3.7
#define CADNULLNODE -1 /* no valid node number */
#define CADWIREMINDIST 8.0
@ -375,7 +375,7 @@ extern char win_temp_dir[PATH_MAX];
* show_label also used on metal option type symbols (pass-through symbols)
* to optionally short two nets (using *_ignore=[true|false] attribute) */
#define IS_LABEL_SH_OR_PIN(type) (!(strcmp(type,"label") && strcmp(type,"ipin") && strcmp(type,"opin") && \
strcmp(type,"show_label") && strcmp(type,"iopin") && strcmp(type,"bus_tap")))
strcmp(type,"scope") && strcmp(type,"show_label") && strcmp(type,"iopin") && strcmp(type,"bus_tap")))
#define IS_LABEL_OR_PIN(type) (!(strcmp(type,"label") && strcmp(type,"ipin") && \
strcmp(type,"opin") && strcmp(type,"iopin")))
#define IS_PIN(type) (!(strcmp(type,"ipin") && strcmp(type,"opin") && strcmp(type,"iopin")))
@ -954,7 +954,7 @@ typedef struct {
int lastsel;
int maxsel;
Selected *sel_array;
Selected first_sel; /* first selected instance (used as master when editing multile pbjects) */
Selected first_sel; /* first selected instance (used as master when editing multiple objects) */
int prep_net_structs;
int prep_hi_structs;
int prep_hash_inst;
@ -1259,6 +1259,7 @@ extern int embed_rawfile(const char *rawfile);
extern int read_rawfile_from_attr(const char *b64s, size_t length, const char *type);
extern int raw_read_from_attr(Raw **rawptr, const char *type, double sweep1, double sweep2);
extern int raw_add_vector(const char *varname, const char *expr, int sweep_idx);
extern int raw_renamevar(const char *old_name, const char *new_name);
extern int raw_deletevar(const char *name);
extern int new_rawfile(const char *name, const char *type, const char *sweepvar,
double start, double end, double step);
@ -1329,7 +1330,7 @@ extern int process_options(int argc, char **argv);
extern void calc_drawing_bbox(xRect *boundbox, int selected);
extern int ps_draw(int what, int fullzoom, int eps);
extern void svg_draw(void);
extern void svg_embedded_graph(FILE *fd, xRect *r, double rx1, double ry1, double rx2, double ry2);
extern void svg_embedded_graph(FILE *fd, int i, double rx1, double ry1, double rx2, double ry2);
extern void set_viewport_size(int w, int h, double lw);
extern void print_image();
extern const char *get_trailing_path(const char *str, int no_of_dir, int skip_ext);
@ -1400,9 +1401,9 @@ extern void tclmainloop(void);
extern int Tcl_AppInit(Tcl_Interp *interp);
extern void abort_operation(void);
extern void draw_crosshair(int what, int state);
extern void draw_snap_cursor(int what);
extern void backannotate_at_cursor_b_pos(xRect *r, Graph_ctx *gr);
/* extern void snapped_wire(double c_snap); */
extern void unselect_attached_floaters(void);
extern int callback(const char *win_path, 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);
@ -1547,6 +1548,8 @@ extern void new_line(int what, double mx_snap, double my_snap);
extern void new_arc(int what, double sweep, double mousex_snap, double mousey_snap);
extern void arc_3_points(double x1, double y1, double x2, double y2, double x3, double y3,
double *x, double *y, double *r, double *a, double *b);
/* sel: if set to 1 change references only on selected items, like in a copy operation */
extern void update_attached_floaters(const char *from_name, int inst, int sel);
extern void move_objects(int what,int merge, double dx, double dy);
extern void check_collapsing_objects();
extern void redraw_w_a_l_r_p_z_rubbers(int force); /* redraw wire, arcs, line, polygon rubbers */
@ -1611,6 +1614,7 @@ extern char *trim_chars(const char *str, const char *sep);
extern char *find_nth(const char *str, const char *sep, const char *quote, int keep_quote, int n);
extern int isonlydigit(const char *s);
extern const char *spice_get_node(const char *token);
extern char *get_fqdevice(const char *param, int modelparam, const char *instname);
extern const char *translate(int inst, const char* s);
extern const char* translate2(Lcc *lcc, int level, char* s);
extern const char *translate3(const char* s, int eat_escapes, const char *s1,
@ -1688,13 +1692,13 @@ extern const char *expandlabel(const char *s, int *m);
extern void parse(const char *s);
extern void clear_expandlabel_data(void);
extern void merge_file(int selection_load, const char ext[]);
extern void select_wire(int i, unsigned short select_mode, int fast);
extern void select_wire(int i, unsigned short select_mode, int fast, int override_lock);
extern void select_element(int i, unsigned short select_mode, int fast, int override_lock);
extern void select_text(int i, unsigned short select_mode, int fast);
extern void select_text(int i, unsigned short select_mode, int fast, int override_lock);
extern void select_box(int c, int i, unsigned short select_mode, int fast, int override_lock);
extern void select_arc(int c, int i, unsigned short select_mode, int fast);
extern void select_line(int c, int i, unsigned short select_mode, int fast);
extern void select_polygon(int c, int i, unsigned short select_mode, int fast );
extern void select_arc(int c, int i, unsigned short select_mode, int fast, int override_lock);
extern void select_line(int c, int i, unsigned short select_mode, int fast, int override_lock);
extern void select_polygon(int c, int i, unsigned short select_mode, int fast, int override_lock );
extern const char *net_name(int i, int j, int *mult, int hash_prefix_unnamed_net, int erc);
extern int record_global_node(int what, FILE *fp, const char *node);
extern int count_items(const char *s, const char *sep, const char *quote);

View File

@ -628,6 +628,10 @@ proc from_eng {i} {
## convert number to engineering form
proc to_eng {args} {
set suffix {}
if {[ catch {uplevel #0 expr [join $args]} i]} {
return [join $args]
}
set i [uplevel #0 expr [join $args]]
set absi [expr {abs($i)}]
@ -1836,6 +1840,7 @@ proc simconf_add {tool} {
############ cellview
# proc cellview prints symbol bindings (default binding or "schematic" attr in symbol)
# of all symbols used in current and sub schematics.
# the derived_symbols parameter of cellview should be either empty or 'derived_symbols'
proc cellview_setlabels {w symbol derived_symbol} {
global dark_gui_colorscheme netlist_type
if {$dark_gui_colorscheme} {
@ -1937,6 +1942,8 @@ proc cellview_edit_sym {w} {
xschem load_new_window $sym
}
# derived_symbols: empty or 'derived_symbols'
# upd: never set by caller (used iinternally to update)
proc cellview { {derived_symbols {}} {upd 0}} {
global keep_symbols nolist_libs dark_gui_colorscheme netlist_type
@ -2095,10 +2102,9 @@ proc traversal_setlabels {w parent_sch instname inst_sch sym_sch default_sch
set save_netlist_type [xschem get netlist_type]
# puts "traversal_setlabels: $w parent: |$parent_sch| inst: $instname def: $sym_sch $inst_sch --> [$w get]"
# update schematic
if {$parent_sch ne {}} {
if {$parent_sch ne {} && $sym_spice_sym_def eq {} && $inst_spice_sym_def eq {} } {
set current [xschem get current_name]
if { $inst_sch ne [$w get] } {
puts "update attr"
xschem load -undoreset -nodraw $parent_sch
if { [$w get] eq $sym_sch} {
xschem setprop -fast instance $instname schematic ;# remove schematic attr on instance
@ -2224,6 +2230,7 @@ proc hier_traversal {{level 0} {only_subckts 0} {all_hierarchy 1}} {
set instances [xschem get instances]
set current_level [xschem get currsch]
for {set i 0} { $i < $instances} { incr i} {
# puts "hier_traversal: i=$i, current_level=$current_level, parent_sch=$parent_sch"
set instname [xschem getprop instance $i name]
set symbol [xschem getprop instance $i cell::name]
set default_sch [add_ext $symbol .sch]
@ -2301,8 +2308,10 @@ proc hier_traversal {{level 0} {only_subckts 0} {all_hierarchy 1}} {
if {$descended} {
incr level
set dp [hier_traversal $level $only_subckts 1]
xschem go_back 1
xschem go_back 2
incr level -1
} else { ;# descended into a blank schematic. Go back.
xschem go_back 2
}
}
}
@ -4365,8 +4374,10 @@ proc file_dialog_display_preview {f} {
proc file_dialog_right_listboxselect {dirselect} {
global file_dialog_yview file_dialog_dir1 file_dialog_dir2 file_dialog_retval file_dialog_sel
global OS file_dialog_loadfile file_dialog_index1 file_dialog_files1 file_dialog_globfilter
global file_dialog_others
set file_dialog_yview [.load.l.paneright.f.list yview]
set file_dialog_sel [.load.l.paneright.f.list curselection]
set file_dialog_sel [lindex [.load.l.paneright.f.list curselection] 0]
if { $file_dialog_sel ne {} } {
set curr_dir [abs_sym_path [lindex $file_dialog_files1 $file_dialog_index1]]
set curr_item [.load.l.paneright.f.list get $file_dialog_sel]
@ -4399,6 +4410,17 @@ proc file_dialog_right_listboxselect {dirselect} {
set file_dialog_dir1 $curr_dir
set file_dialog_dir2 $curr_item
set file_dialog_others {}
if {$file_dialog_loadfile == 1} {
foreach i [lrange [.load.l.paneright.f.list curselection] 1 end] {
set file_dialog_retval [.load.l.paneright.f.list get $i]
lappend file_dialog_others [file_dialog_getresult 1 0]
}
}
set file_dialog_retval {} ;# we used this variable above to communicate with file_dialog_getresult
if { [file isdirectory $file_dialog_d]} {
bind .load.l.paneright.draw <Expose> {}
bind .load.l.paneright.draw <Configure> {}
@ -4421,6 +4443,16 @@ proc file_dialog_right_listboxselect {dirselect} {
}
}
proc load_additional_files {} {
global file_dialog_others
if {$file_dialog_others ne {} } {
foreach i $file_dialog_others {
xschem load_new_window $i
}
}
}
# global_initdir: name of global variable containing the initial directory
# loadfile: set to 0 if calling for saving instead of loading a file
# set to 2 for non blocking operation (symbol insertion)
@ -4506,11 +4538,15 @@ proc load_file_dialog {{msg {}} {ext {}} {global_initdir {INITIALINSTDIR}}
eval .load.l.paneright paneconfigure .load.l.paneright.f $optnever
eval .load.l.paneright paneconfigure .load.l.paneright.draw $optalways
if {$global_initdir eq {INITIALINSTDIR}} {
set selmode browse
} else {
set selmode extended
}
listbox .load.l.paneright.f.list -background {grey90} -listvariable file_dialog_files2 -width 20 -height 12\
-fg black -highlightcolor red -highlightthickness 2 \
-yscrollcommand ".load.l.paneright.f.yscroll set" -selectmode browse \
-yscrollcommand ".load.l.paneright.f.yscroll set" -selectmode $selmode \
-xscrollcommand ".load.l.paneright.f.xscroll set" -exportselection 0
scrollbar .load.l.paneright.f.yscroll -command ".load.l.paneright.f.list yview" -takefocus 0
scrollbar .load.l.paneright.f.xscroll -command ".load.l.paneright.f.list xview" -orient horiz -takefocus 0
@ -6447,12 +6483,17 @@ proc editdata {{data {}} {title {Edit data}} } {
# wm transient $window [xschem get topwindow]
frame $window.buttons
pack $window.buttons -side bottom -fill x -pady 2m
button $window.buttons.copy -text Copy -command "
clipboard clear
clipboard append \[$window.text get 1.0 {end - 1 chars}\]
"
button $window.buttons.ok -text OK -command "
set retval \[$window.text get 1.0 {end - 1 chars}\]; destroy $window
"
button $window.buttons.cancel -text Cancel -command "destroy $window"
pack $window.buttons.ok -side left -expand 1
pack $window.buttons.cancel -side left -expand 1
pack $window.buttons.copy -side left -expand 1
eval text $window.text -undo 1 -relief sunken -bd 2 -yscrollcommand \"$window.yscroll set\" -setgrid 1 \
-xscrollcommand \"$window.xscroll set\" -wrap none -height 30 $text_tabs_setting
@ -6744,8 +6785,14 @@ proc rel_sym_path {symbol} {
global OS pathlist env
regsub {^~/} $symbol ${env(HOME)}/ symbol
if {![regexp {^/} $symbol]} {
set symbol [pwd]/$symbol
if {$OS eq "Windows"} {
if {![regexp {^[A-Za-z]\:/} $symbol]} {
set symbol [pwd]/$symbol
}
} else {
if {![regexp {^/} $symbol]} {
set symbol [pwd]/$symbol
}
}
set curr_dirname [pwd]
set name {}
@ -7848,42 +7895,34 @@ proc no_open_dialogs {} {
## "file_dialog_*" only one load_file_dialog window is allowed
set tctx::global_list {
PDK_ROOT PDK SKYWATER_MODELS SKYWATER_STDCELLS
INITIALINSTDIR INITIALLOADDIR INITIALPROPDIR INITIALTEXTDIR XSCHEM_LIBRARY_PATH
add_all_windows_drives auto_hilight auto_hilight_graph_nodes autofocus_mainwindow
autotrim_wires orthogonal_wiring snap_cursor bespice_listen_port big_grid_points bus_replacement_char cadgrid cadlayers
cadsnap cadence_compat cairo_font_name cairo_font_scale change_lw color_ps tctx::colors compare_sch constr_mv
copy_cell crosshair_layer crosshair_size cursor_2_hook snap_cursor_size custom_label_prefix custom_token
dark_colors dark_colorscheme dark_gui_colorscheme delay_flag
dim_bg dim_value disable_unique_names do_all_inst draw_crosshair
draw_grid draw_grid_axes draw_window edit_prop_pos edit_prop_size
edit_symbol_prop_new_sel editprop_sympath en_hilight_conn_inst enable_dim_bg enable_stretch
enter_text_default_geometry filetmp fix_broken_tiled_fill flat_netlist fullscreen
gaw_fd gaw_tcp_address graph_autoload graph_bus
graph_change_done graph_digital graph_dialog_default_geometry
graph_legend graph_linewidth_mult graph_logx
graph_logy graph_private_cursor graph_rainbow graph_schname graph_sel_color graph_sel_wave
graph_selected graph_sort graph_unlocked graph_use_ctrl_key
hide_empty_graphs hide_symbols tctx::hsize
incr_hilight incremental_select infix_interface infowindow_text intuitive_interface
keep_symbols launcher_default_program
light_colors line_width live_cursor2_backannotate local_netlist_dir lvs_ignore
lvs_netlist measure_text netlist_dir netlist_show netlist_type no_ask_save
no_change_attrs nolist_libs noprint_libs old_selected_tok only_probes path pathlist
persistent_command preserve_unchanged_attrs prev_symbol ps_colors ps_paper_size rainbow_colors
tctx::rcode recentfile
retval retval_orig rotated_text search_case search_exact search_found search_schematic
search_select search_value select_touch selected_tok show_hidden_texts show_infowindow
show_infowindow_after_netlist
simconf_default_geometry simconf_vpos simulate_bg spiceprefix split_files svg_colors
svg_font_name sym_txt symbol symbol_width tabstop tclcmd_txt tclstop text_line_default_geometry
text_replace_selection text_tabs_setting textwindow_fileid textwindow_filename textwindow_w
toolbar_horiz toolbar_list
toolbar_visible top_is_subckt transparent_svg undo_type use_lab_wire unselect_partial_sel_wires
use_label_prefix use_tclreadline
user_wants_copy_cell verilog_2001 verilog_bitblast viewdata_fileid viewdata_filename viewdata_w
tctx::vsize xschem_libs xschem_listen_port zoom_full_center orthogonal_wiring snap_cursor
snap_cursor_size cadence_compat use_cursor_for_selection
INITIALINSTDIR INITIALLOADDIR INITIALPROPDIR INITIALTEXTDIR PDK PDK_ROOT SKYWATER_MODELS
SKYWATER_STDCELLS XSCHEM_LIBRARY_PATH add_all_windows_drives auto_hilight
auto_hilight_graph_nodes autofocus_mainwindow autotrim_wires bespice_listen_port big_grid_points
bus_replacement_char cadence_compat cadgrid cadlayers cadsnap cairo_font_name cairo_font_scale
change_lw color_ps compare_sch constr_mv copy_cell crosshair_layer crosshair_size cursor_2_hook
custom_label_prefix custom_token dark_colors dark_colorscheme dark_gui_colorscheme delay_flag
dim_bg dim_value disable_unique_names do_all_inst draw_crosshair draw_grid draw_grid_axes
draw_window edit_prop_pos edit_prop_size edit_symbol_prop_new_sel editprop_sympath
en_hilight_conn_inst enable_dim_bg enable_stretch enter_text_default_geometry filetmp
fix_broken_tiled_fill flat_netlist fullscreen gaw_fd gaw_tcp_address graph_autoload graph_bus
graph_change_done graph_dialog_default_geometry graph_digital graph_legend graph_linewidth_mult
graph_logx graph_logy graph_private_cursor graph_rainbow graph_schname graph_sel_color
graph_sel_wave graph_selected graph_sort graph_unlocked graph_use_ctrl_key hide_empty_graphs
hide_symbols incr_hilight incremental_select infix_interface infowindow_text intuitive_interface
keep_symbols launcher_default_program light_colors line_width live_cursor2_backannotate
local_netlist_dir lvs_ignore lvs_netlist measure_text netlist_dir netlist_show netlist_type
no_ask_save no_change_attrs nolist_libs noprint_libs old_selected_tok only_probes
orthogonal_wiring path pathlist persistent_command preserve_unchanged_attrs prev_symbol ps_colors
ps_paper_size rainbow_colors recentfile retval retval_orig rotated_text search_case search_exact
search_found search_schematic search_select search_value select_touch selected_tok
show_hidden_texts show_infowindow show_infowindow_after_netlist simconf_default_geometry
simconf_vpos simulate_bg snap_cursor snap_cursor_size spiceprefix split_files svg_colors
svg_font_name sym_txt symbol symbol_width tabstop tclcmd_txt tclstop tctx::colors tctx::hsize
tctx::rcode tctx::vsize text_line_default_geometry text_replace_selection text_tabs_setting
textwindow_fileid textwindow_filename textwindow_w toolbar_horiz toolbar_list toolbar_visible
top_is_subckt transparent_svg undo_type unselect_partial_sel_wires use_cursor_for_selection
use_lab_wire use_label_prefix use_tclreadline user_wants_copy_cell verilog_2001 verilog_bitblast
viewdata_fileid viewdata_filename viewdata_w xschem_libs xschem_listen_port zoom_full_center
}
## list of global arrays to save/restore on context switching
@ -8268,7 +8307,7 @@ proc load_raw {{type {}}} {
proc build_widgets { {topwin {} } } {
global XSCHEM_SHAREDIR tabbed_interface simulate_bg OS sim
global dark_gui_colorscheme draw_crosshair
global dark_gui_colorscheme draw_crosshair grid_point_size
global recentfile color_ps transparent_svg menu_debug_var enable_stretch
global netlist_show flat_netlist split_files compare_sch intuitive_interface
global draw_grid big_grid_points sym_txt change_lw incr_hilight symbol_width cadence_compat
@ -8421,6 +8460,19 @@ proc build_widgets { {topwin {} } } {
$topwin.menubar.option add checkbutton -label "Draw persistent snap cursor" -variable snap_cursor \
-selectcolor $selectcolor -accelerator {Alt-Z}
$topwin.menubar.option add cascade -label "Crosshair" \
-menu $topwin.menubar.option.crosshair
menu $topwin.menubar.option.crosshair -tearoff 0
$topwin.menubar.option.crosshair add checkbutton -label "Draw snap cursor" \
-variable snap_cursor -selectcolor $selectcolor
$topwin.menubar.option.crosshair add checkbutton -label "Draw crosshair" \
-variable draw_crosshair -selectcolor $selectcolor -accelerator {Alt-X}
$topwin.menubar.option.crosshair add command -label "Crosshair size" \
-command {
input_line "Enter crosshair size (int, 0 = full screen width):" \
"set crosshair_size" $crosshair_size
}
$topwin.menubar.option add command -label "Replace \[ and \] for buses in SPICE netlist" \
-command {
input_line "Enter two characters to replace default bus \[\] delimiters:" "set bus_replacement_char"
@ -8601,6 +8653,10 @@ proc build_widgets { {topwin {} } } {
set change_lw 0
input_line "Enter linewidth (float):" "xschem line_width"
}
$topwin.menubar.view add command -label "Set grid point size" \
-command {
input_line "Enter Grid point size (int or -1: $grid_point_size)" "set grid_point_size" $grid_point_size
}
$topwin.menubar.view add checkbutton -label "Tabbed interface" -variable tabbed_interface \
-selectcolor $selectcolor -command setup_tabbed_interface
@ -8675,6 +8731,8 @@ proc build_widgets { {topwin {} } } {
-command "xschem net_label 0" -accelerator Alt-Shift-L
$topwin.menubar.sym add command -label "Change selected inst. texts to floaters" \
-command "xschem floaters_from_selected_inst"
$topwin.menubar.sym add command -label "Unselect attached floaters" \
-command "xschem unselect_attached_floaters"
$topwin.menubar.sym add command -label "Print list of highlight nets" \
-command "xschem print_hilight_net 1" -accelerator J
$topwin.menubar.sym add command -label "Print list of highlight nets, with buses expanded" \
@ -9331,6 +9389,7 @@ set_ne enable_stretch 0
set_ne constr_mv 0
set_ne unselect_partial_sel_wires 0
set_ne load_file_dialog_fullpath 1
set_ne file_dialog_others {} ;# contains 2nd, 3rd, ... selected filenames on mult. selections in load file
# if set show selected elements while dragging the selection rectangle.
# once selected these can not be unselected by retracting the selection rectangle
@ -9340,6 +9399,7 @@ set_ne select_touch 1
set_ne draw_grid 1
set_ne big_grid_points 0
set_ne grid_point_size -1 ;# grid point size (>=0) or unspecified (-1)
set_ne draw_grid_axes 1
set_ne persistent_command 0
set_ne intuitive_interface 1

View File

@ -295,6 +295,9 @@
#### enable to scale grid point size as done with lines at close zoom, default: 0
# set big_grid_points 0
#### explicitly set grid point size in pixels. Default: -1 (not set)
# set grid_point_size 2
#### enable drawing grid axes. Default: enabled (1)
# set draw_grid_axes 1

View File

@ -0,0 +1,33 @@
v {xschem version=3.4.6 file_version=1.2
*
* This file is part of XSCHEM,
* a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit
* simulation.
* Copyright (C) 1998-2024 Stefan Frederik Schippers
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
}
G {}
K {type=scope
template="name=l1"
highlight=true}
V {}
S {}
E {}
L 4 0 0 10 -20 {}
B 5 -1.25 -1.25 1.25 1.25 {name=p dir=in}
P 4 5 10 -20 10 -140 140 -140 140 -20 10 -20 {}
T {@#0:net_name} 12.5 -18.125 0 0 0.2 0.2 {layer=4}
T {@#0:spice_get_voltage} 12.5 -139.375 0 0 0.15 0.15 {layer=15}

View File

@ -0,0 +1,36 @@
v {xschem version=3.4.6 file_version=1.2
*
* This file is part of XSCHEM,
* a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit
* simulation.
* Copyright (C) 1998-2024 Stefan Frederik Schippers
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
}
G {}
K {type=scope
template="name=l1"
highlight=true}
V {}
S {}
E {}
L 4 0 0 10 -20 {}
L 4 0 -160 10 -140 {}
B 5 -1.25 -161.25 1.25 -158.75 {name=p dir=in}
B 5 -1.25 -1.25 1.25 1.25 {name=m dir=in}
P 4 5 10 -20 10 -140 140 -140 140 -20 10 -20 {}
T {@#1:net_name} 12.5 -18.125 0 0 0.2 0.2 {layer=4}
T {@#0:net_name} 12.5 -153.125 0 0 0.2 0.2 {layer=4}
T {@spice_get_diff_voltage} 12.5 -139.375 0 0 0.15 0.15 {layer=15}

View File

@ -0,0 +1,31 @@
v {xschem version=3.4.6 file_version=1.2
*
* This file is part of XSCHEM,
* a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit
* simulation.
* Copyright (C) 1998-2024 Stefan Frederik Schippers
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
}
G {}
K {type=scope
template="name=l1"
highlight=true}
V {}
S {}
E {}
P 4 5 10 -20 10 -140 140 -140 140 -20 10 -20 {}
T {@device} 12.5 -18.125 0 0 0.2 0.2 {layer=4}
T {tcleval(@spice_get_node [xschem get_fqdevice @device ] )} 12.5 -139.375 0 0 0.15 0.15 {layer=17}

View File

@ -1,4 +1,4 @@
v {xschem version=3.4.6RC file_version=1.2
v {xschem version=3.4.6 file_version=1.2
*
* This file is part of XSCHEM,
* a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit
@ -24,6 +24,15 @@ K {}
V {}
S {}
E {}
B 2 520 -415 630 -315 {name=l4
flags=graph,unlocked
lock=1
color=8
node="tcleval([xschem get_fqdevice [xschem translate l4 @device]])"
y1=-0.00014
y2=0.00013
x1=0.00044464632
x2=0.00046163671}
T {( @#0:resolved_net )} 440 -265 0 1 0.2 0.2 {name=l2 layer=15}
T {( @#0:resolved_net )} 100 -285 0 1 0.2 0.2 {name=p1 layer=15}
T {( @#0:resolved_net )} 100 -235 0 1 0.2 0.2 {name=p2 layer=15}
@ -49,3 +58,6 @@ m=1}
C {parax_cap.sym} 630 -230 0 0 {name=C3 gnd=0 value=\{COUT\} m=1}
C {vsource.sym} 150 -260 1 0 {name=V1 value=0}
C {vsource.sym} 150 -210 1 0 {name=V2 value=0}
C {scope_ammeter.sym} 500 -290 0 0 {name=l4
attach=l4
device=R1}

View File

@ -26,34 +26,34 @@ K {}
V {}
S {}
E {}
L 2 105 -1005 105 -775 {}
L 2 145 -1005 145 -775 {}
L 2 185 -1005 185 -775 {}
L 2 225 -1005 225 -775 {}
L 2 265 -1005 265 -775 {}
L 2 305 -1005 305 -775 {}
L 2 345 -1005 345 -775 {}
L 2 385 -1005 385 -775 {}
L 2 65 -975 395 -975 {}
L 2 65 -935 395 -935 {}
L 2 65 -895 395 -895 {}
L 2 65 -855 395 -855 {}
L 2 65 -815 395 -815 {}
L 4 65 -1015 65 -755 {}
L 4 55 -775 405 -775 {}
L 4 105 -775 105 -765 {}
L 4 145 -775 145 -765 {}
L 4 185 -775 185 -765 {}
L 4 225 -775 225 -765 {}
L 4 265 -775 265 -765 {}
L 4 305 -775 305 -765 {}
L 4 345 -775 345 -765 {}
L 4 385 -775 385 -765 {}
L 4 55 -815 65 -815 {}
L 4 55 -855 65 -855 {}
L 4 55 -895 65 -895 {}
L 4 55 -935 65 -935 {}
L 4 55 -975 65 -975 {}
L 2 95 -1105 95 -875 {}
L 2 135 -1105 135 -875 {}
L 2 175 -1105 175 -875 {}
L 2 215 -1105 215 -875 {}
L 2 255 -1105 255 -875 {}
L 2 295 -1105 295 -875 {}
L 2 335 -1105 335 -875 {}
L 2 375 -1105 375 -875 {}
L 2 55 -1075 385 -1075 {}
L 2 55 -1035 385 -1035 {}
L 2 55 -995 385 -995 {}
L 2 55 -955 385 -955 {}
L 2 55 -915 385 -915 {}
L 4 55 -1115 55 -855 {}
L 4 45 -875 395 -875 {}
L 4 95 -875 95 -865 {}
L 4 135 -875 135 -865 {}
L 4 175 -875 175 -865 {}
L 4 215 -875 215 -865 {}
L 4 255 -875 255 -865 {}
L 4 295 -875 295 -865 {}
L 4 335 -875 335 -865 {}
L 4 375 -875 375 -865 {}
L 4 45 -915 55 -915 {}
L 4 45 -955 55 -955 {}
L 4 45 -995 55 -995 {}
L 4 45 -1035 55 -1035 {}
L 4 45 -1075 55 -1075 {}
L 4 610 -1100 630 -1140 {}
L 4 630 -1140 650 -1100 {}
L 4 650 -1100 670 -1140 {}
@ -83,13 +83,13 @@ L 4 960 -340 970 -340 {}
L 4 960 -340 970 -330 {}
L 4 970 -330 980 -340 {}
L 4 970 -340 980 -340 {}
B 2 1260 -560 1680 -390 {flags=graph
B 2 1370 -555 1790 -385 {flags=graph
y1 = -0.00068
y2 = 22
divy = 6
subdivy=1
x1=2.9358714e-05
x2=0.0010293582
x1=5e-10
x2=0.001
divx=8
node="PANEL
LED" unitx=m
@ -104,13 +104,13 @@ autoload=0
sim_type=tran
xrawfile=$netlist_dir/solar_panel.raw}
B 2 1260 -390 1680 -220 {flags=graph
B 2 1370 -385 1790 -215 {flags=graph
y1 = -0.0012
y2 = 6.8
divy = 4
subdivy=1
x1=2.9358714e-05
x2=0.0010293582
x1=5e-10
x2=0.001
divx=8
unitx=m
color="7 4 6"
@ -123,13 +123,13 @@ autoload=0
sim_type=tran
xrawfile=$netlist_dir/solar_panel.raw}
B 2 1260 -750 1680 -560 {flags=graph
B 2 1370 -745 1790 -555 {flags=graph
y1 = -2.7e-05
y2 = 100
divy = 5
subdivy=1
x1=2.9358714e-05
x2=0.0010293582
x1=5e-10
x2=0.001
divx=9
unitx=m subdivx=4
@ -146,13 +146,13 @@ autoload=0
sim_type=tran
xrawfile=$netlist_dir/solar_panel.raw}
B 2 1260 -940 1680 -750 {flags=graph
B 2 1370 -935 1790 -745 {flags=graph
y1 = 0
y2 = 1
divy = 5
subdivy=1
x1=2.9358714e-05
x2=0.0010293582
x1=5e-10
x2=0.001
divx=9
unitx=u subdivx=4
@ -169,13 +169,13 @@ autoload=0
sim_type=tran
xrawfile=$netlist_dir/solar_panel.raw}
B 2 1260 -1140 1680 -950 {flags=graph
B 2 1370 -1135 1790 -945 {flags=graph
y1 = 0
y2 = 1
divy = 5
subdivy=1
x1=2.9358714e-05
x2=0.0010293582
x1=5e-10
x2=0.001
divx=9
unitx=u subdivx=4
@ -193,29 +193,65 @@ autoload=0
sim_type=tran
xrawfile=$netlist_dir/solar_panel.raw}
B 18 65 -960 320 -775 {}
A 5 320 -960 5.590169943749475 243.434948822922 360 {fill=true}
P 7 6 395 -775 340 -931.25 335 -945 322.5 -960 310 -965 65 -975 {}
T {2x10 1W white LED} 1240 -200 0 0 0.4 0.4 {layer=8}
T {2xseries 1W white LEDs} 1220 -140 0 0 0.4 0.4 {}
T {2.5} 95 -755 0 0 0.2 0.2 {}
T {5.0} 135 -755 0 0 0.2 0.2 {}
T {7.5} 175 -755 0 0 0.2 0.2 {}
T {10.0} 215 -755 0 0 0.2 0.2 {}
T {12.5} 255 -755 0 0 0.2 0.2 {}
T {15.0} 295 -755 0 0 0.2 0.2 {}
T {17.5} 335 -755 0 0 0.2 0.2 {}
T {20.0} 375 -755 0 0 0.2 0.2 {}
T {2.5} 35 -980 0 0 0.2 0.2 {}
T {2.0} 35 -940 0 0 0.2 0.2 {}
T {1.5} 35 -895 0 0 0.2 0.2 {}
T {1.0} 35 -860 0 0 0.2 0.2 {}
T {0.5} 35 -820 0 0 0.2 0.2 {}
T {25C, 1000W/m2} 190 -1030 0 0 0.2 0.2 {}
T {V} 410 -765 0 0 0.4 0.4 {}
T {I} 40 -1020 0 0 0.4 0.4 {}
T {SOLAR PANEL} 145 -1055 0 0 0.4 0.4 {}
T {Maximum Power} 307.5 -980 0 0 0.2 0.2 {layer=8}
B 2 1210 -605 1320 -505 {name=l21
flags=graph,unlocked
lock=1
color=8
node="tcleval([xschem translate l21 @#0:net_name] [xschem translate l21 @#1:net_name] -)"
x1=5e-10
x2=0.001
y1=-4.8
y2=15}
B 2 400 -735 510 -635 {name=l22
flags=graph,unlocked
lock=1
color=8
node="tcleval([xschem translate l22 @#0:net_name])"
y1=0.00033
y2=21
x1=5e-10
x2=0.001}
B 2 600 -485 710 -385 {name=l23
flags=graph,unlocked
lock=1
color=8
node="tcleval([xschem get_fqdevice [xschem translate l23 @device]])"
x1=5e-10
x2=0.001
y1=-2.9
y2=6.8}
B 2 640 -295 750 -195 {name=l26
flags=graph,unlocked
lock=1
color=8
node="tcleval([xschem get_fqdevice [xschem translate l26 @device]])"
x1=5e-10
x2=0.001
y1=-2.9
y2=6.8}
B 18 55 -1060 310 -875 {}
A 5 310 -1060 5.590169943749475 243.434948822922 360 {fill=true}
P 7 6 385 -875 330 -1031.25 325 -1045 312.5 -1060 300 -1065 55 -1075 {}
T {2x10 1W white LED} 1350 -195 0 0 0.4 0.4 {layer=8}
T {2xseries 1W white LEDs} 1330 -135 0 0 0.4 0.4 {}
T {2.5} 85 -855 0 0 0.2 0.2 {}
T {5.0} 125 -855 0 0 0.2 0.2 {}
T {7.5} 165 -855 0 0 0.2 0.2 {}
T {10.0} 205 -855 0 0 0.2 0.2 {}
T {12.5} 245 -855 0 0 0.2 0.2 {}
T {15.0} 285 -855 0 0 0.2 0.2 {}
T {17.5} 325 -855 0 0 0.2 0.2 {}
T {20.0} 365 -855 0 0 0.2 0.2 {}
T {2.5} 25 -1080 0 0 0.2 0.2 {}
T {2.0} 25 -1040 0 0 0.2 0.2 {}
T {1.5} 25 -995 0 0 0.2 0.2 {}
T {1.0} 25 -960 0 0 0.2 0.2 {}
T {0.5} 25 -920 0 0 0.2 0.2 {}
T {25C, 1000W/m2} 180 -1130 0 0 0.2 0.2 {}
T {V} 400 -865 0 0 0.4 0.4 {}
T {I} 30 -1120 0 0 0.4 0.4 {}
T {SOLAR PANEL} 135 -1155 0 0 0.4 0.4 {}
T {Maximum Power} 297.5 -1080 0 0 0.2 0.2 {layer=8}
T {set between 0 and 1
to simulate
sun radiation
@ -232,21 +268,21 @@ T {Floater text
example} 870 -440 0 0 0.4 0.4 {}
T {@spice_get_current} 875 -598.75 0 0 0.3 0.3 {layer=7 name=L2}
T {@spice_get_current} 1015 -268.75 0 0 0.3 0.3 {layer=7 name=C1}
N 1010 -210 1100 -210 {lab=0}
N 1100 -300 1100 -210 {lab=0}
N 1010 -180 1100 -180 {lab=0}
N 1100 -300 1100 -180 {lab=0}
N 640 -610 730 -610 {lab=#net1}
N 1010 -440 1040 -440 {lab=VO}
N 1010 -440 1010 -310 {lab=VO}
N 1010 -250 1010 -210 {lab=0}
N 530 -610 580 -610 {lab=PANEL}
N 1010 -250 1010 -180 {lab=0}
N 360 -610 580 -610 {lab=PANEL}
N 1010 -610 1010 -440 {lab=VO}
N 820 -610 860 -610 {lab=SW}
N 820 -610 820 -490 {lab=SW}
N 790 -610 820 -610 {lab=SW}
N 820 -210 1010 -210 {lab=0}
N 800 -210 820 -210 {lab=0}
N 820 -180 1010 -180 {lab=0}
N 800 -180 820 -180 {lab=0}
N 1000 -610 1010 -610 {lab=VO}
N 1100 -440 1140 -440 {lab=LED}
N 1100 -440 1280 -440 {lab=LED}
N 1100 -440 1100 -360 {lab=LED}
N 820 -430 820 -390 { lab=#net2}
N 920 -610 940 -610 { lab=#net3}
@ -295,12 +331,14 @@ N 770 -1080 770 -1030 {
lab=TRIANG}
N 770 -1030 890 -1030 {
lab=TRIANG}
N 820 -330 820 -210 {
N 820 -330 820 -180 {
lab=0}
N 1190 -480 1190 -440 {lab=LED}
N 1190 -670 1190 -640 {lab=PANEL}
C {title.sym} 160 -40 0 0 {name=l1 author="Stefan Schippers"}
C {code_shown.sym} 170 -310 0 0 {name=CONTROL
C {code_shown.sym} 180 -310 0 0 {name=CONTROL
value="tcleval(
.probe alli
.option savecurrents
.control
* example of tcl evaluation of code blocks:
* current path: $path
@ -318,24 +356,26 @@ C {code.sym} 20 -240 0 0 {name=MODELS value=".MODEL DIODE D(IS=1.139e-08 RS=0.99
.MODEL swmod SW(VT=0.5 VH=0.01 RON=0.01 ROFF=10000000)
"}
C {lab_pin.sym} 650 -530 0 1 {name=l4 lab=PANEL }
C {lab_pin.sym} 800 -210 0 0 {name=l6 lab=0 }
C {lab_pin.sym} 800 -180 0 0 {name=l6 lab=0 }
C {ammeter.sym} 1070 -440 3 0 {name=Vled}
C {ind.sym} 890 -610 3 1 {name=L2
m=1
value=40u
footprint=1206
device=inductor
hide_texts=true}
C {lab_pin.sym} 1140 -440 0 1 {name=l7 lab=LED }
hide_texts=true
attach=L2}
C {lab_pin.sym} 1280 -440 0 1 {name=l7 lab=LED }
C {lab_pin.sym} 820 -550 0 1 {name=l9 lab=SW }
C {capa.sym} 1010 -280 0 0 {name=C1
m=1
value=500n
footprint=1206
device="ceramic capacitor"
hide_texts=true}
hide_texts=true
attach=C1}
C {lab_pin.sym} 1010 -400 0 1 {name=l10 lab=VO }
C {lab_pin.sym} 530 -610 0 0 {name=l3 lab=PANEL }
C {lab_pin.sym} 360 -610 0 0 {name=l3 lab=PANEL }
C {ammeter.sym} 970 -610 3 0 {name=Vind}
C {isource_table.sym} 1100 -330 0 0 {name=G2[9..0] CTRL="V(LED)" TABLE="
+ (0, 0)
@ -403,3 +443,15 @@ C {spice_probe.sym} 850 -1030 0 1 {name=p4 analysis=tran}
C {spice_probe.sym} 810 -890 0 1 {name=p5 analysis=tran}
C {spice_probe.sym} 760 -670 0 0 {name=p6 analysis=tran}
C {spice_probe.sym} 160 -450 0 0 {name=p7 analysis=tran}
C {lab_show.sym} 440 -610 2 0 {name=l24}
C {lab_pin.sym} 1190 -670 0 0 {name=l25 lab=PANEL }
C {scope2.sym} 1190 -480 0 0 {name=l21
attach=l21}
C {scope.sym} 380 -610 0 0 {name=l22
attach=l22}
C {scope_ammeter.sym} 580 -360 0 0 {name=l23
attach=l23
device=Vcap}
C {scope_ammeter.sym} 620 -170 0 0 {name=l26
attach=l26
device=Vdiode}