cegui 4 创建CEGUI窗口入门——讲述如何创建一个简单的CEGUI窗口.

来源:互联网 发布:键盘电子琴软件 编辑:程序博客网 时间:2024/04/28 01:37
 

cegui 4

创建CEGUI窗口入门         讲述如何创建一个简单的CEGUI窗口.
所有的控件都是窗口
这是最重要的概念。所有的控件类都是从Window这个基类派生出来的,所以,在此教程中,每当我提到一个窗口的时候,它可以是一个按钮也可以是一个滚动条控件。
很多的设置都会被继承下去
CEGUI中,窗口的很多的设置和属性都会按窗口父子等级向下传递。比如:如果你将一个窗口的alpha透明度设置为0.5,那么,默认情况下,所有附属于那个窗口的子窗口/组件都将受到影响。同时要注意:子窗口的实际设置并没有改变 ---- 最终的属性值通常是由最顶层到当前窗口所有属性值组合而成的。好多东西都有这个规律,比如窗口的销毁:默认情况下,一个窗口在销毁的时候将销毁它的所有子窗口。这一机制最大的优点是:通过改变根窗口的alpha透明度、显示/隐藏、激活/禁用状态等可以很轻易的控制整个GUI;通过简单的销毁根窗口就可以轻松的清空整个GUI。当个别窗口需要更精确的控制或有更好的管理技术用的时候,可以更改这一默认继承机制。
创建窗口
有两种方法来创建窗口:通过C++硬编码实现和通过XML布局文件实现。下面将讨论这两种方法。
CEGUI的所有窗口都是被WindowManager这一对象创建的。你可以通过getSingleton函数获得这个对象,代码如下:
  1. using namespace CEGUI;  
  2. WindowManager& wmgr = WindowManager::getSingleton();  

一般情况,你将用DefaultWindow(或者它的老名字:DefaultGUISheet)作为GUI的“root”窗口。这点并不是必须的,但它是使用CEGUI很好的习惯,而且可以帮助简化布局。下一步,我们将创建一个DefaultWindow作为GUI的根窗口(这里sheetroot的意思)。

  1. Window* myRoot = wmgr.createWindow( "DefaultWindow""root" );  
  2. System::getSingleton().setGUISheet( myRoot );  
indowManager::createWindow函数有两个string类型的参数。第一个参数,本例中为“DefaultWindow”,告诉系统你要创建的窗口类型或类。通常,你可以使用的窗口类型是那些当你载入scheme文件的时候注册的窗口类。而有些像DefaultWindow这样的是全局类型,它们总是可用的。第二个参数,本例中为“root”,是一个将要赋予这个窗口的独一无二的名字。以后可以通过这个名字获取指向这个窗口的指针。注意:并不是一定要给你的根窗口命名为“root”,但这是通常的命名约定。
 System::setGUISheet函数用来指定一个窗口作为GUI的根窗口。这将替换掉当前的根窗口,但是要注意:之前的一系列窗口/控件并没有被销毁,只是从当前的显示链中摘除 ---- 通过使用setGUISheet函数,你可以轻松的在多个GUI中切换。

现在,你已经创建了第一个窗口并把它附着在GUI系统上,当系统画GUI的时候,它将把这个窗口作为GUI的根。但是,如果你编译运行这些代码,你依然不会看到任何东西。怎么了?你的程序没有任何问题,问题在:我们刚才创建的DefaultWindow是隐藏的!这就是为什么DefaultWindow那么适合做根窗口的原因:它仅仅被用作供其他的窗口和控件依附的空画布。那么,我们再加把劲吧。。。现在,我们将要创建一个框架窗口:这个窗口和你桌面上的窗口很类似,它有一个标题栏,也可以移动和改变大小。代码如下:

  1. FrameWindow* fWnd = (FrameWindow*)wmgr.createWindow(   
  2.                         "TaharezLook/FrameWindow""testWindow" );  

