Only this pageAll pages
Powered by GitBook
Couldn't generate the PDF for 283 pages, generation stopped at 100.
Extend with 50 more pages.
1 of 100

Gum

Gum Tool

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Intro Tutorials

Introduction

The tutorials contained within this section provide an introduction to working with the Gum UI tool. This tutorial is a great place to start whether you are an artist who will be creating screens and components in Gum, or if you are a programmer who will be integrating Gum into your game or application.

If you are using Gum in a game project, you may want to continue reading other sections after you finish these tutorials.

Tutorials and Examples

Animation Tutorials

Examples

4 - Combining Multiple Categories

Animation keyframes are defined by creating states in categories. If an animation uses two states in the same category then the animation will tween between them

Introduction

Gum is the best Game UI Layout tool available. It provides a flexible, efficient layout engine capable of producing virtually any layout. Gum can be used in a variety of contexts including in the FlatRedBall game engine, MonoGame, Meadow, and more. Gum can also be rendered on Skia so it can be used in any environment that supports Skia such as WPF, Silk.NET, and Avalonia.

The Gum layout engine can also be included in any .NET project without requiring the use of a particular graphical API.

Powerful WYSIWYG Editor

Gum UI includes advanced layout functionality to create and preview your UI

Gum UI

Object Oriented Design Focused on Reusable Controls

Gum allows the creation of components which can be instanced and customized in screens and other components

Gum Components

Gum Objects Support Multiple Size and Position Units

Adjust an object’s origin, position units, size units, and stacking to create fluid UI

Position and Size Units

Simple Integration with any FlatRedBall or MonoGame Project

Grab the NuGet, add a few lines of code, see your Gum project in game!

Gum UI in game

Interact with Gum in Code

Gum objects can be created and modified in code. Create fully-featured UI by subscribing to common UI events.

Working with Gum in Code

Time-Tested and Reliable

Gum has been used in commercial projects of all sizes - check them out in our Showcase page.

Need Help?

Gum is actively maintained and provides lots of ways to get answers:

  • Check the rest of the documentation here

  • Join the Discord chat (shared discord with FlatRedBall)

  • Create an issue on Github

5 - Exposing Variables

Introduction

The ability to expose variables in Gum makes components flexible. For this example we will continue the Button example from the last tutorial.

Recap

The last tutorial created a Button component with Text and ColoredRectangle instances. The instances were set up to be positioned correctly according to the size of the button.

We then created a MainMenu screen and added a few instances of the Button component to the MainMenu screen.

While the size and positioning functionality in our button works well, the Text itself always says "Hello".

Exposing the Text variable

By default a Button only exposes its top level variables. Variables on instances inside the button are not available outside of the button. In programming terms these variables are considered protected.

However, we can expose variables on instances so that they can be modified in our MainMenu screen.

To do this:

  1. Select TextInstance under Button

  2. Find the Text variable in the Variables tab (Second column, under the "States" panel)

  3. Right-click on the text box and select Expose Variable

  4. Enter the name "Text" for the variable name

You can verify that the Text variable is exposed by clicking on the the Button component and seeing the Text variable under the Exposed category:

Setting instance variables

Now that the Text variable is an exposed variable, it can be changed on each Button instance. To do this:

  1. Select one of the Buttons in MainMenu

  2. Change its Text to "Button 1"

Feel free to set different Text values on all of the buttons. Notice that the Text may word-wrap.

Conclusion

This tutorial shows how to expose Text values per-instance. You can expose other instance variables in your components to customize instances. Other examples of variables which may be exposed include:

  • Visibility of icons on a Button component

  • Font sizes on a Label component

  • Sprite visibility showing the number of connected gamepads on a JoinGame component

  • Width (percentage) on a HealthBar component

It's best to experiment with exposed variables to get a feel for how you can use them in your own components.

1 - Introduction to Animation

Introduction

Gum supports creating and previewing animations in the editor through the use of states. The general workflow for creating an animation is as follows:

  1. Create states representing the keyframes in the animation (usually one category per animation)

  2. Add an animation to the component or screen

  3. Add states to the animation and adjust their time

  4. Set interpolation values for each keyframe to control "easing"

Examples of animations

Gum's animation system is very powerful and can be used in a variety of situations:

  • Animations which play when a screen or component is shown or hidden

  • Animations used to transition between behavior states such as changing a button from regular to highlighted state

  • Lengthy animations which can last multiple seconds for complex transitions

Storage of animations

Animations are stored separate from the screen or component on the file system. If a screen or component contains at least one animation then Gum will save a Gum Animation XML file (.ganx extension) with the word "Animations" appended on the screen or component's name. In other words GameScreen would have a file called GameScreenAnimations.ganx in the same folder containing information about its animations.

Playing animations

Once an animation has been made it can be played back in editor. The following shows how an animation is played back, both in real time and also by dragging the slider.

Showcase

Right-click to expose a variable
Text variable is exposed
Text values set per button instance
Deadvivors
Deadvivors
Cranky Chibi Cthulhu
Cranky Chibi Cthulhu
TerraScriber
TerraScriber
Champions of Anteria
Champions of Anteria
Tetris Blitz
Tetris Blitz
Tula Mobile App
Tula Mobile App
Catnip Coast
War Haven
War Haven
BattleCrypt Bombers
BattleCrypt Bombers
Teotihuacan
Ship Skwabble

Gum Elements

Running from Source

Introduction

Gum is an open source project so you can run it from source instead of running the pre-compiled project. Running from source is not a requirement, and is only needed if you intend to contribute to Gum or if you'd like to diagnose problems in a debugger.

Obtaining the source code

  1. Download the source file from GitHub

    1. If you downloaded the .zip file from the GitHub main page, unzip the file

    2. If you downloaded the file through a Git client, be sure to be on the master branch

Gum repository in Github Desktop

Running the code

  1. Locate the Gum.sln file

    1. If you downloaded the .zip, it is in the root folder of the zip

    2. If you cloned the repository, it is at the root of the Gum folder

  2. Double-click it to open Visual Studio, or open Visual Studio and load the .sln

  3. Run the build configuration in "x86". The build configuration may default to "Mixed Platforms". If you do not change it Gum will not compile.

  4. Be sure to build solution rather than pressing F5 (which only builds the current project). This guarantees that all plugins are built and copied correctly. For more information see below.

Building Plugins

Gum depends on a number of plugins for its functionality. By default if you build the project and run it (such as by pressing F5 in Visual Studio), then plugins are not automatically built. To build plugins, you need to explicitly build all plugin projects. The easiest way to do this is to select the Build -> Rebuild Solution option in Visual Studio.

Build -> Rebuild Solution in Visual Studio

3 - Files

Introduction

Gum supports loading image files for Sprites and NineSlices. This tutorial discusses how to load files, and how they are referenced in Gum.

Setting up a workspace

First we'll set up a workspace:

  1. Create a Screen called SpriteScreen.

  2. Drag+drop a Sprite into the newly-created Screen

Drag+drop a Sprite onto SpriteScreen

Setting the Sprite Source File

The Source File property is the image that the Sprite displays. Usually Source Files are of the .png file format. To set the source file:

  1. Select SpriteInstance

  2. Find Source File in the Variables tab

  3. Click the "..." button to bring up a file window

  4. Navigate to the location of the file you would like to load

  5. Click "Open" in the file window

  6. Once Source File is set, the Sprite displays the image in the Editor tab

SpriteInstance displaying a bear Source File

If you select a file which is not located in the same folder or a sub folder of your gum project, Gum asks if you would like to reference the file in its original location or create a copy.

Gum asks to copy files if they are outside of the project directory

Usually it's best to copy the file to the Gum project folder so that the Gum project can be moved to different computers without breaking file references.

Texture Coordinates

Sprites can display portions of their Source File. Files which combine multiple images are often called sprite sheets or tile sheets, and are commonly used in game development to keep art organized and to improve performance.

For example, the following file contains images for an animated character, ground tiles, and other entities for a platformer game.

If we download this file and set it as our , then the sprite displays the entire file.

Sprite displaying entire sprite sheet

We can display a portion of the Sprite rather than the entire file:

  1. Click on the Texture Coordinates tab

  2. Check the Snap to grid option to make it easier to select a region

  3. Double-click anywhere on the image to select a region around the cursor

  4. Move the selected region to the desired location to adjust the sprite's texture coordinate values

Texture coordinate values can be adjusted in the Texture Coordinates tab

2 - Creating an Animation

Introduction

This article shows how to create an animated component. It will contain an animation which can be used when the component first appears.

Creating the Component

First we'll create a component which will be animated. To do this:

  1. Right-click on Components

  2. Select Add Component

  3. Enter the name TextComponent and click OK

  4. Drag+drop the Text Standard into the TextComponent to create a Text instance

  5. Select the Alignment tab and click the middle button to have the TextInstance fill the TextComponent

Creating the States

Now that we have a component we'll add the states needed for animation. We'll add all states in a category called HideShow. Animation states should always be categorized. To create the states:

  1. Right click in the States list box

  2. Select Add Category

  3. Enter the name HideShow

  4. Right-click on the HideShow folder

  5. Select Add State

  6. Enter the name Hidden and click OK

  7. Right-click on the HideShow folder

  8. Select Add State

  9. Select Shown

Setting values in the states

Now that we have the states defined we can set values for the states. In this case the only thing we'll be modifying is the TextInstance's Font Scale value. To do this:

  1. Select TextInstance

  2. Select the Hidden state

  3. Set the Font Scale to 0. This makes the Text so small that it's invisible

  4. Select the Shown state

  5. Verify the Font Scale is 1, or set it to 1 if not. This makes the Text regular size

Creating the Show animation

The two states we created above will be used as the keyframes for our animation. The animation will begin in the Hidden state then interpolate to the Shown state. To add this animation:

  1. Verify that TextComponent or any objects under it are selected

  2. Select View -> View Animations

  3. The Animations tab appears in the bottom right

  4. Click the Add Animation button

  5. Name the animation Show and click OK

  6. Select the Show animation and click Add State

  7. Select the Hidden state and click OK - this is the first keyframe in our animation

  8. Click Add State again

  9. Select Shown and click OK

The animation can now be played or previewed:

Adjusting Interpolation Type

The Interpolation Type value sets how one keyframe blends to another. By default keyframes use Linear interpolation, which is a constant change from one state to another. When interpolating from one keyframe to another, the first keframe defines the interpolation type. In our case the Hidden frame defines the interpolation type. We can change the Interpolation Type and preview the animation:

  1. Select the Hidden keyframe

  2. Change Interpolation Type to Elastic

Playing the animation will reflect these changes.

2 - Variables Tab

Introduction

The Gum Variables tab displays all available variables when editing an instance or element. While the Editor tab is handy for quick edits such as positioning and resizing instances, the Variables tab exposes all variables. It is also useful for making fine changes to instances, such as by moving an instance by a single pixel.

The Variables tab shows variables for the selected instance or element.

Editing Variables

Variables can be edited by changing values on the selected variable. For example, to move the text to the right, change its X value to a positive number. Press Enter or Tab to apply the changes:

Positioning Instances

Gum provides a flexible positioning system. The position of an element is a result of a number of variables. We'll go over a few here.

By default all instances are positioned by their top-left corner. For example, setting the Text instance's X and Y to 0 aligned its top-left position to the top-left of the screen (which is identified by a dotted line.

We can change the origin of the Text object by setting its X Origin and Y Origin values. Notice that if X Origin is set to Center then the Text object is positioned by its center:

You may need to pan the view in the Editor tab to be able to see the Text object. Gum provides multiple ways to pan the view:

  • Press and hold the middle mouse button while the cursor is over the preview window. While the middle mouse button is down, move the mouse cursor.

  • Use the scroll bars on the bottom and side of the view

  • Hold down CTRL and press the arrow keys

Changing the X Origin value changes the origin of the selected instance; however, it is still positioned relative to the top-left corner of the Text instance's container - which in this case is the entire screen designated by the dotted outline rectangle.

We can change the origin that the Text is relative to by changing the X Units. By default the X Units variable is set to Pixels From Left and Y Units is set to Pixels From Top.

Changing the X Units to Pixels From Right causes the Text to be positioned on the right-side of the screen.

Text Alignment

The X,Y, Origin, and Units values are all available for every type of element in Gum; however, these values only change the bounds. In the case of a Text object we may be interested in how the text is aligned within the bounds. The Text object offers two variables for aligning its text: Horizontal Alignment and Vertical Alignment. Changing the Horizontal Alignment to Center centers the Text within its bounds:

Default and overriding values

You may have noticed that some variables in the Variables tab have a green background while others have a white background. For example, in the image above the TextInstance's Vertical Alignment is green. This is because instances are not required to define values for every variable. Whenever an instance does not set a variable value, it uses the value that is defined in the Standard Element definition.

To see in action, select the Text item under the Standard folder. Notice that all values have a white background. Keep in mind the the default values for Horizontal Alignment and Vertical Alignment:

If the default Horizontal Alignment and Vertical Alignment values are changed, the changes will immediately be reflected in the preview window for the default Text configuration:

Now if we select the TextIntance we will see that the Vertical Alignment is using the Bottom value; however the Horizontal Alignment is still using Center - this is because a value that is explicitly set on an instance will always override the default value set in the Standard element. Notice that Horizontal Alignment has a white background (indicating a custom value) and Vertical Alignment has a green background (indicating a default value).

Values can be reverted back to their default simply by right-clicking on the variable name in the Variables tab and selecting Make Default

6 - Parent

Introduction

The Components tutorial shows how Text and ColoredRectangle instances can be sized and positioned according to the Button that they are a part of. Instances can use other instances as their parents. Gum does not place a limit to the depth of the parent/child hierarchy, enabling flexible and responsive layouts through.

Parent/child relationships are useful for

  • Automatically adjusting margins and backgrounds

  • Word-wrapping text relative to a parent

  • Stacking objects on top of each other or side by side

  • Placing objects next to other objects which are dynamically sized

  • Creating tables and other complicated layout objects

Creating a Component

For this example we'll create a Component for displaying distance. This component has two Text instances:

  • ValueText - the Text instance responsible for displaying the value for the distance. For example "100".

  • UnitsDisplay - the Text instance responsible for displaying the units for the distance. For example "km" for kilometers.

The two Text instances will have different colors so that ValueText stands out.

A single Text instance can support inline styling. We use two text instances here to show how to work with the Parent variable, but for more info see the page.

To create our component:

  1. Create a new component named MeasurementDisplay

  2. Drop two Text objects in the newly-created component

  3. Name the first ValueText

  4. Name the second UnitsDisplay

Positioning according to a parent

Next we'll make the UnitsDisplay use the ValueText as its parent:

  1. Select the UnitsDisplay Text instance

  2. Change its Parent to ValueText

  3. Change its X Units to Pixels From Right. This makes the text object positioned according to its parent's right edge

  4. Change its X to 10 . This means the UnitsDisplay text is 10 units offset from the right edge of its parent ValueText

  5. Verify its Y is 0

The ValueText actual width should be based on its contents, so we'll do the following:

  1. Select ValueText

  2. Change Width Units to Relative to Children

  3. Change Width to 0

By setting these values, ValueText is now sized according to its children, which in this case are its letters.

You may have noticed that UnitsDisplay is also a child of the ValueText. However, since UnitsDisplay is explicitly positioned outside of the bounds of its parent ValueText, then ValueText ignores this child when calculating its own Width. For a detailed discussion of Width Units and whether children are ignored, see the page.

Adjusting Colors

Now that we have adjusted the position, size, and parent values on our Text instances, let's modify the color of the UnitsDisplay:

  1. Select the UnitsDisplay

  2. Change Red to 200

  3. Change Green to 150

  4. Change Blue to 0

Changing ValueText

Now that we have set up a parent/child relationship between ValueText and UnitsDisplay, UnitsDisplay automatically adjusts its position in response to changes in ValueText. Any change on ValueText resulting in the right-side of the parent changing automatically adjusts the position of UnitsDisplay.

For example, if we change the Text property on ValueText, it grows or shrinks in response.

Width and Effective Width

As mentioned above, changing the Text property causes ValueText to grow or shrink. However, regardless of its size, the Width property is still set to 0.

The Width variable is used in combination with its Width Units to calculate an effective width. In this case, the effective width is determined by the Text property on ValueText. It's important to note that all Gum objects have effective values for x, y, width, and height, all of which are determined by their respective units values.

Children always depend on their parents' effective values rather than their explicitly set values. Gum helps us visualize the effective values when we mouse over one of the resize handles on the selected object. For example, the following image shows the Width, Width Units, and effective width values of our ValueText.

Locked

Introduction

The Locked property controls whether an instance can be clicked in the preview window. If this value is true, then the instance cannot be clicked on directly, but must instead be selected through the Project tab.

The behavior of the Locked property will change in future versions of Gum as defined in this issue:

Once a locked object is selected it can still be edited normally, both in the Variables tab and in the Editor tab. Locking an instance prevents accidental selection in the Editor tab.

The Locked property does not have any impact on the behavior of Gum objects at runtime, such as when running in FlatRedBall or MonoGame. This property only affects editor behavior.

Max Width

Introduction

The Max Width variable sets the maximum width in pixels. The value is applied after all other layout so it can be used to overwrite automatically-assigned width.

By default this value is <NULL> which means there is no Max Width.

If Max Width is assigned (not <NULL>), then the effective width cannot be larger than the Max Width value. The following animation shows that width is limited to a Max Width of 100.

Notice that the Width variable can still be set to a value larger than Max Width, but it does not apply visually.

Max Width can also be used if Width Units is set to values other than Absolute. For example, Max Width can be used to limit the width of a ColoredRectangle when Width Units is Relative to Parent.

Variables tab in Gum
Changing a Text's X variable
Setting X and Y to 0 positions the instance at the top-left of the screen
Text with X Origin set to Center
Default X Units
Text moved to the right-side of the screen by changing its X Units
Centered text in its bounds
Default values for Text Standard Element
Changed values update immediately in the Editor tab
Default values are green, explicitly set values are white
Right-click Make Default option
Text property
Width Units
MeasurementDisplay component
UnitsDisplay positioned relative to the right-side of ValueText
Width and Width Units set to size ValueText according to its contained Text variable
Text with changed color values
Changing the Text property results in ValueText changing its effective width
Width is 0 despite the size being larger than 0
Width is 0, Width Units is Relative To Children, effective width is 65
https://github.com/vchelaru/Gum/issues/273
Locked instances cannot be selected by clicking on them in the editor window
A ColoredRectangle with no Max Width
Max Width set to 100 limits the ColoredRectangle's width
ColoredRectangle's width limited by its Max Width of 100

General Properties

Introduction

General properties are shared by all Standard Elements and Components.

Component

Components are reusable collections of instances. Components can be added in the project's Components folder. Examples of Components include:

  • Button

  • HealthBar

  • Slider

  • Menu

Components can be small and reusable, such as a Label, or they can be large complex objects such as a settings menu with dozens of options.

Component instances can be added to other Components or to Screens.

Has Events

Introduction

The Has Events variable controls whether the selected instance supports UI-related events at runtime such as responding to a cursor click. If this value is false then events are not raised for this instance. If true, then cursor events are raised for this instance.

Usually instances of components should have this value set to true if the component can be interacted with at runtime, such as a button or text box.

This value has no affect in the Gum tool and is only used at runtime.

Has Events and Cursor.WindowOver

If an instance has its Has Events value unchecked then it will not be eligible to be assigned to the Cursor's WindowOver property. For more information, see the Cursor page.

Blend

Introduction

The Blend variable controls how the selected instance combines its colors with whatever is drawn before. The final appearance of a NineSlice depends on its Blend, Alpha, Source File, and Color values.

For more information and examples, see the Sprite Blend page.

Y

7 - States

Introduction

States allow you to set multiple variables at one time. Examples of states might include:

  • A button with Regular, Highlighted, Pressed, and Disabled states

  • A game logo in Large and Small modes

  • A game HUD which can appear on and off screen

Prerequisites

This tutorial builds upon the previous tutorial where a Button component was created. If you haven't yet, you should read through the earlier tutorials to create a Button component.

Defining States

First we'll define two new states. All components and screens have a Default state automatically. This Default state is uncategorized, but all other states must be in a category. Therefore, we'll first add a new category:

  1. Right-click in the States tab

  2. Select Add Category

    Add Category right-click option
  3. Enter the name ButtonStateCategory

To add a new state:

  1. Right-click on ButtonStateCategory

  2. Select Add State

    Add State right-click option
  3. Enter the name "Highlighted"

  4. Click OK

Enter the new state name

