Merge branch 'updateinventory' into 'master'
Some checks failed
Build and test / Ubuntu (push) Has been cancelled
Build and test / MacOS (push) Has been cancelled
Build and test / Read .env file and expose it as output (push) Has been cancelled
Build and test / Windows (2019) (push) Has been cancelled
Build and test / Windows (2022) (push) Has been cancelled

Draft: Update inventory window when item is added or removed into container by script

Closes #8431

See merge request OpenMW/openmw!4609
This commit is contained in:
Kuyondo 2025-04-24 12:25:34 +00:00
commit 76cac3edf7
12 changed files with 129 additions and 12 deletions

View file

@ -134,6 +134,8 @@ namespace MWGui
mItemView->resetScrollBars();
setTitle(actor.getClass().getName(actor));
mPtr.getClass().getContainerStore(mPtr).setContListener(this);
}
void CompanionWindow::onFrame(float dt)
@ -202,4 +204,9 @@ namespace MWGui
mSortModel = nullptr;
}
void CompanionWindow::updateItemView()
{
mItemView->update();
}
}

View file

@ -4,6 +4,8 @@
#include "referenceinterface.hpp"
#include "windowbase.hpp"
#include "../mwworld/containerstore.hpp"
namespace MWGui
{
namespace Widgets
@ -17,7 +19,7 @@ namespace MWGui
class SortFilterItemModel;
class CompanionItemModel;
class CompanionWindow : public WindowBase, public ReferenceInterface
class CompanionWindow : public WindowBase, public ReferenceInterface, public MWWorld::ContainerStoreListener
{
public:
CompanionWindow(DragAndDrop* dragAndDrop, MessageBoxManager* manager);
@ -30,6 +32,11 @@ namespace MWGui
void onFrame(float dt) override;
void clear() override { resetReference(); }
void updateItemView();
void itemAdded(const MWWorld::ConstPtr& item, int count) override { updateItemView(); }
void itemRemoved(const MWWorld::ConstPtr& item, int count) override { updateItemView(); }
std::string_view getWindowIdForLua() const override { return "Companion"; }
private:

View file

@ -160,6 +160,8 @@ namespace MWGui
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton);
setTitle(container.getClass().getName(container));
mPtr.getClass().getContainerStore(mPtr).setContListener(this);
}
void ContainerWindow::resetReference()
@ -320,4 +322,9 @@ namespace MWGui
if (mModel && mModel->usesContainer(ptr))
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
}
void ContainerWindow::updateItemView()
{
mItemView->update();
}
}

View file

