home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2000 May
/
Chip_2000-05_cd1.bin
/
zkuste
/
Perl
/
ActivePerl-5.6.0.613.msi
/
䆊䌷䈹䈙䏵-䞅䞆䞀㡆䞃䄦䠥
/
_5c62b4551a18243e2b820c9033ca738d
< prev
next >
Wrap
Text File
|
2000-03-23
|
9KB
|
226 lines
<HTML>
<HEAD>
<TITLE>Tk::composite - Defining a new composite widget class</TITLE>
<LINK REL="stylesheet" HREF="../../../Active.css" TYPE="text/css">
<LINK REV="made" HREF="mailto:">
</HEAD>
<BODY>
<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=100%>
<TR><TD CLASS=block VALIGN=MIDDLE WIDTH=100% BGCOLOR="#cccccc">
<STRONG><P CLASS=block> Tk::composite - Defining a new composite widget class</P></STRONG>
</TD></TR>
</TABLE>
<A NAME="__index__"></A>
<!-- INDEX BEGIN -->
<UL>
<LI><A HREF="#name">NAME</A></LI><LI><A HREF="#supportedplatforms">SUPPORTED PLATFORMS</A></LI>
<LI><A HREF="#synopsis">SYNOPSIS</A></LI>
<LI><A HREF="#description">DESCRIPTION</A></LI>
<LI><A HREF="#glory details">GLORY DETAILS</A></LI>
<UL>
<LI><A HREF="#composite widget">Composite Widget</A></LI>
<LI><A HREF="#creating subwidgets">Creating Subwidgets</A></LI>
<LI><A HREF="#further steps for frame based composites">Further steps for Frame based composites</A></LI>
</UL>
<LI><A HREF="#see also">SEE ALSO</A></LI>
</UL>
<!-- INDEX END -->
<HR>
<P>
<H1><A NAME="name">NAME</A></H1>
<P>Tk::composite - Defining a new composite widget class</P>
<P>
<HR>
<H1><A NAME="supportedplatforms">SUPPORTED PLATFORMS</A></H1>
<UL>
<LI>Linux</LI>
<LI>Solaris</LI>
<LI>Windows</LI>
</UL>
<HR>
<H1><A NAME="synopsis">SYNOPSIS</A></H1>
<PRE>
package Tk::Whatever;</PRE>
<PRE>
require Tk::Derived;
require Tk::Frame; # or Tk::Toplevel
@ISA = qw(Tk::Derived Tk::Frame)'; # or Tk::Toplevel</PRE>
<PRE>
Construct Tk::Widget 'Whatever';</PRE>
<PRE>
sub ClassInit
{
my ($class,$mw) = @_;</PRE>
<PRE>
#... e.g., class bindings here ...
$class->SUPER::ClassInit($mw);
}</PRE>
<PRE>
sub Populate
{
my ($cw,$args) = @_;</PRE>
<PRE>
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);
}</PRE>
<PRE>
$cw->SUPER::Populate($args);</PRE>
<PRE>
$w = $cw->Component(...);</PRE>
<PRE>
$cw->Delegates(...);</PRE>
<PRE>
$cw->ConfigSpecs(
'-cursor' => [SELF,'cursor','Cursor',undef],
'-something' => [METHOD,dbName,dbClass,'default'],
'-text' => [$label,dbName,dbClass,'default'],
'-heading' => [{-text=>$head},
heading,Heading,'My Heading'],
);
}</PRE>
<PRE>
sub something
{
my ($cw,$value) = @_;
if (@_ > 1)
{
# set it
}
return # current value
}</PRE>
<PRE>
1;</PRE>
<PRE>
__END__</PRE>
<PRE>
# Anything not documented is *private* - your POD is god, so to speak.</PRE>
<PRE>
=head1 NAME</PRE>
<PRE>
Tk::Whatever - a whatever widget</PRE>
<PRE>
=head1 SYNOPSIS</PRE>
<PRE>
use Tk::Whatever;</PRE>
<PRE>
$widget = $parent->Whatever(...);</PRE>
<PRE>
=head1 DESCRIPTION</PRE>
<PRE>
You forgot to document your widget, didn't you? :-)</PRE>
<PRE>
...</PRE>
<P>
<HR>
<H1><A NAME="description">DESCRIPTION</A></H1>
<P>The intention behind a composite is to create a higher-level widget,
sometimes called a ``super-widget'' or ``meta-widget''. Most often,
a composite will be
built upon other widgets by <STRONG>using</STRONG> them, as opposed to specializing on them.
For example, the supplied composite widget <STRONG>LabEntry</STRONG> is <EM>made of</EM> an
<STRONG>Entry</STRONG> and a <STRONG>Label</STRONG>; it is neither a <EM>kind-of</EM> <STRONG>Label</STRONG>
nor is it a <EM>kind-of</EM> <STRONG>Entry</STRONG>.</P>
<P>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.</P>
<P>
<HR>
<H1><A NAME="glory details">GLORY DETAILS</A></H1>
<P>Depending on your perl/Tk knowledget this section may be enlighting
or confusing.</P>
<P>
<H2><A NAME="composite widget">Composite Widget</A></H2>
<P>Since perl/Tk is heavilly using an object-oriented approach, it is no
suprise that creating a composite goes through a <STRONG>new()</STRONG> method.
However, the composite does not normally define a <STRONG>new()</STRONG> method
itself: it is usually sufficient to simply inherit it from
<STRONG>Tk::Widget</STRONG>.</P>
<P>This is what happens when the composite use</P>
<PRE>
@ISA = qw(Tk::Frame); # or Tk::Toplevel</PRE>
<P>to specify its inheritance chain. To complete the initialisation of the
widget, it must call the <STRONG>Construct</STRONG> method from class <STRONG>Widget</STRONG>. That
method accepts the name of the new class to create, i.e. the package name
of your composite widget:</P>
<PRE>
Construct Tk::Widget 'Whatever';</PRE>
<P>Here, <STRONG>Whatever</STRONG> is the package name (aka the widget's <STRONG>class</STRONG>). This
will define a constructor method for <STRONG>Whatever</STRONG>, normally named after the
widget's class. Instanciating that composite in client code would
the look like:</P>
<PRE>
$mw = MainWindow->new(); # Creates a top-level main window</PRE>
<PRE>
$cw = $mw->Whatever(); # Creates an instance of the
# composite widget Whatever</PRE>
<P>Whenever a composite is instanciated in client code,
<CODE>Tk::Widget::new()</CODE> will be invoked via the widget's class
constructor. That <STRONG>new</STRONG> method will call</P>
<PRE>
$cw->InitObject(\%args);</PRE>
<P>where <EM>%args</EM> is the arguments passed to the widget's constructor. Note
that <STRONG>InitObject</STRONG> receives a <STRONG>reference</STRONG> to the hash array
containing all arguments.</P>
<P>For composite widgets that needs an underlying frame, <STRONG>InitObject</STRONG>
will typically be inherited from <STRONG>Tk::Frame</STRONG>, that is, no method of
this name will appear in the composite package. For composites that
don't need a frame, <STRONG>InitObject</STRONG> will typically be defined in the
composite class (package). Compare the <STRONG>LabEntry</STRONG> composite with
<STRONG>Optionmenu</STRONG>: the former is <STRONG>Frame</STRONG> based while the latter is <STRONG>Widget</STRONG>
based.</P>
<P>In <STRONG>Frame</STRONG> based composites, <STRONG>Tk::Frame::InitObject()</STRONG> will call
<STRONG>Populate()</STRONG>, which should be defined to create the characteristic
subwidgets of the class.</P>
<P><STRONG>Widget</STRONG> based composites don't need an extra <STRONG>Populate</STRONG> layer; they
typically have their own <STRONG>InitObject</STRONG> method that will create subwidgets.</P>
<P>
<H2><A NAME="creating subwidgets">Creating Subwidgets</A></H2>
<P>Subwidget creation happens usually in <STRONG>Populate()</STRONG> (<STRONG>Frame</STRONG> based)
or <STRONG>InitObject()</STRONG> (<STRONG>Widget</STRONG> based). The composite usually calls the
subwidget's constructor method either directly, for ``private'' subwidgets,
or indirectly through the <STRONG>Component</STRONG> method for subwidgets that should
be advertised to clients.</P>
<P><STRONG>Populate</STRONG> may call <STRONG>Delegates</STRONG> 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. <STRONG>ScrListbox</STRONG> directs all methods to the core
<STRONG>Listbox</STRONG> so that <EM>$composite</EM>-><STRONG>get</STRONG>(...) calls
<EM>$listbox</EM>-><STRONG>get</STRONG>(...).</P>
<P>
<H2><A NAME="further steps for frame based composites">Further steps for Frame based composites</A></H2>
<P><STRONG>Populate</STRONG> should also call <STRONG>ConfigSpecs()</STRONG> to specify the
way that configure-like options should be handled in the composite.
Once <STRONG>Populate</STRONG> returns, method <STRONG>Tk::Frame::ConfigDefault</STRONG>
walks through the <STRONG>ConfigSpecs</STRONG> entries and populates
%$args hash with defaults for options from X resources (<EM>.Xdefaults</EM>, etc).</P>
<P>When <STRONG>InitObject()</STRONG> returns to <STRONG>Tk::Widget::new()</STRONG>,
a call to <STRONG>$cw</STRONG>-><EM>configure</EM>(%$args) is made which sets *all*
the options.</P>
<P>
<HR>
<H1><A NAME="see also">SEE ALSO</A></H1>
<P><A HREF="../../../Tk/ConfigSpecs.html">Tk::ConfigSpecs</A>
<A HREF="../../../site/lib/Tk/Derived.html">Tk::Derived</A></P>
<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=100%>
<TR><TD CLASS=block VALIGN=MIDDLE WIDTH=100% BGCOLOR="#cccccc">
<STRONG><P CLASS=block> Tk::composite - Defining a new composite widget class</P></STRONG>
</TD></TR>
</TABLE>
</BODY>
</HTML>