6.4 Example: An Animated Time Waster

In this section we want to program a procedure that signals to the user that a particular computation is still running and entertains the user by some animation.

Figure 6.4 shows a subclass of Tk.canvasTag that creates a bitmap item showing a magnifying glass and starts a thread to move that bitmap randomly. The random movement can be stopped by binding the variable D given as value for the feature done. If the animation has stopped indeed, the variable S gets bound, as you can see in method move.

   fun {RandCoord} {OS.rand} mod 20 + 15 end 
   class RandMag from Tk.canvasTag 
      meth init(parent:P done:D stopped:S)
         {self tkInit(parent:P)}
         {P tk(create bitmap 0 0
                  bitmap:'@'#{Property.get 'oz.home'}# 
                  tags:self foreground:blue)}
         thread {self move(D S)} end 
      meth move(D S)
         {WaitOr {Alarm 400} D}
         if {IsDet D} then S=unit else 
            {self tk(coords {RandCoord} {RandCoord})}
            {self move(D S)}

Figure 6.4: An animated time waster class.

The procedure WaitDone shown in Figure 6.5 takes a variable Done which is used for signalling when the computation we are waiting for is finished. It creates a randomly moving magnifier item and as soon as the magnifier signals that it has been stopped (by Stopped) the toplevel windows is closed.

proc {WaitDone Done}
   W={New Tk.toplevel tkInit(withdraw:true)}
   L={New Tk.label    tkInit(parent:W text:'Computing...')}
   C={New Tk.canvas   tkInit(parent:W width:50 height:50)}
   {Tk.batch [wm(overrideredirect W true)
              pack(L C side:left pady:2#m padx:2#m)
              wm(deiconify W)]}
   _={New RandMag init(parent:C done:Done stopped:Stopped)}
   thread {Wait Stopped} {W tkClose} end 

Figure 6.5: A procedure for creating wait dialogs.

For example,

declare Done
{WaitDone Done}

creates a waiting dialog which disappears by binding Done


Christian Schulte
Version 1.4.0 (20080702)