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