| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- #include "BsDragAndDropManager.h"
- #include "BsPlatform.h"
- #include "BsCoreApplication.h"
- #include <BsTime.h>
- using namespace std::placeholders;
- namespace BansheeEngine
- {
- DragAndDropManager::DragAndDropManager()
- :mIsDragInProgress(false), mDragTypeId(0), mData(nullptr), mCaptureChanged(false), mCaptureActive(0), mNeedsValidDropTarget(false)
- {
- mMouseCaptureChangedConn = Platform::onMouseCaptureChanged.connect(std::bind(&DragAndDropManager::mouseCaptureChanged, this));
- Input::instance().onPointerReleased.connect(std::bind(&DragAndDropManager::cursorReleased, this, _1));
- }
- DragAndDropManager::~DragAndDropManager()
- {
- mMouseCaptureChangedConn.disconnect();
- }
- void DragAndDropManager::addDropCallback(std::function<void(bool)> dropCallback)
- {
- mDropCallbacks.push_back(dropCallback);
- }
- void DragAndDropManager::startDrag(UINT32 typeId, void* data, std::function<void(bool)> dropCallback, bool needsValidDropTarget)
- {
- if (mIsDragInProgress)
- endDrag(false);
- mDragTypeId = typeId;
- mData = data;
- mNeedsValidDropTarget = needsValidDropTarget;
- addDropCallback(dropCallback);
- mIsDragInProgress = true;
- mCaptureActive.store(false);
- mCaptureChanged.store(false);
- Platform::captureMouse(*gCoreApplication().getPrimaryWindow());
- }
- void DragAndDropManager::_update()
- {
- if(!mIsDragInProgress)
- return;
- // This generally happens when window loses focus and capture is lost (e.g. alt+tab)
- int captureActive = mCaptureActive.load();
- if (!captureActive && mCaptureChanged.load() &&
- (gTime().getFrameIdx() > mCaptureChangeFrame.load())) // Wait one frame to insure input (like mouse up) gets a chance to be processed
- {
- endDrag(false);
- mCaptureChanged.store(false);
- }
- }
- void DragAndDropManager::endDrag(bool processed)
- {
- for(auto& callback : mDropCallbacks)
- callback(processed);
- mDragTypeId = 0;
- mData = nullptr;
- mDropCallbacks.clear();
- mIsDragInProgress = false;
- }
- void DragAndDropManager::mouseCaptureChanged()
- {
- mCaptureActive.fetch_xor(1); // mCaptureActive = !mCaptureActive;
- mCaptureChanged.store(true);
- mCaptureChangeFrame.store(gTime().getFrameIdx());
- }
- void DragAndDropManager::cursorReleased(const PointerEvent& event)
- {
- if(!mIsDragInProgress)
- return;
- if(!onDragEnded.empty())
- {
- DragCallbackInfo info;
- onDragEnded(event, info);
- endDrag(info.processed);
- }
- else
- endDrag(false);
- Platform::releaseMouseCapture();
- }
- }
|