//---------------------------------------------------------------------------------------------------------------------------------------------------
//
// Copyright (C)2007 DarkWynter Studios. All rights reserved.
//
//---------------------------------------------------------------------------------------------------------------------------------------------------
// {Contact : darkwynter.com for licensing information
//---------------------------------------------------------------------------------------------------------------------------------------------------
namespace DarkWynter.Engine.UserInterface
{
#region Using Statements
using System;
using System.Collections.Generic;
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 DarkWynter.Stream;
using DarkWynter.Engine.Globals;
using System.ComponentModel;
using DarkWynter.Stream.UIInterfacing;
#endregion
///
/// Creates, updates, and draws a heads up display on the user's viewport.
///
public class HeadsUpDisplay
{
// Attributes:
// Screen dead zone percenta ge
private const float SIDES_DEAD_ZONE_PERCENT = 0.05f;
private const float TOP_BOTTOM_DEAD_ZONE_PERCENT = 0.03f;
private Vector2 DIALOGUE_LOCATION = new Vector2(20, 500);
private Vector2 SPEAKER_OFFSET = new Vector2(25, 10);
private Vector2 TEXT_OFFSET = new Vector2(20, 50);
private int playerIndex = 0;
private int dialogueBoxIndex;
private int speakerTextIndex;
private int dialogueTextIndex;
private int displayLength = 0;
private Texture2D dialogueBoxTexture;
private Texture2D successTexture;
private Stopwatch ReadTimer = new Stopwatch();
private Stopwatch ImageTimer = new Stopwatch();
public List textDisplays { get { return _textDisplays; } set { _textDisplays = value; } }
private List _textDisplays = new List();
public List imageDisplays { get { return _imageDisplays; } set { _imageDisplays = value; } }
public List _imageDisplays = new List();
public List valueDisplays { get { return _valueDisplays; } set { _valueDisplays = value; } }
private List _valueDisplays = new List();
public List imageSpinners { get { return _imageSpinners; } set { _imageSpinners = value; } }
private List _imageSpinners = new List();
///
/// Heads Up Display constructor.
///
public HeadsUpDisplay()
{
playerIndex = 0;
InitializeDialogControl();
}
///
/// Heads Up Display constructor with player index and predefined viewport.
///
/// Player this HUD belongs to.
public HeadsUpDisplay(int index)
{
playerIndex = index;
InitializeDialogControl();
}
///
/// Inits the dialogue control system
///
public void InitializeDialogControl()
{
ReadTimer.Reset();
dialogueBoxTexture = Statics_Engine.SystemSettings.content.Load("Content/_textures/dialogueBox");
DIALOGUE_LOCATION.X = 20;
DIALOGUE_LOCATION.Y = Statics_Stream.RenderSettings.cameraList[0].viewport.Height - (dialogueBoxTexture.Height + 10);
dialogueBoxIndex = AddImageDisplay(dialogueBoxTexture, DIALOGUE_LOCATION, dialogueBoxTexture.Width,
dialogueBoxTexture.Height, Color.White, false);
speakerTextIndex = AddTextDisplay("", DIALOGUE_LOCATION + SPEAKER_OFFSET, Color.White);
UpdateTextVisible(speakerTextIndex, false);
dialogueTextIndex = AddTextDisplay("", DIALOGUE_LOCATION + TEXT_OFFSET, Color.White);
UpdateTextVisible(dialogueTextIndex, false);
}
///
/// Shows the dialogue
///
/// Which image to post in the background
/// Who is talking
/// What the message is
/// Color of the text
public void ShowDialog(Texture2D backgroundImage, string speaker, string message, Color color)
{
UpdateImageDisplay(dialogueBoxIndex, backgroundImage, DIALOGUE_LOCATION, backgroundImage.Width, backgroundImage.Height, Color.White, true);
UpdateImageVis(dialogueBoxIndex, true, color);
UpdateTextVis(speakerTextIndex, speaker, true, Color.White);
UpdateTextVis(dialogueTextIndex, message, true, Color.White);
}
///
/// Removes the dialogue from the HUD
///
public void RemoveDialog()
{
UpdateImageVis(dialogueBoxIndex, false, Color.White);
UpdateTextVis(speakerTextIndex, "ERROR", false, Color.White);
UpdateTextVis(dialogueTextIndex, "YOU SHOULDN'T EVER SEE THIS", false, Color.White);
}
///
/// Displays the dialogue on the HUD
///
/// Which image to post in the background
/// Who is talking
/// What the message is
/// Color
/// Time limit to display message
public void DisplayDialog(Texture2D backgroundImage, string speaker, string message, Color color, int limitMilli)
{
displayLength = limitMilli;
if (!ReadTimer.IsRunning)
{
displayLength = limitMilli;
ReadTimer.Start();
}
else
{
displayLength = limitMilli;
ReadTimer.Reset();
}
ShowDialog(backgroundImage, speaker, message, color);
}
///
/// Removes dialogue once time limit expires
///
public void UpdateDialogue()
{
//Remove dialogue once the limit has passed
if (ReadTimer.ElapsedMilliseconds >= displayLength)
{
RemoveDialog();
ReadTimer.Reset();
displayLength = 0;
}
}
///
/// Resizes the HUD based on viewport change
///
/// The ratio between old viewport and resized viewport
public void Resize(Vector2 HudScaleMultiplier)
{
// Handle the dialogue stuff first...have to handle seperatly so HACK...
DIALOGUE_LOCATION.X = DIALOGUE_LOCATION.X * HudScaleMultiplier.X;
DIALOGUE_LOCATION.Y = DIALOGUE_LOCATION.Y * HudScaleMultiplier.Y;
SPEAKER_OFFSET.X = DIALOGUE_LOCATION.X * HudScaleMultiplier.X;
SPEAKER_OFFSET.Y = DIALOGUE_LOCATION.Y * HudScaleMultiplier.Y;
TEXT_OFFSET.X = TEXT_OFFSET.X * HudScaleMultiplier.X;
TEXT_OFFSET.Y = TEXT_OFFSET.Y *HudScaleMultiplier.Y;
for (int i = 0; i < textDisplays.Count; i++)
{
textDisplays[i].position.X = textDisplays[i].position.X * HudScaleMultiplier.X;
textDisplays[i].position.Y = textDisplays[i].position.Y * HudScaleMultiplier.Y;
}
for (int i = 0; i < _valueDisplays.Count; i++)
{
_valueDisplays[i].position.X = _valueDisplays[i].position.X * HudScaleMultiplier.X;
_valueDisplays[i].position.Y = _valueDisplays[i].position.Y * HudScaleMultiplier.Y;
}
for (int i = 0; i < _imageDisplays.Count; i++)
{
_imageDisplays[i].position.X = _imageDisplays[i].position.X * HudScaleMultiplier.X;
_imageDisplays[i].position.Y = _imageDisplays[i].position.Y * HudScaleMultiplier.Y;
}
for (int i = 0; i < imageSpinners.Count; i++)
{
imageSpinners[i].position.X = imageSpinners[i].position.X * HudScaleMultiplier.X;
imageSpinners[i].position.Y = imageSpinners[i].position.Y * HudScaleMultiplier.Y;
}
}
public void TimedMessage(string text, Vector2 position, Color color, float timeLimit)
{
int sharkIndex = DarkWynterEngine._HUD.AddTextDisplay(text, position, color);
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
}
///
/// Add a Text display to the TextDisplay list.
///
/// Text to add.
/// Position to locate text.
/// Color to display text with.
/// Count of text displays
public int AddTextDisplay(string text, Vector2 position, Color color)
{
TextDisplay_old temp = new TextDisplay_old();
temp.text = text;
Vector2 size = Statics_Stream.Fonts.Arial.MeasureString(text);
temp.width = (int)(size.X);
temp.height = (int)(size.Y);
temp.position = position;
//AdjustForDeadZone(temp);
temp.color = color;
textDisplays.Add(temp);
return textDisplays.Count - 1;
}
///
/// Add a Value display to the ValueDisplay list.
///
/// Text to display.
/// Value to display.
/// Position to display value.
/// Width of value display.
/// Height of value display.
/// Color of value and text.
/// Count of value displays
public int AddValueDisplay(string text, float value, Vector2 position, int width, int height, Color color)
{
ValueDisplay_old temp = new ValueDisplay_old();
temp.text = text;
temp.value = value;
temp.width = width;
temp.height = height;
temp.position = position;
//AdjustForDeadZone(temp);
temp.color = color;
_valueDisplays.Add(temp);
return _valueDisplays.Count - 1;
}
///
/// Add an Image display to our ImageDisplay list.
///
/// Image to display.
/// Position to display value.
/// Width of value display.
/// Height of value display.
/// Color of value and text.
/// Toggle to turn drawing on/off.
/// Count of image displays
public int AddImageDisplay(Texture2D image, Vector2 position, int width, int height, Color color, bool draw)
{
ImageDisplay_old temp = new ImageDisplay_old();
temp.image = image;
temp.width = width;
temp.height = height;
temp.position = position;
//AdjustForDeadZone(temp);
temp.color = color;
temp.visible = draw;
_imageDisplays.Add(temp);
return imageDisplays.Count - 1;
}
# 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
///
/// Update Hud events.
///
public void Update()
{
UpdateDialogue();
}
///
/// Method which allows us to change the text in a TextDisplay
///
/// location
/// New text
public void UpdateText(int index, string newText)
{
if (index < 0 || index >= textDisplays.Count)
{
// Invalid index
return;
}
else
{
// Change the text
textDisplays[index].text = newText;
}
}
///
/// Updates the visibility of a text display
///
/// location
/// New text
/// Visibility
/// Display color
public void UpdateTextVis(int index, string newText, bool vis, Color color)
{
if (index < 0 || index >= textDisplays.Count)
{
// Invalid index
return;
}
else
{
// Change the text
textDisplays[index].color = color;
textDisplays[index].text = newText;
textDisplays[index].visible = vis;
}
}
///
/// Update/Replace an ImageDisplay
///
/// Index of the image display
/// New image to use
/// New position
/// New width
/// New height
/// New Color
/// To draw or not to draw
public void UpdateImageDisplay(int index, Texture2D image, Vector2 position, int width, int height, Color color, bool draw)
{
_imageDisplays[index] = new ImageDisplay_old();
_imageDisplays[index].image = image;
_imageDisplays[index].width = width;
_imageDisplays[index].height = height;
_imageDisplays[index].position = position;
_imageDisplays[index].color = color;
imageDisplays[index].visible = draw;
}
///
/// Method which allows us to change the Value in a ValueDisplay.
///
/// Location of ValueDisplay in list.
/// New value of value display.
public void UpdateValue(int index, float newValue)
{
if (index < 0 || index >= valueDisplays.Count)
{
// Invalid index
return;
}
else
{
// Change the value
valueDisplays[index].value = newValue;
}
}
///
/// Updates the x and y scale of an image display
///
/// Location of ValueDisplay in list.
/// X-scale value.
/// Y-scale value.
public void UpdateImageScale(int index, float xScale, float yScale)
{
if (index < 0 || index >= this._imageDisplays.Count)
{
// Invalid index
return;
}
else
{
this._imageDisplays[index].xScale = xScale;
this._imageDisplays[index].yScale = yScale;
}
}
///
/// Change height of an image.
///
/// Location of ValueDisplay in list.
/// New height of Image..
public void UpdateImageHeight(int index, int amount)
{
if (index < 0 || index >= this._imageDisplays.Count)
{
// Invalid index
return;
}
else
{
this._imageDisplays[index].height = amount;
}
}
///
/// Update the Image's Source
///
/// Location of ImageDisplay in list.
/// New Source on the Image File
public void UpdateImageSource(int index, Rectangle source)
{
if (index < 0 || index >= this._imageDisplays.Count)
{
// Invalid index
return;
}
else
{
this._imageDisplays[index].Source = source;
}
}
///
/// Get the Image's Position
///
/// Location of ImageDisplay in list.
/// The Image at that index's position
public Vector2 GetImagePosition(int index)
{
return this._imageDisplays[index].position;
}
///
/// Chage position of image.
///
/// Location of ValueDisplay in list.
/// New position of image.
public void UpdateImagePosition(int index, Vector2 newPosition)
{
if (index < 0 || index >= this._imageDisplays.Count)
{
// Invalid index
return;
}
else
{
this._imageDisplays[index].position = newPosition;
}
}
/////
///// Change whether image is drawn of not.
/////
///// Location of ValueDisplay in list.
///// True to draw image, false to hide.
//public void UpdateImageDraw(int index, bool value)
//{
// if (index < 0 || index >= this._imageDisplays.Count)
// {
// // Invalid index
// return;
// }
// else
// {
// this._imageDisplays[index].visible = value;
// }
//}
///
/// Change the image's visibility and color
///
/// Index of the image in the HUD
/// Boolean representing whether the image is drawn or not
/// The color to color the image
public void UpdateImageVis(int index, bool visible, Color color)
{
if (index < 0 || index >= this._imageDisplays.Count)
{
// Invalid index
return;
}
else
{
this._imageDisplays[index].visible = visible;
this._imageDisplays[index].color = color;
}
}
///
/// Method that sets a text display as visible or invisible.
///
/// Location of ValueDisplay in list.
/// True to draw image, false to hide.
public void UpdateTextVisible(int index, bool visible)
{
if (index < 0 || index >= textDisplays.Count)
{
// Invalid index
return;
}
else
{
// Change the value
textDisplays[index].visible = visible;
}
}
///
/// Method which allows us to change the color of a TextDisplay.
///
/// Location of ValueDisplay in list.
/// New color of text.
public void UpdateTextColor(int index, Color color)
{
if (index < 0 || index >= textDisplays.Count)
{
// Invalid index
return;
}
else
{
// Change the value
textDisplays[index].color = color;
}
}
///
/// Default Draw function.
///
/// SpriteBatch used to draw used to draw.
public void Draw(SpriteBatch spriteBatch)
{
Draw(spriteBatch, 0, 0);
}
///
/// 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_old element in _imageDisplays)
{
if (element.visible == true)
{
spriteBatch.Draw(element.image,
new Rectangle((int)element.position.X + xoffset,
(int)element.position.Y + yoffset,
element.Size.Width,
element.Size.Height),
element.Source,
element.color);
}
}
foreach (ImageSpinner_old elementBig in imageSpinners)
{
if (elementBig.visible == true)
{
//ImageDisplay element = elementBig.images[elementBig.activeIndex];
//spriteBatch.Draw(element.image,
// new Rectangle((int)element.position.X + xoffset,
// (int)element.position.Y + yoffset,
// element.width,
// element.height),
// new Rectangle(0, 0, (int)(element.image.Width * element.xScale), (int)(element.image.Height * element.yScale)),
// element.color);
}
}
foreach (TextDisplay_old element in textDisplays)
{
if (element.visible)
{
spriteBatch.DrawString(Statics_Stream.Fonts.Arial, element.text, element.position, element.color);
}
}
}
}
}