This project is read-only.

XUI Documentation

Setup

Simples ...
  • Add the XUI libraries to your solution, then add a reference to it in your main project.
  • Add the XUIContent project to your solution, then add a Content Reference to it in your main project.

Get it running

For the bare minimum amount of code you need to get something on the screen, see the "Example_Minimal" solution included in the download, or do the following ...
  • Add a new member variable to your Game class ...
private GameInput GameInput;
  • In LoadContent() ...
// create the GameInput - UI depends on this
GameInput = new GameInput( (int)E_UiButton.Count, (int)E_UiAxis.Count );

// setup the UI's input mappings
_UI.SetupControls( GameInput );

// setup the UI with default settings
_UI.Startup( this, GameInput );

// add the initial UI screen
_UI.Screen.AddScreen( new UI.ScreenTest() );
  • In UnloadContent() ...
// shutdown the UI
_UI.Shutdown();
  • In Update( GameTime gameTime ) ...
float frameTime = (float)gameTime.ElapsedGameTime.TotalSeconds;

// update the GameInput
GameInput.Update( frameTime );

// update the UI
_UI.Sprite.BeginUpdate();
_UI.Screen.Update( frameTime );
  • In Draw( GameTime gameTime ) ...
// render the UI - default 2D render pass
_UI.Sprite.Render( 0 );
  • You also need to create a default Screen (see "ScreenTest.cs" in the "Example_Minimal" solution) ...
using Microsoft.Xna.Framework;

namespace UI
{

// class ScreenTest
public class ScreenTest : Screen
{
	// ScreenTest
	public ScreenTest()
		: base( "Test" )
	{
		// create a graphic in the centre of the screen that is the size of the safe area
		WidgetGraphic g = new WidgetGraphic();
		g.Position = new Vector3( _UI.SXM, _UI.SYM, 0.0f );
		g.Size = new Vector3( _UI.SSX, _UI.SSY, 0.0f );
		g.ColorBase = Color.White;
		g.Align = E_Align.MiddleCentre;
		g.AddTexture( "null", 0.0f, 0.0f, 1.0f, 1.0f );

		// add the graphic to the screen
		Add( g );
	}
};

}; // namespace UI

Assets

All content needed for the UI is handled by the library itself. This includes textures, fonts and effects.

Textures

Textures are created in bundles so that you can load and destroy certain textures at runtime if needed. If you just want to load all your textures at boot though, you only need to ever create one bundle.
  • To create a new texture bundle ...
int bundleIndex = _UI.Texture.CreateBundle();
  • To add a texture to a bundle ...
_UI.Texture.Add( bundleIndex, "Textures\\UI_BackgroundTexture", "background" ); // "background" is the internal name used when adding textures to Widgets
  • To destroy a texture bundle ...
_UI.Texture.DestroyBundle( bundleIndex );

Fonts

XUI uses fonts created by the free BMFont tool. Only a few options need to be fixed in this for the exported fonts to work with XUI.
  • "Output invalid char glyph" must be ticked.
  • "Font descriptor" must be set to XML.
  • The exported font must all fit onto one texture. BMFont supports multiple pages for textures, but XUI doesn't support this for performance reasons.
Here's an example of what the settings looked like for the fonts I've used ...

BMFont

Once you've exported your chosen font(s), just rename the texture to match the .fnt file and then add to your solution's Content project. The .fnt file needs have its "Build Action" property set to "None" and the "Copy to Output Directory" property set to either "Copy if newer" or "Copy always".
  • To load a font ...
_UI.Font.Add( "Fonts\\", "SegoeUI" ); // texture and .fnt file must be in the same directory

Screens

A screen holds a list of widgets. Examples of a screen could include a main menu, a HUD or a leaderboard.
  • Inherit from the Screen class.
  • Create and Add all of your widgets in the constructor for the screen.
  • Override whichever functions you need to provide the functionality you need ...
    • OnInit - called after all widgets have had their Init called.
    • OnPostInit - called after all widgets have had their PostInit called.
    • OnStartLoop - called every frame during the start "transition" of a screen. Start/end transition times can be set with SetScreenTimers .
    • OnProcessInput - called every frame outside of the start/end transition times, after all widgets have had their ProcessInput called, but only for valid input devices and if the screen's AllowInput flag is set.
    • OnProcessMessage - called once per screen, per message if any are waiting to be processed. Messages only last one frame.
    • OnUpdate - called every frame outside of the start/end transition times, after all widgets have had their Update called.
    • OnRender - called every frame, after all widgets have had their Render called.
    • OnEndLoop - called every frame during the end transition of a screen.
    • OnEnd - called just before a screen is about to be destroyed.
