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