From 44f29524444a96d9e40a76f48750f17e2fdc2974 Mon Sep 17 00:00:00 2001 From: mescalinum Date: Sun, 2 Oct 2011 16:42:06 +0000 Subject: reorganize tree following template structure svn path=/trunk/externals/loaders/tclpd/; revision=15443 --- examples/bitmap-help.pd | 77 ++++++++ examples/bitmap-madness.pd | 134 ++++++++++++++ examples/bitmap.tcl | 346 +++++++++++++++++++++++++++++++++++ examples/colorpicker.tcl | 281 ++++++++++++++++++++++++++++ examples/dynreceive-help.pd | 22 +++ examples/dynreceive.tcl | 53 ++++++ examples/dynroute-help.pd | 26 +++ examples/dynroute.tcl | 57 ++++++ examples/list_change-help.pd | 21 +++ examples/list_change.tcl | 31 ++++ examples/properties.tcl | 423 +++++++++++++++++++++++++++++++++++++++++++ examples/slider2-help.pd | 51 ++++++ examples/slider2.tcl | 273 ++++++++++++++++++++++++++++ 13 files changed, 1795 insertions(+) create mode 100644 examples/bitmap-help.pd create mode 100644 examples/bitmap-madness.pd create mode 100644 examples/bitmap.tcl create mode 100644 examples/colorpicker.tcl create mode 100644 examples/dynreceive-help.pd create mode 100644 examples/dynreceive.tcl create mode 100644 examples/dynroute-help.pd create mode 100644 examples/dynroute.tcl create mode 100644 examples/list_change-help.pd create mode 100644 examples/list_change.tcl create mode 100644 examples/properties.tcl create mode 100644 examples/slider2-help.pd create mode 100644 examples/slider2.tcl (limited to 'examples') diff --git a/examples/bitmap-help.pd b/examples/bitmap-help.pd new file mode 100644 index 0000000..e12deab --- /dev/null +++ b/examples/bitmap-help.pd @@ -0,0 +1,77 @@ +#N canvas 625 330 742 518 10; +#X obj 63 244 bitmap -cellsize 15 -uwidth 8 -uheight 8; +#bitmap setdata 1 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 1 0 0 0 +0 1 0 1 1 0 0 0 1 0 1 0 1 0 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 1 0 1 0 1 +0 1 1 0 1 0 1 0 1 0; +#X obj 87 410 print out; +#X msg 39 117 getrow \$1; +#X obj 42 245 vradio 15 1 0 8 empty empty empty 0 -8 0 10 -228856 -162280 +-1 0; +#X obj 42 410 s \$0r; +#X obj 39 89 r \$0r; +#X text 36 19 [bitmap] - a two dimensional array of bits (toggles) +; +#X text 38 49 creation arguments -cellsize <#> -uwidth <#> -uheight <#>; +#X msg 111 117 getcol \$1; +#X obj 111 89 r \$0c; +#X obj 63 213 r \$0b; +#X obj 39 157 s \$0b; +#X obj 63 372 hradio 15 1 0 8 empty empty empty 0 -8 0 10 -228856 -162280 +-1 0; +#X obj 157 410 s \$0c; +#X obj 227 157 s \$0b; +#X msg 227 117 getcell 0 1; +#X msg 317 117 getcell 1 1; +#X text 226 88 getcell ; +#X obj 247 243 bitmap -cellsize 4 -uwidth 16 -uheight 16; +#bitmap setdata 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 +1 0 1 1 1 1 0 1 1 1 1 1 0 0 1 0 1 0 1 0 0 1 0 1 0 0 0 1 0 0 1 1 1 0 +1 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 1 1 1 1 0 1 0 0 0 1 0 0 1 1 1 1 0 0 +0 0 0 1 1 1 1 1 0 0 1 0 0 1 0 1 1 1 1 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 +1 0 1 1 1 1 0 0 1 1 1 1 0 1 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 1 1 1 1 0 +1 0 0 1 0 0 1 1 1 1 1 0 0 0 0 0 1 1 1 1 0 0 1 0 0 0 1 0 1 1 1 1 0 0 +0 0 0 0 1 0 0 0 1 0 1 0 0 1 0 1 1 1 0 0 1 0 0 0 1 0 1 0 0 1 0 1 0 1 +0 0 1 1 1 1 1 0 1 1 1 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; +#X msg 447 200 setcell \$1 \$2 \$3; +#N canvas 4 117 450 300 randomdata 0; +#X obj 220 136 random 2; +#X obj 62 89 t b b b; +#X obj 62 35 inlet; +#X obj 62 187 pack f f f; +#X obj 62 222 outlet; +#X obj 62 62 metro 10; +#X obj 62 136 random 4; +#X obj 141 136 random 4; +#X connect 0 0 3 2; +#X connect 1 0 6 0; +#X connect 1 1 7 0; +#X connect 1 2 0 0; +#X connect 2 0 5 0; +#X connect 3 0 4 0; +#X connect 5 0 1 0; +#X connect 6 0 3 0; +#X connect 7 0 3 1; +#X restore 447 175 pd randomdata; +#X obj 447 151 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1 +1; +#X obj 447 331 bitmap -cellsize 16 -uwidth 4 -uheight 4; +#bitmap setdata 1 0 0 0 1 0 0 1 1 0 1 1 1 1 1 0; +#X msg 465 231 setcol 1 0 0 0 0 \, setcol 2 0 0 0 0; +#X msg 481 292 setrow \$1 \$2 \$2 \$3 \$3; +#X msg 481 265 0 1 0 \, 1 1 0 \, 2 0 1 \, 3 0 1; +#X connect 0 0 1 0; +#X connect 2 0 11 0; +#X connect 3 0 4 0; +#X connect 5 0 2 0; +#X connect 8 0 11 0; +#X connect 9 0 8 0; +#X connect 10 0 0 0; +#X connect 12 0 13 0; +#X connect 15 0 14 0; +#X connect 16 0 14 0; +#X connect 19 0 22 0; +#X connect 20 0 19 0; +#X connect 21 0 20 0; +#X connect 23 0 22 0; +#X connect 24 0 22 0; +#X connect 25 0 24 0; diff --git a/examples/bitmap-madness.pd b/examples/bitmap-madness.pd new file mode 100644 index 0000000..49a9dd3 --- /dev/null +++ b/examples/bitmap-madness.pd @@ -0,0 +1,134 @@ +#N canvas 5 140 311 321 10; +#N canvas 322 138 514 645 in 1; +#X obj 20 462 outlet; +#X obj 51 8 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1 +; +#X obj 44 60 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 +-1; +#N canvas 3 94 332 662 for_X_Y 0; +#X obj 61 60 inlet; +#X obj 71 223 until; +#X msg 125 177 0; +#X obj 72 261 f; +#X obj 106 260 + 1; +#X obj 68 141 t b b; +#X obj 78 418 until; +#X msg 132 372 0; +#X obj 79 456 f; +#X obj 113 455 + 1; +#X obj 75 336 t b b; +#X obj 73 297 t b f; +#X obj 82 502 pack f f; +#X msg 77 528 \$2 \$1; +#X obj 74 589 outlet; +#X msg 72 177 32; +#X msg 79 372 32; +#X connect 0 0 5 0; +#X connect 1 0 3 0; +#X connect 2 0 3 1; +#X connect 3 0 4 0; +#X connect 3 0 11 0; +#X connect 4 0 3 1; +#X connect 5 0 15 0; +#X connect 5 1 2 0; +#X connect 6 0 8 0; +#X connect 7 0 8 1; +#X connect 8 0 9 0; +#X connect 8 0 12 0; +#X connect 9 0 8 1; +#X connect 10 0 16 0; +#X connect 10 1 7 0; +#X connect 11 0 10 0; +#X connect 11 1 12 1; +#X connect 12 0 13 0; +#X connect 13 0 14 0; +#X connect 15 0 1 0; +#X connect 16 0 6 0; +#X restore 50 125 pd for_X_Y; +#X obj 78 270 sin; +#X obj 78 227 / 64; +#X obj 51 154 unpack f f; +#X obj 107 190 t f f; +#X obj 21 422 pack f f f; +#X msg 21 442 setcell \$1 \$2 \$3; +#X obj 76 297 + 0.5; +#X obj 151 277 sin; +#X obj 149 255 / 16; +#X obj 79 321 +; +#X obj 49 189 t f f f; +#X obj 79 249 +; +#X obj 228 155 f; +#X obj 263 154 + 0.1; +#X obj 49 94 t b b; +#X obj 78 360 wrap; +#X obj 77 401 i; +#X obj 148 230 expr sqrt(pow(sin($f3)*32-$f1 \, 2)+pow(cos($f3)*34-$f2 +\, 2)); +#X obj 79 380 * 1.8; +#X obj 79 341 * 1.2; +#X obj 151 299 + 0.6; +#X obj 52 35 metro 40; +#X connect 1 0 25 0; +#X connect 2 0 18 0; +#X connect 3 0 6 0; +#X connect 4 0 10 0; +#X connect 5 0 15 0; +#X connect 6 0 14 0; +#X connect 6 1 7 0; +#X connect 7 0 8 1; +#X connect 7 1 21 1; +#X connect 8 0 9 0; +#X connect 9 0 0 0; +#X connect 10 0 13 0; +#X connect 11 0 24 0; +#X connect 12 0 11 0; +#X connect 13 0 23 0; +#X connect 14 0 8 0; +#X connect 14 1 5 0; +#X connect 14 2 21 0; +#X connect 15 0 4 0; +#X connect 16 0 17 0; +#X connect 16 0 21 2; +#X connect 17 0 16 1; +#X connect 18 0 3 0; +#X connect 18 1 16 0; +#X connect 19 0 22 0; +#X connect 20 0 8 2; +#X connect 21 0 12 0; +#X connect 22 0 20 0; +#X connect 23 0 19 0; +#X connect 24 0 13 1; +#X connect 25 0 18 0; +#X restore 17 10 pd in; +#X obj 17 34 bitmap 8 32 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 +1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 +1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 +1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +1 1 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 +0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 +0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 +0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 +0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 +0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 +0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 +0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 1 1 +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 0 +0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 +0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 +0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 +0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1; +#X connect 0 0 1 0; diff --git a/examples/bitmap.tcl b/examples/bitmap.tcl new file mode 100644 index 0000000..1cbc766 --- /dev/null +++ b/examples/bitmap.tcl @@ -0,0 +1,346 @@ +package require Tclpd 0.2.1 +package require TclpdLib 0.17 + +set ::script_path [file dirname [info script]] + +pd::guiproc bitmap_draw_new {self c x y config data} { + set w [dict get $config -uwidth] + set h [dict get $config -uheight] + set sz [dict get $config -cellsize] + set fgcolor [dict get $config -fgcolor] + set bgcolor [dict get $config -bgcolor] + set colors [list $bgcolor $fgcolor] + set z 0 + for {set i 0} {$i < $h} {incr i} { + for {set j 0} {$j < $w} {incr j} { + $c create rectangle \ + [expr {0+$x+$j*$sz}] [expr {0+$y+$i*$sz}] \ + [expr {1+$x+($j+1)*$sz}] [expr {1+$y+($i+1)*$sz}] \ + -outline $fgcolor -fill [lindex $colors [lindex $data $z]] \ + -tags [list $self cell_${j}_${i}_$self] + incr z + } + } + set x2 [expr {$x+$w*$sz+1}] + set y2 [expr {$y+$h*$sz+1}] + $c create rectangle $x $y $x2 $y2 \ + -outline $fgcolor -tags [list $self border$self] +} + +pd::guiclass bitmap { + constructor { + set s [file join $::script_path properties.tcl] + sys_gui "source {$s}\n" + + pd::add_outlet $self float + + # set defaults: + set @config [list] + lappend @config -uwidth 8 + lappend @config -uheight 8 + lappend @config -cellsize 16 + lappend @config -label "" + lappend @config -labelpos "top" + lappend @config -sendsymbol "" + lappend @config -receivesymbol "" + lappend @config -fgcolor "#000000" + lappend @config -bgcolor "#ffffff" + lappend @config -lblcolor "#000000" + set @data { + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + } + # expanded ($n) send/recv symbols: + set @send {} + set @recv {} + + ::$self 0 config {*}$args + + set @rcvLoadData {#bitmap} + pd_bind [tclpd_get_instance_pd $self] [gensym $@rcvLoadData] + } + + destructor { + set pdself [tclpd_get_instance_pd $self] + if {$@rcvLoadData != {}} { + #should not happen! + pd_unbind $pdself [gensym $@rcvLoadData] + } + if {[dict get $@config -receivesymbol] != {}} { + pd_unbind $pdself $@recv + } + } + + 0_config { + if {$args == {}} { + return $@config + } else { + set newconf [list] + set optlist [pd::strip_selectors $args] + set optlist [pd::strip_empty $optlist] + for {set i 0} {$i < [llength $optlist]} {} { + set k [lindex $optlist $i] + if {![dict exists $@config $k]} { + return -code error "unknown option '$k'" + } + incr i + set v [lindex $optlist $i] + if {[lsearch -exact {-uwidth -uheight -cellsize} $k] != -1} { + set v [expr {int($v)}] + } + dict set newconf $k $v + incr i + } + if {[dict get $@config -uwidth] != [dict get $newconf -uwidth] || + [dict get $@config -uheight] != [dict get $newconf -uheight]} { + $self 0 resize {*}[pd::add_selectors [list \ + [dict get $newconf -uwidth] \ + [dict get $newconf -uheight] \ + ]] + } + set ui 0 + foreach opt {label labelpos cellsize fgcolor bgcolor lblcolor} { + set old [dict get $@config -$opt] + if {[dict exists $newconf -$opt]} { + set new [dict get $newconf -$opt] + if {$old != $new} { + dict set @config -$opt $new + set ui 1 + } + } + } + foreach opt {sendsymbol receivesymbol} { + set old [dict get $@config -$opt] + if {[dict exists $newconf -$opt]} { + set new [dict get $newconf -$opt] + if {$old != $new} { + if {$opt == "receivesymbol"} { + set selfpd [tclpd_get_instance_pd $self] + if {$old != {}} { + pd_unbind $selfpd $@recv + } + if {$new != {}} { + set @recv [canvas_realizedollar \ + [tclpd_get_glist $self] [gensym $new]] + pd_bind $selfpd $@recv + } else { + set @recv {} + } + } + dict set @config -$opt $new + } + } + } + if {$ui && [info exists @c]} { + sys_gui [list $@c delete $self]\n + sys_gui [list bitmap_draw_new $self \ + $@c $@x $@y $@config $@data]\n + } + } + } + + 0_resize { + set w [pd::arg 0 int] + set h [pd::arg 1 int] + set oldw [dict get $@config -uwidth] + set oldh [dict get $@config -uheight] + set newd {} + for {set y 0} {$y < $h} {incr y} { + for {set x 0} {$x < $w} {incr x} { + if {$x < $oldw && $y < $oldh} { + lappend newd [lindex $@data [expr {$y*$oldw+$x}]] + } else { + lappend newd 0 + } + } + } + dict set @config -uwidth $w + dict set @config -uheight $h + set @data $newd + } + + 0_getrow { + set r [list] + set n [pd::arg 0 int] + set w [dict get $@config -uwidth] + for {set i [expr {$n*$w}]} {$i < [expr {($n+1)*$w}]} {incr i} { + lappend r [list float [lindex $@data $i]] + } + pd::outlet $self 0 list $r + } + + 0_getcol { + set r [list] + set n [pd::arg 0 int] + set w [dict get $@config -uwidth] + set h [dict get $@config -uheight] + for {set i [expr {$n}]} {$i < [expr {$w*$h}]} {incr i $w} { + lappend r [list float [lindex $@data $i]] + } + pd::outlet $self 0 list $r + } + + 0_getcell { + set r [pd::arg 0 int] + set c [pd::arg 1 int] + set w [dict get $@config -uwidth] + pd::outlet $self 0 float [lindex $@data [expr {$r*$w+$c}]] + } + + 0_setrow { + set row [pd::arg 0 int] + set z 1 + set col 0 + set w [dict get $@config -uwidth] + set fgcolor [dict get $@config -fgcolor] + set bgcolor [dict get $@config -bgcolor] + set colors [list $bgcolor $fgcolor] + for {set idx [expr {$row*$w}]} {$idx < [expr {($row+1)*$w}]} {incr idx} { + set d [expr {0!=[pd::arg $z int]}] + lset @data $idx $d + sys_gui [list $@c itemconfigure cell_${col}_${row}_$self \ + -fill [lindex $colors $d]]\n + incr z + incr col + } + } + + 0_setcol { + set col [pd::arg 0 int] + set z 1 + set row 0 + set w [dict get $@config -uwidth] + set h [dict get $@config -uheight] + set fgcolor [dict get $@config -fgcolor] + set bgcolor [dict get $@config -bgcolor] + set colors [list $bgcolor $fgcolor] + for {set idx [expr {$col}]} {$idx < [expr {$w*$h}]} {incr idx $w} { + set d [expr {0!=[pd::arg $z int]}] + lset @data $idx $d + sys_gui [list $@c itemconfigure cell_${col}_${row}_$self \ + -fill [lindex $colors $d]]\n + incr z + incr row + } + } + + 0_setcell { + set r [pd::arg 0 int] + set c [pd::arg 1 int] + set d [expr {0!=[pd::arg 2 int]}] + set w [dict get $@config -uwidth] + set fgcolor [dict get $@config -fgcolor] + set bgcolor [dict get $@config -bgcolor] + set colors [list $bgcolor $fgcolor] + set idx [expr {$r*$w+$c}] + lset @data $idx $d + sys_gui [list $@c itemconfigure cell_${r}_${c}_$self \ + -fill [lindex $colors $d]]\n + } + + 0_setdata { + set d [pd::strip_selectors $args] + set l [llength $d] + set w [dict get $@config -uwidth] + set h [dict get $@config -uheight] + if {$l != $w*$h} { + return -code error "bad data size" + } + set @data [list] + foreach i $d {lappend @data [expr {int($i)}]} + if {$@rcvLoadData != {}} { + pd_unbind [tclpd_get_instance_pd $self] [gensym $@rcvLoadData] + set @rcvLoadData {} + } + } + + object_save { + return [list #X obj $@x $@y bitmap {*}[pd::add_empty $@config] \; \ + \#bitmap setdata {*}$@data \; ] + } + + object_properties { + set title "\[bitmap\] properties" + set x_xobj_obpd [tclpd_get_object_pd $self] + set x [tclpd_get_instance $self] + set buf [list propertieswindow %s $@config $title]\n + gfxstub_new $x_xobj_obpd $x $buf + } + + widgetbehavior_getrect { + lassign $args x1 y1 + set w [dict get $@config -uwidth] + set h [dict get $@config -uheight] + set sz [dict get $@config -cellsize] + set x2 [expr {1+$x1+$w*$sz}] + set y2 [expr {1+$y1+$h*$sz}] + return [list $x1 $y1 $x2 $y2] + } + + widgetbehavior_displace { + set dx [lindex $args 0] + set dy [lindex $args 1] + if {$dx != 0 || $dy != 0} { + incr @x $dx + incr @y $dy + sys_gui [list $@c move $self $dx $dy]\n + } + return [list $@x $@y] + } + + widgetbehavior_select { + set sel [lindex $args 0] + set fgcolor [dict get $@config -fgcolor] + set bgcolor [dict get $@config -bgcolor] + set selcolor "blue" + set colors [list $selcolor $fgcolor] + sys_gui [list $@c itemconfigure $self \ + -outline [lindex $colors $sel]]\n + } + + widgetbehavior_activate { + } + + widgetbehavior_vis { + set @c [lindex $args 0] + set @x [lindex $args 1] + set @y [lindex $args 2] + set vis [lindex $args 3] + set w [dict get $@config -uwidth] + set h [dict get $@config -uheight] + set sz [dict get $@config -cellsize] + if {$vis} { + sys_gui [list bitmap_draw_new $self $@c $@x $@y $@config $@data]\n + } else { + sys_gui [list $@c delete $self]\n + } + } + + widgetbehavior_click { + set w [dict get $@config -uwidth] + set h [dict get $@config -uheight] + set sz [dict get $@config -cellsize] + set fgcolor [dict get $@config -fgcolor] + set bgcolor [dict get $@config -bgcolor] + set colors [list $bgcolor $fgcolor] + set xpix [expr {[lindex $args 0]-$@x-1}] + set ypix [expr {[lindex $args 1]-$@y-1}] + if {$xpix < 0 || $xpix >= $w*$sz} {return} + if {$ypix < 0 || $ypix >= $h*$sz} {return} + set shift [lindex $args 2] + set alt [lindex $args 3] + set dbl [lindex $args 4] + set doit [lindex $args 5] + if {$doit} { + set j [expr {$xpix/$sz}] + set i [expr {$ypix/$sz}] + set idx [expr {$w*${i}+${j}}] + set d [expr {[lindex $@data $idx]==0}] + lset @data $idx $d + sys_gui [list $@c itemconfigure cell_${j}_${i}_$self \ + -fill [lindex $colors $d]]\n + } + } +} diff --git a/examples/colorpicker.tcl b/examples/colorpicker.tcl new file mode 100644 index 0000000..0c433cb --- /dev/null +++ b/examples/colorpicker.tcl @@ -0,0 +1,281 @@ +if {[info exists ::colorpicker::version]} {return} +namespace eval ::colorpicker { + namespace export colorpicker + # ========================================= + # colorpicker + set version 0.1 + # (C) 2009 - Federico Ferri + # mescalinum (at) gmail (dot) com + # + # Released under GPL-3 license: + # http://www.gnu.org/licenses/gpl-3.0.html + # ========================================= + package provide colorpicker $version + + variable presets { + ffffff dfdfdf bbbbbb ffc7c6 ffe3c6 + feffc6 c6ffc7 c6feff c7c6ff e3c6ff + 9f9f9f 7c7c7c 606060 ff0400 ff8300 + faff00 00ff04 00faff 0400ff 9c00ff + 404040 202020 000000 551312 553512 + 535512 0f4710 0e4345 131255 2f004d + } + + proc colorpicker {w mode args} { + variable {} + set modes {switches hsv} + if {[lsearch -exact $modes $mode] == -1} { + error "bad mode: $mode. must be one of: $modes." + } + set ($w:mode) $mode + set ($w:color) "#000000" + set ($w:command) {} + set ($w:textvar) {} + frame $w + init_$mode $w + rename $w ::colorpicker::_$w + interp alias {} $w {} ::colorpicker::dispatch $w + if {$args != {}} {uplevel 1 ::colorpicker::config $w $args} + return $w + } + + proc dispatch {w cmd args} { + variable {} + switch -glob -- $cmd { + get {set ($w:color)} + set {uplevel 1 [linsert $args 0 ::colorpicker::set_color_ext $w]} + con* {uplevel 1 [linsert $args 0 ::colorpicker::config $w]} + default {uplevel 1 [linsert $args 0 ::colorpicker::_$w $cmd]} + } + } + + proc config {w args} { + variable {} + set options {} + set flag 0 + foreach {key value} $args { + switch -glob -- $key { + -com* { + set ($w:command) $value + set flag 1 + } + -textvar* { + set ($w:textvar) $value + set flag 1 + } + default { lappend options $key $value } + } + } + if {!$flag || $options != ""} { + uplevel 1 [linsert $options 0 ::scrolledframe::_$w config] + } + } + + proc set_color_ext {w c} { + # called by the widget public method + variable {} + set c [string tolower $c] + if {![regexp {^#[0-9a-f]{6,6}$} $c]} { + error "Invalid color: $c. Specify a color in the format #HHHHHH" + } + switch -exact -- $($w:mode) { + switches { + set_color $w $c + } + hsv { + set r [expr 0x[string range $c 1 2]] + set g [expr 0x[string range $c 3 4]] + set b [expr 0x[string range $c 5 6]] + set hsv [rgbToHsv $r $g $b] + hsv_set $w h [lindex $hsv 0] + hsv_set $w s [lindex $hsv 1] + hsv_set $w v [lindex $hsv 2] + set_color $w $c + } + } + } + + proc set_color {w c} { + # called internally in reaction to events + variable {} + set c [string tolower $c] + set ($w:color) $c + if {$($w:command) != {}} { + set cmd $($w:command) + lappend cmd $c + uplevel #0 $cmd + } + if {$($w:textvar) != {}} { + uplevel #0 [list set $($w:textvar) $c] + } + switch -exact -- $($w:mode) { + switches { + variable presets + set q 0 + for {set row 0} {$row < 3} {incr row} { + for {set col 0} {$col < 10} {incr col} { + set b [expr {$c == "#[lindex $presets $q]"}] + ${w}.r${row}c${col} configure \ + -relief [lindex {raised sunken} $b] + incr q + } + } + } + hsv { + } + } + } + + proc mkColor {rgb} { + set r [lindex $rgb 0]; set g [lindex $rgb 1]; set b [lindex $rgb 2] + if {$r < 0} {set r 0} elseif {$r > 255} {set r 255} + if {$g < 0} {set g 0} elseif {$g > 255} {set g 255} + if {$b < 0} {set b 0} elseif {$b > 255} {set b 255} + return #[format "%2.2x%2.2x%2.2x" $r $g $b] + } + + proc rgbToHsv {r g b} { + set sorted [lsort -real [list $r $g $b]] + set temp [lindex $sorted 0] + set v [lindex $sorted 2] + set value $v + set bottom [expr {$v-$temp}] + if {$bottom == 0} { + set hue 0 + set saturation 0 + set value $v + } else { + if {$v == $r} { + set top [expr {$g-$b}] + if {$g >= $b} { + set angle 0 + } else { + set angle 360 + } + } elseif {$v == $g} { + set top [expr {$b-$r}] + set angle 120 + } elseif {$v == $b} { + set top [expr {$r-$g}] + set angle 240 + } + set hue [expr {round(60*(double($top)/$bottom)+$angle)}] + } + if {$v == 0} { + set saturation 0 + } else { + set saturation [expr {round(255-255*(double($temp)/$v))}] + } + return [list $hue $saturation $value] + } + + proc hsvToRgb {h s v} { + set hi [expr {int(double($h)/60)%6}] + set f [expr {double($h)/60-$hi}] + set s [expr {double($s)/255}] + set v [expr {double($v)/255}] + set p [expr {double($v)*(1-$s)}] + set q [expr {double($v)*(1-$f*$s)}] + set t [expr {double($v)*(1-(1-$f)*$s)}] + switch -- $hi { + 0 {set r $v; set g $t; set b $p} + 1 {set r $q; set g $v; set b $p} + 2 {set r $p; set g $v; set b $t} + 3 {set r $p; set g $q; set b $v} + 4 {set r $t; set g $p; set b $v} + 5 {set r $v; set g $p; set b $q} + default {error "[lindex [info level 0] 0]: bad H value"} + } + set r [expr {round($r*255)}] + set g [expr {round($g*255)}] + set b [expr {round($b*255)}] + return [list $r $g $b] + } + + proc init_switches {w} { + variable {} + variable presets + set q 0 + for {set row 0} {$row < 3} {incr row} { + for {set col 0} {$col < 10} {incr col} { + set c "#[lindex $presets $q]" + set b [expr {$($w:color) == $c}] + grid [frame ${w}.r${row}c${col} -width 18 -height 16 \ + -borderwidth 1 -relief [lindex {raised sunken} $b] \ + -background $c -highlightthickness 0] \ + -row $row -column $col + bind ${w}.r${row}c${col} \ + "[namespace current]::set_color $w $c" + incr q + } + } + } + + proc init_hsv {w} { + variable colorhsv + set colorhsv($w:h) 0 + set colorhsv($w:s) 255 + set colorhsv($w:v) 255 + grid [canvas ${w}.hue -width 130 -height 15 -borderwidth 1 \ + -relief sunken -highlightthickness 0] -column 0 -row 0 + grid [canvas ${w}.sat -width 130 -height 14 -borderwidth 1 \ + -relief sunken -highlightthickness 0] -column 0 -row 1 + grid [canvas ${w}.val -width 130 -height 14 -borderwidth 1 \ + -relief sunken -highlightthickness 0] -column 0 -row 2 + grid [canvas ${w}.test -width 46 -height 46 -borderwidth 1 \ + -relief sunken -highlightthickness 0 -background red] \ + -column 1 -row 0 -rowspan 3 + variable mh + variable ms + variable mv + set mh($w) 0; set ms($w) 0; set mv($w) 0; + set sh "[namespace current]::hsv_set $w h \[expr {%x*360.0/130.0}\]" + set ss "[namespace current]::hsv_set $w s \[expr {%x*255.0/130.0}\]" + set sv "[namespace current]::hsv_set $w v \[expr {%x*255.0/130.0}\]" + bind ${w}.hue "set [namespace current]::mh($w) 1; $sh" + bind ${w}.sat "set [namespace current]::ms($w) 1; $ss" + bind ${w}.val "set [namespace current]::mv($w) 1; $sv" + bind ${w}.hue "set [namespace current]::mh($w) 0" + bind ${w}.sat "set [namespace current]::ms($w) 0" + bind ${w}.val "set [namespace current]::mv($w) 0" + bind ${w}.hue "if {\$[namespace current]::mh($w)} {$sh}" + bind ${w}.sat "if {\$[namespace current]::ms($w)} {$ss}" + bind ${w}.val "if {\$[namespace current]::mv($w)} {$sv}" + for {set x 0} {$x < 130} {incr x 3} { + set c [mkColor [hsvToRgb [expr {$x*360.0/130.0}] 255 255]] + ${w}.hue create rectangle $x 0 [expr {4+$x}] 16 -fill $c -outline {} + } + hsv_regen $w $colorhsv($w:h) + } + + proc hsv_regen {w hue} { + ${w}.sat delete all + ${w}.val delete all + for {set x 0} {$x < 130} {incr x 3} { + set x1 [expr {$x*255.0/130.0}] + set c1 [mkColor [hsvToRgb $hue $x1 255]] + set c2 [mkColor [hsvToRgb $hue 255 $x1]] + ${w}.sat create rectangle $x 0 [expr {4+$x}] 16 \ + -fill $c1 -outline {} + ${w}.val create rectangle $x 0 [expr {4+$x}] 16 \ + -fill $c2 -outline {} + } + } + + proc hsv_set {w what val} { + variable colorhsv + if {$what != {h} && $what != {s} && $what != {v}} {return} + set colorhsv($w:$what) $val + if {$colorhsv($w:$what) < 0.0} {set colorhsv($w:$what) 0} + if {$what == {h}} { + if {$colorhsv($w:$what) >= 360.0} {set colorhsv($w:$what) 0} + hsv_regen $w $colorhsv($w:$what) + } else { + if {$colorhsv($w:$what) > 255.0} {set colorhsv($w:$what) 255} + } + set c [mkColor [hsvToRgb \ + $colorhsv($w:h) $colorhsv($w:s) $colorhsv($w:v)]] + ${w}.test configure -background $c + set_color $w $c + } +} diff --git a/examples/dynreceive-help.pd b/examples/dynreceive-help.pd new file mode 100644 index 0000000..88a5568 --- /dev/null +++ b/examples/dynreceive-help.pd @@ -0,0 +1,22 @@ +#N canvas 416 120 513 409 10; +#X obj 141 168 s \$0.foo; +#X msg 46 120 bar baz; +#X obj 60 320 dynreceive \$0.foo; +#X floatatom 122 123 5 0 0 0 - - -; +#X symbolatom 177 125 10 0 0 0 - - -; +#X obj 267 125 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 +-1 -1; +#X text 43 86 1) send some symbols:; +#X text 45 240 2) try to change the receive symbol:; +#X msg 60 287 set xyz; +#X msg 312 306 \; xyz 1 2 3; +#X obj 60 350 print out; +#X text 39 23 Works like [receive] \, but allows to dynamically set +(or clear) the receive symbol.; +#X text 139 288 <--; +#X connect 1 0 0 0; +#X connect 2 0 10 0; +#X connect 3 0 0 0; +#X connect 4 0 0 0; +#X connect 5 0 0 0; +#X connect 8 0 2 0; diff --git a/examples/dynreceive.tcl b/examples/dynreceive.tcl new file mode 100644 index 0000000..8a269f7 --- /dev/null +++ b/examples/dynreceive.tcl @@ -0,0 +1,53 @@ +package require Tclpd 0.2.1 +package require TclpdLib 0.17 + +pd::class dynreceive { + constructor { + set @sym {} + if {[pd::args] > 0} { + set @sym [pd::arg 0 symbol] + pd_bind [tclpd_get_instance_pd $self] [gensym $@sym] + } + pd::add_outlet $self + } + + destructor { + # don't forget to call pd_unbind, or sending things to a symbol + # bound to dead object will crash pd! + if {$@sym != {}} { + pd_unbind [tclpd_get_instance_pd $self] [gensym $@sym] + } + } + + 0_set { + # send [set empty( to clear the receive symbol + set s [pd::arg 0 symbol] + if {$@sym != {}} { + pd_unbind [tclpd_get_instance_pd $self] [gensym $@sym] + } + if {$s == {empty}} { + set @sym {} + } else { + set @sym $s + pd_bind [tclpd_get_instance_pd $self] [gensym $@sym] + } + } + + 0_bang { + pd::outlet $self 0 bang + } + + 0_float { + pd::outlet $self 0 float [pd::arg 0 float] + } + + 0_symbol { + pd::outlet $self 0 symbol [gensym [pd::arg 0 symbol]] + } + + 0_anything { + set sel [pd::arg 0 symbol] + set argz [lrange $args 1 end] + pd::outlet $self 0 $sel $argz + } +} diff --git a/examples/dynroute-help.pd b/examples/dynroute-help.pd new file mode 100644 index 0000000..86d173e --- /dev/null +++ b/examples/dynroute-help.pd @@ -0,0 +1,26 @@ +#N canvas 1022 530 786 430 10; +#X obj 93 268 dynroute 4; +#X msg 41 147 apple red \, banana yellow \, pear green \, apple yellow +\, strawberry red; +#X obj 41 194 list prepend; +#X msg 200 224 clear \, add apple 0 \, add banana 1 \, add pear 2; +#X msg 206 258 remove pear 2 \, add pear 0 \, add strawberry 2; +#X text 39 32 Dynamically route lists based on first element \, according +to the mapping specified on right inlet. Creation argument (float) +specifies how many outlet to have (including last outlet \, which is +used for sending unmatching items); +#X text 44 120 Test it with some data:; +#X obj 93 379 print out1; +#X obj 115 352 print out2; +#X obj 137 325 print out3; +#X obj 160 298 print other; +#X text 256 293 <-- non-matching stuff is sent here; +#X text 196 192 Change the mapping:; +#X connect 0 0 7 0; +#X connect 0 1 8 0; +#X connect 0 2 9 0; +#X connect 0 3 10 0; +#X connect 1 0 2 0; +#X connect 2 0 0 0; +#X connect 3 0 0 1; +#X connect 4 0 0 1; diff --git a/examples/dynroute.tcl b/examples/dynroute.tcl new file mode 100644 index 0000000..2309ac7 --- /dev/null +++ b/examples/dynroute.tcl @@ -0,0 +1,57 @@ +package require Tclpd 0.2.1 +package require TclpdLib 0.17 + +# dynroute: dynamically route messages based on first element +# non-matching arguments are sent to last inlet +# constructor: specify the number of outlets (default: 1) +# send commands to the right inlet +# available commands: +# add route selector to output number +# remove remove previously created routing +# clear + +pd::class dynroute { + constructor { + pd::add_inlet $self list + + set @num_outlets [pd::arg 0 int] + if {$@num_outlets < 0} {set @num_outlets 2} + + for {set i 0} {$i < $@num_outlets} {incr i} { + pd::add_outlet $self list + } + + set @routing {} + } + + 0_list { + set sel [pd::arg 0 any] + set out [expr {$@num_outlets-1}] + catch {set out [dict get $@routing $sel]} + pd::outlet $self $out list $args + } + + 1_add { + set sel [pd::arg 0 any] + set out [pd::arg 1 int] + if {$out < 0 || $out >= $@num_outlets} { + pd::post "error: add: outlet number out of range" + return + } + dict set @routing $sel $out + } + + 1_remove { + set sel [pd::arg 0 any] + set out [pd::arg 1 int] + if {$out < 0 || $out >= $@num_outlets} { + pd::post "error: add: outlet number out of range" + return + } + catch {dict unset @routing $sel $out} + } + + 1_clear { + set @routing {} + } +} diff --git a/examples/list_change-help.pd b/examples/list_change-help.pd new file mode 100644 index 0000000..430b23d --- /dev/null +++ b/examples/list_change-help.pd @@ -0,0 +1,21 @@ +#N canvas 617 384 635 406 10; +#X obj 54 240 list_change; +#X text 144 236 right inlet sets internal value without output anything +; +#X obj 71 271 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 +-1; +#X obj 54 309 print; +#X text 33 21 Outputs its input (a list) only when it changes. You +can set the current value using the right inlet \, or bang to force +output; +#X msg 117 201 list foo bar; +#X msg 69 140 list foo bar; +#X msg 77 163 list bar baz; +#X msg 54 104 bang; +#X text 98 103 output current value; +#X connect 0 0 2 0; +#X connect 0 0 3 0; +#X connect 5 0 0 1; +#X connect 6 0 0 0; +#X connect 7 0 0 0; +#X connect 8 0 0 0; diff --git a/examples/list_change.tcl b/examples/list_change.tcl new file mode 100644 index 0000000..2c70937 --- /dev/null +++ b/examples/list_change.tcl @@ -0,0 +1,31 @@ +package require Tclpd 0.2.1 +package require TclpdLib 0.17 + +pd::class list_change { + constructor { + # add second inlet (first created by default) + pd::add_inlet $self list + + # add outlet + pd::add_outlet $self list + + set @curlist {} + } + + 0_list { + # HOT inlet + if {$args != $@curlist} { + set @curlist $args + pd::outlet $self 0 list $@curlist + } + } + + 0_bang { + pd::outlet $self 0 list $@curlist + } + + 1_list { + # COLD inlet + set @curlist $args + } +} diff --git a/examples/properties.tcl b/examples/properties.tcl new file mode 100644 index 0000000..d225d74 --- /dev/null +++ b/examples/properties.tcl @@ -0,0 +1,423 @@ +if {[catch {package require colorpicker}]} { + source [file join [file dirname [info script]] colorpicker.tcl] + package require colorpicker +} +namespace import ::colorpicker::colorpicker + +proc propertieswindow {gfxstub_id {options {}} {title {}}} { + set win $gfxstub_id + set ::id($win.p) $gfxstub_id + set ::optkeys($win.p) [list] + foreach {k v} $options { + set ::config($win.p:$k) $v + lappend ::optkeys($win.p) $k + } + toplevel $win + pack [propertiespanel $win.p] + wm resizable $win 0 0 + wm title $win $title + set win +} + +proc has_key {w key} { + expr {[lsearch -exact $::optkeys($w) $key] != -1} +} + +proc propertiespanel {w} { + set pad [propertiespanel_padding $w] + incr pad $pad + frame $w -borderwidth 0 -relief raised -padx $pad -pady $pad + set subpanels {dimensions output behavior connective label colors} + foreach subpanel $subpanels { + set x [propertiespanel_$subpanel $w] + if {$x != {}} {grid $x -sticky ew -in $w} + } + set x [propertiespanel_buttons $w] + grid $x -in $w + grid columnconfigure . 0 -weight 1 + set w +} + +proc propertiespanel_padding {w} { + return 3 +} + +proc propertiespanel_dimensions {w} { + set x ${w}.dimensions + set pad [propertiespanel_padding $w] + labelframe $x -text "Dimensions:" -borderwidth 1 -relief raised + set count 0 + set row 0; set col 0 + if {[has_key $w -width]} { + grid [label ${x}.wl -text "Width (px):" -anchor e] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + grid [entry ${x}.w -textvar ::config($w:-width) -width 5] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + incr count + } + if {[has_key $w -height]} { + grid [label ${x}.hl -text "Height (px):" -anchor e] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + grid [entry ${x}.h -textvar ::config($w:-height) -width 5] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + incr count + } + incr row; set col 0 + if {[has_key $w -uwidth]} { + grid [label ${x}.uwl -text "Width (cells):" -anchor e] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + grid [entry ${x}.uw -textvar ::config($w:-uwidth) -width 5] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + incr count + } + if {[has_key $w -uheight]} { + grid [label ${x}.uhl -text "Height (cells):" -anchor e] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + grid [entry ${x}.uh -textvar ::config($w:-uheight) -width 5] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + incr count + } + incr row; set col 0 + if {[has_key $w -cellsize]} { + grid [label ${x}.csl -text "Cell size (pixels):" -anchor e] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + grid [entry ${x}.cs -textvar ::config($w:-cellsize) -width 5] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + incr count + } + incr row; set col 0 + if {[has_key $w -cellwidth]} { + grid [label ${x}.uwl -text "Cell width:" -anchor e] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + grid [entry ${x}.uw -textvar ::config($w:-cellwidth) -width 5] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + incr count + } + if {[has_key $w -cellheight]} { + grid [label ${x}.uhl -text "Cell height:" -anchor e] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + grid [entry ${x}.uh -textvar ::config($w:-cellheight) -width 5] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + incr count + } + incr row; set col 0 + if {$count == 0} {return {}} + set x +} + +proc propertiespanel_output {w} { + set x ${w}.output + set pad [propertiespanel_padding $w] + labelframe $x -text "Output range:" -borderwidth 1 -relief raised + set count 0 + set row 0; set col 0 + if {[has_key $w -rangebottom]} { + grid [label ${x}.rbl -text "Bottom:" -anchor e] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + grid [entry ${x}.rb -textvar ::config($w:-rangebottom) -width 5] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + incr count + } + if {[has_key $w -rangetop]} { + grid [label ${x}.rtl -text "Top:" -anchor e] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + grid [entry ${x}.rt -textvar ::config($w:-rangetop) -width 5] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + incr count + } + incr row; set col 0 + if {[has_key $w -rangeleft]} { + grid [label ${x}.rll -text "Left:" -anchor e] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + grid [entry ${x}.rl -textvar ::config($w:-rangeleft) -width 5] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + incr count + } + if {[has_key $w -rangeright]} { + grid [label ${x}.rrl -text "Right:" -anchor e] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + grid [entry ${x}.rr -textvar ::config($w:-rangeright) -width 5] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + incr count + } + incr row; set col 0 + if {[has_key $w -rangemin]} { + grid [label ${x}.rml -text "Min:" -anchor e] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + grid [entry ${x}.rm -textvar ::config($w:-rangemin) -width 5] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + incr count + } + if {[has_key $w -rangemax]} { + grid [label ${x}.rMl -text "Max:" -anchor e] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + grid [entry ${x}.rM -textvar ::config($w:-rangemax) -width 5] \ + -row $row -column $col -sticky ew -padx $pad -pady $pad + incr col + incr count + } + incr row; set col 0 + if {[has_key $w -logarithmic]} { + incr col + grid [checkbutton ${x}.rL -variable ::config($w:-logarithmic) \ + -text "Logarithmic"] \ + -row $row -column $col -columnspan 3 -sticky w -padx $pad -pady $pad + incr col + incr count + } + incr row; set col 0 + if {$count == 0} {return {}} + set x +} + +proc propertiespanel_behavior {w} { + set x ${w}.behavior + set pad [propertiespanel_padding $w] + labelframe $x -text "Widget behavior:" -borderwidth 1 -relief raised + set count 0 + set row 0; set col 0 + if {[has_key $w -jumponclick]} { + grid [checkbutton ${x}.joc -variable ::config($w:-jumponclick) \ + -text "Jump on click"] \ + -row $row -column $col -sticky w -padx $pad -pady $pad + incr col + incr count + } + if {[has_key $w -init]} { + grid [checkbutton ${x}.init -variable ::config($w:-init) \ + -text "Output init value"] \ + -row $row -column $col -sticky w -padx $pad -pady $pad + incr col + incr count + } + incr row; set col 0 + if {$count == 0} {return {}} + set x +} + +proc propertiespanel_label {w} { + set x ${w}.label + set pad [propertiespanel_padding $w] + labelframe $x -text "Label:" -borderwidth 1 -relief raised + set count 0 + set row 0 + if {[has_key $w -label]} { + grid [label ${x}.ll -text "Text:" -anchor e] \ + -row $row -column 0 -sticky ew -padx $pad -pady $pad + grid [entry ${x}.l -textvar ::config($w:-label)] \ + -row $row -column 1 -sticky ew -padx $pad -pady $pad + incr row + incr count + } + if {[has_key $w -labelpos]} { + grid [label ${x}.lpl -text "Position:" -anchor e] \ + -row $row -column 0 -sticky ew -padx $pad -pady $pad + frame ${x}.f + if {![info exists ::config($w:-labelpos)]} { + set ::config($w:-labelpos) top + } + grid [radiobutton ${x}.f.lp1 -variable ::config($w:-labelpos) \ + -value top -text Top] \ + -row 1 -column 1 -sticky w -padx $pad -pady $pad -in ${x}.f + grid [radiobutton ${x}.f.lp2 -variable ::config($w:-labelpos) \ + -value bottom -text Bottom] \ + -row 1 -column 2 -sticky w -padx $pad -pady $pad -in ${x}.f + grid [radiobutton ${x}.f.lp3 -variable ::config($w:-labelpos) \ + -value left -text Left] \ + -row 2 -column 1 -sticky w -padx $pad -pady $pad -in ${x}.f + grid [radiobutton ${x}.f.lp4 -variable ::config($w:-labelpos) \ + -value right -text Right] \ + -row 2 -column 2 -sticky w -padx $pad -pady $pad -in ${x}.f + grid ${x}.f -sticky w -row $row -column 1 + incr row + incr count + } + if {$count == 0} {return {}} + set x +} + +proc propertiespanel_connective {w} { + set x ${w}.connective + set pad [propertiespanel_padding $w] + labelframe $x -text "Messages:" -borderwidth 1 -relief raised + set count 0 + set row 0 + if {[has_key $w -sendsymbol]} { + grid [label ${x}.ssl -text "Send symbol:" -anchor e] \ + -row $row -column 0 -sticky ew -padx $pad -pady $pad + grid [entry ${x}.ss -textvar ::config($w:-sendsymbol) -width 15] \ + -row $row -column 1 -sticky ew -padx $pad -pady $pad + incr row + incr count + } + if {[has_key $w -receivesymbol]} { + grid [label ${x}.rsl -text "Receive symbol:" -anchor e] \ + -row $row -column 0 -sticky ew -padx $pad -pady $pad + grid [entry ${x}.rs -textvar ::config($w:-receivesymbol) -width 15] \ + -row $row -column 1 -sticky ew -padx $pad -pady $pad + incr row + incr count + } + if {$count == 0} {return {}} + set x +} + +proc propertiespanel_colors {w} { + set colors {-bgcolor Background -fgcolor Foreground -lblcolor Label} + set x ${w}.colors + set pad [propertiespanel_padding $w] + labelframe $x -text "Colors:" -borderwidth 1 -relief raised + set count 0 + set row 0 + foreach {optkey color} $colors { + if {![has_key $w $optkey]} {continue} + grid [label ${x}.l$color -text "${color}:" -anchor e] \ + -row $row -column 0 -sticky ew -padx $pad -pady $pad + grid [entry ${x}.t$color -textvar ::config($w:$optkey) -width 8] \ + -row $row -column 1 -sticky ew -padx $pad -pady $pad + grid [frame ${x}.p$color -width 20 -height 20 \ + -borderwidth 1 -relief sunken] \ + -row $row -column 2 -sticky ew -padx $pad -pady $pad + grid [button ${x}.b$color -text "Pick..." -overrelief {} \ + -command {} \ + ] -row $row -column 3 -sticky ew -padx $pad -pady $pad + bind ${x}.b$color {break} + bind ${x}.b$color {break} + bind ${x}.b$color [list \ + propertiespanel_colors_pick \ + $w $x $colors ${x}.b$color ${x}.p$color ${x}.t$color] + trace add variable ::config($w:$optkey) write [list \ + propertiespanel_colors_set_wrap $w $x ${x}.p$color $optkey] + incr row + incr count + } + if {![info exists ::cpt($w)]} {set ::cpt($w) switches} + foreach {optkey color} $colors { + if {![has_key $w $optkey]} {continue} + # trigger the variable trace: + if {[info exists ::config($w:$optkey)]} { + set ::config($w:$optkey) $::config($w:$optkey) + } + } + if {$count == 0} {return {}} + frame ${x}.f + grid [radiobutton ${x}.f.cpt1 -variable ::cpt($w) -justify right \ + -value switches -text Switches] \ + -row 0 -column 0 -sticky ew -padx $pad -pady $pad + grid [radiobutton ${x}.f.cpt2 -variable ::cpt($w) -justify right \ + -value hsv -text HSV] \ + -row 1 -column 0 -sticky ew -padx $pad -pady $pad + grid ${x}.f -row $row -column 0 + grid [colorpicker ${x}.cp2 hsv] \ + -row $row -column 1 -columnspan 3 -sticky ew -padx $pad -pady $pad + grid [colorpicker ${x}.cp1 switches -command [list ${x}.cp2 set]] \ + -row $row -column 1 -columnspan 3 -sticky ew -padx $pad -pady $pad + raise ${x}.cp1 + trace add variable ::cpt($w) write \ + [list propertiespanel_colors_switchpicker $w $x $row] + set x +} + +proc propertiespanel_colors_set_wrap {w x wp optkey config_ idx op} { + propertiespanel_colors_set $w $x $wp {} -1 $::config($w:$optkey) +} + +proc propertiespanel_colors_switchpicker {w x row cpt idx op} { + raise ${x}.cp[expr {1+($::cpt($w) == {hsv})}] +} + +proc propertiespanel_colors_pick {w x colors wb wp wt} { + foreach {k color} $colors { + ${x}.b$color configure -relief raised -state normal + } + set r [$wb cget -relief] + if {$r == {sunken}} { + $wb configure -relief raised + ${x}.cp1 configure -command {} + ${x}.cp2 configure -command {} + } else { + $wb configure -relief sunken + ${x}.cp1 configure -command \ + [list propertiespanel_colors_set $w $x $wp $wt 1] + ${x}.cp2 configure -command \ + [list propertiespanel_colors_set $w $x $wp $wt 2] + } +} + +proc propertiespanel_colors_set {w x wp wt from color} { + if {$wt != {}} {$wt delete 0 end ; $wt insert 0 $color} + $wp configure -background $color + if {$::cpt($w) == {switches} && $from == 1} { + ${x}.cp2 set $color + } +} + +proc propertiespanel_buttons {w} { + set x ${w}.buttons + set pad [propertiespanel_padding $w] + frame $x -padx $pad -pady $pad + set col 0 + foreach action {Cancel Apply Ok} { + grid [button ${x}.btn$action \ + -command [list propertiespanel_buttons_action $w $action] \ + -text $action] \ + -row 0 -column $col -padx $pad -pady $pad + incr col + } + set x +} + +proc propertiespanel_buttons_action {w action} { + switch -- $action { + Cancel { + propertiespanel_close $w + } + Apply { + propertiespanel_apply $w + } + Ok { + propertiespanel_apply $w + propertiespanel_close $w + } + } +} + +proc propertiespanel_apply {w} { + set newconf [list] + foreach key $::optkeys($w) { + set v $::config($w:$key) + if {$v == ""} {set v "empty"} + lappend newconf $key $v + } + set newconf [string map {$ \\$} $newconf] + pd [linsert $newconf 0 $::id($w) config]\; +} + +proc propertiespanel_close {w} { + pd [concat $::id($w) cancel \;] +} diff --git a/examples/slider2-help.pd b/examples/slider2-help.pd new file mode 100644 index 0000000..1f36ace --- /dev/null +++ b/examples/slider2-help.pd @@ -0,0 +1,51 @@ +#N canvas 79 235 731 505 10; +#X obj 343 150 slider2 -width 15 -height 130 -headsz 3 -rangebottom +0 -rangetop 127 -init 0 -initvalue 94 -jumponclick 0 -label norm -labelpos +top -orient vertical -sendsymbol empty -receivesymbol empty -fgcolor +#000000 -bgcolor #ffffff -lblcolor #000000; +#X obj 401 150 slider2 -width 15 -height 130 -headsz 3 -rangebottom +127 -rangetop 0 -init 0 -initvalue 63 -jumponclick 0 -label rev -labelpos +top -orient vertical -sendsymbol empty -receivesymbol empty -fgcolor +#000000 -bgcolor #ffffff -lblcolor #000000; +#X obj 522 154 slider2 -width 130 -height 15 -headsz 3 -rangebottom +0 -rangetop 127 -init 0 -initvalue 95 -jumponclick 0 -label norm -labelpos +top -orient horizontal -sendsymbol empty -receivesymbol empty -fgcolor +#000000 -bgcolor #ffffff -lblcolor #000000; +#X obj 522 213 slider2 -width 130 -height 15 -headsz 3 -rangebottom +127 -rangetop 0 -init 0 -initvalue 70 -jumponclick 0 -label rev -labelpos +top -orient horizontal -sendsymbol empty -receivesymbol empty -fgcolor +#000000 -bgcolor #ffffff -lblcolor #000000; +#X floatatom 343 295 5 0 0 0 - - -; +#X floatatom 401 295 5 0 0 0 - - -; +#X floatatom 522 177 5 0 0 0 - - -; +#X floatatom 522 236 5 0 0 0 - - -; +#X text 324 109 -orient vertical; +#X text 523 111 -orient horizontal; +#X text 321 61 Output range test:; +#X obj 46 174 slider2 -width 15 -height 130 -headsz 3 -rangebottom +0 -rangetop 127 -init 0 -initvalue 10 -jumponclick 0 -label empty -labelpos +top -orient vertical -sendsymbol empty -receivesymbol empty -fgcolor +#000000 -bgcolor #ffffff -lblcolor #000000; +#X msg 46 143 config -orient vertical; +#X msg 46 113 config -orient horizontal; +#X floatatom 46 321 5 0 0 0 - - -; +#X obj 159 358 slider2 -width 130 -height 15 -headsz 3 -rangebottom +0 -rangetop 255 -init 0 -initvalue 202.795 -jumponclick 0 -label empty +-labelpos top -orient horizontal -sendsymbol \$0.sl-out -receivesymbol +\$0.sl-in -fgcolor #000000 -bgcolor #20ca34 -lblcolor #000000; +#X obj 45 358 r \$0.sl-out; +#X obj 45 466 s \$0.sl-in; +#X msg 45 439 config -bgcolor \$1; +#X obj 45 412 makefilename #%6.6x; +#X obj 45 385 expr (0x20 << 16) | ($f1 << 8) | (0xff - $f1); +#X connect 0 0 4 0; +#X connect 1 0 5 0; +#X connect 2 0 6 0; +#X connect 3 0 7 0; +#X connect 11 0 14 0; +#X connect 12 0 11 0; +#X connect 13 0 11 0; +#X connect 16 0 20 0; +#X connect 18 0 17 0; +#X connect 19 0 18 0; +#X connect 20 0 19 0; diff --git a/examples/slider2.tcl b/examples/slider2.tcl new file mode 100644 index 0000000..ff4678a --- /dev/null +++ b/examples/slider2.tcl @@ -0,0 +1,273 @@ +package require Tclpd 0.2.1 +package require TclpdLib 0.17 + +set ::script_path [file dirname [info script]] + +pd::guiproc slider2_draw_new {self c x y config state} { + # import variables from dicts: + foreach v {headsz width height fgcolor bgcolor orient} \ + {set $v [dict get $config -$v]} + set x2 [expr {$x+$width+1}] + set y2 [expr {$y+$height+1}] + $c create rectangle $x $y $x2 $y2 \ + -outline $fgcolor -fill $bgcolor -tags [list $self border$self] + switch $orient { + horizontal {set y1 $y; set x3 [expr {$x+$headsz}]} + vertical {set y1 [expr {$y2-$headsz}]; set x3 $x2} + } + $c create rectangle $x $y1 $x3 $y2 -outline {} -fill $fgcolor \ + -tags [list $self head$self] + slider2_update $self $c $x $y $config $state +} + +pd::guiproc slider2_update {self c x y config state} { + # import variables from dicts: + foreach v {initvalue headsz width height label labelpos lblcolor orient} \ + {set $v [dict get $config -$v]} + foreach v {min max rev} {set $v [dict get $state _$v]} + set realvalue [expr {1.0*($initvalue-$min)/($max-$min)}] + if {$realvalue < 0.0} {set realvalue 0} + if {$realvalue > 1.0} {set realvalue 1} + if {$rev} {set realvalue [expr {1.0-$realvalue}]} + if {$orient == "vertical"} {set realvalue [expr {1.0-$realvalue}]} + switch $orient { + horizontal { + set hr [expr {$width-$headsz}] + $c coords head$self [expr {$x+$hr*$realvalue}] $y \ + [expr {$x+$hr*$realvalue+$headsz}] [expr {$y+$height+1}] + } + vertical { + set vr [expr {$height-$headsz}] + $c coords head$self $x [expr {$y+$vr*$realvalue}] \ + [expr {$x+$width+1}] [expr {$y+$vr*$realvalue+$headsz}] + } + } + $c delete label$self + if {$label != {}} { + switch $labelpos { + top + {set lx [expr {$x+$width/2}]; set ly [expr {$y}]; set a "s"} + bottom + {set lx [expr {$x+$width/2}]; set ly [expr {$y+$height+2}]; set a "n"} + left + {set lx [expr {$x}]; set ly [expr {$y+$height/2}]; set a "e"} + right + {set lx [expr {$x+$width+2}]; set ly [expr {$y+$height/2}]; set a "w"} + } + $c create text $lx $ly -anchor $a -text $label -fill $lblcolor \ + -tags [list $self label$self] + } +} + +pd::guiclass slider2 { + constructor { + pd::add_outlet $self float + sys_gui "source {[file join $::script_path properties.tcl]}\n" + # set defaults: + set @config { + -width 15 -height 130 -headsz 3 -rangebottom 0 -rangetop 127 + -init 0 -initvalue 0 -jumponclick 0 -label "" -labelpos "top" + -orient "vertical" -sendsymbol "" -receivesymbol "" + -fgcolor "#000000" -bgcolor "#ffffff" -lblcolor "#000000" + } + set @state {_min 0 _max 127 _rev 0} + # expanded ($n) send/recv symbols: + set @send {} + set @recv {} + ::$self 0 config {*}$args + } + + destructor { + if {[dict get $@config -receivesymbol] != {}} { + pd_unbind [tclpd_get_instance_pd $self] $@recv + } + } + + 0_loadbang { + if {[dict get $@config -init]} {$self 0 bang} + } + + 0_config { + set newconf [list] + set optlist [pd::strip_selectors $args] + set optlist [pd::strip_empty $optlist] + set int_opts {-width -height -cellsize} + set bool_opts {-init -jumponclick} + set ui_opts {-fgcolor -bgcolor -lblcolor -orient -width -height} + set upd_opts {-rangebottom -rangetop -label -labelpos} + set conn_opts {-sendsymbol -receivesymbol} + set ui 0 + set upd 0 + foreach {k v} $optlist { + if {![dict exists $@config $k]} { + return -code error "unknown option '$k'" + } + if {[dict get $@config $k] == $v} {continue} + if {[lsearch -exact $int_opts $k] != -1} {set v [expr {int($v)}]} + if {[lsearch -exact $bool_opts $k] != -1} {set v [expr {int($v)!=0}]} + if {[lsearch -exact $ui_opts $k] != -1} {set ui 1} + if {[lsearch -exact $upd_opts $k] != -1} {set upd 1} + dict set newconf $k $v + } + # process -{send,receive}symbol + if {[dict exists $newconf -receivesymbol]} { + set new_recv [dict get $newconf -receivesymbol] + set selfpd [tclpd_get_instance_pd $self] + if {[dict get $@config -receivesymbol] != {}} { + pd_unbind $selfpd $@recv + } + if {$new_recv != {}} { + set @recv [canvas_realizedollar \ + [tclpd_get_glist $self] [gensym $new_recv]] + pd_bind $selfpd $@recv + } else {set @recv {}} + } + if {[dict exists $newconf -sendsymbol]} { + set new_send [dict get $newconf -sendsymbol] + if {$new_send != {}} { + set @send [canvas_realizedollar \ + [tclpd_get_glist $self] [gensym $new_send]] + } else {set @send {}} + } + # changing orient -> swap sizes + if {[dict exists $newconf -orient] && ![dict exists $newconf -width] + && ![dict exists $newconf -height]} { + dict set newconf -width [dict get $@config -height] + dict set newconf -height [dict get $@config -width] + } + # no errors up to this point. we can safely merge options + set @config [dict merge $@config $newconf] + # adjust reverse range + set a [dict get $@config -rangebottom] + set b [dict get $@config -rangetop] + dict set @state _min [expr {$a>$b?$b:$a}] + dict set @state _max [expr {$a>$b?$a:$b}] + dict set @state _rev [expr {$a>$b}] + set orient [dict get $@config -orient] + switch $orient { + horizontal {set dim [dict get $@config -width]; set mul 1} + vertical {set dim [dict get $@config -height]; set mul -1} + default {return -code error "invalid value '$orient' for -orient"} + } + # recompute pix2units conversion + set @pix2units [expr {(2.0 * [dict get $@state _rev] - 1.0) * + ( [dict get $@state _max] - [dict get $@state _min] ) * + $mul / ( $dim - [dict get $@config -headsz])}] + # if ui changed, update it + if {$ui && [info exists @c]} { + sys_gui [list $@c delete $self]\n + sys_gui [list slider2_draw_new $self $@c $@x $@y $@config $@state]\n + } elseif {$upd && [info exists @c]} { + sys_gui [list slider2_update $self $@c $@x $@y $@config $@state]\n + } + if {[dict exists $newconf -width] || [dict exists $newconf -height]} { + canvas_fixlinesfor \ + [tclpd_get_glist $self] [tclpd_get_instance_text $self] + } + } + + 0_set { + foreach v {min max} {set $v [dict get $@state _$v]} + set f [pd::arg 0 float] + if {$f < $min} {set f $min} + if {$f > $max} {set f $max} + dict set @config -initvalue $f + if {[info exists @c]} { + # update ui: + sys_gui [list slider2_update $self $@c $@x $@y $@config $@state]\n + } + } + + 0_bang { + foreach v {initvalue} {set $v [dict get $@config -$v]} + pd::outlet $self 0 float $initvalue + if {$@send != {}} { + set s_thing [$@send cget -s_thing] + if {$s_thing != {NULL}} {pd_float $s_thing $initvalue} + } + } + + 0_float { + $self 0 set {*}$args + $self 0 bang + } + + object_save { + return [list #X obj $@x $@y slider2 {*}[pd::add_empty $@config] \;] + } + + object_properties { + set c [string map {$ \\$} $@config] + gfxstub_new [tclpd_get_object_pd $self] [tclpd_get_instance $self] \ + [list propertieswindow %s $c "\[slider2\] properties"]\n + } + + widgetbehavior_getrect { + lassign $args x1 y1 + set x2 [expr {1+$x1+[dict get $@config -width]}] + set y2 [expr {1+$y1+[dict get $@config -height]}] + return [list $x1 $y1 $x2 $y2] + } + + widgetbehavior_displace { + lassign $args dx dy + if {$dx != 0 || $dy != 0} { + incr @x $dx; incr @y $dy + sys_gui [list $@c move $self $dx $dy]\n + } + return [list $@x $@y] + } + + widgetbehavior_select { + lassign $args sel + sys_gui [list $@c itemconfigure $self&&!label$self -outline [lindex \ + [list [dict get $@config -fgcolor] {blue}] $sel]]\n + } + + widgetbehavior_vis { + lassign $args @c @x @y vis + if {$vis} { + sys_gui [list slider2_draw_new $self $@c $@x $@y $@config $@state]\n + } else { + sys_gui [list $@c delete $self]\n + } + } + + widgetbehavior_click { + lassign $args x y shift alt dbl doit + set h [dict get $@config -height] + set ypix [expr {[lindex $args 1]-$@y-1}] + if {$ypix < 0 || $ypix >= $h} {return} + if {$doit} { + switch [dict get $@config -orient] { + horizontal { + set @motion_start_x $x + set @motion_curr_x $x + } + vertical { + set @motion_start_y $y + set @motion_curr_y $y + } + } + set @motion_start_v [dict get $@config -initvalue] + tclpd_guiclass_grab [tclpd_get_instance $self] \ + [tclpd_get_glist $self] $x $y + } + } + + widgetbehavior_motion { + lassign $args dx dy + switch [dict get $@config -orient] { + horizontal { + set @motion_curr_x [expr {$dx+$@motion_curr_x}] + set pixdelta [expr {-1*($@motion_curr_x-$@motion_start_x)}] + } + vertical { + set @motion_curr_y [expr {$dy+$@motion_curr_y}] + set pixdelta [expr {-1*($@motion_curr_y-$@motion_start_y)}] + } + } + set f [expr {$@motion_start_v+$pixdelta*$@pix2units}] + $self 0 float {*}[pd::add_selectors [list $f]] + } +} -- cgit v1.2.1