summaryrefslogtreecommitdiff
path: root/fluid/documentation/src/page_functional_nodes.dox
blob: fa4262e9ee43559b67a129b718e3c47aaa001107 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
/**

 \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.

 */