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 | |
8 | namespace 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 | } |