NAME¶
Tk::composite - Defining a new composite widget class
SYNOPSIS¶
package Tk::MyNewWidget;
use Tk::widgets qw/ list of Tk widgets /;
use base qw/ Tk::Frame /; # or Tk::Toplevel
Construct Tk::Widget 'MyNewWidget';
sub ClassInit {
my( $class, $mw ) = @_;
#... e.g., class bindings here ...
$class->SUPER::ClassInit( $mw );
}
sub Populate {
my( $self, $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 $self->configure( -flag => xxx );
}
$self->SUPER::Populate( $args );
$self = $self->Component( ... );
$self->Delegates( ... );
$self->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( $self, $value) = @_;
if ( @_ > 1 ) {
# set it
}
return # current value
}
1;
__END__
=head1 NAME
Tk::Whatever - a whatever widget
=head1 SYNOPSIS
use Tk::Whatever;
$widget = $parent->Whatever(...);
=head1 DESCRIPTION
...
DESCRIPTION¶
The intention behind a composite is to create a higher-level widget, sometimes
called a "super-widget" or "mega-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 consistd in creating subwidgets,
arranging to dispatch configure options to the proper subwidgets and manage
composite-specific configure options.
GLORY DETAILS¶
Depending on your Perl/Tk knowledge this section may be enlighting or confusing.
Since Perl/Tk is heavilly using an object-oriented approach, it is no suprise
that creating a composite goes through a
new()
method. However, the composite does not normally define a
new() method itself: it is usually sufficient to
simply inherit it from
Tk::Widget.
This is what happens when the composite uses
use base qw/ Tk::Frame /; # or Tk::Toplevel
to specify its inheritance chain. To complete the initialisation 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 'MyNewWidget';
Here,
MyNewWidget is the package name (aka the widget's
class).
This will define a constructor method for
MyNewWidget, normally named
after the widget's class. Instanciating that composite in client code would
the look like:
$mw = MainWindow->new; # creates a top-level MainWindow
$self = $mw->MyNewWidget(); # creates an instance of the
# composite widget MyNewWidget
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
$self->Populate(\%args);
where
%args is the arguments passed to the widget's
constructor. Note that
Populate receives a
reference to the hash
array containing all arguments.
Populate is typically defined in the composite class (package), which
creates the characteristic subwidgets of the class.
Subwidget creation happens usually in
Populate().
The composite usually calls the subwidget's constructor method either
directly, for "private" subwidgets, or indirectly through the
Component method for subwidgets that should be advertised 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(...).
Populate should also call
ConfigSpecs() to
specify the way that configure-like options should be handled in the
composite. Once
Populate returns, method
Tk::Frame::ConfigDefault walks through the
ConfigSpecs entries
and populates %$args hash with defaults for options from X resources (
.Xdefaults, etc).
When
Populate returns to
Tk::Widget::new(), a
call to
$self->
configure(%$args) is made which
sets *all* the options.
SEE ALSO¶
Tk::ConfigSpecs Tk::mega Tk::Derived