[Ruby/Tk example] Feedback [incr Widget] -- take 2

This is my second take on the progress indicator example. Perhaps it's more interesting because it uses a TkTimer (aka TkAfter) to step the progress bar.

Puts up a window containing a progress bar and a button. Clicking on the button, disables it and starts stepping the progress bar. When the progress bar has filled, the button is re-enabled and the whole thing can be repeated until you're bored out of your mind :slight_smile:

<code>
#! /usr/bin/ruby -w
# Author: Morton Goldberg

···

#
# Date: September 6, 2006
#
# Progress Indicator 2

require 'tk'
require 'tkextlib/iwidgets'

DEBUG = []

begin
    # Build a window containing a progress indicator and a button.
    root = TkRoot.new {title 'Ruby/Tk Progress Indicator'}
    fb = Tk::Iwidgets::Feedback.new(root) {
       steps 20
       labeltext "Click the Button"
       barcolor 'red'
       barheight 20
       troughcolor 'gray90'
    }
    fb.component_widget('trough').
       configure('relief'=>'ridge', 'borderwidth'=>4)
    fb.component_widget('bar').
       configure('relief'=>'sunken', 'borderwidth'=>5)
    fb.pack('fill'=>'x', 'padx'=>15, 'pady'=>10)
    btn = TkButton.new(root) {
       text "Do Something"
       command {btn.action}
    }
    btn.pack('pady'=>10)
    btn.instance_variable_set(:@fb, fb)
    # Starts the timer going when the button is clicked.
    def btn.action
       self.state = 'disable' # Strange -- explicit receiver required
       # Set the timer to trigger at 200 m-sec intervals, once for each
       # progress step.
       $timer = TkTimer.start(200, @fb.steps) {@fb.update}
    end
    fb.instance_variable_set(:@btn, btn)
    # Run on each timer tick.
    def fb.update
       labeltext = "Doing Something ..."
       step
       # loop_rest returns remaining trigger intervals.
       unless $timer.loop_rest > 1
          labeltext = "Click the Button"
          reset
          @btn.state = 'normal'
       end
    end

    # Set initial window geometry; i.e., size and placement.
    win_w, win_h = 300, 160
    # root.minsize(win_w, win_h)
    win_l = (TkWinfo.screenwidth('.') - win_w) / 2
    root.geometry("#{win_w}x#{win_h}+#{win_l}+50")

    # Set resize permissions.
    root.resizable(false, false)

    # Make Cmnd+Q work as expected.
    root.bind('Command-q') {Tk.root.destroy}

    Tk.mainloop
ensure
    puts DEBUG unless DEBUG.empty?
end
</code>

Regards, Morton