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