You will have to include at least this header file in your main code so that you can call the methods described here.
You can construct all your widgets (and menus and boxtypes and images and other fltk types) without "initializing". The constructors do not require a connection to the X display. This makes it a lot easier, especially if your program has a mode where it does not use a gui, and guarantees that code you don't use is not linked in.
Fltk is usually "initialized" when you show() the first window. At this time the X display is opened and everything is set up so the calls described in the rest of this document work. A few other calls can open the X display, amoung them are fl_width() to measure the size of a font. Be careful that the following calls are done before the display is opened, if not you will get lots of strange X errors.
Most of these "initialization" calls are to get around stupid X
things. I have tried to make these as simple to call as possible and
they have no effect on systems which aren't as badly designed as X.
But you should call them to make your program as portable as possible.
Only the following combinations do anything useful:
This returns true if the system has the capabilities by default or
fltk suceeded in turing them on. Your program will still work even if
this returns false (it just won't look as good).
See here for ways to select the visual
using your own code.
See Fl_Gl_Window for a list of
additional values for the argument.
This does nothing if the current visual is not colormapped or on
MSWindows (even though it probably should if your display is in 8-bit
mode).
Currently this only works on MSWindows. In future versions on X it
may read the KDE or Gnome setup, but for now it does nothing.
Fltk provides an entirely optional command-line switch
parser. You don't have to call it if you don't like them!
Everything it can do can be done with other calls to fltk.
To use the switch parser, call Fl::args(...) near the start of
your program. This does not open the display, instead switches
that need the display open are stashed into static variables. Then
you must display your first window by calling Fl_Window::show(argc,argv), which will do anything
stored in the static variables.
callback lets you define your own switches. It is called
with the same argc and argv, and with i the index of each word.
The callback should return zero if the switch is unrecognized, and not
change i. It should return non-zero if the switch is recognized, and
add at least 1 to i (it can add more to consume words after the
switch). This function is called before any other tests, so you can
override any fltk switch.
On return i is set to the index of the first non-switch.
This is either:
The return value is i unless an unrecognized switch is
found, in which case it is zero. If your program takes no arguments
other than switches you should produce an error if the return value is
less than argc.
All switches may be abbreviated to one letter and case is ignored:
If Fl::args() or Fl::arg() have never been called, this calls
Fl::args(argc,argv) automatically. This is convienent for very small
programs that just want to put up a single window and take no
switches.
Your program can check it's global state and update things after
each call to Fl::wait(), which can be very useful in complex programs.
If there are no windows (this is checked after the idle and
timeouts are called) then Fl::wait() returns zero without waiting for
any events. Your program can either exit at this point, or call
show() on some window so the UI can continue to operate.
If you do several wait(time) calls in a row, the subsequent ones
are measured from when the first one is called, even if you do
time-consuming calculations after they return. This allows you to
accurately make something happen at regular intervals. This code will
accurately call A() once per second (as long as it takes less than a
second to execute):
This returns non-zero if any windows are displayed, and 0 if no
windows are displayed.
This code will print "TICK" each second on stdout, no matter what
else the user or program does:
Only Fl::wait(void) calls the idle callback. Fl::wait(time),
Fl::check(), and Fl::ready() ignore it. This is so that these
functions may be called by the idle callback itself without having to
worry about recursion.
The idle callback can call any fltk functions. However if you call
something that calls Fl::wait() (such as a message pop-up) you should
first set the idle callback to zero so it does not recurse.
The second version takes a when bitfield, with the bits
FL_READ, FL_WRITE, and FL_EXCEPT defined, to indicate when the
callback should be done. This probably only works on Unix.
There can only be one callback of each type for a file descriptor.
Fl::remove_fd() gets rid of all the callbacks for a given file
descriptor.
To stop a window from closing, or conversely to make the closing of
a particular window exit the program you must change the callback()
function. Here is a typical use:
Supposedly Fl::warning means that there was a recoverable problem,
the display may be messed up but the user can probably keep working
(all X protocol errors call this). Fl::error means there is a
recoverable error, but the display is so messed up it is unlikely the
user can continue (very little calls this now). Fl::fatal must not
return, as fltk is in an unusable state (however your version may be
able to use longjmp or an exception to continue, as long as it does
not call fltk again).
int Fl::visual(int)
Selects an X visual so that your graphics are drawn correctly. This
does nothing if the default visual satisfies the capabilities, or if
no visual satisfies the capabilities, or on systems that don't have
such brain-dead notions.
Fl::visual(FL_RGB)
Full/true color (if there are several depths fltk chooses the
largest). Do this if you use fl_draw_image for much better
(non-dithered) output.
Fl::visual(FL_RGB8)
Full color with at least 24 bits of color. FL_RGB will always
pick this if available, but if not it will happily return a
less-than-24 bit deep visual. This call fails if 24 bits are not
available.
Fl::visual(FL_DOUBLE|FL_INDEX)
Hardware double buffering. Call this if you are going to use
Fl_Double_Window.
Fl::visual(FL_DOUBLE|FL_RGB)
Fl::visual(FL_DOUBLE|FL_RGB8)
Hardware double buffering and full color.
int Fl::gl_visual(int)
This does the same thing as Fl::visual(int) but also requires OpenGL
drawing to work. This must be done if you want to draw in
normal windows with OpenGL with gl_start()
and gl_end(). It may be useful to call this so your X windows use
the same visual as an Fl_Gl_Window, on
some servers the windows will drag around easier then.
void Fl::own_colormap();
Makes fltk use it's own X colormap. This may make fltk display
better and will reduce conflicts with other programs that want lots of
colors. However the colors may flash as you drag the cursor between
windows.
void Fl::get_system_colors();
Read the user preference colors from the system and use them to call
Fl::foreground(), Fl::background(), and Fl::background2(). This is
done by Fl_Window::show(argc,argv) before applying the -fg and -bg
switches.
void Fl::background(uchar, uchar, uchar);
Changes
fl_color(FL_GRAY)
to the given color, and changes
the gray ramp from 32 to 56 to black to white. These are the colors
used as backgrounds by almost all widgets and used to draw the edges
of all the boxtypes.
void Fl::foreground(uchar, uchar, uchar);
Changes
fl_color(FL_BLACK)
. Also changes
FL_INACTIVE_COLOR
and FL_SELECTION_COLOR
to
be a ramp between this and FL_WHITE
.
void Fl::background2(uchar, uchar, uchar);
Changes
fl_color(FL_WHITE)
and the same colors as
Fl::foreground(). This color is used as a background by Fl_Input and
other text widgets.
int Fl::args(int argc, char** argv, int
&i, int (*callback)(int,char**,int&)=0)
-display host:n.n
The X display to use (ignored
by MSWindows).
-geometry WxH+X+Y
The window position and size
will be modified according the the standard X geometry string.
-name string Fl_Window::xclass(string)
will be
done to the window, this will change it's icon.
-title string Fl_Window::label(string)
will be
done to the window, changing both it's title and the icontitle.
-iconic Fl_Window::iconize()
will be done to
the window.
-bg color
XParseColor is used to lookup the
passed color and then Fl::background() is done. On MSWindows
only color names of the form "#xxxxxx" are understood.
-bg2 color
XParseColor is used to lookup the
passed color and then Fl::background2() is done.
-fg color
XParseColor is used to lookup the
passed color and then Fl::foreground() is done.
int Fl::arg(int argc, char** argv, int &i)
Consume a single switch from argv, starting at word i. Returns the
number of words eaten (1 or 2, or 0 if it is not recognized) and adds
the same value to i. You can use this function if you prefer to
control the incrementing through the arguments yourself.
void Fl::args(int argc, char** argv)
This method is useful if your program does not have command line
switches of it's own. It parses all the switches, and if any are not
recognized it calls
Fl::abort(Fl::help)
.
const char* const Fl::help;
int Fl_Window::show(int argc, char** argv)
show() a window and set the
XA_WM_COMMAND
attribute to
the passed argc/argv. If this is the first time this has been called
since Fl::args() or Fl::arg(), the results of those switches are used
to set the xclass(), label(), and other attributes of this window.
Running
After fltk is "initialized" by calling show() on some window, you get
fltk to wait for and respond to events by calling the following
methods:
int Fl::run()
Runs fltk until there are no windows displayed, and then returns a zero.
Fl::run() is exactly equivalent to:
while (Fl::wait());
return 0;
int Fl::wait()
Calls the idle function if any, then calls any pending timeout
functions, then calls Fl::flush(). If there are
any windows displayed it then waits some time for events (zero if
there is an idle(), the shortest timeout if there are any timeouts, or
forever) and calls the handle() function on those events, and then
returns non-zero.
float Fl::wait(float time)
Wait only a certain amount of time for anything to happen. This does
the same as wait() except if the given time (in seconds) passes it
returns. The return value is how much time remains. If the return
value is zero or negative then the entire time period elapsed.
for (;;) {
for (float time = 1.0; time > 0; ) time = Fl::wait(time);
A();
}
int Fl::check()
This does the same thing as Fl::wait(0), except because it does not
have to return the elapsed time value it can be implemented faster on
certain systems. Use this to interrupt a big calculation:
while (!calculation_done()) {
calculate();
Fl::check();
if (user_hit_abort_button()) break;
}
int Fl::ready();
Returns non-zero if there are pending timeouts or X events or file
descriptors. This does not call Fl::flush() or any callbacks,
which is useful if your program is in a state where such callbacks are
illegal:
void Fl::add_timeout(float t,void (*cb)(void*),void* v=0);
void Fl::remove_timeout(void (*cb)(void*), void* = 0);
Add or remove a one-shot timeout callback. The timeout will happen as
soon as possible after t seconds after the last time wait() was
called. The optional void* argument is passed to the callback. It is
harmless to remove a timeout callback that no longer exists.
void callback(void *) {
printf("TICK\n");
Fl::add_timeout(1.0,callback);
}
main() {...
Fl::add_timeout(1.0,callback);
Fl::run();
}
void Fl::set_idle(void (*cb)());
If the idle callback is set it will be called by Fl::wait() and
Fl::wait() will return immediately. This can be used for background
processing. This will absorb all your machine's time! There is
only one idle callback, changing it will replace the old one. To turn
off the idle processing use Fl::set_idle(0).
void Fl::flush()
Causes all the windows that need it to be redrawn and graphics forced
out through the pipes. This is what wait() does before looking for
events.
int Fl::damage()
If true then flush() will do something.
Fl_Widget *Fl::readqueue();
All Fl_Widgets that don't have a callback defined use a default callback
that puts a pointer to the widget in this queue, and this method reads
the oldest widget out of this queue.
Listening to other file descriptors (Unix only)
void Fl::add_fd(int fd, void (*cb)(int, void*), void* = 0);
void Fl::add_fd(int fd, int when, void (*cb)(int, void*), void* = 0);
void Fl::remove_fd(int);
Add file descriptor fd to listen to. When the fd becomes ready
for reading the callback is done. The callback is passed the fd and
the arbitrary void* argument. Fl::wait() will return immediately
after calling the callback.
Exiting
When all windows are closed Fl::wait() and Fl::run() return zero. If
your main() routine then returns the program exits. You can also call
exit(0) at any time in your program. You do not need to do any
cleanup code for fltk. In particular you do not have to destroy
any widgets you have created. Fltk also does not sneak any atexit
functions in on you either. You will need to do
#include <stdlib.h>
to call exit().
static void main_window_cb(Fl_Widget*, void*) {
if (document_changed()) {
if (!fl_ask("Exit without saving changes?")) return;
// window will not go away as hide() has not been called...
}
exit(0);
}
...somewhere in main():
main_window->callback(window_cb);
void (*Fl::warning)(const char*,...);
void (*Fl::error)(const char*,...);
void (*Fl::fatal)(const char*,...);
Fltk will call these to print messages when unexpected conditions
occur. By default they fprintf to stderr, and Fl::error and Fl::fatal
call exit(1). You can override the behavior by setting the function
pointers to your own routines.