BsScriptDropTarget.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. #include "BsScriptDropTarget.h"
  2. #include "BsScriptMeta.h"
  3. #include "BsMonoField.h"
  4. #include "BsMonoClass.h"
  5. #include "BsMonoManager.h"
  6. #include "BsMonoMethod.h"
  7. #include "BsMonoUtil.h"
  8. #include "BsMonoArray.h"
  9. #include "BsRTTIType.h"
  10. #include "BsPlatform.h"
  11. #include "BsEditorWidget.h"
  12. #include "BsEditorWindowBase.h"
  13. #include "BsEditorWidgetContainer.h"
  14. #include "BsScriptEditorWindow.h"
  15. using namespace std::placeholders;
  16. namespace BansheeEngine
  17. {
  18. ScriptDropTarget::OnEnterThunkDef ScriptDropTarget::onEnterThunk;
  19. ScriptDropTarget::OnMoveDef ScriptDropTarget::onMoveThunk;
  20. ScriptDropTarget::OnLeaveDef ScriptDropTarget::onLeaveThunk;
  21. ScriptDropTarget::OnDropThunkDef ScriptDropTarget::onDropThunk;
  22. ScriptDropTarget::ScriptDropTarget(MonoObject* instance, EditorWidgetBase* parent)
  23. :ScriptObject(instance), mDropTarget(nullptr), mIsDestroyed(false)
  24. {
  25. mWidgetParentChangedConn = parent->onParentChanged.connect(std::bind(&ScriptDropTarget::widgetParentChanged, this, _1));
  26. mWidgetResizedConn = parent->onResized.connect(std::bind(&ScriptDropTarget::widgetResized, this, _1, _2));
  27. if (parent != nullptr)
  28. {
  29. EditorWindowBase* parentWindow = parent->getParentWindow();
  30. if (parentWindow != nullptr)
  31. setDropTarget(parentWindow->getRenderWindow(), 0, 0, 0, 0);
  32. }
  33. }
  34. ScriptDropTarget::~ScriptDropTarget()
  35. {
  36. if (!mIsDestroyed)
  37. destroy();
  38. }
  39. void ScriptDropTarget::initRuntimeData()
  40. {
  41. metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptDropTarget::internal_CreateInstance);
  42. metaData.scriptClass->addInternalCall("Internal_Destroy", &ScriptDropTarget::internal_Destroy);
  43. metaData.scriptClass->addInternalCall("Internal_SetBounds", &ScriptDropTarget::internal_SetBounds);
  44. metaData.scriptClass->addInternalCall("Internal_GetFilePaths", &ScriptDropTarget::internal_GetFilePaths);
  45. onEnterThunk = (OnEnterThunkDef)metaData.scriptClass->getMethod("InternalDoOnEnter")->getThunk();
  46. onMoveThunk = (OnMoveDef)metaData.scriptClass->getMethod("InternalDoOnDrag")->getThunk();
  47. onLeaveThunk = (OnLeaveDef)metaData.scriptClass->getMethod("InternalDoOnLeave")->getThunk();
  48. onDropThunk = (OnDropThunkDef)metaData.scriptClass->getMethod("InternalDoOnDrop")->getThunk();
  49. }
  50. void ScriptDropTarget::internal_CreateInstance(MonoObject* instance, ScriptEditorWindow* editorWindow)
  51. {
  52. ScriptDropTarget* nativeInstance = new (bs_alloc<ScriptDropTarget>()) ScriptDropTarget(instance, editorWindow->getEditorWidget());
  53. }
  54. void ScriptDropTarget::internal_Destroy(ScriptDropTarget* nativeInstance)
  55. {
  56. if (nativeInstance->mIsDestroyed)
  57. return;
  58. nativeInstance->destroy();
  59. }
  60. void ScriptDropTarget::internal_SetBounds(ScriptDropTarget* nativeInstance, Rect2I bounds)
  61. {
  62. if (nativeInstance->mIsDestroyed)
  63. return;
  64. nativeInstance->setBounds(bounds);
  65. }
  66. MonoArray* ScriptDropTarget::internal_GetFilePaths(ScriptDropTarget* nativeInstance)
  67. {
  68. OSDropTarget* dropTarget = nativeInstance->mDropTarget;
  69. if (nativeInstance->mIsDestroyed || dropTarget == nullptr || dropTarget->getDropType() != OSDropType::FileList)
  70. return ScriptArray::create<String>(0).getInternal();
  71. Vector<WString> fileList = dropTarget->getFileList();
  72. ScriptArray output = ScriptArray::create<WString>((UINT32)fileList.size());
  73. UINT32 idx = 0;
  74. for (auto& path : fileList)
  75. {
  76. output.set(idx, path);
  77. idx++;
  78. }
  79. return output.getInternal();
  80. }
  81. void ScriptDropTarget::destroy()
  82. {
  83. mIsDestroyed = true;
  84. mWidgetParentChangedConn.disconnect();
  85. mWidgetResizedConn.disconnect();
  86. setDropTarget(nullptr, 0, 0, 0, 0);
  87. }
  88. void ScriptDropTarget::setDropTarget(const RenderWindowPtr& parentWindow, INT32 x, INT32 y, UINT32 width, UINT32 height)
  89. {
  90. if (mDropTarget != nullptr)
  91. {
  92. Platform::destroyDropTarget(*mDropTarget);
  93. mDropTargetEnterConn.disconnect();
  94. mDropTargetLeaveConn.disconnect();
  95. mDropTargetMoveConn.disconnect();
  96. mDropTargetDroppedConn.disconnect();
  97. }
  98. if (parentWindow != nullptr)
  99. {
  100. mDropTarget = &Platform::createDropTarget(parentWindow.get(), x, y, width, height);
  101. mDropTargetEnterConn = mDropTarget->onEnter.connect(std::bind(&ScriptDropTarget::dropTargetDragMove, getManagedInstance(), _1, _2));
  102. mDropTargetMoveConn = mDropTarget->onDragOver.connect(std::bind(&ScriptDropTarget::dropTargetDragMove, getManagedInstance(), _1, _2));
  103. mDropTargetLeaveConn = mDropTarget->onLeave.connect(std::bind(&ScriptDropTarget::dropTargetDragLeave, getManagedInstance()));
  104. mDropTargetDroppedConn = mDropTarget->onDrop.connect(std::bind(&ScriptDropTarget::dropTargetDragDropped, getManagedInstance(), _1, _2));
  105. }
  106. else
  107. mDropTarget = nullptr;
  108. }
  109. void ScriptDropTarget::setBounds(const Rect2I& bounds)
  110. {
  111. mArea = bounds;
  112. Rect2I clippedArea = mArea;
  113. clippedArea.clip(mParentArea);
  114. if (mDropTarget != nullptr)
  115. mDropTarget->setArea(mParentArea.x + clippedArea.x, mParentArea.y + clippedArea.y, clippedArea.width, clippedArea.height);
  116. }
  117. void ScriptDropTarget::dropTargetDragEnter(MonoObject* instance, INT32 x, INT32 y)
  118. {
  119. MonoException* exception = nullptr;
  120. onEnterThunk(instance, x, y, &exception);
  121. MonoUtil::throwIfException(exception);
  122. }
  123. void ScriptDropTarget::dropTargetDragMove(MonoObject* instance, INT32 x, INT32 y)
  124. {
  125. MonoException* exception = nullptr;
  126. onMoveThunk(instance, x, y, &exception);
  127. MonoUtil::throwIfException(exception);
  128. }
  129. void ScriptDropTarget::dropTargetDragLeave(MonoObject* instance)
  130. {
  131. MonoException* exception = nullptr;
  132. onLeaveThunk(instance, &exception);
  133. MonoUtil::throwIfException(exception);
  134. }
  135. void ScriptDropTarget::dropTargetDragDropped(MonoObject* instance, INT32 x, INT32 y)
  136. {
  137. MonoException* exception = nullptr;
  138. onDropThunk(instance, x, y, &exception);
  139. MonoUtil::throwIfException(exception);
  140. }
  141. void ScriptDropTarget::widgetParentChanged(EditorWidgetContainer* parent)
  142. {
  143. RenderWindowPtr parentRenderWindow;
  144. if (parent != nullptr)
  145. {
  146. EditorWindowBase* parentWindow = parent->getParentWindow();
  147. if (parentWindow != nullptr)
  148. parentRenderWindow = parentWindow->getRenderWindow();
  149. }
  150. Rect2I clippedArea = mArea;
  151. if (parentRenderWindow == nullptr)
  152. mParentArea = Rect2I();
  153. clippedArea.clip(mParentArea);
  154. setDropTarget(parentRenderWindow, mParentArea.x + clippedArea.x, mParentArea.y + clippedArea.y, clippedArea.width, clippedArea.height);
  155. }
  156. void ScriptDropTarget::widgetResized(UINT32 width, UINT32 height)
  157. {
  158. mParentArea.width = width;
  159. mParentArea.height = height;
  160. setBounds(mArea);
  161. }
  162. }