The Button component now has a new state called Highlighted:

Highlighted state

Setting Variables in States

Once a state is defined and selected, setting a variable associates that variable with the selected state. In other words, any variable that is set when the Highlighted state is selected results in that variable being added to that state.

For this example, we can make the button become a lighter blue when highlighted. To do this:

  1. Verify the Highlighted state is selected

  2. Select the ColoredRectangleInstance

  3. Set the Green and Red values to 100

Notice that the Green and Red values are rendered with a white background rather than green - indicating that they are explicitly set in the Highlight state.

Red and Green Variables in Highlighted State

Be careful when editing objects with multiple states. You may end up making changes without realizing that you are doing so in the wrong state.

Whenever you have a non-Default state selected, Gum displays a label telling you which state you are editing.

Switching Between States

The values that have just been set apply only to the state that was selected when the changes were made - the Highlight state. This means that clicking on the Default state switches the button back to the default colors. By clicking on the states in Gum you can preview and edit states easily.

Changing states updates the Editor and Variables tabs to show the selected state

Category Variables

Whenever a state in a category sets a variable, that variable is set across all states in that category. So far this tutorial only created a single state called Highlighted, but if additional states are set, all will explicitly set the Red and Green variables. This topic is covered in more detail in the next tutorial.

Setup

Gum Application (binaries):

  • Latest release direct link: files.flatredball.com/content/Tools/Gum/Gum.zip

  • Release history (including older releases): https://github.com/vchelaru/Gum/releases

Gum Source Code: https://www.github.com/vchelaru/Gum

Windows

Download and unzip the .zip file and run the Gum.exe file which is located in Data/Debug/.

Since Gum is a prebuilt file in a .zip, Windows blocks the file which results in the "Windows protected your PC" popup:

Windows protected your PC popup

You can click More info, then Run anyway. Alternatively, you can right-click on the .zip file and select the option to unblock:

Unblocking the .zip file removes the "Windows protected your PC" popup

MacOS

Prerequisites

Before proceeding, ensure that you have the following prerequisites installed on your system:

  1. Homebrew

  2. WINE

  3. Winetricks

Install Homebrew

Homebrew is a package manager for macOS. If you haven't installed Homebrew yet, you can install it by following the instructions on the official Homebrew website.

Install WINE and Winetricks

You can install WINE and Winetricks using Homebrew. Open a terminal and run the following commands:

brew install --cask --no-quarantine wine-stable
brew install winetricks

Automated Setup MacOS

The following goes through the steps do download and run the setup_gum_mac.sh automation script. This script goes through the steps for you with minimal interaction to setup your environment on macOS to run the GUM tool using WINE. If you would prefer to do this setup manually, please see the Manual Setup Steps section below.

  1. Download the setup_gum.mac.sh script https://raw.githubusercontent.com/vchelaru/Gum/master/setup_gum_mac.sh

  2. Open a terminal and cd to the directory that the script was downloaded to

  3. Make the script executable

chmod +x ./setup_gum_mac.sh
  1. Execute the script

./setup_gum.mac.sh

Linux

Prerequisites

You will need these following prerequisites installed on your system, you can run the automated install script to have them installed automatically or you can install them yourself manually if you run into issues (see Manual Setup Steps section):

  1. WINE

  2. Winetricks

Automated Setup Linux

These following commands will go through the steps of downloading and running the setup_gum_linux.sh script. This script goes through the steps for you with minimal interaction required to setup your Linux environment to run the GUM tool using WINE. If you would prefer to do this setup manually, please refer to the Manual Setup Steps section below.

  1. Download the setup_gum.linux.sh script https://raw.githubusercontent.com/vchelaru/Gum/master/setup_gum_linux.sh

  2. Open a terminal and cd to the directory that the script was downloaded to

  3. Make the script executable

chmod +x ./setup_gum_linux.sh
  1. Execute the script

./setup_gum_linux.sh

Install WINE and Winetricks Manually

If the auto script fails to install the prerequisites try this.

You can install WINE and Winetricks using your package manager. Open a terminal and run the following commands:

If your distro is not listed bellow please use your prefered search engine to find out how to install wine and winetricks properly on your system.

Ubuntu 22.04

sudo dpkg --add-architecture i386 
sudo mkdir -pm755 /etc/apt/keyrings
wget -O - https://dl.winehq.org/wine-builds/winehq.key | sudo gpg --dearmor -o /etc/apt/keyrings/winehq-archive.key -
sudo wget -NP /etc/apt/sources.list.d/ https://dl.winehq.org/wine-builds/ubuntu/dists/jammy/winehq-jammy.sources
sudo apt update && sudo apt install --install-recommends winehq-stable
sudo apt-get -y install winetricks

Ubuntu 24.04

sudo dpkg --add-architecture i386 
sudo mkdir -pm755 /etc/apt/keyrings
wget -O - https://dl.winehq.org/wine-builds/winehq.key | sudo gpg --dearmor -o /etc/apt/keyrings/winehq-archive.key -
sudo wget -NP /etc/apt/sources.list.d/ https://dl.winehq.org/wine-builds/ubuntu/dists/noble/winehq-noble.sources
sudo apt update && sudo apt install --install-recommends winehq-stable
sudo apt-get -y install winetricks

Fedora & Nobara (All Versions)

sudo dnf install wine
sudo dnf install winetricks

Linux Mint 20

sudo apt install dirmngr ca-certificates software-properties-common apt-transport-https curl -y
sudo dpkg --add-architecture i386
curl -s https://dl.winehq.org/wine-builds/winehq.key | sudo gpg --dearmor | sudo tee /usr/share/keyrings/winehq.gpg > /dev/null
echo deb [signed-by=/usr/share/keyrings/winehq.gpg] http://dl.winehq.org/wine-builds/ubuntu/ focal main | sudo tee /etc/apt/sources.list.d/winehq.list
sudo apt-get install winetricks

Linux Mint 21

sudo apt install dirmngr ca-certificates software-properties-common apt-transport-https curl -y
sudo dpkg --add-architecture i386
curl -s https://dl.winehq.org/wine-builds/winehq.key | sudo gpg --dearmor | sudo tee /usr/share/keyrings/winehq.gpg > /dev/null
echo deb [signed-by=/usr/share/keyrings/winehq.gpg] http://dl.winehq.org/wine-builds/ubuntu/ jammy main | sudo tee /etc/apt/sources.list.d/winehq.list
sudo apt-get install winetricks

Linux Mint 22

sudo apt install dirmngr ca-certificates software-properties-common apt-transport-https curl -y
sudo dpkg --add-architecture i386
curl -s https://dl.winehq.org/wine-builds/winehq.key | sudo gpg --dearmor | sudo tee /usr/share/keyrings/winehq.gpg > /dev/null
echo deb [signed-by=/usr/share/keyrings/winehq.gpg] http://dl.winehq.org/wine-builds/ubuntu/ noble main | sudo tee /etc/apt/sources.list.d/winehq.list
sudo apt-get install winetricks

Manual Setup Steps

These following commands will go through the steps setting up your macOS or Linux environment to run the GUM tool using WINE.

  1. Open a new terminal

  2. Install .NET Framework 4.8 using winetricks with the following command:

winetricks dotnet48

This command initiates the installation of .NET Framework 4.8. A total of two installer dialogs appear one after another. Follow the steps for both to complete the installation. This process may take a several minutes, so please be patient.

  1. Download the XNA 4.0 Redistributable MSI file from Microsoft. You can download it using the following command:

curl -O https://download.microsoft.com/download/A/C/2/AC2C903B-E6E8-42C2-9FD7-BEBAC362A930/xnafx40_redist.msi
  1. After downloading the MSI file, install it using the following command:

wine msiexec /i xnafx40_redist.msi

Follow the installation prompts. At the end of the installation, it may display an error related to launching DirectX. This is normal; just click "Close" on the error dialog.

  1. Download the Gum Tool ZIP file from the FlatRedBall website and save it to your preferred location. You can download it using the following command:

curl -o Gum.zip https://files.flatredball.com/content/Tools/Gum/Gum.zip
  1. Unzip the downloaded Gum Tool ZIP file into the Program Files directory of the WINE folder. Run the following command in the terminal:

unzip Gum.zip -d ~/.wine/drive_c/Program\ Files/Gum
  1. After unzipping the Gum Tool, remove the downloaded ZIP file using the following command:

rm -f Gum.zip
  1. Create a script to run the Gum Tool. Run the following command in the terminal:

echo '#!/bin/bash
wine ~/.wine/drive_c/Program\\ Files/Gum/Data/Gum.exe' > ~/bin/Gum
  1. Make the script executable by running:

chmod +x ~/bin/gum
  1. To ensure you can run the Gum Tool from any directory, add the script directory to your PATH. Most Linux and macOS users using macOS 10.14 or lower, will be using the BASH shell. While for most macOS user using macOS 10.15 or higher, you'll be using the ZSH shell.

For Bash SHELL

if ! grep -q 'export PATH="\$HOME/bin:\$PATH"' ~/.bash_profile 2>/dev/null; then
    echo 'export PATH="$HOME/bin:$PATH"' >> ~/.bash_profile
fi

For ZSH Shell

if ! grep -q 'export PATH="\$HOME/bin:\$PATH"' ~/.zshrc 2>/dev/null; then
    echo 'export PATH="$HOME/bin:$PATH"' >> ~/.zshrc
fi
  1. Reload the shell configuration to apply the changes. Run the following command:

For BASH Shell

source ~/.bash_profile

For ZSH Shell

source ~/.zshrc

Running the Gum Tool

Congratulations! You have now successfully set up the Gum Tool on macOS using WINE. You can open the Gum Tool by simply typing the following command in the terminal:

gum

If the command doesn't work immediately, try closing and reopening the terminal.

Centering

Introduction

Gum provides simple controls for centering objects inside of their parents. This page shows how to center objects in a variety of situations. For brevity this document uses vertical centering, but the same concepts apply to horizontal centering.

Centering with Anchors (Alignment Tab)

The easiest way to center an object is to use the center Anchor. This sets all of the values necessary to center an object both vertically and horizontally.

Centering using the alignment tab

Centering Using Units

Objects can be centered by setting their unit and numerical values. The Alignment tab is a shortcut for these values, but we can assign each value individually so an object is centered vertically:

  • Set Y to 0

  • Set Y Units to Pixels from Center

  • Set Y Origin to Center

Centering using Y, Y Units, and Y Origin

Centering with Margins

Centering can be performed with margins by adding an additional container to create the necessary margins. For example, consider a situation where we want to center the green rectangle inside the blue rectangle, but leave a 32 pixel margin at the top.

We may want something similar to the following image:

Green rectangle is centered in the remaining area below the yellow area

To do this, an additional container can be added as shown in the following image:

Container inside the blue rectangle defining the centering space

In this case, the container has the following relevant properties:

  • Y = 0 (so it is pressed against the bottom)

  • Y Units = Pixels From Bottom (so it is bottom justified)

  • Height = -32 (leaving a 32 pixel margin)

  • Height Units = Relative to Parent (so that it always has a 32 pixel margin regardless of parent size)

The green rectangle can be added as a child to the container, and then centered within the container. This results in the green rectangle always being centered within the area that leaves a 32 pixel margin at the top even if the main rectangle is resized, as shown in the following animation:

Blue rectangle resized, keeping the green rectangle centered within the area leaving a 32 pixel margin at the top

Additional margin can also be added to the bottom by changing the container's Y value. For example, a 20 margin border can be added at the bottom, leaving a 32 pixel margin at the top by setting the following values on the container:

  • Y = -20 (move the bottom of the container up by 20 pixels)

  • Height = -52 (leaving a 32 pixel margin at the top, and accounting for the container being moved up an extra 20 pixels)

Centering leaving an extra margin on both top and bottom

Center Stacks

Stacks can be centered horizontally or vertically. To center a stack of objects, an internal container is needed.

A centered stack might look like this:

Centered stacking ColoredRectangles

For this example, we'll begin with a Container and a background ColoredRectangle. The background is not necessary, but it helps visualize the main Container's size.

MainContainer with a blue ColoredRectangle background

Next we'll add another container which will hold our stacking instances.

  1. Drag+drop a container onto the MainContainer

  2. Click the Alignment tab

  3. Click Anchor Center

New inner container centered

We can add children to the container:

  1. Set the inner container's Children Layout to Top to Bottom Stack

  2. Drag+drop children onto the inner container to have them stack

  3. Optionally adjust the Stack Spacing variable to add gaps between the children

  4. Optionally adjust the children such as changing their size or color

Add childre nto the stack

For this example I modified each child rectangle to have

  • Width = 128

  • Height = 32

  • Color = Green

Adjusted rectangle sizes and colors

Finally, we mark the inner container to be sized according to its children. Since it remains centered, whenever its size adjusts (by adding or removing children), the inner container adjusts to remain centered.

Set the inner container to Size to Children

Now if children are added or removed, the container remains centered.

Inner container expanding in response to new children

3 - Playing Animations inside other Animations

Introduction

Gum supports creating animations which can play other animations. This is especially useful when creating animations in Screens that contain components which themselves have animations. This tutorial will build upon the previous tutorial where we created an animated component called TextComponent.

Creating a Screen

First we'll create a Screen called AnimatedScreen. To do this:

  1. Right-click on Screens

  2. Select "Add Screen"

  3. Enter the name "AnimatedScreen" and click the OK button

  4. Drag+drop a few TextComponents into the Screen and spread them out visually

Defining the initial state

The animation we will be creating in our Screen will start with all TextComponents being invisible, then each one appearing by playing their Show animation. The animations will be slightly staggered. First we'll add the initial state where all of the TextComponents are invisible. To do this:

  1. Verify that the AnimatedScreen is selected

  2. Right-click in the states area and select "Add Category" name it "ScreenCategory"

  3. Right-click the category and select "Add State"

  4. Name the state "AllInvisible" and click OK

  5. Click to select the "AllInvisible" state.

  6. Select one of the TextComponents

  7. Set its HideShow State to Hidden

  8. Repeat setting the State to Hidden for the other TextComponents

Creating the Animation

Now we have all of the states and animations that we'll use as keyframes in our animation. To create the animation:

  1. Select AnimatedScreen

  2. Select "View" -> "View Animations"

  3. Click "Add Animation"

  4. Name the animation "ShowAll"

  5. Select the ShowAll animation

  6. Click "Add State"

  7. Select "ScreenCategory/AllInvisible" and click OK

The animation now sets all TextComponents to their Hidden state initially.

Adding Sub-Animations

Next we'll be adding animations to animate the TextComponent instances to visible. To do this:

  1. Bring up the animation window for AnimatedScreen if it is not already showing

  2. Select "ShowAll"

  3. Click "Add Sub-animation"

  4. Select the first TextComponentInstance

  5. Select the Show animation and click OK

  6. Select the newly-created animation and set its Time to 0.5

  7. Repeat the above steps to add animations for the other two TextComponents, but set their times to 1.0 and 1.5

Now the animation can be played or previewed with the slider bar:

Rotation

Introduction

Rotation can be used to rotate Gum components. Rotation is measured in degrees, where positive values rotate an object counterclockwise about its origin (X Origin and Y Origin).

Example

An object is rotated about its origin, which by default is its top-left corner:

Rotating an object using the Rotation variable

Objects can also be rotated visually by grabbing the rotation handle:

Rotation handles can rotate an object

Holding the SHIFT key snaps angles to 15 degree increments.

SHIFT rotate snaps to 15 degree increments

X Origin and Y Origin

The X Origin and Y Origin properties define the point of rotation for an object. The following animation shows how changing origin values can affect rotation.

Objects rotate about their origin.

X Origin

Introduction

The X Origin variable controls the point which an object is positioned by. By default the X Origin is Left. X Origin is shown visually as a white "X" in the editor.

ColoredRectangle with an X Origin of Left

Left

The following image shows a ColoredRectangle with its X Origin set to Left:

Colored Rectangle with X Origin set to Left

Center

The following image shows a ColoredRectangle with its X Origin set to Center:

ColoredRectangle with X Origin set to Center

Right

The following image shows a ColoredRectangle with its X Origin set to Right:

ColoredRectangle with its X Origin set to Right

Order

Introduction

Children in a Screen, Component, or parent instance are drawn top-to-bottom, so that children further down are drawn on top.

Red is the first item drawn, so it is under the other rectangles. Blue is the last, so it appears on top.

Changing Order

Gum provides a number of ways to reorder instances.

Items can be right-clicked in the editor to change their order.

  • Bring to Front - reorders the instance so that it is in front of all of its siblings.

  • Move Forward - moves the instance in front of the sibling that is in front of it. In other words, moves the item forward by one index.

  • Move In Front Of - moves the instance in front of the selected sibling.

  • Move Backward - moves the instance behind the sibling that is currently behind it. In other words, moves the item backwards by one index.

  • Send to Back - reorders the instance so that it is behind all of its siblings.

Right-click options can be used to reorder instances

Items can be re-ordered in the Project tree view by holding the alt key and pressing up or down.

Alt+arrow keys can be used to reorder items

Parent and Children Ordering

Gum uses a hierarchical ordering which means that a parent and all of its children draw before any of the siblings of the parent. For example, a container and all of its children draw before any other siblings of the container.

The following animation shows a container named ContainerInstance2 which draws on top of ContainerInstance1. All children of ContainerInstance2 also draw on top of children of ContainerInstance1.

If a parent draws on top of other instances, then its children also draw on top

If a parent is reordered, then all of its children also respect the new order. For example, if ContainerInstance2 is sent to the back, then all of its children draw below ContainerInstance1 and its children.

If a parent is sent to the back, all children also draw behind other siblings of the parent container.

Order and Stacking / Grid

If a parent uses a stack or grid layout for its Children Layout variable, then the order of the children in the Project tab determines their order in the stack or grid.

For more information, see the Children Layout page.

Thickness

Introduction

Thickness controls the width of the arc line in pixels. This value can be increased to make the line arc thicker.

Changing the thickness chnages the width of the arc's line

Thickness can be increased to create a wedge.

Increasing Thickness to create a wedge

Note that Thickness can be increased to any value including values larger than the radius of the arc. Large values can result in the arc rendering past its center point creating a bowtie shape.

Bowtie created by setting thickness to be larger than the radius of the arc

Other undesirable rendering effects can happen with large thicknesses when working with arcs which have one size (width or height) larger than the other, as shown in the following image:

Arck with the values Width=340, Height=160, Thickness=95 rendering incorrectly

Default Implementation

Introduction

The Default Implementation property can be used to indicate which component is the default implementation for a behavior. This property is not used by the Gum tool, but instead exists for runtime implementations (such as FlatRedBall) to decide which type of component to create when an instance of a behavior is requested.

ListBoxItemBehavior with a Default Implementation set to Controls/ListBoxItem

As of March 2025 this property is used in the following runtimes:

  • FlatRedBall

  • MonoGame/Kni/FNA

Additional runtimes may add support for this property in the future. If you need it for your project please make a request on GitHub or Discord.

Common Usage

Behaviors are often used to help with the creation of components which need to have a certain set of states and instances. For example, the Button type in Gum Forms is associated with the ButtonBehavior.

At runtime, a game may need to create an instance of the Button type without specifying a component. For example, the following code can be used to create a button:

var button = new Button();
button.Text = "Hello";
StackLayoutInstance.AddChild(button);

The Default Implementation property can help runtime libraries determine which component to create for the Button's visual.

The Button type is a good example of why this property might be needed because the default Forms components include multiple components which use ButtonBehavior.

Multiple button components

To resolve this ambiguity, the ButtonBehavior's Default Implementation is automatically set to Controls/ButtonStandard.

ButtonBehavior using ButtonStandard as the Default Implementation

For more information about whether you should set the Default Implementation, refer to the documentation for your particular runtime.

If you have created a custom runtime, such as a new ListBoxItem, you may need to change the Default Implementation for the ListBoxItem behavior.

RoundedRectangle

Introduction

RoundedRectangle is similar to a ColoredRectangle with the added functionality of supporting rounded corners.

Default RoundedRectangle

RoundedRectangles also support Skia properties such as Has Dropshadow, Is Filled, and Use Gradient. For more information and examples, see the Skia Standard Element General Properties pages.

Ignored By Parent Size

Introduction

Ignored By Parent Size determines whether the parent of an instance considers the instance when performing its sizing. This value is only used if the parent has a Height Units or Width Units of Relative To Children. If a parent has a Height Units or Width Units of any other value, then this value has no impact on the parent's size.

Ignored By Parent Size controls whether the parent ignores the child when performing a layout

Color

Introduction

