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_LayerItem.h"
9 #include "MyGUI_OverlappedLayer.h"
10 #include "MyGUI_LayerNode.h"
11 #include "MyGUI_RenderManager.h"
12 
13 namespace MyGUI
14 {
15 
OverlappedLayer()16 	OverlappedLayer::OverlappedLayer() :
17 		mIsPick(false),
18 		mOutOfDate(false)
19 	{
20 		mViewSize = RenderManager::getInstance().getViewSize();
21 	}
22 
~OverlappedLayer()23 	OverlappedLayer::~OverlappedLayer()
24 	{
25 		MYGUI_ASSERT(mChildItems.empty(), "Layer '" << getName() << "' must be empty before destroy");
26 	}
27 
deserialization(xml::ElementPtr _node,Version _version)28 	void OverlappedLayer::deserialization(xml::ElementPtr _node, Version _version)
29 	{
30 		mName = _node->findAttribute("name");
31 		if (_version >= Version(1, 2))
32 		{
33 			MyGUI::xml::ElementEnumerator propert = _node->getElementEnumerator();
34 			while (propert.next("Property"))
35 			{
36 				const std::string& key = propert->findAttribute("key");
37 				const std::string& value = propert->findAttribute("value");
38 				if (key == "Pick")
39 					setPick(utility::parseValue<bool>(value));
40 			}
41 		}
42 		else if (_version >= Version(1, 0))
43 		{
44 			setPick(utility::parseBool(_node->findAttribute("pick")));
45 		}
46 		else
47 		{
48 			setPick(utility::parseBool(_node->findAttribute("peek")));
49 		}
50 	}
51 
setPick(bool _pick)52 	void OverlappedLayer::setPick(bool _pick)
53 	{
54 		mIsPick = _pick;
55 	}
56 
createChildItemNode()57 	ILayerNode* OverlappedLayer::createChildItemNode()
58 	{
59 		// создаем рутовый айтем
60 		ILayerNode* node = new LayerNode(this);
61 		mChildItems.push_back(node);
62 
63 		mOutOfDate = true;
64 
65 		return node;
66 	}
67 
destroyChildItemNode(ILayerNode * _item)68 	void OverlappedLayer::destroyChildItemNode(ILayerNode* _item)
69 	{
70 		// если есть отец, то русть сам и удаляет
71 		ILayerNode* parent = _item->getParent();
72 		if (parent)
73 		{
74 			parent->destroyChildItemNode(_item);
75 
76 			mOutOfDate = true;
77 
78 			return;
79 		}
80 
81 		// айтем рутовый, мы удаляем
82 		for (VectorILayerNode::iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter)
83 		{
84 			if ((*iter) == _item)
85 			{
86 				delete _item;
87 				mChildItems.erase(iter);
88 
89 				mOutOfDate = true;
90 
91 				return;
92 			}
93 		}
94 
95 		MYGUI_EXCEPT("item node not found");
96 	}
97 
upChildItemNode(ILayerNode * _item)98 	void OverlappedLayer::upChildItemNode(ILayerNode* _item)
99 	{
100 		// если есть отец, то пусть сам рулит
101 		ILayerNode* parent = _item->getParent();
102 		if (parent != nullptr)
103 		{
104 			parent->upChildItemNode(_item);
105 
106 			mOutOfDate = true;
107 
108 			return;
109 		}
110 
111 		if ((2 > mChildItems.size()) || (mChildItems.back() == _item))
112 			return;
113 
114 		for (VectorILayerNode::iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter)
115 		{
116 			if ((*iter) == _item)
117 			{
118 				mChildItems.erase(iter);
119 				mChildItems.push_back(_item);
120 
121 				mOutOfDate = true;
122 
123 				return;
124 			}
125 		}
126 
127 		MYGUI_EXCEPT("item node not found");
128 	}
129 
getLayerItemByPoint(int _left,int _top) const130 	ILayerItem* OverlappedLayer::getLayerItemByPoint(int _left, int _top) const
131 	{
132 		if (!mIsPick)
133 			return nullptr;
134 
135 		VectorILayerNode::const_reverse_iterator iter = mChildItems.rbegin();
136 		while (iter != mChildItems.rend())
137 		{
138 			ILayerItem* item = (*iter)->getLayerItemByPoint(_left, _top);
139 			if (item != nullptr)
140 				return item;
141 			++iter;
142 		}
143 		return nullptr;
144 	}
145 
getPosition(int _left,int _top) const146 	IntPoint OverlappedLayer::getPosition(int _left, int _top) const
147 	{
148 		return IntPoint(_left, _top);
149 	}
150 
renderToTarget(IRenderTarget * _target,bool _update)151 	void OverlappedLayer::renderToTarget(IRenderTarget* _target, bool _update)
152 	{
153 		for (VectorILayerNode::iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter)
154 			(*iter)->renderToTarget(_target, _update);
155 
156 		mOutOfDate = false;
157 	}
158 
resizeView(const IntSize & _viewSize)159 	void OverlappedLayer::resizeView(const IntSize& _viewSize)
160 	{
161 		for (VectorILayerNode::iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter)
162 			(*iter)->resizeView(_viewSize);
163 
164 		mViewSize = _viewSize;
165 	}
166 
getEnumerator() const167 	EnumeratorILayerNode OverlappedLayer::getEnumerator() const
168 	{
169 		return EnumeratorILayerNode(mChildItems);
170 	}
171 
getLayerNodeCount() const172 	size_t OverlappedLayer::getLayerNodeCount() const
173 	{
174 		return mChildItems.size();
175 	}
176 
getLayerNodeAt(size_t _index) const177 	ILayerNode* OverlappedLayer::getLayerNodeAt(size_t _index) const
178 	{
179 		MYGUI_ASSERT_RANGE(_index, mChildItems.size(), "OverlappedLayer::getLayerNodeAt");
180 
181 		return mChildItems[_index];
182 	}
183 
getSize() const184 	const IntSize& OverlappedLayer::getSize() const
185 	{
186 		return mViewSize;
187 	}
188 
isOutOfDate() const189 	bool OverlappedLayer::isOutOfDate() const
190 	{
191 		for (VectorILayerNode::const_iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter)
192 		{
193 			if (static_cast<const LayerNode*>(*iter)->isOutOfDate())
194 				return true;
195 		}
196 
197 		return mOutOfDate;
198 	}
199 
200 } // namespace MyGUI
201