图形用户界面 1

来源:互联网 发布:iphone 查看端口 编辑:程序博客网 时间:2024/06/06 01:07

在本教程中我们将介绍以下操作的基本知识:

  • 创建一个 GUI 环境并将它激活
  • 创建一个对话框实例
  • 通过编辑 XML 来配置对话框
  • 动态地向对话框中添加项目
  • 实现一个自定义的对话框类并与按钮事件关联

在本教程中我们将学习在 Vision 中创建并显示 GUI 的基本要素。 我们将学习如何定义布局以及如何加载 XML 并通过修改它们来显示自定义菜单和对话框。

扩展阅读 - Vision Engine Programmers' Documentation:

Tutorials for Programmers -> GUI System Tutorial

基本概念:

Vision 的 GUI 系统基于引擎的底层 2D 渲染功能。 GUI 的类会被编译成 VisionEnginePlugin,因此在插件被加载的时候它们会被正确地初始化。 它支持对话框,事件以及很多不同种类的控件。 所需的资源和对话框布局都在 XML 资源文件中定义。

所有的GUI 资源,比如对话框布局、游标、字体等等都通过专有的 GUI 管理器处理。 该管理器维护一个列表,管理所有使用 GUI 资源的 GUI 环境。 一个 GUI 环境的实例定义了一个独立于其它 GUI 环境的具体的状态(例如,如果场景中有很多控制台模型的实例,这些控制台显示带有门禁密码的用户界面,每一个控制台都可以处于不同的状态,锁定/解锁)。

创建你的第一个对话框:

  1. 确保你已经从主课程页面下载了样例工程。
  2. 本教程所需的文件在样例工程的“Dialogs”文件夹下。 你需要将 Dialogs 文件夹复制到: <VisionSDK>\Data\Vision\Samples\Engine\Maps\ViewerMap。 保持文件夹的名字为 Dialogs。
  3. 从 <VisionSDK>\Workspace 的一个子目录下打开一个 HavokVision_Samples_* 的方案
  4. 将“Tutorial01”工程设为起始工程然后打开它的 main.cpp 文件。
  5. 包含此 GUI 头文件:

 


#include <Vision/Runtime/EnginePlugins/VisionEnginePlugin/GUI/vGUI.hpp>


  1. 为了显示一个 GUI,第一步需要创建一个 GUI 环境以及 一个 GUI 对话框。 声明如下两个全局变量:

 


VSmartPtr<VGUIMainContext> spGUIContext;

VDialogPtr spMainDlg;


  1. 在你使用新的 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;

}


  1. GUI 环境可以在整个游戏中一直保留,只要对话框处于关闭状态,它不会消耗太多内存或影响性能。 但需要在退出程序之前将其关闭并销毁,不然这个泄露会导致引擎在关闭时崩溃。 现在在 DeInitGUI 函数中关闭 GUI:

void DeInitGUI()

{

  spMainDlg = NULL;                  // 销毁主对话框对象

  spGUIContext->SetActivate(false);  // 关闭 GUI 环境...

  spGUIContext = NULL;               // ... 并将其销毁

}


不要忘记在 VISION_DEINIT 中调用它:


VISION_DEINIT

{

  DeInitGUI();

  // ...

}


  1. 最后,还应该处理返回结果:

VISION_SAMPLEAPP_RUN
{
  return spApp->Run() && spMainDlg->GetDialogResult()!=VGUIManager::ID_CANCEL;
}

  1. 编译并运行。 你会看到如图所示的菜单:


恭喜! 你已经成功地在 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>

  1. 打开“Dialogs”文件夹中的 MainMenu.xml
  2. 你可以看到,这个 XML 定义了一个带有多种控件的对话框:
    1. 一个显示 Anarchy 徽标的图片控件。
    2. 一个黄颜色的文本标签,文本显示“Equipment Menu”。
    3. 两个勾选框。
    4. 一个标为“Quit”的按钮。

 

