Forms vs Gum in Code
Last updated
Last updated
FlatRedBall Forms is a set of classes which are used to give UI controls automatic behavior. When using FlatRedBall Forms, your code has access to the FlatRedBall Forms object (such as Button) as well as the Visual for the Forms object (such as the component DefaultForms/Button). Since your code has access to both the Forms and Gum object, some confusion may arise about which object to interact with in code.
This guide discusses the relationship between the Forms and Gum objects, and provides some guidelines to determine whether to interact with one of the other.
The most important concept here is - some components in your project are Forms types, and some are not. Only Forms-implementing component instances appear in the Forms property, but all instances appear in the GumScreen property.
To understand how Forms and Gum objects interact, we will consider a simple example - a Screen with a single Button. The following image shows a default Button instance in a Gum screen:
In this example, the MenuScreenGum is loaded by the FlatRedBall screen MenuScreen.
We can access both the Gum and Forms objects in Visual Studio as shown in the following code. Keep in mind that every Screen with Gum and Forms objects will have GumScreen and Forms properties. These make it easy to access objects the same way no matter which Screen you are working on:
Notice that setting width and height modifies the same object at runtime - it appears as a square. Also, filling in the two click handlers would result in both handlers being called when the button is clicked.
You may be wondering - which object should I access in code? The answer is - usually it's best to use the Forms object. If you end up needing to make changes to the Gum object (such as to change its position or size), it's worth considering whether this change should actually be done in code. Most of the time these changes should be performed in the Gum tool.
FlatRedBall.Forms objects are wrappers around Gum objects. For example, in the example above we have a Forms.ButtonInstance. This object has a reference to the Gum object. The Forms object automates behavior so that the Gum object behaves like a UI element. For example, the Forms Button object automatically modifies the state of the button in response to cursor hovers and clicks. No custom code is necessary to achieve this behavior.
This behavior is convenient, but it is not particularly complex - at least not conceptually. The Forms object is responsible for detecting if the cursor is hovering over the button, or if the left mouse button is pressed. If so, the Forms object modifies the state of the button. These states are part of the default Button control, and can be inspected (and modified) in Gum.
The Forms Button logic is responsible for setting the button's state, and it will do so in response to any UI behavior. Therefore, manually setting the Gum object's state is not recommended - it will be over written by the Forms object as shown in the following code and animation:
Notice that the state is not immediately changed, but rather only when the mouse moves over the button. Once the mouse hovers over the button, its state changes immediatelz. After the mouse leaves the button, the state is reverted to Enabled. Setting the state through the Gum object can produce confusion. For example, a button may appear pushed or disabled if the state is manually assigned; however, the actual behavior of the button will not match a disabled state. Therefore, the button's state (specifically the CurrentButtonCategoryState) is controlled by the Forms Button object. The Forms Button object will modify the state according to standard button behavior, so custom code should not modify the Gum button's state.
The Forms property in FlatRedBall Screens contains properties for all Forms objects in the Gum screen, and only the Forms objects. Therefore, any object that is part of the Gum screen which is not a Forms type (such as Button or TextBox) does not appear in the Forms property.
For example, consider the following screen in Gum:
The left column consists of Forms controls: a Button, ListBox, and TextBox. The right column consists of instances of Gum objects which do not implement any Forms controls: a Text, ColoredRectangle, and Container.
In code, the Forms property only contains references to the Gum-implementing instances. Therefore, the following code is valid: