【CEGUI】CEGUI入门篇之创建window(四)

2022-09-15 10:27:20 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

以下内容翻译自http://static.cegui.org.uk/docs/0.8.7/window_tutorial.html

这里介绍CEGUI window的创建及如何让window在屏幕上显示出来,在此之前,需要了解“CEGUI入门篇之初始化(一)”、“CEGUI入门篇之使用ResourceProvider加载资源(二)”和“CEGUI入门篇之数据文件及默认初始化(三)”。

1、window和widget相关概念

一切widget都是window——

在CEGUI中,一切widget都是window,这是一个很重要的概念,所有的widget都继承自同一个window基类,所以适用于window的东西同样适用于widget,如PushButton、Scrollbar等widget。

属性继承——

在CEGUI的window层级结构中,许多可用的设置和属性都会从上层传递到下层,比如说设置了某个window的alpha属性为0.5,将影响其所有的子window,但子window的alpha属性值保持不变,最终效果为从上到下的层级结构中alpha属性的混合,同时这种特性还适用于对象析构,当某个window销毁时,还自动销毁它所有的子window。CEGUI的这种属性继承特性主要是方便通过修改root window的属性而影响所有的window,当然还可以分别对不同的子window进行不同的修改。

2、创建window

创建window有两种方式,通过C 代码或者xml layout文件。

通过C 代码创建window——

CEGUI中的window都通过WindowManager这个单例来创建,获取WindowManager的方法如下:

代码语言:javascript复制
using namespace CEGUI;
WindowManager& wmgr = WindowManager::getSingleton();

一般来说,在GUI布局中使用DefaultWindow作为root window,虽不是必需的,但这是CEGUI强烈推荐使用的一种模式,有助于处理输入事件,后续更多的window也能很好的布局。DefaultWindow作为应用程序和布局文件的root window,覆盖了整个窗口,可以在任何时候设置作为root window,但只能有一个root window,其它所有的window都必须依附于这个root window。DefaultWindow创建方法如下:

代码语言:javascript复制
Window* myRoot = wmgr.createWindow( "DefaultWindow", "root" );
System::getSingleton().getDefaultGUIContext().setRootWindow( myRoot );

WindowManager::createWindow函数有两个字符串类型的参数,第一个参数如DefaultWindow为window的类型,这些window类型是在加载的scheme文件中注册过的,第二个参数如root为这个window的名字。GUIContext::setRootWindow函数用于设置给定GUIContext的root window,会替换掉之前的root window,但之前的root window只是从GUIContext分离而没有被销毁。通过GUIContext创建了第一个window即root window后,系统将使用这个root window进行GUI描画,但这个DefaultWindow是不可视的,是一个空白的画布,需要添加其它window,如FrameWindow,类似于桌面上的window,有标题栏,可以移动,可以缩放,代码如下:

代码语言:javascript复制
FrameWindow* fWnd = static_cast<FrameWindow*>(
    wmgr.createWindow( "TaharezLook/FrameWindow", "testWindow" ));

上面创建了一个类型为TaharezLook/FrameWindow的window,名字为testWindow,这些在加载的scheme文件中已经定义,同时还要向下转换Window指针为FrameWindow指针。FrameWindow创建成功后,首先需要添加到root window上,如下:

代码语言:javascript复制
myRoot->addChild( fWnd );

然后可以给window设置位置和大小,CEGUI有特殊的坐标系统(可参考http://static.cegui.org.uk/docs/0.8.7/fal_intro.html#fal_unifiedsystem),相对的scale和绝对的offset,如下:

代码语言:javascript复制
// position a quarter of the way in from the top-left of parent.
fWnd->setPosition( UVector2( UDim( 0.25f, 0.0f ), UDim( 0.25f, 0.0f ) ) );
// set size to be half the size of the parent
fWnd->setSize( USize( UDim( 0.5f, 0.0f ), UDim( 0.5f, 0.0f ) ) );

最后,给window的标题栏设置内容:

代码语言:javascript复制
fWnd->setText( "Hello World!" );

这样,一个基本的FrameWindow(testWindow)就创建完成了,其父亲为DefaultWindow(root)。在CEGUI的window层级结构中,其实是一个树状结构,还有一个很重要的东西是window路径,当window布局较复杂时,很可能需要从某个window中访问它的子window,这时就可以使用window路径,把各个window的名字以斜线/拼接起来即可,如上面例子中的root/testWindow,使用CEGUI::Window::getChild函数获取子window,函数参数不包括当前window名,如从DefaultWindow(root)中获取FrameWindow(testWindow)时参数为testwindow,如果FrameWindow(testWindow)有一个名为myButton的子window,那么从DefaultWindow(root)中获取myButton的函数参数就是testwindow/myButton。

通过xml layout文件创建window——

上面通过C 代码创建window,但有其不足之处,每次调整GUI布局时都需要重新编码、编译,而xml layout文件则更为快捷,通过WindowManager加载一个xml文件就搞定了,并且帮我们创建好了所有的window,返回一个root window供我们使用。首先,需要创建一个xml文件(test.layout),如下的xml文件等同于上面的通过C 代码创建window的例子。

代码语言:javascript复制
<?xml version="1.0" ?>
<GUILayout version="4">
    <Window type="DefaultWindow" name="root">
        <Window type="TaharezLook/FrameWindow" name="testWindow">
            <Property name="Position" value="{ {0.25, 0}, {0.25, 0} }" />
            <Property name="Size" value="{ {0.5, 0}, {0.5, 0} }" />
            <Property name="Text" value="Hello World!" />
        </Window>
    </Window>
</GUILayout>

xml文件中的Window通过WindowManager::createWindow函数创建,函数参数为type和name,嵌套的Window表示树状关系,Property用于设置属性。创建好xml文件后,通过下面的函数加载。

代码语言:javascript复制
using namespace CEGUI;
Window* myRoot = WindowManager::getSingleton().loadLayoutFromFile( "test.layout" );
System::getSingleton().getDefaultGUIContext().setRootWindow( myRoot );

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/163743.html原文链接:https://javaforall.cn

0 人点赞