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