UIElement.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. //
  2. // Urho3D Engine
  3. // Copyright (c) 2008-2012 Lasse Öörni
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. #pragma once
  24. #include "Object.h"
  25. #include "UIBatch.h"
  26. #include "Vector2.h"
  27. #include "XMLFile.h"
  28. /// %UI element horizontal alignment.
  29. enum HorizontalAlignment
  30. {
  31. HA_LEFT = 0,
  32. HA_CENTER,
  33. HA_RIGHT
  34. };
  35. /// %UI element vertical alignment.
  36. enum VerticalAlignment
  37. {
  38. VA_TOP = 0,
  39. VA_CENTER,
  40. VA_BOTTOM
  41. };
  42. /// %UI element corners.
  43. enum Corner
  44. {
  45. C_TOPLEFT = 0,
  46. C_TOPRIGHT,
  47. C_BOTTOMLEFT,
  48. C_BOTTOMRIGHT,
  49. MAX_UIELEMENT_CORNERS
  50. };
  51. /// %UI element orientation.
  52. enum Orientation
  53. {
  54. O_HORIZONTAL = 0,
  55. O_VERTICAL
  56. };
  57. /// %UI element focus mode.
  58. enum FocusMode
  59. {
  60. /// Is not focusable and does not affect existing focus.
  61. FM_NOTFOCUSABLE = 0,
  62. /// Resets focus when clicked.
  63. FM_RESETFOCUS,
  64. /// Is focusable.
  65. FM_FOCUSABLE,
  66. /// Is focusable and also defocusable by pressing ESC.
  67. FM_FOCUSABLE_DEFOCUSABLE
  68. };
  69. /// Layout operation mode.
  70. enum LayoutMode
  71. {
  72. /// No layout operations will be performed.
  73. LM_FREE = 0,
  74. /// Layout child elements horizontally and resize them to fit. Resize element if necessary.
  75. LM_HORIZONTAL,
  76. /// Layout child elements vertically and resize them to fit. Resize element if necessary.
  77. LM_VERTICAL
  78. };
  79. /// Drag and drop disabled.
  80. static const unsigned DD_DISABLED = 0x0;
  81. /// Drag and drop source flag.
  82. static const unsigned DD_SOURCE = 0x1;
  83. /// Drag and drop target flag.
  84. static const unsigned DD_TARGET = 0x2;
  85. /// Drag and drop source and target.
  86. static const unsigned DD_SOURCE_AND_TARGET = 0x3;
  87. class Cursor;
  88. class ResourceCache;
  89. class asIScriptEngine;
  90. /// Base class for %UI elements.
  91. class UIElement : public Object
  92. {
  93. OBJECT(UIElement);
  94. public:
  95. /// Construct.
  96. UIElement(Context* context);
  97. /// Destruct.
  98. virtual ~UIElement();
  99. /// Register object factory.
  100. static void RegisterObject(Context* context);
  101. /// %Set UI element style from XML data.
  102. virtual void SetStyle(const XMLElement& element);
  103. /// Perform UI element update.
  104. virtual void Update(float timeStep);
  105. /// Return UI rendering batches.
  106. virtual void GetBatches(PODVector<UIBatch>& batches, PODVector<UIQuad>& quads, const IntRect& currentScissor);
  107. /// React to mouse hover.
  108. virtual void OnHover(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor);
  109. /// React to mouse click.
  110. virtual void OnClick(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor);
  111. /// React to mouse drag start.
  112. virtual void OnDragStart(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor);
  113. /// React to mouse drag motion.
  114. virtual void OnDragMove(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor);
  115. /// React to mouse drag end.
  116. virtual void OnDragEnd(const IntVector2& position, const IntVector2& screenPosition, Cursor* cursor);
  117. /// React to drag and drop test. Return true to signal that the drop is acceptable.
  118. virtual bool OnDragDropTest(UIElement* source);
  119. /// React to drag and drop finish. Return true to signal that the drop was accepted.
  120. virtual bool OnDragDropFinish(UIElement* source);
  121. /// React to mouse wheel.
  122. virtual void OnWheel(int delta, int buttons, int qualifiers);
  123. /// React to a key press.
  124. virtual void OnKey(int key, int buttons, int qualifiers);
  125. /// React to a key press translated to a character.
  126. virtual void OnChar(unsigned c, int buttons, int qualifiers);
  127. /// React to resize.
  128. virtual void OnResize();
  129. /// %Set name.
  130. void SetName(const String& name);
  131. /// %Set position.
  132. void SetPosition(const IntVector2& position);
  133. /// %Set position.
  134. void SetPosition(int x, int y);
  135. /// %Set size.
  136. void SetSize(const IntVector2& size);
  137. /// %Set size.
  138. void SetSize(int width, int height);
  139. /// %Set width only.
  140. void SetWidth(int width);
  141. /// %Set height only.
  142. void SetHeight(int height);
  143. /// %Set minimum size.
  144. void SetMinSize(const IntVector2& minSize);
  145. /// %Set minimum size.
  146. void SetMinSize(int width, int height);
  147. /// %Set minimum width.
  148. void SetMinWidth(int width);
  149. /// %Set minimum height.
  150. void SetMinHeight(int height);
  151. /// %Set maximum size.
  152. void SetMaxSize(const IntVector2& maxSize);
  153. /// %Set maximum size.
  154. void SetMaxSize(int width, int height);
  155. /// %Set maximum width.
  156. void SetMaxWidth(int width);
  157. /// %Set maximum height.
  158. void SetMaxHeight(int height);
  159. /// %Set fixed size.
  160. void SetFixedSize(const IntVector2& size);
  161. /// %Set fixed size.
  162. void SetFixedSize(int width, int height);
  163. /// %Set fixed width.
  164. void SetFixedWidth(int width);
  165. /// %Set fixed height.
  166. void SetFixedHeight(int height);
  167. /// %Set horizontal and vertical alignment.
  168. void SetAlignment(HorizontalAlignment hAlign, VerticalAlignment vAlign);
  169. /// %Set horizontal alignment.
  170. void SetHorizontalAlignment(HorizontalAlignment align);
  171. /// %Set vertical alignment.
  172. void SetVerticalAlignment(VerticalAlignment align);
  173. /// %Set child element clipping border.
  174. void SetClipBorder(const IntRect& rect);
  175. /// %Set color on all corners.
  176. void SetColor(const Color& color);
  177. /// %Set color on one corner.
  178. void SetColor(Corner corner, const Color& color);
  179. /// %Set priority.
  180. void SetPriority(int priority);
  181. /// %Set opacity.
  182. void SetOpacity(float opacity);
  183. /// %Set whether should be brought to front when focused.
  184. void SetBringToFront(bool enable);
  185. /// %Set whether should be put to background when another element is focused.
  186. void SetBringToBack(bool enable);
  187. /// %Set whether should clip child elements. Default false.
  188. void SetClipChildren(bool enable);
  189. /// %Set whether should sort child elements according to priority. Default true.
  190. void SetSortChildren(bool enable);
  191. /// %Set whether reacts to input.
  192. void SetActive(bool enable);
  193. /// %Set whether is focused. Only one element can be focused at a time.
  194. void SetFocus(bool enable);
  195. /// %Set selected mode. Actual meaning is element dependent, for example constant hover or pressed effect.
  196. void SetSelected(bool enable);
  197. /// %Set whether is visible.
  198. void SetVisible(bool enable);
  199. /// %Set focus mode.
  200. void SetFocusMode(FocusMode mode);
  201. /// %Set drag and drop flags.
  202. void SetDragDropMode(unsigned mode);
  203. /// %Set style from an XML file. Find the style element by name.
  204. void SetStyle(XMLFile* file, const String& typeName);
  205. /// %Set style from an XML file. Find the style element automatically.
  206. void SetStyleAuto(XMLFile* file);
  207. /// %Set layout.
  208. void SetLayout(LayoutMode mode, int spacing = 0, const IntRect& border = IntRect::ZERO);
  209. /// %Set layout mode only.
  210. void SetLayoutMode(LayoutMode mode);
  211. /// %Set layout spacing.
  212. void SetLayoutSpacing(int spacing);
  213. /// %Set layout border.
  214. void SetLayoutBorder(const IntRect& border);
  215. /// Manually update layout. Should not be necessary in most cases, but is provided for completeness.
  216. void UpdateLayout();
  217. /// Disable automatic layout update. Should only be used if there are performance problems.
  218. void DisableLayoutUpdate();
  219. /// Enable automatic layout update.
  220. void EnableLayoutUpdate();
  221. /// Bring UI element to front.
  222. void BringToFront();
  223. /// Add a child element.
  224. void AddChild(UIElement* element);
  225. /// Insert a child element into a specific position in the child list.
  226. void InsertChild(unsigned index, UIElement* element);
  227. /// Remove a child element.
  228. void RemoveChild(UIElement* element);
  229. /// Remove all child elements.
  230. void RemoveAllChildren();
  231. /// Remove from the parent element. If no other shared pointer references exist, causes immediate deletion.
  232. void Remove();
  233. /// %Set parent element. Same as parent->AddChild(this).
  234. void SetParent(UIElement* parent);
  235. /// Return name.
  236. const String& GetName() const { return name_; }
  237. /// Return position.
  238. const IntVector2& GetPosition() const { return position_; }
  239. /// Return screen position.
  240. IntVector2 GetScreenPosition();
  241. /// Return size.
  242. const IntVector2& GetSize() const { return size_; }
  243. /// Return width.
  244. int GetWidth() const { return size_.x_; }
  245. /// Return height.
  246. int GetHeight() const { return size_.y_; }
  247. /// Return minimum size.
  248. const IntVector2& GetMinSize() const { return minSize_; }
  249. /// Return minimum width.
  250. int GetMinWidth() const { return minSize_.x_; }
  251. /// Return minimum height.
  252. int GetMinHeight() const { return minSize_.y_; }
  253. /// Return maximum size.
  254. const IntVector2& GetMaxSize() const { return maxSize_; }
  255. /// Return minimum width.
  256. int GetMaxWidth() const { return maxSize_.x_; }
  257. /// Return minimum height.
  258. int GetMaxHeight() const { return maxSize_.y_; }
  259. /// Return child element offset.
  260. const IntVector2& GetChildOffset() const { return childOffset_; }
  261. /// Return horizontal alignment.
  262. HorizontalAlignment GetHorizontalAlignment() const { return horizontalAlignment_; }
  263. /// Return vertical alignment.
  264. VerticalAlignment GetVerticalAlignment() const { return verticalAlignment_; }
  265. /// Return child element clipping border.
  266. const IntRect& GetClipBorder() const { return clipBorder_; }
  267. /// Return corner color.
  268. const Color& GetColor(Corner corner) const { return color_[corner]; }
  269. /// Return priority.
  270. int GetPriority() const { return priority_; }
  271. /// Return opacity.
  272. float GetOpacity() const { return opacity_; }
  273. /// Return derived opacity (affected by parent elements.)
  274. float GetDerivedOpacity();
  275. /// Return whether should be brought to front when focused.
  276. bool GetBringToFront() const { return bringToFront_; }
  277. /// Return whether should be put to background when another element is focused.
  278. bool GetBringToBack() const { return bringToBack_; }
  279. /// Return whether should clip child elements.
  280. bool GetClipChildren() const { return clipChildren_; }
  281. /// Return whether should sort child elements according to priority.
  282. bool GetSortChildren() const { return sortChildren_; }
  283. /// Return whether has focus.
  284. bool HasFocus() const;
  285. /// Return whether reacts to input.
  286. bool IsActive() const { return active_; }
  287. /// Return whether is selected. Actual meaning is element dependent.
  288. bool IsSelected() const { return selected_; }
  289. /// Return whether is visible.
  290. bool IsVisible() const { return visible_; }
  291. /// Return whether the cursor is hovering on this element.
  292. bool IsHovering() const { return hovering_; }
  293. /// Return whether has different color in at least one corner.
  294. bool HasColorGradient() const { return colorGradient_; }
  295. /// Return focus mode.
  296. FocusMode GetFocusMode() const { return focusMode_; }
  297. /// Return drag and drop flags.
  298. unsigned GetDragDropMode() const { return dragDropMode_; }
  299. /// Return layout mode.
  300. LayoutMode GetLayoutMode() const { return layoutMode_; }
  301. /// Return layout spacing.
  302. int GetLayoutSpacing() const { return layoutSpacing_; }
  303. /// Return layout border.
  304. const IntRect& GetLayoutBorder() const { return layoutBorder_; }
  305. /// Return number of child elements.
  306. unsigned GetNumChildren(bool recursive = false) const;
  307. /// Return child element by index.
  308. UIElement* GetChild(unsigned index) const;
  309. /// Return child element by name.
  310. UIElement* GetChild(const String& name, bool recursive = false) const;
  311. /// Return immediate child elements.
  312. const Vector<SharedPtr<UIElement> >& GetChildren() const { return children_; }
  313. /// Return child elements either recursively or non-recursively.
  314. void GetChildren(PODVector<UIElement*>& dest, bool recursive = false) const;
  315. /// Return parent element.
  316. UIElement* GetParent() const { return parent_; }
  317. /// Return root element.
  318. UIElement* GetRoot() const;
  319. /// Return precalculated 32-bit color. Only valid when no gradient.
  320. unsigned GetUIntColor();
  321. /// Return user variables.
  322. VariantMap& GetVars() { return vars_; }
  323. /// Convert screen coordinates to element coordinates.
  324. IntVector2 ScreenToElement(const IntVector2& screenPosition);
  325. /// Convert element coordinates to screen coordinates.
  326. IntVector2 ElementToScreen(const IntVector2& position);
  327. /// Return whether a point (either in element or screen coordinates) is inside the element.
  328. bool IsInside(IntVector2 position, bool isScreen);
  329. /// Return whether a point (either in element or screen coordinates) is inside the combined rect of the element and its children.
  330. bool IsInsideCombined(IntVector2 position, bool isScreen);
  331. /// Return combined screen coordinate rect of element and its children.
  332. IntRect GetCombinedScreenRect();
  333. /// Sort child elements if sorting enabled and order dirty. Called by UI.
  334. void SortChildren();
  335. /// Return minimum layout element size in the layout direction. Only valid after layout has been calculated.
  336. int GetLayoutMinSize() const { return layoutMinSize_; }
  337. /// %Set child offset.
  338. void SetChildOffset(const IntVector2& offset);
  339. /// %Set hovering state.
  340. void SetHovering(bool enable);
  341. /// Adjust scissor for rendering.
  342. void AdjustScissor(IntRect& currentScissor);
  343. /// Get UI rendering batches with a specified offset. Also recurses to child elements.
  344. void GetBatchesWithOffset(IntVector2& offset, PODVector<UIBatch>& batches, PODVector<UIQuad>& quads, IntRect
  345. currentScissor);
  346. /// User variables.
  347. VariantMap vars_;
  348. protected:
  349. /// Mark screen position as needing an update.
  350. void MarkDirty();
  351. /// Name.
  352. String name_;
  353. /// Child elements.
  354. Vector<SharedPtr<UIElement> > children_;
  355. /// Parent element.
  356. UIElement* parent_;
  357. /// Child element clipping border.
  358. IntRect clipBorder_;
  359. /// Colors.
  360. Color color_[MAX_UIELEMENT_CORNERS];
  361. /// Priority.
  362. int priority_;
  363. /// Bring to front when focused flag.
  364. bool bringToFront_;
  365. /// Bring to back when defocused flag.
  366. bool bringToBack_;
  367. /// Clip children flag.
  368. bool clipChildren_;
  369. /// Sort childrenaccording to priority flag.
  370. bool sortChildren_;
  371. /// Input enabled flag.
  372. bool active_;
  373. /// Selected flag.
  374. bool selected_;
  375. /// Visible flag.
  376. bool visible_;
  377. /// Hovering flag.
  378. bool hovering_;
  379. /// Focus mode.
  380. FocusMode focusMode_;
  381. /// Drag and drop flags.
  382. unsigned dragDropMode_;
  383. /// Layout mode.
  384. LayoutMode layoutMode_;
  385. /// Layout spacing.
  386. int layoutSpacing_;
  387. /// Layout borders.
  388. IntRect layoutBorder_;
  389. /// Resize nesting level to prevent multiple events and endless loop.
  390. unsigned resizeNestingLevel_;
  391. /// Layout update nesting level to prevent endless loop.
  392. unsigned layoutNestingLevel_;
  393. /// Layout element minimum size in layout direction.
  394. int layoutMinSize_;
  395. private:
  396. /// Return child elements recursively.
  397. void GetChildrenRecursive(PODVector<UIElement*>& dest) const;
  398. /// Calculate layout width for resizing the parent element.
  399. int CalculateLayoutParentSize(const PODVector<int>& sizes, int begin, int end, int spacing);
  400. /// Calculate child widths/positions in the layout.
  401. void CalculateLayout(PODVector<int>& positions, PODVector<int>& sizes, const PODVector<int>& minSizes, const PODVector<int>& maxSizes, int targetWidth, int begin, int end, int spacing);
  402. /// Get child element constant position in a layout.
  403. IntVector2 GetLayoutChildPosition(UIElement* child);
  404. /// Position.
  405. IntVector2 position_;
  406. /// Screen position.
  407. IntVector2 screenPosition_;
  408. /// Size.
  409. IntVector2 size_;
  410. /// Minimum size.
  411. IntVector2 minSize_;
  412. /// Maximum size.
  413. IntVector2 maxSize_;
  414. /// Child elements' offset. Used internally.
  415. IntVector2 childOffset_;
  416. /// Horizontal alignment.
  417. HorizontalAlignment horizontalAlignment_;
  418. /// Vertical alignment.
  419. VerticalAlignment verticalAlignment_;
  420. /// Opacity.
  421. float opacity_;
  422. /// Derived opacity.
  423. float derivedOpacity_;
  424. /// Precalculated 32-bit color.
  425. unsigned uintColor_;
  426. /// Screen position dirty flag.
  427. bool positionDirty_;
  428. /// Derived opacity dirty flag.
  429. bool opacityDirty_;
  430. /// Derived color dirty flag (only used when no gradient.)
  431. bool derivedColorDirty_;
  432. /// Child priority sorting dirty flag.
  433. bool sortOrderDirty_;
  434. /// Has color gradient flag.
  435. bool colorGradient_;
  436. };