The Color value controls a Text object's color. The Color value is created by combining the Red, Green, and Blue values.

The Color value can be changed through the color picker, or by changing the individual Red, Green, and Blue color values.

Changing the Color values by changing Red, Green, Blue, or using the color picker

Color Multiplication

For default Text objects, the Color value modifies the displayed Text color. Gum creates .fnt and .png files where the color is white. If the .png includes any colors that are not white, then the resulting color is produced by multiplying the color value with each pixel. Therefore, if a Font is outlined, then the black pixels remain black.

Changing the color value of outlines

Texture Left

Introduction

The Texture Left variable controls the left pixel of the source rectangle used to draw the NineSlice. Texture Left is only available if the NineSlice uses a Texture Address of Custom or Dimension Based.

The following image shows a NineSlice with a Texture Left value of 96.

NineSlice with Texture Left set to 96

Texture Left controls the left side of the region that the NineSlice displays on its source file. In this case, the left-edge of the source rectangle is 96 pixels from the left edge of the entire file.

Texture Left set to 96 pixels in the Texture Coordinates tab

Container

Containers are used to group objects to simply movement, alignment, positioning, and size. Containers are usually invisible, although they can draw their outlines in Gum to help visualize their position and size.

A container holding four ColoredRectangle instances

X

Introduction

The X property controls the horizontal position for an object. The X value represents the position of an object's X Origin, using its X Units.

Example

By default, an object's top-left corner is positioned relative to its parent's top-left corner.

Custom NineSlice

Introduction

Although Gum includes a standard NineSlice element, the Gum layout system can be used to create a custom NineSlice component. Such a component could be used if additional flexibility beyond what is provided by the standard NineSlice is needed.

Creating the Component

As implied by the name, the NineSlice element is composed of nine Sprites. First we'll create the component:

  1. Open Gum

  2. Open or create a new Gum project

  3. Right-click on the Components folder

  4. Select Add Component

  5. Name the Component "CustomNineSlice"

Adding Corner Sprites

Next, we'll add corner Sprite instances to our CustomNineSlice. We'll be using the alignment tab to position Sprites. The alignment tab provides a quick way to place objects, but the same could be achieved using the following variables individually:

To create the corner Sprites:

  1. Drag+drop a Sprite element onto the CustomNineSlice component

  1. Click the Alignment tab

  2. Anchor the newly-created Sprite to the top-left of its container

  3. Repeat the steps above three more times, creating one Sprite for each of the four corners, anchoring each one to their respective corner

Notice if we resize our CustomNineSlice component, each of the four Sprites remains in its respective corner.

Adding Edge Sprites

Next we'll add the four Sprites which will sit on the edges of our component:

  1. Drag+drop a Sprite element onto the CustomNineSlice component

  2. Click on the Alignment tab

  3. Dock the newly-created Sprite to the top of its container. Docking sets the width of the sprite to match the width of the component. We'll address this in the next step.

  4. To accommodate for the corner Sprites, we need to adjust the width of the top Sprite. Set the newly-created Sprite's Width to -128. Since the Sprite uses a Width Units of Relative to Parent, setting the value to -128 makes the Sprite 128 units smaller than its parent. We picked 128 because each of the corner sprites is 64.

  5. Repeat the above steps, but instead setting the dock to create sprites on the left, right, and bottom. adjust width and height values as necessary.

Adding the Center Sprite

Finall we'll add the center Sprite:

  1. Drag+drop a Sprite element onto the CustomNineSlice component

  2. Click on the alignment tab

  3. Dock the newly-created Sprite to the center of its container.

  4. Set both the newly created Sprite's Width and Height to -128

Now the Sprites stretch and adjust whenever the CustomNineSlice is resized.

Assigning values on CustomNineSlice

Unlike the regular NineSlice, changing the texture values requires a considerable amount of variable assignment. To change the CustomNineSlice to use 9 separate textures, the following values must be set:

  • Each of the Sprite instances must have its SourceFile value set

  • The edge Sprites will have to have their Width and Height values modified to account for the possible resizing of the corner sprites

  • The center Sprite will have to have both its Width and Height values modified

If using a sprite sheet, then all of the work above will need to be done plus the texture coordinate values will need to be modified.

Clips Children

The Clips Children property controls whether children of a component or container can render outside of the bounds of their parent. By default this is false, which means that all children are not clipped (can fully-render) regardless of whether they are within the bounds of their parent or not. Setting this value to true prevents children from rendering outside of the bounds of their parent.

Children outside of the bounds of a container with Clips Children set to true can also be clipped by setting a container's value to true.

Alpha

Introduction

Alpha controls an instance's transparency. A fully opaque instance has an Alpha of 255. A fully transparent instance has an Alpha of 0.

An object's transparency is a combination of its Alpha, , and its . Skia elements may also have transparent portions due to their shape (such as and ) as well as .

Alpha and Children

By default the Alpha property affects the selected instance only - it does not cascade down to its children. For example, the following shows a parent white ColoredRectangle with a child blue ColoredRectangle. If the white ColoredRectangle's Alpha property changes, the BlueRectangle's opacity does not change.

A parent can affect its children's transparency if the parent is a container with Is Render Target set to true. For example, if the white rectangle is added to a Container, the Container can make its entire contents transparent.

Note that by setting Is Render Target to true, the entire container's Alpha can be adjusted rather rather than the alpha value cascading to each individual child. This Alpha value is used to control transparency after all children have been drawn. We can see the difference between a partially-transparent Container and each child individually being made partially transparent by overlapping two children ColoredRectangles.

The rectangles on the left each have an Alpha value of 255. These rectangles are in a Container Is Render Target set to true and an Alpha set to 128.

The rectangles on the right each have an Alpha of 128, so the red rectangle is visible behind the blue rectangle.

Skia Standard Elements

Introduction

Skia standard elements are a collection of elements which use SkiaSharp for rendering. Skia standard elements provide additional types of visuals supported by Gum, but not all runtimes support Skia standard elements.

Skia adds advanced vector graphics support for shapes such as Arc, ColoredCircle, and RoundedRectangle. Skia also adds support for vector file formats such as SVG and Lottie.

Using Skia Standard Elements may limit which platforms can run your Gum project. For more information, see the page.

Enabling Skia Standard Elements

Skia standard elements must be explicitly added to gum projects. To add Skia standard elements Select Plugins -> Add Skia Standard Elements.

After clicking this option, Gum adds new standard elements.

Once these Skia standard elements are added, they can be added to Screens and Components just like any other standard element.

Visible

Introduction

The Visible variable controls whether an object and its children appear.

Example

Setting Visible to false hides the selected instance.

Parent/Child Visibility

Setting a parent's Visible variable to false also hides all children. Note that this does not explicitly set the Visible property to false for all children, but a child's effective visibility depends on its parent.

Visibility and Stacking

If an instance is part of a parent which stacks its children (has a Children Layout of Left to Right Stack or Top to Bottom Stack), then it will no longer be considered when stacking siblings if it is invisible. In other words, making an item invisible removes it from the stack.

If the stack contains children which use a Width Units of Ratio, then hiding any of the siblings results in the children with ratio width adjusting to occupy the extra space.

Selecting Invisible Objects

An invisible object can be selected by clicking on it in the Project tab or in the Editor tab.

Visible items are given preferential selection even if they are ordered behind invisible items.

Min Width

Introduction

The Min Width variable sets the minimum width in pixels. The value is applied after all other layout so it can be used to overwrite automatically-assigned width.

By default this value is <NULL> which means there is no Min Width.

If Min Width is assigned (not <NULL>), then the effective width cannot be smaller than the Min Width value. The following animation shows that the width is limited to a Min Width of 100.

Notice that the Width variable can still be set to a value smaller than Min Width, but it does not apply visually.

Min Width can also be used if Width Units is set to values other than Absolute. For example, Min Width can be used to limit the width of a ColoredRectangle when Width Units is Relative to Parent.

Padding

Introduction

The concept of padding is often used to add spacing between the edge of a container and its children. Padding can be achieved by adding sub-containers.

Creating a Container

First we'll create a top-level container. This container controls the size of all objects internally, including the background. We will also include a background object which is sized according to the container. To keep things simple, this example uses a dark blue ColoredRectangle.

The ColoredRectangle is set so its size matches its parent.

Next we can add another container to the top-level container. By default this container sits at the top-left of the parent when it is added with a drag+drop.

To have the container fill its parent, but also include padding:

  1. Select the inner container

  2. Click the Alignment tab

  3. Enter the desired padding in the Margin text box

  4. Click the Dock Fill button

This inner container can now be used to hold all children. Note that if you are creating a Component and you want to make this be the default container for children, you may want to set the Default Child Container to this inner container. For more information see the page.

Min Height

Introduction

The Min Height variable sets the minimum height in pixels. This value is applied after all other layout so it can be used to overwrite automatically-assigned height.

By default this value is <NULL> which means there is no Min Height.

If Min Height is assigned (not <NULL>), then the effective height cannot be less than the Min Height value. The following animation shows that height is limited to a Min Height of 100.

Notice that the Height variable can still be set to a value smaller than Min Height, but it does not apply visually.

Min Height can also be used if Height Units is set to values other than Absolute. For example, Min Height can be used to limit the height of a ColoredRectangle when Height Units is Relative to Parent.

ColoredRectangle

Introduction

ColoredRectangles are used to display solid color rectangles. It can be used to provide a solid colored background or placeholders for content such as Sprites. ColoredRectangles are also useful for quickly blocking out a UI or learning about Gum's layout with a visual object.

As the name suggests, ColoredRectangles have a Color property which can be modified.

Blue

The Blue value controls the color of the Text object. The Blue value has a range of 0 - 255. The Blue value combines with the Red and Green values to create the final color.

For more information on working with color, see the .

Custom Frame Texture Coordinate Width

Introduction

The Custom Frame Texture Coordinate Width property allows a NineSlice to customize the number of pixels used on the source texture when defining its outer frame. This allows for fine control over which parts of a NineSlice stretch and which parts are used as the corners and edges.

By default this value is null, which means the NineSlice automatically dedicates 1/3 of the texture for the edges.

Changing Custom Frame Texture Coordinate Width

If the Custom Frame Texture Coordinate Width value is changed, then the source texture applies a fixed pixel size to the borders. For example, using the image above, the frame can be changed to 3 so that only the black and white pixels are part of the border.

X Units

The X Units variable controls how a unit is horizontally positioned relative to its parent. By default an object is positioned relative to the left of its parent, where each unit represents 1 pixel.

Pixels From Left

The following shows a child positioned 50 Pixels From Left relative to its parent:

Pixels From Center

The following shows a child ColoredRectangle positioned 50 Pixels From Center relative to its parent:

Pixels From Right

The following shows a child ColoredRectangle positioned 50 Pixels From Right relative to its Parent:

Percentage Parent Width

The following shows a child ColoredRectangle positioned 50 Percentage Parent Width relative to its Parent. In other words, it will be positioned halfway between the left and right edges of the Parent:

Polygon

Introduction

Polygons are shapes defined by an ordered set of points. Polygons can be used to draw lines, shapes, and define collision in games.

Corner Radius

Introduction

The Corner Radius variable controls the radius of each of the four corners on a rounded rectangle. A value of 0 results in a sharp corner. Increasing this value makes the corners more rounded.

Corner Radius is restricted to half of the smallest absolute dimension. In other words, if the RoundedRectangle is too small to fit its set CornerRadius, then the effective CornerRadius shrinks.

The following shows a RoundedRectangle with a Corner Radius of 60. If it is resized to have an effective width or height of less than 120, then the effective radius shrinks.

Similarly, setting a Corner Radius that is larger than half the Width or Height does not affect the RoundedRectangle.

Sweep Angle

Introduction

Sweep Angle defines the angle that the arc covers. This is a signed value, with positive values going counterclockwise.

The following shows an arc with a positive Sweep Angle of 135 degrees.

Changing the Sweep Angle changes the length of the arc. If the value is negative, then the Sweep Angle increases the size clockwise.

A sweep angle of 360 creates an arc that extends to a full circle. Values greater than 360 appear the same as if Sweep Angle is set to 360.

LottieAnimation

Introduction

LottieAnimation instances can render animations in the . Lottie files are animated files, usually with vector art, which serve as an alternative to gifs. Since they are often vector art, Lottie files can be resized without pixelation.

Lottie files can be downloaded from various sites or created in application such as Adobe After Effects. If you are interested in testing out Lottie animations, you may want to check for sample Lottie files.

The following shows a Lottie animation playing in Gum. Source file:

Source File

The Source File variable controls the lottie animation displayed. This value can be set and changed just like source files on other elements such as a .png on a Sprite.

Lottie Width and Height

Width and Height values can be set on a Lottie file just like any other Gum element. Unlike rasterized objects such as Sprites, LottieAnimations use Vector art so they can be resized and still retain crisp edges and details.

LottieAnimations are still rasterized in Gum, so they display pixels when the view is zoomed in, especially if the LottieAnimation has a small Width or Height.

Text

Introduction

The text object can be used to display written information. The text object supports:

  • Horizontal and Vertical alignment

  • Text wrapping

  • Fonts from the installed font library on your machine

  • Custom fonts using Bitmap Font Generator:

  • Scaling independent of source font

  • BBCode-style inline formatting

Text Wrapping

Texts wrap their contained words based on their dimensions. Whether a text wraps ultimately depends on whether the Text's Width Units is Relative To Children.

The following animation shows text wrapping on a text which is using an Absolute Width Units.

Arc

Introduction

Arcs are curved lines with variable thickness. Arcs can also be used to draw wedges if the line thickness is large enough.

Arc dimensions

Arcs draw inside their bounds, with the edge of the arc touching the bounding rectangle. The thickness of the arc remains consisntent regardless of the bound width and height.

The following shows an arc with a Sweep Angle of 270 degrees, being resized in the Editor tab.

Max Height

Introduction

The Max Height variable sets the maximum height in pixels. This value is applied after all other layout so it can be used to overwrite automatically-assigned height.

By default this value is <NULL> which means there is no Max Height.

If Max Height is assigned (not <NULL>), then the effective height cannot be larger than the Max Height value. The following animation shows that height is limited to a Max Height of 100.

Notice that the Height variable can still be set to a value larger than the Max Height, but it does not apply visually.

Max Height can also be used if Height Units is set to values other than Absolute. For example, Max Height can be used to limit the height of a ColoredRectangle when Height Units is Relative to Parent.

Color page
Is Render Target
Clips Children set to true prevents children from rendering outside of the container's bounds
Blend
Source File
ColoredCircle
RoundedRectangle
dropshadows
Sprites with Alpha of 255, 200, 150, 100, 50, and 0
Parent Alpha does not change child opacity
Entire Container Alpha makes all children transparent
Container Alpha on the left, individual Alpha on the right
SkiaGum Platform Support
Add Skia Standard Elements
Skia standard elements in Gum
Skia standard elements can be added just like any other standard element
Visible property controls whether an instance is hidden or shown
A parent's Visible value controls whether children are visible
Invisible siblings are not considered in stacking
Invisible siblings are not considered when calculating used space for Width Units of Ratio.
Invisible objects can be selected
The visible ColoredRectangle is selected before the invisible container
A ColoredRectangle with no Min Width
Min Width set to 100 limits the ColoredRectangle's width
ColoredRectangle's width limited by its Min Width of 100
Default Child Container
Container with a blue background
Container added with drag+drop
Creating padding by havign an internal continer use Margin of 10
A ColoredRectangle with no Min Height
Min Height set to 100 limits the ColoredRectangle' height
Rectangle's height limited by its Min Height of 100
ColoredRectangle with a green color
ColoredRectangle
Polygon in Gum
Corner radius shrinking in response to smaller size
An arc with a Sweep Angle of 135
Sweep Angle can be positive or negative
Sweep Angle of 360
Lottie format
lottiefiles.com
https://lottiefiles.com/free-animation/city-skyline-HFnJYQZLPP
LottieAnimation in Gum
LottieAnimations can be resized and maintain their crisp visuals
LottieAnimations are still rasterized so zooming in shows pixels
http://www.angelcode.com/products/bmfont/
Resizing a Text causes it to wrap
Three arc instances - a default arc, a rounded arc with gradient graphics, and an arc creating a wedge
Arc thickness remains constant when an arc's dimensions change
A ColoredRectangle with no Max Height
Max Height set to 100 limits the ColoredRectangle's height
Rectangle's height limited by its Max Height of 100

General Properties

Width Units
X Origin
X Units
Height Units
Y Origin
Y Units
Component named CustomNineSlice
Drag+drop a Sprite onto CustomNineSlice
Anchor the Sprite to the top-left of its container
Four sprites in CustomNineSlice
Resized CustomNineSlice keeping its Sprites in the corner
Click the top dock tab
Top Sprite in CustomNineSlice

1 - The Basics

Introduction

This page walks you through the basics of using the Gum UI tool, which we'll refer to simply as Gum for this and all other documentation.

Empty Gum Project

Gum Elements

Gum separates its elements into three categories: Screens, Components, and Standard. Behaviors are an advanced topic that we'll skip for these tutorials.

Screens, Components, and Standard folders

Standard elements represent the building-blocks for screens and components, and all projects use the same set of standard elements. To see the list of elements, expand the Standard tree item. Clicking on any element displays it in the preview window.

A Sprite standard element with no source file set

Sprite element is selected in the image above. Notice that since a SourceFile is not set, the Sprite renders as a red X.

Standard Types

  • Circle - circle outline. These are usually not used for UI, but can be used if you are defining collision in your Gum objects for a game.

  • ColoredRectangle - filled-in rectangle. These are often used for solid-colored backgrounds and frames.

  • Container - invisible object used to contain other objects. These are used to provide margins, change layouts (such as vertical vs horizontal stacking), and to organize your UI.

  • NineSlice - visual object which uses nine sprites to create a resizable object from a source PNG (or portion of a PNG). The corner sprites (4) are not resized. The top, bottom, left, and right sprites are stretched on one axis. The middle sprite stretches both horizontally and vertically. These are used to create resizable frames.

  • Polygon - polygon outline which can have any number of points. These are usually not used for UI, but can be used if you are defining collision in your Gum objects for a game.

  • Rectangle - rectangle outline. These can be used for single-line frames or if you are defining collision in your Gum objects for a game.

  • Sprite - a visual object which displays a source PNG (or a portion of a PNG). These are used for icons, backgrounds, and other visual objects which are usually not resized dynamically.

  • Text - a visual object which can display characters. These are used for any situation where text needs to be displayed such as labels and paragraphs.

Plugins can add additional standard elements. The list above is the default list of standard elements before plugins have made any changes.

Components

Components are objects which can contain standard elements and instances of other components. Components can be very simple, such as a Label, or very complex, such as an options menu with dozens of instances. Items added to components or screens are called instances.

Screens

Screens are objects which can contain standard elements and instances of other components. Unlike Components, Screens cannot be added to other Screens. Screens exist mainly for organization. Screens can be simple, such as a loading screen, or complex such as a HUD in an RTS game.

Components vs. Screens

Components and screens are similar - both can contain instances of standard elements, and both can contain other components. The only difference between screens and components is that screens cannot contain other screens.

For example you can think of screens in a video game which might include a main menu, credits screen, options screen, and level selection screen. You can think of components as elements which are composed of multiple standard elements. Examples include a Button component which is made up of a Sprite instance and a Text instance, or a Logo component which may be made up of multiple Sprites and Text objects.

Creating a Screen

To create a screen:

  1. Right-click on the Screens tree item and select Add Screen

    Right-click, Add Screen option
  2. Enter the name of the new screen - such as MainMenu

  3. Click OK. The newly-created screen is created and selected

    The MainMenu screen in Gum

Adding instances

