MyGUI  3.2.1
MyGUI_Widget.cpp
Go to the documentation of this file.
1 /*
2  * This source file is part of MyGUI. For the latest info, see http://mygui.info/
3  * Distributed under the MIT License
4  * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
5  */
6 
7 #include "MyGUI_Precompiled.h"
8 #include "MyGUI_Widget.h"
9 #include "MyGUI_Gui.h"
10 #include "MyGUI_InputManager.h"
11 #include "MyGUI_SkinManager.h"
12 #include "MyGUI_SubWidgetManager.h"
13 #include "MyGUI_WidgetManager.h"
14 #include "MyGUI_ResourceSkin.h"
15 #include "MyGUI_WidgetDefines.h"
16 #include "MyGUI_LayerItem.h"
17 #include "MyGUI_LayerManager.h"
18 #include "MyGUI_RenderItem.h"
19 #include "MyGUI_ISubWidget.h"
20 #include "MyGUI_ISubWidgetText.h"
21 #include "MyGUI_TextBox.h"
22 #include "MyGUI_FactoryManager.h"
23 #include "MyGUI_CoordConverter.h"
24 #include "MyGUI_RenderManager.h"
25 #include "MyGUI_ToolTipManager.h"
26 #include "MyGUI_LayoutManager.h"
27 
28 namespace MyGUI
29 {
30 
32  mWidgetClient(nullptr),
33  mEnabled(true),
34  mInheritsEnabled(true),
35  mInheritsVisible(true),
36  mAlpha(ALPHA_MAX),
37  mRealAlpha(ALPHA_MAX),
38  mInheritsAlpha(true),
39  mParent(nullptr),
40  mWidgetStyle(WidgetStyle::Child),
41  mContainer(nullptr),
42  mAlign(Align::Default),
43  mVisible(true),
44  mDepth(0)
45  {
46  }
47 
49  {
50  }
51 
52  void Widget::_initialise(WidgetStyle _style, const IntCoord& _coord, const std::string& _skinName, Widget* _parent, ICroppedRectangle* _croppedParent, const std::string& _name)
53  {
54  ResourceSkin* skinInfo = nullptr;
55  ResourceLayout* templateInfo = nullptr;
56 
57  if (LayoutManager::getInstance().isExist(_skinName))
58  templateInfo = LayoutManager::getInstance().getByName(_skinName);
59  else
60  skinInfo = SkinManager::getInstance().getByName(_skinName);
61 
62  mCoord = _coord;
63 
64  mAlign = Align::Default;
65  mWidgetStyle = _style;
66  mName = _name;
67 
68  mCroppedParent = _croppedParent;
69  mParent = _parent;
70 
71 
72 #if MYGUI_DEBUG_MODE == 1
73  // проверяем соответсвие входных данных
74  if (mWidgetStyle == WidgetStyle::Child)
75  {
76  MYGUI_ASSERT(mCroppedParent, "must be cropped");
77  MYGUI_ASSERT(mParent, "must be parent");
78  }
79  else if (mWidgetStyle == WidgetStyle::Overlapped)
80  {
81  MYGUI_ASSERT((mParent == nullptr) == (mCroppedParent == nullptr), "error cropped");
82  }
83  else if (mWidgetStyle == WidgetStyle::Popup)
84  {
85  MYGUI_ASSERT(!mCroppedParent, "cropped must be nullptr");
86  MYGUI_ASSERT(mParent, "must be parent");
87  }
88 #endif
89 
90  // корректируем абсолютные координаты
91  mAbsolutePosition = _coord.point();
92 
93  if (nullptr != mCroppedParent)
95 
96  const WidgetInfo* root = initialiseWidgetSkinBase(skinInfo, templateInfo);
97 
98  // дочернее окно обыкновенное
99  if (mWidgetStyle == WidgetStyle::Child)
100  {
101  if (mParent)
102  mParent->addChildItem(this);
103  }
104  // дочернее нуно перекрывающееся
105  else if (mWidgetStyle == WidgetStyle::Overlapped)
106  {
107  // дочернее перекрывающееся
108  if (mParent)
109  mParent->addChildNode(this);
110  }
111 
112  // витр метод для наследников
114 
115  if (skinInfo != nullptr)
116  setSkinProperty(skinInfo);
117 
118  if (root != nullptr)
119  {
120  for (VectorStringPairs::const_iterator iter = root->properties.begin(); iter != root->properties.end(); ++iter)
121  {
122  setProperty(iter->first, iter->second);
123  }
124  }
125  }
126 
128  {
129  // витр метод для наследников
131 
132  shutdownWidgetSkinBase();
133 
135 
136  // дочернее окно обыкновенное
137  if (mWidgetStyle == WidgetStyle::Child)
138  {
139  if (mParent)
140  mParent->removeChildItem(this);
141  }
142  // дочернее нуно перекрывающееся
143  else if (mWidgetStyle == WidgetStyle::Overlapped)
144  {
145  // дочернее перекрывающееся
146  if (mParent)
147  mParent->removeChildNode(this);
148  }
149 
150  mParent = nullptr;
151  mCroppedParent = nullptr;
152  }
153 
154  void Widget::changeWidgetSkin(const std::string& _skinName)
155  {
156  ResourceSkin* skinInfo = nullptr;
157  ResourceLayout* templateInfo = nullptr;
158 
159  if (LayoutManager::getInstance().isExist(_skinName))
160  templateInfo = LayoutManager::getInstance().getByName(_skinName);
161  else
162  skinInfo = SkinManager::getInstance().getByName(_skinName);
163 
165 
166  saveLayerItem();
167 
168  shutdownWidgetSkinBase();
169  const WidgetInfo* root = initialiseWidgetSkinBase(skinInfo, templateInfo);
170 
172 
174 
175  if (skinInfo != nullptr)
176  setSkinProperty(skinInfo);
177 
178  if (root != nullptr)
179  {
180  for (VectorStringPairs::const_iterator iter = root->properties.begin(); iter != root->properties.end(); ++iter)
181  {
182  setProperty(iter->first, iter->second);
183  }
184  }
185  }
186 
187  const WidgetInfo* Widget::initialiseWidgetSkinBase(ResourceSkin* _skinInfo, ResourceLayout* _templateInfo)
188  {
189  const WidgetInfo* root = nullptr;
190  bool skinOnly = false;
191 
192  if (_skinInfo == nullptr)
193  {
194  skinOnly = true;
195  std::string skinName;
196 
197  const VectorWidgetInfo& data = _templateInfo->getLayoutData();
198  for (VectorWidgetInfo::const_iterator item = data.begin(); item != data.end(); ++item)
199  {
200  if ((*item).name == "Root")
201  {
202  skinName = (*item).skin;
203  root = &(*item);
204  break;
205  }
206  }
207 
208  _skinInfo = SkinManager::getInstance().getByName(skinName);
209  }
210 
211  //SAVE
212  const IntSize& _size = mCoord.size();
213 
214  if (_skinInfo != nullptr)
215  {
216  //FIXME - явный вызов
217  Widget::setSize(_skinInfo->getSize());
218 
219  _createSkinItem(_skinInfo);
220  }
221 
222  // выставляем альфу, корректировка по отцу автоматически
223  _updateAlpha();
224  _updateEnabled();
225  _updateVisible();
226 
227  if (!skinOnly)
228  {
229  const MapString& properties = _skinInfo->getProperties();
230  for (MapString::const_iterator item = properties.begin(); item != properties.end(); ++item)
231  {
232  if (BackwardCompatibility::isIgnoreProperty((*item).first))
233  setUserString((*item).first, (*item).second);
234  }
235 
236  // создаем детей скина
237  const VectorChildSkinInfo& child = _skinInfo->getChild();
238  for (VectorChildSkinInfo::const_iterator iter = child.begin(); iter != child.end(); ++iter)
239  {
240  Widget* widget = baseCreateWidget(iter->style, iter->type, iter->skin, iter->coord, iter->align, iter->layer, iter->name, true);
241  // заполняем UserString пропертями
242  for (MapString::const_iterator prop = iter->params.begin(); prop != iter->params.end(); ++prop)
243  widget->setUserString(prop->first, prop->second);
244  }
245  }
246 
247  if (root != nullptr)
248  {
249  //FIXME - явный вызов
250  Widget::setSize(root->intCoord.size());
251 
252  for (MapString::const_iterator iter = root->userStrings.begin(); iter != root->userStrings.end(); ++iter)
253  {
254  setUserString(iter->first, iter->second);
255  }
256 
257  for (VectorWidgetInfo::const_iterator iter = root->childWidgetsInfo.begin(); iter != root->childWidgetsInfo.end(); ++iter)
258  {
259  _templateInfo->createWidget(*iter, "", this, true);
260  }
261  }
262 
263  //FIXME - явный вызов
264  Widget::setSize(_size);
265 
266  return root;
267  }
268 
269  void Widget::shutdownWidgetSkinBase()
270  {
271  setMaskPick("");
272 
273  _deleteSkinItem();
274 
275  // удаляем виджеты чтобы ли в скине
276  for (VectorWidgetPtr::iterator iter = mWidgetChildSkin.begin(); iter != mWidgetChildSkin.end(); ++iter)
277  {
278  // Добавляем себя чтобы удалилось
279  mWidgetChild.push_back(*iter);
280  _destroyChildWidget(*iter);
281  }
282  mWidgetChildSkin.clear();
283 
284  mWidgetClient = nullptr;
285  }
286 
287  Widget* Widget::baseCreateWidget(WidgetStyle _style, const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _layer, const std::string& _name, bool _template)
288  {
289  Widget* widget = nullptr;
290 
291  if (_template)
292  {
293  widget = WidgetManager::getInstance().createWidget(_style, _type, _skin, _coord, this, _style == WidgetStyle::Popup ? nullptr : this, _name);
294  mWidgetChildSkin.push_back(widget);
295  }
296  else
297  {
298  if (mWidgetClient != nullptr)
299  {
300  widget = mWidgetClient->baseCreateWidget(_style, _type, _skin, _coord, _align, _layer, _name, _template);
301  onWidgetCreated(widget);
302  return widget;
303  }
304  else
305  {
306  widget = WidgetManager::getInstance().createWidget(_style, _type, _skin, _coord, this, _style == WidgetStyle::Popup ? nullptr : this, _name);
307  addWidget(widget);
308  }
309  }
310 
311  widget->setAlign(_align);
312 
313  // присоединяем виджет с уровню
314  if (!_layer.empty() && widget->isRootWidget())
316 
317  onWidgetCreated(widget);
318 
319  return widget;
320  }
321 
322  Widget* Widget::createWidgetRealT(const std::string& _type, const std::string& _skin, const FloatCoord& _coord, Align _align, const std::string& _name)
323  {
324  return createWidgetT(_type, _skin, CoordConverter::convertFromRelative(_coord, getSize()), _align, _name);
325  }
326 
328  {
329  bool margin = mCroppedParent ? _checkMargin() : false;
330 
331  // вьюпорт стал битым
332  if (margin)
333  {
334  // проверка на полный выход за границу
335  if (_checkOutside())
336  {
337  // запоминаем текущее состояние
338  mIsMargin = margin;
339 
340  // скрываем
341  _setSubSkinVisible(false);
342 
343  // вся иерархия должна быть проверенна
344  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
345  (*widget)->_updateView();
346  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget)
347  (*widget)->_updateView();
348 
349  return;
350  }
351  }
352  // мы не обрезаны и были нормальные
353  else if (!mIsMargin)
354  {
356  return;
357  }
358 
359  // запоминаем текущее состояние
360  mIsMargin = margin;
361 
362  // если скин был скрыт, то покажем
363  _setSubSkinVisible(true);
364 
365  // обновляем наших детей, а они уже решат обновлять ли своих детей
366  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
367  (*widget)->_updateView();
368  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget)
369  (*widget)->_updateView();
370 
372  }
373 
374  bool Widget::_setWidgetState(const std::string& _state)
375  {
376  return _setSkinItemState(_state);
377  }
378 
380  {
381  MYGUI_ASSERT(nullptr != _widget, "invalid widget pointer");
382 
383  if (mParent != nullptr && mParent->getClientWidget() == this)
384  mParent->onWidgetDestroy(_widget);
385 
386  onWidgetDestroy(_widget);
387 
388  VectorWidgetPtr::iterator iter = std::find(mWidgetChild.begin(), mWidgetChild.end(), _widget);
389  if (iter != mWidgetChild.end())
390  {
391  // сохраняем указатель
392  MyGUI::Widget* widget = *iter;
393 
394  // удаляем из списка
395  mWidgetChild.erase(iter);
396 
397  // отписываем от всех
399 
400  // непосредственное удаление
402  }
403  else
404  {
405  MYGUI_EXCEPT("Widget '" << _widget->getName() << "' not found");
406  }
407  }
408 
409  // удаляет всех детей
411  {
413  while (!mWidgetChild.empty())
414  {
415  // сразу себя отписывем, иначе вложенной удаление убивает все
416  Widget* widget = mWidgetChild.back();
417  mWidgetChild.pop_back();
418 
419  // отписываем от всех
420  manager.unlinkFromUnlinkers(widget);
421 
422  // и сами удалим, так как его больше в списке нет
424  }
425  }
426 
428  {
429  MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget");
430  if (mWidgetClient != nullptr)
431  return mWidgetClient->getCoord();
432  return IntCoord(0, 0, mCoord.width, mCoord.height);
433  }
434 
435  void Widget::setAlpha(float _alpha)
436  {
437  if (mAlpha == _alpha)
438  return;
439  mAlpha = _alpha;
440 
441  _updateAlpha();
442  }
443 
444  void Widget::_updateAlpha()
445  {
446  if (nullptr != mParent)
447  mRealAlpha = mAlpha * (mInheritsAlpha ? mParent->_getRealAlpha() : ALPHA_MAX);
448  else
449  mRealAlpha = mAlpha;
450 
451  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
452  (*widget)->_updateAlpha();
453  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget)
454  (*widget)->_updateAlpha();
455 
456  _setSkinItemAlpha(mRealAlpha);
457  }
458 
459  void Widget::setInheritsAlpha(bool _inherits)
460  {
461  mInheritsAlpha = _inherits;
462  _updateAlpha();
463  }
464 
465  ILayerItem* Widget::getLayerItemByPoint(int _left, int _top) const
466  {
467  // проверяем попадание
468  if (!mEnabled
469  || !mVisible
470  || (!getNeedMouseFocus() && !getInheritsPick())
471  || !_checkPoint(_left, _top)
472  // если есть маска, проверяем еще и по маске
473  || !isMaskPickInside(IntPoint(_left - mCoord.left, _top - mCoord.top), mCoord)
474  )
475  return nullptr;
476 
477  // спрашиваем у детишек
478  for (VectorWidgetPtr::const_reverse_iterator widget = mWidgetChild.rbegin(); widget != mWidgetChild.rend(); ++widget)
479  {
480  // общаемся только с послушными детьми
481  if ((*widget)->mWidgetStyle == WidgetStyle::Popup)
482  continue;
483 
484  ILayerItem* item = (*widget)->getLayerItemByPoint(_left - mCoord.left, _top - mCoord.top);
485  if (item != nullptr)
486  return item;
487  }
488  // спрашиваем у детишек скина
489  for (VectorWidgetPtr::const_reverse_iterator widget = mWidgetChildSkin.rbegin(); widget != mWidgetChildSkin.rend(); ++widget)
490  {
491  ILayerItem* item = (*widget)->getLayerItemByPoint(_left - mCoord.left, _top - mCoord.top);
492  if (item != nullptr)
493  return item;
494  }
495 
496  // непослушные дети
497  return getInheritsPick() ? nullptr : const_cast<Widget*>(this);
498  }
499 
500  void Widget::_updateAbsolutePoint()
501  {
502  // мы рут, нам не надо
503  if (!mCroppedParent)
504  return;
505 
507 
508  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
509  (*widget)->_updateAbsolutePoint();
510  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget)
511  (*widget)->_updateAbsolutePoint();
512 
514  }
515 
516  void Widget::_forcePick(Widget* _widget)
517  {
518  MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget");
519  if (mWidgetClient != nullptr)
520  {
521  mWidgetClient->_forcePick(_widget);
522  return;
523  }
524 
525  VectorWidgetPtr::iterator iter = std::find(mWidgetChild.begin(), mWidgetChild.end(), _widget);
526  if (iter == mWidgetChild.end())
527  return;
528 
529  VectorWidgetPtr copy = mWidgetChild;
530  for (VectorWidgetPtr::iterator widget = copy.begin(); widget != copy.end(); ++widget)
531  {
532  if ((*widget) == _widget)
533  (*widget)->setDepth(-1);
534  else if ((*widget)->getDepth() == -1)
535  (*widget)->setDepth(0);
536  }
537  }
538 
539  Widget* Widget::findWidget(const std::string& _name)
540  {
541  if (_name == mName)
542  return this;
543  MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget");
544  if (mWidgetClient != nullptr)
545  return mWidgetClient->findWidget(_name);
546 
547  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
548  {
549  Widget* find = (*widget)->findWidget(_name);
550  if (nullptr != find)
551  return find;
552  }
553  return nullptr;
554  }
555 
557  {
559  }
560 
561  void Widget::setRealSize(const FloatSize& _size)
562  {
564  }
565 
566  void Widget::setRealCoord(const FloatCoord& _coord)
567  {
569  }
570 
571  void Widget::_setAlign(const IntSize& _oldsize, const IntSize& _newSize)
572  {
573  const IntSize& size = _newSize;//getParentSize();
574 
575  bool need_move = false;
576  bool need_size = false;
577  IntCoord coord = mCoord;
578 
579  // первоначальное выравнивание
580  if (mAlign.isHStretch())
581  {
582  // растягиваем
583  coord.width = mCoord.width + (size.width - _oldsize.width);
584  need_size = true;
585  }
586  else if (mAlign.isRight())
587  {
588  // двигаем по правому краю
589  coord.left = mCoord.left + (size.width - _oldsize.width);
590  need_move = true;
591  }
592  else if (mAlign.isHCenter())
593  {
594  // выравнивание по горизонтали без растяжения
595  coord.left = (size.width - mCoord.width) / 2;
596  need_move = true;
597  }
598 
599  if (mAlign.isVStretch())
600  {
601  // растягиваем
602  coord.height = mCoord.height + (size.height - _oldsize.height);
603  need_size = true;
604  }
605  else if (mAlign.isBottom())
606  {
607  // двигаем по нижнему краю
608  coord.top = mCoord.top + (size.height - _oldsize.height);
609  need_move = true;
610  }
611  else if (mAlign.isVCenter())
612  {
613  // выравнивание по вертикали без растяжения
614  coord.top = (size.height - mCoord.height) / 2;
615  need_move = true;
616  }
617 
618  if (need_move)
619  {
620  if (need_size)
621  setCoord(coord);
622  else
623  setPosition(coord.point());
624  }
625  else if (need_size)
626  {
627  setSize(coord.size());
628  }
629  else
630  {
631  _updateView(); // только если не вызвано передвижение и сайз
632  }
633  }
634 
635  void Widget::setPosition(const IntPoint& _point)
636  {
637  // обновляем абсолютные координаты
638  mAbsolutePosition += _point - mCoord.point();
639 
640  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
641  (*widget)->_updateAbsolutePoint();
642  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget)
643  (*widget)->_updateAbsolutePoint();
644 
645  mCoord = _point;
646 
647  _updateView();
648 
649  eventChangeCoord(this);
650  }
651 
652  void Widget::setSize(const IntSize& _size)
653  {
654  // устанавливаем новую координату а старую пускаем в расчеты
655  IntSize old = mCoord.size();
656  mCoord = _size;
657 
658  bool visible = true;
659 
660  // обновляем выравнивание
661  bool margin = mCroppedParent ? _checkMargin() : false;
662 
663  if (margin)
664  {
665  // проверка на полный выход за границу
666  if (_checkOutside())
667  {
668  // скрываем
669  visible = false;
670  }
671  }
672 
673  _setSubSkinVisible(visible);
674 
675  // передаем старую координату , до вызова, текущая координата отца должна быть новой
676  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
677  (*widget)->_setAlign(old, getSize());
678  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget)
679  (*widget)->_setAlign(old, getSize());
680 
681  _setSkinItemAlign(old);
682 
683  // запоминаем текущее состояние
684  mIsMargin = margin;
685 
686  eventChangeCoord(this);
687  }
688 
689  void Widget::setCoord(const IntCoord& _coord)
690  {
691  // обновляем абсолютные координаты
692  mAbsolutePosition += _coord.point() - mCoord.point();
693 
694  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
695  (*widget)->_updateAbsolutePoint();
696  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget)
697  (*widget)->_updateAbsolutePoint();
698 
699  // устанавливаем новую координату а старую пускаем в расчеты
700  IntCoord old = mCoord;
701  mCoord = _coord;
702 
703  bool visible = true;
704 
705  // обновляем выравнивание
706  bool margin = mCroppedParent ? _checkMargin() : false;
707 
708  if (margin)
709  {
710  // проверка на полный выход за границу
711  if (_checkOutside())
712  {
713  // скрываем
714  visible = false;
715  }
716  }
717 
718  _setSubSkinVisible(visible);
719 
720  // передаем старую координату , до вызова, текущая координата отца должна быть новой
721  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
722  (*widget)->_setAlign(old.size(), getSize());
723  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget)
724  (*widget)->_setAlign(old.size(), getSize());
725 
726  _setSkinItemAlign(old.size());
727 
728  // запоминаем текущее состояние
729  mIsMargin = margin;
730 
731  eventChangeCoord(this);
732  }
733 
734  void Widget::setAlign(Align _value)
735  {
736  mAlign = _value;
737  }
738 
739  void Widget::detachFromWidget(const std::string& _layer)
740  {
741  std::string oldlayer = getLayer() != nullptr ? getLayer()->getName() : "";
742 
743  Widget* parent = getParent();
744  if (parent)
745  {
746  // отдетачиваемся от лееров
747  if ( ! isRootWidget() )
748  {
750 
751  if (mWidgetStyle == WidgetStyle::Child)
752  {
753  mParent->removeChildItem(this);
754  }
755  else if (mWidgetStyle == WidgetStyle::Overlapped)
756  {
757  mParent->removeChildNode(this);
758  }
759 
760  mWidgetStyle = WidgetStyle::Overlapped;
761 
762  mCroppedParent = nullptr;
763 
764  // обновляем координаты
766 
767  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
768  (*widget)->_updateAbsolutePoint();
769  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget)
770  (*widget)->_updateAbsolutePoint();
771 
772  // сбрасываем обрезку
773  mMargin.clear();
774 
775  _updateView();
776  }
777 
778  // нам нужен самый рутовый парент
779  while (parent->getParent())
780  parent = parent->getParent();
781 
782  //mIWidgetCreator = parent->mIWidgetCreator;
783  //mIWidgetCreator->_linkChildWidget(this);
785  mParent->_unlinkChildWidget(this);
786  mParent = nullptr;
787  }
788 
789  if (!_layer.empty())
790  {
792  }
793  else if (!oldlayer.empty())
794  {
796  }
797 
798  _updateAlpha();
799  }
800 
801  void Widget::attachToWidget(Widget* _parent, WidgetStyle _style, const std::string& _layer)
802  {
803  MYGUI_ASSERT(_parent, "parent must be valid");
804  MYGUI_ASSERT(_parent != this, "cyclic attach (attaching to self)");
805 
806  // attach to client if widget have it
807  if (_parent->getClientWidget())
808  _parent = _parent->getClientWidget();
809 
810  // проверяем на цикличность атача
811  Widget* parent = _parent;
812  while (parent->getParent())
813  {
814  MYGUI_ASSERT(parent != this, "cyclic attach");
815  parent = parent->getParent();
816  }
817 
818  // отдетачиваемся от всего
820 
821  mWidgetStyle = _style;
822 
823  if (_style == WidgetStyle::Popup)
824  {
825  //mIWidgetCreator->_unlinkChildWidget(this);
826  //mIWidgetCreator = _parent;
827  if (mParent == nullptr)
829  else
830  mParent->_unlinkChildWidget(this);
831 
832  mParent = _parent;
833  mParent->_linkChildWidget(this);
834 
835  mCroppedParent = nullptr;
836 
837  if (!_layer.empty())
838  {
840  }
841  }
842  else if (_style == WidgetStyle::Child)
843  {
845 
846  //mIWidgetCreator->_unlinkChildWidget(this);
847  //mIWidgetCreator = _parent;
848  if (mParent == nullptr)
850  else
851  mParent->_unlinkChildWidget(this);
852 
853  mParent = _parent;
854  mParent->_linkChildWidget(this);
855 
856  mCroppedParent = _parent;
858 
859  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
860  (*widget)->_updateAbsolutePoint();
861  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget)
862  (*widget)->_updateAbsolutePoint();
863 
864  mParent->addChildItem(this);
865 
866  _updateView();
867  }
868  else if (_style == WidgetStyle::Overlapped)
869  {
871 
872  //mIWidgetCreator->_unlinkChildWidget(this);
873  //mIWidgetCreator = _parent;
874  if (mParent == nullptr)
876  else
877  mParent->_unlinkChildWidget(this);
878 
879  mParent = _parent;
880  mParent->_linkChildWidget(this);
881 
882  mCroppedParent = _parent;
884 
885  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
886  (*widget)->_updateAbsolutePoint();
887  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget)
888  (*widget)->_updateAbsolutePoint();
889 
890  mParent->addChildNode(this);
891 
892  _updateView();
893  }
894 
895  _updateAlpha();
896  }
897 
898  void Widget::setWidgetStyle(WidgetStyle _style, const std::string& _layer)
899  {
900  if (_style == mWidgetStyle)
901  return;
902  if (nullptr == getParent())
903  return;
904 
905  Widget* parent = mParent;
906 
908  attachToWidget(parent, _style, _layer);
909  // ищем леер к которому мы присоедененны
910  }
911 
912  Widget* Widget::createWidgetT(const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _name)
913  {
914  return baseCreateWidget(WidgetStyle::Child, _type, _skin, _coord, _align, "", _name, false);
915  }
916 
917  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)
918  {
919  return createWidgetT(_type, _skin, IntCoord(_left, _top, _width, _height), _align, _name);
920  }
921 
922  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)
923  {
924  return createWidgetRealT(_type, _skin, FloatCoord(_left, _top, _width, _height), _align, _name);
925  }
926 
927  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)
928  {
929  return baseCreateWidget(_style, _type, _skin, _coord, _align, _layer, _name, false);
930  }
931 
933  {
934  MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget");
935  if (mWidgetClient != nullptr)
936  return mWidgetClient->getEnumerator();
937  return Enumerator<VectorWidgetPtr>(mWidgetChild.begin(), mWidgetChild.end());
938  }
939 
941  {
942  MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget");
943  if (mWidgetClient != nullptr)
944  return mWidgetClient->getChildCount();
945  return mWidgetChild.size();
946  }
947 
948  Widget* Widget::getChildAt(size_t _index)
949  {
950  MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget");
951  if (mWidgetClient != nullptr)
952  return mWidgetClient->getChildAt(_index);
953  MYGUI_ASSERT_RANGE(_index, mWidgetChild.size(), "Widget::getChildAt");
954  return mWidgetChild[_index];
955  }
956 
958  {
959  if (getInheritedEnabled())
960  _setWidgetState("normal");
961  else
962  _setWidgetState("disabled");
963  }
964 
965  void Widget::setVisible(bool _value)
966  {
967  if (mVisible == _value)
968  return;
969  mVisible = _value;
970 
971  _updateVisible();
972  }
973 
974  void Widget::_updateVisible()
975  {
976  mInheritsVisible = mParent == nullptr || (mParent->getVisible() && mParent->getInheritedVisible());
977  bool value = mVisible && mInheritsVisible;
978 
979  _setSkinItemVisible(value);
980 
981  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
982  (*widget)->_updateVisible();
983  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget)
984  (*widget)->_updateVisible();
985 
986  if (!value && InputManager::getInstance().getMouseFocusWidget() == this)
988  if (!value && InputManager::getInstance().getKeyFocusWidget() == this)
990  }
991 
992  void Widget::setEnabled(bool _value)
993  {
994  if (mEnabled == _value)
995  return;
996  mEnabled = _value;
997 
998  _updateEnabled();
999  }
1000 
1001  void Widget::_updateEnabled()
1002  {
1003  mInheritsEnabled = mParent == nullptr || (mParent->getInheritedEnabled());
1004  mInheritsEnabled = mInheritsEnabled && mEnabled;
1005 
1006  for (VectorWidgetPtr::iterator iter = mWidgetChild.begin(); iter != mWidgetChild.end(); ++iter)
1007  (*iter)->_updateEnabled();
1008  for (VectorWidgetPtr::iterator iter = mWidgetChildSkin.begin(); iter != mWidgetChildSkin.end(); ++iter)
1009  (*iter)->_updateEnabled();
1010 
1011  baseUpdateEnable();
1012 
1013  if (!mInheritsEnabled)
1015  }
1016 
1017  void Widget::setColour(const Colour& _value)
1018  {
1019  _setSkinItemColour(_value);
1020 
1021  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget)
1022  (*widget)->setColour(_value);
1023  }
1024 
1026  {
1027  if (mCroppedParent)
1028  return static_cast<Widget*>(mCroppedParent)->getSize();
1029  if (getLayer())
1030  return getLayer()->getSize();
1031 
1033  }
1034 
1035  void Widget::_resetContainer(bool _updateOnly)
1036  {
1037  if (getNeedToolTip())
1039  }
1040 
1041  bool Widget::_checkPoint(int _left, int _top) const
1042  {
1043  return ! ((_getViewLeft() > _left) || (_getViewTop() > _top) || (_getViewRight() < _left) || (_getViewBottom() < _top));
1044  }
1045 
1046  void Widget::_linkChildWidget(Widget* _widget)
1047  {
1048  VectorWidgetPtr::iterator iter = std::find(mWidgetChild.begin(), mWidgetChild.end(), _widget);
1049  MYGUI_ASSERT(iter == mWidgetChild.end(), "widget already exist");
1050  addWidget(_widget);
1051  }
1052 
1053  void Widget::_unlinkChildWidget(Widget* _widget)
1054  {
1055  VectorWidgetPtr::iterator iter = std::remove(mWidgetChild.begin(), mWidgetChild.end(), _widget);
1056  MYGUI_ASSERT(iter != mWidgetChild.end(), "widget not found");
1057  mWidgetChild.erase(iter);
1058  }
1059 
1061  {
1062  }
1063 
1065  {
1066  }
1067 
1068  void Widget::setSkinProperty(ResourceSkin* _info)
1069  {
1070  const MapString& properties = _info->getProperties();
1071  for (MapString::const_iterator item = properties.begin(); item != properties.end(); ++item)
1072  setProperty((*item).first, (*item).second);
1073  }
1074 
1075  void Widget::setProperty(const std::string& _key, const std::string& _value)
1076  {
1077  std::string key = _key;
1078  std::string value = _value;
1079 
1080  if (BackwardCompatibility::checkProperty(this, key, value))
1081  {
1082  size_t index = key.find("_");
1083  if (index != std::string::npos)
1084  {
1085  MYGUI_LOG(Warning, "Widget property '" << key << "' have type prefix - use '" << key.substr(index + 1) << "' instead [" << LayoutManager::getInstance().getCurrentLayout() << "]");
1086  key = key.substr(index + 1);
1087  }
1088 
1089  setPropertyOverride(key, value);
1090  }
1091  }
1092 
1094  {
1095  VectorWidgetPtr result;
1096 
1097  for (VectorWidgetPtr::iterator iter = mWidgetChildSkin.begin(); iter != mWidgetChildSkin.end(); ++iter)
1098  (*iter)->findWidgets(_name, result);
1099 
1100  return result;
1101  }
1102 
1103  void Widget::findWidgets(const std::string& _name, VectorWidgetPtr& _result)
1104  {
1105  if (_name == mName)
1106  _result.push_back(this);
1107 
1108  MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget");
1109  if (mWidgetClient != nullptr)
1110  {
1111  mWidgetClient->findWidgets(_name, _result);
1112  }
1113  else
1114  {
1115  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
1116  (*widget)->findWidgets(_name, _result);
1117  }
1118  }
1119 
1121  {
1122  mWidgetChild.push_back(_widget);
1124  }
1125 
1127  {
1128  }
1129 
1131  {
1132  }
1133 
1135  {
1136  mWidgetClient = _widget;
1137  }
1138 
1139  Widget* Widget::_createSkinWidget(WidgetStyle _style, const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _layer, const std::string& _name)
1140  {
1141  return baseCreateWidget(_style, _type, _skin, _coord, _align, _layer, _name, true);
1142  }
1143 
1144  void Widget::setPropertyOverride(const std::string& _key, const std::string& _value)
1145  {
1147  if (_key == "Position")
1148  setPosition(utility::parseValue<IntPoint>(_value));
1149 
1151  else if (_key == "Size")
1152  setSize(utility::parseValue<IntSize>(_value));
1153 
1155  else if (_key == "Coord")
1156  setCoord(utility::parseValue<IntCoord>(_value));
1157 
1159  else if (_key == "Visible")
1160  setVisible(utility::parseValue<bool>(_value));
1161 
1163  else if (_key == "Depth")
1164  setDepth(utility::parseValue<int>(_value));
1165 
1167  else if (_key == "Alpha")
1168  setAlpha(utility::parseValue<float>(_value));
1169 
1171  else if (_key == "Colour")
1172  setColour(utility::parseValue<Colour>(_value));
1173 
1175  else if (_key == "InheritsAlpha")
1176  setInheritsAlpha(utility::parseValue<bool>(_value));
1177 
1179  else if (_key == "InheritsPick")
1180  setInheritsPick(utility::parseValue<bool>(_value));
1181 
1183  else if (_key == "MaskPick")
1184  setMaskPick(_value);
1185 
1187  else if (_key == "NeedKey")
1188  setNeedKeyFocus(utility::parseValue<bool>(_value));
1189 
1191  else if (_key == "NeedMouse")
1192  setNeedMouseFocus(utility::parseValue<bool>(_value));
1193 
1195  else if (_key == "Enabled")
1196  setEnabled(utility::parseValue<bool>(_value));
1197 
1199  else if (_key == "NeedToolTip")
1200  setNeedToolTip(utility::parseValue<bool>(_value));
1201 
1203  else if (_key == "Pointer")
1204  setPointer(_value);
1205 
1206  else
1207  {
1208  MYGUI_LOG(Warning, "Widget property '" << _key << "' not found" << " [" << LayoutManager::getInstance().getCurrentLayout() << "]");
1209  return;
1210  }
1211 
1212  eventChangeProperty(this, _key, _value);
1213  }
1214 
1215  void Widget::setPosition(int _left, int _top)
1216  {
1217  setPosition(IntPoint(_left, _top));
1218  }
1219 
1220  void Widget::setSize(int _width, int _height)
1221  {
1222  setSize(IntSize(_width, _height));
1223  }
1224 
1225  void Widget::setCoord(int _left, int _top, int _width, int _height)
1226  {
1227  setCoord(IntCoord(_left, _top, _width, _height));
1228  }
1229 
1230  void Widget::setRealPosition(float _left, float _top)
1231  {
1232  setRealPosition(FloatPoint(_left, _top));
1233  }
1234 
1235  void Widget::setRealSize(float _width, float _height)
1236  {
1237  setRealSize(FloatSize(_width, _height));
1238  }
1239 
1240  void Widget::setRealCoord(float _left, float _top, float _width, float _height)
1241  {
1242  setRealCoord(FloatCoord(_left, _top, _width, _height));
1243  }
1244 
1245  const std::string& Widget::getName() const
1246  {
1247  return mName;
1248  }
1249 
1250  bool Widget::getVisible() const
1251  {
1252  return mVisible;
1253  }
1254 
1256  {
1257  return mAlign;
1258  }
1259 
1260  float Widget::getAlpha() const
1261  {
1262  return mAlpha;
1263  }
1264 
1266  {
1267  return mInheritsAlpha;
1268  }
1269 
1271  {
1272  return nullptr == mCroppedParent;
1273  }
1274 
1276  {
1277  return mParent;
1278  }
1279 
1280  void Widget::setEnabledSilent(bool _value)
1281  {
1282  mEnabled = _value;
1283  }
1284 
1285  bool Widget::getEnabled() const
1286  {
1287  return mEnabled;
1288  }
1289 
1291  {
1292  return mWidgetClient;
1293  }
1294 
1296  {
1297  return mWidgetStyle;
1298  }
1299 
1301  {
1302  return ITEM_NONE;
1303  }
1304 
1306  {
1307  mContainer = _value;
1308  }
1309 
1311  {
1312  return mContainer;
1313  }
1314 
1315  size_t Widget::_getContainerIndex(const IntPoint& _point)
1316  {
1317  return ITEM_NONE;
1318  }
1319 
1321  {
1322  return mCoord;
1323  }
1324 
1325  float Widget::_getRealAlpha() const
1326  {
1327  return mRealAlpha;
1328  }
1329 
1331  {
1332  return mInheritsEnabled;
1333  }
1334 
1336  {
1337  return mInheritsVisible;
1338  }
1339 
1340  void Widget::resizeLayerItemView(const IntSize& _oldView, const IntSize& _newView)
1341  {
1342  _setAlign(_oldView, _newView);
1343  }
1344 
1345  void Widget::setDepth(int _value)
1346  {
1347  if (mDepth == _value)
1348  return;
1349 
1350  mDepth = _value;
1351 
1352  if (mParent != nullptr)
1353  {
1354  mParent->_unlinkChildWidget(this);
1355  mParent->_linkChildWidget(this);
1356  mParent->_updateChilds();
1357  }
1358  }
1359 
1360  int Widget::getDepth() const
1361  {
1362  return mDepth;
1363  }
1364 
1365  void Widget::addWidget(Widget* _widget)
1366  {
1367  // сортировка глубины от большого к меньшему
1368 
1369  int depth = _widget->getDepth();
1370 
1371  for (size_t index = 0; index < mWidgetChild.size(); ++index)
1372  {
1373  Widget* widget = mWidgetChild[index];
1374  if (widget->getDepth() < depth)
1375  {
1376  mWidgetChild.insert(mWidgetChild.begin() + index, _widget);
1377  _updateChilds();
1378  return;
1379  }
1380  }
1381 
1382  mWidgetChild.push_back(_widget);
1383  }
1384 
1386  {
1387  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
1388  {
1389  if ((*widget)->getWidgetStyle() == WidgetStyle::Child)
1390  {
1391  (*widget)->detachFromLayerItemNode(true);
1392  removeChildItem((*widget));
1393  }
1394  }
1395 
1396  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
1397  {
1398  if ((*widget)->getWidgetStyle() == WidgetStyle::Child)
1399  {
1400  addChildItem((*widget));
1401  (*widget)->_updateView();
1402  }
1403  }
1404  }
1405 
1406 } // namespace MyGUI