Issue #290: Auto-Close MW-reference related GUI windows

actorid
scrawl 13 years ago
parent a7e6a142f9
commit f1d3978897

@ -28,7 +28,7 @@ add_openmw_dir (mwgui
dialogue_history window_base stats_window messagebox journalwindow charactercreation
map_window window_pinnable_base cursorreplace tooltips scrollwindow bookwindow list
formatting inventorywindow container hud countdialog tradewindow settingswindow
confirmationdialog alchemywindow
confirmationdialog alchemywindow referenceinterface
)
add_openmw_dir (mwdialogue

@ -171,7 +171,7 @@ namespace MWGui
// create a reference and add it to player inventory
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), result.first);
MWWorld::ContainerStore& store = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
MWWorld::ContainerStore& store = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
ref.getPtr().getRefData().setCount(1);
store.add(ref.getPtr());
@ -223,7 +223,7 @@ namespace MWGui
setFilter(ContainerBase::Filter_Ingredients);
// pick the best available apparatus
MWWorld::ContainerStore& store = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
MWWorld::ContainerStore& store = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
MWWorld::Ptr bestAlbemic;
MWWorld::Ptr bestMortarPestle;

@ -42,6 +42,8 @@ namespace MWGui
void removeIngredient(MyGUI::Widget* ingredient);
virtual void onReferenceUnavailable() { ; }
void update();
};
}

