The Layer Tree
Although it is hidden at first, the underlying structure that powers the controller’s menus and components is called the "Layer Tree". For most people, this is initially an advanced concept, but it's extremely powerful and well worth understanding. Think of it like Photoshop for controller configuration: Different layers can be visible or invisible, and depending on that, different Behaviors are visible on your controller. We will later explore how these visibilities can be controlled by various Conditions, but for now, let's take a closer look at how the tree works.
Tip: The tree is hidden by default. Check this page to see how to open it: Configurator Layout
The Inverted Tree
When viewing the tree, you will notice that it doesn’t unfold like hierarchies in other applications, such as file browsers. This is because we are looking at the tree from above, just like viewing the controller. Layers and behaviors on top will be visible first, while those further down may be covered.
The tree’s Root Layer is the base at the bottom. Layers can be opened and collapsed to show their sub layers (branches).
Multiple Files Make Up the Tree
The Tree can be a combination of one or more layer files. The root layer is always defined by the current Reactor project, but it can include other files that get appended to the layer that includes them. To add a layer file, use the "Included Layer File" section in the layer's inspector window. When viewing the tree, you can identify where other files have been included.
Having the tree split into separate files allows for the reuse of configuration parts in other places. This is sometimes referred to as Snippets. In our default configuration, this concept is essential, allowing for quick switching of sub-configurations like Tally Forwarding or Routing Triggers. For building most custom configurations, we recommend not splitting it into multiple files, as this tends to increase complexity.
Layer Visibility and Behaviors
In the tree, every layer can have an Active-If condition. Depending on this condition, the layer is either active or hidden. When viewing the tree in the configurator, you can check if a layer is currently visible by looking at the blue border on the left side. If the border is visible, the layer is active; if not, it is hidden.
When a layer is hidden, all its elements are also hidden. Behaviors defined on the layer, variables, sub layers, virtual triggers, layer scripts, and other elements are hidden or disabled from the controller.
In the simplified example below, the root layer defines a Behavior called Behavior1. Since layer 2 above it redefines the behavior, the one shown on the controller is the one defined on layer 2, as it is higher up in the tree. Behavior2 on the other hand is not redefined, so the definition on the root layer is the active one.
Tree Elements
Layers in the tree include the definition of every other configuration element. These include:
- Behaviors
- Variables
- Virtual Triggers
- Flags
- Preset Kinds
- Template Behaviors (aka Master Behaviors)
- Settings Tables (aka Constant Sets)
- Key Maps
In the tree view, you can see most of these elements, making it easier to find them and the layer they are defined on. You can use the tree search function at the top of the tree to find elements more quickly. Additionally, you can select which elements of the tree are shown.
Inheritance
When a tree element is defined on a layer, it is also inherited by all of its sublayers. Let’s take a simple example of a variable.
The variable myvariable is defined on layer 2. This means that behaviors defined on the layer can read and modify this variable. The same applies to all behaviors of sublayers of layer 2, such as layer 2.1. However, the two behaviors on the Root Layer - Treetest cannot access the variable myvariable.
By following this basic concept, we can understand which tree elements are available to which behaviors and layers. 1
Types of Tree Elements
Let’s take a look at the different tree elements and their functions.
Behaviors
Behaviors are shown in the tree by their names. The color indicates whether the behavior is selected and visible (or covered).
When a behavior is shown in:
- blue: It is currently visible.
- green: It is currently visible and selected.
- grey: It is currently hidden (covered by a different behavior above or on a non-visible layer).
- orange: It is currently hidden and selected.
Variables
Variables are shown in the tree with their key. A variable can have a key and a name — the name is a friendly name displayed in the interface, while the key is the actual reference to this variable used in all Parameter References. Changing the name only changes how the variable appears in different places, but changing its key breaks the links to other parts of the configuration.
Next to the variable, you can also see its current value. A variable can have more than one value at once (an array); if that is the case, the current values will be shown separated by commas.
Key Maps
A Key Map can map behavior names to the physical hardware components on panels. They can also remap behavior names to different ones. Most of the time, Key Maps are managed automatically by the configurator.
Each hardware component of a panel has a fixed address format:
_p<panelID>.<componentID>
For example: _p1.15 (Panel 1, Hardware Component 15) or _p3.23 (Panel 3, Hardware Component 23).
To make configurations compatible with multiple panels and more understandable, Key Maps are used to assign names to these addresses.
A Key Map can contain different mappings:
- Component address to behavior name: This assigns behavior names to hardware components in the configurator.
- Behavior name to behavior name: Remap a behavior name to a different one in the layers below, often used when a configuration is remapped to a different set of buttons.
- Panel Wildcard (e.g., _p1.*): Remap a panel ID used in the layers below to a different one. This is mostly used by the Home Screen to map your panels to their selected configurations.
Behavior to behavior mapping and Panel Wildcard mapping are often used in combination with the inclusion of different layer files. This is useful when remapping IDs in an included configuration.
The Key Map is shown in the tree on the layer where it is defined, and its mapping is valid for that layer and all its sublayers, like the inheritance of any other tree element.
Virtual Triggers
Virtual Triggers are defined on layers in the tree. When a layer becomes hidden, the virtual trigger will not execute anymore. See more about Virtual Triggers in the chapter Virtual Triggers.
Preset Kinds
Preset Kinds define a Reactor Preset as a list of parameters that can be stored and recalled from your panel. You can read more in the chapter Shading Presets.
Flag Group
Flag Groups are defined in the tree. Read more about them in the chapter Flag Groups.
Custom Template Behaviors
If you find yourself creating the same kind of behavior repeatedly, you might want to create a Template Behavior. In Reactor, Template Behaviors are also called Master Behaviors.
You can create a Template Behavior on any layer and configure it as needed. Afterward, you can select the new Template Behavoir for other Behaviors (within the scope of inheritance). See more in the chapter Custom Template Behaviors.
Settings Tables (aka Constant Sets)
Settings Tables - or Constant Sets - are a table structure used for various purposes in Reactor, such as:
- Storing configuration settings that can be changed directly on the Home Screen.
- Generating layers with Behaviors based on table rows.
- Creating multiple Virtual Triggers based on table rows.
As with all other tree elements, they follow inheritance. Learn more about their use here: Generators and Constant Sets.
Examples of Settings Tables in default configurations include:
- Camera Selector
- Tally Config
- GPIO Mappings
- (See more examples in Default Configurations)
We call them Settings Tables because they often store important settings available from the Home Screen. Their original name, Constant Sets, reflects the fact that their values are stored within the configuration and cannot be changed while the controller is running, unlike variables. Any modifications require updating the configuration through the UI.
Layer Paths
Technically, every layer has a path. Paths are denoted as, for example, 0/1/4/1/.
0/ always references the root layer. 0/0/ references the topmost child layer of the root layer, and so on.
Knowledge of layer paths is not required to use Reactor, but it can help you better understand the system.
Variables and Settings Tables (Constant Sets) can have advanced options that affect inheritance, such as Expand Scope, Capture, and Always Define. This is an advanced topic and will be covered later. Please refer to the corresponding tool tips in the configurator for more details.