![]() | Overview of programming in FL |
FL is a library of C++ objects and routines that allow you to build a user interface with multiple windows containing buttons, sliders, input fields, dials, etc. in a very simple way.
All public symbols in FL start with the characters 'F' and 'L':
Fl::foo()
or fl_foo()
.
Fl_Foo
.
FL_FOO
.
<FL/...>
.
I intend someday to put all the public symbols of FL in to a C++ namespace called Fl. Currently most compilers do not support namespaces. I simulate one with a dummy class Fl but most symbols are not in it because they would all have to be in the same header file. The change to namespaces will be incompatable and will require replacing all occurances of "fl_" in your code with "Fl::", and may remove the "Fl_" prefix off the include file names).
The first thing your program should do is construct one or more
trees of Fl_Objects
. The base
object of each of these is an Fl_Window
object. All the other
objects are constructed and the add()
method on the
Fl_Window
is used to make them
a child of it. Constructing the objects does not require the display
to be open and does not open it, unless you purposely open it
to get information such as the width of a font.
Fl_Window
s are displayed on
the screen with the show()
method. The first one of
these will open the display. Then the program repeatedly calls
Fl::wait()
. Each time
"something happens" Fl::wait()
returns, usually after a
block of X events have been read and processed. The main program can
then test its state and react in any desired way.
If a button or other object is activated, this can be detected by
doing Fl::readqueue()
after
Fl::wait()
, which will
return a pointer to the object. Alternatively you can set the object
up with a callback, this function is called
from inside Fl::wait()
just before it returns.
To display graphic data, you must subclass either Fl_Window
or Fl_Object
and define the virtual
draw()
method. This can
use functions defined in <FL/fl_draw.H>, or can use
system-specific calls such as Xlib. If the
data being displayed changes, your main program calls the
redraw()
method on your object, and FL will call
draw()
while waiting for the next event. Subclassing
Fl_Window
or Fl_Object
is so easy that I
felt it unnecessary to provide the "canvas" object that most toolkits
have.
If your program needs to monitor another device (such as stdin) you
can provide a callback routine for when it becomes ready, by using
Fl::add_fd(i)
. If your
program needs something to happen at regular intervals you can define
a timeout callback with Fl::add_timeout(time)
. If
any of these happen then Fl::wait()
will return so you can test
the state.
Building a large hierarchy is made much easier with the FL User Interface Designer "Fluid". This is a program that lets you interactively design the object layout and set all the properties visually. It outputs C++ source code that you compile and link with your program. All you have to write is the main loop and any callbacks.