You are on page 1of 31

FLTK 1.3.

0 Tutorial
This a tutorial can be used by the absolute FLTK beginner. In the course of the tutorial
the most common widgets will be explained and you will gain a good overview of the FLTK
toolkit. The examples have been kept as short and simple as possible so it will not take a
lot of time to understand them.
I ported FLTK to D! and took the screenshots in D!. The examples will work without
any changes on any platform FLTK can be used for.
Contents
". Introduction
#. The FLTK structure
$. Installation of the FLTK toolkit
%. The first program
&. The button widget
'. (allback functions
). Input and utput boxes
*. The editor widget
+. The browser widget
",. The menubar widget
"". Toolbar and drop-down list
"#. . dialog window with radio buttons
"$. Displaying images
"%. /rouping widgets in Tabs
"&. 0andling mouse events part"
"'. 0andling mouse events part#
"). Displaying the events generated by FLTK
"*. The tree widget
"+. 1eferences
1. Introduction
FLTK shall stand for Fast Light ToolKit and is a /2I written in (33 for (33 programs. It
can be used on Linux4 5indows4 .pple 6ac and D!. FLTK has lower memory
re7uirements than other toolkits and can be linked as a static library with an application. It
can also be compiled as a shared library too.
FLTK has been in development over many years and the currently latest version is ".$.,.
There had been a version #., before but unfortunately this branch never got out of alpha
and development of that has been canceled now in favor of version ".$.,. !o ".$., is the
version any new development should be based on.
2. The FLTK structure
8eing written in (33 FLTK defines a class for every widget. /2I toolkits usually refer to all
sorts of ob9ects4 like buttons4 input boxes4 scrollbars etc as widgets.
The base class for all widgets is the Fl:5idget class. .ll widgets are subclasses from the
Fl:5idget class or again subclasses from these subclasses.
This are some of the direct subclasses of Fl:5idget; Fl:8ox4 Fl:8utton4 Fl:/roup4
Fl:Input:4 Fl:6enu:4 Fl:<rogress and Fl:Timer.
. subclass of Fl:/roup again is Fl:5indow4 a class you will be using in every program.
.n example of a long tree of subclasses is FL:1adio:1ound:8utton. .s shown below this
button type is a subclass of Fl:1ound:8utton which is a subclass of Fl:Light:8utton
which is again a subclass of Fl:8utton.
The FL:1adio:1ound:8utton class has access to all methods or functions defined in one
of the classes it is a subclass of. =ou will have to check in the documentation whether any
of these classes has a method which does what you want to achieve.
There is also the FL global >static? class containing state information and global methods
for the current application.
In addition several non-class functions and symbols are provided4 they are grouped into
header files with lower-case names.
3. Installation of the FLTK toolkit
a.? Linux
download the latest source4 unpack it and then do configure4make4install. Then compile
your program e.g. as;
@fltk-configA --compile example.cxx@
or if you use images;
@fltk-config --use-images --compile example.cxx@
Further details can be found in the FLTK manual here;
http;BBwww.fltk.orgBdoc-".$Bbasics.html There is a section called @(ompiling <rograms with
!tandard (ompilers@ further below on that page.
=ou can also read the 1C.D6C.2nix.txt file that is included in the FLTK source code
package. This also covers using FLTK with the (ode;;8locks IDC.
b.? 5indows
There are a number of alternatives to develop FLTK programs on 5indows. The FLTK site
9ust has the source code so you either compile FLTK on 5indows or download binaries
from the net as described below.
b".? DCD-(<<
This is an IDC which uses 6in/5 to generate ( and (33 programs on 5indows. =ou can
download it here; http;BBwww.bloodshed.netBdevBdevcpp.html
Then you can download a @devpak@ of FLTK ".$., here;
http;BBnanox-microwindows-nxlib-fltk-for-dos.googlecode.comBfilesBfltk-"$,-"gp.Dev<ak
.fter starting DCD-(<< select @Tools@ from the menu and @<ackage 6anager@. In there
select @Install@ and open the downloaded Dev<ak to install it.
Then open a new pro9ect >File-EFew-E<ro9ect?4 select the @/2I@ tab and in there select
@FLTK@. .fter a few 7uestions how to name the pro9ect and the program file this will come
up with the default FLTK program which you can build and run by entering @F+@.
b#.? (ode;;8locks
This is another good IDC using 6in/5. If you open a new pro9ect4 you can select the
FLTK icon in there. .fter that you will have enter the location of the FLTK files. =ou can
download the binaries here; http;BBcode.google.comBpBfltkwinbinBdownloadsBlist
and then put them into a directory of your choice. Then enter that path into the
(ode;;8locksA input box. (ode;;8locks 9ust needs the path to the root FLTK directory where
bin4 include4 lib4 share and test are in.
=ou can then select file-Enew-Eempty file and save that as main. Then cut and past one of
the examples in this tutorial into the edit window and save the file.
Then right-click on the pro9ect4 select @8uild options@ and add the following libraries to the
linker settings;
libcomctl$#.a4 libcomdlg$#.a4 libole$#.a4libgdi$#.a and libuuid.a. =ou find these libraries in
the @(ode8locksG6in/5GlibG@ directory.
.fter this select 8uild-E1un or (T1L-F", that should build the pro9ect and run it.
b$.? (ompile FLTK on 5indows with 6in/5.
8oth DCD-(<< and (ode;;8locks install 6in/5 on your <(. If you install 6in/5 after
you already have installed one of these IDCs 5indows will point to the new 6in/5
directory and and that causes problems with DCD-(<<.
Details how to compile FLTK with 6in/5 are in the file 1C.D6C.6!5indows.txt which is
included in the FLTK source code package.
It also described in there how to use FLTK with (ygwin.
=ou can also compile FLTK on 5indows with (ode;;8locks if you follow this tutorial;
http;BBgintasdx.althirius-studios.comB#,""B,*Btutorial-codeblocks-with-fltk.html
b%.? 6icrosoft Disual (33
This is covered in the file 1C.D6C.6!5indows.txt.
Further details can also be found here;
http;BBresearch.cs.wisc.eduBgraphicsB(oursesB&&+-f#,,+B6ainBTutorial"
c.? .pple ! H
<lease read the file 1C.D6C.!H.txt which is included in the FLTK source code package.
d.? D!
Download the DI/<< package from
http;BBcode.google.comBpBnanox-microwindows-nxlib-fltk-for-dosBdownloadsBlist 4
edit the start.bat file in there to your paths. The re7uired FLTK libraries are already
included in the DI/<< package but can be downloaded from that site separately as well.
=ou can compile the examples either with this line >observe the line wrap here?;
gpp -g -IBd9gppBinclude -o example.exe example.cxx -LBd9gppBlib -lfltk -lFH"" -lnano-H
-lfreetype
For the examples which load an image you have to add additional parameters to this line;
gpp -g -IBd9gppBinclude -o ex"$.exe ex"$.cxx -LBd9gppBlib -lfltk:images -lfltk -lFH"" -lnano-H
-lfreetype -l9peg -lpng -lJ
r you enter a shell with @sh@ and use the @fltk-config@ script;
sh-#.,%K Afltk-configA --compile example.cxx
sh-#.,%K Afltk-configA --use-images --compile example.cxx
4. The first program
This tutorial starts with very simple examples. !ome readers may consider them too
simple but those may read these parts more 7uickly.
ur first program 9ust opens a window with a title. =ou can terminate the program by
closing the window with your mouse or pressing the C!( key.
To run this or any other example please copy the lines below and paste them into the
editor that you will use for compiling the code.
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
int main()
{
// Create a window - width, heiht, la!el ("title)
Fl_Window win(#$$, #$$,%FL&' &utorial - ()am*le +%),
// -i.*la/ the window
win..how(),
// 0un and return
return Fl11run(),
2
.ll programs must include the file LFLBFL.0E to include the FLTK global class FL. In
addition the program must include a header file for each FLTK class it uses4 in our case it
is 9ust Fl:5indow4 a subclass of Fl:/roup.
The statement;
Fl:5indow win>%,,4 %,,4@FLTK Tutorial - Cxample "@?M
creates a new ob9ect of the Fl:5indow class called @win@. The call also defines the siJe of
the window to be created and the title string.
Then there is a call the @show@ method of the Fl:5indow class to display the window;
win.show>?M
Finally every FLTK program has to have the Fl;;run>? statement;
return Fl;;run>?M
This enters the FLTK event loop. The program now waits for events4 like mouse clicks or
keystrokes to happen and act upon them. 5hen the window is closed or the C!( key
pressed4 this function will return.
. The !utton "idget
0ere are two examples that add a button to the window made in the example above. The
first one extends the example above while the other defines a subclass of FL:5indow
which gives the code a completely different structure.
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_3utton.H>
int main(int arc, char 44ar5)
{
// Create a window - width, heiht, la!el ("title)
Fl_Window 4win " new Fl_Window(6#$,+7$,%FL&' &utorial - ()am*le 8%),
// 9et color o: window to white
win->color(FL_WH;&(),
// 3ein addin children to thi. window
win->!ein(),
//Create a !utton - ) , / , width, heiht, la!el
Fl_3utton 4!utton+ " new Fl_3utton(8<,+<,+#$,#$,%='%),
// 9et color o: !utton to red
!utton+->color(FL_0(-),
// 9to* addin children to thi. window
win->end(),
// -i.*la/ the window
win->.how(),
// 0un and return
return Fl11run(),
2
!ince we are using a new widget here4 the button widget4 we have to include a header file
for that class first.
The statement;
Fl_Window 4win " new Fl_Window(6#$,+7$,%FL&' &utorial - ()am*le 8%),
creates a pointer to the new window ob9ect @win@. This is different to the first example and
we will have to use @win-Eshow>?M@ now instead of @win.show>?M@ as before.
Then we use a @set@ method to turn the color of our window to white;
win->color(FL_WH;&(),
FLTK usually has a corresponding @get@ method for each @set@ method. 0ere @Fl:color c N
win-Ecolor>?M@ would return the current window color in @c@.
Then there is;
win->!ein(),
that tells FLTK to start a group of children for our @win@ ob9ect. This statement could be
omitted and FLTK will add this implicitly then.
Following that we create a pointer to a new button ob9ect;
Fl_3utton 4!utton+ " new Fl_3utton(8<,+<,+#$,#$,%='%),
and make a @set@ statement to set its color to red.
The statement
win->end(),
will tell FLTK that we are done defining the children for the @win@ ob9ect. The defined group
will be set to the parent of the window4 in this case to F2LL because @win@ does not have a
parent.
The following statements will cause the window to be displayed and enter the FLTK event
loop.
!o far we have not defined classes in the examples. To show how this can be done using
FLTK classes and inheritance we rewrite the example above;
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_3utton.H>
cla.. >/Window 1 *u!lic Fl_Window
{
*u!lic1
>/Window(int width, int heiht, con.t char4 title"$) 1
Fl_Window(width,heiht,title)
{
// 9et color o: window to white
color(FL_WH;&(),
// 3ein addin children to thi. window
!ein(),
//Create a !utton - ) , / , width, heiht, la!el
Fl_3utton 4!utton+ " new Fl_3utton(8<,+<,+#$,#$,%='%),
// 9et color o: !utton to red
!utton+->color(FL_0(-),
// 9to* addin children to thi. window
end(),
// -i.*la/ the window
.how(),
2
2,
int main()
{
// Create a window with our new cla.. - width, heiht, la!el ("title)
>/Window win(6#$,+7$,%FL&' &utorial - ()am*le 8??%),
// 0un and return
return Fl11run(),
2
0ere the statement
cla.. >/Window 1 *u!lic Fl_Window
creates a class called 6y5indow which is derived from the Fl:5indow class. In the
constructor of this class we define the color of the window4 the button as a child of the
window and display the window. !ince the @this@ pointer is implicit4 you do not need a
pointer in front of the begin>?4 end>? and show>? statements.
In the main function we 9ust create a new ob9ect of the 6y5indow class called @win@ and
then enter the FLTK event loop.
#. Call!ack functions
Fow we will add a callback function which will be called by FLTK as soon as the button is
clicked. This callback function will then change the color of the button.
There is no screenshot provided since it looks like the one in the previous example.
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_3utton.H>
5oid !utton+_c!(Fl_Widet4 !utton*tr){
i: (!utton*tr->color() "" FL_3L@() {
!utton*tr->color(FL_0(-), //tole
2el.e {
!utton*tr->color(FL_3L@(),//tole
2
2
int main(int arc, char 44ar5)
{
// Create a window - width, heiht, la!el ("title)
Fl_Window 4win " new Fl_Window(6#$,+7$,%FL&' &utorial - ()am*le 6%),
win->color(FL_WH;&(),
// 3ein addin children to thi. window
win->!ein(),
//Create a !utton - ) , / , width, heiht, la!el
Fl_3utton 4!utton+ " new Fl_3utton(8<,+<,+#$,#$,%ClicA meB%),
!utton+->color(FL_0(-),
//rei.ter call!acA :unction with thi. !utton
!utton+->call!acA(!utton+_c!),
// 9to* addin children to thi. window
win->end(),
// -i.*la/ the window
win->.how(),
// 0un and return
return Fl11run(),
2
The statement;
!utton+->call!acA(!utton+_c!),
defines that the callback @button":cb@ will be called when the user clicks on it.
This function is defined as
5oid !utton+_c!(Fl_Widet4 !utton*tr)
<lease observe that a pointer to the Fl:5idget class is passed and not to Fl:8utton. This
way we can only use methods defined in Fl:5idget. For this example this is fine since we
will only be using the @color@ method defined in Fl:5idget. If we want to use methods
defined in the Fl:8utton class we will have to cast the buttonptr to a Fl:8utton class e.g;
Fl_3utton4 ! " (Fl_3utton4)!utton*tr,
The rest of the function checks if the button color is blue and if yes turns it to red and vice
versa.
$. Input and %utput !o&es
This example will display an input and an output widget. The text you enter in the input box
will be copied into the output box and the label of the input box will be changed.
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_;n*ut.H>
#include <FL/Fl_=ut*ut.H>
Fl_;n*ut in*ut+(C$, +$, +7$, 8$, %;n*ut 1 %),
Fl_=ut*ut out*ut+(C$, #$, +7$, 8$, %=ut*ut 1 %),
.tatic 5oid c!_in*ut+(Fl_;n*ut4, 5oid4 u.erdata) {
in*ut+.la!el((con.t char4)u.erdata),
out*ut+.5alue(in*ut+.5alue()),
in*ut+.5alue(%%), //clear aain
2
int main(int arc, char 44ar5) {
Fl_Window win(6$$, C$, %()am*le :or ;n*ut and =ut*ut !o)e.%),
win.!ein(),
win.add(in*ut+),
in*ut+.call!acA((Fl_Call!acA4)c!_in*ut+,(5oid 4)%(nter ne)t1%),
in*ut+.when(FL_WH(D_0(L(E9( F FL_WH(D_(D&(0_'(G),
win.add(out*ut+),
win.end(),
win..how(),
return Fl11run(),
2
0ere input" and output" are defined as globals so they can be accessed in the input"
callback function.
In the main function we define a window ob9ect called @win@ and add the input" and
output" widgets to that using the @win.add>?@ statements.
In the next line;
in*ut+.call!acA((Fl_Call!acA4)c!_in*ut+,(5oid 4)%(nter ne)t1%),
the callback function @cb:input"@ is set to be called if an event regarding the input" widget
occurs.
.s an example we have used the second parameter of the callback function here to pass a
void pointer to the string @Cnter next;@. This parameter is called the @userdata@ parameter.
0ere the pointer will be used as label text in the callback function.
Following that using the @.when>?@ method it is defined what event shall trigger the callback
function. This will be the Cnter key and when the input widget is released.
In the callback function the label of the input" widget is changed to the userdata string.
The value of the input widget4 i.e. the text entered into this widget4 is copied into the output
widget und the input widget is cleared again after that.
'. The editor "idget
This program shows how to use the editor widget included in FLTK. This example is taken
from /reg Crcolanos FLTK cheat sheet page at; http;BBseriss.comBpeopleBercoBfltkB
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_&e)t_(ditor.H>
int main() {
Fl_Window 4win " new Fl_Window(#$$, 8$$),
Fl_&e)t_3u::er 4!u:: " new Fl_&e)t_3u::er(),
Fl_&e)t_(ditor 4di.* " new Fl_&e)t_(ditor(8$, 8$, 6H$, +H$, %(ditor Window%),
di.*->!u::er(!u::),
win->re.iIa!le(4di.*),
win->.how(),
!u::->te)t(%FL&' &utorial%), //add initial te)t here i: reJuired
return(Fl11run()),
2
.lthough the editor widget is comprised of a lot of FLTK code4 it is simple to use.
First there are pointers created to the new window ob9ect @win@4 the new buffer ob9ect @buff@
and the new editor widget @disp@. Then the buffer ob9ect is attached to the editor ob9ect
using the @buffer@ method the Fl:Text:Cditor widget has inherited from the FL:Display
widget;
di.*->!u::er(!u::),
5ith the @text>?@ method we can move a string into the buffer.
(. The !ro"ser "idget
The browser widget displays an array of strings line by line in a window and lets the user
select items from this list. 0ere the browser is initialiJed with three lines. 5henever one of
these lines is clicked an additional line is added stating what line was selected.
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_3row.er.H>
5oid !row.er_c!(Fl_Widet 4w) {
Fl_3row.er 4! " (Fl_3row.er4)w, //ca.t to et acce.. to 3row.er method.
// retrie5e .elected item :rom !row.er
int inde) " !->5alue(),
// add te)t to !row.er u.in the retrie5ed inde) num!er
i: ( inde) "" + ) {
!->add(%Gou .elected Line+%),
2 el.e i: ( inde) "" 8 ) {
!->add(%Gou .elected Line8%),
2 el.e i: ( inde) "" 6 ) {
!->add(%Gou .elected Line6%),
2
2
int main() {
Fl_Window 4win " new Fl_Window(6$$,8$$,%3row.er ()am*le%),
Fl_3row.er 4! " new Fl_3row.er(+$,#$,win->w()-8$, win->h()-<$),
!->t/*e(FL_>@L&;_30=W9(0),
!->add(%Line+%),
!->add(%Line8%),
!->add(%Line6%),
!->call!acA(!row.er_c!),
win->.how(),
return(Fl11run()),
2
In the main>? function we first create pointers to a new window and browser ob9ect. For the
browser ob9ect we use the @get@ functions @win-Ew>?@ and @win-Eh>?@ to retrieve the siJe of
the window @win@ to fit it into that. Then we add three lines into the browser ob9ect and
register its callback function as @browser:cb@.
In the callback function we first cast the Fl:5idget pointer to a Fl:8rowser pointer to be
able to use the value method of this widget. 5ith the statement;
int inde) " !->5alue(),
we can retrieve which of the three lines the user has clicked last and thus selected it. The
index of this line is used to add additional lines to the browser specifying which line had
been selected on each click.
10. The menu!ar "idget
This example opens a window with a small menubar. The menu items selected will be
displayed in the window title.
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_>enu_3ar.H>
Fl_Window4 win,
5oid >enu_C3_=*en(Fl_Widet4 w,5oid4) {win->la!el(%=*en .elected%),2
5oid >enu_C3_9a5e(Fl_Widet4 w,5oid4) {win->la!el(%9a5e .elected%),2
5oid >enu_C3_Kuit(Fl_Widet4 w,5oid4) {win->la!el(%Kuit .elected%),2
5oid >enu_C3_Hel*(Fl_Widet4 w,5oid4) {win->la!el(%Hel* .elected%),2
int main() {
// =*en the a**lication window and menu !ar with call!acA.
win " new Fl_Window(#8$, 87$),
win->color(FL_WH;&(),
Fl_>enu_3ar menu!ar($, $, win->w(), 8<),
menu!ar.add(%LFile/L=*en%, $, >enu_C3_=*en),
menu!ar.add(%LFile/L9a5e%, $, >enu_C3_9a5e),
menu!ar.add(%LFile/LKuit%, $, >enu_C3_Kuit),
menu!ar.add(%LHel*%, $, >enu_C3_Hel*),
win->end(),
win->.how(),
return(Fl11run()),
2
To keep the example short4 @win@ is defined as a global Fl:5indow ob9ect pointer so we
can use it directly in the callback functions.
0ere a Fl:6enu:8ar ob9ect called @menubar@ is added to our main window. There are four
menubar items defined. The @O@ character defines the shortcut key for this menu item. The
first three statements define the @File@ menu with the subitems @pen@4 @!ave@ and @Puit@.
The @0elp@ item has no submenu items. Cach statement defines the callback function that
shall be called if the user clicks on the menu item. 0ere these callback functions change
the label >title? of the main window to show which menu item had been selected.
11. Tool!ar and drop)do"n list
6any applications place a toolbar with several icons below a menu bar. In this example not
only icons but also a drop down list is placed in such a toolbar.
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_3utton.H>
#include <FL/Fl_Mi)ma*.H>
#include <FL/Fl_;n*ut.H>
#include <FL/Fl_Nrou*.H>
#include <FL/Fl_Choice.H>
#include <FL/:l_a.A.H>
#include <FL/Fl_>enu_3ar.H>
#de:ine F=D&_9(0;F +
#de:ine F=D&_9ED9_9(0;F 8
#de:ine F=D&_>=D=9MEC( 6
.tatic con.t char 4.a5e_)*mOP " {
%+H +H C +%,
% c Done%,
%. c #$$$$$$%,
%? c #$$$$FF%,
%Q c #$$$$7$%,
%# c #E$E$E$%,
%R c #$$$$C$%,
%S c #FFFFFF%,
%L c #C$C$FF%,
%4 c #-C-C-C%,
%................%,
%.?Q##########Q?.%,
%.RQSSSSSSSSSSQR.%,
%.?QSSSSSSSSSSQ?.%,
%.?QS########SQ?.%,
%.?QSSSSSSSSSSQ?.%,
%.?QS########SQ?.%,
%.?QLSSSSSSSSLQ?.%,
%.??QQQQQQQQQQ??.%,
%.??????????????.%,
%.??R......QQR??.%,
%.??.444444.?Q??.%,
%.??.4Q?444.?Q??.%,
%.??.4Q?444.?Q??.%,
%.Q?.444444.?Q??.%,
% ...............%2,
cla.. &ool!ar 1 *u!lic Fl_Nrou* {
*u!lic1
Fl_3utton 4.a5e+,
Fl_3utton 4.a5e8,
Fl_Mi)ma* 4*_.a5e,
Fl_Choice 4:ont_rou*,
Fl_>enu_;tem 4:ont_rou*_item.,
.tatic 5oid c!_.a5e(Fl_Widet4, 5oid4),
.tatic 5oid c!_:ont.(Fl_Widet4, 5oid4),
&ool!ar(int T*o., int G*o., int Width, int Heiht),
2,
5oid &ool!ar11c!_.a5e(Fl_Widet 4w, 5oid 4data){
:l_alert(%9a5e 3utton Sd *re..edB%,(int)data),2
5oid &ool!ar11c!_:ont.(Fl_Widet 4w, 5oid 4data){
:l_alert(%Font num!er Sd .electedB%,(int)data),2
&ool!ar11&ool!ar(int T*o., int G*o., int Width, int Heiht) 1
Fl_Nrou*(T*o., G*o., Width, Heiht)
{
!o)(FL_@M_3=T),
G*o. ?" 8, Heiht -" #, T*o. ?" 6, Width " Heiht,
int i,
.a5e+ " new Fl_3utton(T*o., G*o., Width, Heiht), T*o. ?" Width ? <,
.a5e8 " new Fl_3utton(T*o., G*o., Width, Heiht), T*o. ?" Width ? <,
:ont_rou* " new Fl_Choice(T*o., G*o., ++$, Heiht), T*o. ?" +++,

*_.a5e " new Fl_Mi)ma*(.a5e_)*m),
.a5e+->imae(*_.a5e),
.a5e8->imae(*_.a5e),
.a5e+->toolti*(%9a5e :ile+%),
.a5e+->call!acA(c!_.a5e,(5oid4)+),
.a5e8->toolti*(%9a5e :ile8%),
.a5e8->call!acA(c!_.a5e,(5oid4)8),
:ont_rou*_item. " new Fl_>enu_;temO#P,
:or (i " $, i < #, i??) :ont_rou*_item.OiP.te)t " D@LL,
:ont_rou*_item.->add(%9eri:%, $, c!_:ont., (5oid4) F=D&_9(0;F, $),
:ont_rou*_item.->add(%9an.-9eri:%, $, c!_:ont.,(5oid4) F=D&_9ED9_9(0;F, $),
:ont_rou*_item.->add(%>ono.*ace%, $, c!_:ont., (5oid4) F=D&_>=D=9MEC(, $),
:ont_rou*->menu(:ont_rou*_item.),
2
int main()
{
Fl_Window win(<$$, 6$$,%FL&' &ool!ar ()am*le%),
win.color(FL_WH;&(),
win.!ein(),
Fl_>enu_3ar menu!ar($, $, win.w(), 8<),
menu!ar.add(%LFile%, $, $),
menu!ar.add(%L(dit%, $, $),
&ool!ar tool($,8H,win.w(),6$),
tool.clear_5i.i!le_:ocu.(), //Uu.t u.e mou.e, no &E3.
win.end(),
win..how(),
return Fl11run(),
2
In the main window first there is defined a menubar and below that an ob9ect of the Toolbar
class which is defined in this program. 5hen this Toolbar ob9ect is created its position and
siJe is specified.
The constructor will first make a box of the siJe of the toolbar. Then two icons and a drop-
down list widget are placed in this box. The icons are defined as an H<6 image which
again is specified at the top of the code. .n H<6 image can e.g. be created on 5indows
with the xpmedit program; http;BBwww.9land.orgBswatBxpmeditB . To save space the same
icon is used here twice in the example.
Then an FL-<ixmap ob9ect of the H<6 image is made in the constructor and using image>?
it is set as the image for both buttons. Further for each button a tooltip and a callback
function is specified.
Following that the drop-down list is defined. The items of this list are specified as menu
items. These items have the same callback function4 9ust different userdata is passed.
.fter calling menu>? the items are shown in the drop-down list on the screen.
The callback functions use the @fl:alert@ function to display the userdata passed and
indicate which button or item has been selected by the user. The @fl:alert@ function can
take the message text in an sprintf-like format.
FLTK features a number of common dialog functions which are documented in the
@modules@ section of the FLTK documentation. These are defined with lower-case letter
names.

12. * dialog "indo" "ith radio !uttons
This example shows how to open a dialog window when a menu item is selected. It is
often necessary to define a window where the user can make a number of selections.
#include <FL/Fl.H>
#include <FL/Fl_Nrou*.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_3utton.H>
#include <FL/Fl_0ound_3utton.H>
#include <FL/Fl_>enu_3ar.H>
cla.. -ialo_Window 1 *u!lic Fl_Window
{
*u!lic1
int .tatu.,
int radio,
.tatic -ialo_Window 4dw_thi.,
.tatic 5oid c!_!utton(Fl_Widet 4w, 5oid 4d),
.tatic 5oid c!_radio(Fl_Widet 4!, 5oid 4d),
-ialo_Window(int )*o., int /*o., int width, int heiht,
con.t char4 title"$) 1 Fl_Window()*o.,/*o.,width,heiht,title)
{
dw_thi. " thi.,
color(FL_WH;&(),
// 3ein addin children to thi. window
!ein(),
Fl_Nrou*4 r!_rou* " new Fl_Nrou*(+<, +$, +$<, +$<),
r!_rou*->!o)(FL_@M_F0E>(),
{ Fl_0ound_3utton4 r!+ " new Fl_0ound_3utton(8$, +<, V$, 6$, %LCo::ee%),
r!+->t/*e(+$8),
r!+->down_!o)(FL_0=@D-_-=WD_3=T),
r!+->call!acA(c!_radio,(5oid4)+),
2
{ Fl_0ound_3utton4 r!8 " new Fl_0ound_3utton(8$, #<, V$, 6$, %L(.*re..o%),
r!8->t/*e(+$8),
r!8->down_!o)(FL_0=@D-_-=WD_3=T),
r!8->call!acA(c!_radio,(5oid4)8),
2
{ Fl_0ound_3utton4 r!6 " new Fl_0ound_3utton(8$, V<, V$, 6$,
%CaL**ucino%),
r!6->t/*e(+$8),
r!6->down_!o)(FL_0=@D-_-=WD_3=T),
r!6->call!acA(c!_radio,(5oid4)6),
2
r!_rou*->end(),

Fl_3utton 4!utton_oA " new Fl_3utton(+$,+<$,7$,#$,%='%),
Fl_3utton 4!utton_c " new Fl_3utton(++$,+<$,7$,#$,%Cancel%),
!utton_oA->call!acA(c!_!utton,(5oid4)+),
!utton_c->call!acA(c!_!utton,(5oid4)8),
end(),
.et_modal(),
.how(),
2
2,
-ialo_Window 4-ialo_Window11dw_thi. " D@LL,
5oid -ialo_Window11c!_radio(Fl_Widet 4!, 5oid 4d) {
char m.OH#P,
dw_thi.->radio"(int)d,
.*rint:(m., %0adio 3utton1 Sd%, dw_thi.->radio),
dw_thi.->la!el(m.),
2
5oid -ialo_Window11c!_!utton(Fl_Widet 4w, 5oid 4d)
{
dw_thi.->hide(),
dw_thi.->.tatu. " (int)d,
2
5oid c!_:ile(Fl_Widet 4w, 5oid 4data){
Fl_Window4 *arent"(Fl_Window4)data,
*arent->la!el(%Mlea.e enter data now%),
-ialo_Window4 dw " new -ialo_Window(*arent->)()?8$,*arent->/()?8$,
8$$, 8$$, D@LL),
2
int main()
{
Fl_Window win(6$$, 8<$,%FL&' -ialo Window ()am*le%),
win.color(FL_WH;&(),
win.!ein(),
Fl_>enu_3ar menu!ar($, $, win.w(), 8<),
menu!ar.add(%LCo::ee%, $, c!_:ile,(5oid4)Lwin),
win.end(),
win..how(),
return Fl11run(),
2
In this example the main window 9ust has a menu bar with one item to call the dialog
window. The menu item passes a pointer to the main window as userdata in the callback.
The callback can then change the label of the main window and read its position so the
dialog window is created at a fixed position relative to the main window no matter where
this currently is on the screen. The callback makes an ob9ect of the Dialog:window class
called @dw@. This class defines the dialog window called Dialog:window.
The constructor of this class opens the dialog window and defines a group with three radio
buttons or round buttons. There is a box drawn around the group of radio buttons.
.lso there are an K and a (ancel button defined in the dialog window. The dialog
window is opened @modal@ so user input is directed to this window only while it is
displayed.
The callback functions of each button are passed the number of the button in the userdata
parameter. Thes callback function makes a msg string with this number and writes it to the
title of the dialog window. It also writes the number to the public integer variable @radio@ in
the Dialog:window ob9ect.
The K and (ancel button callbacks hide the dialog window and write a status value into
the public variable of the Dialog:window ob9ect.
This example also shows how to make the @this@ pointer of the Dialog:window dw ob9ect
available in the entire program. The @this@ pointer of this ob9ect is written into the static
variable @dw:this@ which is also initialiJed outside the class definition and therefore can be
accessed from anywhere in the program.
13. +ispla,ing images
The first example displays a <F/ image in a window4 the second displays a I</ image in
a smaller window and lets you scroll the image using scrollbars. 8oth examples were
developed by /reg Crcolano.
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_9hared_;mae.H>
#include <FL/Fl_MDN_;mae.H>
#include <FL/Fl_3o).H>
int main() {
:l_rei.ter_imae.(), // initialiIe imae li!
Fl_Window win(<$$,#$$), // maAe a window
Fl_3o) !o)(+$,+$,<$$-8$,#$$-8$), // widet that will contain imae
Fl_MDN_;mae *n(%Uoll/.*n%), // load *n imae into ram
!o).imae(*n), // attach *n imae to !o)
win..how(),
return(Fl11run()),
2
The included comments explain the example already. There is a new widget used here;
Fl:8ox. This box is not visible since when you attach the image to this ob9ect you see the
image in the defined box.
5hen creating the Fl:<F/:Image ob9ect the image file is already read from disk because
the constructor of this class loads the named <F/ image from the given png filename.
This is the second example;
#include <.tdio.h>
#include <.tdli!.h>
#include <FL/Fl.H>
#include <FL/Fl_9hared_;mae.H>
#include <FL/Fl_-ou!le_Window.H>
#include <FL/Fl_9croll.H>
#include <FL/Fl_WM(N_;mae.H>
#include <FL/Fl_3o).H>
#de:ine WMNF;L( %Uoll/.U*%
int main() {
:l_rei.ter_imae.(),
Fl_-ou!le_Window win(<8$,#$$,%()am*le imae 5iewer with .croll!ar.%),
Fl_9croll .cr($,$,<8$,#$$),
Fl_WM(N_;mae U*(WMNF;L(),
i: ( U*.h() "" $ ) { *error(WMNF;L(), e)it(+), 2 // error checA
Fl_3o) !o)($,$,U*.w(),U*.h()),
!o).imae(U*),
win.re.iIa!le(win),
win..how(),
return(Fl11run()),
2
In this example the Fl:!croll widget is used. This is a container widget and will let
scrollbars appear if its child widget4 here the I<C/ image4 is larger than the siJe of this
scroll widget. In this program the siJe of the scroll widget is set to the siJe of the main
window.
The main window is defined using the Fl:Double:5indow subclass. This subclass will be
using a double-buffered window. If possible this window widget will use the H double
buffering extension >Hdbe?. If not4 it will draw the window data into an off-screen pixmap4
and then copy it to the on-screen window.
=ou can take any <F/ or I<C/ image. I made /oogle image search for @Iolly 1oger@ and
converted the result into a <F/ and a I<C/ file for this example.
14. -rouping "idgets in Ta!s
This is another example from /reg Crcolano showing how T.8s work in FLTK. There are
two T.8s which group two different sets of buttons.
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_&a!..H>
#include <FL/Fl_Nrou*.H>
#include <FL/Fl_3utton.H>
int main(int arc, char 4ar5OP) {
Fl_Window 4win " new Fl_Window(#$$,8$$,%&a!. ()am*le%),
{
Fl_&a!. 4ta!. " new Fl_&a!.(+$,+$,#$$-8$,8$$-8$),
{
// E ta!
Fl_Nrou* 4aaa " new Fl_Nrou*(+$,6<,#$$-8$,8$$-#<,%E-3utton.%),
{
Fl_3utton 4!+ " new Fl_3utton(<$, H$,C$,8<,%3utton E+%),
!+->color(77?+),
Fl_3utton 4!8 " new Fl_3utton(<$, C$,C$,8<,%3utton E8%),
!8->color(77?8),
Fl_3utton 4!6 " new Fl_3utton(<$,+8$,C$,8<,%3utton E6%),
!6->color(77?6),
2
aaa->end(),
// 3 ta!
Fl_Nrou* 4!!! " new Fl_Nrou*(+$,6<,#$$-+$,8$$-6<,%3-3utton.%),
{
Fl_3utton 4!+ " new Fl_3utton( <$,H$,C$,8<,%3utton 3+%),
!+->color(77?+),
Fl_3utton 4!8 " new Fl_3utton(+<$,H$,C$,8<,%3utton 38%),
!8->color(77?6),
Fl_3utton 4!6 " new Fl_3utton(8<$,H$,C$,8<,%3utton 36%),
!6->color(77?<),
2
!!!->end(),
2
ta!.->end(),
2
win->end(),
win->.how(),
return(Fl11run()),
2
In the examples we have used so far we declared a window ob9ect and our buttons and
other widgets were in the group of this window ob9ect. 0ere the window has one child
which is the T.8s widget. This widget has two Fl:/roup ob9ect groups as its childen4 the
group @aaa@ and @bbb@. Cach of these groups has three buttons as its children again.
The T.8s widget will 9ust display the group belonging to the currently selected T.8.
1. .andling mouse e/ents part1
In this program it is monitored whether the mouse is over the box in the middle of the
window. If yes4 the box will turn red. Keyboard events are also retrieved and displayed in
the title bar of the window.
#include <FL/Fl_Window.H>
#include <FL/Fl_-ou!le_Window.H>
#include <FL/Fl.H>
#include <FL/Fl_3o).H>
Fl_Window4 win,
cla.. (5entWindow1 *u!lic Fl_3o)
{
*ri5ate1
int handle_Ae/(int e,int Ae/),
*u!lic1
(5entWindow(int t, int l, int width, int heiht),
int handle(int e),
2,
(5entWindow11(5entWindow(int t, int l, int width, int heiht)
1Fl_3o)(FL_@M_3=T, t, l, width, heiht, %%)
{ la!el:ont(FL_;&EL;C),
la!el.iIe(8#),
la!elt/*e(FL_9HE-=W_LE3(L),
la!el(%=n>ou.e=5er%),
Fl11:ocu.(thi.),
2
int (5entWindow11handle(int e)
{
.witch(e) {
ca.e FL_(D&(01
color (FL_0(-),
la!elcolor(FL_3LEC'),
damae(+),
return +,
ca.e FL_L(EX(1
color(FL_N0EG),
la!elcolor(FL_3LEC'),
damae(+),
return +,
ca.e FL_'(G-=WD1
return handle_Ae/(e,Fl11e5ent_Ae/()),
de:ault1
return Fl_3o)11handle(e),
2,
2
int (5entWindow11handle_Ae/(int e,int Ae/)
{
char la!elte)tO8$P,
.*rint:(la!elte)t,%'e/ entered1 Sc %,Ae/),
win->la!el(la!elte)t),
return +,
2
int main()
{
win " new Fl_Window(6$$, 8$$),
win->color(FL_3L@(),
(5entWindow ewin(8$, 8$, 8H$, +H$),
ewin..how(),
win->end(),
win->.how(),
return Fl11run(),
2
In the main>? function a new window ob9ect is created and this time there is not a button or
a box ob9ect as before but a new window ob9ect called @ewin@ is added as the child. This
window is created using the class Cvent5indow which is defined in this example as a
subclass of the Fl:5indow class. The constructor of this class will write the text
@n6ousever@ into this window.
This class also has a method that overwrites the Fl:5idget;;handle>? virtual method. This
way all the events are sent to this handle>? method by FLTK. The method checks for three
different events and returns a one for those to indicate to FLTK that these events are
handled by this function; FL:CFTC14 FL:LC.DC and FL:KC=D5F. . FL:CFTC1 event
occurs when the mouse is over the window created by the @ewin@ ob9ect while a
FL:LC.DC event occurs when the mouse has been moved outside this window. These
events are used here to change the color of this window.
5hen a FL:KC=D5F event occured4 the function handle:key>? will be called which
displays the key value in the title bar of the main window.
1etrieving keyboard events is usually not necessary with FLTK since you will be using
input boxes etc. for keyboard input which do not re7uire you to keep track of every
keystroke.
1#. .andling mouse e/ents part2
The example is somewhat similar to a paint program. 5hen you click and drag the mouse4
a line will be painted following the mouse movement. 5hen you click once a line will be
drawn to the point of the next click with the LCFT mouse button. If you click with the
1I/0T mouse button a frame will be drawn instead.
This example is based on one posted by Ian 6ac.rthur. Drawing with FLTK is usually
done inside the virtual draw>? method. =ou then implement your own version of this
method for drawing that overwrites FLTKAs draw>? virtual method. 5henever draw>? is
called it will draw the screen again as defined in this method.
For incremental drawing you better draw into an offscreen buffer that is copied to the
screen whenever the draw>? method is called. !ince FLTK does not store the screen
contents these will be erased when the window is iconiJed and restored. The contents in
the offscreen buffer will be preserved though. This example does incremental drawing and
shows the use of such an offscreen buffer.
#include <Fl/Fl.H>
#include <FL/Fl_-ou!le_Window.H>
#include <Fl/Fl_3o).H>
#include <Fl/:l_draw.H>
#de:ine window_.iIe #$$
.tatic Fl_-ou!le_Window 4main_window " $, // the main a** window
.tatic Fl_=::.creen o::.creen_!u::er " $, // the o::.creen .ur:ace
/44444444444444444444444444444444444444444444444444444444444444444444444444444/
/4 &hi. cla.. *ro5ide. a 5iew to co*/ the o::.creen .ur:ace to 4/
cla.. can5a. 1 *u!lic Fl_3o) {
5oid draw(),
int handle(int e5ent),
*u!lic1
can5a.(int ), int /, int w, int h),
2,
/44444444444444444444444444444444444444444444444444444444444444444444444444444/
/4 Con.tructor 4/
can5a.11can5a.(int ), int /, int w, int h) 1 Fl_3o)(),/,w,h){
2 // Con.tructor
/44444444444444444444444444444444444444444444444444444444444444444444444444444/
5oid can5a.11draw() {
i:(o::.creen_!u::er) { // o::.creen e)i.t.
// !lit the reJuired 5iew :rom the o::.creen onto the !o)
:l_co*/_o::.creen()(), /(), w(), h(), o::.creen_!u::er, $,$),
2
el.e { // create the o::.creen
main_window->maAe_current(), //en.ure. .uita!le ra*hic conte)t
o::.creen_!u::er " :l_create_o::.creen( w(), h() ),
i:(Bo::.creen_!u::er){:*rint:(.tderr,%Failed !u::er creation%), e)it(+),2
:l_!ein_o::.creen(o::.creen_!u::er), /4 =*en the o::.creen conte)t 4/
:l_color(FL_WH;&(),
:l_rect:($, $, w(), h() ),
:l_end_o::.creen(), /4 clo.e the o::.creen conte)t 4/
/4 init .creen with o::.creen !u::er 4/
:l_co*/_o::.creen()(), /(), w(), h(), o::.creen_!u::er, $,$),
2
2 // draw method
/44444444444444444444444444444444444444444444444444444444444444444444444444444/
int can5a.11handle(int e5ent) {
.tatic char la!elte)tO+$$P,
int !utton,),/,
int ret5alue " $,
.tatic int )_old,/_old,
.tatic int *u.h+.t"$,
i: (Bo::.creen_!u::er) return +,
ret5alue " Fl_3o)11handle(e5ent),
.witch (e5ent) {
ca.e FL_M@9H1
ca.e FL_-0EN1
!utton " Fl11e5ent_!utton(),
) " Fl11e5ent_)(),
/ " Fl11e5ent_/(),
2,
.witch ( !utton ) {
ca.e +1 // Le:t !utton
.*rint:(la!elte)t,%La.t mou.e !utton" Le:t F >ou.e at Sd,Sd now%,),/),
window()->la!el(la!elte)t),
ret5alue " +,
!reaA,
ca.e 61 // 0iht !utton
.*rint:(la!elte)t,%La.t mou.e !utton" 0iht F >ou.e at Sd,Sd now%,),/),
window()->la!el(la!elte)t),
ret5alue " +,
!reaA,
2
.witch(e5ent) {
ca.e FL_M@9H1
i: (*u.h+.t "" $) {
)_old " ),
/_old " /,
*u.h+.t " +,
!reaA,
2 el.e {
*u.h+.t " $,
/4 =*en the o::.creen conte)t :or drawin 4/
:l_!ein_o::.creen(o::.creen_!u::er),
i: (!utton""+){ //le:t mou.e !utton
:l_color(FL_0(-),
:l_line()_old,/_old,),/),
2 el.e { //riht mou.e !utton
:l_draw_!o)(FL_3=0-(0_F0E>(,)_old,/_old,()-)_old),
(/-/_old),FL_3L@(),
2
:l_end_o::.creen(), /4 clo.e the o::.creen conte)t 4/
redraw(),
2
ca.e FL_-0EN1
{*u.h+.t"$, //clear i: drain
/4 =*en the o::.creen conte)t :or drawin 4/
:l_!ein_o::.creen(o::.creen_!u::er),
:l_color(FL_3LEC'),
:l_*oint(),/),
:l_end_o::.creen(), // clo.e the o::.creen conte)t
redraw(),2
!reaA,
de:ault1
redraw(),
!reaA,
2
return ret5alue,
2 // handle
/44444444444444444444444444444444444444444444444444444444444444444444444444444/
int main (int arc, char 44ar5) {
main_window " new Fl_-ou!le_Window(window_.iIe, window_.iIe,
%-rawin with mou.e e)am*le%),
main_window->!ein(),
// a 5iew o: the o::.creen, in.ide the main window
.tatic can5a. 4o._!o) " new can5a.(<,<,(window_.iIe-+$),(window_.iIe-+$)),
main_window->end(),
main_window->re.iIa!le(o._!o)),
main_window->.how(arc, ar5),

return Fl11run(),
2 // main
. new window class called canvas is defined in this example as a subclass of Fl:8ox. This
defines the area that will be used for drawing. . new ob9ect of this canvas class is created
as a child widget of the main:window in the main>? function.
The canvas class also defines a handle>? method which overwrites the Fl:5idget;;handle>?
virtual method. This way all the events are sent to the canvas handle>? method by FLTK.
This method checks for two different mouse events and returns a one for those to indicate
to FLTK that they are handled by this function; FL:<2!0 and FL:D1./. If one of these
events is received4 this method will write into the title of the window which mouse button
has been clicked last and what the current position of the mouse is.
Then4 if the event is a FL:D1./ it will draw a pixel at the current mouse position. If the
event is a FL:<2!04 9ust the mouse position will be stored. n a second FL:<2!0 event
it depends whether the left or the right mouse button has been clicked. If the left mouse
button was clicked4 a line will be drawn from the position of the first click to the current
mouse position. If the click was done with the right mouse button4 a box will be drawn
instead of the line. The drawing to the offscreen buffer has to be done after a call to
fl:begin:offscreen>? and end with a call to fl:end:offscreen>?.
The draw method 9ust copies the offscreen buffer to the screen. 5hen it is called for the
first time it will use fl:create:offscreen>? to allocate the offscreen buffer and then use
fl:rectf>? to clear the buffer to white. 5hen the buffer is drawn to the screen it will turn the
drawing area to white. Iust to ensure we have a suitable graphic context to base the
offscreen on the main:window is made current.
1$. +ispla,ing the e/ents generated !, FLTK
This example is based on the one given by 1obert .rkiletian in his tutorial. There are two
buttons defined in the window which will cause events when the mouse moves over them
or clicks them4 also keyboard events etc. will be displayed in a scrolling FLTK browser
window. The callback functions defined for the buttons are called when the buttons are
clicked or the letters AaA or AbA are entered.
The siJe of the example could be reduced by using the new fl:eventnames array in FLTK
version ".$.,.
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_3row.er.H>
#include <FL/Fl_3utton.H>
#include <FL/name..h>
Fl_Window 4win,
Fl_3row.er 4!,
cla.. >/3utton 1 *u!lic Fl_3utton
{
.tatic int count,
*u!lic1
char linete)tO+$$P,
>/3utton(int ),int /,int w,int h,con.t char4l"$)
1Fl_3utton(),/,w,h,l) {2
int handle(int e) {
int ret " Fl_3utton11handle(e),
.*rint:(linete)t,%3utton S. ot e5ent1 S., return.1 Sd %, Y
la!el(),:l_e5entname.OeP,ret),
!->add(linete)t),
!->!ottomline(68$$$), //alwa/. di.*la/ the la.t line
return(ret),
2
2,
int >/3utton11count"$,
5oid !ut_a_c!(Fl_Widet4 w, 5oid4 5){
win->la!el(%3utton E call!acAB%),
2
5oid !ut_!_c!(Fl_Widet4 w, 5oid4 5){
win->la!el(%3utton 3 call!acAB%),
2
int main()
{
win" new Fl_Window(<6$,6<$,%FL&' e5ent. e)am*le%),
win->!ein(),
! " new Fl_3row.er(+#$,8$,win->w()-+H$, win->h()-<$),
!->t/*e(FL_>@L&;_30=W9(0),
>/3utton !ut_a(+$,8$,+$$,8<,%E%),
!ut_a.color(FL_3L@(),
!ut_a..hortcut(ZaZ),
!ut_a.call!acA(!ut_a_c!),
>/3utton !ut_!(+$,H$,+$$,8<,%3%),
!ut_!.color(FL_N0((D),
!ut_!..hortcut(Z!Z),
!ut_!.call!acA(!ut_!_c!),
win->end(),
win->.how(),
return(Fl11run()),
2
In the main>? function a new window ob9ect is created and a multi browser widget plus two
buttons are added as children. The browser widget will list the events generated by FLTK
on the screen. For each button a callback function is defined which will display a message
in the windowAs title bar when clicked or when selected by a shortcut key. !hortcut keys
are 9ust the letters AaA and AbA here4 not an .LT- or (T1L- combination.
To create the button ob9ects a new class has been defined called @6y8utton@ which is a
subclass of the Fl:8utton class. .ll that this class does is to overwrite the
Fl:5idget;;handle>? virtual method. This way all the events are sent to this handle>?
method by FLTK and can then be displayed in the browser window. .s you can see in the
screenshot4 some events are sent to both buttons. If the handle>? function would return a
one4 the event would be considered handled by FLTK and not be send to other widgets to
give these a chance to process the event.
1'. The tree "idget
There is a new widget in FLTK ".$., developed by /reg Crcolano. It is the tree widget
which lets you design file explorer style windows.
The following example allows to select one or more items in the tree by clicking on them.
Then by clicking on the @(opy selected@ button the selected items will be added to the
browser window on the right.
=ou can also select a single group and by using the @!elect group@ button select all the
items which belong to this group. The items will also be selected when the group display is
closed.
8y clicking on the @!how pathname@ button a message window appears specifying the
path of the selected item. Finally the @Deselect all@ button removes all selections.
#include <FL/Fl.H>
#include <FL/Fl_-ou!le_Window.H>
#include <FL/Fl_&ree.H>
#include <FL/Fl_3utton.H>
#include <FL/Fl_3row.er.H>
#include <FL/:l_me..ae.H>
Fl_-ou!le_Window4 win " new Fl_-ou!le_Window(H#<, #+#,%&ree widet e)am*le%),
Fl_&ree4 tree " new Fl_&ree(8<, 8<, 8V<, 8H$),
Fl_3row.er 4!,
/44
E..in u.er icon. to the item.
4/
5oid E..in@.er;con.() {
.tatic con.t char 4L_:older_)*mOP " {
%++ ++ 6 +%,
%. c Done%,
%) c #d7d766%,
%Q c #7$7$++%,
%...........%,
%.....QQQQ..%,
%....Q))))Q.%,
%QQQQQ))))QQ%,
%Q)))))))))Q%,
%Q)))))))))Q%,
%Q)))))))))Q%,
%Q)))))))))Q%,
%Q)))))))))Q%,
%Q)))))))))Q%,
%QQQQQQQQQQQ%2,
.tatic Fl_Mi)ma* L_:older*i)ma*(L_:older_)*m),

.tatic con.t char 4L_document_)*mOP " {
%++ ++ 6 +%,
%. c Done%,
%) c #d7d7:7%,
%Q c #8$8$H$%,
%.QQQQQQQQQ.%,
%.Q)))))))Q.%,
%.Q)))))))Q.%,
%.Q)))))))Q.%,
%.Q)))))))Q.%,
%.Q)))))))Q.%,
%.Q)))))))Q.%,
%.Q)))))))Q.%,
%.Q)))))))Q.%,
%.Q)))))))Q.%,
%.QQQQQQQQQ.%2,
.tatic Fl_Mi)ma* L_document*i)ma*(L_document_)*m),

// E..in u.er icon. to tree item.
:or ( Fl_&ree_;tem 4item " tree->:ir.t(), item, item"item->ne)t())
// E..in cu.tom icon.
item->u.ericon(item->ha._children() [ LL_:older*i)ma* 1 LL_document*i)ma*),
//item->u.ericon($), // -onZt a..in cu.tom icon.

tree->redraw(),
2
5oid tree_c!(Fl_&ree4 w, 5oid4){
Fl_&ree 4tree " (Fl_&ree4)w,
// Find item that wa. clicAed
Fl_&ree_;tem 4item " (Fl_&ree_;tem4)tree->item_clicAed(),
i: ( item->i._.elected() ) { //item i. alread/ .elected
2 el.e { //clicA on additional item
tree->.elect(item), // .elect thi. one too
2
E..in@.er;con.(), //include. tree->redraw(),
2
//Dow the !utton call!acA. :or :our !utton.
5oid !utton_*athname_c!(Fl_Widet4){
char *athnameO8<HP,
Fl_&ree_;tem 4item " tree->:ir.t_.elected_item(),
i: ( Bitem ) { :l_me..ae(%Do item wa. .elected%), 2 el.e {
tree->item_*athname(*athname, .iIeo:(*athname), item),
:l_me..ae(%Mathname :or ZS.Z i.1 Y%S.Y%%, (item->la!el() [ item->la!el() 1 Y
%[[[%), *athname),
2
2
5oid !utton_co*/_c!(Fl_Widet4){
char linete)tO+$$P,
:or ( Fl_&ree_;tem 4item " tree->:ir.t(), item, item " tree->ne)t(item))
{
i: ( item->i._.elected()) {
.*rint:(linete)t,%;tem .elected1 ZS.ZYn%, item->la!el()),
!->add(linete)t),
!->!ottomline(68$$$), //alwa/. di.*la/ the la.t line
2
2
2
5oid !utton_.elect_rou*_c!(Fl_Widet4){
Fl_&ree_;tem 4item " (Fl_&ree_;tem4)tree->:ir.t_.elected_item(),
i: (item->ha._children()) {
tree->.elect_all(item),
tree->de.elect(item,$), //do not .elect the :older it.el:
//8nd *arameter"$ - no call!acA triered
E..in@.er;con.(), //include. tree->redraw(),
2 el.e {
:l_me..ae(%Mlea.e .elect Uu.t a :older :ir.tB%),
return,
2
2
5oid !utton_de.elect_c!(Fl_Widet4){
tree->de.elect_all($,$), //8nd *arameter"$ - no call!acA triered
E..in@.er;con.(), //include. tree->redraw(),
2
int main(int arc, char 44ar5)
{
// Create tree and add item.
tree->add(%Car./Che5rolet%),
tree->add(%Car./>ercede. 3enI%),
tree->add(%Car./Xol5o%),
tree->add(%Car./&o/ota%),
tree->add(%>otorc/cle./Harle/ -a5id.on%),
tree->add(%>otorc/cle./Honda%),
tree->add(%>otorc/cle./9uIuAi%),
tree->clo.e(%/>otorc/cle.%),
tree->.electmode(FL_&0((_9(L(C&_>@L&;), // >ulti*le ;tem.
tree->call!acA((Fl_Call!acA4)tree_c!),
tree->end(),

//Create !utton. and de:ine call!acA.
Fl_3utton 4!utton_*athname " new Fl_3utton(8<,6$$,+8$,6$,%9how *athname%),
!utton_*athname->color(FL_N0((D),
!utton_*athname->call!acA(!utton_*athname_c!),
Fl_3utton 4!utton_.elect_rou* " new Fl_3utton(+7$,6$$,+8$,6$,%9elect rou*%),
!utton_.elect_rou*->color(FL_N0((D),
!utton_.elect_rou*->call!acA(!utton_.elect_rou*_c!),
Fl_3utton 4!utton_co*/ " new Fl_3utton(8<,6<$,+8$,6$,%Co*/ .elected%),
!utton_co*/->color(FL_N0((D),
!utton_co*/->call!acA(!utton_co*/_c!),
Fl_3utton 4!utton_de.elect " new Fl_3utton(+7$,6<$,+8$,6$,%-e.elect all%),
!utton_de.elect->color(FL_N0((D),
!utton_de.elect->call!acA(!utton_de.elect_c!),
//Create !row.er window
! " new Fl_3row.er(6#$,8<,8H$,6<<),
!->t/*e(FL_>@L&;_30=W9(0),
win->end(),
// -i.*la/ the window
win->.how(),
E..in@.er;con.(), //include. tree->redraw(),
// 0un and return
return Fl11run(),
2
The main window ob9ect4 the tree widget ob9ect and the browser ob9ect are defined as
globals here to simplify access to them from the callback functions.
In the main function the tree widget is set up with the tree:cb as its callback. This callback
9ust allows to select several items simultaneously which is possible since the browser type
is set to FL:62LTI:815!C1.
Then four buttons are defined with separate callbacks. The @!how pathname@ button
callback retrieves the first selected item in the tree and then uses the item:pathname>?
method to get its pathname which it then displays in a message window.
The @(opy selected@ button callback walks in a loop through all items in the tree and if one
of them is selected it will copy that to the browser window.
The @!elect group@ button callback looks if the first selected item in the tree is a folder4 i.e.
it has children4 and if yes will select all items belonging to the folder. The folder item itself
will be deselected again in this example.
The @Deselect all@ button callback uses the deselect:all>? method to deselect all items in
the tree.
The .ssign2serIcons function at the beginning of the code is fre7uently called in this
example. This is taken from the @Tree@ example in the FLTK package. It defines two icons
using the H<6 format and these will be added to the connector line depending whether it
is a folder or a file. Then it calls tree:redraw>? to refresh the tree display. These icons 9ust
make the tree look better4 they are not re7uired.
1(. 0eferences
I read the following resources and got most of my knowledge from them.
a? 1obert .rtiletianAs tutorial;
http;BBwww$.telus.netBpublicBrobarkB
b? /reg CrcolanoAs FLTK (heat page;
http;BBseriss.comBpeopleBercoBfltkB
c? Tutorials on the Fational Taiwan 2niversity site;
http;BBgraphics.csie.ntust.edu.twBcoursesBindex.phpB6ainBTutorial
d? The FLTK manual;
http;BBwww.fltk.orgBdoc-".$Bindex.html
'th of 6arch #,"# - /eorg <otthast

You might also like