1/** 2 <!-- Warning: \p .fl does not work but <tt>.fl</tt> does --> 3 <!-- Warning: \p .h does not work but <tt>.h</tt> does --> 4 <!-- Warning: \p .cxx does not work but <tt>.cxx</tt> does --> 5 6 \page fluid Programming with FLUID 7 8This chapter shows how to use the Fast Light User-Interface Designer 9("FLUID") to create your GUIs. 10 11Subchapters: 12 13\li \ref fluid_what_is_fluid 14\li \ref fluid_fluid_under_unix 15\li \ref fluid_fluid_under_windows 16\li \ref fluid_compiling_fl_files 17\li \ref fluid_tutorial 18\li \ref fluid_references 19\li \ref fluid_i18n 20\li \ref fluid_limitations 21 22\section fluid_what_is_fluid What is FLUID? 23 24The Fast Light User Interface Designer, or FLUID, is a 25graphical editor that is used to produce FLTK source code. FLUID 26edits and saves its state in <tt>.fl</tt> files. These files 27are text, and you can (with care) edit them in a text editor, 28perhaps to get some special effects. 29 30FLUID can "compile" the <tt>.fl</tt> file into a 31<tt>.cxx</tt> and a <tt>.h</tt> file. The <tt>.cxx</tt> file 32defines all the objects from the <tt>.fl</tt> file and the 33<tt>.h</tt> file declares all the global ones. FLUID also 34supports localization (\ref fluid_i18n "Internationalization") 35of label strings using message files and the GNU gettext or 36POSIX catgets interfaces. 37 38A simple program can be made by putting all your code (including a 39\p main() function) into the <tt>.fl</tt> file and thus making the 40<tt>.cxx</tt> file a 41single source file to compile. Most programs are more complex than 42this, so you write other <tt>.cxx</tt> files that call the FLUID functions. 43These <tt>.cxx</tt> files must 44\p \#include 45the <tt>.h</tt> file or they can 46\p \#include 47the <tt>.cxx</tt> file so it still appears to be a single source file. 48 49 \image html fluid-org.png "Figure 9-1: FLUID organization" 50 \image latex fluid-org.png "FLUID organization" width=12cm 51 52Normally the FLUID file defines one or more functions or classes which 53output C++ code. Each function defines a one or more FLTK 54windows, and all the widgets that go inside those windows. 55 56Widgets created by FLUID are either "named", "complex named" or 57"unnamed". A named widget has a legal C++ variable identifier as its 58name (i.e. only alphanumeric and underscore). In this case FLUID 59defines a global variable or class member that will point at the widget 60after the function defining it is called. A complex named object has 61punctuation such as <tt>'.'</tt> or <tt>'->'</tt> or any other symbols 62in its name. In 63this case FLUID assigns a pointer to the widget to the name, but does 64not attempt to declare it. This can be used to get the widgets into 65structures. An unnamed widget has a blank name and no pointer is stored. 66 67Widgets may either call a named callback function that you write in 68another source file, or you can supply a small piece of C++ source and 69FLUID will write a private callback function into the <tt>.cxx</tt> file. 70 71\section fluid_fluid_under_unix Running FLUID Under UNIX 72 73To run FLUID under UNIX, type: 74 75\code 76fluid filename.fl & 77\endcode 78 79to edit the <tt>.fl</tt> file <tt>filename.fl</tt>. 80If the file does not exist 81you will get an error pop-up, but if you dismiss it you will be editing 82a blank file of that name. You can run FLUID without any name, in 83which case you will be editing an unnamed blank setup (but you can use 84save-as to write it to a file). 85 86You can provide any of the standard FLTK switches before the filename: 87 88\code 89-display host:n.n 90-geometry WxH+X+Y 91-title windowtitle 92-name classname 93-iconic 94-fg color 95-bg color 96-bg2 color 97-scheme schemename 98\endcode 99 100Changing the colors may be useful to see what your interface 101will look at if the user calls it with the same switches. 102Similarly, using "-scheme plastic" will show how the interface 103will look using the "plastic" scheme. 104 105In the current version, if you don't put FLUID into the 106background with <tt>'&'</tt> then you will be able to abort FLUID by 107typing <tt>CTRL-C</tt> on the terminal. It will exit 108immediately, losing any changes. 109 110\section fluid_fluid_under_windows Running FLUID Under Microsoft Windows 111 112To run FLUID under WIN32, double-click on the \e FLUID.exe 113file. You can also run FLUID from the Command Prompt window. 114FLUID always runs in the background under WIN32. 115 116\section fluid_compiling_fl_files Compiling .fl files 117 118FLUID can also be called as a command-line 119"compiler" to create the <tt>.cxx</tt> and <tt>.h</tt> 120file from a <tt>.fl</tt> file. To do this type: 121 122\code 123fluid -c filename.fl 124\endcode 125 126This will read the <tt>filename.fl</tt> file and write 127<tt>filename.cxx</tt> and <tt>filename.h</tt>. Any leading 128directory on <tt>filename.fl</tt> will be stripped, so they are 129always written to the current directory. If there are any errors 130reading or writing the files, FLUID will print the error and 131exit with a non-zero code. You can use the following lines in a 132makefile to automate the creation of the source and header 133files: 134 135\code 136my_panels.h my_panels.cxx: my_panels.fl 137 fluid -c my_panels.fl 138\endcode 139 140Most versions of make support rules that cause <tt>.fl</tt> 141files to be compiled: 142 143\code 144.SUFFIXES: .fl .cxx .h 145.fl.h .fl.cxx: 146 fluid -c $< 147\endcode 148 149\section fluid_tutorial A Short Tutorial 150 151FLUID is an amazingly powerful little program. However, this 152power comes at a price as it is not always obvious how to 153accomplish seemingly simple tasks with it. This tutorial will 154show you how to generate a complete user interface class with 155FLUID that is used for the CubeView program provided with FLTK. 156 157\image html cubeview.png "Figure 9-2: CubeView demo" 158\image latex cubeview.png "CubeView demo" width=10cm 159 160The window is of class CubeViewUI, and is completely generated by FLUID, 161including 162class member functions. The central display of the cube is a separate 163subclass of Fl_Gl_Window called CubeView. CubeViewUI manages CubeView 164using callbacks from the various sliders and rollers to manipulate the 165viewing angle and zoom of CubeView. 166 167At the completion of this tutorial you will (hopefully) understand 168how to: 169 170-# Use FLUID to create a complete user interface class, including 171 constructor and any member functions necessary. 172-# Use FLUID to set callbacks member functions of a custom widget 173 classes. 174-# Subclass an Fl_Gl_Window to suit your purposes. 175 176\subsection fluid_cubeview The CubeView Class 177 178The CubeView class is a subclass of Fl_Gl_Window. It has methods for 179setting the zoom, the \e x and \e y pan, and the rotation angle 180about the \e x and \e y axes. 181 182You can safely skip this section as long as you realize the CubeView 183is a sublass of Fl_Gl_Window and will respond to calls from 184CubeViewUI, generated by FLUID. 185 186\par The CubeView Class Definition 187 188Here is the CubeView class definition, as given by its header file 189"test/CubeView.h": 190 191\code 192class CubeView : public Fl_Gl_Window { 193 public: 194 CubeView(int x,int y,int w,int h,const char *l=0); 195 // this value determines the scaling factor used to draw the cube. 196 double size; 197 /* Set the rotation about the vertical (y ) axis. 198 * 199 * This function is called by the horizontal roller in CubeViewUI 200 * and the initialize button in CubeViewUI. 201 */ 202 void v_angle(float angle){vAng=angle;}; 203 // Return the rotation about the vertical (y ) axis. 204 float v_angle(){return vAng;}; 205 /* Set the rotation about the horizontal (x ) axis. 206 * 207 * This function is called by the vertical roller in CubeViewUI 208 and the 209 * initialize button in CubeViewUI. 210 */ 211 void h_angle(float angle){hAng=angle;}; 212 // the rotation about the horizontal (x ) axis. 213 float h_angle(){return hAng;}; 214 /* Sets the x shift of the cube view camera. 215 * 216 * This function is called by the slider in CubeViewUI and the 217 * initialize button in CubeViewUI. 218 */ 219 void panx(float x){xshift=x;}; 220 /* Sets the y shift of the cube view camera. 221 * 222 * This function is called by the slider in CubeViewUI and the 223 * initialize button in CubeViewUI. 224 */ 225 void pany(float y){yshift=y;}; 226 /* The widget class draw() override. 227 * The draw() function initialize Gl for another round of 228 * drawing then calls specialized functions for drawing each 229 * of the entities displayed in the cube view. 230 */ 231 void draw(); 232 233 private: 234 /* Draw the cube boundaries 235 * Draw the faces of the cube using the boxv[] vertices, using 236 * GL_LINE_LOOP for the faces. The color is #defined by 237 * CUBECOLOR. 238 */ 239 void drawCube(); 240 241 float vAng,hAng; float xshift,yshift; 242 243 float boxv0[3];float boxv1[3]; float boxv2[3];float boxv3[3]; 244 float boxv4[3];float boxv5[3]; float boxv6[3];float boxv7[3]; 245}; 246\endcode 247 248\par The CubeView Class Implementation 249 250Here is the CubeView implementation. It is very similar to the 251"cube" demo included with FLTK. 252 253\code 254#include "CubeView.h" 255#include <math.h> 256 257CubeView::CubeView(int x,int y,int w,int h,const char *l) 258 : Fl_Gl_Window(x,y,w,h,l) 259{ 260 vAng = 0.0; hAng=0.0; size=10.0; 261 /* The cube definition. These are the vertices of a unit cube 262 * centered on the origin.*/ 263 boxv0[0] = -0.5; boxv0[1] = -0.5; boxv0[2] = -0.5; boxv1[0] = 0.5; 264 boxv1[1] = -0.5; boxv1[2] = -0.5; boxv2[0] = 0.5; boxv2[1] = 0.5; 265 boxv2[2] = -0.5; boxv3[0] = -0.5; boxv3[1] = 0.5; boxv3[2] = -0.5; 266 boxv4[0] = -0.5; boxv4[1] = -0.5; boxv4[2] = 0.5; boxv5[0] = 0.5; 267 boxv5[1] = -0.5; boxv5[2] = 0.5; boxv6[0] = 0.5; boxv6[1] = 0.5; 268 boxv6[2] = 0.5; boxv7[0] = -0.5; boxv7[1] = 0.5; boxv7[2] = 0.5; 269}; 270 271// The color used for the edges of the bounding cube. 272#define CUBECOLOR 255,255,255,255 273 274void CubeView::drawCube() { 275/* Draw a colored cube */ 276#define ALPHA 0.5 277 glShadeModel(GL_FLAT); 278 279 glBegin(GL_QUADS); 280 glColor4f(0.0, 0.0, 1.0, ALPHA); 281 glVertex3fv(boxv0); 282 glVertex3fv(boxv1); 283 glVertex3fv(boxv2); 284 glVertex3fv(boxv3); 285 286 glColor4f(1.0, 1.0, 0.0, ALPHA); 287 glVertex3fv(boxv0); 288 glVertex3fv(boxv4); 289 glVertex3fv(boxv5); 290 glVertex3fv(boxv1); 291 292 glColor4f(0.0, 1.0, 1.0, ALPHA); 293 glVertex3fv(boxv2); 294 glVertex3fv(boxv6); 295 glVertex3fv(boxv7); 296 glVertex3fv(boxv3); 297 298 glColor4f(1.0, 0.0, 0.0, ALPHA); 299 glVertex3fv(boxv4); 300 glVertex3fv(boxv5); 301 glVertex3fv(boxv6); 302 glVertex3fv(boxv7); 303 304 glColor4f(1.0, 0.0, 1.0, ALPHA); 305 glVertex3fv(boxv0); 306 glVertex3fv(boxv3); 307 glVertex3fv(boxv7); 308 glVertex3fv(boxv4); 309 310 glColor4f(0.0, 1.0, 0.0, ALPHA); 311 glVertex3fv(boxv1); 312 glVertex3fv(boxv5); 313 glVertex3fv(boxv6); 314 glVertex3fv(boxv2); 315 glEnd(); 316 317 glColor3f(1.0, 1.0, 1.0); 318 glBegin(GL_LINES); 319 glVertex3fv(boxv0); 320 glVertex3fv(boxv1); 321 322 glVertex3fv(boxv1); 323 glVertex3fv(boxv2); 324 325 glVertex3fv(boxv2); 326 glVertex3fv(boxv3); 327 328 glVertex3fv(boxv3); 329 glVertex3fv(boxv0); 330 331 glVertex3fv(boxv4); 332 glVertex3fv(boxv5); 333 334 glVertex3fv(boxv5); 335 glVertex3fv(boxv6); 336 337 glVertex3fv(boxv6); 338 glVertex3fv(boxv7); 339 340 glVertex3fv(boxv7); 341 glVertex3fv(boxv4); 342 343 glVertex3fv(boxv0); 344 glVertex3fv(boxv4); 345 346 glVertex3fv(boxv1); 347 glVertex3fv(boxv5); 348 349 glVertex3fv(boxv2); 350 glVertex3fv(boxv6); 351 352 glVertex3fv(boxv3); 353 glVertex3fv(boxv7); 354 glEnd(); 355};//drawCube 356 357void CubeView::draw() { 358 if (!valid()) { 359 glLoadIdentity(); glViewport(0,0,w(),h()); 360 glOrtho(-10,10,-10,10,-20000,10000); glEnable(GL_BLEND); 361 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 362 } 363 364 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 365 glPushMatrix(); glTranslatef(xshift, yshift, 0); 366 glRotatef(hAng,0,1,0); glRotatef(vAng,1,0,0); 367 glScalef(float(size),float(size),float(size)); drawCube(); 368 glPopMatrix(); 369}; 370\endcode 371 372\subsection fluid_cubevieui The CubeViewUI Class 373 374We will completely construct a window to display and control the 375CubeView defined in the previous section using FLUID. 376 377\par Defining the CubeViewUI Class 378 379Once you have started FLUID, the first step in defining a class is to 380create a new class within FLUID using the <b>New->Code->Class</b> 381menu item. Name the class "CubeViewUI" and leave the 382subclass blank. We do not need any inheritance for this 383window. You should see the new class declaration in the FLUID 384browser window. 385 386\image html fluid1.png "Figure 9-3: FLUID file for CubeView" 387\image latex fluid1.png "FLUID file for CubeView" width=10cm 388 389\par Adding the Class Constructor 390 391Click on the CubeViewUI class in the FLUID window and add a new method 392by selecting <b>New->Code->Function/Method.</b> The name of the 393function will also be CubeViewUI. FLUID will understands that this will 394be the constructor for the class and will generate the appropriate 395code. Make sure you declare the constructor public. 396 397Then add a window to the CubeViewUI class. Highlight the name of 398the constructor in the FLUID browser window and click on 399<b>New->Group->Window</b>. In a similar manner add the 400following to the CubeViewUI constructor: 401 402\li A horizontal roller named \p hrot 403\li A vertical roller named \p vrot 404\li A horizontal slider named \p xpan 405\li A vertical slider named \p ypan 406\li A horizontal value slider named \p zoom 407 408None of these additions need be public. And they shouldn't be 409unless you plan to expose them as part of the interface for 410CubeViewUI. 411 412When you are finished you should have something like this: 413 414\image html fluid2.png "Figure 9-4: FLUID window containing CubeView demo" 415\image latex fluid2.png "FLUID window containing CubeView demo" width=10cm 416 417We will talk about the \p show() method that is highlighted 418shortly. 419 420\par Adding the CubeView Widget 421 422What we have is nice, but does little to show our cube. We have already 423defined the CubeView class and we would like to show it within the 424CubeViewUI. 425 426The CubeView class inherits the Fl_Gl_Window class, which 427is created in the same way as a Fl_Box widget. Use 428<b>New->Other->Box</b> to add a square box to the main window. 429This will be no ordinary box, however. 430 431The Box properties window will appear. The key to letting CubeViewUI 432display CubeView is to enter CubeView in the <b>Class:</b> text 433entry box. This tells FLUID that it is not an Fl_Box, but a 434similar widget with the same constructor. 435 436In the <b>Extra Code:</b> field enter <tt>\#include "CubeView.h"</tt> 437 438This \p \#include is important, as we have just included 439CubeView as a member of CubeViewUI, so any public CubeView methods are 440now available to CubeViewUI. 441 442\image html fluid3-cxx.png "Figure 9-5: CubeView methods" 443\image latex fluid3-cxx.png "CubeView methods" width=10cm 444 445\par Defining the Callbacks 446 447Each of the widgets we defined before adding CubeView can have 448callbacks that call CubeView methods. You can call an external 449function or put in a short amount of code in the <b>Callback</b> 450field of the widget panel. For example, the callback for the 451\p ypan slider is: 452 453\code 454cube->pany(((Fl_Slider *)o)->value()); 455cube->redraw(); 456\endcode 457 458We call <tt>cube->redraw()</tt> after changing the value to update 459the CubeView window. CubeView could easily be modified to do this, but 460it is nice to keep this exposed in the case where you may want to do 461more than one view change only redrawing once saves a lot of time. 462 463There is no reason no wait until after you have added CubeView to 464enter these callbacks. FLUID assumes you are smart enough not to refer 465to members or functions that don't exist. 466 467\par Adding a Class Method 468 469You can add class methods within FLUID that have nothing to do with the 470GUI. An an example add a show function so that CubeViewUI can actually 471appear on the screen. 472 473Make sure the top level CubeViewUI is selected and select 474<b>New->Code->Function/Method</b>. Just use the name 475\p show(). We don't need a return value here, and since we will 476not be adding any widgets to this method FLUID will assign it a return 477type of \p void. 478 479\image html fluid4.png "Figure 9-6: CubeView constructor" 480\image latex fluid4.png "CubeView constructor" width=10cm 481 482Once the new method has been added, highlight its name and select 483<b>New->Code->Code.</b> Enter the method's code in the code window. 484 485\subsection fluid_addconst Adding Constructor Initialization Code 486 487If you need to add code to initialize class, for example setting 488initial values of the horizontal and vertical angles in the 489CubeView, you can simply highlight the Constructor and select 490<b>New->Code->Code</b>. Add any required code. 491 492\subsection fluid_gencode Generating the Code 493 494Now that we have completely defined the CubeViewUI, we have to generate 495the code. There is one last trick to ensure this all works. Open the 496preferences dialog from <b>Edit->Preferences</b>. 497 498At the bottom of the preferences dialog box is the key: 499<b>"Include Header from Code"</b>. 500Select that option and set your desired file 501extensions and you are in business. You can include the CubeViewUI.h 502(or whatever extension you prefer) as you would any other C++ class. 503 504<!-- NEW PAGE --> 505 506\section fluid_references FLUID Reference 507 508The following sections describe each of the windows in FLUID. 509 510\subsection fluid_browser The Widget Browser 511 512The main window shows a menu bar and a scrolling browser of 513all the defined widgets. The name of the <tt>.fl</tt> file being 514edited is shown in the window title. 515 516The widgets are stored in a hierarchy. You can open and close a 517level by clicking the "triangle" at the left of a widget. 518The leftmost widgets are the \e parents, and all the widgets 519listed below them are their \e children. Parents don't have to have 520any children. 521 522The top level of the hierarchy is composed of \e functions and 523\e classes. Each of these will produce a single C++ public 524function or class in the output <tt>.cxx</tt> file. Calling the function or 525instantiating the class will create all of the child widgets. 526 527The second level of the hierarchy contains the \e windows. 528Each of these produces an instance of class Fl_Window. 529 530Below that are either \e widgets (subclasses of Fl_Widget) or 531\e groups of widgets (including other groups). Plain groups are for 532layout, navigation, and resize purposes. <i>Tab groups</i> provide the 533well-known file-card tab interface. 534 535Widgets are shown in the browser by either their \e name (such 536as "main_panel" in the example), or by their \e type 537and \e label (such as "Button "the green""). 538 539You \e select widgets by clicking on their names, which highlights 540them (you can also select widgets from any displayed window). You can 541select many widgets by dragging the mouse across them, or by using 542Shift+Click to toggle them on and off. To select no widgets, click in 543the blank area under the last widget. Note that hidden children may 544be selected even when there is no visual indication of this. 545 546You \e open widgets by double-clicking on them, or (to open several 547widgets you have picked) by typing the F1 key. A control panel will appear 548so you can change the widget(s). 549 550\subsection fluid_menu_items Menu Items 551 552The menu bar at the top is duplicated as a pop-up menu on any 553displayed window. The shortcuts for all the menu items work in any 554window. The menu items are: 555 556\par File/Open... (Ctrl+o) 557 558\par 559Discards the current editing session and reads in a different 560<tt>.fl</tt> file. You are asked for confirmation if you have 561changed the current file. 562 563\par 564FLUID can also read <tt>.fd</tt> files produced by the Forms 565and XForms "fdesign" programs. It is best to 566File/Merge them instead of opening them. FLUID does not 567understand everything in a <tt>.fd</tt> file, and will print a 568warning message on the controlling terminal for all data it does 569not understand. You will probably need to edit the resulting 570setup to fix these errors. Be careful not to save the file 571without changing the name, as FLUID will write over the 572<tt>.fd</tt> file with its own format, which fdesign cannot 573read! 574 575\par File/Insert... (Ctrl+i) 576 577\par 578Inserts the contents of another <tt>.fl</tt> file, without 579changing the name of the current <tt>.fl</tt> file. All the 580functions (even if they have the same names as the current ones) 581are added, and you will have to use cut/paste to put the widgets 582where you want. 583 584\par File/Save (Ctrl+s) 585 586\par 587Writes the current data to the <tt>.fl</tt> file. If the 588file is unnamed then FLUID will ask for a filename. 589 590\par File/Save As... (Ctrl+Shift+S) 591 592\par 593Asks for a new filename and saves the file. 594 595\par File/Write Code (Ctrl+Shift+C) 596 597\par 598"Compiles" the data into a <tt>.cxx</tt> and <tt>.h</tt> 599file. These are exactly the same as the files you get when you run 600FLUID with the \c -c switch. 601 602\par 603The output file names are the same as the <tt>.fl</tt> file, with 604the leading directory and trailing ".fl" stripped, and 605".h" or ".cxx" appended. 606 607\par File/Write Strings (Ctrl+Shift+W) 608 609\par 610Writes a message file for all of the text labels defined in 611the current file. 612 613\par 614The output file name is the same as the <tt>.fl</tt> file, 615with the leading directory and trailing ".fl" 616stripped, and ".txt", ".po", or ".msg" appended depending on the 617\ref fluid_i18n "Internationalization Mode". 618 619\par File/Quit (Ctrl+q) 620 621\par 622Exits FLUID. You are asked for confirmation if you have 623changed the current file. 624 625\par Edit/Undo (Ctrl+z) 626 627\par 628This isn't implemented yet. You should do save often so you can 629recover from any mistakes you make. 630 631\par Edit/Cut (Ctrl+x) 632 633\par 634Deletes the selected widgets and all of their children. 635These are saved to a "clipboard" file and can be 636pasted back into any FLUID window. 637 638\par Edit/Copy (Ctrl+c) 639 640\par 641Copies the selected widgets and all of their children to the 642"clipboard" file. 643 644\par Edit/Paste (Ctrl+c) 645 646\par 647Pastes the widgets from the clipboard file. 648 649\par 650If the widget is a window, it is added to whatever function 651is selected, or contained in the current selection. 652 653\par 654If the widget is a normal widget, it is added to whatever 655window or group is selected. If none is, it is added to the 656window or group that is the parent of the current selection. 657 658\par 659To avoid confusion, it is best to select exactly one widget 660before doing a paste. 661 662\par 663Cut/paste is the only way to change the parent of a 664widget. 665 666\par Edit/Select All (Ctrl+a) 667 668\par 669Selects all widgets in the same group as the current selection. 670 671\par 672If they are all selected already then this selects all 673widgets in that group's parent. Repeatedly typing Ctrl+a will 674select larger and larger groups of widgets until everything is 675selected. 676 677\par Edit/Open... (F1 or double click) 678 679\par 680Displays the current widget in the attributes panel. If the 681widget is a window and it is not visible then the window is 682shown instead. 683 684\par Edit/Sort 685 686\par 687Sorts the selected widgets into left to right, top to bottom 688order. You need to do this to make navigation keys in FLTK work 689correctly. You may then fine-tune the sorting with 690"Earlier" and "Later". This does not affect 691the positions of windows or functions. 692 693\par Edit/Earlier (F2) 694 695\par 696Moves all of the selected widgets one earlier in order among 697the children of their parent (if possible). This will affect 698navigation order, and if the widgets overlap it will affect how 699they draw, as the later widget is drawn on top of the earlier 700one. You can also use this to reorder functions, classes, and 701windows within functions. 702 703\par Edit/Later (F3) 704 705\par 706Moves all of the selected widgets one later in order among 707the children of their parent (if possible). 708 709\par Edit/Group (F7) 710 711\par 712Creates a new Fl_Group and make all the currently 713selected widgets children of it. 714 715\par Edit/Ungroup (F8) 716 717\par 718Deletes the parent group if all the children of a group are 719selected. 720 721\par Edit/Overlays on/off (Ctrl+Shift+O) 722 723\par 724Toggles the display of the red overlays off, without changing 725the selection. This makes it easier to see box borders and how 726the layout looks. The overlays will be forced back on if you 727change the selection. 728 729\par Edit/Project Settings... (Ctrl+p) 730 731\par 732Displays the project settings panel. 733The output filenames control the extensions or names of the 734files the are generated by FLUID. If you check the "Include .h 735from .cxx" button the code file will include the header file 736automatically. 737 738\par 739The \ref fluid_i18n "internationalization" options are described 740later in this chapter. 741 742\image html fluid_prefs.png "Figure 9-7: FLUID Preferences Window" 743\image latex fluid_prefs.png "FLUID Preferences Window" width=10cm 744 745\par Edit/GUI Settings... (Shift+Ctrl+p) 746 747\par 748Displays the GUI settings panel. This panel is used 749to control the user interface settings. 750 751\par New/Code/Function 752 753\par 754Creates a new C function. You will be asked for a name for 755the function. This name should be a legal C++ function 756template, without the return type. You can pass arguments which 757can be referred to by code you type into the individual widgets. 758 759\par 760If the function contains any unnamed windows, it will be 761declared as returning a Fl_Window pointer. The unnamed window 762will be returned from it (more than one unnamed window is 763useless). If the function contains only named windows, it will 764be declared as returning nothing (\c void ). 765 766\par 767It is possible to make the <tt>.cxx</tt> output be a 768self-contained program that can be compiled and executed. This 769is done by deleting the function name so 770\p main(argc,argv) is used. The function will call 771\p show() on all the windows it creates and then call 772\p Fl::run(). This can also be used to test resize 773behavior or other parts of the user interface. 774 775\par 776You can change the function name by double-clicking on the 777function. 778 779\par New/Window 780 781\par 782Creates a new Fl_Window widget. The window is added 783to the currently selected function, or to the function 784containing the currently selected item. The window will appear, 785sized to 100x100. You can resize it to whatever size you 786require. 787 788\par 789The widget panel will also appear and is described later in 790this chapter. 791 792\par New/... 793 794\par 795All other items on the New menu are subclasses of 796Fl_Widget. Creating them will add them to the 797currently selected group or window, or the group or window 798containing the currently selected widget. The initial 799dimensions and position are chosen by copying the current 800widget, if possible. 801 802\par 803When you create the widget you will get the widget's control 804panel, which is described later in this chapter. 805 806\par Layout/Align/... 807 808\par 809Align all selected widgets to the first widget in the selection. 810 811\par Layout/Space Evenly/... 812 813\par 814Space all selected widgets evenly inside the selected space. 815Widgets will be sorted from first to last. 816 817\par Layout/Make Same Size/... 818 819\par 820Make all selected widgets the same size as the first selected widget. 821 822\par Layout/Center in Group/... 823 824\par 825Center all selected widgets relative to their parent widget 826 827\par Layout/Grid... (Ctrl+g) 828 829\par 830Displays the grid settings panel. 831This panel 832controls the grid that all widgets snap to when you move and 833resize them, and for the "snap" which is how far a widget has to 834be dragged from its original position to actually change. 835 836\par Shell/Execute Command... (Alt+x) 837 838\par 839Displays the shell command panel. The shell command 840is commonly used to run a 'make' script to compile the FLTK output. 841 842\par Shell/Execute Again (Alt+g) 843 844\par 845Run the shell command again. 846 847\par Help/About FLUID 848 849\par 850Pops up a panel showing the version of FLUID. 851 852\par Help/On FLUID 853 854\par 855Shows this chapter of the manual. 856 857\par Help/Manual 858 859\par 860Shows the contents page of the manual 861 862\subsection fluid_widget_panel The Widget Panel 863 864When you double-click on a widget or a set of widgets you 865will get the "widget attribute panel". 866 867When you change attributes using this panel, the changes are 868reflected immediately in the window. It is useful to hit the 869"no overlay" button (or type Ctrl+Shift+O) to hide the 870red overlay so you can see the widgets more accurately, 871especially when setting the box type. 872 873If you have several widgets selected, they may have different 874values for the fields. In this case the value for \e one of 875the widgets is shown. But if you change this value, \e all 876of the selected widgets are changed to the new value. 877 878Hitting "OK" makes the changes permanent. 879Selecting a different widget also makes the changes permanent. 880FLUID checks for simple syntax errors such as mismatched 881parenthesis in any code before saving any text. 882 883"Revert" or "Cancel" put everything back 884to when you last brought up the panel or hit OK. However in the 885current version of FLUID, changes to "visible" 886attributes (such as the color, label, box) are not undone by 887revert or cancel. Changes to code like the callbacks are 888undone, however. 889 890<!-- NEW PAGE --> 891 892\image html fluid_widget_gui.png "Figure 9-8: The FLUID widget GUI attributes" 893\image latex fluid_widget_gui.png "The FLUID widget GUI attributes" width=10cm 894 895\section fluid_widget_attributes GUI Attributes 896 897\par Label (text field) 898 899\par 900String to print next to or inside the button. You can put 901newlines into the string to make multiple lines. The easiest way 902is by typing Ctrl+j. 903 904\par 905\ref common_labels "Symbols" 906can be added to the label using the at sign ("@"). 907 908\par Label (pull down menu) 909 910\par 911How to draw the label. Normal, shadowed, engraved, and 912embossed change the appearance of the text. 913 914\par Image 915 916\par 917The active image for the widget. Click on the 918\b Browse... button to pick an image file using the file 919chooser. 920 921\par Inactive 922 923\par 924The inactive image for the widget. Click on the 925\b Browse... button to pick an image file using the file 926chooser. 927 928\par Alignment (buttons) 929 930\par 931Where to draw the label. The arrows put it on that side of 932the widget, you can combine the to put it in the corner. The 933"box" button puts the label inside the widget, rather 934than outside. 935 936\par 937The \b clip button clips the label to the widget box, the 938\b wrap button wraps any text in the label, and the 939<b>text image</b> button puts the text over the image instead of under 940the image. 941 942\par Position (text fields) 943 944\par 945The position fields show the current position and size of the 946widget box. Enter new values to move and/or resize a widget. 947 948\par Values (text fields) 949 950\par 951The values and limits of the current widget. Depending on the 952type of widget, some or all of these fields may be inactive. 953 954\par Shortcut 955 956\par 957The shortcut key to activate the widget. Click on the 958shortcut button and press any key sequence to set the shortcut. 959 960\par Attributes (buttons) 961 962\par 963The \b Visible button controls whether the widget is 964visible (on) or hidden (off) initially. Don't change this for 965windows or for the immediate children of a Tabs group. 966 967\par 968The \b Active button controls whether the widget is 969activated (on) or deactivated (off) initially. Most widgets 970appear greyed out when deactivated. 971 972\par 973The \b Resizable button controls whether the window is 974resizeable. In addition all the size changes of a window or 975group will go "into" the resizable child. If you have 976a large data display surrounded by buttons, you probably want 977that data area to be resizable. You can get more complex 978behavior by making invisible boxes the resizable widget, or by 979using hierarchies of groups. Unfortunately the only way to test 980it is to compile the program. Resizing the FLUID window is 981\e not the same as what will happen in the user program. 982 983\par 984The \b Hotspot button causes the parent window to be 985positioned with that widget centered on the mouse. This 986position is determined <i>when the FLUID function is called</i>, 987so you should call it immediately before showing the window. If 988you want the window to hide and then reappear at a new position, 989you should have your program set the hotspot itself just before 990\p show(). 991 992\par 993The \b Border button turns the window manager border on 994or off. On most window managers you will have to close the 995window and reopen it to see the effect. 996 997\par X Class (text field) 998 999\par 1000The string typed into here is passed to the X window manager 1001as the class. This can change the icon or window decorations. 1002On most (all?) window managers you will have to close the window 1003and reopen it to see the effect. 1004 1005\image html fluid_widget_style.png "Figure 9-9: The FLUID widget Style attributes" 1006\image latex fluid_widget_style.png "The FLUID widget Style attributes" width=10cm 1007 1008\subsection fluid_style_attributes Style Attributes 1009 1010\par Label Font (pulldown menu) 1011 1012\par 1013Font to draw the label in. Ignored by symbols, bitmaps, and 1014pixmaps. Your program can change the actual font used by these 1015"slots" in case you want some font other than the 16 1016provided. 1017 1018\par Label Size (pulldown menu) 1019 1020\par 1021Pixel size (height) for the font to draw the label in. 1022Ignored by symbols, bitmaps, and pixmaps. To see the result 1023without dismissing the panel, type the new number and then Tab. 1024 1025\par Label Color (button) 1026 1027\par 1028Color to draw the label. Ignored by pixmaps (bitmaps, 1029however, do use this color as the foreground color). 1030 1031\par Box (pulldown menu) 1032 1033\par 1034The boxtype to draw as a background for the widget. 1035 1036\par 1037Many widgets will work, and draw faster, with a 1038"frame" instead of a "box". A frame does 1039not draw the colored interior, leaving whatever was already 1040there visible. Be careful, as FLUID may draw this ok but the 1041real program may leave unwanted stuff inside the widget. 1042 1043\par 1044If a window is filled with child widgets, you can speed up 1045redrawing by changing the window's box type to 1046"NO_BOX". FLUID will display a checkerboard for any 1047areas that are not colored in by boxes. Note that this 1048checkerboard is not drawn by the resulting program. Instead 1049random garbage will be displayed. 1050 1051\par Down Box (pulldown menu) 1052 1053\par 1054The boxtype to draw when a button is pressed or for some 1055parts of other widgets like scrollbars and valuators. 1056 1057\par Color (button) 1058 1059\par 1060The color to draw the box with. 1061 1062\par Select Color (button) 1063 1064\par 1065Some widgets will use this color for certain parts. FLUID 1066does not always show the result of this: this is the color 1067buttons draw in when pushed down, and the color of input fields 1068when they have the focus. 1069 1070\par Text Font, Size, and Color 1071 1072\par 1073Some widgets display text, such as input fields, pull-down 1074menus, and browsers. 1075 1076\image html fluid_widget_cxx.png "Figure 9-10: The FLUID widget C++ attributes" 1077\image latex fluid_widget_cxx.png "The FLUID widget C++ attributes" width=10cm 1078 1079\subsection fluid_cpp_attributes C++ Attributes 1080 1081\par Class 1082 1083\par 1084This is how you use your own subclasses of 1085Fl_Widget. Whatever identifier you type in here will 1086be the class that is instantiated. 1087 1088\par 1089In addition, no \p \#include header file is put in the 1090<tt>.h</tt> file. You must provide a \p \#include line as 1091the first line of the "Extra Code" which declares your 1092subclass. 1093 1094\par 1095The class must be similar to the class you are spoofing. It 1096does not have to be a subclass. It is sometimes useful to 1097change this to another FLTK class. Currently the only way to get 1098a double-buffered window is to change this field for the window 1099to "Fl_Double_Window" and to add 1100\code #include <FL/Fl_Double_Window.h> \endcode 1101to the extra code. 1102 1103\par Type (upper-right pulldown menu) 1104 1105\par 1106Some classes have subtypes that modify their appearance or behavior. 1107You pick the subtype off of this menu. 1108 1109\par Name (text field) 1110 1111\par 1112Name of a variable to declare, and to store a pointer to this 1113widget into. This variable will be of type "<class>*". If the name is 1114blank then no variable is created. 1115 1116\par 1117You can name several widgets with "name[0]", "name[1]", "name[2]", 1118etc. This will cause FLUID to declare an array of pointers. The array 1119is big enough that the highest number found can be stored. All widgets 1120that in the array must be the same type. 1121 1122\par Public (button) 1123 1124\par 1125Controls whether the widget is publicly accessible. When 1126embedding widgets in a C++ class, this controls whether the 1127widget is \p public or \p private in the class. 1128Otherwise is controls whether the widget is declared 1129\p static or global (\p extern ). 1130 1131\par Extra Code (text fields) 1132 1133\par 1134These four fields let you type in literal lines of code to 1135dump into the <tt>.h</tt> or <tt>.cxx</tt> files. 1136 1137\par 1138If the text starts with a <tt>\#</tt> or the word 1139\p extern then FLUID thinks this is an "include" 1140line, and it is written to the <tt>.h</tt> file. If the same 1141include line occurs several times then only one copy is 1142written. 1143 1144\par 1145All other lines are "code" lines. The current 1146widget is pointed to by the local variable \p o. The 1147window being constructed is pointed to by the local variable 1148\p w. You can also access any arguments passed to the 1149function here, and any named widgets that are before this 1150one. 1151 1152\par 1153FLUID will check for matching parenthesis, braces, and 1154quotes, but does not do much other error checking. Be careful 1155here, as it may be hard to figure out what widget is producing 1156an error in the compiler. If you need more than four lines you 1157probably should call a function in your own <tt>.cxx</tt> 1158code. 1159 1160\par Callback (text field) 1161 1162\par 1163This can either be the name of a function, or a small snippet 1164of code. If you enter anything other than letters, numbers, and the 1165underscore then FLUID treats it as code. 1166 1167\par 1168A name refers to a function in your own code. It must be 1169declared as <tt>void name(<class>*,void*)</tt>. 1170 1171\par 1172A code snippet is inserted into a static function in the 1173<tt>.cxx</tt> output file. The function prototype is 1174<tt>void name(class *o, void *v)</tt> 1175so that you can refer to the widget as \p o and the \p user_data() 1176as \p v. FLUID will check for matching parenthesis, braces, 1177and quotes, but does not do much other error checking. Be 1178careful here, as it may be hard to figure out what widget is 1179producing an error in the compiler. 1180 1181\par 1182If the callback is blank then no callback is set. 1183 1184\par User Data (text field) 1185 1186\par 1187This is a value for the \p user_data() of the widget. 1188If blank the default value of zero is used. This can be any 1189piece of C code that can be cast to a \p void pointer. 1190 1191\par Type (text field) 1192 1193\par 1194The \p void* in the callback function prototypes is 1195replaced with this. You may want to use \p long for old 1196XForms code. Be warned that anything other than \p void* 1197is not guaranteed to work! However on most architectures other 1198pointer types are ok, and \p long is usually ok, too. 1199 1200\par When (pulldown menu) 1201 1202\par 1203When to do the callback. This can be \b Never, 1204\b Changed, \b Release, or \b Enter Key. The value of 1205<b>Enter Key</b> is only useful for text input fields. 1206 1207\par 1208There are other rare but useful values for the 1209\p when() field that are not in the menu. You should use 1210the extra code fields to put these values in. 1211 1212\par No Change (button) 1213 1214\par 1215The <b>No Change</b> button means the callback is done on the 1216matching event even if the data is not changed. 1217 1218\section fluid_selecting_moving Selecting and Moving Widgets 1219 1220Double-clicking a window name in the browser will display it, 1221if not displayed yet. From this display you can select widgets, 1222sets of widgets, and move or resize them. To close a window 1223either double-click it or type \c ESC. 1224 1225To select a widget, click it. To select several widgets drag 1226a rectangle around them. Holding down shift will toggle the 1227selection of the widgets instead. 1228 1229You cannot pick hidden widgets. You also cannot choose some 1230widgets if they are completely overlapped by later widgets. Use 1231the browser to select these widgets. 1232 1233The selected widgets are shown with a red "overlay" 1234line around them. You can move the widgets by dragging this 1235box. Or you can resize them by dragging the outer edges and 1236corners. Hold down the Alt key while dragging the mouse to 1237defeat the snap-to-grid effect for fine positioning. 1238 1239If there is a tab box displayed you can change which child is 1240visible by clicking on the file tabs. The child you pick is 1241selected. 1242 1243The arrow, tab, and shift+tab keys "navigate" the 1244selection. Left, right, tab, or shift+tab move to the next or 1245previous widgets in the hierarchy. Hit the right arrow enough 1246and you will select every widget in the window. Up/down widgets 1247move to the previous/next widgets that overlap horizontally. If 1248the navigation does not seem to work you probably need to 1249"Sort" the widgets. This is important if you have 1250input fields, as FLTK uses the same rules when using arrow keys 1251to move between input fields. 1252 1253To "open" a widget, double click it. To open 1254several widgets select them and then type F1 or pick 1255"Edit/Open" off the pop-up menu. 1256 1257Type Ctrl+o to temporarily toggle the overlay off without 1258changing the selection, so you can see the widget borders. 1259 1260You can resize the window by using the window manager border 1261controls. FLTK will attempt to round the window size to the 1262nearest multiple of the grid size and makes it big enough to 1263contain all the widgets (it does this using illegal X methods, 1264so it is possible it will barf with some window managers!). 1265Notice that the actual window in your program may not be 1266resizable, and if it is, the effect on child widgets may be 1267different. 1268 1269The panel for the window (which you get by double-clicking 1270it) is almost identical to the panel for any other Fl_Widget. 1271There are three extra items: 1272 1273\section fluid_images Image Labels 1274 1275The \e contents of the image files in the \b Image 1276and \b Inactive text fields are written to the <tt>.cxx</tt> 1277file. If many widgets share the same image then only one copy is 1278written. Since the image data is embedded in the generated 1279source code, you need only distribute the C++ code and not the 1280image files themselves. 1281 1282However, the \e filenames are stored in the <tt>.fl</tt> 1283file so you will need the image files as well to read the 1284<tt>.fl</tt> file. Filenames are relative to the location of the 1285<tt>.fl</tt> file and not necessarily the current directory. We 1286recommend you either put the images in the same directory as the 1287<tt>.fl</tt> file, or use absolute path names. 1288 1289\par Notes for All Image Types 1290 1291\par 1292FLUID runs using the default visual of your X server. This 1293may be 8 bits, which will give you dithered images. You may get 1294better results in your actual program by adding the code 1295"Fl::visual(FL_RGB)" to your code right before the 1296first window is displayed. 1297 1298\par 1299All widgets with the same image on them share the same code 1300and source X pixmap. Thus once you have put an image on a 1301widget, it is nearly free to put the same image on many other 1302widgets. 1303 1304\par 1305If you edit an image at the same time you are using it in FLUID, 1306the only way to convince FLUID to read the image file again is to 1307remove the image from all widgets that are using it or re-load the 1308<tt>.fl</tt> file. 1309 1310\par 1311Don't rely on how FLTK crops images that are outside the 1312widget, as this may change in future versions! The cropping of 1313inside labels will probably be unchanged. 1314 1315\par 1316To more accurately place images, make a new "box" 1317widget and put the image in that as the label. 1318 1319\par XBM (X Bitmap) Files 1320 1321\par 1322FLUID reads X bitmap files which use C source code to define 1323a bitmap. Sometimes they are stored with the ".h" or 1324".bm" extension rather than the standard 1325".xbm" extension. 1326 1327\par 1328FLUID writes code to construct an Fl_Bitmap image and use it 1329to label the widget. The '1' bits in the bitmap are drawn using 1330the label color of the widget. You can change this color in the 1331FLUID widget attributes panel. The '0' bits are transparent. 1332 1333\par 1334The program "bitmap" on the X distribution does an 1335adequate job of editing bitmaps. 1336 1337\par XPM (X Pixmap) Files 1338 1339\par 1340FLUID reads X pixmap files as used by the \p libxpm 1341library. These files use C source code to define a pixmap. The 1342filenames usually have the ".xpm" extension. 1343 1344\par 1345FLUID writes code to construct an Fl_Pixmap image and use it 1346to label the widget. The label color of the widget is ignored, 1347even for 2-color images that could be a bitmap. XPM files can 1348mark a single color as being transparent, and FLTK uses this 1349information to generate a transparency mask for the image. 1350 1351\par 1352We have not found any good editors for small iconic pictures. 1353For pixmaps we have used 1354<A href="http://home.worldonline.dk/~torsten/xpaint/index.html">XPaint</A> 1355and the KDE icon editor. 1356 1357\par BMP Files 1358 1359\par 1360FLUID reads Windows BMP image files which are often used in 1361WIN32 applications for icons. FLUID converts BMP files into 1362(modified) XPM format and uses a Fl_BMP_Image image to label the 1363widget. Transparency is handled the same as for XPM files. All 1364image data is uncompressed when written to the source file, so 1365the code may be much bigger than the <tt>.bmp</tt> file. 1366 1367\par GIF Files 1368 1369\par 1370FLUID reads GIF image files which are often used in HTML 1371documents to make icons. FLUID converts GIF files into 1372(modified) XPM format and uses a Fl_GIF_Image image to label the 1373widget. Transparency is handled the same as for XPM files. All 1374image data is uncompressed when written to the source file, so 1375the code may be much bigger than the <tt>.gif</tt> file. Only 1376the first image of an animated GIF file is used. 1377 1378\par JPEG Files 1379 1380\par 1381If FLTK is compiled with JPEG support, FLUID can read JPEG 1382image files which are often used for digital photos. FLUID uses 1383a Fl_JPEG_Image image to label the widget, and writes 1384uncompressed RGB or grayscale data to the source file. 1385 1386\par PNG (Portable Network Graphics) Files 1387 1388\par 1389If FLTK is compiled with PNG support, FLUID can read PNG 1390image files which are often used in HTML documents. FLUID uses a 1391Fl_PNG_Image image to label the widget, and writes uncompressed 1392RGB or grayscale data to the source file. PNG images can provide 1393a full alpha channel for partial transparency, and FLTK supports 1394this as best as possible on each platform. 1395 1396\section fluid_i18n Internationalization with FLUID 1397 1398FLUID supports internationalization (I18N for short) of label 1399strings used by widgets. The preferences window 1400(<tt>Ctrl+p</tt>) provides access to the I18N options. 1401 1402\subsection fluid_i18n_methods I18N Methods 1403 1404FLUID supports three methods of I18N: use none, use GNU 1405gettext, and use POSIX catgets. The "use none" method is the 1406default and just passes the label strings as-is to the widget 1407constructors. 1408 1409The "GNU gettext" method uses GNU gettext (or a similar 1410text-based I18N library) to retrieve a localized string before 1411calling the widget constructor. 1412 1413The "POSIX catgets" method uses the POSIX catgets function to 1414retrieve a numbered message from a message catalog before 1415calling the widget constructor. 1416 1417\subsection fluid_gettext_i18n Using GNU gettext for I18N 1418 1419FLUID's code support for GNU gettext is limited to calling a 1420function or macro to retrieve the localized label; you still 1421need to call \p setlocale() and \p textdomain() or 1422\p bindtextdomain() to select the appropriate language and 1423message file. 1424 1425To use GNU gettext for I18N, open the preferences window and 1426choose "GNU gettext" from the \b Use: chooser. Two new input 1427fields will then appear to control the include file and 1428function/macro name to use when retrieving the localized label 1429strings. 1430 1431 \image html fluid-gettext.png "Figure 9-11: Internationalization using GNU gettext" 1432 \image latex fluid-gettext.png "Internationalization using GNU gettext" width=10cm 1433 1434The \b \#include 1435field controls the header file to include for 1436I18N; by default this is \b <libintl.h>, the 1437standard I18N file for GNU gettext. 1438 1439The \b Function: field controls the function (or macro) that 1440will retrieve the localized message; by default the 1441\p gettext function will be called. 1442 1443\subsection fluid_catgets_i18n Using POSIX catgets for I18N 1444 1445FLUID's code support for POSIX catgets allows you to use a 1446global message file for all interfaces or a file specific to 1447each <tt>.fl</tt> file; you still need to call 1448\p setlocale() to select the appropriate language. 1449 1450To use POSIX catgets for I18N, open the preferences window 1451and choose "POSIX catgets" from the \b Use: chooser. Three new 1452input fields will then appear to control the include file, 1453catalog file, and set number for retrieving the localized label 1454strings. 1455 1456 \image html fluid-catgets.png "Figure 9-12: Internationalization using POSIX catgets" 1457 \image latex fluid-catgets.png "Internationalization using POSIX catgets" width=10cm 1458 1459The \b \#include 1460field controls the header file to include for 1461I18N; by default this is \b <nl_types.h>, the 1462standard I18N file for POSIX catgets. 1463 1464The \b File: field controls the name of the catalog file 1465variable to use when retrieving localized messages; by default 1466the file field is empty which forces a local (static) catalog 1467file to be used for all of the windows defined in your 1468<tt>.fl</tt> file. 1469 1470The \b Set: field controls the set number in the catalog file. 1471The default set is 1 and rarely needs to be changed. 1472 1473\section fluid_limitations Known limitations 1474 1475Declaration Blocks can be used to temporarily block out already 1476designed code using <tt>\#if 0</tt> and <tt>\#endif</tt> 1477type construction. This will effectively avoid compilation of 1478blocks of code. However, static code and data generated by this 1479segment (menu items, images, include statements, etc.) will still 1480be generated and likely cause compile-time warnings. 1481 1482 1483\htmlonly 1484<hr> 1485<table summary="navigation bar" width="100%" border="0"> 1486<tr> 1487 <td width="45%" align="LEFT"> 1488 <a class="el" href="opengl.html"> 1489 [Prev] 1490 Using OpenGL 1491 </a> 1492 </td> 1493 <td width="10%" align="CENTER"> 1494 <a class="el" href="index.html">[Index]</a> 1495 </td> 1496 <td width="45%" align="RIGHT"> 1497 <a class="el" href="advanced.html"> 1498 Advanced FLTK 1499 [Next] 1500 </a> 1501 </td> 1502</tr> 1503</table> 1504\endhtmlonly 1505 1506*/ 1507