@ -264,16 +264,16 @@ void ContainerBase::onContainerClicked(MyGUI::Widget* _sender)
if(mDragAndDrop->mIsOnDragAndDrop) //drop item here
{
MWWorld::Ptr object = *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>();
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
if (mDragAndDrop->mDraggedFrom != this)
{
assert(object.getContainerStore() && "Item is not in a container!");
// check the container's Organic flag (if this is a container). container with Organic flag doesn't allow putting items inside
if (mContainer.getTypeName() == typeid(ESM::Container).name())
if (mPtr.getTypeName() == typeid(ESM::Container).name())
{
ESMS::LiveCellRef<ESM::Container, MWWorld::RefData>* ref = mContainer.get<ESM::Container>();
ESMS::LiveCellRef<ESM::Container, MWWorld::RefData>* ref = mPtr.get<ESM::Container>();
if (ref->base->flags & ESM::Container::Organic)
{
// user notification
@ -288,13 +288,13 @@ void ContainerBase::onContainerClicked(MyGUI::Widget* _sender)
// check that we don't exceed the allowed weight (only for containers, not for inventory)
if (!isInventory())
{
float capacity = MWWorld::Class::get(mContainer).getCapacity(mContainer);
float capacity = MWWorld::Class::get(mPtr).getCapacity(mPtr);
// try adding the item, and if weight is exceeded, just remove it again.
object.getRefData().setCount(mDragAndDrop->mDraggedCount);
MWWorld::ContainerStoreIterator it = containerStore.add(object);
float curWeight = MWWorld::Class::get(mContainer).getEncumbrance(mContainer);
float curWeight = MWWorld::Class::get(mPtr).getEncumbrance(mPtr);
if (curWeight > capacity)
{
it->getRefData().setCount(0);
@ -346,7 +346,7 @@ void ContainerBase::setFilter(ContainerBase::Filter filter)
void ContainerBase::openContainer(MWWorld::Ptr container)
{
mContainer = container;
mPtr = container;
drawItems();
}
@ -356,7 +356,7 @@ void ContainerBase::drawItems()
{
MyGUI::Gui::getInstance().destroyWidget(mContainerWidget->getChildAt(0));
}
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
int x = 0;
int y = 0;
@ -557,7 +557,7 @@ void ContainerBase::addBarteredItem(MWWorld::Ptr item, int count)
void ContainerBase::addItem(MWWorld::Ptr item, int count)
{
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
int origCount = item.getRefData().getCount();
@ -569,7 +569,7 @@ void ContainerBase::addItem(MWWorld::Ptr item, int count)
void ContainerBase::transferBoughtItems()
{
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
for (MWWorld::ContainerStoreIterator it(mBoughtItems.begin()); it != mBoughtItems.end(); ++it)
{
@ -587,7 +587,7 @@ void ContainerBase::returnBoughtItems(MWWorld::ContainerStore& store)
MWWorld::ContainerStore& ContainerBase::getContainerStore()
{
MWWorld::ContainerStore& store = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
MWWorld::ContainerStore& store = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
return store;
}
@ -651,7 +651,7 @@ void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender)
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
{
// transfer everything into the player's inventory
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWWorld::ContainerStore& playerStore = MWWorld::Class::get(player).getContainerStore(player);
@ -676,3 +676,8 @@ void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender)
MWBase::Environment::get().getWindowManager()->popGuiMode();
}
}
void ContainerWindow::onReferenceUnavailable()
{
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
}

@ -2,15 +2,14 @@
#define MGUI_CONTAINER_H
#include <components/esm_store/store.hpp>
#include "../mwclass/container.hpp"
#include <sstream>
#include <set>
#include <string>
#include <utility>
#include "window_base.hpp"
#include "referenceinterface.hpp"
#include "../mwclass/container.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/containerstore.hpp"
#include <vector>
namespace MWWorld
{
@ -43,7 +42,7 @@ namespace MWGui
int mDraggedCount;
};
class ContainerBase
class ContainerBase : public ReferenceInterface
{
public:
ContainerBase(DragAndDrop* dragAndDrop);
@ -89,7 +88,6 @@ namespace MWGui
MyGUI::Widget* mSelectedItem;
DragAndDrop* mDragAndDrop;
MWWorld::Ptr mContainer;
Filter mFilter;
@ -140,6 +138,8 @@ namespace MWGui
void onWindowResize(MyGUI::Window* window);
void onCloseButtonClicked(MyGUI::Widget* _sender);
void onTakeAllButtonClicked(MyGUI::Widget* _sender);
virtual void onReferenceUnavailable();
};
}
#endif // CONTAINER_H

@ -125,7 +125,7 @@ void DialogueWindow::onSelectTopic(std::string topic)
{
/// \todo check if the player is allowed to trade with this actor (e.g. faction rank high enough)?
mWindowManager.pushGuiMode(GM_Barter);
mWindowManager.getTradeWindow()->startTrade(mActor);
mWindowManager.getTradeWindow()->startTrade(mPtr);
}
else
@ -135,7 +135,7 @@ void DialogueWindow::onSelectTopic(std::string topic)
void DialogueWindow::startDialogue(MWWorld::Ptr actor, std::string npcName)
{
mEnabled = true;
mActor = actor;
mPtr = actor;
topicsList->setEnabled(true);
setTitle(npcName);
@ -260,3 +260,8 @@ void DialogueWindow::goodbye()
topicsList->setEnabled(false);
mEnabled = false;
}
void DialogueWindow::onReferenceUnavailable()
{
mWindowManager.removeGuiMode(GM_Dialogue);
}

@ -2,6 +2,7 @@
#define MWGUI_DIALOGE_H
#include "window_base.hpp"
#include "referenceinterface.hpp"
#include <boost/array.hpp>
#include "../mwworld/ptr.hpp"
@ -25,7 +26,7 @@ namespace MWGui
{
class DialogueHistory;
class DialogueWindow: public WindowBase
class DialogueWindow: public WindowBase, public ReferenceInterface
{
public:
DialogueWindow(WindowManager& parWindowManager);
@ -58,6 +59,8 @@ namespace MWGui
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
void onWindowResize(MyGUI::Window* _sender);
virtual void onReferenceUnavailable();
private:
void updateOptions();
/**
@ -70,8 +73,6 @@ namespace MWGui
bool mEnabled;
MWWorld::Ptr mActor; // actor being talked to
DialogueHistory* history;
Widgets::MWList* topicsList;
MyGUI::ProgressPtr pDispositionBar;

@ -155,7 +155,7 @@ namespace MWGui
if (mDragAndDrop->mDraggedFrom != this)
{
// add item to the player's inventory
MWWorld::ContainerStore& invStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
MWWorld::ContainerStore& invStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
MWWorld::ContainerStoreIterator it = invStore.begin();
int origCount = ptr.getRefData().getCount();
@ -192,7 +192,7 @@ namespace MWGui
std::vector<MWWorld::Ptr> InventoryWindow::getEquippedItems()
{
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mContainer).getInventoryStore(mContainer);
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
std::vector<MWWorld::Ptr> items;
@ -210,7 +210,7 @@ namespace MWGui
void InventoryWindow::_unequipItem(MWWorld::Ptr item)
{
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mContainer).getInventoryStore(mContainer);
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot)
{
@ -244,7 +244,7 @@ namespace MWGui
int InventoryWindow::getPlayerGold()
{
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mContainer).getInventoryStore(mContainer);
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
for (MWWorld::ContainerStoreIterator it = invStore.begin();
it != invStore.end(); ++it)

@ -48,6 +48,8 @@ namespace MWGui
virtual bool isInventory() { return true; }
virtual std::vector<MWWorld::Ptr> getEquippedItems();
virtual void _unequipItem(MWWorld::Ptr item);
virtual void onReferenceUnavailable() { ; }
};
}

@ -0,0 +1,28 @@
#include "referenceinterface.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/world.hpp"
#include "../mwbase/environment.hpp"
namespace MWGui
{
ReferenceInterface::ReferenceInterface()
: mCurrentPlayerCell(NULL)
{
}
void ReferenceInterface::checkReferenceAvailable()
{
if (mPtr.isEmpty())
return;
MWWorld::Ptr::CellStore* playerCell = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell();
// check if player has changed cell, or count of the reference has become 0
if ((playerCell != mCurrentPlayerCell && mCurrentPlayerCell != NULL)
|| mPtr.getRefData().getCount() == 0)
onReferenceUnavailable();
mCurrentPlayerCell = playerCell;
}
}

@ -0,0 +1,29 @@
#ifndef MWGUI_REFERENCEINTERFACE_H
#define MWGUI_REFERENCEINTERFACE_H
#include "../mwworld/ptr.hpp"
namespace MWGui
{
/// \brief this class is intended for GUI interfaces that access an MW-Reference
/// for example dialogue window accesses an NPC, or Container window accesses a Container
/// these classes have to be automatically closed if the reference becomes unavailable
/// make sure that checkReferenceAvailable() is called every frame and that onReferenceUnavailable() has been overridden
class ReferenceInterface
{
public:
ReferenceInterface();
void checkReferenceAvailable(); ///< closes the window, if the MW-reference has become unavailable
protected:
virtual void onReferenceUnavailable() = 0; ///< called when reference has become unavailable
MWWorld::Ptr mPtr;
private:
MWWorld::Ptr::CellStore* mCurrentPlayerCell;
};
}
#endif

@ -157,9 +157,9 @@ namespace MWGui
// check if the merchant can afford this
int merchantgold;
if (mContainer.getTypeName() == typeid(ESM::NPC).name())
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
{
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mContainer.get<ESM::NPC>();
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mPtr.get<ESM::NPC>();
if (ref->base->npdt52.gold == -10)
merchantgold = ref->base->npdt12.gold;
else
@ -167,7 +167,7 @@ namespace MWGui
}
else // ESM::Creature
{
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mContainer.get<ESM::Creature>();
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mPtr.get<ESM::Creature>();
merchantgold = ref->base->data.gold;
}
if (mCurrentBalance > 0 && merchantgold < mCurrentBalance)
@ -218,7 +218,7 @@ namespace MWGui
// i give you back your stuff!
returnBoughtItems(mWindowManager.getInventoryWindow()->getContainerStore());
// now gimme back my stuff!
mWindowManager.getInventoryWindow()->returnBoughtItems(MWWorld::Class::get(mContainer).getContainerStore(mContainer));
mWindowManager.getInventoryWindow()->returnBoughtItems(MWWorld::Class::get(mPtr).getContainerStore(mPtr));
mWindowManager.popGuiMode();
}
@ -240,9 +240,9 @@ namespace MWGui
}
int merchantgold;
if (mContainer.getTypeName() == typeid(ESM::NPC).name())
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
{
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mContainer.get<ESM::NPC>();
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mPtr.get<ESM::NPC>();
if (ref->base->npdt52.gold == -10)
merchantgold = ref->base->npdt12.gold;
else
@ -250,7 +250,7 @@ namespace MWGui
}
else // ESM::Creature
{
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mContainer.get<ESM::Creature>();
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mPtr.get<ESM::Creature>();
merchantgold = ref->base->data.gold;
}
@ -262,13 +262,13 @@ namespace MWGui
{
std::vector<MWWorld::Ptr> items;
if (mContainer.getTypeName() == typeid(ESM::Creature).name())
if (mPtr.getTypeName() == typeid(ESM::Creature).name())
{
// creatures don't have equipment slots.
return items;
}
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mContainer).getInventoryStore(mContainer);
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot)
{
@ -285,15 +285,15 @@ namespace MWGui
bool TradeWindow::npcAcceptsItem(MWWorld::Ptr item)
{
int services = 0;
if (mContainer.getTypeName() == typeid(ESM::NPC).name())
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
{
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mContainer.get<ESM::NPC>();
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mPtr.get<ESM::NPC>();
if (ref->base->hasAI)
services = ref->base->AI.services;
}
else if (mContainer.getTypeName() == typeid(ESM::Creature).name())
else if (mPtr.getTypeName() == typeid(ESM::Creature).name())
{
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mContainer.get<ESM::Creature>();
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mPtr.get<ESM::Creature>();
if (ref->base->hasAI)
services = ref->base->AI.services;
}
@ -327,7 +327,7 @@ namespace MWGui
std::vector<MWWorld::Ptr> TradeWindow::itemsToIgnore()
{
std::vector<MWWorld::Ptr> items;
MWWorld::ContainerStore& invStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
MWWorld::ContainerStore& invStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
for (MWWorld::ContainerStoreIterator it = invStore.begin();
it != invStore.end(); ++it)
@ -356,4 +356,11 @@ namespace MWGui
updateLabels();
}
void TradeWindow::onReferenceUnavailable()
{
// remove both Trade and Dialogue (since you always trade with the NPC/creature that you have previously talked to)
mWindowManager.removeGuiMode(GM_Barter);
mWindowManager.removeGuiMode(GM_Dialogue);
}
}

@ -69,6 +69,8 @@ namespace MWGui
virtual std::vector<MWWorld::Ptr> itemsToIgnore();
void updateLabels();
virtual void onReferenceUnavailable();
};
}

@ -472,6 +472,10 @@ void WindowManager::onFrame (float frameDuration)
mStatsWindow->onFrame();
hud->onFrame(frameDuration);
mDialogueWindow->checkReferenceAvailable();
mTradeWindow->checkReferenceAvailable();
mContainerWindow->checkReferenceAvailable();
}
const ESMS::ESMStore& WindowManager::getStore() const
@ -626,3 +630,17 @@ void WindowManager::popGuiMode()
updateVisible();
}
void WindowManager::removeGuiMode(GuiMode mode)
{
std::vector<GuiMode>::iterator it = mGuiModes.begin();
while (it != mGuiModes.end())
{
if (*it == mode)
it = mGuiModes.erase(it);
else
++it;
}
updateVisible();
}

@ -109,6 +109,7 @@ namespace MWGui
void pushGuiMode(GuiMode mode);
void popGuiMode();
void removeGuiMode(GuiMode mode); ///< can be anywhere in the stack
GuiMode getMode() const
{

Loading…
Cancel
Save