//--------------------------------------------------------------------------------------------------------------------------------------------------- // // 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; } } } } }