mirror of https://github.com/fltk/fltk.git
FLTK - Fast Light Tool Kit - https://github.com/fltk/fltk - cross platform GUI development
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
545 lines
19 KiB
545 lines
19 KiB
|
|
FLUID .fl file format version 1.4 |
|
================================= |
|
|
|
This text explains the history of the FLUID .fl format and faithfully describes |
|
all elements of the format and its caveats. |
|
|
|
|
|
History |
|
------- |
|
|
|
FLUID, the Fast Light User Interface Designer was started in the 1990's loosely |
|
based on 'fdesign', a GUI designer that came with the 'Forms Library', later |
|
'XForms Library'. FLUID's .fl file format was originally compatible with the |
|
fdesign '.fd' format, but evolved somewhat ad hoc to become what it is today. |
|
|
|
|
|
Basics |
|
====== |
|
|
|
FLUID is a visual editor, storing the user interface description in .fl files |
|
with the ability to create ready-to-compile C++ code. FLUID can also be used |
|
as a command line tool to translate .fl files directly into source code. It |
|
can be integrated into build scripts and most IDEs as an external tool. |
|
|
|
.fl files describe a hierarchical graphical user interface for the 'FLTK' |
|
library as a tree structure. Elements in the tree can be FLTK Widgets as well |
|
as functional components like classes, C++ functions, variables, etc. . |
|
FLUID calls all elements in the hierarchy 'Type'. |
|
|
|
|
|
Line Endings |
|
------------ |
|
|
|
Although FLUID writes all line endings as '\n', readers should tolerate '\r\n' |
|
MSWindows line endings as well. Except for the Header, the FLUID reader does not |
|
differentiate between a line ending and a space character outside of a 'word'. |
|
|
|
|
|
Unicode |
|
------- |
|
|
|
FLUID does not handle UTF-8 characters in any special manner (unescaped), |
|
but stores and reads them verbatim, making UTF-8 character sequences perfectly |
|
legal in .fl files. FLUID can translate UTF-8 into escape sequence when writing |
|
source code files. |
|
|
|
|
|
File Structure |
|
-------------- |
|
|
|
.fl files start with a 'Header', followed by a list of 'Options', followed |
|
by a hierarchy of 'Type' entries, the 'Tree'. All elements besides the Header |
|
are composed of 'Words', 'Strings', and 'Groups'. |
|
|
|
|
|
Words |
|
----- |
|
|
|
Words can be any sequence of ASCII and UTF-8 characters. Words are always |
|
case-sensitive. |
|
|
|
Simple Words that are composed of 'a'-'z', 'A'-'Z', '0'-'9', and '_' only are |
|
written verbatim, followed by a space or newline. |
|
|
|
All other character sequences are bracketed between between ‘{‘ and ‘}’ without |
|
padding spaces. For example, an empty word with no characters is written |
|
as '{}', and ".hello" is written as '{.hello}'. |
|
|
|
The special characters ‘\’ and ‘#’ are escaped by prepending the ‘\’ character, |
|
so "#define" is written as '{\#define}`. |
|
|
|
The characters ‘{‘ and ‘}’ are also escaped with a '\' unless every opening |
|
‘{‘ in the Word is matched with a closing ‘}’. |
|
|
|
Note: line endings and the following indents are copied verbatim and become |
|
significant within a Word. |
|
|
|
|
|
Strings |
|
------- |
|
|
|
Strings are generated with 'printf' statements in the hope that the |
|
generated text can be read back as one Word, set against a corresponding |
|
'scanf' to retrieve the original values. |
|
|
|
Note: As there are no defined start and end markers to a String, a reader must |
|
know when these Strings appear and be prepared to read them correctly, |
|
even if the String itself is not useful to the reader. |
|
|
|
Note: All Strings that are generated by the current FLUID source code |
|
can be read back as a single Word. |
|
|
|
|
|
Groups |
|
------ |
|
|
|
To create a hierarchy, Types can be grouped within Types. A Group starts with |
|
a lone '{' and ends with a lone '}'. |
|
|
|
Note: To know whether a '{' character starts a Word or a Group, the reader must |
|
know its position within the Type sequence (see 'Types' below). |
|
|
|
|
|
Elements |
|
======== |
|
|
|
|
|
Header |
|
------ |
|
|
|
The Header for any .fl file is |
|
|
|
# data file for the Fltk User Interface Designer (fluid) |
|
|
|
followed by a newline, followed by |
|
|
|
version <float v> |
|
|
|
wehere 'v' is the version number as in FL_VERSION (major*1.0 + minor * 0.01 |
|
+ patch * 0.0001). So for FLTK 1.3.4, 'v' would be 1.0304 |
|
|
|
Note: the version number corresponds not so much to the version of FLUID, but |
|
to the version of the underlying FLTK library. So unless the version of |
|
FLTK is finalised, the file format in the GitHub master branch can still |
|
change unexpectedly. |
|
|
|
Note: if the version number is above the internal version number, FLUID will |
|
report an error and continue reading, hoping for the best. |
|
There are no other uses inside the FLUID reader except for features for |
|
the discontinued fltk2 which is beyond the scope of this document. |
|
|
|
Note: fdesign files (.fd) start with the text "Magic:". FLUID can read these |
|
files, but Forms/XForms files are beyond the scope of this document. |
|
|
|
|
|
Options |
|
------- |
|
|
|
Options are usually comprised of a Word, two Words, or a Word and a String. If |
|
an Option is missing, a default value is assumed. |
|
|
|
"Magic:" : used by fdesign, not written by FLUID |
|
|
|
"define_in_struct" : no longer used |
|
|
|
"do_not_include_H_from_C" : don’t generate #include “myDesign.h” |
|
|
|
"use_FL_COMMAND" : use macOS CMD key instead of Ctrl |
|
|
|
"utf8_in_src" : allow UTF-8 when writing source code, otherwise |
|
escape UTF-8 sequences in source code |
|
|
|
"avoid_early_includes" : generate the '#include <FL/Fl.H>' statement late |
|
|
|
"i18n_type" <word> : integer 0=default=none, 1=gettext, 2=catgets |
|
|
|
--- the following list is valid until June 2023 |
|
|
|
"i18n_function" <word> : function name, e.g. “gettext” |
|
|
|
"i18n_static_function" <word> : function name, e.g. “gettext_noop” |
|
|
|
"i18n_file" <word> : file name |
|
|
|
"i18n_set" <word> : string |
|
|
|
--- the following list is valid from June 2023 |
|
|
|
"i18n_gnu_function" <word> : function name, e.g. “gettext” |
|
|
|
"i18n_gnu_static_function" <word> : function name, e.g. “gettext_noop” |
|
|
|
"i18n_pos_file" <word> : file name |
|
|
|
"i18n_pos_set" <word> : string |
|
|
|
--- end of June 2023 changes |
|
|
|
"i18n_include" <word> : file name, e.g. “<libintl.h>” |
|
|
|
"i18n_conditional" <word> : string |
|
|
|
"header_name" <word> : can be the full filename, or just the |
|
extension e.g. “.h” in which case FLUID will use the same filename |
|
as the .fl file. |
|
|
|
"code_name" <word> : can be the full filename, or just the |
|
extension e.g. “.cxx” |
|
|
|
"snap" <word> : starting in V1.4 from May 2023, the 'snap' keyword can be |
|
used to store the selected layout and preset and include more suites |
|
of presets. The following block can be skipped by reading it as a |
|
single word. The format looks like this: |
|
|
|
snap { optional snap Word since 5.2023 |
|
ver 1 version of following data |
|
current_suite {My Test} opt. name of suite selected at save time |
|
current_preset 1 opt. preset selected within suite |
|
suite { optional suite store within project |
|
name {MyLayout v0.3} name of the layout |
|
preset { 1 3x preset, preset version |
|
(24 integers) values representing the layout preset |
|
} |
|
... (two more presets) |
|
} |
|
... (opt. more suites) |
|
} |
|
|
|
"gridx" <word> : ignored |
|
|
|
"gridy" <word> : ignored |
|
|
|
"shell_commands" <word> : starting in V1.4 from Sep 2023, the 'shell_commands' |
|
keyword can be used to store user configurable shell commands in a |
|
project file. The following block can be skipped by reading it as a |
|
single word. |
|
|
|
shell_commands { |
|
command { |
|
name <string> |
|
label <string> |
|
shortcut <int> (optional if not 0) |
|
condition <int> (optional if not 0, see Fd_Shell_Command enum) |
|
condition_data <string> (optional if not "") |
|
command <string> (optional, but usually there) |
|
flags <int> (optional if not 0, see Fd_Shell_Command 2nd enum) |
|
} ( repeat as needed) |
|
} |
|
|
|
Note: There is no keyword that marks the end of the Options section. The |
|
Option list ends when a Word is not in the Options list and it is in |
|
the list of known Types. |
|
|
|
If the Word is neither an Option nor a vaild Type, FLUID will give an |
|
error message and try to continue to read the file. Using new Option |
|
keywords makes .fl files incompatible to earlier versions of FLUID. |
|
Due to the forgiving interpreter, files may still be read correctly |
|
despite error messages. |
|
|
|
If a Word is in the list of known Types, the Type is read, including |
|
optional children. No more Options are allowed beyond this point. |
|
|
|
|
|
Tree |
|
==== |
|
|
|
If a keyword is read that is not in the Option list, we start reading Types. |
|
Types represent all possible entries in the hierarchy including C functions, |
|
class definitions, and of course all Widgets. A Type is any of the supported |
|
Widgets classes, or one of the following (case sensitive): |
|
|
|
Function, code, codeblock, decl, data, declblock, comment, class, widget_class |
|
|
|
Every Type keyword is followed by a Word, which is usually interpreted as the |
|
C++ name of the Type, followed by an opening `{`, a list of properties, and |
|
a closing ‘}’. If the Type has children, they are stored in a Group between |
|
another opening ‘{‘, followed by a list of Types, followed by a closing ‘}’. |
|
|
|
Fl_Group MyGroup { Type name start_of_options |
|
label Surprise ... Option parameter |
|
} { end_of_options start_of_children |
|
Fl_Button {} { Type name start_of_options |
|
label {Don't panic...!} Option parameter |
|
hide Option |
|
} end_of_options |
|
} end_of_children |
|
|
|
The file ends when there are no more Types. |
|
|
|
Note: the "class" Type may have an additional Word following immediately after |
|
the keyword. It contains the prefix for the class. A class definition may |
|
be written as: |
|
|
|
class FL_EXPORT MyClass { ...properties... } { ...children... } |
|
|
|
or without a prefix as |
|
|
|
class MyOtherClass { ...properties... } { ...children... } |
|
|
|
According to the source code, we know if the word after class is a prefix |
|
if the next word is not a lone '{'. We apologize for the inconvenience. |
|
|
|
|
|
Types |
|
----- |
|
|
|
Type names are based on FLTK class names. Types derive properties from super |
|
Types loosely similar to FLTK. |
|
|
|
Note: the hierarchical dependency is implemented twice and somewhat conflicting |
|
in FLUID via the Fl_..._Type hierarchy, and by using '::is_some_type()' |
|
virtual functions, which does not always match the Type hierarchy. |
|
|
|
|
|
The list of known Types and their inheritance is: |
|
|
|
Fl_Type (note: can't be written) |
|
+-- Function |
|
+-- code |
|
+-- codeblock |
|
+-- decl |
|
+-- data |
|
+-- declblock |
|
+-- comment |
|
+-- class |
|
+-- Fl_Widget (note: can't be written) |
|
| +-- Fl_Window |
|
| | +-- widget_class |
|
| +-- Fl_Group |
|
| | +-- Fl_Pack |
|
| | +-- Fl_Flex |
|
| | +-- Fl_Table |
|
| | +-- Fl_Tabs |
|
| | +-- Fl_Scroll |
|
| | +-- Fl_Terminal |
|
| | +-- Fl_Tile |
|
| | +-- Fl_Wizard |
|
| | +-- Fl_Grid |
|
| +-- Fl_Menu_Type (note: can't be written) |
|
| | +-- Fl_Menu_Button |
|
| | +-- Fl_Choice |
|
| | +-- Fl_Input_Choice |
|
| | +-- Fl_Menu_Bar |
|
| | +-- Fl_ |
|
| +-- Fl_Box |
|
| +-- Fl_Button |
|
| | +-- Fl_Return_Button |
|
| | +-- Fl_Light_Button |
|
| | +-- Fl_Check_Button |
|
| | +-- Fl_Round_Button |
|
| +-- Fl_Repeat_Button |
|
| +-- Fl_Browser |
|
| +-- Fl_Check_Browser |
|
| +-- Fl_Tree |
|
| +-- Fl_File_Browser |
|
| +-- Fl_Counter |
|
| +-- Fl_Spinner |
|
| +-- Fl_Input |
|
| | +-- Fl_Output |
|
| +-- Fl_File_Input |
|
| +-- Fl_Text_Display |
|
| +-- Fl_Text_Editor |
|
| +-- Fl_Clock |
|
| +-- Fl_Help_View |
|
| +-- Fl_Progress |
|
| +-- Fl_Adjuster |
|
| +-- Fl_Dial |
|
| +-- Fl_Roller |
|
| +-- Fl_Slider |
|
| | +-- Fl_Scrollbar |
|
| | +-- Fl_Value_Slider |
|
| +-- Fl_Value_Input |
|
| +-- Fl_Value_Output |
|
. |
|
|
|
|
|
Properties |
|
---------- |
|
|
|
Properties have zero or one Words as their arguments. The number of arguments |
|
are defined per property per Type. The content of the argument Word is defined |
|
by the implementation of the property and can contain mutiple values, as |
|
described above in Strings. |
|
|
|
Properties are inherited from super Types. They can be limited to certain Types |
|
by calls to 'MyType->is_some_type()'. All properties are optional, some are |
|
mutually exclusive. |
|
|
|
Note: It is possible that the same property by name has different arguments |
|
when used in a different Type. |
|
|
|
Every node can have properties that it holds for its parent. Parent properties |
|
are stored as "parent_properties { ...list... }". If a node encounters this |
|
property tag, it must ask its parent to interpret the contents of that list. |
|
See Fl_Grid for an example. |
|
|
|
Type Fl_Type <word> |
|
|
|
"uid" <4-digit-hex> : since Oct 2023, optional, a unique id for this node |
|
within the project file |
|
“label” <word> : text |
|
“user_data” <word> : a value or an expression |
|
“user_data_type” <word> : usually “void*” or “long” |
|
“callback” <word> : a function name or a function body |
|
“comment” <word> : one or many lines of text |
|
“open” : Group content visible in the FLUID tree browser |
|
“selected” : Type was selected in tree view |
|
|
|
Type "Function" <word> : function signature |
|
|
|
none or "private" or "protected" : for methods in classes, or to mark |
|
functions static in a file, default is public |
|
“C” : if set, function is extern “C” |
|
“return_type” <word> : C or C++ type descriptor, can start with “virtual” |
|
and/or “static” to further define the function. |
|
... : inherits more from Fl_Type |
|
|
|
Type codeblock <word> : C++ code, for example "if (test())" |
|
|
|
"after" <word> : C++ code or comment following the closing '}' |
|
... : inherits more from Fl_Type |
|
|
|
Type "decl" <word> : C++ code to declare a variable or class member |
|
|
|
none or "public" or "private" or "protected" : for declarations within classes |
|
defaults to "private" |
|
none or "local" or "global": for declaration in the code body |
|
defaults to "global" |
|
... : inherits more from Fl_Type |
|
|
|
Type "data" <word> : C++ variable name |
|
|
|
"filename" <word> : name or path as entered by user, forward slashes |
|
"textmode" : defaults to binary mode |
|
"compressed" : defaults to not compressed |
|
... : inherits more from decl |
|
|
|
Type "declblock" <word> : C++ code |
|
|
|
none or "public" or "protected" : defaults to private (obsolete) |
|
"map" <word> : integer value, default is 2 (CODE_IN_SOURCE), |
|
see Fl_DeclBlock_Type::write_map_ |
|
"after" <word> : C++ code or comment following the block |
|
... : inherits more from Fl_Type |
|
|
|
Type "comment" <word> : comment text |
|
|
|
"in_source" or "not_in_source": default to in_source |
|
"in_header" or "not_in_header": default to in_header |
|
... : inherits more from Fl_Type |
|
|
|
Type "class" <word> <word> : prefix, class name |
|
|
|
none or "private" or "protected" : defaults to public |
|
":" <word> : name of super class |
|
... : inherits more from Fl_Type |
|
|
|
Type "Fl_Widget" <word> : C++ variable name |
|
|
|
none or "private" or "protected" : default is public |
|
"xywh" <word> : "{%d %d %d %d}" x, y, w, h |
|
"tooltip" <word> : tooltip text |
|
"scale_image <word>: "{%d %d}" width, height, default is 0, 0 |
|
"image" <word> : image name |
|
"compress_image" <word> : integer (1.4 and up, only if `image` is set) |
|
"bind_image" <word> : integer (1.4 and up) |
|
"scale_deimage <word>: "{%d %d}" width, height, default is 0, 0 |
|
"deimage" <word> : deactivated image name |
|
"compress_deimage" <word> : integer (1.4 and up, only if `deimage` is set) |
|
"bind_deimage" <word> : integer (1.4 and up) |
|
"type" <word> : integer |
|
"box" <word> : text or integer (see FLTK boxtypes) |
|
"down_box" <word> : (is_button() or Fl_Input_choice" or is_menu_button()) |
|
text or integer (see FLTK boxtypes) |
|
"value" <word> : (is_button()) integer |
|
"value" <word> : (is_valuator(), is_spinner()) double |
|
"color" <word> : |
|
If Word starts with "0x", the rest of the field is a hex number. |
|
If two integers follow, this is color and selection_color (deprecated). |
|
If one integer follows, it's the color index. |
|
"selection_color" <word> : integer color index |
|
"labeltype" <word> : |
|
If the Word is "image", TBD. |
|
Or one of "NORMAL_LABEL", "SHADOW_LABEL", "ENGRAVED_LABEL", |
|
"EMBOSSED_LABEL", or "NO_LABEL" |
|
"labelfont" <word> : integer, font index |
|
"labelsize" <word> : integer |
|
"labelcolor" <word> : integer, color index |
|
"align" <word> : integer, see Fl_Align |
|
"h_label_margin" <word> : integer, horizontal label margin |
|
"v_label_margin" <word> : integer, vertical label margin |
|
"image_spacing" <word> : integer, see Fl_Widget::label_image_spacing() |
|
"when" <word> : integer, see Fl_When |
|
"minimum" <word> : (is_valuator(), is_spinner()) double |
|
"maximum" <word> : (is_valuator(), is_spinner()) double |
|
"step" <word> : (is_valuator(), is_spinner()) double |
|
"slider_size" <word> : (is_valuator()==2) double |
|
"size" <word> : (is_valuator()==2) double |
|
"textfont" <word> : integer, font index |
|
"textsize" <word> : integer |
|
"textcolor" <word> : integer, color index |
|
"hide" : default visible |
|
"deactivate" : default active |
|
"resizable" : default fixed |
|
"hotspot" : make a Widget a hotspot |
|
"divider" : add a divider under a menu item |
|
"class" <word> : superclass |
|
"shortcut" <word> : integer |
|
"code0" or "code1" or "code2" or "code3" <word> : C++ extra code lines |
|
"extra_code" <word> : C++ extra code lines |
|
... : inherits more from Fl_Type |
|
|
|
Type "Fl_Button" <word> : C++ variable name |
|
|
|
"compact" <word> : integer, set the flag for compact buttons, defaults to 0 |
|
|
|
Type "Fl_Flex" <word> : C++ variable name |
|
|
|
"margins" <word> : this Word is written with printf as "{%d %d %d %d}", |
|
left, top, right, bottom |
|
"gap" <word> : integer |
|
"fixed_size_tuples" <word> : this Word is written with printf "{%d", where %d |
|
encodes the number of tuples to follow, and zero or more " %d %d" |
|
containing the index and size of that child, followed by a '}'. |
|
... : inherits more from Fl_Group |
|
|
|
Type "Fl_Window" <word> : C++ variable name |
|
|
|
none or "modal", or "non_modal": defaults to not modal (which is |
|
different to non_modal!) |
|
"visible" : show window when opening file in FLUID |
|
"noborder" : borderless window |
|
"xclass" <word> : see FLTK |
|
"size_range" : this Word is written with printf as "{%d %d %d %d}", |
|
min_w, min_h, max_w, max_h |
|
"xywh" <word> : this Word is written with printf as "{%d %d %d %d}", |
|
x, y, w, h. This as actually read in the Fl_Widget Type, but here |
|
it ensures that window is not created as a subwindow. |
|
... : inherits more from Fl_Widget (not Fl_Group) |
|
|
|
Type "Fl_Grid" <word> : C++ variable name |
|
|
|
"dimensions" <word> : {int rows, int cols} |
|
"margin" <word> : {int left, int top, int right, int bottom} |
|
"gap" <word> : {int row gap, int col gap} |
|
"rowheights" <word> : {int h, ...*rows} |
|
"rowweights" <word> : {int h, ...*rows} |
|
"rowgaps" <word> : {int h, ...*rows} |
|
"colwidths" <word> : {int h, ...*cols} |
|
"colweights" <word> : {int h, ...*cols} |
|
"colgaps" <word> : {int h, ...*cols} |
|
|
|
Fl_Grid can also produce parent properties in their children |
|
|
|
"location" <word> : {int row, int col} |
|
"colspan" <int>" |
|
"rowspan" <int> |
|
"align" <int> : see Fl_Grid_Align enum |
|
"min_size" <word> : {int width, int height} |
|
|
|
Please report errors and omissions to the fltk.coredev or fltk.general |
|
Google group. Thank you. |
|
|
|
- Matthias
|
|
|