Skip to content

Instantly share code, notes, and snippets.

@nmichaud

nmichaud/21.folk Secret

Last active September 16, 2024 14:49
Show Gist options
  • Save nmichaud/fc7b77bd2c77f9df0334a05c76271031 to your computer and use it in GitHub Desktop.
Save nmichaud/fc7b77bd2c77f9df0334a05c76271031 to your computer and use it in GitHub Desktop.
Parameters
Wish $this has parameter "iterations" with options [dict create \
default 3 \
range [list 1 10] \
order 0 \
]
Wish $this has parameter "size" with options [dict create \
default 20 \
range [list 10 50] \
order 1 \
]
Wish $this has parameter "spacing" with options [dict create \
default 20 \
range [list 10 50] \
order 2 \
]
When $this has region /r/ & \
$this has parameter "iterations" with value /iter/ & \
$this has parameter "size" with value /size/ & \
$this has parameter "spacing" with value /spacing/ {
set iter [expr {int($iter)}]
set c [vec2 sub [region centroid $r] [list [expr {$iter*10}] 0]]
for {set i 0} {$i < $iter} {incr i} {
set pos [vec2 add $c [list [expr {$spacing*$i}] 0]]
Wish to draw a circle with center $pos radius $size thickness 5 filled false color green
}
}
set PI 3.14159
When /knob/ is a knob {
On unmatch {
Commit (on $knob) {}
}
}
When /knob/ is a knob & \
/knob/ has region /r/ & \
/someone/ wishes /knob/ displays /name/ value /value/ with range /range/ {
lassign $range lo hi
set frac [expr {(double($value)-$lo)/($hi-$lo)}]
set arclen [expr {(2*$PI)*$frac}]
set start [expr {2*$PI - $arclen}]
set radius [expr {[region width $r] * 2.0}]
lassign [region centroid $r] cx cy
Wish to draw an arc with x $cx y $cy start $start arclen $arclen radius $radius thickness 20 color blue
set text "$name ($lo - $hi)"
Wish to draw text with center [vec2 add [list $cx $cy] [list 0 [expr {$radius*1.4}]]] text $text radians $PI
}
# Incremental delta angles with handling around -PI/PI boundary
When /knob/ is a knob & \
/knob/ has region /r/ {
set angle [region angle $r]
When $knob has prev_a /nothing/ {
Commit (on $knob) {
Claim $knob has prev_a $angle
}
}
When $knob has prev_a /prev_a/ {
set delta_a [expr {$prev_a - $angle}]
if {$delta_a > $PI} {
set delta_a [expr {$delta_a - 2*$PI}]
} elseif {$delta_a < [expr {-$PI}]} {
set delta_a [expr {$delta_a + 2*$PI}]
}
if {[expr {abs($delta_a)}] >= 0.05} {
# Claim in percent terms
Claim $knob has rotation change [expr {$delta_a/(2*$PI)}]
Commit (on $knob) {
Claim $knob has prev_a $angle
}
}
}
}
When /box/ is a parameter & \
/knob/ is a knob & \
the distance between /box/ and /knob/ is /distance/ {
if {$distance < 200} {
Claim $knob is within 200px of $box
}
}
When /knob/ is a knob & \
/knob/ has region /region/ & \
the collected matches for [list /p/ is a parameter & /p/ has region /r/] are /matches/ {
if {[llength $matches] > 0 } {
set distances [lmap match $matches {
set r [dict get $match r]
vec2 distance [region centroid $region] [region left $r]
}]
set idx 0
set m [lindex $distances $idx]
for {set i 0} {$i < [llength $distances]} {incr i} {
set new_m [expr {min($m, [lindex $distances $i])}]
if {$new_m < $m} {
set idx $i
}
set p [dict get [lindex $matches $i] p]
}
Commit (on $knob) closest {
Claim $knob is the closest knob to [dict get [lindex $matches $idx] p]
}
}
}
When /someone/ wishes /p/ has parameter /name/ with options /options/ {
# Setup options
set default [dict_getdef $options default 1]
set range [dict_getdef $options range [list 0 1]]
When /someone/ claims $p parameter $name has value /nothing/ with options /o/ {
Commit (on $p) "parameter-$name" {
Claim $p parameter $name has value $default with options $options
}
}
Wish $p shows parameters
}
When /p/ parameter /name/ has value /value/ with options /o/ {
Claim $p has parameter $name with value $value
}
When /p/ parameter /name/ has value /value/ with options /o/ & \
/someone/ wishes /p/ shows parameters {
set box "$p-parameter-$name"
set width 100
set height [expr {25*2}]
set order [dict_getdef $o order 0]
Claim $p fans out box $box on right with width $width height $height order $order
#Wish $box draws text $name with position (x=0, y=0)
#Wish $box draws text $value with position (x=0, y=font_height+0.5)
set label "$name\n$value"
Wish $box is labelled $label
Claim $box is a parameter
Claim $box represents parameter $name for $p
}
# Fan out sub-regions
When /obj/ has region /region/ {
lassign [region right $region] x y
set angle [region angle $region]
When the collected matches for [list $obj fans out box /box/ on right with width /w/ height /h/ order /o/] are /matches/ {
if {[llength $matches] > 0} {
# This sorting is hacky and relies on the fact that the order is the last argument in the dictionary
set matches [lsort -index end $matches]
set spacing 16
set height [::tcl::mathop::+ {*}[lmap match $matches {dict get $match h}]]
set height [expr {$height + 16*([llength $matches]-1)}]
set width [::tcl::mathfunc::max {*}[lmap match $matches {dict get $match w}]]
# Dummy region to start off
set dy [expr {$height/2+$spacing}]
set newr [region move [region fromRect $x $y 0 0 $angle] right [expr {$width/2 + 60}]px up ${dy}px]
for {set i 0} {$i < [llength $matches]} {incr i} {
set match [lindex $matches $i]
set box [dict get $match box]
# New region relative to previous
set prevh [region height $newr]
lassign [region centroid $newr] x y
set w [dict get $match w]
set h [dict get $match h]
set newr [region move [region fromRect $x $y $w $h $angle] down [expr {$prevh/2+$h/2+16}]px]
Claim $box has region $newr
}
}
}
}
When /p/ parameter /name/ has value /value/ with options /o/ & \
/box/ represents parameter /name/ for /p/ & \
/knob/ is the closest knob to /box/ & \
/knob/ is within 200px of /box/ {
set range [dict get $o range]
Wish $knob displays $name value $value with range $range
Wish $knob is connected to $box from centroid to right
When /knob/ has rotation change /r/ {
lassign [dict get $o range] lo hi
set full_range [expr {$hi - $lo}]
set new_value [expr {$value + $full_range * $r}]
set new_value [expr {max($lo, min($hi, $new_value))}]
set new_value [expr {round(100*double($new_value))/100.0}]
Commit (on $p) "parameter-$name" {
Claim $p parameter $name has value $new_value with options $o
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment