图形用户界面 1
来源:互联网 发布:iphone 查看端口 编辑:程序博客网 时间:2024/06/06 01:07
在本教程中我们将介绍以下操作的基本知识:
- 创建一个 GUI 环境并将它激活
- 创建一个对话框实例
- 通过编辑 XML 来配置对话框
- 动态地向对话框中添加项目
- 实现一个自定义的对话框类并与按钮事件关联
在本教程中我们将学习在 Vision 中创建并显示 GUI 的基本要素。 我们将学习如何定义布局以及如何加载 XML 并通过修改它们来显示自定义菜单和对话框。
基本概念:
Vision 的 GUI 系统基于引擎的底层 2D 渲染功能。 GUI 的类会被编译成 VisionEnginePlugin,因此在插件被加载的时候它们会被正确地初始化。 它支持对话框,事件以及很多不同种类的控件。 所需的资源和对话框布局都在 XML 资源文件中定义。
所有的GUI 资源,比如对话框布局、游标、字体等等都通过专有的 GUI 管理器处理。 该管理器维护一个列表,管理所有使用 GUI 资源的 GUI 环境。 一个 GUI 环境的实例定义了一个独立于其它 GUI 环境的具体的状态(例如,如果场景中有很多控制台模型的实例,这些控制台显示带有门禁密码的用户界面,每一个控制台都可以处于不同的状态,锁定/解锁)。
创建你的第一个对话框:
- 确保你已经从主课程页面下载了样例工程。
- 本教程所需的文件在样例工程的“Dialogs”文件夹下。 你需要将 Dialogs 文件夹复制到: <VisionSDK>\Data\Vision\Samples\Engine\Maps\ViewerMap。 保持文件夹的名字为 Dialogs。
- 从 <VisionSDK>\Workspace 的一个子目录下打开一个 HavokVision_Samples_* 的方案
- 将“Tutorial01”工程设为起始工程然后打开它的 main.cpp 文件。
- 包含此 GUI 头文件:
#include <Vision/Runtime/EnginePlugins/VisionEnginePlugin/GUI/vGUI.hpp>
- 为了显示一个 GUI,第一步需要创建一个 GUI 环境以及 一个 GUI 对话框。 声明如下两个全局变量:
VSmartPtr<VGUIMainContext> spGUIContext;
VDialogPtr spMainDlg;
- 在你使用新的 GUI 环境之前,需要将其实例化并激活。 在 InitGUI 函数中初始化 GUI,加载所需的资源和菜单布局:
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;
}
- GUI 环境可以在整个游戏中一直保留,只要对话框处于关闭状态,它不会消耗太多内存或影响性能。 但需要在退出程序之前将其关闭并销毁,不然这个泄露会导致引擎在关闭时崩溃。 现在在 DeInitGUI 函数中关闭 GUI:
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>
- 打开“Dialogs”文件夹中的 MainMenu.xml。
- 你可以看到,这个 XML 定义了一个带有多种控件的对话框:
- 一个显示 Anarchy 徽标的图片控件。
- 一个黄颜色的文本标签,文本显示“Equipment Menu”。
- 两个勾选框。
- 一个标为“Quit”的按钮。
来理解一下用到的语法。 有许多种类的控件:文本框、列表、检索图、滑块等等。 可以在这里找到关于 XML 控件的完整参考说明:
- 我们现在改进一下“Quit”按钮,为它添加一个背景图。 把下列 XML 代码添加到 VPushButton 控件上:
<!-- 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)。 你可以为每种状态设置不同的图片。 你还能改变与按钮互动时的游标图片。
- 保存文件并重新运行程序。 “Quit”按钮现在看起来像这样:
如果你将鼠标移到按钮上,你会看到按钮和鼠标的外观都发生了改变。 在你点击它的时候同样会变化。
- 现在你可以尝试在 XML 改变或添加控件。
恭喜! 你已经成功地在 Vision 中修改了 GUI 布局!
动态地为对话框实例添加项目:
某些情况下需要动态地为对话框添加没有预先在 XML 中定义的控件(例如,一个带有可变数量控件的表格)。 在对话框实例中添加控件非常方便。
- 回到“Tutorial01”工程中修改 C++ 代码。
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;
}
- 编译并运行。 GUI 中现在会显示出你新加的动态标签:
如果你想要动态地添加其它种类的控件,可以在文档中找到更多的信息:Vision Engine Programmer's Documentation -> Tutorials for Programmers -> GUI System Tutorial。
恭喜! 你已经成功地在 Vision 中向 GUI 添加了一个动态控件!
创建你自已的对话框类:
很多情况下你需要在应用程序中自定义 GUI 的行为,那么你就需要实现自己的控件或对话框。 由于 GUI 系统使用动态类型管理,可以很直接地实现自定义控件或对话框。 作为示例,我们现在添加一个消息确认对话框,让它在 InitGUI 函数之后启动:
- 创建一个 SubDialog 类,继承自 VDialog,它将响应按钮点击事件:
class SubDialog : public VDialog
{
public:
// 响应点击事件
VOVERRIDE void OnItemClicked(VMenuEventDataObject *pEvent);
protected:
V_DECLARE_SERIAL_DLLEXP( SubDialog, DECLSPEC_DLLEXPORT )
VOVERRIDE void Serialize( VArchive &ar ) {}
};
- 实现重载的 OnItemClicked 函数,让对话框在任何按钮点击后关闭,如果点击了“NO”按钮则退出程序。
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。 然后你就能在界面 XML 中使用该类名。 在 OnItemClicked 函数后添加下列代码:
// 注册你的自定义对话框类
VModule &GUIModule = VGUIManager::GUIModule();
V_IMPLEMENT_SERIAL(SubDialog, VDialog, 0, &GUIModule);
- 现在你已经完成了 SubDialog 类的创建,声明一个全局变量以保存它的实例。
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 后将其销毁:
VISION_DEINIT
{
spSubDlg = NULL; // 销毁 SubDialog 对象
DeInitGUI();
// ...
}
- 最后你要做的就是在 XML 中使用你的类名。 打开“Dialogs”文件夹中的 MessageBox.xml。 将对话框的类名(VDialog)替换为你的类名(SubDialog)。
<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 功能。
转自:http://anarchy.cn/portal.php?mod=view&aid=34- [1.2.1] 图形用户界面
- 图形用户界面 1
- java图形用户界面1
- Lesson7 图形用户界面1
- Lesson7 图形用户界面1
- 图形用户界面1
- 图形用户界面1
- Lesson7 图形用户界面1
- Java图形用户界面设计1
- 图形用户界面 GUI(1)
- Java【图形用户界面(1)】
- Java图形用户界面(1)
- 图形用户界面
- 图形用户界面
- 图形用户界面
- 图形用户界面
- 图形用户界面
- 图形用户界面
- httpd服务和 apache tomcat有什么区别
- 使用Google code + SVN进行多人开发
- C/C++中extern关键字详解
- 为什么我觉得程序员需要谈恋爱以及为什么我不支持裸辞
- MyBatis的association示例——MyBatis学习笔记之三
- 图形用户界面 1
- 防止网页被嵌入框架的JS代码
- LeetCode之Valid Parentheses
- Qt+JS调用
- Asp.net浅谈之——内置对象
- tcp recv 和 udp recvfrom 接收的包个数
- js 中加减乘除js 中加减乘除
- java序列化与深度克隆
- 在windows 2008 64位环境下,oracle连接 Badimage 问题的解决