ManaPlus
itemshortcutcontainer.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2007-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 "dragdrop.h"
26 #include "settings.h"
27 #include "spellmanager.h"
28 
29 #include "being/playerinfo.h"
30 
31 #include "input/inputmanager.h"
32 
33 #include "gui/skin.h"
34 #include "gui/viewport.h"
35 
36 #include "gui/fonts/font.h"
37 
40 
41 #include "gui/popups/itempopup.h"
42 #include "gui/popups/popupmenu.h"
43 #include "gui/popups/skillpopup.h"
44 #include "gui/popups/spellpopup.h"
45 
48 
50 
51 #include "const/resources/skill.h"
52 
53 #include "utils/stringutils.h"
54 
55 #include "debug.h"
56 
58  const unsigned number) :
59  ShortcutContainer(widget),
60  mEquipedColor(getThemeColor(ThemeColorId::ITEM_EQUIPPED, 255U)),
61  mEquipedColor2(getThemeColor(ThemeColorId::ITEM_EQUIPPED_OUTLINE, 255U)),
62  mUnEquipedColor(getThemeColor(ThemeColorId::ITEM_NOT_EQUIPPED, 255U)),
63  mUnEquipedColor2(getThemeColor(ThemeColorId::ITEM_NOT_EQUIPPED_OUTLINE,
64  255U)),
65  mNumber(number),
66  mKeyOffsetX(2),
67  mKeyOffsetY(2),
68  mItemClicked(false)
69 {
71 }
72 
74 {
75 }
76 
77 void ItemShortcutContainer::setSkin(const Widget2 *const widget,
78  Skin *const skin)
79 {
80  ShortcutContainer::setSkin(widget, skin);
85  255U);
88  if (mSkin != nullptr)
89  {
90  mKeyOffsetX = mSkin->getOption("keyOffsetX", 2);
91  mKeyOffsetY = mSkin->getOption("keyOffsetY", 2);
92  }
93 }
94 
96 {
97  BLOCK_START("ItemShortcutContainer::draw")
98  const ItemShortcut *const selShortcut = itemShortcut[mNumber];
99  if (selShortcut == nullptr)
100  {
101  BLOCK_END("ItemShortcutContainer::draw")
102  return;
103  }
104 
105  if (settings.guiAlpha != mAlpha)
106  {
107  if (mBackgroundImg != nullptr)
110  }
111 
112  Font *const font = getFont();
113  drawBackground(graphics);
114 
115  const Inventory *const inv = PlayerInfo::getInventory();
116  if (inv == nullptr)
117  {
118  BLOCK_END("ItemShortcutContainer::draw")
119  return;
120  }
121 
122  // +++ for future usage need reorder drawing images before text or back
123  for (unsigned i = 0; i < mMaxItems; i++)
124  {
125  const int itemX = (i % mGridWidth) * mBoxWidth;
126  const int itemY = (i / mGridWidth) * mBoxHeight;
127 
128  // Draw item keyboard shortcut.
129  const std::string key = inputManager.getKeyValueString(
131  font->drawString(graphics,
134  key,
135  itemX + mKeyOffsetX,
136  itemY + mKeyOffsetY);
137 
138  const int itemId = selShortcut->getItem(i);
139  const ItemColor itemColor = selShortcut->getItemColor(i);
140 
141  if (itemId < 0)
142  continue;
143 
144  // this is item
145  if (itemId < SPELL_MIN_ID)
146  {
147  const Item *const item = inv->findItem(itemId, itemColor);
148  if (item != nullptr)
149  {
150  // Draw item icon.
151  Image *const image = item->getImage();
152  if (image != nullptr)
153  {
154  std::string caption;
155  if (item->getQuantity() > 1)
156  caption = toString(item->getQuantity());
157  else if (item->isEquipped() == Equipped_true)
158  caption = "Eq.";
159 
160  image->setAlpha(1.0F);
161  graphics->drawImage(image,
162  itemX + mImageOffsetX,
163  itemY + mImageOffsetY);
164  if (item->isEquipped() == Equipped_true)
165  {
166  font->drawString(graphics,
169  caption,
170  itemX + (mBoxWidth - font->getWidth(caption)) / 2,
171  itemY + mBoxHeight - 14);
172  }
173  else
174  {
175  font->drawString(graphics,
178  caption,
179  itemX + (mBoxWidth - font->getWidth(caption)) / 2,
180  itemY + mBoxHeight - 14);
181  }
182  }
183  }
184  }
185  else if (itemId < SKILL_MIN_ID && (spellManager != nullptr))
186  { // this is magic shortcut
187  const TextCommand *const spell = spellManager
188  ->getSpellByItem(itemId);
189  if (spell != nullptr)
190  {
191  if (!spell->isEmpty())
192  {
193  Image *const image = spell->getImage();
194 
195  if (image != nullptr)
196  {
197  image->setAlpha(1.0F);
198  graphics->drawImage(image,
199  itemX + mImageOffsetX,
200  itemY + mImageOffsetY);
201  }
202  }
203 
204  font->drawString(graphics,
207  spell->getSymbol(),
208  itemX + mTextOffsetX,
209  itemY + mTextOffsetY);
210  }
211  }
212  else if (skillDialog != nullptr)
213  {
214  const SkillInfo *const skill = skillDialog->getSkill(
215  itemId - SKILL_MIN_ID);
216  if (skill != nullptr)
217  {
218  Image *const image = skill->data->icon;
219 
220  if (image != nullptr)
221  {
222  image->setAlpha(1.0F);
223  graphics->drawImage(image,
224  itemX + mImageOffsetX,
225  itemY + mImageOffsetY);
226  }
227  if (!skill->data->haveIcon)
228  {
229  font->drawString(graphics,
232  skill->data->shortName,
233  itemX + mTextOffsetX,
234  itemY + mTextOffsetY);
235  }
236  }
237  }
238  }
239  BLOCK_END("ItemShortcutContainer::draw")
240 }
241 
243 {
244  BLOCK_START("ItemShortcutContainer::draw")
245  const ItemShortcut *const selShortcut = itemShortcut[mNumber];
246  if (selShortcut == nullptr)
247  {
248  BLOCK_END("ItemShortcutContainer::draw")
249  return;
250  }
251 
252  if (settings.guiAlpha != mAlpha)
253  {
254  if (mBackgroundImg != nullptr)
257  }
258 
259  Font *const font = getFont();
260  safeDrawBackground(graphics);
261 
262  const Inventory *const inv = PlayerInfo::getInventory();
263  if (inv == nullptr)
264  {
265  BLOCK_END("ItemShortcutContainer::draw")
266  return;
267  }
268 
269  // +++ for future usage need reorder drawing images before text or back
270  for (unsigned i = 0; i < mMaxItems; i++)
271  {
272  const int itemX = (i % mGridWidth) * mBoxWidth;
273  const int itemY = (i / mGridWidth) * mBoxHeight;
274 
275  // Draw item keyboard shortcut.
276  const std::string key = inputManager.getKeyValueString(
278  font->drawString(graphics,
281  key,
282  itemX + mKeyOffsetX,
283  itemY + mKeyOffsetY);
284 
285  const int itemId = selShortcut->getItem(i);
286  const ItemColor itemColor = selShortcut->getItemColor(i);
287 
288  if (itemId < 0)
289  continue;
290 
291  // this is item
292  if (itemId < SPELL_MIN_ID)
293  {
294  const Item *const item = inv->findItem(itemId, itemColor);
295  if (item != nullptr)
296  {
297  // Draw item icon.
298  Image *const image = item->getImage();
299  if (image != nullptr)
300  {
301  std::string caption;
302  if (item->getQuantity() > 1)
303  caption = toString(item->getQuantity());
304  else if (item->isEquipped() == Equipped_true)
305  caption = "Eq.";
306 
307  image->setAlpha(1.0F);
308  graphics->drawImage(image,
309  itemX + mImageOffsetX,
310  itemY + mImageOffsetY);
311  if (item->isEquipped() == Equipped_true)
312  {
313  font->drawString(graphics,
316  caption,
317  itemX + (mBoxWidth - font->getWidth(caption)) / 2,
318  itemY + mBoxHeight - 14);
319  }
320  else
321  {
322  font->drawString(graphics,
325  caption,
326  itemX + (mBoxWidth - font->getWidth(caption)) / 2,
327  itemY + mBoxHeight - 14);
328  }
329  }
330  }
331  }
332  else if (itemId < SKILL_MIN_ID && (spellManager != nullptr))
333  { // this is magic shortcut
334  const TextCommand *const spell = spellManager
335  ->getSpellByItem(itemId);
336  if (spell != nullptr)
337  {
338  if (!spell->isEmpty())
339  {
340  Image *const image = spell->getImage();
341 
342  if (image != nullptr)
343  {
344  image->setAlpha(1.0F);
345  graphics->drawImage(image,
346  itemX + mImageOffsetX,
347  itemY + mImageOffsetY);
348  }
349  }
350 
351  font->drawString(graphics,
354  spell->getSymbol(),
355  itemX + mTextOffsetX,
356  itemY + mTextOffsetY);
357  }
358  }
359  else if (skillDialog != nullptr)
360  {
361  const SkillInfo *const skill = skillDialog->getSkill(
362  itemId - SKILL_MIN_ID);
363  if (skill != nullptr)
364  {
365  Image *const image = skill->data->icon;
366 
367  if (image != nullptr)
368  {
369  image->setAlpha(1.0F);
370  graphics->drawImage(image,
371  itemX + mImageOffsetX,
372  itemY + mImageOffsetY);
373  }
374  if (!skill->data->haveIcon)
375  {
376  font->drawString(graphics,
379  skill->data->shortName,
380  itemX + mTextOffsetX,
381  itemY + mTextOffsetY);
382  }
383  }
384  }
385  }
386  BLOCK_END("ItemShortcutContainer::draw")
387 }
388 
390 {
391  if (mNumber == SHORTCUT_AUTO_TAB)
392  return;
393  ItemShortcut *const selShortcut = itemShortcut[mNumber];
394  if (selShortcut == nullptr)
395  return;
396 
397  if (event.getButton() == MouseButton::LEFT)
398  {
399  if (dragDrop.isEmpty() && mItemClicked)
400  {
401  mItemClicked = false;
402 
403  const int index = getIndexFromGrid(event.getX(), event.getY());
404  if (index == -1)
405  return;
406 
407  const int itemId = selShortcut->getItem(index);
408  const ItemColor itemColor = selShortcut->getItemColor(index);
409 
410  if (itemId < 0)
411  return;
412 
413  event.consume();
414  if (itemId < SPELL_MIN_ID)
415  { // items
416  if (PlayerInfo::getInventory() == nullptr)
417  return;
418 
419  const Item *const item = PlayerInfo::getInventory()->findItem(
420  itemId, itemColor);
421 
422  if (item != nullptr)
423  {
424  selShortcut->removeItem(index);
426  }
427  else
428  {
429  dragDrop.clear();
430  }
431  }
432  else if (itemId < SKILL_MIN_ID)
433  { // spells/commands
434  if (spellManager == nullptr)
435  {
436  dragDrop.clear();
437  return;
438  }
439 
440  const TextCommand *const spell = spellManager->getSpellByItem(
441  itemId);
442  if (spell != nullptr)
443  {
444  selShortcut->removeItem(index);
445  dragDrop.dragCommand(spell,
447  dragDrop.setItem(itemId);
448  }
449  else
450  {
451  dragDrop.clear();
452  }
453  }
454  else
455  { // skills
456  if (skillDialog == nullptr)
457  {
458  dragDrop.clear();
459  return;
460  }
461  const SkillInfo *const skill
462  = skillDialog->getSkillByItem(itemId);
463  if (skill != nullptr)
464  {
465  const std::string itemData = selShortcut->getItemData(
466  index);
467  selShortcut->removeItem(index);
468  dragDrop.dragSkill(skill,
470  index);
471  dragDrop.setItem(itemId);
472  dragDrop.setItemColor(itemColor);
473  dragDrop.setItemData(itemData);
474  }
475  else
476  {
477  dragDrop.clear();
478  }
479  }
480  }
481  }
482 }
483 
485 {
486  ItemShortcut *const selShortcut = itemShortcut[mNumber];
487  if (selShortcut == nullptr)
488  return;
489 
490  const int index = getIndexFromGrid(event.getX(), event.getY());
491 
492  if (index == -1)
493  return;
494 
495  if (event.getButton() == MouseButton::LEFT)
496  {
497  event.consume();
498  // Stores the selected item if theirs one.
499  if (selShortcut->isItemSelected() && (inventoryWindow != nullptr) &&
501  || selShortcut->getSelectedItem() >= SPELL_MIN_ID))
502  {
503  selShortcut->setItem(index);
504  selShortcut->setItemSelected(-1);
505  if (spellShortcut != nullptr)
508  }
509  else if (selShortcut->getItem(index) != 0)
510  {
511  mItemClicked = true;
512  }
513  }
514  else if (event.getButton() == MouseButton::RIGHT)
515  {
516  event.consume();
517  if (popupMenu != nullptr &&
518  viewport != nullptr)
519  {
521  viewport->mMouseY,
522  selShortcut->getItem(index),
523  selShortcut->getItemColor(index));
524  }
525  }
526 }
527 
529 {
530  ItemShortcut *const selShortcut = itemShortcut[mNumber];
531  if (selShortcut == nullptr)
532  return;
533 
534  if (event.getButton() == MouseButton::LEFT)
535  {
536  if (selShortcut->isItemSelected())
537  selShortcut->setItemSelected(-1);
538 
539  const int index = getIndexFromGrid(event.getX(), event.getY());
540  if (index == -1)
541  return;
542 
543  if (dragDrop.isEmpty())
544  {
545  if ((selShortcut->getItem(index) != 0) && mItemClicked)
546  selShortcut->useItem(index);
547  }
548  else
549  {
551  {
552  const int oldIndex = dragDrop.getTag();
553  selShortcut->setItem(oldIndex, dragDrop.getItem(),
555  selShortcut->swap(oldIndex, index);
556  }
557  else
558  {
559  selShortcut->setItemData(index,
561  selShortcut->setItem(index, dragDrop.getItem(),
563  }
564  dragDrop.clear();
565  dragDrop.deselect();
566  }
567 
568  mItemClicked = false;
569  }
570 }
571 
573 {
574  const ItemShortcut *const selShortcut = itemShortcut[mNumber];
575  if (selShortcut == nullptr)
576  return;
577 
578  const int index = getIndexFromGrid(event.getX(), event.getY());
579 
580  if (index == -1)
581  return;
582 
583  const int itemId = selShortcut->getItem(index);
584  const ItemColor itemColor = selShortcut->getItemColor(index);
585 
586  if (itemId < 0)
587  return;
588 
589  if (itemId < SPELL_MIN_ID)
590  {
593 
594  Inventory *const inv = PlayerInfo::getInventory();
595  if (inv == nullptr)
596  return;
597 
598  const Item *const item = inv->findItem(itemId, itemColor);
599  if ((item != nullptr) && (viewport != nullptr))
600  {
601  itemPopup->setItem(item, false);
603  }
604  else
605  {
607  }
608  }
609  else if (itemId < SKILL_MIN_ID && (spellManager != nullptr))
610  {
613  const TextCommand *const spell = spellManager->getSpellByItem(itemId);
614  if ((spell != nullptr) && (viewport != nullptr))
615  {
616  spellPopup->setItem(spell);
618  viewport->mMouseY);
619  }
620  else
621  {
623  }
624  }
625  else if (skillDialog != nullptr)
626  {
629  const SkillInfo *const skill = skillDialog->getSkillByItem(itemId);
630  if (skill == nullptr)
631  return;
632 
633  const std::string data = selShortcut->getItemData(index);
634  CastTypeT castType = CastType::Default;
635  int offsetX = 0;
636  int offsetY = 0;
637  if (!data.empty())
638  {
639  STD_VECTOR<int> vect;
640  splitToIntVector(vect, data, ' ');
641  const size_t sz = vect.size();
642  if (sz > 0)
643  castType = static_cast<CastTypeT>(vect[0]);
644  if (sz > 2)
645  {
646  offsetX = vect[1];
647  offsetY = vect[2];
648  }
649  }
650  skillPopup->show(skill,
651  toInt(itemColor, int),
652  castType,
653  offsetX,
654  offsetY);
656  viewport->mMouseY);
657  }
658 }
659 
660 // Hide ItemTooltip
662 {
663  if (itemPopup != nullptr)
665  if (spellPopup != nullptr)
667  if (skillPopup != nullptr)
669 }
670 
672 {
673  if (itemPopup != nullptr)
675  if (spellPopup != nullptr)
677 }
Font * getFont() const
Definition: widget.cpp:330
void useItem(const size_t index) const
void removeItem(const size_t index)
Definition: itemshortcut.h:145
void setItemSelected(const int itemId)
Definition: itemshortcut.h:125
int getTag() const
Definition: dragdrop.h:234
bool skill(InputEvent &event)
Definition: commands.cpp:96
void draw(Graphics *const graphics)
Definition: skin.h:35
int getSelectedItem() const
Definition: itemshortcut.h:133
SkillInfo * getSkillByItem(const int itemId) const
Definition: font.h:88
SpellManager * spellManager
void clear()
Definition: dragdrop.h:182
Item * findItem(const int itemId, const ItemColor color) const
Definition: inventory.cpp:93
SkillPopup * skillPopup
Definition: skillpopup.cpp:41
void setVisible(Visible visible)
Definition: widget.cpp:224
Equipped isEquipped() const
Definition: item.h:128
MouseButtonT getButton() const
Definition: mouseevent.h:115
Inventory * getInventory()
Definition: playerinfo.cpp:193
#define BLOCK_START(name)
Definition: perfomance.h:78
DragDrop dragDrop
bool isItemSelected() const
Definition: itemshortcut.h:139
#define BLOCK_END(name)
Definition: perfomance.h:79
const size_t SHORTCUT_AUTO_TAB
Definition: itemshortcut.h:28
uint16_t ItemColor
Definition: itemcolor.h:29
int mMouseX
Definition: viewport.h:153
void swap(const size_t index1, const size_t index2)
SpellPopup * spellPopup
Definition: spellpopup.cpp:34
const bool Equipped_true
Definition: equipped.h:29
bool isEmpty() const
Definition: dragdrop.h:195
std::string getItemData()
Definition: dragdrop.h:80
const int SKILL_MIN_ID
Definition: skill.h:24
InventoryWindow * inventoryWindow
void show(const SkillInfo *const skill, const int level, const CastTypeT type, const int offsetX, const int offsetY)
Definition: skillpopup.cpp:105
Color mForegroundColor
Definition: widget.h:1085
Image * icon
Definition: skilldata.h:46
void dragItem(const Item *const item, const DragDropSourceT source, const int tag)
Definition: dragdrop.h:86
void setItemData(const size_t index, const std::string &data)
Definition: itemshortcut.h:75
int getOption(const std::string &name) const
Definition: skin.h:105
SkillData * data
Definition: skillinfo.h:62
int getIndexFromGrid(const int pointX, const int pointY) const
void mouseReleased(MouseEvent &event)
#define toInt(val, name)
Definition: intdefines.h:46
Settings settings
Definition: settings.cpp:31
virtual void setAlpha(const float alpha)
Definition: image.cpp:286
const int SPELL_MIN_ID
Definition: spells.h:27
void mouseDragged(MouseEvent &event)
void setSkin(const Widget2 *const widget, Skin *const skin)
SkillInfo * getSkill(const int id) const
void safeDraw(Graphics *const graphics)
const bool Visible_false
Definition: visible.h:29
int getQuantity() const
Definition: item.h:104
void mouseExited(MouseEvent &event)
void setItemData(const std::string &data)
Definition: dragdrop.h:77
virtual void setSkin(const Widget2 *const widget, Skin *const skin)
std::string getKeyValueString(const InputActionT index) const
void dragSkill(const SkillInfo *const info, const DragDropSourceT source, const int tag)
Definition: dragdrop.h:151
uint32_t data
PopupMenu * popupMenu
Definition: popupmenu.cpp:102
void position(const int x, const int y)
Definition: popup.cpp:234
void drawString(Graphics *const graphics, Color col, const Color &col2, const std::string &text, const int x, const int y)
Definition: font.cpp:253
Definition: item.h:48
void setItem(const TextCommand *const spell)
Definition: spellpopup.cpp:63
bool isWindowVisible() const
Definition: window.h:483
void setItem(const int item)
Definition: dragdrop.h:237
void setItemColor(const ItemColor color)
Definition: dragdrop.h:71
int getItem(const size_t index) const
Definition: itemshortcut.h:69
void deselect()
Definition: dragdrop.h:212
void setItemSelected(const int itemId)
Definition: spellshortcut.h:58
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
void view(const int x, const int y)
Definition: spellpopup.cpp:91
ItemShortcut * itemShortcut[SHORTCUT_TABS]
void setItem(const size_t index)
int mMouseY
Definition: viewport.h:154
void drawBackground(Graphics *const g)
bool haveIcon
Definition: skilldata.h:57
SkillDialog * skillDialog
Definition: skilldialog.cpp:65
std::string toString(T const &value)
converts any type to a string
Definition: catch.hpp:1774
const TextCommand * getSpellByItem(const int itemId) const
#define A_UNUSED
Definition: localconsts.h:159
Color mForegroundColor2
Definition: widget2.h:112
Image * getImage() const
Definition: item.h:86
virtual void drawImage(const Image *const image, int dstX, int dstY)=0
std::string getSymbol() const
Definition: textcommand.h:91
int getWidth(const std::string &text) const
Definition: font.cpp:333
Definition: event.h:77
ItemColor getItemColor() const
Definition: dragdrop.h:68
Definition: image.h:61
void showItemPopup(const int x, const int y, const Item *const item)
Definition: popupmenu.cpp:1789
void safeDrawBackground(Graphics *const g)
bool isEmpty() const
Definition: textcommand.h:153
static int getItemCount()
Definition: itemshortcut.h:85
const Color & getThemeColor(const ThemeColorIdT type, const unsigned int alpha) const A_INLINE
Definition: widget2.h:44
int getX() const
Definition: mouseevent.h:126
InputManager inputManager
void splitToIntVector(std::vector< int > &tokens, const std::string &text, const char separator)
DragDropSourceT getSource() const
Definition: dragdrop.h:83
ItemPopup * itemPopup
Definition: itempopup.cpp:63
ItemShortcutContainer(Widget2 *const widget, const unsigned number)
float guiAlpha
Definition: settings.h:129
void widgetHidden(const Event &event)
std::string shortName
Definition: skilldata.h:34
std::string getItemData(const size_t index) const
Definition: itemshortcut.h:79
ItemColor getItemColor(const size_t index) const
Definition: itemshortcut.h:72
void dragCommand(const TextCommand *const command, const DragDropSourceT source, const int tag)
Definition: dragdrop.h:116
SpellShortcut * spellShortcut
void mouseMoved(MouseEvent &event)
Image * getImage() const
Definition: textcommand.h:156
void mousePressed(MouseEvent &event)
Viewport * viewport
Definition: viewport.cpp:35
int getItem() const
Definition: dragdrop.h:65
CastType ::T CastTypeT
Definition: casttype.h:33