[Gameplay] Reduce loom cost
[0ad.git] / source / gui / IGUIScrollBar.cpp
blob68833f04bf625a2cc001918f4b957cf80dff9968
1 /* Copyright (C) 2021 Wildfire Games.
2 * This file is part of 0 A.D.
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.
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.
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/>.
18 #include "precompiled.h"
20 #include "IGUIScrollBar.h"
22 #include "gui/CGUI.h"
23 #include "gui/SGUIMessage.h"
24 #include "gui/ObjectBases/IGUIScrollBarOwner.h"
25 #include "maths/MathUtil.h"
27 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 m_BarPressed(false)
43 IGUIScrollBar::~IGUIScrollBar()
47 void IGUIScrollBar::SetupBarSize()
49 if (!GetStyle())
50 return;
52 float min = GetStyle()->m_MinimumBarSize;
53 float max = GetStyle()->m_MaximumBarSize;
54 float length = m_Length;
56 // Check for edge buttons
57 if (GetStyle()->m_UseEdgeButtons)
58 length -= GetStyle()->m_Width * 2.f;
60 // Check min and max are valid
61 if (min > length)
62 min = 0.f;
63 if (max < min)
64 max = length;
66 // Clamp size to not exceed a minimum or maximum.
67 m_BarSize = Clamp(length * std::min(m_ScrollSpace / m_ScrollRange, 1.f), min, max);
70 const SGUIScrollBarStyle* IGUIScrollBar::GetStyle() const
72 if (!m_pHostObject)
73 return nullptr;
75 return m_pHostObject->GetScrollBarStyle(m_ScrollBarStyle);
78 void IGUIScrollBar::UpdatePosBoundaries()
80 if (m_Pos < 0.f ||
81 m_ScrollRange < m_ScrollSpace) // <= scrolling not applicable
82 m_Pos = 0.f;
83 else if (m_Pos > GetMaxPos())
84 m_Pos = GetMaxPos();
87 void IGUIScrollBar::HandleMessage(SGUIMessage& Message)
89 switch (Message.type)
91 case GUIM_MOUSE_MOTION:
93 // TODO Gee: Optimizations needed!
95 const CVector2D& mouse = m_pGUI.GetMousePos();
97 // If bar is being dragged
98 if (m_BarPressed)
100 SetPosFromMousePos(mouse);
101 UpdatePosBoundaries();
104 // check if components are being hovered
105 m_BarHovered = GetBarRect().PointInside(mouse);
106 m_ButtonMinusHovered = HoveringButtonMinus(mouse);
107 m_ButtonPlusHovered = HoveringButtonPlus(mouse);
109 if (!m_ButtonMinusHovered)
110 m_ButtonMinusPressed = false;
112 if (!m_ButtonPlusHovered)
113 m_ButtonPlusPressed = false;
114 break;
117 case GUIM_MOUSE_PRESS_LEFT:
119 if (!m_pHostObject)
120 break;
122 const CVector2D& mouse = m_pGUI.GetMousePos();
124 // if bar is pressed
125 if (GetBarRect().PointInside(mouse))
127 m_BarPressed = true;
128 m_BarPressedAtPos = mouse;
129 m_PosWhenPressed = m_Pos;
131 // if button-minus is pressed
132 else if (m_ButtonMinusHovered)
134 m_ButtonMinusPressed = true;
135 ScrollMinus();
137 // if button-plus is pressed
138 else if (m_ButtonPlusHovered)
140 m_ButtonPlusPressed = true;
141 ScrollPlus();
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
148 if (GetOuterRect().PointInside(mouse))
150 // Scroll plus or minus a lot, this might change, it doesn't
151 // have to be fancy though.
152 if (mouse.Y < GetBarRect().top)
153 ScrollMinusPlenty();
154 else
155 ScrollPlusPlenty();
156 // Simulate mouse movement to see if bar now is hovered
157 SGUIMessage msg(GUIM_MOUSE_MOTION);
158 HandleMessage(msg);
161 break;
164 case GUIM_MOUSE_RELEASE_LEFT:
165 m_ButtonMinusPressed = false;
166 m_ButtonPlusPressed = false;
167 break;
169 case GUIM_MOUSE_WHEEL_UP:
171 ScrollMinus();
172 // Since the scroll was changed, let's simulate a mouse movement
173 // to check if scrollbar now is hovered
174 SGUIMessage msg(GUIM_MOUSE_MOTION);
175 HandleMessage(msg);
176 break;
179 case GUIM_MOUSE_WHEEL_DOWN:
181 ScrollPlus();
182 // Since the scroll was changed, let's simulate a mouse movement
183 // to check if scrollbar now is hovered
184 SGUIMessage msg(GUIM_MOUSE_MOTION);
185 HandleMessage(msg);
186 break;
189 default:
190 break;