BsScriptDragDropManager.cpp 11 KB

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