// Copyright (c) Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Core/Types/String.h"
#include "Engine/Core/Math/Rectangle.h"
#include "Engine/Platform/CreateWindowSettings.h"
#include "Engine/Scripting/ScriptingObject.h"
#include "Engine/Input/KeyboardKeys.h"
#include "Engine/Input/Enums.h"
#include "Enums.h"
class Input;
class Engine;
class RenderTask;
class SceneRenderTask;
class GPUSwapChain;
class TextureData;
class IGuiData;
API_INJECT_CODE(cpp, "#include \"Engine/Platform/Window.h\"");
///
/// Native platform window object.
///
API_CLASS(NoSpawn, NoConstructor, Sealed, Name="Window")
class FLAXENGINE_API WindowBase : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE_NO_SPAWN(WindowBase);
friend GPUSwapChain;
protected:
bool _visible, _minimized, _maximized, _isClosing, _showAfterFirstPaint, _focused;
GPUSwapChain* _swapChain;
CreateWindowSettings _settings;
String _title;
CursorType _cursor;
Float2 _clientSize;
int _dpi;
float _dpiScale;
Float2 _trackingMouseOffset;
bool _isUsingMouseOffset = false;
Rectangle _mouseOffsetScreenSize;
bool _isTrackingMouse = false;
bool _isHorizontalFlippingMouse = false;
bool _isVerticalFlippingMouse = false;
bool _isClippingCursor = false;
explicit WindowBase(const CreateWindowSettings& settings);
virtual ~WindowBase();
public:
///
/// The rendering task for that window.
///
RenderTask* RenderTask;
///
/// Event fired when window gets shown.
///
Action Shown;
///
/// Event fired when window gets hidden.
///
Action Hidden;
///
/// Event fired when window gets closed.
///
Action Closed;
///
/// Event fired when window gets resized.
///
Delegate Resized;
///
/// Event fired when window gets focused.
///
Action GotFocus;
///
/// Event fired when window lost focus.
///
Action LostFocus;
///
/// Event fired when window updates UI.
///
Delegate Update;
///
/// Event fired when window draws UI.
///
Action Draw;
public:
// Returns true if that window is the main Engine window (works in both editor and game mode)
bool IsMain() const;
// Gets rendering output swap chain
FORCE_INLINE GPUSwapChain* GetSwapChain() const
{
return _swapChain;
}
// Gets create window settings constant reference
FORCE_INLINE const CreateWindowSettings& GetSettings() const
{
return _settings;
}
///
/// Gets a value that indicates whether a window is in a fullscreen mode.
///
API_PROPERTY() bool IsFullscreen() const;
///
/// Sets a value that indicates whether a window is in a fullscreen mode.
///
/// If set to true window will enter fullscreen mode, otherwise windowed mode.
API_PROPERTY() virtual void SetIsFullscreen(bool isFullscreen);
///
/// Gets a value that indicates whether a window is not in a fullscreen mode.
///
API_PROPERTY() FORCE_INLINE bool IsWindowed() const
{
return !IsFullscreen();
}
///
/// Gets a value that indicates whether a window is visible (hidden or shown).
///
API_PROPERTY() bool IsVisible() const;
///
/// Sets a value that indicates whether a window is visible (hidden or shown).
///
/// True if show window, otherwise false if hide it.
API_PROPERTY() void SetIsVisible(bool isVisible);
///
/// Gets a value that indicates whether a window is minimized.
///
API_PROPERTY() FORCE_INLINE bool IsMinimized() const
{
return _minimized;
}
///
/// Gets a value that indicates whether a window is maximized.
///
API_PROPERTY() FORCE_INLINE bool IsMaximized() const
{
return _maximized;
}
///
/// Gets the native window handle.
///
/// The native window object handle.
API_PROPERTY() virtual void* GetNativePtr() const = 0;
public:
///
/// Performs the UI update.
///
/// The delta time (in seconds).
virtual void OnUpdate(float dt);
///
/// Performs the window UI rendering using Render2D.
///
virtual void OnDraw();
///
/// Initializes the swap chain and the rendering task.
///
/// True if failed, otherwise false.
virtual bool InitSwapChain();
///
/// Shows the window.
///
API_FUNCTION() virtual void Show();
///
/// Hides the window.
///
API_FUNCTION() virtual void Hide();
///
/// Minimizes the window.
///
API_FUNCTION() virtual void Minimize()
{
}
///
/// Maximizes the window.
///
API_FUNCTION() virtual void Maximize()
{
}
///
/// Sets the window to be borderless or not and to be fullscreen.
///
/// Whether or not to have borders on window.
/// Whether or not to make the borderless window fullscreen (maximize to cover whole screen).
API_FUNCTION() virtual void SetBorderless(bool isBorderless, bool maximized = false)
{
}
///
/// Restores the window state before minimizing or maximizing.
///
API_FUNCTION() virtual void Restore()
{
}
///
/// Closes the window.
///
/// The closing reason.
API_FUNCTION() virtual void Close(ClosingReason reason = ClosingReason::CloseEvent);
///
/// Checks if window is closed.
///
API_PROPERTY() virtual bool IsClosed() const
{
return _isClosing;
}
///
/// Checks if window is foreground (the window with which the user is currently working).
///
API_PROPERTY() virtual bool IsForegroundWindow() const;
public:
///
/// Gets the client bounds of the window (client area not including border).
///
API_PROPERTY() FORCE_INLINE Rectangle GetClientBounds() const
{
return Rectangle(GetClientPosition(), GetClientSize());
}
///
/// Sets the client bounds of the window (client area not including border).
///
/// The client area.
API_PROPERTY() virtual void SetClientBounds(const Rectangle& clientArea)
{
}
///
/// Gets the window position (in screen coordinates).
///
API_PROPERTY() virtual Float2 GetPosition() const
{
return Float2::Zero;
}
///
/// Sets the window position (in screen coordinates).
///
/// The position.
API_PROPERTY() virtual void SetPosition(const Float2& position)
{
}
///
/// Gets the client position of the window (client area not including border).
///
API_PROPERTY() FORCE_INLINE Float2 GetClientPosition() const
{
return ClientToScreen(Float2::Zero);
}
///
/// Sets the client position of the window (client area not including border)
///
/// The client area position.
API_PROPERTY() virtual void SetClientPosition(const Float2& position)
{
SetClientBounds(Rectangle(position, GetClientSize()));
}
///
/// Gets the window size (including border).
///
API_PROPERTY() virtual Float2 GetSize() const
{
return _clientSize;
}
///
/// Gets the size of the client area of the window (not including border).
///
API_PROPERTY() virtual Float2 GetClientSize() const
{
return _clientSize;
}
///
/// Sets the size of the client area of the window (not including border).
///
/// The window client area size.
API_PROPERTY() void SetClientSize(const Float2& size)
{
SetClientBounds(Rectangle(GetClientPosition(), size));
}
///
/// Converts screen space location into window space coordinates.
///
/// The screen position.
/// The client space position.
API_FUNCTION() virtual Float2 ScreenToClient(const Float2& screenPos) const
{
return screenPos;
}
///
/// Converts window space location into screen space coordinates.
///
/// The client position.
/// The screen space position.
API_FUNCTION() virtual Float2 ClientToScreen(const Float2& clientPos) const
{
return clientPos;
}
///
/// Gets the window DPI setting.
///
API_PROPERTY() int GetDpi() const
{
return _dpi;
}
///
/// Gets the window DPI scale factor (1 is default). Includes custom DPI scale
///
API_PROPERTY() float GetDpiScale() const
{
return Platform::CustomDpiScale * _dpiScale;
}
public:
///
/// Gets the window title.
///
/// The window title.
API_PROPERTY() virtual String GetTitle() const
{
return _title;
}
///
/// Sets the window title.
///
/// The title.
API_PROPERTY() virtual void SetTitle(const StringView& title)
{
_title = title;
}
///
/// Gets window opacity value (valid only for windows created with SupportsTransparency flag). Opacity values are normalized to range [0;1].
///
API_PROPERTY() virtual float GetOpacity() const
{
return 1.0f;
}
///
/// Sets window opacity value (valid only for windows created with SupportsTransparency flag). Opacity values are normalized to range [0;1].
///
/// The opacity.
API_PROPERTY() virtual void SetOpacity(float opacity)
{
}
///
/// Determines whether this window is focused.
///
API_PROPERTY() FORCE_INLINE bool IsFocused() const
{
return _focused;
}
///
/// Focuses this window.
///
API_FUNCTION() virtual void Focus()
{
}
///
/// Brings window to the front of the Z order.
///
/// True if move to the front by force, otherwise false.
API_FUNCTION() virtual void BringToFront(bool force = false)
{
}
///
/// Flashes the window to bring use attention.
///
API_FUNCTION() virtual void FlashWindow()
{
}
public:
///
/// Starts drag and drop operation
///
/// The data.
/// The result.
API_FUNCTION() virtual DragDropEffect DoDragDrop(const StringView& data)
{
return DragDropEffect::None;
}
///
/// Starts the mouse tracking.
///
/// If set to true will use mouse screen offset.
API_FUNCTION() virtual void StartTrackingMouse(bool useMouseScreenOffset)
{
}
///
/// Gets the mouse tracking offset.
///
API_PROPERTY() Float2 GetTrackingMouseOffset() const
{
return _trackingMouseOffset;
}
///
/// Gets the value indicating whenever mouse input is tracked by this window.
///
API_PROPERTY() bool IsMouseTracking() const
{
return _isTrackingMouse;
}
///
/// Gets the value indicating if the mouse flipped to the other screen edge horizontally
///
API_PROPERTY() bool IsMouseFlippingHorizontally() const
{
return _isHorizontalFlippingMouse;
}
///
/// Gets the value indicating if the mouse flipped to the other screen edge vertically
///
API_PROPERTY() bool IsMouseFlippingVertically() const
{
return _isVerticalFlippingMouse;
}
///
/// Ends the mouse tracking.
///
API_FUNCTION() virtual void EndTrackingMouse()
{
}
///
/// Starts the cursor clipping.
///
/// The screen-space bounds that the cursor will be confined to.
API_FUNCTION() virtual void StartClippingCursor(const Rectangle& bounds)
{
}
///
/// Gets the value indicating whenever the cursor is being clipped.
///
API_PROPERTY() bool IsCursorClipping() const
{
return _isClippingCursor;
}
///
/// Ends the cursor clipping.
///
API_FUNCTION() virtual void EndClippingCursor()
{
}
///
/// Gets the mouse cursor.
///
API_PROPERTY() FORCE_INLINE CursorType GetCursor() const
{
return _cursor;
}
///
/// Sets the mouse cursor.
///
/// The cursor type.
API_PROPERTY() virtual void SetCursor(CursorType type)
{
_cursor = type;
}
///
/// Sets the window icon.
///
/// The icon.
virtual void SetIcon(TextureData& icon)
{
}
///
/// Gets the value indicating whenever rendering to this window enabled.
///
API_PROPERTY() bool GetRenderingEnabled() const;
///
/// Sets the value indicating whenever rendering to this window enabled.
///
API_PROPERTY() void SetRenderingEnabled(bool value);
public:
typedef Delegate CharDelegate;
typedef Delegate KeyboardDelegate;
typedef Delegate MouseDelegate;
typedef Delegate MouseButtonDelegate;
typedef Delegate MouseWheelDelegate;
typedef Delegate TouchDelegate;
typedef Delegate DragDelegate;
typedef Delegate HitTestDelegate;
typedef Delegate ButtonHitDelegate;
typedef Delegate ClosingDelegate;
///
/// Event fired on character input.
///
CharDelegate CharInput;
void OnCharInput(Char c);
///
/// Event fired on key pressed.
///
KeyboardDelegate KeyDown;
void OnKeyDown(KeyboardKeys key);
///
/// Event fired on key released.
///
KeyboardDelegate KeyUp;
void OnKeyUp(KeyboardKeys key);
///
/// Event fired when mouse button goes down.
///
MouseButtonDelegate MouseDown;
void OnMouseDown(const Float2& mousePosition, MouseButton button);
///
/// Event fired when mouse button goes up.
///
MouseButtonDelegate MouseUp;
void OnMouseUp(const Float2& mousePosition, MouseButton button);
///
/// Event fired when mouse button double clicks.
///
MouseButtonDelegate MouseDoubleClick;
void OnMouseDoubleClick(const Float2& mousePosition, MouseButton button);
///
/// Event fired when mouse wheel is scrolling (wheel delta is normalized).
///
MouseWheelDelegate MouseWheel;
void OnMouseWheel(const Float2& mousePosition, float delta);
///
/// Event fired when mouse moves.
///
MouseDelegate MouseMove;
void OnMouseMove(const Float2& mousePosition);
///
/// Event fired when mouse moves in relative mode.
///
MouseDelegate MouseMoveRelative;
void OnMouseMoveRelative(const Float2& mousePositionRelative);
///
/// Event fired when mouse leaves window.
///
Action MouseLeave;
void OnMouseLeave();
///
/// Event fired when touch action begins.
///
TouchDelegate TouchDown;
void OnTouchDown(const Float2& pointerPosition, int32 pointerIndex);
///
/// Event fired when touch action moves.
///
TouchDelegate TouchMove;
void OnTouchMove(const Float2& pointerPosition, int32 pointerIndex);
///
/// Event fired when touch action ends.
///
TouchDelegate TouchUp;
void OnTouchUp(const Float2& pointerPosition, int32 pointerIndex);
///
/// Event fired when drag&drop enters window.
///
DragDelegate DragEnter;
void OnDragEnter(IGuiData* data, const Float2& mousePosition, DragDropEffect& result);
///
/// Event fired when drag&drop moves over window.
///
DragDelegate DragOver;
void OnDragOver(IGuiData* data, const Float2& mousePosition, DragDropEffect& result);
///
/// Event fired when drag&drop ends over window with drop.
///
DragDelegate DragDrop;
void OnDragDrop(IGuiData* data, const Float2& mousePosition, DragDropEffect& result);
///
/// Event fired when drag&drop leaves window.
///
Action DragLeave;
void OnDragLeave();
///
/// Event fired when system tests if the specified location is part of the window.
///
HitTestDelegate HitTest;
void OnHitTest(const Float2& mousePosition, WindowHitCodes& result, bool& handled);
///
/// Event fired when system tests if the left button hit the window for the given hit code.
///
ButtonHitDelegate LeftButtonHit;
void OnLeftButtonHit(WindowHitCodes hit, bool& result);
///
/// Event fired when window is closing. Can be used to cancel the operation.
///
ClosingDelegate Closing;
void OnClosing(ClosingReason reason, bool& cancel);
public:
///
/// Gets the text entered during the current frame (Unicode).
///
/// The input text (Unicode).
API_PROPERTY() StringView GetInputText() const;
///
/// Gets the key state (true if key is being pressed during this frame).
///
/// Key ID to check
/// True while the user holds down the key identified by id
API_FUNCTION() bool GetKey(KeyboardKeys key) const;
///
/// Gets the key 'down' state (true if key was pressed in this frame).
///
/// Key ID to check
/// True during the frame the user starts pressing down the key
API_FUNCTION() bool GetKeyDown(KeyboardKeys key) const;
///
/// Gets the key 'up' state (true if key was released in this frame).
///
/// Key ID to check
/// True during the frame the user releases the key
API_FUNCTION() bool GetKeyUp(KeyboardKeys key) const;
public:
///
/// Gets the mouse position in window coordinates.
///
API_PROPERTY() Float2 GetMousePosition() const;
///
/// Sets the mouse position in window coordinates.
///
/// Mouse position to set on
API_PROPERTY() void SetMousePosition(const Float2& position) const;
///
/// Gets the mouse position change during the last frame.
///
/// Mouse cursor position delta
API_PROPERTY() Float2 GetMousePositionDelta() const;
///
/// Gets the mouse wheel change during the last frame.
///
API_PROPERTY() float GetMouseScrollDelta() const;
///
/// Gets the mouse button state.
///
/// Mouse button to check
/// True while the user holds down the button
API_FUNCTION() bool GetMouseButton(MouseButton button) const;
///
/// Gets the mouse button down state.
///
/// Mouse button to check
/// True during the frame the user starts pressing down the button
API_FUNCTION() bool GetMouseButtonDown(MouseButton button) const;
///
/// Gets the mouse button up state.
///
/// Mouse button to check
/// True during the frame the user releases the button
API_FUNCTION() bool GetMouseButtonUp(MouseButton button) const;
public:
void OnShow();
void OnResize(int32 width, int32 height);
void OnClosed();
void OnGotFocus();
void OnLostFocus();
private:
void OnMainRenderTaskDelete(class ScriptingObject* obj)
{
RenderTask = nullptr;
}
public:
// [ScriptingObject]
String ToString() const override;
void OnDeleteObject() override;
};