Files
FlaxEngine/Source/Engine/UI/GUI/RootControl.cs
Ari Vuollet 387eb90576
Some checks failed
Build Android / Game (Android, Release ARM64) (push) Has been cancelled
Build iOS / Game (iOS, Release ARM64) (push) Has been cancelled
Build Linux / Editor (Linux, Development x64) (push) Has been cancelled
Build Linux / Game (Linux, Release x64) (push) Has been cancelled
Build macOS / Editor (Mac, Development ARM64) (push) Has been cancelled
Build macOS / Game (Mac, Release ARM64) (push) Has been cancelled
Build Windows / Editor (Windows, Development x64) (push) Has been cancelled
Build Windows / Game (Windows, Release x64) (push) Has been cancelled
Cooker / Cook (Mac) (push) Has been cancelled
Tests / Tests (Linux) (push) Has been cancelled
Tests / Tests (Windows) (push) Has been cancelled
_wayland temp investigate
2025-01-10 11:28:22 +02:00

235 lines
8.0 KiB
C#

// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
using System;
using System.Collections.Generic;
namespace FlaxEngine.GUI
{
/// <summary>
/// GUI root control that is represented by a window or a canvas and can contain children but has no parent at all. It's a source of the input events.
/// </summary>
public abstract class RootControl : ContainerControl
{
private static ContainerControl _gameRoot;
private static CanvasContainer _canvasContainer = new CanvasContainer();
/// <summary>
/// Gets the main GUI control (it can be window or editor overriden control). Use it to plug-in custom GUI controls.
/// </summary>
public static ContainerControl GameRoot
{
get => _gameRoot;
internal set
{
_gameRoot = value;
_canvasContainer.Parent = _gameRoot;
}
}
/// <summary>
/// Gets the canvas controls root container.
/// </summary>
internal static CanvasContainer CanvasRoot => _canvasContainer;
/// <summary>
/// Gets or sets the current focused control
/// </summary>
public abstract Control FocusedControl { get; set; }
/// <summary>
/// Gets the tracking mouse offset.
/// </summary>
public abstract Float2 TrackingMouseOffset { get; }
/// <summary>
/// Gets or sets the position of the mouse in the window space coordinates.
/// </summary>
public abstract Float2 MousePosition { get; set; }
/// <summary>
/// The update callbacks collection. Controls can register for this to get the update event for logic handling.
/// </summary>
public readonly List<UpdateDelegate> UpdateCallbacks = new List<UpdateDelegate>(1024);
/// <summary>
/// The update callbacks to add before invoking the update.
/// </summary>
public List<UpdateDelegate> UpdateCallbacksToAdd = new List<UpdateDelegate>();
/// <summary>
/// The update callbacks to remove before invoking the update.
/// </summary>
public List<UpdateDelegate> UpdateCallbacksToRemove = new List<UpdateDelegate>();
/// <summary>
/// Initializes a new instance of the <see cref="RootControl"/> class.
/// </summary>
protected RootControl()
: base(0, 0, 100, 60)
{
AutoFocus = false;
}
#region Navigation
/// <summary>
/// The custom callback function for UI navigation. Can be used to override the default behaviour.
/// </summary>
public Action<NavDirection> CustomNavigation;
/// <summary>
/// Performs the UI navigation.
/// </summary>
/// <param name="direction">The navigation direction.</param>
public void Navigate(NavDirection direction)
{
if (direction == NavDirection.None)
return;
if (CustomNavigation != null)
{
// Custom
CustomNavigation.Invoke(direction);
return;
}
var focused = FocusedControl;
if (focused == null)
{
// Nothing is focused so go to the first control
focused = OnNavigate(direction, Float2.Zero, this, new List<Control>());
focused?.NavigationFocus();
return;
}
var target = focused.GetNavTarget(direction);
if (target != null)
{
// Explicitly specified focus target
target.NavigationFocus();
return;
}
// Automatic navigation routine
target = focused.OnNavigate(direction, focused.GetNavOrigin(direction), this, new List<Control>());
target?.NavigationFocus();
}
/// <summary>
/// Submits the currently focused control.
/// </summary>
public void SubmitFocused()
{
FocusedControl?.OnSubmit();
}
#endregion
/// <inheritdoc />
public override void Update(float deltaTime)
{
base.Update(deltaTime);
// Flush requests
Profiler.BeginEvent("RootControl.SyncCallbacks");
for (int i = 0; i < UpdateCallbacksToAdd.Count; i++)
{
UpdateCallbacks.Add(UpdateCallbacksToAdd[i]);
}
UpdateCallbacksToAdd.Clear();
for (int i = 0; i < UpdateCallbacksToRemove.Count; i++)
{
UpdateCallbacks.Remove(UpdateCallbacksToRemove[i]);
}
UpdateCallbacksToRemove.Clear();
Profiler.EndEvent();
// Perform the UI update
try
{
Profiler.BeginEvent("RootControl.Update");
for (int i = 0; i < UpdateCallbacks.Count; i++)
{
//UpdateCallbacks[i](deltaTime);
}
}
finally
{
Profiler.EndEvent();
}
}
/// <inheritdoc />
public override bool RayCast(ref Float2 location, out Control hit)
{
// Ignore self
return RayCastChildren(ref location, out hit);
}
/// <inheritdoc />
public override bool ContainsPoint(ref Float2 location, bool precise = false)
{
if (precise) // Ignore as utility-only element
return false;
return base.ContainsPoint(ref location, precise);
}
/// <summary>
/// Starts the mouse tracking. Used by the scrollbars, splitters, etc.
/// </summary>
/// <param name="control">The target control that want to track mouse. It will receive OnMouseMove event.</param>
/// <param name="useMouseScreenOffset">If set to <c>true</c> will use mouse screen offset.</param>
public abstract void StartTrackingMouse(Control control, bool useMouseScreenOffset);
/// <summary>
/// Ends the mouse tracking.
/// </summary>
public abstract void EndTrackingMouse();
/// <summary>
/// Gets keyboard key state.
/// </summary>
/// <param name="key">Key to check.</param>
/// <returns>True while the user holds down the key identified by id.</returns>
public abstract bool GetKey(KeyboardKeys key);
/// <summary>
/// Gets keyboard key down state.
/// </summary>
/// <param name="key">Key to check.</param>
/// <returns>True during the frame the user starts pressing down the key.</returns>
public abstract bool GetKeyDown(KeyboardKeys key);
/// <summary>
/// Gets keyboard key up state.
/// </summary>
/// <param name="key">Key to check.</param>
/// <returns>True during the frame the user releases the button.</returns>
public abstract bool GetKeyUp(KeyboardKeys key);
/// <summary>
/// Gets mouse button state.
/// </summary>
/// <param name="button">Mouse button to check.</param>
/// <returns>True while the user holds down the button.</returns>
public abstract bool GetMouseButton(MouseButton button);
/// <summary>
/// Gets mouse button down state.
/// </summary>
/// <param name="button">Mouse button to check.</param>
/// <returns>True during the frame the user starts pressing down the button.</returns>
public abstract bool GetMouseButtonDown(MouseButton button);
/// <summary>
/// Gets mouse button up state.
/// </summary>
/// <param name="button">Mouse button to check.</param>
/// <returns>True during the frame the user releases the button.</returns>
public abstract bool GetMouseButtonUp(MouseButton button);
/// <inheritdoc />
public override RootControl Root => this;
}
}