@ -6,6 +6,8 @@
#include "itemmodel.hpp"
#include "../mwworld/containerstore.hpp"
namespace MyGUI
{
class Gui;
@ -21,7 +23,7 @@ namespace MWGui
namespace MWGui
{
class ContainerWindow : public WindowBase, public ReferenceInterface
class ContainerWindow : public WindowBase, public ReferenceInterface, public MWWorld::ContainerStoreListener
{
public:
ContainerWindow(DragAndDrop* dragAndDrop);
@ -38,6 +40,11 @@ namespace MWGui
void treatNextOpenAsLoot() { mTreatNextOpenAsLoot = true; }
void updateItemView();
void itemAdded(const MWWorld::ConstPtr& item, int count) override { updateItemView(); }
void itemRemoved(const MWWorld::ConstPtr& item, int count) override { updateItemView(); }
std::string_view getWindowIdForLua() const override { return "Container"; }
private:

View file

@ -11,7 +11,6 @@
#include "controllers.hpp"
#include "inventorywindow.hpp"
#include "itemview.hpp"
#include "itemwidget.hpp"
#include "sortfilteritemmodel.hpp"
namespace MWGui
@ -72,25 +71,26 @@ namespace MWGui
mSourceSortModel->addDragItem(mItem.mBase, count);
}
ItemWidget* baseWidget = MyGUI::Gui::getInstance().createWidget<ItemWidget>(
mDraggedWidget = MyGUI::Gui::getInstance().createWidget<ItemWidget>(
"MW_ItemIcon", 0, 0, 42, 42, MyGUI::Align::Default, "DragAndDrop");
Controllers::ControllerFollowMouse* controller
= MyGUI::ControllerManager::getInstance()
.createItem(Controllers::ControllerFollowMouse::getClassTypeName())
->castType<Controllers::ControllerFollowMouse>();
MyGUI::ControllerManager::getInstance().addItem(baseWidget, controller);
MyGUI::ControllerManager::getInstance().addItem(mDraggedWidget, controller);
mDraggedWidget = baseWidget;
baseWidget->setItem(mItem.mBase);
baseWidget->setNeedMouseFocus(false);
baseWidget->setCount(count);
mDraggedWidget->setItem(mItem.mBase);
mDraggedWidget->setNeedMouseFocus(false);
mDraggedWidget->setCount(count);
sourceView->update();
MWBase::Environment::get().getWindowManager()->setDragDrop(true);
mIsOnDragAndDrop = true;
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->updateItemView();
}
void DragAndDrop::drop(ItemModel* targetModel, ItemView* targetView)
@ -124,6 +124,22 @@ namespace MWGui
mSourceView->update();
}
void DragAndDrop::update()
{
if (mIsOnDragAndDrop)
{
int count = mItem.mBase.getCellRef().getCount();
if (count < mDraggedCount)
{
mItem.mCount = count;
mDraggedCount = count;
mDraggedWidget->setCount(mDraggedCount);
mSourceSortModel->clearDragItems();
mSourceSortModel->addDragItem(mItem.mBase, mDraggedCount);
}
}
}
void DragAndDrop::onFrame()
{
if (mIsOnDragAndDrop && mItem.mBase.getCellRef().getCount() == 0)

View file

@ -2,6 +2,7 @@
#define OPENMW_MWGUI_DRAGANDDROP_H
#include "itemmodel.hpp"
#include "itemwidget.hpp"
namespace MyGUI
{
@ -18,7 +19,7 @@ namespace MWGui
{
public:
bool mIsOnDragAndDrop;
MyGUI::Widget* mDraggedWidget;
ItemWidget* mDraggedWidget;
ItemModel* mSourceModel;
ItemView* mSourceView;
SortFilterItemModel* mSourceSortModel;
@ -30,6 +31,7 @@ namespace MWGui
void startDrag(
int index, SortFilterItemModel* sortModel, ItemModel* sourceModel, ItemView* sourceView, int count);
void drop(ItemModel* targetModel, ItemView* targetView);
void update();
void onFrame();
void finish();

View file

@ -145,6 +145,8 @@ namespace MWGui
auto tradeModel = std::make_unique<TradeItemModel>(std::make_unique<InventoryItemModel>(mPtr), MWWorld::Ptr());
mTradeModel = tradeModel.get();
mPtr.getClass().getInventoryStore(mPtr).setContListener(this);
if (mSortModel) // reuse existing SortModel when possible to keep previous category/filter settings
mSortModel->setSourceModel(std::move(tradeModel));
else
@ -848,6 +850,21 @@ namespace MWGui
mPreview->rebuild();
}
void InventoryWindow::itemRemoved(const MWWorld::ConstPtr& item, int count)
{
if (mDragAndDrop->mIsOnDragAndDrop && mDragAndDrop->mItem.mBase == item)
mDragAndDrop->update();
if (mTrading)
{
mTradeModel->updateBorrowed();
MWBase::Environment::get().getWindowManager()->getTradeWindow()->getTradeModel()->updateBorrowed();
MWBase::Environment::get().getWindowManager()->getTradeWindow()->updateItemView();
}
updateItemView();
}
MyGUI::IntSize InventoryWindow::getPreviewViewportSize() const
{
const MyGUI::IntSize previewWindowSize = mAvatarImage->getSize();

View file

@ -5,6 +5,7 @@
#include "windowpinnablebase.hpp"
#include "../mwrender/characterpreview.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/ptr.hpp"
namespace osg
@ -30,7 +31,7 @@ namespace MWGui
class DragAndDrop;
class ItemModel;
class InventoryWindow : public WindowPinnableBase
class InventoryWindow : public WindowPinnableBase, public MWWorld::ContainerStoreListener
{
public:
InventoryWindow(DragAndDrop* dragAndDrop, osg::Group* parent, Resource::ResourceSystem* resourceSystem);
@ -62,6 +63,9 @@ namespace MWGui
void setGuiMode(GuiMode mode);
void itemAdded(const MWWorld::ConstPtr& item, int count) override { updateItemView(); }
void itemRemoved(const MWWorld::ConstPtr& item, int count) override;
/// Cycle to previous/next weapon
void cycle(bool next);

View file

@ -113,6 +113,25 @@ namespace MWGui
encumbrance = std::max(0.f, encumbrance);
}
void TradeItemModel::updateBorrowed()
{
auto update = [](std::vector<ItemStack>& list) {
for (auto it = list.begin(); it != list.end();)
{
size_t actualCount = it->mBase.getCellRef().getCount();
if (actualCount < it->mCount)
it->mCount = actualCount;
if (it->mCount == 0)
it = list.erase(it);
else
++it;
}
};
update(mBorrowedFromUs);
update(mBorrowedToUs);
}
void TradeItemModel::abort()
{
mBorrowedFromUs.clear();

View file

@ -31,6 +31,9 @@ namespace MWGui
void returnItemBorrowedFromUs(ModelIndex itemIndex, ItemModel* source, size_t count);
/// Update borrowed items in this model
void updateBorrowed();
/// Permanently transfers items that were borrowed to us from another model to this model
void transferItems();
/// Aborts trade

View file

@ -201,6 +201,9 @@ namespace MWGui
onFilterChanged(mFilterAll);
mFilterEdit->setCaption({});
for (const auto& source : itemSources)
source.getClass().getContainerStore(source).setContListener(this);
}
void TradeWindow::onFrame(float dt)
@ -643,4 +646,20 @@ namespace MWGui
if (mTradeModel && mTradeModel->usesContainer(ptr))
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Barter);
}
void TradeWindow::updateItemView()
{
mItemView->update();
}
void TradeWindow::itemRemoved(const MWWorld::ConstPtr& item, int count)
{
mTradeModel->updateBorrowed();
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getTradeModel()->updateBorrowed();
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->updateItemView();
updateItemView();
updateOffer();
}
}

View file

@ -4,6 +4,8 @@
#include "referenceinterface.hpp"
#include "windowbase.hpp"
#include "../mwworld/containerstore.hpp"
namespace Gui
{
class NumericEditBox;
@ -20,7 +22,7 @@ namespace MWGui
class SortFilterItemModel;
class TradeItemModel;
class TradeWindow : public WindowBase, public ReferenceInterface
class TradeWindow : public WindowBase, public ReferenceInterface, public MWWorld::ContainerStoreListener
{
public:
TradeWindow();
@ -42,6 +44,13 @@ namespace MWGui
void onDeleteCustomData(const MWWorld::Ptr& ptr) override;
TradeItemModel* getTradeModel() { return mTradeModel; }
void updateItemView();
void itemAdded(const MWWorld::ConstPtr& item, int count) override { updateItemView(); }
void itemRemoved(const MWWorld::ConstPtr& item, int count) override;
typedef MyGUI::delegates::MultiDelegate<> EventHandle_TradeDone;
EventHandle_TradeDone eventTradeDone;