Tutorial 1


This first tutorial will cover setting up a GUIManager object, adding new controls, and handling their events.

Setting Up The Project

The simplest way to begin is to use the WindowSystemTestbed project as a starting template. I simply created a new source file containing a class called Tutorial1, and set that as the startup Game object in Main. You can use this if you don't feel like starting a project from scratch.

Setting Up The GUIManager

The first thing to do is to add a couple using statements for the InputEventSystem and WindowSystem namespaces.

using System;
using Microsoft.Xna.Framework;
...
using InputEventSystem;
using WindowSystem;

Now add some fields.

private GraphicsDeviceManager graphics;
private InputEvents input;
private GUIManager gui;

In the constructor we set up these objects, and add input and gui to the list of game components. It is important that the InputEvents object is created before the GUIManager object because it adds itself to the game services in the constructor, which the GUI will need access to. Not creating an InputEvents object at all will cause the program to crash.

public Tutorial1()
{
    this.graphics = new GraphicsDeviceManager(this);
    this.input = new InputEvents(this);
    Components.Add(this.input);
    this.gui = new GUIManager(this);
    Components.Add(this.gui);
    // GUI requires variable timing to function correctly
    IsFixedTimeStep = false;
    Window.Title = "Window System Tutorial 1";
}

The GUIManager object should be initialised in the overriden Initialize() method, before any child controls are added. This is so that order of resource loading can be predicted.

protected override void Initialize()
{
    // Has to be initialised before child controls can be added
    this.gui.Initialize();
    base.Initialize();
}

You will also want to override the Draw() method, to clear the screen each frame, although this probably doesn't affect the GUI as it handles drawing itself.

Adding Controls

I'm going to use a menu bar with various menus and menu items as an example. This will show how to create controls, how to add them to the GUI, and how to handle their events.

First we should add some fields, which are the menu bar and the menu items that the user will actually select. This means that we don't actually need to keep a reference to the 'File' menu for example, because it handles itself. We do need to keep references to child menu items that will actually be clicked, so that we can determine which one was selected. An example would be the 'New' or 'Save' menu items.

private MenuBar menuBar;
private MenuItem newMenuItem;
private MenuItem openMenuItem;
private MenuItem saveMenuItem;
private MenuItem saveAsMenuItem;
private MenuItem exitMenuItem;
private MenuItem undoMenuItem;
private MenuItem redoMenuItem;

Next we have to actually set up the GUI objects, and add them to the GUI. This should take place in Initialize(), after the GUIManager has been initialised.

this.menuBar = new MenuBar(this, gui);
MenuItem fileMenu = new MenuItem(this, gui);
fileMenu.Text = "File";
this.newMenuItem = new MenuItem(this, gui);
this.newMenuItem.Text = "New...";
fileMenu.Add(this.newMenuItem);
this.openMenuItem = new MenuItem(this, gui);
this.openMenuItem.Text = "Open...";
fileMenu.Add(this.openMenuItem);
this.saveMenuItem = new MenuItem(this, gui);
this.saveMenuItem.Text = "Save";
this.saveMenuItem.IsEnabled = false;
fileMenu.Add(this.saveMenuItem);
this.saveAsMenuItem = new MenuItem(this, gui);
this.saveAsMenuItem.Text = "Save As...";
this.saveAsMenuItem.IsEnabled = false;
fileMenu.Add(this.saveAsMenuItem);
this.exitMenuItem = new MenuItem(this, gui);
this.exitMenuItem.Text = "Exit";
fileMenu.Add(this.exitMenuItem);
menuBar.Add(fileMenu);
MenuItem editMenu = new MenuItem(this, gui);
editMenu.Text = "Edit";
this.undoMenuItem = new MenuItem(this, gui);
this.undoMenuItem.Text = "Undo";
this.undoMenuItem.IsEnabled = false;
editMenu.Add(this.undoMenuItem);
this.redoMenuItem = new MenuItem(this, gui);
this.redoMenuItem.Text = "Redo";
this.redoMenuItem.IsEnabled = false;
editMenu.Add(this.redoMenuItem);
this.menuBar.Add(editMenu);
// Add menubar to gui
this.gui.Add(this.menuBar);

You may notice that some of the menu items have a property called IsEnabled set to false. This basically makes the item grey and unclickable, just how Windows does it. This property only applies to MenuItem objects currently, but at some point in the future, I will probably make it apply to all controls.

Now if you run the application, it should show a menu bar with all the new menus and menu items.

Control Events

Next we will add event handlers that will be called whenever a menu item is clicked. The reason for holding references to menu items is for comparison with the clicked control, determining which one was actually clicked.

So add the following code to the Initialize() method, probably after the menu bar is added to the GUI.

// Add event handlers
this.newMenuItem.Click += new ClickHandler(OnMenuItemClicked);
this.openMenuItem.Click += new ClickHandler(OnMenuItemClicked);
this.exitMenuItem.Click += new ClickHandler(OnMenuItemClicked);
this.undoMenuItem.Click += new ClickHandler(OnMenuItemClicked);
this.redoMenuItem.Click += new ClickHandler(OnMenuItemClicked);

Finally we need to add a new method that is called whenever a menu item is clicked. We simply check which item was clicked, and act accordingly.

private void OnMenuItemClicked(UIComponent sender)
{
    if (sender == this.newMenuItem)
    {
        MessageBox messageBox = new MessageBox(
            this,
            gui,
            "New clicked!",
            "Tutorial 1",
            MessageBoxButtons.OK,
            MessageBoxType.Info
        );
        messageBox.Show(true);
    }
    else if (sender == this.openMenuItem)
    {
        MessageBox messageBox = new MessageBox(
            this,
            gui,
            "Open clicked!",
            "Tutorial 1",
            MessageBoxButtons.OK,
            MessageBoxType.Info
        );
        messageBox.Show(true);
    }
    else if (sender == this.undoMenuItem)
    {
        MessageBox messageBox = new MessageBox(
            this,
            gui,
            "Undo clicked!",
            "Tutorial 1",
            MessageBoxButtons.OK,
            MessageBoxType.Info
        );
        messageBox.Show(true);
    }
    else if (sender == this.redoMenuItem)
    {
        MessageBox messageBox = new MessageBox(
            this,
            gui,
            "Redo clicked!",
            "Tutorial 1",
            MessageBoxButtons.OK,
            MessageBoxType.Info
        );
        messageBox.Show(true);
    }
    else if (sender == this.exitMenuItem)
        Exit();
}

Summary

This first tutorial was really simple, but should show you the basics of using the window system. It should be enough if all you want to do is add a couple buttons to your game. In the next tutorial I will show how to create a class that inherits from Window, to demonstrate how to begin to create a real application.

Last edited Sep 8, 2008 at 8:04 PM by cdmac, version 3

Comments

johnh619 Mar 6, 2008 at 5:47 PM 
The fields added seem not to be able to find there info in the using reference dlls. The entries in references are there but are not found. Also the entry GraphicsDeviceManager is not found in Microsoft.Xna.Framework instead in Microsoft.Xna.Framework.Game which is not listing in the using area at the source top.

johnh619 Mar 6, 2008 at 5:32 PM 
I was not able to get the code above to work although changing the comment slashes at void main to run the tutorial 1 & 2 did work; I cant understand why when I removed the other two projects that the references to InputEventSystem and WindowSystem in the main project did not suffice to rebuild tut 1 & 2. They did build but would not start.