summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gui/inventorywindow.cpp104
-rw-r--r--src/gui/inventorywindow.h26
-rw-r--r--src/gui/storagewindow.cpp32
-rw-r--r--src/gui/storagewindow.h10
-rw-r--r--src/inventory.cpp35
-rw-r--r--src/inventory.h29
-rw-r--r--src/localplayer.cpp15
-rw-r--r--src/localplayer.h6
8 files changed, 144 insertions, 113 deletions
diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp
index 701558a9..6291d524 100644
--- a/src/gui/inventorywindow.cpp
+++ b/src/gui/inventorywindow.cpp
@@ -53,9 +53,8 @@
#include <string>
-InventoryWindow::InventoryWindow(int invSize):
+InventoryWindow::InventoryWindow():
Window(_("Inventory")),
- mMaxSlots(invSize),
mSplit(false),
mItemDesc(false)
{
@@ -90,10 +89,6 @@ InventoryWindow::InventoryWindow(int invSize):
gcn::ScrollArea *invenScroll = new ScrollArea(mItems);
invenScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
- mTotalWeight = -1;
- mMaxWeight = -1;
- mUsedSlots = -1;
-
mSlotsLabel = new Label(_("Slots:"));
mWeightLabel = new Label(_("Weight:"));
@@ -113,45 +108,17 @@ InventoryWindow::InventoryWindow(int invSize):
Layout &layout = getLayout();
layout.setRowHeight(1, Layout::AUTO_SET);
+ player_node->getInventory()->addInventoyListener(this);
+
loadWindowState();
+ updateWeight();
+ slotsChanged(player_node->getInventory());
}
InventoryWindow::~InventoryWindow()
{
}
-void InventoryWindow::logic()
-{
- if (!isVisible())
- return;
-
- Window::logic();
-
- // It would be nicer if this update could be event based, needs some
- // redesign of InventoryWindow and ItemContainer probably.
- updateButtons();
-
- const int usedSlots = player_node->getInventory()->getNumberOfSlotsUsed();
-
- if (mMaxWeight != player_node->getMaxWeight() ||
- mTotalWeight != player_node->getTotalWeight() ||
- mUsedSlots != usedSlots)
- {
- mTotalWeight = player_node->getTotalWeight();
- mMaxWeight = player_node->getMaxWeight();
- mUsedSlots = usedSlots;
-
- // Adjust progress bars
- mSlotsBar->setProgress((float) mUsedSlots / mMaxSlots);
- mWeightBar->setProgress((float) mTotalWeight / mMaxWeight);
-
- mSlotsBar->setText(strprintf("%d/%d", mUsedSlots, mMaxSlots));
- mWeightBar->setText(strprintf("%s/%s",
- Units::formatWeight(mTotalWeight).c_str(),
- Units::formatWeight(mMaxWeight).c_str()));
- }
-}
-
void InventoryWindow::action(const gcn::ActionEvent &event)
{
if (event.getId() == "outfit")
@@ -255,39 +222,29 @@ void InventoryWindow::keyReleased(gcn::KeyEvent &event)
void InventoryWindow::valueChanged(const gcn::SelectionEvent &event)
{
- if (mSplit && Net::getInventoryHandler()->canSplit(mItems->getSelectedItem()))
- {
- Item *item = mItems->getSelectedItem();
+ Item *item = mItems->getSelectedItem();
- if (item)
- ItemAmountWindow::showWindow(ItemAmountWindow::ItemSplit, this, item,
- (item->getQuantity() - 1));
+ if (mSplit && Net::getInventoryHandler()->
+ canSplit(mItems->getSelectedItem()) && item)
+ {
+ ItemAmountWindow::showWindow(ItemAmountWindow::ItemSplit, this, item,
+ (item->getQuantity() - 1));
}
-}
-
-void InventoryWindow::setSplitAllowed(bool allowed)
-{
- mSplitButton->setVisible(allowed);
-}
-
-void InventoryWindow::updateButtons()
-{
- const Item *selectedItem = mItems->getSelectedItem();
-
- if (!selectedItem || selectedItem->getQuantity() == 0)
+ if (!item || item->getQuantity() == 0)
{
mUseButton->setEnabled(false);
mDropButton->setEnabled(false);
+
return;
}
mUseButton->setEnabled(true);
mDropButton->setEnabled(true);
- if (selectedItem->isEquipment())
+ if (item->isEquipment())
{
- if (selectedItem->isEquipped())
+ if (item->isEquipped())
mUseButton->setCaption(_("Unequip"));
else
mUseButton->setCaption(_("Equip"));
@@ -297,13 +254,40 @@ void InventoryWindow::updateButtons()
mUseButton->setCaption(_("Use"));
}
- if (selectedItem->getQuantity() > 1)
+ if (item->getQuantity() > 1)
mDropButton->setCaption(_("Drop..."));
else
mDropButton->setCaption(_("Drop"));
- if (Net::getInventoryHandler()->canSplit(selectedItem))
+ if (Net::getInventoryHandler()->canSplit(item))
mSplitButton->setEnabled(true);
else
mSplitButton->setEnabled(false);
}
+
+
+void InventoryWindow::setSplitAllowed(bool allowed)
+{
+ mSplitButton->setVisible(allowed);
+}
+
+void InventoryWindow::updateWeight()
+{
+ int total = player_node->getTotalWeight();
+ int max = player_node->getMaxWeight();
+
+ // Adjust progress bar
+ mWeightBar->setProgress((float) total / max);
+ mWeightBar->setText(strprintf("%s/%s", Units::formatWeight(total).c_str(),
+ Units::formatWeight(max).c_str()));
+}
+
+void InventoryWindow::slotsChanged(Inventory* inventory)
+{
+ const int usedSlots = player_node->getInventory()->getNumberOfSlotsUsed();
+ const int maxSlots = player_node->getInventory()->getSize();
+
+ mSlotsBar->setProgress((float) usedSlots / maxSlots);
+
+ mSlotsBar->setText(strprintf("%d/%d", usedSlots, maxSlots));
+}
diff --git a/src/gui/inventorywindow.h b/src/gui/inventorywindow.h
index fdc5e55a..cfea130f 100644
--- a/src/gui/inventorywindow.h
+++ b/src/gui/inventorywindow.h
@@ -47,14 +47,14 @@ class TextBox;
class InventoryWindow : public Window,
public gcn::ActionListener,
public gcn::KeyListener,
- public gcn::SelectionListener
+ public gcn::SelectionListener,
+ public InventoryListener
{
public:
/**
* Constructor.
*/
- InventoryWindow(int invSize = Net::getInventoryHandler()
- ->getSize(Net::InventoryHandler::INVENTORY));
+ InventoryWindow();
/**
* Destructor.
@@ -62,11 +62,6 @@ class InventoryWindow : public Window,
~InventoryWindow();
/**
- * Logic (updates buttons and weight information).
- */
- void logic();
-
- /**
* Called when receiving actions from the widgets.
*/
void action(const gcn::ActionEvent &event);
@@ -100,17 +95,20 @@ class InventoryWindow : public Window,
* Sets whether the split button should be shown.
*/
void setSplitAllowed(bool allowed);
+
+ /**
+ * Updates the weight bar.
+ */
+ void updateWeight();
- private:
- void updateButtons(); /**< Updates button states. */
+ void slotsChanged(Inventory* inventory);
+ private:
ItemContainer *mItems;
std::string mWeight;
std::string mSlots;
- int mUsedSlots;
- int mTotalWeight;
- int mMaxWeight;
+
gcn::Button *mUseButton;
gcn::Button *mDropButton;
gcn::Button *mSplitButton;
@@ -121,8 +119,6 @@ class InventoryWindow : public Window,
ProgressBar *mWeightBar;
ProgressBar *mSlotsBar;
- int mMaxSlots;
-
bool mSplit;
bool mItemDesc;
};
diff --git a/src/gui/storagewindow.cpp b/src/gui/storagewindow.cpp
index 579725c4..c07653b1 100644
--- a/src/gui/storagewindow.cpp
+++ b/src/gui/storagewindow.cpp
@@ -104,6 +104,9 @@ StorageWindow::StorageWindow(Inventory *inventory):
instances.push_back(this);
setVisible(true);
+
+ mInventory->addInventoyListener(this);
+ slotsChanged(mInventory);
}
StorageWindow::~StorageWindow()
@@ -111,26 +114,6 @@ StorageWindow::~StorageWindow()
instances.remove(this);
}
-void StorageWindow::logic()
-{
- if (!isVisible())
- return;
-
- Window::logic();
-
- const int usedSlots = mInventory->getNumberOfSlotsUsed();
-
- if (mUsedSlots != usedSlots)
- {
- mUsedSlots = usedSlots;
-
- mSlotsBar->setProgress((float) mUsedSlots / mInventory->getSize());
-
- mSlotsBar->setText(strprintf("%d/%d", mUsedSlots,
- mInventory->getSize()));
- }
-}
-
void StorageWindow::action(const gcn::ActionEvent &event)
{
if (event.getId() == "store")
@@ -202,6 +185,15 @@ Item *StorageWindow::getSelectedItem() const
return mItems->getSelectedItem();
}
+void StorageWindow::slotsChanged(Inventory* inventory)
+{
+ const int usedSlots = mInventory->getNumberOfSlotsUsed();
+
+ mSlotsBar->setProgress((float) usedSlots / mInventory->getSize());
+
+ mSlotsBar->setText(strprintf("%d/%d", usedSlots, mInventory->getSize()));
+}
+
void StorageWindow::addStore(Item *item, int amount)
{
Net::getInventoryHandler()->moveItem(Net::InventoryHandler::INVENTORY,
diff --git a/src/gui/storagewindow.h b/src/gui/storagewindow.h
index 046b7613..8e09768d 100644
--- a/src/gui/storagewindow.h
+++ b/src/gui/storagewindow.h
@@ -43,7 +43,8 @@ class TextBox;
* \ingroup Interface
*/
class StorageWindow : public Window, gcn::ActionListener,
- gcn::SelectionListener
+ gcn::SelectionListener,
+ public InventoryListener
{
public:
/**
@@ -57,11 +58,6 @@ class StorageWindow : public Window, gcn::ActionListener,
~StorageWindow();
/**
- * Logic (updates buttons and weight information).
- */
- void logic();
-
- /**
* Called when receiving actions from the widgets.
*/
void action(const gcn::ActionEvent &event);
@@ -79,6 +75,8 @@ class StorageWindow : public Window, gcn::ActionListener,
*/
void close();
+ void slotsChanged(Inventory* inventory);
+
/**
* Add the specified ammount of the specified item to storage
*/
diff --git a/src/inventory.cpp b/src/inventory.cpp
index c9fb4fd7..8a6e79bb 100644
--- a/src/inventory.cpp
+++ b/src/inventory.cpp
@@ -34,7 +34,8 @@ struct SlotUsed : public std::unary_function<Item*, bool>
};
Inventory::Inventory(int size):
- mSize(size)
+ mSize(size),
+ mUsed(0)
{
mItems = new Item*[mSize];
std::fill_n(mItems, mSize, (Item*) 0);
@@ -83,6 +84,8 @@ void Inventory::setItem(int index, int id, int quantity, bool equipment)
Item *item = new Item(id, quantity, equipment);
item->setInvIndex(index);
mItems[index] = item;
+ mUsed++;
+ distributeSlotsChangedEvent();
}
else if (id > 0)
{
@@ -113,6 +116,11 @@ void Inventory::removeItemAt(int index)
{
delete mItems[index];
mItems[index] = 0;
+ mUsed--;
+ if (mUsed < 0) // Already at 0, no need to distribute event
+ mUsed = 0;
+ else
+ distributeSlotsChangedEvent();
}
bool Inventory::contains(Item *item) const
@@ -131,11 +139,6 @@ int Inventory::getFreeSlot() const
return (i == mItems + mSize) ? -1 : (i - mItems);
}
-int Inventory::getNumberOfSlotsUsed() const
-{
- return count_if(mItems, mItems + mSize, SlotUsed());
-}
-
int Inventory::getLastUsedSlot() const
{
for (int i = mSize - 1; i >= 0; i--)
@@ -144,3 +147,23 @@ int Inventory::getLastUsedSlot() const
return -1;
}
+
+void Inventory::addInventoyListener(InventoryListener* listener)
+{
+ mInventoryListeners.push_back(listener);
+}
+
+void Inventory::removeInventoyListener(InventoryListener* listener)
+{
+ mInventoryListeners.remove(listener);
+}
+
+void Inventory::distributeSlotsChangedEvent()
+{
+ InventoryListenerList::const_iterator i = mInventoryListeners.begin();
+ InventoryListenerList::const_iterator i_end = mInventoryListeners.end();
+ for (; i != i_end; i++)
+ {
+ (*i)->slotsChanged(this);
+ }
+}
diff --git a/src/inventory.h b/src/inventory.h
index 59da9ba0..0529d504 100644
--- a/src/inventory.h
+++ b/src/inventory.h
@@ -22,11 +22,27 @@
#ifndef INVENTORY_H
#define INVENTORY_H
+#include <list>
+
+class Inventory;
class Item;
+class InventoryListener
+{
+public:
+ virtual ~InventoryListener() {}
+
+ virtual void slotsChanged(Inventory* inventory) = 0;
+
+protected:
+ InventoryListener() {}
+};
+
class Inventory
{
public:
+ static const int NO_SLOT_INDEX = -1; /**< Slot has no index. */
+
/**
* Constructor.
*
@@ -95,18 +111,27 @@ class Inventory
/**
* Get the number of slots filled with an item
*/
- int getNumberOfSlotsUsed() const;
+ int getNumberOfSlotsUsed() const
+ { return mUsed; }
/**
* Returns the index of the last occupied slot or 0 if none occupied.
*/
int getLastUsedSlot() const;
- static const int NO_SLOT_INDEX = -1; /**< Slot has no index. */
+ void addInventoyListener(InventoryListener* listener);
+
+ void removeInventoyListener(InventoryListener* listener);
protected:
+ typedef std::list<InventoryListener*> InventoryListenerList;
+ InventoryListenerList mInventoryListeners;
+
+ void distributeSlotsChangedEvent();
+
Item **mItems; /**< The holder of items */
int mSize; /**< The max number of inventory items */
+ int mUsed; /**< THe number of slots in use */
};
#endif
diff --git a/src/localplayer.cpp b/src/localplayer.cpp
index 6d53cac3..d88b01f5 100644
--- a/src/localplayer.cpp
+++ b/src/localplayer.cpp
@@ -40,6 +40,7 @@
#include "text.h"
#include "gui/gui.h"
+#include "gui/inventorywindow.h"
#include "gui/ministatus.h"
#include "gui/skilldialog.h"
#include "gui/statuswindow.h"
@@ -759,6 +760,20 @@ void LocalPlayer::lowerAttribute(int attr)
Net::getPlayerHandler()->decreaseAttribute(attr);
}
+void LocalPlayer::setTotalWeight(int value)
+{
+ mTotalWeight = value;
+
+ inventoryWindow->updateWeight();
+}
+
+void LocalPlayer::setMaxWeight(int value)
+{
+ mMaxWeight = value;
+
+ inventoryWindow->updateWeight();
+}
+
void LocalPlayer::setAttributeBase(int num, int value, bool notify)
{
int old = mAttributeBase[num];
diff --git a/src/localplayer.h b/src/localplayer.h
index dce83ccd..c97bfc4b 100644
--- a/src/localplayer.h
+++ b/src/localplayer.h
@@ -302,14 +302,12 @@ class LocalPlayer : public Player
int getTotalWeight() const
{ return mTotalWeight; }
- void setTotalWeight(int value)
- { mTotalWeight = value; }
+ void setTotalWeight(int value);
int getMaxWeight() const
{ return mMaxWeight; }
- void setMaxWeight(int value)
- { mMaxWeight = value; }
+ void setMaxWeight(int value);
int getAttributeBase(int num)
{ return mAttributeBase[num]; }