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...
Gum is an open source project so you can run it from source instead of running the pre-compiled project.
Download the source file from GitHub
If you downloaded the .zip file from the GitHub main page, unzip the file
If you downloaded the file through a Git client, be sure to be on the master
branch
Locate the Gum.sln file
If you downloaded the .zip, it is in the root folder of the zip
If you cloned the repository, it is at the root of the Gum folder
Double-click it to open Visual Studio, or open Visual Studio and load the .sln
Run the build configuration in "x86". The build configuration may default to "Mixed Platforms". If you do not change it Gum will not compile.
If your project depends on plugins, be sure to build solution, rather than pressing F5. This guarantees that all plugins are built and copied correctly.
The Categories member provides more detailed control over a DataUiGrid. The easiest way to work with a DataUiGrid is to assign its Instance and let it automatically create UI for all public members. Working with Categories requires more code but gives the most flexibility in setting up a grid.
The following makes the grid only show a single value called "Some Value" which always has a value of 10. An actual implementation may modify some backing variable.
The default behavior for DataUiGrid is to reflect properties from the assigned Instance. When the Instance is assigned, the Grid automatically populates its Categories with members based on reflection.
Properties which have the System.ComponentModel.CategoryAttribute
will be categorized according to the category assigned. Otherwise, properties will be put in the Uncategorized category.
By default all public fields and properties are displayed in a DataUiGrid. To control which properties are shown, the categories can be cleared, and individual InstanceMembers can be added for the desired properties.
For example, the following code clears the properties, and shows only X, Y, and Z:
The AnimateSelf method performs .achx animation logic, advancing the displayed frame on the calling GraphicalUiElement and its children. This call is recursive, so it is typically only called on the root GraphicalUiElement (such as the current Screen).
The following shows how to call AnimateSelf on a GraphicalUiElement. Typically this is called every frame in activity. For example, this code shows how to animate a GraphicalUiElement in a MonoGame project:
AnimateSelf is called automatically in FlatRedBall projects in generated code.
This page discusses all of the classes in Gum at a high level to give you an understanding of how they relate to each other.
The following hierarchy shows a typical (although small) Gum project:
Gum Project Save
ScreenSave
InstanceSave
InstanceSave
StateSave
VariableSave
VariableSave
VariableSave
ScreenSave (etc...)
ComponentSave
InstanceSave
StateSave
VariableSave
VariableSave
VariableSave
ComponentSave (etc...)
StandardElementSave
StateSave
VariableSave
VariableSave
Notice that GumProjects contain ScreenSaves, ComponentSaves, and StandardElementSaves. ScreenSaves, ComponentSaves and StandardElementSaves all share the same base class: ElementSave. Therefore, a lot of Glue code will work with ElementSaves rather than the specific derived type.
ElementSaves can contain instances, and each instance is of type InstanceSave. Therefore, if you wanted to print out information about all of the instances in a given screen you might do something like this:
The DataUiGrid is similar to Winforms PropertyGrid - a reflection-based UI object which can be used to display the properties on objects in real-time. It is used for the properties on Gum objects, but is written to be general purpose to be used in any applications.
It is included in the WpfDataUi.dll file which is part of Gum, so this library can be pulled out and used in any other application.
The DataUiGrid can be used with reflection or its Categories can be manually populated. Using reflection is easier to set up, but does not provide as much flexibility. Manually building up Categories takes more work, but provide the most flexibility.
The following references are needed for displaying the DataUiGrid:
PresentationCore
PresentationFramework
System.Xaml
WindowsBase
To add a grid to your XAML you'll need to:
If using .NET 6+, add the following using:
If using .NET 4.7, add the following using:
Add the following inside a layout container (like a Grid):
You can construct a grid in code just like any other WPF control.
To use the grid in code you simply need to set its Instance member to an instance object you want to view. For example:
This will produce a grid which looks like this:
Alternatively the Instance property can be data bound as shown in the following XAML:
Gum is an open-source tool which enables you to pull code for any other project, or to make modifications so that the tool fits your needs.
Gum uses the following technologies:
.NET 4.6 (included with Visual Studio)
Windows Forms (included with .NET 4.0)
XNA Game Studio 4.0
For information on running from source, see .
For information on how to write Gum plugins, visit this page:
CanvasHeight is a static property which tells the Gum layout engine the size of the canvas. This is used for layouts on GraphicalUiElements which have no parent.
CanvasHeight and CanvasWidth are typically assigned to the height and width of your canvas. This can depend on the development environment. These values are used for layouts, especially layouts which depend on the canvas (or window) width and height.
Setting these values does not automaticaly cause all GraphicalUiElements to perform their layout calls. If these values are changed then any GraphicalUiElements which have no parents should have their Layout method called. Setting properties on a GraphicalUiElement (such as changing WidthUnits) may also perform a layout.
If your game is not zoomed, then the CanvasWidth and CanvasHeight should match the graphicsDevice width and height as shown in the following code:
If responding to a window resize or zoom change you may need to also call UpdateLayout on any objects which do not have parents. Usually this is a single root object, as shown in the following code:
The BlendState property allows a GraphicalUiElement to blend with what is drawn before it. BlendStates can be used to control both color and alpha blending. Most games do not need to modify BlendState, and coverage of BlendStates is beyond the scope of this documentation.
The Gum BlendStates type mimics the XNA (MonoGame) BlendState. For more information see on BlendState, see the MonoGame BlendState API reference:
For examples of custom BlendStates, see this post:
By default Gum objects render directly to the back buffer, so the alpha value of the back buffer does not matter.
If you are rendering to a render target, then you may want to modify the blend state so that the object being renders adds to the alpha. The following code shows how to do this:
The Children collection contains the direct descend children of the GraphicalUiElement. An instance's children will report the instance as their parent.
Note that Screen GraphicalUiElements have null
for Children. The reason is because Screen GraphicalUiElements do not have a position or size - they are merely containers for children without providing any layout information. Therefore, to access the items that a Screen contains, see the ContainedElements property.
This property returns the elements that this contains. This should be used if the GraphicalUiElement represents a Gum screen. Note that the ContainedElements does not respect hierarchy - all contained instances are contained here whether they have a parent or not. Therefore, to obtain only the top-level instances, the Parent property should be checked.
The Camera object is used to adjust the position of all objects in a game and provide zooming capabilities. By default the camera is positioned at 0,0, so all objects are drawn in screen space. Games which need to render objects in world space can do so by applying camera offsets.
By default the Camera's position is at X=0 and Y=0, with the top-left of the Camera defining its position. If the camera moves, then all Gum objects appear to move in the opposite direction. For example, increasing the Camera's X value results in the camera "moving" to the right, resulting in objects in screen moving to the left.
The following code shows how to move objects in response to the MouseState:
By default the Camera's Zoom value is set to 1. This Zoom value applies a global zoom to all drawn UI. This can be adjusted to make all UI bigger.
The following code shows how to zoom in and out.
Note that the text that is positioned along the right and bottom does not update its position in response to the zoom. The reason for this is because the canvas size has not been adjusted.
This can be fixed by also adjusting the canvas as shown in the following code. Note the following code assumes a default width of 800 and height of 600:
The GetAbsoluteY method returns the absolute distance (in pixels) from the top-left of the screen to the top-left of the GraphicalUiElement, regardless of the GraphicalUiElement's Y Units or Y Origin.
For examples, see GetAbsoluteX.
ApplyState can be used to apply a state (StateSave) to a GraphicalUiElement. States can be set by direct StateSave reference, or by unqualified name. Direct StateSave assignment supports states defined in Gum or dynamically created states.
GetChildByNameRecursively returns a GraphicalUiElement by the argument name. This method is recursive so it searches the entire child hierarchy to find a child. If no match is found, null is returned.
Note that this performs a , returning the first instance found. Therefore, if multiple items exist with the same name, this may result in confusion.
The following code can be used to find a Text by the name TextInstance and set its Text property to "You found me":
The IDataUi is an interface that is used by the (WpfDataUi.DataUiGrid) class to display data. This interface must be implemented by any controls which are used in the (WpfDataUi.DataUiGrid). The WpfDataUi library contains a number of built-in controls which implement the IDataUi interface, but it can easily be extended to support more controls.
To create a custom display:
Add a new User Control (WPF)
In the codebehind file, implement the IDataUi interface
This newly-created control can be used in a WpfDataUi grid by assigning the property.
The GumProjectSave object is a serializable object representing a Gum project. Specifically, the GumProjectSave object can directly serialize to the .gumx file format. The GumProjectSave provides access to all Screens, Components, and Standard Elements. Typically the GumProjectSave is accessed through the ProjectState singleton object.
The following code loops through all screens, components, and standard elements in the current project and adds their names to a list of strings:
The GraphicalUiElement class represents any visual element in the Gum runtime. An instance of a GraphicalUiElement exists for every instance of the base rendering types (such as ) as well as instances of components. When loading a .gumx file in a project (such as a MonoGame or FlatRedBall project), each Screen is also a GraphicalUiElement.
The InstanceMember class is used in the DataUiGrid's Categories to control which properties are displayed and how the user can interact with those properties.
InstanceMembers can be created manually or automatically. For more information on using InstanceMembers in a DataUiGrid, see the DataUiGrid pages and its subpages.
Layers provide the ability to sort renderable objects, to independently control zoom, and to keep objects drawn in screen space even if the Camera's X or Y has changed.
The following code shows how to create a Layer:
This code creates a new Layer which draws on top of unlayered objects, and on top of all previously-added layers.
To add a renderable (such as a GraphicalUiElement) to a layer, the AddToManagers method takes a second parameter for the layer. The following code shows how to add a newly-created GraphicalUiElement to a Layer:
All children within a layered renderable also draw on the same layer.
LayerCameraSettings can be used to override default behavior. If no LayerCameraSettings instance is created, then a Layer's zoom and screen-space behavior matches all unlayered objects.
The following code creates LayerCameraSettings which keep all objects on the layer in screen space regardless of the Camera's position:
LayerCameraSettings can be used to offset all renderables on a layer independently. For example, the following LayerCameraSettings results in every object offset by 100 pixels to the right:
The example above results in 100 pixel offsets added to the camera's position. If a layer has its IsInSceenSpace property set to true, then the offset is absolute and ignores the camera's position. For example, the following code offsets all objects by 50 pixels on the Y axis (down) relative to screen space (ignoring Camera position);
The SinglePixelTexture is a reference to a Texture2D which is used to draw solid-colored Gum objects such as ColoredRectangle (renderable type SolidRectangle).
By default the SinglePixelTexture is constructed at runtime in-memory, but this can introduce a large number of rendering state changes when rendering multiple objects.
For performance reasons, the single pixel texture should be a PNG which also has other art in your Gum project. Ideally your project should have just one large PNG which includes a single pixel texture, all fonts, and all other sprites used in Sprite and NineSlice instances.
To assign the SinglePixelTexture, you must access the Renderer. This can typically be accessed through the default SystemManagers as shown in the following code:
The IPositionedSizedObject interface is the interface used by all visual objects in the RenderingLibrary, and it is also used by the GraphicalUiElement object.
The SelectedState class gives you information about what the user has selected in the app. This includes which ElementSave (that is ScreenSave, ComponentSave, or StandardElementSave)/InstanceSave/StateSave is selected.
To get the current ScreenSave:
To get the current InstanceSave:
An InstanceSave represents an instance in Gum. InstanceSave only stores two pieces of information:
The name of the instance
The base type of the instance
All InstanceSaves in Gum will be contained in an . Information about the InstanceSave's variables (such as its position or size) is not stored directly on the InstanceSave. The reason for this is because InstanceSaves have variables which depend on . In other words, an InstanceSave may be at X=0 in one state, and at X=100 in another state.
Therefore, all variables values that define the InstanceSave are stored in states within the InstanceSave's container .
In this pic the Screen1 ScreenSave has 3 InstanceSaves: 1. TextInstance 1. ColoredRectangleInstance 1. ColoredRectangleInstance1
The following code shows how to access the X value of an ElementSave as defined in the default state of its container.
The SpriteRenderer class is responsible for performing MonoGame/FNA-based rendering. It exposes an interface similar to SpriteBatch, but it provides additional functionality including storing a stack of states and providing information about state changes which can be useful for diagnostics.
The SpriteRenderer lives as an object in the Renderer class and can be accessed through the Renderer instance. For example, you can access the SpriteRenderer as shown in the following code:
A VariableSave represents a single variable on an object, such as its X or Y value.
VariableSaves can be of any type, can contain any value, and can hold values either on the Component itself or on a contained instance.
By default an instance does not own its variables. Rather, variables exist inside of states which can affect the instance. For example, consider the following image:
In this case, the GameScreenGum is the owner of the variable, not TextInstance. The GameScreenGum has the following:
GameScreenGum (ScreenSave)
Default State (StateSave)
Variables (List<VariableSave>)
TextInstance.Text = "Hello from Gum" (VariableSave)
This relationship may seem complicated, but it is requires because the Screen can create multiple StateSaves (including StateSaves inside of other StateCategorySaves). The actual value of the variable depends on which StateSave is being considered.
Furthermore, the effective value of a variable (such as "Hello from Gum") can be the result of variables being assgined at multiple levels.
For example, consider that the TextInstance in the example above is setting its text to "Hello from Gum" at the ScreenSave level. This value overrides the Text value which is assigned on the standard Text object.
The following lists the levels where variables can be assigned:
Base standard (such as on the Text under the Standard folder)
On an instance in a component (such as a Text instance in a Button component)
On an instance of a component through an exposed variable (such as a Button instance setting its text to "Quit" in a GameScreen)
In a derived class (such as a derived ExitButton which inherits from Button, but sets the TextInstance.Text to "Exit")
In a categorized state (such as a DarkMode state changing the color of a Button's background)
The hierarchy of which variables take precedence over other variables can be complicated which is why Gum provides a way to get the effective value for a variable.
The GetValueRecursively method provides a way to get the effective value for an object given a state. For example:
The GetAbsoluteX method returns the absolute distance (in pixels) from the top-left of the screen to the top-left of the GraphicalUiElement, regardless of the GraphicalUiElement's X Units or X Origin.
To detect whether the mouse is ove ra GraphicalUiElement, the absolute properties can be used. This code does not assume a paritcular API for mouse coordiantes.
LastFrameDrawStates is an IEnumerable for the draw states used in the previous draw call. This can be used to find performance problems and isolate what may be causing state changes.
The following code can be used to output state changes to the Output window in Visual Studio