Screens can be stacked to process as few or as many as you need. The top screen, however, is the only one to receive input.
  • To add a new screen, for example ...
_UI.Screen.AddScreen( new Screen_Popup( E_PopupType.NewGame ) );
  • To switch out the current screen, for example ...
_UI.Screen.SetNextScreen( new Screen_MainMenu() ); // must only be called from within a screen
  • To shutdown the current screen ...
_UI.Screen.SetNextScreen( null ); // must only be called from within a screen
  • To send a message to the UI's screens, for example ...
_UI.Screen.AddMessage( (int)E_UiMessageType.PopupConfirm, (int)Type );

Input

XUI's input system allows you to map game "buttons" to physical buttons on the input devices. See above for how to create and update the input system.
  • To add a mapping, for example ...
input.AddButtonMapping( (int)E_UiButton.Quit, E_Device.Keyboard, (int)Keys.Escape ); // bind to the keyboard

input.AddButtonMapping( (int)E_UiButton.Up, E_Device.Controller, (int)E_Button.LeftStickUp ); // bind to the controller
input.AddButtonMapping( (int)E_UiButton.Up, E_Device.Controller, (int)E_Button.DPadUp ); // this example shows how the UI can be controlled with both the left stick and the d-pad

input.AddButtonMapping( (int)E_GameButton.Jump, E_Device.Mouse, (int)E_MouseButton.Left ); // bind to the mouse - custom game button

input.AddAxisMapping( (int)E_GameAxis.MoveX, E_Device.Controller, (int)E_Button.LeftStickLeft, (int)E_Button.LeftStickRight ); // create a new axis with the left stick
  • To query a mapping, for example ...
Input input = _UI.GameInput.GetInput( 0 ); // get the input associated with pad 0

if ( input.ButtonJustPressed( (int)E_GameButton.Jump ) ) // no need to worry about the device here
	; // TODO - jump
  • Other functions exist to query the input in different ways ...
bool ButtonDown( int gameButton ); // is the button down?
bool ButtonJustPressed( int gameButton ); // has the button just been pressed?
bool ButtonJustReleased( int gameButton ); // has the button just been released?
float ButtonValue( int gameButton ); // the value of the button - range 0 -> 1
float ButtonHeldTime( int gameButton ); // how long the button has been held for
float ButtonHeldTimePrev( int gameButton ); // the held time from the previous frame - useful if you wish to know the held time, but only after a ButtonJustReleased() trigger
bool ButtonAutoRepeat( int gameButton, float initialDelay, float repeatTime ); // returns true like ButtonJustPressed() based on the delay and repeat time
float AxisValue( int gameAxis ); // value of an axis mapping - range -1 -> 1
  • You can also lock out the UI's input system to a specified pad when required. For example ...
_UI.PrimaryPad = -1; // allow all pad input through
_UI.PrimaryPad = 0; // only allow pad 0 to control the UI

Widgets

TODO

MORE COMING SOON ...

Last edited Sep 18, 2011 at 4:25 PM by Petiephant, version 8

Comments

eurythmech May 21, 2013 at 2:42 PM 
Could you please provide details with how to complete the "simples" steps at the very top?

michaelscherer Jul 2, 2012 at 7:29 PM 
A lot needs to be documented -- many names for arguments are not immediately intuitive (especially for those not familiar with XNA or UI dev), for instance:
AddTexture( string name, float pu, float pv, float su, float sv ) => what are pu, pv, su, sv?
_UI.XL vs. _UI.SXL? I shouldn't have to guess that it's "the left handle of X". Frankly I'm not even sure what the S means on the other one.

This kind of documentation may seem tedious but it is very helpful/necessary.

Other than the lack of documentation this library is very stable and neat. Thanks.

Petiephant Jun 19, 2012 at 10:31 PM 
What in particular do you need clarification on? Concrete examples on problems with variable names and hard to follow code would be great - I'm happy to help with that. I promise that I'll be updating the documentation here _eventually_ when I have the time, but the code should hopefully be pretty self-documenting. Personally, I hate bloating the code with loads of huge XML comments.

JBird6184 Jun 19, 2012 at 8:55 PM 
Please add better comments in your code. All you have is one liners that hardly explain anything that is going on. Comment your functions better to explain what they do. You should use "///" and it will give you a nice description and all you need to do is fill it out. It helps when you hover over functions too to allow the user to see the comments without going to actual definition. Also a lot of variables don't have very descriptive names. Needs to be more user friendly. Other than that great job.