MyGUI  3.0.3
MyGUI_Widget.cpp
Go to the documentation of this file.
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