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-2018 The ManaPlus Developers
6  *
7  * This file is part of The ManaPlus Client.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
24 
25 #include "configuration.h"
26 
27 #include "being/localplayer.h"
28 #include "being/playerinfo.h"
29 
30 #include "gui/popupmanager.h"
31 #include "gui/skin.h"
32 
33 #include "gui/popups/popupmenu.h"
34 #include "gui/popups/statuspopup.h"
35 #include "gui/popups/textpopup.h"
36 
38 
41 
42 #include "net/playerhandler.h"
43 
45 
47 
48 #include "utils/delete2.h"
49 #include "utils/dtor.h"
50 #include "utils/foreach.h"
51 #include "utils/gettext.h"
52 
53 #include "debug.h"
54 
56 extern volatile int tick_time;
57 
58 typedef STD_VECTOR <ProgressBar*>::const_iterator ProgressBarVectorCIter;
59 
61  Window("MiniStatus", Modal_false, nullptr, "ministatus.xml"),
64  StatListener(),
67  mBars(),
68  mBarNames(),
69  mIcons(),
70  mHpBar(createBar(0, 100, 0, ThemeColorId::HP_BAR, ProgressColorId::PROG_HP,
71  "hpprogressbar.xml", "hpprogressbar_fill.xml",
72  // TRANSLATORS: status bar name
73  "hp bar", _("health bar"))),
74  mMpBar(createBar(0, 100, 0, playerHandler->canUseMagic()
76  playerHandler->canUseMagic()
78  playerHandler->canUseMagic()
79  ? "mpprogressbar.xml" : "nompprogressbar.xml",
80  playerHandler->canUseMagic()
81  ? "mpprogressbar_fill.xml" : "nompprogressbar_fill.xml",
82  // TRANSLATORS: status bar name
83  "mp bar", _("mana bar"))),
84  mXpBar(createBar(0, 100, 0,
86  "xpprogressbar.xml", "xpprogressbar_fill.xml",
87  // TRANSLATORS: status bar name
88  "xp bar", _("experience bar"))),
89  mJobBar(nullptr),
90  mWeightBar(createBar(0, 140, 0, ThemeColorId::WEIGHT_BAR,
92  "weightprogressbar.xml", "weightprogressbar_fill.xml",
93  // TRANSLATORS: status bar name
94  "weight bar", _("weight bar"))),
95  mInvSlotsBar(createBar(0, 45, 0,
97  "slotsprogressbar.xml", "slotsprogressbar_fill.xml",
98  "inventory slots bar",
99  // TRANSLATORS: status bar name
100  _("inventory slots bar"))),
101  mMoneyBar(createBar(0, 130, 0, ThemeColorId::MONEY_BAR,
103  "moneyprogressbar.xml", "moneyprogressbar_fill.xml",
104  // TRANSLATORS: status bar name
105  "money bar", _("money bar"))),
106  mArrowsBar(createBar(0, 50, 0, ThemeColorId::ARROWS_BAR,
108  "arrowsprogressbar.xml", "arrowsprogressbar_fill.xml",
109  // TRANSLATORS: status bar name
110  "arrows bar", _("arrows bar"))),
111  mStatusBar(createBar(100, (config.getIntValue("fontSize") > 16
112  ? 270 : 180), 0, ThemeColorId::STATUS_BAR,
114  "statusprogressbar.xml", "statusprogressbar_fill.xml",
115  // TRANSLATORS: status bar name
116  "status bar", _("status bar"))),
117  mStatusPopup(CREATEWIDGETR0(StatusPopup)),
118  mSpacing(mSkin != nullptr ? mSkin->getOption("spacing", 3) : 3),
119  mIconPadding(mSkin != nullptr ? mSkin->getOption("iconPadding", 3) : 3),
120  mIconSpacing(mSkin != nullptr ? mSkin->getOption("iconSpacing", 2) : 2),
121  mMaxX(0)
122 {
124  false);
125 
126  if (statusWindow != nullptr)
127  {
129  false);
130  }
131 
132  const bool job = serverConfig.getValueBool("showJob", true);
133 
135  true);
136 
137  if (job)
138  {
139  mJobBar = createBar(0, 100, 0,
142  "jobprogressbar.xml", "jobprogressbar_fill.xml",
143  // TRANSLATORS: status bar name
144  "job bar", _("job bar"));
146  true);
147  }
148 
149  loadBars();
150  updateBars();
151 
153  addMouseListener(this);
154  Inventory *const inv = PlayerInfo::getInventory();
155  if (inv != nullptr)
156  inv->addInventoyListener(this);
157 
160  updateStatus();
161 }
162 
164 {
167  mIcons.clear();
168 
169  Inventory *const inv = PlayerInfo::getInventory();
170  if (inv != nullptr)
171  inv->removeInventoyListener(this);
172 
174  {
175  ProgressBar *bar = *it;
176  if (bar == nullptr)
177  continue;
178  if (bar->mVisible == Visible_false)
179  delete bar;
180  }
181  mBars.clear();
182 }
183 
185  const int width,
186  const int height,
187  const ThemeColorIdT textColor,
188  const ProgressColorIdT backColor,
189  const std::string &restrict skin,
190  const std::string &restrict skinFill,
191  const std::string &restrict name,
192  const std::string &restrict
193  description)
194 {
195  ProgressBar *const bar = new ProgressBar(this,
196  progress, width, height, backColor, skin, skinFill);
197  bar->setActionEventId(name);
198  bar->setId(description);
199  bar->setColor(getThemeColor(textColor, 255U),
200  getThemeColor(textColor + 1, 255U));
201  mBars.push_back(bar);
202  mBarNames[name] = bar;
203  return bar;
204 }
205 
207 {
208  int x = 0;
209  const ProgressBar *lastBar = nullptr;
211  remove(*it);
212 
214  {
215  ProgressBar *const bar = *it;
216  if (bar == nullptr)
217  continue;
218  if (bar->mVisible == Visible_true)
219  {
220  bar->setPosition(x, 0);
221  add(bar);
222  x += bar->getWidth() + mSpacing;
223  lastBar = bar;
224  }
225  }
226 
227  if (lastBar != nullptr)
228  {
229  setContentSize(lastBar->getX() + lastBar->getWidth(),
230  lastBar->getY() + lastBar->getHeight());
231  }
232  mMaxX = x;
233 }
234 
235 void MiniStatusWindow::setIcon(const int index, AnimatedSprite *const sprite)
236 {
237  if (index >= CAST_S32(mIcons.size()))
238  mIcons.resize(index + 1, nullptr);
239 
240  delete mIcons[index];
241  mIcons[index] = sprite;
242 }
243 
244 void MiniStatusWindow::eraseIcon(const int index)
245 {
246  if (index < CAST_S32(mIcons.size()))
247  {
248  delete mIcons[index];
249  mIcons.erase(mIcons.begin() + index);
250  }
251 }
252 
254 {
255  // Draw icons
256  int icon_x = mMaxX + mIconPadding;
257  for (size_t i = 0, sz = mIcons.size(); i < sz; i ++)
258  {
259  const AnimatedSprite *const icon = mIcons[i];
260  if (icon != nullptr)
261  {
262  icon->draw(graphics, icon_x, mIconPadding);
263  icon_x += mIconSpacing + icon->getWidth();
264  }
265  }
266 }
267 
269  const int oldVal1 A_UNUSED,
270  const int oldVal2 A_UNUSED)
271 {
272  if (statusWindow != nullptr)
273  {
275  false);
276  }
278  true);
279 }
280 
282  const int64_t oldVal A_UNUSED,
283  const int64_t newVal A_UNUSED)
284 {
285  PRAGMA45(GCC diagnostic push)
286  PRAGMA45(GCC diagnostic ignored "-Wswitch-enum")
287  switch (id)
288  {
292  false);
293  break;
297  false);
298  break;
302  true);
303  break;
307  break;
308  case Attributes::MONEY:
310  break;
311  default:
312  break;
313  }
314  PRAGMA45(GCC diagnostic pop)
315 }
316 
318 {
319  if (statusWindow != nullptr)
320  {
322  true);
323  }
324  if ((mStatusPopup != nullptr) && mStatusPopup->isPopupVisible())
325  mStatusPopup->update();
326 }
327 
329 {
330  BLOCK_START("MiniStatusWindow::logic")
331  Window::logic();
332 
333  for (size_t i = 0, sz = mIcons.size(); i < sz; i++)
334  {
335  AnimatedSprite *const icon = mIcons[i];
336  if (icon != nullptr)
337  icon->update(tick_time * 10);
338  }
339  BLOCK_END("MiniStatusWindow::logic")
340 }
341 
342 void MiniStatusWindow::draw(Graphics *const graphics)
343 {
344  BLOCK_START("MiniStatusWindow::draw")
345  drawChildren(graphics);
346  BLOCK_END("MiniStatusWindow::draw")
347 }
348 
350 {
351  BLOCK_START("MiniStatusWindow::draw")
352  safeDrawChildren(graphics);
353  BLOCK_END("MiniStatusWindow::draw")
354 }
355 
357 {
358  Window::mouseMoved(event);
359 
360  const int x = event.getX();
361  const int y = event.getY();
362 
363  const Rect &rect = mDimension;
364  if (event.getSource() == mStatusBar)
365  {
366  mStatusPopup->view(x + rect.x, y + rect.y);
367  textPopup->hide();
368  }
369  else if (event.getSource() == mXpBar)
370  {
371  std::string level;
372  if ((localPlayer != nullptr) && localPlayer->isGM())
373  {
374  // TRANSLATORS: status bar label
375  level = strprintf(_("Level: %d (GM %d)"),
378  }
379  else
380  {
381  // TRANSLATORS: status bar label
382  level = strprintf(_("Level: %d"),
384  }
385 
387  const int64_t expNeed = PlayerInfo::getAttribute64(
389  const std::string str = toString(CAST_U64(exp)) +
390  "/" +
391  toString(CAST_U64(expNeed));
392  if (exp > expNeed)
393  {
394  textPopup->show(x + rect.x,
395  y + rect.y,
396  level,
397  str);
398  }
399  else
400  {
401  const std::string str2 = toString(CAST_U64(expNeed - exp));
402  textPopup->show(x + rect.x,
403  y + rect.y,
404  level,
405  str,
406  // TRANSLATORS: status bar label
407  strprintf("%s: %s", _("Need"), str2.c_str()));
408  }
409  mStatusPopup->hide();
410  }
411  else if (event.getSource() == mHpBar)
412  {
413  textPopup->show(x + rect.x, y + rect.y, event.getSource()->getId(),
416  mStatusPopup->hide();
417  }
418  else if (event.getSource() == mMpBar)
419  {
420  textPopup->show(x + rect.x, y + rect.y, event.getSource()->getId(),
423  mStatusPopup->hide();
424  }
425  else if (event.getSource() == mJobBar)
426  {
427  const int64_t exp = PlayerInfo::getAttribute64(
429  const int64_t expNeed = PlayerInfo::getAttribute64(
431  const int32_t jobLevel = PlayerInfo::getAttribute(
433  const std::string expStr = toString(CAST_U64(exp));
434  const std::string expNeedStr = toString(CAST_U64(expNeed));
435  const std::string expLeftStr = toString(CAST_U64(expNeed - exp));
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  textPopup->show(x + rect.x,
451  y + rect.y,
452  level,
453  strprintf("%s/%s", expStr.c_str(), expNeedStr.c_str()),
454  // TRANSLATORS: status bar label
455  strprintf("%s: %s", _("Need"), expLeftStr.c_str()));
456  }
457  mStatusPopup->hide();
458  }
459  else if (event.getSource() == mWeightBar)
460  {
461  textPopup->show(x + rect.x, y + rect.y, event.getSource()->getId(),
465  mStatusPopup->hide();
466  }
467  else if (event.getSource() == mInvSlotsBar)
468  {
469  const Inventory *const inv = PlayerInfo::getInventory();
470  if (inv != nullptr)
471  {
472  const int usedSlots = inv->getNumberOfSlotsUsed();
473  const int maxSlots = inv->getSize();
474  textPopup->show(x + rect.x, y + rect.y,
475  event.getSource()->getId(),
476  strprintf("%d/%d", usedSlots, maxSlots));
477  }
478  mStatusPopup->hide();
479  }
480  else if (event.getSource() == mMoneyBar)
481  {
482  textPopup->show(x + rect.x, y + rect.y,
483  event.getSource()->getId(),
485  }
486  else
487  {
488  textPopup->hide();
489  mStatusPopup->hide();
490  }
491 }
492 
494 {
495  if (event.getButton() == MouseButton::RIGHT)
496  {
497  const ProgressBar *const bar = dynamic_cast<ProgressBar*>(
498  event.getSource());
499  if (bar == nullptr)
500  return;
501  event.consume();
502  if (popupManager != nullptr)
503  {
504  popupMenu->showPopup(getX() + event.getX(),
505  getY() + event.getY(), bar);
506  }
507  }
508 }
509 
511 {
512  Window::mouseExited(event);
513 
514  textPopup->hide();
515  mStatusPopup->hide();
516 }
517 
518 void MiniStatusWindow::showBar(const std::string &name,
519  const Visible visible)
520 {
521  ProgressBar *const bar = mBarNames[name];
522  if (bar == nullptr)
523  return;
524  bar->setVisible(visible);
525  updateBars();
526  saveBars();
527 }
528 
530 {
531  if (config.getIntValue("ministatussaved") == 0)
532  {
533  if (mWeightBar != nullptr)
535  if (mInvSlotsBar != nullptr)
537  if (mMoneyBar != nullptr)
539  if (mArrowsBar != nullptr)
541  if (mStatusBar != nullptr)
543  if (mJobBar != nullptr)
545  return;
546  }
547 
548  for (int f = 0; f < 10; f ++)
549  {
550  const std::string str = config.getValue(
551  "ministatus" + toString(f), "");
552  if (str.empty())
553  continue;
554  ProgressBar *const bar = mBarNames[str];
555  if (bar == nullptr)
556  continue;
558  }
559 }
560 
562 {
563  int i = 0;
565  {
566  const ProgressBar *const bar = *it;
567  if (bar->mVisible == Visible_false)
568  {
569  config.setValue("ministatus" + toString(i),
570  bar->getActionEventId());
571  i ++;
572  }
573  }
574  for (int f = i; f < 10; f ++)
575  config.deleteKey("ministatus" + toString(f));
576 
577  config.setValue("ministatussaved", true);
578 }
579 
580 void MiniStatusWindow::slotsChanged(const Inventory *const inventory)
581 {
582  if (inventory == nullptr)
583  return;
584 
585  if (inventory->getType() == InventoryType::Inventory)
587 }
588 
590 {
591  const int padding = mPadding;
592  const int padding2 = padding * 2;
593  const Rect &rect = mDimension;
594  return Rect(padding, padding,
595  rect.width - padding2,
596  rect.height - padding2);
597 }
598 
600 {
602 }
603 
604 #ifdef USE_PROFILER
606 {
607  BLOCK_START("MiniStatusWindow::logicChildren")
609  BLOCK_END("MiniStatusWindow::logicChildren")
610 }
611 #endif // USE_PROFILER
Net::PlayerHandler * playerHandler
Definition: net.cpp:89
#define FOR_EACH(type, iter, array)
Definition: foreach.h:24
ProgressColorId ::T ProgressColorIdT
void show(const int x, const int y, const std::string &str1)
Definition: textpopup.h:56
#define _(s)
Definition: gettext.h:34
int width
Definition: rect.h:218
void statChanged(const AttributesT id, const int oldVal1, const int oldVal2)
int getWidth() const
Definition: widget.h:220
std::map< std::string, ProgressBar * > mBarNames
int getNumberOfSlotsUsed() const
Definition: inventory.h:163
volatile int tick_time
Definition: timer.cpp:52
int mPadding
Definition: window.h:617
ProgressBar * mMoneyBar
const bool Visible_true
Definition: visible.h:29
static void updateWeightBar(ProgressBar *const bar)
PRAGMA45(GCC diagnostic push) PRAGMA45(GCC diagnostic ignored "-Wunused-result") int TestLauncher
int getY() const
Definition: widget.h:287
void safeDraw(Graphics *const graphics)
void setVisible(Visible visible)
Definition: widget.cpp:224
ProgressBar * mStatusBar
MouseButtonT getButton() const
Definition: mouseevent.h:115
Definition: rect.h:72
#define CAST_U64
Definition: cast.h:32
Inventory * getInventory()
Definition: playerinfo.cpp:192
Definition: window.h:98
#define BLOCK_START(name)
Definition: perfomance.h:78
static void updateInvSlotsBar(ProgressBar *const bar)
Configuration config
void draw(Graphics *const graphics, const int posX, const int posY) const
static void updateArrowsBar(ProgressBar *const bar)
PopupManager * popupManager
void mouseMoved(MouseEvent &event)
Definition: window.cpp:962
void mouseMoved(MouseEvent &event)
StatusWindow * statusWindow
void attributeChanged(const AttributesT id, const int64_t oldVal, const int64_t newVal)
#define BLOCK_END(name)
Definition: perfomance.h:79
int getIntValue(const std::string &key) const
void drawIcons(Graphics *const graphics)
const std::string & getActionEventId() const
Definition: widget.h:604
bool isPopupVisible() const
Definition: popup.h:173
void setActionEventId(const std::string &actionEventId)
Definition: widget.h:595
void view(const int x, const int y)
#define delete2(var)
Definition: delete2.h:24
Configuration serverConfig
ProgressBar * mWeightBar
int64_t getAttribute64(const AttributesT id)
Definition: playerinfo.cpp:92
Visible mVisible
Definition: widget.h:962
void updateStatusBar(ProgressBar *const bar, const bool percent) const
ThemeColorId ::T ThemeColorIdT
Definition: themecolorid.h:256
void setContentSize(int width, int height)
Definition: window.cpp:491
int x
Definition: rect.h:208
MiniStatusWindow * miniStatusWindow
void hide()
Definition: popup.cpp:262
const std::string & getId() const
Definition: widget.h:918
void mousePressed(MouseEvent &event)
void updateMPBar(ProgressBar *bar, const bool showMax) const
#define CAST_S32
Definition: cast.h:29
std::string strprintf(const char *const format,...)
Definition: stringutils.cpp:99
void delete_all(Container &c)
Definition: dtor.h:55
const bool Visible_false
Definition: visible.h:29
static void updateHPBar(ProgressBar *const bar, const bool showMax)
void eraseIcon(const int index)
Widget * getSource() const
Definition: event.h:103
int y
Definition: rect.h:213
LocalPlayer * localPlayer
PopupMenu * popupMenu
Definition: popupmenu.cpp:102
virtual void logicChildren()
static void updateMoneyBar(ProgressBar *const bar)
void mouseExited(MouseEvent &event)
virtual void add(Widget *const widget)
#define nullptr
Definition: localconsts.h:44
bool getValueBool(const std::string &key, const bool deflt) const
std::map< int, std::string > mIcons
Definition: languagedb.cpp:35
StatusPopup * mStatusPopup
void addMouseListener(MouseListener *const mouseListener)
Definition: widget.cpp:291
ProgressBar * mArrowsBar
void setPosition(const int x, const int y)
Definition: widget.cpp:160
int height
Definition: rect.h:223
int getGroupId() const
Definition: being.h:1083
void showBar(const std::string &name, const Visible visible)
ProgressBar * mInvSlotsBar
int getX() const
Definition: widget.h:268
std::string toString(T const &value)
converts any type to a string
Definition: catch.hpp:1774
std::string getValue(const std::string &key, const std::string &deflt) const
#define A_UNUSED
Definition: localconsts.h:171
virtual void setVisible(Visible visible)
Definition: window.cpp:773
void setId(const std::string &id)
Definition: widget.h:915
int getWidth() const
void draw(Graphics *const graphics)
virtual void drawChildren(Graphics *const graphics)
ProgressBar * mHpBar
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 * mXpBar
Attributes ::T AttributesT
Definition: attributes.h:117
void update()
Definition: statuspopup.cpp:89
void deleteKey(const std::string &key)
int getHeight() const
Definition: widget.h:239
void mouseExited(MouseEvent &event)
Definition: window.cpp:919
#define restrict
Definition: localconsts.h:176
std::vector< AnimatedSprite * > mIcons
const Color & getThemeColor(const ThemeColorIdT type, const unsigned int alpha) const A_INLINE
Definition: widget2.h:44
int getX() const
Definition: mouseevent.h:126
void addInventoyListener(InventoryListener *const listener)
Definition: inventory.cpp:301
void slotsChanged(const Inventory *const inventory)
std::vector< ProgressBar * > mBars
static void updateXPBar(ProgressBar *const bar, const bool percent)
static void updateJobBar(ProgressBar *const bar, const bool percent)
bool update(const int time)
ProgressBar * mJobBar
ProgressBar * mMpBar
int32_t getAttribute(const AttributesT id)
Definition: playerinfo.cpp:100
Rect mDimension
Definition: widget.h:1100
void setColor(const Color &color1, const Color &color2)
InventoryTypeT getType() const
Definition: inventory.h:175
virtual void safeDrawChildren(Graphics *const graphics)
void setValue(const std::string &key, const std::string &value)
std::vector< ProgressBar * >::const_iterator ProgressBarVectorCIter
void setIcon(const int index, AnimatedSprite *const sprite)
void showPopup(const int x, const int y, const Being *const being)
Definition: popupmenu.cpp:202
bool isGM() const
Definition: being.h:652
TextPopup * textPopup
Definition: textpopup.cpp:32
unsigned getSize() const
Definition: inventory.h:75
void removeInventoyListener(InventoryListener *const listener)
Definition: inventory.cpp:306
#define CREATEWIDGETR0(type)
Definition: createwidget.h:38