// // Copyright (c) 2008-2015 the Urho3D project. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // #pragma once #include "../../Core/Object.h" #include "Cursor.h" #include "SystemUIBatch.h" namespace Atomic { class Graphics; class ResourceCache; class Timer; class VertexBuffer; class XMLElement; class XMLFile; namespace SystemUI { class Cursor; class SystemUIBatch; class UIElement; /// %UI subsystem. Manages the graphical user interface. class ATOMIC_API SystemUI : public Object { OBJECT(SystemUI); public: /// Construct. SystemUI(Context* context); /// Destruct. virtual ~SystemUI(); /// Set cursor UI element. void SetCursor(Cursor* cursor); /// Set focused UI element. void SetFocusElement(UIElement* element, bool byKey = false); /// Set modal element. Until all the modal elements are dismissed, all the inputs and events are only sent to them. Return true when successful. /// Only the modal element can clear its modal status or when it is being destructed. bool SetModalElement(UIElement* modalElement, bool enable); /// Clear the UI (excluding the cursor.) void Clear(); /// Update the UI logic. Called by HandlePostUpdate(). void Update(float timeStep); /// Update the UI for rendering. Called by HandleRenderUpdate(). void RenderUpdate(); /// Render the UI. If resetRenderTargets is true, is assumed to be the default UI render to backbuffer called by Engine, and will be performed only once. Additional UI renders to a different rendertarget may be triggered from the renderpath. void Render(bool resetRenderTargets = true); /// Debug draw a UI element. void DebugDraw(UIElement* element); /// Load a UI layout from an XML file. Optionally specify another XML file for element style. Return the root element. SharedPtr LoadLayout(Deserializer& source, XMLFile* styleFile = 0); /// Load a UI layout from an XML file. Optionally specify another XML file for element style. Return the root element. SharedPtr LoadLayout(XMLFile* file, XMLFile* styleFile = 0); /// Save a UI layout to an XML file. Return true if successful. bool SaveLayout(Serializer& dest, UIElement* element); /// Set clipboard text. void SetClipboardText(const String& text); /// Set UI element double click interval in seconds. void SetDoubleClickInterval(float interval); /// Set UI drag event start interval in seconds. void SetDragBeginInterval(float interval); /// Set UI drag event start distance threshold in pixels. void SetDragBeginDistance(int pixels); /// Set tooltip default display delay in seconds. void SetDefaultToolTipDelay(float delay); /// Set maximum font face texture size. Must be a power of two. Default is 2048. void SetMaxFontTextureSize(int size); /// Set whether mouse wheel can control also a non-focused element. void SetNonFocusedMouseWheel(bool nonFocusedMouseWheel); /// Set whether to use system clipboard. Default false. void SetUseSystemClipboard(bool enable); /// Set whether to show the on-screen keyboard (if supported) when a %LineEdit is focused. Default true on mobile devices. void SetUseScreenKeyboard(bool enable); /// Set whether to use mutable (eraseable) glyphs to ensure a font face never expands to more than one texture. Default false. void SetUseMutableGlyphs(bool enable); /// Set whether to force font autohinting instead of using FreeType's TTF bytecode interpreter. void SetForceAutoHint(bool enable); /// Return root UI element. UIElement* GetRoot() const { return rootElement_; } /// Return root modal element. UIElement* GetRootModalElement() const { return rootModalElement_; } /// Return cursor. Cursor* GetCursor() const { return cursor_; } /// Return cursor position. IntVector2 GetCursorPosition() const; /// Return UI element at screen coordinates. By default returns only input-enabled elements. UIElement* GetElementAt(const IntVector2& position, bool enabledOnly = true); /// Return UI element at screen coordinates. By default returns only input-enabled elements. UIElement* GetElementAt(int x, int y, bool enabledOnly = true); /// Return focused element. UIElement* GetFocusElement() const { return focusElement_; } /// Return topmost enabled root-level non-modal element. UIElement* GetFrontElement() const; /// Return currently dragged elements. const Vector GetDragElements(); /// Return the number of currently dragged elements. unsigned GetNumDragElements() const { return (unsigned)dragConfirmedCount_; } /// Return the drag element at index. UIElement* GetDragElement(unsigned index); /// Return clipboard text. const String& GetClipboardText() const; /// Return UI element double click interval in seconds. float GetDoubleClickInterval() const { return doubleClickInterval_; } /// Return UI drag start event interval in seconds. float GetDragBeginInterval() const { return dragBeginInterval_; } /// Return UI drag start event distance threshold in pixels. int GetDragBeginDistance() const { return dragBeginDistance_; } /// Return tooltip default display delay in seconds. float GetDefaultToolTipDelay() const { return defaultToolTipDelay_; } /// Return font texture maximum size. int GetMaxFontTextureSize() const { return maxFontTextureSize_; } /// Return whether mouse wheel can control also a non-focused element. bool IsNonFocusedMouseWheel() const { return nonFocusedMouseWheel_; } /// Return whether is using the system clipboard. bool GetUseSystemClipboard() const { return useSystemClipboard_; } /// Return whether focusing a %LineEdit will show the on-screen keyboard. bool GetUseScreenKeyboard() const { return useScreenKeyboard_; } /// Return whether is using mutable (eraseable) glyphs for fonts. bool GetUseMutableGlyphs() const { return useMutableGlyphs_; } /// Return whether is using forced autohinting. bool GetForceAutoHint() const { return forceAutoHint_; } /// Return true when UI has modal element(s). bool HasModalElement() const; /// Return whether a drag is in progress. bool IsDragging() const { return dragConfirmedCount_ > 0; } /// Data structure used to represent the drag data associated to a UIElement. struct DragData { /// Which button combo initiated the drag. int dragButtons; /// How many buttons initiated the drag. int numDragButtons; /// Sum of all touch locations IntVector2 sumPos; /// Flag for a drag start event pending. bool dragBeginPending; /// Timer used to trigger drag begin event. Timer dragBeginTimer; /// Drag start position. IntVector2 dragBeginSumPos; }; void CreateConsoleAndDebugHud(); private: /// Initialize when screen mode initially set. void Initialize(); /// Update UI element logic recursively. void Update(float timeStep, UIElement* element); /// Upload UI geometry into a vertex buffer. void SetVertexData(VertexBuffer* dest, const PODVector& vertexData); /// Render UI batches. Geometry must have been uploaded first. void Render (bool resetRenderTargets, VertexBuffer* buffer, const PODVector& batches, unsigned batchStart, unsigned batchEnd); /// Generate batches from an UI element recursively. Skip the cursor element. void GetBatches(UIElement* element, IntRect currentScissor); /// Return UI element at screen position recursively. void GetElementAt(UIElement*& result, UIElement* current, const IntVector2& position, bool enabledOnly); /// Return the first element in hierarchy that can alter focus. UIElement* GetFocusableElement(UIElement* element); /// Return cursor position and visibility either from the cursor element, or the Input subsystem. void GetCursorPositionAndVisible(IntVector2& pos, bool& visible); /// Set active cursor's shape. void SetCursorShape(CursorShape shape); /// Force release of font faces when global font properties change. void ReleaseFontFaces(); /// Handle button or touch hover void ProcessHover(const IntVector2& cursorPos, int buttons, int qualifiers, Cursor* cursor); /// Handle button or touch begin. void ProcessClickBegin(const IntVector2& cursorPos, int button, int buttons, int qualifiers, Cursor* cursor, bool cursorVisible); /// Handle button or touch end. void ProcessClickEnd(const IntVector2& cursorPos, int button, int buttons, int qualifiers, Cursor* cursor, bool cursorVisible); /// Handle mouse or touch move. void ProcessMove(const IntVector2& cursorPos, const IntVector2& cursorDeltaPos, int buttons, int qualifiers, Cursor* cursor, bool cursorVisible); /// Send a UI element drag or hover begin event. void SendDragOrHoverEvent (StringHash eventType, UIElement* element, const IntVector2& screenPos, const IntVector2& deltaPos, SystemUI::DragData* dragData); /// Send a UI click or double click event. void SendClickEvent (StringHash eventType, UIElement* beginElement, UIElement* endElement, const IntVector2& pos, int button, int buttons, int qualifiers); /// Handle screen mode event. void HandleScreenMode(StringHash eventType, VariantMap& eventData); /// Handle mouse button down event. void HandleMouseButtonDown(StringHash eventType, VariantMap& eventData); /// Handle mouse button up event. void HandleMouseButtonUp(StringHash eventType, VariantMap& eventData); /// Handle mouse move event. void HandleMouseMove(StringHash eventType, VariantMap& eventData); /// Handle mouse wheel event. void HandleMouseWheel(StringHash eventType, VariantMap& eventData); /// Handle touch begin event. void HandleTouchBegin(StringHash eventType, VariantMap& eventData); /// Handle touch end event. void HandleTouchEnd(StringHash eventType, VariantMap& eventData); /// Handle touch move event. void HandleTouchMove(StringHash eventType, VariantMap& eventData); /// Handle keypress event. void HandleKeyDown(StringHash eventType, VariantMap& eventData); /// Handle text input event. void HandleTextInput(StringHash eventType, VariantMap& eventData); /// Handle frame begin event. void HandleBeginFrame(StringHash eventType, VariantMap& eventData); /// Handle logic post-update event. void HandlePostUpdate(StringHash eventType, VariantMap& eventData); /// Handle render update event. void HandleRenderUpdate(StringHash eventType, VariantMap& eventData); /// Handle a file being drag-dropped into the application window. void HandleDropFile(StringHash eventType, VariantMap& eventData); /// Remove drag data and return next iterator. HashMap, DragData*>::Iterator DragElementErase(HashMap, DragData*>::Iterator dragElement); /// Handle clean up on a drag cancel. void ProcessDragCancel(); /// Sum touch positions and return the begin position ready to send. IntVector2 SumTouchPositions(SystemUI::DragData* dragData, const IntVector2& oldSendPos); /// Graphics subsystem. WeakPtr graphics_; /// UI root element. SharedPtr rootElement_; /// UI root modal element. SharedPtr rootModalElement_; /// Cursor. SharedPtr cursor_; /// Currently focused element. WeakPtr focusElement_; /// UI rendering batches. PODVector batches_; /// UI rendering vertex data. PODVector vertexData_; /// UI rendering batches for debug draw. PODVector debugDrawBatches_; /// UI rendering vertex data for debug draw. PODVector debugVertexData_; /// UI vertex buffer. SharedPtr vertexBuffer_; /// UI debug geometry vertex buffer. SharedPtr debugVertexBuffer_; /// UI element query vector. PODVector tempElements_; /// Clipboard text. mutable String clipBoard_; /// Seconds between clicks to register a double click. float doubleClickInterval_; /// Seconds from mouse button down to begin a drag if there has been no movement exceeding pixel threshold. float dragBeginInterval_; /// Tooltip default display delay in seconds. float defaultToolTipDelay_; /// Drag begin event distance threshold in pixels. int dragBeginDistance_; /// Mouse buttons held down. int mouseButtons_; /// Last mouse button pressed. int lastMouseButtons_; /// Qualifier keys held down. int qualifiers_; /// Font texture maximum size. int maxFontTextureSize_; /// Initialized flag. bool initialized_; /// Touch used flag. bool usingTouchInput_; /// Flag to switch mouse wheel event to be sent to non-focused element at cursor. bool nonFocusedMouseWheel_; /// Flag for using operating system clipboard instead of internal. bool useSystemClipboard_; /// Flag for showing the on-screen keyboard on focusing a %LineEdit. bool useScreenKeyboard_; /// Flag for using mutable (erasable) font glyphs. bool useMutableGlyphs_; /// Flag for forcing FreeType auto hinting. bool forceAutoHint_; /// Flag for UI already being rendered this frame. bool uiRendered_; /// Non-modal batch size (used internally for rendering). unsigned nonModalBatchSize_; /// Timer used to trigger double click. Timer clickTimer_; /// UI element last clicked for tracking double clicks. WeakPtr doubleClickElement_; /// Currently hovered elements. HashMap, bool> hoveredElements_; /// Currently dragged elements. HashMap, DragData*> dragElements_; /// Number of elements in dragElements_. int dragElementsCount_; /// Number of elements in dragElements_ with dragPending = false. int dragConfirmedCount_; /// UI elements that are being touched with touch input. HashMap, int> touchDragElements_; /// Confirmed drag elements cache. Vector dragElementsConfirmed_; }; /// Register UI library objects. void ATOMIC_API RegisterSystemUILibrary(Context* context); } }