• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

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

Generated on Sun Jan 30 2011 for MyGUI by  doxygen 1.7.1