1#!/usr/bin/env ruby
2#
3#   countdown timer
4#     usage: cd_timer min [, min ... ]
5#            ( e.g. cd_timer 0.5 1 3 5 10 )
6#
7require 'tk'
8
9if ARGV.empty?
10  $stderr.puts 'Error:: No time arguments for counting down'
11  exit(1)
12end
13
14width = 10
15
16TkButton.new(:text=>'exit',
17             :command=>proc{exit}).pack(:side=>:bottom, :fill=>:x)
18
19b = TkButton.new(:text=>'start').pack(:side=>:top, :fill=>:x)
20
21f = TkFrame.new(:relief=>:ridge, :borderwidth=>2).pack(:fill=>:x)
22TkLabel.new(f, :relief=>:flat, :pady=>3,
23            :background=>'black', :foreground=>'white',
24            :text=>'  elapsed: ').pack(:fill=>:x, :side=>:left, :expand=>true)
25now = TkLabel.new(f, :width=>width, :relief=>:flat, :pady=>3, :anchor=>:w,
26                  :background=>'black', :foreground=>'white',
27                  :text=>'%4d:%02d.00' % [0, 0]).pack(:side=>:right)
28
29timers = [ TkRTTimer.new(10){|tm|
30    t = (tm.return_value || 0) + 1
31    s, u = t.divmod(100)
32    m, s = s.divmod(60)
33    now.text('%4d:%02d.%02d' % [m, s, u])
34    t
35  }.set_start_proc(0, proc{
36                     now.text('%4d:%02d.00' % [0,0])
37                     now.foreground('white')
38                     0
39                   })
40]
41
42ARGV.collect{|arg| (Float(arg) * 60).to_i}.sort.each_with_index{|time, idx|
43  f = TkFrame.new(:relief=>:ridge, :borderwidth=>2).pack(:fill=>:x)
44  TkLabel.new(f, :relief=>:flat, :pady=>3,
45              :text=>'  %4d:%02d  --> ' % (time.divmod(60))).pack(:side=>:left)
46  l = TkLabel.new(f, :width=>width, :relief=>:flat, :pady=>3, :anchor=>:w,
47                  :text=>'%4d:%02d' % (time.divmod(60))).pack(:side=>:right)
48  timers << TkRTTimer.new(1000){|tm|
49    t = (tm.return_value || time) - 1
50    if t < 0
51      l.text('%4d:%02d' % ((-t).divmod(60)))
52    else
53      l.text('%4d:%02d' % (t.divmod(60)))
54    end
55    if t.zero?
56      l.foreground('red')
57      idx.times{Tk.bell}
58    end
59    t
60  }.set_start_proc(0, proc{
61                     l.text('%4d:%02d' % (time.divmod(60)))
62                     l.foreground('black')
63                     time
64                   })
65}
66
67mode = :start
68b.command(proc{
69            if mode == :start
70              timers.each{|timer| timer.restart}
71              b.text('reset')
72              mode = :reset
73            else
74              timers.each{|timer| timer.stop.reset}
75              b.text('start')
76              mode = :start
77            end
78          })
79
80Tk.mainloop
81
82