Line data Source code
1 : /* Copyright (C) 2021 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * 0 A.D. is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : /*
19 : A GUI Scrollbar, this class doesn't present all functionality
20 : to the scrollbar, it just controls the drawing and a wrapper
21 : for interaction with it.
22 : */
23 :
24 : #ifndef INCLUDED_IGUISCROLLBAR
25 : #define INCLUDED_IGUISCROLLBAR
26 :
27 : #include "gui/CGUISprite.h"
28 : #include "maths/Vector2D.h"
29 : #include "ps/CStr.h"
30 :
31 : class CCanvas2D;
32 : class CGUI;
33 : class IGUIScrollBarOwner;
34 : struct SGUIMessage;
35 :
36 : /**
37 : * The GUI Scroll-bar style. Tells us how scroll-bars look and feel.
38 : *
39 : * A scroll-bar style can choose whether to support horizontal, vertical
40 : * or both.
41 : *
42 : * @see IGUIScrollBar
43 : */
44 0 : struct SGUIScrollBarStyle
45 : {
46 : // CGUISpriteInstance makes this NONCOPYABLE implicitly, make it explicit
47 : NONCOPYABLE(SGUIScrollBarStyle);
48 0 : MOVABLE(SGUIScrollBarStyle);
49 0 : SGUIScrollBarStyle() = default;
50 :
51 : //--------------------------------------------------------
52 : /** @name General Settings */
53 : //--------------------------------------------------------
54 : //@{
55 :
56 : /**
57 : * Width of bar, also both sides of the edge buttons.
58 : */
59 : float m_Width;
60 :
61 : /**
62 : * Scrollable with the wheel.
63 : */
64 : bool m_ScrollWheel;
65 :
66 : /**
67 : * How much (in percent, 0.1f = 10%) to scroll each time
68 : * the wheel is admitted, or the buttons are pressed.
69 : */
70 : float m_ScrollSpeed;
71 :
72 : /**
73 : * Whether or not the edge buttons should appear or not. Sometimes
74 : * you actually don't want them, like perhaps in a combo box.
75 : */
76 : bool m_ScrollButtons;
77 :
78 : /**
79 : * Sometimes there is *a lot* to scroll, but to prevent the scroll "bar"
80 : * from being almost invisible (or ugly), you can set a minimum in pixel
81 : * size.
82 : */
83 : float m_MinimumBarSize;
84 :
85 : /**
86 : * Sometimes you would like your scroll bar to have a fixed maximum size
87 : * so that the texture does not get too stretched, you can set a maximum
88 : * in pixels.
89 : */
90 : float m_MaximumBarSize;
91 :
92 : /**
93 : * True if you want edge buttons, i.e. buttons that can be pressed in order
94 : * to scroll.
95 : */
96 : bool m_UseEdgeButtons;
97 :
98 : //@}
99 : //--------------------------------------------------------
100 : /** @name Vertical Sprites */
101 : //--------------------------------------------------------
102 : //@{
103 :
104 : CGUISpriteInstance m_SpriteButtonTop;
105 : CGUISpriteInstance m_SpriteButtonTopPressed;
106 : CGUISpriteInstance m_SpriteButtonTopDisabled;
107 : CGUISpriteInstance m_SpriteButtonTopOver;
108 :
109 : CGUISpriteInstance m_SpriteButtonBottom;
110 : CGUISpriteInstance m_SpriteButtonBottomPressed;
111 : CGUISpriteInstance m_SpriteButtonBottomDisabled;
112 : CGUISpriteInstance m_SpriteButtonBottomOver;
113 :
114 : CGUISpriteInstance m_SpriteBarVertical;
115 : CGUISpriteInstance m_SpriteBarVerticalOver;
116 : CGUISpriteInstance m_SpriteBarVerticalPressed;
117 :
118 : CGUISpriteInstance m_SpriteBackVertical;
119 :
120 : //@}
121 : //--------------------------------------------------------
122 : /** @name Horizontal Sprites */
123 : //--------------------------------------------------------
124 : //@{
125 :
126 : CGUISpriteInstance m_SpriteButtonLeft;
127 : CGUISpriteInstance m_SpriteButtonLeftPressed;
128 : CGUISpriteInstance m_SpriteButtonLeftDisabled;
129 :
130 : CGUISpriteInstance m_SpriteButtonRight;
131 : CGUISpriteInstance m_SpriteButtonRightPressed;
132 : CGUISpriteInstance m_SpriteButtonRightDisabled;
133 :
134 : CGUISpriteInstance m_SpriteBackHorizontal;
135 : CGUISpriteInstance m_SpriteBarHorizontal;
136 :
137 : //@}
138 : };
139 :
140 :
141 : /**
142 : * The GUI Scroll-bar, used everywhere there is a scroll-bar in the game.
143 : *
144 : * To include a scroll-bar to an object, inherent the object from
145 : * IGUIScrollBarOwner and call AddScrollBar() to add the scroll-bars.
146 : *
147 : * It's also important that the scrollbar is located within the parent
148 : * object's mouse over area. Otherwise the input won't be sent to the
149 : * scroll-bar.
150 : *
151 : * The class does not provide all functionality to the scroll-bar, many
152 : * things the parent of the scroll-bar, must provide. Like a combo-box.
153 : */
154 : class IGUIScrollBar
155 : {
156 : public:
157 : NONCOPYABLE(IGUIScrollBar);
158 :
159 : IGUIScrollBar(CGUI& pGUI);
160 : virtual ~IGUIScrollBar();
161 :
162 : public:
163 : /**
164 : * Draw the scroll-bar
165 : */
166 : virtual void Draw(CCanvas2D& canvas) = 0;
167 :
168 : /**
169 : * If an object that contains a scrollbar has got messages, send
170 : * them to the scroll-bar and it will see if the message regarded
171 : * itself.
172 : *
173 : * @see IGUIObject#HandleMessage()
174 : */
175 : virtual void HandleMessage(SGUIMessage& Message) = 0;
176 :
177 : /**
178 : * Set m_Pos with g_mouse_x/y input, i.e. when draggin.
179 : */
180 : virtual void SetPosFromMousePos(const CVector2D& mouse) = 0;
181 :
182 : /**
183 : * Hovering the scroll minus button
184 : *
185 : * @param mouse current mouse position
186 : * @return True if mouse positions are hovering the button
187 : */
188 0 : virtual bool HoveringButtonMinus(const CVector2D& UNUSED(mouse)) { return false; }
189 :
190 : /**
191 : * Hovering the scroll plus button
192 : *
193 : * @param mouse current mouse position
194 : * @return True if mouse positions are hovering the button
195 : */
196 0 : virtual bool HoveringButtonPlus(const CVector2D& UNUSED(mouse)) { return false; }
197 :
198 : /**
199 : * Get scroll-position
200 : */
201 0 : float GetPos() const { return m_Pos; }
202 :
203 : /**
204 : * Set scroll-position by hand
205 : */
206 0 : virtual void SetPos(float f) { m_Pos = f; UpdatePosBoundaries(); }
207 :
208 : /**
209 : * Get the value of m_Pos that corresponds to the bottom of the scrollable region
210 : */
211 0 : float GetMaxPos() const { return std::max(0.f, m_ScrollRange - m_ScrollSpace); }
212 :
213 : /**
214 : * Scrollbars without height shouldn't be visible
215 : */
216 0 : bool IsVisible() const { return GetMaxPos() != 0.f; }
217 :
218 : /**
219 : * Increase scroll one step
220 : */
221 0 : virtual void ScrollPlus() { m_Pos += 30.f; UpdatePosBoundaries(); }
222 :
223 : /**
224 : * Decrease scroll one step
225 : */
226 0 : virtual void ScrollMinus() { m_Pos -= 30.f; UpdatePosBoundaries(); }
227 :
228 : /**
229 : * Increase scroll three steps
230 : */
231 0 : virtual void ScrollPlusPlenty() { m_Pos += 90.f; UpdatePosBoundaries(); }
232 :
233 : /**
234 : * Decrease scroll three steps
235 : */
236 0 : virtual void ScrollMinusPlenty() { m_Pos -= 90.f; UpdatePosBoundaries(); }
237 :
238 : /**
239 : * Set host object, must be done almost at creation of scroll bar.
240 : * @param pOwner Pointer to host object.
241 : */
242 0 : void SetHostObject(IGUIScrollBarOwner* pOwner) { m_pHostObject = pOwner; }
243 :
244 : /**
245 : * Set Width
246 : * @param width Width
247 : */
248 : void SetWidth(float width) { m_Width = width; }
249 :
250 : /**
251 : * Set X Position
252 : * @param x Position in this axis
253 : */
254 0 : void SetX(float x) { m_X = x; }
255 :
256 : /**
257 : * Set Y Position
258 : * @param y Position in this axis
259 : */
260 0 : void SetY(float y) { m_Y = y; }
261 :
262 : /**
263 : * Set Z Position
264 : * @param z Position in this axis
265 : */
266 0 : void SetZ(float z) { m_Z = z; }
267 :
268 : /**
269 : * Set Length of scroll bar
270 : * @param length Length
271 : */
272 0 : void SetLength(float length) { m_Length = length; }
273 :
274 : /**
275 : * Set content length
276 : * @param range Maximum scrollable range
277 : */
278 0 : void SetScrollRange(float range) { m_ScrollRange = std::max(range, 1.f); SetupBarSize(); UpdatePosBoundaries(); }
279 :
280 : /**
281 : * Set space that is visible in the scrollable control.
282 : * @param space Visible area in the scrollable control.
283 : */
284 0 : void SetScrollSpace(float space) { m_ScrollSpace = space; SetupBarSize(); UpdatePosBoundaries(); }
285 :
286 : /**
287 : * Set bar pressed
288 : * @param b True if bar is pressed
289 : */
290 0 : void SetBarPressed(bool b) { m_BarPressed = b; }
291 :
292 : /**
293 : * Set Scroll bar style string
294 : * @param style String with scroll bar style reference name
295 : */
296 0 : void SetScrollBarStyle(const CStr& style) { m_ScrollBarStyle = style; }
297 :
298 : /**
299 : * Get style used by the scrollbar
300 : * @return Scroll bar style struct.
301 : */
302 : const SGUIScrollBarStyle* GetStyle() const;
303 :
304 : /**
305 : * Get the rectangle of the actual BAR. not the whole scroll-bar.
306 : * @return Rectangle, CRect
307 : */
308 : virtual CRect GetBarRect() const = 0;
309 :
310 : /**
311 : * Get the rectangle of the outline of the scrollbar, every component of the
312 : * scroll-bar should be inside this area.
313 : * @return Rectangle, CRect
314 : */
315 : virtual CRect GetOuterRect() const = 0;
316 :
317 : protected:
318 : /**
319 : * Sets up bar size
320 : */
321 : void SetupBarSize();
322 :
323 : /**
324 : * Call every time m_Pos has been updated.
325 : */
326 : void UpdatePosBoundaries();
327 :
328 : protected:
329 : //@}
330 : //--------------------------------------------------------
331 : /** @name Settings */
332 : //--------------------------------------------------------
333 : //@{
334 :
335 : /**
336 : * Width of the scroll bar
337 : */
338 : float m_Width;
339 :
340 : /**
341 : * Absolute X Position
342 : */
343 : float m_X;
344 :
345 : /**
346 : * Absolute Y Position
347 : */
348 : float m_Y;
349 :
350 : /**
351 : * Absolute Z Position
352 : */
353 : float m_Z;
354 :
355 : /**
356 : * Total length of scrollbar, including edge buttons.
357 : */
358 : float m_Length;
359 :
360 : /**
361 : * Content that can be scrolled, in pixels
362 : */
363 : float m_ScrollRange;
364 :
365 : /**
366 : * Content that can be viewed at a time, in pixels
367 : */
368 : float m_ScrollSpace;
369 :
370 : /**
371 : * Use input from the scroll-wheel? True or false.
372 : */
373 : float m_BarSize;
374 :
375 : /**
376 : * Scroll bar style reference name
377 : */
378 : CStr m_ScrollBarStyle;
379 :
380 : /**
381 : * Pointer to scroll bar style used.
382 : */
383 : SGUIScrollBarStyle* m_pStyle;
384 :
385 : /**
386 : * Host object, prerequisite!
387 : */
388 : IGUIScrollBarOwner* m_pHostObject;
389 :
390 : /**
391 : * Reference to CGUI object, these cannot work stand-alone
392 : */
393 : CGUI& m_pGUI;
394 :
395 : /**
396 : * Mouse position when bar was pressed
397 : */
398 : CVector2D m_BarPressedAtPos;
399 :
400 : //@}
401 : //--------------------------------------------------------
402 : /** @name States */
403 : //--------------------------------------------------------
404 : //@{
405 :
406 : /**
407 : * If the bar is currently being pressed and dragged.
408 : */
409 : bool m_BarPressed;
410 :
411 : /**
412 : * Bar being hovered or not
413 : */
414 : bool m_BarHovered;
415 :
416 : /**
417 : * Scroll buttons hovered
418 : */
419 : bool m_ButtonMinusHovered, m_ButtonPlusHovered;
420 :
421 : /**
422 : * Scroll buttons pressed
423 : */
424 : bool m_ButtonMinusPressed, m_ButtonPlusPressed;
425 :
426 : /**
427 : * Position of scroll bar, 0 means scrolled all the way to one side.
428 : * It is measured in pixels, it is up to the host to make it actually
429 : * apply in pixels.
430 : */
431 : float m_Pos;
432 :
433 : /**
434 : * Position from 0.f to 1.f it had when the bar was pressed.
435 : */
436 : float m_PosWhenPressed;
437 :
438 : //@}
439 : };
440 :
441 : #endif // INCLUDED_IGUISCROLLBAR
|