BsEditorWidget.h 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsEditorPrerequisites.h"
  5. #include "BsEditorWidgetManager.h"
  6. #include "BsEvent.h"
  7. #include "BsRect2I.h"
  8. namespace BansheeEngine
  9. {
  10. /**
  11. * @brief Editor widget represents a single "window" in the editor. It may be dragged,
  12. * docked and can share space with multiple other widgets by using tabs.
  13. *
  14. * Each widget has its own position, size, GUI and update method.
  15. * Widget is always docked inside an EditorWidgetContainer unless it's being dragged
  16. * and is not visible.
  17. */
  18. class BS_ED_EXPORT EditorWidgetBase
  19. {
  20. public:
  21. /**
  22. * @brief Gets a unique name for this widget. This name will be used for referencing
  23. * the widget by other systems.
  24. */
  25. const String& getName() const { return mName; }
  26. /**
  27. * @brief Gets the display name for the widget. This is what editor users will see
  28. * in the widget title bar.
  29. */
  30. const HString& getDisplayName() const { return mDisplayName; }
  31. /**
  32. * @brief Returns the X position of the widget inside of its container.
  33. */
  34. INT32 getX() const { return mX; }
  35. /**
  36. * @brief Returns the Y position of the widget inside of its container.
  37. */
  38. INT32 getY() const { return mY; }
  39. /**
  40. * @brief Returns the width of the widget in pixels.
  41. */
  42. UINT32 getWidth() const { return mWidth; }
  43. /**
  44. * @brief Returns the height of the widget in pixels.
  45. */
  46. UINT32 getHeight() const { return mHeight; }
  47. /**
  48. * @brief Returns the width of the widget when initially created, in pixels.
  49. */
  50. UINT32 getDefaultWidth() const { return mDefaultWidth; }
  51. /**
  52. * @brief Returns the height of the widget when initially created, in pixels.
  53. */
  54. UINT32 getDefaultHeight() const { return mDefaultHeight; }
  55. /**
  56. * @brief Returns the bounds of the widget in pixels, relative
  57. * to its parent container.
  58. */
  59. Rect2I getBounds() const { return Rect2I(mX, mY, mWidth, mHeight); }
  60. /**
  61. * @brief Checks if the widget has focus (usually means user clicked on it last).
  62. */
  63. bool hasFocus() const { return mHasFocus; }
  64. /**
  65. * Checks is the widget the currently active widget in its container. This means the widget's tab is active or
  66. * the widget is the only one in its container.
  67. */
  68. bool isActive() const { return mIsActive; }
  69. /**
  70. * @brief Gets the parent editor window this widget is docked in. Can be null (e.g. when widget is in the
  71. * process of dragging and not visible).
  72. */
  73. EditorWindowBase* getParentWindow() const;
  74. /**
  75. * @brief Changes the size of the widget (and its internal GUI panel).
  76. *
  77. * @note Internal method.
  78. */
  79. void _setSize(UINT32 width, UINT32 height);
  80. /**
  81. * @brief Changes the position of the widget (and its internal GUI panel),
  82. * relative to its parent container.
  83. *
  84. * @note Internal method.
  85. */
  86. void _setPosition(INT32 x, INT32 y);
  87. /**
  88. * @brief Changes the parent container of the widget (e.g. when re-docking or moving
  89. * a widget to another window). Parent can be null (e.g. when widget is in the
  90. * process of dragging and not visible).
  91. *
  92. * @note Internal method.
  93. */
  94. void _changeParent(EditorWidgetContainer* parent);
  95. /**
  96. * @brief Sets or removes focus for this widget.
  97. *
  98. * @note Internal method.
  99. */
  100. void _setHasFocus(bool focus);
  101. /**
  102. * @brief Returns the parent widget container. Can be null (e.g. when widget is in the
  103. * process of dragging and not visible).
  104. *
  105. * @note Internal method.
  106. */
  107. EditorWidgetContainer* _getParent() const { return mParent; }
  108. /**
  109. * @brief Converts screen coordinates to coordinates relative to the
  110. * widget.
  111. */
  112. Vector2I screenToWidgetPos(const Vector2I& screenPos) const;
  113. /**
  114. * @brief Converts widget relative coordinates to screen coordiantes.
  115. */
  116. Vector2I widgetToScreenPos(const Vector2I& widgetPos) const;
  117. /**
  118. * @brief Disables the widget making its GUI contents not visible. The widget
  119. * remains docked in its container.
  120. *
  121. * @note Internal method.
  122. */
  123. void _disable();
  124. /**
  125. * @brief Enables the widget making its previously hidden GUI contents visible.
  126. *
  127. * @note Internal method.
  128. */
  129. void _enable();
  130. /**
  131. * @brief Closes the widget, undocking it from its container and freeing any resources
  132. * related to it.
  133. */
  134. void close();
  135. /**
  136. * @brief Called once per frame.
  137. *
  138. * @note Internal method.
  139. */
  140. virtual void update() { }
  141. Event<void(UINT32, UINT32)> onResized; /**< Triggered whenever widget size changes. */
  142. Event<void(INT32, INT32)> onMoved; /**< Triggered whenever widget position changes. */
  143. Event<void(EditorWidgetContainer*)> onParentChanged; /**< Triggered whenever widget parent container changes. */
  144. Event<void(bool)> onFocusChanged; /**< Triggered whenever widget receives or loses focus. */
  145. protected:
  146. friend class EditorWidgetManager;
  147. EditorWidgetBase(const HString& displayName, const String& name, UINT32 defaultWidth,
  148. UINT32 defaultHeight, EditorWidgetContainer& parentContainer);
  149. virtual ~EditorWidgetBase();
  150. /**
  151. * @brief Triggered whenever widget position changes.
  152. */
  153. virtual void doOnMoved(INT32 x, INT32 y);
  154. /**
  155. * @brief Triggered whenever widget size changes.
  156. */
  157. virtual void doOnResized(UINT32 width, UINT32 height);
  158. /**
  159. * @brief Triggered whenever widget parent container changes.
  160. */
  161. virtual void doOnParentChanged();
  162. /**
  163. * @brief Returns the parent GUI widget. Before calling this you must ensure
  164. * the widget has a container parent otherwise this method will fail.
  165. */
  166. GUIWidget& getParentWidget() const;
  167. /**
  168. * @brief Frees widget resources and deletes the instance.
  169. */
  170. static void destroy(EditorWidgetBase* widget);
  171. String mName;
  172. HString mDisplayName;
  173. EditorWidgetContainer* mParent;
  174. INT32 mX, mY;
  175. UINT32 mWidth, mHeight;
  176. UINT32 mDefaultWidth, mDefaultHeight;
  177. GUIPanel* mContent;
  178. bool mHasFocus;
  179. bool mIsActive;
  180. };
  181. /**
  182. * @brief Helper class that registers a widget creation callback with the widget manager.
  183. * The creation callback allows the runtime to open widgets just by their name
  184. * without knowing the actual type.
  185. */
  186. template<typename Type>
  187. struct RegisterWidgetOnStart
  188. {
  189. public:
  190. RegisterWidgetOnStart()
  191. {
  192. EditorWidgetManager::preRegisterWidget(Type::getTypeName(), &create);
  193. }
  194. /**
  195. * @brief Creates a new widget of a specific type and adds it to the provided container.
  196. */
  197. static EditorWidgetBase* create(EditorWidgetContainer& parentContainer)
  198. {
  199. return bs_new<Type>(EditorWidget<Type>::ConstructPrivately(), parentContainer);
  200. }
  201. };
  202. /**
  203. * @brief Editor widget template class that widgets can inherit from. Ensures that
  204. * all widget implementations are automatically registered with the widget manager.
  205. *
  206. * @see EditorWidgetBase
  207. */
  208. template <class Type>
  209. class EditorWidget : public EditorWidgetBase
  210. {
  211. static volatile RegisterWidgetOnStart<Type> RegisterOnStart;
  212. protected:
  213. friend struct RegisterWidgetOnStart<Type>;
  214. struct ConstructPrivately {};
  215. EditorWidget(const HString& displayName, UINT32 defaultWidth, UINT32 defaultHeight,
  216. EditorWidgetContainer& parentContainer)
  217. :EditorWidgetBase(displayName, Type::getTypeName(), defaultWidth, defaultHeight, parentContainer)
  218. { }
  219. public:
  220. virtual ~EditorWidget() { }
  221. };
  222. template <typename Type>
  223. volatile RegisterWidgetOnStart<Type> EditorWidget<Type>::RegisterOnStart;
  224. }