| Previous | Next
Splash ScreensSplash screens are those windows that pop up for the amusement of the user while a long-loading program gets underway. Some folks display their splash screens during program initialization sequentially, so that if a splash screen stays on the display for three seconds, the program takes three seconds longer to load. We, however, prefer that our splash screens run in parallel with program initialization. One approach might be:
There's a problem with this scheme: if initialization takes too long and the splash timer expires, the my $mw = MainWindow->new; $mw->withdraw; my ($splash_scr, $splash_tid, $splash_var) = splash 3000; # - program initialization. my $why = $mw->&waitVariableX(3000, $splash_var); $splash_scr->afterCancel($splash_tid); $splash_scr->destroy; $mw->deiconify; But this just doesn't feel right. First, having the splash screen remain on the screen for X seconds one time, and X+3 seconds at others, is an unsatisfactory hack. Second, too much of the work is left to the application. We need to encapsulate things in a mega-widget. Besides, there are some subtle details, as we are about to see. Tk::SplashscreenWe've just written tkhp16c, our version of the venerable RPN developing calculator, shown in Figure 15-6. As Tk programs go, this application loads slowly, because it's composed of so many widgets. So we'll incorporate a splash screen. Figure 15-6. An HP-16C RPN calculatorTk::Splashscreen is a Toplevel mega-widget providing all the display, destroy, and timing events. All we do is create the Splashscreen widget, populate it, then invoke Here's the mega-widget preamble. If it's unfamiliar, please read "Creating Custom Widgets in Pure Perl/Tk" for complete details. Note that for this mega-widget, we import the $Tk::Splashscreen::VERSION = '1.0'; package Tk::Splashscreen; use Tk qw/Ev/; use Tk qw/:eventtypes/; use Tk::waitVariableX; use Tk::widgets qw/Toplevel/; use base qw/Tk::Toplevel/; Construct Tk::Widget 'Splashscreen'; Subroutine The two button bindings use the special format where we explicitly state the object to use, Lastly, instance variable
At this point, we have an empty Splashscreen widget. Before we show it, let's put something inside. We'll keep it simple, with a MacProgressBar and a picture of an actual HP-16C calculator, as shown in Figure 15-7. A MacProgressBar widget has a 3D look, exactly like the classic Macintosh progress bar. We won't examine the code here, but it's listed in Appendix C, "Complete Program Listings". It's a versatile widget. Here's a pseudo-volume meter:
Figure 15-7. tkhp16c initialization is 90% completeAnyway, we keep the MacProgressBar widget reference in the global variable $splash = $mw->Splashscreen(-milliseconds => 3000); $splash->Label(-text => 'Building your HP 16C ...', -bg => $BLUE)-> pack(qw/-fill both -expand 1/); $MAC_PB = $splash->MacProgressBar(-width => 300); $MAC_PB->pack(qw/-fill both -expand 1/); $splash->Label(-image => $mw->Photo(-file => 'hp16c-splash.gif'))->pack; Here's how we use the Splashscreen. First, my $mw = MainWindow->new; $mw->withdraw; $splash->Splash; # show Splashscreen build_help_window; build_calculator; $MAC_PB->set($MAC_PB_P = 100); $splash->Destroy; # tear down Splashscreen $mw->deiconify; # show calculator The
We then create a generic completion callback that does one final Now, if the program initialization has taken longer than the minimum Splashscreen time, we call the completion callback and return. Otherwise, we process all timer events, wait the requisite amount of time, and destroy the Splashscreen.
These are the private methods responsible for moving a Splashscreen widget. On a button press, we record the cursor's x and y coordinates relative to the Splashscreen's top-left corner. When the button is released, we compute new x and y coordinates relative to the display's top-left corner and use
To complete our discussion on Tk::Splashscreen, here is a ## Binding information for '.splashscreen', Tk::Splashscreen=HASH(0x83a6874) ## 1. Binding tag 'Tk::Splashscreen' has no bindings. 2. Binding tag '.splashscreen' has these bindings: <ButtonRelease-3> : Tk::Callback=ARRAY(0x83aaaf8) Tk::Splashscreen=HASH(0x83a6874) 'b3rls' Tk::Ev=SCALAR(0x83aab1c) : 'X' Tk::Ev=SCALAR(0x83aab58) : 'Y' <Button-3> : Tk::Callback=ARRAY(0x83aaae0) Tk::Splashscreen=HASH(0x83a6874) 'b3prs' Tk::Ev=SCALAR(0x839a348) : 'x' Tk::Ev=SCALAR(0x83aab04) : 'y' 3. Binding tag 'all' has these bindings: <Key-F10> : Tk::Callback=SCALAR(0x839a3fc) 'FirstMenu' <Alt-Key> : Tk::Callback=ARRAY(0x839a390) 'TraverseToMenu' Tk::Ev=SCALAR(0x816e198) : 'K' <<LeftTab>> : Tk::Callback=SCALAR(0x839a360) 'focusPrev' <Key-Tab> : Tk::Callback=SCALAR(0x839a264) 'focusNext' |