看到这么好的输入控件,一定要跟大家分享哈。
使用CCTextField的时候,各种纠结哈,血泪史就不多说了。
先介绍下这个令人使用极其舒服的扩展控件,首先感谢他的作者,James Chen(虽然我不知道他是谁,笑)。
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2012 James Chen
呵呵,现在看下这个CCEditBox的源码吧。
S1,首先看下,它为我们提供的虚拟键盘各种模式吧
这是键盘完成按钮的模式,从默认到done、go等。
enum KeyboardReturnType {
kKeyboardReturnTypeDefault = 0,
kKeyboardReturnTypeDone,
kKeyboardReturnTypeSend,
kKeyboardReturnTypeSearch,
kKeyboardReturnTypeGo
};
这是键盘的输入模式,有数字,电话,和邮件等。
enum EditBoxInputMode
{
/**
* The user is allowed to enter any text, including line breaks.
*/
kEditBoxInputModeAny = 0,
/**
* The user is allowed to enter an e-mail address.
*/
kEditBoxInputModeEmailAddr,
/**
* The user is allowed to enter an integer value.
*/
kEditBoxInputModeNumeric,
/**
* The user is allowed to enter a phone number.
*/
kEditBoxInputModePhoneNumber,
/**
* The user is allowed to enter a URL.
*/
kEditBoxInputModeUrl,
/**
* The user is allowed to enter a real number value.
* This extends kEditBoxInputModeNumeric by allowing a decimal point.
*/
kEditBoxInputModeDecimal,
/**
* The user is allowed to enter any text, except for line breaks.
*/
kEditBoxInputModeSingleLine
};
然后,就是输入框的标记,有些输入密码的时候要的星号就在这里了。
enum EditBoxInputFlag
{
/**
* Indicates that the text entered is confidential data that should be
* obscured whenever possible. This implies EDIT_BOX_INPUT_FLAG_SENSITIVE.
*/
kEditBoxInputFlagPassword = 0,
/**
* Indicates that the text entered is sensitive data that the
* implementation must never store into a dictionary or table for use
* in predictive, auto-completing, or other accelerated input schemes.
* A credit card number is an example of sensitive data.
*/
kEditBoxInputFlagSensitive,
/**
* This flag is a hint to the implementation that during text editing,
* the initial letter of each word should be capitalized.
*/
kEditBoxInputFlagInitialCapsWord,
/**
* This flag is a hint to the implementation that during text editing,
* the initial letter of each sentence should be capitalized.
*/
kEditBoxInputFlagInitialCapsSentence,
/**
* Capitalize all characters automatically.
*/
kEditBoxInputFlagInitialCapsAllCharacters
};
S2,看下CCEditBox的源代码:
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2012 James Chen
http://www.cocos2d-x.org
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:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
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 "CCEditBox.h"
#include "CCEditBoxImpl.h"
NS_CC_EXT_BEGIN
CCEditBox::CCEditBox(void)
: m_pEditBoxImpl(NULL)
, m_pDelegate(NULL)
, m_eEditBoxInputMode(kEditBoxInputModeSingleLine)
, m_eEditBoxInputFlag(kEditBoxInputFlagInitialCapsAllCharacters)
, m_eKeyboardReturnType(kKeyboardReturnTypeDefault)
, m_nFontSize(-1)
, m_nPlaceholderFontSize(-1)
, m_colText(ccWHITE)
, m_colPlaceHolder(ccGRAY)
, m_nMaxLength(0)
, m_fAdjustHeight(0.0f)
, m_nScriptEditBoxHandler(0)
{
}
CCEditBox::~CCEditBox(void)
{
CC_SAFE_DELETE(m_pEditBoxImpl);
unregisterScriptEditBoxHandler();
}
void CCEditBox::touchDownAction(CCObject *sender, CCControlEvent controlEvent)
{
m_pEditBoxImpl->openKeyboard();
}
CCEditBox* CCEditBox::create(const CCSize& size, CCScale9Sprite* pNormal9SpriteBg, CCScale9Sprite* pPressed9SpriteBg/* = NULL*/, CCScale9Sprite* pDisabled9SpriteBg/* = NULL*/)
{
CCEditBox* pRet = new CCEditBox();
if (pRet != NULL && pRet->initWithSizeAndBackgroundSprite(size, pNormal9SpriteBg))
{
if (pPressed9SpriteBg != NULL)
{
pRet->setBackgroundSpriteForState(pPressed9SpriteBg, CCControlStateHighlighted);
}
if (pDisabled9SpriteBg != NULL)
{
pRet->setBackgroundSpriteForState(pDisabled9SpriteBg, CCControlStateDisabled);
}
pRet->autorelease();
}
else
{
CC_SAFE_DELETE(pRet);
}
return pRet;
}
bool CCEditBox::initWithSizeAndBackgroundSprite(const CCSize& size, CCScale9Sprite* pPressed9SpriteBg)
{
if (CCControlButton::initWithBackgroundSprite(pPressed9SpriteBg))
{
m_pEditBoxImpl = __createSystemEditBox(this);
m_pEditBoxImpl->initWithSize(size);
this->setZoomOnTouchDown(false);
this->setPreferredSize(size);
this->setPosition(ccp(0, 0));
this->addTargetWithActionForControlEvent(this, cccontrol_selector(CCEditBox::touchDownAction), CCControlEventTouchUpInside);
return true;
}
return false;
}
void CCEditBox::setDelegate(CCEditBoxDelegate* pDelegate)
{
m_pDelegate = pDelegate;
if (m_pEditBoxImpl != NULL)
{
m_pEditBoxImpl->setDelegate(pDelegate);
}
}
CCEditBoxDelegate* CCEditBox::getDelegate()
{
return m_pDelegate;
}
void CCEditBox::setText(const char* pText)
{
if (pText != NULL)
{
m_strText = pText;
if (m_pEditBoxImpl != NULL)
{
m_pEditBoxImpl->setText(pText);
}
}
}
const char* CCEditBox::getText(void)
{
if (m_pEditBoxImpl != NULL)
{
const char* pText = m_pEditBoxImpl->getText();
if(pText != NULL)
return pText;
}
return "";
}
void CCEditBox::setFont(const char* pFontName, int fontSize)
{
m_strFontName = pFontName;
m_nFontSize = fontSize;
if (pFontName != NULL)
{
if (m_pEditBoxImpl != NULL)
{
m_pEditBoxImpl->setFont(pFontName, fontSize);
}
}
}
void CCEditBox::setFontName(const char* pFontName)
{
m_strFontName = pFontName;
if (m_pEditBoxImpl != NULL && m_nFontSize != -1)
{
m_pEditBoxImpl->setFont(pFontName, m_nFontSize);
}
}
void CCEditBox::setFontSize(int fontSize)
{
m_nFontSize = fontSize;
if (m_pEditBoxImpl != NULL && m_strFontName.length() > 0)
{
m_pEditBoxImpl->setFont(m_strFontName.c_str(), m_nFontSize);
}
}
void CCEditBox::setFontColor(const ccColor3B& color)
{
m_colText = color;
if (m_pEditBoxImpl != NULL)
{
m_pEditBoxImpl->setFontColor(color);
}
}
void CCEditBox::setPlaceholderFont(const char* pFontName, int fontSize)
{
m_strPlaceholderFontName = pFontName;
m_nPlaceholderFontSize = fontSize;
if (pFontName != NULL)
{
if (m_pEditBoxImpl != NULL)
{
m_pEditBoxImpl->setPlaceholderFont(pFontName, fontSize);
}
}
}
void CCEditBox::setPlaceholderFontName(const char* pFontName)
{
m_strPlaceholderFontName = pFontName;
if (m_pEditBoxImpl != NULL && m_nPlaceholderFontSize != -1)
{
m_pEditBoxImpl->setPlaceholderFont(pFontName, m_nFontSize);
}
}
void CCEditBox::setPlaceholderFontSize(int fontSize)
{
m_nPlaceholderFontSize = fontSize;
if (m_pEditBoxImpl != NULL && m_strPlaceholderFontName.length() > 0)
{
m_pEditBoxImpl->setPlaceholderFont(m_strPlaceholderFontName.c_str(), m_nFontSize);
}
}
void CCEditBox::setPlaceholderFontColor(const ccColor3B& color)
{
m_colText = color;
if (m_pEditBoxImpl != NULL)
{
m_pEditBoxImpl->setPlaceholderFontColor(color);
}
}
void CCEditBox::setPlaceHolder(const char* pText)
{
if (pText != NULL)
{
m_strPlaceHolder = pText;
if (m_pEditBoxImpl != NULL)
{
m_pEditBoxImpl->setPlaceHolder(pText);
}
}
}
const char* CCEditBox::getPlaceHolder(void)
{
return m_strPlaceHolder.c_str();
}
void CCEditBox::setInputMode(EditBoxInputMode inputMode)
{
m_eEditBoxInputMode = inputMode;
if (m_pEditBoxImpl != NULL)
{
m_pEditBoxImpl->setInputMode(inputMode);
}
}
void CCEditBox::setMaxLength(int maxLength)
{
m_nMaxLength = maxLength;
if (m_pEditBoxImpl != NULL)
{
m_pEditBoxImpl->setMaxLength(maxLength);
}
}
int CCEditBox::getMaxLength()
{
return m_nMaxLength;
}
void CCEditBox::setInputFlag(EditBoxInputFlag inputFlag)
{
m_eEditBoxInputFlag = inputFlag;
if (m_pEditBoxImpl != NULL)
{
m_pEditBoxImpl->setInputFlag(inputFlag);
}
}
void CCEditBox::setReturnType(KeyboardReturnType returnType)
{
if (m_pEditBoxImpl != NULL)
{
m_pEditBoxImpl->setReturnType(returnType);
}
}
/* override function */
void CCEditBox::setPosition(const CCPoint& pos)
{
CCControlButton::setPosition(pos);
if (m_pEditBoxImpl != NULL)
{
m_pEditBoxImpl->setPosition(pos);
}
}
void CCEditBox::setVisible(bool visible)
{
CCControlButton::setVisible(visible);
if (m_pEditBoxImpl != NULL)
{
m_pEditBoxImpl->setVisible(visible);
}
}
void CCEditBox::setContentSize(const CCSize& size)
{
CCControlButton::setContentSize(size);
if (m_pEditBoxImpl != NULL)
{
m_pEditBoxImpl->setContentSize(size);
}
}
void CCEditBox::setAnchorPoint(const CCPoint& anchorPoint)
{
CCControlButton::setAnchorPoint(anchorPoint);
if (m_pEditBoxImpl != NULL)
{
m_pEditBoxImpl->setAnchorPoint(anchorPoint);
}
}
void CCEditBox::visit(void)
{
CCControlButton::visit();
if (m_pEditBoxImpl != NULL)
{
m_pEditBoxImpl->visit();
}
}
void CCEditBox::onEnter(void)
{
CCControlButton::onEnter();
if (m_pEditBoxImpl != NULL)
{
m_pEditBoxImpl->onEnter();
}
}
void CCEditBox::onExit(void)
{
CCControlButton::onExit();
if (m_pEditBoxImpl != NULL)
{
// remove system edit control
m_pEditBoxImpl->closeKeyboard();
}
}
static CCRect getRect(CCNode * pNode)
{
CCSize contentSize = pNode->getContentSize();
CCRect rect = CCRectMake(0, 0, contentSize.width, contentSize.height);
return CCRectApplyAffineTransform(rect, pNode->nodeToWorldTransform());
}
void CCEditBox::keyboardWillShow(CCIMEKeyboardNotificationInfo& info)
{
// CCLOG("CCEditBox::keyboardWillShow");
CCRect rectTracked = getRect(this);
// some adjustment for margin between the keyboard and the edit box.
rectTracked.origin.y -= 4;
// if the keyboard area doesn't intersect with the tracking node area, nothing needs to be done.
if (!rectTracked.intersectsRect(info.end))
{
CCLOG("needn't to adjust view layout.");
return;
}
// assume keyboard at the bottom of screen, calculate the vertical adjustment.
m_fAdjustHeight = info.end.getMaxY() - rectTracked.getMinY();
// CCLOG("CCEditBox:needAdjustVerticalPosition(%f)", m_fAdjustHeight);
if (m_pEditBoxImpl != NULL)
{
m_pEditBoxImpl->doAnimationWhenKeyboardMove(info.duration, m_fAdjustHeight);
}
}
void CCEditBox::keyboardDidShow(CCIMEKeyboardNotificationInfo& info)
{
}
void CCEditBox::keyboardWillHide(CCIMEKeyboardNotificationInfo& info)
{
// CCLOG("CCEditBox::keyboardWillHide");
if (m_pEditBoxImpl != NULL)
{
m_pEditBoxImpl->doAnimationWhenKeyboardMove(info.duration, -m_fAdjustHeight);
}
}
void CCEditBox::keyboardDidHide(CCIMEKeyboardNotificationInfo& info)
{
}
void CCEditBox::registerScriptEditBoxHandler(int handler)
{
unregisterScriptEditBoxHandler();
m_nScriptEditBoxHandler = handler;
}
void CCEditBox::unregisterScriptEditBoxHandler(void)
{
if (0 != m_nScriptEditBoxHandler)
{
CCScriptEngineManager::sharedManager()->getScriptEngine()->removeScriptHandler(m_nScriptEditBoxHandler);
m_nScriptEditBoxHandler = 0;
}
}
NS_CC_EXT_END
当然,我们主要使用的方法主要是设置位置,大小,字体属性,键盘模式,长度,设置和获取键盘输入的内容。
S3,看下我们怎么使用这个类来实现我们的虚拟键盘,ps:键盘缩回的神马问题在这里都是浮云
首先,继承这个CCEditBoxDelegate。重写这些方法,但是基本上不做什么。
virtual void editBoxEditingDidBegin(CCEditBox* editBox) ;
virtual void editBoxEditingDidEnd(CCEditBox* editBox) ;
virtual void editBoxTextChanged(CCEditBox* editBox, const std::string& text) ;
virtual void editBoxReturn(CCEditBox* editBox) ;
然后,就设置EditBox的属性控制。废话不说,看代码:
//设置CCEditBox的输入框的背景图片,CCScale9Sprite是可拉伸
CCScale9Sprite* sacel9Spr = CCScale9Sprite::create("Icon@2x.png");
//设置的长和宽,和背景图片
box = CCEditBox::create(CCSizeMake(300, 100), sacel9Spr);
//设置位置
box->setPosition(ccp(size.width/2, size.height/2));
//设置字体颜色
box->setFontColor(ccc3(255, 228, 173));
//设置输入框提示字
box->setPlaceHolder("length 5");
//设置键盘输入模式
box->setInputMode(kEditBoxInputModeAny);
//设置键盘输入的字符的首写大写
box->setInputFlag(kEditBoxInputFlagInitialCapsWord);
//设置键盘缩回按钮为done
box->setReturnType(kKeyboardReturnTypeDone);
//设置代理
box->setDelegate(this);
//设置输入长度为20个字符
box->setMaxLength(20);
this->addChild(box, 1);
下面贴图一张,看下效果: