add graph_use_ctrl_key variable (default 0) to force holding Control key to interact with graphs. This avoid graphs "stealing" events that are expected to work on the schematic

This commit is contained in:
stefan schippers 2024-11-29 22:52:36 +01:00
parent 7ca8857302
commit ebc4babdd4
6 changed files with 86 additions and 40 deletions

View File

@ -95,7 +95,7 @@ Set output for netlist.
.TP .TP
.B -N, --netlist_filename .B -N, --netlist_filename
Set name (only name, not path) of top level netlist file. Set name (only name or full path) of top level netlist file.
.TP .TP
.B -t, --tedax .B -t, --tedax

View File

@ -68,7 +68,7 @@ Options:
--netlist_path <path> --netlist_path <path>
-o <path> Set output path for netlist. -o <path> Set output path for netlist.
--netlist_filename <file> --netlist_filename <file>
-N <file> Set name (only name, not path) of top level netlist file. -N <file> Set name (only name or full path) of top level netlist file.
-t --tedax Set netlist type to tEDAx. -t --tedax Set netlist type to tEDAx.
-s --spice Set netlist type to SPICE. -s --spice Set netlist type to SPICE.
-y --symbol Set netlist type to SYMBOL (used when drawing symbols) -y --symbol Set netlist type to SYMBOL (used when drawing symbols)

View File

