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 - 't' Place text
shift 'T' Toggle *_ignore flag on selected instances shift 'T' Toggle *_ignore flag on selected instances
alt 'u' Align to current grid selected objects alt 'u' Align to current grid selected objects
ctrl 'u' Unselect attached floater objects
shift 'U' Redo shift 'U' Redo
- 'u' Undo - 'u' Undo
- 'v' Constrained vertical move/copy of objects - '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> <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 <p> This attribute sets the layer of symbol text item number <kbd>n</kbd>. This allows
instance based symbol text color customization.</p> 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> <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> <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> <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> <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> return result of get_cell function </pre>
<li><kbd> get_cell_w_ext cell n_dirs</kbd></li><pre> <li><kbd> get_cell_w_ext cell n_dirs</kbd></li><pre>
return result of get_cell_w_ext function </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> <li><kbd> getprop instance|instance_pin|symbol|text ref</kbd></li><pre>
getprop instance inst 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> <li><kbd> push_undo</kbd></li><pre>
Push current state on undo stack </pre> Push current state on undo stack </pre>
<li><kbd> raw what ...</kbd></li><pre> <li><kbd> raw what ...</kbd></li><pre>
what = add | clear | datasets | index | info | loaded | list | new | points | rawfile | del | what = add | clear | datasets | index | info | loaded | list |
read | set | sim_type | switch | switch_back | table_read | value | values | pos_at | vars | 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]] xschem raw read filename [type [sweep1 sweep2]]
if sweep1, sweep2 interval is given in 'read' subcommand load only the interval 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 xschem raw del name
delete named vector from current raw file 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 xschem raw info
print information about loaded raw files and show the currently active one. 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. new dataset do not start with a header row.
Lines beginning with '#' are comments and ignored 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 # this is a comment, ignored
0.0 0.0 1.8 0.3 0.0 0.0 1.8 0.3
&lt;single empty line: ignored&gt; &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> Unhighlight selected nets/pins </pre>
<li><kbd> unselect_all [draw]</kbd></li><pre> <li><kbd> unselect_all [draw]</kbd></li><pre>
Unselect everything. If draw is given and set to '0' no drawing is done </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> <li><kbd> update_all_sym_bboxes</kbd></li><pre>
Update all symbol bounding boxes </pre> Update all symbol bounding boxes </pre>
<li><kbd> update_op</kbd></li><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> </ul>

View File

@ -551,6 +551,19 @@ verilog_format="xnor #(@risedel , @falldel ) @name ( @@Z , @@A , @@B );"
</ul> </ul>
<h3>PREDEFINED SYMBOL VALUES</h3> <h3>PREDEFINED SYMBOL VALUES</h3>
<ul> <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> <li><kbd>@symname</kbd></li>
<p> This expands to the name of the symbol</p> <p> This expands to the name of the symbol</p>
<li><kbd>@symref</kbd></li> <li><kbd>@symref</kbd></li>

View File

