现在光标终于可移动了,然后其实主要是逻辑问题,也没什么技术含量,所以总是一大堆位置判断!再者自己能力比较水,所以代码比较挫,这里代码只有更新那部分,具体的回车什么的自己去弄就好了,其实跟这个思想差不多吧!个人觉得。
代码:
CursorTextField.h
#ifndef _CursorTextField_H_ #define _CursorTextField_H_ #include "cocos2d.h" USING_NS_CC; class CursorTextField : public TextFieldTTF,public TextFieldDelegate { private: // 点击开始位置 Point m_beginPos; // 光标精灵 Sprite * m_pCursorSprite; // 光标动画 Action *m_pCursorAction; // 光标坐标 Point m_cursorPos; //输入框长度 float inputFrameWidth; //允许输入的最大字符数Unicode float inputMaxLength; int m_Sprite_Posi = 0; // 输入框总内容 std::string m_pInputText; std::string inpuText; //当前输入框内容 int fontsize = 0; std::string fontName; int nowtextlenght = 0; void setTextPosi(std::string,bool is_add = true); public: CursorTextField(); ~CursorTextField(); static CursorTextField * getinstance(); // static static CursorTextField * textFieldWithPlaceHolder(cocos2d::Node * node,const char *placeholder,const char *fontName,float fontSize); // Layer void onEnter(); void onExit(); bool init(); // 初始化光标精灵 void initCursorSprite(int nHeight); virtual void setPositionX(Node *node,float x); // TextFieldDelegate virtual bool onTextFieldAttachWithIME(TextFieldTTF *pSender) override; virtual bool onTextFieldDetachWithIME(TextFieldTTF * pSender) override; virtual bool onTextFieldInsertText(cocos2d::TextFieldTTF* sender,const char * text,size_t nLen) override; virtual bool onTextFieldDeleteBackward(cocos2d::TextFieldTTF* sender,const char * delText,size_t nLen) override; virtual void setPosition(const Point& pos); virtual void setPosition(float &x,float &y); void setCursorPositionX(float x); // 设置光标x位置 // 把光标添加到和输入框一起的层中 void AddCursor(Node *node); // Layer Touch bool onTouchBegan(Touch *pTouch,Event *pEvent); void onTouchEnded(Touch *pTouch,Event *pEvent); void onKeyPressed(cocos2d::EventKeyboard::KeyCode,cocos2d::Event*); void onKeyReleased(cocos2d::EventKeyboard::KeyCode,cocos2d::Event*); // 判断是否点击在TextField处 bool isInTextField(Touch *pTouch); // 得到TextField矩形 Rect getRect(); // 打开输入法 void openIME(); // 关闭输入法 void closeIME(); std::string split_text(std::string name,int len,int start); const char* getInputText(); void setInpuntText(char* text); void setInputWidth(float width); void setInputMaxLength(float length); cocos2d::Node * parentNode; void BlickSpriteLeft(); void BlickSpriteRight(); void KeyDelete(); float getLabelWidth(std::string str,std::string fontName,float fontsize); int getPosifromText(std::string str,int posi); int getPosiformPosi(std::string str,float posi); void MyRemoveFromParent(); protected: EventListenerTouchOneByOne * listener; }; #endif
CursorTextField.cpp
#include "CursorTextField.h" #include "MyCharSet.h" #include "MyKeyInsert.h" const static float DELTA = 0.5f; using namespace cocos2d; using namespace std; static CursorTextField * _CursorTextField; CursorTextField::CursorTextField() { TextFieldTTF(); m_pCursorSprite = NULL; m_Sprite_Posi = 0; } CursorTextField::~CursorTextField() { } CursorTextField * CursorTextField::getinstance() { return _CursorTextField; } void CursorTextField::onEnter() { TextFieldTTF::onEnter(); listener = EventListenerTouchOneByOne::create(); listener->setSwallowTouches(true); listener->onTouchBegan = CC_CALLBACK_2(CursorTextField::onTouchBegan,this); listener->onTouchEnded = CC_CALLBACK_2(CursorTextField::onTouchEnded,this); Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraPHPriority(listener,this); KeyInsert::getinstence()->addKeyBordClick(this); this->setDelegate(this); } CursorTextField * CursorTextField::textFieldWithPlaceHolder(Node * node,float fontSize) { _CursorTextField = new (std::nothrow)CursorTextField(); _CursorTextField->parentNode = node; if (_CursorTextField && ((TextFieldTTF*)_CursorTextField)->initWithPlaceHolder(placeholder,fontName,fontSize)) { _CursorTextField->fontsize = fontSize; _CursorTextField->fontName = fontName; _CursorTextField->autorelease(); if (placeholder) { _CursorTextField->setPlaceHolder(placeholder); } _CursorTextField->init(); _CursorTextField->initCursorSprite(fontSize); _CursorTextField->setHorizontalAlignment(kCCTextAlignmentLeft); return _CursorTextField; } CC_SAFE_DELETE(_CursorTextField); return NULL; } bool CursorTextField::init(){ this->inputFrameWidth = 400; this->inputMaxLength = 16; inpuText = ""; return true; } void CursorTextField::initCursorSprite(const int mHeight) { int column = 2; int nHeight = 20; int pixels[50][2]; for (int i = 0; i < nHeight; ++i) { for (int j = 0; j < column; ++j) { pixels[i][j] = 0xffffffff; } } Texture2D* texture = new Texture2D(); texture->initWithData(pixels,20,Texture2D::PixelFormat::RGB888,4,mHeight,CCSizeMake(column,nHeight)); m_pCursorSprite = Sprite::createWithTexture(texture); texture->autorelease(); if (m_pCursorSprite == nullptr) { CCLOG("NULL"); } //m_pCursorSprite->setColor(Color3B(255,0)); Size winSize = getContentSize(); m_pCursorSprite->setVisible(false); parentNode->addChild(m_pCursorSprite); m_pCursorAction = RepeatForever::create(Sequence::create(FadeOut::create(0.25f),FadeIn::create(0.25f),NULL)); m_pCursorSprite->runAction(m_pCursorAction); //m_pInputText = new std::string(); } void CursorTextField::setPositionX(Node * node,float x) { int i = 0; int count = 0; float width = 0.0; std::string str; if (m_Sprite_Posi <= 0) { width = 0.0; m_Sprite_Posi = 0; } else { std::string ss; for (i = 0; i < inpuText.size();) { ss = split_text(inpuText,1,i); i += ss.length(); str.append(ss); count++; if (count == m_Sprite_Posi) { break; } } width = getLabelWidth(str,_CursorTextField->fontName,_CursorTextField->fontsize); } width += x; node->setPositionX(width); } void CursorTextField::setPosition(float &x,float &y) { Point posi(x,y); setPosition(posi); } void CursorTextField::setPosition(const Point& pos) { TextFieldTTF::setPosition(pos); // 设置光标位置 if (NULL != m_pCursorSprite) { Size winSize = getContentSize(); m_cursorPos = ccp(0,0/*winSize.height / 2*/); m_cursorPos = m_cursorPos + pos; m_pCursorSprite->setPosition(m_cursorPos.x + m_pCursorSprite->getContentSize().width,m_cursorPos.y + m_pCursorSprite->getContentSize().height / 2.0); } } void CursorTextField::setCursorPositionX(float x) // 设置光标x位置 { Point pt = getPosition(); // 获取输入框位置 x += pt.x; setPositionX(m_pCursorSprite,x); } // 把光标添加到和输入框一起的层中 void CursorTextField::AddCursor(Node *node) { if (NULL != node && NULL != m_pCursorSprite) { node->addChild(m_pCursorSprite); m_pCursorSprite->setPositionY(getContentSize().height / 2.0); m_pCursorSprite->runAction(m_pCursorAction); } } bool CursorTextField::onTouchBegan(cocos2d::Touch *pTouch,cocos2d::Event *pEvent) { m_beginPos = pTouch->getLocation(); return true; } Rect CursorTextField::getRect() { Size check; check.width = fontsize; Size size = getContentSize() + check; 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); setPositionX(m_pCursorSprite,this->getPosition().x); inpuText = ""; } //设置输入框宽度 一旦字符串宽度超度这个长度 字符串会自动向左缩进 void CursorTextField::setInputWidth(float width){ this->inputFrameWidth = width; } //设置输入宽显示的最大字符数量Unicode void CursorTextField::setInputMaxLength(float length){ this->inputMaxLength = length; } //判断点击事件,是否响应在输入框范围内 bool CursorTextField::isInTextField(cocos2d::Touch *pTouch) { return getRect().containsPoint(convertTouchToNodeSpaceAR(pTouch)); } void CursorTextField::onTouchEnded(cocos2d::Touch *pTouch,cocos2d::Event *pEvent) { Point 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(); if (m_pCursorSprite->isVisible()) { //开始所在字节 int len = getPosiformPosi(inpuText,m_pCursorSprite->getPositionX()); //结束所在的字节 int endlen = getPosiformPosi(inpuText,endPos.x); m_pCursorSprite->setPositionX(this->getPositionX() + getLabelWidth(inpuText.substr(0,endlen),fontsize)); int i = 0; int count = 0; //点了前面,mposi减去字符 if (len > endlen) { count = 0; for (i = endlen; i < len;) { std::string temp = split_text(inpuText,i); count++; i += temp.length(); } m_Sprite_Posi -= count; } //原来位置 else if (len == endlen) { } //点了后面,mposi加上字符 else { count = 0; for (i = len; i < endlen;) { std::string temp = split_text(inpuText,i); count++; i += temp.length(); } m_Sprite_Posi += count; } } } //弹出手机键盘时响应事件 bool CursorTextField::onTextFieldAttachWithIME(cocos2d::TextFieldTTF *pSender) { if (m_pInputText.empty()) { return false; } //setPositionX(m_pCursorSprite,this->getPosition().x); return false; } //当有输入进来时响应 //@param pSender 发送事件对象 //@param text 输入内容 //@param 内容字节长度 bool CursorTextField::onTextFieldInsertText(cocos2d::TextFieldTTF* sender,size_t nLen) { //log("OUT ==== %s =Length= %d",text,nLen); int j = 0 ; std::string mytext = text; for (j = 0; j < mytext.size();) { std::string sText = m_pInputText.c_str(); wchar_t* wText = new wchar_t[200]; char t[200]; memset(t,sizeof(t)); strcpy(t,sText.c_str()); int unisize = 0; int codenum = MyCharSet::getinstence()->utf8_to_unicode((uint8_t*)t,(uint16_t **)wText,&unisize); //当字符数量超过规定值 不做处理 if (codenum >= inputMaxLength && inputMaxLength != 0) { codenum = inputMaxLength; CC_SAFE_DELETE_ARRAY(wText); return true; } nowtextlenght++; std::string ss = split_text(mytext,j); j += ss.length(); //屏蔽回车输入 if (ss == "\n") { CC_SAFE_DELETE_ARRAY(wText); continue; } std::string mmss = ""; std::string mystr; int i = 0; //根据字符位置插入 if (m_Sprite_Posi != 0) { int count = 0; for (i = 0; i < m_pInputText.size();) { mmss = split_text(m_pInputText,i); i += mmss.length(); mystr.append(mmss); count++; if (count == m_Sprite_Posi) { break; } } } //字符位置相加 m_Sprite_Posi++; mystr.append(ss); mystr.append(m_pInputText.substr(i)); //输入框总内容就是两个相加 m_pInputText.clear(); //inpuText.clear(); m_pInputText.append(mystr); //inpuText.append(mystr); //输入框当前字符串添加 //inpuText.append(ss); setTextPosi(ss,true); CC_SAFE_DELETE_ARRAY(wText); //AndroidShowtext(mychar,1); } return true; } //当有输入进来时响应 //@param pSender 发送事件对象 //@param text 删除内容 //@param 内容字节长度 bool CursorTextField::onTextFieldDeleteBackward(cocos2d::TextFieldTTF* sender,size_t nLen) { std::string ss; if (m_Sprite_Posi != 0) { int i = 0; int count = 0; for (i = 0; i < m_pInputText.size();) { ss = split_text(m_pInputText,i); i += ss.length(); count++; if (count == m_Sprite_Posi) { m_pInputText.erase(i - ss.length(),ss.length()); //inpuText.erase(i - ss.length(),ss.length()); break; } } } //字符位置减1 m_Sprite_Posi--; //m_pInputText.resize(m_pInputText.size() - nLen); if (m_pInputText.size() <= 0) { m_Sprite_Posi = 0; } if (m_Sprite_Posi < 0) { m_Sprite_Posi = 0; } setTextPosi(ss,false); return true; } void CursorTextField::setTextPosi(std::string ss,bool is_add) { if (inputFrameWidth <= 0) { inputFrameWidth = _CursorTextField->inputFrameWidth; } if (!is_add) { if (m_pInputText.empty()) { m_Sprite_Posi = 0; m_pCursorSprite->setPositionX(m_pCursorSprite->getPositionX() - getLabelWidth(ss,fontsize)); setString(""); inpuText.clear(); return; } std::string localText = inpuText; int i = getPosifromText(m_pInputText,m_Sprite_Posi); int inlength = getPosiformPosi(inpuText,m_pCursorSprite->getPositionX()); if (inlength == 0) { return; } std::string mystr; std::string instr; if (i >= inlength) { int reposi = i - inlength; for (i = 0; i < m_pInputText.length();) { std::string temp = split_text(m_pInputText,i); if (i <= reposi && reposi < temp.length() + i) { break; } else { i += temp.length(); } } mystr = m_pInputText.substr(i,1); if (!mystr.empty()) { if (mystr[0] < 0) { mystr = m_pInputText.substr(i,3); } else { mystr = m_pInputText.substr(i,1); } } } //当前输入框剔除 std::string deletestr; if (inlength - 3 >= 0) { int reposi = inlength; for (i = 0; i < inpuText.length();) { std::string temp = split_text(inpuText,i); if (i <= reposi && reposi <= temp.length() + i) { break; } else { i += temp.length(); } } deletestr = inpuText.substr(i,3); if (deletestr[0] < 0) { inpuText.erase(inlength - 3,3); } else if (!deletestr.empty()) { deletestr = inpuText.substr(inlength - 1,1); inpuText.erase(inlength - 1,1); } //log("%s %s",inpuText.c_str(),deletestr.c_str()); } else { deletestr = inpuText.substr(0,1); } } if (mystr.empty()) { instr = m_pInputText.substr(inpuText.length(),1); if (!instr.empty()) { if (instr[0] < 0) { instr = m_pInputText.substr(inpuText.length(),3); } else { //instr.erase(1,2); instr = m_pInputText.substr(inpuText.length(),1); } } inpuText.append(instr); } std::string lastins = mystr; mystr.append(inpuText); inpuText = mystr; if (lastins.empty()) { m_pCursorSprite->setPositionX(m_pCursorSprite->getPositionX() - getLabelWidth(deletestr,fontsize)); } else if (!instr.empty()) { float reposi = getLabelWidth(deletestr,fontsize) - getLabelWidth(instr,fontsize); m_pCursorSprite->setPositionX(m_pCursorSprite->getPositionX() + reposi); } else if (!lastins.empty()) { float reposi = getLabelWidth(lastins,fontsize) - getLabelWidth(deletestr,fontsize); m_pCursorSprite->setPositionX(m_pCursorSprite->getPositionX() + reposi); } setString(inpuText); } else { std::string localText = m_pInputText; setString(m_pInputText); //如果总字符串的长度大于指定宽度 if (getLabelWidth(m_pInputText,fontsize) > inputFrameWidth){ int inlength = getPosiformPosi(inpuText,m_pCursorSprite->getPositionX()); //光标在0处,需要获取到当前输入框最后一个字符,if (inlength == 0) { std::string mystr = ss; mystr.append(inpuText); inpuText = mystr; std::string str = inpuText.substr(inpuText.length() - 1); if (str[0] < 0) { inpuText.resize(inpuText.length() - 3); } else { inpuText.resize(inpuText.length() - 1); } setString(inpuText); m_pCursorSprite->setPositionX(m_pCursorSprite->getPositionX() + getLabelWidth(ss,fontsize)); return; } //光标在末尾,需要获取第一个字符 else if (inlength == inpuText.length()) { inpuText.append(ss); std::string str = inpuText.substr(0,3); if (str[0] < 0) { inpuText.erase(0,3); } else { str.erase(1,2); inpuText.erase(0,1); } setString(inpuText); float x = getLabelWidth(str,fontsize) - getLabelWidth(ss,fontsize); m_pCursorSprite->setPositionX(m_pCursorSprite->getPositionX() - x); return; } //在字符两段切割 std::string last = inpuText.substr(0,inlength); std::string next = inpuText.substr(inlength); //字符相连 inpuText = last; inpuText.append(ss); inpuText.append(next); std::string temp = inpuText.substr(0,3); if (temp[0] < 0 ) { inpuText.erase(0,3); } else { inpuText.erase(0,1); temp = inpuText.substr(0,1); } float reposi = getLabelWidth(ss,fontsize) - getLabelWidth(temp,fontsize); m_pCursorSprite->setPositionX(m_pCursorSprite->getPositionX() + reposi); setString(inpuText); } else{ //小于,直接设置显示总字符串 int startCur = 0; setString(m_pInputText); inpuText = m_pInputText; std::string showinput; for (int j = 0; j < m_pInputText.size();) { std::string nowstr = split_text(m_pInputText,j); showinput.append(nowstr); j += nowstr.length(); startCur++; if (startCur == m_Sprite_Posi) { break; } } startCur = 0; m_pCursorSprite->setPositionX(this->getPosition().x + getLabelWidth(showinput,fontsize)); } //设置光标位置 //setPositionX(m_pCursorSprite,this->getPosition().x); } } bool CursorTextField::onTextFieldDetachWithIME(cocos2d::TextFieldTTF *pSender) { return false; } void CursorTextField::openIME() { m_pCursorSprite->setVisible(true); #if ( CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) setString(m_pInputText); #endif ((TextFieldTTF *)this)->attachWithIME(); } void CursorTextField::closeIME() { m_pCursorSprite->setVisible(false); //auto pTextField = (TextFieldTTF *)pRet; ((TextFieldTTF *)this)->detachWithIME(); } void CursorTextField::onExit() { TextFieldTTF::onExit(); Director::getInstance()->getEventDispatcher()->removeEventListener(listener); KeyInsert::getinstence()->destoryinstence(); } //根据位置分割字符,并返回字符 std::string CursorTextField::split_text(std::string name,int start) { int i = start; std::string str; if (name[i] < 0) { i++; } if (start == i) { str = name.substr(start,1); } else { str = name.substr(start,3); } //log("mysubstr %s",str.c_str()); return str; } //向左移 void CursorTextField::BlickSpriteLeft() { if (!_CursorTextField->m_pCursorSprite->isVisible()) { return; } float posix = _CursorTextField->m_pCursorSprite->getPosition().x; float contextsizeposi = _CursorTextField->m_pCursorSprite->getContentSize().width / 2; float parentposi = _CursorTextField->getPosition().x; std::string str; //光标已在输入框最左边 if (posix - parentposi <= contextsizeposi) { if (_CursorTextField->m_pInputText == _CursorTextField->inpuText || _CursorTextField->m_Sprite_Posi == 0) { return; } int mlength = _CursorTextField->getPosifromText(_CursorTextField->m_pInputText,_CursorTextField->m_Sprite_Posi); //光标在所有字符的最左边 if (mlength <= 0) { return; } //选取光标前一个字符 str = _CursorTextField->m_pInputText.substr(mlength - 1,1); if (str[0] < 0) { str = _CursorTextField->m_pInputText.substr(mlength - 3,3); } std::string mystr = _CursorTextField->inpuText.substr(_CursorTextField->inpuText.length() - 1,1); //剔除最后一个字符 if (mystr[0] < 0) { _CursorTextField->inpuText.resize(_CursorTextField->inpuText.length() - 3); } else { _CursorTextField->inpuText.resize(_CursorTextField->inpuText.length() - 1); } //字符相加 str.append(_CursorTextField->inpuText); _CursorTextField->inpuText = str; _CursorTextField->setString(_CursorTextField->inpuText); } else { //只是移动 int nlength = _CursorTextField->getPosiformPosi(_CursorTextField->inpuText,_CursorTextField->m_pCursorSprite->getPositionX()); str = _CursorTextField->inpuText.substr(nlength - 1,1); if (str[0] < 0) { str = _CursorTextField->inpuText.substr(nlength - 3,3); } float nowposi = _CursorTextField->getLabelWidth(str,_CursorTextField->fontsize); _CursorTextField->m_pCursorSprite->setPositionX(_CursorTextField->m_pCursorSprite->getPositionX() - nowposi); } //光标所在所有字符中减一 _CursorTextField->m_Sprite_Posi--; if (_CursorTextField->m_Sprite_Posi < 0) { _CursorTextField->m_Sprite_Posi = 0; } } //向右与左类似 void CursorTextField::BlickSpriteRight() { if (!_CursorTextField->m_pCursorSprite->isVisible()) { return; } float posix = _CursorTextField->m_pCursorSprite->getPosition().x; float contextsizeposi = _CursorTextField->m_pCursorSprite->getContentSize().width / 2; float parentposi = _CursorTextField->getPosition().x + _CursorTextField->getLabelWidth(_CursorTextField->inpuText,_CursorTextField->fontsize); std::string str; if (posix + contextsizeposi >= parentposi) { if (_CursorTextField->m_pInputText == _CursorTextField->inpuText || _CursorTextField->m_Sprite_Posi >= _CursorTextField->nowtextlenght) { return; } int mlength = _CursorTextField->getPosifromText(_CursorTextField->m_pInputText,_CursorTextField->m_Sprite_Posi); if (mlength == _CursorTextField->m_pInputText.length()) { return; } str = _CursorTextField->m_pInputText.substr(mlength,1); if (str[0] < 0) { str = _CursorTextField->m_pInputText.substr(mlength,3); } std::string mystr = _CursorTextField->inpuText.substr(0,1); if (mystr[0] < 0) { mystr = _CursorTextField->inpuText.substr(0,3); _CursorTextField->inpuText.erase(0,3); } else { _CursorTextField->inpuText.erase(0,1); } _CursorTextField->inpuText.append(str); //位移差 float posix = getLabelWidth(str,_CursorTextField->fontsize) - getLabelWidth(mystr,_CursorTextField->fontsize); _CursorTextField->m_pCursorSprite->setPositionX(_CursorTextField->m_pCursorSprite->getPositionX() + posix); _CursorTextField->setString(_CursorTextField->inpuText); } else { int nlength = _CursorTextField->getPosiformPosi(_CursorTextField->inpuText,_CursorTextField->m_pCursorSprite->getPositionX()); str = _CursorTextField->inpuText.substr(nlength,1); if (str[0] < 0) { str = _CursorTextField->inpuText.substr(nlength,_CursorTextField->fontsize); _CursorTextField->m_pCursorSprite->setPositionX(_CursorTextField->m_pCursorSprite->getPositionX() + nowposi); } _CursorTextField->m_Sprite_Posi++; } void CursorTextField::KeyDelete() { if (!_CursorTextField->m_pCursorSprite->isVisible()) { return; } int nlength = _CursorTextField->getPosiformPosi(_CursorTextField->inpuText,_CursorTextField->m_pCursorSprite->getPositionX()); int mlength = _CursorTextField->getPosifromText(_CursorTextField->m_pInputText,_CursorTextField->m_Sprite_Posi); std::string inlast; std::string innext; std::string insMNext; std::string insMLast; if (mlength == _CursorTextField->m_pInputText.length()) { return; } std::string in_str = _CursorTextField->inpuText.substr(nlength,3); std::string im_str = _CursorTextField->m_pInputText.substr(mlength,3); if (in_str[0] < 0) { _CursorTextField->inpuText.erase(nlength,3); } else { _CursorTextField->inpuText.erase(nlength,1); } if (im_str[0] < 0) { _CursorTextField->m_pInputText.erase(mlength,3); } else { _CursorTextField->m_pInputText.erase(mlength,1); } insMNext = _CursorTextField->m_pInputText.substr(mlength + _CursorTextField->inpuText.length() - nlength,1); if (insMNext[0] >= 0) { insMNext = _CursorTextField->m_pInputText.substr(mlength + _CursorTextField->inpuText.length() - nlength,1); } else { insMNext = _CursorTextField->m_pInputText.substr(mlength + _CursorTextField->inpuText.length() - nlength,3); } if (insMNext.empty() && mlength != nlength) { if (mlength - nlength - 3 < 0) { insMLast = _CursorTextField->m_pInputText.substr(mlength - nlength - 1,1); } else { int lenposi = mlength - nlength; int i; for (i = 0; i < _CursorTextField->m_pInputText.length();) { std::string temp = _CursorTextField->split_text(_CursorTextField->m_pInputText,i); if (i <= lenposi && lenposi < i + temp.length()) { break; } i += temp.length(); } lenposi = i; insMLast = _CursorTextField->m_pInputText.substr(lenposi - 3,3); if (insMLast[2] >= 0) { insMLast = _CursorTextField->m_pInputText.substr(lenposi - 1,1); } } } std::string myallstr; myallstr.append(insMLast); myallstr.append(_CursorTextField->inpuText); myallstr.append(insMNext); _CursorTextField->inpuText = myallstr; _CursorTextField->setString(_CursorTextField->inpuText); if (!insMLast.empty()) { _CursorTextField->m_pCursorSprite->setPositionX(_CursorTextField->m_pCursorSprite->getPositionX() + _CursorTextField->getLabelWidth(insMLast,_CursorTextField->fontsize)); } } //根据string获取字符宽度 float CursorTextField::getLabelWidth(std::string str,float fontsize) { if (str.empty()) { return 0; } LabelTTF * label = LabelTTF::create(str,fontsize); float nowposi = label->getContentSize().width; return nowposi; } //根据字符位置返回字节位置 int CursorTextField::getPosifromText(std::string str,int posi) { int count = 0; int i; for (i = 0; i < str.length();) { std::string mystr = split_text(str,i); i += mystr.length(); count++; if (count == posi) { return i; } } return 0; } //根据坐标位置返回字节位置 int CursorTextField::getPosiformPosi(std::string str,float posi) { std::string mystr; std::string temp; float parentPosi = this->getPositionX(); float reposi = posi - parentPosi; if (parentPosi + getLabelWidth(str,fontsize) <= posi) { return str.length(); } if (reposi <= 0) { return 0; } int i = 0; float last,next; for (i = 0; i < str.length();) { temp = split_text(str,i); last = getLabelWidth(mystr,fontsize); next = getLabelWidth(mystr.append(temp),fontsize); if (last <= reposi && next > reposi) { return i; } else if (next == reposi) { return i + temp.length(); } i += temp.length(); } return 0; } void CursorTextField::MyRemoveFromParent() { if (_CursorTextField) { m_pCursorSprite->stopAllActions(); parentNode->removeChild(m_pCursorSprite); parentNode->removeChild(_CursorTextField); _CursorTextField = NULL; } }
MyKeyInsert.h
#pragma once //#include "cocos2d.h" #include "CursorTextField.h" class KeyInsert : public CursorTextField { public: KeyInsert(); ~KeyInsert(); static KeyInsert * getinstence(); static void destoryinstence(); void addKeyBordClick(cocos2d::Node * node); cocos2d::Node * parentNode; cocos2d::EventListenerKeyboard * _keyBordListener; void onKeyPressed(cocos2d::EventKeyboard::KeyCode,cocos2d::Event*); private: };
MyKeyInsert.cpp
#include "MyKeyInsert.h" USING_NS_CC; static KeyInsert * _KeyInsert = NULL; KeyInsert::KeyInsert() { _KeyInsert = this; _KeyInsert->autorelease(); } KeyInsert::~KeyInsert() { } KeyInsert * KeyInsert::getinstence() { if (_KeyInsert == NULL) { _KeyInsert = new (std::nothrow)KeyInsert(); } return _KeyInsert; } void KeyInsert::destoryinstence() { Director::getInstance()->getEventDispatcher()->removeEventListener(_KeyInsert->_keyBordListener); CC_SAFE_RELEASE(_KeyInsert); } void KeyInsert::addKeyBordClick(cocos2d::Node * node) { _KeyInsert->parentNode = node; _KeyInsert->_keyBordListener = EventListenerKeyboard::create(); _KeyInsert->_keyBordListener->onKeyPressed = CC_CALLBACK_2(KeyInsert::onKeyPressed,this); _KeyInsert->_keyBordListener->onKeyReleased = CC_CALLBACK_2(KeyInsert::onKeyReleased,this); Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraPHPriority(_keyBordListener,_KeyInsert->parentNode); } void KeyInsert::onKeyPressed(EventKeyboard::KeyCode keycode,Event* event) { switch (keycode) { case EventKeyboard::KeyCode::KEY_LEFT_ARROW: //log("Left"); BlickSpriteLeft(); break; case EventKeyboard::KeyCode::KEY_RIGHT_ARROW: //log("right"); BlickSpriteRight(); break; case EventKeyboard::KeyCode::KEY_DELETE : KeyDelete(); break; case EventKeyboard::KeyCode::KEY_UP_ARROW: log("Up"); break; case EventKeyboard::KeyCode::KEY_DOWN_ARROW: log("DOWN"); break; default: break; } } void KeyInsert::onKeyReleased(EventKeyboard::KeyCode keycode,Event* event) { //log("BBB"); }具体效果自己去测试!我偷了下懒,那就是不是限定位置而是限定字符! 原文链接:https://www.f2er.com/cocos2dx/342409.html