MyGUI  3.2.0
MyGUI_TabControl.cpp
Go to the documentation of this file.
00001 
00006 /*
00007     This file is part of MyGUI.
00008 
00009     MyGUI is free software: you can redistribute it and/or modify
00010     it under the terms of the GNU Lesser General Public License as published by
00011     the Free Software Foundation, either version 3 of the License, or
00012     (at your option) any later version.
00013 
00014     MyGUI is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017     GNU Lesser General Public License for more details.
00018 
00019     You should have received a copy of the GNU Lesser General Public License
00020     along with MyGUI.  If not, see <http://www.gnu.org/licenses/>.
00021 */
00022 #include "MyGUI_Precompiled.h"
00023 #include "MyGUI_TabControl.h"
00024 #include "MyGUI_ControllerManager.h"
00025 #include "MyGUI_WidgetManager.h"
00026 #include "MyGUI_Button.h"
00027 #include "MyGUI_TabItem.h"
00028 #include "MyGUI_ResourceSkin.h"
00029 
00030 namespace MyGUI
00031 {
00032 
00033     const float TAB_SPEED_FADE_COEF = 5.0f;
00034 
00035     TabControl::TabControl() :
00036         mOffsetTab(0),
00037         mButtonShow(true),
00038         mWidthBar(0),
00039         mWidgetBar(nullptr),
00040         mButtonLeft(nullptr),
00041         mButtonRight(nullptr),
00042         mButtonDecor(nullptr),
00043         mEmptyBarWidget(nullptr),
00044         mItemTemplate(nullptr),
00045         mStartIndex(0),
00046         mIndexSelect(ITEM_NONE),
00047         mButtonDefaultWidth(1),
00048         mSmoothShow(true),
00049         mButtonAutoWidth(true),
00050         mShutdown(false),
00051         mHeaderPlace(nullptr),
00052         mControls(nullptr),
00053         mEmpty(nullptr)
00054     {
00055     }
00056 
00057     void TabControl::initialiseOverride()
00058     {
00059         Base::initialiseOverride();
00060 
00061         if (isUserString("ButtonSkin"))
00062             mButtonSkinName = getUserString("ButtonSkin");
00063 
00064         // OBSOLETE
00065         if (isUserString("OffsetBar"))
00066             mOffsetTab = utility::parseValue<int>(getUserString("OffsetBar"));
00067         // OBSOLETE
00068         if (isUserString("EmptyBarSkin"))
00069             mEmptySkinName = getUserString("EmptyBarSkin");
00070 
00071         // OBSOLETE
00072         assignWidget(mWidgetBar, "Bar");
00073         if (mWidgetBar != nullptr)
00074         {
00075             mWidgetBar->setSize(mWidgetBar->getWidth() - mOffsetTab, mWidgetBar->getHeight());
00076         }
00077 
00078         assignWidget(mButtonLeft, "Left");
00079         if (mButtonLeft != nullptr)
00080         {
00081             mButtonLeft->eventMouseButtonClick += newDelegate(this, &TabControl::notifyPressedButtonEvent);
00082         }
00083 
00084         assignWidget(mButtonRight, "Right");
00085         if (mButtonRight != nullptr)
00086         {
00087             mButtonRight->eventMouseButtonClick += newDelegate(this, &TabControl::notifyPressedButtonEvent);
00088         }
00089 
00090         // OBSOLETE
00091         assignWidget(mButtonDecor, "ButtonDecor");
00092         if (mButtonDecor != nullptr)
00093         {
00094             mButtonDecor->setVisible(false);
00095         }
00096 
00097         assignWidget(mItemTemplate, "TabItem");
00098         if (mItemTemplate != nullptr)
00099         {
00100             mItemTemplate->setVisible(false);
00101         }
00102 
00103 #ifndef MYGUI_DONT_USE_OBSOLETE
00104         if (mItemTemplate == nullptr)
00105         {
00106             assignWidget(mItemTemplate, "Sheet");
00107             if (mItemTemplate != nullptr)
00108             {
00109                 mItemTemplate->setVisible(false);
00110             }
00111         }
00112 #endif // MYGUI_DONT_USE_OBSOLETE
00113 
00114         // OBSOLETE
00115         Widget* showPatch = nullptr;
00116         assignWidget(showPatch, "ShowPatch");
00117         if (showPatch != nullptr)
00118         {
00119             mWidgetsPatch.push_back(showPatch);
00120             showPatch->setVisible(false);
00121         }
00122 
00123         assignWidget(mHeaderPlace, "HeaderPlace");
00124         assignWidget(mControls, "Controls");
00125         assignWidget(mEmpty, "Empty");
00126 
00127         if (mEmpty == nullptr)
00128         {
00129             // создаем виджет, носитель скина пустоты бара
00130             // OBSOLETE
00131             mEmptyBarWidget = _getWidgetBar()->createWidget<Widget>(mEmptySkinName, IntCoord(), Align::Left | Align::Top);
00132         }
00133 
00134         updateBar();
00135 
00136         // FIXME добавленно, так как шетдаун вызывается и при смене скина
00137         mShutdown = false;
00138     }
00139 
00140     void TabControl::shutdownOverride()
00141     {
00142         mWidgetsPatch.clear();
00143         mWidgetBar = nullptr;
00144         mButtonLeft = nullptr;
00145         mButtonRight = nullptr;
00146         mButtonDecor = nullptr;
00147         mItemTemplate = nullptr;
00148         mEmptyBarWidget = nullptr;
00149 
00150         mHeaderPlace = nullptr;
00151         mControls = nullptr;
00152         mEmpty = nullptr;
00153 
00154         // FIXME перенесенно из деструктора, может косячить при смене скина
00155         mShutdown = true;
00156 
00157         Base::shutdownOverride();
00158     }
00159 
00160     void TabControl::onWidgetCreated(Widget* _widget)
00161     {
00162         Base::onWidgetCreated(_widget);
00163 
00164         TabItem* child = _widget->castType<TabItem>(false);
00165         if (child != nullptr)
00166         {
00167             child->setCoord(_getWidgetTemplate()->getAbsoluteLeft() - getAbsoluteLeft(), _getWidgetTemplate()->getAbsoluteTop() - getAbsoluteTop(), _getWidgetTemplate()->getWidth(), _getWidgetTemplate()->getHeight());
00168             child->setAlign(_getWidgetTemplate()->getAlign());
00169 
00170             _insertItem(ITEM_NONE, "", child, Any::Null);
00171         }
00172     }
00173 
00174     TabItem* TabControl::insertItemAt(size_t _index, const UString& _name, Any _data)
00175     {
00176         MYGUI_ASSERT_RANGE_INSERT(_index, mItemsInfo.size(), "TabControl::insertItem");
00177 
00178         Widget* widget = Base::baseCreateWidget(WidgetStyle::Child, TabItem::getClassTypeName(), "Default", _getWidgetTemplate()->getCoord(), _getWidgetTemplate()->getAlign(), "", "", false);
00179 
00180         size_t lastIndex = mItemsInfo.size() - 1;
00181         setItemNameAt(lastIndex, _name);
00182         setItemDataAt(lastIndex, _data);
00183 
00184         swapItems(_index == ITEM_NONE ? lastIndex : _index, lastIndex);
00185 
00186         return widget->castType<TabItem>();
00187     }
00188 
00189     void TabControl::swapItems(size_t _index1, size_t _index2)
00190     {
00191         MYGUI_ASSERT_RANGE(_index1, mItemsInfo.size(), "TabControl::swapItems");
00192         MYGUI_ASSERT_RANGE(_index2, mItemsInfo.size(), "TabControl::swapItems");
00193 
00194         if (_index1 != _index2)
00195         {
00196             std::swap(mItemsInfo[_index1], mItemsInfo[_index2]);
00197             updateBar();
00198         }
00199     }
00200 
00201     void TabControl::setPosition(const IntPoint& _point)
00202     {
00203         Base::setPosition(_point);
00204 
00205         updateBar();
00206     }
00207 
00208     void TabControl::setSize(const IntSize& _size)
00209     {
00210         Base::setSize(_size);
00211 
00212         updateBar();
00213     }
00214 
00215     void TabControl::setCoord(const IntCoord& _coord)
00216     {
00217         Base::setCoord(_coord);
00218 
00219         updateBar();
00220     }
00221 
00222     void TabControl::notifyPressedButtonEvent(MyGUI::Widget* _sender)
00223     {
00224         if (_sender == mButtonLeft)
00225         {
00226             if (mStartIndex > 0)
00227             {
00228                 mStartIndex --;
00229                 updateBar();
00230             }
00231         }
00232         else if (_sender == mButtonRight)
00233         {
00234             if ((mStartIndex + 1) < mItemsInfo.size())
00235             {
00236                 mStartIndex ++;
00237                 // в updateBar() будет подкорректированно если что
00238                 updateBar();
00239             }
00240         }
00241     }
00242 
00243     void TabControl::notifyPressedBarButtonEvent(MyGUI::Widget* _sender)
00244     {
00245         size_t select = *_sender->_getInternalData<size_t>() + mStartIndex;
00246         // щелкнули по той же кнопке
00247         if (select == mIndexSelect)
00248         {
00249             // стараемся показать выделенную кнопку
00250             beginToItemSelected();
00251             return;
00252         }
00253         size_t old = mIndexSelect;
00254         mIndexSelect = select;
00255 
00256         size_t count = 0;
00257         for (size_t pos = 0; pos < mItemButton.size(); pos++)
00258         {
00259             Button* button = mItemButton[count]->castType<Button>();
00260             if (button->getVisible())
00261             {
00262                 // корректируем нажатость кнопки
00263                 button->setStateSelected((pos + mStartIndex) == mIndexSelect);
00264             }
00265             count ++;
00266         }
00267 
00268         // стараемся показать выделенную кнопку
00269         beginToItemSelected();
00270 
00271         // поднимаем страницу для пикинга
00272         _forcePick(mItemsInfo[mIndexSelect].item);
00273 
00274         _showItem(mItemsInfo[mIndexSelect].item, true, mSmoothShow);
00275         _showItem(mItemsInfo[old].item, false, mSmoothShow);
00276 
00277         eventTabChangeSelect(this, mIndexSelect);
00278     }
00279 
00280     void TabControl::beginToItemAt(size_t _index)
00281     {
00282         MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "TabControl::beginToItemAt");
00283 
00284         // подстраховка
00285         if (_getWidgetBar()->getWidth() < 1)
00286             return;
00287 
00288         if (_index == mStartIndex)
00289             return;
00290         else if (_index < mStartIndex)
00291         {
00292             mStartIndex = _index;
00293             updateBar();
00294         }
00295         else
00296         {
00297             // длинна бара от старт индекса до нужной включительно
00298             int width = 0;
00299             for (size_t pos = mStartIndex; pos <= _index; pos++)
00300             {
00301                 width += mItemsInfo[pos].width;
00302             }
00303 
00304             // уменьшем старт индекс пока не появиться нужная
00305             bool change = false;
00306             while ((mStartIndex < _index) && (width > _getWidgetBar()->getWidth()))
00307             {
00308                 width -= mItemsInfo[mStartIndex].width;
00309                 mStartIndex ++;
00310                 change = true;
00311             }
00312             if (change)
00313                 updateBar();
00314         }
00315     }
00316 
00317     void TabControl::setButtonDefaultWidth(int _width)
00318     {
00319         mButtonDefaultWidth = _width;
00320         if (mButtonDefaultWidth < 1)
00321             mButtonDefaultWidth = 1;
00322         setButtonAutoWidth(false);
00323     }
00324 
00325     void TabControl::setButtonAutoWidth(bool _auto)
00326     {
00327         mButtonAutoWidth = _auto;
00328 
00329         for (size_t pos = 0; pos < mItemsInfo.size(); pos++)
00330         {
00331             int width;
00332             if (mButtonAutoWidth)
00333                 width = _getTextWidth(mItemsInfo[pos].name);
00334             else
00335                 width = mButtonDefaultWidth;
00336 
00337             mWidthBar += width - mItemsInfo[pos].width;
00338             mItemsInfo[pos].width = width;
00339         }
00340 
00341         updateBar();
00342     }
00343 
00344     void TabControl::setButtonWidthAt(size_t _index, int _width)
00345     {
00346         MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "TabControl::setButtonWidthAt");
00347 
00348         if (_width <= 0)
00349         {
00350             if (mButtonAutoWidth)
00351                 _width = _getTextWidth(mItemsInfo[_index].name);
00352             else
00353                 _width = mButtonDefaultWidth;
00354         }
00355 
00356         mWidthBar += _width - mItemsInfo[_index].width;
00357         mItemsInfo[_index].width = _width;
00358 
00359         updateBar();
00360     }
00361 
00362     void TabControl::setItemNameAt(size_t _index, const UString& _name)
00363     {
00364         MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "TabControl::setItemNameAt");
00365         mItemsInfo[_index].name = _name;
00366 
00367         int width;
00368         if (mButtonAutoWidth)
00369             width = _getTextWidth(_name);
00370         else
00371             width = mButtonDefaultWidth;
00372 
00373         mWidthBar += width - mItemsInfo[_index].width;
00374         mItemsInfo[_index].width = width;
00375 
00376         updateBar();
00377     }
00378 
00379     void TabControl::setIndexSelected(size_t _index)
00380     {
00381         MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "TabControl::setIndexSelected");
00382         if (mIndexSelect == _index)
00383             return;
00384         size_t old = mIndexSelect;
00385         mIndexSelect = _index;
00386         updateBar();
00387 
00388         // поднимаем страницу для пикинга
00389         if (mSmoothShow)
00390             _forcePick(mItemsInfo[mIndexSelect].item);
00391 
00392         _showItem(mItemsInfo[mIndexSelect].item, true, mSmoothShow);
00393         _showItem(mItemsInfo[old].item, false, mSmoothShow);
00394 
00395         beginToItemSelected();
00396     }
00397 
00398     void TabControl::actionWidgetHide(Widget* _widget)
00399     {
00400         _widget->setVisible(false);
00401         _widget->setEnabled(true);
00402     }
00403 
00404     void TabControl::_showItem(TabItem* _item, bool _show, bool _smooth)
00405     {
00406         if (!_smooth)
00407         {
00408             ControllerManager::getInstance().removeItem(_item);
00409             _item->setAlpha(ALPHA_MAX);
00410 
00411             _item->setVisible(_show);
00412 
00413             return;
00414         }
00415 
00416         if (_show)
00417         {
00418             ControllerFadeAlpha* controller = createControllerFadeAlpha(ALPHA_MAX, TAB_SPEED_FADE_COEF, true);
00419             ControllerManager::getInstance().addItem(_item, controller);
00420         }
00421         else
00422         {
00423             ControllerFadeAlpha* controller = createControllerFadeAlpha(ALPHA_MIN, TAB_SPEED_FADE_COEF, false);
00424             controller->eventPostAction += newDelegate(this, &TabControl::actionWidgetHide);
00425             ControllerManager::getInstance().addItem(_item, controller);
00426         }
00427     }
00428 
00429     Button* TabControl::createButton()
00430     {
00431         Widget* parent = this;
00432         if (mWidgetBar != nullptr)
00433             parent = mWidgetBar;
00434         else if (mHeaderPlace != nullptr)
00435             parent = mHeaderPlace;
00436 
00437         return parent->createWidget<Button>(mButtonSkinName, IntCoord(), Align::Left | Align::Top);
00438     }
00439 
00440     void TabControl::_createItemButton()
00441     {
00442         Button* button = createButton();
00443         button->eventMouseButtonClick += newDelegate(this, &TabControl::notifyPressedBarButtonEvent);
00444         button->_setInternalData(mItemButton.size()); // порядковый номер
00445         mItemButton.push_back(button);
00446     }
00447 
00448     int TabControl::_getTextWidth(const UString& _text)
00449     {
00450         if (mItemButton.empty())
00451             _createItemButton();
00452 
00453         UString save = mItemButton[0]->getCaption();
00454         mItemButton[0]->setCaption(_text);
00455 
00456         ISubWidgetText* text = mItemButton[0]->getSubWidgetText();
00457         const IntSize& size = text ? text->getTextSize() : IntSize();
00458         const IntCoord& coord = text ? text->getCoord() : IntCoord();
00459 
00460         mItemButton[0]->setCaption(save);
00461 
00462         return size.width + mItemButton[0]->getWidth() - coord.width;
00463     }
00464 
00465     void TabControl::_notifyDeleteItem(TabItem* _sheet)
00466     {
00467         // общий шутдаун виджета
00468         if (mShutdown)
00469             return;
00470 
00471         size_t index = getItemIndex(_sheet);
00472 
00473         mWidthBar -= mItemsInfo[index].width;
00474         mItemsInfo.erase(mItemsInfo.begin() + index);
00475 
00476         if (mItemsInfo.empty())
00477             mIndexSelect = ITEM_NONE;
00478         else
00479         {
00480             if (index < mIndexSelect)
00481                 mIndexSelect --;
00482             else if (index == mIndexSelect)
00483             {
00484                 if (mIndexSelect == mItemsInfo.size())
00485                     mIndexSelect --;
00486                 mItemsInfo[mIndexSelect].item->setVisible(true);
00487                 mItemsInfo[mIndexSelect].item->setAlpha(ALPHA_MAX);
00488             }
00489         }
00490 
00491         updateBar();
00492     }
00493 
00494     void TabControl::_insertItem(size_t _index, const UString& _name, TabItem* _sheet, Any _data)
00495     {
00496         if (_index == ITEM_NONE)
00497             _index = mItemsInfo.size();
00498 
00499         // добавляем инфу о вкладке
00500         int width = (mButtonAutoWidth ? _getTextWidth(_name) : mButtonDefaultWidth);
00501         mWidthBar += width;
00502 
00503         mItemsInfo.insert(mItemsInfo.begin() + _index, TabItemInfo(width, _name, _sheet, _data));
00504 
00505         // первая вкладка
00506         if (1 == mItemsInfo.size())
00507             mIndexSelect = 0;
00508         else
00509         {
00510             _sheet->setVisible(false);
00511             if (_index <= mIndexSelect)
00512                 mIndexSelect ++;
00513         }
00514 
00515         updateBar();
00516     }
00517 
00518     void TabControl::setItemDataAt(size_t _index, Any _data)
00519     {
00520         MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "TabControl::setItemDataAt");
00521         mItemsInfo[_index].data = _data;
00522     }
00523 
00524     int TabControl::getButtonWidthAt(size_t _index)
00525     {
00526         MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "TabControl::getButtonWidthAt");
00527         return mItemsInfo[_index].width;
00528     }
00529 
00530     const UString& TabControl::getItemNameAt(size_t _index)
00531     {
00532         MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "TabControl::getItemNameAt");
00533         return mItemsInfo[_index].name;
00534     }
00535 
00536     TabItem* TabControl::getItemAt(size_t _index)
00537     {
00538         MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "TabControl::getItemAt");
00539         return mItemsInfo[_index].item;
00540     }
00541 
00542     void TabControl::removeItemAt(size_t _index)
00543     {
00544         MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "TabControl::removeItemAt");
00545         this->_destroyChildWidget(mItemsInfo[_index].item);
00546     }
00547 
00548     void TabControl::removeAllItems()
00549     {
00550         while (!mItemsInfo.empty())
00551         {
00552             _destroyChildWidget(mItemsInfo.back().item);
00553         }
00554     }
00555 
00556     ControllerFadeAlpha* TabControl::createControllerFadeAlpha(float _alpha, float _coef, bool _enable)
00557     {
00558         ControllerItem* item = ControllerManager::getInstance().createItem(ControllerFadeAlpha::getClassTypeName());
00559         ControllerFadeAlpha* controller = item->castType<ControllerFadeAlpha>();
00560 
00561         controller->setAlpha(_alpha);
00562         controller->setCoef(_coef);
00563         controller->setEnabled(_enable);
00564 
00565         return controller;
00566     }
00567 
00568     size_t TabControl::getItemIndex(TabItem* _item)
00569     {
00570         for (size_t pos = 0; pos < mItemsInfo.size(); pos++)
00571         {
00572             if (mItemsInfo[pos].item == _item)
00573                 return pos;
00574         }
00575         MYGUI_EXCEPT("item (" << _item << ") not found, source 'TabControl::getItemIndex'");
00576     }
00577 
00578     size_t TabControl::findItemIndex(TabItem* _item)
00579     {
00580         for (size_t pos = 0; pos < mItemsInfo.size(); pos++)
00581         {
00582             if (mItemsInfo[pos].item == _item)
00583                 return pos;
00584         }
00585         return ITEM_NONE;
00586     }
00587 
00588     size_t TabControl::findItemIndexWith(const UString& _name)
00589     {
00590         for (size_t pos = 0; pos < mItemsInfo.size(); pos++)
00591         {
00592             if (mItemsInfo[pos].name == _name)
00593                 return pos;
00594         }
00595         return ITEM_NONE;
00596     }
00597 
00598     TabItem* TabControl::findItemWith(const UString& _name)
00599     {
00600         for (size_t pos = 0; pos < mItemsInfo.size(); pos++)
00601         {
00602             if (mItemsInfo[pos].name == _name)
00603                 return mItemsInfo[pos].item;
00604         }
00605         return nullptr;
00606     }
00607 
00608     TabItem* TabControl::getItemSelected()
00609     {
00610         return getIndexSelected() != ITEM_NONE ? getItemAt(getIndexSelected()) : nullptr;
00611     }
00612 
00613     Widget* TabControl::_getWidgetTemplate()
00614     {
00615         return mItemTemplate == nullptr ? this : mItemTemplate;
00616     }
00617 
00618     Widget* TabControl::_getWidgetBar()
00619     {
00620         return mWidgetBar == nullptr ? this : mWidgetBar;
00621     }
00622 
00623     void TabControl::setPropertyOverride(const std::string& _key, const std::string& _value)
00624     {
00625         if (_key == "ButtonWidth")
00626             setButtonDefaultWidth(utility::parseValue<int>(_value));
00627         else if (_key == "ButtonAutoWidth")
00628             setButtonAutoWidth(utility::parseValue<bool>(_value));
00629         else if (_key == "SmoothShow")
00630             setSmoothShow(utility::parseValue<bool>(_value));
00631         else if (_key == "SelectItem")
00632             setIndexSelected(utility::parseValue<size_t>(_value));
00633         else
00634         {
00635             Base::setPropertyOverride(_key, _value);
00636             return;
00637         }
00638         eventChangeProperty(this, _key, _value);
00639     }
00640 
00641     void TabControl::setPosition(int _left, int _top)
00642     {
00643         setPosition(IntPoint(_left, _top));
00644     }
00645 
00646     void TabControl::setSize(int _width, int _height)
00647     {
00648         setSize(IntSize(_width, _height));
00649     }
00650 
00651     void TabControl::setCoord(int _left, int _top, int _width, int _height)
00652     {
00653         setCoord(IntCoord(_left, _top, _width, _height));
00654     }
00655 
00656     size_t TabControl::getItemCount() const
00657     {
00658         return mItemsInfo.size();
00659     }
00660 
00661     TabItem* TabControl::insertItem(TabItem* _to, const UString& _name, Any _data)
00662     {
00663         return insertItemAt(getItemIndex(_to), _name, _data);
00664     }
00665 
00666     TabItem* TabControl::addItem(const UString& _name, Any _data)
00667     {
00668         return insertItemAt(ITEM_NONE, _name, _data);
00669     }
00670 
00671     void TabControl::removeItem(TabItem* _item)
00672     {
00673         removeItemAt(getItemIndex(_item));
00674     }
00675 
00676     size_t TabControl::getIndexSelected() const
00677     {
00678         return mIndexSelect;
00679     }
00680 
00681     void TabControl::setItemSelected(TabItem* _item)
00682     {
00683         setIndexSelected(getItemIndex(_item));
00684     }
00685 
00686     void TabControl::setItemData(TabItem* _item, Any _data)
00687     {
00688         setItemDataAt(getItemIndex(_item), _data);
00689     }
00690 
00691     void TabControl::clearItemDataAt(size_t _index)
00692     {
00693         setItemDataAt(_index, Any::Null);
00694     }
00695 
00696     void TabControl::clearItemData(TabItem* _item)
00697     {
00698         clearItemDataAt(getItemIndex(_item));
00699     }
00700 
00701     void TabControl::setItemName(TabItem* _item, const UString& _name)
00702     {
00703         setItemNameAt(getItemIndex(_item), _name);
00704     }
00705 
00706     const UString& TabControl::getItemName(TabItem* _item)
00707     {
00708         return getItemNameAt(getItemIndex(_item));
00709     }
00710 
00711     void TabControl::beginToItem(TabItem* _item)
00712     {
00713         beginToItemAt(getItemIndex(_item));
00714     }
00715 
00716     void TabControl::beginToItemFirst()
00717     {
00718         if (getItemCount())
00719             beginToItemAt(0);
00720     }
00721 
00722     void TabControl::beginToItemLast()
00723     {
00724         if (getItemCount())
00725             beginToItemAt(getItemCount() - 1);
00726     }
00727 
00728     void TabControl::beginToItemSelected()
00729     {
00730         if (getIndexSelected() != ITEM_NONE)
00731             beginToItemAt(getIndexSelected());
00732     }
00733 
00734     void TabControl::setButtonWidth(TabItem* _item, int _width)
00735     {
00736         setButtonWidthAt(getItemIndex(_item), _width);
00737     }
00738 
00739     int TabControl::getButtonWidth(TabItem* _item)
00740     {
00741         return getButtonWidthAt(getItemIndex(_item));
00742     }
00743 
00744     int TabControl::getButtonDefaultWidth() const
00745     {
00746         return mButtonDefaultWidth;
00747     }
00748 
00749     bool TabControl::getButtonAutoWidth() const
00750     {
00751         return mButtonAutoWidth;
00752     }
00753 
00754     void TabControl::setSmoothShow(bool _value)
00755     {
00756         mSmoothShow = _value;
00757     }
00758 
00759     bool TabControl::getSmoothShow() const
00760     {
00761         return mSmoothShow;
00762     }
00763 
00764     size_t TabControl::_getItemCount()
00765     {
00766         return getItemCount();
00767     }
00768 
00769     void TabControl::_addItem(const MyGUI::UString& _name)
00770     {
00771         addItem(_name);
00772     }
00773 
00774     void TabControl::_removeItemAt(size_t _index)
00775     {
00776         removeItemAt(_index);
00777     }
00778 
00779     Widget* TabControl::_getItemAt(size_t _index)
00780     {
00781         return getItemAt(_index);
00782     }
00783 
00784     void TabControl::_setItemNameAt(size_t _index, const UString& _name)
00785     {
00786         setItemNameAt(_index, _name);
00787     }
00788 
00789     const UString& TabControl::_getItemNameAt(size_t _index)
00790     {
00791         return getItemNameAt(_index);
00792     }
00793 
00794     void TabControl::updateBar()
00795     {
00796         if (mHeaderPlace != nullptr)
00797             updateBarNew();
00798         else
00799             updateBarOld();
00800     }
00801 
00802     void TabControl::updateBarOld()
00803     {
00804         // подстраховка
00805         if (_getWidgetBar()->getWidth() < 1)
00806             return;
00807 
00808         if ((_getWidgetBar()->getWidth() < mWidthBar) && (1 < mItemsInfo.size()))
00809         {
00810             if (!mButtonShow)
00811             {
00812                 mButtonShow = true;
00813 
00814                 if (nullptr != mButtonLeft)
00815                     mButtonLeft->setVisible(true);
00816                 if (nullptr != mButtonRight)
00817                     mButtonRight->setVisible(true);
00818                 if (nullptr != mButtonDecor)
00819                     mButtonDecor->setVisible(true);
00820                 for (VectorWidgetPtr::iterator iter = mWidgetsPatch.begin(); iter != mWidgetsPatch.end(); ++iter)
00821                     (*iter)->setVisible(true);
00822                 if (mWidgetBar != nullptr)
00823                     mWidgetBar->setSize(mWidgetBar->getWidth() - mOffsetTab, mWidgetBar->getHeight());
00824             }
00825         }
00826         else
00827         {
00828             if (mButtonShow)
00829             {
00830                 mButtonShow = false;
00831                 if (nullptr != mButtonLeft)
00832                     mButtonLeft->setVisible(false);
00833                 if (nullptr != mButtonRight)
00834                     mButtonRight->setVisible(false);
00835                 if (nullptr != mButtonDecor)
00836                     mButtonDecor->setVisible(false);
00837                 for (VectorWidgetPtr::iterator iter = mWidgetsPatch.begin(); iter != mWidgetsPatch.end(); ++iter)
00838                     (*iter)->setVisible(false);
00839                 if (mWidgetBar != nullptr)
00840                     mWidgetBar->setSize(mWidgetBar->getWidth() + mOffsetTab, mWidgetBar->getHeight());
00841             }
00842         }
00843 
00844         // проверяем правильность стартового индекса
00845         if (mStartIndex > 0)
00846         {
00847             // считаем длинну видимых кнопок
00848             int width = 0;
00849             for (size_t pos = mStartIndex; pos < mItemsInfo.size(); pos++)
00850                 width += mItemsInfo[pos].width;
00851 
00852             // уменьшаем индекс до тех пор пока кнопка до индекста полностью не влезет в бар
00853             while ((mStartIndex > 0) && ((width + mItemsInfo[mStartIndex-1].width) <= _getWidgetBar()->getWidth()))
00854             {
00855                 mStartIndex--;
00856                 width += mItemsInfo[mStartIndex].width;
00857             }
00858         }
00859 
00860         // проверяем и обновляем бар
00861         int width = 0;
00862         size_t count = 0;
00863         size_t pos = mStartIndex;
00864         for (; pos < mItemsInfo.size(); pos++)
00865         {
00866             // текущая кнопка не влазиет
00867             if (width > _getWidgetBar()->getWidth())
00868                 break;
00869 
00870             // следующая не влазиет
00871             TabItemInfo& info = mItemsInfo[pos];
00872             if ((width + info.width) > _getWidgetBar()->getWidth())
00873             {
00874                 break;
00875             }
00876 
00877             // проверяем физическое наличие кнопки
00878             if (count >= mItemButton.size())
00879                 _createItemButton();
00880 
00881             // если кнопка не соответствует, то изменяем ее
00882             Button* button = mItemButton[count]->castType<Button>();
00883             button->setVisible(true);
00884 
00885             // корректируем нажатость кнопки
00886             button->setStateSelected(pos == mIndexSelect);
00887 
00888             if (button->getCaption() != info.name)
00889                 button->setCaption(info.name);
00890             // положение кнопки
00891             IntCoord coord(width, 0, info.width, _getWidgetBar()->getHeight());
00892             if (coord != button->getCoord())
00893                 button->setCoord(coord);
00894 
00895             width += info.width;
00896             count ++;
00897         }
00898 
00899         // скрываем кнопки что были созданны, но не видны
00900         while (count < mItemButton.size())
00901         {
00902             mItemButton[count]->setVisible(false);
00903             count ++;
00904         }
00905 
00906         bool right = true;
00907         if (pos == mItemsInfo.size())
00908             right = false;
00909 
00910         // в редакторе падает почему то, хотя этот скин создается всегда
00911         if (mEmptyBarWidget != nullptr)
00912         {
00913             // корректируем виджет для пустоты
00914             if (width < _getWidgetBar()->getWidth())
00915             {
00916                 mEmptyBarWidget->setVisible(true);
00917                 mEmptyBarWidget->setCoord(width, 0, _getWidgetBar()->getWidth() - width, _getWidgetBar()->getHeight());
00918             }
00919             else
00920             {
00921                 mEmptyBarWidget->setVisible(false);
00922             }
00923         }
00924 
00925         // корректируем доступность стрелок
00926         if (mStartIndex == 0)
00927         {
00928             if (nullptr != mButtonLeft)
00929                 mButtonLeft->setEnabled(false);
00930         }
00931         else
00932         {
00933             if (nullptr != mButtonLeft)
00934                 mButtonLeft->setEnabled(true);
00935         }
00936 
00937         if (right)
00938         {
00939             if (nullptr != mButtonRight)
00940                 mButtonRight->setEnabled(true);
00941         }
00942         else
00943         {
00944             if (nullptr != mButtonRight)
00945                 mButtonRight->setEnabled(false);
00946         }
00947     }
00948 
00949     void TabControl::updateBarNew()
00950     {
00951         // подстраховка
00952         if (mHeaderPlace->getWidth() < 1)
00953             return;
00954 
00955         if (mHeaderPlace == nullptr)
00956             return;
00957 
00958         int widthControls = 0;
00959         if (mControls != nullptr)
00960             widthControls = mControls->getWidth();
00961 
00962         if ((mHeaderPlace->getWidth() < mWidthBar) && (1 < mItemsInfo.size()) && (mHeaderPlace->getWidth() >= widthControls))
00963         {
00964             if (!mButtonShow)
00965             {
00966                 mButtonShow = true;
00967 
00968                 if (nullptr != mControls)
00969                     mControls->setVisible(true);
00970             }
00971 
00972             if (mControls != nullptr)
00973                 mControls->setCoord(mHeaderPlace->getWidth() - mControls->getWidth(), 0, mControls->getWidth(), mHeaderPlace->getHeight());
00974         }
00975         else
00976         {
00977             if (mButtonShow)
00978             {
00979                 mButtonShow = false;
00980 
00981                 if (nullptr != mControls)
00982                     mControls->setVisible(false);
00983             }
00984 
00985             widthControls = 0;
00986         }
00987 
00988         // проверяем правильность стартового индекса
00989         if (mStartIndex > 0)
00990         {
00991             // считаем длинну видимых кнопок
00992             int width = 0;
00993             for (size_t pos = mStartIndex; pos < mItemsInfo.size(); pos++)
00994                 width += mItemsInfo[pos].width;
00995 
00996             // уменьшаем индекс до тех пор пока кнопка до индекста полностью не влезет в бар
00997             while ((mStartIndex > 0) && ((width + mItemsInfo[mStartIndex-1].width) <= (mHeaderPlace->getWidth() - widthControls)))
00998             {
00999                 mStartIndex--;
01000                 width += mItemsInfo[mStartIndex].width;
01001             }
01002         }
01003 
01004         // проверяем и обновляем бар
01005         int width = 0;
01006         size_t count = 0;
01007         size_t pos = mStartIndex;
01008         for (; pos < mItemsInfo.size(); pos++)
01009         {
01010             // текущая кнопка не влазиет
01011             if (width > (mHeaderPlace->getWidth() - widthControls))
01012                 break;
01013 
01014             // следующая не влазиет
01015             TabItemInfo& info = mItemsInfo[pos];
01016             if ((width + info.width) > (mHeaderPlace->getWidth() - widthControls))
01017             {
01018                 break;
01019             }
01020 
01021             // проверяем физическое наличие кнопки
01022             if (count >= mItemButton.size())
01023                 _createItemButton();
01024 
01025             // если кнопка не соответствует, то изменяем ее
01026             Button* button = mItemButton[count];
01027             button->setVisible(true);
01028 
01029             // корректируем нажатость кнопки
01030             button->setStateSelected(pos == mIndexSelect);
01031 
01032             if (button->getCaption() != info.name)
01033                 button->setCaption(info.name);
01034             // положение кнопки
01035             IntCoord coord(width, 0, info.width, mHeaderPlace->getHeight());
01036             if (coord != button->getCoord())
01037                 button->setCoord(coord);
01038 
01039             width += info.width;
01040             count ++;
01041         }
01042 
01043         // скрываем кнопки что были созданны, но не видны
01044         while (count < mItemButton.size())
01045         {
01046             mItemButton[count]->setVisible(false);
01047             count ++;
01048         }
01049 
01050         bool right = true;
01051         if (pos == mItemsInfo.size())
01052             right = false;
01053 
01054         if (mEmpty != nullptr)
01055         {
01056             // корректируем виджет для пустоты
01057             mEmpty->setCoord(width, 0, mHeaderPlace->getWidth() - width - widthControls, mHeaderPlace->getHeight());
01058         }
01059 
01060         // корректируем доступность стрелок
01061         if (mStartIndex == 0)
01062         {
01063             if (nullptr != mButtonLeft)
01064                 mButtonLeft->setEnabled(false);
01065         }
01066         else
01067         {
01068             if (nullptr != mButtonLeft)
01069                 mButtonLeft->setEnabled(true);
01070         }
01071 
01072         if (right)
01073         {
01074             if (nullptr != mButtonRight)
01075                 mButtonRight->setEnabled(true);
01076         }
01077         else
01078         {
01079             if (nullptr != mButtonRight)
01080                 mButtonRight->setEnabled(false);
01081         }
01082     }
01083 
01084 } // namespace MyGUI