MyGUI 3.4.3
MyGUI_TileRect.cpp
Go to the documentation of this file.
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_TileRect.h"
9#include "MyGUI_RenderItem.h"
10#include "MyGUI_SkinManager.h"
12#include "MyGUI_LayerNode.h"
14#include "MyGUI_RenderManager.h"
16
17namespace MyGUI
18{
19
21
27
28 void TileRect::setVisible(bool _visible)
29 {
30 if (mVisible == _visible)
31 return;
32 mVisible = _visible;
33
34 if (nullptr != mNode)
35 mNode->outOfDate(mRenderItem);
36 }
37
38 void TileRect::setAlpha(float _alpha)
39 {
40 uint32 alpha = ((uint8)(_alpha * 255) << 24);
41 mCurrentColour = (mCurrentColour & 0x00FFFFFF) | (alpha & 0xFF000000);
42
43 if (nullptr != mNode)
44 mNode->outOfDate(mRenderItem);
45 }
46
48 {
49 if (nullptr != mNode)
50 mNode->outOfDate(mRenderItem);
51 }
52
53 void TileRect::_setAlign(const IntSize& _oldsize)
54 {
55 // первоначальное выравнивание
56 if (mAlign.isHStretch())
57 {
58 // растягиваем
59 mCoord.width = mCoord.width + (mCroppedParent->getWidth() - _oldsize.width);
60 mIsMargin = true; // при изменении размеров все пересчитывать
61 }
62 else if (mAlign.isRight())
63 {
64 // двигаем по правому краю
65 mCoord.left = mCoord.left + (mCroppedParent->getWidth() - _oldsize.width);
66 }
67 else if (mAlign.isHCenter())
68 {
69 // выравнивание по горизонтали без растяжения
70 mCoord.left = (mCroppedParent->getWidth() - mCoord.width) / 2;
71 }
72
73 if (mAlign.isVStretch())
74 {
75 // растягиваем
76 mCoord.height = mCoord.height + (mCroppedParent->getHeight() - _oldsize.height);
77 mIsMargin = true; // при изменении размеров все пересчитывать
78 }
79 else if (mAlign.isBottom())
80 {
81 // двигаем по нижнему краю
82 mCoord.top = mCoord.top + (mCroppedParent->getHeight() - _oldsize.height);
83 }
84 else if (mAlign.isVCenter())
85 {
86 // выравнивание по вертикали без растяжения
87 mCoord.top = (mCroppedParent->getHeight() - mCoord.height) / 2;
88 }
89
91 if (!mTileH)
92 mTileSize.width = mCoord.width;
93 if (!mTileV)
94 mTileSize.height = mCoord.height;
96 }
97
99 {
100 bool margin = _checkMargin();
101
102 mEmptyView = ((0 >= _getViewWidth()) || (0 >= _getViewHeight()));
103
104 mCurrentCoord.left = mCoord.left + mMargin.left;
105 mCurrentCoord.top = mCoord.top + mMargin.top;
107 mCurrentCoord.height = _getViewHeight();
108
109 // подсчитываем необходимое колличество тайлов
110 if (!mEmptyView)
111 {
112 size_t count = 0;
113 if (!mTileSize.empty())
114 {
115 size_t count_x = mCoord.width / mTileSize.width;
116 if ((mCoord.width % mTileSize.width) > 0)
117 count_x++;
118
119 size_t count_y = mCoord.height / mTileSize.height;
120 if ((mCoord.height % mTileSize.height) > 0)
121 count_y++;
122
123 count = count_y * count_x * VertexQuad::VertexCount;
124 }
125
126 // нужно больше вершин
127 if (count > mCountVertex)
128 {
130 if (nullptr != mRenderItem)
131 mRenderItem->reallockDrawItem(this, mCountVertex);
132 }
133 }
134
135 // вьюпорт стал битым
136 if (margin)
137 {
138 // проверка на полный выход за границу
139 if (_checkOutside())
140 {
141 // запоминаем текущее состояние
142 mIsMargin = margin;
143
144 // обновить перед выходом
145 if (nullptr != mNode)
146 mNode->outOfDate(mRenderItem);
147 return;
148 }
149 }
150
151 // запоминаем текущее состояние
152 mIsMargin = margin;
153
154 if (nullptr != mNode)
155 mNode->outOfDate(mRenderItem);
156 }
157
159 {
160 mCurrentTexture = _rect;
161 if (nullptr != mNode)
162 mNode->outOfDate(mRenderItem);
163 }
164
166 {
167 if (!mVisible || mEmptyView || mTileSize.empty())
168 return;
169
170 VertexQuad* quad = reinterpret_cast<VertexQuad*>(mRenderItem->getCurrentVertexBuffer());
171
172 const RenderTargetInfo& info = mRenderItem->getRenderTarget()->getInfo();
173
174 // размер одного тайла
175 mRealTileWidth = info.pixScaleX * (float)(mTileSize.width) * 2;
176 mRealTileHeight = info.pixScaleY * (float)(mTileSize.height) * 2;
177
180
181 float vertex_z = mNode->getNodeDepth();
182
183 // абсолютный размер окна
184 float window_left =
185 ((info.pixScaleX * (float)(mCoord.left + mCroppedParent->getAbsoluteLeft() - info.leftOffset) +
186 info.hOffset) *
187 2) -
188 1;
189 float window_top = -(
190 ((info.pixScaleY * (float)(mCoord.top + mCroppedParent->getAbsoluteTop() - info.topOffset) + info.vOffset) *
191 2) -
192 1);
193
194 // размер вьюпорта
195 float real_left =
196 ((info.pixScaleX * (float)(mCurrentCoord.left + mCroppedParent->getAbsoluteLeft() - info.leftOffset) +
197 info.hOffset) *
198 2) -
199 1;
200 float real_right = real_left + (info.pixScaleX * (float)mCurrentCoord.width * 2);
201 float real_top =
202 -(((info.pixScaleY * (float)(mCurrentCoord.top + mCroppedParent->getAbsoluteTop() - info.topOffset) +
203 info.vOffset) *
204 2) -
205 1);
206 float real_bottom = real_top - (info.pixScaleY * (float)mCurrentCoord.height * 2);
207
208 size_t count = 0;
209
210 float bottom = window_top;
211
212 for (int y = 0; y < mCoord.height; y += mTileSize.height)
213 {
214 float top = bottom;
215 bottom -= mRealTileHeight;
216 float right = window_left;
217
218 float vertex_top = top;
219 float vertex_bottom = bottom;
220 bool texture_crop_height = false;
221
222 if (vertex_top > real_top)
223 {
224 // проверка на полный выход
225 if (vertex_bottom > real_top)
226 {
227 continue;
228 }
229 // обрезаем
230 vertex_top = real_top;
231 texture_crop_height = true;
232 }
233 if (vertex_bottom < real_bottom)
234 {
235 // вообще вниз ушли
236 if (vertex_top < real_bottom)
237 {
238 continue;
239 }
240 // обрезаем
241 vertex_bottom = real_bottom;
242 texture_crop_height = true;
243 }
244
245 for (int x = 0; x < mCoord.width; x += mTileSize.width)
246 {
247 float left = right;
248 right += mRealTileWidth;
249
250 float vertex_left = left;
251 float vertex_right = right;
252 bool texture_crop_width = false;
253
254
255 if (vertex_left < real_left)
256 {
257 // проверка на полный выход
258 if (vertex_right < real_left)
259 {
260 continue;
261 }
262 // обрезаем
263 vertex_left = real_left;
264 texture_crop_width = true;
265 }
266
267 if (vertex_right > real_right)
268 {
269 // вообще строку до конца не нуна
270 if (vertex_left > real_right)
271 {
272 continue;
273 }
274 // обрезаем
275 vertex_right = real_right;
276 texture_crop_width = true;
277 }
278
279 // текущие текстурные координаты
280 float texture_left = mCurrentTexture.left;
281 float texture_right = mCurrentTexture.right;
282 float texture_top = mCurrentTexture.top;
283 float texture_bottom = mCurrentTexture.bottom;
284
285 // смещение текстуры по вертикили
286 if (texture_crop_height)
287 {
288 // прибавляем размер смещения в текстурных координатах
289 texture_top += (top - vertex_top) * mTextureHeightOne;
290 // отнимаем размер смещения в текстурных координатах
291 texture_bottom -= (vertex_bottom - bottom) * mTextureHeightOne;
292 }
293
294 // смещение текстуры по горизонтали
295 if (texture_crop_width)
296 {
297 // прибавляем размер смещения в текстурных координатах
298 texture_left += (vertex_left - left) * mTextureWidthOne;
299 // отнимаем размер смещения в текстурных координатах
300 texture_right -= (right - vertex_right) * mTextureWidthOne;
301 }
302
303 quad[count].set(
304 vertex_left,
305 vertex_top,
306 vertex_right,
307 vertex_bottom,
308 vertex_z,
309 texture_left,
310 texture_top,
311 texture_right,
312 texture_bottom,
314
315 count++;
316 }
317 }
318
319 mRenderItem->setLastVertexCount(VertexQuad::VertexCount * count);
320 }
321
323 {
324 MYGUI_ASSERT(!mRenderItem, "mRenderItem must be nullptr");
325
326 mNode = _node;
327 mRenderItem = mNode->addToRenderItem(_texture, true, false);
328 mRenderItem->addDrawItem(this, mCountVertex);
329 }
330
332 {
333 MYGUI_ASSERT(mRenderItem, "mRenderItem must be not nullptr");
334
335 mNode = nullptr;
336 mRenderItem->removeDrawItem(this);
337 mRenderItem = nullptr;
338 }
339
341 {
343
344 mTileSize = data->getTileSize();
345 mTileH = data->getTileH();
346 mTileV = data->getTileV();
347 _setUVSet(data->getRect());
348 }
349
350 void TileRect::_setColour(const Colour& _value)
351 {
353 mCurrentColour = (colour & 0x00FFFFFF) | (mCurrentColour & 0xFF000000);
354
355 if (nullptr != mNode)
356 mNode->outOfDate(mRenderItem);
357 }
358
359} // namespace MyGUI
#define MYGUI_ASSERT(exp, dest)
Type * castType(bool _throw=true)
virtual VertexColourType getVertexFormat() const =0
static RenderManager & getInstance()
void _setAlign(const IntSize &_oldsize) override
RenderItem * mRenderItem
FloatRect mCurrentTexture
void _setUVSet(const FloatRect &_rect) override
IntCoord mCurrentCoord
void setVisible(bool _visible) override
void createDrawItem(ITexture *_texture, ILayerNode *_node) override
void _setColour(const Colour &_value) override
void setStateData(IStateInfo *_data) override
void _correctView() override
ILayerNode * mNode
void setAlpha(float _alpha) override
void doRender() override
VertexColourType mVertexFormat
void destroyDrawItem() override
void _updateView() override
const FloatRect & getRect() const
const IntSize & getTileSize() const
uint32 toNativeColour(const Colour &_colour, VertexColourType _format)
Convert Colour to 32-bit representation.
uint32_t uint32
Definition MyGUI_Types.h:48
uint8_t uint8
Definition MyGUI_Types.h:46
types::TRect< float > FloatRect
Definition MyGUI_Types.h:34
const size_t TILERECT_COUNT_VERTEX
types::TSize< int > IntSize
Definition MyGUI_Types.h:30
void set(float _l, float _t, float _r, float _b, float _z, float _u1, float _v1, float _u2, float _v2, uint32 _colour)