MyGUI 3.4.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"
11#include "MyGUI_ResourceSkin.h"
12#include "MyGUI_RotatingSkin.h"
13#include "MyGUI_Gui.h"
15
16namespace 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
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
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
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
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) const
259 {
260 MYGUI_ASSERT_RANGE(_index, mItems.size(), "ImageBox::getItemFrameRate");
261 VectorImages::const_iterator iter = mItems.begin() + _index;
262 return iter->frame_rate;
263 }
264
265 void ImageBox::addItemFrameDuplicate(size_t _index, size_t _indexSourceFrame)
266 {
267 MYGUI_ASSERT_RANGE(_index, mItems.size(), "ImageBox::addItemFrameDuplicate");
268
269 VectorImages::iterator iter = mItems.begin() + _index;
270 MYGUI_ASSERT_RANGE(_indexSourceFrame, iter->images.size(), "ImageBox::addItemFrameDuplicate");
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::insertItemFrameDuplicate(size_t _index, size_t _indexFrame, size_t _indexSourceFrame)
287 {
288 MYGUI_ASSERT_RANGE(_index, mItems.size(), "ImageBox::insertItemFrameDuplicate");
289
290 VectorImages::iterator iter = mItems.begin() + _index;
291 MYGUI_ASSERT_RANGE_INSERT(_indexFrame, iter->images.size(), "ImageBox::insertItemFrameDuplicate");
292 if (_indexFrame == ITEM_NONE) _indexFrame = iter->images.size() - 1;
293
294 MYGUI_ASSERT_RANGE(_indexSourceFrame, iter->images.size(), "ImageBox::insertItemFrameDuplicate");
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
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
510 {
511 return mItems.size();
512 }
513
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
#define MYGUI_ASSERT_RANGE_INSERT(index, size, owner)
#define MYGUI_ASSERT_RANGE(index, size, owner)
#define MYGUI_LOG(level, text)
static FloatRect convertTextureCoord(const IntCoord &_coord, const IntSize &_textureSize)
T::const_reference current()
static Gui & getInstance()
EventHandle_FrameEventDelegate eventFrameStart
Definition: MyGUI_Gui.h:150
Type * castType(bool _throw=true)
Definition: MyGUI_IObject.h:18
virtual void _setUVSet(const FloatRect &_rect)
void setItemFrame(size_t _index, size_t _indexFrame, const IntCoord &_item)
IntSize getImageSize() const
void setItemFrameRate(size_t _index, float _rate)
void setImageInfo(const std::string &_texture, const IntCoord &_coord, const IntSize &_tile)
void insertItemFrame(size_t _index, size_t _indexFrame, const IntCoord &_item)
void shutdownOverride() override
void deleteAllItemFrames(size_t _index)
void setPropertyOverride(const std::string &_key, const std::string &_value) override
void resetItemSelect()
Reset item selection.
void setItemName(const std::string &_value)
void setItemSelect(size_t _index)
Select specified _index.
void setImageTile(const IntSize &_value)
bool setItemResource(const std::string &_name)
void setImageTexture(const std::string &_value)
void setImageIndex(size_t _index)
void setItemResourcePtr(ResourceImageSetPtr _resource)
void setItemResourceInfo(const ImageIndexInfo &_info)
ResourceImageSetPtr getItemResource() const
void setImageCoord(const IntCoord &_value)
void insertItem(size_t _index, const IntCoord &_item)
Insert an item into a list at a specified position.
void insertItemFrameDuplicate(size_t _index, size_t _indexFrame, size_t _indexSourceFrame)
void deleteItemFrame(size_t _index, size_t _indexFrame)
size_t getItemCount() const
Get number of items.
float getItemFrameRate(size_t _index) const
void addItemFrameDuplicate(size_t _index, size_t _indexSourceFrame)
void deleteAllItems()
Delete all items.
void addItemFrame(size_t _index, const IntCoord &_item)
void setItemGroup(const std::string &_value)
size_t getItemSelect() const
Get index of selected item (ITEM_NONE if none selected)
void setImageRect(const IntRect &_value)
void deleteItem(size_t _index)
Delete item at a specified position.
void addItem(const IntCoord &_item)
Add an item to the end of a list.
void setItem(size_t _index, const IntCoord &_item)
Replace an item at a specified position.
size_t getImageIndex() const
ImageIndexInfo getIndexInfo(const std::string &_group, const std::string &_index) const
EnumeratorGroupImage getEnumerator() const
IResource * getByName(const std::string &_name, bool _throw=true) const
static ResourceManager & getInstance()
ISubWidgetRect * getSubWidgetMain() const
const std::string & _getTextureName() const
void _setTextureName(const std::string &_texture)
EventHandle_WidgetStringString eventChangeProperty
Definition: MyGUI_Widget.h:267
const IntSize & getTextureSize(const std::string &_texture, bool _cache=true)
const size_t IMAGE_MAX_INDEX
types::TCoord< int > IntCoord
Definition: MyGUI_Types.h:35
const size_t ITEM_NONE
Definition: MyGUI_Macros.h:17
delegates::DelegateFunction< Args... > * newDelegate(void(*_func)(Args... args))
types::TRect< float > FloatRect
Definition: MyGUI_Types.h:33
const std::string & texture
const IntSize & size
const std::vector< IntPoint > & frames
std::string print() const
Definition: MyGUI_TRect.h:156
void set(T const &_left, T const &_top, T const &_right, T const &_bottom)
Definition: MyGUI_TRect.h:121
bool empty() const
Definition: MyGUI_TRect.h:136
bool empty() const
Definition: MyGUI_TSize.h:108
std::string print() const
Definition: MyGUI_TSize.h:113
void set(T const &_width, T const &_height)
Definition: MyGUI_TSize.h:95