BsScriptDragDropManager.cpp 9.7 KB

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