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 : #include "precompiled.h"
19 :
20 : #include "IGUIScrollBar.h"
21 :
22 : #include "gui/CGUI.h"
23 : #include "gui/SGUIMessage.h"
24 : #include "gui/ObjectBases/IGUIScrollBarOwner.h"
25 : #include "maths/MathUtil.h"
26 :
27 0 : IGUIScrollBar::IGUIScrollBar(CGUI& pGUI)
28 : : m_pGUI(pGUI),
29 : m_pStyle(nullptr),
30 : m_X(300.f), m_Y(300.f),
31 : m_ScrollRange(1.f), m_ScrollSpace(0.f), // MaxPos: not 0, due to division.
32 : m_Length(200.f), m_Width(20.f),
33 : m_BarSize(0.f), m_Pos(0.f),
34 : m_ButtonPlusPressed(false),
35 : m_ButtonMinusPressed(false),
36 : m_ButtonPlusHovered(false),
37 : m_ButtonMinusHovered(false),
38 : m_BarHovered(false),
39 0 : m_BarPressed(false)
40 : {
41 0 : }
42 :
43 0 : IGUIScrollBar::~IGUIScrollBar()
44 : {
45 0 : }
46 :
47 0 : void IGUIScrollBar::SetupBarSize()
48 : {
49 0 : if (!GetStyle())
50 0 : return;
51 :
52 0 : float min = GetStyle()->m_MinimumBarSize;
53 0 : float max = GetStyle()->m_MaximumBarSize;
54 0 : float length = m_Length;
55 :
56 : // Check for edge buttons
57 0 : if (GetStyle()->m_UseEdgeButtons)
58 0 : length -= GetStyle()->m_Width * 2.f;
59 :
60 : // Check min and max are valid
61 0 : if (min > length)
62 0 : min = 0.f;
63 0 : if (max < min)
64 0 : max = length;
65 :
66 : // Clamp size to not exceed a minimum or maximum.
67 0 : m_BarSize = Clamp(length * std::min(m_ScrollSpace / m_ScrollRange, 1.f), min, max);
68 : }
69 :
70 0 : const SGUIScrollBarStyle* IGUIScrollBar::GetStyle() const
71 : {
72 0 : if (!m_pHostObject)
73 0 : return nullptr;
74 :
75 0 : return m_pHostObject->GetScrollBarStyle(m_ScrollBarStyle);
76 : }
77 :
78 0 : void IGUIScrollBar::UpdatePosBoundaries()
79 : {
80 0 : if (m_Pos < 0.f ||
81 0 : m_ScrollRange < m_ScrollSpace) // <= scrolling not applicable
82 0 : m_Pos = 0.f;
83 0 : else if (m_Pos > GetMaxPos())
84 0 : m_Pos = GetMaxPos();
85 0 : }
86 :
87 0 : void IGUIScrollBar::HandleMessage(SGUIMessage& Message)
88 : {
89 0 : switch (Message.type)
90 : {
91 0 : case GUIM_MOUSE_MOTION:
92 : {
93 : // TODO Gee: Optimizations needed!
94 :
95 0 : const CVector2D& mouse = m_pGUI.GetMousePos();
96 :
97 : // If bar is being dragged
98 0 : if (m_BarPressed)
99 : {
100 0 : SetPosFromMousePos(mouse);
101 0 : UpdatePosBoundaries();
102 : }
103 :
104 : // check if components are being hovered
105 0 : m_BarHovered = GetBarRect().PointInside(mouse);
106 0 : m_ButtonMinusHovered = HoveringButtonMinus(mouse);
107 0 : m_ButtonPlusHovered = HoveringButtonPlus(mouse);
108 :
109 0 : if (!m_ButtonMinusHovered)
110 0 : m_ButtonMinusPressed = false;
111 :
112 0 : if (!m_ButtonPlusHovered)
113 0 : m_ButtonPlusPressed = false;
114 0 : break;
115 : }
116 :
117 0 : case GUIM_MOUSE_PRESS_LEFT:
118 : {
119 0 : if (!m_pHostObject)
120 0 : break;
121 :
122 0 : const CVector2D& mouse = m_pGUI.GetMousePos();
123 :
124 : // if bar is pressed
125 0 : if (GetBarRect().PointInside(mouse))
126 : {
127 0 : m_BarPressed = true;
128 0 : m_BarPressedAtPos = mouse;
129 0 : m_PosWhenPressed = m_Pos;
130 : }
131 : // if button-minus is pressed
132 0 : else if (m_ButtonMinusHovered)
133 : {
134 0 : m_ButtonMinusPressed = true;
135 0 : ScrollMinus();
136 : }
137 : // if button-plus is pressed
138 0 : else if (m_ButtonPlusHovered)
139 : {
140 0 : m_ButtonPlusPressed = true;
141 0 : ScrollPlus();
142 : }
143 : // Pressing the background of the bar, to scroll
144 : // notice the if-sentence alone does not admit that,
145 : // it must be after the above if/elses
146 : else
147 : {
148 0 : if (GetOuterRect().PointInside(mouse))
149 : {
150 : // Scroll plus or minus a lot, this might change, it doesn't
151 : // have to be fancy though.
152 0 : if (mouse.Y < GetBarRect().top)
153 0 : ScrollMinusPlenty();
154 : else
155 0 : ScrollPlusPlenty();
156 : // Simulate mouse movement to see if bar now is hovered
157 0 : SGUIMessage msg(GUIM_MOUSE_MOTION);
158 0 : HandleMessage(msg);
159 : }
160 : }
161 0 : break;
162 : }
163 :
164 0 : case GUIM_MOUSE_RELEASE_LEFT:
165 0 : m_ButtonMinusPressed = false;
166 0 : m_ButtonPlusPressed = false;
167 0 : break;
168 :
169 0 : case GUIM_MOUSE_WHEEL_UP:
170 : {
171 0 : ScrollMinus();
172 : // Since the scroll was changed, let's simulate a mouse movement
173 : // to check if scrollbar now is hovered
174 0 : SGUIMessage msg(GUIM_MOUSE_MOTION);
175 0 : HandleMessage(msg);
176 0 : break;
177 : }
178 :
179 0 : case GUIM_MOUSE_WHEEL_DOWN:
180 : {
181 0 : ScrollPlus();
182 : // Since the scroll was changed, let's simulate a mouse movement
183 : // to check if scrollbar now is hovered
184 0 : SGUIMessage msg(GUIM_MOUSE_MOTION);
185 0 : HandleMessage(msg);
186 0 : break;
187 : }
188 :
189 0 : default:
190 0 : break;
191 : }
192 0 : }
|