DreamGUI
The .dui Language

Styles and resources

A style is a named set of lines that can inherit and carry components and slot lines; a resource is a typed, named constant.

Styles and resources both keep one value from being written many times, but they are two different things: a style is a set of lines applied to a node by name, and a resource is a value referred to by name.

Styles

A style is a named set of lines, applied to a node by : Name:

style Caption {
    FontSize = 14
    Color    = #8C93A6
}

style Warning : Caption {
    Color = #E05A47
}

Widget Root {
    + VerticalBox { }
    Text Note : Warning { Text = "Unsaved changes" }
}

Note ends up at size 14 in #E05A47. The rules:

  • A style may inherit another (style Warning : Caption): the base's lines apply first, then the derived style's, then the node's own. A base that comes back around is DUI3015.
  • : Name naming no style this file sees is DUI3004.
  • A local style shadows an imported one of the same name. Two local styles of one name are DUI3005.
  • The order of declaration is free; a style may come after the node that wears it.

A style is a bag of values applied by name, with no identity of its own: its values land on the nodes that wear it, and the style itself never becomes a variable of the class.

Components and slot lines in a style

A style may also carry + Component blocks and slot lines, so that a kind of column is one name:

style RowColumn {
    + VerticalBox { Spacing = 15 }
    @fill
}

Widget Root {
    + HorizontalBox { Spacing = 24 }
    Widget Left : RowColumn {
        Text { Text = "Left" }
    }
    Widget Right : RowColumn {
        + VerticalBox { Spacing = 30 }
        @slot FillWeight = 2
        Text { Text = "Right" }
    }
}
  • The style's components come first. A component of the same class the node also writes is one object, the style's values first and the node's after. Right's vertical box above ends up at Spacing = 30, and there is no second layout container.
  • The node's own @slot lines win over the style's. Right above is Fill (from the style) with weight 2 (from the node).
  • A style holds no children: it is a set of lines, not a tree.

Changing, in the designer, a value a node takes from its style's + line is not written back (DUI7005): the style is shared, and the node has no + line of its own to hold the change. Add one to the node (+ VerticalBox { Spacing = 20 }) or change the style. See Designer write-back.

Styles across files

Styles are shared between files through use: after use "UI/Library.dui" you write : Caption, after use "UI/Library.dui" as ui you write : ui.Caption. See use.

The VS Code extension can extract selected property lines into a style the node then wears, and inline a worn style back (base first, derived overriding), its + components and slot lines included.

Resources

class /Game/UI/WBP_Palette

resources {
    Color   Accent = #FF6600
    Number  Gap    = 8
    Vector2 Icon   = (24, 24)
    String  Brand  = "Dream"
    Asset   Body   = /DreamGUI/DefaultFont_DistanceField
}

VerticalBox Root {
    Spacing = @Gap
    Text Title {
        Text  = @Brand
        Font  = @Body
        Color = @Accent
    }
    Image Logo {
        Brush.ImageSize = @Icon
    }
}

Each entry is a type, a name and a value. There are five types: Color, Number, Vector2, String, Asset. From then on @Accent stands for #FF6600 wherever a value goes, and in a binding expression. An Asset entry also takes a quoted path.

  • The type is checked against the entry's own value (Color Accent = 8 fails on the entry's line, once, instead of as a shape mismatch on every line that says @Accent): a mismatch is DUI4008, and so is a type name outside the five.
  • A reference to an entry that does not exist is DUI4007.
  • Entries accumulate over several resources blocks; one name declared twice is DUI3014.
  • Each entry also becomes a variable of the compiled class, so a graph and the Class Defaults panel can see what @Accent is. Entries a use brought in do too; a local entry of the same name shadows the imported one.

Why resources are typed when nothing else is: 8 on a property knows what it is from the FProperty it lands on, but 8 in a resources block has nothing to land on until somebody writes @Gap — and by then a type error would point at the use instead of the mistake.

Resources in a binding

class /Game/UI/WBP_Fade

resources {
    Number Dim = 0.8
}

Widget Root {
    + Overlay { }
    Image Glow {
        RenderOpacity <- Fade() * @Dim
    }
}

A resource as a node type

An Asset entry naming a widget class can be a node type: @Row Audio { … }. An entry that is not an Asset used as a type is DUI4008. use … as does the same with less; see use.

In VS Code a literal can be extracted into a resource (that occurrence, or all of them), and an undeclared resource has a quick fix that declares it.

On this page