.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "mega 3pm" .TH mega 3pm "2020-11-09" "perl v5.32.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Tk::mega \- Perl/Tk support for writing widgets in pure Perl .SH "SYNOPSIS" .IX Header "SYNOPSIS" Define the widget's new class name: .PP     \fBpackage Tk::\fR\fIMyNewWidget\fR; .PP For composite widget classes: .PP     \fBuse base qw/ Tk::container /\fR; # where \fBcontainer\fR is \fIFrame\fR or \fIToplevel\fR .PP For derived widget classes: .PP     \fBuse base qw/ Tk::Derived Tk::DerivedWidget /;\fR .PP Install the new widget in Tk's namespace and establish class and instance constructors. .PP     \fBConstruct Tk::\fR\fIWidget\fR \fI'MyNewWidget'\fR; .PP     \fBsub ClassInit\fR { \fImy ($self, \f(CI$args\fI) = \f(CI@_\fI; ...\fR } .PP     \fBsub Populate\fR { \fImy ($self, \f(CI$args\fI) = \f(CI@_\fI; ...\fR } .SH "DESCRIPTION" .IX Header "DESCRIPTION" The goal of the mega-widget support of Perl/Tk is to make it easy to write mega-widgets that obey the same protocol and interface that the Tk core widgets support. \&\fIFor mega-widget sample code please run the \f(BIwidget\fI demonstration program and go to the section \f(BISample Perl Mega-Widgets\fI.\fR .PP There are two kinds of mega-widgets: .IP "\(bu" 4 Composite Widgets .Sp A composite widget is composed with one or more existing widgets. The composite widget looks to the user like a simple single widget. A well known example is the file selection box. .IP "\(bu" 4 Derived Widgets .Sp A derived widget adds/modifies/removes properties and methods from a single widget (this widget may itself be a mega-widget). .SH "MEGA-WIDGET SUPPORT" .IX Header "MEGA-WIDGET SUPPORT" .SS "Advertise" .IX Subsection "Advertise" Give a subwidget a symbolic name. .PP Usage: .PP     \fI\f(CI$self\fI\fR\->\fBAdvertise\fR(\fBname\fR=>\fI\f(CI$widget\fI\fR); .PP Gives a subwidget \fI\f(CI$widget\fI\fR of the mega-widget \fI\f(CI$self\fI\fR the name \fBname\fR. One can retrieve the reference of an advertised subwidget with the Subwidget method. .PP \&\fBComment:\fR Mega-Widget Writers: Please make sure to document the advertised widgets that are intended for \fIpublic\fR use. If there are none, document this fact, e.g.: .PP .Vb 1 \& =head1 ADVERTISED WIDGETS \& \& None. .Ve .SS "Callback" .IX Subsection "Callback" Invoke a callback specified with an option. .PP Usage: .PP     \fI\f(CI$self\fI\fR\->\fBCallback\fR(\fI\-option\fR ?,\fIargs\fR ...?); .PP \&\fBCallback\fR executes the callback defined with \&\fI\f(CI$self\fI\fR\->\fBConfigSpecs\fR(\fI\-option\fR, [\fB\s-1CALLBACK\s0\fR, ...]); If \fIargs\fR are given they are passed to the callback. If \&\fI\-option\fR is not defined it does nothing. .SS "ClassInit" .IX Subsection "ClassInit" Initialization of the mega-widget class. .PP Usage: .PP     \fBsub ClassInit\fR { \fImy ($class, \f(CI$mw\fI) = \f(CI@_\fI;\fR ... } .PP \&\fBClassInit\fR is called once for \fIeach\fR MainWindow just before the first widget instance of a class is created in the widget tree of \fBMainWindow\fR. .PP \&\fBClassInit\fR is often used to define bindings and/or other resources shared by all instances, e.g., images. .PP Examples: .PP .Vb 3 \& $mw\->bind($class,"", sub { my $w = shift; $w\->Insert("\et"); $w\->focus; $w\->break}); \& $mw\->bind($class,"", [\*(AqInsert\*(Aq,"\en"]); \& $mw\->bind($class,"",\*(AqDelete\*(Aq); .Ve .PP Notice that \fI\f(CI$class\fI\fR is the class name (e.g. \fBTk::MyText\fR) and \fI\f(CI$mw\fI\fR is the mainwindow. .PP Don't forget to call \fI\f(CI$class\fI\fR\->\fBSUPER::ClassInit($mw)\fR in \&\fBClassInit\fR. .SS "Component" .IX Subsection "Component" Convenience function to create subwidgets. .PP Usage: .PP .Vb 4 \& $cw\->Component(\*(AqWhatever\*(Aq, \*(AqAdvertisedName\*(Aq, \& \-delegate => [\*(Aqmethod1\*(Aq, \*(Aqmethod2\*(Aq, ...], \& ... more widget options ..., \& ); .Ve .PP \&\fBComponent\fR does several things for you with one call: .Sp .RS 4 o Creates the widget .Sp o Advertises it with a given name (overridden by 'Name' option) .Sp o Delegates a set of methods to this widget (optional) .RE .PP Example: .PP .Vb 1 \& $cw\->Component(\*(AqButton\*(Aq, \*(AqquitButton\*(Aq, \-command => sub{$mw\->\*(Aqdestroy\*(Aq}); .Ve .SS "ConfigSpecs" .IX Subsection "ConfigSpecs" Defines options and their treatment .PP Usage: .PP .Vb 5 \& $cw\->ConfigSpecs( \& \-option => [ where, dbname, dbclass, default], \& ..., \& DEFAULT => [where], \& ); .Ve .PP Defines the options of a mega-widget and what actions are triggered by configure/cget of an option (see Tk::ConfigSpecs and Tk::Derived for details). .SS "Construct" .IX Subsection "Construct" Make the new mega-widget known to \fBTk\fR. .PP Usage: .PP     \fBConstruct\fR \fIbaseclass\fR \fB'Name'\fR; .PP \&\fBConstruct\fR declares the new widget class so that your mega-widget works like normal Perl/Tk widgets. .PP Examples: .PP     \fBConstruct Tk::Widget\fR \fI'Whatever'\fR;     \fBConstruct Tk::Menu\fR \fI'MyItem'\fR; .PP First example lets one use \fI\f(CI$widget\fI\fR\->\fBWhatever\fR to create new \fBWhatever\fR widget. .PP The second example restricts the usage of the \fBMyItem\fR constructor method to widgets that are derived from \fBMenu\fR: \&\fI\f(CI$isamenu\fI\fR\->\fIMyItem\fR. .SS "CreateArgs" .IX Subsection "CreateArgs" Process options before any widget is created: .PP     \fBsub CreateArgs\fR { \fImy ($package, \f(CI$parent\fI, \f(CI$args\fI) = \f(CI@_\fI; ...; return \f(CI@newargs\fI;\fR } .PP \&\fI\f(CI$package\fI\fR is the package of the mega-widget (e.g., \fBTk::MyText\fR, \&\fI\f(CI$parent\fI\fR the parent of the widget to be created and \f(CW$args\fR the hash reference to the options specified in the widget constructor call. .PP Don't forget to call \fI\f(CI$package\fI\fR\->\fBSUPER::CreateArgs\fR(\fI\f(CI$parent\fI\fR, \fI\f(CI$args\fI\fR) in \&\fBCreateArgs\fR. .SS "Delegates" .IX Subsection "Delegates" Redirect a method of the mega-widget to a subwidget of the composite widget .PP Usage: .PP .Vb 7 \& $cw\->Delegates( \& \*(Aqmethod1\*(Aq => $subwidget1, \& \*(Aqmethod2\*(Aq => \*(Aqadvertived_name\*(Aq, \& ..., \& \*(AqConstruct\*(Aq => $subwidget2, \& \*(AqDEFAULT\*(Aq => $subwidget3, \& ); .Ve .PP The \fB'Construct'\fR delegation has a special meaning. After \&'Construct' is delegated all Widget constructors are redirected. E.g. after .PP     \fI\f(CI$self\fI\fR\->\fBDelegates\fR(\fB'Construct'\fR=>\fI\f(CI$subframe\fI\fR); .PP a \fI\f(CI$self\fI\fR\->\fBButton\fR does really a \fI\f(CI$subframe\fI\fR\->\fBButton\fR so the created button is a child of \fI\f(CI$subframe\fI\fR and not \fI\f(CI$self\fI\fR. .PP \&\fBComment:\fR Delegates works only with methods that \fI\f(CI$cw\fI\fR does not have itself. .SS "InitObject" .IX Subsection "InitObject" \&\fINote: this method should not, in general, be used, as it has been superceeded by \f(BIPopulate\fI and specifying \f(BITk::Derived\fI as one of the base classes.\fR .PP Defines construction and interface of derived widgets. .PP Usage: .PP .Vb 4 \& sub InitObject { \& my ($derived, $args) = @_; \& ... \& } .Ve .PP where \fI\f(CI$derived\fI\fR is the widget reference of the already created baseclass widget and \fI\f(CI$args\fI\fR is the reference to a hash of \&\fI\-option\-value\fR pairs. .PP \&\fBInitObject\fR is almost identical to Populate method. \&\fBPopulate\fR does some more 'magic' things useful for mega-widgets with several widgets. .PP Don't forget to call \fI\f(CI$derived\fI\fR\->\fBSUPER::InitObject\fR(\fI\f(CI$args\fI\fR) in \&\fBInitObject\fR. .SS "OnDestroy" .IX Subsection "OnDestroy" Define a callback invoked when the mega-widget is destroyed. .PP Usage: .PP     \fI\f(CI$widget\fI\fR\->\fBOnDestroy\fR(\fIcallback\fR); .PP \&\fBOnDestroy\fR installs a callback that's called when a widget is going to to be destroyed. Useful for special cleanup actions. It differs from a normal \fBdestroy\fR in that all the widget's data structures are still intact. .PP \&\fBComment:\fR This method could be used with any widgets not just for mega-widgets. It's listed here because of its usefulness. .SS "Populate" .IX Subsection "Populate" Defines construction and interface of the composite widget. .PP Usage: .PP .Vb 4 \& sub Populate { \& my ($self, $args) = @_; \& ... \& } .Ve .PP where \fI\f(CI$self\fI\fR is the widget reference of the already created baseclass widget and \fI\f(CI$args\fI\fR is the reference to a hash of \fI\-option\-value\fR pairs. .PP Most the other support function are normally used inside the \fBPopulate\fR subroutine. .PP Don't forget to call \fI\f(CI$cw\fI\fR\->\fBSUPER::Populate\fR(\fI\f(CI$args\fI\fR) in \&\fBPopulate\fR. .SS "privateData" .IX Subsection "privateData" Set/get a private hash of a widget to storage composite internal data .PP Usage: .PP     \fI\f(CI$hashref\fI\fR = \fI\f(CI$self\fI\fR\->\fBprivateData\fR(); .PP     \fI\f(CI$another\fI\fR = \fI\f(CI$self\fI\fR\->\fBprivateData\fR(\fIunique_key\fR|\fIpackage\fR); .SS "Subwidget" .IX Subsection "Subwidget" Get the widget reference of an advertised subwidget. .PP     \fI\f(CI@subwidget\fI\fR = \fI\f(CI$cw\fI\fR\->\fBSubwidget\fR(); .PP     \fI\f(CI$subwidget\fI\fR = \fI\f(CI$cw\fI\fR\->\fBSubwidget\fR(\fIname\fR); .PP     \fI\f(CI@subwidget\fI\fR = \fI\f(CI$cw\fI\fR\->\fBSubwidget\fR(\fIname\fR ?,...?); .PP Returns the widget reference(s) of the subwidget known under the given name(s). Without arguments, return all known subwidgets of \fI\f(CI$cw\fI\fR. See Advertise method how to define \fIname\fR for a subwidget. .PP \&\fBComment:\fR Mega-Widget Users: Use \fBSubwidget\fR to get \fIonly\fR documented subwidgets. .SH "PITFALLS" .IX Header "PITFALLS" .IP "\(bu" 4 Resource \s-1DB\s0 class name .Sp Some of the standard options use a resource date base class that is not equal to the resource database name. E.g., .Sp .Vb 1 \& Switch: Name: Class: \& \& \-padx padX Pad \& \-activerelief activeRelief Relief \& \-activebackground activeBackground Foreground \& \-status undef undef .Ve .Sp One should do the same when one defines one of these options via \fBConfigSpecs\fR. .IP "\(bu" 4 Method delegation .Sp Redirecting methods to a subwidget with \fBDelegate\fR can only work if the base widget itself does have a method with this name. Therefore one can't ``\fIdelegate\fR'' any of the methods listed in Tk::Widget. A common problematic method is \fBbind\fR. In this case one as to explicitly redirect the method. .Sp .Vb 5 \& sub bind { \& my $self = shift; \& my $to = $self\->privateData\->{\*(Aqmy_bind_target\*(Aq}; \& $to\->bind(@_); \& } .Ve .IP "\(bu" 4 privateData .Sp Graham Barr wrote: ... It is probably more private than most people think. Not all calls to privateData will return that same \s-1HASH\s0 reference. The \s-1HASH\s0 reference that is returned depends on the package it was called from, a different \s-1HASH\s0 is returned for each package. This allows a widget to hold private data, but then if it is sub-classed the sub-class will get a different \s-1HASH\s0 and so not cause duplicate name clashes. .Sp But privateData does take an optional argument if you want to force which \s-1HASH\s0 is returned. .IP "\(bu" 4 Scrolled and Composite .Sp \&\fBScrolled\fR(\fIKind\fR,...) constructor can not be used with \fBComposite\fR. One has to use \f(CW$cw\fR\->\fBComposite\fR(\fBScrl\fR\fIKind\fR => \fB'name'\fR, ...); .SH "MISSING" .IX Header "MISSING" Of course Perl/Tk does not define support function for all necessities. Here's a short list of things you have to handle yourself: .IP "\(bu" 4 No support to define construction-time only options. .IP "\(bu" 4 No support to remove an option that is known to the base widget. .IP "\(bu" 4 It's hard to define \fBundef\fR as fallback for an widget option that is not already \fBundef\fR. .IP "\(bu" 4 Frame in Perl/Tk carries magic and overhead not needed for composite widget class definition. .IP "\(bu" 4 No support methods for bindings that are shared between all widgets of a composite widget (makes sense at all?) .SH "KEYWORDS" .IX Header "KEYWORDS" mega, composite, derived, widget .SH "SEE ALSO" .IX Header "SEE ALSO" Tk::composite Tk::ConfigSpecs Tk::option Tk::callbacks Tk::bind