转自:http://blog.csdn.net/we000636/article/details/8829172
聊天输入框 (单行输入框 ,多行可自己扩展)
实现功能:
1.普通输入
2.设置输入框显示最大宽度(PT值,cocos2d-x坐标值)
3.设置输入框允许的最大字符数量(字符Unicode)
4.输入框自动缩进(当输入字符串数量超过显示框最大宽度时,会自动向左缩进,显示最新字符串
输入框实现代码
头文件:
-
#ifndefCursorInputDemo_CursorTextField_h
-
#defineCursorInputDemo_CursorTextField_h
-
-
#include"cocos2d.h"
-
-
USING_NS_CC;
-
-
classCursorTextField:publicCCTextFieldTTF,publicCCTextFieldDelegate,publicCCTouchDelegate
-
{
-
private:
-
-
CCPointm_beginPos;
-
-
CCSprite*m_pCursorSprite;
-
-
CCAction*m_pCursorAction;
-
-
CCPointm_cursorPos;
-
-
floatinputFrameWidth;
-
-
floatinputMaxLength;
-
intnLenCount;
-
int*codeNumType;
-
intcodeCur;
-
intstartCur;
-
intendCur;
-
-
std::string*m_pInputText;
-
std::stringinpuText;
-
public:
-
CursorTextField();
-
~CursorTextField();
-
-
staticCursorTextField*textFieldWithPlaceHolder(constchar*placeholder,constchar*fontName,floatfontSize);
-
-
voidonEnter();
-
voidonExit();
-
boolinit();
-
-
voidinitCursorSprite(intnHeight);
-
-
-
virtualboolonTextFieldAttachWithIME(CCTextFieldTTF*pSender);
-
virtualboolonTextFieldDetachWithIME(CCTextFieldTTF*pSender);
-
virtualboolonTextFieldInsertText(CCTextFieldTTF*pSender,constchar*text,intnLen);
-
virtualboolonTextFieldDeleteBackward(CCTextFieldTTF*pSender,constchar*delText,intnLen);
-
-
-
boolccTouchBegan(CCTouch*pTouch,CCEvent*pEvent);
-
voidccTouchEnded(CCTouch*pTouch,CCEvent*pEvent);
-
-
-
boolisInTextField(CCTouch*pTouch);
-
-
CCRectgetRect();
-
-
-
voidopenIME();
-
-
voidcloseIME();
-
-
constchar*getInputText();
-
voidsetInpuntText(char*text);
-
voidsetInputWidth(floatwidth);
-
voidsetInputMaxLength(floatlength);
-
-
intUtf82Unicode(LPWSTRout,intoutsize,LPSTRin,intinsize);
-
};
-
-
#endif
cpp文件:
-
#include"CursorTextField.h"
-
-
conststaticfloatDELTA=0.5f;
-
-
usingnamespacecocos2d;
-
usingnamespacestd;
-
-
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);
-
}
-
-
voidCursorTextField::onEnter()
-
{
-
CCTextFieldTTF::onEnter();
-
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,0,false);
-
this->setDelegate(this);
-
}
-
-
CursorTextField*CursorTextField::textFieldWithPlaceHolder(constchar*placeholder,constchar*fontName,floatfontSize)
-
{
-
CursorTextField*pRet=newCursorTextField();
-
if(pRet&&pRet->initWithString("",fontName,fontSize))
-
{
-
pRet->autorelease();
-
if(placeholder)
-
{
-
pRet->setPlaceHolder(placeholder);
-
}
-
pRet->init();
-
pRet->initCursorSprite(fontSize);
-
pRet->setHorizontalAlignment(kCCTextAlignmentLeft);
-
returnpRet;
-
}
-
CC_SAFE_DELETE(pRet);
-
returnNULL;
-
}
-
-
boolCursorTextField::init(){
-
this->inputFrameWidth=400;
-
this->inputMaxLength=38;
-
this->nLenCount=0;
-
this->codeNumType=newint[50];
-
this->codeCur=0;
-
this->startCur=0;
-
this->endCur=0;
-
inpuText="";
-
returntrue;
-
}
-
voidCursorTextField::initCursorSprite(constintmHeight)
-
{
-
-
constintcolumn=4;
-
constintnHeight=(constint)mHeight;
-
intpixels[25][column];
-
for(inti=0;i<nHeight;++i){
-
for(intj=0;j<column;++j){
-
pixels[i][j]=0xffffffff;
-
}
-
}
-
CCTexture2D*texture=newCCTexture2D();
-
texture->initWithData(pixels,kCCTexture2DPixelFormat_RGB888,1,1,CCSizeMake(column,nHeight));
-
m_pCursorSprite=CCSprite::createWithTexture(texture);
-
CCSizewinSize=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=newstd::string();
-
}
-
-
boolCursorTextField::ccTouchBegan(cocos2d::CCTouch*pTouch,cocos2d::CCEvent*pEvent)
-
{
-
m_beginPos=pTouch->getLocation();
-
returntrue;
-
}
-
-
CCRectCursorTextField::getRect()
-
{
-
CCSizesize=getContentSize();
-
returnCCRectMake(0,-size.height/2,inputFrameWidth,size.height);
-
}
-
-
-
constchar*CursorTextField::getInputText(){
-
constchar*text=m_pInputText->c_str();
-
returntext;
-
}
-
-
-
voidCursorTextField::setInpuntText(char*text){
-
*m_pInputText="";
-
setString(text);
-
m_pCursorSprite->setPositionX(0);
-
CC_SAFE_DELETE_ARRAY(codeNumType);
-
codeNumType=newint[50];
-
codeCur=0;
-
startCur=0;
-
endCur=0;
-
inpuText="";
-
}
-
-
-
voidCursorTextField::setInputWidth(floatwidth){
-
this->inputFrameWidth=width;
-
}
-
-
-
voidCursorTextField::setInputMaxLength(floatlength){
-
this->inputMaxLength=length;
-
}
-
-
-
boolCursorTextField::isInTextField(cocos2d::CCTouch*pTouch)
-
{
-
returngetRect().containsPoint(convertTouchToNodeSpaceAR(pTouch));
-
}
-
-
voidCursorTextField::ccTouchEnded(cocos2d::CCTouch*pTouch,cocos2d::CCEvent*pEvent)
-
{
-
CCPointendPos=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();
-
}
-
-
-
boolCursorTextField::onTextFieldAttachWithIME(cocos2d::CCTextFieldTTF*pSender)
-
{
-
if(m_pInputText->empty()){
-
returnfalse;
-
}
-
m_pCursorSprite->setPositionX(getContentSize().width);
-
returnfalse;
-
}
-
-
-
-
-
-
boolCursorTextField::onTextFieldInsertText(cocos2d::CCTextFieldTTF*pSender,constchar*text,intnLen)
-
{
-
std::stringsText=m_pInputText->c_str();
-
wchar_t*wText=newwchar_t[200];
-
chart[200];
-
memset(t,0,200);
-
strcpy(t,sText.c_str());
-
-
intcou=Utf82Unicode(wText,200,t,sText.length());
-
-
if(cou>=inputMaxLength)returntrue;
-
-
if(text[0]=='\n')
-
returntrue;
-
-
m_pInputText->append(text);
-
-
-
CCLabelTTF*ttf=CCLabelTTF::create(text,"Verdana-Bold",26);
-
floatteWidth=ttf->getContentSize().width;
-
CCLOG("anycodelength---%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){
-
intnnLen=nLen;
-
if(codeNumType[startCur]==1){
-
nnLen=1;
-
}
-
if(codeNumType[startCur]==3){
-
nnLen=3;
-
}
-
startCur++;
-
nLenCount+=nnLen;
-
floatgap=localText->size()-nLenCount;
-
inpuText=localText->substr(nLenCount,gap);
-
setString(inpuText.c_str());
-
floatcoWidth=getContentSize().width;
-
}
-
}
-
else{
-
-
nLenCount=0;
-
startCur=0;
-
setString(m_pInputText->c_str());
-
}
-
-
m_pCursorSprite->setPositionX(getContentSize().width);
-
CC_SAFE_DELETE_ARRAY(wText);
-
returntrue;
-
}
-
-
-
-
-
-
-
boolCursorTextField::onTextFieldDeleteBackward(cocos2d::CCTextFieldTTF*pSender,constchar*delText,intnLen)
-
{
-
-
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){
-
intnnLen=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;
-
floatgap=localText->size()-nLenCount;
-
conststd::stringtext=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);
-
}
-
-
returntrue;
-
}
-
-
boolCursorTextField::onTextFieldDetachWithIME(cocos2d::CCTextFieldTTF*pSender)
-
{
-
returnfalse;
-
}
-
-
voidCursorTextField::openIME()
-
{
-
m_pCursorSprite->setVisible(true);
-
this->attachWithIME();
-
}
-
-
voidCursorTextField::closeIME()
-
{
-
m_pCursorSprite->setVisible(false);
-
this->detachWithIME();
-
}
-
-
voidCursorTextField::onExit()
-
{
-
CCTextFieldTTF::onExit();
-
CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
-
}
-
intCursorTextField::Utf82Unicode(LPWSTRout,intoutsize,LPSTRin,intinsize)
-
{
-
-
-
if(out==NULL||in==NULL||insize<0)
-
{
-
return-1;
-
}
-
inttypeCount=0;
-
inttotalNum=0;
-
char*p=in;
-
for(inti=0;i<insize;i++)
-
{
-
if(*p>=0x00&&*p<=0x7f)
-
{
-
p++;
-
totalNum+=1;
-
}
-
elseif((*p&(0xe0))==0xc0)
-
{
-
p++;
-
p++;
-
totalNum+=1;
-
}
-
elseif((*p&(0xf0))==0xe0)
-
{
-
p++;
-
p++;
-
p++;
-
totalNum+=1;
-
}
-
}
-
if(outsize<totalNum)
-
{
-
return-1;
-
}
-
-
intresultsize=0;
-
-
p=in;
-
char*tmp=(char*)out;
-
while(*p)
-
{
-
if(*p>=0x00&&*p<=0x7f)
-
{
-
*tmp=*p;
-
tmp++;
-
-
tmp++;
-
resultsize+=1;
-
}
-
elseif((*p&0xe0)==0xc0)
-
{
-
wchar_tt=0;
-
chart1=0;
-
chart2=0;
-
-
t1=*p&(0x1f);
-
p++;
-
t2=*p&(0x3f);
-
-
*tmp=t2|((t1&(0x03))<<6);
-
tmp++;
-
*tmp=t1>>2;
-
tmp++;
-
resultsize+=1;
-
}
-
elseif((*p&(0xf0))==0xe0)
-
{
-
wchar_tt=0;
-
wchar_tt1=0;
-
wchar_tt2=0;
-
wchar_tt3=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;
-
*/
-
returnresultsize;
-
}
上面代码是通是UTF-8转Unicode来获取字符数量。当输入字符数量过多时,可能字节大小会超过声明的char数组大小,导致出现越界情况,程序崩溃。
解决方法一:根据限定字符数量,将char数组大小声明为最大数量,来避免越界情况出生
解决方法二:定义一个私有变量unicodeCount(名字随意取)来记录输入字符的总数量。由于onTextFieldInsertText,onTextFieldDeleteBackward这两个方法都是在我们输入一个完整字符或者减去一个完整字符时调用一次,所以将unicodeCount++放入onTextFieldInsertText,将unicodeCount--放入onTextFieldDeleteBackward中,可以完成输入字符数量的保存。这样就可以免去UTF-8转Unicode的操作,完全避免越界情况产生,也提高了效率
效率方面尚未优化,请参考自行优化,只提供一个解决思路
接下来将会写一篇光于cocos2d-普通文本显示框,不支持富文本,主要提供自动换行解决思路,以解决当前CCLabelTTF自动换行Bug的替代方案
分享到:
相关推荐
cocos2d-x输入框 点九图 VS2010 cocos2d-x v2.2.0
封装cocos2d-x中的CCTextFieldTTF为带光标的输入框
cocosBuilder3.0beta for cocos2d-x,含CCEditBox和CCTexTFieldTTF两个插件,插件在完善中.
主要介绍了Cocos2d-x中CCEditBox文本输入框的使用实例,本文在代码中用大量注释讲解了CCEditBox的使用方法,需要的朋友可以参考下
输入框cocos2d-x 2.1.4 的另一个编辑框cocos2d-x的CCEditbox不完善,LLInputBox也不完善但是 LLInputBox 提供光标,最大大小限制(超出部分将被隐藏)。 将项目放入cocos2d的项目中为: .../cocos2d-x-2.1.4/...
Cocos2d-x的学习之旅(六)输入框-附件资源
cocos2d下的多行输入框,带光标,包括自动换行后光标正确的位置,包括了在光标位置的插入和删除.和我们发送短信是一样的.可以从中间插入删除.
EditBox4Cocos2dx 修改了IOS版本的Editbox。 现在它看起来应该更高端一些,事实上,大部分游戏也用的这个风格。 直接下载覆盖项目里边的就成 Path:cocos2d/cocos/ui/UIEditBox
Android移动开发实例包002是学习Android开发的利器,...11、cocos2d-x带光标的输入框 12、Android中如何使用ViewPager实现类似 13、页面滑动切换demo 14、Android 滑动效果ViewFlipper 15、Android滑动菜单框架完全解析
只能输入数字的控件,限制字符,其它字符不能输入。
带触控的CCTextFieldTTf输入框,如果知道输入框的写法,然后又知道触控的写法的话,那理解更加容易。
带光标与触控的输入框,并且我也写了注册与登录功能, 虽然比较简陋,但是希望有帮助。