diff options
-rw-r--r-- | src/gui/inventorywindow.cpp | 104 | ||||
-rw-r--r-- | src/gui/inventorywindow.h | 26 | ||||
-rw-r--r-- | src/gui/storagewindow.cpp | 32 | ||||
-rw-r--r-- | src/gui/storagewindow.h | 10 | ||||
-rw-r--r-- | src/inventory.cpp | 35 | ||||
-rw-r--r-- | src/inventory.h | 29 | ||||
-rw-r--r-- | src/localplayer.cpp | 15 | ||||
-rw-r--r-- | src/localplayer.h | 6 |
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]; } |