展会信息港展会大全

cocos2dx3.6 实现带光标的输入框
来源:互联网   发布日期:2015-09-28 14:01:27   浏览:7681次  

导读: 多的不说,我这个学渣,我写的代码比较搓!忍耐下吧! CursorTextField.h #ifndef _CursorTextField_H_ #define _CursorTextFiel...

多的不说,我这个学渣,我写的代码比较搓!忍耐下吧!

CursorTextField.h

#ifndef _CursorTextField_H_

#define _CursorTextField_H_

#include "cocos2d.h"

USING_NS_CC;

class CursorTextField : public TextFieldTTF, public TextFieldDelegate , public IMEDelegate

{

private:

// 点击开始位置

Point m_beginPos;

// 光标精灵

Sprite * m_pCursorSprite;

// 光标动画

Action *m_pCursorAction;

// 光标坐标

Point m_cursorPos;

//输入框长度

float inputFrameWidth;

//允许输入的最大字符数Unicode

float inputMaxLength;

int nLenCount;

int codeNumType[50];//每个字符对应的字节数量

int codeCur;//当前第几个字符

int startCur;//行开头字符下标

int endCur;//行末尾下标

// 输入框总内容

std::string m_pInputText;

std::string inpuText; //当前输入框内容

public:

CursorTextField();

~CursorTextField();

// 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);

// 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);

// 判断是否点击在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;

protected:

EventListenerTouchOneByOne * listener;

};

#endifCursorTextField.cpp

#include "CursorTextField.h"

#include "MyCharSet.h"

const static float DELTA = 0.5f;

using namespace cocos2d;

using namespace std;

CursorTextField::CursorTextField()

{

TextFieldTTF();

m_pCursorSprite = NULL;

}

CursorTextField::~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);

this->setDelegate(this);

}

CursorTextField * CursorTextField::textFieldWithPlaceHolder(Node * node , const char *placeholder, const char *fontName, float fontSize)

{

auto pRet = new CursorTextField();

pRet->parentNode = node;

if (pRet && ((TextFieldTTF*)pRet)->initWithPlaceHolder(placeholder, 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 = 16;

this->nLenCount = 0;

memset(codeNumType, 0, sizeof(codeNumType));

this->codeCur = 0;

this->startCur = 0;

this->endCur = 0;

inpuText = "";

return true;

}

void CursorTextField::initCursorSprite(const int mHeight)

{

int column = 2;

int nHeight = 20;

int pixels[50][2];

for (int i = 0; i initWithData(pixels, 20, Texture2D::PixelFormat::RGB888, 4, mHeight, CCSizeMake(column, nHeight));

m_pCursorSprite = Sprite::createWithTexture(texture);

texture->autorelease();

if (m_pCursorSprite == nullptr)

{

CCLOG("NULL");

}

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);

}

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_cursorPos.y + m_pCursorSprite->getContentSize().height / 2.0);

}

}

void CursorTextField::setCursorPositionX(float x) // 设置光标x位置

