Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | # Learn how to write your own widget demonstration. |
2 | ||
3 | use vars qw/$TOP/; | |
4 | ||
5 | sub TEMPLATE { | |
6 | my($demo) = @_; | |
7 | $TOP = $MW->WidgetDemo( | |
8 | -name => $demo, | |
9 | -text => 'Learn how to write a widget demonstration!', | |
10 | -geometry_manager => 'grid', | |
11 | -title => 'WidgetDemo Example', | |
12 | -iconname => 'WidgetDemo', | |
13 | ); | |
14 | $TOP->Label(-text => 'Click "See Code".')->grid; | |
15 | } | |
16 | __END__ | |
17 | ||
18 | The template code above specifies how user contributed widget demonstrations | |
19 | can be written. | |
20 | ||
21 | widget looks in the directory specified on the command line to load user | |
22 | contributed demonstrations. If no directory name is specified when widget is | |
23 | invoked and the environment variable WIDTRIB is defined then demonstrations | |
24 | are loaded from the WIDTRIB directory. If WIDTRIB is undefined then widget | |
25 | defaults to the released user contributed directory. | |
26 | ||
27 | The first line of the file is the DDD (Demonstration Description Data), which | |
28 | briefly describes the purpose of the demonstration. The widget program reads | |
29 | this line and uses it when building its interface. | |
30 | ||
31 | Demonstrations may have a unique subroutine which is the same as the filename | |
32 | with .pl stripped off. When widget calls your subroutine it's passed one | |
33 | argument, the demonstration name. So file TEMPLATE.pl contains subroutine | |
34 | TEMPLATE(). But a demo can actually be an entire program - read on! | |
35 | ||
36 | For consistency your demonstration should use the WidgetDemo widget. This is | |
37 | a toplevel widget with three frames. The top frame contains descriptive | |
38 | demonstration text. The bottom frame contains the "Dismiss" and "See Code" | |
39 | buttons. The middle frame is the demonstration container, which can be | |
40 | managed by either the pack or grid geometry manager. | |
41 | ||
42 | Since your subroutine can "see" all of widget's global variables, you | |
43 | use $MW (the main window reference) to create the WidgetDemo toplevel; be sure | |
44 | to pass at least the -name and -text parameters. -geometry_manager defaults | |
45 | to "pack". The call to WidgetDemo() returns a reference to the containing | |
46 | frame for your demonstration, so treat it as if it were the MainWindow, the | |
47 | top-most window of your widget hierarchy. | |
48 | ||
49 | Alternatively the .pl file make contain typical Perl/Tk code of the form: | |
50 | ||
51 | # Demonstration Description Data | |
52 | ||
53 | use Tk; | |
54 | my $top = MainWindow->new; | |
55 | $top->Label(-text => 'Whatever'); | |
56 | MainLoop; | |
57 | __END__ | |
58 | ||
59 | widget has re-defined normal MainWindow to actually create a WidgetDemo | |
60 | on your code's behalf. MainLoop is optional in a demo (it will immediately | |
61 | return as MainLoop is already active). | |
62 | ||
63 | Other consideration: | |
64 | ||
65 | . widget global variables are all uppercase, like $MW - be careful not | |
66 | to stomp on them! | |
67 | ||
68 | . Demo files should really be run in private packages to avoid those | |
69 | problems. | |
70 | ||
71 | . Don't subvert the inheritance mechanism by calling Tk::MainWindow | |
72 | in your demo code. | |
73 | ||
74 | . The description should really be extracted from POD documentation | |
75 | in the .pl file rather than a magic comment. | |
76 | ||
77 | . If your demonstration has a Quit button change it to ring the bell | |
78 | and use the builtin Dismiss instead. In particular destroying a | |
79 | MainWindow is acceptable, but exit will shut down widget itself! | |
80 | ||
81 | . Be sure $TOP is declared in a "use vars" statement and not as a | |
82 | lexical my() in the subroutine (see below). | |
83 | ||
84 | . If you're wrapping an existing main program in a subroutine be very | |
85 | alert for closure bugs. Lexicals inside a subroutine become closed | |
86 | so you may run into initialization problems on the second and | |
87 | subsequent invokations of the demonstration. The npuz and plop | |
88 | demonstrations show how to work around this. Essentially, remove | |
89 | all "global" my() variables and place them within a "use vars". | |
90 | This practice is prone to subtle bugs and is not recommended! | |
91 | ||
92 |