summaryrefslogtreecommitdiff
path: root/documentation/subclassing.html
diff options
context:
space:
mode:
authorMichael R Sweet <michael.r.sweet@gmail.com>1999-01-07 16:36:11 +0000
committerMichael R Sweet <michael.r.sweet@gmail.com>1999-01-07 16:36:11 +0000
commit367f908d8ed5a3464b9676223a26ddf4e11bdb5b (patch)
tree2b0ec583852973ccf7b9804957e78d474e0e7e5d /documentation/subclassing.html
parent85e6f449590eeb6e09f7547733adf4c7137470d0 (diff)
"Final" changes for first draft of 1.0 documentation.
git-svn-id: file:///fltk/svn/fltk/trunk@187 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'documentation/subclassing.html')
-rw-r--r--documentation/subclassing.html668
1 files changed, 303 insertions, 365 deletions
diff --git a/documentation/subclassing.html b/documentation/subclassing.html
index 414cca67b..7ed03ed7a 100644
--- a/documentation/subclassing.html
+++ b/documentation/subclassing.html
@@ -1,427 +1,338 @@
<HTML>
<BODY>
-<H1 ALIGN=RIGHT><A NAME="subclassing">5 - Adding and Extending Widgets</A></H1>
+<H1 ALIGN=RIGHT><A NAME="subclassing">7 - Adding and Extending Widgets</A></H1>
-This chapter describes how to add your own widgets or extend existing widgets in FLTK.
+This chapter describes how to add your own widgets or extend existing
+widgets in FLTK.
<H2>Subclassing</H2>
-<H2>Adding Syntax Highlighting to the Fl_Input Widget</H2>
+New widgets are created by <i>subclassing</i> an existing FLTK widget,
+typically <tt>Fl_Widget</tt> for controls and <tt>Fl_Group</tt> for
+containers.
-<H2>Drawing Functions</H2>
+<p>A control widget typically interacts with the user to receive and/or
+display a value of some sort.
-<H3>Lines, Rectangles, and Curves, Oh, My!</H3>
+<p>A container widget holds a list of child widgets and handles moving,
+sizing, showing, or hiding them as needed. <tt>Fl_Group</tt> is the
+main container widget class in FLTK, and all of the other containers
+(<tt>Fl_Pack</tt>, <tt>Fl_Scroll</tt>, <tt>Fl_Tabs</tt>, <tt>Fl_Tile</tt>,
+and <tt>Fl_Window</tt>) are subclasses of it.
-<H3>Colors</H3>
+<p>You can also subclass other existing widgets to provide a different look
+or user-interface. For example, the button widgets are all subclasses of
+<tt>Fl_Button</tt> since they all interact with the user via a mouse button
+click. The only difference is the code that draws the face of the button.
-<H3>Fonts</H3>
+<H2>Making a Subclass of Fl_Widget</H2>
-<H3>Images</H3>
+Your subclasses can directly descend from <tt>Fl_Widget</tt> or any
+subclass of <tt>Fl_Widget</tt>. <tt>Fl_Widget</tt> has only four
+virtual methods, and overriding some or all of these may be necessary.
-<H2><A NAME="Fl_Table">Writing a Table Widget</A></H2>
+<H2>The Constructor</H2>
-<H3>Methods</H3>
+The constructor should access the following arguments:
-<H3>Cut and Paste Support</H3>
-
-</BODY>
-</HTML>
-<title>Cut & paste</title>
-<h2>Cut & paste</h2>
-
-Fltk provides routines to cut and paste ASCII text (in the future this
-may be UTF-8) between applications. It may be possible to cut/paste
-non-ascii data under X by using <a
-href=events.html#add_handler>Fl::add_handler()</a>.
-
-</ul><h4><code>void Fl::paste(Fl_Widget *receiver)</code></h4><ul>
-
-<P>Set things up so the receiver widget will be called with an <a
-href=events.html#paste>FL_PASTE</a> event some time in the future.
-The reciever should be prepared to be called <i>directly</i> by this,
-or for it to happen <i>later</i>, or possibly <i>not at all</i>. This
-allows the window system to take as long as necessary to retrieve the
-paste buffer (or even to screw up completely) without complex and
-error-prone synchronization code in fltk.
+<ul><pre>
+MyClass(int x, int y, int w, int h, const char *label = 0);
+</pre></ul>
-</ul><h4><code>void Fl::selection(Fl_Widget *owner, const char *stuff, int len);
-</code></h4><ul>
+This will allow the class to be used in <a href="#fluid">Fluid</a> without
+problems.
-<p>Change the current selection. The block of text is copied to an
-internal buffer by Fltk (be careful if doing this in response to an
-FL_PASTE as this <i>may</i> be the same buffer returned by
-event_text()). The selection_owner is set to the passed owner
-(possibly sending FL_SELECTIONCLEAR to the previous owner).
+<p>The constructor must call the constructor for the base class and
+pass the same arguments:
-</ul><h4><code>const char* Fl::selection();
-<br>int Fl::selection_length();</code></h4><ul>
+<ul><pre>
+MyClass::MyClass(int x, int y, int w, int h, const char *label)
+: Fl_Widget(x, y, w, h, label) {
+// do initialization stuff...
+}
+</pre></ul>
-You can look at the buffer containing the current selection. Contents
-of this buffer are undefined if this program does not own the X
-selection.
+<tt>Fl_Widget</tt>'s protected constructor sets <tt>x()</tt>,
+<tt>y()</tt>, <tt>w()</tt>, <tt>h()</tt>, and <tt>label()</tt> to the
+passed values and initializes the other instance variables to:
+
+<ul><pre>
+type(0);
+box(FL_NO_BOX);
+color(FL_GRAY);
+selection_color(FL_GRAY);
+labeltype(FL_NORMAL_LABEL);
+labelstyle(FL_NORMAL_STYLE);
+labelsize(FL_NORMAL_SIZE);
+labelcolor(FL_BLACK);
+align(FL_ALIGN_CENTER);
+callback(default_callback,0);
+flags(ACTIVE|VISIBLE);
+</pre></ul>
-</ul><h4><code>Fl_Widget *Fl::selection_owner() const;
-<br>void Fl::selection_owner(Fl_Widget *);</code></h4><ul>
+<H2>Protected Methods of Fl_Widget</H2>
-<p>The single-argument selection_owner(x) call can be used to move the
-selection to another widget or to set the owner to NULL, without
-changing the actual text of the selection. FL_SELECTIONCLEAR is sent
-to the old selection owner, if any.
+The following methods are provided for subclasses to use:
+<ul>
+ <li><a name="#clear_visible">clear_visible</a>
+ <li><a name="#damage">damage</a>
+ <li><a name="#draw_box">draw_box</a>
+ <li><a name="#draw_label">draw_label</a>
+ <li><a name="#set_flag">set_flag</a>
+ <li><a name="#set_visible">set_visible</a>
+ <li><a name="#test_shortcut">test_shortcut</a>
+ <li><a name="#type">type</a>
</ul>
-<p><i>Copying the buffer every time the selection is changed is
-obviously wasteful, especially for large selections. I expect an
-interface will be added in a future version to allow the selection to
-be made by a callback function. The current interface will be
-emulated on top of this.</i>
+<H3><a name="damage">void Fl_Widget::damage(uchar mask)<br>
+void Fl_Widget::damage(uchar mask, int x, int y, int w, int h)<br>
+uchar Fl_Widget::damage()</a></H3>
-<title>Making a subclass of Fl_Widget</title>
-</ul><h2>Making a subclass of Fl_Widget</h2>
+The first form indicates that a partial update of the object is
+needed. The bits in mask are OR'd into <tt>damage()</tt>. Your
+<tt>draw()</tt> routine can examine these bits to limit what it is
+drawing. The public method <tt>Fl_Widget::redraw()</tt> simply does
+<tt>Fl_Widget::damage(FL_DAMAGE_ALL)</tt>.
-<p>Your subclasses can directly descend from Fl_Widget or any
-subclass of Fl_Widget. Fl_Widget has only four virtual methods, and
-overriding some or all of these may be necessary.
+<p>The second form indicates that a region is damaged. If only these
+calls are done in a window (no calls to <tt>damage(n)</tt>) then FLTK
+will clip to the union of all these calls before drawing anything.
+This can greatly speed up incremental displays. The mask bits are or'd
+into <tt>damage()</tt> unless this is a <tt>Fl_Window</tt> widget.
-<p>Parts of this document:
+<p>The third form returns the bitwise-OR of all <tt>damage(n)</tt>
+calls done since the last <tt>draw()</tt>. The public method
+<tt>redraw()</tt> does <tt>damage(FL_DAMAGE_ALL)</tt>, but the
+implementation of your widget can call the private <tt>damage(n)</tt>.
-<ul>
+<H3><a name="draw_box">void Fl_Widget::draw_box() const<br>
+</a>void Fl_Widget::draw_box(Fl_Boxtype b, ulong c) const</H3>
-<li><a href=#constructor>Constructing your Fl_Widget</a>
+The first form draws this widget's <tt>box()</tt>, using the dimensions
+of the widget.
-<li><a href=#protected>Protected methods of Fl_Widget</a>
+The second form uses <tt>b</tt> as the box type and <tt>c</tt> as the
+color for the box.
-<li>Virtual functions to override:
-
-<ul>
+<H3><a name="draw_label">void Fl_Widget::draw_label() const<br>
+void Fl_Widget::draw_label(int x, int y, int w, int h) const<br>
+void Fl_Widget::draw_label(int x, int y, int w, int h, Fl_Align align) const</a></H3>
-<li><code><a href=#handle>int Fl_Widget::handle(int
-event);</a></code>
-
-<li><code><a href=#draw>void Fl_Widget::draw();</a></code>
+This is the usual function for a <tt>draw()</tt> method to call to draw
+the widget's label. It does not draw the label if it is supposed to be
+outside the box (on the assumption that the enclosing group will draw
+those labels).
-<li><code><a href=#resize>void
-Fl_Widget::resize(int,int,int,int);</a></code>
+<p>The second form uses the passed bounding box instead of the widget's
+bounding box. This is useful so "centered" labels are aligned with some
+feature, such as a moving slider.
-<li><code><a href=#destructor>Fl_Widget::~Fl_Widget();</a></code>
+<p>The third form draws the label anywhere. It acts as though
+<tt>FL_ALIGN_INSIDE</tt> has been forced on, the label will appear
+inside the passed bounding box. This is designed for parent groups to
+draw labels with.
-</ul>
+<H3><a name="set_flag">void Fl_Widget::set_flag(SHORTCUT_LABEL)</a></H3>
-<li><a href=#composite>Making a Composite/Group Widget</a>
+If your constructor calls this it modifies <tt>draw_label()</tt> so
+that '&' characters cause an underscore to be printed under the next
+letter.
-<li><a href=#window>Making a subclass of Fl_Window</a>
+<H3><a name="set_visible">void Fl_Widget::set_visible()</a><br>
+<a name="clear_visible">void Fl_Widget::clear_visible()</a></H3>
-</ul>
+Fast inline versions of <tt>Fl_Widget::hide()</tt> and
+<tt>Fl_Widget::show()</tt>. These do not send the <tt>FL_HIDE</tt> and
+<tt>FL_SHOW</tt> events to the widget.
-<a name=constructor>
-<h2>Constructing your Fl_Widget</h2>
+<H3><a name="test_shortcut">int Fl_Widget::test_shortcut() const<br>
+static int Fl_Widget::test_shortcut(const char *s)</a></H3>
-I recommend your constructor be of this form:
+The first version tests <tt>Fl_Widget::label()</tt> against the current
+event (which should be a <tt>FL_SHORTCUT</tt> event). If the label
+contains a '&' character and the character after it matches the key
+press, this returns true. This returns false if the
+<tt>SHORTCUT_LABEL</tt> flag is off, if the label is <tt>NULL</tt> or
+does not have a '&' character in it, or if the keypress does not match
+the character.
-<p><pre>
- Class(int x, int y, int w, int h, const char* label = 0);
-</pre>
+<p>The second version lets you do this test against an arbitrary string.
-<p>This will allow the class name to be typed into <a
-href=fluid.html>fluid</a> and it will produce the correct call.
+<H3><a name="type">uchar Fl_Widget::type() const<br>
+void Fl_Widget::type(uchar t)</a></H3>
-<p>The constructor must call the constructor for the base class and
-pass the same arguments. Fl_Widget's protected constructor sets x(),
-y(), w(), h(), and label() to the passed values and initializes the
-other instance variables to:
-
-<p><pre>
- type(0);
- box(FL_NO_BOX);
- color(FL_GRAY);
- selection_color(FL_GRAY);
- labeltype(FL_NORMAL_LABEL);
- labelstyle(FL_NORMAL_STYLE);
- labelsize(FL_NORMAL_SIZE);
- labelcolor(FL_BLACK);
- align(FL_ALIGN_CENTER);
- callback(default_callback,0);
- flags(ACTIVE|VISIBLE);
-</pre>
-
-<a name=protected>
-<h2>Protected methods of Fl_Widget</h2>
-
-<p>These methods are provided for subclasses to use.
-
-</ul><h4><code>uchar Fl_Widget::type() const;
-<br>void Fl_Widget::type(uchar);
-</code></h4><ul>
-
-The property Fl_Widget::type() can return an arbitrary 8-bit
-identifier, and can be set with the protected method type(uchar).
-This value had to be provided for Forms compatability, but you can use
+The property <tt>Fl_Widget::type()</tt> can return an arbitrary 8-bit
+identifier, and can be set with the protected method <tt>type(uchar t)</tt>.
+This value had to be provided for Forms compatibility, but you can use
it for any purpose you want. Try to keep the value less than 100 to
not interfere with reserved values.
-<p>Fltk does not use RTTI (Run Time Typing Infomation), to enhance
+<p>FLTK does not use RTTI (Run Time Typing Infomation), to enhance
portability. But this may change in the near future if RTTI becomes
standard everywhere.
-<p>If you don't have RTTI you can use the clumsy fltk mechanisim, by
-having type() have a unique value. These unique values must be
-greater than the symbol FL_RESERVED_TYPE (which is 100). Grep through
-the header files for "FL_RESERVED_TYPE" to find an unused number. If
-you make a subclass of Fl_Group you must use FL_GROUP+n, and if you
-make a subclass of Fl_Window you must use FL_WINDOW+n (in both cases n
-is in the range 1-7).
-
-<a name=test_shortcut>
-</ul><h4><code>void Fl_Widget::set_flag(SHORTCUT_LABEL);</code></h4><ul>
-
-If your constructor calls this it modifies draw_label() so that '&'
-characters cause an underscore to be printed under the next letter.
-
-</ul><h4><code>int Fl_Widget::test_shortcut() const;<br>
-static int Fl_Widget::test_shortcut(const char *);</code></h4><ul>
-
-The first version tests Fl_Widget::label() against the current event
-(which should be a FL_SHORTCUT event). If the label contains a '&'
-character and the character after it matches the key press, this
-returns true. This returns false if the SHORTCUT_LABEL flag is off,
-if the label is null or does not have a '&' character in it, or if the
-keypress does not match the character.
-
-<p>The second version lets you do this test to an arbitrary string.
-
-</ul><h4><code>void Fl_Widget::x(short);
-<br>void Fl_Widget::y(short);
-<br>void Fl_Widget::w(short);
-<br>void Fl_Widget::h(short);</code></h4><ul>
-
-You can directly clobber the values for <a
-href=Fl_Widget.html#xywh>x(), y(), w(), and h()</a>. Make sure you
-know what you are doing. This is most useful for temporarily
-replacing the values before calling handle() or draw() on the base
-class to "fool" it into working in a different area.
-
-<a name=damage>
-</ul><h4><code>void Fl_Widget::damage(uchar mask);</code></h4><ul>
-
-Indicate that a partial update of the object is needed. The bits in
-mask are or'd into damage(). Your draw() routine can examine these
-bits to limit what it is drawing. The public method
-Fl_Widget::redraw() simply does Fl_Widget::damage(-1).
-
-</ul><h4><code>void Fl_Widget::damage(uchar mask,int x,int y,int w,int
-h);</code></h4><ul>
-
-Indicate that a region is damaged. If only these calls are done in a
-window (no calls to damage(n)) then fltk will clip to the union of all
-these calls before drawing anything. This can greatly speed up
-incremental displays. The mask bits are or'd into damage() (unless
-this is a Fl_Window, in which case they are forced to the value 6 for
-internal reasons).
-
-</ul><h4><code>void Fl_Widget::clear_damage(uchar value = 0);</code></h4><ul>
-
-Directly set damage() to the passed value. This is provided for
-kludges only.
-
-</ul><h4><code>uchar Fl_Widget::damage()</code></h4><ul>
-
-Return the bitwise-or of all damage(n) calls done since the last
-draw(). The public method redraw() does damage(-1), but the
-implementation of your widget can call the private damage(n).
-
-</ul><h4><code>void Fl_Widget::set_visible();
-<br>void Fl_Widget::clear_visible();</code></h4><ul>
-
-Fast inline versions of Fl_Widget::hide() and Fl_Widget::show().
-These do not send the FL_HIDE and FL_SHOW events to the widget.
+<p>If you don't have RTTI you can use the clumsy FLTK mechanisim, by
+having <tt>type()</tt> have a unique value. These unique values must
+be greater than the symbol <tt>FL_RESERVED_TYPE</tt> (which is 100).
+Look through the header files for <tt>FL_RESERVED_TYPE</tt> to find an
+unused number. If you make a subclass of <tt>Fl_Group</tt> you must
+use <tt>FL_GROUP + n</tt>, and if you make a subclass of
+<tt>Fl_Window<tt> you must use <tt>FL_WINDOW + n</tt> (in both cases
+<tt>n is in the range 1 to 7).
-</ul><h4><code>void Fl_Widget::draw_box() const ;</code></h4><ul>
+<H2>Handling Events</H2>
-Draw this widget's box(), using the dimensions of the widget.
+The virtual method <tt>int Fl_Widget::handle(int event)</tt> is called
+to handle each event passed to the widget. It can:
-</ul><h4><code>void Fl_Widget::draw_box(Fl_Boxtype b,ulong c) const
-;</code></h4><ul>
-
-Pretend the box()==b and the color()==c and draw this widget's box.
-
-<a name=draw_label>
-</ul><h4><code>void Fl_Widget::draw_label() const ;</code></h4><ul>
-
-This is the usual function for a draw() method to call to draw the
-widget's label. It does not draw the label if it is supposed to be
-outside the box (on the assumption that the enclosing group will draw
-those labels).
-
-</ul><h4><code>void Fl_Widget::draw_label(int x,int y,int w,int h) const
-;</code></h4><ul>
-
-Do the same thing except use the passed bounding box. This is useful
-so "centered" labels are aligned with some feature, such as a moving
-slider.
-
-</ul><h4><code>void Fl_Widget::draw_label(int x,int y,int w,int
-h,Fl_Align align) const ;</code></h4><ul>
-
-Draw the label anywhere. It acts as though FL_ALIGN_INSIDE has been
-forced on, the label will appear inside the passed bounding box. This
-is designed for parent groups to draw labels with.
-
-</ul>
-<a name=handle>
-<h2>virtual int Fl_Widget::handle()</h2>
-
-The virtual method <b><code>int Fl_Widget::handle(int
-event)</code></b> is called to handle each event passed to the widget.
-It can:<ul>
-
-<li>Change the state of the widget.
-
-<li>Call <a href=Fl_Widget.html>Fl_Widget::redraw()</a> if the widget
-needs to be redisplayed.
+<ul>
+ <li>Change the state of the widget.
-<li>Call <a href=#damage>Fl_Widget::damage(n)</a> if the widget needs
-a partial-update (assumming you provide support for this in your
-Fl_Widget::draw() method).
+ <li>Call <a href="#Fl_Widget.redraw"><tt>Fl_Widget::redraw()</tt></a>
+ if the widget needs to be redisplayed.
-<li>Call <a href=Fl_Widget.html>Fl_Widget::do_callback()</a> if a
-callback should be generated.
+ <li>Call <a
+ href="#Fl_Widget.damage"><tt>Fl_Widget::damage(n)</tt></a> if
+ the widget needs a partial-update (assumming you provide
+ support for this in your <tt>Fl_Widget::draw()</tt> method).
-<li>Call Fl_Widget::handle() on child widgets.
+ <li>Call <a
+ href="#Fl_Widget.do_callback"><tt>Fl_Widget::do_callback()</tt></a>
+ if a callback should be generated.
+ <li>Call <tt>Fl_Widget::handle()</tt> on child widgets.
</ul>
-<p>Events are identified the small integer argument. Other
-information about the most recent event is stored in static locations
-and aquired by calling <a href=events.html><code>Fl::event_*()</code></a>.
-This other information remains valid until another event is read from
-the X server.
+Events are identified by the integer argument. Other information about
+the most recent event is stored in static locations and aquired by
+calling the <a href="#events"><tt>Fl::event_*()</tt></a> functions.
+This information remains valid until another event is handled.
-<p>Here is a sample Fl_Widget::handle(), for a widget that acts as a
+<p>Here is a sample <tt>handle()</tt> method for a widget that acts as a
pushbutton and also accepts the keystroke 'x' to cause the callback:
-<ul><pre>int Fl_Pushbutton::handle(int event) {
+<ul><pre>
+int MyClass::handle(int event) {
switch(event) {
case FL_PUSH:
- highlight = 1; redraw();
+ highlight = 1;
+ redraw();
return 1;
- case FL_DRAG:
- {int t = Fl::event_inside(this);
- if (t != highlight) {highlight = t; redraw();}}
+ case FL_DRAG: {
+ int t = Fl::event_inside(this);
+ if (t != highlight) {
+ highlight = t;
+ redraw();
+ }
+ }
return 1;
case FL_RELEASE:
if (highlight) {
- highlight = 0; redraw();
+ highlight = 0;
+ redraw();
do_callback();
- // never do anything after a callback, so that the callback
+ // never do anything after a callback, as the callback
// may delete the widget!
}
return 1;
case FL_SHORTCUT:
- if (Fl::event_key() == 'x') {do_callback(); return 1;}
+ if (Fl::event_key() == 'x') {
+ do_callback();
+ return 1;
+ }
return 0;
default:
return 0;
- }
}
}
</pre></ul>
-<p>You must return non-zero if your handle() method used the event.
-If you return zero it indicates to the parent that it can try sending
-another widget the event.
+You must return non-zero if your <tt>handle()</tt> method uses the
+event. If you return zero it indicates to the parent widget that it can
+try sending the event to another widget.
-<p>It looks like it is best to make the handle() method public.
+<H2>Drawing the Widget</H2>
-<a name=draw>
-<h2>virtual void Fl_Widget::draw()</h2>
+The <tt>draw()</tt> virtual method is called when FLTK wants you to
+redraw your widget. It will be called if and only if <tt>damage()</tt>
+is non-zero, and <tt>damage()</tt> will be cleared to zero after it
+returns. <tt>draw()</tt> should be declared protected, so that it can't
+be called from non-drawing code.
-<p>The virtual method Fl_Widget::draw() is called when fltk wants you
-to redraw your widget. It will be called if and only if damage() is
-non-zero, and damage() will be cleared to zero after it returns.
-draw() should be declared protected, so that subclasses may call it
-but it can't be called from non-drawing code.
-
-<p>damage() contains the bitwise-or of all the damage(n) calls to this
+<p><tt>damage()</tt> contains the bitwise-OR of all the <tt>damage(n)</tt> calls to this
widget since it was last drawn. This can be used for minimal update,
-by only redrawing the parts whose bits are set. Fltk will turn
+by only redrawing the parts whose bits are set. FLTK will turn
<i>all</i> the bits on if it thinks the entire widget must be redrawn
-(for instance due to an expose event). It is easiest to program to
-handle this by pretending a bit (usually damage()&128) draw the
-non-minimal-update parts of your widget (such as the box()).
-
-<p>Expose events (and the above damage(b,x,y,w,h)) will cause draw()
-to be called with fltk's <a href=Draw.html#clipping>clipping</a>
-turned on. You can greatly speed up redrawing in some cases by
-testing <code>fl_clipped</code> and <code>fl_current_clip</code>
-and skipping invisible parts.
-
-<p>The functions you can use to draw are described in <a
-href=Draw.html>&lt;FL/fl_draw.H></a> or any of the protected
-Fl_Widget::draw_* methods described above.
-
-<a name=resize>
-<h2>virtual void Fl_Widget::resize(int,int,int,int);</h2>
-
-This is called when the widget is being resized or moved. The
-arguments are the new position, width, and height. x(), y(), w(), and
-h() still return the old size. You must call resize() on your
-base class with the same arguments to get the widget size to actually
-change.
+(for instance due to an expose event).
-<p>This should <i>not</i> call redraw(), at least if only the x() and
-y() change. This is because group objects like <a
-href=Fl_Scroll.html>Fl_Scroll</a> may have a more efficient way of
-drawing the new position.
+<p>Expose events (and the above <tt>damage(b,x,y,w,h)</tt>) will cause
+<tt>draw()</tt> to be called with FLTK's <a
+href="#clipping">clipping</a> turned on. You can greatly speed up
+redrawing in some cases by testing <tt>fl_clipped</tt> and
+<tt>fl_current_clip</tt> and skipping invisible parts.
-<p>It may be useful to refer to the size the widget was constructed
-at, these are stored in Fl_Widget::ix(), iy(), iw(), and ih().
+<p>Besides the protected methods described above, FLTK provide a large
+number of basic drawing functions, which are described <a
+href=#drawing>below</a>.
-<p>Resize should be declared public.
+<H2>Resizing the Widget</H2>
-<a name=destructor>
-<h2>virtual Fl_Widget::~Fl_Widget();</h2>
+The <tt>resize(int x, int y, int w, int h)</tt> method is called when
+the widget is being resized or moved. The arguments are the new
+position, width, and height. <tt>x()</tt>, <tt>y()</tt>, <tt>w()</tt>,
+and <tt>h()</tt> still remain the old size. You must call
+<tt>resize()</tt> on your base class with the same arguments to get the
+widget size to actually change.
-We all know why the destructor must be virtual don't we? Don't forget
-to make it public.
+<p>This should <i>not</i> call <tt>redraw()</tt>, at least if only the
+<tt>x()</tt> and <tt>y()</tt> change. This is because group objects
+like <a href="#Fl_Scroll"><tt>Fl_Scroll</tt></a> may have a more
+efficient way of drawing the new position.
-<a name=composite>
-<h2>Making a Composite/Group Widget</h2>
+<H2>Making a Composite/Group Widget</H2>
A "composite" widget contains one or more "child" widgets. To do this
-you should subclass <a href=Fl_Group.html>Fl_Group</a> (it is
+you should subclass <a href="#Fl_Group"><tt>Fl_Group</tt></a>. It is
possible to make a composite object that is not a subclass of
-Fl_Group, but this is very difficult).
+<tt>Fl_Group</tt>, but you'll have to duplicate the code in <tt>Fl_Group</tt>
+anyways.
<p>Instances of the child widgets may be included in the parent:
-<ul><pre>class MyClass : public Fl_Group {
+<ul><pre>
+class MyClass : public Fl_Group {
Fl_Button the_button;
Fl_Slider the_slider;
...
};
</pre></ul>
-<p>The constructor has to initialize these instances. They are
-automatically add()ed to the group, since the Fl_Group constructor
-does begin(). <i>Don't forget to call end():</i>
-
-<ul><pre>MyClass::MyClass(int x,int y,int w,int h) :
- Fl_Group(x,y,w,h),
- the_button(x+5,y+5,100,20),
- the_slider(x,y+50,w,20)
+The constructor has to initialize these instances. They are
+automatically <tt>add()</tt>ed to the group, since the
+<tt>Fl_Group</tt> constructor does <tt>begin()</tt>. <i>Don't forget
+to call <tt>end()</tt> or use the <a href="#Fl_End"><tt>Fl_End</tt></a>
+pseudo-class:</i>
+
+<ul><pre>
+MyClass::MyClass(int x, int y, int w, int h) :
+ Fl_Group(x, y, w, h),
+ the_button(x + 5, y + 5, 100, 20),
+ the_slider(x, y + 50, w, 20)
{
...(you could add dynamically created child widgets here)...
end(); // don't forget to do this!
}
</pre></ul>
-<p>The child widgets need callbacks. These will be called with a
-pointer to the children, but the widget itself may be found in the
-parent() pointer of the child. Usually these callbacks can be static
-private methods, with a matching private method:
+The child widgets need callbacks. These will be called with a pointer
+to the children, but the widget itself may be found in the
+<tt>parent()</tt> pointer of the child. Usually these callbacks can be
+static private methods, with a matching private method:
-<ul><pre>void MyClass::slider_cb(Fl_Widget* v, void *) { // static method
+<ul><pre>
+void MyClass::slider_cb(Fl_Widget* v, void *) { // static method
((MyClass*)(v->parent())->slider_cb();
}
void MyClass::slider_cb() { // normal method
@@ -429,31 +340,33 @@ void MyClass::slider_cb() { // normal method
}
</pre></ul>
-<p>If you make the handle() method, you can quickly pass all the
-events to the children (notice that you don't need to override
-handle() if your composite widget does nothing other than pass events
-to the children):
+If you make the <tt>handle()</tt> method, you can quickly pass all the
+events to the children using the <tt>Fl_Group::handle()</tt> method.
+Note that you don't need to override <tt>handle()</tt> if your
+composite widget does nothing other than pass events to the children:
-<ul><pre>int MyClass::handle(int event) {
+<ul><pre>
+int MyClass::handle(int event) {
if (Fl_Group::handle(event)) return 1;
... handle events that children don't want ...
}
</pre></ul>
-<p>If you override draw() you need to draw all the children. If
-redraw() or damage() is called on a child, damage(1) is done to the
-group. Thus the 1 bit of damage() can be used to indicate that a
-child needs to be drawn. It is fastest if you avoid drawing anything
-else in this case:
-
-<ul><pre>int MyClass::draw() {
- Fl_Widget*const* a = array();
- if (damage()==1) { // only redraw some children
- for (int i=children(); i--; a++) update_child(**a);
+If you override <tt>draw()</tt> you need to draw all the children. If
+<tt>redraw()</tt> or <tt>damage()</tt> is called on a child,
+<tt>damage(FL_DAMAGE_CHILD)</tt> is done to the group, so this bit of
+<tt>damage()</tt> can be used to indicate that a child needs to be
+drawn. It is fastest if you avoid drawing anything else in this case:
+
+<ul><pre>
+int MyClass::draw() {
+ Fl_Widget *const*a = array();
+ if (damage() == FL_DAMAGE_CHILD) { // only redraw some children
+ for (int i = children(); i --; a ++) update_child(**a);
} else { // total redraw
... draw background graphics ...
// now draw all the children atop the background:
- for (int i=children_; i--; a++) {
+ for (int i = children_; i --; a ++) {
draw_child(**a);
draw_outside_label(**a); // you may not want to do this
}
@@ -461,59 +374,84 @@ else in this case:
}
</pre></ul>
-<p>Fl_Group provides some protected methods to make drawing easier:
+<tt>Fl_Group</tt> provides some protected methods to make drawing easier:
+
+<ul>
+ <li><a href="#draw_child">draw_child</a>
+ <li><a href="#draw_outside_label">draw_outside_label</a>
+ <li><a href="#update_child">update_child</a>
+</ul>
-</ul><h4><code>void Fl_Group::draw_outside_label(Fl_Widget&) const;</code></h4><ul>
+<H3><a name="draw_child">void Fl_Group::draw_child(Fl_Widget&amp;)</a></H3>
-Draw the labels that are <i>not</i> drawn by <a
-href=#draw_label>draw_label()</a>. If you want more control over the
-label positions you might want to call child->draw_label(x,y,w,h,a).
+This will force the child's <tt>damage()</tt> bits all to one and call
+<tt>draw()</tt> on it, then clear the <tt>damage()</tt>. You should
+call this on all children if a total redraw of your widget is
+requested, or if you draw something (like a background box) that
+damages the child. Nothing is done if the child is not
+<tt>visible()</tt> or if it is clipped.
-</ul><h4><code>void Fl_Group::draw_child(Fl_Widget&);</code></h4><ul>
+<H3><a name="draw_outside_label">void Fl_Group::draw_outside_label(Fl_Widget&amp;) const</a></H3>
-This will force the child's damage() bits all to one and call draw()
-on it, then clear the damage(). You should call this on all children
-if a total redraw of your widget is requested, or if you draw
-something (like a background box) that damages the child. Nothing is
-done if the child is not visible() or if it is clipped.
+Draw the labels that are <i>not</i> drawn by
+<a href="#draw_label"><tt>draw_label()</tt></a>. If you want more control
+over the label positions you might want to call
+<tt>child->draw_label(x,y,w,h,a)</tt>.
-</ul><h4><code>void Fl_Group::update_child(Fl_Widget&);</code></h4><ul>
+<H3><a name="update_child">void Fl_Group::update_child(Fl_Widget&amp;)</a></H3>
-Draws the child only if it's damage() is non-zero. You should call
-this on all the children if your own damage is equal to 1. Nothing is
-done if the child is not visible() or if it is clipped.
+Draws the child only if it's <tt>damage()</tt> is non-zero. You should
+call this on all the children if your own damage is equal to
+FL_DAMAGE_CHILD. Nothing is done if the child is not
+<tt>visible()</tt> or if it is clipped.
+<H2>Cut and Paste Support</H2>
+
+FLTK provides routines to cut and paste ASCII text (in the future this
+may be UTF-8) between applications:
+
+<ul>
+ <li><a href="#paste">Fl::paste</a>
+ <li><a href="#selection">Fl::selection</a>
+ <li><a href="#selection_length">Fl::selection_length</a>
+ <li><a href="#selection_owner">Fl::selection_owner</a>
</ul>
-<a name=window>
-<h2>Making a subclass of Fl_Window</h2>
-<p>You may want your widget to be a subclass of Fl_Window. This can
-be useful if your widget wants to occupy an entire window, and can
+It may be possible to cut/paste non-ASCII data by using <a
+href="#add_handler"><tt>Fl::add_handler()</tt></a>.
+
+<H2>Making a subclass of Fl_Window</H2>
+
+You may want your widget to be a subclass of <tt>Fl_Window</tt>. This
+can be useful if your widget wants to occupy an entire window, and can
also be used to take advantage of system-provided clipping, or to work
with a library that expects a system window id to indicate where to
draw.
-<p>Subclassing Fl_Window is almost exactly like subclassing Fl_Widget,
-in fact you can easily switch a subclass back and forth. Watch out
-for the following differences:
+<p>Subclassing <tt>Fl_Window</tt> is almost exactly like subclassing
+<tt>Fl_Widget</tt>, in fact you can easily switch a subclass back and
+forth. Watch out for the following differences:
<ol>
-<li>Fl_Window is a subclass of Fl_Group so <i>make sure your constructor
-calls end()</i> (unless you actually want children added to your
-window).
-
-<li>When handling events and drawing, the lower-left corner is at 0,0,
-not x(),y() as in other Fl_Widgets. For instance, to draw a box
-around the widget, call draw_box(0,0,w(),h()), rather than
-draw_box(x(),y(),w(),h()).
+ <li><tt>Fl_Window</tt> is a subclass of <tt>Fl_Group</tt> so
+ <i>make sure your constructor calls <tt>end()</tt></i> (unless
+ you actually want children added to your window).
+ <li>When handling events and drawing, the upper-left corner is
+ at 0,0, not <tt>x(),y()</tt> as in other <tt>Fl_Widget</tt>s.
+ For instance, to draw a box around the widget, call
+ <tt>draw_box(0, 0, w(), h())</tt>, rather than
+ <tt>draw_box( x(), y(), w(), h())</tt>.
</ol>
-<p>You may also want to subclass Fl_Window in order to get access to
-different X visuals or to change other X attributes of the windows,
-<a href=x.html#window>See here for details</a>.
+You may also want to subclass <tt>Fl_Window</tt> in order to get access to
+different visuals or to change other attributes of the windows. See
+<a href="#osissues">Appendix F - Operating System Issues</a> for more
+information.
+
+</BODY>
+</HTML>
-<p><a href = index.html>(back to contents)</a>