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