CEGUI 探讨 定制
我喜欢看张国荣的《东邪西毒》
讨论对象:CEGUI 0.7.1
1.从源代码开始
下完cegui 0.7.1 解压到当前文件夹 得到一个CEGUI-0.7.1文件夹 下载deps 解压到该目录下 形成类似
./CEGUI-0.7.1
./CEGUI-0.7.1/dependencies
./CEGUI-0.7.1/bin
的目录结构 转到./CEGUI-0.7.1/projects/premake/
里面有许多版本的VS 我的版本是VS 2008的 在运行build_vs2008.bat之前 打开config.lua
该文件定制cegui的各个模块 来看下我的:
--
-- CEGUI premake configuration script
--
-- comment this to disable debug suffixes for dynamic module dlls
-- if you want to use another suffix, just change the string :)
-- all the debug cegui libraries are built with this suffix
DEBUG_DLL_SUFFIX = " _d "
-- SDK / dependency paths
-- { base, include_suffix, library_suffix }
-- base can be absolute or relative to the root cegui_mk2 dir
IRRLICHT_PATHS = { " irrlicht-1.4 " , " include " , " lib/Win32-visualstudio " }
OGRE_PATHS = { " D:/wildpigdev/ogre/ogre_src_v1-7-1/vc9/sdk " , " include/OGRE " , " lib " }
OIS_PATHS = { " D:/wildpigdev/ogre/ogre_src_v1-7-1/vc9/sdk " , " include/OIS " , " lib " }
--- Irrlicht SDK Version
--- 14 is means 1.4 or 1.5 .x and 16 means 1.6 ( and above?)
CEGUI_IRR_SDK_VERSION = 14
--- OIS API version to be used in the Ogre samples base app.
--- true: use older numKeyboards / numMice
--- false: use getNumberOfDevices
CEGUI_OLD_OIS_API = false
--- Lua version
--- 51 is 5.1 ( and above?) From 0.7 .0 onwards, lua 5.0 is no longer supported.
CEGUI_LUA_VER = 51
--- Freetype library
--- CEGUI uses the freetype library for some of it ' s font support. To disable
--- the use of freetype, set this to false.
CEGUI_USE_FREETYPE = true
--- PCRE library
--- CEGUI uses the pcre library for it ' s regular expression based string
--- validation as used in the Editbox ( and derived classes, such as Spinner).
--- To disable the use of PCRE ( and therefore the validation factilities), set
--- this to false. (Attempts to set validation string will throw).
CEGUI_USE_PCRE_REGEX = true
--- CEGUI::DefaultLogger
--- To disable compilation and use of the CEGUI::DefaultLogger, set this to
--- false.
---
--- Note: If you disable this, you MUST provide an alternative CEGUI::Logger
--- based class and instantiate it before creating the main CEGUI::System object.
CEGUI_USE_DEFAULT_LOGGER = true
--- BiDirectional text support.
--- To enable support for bi - directional text in CEGUI, set CEGUI_BIDI_SUPPORT
--- to true.
--- With bidirectional support enabled, CEGUI_USE_MINIBIDI then controls whether
--- that support is provided viaan embedded copy of minibidi (true) or an
--- external copy of the fribidi library (false).
CEGUI_BIDI_SUPPORT = false;
CEGUI_USE_MINIBIDI = true;
-------------
-- Renderers
-- this controls which renderer modules are built
OPENGL_RENDERER = false
DIRECT3D9_RENDERER = false
DIRECT3D10_RENDERER = false
IRRLICHT_RENDERER = false
OGRE_RENDERER = true
----------------
-- Image Codecs
-- this controls which image codecs are built
TGA_IMAGE_CODEC = false
SILLY_IMAGE_CODEC = false
DEVIL_IMAGE_CODEC = false
FREEIMAGE_IMAGE_CODEC = true
CORONA_IMAGE_CODEC = false
-- this setting selects the default image codec module
-- can be either " tga " , " silly " , " devil " , " freeimage " or " corona "
-- SILLY was written for CEGUI
DEFAULT_IMAGE_CODEC = " freeimage "
---------------
-- Window Renderers
-- controls window renderers built
FALAGARD_WR = true
-- default WR
-- available: falagard
DEFAULT_WINDOW_RENDERER = " falagard "
---------------
-- XML parsers
-- this controls which xml parser modules are built
EXPAT_PARSER = true
XERCES_PARSER = false
TINYXML_PARSER = false
LIBXML_PARSER = false
-- this selects the default XML parser module
-- can be either " expat " , " xerces " , " tinyxml " or " libxml "
DEFAULT_XML_PARSER = " expat "
-------
-- Lua
-- this controls whether CEGUILua is enabled
LUA_SCRIPT_MODULE = true
-- disable this for a smaller and faster, but less safe Lua module
-- only affects Release builds. Debug and ReleaseWithSymbols always
-- enable this
LUA_SCRIPT_MODULE_SAFE = false
-- enable this to build the bundled tolua ++ as a static library
TOLUA_STATIC = false
-----------
-- Samples
-- remember you have to edit CEGUISamplesConfig.h as well this just controls
-- dependencies etc. if the renderer is disabled this has no effect
SAMPLES_GL = false
SAMPLES_DX9 = false
SAMPLES_DX10 = false
SAMPLES_IRRLICHT = false
SAMPLES_OGRE = true
-- this setting controls if the samples should be included in the same
-- solution as the core libraries. If this setting is disabled you can
-- still generate a seperate solution for the samples
--
-- due to a missing feature in premake enabling this will cause the
-- output files to be placed in cegui_mk2 / bin and not cegui_mk2 / Samples / bin
--
SAMPLES_INCLUDED = true
-- CEGUI premake configuration script
--
-- comment this to disable debug suffixes for dynamic module dlls
-- if you want to use another suffix, just change the string :)
-- all the debug cegui libraries are built with this suffix
DEBUG_DLL_SUFFIX = " _d "
-- SDK / dependency paths
-- { base, include_suffix, library_suffix }
-- base can be absolute or relative to the root cegui_mk2 dir
IRRLICHT_PATHS = { " irrlicht-1.4 " , " include " , " lib/Win32-visualstudio " }
OGRE_PATHS = { " D:/wildpigdev/ogre/ogre_src_v1-7-1/vc9/sdk " , " include/OGRE " , " lib " }
OIS_PATHS = { " D:/wildpigdev/ogre/ogre_src_v1-7-1/vc9/sdk " , " include/OIS " , " lib " }
--- Irrlicht SDK Version
--- 14 is means 1.4 or 1.5 .x and 16 means 1.6 ( and above?)
CEGUI_IRR_SDK_VERSION = 14
--- OIS API version to be used in the Ogre samples base app.
--- true: use older numKeyboards / numMice
--- false: use getNumberOfDevices
CEGUI_OLD_OIS_API = false
--- Lua version
--- 51 is 5.1 ( and above?) From 0.7 .0 onwards, lua 5.0 is no longer supported.
CEGUI_LUA_VER = 51
--- Freetype library
--- CEGUI uses the freetype library for some of it ' s font support. To disable
--- the use of freetype, set this to false.
CEGUI_USE_FREETYPE = true
--- PCRE library
--- CEGUI uses the pcre library for it ' s regular expression based string
--- validation as used in the Editbox ( and derived classes, such as Spinner).
--- To disable the use of PCRE ( and therefore the validation factilities), set
--- this to false. (Attempts to set validation string will throw).
CEGUI_USE_PCRE_REGEX = true
--- CEGUI::DefaultLogger
--- To disable compilation and use of the CEGUI::DefaultLogger, set this to
--- false.
---
--- Note: If you disable this, you MUST provide an alternative CEGUI::Logger
--- based class and instantiate it before creating the main CEGUI::System object.
CEGUI_USE_DEFAULT_LOGGER = true
--- BiDirectional text support.
--- To enable support for bi - directional text in CEGUI, set CEGUI_BIDI_SUPPORT
--- to true.
--- With bidirectional support enabled, CEGUI_USE_MINIBIDI then controls whether
--- that support is provided viaan embedded copy of minibidi (true) or an
--- external copy of the fribidi library (false).
CEGUI_BIDI_SUPPORT = false;
CEGUI_USE_MINIBIDI = true;
-------------
-- Renderers
-- this controls which renderer modules are built
OPENGL_RENDERER = false
DIRECT3D9_RENDERER = false
DIRECT3D10_RENDERER = false
IRRLICHT_RENDERER = false
OGRE_RENDERER = true
----------------
-- Image Codecs
-- this controls which image codecs are built
TGA_IMAGE_CODEC = false
SILLY_IMAGE_CODEC = false
DEVIL_IMAGE_CODEC = false
FREEIMAGE_IMAGE_CODEC = true
CORONA_IMAGE_CODEC = false
-- this setting selects the default image codec module
-- can be either " tga " , " silly " , " devil " , " freeimage " or " corona "
-- SILLY was written for CEGUI
DEFAULT_IMAGE_CODEC = " freeimage "
---------------
-- Window Renderers
-- controls window renderers built
FALAGARD_WR = true
-- default WR
-- available: falagard
DEFAULT_WINDOW_RENDERER = " falagard "
---------------
-- XML parsers
-- this controls which xml parser modules are built
EXPAT_PARSER = true
XERCES_PARSER = false
TINYXML_PARSER = false
LIBXML_PARSER = false
-- this selects the default XML parser module
-- can be either " expat " , " xerces " , " tinyxml " or " libxml "
DEFAULT_XML_PARSER = " expat "
-------
-- Lua
-- this controls whether CEGUILua is enabled
LUA_SCRIPT_MODULE = true
-- disable this for a smaller and faster, but less safe Lua module
-- only affects Release builds. Debug and ReleaseWithSymbols always
-- enable this
LUA_SCRIPT_MODULE_SAFE = false
-- enable this to build the bundled tolua ++ as a static library
TOLUA_STATIC = false
-----------
-- Samples
-- remember you have to edit CEGUISamplesConfig.h as well this just controls
-- dependencies etc. if the renderer is disabled this has no effect
SAMPLES_GL = false
SAMPLES_DX9 = false
SAMPLES_DX10 = false
SAMPLES_IRRLICHT = false
SAMPLES_OGRE = true
-- this setting controls if the samples should be included in the same
-- solution as the core libraries. If this setting is disabled you can
-- still generate a seperate solution for the samples
--
-- due to a missing feature in premake enabling this will cause the
-- output files to be placed in cegui_mk2 / bin and not cegui_mk2 / Samples / bin
--
SAMPLES_INCLUDED = true
我是用ogre来渲染的 需要注意的是 OGRE_PATHS OIS_PATHS 该路径自己选择 其他的都可根据个人需求定制 比如ImageCodec
定制完该lua脚本后 生成对应的VS版本 编译下 一般没啥问题 然后 可以看看自带的ogre的gui例子
说说初始化 在这个版本中相当简单 一行代码搞定
// 初始化
CEGUI::OgreRenderer::bootstrapSystem();
// 创建gui
CEGUI::SchemeManager::getSingleton().create("TaharezLook.scheme");
CEGUI::WindowManager& winMgr = CEGUI::WindowManager::getSingleton();
CEGUI::Window* root= winMgr.loadWindowLayout("yezhu.layout");
CEGUI::System::getSingleton().setGUISheet(root);
CEGUI::System::getSingletonPtr()->setDefaultMouseCursor((CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MouseArrow");
如果想知道更多 可以看其源代码
CEGUI::OgreRenderer::bootstrapSystem();
// 创建gui
CEGUI::SchemeManager::getSingleton().create("TaharezLook.scheme");
CEGUI::WindowManager& winMgr = CEGUI::WindowManager::getSingleton();
CEGUI::Window* root= winMgr.loadWindowLayout("yezhu.layout");
CEGUI::System::getSingleton().setGUISheet(root);
CEGUI::System::getSingletonPtr()->setDefaultMouseCursor((CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MouseArrow");
如果要定制窗口 需要看看 TaharezLook.scheme这个文件 这是个xml文件 里面放着Imageset定义
Font定义 LookNFeel定义 了解这些新名词是定制窗口的关键 事情可以这样理解
LookNFeel文件在这里起着关键因素 我们生成的gui窗口的外貌和这个文件是息息相关的
打开这个LookNFeel文件 我们可以看到各种窗口的外观定义 如果我们要定制外观
修改现有的或者增加新的外观定义 特别感兴趣的可以 看看《火炬之光》里面的gui
迅雷单机游戏里有下的 玩起来还行。。。 ogre+cegui做的 可以打开她的gui文件看看
2.定制窗口
好 接下来 我们要定制窗口了 假如我们现在需要个性点的窗口 假如叫她MyButton 继承自CEGUI::PushButton
#ifndef MYBUTTON_H
#define MYBUTTON_H
#include < CEGUI.h >
namespace CEGUI
{
class MyButton : public PushButton
{
public :
MyButton( const String & type, const String & name);
virtual ~MyButton ();
static const String WidgetTypeName; //工厂名
};
}
#endif
需要注意的是WidgetTypeName 我们在创建窗口的时候最终会通过该名字来找到相应的工厂
#define MYBUTTON_H
#include < CEGUI.h >
namespace CEGUI
{
class MyButton : public PushButton
{
public :
MyButton( const String & type, const String & name);
virtual ~MyButton ();
static const String WidgetTypeName; //工厂名
};
}
#endif
每一个窗口都有相应的工厂用来创建自己
如果你查看cegui的初始化代码 你会看到一些类似以下的代码:
WindowFactoryManager::addFactory
<
TplWindowFactory
<
GUISheet
>
>
();
WindowFactoryManager::addFactory < TplWindowFactory < DragContainer > > ()
WindowFactoryManager::addFactory < TplWindowFactory < ScrolledContainer > > ();
WindowFactoryManager::addFactory < TplWindowFactory < ClippedContainer > > ();
WindowFactoryManager::addFactory < TplWindowFactory < Checkbox > > ();
WindowFactoryManager::addFactory < TplWindowFactory < PushButton > > ();
WindowFactoryManager::addFactory < TplWindowFactory < RadioButton > > ();
WindowFactoryManager::addFactory < TplWindowFactory < Combobox > > ();
所以 现在 我们要做的也是加入MyButton对应的工厂 不错 正如你所看到的 一行代码搞定
WindowFactoryManager::addFactory < TplWindowFactory < DragContainer > > ()
WindowFactoryManager::addFactory < TplWindowFactory < ScrolledContainer > > ();
WindowFactoryManager::addFactory < TplWindowFactory < ClippedContainer > > ();
WindowFactoryManager::addFactory < TplWindowFactory < Checkbox > > ();
WindowFactoryManager::addFactory < TplWindowFactory < PushButton > > ();
WindowFactoryManager::addFactory < TplWindowFactory < RadioButton > > ();
WindowFactoryManager::addFactory < TplWindowFactory < Combobox > > ();
WindowFactoryManager::addFactory
<
TplWindowFactory
<MyButton
>
>
()
注意的是 很显然 该行代码要在我们使用该窗口之前调用
接下来 看看MyButton的实现文件
#include
"MyButton
.h
"
namespace CEGUI
{
// 工厂名 通过该名字找到对应工厂
const String MyButton::WidgetTypeName( " Custom/MyButton " );
MyButton::MyButton( const String & type, const String & name) :PushButton(type, name)
{
}
MyButton:: ~ MyButton()
{
}
}
没啥特别的地方 你可以放置任何其他数据 好 目前为止 我们新建了一个窗口类 并把对应的工厂加入系统
namespace CEGUI
{
// 工厂名 通过该名字找到对应工厂
const String MyButton::WidgetTypeName( " Custom/MyButton " );
MyButton::MyButton( const String & type, const String & name) :PushButton(type, name)
{
}
MyButton:: ~ MyButton()
{
}
}
回过头看TaharezLook.scheme文件 我们可以看到里面有许多类似这样的元素:
<
FalagardMapping
WindowType
="TaharezLook/Button"
TargetType
="CEGUI/PushButton"
Renderer
="Falagard/Button"
LookNFeel
="TaharezLook/Button"
/>
< FalagardMapping WindowType ="TaharezLook/Checkbox" TargetType ="CEGUI/Checkbox" Renderer ="Falagard/ToggleButton" LookNFeel ="TaharezLook/Checkbox" />
< FalagardMapping WindowType ="TaharezLook/ImageButton" TargetType ="CEGUI/PushButton" Renderer ="Falagard/Button" LookNFeel ="TaharezLook/ImageButton" />
< FalagardMapping WindowType ="TaharezLook/Titlebar" TargetType ="CEGUI/Titlebar" Renderer ="Falagard/Titlebar" LookNFeel ="TaharezLook/Titlebar" />
< FalagardMapping WindowType ="TaharezLook/SystemButton" TargetType ="CEGUI/PushButton" Renderer ="Falagard/Button" LookNFeel ="TaharezLook/Button" />
< FalagardMapping WindowType ="TaharezLook/Editbox" TargetType ="CEGUI/Editbox" Renderer ="Falagard/Editbox" LookNFeel ="TaharezLook/Editbox" />
< FalagardMapping WindowType ="TaharezLook/Menubar" TargetType ="CEGUI/Menubar" Renderer ="Falagard/Menubar" LookNFeel ="TaharezLook/Menubar" />
WindowType是我们在创建窗口时用到的名字 当然 我们也可以直接用后面的TargetType
< FalagardMapping WindowType ="TaharezLook/Checkbox" TargetType ="CEGUI/Checkbox" Renderer ="Falagard/ToggleButton" LookNFeel ="TaharezLook/Checkbox" />
< FalagardMapping WindowType ="TaharezLook/ImageButton" TargetType ="CEGUI/PushButton" Renderer ="Falagard/Button" LookNFeel ="TaharezLook/ImageButton" />
< FalagardMapping WindowType ="TaharezLook/Titlebar" TargetType ="CEGUI/Titlebar" Renderer ="Falagard/Titlebar" LookNFeel ="TaharezLook/Titlebar" />
< FalagardMapping WindowType ="TaharezLook/SystemButton" TargetType ="CEGUI/PushButton" Renderer ="Falagard/Button" LookNFeel ="TaharezLook/Button" />
< FalagardMapping WindowType ="TaharezLook/Editbox" TargetType ="CEGUI/Editbox" Renderer ="Falagard/Editbox" LookNFeel ="TaharezLook/Editbox" />
< FalagardMapping WindowType ="TaharezLook/Menubar" TargetType ="CEGUI/Menubar" Renderer ="Falagard/Menubar" LookNFeel ="TaharezLook/Menubar" />
该名字就是对应的工厂名 Render不用去管她 相当于如何渲染
LookNFeel是重点 在对应的LookNFeel文件中我们可以找到该名字对应的定义
就是这些定义使得我们的窗口会呈现各种外观 所以下面的工作就是写LookNFeel定义
并通过程序加入如上的映射
好 关于如何写LookNFeel定义 好吧 这是另外一个主题了 在这里
我们假设在外观文件中新增一个外观定义“CustomLook/MyButton”
现在 我们要加入一个映射:
CEGUI::WindowFactoryManager
&
wfMgr
=
CEGUI::WindowFactoryManager::getSingleton();
wfMgr.addFalagardWindowMapping( " TaharezLook/MyButton " , " Custom/MyButton " , "CustomLook/MyButton " , " Falagard/Button " );
映射函数参数依次是 映射名 工厂名 外观定义名 Render名
wfMgr.addFalagardWindowMapping( " TaharezLook/MyButton " , " Custom/MyButton " , "CustomLook/MyButton " , " Falagard/Button " );
好了 现在你就可以使用这个新窗口了
CEGUI::WindowManager
*
m_WndMgr
=
CEGUI::WindowManager::getSingletonPtr();
m_WndMgr->createWindow("TaharezLook/MyButton","mytestwindow");
createWindow会从对应映射中找到工厂创建窗口
m_WndMgr->createWindow("TaharezLook/MyButton","mytestwindow");
基本就是这样 over~
PS:
另外 当我们只需要改变某个窗口的lookNFeel定义时
调用void Window::setLookNFeel(const String& look)
可以在运行时改变窗口的lookNFeel定义