Instances of standard and component elements can be added to screens and components. To add an instance:

  1. Select the destination screen or component. For example, select the MainMenu screen

  2. Push the left mouse button (but don't release it) on the Text item. If you happen to release the mouse button, this selects the Text item, so you need to re-select the destination (MainMenu).

  3. Drag the Text item onto the Editor tab

  4. Release the mouse button. A new text instance appears in your screen.

    Adding a Text instance to the MainMenu screen in the Editor tab

Alternatively, you can also drag+drop a standard element into a screen in the tree view.

Adding a Text instance to the MainMenu screen in the Project tab

If an element is dropped in the Editor window, it appears at the location where it has been dropped - setting its X and Y values. If an element is dropped in the Project tab, then it preserves its default X and Y values.

Editing in the preview window

Once an instance is a part of a screen or component it can be edited visually in the preview window. The selected instance has eight (8) handles surrounding it. These are called the resize handles and can be used to change the selected instance's width and height.

A selected Text instance with resize handles

In the case of the Text object, the resize handles are used to control how the text object performs line wrapping.

You can use the resize handles to resize the instance, or you can simply push the mouse button and drag inside the instance to change its position. Notice that an object's outline is displayed when the cursor is hovering over the instance.

Moving and resizing a Text object.

Conclusion

This tutorial introduces the basics of working with standard elements and adding them to Screens. The next tutorial covers the Variables tab which can be used to access all element variables.

NineSlice

Introduction

NineSlice is a standard component which can be used to create visual objects which can stretch to any size without creating distortion on the source image. For example, consider the following image:

This image could be used to create nine slices of various sizes without any distortion:

The NineSlice achieves this effect by splitting the texture into nine pieces, and scales each one differently to prevent distortion. Highlighting a nine slice shows how it is split:

This is achieved by splitting the texture into 1/3 sections wide and tall. The following image shows how the original image will be split:

NineSlice Texture

The simplest way to assign a texture to a NineSlice is to use a single file. Setting the SourceFile to a single PNG will result in the NineSlice using that one texture, where each section of the NineSlice displays 1/3 of the width of the file and 1/3 of the height of the file.

A NineSlice's Texture Address property can be used to change the portion of the source texture that it uses. More info can be found in the Texture Address subpage.

Alternatively, nine files can be used to specify each section of the NineSlice independently. To use nine individual files, each file must be given a specific suffix.

The following suffixes can be added to create nine slice graphics. For example, assuming your NineSlice image is called "Image" and you are using the .png file format:

  • Image_BottomCenter.png

  • Image_BottomLeft.png

  • Image_BottomRight.png

  • Image_Center.png

  • Image_Left.png

  • Image_Right.png

  • Image_TopCenter.png

  • Image_TopLeft.png

  • Image_TopRight.png

Stack Spacing

Introduction

The Stack Spacing variable controls the additional padding between children when a container uses a Children Layout of either Top to Bottom Stack or Left to Right Stack. Stack Spacing serves as an alternative to adjusting the position of each item in a stack.

Setting Stack Spacing

A larger Stack Spacing value increases the spacing between each child. By default Stack Spacing is set to 0 which means that no spacing is added between items in a stack.

Stack Spacing of 0 results in no space between children

Changing the stack spacing adds gaps between each child as shown in the following animation.

Stack Spacing used to add gaps between children

Stack Spacing can also be a negative value resulting in overlapping children. The items in the following animation are partially transparent to show the overlap.

Negative stack spacing results in overlaping children

Stack Spacing and Stacking Direction

Stack Spacing can be used for either Top to Bottom or Left to Right Stacking.

Stack Spacing can apply spacing vertically or horizontally

Stack Spacing and Wrapping

Stack Spacing can be used on container instances which stack and wrap their children. As stack spacing increases, the amount of space allocated to each object also increases, resulting in wrapping occurring earlier.

If wrapping occurs, then stack spacing applies spacing between rows and columns as shown the following animation:

Increasing Stack Spacing results in spacing between children both vertically and horizontally

Default Child Container

Default Child Container specifies the default parent for children of the selected component.

By default this value is blank, which means that newly added children treat the entire component as their parent. If this value is set, children which are dropped on instances of this component type use the instance as their parent.

Default Child Container is typically set on containers which are designed to hold children, but which have margins or decoration around the dedicated container instance. Examples include list boxes, tree views, and frames.

Example

Consider a Component named Frame which has two instances: OuterRectangle and InnerRectangle.

Frame component with two children

This Component is designed to keep all of is children inside the InnerRectangle, so that any child automatically respects the margin specified by InnerRectangle.

To make this kind of relationship the default, the Frame can set its Default Child Container property to InnerRectangle.

Setting the Default Child Container

Once this value is set, instances which are drag+dropped onto Frame instances use the InnerRectangle as their parent, as shown in the following animation.

Adding a child automatically uses the Default Child Container

Parent Details

When one instance is drag+dropped onto another instance, the Parent property is set according to the parent's Default Child Container.

Using the example above, the RectangleInstance is dropped on the ContainerTestInstance. Since the ContainerTestInstance is of type Frame, then the Default Child Container is applied on the drop, which results in the RectangleInstance's Parent being set to ContainerTestInstance.InnerRectangle.

Ignoring Default Child Container

As mentioned above, if an instance is added to a parent component, the instance automatically attaches itself to the parent's Default Child Container. This can be undone by manually changing the Parent property.

For example, the Parent can be manually changed to ContainerTestInstance.

Changing the Parent to the name of the instance can force a child to be attached to the root of the parent

Texture Address

Introduction

The texture address property controls the texture address behavior of a sprite. Specifically it can control whether texture addresses variables are available, and how texture coordinates and sprite size are related.

Entire Texture

If the texture address property is set to EntireTexture then the sprite draws its full image. The sprite does not repeat or render only part of the texture. This renders the entire image.

Sprite with Texture Address set to EntireTexture

Custom

If the texture address property is set to Custom then the top, bottom, left, and right properties can be independently set. This allows a sprite to only render a portion of its source texture.

Sprite with Texture Address set to Custom

Typically a Texture Address of Custom is used in combination with a Width Units of Percent of File Width and a Height Units of Percent of File Height. In this case, the size of the sprite depends on the texture coordinates.

When using Custom Texture Address, wrapping is possible. For more information see the Wrap page.

DimensionsBased

If the Texture Address property is set to DimensionsBased then the texture coordinates adjusts internally according to the width and the height of the Sprite. In other words, making the sprite larger or smaller does not stretch the image that it is rendering. Instead the image is be clipped, or clamped/wrapped according to the Wrap property.

Resizing a Sprite with Texture Address set to DimensionsBased

When the Texture Address is set to DimensionsBased, then the Texture Width and Texture Height values are replaced by Texture Width Scale and Texture Height Scale. In this mode, the Texture Width and Texture Height values are calculated by multiplying the absolute size of the Sprite by its respective scale values.

When using DimensionsBased Texture Address, wrapping is possible. For more information see the Wrap page.

DimensionsBased Texture Address and Percentage of File Width/Height

If a Sprite uses a Width Units of Percentage of File Width or a Height Units of Percentage of File Height, then the Width and Height values represent the size of the sprite relative to the entire source file.

For example, if a Sprite is displaying a source PNG file with a width of 130 pixels and its Width is 300, then the absolute width of the Sprite is 390 (130 * 300%). If Wrap is checked, then this indicates the number of times that the image repeats on the Sprite.

Sprite displaying a PNG with dimensions 130x180 with a Width of 300 and Height of 200

Texture Width Scale and Texture Height Scale

The Texture Width Scale and Texture Height Scale values determine the size of the texture on the Sprite when using DimensionsBased Texture Address. By default this value is 1, which means that the source image displays at its native size.

Increasing this value results in the image displaying larger. For example setting a value of 2 results in the displayed image being twice as large. Scale values for width and height can be set independently.

Larger scale values increase the displayed size of the texture

Since a larger value results in the image appearing larger, this means that mathematically a larger scale value results in smaller Texture Width and Texture Height value.

Texture Address

Introduction

The Texture Address variable can be used to define the area that the NineSlice displays. By default the Texture Address is set to Entire Texture which means the NineSlice will display the entire source file (split up among the nine pieces).

NineSlice only supports Entire Texture and Custom for the Texture Address value. It does not support Dimension Based, which is only available on the Sprite element.

Entire Texture

The following screenshot shows an entire texture being used for a NineSlice.

The entire texture is split up into 3 sections horizontally and 3 sections vertically, matching up the texture coordinates used to display the NineSlice's 9 sections.

Custom

The Custom value allows specifying a custom set of coordinates for the Nine Slice. Custom is most often used when an image is part of a sprite sheet. The following example uses this image:

The NineSlice uses the following variables:

  • Texture Address = Custom

  • Texture Top = 0

  • Texture Left = 0

  • Texture Height = 40

  • Texture Width = 40

These values result in the the following NineSlice:

Use Gradient

Introduction

The Use Gradient property controls whether a Skia Standard Element uses gradient values if true or a solid color if false.

By default this value is false.

RoundedRectangle with Use Gradient set to false

If this value is set to true, then additional properties appear for controlling the gradient.

RoundedRectangle with Use Gradient set to true showing gradient values

Red1 and 2, Green1 and 2, Blue1 and 2

Gradients create a smooth interpolation of color from the first set of values (Red1, Green1, Blue1) to the second set of values (Red2, Green2, Blue2).

Changing these values adjusts the gradient start and end colors.

Gradient Red, Green, and Blue values

Gradient X1 and 2, Gradient Y1 and 2

The gradient values appear at their respective values at the points specified by Gradient X1, Gradient Y1, Gradient X2, and Gradient Y2. For example the gradient points could be visualized as shown in the following image:

Gradient positions visualized over a RoundedRectangle

Changing the Gradient X or Y values changes the start and end points for the gradient.

Changing gradient X and Y values changes the gradient direction and interpolation distance

Gradient X1 and X2 Units, Gradient Y1 and Y2 Units

Gradient values use Units similar to X Units and Y Units. By default, gradient values are relative to the top-left of the element. Since the gradient values are not affected by size, changing the size of the element does not affect the gradient.

By default gradient values are relative to the element's top-left corner

The gradient X and Y units can be changed. Each value can be set independently. For example, the X2 and Y2 units can be adjusted to be relative to the bottom-right corner of the instance. The following shows a RoundedRectangle with the Gradient X2 and Y2 values 100 pixels up and to the left of the bottom-right corner. If the RoundedRectangle is resized, then the gradient adjusts in response.

Gradient X and Y units relative to the bottom right of the instance.

Gradient X and Y values can exist outside of the visual space of the instance, and even outside of its bounds. The following image shows an Arc with a gradient which is defined below the visual part of the arc. Notice that the Gradient Y values are both 0 PixelsFromBottom.

Gradient Type

Gradient Type controls whether the gradient is linear or radial. Radial gradients place the center of the radial gradient at X1,Y1 and the edge of the radial gradient at X2, Y2.

Linear Gradient Type on the left, Radial Gradient Type on the right

Has Dropshadow

Introduction

Has Dropshadow controls whether a dropshadow is drawn below an element. By default this value is false.

The following image shows two RoundedRectangles. The left with Has Dropshadow unchecked, the right with Has Dropshadow checked.

Two RoundedRectangle instances

Note that if an instance has a dropshadow, the dropshadow renders outside of the bounds of the instance.

Dark pixels from a dropshadow rendering below the bounds of a RoundedRectangle

Dropshadows draw as part of the object, so if multiple objects stack, their dropshadows also stack.

Multiple stacked ColoredRectangles with dropshadows

Dropshadow Offset X and Y

Dropshadow Offset X and Y control the position of the dropshadow relative to the main body of the instance. By default this value is 3 pixels below (Dropshadow Offset Y of positive 3).

This value can be changed to offset the dropshadow in any direction increasing a sense of height for the element.

Dropshadow Offset X and Y can affect the dropshadow position

Dropshadow Blur X and Y

Dropshadow Blur X and Y control how much to blur the dropshadow on the X and Y axes, respectively. A value of 0 creates a sharp shadow, while a larger value increases blur. Note that the X and Y values can be adjusted independently.

Dropshadow Blur X and Y values can be adjusted to make a dropshadow more blurry

Dropshadow blur values roughly measure the number of pixels that it takes to interpolate the edge of a shadow from its full color to fully transparent. This value is not exact due to antialiasing.

Dropshadow Alpha

Dropshadow Alpha controls the transparency of a dropshadow. A fully-opaque dropshadow has an alpha of 255. This value can be modified to decrease or increase the dropshadow's opacity.

Dropshadow Alpha adjusts the dropshadow transparency

Dropshadow Red, Green, and Blue

Dropshadow Red, Green, and Blue can be used to adjust the dropshadow color. Usually dropshadows are pure black with their transparency adjusted by Dropshadow Alpha, but they can also include other colors if needed.

Dropshadow Red, Green, and Blue values can be modified to create different colored shadows

Font Size

Introduction

Font Size controls how large a font appears on screen. Each font size and Font combination creates its own rasterized font, so using a lot of different font sizes will increase the amount of texture memory your game needs.

Example

The Font Size property can be set in Gum to make a text object's font larger or smaller. For example, the following shows a Text object with a font size of 18:

Changing the font size will increase the size of the Text object. For example, here is the same Text object with a Font Size of 36:

Font Cache

The first time a Font and Font Size combination are referenced, Gum creates a file in the FontCache folder. You may notice a small pause in Gum when setting Font and Font Size combinations for the first time as the file is created, but subsequent changes will be fast.

The FontCache folder is located in the following location:

/FontCache/

Font Size and Pixel Fonts

Games which are using fonts that are intentionally pixelated should avoid setting Font Size in-between the intended font size multiples for the given font. These sizes depend on the specific font used, and may require some trial and error.

For example, consider the font Press Start 2P which can be installed from https://fonts.google.com/specimen/Press+Start+2P

Font Size can be set to any value, but this font only looks good if Font Size is set to 8.

Font Size 8 through 15 with Press Start 2P Font

The rendering artifacts are more obvious when zooming in, as shown in the following image:

Rendering artifacts on font sizes which are not multiples of the intended font size for Press Start 2P font

Of course, we could also set the Font Size to 16, but this is unnecessary. Since text instances using pixelated fonts usually have Use Font Smoothing set to false, then the Text can use its Font Scale to adjust its size.

Wrap

Introduction

The Wrap value controls whether the sprite wraps its image when rendering portions beyond the right and bottom image bounds. If this value is true then wrapping occurs. Otherwise, areas beyond the texture extend the last pixel - also known as "clamping" the value.

The Wrap variable applies when dealing with a Texture Address of Custom or DimensionsBased. Wrapping is not available when using a Texture Address value of Entire Texture.

Wrap and Custom Texture Address

If Texture Address is set to Custom then wrapping is available. All examples in the Custom Texture Address section use the following values:

  • Width = 100

  • Width Units = Percentage of File Width

  • Height = 100

  • Height Units = Percentage of File Height

For more information, see the Width Unit and Height Unit pages.

Default Sprite width and height values are used in this section

Toggling wrapping adjusts whether the Sprite wraps or clamps the area defined by the Texture Left, Texture Top, Texture Width, and Texture Height values.

A Sprite can wrap or clamp the area outside of the right and bottom bounds of its source

A texture is wrapped if its Texture Right or Texture Bottom values are set to be larger than the source texture. For example, the following image shows a Sprite which is using an image that is 200x200. Its Texture Width is set to 500 and Texture Height is set to 300 so the sprite displays wrapping.

Sprite wrapping its image

If the Texture Width or Texture Height values are adjusted, then the Sprite's wrapping also adjusts.

Adjusting Texture Width and Texture Heigh changes wrapping

If Wrap is set to true, then wrapping happens for any area to the right or bottom of the bounds of the source. The following shows the bounds of a sprite moved in the Texture Coordinate tab resulting in the area that is being displayed wrapping and repeating.

Sprite repeating the image as its texture address is moved to the right

If a Sprite's Texture Left or Texture Top are set to less than 0 then the Sprite clamps this area. This may change to wrap in future versions of Gum so this behavior should not be relied upon.

Wrap and DimensionsBased

If a Sprite sets DimensionsBased for its Texture Address, then its source file can wrap if its dimensions are large enough to result in the texture width or texture height set to a value larger than the source dimensions.

All examples in the DimensionsBased Texture Address section use the following values:

  • Width Units = Absolute

  • Height Units = Absolute

Sprite width and height values used in this section

Toggling wrapping adjusts whether the Sprite wraps or clamps the area defined by the Texture Left, Texture Top, and its size.

A Sprite can wrap or clamp the area outside of the right and bottom bounds of its source

If a Sprite's width or height are adjusted, this results in its texture coordinate values also being modified. If Wrap is true then areas outside of the source file wrap.

The source image wraps if the width or height are adjusted Texture Address is DimensionsBased

Wrapping can also be affected by changing the Texture Width Scale or Texture Height Scale. Smaller values result in image being drawn smaller, making it wrap more.

Is Render Target

Introduction

Is Render Target controls whether all instances contained in this container render directly to the screen (if false), or if they first render to their own dedicated target before rendering to the screen (if true).

Is Render Target defaults to false (unchecked).

Is Render Target enables a number of graphical effects including:

  • Container Alpha (transparency)

  • Container Blend

  • Alpha-only Blend modes on instances contained in the Container

As of February 2025 the Is Render Target variable is considered experimental. You may experience issues when using this as it is being developed. Please report any problems you find through GitHub or on Discord.

Is Render Target Clips Children

Containers with Is Render Target set to true automatically clip their children. This behavior is the same as setting Clips Children to true. This happens because render targets internally create a texture which matches their size. Therefore, any items which are placed outside of the bounds of a render target container are not rendered.

Is Render Target set to true clips children

ColoredCircle

Introduction

ColoredCircle are round shapes which can be filled in or drawn as an outline. Unlike the non-Skia Circle element, ColoredCircles can be filled in and provide more options for customizing their appearance.

A default ColoredCircle

ColoredCircles support Skia properties such as Has Dropshadow, Is Filled, and Use Gradient. For more information and examples, see the Skia Standard Element General Properties pages.

States

Introduction

States are collection of variables which can be used to represent a component or screen configuration. States can be used for a variety of situations including:

  • Defining the appearance of a UI element such as Enabled, Disabled, Highlighted, and Pushed

  • Defining positions for interpolation and animation such as OffScreen and OnScreen

  • Defining start/end or empty/full states for interpolation such as AmmoFull and AmmoEmpty

  • Defining appearance in response to game-specific status such as NotJoined and PlayerJoined.

Every element automatically includes a Default state which cannot be removed. This state is automatically selected and any changes made to a component happen on the Default state unless a different state is selected.

Default state in a component named DefaultComponent

Additional states can be created in Screens, Components, and Standard elements. These states must be created in Categories. For more information, see the Categories page.

Canvas

Introduction

The Canvas element creates an instance of a SKCanvas which can be accessed in code to perform custom rendering. The contents of the Canvas cannot be modified in Gum. Since it is a Gum object, it does provide all of the variables for positioning, sizing but the rendering must be performed in custom code.

Since the Canvas cannot perform any rendering in Gum, it appears as an empty container.

Canvas instances in Gum apppear as empty containers

Is Filled

Introduction

Is Filled controls whether a shape is filled in or if it is drawn using stroke - another word for outline. By default this is true, but it can be unchecked to make a shape draw its outline.

ColoredCircle toggling its Is Filled property

Stroke Width

Stroke Width controls the thickness of the stroke (outline). Increasing the value makes the stroke thicker.

Stroke Width controls the thickness of the outline

Stroke, Gradient, and Dropshadow

If a Skia standard element has its Is Filled unchecked, this affects the rendering of gradients and dropshadows.

Gradients only fill the solid parts of a shape, so if a shape has Is Filled set to false, the hollow center of the shape does not show gradient color.

Toggling Is Filled affects the gradient rendering at the center of the shape

Dropshadows respect the opaque part of the shape, so changing Is Filled also affects the dropshadow.

Changing a ColoredCircle's Is Filled to false results in the dropshadow having a hollow center

Start Angle

Introduction

Start Angle defines the angle of the starting point of the arc. This value is measured in degrees, with a value of 0 pointing to the right. The value increases counterclockwise. the Start Angle and Sweep Angle values combine to determine the range of angles covered by the Arc.

The following image shows the an Arc with a Start Angle of 0. The red lines and text are not part of the arc and are added to the screen shot to show the location of the Start Angle.

An arc with a Start Angle of 0

Changing the Start Angle moves one side of the arc. The arc appears to rotate if the Start Angle is changed gradually.

Changing the Start Angle makes the arc appear to be rotating

Start Angle defines the starting point of the arc. A value of 270 degrees and a value of -90 place the starting point of the arc in the same location. Values larger than 360 result in the value looping. These values, although normally not needed, can be used to create spinning animatoins.

Source File

Introduction

The Source File property determines the file that is used by the Sprite. Sprite Source Files support the following formats:

  • .png files

  • .achx files (AnimationChains)

  • Images from URLs

Sprite displaying the FlatRedBall logo

If a Sprite has an empty Source File or if it references a missing file, then the missing file texture is displayed.

Sprite with a missing or emtpy Source File

Setting a PNG Source File

Source File can be set by typing a value or using the ... button to browser for a file.

All files are added as paths relative to the .gumx project.

Sprite referencing UISpriteSheet.png located in the same folder as the .gumx file

If a file is referenced outside of the .gumx folder, then Gum asks if you would like to copy the file or reference it outside of the current directory. Usually files should be copied to the project folder to keep the entire Gum project portable.

Gum asking whether a file should be copied or referenced in its current location.

ACHX Files

Gum natively supports referencing Animation Chain XML files (.achx) which are created by the FlatRedBall AnimationEditor. For more information on creating .achx files, see the FlatRedBall AnimationEditor page.

Once you have created an .achx file, you can reference it the same as a .png by entering its name or selecting it with the ... button.

Animated sprite referencing an .achx file

When referencing an .achx file, be sure to also check the Animate checkbox and to select the Current Chain Name.

.achx files are XML files which reference one or more other PNG files. If you are moving an .achx file be sure to also move the referenced PNG files.

Referencing URLs

Gum Sprites can also reference URLs. Gum can display images from URLs with standard file extensions such as .png and .jpg

Gum Sprite referencing an image of Super Mario World from gameuidatabase.com

Sprites can also reference images without extensions, such as urls from https://picsum.photos/

400x320 image referenced from Lorem Picsum

Sprite

Introduction

Sprites are objects which can draw an image (such as a .png) or a portion of a .png.

A Sprite displaying the old FlatRedBall logo

8 - State Categories

Introduction

States are a powerful way to create expressive groups of variables. Some UI elements may require a combination of states to be applied simultaneously.

For example, consider a Button component which displays a button callout.

This button might be a standard Button with the following states:

  • Enabled

  • Disabled

  • Highlighted

  • Pushed

But it may also have states for which button icon to display:

  • A

  • B

  • X

  • Y

  • LeftStick

  • RightStick

These two sets of states could be set independently and combined at runtime. Categories let you create groups of states so that multiple states can be set simultaneously.

Creating Categorized States

For this tutorial we'll create a new component. This component has state categories for size and for color. To do this:

  1. Open Gum

  2. Create a new Component called CategoryDemo

  3. Right-click anywhere in the State box and select Add Category

  4. Enter the name "Size" for the new category and click OK

  5. Repeat the above steps to create a "Color" category

Now we can add states to the categories. To do this:

  1. Right-click on the Size category and select Add State

  2. Enter the name "Small" for the new state

  3. Right-click on the Size category again and select Add State

  4. Add a second state to "Big"

  5. Right-click on the Color category and select Add State

  6. Add a state called "Red"

  7. Right-click on the Color category again and select Add State

  8. Add a state called "Blue"

Adding Visuals

Now that we have states set up we need to add a visual element to the component so that we can see our changes.

To do this, select the Default state and drag+drop a ColoredRectangle into your component

Setting Variables in States

To modify a state, you can select it and edit in the Editor tab or change properties in the Variables tab to modify what the state sets. Notice that normally for a component like this the ColoredRectangleInstance would have its width and height be relative to its container, but we're not doing this for the sake of keeping the tutorial shorter.

First we'll set the Size states. To do this:

  1. Select the Big state

  2. Resize the colored rectangle so it is larger than the default

  3. Select the Small state

  4. Resize the colored rectangle so it is smaller than the default

Next we'll set the Color states. To do this:

  1. Select the Red state

  2. Set the Red, Green, and Blue values to: 255, 0, 0

  3. Select the Blue state

  4. Set the Red, Green, Blue values to: 0, 0, 255

Viewing Multiple States on an Instance

Now that we have our CategoryDemo component set up with multiple categories, we can view these states on any CategoryDemo instance. To do this:

  1. Create a Screen called "CategoryDemoScreen"

  2. Drop an instance of the CategoryDemo component into the CategoryDemoScreen

  3. Select the newly-created CategoryDemoInstance

  4. Scroll down in the Variables list and notice that the instance has drop-downs for each category.

  5. You can set each state independently and the states combine

We can revert the states back to their unset values by right-clicking on the state variable and selecting the Make Default item.

Categories and Variables

If a variable is modified in one of the states in a category, then all of the states in that category are automatically assigned the default value, and this value is explicitly set. This concept makes working with states far more predictable.

For example, consider a component which has:

  • A single ColoredRectangle

  • A category called RectangleSizeCategory

  • States called Big, Medium, and Small

Initially, all states in a category do not explicitly assign any variables. We can see this by selecting the category and observing the Variables tab.

If a variable is changed in one of the states in the category, then that variable propagates to all other states, and the Category lists this as one of the variables that it modifies.

For example, we can select the Big category and change the ColoredRectangle.Width property to 150.

Once this value is changed, the RectangleSizeCategory lists this as a variable that it modifies in the Variables tab.

If we select any of the other states in the category, they show that they explicitly set the Width value as well (the value has a white background instead of light green). The value is inherited from the default state.

Once a variable is set in a category, all states are required to set this value. A variable cannot be removed from a single state in a category. Rather, to remove a variable, all states in the category must remove the variable. This can be done by selecting the category and pressing the X button next to the variable name.

Health Bar

Introduction

Introduction

Health bars are common UI elements in games. They are similar to progress bars, so this example could be used to create either. This example explains how to create a health bar component.

Creating the Component

First we'll define the component:

  1. Open Gum

  2. Open or create a new Gum project

  3. Right-click on the Components folder

  4. Name the component "HealthBar"

  5. Resize the HealthBar component so it is wider than it is tall. For example, assign Width to 200 and Height to 32.

Adding a Background

Next we'll add a background to our HealthBar Component

  1. Drag+drop a ColoredRectangle into the HealthBar

  2. Select the newly-created ColoredRectangleInstance

  3. Select the Alignment tab

  4. Click the Fill Dock button

  5. Change the ColoredRectangleInstance color to black

Now we have a black background in our HealthBar

Creating an Inner Container

The HealthBar displays its current health with another rectangle. This second rectangle will be contained inside a container to provide a boundary. To add an inner container:

  1. Drag+drop a Container onto the HealthBar

  2. Select the Alignment tab

  3. Enter a Margin value of 4

  4. Click the Fill Dock button

Now we have a ContainerInstance with the proper margin

Adding the Foreground Rectangle

Finally we'll add the foreground rectangle which displays the health:

  1. Drag+drop another ColoredRectangle onto the ContainerInstance. Be sure to drop it on ContainerInstance so that the newly-added ColoredRectangle is a child of the container

  2. Click the Alignment tab

  3. Set Margin back to 0

  4. Click the Fill Dock button

  5. Change the following values:

    1. X Units to Pixels from Left

    2. X Origin to Left

    3. Width to Percentage of Container

    4. Width to 100

Now, the Width value can change between 0 and 100 to indicate the health percentage.

Expose Width

Next we'll expose the inner ColoredRectangle's Width property so it can be assigned per HealthBar instance:

  1. Select the inner ColoredRectangle instance

  2. Right-click on its Width variable and select Expose Variable

  3. Enter an appropriate name such as "Percentage" and click OK

Now we can add instances of the HealthBar to a screen and control its fill percentage.

Y Units

The Y Units variable controls how a unit is vertically positioned relative to its parent. By default an object is positioned relative to the top of its parent, where each unit represents 1 pixel downward.

Pixels From Top

The following image shows a child positioned 50 Pixels From Top relative to its parent:

Pixels From Center

The following image shows a child ColoredRectangle positioned 50 Pixels From Center relative to its parent:

Pixels From Bottom

The following image shows a child ColoredRectangle positioned 50 Pixels From Bottom relative to its parent:

Percentage Parent Height

The following image shows a child ColoredRectangle positioned 50 Percentage Parent Height relative to its parent:

Pixels From Baseline

Pixels From Baseline positions a child relative to the parent's baseline. If the parent is a Text instance, the baseline is the Y position of the bottom of letters which do not have descenders. For more information on the concept of text baseline, see the baseline Wikipedia page

The following image shows a child ColoredRectangle positioned 0 pixels relative to a Text instance's baseline.

When using Pixels From Baseline, the position depends on the font size, baseline definition in the .fnt, and whether the text wraps. For example, changing the Width of the Text causes line wrapping which shifts the baseline.

A text instance's baseline is defined by its Font and Font Scale values. These values ultimately create a .fnt file with a base value indicating the distance from the top of the text instance to the baseline. For example, an Arial font with Font Size 40 has a base value of 36 and a lineHeight of 45.

This means that 36 pixels fall above the baseline, and 9 pixels (45 - 36) below.

Note that if the parent is not a Text instance, then the bottom of the parent is used as the baseline. The following image shows a Colored Rectangle using a Y Units of Pixels From Baseline with a Container parent.

Font

Introduction

The Font variable sets the font family used by the text.

This dropdown appears only if is set to false.

The Font dropdown has access to any font which is installed locally.

To use a font in Gum, download the font and install it by double-clicking or right-clicking on the font.

Font Generation and Font Cache

Gum performs rendering using rasterized fonts. In other words, it renders using pre-made .png files which contain all of the characters in a font.

You can view the Font Cache in your project by selecting Content -> View Font Cache.

This folder contains all font files used by your project.

Note that each font has three files:

  • bmfc - Bitmap Font Generator configuration file. This can be opened in Bitmap Font Generator to see the settings that have been used to export the other files

  • fnt - Bitmap Font Generator font file. This is a text file indicating the location of each character in the matching png files. It also includes kerning pairs.

  • png - This is the image file containing the letters for the font. The font may contain multiple image files if the character set or font size are large enough.

Each PNG can be opened in an image editor to view the packed characters. For example, the following shows the Arial 24 font. The blue background has been added manually to make the white characters visible:

Font Cache Generation

Fonts are generated as needed by Gum. This happens whenever a property changes on a Text object requiring a new font. Gum only re-generates fonts if a matching font doesn't already exist. The following animation shows new fonts being generated as a Text's Font Size is changed.

Fonts are generated in response to any of the following properties changing:

  • Font

Installing Fonts

Windows Machines typically have dozens of fonts installed automatically. You may be working on a project which needs custom fonts. These fonts can be obtained on many websites including and .

Once a font has been installed, you must restart Gum for the font to be available in the Font dropdown.

Wraps Children

The Wraps Children property controls whether children wrap or stack beyond their container's boundaries when the container's is set to Top to Bottom Stack or Left to Right Stack.

If a parent has Wraps children set to true, the wrapping adjusts in response to resizing the parent.

Similarly, resizing a child may result in the stacking changing.

The row height in a Left to Right Stack is determined by the largest child in the row.

Similarly, column width in a Top to bottom Stack is determined by the largest child in the column.

Font Scale

Introduction

The font scale property allows you to zoom a font in or out, effectively making the text larger or smaller. Unlike using the font size property, font scale will not re-create the font (when using standard fonts). Font scale is also necessary for resizing custom fonts.

Details

By default Text objects Font Scale value of 1.

Font scale can be increased, but doing so can make fonts pixellated. For example, setting the Font Scale value to 5 makes each pixel on the font 5x as large, resulting in a pixellated text object.

Similarly, FontScale can be set to a value smaller than 1, resulting in a shrunk font.

Svg

Introduction

Svgs can display .svg files. Since these files are vector art, they can be resized without pixelation.

The following is an Svg instance displaying the FlatRedBall logo. Source SVG:

Source File

The Source File variable controls the lottie animation displayed. This value can be set and changed just like source files on other elements such as a .png on a Sprite.

Svg Width and Height

Width and Height values can be set on an Svg file just any other Gum element. Unlike rasterized objects such as Sprites, Svgs use Vector art so they can be resized and still retain crisp edges and details.

Svgs are still rasterized in Gum, so they display pixels when the view is zoomed in, especially if the Svg has a small Width or Height.

Maintain File Aspect Ratio Width and Height

Svgs support the Maintain File Aspect Ratio Width and Maintain File Aspect Ratio Height units. For more information, see the and page.

Y Origin

Introduction

The Y Origin variable controls the point which an object is positioned by. By default the Y Origin is Top. The Y Origin is shown visually as a white "X" in the editor.

Top

The following image shows a with its Y Origin set to Top:

Center

The following image shows a ColoredRectangle with its Y Origin set to Center:

Bottom

The following image shows a ColoredRectangle with its Y Origin set to Bottom:

Baseline

The following shows a Text with its Y Origin set to Baseline:

Baseline refers to the bottom of the text for letters without descenders. For more information see the .

Baseline is often used to align fonts of different sizes. The following image shows two Text instances with different font sizes. Both are positioned by their baseline so their bottoms align properly (ignoring descenders, such as on the letter p and the comma).

By contrast, the following image shows the same Text instances using bottom alignment.

Points

Introduction

Points are an ordered set of X,Y values defining the shape of the polygon. All points are relative to the Polygon's position. Typically the last point is the same as the first point creating a closed polygon.

By default polygons have four sides. Since the first and last point is repeated, a four-sided polygon has five points.

Each point is relative to the polygon's X and Y (position). Points use pixel coordinates. The following image shows a polygon with the following points:

  • -32, -32

  • 32, -32

  • 32, 32

  • 32, -32

  • -32, -32 (repeat of first point)

Notice that the image above has points which appear above and to the left of the polygon's origin.

Adding Points in the Editor

The easiest way to add points is by selecting a Polygon, then clicking on the + icon that appears in the center of the line where you would like to add a point. The following animation shows how to add points to a square to create an octagon:

Moving Points

Points can be moved by clicking on them and dragging them in the editor. Note that points can be positioned anywhere, even if lines cross or if a polygon is concave.

Removing Points

A point can be removed by clicking on it and pressing the delete key.

Advanced Point Editing

Points can also be edited manually in the Screen or Component which contains the Polygon instance. You can open the file in a text editor to see a list of points.

For example, consider the following polygon:

The points for this polygon defined in the MainMenu XML file might look like this:

These points can be changed in the XML file. If the file is changed then Gum automatically reloads this file.

Remember that the first and last points should have the same values if you want your polygon to be closed. You can make edits in the XML file to separate the start and end if you would like to draw a segmented line rather than a closed polygon.

Color

Introduction

The Color value is used to perform a multiply color operation on the sprite. Color values can be used to darken or tint a grayscale texture. By default Sprites us a white color, which means the original texture will display unmodified.

Examples

The following images show the color values as applied to a multi-color sprite.

Red: 255 Green: 255 Blue: 255

Red: 255 Green: 0 Blue: 0

Red: 0 Green: 255 Blue: 0

Red: 0 Green: 0 Blue: 255

Red: 128 Green: 128 Blue: 128

Red: 0 Green: 0 Blue: 0

Texture Top

Introduction

The Texture Top variable controls the top pixel of the source rectangle used to draw the NineSlice. Texture Top is only available if the NineSlice uses a Texture Address of Custom or Dimension Based.

The following image shows a NineSlice with a Texture Top value of 48.

Texture Top controls the top side of the region that the NineSlice displays on its source file. In this case, the top-edge of the source rectangle is 48 pixels from the top edge of the entire file.

Button with Y button callout. Credit Game UI Database https://www.gameuidatabase.com/gameData.php?id=36&autoload=975
Size and Color categories
Red and Blue states with the correct color values
Combining states on an instance
States can be made default through the right-click make Default item
RectangleSizeCategory which does not set any variables
Setting ColoredRectangleInstance Width to 150
RectangleSizeCategory lists any variables that it changes
Width value set by Medium state
Press the X next to a variable on a category to remove the assignment of that variable on all states in the category
Add ColoredRectangle to HealthBar
Fill Dock to make the background take up the entire size of its parent HealthBar component
Set Margin to 4, then click the Fill Dock button
Click Expose Variable
Percentage value updated on a ScrollBar instance
ColoredRectangle
https://en.wikipedia.org/wiki/Baseline_(typography)
Rectangle with Y Units of Pixels From Top
ColoredRectangle with Y Units of Pixels From Center
ColoredRectangle with Y Units of Pixels From Bottom
ColoredRectangle with Y Units of Percentage Parent Height
Baseline Example
ColoredRectangle with Y Units of Pixels From Baseline
Baseline Shifts when the parent Width changes
Arial with Font Size 40 has a base value of 36
Base defines the distance from the top of the Text instance to the baseline
Pixels from Baseline uses the bottom of the parent if it is not a Text instance
Use Custom Font
Font Size
Outline Thickness
Is Italic
Is Bold
Use Font Smoothing
https://www.dafont.com/
https://fonts.google.com/
Text instance using Arial font family
Changing the font updates the appearance of the Text instance
Right-click Install font option
View Font Cache menu item
Font files in the FontCache folder
Arial 24 font in a PNG with an added blue background for visibility
Fonts generated as the Font Size changes
Font available in the Font dropdown after being installed
Children Layout
Wraps children makes children wrap when using either Top to Bottom Stack or Left to Right Stack.
Resizing a parent can change wrapping
Resizing children can change wrapping
Height of each item in the row determines row height
Width of each item in the column determines column width
https://github.com/flatredball/FlatRedBallMedia/blob/master/FlatRedBall%20Logos/frb-logo-main.svg
Width Units
Height Units
Svg displaying the FlatRedBall logo
Resized SVG maintains crisp edges when resized
Small Svgs display pixels if zoomed in
ColoredRectangle
Wikipedia Baseline page
ColoredRectangle with Top Y Origin
ColoredRectangle with Center Y Origin
ColoredRectangle with Bottom Y Origin
Text with Baseline Y Origin
50,000 xp aligned by baseline
<VariableList xsi:type="VariableListSaveOfVector2">
  <Type>Vector2</Type>
  <Name>PolygonInstance.Points</Name>
  <IsFile>false</IsFile>
  <IsHiddenInPropertyGrid>false</IsHiddenInPropertyGrid>
  <Value>
    <Vector2>
      <X>0</X>
      <Y>46</Y>
    </Vector2>
    <Vector2>
      <X>32</X>
      <Y>32</Y>
    </Vector2>
    <Vector2>
      <X>10</X>
      <Y>0</Y>
    </Vector2>
    <Vector2>
      <X>0</X>
      <Y>46</Y>
    </Vector2>
  </Value>
</VariableList>
A default four-sided polygon
Polygon with points 32 units from the origin on both X and Y
Points can be added by clicking in the center of lines
Polygons can be concave and even have crossing lines.
Press the delete key to remove points
PolygonInstance in MainMenu
NineSlice with Texture Top set to 48
Texture Top set to 48 pixels in the Texture Coordinates tab

Parent

Introduction

The Parent variable allows UI elements to be positioned and sized according to other UI elements. Parenting hierarchies can go many levels deep and the parent/child relationship can be visualized by the white line connecting the parent to the child when the child is selected.

Parents and Units

Parents control control the position of their children. Parents can also control the size of their objects depending on the child's Width Units and Height Units.

For example, if a parent is moved, its children move along with it. For more information on positioning children, see the X Units and Y Units pages.

Moving a parent also moves its children

Children can also be sized according to their parents. For more information on sizing children according to their parent, see the Width Units and Height Units pages.

Children can be resized according to their parent

Children Outside of Parent Bounds

Children can be placed outside of their parent's bounds. In the simplest case, a child can be dragged outside of its parent's bounds in the editor.

Children can be placed outside of their parents' bounds

Children outside of their parent's bounds still follow all of the same rules for sizing and positioning, but there are some important things to keep in mind.

Children placed outside of a parent do not affect the parent's effective width or height. Any unit value that depends on children or parents only considers the immediate child or parent and does not look at sizes beyond the immediate relationship.

For example if a parent has 100 effective width, and its child is given an X of 200, the parent's effective width remains 100 (assuming the parent does not size itself according to its children). This is important when other children are sized or positioned according to the parent's width.

The following animation shows three instances:

  1. A parent container

  2. A blue rectangle which is sized according to the parent rectangle

  3. A yellow rectangle which is moved outside of the bounds of its parent

Notice that when the parent resizes the blue rectangle is also resized, but when the yellow rectangle is moved outside of the parent bounds, the parent and blue rectangle are not resized.

Children can exist outside of the parent bounds without resizing the parent

Children outside of bounds may not respond to click events unless the parent is explicitly checking for click events outside of its bounds. This is a property which is set at runtime. For more information see the RaiseChildrenEventsOutsideOfBounds page.

Example - Drag+Drop in the Tree View

To change Parent in the Project tab:

  1. Select a child

  2. Drag+drop the child onto the desired parent

Drag+drop a child onto the desired parent

The child can be detached from its Parent by drag+dropping it onto the Component.

Drag+drop a child onto its root component or screen to detach it from its current parent

Drag+dropping onto a parent may set the Parent property to an instance inside of the parent's Component type sets its Default Child Container value. For more information see the Default Child Container page.

Example - Using the Dropdown

To set Parent by name:

  1. Select the desired child

  2. Change the Parent property to the desired parent:

Change Parent using the dropdown

Base Type (Inheritance)

Introduction

The Base Type variable can be used to specify both inheritance but also the type of an instance.

Base Type on an instance indicates its type. This is usually automatically set when an instance is first created - usually by drag+dropping a component or standard element onto its target component or screen.

Gum Screens and Components support changing Base Type to specify inheritance. By setting Base Type, a screen or component automatically inherits the following:

  • Variable values

  • Exposed variables

  • Instances

  • Available variables, such as stacking if inheriting from a container

Inheritance is useful if your project needs multiple screens or components which share common variables or instances.

Instance Base Type

All instances must have a Base Type set. For example, the following instance is of type Container.

Instance named ContainerInstance is of type Container

Base Type is automatically assigned when a new instance is created. For example, the following animation shows a new ColoredRectangle instance created. Note that its Base Type is automatically assigned to ColoredRectangle.

Creating a new ColoredRectangle instance assigns the base type to ColoredRectangle

Base Type can be changed after an instance is created. Keep in mind that doing so does not change its name or any other properties, so you may need to manually adjust properties when converting between different Base Types. Also, note that default values may change when switching from one Base Type to another.

The following shows a ColoredRectangle changed to a Container. Since Container and ColoredRectangle have different default Width and Height values, changing Base Type results in changes to default size too.

Changing Base Type can change other variables such as Width and Height

Component Inheritance

All components use inheritance even if their Base Type variable is not set explicitly. By default components inherit from the Container type.

Button component inheriting from Container

By inheriting from the Container type, components have access to all Container variables such as Children Layout.

Inheriting from Standard Types

Components can inherit from standard types. For example, instead of inheriting from Container a component may inherit from ColoredRectangle. By doing so, it has access to all properties on the ColoredRectangle type.

Component inheriting from ColoredRectangle

Most components inherit from the Container type. If a component needs to display visuals, such as a ColoredRectangle, typically the ColoredRectangle is added as a child to the component rather than being used as a Base Type.

Inheriting from Components

Components can inherit from other components. By doing so the component inherits all children and exposed variables from its base component.

A component which inherits from another component is often called a derived component. The component which is being inherited from is often called a base component.

A base component can be used to define instances which the derived component can modify. For example a component named ButtonBase may define that all components have a ColoredRectangle named Background and a Text named TextInstance.

Example component named ButtonBase

If another component uses ButtonBase as its Base Type, then this component automatically gets Background and TextInstance children which match the base instances.

Setting the base to ButtonBase automatically adds the same children to CancelButton

The CancelButton can modify variables on the added children. For example the CancelButton can modify the Text on the TextInstance and the color values on the Background.

CancelButton with modified children variables (Text and color values)

The derived component has the following restrictions when working with children instances:

  • Name cannot be changed. For example Background must always be named Background.

  • Base Type cannot be changed. For example, the base type for Background must be ColoredRectangle

  • Children defined in the base cannot be removed. For example, the Background child cannot be deleted from CancelButton. Children can be made invisible.

If the base type adds new instances, then the derived types automatically get the same instances added as well. Similarly, if the base type deletes a child, then the child is also removed from the derived type.

Children added and removed to base types are also added and removed on the derived types

Derived types get access to all of the exposed variables in the base type. For example, if ButtonBase exposes the TextInstance's Text property, this is also available on the derived component.

Exposed variables are inherited

Base Type vs States

Base Types allow for the customization of a component, including the creation of many variants. Similarly, States also allow for the customization of a component in similar ways. When deciding between whether to use states or inheritance, keep the following in mind:

  • States are often used to set variables temporarily, while inheritance is permanent. For example, a button may set its background color values in response to being highlighted. By contrast, a Cancel button may always say "Cancel".

  • States do not allow for the creation of new instances. Although derived components cannot delete children which are defined by their Base Type, derived components can add additional instances.

  • Components can use multiple categories. Therefore, it may not be clear which category defines the type of component. A component can only have one Base Type, so its type is defined clearly.

Behaviors

Introduction

Behaviors can define requirements which are reusable across multiple components to standardize instance names and behaviors. If a component uses a behavior, then the component is forced to include categories and instances according to the behavior definition.

The most common usage of behaviors is the automatic creation and inclusion of Gum Forms behaviors.

Behaviors are used to define requirements for components, to simplify the creation of new components, and to reduce the chances of spelling and implementation mistakes.

C# programmers may find the concept of behaviors to be similar to interfaces in code. Behaviors define requirements for components, but they give components the flexibility to implement these requirements, just like interfaces define required properties and methods which classes can implement.

Common Behavior Usage

Behaviors are used to standardize state, category, and instance names. The most common usage of behaviors is with Gum Forms. Of course, behaviors can also be used to standardize names in your project for components which are not intended to be with Gum Forms.

Creating a Behavior

To add a behavior:

  1. Right-click on the Behaviors folder

  2. Select Add Behavior

  3. Enter the new behavior name. Often time the word Behavior is added at the end of the name, such as ButtonBehavior

New behaviors appear in the Project tab.

Once a behavior is created, it can be given categories, states, and instances. Components which use this behavior are required to have matching categories and states.

The process of adding and removing states to behaviors is the same as adding and removing states in other elements. For more information, see the page.

For example, the ButtonBehavior may have the following:

  • ButtonCategory (Category)

    • Enabled (State)

    • Disabled (State)

    • Focused (State)

    • Pushed (State)

A behavior can have as many categories and states as needed.

Once a behavior is added, it can be used in a component. To add a behavior to a component, drag+drop the behavior onto the component in the tree view.

Behaviors can also be added and removed on the component's Behaviors tab:

  1. Select a component which should use the behavior

  2. Click the Behaviors tab

  3. Click the Edit button

  4. Check the desired behaviors - a component may use multiple behaviors

  5. Click OK

Notice that once a behavior is added to a component, the component automatically creates the matching categories and states.

If the behavior is selected in the Behaviors tab, the required states and categories are highlighted in the States tab.

These categories cannot be removed as long as the component uses the behavior.

Category and State Requirements

As mentioned above, if a component uses a behavior, then the component is required to include all of the states and categories defined by the behavior. If a behavior is added to a component, then all states and categories in the behavior are automatically added to the component. Keep in mind that newly-added states do not automatically assign any values. The behavior only requires that the states exist but it does not decide which variables are assigned by the states. These required states can even be left to their default so they have no affect on the component.

Required states and categories cannot be removed or renamed. Required states cannot be moved to different categories.

If a new category or state is added to a behavior, all components which use the behavior also have the new category or state added.

If a state or category is removed from a behavior, Gum does not remove the state or category from components which implement the behavior. Behaviors only define what is required, but they do not prevent components from defining additional states and categories. Also, the states on components may still be needed even if the behavior is removed. Therefore, if you remove any states or categories from a behavior, you may need to manually remove the same states and categories from components which use the behavior if these are no longer needed.

Instance Requirements

Behaviors can include instances, resulting in required instances existing in components which use the behavior. Instances in behaviors only include two properties:

  • Name

  • Base Type

Instances in behaviors only require that instances in components have these two matching properties. All other properties can be set to any value.

To add an instance to a behavior, drag+drop a standard element or component onto the behavior in the Project tab.

An instance can have its Name changed, Base Type changed, or removed.

If a component is missing a behavior then the Error window provides information about the missing requirement.

At this time Gum does not automatically add required instances to components which need them. This may change in future versions of Gum. For now, instances must be manually added to resolve errors.

Bottom-Up Stack

Bottom-up stacks can be used to display stacks of elements which should move up as more are added. This concept is similar to messages received in a chat window. Gum layout can be used to produce this type of stack.

This example shows a bottom-up stack (vertical) but the same approach could be used to create a right-aligned stack.

Items in a bottom-up stack need a parent Container. This Container could be an instance of a Container or a component since components usually have their Base Type set to Container. For this example we'll use a container.

This container to stack needs the following variables set:

  • Children Layout set to Top to Bottom Stack so all children stack vertically

  • Height Units set to Relative to Children so the container resizes itself as more children are added

  • Height set to 0 so the effective height of the container is based purely on its children

  • Stack Spacing set to 2 (optional) to add spacing between each child

Now children of the Container stack vertically. This concept works for any type of child, but we'll use ColoredRectangles for this example. Add a few instances to the Container and they stack vertically.

Finally we can have the stack grow up instead of down. To do this, change the following variables on the parent container:

  • Y Origin set to Bottom

  • Y Units set to Pixels from Bottom

Now as new children are added, the parent stack grows and all items shift up.

Contained Type

Introduction

Contained Type enables code generation and Gum runtimes (such as FlatRedBall) to create strongly-typed containers.

Currently the Contained Type variable does not have any affect on objects in the Gum tool and it exists only to support strongly-typed runtimes. This may change in future versions of the Gum tool.

Common Usage

Some Gum components or Containers may exist to hold a list of a particular type of item. For example, consider a game which includes a row of hearts to show the player's current health.

In this particular case, the hearts can be filled or empty to show the current and max health, but the max health can also be increased. If the max health increases, then a new heart instance is added to the container at runtime.

Since this container should only ever contain instances of a Heart component, then the container's Contained Type can be set to Heart.

In this example, FlatRedBall respects the Contained Type variable and generates a generic list.

As mentioned above, the implementation of this variable depends on the runtime you are using. If you are using a runtime which does not implement this feature and you would like to have it added, please create a GitHub issue or make a request in Discord.

Circle

Introduction

Circles are an outlined shape which can be used for visualizations or collision in games. Circles provide a color for their outline but they cannot be filled in.

Container instance
Children Layout set to Top to Bottom Stack
Height Units set to Relative to Children
Height set to 0
Stack Spacing set to 2
ColoredRectangle instances stacking vertically in a container
Y Origin set to Bottom
Y Units set to Pixels from Bottom
Stack grows upward as more children are added
Row of hearts displaying the player's health
HealthContainer instance with its Contained Type set to Heart
ContainerRuntime can be generic in FlatRedBall, so it respects the Contained Type variable
Circle in Gum using the default white color
States
Add Behavior menu item
ButtonBehavior in the Behaviors folder
ButtonCategory defined on ButtonBehavior
Add a behavior to a component by drag+dropping the behavior on the component in the Project tab
Button component adding the ButtonBehavior
States and Categories required by the selected behavior are highlighted
Renaming and deleting states and categories required by behaviors is not allowed
Adding states and categories in a component adds the states and categories to all components using the behavior
Drag+drop standard elements or components onto behaviors to create instances in the behavior
The Variables tab lets you change Name and Base Type. Right-click to delete an instance.
Button component is missing a SpriteInstance which is required by the ButtonBehavior

Blend

Introduction

The Blend variable controls how the selected instance combines its colors with whatever is drawn before. The final appearance depends on its Blend, Alpha, Source File, and Color values.

Blend is available on the following types:

  • ColoredRectangle

  • Container (if Is Render Target is set to true)

  • NineSlice

  • Sprite

Blend is also available on all Skia elements:

  • Arc

  • ColoredCircle

  • LottieAnimation

  • RoundedRectangle

  • Svg

Most examples on this page overlay a Sprite over ColoredRectangles, but the same Blend behavior applies to all items which support the Blend variable.

Normal Blend

Normal Blend is the default value. When an instance uses Normal Blend, it interpolates its color with whatever it draws on top of using its Alpha value as a weight.

If a Normal Blend Sprite has an Alpha of 255, then the Sprite completely replaces whatever is below.

Normal Blend Sprite with an Alpha of 255

If a Sprite has an Alpha of 128 (roughly half of 255), then it averages its color with whatever is below.

Normal Blend Sprite with an Alpha of 128

A Sprite with an Alpha of 25 (roughly 10%) blends with whatever is below, but its color is given a weight of roughly 10%.

Normal Blend Sprite with an Alpha of 25

The examples above use the Alpha value to apply transparency. Note that if the source file (.png) has transparency as part of the file, the same effect applies.

Additive Blend

Additive Blend results in the color of a element being added to whatever is below. This typically results in brighter colors. Additive Blend can be used to simulate a light.

Since Additive Blend results in a modification of what is under instead of a replacement, an Additive Blend Sprite typically appear transparent even when Alpha is 255.

Additive Blend Sprite with an Alpha of 255

As Alpha is reduced, the brightening effect is reduced. A Sprite with an Alpha of 128 only applies roughly half as much of a brightening effect.

Additive Blend Sprite with an Alpha of 128

A Sprite with an Alpha of 25 applies a slight brightening effect.

Additive Blend Sprite with an Alpha of 25

Stacking multiple Sprites with Additive Blend results in the brightening effect stacking as well.

Four Additive Blend Sprites with an Alpha of 255

Replace Blend

Replace Blend results in the instance completely replacing whatever it is drawn on top of regardless of its Alpha or transparency in the source file.

A Sprite with no transparency in its source file drawn with Alpha of 255 looks the same whether it uses Replace or Normal Blend.

Replace Blend Sprite with an Alpha of 255

Changing the Alpha on a Sprite with Replace Blend does not affect how it is drawn - it is always drawn at full opacity.

Replace Blend Sprite with an Alpha of 128

Replace Blend results in a Sprite being fully opaque even if its source file has transparency. The following image shows two Sprites displaying the same image.

Normal and Replace Blend on the same source file.

Alpha-Only Blends

Gum supports Blend modes which modify the alpha (opacity) of whatever is under the instance using the alpha-only Blend . Alpha-only Blend modes ignore the color of the instance using the Blend - only the alpha matters. Therefore, the following three circles would behave the same despite having different colors:

Color values are ignored with Alpha-only Blends

Since alpha-only blends operate directly on the alpha of whatever is below, they are only intended to be used on Containers with Is Render Target set to true. Usually objects with these blend modes are drawn on top of all other items in the container. For example, the following image shows a RenderTargetContainer which holds a number of items including the AlphaOnlyCircle. AlphaOnlyCircle is an instance which can be used to apply Alpha-only Blends to whatever is below.

AlphaOnlyCircle can be used to modify the alpha of what is below

Using an alpha-only Blend outside of a container with Is Render Target set to true typically results in the instance either being drawn as pure black or being invisible.

Subtract Alpha Blend

Subtract Alpha Blend subtracts, or "cuts out", the alpha of whatever is below.

Subtract Alpha removing the alpha of what is below

As Alpha is reduced, the amount of opacity removed effect is also reduced. A Sprite with an Alpha of 128 only removes roughly half as much opacity from what is below.

Reducing Alpha results in less opacity being removed

Replace Alpha Blend

Replace Alpha forcefully sets the opacity of whatever is below. Rather than subtracting alpha, replace can forcefully set the alpha.

Replace Alpha with an Alpha value of 255 results in no changes if what is under is already opaque, but it can add alpha if what is under is transparent.

Replace Alpha with Alpha of 255 results in no changes on already-opaque regions, but can add alpha

If Alpha is reduced, then the resulting pixels display the explicitly set alpha. The following shows setting alpha explicitly to 128 (about 50%).

Explicitly setting alpha to 128 with Replace Alpha

Setting Alpha to 0 forcefully sets whatever is under to fully transparent. This is similar to performing Subtract Alpha with an Alpha of 255.

Replace Alpha with Alpha of 0

Keep in mind that Replace Alpha can apply different alpha values if the instance itself has variable alpha, such as a Sprite with some parts transparent and some parts opaque.

Alpha being replaced to opaque in the center and transparent on the edges of the circle

Min Alpha

Min Alpha modifies the underlying object so that the result is the minimum alpha between the instance and what is below. This can be used to create an alpha mask.

Min alpha creates a mask

If the instance alpha is reduced, then the resulting transparency is reduced as well. The following shows setting Alpha to 128 (about 50%).

Min alpha with an alpha of 128

Keep in mind that multiple objects can be combined to create larger masks. For example, additional ColoredRectangles can be added to the circle above to create a larger mask. Each rectangle also has its Blend set to Min Alpha.

Extending masks with additional shapes

Children Layout

Introduction

Children Layout determines how a container positions its children. The default value is Regular which means that children are positioned according to their X Units and Y Units.

Children Layout with Regular selected

Top to Bottom Stack results in the children stacking one on top of another, from top to bottom.

Left to Right Stack results in the children stacking one beside another, from left to right.

Auto Grid Horizontal results in the children being placed in a grid, filling in horizontally first before wrapping to the next row.

Auto Grid Vertical results in the children being placed in a grid, filling in vertically first before wrapping to a new column.

Example

The following animation shows how to use the ChildrenLayout variable to change the default position of a Container's children:

Changing Children Layout updates the position of all contained children

Regular

Regular layout positions each child independent of every other child. The position of one child does not affect the position other children. This is the default layout for containers.

Two ColoredRectangles using Regular layout

Top to Bottom Stack

Top to Bottom Stack results in each child being positioned after its previous sibling vertically. This can be used to create horizontal stacks.

Text Instances in a top to bottom stack

Left to Right Stack

Left to Right Stack results in each child being positioned after its previous sibling horizontally. This can be used to create vertical stacks.

Sprites in a Left to Right Stack

Stacking and Container Height Units and Width Units

A container can stack its children and also have its size based on its children. This results in the container growing as children are added.

For example, the following shows a container with its Height Units set to Relative To Children and its Children Layout set to Top To Bottom Stack. As more children are added the container grows vertically.

Top To Bottom Stack can be used with Height Units of Relative To Children to grow the container as children are added

Stacking and X/Y Values

When children stack, each child's X or Y depends on the boundary of its previous sibling. When stacking vertically, the child's Y value begins at the bottom side of the previous item. Similarly, when stacking horizontally, the child's X value begins at the right side of the previous item.

For example, the following image shows a Text object with a Y value of 20. Notice that it is positioned 20 units below the item above it.

A Text's Y value can be used to separate it from its previous sibling in a Top to Bottom Stack

This effect is easy to notice when dragging an object inside a stack, as shown in the following animation:

As a Y value changes, all following siblings move too

Stacking and Units

If instances are stacked in a container, the stacking controls the instance values based on the direction of the stack.

  • Top to Bottom Stack containers control the Y value of their children.

  • Left to Right Stack containers control the X value of their children.

The position value which is not controlled by the stack can be changed freely without any impact on the stacking.

For example, if a container stacks its children using a Top to Bottom Stack, the children in the stack are free to change their X values. The following animation shows how children can be left, center, or right anchored (which changes their X Units and X Origin) without affecting the other children in the stack.

Changing horizontal layout values does not affect siblings in a Top to Bottom Stack

An object stacks only if its position unit values are top or left for vertical or horizontal stacks. For example, if a child is part of a Top to Bottom Stack, it only stacks if its Y Units is set to Pixels from Top. Otherwise it ignores its parents stacking behavior.

Top to Bottom Stack is only respected if the child has its Y Units set to Pixels from Top

In general this can cause unexpected behavior, especially if additional siblings follow the child which is not using the default Pixels from Top or Pixels from Left, so changing this value on the primary stacking direction is not recommended.

Stack Spacing

Top to Bottom Stack and Left to Right Stack separate their children using the Stack Spacing value. For more information, see the Stack Spacing page.

Stacking and Children Origin

The position of a child in a stack is determined by the size of the previous item in the stack and the origin of the child. In most cases children which are stacked should use a Left X Origin if the parent uses a Left To Right Stack and should use a Top Y Origin if the parent uses a Top To Bottom Stack.

Consider a container with a blue rectangle which stacks horizontally. The blue occupies some space according to its absolute width. The next instance after the blue rectangle is placed relative to the right-side of the blue rectangle.

The next item's position is based on the right-side of the blue rectangle

For example, if a red rectangle (partially transparent to make it easier to see when overlapping) is added to the container, the stack may create a layout similar to the following image:

Red rectangle is positioned relative to the right-side of the blue rectangle.

Keep in mind that the stack simply states the position of the next item. Each item can freely adjust its X Origin (or Y Origin in a Top to Bottom Stack). If the red rectangle's X Origin is changed to Center, the red rectangle overlaps the blue rectangle.

Stack determines a child's position, the child can change its origin

If the red rectangle's X Origin is changed to Right, then its right side aligns with the right side of the blue rectangle, resulting in the red overlapping the blue completely. In this case the red rectangle's stacking is essentially cancelled out by the X Origin.

Red rectangle overlapping blue rectangle

This overlapping may not be desirable, so keep this in mind when changing a stacked child's origin.

Wraps Children

The Wraps Children property controls how stacking behaves beyond boundaries. For more information, see the Wraps Children page.

Reordering Children

Children of a container which uses the Top To Bottom Stack or Left To Right Stack are ordered according to their order in the tree view on the left. By default this is the order in which the children are added to a parent container.

Item order in the Project tab determines the order of items in a stacked container

Children can be reordered using the right-click menu on an instance.

Alternatively, children order can be changed by clicking on the item in the tree view, holding down the ALT key, then pressing the up or down arrows.

Changing order with ALT+Arrow hotkey

For more information on ordering, see the Order page.

Auto Grid Horizontal and Auto Grid Vertical

Auto Grid Horizontal and Auto Grid Vertical layouts result in each child of the container being placed in its own cell. All position and size values are relative to the entire cell, so children can expand to fill their cell or be positioned according to any side or corner.

Blue ColoredRectangles in a Container using Children Layout of Auto Grid Horizontal

The following shows a container with an Auto Grid Horizontal and Vertical Cells of 2, resulting in a 2x2 grid. As children are added to the container through copy/paste, each child is placed in its own cell.

Container using Auto Grid Horizontal creating a 2x2 grid

The number of cells is controlled by the Auto Grid Horizontal Cells and Auto Grid Vertical Cells. Increasing the number of cells results in the rows or columns adjusting automatically.

Increasing Auto Grid Horizontal Cells adds additional columns

Each child occupies one cell, and the order of the children controls the order of the placement in grids. The first child occupies the top-left row. If using Auto Grid Horizontal, each child is placed to the right of its preceding sibling, wrapping to the next line when reaching the end of a row. If using Auto Grid Vertical, each child is placed below its preceding sibling, wrapping to the next column when reaching the end of a column.

Auto Grid Vertical and Horizontal change the ordering of children

Children can be reordered by using the alt+arrow key in the tree view, resulting in reordering just like when using a stacking Children Layout.

Alt+arrow changes the order of the selected item in the tree view, updating the positions in the grid

Children treat their particular cell in the grid as their parent, so any sizes or positions will be based on their parent cell. In other words, if a child's Width Units is set to Relative To Parent, the parent in this case is the cell, not the entire Container instance.

Changing Anchor and Dock values results in children being placed relative to their particular cell

The number of cells in a grid is determined by multiplying Auto Grid Cells Horizontal by Auto Grid Cells Vertical. If a container has more children than its total cells and if the container's size does not depend on its children, additional children spill over the bounds of the grid. The following animation shows a 3x3 grid using Auto Grid Horizontal. As more children are added, additional rows are added below the bounds of the grid.

Additional children can create rows or columns outside of the bounds of the grid.

If the container has its Width Units or Height Units set to Relative To Children, then its size may adjust in response to adding more children. For more information, see the Width Units and Height Units pages.

When using Auto Grid Horizontal, the number of columns is fixed, but additional rows can be added beyond the bounds of the container.

When using Auto Grid Vertical, the number of rows is fixed, but additional columns can be added beyond the bounds of the container.

Auto Grid and Width/Height Units

If a container's Children Layout is set to Auto Grid Horizontal or Auto Grid Vertical, it can size itself according to the largest cell by using Width Units or Height Units of Relative To Children. For more information see the Width Units and Height Units pages.

Width Units

Introduction

The Width Units variable controls how a unit is horizontally sized, which may be relative to its parent. By default elements uses Absolute width, where each unit represents 1 pixel of width in absolute terms. When using Absolute, an object ignores its parents' effective width.

Absolute

The following shows a child ColoredRectangle with 50 Absolute Width:

Rectangle with an Absolute Width of 50

Relative to Parent

The following image shows a child ColoredRectangle with -10 Relative to Parent Width, so it sizes itself 10 pixels less wide than its parent.

Rectangle using a Relative to Parent Width value of -10

If an instance does not have a parent, then it uses the canvas size when using a Width Units of Relative to Parent.

Rectangle using 0 Relative to Parent with no direct parent

All relationships between parent and children depend only on the direct parent or child. Grandchildren and grandparents are not considered when performing calculations. For more information, see the Parent page.

Percentage of Parent

The following shows a child ColoredRectangle with 100 Percentage of Parent Width, which means it has 100% of the effective width of its parent. Note that 100 Percentage of Parent is the same as 0 Relative to Parent:

Rectangle using 100% of its parent

If an object does not have a parent, then the width of the canvas is used.

Rectangle using 100% of the screen when it has no direct parent

Ratio of Parent

Ratio of Parent can be used to fill available space or to share available space with other objects using a ratio. It behaves similar to a Height Units of Ratio of Parent, but operates horizontally rather than vertically.

Blue rectangle using a ratio value of 2, next to siblings each using a ratio value of 1

Ratio of Parent is usually used with a parent that has its Children Layout set to Left to Right Stack or Top to Bottom Stack. For more information, see the Children Layout page.

Relative to Children

The following image shows a child ColoredRectangle with 50 Relative to Children Width, which means that it is sized 50 pixels wider than is necessary to contain its children. Since the rectangle has no children, this is the same as having 50 Absolute Width:

Rectangle with a width of 50 Relative to Children, but since it has no children it is 50 units wide

Relative to Children can be used to size an object based on the position and sizes of a parent's children. The following animation shows a container with 0 Relative to Children Width, which means that its effective width is set just large enough to contain its children. Notice that if the children are moved, the parent's effective width adjusts. Both children are considered so the container adjusts its width according to the right-most side of either child:

Moving children can adjust the absolute width of the parent if the parent is using a Width Units of Relative to Children

A non-zero Width when using Relative to Children can be used to add additional padding to a parent container. The following animation shows how changing the Width variable can adjust the absolute width relative to children:

Width is relative to the right-most child when using Relative to Children

Relative to Children results in effective width dynamically adjusting in response to changes on a container's children. The following animation shows a container with Children Layout of Left to Right Stack. Adding additional children expands the container automatically:

Adding children expands the effective width of the parent if the children are positioned in a horizontal stack.

Ignored Width Values

A parent container can ignore its children when it determines its absolute width when using a Width Units of Relative to Children if any of the following are true:

  1. The child's Ignored By Parent Size is true.

  2. The child's width depends on its parent's width. This circular dependency is resolved by the parent ignoring this child.

  3. The child is explicitly positioned outside of the parent's bounds

  4. The child's X Units is Percentage of Parent Width

Child's Ignored By Parent Size is True (1)

If a child has its Ignored By Parent Size set to true, then the parent ignores this child when calculating its own size. For more information, see the Ignored By Parent Size page.

Child Width Depends on its Parent's Width (2)

If a child's width depends on the parent, then the child is ignored by the parent. Once the parent has determined its own width, then the child is sized according to the parent. This type of circular dependency is common when adding background visuals to a container.

For example consider a container with two children - BlueRectangle and YellowRectangle - with the following variables:

  • BlueRectangle X = Pixels from Left

  • BlueRectangle Width Units = Absolute

  • YellowRectangle Width Units = Relative to Parent

Only YellowRectangle depends on its parent.

Since BlueRectangle's absolute width value does not depend on the parent, the parent can use BlueRectangle's absolute width when calculating its own absolute width. Since YellowRectangle depends on the parent, the parent ignores the YellowRectangle. Instead, YellowRectangle depends on the parent container's absolute width for calculating its own absolute width. This in effect creates a situation where BlueRectangle affects the width of both its parent and also its YellowRectangle sibling.

Moving BlueRectangle changes the width of both its parent and also YellowRectangle

Child is Explicitly Positioned Outside of Parent's Bounds (3)

A parent does not consider a child if the child is explicitly positioned outside of the parent's bounds. This can happen if the child's X Units and X values result in the child being drawn outside of the parent's bounds

If a child has X Units of Pixels from Left and its X value pushes the child out of the left of the parent, then the portion that is outside of the left of the parent is ignored. The BlueRectangle in the following image has an absolute width of 50. Its X value is -20, so only 30 pixels are used to determine the parent's effective height.

Parent absolute width is 30 since the BlueRectangle explicitly has 20 of its width set outside of the parent's bounds

Similarly, if a child uses an X Units of Pixels from Right then the parent does not consider the width of any portion which is outside of its bounds. The following animation shows RedRectangle placed outside of the right of the container's bounds with a X Units of Pixels from Right.

RedRectangle not affecting the absolute width of its parent since it is placed outside of the parent's bounds

Notice that if RedRectangle is moved so that it is inside the bounds, it can affect the absolute width of the parent. As RedRectangle is moved into the bounds, the parent grows to accommodate the desired RedRectangle X value.

Moving a child which uses Pixels from Right can make the parent grow to accommodate the child's X value

Child's X Units is Percentage of Parent Width (4)

A parent ignores its child if the child uses an X Units of Percentage of Parent Width because this also creates a circular dependency (parent width depends on child position, child position depends on parent width).

X Units of Percentage of Parent Width result in the child ignored

Relative to Children and Auto Grid Horizontal

If a parent sets its Width Units to Relative to Children, then it must resize itself to contain its children. Normally the width of the entire parent is determined by the child which needs the most space horizontally. If the parent uses an Auto Grid Horizontal layout, then the children control the size of the cells rather than the entire parent. Since all cells must be the same size, the child which needs the most amount of space horizontally determines the width of all cells.

For example, the following image shows a four by four grid, each containing one white rectangle. The first rectangle has an Absolute Width and Height of 100, so each cell is sized to be 100x100. Note that the other rectangles are 50x50.

The largest child determines the width of the cell when the parent uses Relative to Children width

The largest child determines the cell size for all other children. Therefore, if a child is moved or resized so it outgrows its cell, then the parent width adjusts in response.

Resizing or moving a child can result in all cells growing or shrinking

The width of a container is determined by the width of the largest cell multiplied by the number of columns. If the parent contains enough columns to support all of its children, then the Auto Grid Horizontal Cells value is used to determine the number of columns displayed.

For example, the following container has 3 columns and 4 rows, resulting in 12 cells. The width of the grid is based on 3 columns multiplied by the width of the largest cell.

Auto Grid vertical with Width Units Relative To Children

If children are removed from the container, the container's width does not change - Auto Grid Horizontal Cells acts as a minimum number of columns.

Removed children do not shrink the container beyond its minimum number of columns

Since Auto Grid Horizontal Cells acts only as a minimum and not maximum, more children can be added and the container expands to support the newly-added children.

Container expanding as more children are added to the grid

Relative to Children and Text

Setting a Text instance's Width Units to Relative to Children results in the Text object adjusting according to its text contents. In other words if a Text's Width Units is set to Relative To Children, then the words in the Text do not wrap.

For example, setting the Width Units to Relative to Children and setting the Width to 0 results in the Text object automatically adjusting its actual width according to the text it contains.

Text with Relative to Children width results in the contents of the Text instance controlling its size

Percentage of Height

Percentage of Height adjusts the object's effective width so it remains proportional to the effective height value multiplied by the Width value (as a percentage). For example, if a Width value of 200 is entered, then the effective width is 200% (2x) of the height.

The following image shows a child ColoredRectangle with a Width of 200 Percentage of Height. In this image, the Height value is 50 units, so the effective width is 100 units:

Rectangle displaying a width 200% of its height

Percentage of File Width

Sprites can select a Width Unit called Percentage of File Width, which sets the width of the Sprite according to the file that it is displaying. This is the default Width Unit for Sprites.

The following image shows a child Sprite with 200 Percentage of Source File Width, which means it draws two times as wide as its source image:

Sprite using 200 Percentage of File width

When using Percentage of Source File Width, the Sprite's absolute width depends on the Sprite's Texture Width property.

Changing a Sprite's Texture Width adjusts its absolute height when using Percentage of File Width

For more information, see the Sprite Texture Address page.

Maintain File Aspect Ratio Width

Sprites can select a Width Unit called Maintain File Aspect Ratio Width, which sets the effective width of the Sprite so that its aspect ratio matches its source file multiplied by the Width value. Usually Maintain File Aspect Ratio Width is used with a Width value of 100 so that the Sprite shows is source file at the correct aspect ratio.

Svgs also support using Maintain File Aspect Ratio Width. For more information on using Svgs see the Skia Standard Elements page.

When this value is used, a Sprite's Height can be changed resulting in its absolute width also changing.

Changing the Height when using Maintain File Aspect Ratio Width also adjusts absolute width

When using Maintain File Aspect Ratio Width, the Sprite's effective width depends on the Sprite's Texture Width property.

Changing either Height or Texture Width affects the Sprite's effective width

Absolute Multiplied by Font Scale

Absolute Multiplied by Font Scale is a value which multiplies the Font Scale property at runtime with the Width value. This can be used to create widths which are responsive to font scales for devices which may have variable text sizes.

At the time of this writing, the Gum tool always uses a Font Scale of 1, so this cannot be previewed in the tool. However, when a Gum project is loaded at runtime, the runtime may apply a Font Scale value such as using the Text size from Windows.

Width of 100 using Absolute Multiplied by Font Scale results in an absolute width of 100 in the Gum tool

4 - Components

Introduction

Components can contain instances of other components and of standard objects. Examples of components include:

  • Check boxes

  • Buttons

  • Popup Menus

Components can also be simple such as a button or more complex UI elements such as a full Options screen with dozens of instances.

Simple Button Example - Creating the Entity

To understand how components work, we'll create a simple Button component. To do this:

  1. Right-click on the Components folder in Gum and select Add Component

  2. Name the Component "Button"

  3. Drag+drop a ColoredRectangle standard element into the Button component

  4. Drag+drop a Text standard element into the Button component

A single Button Component with ColoredRectangle and Text. Note that the text is white.

Since ColoredRectangleInstance and TextInstance are both white you may not be able to see the Text. Let's change the ColoredRectangleInstance's color:

  1. Select ColoredRectangleInstance

  2. Change Red to 0

  3. Change Green to 0

  4. Keep Blue as 255

Notice that as you change the values, the background on the text box changes from green to white to indicate that the value has an explicit value. The Blue text box keeps a green value since it has not been changed from its default value.

Values backgrounds change from green to white when explicitly set

Now you should be able to see the Text on top of the rectangle:

White text on top of a blue ColoredRectangle

Sizing the colored rectangle

At this point we have made some progress towards creating our first button, but it still needs some work.

First, we're going to adjust the size of the instances inside of our Button component. At this point you can see that the ColoredRectangle (the blue background) is not the same size as the button. Not only do we want to make the blue ColoredRectangle larger, but we also want it to automatically match the Button's size (the dotted outline).

To do this:

  1. Select the ColoredRectangleInstance

  2. Select the Alignment tab

  3. Click the Fill Dock button

Fill Dock expands the ColoredRectangleInstance to occupy its full parent

Alternatively you can adjust the individual values. Keep in mind that using the Alignment tab is the fastest way to get your instances setup. The next section shows all of the changes that the Alignment tab performs for you:

  1. Select the ColoredRectangleInstance

  2. Change Height Units to Relative To Parent

  3. Change Width Units to Relative to Parent

  4. Change Height to 0. This means that the actual height of the ColoredRectangleInstance matches the actual height of its container (the Button Component). Since Height Units is set to Relative To Parent.

  5. Change Width to 0. This means that the actual width of the ColoredRectangleInstance matches the actual width of its parent.

Now the ColoredRectangleInstance automatically matches the Button's actual with and height:

ColoredRectangleInstance fills its parent by matching its width and height

Next we'll position the TextInstance. We'll want to adjust the Text so that it is always centered, and line-wraps with the size of the button.

To do this:

  1. Select TextInstance

  2. Click the Alignment tab

  3. Set Margin to 20

  4. Click the Fill Dock button

Alternatively you can set each individual value on the Text by following these steps:

  1. Select TextInstance

  2. Change its Horizontal Alignment to Center

  3. Change its Vertical Alignment to Center

At this point the Text is vertically and horizontally centered within its boundaries, but we want to have the boundaries centered within the Button. To do this:

  1. Keep TextInstance selected

  2. Change the X Units to Pixels From Center

  3. Change the X Origin to Center

  4. Change X to 0

Now let's make it centered on the Y as well:

  1. Keep the TextInstance selected

  2. Change the Y Units to Pixels From Center

  3. Change the Y Origin to Center

  4. Change Y to 0

Finally, let's make the width of the text match the width of the button. For the Text we'll actually leave a border around the edge so the Text doesn't line wrap right against the edge of the button. To do this:

  1. Keep the TextInstance selected

  2. Change the Width Units to Relative to Parent

  3. Change Width to -40. This means the actual width of the Text is 40 pixels less than the actual width of its container. Since the button is centered this means a 20 pixel border on the left and 20 on the right (20+20=40).

Width and Width Units set explicitly to give the text a margin

Setting the Button Default Variables

Buttons are typically wider than they are tall. To match this common layout, let's set some variables on the Button:

  1. Select the Button component

  2. Change Width to 120

  3. Change Height to 36

Notice that whenever you change these values, the contained objects (text and colored rectangle) adjust automatically.

Text adjusted to be wider than it is tall

Creating Component Instances

Now that we have a component created, we can add instances of this component the same way we have added standard elements. To do this:

  1. Create a new Screen. I'll call mine MainMenu

  2. Drag+drop the Button component into the Screen

We can now resize and position the Button instance. We can reuse our Button component to create multiple instances. Each instance can be adjusted by changing its X, Y, Width, and Height values.

Multiple Button instances in MainMenu

We can change top level variables on the Button such as X, Y, Width, and Height, but we cannot change variables on instances within the Button - all of our buttons currently display "Hello" text.

The next tutorial shows how to use exposed variables to further customize each button instance.

Variable References

Introduction

Variable References allows any variable on an instance or component to reference other variables. These other variables can be on the same instance or component, a different instance, or even variables from a different component.

Component setting its Height relative to its Width

One common use of Variable References is to create a centralized style component which can be referenced throughout a Gum project.

Variables which are assigned through Variable References cannot be directly set on the instance - the value obtained through the reference overwrites any custom value. For example, the reference Height = Width results in Height being read-only and depending on Width. Note that this is using a shorthand variable assignment which is discussed in later sections.

Height is assigned to Width, so it is read only

Variable References result in the following changes

  • Dynamic updating of variables whenever the right side changes

  • Evaluation of the variable reference in tool, explicitly setting the left side

As of February 2025 no runtimes support dynamic variable assignments; however any changes made in the will propgate those changes in the tool and they will appear in the games.

This limitation may change in future versions of Gum. If you need dynamic variable refernces please file an issue on GitHub or make a request in Discord.

Variable references mimic the C# syntax, but provide only a subset of C# functionality. Future versions of Gum may expand supported syntax. If your project requires additional functionality, please post an issue on GitHub, or make a request in the Discord server.

Variable Reference Syntax

Variable References can contain multiple lines. Each line is a separate variable reference. Each variable reference uses the following syntax:

{Variable} = {Components or Screens}/{ComponentOrScreenName}.{Instance}.{Variable}

For example, to assign a Component's X value to a different component's X value, the following syntax could be used:

X = Components/OtherComponent.X

Variable Assignment Reference

X references the X value in OtherComponent. Note that X could be the X value on any component or any instance inside of a component:

X = Components/OtherComponent.X

Spaces are optional around the equals sign, but spaces are not allowed in variable names. The following lines are okay:

Y=Components/OtherComponent.Y
Width = Components/OtherComponent.Width

However, the following is not allowed:

// Spaces are not allowed, so Gum would comment this reference:
X Units = Components/OtherComponent.X Units

Previous versions of Gum included spaces in some variable names. The public release of Gum in February 2025 has removed all spaces to simplify the syntax.

For more information, see the Removal of Variable Spaces page.

Lines can be commented out to disable the reference. If Gum encounters a scripting error, it will automatically comment out lines as well so that you can make corrections:

// This is considered a comment so it will not run
// Neither will this:
// X = Components/OtherComponent.Y

An Instance can reference its own Component's X value by using the qualified name:

X = Components/ComponentContainingThisInstance.X

An instance or component can reference the variable of another instance in the same component by using the name of the instance. The name of the containing component or screen is not required if the instances are both in the same component or screen:

Width = OtherInstanceInSameComponent.Width

Components and instances can reference variables that are contained within instances of other components. In this case the name of the referenced instance is appended to the qualified name of the Screen or Component:

Red = Components/StyleComponent.PrimaryColorRectangle.Red

Elements and Screens inside subfolders can be referenced. The subfolder path is included with forward slashes:

XUnits = Components/ComponentFolder/ComponentInFolder.XUnits

The right side can be a variable in a Screen, although this isn't too common in practice:

Green = Screens/MainMenuGum.ColoredRectangleInstance.Green

Similarly, variables on Standards can also be referenced. This is also quite rare, since this modifying the Standard element also has side effects on every other instance that is of the same type:

YUnits = Standards/Text.YUnits

Although it's common for variables to reference the same variable on a different object (such as X being set to another object's X value), this is not a requirement. For example, the following lines are valid:

