You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
168 lines
5.1 KiB
C++
168 lines
5.1 KiB
C++
#include "draganddrop.hpp"
|
|
|
|
#include <MyGUI_Gui.h>
|
|
#include <MyGUI_ControllerManager.h>
|
|
|
|
#include "../mwbase/windowmanager.hpp"
|
|
#include "../mwbase/environment.hpp"
|
|
|
|
#include "../mwworld/class.hpp"
|
|
|
|
#include "sortfilteritemmodel.hpp"
|
|
#include "inventorywindow.hpp"
|
|
#include "itemwidget.hpp"
|
|
#include "itemview.hpp"
|
|
#include "controllers.hpp"
|
|
|
|
namespace MWGui
|
|
{
|
|
|
|
|
|
DragAndDrop::DragAndDrop()
|
|
: mIsOnDragAndDrop(false)
|
|
, mDraggedWidget(NULL)
|
|
, mSourceModel(NULL)
|
|
, mSourceView(NULL)
|
|
, mSourceSortModel(NULL)
|
|
, mDraggedCount(0)
|
|
{
|
|
}
|
|
|
|
void DragAndDrop::startDrag (int index, SortFilterItemModel* sortModel, ItemModel* sourceModel, ItemView* sourceView, int count)
|
|
{
|
|
mItem = sourceModel->getItem(index);
|
|
mDraggedCount = count;
|
|
mSourceModel = sourceModel;
|
|
mSourceView = sourceView;
|
|
mSourceSortModel = sortModel;
|
|
|
|
// If picking up an item that isn't from the player's inventory, the item gets added to player inventory backend
|
|
// immediately, even though it's still floating beneath the mouse cursor. A bit counterintuitive,
|
|
// but this is how it works in vanilla, and not doing so would break quests (BM_beasts for instance).
|
|
ItemModel* playerModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getModel();
|
|
if (mSourceModel != playerModel)
|
|
{
|
|
MWWorld::Ptr item = mSourceModel->moveItem(mItem, mDraggedCount, playerModel);
|
|
|
|
playerModel->update();
|
|
|
|
ItemModel::ModelIndex newIndex = -1;
|
|
for (unsigned int i=0; i<playerModel->getItemCount(); ++i)
|
|
{
|
|
if (playerModel->getItem(i).mBase == item)
|
|
{
|
|
newIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
mItem = playerModel->getItem(newIndex);
|
|
mSourceModel = playerModel;
|
|
|
|
SortFilterItemModel* playerFilterModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getSortFilterModel();
|
|
mSourceSortModel = playerFilterModel;
|
|
}
|
|
|
|
std::string sound = mItem.mBase.getClass().getUpSoundId(mItem.mBase);
|
|
MWBase::Environment::get().getWindowManager()->playSound (sound);
|
|
|
|
if (mSourceSortModel)
|
|
{
|
|
mSourceSortModel->clearDragItems();
|
|
mSourceSortModel->addDragItem(mItem.mBase, count);
|
|
}
|
|
|
|
ItemWidget* baseWidget = 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);
|
|
|
|
mDraggedWidget = baseWidget;
|
|
baseWidget->setItem(mItem.mBase);
|
|
baseWidget->setNeedMouseFocus(false);
|
|
baseWidget->setCount(count);
|
|
|
|
sourceView->update();
|
|
|
|
MWBase::Environment::get().getWindowManager()->setDragDrop(true);
|
|
|
|
mIsOnDragAndDrop = true;
|
|
}
|
|
|
|
void DragAndDrop::drop(ItemModel *targetModel, ItemView *targetView)
|
|
{
|
|
std::string sound = mItem.mBase.getClass().getDownSoundId(mItem.mBase);
|
|
MWBase::Environment::get().getWindowManager()->playSound(sound);
|
|
|
|
// We can't drop a conjured item to the ground; the target container should always be the source container
|
|
if (mItem.mFlags & ItemStack::Flag_Bound && targetModel != mSourceModel)
|
|
{
|
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sBarterDialog12}");
|
|
return;
|
|
}
|
|
|
|
// If item is dropped where it was taken from, we don't need to do anything -
|
|
// otherwise, do the transfer
|
|
if (targetModel != mSourceModel)
|
|
{
|
|
mSourceModel->moveItem(mItem, mDraggedCount, targetModel);
|
|
}
|
|
|
|
mSourceModel->update();
|
|
|
|
finish();
|
|
if (targetView)
|
|
targetView->update();
|
|
|
|
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->updateItemView();
|
|
|
|
// We need to update the view since an other item could be auto-equipped.
|
|
mSourceView->update();
|
|
}
|
|
|
|
void DragAndDrop::onFrame()
|
|
{
|
|
if (mIsOnDragAndDrop && mItem.mBase.getRefData().getCount() == 0)
|
|
finish();
|
|
}
|
|
|
|
/*
|
|
Start of tes3mp change (minor)
|
|
|
|
Add a deleteDragItems argument that allows the deletion of the
|
|
items in the drag as oppposed to the regular behavior of returning
|
|
them to their source model
|
|
|
|
This is required to reduce unpredictable behavior for drags approved
|
|
or rejected by the server
|
|
*/
|
|
void DragAndDrop::finish(bool deleteDragItems)
|
|
/*
|
|
End of tes3mp change (minor)
|
|
*/
|
|
{
|
|
mIsOnDragAndDrop = false;
|
|
mSourceSortModel->clearDragItems();
|
|
|
|
/*
|
|
Start of tes3mp addition
|
|
|
|
Make it possible to entirely delete the items in the drag
|
|
*/
|
|
if (deleteDragItems)
|
|
mSourceModel->removeItem(mItem, mDraggedCount);
|
|
/*
|
|
End of tes3mp addition
|
|
*/
|
|
|
|
// since mSourceView doesn't get updated in drag()
|
|
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->updateItemView();
|
|
|
|
MyGUI::Gui::getInstance().destroyWidget(mDraggedWidget);
|
|
mDraggedWidget = 0;
|
|
MWBase::Environment::get().getWindowManager()->setDragDrop(false);
|
|
}
|
|
|
|
}
|