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"
23 #include "gui/SGUIMessage.h"
24 #include "gui/ObjectBases/IGUIScrollBarOwner.h"
25 #include "maths/MathUtil.h"
27 IGUIScrollBar::IGUIScrollBar(CGUI
& pGUI
)
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),
43 IGUIScrollBar::~IGUIScrollBar()
47 void IGUIScrollBar::SetupBarSize()
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
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
75 return m_pHostObject
->GetScrollBarStyle(m_ScrollBarStyle
);
78 void IGUIScrollBar::UpdatePosBoundaries()
81 m_ScrollRange
< m_ScrollSpace
) // <= scrolling not applicable
83 else if (m_Pos
> GetMaxPos())
87 void IGUIScrollBar::HandleMessage(SGUIMessage
& Message
)
91 case GUIM_MOUSE_MOTION
:
93 // TODO Gee: Optimizations needed!
95 const CVector2D
& mouse
= m_pGUI
.GetMousePos();
97 // If bar is being dragged
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;
117 case GUIM_MOUSE_PRESS_LEFT
:
122 const CVector2D
& mouse
= m_pGUI
.GetMousePos();
125 if (GetBarRect().PointInside(mouse
))
128 m_BarPressedAtPos
= mouse
;
129 m_PosWhenPressed
= m_Pos
;
131 // if button-minus is pressed
132 else if (m_ButtonMinusHovered
)
134 m_ButtonMinusPressed
= true;
137 // if button-plus is pressed
138 else if (m_ButtonPlusHovered
)
140 m_ButtonPlusPressed
= true;
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
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
)
156 // Simulate mouse movement to see if bar now is hovered
157 SGUIMessage
msg(GUIM_MOUSE_MOTION
);
164 case GUIM_MOUSE_RELEASE_LEFT
:
165 m_ButtonMinusPressed
= false;
166 m_ButtonPlusPressed
= false;
169 case GUIM_MOUSE_WHEEL_UP
:
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
);
179 case GUIM_MOUSE_WHEEL_DOWN
:
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
);