@ -30,14 +30,16 @@ static int waves_selected(int event, KeySym key, int state, int button)
{ {
int rstate; /* state without ShiftMask */ int rstate; /* state without ShiftMask */
int i, check; int i, check;
int graph_use_ctrl_key = tclgetboolvar("graph_use_ctrl_key");
int is_inside = 0, skip = 0; int is_inside = 0, skip = 0;
static unsigned int excl = STARTZOOM | STARTRECT | STARTLINE | STARTWIRE | static unsigned int excl = STARTZOOM | STARTRECT | STARTLINE | STARTWIRE |
STARTPAN | STARTSELECT | STARTMOVE | STARTCOPY; STARTPAN | STARTSELECT | STARTMOVE | STARTCOPY;
int draw_xhair = tclgetboolvar("draw_crosshair"); int draw_xhair = tclgetboolvar("draw_crosshair");
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 sifficient */ rstate &= ~ShiftMask; /* don't use ShiftMask, identifying characters is sufficient */
if(xctx->ui_state & excl) skip = 1; if(xctx->ui_state & excl) skip = 1;
else if(event != -3 && sch_waves_loaded() < 0 ) skip = 1; else if(event != -3 && sch_waves_loaded() < 0 ) skip = 1;
else if(graph_use_ctrl_key && !(state & ControlMask)) skip = 1;
else if(SET_MODMASK) skip = 1; else if(SET_MODMASK) skip = 1;
else if(event == MotionNotify && (state & Button2Mask)) skip = 1; else if(event == MotionNotify && (state & Button2Mask)) skip = 1;
else if(event == MotionNotify && (state & Button1Mask) && (state & ShiftMask)) skip = 1; else if(event == MotionNotify && (state & Button1Mask) && (state & ShiftMask)) skip = 1;
@ -350,6 +352,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
{ {
Graph_ctx *gr; Graph_ctx *gr;
int rstate; /* reduced state wit ShiftMask bit filtered out */ int rstate; /* reduced state wit ShiftMask bit filtered out */
int graph_use_ctrl_key = tclgetboolvar("graph_use_ctrl_key");
int i, redraw_all_at_end = 0, need_all_redraw = 0, need_redraw = 0, dataset = 0; int i, redraw_all_at_end = 0, need_all_redraw = 0, need_redraw = 0, dataset = 0;
double xx1 = 0.0, xx2 = 0.0, yy1, yy2; double xx1 = 0.0, xx2 = 0.0, yy1, yy2;
double delta_threshold = 0.25; double delta_threshold = 0.25;
@ -357,11 +360,11 @@ 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) );
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 sifficient */ rstate &= ~ShiftMask; /* don't use ShiftMask, identifying characters is sifficient */
#if HAS_CAIRO==1 #if HAS_CAIRO==1
cairo_save(xctx->cairo_ctx); cairo_save(xctx->cairo_ctx);
cairo_save(xctx->cairo_save_ctx); cairo_save(xctx->cairo_save_ctx);
@ -498,7 +501,6 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
if(fabs(xctx->mousex - W_X(cursor1)) < 10) { if(fabs(xctx->mousex - W_X(cursor1)) < 10) {
tclvareval("input_line {Pos:} {} ", dtoa_eng(cursor1), NULL); tclvareval("input_line {Pos:} {} ", dtoa_eng(cursor1), NULL);
cursor1 = atof_spice(tclresult()); cursor1 = atof_spice(tclresult());
here(cursor1);
if(r->flags & 4) { if(r->flags & 4) {
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "cursor1_x", dtoa(cursor1))); my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "cursor1_x", dtoa(cursor1)));
} else { } else {
@ -546,7 +548,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
} }
} }
/* x cursor1 toggle */ /* x cursor1 toggle */
else if((key == 'a' && rstate == 0) ) { else if(key == 'a' && access_cond) {
xctx->graph_flags ^= 2; xctx->graph_flags ^= 2;
need_all_redraw = 1; need_all_redraw = 1;
if(xctx->graph_flags & 2) { if(xctx->graph_flags & 2) {
@ -563,7 +565,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
} }
} }
/* x cursor2 toggle */ /* x cursor2 toggle */
else if((key == 'b') ) { else if(key == 'b' && access_cond) {
int floaters = there_are_floaters(); int floaters = there_are_floaters();
xctx->graph_flags ^= 4; xctx->graph_flags ^= 4;
@ -593,7 +595,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
} }
} }
/* swap cursors */ /* swap cursors */
else if((key == 's') ) { else if((key == 's' && access_cond) ) {
double tmp, cursor1, cursor2; double tmp, cursor1, cursor2;
int floaters = there_are_floaters(); int floaters = there_are_floaters();
@ -641,13 +643,13 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
else need_all_redraw = 1; else need_all_redraw = 1;
} }
/* measurement tooltip */ /* measurement tooltip */
else if((key == 'm') ) { else if((key == 'm') && access_cond) {
xctx->graph_flags ^= 64; xctx->graph_flags ^= 64;
if(!(xctx->graph_flags & 64)) { if(!(xctx->graph_flags & 64)) {
tcleval("graph_show_measure stop"); tcleval("graph_show_measure stop");
} }
} }
else if((key == 't') ) { else if(key == 't' && access_cond) {
if(!gr->digital) { if(!gr->digital) {
const char *d = get_tok_value(r->prop_ptr, "dataset", 0); const char *d = get_tok_value(r->prop_ptr, "dataset", 0);
if(d[0]) { if(d[0]) {
@ -882,7 +884,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
} }
} }
} }
else if((key == 't') ) { else if(key == 't' && access_cond ) {
if(track_dset != -2) { if(track_dset != -2) {
/* /*
const char *unlocked = strstr(get_tok_value(r->prop_ptr, "flags", 0), "unlocked"); const char *unlocked = strstr(get_tok_value(r->prop_ptr, "flags", 0), "unlocked");
@ -1100,7 +1102,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
} }
} }
} }
else if(key == 'f') { else if(key == 'f' && access_cond) {
if(xctx->raw && xctx->raw->values) { if(xctx->raw && xctx->raw->values) {
if(xctx->graph_left) { /* full Y zoom*/ if(xctx->graph_left) { /* full Y zoom*/
if(i == xctx->graph_master) { if(i == xctx->graph_master) {
@ -1782,12 +1784,14 @@ static void context_menu_action(double mx, double my)
/* Mouse wheel events */ /* Mouse wheel events */
static int handle_mouse_wheel(int event, int mx, int my, KeySym key, int button, int aux, int state) static int handle_mouse_wheel(int event, int mx, int my, KeySym key, int button, int aux, int state)
{ {
int graph_use_ctrl_key = tclgetboolvar("graph_use_ctrl_key");
if(button==Button5 && state == 0 ) { if(button==Button5 && state == 0 ) {
if(waves_selected(event, key, state, button)) { if(waves_selected(event, key, state, button)) {
waves_callback(event, mx, my, key, button, aux, state); waves_callback(event, mx, my, key, button, aux, state);
return 1; return 1;
} }
view_unzoom(CADZOOMSTEP); view_unzoom(CADZOOMSTEP);
return 0;
} }
else if(button==Button4 && state == 0 ) { else if(button==Button4 && state == 0 ) {
if(waves_selected(event, key, state, button)) { if(waves_selected(event, key, state, button)) {
@ -1795,33 +1799,37 @@ static int handle_mouse_wheel(int event, int mx, int my, KeySym key, int button,
return 1; return 1;
} }
view_zoom(CADZOOMSTEP); view_zoom(CADZOOMSTEP);
return 0;
} }
else if(button==Button4 && (state & ShiftMask) && !(state & Button2Mask)) { if(!graph_use_ctrl_key) {
if(waves_selected(event, key, state, button)) { if(button==Button4 && (state & ShiftMask) && !(state & Button2Mask)) {
waves_callback(event, mx, my, key, button, aux, state); if(waves_selected(event, key, state, button)) {
return 1; waves_callback(event, mx, my, key, button, aux, state);
} return 1;
xctx->xorigin+=-CADMOVESTEP*xctx->zoom/2.; }
draw(); xctx->xorigin+=-CADMOVESTEP*xctx->zoom/2.;
redraw_w_a_l_r_p_rubbers(); draw();
} redraw_w_a_l_r_p_rubbers();
else if(button==Button5 && (state & ShiftMask) && !(state & Button2Mask)) { }
if(waves_selected(event, key, state, button)) { else if(button==Button5 && (state & ShiftMask) && !(state & Button2Mask)) {
waves_callback(event, mx, my, key, button, aux, state); if(waves_selected(event, key, state, button)) {
return 1; waves_callback(event, mx, my, key, button, aux, state);
} return 1;
xctx->xorigin-=-CADMOVESTEP*xctx->zoom/2.; }
draw(); xctx->xorigin-=-CADMOVESTEP*xctx->zoom/2.;
redraw_w_a_l_r_p_rubbers(); draw();
} redraw_w_a_l_r_p_rubbers();
else if(button==Button4 && (state & ControlMask) && !(state & Button2Mask)) { }
xctx->yorigin+=-CADMOVESTEP*xctx->zoom/2.; else if(button==Button4 && (state & ControlMask) && !(state & Button2Mask)) {
draw(); xctx->yorigin+=-CADMOVESTEP*xctx->zoom/2.;
redraw_w_a_l_r_p_rubbers(); draw();
} redraw_w_a_l_r_p_rubbers();
else if(button==Button5 && (state & ControlMask) && !(state & Button2Mask)) { }
xctx->yorigin-=-CADMOVESTEP*xctx->zoom/2.; else if(button==Button5 && (state & ControlMask) && !(state & Button2Mask)) {
draw(); xctx->yorigin-=-CADMOVESTEP*xctx->zoom/2.;
draw();
redraw_w_a_l_r_p_rubbers();
}
} }
return 0; return 0;
} }
@ -2343,6 +2351,10 @@ int rstate; /* (reduced state, without ShiftMask) */
} }
if(key == 'b' && rstate==ControlMask) /* toggle show text in symbol */ if(key == 'b' && rstate==ControlMask) /* toggle show text in symbol */
{ {
if(waves_selected(event, key, state, button)) {
waves_callback(event, mx, my, key, button, aux, state);
break;
}
xctx->sym_txt =!xctx->sym_txt; xctx->sym_txt =!xctx->sym_txt;
if(xctx->sym_txt) { if(xctx->sym_txt) {
/* tcleval("alert_ { enabling text in symbol} {}"); */ /* tcleval("alert_ { enabling text in symbol} {}"); */
@ -2736,6 +2748,14 @@ int rstate; /* (reduced state, without ShiftMask) */
} }
break; break;
} }
if(key=='t' && (rstate & ControlMask))
{
if(waves_selected(event, key, state, button)) {
waves_callback(event, mx, my, key, button, aux, state);
break;
}
break;
}
if(key=='r' /* && !xctx->ui_state */ && rstate==0) /* start rect */ if(key=='r' /* && !xctx->ui_state */ && rstate==0) /* start rect */
{ {
dbg(1, "callback(): start rect\n"); dbg(1, "callback(): start rect\n");
@ -2769,6 +2789,10 @@ int rstate; /* (reduced state, without ShiftMask) */
if(key=='s' && rstate == ControlMask ) /* save 20121201 */ if(key=='s' && rstate == ControlMask ) /* save 20121201 */
{ {
if(xctx->semaphore >= 2) break; if(xctx->semaphore >= 2) break;
if(waves_selected(event, key, state, button)) {
waves_callback(event, mx, my, key, button, aux, state);
break;
}
/* check if unnamed schematic, use saveas in this case */ /* check if unnamed schematic, use saveas in this case */
if(!strcmp(xctx->sch[xctx->currsch],"") || strstr(xctx->sch[xctx->currsch], "untitled")) { if(!strcmp(xctx->sch[xctx->currsch],"") || strstr(xctx->sch[xctx->currsch], "untitled")) {
saveas(NULL, SCHEMATIC); saveas(NULL, SCHEMATIC);
@ -2856,6 +2880,10 @@ int rstate; /* (reduced state, without ShiftMask) */
} }
if(key=='a' && rstate == ControlMask) /* select all */ if(key=='a' && rstate == ControlMask) /* select all */
{ {
if(waves_selected(event, key, state, button)) {
waves_callback(event, mx, my, key, button, aux, state);
break;
}
select_all(); select_all();
break; break;
} }
@ -3385,6 +3413,10 @@ int rstate; /* (reduced state, without ShiftMask) */
if(key=='m' && rstate == ControlMask && if(key=='m' && rstate == ControlMask &&
!(xctx->ui_state & (STARTMOVE | STARTCOPY))) /* move selection */ !(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->mx_double_save=xctx->mousex_snap;
xctx->my_double_save=xctx->mousey_snap; xctx->my_double_save=xctx->mousey_snap;
if(!tclgetboolvar("enable_stretch")) if(!tclgetboolvar("enable_stretch"))
@ -3619,6 +3651,10 @@ int rstate; /* (reduced state, without ShiftMask) */
if(key=='f' && rstate == ControlMask) /* search */ if(key=='f' && rstate == ControlMask) /* search */
{ {
if(xctx->semaphore >= 2) break; if(xctx->semaphore >= 2) break;
if(waves_selected(event, key, state, button)) {
waves_callback(event, mx, my, key, button, aux, state);
break;
}
tcleval("property_search"); tcleval("property_search");
break; break;
} }

View File

@ -21,7 +21,7 @@ Options:
--netlist_path <path> --netlist_path <path>
-o <path> Set output path for netlist. -o <path> Set output path for netlist.
--netlist_filename <file> --netlist_filename <file>
-N <file> Set name (only name, not path) of top level netlist file. -N <file> Set name (only name or full path) of top level netlist file.
-t --tedax Set netlist type to tEDAx. -t --tedax Set netlist type to tEDAx.
-s --spice Set netlist type to SPICE. -s --spice Set netlist type to SPICE.
-y --symbol Set netlist type to SYMBOL (used when drawing symbols) -y --symbol Set netlist type to SYMBOL (used when drawing symbols)

View File

@ -7022,7 +7022,8 @@ set tctx::global_list {
graph_change_done graph_digital graph_dialog_default_geometry graph_change_done graph_digital graph_dialog_default_geometry
graph_legend graph_linewidth_mult graph_logx graph_legend graph_linewidth_mult graph_logx
graph_logy graph_private_cursor graph_rainbow graph_schname graph_sel_color graph_sel_wave graph_logy graph_private_cursor graph_rainbow graph_schname graph_sel_color graph_sel_wave
graph_selected graph_sort graph_unlocked hide_empty_graphs hide_symbols tctx::hsize graph_selected graph_sort graph_unlocked graph_use_ctrl_key
hide_empty_graphs hide_symbols tctx::hsize
incr_hilight incremental_select infowindow_text intuitive_interface incr_hilight incremental_select infowindow_text intuitive_interface
keep_symbols launcher_default_program keep_symbols launcher_default_program
light_colors line_width live_cursor2_backannotate local_netlist_dir lvs_ignore light_colors line_width live_cursor2_backannotate local_netlist_dir lvs_ignore
@ -8454,6 +8455,7 @@ set_ne lvs_netlist 0
set_ne top_is_subckt 0 set_ne top_is_subckt 0
set_ne lvs_ignore 0 set_ne lvs_ignore 0
set_ne hide_empty_graphs 0 ;# if set to 1 waveform boxes will be hidden if no raw file loaded set_ne hide_empty_graphs 0 ;# if set to 1 waveform boxes will be hidden if no raw file loaded
set_ne graph_use_ctrl_key 0;# if set forces to use Control key to operate on graphs
set_ne spiceprefix 1 set_ne spiceprefix 1
set_ne verilog_2001 1 set_ne verilog_2001 1
set_ne verilog_bitblast 0 set_ne verilog_bitblast 0

View File

@ -559,6 +559,14 @@
#### default: 0 (not set) #### default: 0 (not set)
# set show_hidden_texts 1 # set show_hidden_texts 1
###########################################################################
#### USE CTRL MODIFIER TO OPERATE ON GRAPHS WITH MOUSE & KEYBOARD
###########################################################################
#### if enabled forces to hold Control key pressed to operate on graphs
#### to prevent "graph event stealing to schematic"
#### Default: 0 (not set)
# set graph_use_ctrl_key 1
########################################################################### ###########################################################################
#### HIDE GRAPHS IF NO SPICE DATA LOADED #### HIDE GRAPHS IF NO SPICE DATA LOADED
########################################################################### ###########################################################################