Skip to content

Using DML to create layouts

Grim Maple edited this page Nov 24, 2022 · 11 revisions

DML purpose

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

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 newline PropertyDefinitions

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

Standard registered widget types

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

Standard widget properties

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

Additional properties for some standard widgets

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

Registering widgets for using in DML

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)());

Registering custom widget properties

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"));