-
Notifications
You must be signed in to change notification settings - Fork 123
Using DML to create layouts
DML (DlangUI Markup Language) is declarative language for easy describing of UI layouts (hierarchy of widgets).
Like QML, it allows to specify widget and its children, set their properties and styles.
Unlike QML, writing of event handlers in DML is not yet supported.
There is DMLEDIT example - dlangui/examples/dmledit - GUI for writing and testing DML.
DML may be used either to fill properties and populate children of existing widget, or to create new widget.
To create widget, use "WidgetClassName { ... }":
// using DML to create new widget
VerticalLayout layout = parseML!VerticalLayout(q{
VerticalLayout {
TextWidget { text: "line1" }
TextWidget { text: "line2" }
}
});
To apply DML to existing widget, use "{ ... }":
// using DML to fill content and set properties of specified widget
parseML(q{
{
backgroundColor: "#FFFFFF"
TextWidget { text: "line1" }
TextWidget { text: "line2" }
}
}, this);
DML syntax is similar to JSON or QML.
Comments:
// one line comment till end of line
/* Multiline comment
may span several lines */
Identifiers must start with alpha or underscore, may content alpha, digits, and underscores (case sensitive):
SomeIdent
MY_IDENT
_ident123
Strings must be enclosed in ''
or ""
quotes. Quotes may be omitted if string itself forms valid Identifier
. In this case value of string is just a name of identifier.
'Some string' // string in single quotes
"Yet another string" // string in double quotes
SOME_IDENTIFIER // equivalent of "SOME_IDENTIFIER"
For UIString values, identifier w/o quotes is identifier of translation string - will be replaced by value from translation resource. String in quotes is a raw string.
FILE_OPEN // translation resource id; in res/i18n/en.ini there should be line like `FILE_OPEN=Open file...`
"Open file..." // raw string; will be displayed as is
Blocks are delimited with {}
DMLFile
:
WidgetDefinitionBlock
WidgetDefinitionBlockNoType
WidgetDefinitionBlock
-
WidgetType
{BlockContent
}
WidgetDefinitionBlockNoType
-
{
BlockContent
}
WidgetType
:
Identifier
BlockContent
:
- empty
-
WidgetDefinitionBlock
BlockContent
-
PropertyDefinitions
BlockContent
PropertyDefinitions
:
PropertyDefinition
-
PropertyDefinition
;PropertyDefinitions
-
PropertyDefinitions
newlinePropertyDefinitions
PropertyDefinition
:
-
Identifier
:PropertyValue
Identifiers are case sensitive.
When identifier string is expected, and identifier starts with alpha, and contains only alphas, digits and underscores, quotation marks may be omitted.
TBD
type | module | description |
---|---|---|
Widget | dlangui.widgets.widget | base widget class (cannot contain children) |
TextWidget | dlangui.widgets.controls | static text |
MultilineTextWidget | dlangui.widgets.controls | multiline static text |
Button | dlangui.widgets.controls | button with text |
ImageWidget | dlangui.widgets.controls | static image |
ImageButton | dlangui.widgets.controls | button with icon |
ImageCheckButton | dlangui.widgets.controls | checkbutton with icon |
ImageTextButton | dlangui.widgets.controls | button with icon and text |
RadioButton | dlangui.widgets.controls | radio button |
CheckBox | dlangui.widgets.controls | check box |
ScrollBar | dlangui.widgets.controls | scroll bar -- vertical or horizontal |
HSpacer | dlangui.widgets.controls | horizontal spacer -- fills horizontal space in layouts |
VSpacer | dlangui.widgets.controls | vertical spacer -- fills vertical space in layouts |
CanvasWidget | dlangui.widgets.controls | canvas for custom drawing |
VerticalLayout | dlangui.widgets.layouts | lays out children vertically |
HorizontalLayout | dlangui.widgets.layouts | lays out children horizontally |
TableLayout | dlangui.widgets.layouts | lays out children as a table (don't forget to specify colCount property) |
FrameLayout | dlangui.widgets.layouts | lays out children to show one at a time (others stay invisible) |
ListWidget | dlangui.widgets.lists | scrollable list of widgets (like in android) |
StringListWidget | dlangui.widgets.lists | scrollable list of string items |
EditLine | dlangui.widgets.editors | single line text edit widget |
EditBox | dlangui.widgets.editors | multiline text edit widget |
LogWidget | dlangui.widgets.editors | readonly multiline text edit widget suitable for logging |
ComboBox | dlangui.widgets.combobox | combo box control |
StringGridWidget | dlangui.widgets.grid | grid (like a spreadsheet) with string items |
ProgressBarWidget | dlangui.widgets.progressbar | progress bar |
GroupBox | dlangui.widgets.groupbox | group box |
MainMenu | dlangui.widgets.menu | main menu widget |
TreeWidget | dlangui.widgets.tree | tree widget |
name | type | description | example |
---|---|---|---|
id | id string | id for widget | id: BUTTON1 |
styleId | id string | id of style to use for displaying widget | styleId: BUTTON |
backgroundImageId | drawable resource id | id drawable resource to draw as widget background (includes padding, excludes margins) | backgroundImageId: button_bg_blue |
backgroundColor | color | color to draw as widget background (includes padding, excludes margins) | backgroundColor: "#FF00FF" |
alignment | alignment | List of alignment flags (combined with |): Left, Right, Top, Bottom, HCenter, VCenter, Center, TopLeft | alignment: Center |
text | id string or string | Either the text fir the widget, either the text resource ID |
text: MY_TEXT or text: "My Text"
|
textColor | color | color to draw text in widget | textColor: "#FF00FF" |
margins | dimensions | margins from widget box to parent box (widget background is excluded from margins) | margins=[10px,5pt,3,3] |
padding | dimensions | padding widget box to content (widget background will include padding) | padding=[3,4,1em,1.5em] |
minWidth | dimension | minimal width of widget | minWidth: 300px |
maxWidth | dimension | maximal width of widget | maxWidth: 300pt |
minHeight | dimension | minimal height of widget | minHeight: 3em |
maxHeight | dimension | maximal height of widget | maxHeight: 100 |
maxLines | integer | maximal number of text lines; applicable to some types of widgets | maxLines="3" |
fontFace | font face | list of font face to use for displaying text | fontFace: "Arial;DjVu Sans" |
fontFamily | font family | font family to use for displaying text: SansSerif, Serif, Cursive, Fantasy, MonoSpace, Unspecified | fontFamily: "MonoSpace" |
fontSize | dimension | size of font for displaying text in widget | fontSize: 12pt |
fontWeight | font weight | weight of font - either "bold" or "normal" | fontWeight: bold |
layoutWidth | layout dimension | FILL_PARENT, WRAP_CONTENT or fixed dimension | layoutWidth: fill |
layoutHeight | layout dimension | FILL_PARENT, WRAP_CONTENT or fixed dimension | layoutHeight: wrap |
alpha | dimension | widget transparency (0==opaque, 100%==transparent) | alpha: 50% |
textFlags | text flags | text property flags - set of HotKeys, UnderlineHotKeys, UnderlineHotKeysWhenAltPressed, Underline | textFlags: Underline |
name | widget type | type | description | example |
---|---|---|---|---|
colCount | StringGrid | integer | number of columns | colCount: 2 |
tabSize | EditLine, EditBox | integer | number of spaces for tab character | tabSize: 4 |
readOnly | EditLine, EditBox, ComboBox | bool | when true, text in editor cannot be modified, but you can use selection to copy part of text | readOnly: true |
useSpacesForTabs | EditLine, EditBox | bool | when true, insert spaces instead of TAB character on pressing of TAB key | useSpacesForTabs: true |
wantTabs | EditLine, EditBox | bool | when true, TAB key inserts tab character instead of moving focus to another widget | wantTabs: true |
replaceMode | EditLine, EditBox | bool | when true, new entered characters replace characters under cursor | replaceMode: true |
showTabPositionMarks | EditBox | bool | when true, vertical lines for tab positions are show for left whitespace | showTabPositionMarks: true |
copyCurrentLineWhenNoSelection | EditBox | bool | when true, and there is no selection, COPY action copies fill current line instead of empty string | copyCurrentLineWhenNoSelection: true |
showIcons | EditBox | bool | when true, show icons (e.g. for bookmarked line, error or breakpoint) in text editor | showIcons: true |
showFolding | EditBox | bool | when true, show icons (e.g. for bookmarked line, error or breakpoint) in source text editor | showFolding: true |
showModificationMarks | EditBox | bool | when true, TAB key inserts tab character instead of moving focus to another widget | showModificationMarks: true |
showLineNumbers | EditBox | bool | when true, show line numbers on left panel | showLineNumbers: true |
items | StringListWidget, ComboBox | array of UIString | strings to show in list | items: ["item1", "item2"] |
orientation | ScrollBar | orientation | either Vertical or Horizontal | orientation: Vertical |
minValue | ScrollBar, ProgressBar | integer | minimal value for scroll bar position | minValue: 0 |
maxValue | ScrollBar, ProgressBar | integer | max value for scroll bar position | maxValue: 100 |
pageSize | ScrollBar | integer | visible part of minValue..maxValue range | pageSize: 10 |
position | ScrollBar, ProgressBar | integer | current position | position: 50 |
Standard widgets are registered in registerStandardWidgets() function of startup.d
module.
mixin(registerWidgets!(FileNameEditLine, DirEditLine, //dlangui.dialogs.filedlg
ComboBox, ComboEdit, //dlangui.widgets.combobox
Widget, TextWidget, MultilineTextWidget, Button, ImageWidget, ImageButton, ImageCheckButton, ImageTextButton,
SwitchButton, RadioButton, CheckBox, HSpacer, VSpacer, CanvasWidget, // dlangui.widgets.controls
ScrollBar, SliderWidget, // dlangui.widgets.scrollbar
EditLine, EditBox, LogWidget,//dlangui.widgets.editors
GroupBox, // dlangui.widgets.groupbox
ProgressBarWidget, // dlangui.widgets.progressbar
StringGridWidget, //dlangui.widgets.grid
VerticalLayout, HorizontalLayout, TableLayout, FrameLayout, // dlangui.widgets.layouts
ListWidget, StringListWidget,//dlangui.widgets.lists
MainMenu, //dlangui.widgets.menu
TreeWidget, // dlangui.widgets.tree
)("void registerWidgets"));
registerWidgets();
You may write similar code to register your own widget.
Widgets must be registered before their using in DML.
Sample code to register widgets:
import dlangui.widgets.metadata;
mixin(registerWidgets!(MyCustomWidget1, MyCustomWidget2)());
Widgets inherit DML attributes of parent widget class.
You may want to add custom attributes to your widget class.
Widget class defines property setter methods for different types. It has several bool setXXXProperty(string name, T value)
methods - one method per type. Property setter returns false if property name is unknown.
/// set string property value, for ML loaders
bool setStringProperty(string name, string value);
/// set string property value, for ML loaders
bool setDstringProperty(string name, dstring value);
/// set string property value, for ML loaders
bool setUistringProperty(string name, UIString value);
/// StringListValue list values
bool setStringListValueListProperty(string propName, StringListValue[] values);
/// UIString list values
bool setUIStringListProperty(string propName, UIString[] values);
/// set string property value, for ML loaders
bool setBoolProperty(string name, bool value);
/// set double property value, for ML loaders
bool setDoubleProperty(string name, double value);
/// set int property value, for ML loaders
bool setIntProperty(string name, int value);
/// set Rect property value, for ML loaders
bool setRectProperty(string name, Rect value);
You may use mixin for simple generation of setXXXProperty method:
/// set int property value, for ML loaders
mixin(generatePropertySettersMethodOverride("setIntProperty", "int",
"headerCols", "headerRows", "fixedCols", "fixedRows", "cols", "rows", "defColumnWidth", "defRowHeight"));