BsGUIMenuBar.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  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().addSpace(5);
  25. mMainArea->getLayout().addFlexibleSpace();
  26. }
  27. GUIMenuBar::~GUIMenuBar()
  28. {
  29. for(auto& menu : mChildMenus)
  30. {
  31. cm_delete<PoolAlloc>(menu.menu);
  32. GUIElement::destroy(menu.button);
  33. }
  34. GUIElement::destroy(mBgTexture);
  35. GUIElement::destroy(mLogoTexture);
  36. GUIArea::destroy(mMainArea);
  37. GUIArea::destroy(mBackgroundArea);
  38. }
  39. void GUIMenuBar::setArea(CM::INT32 x, CM::INT32 y, CM::UINT32 width, CM::UINT32 height)
  40. {
  41. mMainArea->setPosition(x, y);
  42. mBackgroundArea->setPosition(x, y);
  43. mMainArea->setSize(width, height);
  44. mBackgroundArea->setSize(width, height);
  45. }
  46. const GUIMenuItem* GUIMenuBar::addMenuItem(const CM::WString& path, std::function<void()> callback)
  47. {
  48. WString strippedPath = path;
  49. WString rootName;
  50. if(!stripPath(strippedPath, rootName))
  51. return nullptr;
  52. const GUIMenuBarData* subMenu = getSubMenu(rootName);
  53. if(subMenu == nullptr)
  54. {
  55. mChildMenus.push_back(GUIMenuBarData());
  56. GUIMenuBarData& newSubMenu = mChildMenus.back();
  57. newSubMenu.name = rootName;
  58. newSubMenu.menu = cm_new<GUIMenu>();
  59. GUIButton* newButton = GUIButton::create(*mParentWidget, rootName, EngineGUI::instance().getSkin().getStyle("MenuBarBtn"));
  60. newButton->onClick.connect(boost::bind(&GUIMenuBar::openSubMenu, this, rootName));
  61. mMainArea->getLayout().insertElement(mMainArea->getLayout().getNumChildren() - 1, newButton);
  62. newSubMenu.button = newButton;
  63. subMenu = &newSubMenu;
  64. }
  65. return subMenu->menu->addMenuItem(strippedPath, callback);
  66. }
  67. const GUIMenuItem* GUIMenuBar::addSeparator(const CM::WString& path)
  68. {
  69. WString strippedPath = path;
  70. WString rootName;
  71. if(!stripPath(strippedPath, rootName))
  72. return nullptr;
  73. const GUIMenuBarData* subMenu = getSubMenu(rootName);
  74. if(subMenu == nullptr)
  75. {
  76. mChildMenus.push_back(GUIMenuBarData());
  77. GUIMenuBarData& newSubMenu = mChildMenus.back();
  78. newSubMenu.name = rootName;
  79. newSubMenu.menu = cm_new<GUIMenu>();
  80. GUIButton* newButton = GUIButton::create(*mParentWidget, rootName, EngineGUI::instance().getSkin().getStyle("MenuBarBtn"));
  81. newButton->onClick.connect(boost::bind(&GUIMenuBar::openSubMenu, this, rootName));
  82. mMainArea->getLayout().insertElement(mMainArea->getLayout().getNumChildren() - 1, newButton);
  83. newSubMenu.button = newButton;
  84. subMenu = &newSubMenu;
  85. }
  86. return subMenu->menu->addSeparator(strippedPath);
  87. }
  88. const GUIMenuItem* GUIMenuBar::getMenuItem(const CM::WString& path) const
  89. {
  90. WString strippedPath = path;
  91. WString rootName;
  92. if(!stripPath(strippedPath, rootName))
  93. return nullptr;
  94. const GUIMenuBarData* subMenu = getSubMenu(rootName);
  95. if(subMenu == nullptr)
  96. return nullptr;
  97. return subMenu->menu->getMenuItem(strippedPath);
  98. }
  99. void GUIMenuBar::removeMenuItem(const CM::WString& path)
  100. {
  101. WString strippedPath = path;
  102. WString rootName;
  103. if(!stripPath(strippedPath, rootName))
  104. return;
  105. if(strippedPath == L"")
  106. {
  107. UINT32 curIdx = 0;
  108. GUIMenuBarData* subMenuToRemove = nullptr;
  109. for(auto& subMenuData : mChildMenus)
  110. {
  111. if(subMenuData.name == rootName)
  112. {
  113. subMenuToRemove = &subMenuData;
  114. break;
  115. }
  116. curIdx++;
  117. }
  118. if(subMenuToRemove == nullptr)
  119. return;
  120. mMainArea->getLayout().removeElement(subMenuToRemove->button);
  121. GUIElement::destroy(subMenuToRemove->button);
  122. cm_delete<PoolAlloc>(subMenuToRemove->menu);
  123. mChildMenus.erase(mChildMenus.begin() + curIdx);
  124. return;
  125. }
  126. const GUIMenuBarData* subMenu = getSubMenu(rootName);
  127. if(subMenu == nullptr)
  128. return;
  129. const GUIMenuItem* item = subMenu->menu->getMenuItem(strippedPath);
  130. if(item == nullptr)
  131. return;
  132. subMenu->menu->removeMenuItem(item);
  133. }
  134. const GUIMenuBar::GUIMenuBarData* GUIMenuBar::getSubMenu(const CM::WString& name) const
  135. {
  136. for(auto& subMenu : mChildMenus)
  137. {
  138. if(subMenu.name == name)
  139. return &subMenu;
  140. }
  141. return nullptr;
  142. }
  143. bool GUIMenuBar::stripPath(CM::WString& path, CM::WString& pathRoot) const
  144. {
  145. Vector<WString>::type pathElements = StringUtil::split(path, L"/");
  146. if(pathElements.size() == 0)
  147. return false;
  148. pathRoot = pathElements[0];
  149. path.erase(0, pathRoot.size());
  150. if(path.size() > 0)
  151. path.erase(0, 1); // Forward slash
  152. return true;
  153. }
  154. void GUIMenuBar::openSubMenu(const CM::WString& name)
  155. {
  156. const GUIMenuBarData* subMenu = getSubMenu(name);
  157. if(subMenu == nullptr)
  158. return;
  159. GUIManager::instance().openMenuBarMenu(subMenu->button, subMenu->menu);
  160. for(auto& childMenu : mChildMenus)
  161. {
  162. GUIManager::instance().addSelectiveInputElement(childMenu.button);
  163. }
  164. }
  165. }