MyGUI  3.2.0
MyGUI_MenuControl.cpp
Go to the documentation of this file.
1 
6 /*
7  This file is part of MyGUI.
8 
9  MyGUI is free software: you can redistribute it and/or modify
10  it under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  MyGUI is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  along with MyGUI. If not, see <http://www.gnu.org/licenses/>.
21 */
22 #include "MyGUI_Precompiled.h"
23 #include "MyGUI_MenuControl.h"
24 #include "MyGUI_ResourceSkin.h"
25 #include "MyGUI_MenuItem.h"
26 #include "MyGUI_ImageBox.h"
27 #include "MyGUI_MenuBar.h"
28 #include "MyGUI_WidgetManager.h"
29 #include "MyGUI_LayerManager.h"
31 #include "MyGUI_InputManager.h"
32 #include "MyGUI_Gui.h"
33 #include "MyGUI_RenderManager.h"
34 
35 namespace MyGUI
36 {
37 
38  const float POPUP_MENU_SPEED_COEF = 3.0f;
39 
41  mHideByAccept(true),
42  mMenuDropMode(false),
43  mIsMenuDrop(true),
44  mHideByLostKey(false),
45  mResizeToContent(true),
46  mShutdown(false),
47  mVerticalAlignment(true),
48  mDistanceButton(0),
49  mPopupAccept(false),
50  mOwner(nullptr),
51  mAnimateSmooth(false),
52  mChangeChildSkin(false),
53  mClient(nullptr)
54  {
55  }
56 
58  {
59  Base::initialiseOverride();
60 
61  // инициализируем овнера
62  Widget* parent = getParent();
63  if (parent)
64  {
65  mOwner = parent->castType<MenuItem>(false);
66  if (!mOwner)
67  {
68  Widget* client = parent;
69  parent = client->getParent();
70  if (parent && parent->getClientWidget())
71  {
72  mOwner = parent->castType<MenuItem>(false);
73  }
74  }
75  }
76 
77  // FIXME нам нужен фокус клавы
78  setNeedKeyFocus(true);
79 
80  assignWidget(mClient, "Client");
81  if (mClient != nullptr)
82  {
83  setWidgetClient(mClient);
84  }
85 
86  //OBSOLETE
87  if (isUserString("SkinLine"))
88  {
89  mItemNormalSkin = getUserString("SkinLine");
90  mItemPopupSkin = mItemNormalSkin;
91  }
92 
93  if (isUserString("SeparatorSkin"))
94  mItemSeparatorSkin = getUserString("SeparatorSkin");
95 
96  if (isUserString("NormalSkin"))
97  mItemNormalSkin = getUserString("NormalSkin");
98 
99  if (isUserString("PopupSkin"))
100  mItemPopupSkin = getUserString("PopupSkin");
101 
102  if (isUserString("DistanceButton"))
103  mDistanceButton = utility::parseValue<int>(getUserString("DistanceButton"));
104 
105  if (isUserString("SubMenuSkin"))
106  mSubMenuSkin = getUserString("SubMenuSkin");
107  if (isUserString("SubMenuLayer"))
108  mSubMenuLayer = getUserString("SubMenuLayer");
109 
110  // FIXME добавленно, так как шетдаун вызывается и при смене скина
111  mShutdown = false;
112  }
113 
115  {
116  mShutdown = true;
117 
118  if (mOwner != nullptr)
119  mOwner->getMenuCtrlParent()->_notifyDeletePopup(mOwner);
120 
121  Base::shutdownOverride();
122  }
123 
125  {
126  Base::onWidgetCreated(_widget);
127 
128  MenuItem* child = _widget->castType<MenuItem>(false);
129  if (child != nullptr)
130  {
131  _wrapItem(child, mItemsInfo.size(), "", MenuItemType::Normal, "", Any::Null);
132  }
133  }
134 
135  MenuItem* MenuControl::insertItemAt(size_t _index, const UString& _name, MenuItemType _type, const std::string& _id, Any _data)
136  {
137  MYGUI_ASSERT_RANGE_INSERT(_index, mItemsInfo.size(), "MenuControl::insertItemAt");
138  if (_index == ITEM_NONE) _index = mItemsInfo.size();
139 
140  MenuItem* item = _getClientWidget()->createWidget<MenuItem>(getSkinByType(_type), IntCoord(), Align::Default);
141  _wrapItem(item, _index, _name, _type, _id, _data);
142 
143  return item;
144  }
145 
146  void MenuControl::removeItemAt(size_t _index)
147  {
148  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::removeItemAt");
149 
150  if (mItemsInfo[_index].submenu)
151  {
152  WidgetManager::getInstance().destroyWidget(mItemsInfo[_index].submenu);
153  mItemsInfo[_index].submenu = nullptr;
154  }
155  WidgetManager::getInstance().destroyWidget(mItemsInfo[_index].item);
156  }
157 
159  {
160  while (!mItemsInfo.empty())
161  {
162  if (mItemsInfo.back().submenu)
163  {
164  WidgetManager::getInstance().destroyWidget(mItemsInfo.back().submenu);
165  mItemsInfo.back().submenu = nullptr;
166  }
167  WidgetManager::getInstance().destroyWidget(mItemsInfo.back().item);
168  }
169  }
170 
171  const UString& MenuControl::getItemNameAt(size_t _index)
172  {
173  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::getItemNameAt");
174  return mItemsInfo[_index].name;
175  }
176 
177  void MenuControl::update()
178  {
179  IntSize size;
180 
181  if (mVerticalAlignment)
182  {
183  for (VectorMenuItemInfo::iterator iter = mItemsInfo.begin(); iter != mItemsInfo.end(); ++iter)
184  {
185  IntSize contentSize = iter->item->_getContentSize();
186  iter->item->setCoord(0, size.height, _getClientWidget()->getWidth(), contentSize.height);
187  size.height += contentSize.height + mDistanceButton;
188 
189  if (contentSize.width > size.width)
190  size.width = contentSize.width;
191  }
192  if (!mItemsInfo.empty())
193  size.height -= mDistanceButton;
194  }
195  else
196  {
197  int maxHeight = 0;
198  for (VectorMenuItemInfo::iterator iter = mItemsInfo.begin(); iter != mItemsInfo.end(); ++iter)
199  {
200  IntSize contentSize = iter->item->_getContentSize();
201  if (maxHeight < contentSize.height)
202  maxHeight = contentSize.height;
203  }
204 
205  for (VectorMenuItemInfo::iterator iter = mItemsInfo.begin(); iter != mItemsInfo.end(); ++iter)
206  {
207  IntSize contentSize = iter->item->_getContentSize();
208  iter->item->setCoord(size.width, 0, contentSize.width, maxHeight);
209  size.width += contentSize.width + mDistanceButton;
210  }
211 
212  if (!mItemsInfo.empty())
213  size.width -= mDistanceButton;
214  }
215 
216  if (mResizeToContent)
217  setSize(size + mCoord.size() - _getClientWidget()->getSize());
218  }
219 
220  void MenuControl::setItemDataAt(size_t _index, Any _data)
221  {
222  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::setItemDataAt");
223  mItemsInfo[_index].data = _data;
224  }
225 
227  {
228  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::getItemChildAt");
229  return mItemsInfo[_index].submenu;
230  }
231 
232  void MenuControl::removeItemChildAt(size_t _index)
233  {
234  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::removeItemChildAt");
235 
236  if (mItemsInfo[_index].submenu != nullptr)
237  {
238  WidgetManager::getInstance().destroyWidget(mItemsInfo[_index].submenu);
239  mItemsInfo[_index].submenu = nullptr;
240  }
241 
242  update();
243  }
244 
245  void MenuControl::setItemNameAt(size_t _index, const UString& _name)
246  {
247  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::setItemNameAt");
248 
249  mItemsInfo[_index].name = _name;
250  MenuItem* item = mItemsInfo[_index].item;
251  item->setCaption(_name);
252 
253  update();
254  }
255 
256  void MenuControl::setItemIdAt(size_t _index, const std::string& _id)
257  {
258  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::setItemIdAt");
259  mItemsInfo[_index].id = _id;
260  }
261 
262  const std::string& MenuControl::getItemIdAt(size_t _index)
263  {
264  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::getItemIdAt");
265  return mItemsInfo[_index].id;
266  }
267 
269  {
270  // дитю меняем скин
271  if (mChangeChildSkin)
272  return;
273 
274  // общий шутдаун виджета
275  if (mShutdown)
276  return;
277 
278  size_t index = getItemIndex(_item);
279  mItemsInfo.erase(mItemsInfo.begin() + index);
280  update();
281  }
282 
284  {
285  size_t index = getItemIndex(_item);
286  mItemsInfo[index].submenu = nullptr;
287  }
288 
290  {
291  size_t index = getItemIndex(_item);
292  mItemsInfo[index].name = _item->getCaption();
293 
294  ISubWidgetText* text = _item->getSubWidgetText();
295  mItemsInfo[index].width = text ? (text->getTextSize().width + _item->getSize().width - text->getWidth()) : 0;
296  update();
297  }
298 
300  {
301  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::getItemTypeAt");
302  return mItemsInfo[_index].type;
303  }
304 
305  void MenuControl::setItemTypeAt(size_t _index, MenuItemType _type)
306  {
307  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::setItemTypeAt");
308  ItemInfo& info = mItemsInfo[_index];
309  if (info.type == _type)
310  return;
311 
312  // сохраняем данные
313  info.type = _type;
314 
315  // при смене скина дите отпишется
316  mChangeChildSkin = true;
317  info.item->changeWidgetSkin(getSkinByType(_type));
318  mChangeChildSkin = false;
319 
320  info.item->setImageName(getIconIndexByType(_type ));
321  info.item->setCaption(info.name);
322 
323  update();
324  }
325 
326  void MenuControl::notifyMenuCtrlAccept(MenuItem* _item)
327  {
328  if (mHideByAccept)
329  {
330  setVisibleSmooth(false);
331  }
332  else
333  {
335  }
336 
337  MenuItem* parent_item = getMenuItemParent();
338  if (parent_item)
339  {
340  MenuControl* parent_ctrl = parent_item->getMenuCtrlParent();
341  if (parent_ctrl)
342  {
343  parent_ctrl->notifyMenuCtrlAccept(_item);
344  }
345  }
346 
347  eventMenuCtrlAccept(this, _item);
348  }
349 
350  void MenuControl::setItemChildVisibleAt(size_t _index, bool _visible)
351  {
352  _setItemChildVisibleAt(_index, _visible, true);
353  }
354 
355  void MenuControl::_setItemChildVisibleAt(size_t _index, bool _visible, bool _smooth)
356  {
357  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::setItemChildVisibleAt");
358 
359  if (_visible)
360  {
361  if (mItemsInfo[_index].submenu && mItemsInfo[_index].submenu->getItemCount())
362  {
363  int offset = mItemsInfo[0].item->getAbsoluteTop() - getAbsoluteTop();
364 
365  const IntCoord& coord = mItemsInfo[_index].item->getAbsoluteCoord();
366  IntPoint point(getAbsoluteRect().right, coord.top - offset);
367 
368  MenuControl* menu = mItemsInfo[_index].submenu;
369 
370  if (mVerticalAlignment)
371  {
372  // too wide
373  if (point.left + menu->getWidth() > menu->getParentSize().width)
374  {
375  // move to the left side if possible
376  if (point.left - menu->getWidth() - getWidth() > 0)
377  point.left -= menu->getWidth() + getWidth();
378  // or put near right parent border (window) if too wide for left side too
379  else
380  point.left = menu->getParentSize().width - menu->getWidth();
381  }
382  // too high (same logic as for too wide)
383  if (point.top + menu->getHeight() > menu->getParentSize().height)
384  {
385  // move to the top side if possible
386  if (point.top - menu->getHeight() - getHeight() > 0)
387  point.top -= menu->getHeight() + getHeight();
388  // or put near bottom parent border (window) if too high for top side too
389  else
390  point.top = menu->getParentSize().height - menu->getHeight();
391  }
392  }
393  else
394  {
395  point.set(coord.left, getAbsoluteRect().bottom);
396  }
397 
398  menu->setPosition(point);
399  if (_smooth)
400  menu->setVisibleSmooth(true);
401  else
402  menu->setVisible(true);
403 
405  }
406  }
407  else
408  {
409  if (mItemsInfo[_index].submenu)
410  {
411  if (_smooth)
412  mItemsInfo[_index].submenu->setVisibleSmooth(false);
413  else
414  mItemsInfo[_index].submenu->setVisible(false);
415  }
416  }
417  }
418 
419  void MenuControl::notifyRootKeyChangeFocus(Widget* _sender, bool _focus)
420  {
421  MenuItem* item = _sender->castType<MenuItem>();
422  if (item->getItemType() == MenuItemType::Popup)
423  {
424  if (_focus)
425  {
426  if (!mMenuDropMode || mIsMenuDrop)
427  {
428  item->setItemChildVisible(true);
429  item->setStateSelected(true);
430  }
431  }
432  else
433  {
434  item->setItemChildVisible(false);
435  item->setStateSelected(false);
436  }
437  }
438  }
439 
440  Widget* MenuControl::createItemChildByType(size_t _index, const std::string& _type)
441  {
442  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::createItemChildByType");
443  removeItemChildAt(_index);
444  Widget* child = mItemsInfo[_index].item->createWidgetT(WidgetStyle::Popup, _type, mSubMenuSkin, IntCoord(), Align::Default, mSubMenuLayer);
445  MYGUI_ASSERT(child->isType<MenuControl>(), "child must have MenuControl base type");
446  return child;
447  }
448 
449  void MenuControl::notifyMouseButtonClick(Widget* _sender)
450  {
451  MenuItem* item = _sender->castType<MenuItem>();
452  if (mMenuDropMode)
453  {
454  if (mIsMenuDrop)
455  {
456  if (item->getItemType() == MenuItemType::Popup)
457  {
458  item->setStateSelected(false);
459  item->setItemChildVisible(false);
460  mIsMenuDrop = false;
461  }
462  }
463  else
464  {
465  if (item->getItemType() == MenuItemType::Popup)
466  {
467  mIsMenuDrop = true;
468  item->setStateSelected(true);
469  item->setItemChildVisible(true);
471  }
472  }
473  }
474  else
475  {
476  if ((item->getItemType() == MenuItemType::Popup && mPopupAccept) ||
477  item->getItemType() == MenuItemType::Normal)
478  {
479  notifyMenuCtrlAccept(item);
480  }
481  }
482  }
483 
485  {
486  if (mMenuDropMode)
487  {
488  mIsMenuDrop = false;
489  }
490  if (!_focus && mHideByLostKey)
491  {
492  setVisibleSmooth(false);
493  eventMenuCtrlClose(this);
494  }
495  Base::onKeyChangeRootFocus(_focus);
496  }
497 
498  void MenuControl::notifyMouseSetFocus(Widget* _sender, Widget* _new)
499  {
501  }
502 
504  {
505  // заменяем
506  size_t index = getItemIndex(_item);
507  if (mItemsInfo[index].submenu != nullptr)
508  {
509  WidgetManager::getInstance().destroyWidget(mItemsInfo[index].submenu);
510  mItemsInfo[index].submenu = nullptr;
511  }
512  mItemsInfo[index].submenu = _widget;
513  // скрываем менюшку
514  mItemsInfo[index].submenu->setVisible(false);
515 
516  update();
517  }
518 
519  void MenuControl::_wrapItem(MenuItem* _item, size_t _index, const UString& _name, MenuItemType _type, const std::string& _id, Any _data)
520  {
521  _item->setAlign(mVerticalAlignment ? Align::Top | Align::HStretch : Align::Default);
522  _item->eventRootKeyChangeFocus += newDelegate(this, &MenuControl::notifyRootKeyChangeFocus);
523  _item->eventMouseButtonClick += newDelegate(this, &MenuControl::notifyMouseButtonClick);
524  _item->eventMouseSetFocus += newDelegate(this, &MenuControl::notifyMouseSetFocus);
525 
526  _item->setImageName(getIconIndexByType(_type ));
527 
528  MenuControl* submenu = nullptr;
529 
530  ItemInfo info = ItemInfo(_item, _name, _type, submenu, _id, _data);
531 
532  mItemsInfo.insert(mItemsInfo.begin() + _index, info);
533 
534  mChangeChildSkin = true;
535  _item->changeWidgetSkin(getSkinByType(_type));
536  mChangeChildSkin = false;
537 
538  // его сет капшен, обновит размер
539  _item->setCaption(_name);
540 
541  update();
542  }
543 
544  void MenuControl::setVisible(bool _visible)
545  {
546  if (mAnimateSmooth)
547  {
550  setEnabledSilent(true);
551  mAnimateSmooth = false;
552  }
553 
554  if (_visible)
555  {
556  if (mOwner == nullptr && mHideByLostKey)
557  {
559  }
560  }
561 
562  Base::setVisible(_visible);
563  }
564 
565  void MenuControl::setVisibleSmooth(bool _visible)
566  {
567  mAnimateSmooth = true;
569 
570  if (_visible)
571  {
572  setEnabledSilent(true);
573  if (!getVisible())
574  {
576  Base::setVisible(true);
577  }
578 
579  ControllerFadeAlpha* controller = createControllerFadeAlpha(ALPHA_MAX, POPUP_MENU_SPEED_COEF, true);
581  ControllerManager::getInstance().addItem(this, controller);
582  }
583  else
584  {
585  setEnabledSilent(false);
586 
587  ControllerFadeAlpha* controller = createControllerFadeAlpha(ALPHA_MIN, POPUP_MENU_SPEED_COEF, false);
589  ControllerManager::getInstance().addItem(this, controller);
590  }
591  }
592 
593  ControllerFadeAlpha* MenuControl::createControllerFadeAlpha(float _alpha, float _coef, bool _enable)
594  {
596  ControllerFadeAlpha* controller = item->castType<ControllerFadeAlpha>();
597 
598  controller->setAlpha(_alpha);
599  controller->setCoef(_coef);
600  controller->setEnabled(_enable);
601 
602  return controller;
603  }
604 
605  MenuItem* MenuControl::insertItem(MenuItem* _to, const UString& _name, MenuItemType _type, const std::string& _id, Any _data)
606  {
607  return insertItemAt(getItemIndex(_to), _name, _type, _id, _data);
608  }
609 
610  MenuItem* MenuControl::addItem(const UString& _name, MenuItemType _type, const std::string& _id, Any _data)
611  {
612  return insertItemAt(ITEM_NONE, _name, _type, _id, _data);
613  }
614 
616  {
617  removeItemAt(getItemIndex(_item));
618  }
619 
621  {
622  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::getItemAt");
623  return mItemsInfo[_index].item;
624  }
625 
627  {
628  for (size_t pos = 0; pos < mItemsInfo.size(); pos++)
629  {
630  if (mItemsInfo[pos].item == _item)
631  return pos;
632  }
633  MYGUI_EXCEPT("item (" << _item << ") not found, source 'MenuControl::getItemIndex'");
634  }
635 
637  {
638  for (size_t pos = 0; pos < mItemsInfo.size(); pos++)
639  {
640  if (mItemsInfo[pos].name == _name)
641  return mItemsInfo[pos].item;
642  }
643  return nullptr;
644  }
645 
646  MenuItem* MenuControl::getItemById(const std::string& _id)
647  {
648  for (size_t index = 0; index < mItemsInfo.size(); index++)
649  {
650  if (mItemsInfo[index].id == _id)
651  return mItemsInfo[index].item;
652  }
653  MYGUI_EXCEPT("item id (" << _id << ") not found, source 'MenuControl::getItemById'");
654  }
655 
656  size_t MenuControl::getItemIndexById(const std::string& _id)
657  {
658  for (size_t index = 0; index < mItemsInfo.size(); index++)
659  {
660  if (mItemsInfo[index].id == _id)
661  return index;
662  }
663  MYGUI_EXCEPT("item id (" << _id << ") not found, source 'MenuControl::getItemById'");
664  }
665 
666  MenuItem* MenuControl::findItemById(const std::string& _id, bool _recursive)
667  {
668  for (size_t index = 0; index < mItemsInfo.size(); index++)
669  {
670  if (mItemsInfo[index].id == _id)
671  return mItemsInfo[index].item;
672 
673  if (_recursive && mItemsInfo[index].submenu != nullptr)
674  {
675  MenuItem* find = mItemsInfo[index].submenu->findItemById(_id, _recursive);
676  if (find != nullptr)
677  return find;
678  }
679  }
680  return nullptr;
681  }
682 
684  {
685  for (size_t index = 0; index < mItemsInfo.size(); index++)
686  {
687  if (mItemsInfo[index].name == _name)
688  return index;
689  }
690  return ITEM_NONE;
691  }
692 
694  {
695  for (size_t index = 0; index < mItemsInfo.size(); index++)
696  {
697  if (mItemsInfo[index].item == _item)
698  return index;
699  }
700  return ITEM_NONE;
701  }
702 
703  Widget* MenuControl::_getClientWidget()
704  {
705  return mClient == nullptr ? this : mClient;
706  }
707 
709  {
710  return mItemsInfo.size();
711  }
712 
714  {
715  setItemDataAt(getItemIndex(_item), _data);
716  }
717 
718  void MenuControl::clearItemDataAt(size_t _index)
719  {
720  setItemDataAt(_index, Any::Null);
721  }
722 
724  {
726  }
727 
728  void MenuControl::setItemId(MenuItem* _item, const std::string& _id)
729  {
730  setItemIdAt(getItemIndex(_item), _id);
731  }
732 
733  const std::string& MenuControl::getItemId(MenuItem* _item)
734  {
735  return getItemIdAt(getItemIndex(_item));
736  }
737 
738  void MenuControl::setItemName(MenuItem* _item, const UString& _name)
739  {
740  setItemNameAt(getItemIndex(_item), _name);
741  }
742 
744  {
745  return getItemNameAt(getItemIndex(_item));
746  }
747 
748  void MenuControl::setItemChildVisible(MenuItem* _item, bool _visible)
749  {
750  setItemChildVisibleAt(getItemIndex(_item), _visible);
751  }
752 
754  {
755  return getItemChildAt(getItemIndex(_item));
756  }
757 
759  {
760  return createItemChildTAt<MenuControl>(_index);
761  }
762 
764  {
765  return createItemChildAt(getItemIndex(_item));
766  }
767 
769  {
771  }
772 
774  {
775  return getItemTypeAt(getItemIndex(_item));
776  }
777 
779  {
780  setItemTypeAt(getItemIndex(_item), _type);
781  }
782 
783  void MenuControl::setPopupAccept(bool _value)
784  {
785  mPopupAccept = _value;
786  }
787 
789  {
790  return mPopupAccept;
791  }
792 
794  {
795  return mOwner;
796  }
797 
798  const std::string& MenuControl::getSkinByType(MenuItemType _type) const
799  {
800  if (_type == MenuItemType::Popup)
801  return mItemPopupSkin;
802  else if (_type == MenuItemType::Separator)
803  return mItemSeparatorSkin;
804  return mItemNormalSkin;
805  }
806 
807  std::string MenuControl::getIconIndexByType(MenuItemType _type) const
808  {
809  if (_type == MenuItemType::Popup)
810  return "Popup";
811  return "None";
812  }
813 
814  MenuItemType MenuControl::getItemType(bool _submenu, bool _separator) const
815  {
816  if (_submenu)
817  return MenuItemType::Popup;
818  else if (_separator)
820  return MenuItemType::Normal;
821  }
822 
824  {
825  return getItemCount();
826  }
827 
829  {
831  }
832 
833  void MenuControl::_removeItemAt(size_t _index)
834  {
835  removeItemAt(_index);
836 
838  }
839 
841  {
842  return getItemAt(_index);
843  }
844 
845  void MenuControl::_setItemNameAt(size_t _index, const UString& _name)
846  {
847  setItemNameAt(_index, _name);
848  }
849 
850  const UString& MenuControl::_getItemNameAt(size_t _index)
851  {
852  return getItemNameAt(_index);
853  }
854 
856  {
857  MenuItem* item = static_cast<MenuItem*>(_item);
858  for (VectorMenuItemInfo::iterator iter = mItemsInfo.begin(); iter != mItemsInfo.end(); ++iter)
859  {
860  if ((*iter).type == MenuItemType::Popup)
861  {
862  (*iter).item->setStateSelected(false);
863 
864  if ((*iter).submenu != nullptr)
865  (*iter).submenu->setVisible(false);
866  }
867  }
868 
869  if (item->getItemType() == MenuItemType::Popup)
870  {
871  item->setStateSelected(true);
872  size_t index = getItemIndex(item);
873 
874  _setItemChildVisibleAt(index, true, false);
875 
876  _updateItems(index);
877  }
878  }
879 
880  void MenuControl::_updateItems(size_t _index)
881  {
882  if (mItemsInfo[_index].submenu != nullptr)
883  mItemsInfo[_index].submenu->_updateSizeForEmpty();
884  }
885 
887  {
888  if (mItemsInfo.empty())
889  setSize(100, 100);
890  }
891 
893  {
894  mVerticalAlignment = _value;
895 
896  update();
897  }
898 
900  {
901  return mVerticalAlignment;
902  }
903 
904  void MenuControl::setPropertyOverride(const std::string& _key, const std::string& _value)
905  {
906  if (_key == "VerticalAlignment")
907  setVerticalAlignment(utility::parseValue<bool>(_value));
908  else
909  {
910  Base::setPropertyOverride(_key, _value);
911  return;
912  }
913  eventChangeProperty(this, _key, _value);
914  }
915 
916 } // namespace MyGUI