MyGUI 3.4.3
MyGUI_RotatingSkin.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"
9#include "MyGUI_RenderItem.h"
11#include "MyGUI_RenderManager.h"
13
14namespace MyGUI
15{
16
21
22 void RotatingSkin::setAngle(float _angle)
23 {
24 mAngle = _angle;
25 mGeometryOutdated = true;
26
27 if (nullptr != mNode)
28 mNode->outOfDate(mRenderItem);
29 }
30
31 void RotatingSkin::setCenter(const IntPoint& _center)
32 {
33 mCenterPos = _center;
34 mGeometryOutdated = true;
35
36 if (nullptr != mNode)
37 mNode->outOfDate(mRenderItem);
38 }
39
41 {
42 return mCenterPos + (_local ? IntPoint() : mCroppedParent->getAbsolutePosition());
43 }
44
45 void RotatingSkin::setVisible(bool _visible)
46 {
47 if (mVisible == _visible)
48 return;
49
50 mVisible = _visible;
51 mGeometryOutdated = true;
52
53 if (nullptr != mNode)
54 mNode->outOfDate(mRenderItem);
55 }
56
57 void RotatingSkin::setAlpha(float _alpha)
58 {
59 uint32 alpha = ((uint8)(_alpha * 255) << 24);
60 mCurrentColour = (mCurrentColour & 0x00FFFFFF) | (alpha & 0xFF000000);
61
62 if (nullptr != mNode)
63 mNode->outOfDate(mRenderItem);
64 }
65
67 {
68 mGeometryOutdated = true;
69
70 if (nullptr != mNode)
71 mNode->outOfDate(mRenderItem);
72 }
73
74 void RotatingSkin::_setAlign(const IntSize& _oldsize)
75 {
76 // первоначальное выравнивание
77 if (mAlign.isHStretch())
78 {
79 // растягиваем
80 mCoord.width = mCoord.width + (mCroppedParent->getWidth() - _oldsize.width);
81 mIsMargin = true; // при изменении размеров все пересчитывать
82 }
83 else if (mAlign.isRight())
84 {
85 // двигаем по правому краю
86 mCoord.left = mCoord.left + (mCroppedParent->getWidth() - _oldsize.width);
87 }
88 else if (mAlign.isHCenter())
89 {
90 // выравнивание по горизонтали без растяжения
91 mCoord.left = (mCroppedParent->getWidth() - mCoord.width) / 2;
92 }
93
94 if (mAlign.isVStretch())
95 {
96 // растягиваем
97 mCoord.height = mCoord.height + (mCroppedParent->getHeight() - _oldsize.height);
98 mIsMargin = true; // при изменении размеров все пересчитывать
99 }
100 else if (mAlign.isBottom())
101 {
102 // двигаем по нижнему краю
103 mCoord.top = mCoord.top + (mCroppedParent->getHeight() - _oldsize.height);
104 }
105 else if (mAlign.isVCenter())
106 {
107 // выравнивание по вертикали без растяжения
108 mCoord.top = (mCroppedParent->getHeight() - mCoord.height) / 2;
109 }
110
111 mCurrentCoord = mCoord;
112 _updateView();
113 }
114
116 {
117 mEmptyView = ((0 >= _getViewWidth()) || (0 >= _getViewHeight()));
118
119 mGeometryOutdated = true;
120
121 if (nullptr != mNode)
122 mNode->outOfDate(mRenderItem);
123 }
124
126 {
127 MYGUI_ASSERT(!mRenderItem, "mRenderItem must be nullptr");
128
129 mNode = _node;
130 mRenderItem = mNode->addToRenderItem(_texture, true, false);
131 mRenderItem->addDrawItem(this, (GEOMETRY_VERTICIES_TOTAL_COUNT - 2) * 3);
132 }
133
135 {
136 MYGUI_ASSERT(mRenderItem, "mRenderItem must be not nullptr");
137
138 mNode = nullptr;
139 mRenderItem->removeDrawItem(this);
140 mRenderItem = nullptr;
141 }
142
144 {
145 if (!mVisible || mEmptyView)
146 return;
147
148 Vertex* verticies = mRenderItem->getCurrentVertexBuffer();
149
150 float vertex_z = mNode->getNodeDepth();
151
152 if (mGeometryOutdated)
153 {
155 mGeometryOutdated = false;
156 }
157
158 for (int i = 1; i < GEOMETRY_VERTICIES_TOTAL_COUNT - 1; ++i)
159 {
160 verticies[3 * i - 3].set(
161 mResultVerticiesPos[0].left,
162 mResultVerticiesPos[0].top,
163 vertex_z,
164 mResultVerticiesUV[0].left,
165 mResultVerticiesUV[0].top,
166 mCurrentColour);
167 verticies[3 * i - 2].set(
168 mResultVerticiesPos[i].left,
169 mResultVerticiesPos[i].top,
170 vertex_z,
171 mResultVerticiesUV[i].left,
172 mResultVerticiesUV[i].top,
173 mCurrentColour);
174 verticies[3 * i - 1].set(
175 mResultVerticiesPos[i + 1].left,
176 mResultVerticiesPos[i + 1].top,
177 vertex_z,
178 mResultVerticiesUV[i + 1].left,
179 mResultVerticiesUV[i + 1].top,
180 mCurrentColour);
181 }
182
183 mRenderItem->setLastVertexCount((GEOMETRY_VERTICIES_TOTAL_COUNT - 2) * 3);
184 }
185
187 {
188 uint32 colour = texture_utility::toNativeColour(_value, mVertexFormat);
189 mCurrentColour = (colour & 0x00FFFFFF) | (mCurrentColour & 0xFF000000);
190
191 if (nullptr != mNode)
192 mNode->outOfDate(mRenderItem);
193 }
194
196 {
198
199 setAngle(data->getAngle());
200 setCenter(data->getCenter());
201
202 _setUVSet(data->getRect());
203 }
204
206 {
207 mCurrentTexture = _rect;
208
209 mGeometryOutdated = true;
210
211 if (nullptr != mNode)
212 mNode->outOfDate(mRenderItem);
213 }
214
215 inline float len(float x, float y)
216 {
217 return std::sqrt(x * x + y * y);
218 }
219
221 {
222 /*
223 0 1
224 3 2
225 */
226#ifdef M_PI
227 #undef M_PI
228#endif
229 const float M_PI = 3.141593f;
230
231 float width_base = (float)mCurrentCoord.width;
232 float height_base = (float)mCurrentCoord.height;
233
234 // calculate original unrotated angles of uncropped rectangle verticies: between axis and line from center of rotation to vertex)
235 float baseAngles[RECT_VERTICIES_COUNT];
236 baseAngles[0] = std::atan2((float)mCenterPos.left, (float)mCenterPos.top) + M_PI / 2;
237 baseAngles[1] = std::atan2(-width_base + (float)mCenterPos.left, (float)mCenterPos.top) + M_PI / 2;
238 baseAngles[2] =
239 std::atan2(-width_base + (float)mCenterPos.left, -height_base + (float)mCenterPos.top) + M_PI / 2;
240 baseAngles[3] = std::atan2((float)mCenterPos.left, -height_base + (float)mCenterPos.top) + M_PI / 2;
241
242 // calculate original unrotated distances of uncropped rectangle verticies: between center of rotation and vertex)
243 float baseDistances[RECT_VERTICIES_COUNT];
244 baseDistances[0] = len((float)mCenterPos.left, (float)mCenterPos.top);
245 baseDistances[1] = len(-width_base + (float)mCenterPos.left, (float)mCenterPos.top);
246 baseDistances[2] = len(-width_base + (float)mCenterPos.left, -height_base + (float)mCenterPos.top);
247 baseDistances[3] = len((float)mCenterPos.left, -height_base + (float)mCenterPos.top);
248
249
250 // calculate rotated positions of uncropped rectangle verticies (relative to parent)
251 FloatPoint baseVerticiesPos[RECT_VERTICIES_COUNT];
252
253 int offsetX = /*mCurrentCoord.left +*/ mCenterPos.left;
254 int offsetY = /*mCurrentCoord.top +*/ mCenterPos.top;
255
256 for (int i = 0; i < RECT_VERTICIES_COUNT; ++i)
257 {
258 baseVerticiesPos[i].left = offsetX + std::cos(-mAngle + baseAngles[i]) * baseDistances[i];
259 baseVerticiesPos[i].top = offsetY - std::sin(-mAngle + baseAngles[i]) * baseDistances[i];
260 }
261
262 // base texture coordinates
263 FloatPoint baseVerticiesUV[RECT_VERTICIES_COUNT] = {
264 FloatPoint(mCurrentTexture.left, mCurrentTexture.top),
265 FloatPoint(mCurrentTexture.right, mCurrentTexture.top),
266 FloatPoint(mCurrentTexture.right, mCurrentTexture.bottom),
267 FloatPoint(mCurrentTexture.left, mCurrentTexture.bottom)};
268
269 // now we have rotated uncropped rectangle verticies coordinates
270
271 // --------- here the cropping starts ---------
272
273 // now we are going to calculate verticies of resulting figure
274
275 // no parent - no cropping
276 size_t size = RECT_VERTICIES_COUNT;
277 if (nullptr == mCroppedParent->getCroppedParent())
278 {
279 for (int i = 0; i < RECT_VERTICIES_COUNT; ++i)
280 {
281 mResultVerticiesPos[i] = baseVerticiesPos[i];
282 mResultVerticiesUV[i] = baseVerticiesUV[i];
283 }
284 }
285 else
286 {
287 ICroppedRectangle* parent = mCroppedParent->getCroppedParent();
288
290 baseVerticiesPos,
291 RECT_VERTICIES_COUNT,
292 IntCoord(
293 parent->_getMarginLeft() - mCroppedParent->getLeft(),
294 parent->_getMarginTop() - mCroppedParent->getTop(),
295 parent->_getViewWidth(),
296 parent->_getViewHeight()));
297
298 for (size_t i = 0; i < resultVerticiesPos.size(); ++i)
299 {
300 mResultVerticiesPos[i] = resultVerticiesPos[i];
301 }
302
303 size = resultVerticiesPos.size();
304
305 // calculate texture coordinates
306 FloatPoint v0 = baseVerticiesUV[3] - baseVerticiesUV[0];
307 FloatPoint v1 = baseVerticiesUV[1] - baseVerticiesUV[0];
308 for (size_t i = 0; i < GEOMETRY_VERTICIES_TOTAL_COUNT; ++i)
309 {
310 if (i < size)
311 {
313 mResultVerticiesPos[i],
314 baseVerticiesPos[0],
315 baseVerticiesPos[1],
316 baseVerticiesPos[3]);
317 mResultVerticiesUV[i] =
318 geometry_utility::getUVFromPositionInsideRect(point, v0, v1, baseVerticiesUV[0]);
319 }
320 else
321 {
322 // all unused verticies is equal to last used
323 mResultVerticiesUV[i] = mResultVerticiesUV[size == 0 ? 0 : (size - 1)];
324 }
325 }
326 }
327
328
329 // now calculate widget base offset and then resulting position in screen coordinates
330 const RenderTargetInfo& info = mRenderItem->getRenderTarget()->getInfo();
331 float vertex_left_base = ((info.pixScaleX * (float)(mCroppedParent->getAbsoluteLeft()) + info.hOffset) * 2) - 1;
332 float vertex_top_base =
333 -(((info.pixScaleY * (float)(mCroppedParent->getAbsoluteTop()) + info.vOffset) * 2) - 1);
334
335 for (size_t i = 0; i < GEOMETRY_VERTICIES_TOTAL_COUNT; ++i)
336 {
337 if (i < size)
338 {
339 mResultVerticiesPos[i].left = vertex_left_base + mResultVerticiesPos[i].left * info.pixScaleX * 2;
340 mResultVerticiesPos[i].top = vertex_top_base + mResultVerticiesPos[i].top * info.pixScaleY * -2;
341 }
342 else
343 {
344 // all unused verticies is equal to last used
345 mResultVerticiesPos[i] = mResultVerticiesPos[size == 0 ? 0 : (size - 1)];
346 }
347 }
348 }
349
351 {
352 return mAngle;
353 }
354
355} // namespace MyGUI
#define MYGUI_ASSERT(exp, dest)
virtual RenderItem * addToRenderItem(ITexture *_texture, bool _firstQueue, bool _separate)=0
Type * castType(bool _throw=true)
void addDrawItem(ISubWidget *_item, size_t _count)
virtual VertexColourType getVertexFormat() const =0
static RenderManager & getInstance()
void setAlpha(float _alpha) override
void setAngle(float _angle)
void _setColour(const Colour &_value) override
void _setUVSet(const FloatRect &_rect) override
IntPoint getCenter(bool _local=true) const
void setStateData(IStateInfo *_data) override
void _correctView() override
void destroyDrawItem() override
void setVisible(bool _visible) override
void createDrawItem(ITexture *_texture, ILayerNode *_node) override
void setCenter(const IntPoint &_center)
void _setAlign(const IntSize &_oldsize) override
const IntPoint & getCenter() const
const FloatRect & getRect() const
FloatPoint getUVFromPositionInsideRect(const FloatPoint &_point, const FloatPoint &_v0, const FloatPoint &_v1, const FloatPoint &_baseUV)
FloatPoint getPositionInsideRect(const FloatPoint &_point, const FloatPoint &_corner0, const FloatPoint &_corner1, const FloatPoint &_corner2)
VectorFloatPoint cropPolygon(FloatPoint *_baseVerticiesPos, size_t _size, const IntCoord &_cropRectangle)
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::TPoint< int > IntPoint
Definition MyGUI_Types.h:27
types::TRect< float > FloatRect
Definition MyGUI_Types.h:34
types::TPoint< float > FloatPoint
Definition MyGUI_Types.h:28
std::vector< FloatPoint > VectorFloatPoint
types::TCoord< int > IntCoord
Definition MyGUI_Types.h:36
types::TSize< int > IntSize
Definition MyGUI_Types.h:30
float len(float x, float y)
void set(float _x, float _y, float _z, float _u, float _v, uint32 _colour)