Skip to content

Chapter 3.2: Layout File Format (.layout)

Home | << Previous: Widget Types | Layout File Format | Next: Sizing & Positioning >>


Basic Structure

A .layout file defines a tree of widgets. Every file has exactly one root widget, which contains nested children.

WidgetTypeClass WidgetName {
 attribute value
 attribute "quoted value"
 {
  ChildWidgetTypeClass ChildName {
   attribute value
  }
 }
}

Key rules:

  1. The root element is always a single widget (typically FrameWidgetClass).
  2. Widget type names use the layout class name, which always ends with Class (e.g., FrameWidgetClass, TextWidgetClass, ButtonWidgetClass).
  3. Each widget has a unique name following its type class.
  4. Attributes are key value pairs, one per line.
  5. Attribute names containing spaces must be quoted: "text halign" center.
  6. String values are quoted: text "Hello World".
  7. Numeric values are unquoted: size 0.5 0.3.
  8. Children are nested inside { } blocks after the parent's attributes.

Attribute Reference

Umístění a rozměry

AtributHodnotyPopis
positionx yWidget position (proportional 0-1 or pixel values)
sizew hWidget dimensions (proportional 0-1 or pixel values)
halignleft_ref, center_ref, right_refHorizontal alignment reference point
valigntop_ref, center_ref, bottom_refVertical alignment reference point
hexactpos0 or 10 = proportional X position, 1 = pixel X position
vexactpos0 or 10 = proportional Y position, 1 = pixel Y position
hexactsize0 or 10 = proportional width, 1 = pixel width
vexactsize0 or 10 = proportional height, 1 = pixel height
fixaspectfixwidth, fixheightMaintain aspect ratio by constraining one dimension
scaled0 or 1Scale with DayZ UI scaling setting
priorityintegerZ-order (higher values render on top)

The hexactpos, vexactpos, hexactsize, and vexactsize flags are the most important attributes in the entire layout system. They control whether each dimension uses proportional (0.0 - 1.0 relative to parent) or pixel (absolute screen pixels) units. See 3.3 Sizing & Positioning for a thorough explanation.

Vizuální atributy

AtributHodnotyPopis
visible0 or 1Initial visibility (0 = hidden)
colorr g b aColor as four floats, each 0.0 to 1.0
stylestyle namePredefined visual style (e.g., Default, Colorable)
draggable0 or 1Widget can be dragged by the user
clipchildren0 or 1Clip child widgets to this widget's bounds
inheritalpha0 or 1Children inherit this widget's alpha value
keepsafezone0 or 1Keep widget within screen safe zone

Atributy chování

AtributHodnotyPopis
ignorepointer0 or 1Widget ignores mouse input (clicks pass through)
disabled0 or 1Widget is disabled
"no focus"0 or 1Widget cannot receive keyboard focus

Textové atributy

These apply to TextWidgetClass, RichTextWidgetClass, MultilineTextWidgetClass, ButtonWidgetClass, and other text-bearing widgets.

AtributHodnotyPopis
text"string"Default text content
font"path/to/font"Font file path
"text halign"left, center, rightHorizontal text alignment within the widget
"text valign"top, center, bottomVertical text alignment within the widget
"bold text"0 or 1Bold rendering
"italic text"0 or 1Italic rendering
"exact text"0 or 1Use exact pixel font size instead of proportional
"exact text size"integerFont size in pixels (requires "exact text" 1)
"size to text h"0 or 1Resize widget width to fit text
"size to text v"0 or 1Resize widget height to fit text
"text sharpness"floatText rendering sharpness
wrap0 or 1Enable word wrapping

Atributy obrázku

These apply to ImageWidgetClass.

AtributHodnotyPopis
image0"set:name image:name"Primary image from an imageset
modeblend, additive, stretchImage blend mode
"src alpha"0 or 1Use the source alpha channel
stretch0 or 1Stretch image to fill widget
filter0 or 1Enable texture filtering
"flip u"0 or 1Flip image horizontally
"flip v"0 or 1Flip image vertically
"clamp mode"clamp, wrapTexture edge behavior
"stretch mode"stretch_w_h, etc.Stretch mode

Atributy Spacer

These apply to WrapSpacerWidgetClass and GridSpacerWidgetClass.

AtributHodnotyPopis
PaddingintegerInner padding in pixels
MarginintegerSpace between child items in pixels
"Size To Content H"0 or 1Resize width to match children
"Size To Content V"0 or 1Resize height to match children
content_halignleft, center, rightChild content horizontal alignment
content_valigntop, center, bottomChild content vertical alignment
ColumnsintegerGrid columns (GridSpacer only)
RowsintegerGrid rows (GridSpacer only)

Atributy tlačítka

AtributHodnotyPopis
switchtoggleMakes the button a toggle (stays pressed)
stylestyle nameVisual style for the button

Atributy posuvníku

