BsScriptDragDropManager.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  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 "BsScriptSceneObject.h"
  9. #include "BsScriptGameObjectManager.h"
  10. #include "BsGUISceneTreeView.h"
  11. #include "BsGUIResourceTreeView.h"
  12. #include "BsTime.h"
  13. using namespace std::placeholders;
  14. namespace BansheeEngine
  15. {
  16. ScriptDragDrop::ScriptDragDrop(MonoObject* instance)
  17. :ScriptObject(instance)
  18. { }
  19. void ScriptDragDrop::initRuntimeData()
  20. {
  21. metaData.scriptClass->addInternalCall("Internal_IsDragInProgress", &ScriptDragDrop::internal_IsDragInProgress);
  22. metaData.scriptClass->addInternalCall("Internal_IsDropInProgress", &ScriptDragDrop::internal_IsDropInProgress);
  23. metaData.scriptClass->addInternalCall("Internal_GetData", &ScriptDragDrop::internal_GetData);
  24. metaData.scriptClass->addInternalCall("Internal_GetDragType", &ScriptDragDrop::internal_GetDragType);
  25. metaData.scriptClass->addInternalCall("Internal_StartSceneObjectDrag", &ScriptDragDrop::internal_StartSceneObjectDrag);
  26. metaData.scriptClass->addInternalCall("Internal_StartResourceDrag", &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", &ScriptSceneObjectDragDropData::internal_CreateInstance);
  80. metaData.scriptClass->addInternalCall("Internal_GetObjects", &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->getNativeSceneObject();
  105. }
  106. ScriptSceneObjectDragDropData* nativeInstance = 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", &ScriptResourceDragDropData::internal_CreateInstance);
  125. metaData.scriptClass->addInternalCall("Internal_GetPaths", &ScriptResourceDragDropData::internal_GetPaths);
  126. }
  127. MonoObject* ScriptResourceDragDropData::create(const Vector<Path>& paths)
  128. {
  129. MonoArray* rawArray = mono_array_new(MonoManager::instance().getDomain(), mono_get_string_class(), (UINT32)paths.size());
  130. ScriptArray arrStrings(rawArray);
  131. UINT32 idx = 0;
  132. for (auto& path : paths)
  133. {
  134. MonoString* managedPath = MonoUtil::wstringToMono(path.toWString());
  135. arrStrings.set(idx, managedPath);
  136. idx++;
  137. }
  138. void* params[1] = { arrStrings.getInternal() };
  139. MonoObject* instance = metaData.scriptClass->createInstance(params, 1);
  140. return instance;
  141. }
  142. void ScriptResourceDragDropData::internal_CreateInstance(MonoObject* managedInstance, MonoArray* monoPaths)
  143. {
  144. ScriptArray pathsArray = ScriptArray(monoPaths);
  145. Vector<Path> paths(pathsArray.size());
  146. for (UINT32 i = 0; i < pathsArray.size(); i++)
  147. {
  148. MonoString* monoPath = pathsArray.get<MonoString*>(i);
  149. paths[i] = MonoUtil::monoToWString(monoPath);
  150. }
  151. ScriptResourceDragDropData* nativeInstance = new (bs_alloc<ScriptResourceDragDropData>()) ScriptResourceDragDropData(managedInstance, paths);
  152. }
  153. MonoArray* ScriptResourceDragDropData::internal_GetPaths(ScriptResourceDragDropData* instance)
  154. {
  155. MonoArray* rawArray = mono_array_new(MonoManager::instance().getDomain(),
  156. mono_get_string_class(), (UINT32)instance->mPaths.size());
  157. ScriptArray arrStrings(rawArray);
  158. UINT32 idx = 0;
  159. for (auto& path : instance->mPaths)
  160. {
  161. MonoString* managedPath = MonoUtil::wstringToMono(path.toWString());
  162. arrStrings.set(idx, managedPath);
  163. idx++;
  164. }
  165. return arrStrings.getInternal();
  166. }
  167. ScriptDragDropManager::ScriptDragDropManager()
  168. :mDroppedFrameIdx(0), mIsDropInProgress(false), mDropType(ScriptDragDropType::None)
  169. {
  170. mDragEndedConn = DragAndDropManager::instance().onDragEnded.connect(std::bind(&ScriptDragDropManager::onMouseDragEnded, this, _1, _2));
  171. }
  172. ScriptDragDropManager::~ScriptDragDropManager()
  173. {
  174. mDragEndedConn.disconnect();
  175. }
  176. void ScriptDragDropManager::update()
  177. {
  178. // This only stays active for a single frame
  179. if (mIsDropInProgress && mDroppedFrameIdx < Time::instance().getFrameIdx())
  180. mIsDropInProgress = false;
  181. }
  182. MonoObject* ScriptDragDropManager::getDropData() const
  183. {
  184. if (DragAndDropManager::instance().isDragInProgress())
  185. {
  186. UINT32 nativeType = DragAndDropManager::instance().getDragTypeId();
  187. if (nativeType == (UINT32)DragAndDropType::SceneObject)
  188. {
  189. DraggedSceneObjects* draggedData = reinterpret_cast<DraggedSceneObjects*>(DragAndDropManager::instance().getDragData());
  190. Vector<HSceneObject> draggedSceneObjects;
  191. for (UINT32 i = 0; i < draggedData->numObjects; i++)
  192. draggedSceneObjects.push_back(draggedData->objects[i]);
  193. return ScriptSceneObjectDragDropData::create(draggedSceneObjects);
  194. }
  195. else if (nativeType == (UINT32)DragAndDropType::Resources)
  196. {
  197. DraggedResources* draggedResources = reinterpret_cast<DraggedResources*>(DragAndDropManager::instance().getDragData());
  198. return ScriptResourceDragDropData::create(draggedResources->resourcePaths);
  199. }
  200. }
  201. else
  202. {
  203. if (mDropType == ScriptDragDropType::SceneObject)
  204. return ScriptSceneObjectDragDropData::create(mDroppedSceneObjects);
  205. else if (mDropType == ScriptDragDropType::Resource)
  206. return ScriptResourceDragDropData::create(mDroppedPaths);
  207. }
  208. return nullptr;
  209. }
  210. ScriptDragDropType ScriptDragDropManager::getDragType() const
  211. {
  212. if (DragAndDropManager::instance().isDragInProgress())
  213. {
  214. UINT32 nativeType = DragAndDropManager::instance().getDragTypeId();
  215. if (nativeType == (UINT32)DragAndDropType::SceneObject)
  216. return ScriptDragDropType::SceneObject;
  217. else if (nativeType == (UINT32)DragAndDropType::Resources)
  218. return ScriptDragDropType::Resource;
  219. return ScriptDragDropType::None;
  220. }
  221. else
  222. return mDropType;
  223. }
  224. void ScriptDragDropManager::onMouseDragEnded(const PointerEvent& evt, DragCallbackInfo& callbackInfo)
  225. {
  226. if (!DragAndDropManager::instance().isDragInProgress())
  227. return;
  228. mDroppedPaths.clear();
  229. mDroppedSceneObjects.clear();
  230. mIsDropInProgress = false;
  231. mDropType = ScriptDragDropType::None;
  232. UINT32 nativeType = DragAndDropManager::instance().getDragTypeId();
  233. if (nativeType == (UINT32)DragAndDropType::SceneObject)
  234. {
  235. DraggedSceneObjects* draggedSceneObjects = reinterpret_cast<DraggedSceneObjects*>(DragAndDropManager::instance().getDragData());
  236. for (UINT32 i = 0; i < draggedSceneObjects->numObjects; i++)
  237. mDroppedSceneObjects.push_back(draggedSceneObjects->objects[i]);
  238. mIsDropInProgress = true;
  239. mDropType = ScriptDragDropType::SceneObject;
  240. mDroppedFrameIdx = Time::instance().getFrameIdx();
  241. }
  242. else if (nativeType == (UINT32)DragAndDropType::Resources)
  243. {
  244. DraggedResources* draggedResources = reinterpret_cast<DraggedResources*>(DragAndDropManager::instance().getDragData());
  245. mDroppedPaths = draggedResources->resourcePaths;
  246. mIsDropInProgress = true;
  247. mDropType = ScriptDragDropType::Resource;
  248. mDroppedFrameIdx = Time::instance().getFrameIdx();
  249. }
  250. }
  251. }