MyGUI  3.2.0
MyGUI_ImageBox.cpp
Go to the documentation of this file.
1 
6 /*
7  This file is part of MyGUI.
8 
9  MyGUI is free software: you can redistribute it and/or modify
10  it under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  MyGUI is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  along with MyGUI. If not, see <http://www.gnu.org/licenses/>.
21 */
22 #include "MyGUI_Precompiled.h"
23 #include "MyGUI_ImageBox.h"
24 #include "MyGUI_CoordConverter.h"
25 #include "MyGUI_ResourceManager.h"
26 #include "MyGUI_ResourceSkin.h"
27 #include "MyGUI_RotatingSkin.h"
28 #include "MyGUI_Gui.h"
29 #include "MyGUI_TextureUtility.h"
30 
31 namespace MyGUI
32 {
33 
34  const size_t IMAGE_MAX_INDEX = 256;
35 
37  mIndexSelect(ITEM_NONE),
38  mFrameAdvise(false),
39  mCurrentTime(0),
40  mCurrentFrame(0),
41  mResource(nullptr)
42  {
43  }
44 
46  {
47  frameAdvise(false);
48 
50  }
51 
52  void ImageBox::setImageInfo(const std::string& _texture, const IntCoord& _coord, const IntSize& _tile)
53  {
54  mCurrentTextureName = _texture;
55  mSizeTexture = texture_utility::getTextureSize(mCurrentTextureName);
56 
57  mSizeTile = _tile;
58  mRectImage.left = _coord.left;
59  mRectImage.top = _coord.top;
60  mRectImage.right = _coord.left + _coord.width;
61  mRectImage.bottom = _coord.top + _coord.height;
62 
63  recalcIndexes();
64  updateSelectIndex(mIndexSelect);
65  }
66 
67  void ImageBox::setImageTile(const IntSize& _tile)
68  {
69  mSizeTile = _tile;
70 
71  // если размер еще не установлен, то ставим тот что у тайла
72  if (mRectImage.empty()) mRectImage.set(0, 0, _tile.width, _tile.height);
73  //если индекса еще нет, то ставим 0
74  if (mIndexSelect == ITEM_NONE) mIndexSelect = 0;
75 
76  recalcIndexes();
77  updateSelectIndex(mIndexSelect);
78  }
79 
80  void ImageBox::setImageCoord(const IntCoord& _coord)
81  {
82  mRectImage.left = _coord.left;
83  mRectImage.top = _coord.top;
84  mRectImage.right = _coord.left + _coord.width;
85  mRectImage.bottom = _coord.top + _coord.height;
86 
87  // если тайл еще не установлен, то ставим тот что у координат
88  if (mSizeTile.empty()) mSizeTile = _coord.size();
89  //если индекса еще нет, то ставим 0
90  if (mIndexSelect == ITEM_NONE) mIndexSelect = 0;
91 
92  recalcIndexes();
93  updateSelectIndex(mIndexSelect);
94  }
95 
96  void ImageBox::setImageRect(const IntRect& _rect)
97  {
98  mRectImage = _rect;
99 
100  // если тайл еще не установлен, то ставим тот что у координат
101  if (mSizeTile.empty()) mSizeTile.set(_rect.width(), _rect.height());
102  //если индекса еще нет, то ставим 0
103  if (mIndexSelect == ITEM_NONE) mIndexSelect = 0;
104 
105  recalcIndexes();
106  updateSelectIndex(mIndexSelect);
107  }
108 
109  void ImageBox::setImageTexture(const std::string& _texture)
110  {
111  mCurrentTextureName = _texture;
112  mSizeTexture = texture_utility::getTextureSize(mCurrentTextureName);
113 
114  // если первый раз, то ставим во всю текстуру
115  if (mItems.empty())
116  {
117  _setUVSet(FloatRect(0, 0, 1, 1));
118  _setTextureName(mCurrentTextureName);
119  }
120  else
121  {
122  recalcIndexes();
123  updateSelectIndex(mIndexSelect);
124  }
125  }
126 
127  void ImageBox::recalcIndexes()
128  {
129  mItems.clear();
130 
131  if ((mRectImage.right <= mRectImage.left) || (mRectImage.bottom <= mRectImage.top))
132  return;
133  if ((mSizeTile.width <= 0) || (mSizeTile.height <= 0))
134  return;
135 
136  size_t count_h = (size_t)(mRectImage.width() / mSizeTile.width);
137  size_t count_v = (size_t)(mRectImage.height() / mSizeTile.height);
138 
139  if ((count_h * count_v) > IMAGE_MAX_INDEX)
140  {
141  MYGUI_LOG(Warning, "Tile count very mach, rect : " << mRectImage.print() << " tile : " << mSizeTile.print() << " texture : " << _getTextureName() << " indexes : " << (count_h * count_v) << " max : " << IMAGE_MAX_INDEX);
142  return;
143  }
144 
145  int pos_h = mRectImage.left;
146  int pos_v = mRectImage.top;
147 
148  for (size_t v = 0; v < count_v; ++v)
149  {
150  for (size_t h = 0; h < count_h; ++h)
151  {
152  addItem(IntCoord(pos_h, pos_v, mSizeTile.width, mSizeTile.height));
153  pos_h += mSizeTile.width;
154  }
155  pos_v += mSizeTile.height;
156  pos_h = mRectImage.left;
157  }
158  }
159 
160  void ImageBox::updateSelectIndex(size_t _index)
161  {
162  mIndexSelect = _index;
163 
164  if ((_index == ITEM_NONE) || (_index >= mItems.size()))
165  {
166  _setTextureName("");
167  return;
168  }
169  else
170  {
171  _setTextureName(mCurrentTextureName);
172  }
173 
174  VectorImages::iterator iter = mItems.begin() + _index;
175 
176  if (iter->images.size() < 2)
177  {
178  frameAdvise(false);
179  }
180  else
181  {
182  if ( ! mFrameAdvise)
183  {
184  mCurrentTime = 0;
185  mCurrentFrame = 0;
186  }
187  frameAdvise(true);
188  }
189 
190  if ( ! iter->images.empty())
191  {
192  _setUVSet(iter->images.front());
193  }
194  }
195 
196  void ImageBox::deleteItem(size_t _index)
197  {
198  MYGUI_ASSERT_RANGE(_index, mItems.size(), "ImageBox::deleteItem");
199 
200  mItems.erase(mItems.begin() + _index);
201 
202  if (mIndexSelect != ITEM_NONE)
203  {
204  if (mItems.empty()) updateSelectIndex(ITEM_NONE);
205  else if ((_index < mIndexSelect) || (mIndexSelect == mItems.size())) updateSelectIndex(mIndexSelect--);
206  }
207  }
208 
210  {
211  updateSelectIndex(ITEM_NONE);
212  mItems.clear();
213  }
214 
215  void ImageBox::insertItem(size_t _index, const IntCoord& _item)
216  {
217  MYGUI_ASSERT_RANGE_INSERT(_index, mItems.size(), "ImageBox::insertItem");
218  if (_index == ITEM_NONE) _index = mItems.size();
219 
220  VectorImages::iterator iter = mItems.insert(mItems.begin() + _index, ImageItem());
221 
222  iter->images.push_back(CoordConverter::convertTextureCoord(_item, mSizeTexture));
223 
224  if ((mIndexSelect != ITEM_NONE) && (_index <= mIndexSelect)) updateSelectIndex(mIndexSelect++);
225  }
226 
227  void ImageBox::setItem(size_t _index, const IntCoord& _item)
228  {
229  MYGUI_ASSERT_RANGE(_index, mItems.size(), "ImageBox::setItem");
230 
231  VectorImages::iterator iter = mItems.begin() + _index;
232  iter->images.clear();
233  iter->images.push_back(CoordConverter::convertTextureCoord(_item, mSizeTexture));
234 
235  if (_index == mIndexSelect) updateSelectIndex(mIndexSelect);
236  }
237 
238  void ImageBox::frameEntered(float _frame)
239  {
240  if (mIndexSelect == ITEM_NONE) return;
241 
242  if (mItems.empty()) return;
243  VectorImages::iterator iter = mItems.begin() + mIndexSelect;
244  if ((iter->images.size() < 2) || (iter->frame_rate == 0)) return;
245 
246  mCurrentTime += _frame;
247 
248  while (mCurrentTime >= iter->frame_rate)
249  {
250  mCurrentTime -= iter->frame_rate;
251  mCurrentFrame ++;
252  if (mCurrentFrame >= (iter->images.size())) mCurrentFrame = 0;
253  }
254 
255  _setUVSet(iter->images[mCurrentFrame]);
256  }
257 
258  void ImageBox::deleteAllItemFrames(size_t _index)
259  {
260  MYGUI_ASSERT_RANGE(_index, mItems.size(), "ImageBox::clearItemFrame");
261  VectorImages::iterator iter = mItems.begin() + _index;
262  iter->images.clear();
263  }
264 
265  void ImageBox::addItemFrame(size_t _index, const IntCoord& _item)
266  {
267  MYGUI_ASSERT_RANGE(_index, mItems.size(), "ImageBox::addItemFrame");
268  VectorImages::iterator iter = mItems.begin() + _index;
269  iter->images.push_back(CoordConverter::convertTextureCoord(_item, mSizeTexture));
270  }
271 
272  void ImageBox::setItemFrameRate(size_t _index, float _rate)
273  {
274  MYGUI_ASSERT_RANGE(_index, mItems.size(), "ImageBox::setItemFrameRate");
275  VectorImages::iterator iter = mItems.begin() + _index;
276  iter->frame_rate = _rate;
277  }
278 
279  float ImageBox::getItemFrameRate(size_t _index)
280  {
281  MYGUI_ASSERT_RANGE(_index, mItems.size(), "ImageBox::getItemFrameRate");
282  VectorImages::iterator iter = mItems.begin() + _index;
283  return iter->frame_rate;
284  }
285 
286  void ImageBox::addItemFrameDublicate(size_t _index, size_t _indexSourceFrame)
287  {
288  MYGUI_ASSERT_RANGE(_index, mItems.size(), "ImageBox::addItemFrameDublicate");
289 
290  VectorImages::iterator iter = mItems.begin() + _index;
291  MYGUI_ASSERT_RANGE(_indexSourceFrame, iter->images.size(), "ImageBox::addItemFrameDublicate");
292  iter->images.push_back(iter->images[_indexSourceFrame]);
293  }
294 
295  void ImageBox::insertItemFrame(size_t _index, size_t _indexFrame, const IntCoord& _item)
296  {
297  MYGUI_ASSERT_RANGE(_index, mItems.size(), "ImageBox::insertItemFrame");
298 
299  VectorImages::iterator iter = mItems.begin() + _index;
300  MYGUI_ASSERT_RANGE_INSERT(_indexFrame, iter->images.size(), "ImageBox::insertItemFrame");
301  if (_indexFrame == ITEM_NONE) _indexFrame = iter->images.size() - 1;
302 
303  iter->images.insert(iter->images.begin() + _indexFrame,
304  CoordConverter::convertTextureCoord(_item, mSizeTexture));
305  }
306 
307  void ImageBox::insertItemFrameDublicate(size_t _index, size_t _indexFrame, size_t _indexSourceFrame)
308  {
309  MYGUI_ASSERT_RANGE(_index, mItems.size(), "ImageBox::insertItemFrameDublicate");
310 
311  VectorImages::iterator iter = mItems.begin() + _index;
312  MYGUI_ASSERT_RANGE_INSERT(_indexFrame, iter->images.size(), "ImageBox::insertItemFrameDublicate");
313  if (_indexFrame == ITEM_NONE) _indexFrame = iter->images.size() - 1;
314 
315  MYGUI_ASSERT_RANGE(_indexSourceFrame, iter->images.size(), "ImageBox::insertItemFrameDublicate");
316 
317  iter->images.insert(iter->images.begin() + _indexFrame, iter->images[_indexSourceFrame]);
318  }
319 
320  void ImageBox::setItemFrame(size_t _index, size_t _indexFrame, const IntCoord& _item)
321  {
322  MYGUI_ASSERT_RANGE(_index, mItems.size(), "ImageBox::setItemFrame");
323 
324  VectorImages::iterator iter = mItems.begin() + _index;
325  MYGUI_ASSERT_RANGE(_indexFrame, iter->images.size(), "ImageBox::setItemFrame");
326 
327  iter->images[_indexFrame] = CoordConverter::convertTextureCoord(_item, mSizeTexture);
328  }
329 
330  void ImageBox::deleteItemFrame(size_t _index, size_t _indexFrame)
331  {
332  MYGUI_ASSERT_RANGE(_index, mItems.size(), "ImageBox::deleteItemFrame");
333 
334  VectorImages::iterator iter = mItems.begin() + _index;
335  MYGUI_ASSERT_RANGE_INSERT(_indexFrame, iter->images.size(), "ImageBox::deleteItemFrame");
336  if (_indexFrame == ITEM_NONE) _indexFrame = iter->images.size() - 1;
337 
338  iter->images.erase(iter->images.begin() + _indexFrame);
339  }
340 
342  {
343  mCurrentTextureName = _info.texture;
344  mSizeTexture = texture_utility::getTextureSize(mCurrentTextureName);
345 
346  mItems.clear();
347 
348  if (_info.frames.size() != 0)
349  {
350  std::vector<IntPoint>::const_iterator iter = _info.frames.begin();
351 
352  addItem(IntCoord(*iter, _info.size));
353  setItemFrameRate(0, _info.rate);
354 
355  for (++iter; iter != _info.frames.end(); ++iter)
356  {
357  addItemFrame(0, MyGUI::IntCoord(*iter, _info.size));
358  }
359 
360  }
361 
362  mIndexSelect = 0;
363  updateSelectIndex(mIndexSelect);
364  }
365 
366  bool ImageBox::setItemResource(const std::string& _name)
367  {
368  IResourcePtr resource = ResourceManager::getInstance().getByName(_name, false);
369  setItemResourcePtr(resource ? resource->castType<ResourceImageSet>() : nullptr);
370  return resource != nullptr;
371  }
372 
374  {
375  if (mResource == _resource)
376  return;
377 
378  // если первый раз то устанавливаем дефолтное
379  if (mResource == nullptr && _resource != nullptr)
380  {
381  if (mItemGroup.empty())
382  {
383  EnumeratorGroupImage iter_group = _resource->getEnumerator();
384  while (iter_group.next())
385  {
386  mItemGroup = iter_group.current().name;
387  if (mItemName.empty() && !iter_group.current().indexes.empty())
388  {
389  mItemName = iter_group.current().indexes[0].name;
390  }
391  break;
392  }
393  }
394  else if (mItemName.empty())
395  {
396  EnumeratorGroupImage iter_group = _resource->getEnumerator();
397  while (iter_group.next())
398  {
399  if (mItemGroup == iter_group.current().name)
400  {
401  if (!iter_group.current().indexes.empty())
402  {
403  mItemName = iter_group.current().indexes[0].name;
404  break;
405  }
406  }
407  }
408  }
409  }
410 
411  mResource = _resource;
412  if (!mResource || mItemGroup.empty() || mItemName.empty()) updateSelectIndex(ITEM_NONE);
413  else setItemResourceInfo(mResource->getIndexInfo(mItemGroup, mItemName));
414  }
415 
416  void ImageBox::setItemGroup(const std::string& _group)
417  {
418  if (mItemGroup == _group)
419  return;
420 
421  mItemGroup = _group;
422  if (!mResource || mItemGroup.empty() || mItemName.empty()) updateSelectIndex(ITEM_NONE);
423  else setItemResourceInfo(mResource->getIndexInfo(mItemGroup, mItemName));
424  }
425 
426  void ImageBox::setItemName(const std::string& _name)
427  {
428  if (mItemName == _name)
429  return;
430 
431  mItemName = _name;
432  if (!mResource || mItemGroup.empty() || mItemName.empty()) updateSelectIndex(ITEM_NONE);
433  else setItemResourceInfo(mResource->getIndexInfo(mItemGroup, mItemName));
434  }
435 
436  void ImageBox::setItemResourceInfo(ResourceImageSetPtr _resource, const std::string& _group, const std::string& _name)
437  {
438  mResource = _resource;
439  mItemGroup = _group;
440  mItemName = _name;
441  if (!mResource || mItemGroup.empty() || mItemName.empty()) updateSelectIndex(ITEM_NONE);
442  else setItemResourceInfo(mResource->getIndexInfo(mItemGroup, mItemName));
443  }
444 
445  void ImageBox::frameAdvise(bool _advise)
446  {
447  if ( _advise )
448  {
449  if ( ! mFrameAdvise )
450  {
451  MyGUI::Gui::getInstance().eventFrameStart += MyGUI::newDelegate( this, &ImageBox::frameEntered );
452  mFrameAdvise = true;
453  }
454  }
455  else
456  {
457  if ( mFrameAdvise )
458  {
459  MyGUI::Gui::getInstance().eventFrameStart -= MyGUI::newDelegate( this, &ImageBox::frameEntered );
460  mFrameAdvise = false;
461  }
462  }
463  }
464 
465  void ImageBox::setImageIndex(size_t _index)
466  {
467  setItemSelect(_index);
468  }
469 
470  size_t ImageBox::getImageIndex() const
471  {
472  return getItemSelect();
473  }
474 
475  void ImageBox::setItemSelect(size_t _index)
476  {
477  if (mIndexSelect != _index) updateSelectIndex(_index);
478  }
479 
480  void ImageBox::_setUVSet(const FloatRect& _rect)
481  {
482  if (nullptr != getSubWidgetMain())
483  getSubWidgetMain()->_setUVSet(_rect);
484  }
485 
486  void ImageBox::setPropertyOverride(const std::string& _key, const std::string& _value)
487  {
488  if (_key == "ImageTexture")
489  setImageTexture(_value);
490  else if (_key == "ImageCoord")
491  setImageCoord(utility::parseValue<IntCoord>(_value));
492  else if (_key == "ImageTile")
493  setImageTile(utility::parseValue<IntSize>(_value));
494  else if (_key == "ImageIndex")
495  setItemSelect(utility::parseValue<size_t>(_value));
496  else if (_key == "ImageResource")
497  setItemResource(_value);
498  else if (_key == "ImageGroup")
499  setItemGroup(_value);
500  else if (_key == "ImageName")
501  setItemName(_value);
502  else
503  {
504  Base::setPropertyOverride(_key, _value);
505  return;
506  }
507  eventChangeProperty(this, _key, _value);
508  }
509 
510  size_t ImageBox::getItemCount() const
511  {
512  return mItems.size();
513  }
514 
515  size_t ImageBox::getItemSelect() const
516  {
517  return mIndexSelect;
518  }
519 
521  {
523  }
524 
525  void ImageBox::addItem(const IntCoord& _item)
526  {
527  insertItem(ITEM_NONE, _item);
528  }
529 
531  {
532  return mResource;
533  }
534 
535 } // namespace MyGUI
bool empty() const
Definition: MyGUI_TRect.h:151
void addItem(const IntCoord &_item)
Add an item to the end of a list.
bool empty() const
Definition: MyGUI_TSize.h:123
void setImageTexture(const std::string &_value)
virtual void setPropertyOverride(const std::string &_key, const std::string &_value)
EventHandle_FrameEventDelegate eventFrameStart
Definition: MyGUI_Gui.h:166
const IntSize & size
ImageIndexInfo getIndexInfo(const std::string &_group, const std::string &_index)
void setItemResourceInfo(const ImageIndexInfo &_info)
void setImageTile(const IntSize &_value)
delegates::IDelegate0 * newDelegate(void(*_func)())
static ResourceManager & getInstance()
const IntSize & getTextureSize(const std::string &_texture, bool _cache=true)
TSize< T > size() const
Definition: MyGUI_TCoord.h:205
void setItemFrameRate(size_t _index, float _rate)
void insertItemFrame(size_t _index, size_t _indexFrame, const IntCoord &_item)
void set(T const &_width, T const &_height)
Definition: MyGUI_TSize.h:110
void deleteAllItems()
Delete all items.
size_t getItemSelect() const
Get index of selected item (ITEM_NONE if none selected)
const std::string & _getTextureName() const
const size_t ITEM_NONE
Definition: MyGUI_Macros.h:32
#define nullptr
virtual void _setUVSet(const FloatRect &_rect)
void insertItem(size_t _index, const IntCoord &_item)
Insert an item into a list at a specified position.
void _setTextureName(const std::string &_texture)
const size_t IMAGE_MAX_INDEX
types::TCoord< int > IntCoord
Definition: MyGUI_Types.h:50
float getItemFrameRate(size_t _index)
void resetItemSelect()
Reset item selection.
void deleteAllItemFrames(size_t _index)
IResource * getByName(const std::string &_name, bool _throw=true) const
ISubWidgetRect * getSubWidgetMain()
#define MYGUI_LOG(level, text)
void deleteItemFrame(size_t _index, size_t _indexFrame)
size_t getItemCount() const
Get number of items.
void setItemFrame(size_t _index, size_t _indexFrame, const IntCoord &_item)
void insertItemFrameDublicate(size_t _index, size_t _indexFrame, size_t _indexSourceFrame)
void addItemFrame(size_t _index, const IntCoord &_item)
std::string print() const
Definition: MyGUI_TSize.h:128
void setImageRect(const IntRect &_value)
EventHandle_WidgetStringString eventChangeProperty
Definition: MyGUI_Widget.h:271
size_t getImageIndex() const
void deleteItem(size_t _index)
Delete item at a specified position.
void setImageIndex(size_t _index)
std::string print() const
Definition: MyGUI_TRect.h:171
const std::string & texture
void setItem(size_t _index, const IntCoord &_item)
Replace an item at a specified position.
void setItemName(const std::string &_value)
bool setItemResource(const std::string &_name)
Type * castType(bool _throw=true)
Definition: MyGUI_IObject.h:33
void set(T const &_left, T const &_top, T const &_right, T const &_bottom)
Definition: MyGUI_TRect.h:136
ResourceImageSetPtr getItemResource() const
types::TRect< float > FloatRect
Definition: MyGUI_Types.h:48
void setItemGroup(const std::string &_value)
#define MYGUI_ASSERT_RANGE(index, size, owner)
void setItemSelect(size_t _index)
Select specified _index.
virtual void shutdownOverride()
EnumeratorGroupImage getEnumerator() const
static FloatRect convertTextureCoord(const IntCoord &_coord, const IntSize &_textureSize)
void setImageCoord(const IntCoord &_value)
void setItemResourcePtr(ResourceImageSetPtr _resource)
void addItemFrameDublicate(size_t _index, size_t _indexSourceFrame)
T::const_reference current()
#define MYGUI_ASSERT_RANGE_INSERT(index, size, owner)
void setImageInfo(const std::string &_texture, const IntCoord &_coord, const IntSize &_tile)
const std::vector< IntPoint > & frames