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 "Utility/BsEvent.h"
8
9namespace bs
10{
11 /** @addtogroup Implementation
12 * @{
13 */
14
15 /** GUI element representing an element with a draggable handle of a variable size. */
16 class BS_EXPORT GUIScrollBar : public GUIElement
17 {
18 public:
19 /** Style type name for the horizontal scroll handle. */
20 static const String& getHScrollHandleType();
21
22 /** Style type name for the vertical scroll handle. */
23 static const String& getVScrollHandleType();
24
25 /** Returns the position of the scroll handle in percent (ranging [0, 1]). */
26 float getScrollPos() const;
27
28 /** Sets the position of the scroll handle in percent (ranging [0, 1]). */
29 void setScrollPos(float pct);
30
31 /** Gets the size of the scroll handle in percent (ranging [0, 1]) of the total scroll bar area. */
32 float getHandleSize() const;
33
34 /** Sets the size of the scroll handle in percent (ranging [0, 1]) of the total scroll bar area. */
35 void setHandleSize(float pct);
36
37 /**
38 * Moves the handle by some amount. Amount is specified in the percentage of the entire scrollable area. Values out
39 * of range will be clamped.
40 */
41 void scroll(float amount);
42
43 /** Returns the maximum scrollable size the handle can move within (for example scroll bar length). */
44 UINT32 getScrollableSize() const;
45
46 /** @copydoc GUIElement::setTint */
47 void setTint(const Color& color) override;
48
49 /**
50 * Triggered whenever the scrollbar handle is moved or resized. Values provided are the handle position and size
51 * in percent (ranging [0, 1]).
52 */
53 Event<void(float posPct, float sizePct)> onScrollOrResize;
54
55 public: // ***** INTERNAL ******
56 /** @name Internal
57 * @{
58 */
59
60 /**
61 * Sets the size of the handle in percent (ranging [0, 1]) of the total scroll bar area.
62 *
63 * @note Does not trigger layout update.
64 */
65 void _setHandleSize(float pct);
66
67 /**
68 * Sets the position of the scroll handle in percent (ranging [0, 1]).
69 *
70 * @note Does not trigger layout update.
71 */
72 void _setScrollPos(float pct);
73
74 /** @copydoc GUIElement::_getOptimalSize */
75 Vector2I _getOptimalSize() const override;
76
77 /** @} */
78 protected:
79 /**
80 * Constructs a new scrollbar.
81 *
82 * @param[in] horizontal If true the scroll bar will have a horizontal moving handle, otherwise it will be a
83 * vertical one.
84 * @param[in] resizable If true the scrollbar will have additional handles that allow the scroll handle to be
85 * resized. This allows you to adjust the size of the visible scroll area.
86 * @param[in] styleName Optional style to use for the element. Style will be retrieved from GUISkin of the
87 * GUIWidget the element is used on. If not specified default style is used.
88 * @param[in] dimensions Determines valid dimensions (size) of the element.
89 */
90 GUIScrollBar(bool horizontal, bool resizable, const String& styleName, const GUIDimensions& dimensions);
91 virtual ~GUIScrollBar();
92
93 /** @copydoc GUIElement::_getNumRenderElements */
94 UINT32 _getNumRenderElements() const override;
95
96 /** @copydoc GUIElement::_getMaterial */
97 const SpriteMaterialInfo& _getMaterial(UINT32 renderElementIdx, SpriteMaterial** material) const override;
98
99 /** @copydoc GUIElement::_getMeshInfo() */
100 void _getMeshInfo(UINT32 renderElementIdx, UINT32& numVertices, UINT32& numIndices, GUIMeshType& type) const override;
101
102 /** @copydoc GUIElement::_fillBuffer */
103 void _fillBuffer(UINT8* vertices, UINT32* indices, UINT32 vertexOffset, UINT32 indexOffset,
104 UINT32 maxNumVerts, UINT32 maxNumIndices, UINT32 renderElementIdx) const override;
105
106 /** @copydoc GUIElement::updateRenderElementsInternal */
107 void updateRenderElementsInternal() override;
108
109 /** @copydoc GUIElement::updateClippedBounds */
110 void updateClippedBounds() override;
111
112 /** @copydoc GUIElement::_getRenderElementDepth */
113 UINT32 _getRenderElementDepth(UINT32 renderElementIdx) const override;
114
115 /** @copydoc GUIElement::_getRenderElementDepthRange */
116 UINT32 _getRenderElementDepthRange() const override;
117
118 /** @copydoc GUIElement::styleUpdated */
119 void styleUpdated() override;
120
121 /**
122 * Helper method that returns style name used by a specific scrollbar type. If override style is empty, default
123 * style for that type is returned.
124 */
125 template<class T>
126 static const String& getStyleName(bool resizeable, const String& overrideStyle)
127 {
128 if(overrideStyle == StringUtil::BLANK)
129 return T::getGUITypeName(resizeable);
130
131 return overrideStyle;
132 }
133 private:
134 /**
135 * Triggered whenever the scroll handle moves. Provided value represents the new position and size of the handle
136 * in percent (ranging [0, 1]).
137 */
138 void handleMoved(float handlePct, float sizePct);
139
140 /** Triggered when scroll up button is clicked. */
141 void upButtonClicked();
142
143 /** Triggered when scroll down button is clicked. */
144 void downButtonClicked();
145
146 GUILayout* mLayout;
147 ImageSprite* mImageSprite;
148
149 GUIButton* mUpBtn;
150 GUIButton* mDownBtn;
151 GUISliderHandle* mHandleBtn;
152 bool mHorizontal;
153
154 static const UINT32 ButtonScrollAmount;
155 };
156
157 /** @} */
158}