MyGUI
3.2.1
|
00001 /* 00002 * This source file is part of MyGUI. For the latest info, see http://mygui.info/ 00003 * Distributed under the MIT License 00004 * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT) 00005 */ 00006 00007 #include "MyGUI_Precompiled.h" 00008 #include "MyGUI_MenuControl.h" 00009 #include "MyGUI_ResourceSkin.h" 00010 #include "MyGUI_MenuItem.h" 00011 #include "MyGUI_ImageBox.h" 00012 #include "MyGUI_MenuBar.h" 00013 #include "MyGUI_WidgetManager.h" 00014 #include "MyGUI_LayerManager.h" 00015 #include "MyGUI_ControllerManager.h" 00016 #include "MyGUI_InputManager.h" 00017 #include "MyGUI_Gui.h" 00018 #include "MyGUI_RenderManager.h" 00019 00020 namespace MyGUI 00021 { 00022 00023 const float POPUP_MENU_SPEED_COEF = 3.0f; 00024 00025 MenuControl::MenuControl() : 00026 mHideByAccept(true), 00027 mMenuDropMode(false), 00028 mIsMenuDrop(true), 00029 mHideByLostKey(false), 00030 mResizeToContent(true), 00031 mShutdown(false), 00032 mVerticalAlignment(true), 00033 mDistanceButton(0), 00034 mPopupAccept(false), 00035 mOwner(nullptr), 00036 mAnimateSmooth(false), 00037 mChangeChildSkin(false), 00038 mClient(nullptr), 00039 mInternalCreateChild(false) 00040 { 00041 } 00042 00043 void MenuControl::initialiseOverride() 00044 { 00045 Base::initialiseOverride(); 00046 00047 // инициализируем овнера 00048 Widget* parent = getParent(); 00049 if (parent) 00050 { 00051 mOwner = parent->castType<MenuItem>(false); 00052 if (!mOwner) 00053 { 00054 Widget* client = parent; 00055 parent = client->getParent(); 00056 if (parent && parent->getClientWidget()) 00057 { 00058 mOwner = parent->castType<MenuItem>(false); 00059 } 00060 } 00061 } 00062 00063 // FIXME нам нужен фокус клавы 00064 setNeedKeyFocus(true); 00065 00067 assignWidget(mClient, "Client"); 00068 if (mClient != nullptr) 00069 { 00070 setWidgetClient(mClient); 00071 } 00072 00073 //OBSOLETE 00074 if (isUserString("SkinLine")) 00075 { 00076 mItemNormalSkin = getUserString("SkinLine"); 00077 mItemPopupSkin = mItemNormalSkin; 00078 } 00079 00080 if (isUserString("SeparatorSkin")) 00081 mItemSeparatorSkin = getUserString("SeparatorSkin"); 00082 00083 if (isUserString("NormalSkin")) 00084 mItemNormalSkin = getUserString("NormalSkin"); 00085 00086 if (isUserString("PopupSkin")) 00087 mItemPopupSkin = getUserString("PopupSkin"); 00088 00089 if (isUserString("DistanceButton")) 00090 mDistanceButton = utility::parseValue<int>(getUserString("DistanceButton")); 00091 00092 if (isUserString("SubMenuSkin")) 00093 mSubMenuSkin = getUserString("SubMenuSkin"); 00094 00095 if (isUserString("SubMenuLayer")) 00096 mSubMenuLayer = getUserString("SubMenuLayer"); 00097 00098 // FIXME добавленно, так как шетдаун вызывается и при смене скина 00099 mShutdown = false; 00100 } 00101 00102 void MenuControl::shutdownOverride() 00103 { 00104 mShutdown = true; 00105 00106 if (mOwner != nullptr) 00107 mOwner->getMenuCtrlParent()->_notifyDeletePopup(mOwner); 00108 00109 Base::shutdownOverride(); 00110 } 00111 00112 void MenuControl::onWidgetCreated(Widget* _widget) 00113 { 00114 Base::onWidgetCreated(_widget); 00115 00116 MenuItem* child = _widget->castType<MenuItem>(false); 00117 if (child != nullptr && !mInternalCreateChild) 00118 { 00119 _wrapItem(child, mItemsInfo.size(), "", MenuItemType::Normal, "", Any::Null); 00120 } 00121 } 00122 00123 MenuItem* MenuControl::insertItemAt(size_t _index, const UString& _name, MenuItemType _type, const std::string& _id, Any _data) 00124 { 00125 MYGUI_ASSERT_RANGE_INSERT(_index, mItemsInfo.size(), "MenuControl::insertItemAt"); 00126 if (_index == ITEM_NONE) _index = mItemsInfo.size(); 00127 00128 mInternalCreateChild = true; 00129 MenuItem* item = _getClientWidget()->createWidget<MenuItem>(getSkinByType(_type), IntCoord(), Align::Default); 00130 mInternalCreateChild = false; 00131 _wrapItem(item, _index, _name, _type, _id, _data); 00132 00133 return item; 00134 } 00135 00136 void MenuControl::removeItemAt(size_t _index) 00137 { 00138 MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::removeItemAt"); 00139 00140 if (mItemsInfo[_index].submenu) 00141 { 00142 WidgetManager::getInstance().destroyWidget(mItemsInfo[_index].submenu); 00143 mItemsInfo[_index].submenu = nullptr; 00144 } 00145 WidgetManager::getInstance().destroyWidget(mItemsInfo[_index].item); 00146 } 00147 00148 void MenuControl::removeAllItems() 00149 { 00150 while (!mItemsInfo.empty()) 00151 { 00152 if (mItemsInfo.back().submenu) 00153 { 00154 WidgetManager::getInstance().destroyWidget(mItemsInfo.back().submenu); 00155 mItemsInfo.back().submenu = nullptr; 00156 } 00157 WidgetManager::getInstance().destroyWidget(mItemsInfo.back().item); 00158 } 00159 } 00160 00161 const UString& MenuControl::getItemNameAt(size_t _index) 00162 { 00163 MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::getItemNameAt"); 00164 return mItemsInfo[_index].name; 00165 } 00166 00167 void MenuControl::update() 00168 { 00169 IntSize size; 00170 00171 if (mVerticalAlignment) 00172 { 00173 for (VectorMenuItemInfo::iterator iter = mItemsInfo.begin(); iter != mItemsInfo.end(); ++iter) 00174 { 00175 IntSize contentSize = iter->item->_getContentSize(); 00176 iter->item->setCoord(0, size.height, _getClientWidget()->getWidth(), contentSize.height); 00177 size.height += contentSize.height + mDistanceButton; 00178 00179 if (contentSize.width > size.width) 00180 size.width = contentSize.width; 00181 } 00182 if (!mItemsInfo.empty()) 00183 size.height -= mDistanceButton; 00184 } 00185 else 00186 { 00187 int maxHeight = 0; 00188 for (VectorMenuItemInfo::iterator iter = mItemsInfo.begin(); iter != mItemsInfo.end(); ++iter) 00189 { 00190 IntSize contentSize = iter->item->_getContentSize(); 00191 if (maxHeight < contentSize.height) 00192 maxHeight = contentSize.height; 00193 } 00194 00195 for (VectorMenuItemInfo::iterator iter = mItemsInfo.begin(); iter != mItemsInfo.end(); ++iter) 00196 { 00197 IntSize contentSize = iter->item->_getContentSize(); 00198 iter->item->setCoord(size.width, 0, contentSize.width, maxHeight); 00199 size.width += contentSize.width + mDistanceButton; 00200 } 00201 00202 if (!mItemsInfo.empty()) 00203 size.width -= mDistanceButton; 00204 } 00205 00206 if (mResizeToContent) 00207 setSize(size + mCoord.size() - _getClientWidget()->getSize()); 00208 } 00209 00210 void MenuControl::setItemDataAt(size_t _index, Any _data) 00211 { 00212 MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::setItemDataAt"); 00213 mItemsInfo[_index].data = _data; 00214 } 00215 00216 MenuControl* MenuControl::getItemChildAt(size_t _index) 00217 { 00218 MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::getItemChildAt"); 00219 return mItemsInfo[_index].submenu; 00220 } 00221 00222 void MenuControl::removeItemChildAt(size_t _index) 00223 { 00224 MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::removeItemChildAt"); 00225 00226 if (mItemsInfo[_index].submenu != nullptr) 00227 { 00228 WidgetManager::getInstance().destroyWidget(mItemsInfo[_index].submenu); 00229 mItemsInfo[_index].submenu = nullptr; 00230 } 00231 00232 update(); 00233 } 00234 00235 void MenuControl::setItemNameAt(size_t _index, const UString& _name) 00236 { 00237 MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::setItemNameAt"); 00238 00239 mItemsInfo[_index].name = _name; 00240 MenuItem* item = mItemsInfo[_index].item; 00241 item->setCaption(_name); 00242 00243 update(); 00244 } 00245 00246 void MenuControl::setItemIdAt(size_t _index, const std::string& _id) 00247 { 00248 MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::setItemIdAt"); 00249 mItemsInfo[_index].id = _id; 00250 } 00251 00252 const std::string& MenuControl::getItemIdAt(size_t _index) 00253 { 00254 MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::getItemIdAt"); 00255 return mItemsInfo[_index].id; 00256 } 00257 00258 void MenuControl::_notifyDeleteItem(MenuItem* _item) 00259 { 00260 // дитю меняем скин 00261 if (mChangeChildSkin) 00262 return; 00263 00264 // общий шутдаун виджета 00265 if (mShutdown) 00266 return; 00267 00268 size_t index = getItemIndex(_item); 00269 mItemsInfo.erase(mItemsInfo.begin() + index); 00270 update(); 00271 } 00272 00273 void MenuControl::_notifyDeletePopup(MenuItem* _item) 00274 { 00275 size_t index = getItemIndex(_item); 00276 mItemsInfo[index].submenu = nullptr; 00277 } 00278 00279 void MenuControl::_notifyUpdateName(MenuItem* _item) 00280 { 00281 size_t index = getItemIndex(_item); 00282 mItemsInfo[index].name = _item->getCaption(); 00283 00284 ISubWidgetText* text = _item->getSubWidgetText(); 00285 mItemsInfo[index].width = text ? (text->getTextSize().width + _item->getSize().width - text->getWidth()) : 0; 00286 update(); 00287 } 00288 00289 MenuItemType MenuControl::getItemTypeAt(size_t _index) 00290 { 00291 MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::getItemTypeAt"); 00292 return mItemsInfo[_index].type; 00293 } 00294 00295 void MenuControl::setItemTypeAt(size_t _index, MenuItemType _type) 00296 { 00297 MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::setItemTypeAt"); 00298 ItemInfo& info = mItemsInfo[_index]; 00299 if (info.type == _type) 00300 return; 00301 00302 // сохраняем данные 00303 info.type = _type; 00304 00305 // при смене скина дите отпишется 00306 mChangeChildSkin = true; 00307 info.item->changeWidgetSkin(getSkinByType(_type)); 00308 mChangeChildSkin = false; 00309 00310 info.item->setImageName(getIconIndexByType(_type )); 00311 info.item->setCaption(info.name); 00312 00313 update(); 00314 } 00315 00316 void MenuControl::notifyMenuCtrlAccept(MenuItem* _item) 00317 { 00318 if (mHideByAccept) 00319 { 00320 setVisibleSmooth(false); 00321 } 00322 else 00323 { 00324 InputManager::getInstance().setKeyFocusWidget(nullptr); 00325 } 00326 00327 MenuItem* parent_item = getMenuItemParent(); 00328 if (parent_item) 00329 { 00330 MenuControl* parent_ctrl = parent_item->getMenuCtrlParent(); 00331 if (parent_ctrl) 00332 { 00333 parent_ctrl->notifyMenuCtrlAccept(_item); 00334 } 00335 } 00336 00337 eventMenuCtrlAccept(this, _item); 00338 } 00339 00340 void MenuControl::setItemChildVisibleAt(size_t _index, bool _visible) 00341 { 00342 _setItemChildVisibleAt(_index, _visible, true); 00343 } 00344 00345 void MenuControl::_setItemChildVisibleAt(size_t _index, bool _visible, bool _smooth) 00346 { 00347 MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::setItemChildVisibleAt"); 00348 00349 if (_visible) 00350 { 00351 if (mItemsInfo[_index].submenu && mItemsInfo[_index].submenu->getItemCount()) 00352 { 00353 int offset = mItemsInfo[0].item->getAbsoluteTop() - getAbsoluteTop(); 00354 00355 const IntCoord& coord = mItemsInfo[_index].item->getAbsoluteCoord(); 00356 IntPoint point(getAbsoluteRect().right, coord.top - offset); 00357 00358 MenuControl* menu = mItemsInfo[_index].submenu; 00359 00360 if (mVerticalAlignment) 00361 { 00362 // too wide 00363 if (point.left + menu->getWidth() > menu->getParentSize().width) 00364 { 00365 // move to the left side if possible 00366 if (point.left - menu->getWidth() - getWidth() > 0) 00367 point.left -= menu->getWidth() + getWidth(); 00368 // or put near right parent border (window) if too wide for left side too 00369 else 00370 point.left = menu->getParentSize().width - menu->getWidth(); 00371 } 00372 // too high (same logic as for too wide) 00373 if (point.top + menu->getHeight() > menu->getParentSize().height) 00374 { 00375 // move to the top side if possible 00376 if (point.top - menu->getHeight() - getHeight() > 0) 00377 point.top -= menu->getHeight() + getHeight(); 00378 // or put near bottom parent border (window) if too high for top side too 00379 else 00380 point.top = menu->getParentSize().height - menu->getHeight(); 00381 } 00382 } 00383 else 00384 { 00385 point.set(coord.left, getAbsoluteRect().bottom); 00386 } 00387 00388 menu->setPosition(point); 00389 if (_smooth) 00390 menu->setVisibleSmooth(true); 00391 else 00392 menu->setVisible(true); 00393 00394 MyGUI::LayerManager::getInstance().upLayerItem(menu); 00395 } 00396 } 00397 else 00398 { 00399 if (mItemsInfo[_index].submenu) 00400 { 00401 if (_smooth) 00402 mItemsInfo[_index].submenu->setVisibleSmooth(false); 00403 else 00404 mItemsInfo[_index].submenu->setVisible(false); 00405 } 00406 } 00407 } 00408 00409 void MenuControl::notifyRootKeyChangeFocus(Widget* _sender, bool _focus) 00410 { 00411 MenuItem* item = _sender->castType<MenuItem>(); 00412 if (item->getItemType() == MenuItemType::Popup) 00413 { 00414 if (_focus) 00415 { 00416 if (!mMenuDropMode || mIsMenuDrop) 00417 { 00418 item->setItemChildVisible(true); 00419 item->setStateSelected(true); 00420 } 00421 } 00422 else 00423 { 00424 item->setItemChildVisible(false); 00425 item->setStateSelected(false); 00426 } 00427 } 00428 } 00429 00430 Widget* MenuControl::createItemChildByType(size_t _index, const std::string& _type) 00431 { 00432 MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::createItemChildByType"); 00433 removeItemChildAt(_index); 00434 Widget* child = mItemsInfo[_index].item->createWidgetT(WidgetStyle::Popup, _type, mSubMenuSkin, IntCoord(), Align::Default, mSubMenuLayer); 00435 MYGUI_ASSERT(child->isType<MenuControl>(), "child must have MenuControl base type"); 00436 return child; 00437 } 00438 00439 void MenuControl::notifyMouseButtonClick(Widget* _sender) 00440 { 00441 MenuItem* item = _sender->castType<MenuItem>(); 00442 if (mMenuDropMode) 00443 { 00444 if (mIsMenuDrop) 00445 { 00446 if (item->getItemType() == MenuItemType::Popup) 00447 { 00448 item->setStateSelected(false); 00449 item->setItemChildVisible(false); 00450 mIsMenuDrop = false; 00451 } 00452 } 00453 else 00454 { 00455 if (item->getItemType() == MenuItemType::Popup) 00456 { 00457 mIsMenuDrop = true; 00458 item->setStateSelected(true); 00459 item->setItemChildVisible(true); 00460 InputManager::getInstance().setKeyFocusWidget(item); 00461 } 00462 } 00463 } 00464 else 00465 { 00466 if ((item->getItemType() == MenuItemType::Popup && mPopupAccept) || 00467 item->getItemType() == MenuItemType::Normal) 00468 { 00469 notifyMenuCtrlAccept(item); 00470 } 00471 } 00472 } 00473 00474 void MenuControl::onKeyChangeRootFocus(bool _focus) 00475 { 00476 if (mMenuDropMode) 00477 { 00478 mIsMenuDrop = false; 00479 } 00480 if (!_focus && mHideByLostKey) 00481 { 00482 setVisibleSmooth(false); 00483 eventMenuCtrlClose(this); 00484 } 00485 Base::onKeyChangeRootFocus(_focus); 00486 } 00487 00488 void MenuControl::notifyMouseSetFocus(Widget* _sender, Widget* _new) 00489 { 00490 InputManager::getInstance().setKeyFocusWidget(_sender); 00491 } 00492 00493 void MenuControl::_wrapItemChild(MenuItem* _item, MenuControl* _widget) 00494 { 00495 // заменяем 00496 size_t index = getItemIndex(_item); 00497 if (mItemsInfo[index].submenu != nullptr) 00498 { 00499 WidgetManager::getInstance().destroyWidget(mItemsInfo[index].submenu); 00500 mItemsInfo[index].submenu = nullptr; 00501 } 00502 mItemsInfo[index].submenu = _widget; 00503 // скрываем менюшку 00504 mItemsInfo[index].submenu->setVisible(false); 00505 00506 update(); 00507 } 00508 00509 void MenuControl::_wrapItem(MenuItem* _item, size_t _index, const UString& _name, MenuItemType _type, const std::string& _id, Any _data) 00510 { 00511 _item->setAlign(mVerticalAlignment ? Align::Top | Align::HStretch : Align::Default); 00512 _item->eventRootKeyChangeFocus += newDelegate(this, &MenuControl::notifyRootKeyChangeFocus); 00513 _item->eventMouseButtonClick += newDelegate(this, &MenuControl::notifyMouseButtonClick); 00514 _item->eventMouseSetFocus += newDelegate(this, &MenuControl::notifyMouseSetFocus); 00515 00516 _item->setImageName(getIconIndexByType(_type )); 00517 00518 MenuControl* submenu = nullptr; 00519 00520 ItemInfo info = ItemInfo(_item, _name, _type, submenu, _id, _data); 00521 00522 mItemsInfo.insert(mItemsInfo.begin() + _index, info); 00523 00524 mChangeChildSkin = true; 00525 _item->changeWidgetSkin(getSkinByType(_type)); 00526 mChangeChildSkin = false; 00527 00528 // его сет капшен, обновит размер 00529 _item->setCaption(_name); 00530 00531 update(); 00532 } 00533 00534 void MenuControl::setVisible(bool _visible) 00535 { 00536 if (mAnimateSmooth) 00537 { 00538 ControllerManager::getInstance().removeItem(this); 00539 setAlpha(ALPHA_MAX); 00540 setEnabledSilent(true); 00541 mAnimateSmooth = false; 00542 } 00543 00544 if (_visible) 00545 { 00546 if (mOwner == nullptr && mHideByLostKey) 00547 { 00548 MyGUI::InputManager::getInstance().setKeyFocusWidget(this); 00549 } 00550 } 00551 00552 Base::setVisible(_visible); 00553 } 00554 00555 void MenuControl::setVisibleSmooth(bool _visible) 00556 { 00557 mAnimateSmooth = true; 00558 ControllerManager::getInstance().removeItem(this); 00559 00560 if (_visible) 00561 { 00562 setEnabledSilent(true); 00563 if (!getVisible()) 00564 { 00565 setAlpha(ALPHA_MIN); 00566 Base::setVisible(true); 00567 } 00568 00569 ControllerFadeAlpha* controller = createControllerFadeAlpha(ALPHA_MAX, POPUP_MENU_SPEED_COEF, true); 00570 controller->eventPostAction += newDelegate(action::actionWidgetShow); 00571 ControllerManager::getInstance().addItem(this, controller); 00572 } 00573 else 00574 { 00575 setEnabledSilent(false); 00576 00577 ControllerFadeAlpha* controller = createControllerFadeAlpha(ALPHA_MIN, POPUP_MENU_SPEED_COEF, false); 00578 controller->eventPostAction += newDelegate(action::actionWidgetHide); 00579 ControllerManager::getInstance().addItem(this, controller); 00580 } 00581 } 00582 00583 ControllerFadeAlpha* MenuControl::createControllerFadeAlpha(float _alpha, float _coef, bool _enable) 00584 { 00585 ControllerItem* item = ControllerManager::getInstance().createItem(ControllerFadeAlpha::getClassTypeName()); 00586 ControllerFadeAlpha* controller = item->castType<ControllerFadeAlpha>(); 00587 00588 controller->setAlpha(_alpha); 00589 controller->setCoef(_coef); 00590 controller->setEnabled(_enable); 00591 00592 return controller; 00593 } 00594 00595 MenuItem* MenuControl::insertItem(MenuItem* _to, const UString& _name, MenuItemType _type, const std::string& _id, Any _data) 00596 { 00597 return insertItemAt(getItemIndex(_to), _name, _type, _id, _data); 00598 } 00599 00600 MenuItem* MenuControl::addItem(const UString& _name, MenuItemType _type, const std::string& _id, Any _data) 00601 { 00602 return insertItemAt(ITEM_NONE, _name, _type, _id, _data); 00603 } 00604 00605 void MenuControl::removeItem(MenuItem* _item) 00606 { 00607 removeItemAt(getItemIndex(_item)); 00608 } 00609 00610 MenuItem* MenuControl::getItemAt(size_t _index) 00611 { 00612 MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "MenuControl::getItemAt"); 00613 return mItemsInfo[_index].item; 00614 } 00615 00616 size_t MenuControl::getItemIndex(MenuItem* _item) 00617 { 00618 for (size_t pos = 0; pos < mItemsInfo.size(); pos++) 00619 { 00620 if (mItemsInfo[pos].item == _item) 00621 return pos; 00622 } 00623 MYGUI_EXCEPT("item (" << _item << ") not found, source 'MenuControl::getItemIndex'"); 00624 } 00625 00626 MenuItem* MenuControl::findItemWith(const UString& _name) 00627 { 00628 for (size_t pos = 0; pos < mItemsInfo.size(); pos++) 00629 { 00630 if (mItemsInfo[pos].name == _name) 00631 return mItemsInfo[pos].item; 00632 } 00633 return nullptr; 00634 } 00635 00636 MenuItem* MenuControl::getItemById(const std::string& _id) 00637 { 00638 for (size_t index = 0; index < mItemsInfo.size(); index++) 00639 { 00640 if (mItemsInfo[index].id == _id) 00641 return mItemsInfo[index].item; 00642 } 00643 MYGUI_EXCEPT("item id (" << _id << ") not found, source 'MenuControl::getItemById'"); 00644 } 00645 00646 size_t MenuControl::getItemIndexById(const std::string& _id) 00647 { 00648 for (size_t index = 0; index < mItemsInfo.size(); index++) 00649 { 00650 if (mItemsInfo[index].id == _id) 00651 return index; 00652 } 00653 MYGUI_EXCEPT("item id (" << _id << ") not found, source 'MenuControl::getItemById'"); 00654 } 00655 00656 MenuItem* MenuControl::findItemById(const std::string& _id, bool _recursive) 00657 { 00658 for (size_t index = 0; index < mItemsInfo.size(); index++) 00659 { 00660 if (mItemsInfo[index].id == _id) 00661 return mItemsInfo[index].item; 00662 00663 if (_recursive && mItemsInfo[index].submenu != nullptr) 00664 { 00665 MenuItem* find = mItemsInfo[index].submenu->findItemById(_id, _recursive); 00666 if (find != nullptr) 00667 return find; 00668 } 00669 } 00670 return nullptr; 00671 } 00672 00673 size_t MenuControl::findItemIndexWith(const UString& _name) 00674 { 00675 for (size_t index = 0; index < mItemsInfo.size(); index++) 00676 { 00677 if (mItemsInfo[index].name == _name) 00678 return index; 00679 } 00680 return ITEM_NONE; 00681 } 00682 00683 size_t MenuControl::findItemIndex(MenuItem* _item) 00684 { 00685 for (size_t index = 0; index < mItemsInfo.size(); index++) 00686 { 00687 if (mItemsInfo[index].item == _item) 00688 return index; 00689 } 00690 return ITEM_NONE; 00691 } 00692 00693 Widget* MenuControl::_getClientWidget() 00694 { 00695 return mClient == nullptr ? this : mClient; 00696 } 00697 00698 size_t MenuControl::getItemCount() const 00699 { 00700 return mItemsInfo.size(); 00701 } 00702 00703 void MenuControl::setItemData(MenuItem* _item, Any _data) 00704 { 00705 setItemDataAt(getItemIndex(_item), _data); 00706 } 00707 00708 void MenuControl::clearItemDataAt(size_t _index) 00709 { 00710 setItemDataAt(_index, Any::Null); 00711 } 00712 00713 void MenuControl::clearItemData(MenuItem* _item) 00714 { 00715 clearItemDataAt(getItemIndex(_item)); 00716 } 00717 00718 void MenuControl::setItemId(MenuItem* _item, const std::string& _id) 00719 { 00720 setItemIdAt(getItemIndex(_item), _id); 00721 } 00722 00723 const std::string& MenuControl::getItemId(MenuItem* _item) 00724 { 00725 return getItemIdAt(getItemIndex(_item)); 00726 } 00727 00728 void MenuControl::setItemName(MenuItem* _item, const UString& _name) 00729 { 00730 setItemNameAt(getItemIndex(_item), _name); 00731 } 00732 00733 const UString& MenuControl::getItemName(MenuItem* _item) 00734 { 00735 return getItemNameAt(getItemIndex(_item)); 00736 } 00737 00738 void MenuControl::setItemChildVisible(MenuItem* _item, bool _visible) 00739 { 00740 setItemChildVisibleAt(getItemIndex(_item), _visible); 00741 } 00742 00743 MenuControl* MenuControl::getItemChild(MenuItem* _item) 00744 { 00745 return getItemChildAt(getItemIndex(_item)); 00746 } 00747 00748 MenuControl* MenuControl::createItemChildAt(size_t _index) 00749 { 00750 return createItemChildTAt<MenuControl>(_index); 00751 } 00752 00753 MenuControl* MenuControl::createItemChild(MenuItem* _item) 00754 { 00755 return createItemChildAt(getItemIndex(_item)); 00756 } 00757 00758 void MenuControl::removeItemChild(MenuItem* _item) 00759 { 00760 removeItemChildAt(getItemIndex(_item)); 00761 } 00762 00763 MenuItemType MenuControl::getItemType(MenuItem* _item) 00764 { 00765 return getItemTypeAt(getItemIndex(_item)); 00766 } 00767 00768 void MenuControl::setItemType(MenuItem* _item, MenuItemType _type) 00769 { 00770 setItemTypeAt(getItemIndex(_item), _type); 00771 } 00772 00773 void MenuControl::setPopupAccept(bool _value) 00774 { 00775 mPopupAccept = _value; 00776 } 00777 00778 bool MenuControl::getPopupAccept() const 00779 { 00780 return mPopupAccept; 00781 } 00782 00783 MenuItem* MenuControl::getMenuItemParent() 00784 { 00785 return mOwner; 00786 } 00787 00788 const std::string& MenuControl::getSkinByType(MenuItemType _type) const 00789 { 00790 if (_type == MenuItemType::Popup) 00791 return mItemPopupSkin; 00792 else if (_type == MenuItemType::Separator) 00793 return mItemSeparatorSkin; 00794 return mItemNormalSkin; 00795 } 00796 00797 std::string MenuControl::getIconIndexByType(MenuItemType _type) const 00798 { 00799 if (_type == MenuItemType::Popup) 00800 return "Popup"; 00801 return "None"; 00802 } 00803 00804 MenuItemType MenuControl::getItemType(bool _submenu, bool _separator) const 00805 { 00806 if (_submenu) 00807 return MenuItemType::Popup; 00808 else if (_separator) 00809 return MenuItemType::Separator; 00810 return MenuItemType::Normal; 00811 } 00812 00813 size_t MenuControl::_getItemCount() 00814 { 00815 return getItemCount(); 00816 } 00817 00818 void MenuControl::_addItem(const MyGUI::UString& _name) 00819 { 00820 addItem(_name, MenuItemType::Normal); 00821 } 00822 00823 void MenuControl::_removeItemAt(size_t _index) 00824 { 00825 removeItemAt(_index); 00826 00827 _updateSizeForEmpty(); 00828 } 00829 00830 Widget* MenuControl::_getItemAt(size_t _index) 00831 { 00832 return getItemAt(_index); 00833 } 00834 00835 void MenuControl::_setItemNameAt(size_t _index, const UString& _name) 00836 { 00837 setItemNameAt(_index, _name); 00838 } 00839 00840 const UString& MenuControl::_getItemNameAt(size_t _index) 00841 { 00842 return getItemNameAt(_index); 00843 } 00844 00845 void MenuControl::_setItemSelected(IItem* _item) 00846 { 00847 MenuItem* item = static_cast<MenuItem*>(_item); 00848 for (VectorMenuItemInfo::iterator iter = mItemsInfo.begin(); iter != mItemsInfo.end(); ++iter) 00849 { 00850 if ((*iter).type == MenuItemType::Popup) 00851 { 00852 (*iter).item->setStateSelected(false); 00853 00854 if ((*iter).submenu != nullptr) 00855 (*iter).submenu->setVisible(false); 00856 } 00857 } 00858 00859 if (item->getItemType() == MenuItemType::Popup) 00860 { 00861 item->setStateSelected(true); 00862 size_t index = getItemIndex(item); 00863 00864 _setItemChildVisibleAt(index, true, false); 00865 00866 _updateItems(index); 00867 } 00868 } 00869 00870 void MenuControl::_updateItems(size_t _index) 00871 { 00872 if (mItemsInfo[_index].submenu != nullptr) 00873 mItemsInfo[_index].submenu->_updateSizeForEmpty(); 00874 } 00875 00876 void MenuControl::_updateSizeForEmpty() 00877 { 00878 if (mItemsInfo.empty()) 00879 setSize(100, 100); 00880 } 00881 00882 void MenuControl::setVerticalAlignment(bool _value) 00883 { 00884 mVerticalAlignment = _value; 00885 00886 update(); 00887 } 00888 00889 bool MenuControl::getVerticalAlignment() const 00890 { 00891 return mVerticalAlignment; 00892 } 00893 00894 void MenuControl::setPropertyOverride(const std::string& _key, const std::string& _value) 00895 { 00897 if (_key == "VerticalAlignment") 00898 setVerticalAlignment(utility::parseValue<bool>(_value)); 00899 00900 else 00901 { 00902 Base::setPropertyOverride(_key, _value); 00903 return; 00904 } 00905 00906 eventChangeProperty(this, _key, _value); 00907 } 00908 00909 } // namespace MyGUI