ManaPlus
ministatuswindow.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 "configuration.h"
27 
28 #include "being/localplayer.h"
29 #include "being/playerinfo.h"
30 
31 #include "gui/popupmanager.h"
32 #include "gui/skin.h"
33 
34 #include "gui/popups/popupmenu.h"
35 #include "gui/popups/statuspopup.h"
36 #include "gui/popups/textpopup.h"
37 
39 
42 
43 #include "net/playerhandler.h"
44 
46 
48 
49 #include "utils/delete2.h"
50 #include "utils/dtor.h"
51 #include "utils/foreach.h"
52 #include "utils/gettext.h"
53 
54 #include "debug.h"
55 
57 extern volatile int tick_time;
58 
59 typedef STD_VECTOR <ProgressBar*>::const_iterator ProgressBarVectorCIter;
60 
62  Window("MiniStatus", Modal_false, nullptr, "ministatus.xml"),
65  StatListener(),
68  mBars(),
69  mBarNames(),
70  mIcons(),
71  mHpBar(createBar(0, 100, 0, ThemeColorId::HP_BAR, ProgressColorId::PROG_HP,
72  "hpprogressbar.xml", "hpprogressbar_fill.xml",
73  // TRANSLATORS: status bar name
74  "hp bar", _("health bar"))),
75  mMpBar(createBar(0, 100, 0, playerHandler->canUseMagic()
76  ? ThemeColorId::MP_BAR : ThemeColorId::NO_MP_BAR,
77  playerHandler->canUseMagic()
79  playerHandler->canUseMagic()
80  ? "mpprogressbar.xml" : "nompprogressbar.xml",
81  playerHandler->canUseMagic()
82  ? "mpprogressbar_fill.xml" : "nompprogressbar_fill.xml",
83  // TRANSLATORS: status bar name
84  "mp bar", _("mana bar"))),
85  mXpBar(createBar(0, 100, 0,
87  "xpprogressbar.xml", "xpprogressbar_fill.xml",
88  // TRANSLATORS: status bar name
89  "xp bar", _("experience bar"))),
90  mJobBar(nullptr),
91  mWeightBar(createBar(0, 140, 0, ThemeColorId::WEIGHT_BAR,
93  "weightprogressbar.xml", "weightprogressbar_fill.xml",
94  // TRANSLATORS: status bar name
95  "weight bar", _("weight bar"))),
96  mInvSlotsBar(createBar(0, 45, 0,
98  "slotsprogressbar.xml", "slotsprogressbar_fill.xml",
99  "inventory slots bar",
100  // TRANSLATORS: status bar name
101  _("inventory slots bar"))),
102  mMoneyBar(createBar(0, 130, 0, ThemeColorId::MONEY_BAR,
104  "moneyprogressbar.xml", "moneyprogressbar_fill.xml",
105  // TRANSLATORS: status bar name
106  "money bar", _("money bar"))),
107  mArrowsBar(createBar(0, 50, 0, ThemeColorId::ARROWS_BAR,
109  "arrowsprogressbar.xml", "arrowsprogressbar_fill.xml",
110  // TRANSLATORS: status bar name
111  "arrows bar", _("arrows bar"))),
112  mStatusBar(createBar(100, (config.getIntValue("fontSize") > 16
113  ? 270 : 180), 0, ThemeColorId::STATUS_BAR,
115  "statusprogressbar.xml", "statusprogressbar_fill.xml",
116  // TRANSLATORS: status bar name
117  "status bar", _("status bar"))),
118  mStatusPopup(CREATEWIDGETR0(StatusPopup)),
119  mSpacing(mSkin != nullptr ? mSkin->getOption("spacing", 3) : 3),
120  mIconPadding(mSkin != nullptr ? mSkin->getOption("iconPadding", 3) : 3),
121  mIconSpacing(mSkin != nullptr ? mSkin->getOption("iconSpacing", 2) : 2),
122  mMaxX(0)
123 {
125  false);
126 
127  if (statusWindow != nullptr)
128  {
130  false);
131  }
132 
133  const bool job = serverConfig.getValueBool("showJob", true);
134 
136  true);
137 
138  if (job)
139  {
140  mJobBar = createBar(0, 100, 0,
141  ThemeColorId::JOB_BAR,
143  "jobprogressbar.xml", "jobprogressbar_fill.xml",
144  // TRANSLATORS: status bar name
145  "job bar", _("job bar"));
147  true);
148  }
149 
150  loadBars();
151  updateBars();
152 
154  addMouseListener(this);
155  Inventory *const inv = PlayerInfo::getInventory();
156  if (inv != nullptr)
157  inv->addInventoyListener(this);
158 
161  updateStatus();
162 }
163 
165 {
168  mIcons.clear();
169 
170  Inventory *const inv = PlayerInfo::getInventory();
171  if (inv != nullptr)
172  inv->removeInventoyListener(this);
173 
175  {
176  ProgressBar *bar = *it;
177  if (bar == nullptr)
178  continue;
179  if (bar->mVisible == Visible_false)
180  delete bar;
181  }
182  mBars.clear();
183 }
184 
186  const int width,
187  const int height,
188  const ThemeColorIdT textColor,
189  const ProgressColorIdT backColor,
190  const std::string &restrict skin,
191  const std::string &restrict skinFill,
192  const std::string &restrict name,
193  const std::string &restrict
194  description)
195 {
196  ProgressBar *const bar = new ProgressBar(this,
197  progress, width, height, backColor, skin, skinFill);
198  bar->setActionEventId(name);
199  bar->setId(description);
200  bar->setColor(getThemeColor(textColor, 255U),
201  getThemeColor(textColor + 1, 255U));
202  mBars.push_back(bar);
203  mBarNames[name] = bar;
204  return bar;
205 }
206 
208 {
209  int x = 0;
210  const ProgressBar *lastBar = nullptr;
212  remove(*it);
213 
215  {
216  ProgressBar *const bar = *it;
217  if (bar == nullptr)
218  continue;
219  if (bar->mVisible == Visible_true)
220  {
221  bar->setPosition(x, 0);
222  add(bar);
223  x += bar->getWidth() + mSpacing;
224  lastBar = bar;
225  }
226  }
227 
228  if (lastBar != nullptr)
229  {
230  setContentSize(lastBar->getX() + lastBar->getWidth(),
231  lastBar->getY() + lastBar->getHeight());
232  }
233  mMaxX = x;
234 }
235 
236 void MiniStatusWindow::setIcon(const int index, AnimatedSprite *const sprite)
237 {
238  if (index >= CAST_S32(mIcons.size()))
239  mIcons.resize(index + 1, nullptr);
240 
241  delete mIcons[index];
242  mIcons[index] = sprite;
243 }
244 
245 void MiniStatusWindow::eraseIcon(const int index)
246 {
247  if (index < CAST_S32(mIcons.size()))
248  {
249  delete mIcons[index];
250  mIcons.erase(mIcons.begin() + index);
251  }
252 }
253 
255 {
256  // Draw icons
257  unsigned int icon_x = mMaxX + mIconPadding;
258  for (size_t i = 0, sz = mIcons.size(); i < sz; i ++)
259  {
260  const AnimatedSprite *const icon = mIcons[i];
261  if (icon != nullptr)
262  {
263  icon->draw(graphics, CAST_S32(icon_x), mIconPadding);
264  icon_x += CAST_U32(mIconSpacing + icon->getWidth());
265  }
266  }
267 }
268 
270  const int oldVal1 A_UNUSED,
271  const int oldVal2 A_UNUSED)
272 {
273  if (statusWindow != nullptr)
274  {
276  false);
277  }
279  true);
280 }
281 
283  const int64_t oldVal A_UNUSED,
284  const int64_t newVal A_UNUSED)
285 {
286  PRAGMA45(GCC diagnostic push)
287  PRAGMA45(GCC diagnostic ignored "-Wswitch-enum")
288  switch (id)
289  {
293  false);
294  break;
298  false);
299  break;
303  true);
304  break;
308  break;
309  case Attributes::MONEY:
311  break;
312  default:
313  break;
314  }
315  PRAGMA45(GCC diagnostic pop)
316 }
317 
319 {
320  if (statusWindow != nullptr)
321  {
323  true);
324  }
325  if ((mStatusPopup != nullptr) && mStatusPopup->isPopupVisible())
326  mStatusPopup->update();
327 }
328 
330 {
331  BLOCK_START("MiniStatusWindow::logic")
332  Window::logic();
333 
334  for (size_t i = 0, sz = mIcons.size(); i < sz; i++)
335  {
336  AnimatedSprite *const icon = mIcons[i];
337  if (icon != nullptr)
338  icon->update(tick_time * 10);
339  }
340  BLOCK_END("MiniStatusWindow::logic")
341 }
342 
343 void MiniStatusWindow::draw(Graphics *const graphics)
344 {
345  BLOCK_START("MiniStatusWindow::draw")
346  drawChildren(graphics);
347  BLOCK_END("MiniStatusWindow::draw")
348 }
349 
351 {
352  BLOCK_START("MiniStatusWindow::draw")
353  safeDrawChildren(graphics);
354  BLOCK_END("MiniStatusWindow::draw")
355 }
356 
358 {
359  Window::mouseMoved(event);
360 
361  const int x = event.getX();
362  const int y = event.getY();
363 
364  const Rect &rect = mDimension;
365  if (event.getSource() == mStatusBar)
366  {
367  mStatusPopup->view(x + rect.x, y + rect.y);
368  textPopup->hide();
369  }
370  else if (event.getSource() == mXpBar)
371  {
372  std::string level;
373  if ((localPlayer != nullptr) && localPlayer->isGM())
374  {
375  // TRANSLATORS: status bar label
376  level = strprintf(_("Level: %d (GM %d)"),
379  }
380  else
381  {
382  // TRANSLATORS: status bar label
383  level = strprintf(_("Level: %d"),
385  }
386 
388  const int64_t expNeed = PlayerInfo::getAttribute64(
390  const std::string str = toString(CAST_U64(exp)) +
391  "/" +
392  toString(CAST_U64(expNeed));
393  if (exp > expNeed)
394  {
395  textPopup->show(x + rect.x,
396  y + rect.y,
397  level,
398  str);
399  }
400  else
401  {
402  const std::string str2 = toString(CAST_U64(expNeed - exp));
403  textPopup->show(x + rect.x,
404  y + rect.y,
405  level,
406  str,
407  // TRANSLATORS: status bar label
408  strprintf("%s: %s", _("Need"), str2.c_str()));
409  }
410  mStatusPopup->hide();
411  }
412  else if (event.getSource() == mHpBar)
413  {
414  textPopup->show(x + rect.x, y + rect.y, event.getSource()->getId(),
417  mStatusPopup->hide();
418  }
419  else if (event.getSource() == mMpBar)
420  {
421  textPopup->show(x + rect.x, y + rect.y, event.getSource()->getId(),
424  mStatusPopup->hide();
425  }
426  else if (event.getSource() == mJobBar)
427  {
428  const int64_t exp = PlayerInfo::getAttribute64(
430  const int64_t expNeed = PlayerInfo::getAttribute64(
432  const int32_t jobLevel = PlayerInfo::getAttribute(
434  const std::string expStr = toString(CAST_U64(exp));
435  const std::string expNeedStr = toString(CAST_U64(expNeed));
436 
437  // TRANSLATORS: job bar label
438  const std::string level = strprintf(_("Job level: %d"),
439  jobLevel);
440 
441  if (exp > expNeed)
442  {
443  textPopup->show(x + rect.x,
444  y + rect.y,
445  level,
446  strprintf("%s/%s", expStr.c_str(), expNeedStr.c_str()));
447  }
448  else
449  {
450  const std::string expLeftStr = toString(CAST_U64(expNeed - exp));
451  textPopup->show(x + rect.x,
452  y + rect.y,
453  level,
454  strprintf("%s/%s", expStr.c_str(), expNeedStr.c_str()),
455  // TRANSLATORS: status bar label
456  strprintf("%s: %s", _("Need"), expLeftStr.c_str()));
457  }
458  mStatusPopup->hide();
459  }
460  else if (event.getSource() == mWeightBar)
461  {
462  textPopup->show(x + rect.x, y + rect.y, event.getSource()->getId(),
466  mStatusPopup->hide();
467  }
468  else if (event.getSource() == mInvSlotsBar)
469  {
470  const Inventory *const inv = PlayerInfo::getInventory();
471  if (inv != nullptr)
472  {
473  const int usedSlots = inv->getNumberOfSlotsUsed();
474  const int maxSlots = inv->getSize();
475  textPopup->show(x + rect.x, y + rect.y,
476  event.getSource()->getId(),
477  strprintf("%d/%d", usedSlots, maxSlots));
478  }
479  mStatusPopup->hide();
480  }
481  else if (event.getSource() == mMoneyBar)
482  {
483  textPopup->show(x + rect.x, y + rect.y,
484  event.getSource()->getId(),
486  }
487  else
488  {
489  textPopup->hide();
490  mStatusPopup->hide();
491  }
492 }
493 
495 {
496  if (event.getButton() == MouseButton::RIGHT)
497  {
498  const ProgressBar *const bar = dynamic_cast<ProgressBar*>(
499  event.getSource());
500  if (bar == nullptr)
501  return;
502  event.consume();
503  if (popupManager != nullptr)
504  {
505  popupMenu->showPopup(getX() + event.getX(),
506  getY() + event.getY(), bar);
507  }
508  }
509 }
510 
512 {
513  Window::mouseExited(event);
514 
515  textPopup->hide();
516  mStatusPopup->hide();
517 }
518 
519 void MiniStatusWindow::showBar(const std::string &name,
520  const Visible visible)
521 {
522  ProgressBar *const bar = mBarNames[name];
523  if (bar == nullptr)
524  return;
525  bar->setVisible(visible);
526  updateBars();
527  saveBars();
528 }
529 
531 {
532  if (config.getIntValue("ministatussaved") == 0)
533  {
534  if (mWeightBar != nullptr)
536  if (mInvSlotsBar != nullptr)
538  if (mMoneyBar != nullptr)
540  if (mArrowsBar != nullptr)
542  if (mStatusBar != nullptr)
544  if (mJobBar != nullptr)
546  return;
547  }
548 
549  for (int f = 0; f < 10; f ++)
550  {
551  const std::string str = config.getValue(
552  "ministatus" + toString(f), "");
553  if (str.empty())
554  continue;
555  ProgressBar *const bar = mBarNames[str];
556  if (bar == nullptr)
557  continue;
559  }
560 }
561 
563 {
564  int i = 0;
566  {
567  const ProgressBar *const bar = *it;
568  if (bar->mVisible == Visible_false)
569  {
570  config.setValue("ministatus" + toString(i),
571  bar->getActionEventId());
572  i ++;
573  }
574  }
575  for (int f = i; f < 10; f ++)
576  config.deleteKey("ministatus" + toString(f));
577 
578  config.setValue("ministatussaved", true);
579 }
580 
581 void MiniStatusWindow::slotsChanged(const Inventory *const inventory)
582 {
583  if (inventory == nullptr)
584  return;
585 
586  if (inventory->getType() == InventoryType::Inventory)
588 }
589 
591 {
592  const int padding = mPadding;
593  const int padding2 = padding * 2;
594  const Rect &rect = mDimension;
595  return Rect(padding, padding,
596  rect.width - padding2,
597  rect.height - padding2);
598 }
599 
601 {
603 }
604 
605 #ifdef USE_PROFILER
607 {
608  BLOCK_START("MiniStatusWindow::logicChildren")
611 }
612 #endif // USE_PROFILER
Attributes ::T AttributesT
Definition: attributes.h:118
#define CAST_S32
Definition: cast.h:30
#define CAST_U32
Definition: cast.h:31
#define CAST_U64
Definition: cast.h:33
int getWidth() const
void draw(Graphics *const graphics, const int posX, const int posY) const
bool update(const int time)
virtual void add(Widget *const widget)
virtual void safeDrawChildren(Graphics *const graphics)
virtual void logicChildren()
virtual void remove(Widget *const widget)
virtual void drawChildren(Graphics *const graphics)
int getGroupId() const
Definition: being.h:1087
bool isGM() const
Definition: being.h:659
std::string getValue(const std::string &key, const std::string &deflt) const
bool getValueBool(const std::string &key, const bool deflt) const
void deleteKey(const std::string &key)
void setValue(const std::string &key, const std::string &value)
int getIntValue(const std::string &key) const
Widget * getSource() const
Definition: event.h:104
unsigned getSize() const
Definition: inventory.h:76
InventoryTypeT getType() const
Definition: inventory.h:176
void removeInventoyListener(InventoryListener *const listener)
Definition: inventory.cpp:307
void addInventoyListener(InventoryListener *const listener)
Definition: inventory.cpp:302
int getNumberOfSlotsUsed() const
Definition: inventory.h:164
void mouseMoved(MouseEvent &event)
std::vector< AnimatedSprite * > mIcons
ProgressBar * mMoneyBar
ProgressBar * mHpBar
ProgressBar * mWeightBar
std::map< std::string, ProgressBar * > mBarNames
void mouseExited(MouseEvent &event)
void setIcon(const int index, AnimatedSprite *const sprite)
ProgressBar * mInvSlotsBar
std::vector< ProgressBar * > mBars
void eraseIcon(const int index)
void safeDraw(Graphics *const graphics)
ProgressBar * mMpBar
void draw(Graphics *const graphics)
ProgressBar * mStatusBar
ProgressBar * createBar(const float progress, const int width, const int height, const ThemeColorIdT textColor, const ProgressColorIdT backColor, const std::string &skin, const std::string &skinFill, const std::string &name, const std::string &description)
ProgressBar * mJobBar
void drawIcons(Graphics *const graphics)
void statChanged(const AttributesT id, const int oldVal1, const int oldVal2)
void attributeChanged(const AttributesT id, const int64_t oldVal, const int64_t newVal)
StatusPopup * mStatusPopup
void slotsChanged(const Inventory *const inventory)
ProgressBar * mArrowsBar
void showBar(const std::string &name, const Visible visible)
void mousePressed(MouseEvent &event)
ProgressBar * mXpBar
MouseButtonT getButton() const
Definition: mouseevent.h:116
void showPopup(const int x, const int y, const Being *const being)
Definition: popupmenu.cpp:203
void hide()
Definition: popup.cpp:265
bool isPopupVisible() const
Definition: popup.h:174
void setColor(const Color &color1, const Color &color2)
Definition: rect.h:74
int y
Definition: rect.h:214
int width
Definition: rect.h:219
int x
Definition: rect.h:209
int height
Definition: rect.h:224
void view(const int x, const int y)
void update()
Definition: statuspopup.cpp:89
static void updateArrowsBar(ProgressBar *const bar)
static void updateXPBar(ProgressBar *const bar, const bool percent)
static void updateMoneyBar(ProgressBar *const bar)
void updateMPBar(ProgressBar *bar, const bool showMax) const
void updateStatusBar(ProgressBar *const bar, const bool percent) const
static void updateHPBar(ProgressBar *const bar, const bool showMax)
static void updateJobBar(ProgressBar *const bar, const bool percent)
static void updateWeightBar(ProgressBar *const bar)
static void updateInvSlotsBar(ProgressBar *const bar)
void show(const int x, const int y, const std::string &str1)
Definition: textpopup.h:57
const Color & getThemeColor(const ThemeColorIdT type, const unsigned int alpha) const A_INLINE
Definition: widget2.h:45
void setVisible(Visible visible)
Definition: widget.cpp:225
Rect mDimension
Definition: widget.h:1101
void setId(const std::string &id)
Definition: widget.h:916
void addMouseListener(MouseListener *const mouseListener)
Definition: widget.cpp:292
void setActionEventId(const std::string &actionEventId)
Definition: widget.h:596
int getY() const
Definition: widget.h:288
const std::string & getId() const
Definition: widget.h:919
Visible mVisible
Definition: widget.h:963
void setPosition(const int x, const int y)
Definition: widget.cpp:161
int getX() const
Definition: widget.h:269
int getHeight() const
Definition: widget.h:240
const std::string & getActionEventId() const
Definition: widget.h:605
int getWidth() const
Definition: widget.h:221
Definition: window.h:102
virtual void setVisible(Visible visible)
Definition: window.cpp:778
void setContentSize(int width, int height)
Definition: window.cpp:492
void mouseExited(MouseEvent &event)
Definition: window.cpp:924
void mouseMoved(MouseEvent &event)
Definition: window.cpp:967
int mPadding
Definition: window.h:618
Configuration config
Configuration serverConfig
#define CREATEWIDGETR0(type)
Definition: createwidget.h:39
#define delete2(var)
Definition: delete2.h:25
void delete_all(Container &c)
Definition: dtor.h:56
#define FOR_EACH(type, iter, array)
Definition: foreach.h:25
#define _(s)
Definition: gettext.h:35
PRAGMA45(GCC diagnostic push) PRAGMA45(GCC diagnostic ignored "-Wredundant-decls") PRAGMA45(GCC diagnostic pop) class TestMain
#define restrict
Definition: localconsts.h:165
#define nullptr
Definition: localconsts.h:45
#define A_UNUSED
Definition: localconsts.h:160
LocalPlayer * localPlayer
volatile int tick_time
Definition: timer.cpp:53
MiniStatusWindow * miniStatusWindow
std::vector< ProgressBar * >::const_iterator ProgressBarVectorCIter
const bool Modal_false
Definition: modal.h:30
@ PLAYER_EXP_NEEDED
Definition: attributes.h:37
@ TOTAL_WEIGHT
Definition: attributes.h:39
@ PLAYER_MAX_MP
Definition: attributes.h:35
@ PLAYER_BASE_LEVEL
Definition: attributes.h:31
@ PLAYER_JOB_EXP
Definition: attributes.h:66
@ PLAYER_JOB_LEVEL
Definition: attributes.h:41
@ PLAYER_MAX_HP
Definition: attributes.h:33
@ PLAYER_JOB_EXP_NEEDED
Definition: attributes.h:67
std::string toString(T const &value)
converts any type to a string
Definition: catch.hpp:1774
int64_t getAttribute64(const AttributesT id)
Definition: playerinfo.cpp:94
Inventory * getInventory()
Definition: playerinfo.cpp:195
int32_t getAttribute(const AttributesT id)
Definition: playerinfo.cpp:102
std::map< int, std::string > mIcons
Definition: languagedb.cpp:36
Net::PlayerHandler * playerHandler
Definition: net.cpp:96
#define BLOCK_END(name)
Definition: perfomance.h:80
#define BLOCK_START(name)
Definition: perfomance.h:79
PopupManager * popupManager
PopupMenu * popupMenu
Definition: popupmenu.cpp:103
ProgressColorId ::T ProgressColorIdT
StatusWindow * statusWindow
std::string strprintf(const char *const format,...)
TextPopup * textPopup
Definition: textpopup.cpp:33
ThemeColorId ::T ThemeColorIdT
Definition: themecolorid.h:35
bool Visible
Definition: visible.h:30
const bool Visible_false
Definition: visible.h:30
const bool Visible_true
Definition: visible.h:30