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 ...
随机推荐
- Eclipse通过Spket增加JQuery提示的方法
Eclipse通过Spket增加JQuery提示的方法 1.增加在线更新源:Help->Install New Software...->Add...->Name: "Sp ...
- Mapreduce报错:java.lang.ClassNotFoundException: Class Mapper not found
mapreduce找不到mapper类 解决方法: 开始自己用的是mapreduce自己打包的一种方法: job.setJarByClass(StandardJob.class); 但这样一直在报错: ...
- centos7安装后的防火墙问题
centos7 默认使用firewall作为防火墙 停止并关闭开机自启动: systemctl stop firewalld.service #停止firewall systemctl disable ...
- 接口测试框架开发(一):rest-Assured_接口返回数据验证
转载:http://www.cnblogs.com/lin-123/p/7111034.html 返回的json数据:{"code":"200","m ...
- java线程总结(2/5)
线程基本信息和优先级别 方 法 功 能 isAlive() 判断线程是否还“活”着,即线程是否还未终止. getPriority() 获得线程的优先级数值 setPriority() ...
- 下载论坛源码GBK UTF8 BIG5分别是什么意思
下载论坛源码GBK UTF8 BIG5分别是什么意思? 提问者:ly1987520 | 浏览次数:4010次 下载论坛源码简体中文GBK 简体中文UTF8 繁体中文BIG5 分别是什么意思?他们的区别 ...
- docker中的link
一.查看容器的详细情形 docker inspect 容器id/名称 二.为什么要用link 容器每次重启时,ip都会变动,这不利于前端引用中连接数据库. 三.link docker run -p 8 ...
- Android实战技巧之三十八:Handler使用中可能引发的内存泄漏
问题描写叙述 曾几何时,我们用原来的办法使用Handler时会有以下一段温馨的提示: This Handler class should be static or leaks might occur ...
- mongodb的基本语法(一)
一.数据库常用命令 1.Help查看命令提示 help db.help(); db.yourColl.help(); db.youColl.find().help(); rs.help(); 2.切换 ...
- pandas数据处理基础——基础加减乘除的运算规则
上周公司对所有员工封闭培训了一个星期,期间没收手机,基本上博客的更新都停止了,尽管培训时间不长,但还是有些收获,不仅来自于培训讲师的,更多的是发现自己与别人的不足,一个优秀的人不仅仅是自己专业那块的精 ...