//---------------------------------------------------------------------------------------------------------------------------------------------------
//
// Copyright (C)2007 DarkWynter Studios. All rights reserved.
//
//---------------------------------------------------------------------------------------------------------------------------------------------------
// {License Information: Creative Commons}
//---------------------------------------------------------------------------------------------------------------------------------------------------
namespace ElementalGame
{
#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
#endregion
// Generic Menu Enumeration
public enum MenuElementType
{
BUTTON,
OPTION,
VALUE,
LABEL,
IMAGE_SCROLL,
IMAGE_DISPLAY,
NONE
};
// Wrapper class for Game Menu Elements
public class GameMenuElement
{
protected string title = "Untitled";
protected MenuElementType type;
protected bool visible = true;
protected float scaleX = 1.0f;
protected float scaleY = 1.0f;
protected SpriteFont font = FontWriter.ComicSans;
public GameMenuElement()
{
type = MenuElementType.NONE;
}
public MenuElementType GetElementType()
{
return type;
}
public void SetScale(float scaleX, float scaleY)
{
this.scaleX = scaleX;
this.scaleY = scaleY;
}
public SpriteFont GetFont()
{
return font;
}
public void SetFont(SpriteFont font)
{
this.font = font;
}
public float GetScaleX()
{
return scaleX;
}
public float GetScaleY()
{
return scaleY;
}
public void SetTitle(string title)
{
this.title = title;
}
public string GetTitle()
{
return title;
}
public void Hide()
{
visible = false;
}
public void Show()
{
visible = true;
}
public bool isVisible()
{
return visible;
}
}
// 2D Label
public class GameMenuLabel : GameMenuElement
{
public GameMenuLabel()
{
type = MenuElementType.LABEL;
}
public GameMenuLabel(string title)
{
type = MenuElementType.LABEL;
this.title = title;
}
}
// 2D Image display
public class GameMenuRandomImageDisplay : GameMenuElement
{
private List images = new List();
private int selectedIndex = 0;
private List used = new List();
Random rand = new Random();
public GameMenuRandomImageDisplay()
{
type = MenuElementType.IMAGE_DISPLAY;
}
public GameMenuRandomImageDisplay(string title)
{
type = MenuElementType.IMAGE_DISPLAY;
this.title = title;
}
public void AddImage(Texture2D img)
{
images.Add(img);
}
public void RandomIndex()
{
if (used.Count == images.Count)
{
used.Clear();
}
do
{
selectedIndex = rand.Next(images.Count);
}
while (used.Contains(selectedIndex));
used.Add(selectedIndex);
}
public Texture2D GetCurrentTexture()
{
if (selectedIndex >= 0 && selectedIndex < images.Count)
{
return images[selectedIndex];
}
return null;
}
}
// 2D Button
public class GameMenuButton : GameMenuElement
{
public GameMenuButton()
{
type = MenuElementType.BUTTON;
}
public GameMenuButton(string title)
{
this.title = title;
type = MenuElementType.BUTTON;
}
}
// 2D Renderable
public class GameMenuValueInput : GameMenuElement
{
private int value = 0;
private int maxValue = 0;
private int minValue = 0;
private int valueIncrement = 1;
private float valueRatio = 0.0f;
public GameMenuValueInput()
{
type = MenuElementType.VALUE;
}
public GameMenuValueInput(string title, int minValue, int maxValue, int defaultValue, int increment)
{
this.title = title;
this.minValue = minValue;
this.maxValue = maxValue;
this.value = defaultValue;
this.valueIncrement = increment;
valueRatio = (float)this.value / (float)(this.maxValue - this.minValue);
type = MenuElementType.VALUE;
}
public int GetValue()
{
return value;
}
public void SetRange(int min, int max)
{
maxValue = max;
minValue = min;
UpdateValueRatio();
}
public void SetValue(int val)
{
if (val <= maxValue && val >= minValue)
{
value = val;
UpdateValueRatio();
}
}
private void UpdateValueRatio()
{
if (maxValue == minValue)
{
valueRatio = 1.0f;
}
else
{
valueRatio = ((float)this.value - this.minValue) / ((float)(this.maxValue - this.minValue));
}
}
public float GetValueRatio()
{
return valueRatio;
}
public void Increment()
{
value += valueIncrement;
if (value > maxValue)
{
value = maxValue;
}
UpdateValueRatio();
}
public void Decrement()
{
value -= valueIncrement;
if (value < minValue)
{
value = minValue;
}
UpdateValueRatio();
}
}
// 2D Value Scroller
public class GameMenuOption : GameMenuElement
{
private List options = new List();
private int activeOptionIndex = 0;
public GameMenuOption()
{
type = MenuElementType.OPTION;
}
public GameMenuOption(string title)
{
this.title = title;
type = MenuElementType.OPTION;
}
public void AddOption(string option)
{
options.Add(option);
}
public void SetOption(List optionList)
{
options = optionList;
}
public void SetCurrentIndex(int index)
{
activeOptionIndex = index;
}
public void PreviousOption()
{
activeOptionIndex--;
if (activeOptionIndex < 0)
{
activeOptionIndex = 0;
}
}
public void NextOption()
{
activeOptionIndex++;
if (activeOptionIndex >= options.Count)
{
activeOptionIndex = options.Count - 1;
}
}
public string GetActiveOption()
{
return options[activeOptionIndex];
}
public int GetActiveIndex()
{
return activeOptionIndex;
}
}
public class GameMenuImageScroller : GameMenuElement
{
public struct ImageScrollItem
{
public Texture2D offImage;
public Texture2D onImage;
public int x;
public int y;
public string name;
};
protected int maxVisibleAtATime = 0;
List items = new List();
private int activeItemIndex = 0;
public GameMenuImageScroller()
{
type = MenuElementType.IMAGE_SCROLL;
}
public GameMenuImageScroller(string title, int numVisible)
{
maxVisibleAtATime = numVisible;
this.title = title;
type = MenuElementType.IMAGE_SCROLL;
}
public void AddNew(string name, Texture2D onImage, Texture2D offImage, int x, int y)
{
ImageScrollItem item = new ImageScrollItem();
item.name = name;
item.onImage = onImage;
item.offImage = offImage;
item.x = x;
item.y = y;
items.Add(item);
}
public void AddNew(string name, Texture2D onImage, Texture2D offImage)
{
ImageScrollItem item = new ImageScrollItem();
item.name = name;
item.onImage = onImage;
item.offImage = offImage;
item.x = -1;
item.y = -1;
items.Add(item);
}
public ImageScrollItem GetItemAt(int index)
{
if (index >= 0 && index < items.Count)
{
return items[index];
}
return new ImageScrollItem();
}
public int GetNumItems()
{
return items.Count;
}
public int GetMaxItemsVisible()
{
return maxVisibleAtATime;
}
public void Clear()
{
activeItemIndex = 0;
items.Clear();
}
public void PreviousItem()
{
activeItemIndex--;
if (activeItemIndex < 0)
{
activeItemIndex = items.Count - 1;
}
}
public void NextItem()
{
activeItemIndex++;
if (activeItemIndex >= items.Count)
{
activeItemIndex = 0;
}
}
public ImageScrollItem GetActiveItem()
{
return items[activeItemIndex];
}
public int GetActiveIndex()
{
return activeItemIndex;
}
public void SetCurrentIndex(int index)
{
if (index >= 0 || index < items.Count)
{
activeItemIndex = index;
}
}
}
// Constructors, Gets, and Sets
public class GameMenu
{
private string title = "Untitled Menu";
private List menuElements = new List();
private int activeElementIndex = 0;
private Vector2 position = new Vector2();
private const int SLIDER_WIDTH = 150;
private const int SLIDER_HEIGHT = 30;
private bool drawMenuTitle = true;
//This texture is loaded in ElementalGame::Initialize
public static Texture2D sliderBackground;
public GameMenu(float x, float y)
{
position.X = x;
position.Y = y;
}
public void SetDrawMenuTitle(bool draw)
{
drawMenuTitle = draw;
}
public GameMenu(string title, float x, float y)
{
this.title = title;
position.X = x;
position.Y = y;
}
public void SetTitle(string title)
{
this.title = title;
}
public void SetPosition(float x, float y)
{
position.X = x;
position.Y = y;
}
public void AddMenuButton(bool visible, string title)
{
AddMenuButton(title);
if (!visible)
{
GetMenuElement(title).Hide();
}
}
public void AddMenuButton(string title)
{
menuElements.Add(new GameMenuButton(title));
}
public void AddMenuOption(bool visible, string title, params string[] options)
{
AddMenuOption(title,options);
if (!visible)
{
GetMenuElement(title).Hide();
}
}
public void AddMenuOption(string title, params string[] options)
{
GameMenuOption element = new GameMenuOption(title);
foreach (string s in options)
{
element.AddOption(s);
}
menuElements.Add(element);
}
public void AddRandomImageDisplay(string title, params Texture2D[] images)
{
GameMenuRandomImageDisplay element = new GameMenuRandomImageDisplay(title);
foreach (Texture2D image in images)
{
element.AddImage(image);
}
menuElements.Add(element);
}
public void SetMenuOption(List optionList, int optionNumber)
{
GameMenuOption menuOptions = (GameMenuOption)menuElements[optionNumber];
menuOptions.SetOption(optionList);
}
public void AddValueInput(bool visible, string title, int minValue, int maxValue, int defaultValue, int increment)
{
AddValueInput(title, minValue, maxValue, defaultValue, increment);
if (!visible)
{
GetMenuElement(title).Hide();
}
}
public void AddValueInput(string title, int minValue, int maxValue, int defaultValue, int increment)
{
GameMenuValueInput valueInput = new GameMenuValueInput(title, minValue, maxValue, defaultValue, increment);
menuElements.Add(valueInput);
}
public void AddImageScroller(string title, int numVisible)
{
GameMenuImageScroller element = new GameMenuImageScroller(title, numVisible);
menuElements.Add(element);
}
public void AddLabel(string title)
{
GameMenuLabel label = new GameMenuLabel(title);
menuElements.Add(label);
}
public void PreviousMenuElement()
{
activeElementIndex--;
if (activeElementIndex < 0)
{
activeElementIndex = 0;
}
if (GetActiveMenuElement().isVisible() == false)
{
PreviousMenuElement();
}
if (GetActiveMenuElement().GetElementType() == MenuElementType.LABEL)
{
if (activeElementIndex == 0)
{
NextMenuElement();
}
else
{
PreviousMenuElement();
}
}
}
public void NextMenuElement()
{
activeElementIndex++;
if (activeElementIndex >= menuElements.Count)
{
activeElementIndex = menuElements.Count - 1;
}
if (GetActiveMenuElement().isVisible() == false)
{
NextMenuElement();
}
if (GetActiveMenuElement().GetElementType() == MenuElementType.LABEL)
{
if (activeElementIndex == menuElements.Count - 1)
{
PreviousMenuElement();
}
else
{
NextMenuElement();
}
}
}
public string GetTitle()
{
return title;
}
public GameMenuElement GetActiveMenuElement()
{
return menuElements[activeElementIndex];
}
public int GetActiveIndex()
{
return activeElementIndex;
}
public GameMenuElement GetMenuElement(int index)
{
return menuElements[index];
}
public GameMenuElement GetMenuElement(string title)
{
foreach (GameMenuElement element in menuElements)
{
if (element.GetTitle() == title)
{
return element;
}
}
return new GameMenuElement();
}
public GameMenuElement GetMenuElement(string title, int fromIndex)
{
for (int i = fromIndex; i < menuElements.Count; i++)
{
if (menuElements[i].GetTitle() == title)
{
return menuElements[i];
}
}
return new GameMenuElement();
}
public void SetFont(SpriteFont font)
{
for (int i = 0; i < menuElements.Count; i++)
{
menuElements[i].SetFont(font);
}
}
public void Draw()
{
float yPosition = position.Y;
int titleLength = 0;
float scaleX = (XML.SystemSettings.GAME_WINDOW_WIDTH / 1280.0f);
float scaleY = (XML.SystemSettings.GAME_WINDOW_HEIGHT / 1024.0f);
if (drawMenuTitle)
{
ElementalGame.spriteBatch.DrawString(FontWriter.ComicSans, title, new Vector2(position.X, position.Y), Color.White);
//FontWriter.Ogilvie24.Draw(position.X, position.Y, title, Alignment.Left, Color.White, spriteBatch);
Vector2 size = FontWriter.ComicSans.MeasureString(title);
//Extra padding below the big font
yPosition += size.Y;
}
for (int i = 0; i < menuElements.Count; i++)
{
if (menuElements[i].isVisible() == true)
{
Color textColor = Color.White;
if (i == activeElementIndex)
{
textColor = Color.Red;
//FontWriter.MeadBold16.Draw(position.X, yPosition, menuElements[i].GetTitle(), Alignment.Left, Color.Red, spriteBatch);
}
ElementalGame.spriteBatch.DrawString(menuElements[i].GetFont(), menuElements[i].GetTitle(), new Vector2(position.X, yPosition), textColor);
//else
//{
// FontWriter.MeadBold16.Draw(position.X, yPosition, menuElements[i].GetTitle(), Alignment.Left, Color.White, spriteBatch);
//}
Vector2 stringSize = menuElements[i].GetFont().MeasureString(menuElements[i].GetTitle());
titleLength = (int)(stringSize.X) + 10;
if (menuElements[i].GetElementType() == MenuElementType.OPTION)
{
GameMenuOption option = (GameMenuOption)menuElements[i];
ElementalGame.spriteBatch.DrawString(menuElements[i].GetFont(), option.GetActiveOption(), new Vector2(position.X + titleLength, yPosition), Color.White);
/*
FontWriter.MeadBold16.Draw(position.X + titleLength,
yPosition,
option.GetActiveOption(),
Alignment.Left,
Color.White,
spriteBatch);*/
}
else if (menuElements[i].GetElementType() == MenuElementType.VALUE)
{
//GameMenuValueInput valueInput = (GameMenuValueInput)menuElements[i];
//FontWriter.MeadBold16.Draw(position.X + titleLength, yPosition, "" + valueInput.GetValue(), Alignment.Left, Color.White);
GameMenuValueInput valueSlider = (GameMenuValueInput)menuElements[i];
ElementalGame.spriteBatch.Draw(sliderBackground,
new Rectangle((int)(position.X) + titleLength, (int)(yPosition), SLIDER_WIDTH, SLIDER_HEIGHT),
Color.Honeydew);
//Draw the actual slider value here
ElementalGame.spriteBatch.Draw(sliderBackground,
new Rectangle((int)(position.X) + titleLength,
(int)(yPosition),
(int)(SLIDER_WIDTH * valueSlider.GetValueRatio()),
SLIDER_HEIGHT),
Color.DarkRed);
ElementalGame.spriteBatch.DrawString(menuElements[i].GetFont(), "" + valueSlider.GetValue(), new Vector2(position.X + titleLength + (SLIDER_WIDTH / 2), yPosition - 3), Color.Black);
//FontWriter.MeadBold16.Draw(position.X + titleLength + (SLIDER_WIDTH / 2),
// yPosition - 3,
// "" + valueSlider.GetValue(),
// Alignment.Left,
// Color.Black,
// spriteBatch);
}
else if (menuElements[i].GetElementType() == MenuElementType.IMAGE_DISPLAY)
{
GameMenuRandomImageDisplay imageDisplay = (GameMenuRandomImageDisplay)menuElements[i];
Texture2D image = imageDisplay.GetCurrentTexture();
//yPosition += (160 * scaleY);
if (image != null)
{
ElementalGame.spriteBatch.Draw(image, new Rectangle((int)(position.X),
(int)(yPosition),
(int)(image.Width * imageDisplay.GetScaleX() * scaleX),
(int)(image.Height * imageDisplay.GetScaleY() * scaleY)), Color.White);
yPosition += (image.Height + 50) * scaleY;
}
}
else if (menuElements[i].GetElementType() == MenuElementType.IMAGE_SCROLL)
{
GameMenuImageScroller scroller = (GameMenuImageScroller)menuElements[i];
int numItems = scroller.GetNumItems();
int maxItems = scroller.GetMaxItemsVisible();
int activeIndex = scroller.GetActiveIndex();
yPosition += 8;
//if the window is smaller than the list.. start with the active one
for (int index = (maxItems < numItems) ? activeIndex : 0;
index < ((maxItems < numItems)? activeIndex+maxItems : maxItems); index++)
{
if (index >= numItems)
{
break;
}
GameMenuImageScroller.ImageScrollItem item = scroller.GetItemAt(index);
float x, y;
if (item.x == -1)
{
x = position.X;
}
else
{
x = item.x;
}
if (item.y == -1)
{
y = yPosition;
}
else
{
y = item.y;
}
if (scroller.GetActiveIndex() == index)
{
if (item.onImage != null)
{
ElementalGame.spriteBatch.Draw(item.onImage, new Rectangle((int)(x),
(int)(y),
(int)(item.onImage.Width * scroller.GetScaleX() * scaleX),
(int)(item.onImage.Height * scroller.GetScaleY() * scaleY)), Color.White);
}
}
else
{
if (item.offImage != null)
{
ElementalGame.spriteBatch.Draw(item.offImage, new Rectangle((int)(x),
(int)(y),
(int)(item.offImage.Width * scroller.GetScaleX() * scaleX),
(int)(item.offImage.Height * scroller.GetScaleY() * scaleY)), Color.White);
}
}
int heightOffset = 0;
if (item.offImage != null)
{
heightOffset = item.offImage.Height;
}
yPosition += (heightOffset + 50) * scaleY;
}
}
yPosition += stringSize.Y + 10;
}
}
}
}
}