MyGUI
3.2.1
|
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