CEGUIEditBox : 获得准确的字符长度,看我给CEGUIEditBox动手术
来源:互联网 发布:尼加拉瓜运河 知乎 编辑:程序博客网 时间:2024/06/09 19:27
天龙八部的底层是用0.4.0版本的cegui做的,种种控件已经做得很完整了。
天龙八部的代码拯救了大部分无家可归的程序员。
CEGUIEditbox控件已经为我们做好了这个最大长度限制的属性 MaxTextLength
我们打开天龙八部的logon.layout.xml文件 虽然是武侠世界的源码但是我觉得已经做很完整了,至少学习足够了
.....
<Window Type="TLBB_EditBoxNormal" Name="LogOn_ID">
<Property Name="AbsolutePosition" Value="x:33.000000 y:60.000000" />
<Property Name="AbsoluteSize" Value="w:100.000000 h:19.000000" />
<Property Name="Text" Value="请输入账号" />
<Event Name="TextAccepted" Function="Logon_LogOn_ID_Return();" /> 文字注入捕获 Lua处理函数 Logon_LogOn_ID_Return()
<Event Name="TabPressed" Function="Logon_ID_TabPressed();" />TAB键捕获Lua处理函数 Logon_ID_TabPressed()
<Event Name="MouseEnter" Function="LogOn_ID_MouseEnter();" />鼠标进入捕获Lua处理函数 LogOn_ID_MouseEnter()
<Event Name="MouseLeave" Function="LogOn_MouseLeave();" />鼠标移出捕获Lua处理函数 ="LogOn_MouseLeave()
<Event Name="Activated" Function="LogOn_LogonID_Active();" />输入框激活捕获Lua处理函数 LogOn_LogonID_Active()
<Event Name="Deactivated" Function="LogOn_LogonID_Deactivated();" />输入框冻结捕获Lua处理函数 LogOn_LogonID_Deactivated()
<Property Name="MaxTextLength" Value="32" />
</Window>
.....
<Property Name="MaxTextLength" Value="32" />
有这个属性在我们能够很清楚的了解一个事情,LogOn_ID里面最大的输入串长度是32字节;
如果我们的cegui版本没有动过手术的话,那么MaxTextLength的数值必然是32个字符,或者32个汉字。至少我用的版本0.75是如此。
那么如何获得到精准的字符长度呢?比如如果我的输入框就是想让中英文结合,此时我想让玩家输入的数据只有32字节长度,怎么办。
字符占用一个字节,汉字占用2个字节;从高中的计算机教材中就能了解这些,
接下来如何实现:
来看下天龙八部是怎么处理字符串长度的问题的吧cegui0.75和cegui0.40版本有本质上的不同,至于不同点是什么,诶引用句广告词:蚁力神,谁用谁知道。
最大的区别就是0.6以后cegui版本彻底把逻辑和渲染分开,0.75开始支持3d旋转了。就是一个界面可以有360的角度变化了,效率提高了一大截 XXXX
诶。言归正传,他们的区别远不止这些;说正事
我们翻阅下cegui的EditBox实现部分在获得文字注入消息的时候他会激活这个函数
当然天龙版本是0.40版本激活 addCharater()0.75版本触发的函数是onCharacter()
虽然名字换了,但大体是换汤不换药。功能不会换。
0.75 版本
onCharacter()
{
// backup current text
String tmp(getText());
tmp.erase(getSelectionStartIndex(), getSelectionLength());
// if there is room
if (tmp.length() < d_maxTextLen)
{ 。。。。。。。。。。。。。。};
}
为何新的0.75只和字符数量杠上了,元凶在这红色代码上面接下来直接看天龙代码是如何改的
天龙的0.40是这样的函数addCharater()是接收字符的地方里面有这句话
addCharater()
{
。。。。。。
if (tmp.mbcs_length() + str.mbcs_length() <= d_maxTextLen)
。。。。。。
}
好找了,打开天龙的CEGUIString.h我们看下这个函数的实现
// return number of code units in a null terminated string
//天龙八部的实现
//应该是这样的,天龙八部的实现方法是有错的
// 这里我更正下当初自己的错误观点以下的实现才是真正的‘可视字符串实现’
size_type mbcs_length(void) const
{
const char* code = c_str();
const utf8* buf = build_utf8_buff();
size_type len = d_encodedbuff;
utf8 tcp;
size_type count = 0;
while (len--)
{
tcp = *buf++;
++count;
if (tcp < 0x80)
{
}
else if (tcp < 0xE0)
{
--len;
++buf;
++count;
}
else if (tcp < 0xF0)
{
len -= 2;
buf += 2;
++count;
}
else
{
len -= 2;
buf += 3;
++count;
}
}
return --count;
}
变动下这里
0.75 版本 EdibBox:::onCharacter()
{
。。。。。。
if (tmp.mbcs_length() < d_maxTextLen)
。。。。。。
}
ok了,我的demo已经成功切断多余的字符完成了这个小手术075也有这个功能了
如果觉得这个功能直接改不太好,那么完全可以给EditBox再增加个新属性
什么时候想用了,让这个属性打开就成了
说做就做;
在CEGUIEditBoxProperty.h文件中添加
class ActiveByteLenth: public Property
{
public:
ActiveByteLenth() : Property(
"ActiveByteLenth",
"False."// 这个属性默认为关闭状态否则麻烦大大
{}
String get(const PropertyReceiver* receiver) const;
void set(PropertyReceiver* receiver, const String& value);
};
CEGUIEditBoxProperty.cpp中添加
void MaskCodepoint::set(PropertyReceiver* receiver, const String& value)
{
static_cast<Editbox*>(receiver)->setActiveByteLenth(PropertyHelper::stringToBool(value));
}
String ValidationString::get(const PropertyReceiver* receiver) const
{
return PropertyHelper::boolToString(static_cast<const Editbox*>(receiver)->isActiveByteLenth());
}
在CEGUIEditbox.h中添加
bool b_activeBytelenth;// 记得给这个值初始化否则debug和release下面默认值的结果是相反的
void setActiveByteLenth(bool setting) {b_activeBytelenth = setting;};
bool isActiveByteLenth(void) const {return b_activeBytelenth;};
static EditboxProperties::ActiveByteLenth d_activeByteLenthProperty;
在CEGUIEditbox..cpp中添加
EditboxProperties::ActiveByteLenth Editbox::d_activeByteLenthProperty;
void Editbox::addEditboxProperties(void)
{
CEGUI_START_ADD_STATICPROPERTY( Editbox );
CEGUI_ADD_STATICPROPERTY( &d_activeByteLenthProperty); //包含到控件中如此属性就和变量关联起来了
CEGUI_END_ADD_STATICPROPERTY
}
然后在函数onCharacter中可以这样写
EdibBox:::onCharacter()
{
。。。。。。
int tmplenth = b_activeBytelenth ? tmp.mbcs_length() :tmp.length() ;
if (tmplenth < d_maxTextLen)
。。。。。。
}
如此我的0.75就拥有了新的属性成员ActiveByteLenth
<Window Type="TLBB_EditBoxNormal" Name="LogOn_ID">
<Property Name="AbsolutePosition" Value="x:33.000000 y:60.000000" />
<Property Name="AbsoluteSize" Value="w:100.000000 h:19.000000" />
<Property Name="Text" Value="请输入账号" />
<Property Name="ActiveByteLenth" Value="True" />
<Property Name="MaxTextLength" Value="32" />
</Window>
如此我就可以在layout.xml文件中轻而易举的打开和关闭这个属性什么时候想用什么时候讲ActiveByteLenth设置成True就可以了,其他的控件依旧保持原有属性
扩展了一个属性比改掉一个接口要可取些
- CEGUIEditBox : 获得准确的字符长度,看我给CEGUIEditBox动手术
- 要对我的IBM ThinkPad R60e动手术了
- 看我的字符加密
- asp.net准确截取文本长度(取得标题的字符数)
- 通过指针遍历获得字符数组的长度
- 用DELPHI给OICQ动手术(一)
- 用DELPHI给OICQ动手术(二)
- 字符,数组,指针的准确操作
- 给大家看一下我的ubuntu工作桌面
- 给我自己看的两张图表
- 不知你看了会给我什么样的意见
- 泛型是给编译器看的,我可以通过反射使用。。。
- oracle 嵌套查询(给我自己看的)
- JavaScript技巧【总结给我自己看的-。-】
- 给textarea设置字符长度限制
- 不用动手术的肝脏清洗法
- 字符数组的长度
- 字符的长度
- POJ 1094 Sorting It All Out 拓扑排序
- oracle实现行列转换
- VMware虚拟机和宿主机互相映射磁盘分区
- hive横转竖
- Installing JDeveloper on Mac OS X Lion (10.7)
- CEGUIEditBox : 获得准确的字符长度,看我给CEGUIEditBox动手术
- c++虚函数的前奏--函数指针与回调
- 解决了Could not get lock /var/cache/apt/archives/lock
- 如何在一个java类main方法中调用另一个类中的main方法
- JAVA 数据库连接编码问题
- erlang(2) gen_server
- 深入理解C/C++函数指针
- 37所国家示范性软件学院
- Qt配置文件分析