#!/dis/sh
# interactive demo. run with no arguments. picks up possible demos from
# the *.demo directories.
load tk
font=/fonts/lucida/latin1CW.10.font
nl='
'
fn shctl {
echo ${quote $*} > /chan/shctl
}
# ${vbind block [var...]}
# give the named vars their current values when block
# comes to be executed.
subfn vbind {
if {no $*} {
echo 'usage: ${vbind block [var ...]}' >[1=2]
raise usage
}
result = ''
apply {
result=$result^${quote $1}^':='^${quote $$1}^';'
} ${tl $*}
result = ${parse '{'^$result^${hd $*}^' $*}'}
}
# show a sequence of buttons, each an associated action.
# also allow typing at the console.
# it expects as its argument a list of (label, script) pairs.
# when script is evaluated, it should set $result to a string
# to be sent to the shell.
fn dodemo {
load tk
chan event kbd
cmds := $*
if {~ $#cmds 0} {
raise 'no commands'
}
while {} {
x := "{read}
if {! ~ $x ''} {
x=$x^$nl
}
send event $x
} < /chan/shctl &
while {} {
getlines {
send kbd $line^$nl
}
send kbd ''
} &
subfn valof {
$*
}
{
while {! ~ $#cmds 0} {
(label cmd cmds) = $cmds
cmd = ${valof $cmd}
shctl clear
shctl action $label $cmd
chan := kbd
while {~ $chan kbd} {
(chan x) = ${alt event kbd}
if {~ $chan event} {
echo -n $x >[1=2]
if {~ $x ''} {
echo -n '' >[1=2]
}
}
echo -n $x
}
}
kill -g ${pid}
} | $executor
}
{
pctl newpgrp
wid=${tk window 'Demos'}
tk $wid update
fn x { a := $*; or {tk $wid $a} {echo error on tk cmd $"a':' $status }}
while {} {tk winctl $wid ${recv $wid}} &
chan cmd
tk namechan $wid cmd
for (i in *.demo) {
(name nil) := ${split '.' $i}
x button .^$name -text ${tkquote $name} -command '{send cmd' ${vbind {
(wm/sh
-f $font
-w 1000 -h 800
-c {
pctl forkns
cd $i
executor := {sh -i}
run demo
}
)
} i} '}'
x pack .^$name -side top -anchor w -fill x
}
tk onscreen $wid
x update
while {} {
${recv cmd} # execute shell command sent by button
}
} &
|