FLTK Tutorial - FLTK Tweaks
FLTK Tutorial - FLTK Tweaks
FLTK Tutorial - FLTK Tweaks
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, hei ht, 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 ar c, char 44ar 5) { // Create a window - width, hei ht, 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;&(), // 3e in addin children to thi. window win->!e in(), //Create a !utton - ) , / , width, hei ht, 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->!e in(),
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 hei ht, con.t char4 title"$) 1 Fl_Window(width,hei ht,title) { // 9et color o: window to white color(FL_WH;&(), // 3e in addin children to thi. window !e in(), //Create a !utton - ) , / , width, hei ht, 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, hei ht, la!el ("title) >/Window win(6#$,+7$,%FL&' &utorial - ()am*le 8??%), // 0un and return return Fl11run(), 2
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_Wid et4 !utton*tr){ i: (!utton*tr->color() "" FL_3L@() { !utton*tr->color(FL_0(-), //to le 2el.e { !utton*tr->color(FL_3L@(),//to le 2 2 int main(int ar c, char 44ar 5) { // Create a window - width, hei ht, la!el ("title) Fl_Window 4win " new Fl_Window(6#$,+7$,%FL&' &utorial - ()am*le 6%), win->color(FL_WH;&(), // 3e in addin children to thi. window win->!e in(), //Create a !utton - ) , / , width, hei ht, la!el Fl_3utton 4!utton+ " new Fl_3utton(8<,+<,+#$,#$,%ClicA meB%), !utton+->color(FL_0(-), //re i.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_Wid et4 !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.
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 a ain 2 int main(int ar c, char 44ar 5) { Fl_Window win(6$$, C$, %()am*le :or ;n*ut and =ut*ut !o)e.%), win.!e in(), 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_Wid et 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 5oid 5oid 5oid >enu_C3_=*en(Fl_Wid >enu_C3_9a5e(Fl_Wid >enu_C3_Kuit(Fl_Wid >enu_C3_Hel*(Fl_Wid et4 et4 et4 et4 w,5oid4) w,5oid4) w,5oid4) w,5oid4) {win->la!el(%=*en {win->la!el(%9a5e {win->la!el(%Kuit {win->la!el(%Hel* .elected%),2 .elected%),2 .elected%),2 .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.
#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!lic1 Fl_3utton Fl_3utton Fl_Mi)ma* *u!lic Fl_Nrou* { 4.a5e+, 4.a5e8, 4*_.a5e,
Fl_Choice 4:ont_ rou*, Fl_>enu_;tem 4:ont_ rou*_item., .tatic 5oid c!_.a5e(Fl_Wid et4, 5oid4), .tatic 5oid c!_:ont.(Fl_Wid et4, 5oid4), 2, &ool!ar(int T*o., int G*o., int Width, int Hei ht),
5oid &ool!ar11c!_.a5e(Fl_Wid et 4w, 5oid 4data){ :l_alert(%9a5e 3utton Sd *re..edB%,(int)data),2 5oid &ool!ar11c!_:ont.(Fl_Wid et 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 Hei ht) 1 Fl_Nrou*(T*o., G*o., Width, Hei ht) { !o)(FL_@M_3=T), G*o. ?" 8, Hei ht -" #, T*o. ?" 6, Width " Hei ht, int i, .a5e+ " new Fl_3utton(T*o., G*o., Width, Hei ht), T*o. ?" Width ? <, .a5e8 " new Fl_3utton(T*o., G*o., Width, Hei ht), T*o. ?" Width ? <, :ont_ rou* " new Fl_Choice(T*o., G*o., ++$, Hei ht), T*o. ?" +++, *_.a5e " new Fl_Mi)ma*(.a5e_)*m), .a5e+->ima e(*_.a5e), .a5e8->ima e(*_.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.!e in(), 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.
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 dropdown 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.
cla.. -ialo _Window 1 *u!lic Fl_Window { *u!lic1 int .tatu., int radio, .tatic -ialo _Window 4dw_thi., .tatic 5oid c!_!utton(Fl_Wid et 4w, 5oid 4d), .tatic 5oid c!_radio(Fl_Wid et 4!, 5oid 4d), -ialo _Window(int )*o., int /*o., int width, int hei ht, con.t char4 title"$) 1 Fl_Window()*o.,/*o.,width,hei ht,title) { dw_thi. " thi., color(FL_WH;&(), // 3e in addin children to thi. window !e in(), 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_Wid et 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_Wid et 4w, 5oid 4d)
{ 2
5oid c!_:ile(Fl_Wid et 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),
int main() { Fl_Window win(6$$, 8<$,%FL&' -ialo Window ()am*le%), win.color(FL_WH;&(), win.!e in(), 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.
int main() { :l_re i.ter_ima e.(), // initialiIe ima e li! Fl_Window win(<$$,#$$), // maAe a window Fl_3o) !o)(+$,+$,<$$-8$,#$$-8$), // wid et that will contain ima e Fl_MDN_;ma e *n (%Uoll/.*n %), // load *n ima e into ram !o).ima e(*n ), // attach *n ima e 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.
#de:ine WMNF;L( %Uoll/.U* % int main() { :l_re i.ter_ima e.(), Fl_-ou!le_Window win(<8$,#$$,%()am*le ima e 5iewer with .croll!ar.%), Fl_9croll .cr($,$,<8$,#$$), Fl_WM(N_;ma e U* (WMNF;L(), i: ( U* .h() "" $ ) { *error(WMNF;L(), e)it(+), 2 // error checA Fl_3o) !o)($,$,U* .w(),U* .h()), !o).ima e(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.
int main(int ar c, char 4ar 5OP) { 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(),
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.
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 hei ht), int handle(int e), 2, (5entWindow11(5entWindow(int t, int l, int width, int hei ht) 1Fl_3o)(FL_@M_3=T, t, l, width, hei ht, %%) { 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'), dama e(+), return +, ca.e FL_L(EX(1 color(FL_N0EG), la!elcolor(FL_3LEC'), dama e(+), 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 @ n6ouse ver@ 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=D 5F. . 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=D 5F 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 #include #include #include <Fl/Fl.H> <FL/Fl_-ou!le_Window.H> <Fl/Fl_3o).H> <Fl/:l_draw.H> // the main a** window // the o::.creen .ur:ace
#de:ine window_.iIe #$$ .tatic Fl_-ou!le_Window 4main_window " $, .tatic Fl_=::.creen o::.creen_!u::er " $,
/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_!e in_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 // 0i ht !utton .*rint:(la!elte)t,%La.t mou.e !utton" 0i ht F >ou.e at Sd,Sd now%,),/), window()->la!el(la!elte)t), ret5alue " +, !reaA,
.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_!e in_o::.creen(o::.creen_!u::er), i: (!utton""+){ //le:t mou.e !utton :l_color(FL_0(-), :l_line()_old,/_old,),/), 2 el.e { //ri ht 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: dra in /4 =*en the o::.creen conte)t :or drawin 4/ :l_!e in_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 ar c, char 44ar 5) { main_window " new Fl_-ou!le_Window(window_.iIe, window_.iIe, %-rawin with mou.e e)am*le%), main_window->!e in(), // 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(ar c, ar 5), 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 #include #include #include #include <FL/Fl.H> <FL/Fl_Window.H> <FL/Fl_3row.er.H> <FL/Fl_3utton.H> <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_Wid et4 w, 5oid4 5){ win->la!el(%3utton E call!acAB%), 2 5oid !ut_!_c!(Fl_Wid et4 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->!e in(), ! " 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()),
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 #include #include #include #include #include <FL/Fl.H> <FL/Fl_-ou!le_Window.H> <FL/Fl_&ree.H> <FL/Fl_3utton.H> <FL/Fl_3row.er.H> <FL/:l_me..a e.H>
Fl_-ou!le_Window4 win " new Fl_-ou!le_Window(H#<, #+#,%&ree wid et e)am*le%), Fl_&ree4 tree " new Fl_&ree(8<, 8<, 8V<, 8H$), Fl_3row.er 4!, /44 E..i n u.er icon. to the item. 4/ 5oid E..i n@.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..i n u.er icon. to tree item. :or ( Fl_&ree_;tem 4item " tree->:ir.t(), item, item"item->ne)t()) // E..i n cu.tom icon. item->u.ericon(item->ha._children() [ LL_:older*i)ma* 1 LL_document*i)ma*), //item->u.ericon($), // -onZt a..i n 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..i n@.er;con.(), //include. tree->redraw(),
//Dow the !utton call!acA. :or :our !utton. 5oid !utton_*athname_c!(Fl_Wid et4){ char *athnameO8<HP, Fl_&ree_;tem 4item " tree->:ir.t_.elected_item(), i: ( Bitem ) { :l_me..a e(%Do item wa. .elected%), 2 el.e { tree->item_*athname(*athname, .iIeo:(*athname), item), :l_me..a e(%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_Wid et4){ 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_Wid et4){ 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 tri ered E..i n@.er;con.(), //include. tree->redraw(), 2 el.e { :l_me..a e(%Mlea.e .elect Uu.t a :older :ir.tB%), return, 2 2 5oid !utton_de.elect_c!(Fl_Wid et4){ tree->de.elect_all($,$), //8nd *arameter"$ - no call!acA tri E..i n@.er;con.(), //include. tree->redraw(), 2 int main(int ar c, char 44ar 5) { // 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!), ered
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 !utton_.elect_ rou*->color(FL_N0((D), !utton_.elect_ rou*->call!acA(!utton_.elect_ rou*_c!), rou*%),
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..i n@.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:81 5!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