此代码创建了一个“TaharezLook/FrameWindow”窗口。整个系统都使用这种命名约定:窗口类型以组件组名做为前缀(假如你载入了WindowsLook scheme,你就可以创建一个“WindowsLook/FrameWindow”对象)。我们为这个新窗口命名为“testWindow”。需要注意的是:那个类型转换的使用,由于createWindow函数总是返回Window基类指针,尽管对于此例以及其他情况,返回这个Window指针就足够了,但是有时你需要访问子类的方法,所以使用CEGUI的时候示例中的类型转换是很常见的。

为了让系统能够用我们的新窗口做一些有用的事情,我们还需要做一些事情。
首先,我们必须把这个新窗口附着到我们上面指定的根窗口上,代码如下:

  1. myRoot->addChildWindow( fWnd );  

现在,我们可以设置它的位置和大小。CEGUI使用一个“统一的(unified)”坐标系,使得可以同时使用相对部分和绝对部分 ---- 这就是为什么你看到的每个坐标都由两个部分组成。

  1. // 定位在其父窗口左上角开始的1/4位置  
  2. fWnd->setPosition(UVector2( UDim( 0.25f, 0 ), UDim( 0.25f, 0 ) ) );  
  3.   
  4. // 设置其大小为其父窗口的一半  
  5. fWnd->setSize( UVector2( UDim( 0.5f, 0 ), UDim( 0.5f, 0 ) ) );  

最后,我们为这个框架窗口的标题栏设置一个标题:

  1. fWnd->setText( "Hello World!" );  
XML布局

上面的方法看起来很不错,但是,它有一个很大的弊端:每次你想要调整GUI布局的时候,你就得去修改代码,然后重新编译。这样还不累死了?你真正想要做的是能够把布局保存在文件中,然后在代码中调用那个布局文件。

系统支持XML格式的布局文件,可以通过WindowManager::loadWindowLayout函数载入此文件。此函数为你创建所有的窗口并返回一个指向根窗口的指针。调用setGUISheet设置GUI的根窗口的时候用此指针再适合不过了。
所以,首先我们需要一个布局文件。下面这个XML文件所描述的窗口和我们上面用C++创建的窗口是一样的:

  1. <guilayout>  
  2.   <window type="DefaultWindow" name="root">  
  3.     <window type="TaharezLook/FrameWindow" name="testWindow">  
  4.       <property name="UnifiedPosition" value="{{0.25,0},{0.25,0}}">  
  5.       <property name="UnifiedSize" value="{{0.5,0},{0.5,0}}">  
  6.       <property name="Text" value="Hello World!">  
  7.     </property></property></property></window>  
  8.   </window>  
  9. </guilayout>  

Window元素的属性和WindowManager::createWindow函数的参数是一一对应的。参见上面讨论过的createWindow 函数
镶嵌的Window元素用来表明窗口的父子关系。注意:在一个布局文件中,你仅可以拥有一个“根”级别的窗口,这也是通常情况下把DefaultWindow用作根窗口的另一个原因。

Property元素是用来设置当前窗口的属性的。每种窗口/控件类都有很多属性,而且每个类都从它的父类中继承所有的属性。可以在这里查看所有硬编码属性以及它们的格式。由于“Falagard”蒙皮('Falagard' skins)可以创建自己的属性,你所使用的窗口可能会有更多的属性 ---- 对于那些“软编码”属性,你需要参阅你所使用的蒙皮的相关文档(参看样品蒙皮TaharezLookWindowsLook)。

如果保存此布局文件为“test.layout”,你可以按如下方法加载并设置GUI根窗口:

  1. using namespace CEGUI;  
  2. Window* myRoot = WindowManager::getSingleton().loadWindowLayout(   
  3.                                             "test.layout" );  
  4. System::getSingleton().setGUISheet( myRoot );  

编译运行后得到的结果和前面用C++写的程序是一样的。不过,现在你可以轻松修改、增强GUI布局而不用修改、重新编译代码啦。

总结

现在,你已经学习了:基本窗口的创建,多窗口的创建,以及如何修改窗口设置。你学习了如何通过C++硬编码实现和如何通过XML布局文件实现。有很多更先进的方法可以同时使用那两种方式,但这最好留给更高级的教程去讲解。

原创粉丝点击