MyGUI
3.0.1
|
00001 00007 /* 00008 This file is part of MyGUI. 00009 00010 MyGUI is free software: you can redistribute it and/or modify 00011 it under the terms of the GNU Lesser General Public License as published by 00012 the Free Software Foundation, either version 3 of the License, or 00013 (at your option) any later version. 00014 00015 MyGUI is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 GNU Lesser General Public License for more details. 00019 00020 You should have received a copy of the GNU Lesser General Public License 00021 along with MyGUI. If not, see <http://www.gnu.org/licenses/>. 00022 */ 00023 #include "MyGUI_Precompiled.h" 00024 #include "MyGUI_Gui.h" 00025 #include "MyGUI_Widget.h" 00026 #include "MyGUI_InputManager.h" 00027 #include "MyGUI_SkinManager.h" 00028 #include "MyGUI_SubWidgetManager.h" 00029 #include "MyGUI_WidgetManager.h" 00030 #include "MyGUI_ResourceSkin.h" 00031 #include "MyGUI_WidgetDefines.h" 00032 #include "MyGUI_LayerItem.h" 00033 #include "MyGUI_LayerManager.h" 00034 #include "MyGUI_RenderItem.h" 00035 #include "MyGUI_ISubWidget.h" 00036 #include "MyGUI_ISubWidgetText.h" 00037 #include "MyGUI_StaticText.h" 00038 #include "MyGUI_FactoryManager.h" 00039 #include "MyGUI_LanguageManager.h" 00040 #include "MyGUI_CoordConverter.h" 00041 #include "MyGUI_RenderManager.h" 00042 00043 namespace MyGUI 00044 { 00045 00046 const float WIDGET_TOOLTIP_TIMEOUT = 0.5f; 00047 00048 Widget::Widget(WidgetStyle _style, const IntCoord& _coord, Align _align, ResourceSkin* _info, Widget* _parent, ICroppedRectangle * _croppedParent, IWidgetCreator * _creator, const std::string& _name) : 00049 mMaskPickInfo(nullptr), 00050 mText(nullptr), 00051 mMainSkin(nullptr), 00052 mEnabled(true), 00053 mInheritsEnabled(true), 00054 mSubSkinsVisible(true), 00055 mInheritsVisible(true), 00056 mAlpha(ALPHA_MIN), 00057 mRealAlpha(ALPHA_MIN), 00058 mInheritsAlpha(true), 00059 mTexture(nullptr), 00060 mParent(nullptr), 00061 mIWidgetCreator(nullptr), 00062 mNeedKeyFocus(false), 00063 mNeedMouseFocus(true), 00064 mInheritsPick(false), 00065 mWidgetClient(nullptr), 00066 mNeedToolTip(false), 00067 mEnableToolTip(true), 00068 mToolTipVisible(false), 00069 mToolTipCurrentTime(0), 00070 mToolTipOldIndex(ITEM_NONE), 00071 mWidgetStyle(WidgetStyle::Child), 00072 mDisableUpdateRelative(false) 00073 { 00074 _initialise(_style, _coord, _align, _info, _parent, _croppedParent, _creator, _name); 00075 } 00076 00077 Widget::Widget() : 00078 mMaskPickInfo(nullptr), 00079 mText(nullptr), 00080 mMainSkin(nullptr), 00081 mEnabled(true), 00082 mInheritsEnabled(true), 00083 mSubSkinsVisible(true), 00084 mInheritsVisible(true), 00085 mAlpha(ALPHA_MIN), 00086 mRealAlpha(ALPHA_MIN), 00087 mInheritsAlpha(true), 00088 mTexture(nullptr), 00089 mParent(nullptr), 00090 mIWidgetCreator(nullptr), 00091 mNeedKeyFocus(false), 00092 mNeedMouseFocus(true), 00093 mInheritsPick(false), 00094 mWidgetClient(nullptr), 00095 mNeedToolTip(false), 00096 mEnableToolTip(true), 00097 mToolTipVisible(false), 00098 mToolTipCurrentTime(0), 00099 mToolTipOldIndex(ITEM_NONE), 00100 mWidgetStyle(WidgetStyle::Child), 00101 mDisableUpdateRelative(false) 00102 { 00103 } 00104 00105 void Widget::_initialise(WidgetStyle _style, const IntCoord& _coord, Align _align, ResourceSkin* _info, Widget* _parent, ICroppedRectangle * _croppedParent, IWidgetCreator * _creator, const std::string& _name) 00106 { 00107 mCoord = IntCoord(_coord.point(), _info->getSize()); 00108 mStateInfo = _info->getStateInfo(); 00109 mMaskPickInfo = _info->getMask(); 00110 00111 mTextureName = _info->getTextureName(); 00112 mTexture = RenderManager::getInstance().getTexture(mTextureName); 00113 00114 mAlign = _align; 00115 mCroppedParent = _croppedParent; 00116 00117 mName = _name; 00118 mParent = _parent; 00119 mIWidgetCreator = _creator; 00120 00121 mWidgetStyle = _style; 00122 00123 // имя отсылателя сообщений 00124 mWidgetEventSender = this; 00125 00126 #if MYGUI_DEBUG_MODE == 1 00127 // проверяем соответсвие входных данных 00128 if (mWidgetStyle == WidgetStyle::Child) 00129 { 00130 MYGUI_ASSERT(mCroppedParent, "must be cropped"); 00131 MYGUI_ASSERT(mParent, "must be parent"); 00132 } 00133 else if (mWidgetStyle == WidgetStyle::Overlapped) 00134 { 00135 MYGUI_ASSERT((mParent == nullptr) == (mCroppedParent == nullptr), "error cropped"); 00136 } 00137 else if (mWidgetStyle == WidgetStyle::Popup) 00138 { 00139 MYGUI_ASSERT(!mCroppedParent, "cropped must be nullptr"); 00140 MYGUI_ASSERT(mParent, "must be parent"); 00141 } 00142 #endif 00143 00144 // корректируем абсолютные координаты 00145 mAbsolutePosition = _coord.point(); 00146 00147 if (nullptr != mCroppedParent) 00148 { 00149 mAbsolutePosition += mCroppedParent->getAbsolutePosition(); 00150 } 00151 00152 const IntSize& parent_size = mCroppedParent ? mCroppedParent->getSize() : Gui::getInstance().getViewSize(); 00153 00154 if (parent_size.width) 00155 { 00156 mRelativeCoord.left = (float)_coord.left / (float)parent_size.width; 00157 mRelativeCoord.width = (float)_coord.width / (float)parent_size.width; 00158 } 00159 else 00160 { 00161 mRelativeCoord.left = 0; 00162 mRelativeCoord.width = 0; 00163 } 00164 00165 if (parent_size.height) 00166 { 00167 mRelativeCoord.top = (float)_coord.top / (float)parent_size.height; 00168 mRelativeCoord.height = (float)_coord.height / (float)parent_size.height; 00169 } 00170 else 00171 { 00172 mRelativeCoord.top = 0; 00173 mRelativeCoord.height = 0; 00174 } 00175 00176 initialiseWidgetSkin(_info, _coord.size()); 00177 00178 // дочернее окно обыкновенное 00179 if (mWidgetStyle == WidgetStyle::Child) 00180 { 00181 if (mParent) mParent->addChildItem(this); 00182 } 00183 // дочернее нуно перекрывающееся 00184 else if (mWidgetStyle == WidgetStyle::Overlapped) 00185 { 00186 // дочернее перекрывающееся 00187 if (mParent) mParent->addChildNode(this); 00188 } 00189 } 00190 00191 Widget::~Widget() 00192 { 00193 Gui::getInstance().eventFrameStart -= newDelegate(this, &Widget::frameEntered); 00194 00195 if (mToolTipVisible) eventToolTip(this, ToolTipInfo(ToolTipInfo::Hide)); 00196 00197 shutdownWidgetSkin(true); 00198 00199 _destroyAllChildWidget(); 00200 00201 // дочернее окно обыкновенное 00202 if (mWidgetStyle == WidgetStyle::Child) 00203 { 00204 if (mParent) mParent->removeChildItem(this); 00205 } 00206 // дочернее нуно перекрывающееся 00207 else if (mWidgetStyle == WidgetStyle::Overlapped) 00208 { 00209 // дочернее перекрывающееся 00210 if (mParent) mParent->removeChildNode(this); 00211 } 00212 } 00213 00214 void Widget::changeWidgetSkin(const std::string& _skinname) 00215 { 00216 ResourceSkin* skin_info = SkinManager::getInstance().getByName(_skinname); 00217 baseChangeWidgetSkin(skin_info); 00218 } 00219 00220 void Widget::baseChangeWidgetSkin(ResourceSkin* _info) 00221 { 00222 IntSize size = mCoord.size(); 00223 00224 saveLayerItem(); 00225 00226 shutdownWidgetSkin(); 00227 initialiseWidgetSkin(_info, size); 00228 00229 restoreLayerItem(); 00230 } 00231 00232 void Widget::initialiseWidgetSkin(ResourceSkin* _info, const IntSize& _size) 00233 { 00234 FactoryManager& factory = FactoryManager::getInstance(); 00235 00236 mTextureName = _info->getTextureName(); 00237 mTexture = RenderManager::getInstance().getTexture(mTextureName); 00238 00239 setRenderItemTexture(mTexture); 00240 mStateInfo = _info->getStateInfo(); 00241 Widget::setSize(_info->getSize()); 00242 00243 // загружаем кирпичики виджета 00244 for (VectorSubWidgetInfo::const_iterator iter=_info->getBasisInfo().begin(); iter!=_info->getBasisInfo().end(); ++iter) 00245 { 00246 IObject* object = factory.createObject("BasisSkin", (*iter).type); 00247 if (object == nullptr) continue; 00248 00249 ISubWidget* sub = object->castType<ISubWidget>(); 00250 sub->_setCroppedParent(this); 00251 sub->setCoord((*iter).coord); 00252 sub->setAlign((*iter).align); 00253 00254 mSubSkinChild.push_back(sub); 00255 addRenderItem(sub); 00256 00257 // ищем дефолтные сабвиджеты 00258 if (mMainSkin == nullptr) mMainSkin = sub->castType<ISubWidgetRect>(false); 00259 if (mText == nullptr) mText = sub->castType<ISubWidgetText>(false); 00260 } 00261 00262 if (!isRootWidget()) 00263 { 00264 // проверяем наследуемую скрытость 00265 if ((!mParent->isVisible()) || (!mParent->_isInheritsVisible())) 00266 { 00267 bool value = false; 00268 mInheritsVisible = value; 00269 for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin) 00270 (*skin)->setVisible(value); 00271 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) 00272 (*widget)->_setInheritsVisible(value); 00273 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) 00274 (*widget)->_setInheritsVisible(value); 00275 } 00276 // проверяем наследуемый дизейбл 00277 if ((!mParent->isEnabled()) || (!mParent->_isInheritsEnable())) 00278 { 00279 bool value = false; 00280 mInheritsEnabled = false; 00281 for (VectorWidgetPtr::iterator iter = mWidgetChild.begin(); iter != mWidgetChild.end(); ++iter) 00282 (*iter)->_setInheritsEnable(value); 00283 for (VectorWidgetPtr::iterator iter = mWidgetChildSkin.begin(); iter != mWidgetChildSkin.end(); ++iter) 00284 (*iter)->_setInheritsEnable(value); 00285 } 00286 } 00287 00288 Widget::setState("normal");//FIXME - явный вызов 00289 00290 // парсим свойства 00291 const MapString& properties = _info->getProperties(); 00292 if (!properties.empty()) 00293 { 00294 MapString::const_iterator iter = properties.end(); 00295 if ((iter = properties.find("NeedKey")) != properties.end()) setNeedKeyFocus(utility::parseBool(iter->second)); 00296 if ((iter = properties.find("NeedMouse")) != properties.end()) setNeedMouseFocus(utility::parseBool(iter->second)); 00297 if ((iter = properties.find("Pointer")) != properties.end()) mPointer = iter->second; 00298 if ((iter = properties.find("Visible")) != properties.end()) { setVisible(utility::parseBool(iter->second)); } 00299 00300 // OBSOLETE 00301 if ((iter = properties.find("AlignText")) != properties.end()) _setTextAlign(Align::parse(iter->second)); 00302 if ((iter = properties.find("Colour")) != properties.end()) _setTextColour(Colour::parse(iter->second)); 00303 if ((iter = properties.find("Show")) != properties.end()) { setVisible(utility::parseBool(iter->second)); } 00304 if ((iter = properties.find("TextAlign")) != properties.end()) _setTextAlign(Align::parse(iter->second)); 00305 if ((iter = properties.find("TextColour")) != properties.end()) _setTextColour(Colour::parse(iter->second)); 00306 if ((iter = properties.find("FontName")) != properties.end()) _setFontName(iter->second); 00307 if ((iter = properties.find("FontHeight")) != properties.end()) _setFontHeight(utility::parseInt(iter->second)); 00308 } 00309 00310 // выставляем альфу, корректировка по отцу автоматически 00311 Widget::setAlpha(ALPHA_MAX);//FIXME - явный вызов 00312 00313 // создаем детей скина 00314 const VectorChildSkinInfo& child = _info->getChild(); 00315 for (VectorChildSkinInfo::const_iterator iter=child.begin(); iter!=child.end(); ++iter) 00316 { 00317 //FIXME - явный вызов 00318 Widget* widget = Widget::baseCreateWidget(iter->style, iter->type, iter->skin, iter->coord, iter->align, iter->layer, ""); 00319 widget->_setInternalData(iter->name); 00320 // заполняем UserString пропертями 00321 for (MapString::const_iterator prop=iter->params.begin(); prop!=iter->params.end(); ++prop) 00322 { 00323 widget->setUserString(prop->first, prop->second); 00324 } 00325 // для детей скина свой список 00326 mWidgetChildSkin.push_back(widget); 00327 mWidgetChild.pop_back(); 00328 } 00329 00330 Widget::setSize(_size);//FIXME - явный вызов 00331 } 00332 00333 void Widget::shutdownWidgetSkin(bool _deep) 00334 { 00335 // удаляем все сабскины 00336 mMainSkin = nullptr; 00337 mText = nullptr; 00338 00339 removeAllRenderItems(); 00340 00341 for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin) 00342 { 00343 delete (*skin); 00344 } 00345 mSubSkinChild.clear(); 00346 00347 mStateInfo.clear(); 00348 00349 // удаляем виджеты чтобы ли в скине 00350 for (VectorWidgetPtr::iterator iter=mWidgetChildSkin.begin(); iter!=mWidgetChildSkin.end(); ++iter) 00351 { 00352 // Добавляем себя чтобы удалилось 00353 mWidgetChild.push_back(*iter); 00354 _destroyChildWidget(*iter); 00355 } 00356 mWidgetChildSkin.clear(); 00357 } 00358 00359 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) 00360 { 00361 Widget* widget = WidgetManager::getInstance().createWidget(_style, _type, _skin, _coord, _align, this, 00362 _style == WidgetStyle::Popup ? nullptr : this, this, _name); 00363 00364 mWidgetChild.push_back(widget); 00365 00366 // присоединяем виджет с уровню 00367 if (!_layer.empty() && widget->isRootWidget()) LayerManager::getInstance().attachToLayerNode(_layer, widget); 00368 00369 return widget; 00370 } 00371 00372 Widget* Widget::createWidgetRealT(const std::string& _type, const std::string& _skin, const FloatCoord& _coord, Align _align, const std::string& _name) 00373 { 00374 return createWidgetT(_type, _skin, CoordConverter::convertFromRelative(_coord, getSize()), _align, _name); 00375 } 00376 00377 void Widget::_updateView() 00378 { 00379 00380 bool margin = mCroppedParent ? _checkMargin() : false; 00381 00382 // вьюпорт стал битым 00383 if (margin) 00384 { 00385 // проверка на полный выход за границу 00386 if (_checkOutside()) 00387 { 00388 // запоминаем текущее состояние 00389 mIsMargin = margin; 00390 00391 // скрываем 00392 _setSubSkinVisible(false); 00393 00394 // для тех кому нужно подправить себя при движении 00395 //for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin) (*skin)->_updateView(); 00396 00397 // вся иерархия должна быть проверенна 00398 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateView(); 00399 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateView(); 00400 00401 return; 00402 } 00403 00404 } 00405 // мы не обрезаны и были нормальные 00406 else if (!mIsMargin) 00407 { 00408 // запоминаем текущее состояние 00409 //mIsMargin = margin; 00410 00411 //_setSubSkinVisible(true); 00412 // для тех кому нужно подправить себя при движении 00413 for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin) (*skin)->_updateView(); 00414 00415 return; 00416 } 00417 00418 // запоминаем текущее состояние 00419 mIsMargin = margin; 00420 00421 // если скин был скрыт, то покажем 00422 _setSubSkinVisible(true); 00423 00424 // обновляем наших детей, а они уже решат обновлять ли своих детей 00425 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateView(); 00426 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateView(); 00427 for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin) (*skin)->_updateView(); 00428 00429 } 00430 00431 void Widget::setCaption(const UString& _caption) 00432 { 00433 if (nullptr != mText) mText->setCaption(_caption); 00434 } 00435 00436 const UString& Widget::getCaption() 00437 { 00438 if (nullptr == mText) 00439 { 00440 static UString empty; 00441 return empty; 00442 } 00443 return mText->getCaption(); 00444 } 00445 00446 bool Widget::setState(const std::string& _state) 00447 { 00448 MapWidgetStateInfo::const_iterator iter = mStateInfo.find(_state); 00449 if (iter == mStateInfo.end()) return false; 00450 size_t index=0; 00451 for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin, ++index) 00452 { 00453 IStateInfo* data = (*iter).second[index]; 00454 if (data != nullptr) 00455 { 00456 (*skin)->setStateData(data); 00457 } 00458 } 00459 return true; 00460 } 00461 00462 void Widget::_destroyChildWidget(Widget* _widget) 00463 { 00464 MYGUI_ASSERT(nullptr != _widget, "invalid widget pointer"); 00465 00466 VectorWidgetPtr::iterator iter = std::find(mWidgetChild.begin(), mWidgetChild.end(), _widget); 00467 if (iter != mWidgetChild.end()) 00468 { 00469 00470 // сохраняем указатель 00471 MyGUI::Widget* widget = *iter; 00472 00473 // удаляем из списка 00474 *iter = mWidgetChild.back(); 00475 mWidgetChild.pop_back(); 00476 00477 // отписываем от всех 00478 WidgetManager::getInstance().unlinkFromUnlinkers(_widget); 00479 00480 // непосредственное удаление 00481 _deleteWidget(widget); 00482 } 00483 else 00484 { 00485 MYGUI_EXCEPT("Widget '" << _widget->getName() << "' not found"); 00486 } 00487 } 00488 00489 // удаляет всех детей 00490 void Widget::_destroyAllChildWidget() 00491 { 00492 WidgetManager& manager = WidgetManager::getInstance(); 00493 while (!mWidgetChild.empty()) 00494 { 00495 00496 // сразу себя отписывем, иначе вложенной удаление убивает все 00497 Widget* widget = mWidgetChild.back(); 00498 mWidgetChild.pop_back(); 00499 00500 //if (widget->isRootWidget()) widget->detachWidget(); 00501 00502 // отписываем от всех 00503 manager.unlinkFromUnlinkers(widget); 00504 00505 // и сами удалим, так как его больше в списке нет 00506 delete widget; 00507 } 00508 } 00509 00510 IntCoord Widget::getClientCoord() 00511 { 00512 MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget"); 00513 if (mWidgetClient != nullptr) return mWidgetClient->getCoord(); 00514 return IntCoord(0, 0, mCoord.width, mCoord.height); 00515 } 00516 00517 void Widget::setAlpha(float _alpha) 00518 { 00519 if (mAlpha == _alpha) return; 00520 mAlpha = _alpha; 00521 if (nullptr != mParent) mRealAlpha = mAlpha * (mInheritsAlpha ? mParent->_getRealAlpha() : ALPHA_MAX); 00522 else mRealAlpha = mAlpha; 00523 00524 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateAlpha(); 00525 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateAlpha(); 00526 for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin) (*skin)->setAlpha(mRealAlpha); 00527 } 00528 00529 void Widget::_updateAlpha() 00530 { 00531 MYGUI_DEBUG_ASSERT(nullptr != mParent, "Widget must have parent"); 00532 mRealAlpha = mAlpha * (mInheritsAlpha ? mParent->_getRealAlpha() : ALPHA_MAX); 00533 00534 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateAlpha(); 00535 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateAlpha(); 00536 for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin) (*skin)->setAlpha(mRealAlpha); 00537 } 00538 00539 void Widget::setInheritsAlpha(bool _inherits) 00540 { 00541 mInheritsAlpha = _inherits; 00542 // принудительно обновляем 00543 float alpha = mAlpha; 00544 mAlpha = 101; 00545 setAlpha(alpha); 00546 } 00547 00548 ILayerItem * Widget::getLayerItemByPoint(int _left, int _top) 00549 { 00550 // проверяем попадание 00551 if (!mSubSkinsVisible 00552 || !mEnabled 00553 || !mVisible 00554 || (!mNeedMouseFocus && !mInheritsPick) 00555 || !_checkPoint(_left, _top) 00556 // если есть маска, проверяем еще и по маске 00557 || ((!mMaskPickInfo->empty()) && (!mMaskPickInfo->pick(IntPoint(_left - mCoord.left, _top - mCoord.top), mCoord)))) 00558 return nullptr; 00559 // спрашиваем у детишек 00560 for (VectorWidgetPtr::reverse_iterator widget= mWidgetChild.rbegin(); widget != mWidgetChild.rend(); ++widget) 00561 { 00562 // общаемся только с послушными детьми 00563 if ((*widget)->mWidgetStyle == WidgetStyle::Popup) continue; 00564 00565 ILayerItem * item = (*widget)->getLayerItemByPoint(_left - mCoord.left, _top - mCoord.top); 00566 if (item != nullptr) return item; 00567 } 00568 // спрашиваем у детишек скна 00569 for (VectorWidgetPtr::reverse_iterator widget= mWidgetChildSkin.rbegin(); widget != mWidgetChildSkin.rend(); ++widget) 00570 { 00571 ILayerItem * item = (*widget)->getLayerItemByPoint(_left - mCoord.left, _top - mCoord.top); 00572 if (item != nullptr) return item; 00573 } 00574 // непослушные дети 00575 return mInheritsPick ? nullptr : this; 00576 } 00577 00578 void Widget::_updateAbsolutePoint() 00579 { 00580 // мы рут, нам не надо 00581 if (!mCroppedParent) return; 00582 00583 mAbsolutePosition = mCroppedParent->getAbsolutePosition() + mCoord.point(); 00584 00585 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateAbsolutePoint(); 00586 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateAbsolutePoint(); 00587 for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin) (*skin)->_correctView(); 00588 } 00589 00590 void Widget::_setUVSet(const FloatRect& _rect) 00591 { 00592 if (nullptr != mMainSkin) mMainSkin->_setUVSet(_rect); 00593 } 00594 00595 void Widget::_setTextureName(const std::string& _texture) 00596 { 00597 //if (_texture == mTextureName) return; 00598 00599 mTextureName = _texture; 00600 mTexture = RenderManager::getInstance().getTexture(mTextureName); 00601 00602 setRenderItemTexture(mTexture); 00603 } 00604 00605 const std::string& Widget::_getTextureName() 00606 { 00607 return mTextureName; 00608 } 00609 00610 void Widget::_setSubSkinVisible(bool _visible) 00611 { 00612 if (mSubSkinsVisible == _visible) return; 00613 mSubSkinsVisible = _visible; 00614 00615 // просто обновляем 00616 for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin) 00617 { 00618 (*skin)->_updateView(); 00619 } 00620 } 00621 00622 void Widget::_forcePeek(Widget* _widget) 00623 { 00624 MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget"); 00625 if (mWidgetClient != nullptr) mWidgetClient->_forcePeek(_widget); 00626 00627 size_t size = mWidgetChild.size(); 00628 if ( (size < 2) || (mWidgetChild[size-1] == _widget) ) return; 00629 for (size_t pos=0; pos<size; pos++) 00630 { 00631 if (mWidgetChild[pos] == _widget) 00632 { 00633 mWidgetChild[pos] = mWidgetChild[size-1]; 00634 mWidgetChild[size-1] = _widget; 00635 return; 00636 } 00637 } 00638 } 00639 00640 const std::string& Widget::getLayerName() 00641 { 00642 ILayer* layer = getLayer(); 00643 if (nullptr == layer) 00644 { 00645 static std::string empty; 00646 return empty; 00647 } 00648 return layer->getName(); 00649 } 00650 00651 void Widget::_getContainer(Widget*& _list, size_t& _index) 00652 { 00653 _list = nullptr; 00654 _index = ITEM_NONE; 00655 _requestGetContainer(this, _list, _index); 00656 } 00657 00658 Widget* Widget::findWidget(const std::string& _name) 00659 { 00660 if (_name == mName) return this; 00661 MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget"); 00662 if (mWidgetClient != nullptr) return mWidgetClient->findWidget(_name); 00663 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) 00664 { 00665 Widget* find = (*widget)->findWidget(_name); 00666 if (nullptr != find) return find; 00667 } 00668 return nullptr; 00669 } 00670 00671 void Widget::setNeedToolTip(bool _need) 00672 { 00673 if (mNeedToolTip == _need) return; 00674 mNeedToolTip = _need; 00675 00676 if (mNeedToolTip) 00677 { 00678 Gui::getInstance().eventFrameStart += newDelegate(this, &Widget::frameEntered); 00679 mToolTipCurrentTime = 0; 00680 } 00681 else 00682 { 00683 Gui::getInstance().eventFrameStart -= newDelegate(this, &Widget::frameEntered); 00684 } 00685 } 00686 00687 void Widget::frameEntered(float _frame) 00688 { 00689 if ( ! mEnableToolTip ) return; 00690 00691 IntPoint point = InputManager::getInstance().getMousePositionByLayer(); 00692 00693 if (mToolTipOldPoint != point) 00694 { 00695 00696 mToolTipCurrentTime = 0; 00697 00698 bool inside = getAbsoluteRect().inside(point); 00699 if (inside) 00700 { 00701 inside = false; 00702 // проверяем не перекрывают ли нас 00703 Widget* widget = InputManager::getInstance().getMouseFocusWidget(); 00704 while (widget != 0) 00705 { 00706 if (widget/*->getName()*/ == this/*mName*/) 00707 { 00708 inside = true; 00709 break; 00710 } 00711 // если виджет берет тултип, значит сбрасываем 00712 if (widget->getNeedToolTip()) 00713 widget = 0;//widget->getParent(); 00714 else 00715 widget = widget->getParent(); 00716 } 00717 00718 if (inside) 00719 { 00720 // теперь смотрим, не поменялся ли индекс внутри окна 00721 size_t index = _getContainerIndex(point); 00722 if (mToolTipOldIndex != index) 00723 { 00724 if (mToolTipVisible) 00725 { 00726 mToolTipCurrentTime = 0; 00727 mToolTipVisible = false; 00728 eventToolTip(this, ToolTipInfo(ToolTipInfo::Hide)); 00729 } 00730 mToolTipOldIndex = index; 00731 } 00732 00733 } 00734 else 00735 { 00736 if (mToolTipVisible) 00737 { 00738 mToolTipCurrentTime = 0; 00739 mToolTipVisible = false; 00740 eventToolTip(this, ToolTipInfo(ToolTipInfo::Hide)); 00741 } 00742 } 00743 00744 } 00745 else 00746 { 00747 if (mToolTipVisible) 00748 { 00749 mToolTipCurrentTime = 0; 00750 mToolTipVisible = false; 00751 eventToolTip(this, ToolTipInfo(ToolTipInfo::Hide)); 00752 } 00753 } 00754 00755 mToolTipOldPoint = point; 00756 } 00757 else 00758 { 00759 bool inside = getAbsoluteRect().inside(point); 00760 if (inside) 00761 { 00762 inside = false; 00763 // проверяем не перекрывают ли нас 00764 Widget* widget = InputManager::getInstance().getMouseFocusWidget(); 00765 while (widget != 0) 00766 { 00767 if (widget/*->getName()*/ == this/*mName*/) 00768 { 00769 inside = true; 00770 break; 00771 } 00772 // если виджет берет тултип, значит сбрасываем 00773 if (widget->getNeedToolTip()) 00774 widget = 0;//widget->getParent(); 00775 else 00776 widget = widget->getParent(); 00777 } 00778 00779 if (inside) 00780 { 00781 if ( ! mToolTipVisible) 00782 { 00783 mToolTipCurrentTime += _frame; 00784 if (mToolTipCurrentTime > WIDGET_TOOLTIP_TIMEOUT) 00785 { 00786 mToolTipVisible = true; 00787 eventToolTip(this, ToolTipInfo(ToolTipInfo::Show, mToolTipOldIndex, point)); 00788 } 00789 } 00790 } 00791 } 00792 } 00793 } 00794 00795 void Widget::setEnableToolTip(bool _enable) 00796 { 00797 if (_enable == mEnableToolTip) return; 00798 mEnableToolTip = _enable; 00799 00800 if ( ! mEnableToolTip) 00801 { 00802 if (mToolTipVisible) 00803 { 00804 mToolTipCurrentTime = 0; 00805 mToolTipVisible = false; 00806 eventToolTip(this, ToolTipInfo(ToolTipInfo::Hide)); 00807 } 00808 } 00809 else 00810 { 00811 mToolTipCurrentTime = 0; 00812 } 00813 } 00814 00815 void Widget::_resetContainer(bool _updateOnly) 00816 { 00817 if ( mEnableToolTip) 00818 { 00819 if (mToolTipVisible) 00820 { 00821 mToolTipVisible = false; 00822 eventToolTip(this, ToolTipInfo(ToolTipInfo::Hide)); 00823 } 00824 mToolTipCurrentTime = 0; 00825 mToolTipOldIndex = ITEM_NONE; 00826 } 00827 } 00828 00829 void Widget::setMaskPick(const std::string& _filename) 00830 { 00831 if (mOwnMaskPickInfo.load(_filename)) 00832 { 00833 mMaskPickInfo = &mOwnMaskPickInfo; 00834 } 00835 else 00836 { 00837 MYGUI_LOG(Error, "mask not load '" << _filename << "'"); 00838 } 00839 } 00840 00841 void Widget::setRealPosition(const FloatPoint& _point) 00842 { 00843 setPosition(CoordConverter::convertFromRelative(_point, mCroppedParent == nullptr ? Gui::getInstance().getViewSize() : mCroppedParent->getSize())); 00844 } 00845 00846 void Widget::setRealSize(const FloatSize& _size) 00847 { 00848 setSize(CoordConverter::convertFromRelative(_size, mCroppedParent == nullptr ? Gui::getInstance().getViewSize() : mCroppedParent->getSize())); 00849 } 00850 00851 void Widget::setRealCoord(const FloatCoord& _coord) 00852 { 00853 setCoord(CoordConverter::convertFromRelative(_coord, mCroppedParent == nullptr ? Gui::getInstance().getViewSize() : mCroppedParent->getSize())); 00854 } 00855 00856 void Widget::_linkChildWidget(Widget* _widget) 00857 { 00858 VectorWidgetPtr::iterator iter = std::find(mWidgetChild.begin(), mWidgetChild.end(), _widget); 00859 MYGUI_ASSERT(iter == mWidgetChild.end(), "widget already exist"); 00860 mWidgetChild.push_back(_widget); 00861 } 00862 00863 void Widget::_unlinkChildWidget(Widget* _widget) 00864 { 00865 VectorWidgetPtr::iterator iter = std::remove(mWidgetChild.begin(), mWidgetChild.end(), _widget); 00866 MYGUI_ASSERT(iter != mWidgetChild.end(), "widget not found"); 00867 mWidgetChild.erase(iter); 00868 } 00869 00870 void Widget::_setTextAlign(Align _align) 00871 { 00872 StaticText* text = this->castType<StaticText>(false); 00873 if (text) text->setTextAlign(_align); 00874 00875 if (mText != nullptr) mText->setTextAlign(_align); 00876 } 00877 00878 Align Widget::_getTextAlign() 00879 { 00880 StaticText* text = this->castType<StaticText>(false); 00881 if (text) return text->getTextAlign(); 00882 00883 if (mText != nullptr) return mText->getTextAlign(); 00884 return Align::Default; 00885 } 00886 00887 void Widget::_setTextColour(const Colour& _colour) 00888 { 00889 StaticText* text = this->castType<StaticText>(false); 00890 if (text) return text->setTextColour(_colour); 00891 00892 if (nullptr != mText) mText->setTextColour(_colour); 00893 } 00894 00895 const Colour& Widget::_getTextColour() 00896 { 00897 StaticText* text = this->castType<StaticText>(false); 00898 if (text) return text->getTextColour(); 00899 00900 return (nullptr == mText) ? Colour::Zero : mText->getTextColour(); 00901 } 00902 00903 void Widget::_setFontName(const std::string& _font) 00904 { 00905 StaticText* text = this->castType<StaticText>(false); 00906 if (text) text->setFontName(_font); 00907 00908 if (nullptr != mText) mText->setFontName(_font); 00909 } 00910 00911 const std::string& Widget::_getFontName() 00912 { 00913 StaticText* text = this->castType<StaticText>(false); 00914 if (text) return text->getFontName(); 00915 00916 if (nullptr == mText) 00917 { 00918 static std::string empty; 00919 return empty; 00920 } 00921 return mText->getFontName(); 00922 } 00923 00924 void Widget::_setFontHeight(int _height) 00925 { 00926 StaticText* text = this->castType<StaticText>(false); 00927 if (text) text->setFontHeight(_height); 00928 00929 if (nullptr != mText) mText->setFontHeight(_height); 00930 } 00931 00932 int Widget::_getFontHeight() 00933 { 00934 StaticText* text = this->castType<StaticText>(false); 00935 if (text) return text->getFontHeight(); 00936 00937 return (nullptr == mText) ? 0 : mText->getFontHeight(); 00938 } 00939 00940 IntSize Widget::_getTextSize() 00941 { 00942 StaticText* text = this->castType<StaticText>(false); 00943 if (text) return text->getTextSize(); 00944 00945 return (nullptr == mText) ? IntSize() : mText->getTextSize(); 00946 } 00947 00948 IntCoord Widget::_getTextRegion() 00949 { 00950 StaticText* text = this->castType<StaticText>(false); 00951 if (text) return text->getTextRegion(); 00952 00953 return (nullptr == mText) ? IntCoord() : mText->getCoord(); 00954 } 00955 00956 void Widget::_setAlign(const IntCoord& _oldcoord, bool _update) 00957 { 00958 // для виджета изменение х у не меняються 00959 _setAlign(_oldcoord.size(), _update); 00960 } 00961 00962 void Widget::_setAlign(const IntSize& _oldsize, bool _update) 00963 { 00964 const IntSize& size = mCroppedParent ? mCroppedParent->getSize() : Gui::getInstance().getViewSize(); 00965 00966 bool need_move = false; 00967 bool need_size = false; 00968 IntCoord coord = mCoord; 00969 00970 // первоначальное выравнивание 00971 if (mAlign.isHRelative()) 00972 { 00973 coord.left = int((float)size.width * mRelativeCoord.left); 00974 coord.width = int((float)size.width * mRelativeCoord.width); 00975 } 00976 else if (mAlign.isHStretch()) 00977 { 00978 // растягиваем 00979 coord.width = mCoord.width + (size.width - _oldsize.width); 00980 need_size = true; 00981 } 00982 else if (mAlign.isRight()) 00983 { 00984 // двигаем по правому краю 00985 coord.left = mCoord.left + (size.width - _oldsize.width); 00986 need_move = true; 00987 } 00988 else if (mAlign.isHCenter()) 00989 { 00990 // выравнивание по горизонтали без растяжения 00991 coord.left = (size.width - mCoord.width) / 2; 00992 need_move = true; 00993 } 00994 00995 if (mAlign.isVRelative()) 00996 { 00997 coord.top = int((float)size.height * mRelativeCoord.top); 00998 coord.height = int((float)size.height * mRelativeCoord.height); 00999 } 01000 else if (mAlign.isVStretch()) 01001 { 01002 // растягиваем 01003 coord.height = mCoord.height + (size.height - _oldsize.height); 01004 need_size = true; 01005 } 01006 else if (mAlign.isBottom()) 01007 { 01008 // двигаем по нижнему краю 01009 coord.top = mCoord.top + (size.height - _oldsize.height); 01010 need_move = true; 01011 } 01012 else if (mAlign.isVCenter()) 01013 { 01014 // выравнивание по вертикали без растяжения 01015 coord.top = (size.height - mCoord.height) / 2; 01016 need_move = true; 01017 } 01018 01019 if (mAlign.isHRelative() || mAlign.isVRelative()) 01020 { 01021 mDisableUpdateRelative = true; 01022 setCoord(coord); 01023 mDisableUpdateRelative = false; 01024 } 01025 else if (need_move) 01026 { 01027 if (need_size) setCoord(coord); 01028 else setPosition(coord.point()); 01029 } 01030 else if (need_size) 01031 { 01032 setSize(coord.size()); 01033 } 01034 else 01035 { 01036 _updateView(); // только если не вызвано передвижение и сайз 01037 } 01038 01039 } 01040 01041 void Widget::setPosition(const IntPoint& _point) 01042 { 01043 if (mAlign.isHRelative() || mAlign.isVRelative()) 01044 { 01045 01046 const IntSize& parent_size = mCroppedParent ? mCroppedParent->getSize() : Gui::getInstance().getViewSize(); 01047 01048 if (parent_size.width) 01049 { 01050 mRelativeCoord.left = (float)_point.left / (float)parent_size.width; 01051 } 01052 else 01053 { 01054 mRelativeCoord.left = 0; 01055 } 01056 01057 if (parent_size.height) 01058 { 01059 mRelativeCoord.top = (float)_point.top / (float)parent_size.height; 01060 } 01061 else 01062 { 01063 mRelativeCoord.top = 0; 01064 } 01065 01066 } 01067 01068 // обновляем абсолютные координаты 01069 mAbsolutePosition += _point - mCoord.point(); 01070 01071 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateAbsolutePoint(); 01072 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateAbsolutePoint(); 01073 01074 mCoord = _point; 01075 01076 _updateView(); 01077 } 01078 01079 void Widget::setSize(const IntSize& _size) 01080 { 01081 if (mAlign.isHRelative() || mAlign.isVRelative()) 01082 { 01083 01084 const IntSize& parent_size = mCroppedParent ? mCroppedParent->getSize() : Gui::getInstance().getViewSize(); 01085 01086 if (parent_size.width) 01087 { 01088 mRelativeCoord.width = (float)_size.width / (float)parent_size.width; 01089 } 01090 else 01091 { 01092 mRelativeCoord.width = 0; 01093 } 01094 01095 if (parent_size.height) 01096 { 01097 mRelativeCoord.height = (float)_size.height / (float)parent_size.height; 01098 } 01099 else 01100 { 01101 mRelativeCoord.height = 0; 01102 } 01103 01104 } 01105 01106 // устанавливаем новую координату а старую пускаем в расчеты 01107 IntSize old = mCoord.size(); 01108 mCoord = _size; 01109 01110 bool visible = true; 01111 01112 // обновляем выравнивание 01113 bool margin = mCroppedParent ? _checkMargin() : false; 01114 01115 if (margin) 01116 { 01117 // проверка на полный выход за границу 01118 if (_checkOutside()) 01119 { 01120 // скрываем 01121 visible = false; 01122 } 01123 } 01124 01125 _setSubSkinVisible(visible); 01126 01127 // передаем старую координату , до вызова, текущая координата отца должна быть новой 01128 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_setAlign(old, mIsMargin || margin); 01129 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_setAlign(old, mIsMargin || margin); 01130 for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin) (*skin)->_setAlign(old, mIsMargin || margin); 01131 01132 // запоминаем текущее состояние 01133 mIsMargin = margin; 01134 01135 } 01136 01137 void Widget::setCoord(const IntCoord& _coord) 01138 { 01139 if (!mDisableUpdateRelative && (mAlign.isHRelative() || mAlign.isVRelative())) 01140 { 01141 01142 const IntSize& parent_size = mCroppedParent ? mCroppedParent->getSize() : Gui::getInstance().getViewSize(); 01143 01144 if (parent_size.width) 01145 { 01146 mRelativeCoord.left = (float)_coord.left / (float)parent_size.width; 01147 mRelativeCoord.width = (float)_coord.width / (float)parent_size.width; 01148 } 01149 else 01150 { 01151 mRelativeCoord.left = 0; 01152 mRelativeCoord.width = 0; 01153 } 01154 01155 if (parent_size.height) 01156 { 01157 mRelativeCoord.top = (float)_coord.top / (float)parent_size.height; 01158 mRelativeCoord.height = (float)_coord.height / (float)parent_size.height; 01159 } 01160 else 01161 { 01162 mRelativeCoord.top = 0; 01163 mRelativeCoord.height = 0; 01164 } 01165 01166 } 01167 01168 // обновляем абсолютные координаты 01169 mAbsolutePosition += _coord.point() - mCoord.point(); 01170 01171 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateAbsolutePoint(); 01172 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateAbsolutePoint(); 01173 01174 // устанавливаем новую координату а старую пускаем в расчеты 01175 IntCoord old = mCoord; 01176 mCoord = _coord; 01177 01178 bool visible = true; 01179 01180 // обновляем выравнивание 01181 bool margin = mCroppedParent ? _checkMargin() : false; 01182 01183 if (margin) 01184 { 01185 // проверка на полный выход за границу 01186 if (_checkOutside()) 01187 { 01188 // скрываем 01189 visible = false; 01190 } 01191 } 01192 01193 _setSubSkinVisible(visible); 01194 01195 // передаем старую координату , до вызова, текущая координата отца должна быть новой 01196 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_setAlign(old, mIsMargin || margin); 01197 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_setAlign(old, mIsMargin || margin); 01198 for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin) (*skin)->_setAlign(old, mIsMargin || margin); 01199 01200 // запоминаем текущее состояние 01201 mIsMargin = margin; 01202 01203 } 01204 01205 void Widget::setAlign(Align _align) 01206 { 01207 ICroppedRectangle::setAlign(_align); 01208 01209 if (mAlign.isHRelative() || mAlign.isVRelative()) 01210 { 01211 const IntSize& parent_size = mCroppedParent ? mCroppedParent->getSize() : Gui::getInstance().getViewSize(); 01212 01213 if (parent_size.width) 01214 { 01215 mRelativeCoord.left = (float)mCoord.left / (float)parent_size.width; 01216 mRelativeCoord.width = (float)mCoord.width / (float)parent_size.width; 01217 } 01218 else 01219 { 01220 mRelativeCoord.left = 0; 01221 mRelativeCoord.width = 0; 01222 } 01223 01224 if (parent_size.height) 01225 { 01226 mRelativeCoord.top = (float)mCoord.top / (float)parent_size.height; 01227 mRelativeCoord.height = (float)mCoord.height / (float)parent_size.height; 01228 } 01229 else 01230 { 01231 mRelativeCoord.top = 0; 01232 mRelativeCoord.height = 0; 01233 } 01234 01235 } 01236 01237 } 01238 01239 void Widget::detachFromWidget(const std::string& _layer) 01240 { 01241 std::string oldlayer = getLayerName(); 01242 01243 Widget* parent = getParent(); 01244 if (parent) 01245 { 01246 // отдетачиваемся от лееров 01247 if ( ! isRootWidget() ) 01248 { 01249 detachFromLayerItemNode(true); 01250 01251 if (mWidgetStyle == WidgetStyle::Child) 01252 { 01253 mParent->removeChildItem(this); 01254 } 01255 else if (mWidgetStyle == WidgetStyle::Overlapped) 01256 { 01257 mParent->removeChildNode(this); 01258 } 01259 01260 mWidgetStyle = WidgetStyle::Overlapped; 01261 01262 mCroppedParent = nullptr; 01263 01264 // обновляем координаты 01265 mAbsolutePosition = mCoord.point(); 01266 01267 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateAbsolutePoint(); 01268 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateAbsolutePoint(); 01269 01270 // сбрасываем обрезку 01271 mMargin.clear(); 01272 01273 _updateView(); 01274 } 01275 01276 // нам нужен самый рутовый парент 01277 while (parent->getParent()) { parent = parent->getParent(); } 01278 01279 mIWidgetCreator = parent->mIWidgetCreator; 01280 mIWidgetCreator->_linkChildWidget(this); 01281 mParent->_unlinkChildWidget(this); 01282 mParent = nullptr; 01283 } 01284 01285 if (!_layer.empty()) 01286 { 01287 LayerManager::getInstance().attachToLayerNode(_layer, this); 01288 } 01289 else if (!oldlayer.empty()) 01290 { 01291 LayerManager::getInstance().attachToLayerNode(oldlayer, this); 01292 } 01293 01294 // корректируем параметры 01295 float alpha = mAlpha; 01296 mAlpha = -1; 01297 setAlpha(alpha); 01298 01299 } 01300 01301 void Widget::attachToWidget(Widget* _parent, WidgetStyle _style, const std::string& _layer) 01302 { 01303 MYGUI_ASSERT(_parent, "parent must be valid"); 01304 MYGUI_ASSERT(_parent != this, "cyclic attach (attaching to self)"); 01305 01306 // attach to client if widget have it 01307 if (_parent->getClientWidget()) _parent = _parent->getClientWidget(); 01308 01309 // проверяем на цикличность атача 01310 Widget* parent = _parent; 01311 while (parent->getParent()) 01312 { 01313 MYGUI_ASSERT(parent != this, "cyclic attach"); 01314 parent = parent->getParent(); 01315 } 01316 01317 // отдетачиваемся от всего 01318 detachFromWidget(); 01319 01320 mWidgetStyle = _style; 01321 01322 if (_style == WidgetStyle::Popup) 01323 { 01324 mIWidgetCreator->_unlinkChildWidget(this); 01325 mIWidgetCreator = _parent; 01326 mParent = _parent; 01327 mParent->_linkChildWidget(this); 01328 01329 mCroppedParent = nullptr; 01330 01331 if (!_layer.empty()) 01332 { 01333 LayerManager::getInstance().attachToLayerNode(_layer, this); 01334 } 01335 } 01336 else if (_style == WidgetStyle::Child) 01337 { 01338 LayerManager::getInstance().detachFromLayer(this); 01339 01340 mIWidgetCreator->_unlinkChildWidget(this); 01341 mIWidgetCreator = _parent; 01342 mParent = _parent; 01343 mParent->_linkChildWidget(this); 01344 01345 mCroppedParent = _parent; 01346 mAbsolutePosition = _parent->getAbsolutePosition() + mCoord.point(); 01347 01348 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateAbsolutePoint(); 01349 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateAbsolutePoint(); 01350 01351 mParent->addChildItem(this); 01352 01353 _updateView(); 01354 } 01355 else if (_style == WidgetStyle::Overlapped) 01356 { 01357 LayerManager::getInstance().detachFromLayer(this); 01358 01359 mIWidgetCreator->_unlinkChildWidget(this); 01360 mIWidgetCreator = _parent; 01361 mParent = _parent; 01362 mParent->_linkChildWidget(this); 01363 01364 mCroppedParent = _parent; 01365 mAbsolutePosition = _parent->getAbsolutePosition() + mCoord.point(); 01366 01367 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateAbsolutePoint(); 01368 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateAbsolutePoint(); 01369 01370 mParent->addChildNode(this); 01371 01372 _updateView(); 01373 } 01374 01375 // корректируем параметры 01376 float alpha = mAlpha; 01377 mAlpha = -1; 01378 setAlpha(alpha); 01379 01380 } 01381 01382 void Widget::setWidgetStyle(WidgetStyle _style, const std::string& _layer) 01383 { 01384 if (_style == mWidgetStyle) return; 01385 if (nullptr == getParent()) return; 01386 01387 Widget* parent = mParent; 01388 01389 detachFromWidget(); 01390 attachToWidget(parent, _style, _layer); 01391 // ищем леер к которому мы присоедененны 01392 /*Widget* root = this; 01393 while (!root->isRootWidget()) 01394 { 01395 root = root->getParent(); 01396 } 01397 01398 // отсоединяем рут 01399 std::string layername; 01400 ILayer* layer = root->getLayer(); 01401 if (layer) 01402 { 01403 layername = layer->getName(); 01404 LayerManager::getInstance().detachFromLayer(root); 01405 01406 // если мы рут, то придется отцеплят более высокого рута 01407 if (root == this) 01408 { 01409 layername.clear(); 01410 01411 if (getParent()) 01412 { 01413 // ищем леер к которому мы присоедененны 01414 root = getParent(); 01415 while (!root->isRootWidget()) 01416 { 01417 root = root->getParent(); 01418 } 01419 01420 layer = root->getLayer(); 01421 if (layer) 01422 { 01423 layername = layer->getName(); 01424 LayerManager::getInstance().detachFromLayer(root); 01425 } 01426 01427 } 01428 } 01429 } 01430 01431 // корректируем 01432 mWidgetStyle = _style; 01433 if (_style == WidgetStyle::Child) 01434 { 01435 01436 Widget* parent = getParent(); 01437 if (parent) 01438 { 01439 mAbsolutePosition = parent->getAbsolutePosition() + mCoord.point(); 01440 mCroppedParent = parent; 01441 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateAbsolutePoint(); 01442 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateAbsolutePoint(); 01443 } 01444 01445 } 01446 else if (_style == WidgetStyle::Popup) 01447 { 01448 01449 mCroppedParent = nullptr; 01450 // обновляем координаты 01451 mAbsolutePosition = mCoord.point(); 01452 // сбрасываем обрезку 01453 mMargin.clear(); 01454 01455 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateAbsolutePoint(); 01456 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateAbsolutePoint(); 01457 01458 } 01459 else if (_style == WidgetStyle::Overlapped) 01460 { 01461 01462 Widget* parent = getParent(); 01463 if (parent) 01464 { 01465 mAbsolutePosition = parent->getAbsolutePosition() + mCoord.point(); 01466 mCroppedParent = parent; 01467 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateAbsolutePoint(); 01468 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateAbsolutePoint(); 01469 } 01470 01471 } 01472 01473 // присоединяем обратно 01474 if (!layername.empty()) 01475 { 01476 LayerManager::getInstance().attachToLayerNode(layername, root); 01477 }*/ 01478 01479 } 01480 01481 void Widget::setCaptionWithNewLine(const std::string& _value) 01482 { 01483 // change '\n' on char 10 01484 size_t pos = _value.find("\\n"); 01485 if (pos == std::string::npos) 01486 { 01487 setCaption(LanguageManager::getInstance().replaceTags(_value)); 01488 } 01489 else 01490 { 01491 std::string value(_value); 01492 while (pos != std::string::npos) 01493 { 01494 value[pos++] = '\n'; 01495 value.erase(pos, 1); 01496 pos = value.find("\\n"); 01497 } 01498 setCaption(LanguageManager::getInstance().replaceTags(value)); 01499 } 01500 } 01501 01502 Widget* Widget::createWidgetT(const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _name) 01503 { 01504 return baseCreateWidget(WidgetStyle::Child, _type, _skin, _coord, _align, "", _name); 01505 } 01506 01507 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) 01508 { 01509 return createWidgetT(_type, _skin, IntCoord(_left, _top, _width, _height), _align, _name); 01510 } 01511 01512 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) 01513 { 01514 return createWidgetRealT(_type, _skin, FloatCoord(_left, _top, _width, _height), _align, _name); 01515 } 01516 01517 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) 01518 { 01519 return baseCreateWidget(_style, _type, _skin, _coord, _align, _layer, _name); 01520 } 01521 01522 EnumeratorWidgetPtr Widget::getEnumerator() 01523 { 01524 MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget"); 01525 if (mWidgetClient != nullptr) return mWidgetClient->getEnumerator(); 01526 return Enumerator<VectorWidgetPtr>(mWidgetChild.begin(), mWidgetChild.end()); 01527 } 01528 01529 size_t Widget::getChildCount() 01530 { 01531 MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget"); 01532 if (mWidgetClient != nullptr) return mWidgetClient->getChildCount(); 01533 return mWidgetChild.size(); 01534 } 01535 01536 Widget* Widget::getChildAt(size_t _index) 01537 { 01538 MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget"); 01539 if (mWidgetClient != nullptr) return mWidgetClient->getChildAt(_index); 01540 MYGUI_ASSERT_RANGE(_index, mWidgetChild.size(), "Widget::getChildAt"); 01541 return mWidgetChild[_index]; 01542 } 01543 01544 const std::string& Widget::getPointer() 01545 { 01546 if (!mEnabled) 01547 { 01548 static std::string empty; 01549 return empty; 01550 } 01551 return mPointer; 01552 } 01553 01554 void Widget::setProperty(const std::string& _key, const std::string& _value) 01555 { 01557 if (_key == "Widget_Caption") setCaptionWithNewLine(_value); 01559 else if (_key == "Widget_Position") setPosition(utility::parseValue<IntPoint>(_value)); 01560 else if (_key == "Widget_Size") setSize(utility::parseValue<IntSize>(_value)); 01561 else if (_key == "Widget_Coord") setCoord(utility::parseValue<IntCoord>(_value)); 01562 else if (_key == "Widget_Visible") setVisible(utility::parseValue<bool>(_value)); 01563 else if (_key == "Widget_Alpha") setAlpha(utility::parseValue<float>(_value)); 01564 else if (_key == "Widget_Colour") setColour(utility::parseValue<Colour>(_value)); 01565 else if (_key == "Widget_InheritsAlpha") setInheritsAlpha(utility::parseValue<bool>(_value)); 01566 else if (_key == "Widget_InheritsPick") setInheritsPick(utility::parseValue<bool>(_value)); 01567 else if (_key == "Widget_MaskPick") setMaskPick(_value); 01568 else if (_key == "Widget_State") setState(_value); 01569 else if (_key == "Widget_NeedKey") setNeedKeyFocus(utility::parseValue<bool>(_value)); 01570 else if (_key == "Widget_NeedMouse") setNeedMouseFocus(utility::parseValue<bool>(_value)); 01571 else if (_key == "Widget_Enabled") setEnabled(utility::parseValue<bool>(_value)); 01572 else if (_key == "Widget_NeedToolTip") setNeedToolTip(utility::parseValue<bool>(_value)); 01573 else if (_key == "Widget_Pointer") setPointer(_value); 01574 01575 #ifndef MYGUI_DONT_USE_OBSOLETE 01576 else if (_key == "Widget_TextColour") 01577 { 01578 MYGUI_LOG(Warning, "Widget_TextColour is obsolete, use Text_TextColour"); 01579 _setTextColour(Colour::parse(_value)); 01580 } 01581 else if (_key == "Widget_FontName") 01582 { 01583 MYGUI_LOG(Warning, "Widget_FontName is obsolete, use Text_FontName"); 01584 _setFontName(_value); 01585 } 01586 else if (_key == "Widget_FontHeight") 01587 { 01588 MYGUI_LOG(Warning, "Widget_FontHeight is obsolete, use Text_FontHeight"); 01589 this->_setFontHeight(utility::parseValue<int>(_value)); 01590 } 01591 else if (_key == "Widget_TextAlign") 01592 { 01593 MYGUI_LOG(Warning, "Widget_TextAlign is obsolete, use Text_TextAlign"); 01594 _setTextAlign(Align::parse(_value)); 01595 } 01596 else if (_key == "Widget_AlignText") 01597 { 01598 MYGUI_LOG(Warning, "Widget_AlignText is obsolete, use Text_TextAlign"); 01599 _setTextAlign(Align::parse(_value)); 01600 } 01601 else if (_key == "Widget_Show") 01602 { 01603 MYGUI_LOG(Warning, "Widget_Show is obsolete, use Widget_Visible"); 01604 setVisible(utility::parseValue<bool>(_value)); 01605 } 01606 else if (_key == "Widget_InheritsPeek") 01607 { 01608 MYGUI_LOG(Warning, "Widget_InheritsPeek is obsolete, use Widget_InheritsPick"); 01609 setInheritsPick(utility::parseValue<bool>(_value)); 01610 } 01611 else if (_key == "Widget_MaskPeek") 01612 { 01613 MYGUI_LOG(Warning, "Widget_MaskPeek is obsolete, use Widget_MaskPick"); 01614 setMaskPick(_value); 01615 } 01616 #endif // MYGUI_DONT_USE_OBSOLETE 01617 01618 else 01619 { 01620 MYGUI_LOG(Warning, "Property " << _key << " not found"); 01621 return; 01622 } 01623 01624 eventChangeProperty(this, _key, _value); 01625 } 01626 01627 void Widget::baseUpdateEnable() 01628 { 01629 if (mEnabled) 01630 { 01631 setState("normal"); 01632 } 01633 else 01634 { 01635 setState("disabled"); 01636 } 01637 } 01638 01639 void Widget::setVisible(bool _value) 01640 { 01641 if (mVisible == _value) return; 01642 mVisible = _value; 01643 01644 if (mInheritsVisible) 01645 { 01646 for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin) 01647 (*skin)->setVisible(_value); 01648 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) 01649 (*widget)->_setInheritsVisible(_value); 01650 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) 01651 (*widget)->_setInheritsVisible(_value); 01652 } 01653 01654 } 01655 01656 void Widget::_setInheritsVisible(bool _value) 01657 { 01658 if (mInheritsVisible == _value) return; 01659 mInheritsVisible = _value; 01660 01661 if (mVisible) 01662 { 01663 for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin) 01664 (*skin)->setVisible(_value); 01665 for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) 01666 (*widget)->_setInheritsVisible(_value); 01667 for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) 01668 (*widget)->_setInheritsVisible(_value); 01669 } 01670 } 01671 01672 void Widget::setEnabled(bool _value) 01673 { 01674 if (mEnabled == _value) return; 01675 mEnabled = _value; 01676 01677 if (mInheritsEnabled) 01678 { 01679 for (VectorWidgetPtr::iterator iter = mWidgetChild.begin(); iter != mWidgetChild.end(); ++iter) 01680 (*iter)->_setInheritsEnable(_value); 01681 for (VectorWidgetPtr::iterator iter = mWidgetChildSkin.begin(); iter != mWidgetChildSkin.end(); ++iter) 01682 (*iter)->_setInheritsEnable(_value); 01683 01684 baseUpdateEnable(); 01685 } 01686 01687 if (!mEnabled) 01688 { 01689 InputManager::getInstance().unlinkWidget(this); 01690 } 01691 } 01692 01693 void Widget::_setInheritsEnable(bool _value) 01694 { 01695 if (mInheritsEnabled == _value) return; 01696 mInheritsEnabled = _value; 01697 01698 if (mEnabled) 01699 { 01700 for (VectorWidgetPtr::iterator iter = mWidgetChild.begin(); iter != mWidgetChild.end(); ++iter) 01701 (*iter)->_setInheritsEnable(_value); 01702 for (VectorWidgetPtr::iterator iter = mWidgetChildSkin.begin(); iter != mWidgetChildSkin.end(); ++iter) 01703 (*iter)->_setInheritsEnable(_value); 01704 01705 baseUpdateEnable(); 01706 } 01707 01708 if (!mEnabled) 01709 { 01710 InputManager::getInstance().unlinkWidget(this); 01711 } 01712 } 01713 01714 void Widget::setColour(const Colour& _value) 01715 { 01716 for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin) 01717 { 01718 ISubWidgetRect* rect = (*skin)->castType<ISubWidgetRect>(false); 01719 if (rect) 01720 rect->_setColour(_value); 01721 } 01722 } 01723 01724 } // namespace MyGUI