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