Input Handlers
Input is handled inline as your templates execute in an immediate mode style. There are three phases to input:
BeforeUpdate
runs after parameters have been passed to your element for this frame but before the update hooks are invokedAfterUpdate
runs after the update hooks have been invoked but before any children have runAfterChildren
runs after all descendents have been updated
Input handlers are the same for typography
, template
and decorator
. function
cannot declare input handlers.
In template code, all input handlers have the same format of event_class:event_name => expression
. The expression can be
either a single line statement or a block. Inside of an event handler the $evt
built in becomes available.
Its type will depend on the event being fired.
- For mouse events,
$evt
will be a MouseInputEvent - for key events,
$evt
will be a KeyboardInputEvent - for focus events,
$evt
will be a FocusChangeEvent - for text input events,
$evt
will be a TextInputEvent - for drag create,
$evt
is a MouseInputEvent - for all other drag events,
$evt
will refer to the current drag event whose type is set by the return value ofdrag:create
template InputExample {
state int clicks;
state int focusCount;
mouse:down => clicks++;
focus:gained => {
focusCount++;
Debug.Log($"Gained focus {focusCount} times!");
}
}
You can modify which phase the event handler fires on with the .beforeUpdate
, .afterUpdate
and .afterChildren
modifiers.
By default, events are fired in the afterChildren
phase.
decorator SomeDecorator {
key:down.beforeUpdate => Debug.Log($"{$evt.keyCode} was pressed");
key:down.afterUpdate => Debug.Log($"{$evt.keyCode} was pressed");
key:down.afterChildren => Debug.Log($"{$evt.keyCode} was pressed");
Propagation
Events effectively fire for a whole hierarchy unless event.StopPropagation()
is called. Once called, this event type
is dead for the duration of the frame and no other element can respond to it.
A common practice in UI frameworks is have the concept of event bubbling and capture. While Evolve doesn't directly implement events in this way, because of the way the event phases are executed we can emulate this fairly well.
Using from
with input events
When using a from
mapping, the event signature must match the below 'Mapping Signature' table. In all cases except for
drag:create
the return type of the linked method is ignored and an be anything. If you use the shorthand for mapping an input handler
from a companion such as mouse:down from $companion
then the method name must match the name given in the 'Mapping Signature' column.
If you supply the method name explicitly such as mouse:down from $companion.SomeMethod
or mouse:up from someState.SomeMethod
then only the signatures must match.
Note that the shorthand that omits the method name is only valid for $companion
Mouse Event Types
Event Name | Method Mapping Name |
---|---|
mouse:enter | OnMouseEnter(MouseInputEvent) |
mouse:exit | OnMouseExit(MouseInputEvent) |
mouse:up | OnMouseUp(MouseInputEvent) |
mouse:down | OnMouseDown(MouseInputEvent) |
mouse:heldDown | OnMouseHeldDown(MouseInputEvent) |
mouse:move | OnMouseMove(MouseInputEvent) |
mouse:hover | OnMouseHover(MouseInputEvent) |
mouse:context | OnMouseContext(MouseInputEvent) |
mouse:scroll | OnMouseScroll(MouseInputEvent) |
mouse:click | OnMouseClick(MouseInputEvent) |
mouse:update | OnMouseUpdate(MouseInputEvent) |
Keyboard Event Types
Event Name | Mapping Method Name |
---|---|
key:down | OnKeyDown(KeyboardInputEvent) |
key:heldDown | OnKeyHeldDown(KeyboardInputEvent) |
key:up | OnKeyUp(KeyboardInputEvent) |
Focus Event Types
Event Name | Mapping Method Name |
---|---|
focus:gain | OnFocusGained(FocusChangeEvent) |
focus:lost | OnFocusLost(FocusChangeEvent) |
Drag Event Types
Drag Event Types
Drag create is a special snowflake because it accepts a MouseInputEvent
and expects to return an instance of DragEvent
.
All other drag handlers conform to the same signature requirements. If you omit a drag event type (listed as T
in the table below),
then these events will fire any drag event type.
Event Name | Mapping Method Name | Description |
---|---|---|
drag:create | DragEvent OnDragCreate(MouseInputEvent)) | Fires when a drag could begin. Returning null will not start a drag. Returning any other subclass of DragEvent will being a drag. |
drag:move<T> | OnDragMove(DragEvent) | Fires when a drag of type T moves across this element |
drag:hover<T> | OnDragHover(DragEvent) | Fires when a drag of type T hovers over this element |
drag:update<T> | OnDragUpdate(DragEvent) | Fires when a drag of type T moves or hovers over this element |
drag:enter<T> | OnDragEnter(DragEvent) | Fires when a drag of type T enters this element |
drag:exit<T> | OnDragExit(DragEvent) | Fires when a drag of type T exits this element |
drag:drop<T> | OnDragDrop(DragEvent) | Fires when a drop event of type T occurs on this element |
drag:cancel<T> | OnDragCancel(DragEvent) | Fires when a drag event of type T is canceled on this element |