2
0

BsGUIInputBox.h 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. #pragma once
  2. #include "BsPrerequisites.h"
  3. #include "BsGUIElement.h"
  4. #include "BsImageSprite.h"
  5. #include "BsTextSprite.h"
  6. #include "BsVirtualInput.h"
  7. namespace BansheeEngine
  8. {
  9. /**
  10. * @brief Input box is a GUI element that accepts Unicode textual input. It can be
  11. * single or multi-line and handles various types of text manipulation.
  12. */
  13. class BS_EXPORT GUIInputBox : public GUIElement
  14. {
  15. /**
  16. * @brief Possible visual states the input box can be in.
  17. */
  18. enum class State
  19. {
  20. Normal,
  21. Hover,
  22. Focused
  23. };
  24. public:
  25. /**
  26. * Returns type name of the GUI element used for finding GUI element styles.
  27. */
  28. static const String& getGUITypeName();
  29. /**
  30. * Creates a new input box.
  31. *
  32. * @param multiline If true the input box can be of arbitrary height and will accept multiple lines of text.
  33. * @param styleName Optional style to use for the element. Style will be retrieved
  34. * from GUISkin of the GUIWidget the element is used on. If not specified
  35. * default style for this element is used.
  36. */
  37. static GUIInputBox* create(bool multiline = false, const String& styleName = StringUtil::BLANK);
  38. /**
  39. * Creates a new input box.
  40. *
  41. * @param multiline If true the input box can be of arbitrary height and will accept multiple lines of text.
  42. * @param options Options that allow you to control how is the element positioned and sized.
  43. * This will override any similar options set by style.
  44. * @param styleName Optional style to use for the element. Style will be retrieved
  45. * from GUISkin of the GUIWidget the element is used on. If not specified
  46. * default button style is used.
  47. */
  48. static GUIInputBox* create(bool multiline, const GUIOptions& options, const String& styleName = StringUtil::BLANK);
  49. /**
  50. * Creates a new single-line input box.
  51. *
  52. * @param options Options that allow you to control how is the element positioned and sized.
  53. * This will override any similar options set by style.
  54. * @param styleName Optional style to use for the element. Style will be retrieved
  55. * from GUISkin of the GUIWidget the element is used on. If not specified
  56. * default button style is used.
  57. */
  58. static GUIInputBox* create(const GUIOptions& options, const String& styleName = StringUtil::BLANK);
  59. /**
  60. * @brief Returns the text currently entered in the input box.
  61. */
  62. const WString& getText() const { return mText; }
  63. /**
  64. * @brief Sets the text inside the input box. This will replace any current text.
  65. */
  66. void setText(const WString& text);
  67. /**
  68. * @brief Sets an optional filter that can control what is allowed to be entered into the
  69. * input box. Filter should return true if the provided string is valid and false otherwise.
  70. * Set the filter to null to deactivate filtering.
  71. */
  72. void setFilter(std::function<bool(const WString&)> filter) { mFilter = filter; }
  73. /**
  74. * @copydoc GUIElement::getElementType
  75. */
  76. virtual ElementType _getElementType() const override { return ElementType::InputBox; }
  77. /**
  78. * @copydoc GUIElement::_getOptimalSize
  79. */
  80. virtual Vector2I _getOptimalSize() const override;
  81. /**
  82. * @brief Triggered whenever input text has changed.
  83. */
  84. Event<void(const WString&)> onValueChanged;
  85. /**
  86. * @brief Triggered whenever the input box receives focus.
  87. */
  88. Event<void()> onFocusGained;
  89. /**
  90. * @brief Triggered whenever the input box loses focus.
  91. */
  92. Event<void()> onFocusLost;
  93. protected:
  94. GUIInputBox(const String& styleName, const GUIDimensions& dimensions, bool multiline);
  95. virtual ~GUIInputBox();
  96. /**
  97. * @copydoc GUIElement::getNumRenderElements()
  98. */
  99. virtual UINT32 _getNumRenderElements() const override;
  100. /**
  101. * @copydoc GUIElement::getMaterial()
  102. */
  103. virtual const GUIMaterialInfo& _getMaterial(UINT32 renderElementIdx) const override;
  104. /**
  105. * @copydoc GUIElement::getNumQuads()
  106. */
  107. virtual UINT32 _getNumQuads(UINT32 renderElementIdx) const override;
  108. /**
  109. * @copydoc GUIElement::fillBuffer()
  110. */
  111. virtual void _fillBuffer(UINT8* vertices, UINT8* uv, UINT32* indices, UINT32 startingQuad,
  112. UINT32 maxNumQuads, UINT32 vertexStride, UINT32 indexStride, UINT32 renderElementIdx) const override;
  113. /**
  114. * @copydoc GUIElement::updateRenderElementsInternal()
  115. */
  116. virtual void updateRenderElementsInternal() override;
  117. /**
  118. * @copydoc GUIElement::updateBounds()
  119. */
  120. virtual void updateClippedBounds() override;
  121. /**
  122. * @copydoc GUIElement::mouseEvent
  123. */
  124. virtual bool _mouseEvent(const GUIMouseEvent& ev) override;
  125. /**
  126. * @copydoc GUIElement::textInputEvent
  127. */
  128. virtual bool _textInputEvent(const GUITextInputEvent& ev) override;
  129. /**
  130. * @copydoc GUIElement::commandEvent
  131. */
  132. virtual bool _commandEvent(const GUICommandEvent& ev) override;
  133. /**
  134. * @copydoc GUIElement::virtualButtonEvent
  135. */
  136. virtual bool _virtualButtonEvent(const GUIVirtualButtonEvent& ev) override;
  137. /**
  138. * @brief Returns how much to offset text due to scrolling.
  139. *
  140. * @note This is used when text is larger than the input box itself. As the
  141. * caret moves the text will scroll so that the caret remains visible, and
  142. * how much scroll is applied is determined by this value.
  143. */
  144. virtual Vector2I _getTextInputOffset() const override;
  145. /**
  146. * @brief Returns rectangle in which the text can be displayed, in local
  147. * coordinates (i.e. text will start at 0, 0).
  148. */
  149. virtual Rect2I _getTextInputRect() const override;
  150. /**
  151. * @copydoc GUIElement::_getRenderElementDepth
  152. */
  153. virtual UINT32 _getRenderElementDepth(UINT32 renderElementIdx) const override;
  154. /**
  155. * @copydoc GUIElement::_getRenderElementDepthRange
  156. */
  157. virtual UINT32 _getRenderElementDepthRange() const override;
  158. /**
  159. * @copydoc GUIElement::_hasCustomCursor
  160. */
  161. virtual bool _hasCustomCursor(const Vector2I position, CursorType& type) const override;
  162. /**
  163. * @copydoc GUIElement::getContextMenu
  164. */
  165. virtual GUIContextMenuPtr _getContextMenu() const override;
  166. private:
  167. /**
  168. * @brief Retrieves a sprite from a render element index, and a local render element index
  169. * that represents render element within the returned sprite.
  170. */
  171. Sprite* renderElemToSprite(UINT32 renderElemIdx, UINT32& localRenderElemIdx) const;
  172. /**
  173. * @brief Returns offset at which is the element with the provided render element index.
  174. * Offset is relative to parent widget.
  175. */
  176. Vector2I renderElemToOffset(UINT32 renderElemIdx) const;
  177. /**
  178. * @brief Returns a clip rectangle that can be used for clipping the render element
  179. * with the provided index. Rectangle is in local coordiantes relative to
  180. * element origin.
  181. */
  182. Rect2I renderElemToClipRect(UINT32 renderElemIdx) const;
  183. /**
  184. * @brief Inserts a new string into the current text at the specified index.
  185. */
  186. void insertString(UINT32 charIdx, const WString& string);
  187. /**
  188. * @brief Inserts a new character into the current text at the specified index.
  189. */
  190. void insertChar(UINT32 charIdx, UINT32 charCode);
  191. /**
  192. * @brief Erases a single character at the specified index.
  193. */
  194. void eraseChar(UINT32 charIdx);
  195. /**
  196. * @brief Deletes text that is currently selected.
  197. */
  198. void deleteSelectedText();
  199. /**
  200. * @brief Returns currently selected text.
  201. */
  202. WString getSelectedText();
  203. /**
  204. * @brief Shows the input caret. You must position the caret manually after showing it.
  205. */
  206. void showCaret();
  207. /**
  208. * @brief Hides the input caret.
  209. */
  210. void hideCaret();
  211. /**
  212. * @brief Shows selection with the specified anchor position. You must
  213. * position selection start and end before selection will actually render.
  214. * Anchor position determines selection behavior as the user moves the selection
  215. * with the keyboard.
  216. */
  217. void showSelection(UINT32 anchorCaretPos);
  218. /**
  219. * @brief Removes any active selection.
  220. */
  221. void clearSelection();
  222. /**
  223. * @brief Adjusts the text offset (scroll) so that the caret is visible.
  224. */
  225. void scrollTextToCaret();
  226. /**
  227. * @brief Clamps the text offset (scroll) so that the text fits in the
  228. * provided bounds nicely with minimal white space.
  229. */
  230. void clampScrollToBounds(Rect2I unclippedTextBounds);
  231. /**
  232. * @brief Returns offset at which to render the text. Relative to parent widget.
  233. */
  234. Vector2I getTextOffset() const;
  235. /**
  236. * @brief Returns rectangle used for clipping the text. Relative to element.
  237. */
  238. Rect2I getTextClipRect() const;
  239. /**
  240. * @brief Returns text sprite descriptor determining how is text sprite created.
  241. */
  242. TEXT_SPRITE_DESC getTextDesc() const;
  243. /**
  244. * @brief Returns currently active input box texture, depending on active state.
  245. */
  246. const HSpriteTexture& getActiveTexture() const;
  247. /**
  248. * @brief Returns currently active input box text color, depending on active state.
  249. */
  250. Color getActiveTextColor() const;
  251. /**
  252. * @brief Cuts currently selected text to clipboard.
  253. */
  254. void cutText();
  255. /**
  256. * @brief Copies currently selected text to clipboard.
  257. */
  258. void copyText();
  259. /**
  260. * @brief Inserts text from clipboard to current caret location.
  261. */
  262. void pasteText();
  263. private:
  264. static VirtualButton mCopyVB;
  265. static VirtualButton mPasteVB;
  266. static VirtualButton mCutVB;
  267. static VirtualButton mSelectAllVB;
  268. // Sprites
  269. ImageSprite* mImageSprite;
  270. TextSprite* mTextSprite;
  271. bool mIsMultiline;
  272. Vector2I mTextOffset;
  273. bool mHasFocus;
  274. bool mIsMouseOver;
  275. State mState;
  276. IMAGE_SPRITE_DESC mImageDesc;
  277. WString mText;
  278. std::function<bool(const WString&)> mFilter;
  279. bool mCaretShown;
  280. bool mSelectionShown;
  281. bool mDragInProgress;
  282. };
  283. }