BsScriptDragDropManager.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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, nullptr, false);
  48. }
  49. void ScriptDragDrop::internal_StartResourceDrag(ScriptResourceDragDropData* value)
  50. {
  51. // TODO
  52. }
  53. ScriptSceneObjectDragDropData::ScriptSceneObjectDragDropData(MonoObject* instance, const Vector<HSceneObject>& sceneObjects)
  54. :ScriptObject(instance), mSceneObjects(sceneObjects)
  55. { }
  56. void ScriptSceneObjectDragDropData::initRuntimeData()
  57. {
  58. metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptSceneObjectDragDropData::internal_CreateInstance);
  59. metaData.scriptClass->addInternalCall("Internal_GetObjects", &ScriptSceneObjectDragDropData::internal_GetObjects);
  60. }
  61. MonoObject* ScriptSceneObjectDragDropData::create(const Vector<HSceneObject>& sceneObjects)
  62. {
  63. ScriptArray arrSceneObjects = ScriptArray::create<ScriptSceneObject>((UINT32)sceneObjects.size());
  64. UINT32 idx = 0;
  65. for (auto& so : sceneObjects)
  66. {
  67. ScriptSceneObject* scriptSceneObject = ScriptGameObjectManager::instance().getOrCreateScriptSceneObject(so);
  68. arrSceneObjects.set(idx, scriptSceneObject);
  69. idx++;
  70. }
  71. void* params[1] = { arrSceneObjects.getInternal() };
  72. MonoObject* instance = metaData.scriptClass->createInstance(params, 1);
  73. return instance;
  74. }
  75. void ScriptSceneObjectDragDropData::internal_CreateInstance(MonoObject* managedInstance, MonoArray* objects)
  76. {
  77. ScriptArray objectsArray = ScriptArray(objects);
  78. Vector<HSceneObject> sceneObjects(objectsArray.size());
  79. for (UINT32 i = 0; i < objectsArray.size(); i++)
  80. {
  81. ScriptSceneObject* scriptSO = ScriptSceneObject::toNative(objectsArray.get<MonoObject*>(i));
  82. if (scriptSO != nullptr)
  83. sceneObjects[i] = scriptSO->getNativeSceneObject();
  84. }
  85. ScriptSceneObjectDragDropData* nativeInstance = new (bs_alloc<ScriptSceneObjectDragDropData>()) ScriptSceneObjectDragDropData(managedInstance, sceneObjects);
  86. }
  87. MonoArray* ScriptSceneObjectDragDropData::internal_GetObjects(ScriptSceneObjectDragDropData* instance)
  88. {
  89. ScriptArray objectsArray = ScriptArray::create<ScriptSceneObject>((UINT32)instance->mSceneObjects.size());
  90. for (UINT32 i = 0; i < (UINT32)instance->mSceneObjects.size(); i++)
  91. {
  92. ScriptSceneObject* scriptSO = ScriptGameObjectManager::instance().getOrCreateScriptSceneObject(instance->mSceneObjects[i]);
  93. if (scriptSO != nullptr)
  94. objectsArray.set(i, scriptSO->getManagedInstance());
  95. }
  96. return objectsArray.getInternal();
  97. }
  98. ScriptResourceDragDropData::ScriptResourceDragDropData(MonoObject* instance, const Vector<Path>& paths)
  99. :ScriptObject(instance), mPaths(paths)
  100. { }
  101. void ScriptResourceDragDropData::initRuntimeData()
  102. {
  103. metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptResourceDragDropData::internal_CreateInstance);
  104. metaData.scriptClass->addInternalCall("Internal_GetPaths", &ScriptResourceDragDropData::internal_GetPaths);
  105. }
  106. MonoObject* ScriptResourceDragDropData::create(const Vector<Path>& paths)
  107. {
  108. MonoArray* rawArray = mono_array_new(MonoManager::instance().getDomain(), mono_get_string_class(), (UINT32)paths.size());
  109. ScriptArray arrStrings(rawArray);
  110. UINT32 idx = 0;
  111. for (auto& path : paths)
  112. {
  113. MonoString* managedPath = MonoUtil::wstringToMono(MonoManager::instance().getDomain(), path.toWString());
  114. arrStrings.set(idx, managedPath);
  115. idx++;
  116. }
  117. void* params[1] = { arrStrings.getInternal() };
  118. MonoObject* instance = metaData.scriptClass->createInstance(params, 1);
  119. return instance;
  120. }
  121. void ScriptResourceDragDropData::internal_CreateInstance(MonoObject* managedInstance, MonoArray* monoPaths)
  122. {
  123. ScriptArray pathsArray = ScriptArray(monoPaths);
  124. Vector<Path> paths(pathsArray.size());
  125. for (UINT32 i = 0; i < pathsArray.size(); i++)
  126. {
  127. MonoString* monoPath = pathsArray.get<MonoString*>(i);
  128. paths[i] = MonoUtil::monoToWString(monoPath);
  129. }
  130. ScriptResourceDragDropData* nativeInstance = new (bs_alloc<ScriptResourceDragDropData>()) ScriptResourceDragDropData(managedInstance, paths);
  131. }
  132. MonoArray* ScriptResourceDragDropData::internal_GetPaths(ScriptResourceDragDropData* instance)
  133. {
  134. MonoArray* rawArray = mono_array_new(MonoManager::instance().getDomain(),
  135. mono_get_string_class(), (UINT32)instance->mPaths.size());
  136. ScriptArray arrStrings(rawArray);
  137. UINT32 idx = 0;
  138. for (auto& path : instance->mPaths)
  139. {
  140. MonoString* managedPath = MonoUtil::wstringToMono(MonoManager::instance().getDomain(), path.toWString());
  141. arrStrings.set(idx, managedPath);
  142. idx++;
  143. }
  144. return arrStrings.getInternal();
  145. }
  146. ScriptDragDropManager::ScriptDragDropManager()
  147. :mDroppedFrameIdx(0), mIsDropInProgress(false), mDropType(ScriptDragDropType::None)
  148. {
  149. mDragEndedConn = DragAndDropManager::instance().onDragEnded.connect(std::bind(&ScriptDragDropManager::onMouseDragEnded, this, _1, _2));
  150. }
  151. ScriptDragDropManager::~ScriptDragDropManager()
  152. {
  153. mDragEndedConn.disconnect();
  154. }
  155. void ScriptDragDropManager::update()
  156. {
  157. // This only stays active for a single frame
  158. if (mIsDropInProgress && mDroppedFrameIdx < Time::instance().getFrameNumber())
  159. mIsDropInProgress = false;
  160. }
  161. MonoObject* ScriptDragDropManager::getDropData() const
  162. {
  163. if (mDropType == ScriptDragDropType::SceneObject)
  164. return ScriptSceneObjectDragDropData::create(mDroppedSceneObjects);
  165. else if (mDropType == ScriptDragDropType::Resource)
  166. return ScriptResourceDragDropData::create(mDroppedPaths);
  167. return nullptr;
  168. }
  169. void ScriptDragDropManager::onMouseDragEnded(const PointerEvent& evt, DragCallbackInfo& callbackInfo)
  170. {
  171. if (!DragAndDropManager::instance().isDragInProgress())
  172. return;
  173. mDroppedPaths.clear();
  174. mDroppedSceneObjects.clear();
  175. mIsDropInProgress = false;
  176. mDropType = ScriptDragDropType::None;
  177. UINT32 nativeType = DragAndDropManager::instance().getDragTypeId();
  178. if (nativeType == (UINT32)DragAndDropType::SceneObject)
  179. {
  180. DraggedSceneObjects* draggedSceneObjects = reinterpret_cast<DraggedSceneObjects*>(DragAndDropManager::instance().getDragData());
  181. for (UINT32 i = 0; i < draggedSceneObjects->numObjects; i++)
  182. mDroppedSceneObjects.push_back(draggedSceneObjects->objects[i]);
  183. mIsDropInProgress = true;
  184. mDropType = ScriptDragDropType::SceneObject;
  185. mDroppedFrameIdx = Time::instance().getFrameNumber();
  186. }
  187. else if (nativeType == (UINT32)DragAndDropType::Resources)
  188. {
  189. DraggedResources* draggedResources = reinterpret_cast<DraggedResources*>(DragAndDropManager::instance().getDragData());
  190. // TODO - When dragging resources I also need to support dragging of resource folders, which isn't supported by this system
  191. mIsDropInProgress = true;
  192. mDropType = ScriptDragDropType::Resource;
  193. mDroppedFrameIdx = Time::instance().getFrameNumber();
  194. }
  195. }
  196. }