自定义cocos2dx中CCTextFieldTTF类,使用超方便

申明:此类借鉴了网上的部分代码,还有不完善的地方需要修改,不过基本功能都实现了。放置此处以飨众生。大笑欢迎各位同学提出宝贵的意见或建议。

#pragma once
#include "cocos2d.h"

USING_NS_CC;
using namespace std;
class NQTextField : public CCTextFieldTTF, public CCTextFieldDelegate, public CCTouchDelegate
{
public:  
	NQTextField();  
	~NQTextField();  

public:
	// static
	static NQTextField* textFieldWithPlaceHolder(const char *placeholder, const char *fontName, float fontSize);
	// CCLayer
	void onEnter();
	void onExit();
	bool init();
	// 初始化光标精灵
	void initCursorSprite(int mHeight);

	// CCTextFieldDelegate
	virtual bool onTextFieldInsertText(CCTextFieldTTF * pSender, const char * text, int nLen);
	virtual bool onTextFieldDeleteBackward(CCTextFieldTTF * pSender, const char * delText, int nLen);

	// CCLayer Touch
	bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);

	// 打开输入法
	void openIME( int posTag );
	// 关闭输入法
	void closeIME();

private:
	//光标
	CCSprite* m_pCursorSprite;

	//字体大小
	float fontHeight;

	//输入框的宽度
	float inputFrameWidth;

	//输入框的内容
	string *m_pInputText;

	//用户写入的placeholder
	std::string m_placeholder;

	//是否为密码框
	bool m_bPassword;

	//密码字符串*
	std::string str_password;

	//存储输入框中字母的字节,用于判断是否为中文
	vector<int> vec_len;

	//输入字符的最大长度
	int m_maxInputWidth;

	//字符的计数
	int m_inputFlag;

	//存储字符总长度,为了点击时,光标位置的移动
	vector<float> vec_sum_len;

	//存储单个字符长度
	vector<float> vec_one_len;

	//保存点击区域,来移动光标的位置
	vector<float> vec_click_area;
	
	//点击的位置
	int m_int_pos;

	//现在为止,还没用
	//是否点击该文本框
	bool m_bClickText;

public:
	//设置为密码框
	void setPassword( bool isPasswrod = true );

	//设置点击区域的宽度 默认宽度200
	void setInputFrameWidth( float newWidth );

	//设置输入框的内容
	void setInputText( std::string newInputText );

	//得到输入框的内容
	const char* getText();

	//设置可以输入的最多字符数
	void setMaxLength(int newMaxInputWidth);

	//判断是否为中文
	bool isChinese();

	//得到输入框的长度
	int getInputWidth();

	//下面两个函数现在为止,还没用
	bool getClickText();

	void setCursorPos( int cursor_direction );
};

#include "NQTextField.h"

using namespace cocos2d;
using namespace std;

NQTextField::NQTextField(void)
{
	CCTextFieldTTF();

}


NQTextField::~NQTextField(void)
{
	
}

