cocos2d-x 输入框升级版 通过鼠标点击事件和键盘左右键移动光标

来源:互联网 发布:计算机通信与网络ppt 编辑:程序博客网 时间:2024/04/24 00:51

//////////////////////////////////////2013-11-11更新\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

通过鼠标点击事件和键盘左右键移动光标的实现原理:

        主要通过每个字体的宽度,存在一个容器中,然后判断点击点的位置,来实现鼠标的点击事件和键盘左右键

(ps: 写的太乱,还有好多可以优化,你们可以和我说,我尽量修改修改。这个输入框在win32中使用,ios和android用CCEditBox


具体实现,
NQTextField.h:
// 打开输入法,设置光标的位置在posTag处void openIME( int posTag );virtual bool onTextFieldInsertText(CCTextFieldTTF * pSender, const char * text, int nLen);//删除文字时。根据光标当前位置,从而进行删除文字和移动光标virtual bool onTextFieldDeleteBackward(CCTextFieldTTF * pSender, const char * delText, int nLen);//存储字符总长度,为了点击时,光标位置的移动vector<float> vec_sum_len;//存储单个字符长度vector<float> vec_one_len;//保存点击区域,来移动光标的位置vector<float> vec_click_area;//点击的位置int m_int_pos;//键盘左右键点击时相应的函数void setCursorPos( int cursor_direction );//点击bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);



NQTextField.cpp
//打开光标和输入法void NQTextField::openIME( int posTag ){if (posTag != 0){float posX = vec_sum_len[posTag-1];m_pCursorSprite->setPositionX(posX);//点击的位置m_int_pos = posTag;}else{m_pCursorSprite->setPositionX(0);//点击的位置m_int_pos = 0;}m_bClickText = true;m_pCursorSprite->setVisible(true);this->attachWithIME();}//删除文字时。根据光标当前位置,从而进行删除文字和移动光标bool NQTextField::onTextFieldDeleteBackward( CCTextFieldTTF * pSender, const char * delText, int nLen ){if (m_int_pos == 0){return true;}//如果有中文的话,对字符的操作int textPos = 0;for (int i=0;i<m_int_pos-1;i++){textPos += vec_len[i];}m_pInputText->erase(textPos,vec_len[m_int_pos-1]);//存储字节减一vector<int>::iterator iter = vec_len.begin()+m_int_pos-1;iter = vec_len.erase(iter);//删除长度vector<float>::iterator iter1 = vec_one_len.begin()+m_int_pos-1;iter1 = vec_one_len.erase(iter1);vec_sum_len.clear();vec_click_area.clear();for (int i=0; i<vec_one_len.size(); i++){if (i == 0){vec_sum_len.push_back(vec_one_len[i]);vec_click_area.push_back(vec_one_len[i]/2);}else{vec_sum_len.push_back( vec_sum_len[i-1] +  vec_one_len[i] );vec_click_area.push_back(vec_click_area[i-1] + vec_one_len[i]/2);}}//计数减一m_inputFlag--;//文本框显示字符setString(m_pInputText->c_str());//CCLOG("m_pInputText: %s",delText);//当前字符的长度float textWidth = getContentSize().width;//判断是否为密码框if (m_bPassword){str_password.resize(str_password.size()-1);setString(str_password.c_str());}//位置下标减一m_int_pos--;//设置光标位置if (m_pInputText->empty() || m_int_pos==0 ){setPlaceHolder("");m_pCursorSprite->setPositionX(0);}else{float posX = vec_sum_len[m_int_pos-1];m_pCursorSprite->setPositionX(posX);//m_pCursorSprite->setPositionX(getContentSize().width);}return true;}//插入文字时,根据光标当前位置,从而进行添加文字和移动光标bool NQTextField::onTextFieldInsertText( CCTextFieldTTF * pSender, const char * text, int nLen ){//计数超过最大输入字符数,不能插入if (m_inputFlag > m_maxInputWidth){return true;}//屏蔽回车输入if(text[0] == '\n')return true;//存储字节vec_len.insert(vec_len.begin()+m_int_pos,nLen);//计数加一m_inputFlag++;//输入框总内容添加//m_pInputText->append(text);int textPos = 0;for (int i=0;i<m_int_pos;i++){textPos += vec_len[i];}m_pInputText->insert(textPos,text);//文本框显示字符setString(m_pInputText->c_str());//判断是否为密码框if (m_bPassword){str_password.append("*");setString(str_password.c_str());}if (vec_one_len.size() == 0){//当前字符的长度float textWidth = getContentSize().width;//保存长度vec_one_len.insert(vec_one_len.begin()+m_int_pos,textWidth);vec_sum_len.push_back(textWidth);}else{//当前字符的长度float textWidth = getContentSize().width  - vec_sum_len[vec_sum_len.size()-1];//保存长度vec_one_len.insert(vec_one_len.begin()+m_int_pos,textWidth);vec_sum_len.clear();vec_click_area.clear();float cursorPosX = 0.0f;float clickPosX = 0.0f;for (int i=0;i<vec_one_len.size();i++){cursorPosX += vec_one_len[i];vec_sum_len.push_back(cursorPosX);if (i == 0){clickPosX = vec_one_len[i]/2;}else{clickPosX = vec_click_area[i-1] + vec_one_len[i]/2;}vec_click_area.push_back(clickPosX);}}//位置下标加1m_int_pos++;//设置光标位置if (m_pInputText->empty()){m_pCursorSprite->setPositionX(0);}else{float cursorPosX = 0.0f;for (int i=0;i<m_int_pos;i++){cursorPosX += vec_one_len[i];}m_pCursorSprite->setPositionX(cursorPosX);}return true;}//键盘左右键点击时相应的函数void NQTextField::setCursorPos( int cursor_direction ){if (cursor_direction == 1){m_int_pos++;}else if (cursor_direction == 2){m_int_pos--;}if (m_int_pos < 0 ){m_int_pos = 0;}if ( m_int_pos >= vec_one_len.size() ){m_int_pos = vec_one_len.size();}float cursorPosX = 0.0f;for (int i=0;i<m_int_pos;i++){cursorPosX += vec_one_len[i];}m_pCursorSprite->setPositionX(cursorPosX);}//点击bool NQTextField::ccTouchBegan( CCTouch *pTouch, CCEvent *pEvent ){CCPoint touchPoint = convertTouchToNodeSpace(pTouch);// 判断是打开输入法还是关闭输入法if (CCRectMake(0, 0, inputFrameWidth, fontHeight).containsPoint(touchPoint)){float touchWidth = touchPoint.x/2;CCLog("touchWidth: %lf",touchWidth);if ( vec_click_area.size() == 0 ){openIME(0);return true;}for (int i=0;i<vec_click_area.size();i++){if (touchWidth < vec_click_area[i]){openIME(i);return true;}}openIME(vec_click_area.size());}else{closeIME();}return true;}




//在HelloWorldScene.cpp中init()调用
NQTextField* text = NQTextField::textFieldWithPlaceHolder("hahaha","Arial",25);text->setPosition(ccp( size.width/2+100,size.height/2 ));this->addChild(text);//接受键盘左右键的点击事件setAccelerometerEnabled(true);

重写父类方法 virtual void didAccelerate(CCAcceleration* pAccelerationValue);
void HelloWorld::didAccelerate( CCAcceleration* pAccelerationValue ){if (!text->getClickText()){return;}float dirX = pAccelerationValue->x;if ( dirX > 0.0f ){text->setCursorPos(1);}else if( dirX < 0.0f ){text->setCursorPos(2);}}