context menu added in drawing area (right mouse button)

This commit is contained in:
Stefan Frederik 2021-11-04 01:13:44 +01:00
parent 5482cd0c2a
commit e85559efec
5 changed files with 4628 additions and 4434 deletions

View File

@ -76,12 +76,13 @@ Alt + LeftButton Unselect selected object
Alt + LeftButton drag
Unselect objects by area
RightButton Edit property of object under the mouse
else edit global schematic / symbol property string
RightButton Context menu
Shift + RightButton Edit property of object under the mouse
else edit global schematic / symbol property string
using the specified (or default) text editor.
Shift + RightButton Select object under the mouse and if label/pin
select attached nets
Ctrl + RightButton Select object under the mouse and if label/pin
select attached nets up to net junctions
LeftButton Double click Terminate Polygon placement
@ -109,7 +110,7 @@ ctrl '0-9' set current layer (4 -13)
'0' set selected net or label to logic value '0'
'1' set selected net or label to logic value '1'
'2' set selected net or label to logic value 'X'
'3' toggle selected net or label: 1->0, 0->1, X->X
'3' toggle selected net or label: 1->0, 0->1, X->X
- 'a' Make symbol from pin list of current schematic
ctrl 'a' Select all
shift 'A' Toggle show netlist

View File

@ -1,4 +1,4 @@
/* File: callback.c
/* file: callback.c
*
* This file is part of XSCHEM,
* a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit
@ -47,6 +47,26 @@ void redraw_w_a_l_r_p_rubbers(void)
}
}
void start_place_symbol(double mx, double my)
{
xctx->last_command = 0;
rebuild_selected_array();
if(xctx->lastsel && xctx->sel_array[0].type==ELEMENT) {
Tcl_VarEval(interp, "set INITIALINSTDIR [file dirname {",
abs_sym_path(xctx->inst[xctx->sel_array[0].n].name, ""), "}]", NULL);
}
unselect_all();
xctx->mx_save = mx; xctx->my_save = my;
xctx->mx_double_save = xctx->mousex_snap;
xctx->my_double_save = xctx->mousey_snap;
if(place_symbol(-1,NULL,xctx->mousex_snap, xctx->mousey_snap, 0, 0, NULL, 4, 1, 1/* to_push_undo */) ) {
xctx->mousey_snap = xctx->my_double_save;
xctx->mousex_snap = xctx->mx_double_save;
move_objects(START,0,0,0);
xctx->ui_state |= PLACE_SYMBOL;
}
}
void start_line(double mx, double my)
{
xctx->last_command = STARTLINE;
@ -650,7 +670,7 @@ int callback(int event, int mx, int my, KeySym key,
dbg(1, "callback(): new color: %d\n",color_index[xctx->rectcolor]);
break;
}
if(key==XK_Delete && (xctx->ui_state & SELECTION) ) /* delete objects */
if(key==XK_Delete && (xctx->ui_state & SELECTION) ) /* delete selection */
{
if(xctx->semaphore >= 2) break;
delete(1/* to_push_undo */);break;
@ -795,7 +815,7 @@ int callback(int event, int mx, int my, KeySym key,
}
break;
}
if(key=='x' && state == ControlMask) /* cut into clipboard */
if(key=='x' && state == ControlMask) /* cut selection into clipboard */
{
if(xctx->semaphore >= 2) break;
rebuild_selected_array();
@ -805,7 +825,7 @@ int callback(int event, int mx, int my, KeySym key,
}
break;
}
if(key=='c' && state == ControlMask) /* save clipboard */
if(key=='c' && state == ControlMask) /* copy selection into clipboard */
{
if(xctx->semaphore >= 2) break;
rebuild_selected_array();
@ -839,7 +859,7 @@ int callback(int event, int mx, int my, KeySym key,
Tcl_VarEval(interp, "xschem load [lindex $recentfile 0]", NULL);
break;
}
if(key=='O' && state == ShiftMask) /* Toggle light/dark colorscheme 20171113 */
if(key=='O' && state == ShiftMask) /* toggle light/dark colorscheme 20171113 */
{
dark_colorscheme=!dark_colorscheme;
tclsetvar("dark_colorscheme", dark_colorscheme ? "1" : "0");
@ -848,17 +868,17 @@ int callback(int event, int mx, int my, KeySym key,
draw();
break;
}
if(key=='v' && state == ControlMask) /* load clipboard */
if(key=='v' && state == ControlMask) /* paste from clipboard */
{
if(xctx->semaphore >= 2) break;
merge_file(2,".sch");
break;
}
if(key=='Q' && state == (ControlMask | ShiftMask) ) /* view prop */
if(key=='Q' && state == (ControlMask | ShiftMask) ) /* view attributes */
{
edit_property(2);break;
}
if(key=='q' && state==0) /* edit prop */
if(key=='q' && state==0) /* edit attributes */
{
if(xctx->semaphore >= 2) break;
edit_property(0);
@ -880,7 +900,7 @@ int callback(int event, int mx, int my, KeySym key,
}
break;
}
if(key=='Q' && state == ShiftMask) /* edit prop with vim */
if(key=='Q' && state == ShiftMask) /* edit attributes in editor */
{
if(xctx->semaphore >= 2) break;
edit_property(1);break;
@ -893,26 +913,8 @@ int callback(int event, int mx, int my, KeySym key,
if(key==XK_Insert || (key == 'I' && state == ShiftMask) ) /* insert sym */
{
if(xctx->semaphore >= 2) break;
xctx->last_command = 0;
#if 1 /* enable on request also in scheduler.c */
rebuild_selected_array();
if(xctx->lastsel && xctx->sel_array[0].type==ELEMENT) {
Tcl_VarEval(interp, "set INITIALINSTDIR [file dirname {",
abs_sym_path(xctx->inst[xctx->sel_array[0].n].name, ""), "}]", NULL);
}
#endif
unselect_all();
start_place_symbol(mx, my);
/* place_symbol(-1,NULL,xctx->mousex_snap, xctx->mousey_snap, 0, 0, NULL,3, 1);*/
xctx->mx_save = mx; xctx->my_save = my;
xctx->mx_double_save = xctx->mousex_snap;
xctx->my_double_save = xctx->mousey_snap;
if(place_symbol(-1,NULL,xctx->mousex_snap, xctx->mousey_snap, 0, 0, NULL, 4, 1, 1/*to_push_undo*/) ) {
xctx->mousey_snap = xctx->my_double_save;
xctx->mousex_snap = xctx->mx_double_save;
move_objects(START,0,0,0);
xctx->ui_state |= PLACE_SYMBOL;
}
break;
}
if(key=='s' && state & Mod1Mask) /* reload */
@ -1125,7 +1127,7 @@ int callback(int event, int mx, int my, KeySym key,
place_net_label(1);
break;
}
if(key >= '0' && key <= '4' && state == 0) { /* Toggle pin logic level */
if(key >= '0' && key <= '4' && state == 0) { /* toggle pin logic level */
if(xctx->semaphore >= 2) break;
if(key == '4') logic_set(-1, 1);
else logic_set(key - '0', 1);
@ -1135,7 +1137,7 @@ int callback(int event, int mx, int my, KeySym key,
place_net_label(0);
break;
}
if(key=='F' && state==ShiftMask) /* Flip */
if(key=='F' && state==ShiftMask) /* flip */
{
if(xctx->ui_state & STARTMOVE) move_objects(FLIP,0,0,0);
else if(xctx->ui_state & STARTCOPY) copy_objects(FLIP);
@ -1151,7 +1153,7 @@ int callback(int event, int mx, int my, KeySym key,
}
break;
}
if(key=='\\' && state==0) /* Fullscreen */
if(key=='\\' && state==0) /* fullscreen */
{
dbg(1, "callback(): toggle fullscreen\n");
toggle_fullscreen();
@ -1172,7 +1174,7 @@ int callback(int event, int mx, int my, KeySym key,
}
break;
}
if(key=='R' && state==ShiftMask) /* Rotate */
if(key=='R' && state==ShiftMask) /* rotate */
{
if(xctx->ui_state & STARTMOVE) move_objects(ROTATE,0,0,0);
else if(xctx->ui_state & STARTCOPY) copy_objects(ROTATE);
@ -1189,7 +1191,7 @@ int callback(int event, int mx, int my, KeySym key,
break;
}
if(key=='r' && state==Mod1Mask) /* Rotate objects around their anchor points 20171208 */
if(key=='r' && state==Mod1Mask) /* rotate objects around their anchor points 20171208 */
{
if(xctx->ui_state & STARTMOVE) move_objects(ROTATE|ROTATELOCAL,0,0,0);
else if(xctx->ui_state & STARTCOPY) copy_objects(ROTATE|ROTATELOCAL);
@ -1204,7 +1206,7 @@ int callback(int event, int mx, int my, KeySym key,
}
break;
}
if(key=='m' && state==0 && !(xctx->ui_state & (STARTMOVE | STARTCOPY)))/* move selected obj. */
if(key=='m' && state==0 && !(xctx->ui_state & (STARTMOVE | STARTCOPY))) /* move selection */
{
xctx->mx_save = mx; xctx->my_save = my;
xctx->mx_double_save=xctx->mousex_snap;
@ -1213,7 +1215,7 @@ int callback(int event, int mx, int my, KeySym key,
break;
}
if(key=='c' && state==0 && /* copy selected obj. */
if(key=='c' && state==0 && /* duplicate selection */
!(xctx->ui_state & (STARTMOVE | STARTCOPY)))
{
if(xctx->semaphore >= 2) break;
@ -1223,25 +1225,25 @@ int callback(int event, int mx, int my, KeySym key,
copy_objects(START);
break;
}
if(key=='n' && state==Mod1Mask) /* Empty schematic in new window */
if(key=='n' && state==Mod1Mask) /* empty schematic in new window */
{
if(xctx->semaphore >= 2) break;
tcleval("xschem new_window");
break;
}
if(key=='N' && state==(ShiftMask|Mod1Mask) ) /* Empty symbol in new window */
if(key=='N' && state==(ShiftMask|Mod1Mask) ) /* empty symbol in new window */
{
if(xctx->semaphore >= 2) break;
tcleval("xschem new_symbol_window");
break;
}
if(key=='n' && state==ControlMask) /* New schematic */
if(key=='n' && state==ControlMask) /* new schematic */
{
if(xctx->semaphore >= 2) break;
tcleval("xschem clear SCHEMATIC");
break;
}
if(key=='N' && state==(ShiftMask|ControlMask) ) /* New symbol */
if(key=='N' && state==(ShiftMask|ControlMask) ) /* new symbol */
{
if(xctx->semaphore >= 2) break;
tcleval("xschem clear SYMBOL");
@ -1433,7 +1435,6 @@ int callback(int event, int mx, int my, KeySym key,
break;
}
break;
case ButtonPress: /* end operation */
dbg(1, "callback(): ButtonPress ui_state=%ld state=%d\n",xctx->ui_state,state);
if(xctx->ui_state & STARTPAN2) {
@ -1441,40 +1442,134 @@ int callback(int event, int mx, int my, KeySym key,
xctx->mx_save = mx; xctx->my_save = my;
xctx->mx_double_save=xctx->mousex_snap;
xctx->my_double_save=xctx->mousey_snap;
break;
}
if(button==Button5 && state == 0 ) view_unzoom(CADZOOMSTEP);
else if(button == Button3 && state == ControlMask && xctx->semaphore <2)
{
if(xctx->semaphore >= 2) break;
sel = select_object(xctx->mousex, xctx->mousey, SELECTED, 0);
if(sel) select_connected_wires(1);
break;
}
else if(button == Button3 && state == ShiftMask && xctx->semaphore <2)
{
if(xctx->semaphore >= 2) break;
sel = select_object(xctx->mousex, xctx->mousey, SELECTED, 0);
if(sel) select_connected_wires(0);
break;
}
else if(button == Button3 && state == 0 && xctx->semaphore <2) {
if(!(xctx->ui_state & STARTPOLYGON) && !(state & Mod1Mask) ) {
int ret;
int prev_state;
tcleval("context_menu");
ret = atoi(tclresult());
switch(ret) {
case 1:
start_place_symbol(mx, my);
break;
case 2:
prev_state = xctx->ui_state;
start_wire(mx, my);
if(prev_state == STARTWIRE) {
tcleval("set constrained_move 0" );
constrained_move=0;
}
break;
case 3:
prev_state = xctx->ui_state;
start_line(mx, my);
if(prev_state == STARTLINE) {
tcleval("set constrained_move 0" );
constrained_move=0;
}
break;
case 4:
xctx->mx_save = mx; xctx->my_save = my;
xctx->mx_double_save=xctx->mousex_snap;
xctx->my_double_save=xctx->mousey_snap;
xctx->last_command = 0;
unselect_all();
select_object(xctx->mousex,xctx->mousey,SELECTED, 1);
new_rect(PLACE);
break;
case 5:
xctx->mx_save = mx; xctx->my_save = my;
xctx->mx_double_save=xctx->mousex_snap;
xctx->my_double_save=xctx->mousey_snap;
xctx->last_command = 0;
new_polygon(PLACE);
break;
case 6:
xctx->last_command = 0;
place_text(1, xctx->mousex_snap, xctx->mousey_snap); /* 1 = draw text */
break;
case 7: /* cut selection into clipboard */
rebuild_selected_array();
if(state & ShiftMask) {
edit_property(1);
} else {
if(xctx->lastsel) { /* 20071203 check if something selected */
save_selection(2);
delete(1/* to_push_undo */);
}
break;
case 8: /* paste from clipboard */
merge_file(2,".sch");
break;
case 9: /* load most recent file */
Tcl_VarEval(interp, "xschem load [lindex $recentfile 0]", NULL);
break;
case 10: /* edit attributes */
edit_property(0);
break;
case 11: /* edit attributes in editor */
edit_property(1);
break;
case 12:
descend_schematic(0);
break;
case 13:
descend_symbol();
break;
case 14:
go_back(1);
break;
case 15: /* copy selection into clipboard */
rebuild_selected_array();
if(xctx->lastsel) {
save_selection(2);
}
break;
case 16: /* move selection */
if(!(xctx->ui_state & (STARTMOVE | STARTCOPY))) {
xctx->mx_save = mx; xctx->my_save = my;
xctx->mx_double_save=xctx->mousex_snap;
xctx->my_double_save=xctx->mousey_snap;
move_objects(START,0,0,0);
}
break;
case 17: /* duplicate selection */
if(!(xctx->ui_state & (STARTMOVE | STARTCOPY))) {
xctx->mx_save = mx; xctx->my_save = my;
xctx->mx_double_save=xctx->mousex_snap;
xctx->my_double_save=xctx->mousey_snap;
copy_objects(START);
}
break;
case 18: /* delete selection */
if(xctx->ui_state & SELECTION) delete(1/* to_push_undo */);
break;
case 19: /* place arc */
xctx->mx_save = mx; xctx->my_save = my;
xctx->mx_double_save=xctx->mousex_snap;
xctx->my_double_save=xctx->mousey_snap;
xctx->last_command = 0;
new_arc(PLACE, 180.);
break;
case 20: /* place circle */
xctx->mx_save = mx; xctx->my_save = my;
xctx->mx_double_save=xctx->mousex_snap;
xctx->my_double_save=xctx->mousey_snap;
xctx->last_command = 0;
new_arc(PLACE, 360.);
break;
default:
break;
}
}
else if(button==Button4 && state == 0 ) view_zoom(CADZOOMSTEP);
else if(button==Button4 && (state & ShiftMask) && !(state & Button2Mask)) {
xctx->xorigin+=-CADMOVESTEP*xctx->zoom/2.;
draw();
@ -1511,7 +1606,6 @@ int callback(int event, int mx, int my, KeySym key,
else if(button==Button2 && (state == 0)) {
pan2(START, mx, my);
xctx->ui_state |= STARTPAN2;
break;
}
else if(xctx->semaphore >= 2) { /* button1 click to select another instance while edit prop dialog open */
if(button==Button1 && state==0 && tclgetvar("edit_symbol_prop_new_sel")[0]) {
@ -1520,7 +1614,6 @@ int callback(int event, int mx, int my, KeySym key,
select_object(xctx->mousex, xctx->mousey, SELECTED, 0);
rebuild_selected_array();
}
break;
}
else if(button==Button1)
{

View File

@ -35,12 +35,13 @@ Alt + LeftButton Unselect selected object
Alt + LeftButton drag
Unselect objects by area
RightButton Edit property of object under the mouse
else edit global schematic / symbol property string
RightButton Context menu
Shift + RightButton Edit property of object under the mouse
else edit global schematic / symbol property string
using the specified (or default) text editor.
Shift + RightButton Select object under the mouse and if label/pin
select attached nets
Ctrl + RightButton Select object under the mouse and if label/pin
select attached nets up to net junctions
LeftButton Double click Terminate Polygon placement

View File

@ -611,6 +611,13 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
my_snprintf(s, S(s), "%d",xctx->instances);
Tcl_SetResult(interp, s,TCL_VOLATILE);
}
else if(!strcmp(argv[2],"lastsel")) {
rebuild_selected_array();
if( xctx->lastsel != 0 )
Tcl_SetResult(interp, "1",TCL_STATIC);
else
Tcl_SetResult(interp, "0",TCL_STATIC);
}
else if(!strcmp(argv[2],"line_width")) {
char s[40];
my_snprintf(s, S(s), "%g", xctx->lw);

View File

@ -3151,11 +3151,103 @@ proc balloon_show {w arg} {
-font fixed -text $arg]
set wmx [winfo rootx $w]
set wmy [expr {[winfo rooty $w]+[winfo height $w]}]
wm geometry $top [winfo reqwidth $top.txt]x[
winfo reqheight $top.txt]+$wmx+$wmy
wm geometry $top [winfo reqwidth $top.txt]x[winfo reqheight $top.txt]+$wmx+$wmy
raise $top
}
proc context_menu { } {
global retval
set retval 0
set font {Sans 8 bold}
set selection [expr {[xschem get lastsel] eq {1}}]
toplevel .ctxmenu
wm overrideredirect .ctxmenu 1
set x [expr {[winfo pointerx .ctxmenu] - 10}]
set y [expr {[winfo pointery .ctxmenu] - 10}]
if { !$selection} {
button .ctxmenu.b9 -text {Open most recent} -padx 1 -pady 0 -anchor w -activebackground red \
-font [subst $font] -command {set retval 9; destroy .ctxmenu}
}
button .ctxmenu.b10 -text {Edit attributes} -padx 1 -pady 0 -anchor w -activebackground red \
-font [subst $font] -command {set retval 10; destroy .ctxmenu}
button .ctxmenu.b11 -text {Edit attr in editor} -padx 1 -pady 0 -anchor w -activebackground red \
-font [subst $font] -command {set retval 11; destroy .ctxmenu}
if {$selection} {
button .ctxmenu.b12 -text {Descend schematic} -padx 1 -pady 0 -anchor w -activebackground red \
-font [subst $font] -command {set retval 12; destroy .ctxmenu}
button .ctxmenu.b13 -text {Descend symbol} -padx 1 -pady 0 -anchor w -activebackground red \
-font [subst $font] -command {set retval 13; destroy .ctxmenu}
button .ctxmenu.b18 -text {Delete selection} -padx 1 -pady 0 -anchor w -activebackground red \
-font [subst $font] -command {set retval 18; destroy .ctxmenu}
button .ctxmenu.b7 -text {Cut selection} -padx 1 -pady 0 -anchor w -activebackground red \
-font [subst $font] -command {set retval 7; destroy .ctxmenu}
button .ctxmenu.b15 -text {Copy selection} -padx 1 -pady 0 -anchor w -activebackground red \
-font [subst $font] -command {set retval 15; destroy .ctxmenu}
button .ctxmenu.b16 -text {Move Selection} -padx 1 -pady 0 -anchor w -activebackground red \
-font [subst $font] -command {set retval 16; destroy .ctxmenu}
button .ctxmenu.b17 -text {Duplicate Selection} -padx 1 -pady 0 -anchor w -activebackground red \
-font [subst $font] -command {set retval 17; destroy .ctxmenu}
}
if {!$selection} {
button .ctxmenu.b14 -text {Go to upper level} -padx 1 -pady 0 -anchor w -activebackground red \
-font [subst $font] -command {set retval 14; destroy .ctxmenu}
button .ctxmenu.b1 -text {Place symbol} -padx 1 -pady 0 -anchor w -activebackground red \
-font [subst $font] -command {set retval 1; destroy .ctxmenu}
button .ctxmenu.b2 -text {Place wire} -padx 1 -pady 0 -anchor w -activebackground red \
-font [subst $font] -command {set retval 2; destroy .ctxmenu}
button .ctxmenu.b3 -text {Place line} -padx 1 -pady 0 -anchor w -activebackground red \
-font [subst $font] -command {set retval 3; destroy .ctxmenu}
button .ctxmenu.b4 -text {Place box} -padx 1 -pady 0 -anchor w -activebackground red \
-font [subst $font] -command {set retval 4; destroy .ctxmenu}
button .ctxmenu.b5 -text {Place polygon} -padx 1 -pady 0 -anchor w -activebackground red \
-font [subst $font] -command {set retval 5; destroy .ctxmenu}
button .ctxmenu.b19 -text {Place arc} -padx 1 -pady 0 -anchor w -activebackground red \
-font [subst $font] -command {set retval 19; destroy .ctxmenu}
button .ctxmenu.b20 -text {Place circle} -padx 1 -pady 0 -anchor w -activebackground red \
-font [subst $font] -command {set retval 20; destroy .ctxmenu}
button .ctxmenu.b6 -text {Place text} -padx 1 -pady 0 -anchor w -activebackground red \
-font [subst $font] -command {set retval 6; destroy .ctxmenu}
button .ctxmenu.b8 -text {Paste} -padx 1 -pady 0 -anchor w -activebackground red \
-font [subst $font] -command {set retval 8; destroy .ctxmenu}
}
if {!$selection} {
pack .ctxmenu.b9 -fill x -expand true
}
pack .ctxmenu.b10 .ctxmenu.b11 -fill x -expand true
if {$selection} {
pack .ctxmenu.b12 .ctxmenu.b13 .ctxmenu.b18 -fill x -expand true
}
if {!$selection} {
pack .ctxmenu.b14 -fill x -expand true
pack .ctxmenu.b1 .ctxmenu.b2 .ctxmenu.b3 .ctxmenu.b4 .ctxmenu.b5 -fill x -expand true
pack .ctxmenu.b19 .ctxmenu.b20 .ctxmenu.b6 -fill x -expand true
}
if {$selection} {
pack .ctxmenu.b7 -fill x -expand true
pack .ctxmenu.b15 .ctxmenu.b16 .ctxmenu.b17 -fill x -expand true
}
if {!$selection} {
pack .ctxmenu.b8 -fill x -expand true
}
wm geometry .ctxmenu "+$x+$y"
update
set wx [winfo width .ctxmenu]
set wy [winfo height .ctxmenu]
set sx [winfo screenwidth .]
set sy [winfo screenheight .]
if { $y + $wy > $sy } {
set y [expr {$y - ( $y + $wy - $sy )} ]
}
if { $x + $wx > $sx } {
set x [expr {$x - ( $x + $wx - $sx )} ]
}
wm geometry .ctxmenu "+$x+$y";# move away from screen edges
bind .ctxmenu <Leave> {if { {%W} eq {.ctxmenu} } {destroy .ctxmenu} }
tkwait window .ctxmenu
return $retval
}
#
# toolbar: Public variables that we allow to be overridden
#