CCTextFieldTTF的使用和再封装

     CCTextFieldTTF是cocos2d-x封装的输入框控件,主要配合CCTextFieldDelegate和CCTouchDelegate两个代理接口使用,前者是用来处理文字的输入删除操作的代理类,后者是用来触发打开和关闭输入法键盘的。

      借鉴网友oneRain88的“带光标的输入框”文章,在其基础上加入了密码框星号显示设置,字符长度设置,触摸弹出输入法区域设置。

     文章链接:http://blog.csdn.net/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 转载请注明出处,谢谢合作。

你可能感兴趣的:(textfield)