Mana
Loading...
Searching...
No Matches
inventorywindow.cpp
Go to the documentation of this file.
1/*
2 * The Mana Client
3 * Copyright (C) 2004-2009 The Mana World Development Team
4 * Copyright (C) 2009-2012 The Mana Developers
5 *
6 * This file is part of The Mana Client.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include "gui/inventorywindow.h"
23
24#include "client.h"
25#include "inventory.h"
26#include "item.h"
27#include "units.h"
28#include "keyboardconfig.h"
29#include "playerinfo.h"
30
32#include "gui/setup.h"
33#include "gui/viewport.h"
34
35#include "gui/widgets/button.h"
37#include "gui/widgets/label.h"
38#include "gui/widgets/layout.h"
41
42#include "resources/iteminfo.h"
43#include "resources/theme.h"
44
45#include "utils/gettext.h"
46#include "utils/stringutils.h"
47
48#include <guichan/font.hpp>
49#include <guichan/mouseinput.hpp>
50
51#include <string>
52
54
56 Window(inventory->isMainInventory() ? _("Inventory") : _("Storage")),
57 mInventory(inventory),
58 mFilterText(new TextField)
59{
61
62 setWindowName(isMainInventory() ? "Inventory" : "Storage");
64 setResizable(true);
65 setCloseButton(true);
66 setSaveVisible(true);
67
69 setMinWidth(316);
70 setMinHeight(179);
71 addKeyListener(this);
72
73 mFilterText->setWidth(150);
74 mFilterText->addKeyListener(this);
75
78
79 auto invenScroll = new ScrollArea(mItems);
80 invenScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
81
82 mSlotsLabel = new Label(_("Slots:"));
83 mFilterLabel = new Label(_("Search:"));
84 mSlotsBar = new ProgressBar(0.0f, 100, 20, Theme::PROG_INVY_SLOTS);
85
86 if (isMainInventory())
87 {
88 std::string equip = _("Equip");
89 std::string use = _("Use");
90 std::string unequip = _("Unequip");
91
92 std::string longestUseString = getFont()->getWidth(equip) >
93 getFont()->getWidth(use) ? equip : use;
94
95 if (getFont()->getWidth(longestUseString) <
96 getFont()->getWidth(unequip))
97 {
98 longestUseString = unequip;
99 }
100
101 mEquipButton = new Button(_("Equip"), "equip", this);
102 mUseButton = new Button(_("Activate"), "activate", this);
103 mDropButton = new Button(_("Drop..."), "drop", this);
104 mOutfitButton = new Button(_("Outfits"), "outfit", this);
105
106 mWeightLabel = new Label(_("Weight:"));
107 mWeightBar = new ProgressBar(0.0f, 100, 20, Theme::PROG_WEIGHT);
108
109 place(0, 0, mWeightLabel).setPadding(3);
110 place(1, 0, mWeightBar, 3);
111 place(4, 0, mSlotsLabel).setPadding(3);
112 place(5, 0, mSlotsBar, 3);
113 place(0, 1, mFilterLabel, 4);
114 place(1, 1, mFilterText, 4);
115 place(0, 2, invenScroll, 8).setPadding(3);
116 place(0, 3, mUseButton);
117 place(1, 3, mEquipButton);
118 place(3, 3, mDropButton);
119 place(7, 3, mOutfitButton);
120
121 updateWeight();
122 }
123 else
124 {
125 mStoreButton = new Button(_("Store"), "store", this);
126 mRetrieveButton = new Button(_("Retrieve"), "retrieve", this);
127
128 place(0, 0, mSlotsLabel).setPadding(3);
129 place(1, 0, mSlotsBar, 3);
130 place(0, 1, mFilterLabel).setPadding(3);
131 place(1, 1, mFilterText, 3);
132 place(0, 2, invenScroll, 4, 4);
133 place(0, 6, mStoreButton);
134 place(1, 6, mRetrieveButton);
135 }
136
137 Layout &layout = getLayout();
139
141
142 instances.push_back(this);
143
146
147 if (!isMainInventory())
148 {
149 setVisible(true);
151 }
152}
153
162
163void InventoryWindow::action(const gcn::ActionEvent &event)
164{
165 if (event.getId() == "outfit")
166 {
167 extern Window *outfitWindow;
168 outfitWindow->setVisible(!outfitWindow->isVisible());
169 if (outfitWindow->isVisible())
170 {
171 outfitWindow->requestMoveToTop();
172 }
173 }
174 else if (event.getId() == "store")
175 {
176 if (!inventoryWindow->isVisible()) return;
177
179 if (!item)
180 return;
181
183 }
184
185 Item *item = mItems->getSelectedItem();
186 if (!item)
187 return;
188
189 if (event.getId() == "activate")
190 {
191 item->doEvent(Event::DoUse);
192 }
193 else if (event.getId() == "equip")
194 {
195 if (item->isEquippable())
196 {
197 if (item->isEquipped())
199 else
200 item->doEvent(Event::DoEquip);
201 }
202 else
203 {
204 item->doEvent(Event::DoUse);
205 }
206 }
207 else if (event.getId() == "drop")
208 {
210 }
211 else if (event.getId() == "retrieve")
212 {
213 Item *item = mItems->getSelectedItem();
214 if (!item)
215 return;
216
218 item);
219 }
220}
221
226
227void InventoryWindow::widgetHidden(const gcn::Event &event)
228{
230 mItems->hidePopup();
231}
232
233void InventoryWindow::mouseClicked(gcn::MouseEvent &event)
234{
235 Window::mouseClicked(event);
236
237 Item *item = mItems->getSelectedItem();
238 if (!item)
239 return;
240
241 if (event.getSource() == mItems && isDoubleClick(item->getInvIndex())
242 && isMainInventory())
243 {
244 if (item->getInfo().activatable)
245 {
246 action(gcn::ActionEvent(mUseButton,
247 mUseButton->getActionEventId()));
248 }
249 else if (item->isEquippable())
250 {
251 action(gcn::ActionEvent(mEquipButton,
252 mEquipButton->getActionEventId()));
253 }
254 return;
255 }
256
257 if (event.getButton() == gcn::MouseEvent::RIGHT)
258 {
259 /* Convert relative to the window coordinates to absolute screen
260 * coordinates.
261 */
262 const int mx = event.getX() + getX();
263 const int my = event.getY() + getY();
264 viewport->showPopup(this, mx, my, item, isMainInventory());
265 }
266
267 if (event.getButton() == gcn::MouseEvent::LEFT)
268 {
270 {
272 {
274 event.setItem("item", item);
275 event.setInt("amount", item->getQuantity());
276 event.setInt("source", Inventory::INVENTORY);
277 event.setInt("destination", Inventory::STORAGE);
278 event.trigger(Event::ItemChannel);
279 }
280 else
281 {
283 event.setItem("item", item);
284 event.setInt("amount", item->getQuantity());
285 event.setInt("source", Inventory::STORAGE);
286 event.setInt("destination", Inventory::INVENTORY);
287 event.trigger(Event::ItemChannel);
288 }
289 }
290 }
291}
292
293void InventoryWindow::keyReleased(gcn::KeyEvent &event)
294{
295 if (isInputFocused())
296 mItems->setFilter(mFilterText->getText());
297}
298
299void InventoryWindow::valueChanged(const gcn::SelectionEvent &event)
300{
302 return;
303
305}
306
308{
309 Item *item = mItems->getSelectedItem();
310
311 if (!item || item->getQuantity() == 0)
312 {
313 mUseButton->setEnabled(false);
314 mEquipButton->setEnabled(false);
315 mDropButton->setEnabled(false);
316 return;
317 }
318
319 mDropButton->setEnabled(true);
320
321 mEquipButton->setCaption(item->isEquipped() ? _("Unequip") : _("Equip"));
322 mEquipButton->setEnabled(item->isEquippable());
323 mEquipButton->adjustSize();
324
325 mUseButton->setEnabled(item->getInfo().activatable);
326
327 mDropButton->setCaption(item->getQuantity() > 1 ? _("Drop...") : _("Drop"));
328 mDropButton->adjustSize();
329}
330
332{
333 if (this == inventoryWindow)
334 {
335 setVisible(false);
336 }
337 else
338 {
340 event.setInt("type", mInventory->getType());
341 event.trigger(Event::ItemChannel);
343 }
344}
345
346void InventoryWindow::event(Event::Channel channel, const Event &event)
347{
348 if (event.getType() == Event::UpdateAttribute)
349 {
350 const int id = event.getInt("id");
351 if (id == TOTAL_WEIGHT || id == MAX_WEIGHT)
352 updateWeight();
353 }
354}
355
357{
358 if (!isMainInventory())
359 return;
360
361 const int total = PlayerInfo::getAttribute(TOTAL_WEIGHT);
362 const int max = PlayerInfo::getAttribute(MAX_WEIGHT);
363
364 if (max <= 0)
365 return;
366
367 // Adjust progress bar
368 mWeightBar->setProgress((float) total / max);
369 mWeightBar->setText(strprintf("%s/%s", Units::formatWeight(total).c_str(),
370 Units::formatWeight(max).c_str()));
371}
372
374{
375 return mFilterText->isFocused();
376}
377
379{
380 for (auto instance : instances)
381 if (instance->isInputFocused())
382 return true;
383
384 return false;
385}
386
388{
389 if (inventory == mInventory)
390 {
391 const int usedSlots = mInventory->getNumberOfSlotsUsed();
392 const int maxSlots = mInventory->getSize();
393
394 mSlotsBar->setProgress((float) usedSlots / maxSlots);
395 mSlotsBar->setText(strprintf("%d/%d", usedSlots, maxSlots));
396 }
397}
Button widget.
Definition button.h:38
void listen(Event::Channel channel)
Definition event.h:42
@ DoUse
Definition event.h:79
@ DoCloseInventory
Definition event.h:74
@ UpdateAttribute
Definition event.h:99
@ DoMove
Definition event.h:77
@ DoEquip
Definition event.h:76
@ DoUnequip
Definition event.h:78
Channel
Definition event.h:45
@ AttributesChannel
Definition event.h:47
@ ItemChannel
Definition event.h:53
gcn::Button * mRetrieveButton
void updateButtons()
Updates the buttons.
void mouseClicked(gcn::MouseEvent &event) override
Handles the mouse clicks.
InventoryWindow(Inventory *inventory)
gcn::Label * mSlotsLabel
static WindowList instances
gcn::Label * mWeightLabel
void keyReleased(gcn::KeyEvent &event) override
Handles the key releases.
~InventoryWindow() override
gcn::Button * mStoreButton
ItemContainer * mItems
gcn::Button * mEquipButton
void valueChanged(const gcn::SelectionEvent &event) override
Updates labels to currently selected item.
void widgetHidden(const gcn::Event &event) override
Handles closing of the window.
bool isMainInventory() const
bool isInputFocused() const
static bool isAnyInputFocused()
void event(Event::Channel channel, const Event &event) override
gcn::Button * mDropButton
ProgressBar * mSlotsBar
gcn::Button * mOutfitButton
Inventory * mInventory
void updateWeight()
Updates the weight bar.
void action(const gcn::ActionEvent &event) override
Called when receiving actions from the widgets.
void slotsChanged(Inventory *inventory) override
std::list< InventoryWindow * > WindowList
gcn::Label * mFilterLabel
void close() override
Closes the Storage Window, as well as telling the server that the window has been closed.
ProgressBar * mWeightBar
Item * getSelectedItem() const
Returns the selected item.
TextField * mFilterText
gcn::Button * mUseButton
int getType() const
Definition inventory.h:126
bool isMainInventory() const
Definition inventory.h:129
void removeInventoryListener(InventoryListener *listener)
void addInventoryListener(InventoryListener *listener)
int getSize() const
Returns the size that this instance is configured for.
Definition inventory.h:67
int getNumberOfSlotsUsed() const
Get the number of slots filled with an item.
Definition inventory.h:115
static void showWindow(Usage usage, Window *parent, Item *item, int maxRange=0)
Creates the dialog, or bypass it if there aren't enough items.
An item container.
void setFilter(const std::string &filter)
Sets item filter.
void addSelectionListener(gcn::SelectionListener *listener)
Adds a listener to the list that's notified each time a change to the selection occurs.
Item * getSelectedItem() const
Returns the selected item.
bool activatable
Whether this item can be activated.
Definition iteminfo.h:134
Represents one or more instances of a certain item type.
Definition item.h:35
void doEvent(Event::Type eventType)
Definition item.cpp:54
bool isEquipped() const
Returns whether this item is equipped.
Definition item.h:79
int getQuantity() const
Returns the number of items.
Definition item.h:69
int getInvIndex() const
Returns the inventory index of this item.
Definition item.h:94
bool isEquippable() const
Returns whether this item is equippable.
Definition item.cpp:69
const ItemInfo & getInfo() const
Returns information about this item type.
Definition item.h:103
bool isKeyActive(int index) const
Checks if the key is active, by providing the key function index.
Label widget.
Definition label.h:34
void setRowHeight(int n, int h)
Definition layout.h:221
LayoutCell & setPadding(int p)
Sets the padding around the cell content.
Definition layout.h:179
This class is an helper for setting the position of widgets.
Definition layout.h:281
@ AUTO_SET
Uses the share as the new size.
Definition layout.h:304
A progress bar.
Definition progressbar.h:34
void setProgress(float progress)
Sets the current progress.
void setText(const std::string &text)
Sets the text shown on the progress bar.
Definition progressbar.h:82
A scroll area.
Definition scrollarea.h:38
void registerWindowForReset(Window *window)
Enables the Reset Windows button.
Definition setup.cpp:108
A text field.
Definition textfield.h:72
@ PROG_INVY_SLOTS
Definition theme.h:274
@ PROG_WEIGHT
Definition theme.h:275
static std::string formatWeight(int value)
Formats the given number in the correct weight/mass format.
Definition units.cpp:221
void showPopup(Window *parent, int x, int y, Item *item, bool isInventory=true, bool canDrop=true)
Shows a popup for an item.
Definition viewport.cpp:538
A window.
Definition window.h:59
virtual void setVisible(bool visible)
Overloads window setVisible by Guichan to allow sticky window handling.
Definition window.cpp:282
void setMinHeight(int height)
Sets the minimum height of the window.
Definition window.cpp:197
Layout & getLayout()
Gets the layout handler for this window.
Definition window.cpp:714
void setWindowName(const std::string &name)
Sets the name of the window.
Definition window.h:272
void setResizable(bool resize)
Sets whether or not the window can be resized.
Definition window.cpp:212
void widgetHidden(const gcn::Event &event) override
Called whenever the widget is hidden.
Definition window.cpp:248
void setSaveVisible(bool save)
Sets whether the window will save it's visibility.
Definition window.h:225
LayoutCell & place(int x, int y, gcn::Widget *, int w=1, int h=1)
Adds a widget to the window and sets it at given cell.
Definition window.cpp:737
void scheduleDelete()
Schedule this window for deletion.
Definition window.cpp:299
void setCloseButton(bool flag)
Sets whether or not the window has a close button.
Definition window.cpp:262
void setDefaultSize()
Set the default win pos and size to the current ones.
Definition window.cpp:545
void loadWindowState()
Reads the position (and the size for resizable windows) in the configuration based on the given strin...
Definition window.cpp:467
void setMinWidth(int width)
Sets the minimum width of the window.
Definition window.cpp:192
bool isDoubleClick(int selected)
Returns whether this call and the last call were done for the same selected index and within a short ...
Definition client.cpp:126
KeyboardConfig keyboard
Definition client.cpp:101
OutfitWindow * outfitWindow
Definition game.cpp:106
Viewport * viewport
Viewport on the map.
Definition game.cpp:115
#define _(s)
Definition gettext.h:38
InventoryWindow * inventoryWindow
Definition game.cpp:96
int getStorageCount()
Returns the number of currently open storage windows.
int getAttribute(int id)
Returns the value of the given attribute.
void setStorageCount(int count)
Sets the number of currently open storage windows.
@ MAX_WEIGHT
Definition playerinfo.h:35
@ TOTAL_WEIGHT
Definition playerinfo.h:35
Setup * setupWindow
Definition setup.cpp:120
std::string strprintf(char const *format,...)
A safe version of sprintf that returns a std::string of the result.