2019-11-23 20:27:39 +08:00
|
|
|
/****************************************************************************
|
|
|
|
Copyright (c) 2015-2016 Chukong Technologies Inc.
|
|
|
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
http://www.cocos2d-x.org
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
THE SOFTWARE.
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include "platform/CCFileUtils.h"
|
|
|
|
#include "2d/CCSprite.h"
|
|
|
|
#include "2d/CCLabel.h"
|
|
|
|
#include "ui/UILayout.h"
|
|
|
|
#include "ui/UITabControl.h"
|
|
|
|
|
|
|
|
NS_CC_BEGIN
|
|
|
|
|
|
|
|
namespace ui
|
|
|
|
{
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
TabControl::TabControl()
|
|
|
|
: _selectedItem(nullptr)
|
|
|
|
, _headerHeight(20)
|
|
|
|
, _headerWidth(50)
|
|
|
|
, _headerDockPlace(Dock::TOP)
|
|
|
|
, _containerPosition(Vec2::ZERO)
|
|
|
|
, _containerSize(Vec2::ZERO)
|
|
|
|
, _currentHeaderZoom(0.1f)
|
|
|
|
, _ignoreHeaderTextureSize(true)
|
|
|
|
{
|
|
|
|
this->_anchorPoint = Vec2(0.f, 0.f);
|
|
|
|
setContentSize(Vec2(200, 200));
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
TabControl::~TabControl()
|
|
|
|
{
|
|
|
|
for (auto& item : _tabItems)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
if (item)
|
|
|
|
CC_SAFE_DELETE(item);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
_tabItems.clear();
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void TabControl::insertTab(int index, TabHeader* header, Layout* container)
|
|
|
|
{
|
|
|
|
int cellSize = (int)_tabItems.size();
|
|
|
|
if (index > cellSize)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
CCLOG("%s", "insert index error");
|
|
|
|
return;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
addProtectedChild(container, -3, -1);
|
|
|
|
addProtectedChild(header, -2, -1);
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
_tabItems.insert(_tabItems.begin() + index, new TabItem(header, container));
|
|
|
|
header->_tabView = this;
|
|
|
|
header->_tabSelectedEvent =
|
|
|
|
CC_CALLBACK_2(TabControl::dispatchSelectedTabChanged, this); // binding tab selected event
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
initAfterInsert(index);
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void TabControl::initAfterInsert(int index)
|
|
|
|
{
|
|
|
|
auto cellSize = _tabItems.size();
|
|
|
|
auto tabItem = _tabItems.at(index);
|
|
|
|
auto headerCell = tabItem->header;
|
|
|
|
auto container = tabItem->container;
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
if (cellSize == 1)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
setSelectTab(0);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
else
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
deactiveTabItem(tabItem);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
headerCell->setContentSize(Vec2(_headerWidth, _headerHeight));
|
|
|
|
headerCell->setAnchorPoint(getHeaderAnchorWithDock());
|
|
|
|
if (headerCell->isIgnoreContentAdaptWithSize() == _ignoreHeaderTextureSize)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
headerCell->ignoreContentAdaptWithSize(!_ignoreHeaderTextureSize);
|
|
|
|
if (_ignoreHeaderTextureSize)
|
|
|
|
headerCell->setContentSize(Vec2(_headerWidth, _headerHeight));
|
|
|
|
headerCell->backGroundDisabledTextureScaleChangedWithSize();
|
|
|
|
headerCell->backGroundSelectedTextureScaleChangedWithSize();
|
|
|
|
headerCell->backGroundDisabledTextureScaleChangedWithSize();
|
|
|
|
headerCell->frontCrossTextureScaleChangedWithSize();
|
|
|
|
headerCell->frontCrossDisabledTextureScaleChangedWithSize();
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
initTabHeadersPos(index);
|
|
|
|
if (_containerSize.equals(Vec2::ZERO))
|
|
|
|
initContainers();
|
|
|
|
else
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
container->setPosition(_containerPosition);
|
|
|
|
container->setContentSize(_containerSize);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void TabControl::removeTab(int index)
|
|
|
|
{
|
|
|
|
int cellSize = (int)_tabItems.size();
|
|
|
|
if (cellSize == 0 || index >= cellSize)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
CCLOG("%s", "no tab or remove index error");
|
|
|
|
return;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
auto tabItem = _tabItems.at(index);
|
|
|
|
if (tabItem == _selectedItem)
|
|
|
|
_selectedItem = nullptr;
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
auto header = tabItem->header;
|
|
|
|
auto container = tabItem->container;
|
|
|
|
if (tabItem)
|
|
|
|
CC_SAFE_DELETE(tabItem);
|
|
|
|
_tabItems.erase(_tabItems.begin() + index);
|
|
|
|
|
|
|
|
if (header != nullptr)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
header->_tabSelectedEvent = nullptr;
|
|
|
|
header->_tabView = nullptr;
|
|
|
|
removeProtectedChild(header);
|
|
|
|
removeProtectedChild(container);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
initTabHeadersPos(index);
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
size_t TabControl::getTabCount() const
|
|
|
|
{
|
|
|
|
return _tabItems.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TabControl::setHeaderWidth(float headerWidth)
|
|
|
|
{
|
|
|
|
_headerWidth = headerWidth;
|
|
|
|
if (_headerDockPlace == Dock::TOP || _headerDockPlace == Dock::BOTTOM)
|
2019-11-23 20:27:39 +08:00
|
|
|
initTabHeadersPos(0);
|
2021-12-25 10:04:45 +08:00
|
|
|
if (_headerDockPlace == Dock::LEFT || _headerDockPlace == Dock::RIGHT)
|
2019-11-23 20:27:39 +08:00
|
|
|
initContainers();
|
2021-12-25 10:04:45 +08:00
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void TabControl::setHeaderHeight(float headerHeight)
|
|
|
|
{
|
|
|
|
_headerHeight = headerHeight;
|
|
|
|
if (_headerDockPlace == Dock::LEFT || _headerDockPlace == Dock::RIGHT)
|
|
|
|
initTabHeadersPos(0);
|
|
|
|
if (_headerDockPlace == Dock::TOP || _headerDockPlace == Dock::BOTTOM)
|
|
|
|
initContainers();
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void TabControl::setHeaderDockPlace(TabControl::Dock dockPlace)
|
|
|
|
{
|
|
|
|
if (_headerDockPlace != dockPlace)
|
|
|
|
{
|
|
|
|
_headerDockPlace = dockPlace;
|
|
|
|
initTabHeadersPos(0);
|
|
|
|
initContainers();
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
auto anpoint = getHeaderAnchorWithDock();
|
|
|
|
for (auto& item : _tabItems)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
item->header->setAnchorPoint(anpoint);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
cocos2d::Vec2 TabControl::getHeaderAnchorWithDock() const
|
|
|
|
{
|
|
|
|
Vec2 anpoint(.5f, .0f);
|
|
|
|
switch (_headerDockPlace)
|
|
|
|
{
|
|
|
|
case Dock::TOP:
|
|
|
|
break;
|
|
|
|
case Dock::LEFT:
|
|
|
|
anpoint.x = 1.f;
|
|
|
|
anpoint.y = .5f;
|
|
|
|
break;
|
|
|
|
case Dock::BOTTOM:
|
|
|
|
anpoint.x = .5f;
|
|
|
|
anpoint.y = 1.f;
|
|
|
|
break;
|
|
|
|
case Dock::RIGHT:
|
|
|
|
anpoint.x = 0.f;
|
|
|
|
anpoint.y = .5f;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return anpoint;
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void TabControl::onSizeChanged()
|
|
|
|
{
|
|
|
|
initTabHeadersPos(0);
|
|
|
|
initContainers();
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void TabControl::initTabHeadersPos(int startIndex)
|
|
|
|
{
|
|
|
|
int cellSize = (int)_tabItems.size();
|
|
|
|
if (startIndex >= cellSize)
|
|
|
|
return;
|
|
|
|
|
|
|
|
float originX = _headerWidth * .5f;
|
|
|
|
float originY = _contentSize.height - _headerHeight;
|
|
|
|
Vec2 deltaPos(0.f, 0.f);
|
|
|
|
switch (_headerDockPlace)
|
|
|
|
{
|
|
|
|
case Dock::TOP:
|
|
|
|
deltaPos.x = _headerWidth;
|
|
|
|
break;
|
|
|
|
case Dock::LEFT:
|
|
|
|
originX = _headerWidth;
|
|
|
|
originY = _contentSize.height - _headerHeight * .5f;
|
|
|
|
deltaPos.y = 0 - _headerHeight;
|
|
|
|
break;
|
|
|
|
case Dock::BOTTOM:
|
|
|
|
originY = _headerHeight;
|
|
|
|
deltaPos.x = _headerWidth;
|
|
|
|
break;
|
|
|
|
case Dock::RIGHT:
|
|
|
|
originX = _contentSize.width - _headerWidth;
|
|
|
|
originY = _contentSize.height - _headerHeight * .5f;
|
|
|
|
deltaPos.y = 0 - _headerHeight;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int cellI = startIndex; cellI < cellSize; cellI++)
|
|
|
|
{
|
|
|
|
auto headerCell = _tabItems.at(cellI)->header;
|
|
|
|
headerCell->setPosition(Vec2(originX + cellI * deltaPos.x, originY + cellI * deltaPos.y));
|
|
|
|
}
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void TabControl::initContainers()
|
|
|
|
{
|
|
|
|
switch (_headerDockPlace)
|
|
|
|
{
|
|
|
|
case Dock::TOP:
|
|
|
|
_containerPosition = Vec2(0, 0);
|
|
|
|
_containerSize = Vec2(_contentSize.width, _contentSize.height - _headerHeight);
|
|
|
|
break;
|
|
|
|
case Dock::LEFT:
|
|
|
|
_containerPosition = Vec2(_headerWidth, 0);
|
|
|
|
_containerSize = Vec2(_contentSize.width - _headerWidth, _contentSize.height);
|
|
|
|
break;
|
|
|
|
case Dock::BOTTOM:
|
|
|
|
_containerPosition = Vec2(0, _headerHeight);
|
|
|
|
_containerSize = Vec2(_contentSize.width, _contentSize.height - _headerHeight);
|
|
|
|
break;
|
|
|
|
case Dock::RIGHT:
|
|
|
|
_containerPosition = Vec2(0, 0);
|
|
|
|
_containerSize = Vec2(_contentSize.width - _headerWidth, _contentSize.height);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (auto& tabItem : _tabItems)
|
|
|
|
{
|
|
|
|
Layout* container = tabItem->container;
|
|
|
|
container->setPosition(_containerPosition);
|
|
|
|
container->setContentSize(_containerSize);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
TabHeader* TabControl::getTabHeader(int index) const
|
|
|
|
{
|
|
|
|
if (index >= (int)getTabCount())
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
return _tabItems.at(index)->header;
|
|
|
|
}
|
|
|
|
|
|
|
|
Layout* TabControl::getTabContainer(int index) const
|
|
|
|
{
|
|
|
|
if (index >= (int)getTabCount())
|
|
|
|
return nullptr;
|
|
|
|
return _tabItems.at(index)->container;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TabControl::dispatchSelectedTabChanged(int tabIndex, TabHeader::EventType eventType)
|
|
|
|
{
|
|
|
|
if (eventType == TabHeader::EventType::SELECTED)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
if (tabIndex <= -1 || tabIndex >= (int)_tabItems.size())
|
|
|
|
{
|
|
|
|
deactiveTabItem(_selectedItem);
|
|
|
|
_selectedItem = nullptr;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
deactiveTabItem(_selectedItem);
|
|
|
|
auto tabItem = _tabItems.at(tabIndex);
|
|
|
|
activeTabItem(tabItem);
|
|
|
|
_selectedItem = tabItem;
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
else if (eventType == TabHeader::EventType::UNSELECTED)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
if (tabIndex >= 0 && tabIndex < (int)_tabItems.size())
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
auto tabItem = _tabItems.at(tabIndex);
|
|
|
|
if (tabItem == _selectedItem)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
deactiveTabItem(_selectedItem);
|
|
|
|
_selectedItem = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
if (_tabChangedCallback != nullptr)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
int currentIndex = getSelectedTabIndex();
|
|
|
|
_tabChangedCallback(currentIndex, EventType::SELECT_CHANGED);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void TabControl::setTabChangedEventListener(const ccTabControlCallback& callback)
|
|
|
|
{
|
|
|
|
_tabChangedCallback = callback;
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
int TabControl::indexOfTabHeader(const TabHeader* tabCell) const
|
|
|
|
{
|
|
|
|
int n = (int)_tabItems.size();
|
|
|
|
for (auto i = 0; i < n; i++)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
if (tabCell == _tabItems.at(i)->header)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
return i;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
return -1;
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
TabControl* TabControl::create()
|
|
|
|
{
|
|
|
|
TabControl* tabview = new TabControl();
|
|
|
|
if (tabview->init())
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
tabview->autorelease();
|
|
|
|
return tabview;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
CC_SAFE_DELETE(tabview);
|
|
|
|
return nullptr;
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void TabControl::setSelectTab(int index)
|
|
|
|
{
|
|
|
|
dispatchSelectedTabChanged(index, TabHeader::EventType::SELECTED);
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void TabControl::setSelectTab(TabHeader* tabHeader)
|
|
|
|
{
|
|
|
|
if (_selectedItem != nullptr && tabHeader == _selectedItem->header)
|
|
|
|
return;
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
setSelectTab(indexOfTabHeader(tabHeader));
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void TabControl::setHeaderSelectedZoom(float zoom)
|
|
|
|
{
|
|
|
|
if (_currentHeaderZoom != zoom)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
_currentHeaderZoom = zoom;
|
|
|
|
if (_selectedItem != nullptr)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
auto currentHeader = _selectedItem->header;
|
|
|
|
currentHeader->setScale(1.0f + _currentHeaderZoom);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void TabControl::activeTabItem(TabItem* item)
|
|
|
|
{
|
|
|
|
if (item != nullptr)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
item->header->setLocalZOrder(-1);
|
|
|
|
item->header->setScale(1.0f + _currentHeaderZoom);
|
|
|
|
item->header->setSelected(true);
|
|
|
|
item->container->setVisible(true);
|
|
|
|
_reorderProtectedChildDirty = true;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void TabControl::deactiveTabItem(TabItem* item)
|
|
|
|
{
|
|
|
|
if (item != nullptr)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
item->header->setLocalZOrder(-2);
|
|
|
|
item->header->setScale(1.0f);
|
|
|
|
item->header->setSelected(false);
|
|
|
|
item->container->setVisible(false);
|
|
|
|
_reorderProtectedChildDirty = true;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void TabControl::copySpecialProperties(Widget* model)
|
|
|
|
{
|
|
|
|
auto srcTab = dynamic_cast<TabControl*>(model);
|
|
|
|
if (srcTab != nullptr)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
Widget::copySpecialProperties(srcTab);
|
|
|
|
_headerWidth = srcTab->_headerWidth;
|
|
|
|
_headerHeight = srcTab->_headerHeight;
|
|
|
|
_headerDockPlace = srcTab->_headerDockPlace;
|
|
|
|
_currentHeaderZoom = srcTab->_currentHeaderZoom;
|
|
|
|
_tabChangedCallback = srcTab->_tabChangedCallback;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void TabControl::ignoreHeadersTextureSize(bool ignore)
|
|
|
|
{
|
|
|
|
if (_ignoreHeaderTextureSize == ignore)
|
|
|
|
return;
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
_ignoreHeaderTextureSize = ignore;
|
|
|
|
for (auto& item : _tabItems)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
item->header->ignoreContentAdaptWithSize(!ignore);
|
|
|
|
if (ignore)
|
|
|
|
item->header->setContentSize(Vec2(_headerWidth, _headerHeight));
|
|
|
|
item->header->backGroundDisabledTextureScaleChangedWithSize();
|
|
|
|
item->header->backGroundSelectedTextureScaleChangedWithSize();
|
|
|
|
item->header->backGroundDisabledTextureScaleChangedWithSize();
|
|
|
|
item->header->frontCrossTextureScaleChangedWithSize();
|
|
|
|
item->header->frontCrossDisabledTextureScaleChangedWithSize();
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int TabControl::getSelectedTabIndex() const
|
|
|
|
{
|
|
|
|
return _selectedItem == nullptr ? -1 : indexOfTabHeader(_selectedItem->header);
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
TabHeader::TabHeader()
|
|
|
|
: _tabLabelRender(nullptr)
|
|
|
|
, _tabLabelFontSize(12)
|
|
|
|
, _tabView(nullptr)
|
|
|
|
, _tabSelectedEvent(nullptr)
|
|
|
|
, _fontType(FontType::SYSTEM)
|
|
|
|
{}
|
|
|
|
|
|
|
|
TabHeader::~TabHeader()
|
|
|
|
{
|
|
|
|
_tabLabelRender = nullptr;
|
|
|
|
_tabView = nullptr;
|
|
|
|
_tabSelectedEvent = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
TabHeader* TabHeader::create()
|
|
|
|
{
|
|
|
|
TabHeader* tabcell = new TabHeader();
|
|
|
|
if (tabcell->init())
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
tabcell->_frontCrossRenderer->setVisible(false); // _isSelected == false
|
|
|
|
tabcell->_anchorPoint = Vec2(.5f, 0.0f);
|
|
|
|
tabcell->autorelease();
|
|
|
|
return tabcell;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
CC_SAFE_DELETE(tabcell);
|
|
|
|
return nullptr;
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-26 23:26:34 +08:00
|
|
|
TabHeader* TabHeader::create(std::string_view titleStr,
|
|
|
|
std::string_view backGround,
|
|
|
|
std::string_view cross,
|
2021-12-25 10:04:45 +08:00
|
|
|
TextureResType texType)
|
|
|
|
{
|
|
|
|
TabHeader* tabcell = new TabHeader;
|
|
|
|
if (tabcell->init(backGround, "", cross, "", "", texType))
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
tabcell->_frontCrossRenderer->setVisible(false);
|
|
|
|
tabcell->_tabLabelRender->setString(titleStr);
|
|
|
|
tabcell->_anchorPoint = Vec2(.5f, 0.0f);
|
|
|
|
tabcell->autorelease();
|
|
|
|
return tabcell;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
CC_SAFE_DELETE(tabcell);
|
|
|
|
return nullptr;
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-26 23:26:34 +08:00
|
|
|
TabHeader* TabHeader::create(std::string_view titleStr,
|
|
|
|
std::string_view backGround,
|
|
|
|
std::string_view backGroundSelected,
|
|
|
|
std::string_view cross,
|
|
|
|
std::string_view backGroundDisabled,
|
|
|
|
std::string_view frontCrossDisabled,
|
2021-12-25 10:04:45 +08:00
|
|
|
TextureResType texType /*= TextureResType::LOCAL*/)
|
|
|
|
{
|
|
|
|
TabHeader* tabcell = new TabHeader;
|
|
|
|
if (tabcell->init(backGround, backGroundSelected, cross, backGroundDisabled, frontCrossDisabled, texType))
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
tabcell->_frontCrossRenderer->setVisible(false);
|
|
|
|
tabcell->_tabLabelRender->setString(titleStr);
|
|
|
|
tabcell->_anchorPoint = Vec2(.5f, 0.0f);
|
|
|
|
tabcell->autorelease();
|
|
|
|
return tabcell;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
CC_SAFE_DELETE(tabcell);
|
|
|
|
return nullptr;
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void TabHeader::initRenderer()
|
|
|
|
{
|
|
|
|
_backGroundBoxRenderer = Sprite::create();
|
|
|
|
_backGroundSelectedBoxRenderer = Sprite::create();
|
|
|
|
_frontCrossRenderer = Sprite::create();
|
|
|
|
_backGroundBoxDisabledRenderer = Sprite::create();
|
|
|
|
_frontCrossDisabledRenderer = Sprite::create();
|
|
|
|
_tabLabelRender = Label::create();
|
|
|
|
|
|
|
|
addProtectedChild(_backGroundBoxRenderer, -2, -1);
|
|
|
|
addProtectedChild(_backGroundSelectedBoxRenderer, -2, -1);
|
|
|
|
addProtectedChild(_frontCrossRenderer, -2, -1);
|
|
|
|
addProtectedChild(_backGroundBoxDisabledRenderer, -2, -1);
|
|
|
|
addProtectedChild(_frontCrossDisabledRenderer, -2, -1);
|
|
|
|
addProtectedChild(_tabLabelRender, -1, -1);
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-26 23:26:34 +08:00
|
|
|
void TabHeader::setTitleText(std::string_view text)
|
2021-12-25 10:04:45 +08:00
|
|
|
{
|
|
|
|
if (text == getTitleText())
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
return;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
_tabLabelRender->setString(text);
|
|
|
|
updateContentSize();
|
|
|
|
_tabLabelRender->setPosition(_contentSize * 0.5f);
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-26 23:26:34 +08:00
|
|
|
std::string_view TabHeader::getTitleText() const
|
2021-12-25 10:04:45 +08:00
|
|
|
{
|
|
|
|
if (nullptr == _tabLabelRender)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-26 23:26:34 +08:00
|
|
|
return ""sv;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
return _tabLabelRender->getString();
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void TabHeader::setTitleColor(const Color4B& color)
|
|
|
|
{
|
|
|
|
_tabLabelRender->setTextColor(color);
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
const Color4B& TabHeader::getTitleColor() const
|
|
|
|
{
|
|
|
|
if (nullptr == _tabLabelRender)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
return Color4B::WHITE;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
return _tabLabelRender->getTextColor();
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void TabHeader::setTitleFontSize(float size)
|
|
|
|
{
|
|
|
|
_tabLabelFontSize = size;
|
|
|
|
if (_fontType == FontType::SYSTEM)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
_tabLabelRender->setSystemFontSize(_tabLabelFontSize);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
else if (_fontType == FontType::TTF)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
TTFConfig config = _tabLabelRender->getTTFConfig();
|
|
|
|
config.fontSize = _tabLabelFontSize;
|
|
|
|
_tabLabelRender->setTTFConfig(config);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
// we can't change font size of BMFont.
|
|
|
|
if (FontType::BMFONT != _fontType)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
updateContentSize();
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
float TabHeader::getTitleFontSize() const
|
|
|
|
{
|
|
|
|
return _tabLabelFontSize;
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void TabHeader::updateContentSize()
|
|
|
|
{
|
|
|
|
ProtectedNode::setContentSize(_customSize);
|
|
|
|
onSizeChanged();
|
|
|
|
}
|
|
|
|
|
2021-12-26 23:26:34 +08:00
|
|
|
void TabHeader::setTitleFontName(std::string_view fontName)
|
2021-12-25 10:04:45 +08:00
|
|
|
{
|
|
|
|
if (FileUtils::getInstance()->isFileExist(fontName))
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-26 23:26:34 +08:00
|
|
|
std::string lowerCasedFontName{fontName};
|
2021-12-25 10:04:45 +08:00
|
|
|
std::transform(lowerCasedFontName.begin(), lowerCasedFontName.end(), lowerCasedFontName.begin(), ::tolower);
|
|
|
|
if (lowerCasedFontName.find(".fnt") != std::string::npos)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
_tabLabelRender->setBMFontFilePath(fontName);
|
|
|
|
_fontType = FontType::BMFONT;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
TTFConfig config = _tabLabelRender->getTTFConfig();
|
|
|
|
config.fontFilePath = fontName;
|
|
|
|
config.fontSize = _tabLabelFontSize;
|
|
|
|
_tabLabelRender->setTTFConfig(config);
|
|
|
|
_fontType = FontType::TTF;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
else
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
_tabLabelRender->setSystemFontName(fontName);
|
|
|
|
if (_fontType == FontType::TTF)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
_tabLabelRender->requestSystemFontRefresh();
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
_tabLabelRender->setSystemFontSize(_tabLabelFontSize);
|
|
|
|
_fontType = FontType::SYSTEM;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
this->updateContentSize();
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
Label* TabHeader::getTitleRenderer() const
|
|
|
|
{
|
|
|
|
return _tabLabelRender;
|
|
|
|
}
|
|
|
|
|
2021-12-26 23:26:34 +08:00
|
|
|
std::string_view TabHeader::getTitleFontName() const
|
2021-12-25 10:04:45 +08:00
|
|
|
{
|
|
|
|
if (this->_fontType == FontType::SYSTEM)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
return _tabLabelRender->getSystemFontName();
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
else if (this->_fontType == FontType::TTF)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
return _tabLabelRender->getTTFConfig().fontFilePath;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
else
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
return _tabLabelRender->getBMFontFilePath();
|
|
|
|
}
|
2021-12-26 23:26:34 +08:00
|
|
|
return ""sv;
|
2021-12-25 10:04:45 +08:00
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void TabHeader::onSizeChanged()
|
|
|
|
{
|
|
|
|
AbstractCheckButton::onSizeChanged();
|
|
|
|
_tabLabelRender->setPosition(_contentSize * 0.5f);
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void TabHeader::releaseUpEvent()
|
|
|
|
{
|
|
|
|
Widget::releaseUpEvent();
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
if (!_isSelected)
|
|
|
|
{
|
|
|
|
setSelected(true);
|
|
|
|
dispatchSelectChangedEvent(true);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void TabHeader::dispatchSelectChangedEvent(bool select)
|
|
|
|
{
|
|
|
|
if (_tabView == nullptr)
|
|
|
|
return;
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
EventType eventType = (select ? EventType::SELECTED : EventType::UNSELECTED);
|
|
|
|
|
|
|
|
if (_tabSelectedEvent != nullptr)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
int index = _tabView->indexOfTabHeader(this);
|
|
|
|
if (index != -1)
|
|
|
|
_tabSelectedEvent(index, eventType);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
if (_ccEventCallback != nullptr)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
_ccEventCallback(this, static_cast<int>(eventType));
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
int TabHeader::getIndexInTabControl() const
|
|
|
|
{
|
|
|
|
if (_tabView == nullptr)
|
|
|
|
return -1;
|
|
|
|
return _tabView->indexOfTabHeader(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TabHeader::copySpecialProperties(Widget* model)
|
|
|
|
{
|
|
|
|
auto header = dynamic_cast<TabHeader*>(model);
|
|
|
|
if (header != nullptr)
|
|
|
|
{
|
|
|
|
AbstractCheckButton::copySpecialProperties(model);
|
|
|
|
_fontType = header->_fontType;
|
|
|
|
_tabLabelFontSize = header->_tabLabelFontSize;
|
|
|
|
_tabSelectedEvent = header->_tabSelectedEvent;
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
|
|
|
} // namespace ui
|
2019-11-23 20:27:39 +08:00
|
|
|
NS_CC_END
|