@ -1066,7 +1066,7 @@ void clear_partial_selected_wires(void)
rebuild_selected_array(); rebuild_selected_array();
for(j=0; j < xctx->lastsel; ++j) if(xctx->sel_array[j].type == WIRE) { for(j=0; j < xctx->lastsel; ++j) if(xctx->sel_array[j].type == WIRE) {
int wire = xctx->sel_array[j].n; int wire = xctx->sel_array[j].n;
select_wire(wire, 0, 1); select_wire(wire, 0, 1, 1);
} }
xctx->need_reb_sel_arr = 1; xctx->need_reb_sel_arr = 1;
rebuild_selected_array(); rebuild_selected_array();
@ -1229,7 +1229,7 @@ int unselect_partial_sel_wires(void)
while(wptr) { while(wptr) {
xWire *w = &xctx->wire[wptr->n]; xWire *w = &xctx->wire[wptr->n];
if(touch(w->x1, w->y1, w->x2, w->y2, pinx0, piny0) && w->sel && w->sel != SELECTED) { 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; changed = 1;
} }
wptr = wptr->next; 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) { if(touch(w->x1, w->y1, w->x2, w->y2, x0, y0) && w->sel && w->sel != SELECTED) {
xctx->wire[wptr->n].sel = 0; xctx->wire[wptr->n].sel = 0;
select_wire(wptr->n, 0, 1); select_wire(wptr->n, 0, 1, 1);
changed = 1; changed = 1;
} }
wptr = wptr->next; wptr = wptr->next;
@ -1450,7 +1450,6 @@ void delete_files(void)
void place_net_label(int type) void place_net_label(int type)
{ {
unselect_all(1);
if(type == 1) { if(type == 1) {
const char *lab = tcleval("rel_sym_path [find_file_first lab_pin.sym]"); 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*/); 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 name[PATH_MAX];
char name1[PATH_MAX]; char name1[PATH_MAX];
char tclev = 0; char tclev = 0;
if(symbol_name==NULL) { if(symbol_name==NULL) {
tcleval("load_file_dialog {Choose symbol} *.\\{sym,tcl\\} INITIALINSTDIR"); tcleval("load_file_dialog {Choose symbol} *.\\{sym,tcl\\} INITIALINSTDIR");
my_strncpy(name1, tclresult(), S(name1)); my_strncpy(name1, tclresult(), S(name1));
} else { } else {
my_strncpy(name1, trim_chars(symbol_name, " \t\n"), S(name1)); 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); dbg(1, "place_symbol(): 1: name1=%s first_call=%d\n",name1, first_call);
/* remove tcleval( given in file selector, if any ... */ /* remove tcleval( given in file selector, if any ... */
if(strstr(name1, "tcleval(")) { 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 /* After having assigned prop_ptr to new instance translate symbol reference
* to resolve @params --> res.tcl(@value\) --> res.tcl(100) */ * to resolve @params --> res.tcl(@value\) --> res.tcl(100) */
my_strncpy(name, translate(n, name), S(name)); 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; xctx->inst[n].ptr = i;
set_inst_flags(&xctx->inst[n]); set_inst_flags(&xctx->inst[n]);
hash_names(n, XINSERT); 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 */ if(xctx->prep_hash_inst) hash_inst(XINSERT, n); /* no need to rehash, add item */
/* xctx->prep_hash_inst=0; */ /* 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) { if(draw_sym & 3) {
bbox(ADD, xctx->inst[n].x1, xctx->inst[n].y1, xctx->inst[n].x2, xctx->inst[n].y2); 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 */ /* hilight new element 24122002 */
if(draw_sym & 4 ) { if(draw_sym & 4 ) {
unselect_all(1);
select_element(n, SELECTED,0, 1); select_element(n, SELECTED,0, 1);
drawtemparc(xctx->gc[SELLAYER], END, 0.0, 0.0, 0.0, 0.0, 0.0); 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); 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; char *ptr;
size_t pathlen; size_t pathlen;
int res = 0; 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_, &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_, &expanded_instname, expandlabel(instname, &inst_mult));
my_strdup2(_ALLOC_ID_, &path, xctx->sch_path[xctx->currsch]); 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 inst_mult, inst_number;
int save_ok = 0; int save_ok = 0;
int i, n = 0; int i, n = 0;
int descend_ok = 1;
if(xctx->currsch + 1 >= CADMAXHIER) { if(xctx->currsch + 1 >= CADMAXHIER) {
dbg(0, "descend_schematic(): max hierarchy depth reached: %d", 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); dbg(1, "descend_schematic(): filename=%s\n", filename);
/* we are descending from a parent schematic downloaded from the web */ /* we are descending from a parent schematic downloaded from the web */
if(!tclgetboolvar("keep_symbols")) remove_symbols(); if(!tclgetboolvar("keep_symbols")) remove_symbols();
load_schematic(1, filename, (set_title & 1), alert); descend_ok = load_schematic(1, filename, (set_title & 1), alert);
if(xctx->hilight_nets) { if(descend_ok) {
prepare_netlist_structs(0); if(xctx->hilight_nets) {
propagate_hilights(1, 0, XINSERT_NOREPLACE); 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); }
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') { if(xctx->rects[GRIDLAYER] > 0 && tcleval("info exists ngspice::ngspice_data")[0] == '0') {
Graph_ctx *gr = &xctx->graph_struct; Graph_ctx *gr = &xctx->graph_struct;
xRect *r = &xctx->rect[GRIDLAYER][0]; xRect *r = &xctx->rect[GRIDLAYER][0];
if(r->flags & 1) { if(r->flags & 1) {
backannotate_at_cursor_b_pos(r, gr); backannotate_at_cursor_b_pos(r, gr);
}
} }
} }
zoom_full(1, 0, 1 + 2 * tclgetboolvar("zoom_full_center"), 0.97); 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]; char filename[PATH_MAX];
int prev_sch_type; int prev_sch_type;
int confirm = what & 1; int confirm = what & 1;
int set_title = !(confirm & 2); int set_title = !(what & 2);
save_ok=1; save_ok=1;
dbg(1,"go_back(): sch[xctx->currsch]=%s\n", xctx->sch[xctx->currsch]); 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); dbg(1,"props=%s, txt=%s\n", props, txt);
create_text(draw_text, mx, my, 0, 0, txt, props, atof(hsize), atof(vsize)); 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 */ rebuild_selected_array(); /* sets xctx->ui_state |= SELECTION */
drawtemprect(xctx->gc[SELLAYER], END, 0.0, 0.0, 0.0, 0.0); 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); 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 == ButtonRelease && button == Button2) skip = 1;
/* else if(event == KeyPress && (state & ShiftMask)) skip = 1; */ /* else if(event == KeyPress && (state & ShiftMask)) skip = 1; */
else if(!skip) for(i=0; i< xctx->rects[GRIDLAYER]; ++i) { else if(!skip) for(i=0; i< xctx->rects[GRIDLAYER]; ++i) {
double lmargin;
xRect *r; xRect *r;
r = &xctx->rect[GRIDLAYER][i]; 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(!(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 = check =
(xctx->ui_state & GRAPHPAN) || (xctx->ui_state & GRAPHPAN) ||
(event != -3 && (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->x1, r->y1, r->x1 + 20, r->y1 + 8) ||
POINTINSIDE(xctx->mousex, xctx->mousey, r->x2 - 20, r->y2 - 8, r->x2, r->y2) 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 {", tclvareval("set INITIALINSTDIR [file dirname {",
abs_sym_path(tcl_hook2(xctx->inst[xctx->sel_array[0].n].name), ""), "}]", NULL); 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->mx_double_save = xctx->mousex_snap;
xctx->my_double_save = xctx->mousey_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 */) ) { 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); int access_cond = !graph_use_ctrl_key || (state & ControlMask);
dbg(1, "uistate=%d, graph_flags=%d\n", xctx->ui_state, xctx->graph_flags); 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 = state; /* rstate does not have ShiftMask bit, so easier to test for KeyPress events */
rstate &= ~ShiftMask; /* don't use ShiftMask, identifying characters is sufficient */ rstate &= ~ShiftMask; /* don't use ShiftMask, identifying characters is sufficient */
#if HAS_CAIRO==1 #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; if(gr->dataset >= 0 /* && gr->dataset < xctx->raw->datasets */) dataset =gr->dataset;
else dataset = -1; 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))) { get_tok_value(xctx->rect[GRIDLAYER][xctx->graph_master].prop_ptr, "sim_type", 0))) {
same_sim_type = 1; 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; 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 */ /* complete the STARTWIRE, STARTRECT, STARTZOOM, STARTCOPY ... operations */
static int end_place_move_copy_zoom() static int end_place_move_copy_zoom()
{ {
@ -1699,6 +1466,195 @@ static int end_place_move_copy_zoom()
return 0; 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) static void unselect_at_mouse_pos(int mx, int my)
{ {
xctx->last_command = 0; 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 */ 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; double x, y;
if(!(xctx->ui_state & STARTWIRE)){ if(!(xctx->ui_state & STARTWIRE)){
find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y); find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y);
xctx->mx_double_save = my_round(x / c_snap) * c_snap; xctx->mx_double_save = my_round(x / c_snap) * c_snap;
xctx->my_double_save = my_round(y / 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(PLACE, x, y);
new_wire(RUBBER, xctx->mousex_snap,xctx->mousey_snap); 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", 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); 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)) { else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTWIRE)) {
int prev_state = xctx->ui_state; int prev_state = xctx->ui_state;
if(xctx->semaphore >= 2) return 0; if(xctx->semaphore >= 2) return 0;
start_wire(xctx->mousex_snap, xctx->mousey_snap); if( state & ShiftMask) {
if(prev_state == STARTWIRE) { snapped_wire(c_snap);
tcleval("set constr_mv 0" ); } else {
xctx->constr_mv=0; 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 #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) static void handle_enter_notify(int draw_xhair, int crosshair_size)
{ {
struct stat buf; struct stat buf;
@ -2477,9 +2486,8 @@ static void handle_motion_notify(int event, KeySym key, int state, int rstate, i
} }
if(draw_xhair) { if(draw_xhair) {
draw_crosshair(1, state); /* when moving mouse: first action is delete crosshair, will be drawn later */ 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 */ /* pan schematic */
if(xctx->ui_state & STARTPAN) pan(RUBBER, mx, my); 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) { if(draw_xhair) {
draw_crosshair(2, state); /* locked UI: draw new crosshair and break out */ 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; return;
} }
@ -2588,7 +2596,7 @@ static void handle_motion_notify(int event, KeySym key, int state, int rstate, i
if(draw_xhair) { if(draw_xhair) {
draw_crosshair(2, state); /* what = 2(draw) */ 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; return;
} }
@ -2827,20 +2835,23 @@ static void handle_key_press(int event, KeySym key, int state, int rstate, int m
draw(); draw();
return; 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(); hilight_net_pin_mismatches();
return; 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; if(xctx->semaphore >= 2) return;
snapped_wire(c_snap); snapped_wire(c_snap);
return; return;
} }
if(key== 's' /* && !xctx->ui_state */ && rstate == 0 && cadence_compat) { /* create wire snapping to closest instance pin (cadence keybind) */ /* create wire snapping to closest instance pin (cadence keybind) */
if(xctx->semaphore >= 2) return; if(key== 's' /* && !xctx->ui_state */ && rstate == 0 && cadence_compat) {
snapped_wire(c_snap); if(xctx->semaphore >= 2) return;
return; snapped_wire(c_snap);
return;
} }
if(key == 'w' /* && !xctx->ui_state */ && rstate==0) /* place wire. */ 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) { if(xctx->ui_state2 & MENUSTARTWIRE) {
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) { if(tclgetboolvar("persistent_command") && (xctx->last_command & STARTWIRE) && cadence_compat) {
xctx->last_command &= ~STARTWIRE; xctx->last_command &= ~STARTWIRE;
if(snap_cursor) draw_snap_cursor(1);
} }
return; 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; if(xctx->semaphore >= 2) return;
ask_new_file(); ask_new_file();
xctx->semaphore--;
tcleval("load_additional_files");
xctx->semaphore++;
return; return;
} }
if(key=='S' && rstate == 0) /* change element order */ 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(); draw();
return; 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; 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); check_unique_names(1);
return; 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(key=='f' && rstate == ControlMask) /* search */
{ {
if(xctx->semaphore >= 2) return; if(xctx->semaphore >= 2) return;
@ -4215,7 +4218,7 @@ static void handle_button_press(int event, int state, int rstate, KeySym key, in
return; return;
} }
/* handle all object insertions started from Tools/Edit menu */ /* 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 */ /* complete the pending STARTWIRE, STARTRECT, STARTZOOM, STARTCOPY ... operations */
if(end_place_move_copy_zoom()) return; 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; int savesem = xctx->semaphore;
move_objects(ABORT, 0, 0.0, 0.0); move_objects(ABORT, 0, 0.0, 0.0);
unselect_all(1); 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); select_object(xctx->mousex, xctx->mousey, SELECTED, 0, NULL);
rebuild_selected_array(); rebuild_selected_array();
xctx->semaphore = 0; 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 */ /* 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; xctx->ui_state &= ~MENUSTART;
return; return;
} }
if(draw_xhair) draw_crosshair(3, state); /* restore crosshair when selecting / unselecting */ 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; return;
} }
@ -4634,7 +4637,7 @@ int wire_draw_active = (xctx->ui_state & STARTWIRE) ||
case LeaveNotify: case LeaveNotify:
if(draw_xhair) draw_crosshair(1, state); /* clear crosshair when exiting window */ 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); tclvareval(xctx->top_path, ".drw configure -cursor {}" , NULL);
xctx->mouse_inside = 0; xctx->mouse_inside = 0;
break; break;
@ -4678,6 +4681,8 @@ int wire_draw_active = (xctx->ui_state & STARTWIRE) ||
break; break;
case KeyRelease: 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; break;
case KeyPress: case KeyPress:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -513,6 +513,82 @@ void draw_selection(GC g, int interruptable)
xctx->movelastsel = i; 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) void copy_objects(int what)
{ {
int tmpi, c, i, n, k /*, tmp */ ; int tmpi, c, i, n, k /*, tmp */ ;
@ -881,6 +957,9 @@ void copy_objects(int what)
newpropcnt++; newpropcnt++;
new_prop_string(xctx->instances, xctx->inst[n].prop_ptr, /* sets also inst[].instname */ new_prop_string(xctx->instances, xctx->inst[n].prop_ptr, /* sets also inst[].instname */
tclgetboolvar("disable_unique_names")); tclgetboolvar("disable_unique_names"));
update_attached_floaters(xctx->inst[n].instname, xctx->instances, 1);
hash_names(xctx->instances, XINSERT); hash_names(xctx->instances, XINSERT);
xctx->instances++; /* symbol_bbox calls translate and translate must have updated xctx->instances */ xctx->instances++; /* symbol_bbox calls translate and translate must have updated xctx->instances */
symbol_bbox(xctx->instances-1, symbol_bbox(xctx->instances-1,

View File

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

View File

@ -48,7 +48,7 @@ static void merge_text(FILE *fd)
xctx->text[i].sel=0; xctx->text[i].sel=0;
load_ascii_string(&xctx->text[i].prop_ptr,fd); load_ascii_string(&xctx->text[i].prop_ptr,fd);
set_text_flags(&xctx->text[i]); set_text_flags(&xctx->text[i]);
select_text(i,SELECTED, 1); select_text(i,SELECTED, 1, 1);
xctx->texts++; xctx->texts++;
} }
@ -66,7 +66,7 @@ static void merge_wire(FILE *fd)
load_ascii_string( &ptr, fd); load_ascii_string( &ptr, fd);
storeobject(-1, x1,y1,x2,y2,WIRE,0,SELECTED,ptr); storeobject(-1, x1,y1,x2,y2,WIRE,0,SELECTED,ptr);
my_free(_ALLOC_ID_, &ptr); my_free(_ALLOC_ID_, &ptr);
select_wire(i, SELECTED, 1); select_wire(i, SELECTED, 1, 1);
} }
static void merge_box(FILE *fd) static void merge_box(FILE *fd)
@ -172,7 +172,7 @@ static void merge_arc(FILE *fd)
ptr[i].dash = 0; ptr[i].dash = 0;
} }
select_arc(c,i, SELECTED, 1); select_arc(c,i, SELECTED, 1, 1);
xctx->arcs[c]++; xctx->arcs[c]++;
} }
@ -232,7 +232,7 @@ static void merge_polygon(FILE *fd)
ptr[i].dash = 0; ptr[i].dash = 0;
} }
select_polygon(c,i, SELECTED, 1); select_polygon(c,i, SELECTED, 1, 1);
xctx->polygons[c]++; xctx->polygons[c]++;
} }
@ -271,7 +271,7 @@ static void merge_line(FILE *fd)
ptr[i].bus = 1; ptr[i].bus = 1;
else else
ptr[i].bus = 0; ptr[i].bus = 0;
select_line(c,i, SELECTED, 1); select_line(c,i, SELECTED, 1, 1);
xctx->lines[c]++; 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; 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 #if defined(HAS_LIBJPEG) && HAS_CAIRO==1
Zoom_info zi; Zoom_info zi;
double rw, rh, scale; 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; int quality=40;
const char *quality_attr; const char *quality_attr;
size_t oLength; size_t oLength;
int i; int j;
double sx1, sy1, sx2, sy2; double sx1, sy1, sx2, sy2;
/* screen position */ /* 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"); d_c = tclgetboolvar("dark_colorscheme");
tclsetboolvar("dark_colorscheme", 0); tclsetboolvar("dark_colorscheme", 0);
build_colors(0, 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); dbg(1, "width=%d, rwi=%d height=%d rhi=%d\n", xctx->xrect[0].width, rwi, xctx->xrect[0].height, rhi);
#ifdef __unix__ #ifdef __unix__
png_sfc = cairo_xlib_surface_create(display, xctx->save_pixmap, visual, 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_source_surface(ct, xctx->cairo_save_sfc, 0, 0);
cairo_set_operator(ct, CAIRO_OPERATOR_SOURCE); cairo_set_operator(ct, CAIRO_OPERATOR_SOURCE);
cairo_paint(ct); cairo_paint(ct);
for (i = 0; i < xctx->rects[GRIDLAYER]; ++i) { setup_graph_data(i, 0, &xctx->graph_struct);
xRect* r2 = &xctx->rect[GRIDLAYER][i]; draw_graph(i, 8 + (xctx->graph_flags & (4 | 2 | 128 | 256)), &xctx->graph_struct, (void *)ct);
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);
}
}
#endif #endif
cairo_image_surface_write_to_jpeg_mem(png_sfc, &jpgData, &fileSize, quality); 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"); fprintf(fd, "} exec\n");
#if 1 /* break lines */ #if 1 /* break lines */
for (i = 0; i < oLength; ++i) for (j = 0; j < oLength; ++j)
{ {
fputc(ascii85EncodedJpeg[i],fd); fputc(ascii85EncodedJpeg[j],fd);
if(i > 0 && (i % 64) == 0) if(j > 0 && (j % 64) == 0)
{ {
fputc('\n',fd); fputc('\n',fd);
/* if (ascii85Encode[i+1]=='%') idx=63; imageMagic does this for some reason?! /* 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; continue;
} }
if (c == GRIDLAYER && (xctx->rect[c][i].flags & 1)) { /* graph */ if (c == GRIDLAYER && (xctx->rect[c][i].flags & 1)) { /* graph */
xRect* r = &xctx->rect[c][i]; xRect *r = &xctx->rect[c][i];
ps_embedded_graph(r, r->x1, r->y1, r->x2, r->y2); ps_embedded_graph(i, r->x1, r->y1, r->x2, r->y2);
} }
if(c != GRIDLAYER || !(xctx->rect[c][i].flags & 1) ) { if(c != GRIDLAYER || !(xctx->rect[c][i].flags & 1) ) {
ps_filledrect(c, xctx->rect[c][i].x1, xctx->rect[c][i].y1, 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; return res;
} }
dbg(1, "raw_read(): type=%s\n", type ? type : "<NULL>"); 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); fd = my_fopen(f, fopen_read_mode);
if(fd) { 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) { if((res = read_dataset(fd, rawptr, type, no_warning)) == 1) {
int i; int i;
set_modify(-2); /* clear text floater caches */ 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; xRect *r;
r = &xctx->rect[GRIDLAYER][0]; r = &xctx->rect[GRIDLAYER][0];
if(r->flags & 1) { if(r->flags & 1) {
setup_graph_data(0, 0, &xctx->graph_struct); /* don't overwrite xctx->graph_struct, being used in draw_graph() which calls raw_read() */
backannotate_at_cursor_b_pos(r, &xctx->graph_struct); Graph_ctx gr_ctx;
setup_graph_data(0, 0, &gr_ctx);
backannotate_at_cursor_b_pos(r, &gr_ctx);
} }
} }
} }
} else { } else {
/* free_rawfile(rawptr, 0, 0); */ /* do not free: already done in read_dataset()->extra_rawfile() */ /* free_rawfile(rawptr, 0, 0); */ /* do not free: already done in read_dataset()->extra_rawfile() */
if(!no_warning) { if(!no_warning) {
@ -1074,6 +1074,22 @@ int raw_read(const char *f, Raw **rawptr, const char *type, int no_warning, doub
return 0; 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 raw_deletevar(const char *name)
{ {
int ret = 0; 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(what == 0) return 0;
/* if not already done insert base raw file (if there is one) into xctx->extra_raw_arr[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) { 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_arr[xctx->extra_raw_n] = xctx->raw;
xctx->extra_raw_n++; 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) { if(!no_warning) {
dbg(0, "extra_rawfile() read: %s not found or no \"%s\" analysis\n", f, type ? type : "<unspecified>"); 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->raw = save; /* restore */
xctx->extra_prev_idx = xctx->extra_idx; 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)); 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, name);
#else #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 #endif
my_free(_ALLOC_ID_, &tmp); my_free(_ALLOC_ID_, &tmp);
if(fscanf(fd, "%lf %lf %hd %hd", &xctx->inst[i].x0, &xctx->inst[i].y0, 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); Tcl_SetResult(interp, (char *)get_cell_w_ext(argv[2], atoi(argv[3])), TCL_VOLATILE);
} }
} }
/************ end xschem get subcommands *************/ /************ 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|instance_pin|symbol|text ref
* *
* getprop instance inst * 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), "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_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), "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), "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_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); 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") ) else if(!strcmp(argv[1], "load") )
{ {
int load_symbols = 1, force = 1, undo_reset = 1, nofullzoom = 0, nodraw = 0; int load_symbols = 1, force = 1, undo_reset = 1, nofullzoom = 0, nodraw = 0;
int keep_symbols = 0; int keep_symbols = 0, first;
size_t i; int i;
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;} if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
for(i = 2; i < argc; i++) { for(i = 2; i < argc; i++) {
if(argv[i][0] == '-') { if(argv[i][0] == '-') {
if(!strcmp(argv[i], "-nosymbols")) { if(!strcmp(argv[i], "-nosymbols")) {
@ -2912,8 +2938,12 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
break; break;
} }
} }
first = i;
if(argc>i) { if(argc==2) {
ask_new_file();
tcleval("load_additional_files");
} else
for(i = first; i < argc; i++) {
char f[PATH_MAX + 100]; char f[PATH_MAX + 100];
my_snprintf(f, S(f),"regsub {^~/} {%s} {%s/}", argv[i], home_dir); my_snprintf(f, S(f),"regsub {^~/} {%s} {%s/}", argv[i], home_dir);
tcleval(f); tcleval(f);
@ -2940,34 +2970,41 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
unselect_all(1); unselect_all(1);
/* no implicit undo: if needed do it before loading */ /* no implicit undo: if needed do it before loading */
/* if(!undo_reset) xctx->push_undo(); */ /* if(!undo_reset) xctx->push_undo(); */
if(undo_reset) xctx->currsch = 0; if(i == first) {
if(!keep_symbols) remove_symbols(); if(undo_reset) xctx->currsch = 0;
if(!nofullzoom) { if(!keep_symbols) remove_symbols();
xctx->zoom=CADINITIALZOOM; if(!nofullzoom) {
xctx->mooz=1/CADINITIALZOOM; xctx->zoom=CADINITIALZOOM;
xctx->xorigin=CADINITIALX; xctx->mooz=1/CADINITIALZOOM;
xctx->yorigin=CADINITIALY; xctx->xorigin=CADINITIALX;
xctx->yorigin=CADINITIALY;
}
} }
dbg(1, "scheduler: undo_reset=%d\n", undo_reset); 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(i > first) {
if(undo_reset) { ret = new_schematic("create", "noconfirm", f, 1);
tclvareval("update_recent_file {", f, "}", NULL); if(undo_reset) {
my_strdup(_ALLOC_ID_, &xctx->sch_path[xctx->currsch], "."); tclvareval("update_recent_file {", f, "}", NULL);
if(xctx->portmap[xctx->currsch].table) str_hash_free(&xctx->portmap[xctx->currsch]); }
str_hash_init(&xctx->portmap[xctx->currsch], HASHSIZE); } else {
xctx->sch_path_hash[xctx->currsch] = 0; ret = load_schematic(load_symbols, f, undo_reset, !force);
xctx->sch_inst_number[xctx->currsch] = 1; 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); 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; int cancel = 0;
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;} if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
if(argc > 2) { if(argc > 2) {
if(!is_from_web(argv[2])) { int i;
my_snprintf(f, S(f),"regsub {^~/} {%s} {%s/}", argv[2], home_dir); for(i = 2; i < argc; i++) {
tcleval(f); if(!is_from_web(argv[i])) {
/* tclvareval("file normalize {", tclresult(), "}", NULL); */ my_snprintf(f, S(f),"regsub {^~/} {%s} {%s/}", argv[i], home_dir);
my_strncpy(f, abs_sym_path(tclresult(), ""), S(f)); tcleval(f);
} else { /* tclvareval("file normalize {", tclresult(), "}", NULL); */
my_strncpy(f, argv[2], S(f)); 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 { } else {
tcleval("load_file_dialog {Load file} *.\\{sch,sym,tcl\\} INITIALLOADDIR"); 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 { } else {
cancel = 1; cancel = 1;
} }
} if(!cancel) {
if(!cancel) { if(f[0]) {
if(f[0]) { dbg(1, "f=%s\n", f);
dbg(1, "f=%s\n", f); new_schematic("create", "noconfirm", f, 1);
new_schematic("create", "noconfirm", f, 1); tclvareval("update_recent_file {", f, "}", NULL);
tclvareval("update_recent_file {", f, "}", NULL); } else {
} else { new_schematic("create", NULL, NULL, 1);
new_schematic("create", NULL, NULL, 1); }
} }
} }
Tcl_ResetResult(interp); Tcl_ResetResult(interp);
@ -3604,7 +3660,6 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
tclvareval("set INITIALINSTDIR [file dirname {", tclvareval("set INITIALINSTDIR [file dirname {",
abs_sym_path(tcl_hook2(xctx->inst[xctx->sel_array[0].n].name), ""), "}]", NULL); 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->mx_double_save = xctx->mousex_snap;
xctx->my_double_save = xctx->mousey_snap; xctx->my_double_save = xctx->mousey_snap;
if(argc > 3) { if(argc > 3) {
@ -3969,8 +4024,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
case 'r': /*----------------------------------------------*/ case 'r': /*----------------------------------------------*/
/* raw what ... /* raw what ...
* what = add | clear | datasets | index | info | loaded | list | new | points | rawfile | del | * what = add | clear | datasets | index | info | loaded | list |
* read | set | sim_type | switch | switch_back | table_read | value | values | pos_at | vars | * 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]] * xschem raw read filename [type [sweep1 sweep2]]
* if sweep1, sweep2 interval is given in 'read' subcommand load only the interval * 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 * xschem raw del name
* delete named vector from current raw file * 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 * xschem raw info
* print information about loaded raw files and show the currently active one. * 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. * new dataset do not start with a header row.
* Lines beginning with '#' are comments and ignored * 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 * # this is a comment, ignored
* 0.0 0.0 1.8 0.3 * 0.0 0.0 1.8 0.3
* <single empty line: ignored> * <single empty line: ignored>
@ -4129,9 +4188,6 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
update_op(); update_op();
} }
Tcl_SetResult(interp, my_itoa(ret), TCL_VOLATILE); 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")) { } else if(argc > 2 && !strcmp(argv[2], "clear")) {
if(argc > 4) { if(argc > 4) {
ret = extra_rawfile(3, argv[3], argv[4], -1.0, -1.0); 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); 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")) { } else if(argc > 3 && !strcmp(argv[2], "index")) {
/* xschem raw index v(ldcp) */ /* xschem raw index v(ldcp) */
int idx; int idx;
@ -4960,7 +5022,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
int n=atoi(argv[3]); int n=atoi(argv[3]);
int valid = n < xctx->wires && n >= 0; int valid = n < xctx->wires && n >= 0;
if(valid) { if(valid) {
select_wire(n, sel, fast); select_wire(n, sel, fast, 1);
xctx->ui_state |= SELECTION; xctx->ui_state |= SELECTION;
} }
Tcl_SetResult(interp, valid ? "1" : "0" , TCL_STATIC); 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 n=atoi(argv[4]);
int valid = n < xctx->lines[c] && n >= 0 && c < cadlayers && c >= 0; int valid = n < xctx->lines[c] && n >= 0 && c < cadlayers && c >= 0;
if(valid) { if(valid) {
select_line(c, n, sel, fast); select_line(c, n, sel, fast, 0);
xctx->ui_state |= SELECTION; xctx->ui_state |= SELECTION;
} }
Tcl_SetResult(interp, valid ? "1" : "0" , TCL_STATIC); 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 n=atoi(argv[4]);
int valid = n < xctx->arcs[c] && n >= 0 && c < cadlayers && c >= 0; int valid = n < xctx->arcs[c] && n >= 0 && c < cadlayers && c >= 0;
if(valid) { if(valid) {
select_arc(c, n, sel, fast); select_arc(c, n, sel, fast, 0);
xctx->ui_state |= SELECTION; xctx->ui_state |= SELECTION;
} }
Tcl_SetResult(interp, valid ? "1" : "0" , TCL_STATIC); 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 n=atoi(argv[4]);
int valid = n < xctx->polygons[c] && n >= 0 && c < cadlayers && c >= 0; int valid = n < xctx->polygons[c] && n >= 0 && c < cadlayers && c >= 0;
if(valid) { if(valid) {
select_polygon(c, n, sel, fast); select_polygon(c, n, sel, fast, 0);
xctx->ui_state |= SELECTION; xctx->ui_state |= SELECTION;
} }
Tcl_SetResult(interp, valid ? "1" : "0" , TCL_STATIC); 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 n=atoi(argv[3]);
int valid = n < xctx->texts && n >= 0; int valid = n < xctx->texts && n >= 0;
if(valid) { if(valid) {
select_text(n, sel, fast); select_text(n, sel, fast, 0);
xctx->ui_state |= SELECTION; xctx->ui_state |= SELECTION;
} }
Tcl_SetResult(interp, valid ? "1" : "0" , TCL_STATIC); 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 { } else {
char *translated_sym = NULL; char *translated_sym = NULL;
int sym_number = -1; int sym_number = -1;
char *subst = NULL; char *subst = NULL, *old_name = NULL;;
if(!fast) { if(!fast) {
symbol_bbox(inst, &xctx->inst[inst].x1, &xctx->inst[inst].y1, &xctx->inst[inst].x2, &xctx->inst[inst].y2); symbol_bbox(inst, &xctx->inst[inst].x1, &xctx->inst[inst].y1, &xctx->inst[inst].x2, &xctx->inst[inst].y2);
xctx->push_undo(); 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_hash_inst=0;
xctx->prep_net_structs=0; xctx->prep_net_structs=0;
xctx->prep_hi_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(argc > 5) {
if(!strcmp(argv[4], "allprops")) { if(!strcmp(argv[4], "allprops")) {
hash_names(-1, XINSERT); hash_names(-1, XINSERT);
@ -5486,7 +5554,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
} }
hash_names(inst, XDELETE); hash_names(inst, XDELETE);
new_prop_string(inst, subst, tclgetboolvar("disable_unique_names")); 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)); my_strdup2(_ALLOC_ID_, &translated_sym, translate(inst, xctx->inst[inst].name));
sym_number=match_symbol(translated_sym); 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; xctx->inst[inst].ptr=sym_number;
} }
if(subst) my_free(_ALLOC_ID_, &subst); if(subst) my_free(_ALLOC_ID_, &subst);
if(old_name) my_free(_ALLOC_ID_, &old_name);
set_inst_flags(&xctx->inst[inst]); set_inst_flags(&xctx->inst[inst]);
hash_names(inst, XINSERT); hash_names(inst, XINSERT);
if(!fast) { if(!fast) {
@ -5927,22 +5998,22 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
select_element(n, SELECTED, 1, 1); select_element(n, SELECTED, 1, 1);
break; break;
case WIRE: case WIRE:
select_wire(n, SELECTED, 1); select_wire(n, SELECTED, 1, 1);
break; break;
case xTEXT: case xTEXT:
select_text(n, SELECTED, 1); select_text(n, SELECTED, 1, 1);
break; break;
case xRECT: case xRECT:
select_box(c, n, SELECTED, 1, 0); select_box(c, n, SELECTED, 1, 1);
break; break;
case LINE: case LINE:
select_line(c, n, SELECTED, 1); select_line(c, n, SELECTED, 1, 1);
break; break;
case POLYGON: case POLYGON:
select_polygon(c, n, SELECTED, 1); select_polygon(c, n, SELECTED, 1, 1);
break; break;
case ARC: case ARC:
select_arc(c, n, SELECTED, 1); select_arc(c, n, SELECTED, 1, 1);
break; break;
} }
} }
@ -6215,6 +6286,14 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
Tcl_ResetResult(interp); 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_sym_bboxes
* Update all symbol bounding boxes */ * Update all symbol bounding boxes */
else if(!strcmp(argv[1], "update_all_sym_bboxes")) 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 = -1 : clear first selected info
* n = -2 : return first selected element if still selected, or get first from * 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 * n >= 0 : store indicated element as first selected
*/ */
int set_first_sel(unsigned short type, int n, unsigned int col) 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 */ char str[1024]; /* overflow safe */
/*my_strncpy(s,xctx->wire[i].prop_ptr!=NULL?xctx->wire[i].prop_ptr:"<NULL>",256); */ /*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 ) if( !fast )
{ {
my_snprintf(str, S(str), "Info: selected wire: n=%d end1=%d end2=%d\nnode=%s",i, 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; 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 == 1: do not update status line
* fast == 2: do not draw / undraw selected elements * fast == 2: do not draw / undraw selected elements
* fast == 3: 1 + 2 * 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; 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 str[1024]; /* overflow safe */
char s[256]; /* overflow safe */ char s[256]; /* overflow safe */
#if HAS_CAIRO==1 #if HAS_CAIRO==1
int customfont; int customfont;
#endif #endif
if(!strboolcmp(get_tok_value(xctx->text[i].prop_ptr, "lock", 0), "true") &&
select_mode == SELECTED && !override_lock) return;
if(!fast) { if(!fast) {
my_strncpy(s,xctx->text[i].prop_ptr!=NULL?xctx->text[i].prop_ptr:"<NULL>",S(s)); 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); 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 str[1024]; /* overflow safe */
char s[256]; /* 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; 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 str[1024]; /* overflow safe */
char s[256]; /* overflow safe */ char s[256]; /* overflow safe */
int bezier; int bezier;
if(!strboolcmp(get_tok_value(xctx->poly[c][i].prop_ptr, "lock", 0), "true") &&
select_mode == SELECTED && !override_lock) return;
if(!fast) if(!fast)
{ {
my_strncpy(s,xctx->poly[c][i].prop_ptr!=NULL?xctx->poly[c][i].prop_ptr:"<NULL>",S(s)); 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; 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 str[1024]; /* overflow safe */
char s[256]; /* 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) if(!fast)
{ {
my_strncpy(s,xctx->line[c][i].prop_ptr!=NULL?xctx->line[c][i].prop_ptr:"<NULL>",S(s)); 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: case WIRE:
if(xctx->wire[sel.n].sel) xctx->already_selected = 1; 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; break;
case xTEXT: case xTEXT:
if(xctx->text[sel.n].sel) xctx->already_selected = 1; 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; break;
case LINE: case LINE:
if(xctx->line[sel.col][sel.n].sel) xctx->already_selected = 1; 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; break;
case POLYGON: case POLYGON:
if(xctx->poly[sel.col][sel.n].sel) xctx->already_selected = 1; 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; break;
case xRECT: case xRECT:
if(xctx->rect[sel.col][sel.n].sel) xctx->already_selected = 1; 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; break;
case ARC: case ARC:
if(xctx->arc[sel.col][sel.n].sel) xctx->already_selected = 1; 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; break;
case ELEMENT: case ELEMENT:
if(xctx->inst[sel.n].sel) xctx->already_selected = 1; 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; break;
default: default:
break; break;
@ -1260,10 +1335,10 @@ void select_attached_nets(void)
for(wptr=xctx->wire_spatial_table[sqx][sqy]; wptr; wptr=wptr->next) { for(wptr=xctx->wire_spatial_table[sqx][sqy]; wptr; wptr=wptr->next) {
i = wptr->n; i = wptr->n;
if(xctx->wire[i].x1 == x0 && xctx->wire[i].y1 == y0) { 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) { 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; i = wptr->n;
if(i == wire) continue; if(i == wire) continue;
if(xctx->wire[i].x1 == x0 && xctx->wire[i].y1 == y0) { 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) { 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)) 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 ???? */ 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) ) else if(stretch && POINTINSIDE(xctx->wire[i].x1,xctx->wire[i].y1, x1,y1,x2,y2) )
{ {
xctx->ui_state |= SELECTION; 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) ) else if(stretch && POINTINSIDE(xctx->wire[i].x2,xctx->wire[i].y2, x1,y1,x2,y2) )
{ {
xctx->ui_state |= SELECTION; xctx->ui_state |= SELECTION;
select_wire(i, SELECTED2, 1); select_wire(i, SELECTED2, 1, 0);
} }
} else { } else {
if(RECT_INSIDE(xctx->wire[i].x1,xctx->wire[i].y1,xctx->wire[i].x2,xctx->wire[i].y2, x1,y1,x2,y2)) 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 ???? */ 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)) 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 ???? */ 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) 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 ???? */ xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
if(sel) { if(sel) {
if(strboolcmp(get_tok_value(xctx->inst[i].prop_ptr, "lock", 0), "true")) { select_element(i, SELECTED, 1, 0);
select_element(i, SELECTED, 1, 1);
}
} else { } else {
select_element(i, 0, 1, 0); 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(flag) {
if(selected_points==0) { 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) { if(selected_points==xctx->poly[c][i].points) {
xctx->ui_state |= SELECTION; xctx->ui_state |= SELECTION;
select_polygon(c, i, SELECTED, 1); select_polygon(c, i, SELECTED, 1, 0);
} else if(selected_points) { } else if(selected_points) {
/* for polygon, SELECTED1 means partial sel */ /* 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)) 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; 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) ) 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 ???? */ 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) ) else if(stretch && POINTINSIDE(xctx->line[c][i].x2,xctx->line[c][i].y2, x1,y1,x2,y2) )
{ {
xctx->ui_state |= SELECTION; xctx->ui_state |= SELECTION;
select_line(c, i,SELECTED2,1); select_line(c, i, SELECTED2, 1, 0);
} }
} else { } 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)) 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; 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); 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)) { 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 ???? */ 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) ) 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 ???? */ 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) ) 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 ???? */ 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) ) 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 ???? */ 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) 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(sel) {
if(strboolcmp(get_tok_value(xctx->rect[c][i].prop_ptr, "lock", 0), "true")) { select_box(c,i, SELECTED, 1, 0);
select_box(c,i, SELECTED, 1, 1);
}
} else { } else {
select_box(c,i, 0, 1, 0); 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; ly2 = xctx->wire[i].y2;
if(lineclip(&lx1, &ly1, &lx2, &ly2, x1,y1,x2,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 ???? */ 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) 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)) 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 ???? */ 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) 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 ???? */ xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
if(sel) { if(sel) {
if(strboolcmp(get_tok_value(xctx->inst[i].prop_ptr, "lock", 0), "true")) { select_element(i, SELECTED, 1, 0);
select_element(i, SELECTED, 1, 1);
}
} else { } else {
select_element(i, 0, 1, 0); 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) { 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) 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; ly2 = xctx->line[c][i].y2;
if(lineclip(&lx1, &ly1, &lx2, &ly2, x1,y1,x2,y2)) { if(lineclip(&lx1, &ly1, &lx2, &ly2, x1,y1,x2,y2)) {
xctx->ui_state |= SELECTION; 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) { 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); 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)) { 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 ???? */ 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) 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 ???? */ xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */
if(sel) { if(sel) {
if(strboolcmp(get_tok_value(xctx->rect[c][i].prop_ptr, "lock", 0), "true")) { select_box(c,i, SELECTED, 1, 0);
select_box(c,i, SELECTED, 1, 1);
}
} else { } else {
select_box(c,i, 0, 1, 0); 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, my_strdup2(_ALLOC_ID_, &xctx->inst[i].prop_ptr,
subst_token(xctx->inst[i].prop_ptr, "hide_texts", "true")); 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]); set_inst_flags(&xctx->inst[i]);
for(t = 0; t < sym->texts; t++) { for(t = 0; t < sym->texts; t++) {
double txtx0, txty0; double txtx0, txty0;
@ -1730,33 +1799,35 @@ void select_all(void)
for(i=0;i<xctx->wires; ++i) 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) 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) 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(c=0;c<cadlayers; ++c)
{ {
for(i=0;i<xctx->polygons[c]; ++i) 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) 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) 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) 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 */ } /* end for c */
drawtemparc(xctx->gc[SELLAYER], END, 0.0, 0.0, 0.0, 0.0, 0.0); 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 */ if(xctx->rect[c][i].flags & 1) { /* graph */
xRect *r = &xctx->rect[c][i]; 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; int i,found;
found=0; found=0;
dbg(1, "match_symbol(): name=%s\n", name);
for(i=0;i<xctx->symbols; ++i) { for(i=0;i<xctx->symbols; ++i) {
/* dbg(1, "match_symbol(): name=%s, sym[i].name=%s\n",name, xctx->sym[i].name);*/ /* 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) 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(....) */ my_strdup2(_ALLOC_ID_, &result, tcl_hook2(result)); /* tcl evaluation if tcleval(....) */
if(strstr(result, "expr(") ) { if(strstr(result, "expr(")) {
result = eval_expr(result); my_strdup2(_ALLOC_ID_, &result, eval_expr(result));
} }
dbg(1, "print_vhdl_primitive(): after translate3() result=%s\n", 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; const char *str_ptr=NULL;
register int c, state=TOK_BEGIN, space; register int c, state=TOK_BEGIN, space;
char *template=NULL,*format=NULL, *s, *name=NULL, *token=NULL; 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; */ /* char *translatedvalue = NULL; */
size_t sizetok=0; size_t sizetok=0;
size_t token_pos=0; size_t token_pos=0;
@ -2462,8 +2464,8 @@ int print_spice_element(FILE *fd, int inst)
value = spiceprefixtag; value = spiceprefixtag;
} }
if(strstr(value, "expr(") ) { if(strstr(value, "expr(")) {
value = eval_expr(value); value = eval_expr(value);
} }
/* token=%xxxx and xxxx is not defined in prop_ptr or template: return xxxx */ /* token=%xxxx and xxxx is not defined in prop_ptr or template: return xxxx */
if(!token_exists && token[0] =='%') { if(!token_exists && token[0] =='%') {
@ -2517,8 +2519,8 @@ int print_spice_element(FILE *fd, int inst)
if(result) { if(result) {
my_strdup(_ALLOC_ID_, &result, tcl_hook2(result)); my_strdup(_ALLOC_ID_, &result, tcl_hook2(result));
} }
if(strstr(result, "expr(") ) { if(strstr(result, "expr(")) {
result = eval_expr(result); my_strdup2(_ALLOC_ID_, &result, eval_expr(result));
} }
if(result) fprintf(fd, "%s", result); if(result) fprintf(fd, "%s", result);
dbg(1, "print_spice_element(): returning |%s|\n", 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(....) */ my_strdup2(_ALLOC_ID_, &result, tcl_hook2(result)); /* tcl evaluation if tcleval(....) */
if(strstr(result, "expr(") ) { if(strstr(result, "expr(")) {
result = eval_expr(result); my_strdup2(_ALLOC_ID_, &result, eval_expr(result));
} }
dbg(1, "print_verilog_primitive(): after translate3() result=%s\n", 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 */ /* 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 */ /* ex.: name=@name w=@w l=@l ---> name=m112 w=3e-6 l=0.8e-6 */
/* if s==NULL return emty string */ /* if s==NULL return emty string */

View File

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

View File

@ -163,8 +163,8 @@ extern char win_temp_dir[PATH_MAX];
#define CADINITIALY -870 #define CADINITIALY -870
#define CADZOOMSTEP 1.2 #define CADZOOMSTEP 1.2
#define CADMOVESTEP 200 #define CADMOVESTEP 200
#define CADMAXZOOM 1000000.0 #define CADMAXZOOM 10000.0
#define CADMINZOOM 0.000001 #define CADMINZOOM 0.005
#define CADHALFDOTSIZE 3.7 #define CADHALFDOTSIZE 3.7
#define CADNULLNODE -1 /* no valid node number */ #define CADNULLNODE -1 /* no valid node number */
#define CADWIREMINDIST 8.0 #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) * show_label also used on metal option type symbols (pass-through symbols)
* to optionally short two nets (using *_ignore=[true|false] attribute) */ * 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") && \ #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") && \ #define IS_LABEL_OR_PIN(type) (!(strcmp(type,"label") && strcmp(type,"ipin") && \
strcmp(type,"opin") && strcmp(type,"iopin"))) strcmp(type,"opin") && strcmp(type,"iopin")))
#define IS_PIN(type) (!(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 lastsel;
int maxsel; int maxsel;
Selected *sel_array; 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_net_structs;
int prep_hi_structs; int prep_hi_structs;
int prep_hash_inst; 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 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_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_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 raw_deletevar(const char *name);
extern int new_rawfile(const char *name, const char *type, const char *sweepvar, extern int new_rawfile(const char *name, const char *type, const char *sweepvar,
double start, double end, double step); 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 void calc_drawing_bbox(xRect *boundbox, int selected);
extern int ps_draw(int what, int fullzoom, int eps); extern int ps_draw(int what, int fullzoom, int eps);
extern void svg_draw(void); 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 set_viewport_size(int w, int h, double lw);
extern void print_image(); extern void print_image();
extern const char *get_trailing_path(const char *str, int no_of_dir, int skip_ext); 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 int Tcl_AppInit(Tcl_Interp *interp);
extern void abort_operation(void); extern void abort_operation(void);
extern void draw_crosshair(int what, int state); 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 backannotate_at_cursor_b_pos(xRect *r, Graph_ctx *gr);
/* extern void snapped_wire(double c_snap); */ /* 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, extern int callback(const char *win_path, int event, int mx, int my, KeySym key,
int button, int aux, int state); int button, int aux, int state);
extern void resetwin(int create_pixmap, int clear_pixmap, int force, int w, int h); 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 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, 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); 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 move_objects(int what,int merge, double dx, double dy);
extern void check_collapsing_objects(); extern void check_collapsing_objects();
extern void redraw_w_a_l_r_p_z_rubbers(int force); /* redraw wire, arcs, line, polygon rubbers */ 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 char *find_nth(const char *str, const char *sep, const char *quote, int keep_quote, int n);
extern int isonlydigit(const char *s); extern int isonlydigit(const char *s);
extern const char *spice_get_node(const char *token); 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 *translate(int inst, const char* s);
extern const char* translate2(Lcc *lcc, int level, 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, 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 parse(const char *s);
extern void clear_expandlabel_data(void); extern void clear_expandlabel_data(void);
extern void merge_file(int selection_load, const char ext[]); 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_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_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_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); 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 ); 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 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 record_global_node(int what, FILE *fp, const char *node);
extern int count_items(const char *s, const char *sep, const char *quote); 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 ## convert number to engineering form
proc to_eng {args} { proc to_eng {args} {
set suffix {} set suffix {}
if {[ catch {uplevel #0 expr [join $args]} i]} {
return [join $args]
}
set i [uplevel #0 expr [join $args]] set i [uplevel #0 expr [join $args]]
set absi [expr {abs($i)}] set absi [expr {abs($i)}]
@ -1836,6 +1840,7 @@ proc simconf_add {tool} {
############ cellview ############ cellview
# proc cellview prints symbol bindings (default binding or "schematic" attr in symbol) # proc cellview prints symbol bindings (default binding or "schematic" attr in symbol)
# of all symbols used in current and sub schematics. # 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} { proc cellview_setlabels {w symbol derived_symbol} {
global dark_gui_colorscheme netlist_type global dark_gui_colorscheme netlist_type
if {$dark_gui_colorscheme} { if {$dark_gui_colorscheme} {
@ -1937,6 +1942,8 @@ proc cellview_edit_sym {w} {
xschem load_new_window $sym 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}} { proc cellview { {derived_symbols {}} {upd 0}} {
global keep_symbols nolist_libs dark_gui_colorscheme netlist_type 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] set save_netlist_type [xschem get netlist_type]
# puts "traversal_setlabels: $w parent: |$parent_sch| inst: $instname def: $sym_sch $inst_sch --> [$w get]" # puts "traversal_setlabels: $w parent: |$parent_sch| inst: $instname def: $sym_sch $inst_sch --> [$w get]"
# update schematic # 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] set current [xschem get current_name]
if { $inst_sch ne [$w get] } { if { $inst_sch ne [$w get] } {
puts "update attr"
xschem load -undoreset -nodraw $parent_sch xschem load -undoreset -nodraw $parent_sch
if { [$w get] eq $sym_sch} { if { [$w get] eq $sym_sch} {
xschem setprop -fast instance $instname schematic ;# remove schematic attr on instance 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 instances [xschem get instances]
set current_level [xschem get currsch] set current_level [xschem get currsch]
for {set i 0} { $i < $instances} { incr i} { 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 instname [xschem getprop instance $i name]
set symbol [xschem getprop instance $i cell::name] set symbol [xschem getprop instance $i cell::name]
set default_sch [add_ext $symbol .sch] set default_sch [add_ext $symbol .sch]
@ -2301,8 +2308,10 @@ proc hier_traversal {{level 0} {only_subckts 0} {all_hierarchy 1}} {
if {$descended} { if {$descended} {
incr level incr level
set dp [hier_traversal $level $only_subckts 1] set dp [hier_traversal $level $only_subckts 1]
xschem go_back 1 xschem go_back 2
incr level -1 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} { proc file_dialog_right_listboxselect {dirselect} {
global file_dialog_yview file_dialog_dir1 file_dialog_dir2 file_dialog_retval file_dialog_sel 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 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_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 {} } { if { $file_dialog_sel ne {} } {
set curr_dir [abs_sym_path [lindex $file_dialog_files1 $file_dialog_index1]] 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] 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_dir1 $curr_dir
set file_dialog_dir2 $curr_item 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]} { if { [file isdirectory $file_dialog_d]} {
bind .load.l.paneright.draw <Expose> {} bind .load.l.paneright.draw <Expose> {}
bind .load.l.paneright.draw <Configure> {} 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 # global_initdir: name of global variable containing the initial directory
# loadfile: set to 0 if calling for saving instead of loading a file # loadfile: set to 0 if calling for saving instead of loading a file
# set to 2 for non blocking operation (symbol insertion) # 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.f $optnever
eval .load.l.paneright paneconfigure .load.l.paneright.draw $optalways 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\ listbox .load.l.paneright.f.list -background {grey90} -listvariable file_dialog_files2 -width 20 -height 12\
-fg black -highlightcolor red -highlightthickness 2 \ -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 -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.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 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] # wm transient $window [xschem get topwindow]
frame $window.buttons frame $window.buttons
pack $window.buttons -side bottom -fill x -pady 2m 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 " button $window.buttons.ok -text OK -command "
set retval \[$window.text get 1.0 {end - 1 chars}\]; destroy $window set retval \[$window.text get 1.0 {end - 1 chars}\]; destroy $window
" "
button $window.buttons.cancel -text Cancel -command "destroy $window" button $window.buttons.cancel -text Cancel -command "destroy $window"
pack $window.buttons.ok -side left -expand 1 pack $window.buttons.ok -side left -expand 1
pack $window.buttons.cancel -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 \ 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 -xscrollcommand \"$window.xscroll set\" -wrap none -height 30 $text_tabs_setting
@ -6744,8 +6785,14 @@ proc rel_sym_path {symbol} {
global OS pathlist env global OS pathlist env
regsub {^~/} $symbol ${env(HOME)}/ symbol regsub {^~/} $symbol ${env(HOME)}/ symbol
if {![regexp {^/} $symbol]} { if {$OS eq "Windows"} {
set symbol [pwd]/$symbol if {![regexp {^[A-Za-z]\:/} $symbol]} {
set symbol [pwd]/$symbol
}
} else {
if {![regexp {^/} $symbol]} {
set symbol [pwd]/$symbol
}
} }
set curr_dirname [pwd] set curr_dirname [pwd]
set name {} set name {}
@ -7848,42 +7895,34 @@ proc no_open_dialogs {} {
## "file_dialog_*" only one load_file_dialog window is allowed ## "file_dialog_*" only one load_file_dialog window is allowed
set tctx::global_list { set tctx::global_list {
PDK_ROOT PDK SKYWATER_MODELS SKYWATER_STDCELLS INITIALINSTDIR INITIALLOADDIR INITIALPROPDIR INITIALTEXTDIR PDK PDK_ROOT SKYWATER_MODELS
INITIALINSTDIR INITIALLOADDIR INITIALPROPDIR INITIALTEXTDIR XSCHEM_LIBRARY_PATH SKYWATER_STDCELLS XSCHEM_LIBRARY_PATH add_all_windows_drives auto_hilight
add_all_windows_drives auto_hilight auto_hilight_graph_nodes autofocus_mainwindow auto_hilight_graph_nodes autofocus_mainwindow autotrim_wires bespice_listen_port big_grid_points
autotrim_wires orthogonal_wiring snap_cursor bespice_listen_port big_grid_points bus_replacement_char cadgrid cadlayers bus_replacement_char cadence_compat cadgrid cadlayers cadsnap cairo_font_name cairo_font_scale
cadsnap cadence_compat cairo_font_name cairo_font_scale change_lw color_ps tctx::colors compare_sch constr_mv change_lw color_ps compare_sch constr_mv copy_cell crosshair_layer crosshair_size cursor_2_hook
copy_cell crosshair_layer crosshair_size cursor_2_hook snap_cursor_size custom_label_prefix custom_token custom_label_prefix custom_token dark_colors dark_colorscheme dark_gui_colorscheme delay_flag
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
dim_bg dim_value disable_unique_names do_all_inst draw_crosshair draw_window edit_prop_pos edit_prop_size edit_symbol_prop_new_sel editprop_sympath
draw_grid draw_grid_axes draw_window edit_prop_pos edit_prop_size en_hilight_conn_inst enable_dim_bg enable_stretch enter_text_default_geometry filetmp
edit_symbol_prop_new_sel editprop_sympath en_hilight_conn_inst enable_dim_bg enable_stretch fix_broken_tiled_fill flat_netlist fullscreen gaw_fd gaw_tcp_address graph_autoload graph_bus
enter_text_default_geometry filetmp fix_broken_tiled_fill flat_netlist fullscreen graph_change_done graph_dialog_default_geometry graph_digital graph_legend graph_linewidth_mult
gaw_fd gaw_tcp_address graph_autoload graph_bus graph_logx graph_logy graph_private_cursor graph_rainbow graph_schname graph_sel_color
graph_change_done graph_digital graph_dialog_default_geometry graph_sel_wave graph_selected graph_sort graph_unlocked graph_use_ctrl_key hide_empty_graphs
graph_legend graph_linewidth_mult graph_logx hide_symbols incr_hilight incremental_select infix_interface infowindow_text intuitive_interface
graph_logy graph_private_cursor graph_rainbow graph_schname graph_sel_color graph_sel_wave keep_symbols launcher_default_program light_colors line_width live_cursor2_backannotate
graph_selected graph_sort graph_unlocked graph_use_ctrl_key local_netlist_dir lvs_ignore lvs_netlist measure_text netlist_dir netlist_show netlist_type
hide_empty_graphs hide_symbols tctx::hsize no_ask_save no_change_attrs nolist_libs noprint_libs old_selected_tok only_probes
incr_hilight incremental_select infix_interface infowindow_text intuitive_interface orthogonal_wiring path pathlist persistent_command preserve_unchanged_attrs prev_symbol ps_colors
keep_symbols launcher_default_program ps_paper_size rainbow_colors recentfile retval retval_orig rotated_text search_case search_exact
light_colors line_width live_cursor2_backannotate local_netlist_dir lvs_ignore search_found search_schematic search_select search_value select_touch selected_tok
lvs_netlist measure_text netlist_dir netlist_show netlist_type no_ask_save show_hidden_texts show_infowindow show_infowindow_after_netlist simconf_default_geometry
no_change_attrs nolist_libs noprint_libs old_selected_tok only_probes path pathlist simconf_vpos simulate_bg snap_cursor snap_cursor_size spiceprefix split_files svg_colors
persistent_command preserve_unchanged_attrs prev_symbol ps_colors ps_paper_size rainbow_colors svg_font_name sym_txt symbol symbol_width tabstop tclcmd_txt tclstop tctx::colors tctx::hsize
tctx::rcode recentfile tctx::rcode tctx::vsize text_line_default_geometry text_replace_selection text_tabs_setting
retval retval_orig rotated_text search_case search_exact search_found search_schematic textwindow_fileid textwindow_filename textwindow_w toolbar_horiz toolbar_list toolbar_visible
search_select search_value select_touch selected_tok show_hidden_texts show_infowindow top_is_subckt transparent_svg undo_type unselect_partial_sel_wires use_cursor_for_selection
show_infowindow_after_netlist use_lab_wire use_label_prefix use_tclreadline user_wants_copy_cell verilog_2001 verilog_bitblast
simconf_default_geometry simconf_vpos simulate_bg spiceprefix split_files svg_colors viewdata_fileid viewdata_filename viewdata_w xschem_libs xschem_listen_port zoom_full_center
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
} }
## list of global arrays to save/restore on context switching ## list of global arrays to save/restore on context switching
@ -8268,7 +8307,7 @@ proc load_raw {{type {}}} {
proc build_widgets { {topwin {} } } { proc build_widgets { {topwin {} } } {
global XSCHEM_SHAREDIR tabbed_interface simulate_bg OS sim 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 recentfile color_ps transparent_svg menu_debug_var enable_stretch
global netlist_show flat_netlist split_files compare_sch intuitive_interface 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 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 \ $topwin.menubar.option add checkbutton -label "Draw persistent snap cursor" -variable snap_cursor \
-selectcolor $selectcolor -accelerator {Alt-Z} -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" \ $topwin.menubar.option add command -label "Replace \[ and \] for buses in SPICE netlist" \
-command { -command {
input_line "Enter two characters to replace default bus \[\] delimiters:" "set bus_replacement_char" 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 set change_lw 0
input_line "Enter linewidth (float):" "xschem line_width" 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 \ $topwin.menubar.view add checkbutton -label "Tabbed interface" -variable tabbed_interface \
-selectcolor $selectcolor -command setup_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 -command "xschem net_label 0" -accelerator Alt-Shift-L
$topwin.menubar.sym add command -label "Change selected inst. texts to floaters" \ $topwin.menubar.sym add command -label "Change selected inst. texts to floaters" \
-command "xschem floaters_from_selected_inst" -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" \ $topwin.menubar.sym add command -label "Print list of highlight nets" \
-command "xschem print_hilight_net 1" -accelerator J -command "xschem print_hilight_net 1" -accelerator J
$topwin.menubar.sym add command -label "Print list of highlight nets, with buses expanded" \ $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 constr_mv 0
set_ne unselect_partial_sel_wires 0 set_ne unselect_partial_sel_wires 0
set_ne load_file_dialog_fullpath 1 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. # if set show selected elements while dragging the selection rectangle.
# once selected these can not be unselected by retracting 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 draw_grid 1
set_ne big_grid_points 0 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 draw_grid_axes 1
set_ne persistent_command 0 set_ne persistent_command 0
set_ne intuitive_interface 1 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 #### enable to scale grid point size as done with lines at close zoom, default: 0
# set big_grid_points 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) #### enable drawing grid axes. Default: enabled (1)
# set draw_grid_axes 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, * This file is part of XSCHEM,
* a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit * a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit
@ -24,6 +24,15 @@ K {}
V {} V {}
S {} S {}
E {} 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 )} 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 -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} 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 {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 -260 1 0 {name=V1 value=0}
C {vsource.sym} 150 -210 1 0 {name=V2 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 {} V {}
S {} S {}
E {} E {}
L 2 105 -1005 105 -775 {} L 2 95 -1105 95 -875 {}
L 2 145 -1005 145 -775 {} L 2 135 -1105 135 -875 {}
L 2 185 -1005 185 -775 {} L 2 175 -1105 175 -875 {}
L 2 225 -1005 225 -775 {} L 2 215 -1105 215 -875 {}
L 2 265 -1005 265 -775 {} L 2 255 -1105 255 -875 {}
L 2 305 -1005 305 -775 {} L 2 295 -1105 295 -875 {}
L 2 345 -1005 345 -775 {} L 2 335 -1105 335 -875 {}
L 2 385 -1005 385 -775 {} L 2 375 -1105 375 -875 {}
L 2 65 -975 395 -975 {} L 2 55 -1075 385 -1075 {}
L 2 65 -935 395 -935 {} L 2 55 -1035 385 -1035 {}
L 2 65 -895 395 -895 {} L 2 55 -995 385 -995 {}
L 2 65 -855 395 -855 {} L 2 55 -955 385 -955 {}
L 2 65 -815 395 -815 {} L 2 55 -915 385 -915 {}
L 4 65 -1015 65 -755 {} L 4 55 -1115 55 -855 {}
L 4 55 -775 405 -775 {} L 4 45 -875 395 -875 {}
L 4 105 -775 105 -765 {} L 4 95 -875 95 -865 {}
L 4 145 -775 145 -765 {} L 4 135 -875 135 -865 {}
L 4 185 -775 185 -765 {} L 4 175 -875 175 -865 {}
L 4 225 -775 225 -765 {} L 4 215 -875 215 -865 {}
L 4 265 -775 265 -765 {} L 4 255 -875 255 -865 {}
L 4 305 -775 305 -765 {} L 4 295 -875 295 -865 {}
L 4 345 -775 345 -765 {} L 4 335 -875 335 -865 {}
L 4 385 -775 385 -765 {} L 4 375 -875 375 -865 {}
L 4 55 -815 65 -815 {} L 4 45 -915 55 -915 {}
L 4 55 -855 65 -855 {} L 4 45 -955 55 -955 {}
L 4 55 -895 65 -895 {} L 4 45 -995 55 -995 {}
L 4 55 -935 65 -935 {} L 4 45 -1035 55 -1035 {}
L 4 55 -975 65 -975 {} L 4 45 -1075 55 -1075 {}
L 4 610 -1100 630 -1140 {} L 4 610 -1100 630 -1140 {}
L 4 630 -1140 650 -1100 {} L 4 630 -1140 650 -1100 {}
L 4 650 -1100 670 -1140 {} L 4 650 -1100 670 -1140 {}
@ -83,13 +83,13 @@ L 4 960 -340 970 -340 {}
L 4 960 -340 970 -330 {} L 4 960 -340 970 -330 {}
L 4 970 -330 980 -340 {} L 4 970 -330 980 -340 {}
L 4 970 -340 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 y1 = -0.00068
y2 = 22 y2 = 22
divy = 6 divy = 6
subdivy=1 subdivy=1
x1=2.9358714e-05 x1=5e-10
x2=0.0010293582 x2=0.001
divx=8 divx=8
node="PANEL node="PANEL
LED" unitx=m LED" unitx=m
@ -104,13 +104,13 @@ autoload=0
sim_type=tran sim_type=tran
xrawfile=$netlist_dir/solar_panel.raw} 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 y1 = -0.0012
y2 = 6.8 y2 = 6.8
divy = 4 divy = 4
subdivy=1 subdivy=1
x1=2.9358714e-05 x1=5e-10
x2=0.0010293582 x2=0.001
divx=8 divx=8
unitx=m unitx=m
color="7 4 6" color="7 4 6"
@ -123,13 +123,13 @@ autoload=0
sim_type=tran sim_type=tran
xrawfile=$netlist_dir/solar_panel.raw} 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 y1 = -2.7e-05
y2 = 100 y2 = 100
divy = 5 divy = 5
subdivy=1 subdivy=1
x1=2.9358714e-05 x1=5e-10
x2=0.0010293582 x2=0.001
divx=9 divx=9
unitx=m subdivx=4 unitx=m subdivx=4
@ -146,13 +146,13 @@ autoload=0
sim_type=tran sim_type=tran
xrawfile=$netlist_dir/solar_panel.raw} xrawfile=$netlist_dir/solar_panel.raw}
B 2 1260 -940 1680 -750 {flags=graph B 2 1370 -935 1790 -745 {flags=graph
y1 = 0 y1 = 0
y2 = 1 y2 = 1
divy = 5 divy = 5
subdivy=1 subdivy=1
x1=2.9358714e-05 x1=5e-10
x2=0.0010293582 x2=0.001
divx=9 divx=9
unitx=u subdivx=4 unitx=u subdivx=4
@ -169,13 +169,13 @@ autoload=0
sim_type=tran sim_type=tran
xrawfile=$netlist_dir/solar_panel.raw} xrawfile=$netlist_dir/solar_panel.raw}
B 2 1260 -1140 1680 -950 {flags=graph B 2 1370 -1135 1790 -945 {flags=graph
y1 = 0 y1 = 0
y2 = 1 y2 = 1
divy = 5 divy = 5
subdivy=1 subdivy=1
x1=2.9358714e-05 x1=5e-10
x2=0.0010293582 x2=0.001
divx=9 divx=9
unitx=u subdivx=4 unitx=u subdivx=4
@ -193,29 +193,65 @@ autoload=0
sim_type=tran sim_type=tran
xrawfile=$netlist_dir/solar_panel.raw} xrawfile=$netlist_dir/solar_panel.raw}
B 18 65 -960 320 -775 {} B 2 1210 -605 1320 -505 {name=l21
A 5 320 -960 5.590169943749475 243.434948822922 360 {fill=true} flags=graph,unlocked
P 7 6 395 -775 340 -931.25 335 -945 322.5 -960 310 -965 65 -975 {} lock=1
T {2x10 1W white LED} 1240 -200 0 0 0.4 0.4 {layer=8} color=8
T {2xseries 1W white LEDs} 1220 -140 0 0 0.4 0.4 {} node="tcleval([xschem translate l21 @#0:net_name] [xschem translate l21 @#1:net_name] -)"
T {2.5} 95 -755 0 0 0.2 0.2 {} x1=5e-10
T {5.0} 135 -755 0 0 0.2 0.2 {} x2=0.001
T {7.5} 175 -755 0 0 0.2 0.2 {} y1=-4.8
T {10.0} 215 -755 0 0 0.2 0.2 {} y2=15}
T {12.5} 255 -755 0 0 0.2 0.2 {} B 2 400 -735 510 -635 {name=l22
T {15.0} 295 -755 0 0 0.2 0.2 {} flags=graph,unlocked
T {17.5} 335 -755 0 0 0.2 0.2 {} lock=1
T {20.0} 375 -755 0 0 0.2 0.2 {} color=8
T {2.5} 35 -980 0 0 0.2 0.2 {} node="tcleval([xschem translate l22 @#0:net_name])"
T {2.0} 35 -940 0 0 0.2 0.2 {} y1=0.00033
T {1.5} 35 -895 0 0 0.2 0.2 {} y2=21
T {1.0} 35 -860 0 0 0.2 0.2 {} x1=5e-10
T {0.5} 35 -820 0 0 0.2 0.2 {} x2=0.001}
T {25C, 1000W/m2} 190 -1030 0 0 0.2 0.2 {} B 2 600 -485 710 -385 {name=l23
T {V} 410 -765 0 0 0.4 0.4 {} flags=graph,unlocked
T {I} 40 -1020 0 0 0.4 0.4 {} lock=1
T {SOLAR PANEL} 145 -1055 0 0 0.4 0.4 {} color=8
T {Maximum Power} 307.5 -980 0 0 0.2 0.2 {layer=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 T {set between 0 and 1
to simulate to simulate
sun radiation sun radiation
@ -232,21 +268,21 @@ T {Floater text
example} 870 -440 0 0 0.4 0.4 {} 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} 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} 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 1010 -180 1100 -180 {lab=0}
N 1100 -300 1100 -210 {lab=0} N 1100 -300 1100 -180 {lab=0}
N 640 -610 730 -610 {lab=#net1} N 640 -610 730 -610 {lab=#net1}
N 1010 -440 1040 -440 {lab=VO} N 1010 -440 1040 -440 {lab=VO}
N 1010 -440 1010 -310 {lab=VO} N 1010 -440 1010 -310 {lab=VO}
N 1010 -250 1010 -210 {lab=0} N 1010 -250 1010 -180 {lab=0}
N 530 -610 580 -610 {lab=PANEL} N 360 -610 580 -610 {lab=PANEL}
N 1010 -610 1010 -440 {lab=VO} N 1010 -610 1010 -440 {lab=VO}
N 820 -610 860 -610 {lab=SW} N 820 -610 860 -610 {lab=SW}
N 820 -610 820 -490 {lab=SW} N 820 -610 820 -490 {lab=SW}
N 790 -610 820 -610 {lab=SW} N 790 -610 820 -610 {lab=SW}
N 820 -210 1010 -210 {lab=0} N 820 -180 1010 -180 {lab=0}
N 800 -210 820 -210 {lab=0} N 800 -180 820 -180 {lab=0}
N 1000 -610 1010 -610 {lab=VO} 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 1100 -440 1100 -360 {lab=LED}
N 820 -430 820 -390 { lab=#net2} N 820 -430 820 -390 { lab=#net2}
N 920 -610 940 -610 { lab=#net3} N 920 -610 940 -610 { lab=#net3}
@ -295,12 +331,14 @@ N 770 -1080 770 -1030 {
lab=TRIANG} lab=TRIANG}
N 770 -1030 890 -1030 { N 770 -1030 890 -1030 {
lab=TRIANG} lab=TRIANG}
N 820 -330 820 -210 { N 820 -330 820 -180 {
lab=0} 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 {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( value="tcleval(
.probe alli .option savecurrents
.control .control
* example of tcl evaluation of code blocks: * example of tcl evaluation of code blocks:
* current path: $path * 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) .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} 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 {ammeter.sym} 1070 -440 3 0 {name=Vled}
C {ind.sym} 890 -610 3 1 {name=L2 C {ind.sym} 890 -610 3 1 {name=L2
m=1 m=1
value=40u value=40u
footprint=1206 footprint=1206
device=inductor device=inductor
hide_texts=true} hide_texts=true
C {lab_pin.sym} 1140 -440 0 1 {name=l7 lab=LED } 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 {lab_pin.sym} 820 -550 0 1 {name=l9 lab=SW }
C {capa.sym} 1010 -280 0 0 {name=C1 C {capa.sym} 1010 -280 0 0 {name=C1
m=1 m=1
value=500n value=500n
footprint=1206 footprint=1206
device="ceramic capacitor" 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} 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 {ammeter.sym} 970 -610 3 0 {name=Vind}
C {isource_table.sym} 1100 -330 0 0 {name=G2[9..0] CTRL="V(LED)" TABLE=" C {isource_table.sym} 1100 -330 0 0 {name=G2[9..0] CTRL="V(LED)" TABLE="
+ (0, 0) + (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} 810 -890 0 1 {name=p5 analysis=tran}
C {spice_probe.sym} 760 -670 0 0 {name=p6 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 {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}