MyGUI  3.4.1
MyGUI_TabControl.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_TabControl.h"
10 #include "MyGUI_WidgetManager.h"
11 #include "MyGUI_Button.h"
12 #include "MyGUI_TabItem.h"
13 #include "MyGUI_ResourceSkin.h"
14 
15 namespace MyGUI
16 {
17 
18  const float TAB_SPEED_FADE_COEF = 5.0f;
19 
21  mOffsetTab(0),
22  mButtonShow(true),
23  mWidthBar(0),
24  mWidgetBar(nullptr),
25  mButtonLeft(nullptr),
26  mButtonRight(nullptr),
27  mButtonDecor(nullptr),
28  mEmptyBarWidget(nullptr),
29  mItemTemplate(nullptr),
30  mStartIndex(0),
31  mIndexSelect(ITEM_NONE),
32  mButtonDefaultWidth(1),
33  mSmoothShow(true),
34  mButtonAutoWidth(true),
35  mShutdown(false),
36  mHeaderPlace(nullptr),
37  mControls(nullptr),
38  mEmpty(nullptr)
39  {
40  }
41 
43  {
44  Base::initialiseOverride();
45 
46  if (isUserString("ButtonSkin"))
47  mButtonSkinName = getUserString("ButtonSkin");
48 
49  // OBSOLETE
50  if (isUserString("OffsetBar"))
51  mOffsetTab = utility::parseValue<int>(getUserString("OffsetBar"));
52 
53  // OBSOLETE
54  if (isUserString("EmptyBarSkin"))
55  mEmptySkinName = getUserString("EmptyBarSkin");
56 
57  // OBSOLETE
58  assignWidget(mWidgetBar, "Bar");
59  if (mWidgetBar != nullptr)
60  {
61  mWidgetBar->setSize(mWidgetBar->getWidth() - mOffsetTab, mWidgetBar->getHeight());
62  }
63 
65  assignWidget(mButtonLeft, "Left");
66  if (mButtonLeft != nullptr)
67  {
69  }
70 
72  assignWidget(mButtonRight, "Right");
73  if (mButtonRight != nullptr)
74  {
76  }
77 
78  // OBSOLETE
79  assignWidget(mButtonDecor, "ButtonDecor");
80  if (mButtonDecor != nullptr)
81  {
82  mButtonDecor->setVisible(false);
83  }
84 
86  assignWidget(mItemTemplate, "TabItem");
87  if (mItemTemplate != nullptr)
88  {
89  mItemTemplate->setVisible(false);
90  }
91 
92 #ifndef MYGUI_DONT_USE_OBSOLETE
93  if (mItemTemplate == nullptr)
94  {
95  assignWidget(mItemTemplate, "Sheet");
96  if (mItemTemplate != nullptr)
97  {
98  mItemTemplate->setVisible(false);
99  }
100  }
101 #endif // MYGUI_DONT_USE_OBSOLETE
102 
103  // OBSOLETE
104  Widget* showPatch = nullptr;
105  assignWidget(showPatch, "ShowPatch");
106  if (showPatch != nullptr)
107  {
108  mWidgetsPatch.push_back(showPatch);
109  showPatch->setVisible(false);
110  }
111 
113  assignWidget(mHeaderPlace, "HeaderPlace");
114 
116  assignWidget(mControls, "Controls");
117 
119  assignWidget(mEmpty, "Empty");
120 
121  if (mEmpty == nullptr)
122  {
123  // создаем виджет, носитель скина пустоты бара
124  // OBSOLETE
125  mEmptyBarWidget = _getWidgetBar()->createWidget<Widget>(mEmptySkinName, IntCoord(), Align::Left | Align::Top);
126  }
127 
128  updateBar();
129 
130  // FIXME добавленно, так как шетдаун вызывается и при смене скина
131  mShutdown = false;
132  }
133 
135  {
136  mWidgetsPatch.clear();
137  mWidgetBar = nullptr;
138  mButtonLeft = nullptr;
139  mButtonRight = nullptr;
140  mButtonDecor = nullptr;
141  mItemTemplate = nullptr;
142  mEmptyBarWidget = nullptr;
143 
144  mHeaderPlace = nullptr;
145  mControls = nullptr;
146  mEmpty = nullptr;
147 
148  // FIXME перенесенно из деструктора, может косячить при смене скина
149  mShutdown = true;
150 
151  Base::shutdownOverride();
152  }
153 
155  {
156  Base::onWidgetCreated(_widget);
157 
158  TabItem* child = _widget->castType<TabItem>(false);
159  if (child != nullptr)
160  {
161  child->setCoord(_getWidgetTemplate()->getAbsoluteLeft() - getAbsoluteLeft(), _getWidgetTemplate()->getAbsoluteTop() - getAbsoluteTop(), _getWidgetTemplate()->getWidth(), _getWidgetTemplate()->getHeight());
162  child->setAlign(_getWidgetTemplate()->getAlign());
163 
164  _insertItem(ITEM_NONE, "", child, Any::Null);
165  }
166  }
167 
168  TabItem* TabControl::insertItemAt(size_t _index, const UString& _name, Any _data)
169  {
170  MYGUI_ASSERT_RANGE_INSERT(_index, mItemsInfo.size(), "TabControl::insertItem");
171 
172  Widget* widget = Base::baseCreateWidget(WidgetStyle::Child, TabItem::getClassTypeName(), "Default", _getWidgetTemplate()->getCoord(), _getWidgetTemplate()->getAlign(), "", "", false);
173 
174  size_t lastIndex = mItemsInfo.size() - 1;
175  setItemNameAt(lastIndex, _name);
176  setItemDataAt(lastIndex, _data);
177 
178  swapItems(_index == ITEM_NONE ? lastIndex : _index, lastIndex);
179 
180  return widget->castType<TabItem>();
181  }
182 
183  void TabControl::swapItems(size_t _index1, size_t _index2)
184  {
185  MYGUI_ASSERT_RANGE(_index1, mItemsInfo.size(), "TabControl::swapItems");
186  MYGUI_ASSERT_RANGE(_index2, mItemsInfo.size(), "TabControl::swapItems");
187 
188  if (_index1 != _index2)
189  {
190  std::swap(mItemsInfo[_index1], mItemsInfo[_index2]);
191  updateBar();
192  }
193  }
194 
195  void TabControl::setPosition(const IntPoint& _point)
196  {
197  Base::setPosition(_point);
198 
199  updateBar();
200  }
201 
202  void TabControl::setSize(const IntSize& _size)
203  {
204  Base::setSize(_size);
205 
206  updateBar();
207  }
208 
209  void TabControl::setCoord(const IntCoord& _coord)
210  {
211  Base::setCoord(_coord);
212 
213  updateBar();
214  }
215 
217  {
218  if (_sender == mButtonLeft)
219  {
220  if (mStartIndex > 0)
221  {
222  mStartIndex --;
223  updateBar();
224  }
225  }
226  else if (_sender == mButtonRight)
227  {
228  if ((mStartIndex + 1) < mItemsInfo.size())
229  {
230  mStartIndex ++;
231  // в updateBar() будет подкорректированно если что
232  updateBar();
233  }
234  }
235  }
236 
238  {
239  size_t select = *_sender->_getInternalData<size_t>() + mStartIndex;
240  // щелкнули по той же кнопке
241  if (select == mIndexSelect)
242  {
243  // стараемся показать выделенную кнопку
245  return;
246  }
247  size_t old = mIndexSelect;
248  mIndexSelect = select;
249 
250  size_t count = 0;
251  for (size_t pos = 0; pos < mItemButton.size(); pos++)
252  {
253  Button* button = mItemButton[count]->castType<Button>();
254  if (button->getVisible())
255  {
256  // корректируем нажатость кнопки
257  button->setStateSelected((pos + mStartIndex) == mIndexSelect);
258  }
259  count ++;
260  }
261 
262  // стараемся показать выделенную кнопку
264 
265  // поднимаем страницу для пикинга
266  _forcePick(mItemsInfo[mIndexSelect].item);
267 
268  _showItem(mItemsInfo[mIndexSelect].item, true, mSmoothShow);
269  _showItem(mItemsInfo[old].item, false, mSmoothShow);
270 
271  eventTabChangeSelect(this, mIndexSelect);
272  }
273 
274  void TabControl::beginToItemAt(size_t _index)
275  {
276  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "TabControl::beginToItemAt");
277 
278  // подстраховка
279  if (_getWidgetBar()->getWidth() < 1)
280  return;
281 
282  if (_index == mStartIndex)
283  return;
284  else if (_index < mStartIndex)
285  {
286  mStartIndex = _index;
287  updateBar();
288  }
289  else
290  {
291  // длинна бара от старт индекса до нужной включительно
292  int width = 0;
293  for (size_t pos = mStartIndex; pos <= _index; pos++)
294  {
295  width += mItemsInfo[pos].width;
296  }
297 
298  // уменьшем старт индекс пока не появиться нужная
299  bool change = false;
300  while ((mStartIndex < _index) && (width > _getWidgetBar()->getWidth()))
301  {
302  width -= mItemsInfo[mStartIndex].width;
303  mStartIndex ++;
304  change = true;
305  }
306  if (change)
307  updateBar();
308  }
309  }
310 
312  {
313  mButtonDefaultWidth = _width;
314  if (mButtonDefaultWidth < 1)
315  mButtonDefaultWidth = 1;
316  setButtonAutoWidth(false);
317  }
318 
320  {
321  mButtonAutoWidth = _auto;
322 
323  for (size_t pos = 0; pos < mItemsInfo.size(); pos++)
324  {
325  int width;
326  if (mButtonAutoWidth)
327  width = _getTextWidth(mItemsInfo[pos].name);
328  else
329  width = mButtonDefaultWidth;
330 
331  mWidthBar += width - mItemsInfo[pos].width;
332  mItemsInfo[pos].width = width;
333  }
334 
335  updateBar();
336  }
337 
338  void TabControl::setButtonWidthAt(size_t _index, int _width)
339  {
340  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "TabControl::setButtonWidthAt");
341 
342  if (_width <= 0)
343  {
344  if (mButtonAutoWidth)
345  _width = _getTextWidth(mItemsInfo[_index].name);
346  else
347  _width = mButtonDefaultWidth;
348  }
349 
350  mWidthBar += _width - mItemsInfo[_index].width;
351  mItemsInfo[_index].width = _width;
352 
353  updateBar();
354  }
355 
356  void TabControl::setItemNameAt(size_t _index, const UString& _name)
357  {
358  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "TabControl::setItemNameAt");
359  mItemsInfo[_index].name = _name;
360 
361  int width;
362  if (mButtonAutoWidth)
363  width = _getTextWidth(_name);
364  else
365  width = mButtonDefaultWidth;
366 
367  mWidthBar += width - mItemsInfo[_index].width;
368  mItemsInfo[_index].width = width;
369 
370  updateBar();
371  }
372 
373  void TabControl::setIndexSelected(size_t _index)
374  {
375  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "TabControl::setIndexSelected");
376  if (mIndexSelect == _index)
377  return;
378  size_t old = mIndexSelect;
379  mIndexSelect = _index;
380  updateBar();
381 
382  // поднимаем страницу для пикинга
383  if (mSmoothShow)
384  _forcePick(mItemsInfo[mIndexSelect].item);
385 
386  _showItem(mItemsInfo[mIndexSelect].item, true, mSmoothShow);
387  _showItem(mItemsInfo[old].item, false, mSmoothShow);
388 
390  }
391 
392  void TabControl::actionWidgetHide(Widget* _widget, ControllerItem* _controller)
393  {
394  _widget->setVisible(false);
395  _widget->setEnabled(true);
396  }
397 
398  void TabControl::_showItem(TabItem* _item, bool _show, bool _smooth)
399  {
400  if (!_smooth)
401  {
403  _item->setAlpha(ALPHA_MAX);
404 
405  _item->setVisible(_show);
406 
407  return;
408  }
409 
410  if (_show)
411  {
412  ControllerFadeAlpha* controller = createControllerFadeAlpha(ALPHA_MAX, TAB_SPEED_FADE_COEF, true);
413  ControllerManager::getInstance().addItem(_item, controller);
414  }
415  else
416  {
417  ControllerFadeAlpha* controller = createControllerFadeAlpha(ALPHA_MIN, TAB_SPEED_FADE_COEF, false);
418  controller->eventPostAction += newDelegate(this, &TabControl::actionWidgetHide);
419  ControllerManager::getInstance().addItem(_item, controller);
420  }
421  }
422 
423  Button* TabControl::createButton()
424  {
425  Widget* parent = this;
426  if (mWidgetBar != nullptr)
427  parent = mWidgetBar;
428  else if (mHeaderPlace != nullptr)
429  parent = mHeaderPlace;
430 
431  return parent->createWidget<Button>(mButtonSkinName, IntCoord(), Align::Left | Align::Top);
432  }
433 
435  {
436  Button* button = createButton();
438  button->_setInternalData(mItemButton.size()); // порядковый номер
439  mItemButton.push_back(button);
440  }
441 
443  {
444  if (mItemButton.empty())
446 
447  UString save = mItemButton[0]->getCaption();
448  mItemButton[0]->setCaption(_text);
449 
450  ISubWidgetText* text = mItemButton[0]->getSubWidgetText();
451  const IntSize& size = text ? text->getTextSize() : IntSize();
452  const IntCoord& coord = text ? text->getCoord() : IntCoord();
453 
454  mItemButton[0]->setCaption(save);
455 
456  return size.width + mItemButton[0]->getWidth() - coord.width;
457  }
458 
460  {
461  // общий шутдаун виджета
462  if (mShutdown)
463  return;
464 
465  size_t index = getItemIndex(_sheet);
466 
467  mWidthBar -= mItemsInfo[index].width;
468  mItemsInfo.erase(mItemsInfo.begin() + index);
469 
470  if (mItemsInfo.empty())
471  mIndexSelect = ITEM_NONE;
472  else
473  {
474  if (index < mIndexSelect)
475  mIndexSelect --;
476  else if (index == mIndexSelect)
477  {
478  if (mIndexSelect == mItemsInfo.size())
479  mIndexSelect --;
480  mItemsInfo[mIndexSelect].item->setVisible(true);
481  mItemsInfo[mIndexSelect].item->setAlpha(ALPHA_MAX);
482  }
483  }
484 
485  updateBar();
486  }
487 
488  void TabControl::_insertItem(size_t _index, const UString& _name, TabItem* _sheet, Any _data)
489  {
490  if (_index == ITEM_NONE)
491  _index = mItemsInfo.size();
492 
493  // добавляем инфу о вкладке
494  int width = (mButtonAutoWidth ? _getTextWidth(_name) : mButtonDefaultWidth);
495  mWidthBar += width;
496 
497  mItemsInfo.insert(mItemsInfo.begin() + _index, TabItemInfo(width, _name, _sheet, _data));
498 
499  // первая вкладка
500  if (1 == mItemsInfo.size())
501  mIndexSelect = 0;
502  else
503  {
504  _sheet->setVisible(false);
505  if (_index <= mIndexSelect)
506  mIndexSelect ++;
507  }
508 
509  updateBar();
510  }
511 
512  void TabControl::setItemDataAt(size_t _index, Any _data)
513  {
514  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "TabControl::setItemDataAt");
515  mItemsInfo[_index].data = _data;
516  }
517 
518  int TabControl::getButtonWidthAt(size_t _index) const
519  {
520  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "TabControl::getButtonWidthAt");
521  return mItemsInfo[_index].width;
522  }
523 
524  const UString& TabControl::getItemNameAt(size_t _index) const
525  {
526  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "TabControl::getItemNameAt");
527  return mItemsInfo[_index].name;
528  }
529 
530  TabItem* TabControl::getItemAt(size_t _index) const
531  {
532  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "TabControl::getItemAt");
533  return mItemsInfo[_index].item;
534  }
535 
536  void TabControl::removeItemAt(size_t _index)
537  {
538  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "TabControl::removeItemAt");
539  this->_destroyChildWidget(mItemsInfo[_index].item);
540  }
541 
543  {
544  while (!mItemsInfo.empty())
545  {
546  _destroyChildWidget(mItemsInfo.back().item);
547  }
548  }
549 
550  ControllerFadeAlpha* TabControl::createControllerFadeAlpha(float _alpha, float _coef, bool _enable)
551  {
553  ControllerFadeAlpha* controller = item->castType<ControllerFadeAlpha>();
554 
555  controller->setAlpha(_alpha);
556  controller->setCoef(_coef);
557  controller->setEnabled(_enable);
558 
559  return controller;
560  }
561 
562  size_t TabControl::getItemIndex(const TabItem* _item) const
563  {
564  for (size_t pos = 0; pos < mItemsInfo.size(); pos++)
565  {
566  if (mItemsInfo[pos].item == _item)
567  return pos;
568  }
569  MYGUI_EXCEPT("item (" << _item << ") not found, source 'TabControl::getItemIndex'");
570  }
571 
572  size_t TabControl::findItemIndex(const TabItem* _item)
573  {
574  for (size_t pos = 0; pos < mItemsInfo.size(); pos++)
575  {
576  if (mItemsInfo[pos].item == _item)
577  return pos;
578  }
579  return ITEM_NONE;
580  }
581 
583  {
584  for (size_t pos = 0; pos < mItemsInfo.size(); pos++)
585  {
586  if (mItemsInfo[pos].name == _name)
587  return pos;
588  }
589  return ITEM_NONE;
590  }
591 
593  {
594  for (size_t pos = 0; pos < mItemsInfo.size(); pos++)
595  {
596  if (mItemsInfo[pos].name == _name)
597  return mItemsInfo[pos].item;
598  }
599  return nullptr;
600  }
601 
603  {
604  return getIndexSelected() != ITEM_NONE ? getItemAt(getIndexSelected()) : nullptr;
605  }
606 
607  Widget* TabControl::_getWidgetTemplate()
608  {
609  return mItemTemplate == nullptr ? this : mItemTemplate;
610  }
611 
612  Widget* TabControl::_getWidgetBar()
613  {
614  return mWidgetBar == nullptr ? this : mWidgetBar;
615  }
616 
617  void TabControl::setPropertyOverride(const std::string& _key, const std::string& _value)
618  {
620  if (_key == "ButtonWidth")
621  setButtonDefaultWidth(utility::parseValue<int>(_value));
622 
624  else if (_key == "ButtonAutoWidth")
625  setButtonAutoWidth(utility::parseValue<bool>(_value));
626 
628  else if (_key == "SmoothShow")
629  setSmoothShow(utility::parseValue<bool>(_value));
630 
631  // не коментировать
632  else if (_key == "SelectItem")
633  setIndexSelected(utility::parseValue<size_t>(_value));
634 
635  else
636  {
637  Base::setPropertyOverride(_key, _value);
638  return;
639  }
640 
641  eventChangeProperty(this, _key, _value);
642  }
643 
645  {
646  return mItemsInfo.size();
647  }
648 
649  TabItem* TabControl::insertItem(TabItem* _to, const UString& _name, Any _data)
650  {
651  return insertItemAt(getItemIndex(_to), _name, _data);
652  }
653 
654  TabItem* TabControl::addItem(const UString& _name, Any _data)
655  {
656  return insertItemAt(ITEM_NONE, _name, _data);
657  }
658 
660  {
661  removeItemAt(getItemIndex(_item));
662  }
663 
665  {
666  return mIndexSelect;
667  }
668 
670  {
672  }
673 
674  void TabControl::setItemData(TabItem* _item, Any _data)
675  {
676  setItemDataAt(getItemIndex(_item), _data);
677  }
678 
679  void TabControl::clearItemDataAt(size_t _index)
680  {
681  setItemDataAt(_index, Any::Null);
682  }
683 
685  {
687  }
688 
689  void TabControl::setItemName(TabItem* _item, const UString& _name)
690  {
691  setItemNameAt(getItemIndex(_item), _name);
692  }
693 
694  const UString& TabControl::getItemName(const TabItem* _item) const
695  {
696  return getItemNameAt(getItemIndex(_item));
697  }
698 
699  void TabControl::beginToItem(const TabItem* _item)
700  {
701  beginToItemAt(getItemIndex(_item));
702  }
703 
705  {
706  if (getItemCount())
707  beginToItemAt(0);
708  }
709 
711  {
712  if (getItemCount())
714  }
715 
717  {
718  if (getIndexSelected() != ITEM_NONE)
720  }
721 
722  void TabControl::setButtonWidth(TabItem* _item, int _width)
723  {
724  setButtonWidthAt(getItemIndex(_item), _width);
725  }
726 
728  {
729  return getButtonWidthAt(getItemIndex(_item));
730  }
731 
733  {
734  return mButtonDefaultWidth;
735  }
736 
738  {
739  return mButtonAutoWidth;
740  }
741 
742  void TabControl::setSmoothShow(bool _value)
743  {
744  mSmoothShow = _value;
745  }
746 
748  {
749  return mSmoothShow;
750  }
751 
753  {
754  return getItemCount();
755  }
756 
758  {
759  addItem(_name);
760  }
761 
762  void TabControl::_removeItemAt(size_t _index)
763  {
764  removeItemAt(_index);
765  }
766 
767  Widget* TabControl::_getItemAt(size_t _index) const
768  {
769  return getItemAt(_index);
770  }
771 
772  void TabControl::_setItemNameAt(size_t _index, const UString& _name)
773  {
774  setItemNameAt(_index, _name);
775  }
776 
777  const UString& TabControl::_getItemNameAt(size_t _index) const
778  {
779  return getItemNameAt(_index);
780  }
781 
783  {
784  if (mHeaderPlace != nullptr)
785  updateBarNew();
786  else
787  updateBarOld();
788  }
789 
790  void TabControl::updateBarOld()
791  {
792  // подстраховка
793  if (_getWidgetBar()->getWidth() < 1)
794  return;
795 
796  if ((_getWidgetBar()->getWidth() < mWidthBar) && (1 < mItemsInfo.size()))
797  {
798  if (!mButtonShow)
799  {
800  mButtonShow = true;
801 
802  if (nullptr != mButtonLeft)
803  mButtonLeft->setVisible(true);
804  if (nullptr != mButtonRight)
805  mButtonRight->setVisible(true);
806  if (nullptr != mButtonDecor)
807  mButtonDecor->setVisible(true);
808  for (VectorWidgetPtr::iterator iter = mWidgetsPatch.begin(); iter != mWidgetsPatch.end(); ++iter)
809  (*iter)->setVisible(true);
810  if (mWidgetBar != nullptr)
811  mWidgetBar->setSize(mWidgetBar->getWidth() - mOffsetTab, mWidgetBar->getHeight());
812  }
813  }
814  else
815  {
816  if (mButtonShow)
817  {
818  mButtonShow = false;
819  if (nullptr != mButtonLeft)
820  mButtonLeft->setVisible(false);
821  if (nullptr != mButtonRight)
822  mButtonRight->setVisible(false);
823  if (nullptr != mButtonDecor)
824  mButtonDecor->setVisible(false);
825  for (VectorWidgetPtr::iterator iter = mWidgetsPatch.begin(); iter != mWidgetsPatch.end(); ++iter)
826  (*iter)->setVisible(false);
827  if (mWidgetBar != nullptr)
828  mWidgetBar->setSize(mWidgetBar->getWidth() + mOffsetTab, mWidgetBar->getHeight());
829  }
830  }
831 
832  // проверяем правильность стартового индекса
833  if (mStartIndex > 0)
834  {
835  // считаем длинну видимых кнопок
836  int width = 0;
837  for (size_t pos = mStartIndex; pos < mItemsInfo.size(); pos++)
838  width += mItemsInfo[pos].width;
839 
840  // уменьшаем индекс до тех пор пока кнопка до индекста полностью не влезет в бар
841  while ((mStartIndex > 0) && ((width + mItemsInfo[mStartIndex - 1].width) <= _getWidgetBar()->getWidth()))
842  {
843  mStartIndex--;
844  width += mItemsInfo[mStartIndex].width;
845  }
846  }
847 
848  // проверяем и обновляем бар
849  int width = 0;
850  size_t count = 0;
851  size_t pos = mStartIndex;
852  for (; pos < mItemsInfo.size(); pos++)
853  {
854  // текущая кнопка не влазиет
855  if (width > _getWidgetBar()->getWidth())
856  break;
857 
858  // следующая не влазиет
859  TabItemInfo& info = mItemsInfo[pos];
860  if ((width + info.width) > _getWidgetBar()->getWidth())
861  {
862  break;
863  }
864 
865  // проверяем физическое наличие кнопки
866  if (count >= mItemButton.size())
868 
869  // если кнопка не соответствует, то изменяем ее
870  Button* button = mItemButton[count]->castType<Button>();
871  button->setVisible(true);
872 
873  // корректируем нажатость кнопки
874  button->setStateSelected(pos == mIndexSelect);
875 
876  if (button->getCaption() != info.name)
877  button->setCaption(info.name);
878  // положение кнопки
879  IntCoord coord(width, 0, info.width, _getWidgetBar()->getHeight());
880  if (coord != button->getCoord())
881  button->setCoord(coord);
882 
883  width += info.width;
884  count ++;
885  }
886 
887  // скрываем кнопки что были созданны, но не видны
888  while (count < mItemButton.size())
889  {
890  mItemButton[count]->setVisible(false);
891  count ++;
892  }
893 
894  bool right = true;
895  if (pos == mItemsInfo.size())
896  right = false;
897 
898  // в редакторе падает почему то, хотя этот скин создается всегда
899  if (mEmptyBarWidget != nullptr)
900  {
901  // корректируем виджет для пустоты
902  if (width < _getWidgetBar()->getWidth())
903  {
904  mEmptyBarWidget->setVisible(true);
905  mEmptyBarWidget->setCoord(width, 0, _getWidgetBar()->getWidth() - width, _getWidgetBar()->getHeight());
906  }
907  else
908  {
909  mEmptyBarWidget->setVisible(false);
910  }
911  }
912 
913  // корректируем доступность стрелок
914  if (mStartIndex == 0)
915  {
916  if (nullptr != mButtonLeft)
917  mButtonLeft->setEnabled(false);
918  }
919  else
920  {
921  if (nullptr != mButtonLeft)
922  mButtonLeft->setEnabled(true);
923  }
924 
925  if (right)
926  {
927  if (nullptr != mButtonRight)
928  mButtonRight->setEnabled(true);
929  }
930  else
931  {
932  if (nullptr != mButtonRight)
933  mButtonRight->setEnabled(false);
934  }
935  }
936 
937  void TabControl::updateBarNew()
938  {
939  if (mHeaderPlace == nullptr)
940  return;
941 
942  // подстраховка
943  if (mHeaderPlace->getWidth() < 1)
944  return;
945 
946  int widthControls = 0;
947  if (mControls != nullptr)
948  widthControls = mControls->getWidth();
949 
950  if ((mHeaderPlace->getWidth() < mWidthBar) && (1 < mItemsInfo.size()) && (mHeaderPlace->getWidth() >= widthControls))
951  {
952  if (!mButtonShow)
953  {
954  mButtonShow = true;
955 
956  if (nullptr != mControls)
957  mControls->setVisible(true);
958  }
959 
960  if (mControls != nullptr)
961  mControls->setCoord(mHeaderPlace->getWidth() - mControls->getWidth(), 0, mControls->getWidth(), mHeaderPlace->getHeight());
962  }
963  else
964  {
965  if (mButtonShow)
966  {
967  mButtonShow = false;
968 
969  if (nullptr != mControls)
970  mControls->setVisible(false);
971  }
972 
973  widthControls = 0;
974  }
975 
976  // проверяем правильность стартового индекса
977  if (mStartIndex > 0)
978  {
979  // считаем длинну видимых кнопок
980  int width = 0;
981  for (size_t pos = mStartIndex; pos < mItemsInfo.size(); pos++)
982  width += mItemsInfo[pos].width;
983 
984  // уменьшаем индекс до тех пор пока кнопка до индекста полностью не влезет в бар
985  while ((mStartIndex > 0) && ((width + mItemsInfo[mStartIndex - 1].width) <= (mHeaderPlace->getWidth() - widthControls)))
986  {
987  mStartIndex--;
988  width += mItemsInfo[mStartIndex].width;
989  }
990  }
991 
992  // проверяем и обновляем бар
993  int width = 0;
994  size_t count = 0;
995  size_t pos = mStartIndex;
996  for (; pos < mItemsInfo.size(); pos++)
997  {
998  // текущая кнопка не влазиет
999  if (width > (mHeaderPlace->getWidth() - widthControls))
1000  break;
1001 
1002  // следующая не влазиет
1003  TabItemInfo& info = mItemsInfo[pos];
1004  if ((width + info.width) > (mHeaderPlace->getWidth() - widthControls))
1005  {
1006  break;
1007  }
1008 
1009  // проверяем физическое наличие кнопки
1010  if (count >= mItemButton.size())
1012 
1013  // если кнопка не соответствует, то изменяем ее
1014  Button* button = mItemButton[count];
1015  button->setVisible(true);
1016 
1017  // корректируем нажатость кнопки
1018  button->setStateSelected(pos == mIndexSelect);
1019 
1020  if (button->getCaption() != info.name)
1021  button->setCaption(info.name);
1022  // положение кнопки
1023  IntCoord coord(width, 0, info.width, mHeaderPlace->getHeight());
1024  if (coord != button->getCoord())
1025  button->setCoord(coord);
1026 
1027  width += info.width;
1028  count ++;
1029  }
1030 
1031  // скрываем кнопки что были созданны, но не видны
1032  while (count < mItemButton.size())
1033  {
1034  mItemButton[count]->setVisible(false);
1035  count ++;
1036  }
1037 
1038  bool right = true;
1039  if (pos == mItemsInfo.size())
1040  right = false;
1041 
1042  if (mEmpty != nullptr)
1043  {
1044  // корректируем виджет для пустоты
1045  mEmpty->setCoord(width, 0, mHeaderPlace->getWidth() - width - widthControls, mHeaderPlace->getHeight());
1046  }
1047 
1048  // корректируем доступность стрелок
1049  if (mStartIndex == 0)
1050  {
1051  if (nullptr != mButtonLeft)
1052  mButtonLeft->setEnabled(false);
1053  }
1054  else
1055  {
1056  if (nullptr != mButtonLeft)
1057  mButtonLeft->setEnabled(true);
1058  }
1059 
1060  if (right)
1061  {
1062  if (nullptr != mButtonRight)
1063  mButtonRight->setEnabled(true);
1064  }
1065  else
1066  {
1067  if (nullptr != mButtonRight)
1068  mButtonRight->setEnabled(false);
1069  }
1070  }
1071 
1072 } // namespace MyGUI
#define MYGUI_EXCEPT(dest)
#define MYGUI_ASSERT_RANGE_INSERT(index, size, owner)
#define MYGUI_ASSERT_RANGE(index, size, owner)
static AnyEmpty Null
Definition: MyGUI_Any.h:59
widget description should be here.
Definition: MyGUI_Button.h:22
void setStateSelected(bool _value)
Set button selected state.
static const std::string & getClassTypeName()
EventPairAddParameter< EventHandle_WidgetPtr, EventHandle_WidgetPtrControllerItemPtr > eventPostAction
ControllerItem * createItem(const std::string &_type)
static ControllerManager & getInstance()
void addItem(Widget *_widget, ControllerItem *_item)
const IntCoord & getCoord() const
Type * castType(bool _throw=true)
Definition: MyGUI_IObject.h:18
virtual IntSize getTextSize() const
EventPair< EventHandle_WidgetSizeT, EventHandle_TabPtrSizeT > eventTabChangeSelect
void setItemNameAt(size_t _index, const UString &_name)
Replace an item name at a specified position.
int _getTextWidth(const UString &_text)
void setButtonWidthAt(size_t _index, int _width=DEFAULT)
Set button width at a specified position.
void setCoord(const IntCoord &_value) override
size_t getIndexSelected() const
Get index of selected item (ITEM_NONE if none selected)
void _setItemNameAt(size_t _index, const UString &_name) override
size_t findItemIndex(const TabItem *_item)
Search item, returns the position of the first occurrence in array or ITEM_NONE if item not found.
void swapItems(size_t _index1, size_t _index2)
int getButtonDefaultWidth() const
void beginToItemSelected()
Move all elements so selected becomes visible.
void clearItemDataAt(size_t _index)
Clear an item data at a specified position.
void setItemDataAt(size_t _index, Any _data)
Replace an item data at a specified position.
void beginToItemFirst()
Move all elements so first becomes visible.
void _notifyDeleteItem(TabItem *_item)
void beginToItemLast()
Move all elements so last becomes visible.
void onWidgetCreated(Widget *_widget) override
void removeAllItems()
Remove all items.
void setSmoothShow(bool _value)
void _insertItem(size_t _index, const UString &_name, TabItem *_sheet, Any _data)
size_t getItemCount() const
Get number of items.
void beginToItem(const TabItem *_item)
Move all elements so specified becomes visible.
size_t findItemIndexWith(const UString &_name)
Search item, returns the position of the first occurrence in array or ITEM_NONE if item not found.
void setItemSelected(TabItem *_item)
Select item.
TabItem * findItemWith(const UString &_name)
Search item, returns the item of the first occurrence in array or nullptr if item not found.
TabItem * getItemSelected() const
Get selected item (nullptr if none selected)
size_t _getItemCount() const override
TabItem * insertItem(TabItem *_to, const UString &_name, Any _data=Any::Null)
Insert an item into a array.
void setPosition(const IntPoint &_value) override
void shutdownOverride() override
void setButtonWidth(TabItem *_item, int _width=DEFAULT)
Set button width.
void _addItem(const MyGUI::UString &_name) override
void setIndexSelected(size_t _index)
Select specified _index.
void setSize(const IntSize &_value) override
void setItemName(TabItem *_item, const UString &_name)
Replace an item name.
void _removeItemAt(size_t _index) override
size_t getItemIndex(const TabItem *_item) const
Get item index.
int getButtonWidth(TabItem *_item) const
Get button width.
Widget * _getItemAt(size_t _index) const override
void removeItemAt(size_t _index)
Remove item at a specified position.
void beginToItemAt(size_t _index)
Move all elements so specified becomes visible.
void clearItemData(TabItem *_item)
Clear an item data.
void notifyPressedBarButtonEvent(MyGUI::Widget *_sender)
void setButtonAutoWidth(bool _value)
const UString & getItemNameAt(size_t _index) const
Get item name from specified position.
void setItemData(TabItem *_item, Any _data)
Replace an item data.
bool getSmoothShow() const
void setPropertyOverride(const std::string &_key, const std::string &_value) override
void removeItem(TabItem *_item)
Remove item.
const UString & _getItemNameAt(size_t _index) const override
TabItem * addItem(const UString &_name, Any _data=Any::Null)
Add an item to the end of a array.
int getButtonWidthAt(size_t _index) const
Get button width at a specified position.
void _showItem(TabItem *_sheet, bool _show, bool _smooth)
bool getButtonAutoWidth() const
TabItem * getItemAt(size_t _index) const
Get item from specified position.
const UString & getItemName(const TabItem *_item) const
Get item name.
void setButtonDefaultWidth(int _value)
void initialiseOverride() override
TabItem * insertItemAt(size_t _index, const UString &_name, Any _data=Any::Null)
Insert an item into a array at a specified position.
void notifyPressedButtonEvent(MyGUI::Widget *_sender)
widget description should be here.
Definition: MyGUI_TabItem.h:22
static const std::string & getClassTypeName()
Definition: MyGUI_TabItem.h:23
A UTF-16 string with implicit conversion to/from std::string and std::wstring.
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
void setCoord(const IntCoord &_value) override
void setAlpha(float _value)
void _destroyChildWidget(Widget *_widget)
EventHandle_WidgetStringString eventChangeProperty
Definition: MyGUI_Widget.h:267
void assignWidget(T *&_widget, const std::string &_name)
Definition: MyGUI_Widget.h:335
virtual void setVisible(bool _value)
virtual void setEnabled(bool _value)
bool getVisible() const
void setSize(const IntSize &_value) override
Align getAlign() const
virtual void setAlign(Align _value)
void _forcePick(Widget *_widget)
T * createWidget(const std::string &_skin, const IntCoord &_coord, Align _align, const std::string &_name="")
Definition: MyGUI_Widget.h:67
EventHandle_WidgetVoid eventMouseButtonClick
const float TAB_SPEED_FADE_COEF
const float ALPHA_MIN
Definition: MyGUI_Macros.h:20
delegates::DelegateFunction< Args... > * newDelegate(void(*_func)(Args... args))
types::TCoord< int > IntCoord
Definition: MyGUI_Types.h:35
const float ALPHA_MAX
Definition: MyGUI_Macros.h:19
types::TSize< int > IntSize
Definition: MyGUI_Types.h:29
const size_t ITEM_NONE
Definition: MyGUI_Macros.h:17