聊天输入框 (单行输入框 ,多行可自己扩展)
实现功能:
1.普通输入
2.设置输入框显示最大宽度(PT值,cocos2d-x坐标值)
3.设置输入框允许的最大字符数量(字符Unicode)
4.输入框自动缩进(当输入字符串数量超过显示框最大宽度时,会自动向左缩进,显示最新字符串
输入框实现代码
头文件:
#ifndef CursorInputDemo_CursorTextField_h #define CursorInputDemo_CursorTextField_h
#include "cocos2d.h"
USING_NS_CC;
class CursorTextField: public CCTextFieldTTF, public CCTextFieldDelegate, public
CCTouchDelegate
{ private: // 点击开始位置 CCPoint m_beginPos; // 光标精灵 CCSprite *m_pCursorSprite; // 光标动画 CCAction *m_pCursorAction; // 光标坐标 CCPoint m_cursorPos; //输入框长度 float inputFrameWidth; //允许输入的最大字符数Unicode float inputMaxLength; int nLenCount; int* codeNumType; //每个字符对应的字节数量 int codeCur; //当前第几个字符 int startCur; //行开头字符下标 int endCur; //行末尾下标 // 输入框总内容 std::string *m_pInputText; std::string inpuText; //当前输入框内容 public: CursorTextField(); ~CursorTextField(); // static static CursorTextField* textFieldWithPlaceHolder(const char *placeholder, const char
*fontName, float fontSize);
// CCLayer void onEnter(); void onExit(); bool init(); // 初始化光标精灵 void initCursorSprite(int nHeight);
// 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();
const char* getInputText();
void setInpuntText(char* text); void setInputWidth(float width); void setInputMaxLength(float length);
int Utf82Unicode(LPWSTR out, int outsize , LPSTR in,int insize);
};
#endif
cpp文件: #include "CursorTextField.h"
const static float DELTA = 0.5f;
using namespace cocos2d;
using namespace std;
CursorTextField::CursorTextField()
{ CCTextFieldTTF();
m_pCursorSprite = NULL;
m_pCursorAction = NULL;
m_pInputText = NULL;
codeNumType = NULL; }
CursorTextField::~CursorTextField()
{ CC_SAFE_DELETE(m_pInputText); CC_SAFE_DELETE_ARRAY(codeNumType); }
void CursorTextField::onEnter()
{ CCTextFieldTTF::onEnter(); CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,0,false); this->setDelegate(this); }
CursorTextField * CursorTextField::textFieldWithPlaceHolder(const char *placeholder, const char
*fontName, float fontSize)
{ CursorTextField *pRet = new CursorTextField(); if(pRet && pRet->initWithString("", fontName, fontSize)) { pRet->autorelease(); if (placeholder) { pRet->setPlaceHolder(placeholder); } pRet->init(); pRet->initCursorSprite(fontSize); pRet->setHorizontalAlignment(kCCTextAlignmentLeft); return pRet; } CC_SAFE_DELETE(pRet); return NULL; }
bool CursorTextField::init(){
this->inputFrameWidth = 400; this->inputMaxLength = 38; this->nLenCount = 0; this->codeNumType = new int[50]; this->codeCur = 0; this->startCur = 0; this->endCur = 0; inpuText = ""; return true; } void CursorTextField::initCursorSprite(const int mHeight) { // 初始化光标 const int column = 4; const int nHeight = (const int)mHeight; int pixels[25][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::createWithTexture(texture); CCSize winSize = getContentSize(); m_cursorPos = ccp(0, winSize.height / 2); m_pCursorSprite->setPosition(m_cursorPos); this->addChild(m_pCursorSprite); m_pCursorSprite->setVisible(false); 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 CursorTextField::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent)
{ m_beginPos = pTouch->getLocation(); return true; }
CCRect CursorTextField::getRect()
{ CCSize size = getContentSize(); return CCRectMake(0, -size.height / 2, inputFrameWidth, size.height); }
//获取输入框内容
const char* CursorTextField::getInputText(){ const char* text = m_pInputText->c_str(); return text; }
//设置输入框内容
void CursorTextField::setInpuntText(char* text){ *m_pInputText = ""; setString(text); m_pCursorSprite->setPositionX(0); CC_SAFE_DELETE_ARRAY(codeNumType); codeNumType = new int[50]; codeCur = 0; startCur = 0; endCur = 0; inpuText = ""; }
//设置输入框宽度 一旦字符串宽度超度这个长度 字符串会自动向左缩进
void CursorTextField::setInputWidth(float width){ this->inputFrameWidth = width; }
//设置输入宽显示的最大字符数量Unicode
void CursorTextField::setInputMaxLength(float length){ this->inputMaxLength = length; }
//判断点击事件,是否响应在输入框范围内
bool CursorTextField::isInTextField(cocos2d::CCTouch *pTouch) { return getRect().containsPoint(convertTouchToNodeSpaceAR(pTouch)); }
void CursorTextField::ccTouchEnded(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent)
{ CCPoint endPos = pTouch->getLocation(); // 判断是否为点击事件 if (::abs(endPos.x - m_beginPos.x) > DELTA || ::abs(endPos.y - m_beginPos.y)) { // 不是点击事件 m_beginPos.x = m_beginPos.y = -1; return; }
// 判断是打开输入法还是关闭输入法
isInTextField(pTouch) ? openIME() : closeIME(); }
//弹出手机键盘时响应事件
bool CursorTextField::onTextFieldAttachWithIME(cocos2d::CCTextFieldTTF *pSender) { if (m_pInputText->empty()) { return false; } m_pCursorSprite->setPositionX(getContentSize().width); return false; }
//当有输入进来时响应
//@param pSender 发送事件对象 //@param text 输入内容 //@param 内容字节长度 bool CursorTextField::onTextFieldInsertText(cocos2d::CCTextFieldTTF *pSender, const char *text,
int nLen)
{ std::string sText = m_pInputText->c_str(); wchar_t* wText = new wchar_t[200]; char t[200]; memset(t,0,200); strcpy(t,sText.c_str()); //将字符串转换为Unicode,并返回Unicode字符数量 int cou = Utf82Unicode(wText,200,t,sText.length()); //当字符数量超过规定值 不做处理 if(cou >= inputMaxLength) return true; //屏蔽回车输入 if(text[0] == '\n') return true; //输入框总内容添加 m_pInputText->append(text);
//测试
CCLabelTTF* ttf = CCLabelTTF::create(text,"Verdana-Bold",26); float teWidth = ttf->getContentSize().width; CCLOG("any code length---%f",teWidth);
//输入框当前字符串添加
inpuText.append(text); //当前字符的长度 codeNumType[codeCur++] = nLen; std::string* localText = m_pInputText; setString(m_pInputText->c_str()); //如果总字符串的长度大于指定宽度 if(getContentSize().width > inputFrameWidth){ //大于,截取字符串,直到字符串的长度小于指定宽度为止 setString(inpuText.c_str()); while(getContentSize().width > inputFrameWidth){ int nnLen = nLen; if(codeNumType[startCur] == 1){ nnLen = 1; } if(codeNumType[startCur] == 3){ nnLen = 3; } startCur++; nLenCount += nnLen; float gap = localText->size() - nLenCount; inpuText = localText->substr(nLenCount,gap); setString(inpuText.c_str()); float coWidth = getContentSize().width; } } else{ //小于,直接设置显示总字符串 nLenCount = 0; startCur = 0; setString(m_pInputText->c_str()); } //设置光标位置 m_pCursorSprite->setPositionX(getContentSize().width); CC_SAFE_DELETE_ARRAY(wText); return true; } //当有输入进来时响应 //@param pSender 发送事件对象 //@param text 删除内容 //@param 内容字节长度 bool CursorTextField::onTextFieldDeleteBackward(cocos2d::CCTextFieldTTF *pSender, const char
*delText, int nLen)
{ //将总字符串长度减去nLen字节长 m_pInputText->resize(m_pInputText->size() - nLen); //当前字符数减一 codeNumType[codeCur--] = 0; std::string* localText = m_pInputText; setString(m_pInputText->c_str()); if(getContentSize().width > inputFrameWidth){ //大于指定宽度,截取字符串,直到字符串长度小于指定宽度 while(getContentSize().width > inputFrameWidth){ int nnLen = nLen; if(codeNumType[startCur - 1] == 1){ nnLen = 1; } if(codeNumType[startCur - 1] == 3){ nnLen = 3; } nLenCount -= nnLen; startCur--; if(startCur <=0) startCur = 0; if(nLenCount <=0 ) nLenCount = 0; float gap = localText->size() - nLenCount; const std::string text = localText->substr(nLenCount,gap); setString(text.c_str()); inpuText = text; } } else{ nLenCount = 0; startCur = 0; setString(m_pInputText->c_str()); } //设置光标位置 m_pCursorSprite->setPositionX(getContentSize().width); if (m_pInputText->empty()) { m_pCursorSprite->setPositionX(0); }
return true;
}
bool CursorTextField::onTextFieldDetachWithIME(cocos2d::CCTextFieldTTF *pSender)
{ return false; }
void CursorTextField::openIME()
{ m_pCursorSprite->setVisible(true); this->attachWithIME(); }
void CursorTextField::closeIME()
{ m_pCursorSprite->setVisible(false); this->detachWithIME(); }
void CursorTextField::onExit()
{ CCTextFieldTTF::onExit(); CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this); } int CursorTextField::Utf82Unicode(LPWSTR out, int outsize , LPSTR in,int insize) {
//-------------------------------------------------------------------------------------------
//参数有效性判断 if(out == NULL || in == NULL || insize<0) { return -1; } int typeCount = 0; int totalNum = 0; char *p = in; for(int i=0;i<insize;i++) { if (*p >= 0x00 && *p <= 0x7f)//说明最高位为'0',这意味着utf8编码只有1个字节! { p++; totalNum += 1; } else if ((*p & (0xe0))== 0xc0)//只保留最高三位,看最高三位是不是110,如果是则意味着utf8
编码有2个字节!
{ p++; p++; totalNum += 1; } else if ((*p & (0xf0))== 0xe0)//只保留最高四位,看最高三位是不是1110,如果是则意味着
utf8编码有3个字节!
{ p++; p++; p++; totalNum += 1; } } if( outsize < totalNum )//参数有效性判断! { return -1; } //------------------------------------------------ int resultsize = 0; p = in; char* tmp = (char *)out; while(*p) { if (*p >= 0x00 && *p <= 0x7f)//说明最高位为'0',这意味着utf8编码只有1个字节! { *tmp = *p; tmp++; //*tmp = '/0'; tmp++; resultsize += 1; } else if ((*p & 0xe0)== 0xc0)//只保留最高三位,看最高三位是不是110,如果是则意味着
utf8编码有2个字节!
{ wchar_t t = 0; char t1 = 0; char t2 = 0; t1 = *p & (0x1f);//高位的后5位!(去除了头部的110这个标志位) p++; t2 = *p & (0x3f);//低位的后6位!(去除了头部的10这个标志位) *tmp = t2 | ((t1 & (0x03)) << 6); tmp++; *tmp = t1 >> 2;//留下其保留的三位 tmp++; resultsize += 1; } else if ((*p & (0xf0))== 0xe0)//只保留最高四位,看最高三位是不是1110,如果是则意味
着utf8编码有3个字节!
{ wchar_t t = 0; wchar_t t1 = 0; wchar_t t2 = 0; wchar_t t3 = 0; t1 = *p & (0x1f); p++; t2 = *p & (0x3f); p++; t3 = *p & (0x3f); *tmp = ((t2 & (0x03)) << 6) | t3; tmp++; *tmp = (t1 << 4) | (t2 >> 2); tmp++; resultsize += 1; } p++; } /*不考虑结束符,如果考虑则打开此段! *tmp = '/0'; tmp++; *tmp = '/0'; resultsize += 2; */ return resultsize; }
希望能为需要的朋友解决问题,
如果还不能解决可以联系QQ897703027,email: hongjiandao@163.com 欢迎大家交流cocos2d-x,C++等各方面的知识,或者创业团队求收留,本人目前在做cocos2dx 网游 |
聊天输入框 (单行输入框
最新推荐文章于 2025-02-20 19:18:32 发布