// 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; bool _restoreRelativeMode = 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 a value that indicates whether a window is always on top of other windows. /// API_PROPERTY() virtual bool IsAlwaysOnTop() const; /// /// Sets a value that indicates whether a window is always on top of other windows. /// /// True if always on top. API_PROPERTY() virtual void SetIsAlwaysOnTop(bool isAlwaysOnTop); /// /// 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 a drag and drop operation. /// /// The data. /// The result. API_FUNCTION() virtual DragDropEffect DoDragDrop(const StringView& data) { return DragDropEffect::None; } /// /// Starts a window drag and drop operation. /// /// The data. /// The offset for positioning the window from cursor. /// The window where dragging started. /// The result. API_FUNCTION() virtual DragDropEffect DoDragDrop(const StringView& data, const Float2& offset, Window* dragSourceWindow) { 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; };