Worked example
A settings screen built from three files — one row component, a library and the screen — walked through to show which rule of the language each part relies on.
A settings screen built from one row component. Three files: the component; a library that names it and styles the family; and the screen.
Both Blueprints have UDreamTextUserWidget as their parent, with Source Files Settings/SettingsRow.dui and
Settings/SettingsScreen.dui. The library has no root and no Blueprint.
The component: one row
The row — a label on the left, a value with arrows on the right — declares what a host sets and hears:
// DUI/Settings/SettingsRow.dui
class /Game/UI/Settings/WBP_SettingsRow
use "Settings/SettingsLibrary.dui"
props {
Text Label
Text Value
Number Index = 0
}
events {
Changed(Number Index, Number Step)
}
Widget Root : RowBox {
+ HorizontalBox { Padding = (16, 0, 16, 0) Spacing = 12 }
+ UIButton { TransitionType = None }
Text LabelText : Caption {
Text <- Label
@fill
}
Native.Button Previous : Arrow {
OnClicked -> emit Changed(Index, -1)
Text { Text = "◀" }
}
Text ValueText : Caption {
Text <- Value
HAlign = Center
@slot MinDesiredSize = (220, 0)
}
Native.Button Next : Arrow {
OnClicked -> emit Changed(Index, 1)
Text { Text = "▶" }
}
}- The
classline says it compiles intoWBP_SettingsRow. The library'suse … as Rowreads the class from this line, so it does not need the editor to find the Blueprint. use "Settings/SettingsLibrary.dui"gives the row the library's styles (RowBox,Caption,Arrow). The libraryuses this file in turn, and that is not a cycle:use … asreads only a component file's header and does not follow itsuselines (seeuse).propsdeclares three Blueprint variables,Label,ValueandIndex;eventsdeclares an event dispatcher,Changed, with two parameters.- The root carries a horizontal box and a button behaviour through two
+blocks; theRowBoxstyle gives it its height. LabelTextbinds its text to the propLabel, and@fillgives it the width the row has left.ValueTextbindsValueand asks for at least 220 of width with a slot line.- Each arrow button raises
Changedwithemit, its arguments binding expressions:Indexis the prop,-1and1the step. TheTextinside each button has no id; theirs arePrevious__Text0andNext__Text0.
The library: names and styles
The library holds the family's look and its names. Because it has no root it can be used plainly or under a namespace, and
its use … as line travels with it:
// DUI/Settings/SettingsLibrary.dui
use "Settings/SettingsRow.dui" as Row
resources {
Color Ink = #E6E9F0
Color Muted = #8C93A6
Color Panel = #1B1E26
}
style Caption {
FontSize = 18
Color = @Ink
}
style RowBox {
AnchorData.SizeDelta = (0, 48)
}
style Arrow {
AnchorData.SizeDelta = (40, 40)
}
style Column {
+ VerticalBox { Spacing = 8 }
@fill
}use … as Rownames the row component. Every screen that uses the library gets that name:Rowafter a plainuse,ui.Rowafteruse … as ui.- The three colour resources become variables of every class that imports them. The
@InkinCaptionalways means this library'sInk, even where the style is used under a namespace. - The
Columnstyle carries a vertical box and an@fill, so a column is one name (see Styles and resources).
The screen
The screen places three rows, routes each one's Changed to a handler of its own, shows a hint only while there are
unsaved changes, and lists the key hints from the class's data:
// DUI/Settings/SettingsScreen.dui
class /Game/UI/Settings/WBP_SettingsScreen
use "Settings/SettingsLibrary.dui" as ui
Widget Root {
AnchorData.AnchorMin = (0, 0)
AnchorData.AnchorMax = (1, 1)
AnchorData.SizeDelta = (0, 0)
+ Overlay { }
Image Backdrop {
Brush.TintColor = @ui.Panel
@slot { HorizontalAlignment = Fill VerticalAlignment = Fill }
}
VerticalBox Page {
Spacing = 24
Padding = (64, 48, 64, 48)
@slot { HorizontalAlignment = Fill VerticalAlignment = Fill }
Text Heading : ui.Caption {
Text = "Settings"
FontSize = 32
}
Widget Rows : ui.Column {
ui.Row Audio {
Label = "Master volume"
Value = "80 %"
Changed -> HandleVolumeChanged
}
ui.Row Display {
Label = "Display mode"
Value = "Fullscreen"
Index = 1
Changed -> HandleDisplayModeChanged
}
ui.Row Language {
Label = "Language"
Value = "English"
Index = 2
Changed -> HandleLanguageChanged
}
}
if HasUnsavedChanges() {
Text UnsavedHint : ui.Caption {
Text = "Unsaved changes"
Color = @ui.Muted
}
}
HorizontalBox {
Spacing = 16
Native.Button Apply { OnClicked -> HandleApply }
Native.Button Back { OnClicked -> HandleBack }
for Hint in KeyHints {
Text : ui.Caption { Text <- Hint.Label }
}
}
}
}The rules each part relies on:
- A namespace.
use … as uikeeps the library's names apart from the screen's own:: ui.Caption,@ui.Panel, and the row asui.Row— the library's ownuse "Settings/SettingsRow.dui" as Rowcame along under the namespace. Seeuse. - Component instances.
ui.Row Audio { … }is an instance of the row:Label,ValueandIndexset its props — the first values only; a handler changesValuelater through the row's variable,Audio— andChanged ->routes the event the row raises withemitfrom its arrow buttons. See Writing a component. - Containers as types.
VerticalBox Pageand the unnamedHorizontalBoxare containers written as node types; theirSpacingandPaddingare the containers'. The unnamed one's id isPage__HorizontalBox0. See Nodes and values. - A style that carries a component.
Widget Rows : ui.Columngets its vertical box and its fill from the style. if. The hint shows only whileHasUnsavedChanges()is true; nothing is created or destroyed when it flips, only its visibility changes. See if and for.for. One text per item of the class'sKeyHints(a FieldNotify array variable of objects with aLabelmember), after the two buttons;Text <- Hint.Labelbinds each copy to its item.- Backdrop and fill. The root is anchored to all four corners with no inset and carries an
Overlay;BackdropandPageboth Fill in both directions through@slot { … }.
What the class supplies
The screen's class supplies these members, in C++ or in the Blueprint's graph:
| Member | Used by | Needs to be |
|---|---|---|
HasUnsavedChanges | the if condition | a function with no parameters returning a bool |
KeyHints | the for source | a FieldNotify array variable of objects with a Label (DUI6006, DUI6007) |
HandleVolumeChanged, HandleDisplayModeChanged, HandleLanguageChanged | Changed -> | handlers with the event's parameters, (Index, Step) (DUI6004, DUI6005) |
HandleApply, HandleBack | OnClicked -> | handlers with the parameters of the button's OnClicked |
The row's class needs nothing written by hand: its props and its event are declared in the .dui and generated at compile.
Designer write-back
The designer is a front end for the .dui — which line an edit is written into, how a hand-written file is left alone, and which edits it refuses (DUI7xxx).
The control library
What DreamGUIControls holds — the Dream* controls by kind, the UI* behaviours they are built from, the action bar, the UMG interop, and how to place a control from .dui.