cocos2dx 富文本框,支持换行,支持神情(支持汉字截断无乱码)
cocos2dx 富文本框,支持换行,支持表情(支持汉字截断无乱码)
小工在做了一个游戏聊天功能,里面用到插入表情的富文本和换行的问题;
先看效果,不是你要的效果,可return;(截图由于:输入的问题,未能输入汉字)
实现方式;
定义一个layer,在layer上摆放文本,表情,按钮,等控件,由此来形成一个多控件组成的一个富文本;
表情:仿照QQ,用的是【xy】这种方式来表示,如【00】,对应资源就是00.png
换行:就是是把超出指定宽度的内容回车,实现换行(主要是坐标x=起始位置)当然涉及到表情等,容易出问题;
例子
string m_sString = “待到山花烂漫时,他在花丛中笑【12】丛中笑【12】丛中笑【12】丛中笑【12】”;
下面伪代码实现
处理string 得到string的真实个数长度,一个汉字,一个字母代表一个长度;
创建循环体,分别来遍历没一个汉字或者是字母+特殊字符等,遇到【就判断是否是表情,如果是表情就添加表情,表情添加之前需要将表情之前的汉字等先排列上,表情排列后继续,进行遍历;
如果发现当前遍历的内容所占的屏幕长度就进行换行。表情的长度=getContextSize().width 来获取;
具体实现如代码
void MessageItem::changeLine() {
CCArray *array = getChildren();
for (int i=0; i<array->count(); i++) {
CCNode* node =(CCNode*) array->objectAtIndex(i);
node->setPositionY(m_iDefaultSize);
}
} void MessageItem::showText(const ccColor3B cColor3B )
{
bool bDoubleLine=false;
int posX= 0;//读取内容的长度小标
int iMsgEnd = 1;
int iMsgStart =1;
int width = m_iPannelWidth ;//显示面板的宽度
std::string r="";
//按照一个汉字一个长度,一个字母或者是特殊符号一个长度,得到的长度;(这样避免换行的时候汉字被分开,出现乱码现象)
int iRealLength = Tools::getRealStringLength(m_TotalMsg);
CCLabelTTF* tempTextView = CCLabelTTF::create();
tempTextView->setFontName("Arial-BoldMT");
tempTextView->setFontSize(24); while( (r= Tools::subString(m_TotalMsg,iMsgStart,iMsgEnd))!= "")
{
//先判断当前读取的字符内容是否是表情
if(r[r.length()-1]=='[')
{
std::string tmp = Tools::subString(m_TotalMsg,iMsgEnd,iMsgEnd+3);
if(tmp[3]==']'&&isNumber(tmp[1])&&isNumber(tmp[2]))//face
{
//表情前面若有内容的处理
if(iMsgEnd-iMsgStart>0)
{
CCLabelTTF* textView = CCLabelTTF::create();
textView->setFontName("Arial-BoldMT");
textView->setFontSize(24);
textView->setColor(cColor3B);
textView->setString(r.substr(0,r.length()-1).c_str());
textView->setPosition(ccp(m_LeftMsg_x+posX, 0));
textView->setAnchorPoint(ccp(0, 0));
posX+=textView->getContentSize().width;
this->addChild(textView); } //如果有表情的处理
char temp[10] = {0};
if(tmp[1]-'0' == 0)
{
sprintf(temp, "%d.png",tmp[2]-'0');
}
else
{
sprintf(temp, "%d%d.png",tmp[1]-'0',tmp[2]-'0');
}
bLineHaveFace = true; CCSprite *sp = CCSprite::create(temp);
sp->setScaleX(0.6);
sp->setScaleY(0.6);
sp->setAnchorPoint(ccp(0, 0));
//如果最后表情在一行的最后的换行处理
if(sp->getContentSize().width+posX>width)
{
posX=0;
if (m_bLimitOneLine == true)
{
break;
}
changeLine();
bDoubleLine=true;
}
iMsgEnd+=4;
iMsgStart=iMsgEnd; sp->setPosition(ccp(m_LeftMsg_x+posX, 0));
posX+=sp->getContentSize().width*0.6; this->addChild(sp);
if(iMsgEnd>iRealLength)
{
break;
}
continue;
}
}
tempTextView->setString(r.c_str());
//如果读取到都是无表情的内容,如下进行换行;
if(tempTextView->getContentSize().width+posX+24 >= width)
{
CCLabelTTF* textView = CCLabelTTF::create();
textView->setFontName("Arial-BoldMT");
textView->setFontSize(24);
textView->setColor(cColor3B);
textView->setString(r.c_str());
textView->setPosition(ccp(m_LeftMsg_x+posX, 0));
textView->setAnchorPoint(ccp(0, 0));
this->addChild(textView);
iMsgEnd++;
iMsgStart=iMsgEnd;
posX=0;
if(iMsgEnd>iRealLength)
{
break;
}
if (m_bLimitOneLine)
{
break;
}
changeLine();
bDoubleLine=true; }
else
{
iMsgEnd++;
if(iMsgEnd>iRealLength)
{
CCLabelTTF* textView = CCLabelTTF::create();
textView->setFontName("Arial-BoldMT");
textView->setColor(cColor3B);
textView->setFontSize(24);
textView->setString(r.c_str());
textView->setPosition(ccp(m_LeftMsg_x+posX, 0));
textView->setAnchorPoint(ccp(0, 0));
this->addChild(textView);
break;
}
}
}
if(bDoubleLine)
{
setContentSize(CCSizeMake(width, m_iDefaultSize*2));
m_pTypeName->setPositionY(m_iDefaultSize);
m_pUserName->setPositionY(m_iDefaultSize);
}
else
{
setContentSize(CCSizeMake(width, m_iDefaultSize));
m_pTypeName->setPositionY(0);
m_pUserName->setPositionY(0);
}
}
// 截取字符,必满乱码的处理;
std::string Tools::subString(std::string str ,int start ,int end)
{
if(typeid(str)==typeid(string) && str.length()>0)
{
int len=str.length(); string tmp=""; //先把str里的汉字和英文分开
vector <string> dump;
int i=0;
while(i<len)
{
if (is_zh_ch(str.at(i))==1)
{
dump.push_back(str.substr(i,3));
i=i+3; }
else
{
dump.push_back(str.substr(i,1));
i=i+1;
}
} int iDumpSize = dump.size();
end=end>0?end:iDumpSize;
if(start<0||start>end)
return "";
for(i=start; i<=end; i++)
{
tmp+=dump[i-1];
}
return tmp;
}
else
{
printf("str is not string\n");
return ""; }
}
//获取字符串的真实长度处理
int Tools::getRealStringLength(std::string str){
int i=0;
int len=str.length();
int r=0;
while(i<len)
{
if (is_zh_ch(str.at(i))==1)
{
r++;
i=i+3; }
else
{
r++;
i=i+1;
}
}
return r; }
如上基本上处理了一个富文本的基本操作,功能比较简单,但是做起来比较容易出问题,像换行,插入表情,截取汉字这个三个问题
cocos2dx 富文本框,支持换行,支持神情(支持汉字截断无乱码)的更多相关文章
- selenium 富文本框处理
selenium 富文本框处理, 网上有用API的解决方法1:参见:http://blog.csdn.net/xc5683/article/details/8963621 群里1位群友的解决方法2:参 ...
- H5页面设计器,仿有赞商城页面在线设计器,比富文本框更友好的内容编辑器
基本上每个web应用,都会牵扯到内容编辑,尤其是移动的web应用,微信开发之类的.页面内容自定义是最常用的功能了,之前大部分解决方案都是采用富文本框编辑器kindeditor,ueditor,cked ...
- 常用的富文本框插件FreeTextBox、CuteEditor、CKEditor、FCKEditor、TinyMCE、KindEditor ;和CKEditor实例
http://www.cnblogs.com/cxd4321/archive/2013/01/30/2883078.html 目前市面上用的比较多的富文本编辑器有: FreeTextBox 一个有很多 ...
- Android 富文本框实现 RichEditText
Android系统自带控件没有富文本框控件,如果想写一封带格式的邮件基本上不可能,EdtiText只有默认一种格式,显示不能滿足要求,!!正好项目需要研究了一下,开发了此控件,现将一些源代码开放一下, ...
- 第三百九十五节,Django+Xadmin打造上线标准的在线教育平台—Xadmin集成富文本框
第三百九十五节,Django+Xadmin打造上线标准的在线教育平台—Xadmin集成富文本框 首先安装DjangoUeditor3模块 Ueditor HTML编辑器是百度开源的HTML编辑器 下载 ...
- webdriver高级应用- 操作富文本框
富文本框的技术实现和普通的文本框的定位存在较大的区别,富文本框的常见技术用到了Frame标签,并且在Frame里面实现了一个完整的HTML网页结构,所以使用普通的定位模式将无法直接定位到富文本框对象. ...
- 基于bootstrap的富文本框——wangEditor【欢迎增加开发】
先来一张效果图: 01. 引言 老早就開始研究富文本框的东西,在写完<深入理解javascript原型与闭包>之后,就想着要去做一个富文本框的插件的样例. 如今网络上开源的富文本框插件许多 ...
- kindeditor富文本框,上传文件后,显示文件名称
kindeditor作为一个应用广泛富文本框,我们经常会利用到它,然而在使用的过程中,发现有的地方使用起来很不方便,例如本文要说的,用户上传文件之后,默认只有文件URL,没有文件说明,如图: 点击确定 ...
- selenium向富文本框填写内容的几种方式
富文本框如果是iframe,则用下 1.先跳转到irame,dr.switchTo().frame(wtext); 然后用js JavascriptExecutor jsExecutor = (Jav ...
随机推荐
- JavaScript 中的不可变对象(Immutable Objects)
默认情况下,JavaScript 中的对象是可变的.我们可以更改原始值(字符串,数字等)和对象.我们来看看这个对象: let obj = { num: , obj: { content: " ...
- Eclipse代码布局怎么使用退格和缩进快捷键?
Eclipse代码布局怎么使用退格和缩进快捷键? 好的程序,不仅要运行快速准确,而且还要易于理解.研究表明,清晰的代码布局可以提高程序猿的理解能力.何为代码布局?其实就是代码的缩进.留白等.为了保证清 ...
- 【JavaScript】ReactJS基础
初探React,将我们的View标签化 前言 我之前喜欢玩一款游戏:全民飞机大战,而且有点痴迷其中,如果你想站在游戏的第一阶梯,便需要不断的练技术练装备,但是腾讯的游戏一般而言是有点恶心的,他会不断的 ...
- CentOS6.8 4.4.43内核 安装PF_RING
环境: 系统:CentOS 6.8 内核版本:4.4.43 PF_RING版本:6.9.0 编译PF_RING需要内核源码,由于我的机器上只有4.4.43版本的modules和4.4.43的源码,并没 ...
- ubuntu 的runlevel设定
修改ubuntu的启动级别 runlevel ----------------------------------------------------------------------------- ...
- 转:windows BAT 批处理脚本教程
转自:http://www.cnblogs.com/mq0036/p/3412171.html BAT 批处理脚本教程 第一章 批处理基础第一节 常用批处理内部命令简介 批处理定义:顾名思义,批处理文 ...
- JVM组成部分以及内存模型
一.JVM的组成部分 我们先把JVM这个虚拟机实现机制画出来,例如以下图所看到的: 从这个图中能够看到,JVM是执行在操作系统之上的,它与硬件没有直接的交互. 我们再来看下JVM有哪些组 成部分,例如 ...
- automake连载--Linux下使用automake入门
http://blog.csdn.net/shanzhizi/article/details/30246587 近来重要要总结一下automake的用法了,连载几篇网上已有的文章,以供参考. 作为Li ...
- VC在windows中打开文件夹并选中文件
网上一位前辈高人的一段精髓代码让我眼前一亮…… ShellExecute(NULL, "open", "explorer.exe", "/select ...
- 帮助自定义选择框样式的Javascript - DropKick.js
来源:GBin1.com 在线演示 在线下载 当你想要设计一个页面样式时,没有什么比表单更让人头疼了.而当你设计一个表单的样式时,最让你头疼的就应该非下拉框<select>莫属了. 我们 ...