ManaPlus
progressbar.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2004-2009 The Mana World Development Team
4  * Copyright (C) 2009-2010 The Mana Developers
5  * Copyright (C) 2011-2019 The ManaPlus Developers
6  * Copyright (C) 2019-2021 Andrei Karas
7  *
8  * This file is part of The ManaPlus Client.
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program. If not, see <http://www.gnu.org/licenses/>.
22  */
23 
25 
26 #include "settings.h"
27 
28 #include "gui/gui.h"
29 #include "gui/skin.h"
30 
31 #include "gui/fonts/font.h"
32 
33 #include "utils/delete2.h"
34 
35 #include "render/graphics.h"
36 
38 
39 #include "debug.h"
40 
42 float ProgressBar::mAlpha = 1.0;
43 
44 ProgressBar::ProgressBar(const Widget2 *const widget,
45  float progress,
46  const int width,
47  const int height,
48  const ProgressColorIdT backColor,
49  const std::string &skin,
50  const std::string &skinFill) :
51  Widget(widget),
53  mFillRect(),
54  mTextChunk(),
55  mSkin(nullptr),
56  mProgress(progress),
57  mProgressToGo(progress),
58  mBackgroundColorToGo(),
59  mText(),
60  mVertexes(new ImageCollection),
61  mProgressPalette(backColor),
62  mPadding(2),
63  mFillPadding(3),
64  mFillImage(false),
65  mSmoothProgress(true),
66  mSmoothColorChange(true),
67  mTextChanged(true)
68 {
70  backColor >= ProgressColorId::PROG_HP
71  ? backColor : ProgressColorId::PROG_HP,
72  mProgress);
74  mForegroundColor2 = getThemeColor(ThemeColorId::PROGRESS_BAR_OUTLINE,
75  255U);
76 
77  // The progress value is directly set at load time:
78  if (mProgress > 1.0F || mProgress < 0.0F)
79  mProgress = 1.0F;
80 
81  mForegroundColor = getThemeColor(ThemeColorId::PROGRESS_BAR, 255U);
82  addWidgetListener(this);
83  setSize(width, height);
84 
85  if (theme != nullptr)
86  {
87  mSkin = theme->load(skin,
88  "progressbar.xml",
89  true,
91  if (mSkin != nullptr)
92  {
94  mFillPadding = mSkin->getOption("fillPadding");
95  mFillImage = mSkin->getOption("fillImage") != 0;
96  if (mFillImage)
97  {
99  skinFill,
100  "progressbar_fill.xml",
101  0,
102  8);
103  }
104  }
105  setHeight(2 * mPadding + getFont()->getHeight() + 2);
106  }
107 
108  mInstances++;
109 }
110 
112 {
113  if (gui != nullptr)
114  gui->removeDragged(this);
115 
116  mInstances--;
117  if (mSkin != nullptr)
118  {
119  if (theme != nullptr)
120  theme->unload(mSkin);
121  mSkin = nullptr;
122  }
126 }
127 
129 {
130  BLOCK_START("ProgressBar::logic")
132  {
133  // Smoothly changing the color for a nicer effect.
146  mRedraw = true;
147  }
148 
150  {
151  // Smoothly showing the progressbar changes.
152  if (mProgressToGo > mProgress)
153  mProgress = std::min(1.0F, mProgress + 0.005F);
154  if (mProgressToGo < mProgress)
155  mProgress = std::max(0.0F, mProgress - 0.005F);
156  mRedraw = true;
157  }
158  BLOCK_END("ProgressBar::logic")
159 }
160 
162 {
163  const float alpha = std::max(settings.guiAlpha,
165  mAlpha = alpha;
166 }
167 
168 void ProgressBar::draw(Graphics *const graphics)
169 {
170  BLOCK_START("ProgressBar::draw")
171  if (mSkin == nullptr)
172  {
173  BLOCK_END("ProgressBar::draw")
174  return;
175  }
176 
177  updateAlpha();
179 
180  if (mRedraw || graphics->getRedraw())
181  {
182  mRedraw = false;
183  mVertexes->clear();
184  graphics->calcWindow(mVertexes, 0, 0,
186  if (mFillImage)
187  {
188  const unsigned int pad = 2 * mFillPadding;
189  const int maxWidth = mDimension.width - pad;
190  int width = CAST_S32(mProgress
191  * static_cast<float>(maxWidth));
192  if (width > 0)
193  {
194  if (width > maxWidth)
195  width = maxWidth;
197  width, mDimension.height - pad, mFillRect);
198  }
199  }
200  graphics->finalize(mVertexes);
201  }
202 
203  graphics->drawTileCollection(mVertexes);
204 
205  // The bar
206  if (!mFillImage && mProgress > 0)
207  {
208  graphics->setColor(mBackgroundColor);
209  const unsigned int pad = 2 * mFillPadding;
210  const int maxWidth = mDimension.width - pad;
211  int width = CAST_S32(mProgress * static_cast<float>(maxWidth));
212  if (width > 0)
213  {
214  if (width > maxWidth)
215  width = maxWidth;
217  width, mDimension.height - pad));
218  }
219  }
220 
221  // The label
222  if (!mText.empty())
223  {
224  Font *const font = gui->getFont();
225  if (mTextChanged)
226  {
227  mTextChunk.textFont = font;
232  font->generate(mTextChunk);
233  mTextChanged = false;
234  }
235 
236  const Image *const image = mTextChunk.img;
237  if (image != nullptr)
238  {
239  const int textX = (mDimension.width - font->getWidth(mText)) / 2;
240  const int textY = (mDimension.height - font->getHeight()) / 2;
241  graphics->drawImage(image, textX, textY);
242  }
243  }
244  BLOCK_END("ProgressBar::draw")
245 }
246 
247 void ProgressBar::safeDraw(Graphics *const graphics)
248 {
249  BLOCK_START("ProgressBar::safeDraw")
250  if (mSkin == nullptr)
251  {
252  BLOCK_END("ProgressBar::safeDraw")
253  return;
254  }
255 
256  updateAlpha();
258 
260  mSkin->getBorder());
261  if (mFillImage)
262  {
263  const unsigned int pad = 2 * mFillPadding;
264  const int maxWidth = mDimension.width - pad;
265  int width = CAST_S32(mProgress
266  * static_cast<float>(maxWidth));
267  if (width > 0)
268  {
269  if (width > maxWidth)
270  width = maxWidth;
272  width, mDimension.height - pad, mFillRect);
273  }
274  }
275 
276  // The bar
277  if (!mFillImage && mProgress > 0)
278  {
279  graphics->setColor(mBackgroundColor);
280  const unsigned int pad = 2 * mFillPadding;
281  const int maxWidth = mDimension.width - pad;
282  int width = CAST_S32(mProgress * static_cast<float>(maxWidth));
283  if (width > 0)
284  {
285  if (width > maxWidth)
286  width = maxWidth;
288  width, mDimension.height - pad));
289  }
290  }
291 
292  // The label
293  if (!mText.empty())
294  {
295  Font *const font = gui->getFont();
296  if (mTextChanged)
297  {
298  mTextChunk.textFont = font;
303  font->generate(mTextChunk);
304  mTextChanged = false;
305  }
306 
307  const Image *const image = mTextChunk.img;
308  if (image != nullptr)
309  {
310  const int textX = (mDimension.width - font->getWidth(mText)) / 2;
311  const int textY = (mDimension.height - font->getHeight()) / 2;
312  graphics->drawImage(image, textX, textY);
313  }
314  }
315  BLOCK_END("ProgressBar::safeDraw")
316 }
317 
318 void ProgressBar::setProgress(const float progress)
319 {
320  const float p = std::min(1.0F, std::max(0.0F, progress));
321  mProgressToGo = p;
322  mRedraw = true;
323 
324  if (!mSmoothProgress)
325  mProgress = p;
326 
328  {
330  mProgressPalette, progress);
331  }
332 }
333 
335 {
336  const ProgressColorIdT oldPalette = mProgressPalette;
337  mProgressPalette = progressPalette;
338  mRedraw = true;
339 
340  if (mProgressPalette != oldPalette &&
342  {
345  }
346 }
347 
349 {
350  mRedraw = true;
351  mBackgroundColorToGo = color;
352 
353  if (!mSmoothColorChange)
354  mBackgroundColor = color;
355 }
356 
357 void ProgressBar::setColor(const Color &color1, const Color &color2)
358 {
359  mForegroundColor = color1;
360  mForegroundColor2 = color2;
361  mTextChanged = true;
362 }
363 
365 {
366  mRedraw = true;
367 }
368 
370 {
371  mRedraw = true;
372 }
373 
374 void ProgressBar::setText(const std::string &str)
375 {
376  if (mText != str)
377  {
378  mText = str;
379  mTextChanged = true;
380  }
381 }
382 
384 {
385  mTextChanged = true;
387 }
#define CAST_S32
Definition: cast.h:30
#define CAST_U32
Definition: cast.h:31
Definition: color.h:76
unsigned int a
Definition: color.h:251
unsigned int b
Definition: color.h:245
unsigned int r
Definition: color.h:235
unsigned int g
Definition: color.h:240
Definition: event.h:79
Definition: font.h:90
int getHeight() const
Definition: font.cpp:362
void generate(TextChunk &chunk)
Definition: font.cpp:430
int getWidth(const std::string &text) const
Definition: font.cpp:334
virtual void drawImage(const Image *const image, int dstX, int dstY)=0
virtual void drawTileCollection(const ImageCollection *const vertCol)=0
bool getRedraw() const
Definition: graphics.h:287
virtual void fillRectangle(const Rect &rectangle)=0
virtual void setColor(const Color &color)
Definition: graphics.h:320
virtual void finalize(ImageCollection *const col)
Definition: graphics.h:465
virtual void calcWindow(ImageCollection *const vertCol, const int x, const int y, const int w, const int h, const ImageRect &imgRect)=0
virtual void drawImageRect(const int x, const int y, const int w, const int h, const ImageRect &imgRect)=0
Font * getFont() const
Definition: gui.h:160
void removeDragged(const Widget *const widget)
Definition: gui.cpp:1162
unsigned int mFillPadding
Definition: progressbar.h:156
void widgetMoved(const Event &event)
void draw(Graphics *const graphics)
void setProgress(const float progress)
bool mTextChanged
Definition: progressbar.h:164
static float mAlpha
Definition: progressbar.h:159
Skin * mSkin
Definition: progressbar.h:146
void setPadding(unsigned int padding)
Definition: progressbar.h:140
float mProgress
Definition: progressbar.h:147
void setColor(const Color &color1, const Color &color2)
void widgetHidden(const Event &event)
static int mInstances
Definition: progressbar.h:158
std::string mText
Definition: progressbar.h:152
float mProgressToGo
Definition: progressbar.h:148
void setBackgroundColor(const Color &color)
void setProgressPalette(const ProgressColorIdT progressPalette)
ProgressBar(const Widget2 *const widget, float progress, const int width, const int height, const ProgressColorIdT backColor, const std::string &skin, const std::string &skinFill)
Definition: progressbar.cpp:44
bool mSmoothProgress
Definition: progressbar.h:162
ImageCollection * mVertexes
Definition: progressbar.h:153
void widgetResized(const Event &event)
bool mSmoothColorChange
Definition: progressbar.h:163
TextChunk mTextChunk
Definition: progressbar.h:145
Color mBackgroundColorToGo
Definition: progressbar.h:150
void safeDraw(Graphics *const graphics)
unsigned int mPadding
Definition: progressbar.h:155
void updateAlpha()
void setText(const std::string &str)
bool mFillImage
Definition: progressbar.h:161
ImageRect mFillRect
Definition: progressbar.h:144
ProgressColorIdT mProgressPalette
Definition: progressbar.h:154
Definition: rect.h:74
int width
Definition: rect.h:219
int height
Definition: rect.h:224
float guiAlpha
Definition: settings.h:131
int getOption(const std::string &name) const
Definition: skin.h:106
const ImageRect & getBorder() const
Definition: skin.h:68
int getPadding() const
Definition: skin.h:100
void deleteImage()
Definition: textchunk.cpp:193
Font * textFont
Definition: textchunk.h:64
Image * img
Definition: textchunk.h:63
Color color
Definition: textchunk.h:66
Color color2
Definition: textchunk.h:67
std::string text
Definition: textchunk.h:65
void unload(Skin *const skin)
Definition: theme.cpp:250
static std::string getThemePath()
Definition: theme.h:67
static void unloadRect(const ImageRect &rect, const int start, const int end)
Definition: theme.cpp:915
Skin * load(const std::string &filename, const std::string &filename2, const bool full, const std::string &defaultPath)
Definition: theme.cpp:179
void loadRect(ImageRect &image, const std::string &name, const std::string &name2, const int start, const int end)
Definition: theme.cpp:883
float getMinimumOpacity() const
Definition: theme.h:124
static Color getProgressColor(const ProgressColorIdT type, const float progress)
Definition: theme.cpp:155
Color mForegroundColor2
Definition: widget2.h:113
const Color & getThemeColor(const ThemeColorIdT type, const unsigned int alpha) const A_INLINE
Definition: widget2.h:45
Definition: widget.h:99
Color mForegroundColor
Definition: widget.h:1086
void setSize(const int width, const int height)
Definition: widget.cpp:367
Rect mDimension
Definition: widget.h:1101
Color mBackgroundColor
Definition: widget.h:1091
void addWidgetListener(WidgetListener *const widgetListener)
Definition: widget.cpp:302
void setHeight(const int height)
Definition: widget.cpp:140
bool mRedraw
Definition: widget.h:1164
Font * getFont() const
Definition: widget.cpp:331
int getHeight() const
Definition: widget.h:240
#define new
Definition: debug_new.h:147
#define delete2(var)
Definition: delete2.h:25
Gui * gui
Definition: gui.cpp:111
#define nullptr
Definition: localconsts.h:45
#define A_UNUSED
Definition: localconsts.h:160
#define BLOCK_END(name)
Definition: perfomance.h:80
#define BLOCK_START(name)
Definition: perfomance.h:79
ProgressColorId ::T ProgressColorIdT
Settings settings
Definition: settings.cpp:32
Theme * theme
Definition: theme.cpp:62