aboutsummaryrefslogtreecommitdiff
path: root/extensions/gui/ix/toxy
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/gui/ix/toxy')
-rwxr-xr-xextensions/gui/ix/toxy/dd-demo.pd33
-rwxr-xr-xextensions/gui/ix/toxy/dd.wid32
-rwxr-xr-xextensions/gui/ix/toxy/dm-demo.pd32
-rwxr-xr-xextensions/gui/ix/toxy/dm.wid84
-rwxr-xr-xextensions/gui/ix/toxy/filter-demo.pd72
-rwxr-xr-xextensions/gui/ix/toxy/filter.wid286
-rwxr-xr-xextensions/gui/ix/toxy/grid-demo.pd69
-rwxr-xr-xextensions/gui/ix/toxy/grid.wid46
-rwxr-xr-xextensions/gui/ix/toxy/img-demo.pd60
-rwxr-xr-xextensions/gui/ix/toxy/img.wid41
-rwxr-xr-xextensions/gui/ix/toxy/kbd-demo.pd61
-rwxr-xr-xextensions/gui/ix/toxy/kbd.wid48
-rwxr-xr-xextensions/gui/ix/toxy/knob-demo.pd43
-rwxr-xr-xextensions/gui/ix/toxy/knob.wid102
-rwxr-xr-xextensions/gui/ix/toxy/lg-demo.pd68
-rwxr-xr-xextensions/gui/ix/toxy/lg.wid237
-rwxr-xr-xextensions/gui/ix/toxy/mat-demo.pd53
-rwxr-xr-xextensions/gui/ix/toxy/mat.wid688
-rw-r--r--extensions/gui/ix/toxy/ngrid-demo.pd310
-rwxr-xr-xextensions/gui/ix/toxy/ngrid.wid150
-rwxr-xr-xextensions/gui/ix/toxy/nob-demo.pd74
-rwxr-xr-xextensions/gui/ix/toxy/nob.wid105
-rwxr-xr-xextensions/gui/ix/toxy/q-demo.pd90
-rwxr-xr-xextensions/gui/ix/toxy/q.wid84
-rwxr-xr-xextensions/gui/ix/toxy/sp-demo.pd325
-rwxr-xr-xextensions/gui/ix/toxy/sp.wid36
-rwxr-xr-xextensions/gui/ix/toxy/spectrum-demo.pd171
-rwxr-xr-xextensions/gui/ix/toxy/spectrum.wid42
-rwxr-xr-xextensions/gui/ix/toxy/tile-demo.pd74
-rwxr-xr-xextensions/gui/ix/toxy/tile.wid87
-rwxr-xr-xextensions/gui/ix/toxy/tree-demo.pd184
-rwxr-xr-xextensions/gui/ix/toxy/tree.wid184
32 files changed, 3971 insertions, 0 deletions
diff --git a/extensions/gui/ix/toxy/dd-demo.pd b/extensions/gui/ix/toxy/dd-demo.pd
new file mode 100755
index 00000000..fb59154f
--- /dev/null
+++ b/extensions/gui/ix/toxy/dd-demo.pd
@@ -0,0 +1,33 @@
+#N canvas 170 459 559 300 12;
+#X obj 11 9 widget dd dt -bg black -width 38 -fg orange;
+#X obj 9 99 dac~;
+#X obj 10 77 *~ 0.3;
+#X obj 52 77 *~ 0.3;
+#X msg 11 33 open \$1 \, 1;
+#X obj 11 55 readsf~ 2;
+#X obj 290 33 widget dd df -bg purple -fg white -width 11;
+#X obj 99 65 widget dd dl2 -bg green -fg purple -width 22;
+#X symbolatom 93 96 30 0 0 0 - - -;
+#X obj 114 110 print;
+#X text 98 50 drop some files here..;
+#X obj 3 184 widget dd d12;
+#X msg 4 162 list la la la la;
+#X floatatom 326 82 5 0 0 0 - - -;
+#X msg 372 88 -width \$1;
+#X obj 344 114 tow . dd df;
+#X text 329 10 < drag amongst widgets;
+#X msg 273 96 clear;
+#X obj 169 137 widget q q -width 64 -height 12 -bg gray90 -fg blue
+;
+#X connect 0 0 4 0;
+#X connect 2 0 1 0;
+#X connect 3 0 1 1;
+#X connect 4 0 5 0;
+#X connect 5 0 2 0;
+#X connect 5 1 3 0;
+#X connect 7 0 8 0;
+#X connect 7 0 9 0;
+#X connect 7 0 18 0;
+#X connect 12 0 11 0;
+#X connect 13 0 14 0;
+#X connect 14 0 15 0;
diff --git a/extensions/gui/ix/toxy/dd.wid b/extensions/gui/ix/toxy/dd.wid
new file mode 100755
index 00000000..b82252ac
--- /dev/null
+++ b/extensions/gui/ix/toxy/dd.wid
@@ -0,0 +1,32 @@
+namespace eval ::ix {
+proc dd {path target symbol args} {
+ set sym [join [lrange $args 0 end] " "]
+ $path delete 0 end
+ $path insert 0 $sym
+ ddp $target $symbol $sym
+}
+proc ddp {target symbol stuff} {
+ if {$symbol == 1} {
+ pd "$target.rp _cb symbol [pdtk_enquote $stuff];"
+ } else {
+ pd "$target.rp _cb $stuff;"
+ }
+}
+}
+#> dd entry
+#. -selectforeground black -selectbackground green
+#. -bg blue -font .(helvetica 10.) -width 24 -borderwidth 0
+#. #symbol 1
+#. @bang ::ix::ddp .| .#symbol [.- get]
+#. @list ::ix::dd .- .| 0 .#args
+#. @symbol ::ix::dd .- .| 1 .#1
+#. @clear .- delete 0 end
+package require tkdnd
+puts "dd .- .|"
+bind .- <ButtonPress-1> {focus .-}
+dnd bindtarget .- text/uri-list <Drop> {foreach i %D {::ix::dd .- .| .#symbol [regsub -- "^file://" $i ""]}}
+dnd bindtarget .- text/plain <Drop> {::ix::dd .- .| .#symbol %D}
+dnd bindsource .- text/plain {return [.- get]}
+dnd bindsource .- text/uri-list {return "\{[.- get]\}"}
+bind .- <Button1-Leave> {dnd drag %W}
+bind .- <Return> {::ix::ddp .| .#symbol [.- get]}
diff --git a/extensions/gui/ix/toxy/dm-demo.pd b/extensions/gui/ix/toxy/dm-demo.pd
new file mode 100755
index 00000000..b128e211
--- /dev/null
+++ b/extensions/gui/ix/toxy/dm-demo.pd
@@ -0,0 +1,32 @@
+#N canvas 45 442 370 233 10;
+#X msg 190 127 clear;
+#X symbolatom 187 203 10 0 0 0 - - -;
+#X obj 187 155 widget dm dm1 #items .( zero one two three four five
+six seven eight nine ten eleven twelve thirteen i14 i15 i16 i17 i18
+i19 i20 i21 i22 i23 i24 i25 i26 i27 i28 i29 i30.) #arrows 0;
+#X obj 140 17 widget dm dm1 #items .(0 1 2 3 4 5 6 7 8 9 10 11 12.)
+-bg gray;
+#X obj 187 185 l2s;
+#X obj 56 119 l2s;
+#X msg 56 76 zero one two three four five six seven eight nine ten
+eleven twelve thirteen i14 i15 i16 i17 i18 i19 i20 i21 i22 i23 i24
+i25 i26 i27 i28 i29 i30;
+#X msg 4 60 list ichi ni san chi;
+#X msg 56 136 #items .( \$1.);
+#X msg 92 25 5;
+#X msg 89 8 12;
+#X msg 259 138 #arrows \$1;
+#X obj 258 122 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X connect 0 0 2 0;
+#X connect 2 0 4 0;
+#X connect 3 0 2 0;
+#X connect 4 0 1 0;
+#X connect 5 0 8 0;
+#X connect 6 0 5 0;
+#X connect 7 0 2 0;
+#X connect 8 0 2 0;
+#X connect 9 0 3 0;
+#X connect 10 0 3 0;
+#X connect 11 0 2 0;
+#X connect 12 0 11 0;
diff --git a/extensions/gui/ix/toxy/dm.wid b/extensions/gui/ix/toxy/dm.wid
new file mode 100755
index 00000000..389e31bb
--- /dev/null
+++ b/extensions/gui/ix/toxy/dm.wid
@@ -0,0 +1,84 @@
+#console show
+namespace eval ::ix {
+ variable _
+ proc spin_resize {w} {
+# update
+ $w config -height [winfo height $w] -width [winfo width $w]
+ }
+ proc spin {c w t bg fg font items arrows} {
+ if {[winfo exists $w.m] != 1} {
+ variable _
+ set _($t:p) 0
+ array set arrow "up \u25b2 dn \u25bc"; array set anchor "up n dn s"
+ menubutton $w.m -menu $w.m.m -textvariable _($t:t) -relief raised \
+ -bg $bg -fg $fg -font $font -padx 0 -pady 0
+ menu $w.m.m -bd 0 -bg $bg -fg $fg; pack $w.m -side left -fill y
+ if {$arrows == 1} {
+ foreach i {up dn} {
+ button $w.$i -padx 0 -pady 0 -text $arrow($i) \
+ -command "::ix::spinclick $w $t $i" \
+ -bd 0 -bg $bg -fg $fg -font {Times 6}
+ pack $w.$i -anchor $anchor($i)
+ }
+ }
+ spin_resize $w
+ foreach item $items {spinitem $w $t $item}
+ $w.m.m activate 0; $w.m.m invoke 0
+ }
+ }
+ proc spinitem {w t item} {
+ variable _
+ set len [$w.m.m index end];
+ if {$len ne "none"} {set n [expr $len + 1]} else {set n 0}
+ $w.m.m add radiobutton -selectcolor green -font {Tahoma 8} -label $item -variable _($t:t) -command "::ix::spinout $w $t $n"
+ set wider [string length $item]; set wide [$w.m cget -width]
+ if {$wide < $wider && $wider <= 31 } {
+ $w.m configure -width $wider
+ spin_resize $w
+ }
+ $w.m.m activate $n
+ }
+ proc spinout {w t i} {
+ set sym [$w.m.m entrycget $i -label]
+ pd [concat $t.rp _cb $sym \;]
+ $w.m.m activate $i
+ }
+ proc spinclick {w t d} {
+ variable _
+ array set shift "up -1 dn 1"
+ set len [$w.m.m index end];
+ set pos $_($t:p)
+ if {$pos != "none"} {
+ incr pos $shift($d)
+ if {$pos > $len} {set pos 0}
+ if {$pos < 0} {set pos $len}
+ $w.m.m activate $pos
+ $w.m.m invoke $pos
+ }
+ set _($t:p) $pos
+ }
+ proc spinclear {w} {
+ $w.m.m delete 0 end
+ $w.m configure -width 0
+ }
+}
+#> dm frame
+#. -bg green -padx 4 -pady 4 -height 40 -width 86 #arrows 1
+#. #bg black #fg "#8888ff" #items {} #font {Tahoma 10}
+#. @list foreach x [list .#args] {::ix::spinitem .- .| $x}
+#. @symbol ::ix::spinitem .- .| {.#1}
+#. @float .-.m.m invoke .#1 .: set ::ix::_(.|:p) .#1
+#. @clear ::ix::spinclear .-
+puts "dm .- .|"
+::ix::spin .^ .- .| .#bg .#fg .#font .#items .#arrows
+bind .- <Enter> {focus .-}
+bind .- <Leave> {focus .^.c}
+bind .- <<spin-dn>> {::ix::spinclick .- .| dn}
+bind .- <<spin-up>> {::ix::spinclick .- .| up}
+event add <<spin-dn>> <Key-space> <Key-Down> <Key-Right>
+event add <<spin-up>> <Key-Up> <Key-Left>
+foreach el {.- .-.m} {
+ bind $el <MouseWheel> {if {%D > 0} {::ix::spinclick .- .| up} else {::ix::spinclick .- .| dn}}
+ bind $el <Button-4> {::ix::spinclick .- .| up}
+ bind $el <Button-5> {::ix::spinclick .- .| dn}
+}
diff --git a/extensions/gui/ix/toxy/filter-demo.pd b/extensions/gui/ix/toxy/filter-demo.pd
new file mode 100755
index 00000000..c98ec407
--- /dev/null
+++ b/extensions/gui/ix/toxy/filter-demo.pd
@@ -0,0 +1,72 @@
+#N canvas 218 245 450 232 10;
+#X obj 51 67 widget filter f1 #div 8 #log 6.53061 #rate 44100 #n 5
+;
+#X msg 11 42 redefine;
+#X obj 185 259 biquad~;
+#X obj 223 259 biquad~;
+#X obj 261 259 biquad~;
+#X obj 298 259 biquad~;
+#X obj 336 259 biquad~;
+#X obj 52 276 multiplex~ 0 99 23 44 88 22;
+#X msg 35 18 #log \$1;
+#X obj 23 7 hsl 50 10 5 10 0 0 empty empty empty -2 -6 0 8 -262144
+-1 -1 0 1;
+#X msg 41 -10 10;
+#X msg 20 -10 0;
+#X floatatom 80 29 3 1 5 0 - - -;
+#X obj 189 278 biquad~;
+#X obj 225 278 biquad~;
+#X obj 263 278 biquad~;
+#X obj 300 278 biquad~;
+#X obj 337 278 biquad~;
+#X obj 52 293 multiplex~ 0 99 23 44 88 22;
+#X obj 51 225 route n params;
+#X msg 80 43 #n \$1;
+#X obj 206 242 route 1 2 3 4 5;
+#X obj 184 242 adc~;
+#X obj 52 310 dac~;
+#X connect 0 0 19 0;
+#X connect 1 0 0 0;
+#X connect 2 0 3 0;
+#X connect 2 0 7 1;
+#X connect 3 0 4 0;
+#X connect 3 0 7 2;
+#X connect 4 0 5 0;
+#X connect 4 0 7 3;
+#X connect 5 0 6 0;
+#X connect 5 0 7 4;
+#X connect 6 0 7 5;
+#X connect 7 0 23 0;
+#X connect 8 0 0 0;
+#X connect 9 0 8 0;
+#X connect 10 0 9 0;
+#X connect 11 0 8 0;
+#X connect 12 0 20 0;
+#X connect 13 0 14 0;
+#X connect 13 0 18 1;
+#X connect 14 0 15 0;
+#X connect 14 0 18 2;
+#X connect 15 0 16 0;
+#X connect 15 0 18 3;
+#X connect 16 0 17 0;
+#X connect 16 0 18 4;
+#X connect 17 0 18 5;
+#X connect 18 0 23 1;
+#X connect 19 0 7 0;
+#X connect 19 0 18 0;
+#X connect 19 1 21 0;
+#X connect 20 0 0 0;
+#X connect 21 0 2 0;
+#X connect 21 0 13 0;
+#X connect 21 1 3 0;
+#X connect 21 1 14 0;
+#X connect 21 2 4 0;
+#X connect 21 2 15 0;
+#X connect 21 3 5 0;
+#X connect 21 3 16 0;
+#X connect 21 4 6 0;
+#X connect 21 4 17 0;
+#X connect 22 0 7 0;
+#X connect 22 0 2 0;
+#X connect 22 1 18 0;
+#X connect 22 1 13 0;
diff --git a/extensions/gui/ix/toxy/filter.wid b/extensions/gui/ix/toxy/filter.wid
new file mode 100755
index 00000000..b05c938a
--- /dev/null
+++ b/extensions/gui/ix/toxy/filter.wid
@@ -0,0 +1,286 @@
+namespace eval ::ix {
+ proc random_int {} {
+ return [expr "int(floor(rand()*16))"]
+ }
+ proc random_clr {} {
+ return [format "\#%1X%1X%1X%1X%1X%1X" [random_int] [random_int] [random_int] [random_int] [random_int] [random_int]]
+ }
+ variable _
+ proc filter_update {path target n} {
+ set type [$path.filter itemcget type_$n -text]
+ set q [$path.filter itemcget q_$n -text]
+ set loc [$path.filter coords sqr_$n]
+ set x [expr 5 + [lindex $loc 0]]
+ set y [expr 5 + [lindex $loc 1]]
+ set inv [filter_invtr $path $target $x $y]
+ set freq [lindex $inv 0]
+ set mag [lindex $inv 1]
+ filter_bqp $path $target $n $type $freq $mag $q
+ }
+ proc filter_bqp {path target n type f0 dBgain Q} {
+ variable _
+ set A [expr pow(10,($dBgain/40.0))]
+ set Fs $_($target:rate)
+ set pi [expr {atan(1) * 4}]
+ set w0 [expr 2 * $pi * $f0 / $Fs]
+ set alpha [expr sin($w0) / (2 * $Q)]
+ switch $type {
+ notch {
+ set b0 1
+ set b1 [expr -2 * cos($w0)]
+ set b2 1
+ set a0 [expr 1 + $alpha]
+ set a1 $b1
+ set a2 [expr 1 - $alpha]
+ }
+ lowpass {
+ set b0 [expr (1 - cos($w0))/2]
+ set b1 [expr 1 - cos($w0)]
+ set b2 $b0
+ set a0 [expr 1 + $alpha]
+ set a1 [expr -2 * cos($w0)]
+ set a2 [expr 1 - $alpha]
+ }
+ highpass {
+ set b0 [expr (1 + cos($w0))/2]
+ set b1 [expr -(1 + cos($w0))]
+ set b2 $b0
+ set a0 [expr 1 + $alpha]
+ set a1 [expr -2 * cos($w0)]
+ set a2 [expr 1 - $alpha]
+ }
+ qbandpass {
+ set b0 [expr sin($w0)/2]
+ set b1 0
+ set b2 [expr -$b0]
+ set a0 [expr 1 + $alpha]
+ set a1 [expr -2 * cos($w0)]
+ set a2 [expr 1 - $alpha]
+ }
+ bandpass {
+ set b0 $alpha
+ set b1 0
+ set b2 [expr -$alpha]
+ set a0 [expr 1 + $alpha]
+ set a1 [expr -2 * cos($w0)]
+ set a2 [expr 1 - $alpha]
+ }
+ allpass {
+ set b0 [expr 1 - $alpha]
+ set b1 [expr -2 * cos($w0)]
+ set b2 [expr 1 + $alpha]
+ set a0 $b2
+ set a1 $b1
+ set a2 $b0
+ }
+ peakingEQ {
+ set b0 [expr 1 + $alpha * $A]
+ set b1 [expr -2 * cos($w0)]
+ set b2 [expr 1 - $alpha * $A]
+ set a0 [expr 1 + $alpha / $A]
+ set a1 $b1
+ set a2 [expr 1 - $alpha / $A]
+ }
+ lowShelf {
+ set b0 [expr $A*(($A+1)-($A-1)*cos($w0)+2*sqrt($A)*$alpha)]
+ set b1 [expr 2*$A*(($A-1)-($A+1)*cos($w0))]
+ set b2 [expr $A*(($A+1)-($A-1)*cos($w0)-2*sqrt($A)*$alpha)]
+ set a0 [expr ($A+1)+($A-1)*cos($w0)+2*sqrt($A)*$alpha]
+ set a1 [expr -2*(($A-1)+($A+1)*cos($w0))]
+ set a2 [expr ($A+1)+($A-1)*cos($w0) - 2*sqrt($A)*$alpha ]
+ }
+ highShelf {
+ set b0 [expr $A*(($A+1)+($A-1)*cos($w0)+2*sqrt($A)*$alpha)]
+ set b1 [expr -2*$A*(($A-1)+($A+1)*cos($w0))]
+ set b2 [expr $A*(($A+1)+($A-1)*cos($w0)-2*sqrt($A)*$alpha)]
+ set a0 [expr ($A+1)-($A-1)*cos($w0)+2*sqrt($A)*$alpha]
+ set a1 [expr 2*(($A-1)-($A+1)*cos($w0))]
+ set a2 [expr ($A+1)-($A-1)*cos($w0) - 2*sqrt($A)*$alpha ]
+ }
+ }
+ set f 0
+ set fr {}
+ set _($target:fmag_$n) {1}
+ set h [winfo height $path.filter]
+ set h2 [expr $h / 2]
+ while {$f < [winfo width $path.filter]} {
+ incr f
+ set w [expr $pi * [filter_invtr_x $path $target $f] / $_($target:nyquist)]
+ set mag [expr sqrt(pow(($b0+$b1*cos($w)+$b2*cos(2*$w)),2)+pow(($b1*sin($w)+$b2*sin(2*$w)),2))/sqrt(pow(($a0+$a1*cos($w)+$a2*cos(2*$w)),2)+pow(($a1*sin($w)+$a2*sin(2*$w)),2))]
+ lappend fr $f [expr $h - $h2 * $mag]
+ lappend _($target:fmag_$n) $mag
+ }
+ $path.filter coords resp_$n $fr
+ pd [concat $target.rp _cb params $n [expr -1 * $a1 / $a0] [expr -1 * $a2 / $a0] [expr $b0 / $a0] [expr $b1 / $a0] [expr $b2 / $a0] \;]
+ filter_resp $path $target
+ }
+ proc filter_resp {path target} {
+ variable _
+ if {$_($target:init) == 1} {
+ set f 0
+ set fr {}
+ set h [winfo height $path.filter]
+ set h2 [expr $h / 2]
+ while {$f < [winfo width $path.filter]} {
+ incr f
+ set cx 0
+ set ci 1
+ while {$cx < $_($target:n)} {
+ incr cx
+ set ci [expr $ci * [lindex $_($target:fmag_$cx) $f]]
+ }
+ lappend fr $f [expr $h - $h2 * $ci]
+ }
+ $path.filter coords resp $fr
+ }
+ }
+ proc filter_motion {path target x y} {
+ set v [filter_invtr $path $target $x $y]
+ $path itemconfigure freq -text "[expr int([lindex $v 0])] hz"
+# $path itemconfigure dB -text "[expr int([lindex $v 1])] dB"
+ }
+ proc filter_invtr {path target x y} {
+ return [list [filter_invtr_x $path $target $x] [filter_invtr_y $path $target $y]]
+ }
+ proc filter_invtr_x {path target x} {
+ variable _
+ set gw [winfo width $path]
+ if {$_($target:log) > 0} {
+ return [expr $_($target:scale) * exp($_($target:log) * $x / $gw.0)]
+ } else {
+ return freq [expr $_($target:nyquist) * $x / $gw.0]
+ }
+ }
+ proc filter_invtr_y {path target y} {
+ set gh [winfo height $path]
+ return [expr (12 * ($y / $gh.0 - 0.5) * - 1.0)]
+ }
+ proc filter_new {path target w h bg div log rate n} {
+ variable _
+ set _($target:init) 0
+ set _($target:n) $n
+ set _($target:log) $log
+ set _($target:rate) $rate
+ set _($target:nyquist) [expr $rate / 2]
+ set _($target:scale) [expr $_($target:nyquist) / exp($_($target:log))]
+ if {[winfo exists $path.filter] != 1} {
+ canvas $path.filter -bg $bg -width $w -height $h
+ pack $path.filter -side left
+ bind $path.filter <Motion> "::ix::filter_motion %W $target %x %y"
+# bind $path.filter <ButtonRelease> "::ix::filter_resp $path $target"
+ bind $path.filter <Leave> {
+ %W itemconfigure freq -text ""
+ %W itemconfigure dB -text ""
+ }
+ bind $path.filter <1> "::ix::filter_click $path $target %x %y"
+ bind $path.filter <B1-Motion> [bind $path.filter <1>]
+ filter_gridlines $path $target $div
+ filter_filters $path $target $n
+ $path.filter create text 2 1 -tags freq -text "" -anchor nw -justify left -font {{Bitstream Vera Sans} 9}
+# $path.filter create text 96 1 -tags dB -text "" -anchor ne -justify right -font {{Bitstream Vera Sans} 9}
+ $path.filter create line 0 0 0 0 -tags resp -fill grey44 -width 1.6
+ set fn 0
+ while {$fn < $n} {
+ incr fn
+ foreach a [list sqr_$fn type_$fn q_$fn] {$path.filter raise $a}
+ }
+ set bd [expr {[$path cget -bd] * 2}]
+ $path configure -bg $bg -width [expr [winfo width $path.filter] + $bd] -height [expr [winfo height $path.filter] + $bd]
+ }
+ pd "$target.rp _cb n $n;"
+ set _($target:init) 1
+ }
+ proc filter_filters {path target n} {
+ set gh [winfo height $path.filter]
+ set gw [winfo width $path.filter]
+ set fn 0
+ while {$fn < $n} {
+ incr fn
+ set px [expr $gw.0 * $fn.0 / $n.0]
+ set py [expr $gh.0 / 2.0]
+ set fill [random_clr]
+ $path.filter create rectangle 0 0 0 0 -tags sqr_$fn -fill $fill
+ $path.filter create line 0 0 0 0 -tags resp_$fn -fill $fill
+ $path.filter create text 0 0 -tags type_$fn -fill grey33 -font {{Bitstream Vera Sans} 8} -text "peakingEQ" -anchor e -justify right
+ $path.filter create text 0 0 -tags q_$fn -fill white -font {{Bitstream Vera Sans} 8} -text "1.0" -anchor w -justify left
+ set b1 "::ix::filter_move $path $target $fn %x %y"
+ set b2 "::ix::filter_menu $path $target $fn %X %Y"
+ set b3 "::ix::filter_move_q $path $target $fn %x %y"
+ set b4 "::ix::filter_locus $path $target $fn %x %y"
+ foreach a [list sqr_$fn type_$fn q_$fn] {
+ $path.filter bind $a <1> $b1
+ $path.filter bind $a <2> $b2
+ $path.filter bind $a <3> $b4
+ $path.filter bind $a <B3-Motion> $b3
+ $path.filter bind $a <B1-Motion> $b1
+ }
+ filter_move $path $target $fn $px $py
+ }
+ }
+ proc filter_menu {path target n x y} {
+ if {[winfo exists $path.ft] == 1} { destroy $path.ft}
+ set m [menu $path.ft -tearoff no]
+ foreach ft {lowpass highpass qbandpass bandpass notch allpass peakingEQ lowShelf highShelf} {
+ $m add command -label $ft -command "::ix::filter_type $path $target $n $ft"
+ }
+ tk_popup $path.ft $x $y
+ }
+ proc filter_type {path target n type} {
+ $path.filter itemconfigure type_$n -text "$type"
+ filter_update $path $target $n
+ }
+ proc filter_click {path target x y} {
+ variable _
+ filter_move $path $target $_($target:recent) $x $y
+ }
+ proc filter_move {path target n px py} {
+ variable _
+ $path.filter coords sqr_$n [expr $px - 5] [expr $py - 5] [expr $px + 5] [expr $py + 5]
+ $path.filter coords type_$n [expr $px - 9] [expr $py]
+ $path.filter coords q_$n [expr $px + 9] [expr $py]
+ filter_motion $path.filter $target $px $py
+ set _($target:recent) $n
+ filter_update $path $target $n
+ }
+ proc filter_locus {path target n px py} {
+ variable _
+ set _($target:lx) $px
+ }
+ proc filter_move_q {path target n px py} {
+ variable _
+ set delta [expr ($px.0 - $_($target:lx).0) / 25]
+ set move [expr [$path.filter itemcget q_$n -text] + $delta]
+ if {$move > 0} {
+ $path.filter itemconfigure q_$n -text $move
+ }
+ filter_update $path $target $n
+ set _($target:lx) $px
+ }
+ proc filter_gridlines {path target lines} {
+ variable _
+ puts "gridlines"
+ set color white
+ set w $path.filter
+ $w delete gridlines
+ set gh [winfo height $w]
+ set gw [winfo width $w]
+ for {set x 1} {$x <= $lines} {incr x} {
+ if {$lines < 16 && $lines > 0} {
+ set oh [expr $gh.0 * $x.0 / $lines.0]
+ set ow [expr $gw.0 * $x.0 / $lines.0]
+ $w create line $ow 0 $ow $gh -fill $color -tags gridlines
+ $w create line 0 $oh $gw $oh -fill $color -tags gridlines
+ set fontsize [expr int(80.0/$lines.0)]
+ $w create text $ow [expr $gh - $fontsize] -font [list {Bitstream Vera Sans} $fontsize] -tags gridlines -text [expr int([filter_invtr_x $path $target $ow])]
+ }
+ }
+ $w raise ${target}sqr
+ }
+}
+#> filter frame
+#. -bd 3 #w 384 #h 144 #bg gray90 #div 6 #n 3
+#. #log 1 #rate 44100
+#. @div ::ix::filter_gridlines .- .| .#1
+#. @params ::ix::filter_lp .- .| .#args
+puts "filter .- .|"
+::ix::filter_new .- .| .#w .#h .#bg .#div .#log .#rate .#n
diff --git a/extensions/gui/ix/toxy/grid-demo.pd b/extensions/gui/ix/toxy/grid-demo.pd
new file mode 100755
index 00000000..24a2dc66
--- /dev/null
+++ b/extensions/gui/ix/toxy/grid-demo.pd
@@ -0,0 +1,69 @@
+#N canvas 361 266 709 441 12;
+#X obj 88 210 pack 0 0;
+#X floatatom 151 352 7 0 0 0 - - -;
+#X floatatom 200 351 7 0 0 0 - - -;
+#X obj 151 331 unpack;
+#X obj 151 228 widget grid g5a #bg white #fg purple #div 5 #shape rectangle
+#w 95 #h 95 #ln pink #x 0.889764 #size 56 -width 55 -height 55;
+#X obj 270 184 widget grid g3;
+#X obj 402 154 widget grid g4 #fg orange #bg black #w 264 #h 159 #div
+0;
+#X obj 269 53 widget grid gg #shape oval #bg orange #fg pink #ln white
+#div 2 #size 67;
+#X obj 136 53 widget grid bllldie #bg red #fg white #ln gray #shape
+arc #size 44 #div 22;
+#X floatatom 131 12 5 0 0 0 - - -;
+#X msg 131 30 #div \$1;
+#X msg 269 31 #size \$1;
+#X floatatom 269 13 5 0 0 0 - - -;
+#X floatatom 403 110 5 0 0 0 - - -;
+#X msg 403 129 #w \$1;
+#X floatatom 442 110 5 0 0 0 - - -;
+#X msg 442 129 #h \$1;
+#X obj 66 174 random 100;
+#X obj 43 133 t b b;
+#X obj 29 157 random 100;
+#X obj 44 198 * 0.01;
+#X obj 43 97 bng 33 250 50 0 empty empty empty 0 -6 0 8 -225271 -1
+-1;
+#X obj 135 186 / 100;
+#X text 426 25 #w #h #bg #fg #ln #div #shape #size;
+#X obj 530 81 tot .;
+#X msg 529 57 tot console show;
+#X obj 199 370 * 200;
+#X obj 339 315 widget grid g3902 #bg green #fg gray #ln yellow #div
+3 #w 97 #h 97;
+#X obj 456 376 widget grid #bg #fg gray #w 32 #h 32;
+#X obj 149 395 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 10
+-262144 -1 -1 0.66 256;
+#X obj 35 71 metro 333;
+#X obj 40 46 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X connect 0 0 4 0;
+#X connect 2 0 26 0;
+#X connect 3 0 1 0;
+#X connect 3 0 29 0;
+#X connect 3 1 2 0;
+#X connect 4 0 3 0;
+#X connect 5 0 8 0;
+#X connect 6 0 5 0;
+#X connect 7 0 5 0;
+#X connect 9 0 10 0;
+#X connect 10 0 8 0;
+#X connect 11 0 7 0;
+#X connect 12 0 11 0;
+#X connect 13 0 14 0;
+#X connect 14 0 6 0;
+#X connect 15 0 16 0;
+#X connect 16 0 6 0;
+#X connect 17 0 22 0;
+#X connect 18 0 19 0;
+#X connect 18 1 17 0;
+#X connect 19 0 20 0;
+#X connect 20 0 0 0;
+#X connect 21 0 18 0;
+#X connect 22 0 0 1;
+#X connect 25 0 24 0;
+#X connect 30 0 21 0;
+#X connect 31 0 30 0;
+#X coords 0 0 1 1 200 140 1;
diff --git a/extensions/gui/ix/toxy/grid.wid b/extensions/gui/ix/toxy/grid.wid
new file mode 100755
index 00000000..1d177ad8
--- /dev/null
+++ b/extensions/gui/ix/toxy/grid.wid
@@ -0,0 +1,46 @@
+namespace eval ::ix {
+ proc grid_click {w target r hy hx hh ww size} {
+ switch $r {
+ 0 { set y [expr $hy / $hh.0]
+ set x [expr $hx / $ww.0]}
+ 1 { set x $hx
+ set y $hy
+ set hx [expr $ww * $hx]
+ set hy [expr $hh * $hy]}}
+ set rs [expr $size / 2]
+ $w coords ${target}sqr [expr $hx - $rs] [expr $hy - $rs] [expr $hx + $rs] [expr $hy + $rs]
+ pd "$target.rp _cb $x $y;"
+ }
+ proc grid_new {path target w h bg fg ln div shape size} {
+ if {[winfo exists $path.grid] != 1} {
+ canvas $path.grid -bg $bg
+ $path configure -width $w -height $h
+ place $path.grid -anchor nw -relwidth 1 -relheight 1
+ $path.grid create $shape 0 0 0 0 -fill $fg -tags ${target}sqr
+ grid_click $path.grid $target 1 0.5 0.5 $h $w $size
+ grid_lines $path.grid $target $div $w $h $ln
+ bind $path.grid <1> "::ix::grid_click %W $target 0 %y %x $h $w $size"
+ bind $path.grid <B1-Motion> "::ix::grid_click %W $target 0 %y %x $h $w $size"
+ }
+ }
+ proc grid_lines {w target lines ww hw color} {
+ $w delete gridlines
+ for {set x 1} {$x <= $lines} {incr x} {
+ if {$lines < 64} {
+ set oh [expr $hw.0 * $x.0 / $lines.0]
+ set ow [expr $ww.0 * $x.0 / $lines.0]
+ $w create line $ow 0 $ow $hw -fill $color -tags gridlines
+ $w create line 0 $oh $ww $oh -fill $color -tags gridlines
+ }
+ }
+ $w raise ${target}sqr
+ }
+}
+#> grid frame
+#. -bd 3
+#. #w 128 #h 128 #x 0.5 #y 0.5
+#. #fg red #bg blue #ln yellow
+#. #shape rectangle #size 12 #div 5
+#. @list ::ix::grid_click .-.grid .| 1 .#2 .#1 .#h .#w .#size
+
+::ix::grid_new .- .| .#w .#h .#bg .#fg .#ln .#div .#shape .#size
diff --git a/extensions/gui/ix/toxy/img-demo.pd b/extensions/gui/ix/toxy/img-demo.pd
new file mode 100755
index 00000000..195d86a8
--- /dev/null
+++ b/extensions/gui/ix/toxy/img-demo.pd
@@ -0,0 +1,60 @@
+#N canvas 0 0 818 675 12;
+#X obj 134 121 widget img i1;
+#X obj 328 135 widget img img__guns #src /var/www/_/_i/p/_guns.gif
+;
+#X obj 328 167 widget img img__lunch #src /var/www/_/_i/p/_lunch.gif
+;
+#X obj 308 205 widget img img__roast #src /var/www/_/_i/p/_roast.gif
+;
+#X obj 328 231 widget img img__door #src /var/www/_/_i/p/_door.gif
+;
+#X obj 328 263 widget img img__fruit #src /var/www/_/_i/p/_fruit.gif
+;
+#X obj 328 295 widget img img__crop #src /var/www/_/_i/p/_crop.gif
+;
+#X obj 328 327 widget img img__twogirls #src /var/www/_/_i/p/_twogirls.gif
+#mouseover 1;
+#X obj 328 359 widget img img__345 #src /var/www/_/_i/p/_345.gif;
+#X obj 328 391 widget img img__machinery #src /var/www/_/_i/p/_machinery.gif
+;
+#X obj 175 252 route _roast _guns;
+#X obj 175 280 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 224 275 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 170 222 a2l;
+#X obj 172 174 print wtf;
+#X obj 189 131 a2l;
+#X obj 381 -297 widget img img_guns #src /var/www/_/_i/p/guns.jpg;
+#X obj 96 132 widget img img__pissers #src /var/www/_/_i/p/_pissers.gif
+;
+#X obj 96 164 widget img img__w3 #src /var/www/_/_i/p/_w3.gif;
+#X obj 96 196 widget img img__w1 #src /var/www/_/_i/p/_w1.gif;
+#X obj 96 228 widget img img__db #src /var/www/_/_i/p/_db.gif;
+#X obj 96 260 widget img img__w4 #src /var/www/_/_i/p/_w4.gif;
+#X obj 96 292 widget img img__scream #src /var/www/_/_i/p/_scream.gif
+;
+#X obj 96 324 widget img img__chair #src /var/www/_/_i/p/_chair.gif
+;
+#X obj 96 356 widget img img__dog #src /var/www/_/_i/p/_dog.gif;
+#X obj 96 388 widget img img__w2 #src /var/www/_/_i/p/_w2.gif;
+#X obj 96 420 widget img img__h #src /var/www/_/_i/p/_h.gif;
+#X obj 96 452 widget img img__shitters #src /var/www/_/_i/p/_shitters.gif
+;
+#X obj 96 484 widget img img__violation #src /var/www/_/_i/p/_violation.gif
+;
+#X obj 96 516 widget img img__melt #src /var/www/_/_i/p/_melt.gif;
+#X msg 206 326 #mouseover \$1;
+#X obj 209 303 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X connect 1 0 13 0;
+#X connect 3 0 13 0;
+#X connect 3 0 15 0;
+#X connect 7 0 14 0;
+#X connect 10 0 11 0;
+#X connect 10 1 12 0;
+#X connect 13 0 10 0;
+#X connect 15 0 14 0;
+#X connect 16 0 14 0;
+#X connect 30 0 7 0;
+#X connect 31 0 30 0;
diff --git a/extensions/gui/ix/toxy/img.wid b/extensions/gui/ix/toxy/img.wid
new file mode 100755
index 00000000..34c82dfe
--- /dev/null
+++ b/extensions/gui/ix/toxy/img.wid
@@ -0,0 +1,41 @@
+#console show
+package require Img
+package require tkdnd
+namespace eval ::ix {
+ variable _
+ proc drop_pics {name files x y} {
+ set c 0
+ for {set n 0} {$n < [llength $files]} {incr n} {
+ if {[regexp {.*/(.+)\.[a-zA-Z0-9]+$} [lindex $files $n] file obj] == 1} {
+ pd [concat $name obj $x [expr $y + ($c * 32)] widget img [pdtk_enquote [string tolower "img_${obj}"]] #src [pdtk_enquote [regsub -- "^file:" [lindex $files $n] ""]] \;]
+ incr c
+ }
+ }
+ }
+ proc pic {c p t src mouseover} {
+ variable _
+ image create photo $t
+ $p configure -image $t
+ if {$src ne "none" && [file exists $src]} {
+ $t configure -file $src
+ set cb "pd \"$t _cb [lindex [regexp -inline {.*/(.+)\.[a-zA-Z0-9]+$} $src] 1] \;\""
+ bind $p <Enter> "$t configure -gamma 2"
+ if {$mouseover != 0} {
+ bind $p <Enter> +$cb
+ }
+ bind $p <Leave> "$t configure -gamma 1"
+ bind $p <ButtonPress-1> "+$t configure -gamma 0.5; $cb"
+ bind $p <ButtonRelease-> "+$t configure -gamma 1"
+ } else {
+ $t configure -format gif -data {R0lGODdhDgAQAKIAAICAgP///8DAwAAAAP8AAP///////////ywAAAAADgAQAAADWQi63Bi6HIIDGLocggMYuhyCAxi6HIIDEUFIEUSBIQMRGEFEhKEyoBoQUUQEykBEYBARBUbIQGAEUQQSRcggYOhyCA5g6HIIDmDocggOYOhyCA6g6LLi6HInADs=}
+ dnd bindtarget $c.c text/uri-list <Drop> "::ix::drop_pics $c %D %x %y"
+ }
+ set _($t:loc) 0
+ }
+}
+#> img label
+#. -borderwidth 0
+#. #src none #mouseover 1
+#. @bang puts "bang"
+::ix::pic .^ .- .| {.#src} .#mouseover
+puts "pic .- .|"
diff --git a/extensions/gui/ix/toxy/kbd-demo.pd b/extensions/gui/ix/toxy/kbd-demo.pd
new file mode 100755
index 00000000..a9baf395
--- /dev/null
+++ b/extensions/gui/ix/toxy/kbd-demo.pd
@@ -0,0 +1,61 @@
+#N canvas 360 12 574 324 12;
+#X obj 56 57 widget kbd k1 #octaves 7 -width 444.094 -height 63.4421
+;
+#X obj 56 134 unpack;
+#X floatatom 56 155 5 0 0 0 - - -;
+#X floatatom 90 155 5 0 0 0 - - -;
+#X floatatom 98 135 5 0 0 0 - - -;
+#X obj 56 29 pack 0 1;
+#X floatatom 56 13 5 0 0 0 - - -;
+#X obj 99 14 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X floatatom 21 32 5 0 0 0 - - -;
+#X obj 56 217 osc~ 440;
+#X obj 56 196 mtof;
+#X obj 110 217 line~;
+#X msg 110 195 \$1 100;
+#X obj 80 265 dac~ 1 2;
+#X obj 81 242 *~;
+#X obj 92 173 * 0.4;
+#X floatatom 149 21 5 0 12 0 - - -;
+#X msg 148 38 #octaves \$1;
+#X obj 143 134 widget kbd k2 #octaves 3 #bg hotpink #fg orange -height
+32;
+#X obj 56 174 + 36;
+#X obj 345 134 widget kbd k2 #octaves 3 #bg blue #fg cyan -height 32
+;
+#X obj 207 232 * 127;
+#X obj 171 230 + 36;
+#X obj 171 265 noteout;
+#X obj 170 203 unpack 0 0 0;
+#X obj 160 172 Append 1;
+#X obj 232 173 Append 2;
+#X connect 0 0 1 0;
+#X connect 0 0 4 0;
+#X connect 1 0 2 0;
+#X connect 1 1 3 0;
+#X connect 2 0 19 0;
+#X connect 3 0 15 0;
+#X connect 5 0 0 0;
+#X connect 6 0 5 0;
+#X connect 7 0 5 1;
+#X connect 8 0 0 0;
+#X connect 9 0 14 0;
+#X connect 10 0 9 0;
+#X connect 11 0 14 1;
+#X connect 12 0 11 0;
+#X connect 14 0 13 0;
+#X connect 14 0 13 1;
+#X connect 15 0 12 0;
+#X connect 16 0 17 0;
+#X connect 17 0 0 0;
+#X connect 18 0 25 0;
+#X connect 19 0 10 0;
+#X connect 20 0 26 0;
+#X connect 21 0 23 1;
+#X connect 22 0 23 0;
+#X connect 24 0 22 0;
+#X connect 24 1 21 0;
+#X connect 24 2 23 2;
+#X connect 25 0 24 0;
+#X connect 26 0 24 0;
diff --git a/extensions/gui/ix/toxy/kbd.wid b/extensions/gui/ix/toxy/kbd.wid
new file mode 100755
index 00000000..06c1d7e7
--- /dev/null
+++ b/extensions/gui/ix/toxy/kbd.wid
@@ -0,0 +1,48 @@
+namespace eval ::ix {
+ proc kbd_list {p t args} {
+ variable _
+ set w $p.f[expr [lindex $args 0] / 12].[lindex $args 0]
+ if {[llength $args] == 1} {set v 1;if {$_($t:lp) != -1 && $_($t:lp) ne $w} {kbd_action $_($t:lp) $t 0}} {set v [lindex $args 1]}
+ kbd_action $w $t $v
+ set _($t:lp) $w}
+
+ proc kbd_play {t m b x y} {
+ variable _
+ foreach a {{rs {0 sunken 1 raised}} {v {0 0 1 {($y - [winfo rooty $w]) / ([winfo height $w] + 0.0)}}}} {array set [lindex $a 0] [lindex $a 1]}
+ set w [winfo containing $x $y]
+ if {$m != 1 && $_($t:lp) != -1 && $_($t:lp) ne $w} {kbd_action $_($t:lp) $t 0}
+ if {[$w cget -relief] eq $rs($b)} {kbd_action $w $t [eval expr $v($b)]}
+ set _($t:lp) $w}
+
+ proc kbd_action {w t v} {
+ if {$v == 0} {set relief raised} {set relief sunken}
+ $w config -relief $relief
+ pd [concat $t.rp _cb [winfo name $w] $v \;]}
+
+ proc kbd_off {p t octaves} {
+ for {set o 0} {$o < $octaves} {incr o} {
+ for {set on 0} {$on < 12} {incr on} {
+ set w $p.f$o.[expr $o * 12 + $on]
+ if {[$w cget -relief] eq "sunken"} {kbd_action $w $t 0}}}}
+
+ proc kbd {path t octaves b f} {
+ $path config -width [expr $octaves * 66]
+ if {![winfo exists $path.f0]} {
+ variable _
+ set _($t:lp) -1
+ set bw {0 1 0 1 0 0 1 0 1 0 1 0} ; set npl {0 1 1 2 2 3 4 4 5 5 6 6}
+ foreach a {{bg "0 $b 1 $f"} {fg "1 $b 0 $f"} {an {0 ";lower $wk" 1 "-anchor n"}} {rw {0 {[expr 1 / 7.]} 1 {[expr 1 / 10.]}}} {rh {0 {[expr 1.]} 1 {[expr 6 / 10.]}}}} {array set [lindex $a 0] [lindex $a 1]}
+ for {set o 0} {$o < $octaves} {incr o} {
+ set w $path.f$o ; frame $w -bd 0 -height 66 -width 66
+ for {set on 0} {$on < 12} {incr on} {
+ set wk $w.[expr $o * 12 + $on] ; set n [lindex $bw $on]
+ eval "label $wk -bg $bg($n) -fg $fg($n) -bd 1 -relief raised;place $wk -relx [expr [lindex $npl $on] / 7.] -y 0 -relwidth $rw($n) -relheight $rh($n) $an($n)"
+ bind $wk <1> "::ix::kbd_play $t 0 1 %X %Y"; bind $wk <B1-Motion> [bind $wk <1>];bind $wk <ButtonRelease-1> "::ix::kbd_play $t 0 0 %X %Y"; bind $wk <Enter> "::ix::kbd_play $t 1 0 %X %Y"; bind $wk <3> "::ix::kbd_play $t 1 1 %X %Y"; bind $wk <B3-Motion> [bind $wk <3>]; bind $wk <2> "::ix::kbd_off $path $t $octaves"}
+ place $w -y 0 -relheight 1.0 -relx [expr $o / $octaves.0] -relwidth [expr 1 / $octaves.0]}}}}
+
+#> kbd frame
+#. -height 100 -width 60
+#. #octaves 6 #bg black #fg white
+#. @list ::ix::kbd_list .- .| .#args
+#. @float ::ix::kbd_list .- .| .#args
+::ix::kbd .- .| .#octaves .#bg .#fg
diff --git a/extensions/gui/ix/toxy/knob-demo.pd b/extensions/gui/ix/toxy/knob-demo.pd
new file mode 100755
index 00000000..3d1035af
--- /dev/null
+++ b/extensions/gui/ix/toxy/knob-demo.pd
@@ -0,0 +1,43 @@
+#N canvas 403 277 313 218 12;
+#X floatatom 157 24 5 16 1024 0 - - -;
+#X msg 157 42 #w \$1 \, #h \$1;
+#X floatatom 194 7 5 3 22 0 - - -;
+#X obj 13 148 nbx 8 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 10
+-262144 -1 -1 -0.0116279 256;
+#X obj 13 39 widget knob n1 #w 88 #h 88 #th 3 #cc purple #cb black
+#ca red #trans 81 #bg green #range 1 #cn navy #ny 79 #nx 43 #max 0
+#min 0 #an white -bd 1;
+#X msg 135 109 #range \$1;
+#X msg 157 144 1;
+#X msg 184 144 10000;
+#X floatatom 203 94 5 0 0 0 - - -;
+#X msg 203 109 #ny \$1;
+#X floatatom 203 61 5 0 0 0 - - -;
+#X msg 203 76 #nx \$1;
+#X msg 157 170 #max 1;
+#X msg 202 170 #max 32 \, #min 16;
+#X msg 157 190 #min 0 \, #max 0;
+#X msg 103 107 1;
+#X msg 103 85 100;
+#X msg 104 63 1000;
+#X msg 104 41 0.1;
+#X msg 194 23 #th \$1;
+#X connect 0 0 1 0;
+#X connect 1 0 4 0;
+#X connect 2 0 19 0;
+#X connect 4 0 3 0;
+#X connect 5 0 4 0;
+#X connect 6 0 4 0;
+#X connect 7 0 4 0;
+#X connect 8 0 9 0;
+#X connect 9 0 4 0;
+#X connect 10 0 11 0;
+#X connect 11 0 4 0;
+#X connect 12 0 4 0;
+#X connect 13 0 4 0;
+#X connect 14 0 4 0;
+#X connect 15 0 5 0;
+#X connect 16 0 5 0;
+#X connect 17 0 5 0;
+#X connect 18 0 5 0;
+#X connect 19 0 4 0;
diff --git a/extensions/gui/ix/toxy/knob.wid b/extensions/gui/ix/toxy/knob.wid
new file mode 100755
index 00000000..450f1baf
--- /dev/null
+++ b/extensions/gui/ix/toxy/knob.wid
@@ -0,0 +1,102 @@
+namespace eval ::ix {
+ variable _
+ proc nobfloat {path t num} {
+ variable _
+ $path itemconfigure $t:num -text $num
+ pd [concat $t.rp _cb $num \;]
+ set _($t:num) $num
+ }
+ proc nob_mover {w t f x y} {
+ variable _
+ if {$::ix::_($t:clickd) > 0} {
+ set move [expr (($x - $::ix::_($t:lx)) + (-1 * ($y - $::ix::_($t:ly)))) / ([winfo width $w].0 + [winfo height $w].0) * $f]
+ nob_move $w $t $move
+ }
+ set ::ix::_($t:clickd) 1
+ set ::ix::_($t:lx) $x
+ set ::ix::_($t:ly) $y
+ }
+ proc nob_move {w t move} {
+ variable _
+ set on [$w itemcget $t:num -text]
+ set no [expr $on + $_($t:range) * $move * 2]
+ if {$_($t:min) != $_($t:max)} {
+ if {$no > $_($t:max)} {set no $_($t:max);set move 0}
+ if {$no < $_($t:min)} {set no $_($t:min);set move 0}
+ }
+ nobfloat $w $t $no
+ foreach e {1 10 100} {
+ set a [expr [$w itemcget $t:nob$e -start] + int($move * $e * 90)]
+ $w itemconfigure $t:nob$e -start $a
+ set _($t:a$e) $a
+ }
+ }
+
+ proc nob {path t w h range bg c1 c2 c3 cn th nx ny max min} {
+ variable _
+ set _($t:lx) 32
+ set _($t:clickd) -1
+ set _($t:max) $max
+ set _($t:min) $min
+ if {$_($t:min) != $_($t:max)} {
+ set _($t:range) [expr abs($min - $max)]
+ } else {
+ set _($t:range) $range
+ }
+ if {[winfo exists $path.nob] != 1} {
+ canvas $path.nob -width $w -height $h -borderwidth 1 -bg $bg
+ $path configure -width $w -height $h
+ place $path.nob -anchor nw -relwidth 1 -relheight 1
+ $path.nob delete *
+ set i 0
+ set colors [list $c1 $c2 $c3]
+ set ratios {1 10 0.1}
+ set edge 10
+ $path.nob create rectangle {1 1 8 4} -fill "#555555"
+ $path.nob create rectangle "1 $h 8 [expr $h - 5]" -fill "#555555"
+ foreach e {1 10 100} {
+ $path.nob create arc \
+ "[expr $w / $edge / ($i + 1) + ($edge / 2)] [expr $h / $edge / ($i + 1) + ($edge / 2)] [expr $w - $w / $edge / ($i + 1) - ($edge / 2)] [expr $h - $h / $edge / ($i + 1) - ($edge / 2)]" \
+ -extent [expr int(300 / $e)] -start 90 \
+ -outline "[lindex $colors $i]" \
+ -style arc \
+ -width [expr int($h / $th)] \
+ -tags $t:nob$e
+ bind $path.nob <B[expr $i + 1]-Motion> \
+ "::ix::nob_mover $path.nob $t [lindex $ratios $i] %x %y"
+ incr i
+ bind $path.nob <ButtonRelease-$i> "set ::ix::_($t:clickd) -1"
+ }
+ bind $path <MouseWheel> {::ix::nob_move %W.nob [winfo name %W] [expr %D / 2400.]}
+ bind $path <Shift-MouseWheel> {::ix::nob_move %W.nob [winfo name %W] [expr %D / 24000.]}
+ bind $path <Control-MouseWheel> {::ix::nob_move %W.nob [winfo name %W] [expr %D / 240.]}
+ bind $path.nob <Shift-B1-Motion> "::ix::nob_mover $path.nob $t 10 %x %y"
+ bind $path.nob <Control-B1-Motion> "::ix::nob_mover $path.nob $t 0.1 %x %y"
+ if {$nx == 0} {
+ set nx [expr $w / 2]
+ set ny [expr $h - 20]
+ }
+ $path.nob create text $nx $ny -text "0.0" -tags $t:num -fill "$cn" -font {{Bitstream Vera Sans} 8}
+ }
+ if {[info exists _($t:num)]} {
+ $path.nob itemconfigure $t:num -text $_($t:num)
+ foreach e {1 10 100} {
+ $path.nob itemconfigure $t:nob$e -start $_($t:a$e)
+ }
+ } else {
+ foreach e {1 10 100} {set _($t:a$e) 90}
+ set _($t:num) 0.0}
+
+ }
+}
+#> knob frame
+#. -bd 1 -bg "#cccccc"
+#. -highlightbackground red
+#. #max 0 #min 0
+#. #w 128 #h 128 #th 5 #range 100 #nx 0 #ny 0
+#. #bg purple #ca blue #cb yellow #cc green #cn orange
+#. @float ::ix::nobfloat .-.nob .| .#1
+#. @cmd eval ".-.nob .#args"
+bind .- <Enter> {focus .-}
+bind .- <Leave> {focus .^.c}
+::ix::nob .- .| .#w .#h .#range .#bg .#ca .#cb .#cc .#cn .#th .#nx .#ny .#max .#min
diff --git a/extensions/gui/ix/toxy/lg-demo.pd b/extensions/gui/ix/toxy/lg-demo.pd
new file mode 100755
index 00000000..a7c95bf4
--- /dev/null
+++ b/extensions/gui/ix/toxy/lg-demo.pd
@@ -0,0 +1,68 @@
+#N canvas 138 75 1019 727 12;
+#X obj 5 87 widget lg lga -width 940 -height 440 -bg green;
+#X obj 92 -48 bng 28 250 50 0 empty empty view 0 -6 0 8 -62784 -1 -1
+;
+#X msg 58 34 clear;
+#X obj 142 34 getall lga;
+#X obj 366 62 srec lga;
+#X msg -2 52 cmd axis configure y -logscale \$1;
+#X obj -3 38 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X msg 421 -36 190 lolp 0 \, 140 lolp 4;
+#X msg 398 -18 1 kgoga 2 3 6 \, 190 kgoga 0 4 3;
+#X obj 70 216;
+#X msg 75 211;
+#X msg 335 -28 delete lolp;
+#X msg 322 -46 delete kgoga;
+#X msg 25 34 dump;
+#X msg 395 1 1 juba 2 3 4 5 \, 200 juba 5 6 7 8;
+#X obj 9 607 pool lga;
+#X obj 74 546 + 1;
+#X obj 47 546 i;
+#X obj 9 563 prepend;
+#X obj 5 528 t a b;
+#X obj 8 585 prepend set;
+#X msg 106 11 reset;
+#X obj 83 -12 t b b;
+#X msg 118 -9 0;
+#X obj 123 -49 bng 32 250 50 0 empty empty write-+ 0 -6 0 8 -24198
+-1 -1;
+#X obj 144 6 t b b;
+#X obj 426 27 tow . lg lga;
+#X msg 217 20 redefine;
+#X msg 227 61 -width \$1;
+#X msg 286 61 -height \$1;
+#X floatatom 227 43 5 0 0 0 - - -;
+#X floatatom 286 43 5 0 0 0 - - -;
+#X connect 0 0 19 0;
+#X connect 1 0 25 0;
+#X connect 2 0 0 0;
+#X connect 3 0 0 0;
+#X connect 5 0 0 0;
+#X connect 6 0 5 0;
+#X connect 7 0 26 0;
+#X connect 8 0 26 0;
+#X connect 11 0 26 0;
+#X connect 12 0 26 0;
+#X connect 13 0 0 0;
+#X connect 14 0 26 0;
+#X connect 16 0 17 1;
+#X connect 17 0 16 0;
+#X connect 17 0 18 1;
+#X connect 18 0 20 0;
+#X connect 19 0 18 0;
+#X connect 19 1 17 0;
+#X connect 20 0 15 0;
+#X connect 21 0 15 0;
+#X connect 22 0 13 0;
+#X connect 22 1 21 0;
+#X connect 22 1 23 0;
+#X connect 23 0 17 1;
+#X connect 24 0 22 0;
+#X connect 25 0 3 0;
+#X connect 25 1 2 0;
+#X connect 27 0 0 0;
+#X connect 28 0 0 0;
+#X connect 29 0 0 0;
+#X connect 30 0 28 0;
+#X connect 31 0 29 0;
diff --git a/extensions/gui/ix/toxy/lg.wid b/extensions/gui/ix/toxy/lg.wid
new file mode 100755
index 00000000..c43b8012
--- /dev/null
+++ b/extensions/gui/ix/toxy/lg.wid
@@ -0,0 +1,237 @@
+package require BLT
+namespace import blt::
+namespace eval ::ix {
+ variable _
+ proc random_int {} {
+ return [expr "int(floor(rand()*16))"]
+ }
+ proc random_clr {} {
+ return [format "\#%1X%1X%1X%1X%1X%1X" [random_int] [random_int] [random_int] [random_int] [random_int] [random_int]]
+ }
+ proc lg_add {path tg args} {
+ variable _
+ set e [lindex $args 1]
+ set l [llength $args]
+ for {set n 2} {$n < $l} {incr n} {
+ if {$l > 3} {set nm $e:[expr $n - 1]} else {set nm $e}
+ set _($path:$nm:e) [expr $n - 1]
+ set _($path:$nm:p) $e
+ set _($path:$e:n) [expr $l - 2]
+ lg_list $path $tg $nm [lindex $args 0] [lindex $args $n]
+ }
+ }
+ proc lg_dumper {path tg args} {
+ variable _
+ foreach e [$path element names] {
+ if {$_($path:$e:e) == 1} {
+ lg_dump $path $tg $e
+ }
+ }
+ }
+ proc lg_dump {path tg e} {
+ variable _
+ set p $_($path:$e:p)
+ set el $_($path:$e:e)
+ set n $_($path:$p:n)
+ for {set i 0} {$i < [$tg:x$e length]} {incr i} {
+ set out {}
+ lappend out [$tg:x$e index $i]
+ lappend out $p
+ if {$n > 1} {
+ for {set x 1} {$x <= $n} {incr x} {
+ lappend out [$tg:y$p:$x index $i]
+ }
+ } else {
+ lappend out [$tg:y$e index $i]
+ }
+ set out [join $out " "]
+# puts $out
+ pd "$tg.rp _cb $out;"
+ }
+ }
+ proc lg_list {path tg e i1 i2} {
+ if {[$path element exists $e] != 1} {lg_nv $path $tg $e}
+ $tg:y$e append $i2
+ $tg:x$e append $i1
+ }
+ proc lg_zoom {path tg d x y} {
+ puts "$path $tg $d"
+ if {$d eq "in"} {set dn 4} {set dn 1}
+ set lx [$path axis limits x]
+ set dx [expr ([lindex $lx 1] - [lindex $lx 0]) / $dn]
+ set cx [$path axis invtransform x $x]
+ set cy [$path axis invtransform y $y]
+ set ly [$path axis limits y]
+ set dy [expr ([lindex $ly 1] - [lindex $ly 0]) / $dn]
+ $path axis configure x -min [expr $cx - $dx] -max [expr $cx + $dx]
+ $path axis configure y -min [expr $cy - $dy] -max [expr $cy + $dy]
+ }
+ proc lg_dr {path tg e x y} {
+ variable _
+ if {[$path element closest $x $y cl -halo 666 -interpolate 1 -along x $e] == 1} {
+ set new [$path axis invtransform y $y]
+ set n $tg:y$cl(name)
+ set io $_($path:clickd)
+ set ic $cl(index)
+ $n index $ic $new
+ if {$io != -1 && [expr abs($io - $ic)] > 1} {lg_smooth $io $ic $n}
+ set _($path:clickd) $ic
+ }
+ }
+ proc lg_smooth {io ic n} {
+# puts "smoothing $n from $io to $ic"
+ set vo [$n index $io]
+ set vc [$n index $ic]
+ if {$ic > $io} {set is $io; set vs $vo} else {set is $ic; set vs $vc}
+ set ne [expr [$n length] - 1]
+ if {$ic != $ne && $io != $ne} {
+ for {set i 1} {$i < [expr abs($io - $ic)]} {incr i} {
+ set nv [expr $vs + (($vc - $vo) * $i / ($ic - $io))]
+ set ni [expr $is + $i]
+ $n index $ni $nv
+ }
+ }
+ }
+ proc lg_sl {path tg e x y} {
+ variable _
+ set t [$path invtransform $x $y]
+ if {$_($path:clickd) != -1} {
+ set dx [expr [lindex $t 0] - [lindex $_($path:clcord) 0]]
+ set dy [expr [lindex $t 1] - [lindex $_($path:clcord) 1]]
+
+ set p $_($path:$e:p)
+ set el $_($path:$e:e)
+ set n $_($path:$p:n)
+
+ if {$n > 1} {
+ for {set i 1} {$i <= $n} {incr i} {
+ set tx $tg:x$p:$i
+ set ty $tg:y$p:$i
+ $tx expr "$tx + $dx"
+ if {$el == $i} {$ty expr "$ty + $dy"}
+ }
+ } else {
+ $tg:x$e expr "$tg:x$e + $dx"
+ $tg:y$e expr "$tg:y$e + $dy"
+ }
+ }
+ set _($path:clcord) $t
+ set _($path:clickd) 1
+ }
+ proc lg_draw {path tg e x y} {
+ variable _
+ if {[$path element closest $x $y cl -halo 666 -interpolate 1 -along x $e] == 1} {
+ set t [$path invtransform $x $y]
+ set p $_($path:$e:p)
+ set el $_($path:$e:e)
+ set n $_($path:$p:n)
+ set io $_($path:clickd)
+ set ic $cl(index)
+ if {$n > 1} {
+ for {set i 1} {$i <= $n} {incr i} {
+ set tx $tg:x$p:$i
+ set ty $tg:y$p:$i
+ if {$el == $i} {set ny [lindex $t 1]} else {
+ if {[$ty length] == $ic} {set tc [expr $ic - 1]} else {set tc $ic}
+ set ny [$ty index $tc]
+ }
+ set nx [lindex $t 0]
+ $ty append $ny
+ $tx append $nx
+ $tx sort $ty
+ if {$i == 1} {
+ if {$ic < $io} {incr io}
+ incr ic
+ }
+ if {$io != -1 && [expr abs($io - $ic)] > 1} {lg_smooth $io $ic $ty}
+ }
+ } else {
+ $tg:y$e append [lindex $t 1]
+ $tg:x$e append [lindex $t 0]
+ $tg:x$e sort $tg:y$e
+ if {$ic < $io} {incr io}
+ incr ic
+ if {$io != -1 && [expr abs($io - $ic)] > 1} {lg_smooth $io $ic $tg:y$e}
+ }
+ set _($path:clickd) $ic
+ }
+ }
+
+ proc lg_trim {path tg e x y} {
+ variable _
+ if {[$path element closest $x $y cl -halo 666 -interpolate 1 -along x $e] == 1} {
+# foreach name [array names cl] {puts "$name $cl($name)"}
+ if {[expr abs([$path axis transform x [$tg:x$e index $cl(index)]] - $x.0)] < 32} {
+ set p $_($path:$cl(name):p)
+ set n $_($path:$p:n)
+ if {$n > 1} {
+ for {set i 1} {$i <= $n} {incr i} {
+ $tg:y$p:$i delete $cl(index)
+ $tg:x$p:$i delete $cl(index)
+ }
+ } else {
+ $tg:y$cl(name) delete $cl(index)
+ $tg:x$cl(name) delete $cl(index)
+ }
+ }
+ }
+ }
+ proc lg_cl {path tg} {
+ foreach e [$path element names] {lg_dv $path $tg $e}
+# pd "$tg.rp _cb symbol clear;"
+ }
+ proc lg_de {path tg e} {
+ variable _
+ set n $_($path:$e:n)
+ if {$n > 1} {
+ for {set i 1} {$i <= $n} {incr i} {
+ lg_dv $path $tg $e:$i
+ }
+ } else {
+ lg_dv $path $tg $e
+ }
+ }
+ proc lg_dv {path tg e} {
+ blt::vector destroy $tg:x$e
+ blt::vector destroy $tg:y$e
+ $path element delete $e
+# pd "$tg.rp _cb delete $e;"
+ }
+ proc lg_nv {path tg e} {
+ variable _
+ blt::vector create $tg:x$e -variable ""
+ blt::vector create $tg:y$e -variable ""
+ set _($path:clickd) -1
+ $path element create $e -x $tg:x$e -y $tg:y$e -symbol "circle" -pixels 2 -linewidth 2 -color [random_clr] -hide 0
+# puts "creating: $path $e -x $tg:x$e -y $tg:y$e -color [random_clr] -hide 0"
+ $path element bind $e <B1-Motion> "::ix::lg_dr $path $tg $e %x %y"
+ $path element bind $e <Shift-B1-Motion> "::ix::lg_sl $path $tg $e %x %y"
+ $path element bind $e <Control-B1-Motion> "::ix::lg_draw $path $tg $e %x %y"
+ $path element bind $e <Alt-B1-Motion> "::ix::lg_trim $path $tg $e %x %y"
+# $path element bind $e <1> "::ix::lg_dr $path $tg $e %x %y"
+ $path element bind $e <ButtonRelease-1> "set ::ix::_($path:clickd) -1"
+# $path element bind $e <Shift-ButtonRelease-1> "set ::ix::_($path:clickd) -1"
+ }
+ proc lg_new {path tg} {
+ bind $path <ButtonPress-3> {}
+ bind $path <Button-4> "::ix::lg_zoom $path $tg in %x %y"
+ bind $path <Button-5> "::ix::lg_zoom $path $tg out %x %y"
+ bind $path <Control-Button-4> "$path axis configure x -min {} -max {}; $path axis configure y -min {} -max {}"
+ bind $path <Control-Button-5> [bind $path <Control-Button-4>]
+ Blt_ZoomStack $path "2" "Control-2"
+ $path axis configure x -background [$path cget -bg]
+ $path axis configure y -background [$path cget -bg]
+ }
+}
+#> lg blt::graph
+#. -bg yellow -halo 16
+#. @clear ::ix::lg_cl .- .|
+#. @delete ::ix::lg_de .- .| .#1
+#. @list ::ix::lg_add .- .| .#args
+#. @add ::ix::lg_add .- .| .#args
+#. @dump ::ix::lg_dumper .- .| .#args
+#. @cmd eval ".- .#args"
+
+::ix::lg_new .- .|
+
+puts "lg .- .|" \ No newline at end of file
diff --git a/extensions/gui/ix/toxy/mat-demo.pd b/extensions/gui/ix/toxy/mat-demo.pd
new file mode 100755
index 00000000..eda61bc5
--- /dev/null
+++ b/extensions/gui/ix/toxy/mat-demo.pd
@@ -0,0 +1,53 @@
+#N canvas 80 85 910 775 12;
+#X obj 15 29 widget mat n1 #w 881 #bg gray83 #divX 8 #divY 5 #h 494
+#Yb 1 #Ya 88 #qYv 2 #qYa 8 #ln white;
+#X msg 1080 -13 -height 26 -width 26 -bg gray95;
+#X msg 184 648 redefine;
+#X obj 131 646 * 127;
+#X obj 95 644 + 36;
+#X obj 587 565 rr ss;
+#X obj 587 546 rg;
+#X obj 20 603 unpack f f f;
+#X obj 47 638 * 127;
+#X obj 26 668 pack f f f;
+#X obj 49 692 makenote 99 250;
+#X obj 102 728 noteout;
+#X obj 77 559 rp ss kbd;
+#X obj 158 583 rp ss kb2;
+#X obj 138 537 widget kbd k1 #bg blue #fg green #ln gray50 -height
+32;
+#X obj 138 570 widget kbd k2 #bg orange #fg red #ln gray50 -height
+32;
+#X obj 108 622 unpack 0 0 0;
+#X obj 108 603 Append 1;
+#X obj 158 602 Append 2;
+#X msg 74 575 1;
+#X obj 3 533 widget dd dd1 -bg green -fg red;
+#X obj 3 493 a2l;
+#X obj 3 549 widget dd s2 #symbol 0;
+#X connect 0 0 21 0;
+#X connect 2 0 0 0;
+#X connect 3 0 11 1;
+#X connect 4 0 11 0;
+#X connect 6 0 5 0;
+#X connect 7 0 9 0;
+#X connect 7 1 8 0;
+#X connect 7 2 9 2;
+#X connect 8 0 9 1;
+#X connect 9 0 10 0;
+#X connect 10 0 11 0;
+#X connect 10 1 11 1;
+#X connect 12 0 17 0;
+#X connect 13 0 18 0;
+#X connect 14 0 17 0;
+#X connect 14 0 12 0;
+#X connect 15 0 18 0;
+#X connect 15 0 13 0;
+#X connect 16 0 4 0;
+#X connect 16 1 3 0;
+#X connect 16 2 11 2;
+#X connect 17 0 16 0;
+#X connect 18 0 16 0;
+#X connect 19 0 9 2;
+#X connect 21 0 20 0;
+#X connect 22 0 20 0;
diff --git a/extensions/gui/ix/toxy/mat.wid b/extensions/gui/ix/toxy/mat.wid
new file mode 100755
index 00000000..237bf772
--- /dev/null
+++ b/extensions/gui/ix/toxy/mat.wid
@@ -0,0 +1,688 @@
+foreach package {snack tkdnd tkpath} {package require $package}
+namespace eval ::ix {
+ proc rc {} {return [format "\#%06x" [expr "int(floor(rand() * 16777216))"]]}
+ proc rgb {} {return [list [expr "int(floor(rand() * 256))"] [expr "int(floor(rand() * 256))"] [expr "int(floor(rand() * 256))"]]}
+ proc lighten {rgb r} {set l {}; foreach c $rgb {lappend l [expr {(256 - $c) * $r + $c}]}; return $l}
+ proc darken {rgb r} {set l {}; foreach c $rgb {lappend l [expr {$c - ($c * $r)}]}; return $l}
+ proc color {rgb} {return [format "\#%02x%02x%02x" [expr int([lindex $rgb 0])] [expr int([lindex $rgb 1])] [expr int([lindex $rgb 2])]]}
+ proc random_txt {n} {
+ set i 0
+ set text ""
+ while {$i < $n} {
+ set int [expr "int(floor(rand()*62))"]
+ if {$int < 10} {incr int 48} elseif {$int < 36} {incr int 55} else {incr int 61}
+ set text "$text[format %c $int]"
+ incr i
+ }
+ return $text
+ }
+
+ proc mat_sel {p t a x y} {
+ variable _
+ set _($t:sc) [rc]
+ switch $a {
+ first {
+ foreach xy {x y} {set _($t:c$xy) [set $xy];set _($t:f$xy) [set $xy]}
+ $p.m create path [::tkpath::coords rect $_($t:cx) $_($t:cy) 0 0 -rx 12 -ry 12] \
+ -tags sel -stroke $_($t:sc) -strokewidth 12 -strokeopacity 0.3}
+ release {$p.m delete sel}
+ motion {
+ mat_updatesel $p $t [mat_cleansel $p $t [$p.m find overlapping $_($t:fx) $_($t:fy) $x $y]]
+ if {$x >= $_($t:cx)} {set xa $_($t:fx);set xb $x} else {set xa $x;set xb $_($t:fx)}
+ if {$y >= $_($t:cy)} {set ya $_($t:fy);set yb $y} else {set ya $y;set yb $_($t:fy)}
+ set w [expr {abs($xb - $xa)}]
+ set h [expr {abs($yb - $ya)}]
+ $p.m coords sel [::tkpath::coords rect $xa $ya $w $h -rx 12 -ry 12]
+ $p.m itemconfigure sel -stroke $_($t:sc)}}}
+
+ proc mat_item_new {p t id d} {
+ variable _
+ if {$id eq "-"} {
+ if {[dict keys $_($t)] eq ""} {set id 0} else {
+ set id -1
+ while true {if {[lsearch -integer [dict keys $_($t)] [incr id]] == -1} {break}}
+ }
+ }
+ set _($t:ci) $id
+ mat_item_ua $p $t $id abs {x 0 xx 0 y 0 yy 0 g 0 v 1} 0
+ mat_item_ua $p $t $id abs $d 0
+ mat_item_draw $p $t $id
+ }
+
+ proc mat_item_draw {p t is} {
+ variable _
+ if {$is eq "all"} {set is [dict keys $_($t)]}
+ foreach id $is {
+ set tags [list item i$id $id]
+ set color [dict get $_($t:g) $_($t:cg) color]
+ switch [dict get $_($t) $id type] {
+ note {
+ $p.m create path [::tkpath::coords rect 0 0 0 0 -rx 3 -ry 3] -tags [concat $tags r] -stroke [color [lighten $color 0.4]] -strokeopacity 1.0 -fill [color $color] -fillopacity 0.08
+ $p.m create path [::tkpath::coords rect 0 0 0 0 -rx 3 -ry 3] -tags [concat $tags q] -fill [color $color] -strokewidth 0 -fillopacity 0.8
+ }
+ sound {
+ snack:::sound s$id
+ set filename [dict get $_($t) $id filename]
+ s$id read $filename
+ $p.m create path [::tkpath::coords rect 0 0 0 0 -rx 3 -ry 3] -tags [concat $tags r] -strokewidth 0 -fill [color $color] -fillopacity 0.08
+ $p.m create waveform 0 0 -tags [concat $tags w] -sound s$id -fill white
+ set length [expr [s$id length] / ($_($t:samplerate) + 0.0) * 1000]
+ mat_item_ua $p $t $id abs [dict create xx [expr [dict get $_($t) $id x] + $length]] 0
+ $p.m create text 0 0 -tags [concat $tags tl] -font {{bitstream vera sans} 8} -fill HotPink -anchor nw -justify left -text "[string range $length 0 10] s"
+ $p.m create rectangle 0 0 0 0 -tags [concat $tags tlr] -fill LightGreen -width 0
+ $p.m raise [$p.m find withtag "i$id && tl"]
+ $p.m create text 0 0 -tags [concat $tags tf] -font {{bitstream vera sans} 8} -fill NavyBlue -anchor ne -justify right -text $filename
+ $p.m create rectangle 0 0 0 0 -tags [concat $tags tfr] -fill gray90 -width 0
+ $p.m raise [$p.m find withtag "i$id && tf"]
+ }
+ }
+ mat_redraw $p $t $id
+ }
+ }
+
+ proc mat_item_delete {p t} {
+ variable _
+ foreach item $_($t:sel) {
+ foreach i [$p.m find withtag i$item] {
+ $p.m delete $i
+ }
+ dict unset _($t) $item
+ set _($t:sel) {}
+ mat_item_info $p $t ""
+ pd [concat $t.rp _cb delete $item \;]
+ }
+ }
+
+ proc mat_quant {p t y v} {
+ variable _
+ if {$y eq "xx"} {set y x}; if {$y eq "yy"} {set y y}
+ if {$y eq "x" || $y eq "y"} {
+ set v [expr {int( ($v + $_($t:q$y) / 2.0 ) / ($_($t:q$y) + 0.0))*$_($t:q$y)}]
+ }
+ return $v
+ }
+
+ proc mat_item_pos {p t item r x y xx yy} {
+ mat_item_ua $p $t $item $r [dict create x $x y $y xx $xx yy $yy] 1}
+
+ proc mat_item_ua {p t item r u redraw} {
+ variable _
+ foreach a [dict keys $u] {
+ switch $r {abs {dict set _($t) $item $a [dict get $u $a]}
+ rel {dict set _($t) $item $a [expr {[dict get $_($t) $item $a] + [dict get $u $a]}]}}
+ pd [concat $t.rp _cb update $item $a [pdtk_enquote [dict get $_($t) $item $a]] \;]
+ }
+ if {$redraw == 1} {mat_redraw $p $t $item}
+ }
+
+ proc mat_draw {p t a x y} {
+ variable _
+ switch $a {
+ motion {
+ if {$_($t:af) == 1} {
+ mat_item_pos $p $t $_($t:ci) abs [mat_tr $p $t y i $y] [mat_tr $p $t x i $x] [mat_tr $p $t y i $_($t:fy)] [mat_tr $p $t x i $x]
+ } else {
+ mat_item_pos $p $t $_($t:ci) abs [mat_tr $p $t x i $x] [mat_tr $p $t y i $y] [mat_tr $p $t x i $_($t:fx)] [mat_tr $p $t y i $y]
+ }
+ }
+ first {mat_item_new $p $t - [dict create type note g $_($t:cg) x 0 y 0 xx 0 yy 0 v 1]}}}
+
+ proc mat_resize_canvas {p t a x y} {mat_viewpoint $p $t [dict create action resize x $x y $y]}
+
+ proc mat_redraw {p t items} {
+ variable _
+ if {$_($t:af) == 1} {
+ array set a {x y y x xx yy yy xx}
+ } else {
+ array set a {x x y y xx xx yy yy}
+ }
+ switch $items {
+ all {set items [dict keys $_($t)]}
+ default {}}
+ foreach id $items {
+ set x [mat_tr $p $t x t [dict get $_($t) $id $a(x)]]
+ set y [mat_tr $p $t y t [dict get $_($t) $id $a(y)]]
+ set qx [mat_tr $p $t x t [mat_quant $p $t x [dict get $_($t) $id $a(x)]]]
+ set qy [mat_tr $p $t y t [mat_quant $p $t y [dict get $_($t) $id $a(y)]]]
+ set wx [expr {[dict get $_($t) $id $a(xx)] - [dict get $_($t) $id $a(x)]}]
+ if {$wx == 0} {set wx 1}
+ set sx [expr abs([mat_tr $p $t x id $wx])]
+ set qsx [expr int(abs([mat_tr $p $t x id [expr {[mat_quant $p $t x [dict get $_($t) $id $a(xx)]] - [mat_quant $p $t x [dict get $_($t) $id $a(x)]]}]]))]
+ set wy [expr {[dict get $_($t) $id $a(yy)] - [dict get $_($t) $id $a(y)]}]
+ if {$wy == 0} {set wy 1}
+ set sy [expr abs([mat_tr $p $t y id $wy])]
+ set qsy [expr int(abs([mat_tr $p $t y id [expr {[mat_quant $p $t y [dict get $_($t) $id $a(yy)]] - [mat_quant $p $t y [dict get $_($t) $id $a(y)]]}]]))]
+ set ro [expr {int( [set s$a(y)] / 2.0 )}]
+ if {[lsearch -integer $_($t:sel) $id] >= 0} {
+ set color $_($t:sc)
+ } else {
+ set color [color [dict get $_($t:g) [dict get $_($t) $id g] color]]
+ }
+ switch [dict get $_($t) $id type] {
+ note {
+ set r [$p.m find withtag "i$id && r"]
+ set q [$p.m find withtag "i$id && q"]
+ $p.m coords $r [::tkpath::coords rect $x $y $sx $sy -rx $ro -ry $ro]
+ $p.m coords $q [::tkpath::coords rect $qx $qy $qsx $qsy -rx $ro -ry $ro]
+ $p.m itemconfigure $q -fillopacity [dict get $_($t) $id v] -fill $color
+ }
+ sound {
+ set waveform [$p.m find withtag "i$id && w"]
+ set r [$p.m find withtag "i$id && r"]
+# set ro [expr int($ro / 2.)]
+ set ro 6
+ $p.m coords $r [::tkpath::coords rect $x $y $sx $sy -rx $ro -ry $ro]
+ $p.m itemconfigure $r -fillopacity [dict get $_($t) $id v] -fill $color
+ $p.m coords $waveform $x $y
+ $p.m itemconfigure $waveform -width $sx -height [expr int($sy)]
+# $p.m itemconfigure $waveform -width $sx
+ $p.m coords [$p.m find withtag "i$id && tl"] [expr $x + 4] [expr $y + 4]
+ $p.m coords [$p.m find withtag "i$id && tlr"] [$p.m bbox [$p.m find withtag "i$id && tl"] ]
+ $p.m coords [$p.m find withtag "i$id && tf"] [expr $x + $sx] [expr $y + 4]
+ $p.m coords [$p.m find withtag "i$id && tfr"] [$p.m bbox [$p.m find withtag "i$id && tf"] ]
+ }
+ }
+ }
+ }
+
+ proc mat_item_v {p t a x y} {
+ variable _
+ foreach item $_($t:sel) {
+ mat_item_ua $p $t $item rel [dict create v [expr {($x - $_($t:cx)) / 100.0}]] 1
+ }
+ mat_item_info $p $t $_($t:sel)
+ }
+
+ proc mat_move_canvas {p t a x y} {mat_viewpoint $p $t [dict create action move x $x y $y]}
+
+ proc mat_move_object {p t a x y} {
+ variable _
+ set mx [mat_tr $p $t x d [expr {$x - $_($t:cx)}]]
+ set my [mat_tr $p $t y d [expr {$y - $_($t:cy)}]]
+ if {$_($t:af) == 1} {
+ foreach item $_($t:sel) {mat_item_pos $p $t $item rel $my $mx $my $mx}
+ } else {
+ foreach item $_($t:sel) {mat_item_pos $p $t $item rel $mx $my $mx $my}
+ }
+ mat_item_info $p $t $_($t:sel)
+ }
+
+ proc mat_resize_left {p t a x y} {mat_resize_object $p $t x $x $y}
+ proc mat_resize_right {p t a x y} {mat_resize_object $p $t xx $x $y}
+ proc mat_resize_top {p t a x y} {mat_resize_object $p $t y $x $y}
+ proc mat_resize_bottom {p t a x y} {mat_resize_object $p $t yy $x $y}
+ proc mat_resize_tl {p t a x y} {mat_resize_object $p $t x $x $y; mat_resize_object $p $t y $x $y}
+ proc mat_resize_tr {p t a x y} {mat_resize_object $p $t x $x $y; mat_resize_object $p $t yy $x $y}
+ proc mat_resize_bl {p t a x y} {mat_resize_object $p $t xx $x $y; mat_resize_object $p $t y $x $y}
+ proc mat_resize_br {p t a x y} {mat_resize_object $p $t xx $x $y; mat_resize_object $p $t yy $x $y}
+
+ proc mat_resize_object {p t e x y} {
+ variable _
+ if {$_($t:af) == 1} {
+ array set ax {x y xx y y x yy x}
+ } else {
+ array set ax {x x xx x y y yy y}
+ }
+ set m [mat_tr $p $t $ax($e) d [expr $$ax($e) - $_($t:c$ax($e))]]
+ foreach item $_($t:sel) {mat_item_ua $p $t $item rel [dict create $e $m] 1}
+ mat_item_info $p $t $_($t:sel)
+ }
+
+ proc mat_cleansel {p t sel} {
+ set clean {}
+ foreach item $sel {if {[lindex [$p.m itemcget $item -tags] 0] eq "item"} {lappend clean [lindex [$p.m itemcget $item -tags] 2]}}
+ set clean [lsort -integer -unique $clean]
+ return $clean
+ }
+
+ proc mat_loc {p t si x y} {
+ variable _
+ if {$si == 1} {
+ set sy $y
+ set sx $x
+ set x [mat_tr $p $t x i $x]
+ set y [mat_tr $p $t y i $y]
+ } else {
+ set sy [mat_tr $p $t y t $y]
+ set sx [mat_tr $p $t x t $x]
+ }
+ $p.m coords lY [concat M 0 $sy L [winfo width $p.m] $sy]
+ $p.m coords lX [concat M $sx 0 L $sx [winfo height $p.m]]
+ $p.m itemconfigure loc -text [list $x $y]
+ }
+
+ proc mat_hover {p t x y} {
+ variable _
+# mat_loc $p $t 1 $x $y
+ if {[$p.m find withtag sel] ne ""} {
+ mat_sel $p $t motion $x $y
+ } else {
+ set clicked [mat_cleansel $p $t [$p.m find overlapping [expr $x - 2] [expr $y - 2] [expr $x + 2] [expr $y + 2]]]
+ if {$clicked ne ""} {
+ mat_resize_modes $p $t $x $y [lindex $clicked end]
+ if {[llength $_($t:sel)] <= 1} {mat_updatesel $p $t [lindex $clicked end]}
+ } else {
+ mat_mode $p $t move_canvas
+ }
+ }
+ }
+
+ proc mat_resize_modes {p t x y id} {
+ variable _
+ set d 3
+ set dx [expr {abs([mat_tr $p $t x t [dict get $_($t) $id x]] - $x)}]
+ set dxx [expr {abs([mat_tr $p $t x t [dict get $_($t) $id xx]] - $x)}]
+ set dy [expr {abs([mat_tr $p $t y t [dict get $_($t) $id y]] - $y)}]
+ set dyy [expr {abs([mat_tr $p $t y t [dict get $_($t) $id yy]] - $y)}]
+ if {$dx < $d && $dy < $d} {
+ mat_mode $p $t resize_tl
+ } elseif {$dxx < $d && $dy < $d} {
+ mat_mode $p $t resize_tr
+ } elseif {$dx < $d && $dyy < $d} {
+ mat_mode $p $t resize_bl
+ } elseif {$dxx < $d && $dyy < $d} {
+ mat_mode $p $t resize_br
+ } elseif {$dx < 5} {
+ mat_mode $p $t resize_left
+ } elseif {$dxx < 5} {
+ mat_mode $p $t resize_right
+ } elseif {$dy < 1} {
+ mat_mode $p $t resize_top
+ } elseif {$dyy < 1} {
+ mat_mode $p $t resize_bottom
+ } else {
+ mat_mode $p $t move_object
+ }
+ }
+
+ proc mat_item_info {p t clicked} {
+ variable _
+ set n 0;$p.m delete hover
+ foreach item $clicked {
+ set info ""
+ set data [dict get $_($t) $item]
+ foreach d $data {lappend info [string range $d 0 7]}
+ $p.m create text [list [expr [winfo width $p.m] - 8.0] [expr [winfo height $p.m] - 8.0 - 11 * $n.0]] -fill $_($t:sc) -justify right -anchor se -font {{bitstream vera sans mono} 10} -tags hover -text $info
+ incr n
+ }}
+
+ proc mat_togglesel {p t d} {
+ variable _
+ if {[lsearch -integer $_($t:sel) $d] < 0} {
+ set _($t:sel) [concat $_($t:sel) $d]
+ } else {
+ set _($t:sel) [lsearch -inline -not -all -integer $_($t:sel) $d]
+ }
+ mat_redraw $p $t $d
+ }
+
+ proc mat_updatesel {p t ns} {
+ variable _
+ set os $_($t:sel)
+ set _($t:sel) $ns
+ mat_redraw $p $t [lsort -unique -integer [concat $os $ns]]
+ mat_item_info $p $t $ns
+ }
+
+ proc mat_click {m button action p t x y X Y} {
+ variable _
+ set clicked [mat_cleansel $p $t [$p.m find overlapping $x $y $x $y]]
+ set a [$p.m itemcget mode -text]
+ switch $action {
+ first {
+ foreach xy {x y} {set _($t:f$xy) [set $xy]}
+ switch $button {
+ 1 {if {$m eq "control"} {
+ mat_mode $p $t draw; mat_draw $p $t $action $x $y
+ } elseif {$m eq "double" || $m eq "shift"} {
+ if {[llength $clicked] > 0} {
+ mat_togglesel $p $t $clicked
+ } else {
+ mat_sel $p $t first $x $y
+ mat_mode $p $t sel
+ }
+ } elseif {[$p.m find withtag sel] ne ""} {
+ mat_sel $p $t release $x $y
+ } elseif {[llength $_($t:sel)] > 1 && [llength $clicked] > 0 && [lsearch $_($t:sel) $clicked] == -1} {
+ mat_updatesel $p $t $clicked}}
+ 2 {mat_mode $p $t resize_canvas}
+ 3 {if {$clicked ne ""} {
+ mat_mode $p $t item_v } else {mat_rmenu $p $t $X $Y}}}}
+ motion {eval mat_$a $p $t $action $x $y}
+ release {
+ switch $button {
+ 1 {if {$a eq "draw" || ($a eq "sel" && [expr {abs($_($t:fx) - $x)}] >13)} {eval mat_$a $p $t $action $x $y}}
+ 2 {mat_mode $p $t move_canvas}
+ 3 {mat_mode $p $t move_canvas}
+ }
+ }
+ }
+ foreach xy {x y} {set _($t:c$xy) [set $xy]}
+ }
+
+ proc mat_rmenu {p t x y} {
+ variable _
+ if {[winfo exists $p.rmenu] != 1} {
+ set m [menu $p.rmenu -tearoff no]
+ $m add command -label "zoom to fit" -command "::ix::mat_viewpoint $p $t {action fit}"
+ $m add command -label "reset zoom" -command "::ix::mat_viewpoint $p $t {action reset}"
+ $m add command -label "add group" -command "::ix::mat_group_new $p $t -"
+ $m add cascade -label "sel to group" -menu [menu $p.rmenu.seltogroup -tearoff no]
+ $m add command -label "flip axes" -command "::ix::mat_flipaxe $p $t"
+ } else {
+ # $p.rmenu entryconfigure 0 -label $x
+ }
+ $p.rmenu.seltogroup delete 0 end
+ foreach group [dict keys $_($t:g)] {
+ $p.rmenu.seltogroup add command -label [dict get $_($t:g) $group name] -command "::ix::mat_group_assign $p $t $group"
+ }
+ tk_popup $p.rmenu $x $y
+ }
+
+ proc mat_tr {p t d inv v} {
+ variable _
+ array set dm {x width y height}
+ switch $inv {
+ t {return [expr {($v - $_($t:${d}a)) / ($_($t:${d}b) - $_($t:${d}a) + 0.0) * [winfo $dm($d) $p.m]}]}
+ i {return [expr {($_($t:${d}b) - $_($t:${d}a)) * $v /([winfo $dm($d) $p.m] + 0.0) + $_($t:${d}a)}]}
+ d {return [expr {($_($t:${d}b) - $_($t:${d}a)) * $v /([winfo $dm($d) $p.m] + 0.0)}]}
+ id {return [expr {$v / ($_($t:${d}b) - $_($t:${d}a) + 0.0) * [winfo $dm($d) $p.m]}]}}}
+
+ proc mat_viewpoint {p t opts} {
+ variable _
+ switch [dict get $opts action] {
+ fit {
+ set i 0
+ dict for {s xy} $_($t) {
+ dict with xy {
+ if {$i == 0} {
+ set xa $x
+ set xb $x
+ set ya $y
+ set yb $y
+ }
+ if {$x > $xb} {set xb $x}
+ if {$x < $xa} {set xa $x}
+ if {$y > $yb} {set yb $y}
+ if {$y < $ya} {set ya $y}
+ if {$xx > $xb} {set xb $xx}
+ if {$xx < $xa} {set xa $xx}
+ if {$yy > $yb} {set yb $yy}
+ if {$yy < $ya} {set ya $yy}
+ incr i
+ }
+ }
+ set _($t:xa) $xa
+ set _($t:xb) $xb
+ set _($t:ya) $ya
+ set _($t:yb) $yb
+ }
+ reset {
+ set _($t:ya) $_($t:yao);set _($t:yb) $_($t:ybo);set _($t:xa) $_($t:xao);set _($t:xb) $_($t:xbo)
+ }
+ move {
+ foreach xy {x y} {
+ set mvt [mat_tr $p $t $xy d [expr {[dict get $opts $xy] - $_($t:c$xy)}]]
+ foreach ab {a b} {set _($t:${xy}$ab) [expr {$_($t:${xy}$ab) - $mvt}]}}
+ }
+ zoom {
+ array set dir {in 0.5 out 1.5}
+ foreach xy [dict get $opts axe] {
+ set radius [expr {($_($t:${xy}b) - $_($t:${xy}a)) / 2. * $dir([dict get $opts dir])}]
+ set center [mat_tr $p $t $xy i [dict get $opts $xy]]
+ set _($t:${xy}a) [expr {$center - $radius}]
+ set _($t:${xy}b) [expr {$center + $radius}]
+ }
+ }
+ resize {
+ foreach xy {x y} {
+ set mvt [mat_tr $p $t $xy d [expr {[dict get $opts $xy] - $_($t:c$xy)}]]
+ set _($t:${xy}a) [expr {$_($t:${xy}a) - $mvt}]
+ set _($t:${xy}b) [expr {$_($t:${xy}b) + $mvt}]}
+ }
+ scroll {
+ set xy [dict get $opts axis]
+ set mv [expr {($_($t:${xy}b) - $_($t:${xy}a)) / 4.0}]
+ foreach ab {a b} {set _($t:${xy}$ab) [expr {[dict get $opts units] > 0 ? $_($t:${xy}$ab) + $mv : $_($t:${xy}$ab) - $mv }]}
+ }
+ }
+ mat_redraw $p $t all
+ mat_gridlines $p $t
+ }
+ proc mat_flipaxe {p t} {
+ variable _
+ set _($t:af) [expr $_($t:af) == 1 ? 0 : 1]
+
+ set ya $_($t:ya)
+ set xa $_($t:xa)
+ set xb $_($t:xb)
+ set yb $_($t:yb)
+ set qx $_($t:qx)
+ set qy $_($t:qy)
+ set mx $_($t:mx)
+ set my $_($t:my)
+
+ set _($t:ya) $xa
+ set _($t:xa) $ya
+ set _($t:yb) $xb
+ set _($t:xb) $yb
+ set _($t:qx) $qy
+ set _($t:qy) $qx
+ set _($t:mx) $my
+ set _($t:my) $mx
+
+ mat_gridlines $p $t
+ mat_redraw $p $t all
+ }
+ proc mat_clip {p t action} {
+ variable _
+ switch $action {
+ selecta {
+ mat_updatesel $p $t [dict keys $_($t)]
+ }
+ cut {
+ set _($t:c) [dict create]
+ set i 0
+ foreach item $_($t:sel) {
+ dict set _($t:c) $i [dict get $_($t) $item]
+ incr i
+ }
+ mat_item_delete $p $t
+ }
+ copy {
+ set _($t:c) [dict create]
+ set i 0
+ foreach item $_($t:sel) {
+ dict set _($t:c) $i [dict get $_($t) $item]
+ incr i
+ }
+ }
+ paste {
+ set pasted {}
+ foreach item [dict keys $_($t:c)] {
+ mat_item_new $p $t - [dict get $_($t:c) $item]
+ }
+ }
+ }
+ }
+
+ proc mat_mode {p t m} {
+ array set cursor {draw pencil move_canvas fleur move_object dotbox item_v box_spiral resize_canvas bogosity sel cross_reverse resize_left left_side resize_right right_side resize_top top_side resize_bottom bottom_side resize_tl top_left_corner resize_tr top_right_corner resize_bl bottom_left_corner resize_br bottom_right_corner}
+ $p.m itemconfigure mode -text $m
+ $p.m configure -cursor $cursor($m)
+ }
+
+ proc mat_group_assign {p t group} {
+ variable _
+ foreach item $_($t:sel) {
+ mat_item_ua $p $t $item abs [dict create g $group] 0
+ }
+ }
+
+ proc mat_group_new {p t grp} {
+ variable _
+ set exists 0
+ dict for {key val} $_($t:g) {if {[dict get $val name] eq $grp} {set exists 1}}
+ if {$exists == 0} {
+ if {$grp eq "-"} {set grp [random_txt [expr "int(floor(rand() * 10 + 2))"]]}
+ set n -1
+ while true { if {[lsearch -integer [dict keys $_($t:g)] [incr n]] == -1} {break}}
+ dict set _($t:g) $n name $grp
+ dict set _($t:g) $n color [rgb]
+ set _($t:cg) $n
+ mat_groups_view $p $t
+ mat_group_active $p $t $n
+ }
+ }
+
+ proc mat_groups_view {p t} {
+ variable _
+ $p.m delete [$p.m find withtag group]
+ foreach i [dict keys $_($t:g)] {
+ set id [$p.m create text [concat 68.0 [expr {38.0 + 11 * $i}]] -fill [color [dict get $_($t:g) $i color]] -justify right -anchor e -font {{bitstream vera sans mono} 10} -tags [concat group $i lb] -text [dict get $_($t:g) $i name]]
+ $p.m bind $id <Enter> "::ix::mat_group_active $p $t $i"
+ $p.m bind $id <1> "::ix::mat_group_assign $p $t $i"
+ set bx [$p.m bbox $id]
+ $p.m lower [$p.m create path [::tkpath::coords rect [lindex $bx 0] [lindex $bx 1] [expr [lindex $bx 2] - [lindex $bx 0]] [expr [lindex $bx 3] - [lindex $bx 1]] -rx 6 -ry 6] -tags [concat group $i bg] -strokewidth 1 -stroke white -fill white -fillopacity 0.5]
+ }
+ }
+
+ proc mat_group_active {p t g} {
+ variable _
+ set _($t:cg) $g
+ foreach n [dict keys $_($t:g)] {
+ if {$g == $n} {set cb black; set cl white; set tl 1} {set cb white; set cl [color [dict get $_($t:g) $n color]]; set tl 0.5}
+ set idb [$p.m find withtag "group && $n && bg"]
+ $p.m itemconfigure $idb -fill $cb -fillopacity $tl -stroke $cl
+ set idl [$p.m find withtag "group && $n && lb"]
+ $p.m itemconfigure $idl -fill $cl;
+ if {$g == $n} {$p.m raise $idb;$p.m raise $idl;}
+ }
+ }
+
+ proc mat_key {p t k b} {
+ puts $k
+ switch $b {
+ 1 {
+ switch $k {
+ 22 {mat_item_delete $p $t}
+ 38 {mat_clip $p $t selecta}
+ 53 {mat_clip $p $t cut}
+ 54 {mat_clip $p $t copy}
+ 55 {mat_clip $p $t paste}
+ 97 {mat_viewpoint $p $t {action reset}}
+ 98 {mat_viewpoint $p $t {action scroll units -1 axis y}}
+ 100 {mat_viewpoint $p $t {action scroll units -1 axis x}}
+ 102 {mat_viewpoint $p $t {action scroll units 1 axis x}}
+ 104 {mat_viewpoint $p $t {action scroll units 1 axis y}}
+ 107 {mat_item_delete $p $t}
+ }
+ }
+# 0 {
+# switch $k {
+# }
+# }
+ }
+ }
+
+ proc mat_drop {p t dropped x y} {
+# foreach d $dropped {
+ foreach d [split $dropped "\n"] {
+ set x [mat_tr $p $t x i $x]
+ set y [mat_tr $p $t y i $y]
+ mat_item_new $p $t - [dict create type sound g 1 v 1 x $x y $y xx $x yy $y filename [regsub -- {^file:[/]+} $d "/"]]
+ }
+ }
+
+ proc mat_new {p t w h bg ln xa xb ya yb qx qy mx my samplerate} {
+ variable _
+ set sc orange
+ foreach xy {x y} {foreach ab {a b} {set ${xy}${ab}o [set ${xy}${ab}]}}
+ foreach a {sc ln xa xb ya yb xao xbo yao ybo qx qy mx my samplerate} {set _($t:$a) [set $a]}
+ if {[winfo exists $p.m] != 1} {
+ canvas $p.m -bg $bg -width $w -height $h
+ pack $p.m -side left
+ bind $p.m <Key> "::ix::mat_key $p $t %k 1"
+ bind $p.m <KeyRelease> "::ix::mat_key $p $t %k 0"
+# dnd bindtarget $p.m text/uri-list <Drop> "::ix::mat_drop $p $t %D %x %y"
+ dnd bindtarget $p.m text/plain <Drop> "::ix::mat_drop $p $t %D %x %y"
+ bind $p.m <Motion> "::ix::mat_hover $p $t %x %y"
+ bind $p.m <4> "::ix::mat_viewpoint $p $t {action scroll units 1 axis x}"
+ bind $p.m <5> "::ix::mat_viewpoint $p $t {action scroll units -1 axis x}"
+ bind $p.m <Control-4> "::ix::mat_viewpoint $p $t {action zoom dir in axe x x %x y %y}"
+ bind $p.m <Control-5> "::ix::mat_viewpoint $p $t {action zoom dir out axe x x %x y %y}"
+ bind $p.m <Alt-4> "::ix::mat_viewpoint $p $t {action zoom dir in axe {x y} x %x y %y}"
+ bind $p.m <Alt-5> "::ix::mat_viewpoint $p $t {action zoom dir out axe {x y} x %x y %y}"
+ bind $p.m <Control-Shift-4> "::ix::mat_viewpoint $p $t {action zoom dir in axe y x %x y %y}"
+ bind $p.m <Control-Shift-5> "::ix::mat_viewpoint $p $t {action zoom dir out axe y x %x y %y}"
+ bind $p.m <Shift-4> "::ix::mat_viewpoint $p $t {action scroll units -1 axis y}"
+ bind $p.m <Shift-5> "::ix::mat_viewpoint $p $t {action scroll units 1 axis y}"
+ foreach m {"Control-" "" "Shift-" "Double-"} {
+ foreach bn {1 2 3} {
+ set b [list [concat $bn first] [concat B${bn}-Motion motion] [concat ButtonRelease-$bn release]]
+ foreach ba {0 1 2} {
+ bind $p.m <$m[lindex [lindex $b $ba] 0]> "::ix::mat_click [list [string tolower [string trimright $m -1]]] $bn [lindex [lindex $b $ba] 1] $p $t %x %y %X %Y"}}}
+ set bd [expr {[$p cget -bd] * 2}]
+# update
+ $p configure -bg gray -width [expr {[winfo width $p.m] + $bd}] -height [expr {[winfo height $p.m] + $bd}]
+ $p.m create text {20 20} -fill blue -justify left -anchor w -font {{bitstream vera sans} 18} -tags mode -text move_canvas
+ $p.m create text [list [expr {$w / 2.}] 5] -fill red -justify center -anchor n -font {{bitstream vera sans} 14} -tags q -text q
+ $p.m create path "M 0 0" -tags lX -stroke black -strokeopacity 0.5
+ $p.m create path "M 0 0" -tags lY -stroke black -strokeopacity 0.5
+ $p.m create text "10 $h" -fill red -justify left -anchor sw -font {{bitstream vera sans} 12 bold} -fill purple -tags loc -text ""
+ if {[info exists _($t)] != 1} {
+ set _($t) {}
+ set _($t:g) {}
+ set af 0; set i -1; set sel {}
+ foreach a {af i sel} {set _($t:$a) [set $a]}
+ mat_group_new $p $t default
+ mat_group_new $p $t wavs
+ }
+ }
+ mat_gridlines $p $t
+ mat_item_draw $p $t all
+ mat_groups_view $p $t
+ }
+
+ proc mat_gridlines {p t} {
+ variable _
+ set w $p.m
+ $w delete gridlines
+ set gh [winfo height $w]
+ set gw [winfo width $w]
+ foreach item [$w find withtag gridline] {$w delete $item}
+ foreach xy {x y} {
+ array set ta {x n y w}
+ array set tj {x center y left}
+ array set igx {y width x height}
+ set range [expr {abs($_($t:${xy}b) - $_($t:${xy}a))}]
+ set numshits [expr {$range / $_($t:q$xy)}]
+ if {$numshits > $_($t:m${xy})} {set factor [expr {int($numshits / ($_($t:m${xy}) + 0.0) + 1)}]} else {
+ set factor [expr {1. / (int(1./($numshits / ($_($t:m${xy}) + 0.0) + 0.0)) + 0.0)}]
+ }
+ set increment [expr {$_($t:q${xy}) * $factor}]
+ for {set x [expr {int($_($t:${xy}a) / ($increment + 0.0) + 1)*($increment + 0.0)}]} {[expr {$_($t:${xy}a) > $_($t:${xy}b) ? $x >= $_($t:${xy}b) : $x <= $_($t:${xy}b)}]} {set x [expr {$_($t:${xy}a) > $_($t:${xy}b) ? $x - $increment : $x + $increment}]} {
+ set og [mat_tr $p $t $xy t $x]
+ set invgeo [winfo $igx($xy) $w]
+ switch $xy {
+ y {set coords [concat M [expr {int(rand()*23)}] $og L $invgeo $og]}
+ x {set coords [concat M $og [expr {int(rand()*16)}] L $og $invgeo]}}
+# y {set coords [concat M 0 $og L $invgeo $og]}
+# x {set coords [concat M $og 0 L $og $invgeo]}}
+ $w lower [$w create text [lrange $coords 1 2] -font {{Bitstream Vera Sans} 8} -fill [rc] -anchor $ta($xy) -text [string range $x 0 7] -justify $tj($xy) -tags gridline]
+ $w lower [$w create path $coords -stroke $_($t:ln) -strokedasharray [expr {int(rand()*42 + 1)}] -tags gridline -strokewidth 1]
+ }}}}
+
+#> mat frame
+#. -bd 3 #w 384 #h 144 #bg gray86 #ln white
+#. #samplerate 44100
+#. #Xa 123 #Xb 2000 #Ya 127 #Yb 0 #qx 50 #qy 1 #mx 12 #my 64
+#. @add ::ix::mat_item_new .- .| .#1 {type .#2}
+#. @update ::ix::mat_item_ua .- .| .#1 abs {.#2 .#3} 1
+#. @updaterel ::ix::mat_item_ua .- .| .#1 rel {.#2 .#3} 1
+#. @up ::ix::mat_item_ua .- .| .#1 abs {.#2 .#3} 0
+#. @uprel ::ix::mat_item_ua .- .| .#1 rel {.#2 .#3} 0
+puts "mat .- .|"
+::ix::mat_new .- .| .#w .#h .#bg .#ln .#Xa .#Xb .#Ya .#Yb .#qx .#qy .#mx .#my .#samplerate
+#bind .-.m <Enter> {focus .-.m}
+bind .-.m <Leave> {focus .^.c}
diff --git a/extensions/gui/ix/toxy/ngrid-demo.pd b/extensions/gui/ix/toxy/ngrid-demo.pd
new file mode 100644
index 00000000..29dacac1
--- /dev/null
+++ b/extensions/gui/ix/toxy/ngrid-demo.pd
@@ -0,0 +1,310 @@
+#N canvas 1333 136 79 124 12;
+#X msg 785 -536 -height 26 -width 26 -bg gray95;
+#N canvas 0 0 595 500 intro 1;
+#X obj 9 418 osc~;
+#X obj 9 456 dac~;
+#X obj 9 399 line;
+#X obj 9 -29 widget ngrid n1 #w 382 #h 382 #move 0 #radius 8;
+#X floatatom 360 365 3 2 233 0 - - -;
+#X floatatom 381 382 2 4 32 0 - - -;
+#X msg 394 381 radius \$1;
+#X msg 382 362 spread \$1;
+#X obj 403 337 bng 23 250 50 0 empty empty empty 0 -6 0 8 -24198 -1
+-1;
+#X obj 61 418 osc~;
+#X obj 35 418 osc~;
+#X obj 87 418 osc~;
+#X obj 113 418 osc~;
+#X obj 139 418 osc~;
+#X obj 35 399 line;
+#X obj 61 399 line;
+#X obj 87 399 line;
+#X obj 113 399 line;
+#X obj 139 399 line;
+#X obj 165 418 osc~;
+#X obj 191 418 osc~;
+#X obj 9 380 route 0x 0y 1x 1y 2x 2y 3x 3y 4x 4y;
+#X obj 296 405 until;
+#X obj 328 422 + 1;
+#X obj 296 424 i;
+#X msg 330 405 0;
+#X obj 217 418 osc~;
+#X obj 243 418 osc~;
+#X obj 165 399 line;
+#X obj 191 399 line;
+#X obj 217 399 line;
+#X obj 243 399 line;
+#X obj 355 446 tow . ngrid n1;
+#X obj 9 360 Append 100;
+#X msg 258 363 move swarm;
+#X msg 312 385 5;
+#X msg 326 363 move;
+#X obj 86 437 prepend set;
+#X obj 86 454 prepend set;
+#X obj 160 442 hsl 128 15 0 2000 0 0 empty empty empty -2 -6 0 8 -262144
+-1 -1 2100 1;
+#X obj 160 458 hsl 128 15 0 2000 0 0 empty empty empty -2 -6 0 8 -262144
+-1 -1 0 1;
+#X obj 423 50 widget ngrid m #w 64 #h 64;
+#X msg 407 451 add x 1 0 10 \, add y 2 0 10;
+#X obj 425 127 route x y;
+#X obj 468 146 prepend set;
+#X obj 400 147 prepend set;
+#X obj 435 166 hsl 128 15 0 10 0 0 empty empty empty -2 -6 0 8 -262144
+-1 -1 12700 1;
+#X obj 435 181 hsl 128 15 0 10 0 0 empty empty empty -2 -6 0 8 -262144
+-1 -1 385 1;
+#X obj 496 50 widget ngrid m #w 64 #h 64;
+#X obj 510 212 widget ngrid m #w 64 #h 64;
+#X obj 514 286 widget ngrid m #w 64 #h 64;
+#X obj 501 367 widget ngrid m #w 64 #h 64;
+#X obj 512 264 prepend pos;
+#X obj 503 371 prepend pos;
+#X obj 425 57 prepend setpos;
+#X obj 476 59 prepend setpos;
+#X msg 353 406 add \$1x 1000 0 2000;
+#X msg 353 425 add \$1y 1000 0 2000;
+#X msg 301 465 pos 4y \$1;
+#X obj 9 437 *~ 0.033;
+#X obj 513 215 prepend pos;
+#X obj 417 198 prepend x;
+#X obj 472 197 prepend y;
+#X msg 409 414 add x 1 10 0 \, add y 2 10 0;
+#X msg 407 434 add x 1 0 10 \, add y 2 10 0;
+#X msg 407 470 add x 1 10 0 \, add y 2 0 10;
+#X msg 303 446 pos 4x \$1;
+#X msg 240 472 pos 3x \$1;
+#X msg 168 472 pos 3y \$1;
+#X msg 195 363 move error;
+#X obj 406 219 sin;
+#X obj 410 240 hsl 99 15 0 6.28 0 0 empty empty empty -2 -6 0 8 -262144
+-1 -1 0 1;
+#X msg 404 297 pos 0x \$1;
+#X obj 458 220 cos;
+#X msg 456 295 pos 0y \$1;
+#X obj 413 259 * 500;
+#X obj 466 258 * 500;
+#X obj 412 279 + 1000;
+#X obj 468 278 + 1000;
+#X obj 414 311 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X msg 451 315 6.28 1000;
+#X obj 446 334 line;
+#X obj 449 370 select 6.28 0;
+#X obj 448 352 spigot;
+#X msg 472 333 0 2000;
+#X obj 49 480 switch~;
+#X obj 430 324 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X obj 63 363 hsl 128 15 0 2000 0 0 empty empty empty -2 -6 0 8 -262144
+-1 -1 12700 1;
+#X obj 78 368 prepend set;
+#X connect 0 0 59 0;
+#X connect 2 0 0 0;
+#X connect 3 0 33 0;
+#X connect 4 0 7 0;
+#X connect 5 0 6 0;
+#X connect 6 0 32 0;
+#X connect 7 0 32 0;
+#X connect 8 0 35 0;
+#X connect 8 0 42 0;
+#X connect 8 0 63 0;
+#X connect 8 0 65 0;
+#X connect 8 0 64 0;
+#X connect 8 0 86 0;
+#X connect 9 0 59 0;
+#X connect 10 0 59 0;
+#X connect 11 0 59 0;
+#X connect 12 0 59 0;
+#X connect 13 0 59 0;
+#X connect 14 0 10 0;
+#X connect 15 0 9 0;
+#X connect 16 0 11 0;
+#X connect 17 0 12 0;
+#X connect 18 0 13 0;
+#X connect 19 0 59 0;
+#X connect 20 0 59 0;
+#X connect 21 0 2 0;
+#X connect 21 1 14 0;
+#X connect 21 2 15 0;
+#X connect 21 3 16 0;
+#X connect 21 4 17 0;
+#X connect 21 5 18 0;
+#X connect 21 6 28 0;
+#X connect 21 7 29 0;
+#X connect 21 8 30 0;
+#X connect 21 8 37 0;
+#X connect 21 9 31 0;
+#X connect 21 9 38 0;
+#X connect 22 0 24 0;
+#X connect 23 0 24 1;
+#X connect 24 0 23 0;
+#X connect 24 0 56 0;
+#X connect 24 0 57 0;
+#X connect 25 0 24 1;
+#X connect 26 0 59 0;
+#X connect 27 0 59 0;
+#X connect 28 0 19 0;
+#X connect 29 0 20 0;
+#X connect 30 0 26 0;
+#X connect 31 0 27 0;
+#X connect 33 0 21 0;
+#X connect 34 0 32 0;
+#X connect 35 0 25 0;
+#X connect 35 0 22 0;
+#X connect 36 0 32 0;
+#X connect 37 0 39 0;
+#X connect 38 0 40 0;
+#X connect 39 0 66 0;
+#X connect 39 0 68 0;
+#X connect 40 0 58 0;
+#X connect 40 0 67 0;
+#X connect 41 0 43 0;
+#X connect 41 0 55 0;
+#X connect 41 0 60 0;
+#X connect 42 0 41 0;
+#X connect 42 0 51 0;
+#X connect 43 0 45 0;
+#X connect 43 1 44 0;
+#X connect 44 0 47 0;
+#X connect 45 0 46 0;
+#X connect 46 0 61 0;
+#X connect 47 0 62 0;
+#X connect 48 0 43 0;
+#X connect 48 0 54 0;
+#X connect 48 0 60 0;
+#X connect 49 0 52 0;
+#X connect 50 0 53 0;
+#X connect 52 0 50 0;
+#X connect 53 0 51 0;
+#X connect 54 0 41 0;
+#X connect 55 0 48 0;
+#X connect 56 0 32 0;
+#X connect 57 0 32 0;
+#X connect 58 0 32 0;
+#X connect 59 0 1 0;
+#X connect 59 0 1 1;
+#X connect 60 0 49 0;
+#X connect 61 0 60 0;
+#X connect 61 0 55 0;
+#X connect 61 0 54 0;
+#X connect 62 0 60 0;
+#X connect 62 0 54 0;
+#X connect 62 0 55 0;
+#X connect 63 0 48 0;
+#X connect 64 0 50 0;
+#X connect 65 0 49 0;
+#X connect 66 0 32 0;
+#X connect 67 0 32 0;
+#X connect 68 0 32 0;
+#X connect 69 0 32 0;
+#X connect 70 0 75 0;
+#X connect 71 0 70 0;
+#X connect 71 0 73 0;
+#X connect 72 0 32 0;
+#X connect 73 0 76 0;
+#X connect 74 0 32 0;
+#X connect 75 0 77 0;
+#X connect 76 0 78 0;
+#X connect 77 0 72 0;
+#X connect 78 0 74 0;
+#X connect 79 0 83 1;
+#X connect 79 0 80 0;
+#X connect 80 0 81 0;
+#X connect 81 0 83 0;
+#X connect 82 0 84 0;
+#X connect 82 1 80 0;
+#X connect 83 0 82 0;
+#X connect 83 0 71 0;
+#X connect 84 0 81 0;
+#X connect 86 0 85 0;
+#X connect 87 0 88 0;
+#X connect 88 0 33 0;
+#X restore 18 35 pd intro;
+#N canvas 0 0 442 580 om 0;
+#X obj 306 502 sendOSC;
+#X msg 307 426 connect localhost 16180;
+#X obj 306 483 prepend send;
+#X obj 23 382 dumpOSC 3339;
+#X obj 22 -8 widget ngrid n2 #w 382 #h 382 #move 0 #radius 8;
+#X obj 23 403 OSCroute /om;
+#X obj 23 422 OSCroute /new_port;
+#X obj 23 441 niagara 4;
+#X obj 23 460 niagara 1;
+#X obj 23 498 glue;
+#X obj 23 555 prepend add;
+#X obj 23 479 a2l;
+#X obj 406 407 t b b b;
+#X msg 306 464 /om/request/all_objects 5;
+#X obj 207 388 widget dm dmngr #items .(error normal swarm trails.)
+;
+#X msg 154 394 move \$1;
+#X msg 351 503 disconnect;
+#X obj 99 459 prepend /om/synth/set_port_value 1;
+#X msg 305 445 /om/engine/register_client 0 localhost 3339;
+#X obj 72 479 niagara 1;
+#X obj 23 517 spigot;
+#X msg 72 517 1;
+#X msg 92 517 0;
+#X obj 72 498 route CONTROL;
+#X obj 146 421 OSCroute /control_change;
+#X obj 146 438 prepend setpos;
+#X obj 102 401 spigot;
+#X obj 133 387 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 165 478 OSCroute /node_removal;
+#X obj 112 517 niagara 1;
+#X obj 23 536 spigot;
+#X msg 72 536 1;
+#X msg 92 536 0;
+#X obj 112 536 route INPUT;
+#X obj 166 497 prepend delete;
+#X obj 354 406 loadbang;
+#X text 266 546 www.nongnu.org/om-synth/;
+#X obj 199 532 print NOSHIT;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 3 0 5 0;
+#X connect 3 0 37 0;
+#X connect 4 0 17 0;
+#X connect 5 0 6 0;
+#X connect 5 0 26 0;
+#X connect 5 0 28 0;
+#X connect 6 0 7 0;
+#X connect 7 0 8 0;
+#X connect 7 1 9 1;
+#X connect 8 0 11 0;
+#X connect 8 1 19 0;
+#X connect 9 0 20 0;
+#X connect 10 0 4 0;
+#X connect 11 0 9 0;
+#X connect 12 0 13 0;
+#X connect 12 1 18 0;
+#X connect 12 2 1 0;
+#X connect 13 0 2 0;
+#X connect 14 0 15 0;
+#X connect 15 0 4 0;
+#X connect 16 0 0 0;
+#X connect 17 0 2 0;
+#X connect 18 0 2 0;
+#X connect 19 0 23 0;
+#X connect 19 1 29 0;
+#X connect 20 0 30 0;
+#X connect 21 0 20 1;
+#X connect 22 0 20 1;
+#X connect 23 0 21 0;
+#X connect 23 1 22 0;
+#X connect 24 0 25 0;
+#X connect 25 0 4 0;
+#X connect 26 0 24 0;
+#X connect 27 0 26 1;
+#X connect 28 0 34 0;
+#X connect 29 0 33 0;
+#X connect 30 0 10 0;
+#X connect 31 0 30 1;
+#X connect 32 0 30 1;
+#X connect 33 0 31 0;
+#X connect 33 1 32 0;
+#X connect 34 0 4 0;
+#X connect 35 0 12 0;
+#X restore 18 59 pd om;
diff --git a/extensions/gui/ix/toxy/ngrid.wid b/extensions/gui/ix/toxy/ngrid.wid
new file mode 100755
index 00000000..6d8f16d2
--- /dev/null
+++ b/extensions/gui/ix/toxy/ngrid.wid
@@ -0,0 +1,150 @@
+namespace eval ::ix {
+ proc random_int {} {return [expr "int(floor(rand()*16))"]}
+ proc random_clr {} {
+ return [format "\#%1X%1X%1X%1X%1X%1X" [random_int] [random_int] [random_int] [random_int] [random_int] [random_int]]
+ }
+ variable _
+
+ proc ngrid_new {path target w h bg ln div move spread radius max} {
+ variable _
+ if {[winfo exists $path.ngrid] != 1} {
+ canvas $path.ngrid -bg $bg -width $w -height $h
+ pack $path.ngrid -side left
+ bind $path.ngrid <1> "::ix::ngrid_click $path $target %x %y"
+ bind $path.ngrid <B1-Motion> [bind $path.ngrid <1>]
+ ngrid_gridlines $path $target $ln $div
+ set bd [expr {[$path cget -bd] * 2}]
+ $path configure -bg $bg -width [expr [winfo width $path.ngrid] + $bd] -height [expr [winfo height $path.ngrid] + $bd]
+ }
+ set _($target:recent) 0
+ set _($target:n) 0
+ set _($target:move) $move
+ set _($target:spread) $spread
+ set _($target:radius) $radius
+ set _($target:max) $max}
+
+ proc ngrid_find {which path target what udata} {
+ variable _
+ array set dm {x width y height}
+ for {set n 0 } {$n <= $_($target:n)} {incr n} {
+ foreach xy {x y} {
+ if {[$path.ngrid find withtag name_${xy}_$n] ne "" && [string match "$what*" [lindex $_($target:box$n:$xy) 0]]} {
+ set x [expr [lindex [$path.ngrid coords sqr_$n] 0] + $_($target:radius)]
+ set y [expr [lindex [$path.ngrid coords sqr_$n] 1] + $_($target:radius)]
+ set $xy [expr ($udata - [lindex $_($target:box$n:$xy) 1 ] + 0.0) / ([lindex $_($target:box$n:$xy) 2] - [lindex $_($target:box$n:$xy) 1 ] + 0.0) * [winfo $dm($xy) $path.ngrid]]
+ switch $which {
+ setpos {$path.ngrid coords sqr_$n [expr $x - $_($target:radius)] [expr $y - $_($target:radius)] [expr $x + $_($target:radius)] [expr $y + $_($target:radius)]}
+ pos {
+ set _($target:recent) $n
+ ngrid_click $path $target $x $y
+ }
+ remove {
+ $path.ngrid delete name_${xy}_$n
+ if {[$path.ngrid find withtag name_x_$n] eq "" && [$path.ngrid find withtag name_x_$n] eq ""} {
+ $path.ngrid delete sqr_$n; $path.ngrid delete hist_$n}}}}}}}
+
+ proc ngrid_vset {path target what where} {variable _; set _($target:$what) $where}
+
+ proc ngrid_add {path target name cur min max} {
+ variable _
+ if {$max == $min} {set max 1.0; set min 0.0}
+ array set justify {x left y right}
+ array set anchor {y e x w}
+ for {set n 0 } {$n <= $_($target:n)} {incr n} {foreach xy {x y} {
+ if {[$path.ngrid itemcget name_${xy}_$n -text] eq $name} {return}}}
+
+ for {set n 0 } {$n <= $_($target:n)} {incr n} {foreach xy {x y} {
+ if {[$path.ngrid find withtag name_x_$n] eq "" && [$path.ngrid find withtag name_y_$n] eq ""} {
+ set fill [set _($target:box$n:fill) [random_clr]]
+ $path.ngrid create oval 0 0 0 0 -tags sqr_$n -fill $fill -outline white -width 2
+ set rx [expr rand() * [winfo width $path.ngrid]]; set ry [expr rand() * [winfo height $path.ngrid]]
+ $path.ngrid create line $rx $ry $rx $ry -tags hist_$n -fill $fill
+ $path.ngrid bind sqr_$n <1> "set ::ix::_($target:recent) $n; ::ix::ngrid_click $path $target %x %y"
+ $path.ngrid bind sqr_$n <B1-Motion> [$path.ngrid bind sqr_$n <1>]
+ $path.ngrid bind sqr_$n <Enter> "::ix::ngrid_highlight $path $target $n grey96"
+ $path.ngrid bind sqr_$n <Leave> "::ix::ngrid_highlight $path $target $n -"
+ ngrid_move $path $target $n $rx $ry
+ incr _($target:n)
+ }
+ if {[$path.ngrid find withtag name_${xy}_$n] eq ""} {
+ set _($target:box$n:$xy) [list $name $min $max]
+ puts "adding $xy $n $name $min $max"
+ switch $xy {
+ x {
+ set tl [concat 0 [expr 5 + $n * 8.0]]
+ set qx [expr ($cur - $min) / ($max - $min + 0.0) * [winfo width $path.ngrid]]
+ set qy [expr [lindex [$path.ngrid coords sqr_$n] 1] + $_($target:radius)]}
+ y {
+ set tl [concat [winfo width $path.ngrid] [expr 5 + $n * 8.0]]
+ set qx [expr [lindex [$path.ngrid coords sqr_$n] 0] + $_($target:radius)]
+ set qy [expr ($cur - $min) / ($max - $min + 0.0) * [winfo height $path.ngrid]]}}
+ $path.ngrid create text $tl -tags name_${xy}_$n -fill $_($target:box$n:fill) -font {{Bitstream Vera Sans} 8} -text $name -anchor $anchor($xy) -justify $justify($xy)
+ $path.ngrid lower name_${xy}_$n
+ $path.ngrid bind name_${xy}_$n <Enter> "::ix::ngrid_highlight $path $target $n grey96"
+ $path.ngrid bind name_${xy}_$n <Leave> "::ix::ngrid_highlight $path $target $n -"
+ ngrid_move $path $target $n $qx $qy
+ return}}}}
+
+ proc ngrid_highlight {path target n color} {
+ variable _
+ foreach el [list name_y_$n name_x_$n sqr_$n] {
+ if {$color eq "-"} {set color $_($target:box$n:fill)}
+ $path.ngrid itemconfigure $el -fill $color
+ set _($target:recent) $n}}
+
+ proc ngrid_click {path target x y} {
+ variable _
+ switch $_($target:move) {
+ swarm {
+ for {set n 0} {$n <= $_($target:n)} {incr n} {
+ ngrid_move $path $target $n [expr rand() * $_($target:spread) - [expr $_($target:spread) / 2.0] + $x] [expr rand() * $_($target:spread) - [expr $_($target:spread) / 2.0] + $y]}}
+ trails {
+ for {set n 0} {$n <= $_($target:n)} {incr n} {
+ if {[expr rand() > 0.96] == 1} {
+ ngrid_move $path $target $n [expr rand() * $_($target:spread) - [expr $_($target:spread) / 2.0] + $x] [expr rand() * $_($target:spread) - [expr $_($target:spread) / 2.0] + $y]}}}
+ error {ngrid_move $path $target $_($target:recent) [expr rand() * $_($target:spread) - [expr $_($target:spread) / 2.0] + $x] [expr rand() * $_($target:spread) - [expr $_($target:spread) / 2.0] + $y]}
+ default {ngrid_move $path $target $_($target:recent) $x $y}}}
+
+ proc ngrid_move {path target n px py} {
+ variable _
+ $path.ngrid coords sqr_$n [expr $px - $_($target:radius)] [expr $py - $_($target:radius)] [expr $px + $_($target:radius)] [expr $py + $_($target:radius)]
+ set h [winfo height $path.ngrid]
+ set w [winfo width $path.ngrid]
+ foreach xy {x y} {
+ if {[$path.ngrid find withtag name_${xy}_$n] ne ""} {
+ set l $_($target:box$n:$xy)
+ set name [lindex $l 0]
+ set min [lindex $l 1]
+ set max [lindex $l 2]
+ if {[expr $min == 0] && [expr $max == 0]} {set max $_($target:max)}
+ pd "$target.rp _cb [pdtk_enquote $name] [expr ($max - $min) * [set p$xy] / $w.0 + $min] \;"}}}
+
+ proc ngrid_gridlines {path target ln lines} {
+ variable _
+ puts "gridlines $ln $lines"
+ set w $path.ngrid
+ $w delete gridlines
+ set gh [winfo height $w]
+ set gw [winfo width $w]
+ for {set x 1} {$x <= $lines} {incr x} {
+ if {$lines < 16 && $lines > 0} {
+ set oh [expr $gh.0 * $x.0 / $lines.0]
+ set ow [expr $gw.0 * $x.0 / $lines.0]
+ $w create line $ow 0 $ow $gh -fill $ln -tags gridlines
+ $w create line 0 $oh $gw $oh -fill $ln -tags gridlines}}}}
+
+#> ngrid frame
+#. -bd 3 #w 384 #h 144 #bg gray10 #ln gray35 #div 6 #n 3
+#. #move normal #spread 96 #radius 9 #max 1
+#. @list ::ix::ngrid_add .- .| {.#1} .#2 .#3 .#4
+#. @add ::ix::ngrid_add .- .| {.#1} .#2 .#3 .#4
+#. @pos ::ix::ngrid_find pos .- .| {.#1} .#2
+#. @setpos ::ix::ngrid_find setpos .- .| {.#1} .#2
+#. @delete ::ix::ngrid_find remove .- .| {.#1} 0
+#. @clear ::ix::ngrid_clear .- .| all
+#. @radius ::ix::ngrid_vset .- .| radius .#1
+#. @spread ::ix::ngrid_vset .- .| spread .#1
+#. @move ::ix::ngrid_vset .- .| move .#1
+#. @max ::ix::ngrid_vset .- .| max .#1
+puts "ngrid .- .|"
+::ix::ngrid_new .- .| .#w .#h .#bg .#ln .#div .#move .#spread .#radius .#max
diff --git a/extensions/gui/ix/toxy/nob-demo.pd b/extensions/gui/ix/toxy/nob-demo.pd
new file mode 100755
index 00000000..901001a8
--- /dev/null
+++ b/extensions/gui/ix/toxy/nob-demo.pd
@@ -0,0 +1,74 @@
+#N canvas 151 325 465 268 12;
+#X floatatom 234 44 5 16 1024 0 - - -;
+#X msg 234 62 #w \$1 \, #h \$1;
+#X msg 14 209 #trans \$1;
+#X floatatom 14 191 5 22 100 0 - - -;
+#X obj 356 150 widget nob n2 #w 34 #h 35 #ca "#ff4a9c" #cb "#83f735"
+#cc "#fff74a" #trans 100 #th 8 #bg "#446dfd" #cn "#83f735" #nx -30
+#ny -30 -bd 1;
+#X obj 103 198 nbx 8 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 10
+-262144 -1 -1 31.6832 256;
+#X obj 103 89 widget nob n1 #w 100 #h 100 #th 7 #cc purple #cb black
+#ca red #trans 81 #bg orange #range 1 #cn yellow #ny 82 #nx 50 #max
+0 #min 0 -bd 1;
+#X msg 225 159 #range \$1;
+#X msg 247 194 1;
+#X msg 274 194 10000;
+#X floatatom 234 6 5 1 50 0 - - -;
+#X msg 234 21 #th \$1;
+#X obj 338 18 tot .;
+#X msg 338 0 query tk_chooseColor;
+#X obj 333 36 makefilename "%s";
+#X obj 183 29 widget nob n3 #size #1 #w 30 #h 30 #ny 87 #nx 33 #th
+8 #bg orange #cc green #trans 134;
+#X floatatom 280 114 5 0 0 0 - - -;
+#X msg 280 129 #ny \$1;
+#X floatatom 183 11 5 0 0 0 - - -;
+#X floatatom 183 62 5 0 0 0 - - -;
+#X floatatom 280 81 5 0 0 0 - - -;
+#X msg 280 96 #nx \$1;
+#X msg 247 220 #max 1;
+#X obj 8 -2 widget dm color #arrows 0 #items .(bg ca cb cc cn.);
+#X obj 108 2 loadbang;
+#X obj 37 -2 widget dm bg #arrows 0 #items .(green red purple blue
+orange yellow black white pink.);
+#X obj 41 53 prepend;
+#X msg 108 21 bg;
+#X obj 285 152 widget dm range #arrow 0 #items .(1 100 1000 0.1.) #arrows
+0;
+#X msg 292 220 #max 32 \, #min 16;
+#X msg 247 240 #min 0 \, #max 0;
+#X obj 7 29 makefilename #%s;
+#X text 347 87 right = 1/10th;
+#X text 347 76 middle = 10;
+#X text 357 99 left = 1;
+#X connect 0 0 1 0;
+#X connect 1 0 6 0;
+#X connect 2 0 6 0;
+#X connect 3 0 2 0;
+#X connect 6 0 5 0;
+#X connect 7 0 6 0;
+#X connect 8 0 6 0;
+#X connect 9 0 6 0;
+#X connect 10 0 11 0;
+#X connect 11 0 6 0;
+#X connect 12 0 14 0;
+#X connect 13 0 12 0;
+#X connect 14 0 26 0;
+#X connect 15 0 19 0;
+#X connect 16 0 17 0;
+#X connect 17 0 6 0;
+#X connect 18 0 15 0;
+#X connect 19 0 6 0;
+#X connect 20 0 21 0;
+#X connect 21 0 6 0;
+#X connect 22 0 6 0;
+#X connect 23 0 31 0;
+#X connect 24 0 27 0;
+#X connect 25 0 26 0;
+#X connect 26 0 6 0;
+#X connect 27 0 31 0;
+#X connect 28 0 7 0;
+#X connect 29 0 6 0;
+#X connect 30 0 6 0;
+#X connect 31 0 26 1;
diff --git a/extensions/gui/ix/toxy/nob.wid b/extensions/gui/ix/toxy/nob.wid
new file mode 100755
index 00000000..9d256537
--- /dev/null
+++ b/extensions/gui/ix/toxy/nob.wid
@@ -0,0 +1,105 @@
+#console show
+package require Tkzinc 3.3
+package require zincGraphics
+namespace eval ::ix {
+ variable _
+ proc nobfloat {path t num} {
+ variable _
+ $path itemconfigure $t:num -text $num
+ pd [concat $t.rp _cb $num \;]
+ set _($t:num) $num
+ }
+ proc nob_mover {w t f x y} {
+ variable _
+ if {$::ix::_($t:clickd) > 0} {
+ set move [expr (($x - $::ix::_($t:lx)) + (-1 * ($y - $::ix::_($t:ly)))) / ([winfo width $w].0 + [winfo height $w].0) * $f]
+ nob_move $w $t $move
+ }
+ set ::ix::_($t:clickd) 1
+ set ::ix::_($t:lx) $x
+ set ::ix::_($t:ly) $y
+ }
+ proc nob_move {w t move} {
+ variable _
+ set on [$w itemcget $t:num -text]
+ set no [expr $on + $_($t:range) * $move * 2]
+ if {$_($t:min) != $_($t:max)} {
+ if {$no > $_($t:max)} {set no $_($t:max);set move 0}
+ if {$no < $_($t:min)} {set no $_($t:min);set move 0}
+ }
+ nobfloat $w $t $no
+ foreach e {1 10 100} {
+ set a [expr [$w itemcget $t:nob$e -startangle] + int($move * $e * 90)]
+ $w itemconfigure $t:nob$e -startangle $a
+ set _($t:a$e) $a
+ }
+ }
+
+ proc nob {path t w h range bg c1 c2 c3 cn trans th nx ny max min} {
+ variable _
+ set _($t:lx) 32
+ set _($t:clickd) -1
+ set _($t:max) $max
+ set _($t:min) $min
+ if {$_($t:min) != $_($t:max)} {
+ set _($t:range) [expr abs($min - $max)]
+ } else {
+ set _($t:range) $range
+ }
+ if {[winfo exists $path.nob] != 1} {
+ zinc $path.nob -render 1 -width $w -height $h -borderwidth 1 -lightangle 140 -backcolor $bg
+ $path configure -width $w -height $h
+ place $path.nob -anchor nw -relwidth 1 -relheight 1
+ $path.nob remove *
+ set i 0
+ set colors [list $c1 $c2 $c3]
+ set ratios {1 10 0.1}
+ set edge 10
+ $path.nob add rectangle 1 {1 1 8 4} -filled 1 -fillcolor "#555555"
+ $path.nob add rectangle 1 "1 $h 8 [expr $h - 5]" -filled 1 -fillcolor "#555555"
+ foreach e {1 10 100} {
+ $path.nob add arc 1 \
+ "[expr $w / $edge / ($i + 1) + ($edge / 2)] [expr $h / $edge / ($i + 1) + ($edge / 2)] [expr $w - $w / $edge / ($i + 1) - ($edge / 2)] [expr $h - $h / $edge / ($i + 1) - ($edge / 2)]" \
+ -closed 0 -filled 0 -extent [expr int(300 / $e)] -startangle 90 \
+ -linecolor "[lindex $colors $i];$trans" \
+ -linewidth [expr int($h / $th)] \
+ -tags $t:nob$e
+ bind $path.nob <B[expr $i + 1]-Motion> \
+ "::ix::nob_mover $path.nob $t [lindex $ratios $i] %x %y"
+ incr i
+ bind $path.nob <ButtonRelease-$i> "set ::ix::_($t:clickd) -1"
+ }
+ bind $path <MouseWheel> {::ix::nob_move %W.nob [winfo name %W] [expr %D / 2400.]}
+ bind $path <Shift-MouseWheel> {::ix::nob_move %W.nob [winfo name %W] [expr %D / 24000.]}
+ bind $path <Control-MouseWheel> {::ix::nob_move %W.nob [winfo name %W] [expr %D / 240.]}
+ bind $path.nob <Shift-B1-Motion> "::ix::nob_mover $path.nob $t 10 %x %y"
+ bind $path.nob <Control-B1-Motion> "::ix::nob_mover $path.nob $t 0.1 %x %y"
+ if {$nx == 0} {
+ set nx [expr $w / 2]
+ set ny [expr $h - 20]
+ }
+ $path.nob add text 1 -text "0.0" \
+ -position "$nx $ny" -tags $t:num -color "$cn;$trans"
+ }
+ if {[info exists _($t:num)]} {
+ $path.nob itemconfigure $t:num -text $_($t:num)
+ foreach e {1 10 100} {
+ $path.nob itemconfigure $t:nob$e -startangle $_($t:a$e)
+ }
+ } else {
+ foreach e {1 10 100} {set _($t:a$e) 90}
+ set _($t:num) 0.0}
+
+ }
+}
+#> nob frame
+#. -height 128 -width 128 -bd 1 -bg "#cccccc"
+#. -highlightbackground red
+#. #max 0 #min 0
+#. #w 128 #h 128 #trans 70 #th 5 #range 100 #nx 0 #ny 0
+#. #bg purple #ca blue #cb yellow #cc green #cn orange
+#. @float ::ix::nobfloat .-.nob .| .#1
+#. @cmd eval ".-.nob .#args"
+bind .- <Enter> {focus .-}
+bind .- <Leave> {focus .^.c}
+::ix::nob .- .| .#w .#h .#range .#bg .#ca .#cb .#cc .#cn .#trans .#th .#nx .#ny .#max .#min
diff --git a/extensions/gui/ix/toxy/q-demo.pd b/extensions/gui/ix/toxy/q-demo.pd
new file mode 100755
index 00000000..492c538e
--- /dev/null
+++ b/extensions/gui/ix/toxy/q-demo.pd
@@ -0,0 +1,90 @@
+#N canvas 46 0 792 949 12;
+#X obj 20 352 widget q q1 -width 37 -height 56 -font .(Tahoma 8.) -bg
+white -fg cyan;
+#X obj 58 332 popen;
+#X msg 58 313 grep \$1 wavs.d;
+#X obj 56 276 widget dd d1 -width 30;
+#X msg 16 313 clear;
+#X obj 18 278 t s b;
+#X obj 312 363 player w;
+#X obj 353 242 loadbang;
+#X msg 387 313 \; pd dsp 1;
+#X floatatom 258 335 5 0 0 0 - - -;
+#X obj 210 584 widget q lb2 -width 24 -height 26;
+#X obj 17 56 widget q x0;
+#X obj 148 56 widget q x1;
+#X obj 278 57 widget q x2;
+#X obj 408 57 widget q x3;
+#X obj 537 57 widget q x5;
+#X obj 19 32 pool w;
+#X msg 19 11 chdir \, getsub;
+#X obj 280 238 l2s;
+#X msg 306 260 symbol /;
+#X obj 19 210 ndx;
+#X obj 670 57 widget q q5;
+#X msg 384 352 load wavs.dat;
+#X obj 280 211 ndx;
+#X obj 150 210 ndx;
+#X obj 411 211 ndx;
+#X obj 539 211 ndx;
+#X obj 672 211 ndx;
+#X text 54 263 search;
+#X text 220 564 <-right click starts drag;
+#X obj 310 409 widget q -bg -fg white -width 41 -bg black;
+#X obj 212 409 widget q -width -bg "#2f3351" -fg "#ff8617" -width 16
+;
+#X msg 151 296 clear;
+#X msg 102 259 bang;
+#X obj 348 382 outlet~;
+#X obj 394 382 outlet~;
+#X msg 222 352 next;
+#X msg 222 334 prev;
+#X msg 263 362 stop;
+#X connect 0 0 6 1;
+#X connect 1 0 0 0;
+#X connect 2 0 1 0;
+#X connect 3 0 5 0;
+#X connect 4 0 0 0;
+#X connect 5 0 2 0;
+#X connect 5 1 4 0;
+#X connect 6 2 30 0;
+#X connect 6 3 31 0;
+#X connect 6 4 36 0;
+#X connect 6 5 34 0;
+#X connect 6 6 35 0;
+#X connect 7 0 8 0;
+#X connect 7 0 19 0;
+#X connect 7 0 22 0;
+#X connect 9 0 0 0;
+#X connect 11 0 20 1;
+#X connect 12 0 24 1;
+#X connect 13 0 23 1;
+#X connect 14 0 25 1;
+#X connect 15 0 26 1;
+#X connect 16 1 11 0;
+#X connect 17 0 16 0;
+#X connect 18 0 6 1;
+#X connect 19 0 18 1;
+#X connect 20 0 18 0;
+#X connect 20 0 24 0;
+#X connect 20 1 12 0;
+#X connect 21 0 27 1;
+#X connect 22 0 6 2;
+#X connect 23 0 18 0;
+#X connect 23 0 25 0;
+#X connect 23 1 14 0;
+#X connect 24 0 18 0;
+#X connect 24 0 23 0;
+#X connect 24 1 13 0;
+#X connect 25 0 18 0;
+#X connect 25 0 26 0;
+#X connect 25 1 15 0;
+#X connect 26 0 18 0;
+#X connect 26 0 27 0;
+#X connect 26 1 21 0;
+#X connect 27 0 18 0;
+#X connect 32 0 3 0;
+#X connect 33 0 3 0;
+#X connect 36 0 0 0;
+#X connect 37 0 0 0;
+#X connect 38 0 6 0;
diff --git a/extensions/gui/ix/toxy/q.wid b/extensions/gui/ix/toxy/q.wid
new file mode 100755
index 00000000..8a971c6e
--- /dev/null
+++ b/extensions/gui/ix/toxy/q.wid
@@ -0,0 +1,84 @@
+#console show
+package require tkdnd
+namespace eval ::ix {
+ proc qo {p t e} {
+ set s [$p get $e]
+ if {$s ne ""} {
+ pd [concat $t.rp _cb symbol [pdtk_enquote $s] \;]
+ } else {pd [concat $t.rp _cb bang \;]}
+ }
+ proc qi {p t i} {
+ $p selection clear 0 end
+ $p selection set $i
+ qo $p $t $i
+ }
+ proc q_go {p t d} {
+ array set direction "next 1 prev -1"
+ array set edge "next end prev 0"
+ set cs [$p curselection]
+ if {$cs eq "" && [$p index end] != 0} {
+ set go 0 } else {
+ set go [expr $direction($d) + [lindex $cs $edge($d)]]}
+ if {$go >= [$p index end]} {set go 0}
+ if {$go < 0} {set go [expr [$p index end] - 1]}
+ qi $p $t $go
+ }
+}
+#> q listbox
+#. -selectmode extended -font {{Bitstream Vera Sans} 8} -exportselection 0
+#. -relief flat -borderwidth 0 -selectborderwidth 0 -bg "#ccffcc" -fg black
+#. @list foreach x [list .#args] {.- insert end $x}
+#. @add .- insert end [join [lrange [list .#args] 0 end] " "]
+#. @scroll .- yview scroll .#1 units
+#. @symbol .- insert end {.#1}
+#. @float ::ix::qi .- .| .#1
+#. @clear .- delete 0 end
+#. @next ::ix::q_go .- .| next
+#. @prev ::ix::q_go .- .| prev
+#. @cmd eval ".- .#args"
+bind .- <Enter> {focus .-}
+bind .- <Leave> {focus .^.c}
+bind .- <4> { pd [concat .|.rp _cb scroll -5 \;]}
+bind .- <5> { pd [concat .|.rp _cb scroll 5 \;]}
+bind .- <Shift-MouseWheel> {.- xview scroll [expr {- (%D / 120) * 4}] units}
+bind .- <ButtonPress-3> {}
+bind .- <Button3-Leave> {dnd drag %W}
+dnd bindtarget .- text/plain <Drop> {
+ foreach l [split %D "\n"] {.- insert end [regsub -- {^file:[/]+} $l "/"]}
+}
+dnd bindtarget .- text/uri-list <Drop> {foreach d %D {.- insert end [regsub -- {^file:[/]+} $d "/"]}}
+dnd bindsource .- text/uri-list {
+ set sel [.- curselection]
+ if {$sel ne ""} {
+ set dd {}
+ foreach el $sel {
+ lappend dd [.- get $el]
+ }
+ return $dd
+ }
+}
+bind .- <<ListboxSelect>> {
+ set sel [.- curselection]
+ if {$sel ne ""} {
+ ::ix::qo .- .| [lindex $sel end]
+# foreach el $sel {
+# ::ix::qo .- .| $el
+# }
+ }
+}
+bind .- <<delete>> {
+ set sel [.- curselection]
+ if {$sel ne ""} {
+ for {set i [expr [llength $sel] - 1]} {0 <= $i} {incr i -1} {
+ .- delete [lindex $sel $i]
+ }
+ }
+}
+bind .- <<selectAll>> {
+ .- selection set 0 end
+}
+event add <<selectAll>> <KeyPress-a>
+event add <<delete>> <Delete>
+event add <<delete>> <BackSpace>
+event add <<delete>> <KeyPress-d>
+puts "q .- .|"
diff --git a/extensions/gui/ix/toxy/sp-demo.pd b/extensions/gui/ix/toxy/sp-demo.pd
new file mode 100755
index 00000000..28bd5464
--- /dev/null
+++ b/extensions/gui/ix/toxy/sp-demo.pd
@@ -0,0 +1,325 @@
+#N canvas 387 298 580 364 10;
+#X obj 40 102 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X obj -196 21 loadbang;
+#X obj -196 111 until;
+#X obj -299 225 textfile;
+#X obj -299 207 prepend add2;
+#X msg -307 171 clear;
+#X msg -307 171 bang;
+#X obj -299 243 prepend draw;
+#X obj -307 153 t b b b;
+#X obj -196 129 f 512;
+#X obj -196 147 mod 512;
+#X obj -196 147 - 1;
+#X obj -176 75 samplerate~;
+#X obj -251 71 * 1000;
+#X obj -196 75 /;
+#X obj -273 89 metro 46;
+#X msg -77 218 img configure -height \$1 \, -height \$1;
+#X obj -196 93 i 512;
+#X obj 63 33 hsl 128 15 0 1000 0 1 empty empty hue -2 -6 0 8 -1 -262144
+-1 6200 1;
+#X obj -149 200 exp;
+#X obj 42 32 tgl 15 1 empty empty empty 0 -6 0 8 -99865 -195568 -1
+1 1;
+#X obj -174 165 demux;
+#X obj -129 182 log;
+#X obj -149 182 *;
+#X obj -129 164 t f f;
+#X obj -129 200 /;
+#X msg -248 129 -1;
+#X msg -225 129 1;
+#X obj 197 33 hsl 128 15 30 300 0 1 empty empty gain -2 -6 0 8 -262144
+-1 -1 4200 1;
+#X obj -129 254 +;
+#X obj 59 49 widget sp sp1 -height 303;
+#X obj -162 236 sqrt;
+#X obj -157 272 mod 1000;
+#X obj -157 290 demux;
+#X obj 42 50 tgl 15 1 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj -129 326 abs;
+#X obj -129 308 - 1000;
+#X obj -129 236 * 110;
+#X msg -196 39 512;
+#X obj -147 129 i;
+#X obj -196 57 t f b;
+#X obj 3 75 nbx 5 14 -1e+37 1e+37 0 1 empty empty empty 0 -6 0 10 -262144
+-1 -1 303 256;
+#X obj -322 17 mp3amp~;
+#X msg -271 -1 disconnect;
+#X msg -209 -1 connecturl live365.com:80/play/wfmu1;
+#X obj 61 -5 widget dd d1 #width 25 -width 73;
+#X obj -271 37 readsf~ 2;
+#X msg -271 17 open \$1 \, 1;
+#X obj -329 55 dac~;
+#X text 6 30 log/lin;
+#X text 11 100 start;
+#X text 2 52 palette;
+#X text 3 44 inverse;
+#N canvas 845 38 435 259 1000sp 0;
+#X obj 96 113 inlet;
+#X obj 12 -13 inlet~;
+#X obj 11 68 rfft~;
+#X obj 5 103 *~;
+#X obj 12 135 sqrt~;
+#X obj 32 103 *~;
+#X obj 94 27 loadbang;
+#X obj 94 48 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X obj 105 65 prepend set;
+#X obj 122 47 pack 1 1 1;
+#X obj 166 21 inlet;
+#X obj 95 83 switch~ 512 1 1;
+#X obj 247 1 table \$0sp 512;
+#X obj 11 166 tabwrite~ \$0sp;
+#X obj 36 9 tabreceive~ \$0w;
+#X obj 338 1 table \$0w;
+#X msg 310 112 0;
+#X obj 267 130 osc~;
+#X obj 267 83 samplerate~;
+#X obj 267 107 / 256;
+#X obj 267 152 *~ -0.5;
+#X obj 267 174 +~ 0.5;
+#X obj 253 41 loadbang;
+#X obj 23 31 *~;
+#X obj 252 203 tabwrite~ \$0w;
+#X obj 338 25 pack f \$0;
+#X msg 338 43 \; \$2w resize \$1;
+#X obj 193 45 t b f;
+#X msg 253 63 bang;
+#X obj 338 101 pack f \$0;
+#X msg 338 119 \; \$2sp resize \$1;
+#X obj 338 83 / 2;
+#X connect 0 0 13 0;
+#X connect 1 0 23 0;
+#X connect 2 0 3 1;
+#X connect 2 0 3 0;
+#X connect 2 1 5 1;
+#X connect 2 1 5 0;
+#X connect 3 0 4 0;
+#X connect 4 0 13 0;
+#X connect 5 0 4 0;
+#X connect 6 0 7 0;
+#X connect 7 0 11 0;
+#X connect 8 0 11 0;
+#X connect 9 0 8 0;
+#X connect 10 0 9 0;
+#X connect 10 0 27 0;
+#X connect 14 0 23 1;
+#X connect 16 0 17 1;
+#X connect 17 0 20 0;
+#X connect 18 0 19 0;
+#X connect 19 0 17 0;
+#X connect 20 0 21 0;
+#X connect 21 0 24 0;
+#X connect 22 0 28 0;
+#X connect 23 0 2 0;
+#X connect 25 0 26 0;
+#X connect 27 0 28 0;
+#X connect 27 1 19 1;
+#X connect 27 1 25 0;
+#X connect 27 1 31 0;
+#X connect 28 0 16 0;
+#X connect 28 0 18 0;
+#X connect 28 0 24 0;
+#X connect 29 0 30 0;
+#X connect 31 0 29 0;
+#X restore -285 112 pd \$0sp;
+#X obj -162 218 tabread4 \$0sp;
+#X msg -170 39 1024;
+#X obj -157 343 * 0.255;
+#N canvas 0 0 356 499 hsv2rgb 0;
+#X obj 152 455 sprintf symbol #%02x%02x%02x;
+#X obj 41 14 inlet;
+#X obj 153 471 outlet;
+#X obj 53 75 / 42.5;
+#X obj 18 55 t f f;
+#X obj 31 33 unpack f f f;
+#X obj 16 85 / 42.5;
+#X obj 23 115 -;
+#X obj 56 97 i;
+#X obj 115 78 / 255;
+#X obj 96 112 *;
+#X obj 70 143 *;
+#X text 14 39 h;
+#X text 58 46 s;
+#X text 88 42 v;
+#X text 75 102 i;
+#X text 16 120 f;
+#X text 145 83 vf;
+#X text 115 117 vs;
+#X text 90 148 vsf;
+#X text 147 185 p;
+#X text 73 225 q;
+#X text 132 212 t;
+#X obj 122 139 t b f;
+#X obj 124 162 f;
+#X obj 126 183 -;
+#X obj 52 192 f;
+#X obj 52 169 t b f;
+#X obj 54 220 -;
+#X obj 112 207 +;
+#X obj 131 272 f;
+#X obj 162 271 f;
+#X obj 197 272 f;
+#X obj 231 271 f;
+#X text 250 277 v;
+#X text 218 275 p;
+#X text 146 279 t;
+#X text 182 278 q;
+#X obj 92 278 i;
+#X obj 214 293 prepend add2;
+#X msg 193 321 96.8999 0 255;
+#X obj 77 325 t b b b;
+#X obj 79 252 t b b f b;
+#X msg 191 295 set;
+#X obj 90 345 t b b b;
+#X obj 116 367 t b b b;
+#X obj 138 387 t b b b;
+#X obj 153 414 t b b b;
+#X obj 167 435 t b b b;
+#X obj 79 300 route 1 2 3 4 5;
+#X connect 0 0 2 0;
+#X connect 1 0 5 0;
+#X connect 3 0 8 0;
+#X connect 4 0 6 0;
+#X connect 4 1 3 0;
+#X connect 5 0 4 0;
+#X connect 5 1 10 0;
+#X connect 5 2 9 0;
+#X connect 5 2 24 1;
+#X connect 5 2 26 1;
+#X connect 5 2 33 1;
+#X connect 6 0 7 0;
+#X connect 7 0 11 0;
+#X connect 8 0 7 1;
+#X connect 8 0 38 1;
+#X connect 9 0 10 1;
+#X connect 10 0 11 1;
+#X connect 10 0 23 0;
+#X connect 11 0 27 0;
+#X connect 23 0 24 0;
+#X connect 23 1 25 1;
+#X connect 24 0 25 0;
+#X connect 25 0 29 1;
+#X connect 25 0 32 1;
+#X connect 26 0 28 0;
+#X connect 27 0 26 0;
+#X connect 27 1 28 1;
+#X connect 27 1 29 0;
+#X connect 28 0 42 0;
+#X connect 29 0 30 1;
+#X connect 30 0 39 0;
+#X connect 31 0 39 0;
+#X connect 32 0 39 0;
+#X connect 33 0 39 0;
+#X connect 38 0 49 0;
+#X connect 39 0 40 0;
+#X connect 40 0 0 0;
+#X connect 41 0 32 0;
+#X connect 41 1 33 0;
+#X connect 41 2 31 0;
+#X connect 42 0 40 0;
+#X connect 42 1 38 0;
+#X connect 42 2 31 1;
+#X connect 42 3 43 0;
+#X connect 43 0 40 0;
+#X connect 44 0 30 0;
+#X connect 44 1 33 0;
+#X connect 44 2 32 0;
+#X connect 45 0 33 0;
+#X connect 45 1 31 0;
+#X connect 45 2 32 0;
+#X connect 46 0 33 0;
+#X connect 46 1 32 0;
+#X connect 46 2 30 0;
+#X connect 47 0 31 0;
+#X connect 47 1 32 0;
+#X connect 47 2 33 0;
+#X connect 48 0 32 0;
+#X connect 48 1 30 0;
+#X connect 48 2 33 0;
+#X connect 49 0 41 0;
+#X connect 49 1 44 0;
+#X connect 49 2 45 0;
+#X connect 49 3 46 0;
+#X connect 49 4 47 0;
+#X connect 49 5 48 0;
+#X restore -268 186 pd hsv2rgb;
+#X obj -313 74 adc~;
+#X obj -268 167 pack 0 255 255;
+#X connect 0 0 15 0;
+#X connect 1 0 38 0;
+#X connect 2 0 9 0;
+#X connect 3 0 7 0;
+#X connect 4 0 3 0;
+#X connect 5 0 3 0;
+#X connect 6 0 3 0;
+#X connect 7 0 30 0;
+#X connect 8 0 6 0;
+#X connect 8 1 17 0;
+#X connect 8 2 5 0;
+#X connect 9 0 11 0;
+#X connect 10 0 9 1;
+#X connect 10 0 21 0;
+#X connect 11 0 10 0;
+#X connect 12 0 14 1;
+#X connect 13 0 15 1;
+#X connect 14 0 13 0;
+#X connect 15 0 53 1;
+#X connect 15 0 8 0;
+#X connect 16 0 30 0;
+#X connect 17 0 2 0;
+#X connect 18 0 29 1;
+#X connect 19 0 54 0;
+#X connect 20 0 21 1;
+#X connect 21 0 54 0;
+#X connect 21 1 23 0;
+#X connect 22 0 25 0;
+#X connect 23 0 19 0;
+#X connect 24 0 22 0;
+#X connect 24 1 25 1;
+#X connect 25 0 23 1;
+#X connect 26 0 11 1;
+#X connect 27 0 11 1;
+#X connect 28 0 37 1;
+#X connect 29 0 32 0;
+#X connect 31 0 37 0;
+#X connect 32 0 33 0;
+#X connect 33 0 56 0;
+#X connect 33 1 36 0;
+#X connect 34 0 33 1;
+#X connect 35 0 56 0;
+#X connect 36 0 35 0;
+#X connect 37 0 29 0;
+#X connect 38 0 40 0;
+#X connect 39 0 10 1;
+#X connect 39 0 9 1;
+#X connect 39 0 16 0;
+#X connect 39 0 17 1;
+#X connect 39 0 24 0;
+#X connect 40 0 14 0;
+#X connect 40 0 53 2;
+#X connect 40 1 12 0;
+#X connect 41 0 39 0;
+#X connect 42 0 48 0;
+#X connect 42 0 53 0;
+#X connect 42 1 48 1;
+#X connect 42 1 53 0;
+#X connect 43 0 42 0;
+#X connect 44 0 42 0;
+#X connect 45 0 47 0;
+#X connect 46 0 48 0;
+#X connect 46 0 53 0;
+#X connect 46 1 48 1;
+#X connect 46 1 53 0;
+#X connect 47 0 46 0;
+#X connect 54 0 31 0;
+#X connect 55 0 40 0;
+#X connect 56 0 59 0;
+#X connect 57 0 4 0;
+#X connect 58 0 53 0;
+#X connect 59 0 57 0;
+#X coords 0 0 2.71716e-06 4.15856e-06 535 500 0;
diff --git a/extensions/gui/ix/toxy/sp.wid b/extensions/gui/ix/toxy/sp.wid
new file mode 100755
index 00000000..2b41902f
--- /dev/null
+++ b/extensions/gui/ix/toxy/sp.wid
@@ -0,0 +1,36 @@
+#console show
+namespace eval ::ix {
+ variable _
+ proc sp {p t} {
+ variable _
+ image create photo $t
+ $p configure -image $t
+ set _($t:loc) 0
+ }
+ proc spl {t args} {
+ variable _
+ incr _($t:loc)
+ if {$_($t:loc) > 511} {set _($t:loc) 0}
+ set draw {}
+ foreach pixel $args {
+ set pixel [expr int($pixel)]
+ lappend draw [format #%02x%02x%02x $pixel $pixel $pixel]
+ }
+ $t put $draw -to $_($t:loc) 0
+ }
+ proc spd {t args} {
+ variable _
+ incr _($t:loc)
+ if {$_($t:loc) > 511} {set _($t:loc) 0}
+ $t put $args -to $_($t:loc) 0
+ }
+}
+#> sp label
+#. @list ::ix::spl .| .#args
+#. @draw ::ix::spd .| .#args
+#. @clear .- delete 0 end
+#. @img eval ".| .#args"
+#. @cmd eval ".- .#args"
+bind .- <B1-Motion> {.| put #eeeeee -to %x %y}
+::ix::sp .- .|
+puts "setup" \ No newline at end of file
diff --git a/extensions/gui/ix/toxy/spectrum-demo.pd b/extensions/gui/ix/toxy/spectrum-demo.pd
new file mode 100755
index 00000000..98c5a385
--- /dev/null
+++ b/extensions/gui/ix/toxy/spectrum-demo.pd
@@ -0,0 +1,171 @@
+#N canvas 62 98 623 209 10;
+#X obj -28 29 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X obj -115 21 loadbang;
+#X obj -95 69 samplerate~;
+#X obj -115 85 * 1000;
+#X obj -115 69 /;
+#X obj -115 101 metro 46;
+#X obj 86 29 tgl 15 1 \$0loglin empty empty 0 -6 0 8 -99865 -195568
+-1 0 1;
+#X obj 112 30 hsl 128 15 1 100 0 1 \$0gain empty empty -2 -6 0 8 -262144
+-1 -1 3500 1;
+#X obj -28 46 widget spectrum sp1 #ca "#ffff4c" #cb "#0ebcd8" #tb 57
+#w 480 #h 160 -height 269;
+#X obj -115 53 t f b;
+#X text 57 30 log/lin;
+#N canvas 755 38 493 259 1000sp 0;
+#X obj 96 113 inlet;
+#X obj 12 -13 inlet~;
+#X obj 11 68 rfft~;
+#X obj 5 103 *~;
+#X obj 12 135 sqrt~;
+#X obj 32 103 *~;
+#X obj 94 27 loadbang;
+#X obj 94 48 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X obj 105 65 prepend set;
+#X obj 122 47 pack 1 1 1;
+#X obj 166 21 inlet;
+#X obj 95 83 switch~ 512 1 1;
+#X obj 36 9 tabreceive~ \$0w;
+#X obj 338 1 table \$0w;
+#X msg 310 112 0;
+#X obj 267 130 osc~;
+#X obj 267 83 samplerate~;
+#X obj 267 107 / 256;
+#X obj 267 152 *~ -0.5;
+#X obj 267 174 +~ 0.5;
+#X obj 253 41 loadbang;
+#X obj 16 32 *~;
+#X obj 252 203 tabwrite~ \$0w;
+#X obj 338 25 pack f \$0;
+#X msg 338 43 \; \$2w resize \$1;
+#X obj 193 45 t b f;
+#X msg 253 63 bang;
+#X obj 338 101 pack f \$0;
+#X obj 338 83 / 2;
+#X obj 51 -14 inlet~;
+#X obj 53 68 rfft~;
+#X obj 47 103 *~;
+#X obj 54 135 sqrt~;
+#X obj 74 103 *~;
+#X obj 58 32 *~;
+#X obj 94 166 tabwrite~ \$0sp1;
+#X obj 11 166 tabwrite~ \$0sp0;
+#X msg 338 119 \; \$2sp0 resize \$1 \; \$2sp1 resize \$1;
+#X obj 247 1 table \$0sp0 512;
+#X obj 247 17 table \$0sp1 512;
+#X connect 0 0 36 0;
+#X connect 0 0 35 0;
+#X connect 1 0 21 0;
+#X connect 2 0 3 1;
+#X connect 2 0 3 0;
+#X connect 2 1 5 1;
+#X connect 2 1 5 0;
+#X connect 3 0 4 0;
+#X connect 4 0 36 0;
+#X connect 5 0 4 0;
+#X connect 6 0 7 0;
+#X connect 7 0 11 0;
+#X connect 8 0 11 0;
+#X connect 9 0 8 0;
+#X connect 10 0 9 0;
+#X connect 10 0 25 0;
+#X connect 12 0 21 1;
+#X connect 12 0 34 1;
+#X connect 14 0 15 1;
+#X connect 15 0 18 0;
+#X connect 16 0 17 0;
+#X connect 17 0 15 0;
+#X connect 18 0 19 0;
+#X connect 19 0 22 0;
+#X connect 20 0 26 0;
+#X connect 21 0 2 0;
+#X connect 23 0 24 0;
+#X connect 25 0 26 0;
+#X connect 25 1 17 1;
+#X connect 25 1 23 0;
+#X connect 25 1 28 0;
+#X connect 26 0 14 0;
+#X connect 26 0 16 0;
+#X connect 26 0 22 0;
+#X connect 27 0 37 0;
+#X connect 28 0 27 0;
+#X connect 29 0 34 0;
+#X connect 30 0 31 1;
+#X connect 30 0 31 0;
+#X connect 30 1 33 1;
+#X connect 30 1 33 0;
+#X connect 31 0 32 0;
+#X connect 32 0 35 0;
+#X connect 33 0 32 0;
+#X connect 34 0 30 0;
+#X restore -144 155 pd \$0sp;
+#X msg -115 37 2048;
+#X text -10 31 power;
+#X obj -145 76 adc~;
+#X msg 289 30 #ca \$1;
+#X obj 358 30 tot .;
+#X msg 353 15 query tk_chooseColor;
+#X obj 387 31 makefilename "%s";
+#X obj 289 14 demux;
+#X obj 338 15 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X msg 323 30 #cb \$1;
+#X floatatom 258 17 5 33 100 0 - - -;
+#X msg 249 30 #tb \$1;
+#X floatatom 7 1 5 30 500 0 - - -;
+#X floatatom -20 1 5 64 640 0 - - -;
+#X msg 94 15 #w \$1;
+#X obj 22 14 spr \$0 \$0sp1 2;
+#X msg 125 15 #h \$1;
+#X obj -50 14 spr \$0 \$0sp0 1;
+#X msg -115 5 480;
+#X msg -92 5 160;
+#X obj -132 132 biquad~;
+#X obj -103 135 notch 4000 42;
+#X obj -139 118 hsl 106 15 0 10000 0 0 empty empty empty -2 -6 0 8
+-262144 -1 -1 8600 1;
+#X connect 0 0 5 0;
+#X connect 1 0 12 0;
+#X connect 1 0 30 0;
+#X connect 1 0 31 0;
+#X connect 2 0 4 1;
+#X connect 3 0 5 1;
+#X connect 4 0 3 0;
+#X connect 5 0 11 2;
+#X connect 5 0 27 0;
+#X connect 5 0 29 0;
+#X connect 9 0 4 0;
+#X connect 9 0 11 3;
+#X connect 9 1 2 0;
+#X connect 12 0 9 0;
+#X connect 14 0 11 0;
+#X connect 14 1 32 0;
+#X connect 15 0 8 0;
+#X connect 16 0 18 0;
+#X connect 17 0 16 0;
+#X connect 18 0 19 0;
+#X connect 19 0 15 0;
+#X connect 19 1 21 0;
+#X connect 20 0 19 1;
+#X connect 21 0 8 0;
+#X connect 22 0 23 0;
+#X connect 23 0 8 0;
+#X connect 24 0 28 0;
+#X connect 24 0 29 2;
+#X connect 24 0 27 2;
+#X connect 25 0 26 0;
+#X connect 25 0 27 1;
+#X connect 25 0 29 1;
+#X connect 26 0 8 0;
+#X connect 27 0 8 0;
+#X connect 28 0 8 0;
+#X connect 29 0 8 0;
+#X connect 30 0 25 0;
+#X connect 31 0 24 0;
+#X connect 32 0 11 1;
+#X connect 33 0 32 0;
+#X connect 34 0 33 0;
+#X coords 0 0 2.71716e-06 4.15856e-06 535 500 0;
diff --git a/extensions/gui/ix/toxy/spectrum.wid b/extensions/gui/ix/toxy/spectrum.wid
new file mode 100755
index 00000000..e42af026
--- /dev/null
+++ b/extensions/gui/ix/toxy/spectrum.wid
@@ -0,0 +1,42 @@
+#console show
+package require Tkzinc 3.3
+package require zincGraphics
+namespace eval ::ix {
+ variable _
+ proc spectrum_sub {t sub} {
+ variable _
+ set _($t:use) $sub
+ }
+ proc spectrum_floats {path t w h args} {
+ variable _
+ set coords "0 $h"
+ set i 0
+ foreach num $args {
+ incr i
+ lappend coords $i $num
+ }
+ lappend coords $w $h
+ $path coords $t:sub$_($t:use) $coords
+
+ }
+ proc spectrum {path t w h bg c1 c2 t1 t2} {
+ if {[winfo exists $path.nob] != 1} {
+ zinc $path.nob -render 1 -width $w -height $h -borderwidth 1 -lightangle 140 -backcolor $bg
+ $path configure -width $w -height $h
+ place $path.nob -anchor nw -relwidth 1 -relheight 1
+ $path.nob remove *
+ $path.nob add curve 1 {1 1 8 4} -filled 1 -linewidth 0 -fillcolor "$c1;$t1" -closed 1 -tags $t:sub1
+ $path.nob add curve 1 {1 1 8 4} -filled 1 -linewidth 0 -fillcolor "$c2;$t2" -closed 1 -tags $t:sub2
+ }
+ }
+}
+#> spectrum frame
+#. -height 160 -width 480 -bd 1 -bg "#cccccc"
+#. #h 160 #w 480 #bg gray20 #ca yellow #cb red #ta 100 #tb 50
+#. @list ::ix::spectrum_floats .-.nob .| .#w .#h .#args
+#. @use ::ix::spectrum_sub .| .#1
+#. @cmd eval ".-.nob .#args"
+bind .- <Enter> {focus .-}
+bind .- <Leave> {focus .^.c}
+::ix::spectrum .- .| .#w .#h .#bg .#ca .#cb .#ta .#tb
+puts "spectrum .- .|"
diff --git a/extensions/gui/ix/toxy/tile-demo.pd b/extensions/gui/ix/toxy/tile-demo.pd
new file mode 100755
index 00000000..4e7c845b
--- /dev/null
+++ b/extensions/gui/ix/toxy/tile-demo.pd
@@ -0,0 +1,74 @@
+#N canvas 265 374 607 366 12;
+#X obj 135 73 widget tile t1 #e non -colwidth -13 -rows 12 -cols 16
+-width 16 -height 12 -rowheight -13 -bd 1 -bg red;
+#X msg 80 87 redefine;
+#X msg 198 53 clr;
+#X msg 100 54 #e \$1;
+#X obj 137 46 widget dm #items #items .(rows columns non.) #arrows
+0 -bg pink;
+#X floatatom 428 3 2 0 64 0 - - -;
+#X floatatom 271 14 5 0 0 0 - - -;
+#X floatatom 271 -2 5 0 0 0 - - -;
+#X obj 459 9 * -1;
+#X msg 419 27 -colwidth \$1 \, -rowheight \$1;
+#X msg 271 30 -cols \$1 \, -width \$1 \, clr;
+#X msg 270 49 -rows \$1 \, -height \$1 \, clr;
+#X obj 199 -10 bng 55 250 50 0 empty empty empty 0 -6 0 8 -241291 -1
+-1;
+#X obj 441 277 osc~ 440;
+#X obj 462 165 mtof;
+#X obj 499 297 line~;
+#X obj 465 325 dac~ 1 2;
+#X obj 466 302 *~;
+#X obj 462 106 - 12;
+#X obj 462 125 abs;
+#X obj 422 78 unpack f f f;
+#X obj 436 188 pack 0 0 0;
+#X obj 440 254 pipe 0 0 1000;
+#X obj 422 100 * 100;
+#X msg 438 210 \$2 \$3 \$1;
+#X obj 438 231 unpack f f f;
+#X obj 462 144 + 48;
+#X obj 495 154 * 0.25;
+#X msg 538 277 0 2;
+#X obj 540 258 del 98;
+#X msg 503 276 \$1 2;
+#X obj 540 236 t b;
+#X connect 0 0 20 0;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 3 0 0 0;
+#X connect 4 0 3 0;
+#X connect 5 0 8 0;
+#X connect 6 0 10 0;
+#X connect 7 0 11 0;
+#X connect 8 0 9 0;
+#X connect 9 0 0 0;
+#X connect 10 0 0 0;
+#X connect 11 0 0 0;
+#X connect 12 0 0 0;
+#X connect 13 0 17 0;
+#X connect 14 0 21 1;
+#X connect 15 0 17 1;
+#X connect 17 0 16 0;
+#X connect 17 0 16 1;
+#X connect 18 0 19 0;
+#X connect 19 0 26 0;
+#X connect 20 0 23 0;
+#X connect 20 1 18 0;
+#X connect 20 2 27 0;
+#X connect 21 0 24 0;
+#X connect 22 0 13 0;
+#X connect 22 1 31 0;
+#X connect 22 1 30 0;
+#X connect 23 0 21 0;
+#X connect 24 0 25 0;
+#X connect 25 0 22 0;
+#X connect 25 1 22 1;
+#X connect 25 2 22 2;
+#X connect 26 0 14 0;
+#X connect 27 0 21 2;
+#X connect 28 0 15 0;
+#X connect 29 0 28 0;
+#X connect 30 0 15 0;
+#X connect 31 0 29 0;
diff --git a/extensions/gui/ix/toxy/tile.wid b/extensions/gui/ix/toxy/tile.wid
new file mode 100755
index 00000000..5bf3cecd
--- /dev/null
+++ b/extensions/gui/ix/toxy/tile.wid
@@ -0,0 +1,87 @@
+#console show
+package require Tktable
+namespace eval ::ix {
+ variable _
+ proc tile {t tg bg fg ac sb sf e} {
+ variable _
+ $t tag configure active -bg $ac
+ $t tag configure OFF -bg $bg -relief ridge
+ $t tag configure ON -bg $fg -relief sunken
+ $t tag configure sel -bg $sb -fg $sf -relief flat
+ if {$e eq "columns"} {
+ bind $t <Motion> {
+ %W selection clear all
+ set sel [%W index @%x,%y row]
+ %W selection set $sel,0 $sel,[%W cget -cols]
+ }
+ } elseif {$e eq "rows"} {
+ bind $t <Motion> {
+ %W selection clear all
+ set sel [%W index @%x,%y col]
+ %W selection set 0,$sel [%W cget -rows],$sel
+ }
+ } else {
+ bind $t <Motion> {
+ %W selection clear all
+ %W selection set @%x,%y
+ }
+ }
+ set _($t:e) $e
+ bind $t <Leave> {%W selection clear all}
+ bind $t <2> {%W configure -state [if {[%W cget -state] eq "normal"} {list disabled} {list normal}]}
+ bind $t <3> {::ix::tile_clk %W %x %y OFF}
+ bind $t <1> {::ix::tile_clk %W %x %y ON}
+ bind $t <B3-Motion> [bind $t <3>]
+ bind $t <B1-Motion> [bind $t <1>]
+
+ tile_clr $t
+ }
+ proc tile_dump {t id} {
+ puts "$t $id"
+ for {set c 0} {$c < [$t cget -cols]} {incr c} {
+ for {set r 0} {$r < [$t cget -rows]} {incr r} {
+ if {[$t tag includes ON $r,$c] == 1} {
+ pd [concat $id.rp _cb $c $r 1\;]
+ }
+ }
+ }
+ }
+ proc tile_clk {t x y v} {
+ variable _
+ if {[$t cget -state] eq "disabled"} {
+ switch $_($t:e) {
+ rows {
+ for {set row 0} {$row < [$t cget -rows]} {incr row} {
+ $t tag celltag OFF $row,[$t index @$x,$y col]
+ }
+ }
+ columns {
+ for {set col 0} {$col < [$t cget -cols]} {incr col} {
+ $t tag celltag OFF [$t index @$x,$y row],$col
+ }
+ }
+ }
+ $t tag celltag $v [$t index @$x,$y]
+ }
+ }
+ proc tile_clr {t} {
+ for {set i 0} {$i < [$t cget -rows]} {incr i} {
+ for {set j 0} {$j < [$t cget -cols]} {incr j} {
+ $t tag celltag OFF $i,$j
+ }
+ }
+ }
+
+}
+#> tile table
+#. -rows 8 -cols 16 -resizeborders none -fg blue
+#. -borderwidth 2 -titlerows 0 -titlecols 0 -roworigin 0 -colorigin 0 -colwidth 4
+#. -width 16 -height 8 -variable tab -flashmode off -font {Tahoma 8}
+#. #bg "#a4e75a" #fg "#fefdff" #cb yellow #ac yellow #sb "#aaff88" #sf green
+#. #e none
+#. @bang ::ix::tile_dump .- .|
+#. @clear ::ix::tile_clr .-
+#. @clr ::ix::tile_clr .-
+
+::ix::tile .- .| .#bg .#fg .#ac .#sb .#sf .#e
+puts "tile .- .|"
diff --git a/extensions/gui/ix/toxy/tree-demo.pd b/extensions/gui/ix/toxy/tree-demo.pd
new file mode 100755
index 00000000..cdfa6fec
--- /dev/null
+++ b/extensions/gui/ix/toxy/tree-demo.pd
@@ -0,0 +1,184 @@
+#N canvas 402 155 495 621 10;
+#X obj 36 131 widget tree t1 -height 300 -selectmode single -width
+205 -bd 2 -border 1 -font .(verdana 8.) -bg yellow -fg blue;
+#X obj 215 16 tow . tree t1;
+#X msg 13 8 0 juice;
+#X msg 21 24 1 coffee;
+#X msg 32 41 2 apples;
+#X msg 43 58 3 plantains;
+#X msg 27 74 2 arugula;
+#X msg 22 90 1 byte;
+#X obj 251 117 bng 15 250 50 0 empty empty empty 0 -6 0 8 -260818 -1
+-1;
+#X msg 107 101 clear;
+#X msg 178 113 path \$1;
+#X msg 178 93 auto \$1;
+#X obj 224 78 tgl 15 0 empty empty empty 0 -6 0 8 -225271 -1 -1 0 1
+;
+#X obj 225 98 tgl 15 0 empty empty empty 0 -6 0 8 -225280 -1 -1 0 1
+;
+#X obj 266 168 widget dd dt -bg gray -fg pink;
+#X obj 11 113 prepend add;
+#X msg 171 0 cmd collapse -recurse all \, cmd expand 0;
+#X msg 255 -16 cmd expand all;
+#X obj 17 -10 t b b b b b;
+#X msg 80 -23 16;
+#X obj 81 -8 until;
+#X obj 78 9 random 6;
+#X obj 73 24 route 0 1 2 3 4 5;
+#X obj 24 -47 bng 31 250 50 0 empty empty empty 0 -6 0 8 -193787 -1
+-1;
+#X obj 56 -48 bng 27 250 50 0 empty empty empty 0 -6 0 8 -258699 -1
+-1;
+#X obj 146 453 s2l /;
+#X msg 240 453 resynth \; supatrigga \;;
+#X msg 215 473 set;
+#X msg 201 453 add \$1;
+#X obj 176 453 drip;
+#X symbolatom 40 492 39 0 0 0 - - -;
+#X obj 96 453 l2s;
+#X obj 116 453 t s b;
+#N canvas 17 433 316 238 pooledit 1;
+#X obj 18 50 prepend mkchdir;
+#X obj 18 9 inlet;
+#X obj 28 66 prepend rmdir;
+#X obj 168 173 outlet;
+#X obj 89 103 l2s;
+#X obj 48 82 niagara 1;
+#X obj 61 139 glue;
+#X obj 89 123 s2l /;
+#X obj 48 101 a2l;
+#X obj 61 158 route list;
+#X obj 61 174 pool tt;
+#X obj 197 66 prepend chdir;
+#X obj 18 26 route new delete cut copy paste;
+#X msg 169 66 paste;
+#X msg 132 66 copyall;
+#X msg 100 66 cutall;
+#X obj 100 50 t a a;
+#X obj 132 50 t a a;
+#X obj 169 50 t a a;
+#X connect 0 0 5 0;
+#X connect 1 0 12 0;
+#X connect 2 0 5 0;
+#X connect 4 0 7 0;
+#X connect 5 0 8 0;
+#X connect 5 1 4 0;
+#X connect 6 0 9 0;
+#X connect 7 0 6 1;
+#X connect 8 0 6 0;
+#X connect 9 0 10 0;
+#X connect 11 0 5 0;
+#X connect 12 0 0 0;
+#X connect 12 1 2 0;
+#X connect 12 2 16 0;
+#X connect 12 3 17 0;
+#X connect 12 4 18 0;
+#X connect 12 5 3 0;
+#X connect 13 0 10 0;
+#X connect 14 0 10 0;
+#X connect 15 0 10 0;
+#X connect 16 0 15 0;
+#X connect 16 1 11 0;
+#X connect 17 0 14 0;
+#X connect 17 1 11 0;
+#X connect 18 0 13 0;
+#X connect 18 1 11 0;
+#X restore 37 437 pd pooledit;
+#N canvas 185 447 106 167 poolview 1;
+#X obj 3 84 packel -1;
+#X msg 4 23 chdir \, getsub -1;
+#X obj 53 84 length;
+#X obj 11 63 t a a;
+#X obj 3 137 outlet;
+#X obj 4 3 inlet;
+#X obj 62 2 inlet;
+#X obj 4 44 pool tt;
+#X obj 3 119 prepend;
+#X obj 53 102 - 1;
+#X connect 0 0 8 0;
+#X connect 1 0 7 0;
+#X connect 2 0 9 0;
+#X connect 3 0 0 0;
+#X connect 3 1 2 0;
+#X connect 5 0 1 0;
+#X connect 6 0 7 0;
+#X connect 7 1 3 0;
+#X connect 8 0 4 0;
+#X connect 9 0 8 1;
+#X restore 267 116 pd poolview;
+#X text 266 154 drag an item here;
+#X obj 158 -33 tot .;
+#X msg 136 -50 tot console show;
+#X obj 267 79 widget dd dfd -width 19;
+#X msg 282 -43 -bg yellow -fg blue;
+#X msg 317 101 reset \, load \$1;
+#X msg 118 64 0 jip jop;
+#X obj 348 281 pool tt;
+#X obj 272 225 prepend chdir;
+#X msg 348 260 getall;
+#X obj 272 244 t b b a;
+#X msg 317 278 set;
+#X msg 253 333 ins 2 \; name supatrigga \; synth 0 \; vendor Bram @
+Smartelectronix \; version 1 \; dll c:/local/wbin/vst/resynth/supatrigga.dll
+\; editor 0 \; outs 2 \;;
+#X obj 306 317 prepend add2;
+#X obj 368 317 prepend add;
+#X connect 0 0 33 0;
+#X connect 2 0 15 0;
+#X connect 3 0 15 0;
+#X connect 4 0 15 0;
+#X connect 5 0 15 0;
+#X connect 6 0 15 0;
+#X connect 7 0 15 0;
+#X connect 8 0 34 0;
+#X connect 9 0 0 0;
+#X connect 10 0 0 0;
+#X connect 11 0 0 0;
+#X connect 12 0 11 0;
+#X connect 13 0 10 0;
+#X connect 15 0 0 0;
+#X connect 16 0 1 0;
+#X connect 17 0 1 0;
+#X connect 18 0 19 0;
+#X connect 18 1 5 0;
+#X connect 18 2 4 0;
+#X connect 18 3 3 0;
+#X connect 18 4 2 0;
+#X connect 19 0 20 0;
+#X connect 20 0 21 0;
+#X connect 21 0 22 0;
+#X connect 22 0 2 0;
+#X connect 22 1 3 0;
+#X connect 22 2 4 0;
+#X connect 22 3 5 0;
+#X connect 22 4 6 0;
+#X connect 22 5 7 0;
+#X connect 23 0 18 0;
+#X connect 24 0 9 0;
+#X connect 25 0 29 0;
+#X connect 25 0 43 0;
+#X connect 27 0 26 0;
+#X connect 28 0 26 0;
+#X connect 29 0 28 0;
+#X connect 31 0 32 0;
+#X connect 32 0 25 0;
+#X connect 32 0 30 0;
+#X connect 32 1 27 0;
+#X connect 33 0 31 0;
+#X connect 34 0 15 0;
+#X connect 37 0 36 0;
+#X connect 38 0 40 0;
+#X connect 39 0 1 0;
+#X connect 40 0 34 1;
+#X connect 41 0 15 0;
+#X connect 42 0 49 0;
+#X connect 42 1 48 0;
+#X connect 43 0 45 0;
+#X connect 44 0 42 0;
+#X connect 45 0 44 0;
+#X connect 45 1 46 0;
+#X connect 45 2 42 0;
+#X connect 46 0 47 0;
+#X connect 48 0 47 0;
+#X connect 49 0 47 0;
diff --git a/extensions/gui/ix/toxy/tree.wid b/extensions/gui/ix/toxy/tree.wid
new file mode 100755
index 00000000..809b2670
--- /dev/null
+++ b/extensions/gui/ix/toxy/tree.wid
@@ -0,0 +1,184 @@
+package require treectrl
+package require tkdnd
+namespace eval ::ix {
+ variable _
+ proc tree {t target title auto echo path delim} {
+ variable _
+ puts "$t $target $title $echo $path $delim"
+ if {[$t element names] != "el1"} {
+ $t column create -text $title
+ $t element create el1 text -fill [list green {selected focus}]
+ $t style create s1
+ $t style elements s1 el1
+ }
+ bind $t <Button1-Leave> {dnd drag %W}
+ bind $t <ButtonPress-1> {
+ set id [lindex [%W identify %x %y] 1]
+ if {$id ne "" && $id ne "tail"} {
+ %W activate $id
+ ::ix::tree_click %W [winfo name %W]
+ }
+ }
+
+ dnd bindsource $t text/plain "return \[::ix::tree_get $t $target -1 -1\]"
+ bind $t <Tab> "::ix::tree_out $t $target -1"
+ bind $t <KeyPress-Right> "::ix::tree_out $t $target -1"
+ bind $t <Double-1> "::ix::tree_out $t $target -1"
+ bind $t <ButtonPress-3> {}
+ bind $t <ButtonPress-3> {
+ variable _
+ focus %W
+ set target [winfo name %W]
+ set id [lindex [%W identify %x %y] 1]
+ if {$id ne ""} {
+ %W activate $id
+ %W selection clear all
+ %W selection add $id
+ set path [::ix::tree_get %W $target 1 -1]
+ if {[winfo exists %W.rc] != 1} {
+ set m [menu %W.rc -tearoff no]
+ $m add command -label "path [::ix::tree_get %W $target -1 $id]" -state disabled
+ $m add command -label delete -command {
+ ::ix::tree_msg $target "delete [pdtk_enquote $path]"
+ set p [%W item parent $id]
+ %W item delete $id
+ if {[%W item numchildren $p] < 1} {
+ %W item configure $p -button no
+ }
+ }
+ $m add command -label new -command {
+ ::ix::tree_nameitem %W $target $path $id
+ }
+ $m add command -label copy -command {::ix::tree_msg $target "copy [pdtk_enquote $path]"}
+ $m add command -label cut -command {::ix::tree_msg $target "cut [pdtk_enquote $path]"}
+ $m add command -label paste -command {::ix::tree_msg $target "paste [pdtk_enquote $path]"}
+ } else {
+ %W.rc entryconfigure 0 -label "path [::ix::tree_get %W $target -1 $id]"
+ }
+ tk_popup %W.rc %X %Y
+ } else {
+ if {[winfo exists %W.rroot] != 1} {
+ set m [menu %W.rroot -tearoff no]
+ $m add command -label "new root" -command {
+ ::ix::tree_nameitem %W $target "" 0
+ }
+ }
+ tk_popup %W.rroot %X %Y
+ }
+ }
+ set _($target:parentList) [list root {} {} {} {} {} {}]
+ set _($target:auto) $auto
+ set _($target:echo) $echo
+ set _($target:path) $path
+ set _($target:delim) $delim
+ }
+ proc tree_nameitem {t target path id} {
+ set path "$path/"
+ destroy .$path
+ toplevel .$path
+ entry .$path.entry -textvariable send_textvariable
+ .$path.entry delete 0 end
+ .$path.entry insert 0 [::ix::random_txt 6]
+ .$path.entry select from 0
+ .$path.entry select adjust end
+# if {$path == "/"} {set pathname ""} else {set pathname path}
+ set submit "::ix::tree_msg $target \"new \[pdtk_enquote \"$path\$send_textvariable\"\]\";::ix::tree_item $t $id \$send_textvariable;destroy .$path"
+ bind .$path.entry <KeyPress-Return> $submit
+ button .$path.ok -text "OK" -command $submit
+ button .$path.cancel -text cancel -command "destroy .$path"
+ pdtk_standardkeybindings .$path.entry
+ grid .$path.entry -sticky news -columnspan 2
+ grid .$path.ok .$path.cancel -sticky news
+ grid columnconfigure .$path 1 -weight 1
+ focus .$path.entry
+ }
+ proc random_txt {n} {
+ set i 0
+ set text ""
+ while {$i < $n} {
+ set int [expr "int(floor(rand()*62))"]
+ if {$int < 10} {incr int 48} elseif {$int < 36} {incr int 55} else {incr int 61}
+ set text "$text[format %c $int]"
+ incr i
+ }
+ return $text
+ }
+ proc tree_item {t p text} {
+ set ti [$t item create]
+ $t item style set $ti 0 s1
+ $t item text $ti 0 $text
+ $t item lastchild $p $ti
+ $t item configure $p -button yes
+ return $ti
+ }
+ proc tree_add {t target args} {
+ variable _
+ set depth [lindex $args 0]
+ set text [lrange $args 1 end]
+ set p [lindex $_($target:parentList) $depth]
+ set ti [tree_item $t $p $text]
+ incr depth
+ set _($target:parentList) [lreplace $_($target:parentList) $depth $depth $ti]
+# if {$_($target:auto) == 1} {
+# tree_msg $target "new [tree_get $t $target -1 $ti]"
+# }
+ }
+ proc tree_click {t target} {
+ variable _
+ if {$_($target:auto) == 1} {tree_out $t $target -1}
+ }
+ proc tree_cmd {t target args} {
+ variable _
+ puts "$t $args"
+ set r [eval "$t $args"]
+ if {$_($target:echo) == 1} {pd "$target.rp _cb $r;"}
+ }
+ proc tree_out {t target rec} {
+ tree_msg $target [tree_get $t $target $rec -1]
+ }
+ proc tree_msg {target msg} {
+ pd "$target.rp _cb $msg;"
+ }
+ proc tree_get {t target rec it} {
+ variable _
+ if {$it < 0} {set it [$t index active]}
+ if {$rec < 0} {set rec $_($target:path)}
+ if {$rec > 0} {return [tree_getrec $t $target $it ""]} else {
+ set item [$t item text $it 0]
+ return $item
+ }
+ }
+ proc tree_getrec {t target tr dl} {
+ variable _
+ if {$tr > 0} {
+ lappend dl $tr
+ tree_getrec $t $target [$t item parent $tr] $dl
+ } else {
+ set tr ""
+ for {set i [expr [llength $dl] - 1]} {0 <= $i} {incr i -1} {
+ set tr "$tr$_($target:delim)[$t item text [lindex $dl $i] 0]"
+ }
+ return $tr
+ }
+ }
+ proc tree_cfg {target item arg} {
+ variable _
+ set _($target:$item) $arg
+ }
+
+}
+
+#> tree treectrl
+#. -height 400 -width 200
+#. #title 1 #auto 1 #echo 0 #path 1 #delim "/"
+#. -font {tahoma 8} -showroot yes -showrootbutton no -selectmode single
+#. @list ::ix::tree_list .- .| .#args
+#. @clear .- item delete all
+#. @add ::ix::tree_add .- .| .#args
+#. @cmd ::ix::tree_cmd .- .| .#args
+#. @auto ::ix::tree_cfg .| auto .#1
+#. @echo ::ix::tree_cfg .| echo .#1
+#. @path ::ix::tree_cfg .| path .#1
+#. @delim ::ix::tree_cfg .| delim .#1
+
+::ix::tree .- .| .#title .#auto .#echo .#path .#delim