Y = OtherInstance.X
Width = Components/OtherComponent.Height

Instances can reference their own variables, but these must be qualified. For example, ColoredRectangleInstance can assign its Width to equal its own Height. Note that Gum will extend shorthand code as shown in a later section:

Width = ColoredRectangleInstance.Height

Variables can be assigned to constant values, essentially locking the value:

X = 100
Text = "Hello"
Visible = true

Math operations can be used in variable assignments. This includes add, subtract, multiply, divide, and parenthesis to control order of operations:

// This evaluates to 17
Y = (1 + 2) * 7 - 4

Math operations can reference both constant values (1, 2, 3) or other variables:

Width = (OtherInstance.Height * 3) + 10

Gum treats the prefixes Components/, Screens/, and Standards/ as special prefixes and does not consider this to be a division operator. Therefore, you should not name variables Components, Screens, or Standards as these are reserved words. Other variable references can freely use the forward slash character to create division.

For example, the following two lines of code show the difference between a simple variable reference assignment and a division operation:

// This is a direct assignment setting X to 
// the X value on Components/OtherComponent:
X = Components/OtherComponent.X
// This is a division operation setting X to
// the result of dividing the CustomVariable by OtherComponent.X
X = CustomVariable/OtherComponent.X

Numeric variable types can be mixed. For example, Red is typically an int value (whole number), while X is a float (supports decimals). Gum automatically casts the variable appropriately:

