BsGUIMenuBar.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #include "BsGUIMenuBar.h"
  2. #include "BsGUIArea.h"
  3. #include "BsGUIElement.h"
  4. #include "BsGUIButton.h"
  5. #include "BsGUITexture.h"
  6. #include "BsGUILayout.h"
  7. #include "BsGUISpace.h"
  8. #include "BsGUIMenu.h"
  9. #include "BsGUIManager.h"
  10. #include "BsEngineGUI.h"
  11. using namespace CamelotFramework;
  12. using namespace BansheeEngine;
  13. namespace BansheeEditor
  14. {
  15. GUIMenuBar::GUIMenuBar(BS::GUIWidget* parent)
  16. :mParentWidget(parent), mMainArea(nullptr), mBackgroundArea(nullptr), mBgTexture(nullptr), mLogoTexture(nullptr)
  17. {
  18. mBackgroundArea = GUIArea::create(*parent, 0, 0, 1, 13, 9900);
  19. mMainArea = GUIArea::create(*parent, 0, 0, 1, 13, 9899);
  20. mBgTexture = GUITexture::create(*parent, GUILayoutOptions::expandableXY(), GUIImageScaleMode::StretchToFit, EngineGUI::instance().getSkin().getStyle("MenuBarBg"));
  21. mBackgroundArea->getLayout().addElement(mBgTexture);
  22. mLogoTexture = GUITexture::create(*parent, GUIImageScaleMode::StretchToFit, EngineGUI::instance().getSkin().getStyle("MenuBarBansheeLogo"));
  23. mMainArea->getLayout().addElement(mLogoTexture);
  24. mMainArea->getLayout().addFlexibleSpace();
  25. }
  26. GUIMenuBar::~GUIMenuBar()
  27. {
  28. for(auto& menu : mChildMenus)
  29. {
  30. cm_delete<PoolAlloc>(menu.menu);
  31. GUIElement::destroy(menu.button);
  32. }
  33. GUIElement::destroy(mBgTexture);
  34. GUIElement::destroy(mLogoTexture);
  35. GUIArea::destroy(mMainArea);
  36. GUIArea::destroy(mBackgroundArea);
  37. }
  38. void GUIMenuBar::setArea(CM::INT32 x, CM::INT32 y, CM::UINT32 width, CM::UINT32 height)
  39. {
  40. mMainArea->setPosition(x, y);
  41. mBackgroundArea->setPosition(x, y);
  42. mMainArea->setSize(width, height);
  43. mBackgroundArea->setSize(width, height);
  44. }
  45. const GUIMenuItem* GUIMenuBar::addMenuItem(const CM::WString& path, std::function<void()> callback)
  46. {
  47. WString strippedPath = path;
  48. WString rootName;
  49. if(!stripPath(strippedPath, rootName))
  50. return nullptr;
  51. const GUIMenuBarData* subMenu = getSubMenu(rootName);
  52. if(subMenu == nullptr)
  53. {
  54. mChildMenus.push_back(GUIMenuBarData());
  55. GUIMenuBarData& newSubMenu = mChildMenus.back();
  56. newSubMenu.name = rootName;
  57. newSubMenu.menu = cm_new<GUIMenu>();
  58. GUIButton* newButton = GUIButton::create(*mParentWidget, rootName, EngineGUI::instance().getSkin().getStyle("MenuBarBtn"));
  59. mMainArea->getLayout().insertElement(mMainArea->getLayout().getNumChildren() - 1, newButton);
  60. newSubMenu.button = newButton;
  61. subMenu = &newSubMenu;
  62. }
  63. return subMenu->menu->addMenuItem(strippedPath, callback);
  64. }
  65. const GUIMenuItem* GUIMenuBar::addSeparator(const CM::WString& path)
  66. {
  67. WString strippedPath = path;
  68. WString rootName;
  69. if(!stripPath(strippedPath, rootName))
  70. return nullptr;
  71. const GUIMenuBarData* subMenu = getSubMenu(rootName);
  72. if(subMenu == nullptr)
  73. {
  74. mChildMenus.push_back(GUIMenuBarData());
  75. GUIMenuBarData& newSubMenu = mChildMenus.back();
  76. newSubMenu.name = rootName;
  77. newSubMenu.menu = cm_new<GUIMenu>();
  78. GUIButton* newButton = GUIButton::create(*mParentWidget, rootName);
  79. newButton->onClick.connect(boost::bind(&GUIMenuBar::openSubMenu, this, rootName));
  80. mMainArea->getLayout().addElement(newButton);
  81. newSubMenu.button = newButton;
  82. subMenu = &newSubMenu;
  83. }
  84. return subMenu->menu->addSeparator(strippedPath);
  85. }
  86. const GUIMenuItem* GUIMenuBar::getMenuItem(const CM::WString& path) const
  87. {
  88. WString strippedPath = path;
  89. WString rootName;
  90. if(!stripPath(strippedPath, rootName))
  91. return nullptr;
  92. const GUIMenuBarData* subMenu = getSubMenu(rootName);
  93. if(subMenu == nullptr)
  94. return nullptr;
  95. return subMenu->menu->getMenuItem(strippedPath);
  96. }
  97. void GUIMenuBar::removeMenuItem(const CM::WString& path)
  98. {
  99. WString strippedPath = path;
  100. WString rootName;
  101. if(!stripPath(strippedPath, rootName))
  102. return;
  103. if(strippedPath == L"")
  104. {
  105. UINT32 curIdx = 0;
  106. GUIMenuBarData* subMenuToRemove = nullptr;
  107. for(auto& subMenuData : mChildMenus)
  108. {
  109. if(subMenuData.name == rootName)
  110. {
  111. subMenuToRemove = &subMenuData;
  112. break;
  113. }
  114. curIdx++;
  115. }
  116. if(subMenuToRemove == nullptr)
  117. return;
  118. mMainArea->getLayout().removeElement(subMenuToRemove->button);
  119. GUIElement::destroy(subMenuToRemove->button);
  120. cm_delete<PoolAlloc>(subMenuToRemove->menu);
  121. mChildMenus.erase(mChildMenus.begin() + curIdx);
  122. return;
  123. }
  124. const GUIMenuBarData* subMenu = getSubMenu(rootName);
  125. if(subMenu == nullptr)
  126. return;
  127. const GUIMenuItem* item = subMenu->menu->getMenuItem(strippedPath);
  128. if(item == nullptr)
  129. return;
  130. subMenu->menu->removeMenuItem(item);
  131. }
  132. const GUIMenuBar::GUIMenuBarData* GUIMenuBar::getSubMenu(const CM::WString& name) const
  133. {
  134. for(auto& subMenu : mChildMenus)
  135. {
  136. if(subMenu.name == name)
  137. return &subMenu;
  138. }
  139. return nullptr;
  140. }
  141. bool GUIMenuBar::stripPath(CM::WString& path, CM::WString& pathRoot) const
  142. {
  143. Vector<WString>::type pathElements = StringUtil::split(path, L"/");
  144. if(pathElements.size() == 0)
  145. return false;
  146. pathRoot = pathElements[0];
  147. path.erase(0, pathRoot.size());
  148. if(path.size() > 0)
  149. path.erase(0, 1); // Forward slash
  150. return true;
  151. }
  152. void GUIMenuBar::openSubMenu(const CM::WString& name)
  153. {
  154. const GUIMenuBarData* subMenu = getSubMenu(name);
  155. if(subMenu == nullptr)
  156. return;
  157. GUIManager::instance().openMenuBarMenu(subMenu->button, subMenu->menu);
  158. }
  159. }