1 | //************************************ bs::framework - Copyright 2018 Marko Pintera **************************************// |
2 | //*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********// |
3 | #include "GUI/BsGUIMenu.h" |
4 | #include "GUI/BsGUIDropDownMenu.h" |
5 | |
6 | namespace bs |
7 | { |
8 | bool GUIMenuItemComparer:: (const GUIMenuItem* const& a, const GUIMenuItem* const& b) const |
9 | { |
10 | return a->mPriority > b->mPriority || (a->mPriority == b->mPriority && a->mSeqIdx < b->mSeqIdx); |
11 | } |
12 | |
13 | GUIMenuItem::(GUIMenuItem* parent, const String& name, std::function<void()> callback, |
14 | INT32 priority, UINT32 seqIdx, const ShortcutKey& key) |
15 | :mParent(parent), mIsSeparator(false), mName(name), mCallback(callback), mPriority(priority), |
16 | mShortcut(key), mSeqIdx(seqIdx) |
17 | { |
18 | |
19 | } |
20 | |
21 | GUIMenuItem::(GUIMenuItem* parent, INT32 priority, UINT32 seqIdx) |
22 | : mParent(parent), mIsSeparator(true), mCallback(nullptr), mPriority(priority), mSeqIdx(seqIdx) |
23 | { |
24 | |
25 | } |
26 | |
27 | GUIMenuItem::() |
28 | { |
29 | for(auto& child : mChildren) |
30 | bs_delete(child); |
31 | } |
32 | |
33 | const GUIMenuItem* GUIMenuItem::(const String& name) const |
34 | { |
35 | auto iterFind = std::find_if(begin(mChildren), end(mChildren), [&] (GUIMenuItem* x) { return x->getName() == name; }); |
36 | |
37 | if(iterFind != mChildren.end()) |
38 | return *iterFind; |
39 | |
40 | return nullptr; |
41 | } |
42 | |
43 | GUIMenuItem* GUIMenuItem::(const String& name) |
44 | { |
45 | auto iterFind = std::find_if(begin(mChildren), end(mChildren), [&] (GUIMenuItem* x) { return x->getName() == name; }); |
46 | |
47 | if(iterFind != mChildren.end()) |
48 | return *iterFind; |
49 | |
50 | return nullptr; |
51 | } |
52 | |
53 | void GUIMenuItem::(const String& name) |
54 | { |
55 | auto iterFind = std::find_if(begin(mChildren), end(mChildren), [&] (GUIMenuItem* x) { return x->getName() == name; }); |
56 | |
57 | if(iterFind != mChildren.end()) |
58 | { |
59 | bs_delete(*iterFind); |
60 | mChildren.erase(iterFind); |
61 | } |
62 | } |
63 | |
64 | void GUIMenuItem::(const GUIMenuItem* item) |
65 | { |
66 | auto iterFind = std::find(begin(mChildren), end(mChildren), item); |
67 | |
68 | if (iterFind != mChildren.end()) |
69 | { |
70 | bs_delete(*iterFind); |
71 | mChildren.erase(iterFind); |
72 | } |
73 | } |
74 | |
75 | GUIMenu::() |
76 | :mRootElement(nullptr, "" , nullptr, 0, 0, ShortcutKey::NONE), mNextIdx(0) |
77 | { |
78 | |
79 | } |
80 | |
81 | GUIMenu::() |
82 | { |
83 | |
84 | } |
85 | |
86 | GUIMenuItem* GUIMenu::(const String& path, std::function<void()> callback, INT32 priority, const ShortcutKey& key) |
87 | { |
88 | return addMenuItemInternal(path, callback, false, priority, key); |
89 | } |
90 | |
91 | GUIMenuItem* GUIMenu::(const String& path, INT32 priority) |
92 | { |
93 | return addMenuItemInternal(path, nullptr, true, priority, ShortcutKey::NONE); |
94 | } |
95 | |
96 | GUIMenuItem* GUIMenu::(const String& path, std::function<void()> callback, bool isSeparator, |
97 | INT32 priority, const ShortcutKey& key) |
98 | { |
99 | Vector<String> pathElements = StringUtil::split(path, "/" ); |
100 | |
101 | GUIMenuItem* = &mRootElement; |
102 | for(UINT32 i = 0; i < (UINT32)pathElements.size(); i++) |
103 | { |
104 | if(pathElements[i] == "" ) |
105 | continue; |
106 | |
107 | const String& pathElem = *(pathElements.begin() + i); |
108 | GUIMenuItem* existingItem = curSubMenu->findChild(pathElem); |
109 | |
110 | if(existingItem == nullptr) |
111 | { |
112 | bool isLastElem = i == (UINT32)(pathElements.size() - 1); |
113 | |
114 | if(isLastElem) |
115 | existingItem = bs_new<GUIMenuItem>(curSubMenu, pathElem, callback, priority, mNextIdx++, key); |
116 | else |
117 | { |
118 | existingItem = bs_alloc<GUIMenuItem>(); |
119 | existingItem = new (existingItem) GUIMenuItem(curSubMenu, pathElem, nullptr, priority, mNextIdx++, ShortcutKey::NONE); |
120 | } |
121 | |
122 | curSubMenu->addChild(existingItem); |
123 | } |
124 | |
125 | curSubMenu = existingItem; |
126 | } |
127 | |
128 | if(isSeparator) |
129 | { |
130 | GUIMenuItem* separatorItem = bs_new<GUIMenuItem>(curSubMenu, priority, mNextIdx++); |
131 | curSubMenu->addChild(separatorItem); |
132 | |
133 | return separatorItem; |
134 | } |
135 | |
136 | return curSubMenu; |
137 | } |
138 | |
139 | GUIMenuItem* GUIMenu::(const String& path) |
140 | { |
141 | Vector<String> pathElements = StringUtil::split(path, "/" ); |
142 | |
143 | GUIMenuItem* = &mRootElement; |
144 | for(UINT32 i = 0; i < (UINT32)pathElements.size(); i++) |
145 | { |
146 | const String& pathElem = *(pathElements.begin() + i); |
147 | GUIMenuItem* existingItem = curSubMenu->findChild(pathElem); |
148 | |
149 | if(existingItem == nullptr || existingItem->isSeparator()) |
150 | return nullptr; |
151 | |
152 | curSubMenu = existingItem; |
153 | } |
154 | |
155 | return curSubMenu; |
156 | } |
157 | |
158 | void GUIMenu::(const GUIMenuItem* item) |
159 | { |
160 | GUIMenuItem* parent = item->mParent; |
161 | assert(parent != nullptr); |
162 | |
163 | parent->removeChild(item->getName()); |
164 | } |
165 | |
166 | GUIDropDownData GUIMenu::() const |
167 | { |
168 | return getDropDownDataInternal(mRootElement); |
169 | } |
170 | |
171 | void GUIMenu::(const String& , const HString& localizedName) |
172 | { |
173 | mLocalizedEntryNames[menuItemLabel] = localizedName; |
174 | } |
175 | |
176 | GUIDropDownData GUIMenu::(const GUIMenuItem& ) const |
177 | { |
178 | GUIDropDownData dropDownData; |
179 | |
180 | for(auto& : menu.mChildren) |
181 | { |
182 | if(menuItem->isSeparator()) |
183 | { |
184 | dropDownData.entries.push_back(GUIDropDownDataEntry::separator()); |
185 | } |
186 | else |
187 | { |
188 | if(menuItem->getNumChildren() == 0) |
189 | { |
190 | dropDownData.entries.push_back(GUIDropDownDataEntry::button(menuItem->getName(), |
191 | menuItem->getCallback(), menuItem->getShortcut().getName())); |
192 | } |
193 | else |
194 | { |
195 | dropDownData.entries.push_back(GUIDropDownDataEntry::subMenu(menuItem->getName(), |
196 | getDropDownDataInternal(*menuItem))); |
197 | } |
198 | } |
199 | } |
200 | |
201 | dropDownData.localizedNames = mLocalizedEntryNames; |
202 | |
203 | return dropDownData; |
204 | } |
205 | } |