X = ColoredRectangleInstance.Red
Green = ColoredRectangleInstance.Y

Gum automatically casts any value to a string (text). For example, a Text's Text variable could be assigned to its own Y value:

Text=TextInstance.Y

Strings can be concatenated (combined) using the + operator:

Text="My Position is " + TextInstance.X + ", " + TextInstance.Y

Gum cannot convert unrelated types, including different Units. For example, the following would be commented out by Gum:

//WidthUnits = TextInstance.HeightUnits

Referencing Custom Variables

Variable references can include custom variables, both on the left and right side. Custom variables can be combined with variable references to create flexible layouts. For more information on using custom variables, see the Add Variables page.

Unqualified and Shorthand Assignments

As mentioned above, fully qualified assignments are allowed in any context. For example, a component can reference its own qualified variables:

X = Components/SameComponent.Y

Components do not need to qualify their own variables. They can reference them without any qualification. Therefore, the following variable reference is equivalent to the fully-qualified reference above:

X = Y

Similarly, the following two variable references are equivalent assuming ContainedInstance is part of the component with the reference:

Y = Components/SameComponent.InstanceInComponent.Y
// is equivalent to:
Y = InstanceInComponent.Y

Instances must qualify their own variables as shown in the following code:

X = SameInstance.Y

Gum will automatically qualify assignments when an instance is selected. In other words, X = Y gets qualified to X = SameInstance.Y if SameInstance is the owner of the variable. This automatic qualification makes it easy for an instance to reference its own values. The following animation shows how the Y and Height values become qualified to the instance after tabbing out of the Variable Reference text box.

