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-2017 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),
74  mIcon(new Icon(this, nullptr)),
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);
92 
93  // Item effect
94  mItemEffect->setEditable(false);
95  mItemEffect->setPosition(0, 2 * fontHeight);
98 
99  // Item weight
100  mItemWeight->setEditable(false);
101  mItemWeight->setPosition(0, 3 * fontHeight);
104 
105  // Item cards
106  mItemCards->setEditable(false);
107  mItemCards->setPosition(0, 4 * fontHeight);
110 
111  // Item options
112  mItemOptions->setEditable(false);
113  mItemOptions->setPosition(0, 5 * fontHeight);
116 }
117 
119 {
120  Popup::postInit();
121  add(mItemName);
122  add(mItemDesc);
123  add(mItemEffect);
124  add(mItemWeight);
125  add(mItemCards);
126  add(mItemOptions);
127  add(mIcon);
128 
129  addMouseListener(this);
130 }
131 
133 {
134  if (mIcon != nullptr)
135  {
136  Image *const image = mIcon->getImage();
137  if (image != nullptr)
138  image->decRef();
139  }
140 }
141 
142 void ItemPopup::setItem(const Item *const item,
143  const bool showImage)
144 {
145  if (item == nullptr)
146  return;
147 
148  const ItemInfo &ii = item->getInfo();
149  setItem(ii,
150  item->getColor(),
151  showImage,
152  item->getId(),
153  item->getCards(),
154  item->getOptions());
155  if (item->getRefine() > 0)
156  {
157  mLastName = ii.getName();
158  mLastColor = item->getColor();
159  mLastId = item->getId();
160 #ifdef TMWA_SUPPORT
162  {
163  mItemName->setCaption(strprintf("%s (+%u), %d",
164  ii.getName().c_str(),
165  CAST_U32(item->getRefine()),
166  ii.getId()));
167  }
168  else
169 #endif // TMWA_SUPPORT
170  {
171  mItemName->setCaption(strprintf("%s (+%u), %d",
172  ii.getName(item->getColor()).c_str(),
173  CAST_U32(item->getRefine()),
174  ii.getId()));
175  }
177  const unsigned minWidth = mItemName->getWidth() + 8;
178  if (CAST_U32(getWidth()) < minWidth)
179  setWidth(minWidth);
180  }
181 }
182 
184  const ItemColor color,
185  const bool showImage,
186  int id,
187  const int *const cards,
188  const ItemOptionsList *const options)
189 {
190  if (mIcon == nullptr)
191  return;
192 
193  std::string cardsStr;
194  std::string optionsStr;
195 
196  if (item.getName() == mLastName &&
197  color == mLastColor &&
198  id == mLastId)
199  {
200  cardsStr = getCardsString(cards);
201  optionsStr = getOptionsString(options);
202  if (mItemOptionsStr == optionsStr &&
203  mCardsStr == cardsStr)
204  {
205  return;
206  }
207  }
208  else
209  {
210  cardsStr = getCardsString(cards);
211  optionsStr = getOptionsString(options);
212  }
213  mItemOptionsStr = STD_MOVE(optionsStr);
214  mCardsStr = STD_MOVE(cardsStr);
215 
216  if (id == -1)
217  id = item.getId();
218 
219  int space = 0;
220 
221  Image *const oldImage = mIcon->getImage();
222  if (oldImage != nullptr)
223  oldImage->decRef();
224 
225  if (showImage)
226  {
227  Image *const image = Loader::getImage(combineDye2(
228  pathJoin(paths.getStringValue("itemIcons"),
229  item.getDisplay().image),
230  item.getDyeIconColorsString(color)));
231 
232  mIcon->setImage(image);
233  if (image != nullptr)
234  {
235  mIcon->setPosition(0, 0);
236  space = mIcon->getWidth();
237  }
238  }
239  else
240  {
241  mIcon->setImage(nullptr);
242  }
243 
244  mItemType = item.getType();
245 
246  mLastName = item.getName();
247  mLastColor = color;
248  mLastId = id;
249 
250 #ifdef TMWA_SUPPORT
252  {
253  mItemName->setCaption(strprintf("%s, %d",
254  item.getName().c_str(), id));
256  }
257  else
258 #endif // TMWA_SUPPORT
259  {
260  mItemName->setCaption(strprintf("%s, %d",
261  item.getName(color).c_str(), id));
262  mItemDesc->setTextWrapped(item.getDescription(color), 196);
263  }
264 
267  mItemName->setPosition(space, 0);
268 
269  mItemEffect->setTextWrapped(item.getEffect(), 196);
270  // TRANSLATORS: popup label
271  mItemWeight->setTextWrapped(strprintf(_("Weight: %s"),
272  UnitsDb::formatWeight(item.getWeight()).c_str()), 196);
275 
276  int minWidth = mItemName->getWidth() + space;
277 
278  if (mItemName->getWidth() + space > minWidth)
279  minWidth = mItemName->getWidth() + space;
280  if (mItemDesc->getMinWidth() > minWidth)
281  minWidth = mItemDesc->getMinWidth();
282  if (mItemEffect->getMinWidth() > minWidth)
283  minWidth = mItemEffect->getMinWidth();
284  if (mItemWeight->getMinWidth() > minWidth)
285  minWidth = mItemWeight->getMinWidth();
286  if (mItemCards->getMinWidth() > minWidth)
287  minWidth = mItemCards->getMinWidth();
288  if (mItemOptions->getMinWidth() > minWidth)
289  minWidth = mItemOptions->getMinWidth();
290 
291  const int numRowsDesc = mItemDesc->getNumberOfRows();
292  const int numRowsEffect = mItemEffect->getNumberOfRows();
293  const int numRowsWeight = mItemWeight->getNumberOfRows();
294  const int numRowsCards = mItemCards->getNumberOfRows();
295  const int numRowsOptions = mItemOptions->getNumberOfRows();
296  const int height = getFont()->getHeight();
297 
298  if (item.getEffect().empty())
299  {
300  setContentSize(minWidth,
301  (numRowsDesc + 2 + numRowsWeight + numRowsCards + numRowsOptions) *
302  height);
303  mItemWeight->setPosition(0, (numRowsDesc + 2) * height);
304  mItemCards->setPosition(0, (numRowsDesc + numRowsWeight + 2) * height);
306  (numRowsDesc + numRowsWeight + numRowsCards + 2) * height);
307  }
308  else
309  {
310  setContentSize(minWidth, (numRowsDesc + numRowsEffect + 2
311  + numRowsWeight + numRowsCards + numRowsOptions) * height);
312  mItemEffect->setPosition(0, (numRowsDesc + 2) * height);
313  mItemWeight->setPosition(0, (numRowsDesc + numRowsEffect + 2)
314  * height);
315  mItemCards->setPosition(0, (numRowsDesc + numRowsEffect
316  + numRowsWeight + 2) * height);
317  mItemOptions->setPosition(0, (numRowsDesc + numRowsEffect
318  + numRowsWeight + numRowsCards + 2) * height);
319  }
320 
321  mItemDesc->setPosition(0, 2 * height);
322 }
323 
324 std::string ItemPopup::getCardsString(const int *const cards)
325 {
326  if (cards == nullptr)
327  return std::string();
328 
329  std::string label;
330 
331  switch (cards[0])
332  {
333  case 0xfe: // named item
334  {
335  const int32_t charId = cards[2] + 65536 * cards[3];
336  std::string name = actorManager->findCharById(charId);
337  if (name.empty())
338  {
339  name = toString(charId);
341  mLastId = 0; // allow recreate popup with same data
342  }
343  // TRANSLATORS: named item description
344  label.append(strprintf(_("Item named: %s"), name.c_str()));
345  return label;
346  }
347  case 0x00FFU: // forged item
348  {
349  return label;
350  }
351  case 0xFF00U:
352  {
353  return label;
354  }
355  default:
356  {
357  for (int f = 0; f < maxCards; f ++)
358  {
359  const int id = cards[f];
360  if (id != 0)
361  {
362  if (!label.empty())
363  label.append(" / ");
364  const ItemInfo &info = ItemDB::get(id);
365  label.append(info.getName());
366  }
367  }
368  if (label.empty())
369  return label;
370  // TRANSLATORS: popup label
371  return _("Cards: ") + label;
372  }
373  }
374 }
375 
376 std::string ItemPopup::getOptionsString(const ItemOptionsList *const options)
377 {
378  if (options == nullptr || translator == nullptr)
379  return std::string();
380  const size_t sz = options->size();
381  std::string effect;
382  for (size_t f = 0; f < sz; f ++)
383  {
384  const ItemOption &option = options->get(f);
385  if (option.index == 0)
386  continue;
387  const STD_VECTOR<ItemFieldType*> &fields = ItemOptionDb::getFields(
388  option.index);
389  if (fields.empty())
390  continue;
391  const std::string valueStr = toString(option.value);
392  FOR_EACH (STD_VECTOR<ItemFieldType*>::const_iterator, it, fields)
393  {
394  const ItemFieldType *const field = *it;
395  std::string value = valueStr;
396  if (!effect.empty())
397  effect.append(" / ");
398  if (field->sign && value[0] != '-')
399  value = std::string("+").append(value);
400  const std::string format = translator->getStr(field->description);
401  effect.append(strprintf(format.c_str(),
402  value.c_str()));
403  }
404  }
405  if (effect.empty())
406  return effect;
407  // TRANSLATORS: popup label
408  return _("Options: ") + effect;
409 }
410 
411 #define caseSetColor(name1, name2) \
412  case name1: \
413  { \
414  return label->setForegroundColorAll(getThemeColor(name2), \
415  getThemeColor(name2##_OUTLINE)); \
416  }
418  const ItemDbTypeT type) const
419 {
420  switch (type)
421  {
441  default:
442  {
443  return label->setForegroundColorAll(getThemeColor(
446  }
447  }
448 }
449 #undef caseSetColor
450 
452 {
453  Popup::mouseMoved(event);
454 
455  // When the mouse moved on top of the popup, hide it
457  resetPopup();
458 }
459 
461 {
462  mLastName.clear();
464  mLastId = 0;
465 }
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:814
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:151
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)
const Color & getThemeColor(const ThemeColorIdT type, const unsigned int alpha=255U) const A_INLINE
Definition: widget2.h:44
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.h:244
Definition: icon.h:39
std::string strprintf(const char *const format,...)
Definition: stringutils.cpp:99
void setCaption(const std::string &caption)
Definition: label.cpp:256
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:249
std::string getOptionsString(const ItemOptionsList *const options)
Definition: itempopup.cpp:376
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:92
void setLabelColor(Label *label, const ItemDbTypeT type) const
Definition: itempopup.cpp:417
#define nullptr
Definition: localconsts.h:44
void mouseMoved(MouseEvent &event)
Definition: itempopup.cpp:451
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:183
std::string getCardsString(const int *const cards)
Definition: itempopup.cpp:324
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:178
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:118
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
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:460
Definition: popup.h:48
std::string combineDye2(std::string file, const std::string &dye)
#define caseSetColor(name1, name2)
Definition: itempopup.cpp:411
void setForegroundColorAll(const Color &color1, const Color &color2)
Definition: label.cpp:209
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:192
void decRef()
Definition: image.cpp:521
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