MyGUI  3.0.1
MyGUI_TileRect.cpp
Go to the documentation of this file.
1 
7 /*
8  This file is part of MyGUI.
9 
10  MyGUI is free software: you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  MyGUI is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with MyGUI. If not, see <http://www.gnu.org/licenses/>.
22 */
23 #include "MyGUI_Precompiled.h"
24 #include "MyGUI_TileRect.h"
25 #include "MyGUI_RenderItem.h"
26 #include "MyGUI_SkinManager.h"
27 #include "MyGUI_LanguageManager.h"
28 #include "MyGUI_LayerNode.h"
29 #include "MyGUI_CommonStateInfo.h"
30 #include "MyGUI_RenderManager.h"
31 #include "MyGUI_TextureUtility.h"
32 
33 namespace MyGUI
34 {
35 
37 
39  mEmptyView(false),
40  mCurrentColour(0xFFFFFFFF),
41  mNode(nullptr),
42  mRenderItem(nullptr),
43  mCountVertex(TILERECT_COUNT_VERTEX),
44  mRealTileWidth(0),
45  mRealTileHeight(0),
46  mTextureHeightOne(0),
47  mTextureWidthOne(0),
48  mTileH(true),
49  mTileV(true)
50  {
51  }
52 
54  {
55  }
56 
57  void TileRect::setVisible(bool _visible)
58  {
59  if (mVisible == _visible) return;
60  mVisible = _visible;
61 
62  if (nullptr != mNode) mNode->outOfDate(mRenderItem);
63  }
64 
65  void TileRect::setAlpha(float _alpha)
66  {
67  uint32 alpha = ((uint8)(_alpha*255) << 24);
68  mCurrentColour = (mCurrentColour & 0x00FFFFFF) | (alpha & 0xFF000000);
69 
70  if (nullptr != mNode) mNode->outOfDate(mRenderItem);
71  }
72 
74  {
75  if (nullptr != mNode) mNode->outOfDate(mRenderItem);
76  }
77 
78  void TileRect::_setAlign(const IntCoord& _oldcoord, bool _update)
79  {
80  _setAlign(_oldcoord.size(), _update);
81  }
82 
83  void TileRect::_setAlign(const IntSize& _oldsize, bool _update)
84  {
85  // необходимо разобраться
86  bool need_update = true;//_update;
87 
88  // первоначальное выравнивание
89  if (mAlign.isHStretch())
90  {
91  // растягиваем
92  mCoord.width = mCoord.width + (mCroppedParent->getWidth() - _oldsize.width);
93  need_update = true;
94  mIsMargin = true; // при изменении размеров все пересчитывать
95  }
96  else if (mAlign.isRight())
97  {
98  // двигаем по правому краю
99  mCoord.left = mCoord.left + (mCroppedParent->getWidth() - _oldsize.width);
100  need_update = true;
101  }
102  else if (mAlign.isHCenter())
103  {
104  // выравнивание по горизонтали без растяжения
106  need_update = true;
107  }
108 
109  if (mAlign.isVStretch())
110  {
111  // растягиваем
113  need_update = true;
114  mIsMargin = true; // при изменении размеров все пересчитывать
115  }
116  else if (mAlign.isBottom())
117  {
118  // двигаем по нижнему краю
119  mCoord.top = mCoord.top + (mCroppedParent->getHeight() - _oldsize.height);
120  need_update = true;
121  }
122  else if (mAlign.isVCenter())
123  {
124  // выравнивание по вертикали без растяжения
126  need_update = true;
127  }
128 
129  if (need_update)
130  {
134  _updateView();
135  }
136 
137  }
138 
140  {
141  bool margin = _checkMargin();
142 
143  mEmptyView = ((0 >= _getViewWidth()) || (0 >= _getViewHeight()));
144 
149 
150  // подсчитываем необходимое колличество тайлов
151  if (!mEmptyView)
152  {
153  size_t count = 0;
154  if (!mTileSize.empty())
155  {
156  size_t count_x = mCoord.width / mTileSize.width;
157  if ((mCoord.width % mTileSize.width) > 0) count_x ++;
158  size_t count_y = mCoord.height / mTileSize.height;
159  if ((mCoord.height % mTileSize.height) > 0) count_y ++;
160  count = count_y * count_x * VertexQuad::VertexCount;
161  }
162 
163  // нужно больше вершин
164  if (count > mCountVertex)
165  {
167  if (nullptr != mRenderItem) mRenderItem->reallockDrawItem(this, mCountVertex);
168  }
169  }
170 
171  // вьюпорт стал битым
172  if (margin)
173  {
174  // проверка на полный выход за границу
175  if (_checkOutside())
176  {
177  // запоминаем текущее состояние
178  mIsMargin = margin;
179 
180  // обновить перед выходом
181  if (nullptr != mNode) mNode->outOfDate(mRenderItem);
182  return;
183  }
184  }
185 
186  // запоминаем текущее состояние
187  mIsMargin = margin;
188 
189  if (nullptr != mNode) mNode->outOfDate(mRenderItem);
190  }
191 
192  void TileRect::_setUVSet(const FloatRect& _rect)
193  {
194  mCurrentTexture = _rect;
195  if (nullptr != mNode) mNode->outOfDate(mRenderItem);
196  }
197 
199  {
200  if (!mVisible || mEmptyView || mTileSize.empty()) return;
201 
203 
205 
206  // размер одного тайла
207  mRealTileWidth = info.pixScaleX * (float)(mTileSize.width) * 2;
208  mRealTileHeight = info.pixScaleY * (float)(mTileSize.height) * 2;
209 
212 
213  float vertex_z = info.maximumDepth;
214 
215  // абсолютный размер окна
216  float window_left = ((info.pixScaleX * (float)(mCoord.left + mCroppedParent->getAbsoluteLeft() - info.leftOffset) + info.hOffset) * 2) - 1;
217  float window_top = -(((info.pixScaleY * (float)(mCoord.top + mCroppedParent->getAbsoluteTop() - info.topOffset) + info.vOffset) * 2) - 1);
218 
219  // размер вьюпорта
220  float real_left = ((info.pixScaleX * (float)(mCurrentCoord.left + mCroppedParent->getAbsoluteLeft() - info.leftOffset) + info.hOffset) * 2) - 1;
221  float real_right = real_left + (info.pixScaleX * (float)mCurrentCoord.width * 2);
222  float real_top = -(((info.pixScaleY * (float)(mCurrentCoord.top + mCroppedParent->getAbsoluteTop() - info.topOffset) + info.vOffset) * 2) - 1);
223  float real_bottom = real_top - (info.pixScaleY * (float)mCurrentCoord.height * 2);
224 
225  size_t count = 0;
226 
227  float left = window_left;
228  float right = window_left;
229  float top = window_top;
230  float bottom = window_top;
231 
232  for (int y=0; y<mCoord.height; y+=mTileSize.height)
233  {
234  top = bottom;
235  bottom -= mRealTileHeight;
236  right = window_left;
237 
238  float vertex_top = top;
239  float vertex_bottom = bottom;
240  bool texture_crop_height = false;
241 
242  if (vertex_top > real_top)
243  {
244  // проверка на полный выход
245  if (vertex_bottom > real_top)
246  {
247  continue;
248  }
249  // обрезаем
250  vertex_top = real_top;
251  texture_crop_height = true;
252  }
253  if (vertex_bottom < real_bottom)
254  {
255  // вообще вниз ушли
256  if (vertex_top < real_bottom)
257  {
258  continue;
259  }
260  // обрезаем
261  vertex_bottom = real_bottom;
262  texture_crop_height = true;
263  }
264 
265  for (int x=0; x<mCoord.width; x+=mTileSize.width)
266  {
267  left = right;
268  right += mRealTileWidth;
269 
270  float vertex_left = left;
271  float vertex_right = right;
272  bool texture_crop_width = false;
273 
274 
275  if (vertex_left < real_left)
276  {
277  // проверка на полный выход
278  if (vertex_right < real_left)
279  {
280  continue;
281  }
282  // обрезаем
283  vertex_left = real_left;
284  texture_crop_width = true;
285  }
286 
287  if (vertex_right > real_right)
288  {
289  // вообще строку до конца не нуна
290  if (vertex_left > real_right)
291  {
292  continue;
293  }
294  // обрезаем
295  vertex_right = real_right;
296  texture_crop_width = true;
297  }
298 
299  // текущие текстурные координаты
300  float texture_left = mCurrentTexture.left;
301  float texture_right = mCurrentTexture.right;
302  float texture_top = mCurrentTexture.top;
303  float texture_bottom = mCurrentTexture.bottom;
304 
305  // смещение текстуры по вертикили
306  if (texture_crop_height)
307  {
308  // прибавляем размер смещения в текстурных координатах
309  texture_top += (top - vertex_top) * mTextureHeightOne;
310  // отнимаем размер смещения в текстурных координатах
311  texture_bottom -= (vertex_bottom - bottom) * mTextureHeightOne;
312  }
313 
314  // смещение текстуры по горизонтали
315  if (texture_crop_width)
316  {
317  // прибавляем размер смещения в текстурных координатах
318  texture_left += (vertex_left - left) * mTextureWidthOne;
319  // отнимаем размер смещения в текстурных координатах
320  texture_right -= (right - vertex_right) * mTextureWidthOne;
321  }
322 
323  quad[count].set(
324  vertex_left,
325  vertex_top,
326  vertex_right,
327  vertex_bottom,
328  vertex_z,
329  texture_left,
330  texture_top,
331  texture_right,
332  texture_bottom,
334  );
335 
336  count ++;
337  }
338  }
339 
341  }
342 
344  {
345  MYGUI_ASSERT(!mRenderItem, "mRenderItem must be nullptr");
346 
347  mNode = _node;
348  mRenderItem = mNode->addToRenderItem(_texture, this);
350  }
351 
353  {
354  MYGUI_ASSERT(mRenderItem, "mRenderItem must be not nullptr");
355 
356  mNode = nullptr;
358  mRenderItem = nullptr;
359  }
360 
362  {
363  TileRectStateInfo* data = _data->castType<TileRectStateInfo>();
364 
365  mTileSize = data->getTileSize();
366  mTileH = data->getTileH();
367  mTileV = data->getTileV();
368  _setUVSet(data->getRect());
369  }
370 
371  void TileRect::_setColour(const Colour& _value)
372  {
373  uint32 colour = texture_utility::toColourARGB(_value);
374  texture_utility::convertColour(colour, RenderManager::getInstance().getVertexFormat());
375  mCurrentColour = (colour & 0x00FFFFFF) | (mCurrentColour & 0xFF000000);
376 
377  if (nullptr != mNode)
379  }
380 
381 } // namespace MyGUI