diff options
-rw-r--r-- | src/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/gui/inventorywindow.cpp | 58 | ||||
-rw-r--r-- | src/gui/inventorywindow.h | 4 | ||||
-rw-r--r-- | src/gui/widgets/horizontcontainer.cpp | 53 | ||||
-rw-r--r-- | src/gui/widgets/horizontcontainer.h | 54 | ||||
-rw-r--r-- | src/gui/widgets/inventoryfilter.cpp | 54 | ||||
-rw-r--r-- | src/gui/widgets/inventoryfilter.h | 56 | ||||
-rw-r--r-- | src/gui/widgets/itemcontainer.cpp | 62 | ||||
-rw-r--r-- | src/gui/widgets/itemcontainer.h | 6 | ||||
-rw-r--r-- | src/item.cpp | 16 | ||||
-rw-r--r-- | src/item.h | 5 | ||||
-rw-r--r-- | src/resources/itemdb.cpp | 40 | ||||
-rw-r--r-- | src/resources/itemdb.h | 4 | ||||
-rw-r--r-- | src/resources/iteminfo.h | 11 |
15 files changed, 405 insertions, 26 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bb7b6e4b2..2dfbfcb7c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -153,10 +153,14 @@ SET(SRCS gui/widgets/emoteshortcutcontainer.h gui/widgets/flowcontainer.cpp gui/widgets/flowcontainer.h + gui/widgets/horizontcontainer.cpp + gui/widgets/horizontcontainer.h gui/widgets/icon.cpp gui/widgets/icon.h gui/widgets/inttextfield.cpp gui/widgets/inttextfield.h + gui/widgets/inventoryfilter.cpp + gui/widgets/inventoryfilter.h gui/widgets/itemcontainer.cpp gui/widgets/itemcontainer.h gui/widgets/itemlinkhandler.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 311f0d8e2..29520258b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -49,10 +49,14 @@ manaplus_SOURCES += gui/widgets/avatarlistbox.cpp \ gui/widgets/emoteshortcutcontainer.h \ gui/widgets/flowcontainer.cpp \ gui/widgets/flowcontainer.h \ + gui/widgets/horizontcontainer.cpp \ + gui/widgets/horizontcontainer.h \ gui/widgets/icon.cpp \ gui/widgets/icon.h \ gui/widgets/inttextfield.cpp \ gui/widgets/inttextfield.h \ + gui/widgets/inventoryfilter.cpp \ + gui/widgets/inventoryfilter.h \ gui/widgets/itemcontainer.cpp \ gui/widgets/itemcontainer.h \ gui/widgets/itemlinkhandler.cpp \ diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp index abb702005..a02fab4e6 100644 --- a/src/gui/inventorywindow.cpp +++ b/src/gui/inventorywindow.cpp @@ -35,10 +35,13 @@ #include "gui/viewport.h" #include "gui/widgets/button.h" +#include "gui/widgets/container.h" +#include "gui/widgets/inventoryfilter.h" #include "gui/widgets/itemcontainer.h" #include "gui/widgets/label.h" #include "gui/widgets/layout.h" #include "gui/widgets/progressbar.h" +#include "gui/widgets/radiobutton.h" #include "gui/widgets/scrollarea.h" #include "net/inventoryhandler.h" @@ -89,6 +92,16 @@ InventoryWindow::InventoryWindow(Inventory *inventory): mSlotsLabel = new Label(_("Slots:")); mSlotsBar = new ProgressBar(0.0f, 100, 20, Theme::PROG_INVY_SLOTS); + mFilter = new InventoryFilter(getWindowName(), 20, 10); + mFilter->addActionListener(this); + mFilter->setActionEventId("tags"); + + mFilterLabel = new Label(_("Filter:")); + + std::vector<std::string> tags = ItemDB::getTags(); + for (unsigned f = 0; f < tags.size(); f ++) + mFilter->add(tags[f]); + if (isMainInventory()) { std::string equip = _("Equip"); @@ -114,17 +127,21 @@ InventoryWindow::InventoryWindow(Inventory *inventory): mWeightLabel = new Label(_("Weight:")); mWeightBar = new ProgressBar(0.0f, 100, 20, Theme::PROG_WEIGHT); - place(0, 0, mWeightLabel).setPadding(3); + place(0, 0, mWeightLabel, 1).setPadding(3); place(1, 0, mWeightBar, 3); - place(4, 0, mSlotsLabel).setPadding(3); + place(4, 0, mSlotsLabel, 1).setPadding(3); place(5, 0, mSlotsBar, 2); - place(0, 1, invenScroll, 7).setPadding(3); - place(0, 2, mUseButton); - place(1, 2, mUseButton2); - place(2, 2, mDropButton); - place(4, 2, mSplitButton); - place(5, 2, mShopButton); - place(6, 2, mOutfitButton); + + place(0, 1, mFilterLabel, 1).setPadding(3); + place(1, 1, mFilter, 6).setPadding(3); + + place(0, 2, invenScroll, 7).setPadding(3); + place(0, 3, mUseButton); + place(1, 3, mUseButton2); + place(2, 3, mDropButton); + place(4, 3, mSplitButton); + place(5, 3, mShopButton); + place(6, 3, mOutfitButton); updateWeight(); } @@ -136,14 +153,18 @@ InventoryWindow::InventoryWindow(Inventory *inventory): place(0, 0, mSlotsLabel).setPadding(3); place(1, 0, mSlotsBar, 3); - place(0, 1, invenScroll, 4, 4); - place(0, 5, mStoreButton); - place(1, 5, mRetrieveButton); - place(3, 5, mCloseButton); + + place(0, 1, mFilterLabel, 1).setPadding(3); + place(1, 1, mFilter, 3).setPadding(3); + + place(0, 2, invenScroll, 4, 4); + place(0, 6, mStoreButton); + place(1, 6, mRetrieveButton); + place(3, 6, mCloseButton); } Layout &layout = getLayout(); - layout.setRowHeight(1, Layout::AUTO_SET); + layout.setRowHeight(2, Layout::AUTO_SET); mInventory->addInventoyListener(this); @@ -186,8 +207,7 @@ void InventoryWindow::action(const gcn::ActionEvent &event) outfitWindow->requestMoveToTop(); } } - - if (event.getId() == "shop") + else if (event.getId() == "shop") { if (shopWindow) { @@ -212,6 +232,12 @@ void InventoryWindow::action(const gcn::ActionEvent &event) ItemAmountWindow::showWindow(ItemAmountWindow::StoreAdd, this, item); } + else if (!event.getId().find("tag_") && mItems) + { + std::string tagName = event.getId().substr(4); + mItems->setFilter(ItemDB::getTagId(tagName)); +// logger->log("eventid: %s", tagName.c_str()); + } Item *item = mItems->getSelectedItem(); diff --git a/src/gui/inventorywindow.h b/src/gui/inventorywindow.h index 87f57eb9d..664a22f4b 100644 --- a/src/gui/inventorywindow.h +++ b/src/gui/inventorywindow.h @@ -42,6 +42,7 @@ class Item; class ItemContainer; +class InventoryFilter; class ProgressBar; class TextBox; @@ -143,9 +144,10 @@ class InventoryWindow : public Window, *mSplitButton, *mOutfitButton, *mShopButton, *mStoreButton, *mRetrieveButton, *mCloseButton; - gcn::Label *mWeightLabel, *mSlotsLabel; + gcn::Label *mWeightLabel, *mSlotsLabel, *mFilterLabel; ProgressBar *mWeightBar, *mSlotsBar; + InventoryFilter *mFilter; bool mSplit; }; diff --git a/src/gui/widgets/horizontcontainer.cpp b/src/gui/widgets/horizontcontainer.cpp new file mode 100644 index 000000000..6ecd3f933 --- /dev/null +++ b/src/gui/widgets/horizontcontainer.cpp @@ -0,0 +1,53 @@ +/* + * The Mana Client + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011 The ManaPlus Developers + * + * This file is part of The Mana Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/horizontcontainer.h" + +HorizontContainer::HorizontContainer(int height, int spacing): + mSpacing(spacing), + mCount(0), + mLastX(0) +{ + setHeight(height); + addWidgetListener(this); +} + +void HorizontContainer::add(gcn::Widget *widget) +{ + if (!widget) + return; + + Container::add(widget); + widget->setPosition(mLastX, 0); + mCount++; + mLastX += widget->getWidth() + mSpacing; +} + +void HorizontContainer::clear() +{ + Container::clear(); + + mCount = 0; +} + +void HorizontContainer::widgetResized(const gcn::Event &event _UNUSED_) +{ +} diff --git a/src/gui/widgets/horizontcontainer.h b/src/gui/widgets/horizontcontainer.h new file mode 100644 index 000000000..b8325a564 --- /dev/null +++ b/src/gui/widgets/horizontcontainer.h @@ -0,0 +1,54 @@ +/* + * The Mana Client + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011 The ManaPlus Developers + * + * This file is part of The Mana Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUI_HORIZONTCONTAINER_H +#define GUI_HORIZONTCONTAINER_H + +#include "gui/widgets/container.h" + +#include <guichan/widgetlistener.hpp> + +#ifdef __GNUC__ +#define _UNUSED_ __attribute__ ((unused)) +#else +#define _UNUSED_ +#endif + +/** + * A widget container. + * + * This container places it's contents veritcally. + */ +class HorizontContainer : public Container, public gcn::WidgetListener +{ + public: + HorizontContainer(int height, int spacing); + virtual void add(gcn::Widget *widget); + virtual void clear(); + void widgetResized(const gcn::Event &event); + + protected: + int mSpacing; + int mCount; + int mLastX; +}; + +#endif diff --git a/src/gui/widgets/inventoryfilter.cpp b/src/gui/widgets/inventoryfilter.cpp new file mode 100644 index 000000000..faceafa9e --- /dev/null +++ b/src/gui/widgets/inventoryfilter.cpp @@ -0,0 +1,54 @@ +/* + * The Mana Client + * Copyright (C) 2011 The ManaPlus Developers + * + * This file is part of The Mana Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/inventoryfilter.h" + +#include "gui/widgets/horizontcontainer.h" +#include "gui/widgets/radiobutton.h" + +#include "log.h" + +InventoryFilter::InventoryFilter(std::string group, int height, int spacing): + HorizontContainer(height, spacing), + mGroup(group) +{ +} + +void InventoryFilter::add(std::string tag) +{ + if (tag.empty()) + return; + + RadioButton *radio = new RadioButton(tag, mGroup, mCount == 0); + radio->adjustSize(); + radio->setActionEventId("tag_" + tag); + radio->addActionListener(this); + HorizontContainer::add(radio); +} + +void InventoryFilter::action(const gcn::ActionEvent &event) +{ + ActionListenerIterator iter; + for (iter = mActionListeners.begin(); + iter != mActionListeners.end(); ++iter) + { + (*iter)->action(event); + } +}
\ No newline at end of file diff --git a/src/gui/widgets/inventoryfilter.h b/src/gui/widgets/inventoryfilter.h new file mode 100644 index 000000000..28423413f --- /dev/null +++ b/src/gui/widgets/inventoryfilter.h @@ -0,0 +1,56 @@ +/* + * The Mana Client + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011 The ManaPlus Developers + * + * This file is part of The Mana Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUI_INVENTORYFILTER_H +#define GUI_INVENTORYFILTER_H + +#include <guichan/actionlistener.hpp> +#include <guichan/widgetlistener.hpp> + +#include "gui/widgets/horizontcontainer.h" + +#ifdef __GNUC__ +#define _UNUSED_ __attribute__ ((unused)) +#else +#define _UNUSED_ +#endif + +//class HorizontContainer; + +/** + * A widget container. + * + * This container places it's contents veritcally. + */ +class InventoryFilter : public HorizontContainer, public gcn::ActionListener +{ + public: + InventoryFilter(std::string group, int height, int spacing); + + void add(std::string tag); + + void action(const gcn::ActionEvent &event); + + private: + std::string mGroup; +}; + +#endif diff --git a/src/gui/widgets/itemcontainer.cpp b/src/gui/widgets/itemcontainer.cpp index 8b5b1914a..3f6a6b45c 100644 --- a/src/gui/widgets/itemcontainer.cpp +++ b/src/gui/widgets/itemcontainer.cpp @@ -65,7 +65,9 @@ ItemContainer::ItemContainer(Inventory *inventory, bool forceQuantity): mSelectionStatus(SEL_NONE), mForceQuantity(forceQuantity), mSwapItems(false), - mDescItems(false) + mDescItems(false), + mTag(0), + mShowMatrix(0) { mItemPopup = new ItemPopup; setFocusable(true); @@ -108,21 +110,29 @@ void ItemContainer::logic() void ItemContainer::draw(gcn::Graphics *graphics) { - if (!mInventory) + if (!mInventory || !mShowMatrix) return; Graphics *g = static_cast<Graphics*>(graphics); g->setFont(getFont()); - for (int i = 0; i < mGridColumns; i++) + int i = 0; + int j = 0; + +// int idx = 0; + + for (int j = 0; j < mGridRows; j++) { - for (int j = 0; j < mGridRows; j++) + for (int i = 0; i < mGridColumns; i++) { int itemX = i * BOX_WIDTH; int itemY = j * BOX_HEIGHT; - int itemIndex = (j * mGridColumns) + i; - Item *item = mInventory->getItem(itemIndex); + int itemIndex = j * mGridColumns + i; + if (mShowMatrix[itemIndex] < 0) + continue; + + Item *item = mInventory->getItem(mShowMatrix[itemIndex]); if (!item || item->getId() == 0) continue; @@ -385,6 +395,40 @@ void ItemContainer::adjustHeight() ++mGridRows; setHeight(mGridRows * BOX_HEIGHT); + + updateMatrix(); +} + +void ItemContainer::updateMatrix() +{ + delete mShowMatrix; + mShowMatrix = new int[mGridRows * mGridColumns]; + memset(mShowMatrix, -1, mGridRows * mGridColumns); + + int i = 0; + int j = 0; + + for (int idx = 0; idx < mInventory->getSize(); idx ++) + { +// int itemX = i * BOX_WIDTH; +// int itemY = j * BOX_HEIGHT; + int itemIndex = idx; + Item *item = mInventory->getItem(itemIndex); + + if (!item || item->getId() == 0 || !item->isHaveTag(mTag)) + continue; + + mShowMatrix[j * mGridColumns + i] = itemIndex; + + i ++; + if (i >= mGridColumns) + { + i = 0; + j ++; + } + if (j >= mGridRows) + break; + } } int ItemContainer::getSlotIndex(int x, int y) const @@ -473,3 +517,9 @@ void ItemContainer::moveHighlight(Direction direction) break; } } + +void ItemContainer::setFilter (int tag) +{ + mTag = tag; + updateMatrix(); +}
\ No newline at end of file diff --git a/src/gui/widgets/itemcontainer.h b/src/gui/widgets/itemcontainer.h index 8aaa236b4..9ce819534 100644 --- a/src/gui/widgets/itemcontainer.h +++ b/src/gui/widgets/itemcontainer.h @@ -119,6 +119,8 @@ class ItemContainer : public gcn::Widget, void removeSelectionListener(gcn::SelectionListener *listener) { mSelectionListeners.remove(listener); } + void setFilter (int tag); + private: enum Direction { @@ -173,6 +175,8 @@ class ItemContainer : public gcn::Widget, */ int getSlotIndex(int x, int y) const; + void updateMatrix(); + Inventory *mInventory; int mGridColumns, mGridRows; Image *mSelImg; @@ -183,8 +187,10 @@ class ItemContainer : public gcn::Widget, bool mSwapItems; bool mDescItems; int mDragPosX, mDragPosY; + int mTag; ItemPopup *mItemPopup; + int *mShowMatrix; typedef std::list<gcn::SelectionListener*> SelectionListenerList; typedef SelectionListenerList::iterator SelectionListenerIterator; diff --git a/src/item.cpp b/src/item.cpp index 94eaf383e..33d3916d3 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -62,7 +62,14 @@ void Item::setId(int id) mDrawImage->decRef(); ResourceManager *resman = ResourceManager::getInstance(); - SpriteDisplay display = getInfo().getDisplay(); + ItemInfo info = getInfo(); + mTags = info.getTags(); + logger->log("tag0=" + toString(mTags[1])); + +// for (int f = 0; f < mTags->size(); f ++) +// logger->log("tag: %d", (*mTags)[f]); + + SpriteDisplay display = info.getDisplay(); std::string imagePath = paths.getStringValue("itemIcons") + display.image; mImage = resman->getImage(imagePath); @@ -81,6 +88,13 @@ void Item::setId(int id) } } +bool Item::isHaveTag(int tagId) +{ + if (mTags.find(tagId) == mTags.end()) + return false; + return mTags[tagId] > 0; +} + Image *Item::getImage(int id) { ResourceManager *resman = ResourceManager::getInstance(); diff --git a/src/item.h b/src/item.h index 520028f8f..de19b2937 100644 --- a/src/item.h +++ b/src/item.h @@ -24,6 +24,8 @@ #include "resources/itemdb.h" +#include <map> + class Image; /** @@ -152,6 +154,8 @@ class Item static Image *getImage(int id); + bool isHaveTag(int tagId); + protected: int mId; /**< Item type id. */ Image *mImage; /**< Item image. */ @@ -162,6 +166,7 @@ class Item bool mInEquipment; /**< Item is in equipment */ int mRefine; /**< Item refine level. */ int mInvIndex; /**< Inventory index. */ + std::map <int, int> mTags; }; #endif diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp index 33978192f..a590dcac1 100644 --- a/src/resources/itemdb.cpp +++ b/src/resources/itemdb.cpp @@ -42,6 +42,8 @@ namespace ItemDB::NamedItemInfos mNamedItemInfos; ItemInfo *mUnknown; bool mLoaded = false; + std::vector<std::string> mTagNames; + std::map<std::string, int> mTags; } // Forward declarations @@ -149,6 +151,7 @@ void ItemDB::load() if (mLoaded) unload(); + int tagNum = 0; logger->log1("Initializing item database..."); mUnknown = new ItemInfo; @@ -168,6 +171,17 @@ void ItemDB::load() return; } + mTags.clear(); + mTagNames.clear(); + mTagNames.push_back("All"); + mTagNames.push_back("Usable"); + mTagNames.push_back("Unusable"); + mTagNames.push_back("Equipment"); + mTags["All"] = tagNum ++; + mTags["Usable"] = tagNum ++; + mTags["Unusable"] = tagNum ++; + mTags["Equipment"] = tagNum ++; + for_each_xml_child_node(node, rootNode) { if (!xmlStrEqual(node->name, BAD_CAST "item")) @@ -210,6 +224,20 @@ void ItemDB::load() itemInfo->setName(name.empty() ? _("unnamed") : name); itemInfo->setDescription(description); itemInfo->setType(itemTypeFromString(typeStr)); + itemInfo->addTag(mTags["All"]); + switch (itemInfo->getType()) + { + case ITEM_USABLE: + itemInfo->addTag(mTags["Usable"]); + break; + case ITEM_UNUSABLE: + itemInfo->addTag(mTags["Unusable"]); + break; + default: + itemInfo->addTag(mTags["Equipment"]); + break; + } + itemInfo->setView(view); itemInfo->setWeight(weight); itemInfo->setAttackAction(attackAction); @@ -315,6 +343,16 @@ void ItemDB::load() mLoaded = true; } +const std::vector<std::string> &ItemDB::getTags() +{ + return mTagNames; +} + +int ItemDB::getTagId(std::string tagName) +{ + return mTags[tagName]; +} + void ItemDB::unload() { logger->log1("Unloading item database..."); @@ -325,6 +363,8 @@ void ItemDB::unload() delete_all(mItemInfos); mItemInfos.clear(); mNamedItemInfos.clear(); + mTags.clear(); + mTagNames.clear(); mLoaded = false; } diff --git a/src/resources/itemdb.h b/src/resources/itemdb.h index 76e646c0f..19e36889e 100644 --- a/src/resources/itemdb.h +++ b/src/resources/itemdb.h @@ -23,6 +23,7 @@ #define ITEM_MANAGER_H #include <list> +#include <vector> #include <map> #include <string> @@ -49,6 +50,8 @@ namespace ItemDB */ void unload(); + const std::vector<std::string> &getTags(); + bool exists(int id); const ItemInfo &get(int id); @@ -60,6 +63,7 @@ namespace ItemDB const std::map<int, ItemInfo*> &getItemInfos(); + int getTagId(std::string tagName); struct Stat { Stat(const std::string &tag, diff --git a/src/resources/iteminfo.h b/src/resources/iteminfo.h index bb84193bb..19bba335d 100644 --- a/src/resources/iteminfo.h +++ b/src/resources/iteminfo.h @@ -207,6 +207,12 @@ class ItemInfo void setDrawPriority(int n) { mDrawPriority = n; } + std::map<int, int> getTags() + { return mTags; } + + void addTag(int tag) + { mTags[tag] = 1; } + protected: SpriteDisplay mDisplay; /**< Display info (like icon) */ std::string mName; @@ -233,10 +239,11 @@ class ItemInfo std::string mMissileParticle; /** Maps gender to sprite filenames. */ - std::map<int, std::string> mAnimationFiles; + std::map <int, std::string> mAnimationFiles; /** Stores the names of sounds to be played at certain event. */ - std::map< EquipmentSoundEvent, std::vector<std::string> > mSounds; + std::map < EquipmentSoundEvent, std::vector<std::string> > mSounds; + std::map <int,int> mTags; }; #endif |