Fuse comes with an extremly powerful layout system that lets one create UIs in a reactive way that will fit on many different screen sizes and aspect ratios. It also makes it straight forward to make components that work with a wide range of input types and sizes.
Defining UI layout
UIs in Fuse are created by a hierarchy of Panels, as well as other primitives like Rectangle and Image. The various Panel types like StackPanel, Grid and DockPanel are used to position and size multiple elements relative to each other as well as relative to the available screen size.
The following example shows how to make a grid with two rows and three columns filled with rectangles of various colors.
<App> <Grid RowCount="2" ColumnCount="3"> <Rectangle Color="#ff4500" /> <Rectangle Color="#ee7942" /> <Rectangle Color="#ee6363" /> <Rectangle Color="#ffb90f" /> <Rectangle Color="#eeb422" /> <Rectangle Color="#eedc82" /> </Grid> </App>
We can nest several panels to create more complex structures:
<App> <StackPanel> <DockPanel Height="50"> <Text Value="Hello" Dock="Left" /> <Rectangle Color="#f00" /> </DockPanel> <DockPanel Height="50"> <Text Value="World" Dock="Left" /> <Rectangle Color="#00f" /> </DockPanel> </StackPanel> </App>
For each UX-tag representing a
Visual element, we can set properties that will affect the elements
Opacity and much more. We can also control how it relates to its parent node and its children nodes using
Margin / Padding
Padding are two of the most used element properties.
Margin controls the distance from the edges of an element to the corresponding edges of its container. Padding works similarly to Margin, but instead works inwards. It sets the distance from its edges to the corresponding edges of its child elements.
Padding are of type
float4, which means they have four floating point value components. They are specified in UX as comma separated lists:
<Panel Margin="10,20,30,40" /> <Panel Padding="10,20,30,40" />
Each value represents one of the elements four edges: "10(left),20(top),30(right),40(bottom)".
We can also write in shortened forms:
<Panel Margin="10" /> <!-- is expanded to "10,10,10,10" --> <Panel Padding="10,20" /> <!-- is expanded to "10,20,10,20" -->
In the cases where an element is smaller than the available space it is assigned by its parent, we can use the
Alignment property to control where in its available space it is placed.
The following example shows how to place rectangles in the four corners of the screen.
<App> <Panel> <Rectangle Alignment="TopLeft" Width="40" Height="40" Color="Red" /> <Rectangle Alignment="TopRight" Width="40" Height="40" Color="Blue" /> <Rectangle Alignment="BottomLeft" Width="40" Height="40" Color="Green" /> <Rectangle Alignment="BottomRight" Width="40" Height="40" Color="Yellow" /> </Panel> </App>
Width / Height
Height properties can be used to ensure a given
Element will have specific dimensions on-screen. By default, these are usually set to
Auto, which means the element's size will be determined automatically by the layout engine. By explicitly setting them to concrete values, we can have fine-grained control over the dimensions of our element.
These properties can be set independently of each other, e.g.
Additionally, properties like
MaxHeight can be used to constrain an element's size to given minimum or maximum values, respectively.
Many layout properties, like
Y, can be specified by different units. The following units are available in most cases.
- Percent -
Widthof an element 50 percent of its parent width.
- Points (default) -
Widthof an element 50 points. This means that the width will appear the same on all screen densities.
- Pixels -
Widthbe exactly 50 pixels. This means that the width will appear smaller on screens with higher pixel densities.
Panels are used to arrange several elements in relation to each other. All panel types have an associated
Layout object attached to it. The plain
Panel type uses DefaultLayout to lay out its children. It does nothing, other than place them on top of each other in the Z-axis. The StackPanel has an associated StackLayout and places its children in a vertical or horizontal stack. Read more about the StackPanel and other panel types in the upcoming sub sections.
Some panel types, like the Grid and DockPanel needs information per child element in order to lay them out. In these cases, we can use the accompanying attached properties associated with the panel type. Attached properties have the form
ClassName.PropertyName="Value" and are available to all elements. On all unambiguous cases, we can ommit the "Class" part, and just do
PropertyName="Value". In this case, attached properties are syntactically identical to normal properties.
Here are a couple examples:
- Dock - Use the
Dockattached property to specify which side a particular element should be docked to (
- Grid - Use the
Columnattached properties to specify which row and column an element should be placed in.
Here is an example of how it looks in UX:
<Grid ColumnCount="3" RowCount="1"> <Panel Row="0" Column="0" Color="#f00" /> <Panel Row="0" Column="2" Color="#00f" /> </Grid>
Draw order and the ZOffset property
Normally, the order in which elements are drawn depends on their place in the child list. Elements defined further up in the document are drawn on top of elements defined further down. In the following case, The red rectangle will be drawn on top of the green circle.
<Panel> <Rectangle Color="Red" Margin="100" /> <Circle Color="Green" /> </Panel>
To take control over this behavior, we can use the ZOffset property. This property is a float value with a default of 0.0. The higher it is the higher on top the element will be drawn.
<Panel> <Rectangle Color="Red" ZOffset="0.0" Margin="100" /> <Circle Color="Green" ZOffset="1.0" /> </Panel>