/** \page page_functional_nodes Functional Node Panels \tableofcontents \section functional_function Function and Method Panel ![](flFunction.png) Functions and Methods Fluid can generate C functions, C++ functions, and methods in classes. Functions can contain widgets to build windows and dialogs. *Code* nodes can be used to add more source code to a function. ### Parents ### To generate a function, the function node must be created at the top level or inside a declaration block. If added inside a class node, this node generates a method inside that class. ### Children ### Function nodes can contain code nodes and windows that in turn contain widgets. If the function node has no children, only a forward declaration will be created in the header, but no source code will be generated. \image html function_panel.png "Function/Method Properties" \image latex function_panel.png "Function/Method Properties" width=7cm ### Declaring a Function ### A function node at the top level or inside a declaration block generates a C or C++ function. The *Name* field contains the function name and all arguments. If the *Name* field is left empty, Fluid will generate a typical 'main()' function. ``` // .cxx int main(int argc, char **argv) { // code generated by children w->show(argc, argv); // <-- code generated if function has a child widget Fl::run(); } ``` If a function node has a name but no children, a forward declaration is generated in the header, but the implementation in the source file is omitted. This is used to reference functions in other modules. ``` // .h void make_window(); ``` If the function contains one or more Code nodes, the implementation code will be generated. The default return type is `void`. Text in the *Return Type* field overrides the default type. ``` // .cxx void make_window() { // code generated by children } ``` If the function contains one or more windows, a pointer to the first window will be returned. The default return type will match the window class. ``` // .h Fl_Window* make_window(); ``` ``` // .cxx Fl_Window* make_window() { Fl_Window* w; // code generated by children: // w = new Fl_Window(...) return w; } ``` #### Options for Functions #### Choosing *static* in the pulldown menu will generate the function `static` in the source file. No forward declaration will be generated in the header file. ``` // .cxx static Fl_Window* make_window() { ... } ``` Choosing *global* will generate a forward declaration of the function in the header file and no `static` attribute in the source file. ``` // .h void make_window(); // .cxx Fl_Window* make_window() { ... } ``` Additionally, if the *C* option is checked, the function will be declared as a plain C function in the header file. ``` // .h extern "C" { void my_plain_c_function(); } // .cxx void my_plain_c_function() { ... } ``` The *local* option will generate a function in the source file with no `static` attribute. No forward declaration will be generated in the header file. ``` // .cxx Fl_Window* make_window() { ... } ``` ### Declaring a Method ### A function node inside a class node generates a C++ method. If a method node has no children, the declaration is generated in the header, but no implementation in the source file. ``` // .h class UserInterface { public: void make_window(); }; ``` If the method contains one or more Code nodes, an implementation will also be generated. ``` // .cxx void UserInterface::make_window() { printf("Hello, World!\n"); } ``` If the method contains at least one widget, a pointer to the topmost widget will be returned and the return type will be generated accordingly. ``` // .h class UserInterface { public: Fl_Double_Window* make_window(); }; ``` ``` // .cxx Fl_Double_Window* UserInterface::make_window() { Fl_Double_Window* w; // code generated by children return w; } ``` #### Options for Methods #### Class access can be defined with the pulldown menu. It provides a choice of `private`, `protected`, and `public`. Fluid recognizes the keyword `static` or `virtual` at the beginning of the *return type* and will generate the declaration including the keyword, but will omit it in the implementation. The return type defaults still apply if there is no text after the keyword. #### Further Options #### Users can define a comment text in the *comment* field. The first line of the comment will be shown in the widget browser. The comment text will be generated in the source file before the function. ``` // .cxx // // My multilen comment will be here... . // Fluid may actually use C style comment markers. // Fl_Window* make_window() { ``` FLUID recognizes default values in the argument list and generates them in the declaration, but omits them in the implementation. A short function body can be appended in the *Name* field. With no child, this creates an inlined function in the header file. \section functional_code C Source Code ![](flCode.png) Code Code nodes hold arbitrary C++ code that is copied verbatim into the source code file. They are commonly used inside Function nodes. ### Parents ### Code nodes can be added inside Functions, Code Blocks, and Widget Classes. \image html code_panel.png "Code Properties" \image latex code_panel.png "Code Properties" width=9cm The Code Properties panel features a syntax-highlighting C++ code editor. Some basic bracket and braces match checking is done when closing the dialog. When inside a Function or Code Block, the C++ code is inserted directly. Inside a Widget Class, the code will be added to the constructor of the widget class. \section functional_codeblock Code Block ![](flCodeBlock.png) Code Block Code Blocks are used when a single function generates different GUI elements conditionally. ### Parents ### Code Blocks are used inside functions and methods. ### Children ### Code Blocks can contain widgets, code, or more code blocks. \image html codeblock_panel.png "Code Block Properties" \image latex codeblock_panel.png "Code Block Properties" width=7cm The two fields expect the code before and after the `{ ... }` statements. The second field can be empty. Two consecutive Code Blocks can be used to generate `else`/`else if` statements by leaving the second field of the first node empty. \section functional_decl Declaration ![](flDeclaration.png) Declaration ### Parents ### Declarations can be added at the top level or inside classes and widget classes. \image html decl_panel.png "Declaration Properties" \image latex decl_panel.png "Declaration Properties" width=7cm Declaration nodes are quite flexible and can be a simple variable declaration such as `int i;`. But include statements are also allowed, as are type declarations, and comments. FLUID does its best to understand user intention, but the generated code should be verified by the user. Declarations nodes at the top level can selectively generate code in the header and /or in the source file. If a declaration is inside a class, the user can select if the class member is *private*, *protected*, or *public* instead. \section functional_declblock Declaration Block ![](flDeclarationBlock.png) Declaration Block Declaration Blocks are a way to selectively compile child nodes via preprocessor commands, typically `#ifdef TEST` and `#endif`. ### Parents ### Declaration Blocks can be created at the top level or inside classes. ### Children ### Declaration Blocks can contain classes, functions, methods, declarations, and comments. \image html declblock_panel.png "Declaration Block Properties" \image latex declblock_panel.png "Declaration Block Properties" width=7cm The C++ code in the "Start" field is output before the code of all children of this node is written to the source file. The text in the "End" field is written after code for all children was generated. The following check boxes enable code generation for different locations in header and source code files. The first two boxes modify the C++ source code file. If the first check box, "implementations", is ticked, all C++ code that implements the children of this declaration block will be enclosed with the code from the "Start" and "End" fields. This check box is marked by default. The second check box, "static initializations and callbacks", will enclose callbacks that may be created by child widgets, menu item arrays, and code as well as data for images. This box should be ticked in most cases, but may be harmful if one image is used more than once and outside of this declaration block. The next two boxes modify the C++ code in the header file. Ticking "forward declarations" will wrap the code that declares functions, methods, and menus. The last box ensure that code declaring widgets is wrapped with yet another copy of from the "Start" and "End" fields. This will also wrap `#include` statements and declarations from widget "Code" fields. FLUID optimizes header files by removing duplicate include statements and certain declarations. Declaration blocks are commonly used for conditional compilation and may effectively "optimize away" include statements that are still needed elsewhere. This can be litigated by explicitly creating Declaration nodes outside of the declaration block. The "Start" and "End" code may appear multiple times per file if more than one of the check boxes above is ticked. The code should not have any side effects or cause conflicts when compiled more than once. It's not safe to rely on a specific order of the generated blocks. \section functional_class Classes ![](flClass.png) Class FLUID can generate code to implement C++ classes. Classes can be used to keep dialogs and groups of UI elements organized. See Widget Class nodes as an alternative to implement compound widgets. ### Parents ### Class nodes can be created at top level or inside a Class or Widget Class node. ### Children ### Class nodes can contain Functions, Declarations, Widgets, Data, and other classes. \image html class_panel.png "Class Properties" \image latex class_panel.png "Class Properties" width=7cm The *Name:* and *Subclass of:* fields should be set to standard C++ class names. Function nodes inside classes are implemented as methods. Constructors and destructors are recognized and implemented as such. Inlined data is declared as a static class member. Note that methods without a code or widget node are only declared in the header file, but no code is generated for them in the source file. \section functional_widgetclass Widget Class ![](flWidgetClass.png) Widget Class The Widget Class node creates a new widget type by deriving a class from another widget class. These are often compound widgets derived from `Fl_Group`. A less automated but more flexible way to implement compound widgets is the Class node. ### Parents ### Widget Class nodes can be created at top level or inside a Class or Widget Class node. ### Children ### Widget Class nodes can contain Functions, Declarations, Widgets, Data, and other classes. ### Properties ### Widget Class nodes use the Widget panel to edit their properties. The super class can be set in the *C++* tab in the *Class* field. If that field is empty, FLUID derives from `Fl_Group`. The Widget Class always creates a constructor with the common widget parameters: ``` MyWidget::MyWidget(int X, int Y, int W, int H, const char *L) : Fl_Group(X, Y, W, H, L) { ... } ``` If the super class name contains the text `Window`, two more constructors and a common initializer method are created: ``` MyWidget::MyWidget(int W, int H, const char *L) : Fl_Window(0, 0, W, H, L) { ... } MyWidget::MyWidget() : Fl_Window(0, 0, 480, 320, 0) { ... } void MyWidget::_MyWidget() { ... } ``` Code and Widget nodes are then added to the constructor. Function nodes are added as methods to the class. Declarations are added as class members. Data nodes generate static class members. It may be useful to design compound widgets with a variable size. The Widget Panel provides a choice menu in the *GUI* tab's *Position* row under *Children*. The options *resize* and *reposition* generate code to fix up the coordinates of the widget after instantiation. Note that methods without a code or widget node are only declared in the header file, but no code is generated for them in the source file. \section functional_comment Comments ![](flComment.png) Comment This node adds a comment block to the generated source code. ### Parents ### Comment nodes can be added inside Functions, Code Blocks, and Widget Classes. If a Comment node is the top node in a tree, it will appear in the source files even before the `// generated by FLUID ...` line. \image html comment_panel.png "Comment Properties" \image latex comment_panel.png "Comment Properties" width=9cm Comment blocks are generated by adding `// ` to the start of each line unless the first line of a comment starts with `/``*`. In that case, FLUID assumes a correct block comment and will copy the text verbatim. Comments can be generated in the header file, the source file, or both. FLUID keeps a small database of predefined comments. Users can add reoccurring comment blocks, license information for example, to this database via the pulldown menu. Comments can also be imported from an external file. \section functional_data Inlined Data ![](flData.png) Inlined Data The Data node makes it easy to inline data from an external file into the source code. ### Parents ### Data nodes can be added at the top level or inside Widget Classes, Classes, and Declaration Blocks. \image html data_panel.png "Data Properties" \image latex data_panel.png "Data Properties" width=7cm At top level, or inside a Declaration Block, Data can be declared *in source file only*, *static in source file*, or *in source and extern in header*. If Data is inside a Class node, it is always declared `static`. The user can select *private*, *protected*, or *public*. Data in binary mode will be stored in an `unsigned char` array. The data size can be queried with `sizeof()`. In Text mode, it will be stored as `const char*` and terminated with a `NUL` character. In compressed mode, data will be compressed with zlib `compress()` and stored in an `unsigned char` array. A second variable, holding the original data size, is declared `int` by appending `_size` to the variable name. ``` // .cxx int myInlineData_size = 12034; unsigned char myInlineData[380] = { 65, 128, ... }; ``` The Variable Name should be a regular C++ name. The Filename field expects the path and name of a file, relative to the location of the .fl file. */