|
|
@@ -0,0 +1,248 @@
|
|
|
+#include "BsScriptDragDropManager.h"
|
|
|
+#include "BsMonoManager.h"
|
|
|
+#include "BsMonoClass.h"
|
|
|
+#include "BsMonoMethod.h"
|
|
|
+#include "BsMonoUtil.h"
|
|
|
+#include "BsScriptSceneObject.h"
|
|
|
+#include "BsScriptGameObjectManager.h"
|
|
|
+#include "BsGUISceneTreeView.h"
|
|
|
+#include "BsGUIResourceTreeView.h"
|
|
|
+#include "BsTime.h"
|
|
|
+
|
|
|
+using namespace std::placeholders;
|
|
|
+
|
|
|
+namespace BansheeEngine
|
|
|
+{
|
|
|
+ ScriptDragDrop::ScriptDragDrop(MonoObject* instance)
|
|
|
+ :ScriptObject(instance)
|
|
|
+ { }
|
|
|
+
|
|
|
+ void ScriptDragDrop::initRuntimeData()
|
|
|
+ {
|
|
|
+ metaData.scriptClass->addInternalCall("Internal_IsDragInProgress", &ScriptDragDrop::internal_IsDragInProgress);
|
|
|
+ metaData.scriptClass->addInternalCall("Internal_IsDropInProgress", &ScriptDragDrop::internal_IsDropInProgress);
|
|
|
+ metaData.scriptClass->addInternalCall("Internal_GetData", &ScriptDragDrop::internal_GetData);
|
|
|
+ metaData.scriptClass->addInternalCall("Internal_StartSceneObjectDrag", &ScriptDragDrop::internal_StartSceneObjectDrag);
|
|
|
+ metaData.scriptClass->addInternalCall("Internal_StartResourceDrag", &ScriptDragDrop::internal_StartResourceDrag);
|
|
|
+ }
|
|
|
+
|
|
|
+ bool ScriptDragDrop::internal_IsDragInProgress()
|
|
|
+ {
|
|
|
+ return DragAndDropManager::instance().isDragInProgress();
|
|
|
+ }
|
|
|
+
|
|
|
+ bool ScriptDragDrop::internal_IsDropInProgress()
|
|
|
+ {
|
|
|
+ return ScriptDragDropManager::instance().isDropInProgress();
|
|
|
+ }
|
|
|
+
|
|
|
+ MonoObject* ScriptDragDrop::internal_GetData()
|
|
|
+ {
|
|
|
+ return ScriptDragDropManager::instance().getDropData();
|
|
|
+ }
|
|
|
+
|
|
|
+ void ScriptDragDrop::internal_StartSceneObjectDrag(ScriptSceneObjectDragDropData* value)
|
|
|
+ {
|
|
|
+ const Vector<HSceneObject>& sceneObjects = value->getSceneObjects();
|
|
|
+ DraggedSceneObjects* draggedSceneObjects = bs_new<DraggedSceneObjects>((UINT32)sceneObjects.size());
|
|
|
+
|
|
|
+ UINT32 idx = 0;
|
|
|
+ for (auto& so : sceneObjects)
|
|
|
+ {
|
|
|
+ draggedSceneObjects->objects[idx] = so;
|
|
|
+ idx++;
|
|
|
+ }
|
|
|
+
|
|
|
+ DragAndDropManager::instance().startDrag((UINT32)DragAndDropType::SceneObject, draggedSceneObjects, nullptr, false);
|
|
|
+ }
|
|
|
+
|
|
|
+ void ScriptDragDrop::internal_StartResourceDrag(ScriptResourceDragDropData* value)
|
|
|
+ {
|
|
|
+ // TODO
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ ScriptSceneObjectDragDropData::ScriptSceneObjectDragDropData(MonoObject* instance, const Vector<HSceneObject>& sceneObjects)
|
|
|
+ :ScriptObject(instance), mSceneObjects(sceneObjects)
|
|
|
+ { }
|
|
|
+
|
|
|
+ void ScriptSceneObjectDragDropData::initRuntimeData()
|
|
|
+ {
|
|
|
+ metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptSceneObjectDragDropData::internal_CreateInstance);
|
|
|
+ metaData.scriptClass->addInternalCall("Internal_GetObjects", &ScriptSceneObjectDragDropData::internal_GetObjects);
|
|
|
+ }
|
|
|
+
|
|
|
+ MonoObject* ScriptSceneObjectDragDropData::create(const Vector<HSceneObject>& sceneObjects)
|
|
|
+ {
|
|
|
+ ScriptArray arrSceneObjects = ScriptArray::create<ScriptSceneObject>((UINT32)sceneObjects.size());
|
|
|
+
|
|
|
+ UINT32 idx = 0;
|
|
|
+ for (auto& so : sceneObjects)
|
|
|
+ {
|
|
|
+ ScriptSceneObject* scriptSceneObject = ScriptGameObjectManager::instance().getOrCreateScriptSceneObject(so);
|
|
|
+
|
|
|
+ arrSceneObjects.set(idx, scriptSceneObject);
|
|
|
+ idx++;
|
|
|
+ }
|
|
|
+
|
|
|
+ void* params[1] = { arrSceneObjects.getInternal() };
|
|
|
+ MonoObject* instance = metaData.scriptClass->createInstance(params, 1);
|
|
|
+
|
|
|
+ return instance;
|
|
|
+ }
|
|
|
+
|
|
|
+ void ScriptSceneObjectDragDropData::internal_CreateInstance(MonoObject* managedInstance, MonoArray* objects)
|
|
|
+ {
|
|
|
+ ScriptArray objectsArray = ScriptArray(objects);
|
|
|
+
|
|
|
+ Vector<HSceneObject> sceneObjects(objectsArray.size());
|
|
|
+ for (UINT32 i = 0; i < objectsArray.size(); i++)
|
|
|
+ {
|
|
|
+ ScriptSceneObject* scriptSO = ScriptSceneObject::toNative(objectsArray.get<MonoObject*>(i));
|
|
|
+ if (scriptSO != nullptr)
|
|
|
+ sceneObjects[i] = scriptSO->getNativeSceneObject();
|
|
|
+ }
|
|
|
+
|
|
|
+ ScriptSceneObjectDragDropData* nativeInstance = new (bs_alloc<ScriptSceneObjectDragDropData>()) ScriptSceneObjectDragDropData(managedInstance, sceneObjects);
|
|
|
+ }
|
|
|
+
|
|
|
+ MonoArray* ScriptSceneObjectDragDropData::internal_GetObjects(ScriptSceneObjectDragDropData* instance)
|
|
|
+ {
|
|
|
+ ScriptArray objectsArray = ScriptArray::create<ScriptSceneObject>((UINT32)instance->mSceneObjects.size());
|
|
|
+ for (UINT32 i = 0; i < (UINT32)instance->mSceneObjects.size(); i++)
|
|
|
+ {
|
|
|
+ ScriptSceneObject* scriptSO = ScriptGameObjectManager::instance().getOrCreateScriptSceneObject(instance->mSceneObjects[i]);
|
|
|
+
|
|
|
+ if (scriptSO != nullptr)
|
|
|
+ objectsArray.set(i, scriptSO->getManagedInstance());
|
|
|
+ }
|
|
|
+
|
|
|
+ return objectsArray.getInternal();
|
|
|
+ }
|
|
|
+
|
|
|
+ ScriptResourceDragDropData::ScriptResourceDragDropData(MonoObject* instance, const Vector<Path>& paths)
|
|
|
+ :ScriptObject(instance), mPaths(paths)
|
|
|
+ { }
|
|
|
+
|
|
|
+ void ScriptResourceDragDropData::initRuntimeData()
|
|
|
+ {
|
|
|
+ metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptResourceDragDropData::internal_CreateInstance);
|
|
|
+ metaData.scriptClass->addInternalCall("Internal_GetPaths", &ScriptResourceDragDropData::internal_GetPaths);
|
|
|
+ }
|
|
|
+
|
|
|
+ MonoObject* ScriptResourceDragDropData::create(const Vector<Path>& paths)
|
|
|
+ {
|
|
|
+ MonoArray* rawArray = mono_array_new(MonoManager::instance().getDomain(), mono_get_string_class(), (UINT32)paths.size());
|
|
|
+ ScriptArray arrStrings(rawArray);
|
|
|
+
|
|
|
+ UINT32 idx = 0;
|
|
|
+ for (auto& path : paths)
|
|
|
+ {
|
|
|
+ MonoString* managedPath = MonoUtil::wstringToMono(MonoManager::instance().getDomain(), path.toWString());
|
|
|
+
|
|
|
+ arrStrings.set(idx, managedPath);
|
|
|
+ idx++;
|
|
|
+ }
|
|
|
+
|
|
|
+ void* params[1] = { arrStrings.getInternal() };
|
|
|
+ MonoObject* instance = metaData.scriptClass->createInstance(params, 1);
|
|
|
+
|
|
|
+ return instance;
|
|
|
+ }
|
|
|
+
|
|
|
+ void ScriptResourceDragDropData::internal_CreateInstance(MonoObject* managedInstance, MonoArray* monoPaths)
|
|
|
+ {
|
|
|
+ ScriptArray pathsArray = ScriptArray(monoPaths);
|
|
|
+
|
|
|
+ Vector<Path> paths(pathsArray.size());
|
|
|
+ for (UINT32 i = 0; i < pathsArray.size(); i++)
|
|
|
+ {
|
|
|
+ MonoString* monoPath = pathsArray.get<MonoString*>(i);
|
|
|
+ paths[i] = MonoUtil::monoToWString(monoPath);
|
|
|
+ }
|
|
|
+
|
|
|
+ ScriptResourceDragDropData* nativeInstance = new (bs_alloc<ScriptResourceDragDropData>()) ScriptResourceDragDropData(managedInstance, paths);
|
|
|
+ }
|
|
|
+
|
|
|
+ MonoArray* ScriptResourceDragDropData::internal_GetPaths(ScriptResourceDragDropData* instance)
|
|
|
+ {
|
|
|
+ MonoArray* rawArray = mono_array_new(MonoManager::instance().getDomain(),
|
|
|
+ mono_get_string_class(), (UINT32)instance->mPaths.size());
|
|
|
+
|
|
|
+ ScriptArray arrStrings(rawArray);
|
|
|
+
|
|
|
+ UINT32 idx = 0;
|
|
|
+ for (auto& path : instance->mPaths)
|
|
|
+ {
|
|
|
+ MonoString* managedPath = MonoUtil::wstringToMono(MonoManager::instance().getDomain(), path.toWString());
|
|
|
+
|
|
|
+ arrStrings.set(idx, managedPath);
|
|
|
+ idx++;
|
|
|
+ }
|
|
|
+
|
|
|
+ return arrStrings.getInternal();
|
|
|
+ }
|
|
|
+
|
|
|
+ ScriptDragDropManager::ScriptDragDropManager()
|
|
|
+ :mDroppedFrameIdx(0), mIsDropInProgress(false), mDropType(ScriptDragDropType::None)
|
|
|
+ {
|
|
|
+ mDragEndedConn = DragAndDropManager::instance().onDragEnded.connect(std::bind(&ScriptDragDropManager::onMouseDragEnded, this, _1, _2));
|
|
|
+ }
|
|
|
+
|
|
|
+ ScriptDragDropManager::~ScriptDragDropManager()
|
|
|
+ {
|
|
|
+ mDragEndedConn.disconnect();
|
|
|
+ }
|
|
|
+
|
|
|
+ void ScriptDragDropManager::update()
|
|
|
+ {
|
|
|
+ // This only stays active for a single frame
|
|
|
+ if (mIsDropInProgress && mDroppedFrameIdx < Time::instance().getFrameNumber())
|
|
|
+ mIsDropInProgress = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ MonoObject* ScriptDragDropManager::getDropData() const
|
|
|
+ {
|
|
|
+ if (mDropType == ScriptDragDropType::SceneObject)
|
|
|
+ return ScriptSceneObjectDragDropData::create(mDroppedSceneObjects);
|
|
|
+ else if (mDropType == ScriptDragDropType::Resource)
|
|
|
+ return ScriptResourceDragDropData::create(mDroppedPaths);
|
|
|
+
|
|
|
+ return nullptr;
|
|
|
+ }
|
|
|
+
|
|
|
+ void ScriptDragDropManager::onMouseDragEnded(const PointerEvent& evt, DragCallbackInfo& callbackInfo)
|
|
|
+ {
|
|
|
+ if (!DragAndDropManager::instance().isDragInProgress())
|
|
|
+ return;
|
|
|
+
|
|
|
+ mDroppedPaths.clear();
|
|
|
+ mDroppedSceneObjects.clear();
|
|
|
+ mIsDropInProgress = false;
|
|
|
+ mDropType = ScriptDragDropType::None;
|
|
|
+
|
|
|
+ UINT32 nativeType = DragAndDropManager::instance().getDragTypeId();
|
|
|
+
|
|
|
+ if (nativeType == (UINT32)DragAndDropType::SceneObject)
|
|
|
+ {
|
|
|
+ DraggedSceneObjects* draggedSceneObjects = reinterpret_cast<DraggedSceneObjects*>(DragAndDropManager::instance().getDragData());
|
|
|
+
|
|
|
+ for (UINT32 i = 0; i < draggedSceneObjects->numObjects; i++)
|
|
|
+ mDroppedSceneObjects.push_back(draggedSceneObjects->objects[i]);
|
|
|
+
|
|
|
+ mIsDropInProgress = true;
|
|
|
+ mDropType = ScriptDragDropType::SceneObject;
|
|
|
+ mDroppedFrameIdx = Time::instance().getFrameNumber();
|
|
|
+ }
|
|
|
+ else if (nativeType == (UINT32)DragAndDropType::Resources)
|
|
|
+ {
|
|
|
+ DraggedResources* draggedResources = reinterpret_cast<DraggedResources*>(DragAndDropManager::instance().getDragData());
|
|
|
+
|
|
|
+ // TODO - When dragging resources I also need to support dragging of resource folders, which isn't supported by this system
|
|
|
+
|
|
|
+ mIsDropInProgress = true;
|
|
|
+ mDropType = ScriptDragDropType::Resource;
|
|
|
+ mDroppedFrameIdx = Time::instance().getFrameNumber();
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|