Post Views:
9,261
原文:CEGUI官方wiki
翻译:基拉铃妖
===================================================================
2012.10.15日更新
被这教程坑啦!!!
后来人注意:在“在CEGUI中正确地注册这个窗口”那段代码里,addFalagardWindowMappings的第二个参数应该填你在CheckListboxItem.cpp里初始化的WidgetTypeName的值,在这个例子里就是“CEGUI/CheckListboxItem”,而不是它的基类“CEGUI/ItemEntry”!!填ItemEntry虽然也能运转,但你在CheckListboxItem里重写的基类函数都不会生效.
我昨天就是死活覆盖不了基类函数,后来下断点发现它连我重写的构造函数都没有进入,当时就寒心了啊我去!!!
还我时间!还我被消耗的对CEGUI的热情!!
———————————————–
不过多亏这个教程我才知道怎么自定义控件,而且它全文也就这一处错误,总的来说还是收益远大于危害的。
……唉。想不违背公允就得好坏都看,这样一来连发泄一下的机会都没有了……
===================================================================
有时候你需要一个列表来包含一些可选中的item。CEGUI 0.5引入的ItemListbox可以接受所有继承自ItemEntry的item。我将向你介绍如何创建一个CheckListboxItem来放入你的list中。
开始!
我假设你使用的是标准imageset,以及标准scheme(现在支持TaharezLook和WindowsLook)。
我们首先来写一个looknfeel entry。这是本教程中最重要的内容,它将占整个教程70%左右的比重。首先,这个entry有几个声明(states):
1.Enabled:当item是enabled时,它是什么样子。
2.Disabled:当item是disabled时,它是什么样子。
3.SelectedEnabled:当item被选中且是enabled时,它是什么样子。
4.SelectedDisabled:当item被选中且是disabled时,它是什么样子。
写下所需文件
打开一个合适的looknfeel文件(WindowsLook.looknfeel或者TaharezLook.looknfeel),然后在文件底部填上以下内容(说是在最下面但是也要在Falagard tag内!)
我们的开始

我们首先需要定义一个WidgetLook,这个文件里包含所有的动作(action)。它有一个属性,name。它代表拟定一个这个widget的名字。现在我们来添加声明(states)。这些声明(states)使item可以响应指定的事件(Events)。比如,当item被设为disabled,则声明(state)Disabled将被使用。

我们通过StateImagery定义一个声明(state)。它需要属性name来指定它在哪个状态(state)内。先不用管Layer。Section总会被用到。这一部分负责市级改变外观。它需要一个属性section,这是要改变 什么 ,在这里指label。TextColour就是颜色(黑色),我们会在下面定义它。现在,如你所见,Enabled状态(state)只是把文本颜色设为黑色,仅此而已。Disabled也类似(记住这是一个item,items通常不会是disabled状态的)。
现在我们来看看另外两个状态。

这些状态很好地解释了它们自己,虽然里面又多了几个section。Section不仅定义要改变什么,它还定义什么应该被显示。在Enabled状态中我们不想让他看起来是被选中的,所以没有selection section。注意,你书写Section的顺序同时也是Z轴的顺序。在本例中我们把selection图放在前面,然后是文字。如果我们把顺序反过来,就看不到字了。(被selection图挡住了)
现在我们来添加颜色和属性的定义。

我们的第一个PropetryDefinition只是定义了一个用在StateImagery sections中的文本颜色。其他PropertyDefinitions也一样,除了SelectionBrush。它不是定义颜色,而是定义了一个图像。在这个例子里,它使用定义在imageset里的WindowsLook的背景图。然后,我们有了一个可以影响某些设置的Property(属性)。在这个例子里,我们通过添加Selectable属性并设为true来创建一个item。
写功能部分
我们现在需要增加增加绘制背景、文字和选取的部分。这看起来有点难,不过其实不是。我们从一个NamedArea开始吧。它是listbox item所必需的,因为listbox需要知道这个item有多大来确保把它很好地放进list。

