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 富文本框,支持换行,支持神情(支持汉字截断无乱码)的更多相关文章

  1. selenium 富文本框处理

    selenium 富文本框处理, 网上有用API的解决方法1:参见:http://blog.csdn.net/xc5683/article/details/8963621 群里1位群友的解决方法2:参 ...

  2. H5页面设计器,仿有赞商城页面在线设计器,比富文本框更友好的内容编辑器

    基本上每个web应用,都会牵扯到内容编辑,尤其是移动的web应用,微信开发之类的.页面内容自定义是最常用的功能了,之前大部分解决方案都是采用富文本框编辑器kindeditor,ueditor,cked ...

  3. 常用的富文本框插件FreeTextBox、CuteEditor、CKEditor、FCKEditor、TinyMCE、KindEditor ;和CKEditor实例

    http://www.cnblogs.com/cxd4321/archive/2013/01/30/2883078.html 目前市面上用的比较多的富文本编辑器有: FreeTextBox 一个有很多 ...

  4. Android 富文本框实现 RichEditText

    Android系统自带控件没有富文本框控件,如果想写一封带格式的邮件基本上不可能,EdtiText只有默认一种格式,显示不能滿足要求,!!正好项目需要研究了一下,开发了此控件,现将一些源代码开放一下, ...

  5. 第三百九十五节,Django+Xadmin打造上线标准的在线教育平台—Xadmin集成富文本框

    第三百九十五节,Django+Xadmin打造上线标准的在线教育平台—Xadmin集成富文本框 首先安装DjangoUeditor3模块 Ueditor HTML编辑器是百度开源的HTML编辑器 下载 ...

  6. webdriver高级应用- 操作富文本框

    富文本框的技术实现和普通的文本框的定位存在较大的区别,富文本框的常见技术用到了Frame标签,并且在Frame里面实现了一个完整的HTML网页结构,所以使用普通的定位模式将无法直接定位到富文本框对象. ...

  7. 基于bootstrap的富文本框——wangEditor【欢迎增加开发】

    先来一张效果图: 01. 引言 老早就開始研究富文本框的东西,在写完<深入理解javascript原型与闭包>之后,就想着要去做一个富文本框的插件的样例. 如今网络上开源的富文本框插件许多 ...

  8. kindeditor富文本框,上传文件后,显示文件名称

    kindeditor作为一个应用广泛富文本框,我们经常会利用到它,然而在使用的过程中,发现有的地方使用起来很不方便,例如本文要说的,用户上传文件之后,默认只有文件URL,没有文件说明,如图: 点击确定 ...

  9. selenium向富文本框填写内容的几种方式

    富文本框如果是iframe,则用下 1.先跳转到irame,dr.switchTo().frame(wtext); 然后用js JavascriptExecutor jsExecutor = (Jav ...

随机推荐

  1. mount命令汇总

    (一)挂接命令(mount) 首先,介绍一下挂接(mount)命令的使用方法,mount命令参数非常多,这里主要讲一下今天我们要用到的. 命令格式: mount [-t vfstype] [-o op ...

  2. 破解IDEA Ultimate2017 测试

    转载:http://blog.csdn.net/linyanqing21/article/details/72594352 IntelliJ Idea 2017 免费激活方法: 1.到网站 http: ...

  3. CentOS7 下安装 Lnmp 架设 Laravel

    最近在hostos上买了个香港的 vps, 装的 centos7, 在架设了 pptp vpn, 效果还行,就想顺便架设个 laravel 看看.下面是架设的过程.准备工作 更新 yum 源,自带的源 ...

  4. 【Web】Javascript、Python、Django模板配合处理URL Encode

    1.JS function relaunch(id, service, submit) { var username = $("#id_username").text(); /* ...

  5. LINUX 下编译不通过解答

    在linux下编译android源码或者webkit等程序源码时,不论在源码下加什么错误,编译器都默认正确,检索不到错误,此时,可能是之前编译的生成文件默认编译器不再检索编译新修改过的文件,只是发现修 ...

  6. 【笔记】js 关于定时器的理解

    总所周知 js 里面的 setTimeout() 方法是用来设定某些功能在某段时间间隔之后执行的.但是今天看了高程对定时器的描述发现并不是这样. setTimeout(function(){ //.c ...

  7. 【转】php中的会话机制(2)

    原文:https://segmentfault.com/a/1190000000468220 发现,在调用session_start()的时候, session_start() 里面应该是有调用类似 ...

  8. 新手IOS tweak越狱app开发记录

    需要改变原先程序功能流程的话,是要用到Logos Tweak 开发.另外,.在苹果商城下载到的app,不能直接拿来分析.需要先做一定的前期准备.网上有很多相关的写第一个越狱插件的文章,这里就不在赘言了 ...

  9. IE6—在链接click事件的响应函数中发送jsonp请求不生效

    $("#link").click(function(){     $.ajax({         type: 'GET',         dataType: 'jsonp', ...

  10. 顶部有一排按钮,最底下还有FooterView的ListView页面

    Android 先上效果图: 下面详细说说这个页面是怎么做出来的: 1.这个页面最下方可以看到一个TAB页签,分别是“主页”.“提及”等等,这个是一个在底部的TAB分页样式,在上一篇博客中已经介绍了 ...