AtributHodnotyPopis
"fill in"0 or 1Show a filled track behind the slider handle
"listen to input"0 or 1Respond to mouse input

Atributy posouvání

AtributHodnotyPopis
"Scrollbar V"0 or 1Show vertical scrollbar
"Scrollbar H"0 or 1Show horizontal scrollbar

Script Integration

Atribut scriptclass

The scriptclass attribute binds a widget to an Enforce Script class. When the layout is loaded, the engine creates an instance of that class and calls its OnWidgetScriptInit(Widget w) method.

FrameWidgetClass MyPanel {
 size 1 1
 scriptclass "MyPanelHandler"
}

The script class must inherit from Managed and implement OnWidgetScriptInit:

c
class MyPanelHandler : Managed
{
    Widget m_Root;

    void OnWidgetScriptInit(Widget w)
    {
        m_Root = w;
    }
}

Blok ScriptParamsClass

Parameters can be passed from the layout to the scriptclass via a ScriptParamsClass block. This block appears as a second { } child block after the widget's children.

ImageWidgetClass Logo {
 image0 "set:dayz_gui image:DayZLogo"
 scriptclass "Bouncer"
 {
  ScriptParamsClass {
   amount 0.1
   speed 1
  }
 }
}

The script class reads these parameters in OnWidgetScriptInit by using the widget's script param system.

DabsFramework ViewBinding

In mods that use DabsFramework MVC, the scriptclass "ViewBinding" pattern connects widgets to a ViewController's data properties:

TextWidgetClass StatusLabel {
 scriptclass "ViewBinding"
 "text halign" center
 {
  ScriptParamsClass {
   Binding_Name "StatusText"
   Two_Way_Binding 0
  }
 }
}
ParametrPopis
Binding_NameName of the ViewController property to bind to
Two_Way_Binding1 = UI changes push back to the controller
Relay_CommandFunction name on the controller to call when the widget is clicked/changed
Selected_ItemProperty to bind the selected item to (for lists)
Debug_Logging1 = enable verbose logging for this binding

Children Nesting

Children are placed inside a { } block after the parent's attributes. Multiple children can exist in the same block.

FrameWidgetClass Parent {
 size 1 1
 {
  TextWidgetClass Child1 {
   position 0 0
   size 1 0.1
   text "First"
  }
  TextWidgetClass Child2 {
   position 0 0.1
   size 1 0.1
   text "Second"
  }
 }
}

Children are always positioned relative to their parent. A child with position 0 0 and size 1 1 (proportional) fills its parent completely.


Complete Annotated Example

Here is a fully annotated layout file for a notification panel -- the kind of UI you might build for a mod:

// Root container -- invisible frame that covers 30% of screen width
// Centered horizontally, positioned at top of screen
FrameWidgetClass NotificationPanel {

 // Start hidden (script will show it)
 visible 0

 // Don't block mouse clicks on things behind this panel
 ignorepointer 1

 // Blue tint color (R=0.2, G=0.6, B=1.0, A=0.9)
 color 0.2 0.6 1.0 0.9

 // Position: 0 pixels from left, 0 pixels from top
 position 0 0
 hexactpos 1
 vexactpos 1

 // Size: 30% of parent width, 30 pixels tall
 size 0.3 30
 hexactsize 0
 vexactsize 1

 // Center horizontally within parent
 halign center_ref

 // Children block
 {
  // Text label fills the entire notification panel
  TextWidgetClass NotificationText {

   // Also ignore mouse input
   ignorepointer 1

   // Position at origin relative to parent
   position 0 0
   hexactpos 1
   vexactpos 1

   // Fill parent completely (proportional)
   size 1 1
   hexactsize 0
   vexactsize 0

   // Center the text both ways
   "text halign" center
   "text valign" center

   // Use a bold font
   font "gui/fonts/Metron-Bold"

   // Default text (will be overridden by script)
   text "Notification"
  }
 }
}

And here is a more complex example -- a dialog with a title bar, scrollable content, and a close button:

WrapSpacerWidgetClass MyDialog {
 clipchildren 1
 color 0.7059 0.7059 0.7059 0.7843
 size 0.35 0
 halign center_ref
 valign center_ref
 priority 998
 style Outline_1px_BlackBackground
 Padding 5
 "Size To Content H" 1
 "Size To Content V" 1
 content_halign center
 {
  // Title bar row
  FrameWidgetClass TitleBarRow {
   size 1 26
   hexactsize 0
   vexactsize 1
   draggable 1
   {
    PanelWidgetClass TitleBar {
     color 0.4196 0.6471 1 0.9412
     size 1 25
     style rover_sim_colorable
     {
      TextWidgetClass TitleText {
       size 0.85 0.9
       text "My Dialog"
       font "gui/fonts/Metron"
       "text halign" center
       "text valign" center
      }
      ButtonWidgetClass CloseBtn {
       size 0.15 0.9
       halign right_ref
       text "X"
      }
     }
    }
   }
  }

  // Scrollable content area
  ScrollWidgetClass ContentScroll {
   size 0.97 235
   hexactsize 0
   vexactsize 1
   "Scrollbar V" 1
   {
    WrapSpacerWidgetClass ContentItems {
     size 1 0
     hexactsize 0
     "Size To Content V" 1
    }
   }
  }
 }
}

