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