NQTextField* NQTextField::textFieldWithPlaceHolder( const char *placeholder, const char *fontName, float fontSize )
{
	NQTextField *pRet = new NQTextField();
	if(pRet && pRet->initWithString("", 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;
}

void NQTextField::onEnter()
{
	CCTextFieldTTF::onEnter();

	//设置点击代理
	CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,-128,false);
	this->setDelegate(this);
}

void NQTextField::onExit()
{
	CCTextFieldTTF::onExit();

	//销毁点击代理
	CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
}

bool NQTextField::init()
{
	
	//必须设置锚点(0,0);
	this->setAnchorPoint(CCPointZero);

	//输入框宽度
	inputFrameWidth = 270;

	//初始化
	m_pInputText = NULL;

	//得到placeholder
	m_placeholder = getPlaceHolder();

	//不是密码框
	m_bPassword = false;

	//密码框字符为空
	str_password = "";

	//最多可以输入字符,默认10
	m_maxInputWidth = 30;

	//计数默认为0
	m_inputFlag = 0;

	//点击的位置
	m_int_pos = 0;

	//没有点击文本框
	m_bClickText = false;

	return true;
}

//初始化光标
void NQTextField::initCursorSprite( int mHeight )
{
	const int column = 1;
	const int nHeight = (const int)mHeight;
	int pixels[50][column];
	for (int i=0; i<nHeight; ++i) {
		for (int j=0; j<column; ++j) {
			//pixels[i][j] = 0xffffffff;
			pixels[i][j] = 0x00000000;
		}
	}

	//创建光标精灵
	
	CCTexture2D *texture = new CCTexture2D();
	texture->initWithData(pixels, kCCTexture2DPixelFormat_RGB888, 1, 1, CCSizeMake(column, nHeight));
	m_pCursorSprite = CCSprite::createWithTexture(texture);
	m_pCursorSprite->setPosition(ccp(0, mHeight / 2));
	this->addChild(m_pCursorSprite);
	m_pCursorSprite->setVisible(false);
	CCActionInterval* m_pCursorAction = CCRepeatForever::create((CCActionInterval *) CCSequence::create(CCFadeOut::create(0.25f), CCFadeIn::create(0.25f), NULL));
	//CCActionInterval* m_pCursorAction = CCRepeatForever::create(CCBlink::create(0.5f,1));
	m_pCursorSprite->runAction(m_pCursorAction);
	

	/*
	float scaleY = mHeight*1.0/25;
	m_pCursorSprite = CCSprite::create("Login/cursor.png");
	m_pCursorSprite->setScaleY(scaleY);
	m_pCursorSprite->setPosition(ccp(0, mHeight / 2));
	this->addChild(m_pCursorSprite);
	m_pCursorSprite->setVisible(false);
	CCActionInterval* m_pCursorAction = CCRepeatForever::create((CCActionInterval *) CCSequence::create(CCFadeOut::create(0.25f), CCFadeIn::create(0.25f), NULL));
	m_pCursorSprite->runAction(m_pCursorAction);
	*/
	//输入字符
	m_pInputText = new std::string();

	//设置字体高度
	fontHeight = mHeight*1.0f;

}

//插入文本
bool NQTextField::onTextFieldInsertText( CCTextFieldTTF * pSender, const char * text, int nLen )
{
	m_pCursorSprite->setVisible(true);

	//计数超过最大输入字符数,不能插入
	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_int_pos == m_inputFlag)
	{
		float cursorPosX = getContentSize().width;
		m_pCursorSprite->setPositionX(cursorPosX);
	}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;
}

bool NQTextField::onTextFieldDeleteBackward( CCTextFieldTTF * pSender, const char * delText, int nLen )
{
	m_pCursorSprite->setVisible(true);

	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::ccTouchBegan( CCTouch *pTouch, CCEvent *pEvent )
{

	CCPoint touchPoint = convertTouchToNodeSpace(pTouch);
	// 判断是打开输入法还是关闭输入法
	if (CCRectMake(0, 0, inputFrameWidth, fontHeight).containsPoint(touchPoint))
	{
		m_pCursorSprite->setVisible(true);

		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
	{
		m_pCursorSprite->setVisible(false);
		closeIME();
	}

	return true;
}

//打开光标和输入法
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();
}

//关闭光标和输入法
void NQTextField::closeIME()
{
	/*
	if (m_pInputText->empty())
	{
		setPlaceHolder(m_placeholder.c_str());
	}
	*/

	CCLOG("content size: %lf,%lf",this->getContentSize().width,this->getContentSize().height);

	for (int i=0;i<vec_click_area.size();i++)
	{
		CCLOG("vec_sum_len: %lf",vec_click_area[i]);
	}

	m_bClickText = false;
	m_pCursorSprite->setVisible(false);
	CCLOG("your string is %s",this->getText());
	this->detachWithIME();
}

//判断是否为中文
bool NQTextField::isChinese(  )
{
	for (int i=0;i<vec_len.size();i++)
	{
		//CCLog("vec_len[%d]: %d",i,vec_len[i]);
		if (vec_len[i]>1)
		{
			return true;
		}
	}
	return false;

}

//设置密码
void NQTextField::setPassword( bool isPasswrod )
{
	m_bPassword = isPasswrod;
}

void NQTextField::setInputFrameWidth( float newWidth )
{
	inputFrameWidth = newWidth;
}

void NQTextField::setInputText( std::string newInputText )
{
	m_pInputText->append(newInputText.c_str());
}

const char* NQTextField::getText()
{
	return m_pInputText->c_str();
}

void NQTextField::setMaxLength( int newMaxInputWidth )
{
	m_maxInputWidth = newMaxInputWidth-1>0?(newMaxInputWidth-1):-1;
}

int NQTextField::getInputWidth()
{
	int sum = 0;
	for (int i=0;i<vec_len.size();i++)
	{
		if (vec_len[i]>1)
		{
			sum = sum + 2;
		}
		else
		{
			sum = sum + 1;
		}
	}

	return sum;
}

bool NQTextField::getClickText()
{
	return m_bClickText;
}

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


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值