# http://whats-your.name/pd foreach pkg {Img snack tkdnd tkpath} { if {[catch {package require $pkg}]} {set has_$pkg 0} {set has_$pkg 1}} source pre8.5.tcl namespace eval ::pd { source pd_objects.tk foreach type [dict keys $obj] { if {[dict exists $obj $type methods]} { eval [dict get $obj $type methods]}} 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 hsvToRgb {hue sat value} { set v [format %.0f [expr {255.0*$value}]] if {$sat == 0} {return "$v $v $v"} else { set hue [expr {$hue*6.0}] if {$hue >= 6.0} {set hue 0.0} scan $hue. %d i set f [expr {$hue-$i}] set p [format %.0f [expr {255.0*$value*(1 - $sat)}]] set q [format %.0f [expr {255.0*$value*(1 - ($sat*$f))}]] set t [format %.0f [expr {255.0*$value*(1 - ($sat*(1 - $f)))}]] switch $i { 0 {return "$v $t $p"} 1 {return "$q $v $p"} 2 {return "$p $v $t"} 3 {return "$p $q $v"} 4 {return "$t $p $v"} 5 {return "$v $p $q"} default {error "i value $i is out of range"}}}} 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} option add *borderWidth 0 option add *font {{bitstream vera sans} 10} proc item_new {_ a} { variable "" variable obj foreach local [dict keys $a] {set $local [dict get $a $local]} if {[dict exists $obj $type attributes]} {set da [dict get $obj $type attributes]} {set da {}} if {$id eq "-"} { if {[dict keys $($_)] eq ""} {set id 0} else {set id -1 while true {if {[lsearch [dict keys $($_)] [incr id]] == -1} {break}}}} if {![info exists x]} {set x 13; set y 31} if {[dict exists $da x]} {set sx [dict get $da x]} {set sx 0} if {[dict exists $da y]} {set sy [dict get $da y]} {set sy 0} update $_ $id abs [dict merge [dict merge [dict merge {class item ins 0 outs 0 color {128 128 128}} $da] [dict remove $a id]] [dict create x $x xx [expr $x + $sx] y $y yy [expr $y + $sy]]] 0 item_draw $_ $id return $id} proc item_draw {_ is} { variable "" variable obj if {$is eq "all"} {set is [dict keys $($_)]} foreach id $is { set type [dict get $($_) $id type] if {[dict exists $obj $type init]} { foreach local [dict keys [dict get $($_) $id]] { set $local [dict get $($_) $id $local]} set tags [list $class i$id $id] set rgb $color; set color [color $rgb] eval [dict get $obj $type init] if {$class eq "item" && ($ins > 0 || $outs > 0)} { eval [dict get $obj io init] } } redraw $_ $id } } proc redraw {_ items} { variable "" variable obj switch $items { all {set items [dict keys $($_)]} default {}} foreach id $items { foreach local [dict keys [dict get $($_) $id]] { set $local [dict get $($_) $id $local]} set x [tr $_ x t $x];set y [tr $_ y t $y];set xx [tr $_ x t $xx];set yy [tr $_ y t $yy] if {[expr $x > $xx]} {lassign "$x $xx" xx x} if {[expr $y > $yy]} {lassign "$y $yy" yy y} set sx [expr $xx - $x]; set sy [expr $yy - $y] if {[lsearch [getsel $_] $id] >= 0} {set rgb {233 233 233};set color [set [l $_ canvas sc]];set selected 1} else { set rgb [dict get $($_) $id color];set color [color $rgb];set selected 0} set atags [concat $class i$id $id] set tags [concat $class && i$id && $id] set item [$_ find withtag $tags] if {[dict exists $obj $type tags]} { foreach tag [dict get $obj $type tags] { set $tag [$_ find withtag "$tags && $tag"]}} if {[dict exists $obj $type redraw]} { eval [dict get $obj $type redraw]} if {$class eq "item" && ($ins > 0 || $outs > 0)} { eval [dict get $obj io redraw] foreach i [dict keys $($_)] { if {[dict get $($_) $i class] eq "cable"} { if {[lindex [dict get $($_) $i from] 0] eq $id || [lindex [dict get $($_) $i to] 0] eq $id} { redraw $_ $i } } } } } } proc item_delete {_ {items ""}} { variable "" variable obj if {$items eq ""} {set items [getsel $_]} foreach id $items { foreach i [$_ find withtag i$id] { $_ delete $i } set type [dict get $($_) $id type] if {[dict exists $obj $type destroy]} { eval [dict get $obj $type destroy]} dict unset ($_) $id set sel [lremove [dict get $($_) canvas sel] $id]; up $_ canvas sel send "delete $_:$id" } } proc update {_ item r u redraw} { variable "" foreach a [dict keys $u] { switch $r { abs {dict set ($_) $item $a [dict get $u $a]} rel {dict set ($_) $item $a [expr {[dict get $($_) $item $a] + [dict get $u $a]}]} } # send [concat update $_:$item $a [dict get $($_) $item $a]] } send [concat update $_:$item $u] if {$redraw == 1} {redraw $_ $item} } proc up {_ id args} { variable "" foreach arg $args { upvar $arg var dict set ($_) $id $arg $var send [concat update $_:$id $arg $var] } } proc item_mua {_ r u redraw {items -}} { variable "" if {$items eq "-"} {set items [getsel $_]} foreach item $items {update $_ $item $r $u $redraw} } proc l {_ id args} { variable "" foreach arg $args { upvar $arg var set var [dict get $($_) $id $arg] } return $args } proc msg {} { if {![winfo exists .msg]} { toplevel .msg grid [entry .msg.text] bind .msg.text {::pd::send [.msg.text get]}}} proc inspector {_} { variable "" set p .ic if {![winfo exists $p]} { toplevel $p if {[info exists ($_:inspect)]} {unset ($_:inspect)}}} proc inspect {_ id} { set p .ic if {![winfo exists $p]} {return} variable "" if {![dict exists $($_) $id]} {return} set keys [dict keys [dict get $($_) $id]] if {![info exists ($_:inspect)] || ($($_:inspect:type) ne [dict get $($_) $id type])} { foreach c [winfo children $p] {destroy $c} set n 0 foreach k [concat id $keys] { entry $p.$k -width 8 -bd 0 -font {{Bitstream Vera Sans} 11} $p.$k insert 0 $k $p.$k configure -state disabled entry $p.${k}v -width 16 -bd 0 -bg gray94 -font {{Bitstream Vera Sans} 10} if {$n == 0} {set cmd "::pd::inspect $_ \[$p.${k}v get\]";set cmdT $cmd} { set cmd "::pd::item_mua $_ abs \[dict create $k \[$p.${k}v get\] \] 1 \[$p.idv get\]" set cmdT "::pd::item_mua $_ abs \[dict create $k \[$p.${k}v get\] \] 1"} bind $p.${k}v $cmd bind $p.${k}v $cmdT grid $p.$k $p.${k}v -sticky nsew grid columnconfigure $p 1 -weight 3 grid columnconfigure $p 0 -weight 1 grid rowconfigure $p $n -weight 1 incr n } set ($_:inspect:type) [dict get $($_) $id type] } set ($_:inspect) $id $p.idv delete 0 end $p.idv insert 0 $id foreach k $keys { $p.${k}v delete 0 end $p.${k}v insert 0 [dict get $($_) $id $k]}} proc rmenu {_ x y X Y} { variable "" variable obj destroy $_.rmenu if {[winfo exists $_.rmenu] != 1} { set m [menu $_.rmenu -tearoff yes] $m add cascade -label "edit" -menu [set me [menu $m.edit -tearoff no]] foreach a {copy cut paste selecta} { $me add command -label $a -command "::pd::clip $_ $a"} $m add cascade -label "object" -menu [set mo [menu $m.object -tearoff no]] foreach type [dict keys $obj] { $mo add command -label $type -command "::pd::item_new $_ \{id - type $type x [tr $_ x i $x] y [tr $_ y i $y]\}"} $m add cascade -label "view" -menu [set mv [menu $m.view -tearoff no]] $mv add command -label "zoom to fit" -command "::pd::viewpoint $_ {action fit}" $mv add command -label "flip x" -command "::pd::viewpoint $_ {action mirror_x}" $mv add command -label "flip y" -command "::pd::viewpoint $_ {action mirror_y}" $mv add command -label "reset" -command "::pd::viewpoint $_ {action reset}" $m add command -label reload -command {source pd_base.tk} $m add command -label "console" -command {source /usr/local/bin/tkcon.tcl; tkcon show} $m add command -label "inspector" -command "::pd::inspector $_" $m add command -label "msg" -command "::pd::msg" } else { # $_.rmenu entryconfigure 0 -label $x } tk_popup $_.rmenu $X $Y } proc tr {_ d inv v} { variable "" array set dm {x width y height} l $_ canvas xa xb ya yb switch $inv { t {return [expr ($v - $${d}a) / ($${d}b - $${d}a + 0.0) * [winfo $dm($d) $_]]} i {return [expr ($${d}b - $${d}a) * $v /([winfo $dm($d) $_] + 0.0) + $${d}a]} d {return [expr ($${d}b - $${d}a) * $v /([winfo $dm($d) $_] + 0.0)]} id {return [expr $v / ($${d}b - $${d}a + 0.0) * [winfo $dm($d) $_]]}}} proc viewpoint {_ opts} { variable "" l $_ canvas xa xb ya yb xao yao xbo ybo switch [dict get $opts action] { fit { lassign [$_ bbox item] xa ya xb yb foreach z {xa xb ya yb} {set $z [tr $_ [string range $z 0 0] i [set $z]]} } mirror_x { lassign "$xb $xa" xa xb } mirror_y { lassign "$yb $ya" ya yb } reset { lassign "$xao $xbo $yao $ybo" xa xb ya yb } square { } move { foreach xy {x y} { set mvt [tr $_ $xy d [expr {[dict get $opts $xy] - $($_:c$xy)}]] foreach ab {a b} {set ${xy}$ab [expr $${xy}$ab - $mvt]}} } zoom { array set dir {in 0.5 out 1.5} foreach xy [dict get $opts axe] { set radius [expr ($${xy}b - $${xy}a) / 2. * $dir([dict get $opts dir])] set center [tr $_ $xy i [dict get $opts $xy]] set ${xy}a [expr {$center - $radius}] set ${xy}b [expr {$center + $radius}] } } resize { foreach xy {x y} { set mvt [tr $_ $xy d [expr {[dict get $opts $xy] - $($_:c$xy)}]] set ${xy}a [expr $${xy}a - $mvt] set ${xy}b [expr $${xy}b + $mvt]} } scroll { set xy [dict get $opts axis] set mv [expr ($${xy}b - $${xy}a) / 4.0] foreach ab {a b} {set ${xy}$ab [expr [dict get $opts units] > 0 ? $${xy}$ab + $mv : $${xy}$ab - $mv ]} } } up $_ canvas xa xb ya yb redraw $_ all } proc clip {_ action} { variable "" switch $action { selecta { set items {} foreach i [dict keys $($_)] {if {[dict get $($_) $i class] eq "item"} {lappend items $i}} updatesel $_ $items } cut { set ($_:c) [dict create] set i 0 foreach item [getsel $_] { dict set ($_:c) $i [dict get $($_) $item] incr i } item_delete $_ } copy { set ($_:c) [dict create] set i 0 foreach item [getsel $_] { dict set ($_:c) $i [dict get $($_) $item] incr i } } paste { set pasted {} foreach item [dict keys $($_:c)] { item_new $_ [dict merge [dict get $($_:c) $item] {id -}] } } } } proc new {_} { variable "" variable obj if {[info exists ($_)] != 1} {set ($_) {}} if {[winfo exists $_] != 1} { item_new $_ [dict create type canvas id canvas] item_new $_ [dict create type gridlines id grid] } } variable pd_send set pd_send -1 proc connect {} { if {[catch {set pd_send [socket localhost 13665]}]} {set pd_send -1} {puts "connected $pd_send"} catch {set pd_receive [socket -server ::pd::receive_conn 13666]} exec pd -guiport 13666 & } proc receive_conn {s addr port} { fileevent $s readable [list ::pd::receive $s] fconfigure $s -buffering line -blocking 0 puts "connection from $addr" } proc receive {s} { set l [gets $s] if {[eof $s]} { close $s } else { if {[catch {eval $l}]} {puts "error in: $l"} } } proc send {msg} { # puts [concat s: $msg] variable pd_send if {$pd_send ne -1} { puts $pd_send [concat $msg \;] flush $pd_send } } if {![winfo exists .c]} { toplevel .c -width 512 -height 512 new .c.c # connect } }