1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsPrerequisites.h"
6#include "GUI/BsGUIElement.h"
7#include "2D/BsImageSprite.h"
8#include "2D/BsTextSprite.h"
9#include "GUI/BsGUIContent.h"
10#include "Utility/BsEvent.h"
11
12namespace bs
13{
14 /** @addtogroup Implementation
15 * @{
16 */
17
18 /** Base class for a clickable GUI button element. */
19 class BS_EXPORT GUIButtonBase : public GUIElement
20 {
21 public:
22 /** Change content displayed by the button. */
23 void setContent(const GUIContent& content);
24
25 /** Triggered when button is clicked. */
26 Event<void()> onClick;
27
28 /** Triggered when pointer hovers over the button. */
29 Event<void()> onHover;
30
31 /** Triggered when pointer that was previously hovering leaves the button. */
32 Event<void()> onOut;
33
34 /** Triggered when button is clicked twice in rapid succession. */
35 Event<void()> onDoubleClick;
36
37 public: // ***** INTERNAL ******
38 /** @name Internal
39 * @{
40 */
41
42 /**
43 * Change the button "on" state. This state determines whether the button uses normal or "on" fields specified in
44 * the GUI style.
45 */
46 void _setOn(bool on);
47
48 /**
49 * Retrieves the button "on" state. This state determines whether the button uses normal or "on" fields specified
50 * in the GUI style.
51 */
52 bool _isOn() const;
53
54 /** Change the internal button state, changing the button look depending on set style. */
55 void _setState(GUIElementState state);
56
57 /** @copydoc GUIElement::_getOptimalSize */
58 Vector2I _getOptimalSize() const override;
59
60 /** @copydoc GUIElement::_getRenderElementDepthRange */
61 UINT32 _getRenderElementDepthRange() const override;
62
63 /** @} */
64 protected:
65 GUIButtonBase(const String& styleName, const GUIContent& content, const GUIDimensions& dimensions,
66 GUIElementOptions options = GUIElementOption::AcceptsKeyFocus);
67 virtual ~GUIButtonBase();
68
69 /** @copydoc GUIElement::_getNumRenderElements */
70 UINT32 _getNumRenderElements() const override;
71
72 /** @copydoc GUIElement::_getMaterial */
73 const SpriteMaterialInfo& _getMaterial(UINT32 renderElementIdx, SpriteMaterial** material) const override;
74
75 /** @copydoc GUIElement::_getMeshInfo() */
76 void _getMeshInfo(UINT32 renderElementIdx, UINT32& numVertices, UINT32& numIndices, GUIMeshType& type) const override;
77
78 /** @copydoc GUIElement::_fillBuffer */
79 void _fillBuffer(UINT8* vertices, UINT32* indices, UINT32 vertexOffset, UINT32 indexOffset,
80 UINT32 maxNumVerts, UINT32 maxNumIndices, UINT32 renderElementIdx) const override;
81
82 /** @copydoc GUIElement::updateRenderElementsInternal */
83 void updateRenderElementsInternal() override;
84
85 /** @copydoc GUIElement::_mouseEvent */
86 bool _mouseEvent(const GUIMouseEvent& ev) override;
87
88 /** @copydoc GUIElement::_commandEvent */
89 bool _commandEvent(const GUICommandEvent& ev) override;
90
91 /** @copydoc GUIElement::_getRenderElementDepth */
92 UINT32 _getRenderElementDepth(UINT32 renderElementIdx) const override;
93
94 /** @copydoc GUIElement::_getTooltip */
95 String _getTooltip() const override;
96
97 /** @copydoc GUIElement::styleUpdated */
98 void styleUpdated() override;
99
100 /** Creates or destroys the content image sprite depending if there is a content image for the active state. */
101 void refreshContentSprite();
102
103 /** Gets the text sprite descriptor used for creating/updating the internal text sprite. */
104 TEXT_SPRITE_DESC getTextDesc() const;
105
106 /** Retrieves internal button state. */
107 GUIElementState getState() const { return mActiveState; }
108
109 /** Returns the active sprite texture, depending on the current state. */
110 const HSpriteTexture& getActiveTexture() const;
111
112 /** Returns the active text color, depending on the current state. */
113 Color getActiveTextColor() const;
114 private:
115 ImageSprite* mImageSprite;
116 ImageSprite* mContentImageSprite = nullptr;
117 TextSprite* mTextSprite;
118 GUIElementState mActiveState = GUIElementState::Normal;
119
120 IMAGE_SPRITE_DESC mImageDesc;
121 GUIContent mContent;
122 bool mHasFocus = false;
123 float mContentAnimationStartTime = 0.0f;
124 };
125
126 /** @} */
127}