Files
FlaxEngine/Source/Engine/UI/GUI/CanvasRootControl.cs
2022-01-14 13:31:12 +01:00

401 lines
12 KiB
C#

// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
using System;
namespace FlaxEngine.GUI
{
/// <summary>
/// Root control implementation used by the <see cref="UICanvas"/> actor.
/// </summary>
/// <seealso cref="FlaxEngine.GUI.RootControl" />
[HideInEditor]
public sealed class CanvasRootControl : RootControl
{
private UICanvas _canvas;
private Vector2 _mousePosition;
private float _navigationHeldTimeUp, _navigationHeldTimeDown, _navigationHeldTimeLeft, _navigationHeldTimeRight, _navigationHeldTimeSubmit;
private float _navigationRateTimeUp, _navigationRateTimeDown, _navigationRateTimeLeft, _navigationRateTimeRight, _navigationRateTimeSubmit;
/// <summary>
/// Gets the owning canvas.
/// </summary>
public UICanvas Canvas => _canvas;
/// <summary>
/// Gets a value indicating whether canvas is 2D (screen-space).
/// </summary>
public bool Is2D => _canvas.RenderMode == CanvasRenderMode.ScreenSpace;
/// <summary>
/// Gets a value indicating whether canvas is 3D (world-space or camera-space).
/// </summary>
public bool Is3D => _canvas.RenderMode != CanvasRenderMode.ScreenSpace;
/// <summary>
/// Initializes a new instance of the <see cref="CanvasRootControl"/> class.
/// </summary>
/// <param name="canvas">The canvas.</param>
internal CanvasRootControl(UICanvas canvas)
{
_canvas = canvas;
}
/// <inheritdoc />
public override CursorType Cursor
{
get => CursorType.Default;
set { }
}
/// <inheritdoc />
public override Control FocusedControl
{
get => Parent?.Root.FocusedControl;
set
{
if (Parent != null)
Parent.Root.FocusedControl = value;
}
}
/// <inheritdoc />
public override Vector2 TrackingMouseOffset => Vector2.Zero;
/// <inheritdoc />
public override Vector2 MousePosition
{
get => _mousePosition;
set { }
}
/// <inheritdoc />
public override void StartTrackingMouse(Control control, bool useMouseScreenOffset)
{
// Not used in games (editor-only feature)
}
/// <inheritdoc />
public override void EndTrackingMouse()
{
// Not used in games (editor-only feature)
}
/// <inheritdoc />
public override bool GetKey(KeyboardKeys key)
{
return Input.GetKey(key);
}
/// <inheritdoc />
public override bool GetKeyDown(KeyboardKeys key)
{
return Input.GetKeyDown(key);
}
/// <inheritdoc />
public override bool GetKeyUp(KeyboardKeys key)
{
return Input.GetKeyUp(key);
}
/// <inheritdoc />
public override bool GetMouseButton(MouseButton button)
{
return Input.GetMouseButton(button);
}
/// <inheritdoc />
public override bool GetMouseButtonDown(MouseButton button)
{
return Input.GetMouseButtonDown(button);
}
/// <inheritdoc />
public override bool GetMouseButtonUp(MouseButton button)
{
return Input.GetMouseButtonUp(button);
}
/// <inheritdoc />
public override Vector2 PointToParent(ref Vector2 location)
{
if (Is2D)
return base.PointToParent(ref location);
var camera = Camera.MainCamera;
if (!camera)
return location;
// Transform canvas local-space point to the game root location
_canvas.GetWorldMatrix(out Matrix world);
Vector3 locationCanvasSpace = new Vector3(location, 0.0f);
Vector3.Transform(ref locationCanvasSpace, ref world, out Vector3 locationWorldSpace);
camera.ProjectPoint(locationWorldSpace, out location);
return location;
}
/// <inheritdoc />
public override bool ContainsPoint(ref Vector2 location)
{
return base.ContainsPoint(ref location)
&& (_canvas.TestCanvasIntersection == null || _canvas.TestCanvasIntersection(ref location));
}
/// <inheritdoc />
public override void Update(float deltaTime)
{
// UI navigation
if (_canvas.ReceivesEvents)
{
UpdateNavigation(deltaTime, _canvas.NavigationInputActionUp, NavDirection.Up, ref _navigationHeldTimeUp, ref _navigationRateTimeUp);
UpdateNavigation(deltaTime, _canvas.NavigationInputActionDown, NavDirection.Down, ref _navigationHeldTimeDown, ref _navigationRateTimeDown);
UpdateNavigation(deltaTime, _canvas.NavigationInputActionLeft, NavDirection.Left, ref _navigationHeldTimeLeft, ref _navigationRateTimeLeft);
UpdateNavigation(deltaTime, _canvas.NavigationInputActionRight, NavDirection.Right, ref _navigationHeldTimeRight, ref _navigationRateTimeRight);
UpdateNavigation(deltaTime, _canvas.NavigationInputActionSubmit, ref _navigationHeldTimeSubmit, ref _navigationRateTimeSubmit, SubmitFocused);
}
else
{
_navigationHeldTimeUp = _navigationHeldTimeDown = _navigationHeldTimeLeft = _navigationHeldTimeRight = 0;
_navigationRateTimeUp = _navigationRateTimeDown = _navigationRateTimeLeft = _navigationRateTimeRight = 0;
}
base.Update(deltaTime);
}
private void UpdateNavigation(float deltaTime, string actionName, NavDirection direction, ref float heldTime, ref float rateTime)
{
if (Input.GetAction(actionName))
{
if (heldTime <= Mathf.Epsilon)
{
Navigate(direction);
}
if (heldTime > _canvas.NavigationInputRepeatDelay)
{
rateTime += deltaTime;
}
if (rateTime > _canvas.NavigationInputRepeatRate)
{
Navigate(direction);
rateTime = 0;
}
heldTime += deltaTime;
}
else
{
heldTime = rateTime = 0;
}
}
private void UpdateNavigation(float deltaTime, string actionName, ref float heldTime, ref float rateTime, Action action)
{
if (Input.GetAction(actionName))
{
if (heldTime <= Mathf.Epsilon)
{
action();
}
if (heldTime > _canvas.NavigationInputRepeatDelay)
{
rateTime += deltaTime;
}
if (rateTime > _canvas.NavigationInputRepeatRate)
{
action();
rateTime = 0;
}
heldTime += deltaTime;
}
else
{
heldTime = rateTime = 0;
}
}
/// <inheritdoc />
public override bool OnCharInput(char c)
{
if (!_canvas.ReceivesEvents)
return false;
return base.OnCharInput(c);
}
/// <inheritdoc />
public override DragDropEffect OnDragDrop(ref Vector2 location, DragData data)
{
if (!_canvas.ReceivesEvents)
return DragDropEffect.None;
return base.OnDragDrop(ref location, data);
}
/// <inheritdoc />
public override DragDropEffect OnDragEnter(ref Vector2 location, DragData data)
{
if (!_canvas.ReceivesEvents)
return DragDropEffect.None;
return base.OnDragEnter(ref location, data);
}
/// <inheritdoc />
public override void OnDragLeave()
{
if (!_canvas.ReceivesEvents)
return;
base.OnDragLeave();
}
/// <inheritdoc />
public override DragDropEffect OnDragMove(ref Vector2 location, DragData data)
{
if (!_canvas.ReceivesEvents)
return DragDropEffect.None;
return base.OnDragMove(ref location, data);
}
/// <inheritdoc />
public override bool OnKeyDown(KeyboardKeys key)
{
if (!_canvas.ReceivesEvents)
return false;
return base.OnKeyDown(key);
}
/// <inheritdoc />
public override void OnKeyUp(KeyboardKeys key)
{
if (!_canvas.ReceivesEvents)
return;
base.OnKeyUp(key);
}
/// <inheritdoc />
public override bool OnMouseDoubleClick(Vector2 location, MouseButton button)
{
if (!_canvas.ReceivesEvents)
return false;
return base.OnMouseDoubleClick(location, button);
}
/// <inheritdoc />
public override bool OnMouseDown(Vector2 location, MouseButton button)
{
if (!_canvas.ReceivesEvents)
return false;
return base.OnMouseDown(location, button);
}
/// <inheritdoc />
public override void OnMouseEnter(Vector2 location)
{
if (!_canvas.ReceivesEvents)
return;
_mousePosition = location;
base.OnMouseEnter(location);
}
/// <inheritdoc />
public override void OnMouseLeave()
{
_mousePosition = Vector2.Zero;
if (!_canvas.ReceivesEvents)
return;
base.OnMouseLeave();
}
/// <inheritdoc />
public override void OnMouseMove(Vector2 location)
{
if (!_canvas.ReceivesEvents)
return;
_mousePosition = location;
base.OnMouseMove(location);
}
/// <inheritdoc />
public override bool OnMouseUp(Vector2 location, MouseButton button)
{
if (!_canvas.ReceivesEvents)
return false;
return base.OnMouseUp(location, button);
}
/// <inheritdoc />
public override bool OnMouseWheel(Vector2 location, float delta)
{
if (!_canvas.ReceivesEvents)
return false;
return base.OnMouseWheel(location, delta);
}
/// <inheritdoc />
public override void OnTouchEnter(Vector2 location, int pointerId)
{
if (!_canvas.ReceivesEvents)
return;
base.OnTouchEnter(location, pointerId);
}
/// <inheritdoc />
public override bool OnTouchDown(Vector2 location, int pointerId)
{
if (!_canvas.ReceivesEvents)
return false;
return base.OnTouchDown(location, pointerId);
}
/// <inheritdoc />
public override void OnTouchMove(Vector2 location, int pointerId)
{
if (!_canvas.ReceivesEvents)
return;
base.OnTouchMove(location, pointerId);
}
/// <inheritdoc />
public override bool OnTouchUp(Vector2 location, int pointerId)
{
if (!_canvas.ReceivesEvents)
return false;
return base.OnTouchUp(location, pointerId);
}
/// <inheritdoc />
public override void OnTouchLeave(int pointerId)
{
if (!_canvas.ReceivesEvents)
return;
base.OnTouchLeave(pointerId);
}
/// <inheritdoc />
public override void Focus()
{
}
/// <inheritdoc />
public override void DoDragDrop(DragData data)
{
}
}
}