MyGUI  3.0.1
MyGUI_Widget.cpp
Go to the documentation of this file.
1 
7 /*
8  This file is part of MyGUI.
9 
10  MyGUI is free software: you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  MyGUI is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with MyGUI. If not, see <http://www.gnu.org/licenses/>.
22 */
23 #include "MyGUI_Precompiled.h"
24 #include "MyGUI_Gui.h"
25 #include "MyGUI_Widget.h"
26 #include "MyGUI_InputManager.h"
27 #include "MyGUI_SkinManager.h"
28 #include "MyGUI_SubWidgetManager.h"
29 #include "MyGUI_WidgetManager.h"
30 #include "MyGUI_ResourceSkin.h"
31 #include "MyGUI_WidgetDefines.h"
32 #include "MyGUI_LayerItem.h"
33 #include "MyGUI_LayerManager.h"
34 #include "MyGUI_RenderItem.h"
35 #include "MyGUI_ISubWidget.h"
36 #include "MyGUI_ISubWidgetText.h"
37 #include "MyGUI_StaticText.h"
38 #include "MyGUI_FactoryManager.h"
39 #include "MyGUI_LanguageManager.h"
40 #include "MyGUI_CoordConverter.h"
41 #include "MyGUI_RenderManager.h"
42 
43 namespace MyGUI
44 {
45 
46  const float WIDGET_TOOLTIP_TIMEOUT = 0.5f;
47 
48  Widget::Widget(WidgetStyle _style, const IntCoord& _coord, Align _align, ResourceSkin* _info, Widget* _parent, ICroppedRectangle * _croppedParent, IWidgetCreator * _creator, const std::string& _name) :
49  mMaskPickInfo(nullptr),
50  mText(nullptr),
51  mMainSkin(nullptr),
52  mEnabled(true),
53  mInheritsEnabled(true),
54  mSubSkinsVisible(true),
55  mInheritsVisible(true),
56  mAlpha(ALPHA_MIN),
57  mRealAlpha(ALPHA_MIN),
58  mInheritsAlpha(true),
59  mTexture(nullptr),
60  mParent(nullptr),
61  mIWidgetCreator(nullptr),
62  mNeedKeyFocus(false),
63  mNeedMouseFocus(true),
64  mInheritsPick(false),
65  mWidgetClient(nullptr),
66  mNeedToolTip(false),
67  mEnableToolTip(true),
68  mToolTipVisible(false),
69  mToolTipCurrentTime(0),
70  mToolTipOldIndex(ITEM_NONE),
71  mWidgetStyle(WidgetStyle::Child),
72  mDisableUpdateRelative(false)
73  {
74  _initialise(_style, _coord, _align, _info, _parent, _croppedParent, _creator, _name);
75  }
76 
78  mMaskPickInfo(nullptr),
79  mText(nullptr),
80  mMainSkin(nullptr),
81  mEnabled(true),
82  mInheritsEnabled(true),
83  mSubSkinsVisible(true),
84  mInheritsVisible(true),
85  mAlpha(ALPHA_MIN),
86  mRealAlpha(ALPHA_MIN),
87  mInheritsAlpha(true),
88  mTexture(nullptr),
89  mParent(nullptr),
90  mIWidgetCreator(nullptr),
91  mNeedKeyFocus(false),
92  mNeedMouseFocus(true),
93  mInheritsPick(false),
94  mWidgetClient(nullptr),
95  mNeedToolTip(false),
96  mEnableToolTip(true),
97  mToolTipVisible(false),
98  mToolTipCurrentTime(0),
99  mToolTipOldIndex(ITEM_NONE),
100  mWidgetStyle(WidgetStyle::Child),
101  mDisableUpdateRelative(false)
102  {
103  }
104 
105  void Widget::_initialise(WidgetStyle _style, const IntCoord& _coord, Align _align, ResourceSkin* _info, Widget* _parent, ICroppedRectangle * _croppedParent, IWidgetCreator * _creator, const std::string& _name)
106  {
107  mCoord = IntCoord(_coord.point(), _info->getSize());
108  mStateInfo = _info->getStateInfo();
109  mMaskPickInfo = _info->getMask();
110 
111  mTextureName = _info->getTextureName();
113 
114  mAlign = _align;
115  mCroppedParent = _croppedParent;
116 
117  mName = _name;
118  mParent = _parent;
119  mIWidgetCreator = _creator;
120 
121  mWidgetStyle = _style;
122 
123  // имя отсылателя сообщений
124  mWidgetEventSender = this;
125 
126 #if MYGUI_DEBUG_MODE == 1
127  // проверяем соответсвие входных данных
129  {
130  MYGUI_ASSERT(mCroppedParent, "must be cropped");
131  MYGUI_ASSERT(mParent, "must be parent");
132  }
134  {
135  MYGUI_ASSERT((mParent == nullptr) == (mCroppedParent == nullptr), "error cropped");
136  }
137  else if (mWidgetStyle == WidgetStyle::Popup)
138  {
139  MYGUI_ASSERT(!mCroppedParent, "cropped must be nullptr");
140  MYGUI_ASSERT(mParent, "must be parent");
141  }
142 #endif
143 
144  // корректируем абсолютные координаты
145  mAbsolutePosition = _coord.point();
146 
147  if (nullptr != mCroppedParent)
148  {
150  }
151 
153 
154  if (parent_size.width)
155  {
156  mRelativeCoord.left = (float)_coord.left / (float)parent_size.width;
157  mRelativeCoord.width = (float)_coord.width / (float)parent_size.width;
158  }
159  else
160  {
161  mRelativeCoord.left = 0;
162  mRelativeCoord.width = 0;
163  }
164 
165  if (parent_size.height)
166  {
167  mRelativeCoord.top = (float)_coord.top / (float)parent_size.height;
168  mRelativeCoord.height = (float)_coord.height / (float)parent_size.height;
169  }
170  else
171  {
172  mRelativeCoord.top = 0;
174  }
175 
176  initialiseWidgetSkin(_info, _coord.size());
177 
178  // дочернее окно обыкновенное
180  {
181  if (mParent) mParent->addChildItem(this);
182  }
183  // дочернее нуно перекрывающееся
185  {
186  // дочернее перекрывающееся
187  if (mParent) mParent->addChildNode(this);
188  }
189  }
190 
192  {
193  Gui::getInstance().eventFrameStart -= newDelegate(this, &Widget::frameEntered);
194 
196 
197  shutdownWidgetSkin(true);
198 
200 
201  // дочернее окно обыкновенное
203  {
204  if (mParent) mParent->removeChildItem(this);
205  }
206  // дочернее нуно перекрывающееся
208  {
209  // дочернее перекрывающееся
210  if (mParent) mParent->removeChildNode(this);
211  }
212  }
213 
214  void Widget::changeWidgetSkin(const std::string& _skinname)
215  {
216  ResourceSkin* skin_info = SkinManager::getInstance().getByName(_skinname);
217  baseChangeWidgetSkin(skin_info);
218  }
219 
221  {
222  IntSize size = mCoord.size();
223 
224  saveLayerItem();
225 
226  shutdownWidgetSkin();
227  initialiseWidgetSkin(_info, size);
228 
230  }
231 
232  void Widget::initialiseWidgetSkin(ResourceSkin* _info, const IntSize& _size)
233  {
235 
236  mTextureName = _info->getTextureName();
238 
240  mStateInfo = _info->getStateInfo();
241  Widget::setSize(_info->getSize());
242 
243  // загружаем кирпичики виджета
244  for (VectorSubWidgetInfo::const_iterator iter=_info->getBasisInfo().begin(); iter!=_info->getBasisInfo().end(); ++iter)
245  {
246  IObject* object = factory.createObject("BasisSkin", (*iter).type);
247  if (object == nullptr) continue;
248 
249  ISubWidget* sub = object->castType<ISubWidget>();
250  sub->_setCroppedParent(this);
251  sub->setCoord((*iter).coord);
252  sub->setAlign((*iter).align);
253 
254  mSubSkinChild.push_back(sub);
255  addRenderItem(sub);
256 
257  // ищем дефолтные сабвиджеты
258  if (mMainSkin == nullptr) mMainSkin = sub->castType<ISubWidgetRect>(false);
259  if (mText == nullptr) mText = sub->castType<ISubWidgetText>(false);
260  }
261 
262  if (!isRootWidget())
263  {
264  // проверяем наследуемую скрытость
265  if ((!mParent->isVisible()) || (!mParent->_isInheritsVisible()))
266  {
267  bool value = false;
268  mInheritsVisible = value;
269  for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin)
270  (*skin)->setVisible(value);
271  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
272  (*widget)->_setInheritsVisible(value);
273  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget)
274  (*widget)->_setInheritsVisible(value);
275  }
276  // проверяем наследуемый дизейбл
277  if ((!mParent->isEnabled()) || (!mParent->_isInheritsEnable()))
278  {
279  bool value = false;
280  mInheritsEnabled = false;
281  for (VectorWidgetPtr::iterator iter = mWidgetChild.begin(); iter != mWidgetChild.end(); ++iter)
282  (*iter)->_setInheritsEnable(value);
283  for (VectorWidgetPtr::iterator iter = mWidgetChildSkin.begin(); iter != mWidgetChildSkin.end(); ++iter)
284  (*iter)->_setInheritsEnable(value);
285  }
286  }
287 
288  Widget::setState("normal");//FIXME - явный вызов
289 
290  // парсим свойства
291  const MapString& properties = _info->getProperties();
292  if (!properties.empty())
293  {
294  MapString::const_iterator iter = properties.end();
295  if ((iter = properties.find("NeedKey")) != properties.end()) setNeedKeyFocus(utility::parseBool(iter->second));
296  if ((iter = properties.find("NeedMouse")) != properties.end()) setNeedMouseFocus(utility::parseBool(iter->second));
297  if ((iter = properties.find("Pointer")) != properties.end()) mPointer = iter->second;
298  if ((iter = properties.find("Visible")) != properties.end()) { setVisible(utility::parseBool(iter->second)); }
299 
300  // OBSOLETE
301  if ((iter = properties.find("AlignText")) != properties.end()) _setTextAlign(Align::parse(iter->second));
302  if ((iter = properties.find("Colour")) != properties.end()) _setTextColour(Colour::parse(iter->second));
303  if ((iter = properties.find("Show")) != properties.end()) { setVisible(utility::parseBool(iter->second)); }
304  if ((iter = properties.find("TextAlign")) != properties.end()) _setTextAlign(Align::parse(iter->second));
305  if ((iter = properties.find("TextColour")) != properties.end()) _setTextColour(Colour::parse(iter->second));
306  if ((iter = properties.find("FontName")) != properties.end()) _setFontName(iter->second);
307  if ((iter = properties.find("FontHeight")) != properties.end()) _setFontHeight(utility::parseInt(iter->second));
308  }
309 
310  // выставляем альфу, корректировка по отцу автоматически
311  Widget::setAlpha(ALPHA_MAX);//FIXME - явный вызов
312 
313  // создаем детей скина
314  const VectorChildSkinInfo& child = _info->getChild();
315  for (VectorChildSkinInfo::const_iterator iter=child.begin(); iter!=child.end(); ++iter)
316  {
317  //FIXME - явный вызов
318  Widget* widget = Widget::baseCreateWidget(iter->style, iter->type, iter->skin, iter->coord, iter->align, iter->layer, "");
319  widget->_setInternalData(iter->name);
320  // заполняем UserString пропертями
321  for (MapString::const_iterator prop=iter->params.begin(); prop!=iter->params.end(); ++prop)
322  {
323  widget->setUserString(prop->first, prop->second);
324  }
325  // для детей скина свой список
326  mWidgetChildSkin.push_back(widget);
327  mWidgetChild.pop_back();
328  }
329 
330  Widget::setSize(_size);//FIXME - явный вызов
331  }
332 
333  void Widget::shutdownWidgetSkin(bool _deep)
334  {
335  // удаляем все сабскины
336  mMainSkin = nullptr;
337  mText = nullptr;
338 
340 
341  for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin)
342  {
343  delete (*skin);
344  }
345  mSubSkinChild.clear();
346 
347  mStateInfo.clear();
348 
349  // удаляем виджеты чтобы ли в скине
350  for (VectorWidgetPtr::iterator iter=mWidgetChildSkin.begin(); iter!=mWidgetChildSkin.end(); ++iter)
351  {
352  // Добавляем себя чтобы удалилось
353  mWidgetChild.push_back(*iter);
354  _destroyChildWidget(*iter);
355  }
356  mWidgetChildSkin.clear();
357  }
358 
359  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)
360  {
361  Widget* widget = WidgetManager::getInstance().createWidget(_style, _type, _skin, _coord, _align, this,
362  _style == WidgetStyle::Popup ? nullptr : this, this, _name);
363 
364  mWidgetChild.push_back(widget);
365 
366  // присоединяем виджет с уровню
367  if (!_layer.empty() && widget->isRootWidget()) LayerManager::getInstance().attachToLayerNode(_layer, widget);
368 
369  return widget;
370  }
371 
372  Widget* Widget::createWidgetRealT(const std::string& _type, const std::string& _skin, const FloatCoord& _coord, Align _align, const std::string& _name)
373  {
374  return createWidgetT(_type, _skin, CoordConverter::convertFromRelative(_coord, getSize()), _align, _name);
375  }
376 
378  {
379 
380  bool margin = mCroppedParent ? _checkMargin() : false;
381 
382  // вьюпорт стал битым
383  if (margin)
384  {
385  // проверка на полный выход за границу
386  if (_checkOutside())
387  {
388  // запоминаем текущее состояние
389  mIsMargin = margin;
390 
391  // скрываем
392  _setSubSkinVisible(false);
393 
394  // для тех кому нужно подправить себя при движении
395  //for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin) (*skin)->_updateView();
396 
397  // вся иерархия должна быть проверенна
398  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateView();
399  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateView();
400 
401  return;
402  }
403 
404  }
405  // мы не обрезаны и были нормальные
406  else if (!mIsMargin)
407  {
408  // запоминаем текущее состояние
409  //mIsMargin = margin;
410 
411  //_setSubSkinVisible(true);
412  // для тех кому нужно подправить себя при движении
413  for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin) (*skin)->_updateView();
414 
415  return;
416  }
417 
418  // запоминаем текущее состояние
419  mIsMargin = margin;
420 
421  // если скин был скрыт, то покажем
422  _setSubSkinVisible(true);
423 
424  // обновляем наших детей, а они уже решат обновлять ли своих детей
425  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateView();
426  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateView();
427  for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin) (*skin)->_updateView();
428 
429  }
430 
431  void Widget::setCaption(const UString& _caption)
432  {
433  if (nullptr != mText) mText->setCaption(_caption);
434  }
435 
437  {
438  if (nullptr == mText)
439  {
440  static UString empty;
441  return empty;
442  }
443  return mText->getCaption();
444  }
445 
446  bool Widget::setState(const std::string& _state)
447  {
448  MapWidgetStateInfo::const_iterator iter = mStateInfo.find(_state);
449  if (iter == mStateInfo.end()) return false;
450  size_t index=0;
451  for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin, ++index)
452  {
453  IStateInfo* data = (*iter).second[index];
454  if (data != nullptr)
455  {
456  (*skin)->setStateData(data);
457  }
458  }
459  return true;
460  }
461 
463  {
464  MYGUI_ASSERT(nullptr != _widget, "invalid widget pointer");
465 
466  VectorWidgetPtr::iterator iter = std::find(mWidgetChild.begin(), mWidgetChild.end(), _widget);
467  if (iter != mWidgetChild.end())
468  {
469 
470  // сохраняем указатель
471  MyGUI::Widget* widget = *iter;
472 
473  // удаляем из списка
474  *iter = mWidgetChild.back();
475  mWidgetChild.pop_back();
476 
477  // отписываем от всех
479 
480  // непосредственное удаление
481  _deleteWidget(widget);
482  }
483  else
484  {
485  MYGUI_EXCEPT("Widget '" << _widget->getName() << "' not found");
486  }
487  }
488 
489  // удаляет всех детей
491  {
493  while (!mWidgetChild.empty())
494  {
495 
496  // сразу себя отписывем, иначе вложенной удаление убивает все
497  Widget* widget = mWidgetChild.back();
498  mWidgetChild.pop_back();
499 
500  //if (widget->isRootWidget()) widget->detachWidget();
501 
502  // отписываем от всех
503  manager.unlinkFromUnlinkers(widget);
504 
505  // и сами удалим, так как его больше в списке нет
506  delete widget;
507  }
508  }
509 
511  {
512  MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget");
513  if (mWidgetClient != nullptr) return mWidgetClient->getCoord();
514  return IntCoord(0, 0, mCoord.width, mCoord.height);
515  }
516 
517  void Widget::setAlpha(float _alpha)
518  {
519  if (mAlpha == _alpha) return;
520  mAlpha = _alpha;
521  if (nullptr != mParent) mRealAlpha = mAlpha * (mInheritsAlpha ? mParent->_getRealAlpha() : ALPHA_MAX);
522  else mRealAlpha = mAlpha;
523 
524  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateAlpha();
525  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateAlpha();
526  for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin) (*skin)->setAlpha(mRealAlpha);
527  }
528 
529  void Widget::_updateAlpha()
530  {
531  MYGUI_DEBUG_ASSERT(nullptr != mParent, "Widget must have parent");
532  mRealAlpha = mAlpha * (mInheritsAlpha ? mParent->_getRealAlpha() : ALPHA_MAX);
533 
534  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateAlpha();
535  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateAlpha();
536  for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin) (*skin)->setAlpha(mRealAlpha);
537  }
538 
539  void Widget::setInheritsAlpha(bool _inherits)
540  {
541  mInheritsAlpha = _inherits;
542  // принудительно обновляем
543  float alpha = mAlpha;
544  mAlpha = 101;
545  setAlpha(alpha);
546  }
547 
549  {
550  // проверяем попадание
551  if (!mSubSkinsVisible
552  || !mEnabled
553  || !mVisible
555  || !_checkPoint(_left, _top)
556  // если есть маска, проверяем еще и по маске
557  || ((!mMaskPickInfo->empty()) && (!mMaskPickInfo->pick(IntPoint(_left - mCoord.left, _top - mCoord.top), mCoord))))
558  return nullptr;
559  // спрашиваем у детишек
560  for (VectorWidgetPtr::reverse_iterator widget= mWidgetChild.rbegin(); widget != mWidgetChild.rend(); ++widget)
561  {
562  // общаемся только с послушными детьми
563  if ((*widget)->mWidgetStyle == WidgetStyle::Popup) continue;
564 
565  ILayerItem * item = (*widget)->getLayerItemByPoint(_left - mCoord.left, _top - mCoord.top);
566  if (item != nullptr) return item;
567  }
568  // спрашиваем у детишек скна
569  for (VectorWidgetPtr::reverse_iterator widget= mWidgetChildSkin.rbegin(); widget != mWidgetChildSkin.rend(); ++widget)
570  {
571  ILayerItem * item = (*widget)->getLayerItemByPoint(_left - mCoord.left, _top - mCoord.top);
572  if (item != nullptr) return item;
573  }
574  // непослушные дети
575  return mInheritsPick ? nullptr : this;
576  }
577 
578  void Widget::_updateAbsolutePoint()
579  {
580  // мы рут, нам не надо
581  if (!mCroppedParent) return;
582 
584 
585  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateAbsolutePoint();
586  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateAbsolutePoint();
587  for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin) (*skin)->_correctView();
588  }
589 
590  void Widget::_setUVSet(const FloatRect& _rect)
591  {
592  if (nullptr != mMainSkin) mMainSkin->_setUVSet(_rect);
593  }
594 
595  void Widget::_setTextureName(const std::string& _texture)
596  {
597  //if (_texture == mTextureName) return;
598 
599  mTextureName = _texture;
601 
603  }
604 
605  const std::string& Widget::_getTextureName()
606  {
607  return mTextureName;
608  }
609 
610  void Widget::_setSubSkinVisible(bool _visible)
611  {
612  if (mSubSkinsVisible == _visible) return;
613  mSubSkinsVisible = _visible;
614 
615  // просто обновляем
616  for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin)
617  {
618  (*skin)->_updateView();
619  }
620  }
621 
622  void Widget::_forcePeek(Widget* _widget)
623  {
624  MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget");
625  if (mWidgetClient != nullptr) mWidgetClient->_forcePeek(_widget);
626 
627  size_t size = mWidgetChild.size();
628  if ( (size < 2) || (mWidgetChild[size-1] == _widget) ) return;
629  for (size_t pos=0; pos<size; pos++)
630  {
631  if (mWidgetChild[pos] == _widget)
632  {
633  mWidgetChild[pos] = mWidgetChild[size-1];
634  mWidgetChild[size-1] = _widget;
635  return;
636  }
637  }
638  }
639 
640  const std::string& Widget::getLayerName()
641  {
642  ILayer* layer = getLayer();
643  if (nullptr == layer)
644  {
645  static std::string empty;
646  return empty;
647  }
648  return layer->getName();
649  }
650 
651  void Widget::_getContainer(Widget*& _list, size_t& _index)
652  {
653  _list = nullptr;
654  _index = ITEM_NONE;
655  _requestGetContainer(this, _list, _index);
656  }
657 
658  Widget* Widget::findWidget(const std::string& _name)
659  {
660  if (_name == mName) return this;
661  MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget");
662  if (mWidgetClient != nullptr) return mWidgetClient->findWidget(_name);
663  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
664  {
665  Widget* find = (*widget)->findWidget(_name);
666  if (nullptr != find) return find;
667  }
668  return nullptr;
669  }
670 
671  void Widget::setNeedToolTip(bool _need)
672  {
673  if (mNeedToolTip == _need) return;
674  mNeedToolTip = _need;
675 
676  if (mNeedToolTip)
677  {
678  Gui::getInstance().eventFrameStart += newDelegate(this, &Widget::frameEntered);
680  }
681  else
682  {
683  Gui::getInstance().eventFrameStart -= newDelegate(this, &Widget::frameEntered);
684  }
685  }
686 
687  void Widget::frameEntered(float _frame)
688  {
689  if ( ! mEnableToolTip ) return;
690 
692 
693  if (mToolTipOldPoint != point)
694  {
695 
697 
698  bool inside = getAbsoluteRect().inside(point);
699  if (inside)
700  {
701  inside = false;
702  // проверяем не перекрывают ли нас
704  while (widget != 0)
705  {
706  if (widget/*->getName()*/ == this/*mName*/)
707  {
708  inside = true;
709  break;
710  }
711  // если виджет берет тултип, значит сбрасываем
712  if (widget->getNeedToolTip())
713  widget = 0;//widget->getParent();
714  else
715  widget = widget->getParent();
716  }
717 
718  if (inside)
719  {
720  // теперь смотрим, не поменялся ли индекс внутри окна
721  size_t index = _getContainerIndex(point);
722  if (mToolTipOldIndex != index)
723  {
724  if (mToolTipVisible)
725  {
727  mToolTipVisible = false;
728  eventToolTip(this, ToolTipInfo(ToolTipInfo::Hide));
729  }
730  mToolTipOldIndex = index;
731  }
732 
733  }
734  else
735  {
736  if (mToolTipVisible)
737  {
739  mToolTipVisible = false;
740  eventToolTip(this, ToolTipInfo(ToolTipInfo::Hide));
741  }
742  }
743 
744  }
745  else
746  {
747  if (mToolTipVisible)
748  {
750  mToolTipVisible = false;
751  eventToolTip(this, ToolTipInfo(ToolTipInfo::Hide));
752  }
753  }
754 
755  mToolTipOldPoint = point;
756  }
757  else
758  {
759  bool inside = getAbsoluteRect().inside(point);
760  if (inside)
761  {
762  inside = false;
763  // проверяем не перекрывают ли нас
765  while (widget != 0)
766  {
767  if (widget/*->getName()*/ == this/*mName*/)
768  {
769  inside = true;
770  break;
771  }
772  // если виджет берет тултип, значит сбрасываем
773  if (widget->getNeedToolTip())
774  widget = 0;//widget->getParent();
775  else
776  widget = widget->getParent();
777  }
778 
779  if (inside)
780  {
781  if ( ! mToolTipVisible)
782  {
783  mToolTipCurrentTime += _frame;
785  {
786  mToolTipVisible = true;
787  eventToolTip(this, ToolTipInfo(ToolTipInfo::Show, mToolTipOldIndex, point));
788  }
789  }
790  }
791  }
792  }
793  }
794 
795  void Widget::setEnableToolTip(bool _enable)
796  {
797  if (_enable == mEnableToolTip) return;
798  mEnableToolTip = _enable;
799 
800  if ( ! mEnableToolTip)
801  {
802  if (mToolTipVisible)
803  {
805  mToolTipVisible = false;
807  }
808  }
809  else
810  {
812  }
813  }
814 
815  void Widget::_resetContainer(bool _updateOnly)
816  {
817  if ( mEnableToolTip)
818  {
819  if (mToolTipVisible)
820  {
821  mToolTipVisible = false;
823  }
826  }
827  }
828 
829  void Widget::setMaskPick(const std::string& _filename)
830  {
831  if (mOwnMaskPickInfo.load(_filename))
832  {
834  }
835  else
836  {
837  MYGUI_LOG(Error, "mask not load '" << _filename << "'");
838  }
839  }
840 
842  {
844  }
845 
846  void Widget::setRealSize(const FloatSize& _size)
847  {
849  }
850 
851  void Widget::setRealCoord(const FloatCoord& _coord)
852  {
854  }
855 
856  void Widget::_linkChildWidget(Widget* _widget)
857  {
858  VectorWidgetPtr::iterator iter = std::find(mWidgetChild.begin(), mWidgetChild.end(), _widget);
859  MYGUI_ASSERT(iter == mWidgetChild.end(), "widget already exist");
860  mWidgetChild.push_back(_widget);
861  }
862 
863  void Widget::_unlinkChildWidget(Widget* _widget)
864  {
865  VectorWidgetPtr::iterator iter = std::remove(mWidgetChild.begin(), mWidgetChild.end(), _widget);
866  MYGUI_ASSERT(iter != mWidgetChild.end(), "widget not found");
867  mWidgetChild.erase(iter);
868  }
869 
871  {
872  StaticText* text = this->castType<StaticText>(false);
873  if (text) text->setTextAlign(_align);
874 
875  if (mText != nullptr) mText->setTextAlign(_align);
876  }
877 
879  {
880  StaticText* text = this->castType<StaticText>(false);
881  if (text) return text->getTextAlign();
882 
883  if (mText != nullptr) return mText->getTextAlign();
884  return Align::Default;
885  }
886 
887  void Widget::_setTextColour(const Colour& _colour)
888  {
889  StaticText* text = this->castType<StaticText>(false);
890  if (text) return text->setTextColour(_colour);
891 
892  if (nullptr != mText) mText->setTextColour(_colour);
893  }
894 
896  {
897  StaticText* text = this->castType<StaticText>(false);
898  if (text) return text->getTextColour();
899 
900  return (nullptr == mText) ? Colour::Zero : mText->getTextColour();
901  }
902 
903  void Widget::_setFontName(const std::string& _font)
904  {
905  StaticText* text = this->castType<StaticText>(false);
906  if (text) text->setFontName(_font);
907 
908  if (nullptr != mText) mText->setFontName(_font);
909  }
910 
911  const std::string& Widget::_getFontName()
912  {
913  StaticText* text = this->castType<StaticText>(false);
914  if (text) return text->getFontName();
915 
916  if (nullptr == mText)
917  {
918  static std::string empty;
919  return empty;
920  }
921  return mText->getFontName();
922  }
923 
924  void Widget::_setFontHeight(int _height)
925  {
926  StaticText* text = this->castType<StaticText>(false);
927  if (text) text->setFontHeight(_height);
928 
929  if (nullptr != mText) mText->setFontHeight(_height);
930  }
931 
933  {
934  StaticText* text = this->castType<StaticText>(false);
935  if (text) return text->getFontHeight();
936 
937  return (nullptr == mText) ? 0 : mText->getFontHeight();
938  }
939 
941  {
942  StaticText* text = this->castType<StaticText>(false);
943  if (text) return text->getTextSize();
944 
945  return (nullptr == mText) ? IntSize() : mText->getTextSize();
946  }
947 
949  {
950  StaticText* text = this->castType<StaticText>(false);
951  if (text) return text->getTextRegion();
952 
953  return (nullptr == mText) ? IntCoord() : mText->getCoord();
954  }
955 
956  void Widget::_setAlign(const IntCoord& _oldcoord, bool _update)
957  {
958  // для виджета изменение х у не меняються
959  _setAlign(_oldcoord.size(), _update);
960  }
961 
962  void Widget::_setAlign(const IntSize& _oldsize, bool _update)
963  {
965 
966  bool need_move = false;
967  bool need_size = false;
968  IntCoord coord = mCoord;
969 
970  // первоначальное выравнивание
971  if (mAlign.isHRelative())
972  {
973  coord.left = int((float)size.width * mRelativeCoord.left);
974  coord.width = int((float)size.width * mRelativeCoord.width);
975  }
976  else if (mAlign.isHStretch())
977  {
978  // растягиваем
979  coord.width = mCoord.width + (size.width - _oldsize.width);
980  need_size = true;
981  }
982  else if (mAlign.isRight())
983  {
984  // двигаем по правому краю
985  coord.left = mCoord.left + (size.width - _oldsize.width);
986  need_move = true;
987  }
988  else if (mAlign.isHCenter())
989  {
990  // выравнивание по горизонтали без растяжения
991  coord.left = (size.width - mCoord.width) / 2;
992  need_move = true;
993  }
994 
995  if (mAlign.isVRelative())
996  {
997  coord.top = int((float)size.height * mRelativeCoord.top);
998  coord.height = int((float)size.height * mRelativeCoord.height);
999  }
1000  else if (mAlign.isVStretch())
1001  {
1002  // растягиваем
1003  coord.height = mCoord.height + (size.height - _oldsize.height);
1004  need_size = true;
1005  }
1006  else if (mAlign.isBottom())
1007  {
1008  // двигаем по нижнему краю
1009  coord.top = mCoord.top + (size.height - _oldsize.height);
1010  need_move = true;
1011  }
1012  else if (mAlign.isVCenter())
1013  {
1014  // выравнивание по вертикали без растяжения
1015  coord.top = (size.height - mCoord.height) / 2;
1016  need_move = true;
1017  }
1018 
1019  if (mAlign.isHRelative() || mAlign.isVRelative())
1020  {
1021  mDisableUpdateRelative = true;
1022  setCoord(coord);
1023  mDisableUpdateRelative = false;
1024  }
1025  else if (need_move)
1026  {
1027  if (need_size) setCoord(coord);
1028  else setPosition(coord.point());
1029  }
1030  else if (need_size)
1031  {
1032  setSize(coord.size());
1033  }
1034  else
1035  {
1036  _updateView(); // только если не вызвано передвижение и сайз
1037  }
1038 
1039  }
1040 
1041  void Widget::setPosition(const IntPoint& _point)
1042  {
1043  if (mAlign.isHRelative() || mAlign.isVRelative())
1044  {
1045 
1046  const IntSize& parent_size = mCroppedParent ? mCroppedParent->getSize() : Gui::getInstance().getViewSize();
1047 
1048  if (parent_size.width)
1049  {
1050  mRelativeCoord.left = (float)_point.left / (float)parent_size.width;
1051  }
1052  else
1053  {
1054  mRelativeCoord.left = 0;
1055  }
1056 
1057  if (parent_size.height)
1058  {
1059  mRelativeCoord.top = (float)_point.top / (float)parent_size.height;
1060  }
1061  else
1062  {
1063  mRelativeCoord.top = 0;
1064  }
1065 
1066  }
1067 
1068  // обновляем абсолютные координаты
1069  mAbsolutePosition += _point - mCoord.point();
1070 
1071  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateAbsolutePoint();
1072  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateAbsolutePoint();
1073 
1074  mCoord = _point;
1075 
1076  _updateView();
1077  }
1078 
1079  void Widget::setSize(const IntSize& _size)
1080  {
1081  if (mAlign.isHRelative() || mAlign.isVRelative())
1082  {
1083 
1084  const IntSize& parent_size = mCroppedParent ? mCroppedParent->getSize() : Gui::getInstance().getViewSize();
1085 
1086  if (parent_size.width)
1087  {
1088  mRelativeCoord.width = (float)_size.width / (float)parent_size.width;
1089  }
1090  else
1091  {
1092  mRelativeCoord.width = 0;
1093  }
1094 
1095  if (parent_size.height)
1096  {
1097  mRelativeCoord.height = (float)_size.height / (float)parent_size.height;
1098  }
1099  else
1100  {
1101  mRelativeCoord.height = 0;
1102  }
1103 
1104  }
1105 
1106  // устанавливаем новую координату а старую пускаем в расчеты
1107  IntSize old = mCoord.size();
1108  mCoord = _size;
1109 
1110  bool visible = true;
1111 
1112  // обновляем выравнивание
1113  bool margin = mCroppedParent ? _checkMargin() : false;
1114 
1115  if (margin)
1116  {
1117  // проверка на полный выход за границу
1118  if (_checkOutside())
1119  {
1120  // скрываем
1121  visible = false;
1122  }
1123  }
1124 
1125  _setSubSkinVisible(visible);
1126 
1127  // передаем старую координату , до вызова, текущая координата отца должна быть новой
1128  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_setAlign(old, mIsMargin || margin);
1129  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_setAlign(old, mIsMargin || margin);
1130  for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin) (*skin)->_setAlign(old, mIsMargin || margin);
1131 
1132  // запоминаем текущее состояние
1133  mIsMargin = margin;
1134 
1135  }
1136 
1137  void Widget::setCoord(const IntCoord& _coord)
1138  {
1140  {
1141 
1142  const IntSize& parent_size = mCroppedParent ? mCroppedParent->getSize() : Gui::getInstance().getViewSize();
1143 
1144  if (parent_size.width)
1145  {
1146  mRelativeCoord.left = (float)_coord.left / (float)parent_size.width;
1147  mRelativeCoord.width = (float)_coord.width / (float)parent_size.width;
1148  }
1149  else
1150  {
1151  mRelativeCoord.left = 0;
1152  mRelativeCoord.width = 0;
1153  }
1154 
1155  if (parent_size.height)
1156  {
1157  mRelativeCoord.top = (float)_coord.top / (float)parent_size.height;
1158  mRelativeCoord.height = (float)_coord.height / (float)parent_size.height;
1159  }
1160  else
1161  {
1162  mRelativeCoord.top = 0;
1163  mRelativeCoord.height = 0;
1164  }
1165 
1166  }
1167 
1168  // обновляем абсолютные координаты
1169  mAbsolutePosition += _coord.point() - mCoord.point();
1170 
1171  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateAbsolutePoint();
1172  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateAbsolutePoint();
1173 
1174  // устанавливаем новую координату а старую пускаем в расчеты
1175  IntCoord old = mCoord;
1176  mCoord = _coord;
1177 
1178  bool visible = true;
1179 
1180  // обновляем выравнивание
1181  bool margin = mCroppedParent ? _checkMargin() : false;
1182 
1183  if (margin)
1184  {
1185  // проверка на полный выход за границу
1186  if (_checkOutside())
1187  {
1188  // скрываем
1189  visible = false;
1190  }
1191  }
1192 
1193  _setSubSkinVisible(visible);
1194 
1195  // передаем старую координату , до вызова, текущая координата отца должна быть новой
1196  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_setAlign(old, mIsMargin || margin);
1197  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_setAlign(old, mIsMargin || margin);
1198  for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin) (*skin)->_setAlign(old, mIsMargin || margin);
1199 
1200  // запоминаем текущее состояние
1201  mIsMargin = margin;
1202 
1203  }
1204 
1206  {
1208 
1209  if (mAlign.isHRelative() || mAlign.isVRelative())
1210  {
1211  const IntSize& parent_size = mCroppedParent ? mCroppedParent->getSize() : Gui::getInstance().getViewSize();
1212 
1213  if (parent_size.width)
1214  {
1215  mRelativeCoord.left = (float)mCoord.left / (float)parent_size.width;
1216  mRelativeCoord.width = (float)mCoord.width / (float)parent_size.width;
1217  }
1218  else
1219  {
1220  mRelativeCoord.left = 0;
1221  mRelativeCoord.width = 0;
1222  }
1223 
1224  if (parent_size.height)
1225  {
1226  mRelativeCoord.top = (float)mCoord.top / (float)parent_size.height;
1227  mRelativeCoord.height = (float)mCoord.height / (float)parent_size.height;
1228  }
1229  else
1230  {
1231  mRelativeCoord.top = 0;
1232  mRelativeCoord.height = 0;
1233  }
1234 
1235  }
1236 
1237  }
1238 
1239  void Widget::detachFromWidget(const std::string& _layer)
1240  {
1241  std::string oldlayer = getLayerName();
1242 
1243  Widget* parent = getParent();
1244  if (parent)
1245  {
1246  // отдетачиваемся от лееров
1247  if ( ! isRootWidget() )
1248  {
1250 
1252  {
1253  mParent->removeChildItem(this);
1254  }
1256  {
1257  mParent->removeChildNode(this);
1258  }
1259 
1261 
1262  mCroppedParent = nullptr;
1263 
1264  // обновляем координаты
1266 
1267  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateAbsolutePoint();
1268  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateAbsolutePoint();
1269 
1270  // сбрасываем обрезку
1271  mMargin.clear();
1272 
1273  _updateView();
1274  }
1275 
1276  // нам нужен самый рутовый парент
1277  while (parent->getParent()) { parent = parent->getParent(); }
1278 
1279  mIWidgetCreator = parent->mIWidgetCreator;
1281  mParent->_unlinkChildWidget(this);
1282  mParent = nullptr;
1283  }
1284 
1285  if (!_layer.empty())
1286  {
1288  }
1289  else if (!oldlayer.empty())
1290  {
1291  LayerManager::getInstance().attachToLayerNode(oldlayer, this);
1292  }
1293 
1294  // корректируем параметры
1295  float alpha = mAlpha;
1296  mAlpha = -1;
1297  setAlpha(alpha);
1298 
1299  }
1300 
1301  void Widget::attachToWidget(Widget* _parent, WidgetStyle _style, const std::string& _layer)
1302  {
1303  MYGUI_ASSERT(_parent, "parent must be valid");
1304  MYGUI_ASSERT(_parent != this, "cyclic attach (attaching to self)");
1305 
1306  // attach to client if widget have it
1307  if (_parent->getClientWidget()) _parent = _parent->getClientWidget();
1308 
1309  // проверяем на цикличность атача
1310  Widget* parent = _parent;
1311  while (parent->getParent())
1312  {
1313  MYGUI_ASSERT(parent != this, "cyclic attach");
1314  parent = parent->getParent();
1315  }
1316 
1317  // отдетачиваемся от всего
1318  detachFromWidget();
1319 
1320  mWidgetStyle = _style;
1321 
1322  if (_style == WidgetStyle::Popup)
1323  {
1325  mIWidgetCreator = _parent;
1326  mParent = _parent;
1327  mParent->_linkChildWidget(this);
1328 
1329  mCroppedParent = nullptr;
1330 
1331  if (!_layer.empty())
1332  {
1334  }
1335  }
1336  else if (_style == WidgetStyle::Child)
1337  {
1339 
1341  mIWidgetCreator = _parent;
1342  mParent = _parent;
1343  mParent->_linkChildWidget(this);
1344 
1345  mCroppedParent = _parent;
1347 
1348  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateAbsolutePoint();
1349  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateAbsolutePoint();
1350 
1351  mParent->addChildItem(this);
1352 
1353  _updateView();
1354  }
1355  else if (_style == WidgetStyle::Overlapped)
1356  {
1358 
1360  mIWidgetCreator = _parent;
1361  mParent = _parent;
1362  mParent->_linkChildWidget(this);
1363 
1364  mCroppedParent = _parent;
1366 
1367  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateAbsolutePoint();
1368  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateAbsolutePoint();
1369 
1370  mParent->addChildNode(this);
1371 
1372  _updateView();
1373  }
1374 
1375  // корректируем параметры
1376  float alpha = mAlpha;
1377  mAlpha = -1;
1378  setAlpha(alpha);
1379 
1380  }
1381 
1382  void Widget::setWidgetStyle(WidgetStyle _style, const std::string& _layer)
1383  {
1384  if (_style == mWidgetStyle) return;
1385  if (nullptr == getParent()) return;
1386 
1387  Widget* parent = mParent;
1388 
1389  detachFromWidget();
1390  attachToWidget(parent, _style, _layer);
1391  // ищем леер к которому мы присоедененны
1392  /*Widget* root = this;
1393  while (!root->isRootWidget())
1394  {
1395  root = root->getParent();
1396  }
1397 
1398  // отсоединяем рут
1399  std::string layername;
1400  ILayer* layer = root->getLayer();
1401  if (layer)
1402  {
1403  layername = layer->getName();
1404  LayerManager::getInstance().detachFromLayer(root);
1405 
1406  // если мы рут, то придется отцеплят более высокого рута
1407  if (root == this)
1408  {
1409  layername.clear();
1410 
1411  if (getParent())
1412  {
1413  // ищем леер к которому мы присоедененны
1414  root = getParent();
1415  while (!root->isRootWidget())
1416  {
1417  root = root->getParent();
1418  }
1419 
1420  layer = root->getLayer();
1421  if (layer)
1422  {
1423  layername = layer->getName();
1424  LayerManager::getInstance().detachFromLayer(root);
1425  }
1426 
1427  }
1428  }
1429  }
1430 
1431  // корректируем
1432  mWidgetStyle = _style;
1433  if (_style == WidgetStyle::Child)
1434  {
1435 
1436  Widget* parent = getParent();
1437  if (parent)
1438  {
1439  mAbsolutePosition = parent->getAbsolutePosition() + mCoord.point();
1440  mCroppedParent = parent;
1441  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateAbsolutePoint();
1442  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateAbsolutePoint();
1443  }
1444 
1445  }
1446  else if (_style == WidgetStyle::Popup)
1447  {
1448 
1449  mCroppedParent = nullptr;
1450  // обновляем координаты
1451  mAbsolutePosition = mCoord.point();
1452  // сбрасываем обрезку
1453  mMargin.clear();
1454 
1455  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateAbsolutePoint();
1456  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateAbsolutePoint();
1457 
1458  }
1459  else if (_style == WidgetStyle::Overlapped)
1460  {
1461 
1462  Widget* parent = getParent();
1463  if (parent)
1464  {
1465  mAbsolutePosition = parent->getAbsolutePosition() + mCoord.point();
1466  mCroppedParent = parent;
1467  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget) (*widget)->_updateAbsolutePoint();
1468  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget) (*widget)->_updateAbsolutePoint();
1469  }
1470 
1471  }
1472 
1473  // присоединяем обратно
1474  if (!layername.empty())
1475  {
1476  LayerManager::getInstance().attachToLayerNode(layername, root);
1477  }*/
1478 
1479  }
1480 
1481  void Widget::setCaptionWithNewLine(const std::string& _value)
1482  {
1483  // change '\n' on char 10
1484  size_t pos = _value.find("\\n");
1485  if (pos == std::string::npos)
1486  {
1487  setCaption(LanguageManager::getInstance().replaceTags(_value));
1488  }
1489  else
1490  {
1491  std::string value(_value);
1492  while (pos != std::string::npos)
1493  {
1494  value[pos++] = '\n';
1495  value.erase(pos, 1);
1496  pos = value.find("\\n");
1497  }
1498  setCaption(LanguageManager::getInstance().replaceTags(value));
1499  }
1500  }
1501 
1502  Widget* Widget::createWidgetT(const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _name)
1503  {
1504  return baseCreateWidget(WidgetStyle::Child, _type, _skin, _coord, _align, "", _name);
1505  }
1506 
1507  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)
1508  {
1509  return createWidgetT(_type, _skin, IntCoord(_left, _top, _width, _height), _align, _name);
1510  }
1511 
1512  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)
1513  {
1514  return createWidgetRealT(_type, _skin, FloatCoord(_left, _top, _width, _height), _align, _name);
1515  }
1516 
1517  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)
1518  {
1519  return baseCreateWidget(_style, _type, _skin, _coord, _align, _layer, _name);
1520  }
1521 
1523  {
1524  MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget");
1525  if (mWidgetClient != nullptr) return mWidgetClient->getEnumerator();
1526  return Enumerator<VectorWidgetPtr>(mWidgetChild.begin(), mWidgetChild.end());
1527  }
1528 
1530  {
1531  MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget");
1532  if (mWidgetClient != nullptr) return mWidgetClient->getChildCount();
1533  return mWidgetChild.size();
1534  }
1535 
1536  Widget* Widget::getChildAt(size_t _index)
1537  {
1538  MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget");
1539  if (mWidgetClient != nullptr) return mWidgetClient->getChildAt(_index);
1540  MYGUI_ASSERT_RANGE(_index, mWidgetChild.size(), "Widget::getChildAt");
1541  return mWidgetChild[_index];
1542  }
1543 
1544  const std::string& Widget::getPointer()
1545  {
1546  if (!mEnabled)
1547  {
1548  static std::string empty;
1549  return empty;
1550  }
1551  return mPointer;
1552  }
1553 
1554  void Widget::setProperty(const std::string& _key, const std::string& _value)
1555  {
1557  if (_key == "Widget_Caption") setCaptionWithNewLine(_value);
1559  else if (_key == "Widget_Position") setPosition(utility::parseValue<IntPoint>(_value));
1560  else if (_key == "Widget_Size") setSize(utility::parseValue<IntSize>(_value));
1561  else if (_key == "Widget_Coord") setCoord(utility::parseValue<IntCoord>(_value));
1562  else if (_key == "Widget_Visible") setVisible(utility::parseValue<bool>(_value));
1563  else if (_key == "Widget_Alpha") setAlpha(utility::parseValue<float>(_value));
1564  else if (_key == "Widget_Colour") setColour(utility::parseValue<Colour>(_value));
1565  else if (_key == "Widget_InheritsAlpha") setInheritsAlpha(utility::parseValue<bool>(_value));
1566  else if (_key == "Widget_InheritsPick") setInheritsPick(utility::parseValue<bool>(_value));
1567  else if (_key == "Widget_MaskPick") setMaskPick(_value);
1568  else if (_key == "Widget_State") setState(_value);
1569  else if (_key == "Widget_NeedKey") setNeedKeyFocus(utility::parseValue<bool>(_value));
1570  else if (_key == "Widget_NeedMouse") setNeedMouseFocus(utility::parseValue<bool>(_value));
1571  else if (_key == "Widget_Enabled") setEnabled(utility::parseValue<bool>(_value));
1572  else if (_key == "Widget_NeedToolTip") setNeedToolTip(utility::parseValue<bool>(_value));
1573  else if (_key == "Widget_Pointer") setPointer(_value);
1574 
1575 #ifndef MYGUI_DONT_USE_OBSOLETE
1576  else if (_key == "Widget_TextColour")
1577  {
1578  MYGUI_LOG(Warning, "Widget_TextColour is obsolete, use Text_TextColour");
1579  _setTextColour(Colour::parse(_value));
1580  }
1581  else if (_key == "Widget_FontName")
1582  {
1583  MYGUI_LOG(Warning, "Widget_FontName is obsolete, use Text_FontName");
1584  _setFontName(_value);
1585  }
1586  else if (_key == "Widget_FontHeight")
1587  {
1588  MYGUI_LOG(Warning, "Widget_FontHeight is obsolete, use Text_FontHeight");
1589  this->_setFontHeight(utility::parseValue<int>(_value));
1590  }
1591  else if (_key == "Widget_TextAlign")
1592  {
1593  MYGUI_LOG(Warning, "Widget_TextAlign is obsolete, use Text_TextAlign");
1594  _setTextAlign(Align::parse(_value));
1595  }
1596  else if (_key == "Widget_AlignText")
1597  {
1598  MYGUI_LOG(Warning, "Widget_AlignText is obsolete, use Text_TextAlign");
1599  _setTextAlign(Align::parse(_value));
1600  }
1601  else if (_key == "Widget_Show")
1602  {
1603  MYGUI_LOG(Warning, "Widget_Show is obsolete, use Widget_Visible");
1604  setVisible(utility::parseValue<bool>(_value));
1605  }
1606  else if (_key == "Widget_InheritsPeek")
1607  {
1608  MYGUI_LOG(Warning, "Widget_InheritsPeek is obsolete, use Widget_InheritsPick");
1609  setInheritsPick(utility::parseValue<bool>(_value));
1610  }
1611  else if (_key == "Widget_MaskPeek")
1612  {
1613  MYGUI_LOG(Warning, "Widget_MaskPeek is obsolete, use Widget_MaskPick");
1614  setMaskPick(_value);
1615  }
1616 #endif // MYGUI_DONT_USE_OBSOLETE
1617 
1618  else
1619  {
1620  MYGUI_LOG(Warning, "Property " << _key << " not found");
1621  return;
1622  }
1623 
1624  eventChangeProperty(this, _key, _value);
1625  }
1626 
1628  {
1629  if (mEnabled)
1630  {
1631  setState("normal");
1632  }
1633  else
1634  {
1635  setState("disabled");
1636  }
1637  }
1638 
1639  void Widget::setVisible(bool _value)
1640  {
1641  if (mVisible == _value) return;
1642  mVisible = _value;
1643 
1644  if (mInheritsVisible)
1645  {
1646  for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin)
1647  (*skin)->setVisible(_value);
1648  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
1649  (*widget)->_setInheritsVisible(_value);
1650  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget)
1651  (*widget)->_setInheritsVisible(_value);
1652  }
1653 
1654  }
1655 
1656  void Widget::_setInheritsVisible(bool _value)
1657  {
1658  if (mInheritsVisible == _value) return;
1659  mInheritsVisible = _value;
1660 
1661  if (mVisible)
1662  {
1663  for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin)
1664  (*skin)->setVisible(_value);
1665  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
1666  (*widget)->_setInheritsVisible(_value);
1667  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget)
1668  (*widget)->_setInheritsVisible(_value);
1669  }
1670  }
1671 
1672  void Widget::setEnabled(bool _value)
1673  {
1674  if (mEnabled == _value) return;
1675  mEnabled = _value;
1676 
1677  if (mInheritsEnabled)
1678  {
1679  for (VectorWidgetPtr::iterator iter = mWidgetChild.begin(); iter != mWidgetChild.end(); ++iter)
1680  (*iter)->_setInheritsEnable(_value);
1681  for (VectorWidgetPtr::iterator iter = mWidgetChildSkin.begin(); iter != mWidgetChildSkin.end(); ++iter)
1682  (*iter)->_setInheritsEnable(_value);
1683 
1684  baseUpdateEnable();
1685  }
1686 
1687  if (!mEnabled)
1688  {
1690  }
1691  }
1692 
1693  void Widget::_setInheritsEnable(bool _value)
1694  {
1695  if (mInheritsEnabled == _value) return;
1696  mInheritsEnabled = _value;
1697 
1698  if (mEnabled)
1699  {
1700  for (VectorWidgetPtr::iterator iter = mWidgetChild.begin(); iter != mWidgetChild.end(); ++iter)
1701  (*iter)->_setInheritsEnable(_value);
1702  for (VectorWidgetPtr::iterator iter = mWidgetChildSkin.begin(); iter != mWidgetChildSkin.end(); ++iter)
1703  (*iter)->_setInheritsEnable(_value);
1704 
1705  baseUpdateEnable();
1706  }
1707 
1708  if (!mEnabled)
1709  {
1711  }
1712  }
1713 
1714  void Widget::setColour(const Colour& _value)
1715  {
1716  for (VectorSubWidget::iterator skin = mSubSkinChild.begin(); skin != mSubSkinChild.end(); ++skin)
1717  {
1718  ISubWidgetRect* rect = (*skin)->castType<ISubWidgetRect>(false);
1719  if (rect)
1720  rect->_setColour(_value);
1721  }
1722  }
1723 
1724 } // namespace MyGUI