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