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_Widget.h" 00024 #include "MyGUI_Gui.h" 00025 #include "MyGUI_InputManager.h" 00026 #include "MyGUI_SkinManager.h" 00027 #include "MyGUI_SubWidgetManager.h" 00028 #include "MyGUI_WidgetManager.h" 00029 #include "MyGUI_ResourceSkin.h" 00030 #include "MyGUI_WidgetDefines.h" 00031 #include "MyGUI_LayerItem.h" 00032 #include "MyGUI_LayerManager.h" 00033 #include "MyGUI_RenderItem.h" 00034 #include "MyGUI_ISubWidget.h" 00035 #include "MyGUI_ISubWidgetText.h" 00036 #include "MyGUI_TextBox.h" 00037 #include "MyGUI_FactoryManager.h" 00038 #include "MyGUI_CoordConverter.h" 00039 #include "MyGUI_RenderManager.h" 00040 #include "MyGUI_ToolTipManager.h" 00041 #include "MyGUI_LayoutManager.h" 00042 00043 namespace MyGUI 00044 { 00045 00046 Widget::Widget() : 00047 mWidgetClient(nullptr), 00048 mEnabled(true), 00049 mInheritsEnabled(true), 00050 mInheritsVisible(true), 00051 mAlpha(ALPHA_MAX), 00052 mRealAlpha(ALPHA_MAX), 00053 mInheritsAlpha(true), 00054 mParent(nullptr), 00055 mWidgetStyle(WidgetStyle::Child), 00056 mContainer(nullptr), 00057 mAlign(Align::Default), 00058 mVisible(true) 00059 { 00060 } 00061 00062 Widget::~Widget() 00063 { 00064 } 00065 00066 void Widget::_initialise(WidgetStyle _style, const IntCoord& _coord, const std::string& _skinName, Widget* _parent, ICroppedRectangle* _croppedParent, const std::string& _name) 00067 { 00068 ResourceSkin* skinInfo = nullptr; 00069 ResourceLayout* templateInfo = nullptr; 00070 00071 if (LayoutManager::getInstance().isExist(_skinName)) 00072 templateInfo = LayoutManager::getInstance().getByName(_skinName); 00073 else 00074 skinInfo = SkinManager::getInstance().getByName(_skinName); 00075 00076 mCoord = _coord; 00077 00078 mAlign = Align::Default; 00079 mWidgetStyle = _style; 00080 mName = _name; 00081 00082 mCroppedParent = _croppedParent; 00083 mParent = _parent; 00084 00085 00086 #if MYGUI_DEBUG_MODE == 1 00087 // проверяем соответсвие входных данных 00088 if (mWidgetStyle == WidgetStyle::Child) 00089 { 00090 MYGUI_ASSERT(mCroppedParent, "must be cropped"); 00091 MYGUI_ASSERT(mParent, "must be parent"); 00092 } 00093 else if (mWidgetStyle == WidgetStyle::Overlapped) 00094 { 00095 MYGUI_ASSERT((mParent == nullptr) == (mCroppedParent == nullptr), "error cropped"); 00096 } 00097 else if (mWidgetStyle == WidgetStyle::Popup) 00098 { 00099 MYGUI_ASSERT(!mCroppedParent, "cropped must be nullptr"); 00100 MYGUI_ASSERT(mParent, "must be parent"); 00101 } 00102 #endif 00103 00104 // корректируем абсолютные координаты 00105 mAbsolutePosition = _coord.point(); 00106 00107 if (nullptr != mCroppedParent) 00108 mAbsolutePosition += mCroppedParent->getAbsolutePosition(); 00109 00110 const WidgetInfo* root = initialiseWidgetSkinBase(skinInfo, templateInfo); 00111 00112 // дочернее окно обыкновенное 00113 if (mWidgetStyle == WidgetStyle::Child) 00114 { 00115 if (mParent) 00116 mParent->addChildItem(this); 00117 } 00118 // дочернее нуно перекрывающееся 00119 else if (mWidgetStyle == WidgetStyle::Overlapped) 00120 { 00121 // дочернее перекрывающееся 00122 if (mParent) 00123 mParent->addChildNode(this); 00124 } 00125 00126 // витр метод для наследников 00127 initialiseOverride(); 00128 00129 if (skinInfo != nullptr) 00130 setSkinProperty(skinInfo); 00131 00132 if (root != nullptr) 00133 { 00134 for (VectorStringPairs::const_iterator iter = root->properties.begin(); iter != root->properties.end(); ++iter) 00135 { 00136 setProperty(iter->first, iter->second); 00137 } 00138 } 00139 } 00140 00141 void Widget::_shutdown() 00142 { 00143 // витр метод для наследников 00144 shutdownOverride(); 00145 00146 shutdownWidgetSkinBase(); 00147 00148 _destroyAllChildWidget(); 00149 00150 // дочернее окно обыкновенное 00151 if (mWidgetStyle == WidgetStyle::Child) 00152 { 00153 if (mParent) 00154 mParent->removeChildItem(this); 00155 } 00156 // дочернее нуно перекрывающееся 00157 else if (mWidgetStyle == WidgetStyle::Overlapped) 00158 { 00159 // дочернее перекрывающееся 00160 if (mParent) 00161 mParent->removeChildNode(this); 00162 } 00163 00164 mParent = nullptr; 00165 mCroppedParent = nullptr; 00166 } 00167 00168 void Widget::changeWidgetSkin(const std::string& _skinName) 00169 { 00170 ResourceSkin* skinInfo = nullptr; 00171 ResourceLayout* templateInfo = nullptr; 00172 00173 if (LayoutManager::getInstance().isExist(_skinName)) 00174 templateInfo = LayoutManager::getInstance().getByName(_skinName); 00175 else 00176 skinInfo = SkinManager::getInstance().getByName(_skinName); 00177 00178 shutdownOverride(); 00179 00180 saveLayerItem(); 00181 00182 shutdownWidgetSkinBase(); 00183 const WidgetInfo* root = initialiseWidgetSkinBase(skinInfo, templateInfo); 00184 00185 restoreLayerItem(); 00186 00187 initialiseOverride(); 00188 00189 if (skinInfo != nullptr) 00190 setSkinProperty(skinInfo); 00191 00192 if (root != nullptr) 00193 { 00194 for (VectorStringPairs::const_iterator iter = root->properties.begin(); iter != root->properties.end(); ++iter) 00195 { 00196 setProperty(iter->first, iter->second); 00197 } 00198 } 00199 } 00200 00201 const WidgetInfo* Widget::initialiseWidgetSkinBase(ResourceSkin* _skinInfo, ResourceLayout* _templateInfo) 00202 { 00203 const WidgetInfo* root = nullptr; 00204 bool skinOnly = false; 00205 00206 if (_skinInfo == nullptr) 00207 { 00208 skinOnly = true; 00209 std::string skinName; 00210 00211 const VectorWidgetInfo& data = _templateInfo->getLayoutData(); 00212 for (VectorWidgetInfo::const_iterator item = data.begin(); item != data.end(); ++item) 00213 { 00214 if ((*item).name == "Root") 00215 { 00216 skinName = (*item).skin; 00217 root = &(*item); 00218 break; 00219 } 00220 } 00221 00222 _skinInfo = SkinManager::getInstance().getByName(skinName); 00223 } 00224 00225 //SAVE 00226 const IntSize& _size = mCoord.size(); 00227 00228 if (_skinInfo != nullptr) 00229 { 00230 //FIXME - явный вызов 00231 Widget::setSize(_skinInfo->getSize()); 00232 00233 _createSkinItem(_skinInfo); 00234 } 00235 00236 // выставляем альфу, корректировка по отцу автоматически 00237 _updateAlpha(); 00238 _updateEnabled(); 00239 _updateVisible(); 00240 00241 if (!skinOnly) 00242 { 00243 const MapString& properties = _skinInfo->getProperties(); 00244 for (MapString::const_iterator item = properties.begin(); item != properties.end(); ++item) 00245 { 00246 if (BackwardCompatibility::isIgnoreProperty((*item).first)) 00247 setUserString((*item).first, (*item).second); 00248 } 00249 00250 // создаем детей скина 00251 const VectorChildSkinInfo& child = _skinInfo->getChild(); 00252 for (VectorChildSkinInfo::const_iterator iter = child.begin(); iter != child.end(); ++iter) 00253 { 00254 Widget* widget = baseCreateWidget(iter->style, iter->type, iter->skin, iter->coord, iter->align, iter->layer, iter->name, true); 00255 // заполняем UserString пропертями 00256 for (MapString::const_iterator prop = iter->params.begin(); prop != iter->params.end(); ++prop) 00257 widget->setUserString(prop->first, prop->second); 00258 } 00259 } 00260 00261 if (root != nullptr) 00262 { 00263 //FIXME - явный вызов 00264 Widget::setSize(root->intCoord.size()); 00265 00266 for (MapString::const_iterator iter = root->userStrings.begin(); iter != root->userStrings.end(); ++iter) 00267 { 00268 setUserString(iter->first, iter->second); 00269 } 00270 00271 for (VectorWidgetInfo::const_iterator iter = root->childWidgetsInfo.begin(); iter != root->childWidgetsInfo.end(); ++iter) 00272 { 00273 _templateInfo->createWidget(*iter, "", this, true); 00274 } 00275 } 00276 00277 //FIXME - явный вызов 00278 Widget::setSize(_size); 00279 00280 return root; 00281 } 00282 00283 void Widget::shutdownWidgetSkinBase() 00284 { 00285 setMaskPick(""); 00286 00287 _deleteSkinItem(); 00288 00289 // удаляем виджеты чтобы ли в скине 00290 for (VectorWidgetPtr::iterator iter = mWidgetChildSkin.begin(); iter != mWidgetChildSkin.end(); ++iter) 00291 { 00292 // Добавляем себя чтобы удалилось 00293 mWidgetChild.push_back(*iter); 00294 _destroyChildWidget(*iter); 00295 } 00296 mWidgetChildSkin.clear(); 00297 00298 mWidgetClient = nullptr; 00299 } 00300 00301 Widget* Widget::baseCreateWidget(WidgetStyle _style, const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _layer, const std::string& _name, bool _template) 00302 { 00303 Widget* widget = nullptr; 00304 00305 if (_template) 00306 { 00307 widget = WidgetManager::getInstance().createWidget(_style, _type, _skin, _coord, this, _style == WidgetStyle::Popup ? nullptr : this, _name); 00308 mWidgetChildSkin.push_back(widget); 00309 } 00310 else 00311 { 00312 if (mWidgetClient != nullptr) 00313 { 00314 widget = mWidgetClient->baseCreateWidget(_style, _type, _skin, _coord, _align, _layer, _name, _template); 00315 onWidgetCreated(widget); 00316 return widget; 00317 } 00318 else 00319 { 00320 widget = WidgetManager::getInstance().createWidget(_style, _type, _skin, _coord, this, _style == WidgetStyle::Popup ? nullptr : this, _name); 00321 mWidgetChild.push_back(widget); 00322 } 00323 } 00324 00325 widget->setAlign(_align); 00326 00327 // присоединяем виджет с уровню 00328 if (!_layer.empty() && widget->isRootWidget()) 00329 LayerManager::getInstance().attachToLayerNode(_layer, widget); 00330 00331 onWidgetCreated(widget); 00332 00333 return widget; 00334 } 00335 00336 Widget* Widget::createWidgetRealT(const std::string& _type, const std::string& _skin, const FloatCoord& _coord, Align _align, const std::string& _name) 00337 { 00338 return createWidgetT(_type, _skin, CoordConverter::convertFromRelative(_coord, getSize()), _align, _name); 00339 } 00340 00341 void Widget::_updateView() 00342 { 00343 bool margin = mCroppedParent ? _checkMargin() : false; 00344 00345 // вьюпорт стал битым 00346 if (margin) 00347 { 00348 // проверка на полный выход за границу 00349 if (_checkOutside()) 00350 { 00351 // запоминаем текущее состояние 00352 mIsMargin = margin; 00353 00354 // скрываем 00355 _setSubSkinVisible(false); 00356 00357 // вся иерархия должна быть проверенна 00358 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) 00359 (*widget)->_updateView(); 00360 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) 00361 (*widget)->_updateView(); 00362 00363 return; 00364 } 00365 00366 } 00367 // мы не обрезаны и были нормальные 00368 else if (!mIsMargin) 00369 { 00370 _updateSkinItemView(); 00371 return; 00372 } 00373 00374 // запоминаем текущее состояние 00375 mIsMargin = margin; 00376 00377 // если скин был скрыт, то покажем 00378 _setSubSkinVisible(true); 00379 00380 // обновляем наших детей, а они уже решат обновлять ли своих детей 00381 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) 00382 (*widget)->_updateView(); 00383 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) 00384 (*widget)->_updateView(); 00385 00386 _updateSkinItemView(); 00387 } 00388 00389 bool Widget::_setWidgetState(const std::string& _state) 00390 { 00391 return _setSkinItemState(_state); 00392 } 00393 00394 void Widget::_destroyChildWidget(Widget* _widget) 00395 { 00396 MYGUI_ASSERT(nullptr != _widget, "invalid widget pointer"); 00397 00398 if (mParent != nullptr && mParent->getClientWidget() == this) 00399 mParent->onWidgetDestroy(_widget); 00400 00401 onWidgetDestroy(_widget); 00402 00403 VectorWidgetPtr::iterator iter = std::find(mWidgetChild.begin(), mWidgetChild.end(), _widget); 00404 if (iter != mWidgetChild.end()) 00405 { 00406 // сохраняем указатель 00407 MyGUI::Widget* widget = *iter; 00408 00409 // удаляем из списка 00410 mWidgetChild.erase(iter); 00411 00412 // отписываем от всех 00413 WidgetManager::getInstance().unlinkFromUnlinkers(_widget); 00414 00415 // непосредственное удаление 00416 WidgetManager::getInstance()._deleteWidget(widget); 00417 } 00418 else 00419 { 00420 MYGUI_EXCEPT("Widget '" << _widget->getName() << "' not found"); 00421 } 00422 } 00423 00424 // удаляет всех детей 00425 void Widget::_destroyAllChildWidget() 00426 { 00427 WidgetManager& manager = WidgetManager::getInstance(); 00428 while (!mWidgetChild.empty()) 00429 { 00430 // сразу себя отписывем, иначе вложенной удаление убивает все 00431 Widget* widget = mWidgetChild.back(); 00432 mWidgetChild.pop_back(); 00433 00434 // отписываем от всех 00435 manager.unlinkFromUnlinkers(widget); 00436 00437 // и сами удалим, так как его больше в списке нет 00438 WidgetManager::getInstance()._deleteWidget(widget); 00439 } 00440 } 00441 00442 IntCoord Widget::getClientCoord() 00443 { 00444 MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget"); 00445 if (mWidgetClient != nullptr) 00446 return mWidgetClient->getCoord(); 00447 return IntCoord(0, 0, mCoord.width, mCoord.height); 00448 } 00449 00450 void Widget::setAlpha(float _alpha) 00451 { 00452 if (mAlpha == _alpha) 00453 return; 00454 mAlpha = _alpha; 00455 00456 _updateAlpha(); 00457 } 00458 00459 void Widget::_updateAlpha() 00460 { 00461 if (nullptr != mParent) 00462 mRealAlpha = mAlpha * (mInheritsAlpha ? mParent->_getRealAlpha() : ALPHA_MAX); 00463 else 00464 mRealAlpha = mAlpha; 00465 00466 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) 00467 (*widget)->_updateAlpha(); 00468 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) 00469 (*widget)->_updateAlpha(); 00470 00471 _setSkinItemAlpha(mRealAlpha); 00472 } 00473 00474 void Widget::setInheritsAlpha(bool _inherits) 00475 { 00476 mInheritsAlpha = _inherits; 00477 _updateAlpha(); 00478 } 00479 00480 ILayerItem* Widget::getLayerItemByPoint(int _left, int _top) const 00481 { 00482 // проверяем попадание 00483 if (!mEnabled 00484 || !mVisible 00485 || (!getNeedMouseFocus() && !getInheritsPick()) 00486 || !_checkPoint(_left, _top) 00487 // если есть маска, проверяем еще и по маске 00488 || !isMaskPickInside(IntPoint(_left - mCoord.left, _top - mCoord.top), mCoord) 00489 ) 00490 return nullptr; 00491 00492 // спрашиваем у детишек 00493 for (VectorWidgetPtr::const_reverse_iterator widget = mWidgetChild.rbegin(); widget != mWidgetChild.rend(); ++widget) 00494 { 00495 // общаемся только с послушными детьми 00496 if ((*widget)->mWidgetStyle == WidgetStyle::Popup) 00497 continue; 00498 00499 ILayerItem* item = (*widget)->getLayerItemByPoint(_left - mCoord.left, _top - mCoord.top); 00500 if (item != nullptr) 00501 return item; 00502 } 00503 // спрашиваем у детишек скна 00504 for (VectorWidgetPtr::const_reverse_iterator widget = mWidgetChildSkin.rbegin(); widget != mWidgetChildSkin.rend(); ++widget) 00505 { 00506 ILayerItem* item = (*widget)->getLayerItemByPoint(_left - mCoord.left, _top - mCoord.top); 00507 if (item != nullptr) 00508 return item; 00509 } 00510 00511 // непослушные дети 00512 return getInheritsPick() ? nullptr : (ILayerItem*)(this); 00513 } 00514 00515 void Widget::_updateAbsolutePoint() 00516 { 00517 // мы рут, нам не надо 00518 if (!mCroppedParent) 00519 return; 00520 00521 mAbsolutePosition = mCroppedParent->getAbsolutePosition() + mCoord.point(); 00522 00523 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) 00524 (*widget)->_updateAbsolutePoint(); 00525 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) 00526 (*widget)->_updateAbsolutePoint(); 00527 00528 _correctSkinItemView(); 00529 } 00530 00531 void Widget::_forcePick(Widget* _widget) 00532 { 00533 MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget"); 00534 if (mWidgetClient != nullptr) 00535 mWidgetClient->_forcePick(_widget); 00536 00537 VectorWidgetPtr::iterator item = std::remove(mWidgetChild.begin(), mWidgetChild.end(), _widget); 00538 if (item != mWidgetChild.end()) 00539 { 00540 mWidgetChild.erase(item); 00541 mWidgetChild.insert(mWidgetChild.begin(), _widget); 00542 } 00543 } 00544 00545 Widget* Widget::findWidget(const std::string& _name) 00546 { 00547 if (_name == mName) 00548 return this; 00549 MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget"); 00550 if (mWidgetClient != nullptr) 00551 return mWidgetClient->findWidget(_name); 00552 00553 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) 00554 { 00555 Widget* find = (*widget)->findWidget(_name); 00556 if (nullptr != find) 00557 return find; 00558 } 00559 return nullptr; 00560 } 00561 00562 void Widget::setRealPosition(const FloatPoint& _point) 00563 { 00564 setPosition(CoordConverter::convertFromRelative(_point, mCroppedParent == nullptr ? RenderManager::getInstance().getViewSize() : mCroppedParent->getSize())); 00565 } 00566 00567 void Widget::setRealSize(const FloatSize& _size) 00568 { 00569 setSize(CoordConverter::convertFromRelative(_size, mCroppedParent == nullptr ? RenderManager::getInstance().getViewSize() : mCroppedParent->getSize())); 00570 } 00571 00572 void Widget::setRealCoord(const FloatCoord& _coord) 00573 { 00574 setCoord(CoordConverter::convertFromRelative(_coord, mCroppedParent == nullptr ? RenderManager::getInstance().getViewSize() : mCroppedParent->getSize())); 00575 } 00576 00577 void Widget::_setAlign(const IntSize& _oldsize, const IntSize& _newSize) 00578 { 00579 const IntSize& size = _newSize;//getParentSize(); 00580 00581 bool need_move = false; 00582 bool need_size = false; 00583 IntCoord coord = mCoord; 00584 00585 // первоначальное выравнивание 00586 if (mAlign.isHStretch()) 00587 { 00588 // растягиваем 00589 coord.width = mCoord.width + (size.width - _oldsize.width); 00590 need_size = true; 00591 } 00592 else if (mAlign.isRight()) 00593 { 00594 // двигаем по правому краю 00595 coord.left = mCoord.left + (size.width - _oldsize.width); 00596 need_move = true; 00597 } 00598 else if (mAlign.isHCenter()) 00599 { 00600 // выравнивание по горизонтали без растяжения 00601 coord.left = (size.width - mCoord.width) / 2; 00602 need_move = true; 00603 } 00604 00605 if (mAlign.isVStretch()) 00606 { 00607 // растягиваем 00608 coord.height = mCoord.height + (size.height - _oldsize.height); 00609 need_size = true; 00610 } 00611 else if (mAlign.isBottom()) 00612 { 00613 // двигаем по нижнему краю 00614 coord.top = mCoord.top + (size.height - _oldsize.height); 00615 need_move = true; 00616 } 00617 else if (mAlign.isVCenter()) 00618 { 00619 // выравнивание по вертикали без растяжения 00620 coord.top = (size.height - mCoord.height) / 2; 00621 need_move = true; 00622 } 00623 00624 if (need_move) 00625 { 00626 if (need_size) 00627 setCoord(coord); 00628 else 00629 setPosition(coord.point()); 00630 } 00631 else if (need_size) 00632 { 00633 setSize(coord.size()); 00634 } 00635 else 00636 { 00637 _updateView(); // только если не вызвано передвижение и сайз 00638 } 00639 } 00640 00641 void Widget::setPosition(const IntPoint& _point) 00642 { 00643 // обновляем абсолютные координаты 00644 mAbsolutePosition += _point - mCoord.point(); 00645 00646 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) 00647 (*widget)->_updateAbsolutePoint(); 00648 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) 00649 (*widget)->_updateAbsolutePoint(); 00650 00651 mCoord = _point; 00652 00653 _updateView(); 00654 } 00655 00656 void Widget::setSize(const IntSize& _size) 00657 { 00658 // устанавливаем новую координату а старую пускаем в расчеты 00659 IntSize old = mCoord.size(); 00660 mCoord = _size; 00661 00662 bool visible = true; 00663 00664 // обновляем выравнивание 00665 bool margin = mCroppedParent ? _checkMargin() : false; 00666 00667 if (margin) 00668 { 00669 // проверка на полный выход за границу 00670 if (_checkOutside()) 00671 { 00672 // скрываем 00673 visible = false; 00674 } 00675 } 00676 00677 _setSubSkinVisible(visible); 00678 00679 // передаем старую координату , до вызова, текущая координата отца должна быть новой 00680 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) 00681 (*widget)->_setAlign(old, getSize()); 00682 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) 00683 (*widget)->_setAlign(old, getSize()); 00684 00685 _setSkinItemAlign(old); 00686 00687 // запоминаем текущее состояние 00688 mIsMargin = margin; 00689 } 00690 00691 void Widget::setCoord(const IntCoord& _coord) 00692 { 00693 // обновляем абсолютные координаты 00694 mAbsolutePosition += _coord.point() - mCoord.point(); 00695 00696 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) 00697 (*widget)->_updateAbsolutePoint(); 00698 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) 00699 (*widget)->_updateAbsolutePoint(); 00700 00701 // устанавливаем новую координату а старую пускаем в расчеты 00702 IntCoord old = mCoord; 00703 mCoord = _coord; 00704 00705 bool visible = true; 00706 00707 // обновляем выравнивание 00708 bool margin = mCroppedParent ? _checkMargin() : false; 00709 00710 if (margin) 00711 { 00712 // проверка на полный выход за границу 00713 if (_checkOutside()) 00714 { 00715 // скрываем 00716 visible = false; 00717 } 00718 } 00719 00720 _setSubSkinVisible(visible); 00721 00722 // передаем старую координату , до вызова, текущая координата отца должна быть новой 00723 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) 00724 (*widget)->_setAlign(old.size(), getSize()); 00725 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) 00726 (*widget)->_setAlign(old.size(), getSize()); 00727 00728 _setSkinItemAlign(old.size()); 00729 00730 // запоминаем текущее состояние 00731 mIsMargin = margin; 00732 } 00733 00734 void Widget::setAlign(Align _value) 00735 { 00736 mAlign = _value; 00737 } 00738 00739 void Widget::detachFromWidget(const std::string& _layer) 00740 { 00741 std::string oldlayer = getLayer() != nullptr ? getLayer()->getName() : ""; 00742 00743 Widget* parent = getParent(); 00744 if (parent) 00745 { 00746 // отдетачиваемся от лееров 00747 if ( ! isRootWidget() ) 00748 { 00749 detachFromLayerItemNode(true); 00750 00751 if (mWidgetStyle == WidgetStyle::Child) 00752 { 00753 mParent->removeChildItem(this); 00754 } 00755 else if (mWidgetStyle == WidgetStyle::Overlapped) 00756 { 00757 mParent->removeChildNode(this); 00758 } 00759 00760 mWidgetStyle = WidgetStyle::Overlapped; 00761 00762 mCroppedParent = nullptr; 00763 00764 // обновляем координаты 00765 mAbsolutePosition = mCoord.point(); 00766 00767 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) 00768 (*widget)->_updateAbsolutePoint(); 00769 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) 00770 (*widget)->_updateAbsolutePoint(); 00771 00772 // сбрасываем обрезку 00773 mMargin.clear(); 00774 00775 _updateView(); 00776 } 00777 00778 // нам нужен самый рутовый парент 00779 while (parent->getParent()) 00780 parent = parent->getParent(); 00781 00782 //mIWidgetCreator = parent->mIWidgetCreator; 00783 //mIWidgetCreator->_linkChildWidget(this); 00784 Gui::getInstance()._linkChildWidget(this); 00785 mParent->_unlinkChildWidget(this); 00786 mParent = nullptr; 00787 } 00788 00789 if (!_layer.empty()) 00790 { 00791 LayerManager::getInstance().attachToLayerNode(_layer, this); 00792 } 00793 else if (!oldlayer.empty()) 00794 { 00795 LayerManager::getInstance().attachToLayerNode(oldlayer, this); 00796 } 00797 00798 _updateAlpha(); 00799 } 00800 00801 void Widget::attachToWidget(Widget* _parent, WidgetStyle _style, const std::string& _layer) 00802 { 00803 MYGUI_ASSERT(_parent, "parent must be valid"); 00804 MYGUI_ASSERT(_parent != this, "cyclic attach (attaching to self)"); 00805 00806 // attach to client if widget have it 00807 if (_parent->getClientWidget()) 00808 _parent = _parent->getClientWidget(); 00809 00810 // проверяем на цикличность атача 00811 Widget* parent = _parent; 00812 while (parent->getParent()) 00813 { 00814 MYGUI_ASSERT(parent != this, "cyclic attach"); 00815 parent = parent->getParent(); 00816 } 00817 00818 // отдетачиваемся от всего 00819 detachFromWidget(); 00820 00821 mWidgetStyle = _style; 00822 00823 if (_style == WidgetStyle::Popup) 00824 { 00825 //mIWidgetCreator->_unlinkChildWidget(this); 00826 //mIWidgetCreator = _parent; 00827 if (mParent == nullptr) 00828 Gui::getInstance()._unlinkChildWidget(this); 00829 else 00830 mParent->_unlinkChildWidget(this); 00831 00832 mParent = _parent; 00833 mParent->_linkChildWidget(this); 00834 00835 mCroppedParent = nullptr; 00836 00837 if (!_layer.empty()) 00838 { 00839 LayerManager::getInstance().attachToLayerNode(_layer, this); 00840 } 00841 } 00842 else if (_style == WidgetStyle::Child) 00843 { 00844 LayerManager::getInstance().detachFromLayer(this); 00845 00846 //mIWidgetCreator->_unlinkChildWidget(this); 00847 //mIWidgetCreator = _parent; 00848 if (mParent == nullptr) 00849 Gui::getInstance()._unlinkChildWidget(this); 00850 else 00851 mParent->_unlinkChildWidget(this); 00852 00853 mParent = _parent; 00854 mParent->_linkChildWidget(this); 00855 00856 mCroppedParent = _parent; 00857 mAbsolutePosition = _parent->getAbsolutePosition() + mCoord.point(); 00858 00859 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) 00860 (*widget)->_updateAbsolutePoint(); 00861 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) 00862 (*widget)->_updateAbsolutePoint(); 00863 00864 mParent->addChildItem(this); 00865 00866 _updateView(); 00867 } 00868 else if (_style == WidgetStyle::Overlapped) 00869 { 00870 LayerManager::getInstance().detachFromLayer(this); 00871 00872 //mIWidgetCreator->_unlinkChildWidget(this); 00873 //mIWidgetCreator = _parent; 00874 if (mParent == nullptr) 00875 Gui::getInstance()._unlinkChildWidget(this); 00876 else 00877 mParent->_unlinkChildWidget(this); 00878 00879 mParent = _parent; 00880 mParent->_linkChildWidget(this); 00881 00882 mCroppedParent = _parent; 00883 mAbsolutePosition = _parent->getAbsolutePosition() + mCoord.point(); 00884 00885 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) 00886 (*widget)->_updateAbsolutePoint(); 00887 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) 00888 (*widget)->_updateAbsolutePoint(); 00889 00890 mParent->addChildNode(this); 00891 00892 _updateView(); 00893 } 00894 00895 _updateAlpha(); 00896 } 00897 00898 void Widget::setWidgetStyle(WidgetStyle _style, const std::string& _layer) 00899 { 00900 if (_style == mWidgetStyle) 00901 return; 00902 if (nullptr == getParent()) 00903 return; 00904 00905 Widget* parent = mParent; 00906 00907 detachFromWidget(); 00908 attachToWidget(parent, _style, _layer); 00909 // ищем леер к которому мы присоедененны 00910 } 00911 00912 Widget* Widget::createWidgetT(const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _name) 00913 { 00914 return baseCreateWidget(WidgetStyle::Child, _type, _skin, _coord, _align, "", _name, false); 00915 } 00916 00917 Widget* Widget::createWidgetT(const std::string& _type, const std::string& _skin, int _left, int _top, int _width, int _height, Align _align, const std::string& _name) 00918 { 00919 return createWidgetT(_type, _skin, IntCoord(_left, _top, _width, _height), _align, _name); 00920 } 00921 00922 Widget* Widget::createWidgetRealT(const std::string& _type, const std::string& _skin, float _left, float _top, float _width, float _height, Align _align, const std::string& _name) 00923 { 00924 return createWidgetRealT(_type, _skin, FloatCoord(_left, _top, _width, _height), _align, _name); 00925 } 00926 00927 Widget* Widget::createWidgetT(WidgetStyle _style, const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _layer, const std::string& _name) 00928 { 00929 return baseCreateWidget(_style, _type, _skin, _coord, _align, _layer, _name, false); 00930 } 00931 00932 EnumeratorWidgetPtr Widget::getEnumerator() const 00933 { 00934 MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget"); 00935 if (mWidgetClient != nullptr) 00936 return mWidgetClient->getEnumerator(); 00937 return Enumerator<VectorWidgetPtr>(mWidgetChild.begin(), mWidgetChild.end()); 00938 } 00939 00940 size_t Widget::getChildCount() 00941 { 00942 MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget"); 00943 if (mWidgetClient != nullptr) 00944 return mWidgetClient->getChildCount(); 00945 return mWidgetChild.size(); 00946 } 00947 00948 Widget* Widget::getChildAt(size_t _index) 00949 { 00950 MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget"); 00951 if (mWidgetClient != nullptr) 00952 return mWidgetClient->getChildAt(_index); 00953 MYGUI_ASSERT_RANGE(_index, mWidgetChild.size(), "Widget::getChildAt"); 00954 return mWidgetChild[_index]; 00955 } 00956 00957 void Widget::baseUpdateEnable() 00958 { 00959 if (mEnabled) 00960 _setWidgetState("normal"); 00961 else 00962 _setWidgetState("disabled"); 00963 } 00964 00965 void Widget::setVisible(bool _value) 00966 { 00967 if (mVisible == _value) 00968 return; 00969 mVisible = _value; 00970 00971 _updateVisible(); 00972 } 00973 00974 void Widget::_updateVisible() 00975 { 00976 mInheritsVisible = mParent == nullptr || (mParent->getVisible() && mParent->getInheritedVisible()); 00977 bool value = mVisible && mInheritsVisible; 00978 00979 _setSkinItemVisible(value); 00980 00981 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) 00982 (*widget)->_updateVisible(); 00983 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) 00984 (*widget)->_updateVisible(); 00985 00986 if (!value && InputManager::getInstance().getMouseFocusWidget() == this) 00987 InputManager::getInstance()._resetMouseFocusWidget(); 00988 } 00989 00990 void Widget::setEnabled(bool _value) 00991 { 00992 if (mEnabled == _value) 00993 return; 00994 mEnabled = _value; 00995 00996 _updateEnabled(); 00997 } 00998 00999 void Widget::_updateEnabled() 01000 { 01001 mInheritsEnabled = mParent == nullptr || (mParent->getEnabled() && mParent->getInheritedEnabled()); 01002 bool value = mEnabled && mInheritsEnabled; 01003 01004 for (VectorWidgetPtr::iterator iter = mWidgetChild.begin(); iter != mWidgetChild.end(); ++iter) 01005 (*iter)->_updateEnabled(); 01006 for (VectorWidgetPtr::iterator iter = mWidgetChildSkin.begin(); iter != mWidgetChildSkin.end(); ++iter) 01007 (*iter)->_updateEnabled(); 01008 01009 baseUpdateEnable(); 01010 01011 if (!value) 01012 InputManager::getInstance().unlinkWidget(this); 01013 } 01014 01015 void Widget::setColour(const Colour& _value) 01016 { 01017 _setSkinItemColour(_value); 01018 01019 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) 01020 (*widget)->setColour(_value); 01021 } 01022 01023 IntSize Widget::getParentSize() const 01024 { 01025 if (mCroppedParent) 01026 return static_cast<Widget*>(mCroppedParent)->getSize(); 01027 if (getLayer()) 01028 return getLayer()->getSize(); 01029 01030 return RenderManager::getInstance().getViewSize(); 01031 } 01032 01033 void Widget::_resetContainer(bool _updateOnly) 01034 { 01035 if (getNeedToolTip()) 01036 ToolTipManager::getInstance()._unlinkWidget(this); 01037 } 01038 01039 bool Widget::_checkPoint(int _left, int _top) const 01040 { 01041 return ! ((_getViewLeft() > _left) || (_getViewTop() > _top) || (_getViewRight() < _left) || (_getViewBottom() < _top)); 01042 } 01043 01044 void Widget::_linkChildWidget(Widget* _widget) 01045 { 01046 VectorWidgetPtr::iterator iter = std::find(mWidgetChild.begin(), mWidgetChild.end(), _widget); 01047 MYGUI_ASSERT(iter == mWidgetChild.end(), "widget already exist"); 01048 mWidgetChild.push_back(_widget); 01049 } 01050 01051 void Widget::_unlinkChildWidget(Widget* _widget) 01052 { 01053 VectorWidgetPtr::iterator iter = std::remove(mWidgetChild.begin(), mWidgetChild.end(), _widget); 01054 MYGUI_ASSERT(iter != mWidgetChild.end(), "widget not found"); 01055 mWidgetChild.erase(iter); 01056 } 01057 01058 void Widget::shutdownOverride() 01059 { 01060 } 01061 01062 void Widget::initialiseOverride() 01063 { 01064 } 01065 01066 void Widget::setSkinProperty(ResourceSkin* _info) 01067 { 01068 const MapString& properties = _info->getProperties(); 01069 for (MapString::const_iterator item = properties.begin(); item != properties.end(); ++item) 01070 setProperty((*item).first, (*item).second); 01071 } 01072 01073 void Widget::setProperty(const std::string& _key, const std::string& _value) 01074 { 01075 std::string key = _key; 01076 std::string value = _value; 01077 01078 if (BackwardCompatibility::checkProperty(this, key, value)) 01079 { 01080 size_t index = key.find("_"); 01081 if (index != std::string::npos) 01082 { 01083 MYGUI_LOG(Warning, "Widget property '" << key << "' have type prefix - use '" << key.substr(index + 1) << "' instead [" << LayoutManager::getInstance().getCurrentLayout() << "]"); 01084 key = key.substr(index + 1); 01085 } 01086 01087 setPropertyOverride(key, value); 01088 } 01089 } 01090 01091 VectorWidgetPtr Widget::getSkinWidgetsByName(const std::string& _name) 01092 { 01093 VectorWidgetPtr result; 01094 01095 for (VectorWidgetPtr::iterator iter = mWidgetChildSkin.begin(); iter != mWidgetChildSkin.end(); ++iter) 01096 (*iter)->findWidgets(_name, result); 01097 01098 return result; 01099 } 01100 01101 void Widget::findWidgets(const std::string& _name, VectorWidgetPtr& _result) 01102 { 01103 if (_name == mName) 01104 _result.push_back(this); 01105 01106 MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget"); 01107 if (mWidgetClient != nullptr) 01108 { 01109 mWidgetClient->findWidgets(_name, _result); 01110 } 01111 else 01112 { 01113 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) 01114 (*widget)->findWidgets(_name, _result); 01115 } 01116 } 01117 01118 void Widget::destroySkinWidget(Widget* _widget) 01119 { 01120 mWidgetChild.push_back(_widget); 01121 WidgetManager::getInstance().destroyWidget(_widget); 01122 } 01123 01124 void Widget::onWidgetCreated(Widget* _widget) 01125 { 01126 } 01127 01128 void Widget::onWidgetDestroy(Widget* _widget) 01129 { 01130 } 01131 01132 void Widget::setWidgetClient(Widget* _widget) 01133 { 01134 mWidgetClient = _widget; 01135 } 01136 01137 Widget* Widget::_createSkinWidget(WidgetStyle _style, const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _layer, const std::string& _name) 01138 { 01139 return baseCreateWidget(_style, _type, _skin, _coord, _align, _layer, _name, true); 01140 } 01141 01142 void Widget::setPropertyOverride(const std::string& _key, const std::string& _value) 01143 { 01145 if (_key == "Position") 01146 setPosition(utility::parseValue<IntPoint>(_value)); 01148 else if (_key == "Size") 01149 setSize(utility::parseValue<IntSize>(_value)); 01151 else if (_key == "Coord") 01152 setCoord(utility::parseValue<IntCoord>(_value)); 01154 else if (_key == "Visible") 01155 setVisible(utility::parseValue<bool>(_value)); 01156 else if (_key == "Alpha") 01157 setAlpha(utility::parseValue<float>(_value)); 01158 else if (_key == "Colour") 01159 setColour(utility::parseValue<Colour>(_value)); 01160 else if (_key == "InheritsAlpha") 01161 setInheritsAlpha(utility::parseValue<bool>(_value)); 01162 else if (_key == "InheritsPick") 01163 setInheritsPick(utility::parseValue<bool>(_value)); 01164 else if (_key == "MaskPick") 01165 setMaskPick(_value); 01166 else if (_key == "NeedKey") 01167 setNeedKeyFocus(utility::parseValue<bool>(_value)); 01168 else if (_key == "NeedMouse") 01169 setNeedMouseFocus(utility::parseValue<bool>(_value)); 01170 else if (_key == "Enabled") 01171 setEnabled(utility::parseValue<bool>(_value)); 01172 else if (_key == "NeedToolTip") 01173 setNeedToolTip(utility::parseValue<bool>(_value)); 01174 else if (_key == "Pointer") 01175 setPointer(_value); 01176 else 01177 { 01178 MYGUI_LOG(Warning, "Widget property '" << _key << "' not found" << " [" << LayoutManager::getInstance().getCurrentLayout() << "]"); 01179 return; 01180 } 01181 01182 eventChangeProperty(this, _key, _value); 01183 } 01184 01185 void Widget::setPosition(int _left, int _top) 01186 { 01187 setPosition(IntPoint(_left, _top)); 01188 } 01189 01190 void Widget::setSize(int _width, int _height) 01191 { 01192 setSize(IntSize(_width, _height)); 01193 } 01194 01195 void Widget::setCoord(int _left, int _top, int _width, int _height) 01196 { 01197 setCoord(IntCoord(_left, _top, _width, _height)); 01198 } 01199 01200 void Widget::setRealPosition(float _left, float _top) 01201 { 01202 setRealPosition(FloatPoint(_left, _top)); 01203 } 01204 01205 void Widget::setRealSize(float _width, float _height) 01206 { 01207 setRealSize(FloatSize(_width, _height)); 01208 } 01209 01210 void Widget::setRealCoord(float _left, float _top, float _width, float _height) 01211 { 01212 setRealCoord(FloatCoord(_left, _top, _width, _height)); 01213 } 01214 01215 const std::string& Widget::getName() const 01216 { 01217 return mName; 01218 } 01219 01220 bool Widget::getVisible() const 01221 { 01222 return mVisible; 01223 } 01224 01225 Align Widget::getAlign() const 01226 { 01227 return mAlign; 01228 } 01229 01230 float Widget::getAlpha() const 01231 { 01232 return mAlpha; 01233 } 01234 01235 bool Widget::getInheritsAlpha() const 01236 { 01237 return mInheritsAlpha; 01238 } 01239 01240 bool Widget::isRootWidget() const 01241 { 01242 return nullptr == mCroppedParent; 01243 } 01244 01245 Widget* Widget::getParent() const 01246 { 01247 return mParent; 01248 } 01249 01250 void Widget::setEnabledSilent(bool _value) 01251 { 01252 mEnabled = _value; 01253 } 01254 01255 bool Widget::getEnabled() const 01256 { 01257 return mEnabled; 01258 } 01259 01260 Widget* Widget::getClientWidget() 01261 { 01262 return mWidgetClient; 01263 } 01264 01265 WidgetStyle Widget::getWidgetStyle() const 01266 { 01267 return mWidgetStyle; 01268 } 01269 01270 size_t Widget::_getItemIndex(Widget* _item) 01271 { 01272 return ITEM_NONE; 01273 } 01274 01275 void Widget::_setContainer(Widget* _value) 01276 { 01277 mContainer = _value; 01278 } 01279 01280 Widget* Widget::_getContainer() 01281 { 01282 return mContainer; 01283 } 01284 01285 size_t Widget::_getContainerIndex(const IntPoint& _point) 01286 { 01287 return ITEM_NONE; 01288 } 01289 01290 const IntCoord& Widget::getLayerItemCoord() const 01291 { 01292 return mCoord; 01293 } 01294 01295 float Widget::_getRealAlpha() const 01296 { 01297 return mRealAlpha; 01298 } 01299 01300 bool Widget::getInheritedEnabled() const 01301 { 01302 return mInheritsEnabled; 01303 } 01304 01305 bool Widget::getInheritedVisible() const 01306 { 01307 return mInheritsVisible; 01308 } 01309 01310 void Widget::resizeLayerItemView(const IntSize& _oldView, const IntSize& _newView) 01311 { 01312 _setAlign(_oldView, _newView); 01313 } 01314 01315 } // namespace MyGUI