BsScriptDropDownWindow.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "Wrappers/BsScriptDropDownWindow.h"
  4. #include "BsScriptMeta.h"
  5. #include "BsMonoField.h"
  6. #include "BsMonoClass.h"
  7. #include "BsMonoMethod.h"
  8. #include "BsMonoAssembly.h"
  9. #include "BsMonoManager.h"
  10. #include "BsMonoUtil.h"
  11. #include "Wrappers/GUI/BsScriptGUILayout.h"
  12. #include "Wrappers/BsScriptEditorWindow.h"
  13. #include "EditorWindow/BsEditorWidget.h"
  14. #include "EditorWindow/BsEditorWindow.h"
  15. #include "EditorWindow/BsEditorWidgetContainer.h"
  16. #include "GUI/BsCGUIWidget.h"
  17. #include "EditorWindow/BsDropDownWindowManager.h"
  18. #include "BsScriptObjectManager.h"
  19. using namespace std::placeholders;
  20. namespace bs
  21. {
  22. MonoField* ScriptDropDownWindow::guiPanelField = nullptr;
  23. ScriptDropDownWindow::ScriptDropDownWindow(ManagedDropDownWindow* window)
  24. :ScriptObject(window->getManagedInstance()), mDropDownWindow(window)
  25. {
  26. mOnAssemblyRefreshStartedConn = ScriptObjectManager::instance().onRefreshStarted.connect(std::bind(&ScriptDropDownWindow::onAssemblyRefreshStarted, this));
  27. }
  28. ScriptDropDownWindow::~ScriptDropDownWindow()
  29. {
  30. mOnAssemblyRefreshStartedConn.disconnect();
  31. // Window must have been marked as deleted already
  32. assert(mDropDownWindow == nullptr);
  33. }
  34. void ScriptDropDownWindow::initRuntimeData()
  35. {
  36. metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptDropDownWindow::internal_CreateInstance);
  37. metaData.scriptClass->addInternalCall("Internal_Close", &ScriptDropDownWindow::internal_Close);
  38. metaData.scriptClass->addInternalCall("Internal_GetWidth", &ScriptDropDownWindow::internal_GetWidth);
  39. metaData.scriptClass->addInternalCall("Internal_SetWidth", &ScriptDropDownWindow::internal_SetWidth);
  40. metaData.scriptClass->addInternalCall("Internal_GetHeight", &ScriptDropDownWindow::internal_GetHeight);
  41. metaData.scriptClass->addInternalCall("Internal_SetHeight", &ScriptDropDownWindow::internal_SetHeight);
  42. metaData.scriptClass->addInternalCall("Internal_ScreenToWindowPos", &ScriptDropDownWindow::internal_ScreenToWindowPos);
  43. metaData.scriptClass->addInternalCall("Internal_WindowToScreenPos", &ScriptDropDownWindow::internal_WindowToScreenPos);
  44. guiPanelField = metaData.scriptClass->getField("GUI");
  45. }
  46. MonoObject* ScriptDropDownWindow::internal_CreateInstance(MonoString* ns, MonoString* typeName,
  47. ScriptEditorWindow* parentWindow, Vector2I* position)
  48. {
  49. String strTypeName = toString(MonoUtil::monoToWString(typeName));
  50. String strNamespace = toString(MonoUtil::monoToWString(ns));
  51. String fullName = strNamespace + "." + strTypeName;
  52. MonoClass* windowClass = MonoManager::instance().findClass(strNamespace, strTypeName);
  53. if (windowClass == nullptr)
  54. return nullptr;
  55. MonoAssembly* assembly = MonoManager::instance().getAssembly(EDITOR_ASSEMBLY);
  56. MonoClass* defaultSizeAttrib = assembly->getClass("BansheeEditor", "DefaultSize");
  57. if (defaultSizeAttrib == nullptr)
  58. BS_EXCEPT(InternalErrorException, "Cannot find DefaultSize managed class.");
  59. MonoField* defaultWidthField = defaultSizeAttrib->getField("width");
  60. MonoField* defaultHeightField = defaultSizeAttrib->getField("height");
  61. int width = 200;
  62. int height = 200;
  63. MonoObject* defaultSizeObj = windowClass->getAttribute(defaultSizeAttrib);
  64. if (defaultSizeObj != nullptr)
  65. {
  66. defaultWidthField->get(defaultSizeObj, &width);
  67. defaultHeightField->get(defaultSizeObj, &height);
  68. }
  69. MonoObject* instance = windowClass->createInstance(false);
  70. ManagedDropDownWindow* dropDownWindow = nullptr;
  71. if (parentWindow != nullptr && !parentWindow->isDestroyed())
  72. {
  73. EditorWidgetBase* editorWidget = parentWindow->getEditorWidget();
  74. EditorWidgetContainer* parentContainer = editorWidget->_getParent();
  75. if (parentContainer != nullptr)
  76. {
  77. SPtr<RenderWindow> parentRenderWindow = parentContainer->getParentWindow()->getRenderWindow();
  78. SPtr<Camera> parentCamera = parentContainer->getParentWidget().getCamera();
  79. position->x += editorWidget->getX();
  80. position->y += editorWidget->getY();
  81. dropDownWindow = DropDownWindowManager::instance().open<ManagedDropDownWindow>(
  82. parentRenderWindow, parentCamera, *position, instance, width, height);
  83. }
  84. }
  85. ScriptDropDownWindow* nativeInstance = new (bs_alloc<ScriptDropDownWindow>()) ScriptDropDownWindow(dropDownWindow);
  86. if (dropDownWindow != nullptr)
  87. dropDownWindow->initialize(nativeInstance);
  88. windowClass->construct(instance);
  89. return instance;
  90. }
  91. void ScriptDropDownWindow::internal_Close(ScriptDropDownWindow* thisPtr)
  92. {
  93. if (thisPtr->mDropDownWindow != nullptr)
  94. DropDownWindowManager::instance().close();
  95. }
  96. void ScriptDropDownWindow::onAssemblyRefreshStarted()
  97. {
  98. if (mDropDownWindow != nullptr)
  99. DropDownWindowManager::instance().close();
  100. }
  101. void ScriptDropDownWindow::notifyWindowClosed()
  102. {
  103. mDropDownWindow = nullptr;
  104. }
  105. UINT32 ScriptDropDownWindow::internal_GetWidth(ScriptDropDownWindow* thisPtr)
  106. {
  107. if (thisPtr->mDropDownWindow != nullptr)
  108. return thisPtr->mDropDownWindow->getWidth();
  109. return 0;
  110. }
  111. void ScriptDropDownWindow::internal_SetWidth(ScriptDropDownWindow* thisPtr, UINT32 value)
  112. {
  113. if (thisPtr->mDropDownWindow != nullptr)
  114. thisPtr->mDropDownWindow->setSize(value, thisPtr->mDropDownWindow->getHeight());
  115. }
  116. UINT32 ScriptDropDownWindow::internal_GetHeight(ScriptDropDownWindow* thisPtr)
  117. {
  118. if (thisPtr->mDropDownWindow != nullptr)
  119. return thisPtr->mDropDownWindow->getHeight();
  120. return 0;
  121. }
  122. void ScriptDropDownWindow::internal_SetHeight(ScriptDropDownWindow* thisPtr, UINT32 value)
  123. {
  124. if (thisPtr->mDropDownWindow != nullptr)
  125. thisPtr->mDropDownWindow->setSize(thisPtr->mDropDownWindow->getWidth(), value);
  126. }
  127. void ScriptDropDownWindow::internal_ScreenToWindowPos(ScriptDropDownWindow* thisPtr, Vector2I* screenPos, Vector2I* windowPos)
  128. {
  129. if (thisPtr->mDropDownWindow != nullptr)
  130. *windowPos = thisPtr->mDropDownWindow->screenToWindowPos(*screenPos);
  131. else
  132. *windowPos = *screenPos;
  133. }
  134. void ScriptDropDownWindow::internal_WindowToScreenPos(ScriptDropDownWindow* thisPtr, Vector2I* windowPos, Vector2I* screenPos)
  135. {
  136. if (thisPtr->mDropDownWindow != nullptr)
  137. *screenPos = thisPtr->mDropDownWindow->windowToScreenPos(*windowPos);
  138. else
  139. *screenPos = *windowPos;
  140. }
  141. ManagedDropDownWindow::ManagedDropDownWindow(const SPtr<RenderWindow>& parent, const SPtr<Camera>& camera,
  142. const Vector2I& position, MonoObject* managedInstance, UINT32 width, UINT32 height)
  143. : DropDownWindow(parent, camera, position, width, height), mOnInitializeThunk(nullptr), mOnDestroyThunk(nullptr)
  144. , mUpdateThunk(nullptr), mIsInitialized(false), mManagedInstance(managedInstance), mGCHandle(0)
  145. , mScriptParent(nullptr), mContentsPanel(nullptr)
  146. {
  147. mGCHandle = MonoUtil::newGCHandle(mManagedInstance);
  148. MonoObject* guiPanel = ScriptGUIPanel::createFromExisting(mContents);
  149. mContentsPanel = ScriptGUILayout::toNative(guiPanel);
  150. ScriptDropDownWindow::guiPanelField->set(mManagedInstance, guiPanel);
  151. ::MonoClass* rawMonoClass = MonoUtil::getClass(mManagedInstance);
  152. MonoClass* monoClass = MonoManager::instance().findClass(rawMonoClass);
  153. mNamespace = monoClass->getNamespace();
  154. mTypename = monoClass->getTypeName();
  155. reloadMonoTypes(monoClass);
  156. }
  157. ManagedDropDownWindow::~ManagedDropDownWindow()
  158. {
  159. mContentsPanel->destroy();
  160. mContentsPanel = nullptr;
  161. triggerOnDestroy();
  162. mScriptParent->notifyWindowClosed();
  163. MonoUtil::freeGCHandle(mGCHandle);
  164. mGCHandle = 0;
  165. }
  166. void ManagedDropDownWindow::initialize(ScriptDropDownWindow* parent)
  167. {
  168. mScriptParent = parent;
  169. }
  170. void ManagedDropDownWindow::triggerOnInitialize()
  171. {
  172. if (mOnInitializeThunk != nullptr && mManagedInstance != nullptr)
  173. {
  174. // Note: Not calling virtual methods. Can be easily done if needed but for now doing this
  175. // for some extra speed.
  176. MonoUtil::invokeThunk(mOnInitializeThunk, mManagedInstance);
  177. }
  178. }
  179. void ManagedDropDownWindow::triggerOnDestroy()
  180. {
  181. if (mOnDestroyThunk != nullptr && mManagedInstance != nullptr)
  182. {
  183. // Note: Not calling virtual methods. Can be easily done if needed but for now doing this
  184. // for some extra speed.
  185. MonoUtil::invokeThunk(mOnDestroyThunk, mManagedInstance);
  186. }
  187. }
  188. void ManagedDropDownWindow::update()
  189. {
  190. if (!mIsInitialized)
  191. {
  192. triggerOnInitialize();
  193. mIsInitialized = true;
  194. }
  195. if (mUpdateThunk != nullptr && mManagedInstance != nullptr)
  196. {
  197. // Note: Not calling virtual methods. Can be easily done if needed but for now doing this
  198. // for some extra speed.
  199. MonoUtil::invokeThunk(mUpdateThunk, mManagedInstance);
  200. }
  201. }
  202. void ManagedDropDownWindow::reloadMonoTypes(MonoClass* windowClass)
  203. {
  204. MonoMethod* updateMethod = windowClass->getMethod("OnEditorUpdate", 0);
  205. if (updateMethod != nullptr)
  206. mUpdateThunk = (UpdateThunkDef)updateMethod->getThunk();
  207. MonoMethod* onInitializeMethod = windowClass->getMethod("OnInitialize", 0);
  208. if (onInitializeMethod != nullptr)
  209. mOnInitializeThunk = (OnInitializeThunkDef)onInitializeMethod->getThunk();
  210. MonoMethod* onDestroyMethod = windowClass->getMethod("OnDestroy", 0);
  211. if (onDestroyMethod != nullptr)
  212. mOnDestroyThunk = (OnDestroyThunkDef)onDestroyMethod->getThunk();
  213. }
  214. }