ManaPlus
itempopup.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2008 The Legend of Mazzeroth Development Team
4  * Copyright (C) 2008-2009 The Mana World Development Team
5  * Copyright (C) 2009-2010 The Mana Developers
6  * Copyright (C) 2011-2018 The ManaPlus Developers
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 
24 #include "gui/popups/itempopup.h"
25 
26 #include "actormanager.h"
27 #include "configuration.h"
28 
29 #include "gui/gui.h"
30 
31 #include "gui/fonts/font.h"
32 
33 #include "gui/widgets/icon.h"
34 #include "gui/widgets/label.h"
35 #include "gui/widgets/textbox.h"
36 
37 #include "net/beinghandler.h"
38 #ifdef TMWA_SUPPORT
39 #include "net/net.h"
40 #endif // TMWA_SUPPORT
41 
42 #include "utils/foreach.h"
43 #include "utils/gettext.h"
44 #include "utils/stdmove.h"
45 
47 
48 #include "resources/iteminfo.h"
49 
51 #include "resources/db/unitsdb.h"
52 
53 #include "resources/image/image.h"
54 
55 #include "resources/item/item.h"
58 
60 
61 #include "debug.h"
62 
63 ItemPopup *itemPopup = nullptr;
64 
66  Popup("ItemPopup", "itempopup.xml"),
67  mItemName(new Label(this)),
68  mItemDesc(new TextBox(this)),
69  mItemEffect(new TextBox(this)),
70  mItemWeight(new TextBox(this)),
71  mItemCards(new TextBox(this)),
72  mItemOptions(new TextBox(this)),
73  mItemType(ItemDbType::UNUSABLE),
75  mLastName(),
76  mCardsStr(),
77  mItemOptionsStr(),
78  mLastId(0),
79  mLastColor(ItemColor_one)
80 {
81  // Item name
83  mItemName->setPosition(0, 0);
84 
85  const int fontHeight = getFont()->getHeight();
86 
87  // Item description
88  mItemDesc->setEditable(false);
89  mItemDesc->setPosition(0, fontHeight);
93 
94  // Item effect
95  mItemEffect->setEditable(false);
96  mItemEffect->setPosition(0, 2 * fontHeight);
100 
101  // Item weight
102  mItemWeight->setEditable(false);
103  mItemWeight->setPosition(0, 3 * fontHeight);
107 
108  // Item cards
109  mItemCards->setEditable(false);
110  mItemCards->setPosition(0, 4 * fontHeight);
114 
115  // Item options
116  mItemOptions->setEditable(false);
117  mItemOptions->setPosition(0, 5 * fontHeight);
121 }
122 
124 {
125  Popup::postInit();
126  add(mItemName);
127  add(mItemDesc);
128  add(mItemEffect);
129  add(mItemWeight);
130  add(mItemCards);
131  add(mItemOptions);
132  add(mIcon);
133 
134  addMouseListener(this);
135 }
136 
138 {
139  if (mIcon != nullptr)
140  {
141  Image *const image = mIcon->getImage();
142  if (image != nullptr)
143  image->decRef();
144  }
145 }
146 
147 void ItemPopup::setItem(const Item *const item,
148  const bool showImage)
149 {
150  if (item == nullptr)
151  return;
152 
153  const ItemInfo &ii = item->getInfo();
154  setItem(ii,
155  item->getColor(),
156  showImage,
157  item->getId(),
158  item->getCards(),
159  item->getOptions());
160  if (item->getRefine() > 0)
161  {
162  mLastName = ii.getName();
163  mLastColor = item->getColor();
164  mLastId = item->getId();
165 #ifdef TMWA_SUPPORT
167  {
168  mItemName->setCaption(strprintf("%s (+%u), %d",
169  ii.getName().c_str(),
170  CAST_U32(item->getRefine()),
171  ii.getId()));
172  }
173  else
174 #endif // TMWA_SUPPORT
175  {
176  mItemName->setCaption(strprintf("%s (+%u), %d",
177  ii.getName(item->getColor()).c_str(),
178  CAST_U32(item->getRefine()),
179  ii.getId()));
180  }
182  const unsigned minWidth = mItemName->getWidth() + 8;
183  if (CAST_U32(getWidth()) < minWidth)
184  setWidth(minWidth);
185  }
186 }
187 
189  const ItemColor color,
190  const bool showImage,
191  int id,
192  const int *const cards,
193  const ItemOptionsList *const options)
194 {
195  if (mIcon == nullptr)
196  return;
197 
198  std::string cardsStr;
199  std::string optionsStr;
200 
201  if (item.getName() == mLastName &&
202  color == mLastColor &&
203  id == mLastId)
204  {
205  cardsStr = getCardsString(cards);
206  optionsStr = getOptionsString(options);
207  if (mItemOptionsStr == optionsStr &&
208  mCardsStr == cardsStr)
209  {
210  return;
211  }
212  }
213  else
214  {
215  cardsStr = getCardsString(cards);
216  optionsStr = getOptionsString(options);
217  }
218  mItemOptionsStr = STD_MOVE(optionsStr);
219  mCardsStr = STD_MOVE(cardsStr);
220 
221  if (id == -1)
222  id = item.getId();
223 
224  int space = 0;
225 
226  Image *const oldImage = mIcon->getImage();
227  if (oldImage != nullptr)
228  oldImage->decRef();
229 
230  if (showImage)
231  {
232  Image *const image = Loader::getImage(combineDye2(
233  pathJoin(paths.getStringValue("itemIcons"),
234  item.getDisplay().image),
235  item.getDyeIconColorsString(color)));
236 
237  mIcon->setImage(image);
238  if (image != nullptr)
239  {
240  mIcon->setPosition(0, 0);
241  space = mIcon->getWidth();
242  }
243  }
244  else
245  {
246  mIcon->setImage(nullptr);
247  }
248 
249  mItemType = item.getType();
250 
251  mLastName = item.getName();
252  mLastColor = color;
253  mLastId = id;
254 
255 #ifdef TMWA_SUPPORT
257  {
258  mItemName->setCaption(strprintf("%s, %d",
259  item.getName().c_str(), id));
261  }
262  else
263 #endif // TMWA_SUPPORT
264  {
265  mItemName->setCaption(strprintf("%s, %d",
266  item.getName(color).c_str(), id));
267  mItemDesc->setTextWrapped(item.getDescription(color), 196);
268  }
269 
272  mItemName->setPosition(space, 0);
273 
274  mItemEffect->setTextWrapped(item.getEffect(), 196);
275  // TRANSLATORS: popup label
276  mItemWeight->setTextWrapped(strprintf(_("Weight: %s"),
277  UnitsDb::formatWeight(item.getWeight()).c_str()), 196);
280 
281  int minWidth = mItemName->getWidth() + space;
282 
283  if (mItemName->getWidth() + space > minWidth)
284  minWidth = mItemName->getWidth() + space;
285  if (mItemDesc->getMinWidth() > minWidth)
286  minWidth = mItemDesc->getMinWidth();
287  if (mItemEffect->getMinWidth() > minWidth)
288  minWidth = mItemEffect->getMinWidth();
289  if (mItemWeight->getMinWidth() > minWidth)
290  minWidth = mItemWeight->getMinWidth();
291  if (mItemCards->getMinWidth() > minWidth)
292  minWidth = mItemCards->getMinWidth();
293  if (mItemOptions->getMinWidth() > minWidth)
294  minWidth = mItemOptions->getMinWidth();
295 
296  const int numRowsDesc = mItemDesc->getNumberOfRows();
297  const int numRowsEffect = mItemEffect->getNumberOfRows();
298  const int numRowsWeight = mItemWeight->getNumberOfRows();
299  const int numRowsCards = mItemCards->getNumberOfRows();
300  const int numRowsOptions = mItemOptions->getNumberOfRows();
301  const int height = getFont()->getHeight();
302 
303  if (item.getEffect().empty())
304  {
305  setContentSize(minWidth,
306  (numRowsDesc + 2 + numRowsWeight + numRowsCards + numRowsOptions) *
307  height);
308  mItemWeight->setPosition(0, (numRowsDesc + 2) * height);
309  mItemCards->setPosition(0, (numRowsDesc + numRowsWeight + 2) * height);
311  (numRowsDesc + numRowsWeight + numRowsCards + 2) * height);
312  }
313  else
314  {
315  setContentSize(minWidth, (numRowsDesc + numRowsEffect + 2
316  + numRowsWeight + numRowsCards + numRowsOptions) * height);
317  mItemEffect->setPosition(0, (numRowsDesc + 2) * height);
318  mItemWeight->setPosition(0, (numRowsDesc + numRowsEffect + 2)
319  * height);
320  mItemCards->setPosition(0, (numRowsDesc + numRowsEffect
321  + numRowsWeight + 2) * height);
322  mItemOptions->setPosition(0, (numRowsDesc + numRowsEffect
323  + numRowsWeight + numRowsCards + 2) * height);
324  }
325 
326  mItemDesc->setPosition(0, 2 * height);
327 }
328 
329 std::string ItemPopup::getCardsString(const int *const cards)
330 {
331  if (cards == nullptr)
332  return std::string();
333 
334  std::string label;
335 
336  switch (cards[0])
337  {
338  case 0xfe: // named item
339  {
340  const int32_t charId = cards[2] + 65536 * cards[3];
341  std::string name = actorManager->findCharById(charId);
342  if (name.empty())
343  {
344  name = toString(charId);
346  mLastId = 0; // allow recreate popup with same data
347  }
348  // TRANSLATORS: named item description
349  label.append(strprintf(_("Item named: %s"), name.c_str()));
350  return label;
351  }
352  case 0x00FFU: // forged item
353  {
354  return label;
355  }
356  case 0xFF00U:
357  {
358  return label;
359  }
360  default:
361  {
362  for (int f = 0; f < maxCards; f ++)
363  {
364  const int id = cards[f];
365  if (id != 0)
366  {
367  if (!label.empty())
368  label.append(" / ");
369  const ItemInfo &info = ItemDB::get(id);
370  label.append(info.getName());
371  }
372  }
373  if (label.empty())
374  return label;
375  // TRANSLATORS: popup label
376  return _("Cards: ") + label;
377  }
378  }
379 }
380 
381 std::string ItemPopup::getOptionsString(const ItemOptionsList *const options)
382 {
383  if (options == nullptr || translator == nullptr)
384  return std::string();
385  const size_t sz = options->size();
386  std::string effect;
387  for (size_t f = 0; f < sz; f ++)
388  {
389  const ItemOption &option = options->get(f);
390  if (option.index == 0)
391  continue;
392  const STD_VECTOR<ItemFieldType*> &fields = ItemOptionDb::getFields(
393  option.index);
394  if (fields.empty())
395  continue;
396  const std::string valueStr = toString(option.value);
397  FOR_EACH (STD_VECTOR<ItemFieldType*>::const_iterator, it, fields)
398  {
399  const ItemFieldType *const field = *it;
400  std::string value = valueStr;
401  if (!effect.empty())
402  effect.append(" / ");
403  if (field->sign && value[0] != '-')
404  value = std::string("+").append(value);
405  const std::string format = translator->getStr(field->description);
406  effect.append(strprintf(format.c_str(),
407  value.c_str()));
408  }
409  }
410  if (effect.empty())
411  return effect;
412  // TRANSLATORS: popup label
413  return _("Options: ") + effect;
414 }
415 
416 #define caseSetColor(name1, name2) \
417  case name1: \
418  { \
419  return label->setForegroundColorAll( \
420  getThemeColor(name2, 255U), \
421  getThemeColor(name2##_OUTLINE, 255U)); \
422  }
424  const ItemDbTypeT type) const
425 {
426  switch (type)
427  {
447  default:
448  {
449  return label->setForegroundColorAll(
452  }
453  }
454 }
455 #undef caseSetColor
456 
458 {
459  Popup::mouseMoved(event);
460 
461  // When the mouse moved on top of the popup, hide it
463  resetPopup();
464 }
465 
467 {
468  mLastName.clear();
470  mLastId = 0;
471 }
uint8_t getRefine() const
Definition: item.h:140
ItemDbTypeT mItemType
Definition: itempopup.h:89
#define CAST_U32
Definition: cast.h:30
Font * getFont() const
Definition: widget.cpp:330
#define FOR_EACH(type, iter, array)
Definition: foreach.h:24
std::string getStringValue(const std::string &key) const
#define _(s)
Definition: gettext.h:34
const ItemInfo & get(const int id)
Definition: itemdb.cpp:792
const std::string & getEffect() const
Definition: iteminfo.h:108
const ItemOptionsList * getOptions() const
Definition: item.h:218
void setContentSize(int width, int height)
Definition: popup.cpp:154
int getWidth() const
Definition: widget.h:220
Font * boldFont
Definition: gui.cpp:111
unsigned int getNumberOfRows() const
Definition: textbox.h:161
void setWidth(const int width)
Definition: widget.cpp:132
void setTextWrapped(const std::string &text, const int minDimension)
Definition: textbox.cpp:108
TextBox * mItemEffect
Definition: itempopup.h:85
const std::string description
Definition: itemfieldtype.h:41
virtual void requestNameByCharId(const int id) const =0
const std::vector< ItemFieldType * > & getFields(const int id)
int16_t value
Definition: itemoption.h:36
int getId() const
Definition: iteminfo.h:67
void setVisible(Visible visible)
Definition: widget.cpp:224
const ItemOption & get(const size_t index) const
std::string formatWeight(const int value)
Definition: unitsdb.cpp:351
std::string pathJoin(std::string str1, const std::string &str2)
void postInit()
Definition: popup.h:176
const std::string & getDescription() const
Definition: iteminfo.h:99
uint16_t ItemColor
Definition: itemcolor.h:29
const ItemColor ItemColor_one
Definition: itemcolor.h:29
const std::string & getName() const
Definition: iteminfo.h:73
#define new
Definition: debug_new.h:147
size_t size() const
void setEditable(const bool editable)
Definition: textbox.cpp:649
Definition: icon.h:39
std::string strprintf(const char *const format,...)
Definition: stringutils.cpp:99
void setCaption(const std::string &caption)
Definition: label.cpp:261
const bool Visible_false
Definition: visible.h:29
std::string mCardsStr
Definition: itempopup.h:92
Definition: label.h:87
Image * getImage(const std::string &idPath)
Definition: imageloader.cpp:85
bool info(InputEvent &event)
Definition: commands.cpp:56
int mLastId
Definition: itempopup.h:94
void mouseMoved(MouseEvent &event)
Definition: popup.cpp:252
std::string getOptionsString(const ItemOptionsList *const options)
Definition: itempopup.cpp:381
virtual void add(Widget *const widget)
ItemColor getColor() const
Definition: item.h:180
int getMinWidth() const
Definition: textbox.h:107
const int * getCards() const
Definition: item.h:213
Definition: item.h:48
Net::BeingHandler * beingHandler
Definition: net.cpp:95
void setLabelColor(Label *label, const ItemDbTypeT type) const
Definition: itempopup.cpp:423
#define nullptr
Definition: localconsts.h:44
void mouseMoved(MouseEvent &event)
Definition: itempopup.cpp:457
const SpriteDisplay & getDisplay() const
Definition: iteminfo.h:93
void addMouseListener(MouseListener *const mouseListener)
Definition: widget.cpp:291
void setPosition(const int x, const int y)
Definition: widget.cpp:160
const ItemInfo & getInfo() const
Definition: item.h:170
void setItem(const ItemInfo &item, const ItemColor color, const bool showImage, int id, const int *const cards, const ItemOptionsList *const options)
Definition: itempopup.cpp:188
std::string getCardsString(const int *const cards)
Definition: itempopup.cpp:329
Label * mItemName
Definition: itempopup.h:83
std::string getDyeIconColorsString(const ItemColor color) const
Definition: iteminfo.cpp:239
TextBox * mItemCards
Definition: itempopup.h:87
#define STD_MOVE(var)
Definition: stdmove.h:27
TextBox * mItemOptions
Definition: itempopup.h:88
ServerTypeT getNetworkType()
Definition: net.cpp:182
Configuration paths
std::string toString(T const &value)
converts any type to a string
Definition: catch.hpp:1774
void setForegroundColorAll(const Color &color1, const Color &color2)
Definition: textbox.cpp:487
int getWeight() const
Definition: iteminfo.h:132
int getId() const
Definition: item.h:80
void postInit()
Definition: itempopup.cpp:123
std::string findCharById(const int32_t id)
void setImage(Image *const image)
Definition: icon.cpp:73
void setFont(Font *const font)
Definition: widget.cpp:348
const bool AutoRelease_false
Definition: autorelease.h:29
uint16_t index
Definition: itemoption.h:35
std::string mItemOptionsStr
Definition: itempopup.h:93
ItemDbTypeT getType() const
Definition: iteminfo.h:126
Definition: image.h:61
void resetPopup()
Definition: itempopup.cpp:466
Definition: popup.h:48
std::string combineDye2(std::string file, const std::string &dye)
#define caseSetColor(name1, name2)
Definition: itempopup.cpp:416
const Color & getThemeColor(const ThemeColorIdT type, const unsigned int alpha) const A_INLINE
Definition: widget2.h:44
void setForegroundColorAll(const Color &color1, const Color &color2)
Definition: label.cpp:214
int getHeight() const
Definition: font.cpp:360
ItemPopup * itemPopup
Definition: itempopup.cpp:63
const std::string getStr(const std::string &str)
Definition: podict.cpp:44
std::string mLastName
Definition: itempopup.h:91
Icon * mIcon
Definition: itempopup.h:90
PoDict * translator
Definition: podict.cpp:27
void adjustSize()
Definition: label.cpp:197
void decRef()
Definition: image.cpp:522
ItemDbType ::T ItemDbTypeT
Definition: itemdbtype.h:48
TextBox * mItemDesc
Definition: itempopup.h:84
Image * getImage() const
Definition: icon.h:63
#define maxCards
Definition: cards.h:24
ItemColor mLastColor
Definition: itempopup.h:95
ActorManager * actorManager
std::string image
Definition: spritedisplay.h:44
const bool sign
Definition: itemfieldtype.h:42
TextBox * mItemWeight
Definition: itempopup.h:86