1 /***************************************************************************
2 * Mechanized Assault and Exploration Reloaded Projectfile *
3 * *
4 * This program 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 * This program 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 this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
19
20 #include "ui/graphical/menu/widgets/special/resourcebar.h"
21
22 #include "main.h"
23 #include "settings.h"
24 #include "video.h"
25 #include "input/mouse/mouse.h"
26 #include "output/sound/sounddevice.h"
27 #include "output/sound/soundchannel.h"
28
29 //------------------------------------------------------------------------------
cResourceBar(const cBox<cPosition> & area,int minValue_,int maxValue_,eResourceBarType type,eOrientationType orientation_,cSoundChunk * clickSound_)30 cResourceBar::cResourceBar (const cBox<cPosition>& area, int minValue_, int maxValue_, eResourceBarType type, eOrientationType orientation_, cSoundChunk* clickSound_) :
31 cClickableWidget (area),
32 clickSound (clickSound_),
33 orientation (orientation_),
34 additionalArea (orientation == eOrientationType::Horizontal ? 8 : 0, orientation == eOrientationType::Vertical ? 8 : 0),
35 minValue (minValue_),
36 maxValue (maxValue_),
37 currentValue (maxValue_),
38 fixedMinEnabled (false),
39 fixedMinValue (minValue_),
40 fixedMaxEnabled (false),
41 fixedMaxValue (maxValue_),
42 inverted (false),
43 stepSize (1)
44 {
45 assert (minValue <= maxValue);
46 assert (minValue >= 0 && maxValue >= 0);
47
48 createSurface (type);
49
50 resize (getSize() + additionalArea * 2);
51 move (additionalArea * -1);
52 }
53
54 //------------------------------------------------------------------------------
draw(SDL_Surface & destination,const cBox<cPosition> & clipRect)55 void cResourceBar::draw (SDL_Surface& destination, const cBox<cPosition>& clipRect)
56 {
57 if (surface != nullptr && (maxValue - minValue) > 0)
58 {
59 const bool horizontal = orientation == eOrientationType::Horizontal;
60
61 SDL_Rect src;
62 src.h = horizontal ? surface->h : (currentValue * surface->h / maxValue);
63 src.w = horizontal ? (currentValue * surface->w / maxValue) : surface->w;
64 src.x = horizontal ? surface->w - src.w : 0;
65 src.y = 0;
66
67 SDL_Rect dest;
68 dest.h = dest.w = 0;
69 dest.x = getPosition().x() + additionalArea.x();
70 dest.y = getPosition().y() + (horizontal ? 0 : surface->h - src.h) + additionalArea.y();
71
72 if (inverted && horizontal)
73 {
74 dest.x += surface->w - src.w;
75 src.x = 0;
76 }
77
78 SDL_BlitSurface (surface.get(), &src, &destination, &dest);
79 }
80
81 cClickableWidget::draw (destination, clipRect);
82 }
83
84 //------------------------------------------------------------------------------
setType(eResourceBarType type)85 void cResourceBar::setType (eResourceBarType type)
86 {
87 createSurface (type);
88 }
89
90 //------------------------------------------------------------------------------
setStepSize(int stepSize_)91 void cResourceBar::setStepSize (int stepSize_)
92 {
93 stepSize = stepSize_;
94 setValue (getValue());
95 }
96
97 //------------------------------------------------------------------------------
getMinValue() const98 int cResourceBar::getMinValue() const
99 {
100 return minValue;
101 }
102
103 //------------------------------------------------------------------------------
setMinValue(int minValue_)104 void cResourceBar::setMinValue (int minValue_)
105 {
106 minValue = minValue_;
107 setValue (getValue());
108 }
109
110 //------------------------------------------------------------------------------
getMaxValue() const111 int cResourceBar::getMaxValue() const
112 {
113 return maxValue;
114 }
115
116 //------------------------------------------------------------------------------
setMaxValue(int maxValue_)117 void cResourceBar::setMaxValue (int maxValue_)
118 {
119 maxValue = maxValue_;
120 setValue (getValue());
121 }
122
123 //------------------------------------------------------------------------------
getFixedMinValue() const124 int cResourceBar::getFixedMinValue() const
125 {
126 return fixedMinEnabled ? fixedMinValue : minValue;
127 }
128
129 //------------------------------------------------------------------------------
setFixedMinValue(int fixedMinValue_)130 void cResourceBar::setFixedMinValue (int fixedMinValue_)
131 {
132 fixedMinValue = std::max (fixedMinValue_, minValue);
133 fixedMinEnabled = true;
134 setValue (getValue());
135 }
136
137 //------------------------------------------------------------------------------
getFixedMaxValue() const138 int cResourceBar::getFixedMaxValue() const
139 {
140 return fixedMaxEnabled ? fixedMaxValue : maxValue;
141 }
142
143 //------------------------------------------------------------------------------
setFixedMaxValue(int fixedMaxValue_)144 void cResourceBar::setFixedMaxValue (int fixedMaxValue_)
145 {
146 fixedMaxValue = std::min (fixedMaxValue_, maxValue);
147 fixedMaxEnabled = true;
148 setValue (getValue());
149 }
150
151 //------------------------------------------------------------------------------
isInverted() const152 bool cResourceBar::isInverted() const
153 {
154 return inverted;
155 }
156
157 //------------------------------------------------------------------------------
setInverted(bool inverted_)158 void cResourceBar::setInverted (bool inverted_)
159 {
160 inverted = inverted_;
161 }
162
163 //------------------------------------------------------------------------------
getValue() const164 int cResourceBar::getValue() const
165 {
166 return currentValue;
167 }
168
169 //------------------------------------------------------------------------------
setValue(int value)170 void cResourceBar::setValue (int value)
171 {
172 value = std::max (minValue, value);
173 value = std::min (maxValue, value);
174
175 if (value < (maxValue / stepSize) * stepSize && value % stepSize != 0)
176 {
177 value = Round ((float)value / stepSize) * stepSize;
178 }
179
180 value = std::max (getFixedMinValue(), value);
181 value = std::min (getFixedMaxValue(), value);
182
183 if (value != currentValue)
184 {
185 currentValue = value;
186 valueChanged();
187 }
188 }
189
190 //------------------------------------------------------------------------------
increase(int offset)191 void cResourceBar::increase (int offset)
192 {
193 setValue (getValue() + offset);
194 }
195
196 //------------------------------------------------------------------------------
decrease(int offset)197 void cResourceBar::decrease (int offset)
198 {
199 increase (-offset);
200 }
201
202 //------------------------------------------------------------------------------
handleClicked(cApplication & application,cMouse & mouse,eMouseButtonType button)203 bool cResourceBar::handleClicked (cApplication& application, cMouse& mouse, eMouseButtonType button)
204 {
205 if (button == eMouseButtonType::Left)
206 {
207 if (clickSound) cSoundDevice::getInstance().playSoundEffect (*clickSound);
208
209 const auto valueRange = maxValue - minValue;
210 switch (orientation)
211 {
212 default:
213 case eOrientationType::Horizontal:
214 setValue (minValue + (mouse.getPosition().x() - (getPosition().x() + additionalArea.x())) * valueRange / (getSize().x() - additionalArea.x() * 2));
215 break;
216 case eOrientationType::Vertical:
217 setValue (minValue + valueRange - (mouse.getPosition().y() - (getPosition().y() + additionalArea.y())) * valueRange / (getSize().y() - additionalArea.y() * 2));
218 break;
219 }
220
221 return true;
222 }
223 return false;
224 }
225
226 //------------------------------------------------------------------------------
createSurface(eResourceBarType type)227 void cResourceBar::createSurface (eResourceBarType type)
228 {
229 cPosition srcPosition;
230 switch (orientation)
231 {
232 default:
233 case eOrientationType::Horizontal:
234 switch (type)
235 {
236 default:
237 case eResourceBarType::Metal:
238 srcPosition.x() = 156;
239 srcPosition.y() = 339;
240 break;
241 case eResourceBarType::Oil:
242 srcPosition.x() = 156;
243 srcPosition.y() = 369;
244 break;
245 case eResourceBarType::Gold:
246 srcPosition.x() = 156;
247 srcPosition.y() = 400;
248 break;
249 case eResourceBarType::Blocked:
250 srcPosition.x() = 156;
251 srcPosition.y() = 307;
252 break;
253 case eResourceBarType::MetalSlim:
254 srcPosition.x() = 156;
255 srcPosition.y() = 256;
256 break;
257 case eResourceBarType::OilSlim:
258 srcPosition.x() = 156;
259 srcPosition.y() = 273;
260 break;
261 case eResourceBarType::GoldSlim:
262 srcPosition.x() = 156;
263 srcPosition.y() = 290;
264 break;
265 }
266 break;
267 case eOrientationType::Vertical:
268 switch (type)
269 {
270 default:
271 case eResourceBarType::Metal:
272 srcPosition.x() = 135;
273 srcPosition.y() = 336;
274 break;
275 case eResourceBarType::Oil:
276 srcPosition.x() = 400;
277 srcPosition.y() = 348;
278 break;
279 case eResourceBarType::Gold:
280 srcPosition.x() = 114;
281 srcPosition.y() = 336;
282 break;
283 }
284 break;
285 }
286
287 cPosition size;
288 switch (orientation)
289 {
290 default:
291 case eOrientationType::Horizontal:
292 switch (type)
293 {
294 default:
295 case eResourceBarType::Metal:
296 case eResourceBarType::Oil:
297 case eResourceBarType::Gold:
298 case eResourceBarType::Blocked:
299 size.x() = 240;
300 size.y() = 30;
301 break;
302 case eResourceBarType::MetalSlim:
303 case eResourceBarType::OilSlim:
304 case eResourceBarType::GoldSlim:
305 size.x() = 223;
306 size.y() = 16;
307 break;
308 }
309 break;
310 case eOrientationType::Vertical:
311 size.x() = 20;
312 size.y() = 115;
313 break;
314 }
315
316 surface = AutoSurface (SDL_CreateRGBSurface (0, size.x(), size.y(), Video.getColDepth(), 0, 0, 0, 0));
317
318 SDL_SetColorKey (surface.get(), SDL_TRUE, 0xFF00FF);
319 SDL_FillRect (surface.get(), nullptr, 0xFF00FF);
320
321 SDL_Rect src = {srcPosition.x(), srcPosition.y(), size.x(), size.y()};
322 SDL_BlitSurface (GraphicsData.gfx_hud_stuff.get(), &src, surface.get(), nullptr);
323 }
324