FREE TRIAL

|

☀
☾

Events

The Nova event system provides a variety of UI-related events, so custom components can react to data-driven content changes and/or user input.

Connected UIBlock Hierarchies

Rather than exposing the provided events as direct properties across a range of components, Nova's event system is unique in that it treats each active UIBlock in a connected UIBlock hierarchy as a node in a hierarchical event graph.

A connected UIBlock hierarchy is an enabled hierarchy of UIBlocks such that each parent Transform of a UIBlock (i.e. UIBlock.transform.parent) also has a UIBlock on its GameObject – in the context of Nova, while UIBlock.Parent != null.

If a given UIBlock's parent Transform doesn't have a UIBlock attached to its GameObject, that top-level UIBlock is considered a root. A UIBlock's root can always be queried via the UIBlock.Root property.

Note

All UIBlocks on enabled GameObjects within a connected UIBlock hierarchy participate in the event propagation step. Event propagation stops at root UIBlocks. Even if there is a UIBlock higher in the Transform hierarchy, if it's disconnected from the UIBlock firing the event, it will not receive that particular event.

Event Propagation

When a Nova component is ready to trigger an event, it sends the relevant event data via the UIBlock on its GameObject, allowing the event to propogate upwards through the UIBlock's ancestral hierarchy. Once the event data reaches an ancestor listening for the propagating event type, the event callbacks registered on that UIBlock are invoked, and the propagation continues up.

The EventHandler referenced in the root of the diagram would be a user-written component. A simple example:

using Nova;
using UnityEngine;

public class EventHandler : MonoBehaviour
{
    // Serialize and assign in Unity Editor
    public UIBlock Root = null;

    private void Start()
    {
        Root.AddGestureHandler<Gesture.OnClick>(Click);
    }

    private void Click(Gesture.OnClick evt)
    {
        Debug.Log("Clicked!");        
    }
}

In the case where an event handler wishes to prevent the event it's handling from propagating further up the UIBlock hierarchy, the Consume() method is available.

    private void Click(Gesture.OnClick evt)
    {
        Debug.Log("Clicked!");

        // Stop hierarchical event propogation
        evt.Consume();
    }
Note

A call to Consume() may not immediately stop triggering event callbacks, if there are other event handlers registered at the current hierarchical propagation level. It simply prevents further propagation up the hierarchy.

See Input to learn more about various gestures.

Event Target Types

The hierarchical event propagation provides a number of benefits, but perhaps most significant is enabling Event + Event Target type-matching. In other words, being able to handle specific events, such as clicks, that occur on specific Event Target types, including user-defined target types. Let's look at a concrete example:

Say you've created a ButtonVisuals class to group the visuals associated with a Button control (see the ItemView article to learn more about creating ItemVisuals):

public class ButtonVisuals : ItemVisuals
{
    public TextBlock Label;
    public UIBlock2D Icon;    
}

Using Nova's Event + Event Target type-matching, you can now create an EventHandler to handle Gesture.OnClick events which occur to ButtonVisuals, like so:

using Nova;
using UnityEngine;

public class EventHandler : MonoBehaviour
{
    // Serialize and assign in Unity Editor
    public UIBlock Root = null;

    private void Start()
    {
        Root.AddGestureHandler<Gesture.OnClick, ButtonVisuals>(ButtonClicked);
    }

    private void ButtonClicked(Gesture.OnClick evt, ButtonVisuals button)
    {
        Debug.Log("Button Clicked!");        
    }
}

A Gesture.OnClick event that is fired on or below the ItemView containing our ButtonVisuals type will traverse up as a Gesture.OnClick + ButtonVisuals pair. Anything on or above the ItemView in the UIBlock hierarchy could then receive the Gesture.OnClick event on the ButtonVisuals type.

This type-matching gives you the flexibility to filter or handle events based on the type of object the event occurred to. For example, if in addition to ButtonVisuals we also had a ToggleVisuals class:

public class ToggleVisuals : ItemVisuals
{
    public TextBlock Label;
    public UIBlock2D IsOnIndicator;    
}

We could modify our EventHandler to handle clicks differently for buttons and toggles:

// Register both Button and Toggle
Root.AddGestureHandler<Gesture.OnClick, ButtonVisuals>(ButtonClicked);
Root.AddGestureHandler<Gesture.OnClick, ToggleVisuals>(ToggleClicked);

// ...

// Handle button clicks
private void ButtonClicked(Gesture.OnClick evt, ButtonVisuals button)
{
    Debug.Log("Button Clicked!");        
}

// Handle toggle clicks
private void ToggleClicked(Gesture.OnClick evt, ToggleVisuals toggle)
{
    Debug.Log("Toggle Clicked!");    
}
Note

The Event Target type-matching handles inheritance, so a GestureHandler registered for Animal will also be invoked for Dog, assuming Dog inherits from Animal.

Multiple Event Target Types

It is worth noting that as an event traverses up the UIBlock hierarchy, it can have multiple Event Target types associated with it. In other words, the process of "picking up" Event Target types is additive.

For example, in the Multiple Type Targeted Events diagram, there are two ItemViews between the Interactable on which a Gesture.OnClick was created, and the EventHandler. One ItemView has a ButtonVisuals type, and another has a FooVisuals type. If the EventHandler has registered for Gesture.OnClick events for both ButtonVisuals and FooVisuals, both callbacks would be invoked for a single Gesture.OnClick event.

Event Types

Event Description Triggered By
Data.OnBind<T> A data-model, T, to ItemVisuals bind event. ListView
Data.OnUnbind<T> A data-model, T, to ItemVisuals unbind event. ListView
Gesture.OnHover A pointer enter input event. Interactable & Scroller
Gesture.OnUnhover A pointer exit input event. Interactable & Scroller
Gesture.OnMove A pointer move input event. Interactable & Scroller
Gesture.OnPress A pointer down input event. Interactable & Scroller
Gesture.OnRelease A pointer up input event. Interactable & Scroller
Gesture.OnClick A pointer click pattern was detected. Interactable & Scroller
Gesture.OnDrag A pointer move while down input event. Interactable
Gesture.OnScroll Corresponds to a pointer move while down input event or an explicit call to Scroll. Scroller
Gesture.OnCancel Corresponds to a higher-priority gesture being detected, the GestureRecognizer component capturing the active gesture being disabled, or an explicit call to Cancel. Interactable & Scroller
Navigate.OnDirection Navigated in a given direction without moving navigation focus. Interactable & Scroller
Navigate.OnMoveTo Navigation focus moved to a new GestureRecognizer. Interactable & Scroller
Navigate.OnMoveFrom Navigation focus moved from a GestureRecognizer. Interactable & Scroller
Navigate.OnSelect The GestureRecognizer with navigation focus was selected. Interactable & Scroller
Navigate.OnDeselect The selected GestureRecognizer was deselected. Interactable & Scroller
☀
☾
In This Article
Legal EmailContact Github
Copyright © 2022 Supernova Technologies, LLC