From 9f4b496049fba02d1f82403274cf3605aa04ddf4 Mon Sep 17 00:00:00 2001 From: Ivica Ico Bukvic <ico@vt.edu> Date: Wed, 1 Aug 2012 13:15:25 -0400 Subject: [PATCH] added ability to provide custom name to the pd-gui instance (for combining all windows under the same icon on recent WMs (like Ubuntu's Unity), made all toplevel windows inside pd.tk inherit the class name of the root window, added new ways to select and edit text inside an object (ctrl+left and ctrl+right take you to the next argument, ctrl+shift+left/right select the same space, shift+left/right alter selection, home/end or down/up take you to the end/beginning of the text entry). --- src/g_editor.c | 8 +++- src/g_rtext.c | 111 +++++++++++++++++++++++++++++++++++++++++++++--- src/pd.tk | 113 +++++++++++++++++++++++++++++++++++++------------ src/s_inter.c | 4 +- src/t_main.c | 5 +++ 5 files changed, 203 insertions(+), 38 deletions(-) diff --git a/src/g_editor.c b/src/g_editor.c index 7cb797269..26f8f5619 100644 --- a/src/g_editor.c +++ b/src/g_editor.c @@ -3485,8 +3485,12 @@ void canvas_key(t_canvas *x, t_symbol *s, int ac, t_atom *av) || !strcmp(gotkeysym->s_name, "Down") || !strcmp(gotkeysym->s_name, "Left") || !strcmp(gotkeysym->s_name, "Right") - || !strcmp(gotkeysym->s_name, "CtrlHome") - || !strcmp(gotkeysym->s_name, "CtrlEnd") + || !strcmp(gotkeysym->s_name, "CtrlLeft") + || !strcmp(gotkeysym->s_name, "CtrlRight") + || !strcmp(gotkeysym->s_name, "ShiftLeft") + || !strcmp(gotkeysym->s_name, "ShiftRight") + || !strcmp(gotkeysym->s_name, "CtrlShiftLeft") + || !strcmp(gotkeysym->s_name, "CtrlShiftRight") || !strcmp(gotkeysym->s_name, "Home") || !strcmp(gotkeysym->s_name, "End"))) { diff --git a/src/g_rtext.c b/src/g_rtext.c index bcfa6588e..42daac36d 100644 --- a/src/g_rtext.c +++ b/src/g_rtext.c @@ -31,6 +31,12 @@ #define SEND_UPDATE 2 #define SEND_CHECK 0 +// selection for shift+arrow selecting +// 0 = none; +// 1 = start; +// 2 = end; +static int last_sel = 0; + struct _rtext { char *x_buf; @@ -447,7 +453,7 @@ void rtext_key(t_rtext *x, int keynum, t_symbol *keysym) { int w = 0, h = 0, indx, i, newsize, ndel; char *s1, *s2; - //post("keysym=%s", keysym->s_name); + //fprintf(stderr,"rtext_key keysym=%s\n", keysym->s_name); if (keynum) { int n = keynum; @@ -506,6 +512,7 @@ be printable in whatever 8-bit character set we find ourselves. */ x->x_selend = x->x_selstart = x->x_selstart + 1; else x->x_selstart = x->x_selend; + last_sel = 0; } else if (!strcmp(keysym->s_name, "Left")) { @@ -513,6 +520,30 @@ be printable in whatever 8-bit character set we find ourselves. */ x->x_selend = x->x_selstart = x->x_selstart - 1; else x->x_selend = x->x_selstart; + last_sel = 0; + } + else if (!strcmp(keysym->s_name, "ShiftRight")) + { + if (!last_sel) last_sel = 2; + if (last_sel == 1 && x->x_selstart < x->x_selend) { + if (x->x_selstart < x->x_bufsize) + x->x_selstart = x->x_selstart + 1; + } else { + last_sel = 2; + if (x->x_selend < x->x_bufsize) + x->x_selend = x->x_selend + 1; + } + } + else if (!strcmp(keysym->s_name, "ShiftLeft")) + { + if (!last_sel) last_sel = 1; + if (last_sel == 2 && x->x_selend > x->x_selstart) { + x->x_selend = x->x_selend - 1; + } else { + last_sel = 1; + if (x->x_selstart > 0) + x->x_selstart = x->x_selstart - 1; + } } /* this should be improved... life's too short */ else if (!strcmp(keysym->s_name, "Up") || !strcmp(keysym->s_name, "Home")) @@ -522,6 +553,7 @@ be printable in whatever 8-bit character set we find ourselves. */ while (x->x_selstart > 0 && x->x_buf[x->x_selstart] != '\n') x->x_selstart--; x->x_selend = x->x_selstart; + last_sel = 0; } else if (!strcmp(keysym->s_name, "Down") || !strcmp(keysym->s_name, "End")) { @@ -531,8 +563,9 @@ be printable in whatever 8-bit character set we find ourselves. */ if (x->x_selend < x->x_bufsize) x->x_selend++; x->x_selstart = x->x_selend; + last_sel = 0; } - else if (!strcmp(keysym->s_name, "CtrlHome")) + else if (!strcmp(keysym->s_name, "CtrlLeft")) { /* first find first non-space char going back */ while (x->x_selstart > 0 && x->x_buf[x->x_selstart-1] == ' ') @@ -542,11 +575,15 @@ be printable in whatever 8-bit character set we find ourselves. */ x->x_buf[x->x_selstart] != '\n' && x->x_buf[x->x_selstart-1] != ' ') x->x_selstart--; - x->x_selend = x->x_selstart; + if (x->x_buf[x->x_selstart+1] == ' ') + x->x_selstart++; + x->x_selend = x->x_selstart; } - else if (!strcmp(keysym->s_name, "CtrlEnd")) + else if (!strcmp(keysym->s_name, "CtrlRight")) { /* now go forward until you find another space or the end of the buffer */ + if (x->x_selend < x->x_bufsize - 1) + x->x_selend++; while (x->x_selend < x->x_bufsize && x->x_buf[x->x_selend] != '\n' && x->x_buf[x->x_selend] != ' ') @@ -554,9 +591,71 @@ be printable in whatever 8-bit character set we find ourselves. */ /* now skip all the spaces and land before next word */ while (x->x_selend < x->x_bufsize && x->x_buf[x->x_selend] == ' ') - x->x_selend++; - x->x_selstart = x->x_selend; + x->x_selend++; + if (x->x_selend > 0 && x->x_buf[x->x_selend-1] == ' ') + x->x_selend--; + x->x_selstart = x->x_selend; } + else if (!strcmp(keysym->s_name, "CtrlShiftLeft")) + { + int swap = 0; + int *target; + if (!last_sel) last_sel = 1; + if (last_sel == 2 && x->x_selend > x->x_selstart) + target = &x->x_selend; + else { + last_sel = 1; + target = &x->x_selstart; + } + /* first find first non-space char going back */ + while (*target > 0 && x->x_buf[*target-1] == ' ') + (*target)--; + /* now go back until you find another space or the beginning of the buffer */ + while (*target > 0 && + x->x_buf[*target] != '\n' && + x->x_buf[*target-1] != ' ') + (*target)--; + if (x->x_buf[*target+1] == ' ') + (*target)++; + if (x->x_selstart > x->x_selend) { + swap = x->x_selend; + x->x_selend = x->x_selstart; + x->x_selstart = swap; + last_sel = 1; + } + } + else if (!strcmp(keysym->s_name, "CtrlShiftRight")) + { + int swap = 0; + int *target; + if (!last_sel) last_sel = 2; + if (last_sel == 1 && x->x_selstart < x->x_selend) + target = &x->x_selstart; + else { + last_sel = 2; + target = &x->x_selend; + } + /* now go forward until you find another space or the end of the buffer */ + if (*target < x->x_bufsize - 1) + (*target)++; + while (*target < x->x_bufsize && + x->x_buf[*target] != '\n' && + x->x_buf[*target] != ' ') + (*target)++; + /* now skip all the spaces and land before next word */ + while (*target < x->x_bufsize && + x->x_buf[*target] == ' ') + (*target)++; + if (*target > 0 && x->x_buf[*target-1] == ' ') + (*target)--; + if (x->x_selstart > x->x_selend) { + swap = x->x_selend; + x->x_selend = x->x_selstart; + x->x_selstart = swap; + last_sel = 2; + } + } + rtext_senditup(x, SEND_UPDATE, &w, &h, &indx); } diff --git a/src/pd.tk b/src/pd.tk index 88e755b68..8a72ab5f9 100644 --- a/src/pd.tk +++ b/src/pd.tk @@ -230,6 +230,9 @@ if { $tcl_platform(platform) == "windows" } { set window_prefs {} set pd_nt 0 set ctrl_key "Control" + # Shift modifier + set shift_l_down 0 + set shift_r_down 0 # Ctrl modifier set ctrl_l_down 0 set ctrl_r_down 0 @@ -739,7 +742,7 @@ pack .controls.dio -side right -padx 20 # pack .controls.clr_console -pady 30 #} -toplevel .printout -class pd-l2ork +toplevel .printout -class [winfo class .] wm title .printout "Console" # initial location of the console window (+x+y) wm geometry .printout +10+170 @@ -1114,7 +1117,7 @@ proc menu_send {} { if { [winfo exists .sendpanel.entry] } { raise .sendpanel } else { - toplevel .sendpanel -class pd-l2ork + toplevel .sendpanel -class [winfo class .] wm title .sendpanel {Send Message to Pd} wm resizable .sendpanel 0 0 match_linux_wm [list .sendpanel configure] @@ -1235,7 +1238,7 @@ proc menu_opentext {filename} { raise .about } else { destroy .about - toplevel .about -class pd-l2ork + toplevel .about -class [winfo class .] wm title .about "About Pd" wm geometry .about 550x480 match_linux_wm [list text .about.text -relief sunken -bd 1 -font text_font \ @@ -1606,7 +1609,7 @@ proc makeapp_embedprefs {appdir patch_to_open} { } proc makeapp_busypanel {appdir} { - toplevel .makeapp -class pd-l2ork + toplevel .makeapp -class [winfo class .] wm title .makeapp "Making App" wm attributes .makeapp -topmost 1 wm resizable .makeapp 0 0 @@ -2058,7 +2061,7 @@ proc menu_findobject {canvas} { set find_canvas $canvas - toplevel .find -class pd-l2ork + toplevel .find -class [winfo class .] wm title .find "Find" match_linux_wm [list .find configure] #wm geometry .find =400x125+150+100 @@ -2211,9 +2214,9 @@ proc pdtk_canvas_new {name width height geometry editable} { } if {$::menu($name) == 1} { - toplevel $name -menu $name.m -class pd-l2ork + toplevel $name -menu $name.m -class [winfo class .] } else { - toplevel $name -menu "" -class pd-l2ork + toplevel $name -menu "" -class [winfo class .] } # initialize variable to reflect that this window has been open @@ -3028,7 +3031,7 @@ proc pdtk_array_listview_new {id arrayName page} { set pd_array_listview_id($arrayName) $id set windowName [format ".%sArrayWindow" $arrayName] if [winfo exists $windowName] then [destroy $windowName] - toplevel $windowName -class pd-l2ork + toplevel $windowName -class [winfo class .] wm geometry $windowName 220x400 wm minsize $windowName 220 400 #pdtk_standardkeybindings $windowName @@ -3546,8 +3549,10 @@ proc pdtk_canvas_sendkey {name state key iso shift focus} { global pd_nt global ctrl_l_down global ctrl_r_down + global shift_l_down + global shift_r_down - # pdtk_post "key = $name $state $key $iso $shift\n" + #puts stderr "key = $name $state $key $iso $shift\n" if {$key == "BackSpace"} { set iso "" @@ -3586,6 +3591,20 @@ proc pdtk_canvas_sendkey {name state key iso shift focus} { set ctrl_r_down 0 } } + if {$key == "Shift_L"} { + if {$state == 1} { + set shift_l_down 1 + } else { + set shift_l_down 0 + } + } + if {$key == "Shift_R"} { + if {$state == 1} { + set shift_r_down 1 + } else { + set shift_r_down 0 + } + } if {$ctrl_l_down || $ctrl_r_down} { set ctrl 1 @@ -3593,16 +3612,54 @@ proc pdtk_canvas_sendkey {name state key iso shift focus} { set ctrl 0 } - if {[string match Home $key] && $ctrl} { - set key "CtrlHome" - set state 1 + if {$shift_l_down || $shift_r_down} { + set shift 1 + } else { + set shift 0 } - if {[string match End $key] && $ctrl} { - set key "CtrlEnd" - set state 1 + #puts stderr "shift=$shift ctrl=$ctrl key=$key" + + #if {[string match Home $key] && $ctrl} { + # set key "CtrlHome" + # set state 1 + #} + + #if {[string match End $key] && $ctrl} { + # set key "CtrlEnd" + # set state 1 + #} + + if {[string match Left $key]} { + if {$ctrl == 1 && $shift == 0} { + set key "CtrlLeft" + set state 1 + } + if {$ctrl == 0 && $shift == 1} { + set key "ShiftLeft" + } + if {$ctrl == 1 && $shift == 1} { + set key "CtrlShiftLeft" + set state 1 + } } + if {[string match Right $key]} { + if {$ctrl == 1 && $shift == 0} { + set key "CtrlRight" + set state 1 + } + if {$ctrl == 0 && $shift == 1} { + set key "ShiftRight" + } + if {$ctrl == 1 && $shift == 1} { + set key "CtrlShiftRight" + set state 1 + } + } + + #puts stderr "FINAL key=$key" + pd [canvastosym $name] key $state $key $shift $focus\; } @@ -3943,7 +4000,7 @@ proc pdtk_canvas_dofont {name canvas initsize} { set font_properties $name set font_canvas $canvas - toplevel $name -class pd-l2ork + toplevel $name -class [winfo class .] match_linux_wm [list $name configure] wm resizable $name 0 0 wm title $name {Font Settings} @@ -4112,7 +4169,7 @@ proc pdtk_gatom_dialog {id initwidth initlo inithi \ set $var_gatomsymfrom [gatom_unescape $symfrom] set $var_gatomsymto [gatom_unescape $symto] - toplevel $id -class pd-l2ork + toplevel $id -class [winfo class .] wm title $id "Atom Box Properties" match_linux_wm [list $id configure] wm resizable $id 0 0 @@ -4852,7 +4909,7 @@ proc pdtk_iemgui_dialog {id mainheader \ set $var_iemgui_l2_f1_b0 0 - toplevel $id -class pd-l2ork + toplevel $id -class [winfo class .] wm title $id [format "%s Properties" $mainheader] match_linux_wm [list $id configure] wm resizable $id 0 0 @@ -5242,7 +5299,7 @@ proc pdtk_array_dialog {id name n flags newone canvas} { set $var_array_drawasrects [expr ( $flags & 2 ) != 0] set $var_array_otherflag 0 - toplevel $id -class pd-l2ork + toplevel $id -class [winfo class .] wm title $id {Edit Array} match_linux_wm [list $id configure] wm resizable $id 0 0 @@ -5541,7 +5598,7 @@ proc pdtk_canvas_dialog {id xscale yscale graphme x1 y1 x2 y2 \ set $var_canvas_xmargin $xmargin set $var_canvas_ymargin $ymargin - toplevel $id -class pd-l2ork + toplevel $id -class [winfo class .] wm title $id {Canvas Properties} match_linux_wm [list $id configure] wm resizable $id 0 0 @@ -5671,7 +5728,7 @@ proc dodata_ok {name} { proc pdtk_data_dialog {name stuff} { global pd_deffont global pd_nt - toplevel $name -class pd-l2ork + toplevel $name -class [winfo class .] match_linux_wm [list $name configure] wm title $name {Atom} wm protocol $name WM_DELETE_WINDOW [concat dodata_cancel $name] @@ -6067,7 +6124,7 @@ proc pdtk_pd_texteditor {stuff} { } else { set name .texteditor - toplevel $name -class pd-l2ork + toplevel $name -class [winfo class .] match_linux_wm [list $name configure] wm title $name {Text Editor} @@ -6292,7 +6349,7 @@ proc pdtk_audio_dialog {id indev1 indev2 indev3 indev4 \ set audio_sr $sr set audio_advance $advance set audio_callback $callback - toplevel $id -class pd-l2ork + toplevel $id -class [winfo class .] match_linux_wm [list $id configure] wm title $id {Audio Settings} wm resizable $id 0 0 @@ -6570,7 +6627,7 @@ proc pdtk_midi_dialog {id indev1 indev2 indev3 indev4 \ set midi_alsain [llength $midi_indevlist] set midi_alsaout [llength $midi_outdevlist] - toplevel $id -class pd-l2ork + toplevel $id -class [winfo class .] match_linux_wm [list $id configure] wm resizable $id 0 0 wm title $id {MIDI Settings} @@ -6765,7 +6822,7 @@ proc pdtk_alsa_midi_dialog {id indev1 indev2 indev3 indev4 \ set midi_alsain [llength $midi_indevlist] set midi_alsaout [llength $midi_outdevlist] - toplevel $id -class pd-l2ork + toplevel $id -class [winfo class .] match_linux_wm [list $id configure] wm resizable $id 0 0 wm title $id {MIDI Settings} @@ -7202,7 +7259,7 @@ namespace eval dlg_ScrollBoxWindow { proc make { id listdata add_method edit_method commit_method title width height } { global pd_nt - toplevel $id -class pd-l2ork + toplevel $id -class [winfo class .] match_linux_wm [list $id configure] wm title $id $title @@ -7322,7 +7379,7 @@ namespace eval dlg_Startup { global cmd set cmd $initialValue - toplevel .inputBox -class pd-l2ork + toplevel .inputBox -class [winfo class .] wm title .inputBox $prompt wm minsize .inputBox 450 30 wm resizable .inputBox 1 0 @@ -7479,7 +7536,7 @@ if { [info tclversion] >= 8.5 && $pd_nt == 0 } { set rgb_g [expr 0x$hex_rgb_g] set rgb_b [expr 0x$hex_rgb_b] - toplevel $name -class pd-l2ork + toplevel $name -class [winfo class .] wm resizable $name 0 0 #global tmp_xpix tmp_ypix diff --git a/src/s_inter.c b/src/s_inter.c index 6cd666aaf..913df89db 100644 --- a/src/s_inter.c +++ b/src/s_inter.c @@ -1096,8 +1096,8 @@ int sys_startgui(const char *guidir) #else sprintf(cmdbuf, "TCL_LIBRARY=\"%s/tcl/library\" TK_LIBRARY=\"%s/tk/library\" \ - \"%s/pd-gui\" %d\n", - sys_libdir->s_name, sys_libdir->s_name, guidir, portno); + \"%s/pd-gui\" %d localhost %s\n", + sys_libdir->s_name, sys_libdir->s_name, guidir, portno, (sys_k12_mode ? "pd-l2ork-k12" : "pd-l2ork")); #endif sys_guicmd = cmdbuf; } diff --git a/src/t_main.c b/src/t_main.c index 54811d31e..6ed972303 100644 --- a/src/t_main.c +++ b/src/t_main.c @@ -56,6 +56,11 @@ main(int argc, char **argv) argc--; argv++; argv[0] = "pd-l2ork"; } + if (argc == 2) + { + //specify root window name + argc--; argv++; + } Tk_Main(argc, argv, Tcl_AppInit); return 0; /* Needed only to prevent compiler warning. */ } -- GitLab