The user can add an arbitrary number of highly configurable shell commands through the setting panel. The commands can be saved as user preferences, inside the .fl file, or exported to an external file. Shell scripts can be limited to individual platforms, can have shortcut keys, etc. . * documentation will follow * support to call `fltk-config` will follow
480 lines
17 KiB
Plaintext
480 lines
17 KiB
Plaintext
|
||
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
|
||
|
||
"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
|
||
|
||
"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 since May 2023, the 'snap' keyword can be
|
||
used to store the selected layout and preset and include more suites
|
||
of presets. 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
|
||
|
||
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_Tile
|
||
| | +-- Fl_Wizard
|
||
| +-- 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_Simple_Terminal
|
||
| +-- 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.
|
||
|
||
|
||
Type Fl_Type <word>
|
||
|
||
“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
|
||
... : inherits more from decl
|
||
|
||
Type "declblock" <word> : C++ code
|
||
|
||
none or "public" or "protected" : defaults to private
|
||
"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
|
||
"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)
|
||
"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
|
||
"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)
|
||
|
||
|
||
Please report errors and omissions to the fltk.coredev or fltk.general
|
||
Google group. Thank you.
|
||
|
||
- Matthias
|