measurement tooltip in graphs

This commit is contained in:
Stefan Frederik 2022-01-03 18:43:34 +01:00
parent 27a8e2246a
commit 625495e27a
7 changed files with 141 additions and 28 deletions

View File

@ -25,14 +25,15 @@
static int waves_selected(int event, int key, int state, int button)
{
int i;
int is_inside = 0;
if(state & Mod1Mask) return 0;
if(event == MotionNotify && (state & Button2Mask)) return 0;
if(event == ButtonPress && button == Button2) return 0;
if(event == ButtonRelease && button == Button2) return 0;
if(xctx->ui_state & STARTSELECT) return 0;
int is_inside = 0, skip = 0;
if(xctx->ui_state & STARTPAN2) skip = 1;
if(state & Mod1Mask) skip = 1;
if(event == MotionNotify && (state & Button2Mask)) skip = 1;
if(event == ButtonPress && button == Button2) skip = 1;
if(event == ButtonRelease && button == Button2) skip = 1;
if(xctx->ui_state & STARTSELECT) skip = 1;
for(i=0; i< xctx->rects[GRIDLAYER]; i++) {
if(!skip) for(i=0; i< xctx->rects[GRIDLAYER]; i++) {
xRect *r;
r = &xctx->rect[GRIDLAYER][i];
if(!(r->flags & 1) ) continue;
@ -41,6 +42,9 @@ static int waves_selected(int event, int key, int state, int button)
is_inside = 1;
}
}
if(!is_inside && (xctx->graph_flags & 64) ) {
tcleval("graph_stop_measure");
}
return is_inside;
}
@ -166,6 +170,7 @@ void start_wire(double mx, double my)
#define G_Y(y) (((y) - dy) / cy)
/* for digital graphs (ypos1, ypos2 instead of wy1, wy2) */
#define DG_Y(y) (((y) - ddy) / dcy)
#define DW_Y(y) (dcy * (y) + ddy)
/* xctx->graph_flags:
* 1:
@ -174,6 +179,7 @@ void start_wire(double mx, double my)
* 8: dnu, reserved, used in draw_graphs()
* 16: move cursor1
* 32: move cursor2
* 64: show measurement tooltip
*/
static int waves_callback(int event, int mx, int my, KeySym key, int button, int aux, int state)
@ -228,6 +234,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
dx = x1 - wx1 * cx;
cy = (y1 - y2) / (wy2 - wy1);
dy = y2 - wy1 * cy;
/* move cursor1 */
/* set cursor position from master graph x-axis */
if(event == MotionNotify && (state & Button1Mask) && (xctx->graph_flags & 16 )) {
@ -266,19 +273,21 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
if((key == 'a') ) {
xctx->graph_flags ^= 2;
need_redraw = 1;
xctx->graph_flags |= 1; /* apply to all graphs */
if(xctx->graph_flags & 2) xctx->graph_cursor1_x = G_X(xctx->mousex);
}
/* x cursor2 toggle */
else if((key == 'b') ) {
xctx->graph_flags ^= 4;
need_redraw = 1;
xctx->graph_flags |= 1; /* apply to all graphs */
if(xctx->graph_flags & 4) xctx->graph_cursor2_x = G_X(xctx->mousex);
}
else if(state & ControlMask) xctx->graph_flags |= 1;
else xctx->graph_flags &= ~1;
/* measurement tooltip */
else if((key == 'm') ) {
xctx->graph_flags ^= 64;
if(!(xctx->graph_flags & 64)) {
tcleval("graph_stop_measure");
}
}
break;
} /* if( POINTINSIDE(...) */
} /* for(i=0; i < xctx->rects[GRIDLAYER]; i++) */
@ -350,6 +359,38 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
dcy = (y1 - y2) / (ypos2 - ypos1);
ddy = y2 - ypos1 * dcy;
/* destroy / show measurement widget */
if(i == xctx->graph_master) {
if(xctx->graph_flags & 64) {
if( POINTINSIDE(xctx->mousex_snap, xctx->mousey_snap, x1, y1, x2, y2)) {
char sx[100], sy[100];
double yval;
if(digital) {
double deltag = wy2 - wy1;
double s1 = 0.1; /* 10 waveforms fit in graph if unscaled vertically */
double s2 = .08; /* 20% spacing between traces */
double c = s1 * deltag;
deltag = deltag * s1 / s2;
yval=(DG_Y(xctx->mousey) - c) / s2;
yval=fmod(yval, deltag ) + wy1;
if(yval > wy2 + deltag * (s1 + s2) * 0.5) yval -= deltag;
} else {
yval = G_Y(xctx->mousey);
}
my_snprintf(sx, S(sx), "%.4g", G_X(xctx->mousex));
my_snprintf(sy, S(sy), "%.4g", yval);
tclvareval("set measure_text \"y=", sy, "\nx=", sx, "\"", NULL);
tcleval("graph_show_measure");
} else {
tcleval("graph_stop_measure");
}
}
}
dbg(1, "%g %g %g %g - %d %d\n", wx1, wy1, wx2, wy2, divx, divy);
if( event == KeyPress || event == ButtonPress || event == MotionNotify ) {
/* move cursor1 */
@ -1819,10 +1860,6 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
if(key=='l' && state == 0) /* start line */
{
int prev_state = xctx->ui_state;
if( waves_selected(event, key, state, button)) {
waves_callback(event, mx, my, key, button, aux, state);
break;
}
start_line(mx, my);
if(prev_state == STARTLINE) {
tcleval("set constrained_move 0" );
@ -1912,6 +1949,10 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
}
if(key=='m' && state==0 && !(xctx->ui_state & (STARTMOVE | STARTCOPY))) /* move selection */
{
if(waves_selected(event, key, state, button)) {
waves_callback(event, mx, my, key, button, aux, state);
break;
}
xctx->mx_double_save=xctx->mousex_snap;
xctx->my_double_save=xctx->mousey_snap;
move_objects(START,0,0,0);

View File

@ -1817,9 +1817,9 @@ static void draw_graph_bus_points(const char *ntok, int first, int last,
{
int p, i;
double deltag = wy2 - wy1;
double s1 = 0.1 * deltag; /* 10 waveforms fit in graph if unscaled vertically */
double s1 = 0.1; /* 10 waveforms fit in graph if unscaled vertically */
double s2 = .08; /* 20% spacing between traces */
double c = (n_nodes - wcnt) * s1;
double c = (n_nodes - wcnt) * s1 * deltag - wy1 * s2;
double x1 = W_X(xctx->graph_values[sweep_idx][first]);
double x2 = W_X(xctx->graph_values[sweep_idx][last-1]);
double ylow = DW_Y(c + wy2 * s2); /* swapped as xschem Y coordinates are top-bottom */
@ -1911,9 +1911,9 @@ static void draw_graph_points(int v, int first, int last,
double c;
if(digital) {
s1 = 0.1 * deltag; /* 10 waveforms fit in graph if unscaled vertically */
s1 = 0.1; /* 10 waveforms fit in graph if unscaled vertically */
s2 = .08; /* 20% spacing between traces */
c = (n_nodes - wcnt) * s1;
c = (n_nodes - wcnt) * s1 * deltag - wy1 * s2;
}
if( !digital || (c >= ypos1 && c <= ypos2) ) {
for(p = first ; p <= last; p++) {
@ -2217,8 +2217,9 @@ void draw_graph(int c, int i, int flags)
if(digital) {
double xt = x1 - 10 * txtsizelab;
double deltag = wy2 - wy1;
double s1 = 0.1 * deltag; /* 10 waveforms fit in graph if unscaled vertically */
double yt = s1 * (double)(n_nodes - wcnt);
double s1 = 0.1; /* 10 waveforms fit in graph if unscaled vertically */
double s2 = .08; /* 20% spacing between traces */
double yt = s1 * (double)(n_nodes - wcnt) * deltag - wy1 * s2;
if(yt <= ypos2 && yt >= ypos1) {
draw_string(wave_color, NOW, tmpstr, 2, 0, 0, 0, xt, DW_Y(yt), digtxtsizelab, digtxtsizelab);

View File

@ -1894,3 +1894,26 @@ void print_hilight_net(int show)
my_free(782, &filetmp2);
}
void list_hilights(void)
{
int i, first = 1;
Hilight_hashentry *entry;
Node_hashentry *node_entry;
Tcl_ResetResult(interp);
prepare_netlist_structs(1); /* use full prepare_netlist_structs(1) to recognize pin direction */
/* when creating pins from hilight nets 20171221 */
for(i=0;i<HASHSIZE;i++) {
entry=xctx->hilight_table[i];
while(entry) {
node_entry = bus_node_hash_lookup(entry->token, "", XLOOKUP, 0, "", "", "", "");
if(node_entry && (node_entry->d.port == 0 || !strcmp(xctx->sch_path[xctx->currsch], ".") )) {
if(!first) Tcl_AppendResult(interp, " ", NULL);
Tcl_AppendResult(interp, entry->path + 1,
entry->token[0] == '#' ? entry->token + 1 : entry->token, NULL);
first = 0;
}
entry = entry ->next ;
}
}
}

View File

@ -308,6 +308,8 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
"flags=1\n"
"y1=0\n"
"y2=5\n"
"ypos1=0\n"
"ypos2=5\n"
"divy=4\n"
"subdivy=1\n"
"x1=0\n"
@ -1505,6 +1507,19 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
Tcl_ResetResult(interp);
}
else if(!strcmp(argv[1], "list_hilights"))
{
const char *sep;
cmd_found = 1;
if(argc > 2) {
sep = argv[2];
} else {
sep = "{ }";
}
list_hilights();
tclvareval("join [lsort -decreasing -dictionary {", tclresult(), "}] ", sep, NULL);
}
else if(!strcmp(argv[1], "list_tokens") && argc == 4)
{
cmd_found = 1;

View File

@ -1320,6 +1320,7 @@ extern Node_hashentry **get_node_table_ptr(void);
extern void change_elem_order(void);
extern int set_different_token(char **s,const char *new, const char *old, int object, int n);
extern void print_hilight_net(int show);
extern void list_hilights(void);
extern void change_layer();
extern void launcher();
extern void windowid(const char *winpath);

View File

@ -1278,6 +1278,35 @@ proc waves {} {
}
# ============================================================
proc graph_stop_measure {} {
global measure_id
if { [info exists measure_id] } {
after cancel $measure_id
unset measure_id
}
destroy .measure
}
proc graph_show_measure {} {
global measure_id measure_text
set_ne measure_text "y=\nx="
if { [info exists measure_id] } {
after cancel $measure_id
unset measure_id
}
destroy .measure
set measure_id [after 400 {
toplevel .measure -bg {}
label .measure.lab -text $measure_text -bg black -fg yellow -justify left
pack .measure.lab
wm overrideredirect .measure 1
wm geometry .measure +[expr {[winfo pointerx .measure] +10}]+[expr {[winfo pointery .measure] -8}]
}]
}
proc get_shell { curpath } {
global netlist_dir debug_var
global terminal
@ -3807,8 +3836,9 @@ proc no_open_dialogs {} {
## list of globals to save/restore on context switching
## EXCEPTIONS, not to be saved/restored:
## "textwindow_wcounter" should be kept global as it is the number of open textwindows
## "viewdata_wcounter" should be kept global as it is the number of open viewdatas
## "textwindow_wcounter" should be kept unique as it is the number of open textwindows
## "viewdata_wcounter" should be kept unique as it is the number of open viewdatas
## "measure_id" should be kept unique since we allow only one measure tooltip in graphs
set tctx::global_list {
auto_hilight autotrim_wires bespice_listen_port big_grid_points bus_replacement_char
@ -3820,6 +3850,7 @@ set tctx::global_list {
flat_netlist fullscreen gaw_fd gaw_tcp_address globfilter hide_empty_graphs hide_symbols hsize hspice_netlist
incr_hilight infowindow_text INITIALINSTDIR INITIALLOADDIR INITIALPROPDIR INITIALTEXTDIR
input_line_cmd input_line_data launcher_default_program light_colors line_width local_netlist_dir
measure_text
myload_d myload_default_geometry myload_dir1 myload_dir2 myload_dirs2 myload_files1 myload_files2 myload_index1
myload_retval myload_sash_pos myload_sel myload_type myload_yview netlist_dir netlist_show
netlist_type no_change_attrs noprint_libs old_selected_tok
@ -3933,6 +3964,7 @@ global env has_x OS
}
}
"
bind $topwin <Leave> "graph_stop_measure"
bind $topwin <Expose> "xschem callback %W %T %x %y 0 %w %h %s"
bind $topwin <Double-Button-1> "xschem callback %W -3 %x %y 0 %b 0 %s"
bind $topwin <Double-Button-2> "xschem callback %W -3 %x %y 0 %b 0 %s"

View File

@ -81,10 +81,10 @@ color=3 unitx=n subdivy=4
}
B 2 1840 -880 2890 -420 {flags=3
digital=1
y1 = 0
y2 = 1.6
ypos1=-0.233024
ypos2=2.1797
y1 = -1
y2 = 2
ypos1=0.175559
ypos2=3.6959
divy = 1
x1=1.26295e-07
x2=2.03758e-07