//---------------------------------------------------------------------------------------------------------------------------------------------------
//
// Copyright (C)2007 DW Studios. All rights reserved.
//
//---------------------------------------------------------------------------------------------------------------------------------------------------
// {License Information: Creative Commons}
//---------------------------------------------------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using System.ComponentModel;
using System.Xml;
using DW.Globals;
using DW.Stream;
using DW.UI.ScreenObjects;
///
/// Scope of all UserInterfacing in the game, includes HUD and ScreenObjects
///
namespace DW.UI
{
///
/// Creates, updates, and draws a heads up display on the user's viewport.
///
public class HUD
{
Dialogue dialogue;
public Rectangle currentScreenSpaceView;
//public Rectangle localSpaceView;
//Vector2 currentDimensions = new Vector2(800, 600);
Vector2 HudScaleMultiplier;
// The nameID of the image that the second needs to get the location from
private string imageReference;
private Vector2 imageOffset = new Vector2();
// An addition modifier to the image location, must be 0 if null
private int modifier;
// Text Display specific
private string operation;
private string textToScreen;
private Vector2 offset;
private const int MARGIN_GUTTER = 15;
private const int SCROLL = 20;
private int dialogueBoxIndex;
private int speakerTextIndex;
private int dialogueTextIndex;
public List textDisplays { get { return _textDisplays; } set { _textDisplays = value; } }
private List _textDisplays = new List();
public List imageDisplays { get { return _imageDisplays; } set { _imageDisplays = value; } }
private List _imageDisplays = new List();
//public List imageSpinners { get { return _imageSpinners; } set { _imageSpinners = value; } }
//private List _imageSpinners = new List();
///
/// Heads Up Display constructor.
///
public HUD(Viewport view)
{
currentScreenSpaceView.X = view.X;
currentScreenSpaceView.Y = view.Y;
currentScreenSpaceView.Width = view.Width;
currentScreenSpaceView.Height = view.Height;
try
{
XmlDocument reader = new XmlDocument();
reader.Load("_xml/test.xml");
foreach (XmlNode node in reader.ChildNodes)
{
if (node.Name == "Dialogue")
{
dialogue = new Dialogue(node);
}
}
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine("Error reading xml");
throw e;
}
}
public HUD()
{ }
///
/// Accessor for the args on the HUD
///
/// Search string (XML name) of the HUD item you are looking for
///
public int getHUDIndex(string name)
{
for (int x = 0; x < imageDisplays.Count; x++)
{
if (imageDisplays[x].name == name)
{
return x;
}
else
{
for (int z = 0; z < textDisplays.Count; z++)
{
if (textDisplays[z].name == name)
{
return z;
}
}
}
}
return 0;
}
#region HUDCreation
///
/// Generate the HUD from XML file
///
public void LoadScreenObjects(XmlNode screenObjects)
{
try
{
foreach (XmlNode screenObjNode in screenObjects.ChildNodes)
{
LoadDisplays(screenObjNode);
}
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine("Error reading xml");
throw e;
}
dialogue.InitializeDialogControl();
}
///
/// Loads the imageDisplay into the imageDisplays list
/// Loads the textDisplay into the textDisplays list
///
/// XML Node ImageDisplay
private void LoadDisplays(XmlNode node)
{
if (node.Name == "ImageDisplay")
{
ImageDisplay so = new ImageDisplay(node);
if (node.Attributes["quadrant"].Value != "null")
{
LocationsTranslation(so, node.Attributes["quadrant"].Value);
//so.position += new Vector2(int.Parse(node.Attributes["imageOffsetX"].Value),int.Parse(node.Attributes["imageOffsetY"].Value));
}
if (node.Attributes["imageReference"].Value != "null")
{
// AdjustLocationBasedOnReferenceImage(so);
}
AddImageDisplay(so);
}
else if (node.Name == "TextDisplay")
{
TextDisplay so = new TextDisplay(node);
if (node.Attributes["quadrant"].Value != "null")
{
LocationsTranslation(so, node.Attributes["quadrant"].Value);
//so.position += new Vector2(int.Parse(node.Attributes["offsetX"].Value), int.Parse(node.Attributes["offsetY"].Value));
}
string imgRef = node.Attributes["imageReference"].Value;
if (imgRef != "null")
{
for (int x = 0; x < imageDisplays.Count; x++)
{
if (imageDisplays[x].name == imgRef)
{
so.position.X = imageDisplays[x].position.X + int.Parse(node.Attributes["offsetX"].Value) ;
so.position.Y = imageDisplays[x].position.Y + int.Parse(node.Attributes["offsetY"].Value) ;
AddTextDisplay(so);
}
}
}
else { AddTextDisplay(so); }
}
}
///
/// Add an Image display to our ImageDisplay list.
///
/// Image to display
/// Name of the image
/// Position to display image
/// Width of the image's texture
/// Height of the image's texture
/// Color of the image
/// Toggle to turn draw on/off
public void AddImageDisplay(Texture2D image, string name, Vector2 position, int width, int height, Color color, bool draw)
{
ImageDisplay temp = new ImageDisplay();
temp.image = image;
temp.name = name;
temp.width = width;
temp.height = height;
temp.position = position;
temp.color = color;
temp.visible = draw;
AddImageDisplay(temp);
}
private void AddImageDisplay(ImageDisplay display)
{
_imageDisplays.Add(display);
}
///
/// Add a Text display to the TextDisplay list.
///
/// ID of the text to be displayed
/// Text to add
/// Position on the HUD
/// Color to display the text in
/// Toggle to turn draw on/off
///
public int AddTextDisplay(string nameID, string text, Vector2 position, Color color, bool draw)
{
TextDisplay temp = new TextDisplay();
temp.name = nameID;
temp.text = text;
Vector2 size = Renderer.SystemFonts.Arial.MeasureString(text);
temp.width = (int)(size.X);
temp.height = (int)(size.Y);
temp.position = position;
temp.color = color;
temp.visible = draw;
AddTextDisplay(temp);
return textDisplays.Count - 1;
}
private void AddTextDisplay(TextDisplay display)
{
textDisplays.Add(display);
}
#endregion
#region Loading HUD helper methods
///
/// Translate from XML quadrant to viewport location
///
/// Size of Image or Text String
private void LocationsTranslation(ImageDisplay so, string quadrant)
{
// Upper, Left
so.position = new Vector2(0, 0);
// Center, Right, Middle, Bottom
if (quadrant.Contains("C")) {
so.position.X = (this.currentScreenSpaceView.Width/2 - so.image.Width/2); }
if (quadrant.Contains("R")) {
so.position.X = this.currentScreenSpaceView.Width - so.image.Width - 0; }
if (quadrant.Contains("M")) { so.position.Y = (this.currentScreenSpaceView.Height/2 - so.image.Height/2); }
if (quadrant.Contains("B")) { so.position.Y = this.currentScreenSpaceView.Height - so.image.Height - 0; }
}
///
/// Translate from XML quadrant to viewport location
///
/// Size of Image or Text String
private void LocationsTranslation(TextDisplay so, string quadrant)
{
// Upper, Left
so.position = new Vector2(MARGIN_GUTTER, MARGIN_GUTTER);
if (so is TextDisplay)
{
so.position.X = Renderer.SystemFonts.Arial.MeasureString(so.text).X;
}
// Center, Right, Middle, Bottom
if (quadrant.Contains("C")) { so.position.X = (this.currentScreenSpaceView.Width - so.position.X) / 2; }
if (quadrant.Contains("R")) { so.position.X = this.currentScreenSpaceView.Width - so.position.X - MARGIN_GUTTER; }
if (quadrant.Contains("M")) { so.position.Y = (this.currentScreenSpaceView.Height - so.position.Y) / 2; }
if (quadrant.Contains("B")) { so.position.Y = this.currentScreenSpaceView.Height - so.position.Y - MARGIN_GUTTER; }
}
#endregion
public void Update(Stopwatch gameTimer, GameTime gametime)
{
try
{
// Update the Game Time
int seconds = ((int)gameTimer.Elapsed.TotalSeconds) % 60;
int minutes = ((int)gameTimer.Elapsed.TotalSeconds) / 60;
string formatedSeconds = seconds.ToString();
if (seconds < 10)
{
formatedSeconds = "0" + seconds.ToString();
}
string timing = minutes.ToString() + ":" + formatedSeconds;
textDisplays[getHUDIndex("timerText")].text = timing;
}
catch (Exception ex) { Console.WriteLine("Camera::Update - TimerText - " + ex.Message); }
// Call update if and ONLY if you are using the event system for DIALOGUE
// UpdateDialogue();
}
//#region Dialogue Controls
/////
///// Removes dialogue once time limit expires
/////
//public void UpdateDialogue()
//{
// //Remove dialogue once the limit has passed
// if (imageDisplays[getHUDIndex("dialogueBox")].stopWatch.ElapsedMilliseconds >= displayLength)
// {
// RemoveDialog();
// imageDisplays[getHUDIndex("dialogueBox")].stopWatch.Reset();
// displayLength = 0;
// }
//}
/////
///// Inits the dialogue control system
/////
//public void InitializeDialogControl()
//{
// try
// {
// imageDisplays[getHUDIndex("dialogueBox")].stopWatch.Reset();
// }
// catch (Exception ex) { Console.WriteLine("HUD::InitializeDialogControl - No Timer Dialog Loaded"); }
//}
/////
///// Shows the dialogue
/////
///// Which image to post in the background
///// Who is talking
///// What the message is
//public void ShowDialog(Texture2D backgroundImage, string speaker, string message)
//{
// imageDisplays[getHUDIndex("dialogueBox")].visible = true;
// textDisplays[getHUDIndex("speakerText")].text = speaker;
// textDisplays[getHUDIndex("speakerText")].visible = true;
// textDisplays[getHUDIndex("dialogueText")].text = message;
// textDisplays[getHUDIndex("dialogueText")].visible = true;
//}
/////
///// Removes the dialogue from the HUD
/////
//public void RemoveDialog()
//{
// imageDisplays[dialogueBoxIndex].visible = false;
// textDisplays[getHUDIndex("dialogueBox")].text = "ERROR";
// textDisplays[getHUDIndex("speakerText")].visible = false;
// textDisplays[getHUDIndex("speakerText")].color = Color.White;
// textDisplays[getHUDIndex("dialogueText")].text = "YOU SHOULDN'T EVER SEE THIS";
// textDisplays[getHUDIndex("dialogueText")].visible = false;
// textDisplays[getHUDIndex("dialogueText")].color = Color.White;
//}
/////
///// Displays the dialogue on the HUD
/////
///// Which image to post in the background
///// Who is talking
///// What the message is
///// Time limit to display message
//public void DisplayDialog(Texture2D backgroundImage, string speaker, string message, int limitMilli)
//{
// displayLength = limitMilli;
// if (!imageDisplays[getHUDIndex("dialogueBox")].stopWatch.IsRunning)
// {
// displayLength = limitMilli;
// imageDisplays[getHUDIndex("dialogueBox")].stopWatch.Start();
// }
// else
// {
// displayLength = limitMilli;
// imageDisplays[getHUDIndex("dialogueBox")].stopWatch.Reset();
// }
// ShowDialog(backgroundImage, speaker, message);
//}
//#endregion
#region Draw functions
///
/// Default Draw function.
///
/// SpriteBatch used to draw used to draw.
public void Draw(SpriteBatch spriteBatch)
{
Draw(spriteBatch, this.currentScreenSpaceView.X, this.currentScreenSpaceView.Y);
}
///
/// Draw function for drawing our displays at a certain offset position.
/// NOTE: SpriteBatch Begin and End are handled outside this scope.
///
/// SpriteBatch used to draw used to draw.
/// X-Offset to draw location.
/// Y-Offset to draw location.
public void Draw(SpriteBatch spriteBatch, int xoffset, int yoffset)
{
foreach (ImageDisplay element in _imageDisplays)
{
if (element.visible)
{
spriteBatch.Draw(element.image,
new Rectangle((int)element.position.X + xoffset,
(int)element.position.Y + yoffset,
(int)(element.Size.Width * HudScaleMultiplier.X),
(int)(element.Size.Height * HudScaleMultiplier.Y)),
element.Source,
element.color);
}
}
foreach (TextDisplay element in textDisplays)
{
if (element.visible)
{
spriteBatch.DrawString(Renderer.SystemFonts.Arial, element.text,
new Vector2(element.position.X + xoffset, element.position.Y + yoffset),
element.color);
}
}
}
///
/// Resizes the HUD based on viewport change
///
/// Current viewport size
public void Resize(Rectangle viewPortRect)
{
if (currentScreenSpaceView != viewPortRect)
{
// Determine multiplier and store new size
HudScaleMultiplier =
new Vector2(viewPortRect.Width, viewPortRect.Height) /
new Vector2(currentScreenSpaceView.Width, currentScreenSpaceView.Height);
// Store new screen space
currentScreenSpaceView = viewPortRect;
// Scale ScreenObjects by ratio
for (int i = 0; i < textDisplays.Count; i++)
{
textDisplays[i].position = textDisplays[i].position * HudScaleMultiplier;
}
for (int i = 0; i < _imageDisplays.Count; i++)
{
_imageDisplays[i].position = _imageDisplays[i].position * HudScaleMultiplier;
}
//for (int playerIndex = 0; playerIndex < imageSpinners.Count; playerIndex++)
//{
// imageSpinners[playerIndex].position = imageSpinners[playerIndex].position * HudScaleMultiplier;
//}
}
else
{
HudScaleMultiplier.X = 1;
HudScaleMultiplier.Y = 1;
}
}
#endregion
}
}
# region Spinner
/////
///// Add an Image spinner to our ImageDisplay list
/////
///// Image spinner to add
///// Count of image spinners
//public int AddImageSpinner(ImageSpinner_old val)
//{
// this.imageSpinners.Add(val);
// return imageSpinners.Count - 1;
//}
/////
///// Set the image spinner at index location to the next in-line
/////
///// location
//public void SpinnerNext(int index)
//{
// if (index < 0 || index >= this.imageSpinners.Count)
// {
// // Invalid index
// return;
// }
// else
// {
// ImageSpinner_old temp = this.imageSpinners[index];
// temp.next();
// this.imageSpinners[index] = temp;
// }
//}
/////
///// Set the image spinner at index location to the previous inline
/////
///// location
//public void SpinnerBack(int index)
//{
// if (index < 0 || index >= this.imageSpinners.Count)
// {
// // Invalid index
// return;
// }
// else
// {
// ImageSpinner_old temp = this.imageSpinners[index];
// temp.prev();
// this.imageSpinners[index] = temp;
// }
//}
/////
///// Set the active index to val in our image spinner at index
/////
///// location
///// Active value
//public void SpinnerSet(int index, int val)
//{
// if (index < 0 || index >= this.imageSpinners.Count)
// {
// // Invalid index
// return;
// }
// ImageSpinner_old temp = this.imageSpinners[index];
// if (val < 0 || temp.images.Length <= val)
// {
// return;
// }
// else
// {
// temp.activeIndex = val;
// this.imageSpinners[index] = temp;
// }
//}
#endregion
/////
///// Loads the imageDisplay into the imageDisplays list
///// Loads the textDisplay into the textDisplays list
/////
///// XML Node ImageDisplay
//private void LoadDisplays(XmlNode node)
//{
// if (node.Name == "ImageDisplay")
// {
// this.nameID = node.Attributes["nameID"].Value;
// this.texturePath = node.Attributes["texturePath"].Value;
// this.textureImage = Renderer.Dimensions.content.Load(texturePath);
// this.displayLocation = new Vector2(int.Parse(node.Attributes["posX"].Value), int.Parse(node.Attributes["posY"].Value));
// this.newColor = new Color(
// byte.Parse(node.Attributes["colorR"].Value),
// byte.Parse(node.Attributes["colorG"].Value),
// byte.Parse(node.Attributes["colorB"].Value),
// byte.Parse(node.Attributes["colorA"].Value)
// );
// this.toDraw = bool.Parse(node.Attributes["toDraw"].Value);
// this.quadrant = node.Attributes["quadrant"].Value;
// if (quadrant != "null")
// {
// LocationsTranslation(new Vector2(this.textureImage.Width, this.textureImage.Height));
// }
// this.imageReference = node.Attributes["imageReference"].Value;
// this.imageAttribute = node.Attributes["imageAttribute"].Value;
// this.modifier = int.Parse(node.Attributes["modifier"].Value);
// if (imageReference != "null")
// {
// AdjustLocationBasedOnReferenceImage();
// }
// AddImageDisplay(this.textureImage, this.nameID, this.displayLocation,
// this.textureImage.Width, this.textureImage.Height, newColor, this.toDraw);
// }
// if (node.Name == "TextDisplay")
// {
// this.nameID = node.Attributes["nameID"].Value;
// this.textToScreen = node.Attributes["text"].Value;
// this.displayLocation = new Vector2(int.Parse(node.Attributes["posX"].Value), int.Parse(node.Attributes["posY"].Value));
// this.newColor = new Color(
// byte.Parse(node.Attributes["colorR"].Value),
// byte.Parse(node.Attributes["colorG"].Value),
// byte.Parse(node.Attributes["colorB"].Value),
// byte.Parse(node.Attributes["colorA"].Value)
// );
// this.toDraw = bool.Parse(node.Attributes["toDraw"].Value);
// this.imageReference = node.Attributes["imageReference"].Value;
// this.operation = node.Attributes["operation"].Value;
// this.offset = new Vector2(int.Parse(node.Attributes["offsetX"].Value), int.Parse(node.Attributes["offsetY"].Value));
// this.quadrant = node.Attributes["quadrant"].Value;
// if (this.quadrant != "null")
// {
// LocationsTranslation(new Vector2(gameFonts.Arial.MeasureString(this.textToScreen).X, textureImage.Height));
// }
// if (imageReference != "null")
// {
// for (int x = 0; x < imageDisplays.Count; x++)
// {
// if (imageDisplays[x].name == imageReference)
// {
// LocationBasedOnReference(x);
// AddTextDisplay(this.nameID, this.textToScreen, this.displayLocation, this.newColor, this.toDraw);
// }
// }
// }
// else
// {
// AddTextDisplay(this.nameID, this.textToScreen, this.displayLocation, this.newColor, this.toDraw);
// }
// }
//}