#ifndef MWGUI_ITEM_MODEL_H #define MWGUI_ITEM_MODEL_H #include #include "../mwworld/ptr.hpp" namespace MWGui { class ItemModel; /// @brief A single item stack managed by an item model struct ItemStack { ItemStack(const MWWorld::Ptr& base, ItemModel* creator, size_t count); ItemStack(); ///< like operator==, only without checking mType enum Type { Type_Barter, Type_Equipped, Type_Normal }; Type mType; enum Flags { Flag_Enchanted = (1 << 0), Flag_Bound = (1 << 1) }; int mFlags; ItemModel* mCreator; size_t mCount; MWWorld::Ptr mBase; }; bool operator==(const ItemStack& left, const ItemStack& right); /// @brief The base class that all item models should derive from. class ItemModel { public: ItemModel(); virtual ~ItemModel() {} typedef int ModelIndex; // -1 means invalid index /// Throws for invalid index or out of range index virtual ItemStack getItem(ModelIndex index) = 0; /// The number of items in the model, this specifies the range of indices you can pass to /// the getItem function (but this range is only valid until the next call to update()) virtual size_t getItemCount() = 0; /// Returns an invalid index if the item was not found virtual ModelIndex getIndex(const ItemStack& item) = 0; /// Rebuild the item model, this will invalidate existing model indices virtual void update() = 0; /// Move items from this model to \a otherModel. /// @note Derived implementations may return an empty Ptr if the move was unsuccessful. virtual MWWorld::Ptr moveItem(const ItemStack& item, size_t count, ItemModel* otherModel); virtual MWWorld::Ptr copyItem(const ItemStack& item, size_t count, bool allowAutoEquip = true) = 0; virtual void removeItem(const ItemStack& item, size_t count) = 0; /// Is the player allowed to use items from this item model? (default true) virtual bool allowedToUseItems() const; virtual void onClose() {} virtual bool onDropItem(const MWWorld::Ptr& item, int count); virtual bool onTakeItem(const MWWorld::Ptr& item, int count); virtual bool usesContainer(const MWWorld::Ptr& container) = 0; private: ItemModel(const ItemModel&); ItemModel& operator=(const ItemModel&); }; /// @brief A proxy item model can be used to filter or rearrange items from a source model (or even add new items to /// it). The neat thing is that this does not actually alter the source model. class ProxyItemModel : public ItemModel { public: ProxyItemModel() = default; virtual ~ProxyItemModel() = default; bool allowedToUseItems() const override; void onClose() override; bool onDropItem(const MWWorld::Ptr& item, int count) override; bool onTakeItem(const MWWorld::Ptr& item, int count) override; MWWorld::Ptr copyItem(const ItemStack& item, size_t count, bool allowAutoEquip = true) override; void removeItem(const ItemStack& item, size_t count) override; ModelIndex getIndex(const ItemStack& item) override; /// @note Takes ownership of the passed pointer. void setSourceModel(std::unique_ptr sourceModel); ModelIndex mapToSource(ModelIndex index); ModelIndex mapFromSource(ModelIndex index); bool usesContainer(const MWWorld::Ptr& container) override; protected: std::unique_ptr mSourceModel; }; } #endif