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