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