在本教程中我们将介绍以下操作的基本知识:
在本教程中我们将学习在 Vision 中创建并显示 GUI 的基本要素。 我们将学习如何定义布局以及如何加载 XML 并通过修改它们来显示自定义菜单和对话框。 基本概念: Vision 的 GUI 系统基于引擎的底层 2D 渲染功能。 GUI 的类会被编译成 VisionEnginePlugin,因此在插件被加载的时候它们会被正确地初始化。 它支持对话框,事件以及很多不同种类的控件。 所需的资源和对话框布局都在 XML 资源文件中定义。 所有的GUI 资源,比如对话框布局、游标、字体等等都通过专有的 GUI 管理器处理。 该管理器维护一个列表,管理所有使用 GUI 资源的 GUI 环境。 一个 GUI 环境的实例定义了一个独立于其它 GUI 环境的具体的状态(例如,如果场景中有很多控制台模型的实例,这些控制台显示带有门禁密码的用户界面,每一个控制台都可以处于不同的状态,锁定/解锁)。 创建你的第一个对话框:
#include <Vision/Runtime/EnginePlugins/VisionEnginePlugin/GUI/vGUI.hpp>
VSmartPtr<VGUIMainContext> spGUIContext; VDialogPtr spMainDlg;
void InitGUI() { spGUIContext = new VGUIMainContext(NULL); spGUIContext->SetActivate(true);
// 加载默认资源(比如字体或游标的图片) VGUIManager::GlobalManager().LoadResourceFile("Dialogs\\MenuSystem.xml");
// 加载并显示主菜单布局 spMainDlg = spGUIContext->ShowDialog("Dialogs\\MainMenu.xml"); VASSERT(spMainDlg); } 在 VISION_INIT 回调函数返回 true 之前调用此函数: VISION_INIT { // ... InitGUI(); return true; }
void DeInitGUI() { spMainDlg = NULL; // 销毁主对话框对象 spGUIContext->SetActivate(false); // 关闭 GUI 环境... spGUIContext = NULL; // ... 并将其销毁 } 不要忘记在 VISION_DEINIT 中调用它: VISION_DEINIT { DeInitGUI(); // ... }
VISION_SAMPLEAPP_RUN { return spApp->Run() && spMainDlg->GetDialogResult()!=VGUIManager::ID_CANCEL; }
恭喜! 你已经成功地在 Vision 中创建了一个 GUI 对话框! 修改 XML 布局: 现在我们有了一个可以运行的 GUI,再来看看布局是如何定义的。 对话框布局文件以 XML 形式存储。 对话框的类名以及所有关于控件的信息都储存在 XML 文件中。 一个典型的对话框资源 XML 是这样的: <root> <DIALOG class="VDialog" name="MainMenu" fullscreen="FALSE" size="300,140" startPosition="ScreenCenter"> <control class="..." .../> <control class="..." .../> <control class="..." .../> </DIALOG> </root>
来理解一下用到的语法。 有许多种类的控件:文本框、列表、检索图、滑块等等。 可以在这里找到关于 XML 控件的完整参考说明:
<!-- Quit button --> <control class="VPushButton" ID="QUIT" ... > ... <image texture="Button.tga" valign="CENTER" halign="CENTER"> <statemodifier state="mouseOver" texture="ButtonMouseOver.tga" cursor="HighMouse"/> <statemodifier state="selected" texture="ButtonClicked.tga" cursor="HighMouse"/> <statemodifier state="disabled" texture="ButtonDisabled.tga"/> </image> </control> 按钮拥有不同的状态(mouseOver、selected、disabled)。 你可以为每种状态设置不同的图片。 你还能改变与按钮互动时的游标图片。
如果你将鼠标移到按钮上,你会看到按钮和鼠标的外观都发生了改变。 在你点击它的时候同样会变化。
恭喜! 你已经成功地在 Vision 中修改了 GUI 布局! 动态地为对话框实例添加项目: 某些情况下需要动态地为对话框添加没有预先在 XML 中定义的控件(例如,一个带有可变数量控件的表格)。 在对话框实例中添加控件非常方便。
2. 新建一个函数来创建和添加新的文本标签: void AddTextLabel(const char* pText, float pX, float pY) { // 创建一个新的文本标签 VTextLabel* pTextLabel = new VTextLabel(); // 设置属性 pTextLabel->SetPosition(pX,pY); pTextLabel->SetText(pText); pTextLabel->SetSize(150,35); VTextStates &states = pTextLabel->Text(); states.SetColor(VColorRef(255,255,255,255)); states.SetFont(Vision::Fonts.FindFont("MenuFont")); // 将控件添加到对话框中 spMainDlg->AddControl(pTextLabel); }
然后在 InitGUI 之后调用它: VISION_INIT { // ... InitGUI(); AddTextLabel("My Dynamic Label",30,250); return true; }
如果你想要动态地添加其它种类的控件,可以在文档中找到更多的信息:Vision Engine Programmer's Documentation -> Tutorials for Programmers -> GUI System Tutorial。 恭喜! 你已经成功地在 Vision 中向 GUI 添加了一个动态控件! 创建你自已的对话框类: 很多情况下你需要在应用程序中自定义 GUI 的行为,那么你就需要实现自己的控件或对话框。 由于 GUI 系统使用动态类型管理,可以很直接地实现自定义控件或对话框。 作为示例,我们现在添加一个消息确认对话框,让它在 InitGUI 函数之后启动:
class SubDialog : public VDialog { public: // 响应点击事件 VOVERRIDE void OnItemClicked(VMenuEventDataObject *pEvent); protected: V_DECLARE_SERIAL_DLLEXP( SubDialog, DECLSPEC_DLLEXPORT ) VOVERRIDE void Serialize( VArchive &ar ) {} };
void SubDialog::OnItemClicked(VMenuEventDataObject *pEvent) { VDialog::OnItemClicked(pEvent); int iDlgResult = GetDialogResult(); if (iDlgResult == VGUIManager::ID_NO) { GetContext()->CloseDialog(this); spApp->Quit(); <segment 1664> } else if (iDlgResult == VGUIManager::ID_YES) { GetContext()->CloseDialog(this); } }
// 注册你的自定义对话框类 VModule &GUIModule = VGUIManager::GUIModule(); V_IMPLEMENT_SERIAL(SubDialog, VDialog, 0, &GUIModule);
VDialogPtr spSubDlg; 在 VISION_INIT 中于 InitGUI 和 AddTextLabel 之后将其初始化并显示新对话框: VISION_INIT { // ... InitGUI(); AddTextLabel("My Dynamic Label",30,250); spSubDlg = spGUIContext->ShowDialog("Dialogs\\MessageBox.xml"); return true; }
VISION_DEINIT { spSubDlg = NULL; // 销毁 SubDialog 对象 DeInitGUI(); // ... }
<root> <DIALOG class="SubDialog" name="MessageBox" fullscreen="FALSE" size="300,140" startPosition="ScreenCenter"> ... </DIALOG> </root> 保存文件。
恭喜! 你已经成功地在 Vision 中创建了一个自定义对话框! 总结: 你已经成功地完成了在 Vision 中创建 GUI 的第一个教程。 但我们仅仅涉及到了初级的功能,Vision 的 GUI 系统提供了很多的可能性。 我们鼓励你尝试不同的控件和对话框,阅读 Programmer's Documentation 并查看 GUI Engine Sample。在该样例中你会看到很多高级的 GUI 功能。 |