Tabbing automatically qualifies variables to the selected instance

Complex assignments are automatically qualified as well.

Y, Width, and Height are automatically qualified to the current instance

The left side of an assignment can be omitted if referencing the same variable on another instance or component. For example, by typing OtherInstance.YUnits , Gum automatically expands the reference to YUnits = OtherInstance.YUnits .

OtherInstance.YUnits is automatically prefixed with the text YUnits=

Note that this only works when assigning one variable directly to another variable. Complex assignments will not be prefixed.

Color Expansion

Assigning color values is a common part of styling, so to help with this situation, Gum also expands the "Color" variable into all three components when the Variable References text box loses focus. For example, the following text can be used to assign all three values at once:

Components/Styles.PrimaryColor.Color

When the Variable References box loses focus, this is expanded to the following assignments:

Red = Components/Styles.PrimaryColor.Red
Green = Components/Styles.PrimaryColor.Green
Blue = Components/Styles.PrimaryColor.Blue
Assigning Color expands the variables automatically

Variable References in the Property Grid

As shown above, Variable References can be used to assign one variable to another. If a variable is referenced, then the variable cannot be manually assigned. The Variable Reference takes priority. For example, if an object references the Red, Green, and Blue variables, then those values cannot be manually set on the object. The values appear disabled and text indicates why they are read-only.