我假设你知道Area、Dim之类的基本概念。FontDim是用来根据label改变item的尺寸的。我们刚刚加进去的部分定义了item的尺寸。这次我不再贴出全部代码,而只展示新增的部分。
OK!现在我们来添加一个世纪的Checkbox吧。这对我们的目标来说很重要,因为它是我们的item可以被点击选中。我们不用为Checkbox写全部的状态和其他东西,我们直接用Child!只要把下面这段内容放在我们的NamedArea下面、第一个StateImagery的上面即可。(它俩中间)

这里添加了一个WindowsLook/Checkbox到我们的item里面去了。其中的suffix是必需的,加它是为了使name不重复。剩下的内容就非常直白了——把checkbox加到item的左边,和左边界留出3个像素的距离,让它看起来更平整一些。
现在我们需要一个label,这部分很简单所以我不会花很多时间去解释,基本上看了就明白了。

TextComponent是一个文本容器。Dim是定位。注意LeftEdge,label离开左边界18个像素。这是因为checkbox占了前面15像素的空间。
现在重要的来了!selection image。

注意我们给属性“name”复制为“selection”,as used in the StateImagery.Area部分还是定位和自适应。Dim用来确保整个item都被填满了。
ImageProperty定义了要使用的图像爱你个。我们已经在WidgetLook的前面某处定义了SelectionBrush。它现在只是用图填充那个区域(Area)。ColourProperty给image上色,我们也已经在WidgetLook的前面某处定义过SelectionColour了。VertFormat和HorzFormat是拉伸的(stretched),如果他没有被拉伸,它将只会画image的一个像素点,那就几乎不可见了。拉伸它是为了确保整个区域都被覆盖了。
完成!我们已经写好了我们的looknfeel entry!!

Pfew am I glad thats done.(基拉:我怀疑这是个拼写错误。作者文中多出拼写错误,有的我识别出来了,有的我真是搞不定,比如这句= =b)
给item写代码
到了实际考验我们的新item的时候了。我们需要再做一点工作来增加这个教程的完成度。首先,我们需要创建CheckListboxItem类。然后,我们要添加window工厂(factory)到系统中。最后,我们要做一个Falagard映射(mapping)。我们先从CheckListboxItem类开始吧。
CheckListItem.h

如你所见,这个类继承自ItemEntry。这是必需的,因为这样才能让我们的新item像个正常的item一样运作。需要特别注意的是这个CEGUI_DECLARE_WINDOW_FACTORY(CheckListboxItem). 它告诉CEGUI我们正在声明这个窗口。
CheckListItem.cpp

这里的CEGUI_DEFINE_WINDOW_FACTORY(CheckListboxItem) 非常重要。它告诉CEGUI我们在哪里放置和这个窗口相关的代码。如你所见,这个类非常空,你,当然,可以加任何你喜欢的东西到这个类里面来——这里写的只是类的基础框架。
现在,还有一件重要的事要做。在CEGUI中正确地注册这个窗口。
(译注:实践证明,addFalagardWindowMappings的第二个参数应该填你在CheckListboxItem.cpp里初始化的WidgetTypeName的值,在这个例子里就是“CEGUI/CheckListboxItem”,而不是它的基类“CEGUI/ItemEntry”。具体区别见本文顶部2012.10.15日更新)

addFalagardWindowMappings的参数分别是:名称(Name),类型(Type),LooknFeel,窗口渲染器(WindowRenderer)。只要把这段代码放在你的main文件的某处,或者放在其他你确定可以在使用我们的新item之前会被执行到的地方。还要注意,为了使用CEGUI_WINDOW_FACTORY(),你需要在CEGUI命名空间内部。
实例
main.cpp

如你所见,在这个main函数里,注册窗口的函数在实际创建窗口之前被调用了。不要在意SDL初始化的部分——那只是我的个人测试环境而已。
恭喜!你已经创建了一个CheckListboxItem了。这是一个非常好的练习,因为你也学会了如何写一个复合Widget。
如果你有任何疑问、评论、反馈……任何事的话,欢迎发邮件告诉我。我的邮件地址是 levia at openfrag dot com.
—User:Levia 21:10, 5 April 2007 (GMT+1)
====== 译者后记 =======
@DHorse WordPress太凶残了,我在你那个网站上上好色的XML代码它都吞,好象是见了尖括号就管不住嘴似的。我算怕了它了,全部贴图搞定!哇哈哈哈哈!!