ManaPlus
inventorywindow.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/playerinfo.h"
29 
30 #include "const/sound.h"
31 
32 #include "enums/gui/layouttype.h"
33 
34 #include "input/inputmanager.h"
35 
36 #include "gui/gui.h"
37 
38 #include "gui/fonts/font.h"
39 
41 
42 #include "gui/popups/itempopup.h"
43 #include "gui/popups/popupmenu.h"
44 #include "gui/popups/textpopup.h"
45 
48 #include "gui/windows/npcdialog.h"
51 
52 #include "gui/widgets/button.h"
55 #include "gui/widgets/dropdown.h"
57 #include "gui/widgets/layout.h"
59 #include "gui/widgets/scrollarea.h"
60 #include "gui/widgets/tabstrip.h"
61 #include "gui/widgets/textfield.h"
63 
65 
66 #include "net/npchandler.h"
67 
68 #include "resources/iteminfo.h"
69 
70 #include "resources/db/unitsdb.h"
71 
72 #include "resources/item/item.h"
73 
74 #include "utils/delete2.h"
75 #include "utils/foreach.h"
76 
77 #include "debug.h"
78 
84 
86  Window("Inventory", Modal_false, nullptr, "inventory.xml"),
88  KeyListener(),
92  mInventory(inventory),
93  mItems(new ItemContainer(this, mInventory, 100000,
95  mUseButton(nullptr),
96  mDropButton(nullptr),
97  mOutfitButton(nullptr),
98  mShopButton(nullptr),
99  mCartButton(nullptr),
100  mEquipmentButton(nullptr),
101  mStoreButton(nullptr),
102  mRetrieveButton(nullptr),
103  mInvCloseButton(nullptr),
104  mWeightBar(nullptr),
105  mSlotsBar(new ProgressBar(this, 0.0F, 100, 0,
107  "slotsprogressbar.xml", "slotsprogressbar_fill.xml")),
108  mFilter(nullptr),
109  mSortModel(new SortListModelInv),
110  mSortDropDown(new DropDown(this, mSortModel, false,
111  Modal_false, this, "sort")),
112  mNameFilter(new TextField(this, "", LoseFocusOnTab_true,
113  this, "namefilter", true)),
114  mSortDropDownCell(nullptr),
115  mNameFilterCell(nullptr),
116  mFilterCell(nullptr),
117  mSlotsBarCell(nullptr),
118  mSplit(false),
119  mCompactMode(false)
120 {
121  mSlotsBar->setColor(getThemeColor(ThemeColorId::SLOTS_BAR, 255U),
122  getThemeColor(ThemeColorId::SLOTS_BAR_OUTLINE, 255U));
123 
124  if (inventory != nullptr)
125  {
126  setCaption(gettext(inventory->getName().c_str()));
127  setWindowName(inventory->getName());
128  switch (inventory->getType())
129  {
132  case InventoryType::Npc:
138  default:
140  "inventorySortOrder"));
141  break;
144  "storageSortOrder"));
145  break;
146  case InventoryType::Cart:
148  "cartSortOrder"));
149  break;
150  }
151  }
152  else
153  {
154  // TRANSLATORS: inventory window name
155  setCaption(_("Inventory"));
156  setWindowName("Inventory");
158  }
159 
160  if ((setupWindow != nullptr) &&
161  (inventory != nullptr) &&
162  inventory->getType() != InventoryType::Storage)
163  {
165  }
166 
167  setResizable(true);
168  setCloseButton(true);
169  setSaveVisible(true);
170  setStickyButtonLock(true);
171 
172  if (mainGraphics->mWidth > 600)
173  setDefaultSize(450, 310, ImagePosition::CENTER, 0, 0);
174  else
175  setDefaultSize(387, 307, ImagePosition::CENTER, 0, 0);
176  setMinWidth(310);
177  setMinHeight(179);
178  addKeyListener(this);
179 
181 
182  const int size = config.getIntValue("fontSize");
183  mFilter = new TabStrip(this, "filter_" + getWindowName(), size + 16, 0);
184  mFilter->addActionListener(this);
185  mFilter->setActionEventId("tag_");
186  mFilter->setSelectable(false);
187 
188  StringVect tags = ItemDB::getTags();
189  const size_t sz = tags.size();
190  for (size_t f = 0; f < sz; f ++)
191  mFilter->addButton(tags[f], tags[f], false);
192 
193  if (mInventory == nullptr)
194  {
195  invInstances.push_back(this);
196  return;
197  }
198 
199  ScrollArea *const invenScroll = new ScrollArea(this, mItems,
200  fromBool(getOptionBool("showbackground", false), Opaque),
201  "inventory_background.xml");
203 
204  switch (mInventory->getType())
205  {
207  {
208  // TRANSLATORS: inventory button
209  const std::string equip = _("Equip");
210  // TRANSLATORS: inventory button
211  const std::string use = _("Use");
212  // TRANSLATORS: inventory button
213  const std::string unequip = _("Unequip");
214 
215  std::string longestUseString = getFont()->getWidth(equip) >
216  getFont()->getWidth(use) ? equip : use;
217 
218  if (getFont()->getWidth(longestUseString) <
219  getFont()->getWidth(unequip))
220  {
221  longestUseString = unequip;
222  }
223 
224  mUseButton = new Button(this,
225  longestUseString,
226  "use",
227  BUTTON_SKIN,
228  this);
229  mDropButton = new Button(this,
230  // TRANSLATORS: inventory button
231  _("Drop..."),
232  "drop",
233  BUTTON_SKIN,
234  this);
235  mOutfitButton = new Button(this,
236  // TRANSLATORS: inventory outfits button
237  _("O"),
238  "outfit",
239  BUTTON_SKIN,
240  this);
241  mCartButton = new Button(this,
242  // TRANSLATORS: inventory cart button
243  _("C"),
244  "cart",
245  BUTTON_SKIN,
246  this);
247  mShopButton = new Button(this,
248  // TRANSLATORS: inventory shop button
249  _("S"),
250  "shop",
251  BUTTON_SKIN,
252  this);
253  mEquipmentButton = new Button(this,
254  // TRANSLATORS: inventory equipment button
255  _("E"),
256  "equipment",
257  BUTTON_SKIN,
258  this);
259  mWeightBar = new ProgressBar(this, 0.0F, 100, 0,
261  "weightprogressbar.xml", "weightprogressbar_fill.xml");
262  mWeightBar->setColor(getThemeColor(ThemeColorId::WEIGHT_BAR, 255U),
263  getThemeColor(ThemeColorId::WEIGHT_BAR_OUTLINE, 255U));
264 
265  // TRANSLATORS: outfits button tooltip
266  mOutfitButton->setDescription(_("Outfits"));
267  // TRANSLATORS: cart button tooltip
268  mCartButton->setDescription(_("Cart"));
269  // TRANSLATORS: shop button tooltip
270  mShopButton->setDescription(_("Shop"));
271  // TRANSLATORS: equipment button tooltip
272  mEquipmentButton->setDescription(_("Equipment"));
273 
274  place(0, 0, mWeightBar, 4, 1);
275  mSlotsBarCell = &place(4, 0, mSlotsBar, 4, 1);
276  mSortDropDownCell = &place(8, 0, mSortDropDown, 3, 1);
277 
278  mFilterCell = &place(0, 1, mFilter, 10, 1).setPadding(3);
279  mNameFilterCell = &place(8, 1, mNameFilter, 3, 1);
280 
281  place(0, 2, invenScroll, 11, 1).setPadding(3);
282  place(0, 3, mUseButton, 1, 1);
283  place(1, 3, mDropButton, 1, 1);
284  ContainerPlacer placer = getPlacer(10, 3);
285  placer(0, 0, mShopButton, 1, 1);
286  placer(1, 0, mOutfitButton, 1, 1);
287  placer(2, 0, mCartButton, 1, 1);
288  placer(3, 0, mEquipmentButton, 1, 1);
289 
290  updateWeight();
291  break;
292  }
293 
295  {
296  mStoreButton = new Button(this,
297  // TRANSLATORS: storage button
298  _("Store"),
299  "store",
300  BUTTON_SKIN,
301  this);
302  mRetrieveButton = new Button(this,
303  // TRANSLATORS: storage button
304  _("Retrieve"),
305  "retrieve",
306  BUTTON_SKIN,
307  this);
308  mInvCloseButton = new Button(this,
309  // TRANSLATORS: storage button
310  _("Close"),
311  "close",
312  BUTTON_SKIN,
313  this);
314 
315  mSlotsBarCell = &place(0, 0, mSlotsBar, 6, 1);
316  mSortDropDownCell = &place(6, 0, mSortDropDown, 1, 1);
317 
318  mFilterCell = &place(0, 1, mFilter, 7, 1).setPadding(3);
319  mNameFilterCell = &place(6, 1, mNameFilter, 1, 1);
320 
321  place(0, 2, invenScroll, 7, 4);
322  place(0, 6, mStoreButton, 1, 1);
323  place(1, 6, mRetrieveButton, 1, 1);
324  place(6, 6, mInvCloseButton, 1, 1);
325  break;
326  }
327 
328  case InventoryType::Cart:
329  {
330  mStoreButton = new Button(this,
331  // TRANSLATORS: storage button
332  _("Store"),
333  "store",
334  BUTTON_SKIN,
335  this);
336  mRetrieveButton = new Button(this,
337  // TRANSLATORS: storage button
338  _("Retrieve"),
339  "retrieve",
340  BUTTON_SKIN,
341  this);
342  mInvCloseButton = new Button(this,
343  // TRANSLATORS: storage button
344  _("Close"),
345  "close",
346  BUTTON_SKIN,
347  this);
348 
349  mWeightBar = new ProgressBar(this, 0.0F, 100, 0,
351  "weightprogressbar.xml", "weightprogressbar_fill.xml");
352  mWeightBar->setColor(getThemeColor(ThemeColorId::WEIGHT_BAR, 255U),
353  getThemeColor(ThemeColorId::WEIGHT_BAR_OUTLINE, 255U));
354 
355  mSlotsBarCell = &place(3, 0, mSlotsBar, 3, 1);
356  mSortDropDownCell = &place(6, 0, mSortDropDown, 1, 1);
357 
358  mFilterCell = &place(0, 1, mFilter, 7, 1).setPadding(3);
359  mNameFilterCell = &place(6, 1, mNameFilter, 1, 1);
360 
361  place(0, 0, mWeightBar, 3, 1);
362  place(0, 2, invenScroll, 7, 4);
363  place(0, 6, mStoreButton, 1, 1);
364  place(1, 6, mRetrieveButton, 1, 1);
365  place(6, 6, mInvCloseButton, 1, 1);
366  break;
367  }
368 
369  default:
371  case InventoryType::Npc:
377  break;
378  }
379 
380  Layout &layout = getLayout();
381  layout.setRowHeight(2, LayoutType::SET);
382 
384 
385  invInstances.push_back(this);
386 
387  if (inventory->isMainInventory())
388  {
390  }
391  else
392  {
393  if (!invInstances.empty())
394  invInstances.front()->updateDropButton();
395  }
396 
397  loadWindowState();
398  enableVisibleSound(true);
399 }
400 
402 {
405 
407  widgetResized(Event(nullptr));
408  if (mInventory != nullptr &&
410  {
412  }
413 }
414 
416 {
417  invInstances.remove(this);
418  if (mInventory != nullptr)
420  if (!invInstances.empty())
421  invInstances.front()->updateDropButton();
422 
423  mSortDropDown->hideDrop(false);
425 }
426 
428 {
429  if (mInventory != nullptr)
430  {
431  switch (mInventory->getType())
432  {
435  case InventoryType::Npc:
441  default:
442  config.setValue("inventorySortOrder",
444  break;
446  config.setValue("storageSortOrder",
448  break;
449  case InventoryType::Cart:
450  config.setValue("cartSortOrder",
452  break;
453  }
454  }
455 }
456 
458 {
459  const std::string &eventId = event.getId();
460  if (eventId == "outfit")
461  {
463  }
464  else if (eventId == "shop")
465  {
467  }
468  else if (eventId == "equipment")
469  {
471  }
472  else if (eventId == "cart")
473  {
475  }
476  else if (eventId == "close")
477  {
478  close();
479  }
480  else if (eventId == "store")
481  {
482  if (inventoryWindow == nullptr || !inventoryWindow->isWindowVisible())
483  return;
484 
485  Item *const item = inventoryWindow->getSelectedItem();
486 
487  if (item == nullptr)
488  return;
489 
490  if (storageWindow != nullptr)
491  {
493  this,
494  item,
495  0,
496  0);
497  }
498  else if ((cartWindow != nullptr) && cartWindow->isWindowVisible())
499  {
501  this,
502  item,
503  0,
504  0);
505  }
506  }
507  else if (eventId == "sort")
508  {
510  storeSortOrder();
511  return;
512  }
513  else if (eventId == "namefilter")
514  {
516  mItems->updateMatrix();
517  }
518  else if (eventId.find("tag_") == 0U)
519  {
520  std::string tagName = event.getId().substr(4);
521  mItems->setFilter(ItemDB::getTagId(tagName));
522  return;
523  }
524 
525  Item *const item = mItems->getSelectedItem();
526 
527  if (item == nullptr)
528  return;
529 
530  if (eventId == "use")
531  {
533  }
534  if (eventId == "equip")
535  {
537  }
538  else if (eventId == "drop")
539  {
540  if (isStorageActive())
541  {
543  item->getInvIndex(),
544  item->getQuantity(),
546  }
547  else if ((cartWindow != nullptr) && cartWindow->isWindowVisible())
548  {
550  item->getInvIndex(),
551  item->getQuantity(),
553  }
554  else
555  {
556  if (PlayerInfo::isItemProtected(item->getId()))
557  return;
558 
560  {
561  PlayerInfo::dropItem(item, item->getQuantity(), Sfx_true);
562  }
563  else
564  {
566  this,
567  item,
568  0,
569  0);
570  }
571  }
572  }
573  else if (eventId == "split")
574  {
576  this,
577  item,
578  item->getQuantity() - 1,
579  9);
580  }
581  else if (eventId == "retrieve")
582  {
583  if (storageWindow != nullptr)
584  {
586  this,
587  item,
588  0,
589  0);
590  }
591  else if ((cartWindow != nullptr) && cartWindow->isWindowVisible())
592  {
594  this,
595  item,
596  0,
597  0);
598  }
599  }
600 }
601 
603 {
604  return mItems->getSelectedItem();
605 }
606 
608 {
609  mItems->selectNone();
610 }
611 
613 {
614  Window::widgetHidden(event);
615  if (itemPopup != nullptr)
617 }
618 
620 {
621  Window::mouseClicked(event);
622 
623  const int clicks = event.getClickCount();
624 
625  if (clicks == 2 && (gui != nullptr))
626  gui->resetClickCount();
627 
628  const bool mod = (isStorageActive() &&
630 
631  const bool mod2 = (tradeWindow != nullptr &&
634 
635  if (mInventory != nullptr)
636  {
637  if (!mod && !mod2 && event.getButton() == MouseButton::RIGHT)
638  {
639  Item *const item = mItems->getSelectedItem();
640 
641  if (item == nullptr)
642  return;
643 
644  /* Convert relative to the window coordinates to absolute screen
645  * coordinates.
646  */
647  if (popupMenu != nullptr)
648  {
649  const int mx = event.getX() + getX();
650  const int my = event.getY() + getY();
651 
652  popupMenu->showPopup(this,
653  mx, my,
654  item,
655  mInventory->getType());
656  }
657  }
658  }
659  else
660  {
661  return;
662  }
663 
664  if (event.getButton() == MouseButton::LEFT ||
665  event.getButton() == MouseButton::RIGHT)
666  {
667  Item *const item = mItems->getSelectedItem();
668 
669  if (item == nullptr)
670  return;
671 
672  if (mod)
673  {
675  {
676  if (event.getButton() == MouseButton::RIGHT)
677  {
681  item,
682  0,
683  0);
684  }
685  else
686  {
688  item->getInvIndex(),
689  item->getQuantity(),
691  }
692  }
693  else
694  {
695  if (event.getButton() == MouseButton::RIGHT)
696  {
700  item,
701  0,
702  0);
703  }
704  else
705  {
707  item->getInvIndex(),
708  item->getQuantity(),
710  }
711  }
712  }
713  else if (mod2 && mInventory->isMainInventory())
714  {
715  if (PlayerInfo::isItemProtected(item->getId()))
716  return;
717  if (event.getButton() == MouseButton::RIGHT)
718  {
720  tradeWindow,
721  item,
722  0,
723  0);
724  }
725  else
726  {
727  if (tradeWindow != nullptr)
728  tradeWindow->tradeItem(item, item->getQuantity(), true);
729  }
730  }
731  else if (clicks == 2)
732  {
734  {
735  if (isStorageActive())
736  {
740  item,
741  0,
742  0);
743  }
744  else if (tradeWindow != nullptr &&
746  {
747  if (PlayerInfo::isItemProtected(item->getId()))
748  return;
751  tradeWindow,
752  item,
753  0,
754  0);
755  }
756  else
757  {
759  }
760  }
761  else
762  {
763  if (isStorageActive())
764  {
768  item,
769  0,
770  0);
771  }
772  }
773  }
774  }
775 }
776 
778 {
779  Window::mouseMoved(event);
780  if (textPopup == nullptr)
781  return;
782 
783  const Widget *const src = event.getSource();
784  if (src == nullptr)
785  {
786  textPopup->hide();
787  return;
788  }
789  const int x = event.getX();
790  const int y = event.getY();
791  const Rect &rect = mDimension;
792  if (src == mSlotsBar || src == mWeightBar)
793  {
794  // TRANSLATORS: money label
795  textPopup->show(rect.x + x, rect.y + y, strprintf(_("Money: %s"),
797  Attributes::MONEY)).c_str()));
798  }
799  else
800  {
801  const Button *const btn = dynamic_cast<const Button *>(src);
802  if (btn == nullptr)
803  {
804  textPopup->hide();
805  return;
806  }
807  const std::string text = btn->getDescription();
808  if (!text.empty())
809  textPopup->show(x + rect.x, y + rect.y, text);
810  }
811 }
812 
814 {
815  textPopup->hide();
816 }
817 
819 {
820  if (event.getActionId() == InputAction::GUI_MOD)
821  mSplit = true;
822 }
823 
825 {
826  if (event.getActionId() == InputAction::GUI_MOD)
827  mSplit = false;
828 }
829 
831 {
832  if ((mInventory == nullptr) || !mInventory->isMainInventory())
833  return;
834 
835  Item *const item = mItems->getSelectedItem();
836 
837  if (mSplit && (item != nullptr) && inventoryHandler->
838  canSplit(mItems->getSelectedItem()))
839  {
841  this,
842  item,
843  item->getQuantity() - 1,
844  0);
845  }
846  updateButtons(item);
847 }
848 
850 {
851  if ((mInventory == nullptr) || !mInventory->isMainInventory())
852  return;
853 
854  const Item *const selectedItem = mItems->getSelectedItem();
855  if ((item != nullptr) && selectedItem != item)
856  return;
857 
858  if (item == nullptr)
859  item = selectedItem;
860 
861  if ((item == nullptr) || item->getQuantity() == 0)
862  {
863  if (mUseButton != nullptr)
864  mUseButton->setEnabled(false);
865  if (mDropButton != nullptr)
866  mDropButton->setEnabled(false);
867  return;
868  }
869 
870  if (mDropButton != nullptr)
871  mDropButton->setEnabled(true);
872 
873  if (mUseButton != nullptr)
874  {
875  const ItemInfo &info = item->getInfo();
876  const std::string &str = (item->isEquipment() == Equipm_true
877  && item->isEquipped() == Equipped_true)
878  ? info.getUseButton2() : info.getUseButton();
879  if (str.empty())
880  {
881  mUseButton->setEnabled(false);
882  // TRANSLATORS: default use button name
883  mUseButton->setCaption(_("Use"));
884  }
885  else
886  {
887  mUseButton->setEnabled(true);
888  mUseButton->setCaption(str);
889  }
890  }
891 
893 }
894 
896 {
897  if (mInventory == nullptr)
898  {
899  Window::close();
900  return;
901  }
902 
903  switch (mInventory->getType())
904  {
906  case InventoryType::Cart:
908  break;
909 
911  if (inventoryHandler != nullptr)
912  {
915  }
916  scheduleDelete();
917  break;
918 
919  default:
921  case InventoryType::Npc:
927  break;
928  }
929 }
930 
932 {
933  if ((mInventory == nullptr) || (mWeightBar == nullptr))
934  return;
935  const InventoryTypeT type = mInventory->getType();
936  if (type != InventoryType::Inventory &&
937  type != InventoryType::Cart)
938  {
939  return;
940  }
941 
942  const bool isInv = type == InventoryType::Inventory;
943  const int total = PlayerInfo::getAttribute(isInv
945  const int max = PlayerInfo::getAttribute(isInv
947 
948  if (max <= 0)
949  return;
950 
951  // Adjust progress bar
952  mWeightBar->setProgress(static_cast<float>(total)
953  / static_cast<float>(max));
954  mWeightBar->setText(strprintf("%s/%s",
955  UnitsDb::formatWeight(total).c_str(),
956  UnitsDb::formatWeight(max).c_str()));
957 }
958 
959 void InventoryWindow::slotsChanged(const Inventory *const inventory)
960 {
961  if (inventory == mInventory)
962  {
963  const int usedSlots = mInventory->getNumberOfSlotsUsed();
964  const int maxSlots = mInventory->getSize();
965 
966  if (maxSlots != 0)
967  {
968  mSlotsBar->setProgress(static_cast<float>(usedSlots)
969  / static_cast<float>(maxSlots));
970  }
971 
972  mSlotsBar->setText(strprintf("%d/%d", usedSlots, maxSlots));
973  mItems->updateMatrix();
974  }
975 }
976 
978 {
979  if (mDropButton == nullptr)
980  return;
981 
982  if (isStorageActive() ||
983  (cartWindow != nullptr && cartWindow->isWindowVisible()))
984  {
985  // TRANSLATORS: inventory button
986  mDropButton->setCaption(_("Store"));
987  }
988  else
989  {
990  const Item *const item = mItems->getSelectedItem();
991  if ((item != nullptr) && item->getQuantity() > 1)
992  {
993  // TRANSLATORS: inventory button
994  mDropButton->setCaption(_("Drop..."));
995  }
996  else
997  {
998  // TRANSLATORS: inventory button
999  mDropButton->setCaption(_("Drop"));
1000  }
1001  }
1002 }
1003 
1005 {
1006  return (mNameFilter != nullptr) && mNameFilter->isFocused();
1007 }
1008 
1010 {
1011  FOR_EACH (WindowList::const_iterator, it, invInstances)
1012  {
1013  if (((*it) != nullptr) && (*it)->isInputFocused())
1014  return true;
1015  }
1016  return false;
1017 }
1018 
1020 {
1021  std::set<Widget*> list;
1022  FOR_EACH (WindowList::const_iterator, it, invInstances)
1023  {
1024  if (((*it) != nullptr) && (*it)->isWindowVisible())
1025  list.insert(*it);
1026  }
1027  return dynamic_cast<InventoryWindow*>(
1029 }
1030 
1032 {
1033  const InventoryWindow *const window = getFirstVisible();
1034  if (window != nullptr)
1035  window->mFilter->nextTab();
1036 }
1037 
1039 {
1040  const InventoryWindow *const window = getFirstVisible();
1041  if (window != nullptr)
1042  window->mFilter->prevTab();
1043 }
1044 
1046 {
1047  Window::widgetResized(event);
1048 
1049  if (mInventory == nullptr)
1050  return;
1051  const InventoryTypeT type = mInventory->getType();
1052  if (type != InventoryType::Inventory &&
1053  type != InventoryType::Cart)
1054  {
1055  return;
1056  }
1057 
1058  if (getWidth() < 600)
1059  {
1060  if (!mCompactMode)
1061  {
1065  mCompactMode = true;
1066  }
1067  }
1068  else if (mCompactMode)
1069  {
1073  mCompactMode = false;
1074  }
1075 }
1076 
1078 {
1079  if (visible == Visible_false)
1080  mSortDropDown->hideDrop(true);
1081  Window::setVisible(visible);
1082 }
1083 
1085 {
1086  if (mInventory != nullptr)
1087  {
1089  if (mItems != nullptr)
1091  }
1092  mInventory = nullptr;
1093 }
1094 
1096  const int64_t oldVal A_UNUSED,
1097  const int64_t newVal A_UNUSED)
1098 {
1099  if (id == Attributes::TOTAL_WEIGHT
1100  || id == Attributes::MAX_WEIGHT
1102  || id == Attributes::CART_MAX_WEIGHT)
1103  {
1104  updateWeight();
1105  }
1106 }
1107 
1108 void InventoryWindow::combineItems(const int index1,
1109  const int index2)
1110 {
1111  if (mInventory == nullptr)
1112  return;
1113  const Item *item1 = mInventory->getItem(index1);
1114  if (item1 == nullptr)
1115  return;
1116  const Item *item2 = mInventory->getItem(index2);
1117  if (item2 == nullptr)
1118  return;
1119 
1120  if (item1->getType() != ItemType::Card)
1121  {
1122  const Item *tmpItem = item1;
1123  item1 = item2;
1124  item2 = tmpItem;
1125  }
1126 
1128  // TRANSLATORS: question dialog title
1129  _("Insert card request"),
1130  // TRANSLATORS: question dialog message
1131  strprintf(_("Insert %s into %s?"),
1132  item1->getName().c_str(),
1133  item2->getName().c_str()),
1134  SOUND_REQUEST,
1135  false,
1136  Modal_true,
1137  nullptr);
1141 }
1142 
1143 void InventoryWindow::moveItemToCraft(const int craftSlot)
1144 {
1145  if (npcHandler == nullptr)
1146  return;
1147 
1148  Item *const item = mItems->getSelectedItem();
1149  if (item == nullptr)
1150  return;
1151 
1152  NpcDialog *const dialog = npcHandler->getCurrentNpcDialog();
1153  if ((dialog != nullptr) &&
1155  {
1156  if (item->getQuantity() > 1
1158  {
1161  item,
1162  0,
1163  craftSlot);
1164  }
1165  else
1166  {
1167  dialog->addCraftItem(item, 1, craftSlot);
1168  }
1169  }
1170 }
Attributes ::T AttributesT
Definition: attributes.h:118
#define fromBool(val, name)
Definition: booldefines.h:49
const std::string BUTTON_SKIN
Definition: button.h:89
Widget * findFirstWidget(const std::set< Widget * > &list)
Definition: button.h:102
std::string getDescription() const
Definition: button.h:168
void setCaption(const std::string &caption)
Definition: button.h:214
void setDescription(const std::string &text)
Definition: button.h:165
void setValue(const std::string &key, const std::string &value)
int getIntValue(const std::string &key) const
int getSelected() const
Definition: dropdown.cpp:509
void hideDrop(bool event)
Definition: dropdown.cpp:378
void setSelected(int selected)
Definition: dropdown.cpp:514
Definition: event.h:79
int getWidth(const std::string &text) const
Definition: font.cpp:334
int mWidth
Definition: graphics.h:484
void resetClickCount()
Definition: gui.cpp:980
void executeAction(const InputActionT keyNum)
bool isActionActive(const InputActionT index) const
void mouseExited(MouseEvent &event)
Button * mRetrieveButton
void moveItemToCraft(const int craftSlot)
void action(const ActionEvent &event)
TabStrip * mFilter
TextField * mNameFilter
static WindowList invInstances
ProgressBar * mSlotsBar
void storeSortOrder() const
Button * mInvCloseButton
void combineItems(const int index1, const int index2)
ItemContainer * mItems
static void nextTab()
void attributeChanged(const AttributesT id, const int64_t oldVal, const int64_t newVal)
Button * mOutfitButton
InventoryWindow(Inventory *const inventory)
LayoutCell * mFilterCell
bool isInputFocused() const
static bool isAnyInputFocused()
static void prevTab()
void widgetResized(const Event &event)
void keyReleased(KeyEvent &event)
LayoutCell * mSortDropDownCell
void valueChanged(const SelectionEvent &event)
Inventory * mInventory
static bool isStorageActive()
DropDown * mSortDropDown
LayoutCell * mNameFilterCell
LayoutCell * mSlotsBarCell
void slotsChanged(const Inventory *const inventory)
Button * mEquipmentButton
SortListModelInv * mSortModel
void mouseClicked(MouseEvent &event)
static InventoryWindow * getFirstVisible()
std::list< InventoryWindow * > WindowList
void keyPressed(KeyEvent &event)
void setVisible(Visible visible)
void mouseMoved(MouseEvent &event)
void widgetHidden(const Event &event)
ProgressBar * mWeightBar
Item * getSelectedItem() const
void updateButtons(const Item *item)
Item * getItem(const int index) const
Definition: inventory.cpp:83
unsigned getSize() const
Definition: inventory.h:76
bool isMainInventory() const
Definition: inventory.h:179
std::string getName() const
Definition: inventory.cpp:351
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
static void showWindow(const ItemAmountWindowUsageT usage, Window *const parent, Item *const item, int maxRange, const int tag)
void setFilter(const int tag)
void unsetInventory()
void setName(const std::string &str)
void addSelectionListener(SelectionListener *listener)
Item * getSelectedItem() const
void setSortType(const int sortType)
Definition: item.h:50
Equipm isEquipment() const
Definition: item.h:117
int getQuantity() const
Definition: item.h:105
Equipped isEquipped() const
Definition: item.h:129
int getInvIndex() const
Definition: item.h:165
std::string getName() const
Definition: item.cpp:140
int getId() const
Definition: item.h:81
ItemTypeT getType() const
Definition: item.h:225
const ItemInfo & getInfo() const
Definition: item.h:171
InputActionT getActionId() const
Definition: keyevent.h:127
LayoutCell & setPadding(int p)
Definition: layoutcell.h:60
void setRowHeight(const int n, const int h)
Definition: layoutcell.cpp:128
void setType(int t)
Definition: layoutcell.h:134
void setWidth(const int w)
Definition: layoutcell.h:143
int getWidth() const
Definition: layoutcell.h:137
Definition: layout.h:45
MouseButtonT getButton() const
Definition: mouseevent.h:116
virtual void mouseClicked(MouseEvent &event)
virtual void moveItem2(const InventoryTypeT source, const int slot, const int amount, const InventoryTypeT destination) const =0
virtual void forgotStorage() const =0
virtual void closeStorage() const =0
virtual NpcDialog * getCurrentNpcDialog() const =0
NpcInputStateT getInputState()
Definition: npcdialog.h:237
void addCraftItem(Item *const item, const int amount, const int slot)
Definition: npcdialog.cpp:1382
void showPopup(const int x, const int y, const Being *const being)
Definition: popupmenu.cpp:203
void hide()
Definition: popup.cpp:265
void setProgress(const float progress)
void setColor(const Color &color1, const Color &color2)
void setText(const std::string &str)
Definition: rect.h:74
int y
Definition: rect.h:214
int x
Definition: rect.h:209
void setHorizontalScrollPolicy(const ScrollPolicy hPolicy)
void registerWindowForReset(Window *const window)
void nextTab()
Definition: tabstrip.cpp:90
void prevTab()
Definition: tabstrip.cpp:108
const std::string & getText() const
Definition: textfield.h:224
void show(const int x, const int y, const std::string &str1)
Definition: textpopup.h:57
void tradeItem(const Item *const item, const int quantity, const bool check) const
const Color & getThemeColor(const ThemeColorIdT type, const unsigned int alpha) const A_INLINE
Definition: widget2.h:45
virtual void addButton(const std::string &text, const std::string &tag, const bool pressed)
Definition: widgetgroup.cpp:42
Definition: widget.h:99
void setVisible(Visible visible)
Definition: widget.cpp:225
Rect mDimension
Definition: widget.h:1101
void setEnabled(const bool enabled)
Definition: widget.h:352
void setActionEventId(const std::string &actionEventId)
Definition: widget.h:596
void addKeyListener(KeyListener *const keyListener)
Definition: widget.cpp:272
int getY() const
Definition: widget.h:288
Font * getFont() const
Definition: widget.cpp:331
void setSelectable(const bool selectable)
Definition: widget.h:948
void addActionListener(ActionListener *const actionListener)
Definition: widget.cpp:252
int getX() const
Definition: widget.h:269
int getWidth() const
Definition: widget.h:221
virtual bool isFocused() const
Definition: widget.cpp:184
Definition: window.h:102
void setSaveVisible(const bool save)
Definition: window.h:300
void setResizable(const bool resize)
Definition: window.cpp:627
void widgetHidden(const Event &event)
Definition: window.cpp:725
ContainerPlacer getPlacer(const int x, const int y)
Definition: window.cpp:1391
virtual void close()
Definition: window.cpp:902
virtual void setVisible(Visible visible)
Definition: window.cpp:778
bool isWindowVisible() const
Definition: window.h:484
bool getOptionBool(const std::string &name, const bool def) const
Definition: window.cpp:1466
Layout & getLayout()
Definition: window.cpp:1365
void setWindowName(const std::string &name)
Definition: window.h:355
void setCaption(const std::string &caption)
Definition: window.h:531
void setMinHeight(const int height)
Definition: window.cpp:604
void mouseMoved(MouseEvent &event)
Definition: window.cpp:967
void postInit()
Definition: window.cpp:249
void setMinWidth(const int width)
Definition: window.cpp:591
void enableVisibleSound(bool b)
Definition: window.h:481
void widgetResized(const Event &event)
Definition: window.cpp:655
const std::string & getWindowName() const
Definition: window.h:361
void setCloseButton(const bool flag)
Definition: window.cpp:749
virtual void scheduleDelete()
Definition: window.cpp:831
void setStickyButtonLock(const bool sticky)
Definition: window.cpp:772
LayoutCell & place(const int x, const int y, Widget *const wg, const int w, const int h)
Definition: window.cpp:1384
void setDefaultSize()
Definition: window.cpp:1198
void loadWindowState()
Definition: window.cpp:1087
Configuration config
#define CREATEWIDGETR(type,...)
Definition: createwidget.h:36
#define new
Definition: debug_new.h:147
#define delete2(var)
Definition: delete2.h:25
const bool Equipm_true
Definition: equipm.h:30
const bool Equipped_true
Definition: equipped.h:30
const bool ForceQuantity_false
Definition: forcequantity.h:30
#define FOR_EACH(type, iter, array)
Definition: foreach.h:25
#define _(s)
Definition: gettext.h:35
Graphics * mainGraphics
Definition: graphics.cpp:109
Gui * gui
Definition: gui.cpp:111
InputManager inputManager
Net::InventoryHandler * inventoryHandler
Definition: net.cpp:89
InventoryType ::T InventoryTypeT
Definition: inventorytype.h:42
InventoryWindow * inventoryWindow
InsertCardListener insertCardListener
InventoryWindow * cartWindow
InventoryWindow * storageWindow
ItemPopup * itemPopup
Definition: itempopup.cpp:64
#define nullptr
Definition: localconsts.h:45
#define A_UNUSED
Definition: localconsts.h:160
const bool LoseFocusOnTab_true
const bool Modal_false
Definition: modal.h:30
const bool Modal_true
Definition: modal.h:30
bool info(InputEvent &event)
Definition: commands.cpp:57
@ CART_TOTAL_WEIGHT
Definition: attributes.h:64
@ CART_MAX_WEIGHT
Definition: attributes.h:65
@ TOTAL_WEIGHT
Definition: attributes.h:39
int size()
Definition: emotedb.cpp:306
@ WINDOW_EQUIPMENT
Definition: inputaction.h:95
const StringVect & getTags()
Definition: itemdb.cpp:749
int getTagId(const std::string &tagName)
Definition: itemdb.cpp:754
@ Card
Definition: itemtype.h:35
void useEquipItem(const Item *const item, const int16_t useType, const Sfx sfx)
Definition: playerinfo.cpp:262
void dropItem(const Item *const item, const int amount, const Sfx sfx)
Definition: playerinfo.cpp:354
void useEquipItem2(const Item *const item, const int16_t useType, const Sfx sfx)
Definition: playerinfo.cpp:313
int32_t getAttribute(const AttributesT id)
Definition: playerinfo.cpp:102
bool isItemProtected(const int id)
Definition: playerinfo.cpp:515
Inventory * mInventory
Definition: playerinfo.cpp:59
std::string formatCurrency(const int value)
Definition: unitsdb.cpp:324
std::string formatWeight(const int value)
Definition: unitsdb.cpp:352
Net::NpcHandler * npcHandler
Definition: net.cpp:93
bool Opaque
Definition: opaque.h:30
PopupMenu * popupMenu
Definition: popupmenu.cpp:103
ConfirmDialog * confirmDlg
Definition: traderecv.cpp:49
SetupWindow * setupWindow
Definition: setupwindow.cpp:64
const bool Sfx_true
Definition: sfx.h:30
const bool ShowEmptyRows_false
Definition: showemptyrows.h:30
static const std::string SOUND_REQUEST
Definition: sound.h:29
std::string strprintf(const char *const format,...)
std::vector< std::string > StringVect
Definition: stringvector.h:29
TextPopup * textPopup
Definition: textpopup.cpp:33
TradeWindow * tradeWindow
Definition: tradewindow.cpp:65
bool Visible
Definition: visible.h:30
const bool Visible_false
Definition: visible.h:30
const bool Visible_true
Definition: visible.h:30
WindowContainer * windowContainer