/*
* CSMessageDisplayPanel.cs
* Authors: Bradley R. Blankenship
* Copyright (c) 2007-2008 Cornell University
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using tAC_Engine.GUI;
using Util;
namespace ColonySim.GUI
{
///
/// Displays a given message and associated icons within the message.
///
public class CSMessageDisplayPanel : GUIPanel
{
#region Constants
// The constant for the size of the icons
const float ICON_SIZE = 48;
#endregion
#region Fields
// The GUILabels we will use for displaying our message
readonly List mTextLabels = new List();
// The GUILabels we will use for displaying the icons
readonly List mIconLabels = new List();
// The amount of time the ticker should display for
float mDisplayTime;
// The amount of time we have displayed for
float mCurrentTime;
// The icons for the current message
Texture2D[] mMessageIcons;
// The current message string
string mMessageString;
// The font we'll use
SpriteFont mFont;
#endregion
#region Properties
///
/// Allow getting and setting of the icon values.
///
public Texture2D[] MessageIcons
{
get { return mMessageIcons; }
set { mMessageIcons = value; }
}
///
/// Allow getting and setting of the message to be displayed.
///
public string MessageString
{
get { return mMessageString; }
set { mMessageString = value; }
}
///
/// Allow access to the amount of time to display a message.
///
public float DisplayTime
{
get { return mDisplayTime; }
set { mDisplayTime = value; }
}
string mFontName;
///
/// Allow getting and setting of the font to be used to display.
///
public string FontName
{
get { return mFontName; }
set { mFontName = value; }
}
#endregion
#region Initialization
///
/// Base Constructor
///
///
public CSMessageDisplayPanel(string font)
{
mFontName = @"Fonts\" + font;
}
///
/// Base Constructor
///
public CSMessageDisplayPanel()
{
mFontName = @"Fonts\dialogfont";
}
///
/// load content and initialize the mess.
///
public override void LoadContent()
{
// Base call
base.LoadContent();
// Load the font
mFont = ParentScreen.Content.Load(mFontName);
// set our background initially
Texture2D blackTexture = new Texture2D(ParentScreen.GraphicsDevice, 1, 1, 1,
TextureUsage.None, SurfaceFormat.Color);
Color[] color = new Color[1];
color[0] = Color.Black;
blackTexture.SetData(color);
Background = blackTexture;
}
///
/// load content and initialize the mess.
///
[Obsolete("LoadContent should never be called in this fashion. CSMessageDisplayPanel should be added to a GUIScreen instead.")]
public void LoadContent(ContentManager content, GameScreen parentScreen)
{
// Base call
base.LoadContent();
// Load the font
mFont = content.Load(@"Fonts\dialogfont");
// set our background initially
Texture2D blackTexture = new Texture2D(parentScreen.GraphicsDevice, 1, 1, 1,
TextureUsage.None, SurfaceFormat.Color);
Color[] color = new Color[1];
color[0] = Color.Black;
blackTexture.SetData(color);
Background = blackTexture;
}
GUILabel GenerateMultilineLabels(GUILabel pLabel, float pSize)
{
// The return value
GUILabel retVal = pLabel;
// Break up the string
string[] brokenString = TextUtility.BreakStringWithSpaces(pLabel.Text, pSize, pLabel.Font);
// Set the text for the label
pLabel.Text = brokenString[0];
pLabel.Size = pLabel.Font.MeasureString(pLabel.Text);
// The new text string
string ltext = string.Empty;
// Now iterate through the rest of the strings
for (int i = 1; i < brokenString.Length; i++)
{
// Add to the text
ltext += brokenString[i];
}
// If we have a string
if (ltext.Length > 0)
{
// Take the string and make a label
GUILabel label = new GUILabel();
label.Text = ltext;
label.Font = pLabel.Font;
label.Size = label.Font.MeasureString(label.Text);
label.Position = new Vector2(0+Bounds.X, pLabel.Bounds.Top + ICON_SIZE);
label.Background = Background;
label.TextColor = Color.Gold;
label.AddColor = Color.TransparentWhite;
label.BackgroundColor = Color.TransparentWhite;
// Add the label to the object
Add(label);
// Set it as the return value
retVal = label;
}
// Return the value
return retVal;
}
///
/// Resize all of the given labels, etc.
///
public override void Resize()
{
// Base call
base.Resize();
// If we have text labels
if (mTextLabels != null)
{
// Create the basic position vector
Vector2 position = new Vector2(Position.X, Position.Y);
// Now go through each of the given labels, one by one
for (int i = 0; i < mTextLabels.Count; i++)
{
GUILabel curLabel = mTextLabels[i];
// Set the size
curLabel.Size = mFont.MeasureString(curLabel.Text);
// If the current label exceeds the panel boundary,
// break the end off and move it to the next line
while (position.X + curLabel.Size.X > Bounds.Right)
{
float charWidth = curLabel.Font.MeasureString("A").X;
// If the left edge of the label is less than a character width
// from the right edge of the frame, move it to the next line
if (Bounds.Right - position.X < charWidth)
{
position.X = Bounds.Left;
position.Y += ICON_SIZE;
}
// Set the position of the current label
curLabel.Position = position;
// Now generate a new text label
curLabel = GenerateMultilineLabels(curLabel, Bounds.Right - position.X);
// Update the position
position.X = curLabel.Bounds.Left;
position.Y = curLabel.Bounds.Top;
}
// Set the position
curLabel.Position = position;
// Update the position value
position.X += curLabel.Size.X;
// If we have icons and our i is in the correct place
if (mIconLabels != null && i < mIconLabels.Count)
{
// Set the size
mIconLabels[i].Size = new Vector2(ICON_SIZE, ICON_SIZE);
// If the current position plus the size is greater than the right-most bounds
if (position.X + mIconLabels[i].Size.X > Bounds.Right)
{
// Update the position
position.X = 0+ Bounds.X;
position.Y += mIconLabels[i].Size.Y;
}
// Set the position
mIconLabels[i].Position = position;
// Update the position value
position.X += mIconLabels[i].Size.X;
}
}
}
}
#endregion
#region Update
///
/// Update the ticker.
///
///
public override void Update(Microsoft.Xna.Framework.GameTime gameTime)
{
// Base update
base.Update(gameTime);
// Get the amount of time that has elapsed
mCurrentTime += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
// If it's greater than us, kill us
if (mCurrentTime > mDisplayTime && mDisplayTime != -1)
{
// Disable and make us invisible
Visible = false;
}
}
#endregion
#region Behavior
///
/// Sets the enabled quality of a value.
///
public override bool Enabled
{
get { return mIsEnabled; }
set { mIsEnabled = value; }
}
///
/// Displays with the given message.
///
/// The current message for the panel.
public void DisplayMessage(string pMessage)
{
// Set our text
MessageString = pMessage;
// Re-initialize our values
ReformMessage();
// Reset our counter
mCurrentTime = 0.0f;
// Set us to be visible
Visible = true;
}
///
/// Reform the message.
///
private void ReformMessage()
{
// Dispose of all of the previous elements
Components.Clear();
// Clear the two lists
mTextLabels.Clear();
mIconLabels.Clear();
// If we have a message
if(MessageString != null)
{
// Divide the string up into it's parts, split on the icons
string[] labelStrings = MessageString.Split('#');
// Go through each of the text labels
for (int i = 0; i < labelStrings.Length; i++)
{
// Set the text values
GUILabel label = new GUILabel();
mTextLabels.Add(label);
label.Text = labelStrings[i];
label.TextColor = Color.Gold;
label.Font = mFont;
label.Background = Background;
label.AddColor = Color.TransparentWhite;
label.BackgroundColor = Color.TransparentWhite;
}
// If we have icons
if (mMessageIcons != null)
{
// Go through and get the message icons
for (int i = 0; i < mMessageIcons.Length; i++)
{
// Set the icon value
GUILabel label = new GUILabel();
label.Background = mMessageIcons[i];
mIconLabels.Add(label);
}
}
// If it is not null
if (mTextLabels.Count > 0)
{
// Add all of the new labels
foreach (GUILabel textLabel in mTextLabels)
{
// Add
Add(textLabel);
}
}
// If it is not null
if (mIconLabels.Count > 0)
{
foreach (GUILabel iconLabel in mIconLabels)
{
// Add
Add(iconLabel);
}
}
// Resize
Resize();
}
}
#endregion
}
}