MyGUI  3.2.0
MyGUI_Widget.cpp
Go to the documentation of this file.
1 
6 /*
7  This file is part of MyGUI.
8 
9  MyGUI is free software: you can redistribute it and/or modify
10  it under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  MyGUI is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  along with MyGUI. If not, see <http://www.gnu.org/licenses/>.
21 */
22 #include "MyGUI_Precompiled.h"
23 #include "MyGUI_Widget.h"
24 #include "MyGUI_Gui.h"
25 #include "MyGUI_InputManager.h"
26 #include "MyGUI_SkinManager.h"
27 #include "MyGUI_SubWidgetManager.h"
28 #include "MyGUI_WidgetManager.h"
29 #include "MyGUI_ResourceSkin.h"
30 #include "MyGUI_WidgetDefines.h"
31 #include "MyGUI_LayerItem.h"
32 #include "MyGUI_LayerManager.h"
33 #include "MyGUI_RenderItem.h"
34 #include "MyGUI_ISubWidget.h"
35 #include "MyGUI_ISubWidgetText.h"
36 #include "MyGUI_TextBox.h"
37 #include "MyGUI_FactoryManager.h"
38 #include "MyGUI_CoordConverter.h"
39 #include "MyGUI_RenderManager.h"
40 #include "MyGUI_ToolTipManager.h"
41 #include "MyGUI_LayoutManager.h"
42 
43 namespace MyGUI
44 {
45 
47  mWidgetClient(nullptr),
48  mEnabled(true),
49  mInheritsEnabled(true),
50  mInheritsVisible(true),
51  mAlpha(ALPHA_MAX),
52  mRealAlpha(ALPHA_MAX),
53  mInheritsAlpha(true),
54  mParent(nullptr),
55  mWidgetStyle(WidgetStyle::Child),
56  mContainer(nullptr),
57  mAlign(Align::Default),
58  mVisible(true)
59  {
60  }
61 
63  {
64  }
65 
66  void Widget::_initialise(WidgetStyle _style, const IntCoord& _coord, const std::string& _skinName, Widget* _parent, ICroppedRectangle* _croppedParent, const std::string& _name)
67  {
68  ResourceSkin* skinInfo = nullptr;
69  ResourceLayout* templateInfo = nullptr;
70 
71  if (LayoutManager::getInstance().isExist(_skinName))
72  templateInfo = LayoutManager::getInstance().getByName(_skinName);
73  else
74  skinInfo = SkinManager::getInstance().getByName(_skinName);
75 
76  mCoord = _coord;
77 
78  mAlign = Align::Default;
79  mWidgetStyle = _style;
80  mName = _name;
81 
82  mCroppedParent = _croppedParent;
83  mParent = _parent;
84 
85 
86 #if MYGUI_DEBUG_MODE == 1
87  // проверяем соответсвие входных данных
88  if (mWidgetStyle == WidgetStyle::Child)
89  {
90  MYGUI_ASSERT(mCroppedParent, "must be cropped");
91  MYGUI_ASSERT(mParent, "must be parent");
92  }
93  else if (mWidgetStyle == WidgetStyle::Overlapped)
94  {
95  MYGUI_ASSERT((mParent == nullptr) == (mCroppedParent == nullptr), "error cropped");
96  }
97  else if (mWidgetStyle == WidgetStyle::Popup)
98  {
99  MYGUI_ASSERT(!mCroppedParent, "cropped must be nullptr");
100  MYGUI_ASSERT(mParent, "must be parent");
101  }
102 #endif
103 
104  // корректируем абсолютные координаты
105  mAbsolutePosition = _coord.point();
106 
107  if (nullptr != mCroppedParent)
109 
110  const WidgetInfo* root = initialiseWidgetSkinBase(skinInfo, templateInfo);
111 
112  // дочернее окно обыкновенное
113  if (mWidgetStyle == WidgetStyle::Child)
114  {
115  if (mParent)
116  mParent->addChildItem(this);
117  }
118  // дочернее нуно перекрывающееся
119  else if (mWidgetStyle == WidgetStyle::Overlapped)
120  {
121  // дочернее перекрывающееся
122  if (mParent)
123  mParent->addChildNode(this);
124  }
125 
126  // витр метод для наследников
128 
129  if (skinInfo != nullptr)
130  setSkinProperty(skinInfo);
131 
132  if (root != nullptr)
133  {
134  for (VectorStringPairs::const_iterator iter = root->properties.begin(); iter != root->properties.end(); ++iter)
135  {
136  setProperty(iter->first, iter->second);
137  }
138  }
139  }
140 
142  {
143  // витр метод для наследников
145 
146  shutdownWidgetSkinBase();
147 
149 
150  // дочернее окно обыкновенное
151  if (mWidgetStyle == WidgetStyle::Child)
152  {
153  if (mParent)
154  mParent->removeChildItem(this);
155  }
156  // дочернее нуно перекрывающееся
157  else if (mWidgetStyle == WidgetStyle::Overlapped)
158  {
159  // дочернее перекрывающееся
160  if (mParent)
161  mParent->removeChildNode(this);
162  }
163 
164  mParent = nullptr;
165  mCroppedParent = nullptr;
166  }
167 
168  void Widget::changeWidgetSkin(const std::string& _skinName)
169  {
170  ResourceSkin* skinInfo = nullptr;
171  ResourceLayout* templateInfo = nullptr;
172 
173  if (LayoutManager::getInstance().isExist(_skinName))
174  templateInfo = LayoutManager::getInstance().getByName(_skinName);
175  else
176  skinInfo = SkinManager::getInstance().getByName(_skinName);
177 
179 
180  saveLayerItem();
181 
182  shutdownWidgetSkinBase();
183  const WidgetInfo* root = initialiseWidgetSkinBase(skinInfo, templateInfo);
184 
186 
188 
189  if (skinInfo != nullptr)
190  setSkinProperty(skinInfo);
191 
192  if (root != nullptr)
193  {
194  for (VectorStringPairs::const_iterator iter = root->properties.begin(); iter != root->properties.end(); ++iter)
195  {
196  setProperty(iter->first, iter->second);
197  }
198  }
199  }
200 
201  const WidgetInfo* Widget::initialiseWidgetSkinBase(ResourceSkin* _skinInfo, ResourceLayout* _templateInfo)
202  {
203  const WidgetInfo* root = nullptr;
204  bool skinOnly = false;
205 
206  if (_skinInfo == nullptr)
207  {
208  skinOnly = true;
209  std::string skinName;
210 
211  const VectorWidgetInfo& data = _templateInfo->getLayoutData();
212  for (VectorWidgetInfo::const_iterator item = data.begin(); item != data.end(); ++item)
213  {
214  if ((*item).name == "Root")
215  {
216  skinName = (*item).skin;
217  root = &(*item);
218  break;
219  }
220  }
221 
222  _skinInfo = SkinManager::getInstance().getByName(skinName);
223  }
224 
225  //SAVE
226  const IntSize& _size = mCoord.size();
227 
228  if (_skinInfo != nullptr)
229  {
230  //FIXME - явный вызов
231  Widget::setSize(_skinInfo->getSize());
232 
233  _createSkinItem(_skinInfo);
234  }
235 
236  // выставляем альфу, корректировка по отцу автоматически
237  _updateAlpha();
238  _updateEnabled();
239  _updateVisible();
240 
241  if (!skinOnly)
242  {
243  const MapString& properties = _skinInfo->getProperties();
244  for (MapString::const_iterator item = properties.begin(); item != properties.end(); ++item)
245  {
246  if (BackwardCompatibility::isIgnoreProperty((*item).first))
247  setUserString((*item).first, (*item).second);
248  }
249 
250  // создаем детей скина
251  const VectorChildSkinInfo& child = _skinInfo->getChild();
252  for (VectorChildSkinInfo::const_iterator iter = child.begin(); iter != child.end(); ++iter)
253  {
254  Widget* widget = baseCreateWidget(iter->style, iter->type, iter->skin, iter->coord, iter->align, iter->layer, iter->name, true);
255  // заполняем UserString пропертями
256  for (MapString::const_iterator prop = iter->params.begin(); prop != iter->params.end(); ++prop)
257  widget->setUserString(prop->first, prop->second);
258  }
259  }
260 
261  if (root != nullptr)
262  {
263  //FIXME - явный вызов
264  Widget::setSize(root->intCoord.size());
265 
266  for (MapString::const_iterator iter = root->userStrings.begin(); iter != root->userStrings.end(); ++iter)
267  {
268  setUserString(iter->first, iter->second);
269  }
270 
271  for (VectorWidgetInfo::const_iterator iter = root->childWidgetsInfo.begin(); iter != root->childWidgetsInfo.end(); ++iter)
272  {
273  _templateInfo->createWidget(*iter, "", this, true);
274  }
275  }
276 
277  //FIXME - явный вызов
278  Widget::setSize(_size);
279 
280  return root;
281  }
282 
283  void Widget::shutdownWidgetSkinBase()
284  {
285  setMaskPick("");
286 
287  _deleteSkinItem();
288 
289  // удаляем виджеты чтобы ли в скине
290  for (VectorWidgetPtr::iterator iter = mWidgetChildSkin.begin(); iter != mWidgetChildSkin.end(); ++iter)
291  {
292  // Добавляем себя чтобы удалилось
293  mWidgetChild.push_back(*iter);
294  _destroyChildWidget(*iter);
295  }
296  mWidgetChildSkin.clear();
297 
298  mWidgetClient = nullptr;
299  }
300 
301  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)
302  {
303  Widget* widget = nullptr;
304 
305  if (_template)
306  {
307  widget = WidgetManager::getInstance().createWidget(_style, _type, _skin, _coord, this, _style == WidgetStyle::Popup ? nullptr : this, _name);
308  mWidgetChildSkin.push_back(widget);
309  }
310  else
311  {
312  if (mWidgetClient != nullptr)
313  {
314  widget = mWidgetClient->baseCreateWidget(_style, _type, _skin, _coord, _align, _layer, _name, _template);
315  onWidgetCreated(widget);
316  return widget;
317  }
318  else
319  {
320  widget = WidgetManager::getInstance().createWidget(_style, _type, _skin, _coord, this, _style == WidgetStyle::Popup ? nullptr : this, _name);
321  mWidgetChild.push_back(widget);
322  }
323  }
324 
325  widget->setAlign(_align);
326 
327  // присоединяем виджет с уровню
328  if (!_layer.empty() && widget->isRootWidget())
330 
331  onWidgetCreated(widget);
332 
333  return widget;
334  }
335 
336  Widget* Widget::createWidgetRealT(const std::string& _type, const std::string& _skin, const FloatCoord& _coord, Align _align, const std::string& _name)
337  {
338  return createWidgetT(_type, _skin, CoordConverter::convertFromRelative(_coord, getSize()), _align, _name);
339  }
340 
342  {
343  bool margin = mCroppedParent ? _checkMargin() : false;
344 
345  // вьюпорт стал битым
346  if (margin)
347  {
348  // проверка на полный выход за границу
349  if (_checkOutside())
350  {
351  // запоминаем текущее состояние
352  mIsMargin = margin;
353 
354  // скрываем
355  _setSubSkinVisible(false);
356 
357  // вся иерархия должна быть проверенна
358  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
359  (*widget)->_updateView();
360  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget)
361  (*widget)->_updateView();
362 
363  return;
364  }
365 
366  }
367  // мы не обрезаны и были нормальные
368  else if (!mIsMargin)
369  {
371  return;
372  }
373 
374  // запоминаем текущее состояние
375  mIsMargin = margin;
376 
377  // если скин был скрыт, то покажем
378  _setSubSkinVisible(true);
379 
380  // обновляем наших детей, а они уже решат обновлять ли своих детей
381  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
382  (*widget)->_updateView();
383  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget)
384  (*widget)->_updateView();
385 
387  }
388 
389  bool Widget::_setWidgetState(const std::string& _state)
390  {
391  return _setSkinItemState(_state);
392  }
393 
395  {
396  MYGUI_ASSERT(nullptr != _widget, "invalid widget pointer");
397 
398  if (mParent != nullptr && mParent->getClientWidget() == this)
399  mParent->onWidgetDestroy(_widget);
400 
401  onWidgetDestroy(_widget);
402 
403  VectorWidgetPtr::iterator iter = std::find(mWidgetChild.begin(), mWidgetChild.end(), _widget);
404  if (iter != mWidgetChild.end())
405  {
406  // сохраняем указатель
407  MyGUI::Widget* widget = *iter;
408 
409  // удаляем из списка
410  mWidgetChild.erase(iter);
411 
412  // отписываем от всех
414 
415  // непосредственное удаление
417  }
418  else
419  {
420  MYGUI_EXCEPT("Widget '" << _widget->getName() << "' not found");
421  }
422  }
423 
424  // удаляет всех детей
426  {
428  while (!mWidgetChild.empty())
429  {
430  // сразу себя отписывем, иначе вложенной удаление убивает все
431  Widget* widget = mWidgetChild.back();
432  mWidgetChild.pop_back();
433 
434  // отписываем от всех
435  manager.unlinkFromUnlinkers(widget);
436 
437  // и сами удалим, так как его больше в списке нет
439  }
440  }
441 
443  {
444  MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget");
445  if (mWidgetClient != nullptr)
446  return mWidgetClient->getCoord();
447  return IntCoord(0, 0, mCoord.width, mCoord.height);
448  }
449 
450  void Widget::setAlpha(float _alpha)
451  {
452  if (mAlpha == _alpha)
453  return;
454  mAlpha = _alpha;
455 
456  _updateAlpha();
457  }
458 
459  void Widget::_updateAlpha()
460  {
461  if (nullptr != mParent)
462  mRealAlpha = mAlpha * (mInheritsAlpha ? mParent->_getRealAlpha() : ALPHA_MAX);
463  else
464  mRealAlpha = mAlpha;
465 
466  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
467  (*widget)->_updateAlpha();
468  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget)
469  (*widget)->_updateAlpha();
470 
471  _setSkinItemAlpha(mRealAlpha);
472  }
473 
474  void Widget::setInheritsAlpha(bool _inherits)
475  {
476  mInheritsAlpha = _inherits;
477  _updateAlpha();
478  }
479 
480  ILayerItem* Widget::getLayerItemByPoint(int _left, int _top) const
481  {
482  // проверяем попадание
483  if (!mEnabled
484  || !mVisible
485  || (!getNeedMouseFocus() && !getInheritsPick())
486  || !_checkPoint(_left, _top)
487  // если есть маска, проверяем еще и по маске
488  || !isMaskPickInside(IntPoint(_left - mCoord.left, _top - mCoord.top), mCoord)
489  )
490  return nullptr;
491 
492  // спрашиваем у детишек
493  for (VectorWidgetPtr::const_reverse_iterator widget = mWidgetChild.rbegin(); widget != mWidgetChild.rend(); ++widget)
494  {
495  // общаемся только с послушными детьми
496  if ((*widget)->mWidgetStyle == WidgetStyle::Popup)
497  continue;
498 
499  ILayerItem* item = (*widget)->getLayerItemByPoint(_left - mCoord.left, _top - mCoord.top);
500  if (item != nullptr)
501  return item;
502  }
503  // спрашиваем у детишек скна
504  for (VectorWidgetPtr::const_reverse_iterator widget = mWidgetChildSkin.rbegin(); widget != mWidgetChildSkin.rend(); ++widget)
505  {
506  ILayerItem* item = (*widget)->getLayerItemByPoint(_left - mCoord.left, _top - mCoord.top);
507  if (item != nullptr)
508  return item;
509  }
510 
511  // непослушные дети
512  return getInheritsPick() ? nullptr : const_cast<Widget*>(this);
513  }
514 
515  void Widget::_updateAbsolutePoint()
516  {
517  // мы рут, нам не надо
518  if (!mCroppedParent)
519  return;
520 
522 
523  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
524  (*widget)->_updateAbsolutePoint();
525  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget)
526  (*widget)->_updateAbsolutePoint();
527 
529  }
530 
531  void Widget::_forcePick(Widget* _widget)
532  {
533  MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget");
534  if (mWidgetClient != nullptr)
535  mWidgetClient->_forcePick(_widget);
536 
537  VectorWidgetPtr::iterator item = std::remove(mWidgetChild.begin(), mWidgetChild.end(), _widget);
538  if (item != mWidgetChild.end())
539  {
540  mWidgetChild.erase(item);
541  mWidgetChild.insert(mWidgetChild.begin(), _widget);
542  }
543  }
544 
545  Widget* Widget::findWidget(const std::string& _name)
546  {
547  if (_name == mName)
548  return this;
549  MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget");
550  if (mWidgetClient != nullptr)
551  return mWidgetClient->findWidget(_name);
552 
553  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
554  {
555  Widget* find = (*widget)->findWidget(_name);
556  if (nullptr != find)
557  return find;
558  }
559  return nullptr;
560  }
561 
563  {
565  }
566 
567  void Widget::setRealSize(const FloatSize& _size)
568  {
570  }
571 
572  void Widget::setRealCoord(const FloatCoord& _coord)
573  {
575  }
576 
577  void Widget::_setAlign(const IntSize& _oldsize, const IntSize& _newSize)
578  {
579  const IntSize& size = _newSize;//getParentSize();
580 
581  bool need_move = false;
582  bool need_size = false;
583  IntCoord coord = mCoord;
584 
585  // первоначальное выравнивание
586  if (mAlign.isHStretch())
587  {
588  // растягиваем
589  coord.width = mCoord.width + (size.width - _oldsize.width);
590  need_size = true;
591  }
592  else if (mAlign.isRight())
593  {
594  // двигаем по правому краю
595  coord.left = mCoord.left + (size.width - _oldsize.width);
596  need_move = true;
597  }
598  else if (mAlign.isHCenter())
599  {
600  // выравнивание по горизонтали без растяжения
601  coord.left = (size.width - mCoord.width) / 2;
602  need_move = true;
603  }
604 
605  if (mAlign.isVStretch())
606  {
607  // растягиваем
608  coord.height = mCoord.height + (size.height - _oldsize.height);
609  need_size = true;
610  }
611  else if (mAlign.isBottom())
612  {
613  // двигаем по нижнему краю
614  coord.top = mCoord.top + (size.height - _oldsize.height);
615  need_move = true;
616  }
617  else if (mAlign.isVCenter())
618  {
619  // выравнивание по вертикали без растяжения
620  coord.top = (size.height - mCoord.height) / 2;
621  need_move = true;
622  }
623 
624  if (need_move)
625  {
626  if (need_size)
627  setCoord(coord);
628  else
629  setPosition(coord.point());
630  }
631  else if (need_size)
632  {
633  setSize(coord.size());
634  }
635  else
636  {
637  _updateView(); // только если не вызвано передвижение и сайз
638  }
639  }
640 
641  void Widget::setPosition(const IntPoint& _point)
642  {
643  // обновляем абсолютные координаты
644  mAbsolutePosition += _point - mCoord.point();
645 
646  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
647  (*widget)->_updateAbsolutePoint();
648  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget)
649  (*widget)->_updateAbsolutePoint();
650 
651  mCoord = _point;
652 
653  _updateView();
654  }
655 
656  void Widget::setSize(const IntSize& _size)
657  {
658  // устанавливаем новую координату а старую пускаем в расчеты
659  IntSize old = mCoord.size();
660  mCoord = _size;
661 
662  bool visible = true;
663 
664  // обновляем выравнивание
665  bool margin = mCroppedParent ? _checkMargin() : false;
666 
667  if (margin)
668  {
669  // проверка на полный выход за границу
670  if (_checkOutside())
671  {
672  // скрываем
673  visible = false;
674  }
675  }
676 
677  _setSubSkinVisible(visible);
678 
679  // передаем старую координату , до вызова, текущая координата отца должна быть новой
680  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
681  (*widget)->_setAlign(old, getSize());
682  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget)
683  (*widget)->_setAlign(old, getSize());
684 
685  _setSkinItemAlign(old);
686 
687  // запоминаем текущее состояние
688  mIsMargin = margin;
689  }
690 
691  void Widget::setCoord(const IntCoord& _coord)
692  {
693  // обновляем абсолютные координаты
694  mAbsolutePosition += _coord.point() - mCoord.point();
695 
696  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
697  (*widget)->_updateAbsolutePoint();
698  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget)
699  (*widget)->_updateAbsolutePoint();
700 
701  // устанавливаем новую координату а старую пускаем в расчеты
702  IntCoord old = mCoord;
703  mCoord = _coord;
704 
705  bool visible = true;
706 
707  // обновляем выравнивание
708  bool margin = mCroppedParent ? _checkMargin() : false;
709 
710  if (margin)
711  {
712  // проверка на полный выход за границу
713  if (_checkOutside())
714  {
715  // скрываем
716  visible = false;
717  }
718  }
719 
720  _setSubSkinVisible(visible);
721 
722  // передаем старую координату , до вызова, текущая координата отца должна быть новой
723  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
724  (*widget)->_setAlign(old.size(), getSize());
725  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget)
726  (*widget)->_setAlign(old.size(), getSize());
727 
728  _setSkinItemAlign(old.size());
729 
730  // запоминаем текущее состояние
731  mIsMargin = margin;
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 (mEnabled)
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  }
989 
990  void Widget::setEnabled(bool _value)
991  {
992  if (mEnabled == _value)
993  return;
994  mEnabled = _value;
995 
996  _updateEnabled();
997  }
998 
999  void Widget::_updateEnabled()
1000  {
1001  mInheritsEnabled = mParent == nullptr || (mParent->getEnabled() && mParent->getInheritedEnabled());
1002  bool value = mEnabled && mInheritsEnabled;
1003 
1004  for (VectorWidgetPtr::iterator iter = mWidgetChild.begin(); iter != mWidgetChild.end(); ++iter)
1005  (*iter)->_updateEnabled();
1006  for (VectorWidgetPtr::iterator iter = mWidgetChildSkin.begin(); iter != mWidgetChildSkin.end(); ++iter)
1007  (*iter)->_updateEnabled();
1008 
1009  baseUpdateEnable();
1010 
1011  if (!value)
1013  }
1014 
1015  void Widget::setColour(const Colour& _value)
1016  {
1017  _setSkinItemColour(_value);
1018 
1019  for (VectorWidgetPtr::iterator widget = mWidgetChildSkin.begin(); widget != mWidgetChildSkin.end(); ++widget)
1020  (*widget)->setColour(_value);
1021  }
1022 
1024  {
1025  if (mCroppedParent)
1026  return static_cast<Widget*>(mCroppedParent)->getSize();
1027  if (getLayer())
1028  return getLayer()->getSize();
1029 
1031  }
1032 
1033  void Widget::_resetContainer(bool _updateOnly)
1034  {
1035  if (getNeedToolTip())
1037  }
1038 
1039  bool Widget::_checkPoint(int _left, int _top) const
1040  {
1041  return ! ((_getViewLeft() > _left) || (_getViewTop() > _top) || (_getViewRight() < _left) || (_getViewBottom() < _top));
1042  }
1043 
1044  void Widget::_linkChildWidget(Widget* _widget)
1045  {
1046  VectorWidgetPtr::iterator iter = std::find(mWidgetChild.begin(), mWidgetChild.end(), _widget);
1047  MYGUI_ASSERT(iter == mWidgetChild.end(), "widget already exist");
1048  mWidgetChild.push_back(_widget);
1049  }
1050 
1051  void Widget::_unlinkChildWidget(Widget* _widget)
1052  {
1053  VectorWidgetPtr::iterator iter = std::remove(mWidgetChild.begin(), mWidgetChild.end(), _widget);
1054  MYGUI_ASSERT(iter != mWidgetChild.end(), "widget not found");
1055  mWidgetChild.erase(iter);
1056  }
1057 
1059  {
1060  }
1061 
1063  {
1064  }
1065 
1066  void Widget::setSkinProperty(ResourceSkin* _info)
1067  {
1068  const MapString& properties = _info->getProperties();
1069  for (MapString::const_iterator item = properties.begin(); item != properties.end(); ++item)
1070  setProperty((*item).first, (*item).second);
1071  }
1072 
1073  void Widget::setProperty(const std::string& _key, const std::string& _value)
1074  {
1075  std::string key = _key;
1076  std::string value = _value;
1077 
1078  if (BackwardCompatibility::checkProperty(this, key, value))
1079  {
1080  size_t index = key.find("_");
1081  if (index != std::string::npos)
1082  {
1083  MYGUI_LOG(Warning, "Widget property '" << key << "' have type prefix - use '" << key.substr(index + 1) << "' instead [" << LayoutManager::getInstance().getCurrentLayout() << "]");
1084  key = key.substr(index + 1);
1085  }
1086 
1087  setPropertyOverride(key, value);
1088  }
1089  }
1090 
1092  {
1093  VectorWidgetPtr result;
1094 
1095  for (VectorWidgetPtr::iterator iter = mWidgetChildSkin.begin(); iter != mWidgetChildSkin.end(); ++iter)
1096  (*iter)->findWidgets(_name, result);
1097 
1098  return result;
1099  }
1100 
1101  void Widget::findWidgets(const std::string& _name, VectorWidgetPtr& _result)
1102  {
1103  if (_name == mName)
1104  _result.push_back(this);
1105 
1106  MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget");
1107  if (mWidgetClient != nullptr)
1108  {
1109  mWidgetClient->findWidgets(_name, _result);
1110  }
1111  else
1112  {
1113  for (VectorWidgetPtr::iterator widget = mWidgetChild.begin(); widget != mWidgetChild.end(); ++widget)
1114  (*widget)->findWidgets(_name, _result);
1115  }
1116  }
1117 
1119  {
1120  mWidgetChild.push_back(_widget);
1122  }
1123 
1125  {
1126  }
1127 
1129  {
1130  }
1131 
1133  {
1134  mWidgetClient = _widget;
1135  }
1136 
1137  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)
1138  {
1139  return baseCreateWidget(_style, _type, _skin, _coord, _align, _layer, _name, true);
1140  }
1141 
1142  void Widget::setPropertyOverride(const std::string& _key, const std::string& _value)
1143  {
1145  if (_key == "Position")
1146  setPosition(utility::parseValue<IntPoint>(_value));
1148  else if (_key == "Size")
1149  setSize(utility::parseValue<IntSize>(_value));
1151  else if (_key == "Coord")
1152  setCoord(utility::parseValue<IntCoord>(_value));
1154  else if (_key == "Visible")
1155  setVisible(utility::parseValue<bool>(_value));
1156  else if (_key == "Alpha")
1157  setAlpha(utility::parseValue<float>(_value));
1158  else if (_key == "Colour")
1159  setColour(utility::parseValue<Colour>(_value));
1160  else if (_key == "InheritsAlpha")
1161  setInheritsAlpha(utility::parseValue<bool>(_value));
1162  else if (_key == "InheritsPick")
1163  setInheritsPick(utility::parseValue<bool>(_value));
1164  else if (_key == "MaskPick")
1165  setMaskPick(_value);
1166  else if (_key == "NeedKey")
1167  setNeedKeyFocus(utility::parseValue<bool>(_value));
1168  else if (_key == "NeedMouse")
1169  setNeedMouseFocus(utility::parseValue<bool>(_value));
1170  else if (_key == "Enabled")
1171  setEnabled(utility::parseValue<bool>(_value));
1172  else if (_key == "NeedToolTip")
1173  setNeedToolTip(utility::parseValue<bool>(_value));
1174  else if (_key == "Pointer")
1175  setPointer(_value);
1176  else
1177  {
1178  MYGUI_LOG(Warning, "Widget property '" << _key << "' not found" << " [" << LayoutManager::getInstance().getCurrentLayout() << "]");
1179  return;
1180  }
1181 
1182  eventChangeProperty(this, _key, _value);
1183  }
1184 
1185  void Widget::setPosition(int _left, int _top)
1186  {
1187  setPosition(IntPoint(_left, _top));
1188  }
1189 
1190  void Widget::setSize(int _width, int _height)
1191  {
1192  setSize(IntSize(_width, _height));
1193  }
1194 
1195  void Widget::setCoord(int _left, int _top, int _width, int _height)
1196  {
1197  setCoord(IntCoord(_left, _top, _width, _height));
1198  }
1199 
1200  void Widget::setRealPosition(float _left, float _top)
1201  {
1202  setRealPosition(FloatPoint(_left, _top));
1203  }
1204 
1205  void Widget::setRealSize(float _width, float _height)
1206  {
1207  setRealSize(FloatSize(_width, _height));
1208  }
1209 
1210  void Widget::setRealCoord(float _left, float _top, float _width, float _height)
1211  {
1212  setRealCoord(FloatCoord(_left, _top, _width, _height));
1213  }
1214 
1215  const std::string& Widget::getName() const
1216  {
1217  return mName;
1218  }
1219 
1220  bool Widget::getVisible() const
1221  {
1222  return mVisible;
1223  }
1224 
1226  {
1227  return mAlign;
1228  }
1229 
1230  float Widget::getAlpha() const
1231  {
1232  return mAlpha;
1233  }
1234 
1236  {
1237  return mInheritsAlpha;
1238  }
1239 
1241  {
1242  return nullptr == mCroppedParent;
1243  }
1244 
1246  {
1247  return mParent;
1248  }
1249 
1250  void Widget::setEnabledSilent(bool _value)
1251  {
1252  mEnabled = _value;
1253  }
1254 
1255  bool Widget::getEnabled() const
1256  {
1257  return mEnabled;
1258  }
1259 
1261  {
1262  return mWidgetClient;
1263  }
1264 
1266  {
1267  return mWidgetStyle;
1268  }
1269 
1271  {
1272  return ITEM_NONE;
1273  }
1274 
1276  {
1277  mContainer = _value;
1278  }
1279 
1281  {
1282  return mContainer;
1283  }
1284 
1285  size_t Widget::_getContainerIndex(const IntPoint& _point)
1286  {
1287  return ITEM_NONE;
1288  }
1289 
1291  {
1292  return mCoord;
1293  }
1294 
1295  float Widget::_getRealAlpha() const
1296  {
1297  return mRealAlpha;
1298  }
1299 
1301  {
1302  return mInheritsEnabled;
1303  }
1304 
1306  {
1307  return mInheritsVisible;
1308  }
1309 
1310  void Widget::resizeLayerItemView(const IntSize& _oldView, const IntSize& _newView)
1311  {
1312  _setAlign(_oldView, _newView);
1313  }
1314 
1315 } // namespace MyGUI