CEGUI 使用方法 四

来源:互联网 发布:java 线程挂起和唤醒 编辑:程序博客网 时间:2024/06/06 01:07

创建CEGUI窗口入门

 

本课将讲述如何创建并显示一个简单的CEGUI窗口。在继续之前,请确保你已经通读并完全理解了前面的几篇教程:CEGUI渲染入门,资源管理入门和装载数据文件和初始化入门。这非常重要,因为本教程是建立在那些教程的基础之上的。

 

概念介绍:窗口和控件

在进行教程之前,你必须了解一些重要的概念。


所有的控件都是窗口
这是最重要的概念。所有的控件类都是从Window这个基类派生出来的,所以,在此教程中,每当我提到一个窗口的时候,它可以是一个按钮也可以是一个滚动条控件。


很多的设置都会被继承下去
CEGUI中,窗口的很多的设置和属性都会按窗口父子等级向下传递。比如:如果你将一个窗口的alpha透明度设置为0.5,那么,默认情况下,所有附属于那个窗口的子窗口/组件都将受到影响。同时要注意:子窗口的实际设置并没有改变 ---- 最终的属性值通常是由最顶层到当前窗口所有属性值组合而成的。好多东西都有这个规律,比如窗口的销毁:默认情况下,一个窗口在销毁的时候将销毁它的所有子窗口。这一机制最大的优点是:通过改变根窗口的alpha透明度、显示/隐藏、激活/禁用状态等可以很轻易的控制整个GUI;通过简单的销毁根窗口就可以轻松的清空整个GUI。当个别窗口需要更精确的控制或有更好的管理技术用的时候,可以更改这一默认继承机制。


创建窗口


聊够了!我们开始吧。
有两种方法来创建窗口:通过C++硬编码实现和通过XML布局文件实现。下面将讨论这两种方法。


通过C++硬编码实现GUI
CEGUI的所有窗口都是被WindowManager这一对象创建的。你可以通过getSingleton函数获得这个对象,代码如下:
using namespace CEGUI;  
WindowManager& wmgr = WindowManager::getSingleton(); 

using namespace CEGUI;
WindowManager& wmgr = WindowManager::getSingleton();
一般情况,你将用DefaultWindow(或者它的老名字:DefaultGUISheet)作为GUI的“root”窗口。这点并不是必须的,但它是使用CEGUI很好的习惯,而且可以帮助简化布局。

下一步,我们将创建一个DefaultWindow作为GUI的根窗口(这里sheet是root的意思)。
Window* myRoot = wmgr.createWindow( "DefaultWindow", "root" );  
System::getSingleton().setGUISheet( myRoot ); 

Window* myRoot = wmgr.createWindow( "DefaultWindow", "root" );
System::getSingleton().setGUISheet( myRoot );
WindowManager::createWindow函数有两个string类型的参数。第一个参数,本例中为“DefaultWindow”,告诉系统你要创建的窗口类型或类。通常,你可以使用的窗口类型是那些当你载入scheme文件的时候注册的窗口类。而有些像DefaultWindow这样的是全局类型,它们总是可用的。第二个参数,本例中为“root”,是一个将要赋予这个窗口的独一无二的名字。以后可以通过这个名字获取指向这个窗口的指针。注意:并不是一定要给你的根窗口命名为“root”,但这是通常的命名约定。

System::setGUISheet函数用来指定一个窗口作为GUI的根窗口。这将替换掉当前的根窗口,但是要注意:之前的一系列窗口/控件并没有被销毁,只是从当前的显示链中摘除 ---- 通过使用setGUISheet函数,你可以轻松的在多个GUI中切换。

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

现在,我们将要创建一个框架窗口:这个窗口和你桌面上的窗口很类似,它有一个标题栏,也可以移动和改变大小。代码如下:
FrameWindow* fWnd = (FrameWindow*)wmgr.createWindow(   
                        "TaharezLook/FrameWindow", "testWindow" ); 

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

