• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

MyGUI_SubSkin.cpp

Go to the documentation of this file.
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 
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;//_update;
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         //mAbsolutePosition = mCroppedParent->getAbsolutePosition() + mCoord.point();
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 } // namespace MyGUI

Generated on Sun Jan 30 2011 for MyGUI by  doxygen 1.7.1