horizontal cursors in graphs
This commit is contained in:
parent
9fda7e2f96
commit
a3e7610d83
|
|
@ -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
|
<kbd>Waves->Op | Ac | Dc | Tran | Tran | Noise | Sp </kbd>. This command loads the user selected
|
||||||
.raw file produced by a ngspice/Xyce simulation.
|
.raw file produced by a ngspice/Xyce simulation.
|
||||||
</p>
|
</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>
|
<p>
|
||||||
The raw file is usually located in the simulation/netlisting directory
|
The raw file is usually located in the simulation/netlisting directory
|
||||||
<kbd>Simulation ->set netlist dir</kbd>.<br>
|
<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
|
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
|
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>).
|
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:
|
if the mouse is outside the graph the usual Xschem functions will be available to operate on schematics:
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
<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>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
|
<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>
|
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
|
<li>Pressing <kbd>Left/Right</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>
|
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
|
<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>
|
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
|
<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>
|
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.
|
<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 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>
|
the values of all signals at the X position of the <kbd>a</kbd> cursor is shown. </li>
|
||||||
|
|
|
||||||
179
src/callback.c
179
src/callback.c
|
|
@ -46,7 +46,7 @@ static int waves_selected(int event, KeySym key, int state, int button)
|
||||||
else if(event == ButtonPress && button == Button2) skip = 1;
|
else if(event == ButtonPress && button == Button2) skip = 1;
|
||||||
else if(event == ButtonPress && button == Button1 && (state & ShiftMask) ) skip = 1;
|
else if(event == ButtonPress && button == Button1 && (state & ShiftMask) ) skip = 1;
|
||||||
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) {
|
||||||
xRect *r;
|
xRect *r;
|
||||||
r = &xctx->rect[GRIDLAYER][i];
|
r = &xctx->rect[GRIDLAYER][i];
|
||||||
|
|
@ -68,6 +68,7 @@ static int waves_selected(int event, KeySym key, int state, int button)
|
||||||
is_inside = 1;
|
is_inside = 1;
|
||||||
if(draw_xhair) draw_crosshair(1);
|
if(draw_xhair) draw_crosshair(1);
|
||||||
tclvareval(xctx->top_path, ".drw configure -cursor tcross" , NULL);
|
tclvareval(xctx->top_path, ".drw configure -cursor tcross" , NULL);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!is_inside) {
|
if(!is_inside) {
|
||||||
|
|
@ -366,7 +367,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
||||||
int save_mouse_at_end = 0, clear_graphpan_at_end = 0;
|
int save_mouse_at_end = 0, clear_graphpan_at_end = 0;
|
||||||
int track_dset = -2; /* used to find dataset of closest wave to mouse if 't' is pressed */
|
int track_dset = -2; /* used to find dataset of closest wave to mouse if 't' is pressed */
|
||||||
xRect *r = NULL;
|
xRect *r = NULL;
|
||||||
int access_cond = !graph_use_ctrl_key || ( (state & ControlMask) && !(state & ShiftMask) );
|
int access_cond = !graph_use_ctrl_key || (state & ControlMask);
|
||||||
|
|
||||||
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 */
|
||||||
|
|
@ -392,9 +393,27 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
||||||
dbg(1, "mouse inside: %d\n", i);
|
dbg(1, "mouse inside: %d\n", i);
|
||||||
setup_graph_data(i, 0, gr);
|
setup_graph_data(i, 0, gr);
|
||||||
|
|
||||||
|
/* move hcursor1 */
|
||||||
|
if(event == MotionNotify && (state & Button1Mask) && (xctx->graph_flags & 512 )) {
|
||||||
|
double c;
|
||||||
|
|
||||||
|
c = G_Y(xctx->mousey);
|
||||||
|
if(gr->logy) c = pow(10, c);
|
||||||
|
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "hcursor1_y", dtoa(c)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* move hcursor2 */
|
||||||
|
else if(event == MotionNotify && (state & Button1Mask) && (xctx->graph_flags & 1024 )) {
|
||||||
|
double c;
|
||||||
|
|
||||||
|
c = G_Y(xctx->mousey);
|
||||||
|
if(gr->logy) c = pow(10, c);
|
||||||
|
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "hcursor2_y", dtoa(c)));
|
||||||
|
}
|
||||||
|
|
||||||
/* move cursor1 */
|
/* move cursor1 */
|
||||||
/* set cursor position from master graph x-axis */
|
/* set cursor position from master graph x-axis */
|
||||||
if(event == MotionNotify && (state & Button1Mask) && (xctx->graph_flags & 16 )) {
|
else if(event == MotionNotify && (state & Button1Mask) && (xctx->graph_flags & 16 )) {
|
||||||
double c;
|
double c;
|
||||||
|
|
||||||
c = G_X(xctx->mousex);
|
c = G_X(xctx->mousex);
|
||||||
|
|
@ -448,7 +467,27 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
||||||
zoom_m = (xctx->mousex - gr->x1) / gr->w;
|
zoom_m = (xctx->mousex - gr->x1) / gr->w;
|
||||||
if(event == ButtonPress && button == Button1) {
|
if(event == ButtonPress && button == Button1) {
|
||||||
/* dragging cursors when mouse is very close */
|
/* dragging cursors when mouse is very close */
|
||||||
if(xctx->graph_flags & 2) {
|
if(xctx->graph_flags & 128) { /* hcursor1 */
|
||||||
|
double cursor;
|
||||||
|
cursor = gr->hcursor1_y;
|
||||||
|
if(gr->logy ) {
|
||||||
|
cursor = mylog10(cursor);
|
||||||
|
}
|
||||||
|
if(fabs(xctx->mousey - W_Y(cursor)) < 10) {
|
||||||
|
xctx->graph_flags |= 512; /* Start move hcursor1 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(xctx->graph_flags & 256) { /* hcursor2 */
|
||||||
|
double cursor;
|
||||||
|
cursor = gr->hcursor2_y;
|
||||||
|
if(gr->logy ) {
|
||||||
|
cursor = mylog10(cursor);
|
||||||
|
}
|
||||||
|
if(fabs(xctx->mousey - W_Y(cursor)) < 10) {
|
||||||
|
xctx->graph_flags |= 1024; /* Start move hcursor2 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(xctx->graph_flags & 2) { /* cursor1 */
|
||||||
double cursor1;
|
double cursor1;
|
||||||
if(r->flags & 4) { /* private_cursor */
|
if(r->flags & 4) { /* private_cursor */
|
||||||
const char *s = get_tok_value(r->prop_ptr, "cursor1_x", 0);
|
const char *s = get_tok_value(r->prop_ptr, "cursor1_x", 0);
|
||||||
|
|
@ -467,7 +506,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
||||||
xctx->graph_flags |= 16; /* Start move cursor1 */
|
xctx->graph_flags |= 16; /* Start move cursor1 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(xctx->graph_flags & 4) {
|
if(xctx->graph_flags & 4) { /* cursor2 */
|
||||||
double cursor2;
|
double cursor2;
|
||||||
if(r->flags & 4) { /* private_cursor */
|
if(r->flags & 4) { /* private_cursor */
|
||||||
const char *s = get_tok_value(r->prop_ptr, "cursor2_x", 0);
|
const char *s = get_tok_value(r->prop_ptr, "cursor2_x", 0);
|
||||||
|
|
@ -518,7 +557,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
||||||
}
|
}
|
||||||
redraw_all_at_end = 1;
|
redraw_all_at_end = 1;
|
||||||
}
|
}
|
||||||
|
/* Numerically set cursor position */
|
||||||
if(xctx->graph_flags & 4) {
|
if(xctx->graph_flags & 4) {
|
||||||
double cursor2;
|
double cursor2;
|
||||||
if(r->flags & 4) { /* private_cursor */
|
if(r->flags & 4) { /* private_cursor */
|
||||||
|
|
@ -678,7 +717,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
||||||
/* check if user clicked on a wave label -> draw wave in bold */
|
/* check if user clicked on a wave label -> draw wave in bold */
|
||||||
if(event == ButtonPress && button == Button3 &&
|
if(event == ButtonPress && button == Button3 &&
|
||||||
edit_wave_attributes(2, i, gr)) {
|
edit_wave_attributes(2, i, gr)) {
|
||||||
draw_graph(i, 1 + 8 + (xctx->graph_flags & 6), gr, NULL); /* draw data in graph box */
|
draw_graph(i, 1 + 8 + (xctx->graph_flags & (2 | 4 | 128 | 256)), gr, NULL); /* draw data in graph box */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* save mouse position when doing pan operations */
|
/* save mouse position when doing pan operations */
|
||||||
|
|
@ -800,7 +839,12 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
||||||
dbg(1, "%g %g %g %g - %d %d\n", gr->gx1, gr->gy1, gr->gx2, gr->gy2, gr->divx, gr->divy);
|
dbg(1, "%g %g %g %g - %d %d\n", gr->gx1, gr->gy1, gr->gx2, gr->gy2, gr->divx, gr->divy);
|
||||||
if( event == KeyPress || event == ButtonPress || event == MotionNotify ) {
|
if( event == KeyPress || event == ButtonPress || event == MotionNotify ) {
|
||||||
/* move cursor1 */
|
/* move cursor1 */
|
||||||
if(event == MotionNotify && (state & Button1Mask) && (xctx->graph_flags & 16 )) {
|
if(event == MotionNotify && (state & Button1Mask) && (xctx->graph_flags & 16)) {
|
||||||
|
need_redraw = 1;
|
||||||
|
}
|
||||||
|
/* move hcursor1 or hcursor2 */
|
||||||
|
else if(event == MotionNotify && i == xctx->graph_master &&
|
||||||
|
(state & Button1Mask) && (xctx->graph_flags & (512 | 1024) )) {
|
||||||
need_redraw = 1;
|
need_redraw = 1;
|
||||||
}
|
}
|
||||||
/* move cursor2 */
|
/* move cursor2 */
|
||||||
|
|
@ -811,7 +855,8 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
||||||
else need_redraw = 1;
|
else need_redraw = 1;
|
||||||
}
|
}
|
||||||
else /* drag waves with mouse */
|
else /* drag waves with mouse */
|
||||||
if(event == MotionNotify && (state & Button1Mask) && !xctx->graph_bottom) {
|
if(event == MotionNotify && (state & Button1Mask) && !xctx->graph_bottom &&
|
||||||
|
!(xctx->graph_flags & (16 | 32 | 512 | 1024))) {
|
||||||
double delta;
|
double delta;
|
||||||
if(xctx->graph_left) {
|
if(xctx->graph_left) {
|
||||||
if(i == xctx->graph_master) {
|
if(i == xctx->graph_master) {
|
||||||
|
|
@ -856,6 +901,36 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(event == ButtonPress && button == Button3) {
|
||||||
|
/* Numerically set hcursor position */
|
||||||
|
if(xctx->graph_flags & 128) {
|
||||||
|
double cursor;
|
||||||
|
cursor = gr->hcursor1_y;
|
||||||
|
if(gr->logy ) {
|
||||||
|
cursor = mylog10(cursor);
|
||||||
|
}
|
||||||
|
if(fabs(xctx->mousey - W_Y(cursor)) < 10) {
|
||||||
|
tclvareval("input_line {Pos:} {} ", dtoa_eng(cursor), NULL);
|
||||||
|
cursor = atof_spice(tclresult());
|
||||||
|
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "hcursor1_y", dtoa(cursor)));
|
||||||
|
}
|
||||||
|
need_redraw = 1;
|
||||||
|
}
|
||||||
|
/* Numerically set hcursor position */
|
||||||
|
if(xctx->graph_flags & 256) {
|
||||||
|
double cursor;
|
||||||
|
cursor = gr->hcursor2_y;
|
||||||
|
if(gr->logy ) {
|
||||||
|
cursor = mylog10(cursor);
|
||||||
|
}
|
||||||
|
if(fabs(xctx->mousey - W_Y(cursor)) < 10) {
|
||||||
|
tclvareval("input_line {Pos:} {} ", dtoa_eng(cursor), NULL);
|
||||||
|
cursor = atof_spice(tclresult());
|
||||||
|
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "hcursor2_y", dtoa(cursor)));
|
||||||
|
}
|
||||||
|
need_redraw = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if((button == Button5 && !(state & ShiftMask))) {
|
else if((button == Button5 && !(state & ShiftMask))) {
|
||||||
double delta;
|
double delta;
|
||||||
if(xctx->graph_left) {
|
if(xctx->graph_left) {
|
||||||
|
|
@ -890,6 +965,30 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* y hcursor1 toggle */
|
||||||
|
else if(key == 'A' && access_cond && i == xctx->graph_master) {
|
||||||
|
xctx->graph_flags ^= 128;
|
||||||
|
need_redraw = 1;
|
||||||
|
if(xctx->graph_flags & 128) {
|
||||||
|
double c = G_Y(xctx->mousey);
|
||||||
|
if(gr->logy) c = pow(10, c);
|
||||||
|
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "hcursor1_y", dtoa(c)));
|
||||||
|
} else {
|
||||||
|
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "hcursor1_y", NULL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* y hcursor2 toggle */
|
||||||
|
else if(key == 'B' && access_cond && i == xctx->graph_master) {
|
||||||
|
xctx->graph_flags ^= 256;
|
||||||
|
need_redraw = 1;
|
||||||
|
if(xctx->graph_flags & 256) {
|
||||||
|
double c = G_Y(xctx->mousey);
|
||||||
|
if(gr->logy) c = pow(10, c);
|
||||||
|
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "hcursor2_y", dtoa(c)));
|
||||||
|
} else {
|
||||||
|
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "hcursor2_y", NULL));
|
||||||
|
}
|
||||||
|
}
|
||||||
else if(key == 't' && access_cond ) {
|
else if(key == 't' && access_cond ) {
|
||||||
if(track_dset != -2) {
|
if(track_dset != -2) {
|
||||||
/*
|
/*
|
||||||
|
|
@ -1161,7 +1260,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
||||||
else if( event == ButtonRelease) {
|
else if( event == ButtonRelease) {
|
||||||
if(button != Button3) {
|
if(button != Button3) {
|
||||||
xctx->ui_state &= ~GRAPHPAN;
|
xctx->ui_state &= ~GRAPHPAN;
|
||||||
xctx->graph_flags &= ~(16 | 32); /* clear move cursor flags */
|
xctx->graph_flags &= ~(16 | 32 | 512 | 1024); /* clear move cursor flags */
|
||||||
}
|
}
|
||||||
/* zoom area by mouse drag */
|
/* zoom area by mouse drag */
|
||||||
else if(button == Button3 && (xctx->ui_state & GRAPHPAN) &&
|
else if(button == Button3 && (xctx->ui_state & GRAPHPAN) &&
|
||||||
|
|
@ -1191,7 +1290,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
||||||
} /* else if( event == ButtonRelease) */
|
} /* else if( event == ButtonRelease) */
|
||||||
if(need_redraw || need_all_redraw) {
|
if(need_redraw || need_all_redraw) {
|
||||||
setup_graph_data(i, 0, gr);
|
setup_graph_data(i, 0, gr);
|
||||||
draw_graph(i, 1 + 8 + (xctx->graph_flags & 6), gr, NULL); /* draw data in each graph box */
|
draw_graph(i, 1 + 8 + (xctx->graph_flags & (4 | 2 | 128 | 256)), gr, NULL); /* draw data in each graph box */
|
||||||
}
|
}
|
||||||
} /* for(i=0; i< xctx->rects[GRIDLAYER]; i++ */
|
} /* for(i=0; i< xctx->rects[GRIDLAYER]; i++ */
|
||||||
|
|
||||||
|
|
@ -2699,17 +2798,27 @@ int rstate; /* (reduced state, without ShiftMask) */
|
||||||
}
|
}
|
||||||
if(key==XK_Right && state == ControlMask) {
|
if(key==XK_Right && state == ControlMask) {
|
||||||
int save = xctx->semaphore;
|
int save = xctx->semaphore;
|
||||||
|
if(waves_selected(event, key, state, button)) {
|
||||||
|
waves_callback(event, mx, my, key, button, aux, state);
|
||||||
|
break;
|
||||||
|
}
|
||||||
if(xctx->semaphore >= 2) break;
|
if(xctx->semaphore >= 2) break;
|
||||||
xctx->semaphore = 0;
|
xctx->semaphore = 0;
|
||||||
tcleval("next_tab");
|
tcleval("next_tab");
|
||||||
xctx->semaphore = save;
|
xctx->semaphore = save;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if(key==XK_Left && state == ControlMask) {
|
if(key==XK_Left && state == ControlMask) {
|
||||||
int save = xctx->semaphore;
|
int save = xctx->semaphore;
|
||||||
|
if(waves_selected(event, key, state, button)) {
|
||||||
|
waves_callback(event, mx, my, key, button, aux, state);
|
||||||
|
break;
|
||||||
|
}
|
||||||
if(xctx->semaphore >= 2) break;
|
if(xctx->semaphore >= 2) break;
|
||||||
xctx->semaphore = 0;
|
xctx->semaphore = 0;
|
||||||
tcleval("prev_tab");
|
tcleval("prev_tab");
|
||||||
xctx->semaphore = save;
|
xctx->semaphore = save;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if(key==XK_Right && !(state & ControlMask)) /* left */
|
if(key==XK_Right && !(state & ControlMask)) /* left */
|
||||||
{
|
{
|
||||||
|
|
@ -3589,20 +3698,32 @@ int rstate; /* (reduced state, without ShiftMask) */
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if(key=='A' && rstate == ControlMask) /* only for graph (toggle hcursor1 if graph_use_ctrl_key set) */
|
||||||
|
{
|
||||||
|
if(waves_selected(event, key, state, button)) {
|
||||||
|
waves_callback(event, mx, my, key, button, aux, state);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
if(key=='A' && rstate == 0) /* toggle show netlist */
|
if(key=='A' && rstate == 0) /* toggle show netlist */
|
||||||
{
|
{
|
||||||
int net_s;
|
int net_s;
|
||||||
net_s = tclgetboolvar("netlist_show");
|
if(waves_selected(event, key, state, button)) {
|
||||||
net_s = !net_s;
|
waves_callback(event, mx, my, key, button, aux, state);
|
||||||
if(net_s) {
|
break;
|
||||||
tcleval("alert_ { enabling show netlist window} {}");
|
}
|
||||||
tclsetvar("netlist_show","1");
|
net_s = tclgetboolvar("netlist_show");
|
||||||
}
|
net_s = !net_s;
|
||||||
else {
|
if(net_s) {
|
||||||
tcleval("alert_ { disabling show netlist window } {}");
|
tcleval("alert_ { enabling show netlist window} {}");
|
||||||
tclsetvar("netlist_show","0");
|
tclsetvar("netlist_show","1");
|
||||||
}
|
}
|
||||||
break;
|
else {
|
||||||
|
tcleval("alert_ { disabling show netlist window } {}");
|
||||||
|
tclsetvar("netlist_show","0");
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if(key=='>') {
|
if(key=='>') {
|
||||||
if(xctx->semaphore >= 2) break;
|
if(xctx->semaphore >= 2) break;
|
||||||
|
|
@ -3628,8 +3749,20 @@ int rstate; /* (reduced state, without ShiftMask) */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if(key=='B' && rstate == ControlMask) /* only for graph (toggle hcursor2 if graph_use_ctrl_key set) */
|
||||||
|
{
|
||||||
|
if(waves_selected(event, key, state, button)) {
|
||||||
|
waves_callback(event, mx, my, key, button, aux, state);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
if(key=='B' && rstate == 0) /* edit schematic header/license */
|
if(key=='B' && rstate == 0) /* edit schematic header/license */
|
||||||
{
|
{
|
||||||
|
if(waves_selected(event, key, state, button)) {
|
||||||
|
waves_callback(event, mx, my, key, button, aux, state);
|
||||||
|
break;
|
||||||
|
}
|
||||||
tcleval("update_schematic_header");
|
tcleval("update_schematic_header");
|
||||||
}
|
}
|
||||||
if(key=='b' && rstate==0) /* merge schematic */
|
if(key=='b' && rstate==0) /* merge schematic */
|
||||||
|
|
|
||||||
80
src/draw.c
80
src/draw.c
|
|
@ -2905,7 +2905,18 @@ void setup_graph_data(int i, int skip, Graph_ctx *gr)
|
||||||
gr->digital = 0;
|
gr->digital = 0;
|
||||||
gr->rainbow = 0;
|
gr->rainbow = 0;
|
||||||
gr->linewidth_mult = tclgetdoublevar("graph_linewidth_mult");
|
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) {
|
if(!skip) {
|
||||||
gr->gx1 = 0;
|
gr->gx1 = 0;
|
||||||
gr->gx2 = 1e-6;
|
gr->gx2 = 1e-6;
|
||||||
|
|
@ -3016,9 +3027,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 < 30 ? 30 : tmp;
|
gr->marginx = tmp < 50 ? 50 : tmp;
|
||||||
tmp = gr->rh * 0.14;
|
tmp = gr->rh * 0.14;
|
||||||
gr->marginy = tmp < 35 ? 35 : tmp;
|
gr->marginy = tmp < 40 ? 40 : 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 */
|
||||||
|
|
@ -3031,7 +3042,7 @@ void setup_graph_data(int i, int skip, Graph_ctx *gr)
|
||||||
gr->h = gr->y2 - gr->y1;
|
gr->h = gr->y2 - gr->y1;
|
||||||
|
|
||||||
/* label text size calculations */
|
/* label text size calculations */
|
||||||
gr->txtsizelab = gr->marginy * 0.007;
|
gr->txtsizelab = gr->marginy * 0.006;
|
||||||
/*
|
/*
|
||||||
* tmp = gr->w * 0.00044;
|
* tmp = gr->w * 0.00044;
|
||||||
* if(tmp < gr->txtsizelab) gr->txtsizelab = tmp;
|
* if(tmp < gr->txtsizelab) gr->txtsizelab = tmp;
|
||||||
|
|
@ -3042,8 +3053,8 @@ void setup_graph_data(int i, int skip, Graph_ctx *gr)
|
||||||
gr->digtxtsizelab = 0.001200 * fabs( gr->h / gr->posh * gr->gh );
|
gr->digtxtsizelab = 0.001200 * fabs( gr->h / gr->posh * gr->gh );
|
||||||
|
|
||||||
/* x axis, y axis text sizes */
|
/* x axis, y axis text sizes */
|
||||||
gr->txtsizey = gr->h / gr->divy * 0.009;
|
gr->txtsizey = gr->h / gr->divy * 0.0095;
|
||||||
tmp = gr->marginx * 0.005;
|
tmp = gr->marginx * 0.003;
|
||||||
if(tmp < gr->txtsizey) gr->txtsizey = tmp;
|
if(tmp < gr->txtsizey) gr->txtsizey = tmp;
|
||||||
tmp = gr->marginy * 0.02;
|
tmp = gr->marginy * 0.02;
|
||||||
if(tmp < gr->txtsizey) gr->txtsizey = tmp;
|
if(tmp < gr->txtsizey) gr->txtsizey = tmp;
|
||||||
|
|
@ -3136,7 +3147,7 @@ static void draw_cursor_difference(double c1, double c2, Graph_ctx *gr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void draw_hcursor(double active_cursory, double other_cursory, int cursor_color, Graph_ctx *gr)
|
static void draw_hcursor(double active_cursory, int cursor_color, Graph_ctx *gr)
|
||||||
{
|
{
|
||||||
double yy, pos = active_cursory;
|
double yy, pos = active_cursory;
|
||||||
double tx1, ty1, tx2, ty2, dtmp;
|
double tx1, ty1, tx2, ty2, dtmp;
|
||||||
|
|
@ -3145,10 +3156,11 @@ static void draw_hcursor(double active_cursory, double other_cursory, int cursor
|
||||||
double txtsize = gr->txtsizey;
|
double txtsize = gr->txtsizey;
|
||||||
double th;
|
double th;
|
||||||
|
|
||||||
|
if(gr->digital) return;
|
||||||
if(gr->logy) pos = mylog10(pos);
|
if(gr->logy) pos = mylog10(pos);
|
||||||
yy = W_Y(pos);
|
yy = W_Y(pos);
|
||||||
if(yy >= gr->y1 && yy <= gr->y2) {
|
if(yy >= gr->y1 && yy <= gr->y2) {
|
||||||
drawline(cursor_color, NOW, gr->rx1, yy, gr->rx2, yy, 1, NULL);
|
drawline(cursor_color, NOW, gr->rx1 + 10, yy, gr->rx2 - 10, yy, 1, NULL);
|
||||||
if(gr->unity != 1.0)
|
if(gr->unity != 1.0)
|
||||||
my_snprintf(tmpstr, S(tmpstr), " %.5g%c ", gr->unity * active_cursory , gr->unity_suffix);
|
my_snprintf(tmpstr, S(tmpstr), " %.5g%c ", gr->unity * active_cursory , gr->unity_suffix);
|
||||||
else
|
else
|
||||||
|
|
@ -3164,7 +3176,41 @@ static void draw_hcursor(double active_cursory, double other_cursory, int cursor
|
||||||
|
|
||||||
static void draw_hcursor_difference(double c1, double c2, Graph_ctx *gr)
|
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 */
|
/* sweep variables on x-axis, node labels */
|
||||||
|
|
@ -3747,7 +3793,7 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
|
||||||
#if 0
|
#if 0
|
||||||
dbg(0, "draw_graph(): window: %d %d %d %d\n", xctx->areax1, xctx->areay1, xctx->areax2, xctx->areay2);
|
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(): 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
|
#endif
|
||||||
|
|
||||||
/* draw stuff */
|
/* draw stuff */
|
||||||
|
|
@ -4074,12 +4120,12 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
|
||||||
if((flags & 4)) draw_cursor(cursor2, cursor1, 3, gr);
|
if((flags & 4)) draw_cursor(cursor2, cursor1, 3, gr);
|
||||||
/* difference between cursors */
|
/* 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);
|
||||||
/* hcursor1 */
|
|
||||||
if(flags & 128) draw_hcursor(9.012345, 15.0, 15, gr);
|
|
||||||
/* hcursor2 */
|
|
||||||
if(flags & 256) draw_hcursor(15.0, 9.012345, 16, gr);
|
|
||||||
/* difference between hcursors */
|
/* difference between hcursors */
|
||||||
if((flags & 128) && (flags & 256)) draw_hcursor_difference(9.012345, 15.00, gr);
|
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(flags & 1) { /* copy save buffer to screen */
|
||||||
if(!xctx->draw_window) {
|
if(!xctx->draw_window) {
|
||||||
|
|
@ -4130,8 +4176,10 @@ static void draw_graph_all(int flags)
|
||||||
if(xctx->enable_layer[GRIDLAYER]) for(i = 0; i < xctx->rects[GRIDLAYER]; ++i) {
|
if(xctx->enable_layer[GRIDLAYER]) for(i = 0; i < xctx->rects[GRIDLAYER]; ++i) {
|
||||||
xRect *r = &xctx->rect[GRIDLAYER][i];
|
xRect *r = &xctx->rect[GRIDLAYER][i];
|
||||||
if(r->flags & 1) {
|
if(r->flags & 1) {
|
||||||
|
int flags2;
|
||||||
setup_graph_data(i, 0, &xctx->graph_struct);
|
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 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
|
||||||
if(argc > 2) {
|
if(argc > 2) {
|
||||||
int i = atoi(argv[2]);
|
int i = atoi(argv[2]);
|
||||||
|
setup_graph_data(i, 0, &xctx->graph_struct);
|
||||||
if(argc > 3) {
|
if(argc > 3) {
|
||||||
flags = atoi(argv[3]);
|
flags = atoi(argv[3]);
|
||||||
} else {
|
} else {
|
||||||
/* 2: draw cursor 1
|
/* 2: draw cursor 1
|
||||||
* 4: draw cursor 2 */
|
* 4: draw cursor 2
|
||||||
flags = 1 + 8 + (xctx->graph_flags & (2 + 4));
|
* 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);
|
draw_graph(i, flags, &xctx->graph_struct, NULL);
|
||||||
}
|
}
|
||||||
Tcl_ResetResult(interp);
|
Tcl_ResetResult(interp);
|
||||||
|
|
|
||||||
|
|
@ -888,6 +888,7 @@ typedef struct {
|
||||||
int logx, logy;
|
int logx, logy;
|
||||||
int rainbow; /* draw multiple datasets with incrementing colors */
|
int rainbow; /* draw multiple datasets with incrementing colors */
|
||||||
double linewidth_mult; /* multiply factor for waveforms line width */
|
double linewidth_mult; /* multiply factor for waveforms line width */
|
||||||
|
double hcursor1_y, hcursor2_y; /* hcursor positions */
|
||||||
} Graph_ctx;
|
} Graph_ctx;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue