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