来理解一下用到的语法。 有许多种类的控件:文本框、列表、检索图、滑块等等。 可以在这里找到关于 XML 控件的完整参考说明:

扩展阅读 - Control XML Reference

Tutorials for Programmers -> GUI System Tutorial -> 6. Control XML Reference

 

  1. 我们现在改进一下“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)。 你可以为每种状态设置不同的图片。 你还能改变与按钮互动时的游标图片。

  1. 保存文件并重新运行程序。 “Quit”按钮现在看起来像这样:

如果你将鼠标移到按钮上,你会看到按钮和鼠标的外观都发生了改变。 在你点击它的时候同样会变化。

  1. 现在你可以尝试在 XML 改变或添加控件。

恭喜! 你已经成功地在 Vision 中修改了 GUI 布局!


动态地为对话框实例添加项目:


某些情况下需要动态地为对话框添加没有预先在 XML 中定义的控件(例如,一个带有可变数量控件的表格)。 在对话框实例中添加控件非常方便。

  1. 回到“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;

}


  1. 编译并运行。 GUI 中现在会显示出你新加的动态标签:


如果你想要动态地添加其它种类的控件,可以在文档中找到更多的信息:Vision Engine Programmer's Documentation -> Tutorials for Programmers -> GUI System Tutorial。

恭喜! 你已经成功地在 Vision 中向 GUI 添加了一个动态控件!


创建你自已的对话框类:


很多情况下你需要在应用程序中自定义 GUI 的行为,那么你就需要实现自己的控件或对话框。 由于 GUI 系统使用动态类型管理,可以很直接地实现自定义控件或对话框。 作为示例,我们现在添加一个消息确认对话框,让它在 InitGUI 函数之后启动:

  1. 创建一个 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 ) {}

};


  1. 实现重载的 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);

  }

}


  1. 为了完成类的创建,你需要将它注册到一个自定义 VModule。 然后你就能在界面 XML 中使用该类名。 在 OnItemClicked 函数后添加下列代码:

// 注册你的自定义对话框类

VModule &GUIModule = VGUIManager::GUIModule();

V_IMPLEMENT_SERIAL(SubDialog, VDialog, 0&GUIModule);


  1. 现在你已经完成了 SubDialog 类的创建,声明一个全局变量以保存它的实例。

VDialogPtr spSubDlg;


在 VISION_INIT 中于 InitGUI 和 AddTextLabel 之后将其初始化并显示新对话框:


VISION_INIT

{

  // ...

  InitGUI();

  AddTextLabel("My Dynamic Label",30,250);

  spSubDlg = spGUIContext->ShowDialog("Dialogs\\MessageBox.xml");

  return true;

}


  1. 最后,不要忘记在 VISION_DEINIT 后将其销毁:

VISION_DEINIT

{

  spSubDlg = NULL;     // 销毁 SubDialog 对象

  DeInitGUI();

  // ...

}


  1. 最后你要做的就是在 XML 中使用你的类名。 打开“Dialogs”文件夹中的 MessageBox.xml。 将对话框的类名(VDialog)替换为你的类名(SubDialog)。

<root>
  <DIALOG class="SubDialog" name="MessageBox" fullscreen="FALSE" size="300,140" startPosition="ScreenCenter">
 
    ...
  
  </DIALOG>
</root>

保存文件。

  1. 编译并运行程序。 主菜单上会出现一个消息框:

恭喜! 你已经成功地在 Vision 中创建了一个自定义对话框!


总结:

你已经成功地完成了在 Vision 中创建 GUI 的第一个教程。 但我们仅仅涉及到了初级的功能,Vision 的 GUI 系统提供了很多的可能性。 我们鼓励你尝试不同的控件和对话框,阅读 Programmer's Documentation 并查看 GUI Engine Sample。在该样例中你会看到很多高级的 GUI 功能。

转自:http://anarchy.cn/portal.php?mod=view&aid=34


0 0