BsScriptDragDropManager.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. #include "BsScriptDragDropManager.h"
  2. #include "BsMonoManager.h"
  3. #include "BsMonoClass.h"
  4. #include "BsMonoMethod.h"
  5. #include "BsMonoUtil.h"
  6. #include "BsScriptSceneObject.h"
  7. #include "BsScriptGameObjectManager.h"
  8. #include "BsGUISceneTreeView.h"
  9. #include "BsGUIResourceTreeView.h"
  10. #include "BsTime.h"
  11. using namespace std::placeholders;
  12. namespace BansheeEngine
  13. {
  14. ScriptDragDrop::ScriptDragDrop(MonoObject* instance)
  15. :ScriptObject(instance)
  16. { }
  17. void ScriptDragDrop::initRuntimeData()
  18. {
  19. metaData.scriptClass->addInternalCall("Internal_IsDragInProgress", &ScriptDragDrop::internal_IsDragInProgress);
  20. metaData.scriptClass->addInternalCall("Internal_IsDropInProgress", &ScriptDragDrop::internal_IsDropInProgress);
  21. metaData.scriptClass->addInternalCall("Internal_GetData", &ScriptDragDrop::internal_GetData);
  22. metaData.scriptClass->addInternalCall("Internal_StartSceneObjectDrag", &ScriptDragDrop::internal_StartSceneObjectDrag);
  23. metaData.scriptClass->addInternalCall("Internal_StartResourceDrag", &ScriptDragDrop::internal_StartResourceDrag);
  24. }
  25. bool ScriptDragDrop::internal_IsDragInProgress()
  26. {
  27. return DragAndDropManager::instance().isDragInProgress();
  28. }
  29. bool ScriptDragDrop::internal_IsDropInProgress()
  30. {
  31. return ScriptDragDropManager::instance().isDropInProgress();
  32. }
  33. MonoObject* ScriptDragDrop::internal_GetData()
  34. {
  35. return ScriptDragDropManager::instance().getDropData();
  36. }
  37. void ScriptDragDrop::internal_StartSceneObjectDrag(ScriptSceneObjectDragDropData* value)
  38. {
  39. const Vector<HSceneObject>& sceneObjects = value->getSceneObjects();
  40. DraggedSceneObjects* draggedSceneObjects = bs_new<DraggedSceneObjects>((UINT32)sceneObjects.size());
  41. UINT32 idx = 0;
  42. for (auto& so : sceneObjects)
  43. {
  44. draggedSceneObjects->objects[idx] = so;
  45. idx++;
  46. }
  47. DragAndDropManager::instance().startDrag((UINT32)DragAndDropType::SceneObject, draggedSceneObjects,
  48. &ScriptDragDrop::sceneObjectDragDropFinalize, false);
  49. }
  50. void ScriptDragDrop::internal_StartResourceDrag(ScriptResourceDragDropData* value)
  51. {
  52. DraggedResources* draggedResources = bs_new<DraggedResources>();
  53. draggedResources->resourcePaths = value->getPaths();
  54. DragAndDropManager::instance().startDrag((UINT32)DragAndDropType::Resources, draggedResources,
  55. &ScriptDragDrop::resourceDragDropFinalize, false);
  56. }
  57. void ScriptDragDrop::sceneObjectDragDropFinalize(bool processed)
  58. {
  59. DraggedSceneObjects* draggedSceneObjects = reinterpret_cast<DraggedSceneObjects*>(DragAndDropManager::instance().getDragData());
  60. bs_delete(draggedSceneObjects);
  61. }
  62. void ScriptDragDrop::resourceDragDropFinalize(bool processed)
  63. {
  64. DraggedResources* draggedResources = reinterpret_cast<DraggedResources*>(DragAndDropManager::instance().getDragData());
  65. bs_delete(draggedResources);
  66. }
  67. ScriptSceneObjectDragDropData::ScriptSceneObjectDragDropData(MonoObject* instance, const Vector<HSceneObject>& sceneObjects)
  68. :ScriptObject(instance), mSceneObjects(sceneObjects)
  69. { }
  70. void ScriptSceneObjectDragDropData::initRuntimeData()
  71. {
  72. metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptSceneObjectDragDropData::internal_CreateInstance);
  73. metaData.scriptClass->addInternalCall("Internal_GetObjects", &ScriptSceneObjectDragDropData::internal_GetObjects);
  74. }
  75. MonoObject* ScriptSceneObjectDragDropData::create(const Vector<HSceneObject>& sceneObjects)
  76. {
  77. ScriptArray arrSceneObjects = ScriptArray::create<ScriptSceneObject>((UINT32)sceneObjects.size());
  78. UINT32 idx = 0;
  79. for (auto& so : sceneObjects)
  80. {
  81. ScriptSceneObject* scriptSceneObject = ScriptGameObjectManager::instance().getOrCreateScriptSceneObject(so);
  82. arrSceneObjects.set(idx, scriptSceneObject);
  83. idx++;
  84. }
  85. void* params[1] = { arrSceneObjects.getInternal() };
  86. MonoObject* instance = metaData.scriptClass->createInstance(params, 1);
  87. return instance;
  88. }
  89. void ScriptSceneObjectDragDropData::internal_CreateInstance(MonoObject* managedInstance, MonoArray* objects)
  90. {
  91. ScriptArray objectsArray = ScriptArray(objects);
  92. Vector<HSceneObject> sceneObjects(objectsArray.size());
  93. for (UINT32 i = 0; i < objectsArray.size(); i++)
  94. {
  95. ScriptSceneObject* scriptSO = ScriptSceneObject::toNative(objectsArray.get<MonoObject*>(i));
  96. if (scriptSO != nullptr)
  97. sceneObjects[i] = scriptSO->getNativeSceneObject();
  98. }
  99. ScriptSceneObjectDragDropData* nativeInstance = new (bs_alloc<ScriptSceneObjectDragDropData>()) ScriptSceneObjectDragDropData(managedInstance, sceneObjects);
  100. }
  101. MonoArray* ScriptSceneObjectDragDropData::internal_GetObjects(ScriptSceneObjectDragDropData* instance)
  102. {
  103. ScriptArray objectsArray = ScriptArray::create<ScriptSceneObject>((UINT32)instance->mSceneObjects.size());
  104. for (UINT32 i = 0; i < (UINT32)instance->mSceneObjects.size(); i++)
  105. {
  106. ScriptSceneObject* scriptSO = ScriptGameObjectManager::instance().getOrCreateScriptSceneObject(instance->mSceneObjects[i]);
  107. if (scriptSO != nullptr)
  108. objectsArray.set(i, scriptSO->getManagedInstance());
  109. }
  110. return objectsArray.getInternal();
  111. }
  112. ScriptResourceDragDropData::ScriptResourceDragDropData(MonoObject* instance, const Vector<Path>& paths)
  113. :ScriptObject(instance), mPaths(paths)
  114. { }
  115. void ScriptResourceDragDropData::initRuntimeData()
  116. {
  117. metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptResourceDragDropData::internal_CreateInstance);
  118. metaData.scriptClass->addInternalCall("Internal_GetPaths", &ScriptResourceDragDropData::internal_GetPaths);
  119. }
  120. MonoObject* ScriptResourceDragDropData::create(const Vector<Path>& paths)
  121. {
  122. MonoArray* rawArray = mono_array_new(MonoManager::instance().getDomain(), mono_get_string_class(), (UINT32)paths.size());
  123. ScriptArray arrStrings(rawArray);
  124. UINT32 idx = 0;
  125. for (auto& path : paths)
  126. {
  127. MonoString* managedPath = MonoUtil::wstringToMono(MonoManager::instance().getDomain(), path.toWString());
  128. arrStrings.set(idx, managedPath);
  129. idx++;
  130. }
  131. void* params[1] = { arrStrings.getInternal() };
  132. MonoObject* instance = metaData.scriptClass->createInstance(params, 1);
  133. return instance;
  134. }
  135. void ScriptResourceDragDropData::internal_CreateInstance(MonoObject* managedInstance, MonoArray* monoPaths)
  136. {
  137. ScriptArray pathsArray = ScriptArray(monoPaths);
  138. Vector<Path> paths(pathsArray.size());
  139. for (UINT32 i = 0; i < pathsArray.size(); i++)
  140. {
  141. MonoString* monoPath = pathsArray.get<MonoString*>(i);
  142. paths[i] = MonoUtil::monoToWString(monoPath);
  143. }
  144. ScriptResourceDragDropData* nativeInstance = new (bs_alloc<ScriptResourceDragDropData>()) ScriptResourceDragDropData(managedInstance, paths);
  145. }
  146. MonoArray* ScriptResourceDragDropData::internal_GetPaths(ScriptResourceDragDropData* instance)
  147. {
  148. MonoArray* rawArray = mono_array_new(MonoManager::instance().getDomain(),
  149. mono_get_string_class(), (UINT32)instance->mPaths.size());
  150. ScriptArray arrStrings(rawArray);
  151. UINT32 idx = 0;
  152. for (auto& path : instance->mPaths)
  153. {
  154. MonoString* managedPath = MonoUtil::wstringToMono(MonoManager::instance().getDomain(), path.toWString());
  155. arrStrings.set(idx, managedPath);
  156. idx++;
  157. }
  158. return arrStrings.getInternal();
  159. }
  160. ScriptDragDropManager::ScriptDragDropManager()
  161. :mDroppedFrameIdx(0), mIsDropInProgress(false), mDropType(ScriptDragDropType::None)
  162. {
  163. mDragEndedConn = DragAndDropManager::instance().onDragEnded.connect(std::bind(&ScriptDragDropManager::onMouseDragEnded, this, _1, _2));
  164. }
  165. ScriptDragDropManager::~ScriptDragDropManager()
  166. {
  167. mDragEndedConn.disconnect();
  168. }
  169. void ScriptDragDropManager::update()
  170. {
  171. // This only stays active for a single frame
  172. if (mIsDropInProgress && mDroppedFrameIdx < Time::instance().getFrameNumber())
  173. mIsDropInProgress = false;
  174. }
  175. MonoObject* ScriptDragDropManager::getDropData() const
  176. {
  177. if (mDropType == ScriptDragDropType::SceneObject)
  178. return ScriptSceneObjectDragDropData::create(mDroppedSceneObjects);
  179. else if (mDropType == ScriptDragDropType::Resource)
  180. return ScriptResourceDragDropData::create(mDroppedPaths);
  181. return nullptr;
  182. }
  183. void ScriptDragDropManager::onMouseDragEnded(const PointerEvent& evt, DragCallbackInfo& callbackInfo)
  184. {
  185. if (!DragAndDropManager::instance().isDragInProgress())
  186. return;
  187. mDroppedPaths.clear();
  188. mDroppedSceneObjects.clear();
  189. mIsDropInProgress = false;
  190. mDropType = ScriptDragDropType::None;
  191. UINT32 nativeType = DragAndDropManager::instance().getDragTypeId();
  192. if (nativeType == (UINT32)DragAndDropType::SceneObject)
  193. {
  194. DraggedSceneObjects* draggedSceneObjects = reinterpret_cast<DraggedSceneObjects*>(DragAndDropManager::instance().getDragData());
  195. for (UINT32 i = 0; i < draggedSceneObjects->numObjects; i++)
  196. mDroppedSceneObjects.push_back(draggedSceneObjects->objects[i]);
  197. mIsDropInProgress = true;
  198. mDropType = ScriptDragDropType::SceneObject;
  199. mDroppedFrameIdx = Time::instance().getFrameNumber();
  200. }
  201. else if (nativeType == (UINT32)DragAndDropType::Resources)
  202. {
  203. DraggedResources* draggedResources = reinterpret_cast<DraggedResources*>(DragAndDropManager::instance().getDragData());
  204. mDroppedPaths = draggedResources->resourcePaths;
  205. mIsDropInProgress = true;
  206. mDropType = ScriptDragDropType::Resource;
  207. mDroppedFrameIdx = Time::instance().getFrameNumber();
  208. }
  209. }
  210. }