00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "MyGUI_Precompiled.h"
00024 #include "MyGUI_SubSkin.h"
00025 #include "MyGUI_RenderItem.h"
00026 #include "MyGUI_SkinManager.h"
00027 #include "MyGUI_LanguageManager.h"
00028 #include "MyGUI_LayerNode.h"
00029 #include "MyGUI_CommonStateInfo.h"
00030
00031 namespace MyGUI
00032 {
00033
00034 SubSkin::SubSkin() :
00035 ISubWidgetRect(),
00036 mEmptyView(false),
00037 mCurrentAlpha(0xFFFFFFFF),
00038 mNode(nullptr),
00039 mRenderItem(nullptr)
00040 {
00041 }
00042
00043 SubSkin::~SubSkin()
00044 {
00045 }
00046
00047 void SubSkin::setVisible(bool _visible)
00048 {
00049 if (mVisible == _visible) return;
00050 mVisible = _visible;
00051
00052 if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00053 }
00054
00055 void SubSkin::setAlpha(float _alpha)
00056 {
00057 mCurrentAlpha = 0x00FFFFFF | ((uint8)(_alpha*255) << 24);
00058 if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00059 }
00060
00061 void SubSkin::_correctView()
00062 {
00063 if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00064 }
00065
00066 void SubSkin::_setAlign(const IntCoord& _oldcoord, bool _update)
00067 {
00068 _setAlign(_oldcoord.size(), _update);
00069 }
00070
00071 void SubSkin::_setAlign(const IntSize& _oldsize, bool _update)
00072 {
00073
00074 bool need_update = true;
00075
00076
00077 if (mAlign.isHStretch())
00078 {
00079
00080 mCoord.width = mCoord.width + (mCroppedParent->getWidth() - _oldsize.width);
00081 need_update = true;
00082 mIsMargin = true;
00083 }
00084 else if (mAlign.isRight())
00085 {
00086
00087 mCoord.left = mCoord.left + (mCroppedParent->getWidth() - _oldsize.width);
00088 need_update = true;
00089 }
00090 else if (mAlign.isHCenter())
00091 {
00092
00093 mCoord.left = (mCroppedParent->getWidth() - mCoord.width) / 2;
00094 need_update = true;
00095 }
00096
00097 if (mAlign.isVStretch())
00098 {
00099
00100 mCoord.height = mCoord.height + (mCroppedParent->getHeight() - _oldsize.height);
00101 need_update = true;
00102 mIsMargin = true;
00103 }
00104 else if (mAlign.isBottom())
00105 {
00106
00107 mCoord.top = mCoord.top + (mCroppedParent->getHeight() - _oldsize.height);
00108 need_update = true;
00109 }
00110 else if (mAlign.isVCenter())
00111 {
00112
00113 mCoord.top = (mCroppedParent->getHeight() - mCoord.height) / 2;
00114 need_update = true;
00115 }
00116
00117 if (need_update)
00118 {
00119 mCurrentCoord = mCoord;
00120 _updateView();
00121 }
00122
00123 }
00124
00125 void SubSkin::_updateView()
00126 {
00127
00128 bool margin = _checkMargin();
00129
00130 mEmptyView = ((0 >= _getViewWidth()) || (0 >= _getViewHeight()));
00131
00132 mCurrentCoord.left = mCoord.left + mMargin.left;
00133 mCurrentCoord.top = mCoord.top + mMargin.top;
00134
00135
00136 if (margin)
00137 {
00138
00139 if (_checkOutside())
00140 {
00141
00142
00143 mIsMargin = margin;
00144
00145
00146 if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00147 return;
00148 }
00149 }
00150
00151
00152 if ( mIsMargin || margin )
00153 {
00154 mCurrentCoord.width = _getViewWidth();
00155 mCurrentCoord.height = _getViewHeight();
00156
00157 if ( (mCurrentCoord.width > 0) && (mCurrentCoord.height > 0) )
00158 {
00159
00160 float UV_lft = mMargin.left / (float)mCoord.width;
00161 float UV_top = mMargin.top / (float)mCoord.height;
00162 float UV_rgt = (mCoord.width - mMargin.right) / (float)mCoord.width;
00163 float UV_btm = (mCoord.height - mMargin.bottom) / (float)mCoord.height;
00164
00165 float UV_sizeX = mRectTexture.right - mRectTexture.left;
00166 float UV_sizeY = mRectTexture.bottom - mRectTexture.top;
00167
00168 float UV_lft_total = mRectTexture.left + UV_lft * UV_sizeX;
00169 float UV_top_total = mRectTexture.top + UV_top * UV_sizeY;
00170 float UV_rgt_total = mRectTexture.right - (1-UV_rgt) * UV_sizeX;
00171 float UV_btm_total = mRectTexture.bottom - (1-UV_btm) * UV_sizeY;
00172
00173 mCurrentTexture.set(UV_lft_total, UV_top_total, UV_rgt_total, UV_btm_total);
00174 }
00175 }
00176
00177 if (mIsMargin && !margin)
00178 {
00179
00180 mCurrentTexture = mRectTexture;
00181 }
00182
00183
00184 mIsMargin = margin;
00185
00186 if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00187 }
00188
00189 void SubSkin::createDrawItem(const std::string& _texture, ILayerNode * _node)
00190 {
00191 MYGUI_ASSERT(!mRenderItem, "mRenderItem must be nullptr");
00192
00193 mNode = _node;
00194 mRenderItem = mNode->addToRenderItem(_texture, this);
00195 mRenderItem->addDrawItem(this, VertexQuad::VertexCount);
00196 }
00197
00198 void SubSkin::destroyDrawItem()
00199 {
00200 MYGUI_ASSERT(mRenderItem, "mRenderItem must be not nullptr");
00201
00202 mNode = nullptr;
00203 mRenderItem->removeDrawItem(this);
00204 mRenderItem = nullptr;
00205 }
00206
00207 void SubSkin::_setUVSet(const FloatRect& _rect)
00208 {
00209 if (mRectTexture == _rect) return;
00210 mRectTexture = _rect;
00211
00212
00213 if (mIsMargin)
00214 {
00215 float UV_lft = mMargin.left / (float)mCoord.width;
00216 float UV_top = mMargin.top / (float)mCoord.height;
00217 float UV_rgt = (mCoord.width - mMargin.right) / (float)mCoord.width;
00218 float UV_btm = (mCoord.height - mMargin.bottom) / (float)mCoord.height;
00219
00220 float UV_sizeX = mRectTexture.right - mRectTexture.left;
00221 float UV_sizeY = mRectTexture.bottom - mRectTexture.top;
00222
00223 float UV_lft_total = mRectTexture.left + UV_lft * UV_sizeX;
00224 float UV_top_total = mRectTexture.top + UV_top * UV_sizeY;
00225 float UV_rgt_total = mRectTexture.right - (1-UV_rgt) * UV_sizeX;
00226 float UV_btm_total = mRectTexture.bottom - (1-UV_btm) * UV_sizeY;
00227
00228 mCurrentTexture.set(UV_lft_total, UV_top_total, UV_rgt_total, UV_btm_total);
00229 }
00230
00231
00232 else
00233 {
00234 mCurrentTexture = mRectTexture;
00235 }
00236
00237 if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00238 }
00239
00240 void SubSkin::doRender()
00241 {
00242 if (!mVisible || mEmptyView) return;
00243
00244 VertexQuad* quad = (VertexQuad*)mRenderItem->getCurrentVertextBuffer();
00245
00246 const RenderTargetInfo& info = mRenderItem->getRenderTarget()->getInfo();
00247
00248 float vertex_z = info.maximumDepth;
00249
00250 float vertex_left = ((info.pixScaleX * (float)(mCurrentCoord.left + mCroppedParent->getAbsoluteLeft() - info.leftOffset) + info.hOffset) * 2) - 1;
00251 float vertex_right = vertex_left + (info.pixScaleX * (float)mCurrentCoord.width * 2);
00252 float vertex_top = -(((info.pixScaleY * (float)(mCurrentCoord.top + mCroppedParent->getAbsoluteTop() - info.topOffset) + info.vOffset) * 2) - 1);
00253 float vertex_bottom = vertex_top - (info.pixScaleY * (float)mCurrentCoord.height * 2);
00254
00255 quad->set(
00256 vertex_left,
00257 vertex_top,
00258 vertex_right,
00259 vertex_bottom,
00260 vertex_z,
00261 mCurrentTexture.left,
00262 mCurrentTexture.top,
00263 mCurrentTexture.right,
00264 mCurrentTexture.bottom,
00265 mCurrentAlpha
00266 );
00267
00268 mRenderItem->setLastVertexCount(VertexQuad::VertexCount);
00269 }
00270
00271 void SubSkin::setStateData(IStateInfo* _data)
00272 {
00273 _setUVSet(_data->castType<SubSkinStateInfo>()->getRect());
00274 }
00275
00276 }