Left-side variables become read-only

Obtaining a Qualified Variable Name

Typing a variable name can be tedious, especially when referencing a variable in a different Screen or Component. Qualified variable names can be obtained by right-clicking on the variable name in Gum and selecting the Copy Qualified Variable Name option. This can then be pasted in the Variable References box of any other object.

Right-click to obtain the qualified name of a variable

Example - Creating Color Styles

The following example creates a Styles component which contains a color value which is referenced by objects in a MainMenu Screen.

Any component can serve as a centralized location for styling, but we use the name Styles by convention.

The Styles component can contain as many objects as are needed to style your project. Additional objects can be added to help indicate how things are used visually. For example, we include a Text object to indicate the red color is the Primary Color.

The color value can be referenced by any other object including objects in different screens or components.

To add a variable reference:

  1. Select the object which should have a variable reference

  2. Click inside the Variable References text box

  3. Type the variable reference. The format of the variable reference is {VariableName} = {Components or Screens}/{ComponentOrScreenName}.{InstanceName}.{InstanceVariable} For example, to reference the Red variable in the Styles component, the syntax is Red = Components/Styles.PrimaryColor.Red

Since color values have three components (Red, Green, and Blue), then all three components must be referenced. In this example, the background can reference the three colors with the following assignment text:

Red = Components/Styles.PrimaryColor.Red
Green = Components/Styles.PrimaryColor.Green
Blue = Components/Styles.PrimaryColor.Blue
Background instance referencing the Styles.PrimaryColor color values

The types of the objects that contain the Variable References or which are being referenced do not matter. For example, a Text object could have its color values depend on the color values defined by a ColoredRectangle in the Styles component.

TextInstance also referencing the PrimaryColor color values

Once Variable References are set, the referenced instances (instances in Styles) can be changed and the changes will immediately propagate throughout the entire project.

Changing the source color values updates all objects referencing the Style.PrimaryColor values

Height Units

Introduction

Height Units controls how a unit is vertically sized, which may be relative to its parent. By default most types uses Absolute height, where each unit represents 1 pixel of height in pixels. When using Absolute, an object ignores its parent's Height.

Absolute

The following shows a child ColoredRectangle with 50 Absolute Height:

Rectangle with an Absolute height of 50

Text instances which use an Absolute height of 0 size themselves to be the height of their contained text. This behavior will likely change in future versions of Gum so this combination is not recommended. Instead, to size a Text instance according to its contained text, Set Height Units to Relative to Children.

Relative to Parent

The following shows a child ColoredRectangle with -10 Relative to Parent Height, which means is sized 10 pixels less tall than its parent.

Rectangle using a Relative to Parent height value of -10

All relationships between parent and children depend only on the direct parent or child. Grandchildren and grandparents are not considered when performing calculations. For more information, see the Parent page.

Percentage of Parent

The following shows a child ColoredRectangle with 100 Percentage of Parent, which means it has 100% of the height of its parent. Note that 100 Percentage is the same as 0 Relative to Parent:

Rectangle using a Percentage of Parent value of 100

Ratio of Parent

Ratio of Parent can be used to fill available space or to share available space with other objects using a ratio.

Ratio of Parent Height Units

The simplest case is a single child in a container with its Height Units set to Ratio of Parent.

Ratio of Parent set to 1

In this case the blue ColoredRectangle has no siblings (its parent has no other children), so it occupies the entire parent height. If a second child is added (by copy/pasting the existing child), then each child is given 1 ratio value, which means each is 1/2 of the size of the entire parent.

Two stacked ColoredRectangles, each with a height ratio of 1

To better visualize the effect of ratio, it's common to set the parent's Children Layout to Top to Bottom Stack, and to give each child a different color as shown in the following image.

Stacked children with a Height Units of Ratio of Parent

As more children are added, each child's height is adjusted to make room for the new children.

Children shrink to make room for new ColoredRectangles

Ratio values are distributed among all siblings using Ratio of Parent proportionally. The image above shows four siblings, each given 1/4 of the ratio. If one of the the ratios changes (such as by increasing the second sibling's Height value to 3), then all siblings adjust in response to this change.

Red ColoredRectangle with a Height value of 3

In this case, the total ratio is 6 (1 + 3 + 1 + 1), so the red is given 3/6 (1/2) of the parent's height, while each of the others is given 1/6 of the parent's height.

Values of 0 are supported, resulting in the object drawing with an absolute height of 0.

ColoredRectangle with a Ratio of Parent Height of 0

Ratio of Parent is calculated after accounting for the height of children which are using absolute height. For example, if the height of the first child is 80 with a Height Units of Absolute, then the other three shrink to give the first the necessary room.

Absolute ColoredRectangle with 80 Height

This effect can also be seen by adjusting the height using the handles.

Adjusting Height changes all sibling heights

Gum ignores invisible objects when calculating available space for Ratio of Parent units. Therefore, if a sibling is invisible, Gum treats it as if it has 0 height which allows all other ratio siblings to expand.

Toggling visibility removes an object from the height ratio calculation

Ratio of Parent also respects Stack Spacing. A Stack Spacing value greater than 0 removes the available space for all children with a Height Units of Relative to Parent.

Increasing Stack Spacing reduces the available ratio space for all children

Relative to Children

The following image shows a child ColoredRectangle with 50 Relative to Children Height, which means that it is 50 pixels taller than is necessary to contain its children. Since the rectangle has no children, this is the same as having 50 Absolute Height:

Rectangle using Relative to Children Height of 50, resulting in an absolute height of 50 since it has no children

Relative to Children can be used to size an object based on the position and sizes of a parent's children. The following image shows a container with 0 Relative to Children Height, which means that its height is set just large enough to contain its children. Notice that if the children are moved, the parent's height adjusts. Both children are considered so the container adjusts its height according to the bottom-most side of either child:

Moving children can adjust the absolute height of the parent if the parent is using a Height Units of Relative to Children

A non-zero Height when using Relative to Children can be used to add additional padding to a parent container. The following animation shows how changing the height can adjust the absolute height relative to children:

Height is relative to the bottom-most child when using Relative to Children

Ignored Height Values

A parent container can ignore its children when it determines its own height when using a Height Units of Relative to Children if any of the following are true:

  1. The child's Ignored By Parent Size is true.

  2. The child's height depends on its parent's height. This circular dependency is resolved by the parent ignoring this child.

  3. The child is explicitly positioned outside of parent's bounds

  4. The child's Y Units is Percentage of Parent Height

Child's Ignored By Parent Size is True (1)

If a child has its Ignored By Parent Size set to true, then the parent ignores this child when calculating its own size. For more information, see the Ignored By Parent Size page.

Child Depends on Parent Height (2)

If a child's height depends on the parent, then the child is ignored by the parent. Once the parent has determined its own height, then the child is sized according to the parent. This type of circular dependency is common when adding background visuals to a container.

For example consider a container with two children - BlueRectangle and YellowRectangle - with the following variables:

  • BlueRectangle Y = Pixels from Top

  • BlueRectangle Height Units = Absolute

  • YellowRectangle Height Units = Relative to Parent

Only YellowRectangle depends on its parent.

Since BlueRectangle's absolute height value does not depend on the parent, the parent can use BlueRectangle's absolute height when calculating its own absolute height. Since YellowRectangle depends on the parent, the parent ignores the YellowRectangle. Instead, YellowRectangle depends on the parent container's absolute height for calculating its own absolute height. This in effect creates a situation where BlueRectangle affects the height of both its parent and also its YellowRectangle sibling.

Moving BlueRectangle changes the height of both its parent and also YellowRectangle

Child Explicitly Positioned Outside of Parent's Bounds (3)

A parent does not consider a child if the child is explicitly positioned outside of the parent's bounds. This can happen if the child's Y Units and Y values result in the child being drawn outside of the parent's bounds.

If a child has Y Units of Pixels from Top and its Y value pushes the child out of the top of its parent, then the portion that is outside of the top of the parent is ignored. The BlueRectangle in the following image has an absolute height of 50. Its Y value is -20, so only 30 pixels are used to determine the parent's height.

Parent absolute height is 30 since the BlueRectangle explicitly has 20 of its height set outside of the parent's bounds

Similarly, if a child uses a Y Units of Pixels from Bottom then the parent does not consider the height of any portion which is outside of its bounds. The following animation shows RedRectangle placed outside of the bottom of its bounds with a Y Units of Pixels from Bottom.

RedRectangle not affecting the absolute height of its parent since it is placed outside of the parent's bounds

Notice that if RedRectangle is moved so that it is inside the bounds, it can affect the absolute height of the parent. As RedRectangle is moved into the bounds, the parent grows to accommodate the desired RedRectangle Y value.

Moving a child which uses Pixels From Bottom upward can make the parent grow to accommodate the child's Y value

If a child is a Text instance using a Y Origin of Baseline and a Y Units of Pixels from Bottom, then portions of the text which fall below the baseline are ignored by the parent's height.

Portions of the text are ignored when calculating heights

Child Y Units is Percentage of Parent Height (4)

A parent ignores its child if the child uses a Y Units of Percentage of Parent Height because this also creates a circular dependency (parent height depends on child position, child position depends on parent height).

Y Units of Percentage of Parent Height results in the child ignored

Relative to Children and Auto Grid Vertical

If a parent sets its Height Units to Relative to Children, then it resizes itself to contain its children. Normally, the height of the entire parent is determined by the child which needs the most space vertically. If the parent uses an Auto Grid Vertical layout, then the children control the size of the cells as well as the entire parent. Since all cells must be the same size, the child which needs the most amount of space vertically determines the height of all cells.

For example, the following image shows a four by four grid, each containing one white rectangle. The first rectangle has an Absolute Width and Height of 100, so each cell is sized to be 100x100. Note that the other rectangles are 50x50.

The largest child determines the height of the cell when the parent uses Relative to Children height

The largest child determines the cell size for all other children. Therefore, if a child is moved or resized so it outgrows its cell, then the parent height adjusts in response.

Resizing or moving a child can result in all cells growing or shrinking

The height of a container is determined by the height of the largest cell multiplied by the number of rows. If the parent contains enough rows to support all of its children, then the Auto Grid Vertical Cells value is used to determine the number of rows displayed.

For example, the following container has 4 columns and 3 rows, resulting in 12 cells. The height of the grid is based on 3 rows multiplied by the height of the largest cell.

Auto Grid Horizontal with Height Units Relative To Children

If children are removed from the container, the container's height does not change - Auto Grid Vertical Cells acts as a minimum number of rows.

Removed children do not shrink the container beyond its minimum number of rows

Since Auto Grid Vertical Cells acts only as a minimum and not maximum, more children can be added and the container expands to support the newly-added children.

Container expanding as more children are added to the grid

Relative to Children and Text

The term "children" can refer to:

  • Instances added to a parent, such as ColoredRectangles added to a Container

  • Individual letters in a Text instance - each letter and line of text can expand the height of its parent

The following animation shows a Text instance which has its Height Units set to Relative To Children. As more lines of text are added, the Text automatically expands in size.

Adding lines of text to a Text instance expands its height if its Height Units is set to Relative To Children

The height of a Text instance using Relative to Children depends on the number of lines displayed by the Text instance and the maximum line height given the current font properties. Therefore, the height of a Text stance remains the same regardless of the contents of a single line.

For example, the following image contains multiple Text instances. Each has a single line of text, but the line of text differs in the height of each character. Notice that the texts are all the same height even though the contents of their lines differ.

Texts with the same height despite having different string

We can observe the absolute height of a Text instance by mousing over one of the handles for resizing vertically.

Text which has an absolute height of 41 pixels

In this case, the height is 41 pixels tall. This is based on the lineHeight as defined on the .fnt file. The image above is using an Arial 36 font which has a lineHeight value of 41 pixels.

Font36Arial has a lineHeight of 41.

Percentage of Width

Percentage of Width adjusts the object's effective height so it remains proportional to the Width value multiplied by the Height value (as a percentage). For example, if a Height value of 200 is entered, then the effective height is 200% (2x) of the Width.

The following image shows a child ColoredRectangle with a Height of 200 Percentage of Other Dimension. In this image, the Width value is 50 units, so the effective height is 100 units:

Rectangle using Percentage of Other Dimension Height of 200

Percentage of File Height

Sprites can select a Height Units called Percentage of File Height, which sets the height of the Sprite according to the file that it is displaying. This is the default Height Units for Sprites.

The following image shows a child Sprite with 200 Percentage of Source File Height, which means it draws two times as tall as its source image:

Sprite using Percentage of File Height of 200

This value depends on the Sprite's Texture Height property, so changing Texture Height also changes the Sprite's absolute height.

Changing a Sprite's Texture Height adjusts its absolute height when using Percentage of File Height

Maintain File Aspect Ratio Height

Sprites can select a Height Unit called Maintain File Aspect Ratio Height which sets the height of the sprite so its aspect ratio matches its source file multiplied by the Height value. Usually Maintain File Aspect Ratio Height is used with a Height value of 100 so that the Sprite shows is source file at the correct aspect ratio.

Svgs also support using Maintain File Aspect Ratio Height. For more information on using Svgs see the Skia Standard Elements page.

When this value is used, a Sprite's Width can be changed resulting in its absolute height also changing.

Changing the Width when using Maintain File Aspect Ratio Height also adjusts absolute height

When using Maintain File Aspect Ratio Height, the Sprite's absolute height depends on the Sprite's Texture Height property.

Changing either Width or Texture Height affects the Sprite's absolute height

Categories

Introduction

Categories can be used to organize similar states into one group (such as a button's Pressed and Unpressed states).

A category can contain one or more states. States within a category have special behavior:

  1. If one state in a category explicitly sets a variable (such as X), then all other states in that category will also explicitly set the variable.

  2. Each category can be set individually on an instance of a component or standard element. In other words, if a component has two categories, each category can be assigned to a state within that category independently.

Creating Categories

To create a new category:

  1. Select a Screen, Component, or Standard element which should contain the new category

  2. Right-click in the States tab in an empty space

  3. Select the Add Category item

  4. Enter a name for the new category

After the new category is created it appears in the States tab as a folder.

Adding States to a Category

To add states to a category:

  1. Right-click on the desired category

  2. Select Add State

  3. Enter a name for the new state

Once the state has been created it can be selected and variables can be changed to add them to the new state.

Categories Create Variables

Once a category is created, the screen, component, or standard element which contains the category is automatically given a variable for that category type. This variable can be assigned on the element itself or on instances of the element.

For example, consider a component with a category named ExampleCategory with two states: State1 and State2.

This component is given a variable named Example Category State.

This value can be assigned in the default state, making the selected state automatically set by default on the component.

For example, the DefaultComponent can select State1 as its Example Category State.

Doing so results in this value automatically being selected on new instances of the DefaultComponent.

States Set by Other States

As mentioned above, once a state is created, it adds a variable to the component. This variable behaves like any other variable including being able to be set by other states.

For example, consider a component with the following categories and states:

  • ColorCategory

    • Bright

    • Dark

  • SizeCategory

    • Big

    • Small

These states can be combined in a new category. For example, a category called CombinedCategory can be created which can include states such as BrightBig or DarkSmall which in turn sets category variables.

Explicit Values Across States in a Category

Normally, when a new category is created and new states are added, all states are empty - they do not assign any variables. The value displayed in the properties window is inherited from the default state.

For example, the following image shows a component with a state called State1 with no variables explicitly assigned. Notice all values are green:

As mentioned in the introduction, if a variable is explicitly set on one state in a category, then all other states in that category will that same variable set to its default. For example, if we set the X variable in the LeftSide state, the X variable in the RightSide state will become explicitly set (black instead of green).

Once the X variable is set on one state in a category, all other states in the same category will automatically have this value set - even new states:

Removing Variables from Categories

Variables can be removed from states, but this removal must be done at the category level rather than at the individual state. Doing so will remove all variables from all states within a category. To remove a variable in all states in a category:

  1. Select the category itself (not the state)

  2. Click the "X" button next to the variable

  3. Confirm that you would like to remove the variable. Warning: this will remove the variable from all contained states.

This will remove the assignment of the variable from all states in the category.

Right click Add Category item
Newly-created category
Right click Add State item
ExampleCategory with two states
Example Category State variable
Example Category State assigned by default
States setting variables created by other categories
Setting X on LeftSide also sets X on other states
New state automatically having variables set