MyGUI  3.4.1
MyGUI_ItemBox.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_ItemBox.h"
9 #include "MyGUI_Button.h"
10 #include "MyGUI_ScrollBar.h"
11 #include "MyGUI_ResourceSkin.h"
12 #include "MyGUI_InputManager.h"
13 #include "MyGUI_Gui.h"
14 #include "MyGUI_WidgetManager.h"
15 
16 namespace MyGUI
17 {
18 
20  mCountItemInLine(0),
21  mCountLines(0),
22  mFirstVisibleIndex(0),
23  mFirstOffsetIndex(0),
24  mIndexSelect(ITEM_NONE),
25  mIndexActive(ITEM_NONE),
26  mIndexAccept(ITEM_NONE),
27  mIndexRefuse(ITEM_NONE),
28  mIsFocus(false),
29  mItemDrag(nullptr),
30  mAlignVert(true)
31  {
33  }
34 
36  {
38 
39  // FIXME нам нужен фокус клавы
40  setNeedKeyFocus(true);
41 
42  mDragLayer = "DragAndDrop";
43 
44  if (isUserString("DragLayer"))
45  mDragLayer = getUserString("DragLayer");
46 
48  if (getClientWidget() != nullptr)
49  {
53  }
54 
56  assignWidget(mVScroll, "VScroll");
57  if (mVScroll != nullptr)
58  {
60  }
61 
63  assignWidget(mHScroll, "HScroll");
64  if (mHScroll != nullptr)
65  {
67  }
68 
69  // подписываем клиент для драгэндропа
70  if (getClientWidget() != nullptr)
72 
73  requestItemSize();
74 
77  }
78 
80  {
81  mVScroll = nullptr;
82  mHScroll = nullptr;
83 
85  }
86 
87  void ItemBox::setPosition(const IntPoint& _point)
88  {
89  Base::setPosition(_point);
90  }
91 
92  void ItemBox::setSize(const IntSize& _size)
93  {
94  Base::setSize(_size);
96  }
97 
98  void ItemBox::setCoord(const IntCoord& _coord)
99  {
100  Base::setCoord(_coord);
102  }
103 
104  void ItemBox::requestItemSize()
105  {
106  IntCoord coord(0, 0, 1, 1);
107 
108  // спрашиваем размер иконок
109  requestCoordItem(this, coord, false);
110 
111  mSizeItem = coord.size();
112  MYGUI_ASSERT((mSizeItem.width > 0 && mSizeItem.height > 0), "(mSizeItem.width > 0 && mSizeItem.height > 0) at requestCoordWidgetItem");
113  }
114 
116  {
117  requestItemSize();
118 
121 
122  _updateAllVisible(true);
123  _resetContainer(true);
124  }
125 
126  void ItemBox::_updateAllVisible(bool _redraw)
127  {
128  int count_visible = 0;
129  if (mAlignVert)
130  {
131  count_visible = (_getClientWidget()->getHeight() / mSizeItem.height) + 2;
132  }
133  else
134  {
135  count_visible = (_getClientWidget()->getWidth() / mSizeItem.width) + 2;
136  }
137 
138  size_t start = (mFirstVisibleIndex * mCountItemInLine);
139  size_t count = (count_visible * mCountItemInLine) + start;
140 
141  size_t index = 0;
142  for (size_t pos = start; pos < count; ++pos, ++index)
143  {
144  // дальше нет айтемов
145  if (pos >= mItemsInfo.size()) break;
146 
147  Widget* item = getItemWidget(index);
148  if (mAlignVert)
149  {
150  item->setPosition(((int)index % mCountItemInLine) * mSizeItem.width - mContentPosition.left,
151  (((int)index / mCountItemInLine) * mSizeItem.height) - mFirstOffsetIndex);
152  }
153  else
154  {
155  item->setPosition((((int)index / mCountItemInLine) * mSizeItem.width) - mFirstOffsetIndex,
156  ((int)index % mCountItemInLine) * mSizeItem.height - mContentPosition.top);
157  }
158 
159  item->setSize(mSizeItem);
160  item->setVisible(true);
161 
162  if (_redraw)
163  {
164  IBDrawItemInfo data(pos, mIndexSelect, mIndexActive, mIndexAccept, mIndexRefuse, true, false);
165  requestDrawItem(this, item, data);
166  }
167 
168  }
169 
170  // все виджеты еще есть, то их надо бы скрыть
171  while (index < mVectorItems.size())
172  {
173  mVectorItems[index]->setVisible(false);
174  index ++;
175  }
176  }
177 
179  {
180  // еще нет такого виджета, нуно создать
181  if (_index == mVectorItems.size())
182  {
183  requestItemSize();
184 
185  Widget* item = _getClientWidget()->createWidget<Widget>("Default", IntCoord(0, 0, mSizeItem.width, mSizeItem.height), Align::Default);
186 
187  // вызываем запрос на создание виджета
188  requestCreateWidgetItem(this, item);
189 
196  item->_setContainer(this);
199 
200  item->_setInternalData((size_t)mVectorItems.size());
201 
202  mVectorItems.push_back(item);
203  }
204 
205  // запрашивать только последовательно
206  MYGUI_ASSERT_RANGE(_index, mVectorItems.size(), "ItemBox::getItemWidget");
207 
208  return mVectorItems[_index];
209  }
210 
211  void ItemBox::onMouseWheel(int _rel)
212  {
213  notifyMouseWheel(nullptr, _rel);
214 
215  Base::onMouseWheel(_rel);
216  }
217 
219  {
220  mIsFocus = true;
221 
222  Base::onKeySetFocus(_old);
223  }
224 
226  {
227  mIsFocus = false;
228 
229  Base::onKeyLostFocus(_new);
230  }
231 
233  {
234  // сбрасываем старую подсветку
235  if (mIndexActive != ITEM_NONE)
236  {
237  size_t start = (size_t)(mFirstVisibleIndex * mCountItemInLine);
238  size_t index = mIndexActive;
239  mIndexActive = ITEM_NONE;
240 
241  // если видим, то обновляем
242  if ((mIndexActive >= start) && (mIndexActive < (start + mVectorItems.size())))
243  {
244  IBDrawItemInfo data(index, mIndexSelect, mIndexActive, mIndexAccept, mIndexRefuse, false, false);
245 
246  requestDrawItem(this, mVectorItems[mIndexActive - start], data);
247  }
248  }
249  }
250 
252  {
253  MYGUI_DEBUG_ASSERT(mIndexActive == ITEM_NONE, "use : resetCurrentActiveItem() before findCurrentActiveItem()");
254 
256 
257  // сначала проверяем клиентскую зону
258  const IntRect& rect = _getClientWidget()->getAbsoluteRect();
259  if ((point.left < rect.left) || (point.left > rect.right) || (point.top < rect.top) || (point.top > rect.bottom))
260  {
261  return;
262  }
263 
264  for (size_t pos = 0; pos < mVectorItems.size(); ++pos)
265  {
266  Widget* item = mVectorItems[pos];
267  const IntRect& abs_rect = item->getAbsoluteRect();
268  if ((point.left >= abs_rect.left) && (point.left <= abs_rect.right) && (point.top >= abs_rect.top) && (point.top <= abs_rect.bottom))
269  {
270 
271  size_t index = calcIndexByWidget(item);
272  // при переборе индекс может быть больше, так как может создасться сколько угодно
273  if (index < mItemsInfo.size())
274  {
275 
276  mIndexActive = index;
277  IBDrawItemInfo data(index, mIndexSelect, mIndexActive, mIndexAccept, mIndexRefuse, false, false);
278 
279  requestDrawItem(this, item, data);
280  }
281 
282  break;
283  }
284  }
285  }
286 
287  size_t ItemBox::_getItemIndex(Widget* _item) const
288  {
289  if (_item == _getClientWidget())
290  return ITEM_NONE;
291  size_t index = calcIndexByWidget(_item);
292  if (index < mItemsInfo.size())
293  return index;
294  return ITEM_NONE;
295  }
296 
297  void ItemBox::_setContainerItemInfo(size_t _index, bool _set, bool _accept)
298  {
299  if (_index == ITEM_NONE) return;
300  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "ItemBox::_setContainerItemInfo");
301 
302  mIndexAccept = (_set && _accept ) ? _index : ITEM_NONE;
303  mIndexRefuse = (_set && !_accept) ? _index : ITEM_NONE;
304 
305  size_t start = (size_t)(mFirstVisibleIndex * mCountItemInLine);
306  if ((_index >= start) && (_index < (start + mVectorItems.size())))
307  {
308  IBDrawItemInfo data(_index, mIndexSelect, mIndexActive, mIndexAccept, mIndexRefuse, false, false);
309  requestDrawItem(this, mVectorItems[_index - start], data);
310  }
311  }
312 
313  void ItemBox::setItemDataAt(size_t _index, Any _data)
314  {
315  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "ItemBox::setItemData");
316  mItemsInfo[_index].data = _data;
317 
318  size_t start = (size_t)(mFirstVisibleIndex * mCountItemInLine);
319  if ((_index >= start) && (_index < (start + mVectorItems.size())))
320  {
321  IBDrawItemInfo data(_index, mIndexSelect, mIndexActive, mIndexAccept, mIndexRefuse, true, false);
322  requestDrawItem(this, mVectorItems[_index - start], data);
323  }
324 
325  _resetContainer(true);
326  }
327 
328  void ItemBox::insertItemAt(size_t _index, Any _data, bool update)
329  {
330  MYGUI_ASSERT_RANGE_INSERT(_index, mItemsInfo.size(), "ItemBox::insertItemAt");
331  if (_index == ITEM_NONE) _index = mItemsInfo.size();
332 
333  _resetContainer(false);
335 
336  mItemsInfo.insert(mItemsInfo.begin() + _index, ItemDataInfo(_data));
337 
338  // расчитываем новый индекс выделения
339  if (mIndexSelect != ITEM_NONE)
340  {
341  if (mIndexSelect >= _index)
342  {
343  mIndexSelect ++;
344  }
345  }
346 
347  if (update)
348  {
351 
353 
354  _updateAllVisible(true);
355  }
356  }
357 
358  void ItemBox::removeItemAt(size_t _index, bool update)
359  {
360  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "ItemBox::removeItemAt");
361 
362  _resetContainer(false);
364 
365  mItemsInfo.erase(mItemsInfo.begin() + _index);
366 
367  // расчитываем новый индекс выделения
368  if (mIndexSelect != ITEM_NONE)
369  {
370  if (mItemsInfo.empty())
371  {
372  mIndexSelect = ITEM_NONE;
373  }
374  else if ((mIndexSelect > _index) || (mIndexSelect == mItemsInfo.size()))
375  {
376  mIndexSelect --;
377  }
378  }
379 
380  if (update)
381  {
384 
386 
387  _updateAllVisible(true);
388  }
389  }
390 
392  {
393  if (mItemsInfo.empty())
394  return;
395  _resetContainer(false);
396 
397  mItemsInfo.clear();
398 
399  mIndexSelect = ITEM_NONE;
400  mIndexActive = ITEM_NONE;
401 
404 
405  _updateAllVisible(true);
406  }
407 
408  void ItemBox::redrawItemAt(size_t _index)
409  {
410  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "ItemBox::redrawItemAt");
411 
412  size_t start = (size_t)(mFirstVisibleIndex * mCountItemInLine);
413  if ((_index >= start) && (_index < (start + mVectorItems.size())))
414  {
415  IBDrawItemInfo data(_index, mIndexSelect, mIndexActive, mIndexAccept, mIndexRefuse, true, false);
416  requestDrawItem(this, mVectorItems[_index - start], data);
417  }
418  }
419 
420  void ItemBox::setIndexSelected(size_t _index)
421  {
422  MYGUI_ASSERT_RANGE_AND_NONE(_index, mItemsInfo.size(), "ItemBox::setIndexSelected");
423  if (_index == mIndexSelect) return;
424 
425  size_t start = (size_t)(mFirstVisibleIndex * mCountItemInLine);
426 
427  // сбрасываем старое выделение
428  if (mIndexSelect != ITEM_NONE)
429  {
430  size_t index = mIndexSelect;
431  mIndexSelect = ITEM_NONE;
432 
433  if ((index >= start) && (index < (start + mVectorItems.size())))
434  {
435  IBDrawItemInfo data(index, mIndexSelect, mIndexActive, mIndexAccept, mIndexRefuse, false, false);
436  requestDrawItem(this, mVectorItems[index - start], data);
437  }
438  }
439 
440  mIndexSelect = _index;
441  if (mIndexSelect != ITEM_NONE)
442  {
443  if ((_index >= start) && (_index < (start + mVectorItems.size())))
444  {
445  IBDrawItemInfo data(_index, mIndexSelect, mIndexActive, mIndexAccept, mIndexRefuse, false, false);
446  requestDrawItem(this, mVectorItems[_index - start], data);
447  }
448  }
449 
450  }
451 
453  {
454  size_t index = getIndexByWidget(_sender);
455 
456  eventSelectItemAccept(this, index);
457  }
458 
460  {
461  if (mAlignVert == _vert)
462  return;
463  mAlignVert = _vert;
464 
465  mCountItemInLine = -1;
467  }
468 
470  {
472  }
473 
475  {
477  }
478 
479  size_t ItemBox::getIndexByWidget(Widget* _widget) const
480  {
481  MYGUI_ASSERT(_widget, "ItemBox::getIndexByWidget : Widget == nullptr");
482  if (_widget == _getClientWidget()) return ITEM_NONE;
483  MYGUI_ASSERT(_widget->getParent() == _getClientWidget(), "ItemBox::getIndexByWidget : Widget is not child");
484 
485  size_t index = calcIndexByWidget(_widget);
486  MYGUI_ASSERT_RANGE(index, mItemsInfo.size(), "ItemBox::getIndexByWidget");
487 
488  return index;
489  }
490 
491  size_t ItemBox::_getContainerIndex(const IntPoint& _point) const
492  {
493  for (const auto& item : mVectorItems)
494  {
495  if (item->getVisible())
496  {
497  if (item->getAbsoluteRect().inside(_point))
498  {
499  return getIndexByWidget(item);
500  }
501  }
502  }
503  return ITEM_NONE;
504  }
505 
506  void ItemBox::_resetContainer(bool _update)
507  {
508  // обязательно у базового
509  Base::_resetContainer(_update);
510 
511  if ( ! _update)
512  {
514  for (VectorWidgetPtr::iterator iter = mVectorItems.begin(); iter != mVectorItems.end(); ++iter)
515  {
516  instance.unlinkFromUnlinkers(*iter);
517  }
518  }
519  }
520 
522  {
523  for (VectorWidgetPtr::iterator iter = mVectorItems.begin(); iter != mVectorItems.end(); ++iter)
524  {
525  if ((*iter)->getVisible())
526  {
527  size_t index = getIndexByWidget(*iter);
528 
529  if (index == _index) return (*iter);
530  }
531  }
532  return nullptr;
533  }
534 
535  void ItemBox::onMouseButtonPressed(int _left, int _top, MouseButton _id)
536  {
537  Base::onMouseButtonPressed(_left, _top, _id);
538  }
539 
540  void ItemBox::onMouseButtonReleased(int _left, int _top, MouseButton _id)
541  {
542  Base::onMouseButtonReleased(_left, _top, _id);
543  }
544 
545  void ItemBox::onMouseDrag(int _left, int _top, MouseButton _id)
546  {
547  Base::onMouseDrag(_left, _top, _id);
548  }
549 
551  {
552  if (mItemDrag) mItemDrag->setVisible(false);
553  }
554 
556  {
557  if (nullptr == mItemDrag)
558  {
559  // спрашиваем размер иконок
560  IntCoord coord;
561 
562  requestCoordItem(this, coord, true);
563 
564  mPointDragOffset = coord.point();
565 
566  // создаем и запрашиваем детей
567  mItemDrag = Gui::getInstance().createWidget<Widget>("Default", IntCoord(0, 0, coord.width, coord.height), Align::Default, mDragLayer);
568  requestCreateWidgetItem(this, mItemDrag);
569  }
570 
572 
573  mItemDrag->setPosition(point.left - mClickInWidget.left + mPointDragOffset.left, point.top - mClickInWidget.top + mPointDragOffset.top);
574  mItemDrag->setVisible(true);
575  }
576 
578  {
579  IBDrawItemInfo data;
580  data.drop_accept = _state.accept;
581  data.drop_refuse = _state.refuse;
582 
583  data.select = false;
584  data.active = false;
585 
586  data.index = mDropSenderIndex;
587  data.update = _state.update;
588  data.drag = true;
589 
590  requestDrawItem(this, mItemDrag, data);
591  }
592 
593  void ItemBox::notifyMouseDrag(Widget* _sender, int _left, int _top, MouseButton _id)
594  {
595  mouseDrag(_id);
596  }
597 
598  void ItemBox::notifyMouseButtonPressed(Widget* _sender, int _left, int _top, MouseButton _id)
599  {
600  mouseButtonPressed(_id);
601 
602  if ( MouseButton::Left == _id)
603  {
604  size_t old = mIndexSelect;
605 
606  if (_sender == _getClientWidget())
607  {
608  // сбрасываем выделение
610  }
611  else
612  {
613  // индекс отправителя
615 
616  // выделенный елемент
618  }
619 
620  // смещение внутри виджета, куда кликнули мышкой
622 
623  // отсылаем событие
624  eventMouseItemActivate(this, mIndexSelect);
625  // смену позиции отсылаем только при реальном изменении
626  if (old != mIndexSelect) eventChangeItemPosition(this, mIndexSelect);
627  }
628 
630  }
631 
632  void ItemBox::notifyMouseButtonReleased(Widget* _sender, int _left, int _top, MouseButton _id)
633  {
634  bool needEvent = !mStartDrop;
635  mouseButtonReleased(_id);
636 
637  if (needEvent)
639  }
640 
641  void ItemBox::notifyRootMouseChangeFocus(Widget* _sender, bool _focus)
642  {
643  size_t index = calcIndexByWidget(_sender);
644  if (_focus)
645  {
646  MYGUI_ASSERT_RANGE(index, mItemsInfo.size(), "ItemBox::notifyRootMouseChangeFocus");
647 
648  // сбрасываем старый
649  if (mIndexActive != ITEM_NONE)
650  {
651  size_t old_index = mIndexActive;
652  mIndexActive = ITEM_NONE;
653  IBDrawItemInfo data(old_index, mIndexSelect, mIndexActive, mIndexAccept, mIndexRefuse, false, false);
654  requestDrawItem(this, mVectorItems[old_index - (mFirstVisibleIndex * mCountItemInLine)], data);
655  }
656 
657  mIndexActive = index;
658  IBDrawItemInfo data(index, mIndexSelect, mIndexActive, mIndexAccept, mIndexRefuse, false, false);
659  requestDrawItem(this, mVectorItems[*_sender->_getInternalData<size_t>()], data);
660  }
661  else
662  {
663  // при сбросе виджет может быть уже скрыт, и соответсвенно отсутсвовать индекс
664  // сбрасываем индекс, только если мы и есть актив
665  if (index < mItemsInfo.size() && mIndexActive == index)
666  {
667  mIndexActive = ITEM_NONE;
668  IBDrawItemInfo data(index, mIndexSelect, mIndexActive, mIndexAccept, mIndexRefuse, false, false);
669  requestDrawItem(this, mVectorItems[*_sender->_getInternalData<size_t>()], data);
670  }
671  }
672  }
673 
675  {
676  if (mAlignVert)
677  {
678  // колличество айтемов на одной строке
679  mCountItemInLine = _getClientWidget()->getWidth() / mSizeItem.width;
680  }
681  else
682  {
683  // колличество айтемов на одной строке
684  mCountItemInLine = _getClientWidget()->getHeight() / mSizeItem.height;
685  }
686 
687  if (1 > mCountItemInLine) mCountItemInLine = 1;
688 
689  // колличество строк
690  mCountLines = mItemsInfo.size() / mCountItemInLine;
691  if (0 != (mItemsInfo.size() % mCountItemInLine)) mCountLines ++;
692 
693  if (mAlignVert)
694  {
695  mContentSize.width = (mSizeItem.width * mCountItemInLine);
696  mContentSize.height = (mSizeItem.height * mCountLines);
697  }
698  else
699  {
700  mContentSize.width = (mSizeItem.width * mCountLines);
701  mContentSize.height = (mSizeItem.height * mCountItemInLine);
702  }
703  }
704 
705  void ItemBox::notifyScrollChangePosition(ScrollBar* _sender, size_t _index)
706  {
707  if (_sender == mVScroll)
708  {
709  mContentPosition.top = (int)_index;
710  }
711  else if (_sender == mHScroll)
712  {
713  mContentPosition.left = (int)_index;
714  }
715 
716  setContentPosition(mContentPosition);
717  }
718 
719  void ItemBox::notifyMouseWheel(Widget* _sender, int _rel)
720  {
721  if (mAlignVert)
722  {
723  if (mContentSize.height <= 0)
724  return;
725 
726  int offset = mContentPosition.top;
727  if (_rel < 0)
728  offset += mSizeItem.height;
729  else
730  offset -= mSizeItem.height;
731 
732  if (mContentSize.height <= _getClientWidget()->getHeight())
733  offset = 0;
734  else if (offset >= mContentSize.height - _getClientWidget()->getHeight())
735  offset = mContentSize.height - _getClientWidget()->getHeight();
736  else if (offset < 0)
737  offset = 0;
738 
739  if (mContentPosition.top == offset)
740  return;
741 
742  // сбрасываем старую подсветку
743  // так как при прокрутке, мышь может находиться над окном
745 
746  mContentPosition.top = offset;
747  }
748  else
749  {
750  if (mContentSize.width <= 0)
751  return;
752 
753  int offset = mContentPosition.left;
754  if (_rel < 0)
755  offset += mSizeItem.width;
756  else
757  offset -= mSizeItem.width;
758 
759  if (mContentSize.width <= _getClientWidget()->getWidth())
760  offset = 0;
761  else if (offset >= mContentSize.width - _getClientWidget()->getWidth())
762  offset = mContentSize.width - _getClientWidget()->getWidth();
763  else if (offset < 0)
764  offset = 0;
765 
766  if (mContentPosition.left == offset)
767  return;
768 
769  // сбрасываем старую подсветку
770  // так как при прокрутке, мышь может находиться над окном
772 
773  mContentPosition.left = offset;
774  }
775 
776  setContentPosition(mContentPosition);
777 
778  // заново ищем и подсвечиваем айтем
779  if (!mNeedDrop)
781 
782  if (nullptr != mVScroll)
783  mVScroll->setScrollPosition(mContentPosition.top);
784  if (nullptr != mHScroll)
785  mHScroll->setScrollPosition(mContentPosition.left);
786  }
787 
788  void ItemBox::setContentPosition(const IntPoint& _point)
789  {
790  mContentPosition = _point;
791 
792  int old = mFirstVisibleIndex;
793 
794  if (mAlignVert)
795  {
796  mFirstVisibleIndex = mContentPosition.top / mSizeItem.height;
797  mFirstOffsetIndex = mContentPosition.top % mSizeItem.height;
798  }
799  else
800  {
801  mFirstVisibleIndex = mContentPosition.left / mSizeItem.width;
802  mFirstOffsetIndex = mContentPosition.left % mSizeItem.width;
803  }
804 
805  _updateAllVisible(old != mFirstVisibleIndex);
806  _resetContainer(true);
807  }
808 
810  {
811  _updateAllVisible(true);
812  }
813 
815  {
816  endDrop(true);
817  }
818 
819  size_t ItemBox::calcIndexByWidget(Widget* _widget) const
820  {
821  return *_widget->_getInternalData<size_t>() + (mFirstVisibleIndex * mCountItemInLine);
822  }
823 
824  IntSize ItemBox::getContentSize() const
825  {
826  return mContentSize;
827  }
828 
829  IntPoint ItemBox::getContentPosition() const
830  {
831  return mContentPosition;
832  }
833 
835  {
836  return _getClientWidget()->getSize();
837  }
838 
839  void ItemBox::eraseContent()
840  {
841  updateMetrics();
842  }
843 
844  size_t ItemBox::getHScrollPage() const
845  {
846  return mSizeItem.width;
847  }
848 
849  size_t ItemBox::getVScrollPage() const
850  {
851  return mSizeItem.height;
852  }
853 
854  Align ItemBox::getContentAlign() const
855  {
856  return Align::Default;
857  }
858 
859  size_t ItemBox::getItemCount() const
860  {
861  return mItemsInfo.size();
862  }
863 
864  void ItemBox::addItem(Any _data, bool update)
865  {
866  insertItemAt(ITEM_NONE, _data, update);
867  }
868 
870  {
871  return mIndexSelect;
872  }
873 
875  {
877  }
878 
879  void ItemBox::clearItemDataAt(size_t _index)
880  {
881  setItemDataAt(_index, Any::Null);
882  }
883 
885  {
886  return mAlignVert;
887  }
888 
890  {
891  return mItemDrag;
892  }
893 
894  void ItemBox::setVisibleVScroll(bool _value)
895  {
896  mVisibleVScroll = _value;
898  }
899 
900  void ItemBox::setVisibleHScroll(bool _value)
901  {
902  mVisibleHScroll = _value;
904  }
905 
907  {
908  return mVisibleVScroll;
909  }
910 
912  {
913  return mVisibleHScroll;
914  }
915 
916  void ItemBox::setPropertyOverride(const std::string& _key, const std::string& _value)
917  {
919  if (_key == "VerticalAlignment")
920  setVerticalAlignment(utility::parseValue<bool>(_value));
921 
923  else if (_key == "VisibleVScroll")
924  setVisibleVScroll(utility::parseValue<bool>(_value));
925 
927  else if (_key == "VisibleHScroll")
928  setVisibleHScroll(utility::parseValue<bool>(_value));
929 
930  else
931  {
932  Base::setPropertyOverride(_key, _value);
933  return;
934  }
935 
936  eventChangeProperty(this, _key, _value);
937  }
938 
939  void ItemBox::setViewOffset(const IntPoint& _value)
940  {
941  if (mAlignVert)
942  {
943  if (mContentSize.height <= 0)
944  return;
945 
946  int offset = _value.top;
947 
948  if (mContentSize.height <= _getClientWidget()->getHeight())
949  offset = 0;
950  else if (offset >= mContentSize.height - _getClientWidget()->getHeight())
951  offset = mContentSize.height - _getClientWidget()->getHeight();
952  else if (offset < 0)
953  offset = 0;
954 
955  if (mContentPosition.top == offset)
956  return;
957 
958  // сбрасываем старую подсветку
959  // так как при прокрутке, мышь может находиться над окном
961 
962  mContentPosition.top = offset;
963  }
964  else
965  {
966  if (mContentSize.width <= 0)
967  return;
968 
969  int offset = _value.left;
970 
971  if (mContentSize.width <= _getClientWidget()->getWidth())
972  offset = 0;
973  else if (offset >= mContentSize.width - _getClientWidget()->getWidth())
974  offset = mContentSize.width - _getClientWidget()->getWidth();
975  else if (offset < 0)
976  offset = 0;
977 
978  if (mContentPosition.left == offset)
979  return;
980 
981  // сбрасываем старую подсветку
982  // так как при прокрутке, мышь может находиться над окном
984 
985  mContentPosition.left = offset;
986  }
987 
988  setContentPosition(mContentPosition);
989 
990  // заново ищем и подсвечиваем айтем
991  if (!mNeedDrop)
993 
994  if (nullptr != mVScroll)
995  mVScroll->setScrollPosition(mContentPosition.top);
996  if (nullptr != mHScroll)
997  mHScroll->setScrollPosition(mContentPosition.left);
998  }
999 
1001  {
1002  return getContentPosition();
1003  }
1004 
1006  {
1007  Base::onKeyButtonPressed(_key, _char);
1008 
1010  }
1011 
1013  {
1015 
1017  }
1018 
1019 } // namespace MyGUI
#define MYGUI_ASSERT(exp, dest)
#define MYGUI_DEBUG_ASSERT(exp, dest)
#define MYGUI_ASSERT_RANGE_INSERT(index, size, owner)
#define MYGUI_ASSERT_RANGE(index, size, owner)
#define MYGUI_ASSERT_RANGE_AND_NONE(index, size, owner)
static AnyEmpty Null
Definition: MyGUI_Any.h:59
void onMouseDrag(int _left, int _top, MouseButton _id) override
void onMouseButtonPressed(int _left, int _top, MouseButton _id) override
void mouseButtonPressed(MouseButton _id)
void onMouseButtonReleased(int _left, int _top, MouseButton _id) override
void mouseButtonReleased(MouseButton _id)
void setPropertyOverride(const std::string &_key, const std::string &_value) override
void mouseDrag(MouseButton _id)
void endDrop(bool _reset)
T * createWidget(const std::string &_skin, const IntCoord &_coord, Align _align, const std::string &_layer, const std::string &_name="")
Definition: MyGUI_Gui.h:69
static Gui & getInstance()
const IntPoint & getAbsolutePosition() const
const IntPoint & getLastPressedPosition(MouseButton _id) const
const IntPoint & getMousePosition() const
static InputManager & getInstance()
IntPoint getMousePositionByLayer() const
void onMouseButtonPressed(int _left, int _top, MouseButton _id) override
void onKeyButtonPressed(KeyCode _key, Char _char) override
void clearItemDataAt(size_t _index)
Clear an item data at a specified position.
void setCoord(const IntCoord &_value) override
void notifyMouseDrag(Widget *_sender, int _left, int _top, MouseButton _id)
void setVisibleHScroll(bool _value)
size_t getIndexByWidget(Widget *_widget) const
void notifyMouseButtonReleased(Widget *_sender, int _left, int _top, MouseButton _id)
size_t getItemCount() const
Get number of items.
EventHandle_ItemBoxPtrWidgetPtrCIBCellDrawInfoRef requestDrawItem
IntPoint getViewOffset() const
void notifyMouseWheel(Widget *_sender, int _rel)
void shutdownOverride() override
void setVisibleVScroll(bool _value)
void removeItemAt(size_t _index, bool update=true)
Remove item at a specified position.
void notifyMouseButtonDoubleClick(Widget *_sender)
bool getVerticalAlignment() const
bool isVisibleHScroll() const
void onKeySetFocus(Widget *_old) override
void redrawItemAt(size_t _index)
Redraw at a specified position.
void setPropertyOverride(const std::string &_key, const std::string &_value) override
void onMouseWheel(int _rel) override
void onKeyButtonReleased(KeyCode _key) override
Widget * getWidgetDrag() const
void notifyScrollChangePosition(ScrollBar *_sender, size_t _index)
void setViewOffset(const IntPoint &_value)
Widget * getItemWidget(size_t _index)
void setIndexSelected(size_t _index)
Select specified _index.
void redrawAllItems()
Redraw all items.
void initialiseOverride() override
void resetCurrentActiveItem()
void onMouseDrag(int _left, int _top, MouseButton _id) override
void onKeyLostFocus(Widget *_new) override
void insertItemAt(size_t _index, Any _data=Any::Null, bool update=true)
Insert an item into a array at a specified position.
size_t _getContainerIndex(const IntPoint &_point) const override
IntSize getViewSize() const override
void setPosition(const IntPoint &_value) override
void notifyMouseButtonPressed(Widget *_sender, int _left, int _top, MouseButton _id)
EventHandle_ItemBoxPtrSizeT eventMouseItemActivate
void setSize(const IntSize &_value) override
EventHandle_ItemBoxPtrWidgetPtr requestCreateWidgetItem
EventHandle_ItemBoxPtrSizeT eventSelectItemAccept
void notifyKeyButtonReleased(Widget *_sender, KeyCode _key)
void setItemDataAt(size_t _index, Any _data)
Replace an item data at a specified position.
Widget * getWidgetByIndex(size_t _index)
void updateDropItems() override
size_t _getItemIndex(Widget *_item) const override
void _updateAllVisible(bool _redraw)
void updateDropItemsState(const DDWidgetState &_state) override
void setVerticalAlignment(bool _value)
size_t getIndexSelected() const
Get index of selected item (ITEM_NONE if none selected)
void _resetContainer(bool _update) override
void notifyRootMouseChangeFocus(Widget *_sender, bool _focus)
void findCurrentActiveItem()
void onMouseButtonReleased(int _left, int _top, MouseButton _id) override
void removeAllItems()
Remove all items.
void notifyKeyButtonPressed(Widget *_sender, KeyCode _key, Char _char)
void removeDropItems() override
void _setContainerItemInfo(size_t _index, bool _set, bool _accept) override
bool isVisibleVScroll() const
void clearIndexSelected()
Clear item selection.
void addItem(Any _data=Any::Null, bool update=true)
Add an item to the end of a array.
EventHandle_ItemBoxPtrIntCoordRefBool requestCoordItem
EventHandle_ItemBoxPtrCIBNotifyCellDataRef eventNotifyItem
EventHandle_ItemBoxPtrSizeT eventChangeItemPosition
widget description should be here.
EventHandle_ScrollBarPtrSizeT eventScrollChangePosition
void setScrollPosition(size_t _value)
bool isUserString(const std::string &_key) const
ValueType * _getInternalData(bool _throw=true) const
void _setInternalData(Any _data)
const std::string & getUserString(const std::string &_key) const
widget description should be here.
Definition: MyGUI_Widget.h:37
Widget * getParent() const
void setCoord(const IntCoord &_value) override
EventHandle_WidgetStringString eventChangeProperty
Definition: MyGUI_Widget.h:267
void assignWidget(T *&_widget, const std::string &_name)
Definition: MyGUI_Widget.h:335
virtual void initialiseOverride()
virtual void setVisible(bool _value)
void setPosition(const IntPoint &_value) override
void setSize(const IntSize &_value) override
Widget * getClientWidget()
virtual void _resetContainer(bool _update)
void _setContainer(Widget *_value)
virtual void shutdownOverride()
T * createWidget(const std::string &_skin, const IntCoord &_coord, Align _align, const std::string &_name="")
Definition: MyGUI_Widget.h:67
Widget * _getClientWidget()
If there is client widget return it, otherwise return this.
EventHandle_WidgetVoid eventMouseButtonDoubleClick
virtual void onKeyLostFocus(Widget *_new)
EventHandle_WidgetIntIntButton eventMouseButtonReleased
void setNeedKeyFocus(bool _value)
virtual void onMouseWheel(int _rel)
EventHandle_WidgetIntIntButton eventMouseButtonPressed
EventHandle_WidgetKeyCodeChar eventKeyButtonPressed
virtual void onKeySetFocus(Widget *_old)
EventHandle_WidgetBool eventRootMouseChangeFocus
virtual void onKeyButtonPressed(KeyCode _key, Char _char)
EventPairAddParameter< EventHandle_WidgetIntInt, EventHandle_WidgetIntIntButton > eventMouseDrag
virtual void onKeyButtonReleased(KeyCode _key)
EventHandle_WidgetInt eventMouseWheel
EventHandle_WidgetKeyCode eventKeyButtonReleased
static WidgetManager & getInstance()
void unlinkFromUnlinkers(Widget *_widget)
delegates::DelegateFunction< Args... > * newDelegate(void(*_func)(Args... args))
types::TCoord< int > IntCoord
Definition: MyGUI_Types.h:35
types::TSize< int > IntSize
Definition: MyGUI_Types.h:29
const size_t ITEM_NONE
Definition: MyGUI_Macros.h:17
types::TPoint< int > IntPoint
Definition: MyGUI_Types.h:26
unsigned int Char
Definition: MyGUI_Types.h:49
TPoint< T > point() const
Definition: MyGUI_TCoord.h:185