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/BsGUIElementContainer.h"
7
8namespace bs
9{
10 /** @addtogroup GUI
11 * @{
12 */
13
14 /** Scroll bar options for a GUI scroll area. */
15 enum class ScrollBarType
16 {
17 ShowIfDoesntFit,
18 AlwaysShow,
19 NeverShow
20 };
21
22 /** A GUI element container with support for vertical & horizontal scrolling. */
23 class BS_EXPORT GUIScrollArea : public GUIElementContainer
24 {
25 public:
26 /** Returns type name of the GUI element used for finding GUI element styles. */
27 static const String& getGUITypeName();
28
29 /**
30 * Creates a new empty scroll area.
31 *
32 * @param[in] vertBarType Vertical scrollbar options.
33 * @param[in] horzBarType Horizontal scrollbar options.
34 * @param[in] scrollBarStyle Style used by the scroll bars.
35 * @param[in] scrollAreaStyle Style used by the scroll content area.
36 */
37 static GUIScrollArea* create(ScrollBarType vertBarType, ScrollBarType horzBarType,
38 const String& scrollBarStyle = StringUtil::BLANK, const String& scrollAreaStyle = StringUtil::BLANK);
39
40 /**
41 * Creates a new empty scroll area.
42 *
43 * @param[in] vertBarType Vertical scrollbar options.
44 * @param[in] horzBarType Horizontal scrollbar options.
45 * @param[in] options Options that allow you to control how is the element positioned and sized. This will
46 * override any similar options set by style.
47 * @param[in] scrollBarStyle Style used by the scroll bars.
48 * @param[in] scrollAreaStyle Style used by the scroll content area.
49 */
50 static GUIScrollArea* create(ScrollBarType vertBarType, ScrollBarType horzBarType,
51 const GUIOptions& options, const String& scrollBarStyle = StringUtil::BLANK,
52 const String& scrollAreaStyle = StringUtil::BLANK);
53
54 /**
55 * Creates a new empty scroll area. Scroll bars will be show if needed and hidden otherwise.
56 *
57 * @param[in] scrollBarStyle Style used by the scroll bars.
58 * @param[in] scrollAreaStyle Style used by the scroll content area.
59 */
60 static GUIScrollArea* create(const String& scrollBarStyle = StringUtil::BLANK,
61 const String& scrollAreaStyle = StringUtil::BLANK);
62
63 /**
64 * Creates a new empty scroll area. Scroll bars will be show if needed and hidden otherwise.
65 *
66 * @param[in] options Options that allow you to control how is the element positioned and sized. This will
67 * override any similar options set by style.
68 * @param[in] scrollBarStyle Style used by the scroll bars.
69 * @param[in] scrollAreaStyle Style used by the scroll content area.
70 */
71 static GUIScrollArea* create(const GUIOptions& options, const String& scrollBarStyle = StringUtil::BLANK,
72 const String& scrollAreaStyle = StringUtil::BLANK);
73
74 /** Returns the scroll area layout that you may use to add elements inside the scroll area. */
75 GUILayout& getLayout() const { return *mContentLayout; }
76
77 /** Scrolls the area up by specified amount of pixels, if possible. */
78 void scrollUpPx(UINT32 pixels);
79
80 /** Scrolls the area down by specified amount of pixels, if possible. */
81 void scrollDownPx(UINT32 pixels);
82
83 /** Scrolls the area left by specified amount of pixels, if possible. */
84 void scrollLeftPx(UINT32 pixels);
85
86 /** Scrolls the area right by specified amount of pixels, if possible. */
87 void scrollRightPx(UINT32 pixels);
88
89 /** Scrolls the area up by specified percentage (ranging [0, 1]), if possible. */
90 void scrollUpPct(float percent);
91
92 /** Scrolls the area down by specified percentage (ranging [0, 1]), if possible. */
93 void scrollDownPct(float percent);
94
95 /** Scrolls the area left by specified percentage (ranging [0, 1]), if possible. */
96 void scrollLeftPct(float percent);
97
98 /** Scrolls the area right by specified percentage (ranging [0, 1]), if possible. */
99 void scrollRightPct(float percent);
100
101 /**
102 * Scrolls the contents to the specified position (0 meaning top-most part of the content is visible, and 1 meaning
103 * bottom-most part is visible).
104 */
105 void scrollToVertical(float pct);
106
107 /**
108 * Scrolls the contents to the specified position (0 meaning left-most part of the content is visible, and 1 meaning
109 * right-most part is visible)
110 */
111 void scrollToHorizontal(float pct);
112
113 /**
114 * Returns how much is the scroll area scrolled in the vertical direction. Returned value represents percentage
115 * where 0 means no scrolling is happening, and 1 means area is fully scrolled to the bottom.
116 */
117 float getVerticalScroll() const;
118
119 /**
120 * Returns how much is the scroll area scrolled in the horizontal direction. Returned value represents percentage
121 * where 0 means no scrolling is happening, and 1 means area is fully scrolled to the right.
122 */
123 float getHorizontalScroll() const;
124
125 /**
126 * Returns the bounds of the scroll area not including the scroll bars (meaning only the portion that contains the
127 * contents).
128 */
129 Rect2I getContentBounds();
130
131 /**
132 * Number of pixels the scroll bar will occupy when active. This is width for vertical scrollbar, and height for
133 * horizontal scrollbar.
134 */
135 static const UINT32 ScrollBarWidth;
136
137 /** @name Internal
138 * @{
139 */
140
141 /** @copydoc GUIElementContainer::_getElementType */
142 ElementType _getElementType() const override { return ElementType::ScrollArea; }
143
144 /** @} */
145 protected:
146 ~GUIScrollArea() = default;
147
148 /** @copydoc GUIElementContainer::_getLayoutSizeRange */
149 LayoutSizeRange _getLayoutSizeRange() const override;
150
151 /** @copydoc GUIElementContainer::updateClippedBounds */
152 void updateClippedBounds() override;
153
154 /** @copydoc GUIElementBase::_calculateLayoutSizeRange */
155 LayoutSizeRange _calculateLayoutSizeRange() const override;
156
157 /** @copydoc GUIElementBase::_updateOptimalLayoutSizes */
158 void _updateOptimalLayoutSizes() override;
159
160 /** @copydoc GUIElementContainer::_getOptimalSize */
161 Vector2I _getOptimalSize() const override;
162 private:
163 GUIScrollArea(ScrollBarType vertBarType, ScrollBarType horzBarType,
164 const String& scrollBarStyle, const String& scrollAreaStyle, const GUIDimensions& dimensions);
165
166 /** @copydoc GUIElementContainer::mouseEvent */
167 bool _mouseEvent(const GUIMouseEvent& ev) override;
168
169 /**
170 * Called when the vertical scrollbar moves.
171 *
172 * @param[in] pct Scrollbar position ranging [0, 1].
173 */
174 void vertScrollUpdate(float pct);
175
176 /**
177 * Called when the horizontal scrollbar moves.
178 *
179 * @param[in] pct Scrollbar position ranging [0, 1].
180 */
181 void horzScrollUpdate(float pct);
182
183 /** @copydoc GUIElementContainer::_updateLayoutInternal */
184 void _updateLayoutInternal(const GUILayoutData& data) override;
185
186 /** @copydoc GUIElementContainer::_getElementAreas */
187 void _getElementAreas(const Rect2I& layoutArea, Rect2I* elementAreas, UINT32 numElements,
188 const Vector<LayoutSizeRange>& sizeRanges, const LayoutSizeRange& mySizeRange) const override;
189
190 /**
191 * @copydoc GUIElementContainer::_getElementAreas
192 *
193 * @note Also calculates some scroll area specific values.
194 */
195 void _getElementAreas(const Rect2I& layoutArea, Rect2I* elementAreas, UINT32 numElements,
196 const Vector<LayoutSizeRange>& sizeRanges, Vector2I& visibleSize, Vector2I& contentSize) const;
197
198 ScrollBarType mVertBarType;
199 ScrollBarType mHorzBarType;
200 String mScrollBarStyle;
201
202 GUILayout* mContentLayout;
203 GUIScrollBarVert* mVertScroll;
204 GUIScrollBarHorz* mHorzScroll;
205
206 float mVertOffset;
207 float mHorzOffset;
208 bool mRecalculateVertOffset;
209 bool mRecalculateHorzOffset;
210
211 Vector2I mVisibleSize;
212 Vector2I mContentSize;
213
214 Vector<LayoutSizeRange> mChildSizeRanges;
215 LayoutSizeRange mSizeRange;
216
217 static const UINT32 MinHandleSize;
218 static const UINT32 WheelScrollAmount;
219 };
220
221 /** @} */
222}