UI.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. //
  2. // Copyright (c) 2008-2017 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #pragma once
  23. #include "../Core/Object.h"
  24. #include "../UI/Cursor.h"
  25. #include "../UI/UIBatch.h"
  26. namespace Urho3D
  27. {
  28. class Cursor;
  29. class Graphics;
  30. class ResourceCache;
  31. class Timer;
  32. class UIBatch;
  33. class UIElement;
  34. class VertexBuffer;
  35. class XMLElement;
  36. class XMLFile;
  37. /// %UI subsystem. Manages the graphical user interface.
  38. class URHO3D_API UI : public Object
  39. {
  40. URHO3D_OBJECT(UI, Object);
  41. public:
  42. /// Construct.
  43. UI(Context* context);
  44. /// Destruct.
  45. virtual ~UI();
  46. /// Set cursor UI element.
  47. void SetCursor(Cursor* cursor);
  48. /// Set focused UI element.
  49. void SetFocusElement(UIElement* element, bool byKey = false);
  50. /// Set modal element. Until all the modal elements are dismissed, all the inputs and events are only sent to them. Return true when successful.
  51. /// Only the modal element can clear its modal status or when it is being destructed.
  52. bool SetModalElement(UIElement* modalElement, bool enable);
  53. /// Clear the UI (excluding the cursor.)
  54. void Clear();
  55. /// Update the UI logic. Called by HandlePostUpdate().
  56. void Update(float timeStep);
  57. /// Update the UI for rendering. Called by HandleRenderUpdate().
  58. void RenderUpdate();
  59. /// 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.
  60. void Render(bool resetRenderTargets = true);
  61. /// Debug draw a UI element.
  62. void DebugDraw(UIElement* element);
  63. /// Load a UI layout from an XML file. Optionally specify another XML file for element style. Return the root element.
  64. SharedPtr<UIElement> LoadLayout(Deserializer& source, XMLFile* styleFile = 0);
  65. /// Load a UI layout from an XML file. Optionally specify another XML file for element style. Return the root element.
  66. SharedPtr<UIElement> LoadLayout(XMLFile* file, XMLFile* styleFile = 0);
  67. /// Save a UI layout to an XML file. Return true if successful.
  68. bool SaveLayout(Serializer& dest, UIElement* element);
  69. /// Set clipboard text.
  70. void SetClipboardText(const String& text);
  71. /// Set UI element double click interval in seconds.
  72. void SetDoubleClickInterval(float interval);
  73. /// Set UI drag event start interval in seconds.
  74. void SetDragBeginInterval(float interval);
  75. /// Set UI drag event start distance threshold in pixels.
  76. void SetDragBeginDistance(int pixels);
  77. /// Set tooltip default display delay in seconds.
  78. void SetDefaultToolTipDelay(float delay);
  79. /// Set maximum font face texture size. Must be a power of two. Default is 2048.
  80. void SetMaxFontTextureSize(int size);
  81. /// Set whether mouse wheel can control also a non-focused element.
  82. void SetNonFocusedMouseWheel(bool nonFocusedMouseWheel);
  83. /// Set whether to use system clipboard. Default false.
  84. void SetUseSystemClipboard(bool enable);
  85. /// Set whether to show the on-screen keyboard (if supported) when a %LineEdit is focused. Default true on mobile devices.
  86. void SetUseScreenKeyboard(bool enable);
  87. /// Set whether to use mutable (eraseable) glyphs to ensure a font face never expands to more than one texture. Default false.
  88. void SetUseMutableGlyphs(bool enable);
  89. /// Set whether to force font autohinting instead of using FreeType's TTF bytecode interpreter.
  90. void SetForceAutoHint(bool enable);
  91. /// Set %UI scale. 1.0 is default (pixel perfect). Resize the root element to match.
  92. void SetScale(float scale);
  93. /// Scale %UI to the specified width in pixels.
  94. void SetWidth(float width);
  95. /// Scale %UI to the specified height in pixels.
  96. void SetHeight(float height);
  97. /// Set custom size of the root element. This disables automatic resizing of the root element according to window size. Set custom size 0,0 to return to automatic resizing.
  98. void SetCustomSize(const IntVector2& size);
  99. /// Set custom size of the root element.
  100. void SetCustomSize(int width, int height);
  101. /// Return root UI element.
  102. UIElement* GetRoot() const { return rootElement_; }
  103. /// Return root modal element.
  104. UIElement* GetRootModalElement() const { return rootModalElement_; }
  105. /// Return cursor.
  106. Cursor* GetCursor() const { return cursor_; }
  107. /// Return cursor position.
  108. IntVector2 GetCursorPosition() const;
  109. /// Return UI element at screen coordinates. By default returns only input-enabled elements.
  110. UIElement* GetElementAt(const IntVector2& position, bool enabledOnly = true);
  111. /// Return UI element at screen coordinates. By default returns only input-enabled elements.
  112. UIElement* GetElementAt(int x, int y, bool enabledOnly = true);
  113. /// Return focused element.
  114. UIElement* GetFocusElement() const { return focusElement_; }
  115. /// Return topmost enabled root-level non-modal element.
  116. UIElement* GetFrontElement() const;
  117. /// Return currently dragged elements.
  118. const Vector<UIElement*> GetDragElements();
  119. /// Return the number of currently dragged elements.
  120. unsigned GetNumDragElements() const { return (unsigned)dragConfirmedCount_; }
  121. /// Return the drag element at index.
  122. UIElement* GetDragElement(unsigned index);
  123. /// Return clipboard text.
  124. const String& GetClipboardText() const;
  125. /// Return UI element double click interval in seconds.
  126. float GetDoubleClickInterval() const { return doubleClickInterval_; }
  127. /// Return UI drag start event interval in seconds.
  128. float GetDragBeginInterval() const { return dragBeginInterval_; }
  129. /// Return UI drag start event distance threshold in pixels.
  130. int GetDragBeginDistance() const { return dragBeginDistance_; }
  131. /// Return tooltip default display delay in seconds.
  132. float GetDefaultToolTipDelay() const { return defaultToolTipDelay_; }
  133. /// Return font texture maximum size.
  134. int GetMaxFontTextureSize() const { return maxFontTextureSize_; }
  135. /// Return whether mouse wheel can control also a non-focused element.
  136. bool IsNonFocusedMouseWheel() const { return nonFocusedMouseWheel_; }
  137. /// Return whether is using the system clipboard.
  138. bool GetUseSystemClipboard() const { return useSystemClipboard_; }
  139. /// Return whether focusing a %LineEdit will show the on-screen keyboard.
  140. bool GetUseScreenKeyboard() const { return useScreenKeyboard_; }
  141. /// Return whether is using mutable (eraseable) glyphs for fonts.
  142. bool GetUseMutableGlyphs() const { return useMutableGlyphs_; }
  143. /// Return whether is using forced autohinting.
  144. bool GetForceAutoHint() const { return forceAutoHint_; }
  145. /// Return true when UI has modal element(s).
  146. bool HasModalElement() const;
  147. /// Return whether a drag is in progress.
  148. bool IsDragging() const { return dragConfirmedCount_ > 0; };
  149. /// Return current UI scale.
  150. float GetScale() const { return uiScale_; }
  151. /// Return root element custom size. Returns 0,0 when custom size is not being used and automatic resizing according to window size is in use instead (default.)
  152. const IntVector2& GetCustomSize() const { return customSize_; }
  153. /// Data structure used to represent the drag data associated to a UIElement.
  154. struct DragData
  155. {
  156. /// Which button combo initiated the drag.
  157. int dragButtons;
  158. /// How many buttons initiated the drag.
  159. int numDragButtons;
  160. /// Sum of all touch locations
  161. IntVector2 sumPos;
  162. /// Flag for a drag start event pending.
  163. bool dragBeginPending;
  164. /// Timer used to trigger drag begin event.
  165. Timer dragBeginTimer;
  166. /// Drag start position.
  167. IntVector2 dragBeginSumPos;
  168. };
  169. private:
  170. /// Initialize when screen mode initially set.
  171. void Initialize();
  172. /// Update UI element logic recursively.
  173. void Update(float timeStep, UIElement* element);
  174. /// Upload UI geometry into a vertex buffer.
  175. void SetVertexData(VertexBuffer* dest, const PODVector<float>& vertexData);
  176. /// Render UI batches. Geometry must have been uploaded first.
  177. void Render
  178. (bool resetRenderTargets, VertexBuffer* buffer, const PODVector<UIBatch>& batches, unsigned batchStart, unsigned batchEnd);
  179. /// Generate batches from an UI element recursively. Skip the cursor element.
  180. void GetBatches(UIElement* element, IntRect currentScissor);
  181. /// Return UI element at screen position recursively.
  182. void GetElementAt(UIElement*& result, UIElement* current, const IntVector2& position, bool enabledOnly);
  183. /// Return the first element in hierarchy that can alter focus.
  184. UIElement* GetFocusableElement(UIElement* element);
  185. /// Return cursor position and visibility either from the cursor element, or the Input subsystem.
  186. void GetCursorPositionAndVisible(IntVector2& pos, bool& visible);
  187. /// Set active cursor's shape.
  188. void SetCursorShape(CursorShape shape);
  189. /// Force release of font faces when global font properties change.
  190. void ReleaseFontFaces();
  191. /// Handle button or touch hover.
  192. void ProcessHover(const IntVector2& cursorPos, int buttons, int qualifiers, Cursor* cursor);
  193. /// Handle button or touch begin.
  194. void
  195. ProcessClickBegin(const IntVector2& cursorPos, int button, int buttons, int qualifiers, Cursor* cursor, bool cursorVisible);
  196. /// Handle button or touch end.
  197. void ProcessClickEnd(const IntVector2& cursorPos, int button, int buttons, int qualifiers, Cursor* cursor, bool cursorVisible);
  198. /// Handle mouse or touch move.
  199. void ProcessMove(const IntVector2& cursorPos, const IntVector2& cursorDeltaPos, int buttons, int qualifiers, Cursor* cursor,
  200. bool cursorVisible);
  201. /// Send a UI element drag or hover begin event.
  202. void SendDragOrHoverEvent
  203. (StringHash eventType, UIElement* element, const IntVector2& screenPos, const IntVector2& deltaPos, UI::DragData* dragData);
  204. /// Send a UI click or double click event.
  205. void SendClickEvent
  206. (StringHash eventType, UIElement* beginElement, UIElement* endElement, const IntVector2& pos, int button, int buttons,
  207. int qualifiers);
  208. /// Handle screen mode event.
  209. void HandleScreenMode(StringHash eventType, VariantMap& eventData);
  210. /// Handle mouse button down event.
  211. void HandleMouseButtonDown(StringHash eventType, VariantMap& eventData);
  212. /// Handle mouse button up event.
  213. void HandleMouseButtonUp(StringHash eventType, VariantMap& eventData);
  214. /// Handle mouse move event.
  215. void HandleMouseMove(StringHash eventType, VariantMap& eventData);
  216. /// Handle mouse wheel event.
  217. void HandleMouseWheel(StringHash eventType, VariantMap& eventData);
  218. /// Handle touch begin event.
  219. void HandleTouchBegin(StringHash eventType, VariantMap& eventData);
  220. /// Handle touch end event.
  221. void HandleTouchEnd(StringHash eventType, VariantMap& eventData);
  222. /// Handle touch move event.
  223. void HandleTouchMove(StringHash eventType, VariantMap& eventData);
  224. /// Handle keypress event.
  225. void HandleKeyDown(StringHash eventType, VariantMap& eventData);
  226. /// Handle text input event.
  227. void HandleTextInput(StringHash eventType, VariantMap& eventData);
  228. /// Handle frame begin event.
  229. void HandleBeginFrame(StringHash eventType, VariantMap& eventData);
  230. /// Handle logic post-update event.
  231. void HandlePostUpdate(StringHash eventType, VariantMap& eventData);
  232. /// Handle render update event.
  233. void HandleRenderUpdate(StringHash eventType, VariantMap& eventData);
  234. /// Handle a file being drag-dropped into the application window.
  235. void HandleDropFile(StringHash eventType, VariantMap& eventData);
  236. /// Remove drag data and return next iterator.
  237. HashMap<WeakPtr<UIElement>, DragData*>::Iterator DragElementErase(HashMap<WeakPtr<UIElement>, DragData*>::Iterator dragElement);
  238. /// Handle clean up on a drag cancel.
  239. void ProcessDragCancel();
  240. /// Sum touch positions and return the begin position ready to send.
  241. IntVector2 SumTouchPositions(UI::DragData* dragData, const IntVector2& oldSendPos);
  242. /// Resize root element to effective size.
  243. void ResizeRootElement();
  244. /// Return effective size of the root element, according to UI scale and resolution / custom size.
  245. IntVector2 GetEffectiveRootElementSize(bool applyScale = true) const;
  246. /// Graphics subsystem.
  247. WeakPtr<Graphics> graphics_;
  248. /// UI root element.
  249. SharedPtr<UIElement> rootElement_;
  250. /// UI root modal element.
  251. SharedPtr<UIElement> rootModalElement_;
  252. /// Cursor.
  253. SharedPtr<Cursor> cursor_;
  254. /// Currently focused element.
  255. WeakPtr<UIElement> focusElement_;
  256. /// UI rendering batches.
  257. PODVector<UIBatch> batches_;
  258. /// UI rendering vertex data.
  259. PODVector<float> vertexData_;
  260. /// UI rendering batches for debug draw.
  261. PODVector<UIBatch> debugDrawBatches_;
  262. /// UI rendering vertex data for debug draw.
  263. PODVector<float> debugVertexData_;
  264. /// UI vertex buffer.
  265. SharedPtr<VertexBuffer> vertexBuffer_;
  266. /// UI debug geometry vertex buffer.
  267. SharedPtr<VertexBuffer> debugVertexBuffer_;
  268. /// UI element query vector.
  269. PODVector<UIElement*> tempElements_;
  270. /// Clipboard text.
  271. mutable String clipBoard_;
  272. /// Seconds between clicks to register a double click.
  273. float doubleClickInterval_;
  274. /// Seconds from mouse button down to begin a drag if there has been no movement exceeding pixel threshold.
  275. float dragBeginInterval_;
  276. /// Tooltip default display delay in seconds.
  277. float defaultToolTipDelay_;
  278. /// Drag begin event distance threshold in pixels.
  279. int dragBeginDistance_;
  280. /// Mouse buttons held down.
  281. int mouseButtons_;
  282. /// Last mouse button pressed.
  283. int lastMouseButtons_;
  284. /// Qualifier keys held down.
  285. int qualifiers_;
  286. /// Font texture maximum size.
  287. int maxFontTextureSize_;
  288. /// Initialized flag.
  289. bool initialized_;
  290. /// Touch used flag.
  291. bool usingTouchInput_;
  292. /// Flag to switch mouse wheel event to be sent to non-focused element at cursor.
  293. bool nonFocusedMouseWheel_;
  294. /// Flag for using operating system clipboard instead of internal.
  295. bool useSystemClipboard_;
  296. /// Flag for showing the on-screen keyboard on focusing a %LineEdit.
  297. bool useScreenKeyboard_;
  298. /// Flag for using mutable (erasable) font glyphs.
  299. bool useMutableGlyphs_;
  300. /// Flag for forcing FreeType auto hinting.
  301. bool forceAutoHint_;
  302. /// Flag for UI already being rendered this frame.
  303. bool uiRendered_;
  304. /// Non-modal batch size (used internally for rendering).
  305. unsigned nonModalBatchSize_;
  306. /// Timer used to trigger double click.
  307. Timer clickTimer_;
  308. /// UI element last clicked for tracking double clicks.
  309. WeakPtr<UIElement> doubleClickElement_;
  310. /// Currently hovered elements.
  311. HashMap<WeakPtr<UIElement>, bool> hoveredElements_;
  312. /// Currently dragged elements.
  313. HashMap<WeakPtr<UIElement>, DragData*> dragElements_;
  314. /// Number of elements in dragElements_.
  315. int dragElementsCount_;
  316. /// Number of elements in dragElements_ with dragPending = false.
  317. int dragConfirmedCount_;
  318. /// UI elements that are being touched with touch input.
  319. HashMap<WeakPtr<UIElement>, int> touchDragElements_;
  320. /// Confirmed drag elements cache.
  321. Vector<UIElement*> dragElementsConfirmed_;
  322. /// Current scale of UI.
  323. float uiScale_;
  324. /// Root element custom size. 0,0 for automatic resizing (default.)
  325. IntVector2 customSize_;
  326. };
  327. /// Register UI library objects.
  328. void URHO3D_API RegisterUILibrary(Context* context);
  329. }