2
0

BsMenuItemManager.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #include "BsMenuItemManager.h"
  2. #include "BsScriptAssemblyManager.h"
  3. #include "BsMonoAssembly.h"
  4. #include "BsMonoClass.h"
  5. #include "BsMonoMethod.h"
  6. #include "BsMonoField.h"
  7. #include "BsMonoManager.h"
  8. #include "BsMonoUtil.h"
  9. #include "BsScriptObjectManager.h"
  10. #include "BsShortcutKey.h"
  11. #include "BsEditorWindowManager.h"
  12. #include "BsMainEditorWindow.h"
  13. #include "BsGUIMenuBar.h"
  14. using namespace std::placeholders;
  15. namespace BansheeEngine
  16. {
  17. MenuItemManager::MenuItemManager(ScriptAssemblyManager& scriptObjectManager)
  18. :mScriptObjectManager(scriptObjectManager), mMenuItemAttribute(nullptr), mPathField(nullptr),
  19. mShortcutField(nullptr), mPriorityField(nullptr)
  20. {
  21. mDomainLoadedConn = ScriptObjectManager::instance().onRefreshDomainLoaded.connect(std::bind(&MenuItemManager::reloadAssemblyData, this));
  22. reloadAssemblyData();
  23. }
  24. MenuItemManager::~MenuItemManager()
  25. {
  26. mDomainLoadedConn.disconnect();
  27. }
  28. void MenuItemManager::clearMenuItems()
  29. {
  30. MainEditorWindow* mainWindow = EditorWindowManager::instance().getMainWindow();
  31. for (auto& menuItem : mMenuItems)
  32. mainWindow->getMenuBar().removeMenuItem(menuItem);
  33. }
  34. void MenuItemManager::reloadAssemblyData()
  35. {
  36. clearMenuItems();
  37. // Reload MenuItem attribute from editor assembly
  38. MonoAssembly* editorAssembly = MonoManager::instance().getAssembly(EDITOR_ASSEMBLY);
  39. mMenuItemAttribute = editorAssembly->getClass("BansheeEditor", "MenuItem");
  40. if (mMenuItemAttribute == nullptr)
  41. BS_EXCEPT(InvalidStateException, "Cannot find MenuItem managed class.");
  42. mPathField = mMenuItemAttribute->getField("path");
  43. mShortcutField = mMenuItemAttribute->getField("shortcut");
  44. mPriorityField = mMenuItemAttribute->getField("priority");
  45. MainEditorWindow* mainWindow = EditorWindowManager::instance().getMainWindow();
  46. Vector<String> scriptAssemblyNames = mScriptObjectManager.getScriptAssemblies();
  47. for (auto& assemblyName : scriptAssemblyNames)
  48. {
  49. MonoAssembly* assembly = MonoManager::instance().getAssembly(assemblyName);
  50. // Find new menu item methods
  51. const Vector<MonoClass*>& allClasses = assembly->getAllClasses();
  52. for (auto curClass : allClasses)
  53. {
  54. const Vector<MonoMethod*>& methods = curClass->getAllMethods();
  55. for (auto& curMethod : methods)
  56. {
  57. WString path;
  58. ShortcutKey shortcutKey = ShortcutKey::NONE;
  59. INT32 priority = 0;
  60. if (parseMenuItemMethod(curMethod, path, shortcutKey, priority))
  61. {
  62. std::function<void()> callback = std::bind(&MenuItemManager::menuItemCallback, curMethod);
  63. mainWindow->getMenuBar().addMenuItem(path, callback, priority, shortcutKey);
  64. mMenuItems.push_back(path);
  65. }
  66. }
  67. }
  68. }
  69. }
  70. bool MenuItemManager::parseMenuItemMethod(MonoMethod* method, WString& path, ShortcutKey& shortcut, INT32& priority) const
  71. {
  72. if (!method->hasAttribute(mMenuItemAttribute))
  73. return false;
  74. if (method->getNumParameters() != 0)
  75. return false;
  76. if (!method->isStatic())
  77. return false;
  78. MonoObject* menuItemAttrib = method->getAttribute(mMenuItemAttribute);
  79. MonoString* monoPath;
  80. mPathField->getValue(menuItemAttrib, &monoPath);
  81. mShortcutField->getValue(menuItemAttrib, &shortcut);
  82. path = MonoUtil::monoToWString(monoPath);
  83. mPriorityField->getValue(menuItemAttrib, &priority);
  84. return true;
  85. }
  86. void MenuItemManager::menuItemCallback(MonoMethod* method)
  87. {
  88. method->invoke(nullptr, nullptr);
  89. }
  90. }