diff options
39 files changed, 2906 insertions, 2075 deletions
diff --git a/pd/doc/3.audio.examples/E07.evenodd.pd b/pd/doc/3.audio.examples/E07.evenodd.pd index 9715e1ea..e6d3851e 100644 --- a/pd/doc/3.audio.examples/E07.evenodd.pd +++ b/pd/doc/3.audio.examples/E07.evenodd.pd @@ -38,11 +38,11 @@ #X text 299 152 <--transpose; #N canvas 0 0 538 208 make-table 0; #X obj 38 71 loadbang; -#X text 16 11 This patch loads a sequence of pitches into array1. The +#X text 16 11 This patch loads a sequence of pitches into E07. The values are floating-point \, so we could use microtones (60.5 \, for example) if we wish.; -#X msg 38 99 \; array1 0 55 56 57 55 57 61 55 61 63 57 63 \; array1 -yticks 36 12 1 \; array1 ylabel 12 36 48 60 72 84 96; +#X msg 38 99 \; E07 0 55 56 57 55 57 61 55 61 63 57 63 \; E07 +yticks 36 12 1 \; E07 ylabel 12 36 48 60 72 84 96; #X connect 0 0 2 0; #X restore 527 195 pd make-table; #X obj 176 50 sel 0; diff --git a/pd/doc/3.audio.examples/E10.complex.FM.pd b/pd/doc/3.audio.examples/E10.complex.FM.pd index 094d68ed..fbd6ce99 100644 --- a/pd/doc/3.audio.examples/E10.complex.FM.pd +++ b/pd/doc/3.audio.examples/E10.complex.FM.pd @@ -43,7 +43,7 @@ frequency for showing spectra: the 16th bin in a 4096-point spectrum #X text 273 232 toggle to graph repeatedly; #X text 262 212 bang to graph once; #X obj 16 494 t b f; -#X obj 19 295 tabwrite~ E10-signal; +#X obj 19 295 tabwrite~ E10-spectrum; #X obj 208 295 tabwrite~ E10-spectrum; #X text 72 536 set carrier multiplier and modulation multipliers after fundamental; diff --git a/pd/doc/3.audio.examples/H04.filter.sweep.pd b/pd/doc/3.audio.examples/H04.filter.sweep.pd index e4f3cf09..1675e9a6 100644 --- a/pd/doc/3.audio.examples/H04.filter.sweep.pd +++ b/pd/doc/3.audio.examples/H04.filter.sweep.pd @@ -1,4 +1,4 @@ -#N canvas 360 15 553 524 12; +#N canvas 360 22 557 528 12; #X floatatom 44 146 5 0 150 0 - #0-pitch -; #X text 126 9 SWEEPING FILTERS; #X obj 44 193 phasor~; @@ -43,6 +43,30 @@ sweep speeds.; "vcf~" instead of "bp~". The vcf~ module takes an audio signal to set center frequency. (Q is still set by messages though.) Vcf is computationally somewhat more expensive than bp~.; +#N canvas 0 22 612 404 conversion-tables 0; +#N canvas 0 22 450 300 graph2 0; +#X array mtof 130 float 1; +#A 0 8.1758 8.66196 9.17702 9.72272 10.3009 10.9134 11.5623 12.2499 +12.9783 13.75 14.5676 15.4339 16.3516 17.3239 18.354 19.4454 20.6017 +21.8268 23.1247 24.4997 25.9565 27.5 29.1352 30.8677 32.7032 34.6478 +36.7081 38.8909 41.2034 43.6535 46.2493 48.9994 51.9131 55 58.2705 +61.7354 65.4064 69.2957 73.4162 77.7817 82.4069 87.3071 92.4986 97.9989 +103.826 110 116.541 123.471 130.813 138.591 146.832 155.563 164.814 +174.614 184.997 195.998 207.652 220 233.082 246.942 261.626 277.183 +293.665 311.127 329.628 349.228 369.994 391.995 415.305 440 466.164 +493.883 523.251 554.365 587.33 622.254 659.255 698.456 739.989 783.991 +830.609 880 932.328 987.767 1046.5 1108.73 1174.66 1244.51 1318.51 +1396.91 1479.98 1567.98 1661.22 1760 1864.66 1975.53 2093 2217.46 2349.32 +2489.02 2637.02 2793.83 2959.96 3135.96 3322.44 3520 3729.31 3951.07 +4186.01 4434.92 4698.64 4978.03 5274.04 5587.65 5919.91 6271.93 6644.88 +7040 7458.62 7902.13 8372.02 8869.84 9397.27 9956.06 10548.1 11175.3 +11839.8 12543.9 13289.8 14080; +#X coords 0 12000 130 0 200 100 1; +#X restore 309 225 graph; +#X text 319 333 ------ 130 samples ------; +#X text 518 318 0; +#X text 520 218 12000; +#X restore 168 463 pd conversion-tables; #X connect 0 0 21 0; #X connect 2 0 8 0; #X connect 3 0 9 0; diff --git a/pd/doc/3.audio.examples/H05.filter.floyd.pd b/pd/doc/3.audio.examples/H05.filter.floyd.pd index 2187f05d..401b5628 100644 --- a/pd/doc/3.audio.examples/H05.filter.floyd.pd +++ b/pd/doc/3.audio.examples/H05.filter.floyd.pd @@ -1,30 +1,31 @@ -#N canvas 708 41 555 646 12; -#N canvas 0 0 600 392 conversion-tables 0; -#N canvas 0 0 450 300 graph1 0; +#N canvas 288 109 559 650 12; +#N canvas 0 22 604 396 conversion-tables 0; +#N canvas 0 22 450 300 graph1 0; #X array dbtorms 123 float 1; #A 0 0 0 1.25893e-05 1.41254e-05 1.58489e-05 1.77828e-05 1.99526e-05 2.23872e-05 2.51189e-05 2.81838e-05 3.16228e-05 3.54813e-05 3.98107e-05 4.46684e-05 5.01187e-05 5.62341e-05 6.30957e-05 7.07946e-05 7.94328e-05 -8.91251e-05 1e-04 0.000112202 0.000125893 0.000141254 0.000158489 0.000177828 -0.000199526 0.000223872 0.000251189 0.000281838 0.000316228 0.000354813 -0.000398107 0.000446684 0.000501187 0.000562341 0.000630957 0.000707946 -0.000794328 0.000891251 0.001 0.00112202 0.00125893 0.00141254 0.00158489 -0.00177828 0.00199526 0.00223872 0.00251189 0.00281838 0.00316228 0.00354813 -0.00398107 0.00446684 0.00501187 0.00562341 0.00630957 0.00707946 0.00794328 -0.00891251 0.01 0.0112202 0.0125893 0.0141254 0.0158489 0.0177828 0.0199526 -0.0223872 0.0251189 0.0281838 0.0316228 0.0354813 0.0398107 0.0446684 -0.0501187 0.0562341 0.0630957 0.0707946 0.0794328 0.0891251 0.1 0.112202 -0.125893 0.141254 0.158489 0.177828 0.199526 0.223872 0.251189 0.281838 -0.316228 0.354813 0.398107 0.446684 0.501187 0.562341 0.630957 0.707946 -0.794328 0.891251 1 1.12202 1.25893 1.41254 1.58489 1.77828 1.99526 -2.23872 2.51189 2.81838 3.16228 3.54813 3.98107 4.46684 5.01187 5.62341 -6.30957 7.07946 7.94328 8.91251 10 11.2202 12.5893; +8.91251e-05 0.0001 0.000112202 0.000125893 0.000141254 0.000158489 +0.000177828 0.000199526 0.000223872 0.000251189 0.000281838 0.000316228 +0.000354813 0.000398107 0.000446684 0.000501187 0.000562341 0.000630957 +0.000707946 0.000794328 0.000891251 0.001 0.00112202 0.00125893 0.00141254 +0.00158489 0.00177828 0.00199526 0.00223872 0.00251189 0.00281838 0.00316228 +0.00354813 0.00398107 0.00446684 0.00501187 0.00562341 0.00630957 0.00707946 +0.00794328 0.00891251 0.01 0.0112202 0.0125893 0.0141254 0.0158489 +0.0177828 0.0199526 0.0223872 0.0251189 0.0281838 0.0316228 0.0354813 +0.0398107 0.0446684 0.0501187 0.0562341 0.0630957 0.0707946 0.0794328 +0.0891251 0.1 0.112202 0.125893 0.141254 0.158489 0.177828 0.199526 +0.223872 0.251189 0.281838 0.316228 0.354813 0.398107 0.446684 0.501187 +0.562341 0.630957 0.707946 0.794328 0.891251 1 1.12202 1.25893 1.41254 +1.58489 1.77828 1.99526 2.23872 2.51189 2.81838 3.16228 3.54813 3.98107 +4.46684 5.01187 5.62341 6.30957 7.07946 7.94328 8.91251 10 11.2202 +12.5893; #X coords 0 10 123 0 200 100 1; #X restore 302 48 graph; #X text 504 141 0; #X text 506 41 10; #X text 321 151 ------ 123 samples ------; -#N canvas 0 0 450 300 graph2 0; +#N canvas 0 22 450 300 graph2 0; #X array mtof 130 float 1; #A 0 8.1758 8.66196 9.17702 9.72272 10.3009 10.9134 11.5623 12.2499 12.9783 13.75 14.5676 15.4339 16.3516 17.3239 18.354 19.4454 20.6017 @@ -65,7 +66,7 @@ #X obj 55 145 + 1; #X obj 22 217 mtof; #X obj 55 169 mod 8; -#N canvas 0 0 450 300 graph1 0; +#N canvas 0 22 450 300 graph1 0; #X array \$0-array1 8 float 2; #X coords 0 96 8 36 200 100 1; #X restore 340 144 graph; @@ -74,9 +75,9 @@ #X text 107 147 sequencer for; #X text 122 164 8 note loop; #X obj 16 576 output~; -#X obj 22 104 tgl 15 0 empty \$1-metro empty 0 -6 0 8 -262144 -1 -1 -1 1; -#N canvas 876 177 375 255 startup 0; +#X obj 22 104 tgl 15 0 empty \$0-metro empty 0 -6 0 8 -262144 -1 -1 +0 1; +#N canvas 876 177 379 259 startup 0; #X obj 22 24 loadbang; #X obj 22 48 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; diff --git a/pd/doc/3.audio.examples/I07.phase.vocoder.pd b/pd/doc/3.audio.examples/I07.phase.vocoder.pd index 95017436..735b8cd2 100644 --- a/pd/doc/3.audio.examples/I07.phase.vocoder.pd +++ b/pd/doc/3.audio.examples/I07.phase.vocoder.pd @@ -1,8 +1,8 @@ -#N canvas 164 25 744 599 12; +#N canvas 425 33 744 599 12; #X floatatom 494 315 5 0 0 0 - transpo-set -; #X floatatom 167 383 3 0 0 0 - speed-set -; #X floatatom 55 385 7 0 0 0 - location-set -; -#N canvas 199 40 821 693 fft-analysis 0; +#N canvas 90 42 821 693 fft-analysis 0; #X obj 51 477 *~; #X obj 18 477 *~; #X obj 18 499 -~; @@ -39,7 +39,7 @@ bang; #X obj 97 425 q8_rsqrt~; #N canvas 139 105 1006 799 read-windows 0; #X obj 18 693 *~; -#X obj 364 448 r window-size; +#X obj 340 448 r window-size; #X obj 156 300 f; #X obj 102 91 r window-size; #X obj 102 139 /; @@ -60,14 +60,14 @@ bang; #X text 188 394 reading location (samples); #X obj 51 597 / 4; #X obj 288 245 * 0.01; -#X floatatom 364 498 7 0 0 0 - - -; -#X obj 364 474 *; -#X obj 502 347 r transpo; -#X obj 502 369 * 0.01; -#X obj 504 390 + 69; -#X obj 505 411 mtof; -#X obj 505 433 / 440; -#X obj 399 474 t b f; +#X floatatom 340 498 7 0 0 0 - - -; +#X obj 340 474 *; +#X obj 499 365 r transpo; +#X obj 499 387 * 0.01; +#X obj 501 408 + 69; +#X obj 502 429 mtof; +#X obj 502 451 / 440; +#X obj 375 474 t b f; #X obj 19 719 outlet~; #X obj 195 720 outlet~; #X obj 218 664 tabreceive~ \$0-hann; @@ -77,7 +77,7 @@ bang; #X obj 768 508 r speed; #X msg 768 532 set \$1; #X obj 768 557 s speed-set; -#X text 432 498 stretched window size (samples); +#X text 411 498 stretched window size (samples); #X obj 877 507 r transpo; #X msg 877 533 set \$1; #X obj 877 558 s transpo-set; @@ -123,8 +123,8 @@ by "location". If "speed" is nonzero \, "location" automatically precesses. #X obj 845 684 r auto; #X obj 730 685 r no-detune; #X msg 730 707 \; detune 0; -#X text 321 280 loop to precess the location according; -#X text 320 296 to the "speed" parameter.; +#X text 326 275 loop to precess the location according; +#X text 325 291 to the "speed" parameter.; #X text 611 31 if location changes \, update number box; #X text 610 50 in main window via "location-set" \, but; #X text 613 69 taking care to limit frequency of updates.; @@ -136,14 +136,6 @@ by "location". If "speed" is nonzero \, "location" automatically precesses. #X text 496 527 "rewind" control takes us; #X text 499 545 to a location depending on; #X text 499 564 stretched window size.; -#X obj 593 457 t b f; -#X obj 617 395 samplerate~; -#X obj 593 348 r \$0-insamprate; -#X obj 593 418 /; -#X obj 505 455 * 1; -#X text 494 312 desired transposition and sample; -#X text 494 329 rate correction for soundfile; -#X obj 593 370 t f b; #X connect 0 0 30 0; #X connect 1 0 23 0; #X connect 2 0 11 0; @@ -179,7 +171,7 @@ by "location". If "speed" is nonzero \, "location" automatically precesses. #X connect 25 0 26 0; #X connect 26 0 27 0; #X connect 27 0 28 0; -#X connect 28 0 99 0; +#X connect 28 0 29 0; #X connect 29 0 23 0; #X connect 29 1 23 1; #X connect 32 0 5 1; @@ -224,14 +216,6 @@ by "location". If "speed" is nonzero \, "location" automatically precesses. #X connect 77 0 75 0; #X connect 79 0 78 0; #X connect 80 0 81 0; -#X connect 95 0 99 0; -#X connect 95 1 99 1; -#X connect 96 0 98 1; -#X connect 97 0 102 0; -#X connect 98 0 95 0; -#X connect 99 0 29 0; -#X connect 102 0 98 0; -#X connect 102 1 96 0; #X restore 109 133 pd read-windows; #X obj 137 543 tabsend~ prev-imag; #X obj 136 567 tabsend~ prev-real; @@ -363,11 +347,11 @@ shifts the signal to the left or right depending on its argument.) #X connect 54 0 21 0; #X restore 55 480 pd fft-analysis; #N canvas 260 23 647 768 phase-tables 0; -#N canvas 0 0 450 300 (subpatch) 0; +#N canvas 0 0 450 300 graph2 0; #X array prev-imag 4096 float 0; #X coords 0 1000 4096 -1000 400 300 1; #X restore 169 326 graph; -#N canvas 0 0 450 300 (subpatch) 0; +#N canvas 0 0 450 300 graph3 0; #X array prev-real 4096 float 0; #X coords 0 500 4096 -500 400 300 1; #X restore 170 17 graph; @@ -378,9 +362,9 @@ shifts the signal to the left or right depending on its argument.) #X text 389 359 normal; #X obj 56 517 output~; #N canvas 0 110 565 454 hann-window 0; -#N canvas 0 0 450 300 (subpatch) 0; -#X array \$0-hann 4096 float 0; -#X coords 0 1 4095 0 300 100 1; +#N canvas 0 0 450 300 graph1 0; +#X array \$0-hann 1024 float 0; +#X coords 0 1 1023 0 300 100 1; #X restore 82 311 graph; #X obj 378 165 osc~; #X obj 378 190 *~ -0.5; @@ -428,9 +412,9 @@ and window-msec (analysis window size in seconds and msec).; #X connect 19 1 18 0; #X restore 440 528 pd hann-window; #N canvas 388 86 694 447 insample 0; -#N canvas 0 0 450 300 (subpatch) 0; -#X array \$0-sample 82301 float 0; -#X coords 0 1 82300 -1 400 150 1; +#N canvas 0 0 450 300 graph1 0; +#X array \$0-sample 160161 float 0; +#X coords 0 1 160160 -1 400 150 1; #X restore 281 135 graph; #X obj 28 133 r read-sample; #X obj 28 184 unpack s f; @@ -449,12 +433,12 @@ and window-msec (analysis window size in seconds and msec).; #X obj 28 381 * 1000; #X obj 28 404 s \$0-samp-msec; #X obj 66 357 r \$0-insamprate; -#X obj 37 68 hip~ 5; -#X obj 37 44 adc~ 1; +#X obj 29 70 hip~ 5; +#X obj 29 46 adc~ 1; #X obj 29 9 inlet; -#X obj 99 44 samplerate~; +#X obj 91 46 samplerate~; #X obj 29 93 tabwrite~ \$0-sample; -#X obj 99 68 s \$0-insamprate; +#X obj 91 70 s \$0-insamprate; #X msg 285 383 \; read-sample ../sound/voice.wav; #X obj 276 20 inlet; #X obj 276 42 openpanel; @@ -479,7 +463,7 @@ and window-msec (analysis window size in seconds and msec).; #X connect 18 0 22 0; #X connect 19 0 18 0; #X connect 20 0 21 0; -#X connect 20 0 22 0; +#X connect 20 0 19 0; #X connect 21 0 23 0; #X connect 25 0 26 0; #X connect 26 0 27 0; @@ -501,6 +485,7 @@ and window-msec (analysis window size in seconds and msec).; #X obj 262 408 s rewind; #X msg 345 336 200; #X msg 345 358 100; +#X msg 345 380 20; #X text 386 335 contract; #X text 390 380 expand; #X obj 493 407 s lock; @@ -542,7 +527,6 @@ to see the workings.; #X obj 535 460 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 466 458 file ->; -#X msg 345 380 20; #X connect 0 0 5 0; #X connect 1 0 21 0; #X connect 2 0 20 0; @@ -552,13 +536,13 @@ to see the workings.; #X connect 14 0 16 0; #X connect 15 0 16 0; #X connect 17 0 11 0; -#X connect 19 0 28 0; +#X connect 19 0 29 0; #X connect 22 0 23 0; -#X connect 24 0 48 0; -#X connect 25 0 48 0; -#X connect 38 0 42 0; -#X connect 39 0 42 0; -#X connect 40 0 42 0; -#X connect 41 0 42 0; -#X connect 52 0 11 1; -#X connect 54 0 48 0; +#X connect 24 0 49 0; +#X connect 25 0 49 0; +#X connect 26 0 49 0; +#X connect 39 0 43 0; +#X connect 40 0 43 0; +#X connect 41 0 43 0; +#X connect 42 0 43 0; +#X connect 53 0 11 1; diff --git a/pd/doc/3.audio.examples/J01.even.odd.pd b/pd/doc/3.audio.examples/J01.even.odd.pd index 71c9fdf5..18603bb3 100644 --- a/pd/doc/3.audio.examples/J01.even.odd.pd +++ b/pd/doc/3.audio.examples/J01.even.odd.pd @@ -40,7 +40,7 @@ and heard. (Listen to the two outputs separately \, then together.) #X text 95 350 output level; #X text 100 308 for difference; #X text 157 77 <-- click to graph; -#X msg 148 97 \; pd DSP 1; +#X msg 148 97 \; pd dsp 1; #X obj 138 247 tabwrite~ \$0-difference; #X obj 138 270 tabwrite~ \$0-sum; #X obj 138 138 tabwrite~ \$0-phasor; diff --git a/pd/extra/bonk~/bonk~.c b/pd/extra/bonk~/bonk~.c index 6776b2e2..d0f18de9 100644 --- a/pd/extra/bonk~/bonk~.c +++ b/pd/extra/bonk~/bonk~.c @@ -53,7 +53,8 @@ decay and other times in msec #include <stdio.h> #include <string.h> -#ifdef NT +/* These pragmas are only used for MSVC, not MinGW or Cygwin <hans@at.or.at> */ +#ifdef _MSC_VER #pragma warning (disable: 4305 4244) #endif diff --git a/pd/extra/expr~/vexp.c b/pd/extra/expr~/vexp.c index 7d4d7b52..732944de 100644 --- a/pd/extra/expr~/vexp.c +++ b/pd/extra/expr~/vexp.c @@ -2137,6 +2137,6 @@ ex_print(struct ex_ex *eptr) post("\n"); } -#ifdef NT +#ifdef _WIN32 void ABORT( void) {bug("expr");} #endif diff --git a/pd/extra/expr~/vexp.h b/pd/extra/expr~/vexp.h index 92dfb06e..d096842f 100644 --- a/pd/extra/expr~/vexp.h +++ b/pd/extra/expr~/vexp.h @@ -236,9 +236,13 @@ extern void ex_store(t_expr *expr, long int argc, struct ex_ex *argv, int value_getonly(t_symbol *s, t_float *f); -#ifdef NT + +/* These pragmas are only used for MSVC, not MinGW or Cygwin <hans@at.or.at> */ +#ifdef _MSC_VER #pragma warning (disable: 4305 4244) +#endif +#ifdef _WIN32 #define abort ABORT void ABORT(void); #endif diff --git a/pd/extra/expr~/vexp_fun.c b/pd/extra/expr~/vexp_fun.c index fba49b18..26b0b767 100644 --- a/pd/extra/expr~/vexp_fun.c +++ b/pd/extra/expr~/vexp_fun.c @@ -123,7 +123,7 @@ static void ex_if(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *opt static void ex_ldexp(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_imodf(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_modf(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); -#ifndef NT +#ifndef _WIN32 static void ex_cbrt(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_erf(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_erfc(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); @@ -176,7 +176,7 @@ t_ex_func ex_funcs[] = { {"ldexp ", ex_ldexp, 1}, {"imodf ", ex_imodf, 1}, {"modf", ex_modf, 1}, -#ifndef NT +#ifndef _WIN32 {"cbrt", ex_cbrt, 1}, {"erf", ex_erf, 1}, {"erfc", ex_erfc, 1}, @@ -542,7 +542,7 @@ ex_toint(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) FUNC_EVAL_UNARY(left, toint, (int), optr, 0); } -#ifdef NT +#ifdef _WIN32 /* No rint in NT land ??? */ double rint(double x); @@ -874,7 +874,7 @@ ex_tanh(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) } -#ifndef NT +#ifndef _WIN32 static void ex_asinh(t_expr *e, long argc, struct ex_ex *argv, struct ex_ex *optr) { @@ -1239,7 +1239,7 @@ FUNC_DEF_UNARY(ex_modf, fracmodf, (double), 1); */ FUNC_DEF(ex_ldexp, ldexp, (double), (int), 1); -#ifndef NT +#ifndef _WIN32 /* * ex_cbrt - cube root */ diff --git a/pd/extra/fiddle~/fiddle~.c b/pd/extra/fiddle~/fiddle~.c index d959b00f..4633b3c0 100644 --- a/pd/extra/fiddle~/fiddle~.c +++ b/pd/extra/fiddle~/fiddle~.c @@ -28,11 +28,17 @@ * */ -#ifdef NT + +/* These pragmas are only used for MSVC, not MinGW or Cygwin <hans@at.or.at> */ +#ifdef _MSC_VER +#pragma warning (disable: 4305 4244) +#endif + +/* this #ifdef does nothing, but its there... */ +#ifdef _WIN32 #define flog log #define fexp exp #define fsqrt sqrt -#pragma warning (disable: 4305 4244) #else #define flog log #define fexp exp diff --git a/pd/extra/pique/pique.c b/pd/extra/pique/pique.c index f4cae5e1..a53ad765 100644 --- a/pd/extra/pique/pique.c +++ b/pd/extra/pique/pique.c @@ -7,7 +7,8 @@ combustible materiel, or as part of any life support system or weapon. */ #include "m_pd.h" #include <math.h> #include <stdio.h> -#ifdef NT +/* These pragmas are only used for MSVC, not MinGW or Cygwin <hans@at.or.at> */ +#ifdef _MSC_VER #pragma warning( disable : 4244 ) #pragma warning( disable : 4305 ) #endif diff --git a/pd/extra/sigmund~/sigmund~.c b/pd/extra/sigmund~/sigmund~.c index d5211ac6..92604b7e 100644 --- a/pd/extra/sigmund~/sigmund~.c +++ b/pd/extra/sigmund~/sigmund~.c @@ -26,13 +26,13 @@ for example, defines this in the file d_fft_mayer.c or d_fft_fftsg.c. */ #include <math.h> #include <stdio.h> #include <string.h> -#ifdef NT +#ifdef _WIN32 #include <malloc.h> #else #include <alloca.h> #endif #include <stdlib.h> -#ifdef NT +#ifdef _MSC_VER #pragma warning( disable : 4244 ) #pragma warning( disable : 4305 ) #endif @@ -1395,7 +1395,7 @@ void sigmund_tilde_setup(void) gensym("print"), 0); class_addmethod(sigmund_class, (t_method)sigmund_printnext, gensym("printnext"), A_FLOAT, 0); - post("sigmund~ version 0.06"); + post("sigmund~ version 0.07"); } #endif /* PD */ @@ -1429,6 +1429,10 @@ static t_int *sigmund_perform(t_int *w) int n = (int)(w[3]), j; int infill = x->x_infill; float *fp = x->x_inbuf2 + infill; + + if (x->x_obj.z_disabled) /* return if in muted MSP subpatch -Rd */ + return (w+4); + if (infill < 0 || infill >= x->x_npts) infill = 0; /* for some reason this sometimes happens: */ @@ -1642,7 +1646,7 @@ int main() class_register(CLASS_BOX, c); sigmund_class = c; - post("sigmund~ v0.06"); + post("sigmund~ version 0.07"); return (0); } diff --git a/pd/src/configure.in b/pd/src/configure.in index dfc1b862..e4f4edd7 100644 --- a/pd/src/configure.in +++ b/pd/src/configure.in @@ -247,7 +247,7 @@ dnl This should be fixed so Pd can use ALSA shared libraries where appropriate. binarymode="-m4755" fi STRIPFLAG=-s - GUINAME="pd-gui" + GUINAME="" if test x$USE_DEBUG_CFLAGS = "xyes"; then MORECFLAGS=$MORECFLAGS" -g" diff --git a/pd/src/g_editor.c b/pd/src/g_editor.c index 7ef5266a..0890d465 100644 --- a/pd/src/g_editor.c +++ b/pd/src/g_editor.c @@ -2251,6 +2251,8 @@ restore: static void canvas_cut(t_canvas *x) { + if (!x->gl_editor) /* ignore if invisible */ + return; if (x->gl_editor && x->gl_editor->e_selectedline) canvas_clearline(x); else if (x->gl_editor->e_textedfor) @@ -2343,6 +2345,8 @@ static void canvas_paste(t_canvas *x) static void canvas_duplicate(t_canvas *x) { + if (!x->gl_editor) + return; if (x->gl_editor->e_onmotion == MA_NONE && x->gl_editor->e_selection) { t_selection *y; @@ -2360,6 +2364,8 @@ static void canvas_duplicate(t_canvas *x) static void canvas_selectall(t_canvas *x) { t_gobj *y; + if (!x->gl_editor) + return; if (!x->gl_edit) canvas_editmode(x, 1); /* if everyone is already selected deselect everyone */ diff --git a/pd/src/makefile.in b/pd/src/makefile.in index 7713be99..ed0f5b7c 100644 --- a/pd/src/makefile.in +++ b/pd/src/makefile.in @@ -1,3 +1,8 @@ +# On Mac OS X, this needs to be defined to enable dlopen and weak linking +# support. Its safe on other platforms since gcc only checks this env var on +# Apple's gcc. <hans@at.or.at> +export MACOSX_DEPLOYMENT_TARGET = 10.3 + VPATH = ../obj:./ OBJ_DIR = ../obj BIN_DIR = ../bin @@ -149,9 +154,8 @@ BINARYMODE=@binarymode@ ABOUT_FILE=$(DESTDIR)$(pddocdir)/1.manual/1.introduction.txt install: all install -d $(DESTDIR)$(libpdbindir) - install $(BIN_DIR)/$(GUINAME) $(DESTDIR)$(libpdbindir)/$(GUINAME) + -install $(BIN_DIR)/$(GUINAME) $(DESTDIR)$(libpdbindir)/$(GUINAME) install $(BIN_DIR)/pd-watchdog $(DESTDIR)$(libpdbindir)/pd-watchdog - install -m644 $(BIN_DIR)/pd.tk $(DESTDIR)$(libpdbindir)/pd.tk install -d $(DESTDIR)$(bindir) install $(BINARYMODE) $(PDEXEC) $(DESTDIR)$(bindir)/pd install -m755 $(BIN_DIR)/pdsend $(DESTDIR)$(bindir)/pdsend diff --git a/pd/src/s_inter.c b/pd/src/s_inter.c index 1f17ce70..1549f9de 100644 --- a/pd/src/s_inter.c +++ b/pd/src/s_inter.c @@ -272,7 +272,7 @@ void sys_setalarm(int microsec) #endif -#ifdef __linux +#ifdef __linux__ #if defined(_POSIX_PRIORITY_SCHEDULING) || defined(_POSIX_MEMLOCK) #include <sched.h> @@ -1063,12 +1063,12 @@ int sys_startgui(const char *libdir) if (stat(wish_paths[i], &statbuf) >= 0) break; } - sprintf(cmdbuf,"\"%s\" %s/tcl/pd.tcl %d\n", wish_paths[i], + sprintf(cmdbuf,"\"%s\" %s/tcl/pd-gui.tcl %d\n", wish_paths[i], libdir, portno); #else sprintf(cmdbuf, "TCL_LIBRARY=\"%s/lib/tcl/library\" TK_LIBRARY=\"%s/lib/tk/library\" \ - wish \"%s/tcl/pd.tcl\" %d\n", + wish \"%s/tcl/pd-gui.tcl\" %d\n", libdir, libdir, libdir, portno); #endif sys_guicmd = cmdbuf; @@ -1116,7 +1116,7 @@ int sys_startgui(const char *libdir) strcpy(scriptbuf, "\""); strcat(scriptbuf, libdir); - strcat(scriptbuf, "/" PDTCLDIR "pd.tcl\""); + strcat(scriptbuf, "/" PDTCLDIR "pd-gui.tcl\""); sys_bashfilename(scriptbuf, scriptbuf); sprintf(portbuf, "%d", portno); diff --git a/pd/src/s_main.c b/pd/src/s_main.c index 058f0232..a1e5af2a 100644 --- a/pd/src/s_main.c +++ b/pd/src/s_main.c @@ -483,12 +483,12 @@ void sys_findprogdir(char *progname) "gui" directory. In "simple" unix installations, the layout is .../bin/pd .../bin/pd-watchdog (etc) - .../tcl/pd.tcl + .../tcl/pd-gui.tcl .../doc and in "complicated" unix installations, it's: .../bin/pd .../lib/pd/bin/pd-watchdog - .../lib/tcl/pd.tcl + .../lib/tcl/pd-gui.tcl .../lib/pd/doc To decide which, we stat .../lib/pd; if that exists, we assume it's the complicated layout. In MSW, it's the "simple" layout, but diff --git a/pd/tcl/AppMain.tcl b/pd/tcl/AppMain.tcl index 26adc832..b170c6f5 100644 --- a/pd/tcl/AppMain.tcl +++ b/pd/tcl/AppMain.tcl @@ -7,8 +7,7 @@ puts --------------------------AppMain.tcl----------------------------------- catch {console show} -# FIXME apple_events must require a newer tcl than 8.4? -# package require apple_events +package require apple_events puts "AppMain.tcl" puts "argv0: $argv0" @@ -21,7 +20,7 @@ if {[string first "-psn" [lindex $argv 0]] == 0} { set argc [expr $argc - 1] } -# launch pd.tk here -if [catch {source [file join [file dirname [info script]] ../tcl/pd.tcl]}] { +# launch pd-gui.tcl here +if [catch {source [file join [file dirname [info script]] pd-gui.tcl]}] { puts stderr $errorInfo } diff --git a/pd/tcl/apple_events.tcl b/pd/tcl/apple_events.tcl index b52dcdba..cfc92982 100644 --- a/pd/tcl/apple_events.tcl +++ b/pd/tcl/apple_events.tcl @@ -29,14 +29,14 @@ proc ::tk::mac::OnShow {} { # kAEShowPreferences proc ::tk::mac::ShowPreferences {} { - menu_preferences_panel + menu_preferences_dialog } # kAEQuitApplication #proc ::tk::mac::Quit {} { -# # TODO sort this out... how to quit pd-gui after sending the message -# puts stderr "Custom exit proc" -# pdsend "pd verifyquit" +# # TODO sort this out... how to quit pd-gui after sending the message +# puts stderr "Custom exit proc" +# pdsend "pd verifyquit" #} # these I gleaned by reading the source (tkMacOSXHLEvents.c) diff --git a/pd/tcl/dialog_array.tcl b/pd/tcl/dialog_array.tcl new file mode 100644 index 00000000..87b2de8c --- /dev/null +++ b/pd/tcl/dialog_array.tcl @@ -0,0 +1,328 @@ +package provide dialog_array 0.1 + +namespace eval ::dialog_array:: { + namespace export pdtk_array_dialog + namespace export pdtk_array_listview_new + namespace export pdtk_array_listview_fillpage + namespace export pdtk_array_listview_setpage + namespace export pdtk_array_listview_closeWindow +} + +# global variables for the listview +array set pd_array_listview_entry {} +array set pd_array_listview_id {} +array set pd_array_listview_page {} +set pd_array_listview_pagesize 0 +# this stores the state of the "save me" check button +array set saveme_button {} +# this stores the state of the "draw as" radio buttons +array set drawas_button {} +# this stores the state of the "in new graph"/"in last graph" radio buttons +# and the "delete array" checkbutton +array set otherflag_button {} + +# TODO figure out how to escape $ args so sharptodollar() isn't needed + +############ pdtk_array_dialog -- dialog window for arrays ######### + +proc ::dialog_array::pdtk_array_listview_setpage {arrayName page} { + set ::pd_array_listview_page($arrayName) $page +} + +proc ::dialog_array::listview_changepage {arrayName np} { + pdtk_array_listview_setpage \ + $arrayName [expr $::pd_array_listview_page($arrayName) + $np] + pdtk_array_listview_fillpage $arrayName +} + +proc ::dialog_array::pdtk_array_listview_fillpage {arrayName} { + set windowName [format ".%sArrayWindow" $arrayName] + set topItem [expr [lindex [$windowName.lb yview] 0] * \ + [$windowName.lb size]] + + if {[winfo exists $windowName]} { + set cmd "$::pd_array_listview_id($arrayName) \ + arrayviewlistfillpage \ + $::pd_array_listview_page($arrayName) \ + $topItem" + + pdsend $cmd + } +} + +proc ::dialog_array::pdtk_array_listview_new {id arrayName page} { + set ::pd_array_listview_page($arrayName) $page + set ::pd_array_listview_id($arrayName) $id + set windowName [format ".%sArrayWindow" $arrayName] + if [winfo exists $windowName] then [destroy $windowName] + toplevel $windowName -class DialogWindow + wm group $windowName . + wm protocol $windowName WM_DELETE_WINDOW \ + "::dialog_array::listview_close $id $arrayName" + wm title $windowName [concat $arrayName "(list view)"] + # FIXME + set font 12 + set $windowName.lb [listbox $windowName.lb -height 20 -width 25\ + -selectmode extended \ + -relief solid -background white -borderwidth 1 \ + -font [format {{%s} %d %s} $::font_family $font $::font_weight]\ + -yscrollcommand "$windowName.lb.sb set"] + set $windowName.lb.sb [scrollbar $windowName.lb.sb \ + -command "$windowName.lb yview" -orient vertical] + place configure $windowName.lb.sb -relheight 1 -relx 0.9 -relwidth 0.1 + pack $windowName.lb -expand 1 -fill both + bind $windowName.lb <Double-ButtonPress-1> \ + "::dialog_array::listview_edit $arrayName $page $font" + # handle copy/paste + switch -- $::windowingsystem { + "x11" {selection handle $windowName.lb \ + "::dialog_array::listview_lbselection $arrayName"} + "win32" {bind $windowName.lb <ButtonPress-3> \ + "::dialog_array::listview_popup $arrayName"} + } + set $windowName.prevBtn [button $windowName.prevBtn -text "<-" \ + -command "::dialog_array::listview_changepage $arrayName -1"] + set $windowName.nextBtn [button $windowName.nextBtn -text "->" \ + -command "::dialog_array::listview_changepage $arrayName 1"] + pack $windowName.prevBtn -side left -ipadx 20 -pady 10 -anchor s + pack $windowName.nextBtn -side right -ipadx 20 -pady 10 -anchor s + focus $windowName +} + +proc ::dialog_array::listview_lbselection {arrayName off size} { + set windowName [format ".%sArrayWindow" $arrayName] + set itemNums [$windowName.lb curselection] + set cbString "" + for {set i 0} {$i < [expr [llength $itemNums] - 1]} {incr i} { + set listItem [$windowName.lb get [lindex $itemNums $i]] + append cbString [string range $listItem \ + [expr [string first ") " $listItem] + 2] \ + end] + append cbString "\n" + } + set listItem [$windowName.lb get [lindex $itemNums $i]] + append cbString [string range $listItem \ + [expr [string first ") " $listItem] + 2] \ + end] + set last $cbString +} + +# Win32 uses a popup menu for copy/paste +proc ::dialog_array::listview_popup {arrayName} { + set windowName [format ".%sArrayWindow" $arrayName] + if [winfo exists $windowName.popup] then [destroy $windowName.popup] + menu $windowName.popup -tearoff false + $windowName.popup add command -label [_ "Copy"] \ + -command "::dialog_array::listview_copy $arrayName; \ + destroy $windowName.popup" + $windowName.popup add command -label [_ "Paste"] \ + -command "::dialog_array::listview_paste $arrayName; \ + destroy $windowName.popup" + tk_popup $windowName.popup [winfo pointerx $windowName] \ + [winfo pointery $windowName] 0 +} + +proc ::dialog_array::listview_copy {arrayName} { + set windowName [format ".%sArrayWindow" $arrayName] + set itemNums [$windowName.lb curselection] + set cbString "" + for {set i 0} {$i < [expr [llength $itemNums] - 1]} {incr i} { + set listItem [$windowName.lb get [lindex $itemNums $i]] + append cbString [string range $listItem \ + [expr [string first ") " $listItem] + 2] \ + end] + append cbString "\n" + } + set listItem [$windowName.lb get [lindex $itemNums $i]] + append cbString [string range $listItem \ + [expr [string first ") " $listItem] + 2] \ + end] + clipboard clear + clipboard append $cbString +} + +proc ::dialog_array::listview_paste {arrayName} { + set cbString [selection get -selection CLIPBOARD] + set lbName [format ".%sArrayWindow.lb" $arrayName] + set itemNum [lindex [$lbName curselection] 0] + set splitChars ", \n" + set itemString [split $cbString $splitChars] + set flag 1 + for {set i 0; set counter 0} {$i < [llength $itemString]} {incr i} { + if {[lindex $itemString $i] ne {}} { + pdsend "$arrayName [expr $itemNum + \ + [expr $counter + \ + [expr $::pd_array_listview_pagesize \ + * $::pd_array_listview_page($arrayName)]]] \ + [lindex $itemString $i]" + incr counter + set flag 0 + } + } +} + +proc ::dialog_array::listview_edit {arrayName page font} { + set lbName [format ".%sArrayWindow.lb" $arrayName] + if {[winfo exists $lbName.entry]} { + ::dialog_array::listview_update_entry \ + $arrayName $::pd_array_listview_entry($arrayName) + unset ::pd_array_listview_entry($arrayName) + } + set itemNum [$lbName index active] + set ::pd_array_listview_entry($arrayName) $itemNum + set bbox [$lbName bbox $itemNum] + set y [expr [lindex $bbox 1] - 4] + set $lbName.entry [entry $lbName.entry \ + -font [format {{%s} %d %s} $::font_family $font $::font_weight]] + $lbName.entry insert 0 [] + place configure $lbName.entry -relx 0 -y $y -relwidth 1 + lower $lbName.entry + focus $lbName.entry + bind $lbName.entry <Return> \ + "::dialog_array::listview_update_entry $arrayName $itemNum;" +} + +proc ::dialog_array::listview_update_entry {arrayName itemNum} { + set lbName [format ".%sArrayWindow.lb" $arrayName] + set splitChars ", \n" + set itemString [split [$lbName.entry get] $splitChars] + set flag 1 + for {set i 0; set counter 0} {$i < [llength $itemString]} {incr i} { + if {[lindex $itemString $i] ne {}} { + pdsend "$arrayName [expr $itemNum + \ + [expr $counter + \ + [expr $::pd_array_listview_pagesize \ + * $::pd_array_listview_page($arrayName)]]] \ + [lindex $itemString $i]" + incr counter + set flag 0 + } + } + pdtk_array_listview_fillpage $arrayName + destroy $lbName.entry +} + +proc ::dialog_array::pdtk_array_listview_closeWindow {arrayName} { + set mytoplevel [format ".%sArrayWindow" $arrayName] + destroy $mytoplevel +} + +proc ::dialog_array::listview_close {mytoplevel arrayName} { + pdtk_array_listview_closeWindow $arrayName + pdsend "$mytoplevel arrayviewclose" +} + +proc ::dialog_array::apply {mytoplevel} { +# TODO figure out how to ditch this escaping mechanism + set mofo [$mytoplevel.name.entry get] + if {[string index $mofo 0] == "$"} { + set mofo [string replace $mofo 0 0 #] } + + pdsend "$mytoplevel arraydialog \ + $mofo \ + [$mytoplevel.size.entry get] \ + [expr $::saveme_button($mytoplevel) + (2 * $::drawas_button($mytoplevel))] \ + $::otherflag_button($mytoplevel)" +} + +proc ::dialog_array::openlistview {mytoplevel} { + pdsend "$mytoplevel arrayviewlistnew" +} + +proc ::dialog_array::cancel {mytoplevel} { + pdsend "$mytoplevel cancel" +} + +proc ::dialog_array::ok {mytoplevel} { + ::dialog_array::apply $mytoplevel + ::dialog_array::cancel $mytoplevel +} + +proc ::dialog_array::pdtk_array_dialog {mytoplevel name size flags newone} { +puts "::dialog_array::pdtk_array_dialog {$mytoplevel $name $size $flags $newone}" + if {[winfo exists $mytoplevel]} { + wm deiconify $mytoplevel + raise $mytoplevel + } else { + create_dialog $mytoplevel $newone + } + + $mytoplevel.name.entry insert 0 $name + $mytoplevel.size.entry insert 0 $size + set ::saveme_button($mytoplevel) [expr $flags & 1] + set ::drawas_button($mytoplevel) [expr ( $flags & 6 ) >> 1] + set ::otherflag_button($mytoplevel) 0 +# pd -> tcl +# 2 * (int)(template_getfloat(template_findbyname(sc->sc_template), gensym("style"), x->x_scalar->sc_vec, 1))); + +# tcl->pd +# int style = ((flags & 6) >> 1); +} + +proc ::dialog_array::create_dialog {mytoplevel newone} { + toplevel $mytoplevel -class DialogWindow + wm title $mytoplevel [_ "Array Properties"] + if {$::windowingsystem eq "aqua"} {$mytoplevel configure -menu .menubar} + ::pd_bindings::dialog_bindings $mytoplevel "array" + + frame $mytoplevel.name + pack $mytoplevel.name -side top + label $mytoplevel.name.label -text [_ "Name:"] + entry $mytoplevel.name.entry + pack $mytoplevel.name.label $mytoplevel.name.entry -anchor w + + frame $mytoplevel.size + pack $mytoplevel.size -side top + label $mytoplevel.size.label -text [_ "Size:"] + entry $mytoplevel.size.entry + pack $mytoplevel.size.label $mytoplevel.size.entry -anchor w + + checkbutton $mytoplevel.saveme -text [_ "Save contents"] \ + -variable ::saveme_button($mytoplevel) -anchor w + pack $mytoplevel.saveme -side top + + labelframe $mytoplevel.drawas -text [_ "Draw as:"] -padx 20 -borderwidth 1 + pack $mytoplevel.drawas -side top -fill x + radiobutton $mytoplevel.drawas.points -value 0 \ + -variable ::drawas_button($mytoplevel) -text [_ "Points"] + radiobutton $mytoplevel.drawas.polygon -value 1 \ + -variable ::drawas_button($mytoplevel) -text [_ "Polygon"] + radiobutton $mytoplevel.drawas.bezier -value 2 \ + -variable ::drawas_button($mytoplevel) -text [_ "Bezier curve"] + pack $mytoplevel.drawas.points -side top -anchor w + pack $mytoplevel.drawas.polygon -side top -anchor w + pack $mytoplevel.drawas.bezier -side top -anchor w + + if {$newone != 0} { + labelframe $mytoplevel.radio -text [_ "Put array into:"] -padx 20 -borderwidth 1 + pack $mytoplevel.radio -side top -fill x + radiobutton $mytoplevel.radio.radio0 -value 0 \ + -variable ::otherflag_button($mytoplevel) -text [_ "New graph"] + radiobutton $mytoplevel.radio.radio1 -value 1 \ + -variable ::otherflag_button($mytoplevel) -text [_ "Last graph"] + pack $mytoplevel.radio.radio0 -side top -anchor w + pack $mytoplevel.radio.radio1 -side top -anchor w + } else { + checkbutton $mytoplevel.deletearray -text [_ "Delete array"] \ + -variable ::otherflag_button($mytoplevel) -anchor w + pack $mytoplevel.deletearray -side top + } + # jsarlo + if {$newone == 0} { + button $mytoplevel.listview -text [_ "Open List View..."] \ + -command "::dialog_array::openlistview $mytoplevel [$mytoplevel.name.entry get]" + pack $mytoplevel.listview -side top + } + # end jsarlo + frame $mytoplevel.buttonframe + pack $mytoplevel.buttonframe -side bottom -fill x -pady 2m + button $mytoplevel.buttonframe.cancel -text [_ "Cancel"] \ + -command "::dialog_array::cancel $mytoplevel" + if {$newone == 0} {button $mytoplevel.buttonframe.apply -text [_ "Apply"] \ + -command "::dialog_array::apply $mytoplevel"} + button $mytoplevel.buttonframe.ok -text [_ "OK"]\ + -command "::dialog_array::ok $mytoplevel" + pack $mytoplevel.buttonframe.cancel -side left -expand 1 + if {$newone == 0} {pack $mytoplevel.buttonframe.apply -side left -expand 1} + pack $mytoplevel.buttonframe.ok -side left -expand 1 +} diff --git a/pd/tcl/dialog_audio.tcl b/pd/tcl/dialog_audio.tcl new file mode 100644 index 00000000..1025f66e --- /dev/null +++ b/pd/tcl/dialog_audio.tcl @@ -0,0 +1,298 @@ +package provide dialog_audio 0.1 + +namespace eval ::dialog_audio:: { + namespace export pdtk_audio_dialog +} + +# TODO this panel really needs some reworking, it works but the code is +# very unreadable + +####################### audio dialog ##################3 + +proc ::dialog_audio::apply {id} { + global audio_indev1 audio_indev2 audio_indev3 audio_indev4 + global audio_inchan1 audio_inchan2 audio_inchan3 audio_inchan4 + global audio_inenable1 audio_inenable2 audio_inenable3 audio_inenable4 + global audio_outdev1 audio_outdev2 audio_outdev3 audio_outdev4 + global audio_outchan1 audio_outchan2 audio_outchan3 audio_outchan4 + global audio_outenable1 audio_outenable2 audio_outenable3 audio_outenable4 + global audio_sr audio_advance audio_callback + + pdsend "pd audio-dialog \ + $audio_indev1 \ + $audio_indev2 \ + $audio_indev3 \ + $audio_indev4 \ + [expr $audio_inchan1 * ( $audio_inenable1 ? 1 : -1 ) ]\ + [expr $audio_inchan2 * ( $audio_inenable2 ? 1 : -1 ) ]\ + [expr $audio_inchan3 * ( $audio_inenable3 ? 1 : -1 ) ]\ + [expr $audio_inchan4 * ( $audio_inenable4 ? 1 : -1 ) ]\ + $audio_outdev1 \ + $audio_outdev2 \ + $audio_outdev3 \ + $audio_outdev4 \ + [expr $audio_outchan1 * ( $audio_outenable1 ? 1 : -1 ) ]\ + [expr $audio_outchan2 * ( $audio_outenable2 ? 1 : -1 ) ]\ + [expr $audio_outchan3 * ( $audio_outenable3 ? 1 : -1 ) ]\ + [expr $audio_outchan4 * ( $audio_outenable4 ? 1 : -1 ) ]\ + $audio_sr \ + $audio_advance \ + $audio_callback" +} + +proc ::dialog_audio::cancel {id} { + pdsend "$id cancel" +} + +proc ::dialog_audio::ok {id} { + ::dialog_audio::apply $id + ::dialog_audio::cancel $id +} + +# callback from popup menu +proc audio_popup_action {buttonname varname devlist index} { + global audio_indevlist audio_outdevlist $varname + $buttonname configure -text [lindex $devlist $index] + set $varname $index +} + +# create a popup menu +proc audio_popup {name buttonname varname devlist} { + if [winfo exists $name.popup] {destroy $name.popup} + menu $name.popup -tearoff false + if {$::windowingsystem eq "win32"} { + $name.popup configure -font menuFont + } + for {set x 0} {$x<[llength $devlist]} {incr x} { + $name.popup add command -label [lindex $devlist $x] \ + -command [list audio_popup_action \ + $buttonname $varname $devlist $x] + } + tk_popup $name.popup [winfo pointerx $name] [winfo pointery $name] 0 +} + +# start a dialog window to select audio devices and settings. "multi" +# is 0 if only one device is allowed; 1 if one apiece may be specified for +# input and output; and 2 if we can select multiple devices. "longform" +# (which only makes sense if "multi" is 2) asks us to make controls for +# opening several devices; if not, we get an extra button to turn longform +# on and restart the dialog. + +proc ::dialog_audio::pdtk_audio_dialog {id indev1 indev2 indev3 indev4 \ + inchan1 inchan2 inchan3 inchan4 \ + outdev1 outdev2 outdev3 outdev4 \ + outchan1 outchan2 outchan3 outchan4 sr advance multi callback \ + longform} { + global audio_indev1 audio_indev2 audio_indev3 audio_indev4 + global audio_inchan1 audio_inchan2 audio_inchan3 audio_inchan4 + global audio_inenable1 audio_inenable2 audio_inenable3 audio_inenable4 + global audio_outdev1 audio_outdev2 audio_outdev3 audio_outdev4 + global audio_outchan1 audio_outchan2 audio_outchan3 audio_outchan4 + global audio_outenable1 audio_outenable2 audio_outenable3 audio_outenable4 + global audio_sr audio_advance audio_callback + global audio_indevlist audio_outdevlist + global pd_indev pd_outdev + global audio_longform + + set audio_indev1 $indev1 + set audio_indev2 $indev2 + set audio_indev3 $indev3 + set audio_indev4 $indev4 + + set audio_inchan1 [expr ( $inchan1 > 0 ? $inchan1 : -$inchan1 ) ] + set audio_inenable1 [expr $inchan1 > 0 ] + set audio_inchan2 [expr ( $inchan2 > 0 ? $inchan2 : -$inchan2 ) ] + set audio_inenable2 [expr $inchan2 > 0 ] + set audio_inchan3 [expr ( $inchan3 > 0 ? $inchan3 : -$inchan3 ) ] + set audio_inenable3 [expr $inchan3 > 0 ] + set audio_inchan4 [expr ( $inchan4 > 0 ? $inchan4 : -$inchan4 ) ] + set audio_inenable4 [expr $inchan4 > 0 ] + + set audio_outdev1 $outdev1 + set audio_outdev2 $outdev2 + set audio_outdev3 $outdev3 + set audio_outdev4 $outdev4 + + set audio_outchan1 [expr ( $outchan1 > 0 ? $outchan1 : -$outchan1 ) ] + set audio_outenable1 [expr $outchan1 > 0 ] + set audio_outchan2 [expr ( $outchan2 > 0 ? $outchan2 : -$outchan2 ) ] + set audio_outenable2 [expr $outchan2 > 0 ] + set audio_outchan3 [expr ( $outchan3 > 0 ? $outchan3 : -$outchan3 ) ] + set audio_outenable3 [expr $outchan3 > 0 ] + set audio_outchan4 [expr ( $outchan4 > 0 ? $outchan4 : -$outchan4 ) ] + set audio_outenable4 [expr $outchan4 > 0 ] + + set audio_sr $sr + set audio_advance $advance + set audio_callback $callback + + toplevel $id + wm title $id [_ "Audio Settings"] + if {$::windowingsystem eq "aqua"} {$id configure -menu .menubar} + ::pd_bindings::dialog_bindings $id "audio" + + frame $id.buttonframe + pack $id.buttonframe -side bottom -fill x -pady 2m + button $id.buttonframe.cancel -text [_ "Cancel"]\ + -command "::dialog_audio::cancel $id" + button $id.buttonframe.apply -text [_ "Apply"]\ + -command "::dialog_audio::apply $id" + button $id.buttonframe.ok -text [_ "OK"]\ + -command "::dialog_audio::ok $id" + button $id.buttonframe.save -text [_ "Save all settings"]\ + -command "::dialog_audio::apply $id \; pdsend \"pd save-preferences\"" + pack $id.buttonframe.cancel $id.buttonframe.apply $id.buttonframe.ok \ + $id.buttonframe.save -side left -expand 1 + + # sample rate and advance + frame $id.srf + pack $id.srf -side top + + label $id.srf.l1 -text [_ "Sample rate:"] + entry $id.srf.x1 -textvariable audio_sr -width 7 + label $id.srf.l2 -text [_ "Delay (msec):"] + entry $id.srf.x2 -textvariable audio_advance -width 4 + pack $id.srf.l1 $id.srf.x1 $id.srf.l2 $id.srf.x2 -side left + if {$audio_callback >= 0} { + checkbutton $id.srf.x3 -variable audio_callback \ + -text [_ "Use callbacks"] -anchor e + pack $id.srf.x3 -side left + } + # input device 1 + frame $id.in1f + pack $id.in1f -side top + + checkbutton $id.in1f.x0 -variable audio_inenable1 \ + -text [_ "Input device 1:"] -anchor e + button $id.in1f.x1 -text [lindex $audio_indevlist $audio_indev1] \ + -command [list audio_popup $id $id.in1f.x1 audio_indev1 $audio_indevlist] + label $id.in1f.l2 -text [_ "Channels:"] + entry $id.in1f.x2 -textvariable audio_inchan1 -width 3 + pack $id.in1f.x0 $id.in1f.x1 $id.in1f.l2 $id.in1f.x2 -side left -fill x + + # input device 2 + if {$longform && $multi > 1 && [llength $audio_indevlist] > 1} { + frame $id.in2f + pack $id.in2f -side top + + checkbutton $id.in2f.x0 -variable audio_inenable2 \ + -text [_ "Input device 2:"] -anchor e + button $id.in2f.x1 -text [lindex $audio_indevlist $audio_indev2] \ + -command [list audio_popup $id $id.in2f.x1 audio_indev2 \ + $audio_indevlist] + label $id.in2f.l2 -text [_ "Channels:"] + entry $id.in2f.x2 -textvariable audio_inchan2 -width 3 + pack $id.in2f.x0 $id.in2f.x1 $id.in2f.l2 $id.in2f.x2 -side left -fill x + } + + # input device 3 + if {$longform && $multi > 1 && [llength $audio_indevlist] > 2} { + frame $id.in3f + pack $id.in3f -side top + + checkbutton $id.in3f.x0 -variable audio_inenable3 \ + -text [_ "Input device 3:"] -anchor e + button $id.in3f.x1 -text [lindex $audio_indevlist $audio_indev3] \ + -command [list audio_popup $id $id.in3f.x1 audio_indev3 \ + $audio_indevlist] + label $id.in3f.l2 -text [_ "Channels:"] + entry $id.in3f.x2 -textvariable audio_inchan3 -width 3 + pack $id.in3f.x0 $id.in3f.x1 $id.in3f.l2 $id.in3f.x2 -side left + } + + # input device 4 + if {$longform && $multi > 1 && [llength $audio_indevlist] > 3} { + frame $id.in4f + pack $id.in4f -side top + + checkbutton $id.in4f.x0 -variable audio_inenable4 \ + -text [_ "Input device 4:"] -anchor e + button $id.in4f.x1 -text [lindex $audio_indevlist $audio_indev4] \ + -command [list audio_popup $id $id.in4f.x1 audio_indev4 \ + $audio_indevlist] + label $id.in4f.l2 -text [_ "Channels:"] + entry $id.in4f.x2 -textvariable audio_inchan4 -width 3 + pack $id.in4f.x0 $id.in4f.x1 $id.in4f.l2 $id.in4f.x2 -side left + } + + # output device 1 + frame $id.out1f + pack $id.out1f -side top + + checkbutton $id.out1f.x0 -variable audio_outenable1 \ + -text [_ "Output device 1:"] -anchor e + if {$multi == 0} { + label $id.out1f.l1 \ + -text [_ "(same as input device) .............. "] + } else { + button $id.out1f.x1 -text [lindex $audio_outdevlist $audio_outdev1] \ + -command [list audio_popup $id $id.out1f.x1 audio_outdev1 \ + $audio_outdevlist] + } + label $id.out1f.l2 -text [_ "Channels:"] + entry $id.out1f.x2 -textvariable audio_outchan1 -width 3 + if {$multi == 0} { + pack $id.out1f.x0 $id.out1f.l1 $id.out1f.x2 -side left -fill x + } else { + pack $id.out1f.x0 $id.out1f.x1 $id.out1f.l2 $id.out1f.x2 -side left -fill x + } + + # output device 2 + if {$longform && $multi > 1 && [llength $audio_outdevlist] > 1} { + frame $id.out2f + pack $id.out2f -side top + + checkbutton $id.out2f.x0 -variable audio_outenable2 \ + -text [_ "Output device 2:"] -anchor e + button $id.out2f.x1 -text [lindex $audio_outdevlist $audio_outdev2] \ + -command \ + [list audio_popup $id $id.out2f.x1 audio_outdev2 $audio_outdevlist] + label $id.out2f.l2 -text [_ "Channels:"] + entry $id.out2f.x2 -textvariable audio_outchan2 -width 3 + pack $id.out2f.x0 $id.out2f.x1 $id.out2f.l2 $id.out2f.x2 -side left + } + + # output device 3 + if {$longform && $multi > 1 && [llength $audio_outdevlist] > 2} { + frame $id.out3f + pack $id.out3f -side top + + checkbutton $id.out3f.x0 -variable audio_outenable3 \ + -text [_ "Output device 3:"] -anchor e + button $id.out3f.x1 -text [lindex $audio_outdevlist $audio_outdev3] \ + -command \ + [list audio_popup $id $id.out3f.x1 audio_outdev3 $audio_outdevlist] + label $id.out3f.l2 -text [_ "Channels:"] + entry $id.out3f.x2 -textvariable audio_outchan3 -width 3 + pack $id.out3f.x0 $id.out3f.x1 $id.out3f.l2 $id.out3f.x2 -side left + } + + # output device 4 + if {$longform && $multi > 1 && [llength $audio_outdevlist] > 3} { + frame $id.out4f + pack $id.out4f -side top + + checkbutton $id.out4f.x0 -variable audio_outenable4 \ + -text [_ "Output device 4:"] -anchor e + button $id.out4f.x1 -text [lindex $audio_outdevlist $audio_outdev4] \ + -command \ + [list audio_popup $id $id.out4f.x1 audio_outdev4 $audio_outdevlist] + label $id.out4f.l2 -text [_ "Channels:"] + entry $id.out4f.x2 -textvariable audio_outchan4 -width 3 + pack $id.out4f.x0 $id.out4f.x1 $id.out4f.l2 $id.out4f.x2 -side left + } + + # if not the "long form" but if "multi" is 2, make a button to + # restart with longform set. + + if {$longform == 0 && $multi > 1} { + frame $id.longbutton + pack $id.longbutton -side top + button $id.longbutton.b -text [_ "Use multiple devices"] \ + -command {pdsend "pd audio-properties 1"} + pack $id.longbutton.b + } + $id.srf.x1 select from 0 + $id.srf.x1 select adjust end + focus $id.srf.x1 +} diff --git a/pd/tcl/dialog_canvas.tcl b/pd/tcl/dialog_canvas.tcl new file mode 100644 index 00000000..06444807 --- /dev/null +++ b/pd/tcl/dialog_canvas.tcl @@ -0,0 +1,213 @@ + +# TODO offset this panel so it doesn't overlap the pdtk_array panel + +package provide dialog_canvas 0.1 + +namespace eval ::dialog_canvas:: { + namespace export pdtk_canvas_dialog +} + +# global variables to store checkbox state on canvas properties window. These +# are only used in the context of getting data from the checkboxes, so they +# aren't really useful elsewhere. It would be nice to have them globally +# useful, but that would mean changing the C code. +array set graphme_button {} +array set hidetext_button {} + +############# pdtk_canvas_dialog -- dialog window for canvases ################# + +proc ::dialog_canvas::apply {mytoplevel} { + pdsend "$mytoplevel donecanvasdialog \ + [$mytoplevel.scale.x.entry get] \ + [$mytoplevel.scale.y.entry get] \ + [expr $::graphme_button($mytoplevel) + 2 * $::hidetext_button($mytoplevel)] \ + [$mytoplevel.range.x.from_entry get] \ + [$mytoplevel.range.y.from_entry get] \ + [$mytoplevel.range.x.to_entry get] \ + [$mytoplevel.range.y.to_entry get] \ + [$mytoplevel.range.x.size_entry get] \ + [$mytoplevel.range.y.size_entry get] \ + [$mytoplevel.range.x.margin_entry get] \ + [$mytoplevel.range.y.margin_entry get]" +} + +proc ::dialog_canvas::cancel {mytoplevel} { + pdsend "$mytoplevel cancel" +} + +proc ::dialog_canvas::ok {mytoplevel} { + ::dialog_canvas::apply $mytoplevel + ::dialog_canvas::cancel $mytoplevel +} + +proc ::dialog_canvas::checkcommand {mytoplevel} { + if { $::graphme_button($mytoplevel) != 0 } { + $mytoplevel.scale.x.entry configure -state disabled + $mytoplevel.scale.y.entry configure -state disabled + $mytoplevel.parent.hidetext configure -state normal + $mytoplevel.range.x.from_entry configure -state normal + $mytoplevel.range.x.to_entry configure -state normal + $mytoplevel.range.x.size_entry configure -state normal + $mytoplevel.range.x.margin_entry configure -state normal + $mytoplevel.range.y.from_entry configure -state normal + $mytoplevel.range.y.to_entry configure -state normal + $mytoplevel.range.y.size_entry configure -state normal + $mytoplevel.range.y.margin_entry configure -state normal + if { [$mytoplevel.range.x.from_entry get] == 0 \ + && [$mytoplevel.range.y.from_entry get] == 0 \ + && [$mytoplevel.range.x.to_entry get] == 0 \ + && [$mytoplevel.range.y.to_entry get] == 0 } { + $mytoplevel.range.y.to_entry insert 0 1 + $mytoplevel.range.y.to_entry insert 0 1 + } + if { [$mytoplevel.range.x.size_entry get] == 0 } { + $mytoplevel.range.x.size_entry delete 0 end + $mytoplevel.range.x.margin_entry delete 0 end + $mytoplevel.range.x.size_entry insert 0 85 + $mytoplevel.range.x.margin_entry insert 0 100 + } + if { [$mytoplevel.range.y.size_entry get] == 0 } { + $mytoplevel.range.y.size_entry delete 0 end + $mytoplevel.range.y.margin_entry delete 0 end + $mytoplevel.range.y.size_entry insert 0 60 + $mytoplevel.range.y.margin_entry insert 0 100 + } + } else { + $mytoplevel.scale.x.entry configure -state normal + $mytoplevel.scale.y.entry configure -state normal + $mytoplevel.parent.hidetext configure -state disabled + $mytoplevel.range.x.from_entry configure -state disabled + $mytoplevel.range.x.to_entry configure -state disabled + $mytoplevel.range.x.size_entry configure -state disabled + $mytoplevel.range.x.margin_entry configure -state disabled + $mytoplevel.range.y.from_entry configure -state disabled + $mytoplevel.range.y.to_entry configure -state disabled + $mytoplevel.range.y.size_entry configure -state disabled + $mytoplevel.range.y.margin_entry configure -state disabled + if { [$mytoplevel.scale.x.entry get] == 0 } { + $mytoplevel.scale.x.entry delete 0 end + $mytoplevel.scale.x.entry insert 0 1 + } + if { [$mytoplevel.scale.y.entry get] == 0 } { + $mytoplevel.scale.y.entry delete 0 end + $mytoplevel.scale.y.entry insert 0 1 + } + } +} + +proc ::dialog_canvas::pdtk_canvas_dialog {mytoplevel xscale yscale graphmeflags \ + xfrom yfrom xto yto \ + xsize ysize xmargin ymargin} { + if {[winfo exists $mytoplevel]} { + wm deiconify $mytoplevel + raise $mytoplevel + } else { + create_dialog $mytoplevel + } + puts "canvas_dialog $mytoplevel" + switch -- $graphmeflags { + 0 { + $mytoplevel.parent.graphme deselect + $mytoplevel.parent.hidetext deselect + } 1 { + $mytoplevel.parent.graphme select + $mytoplevel.parent.hidetext deselect + } 2 { + $mytoplevel.parent.graphme deselect + $mytoplevel.parent.hidetext select + } 3 { + $mytoplevel.parent.graphme select + $mytoplevel.parent.hidetext select + } default { + pdtk_post "Warning: unknown graphme flags received in pdtk_canvas_dialog" + } + } + + $mytoplevel.scale.x.entry insert 0 $xscale + $mytoplevel.scale.y.entry insert 0 $yscale + $mytoplevel.range.x.from_entry insert 0 $xfrom + $mytoplevel.range.y.from_entry insert 0 $yfrom + $mytoplevel.range.x.to_entry insert 0 $xto + $mytoplevel.range.y.to_entry insert 0 $yto + $mytoplevel.range.x.size_entry insert 0 $xsize + $mytoplevel.range.y.size_entry insert 0 $ysize + $mytoplevel.range.x.margin_entry insert 0 $xsize + $mytoplevel.range.y.margin_entry insert 0 $ysize + + ::dialog_canvas::checkcommand $mytoplevel +} + +proc ::dialog_canvas::create_dialog {mytoplevel} { + toplevel $mytoplevel -class DialogWindow + wm title $mytoplevel [_ "Canvas Properties"] + if {$::windowingsystem eq "aqua"} {$mytoplevel configure -menu .menubar} + ::pd_bindings::dialog_bindings $mytoplevel "canvas" + + labelframe $mytoplevel.scale -text [_ "Scale"] -borderwidth 1 + pack $mytoplevel.scale -side top -fill x + frame $mytoplevel.scale.x -pady 2 -borderwidth 1 + pack $mytoplevel.scale.x -side top + label $mytoplevel.scale.x.label -text [_ "X units per pixel:"] + entry $mytoplevel.scale.x.entry -width 10 + pack $mytoplevel.scale.x.label $mytoplevel.scale.x.entry -side left + frame $mytoplevel.scale.y -pady 2 + pack $mytoplevel.scale.y -side top + label $mytoplevel.scale.y.label -text [_ "Y units per pixel:"] + entry $mytoplevel.scale.y.entry -width 10 + pack $mytoplevel.scale.y.label $mytoplevel.scale.y.entry -side left + + labelframe $mytoplevel.parent -text [_ "Appearance on parent patch"] -borderwidth 1 + pack $mytoplevel.parent -side top -fill x + checkbutton $mytoplevel.parent.graphme -text [_ "Graph-On-Parent"] \ + -anchor w -variable graphme_button($mytoplevel) \ + -command [concat ::dialog_canvas::checkcommand $mytoplevel] + pack $mytoplevel.parent.graphme -side top -fill x -padx 40 + checkbutton $mytoplevel.parent.hidetext -text [_ "Hide object name and arguments"] \ + -anchor w -variable hidetext_button($mytoplevel) \ + -command [concat ::dialog_canvas::checkcommand $mytoplevel] + pack $mytoplevel.parent.hidetext -side top -fill x -padx 40 + + labelframe $mytoplevel.range -text [_ "Range and size"] -borderwidth 1 + pack $mytoplevel.range -side top -fill x + frame $mytoplevel.range.x -padx 2 -pady 2 + pack $mytoplevel.range.x -side top + label $mytoplevel.range.x.from_label -text [_ "X range, from"] + entry $mytoplevel.range.x.from_entry -width 6 + label $mytoplevel.range.x.to_label -text [_ "to"] + entry $mytoplevel.range.x.to_entry -width 6 + label $mytoplevel.range.x.size_label -text [_ "Size:"] + entry $mytoplevel.range.x.size_entry -width 4 + label $mytoplevel.range.x.margin_label -text [_ "Margin:"] + entry $mytoplevel.range.x.margin_entry -width 4 + pack $mytoplevel.range.x.from_label $mytoplevel.range.x.from_entry \ + $mytoplevel.range.x.to_label $mytoplevel.range.x.to_entry \ + $mytoplevel.range.x.size_label $mytoplevel.range.x.size_entry \ + $mytoplevel.range.x.margin_label $mytoplevel.range.x.margin_entry \ + -side left + frame $mytoplevel.range.y -padx 2 -pady 2 + pack $mytoplevel.range.y -side top + label $mytoplevel.range.y.from_label -text [_ "Y range, from"] + entry $mytoplevel.range.y.from_entry -width 6 + label $mytoplevel.range.y.to_label -text [_ "to"] + entry $mytoplevel.range.y.to_entry -width 6 + label $mytoplevel.range.y.size_label -text [_ "Size:"] + entry $mytoplevel.range.y.size_entry -width 4 + label $mytoplevel.range.y.margin_label -text [_ "Margin:"] + entry $mytoplevel.range.y.margin_entry -width 4 + pack $mytoplevel.range.y.from_label $mytoplevel.range.y.from_entry \ + $mytoplevel.range.y.to_label $mytoplevel.range.y.to_entry \ + $mytoplevel.range.y.size_label $mytoplevel.range.y.size_entry \ + $mytoplevel.range.y.margin_label $mytoplevel.range.y.margin_entry \ + -side left + + frame $mytoplevel.buttons + pack $mytoplevel.buttons -side bottom -fill x -pady 2m + button $mytoplevel.buttons.cancel -text [_ "Cancel"] \ + -command "::dialog_canvas::cancel $mytoplevel" + button $mytoplevel.buttons.apply -text [_ "Apply"] \ + -command "::dialog_canvas::apply $mytoplevel" + button $mytoplevel.buttons.ok -text [_ "OK"] \ + -command "::dialog_canvas::ok $mytoplevel" + pack $mytoplevel.buttons.cancel $mytoplevel.buttons.apply \ + $mytoplevel.buttons.ok -side left -expand 1 + } diff --git a/pd/tcl/dialog_find.tcl b/pd/tcl/dialog_find.tcl index 92d58347..c7a708ae 100644 --- a/pd/tcl/dialog_find.tcl +++ b/pd/tcl/dialog_find.tcl @@ -4,42 +4,62 @@ package provide dialog_find 0.1 package require pd_bindings namespace eval ::dialog_find:: { + # store the state of the "Match whole word only" check box + variable wholeword_button 0 + # if the search hasn't changed, then the Find button sends "findagain" + variable previous_wholeword_button 0 + variable previous_findstring "" + namespace export menu_dialog_find } -# TODO figure out findagain -# TODO make targetlabel into a popup menu -# TODO make panel go away after a find +# TODO make find panel as small as possible, being topmost means its findable +# TODO (GNOME/Windows) find panel should retain focus after a find +# TODO (Mac OS X) hide panel after success, but stay if the find was unsuccessful -proc find_ok {mytoplevel} {::dialog_find::ok $mytoplevel} ;# TODO temp kludge proc ::dialog_find::ok {mytoplevel} { + variable wholeword_button + variable previous_wholeword_button + variable previous_findstring # find will be on top, so use the previous window that was on top set search_window [lindex [wm stackorder .] end-1] - if {$search_window eq "."} { - puts "search pd window not implemented yet" + puts "search_window $search_window" + set findstring [.find.entry get] + if {$findstring eq ""} {return} + if {$search_window eq ".pdwindow"} { + set matches [.pdwindow.text search -all -nocase -- $findstring 0.0] + .pdwindow.text tag delete sel + foreach match $matches { + .pdwindow.text tag add sel $match "$match wordend" + } + .pdwindow.text see [lindex $matches 0] } else { - puts "search_window $search_window" - set find_string [.find.entry get] - if {$find_string ne ""} { - pdsend "$search_window find $find_string" + if {$findstring eq $previous_findstring \ + && $wholeword_button == $previous_wholeword_button} { + pdsend "$search_window findagain" + } else { + # TODO switch back to this for 0.43: + #pdsend "$search_window find $findstring $wholeword_button" + pdsend "$search_window find $findstring" + set previous_findstring $findstring + set previous_wholeword_button $wholeword_button } } } -proc find_cancel {mytoplevel} {::dialog_find::cancel $mytoplevel} ;# TODO temp kludge proc ::dialog_find::cancel {mytoplevel} { wm withdraw .find } proc ::dialog_find::set_canvas_to_search {mytoplevel} { + # TODO rewrite using global $::focused_window if {[winfo exists .find.frame.targetlabel]} { set focusedtoplevel [winfo toplevel [lindex [wm stackorder .] end]] if {$focusedtoplevel eq ".find"} { set focusedtoplevel [winfo toplevel [lindex [wm stackorder .] end-1]] } - # TODO this text should be based on $::menu_windowlist - if {$focusedtoplevel eq "."} { - .find.frame.targetlabel configure -text [wm title .] + if {$focusedtoplevel eq ".pdwindow"} { + .find.frame.targetlabel configure -text [wm title .pdwindow] } else { foreach window $::menu_windowlist { if {[lindex $window 1] eq $focusedtoplevel} { @@ -51,26 +71,25 @@ proc ::dialog_find::set_canvas_to_search {mytoplevel} { } # the find panel is opened from the menu and key bindings -proc ::dialog_find::menu_dialog_find {mytoplevel} { +proc ::dialog_find::menu_find_dialog {mytoplevel} { if {[winfo exists .find]} { wm deiconify .find raise .find } else { - create_panel $mytoplevel + create_dialog $mytoplevel } } -proc ::dialog_find::create_panel {mytoplevel} { - toplevel .find +proc ::dialog_find::create_dialog {mytoplevel} { + toplevel .find -class DialogWindow wm title .find [_ "Find"] wm geometry .find =475x125+150+150 - wm resizable .find 0 0 - if {[catch {wm attributes .find -topmost}]} {puts stderr ".find -topmost failed"} .find configure - ::pd_bindings::panel_bindings .find "find" + if {$::windowingsystem eq "aqua"} {$mytoplevel configure -menu .menubar} + ::pd_bindings::dialog_bindings .find "find" frame .find.frame - pack .find.frame -side top -fill x -pady 7 + pack .find.frame -side top -fill x -pady 1 label .find.frame.searchin -text [_ "Search in"] label .find.frame.targetlabel -font "TkTextFont 14" label .find.frame.for -text [_ "for:"] @@ -80,15 +99,19 @@ proc ::dialog_find::create_panel {mytoplevel} { focus .find.entry pack .find.entry -side top -padx 10 + checkbutton .find.wholeword -variable ::dialog_find::wholeword_button \ + -text [_ "Match whole word only"] -anchor w + pack .find.wholeword -side top -padx 30 -pady 3 -fill x + frame .find.buttonframe -background yellow button .find.button -text [_ "Find"] -default active -width 9 \ -command "::dialog_find::ok $mytoplevel" if {$::windowingsystem eq "x11"} { button .find.close -text [_ "Close"] -default normal -width 9 \ -command "::dialog_find::cancel $mytoplevel" - pack .find.buttonframe .find.button .find.close -side right -padx 10 -pady 15 + pack .find.buttonframe .find.button .find.close -side right -padx 10 -pady 3 } else { - pack .find.buttonframe .find.button -side right -padx 10 -pady 15 + pack .find.buttonframe .find.button -side right -padx 10 -pady 3 } ::dialog_find::set_canvas_to_search $mytoplevel } diff --git a/pd/tcl/dialog_font.tcl b/pd/tcl/dialog_font.tcl index cebfcb08..578d155e 100644 --- a/pd/tcl/dialog_font.tcl +++ b/pd/tcl/dialog_font.tcl @@ -2,106 +2,132 @@ package provide dialog_font 0.1 namespace eval ::dialog_font:: { - variable fontsize 0 - variable dofont_fontsize 0 - variable stretchval 0 - variable whichstretch 0 - + variable fontsize 10 + variable stretchval 100 + variable whichstretch 1 + variable canvaswindow + variable sizes {8 10 12 16 24 36} + variable gfxstub + namespace export pdtk_canvas_dofont } +# TODO this should use the pd_font_$size fonts created in pd-gui.tcl + +# TODO this should really be changed on the C side so that it doesn't have to +# work around gfxstub/x_gui.c. The gfxstub stuff assumes that there are +# multiple panels, for properties panels like this, its much easier to use if +# there is a single properties panel that adjusts based on which CanvasWindow +# has focus + proc ::dialog_font::apply {mytoplevel myfontsize} { - pdsend "$mytoplevel font $myfontsize $stretchval $whichstretch" + if {$mytoplevel eq ".pdwindow"} { + .pdwindow.text configure -font "-size $myfontsize" + } else { + variable stretchval + variable whichstretch + pdsend "$mytoplevel font $myfontsize $stretchval $whichstretch" + } +} + +proc ::dialog_font::cancel {mygfxstub} { + if {$mygfxstub ne ".pdwindow"} { + pdsend "$mygfxstub cancel" + } + destroy .font } -proc ::dialog_font::close {mytoplevel} { - pdsend "$mytoplevel cancel" +proc ::dialog_font::ok {mygfxstub} { + variable fontsize + ::dialog_font::apply $mygfxstub $fontsize + ::dialog_font::cancel $mygfxstub } -proc ::dialog_font::cancel {mytoplevel} { - ::dialog_font::apply $mytoplevel $fontsize ;# reinstate previous font size - pdsend "$mytoplevel cancel" +proc ::dialog_font::update_font_dialog {mytoplevel} { + set ::dialog_font::canvaswindow $mytoplevel + if {$mytoplevel eq ".pdwindow"} { + set windowname [_ "Pd window"] + } else { + set windowname [lookup_windowname $mytoplevel] + } + if {[winfo exists .font]} { + wm title .font [format [_ "%s Font"] $windowname] + } } -proc ::dialog_font::ok {mytoplevel} { - set fontsize $::dialog_font::fontsize - ::dialog_font::apply $mytoplevel $fontsize - ::dialog_font::close $mytoplevel +proc ::dialog_font::arrow_fontchange {change} { + variable sizes + set position [expr [lsearch $sizes $::dialog_font::fontsize] + $change] + if {$position < 0} {set position 0} + set max [llength $sizes] + if {$position >= $max} {set position [expr $max-1]} + set ::dialog_font::fontsize [lindex $sizes $position] + ::dialog_font::apply $::dialog_font::canvaswindow $::dialog_font::fontsize } # this should be called pdtk_font_dialog like the rest of the panels, but it # is called from the C side, so we'll leave it be -proc ::dialog_font::pdtk_canvas_dofont {mytoplevel initsize} { - create_panel $mytoplevel $initsize +proc ::dialog_font::pdtk_canvas_dofont {mygfxstub initsize} { + variable fontsize $initsize + variable whichstretch 1 + variable stretchval 100 + if {[winfo exists .font]} { + wm deiconify .font + raise .font + # the gfxstub stuff expects multiple font windows, we only have one, + # so kill the new gfxstub requests as the come in. We'll save the + # original gfxstub for when the font panel gets closed + pdsend "$mygfxstub cancel" + } else { + create_dialog $mygfxstub + } } -proc ::dialog_font::create_panel {mytoplevel initsize} { - set fontsize $initsize - set dofont_fontsize $initsize - set stretchval 100 - set whichstretch 1 +proc ::dialog_font::create_dialog {mygfxstub} { + variable gfxstub $mygfxstub + toplevel .font -class DialogWindow + if {$::windowingsystem eq "aqua"} {.font configure -menu .menubar} + ::pd_bindings::dialog_bindings .font "font" + # replace standard bindings to work around the gfxstub stuff + bind .font <KeyPress-Escape> "::dialog_font::cancel $mygfxstub" + bind .font <KeyPress-Return> "::dialog_font::ok $mygfxstub" + bind .font <$::pd_bindings::modifier-Key-w> "::dialog_font::cancel $mygfxstub" + bind .font <Up> "::dialog_font::arrow_fontchange -1" + bind .font <Down> "::dialog_font::arrow_fontchange 1" - toplevel $mytoplevel - wm title $mytoplevel {Patch Font} - wm protocol $mytoplevel WM_DELETE_WINDOW "::dialog_font::cancel $mytoplevel" - - pdtk_panelkeybindings $mytoplevel font - - frame $mytoplevel.buttonframe - pack $mytoplevel.buttonframe -side bottom -fill x -pady 2m - button $mytoplevel.buttonframe.cancel -text "Cancel" \ - -command "::dialog_font::cancel $mytoplevel" - button $mytoplevel.buttonframe.ok -text "OK" \ - -command "::dialog_font::ok $mytoplevel" - pack $mytoplevel.buttonframe.cancel -side left -expand 1 - pack $mytoplevel.buttonframe.ok -side left -expand 1 + frame .font.buttonframe + pack .font.buttonframe -side bottom -fill x -pady 2m + button .font.buttonframe.ok -text [_ "OK"] \ + -command "::dialog_font::ok $mygfxstub" + pack .font.buttonframe.ok -side left -expand 1 - frame $mytoplevel.radiof - pack $mytoplevel.radiof -side left + labelframe .font.fontsize -text [_ "Font Size"] -padx 5 -pady 4 -borderwidth 1 \ + -width [::msgcat::mcmax "Font Size"] -labelanchor n + pack .font.fontsize -side left -padx 5 - label $mytoplevel.radiof.label -text {Font Size:} - pack $mytoplevel.radiof.label -side top - - radiobutton $mytoplevel.radiof.radio8 -value 8 -variable ::dialog_font::fontsize -text "8" \ - -command "::dialog_font::apply $mytoplevel 8" - radiobutton $mytoplevel.radiof.radio10 -value 10 -variable ::dialog_font::fontsize -text "10" \ - -command "::dialog_font::apply $mytoplevel 10" - radiobutton $mytoplevel.radiof.radio12 -value 12 -variable ::dialog_font::fontsize -text "12" \ - -command "::dialog_font::apply $mytoplevel 12" - radiobutton $mytoplevel.radiof.radio16 -value 16 -variable ::dialog_font::fontsize -text "16" \ - -command "::dialog_font::apply $mytoplevel 16" - radiobutton $mytoplevel.radiof.radio24 -value 24 -variable ::dialog_font::fontsize -text "24" \ - -command "::dialog_font::apply $mytoplevel 24" - radiobutton $mytoplevel.radiof.radio36 -value 36 -variable ::dialog_font::fontsize -text "36" \ - -command "::dialog_font::apply $mytoplevel 36" - pack $mytoplevel.radiof.radio8 -side top -anchor w - pack $mytoplevel.radiof.radio10 -side top -anchor w - pack $mytoplevel.radiof.radio12 -side top -anchor w - pack $mytoplevel.radiof.radio16 -side top -anchor w - pack $mytoplevel.radiof.radio24 -side top -anchor w - pack $mytoplevel.radiof.radio36 -side top -anchor w - - set current_radiobutton [format "$mytoplevel.radiof.radio%d" $initsize] - $current_radiobutton select + # this is whacky Tcl at its finest, but I couldn't resist... + foreach size $::dialog_font::sizes { + radiobutton .font.fontsize.radio$size -value $size -text $size \ + -variable ::dialog_font::fontsize \ + -command [format {::dialog_font::apply $::dialog_font::canvaswindow %s} $size] + pack .font.fontsize.radio$size -side top -anchor w + } - frame $mytoplevel.stretchf - pack $mytoplevel.stretchf -side left - - label $mytoplevel.stretchf.label -text "Stretch:" - pack $mytoplevel.stretchf.label -side top - - entry $mytoplevel.stretchf.entry -textvariable stretchval -width 5 - pack $mytoplevel.stretchf.entry -side left + labelframe .font.stretch -text [_ "Stretch"] -padx 5 -pady 5 -borderwidth 1 \ + -width [::msgcat::mcmax "Stretch"] -labelanchor n + pack .font.stretch -side left -padx 5 -fill y - radiobutton $mytoplevel.stretchf.radio1 \ - -value 1 -variable whichstretch -text "X and Y" - radiobutton $mytoplevel.stretchf.radio2 \ - -value 2 -variable whichstretch -text "X only" - radiobutton $mytoplevel.stretchf.radio3 \ - -value 3 -variable whichstretch -text "Y only" + entry .font.stretch.entry -textvariable ::dialog_font::stretchval -width 5 + pack .font.stretch.entry -side top -pady 5 - pack $mytoplevel.stretchf.radio1 -side top -anchor w - pack $mytoplevel.stretchf.radio2 -side top -anchor w - pack $mytoplevel.stretchf.radio3 -side top -anchor w + radiobutton .font.stretch.radio1 -text [_ "X and Y"] \ + -value 1 -variable ::dialog_font::whichstretch + radiobutton .font.stretch.radio2 -text [_ "X only"] \ + -value 2 -variable ::dialog_font::whichstretch + radiobutton .font.stretch.radio3 -text [_ "Y only"] \ + -value 3 -variable ::dialog_font::whichstretch + pack .font.stretch.radio1 -side top -anchor w + pack .font.stretch.radio2 -side top -anchor w + pack .font.stretch.radio3 -side top -anchor w } diff --git a/pd/tcl/dialog_gatom.tcl b/pd/tcl/dialog_gatom.tcl index e377657f..b59751bf 100644 --- a/pd/tcl/dialog_gatom.tcl +++ b/pd/tcl/dialog_gatom.tcl @@ -4,24 +4,15 @@ package provide dialog_gatom 0.1 package require wheredoesthisgo namespace eval ::dialog_gatom:: { - namespace export pdtk_gatom_dialog + namespace export pdtk_gatom_dialog } -# hashtable for communicating the position of the radiobuttons (Tk's +# array for communicating the position of the radiobuttons (Tk's # radiobutton widget requires this to be global) -global gatomlabel_position +array set gatomlabel_radio {} ############ pdtk_gatom_dialog -- run a gatom dialog ######### -# dialogs like this one can come up in many copies; but in TK the easiest -# way to get data from an "entry", etc., is to set an associated variable -# name. This is especially true for grouped "radio buttons". So we have -# to synthesize variable names for each instance of the dialog. The dialog -# gets a TK pathname $id, from which it strips the leading "." to make a -# variable suffix $vid. Then you can get the actual value out by asking for -# [eval concat $$variablename]. There should be an easier way but I don't see -# it yet. - proc ::dialog_gatom::escape {sym} { if {[string length $sym] == 0} { set ret "-" @@ -44,164 +35,128 @@ proc ::dialog_gatom::unescape {sym} { return $ret } -proc gatom_apply {mytoplevel} { - # TODO kludge!! until a common approach to ::pd_bindings::panel_bindings - # is sorted out - ::dialog_gatom::apply $mytoplevel -} - proc ::dialog_gatom::apply {mytoplevel} { - global gatomlabel_position - + global gatomlabel_radio + pdsend "$mytoplevel param \ [$mytoplevel.width.entry get] \ [$mytoplevel.limits.lower.entry get] \ [$mytoplevel.limits.upper.entry get] \ [::dialog_gatom::escape [$mytoplevel.gatomlabel.name.entry get]] \ - $gatomlabel_position($mytoplevel) \ + $gatomlabel_radio($mytoplevel) \ [::dialog_gatom::escape [$mytoplevel.s_r.send.entry get]] \ [::dialog_gatom::escape [$mytoplevel.s_r.receive.entry get]]" } - -proc gatom_cancel {mytoplevel} { - # TODO kludge!! until a common approach to ::pd_bindings::panel_bindings - # is sorted out - ::dialog_gatom::cancel $mytoplevel -} - proc ::dialog_gatom::cancel {mytoplevel} { pdsend "$mytoplevel cancel" } - -proc gatom_ok {mytoplevel} { - # TODO kludge!! until a common approach to ::pd_bindings::panel_bindings - # is sorted out - ::dialog_gatom::ok $mytoplevel -} proc ::dialog_gatom::ok {mytoplevel} { ::dialog_gatom::apply $mytoplevel ::dialog_gatom::cancel $mytoplevel } # set up the panel with the info from pd -proc ::dialog_gatom::pdtk_gatom_dialog {mytoplevel initwidth initlower \ - initupper initgatomlabel_position initgatomlabel initsend initreceive} { - global gatomlabel_position - set gatomlabel_position($mytoplevel) $initgatomlabel_position +proc ::dialog_gatom::pdtk_gatom_dialog {mytoplevel initwidth initlower initupper \ + initgatomlabel_radio \ + initgatomlabel initsend initreceive} { + global gatomlabel_radio + set gatomlabel_radio($mytoplevel) $initgatomlabel_radio if {[winfo exists $mytoplevel]} { - wm deiconify $mytoplevel - raise $mytoplevel + wm deiconify $mytoplevel + raise $mytoplevel } else { - create_panel $mytoplevel + create_dialog $mytoplevel } $mytoplevel.width.entry insert 0 $initwidth $mytoplevel.limits.lower.entry insert 0 $initlower $mytoplevel.limits.upper.entry insert 0 $initupper if {$initgatomlabel ne "-"} { - $mytoplevel.gatomlabel.name.entry insert 0 $initgatomlabel + $mytoplevel.gatomlabel.name.entry insert 0 $initgatomlabel } - set gatomlabel_position($mytoplevel) $initgatomlabel_position - if {$initsend ne "-"} { - $mytoplevel.s_r.send.entry insert 0 $initsend + set gatomlabel_radio($mytoplevel) $initgatomlabel_radio + if {$initsend ne "-"} { + $mytoplevel.s_r.send.entry insert 0 $initsend } if {$initreceive ne "-"} { - $mytoplevel.s_r.receive.entry insert 0 $initreceive + $mytoplevel.s_r.receive.entry insert 0 $initreceive } } -proc ::dialog_gatom::create_panel {mytoplevel} { - global gatomlabel_position +proc ::dialog_gatom::create_dialog {mytoplevel} { + global gatomlabel_radio - toplevel $mytoplevel - wm title $mytoplevel "atom box properties" - wm resizable $mytoplevel 0 0 - catch { # not all platforms/Tcls versions have these options - wm attributes $mytoplevel -topmost 1 - #wm attributes $mytoplevel -transparent 1 - #$mytoplevel configure -highlightthickness 1 - } - wm protocol $mytoplevel WM_DELETE_WINDOW "::dialog_gatom::cancel $mytoplevel" - - ::pd_bindings::panel_bindings $mytoplevel "gatom" + toplevel $mytoplevel -class DialogWindow + wm title $mytoplevel [_ "Atom Box Properties"] + if {$::windowingsystem eq "aqua"} {$mytoplevel configure -menu .menubar} + ::pd_bindings::dialog_bindings $mytoplevel "gatom" frame $mytoplevel.width -height 7 pack $mytoplevel.width -side top - label $mytoplevel.width.label -text "width" + label $mytoplevel.width.label -text [_ "Width:"] entry $mytoplevel.width.entry -width 4 - pack $mytoplevel.width.label $mytoplevel.width.entry -side left + pack $mytoplevel.width.label $mytoplevel.width.entry -side left - labelframe $mytoplevel.limits -text "limits" -padx 15 -pady 4 -borderwidth 1 \ - -font highlight_font + labelframe $mytoplevel.limits -text [_ "Limits"] -padx 15 -pady 4 -borderwidth 1 pack $mytoplevel.limits -side top -fill x frame $mytoplevel.limits.lower pack $mytoplevel.limits.lower -side left - label $mytoplevel.limits.lower.label -text "lower" - entry $mytoplevel.limits.lower.entry -width 8 + label $mytoplevel.limits.lower.label -text [_ "Lower:"] + entry $mytoplevel.limits.lower.entry -width 7 pack $mytoplevel.limits.lower.label $mytoplevel.limits.lower.entry -side left frame $mytoplevel.limits.upper pack $mytoplevel.limits.upper -side left - frame $mytoplevel.limits.upper.spacer -width 20 - label $mytoplevel.limits.upper.label -text "upper" - entry $mytoplevel.limits.upper.entry -width 8 - pack $mytoplevel.limits.upper.spacer $mytoplevel.limits.upper.label \ - $mytoplevel.limits.upper.entry -side left - - frame $mytoplevel.spacer1 -height 7 - pack $mytoplevel.spacer1 -side top - - labelframe $mytoplevel.gatomlabel -text "label" -padx 5 -pady 4 -borderwidth 1 \ - -font highlight_font - pack $mytoplevel.gatomlabel -side top -fill x + label $mytoplevel.limits.upper.label -text [_ "Upper:"] + entry $mytoplevel.limits.upper.entry -width 7 + pack $mytoplevel.limits.upper.label $mytoplevel.limits.upper.entry -side left + + labelframe $mytoplevel.gatomlabel -text [_ "Label"] -padx 5 -pady 5 -borderwidth 1 + pack $mytoplevel.gatomlabel -side top -fill x -pady 5 frame $mytoplevel.gatomlabel.name pack $mytoplevel.gatomlabel.name -side top entry $mytoplevel.gatomlabel.name.entry -width 33 pack $mytoplevel.gatomlabel.name.entry -side left frame $mytoplevel.gatomlabel.radio pack $mytoplevel.gatomlabel.radio -side top - radiobutton $mytoplevel.gatomlabel.radio.left -value 0 -text "left " \ - -variable gatomlabel_position($mytoplevel) -justify left -takefocus 0 - radiobutton $mytoplevel.gatomlabel.radio.right -value 1 -text "right" \ - -variable gatomlabel_position($mytoplevel) -justify left -takefocus 0 - radiobutton $mytoplevel.gatomlabel.radio.top -value 2 -text "top" \ - -variable gatomlabel_position($mytoplevel) -justify left -takefocus 0 - radiobutton $mytoplevel.gatomlabel.radio.bottom -value 3 -text "bottom" \ - -variable gatomlabel_position($mytoplevel) -justify left -takefocus 0 + radiobutton $mytoplevel.gatomlabel.radio.left -value 0 -text [_ "Left "] \ + -variable gatomlabel_radio($mytoplevel) -justify left -takefocus 0 + radiobutton $mytoplevel.gatomlabel.radio.right -value 1 -text [_ "Right"] \ + -variable gatomlabel_radio($mytoplevel) -justify left -takefocus 0 + radiobutton $mytoplevel.gatomlabel.radio.top -value 2 -text [_ "Top"] \ + -variable gatomlabel_radio($mytoplevel) -justify left -takefocus 0 + radiobutton $mytoplevel.gatomlabel.radio.bottom -value 3 -text [_ "Bottom"] \ + -variable gatomlabel_radio($mytoplevel) -justify left -takefocus 0 pack $mytoplevel.gatomlabel.radio.left -side left -anchor w pack $mytoplevel.gatomlabel.radio.right -side right -anchor w pack $mytoplevel.gatomlabel.radio.top -side top -anchor w pack $mytoplevel.gatomlabel.radio.bottom -side bottom -anchor w - frame $mytoplevel.spacer2 -height 7 - pack $mytoplevel.spacer2 -side top - - labelframe $mytoplevel.s_r -text "messages" -padx 5 -pady 4 -borderwidth 1 \ - -font highlight_font + labelframe $mytoplevel.s_r -text [_ "Messages"] -padx 5 -pady 5 -borderwidth 1 pack $mytoplevel.s_r -side top -fill x frame $mytoplevel.s_r.send pack $mytoplevel.s_r.send -side top -anchor e - label $mytoplevel.s_r.send.label -text "send symbol" + label $mytoplevel.s_r.send.label -text [_ "Send symbol:"] entry $mytoplevel.s_r.send.entry -width 21 pack $mytoplevel.s_r.send.entry $mytoplevel.s_r.send.label -side right frame $mytoplevel.s_r.receive pack $mytoplevel.s_r.receive -side top -anchor e - label $mytoplevel.s_r.receive.label -text "receive symbol" + label $mytoplevel.s_r.receive.label -text [_ "Receive symbol:"] entry $mytoplevel.s_r.receive.entry -width 21 pack $mytoplevel.s_r.receive.entry $mytoplevel.s_r.receive.label -side right frame $mytoplevel.buttonframe -pady 5 pack $mytoplevel.buttonframe -side top -fill x -pady 2m - button $mytoplevel.buttonframe.cancel -text {Cancel} \ + button $mytoplevel.buttonframe.cancel -text [_ "Cancel"] \ -command "::dialog_gatom::cancel $mytoplevel" pack $mytoplevel.buttonframe.cancel -side left -expand 1 - button $mytoplevel.buttonframe.apply -text {Apply} \ + button $mytoplevel.buttonframe.apply -text [_ "Apply"] \ -command "::dialog_gatom::apply $mytoplevel" pack $mytoplevel.buttonframe.apply -side left -expand 1 - button $mytoplevel.buttonframe.ok -text {OK} \ + button $mytoplevel.buttonframe.ok -text [_ "OK"] \ -command "::dialog_gatom::ok $mytoplevel" pack $mytoplevel.buttonframe.ok -side left -expand 1 diff --git a/pd/tcl/dialog_iemgui.tcl b/pd/tcl/dialog_iemgui.tcl index 5aabf4c2..34ed4ccb 100644 --- a/pd/tcl/dialog_iemgui.tcl +++ b/pd/tcl/dialog_iemgui.tcl @@ -8,15 +8,15 @@ namespace eval ::dialog_iemgui:: { variable define_min_flashhold 50 variable define_min_flashbreak 10 variable define_min_fontsize 4 - + namespace export pdtk_iemgui_dialog } -# TODO rename $mytoplevel to $mytoplevel +# TODO convert Init/No Init and Steady on click/Jump on click to checkbuttons proc ::dialog_iemgui::clip_dim {mytoplevel} { set vid [string trimleft $mytoplevel .] - + set var_iemgui_wdt [concat iemgui_wdt_$vid] global $var_iemgui_wdt set var_iemgui_min_wdt [concat iemgui_min_wdt_$vid] @@ -38,7 +38,7 @@ proc ::dialog_iemgui::clip_dim {mytoplevel} { proc ::dialog_iemgui::clip_num {mytoplevel} { set vid [string trimleft $mytoplevel .] - + set var_iemgui_num [concat iemgui_num_$vid] global $var_iemgui_num @@ -54,14 +54,14 @@ proc ::dialog_iemgui::clip_num {mytoplevel} { proc ::dialog_iemgui::sched_rng {mytoplevel} { set vid [string trimleft $mytoplevel .] - + set var_iemgui_min_rng [concat iemgui_min_rng_$vid] global $var_iemgui_min_rng set var_iemgui_max_rng [concat iemgui_max_rng_$vid] global $var_iemgui_max_rng set var_iemgui_rng_sch [concat iemgui_rng_sch_$vid] global $var_iemgui_rng_sch - + variable define_min_flashhold variable define_min_flashbreak @@ -91,7 +91,7 @@ proc ::dialog_iemgui::sched_rng {mytoplevel} { proc ::dialog_iemgui::verify_rng {mytoplevel} { set vid [string trimleft $mytoplevel .] - + set var_iemgui_min_rng [concat iemgui_min_rng_$vid] global $var_iemgui_min_rng set var_iemgui_max_rng [concat iemgui_max_rng_$vid] @@ -103,7 +103,7 @@ proc ::dialog_iemgui::verify_rng {mytoplevel} { if {[eval concat $$var_iemgui_max_rng] == 0.0 && [eval concat $$var_iemgui_min_rng] == 0.0} { set $var_iemgui_max_rng 1.0 $mytoplevel.rng.max_ent configure -textvariable $var_iemgui_max_rng - } + } if {[eval concat $$var_iemgui_max_rng] > 0} { if {[eval concat $$var_iemgui_min_rng] <= 0} { set $var_iemgui_min_rng [expr [eval concat $$var_iemgui_max_rng] * 0.01] @@ -120,12 +120,12 @@ proc ::dialog_iemgui::verify_rng {mytoplevel} { proc ::dialog_iemgui::clip_fontsize {mytoplevel} { set vid [string trimleft $mytoplevel .] - + set var_iemgui_gn_fs [concat iemgui_gn_fs_$vid] global $var_iemgui_gn_fs variable define_min_fontsize - + if {[eval concat $$var_iemgui_gn_fs] < $define_min_fontsize} { set $var_iemgui_gn_fs $define_min_fontsize $mytoplevel.label.fs_ent configure -textvariable $var_iemgui_gn_fs @@ -134,7 +134,7 @@ proc ::dialog_iemgui::clip_fontsize {mytoplevel} { proc ::dialog_iemgui::set_col_example {mytoplevel} { set vid [string trimleft $mytoplevel .] - + set var_iemgui_bcol [concat iemgui_bcol_$vid] global $var_iemgui_bcol set var_iemgui_fcol [concat iemgui_fcol_$vid] @@ -143,28 +143,28 @@ proc ::dialog_iemgui::set_col_example {mytoplevel} { global $var_iemgui_lcol $mytoplevel.colors.sections.lb_bk configure \ - -background [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ - -activebackground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ - -foreground [format "#%6.6x" [eval concat $$var_iemgui_lcol]] \ - -activeforeground [format "#%6.6x" [eval concat $$var_iemgui_lcol]] + -background [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ + -activebackground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ + -foreground [format "#%6.6x" [eval concat $$var_iemgui_lcol]] \ + -activeforeground [format "#%6.6x" [eval concat $$var_iemgui_lcol]] if { [eval concat $$var_iemgui_fcol] >= 0 } { - $mytoplevel.colors.sections.fr_bk configure \ - -background [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ - -activebackground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ - -foreground [format "#%6.6x" [eval concat $$var_iemgui_fcol]] \ - -activeforeground [format "#%6.6x" [eval concat $$var_iemgui_fcol]] + $mytoplevel.colors.sections.fr_bk configure \ + -background [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ + -activebackground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ + -foreground [format "#%6.6x" [eval concat $$var_iemgui_fcol]] \ + -activeforeground [format "#%6.6x" [eval concat $$var_iemgui_fcol]] } else { - $mytoplevel.colors.sections.fr_bk configure \ - -background [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ - -activebackground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ - -foreground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ - -activeforeground [format "#%6.6x" [eval concat $$var_iemgui_bcol]]} + $mytoplevel.colors.sections.fr_bk configure \ + -background [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ + -activebackground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ + -foreground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ + -activeforeground [format "#%6.6x" [eval concat $$var_iemgui_bcol]]} } proc ::dialog_iemgui::preset_col {mytoplevel presetcol} { set vid [string trimleft $mytoplevel .] - + set var_iemgui_l2_f1_b0 [concat iemgui_l2_f1_b0_$vid] global $var_iemgui_l2_f1_b0 set var_iemgui_bcol [concat iemgui_bcol_$vid] @@ -182,7 +182,7 @@ proc ::dialog_iemgui::preset_col {mytoplevel presetcol} { proc ::dialog_iemgui::choose_col_bkfrlb {mytoplevel} { set vid [string trimleft $mytoplevel .] - + set var_iemgui_l2_f1_b0 [concat iemgui_l2_f1_b0_$vid] global $var_iemgui_l2_f1_b0 set var_iemgui_bcol [concat iemgui_bcol_$vid] @@ -195,39 +195,39 @@ proc ::dialog_iemgui::choose_col_bkfrlb {mytoplevel} { if {[eval concat $$var_iemgui_l2_f1_b0] == 0} { set $var_iemgui_bcol [expr [eval concat $$var_iemgui_bcol] & 0xFCFCFC] set helpstring [tk_chooseColor -title [_ "Background color"] -initialcolor [format "#%6.6x" [eval concat $$var_iemgui_bcol]]] - if { $helpstring != "" } { - set $var_iemgui_bcol [string replace $helpstring 0 0 "0x"] - set $var_iemgui_bcol [expr [eval concat $$var_iemgui_bcol] & 0xFCFCFC] } + if { $helpstring ne "" } { + set $var_iemgui_bcol [string replace $helpstring 0 0 "0x"] + set $var_iemgui_bcol [expr [eval concat $$var_iemgui_bcol] & 0xFCFCFC] } } if {[eval concat $$var_iemgui_l2_f1_b0] == 1} { set $var_iemgui_fcol [expr [eval concat $$var_iemgui_fcol] & 0xFCFCFC] set helpstring [tk_chooseColor -title [_ "Foreground color"] -initialcolor [format "#%6.6x" [eval concat $$var_iemgui_fcol]]] - if { $helpstring != "" } { - set $var_iemgui_fcol [string replace $helpstring 0 0 "0x"] - set $var_iemgui_fcol [expr [eval concat $$var_iemgui_fcol] & 0xFCFCFC] } + if { $helpstring ne "" } { + set $var_iemgui_fcol [string replace $helpstring 0 0 "0x"] + set $var_iemgui_fcol [expr [eval concat $$var_iemgui_fcol] & 0xFCFCFC] } } if {[eval concat $$var_iemgui_l2_f1_b0] == 2} { set $var_iemgui_lcol [expr [eval concat $$var_iemgui_lcol] & 0xFCFCFC] set helpstring [tk_chooseColor -title [_ "Label color"] -initialcolor [format "#%6.6x" [eval concat $$var_iemgui_lcol]]] - if { $helpstring != "" } { - set $var_iemgui_lcol [string replace $helpstring 0 0 "0x"] - set $var_iemgui_lcol [expr [eval concat $$var_iemgui_lcol] & 0xFCFCFC] } + if { $helpstring ne "" } { + set $var_iemgui_lcol [string replace $helpstring 0 0 "0x"] + set $var_iemgui_lcol [expr [eval concat $$var_iemgui_lcol] & 0xFCFCFC] } } ::dialog_iemgui::set_col_example $mytoplevel } proc ::dialog_iemgui::lilo {mytoplevel} { set vid [string trimleft $mytoplevel .] - + set var_iemgui_lin0_log1 [concat iemgui_lin0_log1_$vid] global $var_iemgui_lin0_log1 set var_iemgui_lilo0 [concat iemgui_lilo0_$vid] global $var_iemgui_lilo0 set var_iemgui_lilo1 [concat iemgui_lilo1_$vid] global $var_iemgui_lilo1 - + ::dialog_iemgui::sched_rng $mytoplevel - + if {[eval concat $$var_iemgui_lin0_log1] == 0} { set $var_iemgui_lin0_log1 1 $mytoplevel.para.lilo configure -text [eval concat $$var_iemgui_lilo1] @@ -241,21 +241,21 @@ proc ::dialog_iemgui::lilo {mytoplevel} { proc ::dialog_iemgui::toggle_font {mytoplevel gn_f} { set vid [string trimleft $mytoplevel .] - + set var_iemgui_gn_f [concat iemgui_gn_f_$vid] global $var_iemgui_gn_f set $var_iemgui_gn_f $gn_f - + switch -- $gn_f { - 0 { set current_font $::font_family} - 1 { set current_font "Helvetica" } - 2 { set current_font "Times" } + 0 { set current_font $::font_family} + 1 { set current_font "Helvetica" } + 2 { set current_font "Times" } } set current_font_spec "{$current_font} 12 $::font_weight" - + $mytoplevel.label.fontpopup_label configure -text $current_font \ - -font $current_font_spec + -font $current_font_spec $mytoplevel.label.name_entry configure -font $current_font_spec $mytoplevel.colors.sections.fr_bk configure -font $current_font_spec $mytoplevel.colors.sections.lb_bk configure -font $current_font_spec @@ -263,37 +263,37 @@ proc ::dialog_iemgui::toggle_font {mytoplevel gn_f} { proc ::dialog_iemgui::lb {mytoplevel} { set vid [string trimleft $mytoplevel .] - + set var_iemgui_loadbang [concat iemgui_loadbang_$vid] global $var_iemgui_loadbang - + if {[eval concat $$var_iemgui_loadbang] == 0} { set $var_iemgui_loadbang 1 - $mytoplevel.para.lb configure -text "init" + $mytoplevel.para.lb configure -text [_ "Init"] } else { set $var_iemgui_loadbang 0 - $mytoplevel.para.lb configure -text "no init" + $mytoplevel.para.lb configure -text [_ "No init"] } } proc ::dialog_iemgui::stdy_jmp {mytoplevel} { set vid [string trimleft $mytoplevel .] - + set var_iemgui_steady [concat iemgui_steady_$vid] global $var_iemgui_steady if {[eval concat $$var_iemgui_steady]} { set $var_iemgui_steady 0 - $mytoplevel.para.stdy_jmp configure -text "jump on click" + $mytoplevel.para.stdy_jmp configure -text [_ "Jump on click"] } else { set $var_iemgui_steady 1 - $mytoplevel.para.stdy_jmp configure -text "steady on click" + $mytoplevel.para.stdy_jmp configure -text [_ "Steady on click"] } } proc ::dialog_iemgui::apply {mytoplevel} { set vid [string trimleft $mytoplevel .] - + set var_iemgui_wdt [concat iemgui_wdt_$vid] global $var_iemgui_wdt set var_iemgui_min_wdt [concat iemgui_min_wdt_$vid] @@ -349,75 +349,65 @@ proc ::dialog_iemgui::apply {mytoplevel} { if {[eval concat $$var_iemgui_snd] == ""} {set hhhsnd "empty"} else {set hhhsnd [eval concat $$var_iemgui_snd]} if {[eval concat $$var_iemgui_rcv] == ""} {set hhhrcv "empty"} else {set hhhrcv [eval concat $$var_iemgui_rcv]} if {[eval concat $$var_iemgui_gui_nam] == ""} {set hhhgui_nam "empty" - } else { - set hhhgui_nam [eval concat $$var_iemgui_gui_nam]} - + } else { + set hhhgui_nam [eval concat $$var_iemgui_gui_nam]} + if {[string index $hhhsnd 0] == "$"} { - set hhhsnd [string replace $hhhsnd 0 0 #] } + set hhhsnd [string replace $hhhsnd 0 0 #] } if {[string index $hhhrcv 0] == "$"} { - set hhhrcv [string replace $hhhrcv 0 0 #] } + set hhhrcv [string replace $hhhrcv 0 0 #] } if {[string index $hhhgui_nam 0] == "$"} { - set hhhgui_nam [string replace $hhhgui_nam 0 0 #] } + set hhhgui_nam [string replace $hhhgui_nam 0 0 #] } set hhhsnd [unspace_text $hhhsnd] set hhhrcv [unspace_text $hhhrcv] set hhhgui_nam [unspace_text $hhhgui_nam] pdsend [concat $mytoplevel dialog \ - [eval concat $$var_iemgui_wdt] \ - [eval concat $$var_iemgui_hgt] \ - [eval concat $$var_iemgui_min_rng] \ - [eval concat $$var_iemgui_max_rng] \ - [eval concat $$var_iemgui_lin0_log1] \ - [eval concat $$var_iemgui_loadbang] \ - [eval concat $$var_iemgui_num] \ - $hhhsnd \ - $hhhrcv \ - $hhhgui_nam \ - [eval concat $$var_iemgui_gn_dx] \ - [eval concat $$var_iemgui_gn_dy] \ - [eval concat $$var_iemgui_gn_f] \ - [eval concat $$var_iemgui_gn_fs] \ - [eval concat $$var_iemgui_bcol] \ - [eval concat $$var_iemgui_fcol] \ - [eval concat $$var_iemgui_lcol] \ - [eval concat $$var_iemgui_steady]] + [eval concat $$var_iemgui_wdt] \ + [eval concat $$var_iemgui_hgt] \ + [eval concat $$var_iemgui_min_rng] \ + [eval concat $$var_iemgui_max_rng] \ + [eval concat $$var_iemgui_lin0_log1] \ + [eval concat $$var_iemgui_loadbang] \ + [eval concat $$var_iemgui_num] \ + $hhhsnd \ + $hhhrcv \ + $hhhgui_nam \ + [eval concat $$var_iemgui_gn_dx] \ + [eval concat $$var_iemgui_gn_dy] \ + [eval concat $$var_iemgui_gn_f] \ + [eval concat $$var_iemgui_gn_fs] \ + [eval concat $$var_iemgui_bcol] \ + [eval concat $$var_iemgui_fcol] \ + [eval concat $$var_iemgui_lcol] \ + [eval concat $$var_iemgui_steady]] } -proc iemgui_cancel {mytoplevel} { - # TODO kludge!! until a common approach to ::pd_bindings::panel_bindings - # is sorted out - ::dialog_iemgui::cancel $mytoplevel -} proc ::dialog_iemgui::cancel {mytoplevel} { pdsend "$mytoplevel cancel" } -proc iemgui_ok {mytoplevel} { - # TODO kludge!! until a common approach to ::pd_bindings::panel_bindings - # is sorted out - ::dialog_iemgui::ok $mytoplevel -} proc ::dialog_iemgui::ok {mytoplevel} { ::dialog_iemgui::apply $mytoplevel ::dialog_iemgui::cancel $mytoplevel } proc ::dialog_iemgui::pdtk_iemgui_dialog {mytoplevel mainheader dim_header \ - wdt min_wdt wdt_label \ - hgt min_hgt hgt_label \ - rng_header min_rng min_rng_label max_rng \ - max_rng_label rng_sched \ - lin0_log1 lilo0_label lilo1_label \ - loadbang steady num_label num \ - snd rcv \ - gui_name \ - gn_dx gn_dy gn_f gn_fs \ - bcol fcol lcol} { - + wdt min_wdt wdt_label \ + hgt min_hgt hgt_label \ + rng_header min_rng min_rng_label max_rng \ + max_rng_label rng_sched \ + lin0_log1 lilo0_label lilo1_label \ + loadbang steady num_label num \ + snd rcv \ + gui_name \ + gn_dx gn_dy gn_f gn_fs \ + bcol fcol lcol} { + set vid [string trimleft $mytoplevel .] - + set var_iemgui_wdt [concat iemgui_wdt_$vid] global $var_iemgui_wdt set var_iemgui_min_wdt [concat iemgui_min_wdt_$vid] @@ -466,7 +456,7 @@ proc ::dialog_iemgui::pdtk_iemgui_dialog {mytoplevel mainheader dim_header \ global $var_iemgui_fcol set var_iemgui_lcol [concat iemgui_lcol_$vid] global $var_iemgui_lcol - + set $var_iemgui_wdt $wdt set $var_iemgui_min_wdt $min_wdt set $var_iemgui_hgt $hgt @@ -481,18 +471,18 @@ proc ::dialog_iemgui::pdtk_iemgui_dialog {mytoplevel mainheader dim_header \ set $var_iemgui_num $num set $var_iemgui_steady $steady if {$snd == "empty"} {set $var_iemgui_snd [format ""] - } else {set $var_iemgui_snd [format "%s" $snd]} + } else {set $var_iemgui_snd [format "%s" $snd]} if {$rcv == "empty"} {set $var_iemgui_rcv [format ""] - } else {set $var_iemgui_rcv [format "%s" $rcv]} + } else {set $var_iemgui_rcv [format "%s" $rcv]} if {$gui_name == "empty"} {set $var_iemgui_gui_nam [format ""] - } else {set $var_iemgui_gui_nam [format "%s" $gui_name]} + } else {set $var_iemgui_gui_nam [format "%s" $gui_name]} if {[string index [eval concat $$var_iemgui_snd] 0] == "#"} { - set $var_iemgui_snd [string replace [eval concat $$var_iemgui_snd] 0 0 $] } + set $var_iemgui_snd [string replace [eval concat $$var_iemgui_snd] 0 0 $] } if {[string index [eval concat $$var_iemgui_rcv] 0] == "#"} { - set $var_iemgui_rcv [string replace [eval concat $$var_iemgui_rcv] 0 0 $] } + set $var_iemgui_rcv [string replace [eval concat $$var_iemgui_rcv] 0 0 $] } if {[string index [eval concat $$var_iemgui_gui_nam] 0] == "#"} { - set $var_iemgui_gui_nam [string replace [eval concat $$var_iemgui_gui_nam] 0 0 $] } + set $var_iemgui_gui_nam [string replace [eval concat $$var_iemgui_gui_nam] 0 0 $] } set $var_iemgui_gn_dx $gn_dx set $var_iemgui_gn_dy $gn_dy set $var_iemgui_gn_f $gn_f @@ -503,13 +493,11 @@ proc ::dialog_iemgui::pdtk_iemgui_dialog {mytoplevel mainheader dim_header \ set $var_iemgui_lcol $lcol set $var_iemgui_l2_f1_b0 0 - - toplevel $mytoplevel + + toplevel $mytoplevel -class DialogWindow wm title $mytoplevel [format [_ "%s Properties"] $mainheader] - wm resizable $mytoplevel 0 0 - wm protocol $mytoplevel WM_DELETE_WINDOW [concat ::dialog_iemgui::cancel $mytoplevel] - - ::pd_bindings::panel_bindings $mytoplevel "iemgui" + if {$::windowingsystem eq "aqua"} {$mytoplevel configure -menu .menubar} + ::pd_bindings::dialog_bindings $mytoplevel "iemgui" frame $mytoplevel.dim pack $mytoplevel.dim -side top @@ -521,9 +509,9 @@ proc ::dialog_iemgui::pdtk_iemgui_dialog {mytoplevel mainheader dim_header \ entry $mytoplevel.dim.h_ent -textvariable $var_iemgui_hgt -width 5 pack $mytoplevel.dim.head -side top pack $mytoplevel.dim.w_lab $mytoplevel.dim.w_ent $mytoplevel.dim.dummy1 -side left - if { $hgt_label != "empty" } { + if { $hgt_label ne "empty" } { pack $mytoplevel.dim.h_lab $mytoplevel.dim.h_ent -side left} - + frame $mytoplevel.rng pack $mytoplevel.rng -side top label $mytoplevel.rng.head -text $rng_header @@ -532,45 +520,45 @@ proc ::dialog_iemgui::pdtk_iemgui_dialog {mytoplevel mainheader dim_header \ label $mytoplevel.rng.dummy1 -text " " -width 1 label $mytoplevel.rng.max_lab -text [_ $max_rng_label] -width 8 entry $mytoplevel.rng.max_ent -textvariable $var_iemgui_max_rng -width 9 - if { $rng_header != "empty" } { + if { $rng_header ne "empty" } { pack $mytoplevel.rng.head -side top - if { $min_rng_label != "empty" } { + if { $min_rng_label ne "empty" } { pack $mytoplevel.rng.min_lab $mytoplevel.rng.min_ent -side left} - if { $max_rng_label != "empty" } { + if { $max_rng_label ne "empty" } { pack $mytoplevel.rng.dummy1 \ - $mytoplevel.rng.max_lab $mytoplevel.rng.max_ent -side left} } + $mytoplevel.rng.max_lab $mytoplevel.rng.max_ent -side left} } if { [eval concat $$var_iemgui_lin0_log1] >= 0 || [eval concat $$var_iemgui_loadbang] >= 0 || [eval concat $$var_iemgui_num] > 0 || [eval concat $$var_iemgui_steady] >= 0 } { label $mytoplevel.space1 -text "" pack $mytoplevel.space1 -side top } - + frame $mytoplevel.para pack $mytoplevel.para -side top label $mytoplevel.para.dummy2 -text "" -width 1 label $mytoplevel.para.dummy3 -text "" -width 1 if {[eval concat $$var_iemgui_lin0_log1] == 0} { button $mytoplevel.para.lilo -text [_ [eval concat $$var_iemgui_lilo0]] -width 5 \ - -command "::dialog_iemgui::lilo $mytoplevel" } + -command "::dialog_iemgui::lilo $mytoplevel" } if {[eval concat $$var_iemgui_lin0_log1] == 1} { button $mytoplevel.para.lilo -text [_ [eval concat $$var_iemgui_lilo1]] -width 5 \ - -command "::dialog_iemgui::lilo $mytoplevel" } + -command "::dialog_iemgui::lilo $mytoplevel" } if {[eval concat $$var_iemgui_loadbang] == 0} { - button $mytoplevel.para.lb -text [_ "no init"] \ - -width [::msgcat::mcmax "no init"] \ - -command "::dialog_iemgui::lb $mytoplevel" } + button $mytoplevel.para.lb -text [_ "No init"] \ + -width [::msgcat::mcmax "No init"] \ + -command "::dialog_iemgui::lb $mytoplevel" } if {[eval concat $$var_iemgui_loadbang] == 1} { button $mytoplevel.para.lb -text [_ "Save"] \ - -width [::msgcat::mcmax "Save"] \ - -command "::dialog_iemgui::lb $mytoplevel" } + -width [::msgcat::mcmax "Save"] \ + -command "::dialog_iemgui::lb $mytoplevel" } label $mytoplevel.para.num_lab -text [_ $num_label] -width 9 entry $mytoplevel.para.num_ent -textvariable $var_iemgui_num -width 4 if {[eval concat $$var_iemgui_steady] == 0} { button $mytoplevel.para.stdy_jmp -command "::dialog_iemgui::stdy_jmp $mytoplevel" \ - -text [_ "jump on click"] -width 12 } + -text [_ "Jump on click"] -width [::msgcat::mcmax "Jump on click"] } if {[eval concat $$var_iemgui_steady] == 1} { button $mytoplevel.para.stdy_jmp -command "::dialog_iemgui::stdy_jmp $mytoplevel" \ - -text [_ "steady on click"] -width 12 } + -text [_ "Steady on click"] -width [::msgcat::mcmax "Steady on click"] } if {[eval concat $$var_iemgui_lin0_log1] >= 0} { pack $mytoplevel.para.lilo -side left -expand 1} if {[eval concat $$var_iemgui_loadbang] >= 0} { @@ -579,192 +567,196 @@ proc ::dialog_iemgui::pdtk_iemgui_dialog {mytoplevel mainheader dim_header \ pack $mytoplevel.para.dummy3 $mytoplevel.para.num_lab $mytoplevel.para.num_ent -side left -expand 1} if {[eval concat $$var_iemgui_steady] >= 0} { pack $mytoplevel.para.dummy3 $mytoplevel.para.stdy_jmp -side left -expand 1} - - frame $mytoplevel.spacer0 -height 4 - pack $mytoplevel.spacer0 -side top - labelframe $mytoplevel.s_r -borderwidth 1 -pady 4 -text [_ "Messages"] \ - -font highlight_font - pack $mytoplevel.s_r -side top -fill x -ipadx 5 + frame $mytoplevel.spacer0 -height 4 + pack $mytoplevel.spacer0 -side top + + labelframe $mytoplevel.s_r -borderwidth 1 -pady 4 -text [_ "Messages"] + pack $mytoplevel.s_r -side top -fill x -ipadx 5 frame $mytoplevel.s_r.send pack $mytoplevel.s_r.send -side top - label $mytoplevel.s_r.send.lab -text [_ "Send symbol"] -width 12 -justify right + label $mytoplevel.s_r.send.lab -text [_ "Send symbol:"] -width 12 -justify right entry $mytoplevel.s_r.send.ent -textvariable $var_iemgui_snd -width 22 - if { $snd != "nosndno" } { + if { $snd ne "nosndno" } { pack $mytoplevel.s_r.send.lab $mytoplevel.s_r.send.ent -side left} frame $mytoplevel.s_r.receive pack $mytoplevel.s_r.receive -side top - label $mytoplevel.s_r.receive.lab -text [_ "Receive symbol"] -width 12 -justify right + label $mytoplevel.s_r.receive.lab -text [_ "Receive symbol:"] -width 12 -justify right entry $mytoplevel.s_r.receive.ent -textvariable $var_iemgui_rcv -width 22 - if { $rcv != "norcvno" } { + if { $rcv ne "norcvno" } { pack $mytoplevel.s_r.receive.lab $mytoplevel.s_r.receive.ent -side left} - # get the current font name from the int given from C-space (gn_f) - set current_font $::font_family + # get the current font name from the int given from C-space (gn_f) + set current_font $::font_family if {[eval concat $$var_iemgui_gn_f] == 1} \ - { set current_font "Helvetica" } + { set current_font "Helvetica" } if {[eval concat $$var_iemgui_gn_f] == 2} \ - { set current_font "Times" } - - frame $mytoplevel.spacer1 -height 7 - pack $mytoplevel.spacer1 -side top - - labelframe $mytoplevel.label -borderwidth 1 -text [_ "Label"] -pady 4 \ - -font highlight_font - pack $mytoplevel.label -side top -fill x + { set current_font "Times" } + + frame $mytoplevel.spacer1 -height 7 + pack $mytoplevel.spacer1 -side top + + labelframe $mytoplevel.label -borderwidth 1 -text [_ "Label"] -pady 4 + pack $mytoplevel.label -side top -fill x entry $mytoplevel.label.name_entry -textvariable $var_iemgui_gui_nam -width 30 \ - -font [list $current_font 12 $::font_weight] + -font [list $current_font 12 $::font_weight] pack $mytoplevel.label.name_entry -side top -expand yes -fill both -padx 5 frame $mytoplevel.label.xy -padx 27 -pady 1 pack $mytoplevel.label.xy -side top - label $mytoplevel.label.xy.x_lab -text [_ "X offset"] -width 6 + label $mytoplevel.label.xy.x_lab -text [_ "X offset"] \ + -width [::msgcat::mcmax "X offset"] entry $mytoplevel.label.xy.x_entry -textvariable $var_iemgui_gn_dx -width 5 label $mytoplevel.label.xy.dummy1 -text " " -width 2 - label $mytoplevel.label.xy.y_lab -text [_ "Y offset"] -width 6 + label $mytoplevel.label.xy.y_lab -text [_ "Y offset"] \ + -width [::msgcat::mcmax "Y offset"] entry $mytoplevel.label.xy.y_entry -textvariable $var_iemgui_gn_dy -width 5 pack $mytoplevel.label.xy.x_lab $mytoplevel.label.xy.x_entry $mytoplevel.label.xy.dummy1 \ - $mytoplevel.label.xy.y_lab $mytoplevel.label.xy.y_entry -side left -anchor e + $mytoplevel.label.xy.y_lab $mytoplevel.label.xy.y_entry -side left -anchor e - label $mytoplevel.label.fontpopup_label -text $current_font \ - -relief groove -font [list $current_font 12 $::font_weight] -padx 5 + label $mytoplevel.label.fontpopup_label -text $current_font \ + -relief groove -font [list $current_font 12 $::font_weight] -padx 5 pack $mytoplevel.label.fontpopup_label -side left -anchor w -expand yes -fill x - label $mytoplevel.label.fontsize_label -text [_ "size:"] -width 4 + label $mytoplevel.label.fontsize_label -text [_ "Size:"] \ + -width [::msgcat::mcmax "Size:"] entry $mytoplevel.label.fontsize_entry -textvariable $var_iemgui_gn_fs -width 5 - pack $mytoplevel.label.fontsize_entry $mytoplevel.label.fontsize_label \ - -side right -anchor e -padx 5 -pady 5 - menu $mytoplevel.popup - $mytoplevel.popup add command \ - -label $::font_family \ - -font [format {{%s} 12 %s} $::font_family $::font_weight] \ - -command "::dialog_iemgui::toggle_font $mytoplevel 0" - $mytoplevel.popup add command \ - -label "Helvetica" \ - -font [format {Helvetica 12 %s} $::font_weight] \ - -command "::dialog_iemgui::toggle_font $mytoplevel 1" - $mytoplevel.popup add command \ - -label "Times" \ - -font [format {Times 12 %s} $::font_weight] \ - -command "::dialog_iemgui::toggle_font $mytoplevel 2" - bind $mytoplevel.label.fontpopup_label <Button> \ - [list tk_popup $mytoplevel.popup %X %Y] - - frame $mytoplevel.spacer2 -height 7 - pack $mytoplevel.spacer2 -side top - - labelframe $mytoplevel.colors -borderwidth 1 -text [_ "Colors"] -font highlight_font + pack $mytoplevel.label.fontsize_entry $mytoplevel.label.fontsize_label \ + -side right -anchor e -padx 5 -pady 5 + menu $mytoplevel.popup + $mytoplevel.popup add command \ + -label $::font_family \ + -font [format {{%s} 12 %s} $::font_family $::font_weight] \ + -command "::dialog_iemgui::toggle_font $mytoplevel 0" + $mytoplevel.popup add command \ + -label "Helvetica" \ + -font [format {Helvetica 12 %s} $::font_weight] \ + -command "::dialog_iemgui::toggle_font $mytoplevel 1" + $mytoplevel.popup add command \ + -label "Times" \ + -font [format {Times 12 %s} $::font_weight] \ + -command "::dialog_iemgui::toggle_font $mytoplevel 2" + bind $mytoplevel.label.fontpopup_label <Button> \ + [list tk_popup $mytoplevel.popup %X %Y] + + frame $mytoplevel.spacer2 -height 7 + pack $mytoplevel.spacer2 -side top + + labelframe $mytoplevel.colors -borderwidth 1 -text [_ "Colors"] pack $mytoplevel.colors -fill x -ipadx 5 -ipady 4 frame $mytoplevel.colors.select pack $mytoplevel.colors.select -side top radiobutton $mytoplevel.colors.select.radio0 -value 0 -variable \ - $var_iemgui_l2_f1_b0 -text [_ "Background"] -width 10 -justify left + $var_iemgui_l2_f1_b0 -text [_ "Background"] -justify left \ + -width [::msgcat::mcmax "Background"] radiobutton $mytoplevel.colors.select.radio1 -value 1 -variable \ - $var_iemgui_l2_f1_b0 -text [_ "Front"] -width 5 -justify left + $var_iemgui_l2_f1_b0 -text [_ "Front"] -justify left \ + -width [::msgcat::mcmax "Front"] radiobutton $mytoplevel.colors.select.radio2 -value 2 -variable \ - $var_iemgui_l2_f1_b0 -text [_ "Label"] -width 5 -justify left + $var_iemgui_l2_f1_b0 -text [_ "Label"] -justify left \ + -width [::msgcat::mcmax "Label"] if { [eval concat $$var_iemgui_fcol] >= 0 } { - pack $mytoplevel.colors.select.radio0 $mytoplevel.colors.select.radio1 \ - $mytoplevel.colors.select.radio2 -side left - } else { - pack $mytoplevel.colors.select.radio0 $mytoplevel.colors.select.radio2 -side left - } + pack $mytoplevel.colors.select.radio0 $mytoplevel.colors.select.radio1 \ + $mytoplevel.colors.select.radio2 -side left + } else { + pack $mytoplevel.colors.select.radio0 $mytoplevel.colors.select.radio2 -side left + } frame $mytoplevel.colors.sections pack $mytoplevel.colors.sections -side top button $mytoplevel.colors.sections.but -text [_ "Compose color"] \ - -width [::msgcat::mcmax "Compose color"] \ - -command "::dialog_iemgui::choose_col_bkfrlb $mytoplevel" + -width [::msgcat::mcmax "Compose color"] \ + -command "::dialog_iemgui::choose_col_bkfrlb $mytoplevel" pack $mytoplevel.colors.sections.but -side left -anchor w -padx 10 -pady 5 \ - -expand yes -fill x + -expand yes -fill x if { [eval concat $$var_iemgui_fcol] >= 0 } { - label $mytoplevel.colors.sections.fr_bk -text "o=||=o" -width 6 \ - -background [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ - -activebackground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ - -foreground [format "#%6.6x" [eval concat $$var_iemgui_fcol]] \ - -activeforeground [format "#%6.6x" [eval concat $$var_iemgui_fcol]] \ - -font [list $current_font 12 $::font_weight] -padx 2 -pady 2 -relief ridge + label $mytoplevel.colors.sections.fr_bk -text "o=||=o" -width 6 \ + -background [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ + -activebackground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ + -foreground [format "#%6.6x" [eval concat $$var_iemgui_fcol]] \ + -activeforeground [format "#%6.6x" [eval concat $$var_iemgui_fcol]] \ + -font [list $current_font 12 $::font_weight] -padx 2 -pady 2 -relief ridge } else { - label $mytoplevel.colors.sections.fr_bk -text "o=||=o" -width 6 \ - -background [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ - -activebackground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ - -foreground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ - -activeforeground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ - -font [list $current_font 12 $::font_weight] -padx 2 -pady 2 -relief ridge - } + label $mytoplevel.colors.sections.fr_bk -text "o=||=o" -width 6 \ + -background [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ + -activebackground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ + -foreground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ + -activeforeground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ + -font [list $current_font 12 $::font_weight] -padx 2 -pady 2 -relief ridge + } label $mytoplevel.colors.sections.lb_bk -text [_ "Test label"] \ - -width [::msgcat::mcmax "Test label"] \ - -background [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ - -activebackground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ - -foreground [format "#%6.6x" [eval concat $$var_iemgui_lcol]] \ - -activeforeground [format "#%6.6x" [eval concat $$var_iemgui_lcol]] \ - -font [list $current_font 12 $::font_weight] -padx 2 -pady 2 -relief ridge + -width [::msgcat::mcmax "Test label"] \ + -background [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ + -activebackground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \ + -foreground [format "#%6.6x" [eval concat $$var_iemgui_lcol]] \ + -activeforeground [format "#%6.6x" [eval concat $$var_iemgui_lcol]] \ + -font [list $current_font 12 $::font_weight] -padx 2 -pady 2 -relief ridge pack $mytoplevel.colors.sections.lb_bk $mytoplevel.colors.sections.fr_bk \ - -side right -anchor e -expand yes -fill both -pady 7 - - # color scheme by Mary Ann Benedetto http://piR2.org + -side right -anchor e -expand yes -fill both -pady 7 + + # color scheme by Mary Ann Benedetto http://piR2.org frame $mytoplevel.colors.r1 pack $mytoplevel.colors.r1 -side top foreach i { 0 1 2 3 4 5 6 7 8 9} \ - hexcol { 0xFFFFFF 0xDFDFDF 0xBBBBBB 0xFFC7C6 0xFFE3C6 \ - 0xFEFFC6 0xC6FFC7 0xc6FEFF 0xC7C6FF 0xE3C6FF } \ - { - label $mytoplevel.colors.r1.c$i -background [format "#%6.6x" $hexcol] \ - -activebackground [format "#%6.6x" $hexcol] -relief ridge \ - -padx 7 -pady 0 - bind $mytoplevel.colors.r1.c$i <Button> [format "::dialog_iemgui::preset_col %s %d" $mytoplevel $hexcol] - } + hexcol { 0xFFFFFF 0xDFDFDF 0xBBBBBB 0xFFC7C6 0xFFE3C6 \ + 0xFEFFC6 0xC6FFC7 0xc6FEFF 0xC7C6FF 0xE3C6FF } \ + { + label $mytoplevel.colors.r1.c$i -background [format "#%6.6x" $hexcol] \ + -activebackground [format "#%6.6x" $hexcol] -relief ridge \ + -padx 7 -pady 0 + bind $mytoplevel.colors.r1.c$i <Button> [format "::dialog_iemgui::preset_col %s %d" $mytoplevel $hexcol] + } pack $mytoplevel.colors.r1.c0 $mytoplevel.colors.r1.c1 $mytoplevel.colors.r1.c2 $mytoplevel.colors.r1.c3 \ - $mytoplevel.colors.r1.c4 $mytoplevel.colors.r1.c5 $mytoplevel.colors.r1.c6 $mytoplevel.colors.r1.c7 \ - $mytoplevel.colors.r1.c8 $mytoplevel.colors.r1.c9 -side left + $mytoplevel.colors.r1.c4 $mytoplevel.colors.r1.c5 $mytoplevel.colors.r1.c6 $mytoplevel.colors.r1.c7 \ + $mytoplevel.colors.r1.c8 $mytoplevel.colors.r1.c9 -side left frame $mytoplevel.colors.r2 pack $mytoplevel.colors.r2 -side top foreach i { 0 1 2 3 4 5 6 7 8 9 } \ - hexcol { 0x9F9F9F 0x7C7C7C 0x606060 0xFF0400 0xFF8300 \ - 0xFAFF00 0x00FF04 0x00FAFF 0x0400FF 0x9C00FF } \ - { - label $mytoplevel.colors.r2.c$i -background [format "#%6.6x" $hexcol] \ - -activebackground [format "#%6.6x" $hexcol] -relief ridge \ - -padx 7 -pady 0 - bind $mytoplevel.colors.r2.c$i <Button> \ - [format "::dialog_iemgui::preset_col %s %d" $mytoplevel $hexcol] - } + hexcol { 0x9F9F9F 0x7C7C7C 0x606060 0xFF0400 0xFF8300 \ + 0xFAFF00 0x00FF04 0x00FAFF 0x0400FF 0x9C00FF } \ + { + label $mytoplevel.colors.r2.c$i -background [format "#%6.6x" $hexcol] \ + -activebackground [format "#%6.6x" $hexcol] -relief ridge \ + -padx 7 -pady 0 + bind $mytoplevel.colors.r2.c$i <Button> \ + [format "::dialog_iemgui::preset_col %s %d" $mytoplevel $hexcol] + } pack $mytoplevel.colors.r2.c0 $mytoplevel.colors.r2.c1 $mytoplevel.colors.r2.c2 $mytoplevel.colors.r2.c3 \ - $mytoplevel.colors.r2.c4 $mytoplevel.colors.r2.c5 $mytoplevel.colors.r2.c6 $mytoplevel.colors.r2.c7 \ - $mytoplevel.colors.r2.c8 $mytoplevel.colors.r2.c9 -side left + $mytoplevel.colors.r2.c4 $mytoplevel.colors.r2.c5 $mytoplevel.colors.r2.c6 $mytoplevel.colors.r2.c7 \ + $mytoplevel.colors.r2.c8 $mytoplevel.colors.r2.c9 -side left frame $mytoplevel.colors.r3 pack $mytoplevel.colors.r3 -side top foreach i { 0 1 2 3 4 5 6 7 8 9 } \ - hexcol { 0x404040 0x202020 0x000000 0x551312 0x553512 \ - 0x535512 0x0F4710 0x0E4345 0x131255 0x2F004D } \ - { - label $mytoplevel.colors.r3.c$i -background [format "#%6.6x" $hexcol] \ - -activebackground [format "#%6.6x" $hexcol] -relief ridge \ - -padx 7 -pady 0 - bind $mytoplevel.colors.r3.c$i <Button> \ - [format "::dialog_iemgui::preset_col %s %d" $mytoplevel $hexcol] - } + hexcol { 0x404040 0x202020 0x000000 0x551312 0x553512 \ + 0x535512 0x0F4710 0x0E4345 0x131255 0x2F004D } \ + { + label $mytoplevel.colors.r3.c$i -background [format "#%6.6x" $hexcol] \ + -activebackground [format "#%6.6x" $hexcol] -relief ridge \ + -padx 7 -pady 0 + bind $mytoplevel.colors.r3.c$i <Button> \ + [format "::dialog_iemgui::preset_col %s %d" $mytoplevel $hexcol] + } pack $mytoplevel.colors.r3.c0 $mytoplevel.colors.r3.c1 $mytoplevel.colors.r3.c2 $mytoplevel.colors.r3.c3 \ - $mytoplevel.colors.r3.c4 $mytoplevel.colors.r3.c5 $mytoplevel.colors.r3.c6 $mytoplevel.colors.r3.c7 \ - $mytoplevel.colors.r3.c8 $mytoplevel.colors.r3.c9 -side left + $mytoplevel.colors.r3.c4 $mytoplevel.colors.r3.c5 $mytoplevel.colors.r3.c6 $mytoplevel.colors.r3.c7 \ + $mytoplevel.colors.r3.c8 $mytoplevel.colors.r3.c9 -side left frame $mytoplevel.cao -pady 10 pack $mytoplevel.cao -side top button $mytoplevel.cao.cancel -text [_ "Cancel"] -width 6 \ - -command "::dialog_iemgui::cancel $mytoplevel" + -command "::dialog_iemgui::cancel $mytoplevel" label $mytoplevel.cao.dummy1 -text "" -width 3 - button $mytoplevel.cao.apply -text [_ "Apply"] -width 6 \ - -command "::dialog_iemgui::apply $mytoplevel" + button $mytoplevel.cao.apply -text [_ "Apply"] -width 6 \ + -command "::dialog_iemgui::apply $mytoplevel" label $mytoplevel.cao.dummy2 -text "" -width 3 button $mytoplevel.cao.ok -text [_ "OK"] -width 6 \ - -command "::dialog_iemgui::ok $mytoplevel" + -command "::dialog_iemgui::ok $mytoplevel" pack $mytoplevel.cao.cancel $mytoplevel.cao.dummy1 -side left - pack $mytoplevel.cao.apply $mytoplevel.cao.dummy2 -side left + pack $mytoplevel.cao.apply $mytoplevel.cao.dummy2 -side left pack $mytoplevel.cao.ok -side left - + if {[info tclversion] < 8.4} { bind $mytoplevel <Key-Tab> {tkTabToWindow [tk_focusNext %W]} bind $mytoplevel <<PrevWindow>> {tkTabToWindow [tk_focusPrev %W]} diff --git a/pd/tcl/dialog_midi.tcl b/pd/tcl/dialog_midi.tcl new file mode 100644 index 00000000..d8554665 --- /dev/null +++ b/pd/tcl/dialog_midi.tcl @@ -0,0 +1,344 @@ +package provide dialog_midi 0.1 + +namespace eval ::dialog_midi:: { + namespace export pdtk_midi_dialog +} + +# TODO this panel really needs some reworking, it works but the code is +# very unreadable + + +####################### midi dialog ################## + +proc ::dialog_midi::apply {mytoplevel} { + global midi_indev1 midi_indev2 midi_indev3 midi_indev4 + global midi_outdev1 midi_outdev2 midi_outdev3 midi_outdev4 + global midi_alsain midi_alsaout + + pdsend "pd midi-dialog \ + $midi_indev1 \ + $midi_indev2 \ + $midi_indev3 \ + $midi_indev4 \ + $midi_outdev1 \ + $midi_outdev2 \ + $midi_outdev3 \ + $midi_outdev4 \ + $midi_alsain \ + $midi_alsaout" +} + +proc ::dialog_midi::cancel {mytoplevel} { + pdsend "$mytoplevel cancel" +} + +proc ::dialog_midi::ok {mytoplevel} { + ::dialog_midi::apply $mytoplevel + ::dialog_midi::cancel $mytoplevel +} + +# callback from popup menu +proc midi_popup_action {buttonname varname devlist index} { + global midi_indevlist midi_outdevlist $varname + $buttonname configure -text [lindex $devlist $index] + set $varname $index +} + +# create a popup menu +proc midi_popup {name buttonname varname devlist} { + if [winfo exists $name.popup] {destroy $name.popup} + menu $name.popup -tearoff false + if {$::windowingsystem eq "win32"} { + $name.popup configure -font menuFont + } +# puts stderr [concat $devlist ] + for {set x 0} {$x<[llength $devlist]} {incr x} { + $name.popup add command -label [lindex $devlist $x] \ + -command [list midi_popup_action \ + $buttonname $varname $devlist $x] + } + tk_popup $name.popup [winfo pointerx $name] [winfo pointery $name] 0 +} + +# start a dialog window to select midi devices. "longform" asks us to make +# controls for opening several devices; if not, we get an extra button to +# turn longform on and restart the dialog. +proc ::dialog_midi::pdtk_midi_dialog {id indev1 indev2 indev3 indev4 \ + outdev1 outdev2 outdev3 outdev4 longform} { + global midi_indev1 midi_indev2 midi_indev3 midi_indev4 + global midi_outdev1 midi_outdev2 midi_outdev3 midi_outdev4 + global midi_indevlist midi_outdevlist + global midi_alsain midi_alsaout + + set midi_indev1 $indev1 + set midi_indev2 $indev2 + set midi_indev3 $indev3 + set midi_indev4 $indev4 + set midi_outdev1 $outdev1 + set midi_outdev2 $outdev2 + set midi_outdev3 $outdev3 + set midi_outdev4 $outdev4 + set midi_alsain [llength $midi_indevlist] + set midi_alsaout [llength $midi_outdevlist] + + toplevel $id + wm title $id [_ "MIDI Settings"] + if {$::windowingsystem eq "aqua"} {$id configure -menu .menubar} + ::pd_bindings::dialog_bindings $id "midi" + + frame $id.buttonframe + pack $id.buttonframe -side bottom -fill x -pady 2m + button $id.buttonframe.cancel -text [_ "Cancel"]\ + -command "::dialog_midi::cancel $id" + button $id.buttonframe.apply -text [_ "Apply"]\ + -command "::dialog_midi::apply $id" + button $id.buttonframe.ok -text [_ "OK"]\ + -command "::dialog_midi::ok $id" + pack $id.buttonframe.cancel -side left -expand 1 + pack $id.buttonframe.apply -side left -expand 1 + pack $id.buttonframe.ok -side left -expand 1 + + # input device 1 + frame $id.in1f + pack $id.in1f -side top + + label $id.in1f.l1 -text [_ "Input device 1:"] + button $id.in1f.x1 -text [lindex $midi_indevlist $midi_indev1] \ + -command [list midi_popup $id $id.in1f.x1 midi_indev1 $midi_indevlist] + pack $id.in1f.l1 $id.in1f.x1 -side left + + # input device 2 + if {$longform && [llength $midi_indevlist] > 2} { + frame $id.in2f + pack $id.in2f -side top + + label $id.in2f.l1 -text [_ "Input device 2:"] + button $id.in2f.x1 -text [lindex $midi_indevlist $midi_indev2] \ + -command [list midi_popup $id $id.in2f.x1 midi_indev2 \ + $midi_indevlist] + pack $id.in2f.l1 $id.in2f.x1 -side left + } + + # input device 3 + if {$longform && [llength $midi_indevlist] > 3} { + frame $id.in3f + pack $id.in3f -side top + + label $id.in3f.l1 -text [_ "Input device 3:"] + button $id.in3f.x1 -text [lindex $midi_indevlist $midi_indev3] \ + -command [list midi_popup $id $id.in3f.x1 midi_indev3 \ + $midi_indevlist] + pack $id.in3f.l1 $id.in3f.x1 -side left + } + + # input device 4 + if {$longform && [llength $midi_indevlist] > 4} { + frame $id.in4f + pack $id.in4f -side top + + label $id.in4f.l1 -text [_ "Input device 4:"] + button $id.in4f.x1 -text [lindex $midi_indevlist $midi_indev4] \ + -command [list midi_popup $id $id.in4f.x1 midi_indev4 \ + $midi_indevlist] + pack $id.in4f.l1 $id.in4f.x1 -side left + } + + # output device 1 + + frame $id.out1f + pack $id.out1f -side top + label $id.out1f.l1 -text [_ "Output device 1:"] + button $id.out1f.x1 -text [lindex $midi_outdevlist $midi_outdev1] \ + -command [list midi_popup $id $id.out1f.x1 midi_outdev1 \ + $midi_outdevlist] + pack $id.out1f.l1 $id.out1f.x1 -side left + + # output device 2 + if {$longform && [llength $midi_outdevlist] > 2} { + frame $id.out2f + pack $id.out2f -side top + label $id.out2f.l1 -text [_ "Output device 2:"] + button $id.out2f.x1 -text [lindex $midi_outdevlist $midi_outdev2] \ + -command \ + [list midi_popup $id $id.out2f.x1 midi_outdev2 $midi_outdevlist] + pack $id.out2f.l1 $id.out2f.x1 -side left + } + + # output device 3 + if {$longform && [llength $midi_midi_outdevlist] > 3} { + frame $id.out3f + pack $id.out3f -side top + label $id.out3f.l1 -text [_ "Output device 3:"] + button $id.out3f.x1 -text [lindex $midi_outdevlist $midi_outdev3] \ + -command \ + [list midi_popup $id $id.out3f.x1 midi_outdev3 $midi_outdevlist] + pack $id.out3f.l1 $id.out3f.x1 -side left + } + + # output device 4 + if {$longform && [llength $midi_midi_outdevlist] > 4} { + frame $id.out4f + pack $id.out4f -side top + label $id.out4f.l1 -text [_ "Output device 4:"] + button $id.out4f.x1 -text [lindex $midi_outdevlist $midi_outdev4] \ + -command \ + [list midi_popup $id $id.out4f.x1 midi_outdev4 $midi_outdevlist] + pack $id.out4f.l1 $id.out4f.x1 -side left + } + + # if not the "long form" make a button to + # restart with longform set. + + if {$longform == 0} { + frame $id.longbutton + pack $id.longbutton -side top + button $id.longbutton.b -text [_ "Use multiple devices"] \ + -command {pdsend "pd midi-properties 1"} + pack $id.longbutton.b + } +} + +proc ::dialog_midi::pdtk_alsa_midi_dialog {id indev1 indev2 indev3 indev4 \ + outdev1 outdev2 outdev3 outdev4 longform alsa} { + global midi_indev1 midi_indev2 midi_indev3 midi_indev4 + global midi_outdev1 midi_outdev2 midi_outdev3 midi_outdev4 + global midi_indevlist midi_outdevlist + global midi_alsain midi_alsaout + + set midi_indev1 $indev1 + set midi_indev2 $indev2 + set midi_indev3 $indev3 + set midi_indev4 $indev4 + set midi_outdev1 $outdev1 + set midi_outdev2 $outdev2 + set midi_outdev3 $outdev3 + set midi_outdev4 $outdev4 + set midi_alsain [llength $midi_indevlist] + set midi_alsaout [llength $midi_outdevlist] + + toplevel $id + wm title $id [_ "ALSA MIDI Settings"] + if {$::windowingsystem eq "aqua"} {$id configure -menu .menubar} + ::pd_bindings::dialog_bindings $id "midi" + + frame $id.buttonframe + pack $id.buttonframe -side bottom -fill x -pady 2m + button $id.buttonframe.cancel -text [_ "Cancel"]\ + -command "::dialog_midi::cancel $id" + button $id.buttonframe.apply -text [_ "Apply"]\ + -command "::dialog_midi::apply $id" + button $id.buttonframe.ok -text [_ "OK"]\ + -command "::dialog_midi::ok $id" + pack $id.buttonframe.cancel -side left -expand 1 + pack $id.buttonframe.apply -side left -expand 1 + pack $id.buttonframe.ok -side left -expand 1 + + frame $id.in1f + pack $id.in1f -side top + + if {$alsa == 0} { + # input device 1 + label $id.in1f.l1 -text [_ "Input device 1:"] + button $id.in1f.x1 -text [lindex $midi_indevlist $midi_indev1] \ + -command [list midi_popup $id $id.in1f.x1 midi_indev1 $midi_indevlist] + pack $id.in1f.l1 $id.in1f.x1 -side left + + # input device 2 + if {$longform && [llength $midi_indevlist] > 2} { + frame $id.in2f + pack $id.in2f -side top + + label $id.in2f.l1 -text [_ "Input device 2:"] + button $id.in2f.x1 -text [lindex $midi_indevlist $midi_indev2] \ + -command [list midi_popup $id $id.in2f.x1 midi_indev2 \ + $midi_indevlist] + pack $id.in2f.l1 $id.in2f.x1 -side left + } + + # input device 3 + if {$longform && [llength $midi_indevlist] > 3} { + frame $id.in3f + pack $id.in3f -side top + + label $id.in3f.l1 -text [_ "Input device 3:"] + button $id.in3f.x1 -text [lindex $midi_indevlist $midi_indev3] \ + -command [list midi_popup $id $id.in3f.x1 midi_indev3 \ + $midi_indevlist] + pack $id.in3f.l1 $id.in3f.x1 -side left + } + + # input device 4 + if {$longform && [llength $midi_indevlist] > 4} { + frame $id.in4f + pack $id.in4f -side top + + label $id.in4f.l1 -text [_ "Input device 4:"] + button $id.in4f.x1 -text [lindex $midi_indevlist $midi_indev4] \ + -command [list midi_popup $id $id.in4f.x1 midi_indev4 \ + $midi_indevlist] + pack $id.in4f.l1 $id.in4f.x1 -side left + } + + # output device 1 + + frame $id.out1f + pack $id.out1f -side top + label $id.out1f.l1 -text [_ "Output device 1:"] + button $id.out1f.x1 -text [lindex $midi_outdevlist $midi_outdev1] \ + -command [list midi_popup $id $id.out1f.x1 midi_outdev1 \ + $midi_outdevlist] + pack $id.out1f.l1 $id.out1f.x1 -side left + + # output device 2 + if {$longform && [llength $midi_outdevlist] > 2} { + frame $id.out2f + pack $id.out2f -side top + label $id.out2f.l1 -text [_ "Output device 2:"] + button $id.out2f.x1 -text [lindex $midi_outdevlist $midi_outdev2] \ + -command \ + [list midi_popup $id $id.out2f.x1 midi_outdev2 $midi_outdevlist] + pack $id.out2f.l1 $id.out2f.x1 -side left + } + + # output device 3 + if {$longform && [llength $midi_outdevlist] > 3} { + frame $id.out3f + pack $id.out3f -side top + label $id.out3f.l1 -text [_ "Output device 3:"] + button $id.out3f.x1 -text [lindex $midi_outdevlist $midi_outdev3] \ + -command \ + [list midi_popup $id $id.out3f.x1 midi_outdev3 $midi_outdevlist] + pack $id.out3f.l1 $id.out3f.x1 -side left + } + + # output device 4 + if {$longform && [llength $midi_outdevlist] > 4} { + frame $id.out4f + pack $id.out4f -side top + label $id.out4f.l1 -text [_ "Output device 4:"] + button $id.out4f.x1 -text [lindex $midi_outdevlist $midi_outdev4] \ + -command \ + [list midi_popup $id $id.out4f.x1 midi_outdev4 $midi_outdevlist] + pack $id.out4f.l1 $id.out4f.x1 -side left + } + + # if not the "long form" make a button to + # restart with longform set. + + if {$longform == 0} { + frame $id.longbutton + pack $id.longbutton -side top + button $id.longbutton.b -text [_ "Use multiple ALSA devices"] \ + -command {pdsend "pd midi-properties 1"} + pack $id.longbutton.b + } + } + if {$alsa} { + label $id.in1f.l1 -text [_ "In Ports:"] + entry $id.in1f.x1 -textvariable midi_alsain -width 4 + pack $id.in1f.l1 $id.in1f.x1 -side left + label $id.in1f.l2 -text [_ "Out Ports:"] + entry $id.in1f.x2 -textvariable midi_alsaout -width 4 + pack $id.in1f.l2 $id.in1f.x2 -side left + } +} diff --git a/pd/tcl/opt_parser.tcl b/pd/tcl/opt_parser.tcl new file mode 100644 index 00000000..d304e045 --- /dev/null +++ b/pd/tcl/opt_parser.tcl @@ -0,0 +1,78 @@ +package provide opt_parser 0.1 + +namespace eval opt_parser { + # list of option vars (keys are long option names) + variable optlist + variable optprefix {-} +} + +proc opt_parser::init {optdata} { + variable optlist + array unset optlist + array set optlist {} + foreach item $optdata { + foreach {longname varlist} $item { + if {[llength $varlist] < 1} { + return -code error "usage: init { {optname {var1 var2 ...}} ... }" + } + set optlist($longname) $varlist + } + } +} + +proc opt_parser::get_options {argv {opts {}}} { + set ignore_unknown_flags 0 + foreach {k v} $opts {set $k $v} + + variable optlist + variable optprefix + + # zero all the options 1st var + foreach optName [array names optlist] { + uplevel [list set [lindex $optlist($optName) 0] 0] + for {set i 1} {$i < [llength $optlist($optName)]} {incr i} { + uplevel [list set [lindex $optlist($optName) $i] [list]] + } + } + + # here will be appended non-options arguments + set residualArgs {} + + set argc [llength $argv] + for {set i 0} {$i < $argc} {} { + # get i-th arg + set argv_i [lindex $argv $i] + incr i + + # if it's not an option, stop here, and add to residualArgs + if {![regexp ^$optprefix $argv_i]} { + lappend residualArgs $argv_i + continue + } + + set optName [regsub ^$optprefix $argv_i {}] + if {[info exists optlist($optName)]} { + set varlist $optlist($optName) + uplevel [list set [lindex $optlist($optName) 0] 1] + set n_required_opt_args [expr {-1+[llength $varlist]}] + set j 1 + while {$n_required_opt_args > 0} { + incr n_required_opt_args -1 + if {$i >= $argc} { + return -code error "not enough arguments for option $optprefix$optName" + } + uplevel [list lappend [lindex $varlist $j] [lindex $argv $i]] + incr j + incr i + } + } else { + if {$ignore_unknown_flags} { + lappend residualArgs $argv_i + continue + } else { + return -code error "unknown option: $optprefix$optName" + } + } + } + return $residualArgs +} diff --git a/pd/tcl/pd-gui.tcl b/pd/tcl/pd-gui.tcl new file mode 100644 index 00000000..6dfe1663 --- /dev/null +++ b/pd/tcl/pd-gui.tcl @@ -0,0 +1,503 @@ +#!/bin/sh +# This line continues for Tcl, but is a single line for 'sh' \ + exec wish "$0" -- ${1+"$@"} +# For information on usage and redistribution, and for a DISCLAIMER OF ALL +# WARRANTIES, see the file, "LICENSE.txt," in this distribution. +# Copyright (c) 1997-2009 Miller Puckette. + +# "." automatically gets a window, we don't want it. Withdraw it before doing +# anything else, so that we don't get the automatic window flashing for a +# second while pd loads. +wm withdraw . + +puts -------------------------------pd-gui.tcl----------------------------------- + +package require Tcl 8.3 +package require Tk +package require Tk +if {[tk windowingsystem] ne "win32"} {package require msgcat} +# TODO figure out msgcat issue on Windows + +# Pd's packages are stored in the same directory as the main script (pd-gui.tcl) +set auto_path [linsert $auto_path 0 [file dirname [info script]]] +package require pd_connect +package require pd_menus +package require pd_bindings +package require pdwindow +package require dialog_array +package require dialog_audio +package require dialog_canvas +package require dialog_font +package require dialog_gatom +package require dialog_iemgui +package require dialog_midi +package require pdtk_canvas +package require pdtk_text +# TODO eliminate this kludge: +package require wheredoesthisgo + +# import into the global namespace for backwards compatibility +namespace import ::pd_connect::pdsend +namespace import ::pdwindow::pdtk_post +namespace import ::dialog_array::pdtk_array_dialog +namespace import ::dialog_audio::pdtk_audio_dialog +namespace import ::dialog_canvas::pdtk_canvas_dialog +namespace import ::dialog_font::pdtk_canvas_dofont +namespace import ::dialog_gatom::pdtk_gatom_dialog +namespace import ::dialog_iemgui::pdtk_iemgui_dialog +namespace import ::dialog_midi::pdtk_midi_dialog +namespace import ::dialog_midi::pdtk_alsa_midi_dialog + +# hack - these should be better handled in the C code +namespace import ::dialog_array::pdtk_array_listview_new +namespace import ::dialog_array::pdtk_array_listview_fillpage +namespace import ::dialog_array::pdtk_array_listview_setpage +namespace import ::dialog_array::pdtk_array_listview_closeWindow + +#------------------------------------------------------------------------------# +# global variables + +set PD_MAJOR_VERSION 0 +set PD_MINOR_VERSION 0 +set PD_BUGFIX_VERSION 0 +set PD_TEST_VERSION "" + +set TCL_MAJOR_VERSION 0 +set TCL_MINOR_VERSION 0 +set TCL_BUGFIX_VERSION 0 + +# for testing which platform we are running on ("aqua", "win32", or "x11") +set windowingsystem "" + +# variable for vwait so that 'pd-gui' will timeout if 'pd' never shows up +set wait4pd "init" + +# canvas font, received from pd in pdtk_pd_startup, set in s_main.c +set font_family "courier" +set font_weight "normal" +# sizes of chars for each of the Pd fixed font sizes: +# fontsize width(pixels) height(pixels) +set font_fixed_metrics { + 8 5 10 + 9 6 11 + 10 6 13 + 12 7 15 + 14 8 17 + 16 10 20 + 18 11 22 + 24 14 30 + 30 18 37 + 36 22 45 +} + +# root path to lib of Pd's files, see s_main.c for more info +set sys_libdir {} +# root path where the pd-gui.tcl GUI script is located +set sys_guidir {} + +set audioapi_list {} +set midiapi_list {} +set pd_whichapi 0 +set pd_whichmidiapi 0 + +# current state of the DSP +set dsp 0 +# the toplevel window that currently is on top and has focus +set focused_window . +# TODO figure out how to get all windows into the menu_windowlist +# store list of parent windows for Window menu +set menu_windowlist {} +# store that last 10 files that were opened +set recentfiles_list {} +set total_recentfiles 10 +# keep track of the location of popup menu for CanvasWindows +set popup_xpix 0 +set popup_ypix 0 + +## per toplevel/patch data +# store editmode for each open canvas, starting with a blank array +array set editmode {} + +#------------------------------------------------------------------------------# +# coding style +# +# these are preliminary ideas, we'll change them as we work things out: +# - when possible use "" doublequotes to delimit messages +# - use '$::myvar' instead of 'global myvar' +# - for the sake of clarity, there should not be any inline code, everything +# should be in a proc that is ultimately triggered from main() +# - if a menu_* proc opens a dialog panel, that proc is called menu_*_dialog +# - use "eq/ne" for string comparison, NOT "==/!=" (http://wiki.tcl.tk/15323) +# +## Names for Common Variables +#---------------------------- +# +# variables named after the Tk widgets they represent +# $mytoplevel = a window id made by a 'toplevel' command +# $mygfxstub = a window id made by a 'toplevel' command via gfxstub/x_gui.c +# $menubar = the 'menu' attached to each 'toplevel' +# $mymenu = 'menu' attached to the menubar +# $menuitem = 'menu' item +# $mycanvas = 'canvas' +# $canvasitem = 'canvas' item +# +# +## Prefix Names for procs +#---------------------------- +# pdtk_ pd -> pd-gui API (i.e. called from 'pd') +# pdsend pd-gui -> pd API (sends a message to 'pd' using pdsend) + +# ------------------------------------------------------------------------------ +# init functions + +proc set_pd_version {versionstring} { + regexp -- {.*([0-9])\.([0-9]+)[\.\-]([0-9]+)([^0-9]?.*)} $versionstring \ + wholematch \ + ::PD_MAJOR_VERSION ::PD_MINOR_VERSION ::PD_BUGFIX_VERSION ::PD_TEST_VERSION +} + +proc set_tcl_version {} { + regexp {([0-9])\.([0-9])\.([0-9]+)} [info patchlevel] \ + wholematch \ + ::TCL_MAJOR_VERSION ::TCL_MINOR_VERSION ::TCL_BUGFIX_VERSION +} + +# root paths to find Pd's files where they are installed +proc set_pd_paths {} { + set ::sys_guidir [file normalize [file dirname [info script]]] + set ::sys_libdir [file normalize [file join $::sys_guidir ".."]] +} + +proc init_for_platform {} { + # we are not using Tk scaling, so fix it to 1 on all platforms. This + # guarantees that patches will be pixel-exact on every platform + tk scaling 1 + + switch -- $::windowingsystem { + "x11" { + # add control to show/hide hidden files in the open panel (load + # the tk_getOpenFile dialog once, otherwise it will not work) + catch {tk_getOpenFile -with-invalid-argument} + set ::tk::dialog::file::showHiddenBtn 1 + set ::tk::dialog::file::showHiddenVar 0 + # set file types that open/save recognize + set ::filetypes \ + [list \ + [list [_ "Associated Files"] {.pd .pat .mxt} ] \ + [list [_ "Pd Files"] {.pd} ] \ + [list [_ "Max Patch Files"] {.pat} ] \ + [list [_ "Max Text Files"] {.mxt} ] \ + ] + } + "aqua" { + # set file types that open/save recognize + set ::filetypes \ + [list \ + [list [_ "Associated Files"] {.pd .pat .mxt} ] \ + [list [_ "Pd Files"] {.pd} ] \ + [list [_ "Max Patch Files (.pat)"] {.pat} ] \ + [list [_ "Max Text Files (.mxt)"] {.mxt} ] \ + ] + } + "win32" { + font create menufont -family Tahoma -size -11 + # set file types that open/save recognize + set ::filetypes \ + [list \ + [list [_ "Associated Files"] {.pd .pat .mxt} ] \ + [list [_ "Pd Files"] {.pd} ] \ + [list [_ "Max Patch Files"] {.pat} ] \ + [list [_ "Max Text Files"] {.mxt} ] \ + ] + } + } +} + +# ------------------------------------------------------------------------------ +# locale handling + +# official GNU gettext msgcat shortcut +if {[tk windowingsystem] ne "win32"} { + proc _ {s} {return [::msgcat::mc $s]} +} else { + proc _ {s} {return $s} +} + +proc load_locale {} { + if {[tk windowingsystem] ne "win32"} { + ::msgcat::mcload [file join [file dirname [info script]] .. po] + } + + # for Windows + #set locale "en" ;# Use whatever is right for your app + #if {[catch {package require registry}]} { + # tk_messageBox -icon error -message "Could not get locale from registry" + #} else { + # set locale [string tolower \ + # [string range \ + # [registry get {HKEY_CURRENT_USER\Control Panel\International} sLanguage] 0 1] ] + #} + + ##--moo: force default system and stdio encoding to UTF-8 + encoding system utf-8 + fconfigure stderr -encoding utf-8 + fconfigure stdout -encoding utf-8 + ##--/moo +} + +# ------------------------------------------------------------------------------ +# font handling + +# this proc gets the internal font name associated with each size +proc get_font_for_size {size} { + return "::pd_font_${size}" +} + +# searches for a font to use as the default. Tk automatically assigns a +# monospace font to the name "Courier" (see Tk 'font' docs), but it doesn't +# always do a good job of choosing in respect to Pd's needs. So this chooses +# from a list of fonts that are known to work well with Pd. +proc find_default_font {} { + set testfonts {Inconsolata "Courier New" "Liberation Mono" FreeMono \ + "DejaVu Sans Mono" "Bitstream Vera Sans Mono"} + foreach family $testfonts { + if {[lsearch -exact -nocase [font families] $family] > -1} { + set ::font_family $family + break + } + } + puts "DEFAULT FONT: $::font_family" +} + +proc set_base_font {family weight} { + if {[lsearch -exact [font families] $family] > -1} { + set ::font_family $family + } else { + pdtk_post [format \ + [_ "WARNING: Font family '%s' not found, using default (%s)"] \ + $family $::font_family] + } + if {[lsearch -exact {bold normal} $weight] > -1} { + set ::font_weight $weight + set using_defaults 0 + } else { + pdtk_post [format \ + [_ "WARNING: Font weight '%s' not found, using default (%s)"] \ + $weight $::font_weight] + } +} + +# creates all the base fonts (i.e. pd_font_8 thru pd_font_36) so that they fit +# into the metrics given by $::font_fixed_metrics for any given font/weight +proc fit_font_into_metrics {} { +# TODO the fonts picked seem too small, probably on fixed width + foreach {size width height} $::font_fixed_metrics { + set myfont [get_font_for_size $size] + font create $myfont -family $::font_family -weight $::font_weight \ + -size [expr {-$height}] + set height2 $height + set giveup 0 + while {[font measure $myfont M] > $width} { + incr height2 -1 + font configure $myfont -size [expr {-$height2}] + if {$height2 * 2 <= $height} { + set giveup 1 + break + } + } + if {$giveup} { + pdtk_post [format \ + [_ "ERROR: %s failed to find font size (%s) that fits into %sx%s!"]\ + [lindex [info level 0] 0] $size $width $height] + continue + } + } +} + + +# ------------------------------------------------------------------------------ +# procs called directly by pd + +# this is only called when 'pd' starts 'pd-gui', not the other way around +proc pdtk_pd_startup {versionstring audio_apis midi_apis sys_font sys_fontweight} { +# pdtk_post "-------------- pdtk_pd_startup ----------------" +# pdtk_post "version: $versionstring" +# pdtk_post "audio_apis: $audio_apis" +# pdtk_post "midi_apis: $midi_apis" +# pdtk_post "sys_font: $sys_font" +# pdtk_post "sys_fontweight: $sys_fontweight" + set oldtclversion 0 + pdsend "pd init [enquote_path [pwd]] $oldtclversion $::font_fixed_metrics" + set_pd_version $versionstring + set ::audioapi_list $audio_apis + set ::midiapi_list $midi_apis + if {$::tcl_version >= 8.5} {find_default_font} + set_base_font $sys_font $sys_fontweight + fit_font_into_metrics + # TODO what else is needed from the original? + set ::wait4pd "started" +} + +##### routine to ask user if OK and, if so, send a message on to Pd ###### +# TODO add 'mytoplevel' once merged to 0.43, with -parent +proc pdtk_check {message reply_to_pd default} { + # TODO this should use -parent and -title, but the hard part is figuring + # out how to get the values for those without changing g_editor.c + set answer [tk_messageBox -type yesno -icon question -default $default \ + -message [_ $message]] + if {$answer eq "yes"} { + pdsend $reply_to_pd + } +} + +proc pdtk_fixwindowmenu {} { + # TODO canvas_updatewindowlist() sets up the menu_windowlist with all of + # the parent CanvasWindows, we should then use [wm stackorder .] to get + # the rest of the CanvasWindows to make sure that all CanvasWindows are in + # the menu. This would probably be better handled on the C side of + # things, since then, the menu_windowlist could be built with the proper + # parent/child relationships. + # pdtk_post "Running pdtk_fixwindowmenu" +} + +# ------------------------------------------------------------------------------ +# X11 procs for handling singleton state and getting args from other instances + +# first instance +proc singleton {key} { + if {![catch { selection get -selection $key }]} { + return 0 + } + selection handle -selection $key . "singleton_request" + selection own -command first_lost -selection $key . + return 1 +} + +proc singleton_request {offset maxbytes} { + wm deiconify .pdwindow + raise .pdwindow + return [tk appname] +} + +proc first_lost {} { + receive_args [selection get -selection PUREDATA] + selection own -command first_lost -selection PUREDATA . + } + +# all other instances +proc send_args {offset maxChars} { + return [string range $::argv $offset [expr {$offset+$maxChars}]] +} + +proc others_lost {} { + set ::singleton_state "exit" + destroy . + exit +} + + +# ------------------------------------------------------------------------------ +# various startup related procs + +proc check_for_running_instances {argc argv} { + # pdtk_post "check_for_running_instances $argc $argv" + switch -- $::windowingsystem { + "aqua" { + # handled by ::tk::mac::OpenDocument in apple_events.tcl + } "x11" { + # http://wiki.tcl.tk/1558 + if {![singleton PUREDATA_MANAGER]} { + # other instances called by wish/pd-gui (exempt 'pd' by 5400 arg) + if {$argc == 1 && [string is int $argv] && $argv >= 5400} {return} + selection handle -selection PUREDATA . "send_args" + selection own -command others_lost -selection PUREDATA . + after 5000 set ::singleton_state "timeout" + vwait ::singleton_state + exit + } else { + # first instance + selection own -command first_lost -selection PUREDATA . + } + } "win32" { + ## http://wiki.tcl.tk/1558 + # TODO on Win: http://tcl.tk/man/tcl8.4/TclCmd/dde.htm + } + } +} + +# this command will open files received from a 2nd instance of Pd +proc receive_args args { + # pdtk_post "receive_files $args" + raise . + foreach filename $args { + open_file $filename + } +} + +proc load_startup {} { + global errorInfo +# TODO search all paths for startup.tcl + set startupdir [file normalize "$::sys_libdir/startup"] + # pdtk_post "load_startup $startupdir" + puts stderr "load_startup $startupdir" + if { ! [file isdirectory $startupdir]} { return } + foreach filename [glob -directory $startupdir -nocomplain -types {f} -- *.tcl] { + puts "Loading $filename" + set tclfile [open $filename] + set tclcode [read $tclfile] + close $tclfile + if {[catch {uplevel #0 $tclcode} errorname]} { + puts stderr "------------------------------------------------------" + puts stderr "UNHANDLED ERROR: $errorInfo" + puts stderr "FAILED TO LOAD $filename" + puts stderr "------------------------------------------------------" + } + } +} + +# ------------------------------------------------------------------------------ +# main +proc main {argc argv} { + # TODO Tcl/Tk 8.3 doesn't have [tk windowingsystem] + set ::windowingsystem [tk windowingsystem] + tk appname pd-gui + load_locale + check_for_running_instances $argc $argv + set_pd_paths + init_for_platform + # post_tclinfo + + # set a timeout for how long 'pd-gui' should wait for 'pd' to start + after 20000 set ::wait4pd "timeout" + # TODO check args for -stderr and set pdtk_post accordingly + if {$argc == 1 && [string is int $argv] && $argv >= 5400} { + # 'pd' started first and launched us, so get the port to connect to + ::pd_connect::to_pd [lindex $argv 0] + } else { + # the GUI is starting first, so create socket and exec 'pd' + set portnumber [::pd_connect::create_socket] + set pd_exec [file join [file dirname [info script]] ../bin/pd] + exec -- $pd_exec -guiport $portnumber & + } + # wait for 'pd' to call pdtk_pd_startup, or exit on timeout + vwait ::wait4pd + if {$::wait4pd eq "timeout"} { + puts stderr [_ "ERROR: 'pd' never showed up, 'pd-gui' quitting!"] + exit 2 + } + ::pd_bindings::class_bindings + ::pd_menus::create_menubar + ::pdtk_canvas::create_popup + ::pdwindow::create_window + ::pd_menus::configure_for_pdwindow + load_startup + # pdtk_post "------------------ done with main ----------------------" +} + +main $::argc $::argv + + + + + + diff --git a/pd/tcl/pd.tcl b/pd/tcl/pd.tcl deleted file mode 100644 index 0418dcd8..00000000 --- a/pd/tcl/pd.tcl +++ /dev/null @@ -1,315 +0,0 @@ -#!/bin/sh -# This line continues for Tcl, but is a single line for 'sh' \ - exec wish "$0" -- ${1+"$@"} -# For information on usage and redistribution, and for a DISCLAIMER OF ALL -# WARRANTIES, see the file, "LICENSE.txt," in this distribution. -# Copyright (c) 1997-2009 Miller Puckette. - -# puts -------------------------------pd.tcl----------------------------------- - -package require Tcl 8.3 -package require Tk -if {[tk windowingsystem] ne "win32"} {package require msgcat} - -# Pd's packages are stored in the same directory as the main script (pd.tcl) -set auto_path [linsert $auto_path 0 [file dirname [info script]]] -package require pd_connect -package require pd_menus -package require pd_bindings -package require dialog_font -package require dialog_gatom -package require dialog_iemgui -package require pdtk_array -package require pdtk_canvas -package require pdtk_text -# TODO eliminate this kludge: -package require wheredoesthisgo - -# import into the global namespace for backwards compatibility -namespace import ::pd_connect::pdsend -namespace import ::dialog_font::pdtk_canvas_dofont -namespace import ::dialog_gatom::pdtk_gatom_dialog -namespace import ::dialog_iemgui::pdtk_iemgui_dialog - -#------------------------------------------------------------------------------# -# global variables - -# for testing which platform we are running on ("aqua", "win32", or "x11") -set windowingsystem "" - -# canvas font, received from pd in pdtk_pd_startup, set in s_main.c -set font_family "Courier" -set font_weight "bold" -# sizes of chars for each of the Pd fixed font sizes: -# fontsize width(pixels) height(pixels) -set font_fixed_metrics { - 8 5 10 - 9 6 11 - 10 6 13 - 12 7 15 - 14 8 17 - 16 10 20 - 18 11 22 - 24 14 30 - 30 18 37 - 36 22 45 -} - -# store list of parent windows for Window menu -set menu_windowlist {} - -#------------------------------------------------------------------------------# -# coding style -# -# these are preliminary ideas, we'll change them as we work things out: -# - when possible use "" doublequotes to delimit messages -# - use '$::myvar' instead of 'global myvar' -# - for the sake of clarity, there should not be any inline code, everything -# should be in a proc that is ultimately triggered from main() -# - if a menu_* proc opens a panel, that proc is called menu_*_panel -# - use "eq/ne" for string comparison, NOT "==/!=" -# -## Names for Common Variables -#---------------------------- -# -# variables named after the Tk widgets they represent -# $mytoplevel = 'toplevel' -# $mymenubar = the 'menu' attached to the 'toplevel' -# $mymenu = 'menu' attached to the menubar 'menu' -# $menuitem = 'menu' item -# $mycanvas = 'canvas' -# $canvasitem = 'canvas' item -# -# -## Prefix Names for procs -#---------------------------- -# pdtk pd -> pd-gui API (i.e. called from 'pd') -# pdsend pd-gui -> pd API (sends a message to 'pd' using pdsend) -# canvas manipulates a canvas -# text manipulates a Tk 'text' widget - -# ------------------------------------------------------------------------------ -# init functions - -proc init {} { - # we are not using Tk scaling, so fix it to 1 on all platforms. This - # guarantees that patches will be pixel-exact on every platform - tk scaling 1 - - # TODO Tcl/Tk 8.3 doesn't have [tk windowingsystem] - set ::windowingsystem [tk windowingsystem] - # get the versions for later testing - regexp {([0-9])\.([0-9])\.([0-9]+)} [info patchlevel] \ - wholematch ::tcl_major ::tcl_minor ::tcl_patch - switch -- $::windowingsystem { - "x11" { - # add control to show/hide hidden files in the open panel (load - # the tk_getOpenFile dialog once, otherwise it will not work) - catch {tk_getOpenFile -with-invalid-argument} - set ::tk::dialog::file::showHiddenBtn 1 - set ::tk::dialog::file::showHiddenVar 0 - # set file types that open/save recognize - set ::filetypes { - {{pd files} {.pd} } - {{max patch files} {.pat} } - {{max text files} {.mxt} } - } - } - "aqua" { - # set file types that open/save recognize - set ::filetypes { - {{Pd Files} {.pd} } - {{Max Patch Files (.pat)} {.pat} } - {{Max Text Files (.mxt)} {.mxt} } - } - } - "win32" { - font create menufont -family Tahoma -size -11 - # set file types that open/save recognize - set ::filetypes { - {{Pd Files} {.pd} } - {{Max Patch Files} {.pat} } - {{Max Text Files} {.mxt} } - } - } - } -} - -# official GNU gettext msgcat shortcut -if {[tk windowingsystem] ne "win32"} { - proc _ {s} {return [::msgcat::mc $s]} -} else { - proc _ {s} {return $s} -} - -proc load_locale {} { - ::msgcat::mcload [file join [file dirname [info script]] locale] - - # for Windows - #set locale "en" ;# Use whatever is right for your app - #if {[catch {package require registry}]} { - # tk_messageBox -icon error -message "Could not get locale from registry" - #} else { - # set locale [string tolower \ - # [string range \ - # [registry get {HKEY_CURRENT_USER\Control Panel\International} sLanguage] 0 1] ] - #} - - ##--moo: force default system and stdio encoding to UTF-8 - encoding system utf-8 - fconfigure stderr -encoding utf-8 - fconfigure stdout -encoding utf-8 - ##--/moo -} - -# ------------------------------------------------------------------------------ -# font handling - -# this proc gets the internal font name associated with each size -proc get_font_for_size {size} { - return "pd_font_${size}" -} - -proc set_base_font {family weight} { - if {[lsearch -exact [font families] $family] > -1} { - set ::font_family $family - } else { - puts stderr "Error: Font family \"$family\" not found, using default: $::font_family" - } - if {[lsearch -exact {bold normal} $weight] > -1} { - set ::font_weight $weight - set using_defaults 0 - } else { - puts stderr "Error: Font weight \"$weight\" not found, using default: $::font_weight" - } - puts stderr "Using FONT $::font_family $::font_weight" -} - -# creates all the base fonts (i.e. pd_font_8 thru pd_font_36) so that they fit -# into the metrics given by $::font_fixed_metrics for any given font/weight -proc fit_font_into_metrics {} { -# TODO the fonts picked seem too small, probably on fixed width - foreach {size width height} $::font_fixed_metrics { - set myfont [get_font_for_size $size] - font create $myfont -family $::font_family -weight $::font_weight \ - -size [expr {-$height}] - set height2 $height - set giveup 0 - while {[font measure $myfont M] > $width} { - incr height2 -1 - font configure $myfont -size [expr {-$height2}] - if {$height2 * 2 <= $height} { - set giveup 1 - puts "error: [lindex [info level 0] 0] failed to find a font of size $size fitting into a $width x $height cell! this system sucks" - break - } - } - if {$giveup} {continue} - } -} - - -# ------------------------------------------------------------------------------ -# procs called directly by pd - -proc pdtk_pd_startup {version {args ""}} { - # pdtk_post "pdtk_pd_startup $version $args" - # pdtk_post "\tversion: $version" - # pdtk_post "\targs: $args" - set oldtclversion 0 - pdsend "pd init [enquote_path [pwd]] $oldtclversion $::font_fixed_metrics" - set_base_font [lindex $args 2] [lindex $args 3] - fit_font_into_metrics - # TODO what else is needed from the original? -} - -##### routine to ask user if OK and, if so, send a message on to Pd ###### -proc pdtk_check {ignoredarg message reply_to_pd default} { - # TODO this should use -parent and -title, but the hard part is figuring - # out how to get the values for those without changing g_editor.c - set answer [tk_messageBox -type yesno -icon question \ - -default $default -message $message] - if {$answer eq "yes"} { - pdsend $reply_to_pd - } -} - -proc pdtk_fixwindowmenu {} { - #TODO figure out how to do this cleanly - puts stderr "Running pdtk_fixwindowmenu" -} - -# ------------------------------------------------------------------------------ -# procs called directly by pd - -proc check_for_running_instances {} { -## http://tcl.tk/man/tcl8.4/TkCmd/send.htm -## This script fragment can be used to make an application that only -## runs once on a particular display. -# -#if {[tk appname FoobarApp] ne "FoobarApp"} { -# send -async FoobarApp RemoteStart $argv -# exit -#} -## The command that will be called remotely, which raises -## the application main window and opens the requested files -#proc RemoteStart args { -# raise . -# foreach filename $args { -# OpenFile $filename -# } -#} -} - -proc load_startup {} { - global errorInfo - set pd_guidir "[pwd]/../startup" - # puts stderr "load_startup $pd_guidir" - if { ! [file isdirectory $pd_guidir]} { return } - foreach filename [glob -directory $pd_guidir -nocomplain -types {f} -- *.tcl] { - puts "Loading $filename" - set tclfile [open $filename] - set tclcode [read $tclfile] - close $tclfile - if {[catch {uplevel #0 $tclcode} errorname]} { - puts stderr "------------------------------------------------------" - puts stderr "UNHANDLED ERROR: $errorInfo" - puts stderr "FAILED TO LOAD $filename" - puts stderr "------------------------------------------------------" - } - } -} - -# ------------------------------------------------------------------------------ -# main -proc main {argc argv} { - catch {console show} ;# Not all platforms have the console command - post_tclinfo - pdtk_post "Starting pd.tcl with main($argc $argv)" - check_for_running_instances - if {[tk windowingsystem] ne "win32"} {load_locale} - init - - # TODO check args for -stderr and set pdtk_post accordingly - if { $argc == 1 && [string is int [lindex $argv 0]]} { - # 'pd' started first and launched us, so get the port to connect to - ::pd_connect::to_pd [lindex $argv 0] - } else { - # the GUI is starting first, so create socket and exec 'pd' - set portnumber [::pd_connect::create_socket] - set pd_exec [file join [file dirname [info script]] ../bin/pd] - exec -- $pd_exec -guiport $portnumber & - #TODO add vwait so that pd-gui will exit if pd never shows up - } - ::pd_bindings::class_bindings - create_pdwindow - load_startup -} - -main $::argc $::argv - - - - - - diff --git a/pd/tcl/pd_bindings.tcl b/pd/tcl/pd_bindings.tcl index 6ea91187..0cef0474 100644 --- a/pd/tcl/pd_bindings.tcl +++ b/pd/tcl/pd_bindings.tcl @@ -7,24 +7,34 @@ namespace eval ::pd_bindings:: { variable modifier namespace export window_bindings - namespace export panel_bindings + namespace export dialog_bindings namespace export canvas_bindings } +# the commands are bound using "" quotations so that the $mytoplevel is +# interpreted immediately. Since the command is being bound to $mytoplevel, +# it makes sense to have value of $mytoplevel already in the command. This is +# the opposite of the menu commands in pd_menus.tcl + +# binding by class is not recursive, so its useful for certain things proc ::pd_bindings::class_bindings {} { - # binding by class is not recursive, so its useful for certain things + # and the Pd window is in a class to itself + bind PdWindow <Configure> "::pd_bindings::window_configure %W" + bind PdWindow <FocusIn> "::pd_bindings::window_focusin %W" + # bind to all the canvas windows bind CanvasWindow <Map> "::pd_bindings::map %W" bind CanvasWindow <Unmap> "::pd_bindings::unmap %W" bind CanvasWindow <Configure> "::pd_bindings::window_configure %W" bind CanvasWindow <FocusIn> "::pd_bindings::window_focusin %W" - bind CanvasWindow <Activate> "::pd_bindings::window_focusin %W" + # bindings for dialog windows, which behave differently than canvas windows + bind DialogWindow <Configure> "::pd_bindings::dialog_configure %W" + bind DialogWindow <FocusIn> "::pd_bindings::dialog_focusin %W" } proc ::pd_bindings::window_bindings {mytoplevel} { variable modifier # for key bindings - # puts "::windowingsystem $::windowingsystem" if {$::windowingsystem eq "aqua"} { set modifier "Mod1" } else { @@ -33,7 +43,7 @@ proc ::pd_bindings::window_bindings {mytoplevel} { # File menu bind $mytoplevel <$modifier-Key-b> "menu_helpbrowser" - bind $mytoplevel <$modifier-Key-f> "::dialog_find::menu_dialog_find $mytoplevel" + bind $mytoplevel <$modifier-Key-f> "::dialog_find::menu_find_dialog $mytoplevel" bind $mytoplevel <$modifier-Key-n> "menu_new" bind $mytoplevel <$modifier-Key-o> "menu_open" bind $mytoplevel <$modifier-Key-p> "menu_print $mytoplevel" @@ -54,34 +64,46 @@ proc ::pd_bindings::pdwindow_bindings {mytoplevel} { window_bindings $mytoplevel # TODO update this to work with the console, if it is used - bind $mytoplevel <$modifier-Key-a> ".printout.text tag add sel 1.0 end" - bind $mytoplevel <$modifier-Key-x> "tk_textCut .printout.text" - bind $mytoplevel <$modifier-Key-c> "tk_textCopy .printout.text" - bind $mytoplevel <$modifier-Key-v> "tk_textPaste .printout.text" - bind $mytoplevel <$modifier-Key-w> { } + bind $mytoplevel <$modifier-Key-a> ".pdwindow.text tag add sel 1.0 end" + bind $mytoplevel <$modifier-Key-x> "tk_textCut .pdwindow.text" + bind $mytoplevel <$modifier-Key-c> "tk_textCopy .pdwindow.text" + bind $mytoplevel <$modifier-Key-v> "tk_textPaste .pdwindow.text" + bind $mytoplevel <$modifier-Key-w> "wm iconify $mytoplevel" + + if {$::windowingsystem eq "aqua"} { + bind $mytoplevel <$modifier-Key-m> "menu_minimize $mytoplevel" + bind $mytoplevel <$modifier-Key-t> "menu_font_dialog $mytoplevel" + bind $mytoplevel <$modifier-quoteleft> "menu_raisenextwindow" + } else { + bind $mytoplevel <$modifier-Key-m> "menu_message_dialog" + bind $mytoplevel <$modifier-Key-t> "menu_texteditor" + } # Tcl event bindings wm protocol $mytoplevel WM_DELETE_WINDOW "pdsend \"pd verifyquit\"" - - # do window maintenance when entering the Pd window (Window menu, scrollbars, etc) - # bind $mytoplevel <FocusIn> "::pd_bindings::window_focusin %W" } -# this is for the panels: find, font, sendmessage, gatom properties, array +# this is for the dialogs: find, font, sendmessage, gatom properties, array # properties, iemgui properties, canvas properties, data structures # properties, Audio setup, and MIDI setup -proc ::pd_bindings::panel_bindings {mytoplevel panelname} { +proc ::pd_bindings::dialog_bindings {mytoplevel dialogname} { variable modifier window_bindings $mytoplevel - bind $mytoplevel <KeyPress-Escape> [format "%s_cancel %s" $panelname $mytoplevel] - bind $mytoplevel <KeyPress-Return> [format "%s_ok %s" $panelname $mytoplevel] - bind $mytoplevel <$modifier-Key-w> [format "%s_cancel %s" $panelname $mytoplevel] - - wm protocol $mytoplevel WM_DELETE_WINDOW "${panelname}_cancel $mytoplevel" + bind $mytoplevel <KeyPress-Escape> "dialog_${dialogname}::cancel $mytoplevel" + bind $mytoplevel <KeyPress-Return> "dialog_${dialogname}::ok $mytoplevel" + bind $mytoplevel <$modifier-Key-w> "dialog_${dialogname}::cancel $mytoplevel" - bind $mytoplevel <FocusIn> "::pd_bindings::panel_focusin %W" + $mytoplevel configure -padx 10 -pady 5 + wm group $mytoplevel . + wm resizable $mytoplevel 0 0 + wm protocol $mytoplevel WM_DELETE_WINDOW "dialog_${dialogname}::cancel $mytoplevel" + catch { # not all platforms/Tcls versions have these options + wm attributes $mytoplevel -topmost 1 + #wm attributes $mytoplevel -transparent 1 + #$mytoplevel configure -highlightthickness 1 + } } proc ::pd_bindings::canvas_bindings {mytoplevel} { @@ -106,8 +128,6 @@ proc ::pd_bindings::canvas_bindings {mytoplevel} { bind $mytoplevel <$modifier-Key-w> "pdsend \"$mytoplevel menuclose 0\"" bind $mytoplevel <$modifier-Key-x> "pdsend \"$mytoplevel cut\"" bind $mytoplevel <$modifier-Key-z> "menu_undo $mytoplevel" - bind $mytoplevel <$modifier-Key-slash> "pdsend \"pd dsp 1\"" - bind $mytoplevel <$modifier-Key-period> "pdsend \"pd dsp 0\"" # annoying, but Tk's bind needs uppercase letter to get the Shift bind $mytoplevel <$modifier-Shift-Key-B> "pdsend \"$mytoplevel bng 1\"" @@ -125,46 +145,48 @@ proc ::pd_bindings::canvas_bindings {mytoplevel} { if {$::windowingsystem eq "aqua"} { bind $mytoplevel <$modifier-Key-m> "menu_minimize $mytoplevel" - bind $mytoplevel <$modifier-Key-t> "menu_dialog_font $mytoplevel" - bind $mytoplevel <$modifier-quoteleft> "menu_raisenextwindow" + bind $mytoplevel <$modifier-Key-t> "menu_font_dialog $mytoplevel" + bind $mytoplevel <$modifier-quoteleft> "menu_raisenextwindow" } else { - bind $mytoplevel <$modifier-Key-m> "menu_message_panel" + bind $mytoplevel <$modifier-Key-m> "menu_message_dialog" bind $mytoplevel <$modifier-Key-t> "menu_texteditor" } - - bind $mycanvas <Key> "pdsend_key %W 1 %K %A 0" - bind $mycanvas <Shift-Key> "pdsend_key %W 1 %K %A 1" - bind $mycanvas <KeyRelease> "pdsend_key %W 0 %K %A 0" + bind $mytoplevel <KeyPress> "::pd_bindings::sendkey %W 1 %K %A 0" + bind $mytoplevel <KeyRelease> "::pd_bindings::sendkey %W 0 %K %A 0" + bind $mytoplevel <Shift-KeyPress> "::pd_bindings::sendkey %W 1 %K %A 1" + bind $mytoplevel <Shift-KeyRelease> "::pd_bindings::sendkey %W 0 %K %A 1" # mouse bindings ----------------------------------------------------------- - # these need to be bound to $mytoplevel.c because %W will return $mytoplevel for + # these need to be bound to $mycanvas because %W will return $mytoplevel for # events over the window frame and $mytoplevel.c for events over the canvas - bind $mycanvas <Motion> "pdtk_canvas_motion %W %x %y 0" - bind $mycanvas <Button-1> "pdtk_canvas_mouse %W %x %y %b 0" - bind $mycanvas <ButtonRelease-1> "pdtk_canvas_mouseup %W %x %y %b" - bind $mycanvas <$modifier-Button-1> "pdtk_canvas_mouse %W %x %y %b 2" + bind $mycanvas <Motion> "pdtk_canvas_motion %W %x %y 0" + bind $mycanvas <$modifier-Motion> "pdtk_canvas_motion %W %x %y 2" + bind $mycanvas <ButtonPress-1> "pdtk_canvas_mouse %W %x %y %b 0" + bind $mycanvas <ButtonRelease-1> "pdtk_canvas_mouseup %W %x %y %b" + bind $mycanvas <$modifier-ButtonPress-1> "pdtk_canvas_mouse %W %x %y %b 2" # TODO look into "virtual events' for a means for getting Shift-Button, etc. switch -- $::windowingsystem { "aqua" { - bind $mycanvas <Button-2> "pdtk_canvas_rightclick %W %x %y %b" + bind $mycanvas <ButtonPress-2> "pdtk_canvas_rightclick %W %x %y %b" # on Mac OS X, make a rightclick with Ctrl-click for 1 button mice bind $mycanvas <Control-Button-1> "pdtk_canvas_rightclick %W %x %y %b" # TODO try replacing the above with this #bind all <Control-Button-1> {event generate %W <Button-2> \ - # -x %x -y %y -rootx %X -rooty %Y \ - # -button 2 -time %t} + # -x %x -y %y -rootx %X -rooty %Y \ + # -button 2 -time %t} } "x11" { - bind $mycanvas <Button-3> "pdtk_canvas_rightclick %W %x %y %b" + bind $mycanvas <ButtonPress-3> "pdtk_canvas_rightclick %W %x %y %b" # on X11, button 2 "pastes" from the X windows clipboard - bind $mycanvas <Button-2> "pdtk_canvas_clickpaste %W %x %y %b" + bind $mycanvas <ButtonPress-2> "pdtk_canvas_clickpaste %W %x %y %b" } "win32" { - bind $mycanvas <Button-3> "pdtk_canvas_rightclick %W %x %y %b" + bind $mycanvas <ButtonPress-3> "pdtk_canvas_rightclick %W %x %y %b" } } #TODO bind $mytoplevel <MouseWheel> # window protocol bindings wm protocol $mytoplevel WM_DELETE_WINDOW "pdsend \"$mytoplevel menuclose 0\"" + bind $mycanvas <Destroy> "::pd_bindings::window_destroy %W" } @@ -175,27 +197,67 @@ proc ::pd_bindings::window_configure {mytoplevel} { pdtk_canvas_getscroll $mytoplevel } +proc ::pd_bindings::window_destroy {mycanvas} { + set mytoplevel [winfo toplevel $mycanvas] + unset ::editmode($mytoplevel) +} + # do tasks when changing focus (Window menu, scrollbars, etc.) proc ::pd_bindings::window_focusin {mytoplevel} { + # pdtk_post "::pd_bindings::window_focusin $mytoplevel" + set ::focused_window $mytoplevel ::dialog_find::set_canvas_to_search $mytoplevel ::pd_menucommands::set_menu_new_dir $mytoplevel + ::dialog_font::update_font_dialog $mytoplevel + if {$mytoplevel eq ".pdwindow"} { + ::pd_menus::configure_for_pdwindow + } else { + ::pd_menus::configure_for_canvas $mytoplevel + } # TODO handle enabling/disabling the Undo and Redo menu items in Edit # TODO handle enabling/disabling the Cut/Copy/Paste menu items in Edit - # TODO enable menu items that the Pd window or panels might have disabled + # TODO enable menu items that the Pd window or dialogs might have disabled + # TODO update "Open Recent" menu } -proc ::pd_bindings::panel_focusin {mytoplevel} { - # TODO disable things on the menus that don't work for panels +proc ::pd_bindings::dialog_configure {mytoplevel} { +} + +proc ::pd_bindings::dialog_focusin {mytoplevel} { + # TODO disable things on the menus that don't work for dialogs + ::pd_menus::configure_for_dialog $mytoplevel } # "map" event tells us when the canvas becomes visible, and "unmap", # invisible. Invisibility means the Window Manager has minimized us. We # don't get a final "unmap" event when we destroy the window. proc ::pd_bindings::map {mytoplevel} { - # puts "map $mytoplevel [wm title $mytoplevel]" pdsend "$mytoplevel map 1" } proc ::pd_bindings::unmap {mytoplevel} { pdsend "$mytoplevel map 0" } + + +#------------------------------------------------------------------------------# +# key usage + +proc ::pd_bindings::sendkey {mycanvas state key iso shift} { + # TODO canvas_key on the C side should be refactored with this proc as well + switch -- $key { + "BackSpace" { set iso ""; set key 8 } + "Tab" { set iso ""; set key 9 } + "Return" { set iso ""; set key 10 } + "Escape" { set iso ""; set key 27 } + "Space" { set iso ""; set key 32 } + "Delete" { set iso ""; set key 127 } + "KP_Delete" { set iso ""; set key 127 } + } + if {$iso ne ""} { + scan $iso %c key + } + puts "::pd_bindings::sendkey {%W:$mycanvas $state %K$key %A$iso $shift}" + # $mycanvas might be a toplevel, but [winfo toplevel] does the right thing + pdsend "[winfo toplevel $mycanvas] key $state $key $shift" +} diff --git a/pd/tcl/pd_connect.tcl b/pd/tcl/pd_connect.tcl index 6d900068..cdd3d91d 100644 --- a/pd/tcl/pd_connect.tcl +++ b/pd/tcl/pd_connect.tcl @@ -9,6 +9,8 @@ namespace eval ::pd_connect:: { namespace export pdsend } +# TODO figure out how to escape { } properly + proc ::pd_connect::configure_socket {sock} { fconfigure $sock -blocking 0 -buffering line -encoding utf-8; fileevent $sock readable {::pd_connect::pd_readsocket ""} @@ -65,7 +67,7 @@ proc ::pd_connect::pd_readsocket {cmd_from_pd} { } append cmd_from_pd [read $pd_socket] while {![info complete $cmd_from_pd] || \ - [string index $cmd_from_pd end] != "\n"} { + [string index $cmd_from_pd end] ne "\n"} { append cmd_from_pd [read $pd_socket] if {[eof $pd_socket]} { close $pd_socket diff --git a/pd/tcl/pd_menucommands.tcl b/pd/tcl/pd_menucommands.tcl index 6530c52a..e1373b84 100644 --- a/pd/tcl/pd_menucommands.tcl +++ b/pd/tcl/pd_menucommands.tcl @@ -16,7 +16,8 @@ proc ::pd_menucommands::menu_new {} { variable untitled_number variable menu_new_dir if { ! [file isdirectory $menu_new_dir]} {set menu_new_dir $::env(HOME)} - pdsend "pd filename Untitled-$untitled_number [enquote_path $menu_new_dir]" + set untitled_name [_ "Untitled"] + pdsend "pd filename $untitled_name-$untitled_number [enquote_path $menu_new_dir]" pdsend "#N canvas" pdsend "#X pop 1" incr untitled_number @@ -31,7 +32,6 @@ proc ::pd_menucommands::menu_open {} { -initialdir $menu_open_dir] if {$files ne ""} { foreach filename $files { - puts "open_file $filename" open_file $filename } set menu_open_dir [file dirname $filename] @@ -40,14 +40,14 @@ proc ::pd_menucommands::menu_open {} { proc ::pd_menucommands::menu_print {mytoplevel} { set filename [tk_getSaveFile -initialfile pd.ps \ - -defaultextension .ps \ - -filetypes { {{postscript} {.ps}} }] - if {$filename != ""} { - $mytoplevel.c postscript -file $filename + -defaultextension .ps \ + -filetypes { {{postscript} {.ps}} }] + if {$filename ne ""} { + $mytoplevel.c postscript -file $filename } } -# panel types: +# dialog types: # global (only one): find, sendmessage, prefs, helpbrowser # per-canvas: font, canvas properties (created with a message from pd) # per object: gatom, iemgui, array, data structures (created with a message from pd) @@ -57,61 +57,56 @@ proc ::pd_menucommands::menu_print {mytoplevel} { # functions called from Edit menu proc menu_undo {mytoplevel} { - puts stderr "menu_undo $mytoplevel not implemented yet" + # puts stderr "menu_undo $mytoplevel not implemented yet" } proc menu_redo {mytoplevel} { - puts stderr "menu_redo $mytoplevel not implemented yet" + # puts stderr "menu_redo $mytoplevel not implemented yet" } # ------------------------------------------------------------------------------ -# open the panels +# open the dialog panels -proc ::pd_menucommands::menu_message_panel {} { +proc ::pd_menucommands::menu_message_dialog {} { if {[winfo exists .send_message]} { wm deiconify .send_message raise .message } else { # TODO insert real message panel here toplevel .send_message + wm group .send_message . wm title .send_message [_ "Send Message..."] wm resizable .send_message 0 0 - ::pd_bindings::panel_bindings .send_message "send_message" + ::pd_bindings::dialog_bindings .send_message "send_message" frame .send_message.frame - label .send_message.label -text "message" -width 30 -height 15 + label .send_message.label -text [_ "Message"] -width 30 -height 15 pack .send_message.label .send_message.frame -side top -expand yes -fill both } } - -proc ::pd_menucommands::menu_dialog_font {mytoplevel} { +proc ::pd_menucommands::menu_font_dialog {mytoplevel} { if {[winfo exists .font]} { - wm deiconify .font raise .font + } elseif {$mytoplevel eq ".pdwindow"} { + pdtk_canvas_dofont .pdwindow [lindex [.pdwindow.text cget -font] 1] } else { - # TODO insert real preference panel here - toplevel .font - wm title .font [_ "Font"] - ::pd_bindings::panel_bindings .font "font" - frame .font.frame - label .font.label -text "font" -width 30 -height 15 - pack .font.label .font.frame -side top -expand yes -fill both + pdsend "$mytoplevel menufont" } } -proc ::pd_menucommands::menu_path_panel {} { +proc ::pd_menucommands::menu_path_dialog {} { if {[winfo exists .path]} { - raise .path + raise .path } else { - pdsend "pd start-path-dialog" + pdsend "pd start-path-dialog" } } -proc ::pd_menucommands::menu_startup_panel {} { +proc ::pd_menucommands::menu_startup_dialog {} { if {[winfo exists .startup]} { - raise .startup + raise .startup } else { - pdsend "pd start-startup-dialog" + pdsend "pd start-startup-dialog" } } @@ -127,13 +122,12 @@ proc ::pd_menucommands::menu_maximize {mytoplevel} { } proc menu_raise_pdwindow {} { - set pd_window . - set top_window [lindex [wm stackorder $pd_window] end] - if {$pd_window eq $top_window} { - lower $pd_window + set top_window [lindex [wm stackorder .pdwindow] end] + if {.pdwindow eq $top_window} { + lower .pdwindow } else { - wm deiconify $pd_window - raise $pd_window + wm deiconify .pdwindow + raise .pdwindow } } @@ -143,15 +137,73 @@ proc menu_raise_pdwindow {} { # this gets the dir from the path of a window's title proc ::pd_menucommands::set_menu_new_dir {mytoplevel} { variable menu_new_dir + variable menu_open_dir # TODO add Aqua specifics once g_canvas.c has [wm attributes -titlepath] - if {$mytoplevel eq "."} { - set menu_new_dir [pwd] + if {$mytoplevel eq ".pdwindow"} { + # puts "set_menu_new_dir $mytoplevel" + set menu_new_dir $menu_open_dir } else { regexp -- ".+ - (.+)" [wm title $mytoplevel] ignored menu_new_dir } } # ------------------------------------------------------------------------------ +# opening docs as menu items (like the Test Audio and MIDI patch and the manual) +proc ::pd_menucommands::menu_doc_open {subdir basename} { + set dirname "$::sys_libdir/$subdir" + + switch -- [string tolower [file extension $basename]] { + ".txt" {::pd_menucommands::menu_opentext "$dirname/$basename" + } ".c" {::pd_menucommands::menu_opentext "$dirname/$basename" + } ".htm" {::pd_menucommands::menu_openhtml "$dirname/$basename" + } ".html" {::pd_menucommands::menu_openhtml "$dirname/$basename" + } default { + pdsend "pd open [enquote_path $basename] [enquote_path $dirname]" + } + } +} + +# open text docs in a Pd window +proc ::pd_menucommands::menu_opentext {filename} { + global pd_myversion + set mytoplevel [format ".help%d" [clock seconds]] + toplevel $mytoplevel -class TextWindow + text $mytoplevel.text -relief flat -borderwidth 0 \ + -yscrollcommand "$mytoplevel.scroll set" -background white + scrollbar $mytoplevel.scroll -command "$mytoplevel.text yview" + pack $mytoplevel.scroll -side right -fill y + pack $mytoplevel.text -side left -fill both -expand 1 + ::pd_bindings::window_bindings $mytoplevel + + set textfile [open $filename] + while {![eof $textfile]} { + set bigstring [read $textfile 1000] + regsub -all PD_BASEDIR $bigstring $::sys_guidir bigstring2 + regsub -all PD_VERSION $bigstring2 $pd_myversion bigstring3 + $mytoplevel.text insert end $bigstring3 + } + close $textfile +} + +# open HTML docs from the menu using the OS-default HTML viewer +proc ::pd_menucommands::menu_openhtml {filename} { + if {$::tcl_platform(os) eq "Darwin"} { + exec sh -c [format "open '%s'" $filename] + } elseif {$::tcl_platform(platform) eq "windows"} { + exec rundll32 url.dll,FileProtocolHandler [format "%s" $filename] & + } else { + foreach candidate { gnome-open xdg-open sensible-browser iceweasel firefox \ + mozilla galeon konqueror netscape lynx } { + set browser [lindex [auto_execok $candidate] 0] + if {[string length $browser] != 0} { + exec -- sh -c [format "%s '%s'" $browser $filename] & + break + } + } + } +} + +# ------------------------------------------------------------------------------ # Mac OS X specific functions proc ::pd_menucommands::menu_bringalltofront {} { diff --git a/pd/tcl/pd_menus.tcl b/pd/tcl/pd_menus.tcl index f8dc2469..99b6be94 100644 --- a/pd/tcl/pd_menus.tcl +++ b/pd/tcl/pd_menus.tcl @@ -9,10 +9,15 @@ package require Tk ## replace Tk widgets with Ttk widgets on 8.5 #namespace import -force ttk::* -# TODO figure out Undo/Redo/Cut/Copy/Paste/DSP state changes for menus +# TODO figure out Undo/Redo/Cut/Copy/Paste state changes for menus # TODO figure out parent window/window list for Window menu # TODO what is the Tcl package constructor or init()? +# TODO $::pd_menus::menubar or .menubar globally? +# since there is one menubar that is used for all windows, the menu -commands +# use {} quotes so that $::focused_window is interpreted when the menu item +# is called, not when the command is mapped to the menu item. This is the +# opposite of the 'bind' commands in pd_bindings.tcl # ------------------------------------------------------------------------------ @@ -23,9 +28,13 @@ namespace import ::pd_menucommands::* namespace eval ::pd_menus:: { variable accelerator + variable menubar ".menubar" + variable current_toplevel ".pdwindow" namespace export create_menubar - namespace export configure_pdwindow + namespace export configure_for_pdwindow + namespace export configure_for_canvas + namespace export configure_for_dialog # turn off tearoff menus globally option add *tearOff 0 @@ -33,210 +42,315 @@ namespace eval ::pd_menus:: { # ------------------------------------------------------------------------------ # -proc ::pd_menus::create_menubar {mymenubar mytoplevel} { +proc ::pd_menus::create_menubar {} { variable accelerator + variable menubar if {$::windowingsystem eq "aqua"} { set accelerator "Cmd" } else { set accelerator "Ctrl" } - menu $mymenubar + menu $menubar set menulist "file edit put find media window help" - if { $::windowingsystem eq "aqua" } {create_apple_menu $mymenubar} -#TODO figure out why this took my menubars out? -msp -# if { $::windowingsystem eq "win32" } {create_system_menu $mymenubar} - foreach mymenu $menulist { - menu $mymenubar.$mymenu - $mymenubar add cascade -label [_ [string totitle $mymenu]] \ - -menu $mymenubar.$mymenu - [format build_%s_menu $mymenu] $mymenubar.$mymenu $mytoplevel + if { $::windowingsystem eq "aqua" } {create_apple_menu $menubar} + # FIXME why does the following (if uncommented) kill my menubar? + # if { $::windowingsystem eq "win32" } {create_system_menu $menubar} + foreach mymenu $menulist { + menu $menubar.$mymenu + $menubar add cascade -label [_ [string totitle $mymenu]] \ + -menu $menubar.$mymenu + [format build_%s_menu $mymenu] $menubar.$mymenu . if {$::windowingsystem eq "win32"} { # fix menu font size on Windows with tk scaling = 1 - $mymenubar.$mymenu configure -font menufont + $menubar.$mymenu configure -font menufont } } } -proc ::pd_menus::configure_pdwindow {mymenubar} { +proc ::pd_menus::configure_for_pdwindow {} { + variable menubar # these are meaningless for the Pd window, so disable them set file_items_to_disable {"Save" "Save As..." "Print..." "Close"} foreach menuitem $file_items_to_disable { - $mymenubar.file entryconfigure [_ $menuitem] -state disabled + $menubar.file entryconfigure [_ $menuitem] -state disabled } set edit_items_to_disable {"Undo" "Redo" "Duplicate" "Tidy Up" "Edit Mode"} foreach menuitem $edit_items_to_disable { - $mymenubar.edit entryconfigure [_ $menuitem] -state disabled + $menubar.edit entryconfigure [_ $menuitem] -state disabled } # disable everything on the Put menu - for {set i 0} {$i <= [$mymenubar.put index end]} {incr i} { - # catch errors by trying to disable separators - catch {$mymenubar.put entryconfigure $i -state disabled } + for {set i 0} {$i <= [$menubar.put index end]} {incr i} { + # catch errors that happen when trying to disable separators + catch {$menubar.put entryconfigure $i -state disabled } } } +proc ::pd_menus::configure_for_canvas {mytoplevel} { + variable menubar + set file_items_to_disable {"Save" "Save As..." "Print..." "Close"} + foreach menuitem $file_items_to_disable { + $menubar.file entryconfigure [_ $menuitem] -state normal + } + set edit_items_to_disable {"Undo" "Redo" "Duplicate" "Tidy Up" "Edit Mode"} + foreach menuitem $edit_items_to_disable { + $menubar.edit entryconfigure [_ $menuitem] -state normal + } + for {set i 0} {$i <= [$menubar.put index end]} {incr i} { + # catch errors that happen when trying to disable separators + catch {$menubar.put entryconfigure $i -state normal } + } + # TODO set "Edit Mode" state using editmode($mytoplevel) +} + +proc ::pd_menus::configure_for_dialog {mytoplevel} { + variable menubar + # these are meaningless for the dialog panels, so disable them + set file_items_to_disable {"Save" "Save As..." "Print..." "Close"} + foreach menuitem $file_items_to_disable { + $menubar.file entryconfigure [_ $menuitem] -state disabled + } + set edit_items_to_disable {"Undo" "Redo" "Duplicate" "Tidy Up" "Edit Mode"} + foreach menuitem $edit_items_to_disable { + $menubar.edit entryconfigure [_ $menuitem] -state disabled + } + # disable everything on the Put menu + for {set i 0} {$i <= [$menubar.put index end]} {incr i} { + # catch errors that happen when trying to disable separators + catch {$menubar.put entryconfigure $i -state disabled } + } +} + + # ------------------------------------------------------------------------------ # menu building functions proc ::pd_menus::build_file_menu {mymenu mytoplevel} { [format build_file_menu_%s $::windowingsystem] $mymenu - $mymenu entryconfigure [_ "New"] -command "menu_new" - $mymenu entryconfigure [_ "Open"] -command "menu_open" - $mymenu entryconfigure [_ "Save"] -command "pdsend \"$mytoplevel menusave\"" - $mymenu entryconfigure [_ "Save As..."] -command "pdsend \"$mytoplevel menusaveas\"" - # $mymenu entryconfigure "Revert*" -command "menu_revert $mytoplevel" - $mymenu entryconfigure [_ "Close"] -command "pdsend \"$mytoplevel menuclose 0\"" - $mymenu entryconfigure [_ "Message"] -command "menu_message_panel" - $mymenu entryconfigure [_ "Print..."] -command "menu_print $mytoplevel" + $mymenu entryconfigure [_ "New"] -command {menu_new} + $mymenu entryconfigure [_ "Open"] -command {menu_open} + $mymenu entryconfigure [_ "Save"] -command {pdsend "$::focused_window menusave"} + $mymenu entryconfigure [_ "Save As..."] -command {pdsend "$::focused_window menusaveas"} + #$mymenu entryconfigure [_ "Revert*"] -command {menu_revert $current_toplevel} + $mymenu entryconfigure [_ "Close"] -command {pdsend "$::focused_window menuclose 0"} + $mymenu entryconfigure [_ "Message"] -command {menu_message_dialog} + $mymenu entryconfigure [_ "Print..."] -command {menu_print $::focused_window} } proc ::pd_menus::build_edit_menu {mymenu mytoplevel} { variable accelerator $mymenu add command -label [_ "Undo"] -accelerator "$accelerator+Z" \ - -command "menu_undo $mytoplevel" + -command {menu_undo $::focused_window} $mymenu add command -label [_ "Redo"] -accelerator "Shift+$accelerator+Z" \ - -command "menu_redo $mytoplevel" + -command {menu_redo $::focused_window} $mymenu add separator $mymenu add command -label [_ "Cut"] -accelerator "$accelerator+X" \ - -command "pdsend \"$mytoplevel cut\"" + -command {pdsend "$::focused_window cut"} $mymenu add command -label [_ "Copy"] -accelerator "$accelerator+C" \ - -command "pdsend \"$mytoplevel copy\"" + -command {pdsend "$::focused_window copy"} $mymenu add command -label [_ "Paste"] -accelerator "$accelerator+V" \ - -command "pdsend \"$mytoplevel paste\"" + -command {pdsend "$::focused_window paste"} $mymenu add command -label [_ "Duplicate"] -accelerator "$accelerator+D" \ - -command "pdsend \"$mytoplevel duplicate\"" + -command {pdsend "$::focused_window duplicate"} $mymenu add command -label [_ "Select All"] -accelerator "$accelerator+A" \ - -command "pdsend \"$mytoplevel selectall\"" + -command {pdsend "$::focused_window selectall"} $mymenu add separator if {$::windowingsystem eq "aqua"} { $mymenu add command -label [_ "Text Editor"] \ - -command "menu_texteditor $mytoplevel" + -command {menu_texteditor $::focused_window} $mymenu add command -label [_ "Font"] -accelerator "$accelerator+T" \ - -command "menu_dialog_font $mytoplevel" + -command {menu_font_dialog $::focused_window} } else { $mymenu add command -label [_ "Text Editor"] -accelerator "$accelerator+T"\ - -command "menu_texteditor $mytoplevel" + -command {menu_texteditor $::focused_window} $mymenu add command -label [_ "Font"] \ - -command "menu_dialog_font $mytoplevel" + -command {menu_font_dialog $::focused_window} } $mymenu add command -label [_ "Tidy Up"] \ - -command "pdsend \"$mytoplevel tidy\"" - # $mymenu add command -label [_ "Toggle Console"] -accelerator "Shift+$accelerator+R" \ - # -command {.controls.switches.console invoke} - # $mymenu add command -label [_ "Clear Console"] -accelerator "Shift+$accelerator+L" \ - # -command "menu_clear_console" + -command {pdsend "$::focused_window tidy"} + $mymenu add command -label [_ "Toggle Console"] -accelerator "Shift+$accelerator+R" \ + -command {.controls.switches.console invoke} + $mymenu add command -label [_ "Clear Console"] -accelerator "Shift+$accelerator+L" \ + -command {menu_clear_console} $mymenu add separator - $mymenu add radiobutton -label [_ "Edit Mode"] -accelerator "$accelerator+E" \ - -indicatoron true -selectcolor grey85 \ - -command "pdsend \"$mytoplevel editmode 0\"" - # if { $editable == 0 } { - # $mymenu entryconfigure "Edit Mode" -indicatoron false - # } - + #TODO madness! how to do set the state of the check box without invoking the menu! + $mymenu add check -label [_ "Edit Mode"] -accelerator "$accelerator+E" \ + -selectcolor grey85 \ + -command {pdsend "$::focused_window editmode 0"} #if { ! [catch {console hide}]} { # TODO set up menu item to show/hide the Tcl/Tk console, if it available #} if {$::windowingsystem ne "aqua"} { $mymenu add separator - $mymenu add command -label [_ "Path..."] \ - -command "menu_path_panel" - $mymenu add command -label [_ "Startup..."] \ - -command "menu_startup_panel" + $mymenu add command -label [_ "Preferences"] \ + -command {menu_preferences_dialog} } } proc ::pd_menus::build_put_menu {mymenu mytoplevel} { variable accelerator $mymenu add command -label [_ "Object"] -accelerator "$accelerator+1" \ - -command "pdsend \"$mytoplevel obj 0\"" + -command {pdsend "$::focused_window obj 0"} $mymenu add command -label [_ "Message"] -accelerator "$accelerator+2" \ - -command "pdsend \"$mytoplevel msg 0\"" + -command {pdsend "$::focused_window msg 0"} $mymenu add command -label [_ "Number"] -accelerator "$accelerator+3" \ - -command "pdsend \"$mytoplevel floatatom 0\"" + -command {pdsend "$::focused_window floatatom 0"} $mymenu add command -label [_ "Symbol"] -accelerator "$accelerator+4" \ - -command "pdsend \"$mytoplevel symbolatom 0\"" + -command {pdsend "$::focused_window symbolatom 0"} $mymenu add command -label [_ "Comment"] -accelerator "$accelerator+5" \ - -command "pdsend \"$mytoplevel text 0\"" + -command {pdsend "$::focused_window text 0"} $mymenu add separator $mymenu add command -label [_ "Bang"] -accelerator "Shift+$accelerator+B" \ - -command "pdsend \"$mytoplevel bng 0\"" + -command {pdsend "$::focused_window bng 0"} $mymenu add command -label [_ "Toggle"] -accelerator "Shift+$accelerator+T" \ - -command "pdsend \"$mytoplevel toggle 0\"" + -command {pdsend "$::focused_window toggle 0"} $mymenu add command -label [_ "Number2"] -accelerator "Shift+$accelerator+N" \ - -command "pdsend \"$mytoplevel numbox 0\"" + -command {pdsend "$::focused_window numbox 0"} $mymenu add command -label [_ "Vslider"] -accelerator "Shift+$accelerator+V" \ - -command "pdsend \"$mytoplevel vslider 0\"" + -command {pdsend "$::focused_window vslider 0"} $mymenu add command -label [_ "Hslider"] -accelerator "Shift+$accelerator+H" \ - -command "pdsend \"$mytoplevel hslider 0\"" + -command {pdsend "$::focused_window hslider 0"} $mymenu add command -label [_ "Vradio"] -accelerator "Shift+$accelerator+D" \ - -command "pdsend \"$mytoplevel vradio 0\"" + -command {pdsend "$::focused_window vradio 0"} $mymenu add command -label [_ "Hradio"] -accelerator "Shift+$accelerator+I" \ - -command "pdsend \"$mytoplevel hradio 0\"" + -command {pdsend "$::focused_window hradio 0"} $mymenu add command -label [_ "VU Meter"] -accelerator "Shift+$accelerator+U"\ - -command "pdsend \"$mytoplevel vumeter 0\"" + -command {pdsend "$::focused_window vumeter 0"} $mymenu add command -label [_ "Canvas"] -accelerator "Shift+$accelerator+C" \ - -command "pdsend \"$mytoplevel mycnv 0\"" + -command {pdsend "$::focused_window mycnv 0"} $mymenu add separator - $mymenu add command -label Graph -command "pdsend \"$mytoplevel graph\"" - $mymenu add command -label Array -command "pdsend \"$mytoplevel menuarray\"" + $mymenu add command -label [_ "Graph"] -command {pdsend "$::focused_window graph"} + $mymenu add command -label [_ "Array"] -command {pdsend "$::focused_window menuarray"} } proc ::pd_menus::build_find_menu {mymenu mytoplevel} { variable accelerator $mymenu add command -label [_ "Find..."] -accelerator "$accelerator+F" \ - -command "::dialog_find::menu_dialog_find $mytoplevel" + -command {::dialog_find::menu_find_dialog $::focused_window} $mymenu add command -label [_ "Find Again"] -accelerator "$accelerator+G" \ - -command "pdsend \"$mytoplevel findagain\"" + -command {pdsend "$::focused_window findagain"} $mymenu add command -label [_ "Find Last Error"] \ - -command "pdsend \"$mytoplevel finderror\"" + -command {pdsend "$::focused_window finderror"} } proc ::pd_menus::build_media_menu {mymenu mytoplevel} { variable accelerator - $mymenu add radiobutton -label [_ "Audio ON"] -accelerator "$accelerator+/" \ - -command "pdsend \"pd dsp 1\"" - $mymenu add radiobutton -label [_ "Audio OFF"] -accelerator "$accelerator+." \ - -command "pdsend \"pd dsp 0\"" -indicatoron true - $mymenu add separator - $mymenu add command -label [_ "Audio settings..."] \ - -command "pdsend \"pd audio-properties\"" - $mymenu add command -label [_ "MIDI settings..."] \ - -command "pdsend \"pd midi-properties\"" - $mymenu add separator + $mymenu add radiobutton -label [_ "DSP On"] -accelerator "$accelerator+/" \ + -variable ::dsp -value 1 -command {pdsend "pd dsp 1"} + $mymenu add radiobutton -label [_ "DSP Off"] -accelerator "$accelerator+." \ + -variable ::dsp -value 0 -command {pdsend "pd dsp 0"} + $mymenu add separator + + set audioapi_list_length [llength $::audioapi_list] + for {set x 0} {$x<$audioapi_list_length} {incr x} { + # pdtk_post "audio [lindex [lindex $::audioapi_list $x] 0]" + $mymenu add radiobutton -label [lindex [lindex $::audioapi_list $x] 0] \ + -command {menu_audio 0} -variable ::pd_whichapi \ + -value [lindex [lindex $::audioapi_list $x] 1]\ + -command {pdsend "pd audio-setapi $::pd_whichapi"} + } + if {$audioapi_list_length > 0} {$mymenu add separator} + + set midiapi_list_length [llength $::midiapi_list] + for {set x 0} {$x<$midiapi_list_length} {incr x} { + # pdtk_post "midi [lindex [lindex $::midiapi_list $x] 0]" + $mymenu add radiobutton -label [lindex [lindex $::midiapi_list $x] 0] \ + -command {menu_midi 0} -variable ::pd_whichmidiapi \ + -value [lindex [lindex $::midiapi_list $x] 1]\ + -command {pdsend "pd midi-setapi $::pd_whichmidiapi"} + } + if {$midiapi_list_length > 0} {$mymenu add separator} + + if {$::windowingsystem ne "aqua"} { + $mymenu add command -label [_ "Audio settings..."] \ + -command {pdsend "pd audio-properties"} + $mymenu add command -label [_ "MIDI settings..."] \ + -command {pdsend "pd midi-properties"} + $mymenu add separator + } $mymenu add command -label [_ "Test Audio and MIDI..."] \ - -command "menu_doc_open doc/7.stuff/tools testtone.pd" + -command {menu_doc_open doc/7.stuff/tools testtone.pd} $mymenu add command -label [_ "Load Meter"] \ - -command "menu_doc_open doc/7.stuff/tools load-meter.pd" + -command {menu_doc_open doc/7.stuff/tools load-meter.pd} } proc ::pd_menus::build_window_menu {mymenu mytoplevel} { variable accelerator if {$::windowingsystem eq "aqua"} { - $mymenu add command -label [_ "Minimize"] -command "menu_minimize ." \ + $mymenu add command -label [_ "Minimize"] -command {menu_minimize .} \ -accelerator "$accelerator+M" - $mymenu add command -label [_ "Zoom"] -command "menu_zoom ." + $mymenu add command -label [_ "Zoom"] -command {menu_zoom .} $mymenu add separator } $mymenu add command -label [_ "Parent Window"] \ - -command "pdsend \"$mytoplevel findparent\"" - $mymenu add command -label [_ "Pd window"] -command "menu_raise_pdwindow" \ + -command {pdsend "$::focused_window findparent"} + $mymenu add command -label [_ "Pd window"] -command {menu_raise_pdwindow} \ -accelerator "$accelerator+R" $mymenu add separator if {$::windowingsystem eq "aqua"} { $mymenu add command -label [_ "Bring All to Front"] \ - -command "menu_bringalltofront" + -command {menu_bringalltofront} $mymenu add separator } } proc ::pd_menus::build_help_menu {mymenu mytoplevel} { if {$::windowingsystem ne "aqua"} { - $mymenu add command -label {About Pd} \ - -command "placeholder menu_doc_open doc/1.manual 1.introduction.txt" + $mymenu add command -label [_ "About Pd"] \ + -command {menu_doc_open doc/1.manual 1.introduction.txt} + } + $mymenu add command -label [_ "HTML Manual..."] \ + -command {menu_doc_open doc/1.manual index.htm} + $mymenu add command -label [_ "Browser..."] \ + -command {placeholder menu_helpbrowser \$help_top_directory} +} + +# ------------------------------------------------------------------------------ +# update the menu entries for opening recent files +proc ::pd_menus::update_recentfiles_menu {} { + variable menubar + switch -- $::windowingsystem { + "aqua" {::pd_menus::update_openrecent_menu_aqua .openrecent} + "win32" {update_recentfiles_on_menu $menubar.file} + "x11" {update_recentfiles_on_menu $menubar.file} + } +} + +proc ::pd_menus::clear_recentfiles_menu {} { + set ::recentfiles_list {} + ::pd_menus::update_recentfiles_menu +} + +proc ::pd_menus::update_openrecent_menu_aqua {mymenu} { + if {! [winfo exists $mymenu]} {menu $mymenu} + $mymenu delete 0 end + foreach filename $::recentfiles_list { + puts "creating menu item for $filename" + $mymenu add command -label [file tail $filename] \ + -command "open_file $filename" + } + $mymenu add separator + $mymenu add command -label [_ "Clear Menu"] \ + -command "::pd_menus::clear_recentfiles_menu" +} + +# this expects to be run on the File menu, and to insert above the last separator +proc ::pd_menus::update_recentfiles_on_menu {mymenu} { + set lastitem [$mymenu index end] + set i 1 + while {[$mymenu type [expr $lastitem-$i]] ne "separator"} {incr i} + set bottom_separator [expr $lastitem-$i] + incr i + while {[$mymenu type [expr $lastitem-$i]] ne "separator"} {incr i} + set top_separator [expr $lastitem-$i] + if {$top_separator < [expr $bottom_separator-1]} { + $mymenu delete [expr $top_separator+1] [expr $bottom_separator-1] + } + set i 0 + foreach filename $::recentfiles_list { + $mymenu insert [expr $top_separator+$i+1] command \ + -label [file tail $filename] -command "open_file $filename" + incr i } - $mymenu add command -label {HTML ...} \ - -command "placeholder menu_doc_open doc/1.manual index.htm" - $mymenu add command -label {Browser ...} \ - -command "placeholder menu_helpbrowser \$help_top_directory" } # ------------------------------------------------------------------------------ @@ -244,18 +358,17 @@ proc ::pd_menus::build_help_menu {mymenu mytoplevel} { # for Mac OS X only proc ::pd_menus::create_apple_menu {mymenu} { - puts stderr BUILD_APPLE_MENU # TODO this should open a Pd patch called about.pd menu $mymenu.apple $mymenu.apple add command -label [_ "About Pd"] \ - -command "menu_doc_open doc/1.manual 1.introduction.txt" + -command {menu_doc_open doc/1.manual 1.introduction.txt} $mymenu add cascade -label "Apple" -menu $mymenu.apple $mymenu.apple add separator # starting in 8.4.14, this is created automatically set patchlevel [split [info patchlevel] .] if {[lindex $patchlevel 1] < 5 && [lindex $patchlevel 2] < 14} { $mymenu.apple add command -label [_ "Preferences..."] \ - -command "menu_preferences_panel" -accelerator "Cmd+," + -command {menu_preferences_dialog" -accelerator "Cmd+,} } } @@ -263,7 +376,8 @@ proc ::pd_menus::build_file_menu_aqua {mymenu} { variable accelerator $mymenu add command -label [_ "New"] -accelerator "$accelerator+N" $mymenu add command -label [_ "Open"] -accelerator "$accelerator+O" - $mymenu add cascade -label [_ "Open Recent"] + ::pd_menus::update_openrecent_menu_aqua .openrecent + $mymenu add cascade -label [_ "Open Recent"] -menu .openrecent $mymenu add separator $mymenu add command -label [_ "Close"] -accelerator "$accelerator+W" $mymenu add command -label [_ "Save"] -accelerator "$accelerator+S" @@ -296,14 +410,16 @@ proc ::pd_menus::build_file_menu_x11 {mymenu} { $mymenu add separator $mymenu add command -label [_ "Save"] -accelerator "$accelerator+S" $mymenu add command -label [_ "Save As..."] -accelerator "Shift+$accelerator+S" - # $mymenu add command -label "Revert" + # $mymenu add command -label "Revert" $mymenu add separator $mymenu add command -label [_ "Message"] -accelerator "$accelerator+M" $mymenu add command -label [_ "Print..."] -accelerator "$accelerator+P" $mymenu add separator + # the recent files get inserted in here by update_recentfiles_on_menu + $mymenu add separator $mymenu add command -label [_ "Close"] -accelerator "$accelerator+W" $mymenu add command -label [_ "Quit"] -accelerator "$accelerator+Q" \ - -command "pdsend \"pd verifyquit\"" + -command {pdsend "pd verifyquit"} } # the "Edit", "Put", and "Find" menus do not have cross-platform differences @@ -333,14 +449,16 @@ proc ::pd_menus::build_file_menu_win32 {mymenu} { $mymenu add separator $mymenu add command -label [_ "Save"] -accelerator "$accelerator+S" $mymenu add command -label [_ "Save As..."] -accelerator "Shift+$accelerator+S" - # $mymenu add command -label "Revert" + # $mymenu add command -label "Revert" $mymenu add separator $mymenu add command -label [_ "Message"] -accelerator "$accelerator+M" $mymenu add command -label [_ "Print..."] -accelerator "$accelerator+P" $mymenu add separator + # the recent files get inserted in here by update_recentfiles_on_menu + $mymenu add separator $mymenu add command -label [_ "Close"] -accelerator "$accelerator+W" $mymenu add command -label [_ "Quit"] -accelerator "$accelerator+Q"\ - -command "pdsend \"pd verifyquit\"" + -command {pdsend "pd verifyquit"} } # the "Edit", "Put", and "Find" menus do not have cross-platform differences diff --git a/pd/tcl/pdtk_canvas.tcl b/pd/tcl/pdtk_canvas.tcl index 656dd327..31505cec 100644 --- a/pd/tcl/pdtk_canvas.tcl +++ b/pd/tcl/pdtk_canvas.tcl @@ -5,9 +5,8 @@ package require pd_bindings namespace eval ::pdtk_canvas:: { } -# keep track of the location of the popup -set popup_xpix 0 -set popup_ypix 0 + +# TODO figure out weird frameless window when you open a graph #------------------------------------------------------------------------------# # canvas new/saveas @@ -15,8 +14,8 @@ set popup_ypix 0 proc pdtk_canvas_new {mytoplevel width height geometry editable} { # TODO check size of window toplevel $mytoplevel -width $width -height $height -class CanvasWindow - ::pd_menus::create_menubar $mytoplevel.menubar $mytoplevel - $mytoplevel configure -menu $mytoplevel.menubar + wm group $mytoplevel . + $mytoplevel configure -menu .menubar # TODO slide off screen windows into view wm geometry $mytoplevel $geometry @@ -25,6 +24,9 @@ proc pdtk_canvas_new {mytoplevel width height geometry editable} { } else { # leave room for the menubar wm minsize $mytoplevel 310 30 } + + set ::editmode($mytoplevel) $editable + set mycanvas $mytoplevel.c canvas $mycanvas -width $width -height $height -background white \ -highlightthickness 0 @@ -33,15 +35,6 @@ proc pdtk_canvas_new {mytoplevel width height geometry editable} { ::pd_bindings::canvas_bindings $mytoplevel - # the popup menu for the canvas - menu $mytoplevel.popup -tearoff false - $mytoplevel.popup add command -label [_ "Properties"] \ - -command "popup_action $mytoplevel 0" - $mytoplevel.popup add command -label [_ "Open"] \ - -command "popup_action $mytoplevel 1" - $mytoplevel.popup add command -label [_ "Help"] \ - -command "popup_action $mytoplevel 2" - # give focus to the canvas so it gets the events rather than the window focus $mycanvas } @@ -80,8 +73,6 @@ proc pdtk_canvas_motion {mycanvas x y mods} { } proc pdtk_canvas_mouse {mycanvas x y b f} { - # TODO perhaps the Tcl/C function names should match "mouse" message - # rather than "mousedown" function set mytoplevel [winfo toplevel $mycanvas] pdsend "$mytoplevel mouse [$mycanvas canvasx $x] [$mycanvas canvasy $y] $b $f" } @@ -106,6 +97,24 @@ proc pdtk_canvas_clickpaste {mycanvas x y b} { #------------------------------------------------------------------------------# # canvas popup menu +# since there is one popup that is used for all canvas windows, the menu +# -commands use {} quotes so that $::focused_window is interpreted when the +# menu item is called, not when the command is mapped to the menu item. This +# is the same as the menubar in pd_menus.tcl but the opposite of the 'bind' +# commands in pd_bindings.tcl +proc ::pdtk_canvas::create_popup {} { + if { ! [winfo exists .popup]} { + # the popup menu for the canvas + menu .popup -tearoff false + .popup add command -label [_ "Properties"] \ + -command {popup_action $::focused_window 0} + .popup add command -label [_ "Open"] \ + -command {popup_action $::focused_window 1} + .popup add command -label [_ "Help"] \ + -command {popup_action $::focused_window 2} + } +} + proc popup_action {mytoplevel action} { pdsend "$mytoplevel done-popup $action $::popup_xpix $::popup_ypix" } @@ -114,18 +123,18 @@ proc pdtk_canvas_popup {mytoplevel xpix ypix hasproperties hasopen} { set ::popup_xpix $xpix set ::popup_ypix $ypix if {$hasproperties} { - $mytoplevel.popup entryconfigure 0 -state normal + .popup entryconfigure [_ "Properties"] -state normal } else { - $mytoplevel.popup entryconfigure 0 -state disabled + .popup entryconfigure [_ "Properties"] -state disabled } if {$hasopen} { - $mytoplevel.popup entryconfigure 1 -state normal + .popup entryconfigure [_ "Open"] -state normal } else { - $mytoplevel.popup entryconfigure 1 -state disabled + .popup entryconfigure [_ "Open"] -state disabled } set mycanvas "$mytoplevel.c" - tk_popup $mytoplevel.popup [expr $xpix + [winfo rootx $mycanvas]] \ - [expr $ypix + [winfo rooty $mycanvas]] 0 + tk_popup .popup [expr $xpix + [winfo rootx $mycanvas]] \ + [expr $ypix + [winfo rooty $mycanvas]] 0 } @@ -134,9 +143,22 @@ proc pdtk_canvas_popup {mytoplevel xpix ypix hasproperties hasopen} { # check or uncheck the "edit" menu item proc pdtk_canvas_editval {mytoplevel value} { - $mytoplevel.menubar.edit invoke [_ "Edit Mode"] -# $mytoplevel.menubar.edit entryconfigure "Edit Mode" -indicatoron $value - # TODO make this work + set ::editmode($mytoplevel) $value +# TODO figure how to change Edit Mode/Interact Mode text and have menu +# enabling and disabling working still in pd_menus.tcl +# if {$value == 0} { +# $::pd_menus::menubar.edit entryconfigure [_ "Interact Mode"] -label [_ "Edit Mode"] +# } else { +# $::pd_menus::menubar.edit entryconfigure [_ "Edit Mode"] -label [_ "Interact Mode"] +# } + #$mytoplevel.menubar.edit entryconfigure [_ "Edit Mode"] -indicatoron $value + # TODO make this work, probably with a proc in pd_menus, or maybe the menu + # item can track the editmode variable +} + +proc pdtk_undomenu {args} { + # TODO make this work, probably with a proc in pd_menus + puts "pdtk_undomenu $args" } proc pdtk_canvas_getscroll {mycanvas} { @@ -145,8 +167,3 @@ proc pdtk_canvas_getscroll {mycanvas} { set mytoplevel [winfo toplevel $mycanvas] # puts stderr "pdtk_canvas_getscroll $mycanvas" } - -proc pdtk_undomenu {args} { - # TODO make this work - puts "pdtk_undomenu $args" -} diff --git a/pd/tcl/pdwindow.tcl b/pd/tcl/pdwindow.tcl new file mode 100644 index 00000000..d0c0c654 --- /dev/null +++ b/pd/tcl/pdwindow.tcl @@ -0,0 +1,53 @@ + +package provide pdwindow 0.1 + +namespace eval ::pdwindow:: { + variable consolefont + variable printout_buffer "" + variable pdwindow_search_index + + namespace export pdtk_post +} + + + +proc ::pdwindow::pdtk_post {message} { + variable printout_buffer + # TODO this should be switchable between Pd window and stderr + if { ! [winfo exists .pdwindow.text]} { + set printout_buffer "$printout_buffer\n$message" + } else { + if {$printout_buffer ne ""} { + .pdwindow.text insert end "$printout_buffer\n" + set printout_buffer "" + } + .pdwindow.text insert end "$message\n" + .pdwindow.text yview end + } + puts stderr $message +} + +proc ::pdwindow::create_window {} { + variable consolefont + toplevel .pdwindow -class PdWindow + wm title .pdwindow [_ "Pd window"] + wm geometry .pdwindow =500x450+20+50 + .pdwindow configure -menu .menubar + ::pd_menus::configure_for_pdwindow + ::pd_bindings::pdwindow_bindings .pdwindow + + frame .pdwindow.header + pack .pdwindow.header -side top -fill x -padx 30 -ipady 10 + # label .pdwindow.header.label -text "The Pd window wants you to make it look nice!" + # pack .pdwindow.header.label -side left -fill y -anchor w + checkbutton .pdwindow.header.dsp -text [_ "DSP"] -variable ::dsp \ + -command "pdsend \"pd dsp 0\"" + pack .pdwindow.header.dsp -side right -fill y -anchor e +# TODO this should use the pd_font_$size created in pd-gui.tcl + text .pdwindow.text -relief raised -bd 2 -font {-size 10} \ + -yscrollcommand ".pdwindow.scroll set" -width 60 + scrollbar .pdwindow.scroll -command ".pdwindow.text yview" + pack .pdwindow.scroll -side right -fill y + pack .pdwindow.text -side bottom -fill both -expand 1 + raise .pdwindow +} diff --git a/pd/tcl/pkgIndex.tcl b/pd/tcl/pkgIndex.tcl index c6e6f7d8..cd28c6bd 100644 --- a/pd/tcl/pkgIndex.tcl +++ b/pd/tcl/pkgIndex.tcl @@ -11,13 +11,18 @@ package ifneeded apple_events 0.1 [list source [file join $dir apple_events.tcl]] package ifneeded pd_bindings 0.1 [list source [file join $dir pd_bindings.tcl]] package ifneeded pd_connect 0.1 [list source [file join $dir pd_connect.tcl]] +package ifneeded dialog_array 0.1 [list source [file join $dir dialog_array.tcl]] +package ifneeded dialog_audio 0.1 [list source [file join $dir dialog_audio.tcl]] +package ifneeded dialog_canvas 0.1 [list source [file join $dir dialog_canvas.tcl]] package ifneeded dialog_find 0.1 [list source [file join $dir dialog_find.tcl]] package ifneeded dialog_font 0.1 [list source [file join $dir dialog_font.tcl]] package ifneeded dialog_gatom 0.1 [list source [file join $dir dialog_gatom.tcl]] package ifneeded dialog_iemgui 0.1 [list source [file join $dir dialog_iemgui.tcl]] +package ifneeded dialog_midi 0.1 [list source [file join $dir dialog_midi.tcl]] +package ifneeded opt_parser 0.1 [list source [file join $dir opt_parser.tcl]] +package ifneeded pdwindow 0.1 [list source [file join $dir pdwindow.tcl]] package ifneeded pd_menucommands 0.1 [list source [file join $dir pd_menucommands.tcl]] package ifneeded pd_menus 0.1 [list source [file join $dir pd_menus.tcl]] -package ifneeded pdtk_array 0.1 [list source [file join $dir pdtk_array.tcl]] package ifneeded pdtk_canvas 0.1 [list source [file join $dir pdtk_canvas.tcl]] package ifneeded pdtk_text 0.1 [list source [file join $dir pdtk_text.tcl]] package ifneeded wheredoesthisgo 0.1 [list source [file join $dir wheredoesthisgo.tcl]] diff --git a/pd/tcl/wheredoesthisgo.tcl b/pd/tcl/wheredoesthisgo.tcl index 148f9878..3fbb9d1f 100644 --- a/pd/tcl/wheredoesthisgo.tcl +++ b/pd/tcl/wheredoesthisgo.tcl @@ -7,8 +7,8 @@ set help_top_directory "" proc post_tclinfo {} { - pdtk_post "Tcl library: [info library]" - pdtk_post "executable: [info nameofexecutable]" + pdtk_post "Tcl library: [file normalize [info library]]" + pdtk_post "executable: [file normalize [info nameofexecutable]]" pdtk_post "tclversion: [info tclversion]" pdtk_post "patchlevel: [info patchlevel]" pdtk_post "sharedlibextension: [info sharedlibextension]" @@ -17,7 +17,7 @@ proc post_tclinfo {} { proc placeholder {args} { # PLACEHOLDER - pdtk_post "PLACEHOLDER $args" + ::pdwindow::pdtk_post "PLACEHOLDER $args" } @@ -25,14 +25,28 @@ proc open_file {filename} { set directory [file dirname $filename] set basename [file tail $filename] if {[regexp -nocase -- "\.(pd|pat|mxt)$" $filename]} { - pdsend "pd open [enquote_path $basename] [enquote_path $directory]" + pdsend "pd open [enquote_path $basename] [enquote_path $directory]" + # remove duplicates first, then the duplicate added after to the top + set index [lsearch -exact $::recentfiles_list $filename] + set ::recentfiles_list [lreplace $::recentfiles_list $index $index] + set ::recentfiles_list \ + "$filename [lrange $::recentfiles_list 0 $::total_recentfiles]" + ::pd_menus::update_recentfiles_menu } } +proc lookup_windowname {mytoplevel} { + foreach window $::menu_windowlist { + if {[lindex $window 1] eq $mytoplevel} { + return [lindex $window 0] + } + } +} + # ------------------------------------------------------------------------------ # quoting functions -# enquote a filename to send it to pd, " isn't handled properly tho... +# TODO enquote a filename to send it to pd, " isn't handled properly tho... proc enquote_path {message} { string map {"," "\\," ";" "\\;" " " "\\ "} $message } @@ -41,39 +55,21 @@ proc enquote_path {message} { #we also blow off "{", "}", "\" because they'll just cause bad trouble later. proc unspace_text {x} { set y [string map {" " "_" ";" "" "," "" "{" "" "}" "" "\\" ""} $x] - if {$y == ""} {set y "empty"} + if {$y eq ""} {set y "empty"} concat $y } -#------------------------------------------------------------------------------# -# key usage - -proc pdsend_key {mycanvas state key iso shift} { - # TODO canvas_key on the C side should be refactored with this proc as well - switch -- $key { - "BackSpace" { set iso ""; set key 8 } - "Tab" { set iso ""; set key 9 } - "Return" { set iso ""; set key 10 } - "Escape" { set iso ""; set key 27 } - "Space" { set iso ""; set key 32 } - "Delete" { set iso ""; set key 127 } - "KP_Delete" { set iso ""; set key 127 } - } - if {$iso != ""} { - scan $iso %c key - } - pdsend "[winfo toplevel $mycanvas] key $state $key $shift" -} - # ------------------------------------------------------------------------------ # lost pdtk functions... # set the checkbox on the "Compute Audio" menuitem and checkbox proc pdtk_pd_dsp {value} { + # TODO canvas_startdsp/stopdsp should really send 1 or 0, not "ON" or "OFF" if {$value eq "ON"} { - #TODO + set ::dsp 1 } else { + set ::dsp 0 } } @@ -99,956 +95,3 @@ proc .mbar.find {command number} { # this should be changed in g_canvas.c, around line 800 .menubar.find $command $number } - -# ------------------------------------------------------------------------------ -# stuff Miller added to get up and running... - -proc menu_doc_open {dirname basename} { - global argv0 - set slashed $argv0 - if {[tk windowingsystem] eq "win32"} { - set slashed [string map {"\\" "/"} $slashed] - } - - set pddir [string range $slashed 0 [expr [string last / $slashed ] - 1]] - - if {[regexp ".*\.(txt|c)$" $basename]} { - menu_opentext $pddir/../$dirname/$basename - } elseif {[regexp ".*\.html?$" $basename]} { - menu_openhtml $pddir/../$dirname/$basename - } else { - pdsend [concat pd open [enquote_path $basename] \ - [enquote_path $pddir/../$dirname] \;] - } -} - -set pd_window_exists 0 - -proc create_pdwindow {} { - global pd_window_exists - set pd_window_exists 1 - wm title . [_ "Pd window"] - wm geometry . +500+50 - - frame .printout - text .printout.text -relief raised -bd 2 -font console_font \ - -yscrollcommand ".printout.scroll set" -width 80 - # .printout.text insert end "\n\n\n\n\n\n\n\n\n\n" - scrollbar .printout.scroll -command ".printout.text yview" - pack .printout.scroll -side right -fill y - pack .printout.text -side left -fill both -expand 1 - pack .printout -side bottom -fill both -expand 1 - - ::pd_menus::create_menubar .menubar . - . configure -menu .menubar -width 400 -height 250 - ::pd_menus::configure_pdwindow .menubar - ::pd_bindings::pdwindow_bindings . -} - -proc pdtk_post {message} { - global pd_window_exists - if {$pd_window_exists} { - .printout.text insert end $message - .printout.text yview end-2char - } else { - puts stderr $message - } -} - -proc pdtk_standardkeybindings {id} { - bind $id <Control-Key> {pdtk_pd_ctrlkey %W %K 0} - bind $id <Control-Shift-Key> {pdtk_pd_ctrlkey %W %K 1} - if {[tk windowingsystem] eq "win32"} { - bind $id <Mod1-Key> {pdtk_canvas_ctrlkey %W %K 0} - bind $id <Mod1-Shift-Key> {pdtk_canvas_ctrlkey %W %K 1} - } -} - -proc pdtk_encodedialog {x} { - concat +[string map {" " "+_" "$" "+d" ";" "+s" "," "+c" "+" "++"} $x] -} - -####################### audio dialog ##################3 - -proc audio_apply {id} { - global audio_indev1 audio_indev2 audio_indev3 audio_indev4 - global audio_inchan1 audio_inchan2 audio_inchan3 audio_inchan4 - global audio_inenable1 audio_inenable2 audio_inenable3 audio_inenable4 - global audio_outdev1 audio_outdev2 audio_outdev3 audio_outdev4 - global audio_outchan1 audio_outchan2 audio_outchan3 audio_outchan4 - global audio_outenable1 audio_outenable2 audio_outenable3 audio_outenable4 - global audio_sr audio_advance audio_callback - - pdsend [concat pd audio-dialog \ - $audio_indev1 \ - $audio_indev2 \ - $audio_indev3 \ - $audio_indev4 \ - [expr $audio_inchan1 * ( $audio_inenable1 ? 1 : -1 ) ]\ - [expr $audio_inchan2 * ( $audio_inenable2 ? 1 : -1 ) ]\ - [expr $audio_inchan3 * ( $audio_inenable3 ? 1 : -1 ) ]\ - [expr $audio_inchan4 * ( $audio_inenable4 ? 1 : -1 ) ]\ - $audio_outdev1 \ - $audio_outdev2 \ - $audio_outdev3 \ - $audio_outdev4 \ - [expr $audio_outchan1 * ( $audio_outenable1 ? 1 : -1 ) ]\ - [expr $audio_outchan2 * ( $audio_outenable2 ? 1 : -1 ) ]\ - [expr $audio_outchan3 * ( $audio_outenable3 ? 1 : -1 ) ]\ - [expr $audio_outchan4 * ( $audio_outenable4 ? 1 : -1 ) ]\ - $audio_sr \ - $audio_advance \ - $audio_callback \ - \;] -} - -proc audio_cancel {id} { - pdsend [concat $id cancel \;] -} - -proc audio_ok {id} { - audio_apply $id - audio_cancel $id -} - -# callback from popup menu -proc audio_popup_action {buttonname varname devlist index} { - global audio_indevlist audio_outdevlist $varname - $buttonname configure -text [lindex $devlist $index] -# puts stderr [concat popup_action $buttonname $varname $index] - set $varname $index -} - -# create a popup menu -proc audio_popup {name buttonname varname devlist} { - if [winfo exists $name.popup] {destroy $name.popup} - menu $name.popup -tearoff false - if {[tk windowingsystem] eq "win32"} { - $name.popup configure -font menuFont - } -# puts stderr [concat $devlist ] - for {set x 0} {$x<[llength $devlist]} {incr x} { - $name.popup add command -label [lindex $devlist $x] \ - -command [list audio_popup_action \ - $buttonname $varname $devlist $x] - } - tk_popup $name.popup [winfo pointerx $name] [winfo pointery $name] 0 -} - -# start a dialog window to select audio devices and settings. "multi" -# is 0 if only one device is allowed; 1 if one apiece may be specified for -# input and output; and 2 if we can select multiple devices. "longform" -# (which only makes sense if "multi" is 2) asks us to make controls for -# opening several devices; if not, we get an extra button to turn longform -# on and restart the dialog. - -proc pdtk_audio_dialog {id indev1 indev2 indev3 indev4 \ - inchan1 inchan2 inchan3 inchan4 \ - outdev1 outdev2 outdev3 outdev4 \ - outchan1 outchan2 outchan3 outchan4 sr advance multi callback \ - longform} { - global audio_indev1 audio_indev2 audio_indev3 audio_indev4 - global audio_inchan1 audio_inchan2 audio_inchan3 audio_inchan4 - global audio_inenable1 audio_inenable2 audio_inenable3 audio_inenable4 - global audio_outdev1 audio_outdev2 audio_outdev3 audio_outdev4 - global audio_outchan1 audio_outchan2 audio_outchan3 audio_outchan4 - global audio_outenable1 audio_outenable2 audio_outenable3 audio_outenable4 - global audio_sr audio_advance audio_callback - global audio_indevlist audio_outdevlist - global pd_indev pd_outdev - - set audio_indev1 $indev1 - set audio_indev2 $indev2 - set audio_indev3 $indev3 - set audio_indev4 $indev4 - - set audio_inchan1 [expr ( $inchan1 > 0 ? $inchan1 : -$inchan1 ) ] - set audio_inenable1 [expr $inchan1 > 0 ] - set audio_inchan2 [expr ( $inchan2 > 0 ? $inchan2 : -$inchan2 ) ] - set audio_inenable2 [expr $inchan2 > 0 ] - set audio_inchan3 [expr ( $inchan3 > 0 ? $inchan3 : -$inchan3 ) ] - set audio_inenable3 [expr $inchan3 > 0 ] - set audio_inchan4 [expr ( $inchan4 > 0 ? $inchan4 : -$inchan4 ) ] - set audio_inenable4 [expr $inchan4 > 0 ] - - set audio_outdev1 $outdev1 - set audio_outdev2 $outdev2 - set audio_outdev3 $outdev3 - set audio_outdev4 $outdev4 - - set audio_outchan1 [expr ( $outchan1 > 0 ? $outchan1 : -$outchan1 ) ] - set audio_outenable1 [expr $outchan1 > 0 ] - set audio_outchan2 [expr ( $outchan2 > 0 ? $outchan2 : -$outchan2 ) ] - set audio_outenable2 [expr $outchan2 > 0 ] - set audio_outchan3 [expr ( $outchan3 > 0 ? $outchan3 : -$outchan3 ) ] - set audio_outenable3 [expr $outchan3 > 0 ] - set audio_outchan4 [expr ( $outchan4 > 0 ? $outchan4 : -$outchan4 ) ] - set audio_outenable4 [expr $outchan4 > 0 ] - - set audio_sr $sr - set audio_advance $advance - set audio_callback $callback - toplevel $id - wm title $id {audio} - wm protocol $id WM_DELETE_WINDOW [concat audio_cancel $id] - - frame $id.buttonframe - pack $id.buttonframe -side bottom -fill x -pady 2m - button $id.buttonframe.cancel -text {Cancel}\ - -command "audio_cancel $id" - button $id.buttonframe.apply -text {Apply}\ - -command "audio_apply $id" - button $id.buttonframe.ok -text {OK}\ - -command "audio_ok $id" - button $id.buttonframe.save -text {Save all settings}\ - -command "audio_apply $id \; pdsend \"pd save-preferences\"" - pack $id.buttonframe.cancel $id.buttonframe.apply $id.buttonframe.ok \ - $id.buttonframe.save -side left -expand 1 - - # sample rate and advance - frame $id.srf - pack $id.srf -side top - - label $id.srf.l1 -text "sample rate:" - entry $id.srf.x1 -textvariable audio_sr -width 7 - label $id.srf.l2 -text "delay (msec):" - entry $id.srf.x2 -textvariable audio_advance -width 4 - pack $id.srf.l1 $id.srf.x1 $id.srf.l2 $id.srf.x2 -side left - if {$audio_callback >= 0} { - checkbutton $id.srf.x3 -variable audio_callback \ - -text {use callbacks} -anchor e - pack $id.srf.x3 -side left - } - # input device 1 - frame $id.in1f - pack $id.in1f -side top - - checkbutton $id.in1f.x0 -variable audio_inenable1 \ - -text {input device 1} -anchor e - button $id.in1f.x1 -text [lindex $audio_indevlist $audio_indev1] \ - -command [list audio_popup $id $id.in1f.x1 audio_indev1 $audio_indevlist] - label $id.in1f.l2 -text "channels:" - entry $id.in1f.x2 -textvariable audio_inchan1 -width 3 - pack $id.in1f.x0 $id.in1f.x1 $id.in1f.l2 $id.in1f.x2 -side left - - # input device 2 - if {$longform && $multi > 1 && [llength $audio_indevlist] > 1} { - frame $id.in2f - pack $id.in2f -side top - - checkbutton $id.in2f.x0 -variable audio_inenable2 \ - -text {input device 2} -anchor e - button $id.in2f.x1 -text [lindex $audio_indevlist $audio_indev2] \ - -command [list audio_popup $id $id.in2f.x1 audio_indev2 \ - $audio_indevlist] - label $id.in2f.l2 -text "channels:" - entry $id.in2f.x2 -textvariable audio_inchan2 -width 3 - pack $id.in2f.x0 $id.in2f.x1 $id.in2f.l2 $id.in2f.x2 -side left - } - - # input device 3 - if {$longform && $multi > 1 && [llength $audio_indevlist] > 2} { - frame $id.in3f - pack $id.in3f -side top - - checkbutton $id.in3f.x0 -variable audio_inenable3 \ - -text {input device 3} -anchor e - button $id.in3f.x1 -text [lindex $audio_indevlist $audio_indev3] \ - -command [list audio_popup $id $id.in3f.x1 audio_indev3 \ - $audio_indevlist] - label $id.in3f.l2 -text "channels:" - entry $id.in3f.x2 -textvariable audio_inchan3 -width 3 - pack $id.in3f.x0 $id.in3f.x1 $id.in3f.l2 $id.in3f.x2 -side left - } - - # input device 4 - if {$longform && $multi > 1 && [llength $audio_indevlist] > 3} { - frame $id.in4f - pack $id.in4f -side top - - checkbutton $id.in4f.x0 -variable audio_inenable4 \ - -text {input device 4} -anchor e - button $id.in4f.x1 -text [lindex $audio_indevlist $audio_indev4] \ - -command [list audio_popup $id $id.in4f.x1 audio_indev4 \ - $audio_indevlist] - label $id.in4f.l2 -text "channels:" - entry $id.in4f.x2 -textvariable audio_inchan4 -width 3 - pack $id.in4f.x0 $id.in4f.x1 $id.in4f.l2 $id.in4f.x2 -side left - } - - # output device 1 - frame $id.out1f - pack $id.out1f -side top - - checkbutton $id.out1f.x0 -variable audio_outenable1 \ - -text {output device 1} -anchor e - if {$multi == 0} { - label $id.out1f.l1 \ - -text "(same as input device) .............. " - } else { - button $id.out1f.x1 -text [lindex $audio_outdevlist $audio_outdev1] \ - -command [list audio_popup $id $id.out1f.x1 audio_outdev1 \ - $audio_outdevlist] - } - label $id.out1f.l2 -text "channels:" - entry $id.out1f.x2 -textvariable audio_outchan1 -width 3 - if {$multi == 0} { - pack $id.out1f.x0 $id.out1f.l1 $id.out1f.x2 -side left - } else { - pack $id.out1f.x0 $id.out1f.x1 $id.out1f.l2 $id.out1f.x2 -side left - } - - # output device 2 - if {$longform && $multi > 1 && [llength $audio_outdevlist] > 1} { - frame $id.out2f - pack $id.out2f -side top - - checkbutton $id.out2f.x0 -variable audio_outenable2 \ - -text {output device 2} -anchor e - button $id.out2f.x1 -text [lindex $audio_outdevlist $audio_outdev2] \ - -command \ - [list audio_popup $id $id.out2f.x1 audio_outdev2 $audio_outdevlist] - label $id.out2f.l2 -text "channels:" - entry $id.out2f.x2 -textvariable audio_outchan2 -width 3 - pack $id.out2f.x0 $id.out2f.x1 $id.out2f.l2 $id.out2f.x2 -side left - } - - # output device 3 - if {$longform && $multi > 1 && [llength $audio_outdevlist] > 2} { - frame $id.out3f - pack $id.out3f -side top - - checkbutton $id.out3f.x0 -variable audio_outenable3 \ - -text {output device 3} -anchor e - button $id.out3f.x1 -text [lindex $audio_outdevlist $audio_outdev3] \ - -command \ - [list audio_popup $id $id.out3f.x1 audio_outdev3 $audio_outdevlist] - label $id.out3f.l2 -text "channels:" - entry $id.out3f.x2 -textvariable audio_outchan3 -width 3 - pack $id.out3f.x0 $id.out3f.x1 $id.out3f.l2 $id.out3f.x2 -side left - } - - # output device 4 - if {$longform && $multi > 1 && [llength $audio_outdevlist] > 3} { - frame $id.out4f - pack $id.out4f -side top - - checkbutton $id.out4f.x0 -variable audio_outenable4 \ - -text {output device 4} -anchor e - button $id.out4f.x1 -text [lindex $audio_outdevlist $audio_outdev4] \ - -command \ - [list audio_popup $id $id.out4f.x1 audio_outdev4 $audio_outdevlist] - label $id.out4f.l2 -text "channels:" - entry $id.out4f.x2 -textvariable audio_outchan4 -width 3 - pack $id.out4f.x0 $id.out4f.x1 $id.out4f.l2 $id.out4f.x2 -side left - } - - # if not the "long form" but if "multi" is 2, make a button to - # restart with longform set. - - if {$longform == 0 && $multi > 1} { - frame $id.longbutton - pack $id.longbutton -side top - button $id.longbutton.b -text {use multiple devices} \ - -command {pdsend "pd audio-properties 1"} - pack $id.longbutton.b - } - bind $id.srf.x1 <KeyPress-Return> [concat audio_ok $id] - bind $id.srf.x2 <KeyPress-Return> [concat audio_ok $id] - bind $id.in1f.x2 <KeyPress-Return> [concat audio_ok $id] - bind $id.out1f.x2 <KeyPress-Return> [concat audio_ok $id] - $id.srf.x1 select from 0 - $id.srf.x1 select adjust end - focus $id.srf.x1 - pdtk_standardkeybindings $id.srf.x1 - pdtk_standardkeybindings $id.srf.x2 - pdtk_standardkeybindings $id.in1f.x2 - pdtk_standardkeybindings $id.out1f.x2 -} - -####################### midi dialog ################## - -proc midi_apply {id} { - global midi_indev1 midi_indev2 midi_indev3 midi_indev4 - global midi_outdev1 midi_outdev2 midi_outdev3 midi_outdev4 - global midi_alsain midi_alsaout - - pdsend [concat pd midi-dialog \ - $midi_indev1 \ - $midi_indev2 \ - $midi_indev3 \ - $midi_indev4 \ - $midi_outdev1 \ - $midi_outdev2 \ - $midi_outdev3 \ - $midi_outdev4 \ - $midi_alsain \ - $midi_alsaout \ - \;] -} - -proc midi_cancel {id} { - pdsend [concat $id cancel \;] -} - -proc midi_ok {id} { - midi_apply $id - midi_cancel $id -} - -# callback from popup menu -proc midi_popup_action {buttonname varname devlist index} { - global midi_indevlist midi_outdevlist $varname - $buttonname configure -text [lindex $devlist $index] -# puts stderr [concat popup_action $buttonname $varname $index] - set $varname $index -} - -# create a popup menu -proc midi_popup {name buttonname varname devlist} { - if [winfo exists $name.popup] {destroy $name.popup} - menu $name.popup -tearoff false - if {[tk windowingsystem] eq "win32"} { - $name.popup configure -font menuFont - } -# puts stderr [concat $devlist ] - for {set x 0} {$x<[llength $devlist]} {incr x} { - $name.popup add command -label [lindex $devlist $x] \ - -command [list midi_popup_action \ - $buttonname $varname $devlist $x] - } - tk_popup $name.popup [winfo pointerx $name] [winfo pointery $name] 0 -} - -# start a dialog window to select midi devices. "longform" asks us to make -# controls for opening several devices; if not, we get an extra button to -# turn longform on and restart the dialog. -proc pdtk_midi_dialog {id indev1 indev2 indev3 indev4 \ - outdev1 outdev2 outdev3 outdev4 longform} { - global midi_indev1 midi_indev2 midi_indev3 midi_indev4 - global midi_outdev1 midi_outdev2 midi_outdev3 midi_outdev4 - global midi_indevlist midi_outdevlist - global midi_alsain midi_alsaout - - set midi_indev1 $indev1 - set midi_indev2 $indev2 - set midi_indev3 $indev3 - set midi_indev4 $indev4 - set midi_outdev1 $outdev1 - set midi_outdev2 $outdev2 - set midi_outdev3 $outdev3 - set midi_outdev4 $outdev4 - set midi_alsain [llength $midi_indevlist] - set midi_alsaout [llength $midi_outdevlist] - - toplevel $id - wm title $id {midi} - wm protocol $id WM_DELETE_WINDOW [concat midi_cancel $id] - - frame $id.buttonframe - pack $id.buttonframe -side bottom -fill x -pady 2m - button $id.buttonframe.cancel -text {Cancel}\ - -command "midi_cancel $id" - button $id.buttonframe.apply -text {Apply}\ - -command "midi_apply $id" - button $id.buttonframe.ok -text {OK}\ - -command "midi_ok $id" - pack $id.buttonframe.cancel -side left -expand 1 - pack $id.buttonframe.apply -side left -expand 1 - pack $id.buttonframe.ok -side left -expand 1 - - # input device 1 - frame $id.in1f - pack $id.in1f -side top - - label $id.in1f.l1 -text "input device 1:" - button $id.in1f.x1 -text [lindex $midi_indevlist $midi_indev1] \ - -command [list midi_popup $id $id.in1f.x1 midi_indev1 $midi_indevlist] - pack $id.in1f.l1 $id.in1f.x1 -side left - - # input device 2 - if {$longform && [llength $midi_indevlist] > 2} { - frame $id.in2f - pack $id.in2f -side top - - label $id.in2f.l1 -text "input device 2:" - button $id.in2f.x1 -text [lindex $midi_indevlist $midi_indev2] \ - -command [list midi_popup $id $id.in2f.x1 midi_indev2 \ - $midi_indevlist] - pack $id.in2f.l1 $id.in2f.x1 -side left - } - - # input device 3 - if {$longform && [llength $midi_indevlist] > 3} { - frame $id.in3f - pack $id.in3f -side top - - label $id.in3f.l1 -text "input device 3:" - button $id.in3f.x1 -text [lindex $midi_indevlist $midi_indev3] \ - -command [list midi_popup $id $id.in3f.x1 midi_indev3 \ - $midi_indevlist] - pack $id.in3f.l1 $id.in3f.x1 -side left - } - - # input device 4 - if {$longform && [llength $midi_indevlist] > 4} { - frame $id.in4f - pack $id.in4f -side top - - label $id.in4f.l1 -text "input device 4:" - button $id.in4f.x1 -text [lindex $midi_indevlist $midi_indev4] \ - -command [list midi_popup $id $id.in4f.x1 midi_indev4 \ - $midi_indevlist] - pack $id.in4f.l1 $id.in4f.x1 -side left - } - - # output device 1 - - frame $id.out1f - pack $id.out1f -side top - label $id.out1f.l1 -text "output device 1:" - button $id.out1f.x1 -text [lindex $midi_outdevlist $midi_outdev1] \ - -command [list midi_popup $id $id.out1f.x1 midi_outdev1 \ - $midi_outdevlist] - pack $id.out1f.l1 $id.out1f.x1 -side left - - # output device 2 - if {$longform && [llength $midi_outdevlist] > 2} { - frame $id.out2f - pack $id.out2f -side top - label $id.out2f.l1 -text "output device 2:" - button $id.out2f.x1 -text [lindex $midi_outdevlist $midi_outdev2] \ - -command \ - [list midi_popup $id $id.out2f.x1 midi_outdev2 $midi_outdevlist] - pack $id.out2f.l1 $id.out2f.x1 -side left - } - - # output device 3 - if {$longform && [llength $midi_midi_outdevlist] > 3} { - frame $id.out3f - pack $id.out3f -side top - label $id.out3f.l1 -text "output device 3:" - button $id.out3f.x1 -text [lindex $midi_outdevlist $midi_outdev3] \ - -command \ - [list midi_popup $id $id.out3f.x1 midi_outdev3 $midi_outdevlist] - pack $id.out3f.l1 $id.out3f.x1 -side left - } - - # output device 4 - if {$longform && [llength $midi_midi_outdevlist] > 4} { - frame $id.out4f - pack $id.out4f -side top - label $id.out4f.l1 -text "output device 4:" - button $id.out4f.x1 -text [lindex $midi_outdevlist $midi_outdev4] \ - -command \ - [list midi_popup $id $id.out4f.x1 midi_outdev4 $midi_outdevlist] - pack $id.out4f.l1 $id.out4f.x1 -side left - } - - # if not the "long form" make a button to - # restart with longform set. - - if {$longform == 0} { - frame $id.longbutton - pack $id.longbutton -side top - button $id.longbutton.b -text {use multiple devices} \ - -command {pdsend "pd midi-properties 1"} - pack $id.longbutton.b - } -} - -proc pdtk_alsa_midi_dialog {id indev1 indev2 indev3 indev4 \ - outdev1 outdev2 outdev3 outdev4 longform alsa} { - global midi_indev1 midi_indev2 midi_indev3 midi_indev4 - global midi_outdev1 midi_outdev2 midi_outdev3 midi_outdev4 - global midi_indevlist midi_outdevlist - global midi_alsain midi_alsaout - - set midi_indev1 $indev1 - set midi_indev2 $indev2 - set midi_indev3 $indev3 - set midi_indev4 $indev4 - set midi_outdev1 $outdev1 - set midi_outdev2 $outdev2 - set midi_outdev3 $outdev3 - set midi_outdev4 $outdev4 - set midi_alsain [llength $midi_indevlist] - set midi_alsaout [llength $midi_outdevlist] - - toplevel $id - wm title $id {midi} - wm protocol $id WM_DELETE_WINDOW [concat midi_cancel $id] - - frame $id.buttonframe - pack $id.buttonframe -side bottom -fill x -pady 2m - button $id.buttonframe.cancel -text {Cancel}\ - -command "midi_cancel $id" - button $id.buttonframe.apply -text {Apply}\ - -command "midi_apply $id" - button $id.buttonframe.ok -text {OK}\ - -command "midi_ok $id" - pack $id.buttonframe.cancel -side left -expand 1 - pack $id.buttonframe.apply -side left -expand 1 - pack $id.buttonframe.ok -side left -expand 1 - - frame $id.in1f - pack $id.in1f -side top - - if {$alsa == 0} { - # input device 1 - label $id.in1f.l1 -text "input device 1:" - button $id.in1f.x1 -text [lindex $midi_indevlist $midi_indev1] \ - -command [list midi_popup $id $id.in1f.x1 midi_indev1 $midi_indevlist] - pack $id.in1f.l1 $id.in1f.x1 -side left - - # input device 2 - if {$longform && [llength $midi_indevlist] > 2} { - frame $id.in2f - pack $id.in2f -side top - - label $id.in2f.l1 -text "input device 2:" - button $id.in2f.x1 -text [lindex $midi_indevlist $midi_indev2] \ - -command [list midi_popup $id $id.in2f.x1 midi_indev2 \ - $midi_indevlist] - pack $id.in2f.l1 $id.in2f.x1 -side left - } - - # input device 3 - if {$longform && [llength $midi_indevlist] > 3} { - frame $id.in3f - pack $id.in3f -side top - - label $id.in3f.l1 -text "input device 3:" - button $id.in3f.x1 -text [lindex $midi_indevlist $midi_indev3] \ - -command [list midi_popup $id $id.in3f.x1 midi_indev3 \ - $midi_indevlist] - pack $id.in3f.l1 $id.in3f.x1 -side left - } - - # input device 4 - if {$longform && [llength $midi_indevlist] > 4} { - frame $id.in4f - pack $id.in4f -side top - - label $id.in4f.l1 -text "input device 4:" - button $id.in4f.x1 -text [lindex $midi_indevlist $midi_indev4] \ - -command [list midi_popup $id $id.in4f.x1 midi_indev4 \ - $midi_indevlist] - pack $id.in4f.l1 $id.in4f.x1 -side left - } - - # output device 1 - - frame $id.out1f - pack $id.out1f -side top - label $id.out1f.l1 -text "output device 1:" - button $id.out1f.x1 -text [lindex $midi_outdevlist $midi_outdev1] \ - -command [list midi_popup $id $id.out1f.x1 midi_outdev1 \ - $midi_outdevlist] - pack $id.out1f.l1 $id.out1f.x1 -side left - - # output device 2 - if {$longform && [llength $midi_outdevlist] > 2} { - frame $id.out2f - pack $id.out2f -side top - label $id.out2f.l1 -text "output device 2:" - button $id.out2f.x1 -text [lindex $midi_outdevlist $midi_outdev2] \ - -command \ - [list midi_popup $id $id.out2f.x1 midi_outdev2 $midi_outdevlist] - pack $id.out2f.l1 $id.out2f.x1 -side left - } - - # output device 3 - if {$longform && [llength $midi_outdevlist] > 3} { - frame $id.out3f - pack $id.out3f -side top - label $id.out3f.l1 -text "output device 3:" - button $id.out3f.x1 -text [lindex $midi_outdevlist $midi_outdev3] \ - -command \ - [list midi_popup $id $id.out3f.x1 midi_outdev3 $midi_outdevlist] - pack $id.out3f.l1 $id.out3f.x1 -side left - } - - # output device 4 - if {$longform && [llength $midi_outdevlist] > 4} { - frame $id.out4f - pack $id.out4f -side top - label $id.out4f.l1 -text "output device 4:" - button $id.out4f.x1 -text [lindex $midi_outdevlist $midi_outdev4] \ - -command \ - [list midi_popup $id $id.out4f.x1 midi_outdev4 $midi_outdevlist] - pack $id.out4f.l1 $id.out4f.x1 -side left - } - - # if not the "long form" make a button to - # restart with longform set. - - if {$longform == 0} { - frame $id.longbutton - pack $id.longbutton -side top - button $id.longbutton.b -text {use multiple alsa devices} \ - -command {pdsend "pd midi-properties 1"} - pack $id.longbutton.b - } - } - if {$alsa} { - label $id.in1f.l1 -text "In Ports:" - entry $id.in1f.x1 -textvariable midi_alsain -width 4 - pack $id.in1f.l1 $id.in1f.x1 -side left - label $id.in1f.l2 -text "Out Ports:" - entry $id.in1f.x2 -textvariable midi_alsaout -width 4 - pack $id.in1f.l2 $id.in1f.x2 -side left - } -} - -############ pdtk_path_dialog -- dialog window for search path ######### - -proc path_apply {id} { - global pd_extrapath pd_verbose - global pd_path_count - set pd_path {} - - for {set x 0} {$x < $pd_path_count} {incr x} { - global pd_path$x - set this_path [set pd_path$x] - if {0==[string match "" $this_path]} { - lappend pd_path [pdtk_encodedialog $this_path] - } - } - - pdsend [concat pd path-dialog $pd_extrapath $pd_verbose $pd_path \;] -} - -proc path_cancel {id} { - pdsend [concat $id cancel \;] -} - -proc path_ok {id} { - path_apply $id - path_cancel $id -} - -proc pdtk_path_dialog {id extrapath verbose} { - global pd_extrapath pd_verbose - global pd_path - global pd_path_count - - set pd_path_count [expr [llength $pd_path] + 2] - if { $pd_path_count < 10 } { set pd_path_count 10 } - - for {set x 0} {$x < $pd_path_count} {incr x} { - global pd_path$x - set pd_path$x [lindex $pd_path $x] - } - - set pd_extrapath $extrapath - set pd_verbose $verbose - toplevel $id - wm title $id {PD search path for patches and other files} - wm protocol $id WM_DELETE_WINDOW [concat path_cancel $id] - - frame $id.buttonframe - pack $id.buttonframe -side bottom -fill x -pady 2m - button $id.buttonframe.cancel -text {Cancel}\ - -command "path_cancel $id" - button $id.buttonframe.apply -text {Apply}\ - -command "path_apply $id" - button $id.buttonframe.ok -text {OK}\ - -command "path_ok $id" - pack $id.buttonframe.cancel -side left -expand 1 - pack $id.buttonframe.apply -side left -expand 1 - pack $id.buttonframe.ok -side left -expand 1 - - frame $id.extraframe - pack $id.extraframe -side bottom -fill x -pady 2m - checkbutton $id.extraframe.extra -text {use standard extensions} \ - -variable pd_extrapath -anchor w - checkbutton $id.extraframe.verbose -text {verbose} \ - -variable pd_verbose -anchor w - button $id.extraframe.save -text {Save all settings}\ - -command "path_apply $id \; pdsend \"pd save-preferences\"" - pack $id.extraframe.extra $id.extraframe.verbose $id.extraframe.save \ - -side left -expand 1 - - for {set x 0} {$x < $pd_path_count} {incr x} { - entry $id.f$x -textvariable pd_path$x -width 80 - bind $id.f$x <KeyPress-Return> [concat path_ok $id] - pdtk_standardkeybindings $id.f$x - pack $id.f$x -side top - } - - focus $id.f0 -} - -proc pd_set {var value} { - global $var - set $var $value -} - -########## pdtk_startup_dialog -- dialog window for startup options ######### - -proc startup_apply {id} { - global pd_nort pd_flags - global pd_startup_count - - set pd_startup {} - for {set x 0} {$x < $pd_startup_count} {incr x} { - global pd_startup$x - set this_startup [set pd_startup$x] - if {0==[string match "" $this_startup]} {lappend pd_startup [pdtk_encodedialog $this_startup]} - } - - pdsend [concat pd startup-dialog $pd_nort [pdtk_encodedialog $pd_flags] $pd_startup \;] -} - -proc startup_cancel {id} { - pdsend [concat $id cancel \;] -} - -proc startup_ok {id} { - startup_apply $id - startup_cancel $id -} - -proc pdtk_startup_dialog {id nort flags} { - global pd_nort pd_flags - global pd_startup - global pd_startup_count - - set pd_startup_count [expr [llength $pd_startup] + 2] - if { $pd_startup_count < 10 } { set pd_startup_count 10 } - - for {set x 0} {$x < $pd_startup_count} {incr x} { - global pd_startup$x - set pd_startup$x [lindex $pd_startup $x] - } - - set pd_nort $nort - set pd_flags $flags - toplevel $id - wm title $id {Pd binaries to load (on next startup)} - wm protocol $id WM_DELETE_WINDOW [concat startup_cancel $id] - - frame $id.buttonframe - pack $id.buttonframe -side bottom -fill x -pady 2m - button $id.buttonframe.cancel -text {Cancel}\ - -command "startup_cancel $id" - button $id.buttonframe.apply -text {Apply}\ - -command "startup_apply $id" - button $id.buttonframe.ok -text {OK}\ - -command "startup_ok $id" - pack $id.buttonframe.cancel -side left -expand 1 - pack $id.buttonframe.apply -side left -expand 1 - pack $id.buttonframe.ok -side left -expand 1 - - frame $id.flags - pack $id.flags -side bottom - label $id.flags.entryname -text {startup flags} - entry $id.flags.entry -textvariable pd_flags -width 80 - bind $id.flags.entry <KeyPress-Return> [concat startup_ok $id] - pdtk_standardkeybindings $id.flags.entry - pack $id.flags.entryname $id.flags.entry -side left - - frame $id.nortframe - pack $id.nortframe -side bottom -fill x -pady 2m - if {[tk windowingsystem] ne "win32"} { - checkbutton $id.nortframe.nort -text {defeat real-time scheduling} \ - -variable pd_nort -anchor w - } - button $id.nortframe.save -text {Save all settings}\ - -command "startup_apply $id \; pdsend \"pd save-preferences\"" - if {[tk windowingsystem] ne "win32"} { - pack $id.nortframe.nort $id.nortframe.save -side left -expand 1 - } else { - pack $id.nortframe.save -side left -expand 1 - } - - - - for {set x 0} {$x < $pd_startup_count} {incr x} { - entry $id.f$x -textvariable pd_startup$x -width 80 - bind $id.f$x <KeyPress-Return> [concat startup_ok $id] - pdtk_standardkeybindings $id.f$x - pack $id.f$x -side top - } - - focus $id.f0 -} - -########## data-driven dialog -- convert others to this someday? ########## - -proc ddd_apply {id} { - set vid [string trimleft $id .] - set var_count [concat ddd_count_$vid] - global $var_count - set count [eval concat $$var_count] - set values {} - - for {set x 0} {$x < $count} {incr x} { - set varname [concat ddd_var_$vid$x] - global $varname - lappend values [eval concat $$varname] - } - set cmd [concat $id done $values \;] - -# puts stderr $cmd - pd $cmd -} - -proc ddd_cancel {id} { - set cmd [concat $id cancel \;] -# puts stderr $cmd - pd $cmd -} - -proc ddd_ok {id} { - ddd_apply $id - ddd_cancel $id -} - -proc ddd_dialog {id dialogname} { - global ddd_fields - set vid [string trimleft $id .] - set count [llength $ddd_fields] - - set var_count [concat ddd_count_$vid] - global $var_count - set $var_count $count - - toplevel $id - label $id.label -text $dialogname - pack $id.label -side top - wm title $id "Pd dialog" - wm resizable $id 0 0 - wm protocol $id WM_DELETE_WINDOW [concat ddd_cancel $id] - - for {set x 0} {$x < $count} {incr x} { - set varname [concat ddd_var_$vid$x] - global $varname - set fieldname [lindex $ddd_fields $x 0] - set $varname [lindex $ddd_fields $x 1] - frame $id.frame$x - pack $id.frame$x -side top -anchor e - label $id.frame$x.label -text $fieldname - entry $id.frame$x.entry -textvariable $varname -width 20 - bind $id.frame$x.entry <KeyPress-Return> [concat ddd_ok $id] - pdtk_standardkeybindings $id.frame$x.entry - pack $id.frame$x.entry $id.frame$x.label -side right - } - - frame $id.buttonframe -pady 5 - pack $id.buttonframe -side top -fill x -pady 2 - button $id.buttonframe.cancel -text {Cancel}\ - -command "ddd_cancel $id" - button $id.buttonframe.apply -text {Apply}\ - -command "ddd_apply $id" - button $id.buttonframe.ok -text {OK}\ - -command "ddd_ok $id" - pack $id.buttonframe.cancel $id.buttonframe.apply \ - $id.buttonframe.ok -side left -expand 1 - -# $id.params.entry select from 0 -# $id.params.entry select adjust end -# focus $id.params.entry -} - |