diff --git a/src/callback.c b/src/callback.c index 39c7cf98..f80f355f 100644 --- a/src/callback.c +++ b/src/callback.c @@ -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); diff --git a/src/draw.c b/src/draw.c index f6f3ba5d..2af0ffd4 100644 --- a/src/draw.c +++ b/src/draw.c @@ -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); diff --git a/src/hilight.c b/src/hilight.c index ec9cc46e..61c24e47 100644 --- a/src/hilight.c +++ b/src/hilight.c @@ -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;ihilight_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 ; + } + } +} diff --git a/src/scheduler.c b/src/scheduler.c index c74194ac..4d28a114 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -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; diff --git a/src/xschem.h b/src/xschem.h index af7ece5f..0b6bafab 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -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); diff --git a/src/xschem.tcl b/src/xschem.tcl index dc5bd4b6..2412d6cb 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -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 "graph_stop_measure" bind $topwin "xschem callback %W %T %x %y 0 %w %h %s" bind $topwin "xschem callback %W -3 %x %y 0 %b 0 %s" bind $topwin "xschem callback %W -3 %x %y 0 %b 0 %s" diff --git a/xschem_library/rom8k/rom8k.sch b/xschem_library/rom8k/rom8k.sch index ca2de56e..5c605e72 100644 --- a/xschem_library/rom8k/rom8k.sch +++ b/xschem_library/rom8k/rom8k.sch @@ -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