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