class fltk::Widget
Class Hierarchy
fltk::Widget
|
+----fltk::InvisibleBox, fltk::Button, fltk::Chart, fltk::Clock,
fltk::Group, fltk::Input, fltk::Positioner,
fltk::Valuator
Include Files
#include <fltk/Widget.h>
Description
fltk::Widget is the base class for all widgets in FLTK. You can't
create one of these because the constructor is not public. However you
can subclass it.
Unless otherwise noted, the property setting methods such as color(n) or label(s) do not call redraw(), even if they change the widget's
appearance. This is to make the setting of several properties faster
and to allow most of them to be small inline functions. It is up to
the calling program to call redraw()
after changing any visible properties.
Methods
Virtual methods
The constructor and these 5 virtual functions are usually rewritten by
any subclass. This is described in more detail under subclassing.
This is the protected constructor for an fltk::Widget, but all derived
widgets have a matching public constructor. It takes a value for
x(),
y(),
w(),
h(),
and an optional value for label().
Draw the widget. The default version draws the box to fill the widget
and draws any inside label. Information on how to write your own
version is here.
Handle an event, and return non-zero if the
widget understood and used the event. The default version returns true for
fltk::ENTER, fltk::LEAVE and fltk::MOVE. Information on how
to write your own version is here.
If you want to send an event to a widget you probably want to use send() which will do some extra processing before and
after the event is handled.
Respond to a change in size or position. Calling relayout() or resize() with a
different size will cause this to be called later (after all pending
events are handled and just before draw() is
called).
The destructor is virtual. The base class removes itself from the
parent widget (if any), and destroys any label made with copy_label().
Static methods
Call the handle() method on the widget and return
the result, but also does some processing of events:
- It makes sure the widget is active and/or visible if the event
requres this.
- It adjusts fltk::event_x/y to be relative to the widget (It is the
caller's responsibility to see if the mouse is pointing at the
widget).
- If this is not the fltk::belowmouse()
widget then it changes fltk::MOVE into fltk::ENTER and
turns fltk::DND_DRAG into fltk::DND_ENTER. If this
is the fltk::belowmouse() widget
then the opposite conversion is done.
- For move, focus, and push events if handle()
returns true it sets the fltk::belowmouse() or fltk::focus() or fltk::pushed() widget to reflect this.
Return the fltk::Style structure used by this
widget. Normally this structure is shared with many other widgets.
bool fltk::Widget::style(fltk::Style* s);
bool fltk::Widget::style(fltk::Style& s);
Set the style to this shared style. If this style has never
been used before fltk adds it as a child of the current style and
returns true (this allows the calling code to initialize it).
Copy the style from another widget. If it is not shared then a copy
is made, otherwise the pointer is just copied. This is done so that
either widget may be destroyed without deleting the style used by the
other one.
fltk::Style* fltk::Widget::wstyle();
Returns a "writable" style. If the current value of style() is shared then a unique copy is made and
returned. This may be modified without changing other widgets.
Return the given field out of the style().
void fltk::Widget::box(fltk::Box);
void fltk::Widget::button_box(fltk::Box);
void fltk::Widget::focus_box(fltk::Box);
void fltk::Widget::glyph(fltk::Glyph);
void fltk::Widget::label_font(fltk::Font);
void fltk::Widget::text_font(fltk::Font);
void fltk::Widget::label_type(fltk::Labeltype);
void fltk::Widget::color(fltk::Color);
void fltk::Widget::label_color(fltk::Color);
void fltk::Widget::highlight_color(fltk::Color);
void fltk::Widget::highlight_label_color(fltk::Color);
void fltk::Widget::button_color(fltk::Color);
void fltk::Widget::text_color(fltk::Color);
void fltk::Widget::selection_color(fltk::Color);
void fltk::Widget::selection_text_color(fltk::Color);
void fltk::Widget::label_size(unsigned);
void fltk::Widget::text_size(unsigned);
void fltk::Widget::leading(unsigned);
These all create a writable fltk::Style with wstyle() and set the given field in it.
Returns a pointer to the parent widget. Usually this is a fltk::Group or fltk::Window. Returns
NULL if none.
Return a pointer to the fltk::Window that this
widget is in (it will skip any and all parent widgets between this and
the window). Returns NULL if none. Note: for an
fltk::Window, this returns the parent window (if any),
not this window.
The property fltk::Widget::type() can return an arbitrary 8-bit
identifier, and can be set with the protected method type(uchar
t). This value had to be provided for Forms compatibility, but
you can use it for any purpose you want (mostly for "bad object
oriented programming" where you insert some subclass functionality
into the base class). fltk::Widget subclasses may store values in the
range 0-99 here (larger values are reserved for use by FLTK).
For portability FLTK does not use RTTI (Run Time Typing Infomation)
internally (you are free to use it, though). If you don't have RTTI you can
use the clumsy FLTK mechanisim, by having type() use a unique
value. These unique values must be greater than the symbol
fltk::Widget::RESERVED_TYPE (which is 100). Look through the header
files for fltk::Widget::RESERVED_TYPE to find an unused number. If you
make a subclass of fltk::Window you must use fltk::Widget::WINDOW_TYPE +
n (n must be in the range 1 to 7), if you
make a subclass of fltk::Group you must use fltk::Widget::GROUP_TYPE +
n (n must be in the range 1 to 7) (fltk needs to be able
to identify fltk::Window and fltk::Group subclasses internally).
Returns true if this fltk::Widget's class is a subclass of fltk::Group. If so you can cast it to a group with
(fltk::Group*)(widget). This is done by using type(), but if your compiler supports RTTI you
may want to safer dynamic_cast<fltk::Group*>(widget).
Returns true if this fltk::Widget's class is a subclass of fltk::Window. If so you can cast it to a window with
(fltk::Window*)(widget). This is done by using type(), but if your compiler supports RTTI you
may want to safer dynamic_cast<fltk::Window*>(widget). If
this is true, is_group() is also true.
The position of the upper-left corner of the widget in its enclosing
fltk::Widget. If this is an outer fltk::Window than this is the position of
th upper-left corner of the contents (not the frame) on the screen.
Returns w() or h(),
but if the current value is zero it calls layout() before returning the value. Using
these calls allows a widget to delay the calculation of size until it
is needed.
Change the size or position of the widget. Nothing is done if the
passed size and position are the same as before. If there is a change
then relayout() is called so that the
virtual function layout() is called
before the next draw().
Inline equivalent to resize(x,y,w(),h()).
Inline equivalent to resize(x(),y(),w,h).
The label is printed somewhere on the widget or next to it. The
string passed to label() is not copied, instead the pointer to
the string is stored. If copy_label()
was called earlier the old string's memory is freed.
The passed string is copied to private storage and used to set the
label. The memory will be freed when the widget is destroyed or when
copy_label() is called again, or label(const char*)
is called.
Passing NULL will set label() to NULL.
fltk::Image to draw as part of the label.
Set the string used as the pop-up tooltip. The pointer to the passed string
is stored, it is not copied! Passing null indicates that the tooltip
of the parent() should be used (or no
tooltip if no parent has one). If you want to disable the tooltip but
let the parent have one, set this tooltip to "".
This is used as the label of the fltk::Tooltip widget that pops up when the user
points at the window. You can probably get some interesting formatting
and symbols in there with the symbol drawing code.
Buttons and menu items use the shortcut to identify a keystroke
that will activate them. The value is a bitwise OR of a key and a set
of shift flags, for example fltk::ALT | 'a'
, fltk::ALT |
(fltk::F + 10)
, or just 'a'
. A value of 0 disables
the shortcut.
The key can be any value returned by
fltk::event_key(), but will usually be an ASCII letter. Use
a lower-case letter unless you require the shift key to be held down.
The shift flags can be any set of values accepted by fltk::event_state(). If
the bit is on that shift key must be pushed. Win, Alt, Ctrl, and
Shift must be off if they are not in the shift flags (zero for the
other bits indicates a "don't care" setting).
Shortcuts can also be done in the MS Windows way
by putting an '&' in front of a letter in the label(). This is equivalent to
fltk::ALT and the letter.
Each widget has a single callback. You can set it or examine it with
these methods.
You can also just change the void* second argument to the
callback with the user_data methods.
For convenience you can also define the callback as taking a long
integer argument. This is implemented by casting the function to a
fltk::Callback and casting the long to a void
* and may not be portable to some machines.
void fltk::Widget::callback(void (*)(fltk::Widget*))
For convenience you can also define the callback as taking only one
argument. This is implemented by casting this to a fltk::Callback
and may not be portable to some machines.
fltk::Widget::when() is a set of bitflags used by subclasses of
fltk::Widget to decide when to do the callback. This field is
in the base class so that you can scan a panel and
do_callback() on all the ones that don't do their own
callbacks in response to an "OK" button.
The following constants can be used, their exact meaning depends on
the widget's implementation:
- fltk::WHEN_NEVER - Never call the callback (0).
- fltk::WHEN_CHANGED - Do the callback each time the widget's
value is changed by the user (many callbacks may be done as the user
drags the mouse)
- fltk::WHEN_RELEASE - Each keystroke that modifies the value,
or when the mouse is released and the value has changed, causes the
callback (some widgets do not implement this and act like
fltk::WHEN_CHANGED)
- fltk::WHEN_RELEASE_ALWAYS - Each recognized keystroke and the mouse
being released will cause the callback, even if the value did not
change. (some widgets do not implement this and act like
fltk::WHEN_RELEASE)
- fltk::WHEN_ENTER_KEY - Do the callback when the user presses
the ENTER key and the value has chagned (used by fltk::Input and fltk::Browser.
- fltk::WHEN_ENTER_KEY_ALWAYS - Do the callback when the user
presses the ENTER key, even if the value has not changed.
- fltk::WHEN_ENTER_KEY_CHANGED - Do the callback when the user
presses the ENTER key and each time the value changes.
The default callback does nothing. callback()
is initialized to this.
You can cause a widget to do its callback at any time, and even pass
arbitrary arguments.
Tests the value of shortcut() and the value of
label() (if fltk::NO_SHORTCUT_LABEL is not set) against
the current event (which must be a fltk::SHORTCUT or fltk::KEY
event). Returns 1 if it matches shortcut(), returns 2 if it matches
the label(), and returns 0 if there is no match.
Returns true if b is a child of this widget, or is equal to
this widget. Returns false if b is NULL.
Returns true if this is a child of a, or is equal to
a. Returns false if a is NULL.
Returns true if this is equal to fltk::pushed(), meaning it has
responded to an fltk::PUSH
event and the mouse is still held down. Using this function avoids the
need to include the <fltk/Fl.h> header file.
Returns true if this is equal to fltk::focus(), meaning it has the
keyboard focus and fltk::KEY events will be
sent to this widget. Using this function avoids the need to include
the <fltk/Fl.h> header file.
Returns true if this is equal to fltk::belowmouse(), meaning
it has the keyboard focus and fltk::MOVE or fltk::PUSH
events will be sent to this widget. Using this function avoids the
need to include the <fltk/Fl.h> header file.
Each widget, and many of the drawing functions, take a bitmask of
flags that indicate the current state and exactly how to draw
things. The following flags are defined:
- fltk::INVISIBLE - !visible()
- fltk::INACTIVE - !active()
- fltk::OUTPUT - output()
- fltk::VALUE - value()
- fltk::SELECTED - selected()
- fltk::HIGHLIGHT - draw highlighted
- fltk::CHANGED - changed()
- fltk::COPIED_LABEL - indicates copy_label() was called
- fltk::RAW_LABEL - prevents interpretation of '&' and '@' in labels
- fltk::ALIGN_* - label alignment, see below.
- fltk::PACK_VERTICAL - fltk::Pack
puts this widget vertical
- fltk::CLICK_TO_FOCUS - click_to_focus()
Forces the values of all the fltk::ALIGN_* flags to the passed
value. This determines how the label is printed next to or inside the
widget. The default value is fltk::ALIGN_CENTER, which centers
the label. The value can be any of these constants or'd together:
- fltk::ALIGN_CENTER - The label is centered (0).
- fltk::ALIGN_TOP - The label is top-aligned.
- fltk::ALIGN_BOTTOM - The label is bottom-aligned.
- fltk::ALIGN_LEFT - The label is left-aligned.
- fltk::ALIGN_RIGHT - The label is right-aligned.
- fltk::ALIGN_CLIP - The label is clipped to the widget.
- fltk::ALIGN_WRAP - The label text is wrapped as needed.
- fltk::ALIGN_TOP_LEFT
- fltk::ALIGN_TOP_RIGHT
- fltk::ALIGN_BOTTOM_LEFT
- fltk::ALIGN_BOTTOM_RIGHT
- fltk::ALIGN_LEFT_TOP
- fltk::ALIGN_RIGHT_TOP
- fltk::ALIGN_LEFT_BOTTOM
- fltk::ALIGN_RIGHT_BOTTOM
- fltk::ALIGN_INSIDE - 'or' this with other values to put
label inside the widget.
An invisible widget never gets redrawn and does not get events. The
visible() method returns true if the widget is set to be
visible.The visible_r() method returns true if the widget and
all of its parents are visible. A widget is only visible if
visible() is true on it and all of its parents.
Changing it will send fltk::SHOW or fltk::HIDE
events to the widget. Do not change it if the parent is not
visible, as this will send false fltk::SHOW or fltk::HIDE
events to the widget. redraw() is called if necessary on
this or the parent.
Fast inline versions of fltk::Widget::hide() and
fltk::Widget::show(). These do not send the fltk::HIDE and
fltk::SHOW events to the widget.
fltk::Widget::active() returns whether the widget is active.
fltk::Widget::active_r() returns whether the widget and all of
its parents are active. An inactive widget does not get any events,
but it does get redrawn. A widget is only active if active() is
true on it and all of its parents.
Changing this value will send fltk::ACTIVATE or
fltk::DEACTIVATE to the widget if active_r() is true.
Currently you cannot deactivate fltk::Window widgets.
output() means the same as !active() except it does
not change how the widget is drawn. The widget will not recieve any
events. This is useful for making scrollbars or buttons that work as
displays rather than input devices.
This is the same as (active() && visible() &&
!output()) but is faster.
If this flag is set then if this widget returns true for an
fltk::PUSH event then fltk will attempt to give it the focus (by
calling take_focus(), so it will work if this
widget also returns true for fltk::FOCUS events). By default
fltk only turns this on on certain widgets such as fltk::Input. Turning this on on all widgets
will make the user interface match Windows more closely.
fltk::Widget::changed() is a flag that is turned on when the user
changes the value stored in the widget. This is only used by
subclasses of fltk::Widget that store values, but is in the base
class so it is easier to scan all the widgets in a panel and
do_callback() on the changed ones in response to an "OK" button.
Most widgets turn this flag off when they do the callback, and when
the program sets the stored value.
A true/false flag used by fltk::Button to
indicate the current state and by "parent" items in a hierarchial fltk::Browser to indicate if they are
open. Many widgets will draw pushed-in or otherwise indicate that this
flag is on.
A true/false flag used to mark widgets currently selected in
fltk::Menu and
fltk::Browser widgets. Some widgets will
draw with much different colors if this is on.
Tries to make this widget be the keyboard focus widget, by first
sending it an fltk::FOCUS
event, and if it returns non-zero, setting fltk::focus() to this widget.
You should use this method to assign the focus to an widget. Returns
true if the widget accepted the focus.
This function is called by ~Widget() and by fltk::Widget::deactivate() and by fltk::Widget::hide(). It indicates that the widget
does not want to receive any more events, and also removes all global
variables that point at the widget (not just the fltk::focus(), but the fltk::belowmouse(), fltk::modal(), and some internal
pointers). Unlike older versions of fltk, no events (i.e.
fltk::LEAVE or fltk::UNFOCUS) are sent to the widget.
Indicates that draw() should be called, and
turns on the given bits in damage(). At
least these bits, and possibly others, will still be on when draw() is called.
Indicate that an outside label needs to be redrawn. This does
nothing if the label is inside the widget or there is no label. If the
label is outside, the enclosing group is flagged to redraw it.
void fltk::Widget::redraw(int x, int y, int w, int h)
Indicates that a rectangular region is damaged. draw() will be called later with damage() set to
fltk::DAMAGE_ALL|fltk::DAMAGE_EXPOSE and with FLTK's clipping set to at least the given
rectangle. Normally this is called more than once and the clip region
will be the union of all these calls. In addition damage from
the operating system (ie from overlapping windows) will increase the
clipping region.
This can be used to get speed up and improve complex displays of
many overlapping and changing objects. Even if you do nothing else
about it, it is usually faster to do a drawing operation that is
clipped than one that appears, so display will be faster. You can also
check to see if anything by testing fltk::not_clipped(x,y,w,h)
or fltk::clip_box(...) and
skipping unnecessary drawing calls completely. Also if your normal
drawing causes blinking (due to overlapping objects) this can make the
display look much better by limiting the blinking to the small area
that is actually changing.
The 'or' of all the calls to redraw()
done since the last draw(). Cleared to zero after
draw() is called.
When redrawing your widgets you should look at the damage bits to
see what parts of your widget need redrawing. The handle()
method can then set individual damage bits to limit the amount of drawing
that needs to be done:
MyClass::handle(int event) {
...
if (change_to_part1) damage(1);
if (change_to_part2) damage(2);
if (change_to_part3) damage(4);
}
MyClass::draw() {
if (damage() & fltk::DAMAGE_ALL) {
... draw frame/box and other static stuff ...
}
if (damage() & (fltk::DAMAGE_ALL | 1)) draw_part1();
if (damage() & (fltk::DAMAGE_ALL | 2)) draw_part2();
if (damage() & (fltk::DAMAGE_ALL | 4)) draw_part3();
}
Fltk assigns meaning to the following bits in the damage:
- fltk::DAMAGE_CHILD - A child of this group widget needs to
be redrawn (non-group widgets can use this bit for their own purposes).
- fltk::DAMAGE_CHILD_LABEL - An outside label of this widget
needs to be redrawn. This is handled (and this bit is cleared) by the
parent group.
- fltk::DAMAGE_EXPOSE - Damage caused by damage() or by expose events
from the operating system. If this and fltk::DAMAGE_ALL is on
the widget should draw every pixel inside it's region.
- fltk::DAMAGE_ALL - This bit is set by redraw() and indicates that
all of the widget (but not "holes" where the background shows through)
needs to be redraw.
To avoid collisions with the these and any other future assigned bit
values, widgets should limit themselves to these predefined bits for
managing their own damage. You can use the names if they are
appropriate, or define your own symbols with the same values:
- fltk::DAMAGE_VALUE
- fltk::DAMAGE_PUSHED
- fltk::DAMAGE_SCROLL
- fltk::DAMAGE_OVERLAY Same value as fltk::DAMAGE_SCROLL.
- fltk::DAMAGE_HIGHLIGHT
- fltk::DAMAGE_CONTENTS Same as fltk::DAMAGE_EXPOSE but
if fltk::DAMAGE_ALL is off you can use this for your own
purposes.
Directly change the value returned by damage().
Cause layout() to be called later (before
the next draw() is called). A subclass may want to use this to defer
expensive display calculations until the next time the system is idle.
The 'or' of all the calls to relayout()
or resize() done since the last time
layout() was called. Cleared to zero by
fltk::Widget::layout().
A typical layout function does not care about the widget moving, an
easy way to skip it is as follows:
MyClass::layout() {
if (!(layout_damage() & ~LAYOUT_XY)) return;
do_expensive_layout();
redraw();
}
The following bit values are defined:
- fltk::LAYOUT_X - x() changed by resize()
- fltk::LAYOUT_Y - y() changed by resize()
- fltk::LAYOUT_XY - same as fltk::LAYOUT_X|fltk::LAYOUT_Y
- fltk::LAYOUT_W - w() changed by resize()
- fltk::LAYOUT_H - h() changed by resize()
- fltk::LAYOUT_WH - same as fltk::LAYOUT_W|fltk::LAYOUT_H
- fltk::LAYOUT_XYWH - same as fltk::LAYOUT_XY|fltk::LAYOUT_WH
- fltk::LAYOUT_CHILD - layout() needs to be called on a child
of this group widget.
- fltk::LAYOUT_DAMAGE - relayout() was called.
void fltk::Widget::layout_damage(uchar c)
Directly change the value returned by layout_damage().
Adjust the x and y offsets and current window of the drawing functions
to draw into this widget. You only need to call this if you want to
incrementally update your widget. When draw() is
called this will already have been done.
Draws only the edge of the box() (by or'ing
fltk::INVISIBLE into the flags to it). If !active_r()
then it also or's in fltk::INACTIVE. This will only work for
rectangular boxtypes.
Fills the entire widget with it's box() and color(). If the box is not rectangular and damage() contains fltk::DAMAGE_EXPOSE then
the parent group's box is drawn to fill in the missing areas. If the
widget is inactive or if any bits are turned on in flags() then the box may draw differently to show this.
Calls the glyph() function with the given
arguments (the caller must figure out inactive and selected, this is
best done by using the return value from draw_box()).
Draws the label anywhere. This ignores the fltk::ALIGN_INSIDE
and always draws the label inside the passed bounding box.
This is used by fltk::Group and fltk::Tabs to draw the outside labels of their
child widgets.
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).
The label consists of the value for label() and the value
for image(). The alignment flags control how they are
arranged next to each other in the box. The color to draw the label is
determined by the settings of the flags, the active_r()
value, and the label_color(), selection_text_color(),
highlight_label_color() of this widget.
The second form uses the passed bounding box instead of the widget's
bounding box. This allows the widget to draw the label somewhere other
than centered on itself, and lets you force fltk::VALUE or
fltk::SELECTED on or off (passed alignment flags are 'or'd with
the widget's flags).
Return in w and h the size that the widget's label() and
image() will take.