{

Point pt = getPosition(); // 获取输入框位置

m_pCursorSprite->setPositionX(pt.x + 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 size = getContentSize();

returnCCRectMake(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(this->getPosition().x);

memset(codeNumType, 0, sizeof(codeNumType));

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::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();

}

//弹出手机键盘时响应事件

bool CursorTextField::onTextFieldAttachWithIME(cocos2d::TextFieldTTF *pSender)

{

if (m_pInputText.empty()) {

return false;

}

m_pCursorSprite->setPositionX(this->getPosition().x + getContentSize().width);

return false;

}

//当有输入进来时响应

//@param pSender 发送事件对象

//@param text 输入内容

//@param内容字节长度

bool CursorTextField::onTextFieldInsertText(cocos2d::TextFieldTTF* sender, const char * text, size_t nLen)

{

int j = 0 ;

std::string mytext = text;

for (j = 0; j utf8_to_unicode((uint8_t*)t, (uint16_t **)wText, &unisize);

std::string ss = split_text(mytext, 1 , j);

j += ss.length();

//当字符数量超过规定值 不做处理

if (cou >= inputMaxLength)

{

CC_SAFE_DELETE_ARRAY(wText);

return true;

}

//return true;

//屏蔽回车输入

if (ss == "\n")

{

CC_SAFE_DELETE_ARRAY(wText);

continue;

}

//输入框总内容添加

m_pInputText.append(ss);

//输入框当前字符串添加

inpuText.append(ss);

//当前字符的长度

codeNumType[codeCur++] = ss.length();

std::string localText = m_pInputText;

setString(m_pInputText);

//如果总字符串的长度大于指定宽度

if (getContentSize().width > inputFrameWidth){

//大于,截取字符串,直到字符串的长度小于指定宽度为止

setString(inpuText);

while (getContentSize().width > inputFrameWidth){

int nnLen = ss.length();

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);

}

//设置光标位置

m_pCursorSprite->setPositionX(this->getPosition().x + getContentSize().width);

CC_SAFE_DELETE_ARRAY(wText);

//AndroidShowtext(mychar, 1);

}

return true;

}

//当有输入进来时响应

//@param pSender 发送事件对象

//@param text 删除内容

//@param内容字节长度

bool CursorTextField::onTextFieldDeleteBackward(cocos2d::TextFieldTTF* sender, const char * delText, size_t nLen)

{

// 将总字符串长度减去nLen字节长

m_pInputText.resize(m_pInputText.size() - nLen);

//当前字符数减一

codeNumType[codeCur--] = 0;

std::string localText = m_pInputText;

setString(m_pInputText);

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 setPositionX(this->getPosition().x + getContentSize().width);

if (m_pInputText.empty()) {

m_pCursorSprite->setPositionX(this->getPosition().x);

}

return true;

}

bool CursorTextField::onTextFieldDetachWithIME(cocos2d::TextFieldTTF *pSender)

{

return false;

}

void CursorTextField::openIME()

{

m_pCursorSprite->setVisible(true);

setString(m_pInputText);

((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);

}

std::string CursorTextField::split_text(std::string name, int len , int start)

{

int i = start;

std::string str;

if (name[i]

字节转换的

MyCharSet.h

#pragma once

#include "stdint.h"

#include "stdio.h"

#include

#include

#include

class MyCharSet

{

public:

MyCharSet();

~MyCharSet();

static MyCharSet * getinstence();

static void destoryinstence();

int utf8_to_unicode(uint8_t *in, uint16_t **out, int *outsize);

int unicode_to_utf8(uint16_t *in, int insize, uint8_t **out);

};

MyCharSet.cpp

#include "MyCharSet.h"

static MyCharSet *_MyCharSet = NULL;

MyCharSet::MyCharSet()

{

}

MyCharSet::~MyCharSet()

{

}

MyCharSet * MyCharSet::getinstence()

{

if (_MyCharSet == NULL)

{

_MyCharSet = new MyCharSet();

}

return _MyCharSet;

}

void MyCharSet::destoryinstence()

{

if (_MyCharSet != NULL)

{

delete _MyCharSet;

}

}

int MyCharSet::utf8_to_unicode(uint8_t *in, uint16_t **out, int *outsize)

{

uint8_t *p = in;

uint16_t *result = NULL;

int resultsize = 0;

uint8_t *tmp = NULL;

result = (uint16_t *)malloc(strlen((char *)in) * 2 + 2); /* should be enough */

memset(result, 0, strlen((char*)in) * 2 + 2);

tmp = (uint8_t *)result;

while (*p)

{

if (*p >= 0x00 && *p > 3);

p++;

t2 = *p & (0xff >> 2);

*tmp = t2 | ((t1 & (0xff >> 6)) > 2;

tmp++;

*tmp = t1 >> 2;//t2 | ((t1 & (0xff >> 6)) > 3);

p++;

t2 = *p & (0xff >> 2);

p++;

t3 = *p & (0xff >> 2);

//Little Endian

*tmp = ((t2 & (0xff >> 6)) > 2);

tmp++;

*tmp = (t1 > 2);//((t2 & (0xff >> 6)) = 0x0000 && unicode = 0x0080 && unicode > 6);

tmp += 1;

*tmp = 0x80 | (unicode & (0xff >> 2));

tmp += 1;

outsize += 2;

}

else if (unicode >= 0x0800 && unicode > 12);

tmp += 1;

*tmp = 0x80 | (unicode >> 6 & 0x00ff);

tmp += 1;

*tmp = 0x80 | (unicode & (0xff >> 2));

tmp += 1;

outsize += 3;

}

}

*tmp = '\0';

*out = result;

return outsize;

}

如果使用直接:

CursorTextField *m_pCursorInputLayer = CursorTextField::textFieldWithPlaceHolder(this, "click and input",

"fonts/Marker Felt.ttf", 40);

m_pCursorInputLayer->setAnchorPoint(ccp(0.0f, 0.0f));

m_pCursorInputLayer->setInputWidth(visibleSize.width);

Vec2 posi(0, visibleSize.height / 2);

m_pCursorInputLayer->setPosition(posi);

this->addChild(m_pCursorInputLayer, 1);

我这个输入解决了Android上一堆输入导致的错误,大家可以仔细去看看!

这个输入自行扩展,现在我的需求不用不需要,也就没写,大家可以自行输入。

给个思路大家吧,在切割字符的时候可以自行添加回车,我暂时想到这样来做!

我做的效果!

赞助本站

人工智能实验室
AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港