MyGUI  3.2.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)
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)
525  {
526  MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "TabControl::getItemNameAt");
527  return mItemsInfo[_index].name;
528  }
529 
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 
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 
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 
644  void TabControl::setPosition(int _left, int _top)
645  {
646  setPosition(IntPoint(_left, _top));
647  }
648 
649  void TabControl::setSize(int _width, int _height)
650  {
651  setSize(IntSize(_width, _height));
652  }
653 
654  void TabControl::setCoord(int _left, int _top, int _width, int _height)
655  {
656  setCoord(IntCoord(_left, _top, _width, _height));
657  }
658 
660  {
661  return mItemsInfo.size();
662  }
663 
664  TabItem* TabControl::insertItem(TabItem* _to, const UString& _name, Any _data)
665  {
666  return insertItemAt(getItemIndex(_to), _name, _data);
667  }
668 
669  TabItem* TabControl::addItem(const UString& _name, Any _data)
670  {
671  return insertItemAt(ITEM_NONE, _name, _data);
672  }
673 
675  {
676  removeItemAt(getItemIndex(_item));
677  }
678 
680  {
681  return mIndexSelect;
682  }
683 
685  {
687  }
688 
689  void TabControl::setItemData(TabItem* _item, Any _data)
690  {
691  setItemDataAt(getItemIndex(_item), _data);
692  }
693 
694  void TabControl::clearItemDataAt(size_t _index)
695  {
696  setItemDataAt(_index, Any::Null);
697  }
698 
700  {
702  }
703 
704  void TabControl::setItemName(TabItem* _item, const UString& _name)
705  {
706  setItemNameAt(getItemIndex(_item), _name);
707  }
708 
710  {
711  return getItemNameAt(getItemIndex(_item));
712  }
713 
715  {
716  beginToItemAt(getItemIndex(_item));
717  }
718 
720  {
721  if (getItemCount())
722  beginToItemAt(0);
723  }
724 
726  {
727  if (getItemCount())
729  }
730 
732  {
733  if (getIndexSelected() != ITEM_NONE)
735  }
736 
737  void TabControl::setButtonWidth(TabItem* _item, int _width)
738  {
739  setButtonWidthAt(getItemIndex(_item), _width);
740  }
741 
743  {
744  return getButtonWidthAt(getItemIndex(_item));
745  }
746 
748  {
749  return mButtonDefaultWidth;
750  }
751 
753  {
754  return mButtonAutoWidth;
755  }
756 
757  void TabControl::setSmoothShow(bool _value)
758  {
759  mSmoothShow = _value;
760  }
761 
763  {
764  return mSmoothShow;
765  }
766 
768  {
769  return getItemCount();
770  }
771 
773  {
774  addItem(_name);
775  }
776 
777  void TabControl::_removeItemAt(size_t _index)
778  {
779  removeItemAt(_index);
780  }
781 
783  {
784  return getItemAt(_index);
785  }
786 
787  void TabControl::_setItemNameAt(size_t _index, const UString& _name)
788  {
789  setItemNameAt(_index, _name);
790  }
791 
792  const UString& TabControl::_getItemNameAt(size_t _index)
793  {
794  return getItemNameAt(_index);
795  }
796 
798  {
799  if (mHeaderPlace != nullptr)
800  updateBarNew();
801  else
802  updateBarOld();
803  }
804 
805  void TabControl::updateBarOld()
806  {
807  // подстраховка
808  if (_getWidgetBar()->getWidth() < 1)
809  return;
810 
811  if ((_getWidgetBar()->getWidth() < mWidthBar) && (1 < mItemsInfo.size()))
812  {
813  if (!mButtonShow)
814  {
815  mButtonShow = true;
816 
817  if (nullptr != mButtonLeft)
818  mButtonLeft->setVisible(true);
819  if (nullptr != mButtonRight)
820  mButtonRight->setVisible(true);
821  if (nullptr != mButtonDecor)
822  mButtonDecor->setVisible(true);
823  for (VectorWidgetPtr::iterator iter = mWidgetsPatch.begin(); iter != mWidgetsPatch.end(); ++iter)
824  (*iter)->setVisible(true);
825  if (mWidgetBar != nullptr)
826  mWidgetBar->setSize(mWidgetBar->getWidth() - mOffsetTab, mWidgetBar->getHeight());
827  }
828  }
829  else
830  {
831  if (mButtonShow)
832  {
833  mButtonShow = false;
834  if (nullptr != mButtonLeft)
835  mButtonLeft->setVisible(false);
836  if (nullptr != mButtonRight)
837  mButtonRight->setVisible(false);
838  if (nullptr != mButtonDecor)
839  mButtonDecor->setVisible(false);
840  for (VectorWidgetPtr::iterator iter = mWidgetsPatch.begin(); iter != mWidgetsPatch.end(); ++iter)
841  (*iter)->setVisible(false);
842  if (mWidgetBar != nullptr)
843  mWidgetBar->setSize(mWidgetBar->getWidth() + mOffsetTab, mWidgetBar->getHeight());
844  }
845  }
846 
847  // проверяем правильность стартового индекса
848  if (mStartIndex > 0)
849  {
850  // считаем длинну видимых кнопок
851  int width = 0;
852  for (size_t pos = mStartIndex; pos < mItemsInfo.size(); pos++)
853  width += mItemsInfo[pos].width;
854 
855  // уменьшаем индекс до тех пор пока кнопка до индекста полностью не влезет в бар
856  while ((mStartIndex > 0) && ((width + mItemsInfo[mStartIndex - 1].width) <= _getWidgetBar()->getWidth()))
857  {
858  mStartIndex--;
859  width += mItemsInfo[mStartIndex].width;
860  }
861  }
862 
863  // проверяем и обновляем бар
864  int width = 0;
865  size_t count = 0;
866  size_t pos = mStartIndex;
867  for (; pos < mItemsInfo.size(); pos++)
868  {
869  // текущая кнопка не влазиет
870  if (width > _getWidgetBar()->getWidth())
871  break;
872 
873  // следующая не влазиет
874  TabItemInfo& info = mItemsInfo[pos];
875  if ((width + info.width) > _getWidgetBar()->getWidth())
876  {
877  break;
878  }
879 
880  // проверяем физическое наличие кнопки
881  if (count >= mItemButton.size())
883 
884  // если кнопка не соответствует, то изменяем ее
885  Button* button = mItemButton[count]->castType<Button>();
886  button->setVisible(true);
887 
888  // корректируем нажатость кнопки
889  button->setStateSelected(pos == mIndexSelect);
890 
891  if (button->getCaption() != info.name)
892  button->setCaption(info.name);
893  // положение кнопки
894  IntCoord coord(width, 0, info.width, _getWidgetBar()->getHeight());
895  if (coord != button->getCoord())
896  button->setCoord(coord);
897 
898  width += info.width;
899  count ++;
900  }
901 
902  // скрываем кнопки что были созданны, но не видны
903  while (count < mItemButton.size())
904  {
905  mItemButton[count]->setVisible(false);
906  count ++;
907  }
908 
909  bool right = true;
910  if (pos == mItemsInfo.size())
911  right = false;
912 
913  // в редакторе падает почему то, хотя этот скин создается всегда
914  if (mEmptyBarWidget != nullptr)
915  {
916  // корректируем виджет для пустоты
917  if (width < _getWidgetBar()->getWidth())
918  {
919  mEmptyBarWidget->setVisible(true);
920  mEmptyBarWidget->setCoord(width, 0, _getWidgetBar()->getWidth() - width, _getWidgetBar()->getHeight());
921  }
922  else
923  {
924  mEmptyBarWidget->setVisible(false);
925  }
926  }
927 
928  // корректируем доступность стрелок
929  if (mStartIndex == 0)
930  {
931  if (nullptr != mButtonLeft)
932  mButtonLeft->setEnabled(false);
933  }
934  else
935  {
936  if (nullptr != mButtonLeft)
937  mButtonLeft->setEnabled(true);
938  }
939 
940  if (right)
941  {
942  if (nullptr != mButtonRight)
943  mButtonRight->setEnabled(true);
944  }
945  else
946  {
947  if (nullptr != mButtonRight)
948  mButtonRight->setEnabled(false);
949  }
950  }
951 
952  void TabControl::updateBarNew()
953  {
954  if (mHeaderPlace == nullptr)
955  return;
956 
957  // подстраховка
958  if (mHeaderPlace->getWidth() < 1)
959  return;
960 
961  int widthControls = 0;
962  if (mControls != nullptr)
963  widthControls = mControls->getWidth();
964 
965  if ((mHeaderPlace->getWidth() < mWidthBar) && (1 < mItemsInfo.size()) && (mHeaderPlace->getWidth() >= widthControls))
966  {
967  if (!mButtonShow)
968  {
969  mButtonShow = true;
970 
971  if (nullptr != mControls)
972  mControls->setVisible(true);
973  }
974 
975  if (mControls != nullptr)
976  mControls->setCoord(mHeaderPlace->getWidth() - mControls->getWidth(), 0, mControls->getWidth(), mHeaderPlace->getHeight());
977  }
978  else
979  {
980  if (mButtonShow)
981  {
982  mButtonShow = false;
983 
984  if (nullptr != mControls)
985  mControls->setVisible(false);
986  }
987 
988  widthControls = 0;
989  }
990 
991  // проверяем правильность стартового индекса
992  if (mStartIndex > 0)
993  {
994  // считаем длинну видимых кнопок
995  int width = 0;
996  for (size_t pos = mStartIndex; pos < mItemsInfo.size(); pos++)
997  width += mItemsInfo[pos].width;
998 
999  // уменьшаем индекс до тех пор пока кнопка до индекста полностью не влезет в бар
1000  while ((mStartIndex > 0) && ((width + mItemsInfo[mStartIndex - 1].width) <= (mHeaderPlace->getWidth() - widthControls)))
1001  {
1002  mStartIndex--;
1003  width += mItemsInfo[mStartIndex].width;
1004  }
1005  }
1006 
1007  // проверяем и обновляем бар
1008  int width = 0;
1009  size_t count = 0;
1010  size_t pos = mStartIndex;
1011  for (; pos < mItemsInfo.size(); pos++)
1012  {
1013  // текущая кнопка не влазиет
1014  if (width > (mHeaderPlace->getWidth() - widthControls))
1015  break;
1016 
1017  // следующая не влазиет
1018  TabItemInfo& info = mItemsInfo[pos];
1019  if ((width + info.width) > (mHeaderPlace->getWidth() - widthControls))
1020  {
1021  break;
1022  }
1023 
1024  // проверяем физическое наличие кнопки
1025  if (count >= mItemButton.size())
1027 
1028  // если кнопка не соответствует, то изменяем ее
1029  Button* button = mItemButton[count];
1030  button->setVisible(true);
1031 
1032  // корректируем нажатость кнопки
1033  button->setStateSelected(pos == mIndexSelect);
1034 
1035  if (button->getCaption() != info.name)
1036  button->setCaption(info.name);
1037  // положение кнопки
1038  IntCoord coord(width, 0, info.width, mHeaderPlace->getHeight());
1039  if (coord != button->getCoord())
1040  button->setCoord(coord);
1041 
1042  width += info.width;
1043  count ++;
1044  }
1045 
1046  // скрываем кнопки что были созданны, но не видны
1047  while (count < mItemButton.size())
1048  {
1049  mItemButton[count]->setVisible(false);
1050  count ++;
1051  }
1052 
1053  bool right = true;
1054  if (pos == mItemsInfo.size())
1055  right = false;
1056 
1057  if (mEmpty != nullptr)
1058  {
1059  // корректируем виджет для пустоты
1060  mEmpty->setCoord(width, 0, mHeaderPlace->getWidth() - width - widthControls, mHeaderPlace->getHeight());
1061  }
1062 
1063  // корректируем доступность стрелок
1064  if (mStartIndex == 0)
1065  {
1066  if (nullptr != mButtonLeft)
1067  mButtonLeft->setEnabled(false);
1068  }
1069  else
1070  {
1071  if (nullptr != mButtonLeft)
1072  mButtonLeft->setEnabled(true);
1073  }
1074 
1075  if (right)
1076  {
1077  if (nullptr != mButtonRight)
1078  mButtonRight->setEnabled(true);
1079  }
1080  else
1081  {
1082  if (nullptr != mButtonRight)
1083  mButtonRight->setEnabled(false);
1084  }
1085  }
1086 
1087 } // namespace MyGUI