MyGUI  3.2.0
MyGUI_LayerNode.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 
23 #include "MyGUI_Precompiled.h"
24 #include "MyGUI_LayerNode.h"
25 #include "MyGUI_ILayerItem.h"
26 #include "MyGUI_ITexture.h"
27 #include "MyGUI_ISubWidget.h"
28 #include "MyGUI_ISubWidgetText.h"
29 
30 namespace MyGUI
31 {
32 
33  LayerNode::LayerNode(ILayer* _layer, ILayerNode* _parent) :
34  mParent(_parent),
35  mLayer(_layer),
36  mOutOfDate(false)
37  {
38  }
39 
41  {
42  for (VectorRenderItem::iterator iter = mFirstRenderItems.begin(); iter != mFirstRenderItems.end(); ++iter)
43  delete (*iter);
44  mFirstRenderItems.clear();
45 
46  for (VectorRenderItem::iterator iter = mSecondRenderItems.begin(); iter != mSecondRenderItems.end(); ++iter)
47  delete (*iter);
48  mSecondRenderItems.clear();
49 
50  for (VectorILayerNode::iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter)
51  delete (*iter);
52  mChildItems.clear();
53  }
54 
56  {
57  LayerNode* layer = new LayerNode(mLayer, this);
58  mChildItems.push_back(layer);
59 
60  mOutOfDate = true;
61 
62  return layer;
63  }
64 
66  {
67  for (VectorILayerNode::iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter)
68  {
69  if ((*iter) == _node)
70  {
71  delete _node;
72  mChildItems.erase(iter);
73 
74  mOutOfDate = true;
75 
76  return;
77  }
78  }
79  MYGUI_EXCEPT("item node not found");
80  }
81 
83  {
84  for (VectorILayerNode::iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter)
85  {
86  if ((*iter) == _item)
87  {
88  mChildItems.erase(iter);
89  mChildItems.push_back(_item);
90 
91  mOutOfDate = true;
92 
93  return;
94  }
95  }
96  MYGUI_EXCEPT("item node not found");
97  }
98 
99  void LayerNode::renderToTarget(IRenderTarget* _target, bool _update)
100  {
101  // проверяем на сжатие пустот
102  bool need_compression = false;
103  for (VectorRenderItem::iterator iter = mFirstRenderItems.begin(); iter != mFirstRenderItems.end(); ++iter)
104  {
105  if ((*iter)->getCompression())
106  {
107  need_compression = true;
108  break;
109  }
110  }
111 
112  if (need_compression)
114 
115  // сначала отрисовываем свое
116  for (VectorRenderItem::iterator iter = mFirstRenderItems.begin(); iter != mFirstRenderItems.end(); ++iter)
117  (*iter)->renderToTarget(_target, _update);
118 
119  for (VectorRenderItem::iterator iter = mSecondRenderItems.begin(); iter != mSecondRenderItems.end(); ++iter)
120  (*iter)->renderToTarget(_target, _update);
121 
122  // теперь отрисовываем дочерние узлы
123  for (VectorILayerNode::iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter)
124  (*iter)->renderToTarget(_target, _update);
125 
126  mOutOfDate = false;
127  }
128 
129  void LayerNode::resizeView(const IntSize& _viewSize)
130  {
131  IntSize oldSize = mLayer->getSize();
132 
133  for (VectorLayerItem::const_iterator iter = mLayerItems.begin(); iter != mLayerItems.end(); ++iter)
134  (*iter)->resizeLayerItemView(oldSize, _viewSize);
135  }
136 
137  ILayerItem* LayerNode::getLayerItemByPoint(int _left, int _top) const
138  {
139  // сначала пикаем детей
140  for (VectorILayerNode::const_iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter)
141  {
142  ILayerItem* item = (*iter)->getLayerItemByPoint(_left, _top);
143  if (nullptr != item)
144  return item;
145  }
146 
147  for (VectorLayerItem::const_iterator iter = mLayerItems.begin(); iter != mLayerItems.end(); ++iter)
148  {
149  ILayerItem* item = (*iter)->getLayerItemByPoint(_left, _top);
150  if (nullptr != item)
151  return item;
152  }
153 
154  return nullptr;
155  }
156 
157  RenderItem* LayerNode::addToRenderItem(ITexture* _texture, bool _firstQueue, bool _manualRender)
158  {
159  // для первичной очереди нужен порядок
160  if (_firstQueue)
161  {
162  if (mFirstRenderItems.empty() || _manualRender)
163  {
164  // создаем новый буфер
165  RenderItem* item = new RenderItem();
166  item->setTexture(_texture);
167  item->setManualRender(_manualRender);
168  mFirstRenderItems.push_back(item);
169 
170  mOutOfDate = false;
171 
172  return item;
173  }
174 
175  // если в конце пустой буфер, то нуна найти последний пустой с краю
176  // либо с нужной текстурой за пустым
177  VectorRenderItem::reverse_iterator iter = mFirstRenderItems.rbegin();
178  if ((*iter)->getNeedVertexCount() == 0)
179  {
180  while (true)
181  {
182  VectorRenderItem::reverse_iterator next = iter + 1;
183  if (next != mFirstRenderItems.rend())
184  {
185  if ((*next)->getNeedVertexCount() == 0)
186  {
187  iter = next;
188  continue;
189  }
190  else if ((*next)->getTexture() == _texture)
191  {
192  iter = next;
193  }
194  }
195 
196  break;
197  }
198 
199  (*iter)->setTexture(_texture);
200 
201  mOutOfDate = false;
202 
203  return (*iter);
204  }
205  // последний буфер с нужной текстурой
206  else if ((*iter)->getTexture() == _texture)
207  {
208  mOutOfDate = false;
209 
210  return *iter;
211  }
212 
213  // создаем новый буфер
214  RenderItem* item = new RenderItem();
215  item->setTexture(_texture);
216  item->setManualRender(_manualRender);
217  mFirstRenderItems.push_back(item);
218 
219  mOutOfDate = false;
220 
221  return item;
222  }
223 
224  // для второй очереди порядок неважен
225  for (VectorRenderItem::iterator iter = mSecondRenderItems.begin(); iter != mSecondRenderItems.end(); ++iter)
226  {
227  // либо такая же текстура, либо пустой буфер
228  if ((*iter)->getTexture() == _texture)
229  {
230  mOutOfDate = false;
231 
232  return (*iter);
233  }
234  else if ((*iter)->getNeedVertexCount() == 0)
235  {
236  (*iter)->setTexture(_texture);
237 
238  mOutOfDate = false;
239 
240  return (*iter);
241  }
242  }
243  // не найденно создадим новый
244  RenderItem* item = new RenderItem();
245  item->setTexture(_texture);
246  item->setManualRender(_manualRender);
247 
248  mSecondRenderItems.push_back(item);
249 
250  mOutOfDate = false;
251 
252  return mSecondRenderItems.back();
253  }
254 
256  {
257  mLayerItems.push_back(_item);
258  _item->attachItemToNode(mLayer, this);
259 
260  mOutOfDate = true;
261  }
262 
264  {
265  for (VectorLayerItem::iterator iter = mLayerItems.begin(); iter != mLayerItems.end(); ++iter)
266  {
267  if ((*iter) == _item)
268  {
269  mLayerItems.erase(iter);
270 
271  mOutOfDate = true;
272 
273  return;
274  }
275  }
276  MYGUI_EXCEPT("layer item not found");
277  }
278 
280  {
281  mOutOfDate = true;
282  if (_item)
283  _item->outOfDate();
284  }
285 
287  {
289  }
290 
292  {
293  // буферы освобождаются по одному всегда
294  if (mFirstRenderItems.size() > 1)
295  {
296  // пытаемся поднять пустой буфер выше полных
297  VectorRenderItem::iterator iter1 = mFirstRenderItems.begin();
298  VectorRenderItem::iterator iter2 = iter1 + 1;
299  while (iter2 != mFirstRenderItems.end())
300  {
301  if ((*iter1)->getNeedVertexCount() == 0 && !(*iter1)->getManualRender())
302  {
303  RenderItem* tmp = (*iter1);
304  (*iter1) = (*iter2);
305  (*iter2) = tmp;
306  }
307  iter1 = iter2;
308  ++iter2;
309  }
310  }
311 
312  mOutOfDate = true;
313  }
314 
316  {
317  return mLayer;
318  }
319 
321  {
322  return mParent;
323  }
324 
326  {
327  for (VectorRenderItem::const_iterator item = mFirstRenderItems.begin(); item != mFirstRenderItems.end(); ++item)
328  {
329  if ((*item)->isOutOfDate())
330  return true;
331  }
332 
333  for (VectorRenderItem::const_iterator item = mSecondRenderItems.begin(); item != mSecondRenderItems.end(); ++item)
334  {
335  if ((*item)->isOutOfDate())
336  return true;
337  }
338 
339  for (VectorILayerNode::const_iterator item = mChildItems.begin(); item != mChildItems.end(); ++item)
340  {
341  if (static_cast<const LayerNode*>(*item)->isOutOfDate())
342  return true;
343  }
344 
345  return mOutOfDate;
346  }
347 
348 } // namespace MyGUI