Skip to content

Layout from XML ​

Every layout field has an attribute of the same name (see Layout for what each one means). This page shows the common shapes. The xml-layout example in the willowui repository has a tab for each.

Stacks ​

xml
<Panel layout="hbox" spacing="16" padding="12">
    <Panel layout="vbox" spacing="6" padding="10" background="#1a1c22" cornerRadius="6">
        <Button text="Top" size="160,36" />
        <Button text="Middle" size="160,36" variant="neutral" />
        <Button text="Bottom" size="160,36" />
    </Panel>
    <Panel layout="vbox" spacing="6" padding="10" size="180,200" justify="end" align="center">
        <Label text="Pushed to the bottom, centered" />
        <Button text="OK" size="80,30" />
    </Panel>
</Panel>

justify places children along the stack (start, center, end, space-between), align across it.

Automatic size ​

A container with children and no size grows to fit them, padding included. Give only one of width or height and the other is fitted. Give size to fix both, for example to make justify meaningful.

Grow ​

Inside a vbox or hbox, children with grow share the space the fixed children leave:

xml
<Panel layout="hbox" size="600,40" spacing="8">
    <Button text="Fixed" size="100,40" />
    <Button text="Grows 1" grow="1" height="40" />
    <Button text="Grows 2" grow="2" height="40" />
</Panel>

Grid ​

xml
<Panel layout="grid" gridColumns="3" spacing="6" padding="10">
    <Button text="1" size="60,40" />
    <Button text="2" size="60,40" />
    <Button text="3" size="60,40" />
    <Button text="4" size="60,40" />
    <Button text="5" size="60,40" />
    <Button text="6" size="60,40" />
</Panel>

Flow ​

Children run left to right and wrap when the next one does not fit the width:

xml
<Panel layout="flow" width="300" spacing="6" flow-row-gap="6">
    <Tag text="fire" />
    <Tag text="ice" />
    <Tag text="lightning" />
    <Tag text="poison" />
    <Tag text="holy" />
</Panel>

Anchors ​

xml
<Panel name="hud" layout="anchor" size="700,420" padding="10">
    <Label anchor="top-left" text="HP 100" />
    <Label anchor="top-right" text="Gold 250" />
    <Label anchor="center" text="Paused" fontSize="32" />
    <Button anchor="bottom-right" offsetX="-8" offsetY="-8" text="Menu" />
</Panel>

Offsets are pixels from the anchor point.

Two columns ​

TwoColumnLayout takes its children in pairs: left, right, left, right. An odd last child is added on its own.

xml
<TwoColumnLayout leftWidth="120" gap="12" rowSpacing="8">
    <Label text="Name" />
    <TextInput width="200" placeholder="Hero" />
    <Label text="Class" />
    <Select options="Warrior,Mage,Rogue" size="200,32" />
    <Label text="Hardcore" />
    <Toggle />
</TwoColumnLayout>

columnRatio sizes the left column as a fraction instead of leftWidth. leftAlign and rightAlign align each column.

Tabs ​

Each <Tab> inside a <TabBar> becomes a page. The tab's own layout attributes apply to its page, and its children go inside.

xml
<TabBar size="500,300">
    <Tab label="General" layout="vbox" spacing="8" padding="12">
        <Checkbox text="Show tips" />
        <Checkbox text="Autosave" />
    </Tab>
    <Tab label="Audio" layout="vbox" spacing="8" padding="12">
        <Label text="Master volume" />
        <Slider width="240" range="0,100" />
    </Tab>
</TabBar>

Windows ​

A Window's children go into its body, which stacks them vertically.

xml
<Window title="Inventory" size="320,240" resizable="true" closeable="true">
    <Label text="Three potions" />
    <Button text="Use one" on:click="usePotion" />
</Window>

Add the instantiated window to DEFAULT_WINDOW_MANAGER so it stacks and focuses with other windows. The Containers page shows a window built in code.

Scrolling ​

ScrollPanel takes size, background, scrollX and scrollY. Its content size is set in code with setContentSize(w, h), so name it and size it after instantiate.