composite(3)
NAME
Tk::composite - Defining a new composite widget class
SYNOPSIS
package Tk::Whatever;
require Tk::Derived;
require Tk::Frame; # or Tk::Toplevel
@ISA = qw(Tk::Derived Tk::Frame)'; # or Tk::Toplevel
Construct Tk::Widget 'Whatever';
sub ClassInit
{
my ($class,$mw) = @_;
#... e.g., class bindings here ...
$class->SUPER::ClassInit($mw);
}
sub Populate
{
my ($cw,$args) = @_;
my $flag = delete $args->{-flag};
if (defined $flag)
{
# handle -flag => xxx which can only be done at
create
# time the delete above ensures that new() does not
try
# and do $cw->configure(-flag => xxx);
}
$cw->SUPER::Populate($args);
$w = $cw->Component(...);
$cw->Delegates(...);
$cw->ConfigSpecs(
'-cursor' => [SELF,'cursor','Cursor',undef],
'-something' => [METHOD,dbName,dbClass,'default'],
'-text' => [$label,dbName,dbClass,'default'],
'-heading' => [{-text=>$head},
heading,Heading,'My Heading'],
);
}
sub something
{
my ($cw,$value) = @_;
if (@_ > 1)
{
# set it
}
return # current value
}
1;
__END__
# Anything not documented is *private* - your POD is
god, so to speak.
=head1 NAME
Tk::Whatever - a whatever widget
=head1 SYNOPSIS
use Tk::Whatever;
$widget = $parent->Whatever(...);
=head1 DESCRIPTION
You forgot to document your widget, didn't you? :-)
...
DESCRIPTION
The intention behind a composite is to create a higherlevel widget, sometimes called a "super-widget" or
"meta-widget". Most often, a composite will be built upon
other widgets by using them, as opposed to specializing on
them. For example, the supplied composite widget LabEntry
is made of an Entry and a Label; it is neither a kind-of
Label nor is it a kind-of Entry.
Most of the work of a composite widget consist in creating
subwidgets, arrange to dispatch configure options to the
proper subwidgets and manage composite-specific configure
options.
GLORY DETAILS
Depending on your perl/Tk knowledget this section may be
enlighting or confusing.
Composite Widget
Since perl/Tk is heavilly using an object-oriented
approach, it is no suprise that creating a composite goes
through a nneeww(()) method. However, the composite does not
normally define a nneeww(()) method itself: it is usually suf
ficient to simply inherit it from Tk::Widget.
- This is what happens when the composite use
- @ISA = qw(Tk::Frame); # or Tk::Toplevel
- to specify its inheritance chain. To complete the ini
tialisation of the widget, it must call the Construct method from class Widget. That method accepts the name of the new class to create, i.e. the package name of your
composite widget:
Construct Tk::Widget 'Whatever';- Here, Whatever is the package name (aka the widget's
class). This will define a constructor method for What ever, normally named after the widget's class. Instanci
ating that composite in client code would the look like:
$mw = MainWindow->new(); # Creates a top-level main- window
- $cw = $mw->Whatever(); # Creates an instance of
- the
# composite widget Whatever
- Whenever a composite is instanciated in client code,
"Tk::Widget::new()" will be invoked via the widget's class
constructor. That new method will call
$cw->InitObject(args);- where %args is the arguments passed to the widget's con
structor. Note that InitObject receives a reference to the hash array containing all arguments. - For composite widgets that needs an underlying frame, Ini
tObject will typically be inherited from Tk::Frame, that is, no method of this name will appear in the composite
package. For composites that don't need a frame, InitOb
ject will typically be defined in the composite class
(package). Compare the LabEntry composite with Option menu: the former is Frame based while the latter is Widget based. - In Frame based composites, TTkk::::FFrraammee::::IInniittOObbjjeecctt(()) will call PPooppuullaattee(()), which should be defined to create the characteristic subwidgets of the class.
- Widget based composites don't need an extra Populate layer; they typically have their own InitObject method that will create subwidgets.
- Creating Subwidgets
- Subwidget creation happens usually in PPooppuullaattee(()) (Frame
based) or IInniittOObbjjeecctt(()) (Widget based). The composite usu
ally calls the subwidget's constructor method either
directly, for "private" subwidgets, or indirectly through
the Component method for subwidgets that should be adver tised to clients. - Populate may call Delegates to direct calls to methods of
chosen subwidgets. For simple composites, typically most
if not all methods are directed to a single subwidget e.g. ScrListbox directs all methods to the core Listbox so that $composite->get(...) calls $listbox->get(...). - Further steps for Frame based composites
- Populate should also call CCoonnffiiggSSppeeccss(()) to specify the way
that configure-like options should be handled in the com
posite. Once Populate returns, method Tk::Frame::Con figDefault walks through the ConfigSpecs entries and popu lates %$args hash with defaults for options from X
resources (.Xdefaults, etc). - When IInniittOObbjjeecctt(()) returns to TTkk::::WWiiddggeett::::nneeww(()), a call to $cw->configure(%$args) is made which sets *all* the options.
SEE ALSO
- Tk::ConfigSpecs Tk::Derived