-
Notifications
You must be signed in to change notification settings - Fork 409
Handling input events
Input handling follows a topological model whereby the top-most (visually) Drawable
handles input prior to anything else in the game. Hierarchically between a single parent-child relationship, the child handles input before the parent.
Parent < Handler #4
Child_1 < Handler #3
Child_2 < Handler #2
Child_2_1 < Handler #1
"Positional" input refers to any input that depends on a screen-space position (e.g. hover). "Non-positional" input refers to any other input (e.g. a button press).
protected virtual bool OnMouseMove(MouseMoveEvent e);
protected virtual bool OnHover(HoverEvent e);
protected virtual void OnHoverLost(HoverLostEvent e);
protected virtual bool OnMouseDown(MouseDownEvent e);
protected virtual bool OnMouseUp(MouseUpEvent e);
protected virtual bool OnClick(ClickEvent e);
protected virtual bool OnDoubleClick(DoubleClickEvent e);
protected virtual bool OnDragStart(DragStartEvent e);
protected virtual bool OnDrag(DragEvent e);
protected virtual bool OnDragEnd(DragEndEvent e);
protected virtual bool OnScroll(ScrollEvent e);
protected virtual bool OnKeyDown(KeyDownEvent e);
protected virtual bool OnKeyUp(KeyUpEvent e);
protected virtual bool OnJoystickPress(JoystickPressEvent e);
protected virtual bool OnJoystickRelease(JoystickReleaseEvent e);
These event handlers should be used when singular events are to be handled.
The boolean return value indicates whether the event should continue being propagated to other Drawable
s in the scene graph.
Example: If a child did not want its parent to receive an OnHover()
event, it should override OnHover()
to return true
.
OnHoverLost()
is an exception which is unconditionally invoked on every un-hovered Drawable
.
Example:
protected override bool OnClick(ClickEvent e)
{
this.ScaleTo(1.25f, 50).Then().ScaleTo(1f, 50);
return true;
}
protected virtual bool Handle(UIEvent e);
This event handler should be used when groups of events with identical implementations are to be handled.
This counts as both a positional and non-positional event handler and works well when combined with the HandleNonPositionalInput
and HandlePositionalInput
properties described below.
Example:
protected override bool Handle(UIEvent e)
{
switch (e)
{
case MouseEvent _:
// Stop all mouse events from being handled by other Drawables
return true;
default:
// Let other Drawables handle everything else
return false;
}
}
By default, any Drawable
that implements the handlers described above will receive all events appropriate for the types of input listed.
public virtual bool HandleNonPositionalInput;
public virtual bool HandlePositionalInput;
The above properties are provided to control whether a Drawable
should receive the types of input events.
Example: If a Drawable
did not want to handle any click, drag, and hover events at some point, it could achieve this by overriding HandlePositionalInput
to return false
.
Warning: Overriding the above properties will cause the Drawable
to be considered for (but not necessarily receive) that type of input, and thus serves as an anti-optimisation if the intention is to make the Drawable
not considered for that type of input.
If a parent should control whether itself or its children should be considered for a type of input at all, the following properties are provided to control the behaviour:
public virtual bool PropagateNonPositionalInputSubTree;
public virtual bool PropagatePositionalInputSubTree;
Example:
class MyContainer : FillFlowContainer
{
public MyContainer()
{
for (int i = 0; i < 1024; i++)
Add(new Button { Size = new Vector2(50) });
}
// Whoah! The buttons we added are just for show, they don't actually handle clicks!
public override bool PropagatePositionalInputSubTree => false;
}
public virtual bool RequestsFocus;
public virtual bool AcceptsFocus;
protected virtual void OnFocus(FocusEvent e);
protected virtual void OnFocusLost(FocusLostEvent e);
Focus may be received via both positional and non-positional input. A Drawable
with AcceptsFocus = false
will never receive focus.
A Drawable
receives focus when OnClick()
returns true
.
The top-most Drawable
with RequestsFocus = true
and HandleNonPostionalInput = true
will receive focus if nothing else has focus.
The OnFocusLost()
method is unconditionally invoked on the un-focused Drawable
.
Example:
class MyDrawable : CompositeDrawable
{
public override bool AcceptsFocus => true;
protected override bool OnClick(ClickEvent e) => true;
protected override void OnFocus(FocusEvent e) => this.ScaleTo(1.5f, 50);
protected override void OnFocusLost(FocusLostEvent e) => this.ScaleTo(1f, 50);
}
- Create your first project
- Learning framework key bindings
- Adding resource stores
- Adding custom key bindings
- Adding custom fonts