为了让系统能够用我们的新窗口做一些有用的事情,我们还需要做一些事情。

首先,我们必须把这个新窗口附着到我们上面指定的根窗口上,代码如下:
myRoot->addChildWindow( fWnd ); 

myRoot->addChildWindow( fWnd );
现在,我们可以设置它的位置和大小。CEGUI使用一个“统一的(unified)”坐标系,使得可以同时使用相对部分和绝对部分 ---- 这就是为什么你看到的每个坐标都由两个部分组成。想了解更多请看Introduction and overview of core "Falagard" support systems 一文。回到这个例子:
// 定位在其父窗口左上角开始的1/4位置  
fWnd->setPosition(UVector2( UDim( 0.25f, 0 ), UDim( 0.25f, 0 ) ) );  
 
// 设置其大小为其父窗口的一半  
fWnd->setSize( UVector2( UDim( 0.5f, 0 ), UDim( 0.5f, 0 ) ) ); 

// 定位在其父窗口左上角开始的1/4位置
fWnd->setPosition(UVector2( UDim( 0.25f, 0 ), UDim( 0.25f, 0 ) ) );

// 设置其大小为其父窗口的一半
fWnd->setSize( UVector2( UDim( 0.5f, 0 ), UDim( 0.5f, 0 ) ) );
最后,我们为这个框架窗口的标题栏设置一个标题:
fWnd->setText( "Hello World!" ); 

fWnd->setText( "Hello World!" );
就这样!当编译运行,你会看到一个简单的框架窗口显示在正中央。

 

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

系统支持XML格式的布局文件,可以通过WindowManager::loadWindowLayout函数载入此文件。此函数为你创建所有的窗口并返回一个指向根窗口的指针。调用setGUISheet设置GUI的根窗口的时候用此指针再适合不过了。

所以,首先我们需要一个布局文件。下面这个XML文件所描述的窗口和我们上面用C++创建的窗口是一样的:
<?xml version="1.0" ?> 
<GUILAYOUT> 
  <WINDOW Type="DefaultWindow" Name="root"> 
    <WINDOW Type="TaharezLook/FrameWindow" Name="testWindow"> 
      <Property Name="UnifiedPosition" Value="{{0.25,0},{0.25,0}}"></Property> 
      <Property Name="UnifiedSize" Value="{{0.5,0},{0.5,0}}"></Property> 
      <Property Name="Text" Value="Hello World!"></Property> 
    </WINDOW> 
  </WINDOW> 
</GUILAYOUT> 
  
         
     

Window元素的属性和WindowManager::createWindow函数的参数是一一对应的。参见上面讨论过的 createWindow 函数。

镶嵌的Window元素用来表明窗口的父子关系。注意:在一个布局文件中,你仅可以拥有一个“根”级别的窗口,这也是通常情况下把DefaultWindow用作根窗口的另一个原因。

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

如果保存此布局文件为“test.layout”,你可以按如下方法加载并设置GUI根窗口:
using namespace CEGUI;  
Window* myRoot = WindowManager::getSingleton().loadWindowLayout(   
                                            "test.layout" );  
System::getSingleton().setGUISheet( myRoot ); 

using namespace CEGUI;
Window* myRoot = WindowManager::getSingleton().loadWindowLayout(
           "test.layout" );
System::getSingleton().setGUISheet( myRoot );
编译运行后得到的结果和前面用C++写的程序是一样的。不过,现在你可以轻松修改、增强GUI布局而不用修改、重新编译代码啦。

 

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


原文作者:CrazyEddie
原作日期:Not Given
原文地址:The Beginner Guide to Creating a CEGUI Window
翻 译 者:天外|OutSky
翻译日期:2008-09-30 04:25

以前,我曾幻想自己做所有东西,包括游戏GUI。现在,我才发现这种想法多么幼稚。更体会到开源精神的伟大!


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/pepper6681747/archive/2008/10/26/3151311.aspx

原创粉丝点击