2020-10-18 12:31:45 +08:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2012 cocos2d-x.org
|
|
|
|
* http://www.cocos2d-x.org
|
|
|
|
*
|
|
|
|
* Copyright 2011 Yannick Loriot.
|
|
|
|
* http://yannickloriot.com
|
2021-12-25 10:04:45 +08:00
|
|
|
*
|
2020-10-18 12:31:45 +08:00
|
|
|
* Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
2021-12-25 10:04:45 +08:00
|
|
|
*
|
2020-10-18 12:31:45 +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
|
|
|
*
|
2020-10-18 12:31:45 +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
|
|
|
*
|
2020-10-18 12:31:45 +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 "CCControlButton.h"
|
|
|
|
#include "2d/CCLabel.h"
|
|
|
|
#include "2d/CCAction.h"
|
|
|
|
#include "2d/CCActionInterval.h"
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
NS_CC_EXT_BEGIN
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
kZoomActionTag = 0xCCCB0001,
|
|
|
|
};
|
|
|
|
|
|
|
|
ControlButton::ControlButton()
|
2021-12-25 10:04:45 +08:00
|
|
|
: _isPushed(false)
|
|
|
|
, _parentInited(false)
|
|
|
|
, _doesAdjustBackgroundImage(false)
|
|
|
|
, _currentTitleColor(Color3B::WHITE)
|
|
|
|
, _titleLabel(nullptr)
|
|
|
|
, _backgroundSprite(nullptr)
|
|
|
|
, _zoomOnTouchDown(false)
|
|
|
|
, _marginV(ControlButtonMarginTB)
|
|
|
|
, _marginH(ControlButtonMarginLR)
|
|
|
|
{}
|
2020-10-18 12:31:45 +08:00
|
|
|
|
|
|
|
ControlButton::~ControlButton()
|
|
|
|
{
|
|
|
|
CC_SAFE_RELEASE(_titleLabel);
|
|
|
|
CC_SAFE_RELEASE(_backgroundSprite);
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
// initialisers
|
2020-10-18 12:31:45 +08:00
|
|
|
|
|
|
|
bool ControlButton::init()
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
return this->initWithLabelAndBackgroundSprite(Label::createWithSystemFont("", "Helvetica", 12),
|
|
|
|
cocos2d::ui::Scale9Sprite::create(), true);
|
2020-10-18 12:31:45 +08:00
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
bool ControlButton::initWithLabelAndBackgroundSprite(Node* node,
|
|
|
|
ui::Scale9Sprite* backgroundSprite,
|
|
|
|
bool adjustBackGroundSize)
|
2020-10-18 12:31:45 +08:00
|
|
|
{
|
|
|
|
if (Control::init())
|
|
|
|
{
|
|
|
|
CCASSERT(node != nullptr, "node must not be nil.");
|
|
|
|
LabelProtocol* label = dynamic_cast<LabelProtocol*>(node);
|
|
|
|
CCASSERT(backgroundSprite != nullptr, "Background sprite must not be nil.");
|
|
|
|
CCASSERT(label != nullptr, "label must not be nil.");
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2020-10-18 12:31:45 +08:00
|
|
|
_parentInited = true;
|
|
|
|
|
|
|
|
_isPushed = false;
|
|
|
|
|
|
|
|
// Adjust the background image by adjustBackGroundSize
|
|
|
|
setPreferredSize(Size::ZERO);
|
|
|
|
setAdjustBackgroundImage(adjustBackGroundSize);
|
|
|
|
// Zooming button by default
|
|
|
|
_zoomOnTouchDown = true;
|
2021-12-25 10:04:45 +08:00
|
|
|
_scaleRatio = 1.1f;
|
|
|
|
|
2020-10-18 12:31:45 +08:00
|
|
|
// Set the default anchor point
|
|
|
|
setIgnoreAnchorPointForPosition(false);
|
|
|
|
setAnchorPoint(Vec2::ANCHOR_MIDDLE);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2020-10-18 12:31:45 +08:00
|
|
|
// Set the nodes
|
|
|
|
setTitleLabel(node);
|
|
|
|
setBackgroundSprite(backgroundSprite);
|
|
|
|
|
|
|
|
// Set the default color and opacity
|
|
|
|
setColor(Color3B::WHITE);
|
|
|
|
setOpacity(255.0f);
|
|
|
|
setOpacityModifyRGB(true);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2020-10-18 12:31:45 +08:00
|
|
|
// Initialize the dispatch table
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2020-10-18 12:31:45 +08:00
|
|
|
setTitleForState(label->getString(), Control::State::NORMAL);
|
|
|
|
setTitleColorForState(node->getColor(), Control::State::NORMAL);
|
|
|
|
setTitleLabelForState(node, Control::State::NORMAL);
|
|
|
|
setBackgroundSpriteForState(backgroundSprite, Control::State::NORMAL);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2020-10-18 12:31:45 +08:00
|
|
|
setLabelAnchorPoint(Vec2::ANCHOR_MIDDLE);
|
|
|
|
|
|
|
|
// Layout update
|
|
|
|
needsLayout();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
// couldn't init the Control
|
2020-10-18 12:31:45 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ControlButton* ControlButton::create(Node* label, cocos2d::ui::Scale9Sprite* backgroundSprite)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
ControlButton* pRet = new ControlButton();
|
2020-10-18 12:31:45 +08:00
|
|
|
pRet->initWithLabelAndBackgroundSprite(label, backgroundSprite, true);
|
|
|
|
pRet->autorelease();
|
|
|
|
return pRet;
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
ControlButton* ControlButton::create(Node* label,
|
|
|
|
cocos2d::ui::Scale9Sprite* backgroundSprite,
|
|
|
|
bool adjustBackGroundSize)
|
2020-10-18 12:31:45 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
ControlButton* pRet = new ControlButton();
|
2020-10-18 12:31:45 +08:00
|
|
|
pRet->initWithLabelAndBackgroundSprite(label, backgroundSprite, adjustBackGroundSize);
|
|
|
|
pRet->autorelease();
|
|
|
|
return pRet;
|
|
|
|
}
|
|
|
|
|
2021-12-28 21:00:45 +08:00
|
|
|
bool ControlButton::initWithTitleAndFontNameAndFontSize(const std::string& title,
|
|
|
|
const std::string& fontName,
|
2021-12-25 10:04:45 +08:00
|
|
|
float fontSize)
|
2020-10-18 12:31:45 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
return initWithLabelAndBackgroundSprite(Label::createWithSystemFont(title, fontName, fontSize),
|
|
|
|
cocos2d::ui::Scale9Sprite::create(), true);
|
2020-10-18 12:31:45 +08:00
|
|
|
}
|
|
|
|
|
2021-12-28 21:00:45 +08:00
|
|
|
ControlButton* ControlButton::create(const std::string& title, const std::string& fontName, float fontSize)
|
2020-10-18 12:31:45 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
ControlButton* pRet = new ControlButton();
|
2020-10-18 12:31:45 +08:00
|
|
|
pRet->initWithTitleAndFontNameAndFontSize(title, fontName, fontSize);
|
|
|
|
pRet->autorelease();
|
|
|
|
return pRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ControlButton::initWithBackgroundSprite(cocos2d::ui::Scale9Sprite* sprite)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
Label* label = Label::createWithSystemFont("", "Arial", 30); //
|
|
|
|
return initWithLabelAndBackgroundSprite(label, sprite, false);
|
2020-10-18 12:31:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
ControlButton* ControlButton::create(cocos2d::ui::Scale9Sprite* sprite)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
ControlButton* pRet = new ControlButton();
|
2020-10-18 12:31:45 +08:00
|
|
|
pRet->initWithBackgroundSprite(sprite);
|
|
|
|
pRet->autorelease();
|
|
|
|
return pRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ControlButton::setMargins(int marginH, int marginV)
|
|
|
|
{
|
|
|
|
_marginV = marginV;
|
|
|
|
_marginH = marginH;
|
|
|
|
needsLayout();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ControlButton::setEnabled(bool enabled)
|
|
|
|
{
|
|
|
|
Control::setEnabled(enabled);
|
|
|
|
needsLayout();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ControlButton::setSelected(bool enabled)
|
|
|
|
{
|
|
|
|
Control::setSelected(enabled);
|
|
|
|
needsLayout();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ControlButton::setHighlighted(bool enabled)
|
|
|
|
{
|
|
|
|
if (enabled == true)
|
|
|
|
{
|
|
|
|
_state = Control::State::HIGH_LIGHTED;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_state = Control::State::NORMAL;
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2020-10-18 12:31:45 +08:00
|
|
|
Control::setHighlighted(enabled);
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
Action* action = getActionByTag(kZoomActionTag);
|
2020-10-18 12:31:45 +08:00
|
|
|
if (action)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
stopAction(action);
|
2020-10-18 12:31:45 +08:00
|
|
|
}
|
|
|
|
needsLayout();
|
2021-12-25 10:04:45 +08:00
|
|
|
if (_zoomOnTouchDown)
|
2020-10-18 12:31:45 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
float scaleValue = (isHighlighted() && isEnabled() && !isSelected()) ? _scaleRatio : 1.0f;
|
|
|
|
Action* zoomAction = ScaleTo::create(0.05f, scaleValue);
|
2020-10-18 12:31:45 +08:00
|
|
|
zoomAction->setTag(kZoomActionTag);
|
|
|
|
runAction(zoomAction);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ControlButton::setZoomOnTouchDown(bool zoomOnTouchDown)
|
|
|
|
{
|
|
|
|
_zoomOnTouchDown = zoomOnTouchDown;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ControlButton::getZoomOnTouchDown() const
|
|
|
|
{
|
|
|
|
return _zoomOnTouchDown;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ControlButton::setPreferredSize(const Size& size)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
if (size.width == 0 && size.height == 0)
|
2020-10-18 12:31:45 +08:00
|
|
|
{
|
|
|
|
_doesAdjustBackgroundImage = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_doesAdjustBackgroundImage = false;
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2020-10-18 12:31:45 +08:00
|
|
|
for (auto iter = _backgroundSpriteDispatchTable.begin(); iter != _backgroundSpriteDispatchTable.end(); ++iter)
|
|
|
|
{
|
|
|
|
iter->second->setPreferredSize(size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_preferredSize = size;
|
|
|
|
needsLayout();
|
|
|
|
}
|
|
|
|
|
|
|
|
const Size& ControlButton::getPreferredSize() const
|
|
|
|
{
|
|
|
|
return _preferredSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ControlButton::setAdjustBackgroundImage(bool adjustBackgroundImage)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
_doesAdjustBackgroundImage = adjustBackgroundImage;
|
2020-10-18 12:31:45 +08:00
|
|
|
needsLayout();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ControlButton::doesAdjustBackgroundImage()
|
|
|
|
{
|
|
|
|
return _doesAdjustBackgroundImage;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Vec2& ControlButton::getLabelAnchorPoint() const
|
|
|
|
{
|
|
|
|
return this->_labelAnchorPoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ControlButton::setLabelAnchorPoint(const Vec2& labelAnchorPoint)
|
|
|
|
{
|
|
|
|
this->_labelAnchorPoint = labelAnchorPoint;
|
|
|
|
if (_titleLabel != nullptr)
|
|
|
|
{
|
|
|
|
this->_titleLabel->setAnchorPoint(labelAnchorPoint);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string ControlButton::getTitleForState(State state)
|
|
|
|
{
|
|
|
|
auto iter = _titleDispatchTable.find((int)state);
|
|
|
|
if (iter != _titleDispatchTable.end())
|
|
|
|
{
|
|
|
|
return iter->second;
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2020-10-18 12:31:45 +08:00
|
|
|
iter = _titleDispatchTable.find((int)Control::State::NORMAL);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2020-10-18 12:31:45 +08:00
|
|
|
return iter != _titleDispatchTable.end() ? iter->second : "";
|
|
|
|
}
|
|
|
|
|
2021-12-28 21:00:45 +08:00
|
|
|
void ControlButton::setTitleForState(const std::string& title, State state)
|
2020-10-18 12:31:45 +08:00
|
|
|
{
|
|
|
|
_titleDispatchTable.erase((int)state);
|
|
|
|
|
|
|
|
if (!title.empty())
|
|
|
|
{
|
|
|
|
_titleDispatchTable[(int)state] = title;
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2020-10-18 12:31:45 +08:00
|
|
|
// If the current state if equal to the given state we update the layout
|
|
|
|
if (getState() == state)
|
|
|
|
{
|
|
|
|
needsLayout();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Color3B ControlButton::getTitleColorForState(State state) const
|
|
|
|
{
|
|
|
|
Color3B returnColor = Color3B::WHITE;
|
|
|
|
|
|
|
|
auto iter = _titleColorDispatchTable.find((int)state);
|
|
|
|
if (iter != _titleColorDispatchTable.end())
|
|
|
|
{
|
|
|
|
returnColor = iter->second;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
iter = _titleColorDispatchTable.find((int)Control::State::NORMAL);
|
|
|
|
if (iter != _titleColorDispatchTable.end())
|
|
|
|
{
|
|
|
|
returnColor = iter->second;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return returnColor;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ControlButton::setTitleColorForState(const Color3B& color, State state)
|
|
|
|
{
|
|
|
|
_titleColorDispatchTable.erase((int)state);
|
|
|
|
_titleColorDispatchTable[(int)state] = color;
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2020-10-18 12:31:45 +08:00
|
|
|
// If the current state if equal to the given state we update the layout
|
|
|
|
if (getState() == state)
|
|
|
|
{
|
|
|
|
needsLayout();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Node* ControlButton::getTitleLabelForState(State state)
|
|
|
|
{
|
|
|
|
Node* titleLabel = _titleLabelDispatchTable.at((int)state);
|
|
|
|
if (titleLabel)
|
|
|
|
{
|
|
|
|
return titleLabel;
|
|
|
|
}
|
|
|
|
return _titleLabelDispatchTable.at((int)Control::State::NORMAL);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ControlButton::setTitleLabelForState(Node* titleLabel, State state)
|
|
|
|
{
|
|
|
|
Node* previousLabel = _titleLabelDispatchTable.at((int)state);
|
|
|
|
if (previousLabel)
|
|
|
|
{
|
|
|
|
removeChild(previousLabel, true);
|
|
|
|
_titleLabelDispatchTable.erase((int)state);
|
|
|
|
}
|
|
|
|
|
|
|
|
_titleLabelDispatchTable.insert((int)state, titleLabel);
|
|
|
|
titleLabel->setVisible(false);
|
|
|
|
titleLabel->setAnchorPoint(Vec2(0.5f, 0.5f));
|
|
|
|
addChild(titleLabel, 1);
|
|
|
|
|
|
|
|
// If the current state if equal to the given state we update the layout
|
|
|
|
if (getState() == state)
|
|
|
|
{
|
|
|
|
needsLayout();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-28 21:00:45 +08:00
|
|
|
void ControlButton::setTitleTTFForState(const std::string& fontName, State state)
|
2020-10-18 12:31:45 +08:00
|
|
|
{
|
|
|
|
this->setTitleLabelForState(Label::createWithSystemFont(getTitleForState(state), fontName, 12), state);
|
|
|
|
}
|
|
|
|
|
2021-12-28 21:00:45 +08:00
|
|
|
const std::string& ControlButton::getTitleTTFForState(State state)
|
2020-10-18 12:31:45 +08:00
|
|
|
{
|
|
|
|
LabelProtocol* label = dynamic_cast<LabelProtocol*>(this->getTitleLabelForState(state));
|
2021-12-25 10:04:45 +08:00
|
|
|
Label* labelTTF = dynamic_cast<Label*>(label);
|
|
|
|
if (labelTTF != 0)
|
2020-10-18 12:31:45 +08:00
|
|
|
{
|
|
|
|
return labelTTF->getSystemFontName();
|
|
|
|
}
|
|
|
|
|
|
|
|
static std::string ret("");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ControlButton::setTitleTTFSizeForState(float size, State state)
|
|
|
|
{
|
|
|
|
LabelProtocol* label = dynamic_cast<LabelProtocol*>(this->getTitleLabelForState(state));
|
2021-12-25 10:04:45 +08:00
|
|
|
if (label)
|
2020-10-18 12:31:45 +08:00
|
|
|
{
|
|
|
|
Label* labelTTF = dynamic_cast<Label*>(label);
|
2021-12-25 10:04:45 +08:00
|
|
|
if (labelTTF != 0)
|
2020-10-18 12:31:45 +08:00
|
|
|
{
|
|
|
|
return labelTTF->setSystemFontSize(size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
float ControlButton::getTitleTTFSizeForState(State state)
|
|
|
|
{
|
|
|
|
LabelProtocol* label = dynamic_cast<LabelProtocol*>(this->getTitleLabelForState(state));
|
2021-12-25 10:04:45 +08:00
|
|
|
Label* labelTTF = dynamic_cast<Label*>(label);
|
|
|
|
if (labelTTF != 0)
|
2020-10-18 12:31:45 +08:00
|
|
|
{
|
|
|
|
return labelTTF->getSystemFontSize();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-28 21:00:45 +08:00
|
|
|
void ControlButton::setTitleBMFontForState(const std::string& fntFile, State state)
|
2020-10-18 12:31:45 +08:00
|
|
|
{
|
|
|
|
std::string title = this->getTitleForState(state);
|
|
|
|
this->setTitleLabelForState(Label::createWithBMFont(fntFile, title), state);
|
|
|
|
}
|
|
|
|
|
2021-12-28 21:00:45 +08:00
|
|
|
const std::string& ControlButton::getTitleBMFontForState(State state)
|
2020-10-18 12:31:45 +08:00
|
|
|
{
|
|
|
|
LabelProtocol* label = dynamic_cast<LabelProtocol*>(this->getTitleLabelForState(state));
|
2021-12-25 10:04:45 +08:00
|
|
|
auto labelBMFont = dynamic_cast<Label*>(label);
|
|
|
|
if (labelBMFont != 0)
|
2020-10-18 12:31:45 +08:00
|
|
|
{
|
|
|
|
return labelBMFont->getBMFontFilePath();
|
|
|
|
}
|
|
|
|
|
|
|
|
static std::string ret("");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
ui::Scale9Sprite* ControlButton::getBackgroundSpriteForState(State state)
|
|
|
|
{
|
|
|
|
auto backgroundSprite = _backgroundSpriteDispatchTable.at((int)state);
|
|
|
|
if (backgroundSprite)
|
|
|
|
{
|
|
|
|
return backgroundSprite;
|
|
|
|
}
|
|
|
|
return _backgroundSpriteDispatchTable.at((int)Control::State::NORMAL);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ControlButton::setBackgroundSpriteForState(ui::Scale9Sprite* sprite, State state)
|
|
|
|
{
|
|
|
|
Size oldPreferredSize = _preferredSize;
|
|
|
|
|
|
|
|
auto previousBackgroundSprite = _backgroundSpriteDispatchTable.at((int)state);
|
|
|
|
if (previousBackgroundSprite)
|
|
|
|
{
|
|
|
|
removeChild(previousBackgroundSprite, true);
|
|
|
|
_backgroundSpriteDispatchTable.erase((int)state);
|
|
|
|
}
|
|
|
|
|
|
|
|
_backgroundSpriteDispatchTable.insert((int)state, sprite);
|
|
|
|
sprite->setVisible(false);
|
|
|
|
sprite->setAnchorPoint(Vec2(0.5f, 0.5f));
|
|
|
|
addChild(sprite);
|
|
|
|
|
|
|
|
if (this->_preferredSize.width != 0 || this->_preferredSize.height != 0)
|
|
|
|
{
|
|
|
|
if (oldPreferredSize.equals(_preferredSize))
|
|
|
|
{
|
|
|
|
// Force update of preferred size
|
2021-12-25 10:04:45 +08:00
|
|
|
sprite->setPreferredSize(Size(oldPreferredSize.width + 1, oldPreferredSize.height + 1));
|
2020-10-18 12:31:45 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2020-10-18 12:31:45 +08:00
|
|
|
sprite->setPreferredSize(this->_preferredSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the current state if equal to the given state we update the layout
|
|
|
|
if (getState() == state)
|
|
|
|
{
|
|
|
|
needsLayout();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void ControlButton::setBackgroundSpriteFrameForState(SpriteFrame* spriteFrame, State state)
|
2020-10-18 12:31:45 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
ui::Scale9Sprite* sprite = ui::Scale9Sprite::createWithSpriteFrame(spriteFrame);
|
2020-10-18 12:31:45 +08:00
|
|
|
this->setBackgroundSpriteForState(sprite, state);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ControlButton::needsLayout()
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
if (!_parentInited)
|
|
|
|
{
|
2020-10-18 12:31:45 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Hide the background and the label
|
2021-12-25 10:04:45 +08:00
|
|
|
if (_titleLabel != nullptr)
|
|
|
|
{
|
2020-10-18 12:31:45 +08:00
|
|
|
_titleLabel->setVisible(false);
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
if (_backgroundSprite)
|
|
|
|
{
|
2020-10-18 12:31:45 +08:00
|
|
|
_backgroundSprite->setVisible(false);
|
|
|
|
}
|
|
|
|
// Update anchor of all labels
|
|
|
|
this->setLabelAnchorPoint(this->_labelAnchorPoint);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2020-10-18 12:31:45 +08:00
|
|
|
// Update the label to match with the current state
|
|
|
|
_currentTitle = getTitleForState(_state);
|
|
|
|
|
|
|
|
_currentTitleColor = getTitleColorForState(_state);
|
|
|
|
|
|
|
|
this->setTitleLabel(getTitleLabelForState(_state));
|
|
|
|
|
|
|
|
LabelProtocol* label = dynamic_cast<LabelProtocol*>(_titleLabel);
|
|
|
|
if (label && !_currentTitle.empty())
|
|
|
|
{
|
|
|
|
label->setString(_currentTitle);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_titleLabel)
|
|
|
|
{
|
|
|
|
_titleLabel->setColor(_currentTitleColor);
|
|
|
|
}
|
|
|
|
if (_titleLabel != nullptr)
|
|
|
|
{
|
|
|
|
_titleLabel->setPosition(getContentSize().width / 2, getContentSize().height / 2);
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2020-10-18 12:31:45 +08:00
|
|
|
// Update the background sprite
|
|
|
|
this->setBackgroundSprite(this->getBackgroundSpriteForState(_state));
|
|
|
|
if (_backgroundSprite != nullptr)
|
|
|
|
{
|
|
|
|
_backgroundSprite->setPosition(getContentSize().width / 2, getContentSize().height / 2);
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2020-10-18 12:31:45 +08:00
|
|
|
// Get the title label size
|
|
|
|
Size titleLabelSize;
|
|
|
|
if (_titleLabel != nullptr)
|
|
|
|
{
|
|
|
|
titleLabelSize = _titleLabel->getBoundingBox().size;
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2020-10-18 12:31:45 +08:00
|
|
|
// Adjust the background image if necessary
|
|
|
|
if (_doesAdjustBackgroundImage)
|
|
|
|
{
|
|
|
|
// Add the margins
|
|
|
|
if (_backgroundSprite != nullptr)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
_backgroundSprite->setContentSize(
|
|
|
|
Size(titleLabelSize.width + _marginH * 2, titleLabelSize.height + _marginV * 2));
|
2020-10-18 12:31:45 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
}
|
2020-10-18 12:31:45 +08:00
|
|
|
else
|
2021-12-25 10:04:45 +08:00
|
|
|
{
|
|
|
|
// TODO: should this also have margins if one of the preferred sizes is relaxed?
|
2020-10-18 12:31:45 +08:00
|
|
|
if (_backgroundSprite != nullptr)
|
|
|
|
{
|
|
|
|
Size preferredSize = _backgroundSprite->getPreferredSize();
|
|
|
|
if (preferredSize.width <= 0)
|
|
|
|
{
|
|
|
|
preferredSize.width = titleLabelSize.width;
|
|
|
|
}
|
|
|
|
if (preferredSize.height <= 0)
|
|
|
|
{
|
|
|
|
preferredSize.height = titleLabelSize.height;
|
|
|
|
}
|
|
|
|
|
|
|
|
_backgroundSprite->setContentSize(preferredSize);
|
|
|
|
}
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2020-10-18 12:31:45 +08:00
|
|
|
// Set the content size
|
|
|
|
Rect rectTitle;
|
|
|
|
if (_titleLabel != nullptr)
|
|
|
|
{
|
|
|
|
rectTitle = _titleLabel->getBoundingBox();
|
|
|
|
}
|
|
|
|
Rect rectBackground;
|
|
|
|
if (_backgroundSprite != nullptr)
|
|
|
|
{
|
|
|
|
rectBackground = _backgroundSprite->getBoundingBox();
|
|
|
|
}
|
|
|
|
|
|
|
|
Rect maxRect = ControlUtils::RectUnion(rectTitle, rectBackground);
|
2021-12-25 10:04:45 +08:00
|
|
|
setContentSize(Size(maxRect.size.width, maxRect.size.height));
|
|
|
|
|
2020-10-18 12:31:45 +08:00
|
|
|
if (_titleLabel != nullptr)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
_titleLabel->setPosition(getContentSize().width / 2, getContentSize().height / 2);
|
2020-10-18 12:31:45 +08:00
|
|
|
// Make visible the background and the label
|
|
|
|
_titleLabel->setVisible(true);
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2020-10-18 12:31:45 +08:00
|
|
|
if (_backgroundSprite != nullptr)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
_backgroundSprite->setPosition(getContentSize().width / 2, getContentSize().height / 2);
|
|
|
|
_backgroundSprite->setVisible(true);
|
|
|
|
}
|
2020-10-18 12:31:45 +08:00
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
bool ControlButton::onTouchBegan(Touch* pTouch, Event* /*pEvent*/)
|
2020-10-18 12:31:45 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
if (!isTouchInside(pTouch) || !isEnabled() || !isVisible() || !hasVisibleParents())
|
2020-10-18 12:31:45 +08:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
|
|
|
for (Node* c = this->_parent; c != nullptr; c = c->getParent())
|
2020-10-18 12:31:45 +08:00
|
|
|
{
|
|
|
|
if (c->isVisible() == false)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2020-10-18 12:31:45 +08:00
|
|
|
_isPushed = true;
|
|
|
|
this->setHighlighted(true);
|
|
|
|
sendActionsForControlEvents(Control::EventType::TOUCH_DOWN);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void ControlButton::onTouchMoved(Touch* pTouch, Event* /*pEvent*/)
|
|
|
|
{
|
2020-10-18 12:31:45 +08:00
|
|
|
if (!isEnabled() || !isPushed() || isSelected())
|
|
|
|
{
|
|
|
|
if (isHighlighted())
|
|
|
|
{
|
|
|
|
setHighlighted(false);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2020-10-18 12:31:45 +08:00
|
|
|
bool isTouchMoveInside = isTouchInside(pTouch);
|
|
|
|
if (isTouchMoveInside && !isHighlighted())
|
|
|
|
{
|
|
|
|
setHighlighted(true);
|
|
|
|
sendActionsForControlEvents(Control::EventType::DRAG_ENTER);
|
|
|
|
}
|
|
|
|
else if (isTouchMoveInside && isHighlighted())
|
|
|
|
{
|
|
|
|
sendActionsForControlEvents(Control::EventType::DRAG_INSIDE);
|
|
|
|
}
|
|
|
|
else if (!isTouchMoveInside && isHighlighted())
|
|
|
|
{
|
|
|
|
setHighlighted(false);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
|
|
|
sendActionsForControlEvents(Control::EventType::DRAG_EXIT);
|
2020-10-18 12:31:45 +08:00
|
|
|
}
|
|
|
|
else if (!isTouchMoveInside && !isHighlighted())
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
sendActionsForControlEvents(Control::EventType::DRAG_OUTSIDE);
|
2020-10-18 12:31:45 +08:00
|
|
|
}
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
void ControlButton::onTouchEnded(Touch* pTouch, Event* /*pEvent*/)
|
2020-10-18 12:31:45 +08:00
|
|
|
{
|
|
|
|
_isPushed = false;
|
|
|
|
setHighlighted(false);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2020-10-18 12:31:45 +08:00
|
|
|
if (isTouchInside(pTouch))
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
sendActionsForControlEvents(Control::EventType::TOUCH_UP_INSIDE);
|
2020-10-18 12:31:45 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
sendActionsForControlEvents(Control::EventType::TOUCH_UP_OUTSIDE);
|
2020-10-18 12:31:45 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ControlButton::setOpacity(uint8_t opacity)
|
|
|
|
{
|
|
|
|
Control::setOpacity(opacity);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2020-10-18 12:31:45 +08:00
|
|
|
for (auto iter = _backgroundSpriteDispatchTable.begin(); iter != _backgroundSpriteDispatchTable.end(); ++iter)
|
|
|
|
{
|
|
|
|
iter->second->setOpacity(opacity);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (auto iter = _titleLabelDispatchTable.begin(); iter != _titleLabelDispatchTable.end(); ++iter)
|
|
|
|
{
|
|
|
|
iter->second->setOpacity(opacity);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ControlButton::updateDisplayedOpacity(uint8_t parentOpacity)
|
|
|
|
{
|
|
|
|
Control::updateDisplayedOpacity(parentOpacity);
|
|
|
|
|
|
|
|
for (auto iter = _backgroundSpriteDispatchTable.begin(); iter != _backgroundSpriteDispatchTable.end(); ++iter)
|
|
|
|
{
|
|
|
|
iter->second->updateDisplayedOpacity(parentOpacity);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (auto iter = _titleLabelDispatchTable.begin(); iter != _titleLabelDispatchTable.end(); ++iter)
|
|
|
|
{
|
|
|
|
iter->second->updateDisplayedOpacity(parentOpacity);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void ControlButton::setColor(const Color3B& color)
|
2020-10-18 12:31:45 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
Control::setColor(color);
|
|
|
|
|
2020-10-18 12:31:45 +08:00
|
|
|
for (auto iter = _backgroundSpriteDispatchTable.begin(); iter != _backgroundSpriteDispatchTable.end(); ++iter)
|
|
|
|
{
|
|
|
|
iter->second->setColor(color);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (auto iter = _titleLabelDispatchTable.begin(); iter != _titleLabelDispatchTable.end(); ++iter)
|
|
|
|
{
|
|
|
|
iter->second->setColor(color);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ControlButton::updateDisplayedColor(const Color3B& parentColor)
|
|
|
|
{
|
|
|
|
Control::updateDisplayedColor(parentColor);
|
|
|
|
|
|
|
|
for (auto iter = _backgroundSpriteDispatchTable.begin(); iter != _backgroundSpriteDispatchTable.end(); ++iter)
|
|
|
|
{
|
|
|
|
iter->second->updateDisplayedColor(parentColor);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (auto iter = _titleLabelDispatchTable.begin(); iter != _titleLabelDispatchTable.end(); ++iter)
|
|
|
|
{
|
|
|
|
iter->second->updateDisplayedColor(parentColor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ControlButton::onTouchCancelled(Touch* /*pTouch*/, Event* /*pEvent*/)
|
|
|
|
{
|
|
|
|
_isPushed = false;
|
|
|
|
setHighlighted(false);
|
|
|
|
sendActionsForControlEvents(Control::EventType::TOUCH_CANCEL);
|
|
|
|
}
|
|
|
|
|
|
|
|
ControlButton* ControlButton::create()
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
ControlButton* pControlButton = new ControlButton();
|
2021-12-08 00:11:53 +08:00
|
|
|
if (pControlButton->init())
|
2020-10-18 12:31:45 +08:00
|
|
|
{
|
|
|
|
pControlButton->autorelease();
|
|
|
|
return pControlButton;
|
|
|
|
}
|
|
|
|
CC_SAFE_DELETE(pControlButton);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_CC_EXT_END
|