home *** CD-ROM | disk | FTP | other *** search
-
- <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>
-