Caste chyby

  1. Zapomenuti na priponu Class -- V layoutech piste TextWidgetClass, ne TextWidget.
  2. Michani proporcionalnich a pixelovych hodnot -- Pokud hexactsize 0, hodnoty velikosti jsou 0.0-1.0 proporcionalne. Pokud hexactsize 1, jsou to pixelove hodnoty. Pouziti 300 v proporcionalnim rezimu znamena 300x sirka rodice.
  3. Neuvozovkovani viceslonnych atributu -- Piste "text halign" center, ne text halign center.
  4. Umisteni ScriptParamsClass do spatneho bloku -- Musi byt v samostatnem bloku { } za blokem potomku, ne uvnitr nej.

Osvedcene postupy

  • Vzdy nastavte vsechny ctyri exact flagy (hexactpos, vexactpos, hexactsize, vexactsize) explicitne na kazdem widgetu. Spolihat se na vychozi hodnoty vede k nejednoznacnym layoutum, ktere se rozbiji pri zmene rodicovske struktury.
  • Pouzivejte scriptclass strídme -- pouze na widgetech, ktere skutecne potrebuji skriptem rizene chovani. Nadmerne vazani pridava rezie inicializace.
  • Pojmenovavejte widgety popisne (PlayerListScroll, TitleBarClose) misto genericke (Frame1, btn). Skriptovy kod pouziva FindAnyWidget() podle nazvu a kolize zpusobuji tiche selhani.
  • Udrzujte layout soubory pod 200 radky. Rozdelete slozita UI do vice .layout souboru nactavanych pomoci CreateWidgets() a programaticky pripojenych k rodici.
  • Vzdy uvozovkujte viceslovna jmena atributu ("text halign", "Size To Content V"). Neuvozovkovane viceslonne atributy tise selhavaji bez chyby.

Teorie vs praxe

Co dokumentace rika versus jak veci skutecne funguji za behu.

KonceptTeorieRealita
Inicializace scriptclassOnWidgetScriptInit je volana pri nacteni layoutuPokud trida nededi z Managed nebo ma chybu v konstruktoru, widget se nacte, ale handler je tise null
ScriptParamsClassParametry predavaji libovolna data skriptovym tridamSpolehlive funguji pouze retezcove a ciselne hodnoty; vnorene objekty nebo pole nejsou podporovany
Atribut colorCtyri floaty 0.0-1.0 (RGBA)Nektere typy widgetu ignoruji alfa kanal nebo vyzaduji inheritalpha 1 na rodici pro sdruzeni pruhlednosti
Vychozi atributyNedokumentovane atributy pouzivaji vychozi hodnoty enginuVychozi hodnoty se lisi podle typu widgetu -- ButtonWidget ma vychozi hexactsize odlisne od FrameWidget na nekterych verzich enginu
"no focus"Zabranuje zamirani klavesniciZabranuje take vyberu gamepadem, coz muze narusit navigaci ovladacem, pokud je nastaveno na interaktivnich widgetech

Kompatibilita a dopad

  • Multi-Mod: Layout soubory jsou izolovane pro kazdy mod -- zadne prime konflikty. Nicmene nazvy scriptclass musi byt globalne unikatni. Dva mody pouzivajici scriptclass "PanelHandler" zpusobi, ze jeden tise selze.
  • Vykon: Kazdy widget v layoutu je skutecny objekt enginu. Layouty s 500+ widgety zpusobuji meritelne poklesy snimkove frekvence. Pro velke seznamy preferujte programaticky pooling.
  • Verze: Format layoutu je stabilni od DayZ 1.0. Blok ScriptParamsClass a scriptclass ViewBinding byly pridany DabsFrameworkem a nejsou vanilla funkce.

Pozorovano v realnuch modech

VzorModDetail
scriptclass "ViewBinding" s ScriptParamsClassDabsFramework / DayZ EditorObousmerna datova vazba mezi layouty a ViewControllery pres parametr Binding_Name
WrapSpacerWidgetClass jako koren dialoguCOT, ExpansionUmoznuje Size To Content V/H pro automatickou velikost dialogu kolem dynamickeho obsahu
Samostatny .layout pro radek seznamuVPP Admin ToolsKazdy radek hrace je samostatny layout nacteny do WrapSpacer, umoznujici opakovane pouziti a pooling
priority 998-999 pro modalni prekryvyDabsFramework, COTZajistuje, ze dialogy se vykresluji nad vsemi ostatnimi prvky UI

Dalsi kroky

Released under CC BY-SA 4.0 | Code examples under MIT License