.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.28) .\" .\" 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 turned on, 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 .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "mega 3pm" .TH mega 3pm "2014-10-14" "perl v5.20.1" "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 it's 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