First, we might have multiple things to wait for, and we want to see how much time is left, not just rely on a single sound to notify us:
set $var $tm
lappend ::dl $var
lappend ::al $var
pack [frame .tMain.f$var] -side top -expand 1 -fill x
pack [label .tMain.lT$var -text $tx] -in .tMain.f$var -side left
pack [label .tMain.l$var] -in .tMain.f$var -side right
This is actually a function (proc addLine {var tm tx}), so I can add lines programmatically.
The "lines" are placed in the window, each one representing a timer counting down.
You have parameters:
- var - the variable which will hold the time, this is displayed elsewhere, so it can be descriptive, and is used inside functions, so it needs the global namespace like "::zombies" or "::arena"
- tm - the time (in seconds) until the event
- tx - the text description for the window
Now, when we want to decrement all the timers:
proc decList {il} {
upvar $il l
# foreach variable in the list
foreach iu $l {
upvar $iu i
# decrement it
incr i -1
# update the GUI
.tMain.l$iu configure -text [tformat $i]
# check for timer expire
if {$i == 0} {
# remove the timer from the list
set idx [lsearch $l $iu]
set l [lreplace $l $idx $idx]
# flash the text
after 1000 ".tMain.lT$iu configure -fg #008800"
after 5000 ".tMain.lT$iu configure -fg #000000"
playSound
}
}
}
The upvar may not be needed, I was trying to work around not using globals...
tformat is my "time format". It converts a number of seconds into a nice "35 m 0 s" or "1 h 0 m 50 s" string for pretty display. It is left as an exercise for the reader.