The button class CCControlButton inherits from the control class CCControl. The control class CCControl mainly provides a series of control trigger events to the subclass. When the child control triggers a related event, the related control event callback function will be executed. This is similar to the menu button callback in CCMenu mentioned earlier.
The control class CCControl has three main subclasses:
(1) Switch control CCControlSwitch
(2) Slider control CCControlSlider
(3) Button control CCControlButton
This section talks about one of its subclasses: the button class CCControlButton.
Changes in Cocos2d-x 3.x
(1) Remove "CC"
(2) Object class CCObject changed to Ref
(3) The button event callback is still cccontrol_selector, and CC_CALLBACK_2 is not used
(4) The button state CCControlState is changed to a strong enumeration Control::State
//
NORMAL //normal
HIGH_LIGHTED //Highlight (that is, in the internal touch state)
DISABLED //disable
SELECTED //selected
//
(5) The button event CCControlEvent is changed to a strong enumeration Control::EventType
//
TOUCH_DOWN //When you just started to touch the button
DRAG_INSIDE //When dragging internally (while keeping touch)
DRAG_OUTSIDE //When dragging externally (while keeping the touch state)
DRAG_ENTER //When the drag just enters the interior (while keeping the touch state)
DRAG_EXIT //When the drag just leaves the interior (while keeping the touch state)
TOUCH_UP_INSIDE //Lift your finger internally (while keeping touching)
TOUCH_UP_OUTSIDE //Lift your finger externally (while keeping touching)
TOUCH_CANCEL //Cancel contact
//
(6) Other changes are not significant.
CCControlButton
Button control CCControlButton, I must be familiar with this, right? Every game basically uses buttons.
A button not only has several different button states, but also some button events. In addition, the background image used by the button control CCControlButton is CCScale9Sprite, which can make the button as large as possible to keep the edges and corners without distortion.
1. Button state CCControlState
//
CCControlStateNormal //Normal
CCControlStateHighlighted //Highlight (that is, in the internal touch state)
CCControlStateDisabled //Disable
CCControlStateSelected //selected
//
2. Button event CCControlEvent
//
CCControlEventTouchDown //When you just started to touch the button
CCControlEventTouchDragInside //When dragging internally (in the touch state)
CCControlEventTouchDragOutside //When dragging externally (while keeping the touch state)
CCControlEventTouchDragEnter //When the drag just enters the interior (while keeping the touch state)
CCControlEventTouchDragExit //When the drag just leaves the interior (while keeping the touch state)
CCControlEventTouchUpInside //Lift your finger internally (hold the touch state)
CCControlEventTouchUpOutside //Lift your finger externally (hold the touch state)
CCControlEventTouchCancel //Cancel contact
//
3. Methods of binding button events
//
//Binding control events
addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::touchDownAction), CCControlEventTouchDown);
void addTargetWithActionForControlEvents(CCObject* target, SEL_CCControlHandler action, CCControlEvent controlEvents);
//Delete control event
//removeTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::touchDownAction), CCControlEventTouchDown);
void removeTargetWithActionForControlEvents(CCObject* target, SEL_CCControlHandler action, CCControlEvent controlEvents);
//
4. Header files and namespaces that need to be quoted
//
#include "cocos-ext.h" //Include cocos-ext.h header file
using namespace cocos2d::extension; //reference cocos2d::extension namespace
//
5. Common operations are as follows:
//
class CCControlButton : public CCControl
{
/**
* Three ways to create CCControlButton
*/
//Use the point nine image CCScale9Sprite, the button does not have the label CCLabel
static CCControlButton* create(CCScale9Sprite* sprite);
//Use label label, can be CCLabelTTF, CCLabelBMFont
static CCControlButton* create(CCNode* label, CCScale9Sprite* backgroundSprite);
//title: label content
//fontName: font resource, such as "Arial"
//fontSize: font size, default 12
//The internally created label is CCLabelTTF
static CCControlButton* create(std::string title, const char* fontName, float fontSize);
/**
* Property setting 1 (under the current CCControlState)
* getCurrentTitle , getCurrentTitleColor ,
* TitleLabel , BackgroundSprite , PreferredSize
*/
//Currently displayed label content, read-only getCurrentTitle
CC_SYNTHESIZE_READONLY(CCString*, m_currentTitle, CurrentTitle);
//The currently displayed label content color, read only getCurrentTitleColor
CC_SYNTHESIZE_READONLY_PASS_BY_REF(ccColor3B, m_currentTitleColor, CurrentTitleColor);
//Set the label under the current CCControlState, set/get
CC_SYNTHESIZE_RETAIN(CCNode*, m_titleLabel, TitleLabel);
//Set the background sprite under the current CCControlState, set/get
CC_SYNTHESIZE_RETAIN(CCScale9Sprite*, m_backgroundSprite, BackgroundSprite);
//Set the button size. If the label size is larger than the button, it will be automatically expanded, set/get.
//But after my test: it is set, but the button size is fixed. It is not automatically stretched according to the size of the label.
CC_PROPERTY(CCSize, m_preferredSize, PreferredSize);
/**
* Property setting 2 (under specified CCControlState)
* setTitleLabelForState , setTitleForState , setTitleColorForState ,
* setTitleTTFForState , setTitleTTFSizeForState ,
* setTitleBMFontForState ,
* setBackgroundSpriteForState , setBackgroundSpriteFrameForState , getBackgroundSpriteForState
*/
//Set the font label under the specified CCControlState
//If the label is not set, the default is the font label of CCButtonStateNormal state
//Font label can be CCLabelTTF, CCLabelBMFont
virtual void setTitleLabelForState(CCNode* label, CCControlState state);
virtual CCNode* getTitleLabelForState(CCControlState state);
//Set the label content under the specified CCControlState
//If the label is not set, the label content in the CCButtonStateNormal state is returned by default
virtual void setTitleForState(CCString* title, CCControlState state);
virtual CCString* getTitleForState(CCControlState state);
//Set the label color under the specified CCControlState
virtual void setTitleColorForState(ccColor3B color, CCControlState state);
virtual const ccColor3B getTitleColorForState(CCControlState state);
//###############################################################################
//Set the label under the specified CCControlState as CCLabelTTF
//fntFile is the font resource name, such as "Arial"
virtual void setTitleTTFForState(const char* fntFile, CCControlState state);
virtual const char * getTitleTTFForState (CCControlState state);
//Set the font size of the CCLabelTTF label under the specified CCControlState
virtual void setTitleTTFSizeForState(float size, CCControlState state);
virtual float getTitleTTFSizeForState(CCControlState state);
//###############################################################################
//Set the label under the specified CCControlState as CCLabelBMFont
//fntFile is the name of the font resource, such as *.fnt
virtual void setTitleBMFontForState(const char* fntFile, CCControlState state);
virtual const char * getTitleBMFontForState(CCControlState state);
//###############################################################################
//Use the point nine image CCScale9Sprite to set the background sprite under the specified CCControlState
virtual void setBackgroundSpriteForState(CCScale9Sprite* sprite, CCControlState state);
//Use the sprite frame CCSpriteFrame to set the background sprite under the specified CCControlState
//In fact, the code implemented internally is actually using the sprite frame spriteFrame to create the point nine image CCScale9Sprite as the background sprite
virtual void setBackgroundSpriteFrameForState(CCSpriteFrame* spriteFrame, CCControlState state);
//Get the background image under the specified CCControlState
virtual CCScale9Sprite* getBackgroundSpriteForState(CCControlState state);
/**
* Inherited from the parent class
*/
virtual void setEnabled(bool enabled); //whether it is enabled
virtual void setSelected(bool enabled); //whether selected
virtual void setHighlighted(bool enabled); //whether to highlight
};
//
Code combat
The code comes from the official project TestCpp of Cocos2d-x.
1. Button background (normal, highlighted)
2. Introduce header files and namespaces
//
#include "cocos-ext.h"
using namespace cocos2d::extension;
//
3. Declare the callback function of the button event in HelloWorld.h and the Label that displays the button state
//
CCLabelTTF* displayLabel; //label to display button status
void touchDownAction(CCObject* sender, CCControlEvent controlEvent); //When you just start to touch the button
void touchDragInsideAction(CCObject* sender, CCControlEvent controlEvent); //When dragging internally (while keeping the touch state)
void touchDragOutsideAction(CCObject* sender, CCControlEvent controlEvent); //When dragging externally (while keeping the touch state)
void touchDragEnterAction(CCObject* sender, CCControlEvent controlEvent); //When the drag just enters the interior (while keeping the touch state)
void touchDragExitAction(CCObject* sender, CCControlEvent controlEvent); //When the drag just leaves the interior (while keeping the touch state)
void touchUpInsideAction(CCObject* sender, CCControlEvent controlEvent); //Lift your finger internally (hold the touch state)
void touchUpOutsideAction(CCObject* sender, CCControlEvent controlEvent); //Lift your finger outside (keep touching)
void touchCancelAction(CCObject* sender, CCControlEvent controlEvent); //Cancel contact
//
4. Create a button in the init of HelloWorld.cpp and bind the button event
//
bool HelloWorld::init()
{
if ( !CCLayer::init() )
{
return false;
}
//Get the size of the visible area
CCSize mysize = CCDirector::sharedDirector()->getVisibleSize();
//Get the origin position of the visible area
CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
//The center of the screen
CCPoint midPos = ccp(mysize.width/2, mysize.height/2);
//Display the label of the button status displayLabel
displayLabel = CCLabelTTF::create("No Event", "Marker Felt", 32);
displayLabel->setPosition( midPos + ccp(0, 100) );
this->addChild(displayLabel);
//The background sprite in the button CCScale9Sprite
CCScale9Sprite* bgNormal = CCScale9Sprite::create("btnNormal.png"); //Normal background
CCScale9Sprite* bgHighlighted = CCScale9Sprite::create("btnHighlighted.png"); //Highlight background
//The label in the button CCLabelTTF
CCLabelTTF* titleNormal = CCLabelTTF::create("Button is Normal !", "Marker Felt", 30);
CCLabelTTF* titleHighlighted = CCLabelTTF::create("Button is Highlighted !", "Marker Felt", 30);
//Create button CCControlButton
CCControlButton * btn = CCControlButton :: create (titleNormal, bgNormal);
btn-> setPosition (midPos);
this->addChild(btn);
//Set the state when the button is highlighted
btn->setTitleLabelForState(titleHighlighted, CCControlStateHighlighted); //Highlight label
btn->setTitleColorForState(ccRED, CCControlStateHighlighted); //红色
btn->setBackgroundSpriteForState(bgHighlighted, CCControlStateHighlighted); //Highlight background
//I wrote this sentence, but the size was fixed. It is not automatically stretched according to the size of the label
// btn-> setPreferredSize (CCSizeMake (120,40));
//Binding event, used to display button state
btn->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::touchDownAction), CCControlEventTouchDown); //When the button is just started to be touched
btn->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::touchDragInsideAction), CCControlEventTouchDragInside); //When dragging internally (while keeping the touch state)
btn->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::touchDragOutsideAction), CCControlEventTouchDragOutside); //When dragging externally (while keeping the touch state)
btn->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::touchDragEnterAction), CCControlEventTouchDragEnter); //When the drag just enters the interior (hold the touch state)
btn->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::touchDragExitAction), CCControlEventTouchDragExit); //When the drag just leaves the interior (while keeping the touch state)
btn->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::touchUpInsideAction), CCControlEventTouchUpInside); //Lift your finger inside (keep touching)
btn->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::touchUpOutsideAction), CCControlEventTouchUpOutside); //Lift your finger outside (keep touching)
btn->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::touchCancelAction), CCControlEventTouchCancel); //取消触点
return true;
}
//
5. Implement the callback function of the button event
//
//When you just started touching the button
void HelloWorld::touchDownAction(CCObject *senderz, CCControlEvent controlEvent)
{
displayLabel->setString("Touch Down");
}
//When dragging internally (while keeping touch)
void HelloWorld::touchDragInsideAction(CCObject *sender, CCControlEvent controlEvent)
{
displayLabel->setString("Drag Inside");
}
//When dragging externally (while keeping touching)
void HelloWorld::touchDragOutsideAction(CCObject *sender, CCControlEvent controlEvent)
{
displayLabel->setString("Drag Outside");
}
//When the drag just enters the interior (while keeping the touch state)
void HelloWorld::touchDragEnterAction(CCObject *sender, CCControlEvent controlEvent)
{
displayLabel->setString("Drag Enter");
}
//When the drag just leaves the interior (while keeping the touch state)
void HelloWorld::touchDragExitAction(CCObject *sender, CCControlEvent controlEvent)
{
displayLabel->setString("Drag Exit");
}
//Lift your finger inside (while keeping touching)
void HelloWorld::touchUpInsideAction(CCObject *sender, CCControlEvent controlEvent)
{
displayLabel->setString("Touch Up Inside.");
}
//Lift your finger outside (while keeping touching)
void HelloWorld::touchUpOutsideAction(CCObject *sender, CCControlEvent controlEvent)
{
displayLabel->setString("Touch Up Outside.");
}
//Cancel all touches
void HelloWorld::touchCancelAction(CCObject *sender, CCControlEvent controlEvent)
{
displayLabel->setString("Touch Cancel");
}
//
6. Operation results
7. Analysis and summary
(1) Originally a small button picture, how big is it i_f15.gif? This is because when the size of the label CCLabelTTF is larger than the button size, the button will automatically stretch.
(2) When I clearly set the highlighted state, the label is titleHighlighted, and the label content should display "Button is Highlighted!". Why is it still "Button is Normal"? i_f06.gif. . . Well, I don't know this question. However, the font color and the background sprite of the button are indeed changed.
(3) As for the button event:
1
2CCControlEventTouchDragEnter //When the drag just enters the interior (while keeping the touch state)
CCControlEventTouchDragExit //When the drag just leaves the interior (while keeping the touch state)
I don't know if you have observed it? Because the effect is only visible when you just enter or leave the button, it becomes DragInside or DragOutside with a shake of your hand.