MyGUI 3.4.3
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 {
23 frameAdvise(false);
24
26 }
27
28 void ImageBox::setImageInfo(std::string_view _texture, const IntCoord& _coord, const IntSize& _tile)
29 {
30 mCurrentTextureName = _texture;
31 mSizeTexture = texture_utility::getTextureSize(mCurrentTextureName);
32
33 mSizeTile = _tile;
34 mRectImage.left = _coord.left;
35 mRectImage.top = _coord.top;
36 mRectImage.right = _coord.left + _coord.width;
37 mRectImage.bottom = _coord.top + _coord.height;
38
39 recalcIndexes();
40 updateSelectIndex(mIndexSelect);
41 }
42
44 {
45 mSizeTile = _tile;
46
47 // если размер еще не установлен, то ставим тот что у тайла
48 if (mRectImage.empty())
49 mRectImage.set(0, 0, _tile.width, _tile.height);
50 //если индекса еще нет, то ставим 0
51 if (mIndexSelect == ITEM_NONE)
52 mIndexSelect = 0;
53
54 recalcIndexes();
55 updateSelectIndex(mIndexSelect);
56 }
57
59 {
60 mRectImage.left = _coord.left;
61 mRectImage.top = _coord.top;
62 mRectImage.right = _coord.left + _coord.width;
63 mRectImage.bottom = _coord.top + _coord.height;
64
65 setImageRect(mRectImage);
66 }
67
69 {
70 mRectImage = _rect;
71
72 // если тайл еще не установлен, то ставим тот что у координат
73 if (mSizeTile.empty())
74 mSizeTile.set(_rect.width(), _rect.height());
75 //если индекса еще нет, то ставим 0
76 if (mIndexSelect == ITEM_NONE)
77 mIndexSelect = 0;
78
79 recalcIndexes();
80 updateSelectIndex(mIndexSelect);
81 }
82
83 void ImageBox::setImageTexture(std::string_view _texture)
84 {
85 mCurrentTextureName = _texture;
86 mSizeTexture = texture_utility::getTextureSize(mCurrentTextureName);
87
88 // если первый раз, то ставим во всю текстуру
89 if (mItems.empty())
90 {
91 _setUVSet(FloatRect(0, 0, 1, 1));
92 _setTextureName(mCurrentTextureName);
93 }
94 else
95 {
96 recalcIndexes();
97 updateSelectIndex(mIndexSelect);
98 }
99 }
100
101 void ImageBox::recalcIndexes()
102 {
103 mItems.clear();
104
105 if ((mRectImage.right <= mRectImage.left) || (mRectImage.bottom <= mRectImage.top))
106 return;
107 if ((mSizeTile.width <= 0) || (mSizeTile.height <= 0))
108 return;
109
110 size_t count_h = (size_t)(mRectImage.width() / mSizeTile.width);
111 size_t count_v = (size_t)(mRectImage.height() / mSizeTile.height);
112
113 if ((count_h * count_v) > IMAGE_MAX_INDEX)
114 {
115 MYGUI_LOG(
116 Warning,
117 "Tile count very mach, rect : "
118 << mRectImage.print() << " tile : " << mSizeTile.print() << " texture : " << _getTextureName()
119 << " indexes : " << (count_h * count_v) << " max : " << IMAGE_MAX_INDEX);
120 return;
121 }
122
123 int pos_h = mRectImage.left;
124 int pos_v = mRectImage.top;
125
126 for (size_t v = 0; v < count_v; ++v)
127 {
128 for (size_t h = 0; h < count_h; ++h)
129 {
130 addItem(IntCoord(pos_h, pos_v, mSizeTile.width, mSizeTile.height));
131 pos_h += mSizeTile.width;
132 }
133 pos_v += mSizeTile.height;
134 pos_h = mRectImage.left;
135 }
136 }
137
138 void ImageBox::updateSelectIndex(size_t _index)
139 {
140 mIndexSelect = _index;
141
142 if ((_index == ITEM_NONE) || (_index >= mItems.size()))
143 {
144 _setTextureName(std::string_view{});
145 return;
146 }
147
148 _setTextureName(mCurrentTextureName);
149
150
151 VectorImages::iterator iter = mItems.begin() + _index;
152
153 if (iter->images.size() < 2)
154 {
155 frameAdvise(false);
156 }
157 else
158 {
159 if (!mFrameAdvise)
160 {
161 mCurrentTime = 0;
162 mCurrentFrame = 0;
163 }
164 frameAdvise(true);
165 }
166
167 if (!iter->images.empty())
168 {
169 _setUVSet(iter->images.front());
170 }
171 }
172
173 void ImageBox::deleteItem(size_t _index)
174 {
175 MYGUI_ASSERT_RANGE(_index, mItems.size(), "ImageBox::deleteItem");
176
177 mItems.erase(mItems.begin() + _index);
178
179 if (mIndexSelect != ITEM_NONE)
180 {
181 if (mItems.empty())
182 updateSelectIndex(ITEM_NONE);
183 else if ((_index < mIndexSelect) || (mIndexSelect == mItems.size()))
184 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)
198 _index = mItems.size();
199
200 VectorImages::iterator iter = mItems.insert(mItems.begin() + _index, ImageItem());
201
202 iter->images.push_back(CoordConverter::convertTextureCoord(_item, mSizeTexture));
203
204 if ((mIndexSelect != ITEM_NONE) && (_index <= mIndexSelect))
205 updateSelectIndex(mIndexSelect++);
206 }
207
208 void ImageBox::setItem(size_t _index, const IntCoord& _item)
209 {
210 MYGUI_ASSERT_RANGE(_index, mItems.size(), "ImageBox::setItem");
211
212 VectorImages::iterator iter = mItems.begin() + _index;
213 iter->images.clear();
214 iter->images.push_back(CoordConverter::convertTextureCoord(_item, mSizeTexture));
215
216 if (_index == mIndexSelect)
217 updateSelectIndex(mIndexSelect);
218 }
219
220 void ImageBox::frameEntered(float _frame)
221 {
222 if (mIndexSelect == ITEM_NONE)
223 return;
224
225 if (mItems.empty())
226 return;
227 VectorImages::iterator iter = mItems.begin() + mIndexSelect;
228 if ((iter->images.size() < 2) || (iter->frame_rate == 0))
229 return;
230
231 mCurrentTime += _frame;
232
233 while (mCurrentTime >= iter->frame_rate)
234 {
235 mCurrentTime -= iter->frame_rate;
236 mCurrentFrame++;
237 if (mCurrentFrame >= (iter->images.size()))
238 mCurrentFrame = 0;
239 }
240
241 _setUVSet(iter->images[mCurrentFrame]);
242 }
243
245 {
246 MYGUI_ASSERT_RANGE(_index, mItems.size(), "ImageBox::clearItemFrame");
247 VectorImages::iterator iter = mItems.begin() + _index;
248 iter->images.clear();
249 }
250
251 void ImageBox::addItemFrame(size_t _index, const IntCoord& _item)
252 {
253 MYGUI_ASSERT_RANGE(_index, mItems.size(), "ImageBox::addItemFrame");
254 VectorImages::iterator iter = mItems.begin() + _index;
255 iter->images.push_back(CoordConverter::convertTextureCoord(_item, mSizeTexture));
256 }
257
258 void ImageBox::setItemFrameRate(size_t _index, float _rate)
259 {
260 MYGUI_ASSERT_RANGE(_index, mItems.size(), "ImageBox::setItemFrameRate");
261 VectorImages::iterator iter = mItems.begin() + _index;
262 iter->frame_rate = _rate;
263 }
264
265 float ImageBox::getItemFrameRate(size_t _index) const
266 {
267 MYGUI_ASSERT_RANGE(_index, mItems.size(), "ImageBox::getItemFrameRate");
268 VectorImages::const_iterator iter = mItems.begin() + _index;
269 return iter->frame_rate;
270 }
271
272 void ImageBox::addItemFrameDuplicate(size_t _index, size_t _indexSourceFrame)
273 {
274 MYGUI_ASSERT_RANGE(_index, mItems.size(), "ImageBox::addItemFrameDuplicate");
275
276 VectorImages::iterator iter = mItems.begin() + _index;
277 MYGUI_ASSERT_RANGE(_indexSourceFrame, iter->images.size(), "ImageBox::addItemFrameDuplicate");
278 iter->images.push_back(iter->images[_indexSourceFrame]);
279 }
280
281 void ImageBox::insertItemFrame(size_t _index, size_t _indexFrame, const IntCoord& _item)
282 {
283 MYGUI_ASSERT_RANGE(_index, mItems.size(), "ImageBox::insertItemFrame");
284
285 VectorImages::iterator iter = mItems.begin() + _index;
286 MYGUI_ASSERT_RANGE_INSERT(_indexFrame, iter->images.size(), "ImageBox::insertItemFrame");
287 if (_indexFrame == ITEM_NONE)
288 _indexFrame = iter->images.size() - 1;
289
290 iter->images.insert(
291 iter->images.begin() + _indexFrame,
292 CoordConverter::convertTextureCoord(_item, mSizeTexture));
293 }
294
295 void ImageBox::insertItemFrameDuplicate(size_t _index, size_t _indexFrame, size_t _indexSourceFrame)
296 {
297 MYGUI_ASSERT_RANGE(_index, mItems.size(), "ImageBox::insertItemFrameDuplicate");
298
299 VectorImages::iterator iter = mItems.begin() + _index;
300 MYGUI_ASSERT_RANGE_INSERT(_indexFrame, iter->images.size(), "ImageBox::insertItemFrameDuplicate");
301 if (_indexFrame == ITEM_NONE)
302 _indexFrame = iter->images.size() - 1;
303
304 MYGUI_ASSERT_RANGE(_indexSourceFrame, iter->images.size(), "ImageBox::insertItemFrameDuplicate");
305
306 iter->images.insert(iter->images.begin() + _indexFrame, iter->images[_indexSourceFrame]);
307 }
308
309 void ImageBox::setItemFrame(size_t _index, size_t _indexFrame, const IntCoord& _item)
310 {
311 MYGUI_ASSERT_RANGE(_index, mItems.size(), "ImageBox::setItemFrame");
312
313 VectorImages::iterator iter = mItems.begin() + _index;
314 MYGUI_ASSERT_RANGE(_indexFrame, iter->images.size(), "ImageBox::setItemFrame");
315
316 iter->images[_indexFrame] = CoordConverter::convertTextureCoord(_item, mSizeTexture);
317 }
318
319 void ImageBox::deleteItemFrame(size_t _index, size_t _indexFrame)
320 {
321 MYGUI_ASSERT_RANGE(_index, mItems.size(), "ImageBox::deleteItemFrame");
322
323 VectorImages::iterator iter = mItems.begin() + _index;
324 MYGUI_ASSERT_RANGE_INSERT(_indexFrame, iter->images.size(), "ImageBox::deleteItemFrame");
325 if (_indexFrame == ITEM_NONE)
326 _indexFrame = iter->images.size() - 1;
327
328 iter->images.erase(iter->images.begin() + _indexFrame);
329 }
330
332 {
333 mCurrentTextureName = _info.texture;
334 mSizeTexture = texture_utility::getTextureSize(mCurrentTextureName);
335
336 mItems.clear();
337
338 if (!_info.frames.empty())
339 {
340 std::vector<IntPoint>::const_iterator iter = _info.frames.begin();
341
342 addItem(IntCoord(*iter, _info.size));
343 setItemFrameRate(0, _info.rate);
344
345 for (++iter; iter != _info.frames.end(); ++iter)
346 {
347 addItemFrame(0, MyGUI::IntCoord(*iter, _info.size));
348 }
349 }
350
351 mIndexSelect = 0;
352 updateSelectIndex(mIndexSelect);
353 }
354
355 bool ImageBox::setItemResource(std::string_view _name)
356 {
357 IResourcePtr resource = ResourceManager::getInstance().getByName(_name, false);
358 setItemResourcePtr(resource ? resource->castType<ResourceImageSet>() : nullptr);
359 return resource != nullptr;
360 }
361
363 {
364 if (mResource == _resource)
365 return;
366
367 // если первый раз то устанавливаем дефолтное
368 if (mResource == nullptr)
369 {
370 if (mItemGroup.empty())
371 {
372 EnumeratorGroupImage iter_group = _resource->getEnumerator();
373 while (iter_group.next())
374 {
375 mItemGroup = iter_group.current().name;
376 if (mItemName.empty() && !iter_group.current().indexes.empty())
377 {
378 mItemName = iter_group.current().indexes[0].name;
379 }
380 break;
381 }
382 }
383 else if (mItemName.empty())
384 {
385 EnumeratorGroupImage iter_group = _resource->getEnumerator();
386 while (iter_group.next())
387 {
388 if (mItemGroup == iter_group.current().name)
389 {
390 if (!iter_group.current().indexes.empty())
391 {
392 mItemName = iter_group.current().indexes[0].name;
393 break;
394 }
395 }
396 }
397 }
398 }
399
400 mResource = _resource;
401 if (!mResource || mItemGroup.empty() || mItemName.empty())
402 updateSelectIndex(ITEM_NONE);
403 else
404 setItemResourceInfo(mResource->getIndexInfo(mItemGroup, mItemName));
405 }
406
407 void ImageBox::setItemGroup(std::string_view _group)
408 {
409 if (mItemGroup == _group)
410 return;
411
412 mItemGroup = _group;
413 if (!mResource || mItemGroup.empty() || mItemName.empty())
414 updateSelectIndex(ITEM_NONE);
415 else
416 setItemResourceInfo(mResource->getIndexInfo(mItemGroup, mItemName));
417 }
418
419 void ImageBox::setItemName(std::string_view _name)
420 {
421 if (mItemName == _name)
422 return;
423
424 mItemName = _name;
425 if (!mResource || mItemGroup.empty() || mItemName.empty())
426 updateSelectIndex(ITEM_NONE);
427 else
428 setItemResourceInfo(mResource->getIndexInfo(mItemGroup, mItemName));
429 }
430
431 void ImageBox::setItemResourceInfo(ResourceImageSetPtr _resource, std::string_view _group, std::string_view _name)
432 {
433 mResource = _resource;
434 mItemGroup = _group;
435 mItemName = _name;
436 if (!mResource || mItemGroup.empty() || mItemName.empty())
437 updateSelectIndex(ITEM_NONE);
438 else
439 setItemResourceInfo(mResource->getIndexInfo(mItemGroup, mItemName));
440 }
441
442 void ImageBox::frameAdvise(bool _advise)
443 {
444 if (_advise)
445 {
446 if (!mFrameAdvise)
447 {
448 MyGUI::Gui::getInstance().eventFrameStart += MyGUI::newDelegate(this, &ImageBox::frameEntered);
449 mFrameAdvise = true;
450 }
451 }
452 else
453 {
454 if (mFrameAdvise)
455 {
456 MyGUI::Gui::getInstance().eventFrameStart -= MyGUI::newDelegate(this, &ImageBox::frameEntered);
457 mFrameAdvise = false;
458 }
459 }
460 }
461
462 void ImageBox::setImageIndex(size_t _index)
463 {
464 setItemSelect(_index);
465 }
466
468 {
469 return getItemSelect();
470 }
471
473 {
474 return mSizeTexture;
475 }
476
477 void ImageBox::setItemSelect(size_t _index)
478 {
479 if (mIndexSelect != _index)
480 updateSelectIndex(_index);
481 }
482
483 void ImageBox::_setUVSet(const FloatRect& _rect)
484 {
485 if (nullptr != getSubWidgetMain())
486 getSubWidgetMain()->_setUVSet(_rect);
487 }
488
489 void ImageBox::setPropertyOverride(std::string_view _key, std::string_view _value)
490 {
492 if (_key == "ImageTexture")
493 setImageTexture(_value);
494
496 else if (_key == "ImageCoord")
498
500 else if (_key == "ImageTile")
502
504 else if (_key == "ImageIndex")
506
508 else if (_key == "ImageResource")
509 setItemResource(_value);
510
512 else if (_key == "ImageGroup")
513 setItemGroup(_value);
514
516 else if (_key == "ImageName")
517 setItemName(_value);
518
519 else
520 {
521 Base::setPropertyOverride(_key, _value);
522 return;
523 }
524
525 eventChangeProperty(this, _key, _value);
526 }
527
529 {
530 return mItems.size();
531 }
532
534 {
535 return mIndexSelect;
536 }
537
542
543 void ImageBox::addItem(const IntCoord& _item)
544 {
545 insertItem(ITEM_NONE, _item);
546 }
547
549 {
550 return mResource;
551 }
552
553} // 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()
Definition MyGUI_Gui.cpp:34
EventHandle_FrameEventDelegate eventFrameStart
Definition MyGUI_Gui.h:215
Type * castType(bool _throw=true)
virtual void _setUVSet(const FloatRect &)
void setItemGroup(std::string_view _group)
void setItemFrame(size_t _index, size_t _indexFrame, const IntCoord &_item)
IntSize getImageSize() const
void setItemFrameRate(size_t _index, float _rate)
void setImageTexture(std::string_view _texture)
void insertItemFrame(size_t _index, size_t _indexFrame, const IntCoord &_item)
void shutdownOverride() override
void deleteAllItemFrames(size_t _index)
bool setItemResource(std::string_view _name)
void resetItemSelect()
Reset item selection.
void setPropertyOverride(std::string_view _key, std::string_view _value) override
void setItemSelect(size_t _index)
Select specified _index.
void setItemName(std::string_view _name)
void setImageIndex(size_t _index)
void setItemResourcePtr(ResourceImageSetPtr _resource)
void setImageInfo(std::string_view _texture, const IntCoord &_coord, const IntSize &_tile)
void setItemResourceInfo(const ImageIndexInfo &_info)
ResourceImageSetPtr getItemResource() const
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 setImageCoord(const IntCoord &_coord)
void addItemFrame(size_t _index, const IntCoord &_item)
void setImageRect(const IntRect &_rect)
void setImageTile(const IntSize &_tile)
size_t getItemSelect() const
Get index of selected item (ITEM_NONE if none selected)
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
EnumeratorGroupImage getEnumerator() const
IResource * getByName(std::string_view _name, bool _throw=true) const
static ResourceManager & getInstance()
ISubWidgetRect * getSubWidgetMain() const
void _setTextureName(std::string_view _texture)
const std::string & _getTextureName() const
EventHandle_WidgetStringString eventChangeProperty
const IntSize & getTextureSize(const std::string &_texture, bool _cache=true)
T parseValue(std::string_view _value)
types::TRect< int > IntRect
Definition MyGUI_Types.h:33
ResourceImageSet * ResourceImageSetPtr
IResource * IResourcePtr
types::TRect< float > FloatRect
Definition MyGUI_Types.h:34
constexpr size_t ITEM_NONE
const size_t IMAGE_MAX_INDEX
types::TCoord< int > IntCoord
Definition MyGUI_Types.h:36
types::TSize< int > IntSize
Definition MyGUI_Types.h:30
delegates::DelegateFunction< Args... > * newDelegate(void(*_func)(Args... args))
Enumerator< VectorGroupImage > EnumeratorGroupImage
std::string_view texture
const std::vector< IntPoint > & frames
std::string print() const
void set(T const &_left, T const &_top, T const &_right, T const &_bottom)
Definition MyGUI_TRect.h:98
std::string print() const
Definition MyGUI_TSize.h:95
void set(T const &_width, T const &_height)
Definition MyGUI_TSize.h:77