openmw-tes3coop/extern/mygui_3.0.1/MyGUIEngine/src/MyGUI_DDContainer.cpp

312 lines
7.8 KiB
C++
Raw Normal View History

/*!
@file
@author Albert Semenov
@date 10/2008
@module
*/
/*
This file is part of MyGUI.
MyGUI is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
MyGUI 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with MyGUI. If not, see <http://www.gnu.org/licenses/>.
*/
#include "MyGUI_Precompiled.h"
#include "MyGUI_DDContainer.h"
#include "MyGUI_InputManager.h"
#include "MyGUI_LayerManager.h"
namespace MyGUI
{
DDContainer::DDContainer() :
mDropResult(false),
mNeedDrop(false),
mStartDrop(false),
mOldDrop(nullptr),
mCurrentSender(nullptr),
mDropSenderIndex(ITEM_NONE),
mDropItem(nullptr),
mNeedDragDrop(false),
mReseiverContainer(nullptr)
{
}
void DDContainer::_initialise(WidgetStyle _style, const IntCoord& _coord, Align _align, ResourceSkin* _info, Widget* _parent, ICroppedRectangle * _croppedParent, IWidgetCreator * _creator, const std::string& _name)
{
Base::_initialise(_style, _coord, _align, _info, _parent, _croppedParent, _creator, _name);
initialiseWidgetSkin(_info);
}
DDContainer::~DDContainer()
{
shutdownWidgetSkin();
}
void DDContainer::baseChangeWidgetSkin(ResourceSkin* _info)
{
shutdownWidgetSkin();
Base::baseChangeWidgetSkin(_info);
initialiseWidgetSkin(_info);
}
void DDContainer::initialiseWidgetSkin(ResourceSkin* _info)
{
}
void DDContainer::shutdownWidgetSkin()
{
}
void DDContainer::onMouseButtonPressed(int _left, int _top, MouseButton _id)
{
// смещение внутри виджета, куда кликнули мышкой
mClickInWidget = InputManager::getInstance().getLastLeftPressed() - getAbsolutePosition();
mouseButtonPressed(_id);
Base::onMouseButtonPressed(_left, _top, _id);
}
void DDContainer::onMouseButtonReleased(int _left, int _top, MouseButton _id)
{
mouseButtonReleased(_id);
Base::onMouseButtonReleased(_left, _top, _id);
}
void DDContainer::onMouseDrag(int _left, int _top)
{
mouseDrag();
Base::onMouseDrag(_left, _top);
}
void DDContainer::mouseButtonPressed(MouseButton _id)
{
if (MouseButton::Left == _id)
{
// сбрасываем инфу для дропа
mDropResult = false;
mOldDrop = nullptr;
mDropInfo.reset();
mReseiverContainer = nullptr;
// сбрасываем, чтобы обновился дропный виджет
mCurrentSender = nullptr;
mStartDrop = false;
}
// если нажата другая клавиша и был дроп то сбрасываем
else
{
endDrop(true);
}
}
void DDContainer::mouseButtonReleased(MouseButton _id)
{
if (MouseButton::Left == _id)
{
endDrop(false);
}
}
void DDContainer::mouseDrag()
{
// нужно ли обновить данные
bool update = false;
// первый раз дропаем елемент
if (!mStartDrop && mDropSenderIndex != ITEM_NONE)
{
mStartDrop = true;
mNeedDrop = false;
update = true;
// запрос на нужность дропа по индексу
mDropInfo.set(this, mDropSenderIndex, nullptr, ITEM_NONE);
mReseiverContainer = nullptr;
eventStartDrag(this, mDropInfo, mNeedDrop);
if (mNeedDrop)
{
eventChangeDDState(this, DDItemState::Start);
setEnableToolTip(false);
}
else
{
// сбрасываем фокус мыши (не обязательно)
InputManager::getInstance().resetMouseCaptureWidget();
}
}
// дроп не нужен
if (!mNeedDrop)
{
return;
}
// делаем запрос, над кем наша мыша
const IntPoint& point = InputManager::getInstance().getMousePosition();
Widget* item = LayerManager::getInstance().getWidgetFromPoint(point.left, point.top);
updateDropItems();
// если равно, значит уже спрашивали
if (mOldDrop == item) return;
mOldDrop = item;
// сбрасываем старую подсветку
if (mReseiverContainer) mReseiverContainer->_setContainerItemInfo(mDropInfo.receiver_index, false, false);
mDropResult = false;
mReseiverContainer = nullptr;
Widget* receiver = nullptr;
size_t receiver_index = ITEM_NONE;
// есть виджет под нами
if (item)
{
// делаем запрос на индекс по произвольному виджету
item->_getContainer(receiver, receiver_index);
// работаем только с контейнерами
if (receiver && receiver->isType<DDContainer>())
{
// подписываемся на информацию о валидности дропа
mReseiverContainer = static_cast<DDContainer*>(receiver);
mReseiverContainer->_eventInvalideContainer = newDelegate(this, &DDContainer::notifyInvalideDrop);
// делаем запрос на возможность дропа
mDropInfo.set(this, mDropSenderIndex, mReseiverContainer, receiver_index);
eventRequestDrop(this, mDropInfo, mDropResult);
// устанавливаем новую подсветку
mReseiverContainer->_setContainerItemInfo(mDropInfo.receiver_index, true, mDropResult);
}
else
{
mDropInfo.set(this, mDropSenderIndex, nullptr, ITEM_NONE);
}
}
// нет виджета под нами
else
{
mDropInfo.set(this, mDropSenderIndex, nullptr, ITEM_NONE);
}
DDItemState state;
DDWidgetState data(mDropSenderIndex);
data.update = update;
if (receiver == nullptr)
{
data.accept = false;
data.refuse = false;
state = DDItemState::Miss;
}
else if (mDropResult)
{
data.accept = true;
data.refuse = false;
state = DDItemState::Accept;
}
else
{
data.accept = false;
data.refuse = true;
state = DDItemState::Refuse;
}
updateDropItemsState(data);
eventChangeDDState(this, state);
}
void DDContainer::endDrop(bool _reset)
{
if (mStartDrop)
{
removeDropItems();
// сбрасываем старую подсветку
if (mReseiverContainer) mReseiverContainer->_setContainerItemInfo(mDropInfo.receiver_index, false, false);
if (_reset) mDropResult = false;
eventDropResult(this, mDropInfo, mDropResult);
eventChangeDDState(this, DDItemState::End);
setEnableToolTip(true);
// сбрасываем инфу для дропа
mStartDrop = false;
mDropResult = false;
mNeedDrop = false;
mOldDrop = nullptr;
mDropInfo.reset();
mReseiverContainer = nullptr;
mDropSenderIndex = ITEM_NONE;
}
}
void DDContainer::removeDropItems()
{
mDropItem = nullptr;
}
void DDContainer::updateDropItems()
{
if (mDropItem == nullptr)
{
requestDragWidgetInfo(this, mDropItem, mDropDimension);
}
const IntPoint& point = InputManager::getInstance().getMousePositionByLayer();
if (mDropItem)
{
mDropItem->setCoord(point.left - mClickInWidget.left + mDropDimension.left, point.top - mClickInWidget.top + mDropDimension.top, mDropDimension.width, mDropDimension.height);
mDropItem->setVisible(true);
}
}
void DDContainer::updateDropItemsState(const DDWidgetState& _state)
{
eventUpdateDropState(this, mDropItem, _state);
}
void DDContainer::notifyInvalideDrop(DDContainer* _sender)
{
mouseDrag();
}
void DDContainer::_getContainer(Widget*& _container, size_t& _index)
{
_container = this;
_index = ITEM_NONE;
}
void DDContainer::setProperty(const std::string& _key, const std::string& _value)
{
if (_key == "DDContainer_NeedDragDrop") setNeedDragDrop(utility::parseValue<bool>(_value));
else
{
Base::setProperty(_key, _value);
return;
}
eventChangeProperty(this, _key, _value);
}
} // namespace MyGUI