BsGUIMenu.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #include "BsGUIMenu.h"
  2. #include "BsGUIDropDownBox.h"
  3. namespace BansheeEngine
  4. {
  5. GUIMenuItem::GUIMenuItem(GUIMenuItem* parent, const WString& name, std::function<void()> callback)
  6. :mParent(parent), mName(name), mCallback(callback), mIsSeparator(false)
  7. {
  8. }
  9. GUIMenuItem::GUIMenuItem(GUIMenuItem* parent)
  10. :mParent(parent), mCallback(nullptr), mIsSeparator(true)
  11. {
  12. }
  13. GUIMenuItem::~GUIMenuItem()
  14. {
  15. for(auto& child : mChildren)
  16. bs_delete<PoolAlloc>(child);
  17. }
  18. const GUIMenuItem* GUIMenuItem::findChild(const WString& name) const
  19. {
  20. auto iterFind = std::find_if(begin(mChildren), end(mChildren), [&] (GUIMenuItem* x) { return x->getName() == name; });
  21. if(iterFind != mChildren.end())
  22. return *iterFind;
  23. return nullptr;
  24. }
  25. GUIMenuItem* GUIMenuItem::findChild(const WString& name)
  26. {
  27. auto iterFind = std::find_if(begin(mChildren), end(mChildren), [&] (GUIMenuItem* x) { return x->getName() == name; });
  28. if(iterFind != mChildren.end())
  29. return *iterFind;
  30. return nullptr;
  31. }
  32. void GUIMenuItem::removeChild(const WString& name)
  33. {
  34. auto iterFind = std::find_if(begin(mChildren), end(mChildren), [&] (GUIMenuItem* x) { return x->getName() == name; });
  35. if(iterFind != mChildren.end())
  36. {
  37. bs_delete<PoolAlloc>(*iterFind);
  38. mChildren.erase(iterFind);
  39. }
  40. }
  41. GUIMenu::GUIMenu()
  42. :mRootElement(nullptr, L"", nullptr)
  43. {
  44. }
  45. GUIMenu::~GUIMenu()
  46. {
  47. }
  48. const GUIMenuItem* GUIMenu::addMenuItem(const WString& path, std::function<void()> callback)
  49. {
  50. return addMenuItemInternal(path, callback, false);
  51. }
  52. const GUIMenuItem* GUIMenu::addSeparator(const WString& path)
  53. {
  54. return addMenuItemInternal(path, nullptr, true);
  55. }
  56. const GUIMenuItem* GUIMenu::addMenuItemInternal(const WString& path, std::function<void()> callback, bool isSeparator)
  57. {
  58. Vector<WString> pathElements = StringUtil::split(path, L"/");
  59. GUIMenuItem* curSubMenu = &mRootElement;
  60. for(UINT32 i = 0; i < (UINT32)pathElements.size(); i++)
  61. {
  62. if(pathElements[i] == L"")
  63. continue;
  64. const WString& pathElem = *(pathElements.begin() + i);
  65. GUIMenuItem* existingItem = curSubMenu->findChild(pathElem);
  66. if(existingItem == nullptr)
  67. {
  68. bool isLastElem = i == (UINT32)(pathElements.size() - 1);
  69. if(isLastElem)
  70. existingItem = bs_new<GUIMenuItem, PoolAlloc>(curSubMenu, pathElem, callback);
  71. else
  72. {
  73. const WString& nextPathElem = *(pathElements.begin() + i);
  74. existingItem = bs_alloc<GUIMenuItem, PoolAlloc>();
  75. existingItem = new (existingItem) GUIMenuItem(curSubMenu, pathElem, nullptr);
  76. }
  77. curSubMenu->addChild(existingItem);
  78. }
  79. curSubMenu = existingItem;
  80. }
  81. if(isSeparator)
  82. {
  83. GUIMenuItem* separatorItem = bs_new<GUIMenuItem, PoolAlloc>(curSubMenu);
  84. curSubMenu->addChild(separatorItem);
  85. return separatorItem;
  86. }
  87. return curSubMenu;
  88. }
  89. const GUIMenuItem* GUIMenu::getMenuItem(const WString& path) const
  90. {
  91. Vector<WString> pathElements = StringUtil::split(path, L"/");
  92. const GUIMenuItem* curSubMenu = &mRootElement;
  93. for(UINT32 i = 0; i < (UINT32)pathElements.size(); i++)
  94. {
  95. const WString& pathElem = *(pathElements.begin() + i);
  96. const GUIMenuItem* existingItem = curSubMenu->findChild(pathElem);
  97. if(existingItem == nullptr || existingItem->isSeparator())
  98. return nullptr;
  99. curSubMenu = existingItem;
  100. }
  101. return curSubMenu;
  102. }
  103. void GUIMenu::removeMenuItem(const GUIMenuItem* item)
  104. {
  105. GUIMenuItem* parent = item->mParent;
  106. assert(parent != nullptr);
  107. parent->removeChild(item->getName());
  108. }
  109. GUIDropDownData GUIMenu::getDropDownData() const
  110. {
  111. return getDropDownDataInternal(mRootElement);
  112. }
  113. void GUIMenu::setLocalizedName(const WString& menuItemLabel, const HString& localizedName)
  114. {
  115. mLocalizedEntryNames[menuItemLabel] = localizedName;
  116. }
  117. GUIDropDownData GUIMenu::getDropDownDataInternal(const GUIMenuItem& menu) const
  118. {
  119. GUIDropDownData dropDownData;
  120. for(auto& menuItem : menu.mChildren)
  121. {
  122. if(menuItem->isSeparator())
  123. {
  124. dropDownData.entries.push_back(GUIDropDownDataEntry::separator());
  125. }
  126. else
  127. {
  128. if(menuItem->getNumChildren() == 0)
  129. {
  130. dropDownData.entries.push_back(GUIDropDownDataEntry::button(menuItem->getName(), menuItem->getCallback()));
  131. }
  132. else
  133. {
  134. dropDownData.entries.push_back(GUIDropDownDataEntry::subMenu(menuItem->getName(), getDropDownDataInternal(*menuItem)));
  135. }
  136. }
  137. }
  138. dropDownData.localizedNames = mLocalizedEntryNames;
  139. return dropDownData;
  140. }
  141. }