Skip to content

Instantly share code, notes, and snippets.

@painquin
Created March 25, 2011 19:59
Show Gist options
  • Save painquin/887531 to your computer and use it in GitHub Desktop.
Save painquin/887531 to your computer and use it in GitHub Desktop.
Immediate Mode GUI for XNA
abstract class GUI
{
#region Enums
public enum ElementState
{
None,
Hovered,
Clicked,
}
#endregion
#region Framework
protected static GUI Current { get; set; }
protected Color DefaultTextColor = Color.LightGray;
protected Color HoverTextColor = Color.White;
protected Color SelectedTextColor = Color.DarkGray;
protected MouseState mouseState;
protected bool mousedown
{
get
{
return mouseState.LeftButton == ButtonState.Pressed;
}
}
protected int hotitem;
protected int activeitem;
protected SpriteBatch spriteBatch;
protected ContentManager Content;
protected static Texture2D DimTexture;
/// <summary>
/// In an inherited class, draws the GUI
/// </summary>
/// <param name="gameTime">The current GameTime, for animated effects.</param>
protected abstract void Draw(GameTime gameTime);
public static void DrawGUI(GameTime gameTime)
{
Current.Prepare();
Current.Draw(gameTime);
Current.Finish();
}
protected GUI(ContentManager content, SpriteBatch sb)
{
if (DimTexture == null)
{
DimTexture = new Texture2D(sb.GraphicsDevice, 1, 1);
DimTexture.SetData(new Color[] { new Color(255, 255, 255, 128) });
}
spriteBatch = sb;
Content = content;
}
public void Prepare()
{
hotitem = 0;
mouseState = Mouse.GetState();
spriteBatch.Begin();
}
public void Finish()
{
if (mousedown == false)
{
activeitem = 0;
}
else if (activeitem == 0)
{
activeitem = -1;
}
spriteBatch.End();
}
#endregion
#region TextButton
/// <summary>
/// Create a clickable text button
/// </summary>
/// <param name="font">The font to draw the text in</param>
/// <param name="text">The string to draw</param>
/// <param name="xpos">The x-coordinate on screen</param>
/// <param name="ypos">The y-coordinate on screen</param>
/// <param name="id">Magic</param>
/// <returns>ElementState indicating if the text was hovered or clicked.</returns>
protected ElementState TextButton(SpriteFont font, string text, int xpos, int ypos, int id)
{
return TextButton(font, text, xpos, ypos, DefaultTextColor, HoverTextColor, SelectedTextColor, id);
}
/// <summary>
/// Create a clickable text button
/// </summary>
/// <param name="font">The font to draw the text in</param>
/// <param name="text">The string to draw</param>
/// <param name="xpos">The x-coordinate on screen</param>
/// <param name="ypos">The y-coordinate on screen</param>
/// <param name="color">The color to use</param>
/// <param name="hoverColor">The color when the text is hovered over</param>
/// <param name="selColor">The color when the text is clicked</param>
/// <param name="id">Magic</param>
/// <returns>ElementState indicating if the text was hovered or clicked.</returns>
protected ElementState TextButton(SpriteFont font, string text, int xpos, int ypos, Color color, Color hoverColor, Color selColor, int id)
{
// measure the string so we know the bounding box
Vector2 size = font.MeasureString(text);
// check the bounding box (min-x, min-y, max-x, max-y) against the mouse position
// to determine hit state (ie, is the mouse over this element)
bool hot =
(mouseState.X >= xpos && mouseState.X < xpos + size.X && // check x-bounds
mouseState.Y >= ypos && mouseState.Y < ypos + size.Y); // check y-bounds
if (hot)
{
hotitem = id;
if (activeitem == 0 && mousedown)
{
activeitem = id;
}
}
if (hotitem == id)
{
if (activeitem == id)
{
color = selColor;
}
else
{
color = hoverColor;
}
}
Text(font, text, xpos, ypos, color);
if (mousedown == false && hotitem == id)
{
if (activeitem == id)
{
return ElementState.Clicked;
}
else
{
return ElementState.Hovered;
}
}
return ElementState.None;
}
#endregion
#region Text
/// <summary>
/// Draw a non-clickable text label
/// </summary>
/// <param name="font">The font to draw the text in</param>
/// <param name="text">The string to draw</param>
/// <param name="xpos">The x-coordinate on screen</param>
/// <param name="ypos">The y-coordinate on screen</param>
protected void Text(SpriteFont font, string text, int xpos, int ypos)
{
Text(font, text, xpos, ypos, DefaultTextColor);
}
/// <summary>
/// Draw a non-clickable text label
/// </summary>
/// <param name="font">The font to draw the text in</param>
/// <param name="text">The string to draw</param>
/// <param name="xpos">The x-coordinate on screen</param>
/// <param name="ypos">The y-coordinate on screen</param>
/// <param name="color">The color to use</param>
protected void Text(SpriteFont font, string text, int xpos, int ypos, Color color)
{
spriteBatch.DrawString(font, text, new Vector2(xpos, ypos), color);
}
#endregion
#region ImageButton
/// <summary>
/// Create a clickable image button
/// </summary>
/// <param name="sheet">The spritesheet to pull from</param>
/// <param name="idx">The default sprite index to draw</param>
/// <param name="hoverIdx">The sprite index to draw when the image is hovered over</param>
/// <param name="selIdx">The sprite index to draw when the image is clicked</param>
/// <param name="xpos">The x-coordinate on screen</param>
/// <param name="ypos">The y-coordinate on screen</param>
/// <param name="id">Magic</param>
/// <returns>ElementState indicating if the image was hovered or clicked</returns>
protected ElementState ImageButton(SpriteSheet sheet, int idx, int hoverIdx, int selIdx, int xpos, int ypos, int id)
{
// check the bounding box (min-x, min-y, max-x, max-y) against the mouse position
// to determine hit state (ie, is the mouse over this element)
bool hot =
(mouseState.X >= xpos && mouseState.X < xpos + sheet.SpriteWidth && // check x-bounds
mouseState.Y >= ypos && mouseState.Y < ypos + sheet.SpriteHeight); // check y-bounds
if (hot)
{
hotitem = id;
if (activeitem == 0 && mousedown)
{
activeitem = id;
}
}
if (hotitem == id)
{
if (activeitem == id)
{
idx = selIdx;
}
else
{
idx = hoverIdx;
}
}
Image(sheet, idx, xpos, ypos);
if (mousedown == false && hotitem == id)
{
if (activeitem == id)
{
return ElementState.Clicked;
}
else
{
return ElementState.Hovered;
}
}
return ElementState.None;
}
#endregion
#region Image
protected void Image(SpriteSheet sheet, int idx, int xpos, int ypos)
{
spriteBatch.Draw(sheet.Texture, new Vector2(xpos, ypos), sheet[idx], Color.White);
}
#endregion
#region Background
protected void Background(Texture2D backgroundTexture)
{
spriteBatch.Draw(backgroundTexture, new Rectangle(0, 0, spriteBatch.GraphicsDevice.Viewport.Width, spriteBatch.GraphicsDevice.Viewport.Height), Color.White);
}
#endregion
#region Dim
protected void Dim(Color color)
{
spriteBatch.Draw(DimTexture, new Rectangle(0, 0, spriteBatch.GraphicsDevice.Viewport.Width, spriteBatch.GraphicsDevice.Viewport.Height), color);
}
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment