Merge branch 'StefanSchippers:master' into master
This commit is contained in:
commit
a184d38007
|
|
@ -1342,8 +1342,10 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
if x0, y0 not given use mouse coordinates </pre>
|
||||
<li><kbd> rotate_in_place</kbd></li><pre>
|
||||
Rotate selected objects around their 0,0 coordinate point </pre>
|
||||
<li><kbd> save</kbd></li><pre>
|
||||
Save schematic if modified. Does not ask confirmation! </pre>
|
||||
<li><kbd> save [fast]</kbd></li><pre>
|
||||
Save schematic if modified. Does not ask confirmation!
|
||||
if 'fast' is given it is passed to save_schematic() to avoid
|
||||
updating window/tab/sim button states </pre>
|
||||
<li><kbd> saveas [file] [type]</kbd></li><pre>
|
||||
save current schematic as 'file'
|
||||
if file is empty ({}) use current schematic name
|
||||
|
|
@ -1393,6 +1395,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
for all other objects 'id' is the position in the respective arrays
|
||||
if 'clear' is specified does an unselect operation
|
||||
if 'fast' is specified avoid sending information to infowindow and status bar
|
||||
if 'nodraw' is given on select instance do not draw selection
|
||||
returns 1 if something selected, 0 otherwise </pre>
|
||||
<li><kbd> select_all</kbd></li><pre>
|
||||
Selects all objects in schematic </pre>
|
||||
|
|
|
|||
|
|
@ -66,9 +66,6 @@ p{padding: 15px 30px 10px;}
|
|||
<kbd>Waves->Op | Ac | Dc | Tran | Tran | Noise | Sp </kbd>. This command loads the user selected
|
||||
.raw file produced by a ngspice/Xyce simulation.
|
||||
</p>
|
||||
<p class="important">
|
||||
Ensure the <kbd>circuit.raw</kbd> is saved in binary format (no <kbd>set filetype=ascii</kbd> in your testbench)
|
||||
</p>
|
||||
<p>
|
||||
The raw file is usually located in the simulation/netlisting directory
|
||||
<kbd>Simulation ->set netlist dir</kbd>.<br>
|
||||
|
|
@ -80,6 +77,17 @@ p{padding: 15px 30px 10px;}
|
|||
Then, select a node or a net label, press 'Alt-G', the net will be added to the graph. Here after a
|
||||
list of commands you can perform in a graph to modify the viewport. These commands are active when
|
||||
the mouse is Inside the graph (you will notice the mouse pointer changing from an arrow to a <kbd>+</kbd>).
|
||||
</p>
|
||||
<p class="important">
|
||||
if <kbd>set graph_use_ctrl_key 1</kbd> is set in the <kbd>xschemrc</kbd> file all bind keys shown
|
||||
below will need the <kbd>Control</kbd> key pressed to operate on the graphs. This setting can be used
|
||||
to make it more explicit when the user wants to operate on graphs. Without the <kbd>Control</kbd>
|
||||
key pressed the usual functions on schematic are performed instead of graph functions.<br>
|
||||
Example: the key <kbd>a</kbd> will create a symbol if used in a schematic while it shows a cursor
|
||||
if done when the mouse pointer is inside a graph. With the <kbd>set graph_use_ctrl_key 1</kbd> option
|
||||
you will need to press <kbd>Control-a</kbd> with the mouse pointer inside a graph to show a cursor.
|
||||
</p>
|
||||
<p>
|
||||
if the mouse is outside the graph the usual Xschem functions will be available to operate on schematics:
|
||||
</p>
|
||||
<ul>
|
||||
|
|
@ -87,13 +95,14 @@ p{padding: 15px 30px 10px;}
|
|||
<li>Pressing <kbd>f</kbd> with the mouse on the left of the Y axis will do a full Y-axis zoom.</li>
|
||||
<li>Pressing <kbd>Left/Right</kbd> or <kbd>Up/Down</kbd> arrow keys while the mouse is inside a graph will
|
||||
move the waveforms to the left/right or zoom in/zoom out respectively.</li>
|
||||
<li>Pressing <kbd>Left/Right</kbd> or <kbd>Up/Down</kbd> arrow keys while the mouse is on the left of the Y-axis
|
||||
will move the waveforms or zoom in/zoom out in the Y direction respectively.</li>
|
||||
<li>Pressing <kbd>Left/Right</kbd> arrow keys while the mouse is on the left of the Y-axis
|
||||
will zoom in/zoom out in the Y direction.</li>
|
||||
<li>Pressing the <kbd>left</kbd> mouse button while the pointer is in the center of the graph
|
||||
will move the waves left or right following the pointer X movement.</li>
|
||||
<li>Pressing the <kbd>left</kbd> mouse button while the pointer is on the left of the Y-axis
|
||||
will move the waves high or low following the pointer Y movement.</li>
|
||||
<li> Doing the above with the <kbd>Shift</kbd> key pressed will zoom in/out instead of moving.</li>
|
||||
<li> pressing <kbd>A</kbd> and/or <kbd>B</kbd> will show a horizontal cursor.
|
||||
The difference between the <kbd>A</kbd> and the <kbd>B</kbd> cursor is shown.</li>
|
||||
<li> pressing <kbd>a</kbd> and/or <kbd>b</kbd> will show a vertical cursor.
|
||||
The sweep variable difference between the <kbd>a</kbd> and the <kbd>b</kbd> cursor is shown and
|
||||
the values of all signals at the X position of the <kbd>a</kbd> cursor is shown. </li>
|
||||
|
|
@ -104,6 +113,8 @@ p{padding: 15px 30px 10px;}
|
|||
configuration dialog box, where you can change many graph parameters.</li>
|
||||
<li> Pressing the <kbd>right</kbd> mouse button in the graph area and dragging some distance in the X direction
|
||||
will zoom in the waveforms to that X range.</li>
|
||||
<li> Pressing the <kbd>right</kbd> mouse button to the left of the Y axis and dragging some distance in the Y direction
|
||||
will zoom in the waveforms to that Y range.</li>
|
||||
</ul>
|
||||
<p>
|
||||
<img src="graphs07.png"><br>
|
||||
|
|
|
|||
|
|
@ -536,8 +536,9 @@ const char *get_file_path(char *f)
|
|||
* 1 : file saved or not needed to save since no change
|
||||
* -1 : user cancel
|
||||
* 0 : file not saved due to errors or per user request
|
||||
* confirm:
|
||||
*/
|
||||
int save(int confirm)
|
||||
int save(int confirm, int fast)
|
||||
{
|
||||
struct stat buf;
|
||||
char *name = xctx->sch[xctx->currsch];
|
||||
|
|
@ -556,10 +557,10 @@ int save(int confirm)
|
|||
if(confirm) {
|
||||
tcleval("ask_save_optional");
|
||||
if(!strcmp(tclresult(), "") ) return -1; /* user clicks "Cancel" */
|
||||
else if(!strcmp(tclresult(), "yes") ) return save_schematic(xctx->sch[xctx->currsch]);
|
||||
else if(!strcmp(tclresult(), "yes") ) return save_schematic(xctx->sch[xctx->currsch], fast);
|
||||
else return 0; /* user clicks "no" */
|
||||
} else {
|
||||
return save_schematic(xctx->sch[xctx->currsch]);
|
||||
return save_schematic(xctx->sch[xctx->currsch], fast);
|
||||
}
|
||||
}
|
||||
return 1; /* circuit not changed: always succeeed */
|
||||
|
|
@ -592,7 +593,7 @@ void saveas(const char *f, int type) /* changed name from ask_save_file to save
|
|||
|
||||
if(!res[0]) return;
|
||||
dbg(1, "saveas(): res = %s\n", res);
|
||||
save_schematic(res);
|
||||
save_schematic(res, 0);
|
||||
tclvareval("update_recent_file {", res,"}", NULL);
|
||||
return;
|
||||
}
|
||||
|
|
@ -603,7 +604,7 @@ void ask_new_file(void)
|
|||
|
||||
if(!has_x) return;
|
||||
if(xctx->modified) {
|
||||
if(save(1) == -1 ) return; /* user cancels save, so do nothing. */
|
||||
if(save(1, 0) == -1 ) return; /* user cancels save, so do nothing. */
|
||||
}
|
||||
tcleval("load_file_dialog {Load file} *.\\{sch,sym,tcl\\} INITIALLOADDIR");
|
||||
my_snprintf(f, S(f),"%s", tclresult());
|
||||
|
|
@ -2231,7 +2232,7 @@ int descend_schematic(int instnumber, int fallback, int alert, int set_title)
|
|||
my_strncpy(res, tclresult(), S(res));
|
||||
if(!res[0]) return 0;
|
||||
dbg(1, "descend_schematic(): saving: %s\n",res);
|
||||
save_ok = save_schematic(res);
|
||||
save_ok = save_schematic(res, 0);
|
||||
if(save_ok==0) return 0;
|
||||
}
|
||||
n = xctx->sel_array[0].n;
|
||||
|
|
@ -2248,7 +2249,7 @@ int descend_schematic(int instnumber, int fallback, int alert, int set_title)
|
|||
if(xctx->modified) {
|
||||
int ret;
|
||||
|
||||
ret = save(1);
|
||||
ret = save(1, 0);
|
||||
/* if circuit is changed but not saved before descending
|
||||
* state will be inconsistent when returning, can not propagare hilights
|
||||
* save() return value:
|
||||
|
|
@ -2402,10 +2403,10 @@ void go_back(int confirm, int set_title) /* 20171006 add confirm */
|
|||
{
|
||||
if(confirm) {
|
||||
tcleval("ask_save_optional");
|
||||
if(!strcmp(tclresult(), "yes") ) save_ok = save_schematic(xctx->sch[xctx->currsch]);
|
||||
if(!strcmp(tclresult(), "yes") ) save_ok = save_schematic(xctx->sch[xctx->currsch], 0);
|
||||
else if(!strcmp(tclresult(), "") ) return;
|
||||
} else {
|
||||
save_ok = save_schematic(xctx->sch[xctx->currsch]);
|
||||
save_ok = save_schematic(xctx->sch[xctx->currsch], 0);
|
||||
}
|
||||
}
|
||||
if(save_ok==0) {
|
||||
|
|
@ -2458,7 +2459,7 @@ void go_back(int confirm, int set_title) /* 20171006 add confirm */
|
|||
|
||||
void clear_schematic(int cancel, int symbol)
|
||||
{
|
||||
if(cancel == 1) cancel=save(1);
|
||||
if(cancel == 1) cancel=save(1, 0);
|
||||
if(cancel != -1) { /* -1 means user cancel save request */
|
||||
char name[PATH_MAX];
|
||||
struct stat buf;
|
||||
|
|
|
|||
1450
src/callback.c
1450
src/callback.c
File diff suppressed because it is too large
Load Diff
150
src/draw.c
150
src/draw.c
|
|
@ -2514,6 +2514,9 @@ int graph_fullyzoom(xRect *r, Graph_ctx *gr, int graph_dataset)
|
|||
int cnt=0, wrap;
|
||||
register SPICE_DATA *gv = raw->values[sweep_idx];
|
||||
ofs_end = ofs + raw->npoints[dset];
|
||||
|
||||
/* optimization: skip unwanted datasets, if no dc no need to detect sweep variable wraps */
|
||||
if(dataset >= 0 && strcmp(xctx->raw->sim_type, "dc") && dataset != sweepvar_wrap) goto done;
|
||||
for(p = ofs ; p < ofs_end; p++) {
|
||||
if(gr->logx) xx = mylog10(gv[p]);
|
||||
else xx = gv[p];
|
||||
|
|
@ -2539,6 +2542,9 @@ int graph_fullyzoom(xRect *r, Graph_ctx *gr, int graph_dataset)
|
|||
++cnt;
|
||||
}
|
||||
} /* for(p = ofs ; p < ofs + raw->npoints[dset]; p++) */
|
||||
|
||||
done:
|
||||
|
||||
/* offset pointing to next dataset */
|
||||
ofs = ofs_end;
|
||||
sweepvar_wrap++;
|
||||
|
|
@ -2905,7 +2911,18 @@ void setup_graph_data(int i, int skip, Graph_ctx *gr)
|
|||
gr->digital = 0;
|
||||
gr->rainbow = 0;
|
||||
gr->linewidth_mult = tclgetdoublevar("graph_linewidth_mult");
|
||||
|
||||
xctx->graph_flags &= ~(128 | 256); /* clear hcursor flags */
|
||||
gr->hcursor1_y = gr->hcursor2_y = 0.0;
|
||||
val = get_tok_value(r->prop_ptr,"hcursor1_y", 0);
|
||||
if(val[0]) {
|
||||
gr->hcursor1_y = atof_spice(val);
|
||||
xctx->graph_flags |= 128;
|
||||
}
|
||||
val = get_tok_value(r->prop_ptr,"hcursor2_y", 0);
|
||||
if(val[0]) {
|
||||
gr->hcursor2_y = atof_spice(val);
|
||||
xctx->graph_flags |= 256;
|
||||
}
|
||||
if(!skip) {
|
||||
gr->gx1 = 0;
|
||||
gr->gx2 = 1e-6;
|
||||
|
|
@ -3016,9 +3033,9 @@ void setup_graph_data(int i, int skip, Graph_ctx *gr)
|
|||
gr->gh = gr->gy2 - gr->gy1;
|
||||
/* set margins */
|
||||
tmp = gr->rw * 0.14;
|
||||
gr->marginx = tmp < 30 ? 30 : tmp;
|
||||
gr->marginx = tmp < 50 ? 50 : tmp;
|
||||
tmp = gr->rh * 0.14;
|
||||
gr->marginy = tmp < 35 ? 35 : tmp;
|
||||
gr->marginy = tmp < 40 ? 40 : tmp;
|
||||
|
||||
/* calculate graph bounding box (container - margin)
|
||||
* This is the box where plot is done */
|
||||
|
|
@ -3031,7 +3048,7 @@ void setup_graph_data(int i, int skip, Graph_ctx *gr)
|
|||
gr->h = gr->y2 - gr->y1;
|
||||
|
||||
/* label text size calculations */
|
||||
gr->txtsizelab = gr->marginy * 0.007;
|
||||
gr->txtsizelab = gr->marginy * 0.006;
|
||||
/*
|
||||
* tmp = gr->w * 0.00044;
|
||||
* if(tmp < gr->txtsizelab) gr->txtsizelab = tmp;
|
||||
|
|
@ -3042,8 +3059,8 @@ void setup_graph_data(int i, int skip, Graph_ctx *gr)
|
|||
gr->digtxtsizelab = 0.001200 * fabs( gr->h / gr->posh * gr->gh );
|
||||
|
||||
/* x axis, y axis text sizes */
|
||||
gr->txtsizey = gr->h / gr->divy * 0.009;
|
||||
tmp = gr->marginx * 0.005;
|
||||
gr->txtsizey = gr->h / gr->divy * 0.0095;
|
||||
tmp = gr->marginx * 0.003;
|
||||
if(tmp < gr->txtsizey) gr->txtsizey = tmp;
|
||||
tmp = gr->marginy * 0.02;
|
||||
if(tmp < gr->txtsizey) gr->txtsizey = tmp;
|
||||
|
|
@ -3136,6 +3153,72 @@ static void draw_cursor_difference(double c1, double c2, Graph_ctx *gr)
|
|||
}
|
||||
}
|
||||
|
||||
static void draw_hcursor(double active_cursory, int cursor_color, Graph_ctx *gr)
|
||||
{
|
||||
double yy, pos = active_cursory;
|
||||
double tx1, ty1, tx2, ty2, dtmp;
|
||||
int tmp;
|
||||
char tmpstr[100];
|
||||
double txtsize = gr->txtsizey;
|
||||
double th;
|
||||
|
||||
if(gr->digital) return;
|
||||
if(gr->logy) pos = mylog10(pos);
|
||||
yy = W_Y(pos);
|
||||
if(yy >= gr->y1 && yy <= gr->y2) {
|
||||
drawline(cursor_color, NOW, gr->rx1 + 10, yy, gr->rx2 - 10, yy, 1, NULL);
|
||||
if(gr->unity != 1.0)
|
||||
my_snprintf(tmpstr, S(tmpstr), " %.5g%c ", gr->unity * active_cursory , gr->unity_suffix);
|
||||
else
|
||||
my_snprintf(tmpstr, S(tmpstr), " %s ", dtoa_eng(active_cursory));
|
||||
text_bbox(tmpstr, txtsize, txtsize, 0, 0, 0, 0, gr->rx1 + 5, yy, &tx1, &ty1, &tx2, &ty2, &tmp, &dtmp);
|
||||
th = (ty2 - ty1) / 2.; /* half text height */
|
||||
ty1 -= th;
|
||||
ty2 -= th;
|
||||
filledrect(0, NOW, tx1, ty1, tx2, ty2, 3, -1, -1);
|
||||
draw_string(cursor_color, NOW, tmpstr, 0, 0, 0, 0, gr->rx1 + 5, yy - th, txtsize, txtsize);
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_hcursor_difference(double c1, double c2, Graph_ctx *gr)
|
||||
{
|
||||
int tmp;
|
||||
char tmpstr[100];
|
||||
double txtsize = gr->txtsizey;
|
||||
double tx1, ty1, tx2, ty2;
|
||||
double cc1 = gr->logy ? mylog10(c1) : c1;
|
||||
double cc2 = gr->logy ? mylog10(c2) : c2;
|
||||
double aa = W_Y(cc1);
|
||||
double a = CLIP(aa, gr->y1, gr->y2);
|
||||
double bb = W_Y(cc2);
|
||||
double b = CLIP(bb, gr->y1, gr->y2);
|
||||
double diff = fabs(b - a);
|
||||
double diffh;
|
||||
double yy = ( a + b ) * 0.5;
|
||||
double xx = gr->rx1 + 5;
|
||||
double dtmp;
|
||||
double xline;
|
||||
|
||||
if(gr->digital) return;
|
||||
diffh = fabs(c2 - c1);
|
||||
if(gr->unity != 1.0)
|
||||
my_snprintf(tmpstr, S(tmpstr), " %.4g%c ", gr->unity * diffh , gr->unity_suffix);
|
||||
else
|
||||
my_snprintf(tmpstr, S(tmpstr), " %s ", dtoa_eng(diffh));
|
||||
text_bbox(tmpstr, txtsize, txtsize, 0, 0, 0, 1, xx, yy, &tx1, &ty1, &tx2, &ty2, &tmp, &dtmp);
|
||||
if( 2 * (ty2 - ty1) < diff ) {
|
||||
filledrect(0, NOW, tx1, ty1, tx2, ty2, 3, -1, -1);
|
||||
draw_string(3, NOW, tmpstr, 0, 0, 0, 1, xx, yy, txtsize, txtsize);
|
||||
if( a > b) {
|
||||
dtmp = a; a = b; b = dtmp;
|
||||
}
|
||||
xline = tx1 + 10;
|
||||
if( ty1 - a > 4.0) drawline(3, NOW, xline, a + 2, xline, ty1 - 2, 1, NULL);
|
||||
if( b - ty2 > 4.0) drawline(3, NOW, xline, ty2 + 2, xline, b - 2, 1, NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* sweep variables on x-axis, node labels */
|
||||
static void draw_graph_variables(int wcnt, int wave_color, int n_nodes, int sweep_idx,
|
||||
int flags, const char *ntok, const char *stok, const char *bus_msb, Graph_ctx *gr)
|
||||
|
|
@ -3451,6 +3534,9 @@ int calc_custom_data_yrange(int sweep_idx, const char *express, Graph_ctx *gr)
|
|||
ofs_end = ofs + raw->npoints[dset];
|
||||
first = -1;
|
||||
last = ofs;
|
||||
|
||||
/* optimization: skip unwanted datasets, if no dc no need to detect sweep variable wraps */
|
||||
if(dataset >= 0 && strcmp(xctx->raw->sim_type, "dc") && dataset != sweepvar_wrap) goto done;
|
||||
for(p = ofs ; p < ofs_end; p++) {
|
||||
if(gr->logx)
|
||||
xx = mylog10(gv[p]);
|
||||
|
|
@ -3483,6 +3569,9 @@ int calc_custom_data_yrange(int sweep_idx, const char *express, Graph_ctx *gr)
|
|||
idx = plot_raw_custom_data(sweep_idx, first, last, express, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
/* offset pointing to next dataset */
|
||||
ofs = ofs_end;
|
||||
sweepvar_wrap++;
|
||||
|
|
@ -3654,12 +3743,14 @@ int find_closest_wave(int i, Graph_ctx *gr)
|
|||
|
||||
|
||||
/* flags:
|
||||
* 1: do final XCopyArea (copy 2nd buffer areas to screen)
|
||||
* If draw_graph_all() is called from draw() no need to do XCopyArea, as draw() does it already.
|
||||
* This makes drawing faster and removes a 'tearing' effect when moving around.
|
||||
* 2: draw x-cursor1
|
||||
* 4: draw x-cursor2
|
||||
* 8: all drawing, if not set do only XCopyArea / x-cursor if specified
|
||||
* 1: do final XCopyArea (copy 2nd buffer areas to screen)
|
||||
* If draw_graph_all() is called from draw() no need to do XCopyArea, as draw() does it already.
|
||||
* This makes drawing faster and removes a 'tearing' effect when moving around.
|
||||
* 2: draw x-cursor1
|
||||
* 4: draw x-cursor2
|
||||
* 128: draw y-cursor1
|
||||
* 256: draw y-cursor2
|
||||
* 8: all drawing, if not set do only XCopyArea / x-cursor if specified
|
||||
* ct is a pointer used in windows for cairo
|
||||
*/
|
||||
void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
|
||||
|
|
@ -3714,7 +3805,7 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
|
|||
#if 0
|
||||
dbg(0, "draw_graph(): window: %d %d %d %d\n", xctx->areax1, xctx->areay1, xctx->areax2, xctx->areay2);
|
||||
dbg(0, "draw_graph(): graph: %g %g %g %g\n", gr->sx1, gr->sy1, gr->sx2, gr->sy2);
|
||||
dbg(0, "draw_graph(): i = %d, flags = %d\n", i, flags);
|
||||
dbg(0, "draw_graph(): i = %d, flags = %d graph_flags=%d\n", i, flags, xctx->graph_flags);
|
||||
#endif
|
||||
|
||||
/* draw stuff */
|
||||
|
|
@ -3905,6 +3996,10 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
|
|||
* p loop split repeated 2 timed (for x and y points) to preserve cache locality */
|
||||
prev_x = 0;
|
||||
last = ofs;
|
||||
|
||||
/* optimization: skip unwanted datasets, if no dc no need to detect sweep variable wraps */
|
||||
if(dataset >= 0 && strcmp(xctx->raw->sim_type, "dc") && dataset != sweepvar_wrap) goto done;
|
||||
|
||||
for(p = ofs ; p < ofs_end; p++) {
|
||||
double xxprevious, xxfollowing;
|
||||
|
||||
|
|
@ -3980,6 +4075,8 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
|
|||
} /* if(xx >= start && xx <= end) */
|
||||
prev_x = xx;
|
||||
} /* for(p = ofs ; p < ofs + xctx->raw->npoints[dset]; p++) */
|
||||
|
||||
|
||||
if(first != -1) {
|
||||
if(dataset == -1 || dataset == sweepvar_wrap) {
|
||||
/* plot graph. Bus bundles are not plotted if graph is not digital.*/
|
||||
|
|
@ -3996,6 +4093,9 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
/* offset pointing to next dataset */
|
||||
ofs = ofs_end;
|
||||
sweepvar_wrap++;
|
||||
|
|
@ -4036,17 +4136,17 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
|
|||
*/
|
||||
if(flags & 8) {
|
||||
/* cursor1 */
|
||||
if((flags & 2)) {
|
||||
draw_cursor(cursor1, cursor2, 1, gr);
|
||||
}
|
||||
if((flags & 2)) draw_cursor(cursor1, cursor2, 1, gr);
|
||||
/* cursor2 */
|
||||
if((flags & 4)) {
|
||||
draw_cursor(cursor2, cursor1, 3, gr);
|
||||
}
|
||||
if((flags & 4)) draw_cursor(cursor2, cursor1, 3, gr);
|
||||
/* difference between cursors */
|
||||
if((flags & 2) && (flags & 4)) {
|
||||
draw_cursor_difference(cursor1, cursor2, gr);
|
||||
}
|
||||
if((flags & 2) && (flags & 4)) draw_cursor_difference(cursor1, cursor2, gr);
|
||||
/* difference between hcursors */
|
||||
if((flags & 128) && (flags & 256)) draw_hcursor_difference(gr->hcursor1_y, gr->hcursor2_y, gr);
|
||||
/* hcursor1 */
|
||||
if(flags & 128) draw_hcursor(gr->hcursor1_y, 15, gr);
|
||||
/* hcursor2 */
|
||||
if(flags & 256) draw_hcursor(gr->hcursor2_y, 19, gr);
|
||||
}
|
||||
if(flags & 1) { /* copy save buffer to screen */
|
||||
if(!xctx->draw_window) {
|
||||
|
|
@ -4097,8 +4197,10 @@ static void draw_graph_all(int flags)
|
|||
if(xctx->enable_layer[GRIDLAYER]) for(i = 0; i < xctx->rects[GRIDLAYER]; ++i) {
|
||||
xRect *r = &xctx->rect[GRIDLAYER][i];
|
||||
if(r->flags & 1) {
|
||||
int flags2;
|
||||
setup_graph_data(i, 0, &xctx->graph_struct);
|
||||
draw_graph(i, flags, &xctx->graph_struct, NULL); /* draw data in each graph box */
|
||||
flags2 = flags | (xctx->graph_flags & (128 | 256)); /* include drawing hcursors if enabled */
|
||||
draw_graph(i, flags2, &xctx->graph_struct, NULL); /* draw data in each graph box */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4701,7 +4803,7 @@ void svg_embedded_graph(FILE *fd, xRect *r, double rx1, double ry1, double rx2,
|
|||
xRect *r = &xctx->rect[GRIDLAYER][i];
|
||||
if(r->flags & 1) {
|
||||
setup_graph_data(i, 0, &xctx->graph_struct);
|
||||
draw_graph(i, 8, &xctx->graph_struct, (void *)ct);
|
||||
draw_graph(i, 8 + (xctx->graph_flags & (4 | 2 | 128 | 256)), &xctx->graph_struct, (void *)ct);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -341,7 +341,7 @@ static int ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, doubl
|
|||
xRect* r2 = &xctx->rect[GRIDLAYER][i];
|
||||
if (r2->flags & 1) {
|
||||
setup_graph_data(i, 0, &xctx->graph_struct);
|
||||
draw_graph(i, 8, &xctx->graph_struct, (void*)ct);
|
||||
draw_graph(i, 8 + (xctx->graph_flags & (4 | 2 | 128 | 256)), &xctx->graph_struct, (void *)ct);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
10
src/save.c
10
src/save.c
|
|
@ -3315,14 +3315,13 @@ Sch_pin_record *sort_schematic_pins(int *npins)
|
|||
* 0 : did not save
|
||||
* 1 : schematic saved
|
||||
*/
|
||||
int save_schematic(const char *schname) /* 20171020 added return value */
|
||||
int save_schematic(const char *schname, int fast) /* 20171020 added return value */
|
||||
{
|
||||
FILE *fd;
|
||||
struct stat buf;
|
||||
xRect *rect;
|
||||
int rects;
|
||||
char msg[PATH_MAX + 100];
|
||||
int same_name = 0;
|
||||
|
||||
if(!schname || !strcmp(schname, "")) return 0;
|
||||
|
||||
|
|
@ -3338,7 +3337,6 @@ int save_schematic(const char *schname) /* 20171020 added return value */
|
|||
set_modify(-1); /* set title to new filename */
|
||||
}
|
||||
else { /* user asks to save to same filename */
|
||||
same_name = 1;
|
||||
if(!stat(xctx->sch[xctx->currsch], &buf)) {
|
||||
if(xctx->time_last_modify && xctx->time_last_modify != buf.st_mtime) {
|
||||
tclvareval("ask_save_optional \"Schematic file: ", xctx->sch[xctx->currsch],
|
||||
|
|
@ -3374,8 +3372,8 @@ int save_schematic(const char *schname) /* 20171020 added return value */
|
|||
* xctx->prep_hash_wires=0;
|
||||
*/
|
||||
if(!strstr(xctx->sch[xctx->currsch], ".xschem_embedded_")) {
|
||||
if(same_name) set_modify(2); /* clear only modified flag, do not set window title etc */
|
||||
else set_modify(0);
|
||||
if(fast) set_modify(2); /* only clear modified flag, no title/tab/sim buttons update */
|
||||
else set_modify(0);
|
||||
}
|
||||
tclvareval(xctx->top_path, ".menubar entryconfigure Simulate -background $simulate_bg", NULL);
|
||||
tclvareval("set tctx::", xctx->current_win_path, "_simulate $simulate_bg", NULL);
|
||||
|
|
@ -5070,7 +5068,7 @@ void descend_symbol(void)
|
|||
if(xctx->modified)
|
||||
{
|
||||
int ret;
|
||||
ret = save(1);
|
||||
ret = save(1, 1);
|
||||
/* if circuit is changed but not saved before descending
|
||||
* state will be inconsistent when returning, can not propagare hilights
|
||||
* save() return value:
|
||||
|
|
|
|||
|
|
@ -877,14 +877,16 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
|
||||
if(argc > 2) {
|
||||
int i = atoi(argv[2]);
|
||||
setup_graph_data(i, 0, &xctx->graph_struct);
|
||||
if(argc > 3) {
|
||||
flags = atoi(argv[3]);
|
||||
} else {
|
||||
/* 2: draw cursor 1
|
||||
* 4: draw cursor 2 */
|
||||
flags = 1 + 8 + (xctx->graph_flags & (2 + 4));
|
||||
* 4: draw cursor 2
|
||||
* 128: draw hcursor 1
|
||||
* 256: draw hcursor 2 */
|
||||
flags = 1 + 8 + (xctx->graph_flags & (2 + 4 + 128 + 256));
|
||||
}
|
||||
setup_graph_data(i, 0, &xctx->graph_struct);
|
||||
draw_graph(i, flags, &xctx->graph_struct, NULL);
|
||||
}
|
||||
Tcl_ResetResult(interp);
|
||||
|
|
@ -914,7 +916,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
|
||||
rebuild_selected_array();
|
||||
if(xctx->lastsel==0 ) {
|
||||
save_schematic(xctx->sch[xctx->currsch]); /* sync data with disk file before editing file */
|
||||
save_schematic(xctx->sch[xctx->currsch], 0); /* sync data with disk file before editing file */
|
||||
my_snprintf(name, S(name), "edit_file {%s}",
|
||||
abs_sym_path(xctx->sch[xctx->currsch], ""));
|
||||
tcleval(name);
|
||||
|
|
@ -2815,7 +2817,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
my_snprintf(f, S(f),"regsub {^~/} {%s} {%s/}", argv[2], home_dir);
|
||||
tcleval(f);
|
||||
my_strncpy(f, tclresult(), S(f));
|
||||
if(force || !has_x || !xctx->modified || save(1) != -1 ) { /* save(1)==-1 --> user cancel */
|
||||
if(force || !has_x || !xctx->modified || save(1, 0) != -1 ) { /* save(1)==-1 --> user cancel */
|
||||
char win_path[WINDOW_PATH_SIZE];
|
||||
int skip = 0;
|
||||
dbg(1, "scheduler(): load: filename=%s\n", argv[2]);
|
||||
|
|
@ -3049,7 +3051,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
if(has_x) tcleval("tk_messageBox -type okcancel -parent [xschem get topwindow] "
|
||||
"-message {do you want to make symbol view ?}");
|
||||
if(!has_x || strcmp(tclresult(), "ok")==0) {
|
||||
save_schematic(xctx->sch[xctx->currsch]);
|
||||
save_schematic(xctx->sch[xctx->currsch], 0);
|
||||
make_symbol();
|
||||
}
|
||||
Tcl_ResetResult(interp);
|
||||
|
|
@ -4590,16 +4592,23 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
else { cmd_found = 0;}
|
||||
break;
|
||||
case 's': /*----------------------------------------------*/
|
||||
/* save
|
||||
* Save schematic if modified. Does not ask confirmation! */
|
||||
/* save [fast]
|
||||
* Save schematic if modified. Does not ask confirmation!
|
||||
* if 'fast' is given it is passed to save_schematic() to avoid
|
||||
* updating window/tab/sim button states */
|
||||
if(!strcmp(argv[1], "save"))
|
||||
{
|
||||
int fast = 0;
|
||||
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
|
||||
dbg(1, "scheduler(): saving: current schematic\n");
|
||||
for(i = 2; i < argc; i++) {
|
||||
if(!strcmp(argv[i], "fast")) fast |= 1;
|
||||
}
|
||||
|
||||
if(!strcmp(xctx->sch[xctx->currsch], "")) { /* check if unnamed schematic, use saveas in this case... */
|
||||
saveas(NULL, SCHEMATIC);
|
||||
} else {
|
||||
save(0);
|
||||
save(0, fast);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4745,6 +4754,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
* for all other objects 'id' is the position in the respective arrays
|
||||
* if 'clear' is specified does an unselect operation
|
||||
* if 'fast' is specified avoid sending information to infowindow and status bar
|
||||
* if 'nodraw' is given on select instance do not draw selection
|
||||
* returns 1 if something selected, 0 otherwise */
|
||||
else if(!strcmp(argv[1], "select"))
|
||||
{
|
||||
|
|
@ -4766,7 +4776,8 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
int i;
|
||||
for(i = 4; i < argc; i++) {
|
||||
if(!strcmp(argv[i], "clear")) sel = 0;
|
||||
if(!strcmp(argv[i], "fast")) fast = 1;
|
||||
if(!strcmp(argv[i], "fast")) fast |= 1;
|
||||
if(!strcmp(argv[i], "nodraw") && !strcmp(argv[2], "instance")) fast |= 2;
|
||||
}
|
||||
}
|
||||
if(!strcmp(argv[2], "instance") && argc > 3) {
|
||||
|
|
|
|||
|
|
@ -937,6 +937,10 @@ void select_wire(int i,unsigned short select_mode, int fast)
|
|||
xctx->need_reb_sel_arr=1;
|
||||
}
|
||||
|
||||
/* fast == 1: do not update status line
|
||||
* fast == 2: do not draw / undraw selected elements
|
||||
* fast == 3: 1 + 2
|
||||
*/
|
||||
void select_element(int i,unsigned short select_mode, int fast, int override_lock)
|
||||
{
|
||||
int c, j;
|
||||
|
|
@ -946,7 +950,7 @@ void select_element(int i,unsigned short select_mode, int fast, int override_loc
|
|||
if(!strboolcmp(get_tok_value(xctx->inst[i].prop_ptr, "lock", 0), "true") &&
|
||||
select_mode == SELECTED && !override_lock) return;
|
||||
my_strncpy(s,xctx->inst[i].prop_ptr!=NULL?xctx->inst[i].prop_ptr:"<NULL>",S(s));
|
||||
if( !fast )
|
||||
if( !(fast & 1) )
|
||||
{
|
||||
my_snprintf(str, S(str), "Info: selected element %d: %s\nproperties:\n%s", i,
|
||||
xctx->inst[i].name ? xctx->inst[i].name : "<NULL>" , s);
|
||||
|
|
@ -976,7 +980,7 @@ void select_element(int i,unsigned short select_mode, int fast, int override_loc
|
|||
}
|
||||
xctx->inst[i].sel = select_mode;
|
||||
if(select_mode == SELECTED) set_first_sel(ELEMENT, i, 0);
|
||||
if(!fast) {
|
||||
if(!(fast & 2) ) {
|
||||
if(select_mode) {
|
||||
for(c=0;c<cadlayers; ++c) {
|
||||
draw_temp_symbol(ADD, xctx->gc[SELLAYER], i,c,0,0,0.0,0.0);
|
||||
|
|
|
|||
|
|
@ -484,7 +484,7 @@ static void alloc_xschem_data(const char *top_path, const char *win_path)
|
|||
xctx->extra_idx = 0;
|
||||
xctx->extra_prev_idx = 0;
|
||||
xctx->extra_raw_n = 0;
|
||||
xctx->graph_master = 0;
|
||||
xctx->graph_master = -1;
|
||||
xctx->graph_cursor1_x = 0;
|
||||
xctx->graph_cursor2_x = 0;
|
||||
xctx->graph_flags = 0;
|
||||
|
|
|
|||
|
|
@ -888,6 +888,7 @@ typedef struct {
|
|||
int logx, logy;
|
||||
int rainbow; /* draw multiple datasets with incrementing colors */
|
||||
double linewidth_mult; /* multiply factor for waveforms line width */
|
||||
double hcursor1_y, hcursor2_y; /* hcursor positions */
|
||||
} Graph_ctx;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -1310,7 +1311,7 @@ extern void new_xschem_process(const char *cell, int symbol);
|
|||
extern void ask_new_file(void);
|
||||
extern void saveas(const char *f, int type);
|
||||
extern const char *get_file_path(char *f);
|
||||
extern int save(int confirm);
|
||||
extern int save(int confirm, int fast);
|
||||
extern void save_ascii_string(const char *ptr, FILE *fd, int newline);
|
||||
extern Hilight_hashentry *bus_hilight_hash_lookup(const char *token, int value, int what) ;
|
||||
/* wrapper function to hash highlighted instances, avoid clash with net names */
|
||||
|
|
@ -1496,7 +1497,7 @@ extern int sym_vs_sch_pins(int all);
|
|||
extern char *get_generator_command(const char *str);
|
||||
extern int match_symbol(const char name[]);
|
||||
extern Sch_pin_record *sort_schematic_pins(int *npins);
|
||||
extern int save_schematic(const char *); /* 20171020 added return value */
|
||||
extern int save_schematic(const char *, int fast); /* 20171020 added return value */
|
||||
extern void copy_symbol(xSymbol *dest_sym, xSymbol *src_sym);
|
||||
extern void push_undo(void);
|
||||
extern void pop_undo(int redo, int set_modify_status);
|
||||
|
|
|
|||
|
|
@ -1785,16 +1785,17 @@ proc cellview_setlabels {w symbol sym_sch default_sch sym_spice_sym_def} {
|
|||
$w configure -bg [option get . background {}]
|
||||
if { $sym_spice_sym_def ne {}} {
|
||||
$w configure -fg $symfg
|
||||
} elseif { ![file exists [abs_sym_path [$w get]]] } {
|
||||
$w configure -bg $missingbg
|
||||
} else {
|
||||
if {[$w get] eq $default_sch} {
|
||||
# ....
|
||||
puts "need to clear schematic attr in symbol"
|
||||
} elseif {[$w get] eq $sym_sch} {
|
||||
$w configure -bg $symbg
|
||||
} else {
|
||||
puts "need to update:[$w get] --> $sym_sch"
|
||||
}
|
||||
if { ![file exists [abs_sym_path [$w get]]] } {
|
||||
$w configure -bg $missingbg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1904,7 +1905,7 @@ proc traversal_setlabels {w parent_sch instname inst_sch sym_sch default_sch ins
|
|||
xschem setprop instance $instname schematic [$w get] fast ;# set schematic attr on instance
|
||||
}
|
||||
xschem set_modify 3 ;# set only modified flag to force a save, do not update window/tab titles
|
||||
xschem save
|
||||
xschem save fast
|
||||
set inst_sch [$w get]
|
||||
# puts "inst_sch set to: $inst_sch"
|
||||
xschem load $current noundoreset nodraw
|
||||
|
|
@ -2083,7 +2084,7 @@ proc hier_traversal {{level 0} {only_subckts 0} {all_hierarchy 1}} {
|
|||
|
||||
set done_print 1
|
||||
if {$type eq {subcircuit} && $all_hierarchy} {
|
||||
xschem select instance $i fast
|
||||
xschem select instance $i fast nodraw
|
||||
set descended [xschem descend 1 6]
|
||||
if {$descended} {
|
||||
incr level
|
||||
|
|
@ -6570,7 +6571,7 @@ proc swap_compare_schematics {} {
|
|||
}
|
||||
proc input_line {txt {cmd {}} {preset {}} {w 12}} {
|
||||
global wm_fix retval
|
||||
set retval {}
|
||||
set retval $preset
|
||||
if { [winfo exists .dialog] } {return}
|
||||
xschem set semaphore [expr {[xschem get semaphore] +1}]
|
||||
toplevel .dialog -class Dialog
|
||||
|
|
|
|||
|
|
@ -53,10 +53,12 @@ color="8 6"
|
|||
|
||||
linewidth_mult=1.0
|
||||
hilight_wave=-1
|
||||
dataset=-1
|
||||
dataset=188
|
||||
rawfile=$netlist_dir/autozero_comp.raw
|
||||
sim_type=tran
|
||||
rainbow=0}
|
||||
rainbow=0
|
||||
hcursor1_y=0.13350312
|
||||
hcursor2_y=0.58853305}
|
||||
B 2 270 -1160 680 -1030 {flags=graph,unlocked
|
||||
y1 = 0.647319
|
||||
y2 = 0.652563
|
||||
|
|
@ -135,6 +137,27 @@ saout
|
|||
sweep="freq0 freq1 freq0"
|
||||
mode=HistoH
|
||||
xlabmag=2.0}
|
||||
B 2 270 -1610 680 -1450 {flags=graph,unlocked
|
||||
y1 = 0
|
||||
y2 = 0.9
|
||||
divy = 5
|
||||
x1=1.9099218e-07
|
||||
x2=3.4920522e-07
|
||||
divx=5
|
||||
subdivx=4
|
||||
unitx=n
|
||||
node="zero0
|
||||
zero1
|
||||
zero2"
|
||||
color="12 4 7"
|
||||
|
||||
linewidth_mult=0.1
|
||||
hilight_wave=-1
|
||||
|
||||
rawfile=$netlist_dir/autozero_comp.raw
|
||||
sim_type=tran
|
||||
rainbow=0
|
||||
dataset=235}
|
||||
T {CAL} 140 -180 0 1 0.4 0.4 {}
|
||||
T {EN} 140 -130 0 1 0.4 0.4 {}
|
||||
T {CALIBRATION
|
||||
|
|
|
|||
Loading…
Reference in New Issue