BsEditorWidget.h 7.5 KB

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