您的位置:首页 > 移动开发 > Cocos引擎

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

2013-11-11 12:26 645 查看
//////////////////////////////////////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);
}
}

//位置下标加1
m_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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