MyGUI  3.0.3
MyGUI_StaticImage.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_StaticImage.h"
00025 #include "MyGUI_CoordConverter.h"
00026 #include "MyGUI_ResourceManager.h"
00027 #include "MyGUI_ResourceSkin.h"
00028 #include "MyGUI_RotatingSkin.h"
00029 #include "MyGUI_Gui.h"
00030 #include "MyGUI_TextureUtility.h"
00031 
00032 namespace MyGUI
00033 {
00034 
00035     const size_t IMAGE_MAX_INDEX = 256;
00036 
00037     StaticImage::StaticImage() :
00038         mIndexSelect(ITEM_NONE),
00039         mFrameAdvise(false),
00040         mCurrentTime(0),
00041         mCurrentFrame(0),
00042         mResource(nullptr)
00043     {
00044     }
00045 
00046     void StaticImage::_initialise(WidgetStyle _style, const IntCoord& _coord, Align _align, ResourceSkin* _info, Widget* _parent, ICroppedRectangle * _croppedParent, IWidgetCreator * _creator, const std::string& _name)
00047     {
00048         Base::_initialise(_style, _coord, _align, _info, _parent, _croppedParent, _creator, _name);
00049 
00050         initialiseWidgetSkin(_info);
00051     }
00052 
00053     StaticImage::~StaticImage()
00054     {
00055         shutdownWidgetSkin();
00056     }
00057 
00058     void StaticImage::baseChangeWidgetSkin(ResourceSkin* _info)
00059     {
00060         shutdownWidgetSkin();
00061         Base::baseChangeWidgetSkin(_info);
00062         initialiseWidgetSkin(_info);
00063     }
00064 
00065     void StaticImage::initialiseWidgetSkin(ResourceSkin* _info)
00066     {
00067         // парсим свойства
00068         const MapString& properties = _info->getProperties();
00069         if ( ! properties.empty() )
00070         {
00071             MapString::const_iterator iter = properties.end();
00072             if ((iter = properties.find("ImageTexture")) != properties.end()) setImageTexture(iter->second);
00073             if ((iter = properties.find("ImageRect")) != properties.end()) setImageRect(IntRect::parse(iter->second));
00074             if ((iter = properties.find("ImageCoord")) != properties.end()) setImageCoord(IntCoord::parse(iter->second));
00075             if ((iter = properties.find("ImageTile")) != properties.end()) setImageTile(IntSize::parse(iter->second));
00076             if ((iter = properties.find("ImageIndex")) != properties.end()) setImageIndex(utility::parseInt(iter->second));
00077             if ((iter = properties.find("ImageResource")) != properties.end()) setItemResource(iter->second);
00078             if ((iter = properties.find("ImageGroup")) != properties.end()) setItemGroup(iter->second);
00079             if ((iter = properties.find("ImageName")) != properties.end()) setItemName(iter->second);
00080         }
00081     }
00082 
00083     void StaticImage::shutdownWidgetSkin()
00084     {
00085         frameAdvise(false);
00086     }
00087 
00088     void StaticImage::setImageInfo(const std::string& _texture, const IntCoord& _coord, const IntSize& _tile)
00089     {
00090         mCurrentTextureName = _texture;
00091         mSizeTexture = texture_utility::getTextureSize(mCurrentTextureName);
00092 
00093         mSizeTile = _tile;
00094         mRectImage.left = _coord.left;
00095         mRectImage.top = _coord.top;
00096         mRectImage.right = _coord.left + _coord.width;
00097         mRectImage.bottom = _coord.top + _coord.height;
00098 
00099         recalcIndexes();
00100         updateSelectIndex(mIndexSelect);
00101     }
00102 
00103     void StaticImage::setImageTile(const IntSize& _tile)
00104     {
00105         mSizeTile = _tile;
00106 
00107         // если размер еще не установлен, то ставим тот что у тайла
00108         if (mRectImage.empty()) mRectImage.set(0, 0, _tile.width, _tile.height);
00109         //если индекса еще нет, то ставим 0
00110         if (mIndexSelect == ITEM_NONE) mIndexSelect = 0;
00111 
00112         recalcIndexes();
00113         updateSelectIndex(mIndexSelect);
00114     }
00115 
00116     void StaticImage::setImageCoord(const IntCoord& _coord)
00117     {
00118         mRectImage.left = _coord.left;
00119         mRectImage.top = _coord.top;
00120         mRectImage.right = _coord.left + _coord.width;
00121         mRectImage.bottom = _coord.top + _coord.height;
00122 
00123         // если тайл еще не установлен, то ставим тот что у координат
00124         if (mSizeTile.empty()) mSizeTile = _coord.size();
00125         //если индекса еще нет, то ставим 0
00126         if (mIndexSelect == ITEM_NONE) mIndexSelect = 0;
00127 
00128         recalcIndexes();
00129         updateSelectIndex(mIndexSelect);
00130     }
00131 
00132     void StaticImage::setImageRect(const IntRect& _rect)
00133     {
00134         mRectImage= _rect;
00135 
00136         // если тайл еще не установлен, то ставим тот что у координат
00137         if (mSizeTile.empty()) mSizeTile.set(_rect.width(), _rect.height());
00138         //если индекса еще нет, то ставим 0
00139         if (mIndexSelect == ITEM_NONE) mIndexSelect = 0;
00140 
00141         recalcIndexes();
00142         updateSelectIndex(mIndexSelect);
00143     }
00144 
00145     void StaticImage::setImageTexture(const std::string& _texture)
00146     {
00147         mCurrentTextureName = _texture;
00148         mSizeTexture = texture_utility::getTextureSize(mCurrentTextureName);
00149 
00150         // если первый раз, то ставим во всю текстуру
00151         if (mItems.empty())
00152         {
00153             _setUVSet(FloatRect(0, 0, 1, 1));
00154             _setTextureName(mCurrentTextureName);
00155         }
00156         else
00157         {
00158             recalcIndexes();
00159             updateSelectIndex(mIndexSelect);
00160         }
00161     }
00162 
00163     void StaticImage::recalcIndexes()
00164     {
00165         mItems.clear();
00166 
00167         if ((mRectImage.right <= mRectImage.left) || (mRectImage.bottom <= mRectImage.top)) return;
00168         if ((mSizeTile.width <= 0) || (mSizeTile.height <= 0)) return;
00169 
00170         size_t count_h = (size_t)(mRectImage.width() / mSizeTile.width);
00171         size_t count_v = (size_t)(mRectImage.height() / mSizeTile.height);
00172 
00173         if ((count_h * count_v) > IMAGE_MAX_INDEX)
00174         {
00175             MYGUI_LOG(Warning, "Tile count very mach, rect : " << mRectImage.print() << " tile : " << mSizeTile.print() << " texture : " << mTextureName << " indexes : " << (count_h * count_v) << " max : " << IMAGE_MAX_INDEX);
00176             return;
00177         }
00178 
00179         int pos_h = mRectImage.left;
00180         int pos_v = mRectImage.top;
00181 
00182         for (size_t v=0; v<count_v; ++v)
00183         {
00184             for (size_t h=0; h<count_h; ++h)
00185             {
00186                 addItem(IntCoord(pos_h, pos_v, mSizeTile.width, mSizeTile.height));
00187                 pos_h += mSizeTile.width;
00188             }
00189             pos_v += mSizeTile.height;
00190             pos_h = mRectImage.left;
00191         }
00192     }
00193 
00194     void StaticImage::updateSelectIndex(size_t _index)
00195     {
00196         mIndexSelect = _index;
00197 
00198         if ((_index == ITEM_NONE) || (_index >= mItems.size()))
00199         {
00200             _setTextureName("");
00201             return;
00202         }
00203         else
00204         {
00205             _setTextureName(mCurrentTextureName);
00206         }
00207 
00208         VectorImages::iterator iter = mItems.begin() + _index;
00209 
00210         if (iter->images.size() < 2)
00211         {
00212             frameAdvise(false);
00213         }
00214         else
00215         {
00216             if ( ! mFrameAdvise)
00217             {
00218                 mCurrentTime = 0;
00219                 mCurrentFrame = 0;
00220             }
00221             frameAdvise(true);
00222         }
00223 
00224         if ( ! iter->images.empty())
00225         {
00226             _setUVSet(iter->images.front());
00227         }
00228     }
00229 
00230     void StaticImage::deleteItem(size_t _index)
00231     {
00232         MYGUI_ASSERT_RANGE(_index, mItems.size(), "StaticImage::deleteItem");
00233 
00234         mItems.erase(mItems.begin() + _index);
00235 
00236         if (mIndexSelect != ITEM_NONE)
00237         {
00238             if (mItems.empty()) updateSelectIndex(ITEM_NONE);
00239             else if ((_index < mIndexSelect) || (mIndexSelect == mItems.size())) updateSelectIndex(mIndexSelect--);
00240         }
00241     }
00242 
00243     void StaticImage::deleteAllItems()
00244     {
00245         updateSelectIndex(ITEM_NONE);
00246         mItems.clear();
00247     }
00248 
00249     void StaticImage::insertItem(size_t _index, const IntCoord& _item)
00250     {
00251         MYGUI_ASSERT_RANGE_INSERT(_index, mItems.size(), "StaticImage::insertItem");
00252         if (_index == ITEM_NONE) _index = mItems.size();
00253 
00254         VectorImages::iterator iter = mItems.insert(mItems.begin() + _index, ImageItem());
00255 
00256         iter->images.push_back(CoordConverter::convertTextureCoord(_item, mSizeTexture));
00257 
00258         if ((mIndexSelect != ITEM_NONE) && (_index <= mIndexSelect)) updateSelectIndex(mIndexSelect++);
00259     }
00260 
00261     void StaticImage::setItem(size_t _index, const IntCoord& _item)
00262     {
00263         MYGUI_ASSERT_RANGE(_index, mItems.size(), "StaticImage::setItem");
00264 
00265         VectorImages::iterator iter = mItems.begin() + _index;
00266         iter->images.clear();
00267         iter->images.push_back(CoordConverter::convertTextureCoord(_item, mSizeTexture));
00268 
00269         if (_index == mIndexSelect) updateSelectIndex(mIndexSelect);
00270     }
00271 
00272     void StaticImage::frameEntered(float _frame)
00273     {
00274         if (mIndexSelect == ITEM_NONE) return;
00275 
00276         if (mItems.empty()) return;
00277         VectorImages::iterator iter = mItems.begin() + mIndexSelect;
00278         if ((iter->images.size() < 2) || (iter->frame_rate == 0)) return;
00279 
00280         mCurrentTime += _frame;
00281 
00282         while (mCurrentTime >= iter->frame_rate)
00283         {
00284             mCurrentTime -= iter->frame_rate;
00285             mCurrentFrame ++;
00286             if (mCurrentFrame >= (iter->images.size())) mCurrentFrame = 0;
00287         }
00288 
00289         _setUVSet(iter->images[mCurrentFrame]);
00290     }
00291 
00292     void StaticImage::deleteAllItemFrames(size_t _index)
00293     {
00294         MYGUI_ASSERT_RANGE(_index, mItems.size(), "StaticImage::clearItemFrame");
00295         VectorImages::iterator iter = mItems.begin() + _index;
00296         iter->images.clear();
00297     }
00298 
00299     void StaticImage::addItemFrame(size_t _index, const IntCoord& _item)
00300     {
00301         MYGUI_ASSERT_RANGE(_index, mItems.size(), "StaticImage::addItemFrame");
00302         VectorImages::iterator iter = mItems.begin() + _index;
00303         iter->images.push_back(CoordConverter::convertTextureCoord(_item, mSizeTexture));
00304     }
00305 
00306     void StaticImage::setItemFrameRate(size_t _index, float _rate)
00307     {
00308         MYGUI_ASSERT_RANGE(_index, mItems.size(), "StaticImage::setItemFrameRate");
00309         VectorImages::iterator iter = mItems.begin() + _index;
00310         iter->frame_rate = _rate;
00311     }
00312 
00313     float StaticImage::getItemFrameRate(size_t _index)
00314     {
00315         MYGUI_ASSERT_RANGE(_index, mItems.size(), "StaticImage::getItemFrameRate");
00316         VectorImages::iterator iter = mItems.begin() + _index;
00317         return iter->frame_rate;
00318     }
00319 
00320     void StaticImage::addItemFrameDublicate(size_t _index, size_t _indexSourceFrame)
00321     {
00322         MYGUI_ASSERT_RANGE(_index, mItems.size(), "StaticImage::addItemFrameDublicate");
00323 
00324         VectorImages::iterator iter = mItems.begin() + _index;
00325         MYGUI_ASSERT_RANGE(_indexSourceFrame, iter->images.size(), "StaticImage::addItemFrameDublicate");
00326         iter->images.push_back(iter->images[_indexSourceFrame]);
00327     }
00328 
00329     void StaticImage::insertItemFrame(size_t _index, size_t _indexFrame, const IntCoord& _item)
00330     {
00331         MYGUI_ASSERT_RANGE(_index, mItems.size(), "StaticImage::insertItemFrame");
00332 
00333         VectorImages::iterator iter = mItems.begin() + _index;
00334         MYGUI_ASSERT_RANGE_INSERT(_indexFrame, iter->images.size(), "StaticImage::insertItemFrame");
00335         if (_indexFrame == ITEM_NONE) _indexFrame = iter->images.size() - 1;
00336 
00337         iter->images.insert(iter->images.begin() + _indexFrame,
00338             CoordConverter::convertTextureCoord(_item, mSizeTexture));
00339     }
00340 
00341     void StaticImage::insertItemFrameDublicate(size_t _index, size_t _indexFrame, size_t _indexSourceFrame)
00342     {
00343         MYGUI_ASSERT_RANGE(_index, mItems.size(), "StaticImage::insertItemFrameDublicate");
00344 
00345         VectorImages::iterator iter = mItems.begin() + _index;
00346         MYGUI_ASSERT_RANGE_INSERT(_indexFrame, iter->images.size(), "StaticImage::insertItemFrameDublicate");
00347         if (_indexFrame == ITEM_NONE) _indexFrame = iter->images.size() - 1;
00348 
00349         MYGUI_ASSERT_RANGE(_indexSourceFrame, iter->images.size(), "StaticImage::insertItemFrameDublicate");
00350 
00351         iter->images.insert(iter->images.begin() + _indexFrame, iter->images[_indexSourceFrame]);
00352     }
00353 
00354     void StaticImage::setItemFrame(size_t _index, size_t _indexFrame, const IntCoord& _item)
00355     {
00356         MYGUI_ASSERT_RANGE(_index, mItems.size(), "StaticImage::setItemFrame");
00357 
00358         VectorImages::iterator iter = mItems.begin() + _index;
00359         MYGUI_ASSERT_RANGE(_indexFrame, iter->images.size(), "StaticImage::setItemFrame");
00360 
00361         iter->images[_indexFrame] = CoordConverter::convertTextureCoord(_item, mSizeTexture);
00362     }
00363 
00364     void StaticImage::deleteItemFrame(size_t _index, size_t _indexFrame)
00365     {
00366         MYGUI_ASSERT_RANGE(_index, mItems.size(), "StaticImage::deleteItemFrame");
00367 
00368         VectorImages::iterator iter = mItems.begin() + _index;
00369         MYGUI_ASSERT_RANGE_INSERT(_indexFrame, iter->images.size(), "StaticImage::deleteItemFrame");
00370         if (_indexFrame == ITEM_NONE) _indexFrame = iter->images.size() - 1;
00371 
00372         iter->images.erase(iter->images.begin() + _indexFrame);
00373     }
00374 
00375     void StaticImage::setItemResourceInfo(const ImageIndexInfo& _info)
00376     {
00377         mCurrentTextureName = _info.texture;
00378         mSizeTexture = texture_utility::getTextureSize(mCurrentTextureName);
00379 
00380         mItems.clear();
00381 
00382         if (_info.frames.size() != 0)
00383         {
00384             std::vector<IntPoint>::const_iterator iter = _info.frames.begin();
00385 
00386             addItem(IntCoord(*iter, _info.size));
00387             setItemFrameRate(0, _info.rate);
00388 
00389             for (++iter; iter!=_info.frames.end(); ++iter)
00390             {
00391                 addItemFrame(0, MyGUI::IntCoord(*iter, _info.size));
00392             }
00393 
00394         }
00395 
00396         mIndexSelect = 0;
00397         updateSelectIndex(mIndexSelect);
00398     }
00399 
00400     bool StaticImage::setItemResource(const Guid& _id)
00401     {
00402         IResourcePtr resource = _id.empty() ? nullptr : ResourceManager::getInstance().getByID(_id, false);
00403         setItemResourcePtr(resource ? resource->castType<ResourceImageSet>() : nullptr);
00404         return resource != nullptr;
00405     }
00406 
00407     bool StaticImage::setItemResource(const std::string& _name)
00408     {
00409         IResourcePtr resource = ResourceManager::getInstance().getByName(_name, false);
00410         setItemResourcePtr(resource ? resource->castType<ResourceImageSet>() : nullptr);
00411         return resource != nullptr;
00412     }
00413 
00414     void StaticImage::setItemResourcePtr(ResourceImageSetPtr _resource)
00415     {
00416         if (mResource == _resource)
00417             return;
00418 
00419         // если первый раз то устанавливаем дефолтное
00420         if (mResource == nullptr && _resource != nullptr)
00421         {
00422             if (mItemGroup.empty())
00423             {
00424                 EnumeratorGroupImage iter_group = _resource->getEnumerator();
00425                 while (iter_group.next())
00426                 {
00427                     mItemGroup = iter_group.current().name;
00428                     if (mItemName.empty() && !iter_group.current().indexes.empty())
00429                     {
00430                         mItemName = iter_group.current().indexes[0].name;
00431                     }
00432                     break;
00433                 }
00434             }
00435             else if (mItemName.empty())
00436             {
00437                 EnumeratorGroupImage iter_group = _resource->getEnumerator();
00438                 while (iter_group.next())
00439                 {
00440                     if (mItemGroup == iter_group.current().name)
00441                     {
00442                         if (!iter_group.current().indexes.empty())
00443                         {
00444                             mItemName = iter_group.current().indexes[0].name;
00445                             break;
00446                         }
00447                     }
00448                 }
00449             }
00450         }
00451 
00452         mResource = _resource;
00453         if (!mResource || mItemGroup.empty() || mItemName.empty()) updateSelectIndex(ITEM_NONE);
00454         else setItemResourceInfo(mResource->getIndexInfo(mItemGroup, mItemName));
00455     }
00456 
00457     void StaticImage::setItemGroup(const std::string& _group)
00458     {
00459         if (mItemGroup == _group)
00460             return;
00461 
00462         mItemGroup = _group;
00463         if (!mResource || mItemGroup.empty() || mItemName.empty()) updateSelectIndex(ITEM_NONE);
00464         else setItemResourceInfo(mResource->getIndexInfo(mItemGroup, mItemName));
00465     }
00466 
00467     void StaticImage::setItemName(const std::string& _name)
00468     {
00469         if (mItemName == _name)
00470             return;
00471 
00472         mItemName = _name;
00473         if (!mResource || mItemGroup.empty() || mItemName.empty()) updateSelectIndex(ITEM_NONE);
00474         else setItemResourceInfo(mResource->getIndexInfo(mItemGroup, mItemName));
00475     }
00476 
00477     void StaticImage::setItemResourceInfo(ResourceImageSetPtr _resource, const std::string& _group, const std::string& _name)
00478     {
00479         mResource = _resource;
00480         mItemGroup = _group;
00481         mItemName = _name;
00482         if (!mResource || mItemGroup.empty() || mItemName.empty()) updateSelectIndex(ITEM_NONE);
00483         else setItemResourceInfo(mResource->getIndexInfo(mItemGroup, mItemName));
00484     }
00485 
00486     void StaticImage::frameAdvise(bool _advise)
00487     {
00488         if ( _advise )
00489         {
00490             if ( ! mFrameAdvise )
00491             {
00492                 MyGUI::Gui::getInstance().eventFrameStart += MyGUI::newDelegate( this, &StaticImage::frameEntered );
00493                 mFrameAdvise = true;
00494             }
00495         }
00496         else
00497         {
00498             if ( mFrameAdvise )
00499             {
00500                 MyGUI::Gui::getInstance().eventFrameStart -= MyGUI::newDelegate( this, &StaticImage::frameEntered );
00501                 mFrameAdvise = false;
00502             }
00503         }
00504     }
00505 
00506     void StaticImage::setImageIndex(size_t _index)
00507     {
00508         setItemSelect(_index);
00509     }
00510 
00511     size_t StaticImage::getImageIndex()
00512     {
00513         return getItemSelect();
00514     }
00515 
00516     void StaticImage::setItemSelect(size_t _index)
00517     {
00518         if (mIndexSelect != _index) updateSelectIndex(_index);
00519     }
00520 
00521     void StaticImage::setProperty(const std::string& _key, const std::string& _value)
00522     {
00523         if (_key == "Image_Texture") setImageTexture(_value);
00524         else if (_key == "Image_Coord") setImageCoord(utility::parseValue<IntCoord>(_value));
00525         else if (_key == "Image_Tile") setImageTile(utility::parseValue<IntSize>(_value));
00526         else if (_key == "Image_Index") setItemSelect(utility::parseValue<size_t>(_value));
00527         else if (_key == "Image_Resource") setItemResource(_value);
00528         else if (_key == "Image_Group") setItemGroup(_value);
00529         else if (_key == "Image_Name") setItemName(_value);
00530         else
00531         {
00532             Base::setProperty(_key, _value);
00533             return;
00534         }
00535         eventChangeProperty(this, _key, _value);
00536     }
00537 
00538 } // namespace MyGUI