CCTextFieldTTF是cocos2d-x封装的输入框控件,主要配合CCTextFieldDelegate和CCTouchDelegate两个代理接口使用,前者是用来处理文字的输入删除操作的代理类,后者是用来触发打开和关闭输入法键盘的。
借鉴网友oneRain88的“带光标的输入框”文章,在其基础上加入了密码框星号显示设置,字符长度设置,触摸弹出输入法区域设置。
文章链接:http://blog.youkuaiyun.com/onerain88/article/details/7572315,这篇文章对CCTextFieldTTF的使用原理讲的很好,封装的思路也很好,想了解原理可以去读读,本人只是在他的基础上加了一些小功能。在此也谢谢oneRain88的分享。
- #ifndef DTCursorTextField_h
- #define DTCursorTextField_h
- #include "cocos2d.h"
- USING_NS_CC;
- class DTCursorTextField: public CCTextFieldTTF, public CCTouchDelegate
- ,public CCTextFieldDelegate
- {
- private:
- // 点击开始位置
- CCPoint m_beginPos;
- // 光标精灵
- CCSprite *m_pCursorSprite;
- // 光标动画
- CCAction *m_pCursorAction;
- // 光标坐标
- CCPoint m_cursorPos;
- // 是否加密显示
- bool isPsw;
- int m_limitNum;
- // 输入框内容
- //std::string *m_pInputText;
- CCSize m_designedSize;
- public:
- DTCursorTextField();
- ~DTCursorTextField();
- // static,暂时不能使用
- // static DTCursorTextField * textFieldWithPlaceHolder(const char *placeholder, const CCSize& dimensions, CCTextAlignment alignment, const char *fontName, float fontSize);
- /** creates a CCLabelTTF from a fontname and font size */
- static DTCursorTextField * textFieldWithPlaceHolder(const char *placeholder, const char *fontName, float fontSize);
- // CCLayer
- void onEnter();
- void onExit();
- // 初始化光标精灵
- void initCursorSprite(int nHeight);
- void setColor(const ccColor3B& color3);
- // CCTextFieldDelegate
- virtual bool onTextFieldAttachWithIME(CCTextFieldTTF *pSender);
- virtual bool onTextFieldDetachWithIME(CCTextFieldTTF * pSender);
- virtual bool onTextFieldInsertText(CCTextFieldTTF * pSender, const char * text, int nLen);
- virtual bool onTextFieldDeleteBackward(CCTextFieldTTF * pSender, const char * delText, int nLen);
- // CCLayer Touch
- bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
- void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
- // 判断是否点击在TextField处
- bool isInTextField(CCTouch *pTouch);
- // 得到TextField矩形
- CCRect getRect();
- // 打开输入法
- void openIME();
- // 关闭输入法
- void closeIME();
- //设置是否星号显示
- bool getIsPsw();
- void setIsPsw(bool bFlag);
- //设置字符长度限制,一个汉字三个字符
- void setLimitNum(int limitNum);
- int getLimitNum();
- //重载原函数,用来显示星号
- void setString(const char* displayTx, const char* inputTx);
- //点击弹出输入法的尺寸范围
- void setDesignedSize(CCSize size);
- CCSize getDesignedSize();
- };
- #endif
- #include "DTCursorTextField.h"
- #include "CCNotificationCenter.h"
- static int _calcCharCount(const char * pszText)
- {
- int n = 0;
- char ch = 0;
- while ((ch = *pszText))
- {
- CC_BREAK_IF(! ch);
- if (0x80 != (0xC0 & ch))
- {
- ++n;
- }
- ++pszText;
- }
- return n;
- }
- const static float DELTA = 20.0f;
- DTCursorTextField::DTCursorTextField()
- {
- CCTextFieldTTF();
- m_pCursorSprite = NULL;
- m_pCursorAction = NULL;
- m_pInputText = NULL;
- isPsw = false;
- m_limitNum = 30;
- }
- DTCursorTextField::~DTCursorTextField()
- {
- //delete m_pInputText;
- }
- void DTCursorTextField::onEnter()
- {
- CCTextFieldTTF::onEnter();
- CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, -128, false);
- this->setDelegate(this);
- }
- //静态生成函数
- DTCursorTextField * DTCursorTextField::textFieldWithPlaceHolder(const char *placeholder, const char *fontName, float fontSize)
- {
- DTCursorTextField *pRet = new DTCursorTextField();
- if(pRet && pRet->initWithString("", fontName, fontSize))
- {
- pRet->autorelease();
- if (placeholder)
- {
- pRet->setPlaceHolder(placeholder);
- }
- pRet->initCursorSprite(fontSize);
- return pRet;
- }
- CC_SAFE_DELETE(pRet);
- return NULL;
- }
- void DTCursorTextField::initCursorSprite(int nHeight)
- {
- // 初始化光标
- int column = 4;
- int pixels[nHeight][column];
- for (int i=0; i<nHeight; ++i) {
- for (int j=0; j<column; ++j) {
- pixels[i][j] = 0xffffffff;
- }
- }
- CCTexture2D *texture = new CCTexture2D();
- texture->initWithData(pixels, kCCTexture2DPixelFormat_RGB888, 1, 1, CCSizeMake(column, nHeight));
- m_pCursorSprite = CCSprite::create(texture);
- CCSize winSize = getContentSize();
- m_cursorPos = ccp(0, winSize.height / 2);
- m_pCursorSprite->setPosition(m_cursorPos);
- this->addChild(m_pCursorSprite);
- m_pCursorAction = CCRepeatForever::create((CCActionInterval *) CCSequence::create(CCFadeOut::create(0.25f), CCFadeIn::create(0.25f), NULL));
- m_pCursorSprite->runAction(m_pCursorAction);
- m_pInputText = new std::string();
- }
- bool DTCursorTextField::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent)
- {
- m_beginPos = pTouch->locationInView();
- m_beginPos = CCDirector::sharedDirector()->convertToGL(m_beginPos);
- return true;
- }
- CCRect DTCursorTextField::getRect()
- {
- CCSize size;
- if (&m_designedSize != NULL) {
- size = m_designedSize;
- }else {
- size = getContentSize();
- }
- CCRect rect = CCRectMake(0 - size.width * getAnchorPoint().x, 0 - size.height * getAnchorPoint().y, size.width, size.height);
- return rect;
- }
- //设置触摸弹出输入法的区域大小
- void DTCursorTextField::setDesignedSize(cocos2d::CCSize size)
- {
- m_designedSize = size;
- }
- CCSize DTCursorTextField::getDesignedSize()
- {
- return m_designedSize;
- }
- bool DTCursorTextField::isInTextField(cocos2d::CCTouch *pTouch)
- {
- CCPoint pToushPos = convertTouchToNodeSpaceAR(pTouch);
- return CCRect::CCRectContainsPoint(getRect(), pToushPos);
- }
- void DTCursorTextField::ccTouchEnded(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent)
- {
- CCPoint endPos = pTouch->locationInView();
- endPos = CCDirector::sharedDirector()->convertToGL(endPos);
- // 判断是否为点击事件
- if (::abs(endPos.x - m_beginPos.x) > DELTA ||
- ::abs(endPos.y - m_beginPos.y) > DELTA)
- {
- // 不是点击事件
- m_beginPos.x = m_beginPos.y = -1;
- return;
- }
- CCLOG("width: %f, height: %f.", getContentSize().width, getContentSize().height);
- // 判断是打开输入法还是关闭输入法
- isInTextField(pTouch) ? openIME() : closeIME();
- }
- bool DTCursorTextField::onTextFieldAttachWithIME(cocos2d::CCTextFieldTTF *pSender)
- {
- if (m_pInputText->empty()) {
- return false;
- }
- m_pCursorSprite->setPositionX(getContentSize().width);
- return false;
- }
- bool DTCursorTextField::onTextFieldInsertText(cocos2d::CCTextFieldTTF *pSender, const char *text, int nLen)
- {
- CCLOG("Width: %f", pSender->getContentSize().width);
- CCLOG("Text: %s", text);
- CCLOG("Length: %d", nLen);
- std::string tempStr = m_pInputText->substr();
- tempStr.append(text);
- if (tempStr.length() > m_limitNum) {
- return true;
- }
- m_pInputText->append(text);
- if (isPsw) {
- std::string tempStr;
- for (int i = 0; i < m_pInputText->size(); i++) {
- tempStr.append("*");
- }
- setString(tempStr.c_str(), m_pInputText->c_str());
- }else {
- setString(m_pInputText->c_str(), m_pInputText->c_str());
- }
- m_pCursorSprite->setPositionX(getContentSize().width);
- return true;
- }
- bool DTCursorTextField::onTextFieldDeleteBackward(cocos2d::CCTextFieldTTF *pSender, const char *delText, int nLen)
- {
- m_pInputText->resize(m_pInputText->size() - nLen);
- CCLog(m_pInputText->c_str());
- if (isPsw) {
- std::string tempStr;
- for (int i = 0; i < m_pInputText->size(); i++) {
- tempStr.append("*");
- }
- setString(tempStr.c_str(), m_pInputText->c_str());
- }else {
- setString(m_pInputText->c_str(), m_pInputText->c_str());
- }
- m_pCursorSprite->setPositionX(getContentSize().width);
- if (m_pInputText->empty()) {
- m_pCursorSprite->setPositionX(0);
- }
- return true;
- }
- bool DTCursorTextField::onTextFieldDetachWithIME(cocos2d::CCTextFieldTTF *pSender)
- {
- return false;
- }
- void DTCursorTextField::openIME()
- {
- m_pCursorSprite->setVisible(true);
- this->attachWithIME();
- }
- void DTCursorTextField::closeIME()
- {
- m_pCursorSprite->setVisible(false);
- this->detachWithIME();
- }
- void DTCursorTextField::onExit()
- {
- this->detachWithIME();
- CCTextFieldTTF::onExit();
- CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
- }
- bool DTCursorTextField::getIsPsw()
- {
- return isPsw;
- }
- //设置星号显示否
- void DTCursorTextField::setIsPsw( bool bFlag)
- {
- isPsw = bFlag;
- }
- int DTCursorTextField::getLimitNum()
- {
- return m_limitNum;
- }
- //设置字符长度
- void DTCursorTextField::setLimitNum(int limitNum)
- {
- m_limitNum = limitNum;
- }
- void DTCursorTextField::setString(const char *displayTx, const char* inputTx)
- {
- CC_SAFE_DELETE(m_pInputText);
- if (inputTx)
- {
- m_pInputText = new std::string(inputTx);
- }
- else
- {
- m_pInputText = new std::string;
- }
- // if there is no input text, display placeholder instead
- if (! m_pInputText->length())
- {
- CCLabelTTF::setString(m_pPlaceHolder->c_str());
- }
- else
- {
- CCLabelTTF::setString(displayTx);
- }
- m_nCharCount = _calcCharCount(m_pInputText->c_str());
- }
- void DTCursorTextField::setColor(const ccColor3B& color3)
- {
- m_sColor = m_sColorUnmodified = color3;
- if (m_bOpacityModifyRGB)
- {
- m_sColor.r = color3.r * m_nOpacity/255.0f;
- m_sColor.g = color3.g * m_nOpacity/255.0f;
- m_sColor.b = color3.b * m_nOpacity/255.0f;
- }
- updateColor();
- m_pCursorSprite->setColor(color3);
- }
使用的时候,直接使用textFieldWithPlaceHolder函数生成一个对象指针,setIsPsw,setLimitNum,setDesignedSize,setColor分别实现星号显示,字符长度,触摸弹出输入法区域大小,字符颜色。
注释比较简单,欢迎指正讨论。
本文来自:http://www.cnblogs.com/Rooty 转载请注明出处,谢谢合作。