v0.1
This commit is contained in:
58
Subsurface/Source/GUI/ComponentStyle.cs
Normal file
58
Subsurface/Source/GUI/ComponentStyle.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
class GUIComponentStyle
|
||||
{
|
||||
public readonly Vector4 Padding;
|
||||
|
||||
public readonly Color Color;
|
||||
|
||||
public readonly Color textColor;
|
||||
|
||||
public readonly Color HoverColor;
|
||||
public readonly Color SelectedColor;
|
||||
|
||||
public readonly Color OutlineColor;
|
||||
|
||||
public readonly List<Sprite> Sprites;
|
||||
|
||||
|
||||
public GUIComponentStyle(XElement element)
|
||||
{
|
||||
Sprites = new List<Sprite>();
|
||||
|
||||
Padding = ToolBox.GetAttributeVector4(element, "padding", Vector4.Zero);
|
||||
|
||||
Vector4 colorVector = ToolBox.GetAttributeVector4(element, "color", new Vector4(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
Color = new Color(colorVector.X, colorVector.Y, colorVector.Z, colorVector.W);
|
||||
|
||||
colorVector = ToolBox.GetAttributeVector4(element, "textcolor", new Vector4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
textColor = new Color(colorVector.X, colorVector.Y, colorVector.Z, colorVector.W);
|
||||
|
||||
colorVector = ToolBox.GetAttributeVector4(element, "hovercolor", new Vector4(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
HoverColor = new Color(colorVector.X, colorVector.Y, colorVector.Z, colorVector.W);
|
||||
|
||||
colorVector = ToolBox.GetAttributeVector4(element, "selectedcolor", new Vector4(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
SelectedColor = new Color(colorVector.X, colorVector.Y, colorVector.Z, colorVector.W);
|
||||
|
||||
colorVector = ToolBox.GetAttributeVector4(element, "outlinecolor", new Vector4(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
OutlineColor = new Color(colorVector.X, colorVector.Y, colorVector.Z, colorVector.W);
|
||||
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLower())
|
||||
{
|
||||
case "sprite":
|
||||
Sprites.Add(new Sprite(subElement));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
398
Subsurface/Source/GUI/GUI.cs
Normal file
398
Subsurface/Source/GUI/GUI.cs
Normal file
@@ -0,0 +1,398 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
[Flags]
|
||||
public enum Alignment
|
||||
{
|
||||
CenterX = 1, Left = 2, Right = 4, CenterY = 8, Top = 16, Bottom = 32 ,
|
||||
TopRight = (Top | Right), TopLeft = (Top | Left), TopCenter = (CenterX | Top),
|
||||
Center = (CenterX | CenterY),
|
||||
BottomRight = (Bottom | Right), BottomLeft = (Bottom | Left), BottomCenter = (CenterX | Bottom)
|
||||
}
|
||||
|
||||
class GUI
|
||||
{
|
||||
public static GUIStyle style;
|
||||
|
||||
static Texture2D t;
|
||||
public static SpriteFont Font, SmallFont;
|
||||
|
||||
private static GraphicsDevice graphicsDevice;
|
||||
|
||||
private static List<GUIMessage> messages = new List<GUIMessage>();
|
||||
|
||||
private static Sound[] sounds;
|
||||
|
||||
private static bool pauseMenuOpen;
|
||||
private static GUIFrame pauseMenu;
|
||||
|
||||
public static bool PauseMenuOpen
|
||||
{
|
||||
get { return pauseMenuOpen; }
|
||||
}
|
||||
|
||||
public static void LoadContent(GraphicsDevice graphics)
|
||||
{
|
||||
graphicsDevice = graphics;
|
||||
|
||||
sounds = new Sound[2];
|
||||
sounds[0] = Sound.Load("Content/Sounds/UI/UImsg.ogg");
|
||||
|
||||
// create 1x1 texture for line drawing
|
||||
t = new Texture2D(graphicsDevice, 1, 1);
|
||||
t.SetData<Color>(
|
||||
new Color[] { Color.White });// fill the texture with white
|
||||
|
||||
style = new GUIStyle("Content/UI/style.xml");
|
||||
}
|
||||
|
||||
public static void TogglePauseMenu()
|
||||
{
|
||||
if (Screen.Selected == Game1.MainMenuScreen) return;
|
||||
|
||||
TogglePauseMenu(null, null);
|
||||
|
||||
if (pauseMenuOpen)
|
||||
{
|
||||
pauseMenu = new GUIFrame(new Rectangle(0,0,200,300), null, Alignment.Center, style);
|
||||
|
||||
int y = 0;
|
||||
var button = new GUIButton(new Rectangle(0, y, 0, 30), "Resume", Alignment.CenterX, GUI.style, pauseMenu);
|
||||
button.OnClicked = TogglePauseMenu;
|
||||
|
||||
y += 60;
|
||||
|
||||
if (Screen.Selected == Game1.GameScreen && Game1.GameSession !=null)
|
||||
{
|
||||
SinglePlayerMode spMode = Game1.GameSession.gameMode as SinglePlayerMode;
|
||||
if (spMode!=null)
|
||||
{
|
||||
button = new GUIButton(new Rectangle(0, y, 0, 30), "Load previous", Alignment.CenterX, GUI.style, pauseMenu);
|
||||
button.OnClicked += TogglePauseMenu;
|
||||
button.OnClicked += Game1.GameSession.LoadPrevious;
|
||||
|
||||
y += 60;
|
||||
}
|
||||
}
|
||||
|
||||
if (Screen.Selected == Game1.LobbyScreen)
|
||||
{
|
||||
SinglePlayerMode spMode = Game1.GameSession.gameMode as SinglePlayerMode;
|
||||
if (spMode != null)
|
||||
{
|
||||
button = new GUIButton(new Rectangle(0, y, 0, 30), "Save & quit", Alignment.CenterX, GUI.style, pauseMenu);
|
||||
button.OnClicked += QuitClicked;
|
||||
button.OnClicked += TogglePauseMenu;
|
||||
button.UserData = "save";
|
||||
|
||||
y += 60;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
button = new GUIButton(new Rectangle(0, y, 0, 30), "Quit", Alignment.CenterX, GUI.style, pauseMenu);
|
||||
button.OnClicked += QuitClicked;
|
||||
button.OnClicked += TogglePauseMenu;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static bool TogglePauseMenu(GUIButton button, object obj)
|
||||
{
|
||||
pauseMenuOpen = !pauseMenuOpen;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool QuitClicked(GUIButton button, object obj)
|
||||
{
|
||||
if (button.UserData as string == "save")
|
||||
{
|
||||
SaveUtil.SaveGame(Game1.GameSession.SaveFile);
|
||||
}
|
||||
|
||||
|
||||
Game1.MainMenuScreen.Select();
|
||||
Game1.MainMenuScreen.SelectTab(null, (int)MainMenuScreen.Tabs.Main);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void DrawLine(SpriteBatch sb, Vector2 start, Vector2 end, Color clr, float depth = 0.0f)
|
||||
{
|
||||
Vector2 edge = end - start;
|
||||
// calculate angle to rotate line
|
||||
float angle = (float)Math.Atan2(edge.Y, edge.X);
|
||||
|
||||
sb.Draw(t,
|
||||
new Rectangle(// rectangle defines shape of line and position of start of line
|
||||
(int)start.X,
|
||||
(int)start.Y,
|
||||
(int)edge.Length(), //sb will strech the texture to fill this rectangle
|
||||
1), //width of line, change this to make thicker line
|
||||
null,
|
||||
clr, //colour of line
|
||||
angle, //angle of line (calulated above)
|
||||
new Vector2(0, 0), // point in line about which to rotate
|
||||
SpriteEffects.None,
|
||||
depth);
|
||||
}
|
||||
|
||||
public static void DrawRectangle(SpriteBatch sb, Vector2 start, Vector2 size, Color clr, bool isFilled = false, float depth = 0.0f)
|
||||
{
|
||||
if (isFilled)
|
||||
{
|
||||
sb.Draw(t, new Rectangle((int)start.X,(int)start.Y,(int)size.X,(int)size.Y),null,clr);
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector2 p2 = new Vector2(start.X + size.X, start.Y);
|
||||
Vector2 p4 = new Vector2(start.X, start.Y + size.Y);
|
||||
|
||||
DrawLine(sb, start, p2, clr, depth);
|
||||
DrawLine(sb, p2, start + size, clr, depth);
|
||||
DrawLine(sb, start + size, p4, clr, depth);
|
||||
DrawLine(sb, p4, start, clr, depth);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DrawRectangle(SpriteBatch sb, Rectangle rect, Color clr, bool isFilled = false, float depth = 0.0f)
|
||||
{
|
||||
if (isFilled)
|
||||
{
|
||||
sb.Draw(t, rect, null, clr);
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector2 p1 = new Vector2(rect.X, rect.Y);
|
||||
Vector2 p2 = new Vector2(rect.X + rect.Width, rect.Y);
|
||||
Vector2 p3 = new Vector2(rect.X + rect.Width, rect.Y + rect.Height);
|
||||
Vector2 p4 = new Vector2(rect.X, rect.Y + rect.Height);
|
||||
|
||||
DrawLine(sb, p1, p2, clr, depth);
|
||||
DrawLine(sb, p2, p3, clr, depth);
|
||||
DrawLine(sb, p3, p4, clr, depth);
|
||||
DrawLine(sb, p4, p1, clr, depth);
|
||||
}
|
||||
}
|
||||
|
||||
public static Texture2D CreateCircle(int radius)
|
||||
{
|
||||
int outerRadius = radius * 2 + 2; // So circle doesn't go out of bounds
|
||||
Texture2D texture = new Texture2D(graphicsDevice, outerRadius, outerRadius);
|
||||
|
||||
Color[] data = new Color[outerRadius * outerRadius];
|
||||
|
||||
// Colour the entire texture transparent first.
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
data[i] = Color.Transparent;
|
||||
|
||||
// Work out the minimum step necessary using trigonometry + sine approximation.
|
||||
double angleStep = 1f / radius;
|
||||
|
||||
for (double angle = 0; angle < Math.PI * 2; angle += angleStep)
|
||||
{
|
||||
// Use the parametric definition of a circle: http://en.wikipedia.org/wiki/Circle#Cartesian_coordinates
|
||||
int x = (int)Math.Round(radius + radius * Math.Cos(angle));
|
||||
int y = (int)Math.Round(radius + radius * Math.Sin(angle));
|
||||
|
||||
data[y * outerRadius + x + 1] = Color.White;
|
||||
}
|
||||
|
||||
texture.SetData(data);
|
||||
return texture;
|
||||
}
|
||||
|
||||
public static Texture2D CreateCapsule(int radius, int height)
|
||||
{
|
||||
int textureWidth = radius * 2, textureHeight = height + radius * 2;
|
||||
|
||||
Texture2D texture = new Texture2D(graphicsDevice, textureWidth, textureHeight);
|
||||
Color[] data = new Color[textureWidth * textureHeight];
|
||||
|
||||
// Colour the entire texture transparent first.
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
data[i] = Color.Transparent;
|
||||
|
||||
// Work out the minimum step necessary using trigonometry + sine approximation.
|
||||
double angleStep = 1f / radius;
|
||||
|
||||
for (int i = 0; i < 2; i++ )
|
||||
{
|
||||
for (double angle = 0; angle < Math.PI * 2; angle += angleStep)
|
||||
{
|
||||
// Use the parametric definition of a circle: http://en.wikipedia.org/wiki/Circle#Cartesian_coordinates
|
||||
int x = (int)Math.Round(radius + radius * Math.Cos(angle));
|
||||
int y = (height-1)*i + (int)Math.Round(radius + radius * Math.Sin(angle));
|
||||
|
||||
data[y * textureWidth + x] = Color.White;
|
||||
}
|
||||
}
|
||||
|
||||
for (int y = radius; y<textureHeight-radius; y++)
|
||||
{
|
||||
data[y * textureWidth] = Color.White;
|
||||
data[y * textureWidth + (textureWidth-1)] = Color.White;
|
||||
}
|
||||
|
||||
texture.SetData(data);
|
||||
return texture;
|
||||
}
|
||||
|
||||
public static Texture2D CreateRectangle(int width, int height)
|
||||
{
|
||||
Texture2D texture = new Texture2D(graphicsDevice, width, height);
|
||||
Color[] data = new Color[width * height];
|
||||
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
data[i] = Color.Transparent;
|
||||
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
data[y * width] = Color.White;
|
||||
data[y * width + (width-1)] = Color.White;
|
||||
}
|
||||
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
data[x] = Color.White;
|
||||
data[(height - 1) * width + x] = Color.White;
|
||||
}
|
||||
|
||||
texture.SetData(data);
|
||||
return texture;
|
||||
}
|
||||
|
||||
public static bool DrawButton(SpriteBatch sb, Rectangle rect, string text, bool isHoldable = false)
|
||||
{
|
||||
Color color = new Color(200, 200, 200);
|
||||
|
||||
bool clicked = false;
|
||||
|
||||
if (rect.Contains(PlayerInput.GetMouseState.Position))
|
||||
{
|
||||
clicked = (PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed);
|
||||
|
||||
color = clicked ? new Color(100, 100, 100) : new Color(250, 250, 250);
|
||||
|
||||
if (!isHoldable)
|
||||
clicked = PlayerInput.LeftButtonClicked();
|
||||
}
|
||||
|
||||
DrawRectangle(sb, rect, color, true);
|
||||
sb.DrawString(Font, text, new Vector2(rect.X + 10, rect.Y + 10), Color.White);
|
||||
|
||||
return clicked;
|
||||
}
|
||||
|
||||
public static void Draw(float deltaTime, SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
spriteBatch.DrawString(Font,
|
||||
"FPS: " + (int)Game1.FrameCounter.AverageFramesPerSecond,
|
||||
new Vector2(10, 10), Color.White);
|
||||
|
||||
if (Game1.DebugDraw)
|
||||
{
|
||||
spriteBatch.DrawString(Font,
|
||||
"Physics: " + Game1.World.UpdateTime
|
||||
+ " - bodies: " + Game1.World.BodyList.Count
|
||||
+ "Camera pos: " + Game1.GameScreen.Cam.Position,
|
||||
new Vector2(10, 30), Color.White);
|
||||
}
|
||||
|
||||
|
||||
if (Character.Controlled != null && cam!=null) Character.Controlled.DrawHud(spriteBatch, cam);
|
||||
if (Game1.NetworkMember != null) Game1.NetworkMember.Draw(spriteBatch);
|
||||
|
||||
DrawMessages(spriteBatch, (float)deltaTime);
|
||||
|
||||
if (GUIMessageBox.messageBoxes.Count>0)
|
||||
{
|
||||
var messageBox = GUIMessageBox.messageBoxes.Peek();
|
||||
if (messageBox != null) messageBox.Draw(spriteBatch);
|
||||
}
|
||||
|
||||
if (pauseMenuOpen)
|
||||
{
|
||||
pauseMenu.Update(1.0f);
|
||||
pauseMenu.Draw(spriteBatch);
|
||||
}
|
||||
|
||||
DebugConsole.Draw(spriteBatch);
|
||||
|
||||
|
||||
if (GUIComponent.MouseOn != null && !string.IsNullOrWhiteSpace(GUIComponent.MouseOn.ToolTip)) GUIComponent.MouseOn.DrawToolTip(spriteBatch);
|
||||
}
|
||||
|
||||
public static void Update(float deltaTime)
|
||||
{
|
||||
if (GUIMessageBox.messageBoxes.Count > 0)
|
||||
{
|
||||
var messageBox = GUIMessageBox.messageBoxes.Peek();
|
||||
if (messageBox != null)
|
||||
{
|
||||
GUIComponent.MouseOn = messageBox;
|
||||
messageBox.Update(deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddMessage(string message, Color color, float lifeTime = 3.0f, bool playSound = true)
|
||||
{
|
||||
if (messages.Count>0 && messages[messages.Count-1].Text == message)
|
||||
{
|
||||
messages[messages.Count - 1].LifeTime = lifeTime;
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2 currPos = new Vector2(Game1.GraphicsWidth / 2.0f, Game1.GraphicsHeight * 0.7f);
|
||||
currPos.Y += messages.Count * 30;
|
||||
|
||||
messages.Add(new GUIMessage(message, color, currPos, lifeTime));
|
||||
if (playSound) PlayMessageSound();
|
||||
}
|
||||
|
||||
public static void PlayMessageSound()
|
||||
{
|
||||
sounds[0].Play();
|
||||
}
|
||||
|
||||
private static void DrawMessages(SpriteBatch spriteBatch, float deltaTime)
|
||||
{
|
||||
if (messages.Count == 0) return;
|
||||
|
||||
Vector2 currPos = new Vector2(Game1.GraphicsWidth / 2.0f, Game1.GraphicsHeight * 0.7f);
|
||||
|
||||
int i = 1;
|
||||
foreach (GUIMessage msg in messages)
|
||||
{
|
||||
float alpha = 1.0f;
|
||||
|
||||
if (msg.LifeTime < 1.0f)
|
||||
{
|
||||
alpha -= 1.0f - msg.LifeTime;
|
||||
}
|
||||
|
||||
msg.Pos = MathUtils.SmoothStep(msg.Pos, currPos, deltaTime*20.0f);
|
||||
|
||||
spriteBatch.DrawString(Font, msg.Text,
|
||||
new Vector2((int)msg.Pos.X, (int)msg.Pos.Y),
|
||||
msg.Color * alpha, 0.0f,
|
||||
new Vector2((int)(0.5f * msg.Size.X), (int)(0.5f * msg.Size.Y)), 1.0f, SpriteEffects.None, 0.0f);
|
||||
|
||||
currPos.Y += 30.0f;
|
||||
|
||||
messages[0].LifeTime -= deltaTime/i;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
if (messages[0].LifeTime <= 0.0f) messages.Remove(messages[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
103
Subsurface/Source/GUI/GUIButton.cs
Normal file
103
Subsurface/Source/GUI/GUIButton.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
class GUIButton : GUIComponent
|
||||
{
|
||||
protected GUITextBlock textBlock;
|
||||
protected GUIFrame frame;
|
||||
|
||||
public delegate bool OnClickedHandler(GUIButton button, object obj);
|
||||
public OnClickedHandler OnClicked;
|
||||
|
||||
public delegate bool OnPressedHandler();
|
||||
public OnPressedHandler OnPressed;
|
||||
|
||||
public bool Enabled { get; set; }
|
||||
|
||||
public string Text
|
||||
{
|
||||
get { return textBlock.Text; }
|
||||
set { textBlock.Text = value; }
|
||||
}
|
||||
|
||||
public GUIButton(Rectangle rect, string text, GUIStyle style, GUIComponent parent = null)
|
||||
: this(rect, text, null, Alignment.Left, style, parent)
|
||||
{
|
||||
}
|
||||
|
||||
public GUIButton(Rectangle rect, string text, Alignment alignment, GUIStyle style, GUIComponent parent = null)
|
||||
: this(rect, text, null, alignment, style, parent)
|
||||
{
|
||||
}
|
||||
|
||||
public GUIButton(Rectangle rect, string text, Color? color, GUIStyle style, GUIComponent parent = null)
|
||||
: this(rect, text, color, (Alignment.Left | Alignment.Top), style, parent)
|
||||
{
|
||||
}
|
||||
|
||||
public GUIButton(Rectangle rect, string text, Color? color, Alignment alignment, GUIStyle style, GUIComponent parent = null)
|
||||
:base (style)
|
||||
{
|
||||
this.rect = rect;
|
||||
if (color!=null) this.color = (Color)color;
|
||||
this.alignment = alignment;
|
||||
|
||||
Enabled = true;
|
||||
|
||||
if (parent != null)
|
||||
parent.AddChild(this);
|
||||
|
||||
frame = new GUIFrame(new Rectangle(0,0,0,0), style, this);
|
||||
if (style!=null) style.Apply(frame, this);
|
||||
|
||||
textBlock = new GUITextBlock(new Rectangle(0, 0, 0, 0), text,
|
||||
Color.Transparent, (this.style==null) ? Color.Black : this.style.textColor,
|
||||
Alignment.Center, style, this);
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
if (rect.Contains(PlayerInput.GetMouseState.Position) && Enabled && (MouseOn == null || MouseOn == this || IsParentOf(MouseOn)))
|
||||
{
|
||||
state = ComponentState.Hover;
|
||||
if (PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed)
|
||||
{
|
||||
if (OnPressed != null)
|
||||
{
|
||||
if (OnPressed()) state = ComponentState.Selected;
|
||||
}
|
||||
}
|
||||
else if (PlayerInput.LeftButtonClicked())
|
||||
{
|
||||
if (OnClicked != null)
|
||||
{
|
||||
if (OnClicked(this, UserData)) state = ComponentState.Selected;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
state = ComponentState.None;
|
||||
}
|
||||
|
||||
frame.State = state;
|
||||
|
||||
//Color currColor = color;
|
||||
//if (state == ComponentState.Hover) currColor = hoverColor;
|
||||
//if (state == ComponentState.Selected) currColor = selectedColor;
|
||||
|
||||
//GUI.DrawRectangle(spriteBatch, rect, currColor * alpha, true);
|
||||
|
||||
////spriteBatch.DrawString(HUD.font, text, new Vector2(rect.X+rect.Width/2, rect.Y+rect.Height/2), Color.Black, 0.0f, new Vector2(0.5f,0.5f), 1.0f, SpriteEffects.None, 0.0f);
|
||||
|
||||
//GUI.DrawRectangle(spriteBatch, rect, Color.Black * alpha, false);
|
||||
|
||||
DrawChildren(spriteBatch);
|
||||
|
||||
if (!Enabled) GUI.DrawRectangle(spriteBatch, rect, Color.Gray*0.5f, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
347
Subsurface/Source/GUI/GUIComponent.cs
Normal file
347
Subsurface/Source/GUI/GUIComponent.cs
Normal file
@@ -0,0 +1,347 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using EventInput;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
abstract class GUIComponent
|
||||
{
|
||||
public static GUIComponent MouseOn;
|
||||
|
||||
protected static KeyboardDispatcher keyboardDispatcher;
|
||||
|
||||
public enum ComponentState { None, Hover, Selected};
|
||||
|
||||
protected Alignment alignment;
|
||||
|
||||
protected GUIComponentStyle style;
|
||||
|
||||
protected object userData;
|
||||
|
||||
protected Rectangle rect;
|
||||
|
||||
public bool CanBeFocused;
|
||||
|
||||
protected Vector4 padding;
|
||||
|
||||
protected Color color;
|
||||
protected Color hoverColor;
|
||||
protected Color selectedColor;
|
||||
|
||||
protected GUIComponent parent;
|
||||
public List<GUIComponent> children;
|
||||
|
||||
protected ComponentState state;
|
||||
|
||||
public virtual SpriteFont Font
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public string ToolTip
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
private GUITextBlock toolTipBlock;
|
||||
|
||||
//protected float alpha;
|
||||
|
||||
public GUIComponent Parent
|
||||
{
|
||||
get { return parent; }
|
||||
}
|
||||
|
||||
public Vector2 Center
|
||||
{
|
||||
get { return new Vector2(rect.Center.X, rect.Center.Y); }
|
||||
}
|
||||
|
||||
public Rectangle Rect
|
||||
{
|
||||
get { return rect; }
|
||||
set
|
||||
{
|
||||
int prevX = rect.X, prevY = rect.Y;
|
||||
int prevWidth = rect.Width, prevHeight = rect.Height;
|
||||
|
||||
rect = value;
|
||||
|
||||
if (prevX == rect.X && prevY == rect.Y && rect.Width == prevWidth && rect.Height == prevHeight) return;
|
||||
|
||||
foreach (GUIComponent child in children)
|
||||
{
|
||||
child.Rect = new Rectangle(
|
||||
child.rect.X + (rect.X - prevX),
|
||||
child.rect.Y + (rect.Y - prevY),
|
||||
Math.Max(child.rect.Width + (rect.Width - prevWidth),0),
|
||||
Math.Max(child.rect.Height + (rect.Height - prevHeight),0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected List<Sprite> sprites;
|
||||
//public Alignment SpriteAlignment { get; set; }
|
||||
//public bool RepeatSpriteX, RepeatSpriteY;
|
||||
|
||||
public Color OutlineColor { get; set; }
|
||||
|
||||
public ComponentState State
|
||||
{
|
||||
get { return state; }
|
||||
set { state = value; }
|
||||
}
|
||||
|
||||
public object UserData
|
||||
{
|
||||
get { return userData; }
|
||||
set { userData = value; }
|
||||
}
|
||||
|
||||
public virtual Vector4 Padding
|
||||
{
|
||||
get { return padding; }
|
||||
set { padding = value; }
|
||||
}
|
||||
|
||||
public int CountChildren
|
||||
{
|
||||
get { return children.Count(); }
|
||||
}
|
||||
|
||||
public virtual Color Color
|
||||
{
|
||||
get { return color; }
|
||||
set { color = value; }
|
||||
}
|
||||
|
||||
public Color HoverColor
|
||||
{
|
||||
get { return hoverColor; }
|
||||
set { hoverColor = value; }
|
||||
}
|
||||
|
||||
public Color SelectedColor
|
||||
{
|
||||
get { return selectedColor; }
|
||||
set { selectedColor = value; }
|
||||
}
|
||||
|
||||
|
||||
//public float Alpha
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// return alpha;
|
||||
// }
|
||||
// set
|
||||
// {
|
||||
// alpha = MathHelper.Clamp(value, 0.0f, 1.0f);
|
||||
// foreach (GUIComponent child in children)
|
||||
// {
|
||||
// child.Alpha = value;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
protected GUIComponent(GUIStyle style)
|
||||
{
|
||||
//alpha = 1.0f;
|
||||
|
||||
OutlineColor = Color.Transparent;
|
||||
|
||||
Font = GUI.Font;
|
||||
|
||||
sprites = new List<Sprite>();
|
||||
children = new List<GUIComponent>();
|
||||
|
||||
CanBeFocused = true;
|
||||
|
||||
if (style!=null) style.Apply(this);
|
||||
}
|
||||
|
||||
public static void Init(GameWindow window)
|
||||
{
|
||||
keyboardDispatcher = new KeyboardDispatcher(window);
|
||||
}
|
||||
|
||||
public T GetChild<T>()
|
||||
{
|
||||
foreach (GUIComponent child in children)
|
||||
{
|
||||
if (child is T) return (T)(object)child;
|
||||
}
|
||||
|
||||
return default(T);
|
||||
}
|
||||
|
||||
public GUIComponent GetChild(object obj)
|
||||
{
|
||||
foreach (GUIComponent child in children)
|
||||
{
|
||||
if (child.UserData == obj) return child;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool IsParentOf(GUIComponent component)
|
||||
{
|
||||
foreach (GUIComponent child in children)
|
||||
{
|
||||
if (child == component) return true;
|
||||
if (child.IsParentOf(component)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
Color currColor = color;
|
||||
if (state == ComponentState.Selected) currColor = selectedColor;
|
||||
if (state == ComponentState.Hover) currColor = hoverColor;
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, rect, currColor * (currColor.A / 255.0f), true);
|
||||
|
||||
if (sprites != null)
|
||||
{
|
||||
foreach (Sprite sprite in sprites)
|
||||
{
|
||||
Vector2 startPos = new Vector2(rect.X, rect.Y);
|
||||
Vector2 size = new Vector2(sprite.SourceRect.Width, sprite.SourceRect.Height);
|
||||
|
||||
if (sprite.size.X == 0.0f) size.X = rect.Width;
|
||||
if (sprite.size.Y == 0.0f) size.Y = rect.Height;
|
||||
|
||||
sprite.DrawTiled(spriteBatch, startPos, size, currColor * (currColor.A / 255.0f));
|
||||
}
|
||||
}
|
||||
|
||||
//Color newColor = color;
|
||||
//if (state == ComponentState.Selected) newColor = selectedColor;
|
||||
//if (state == ComponentState.Hover) newColor = hoverColor;
|
||||
|
||||
//GUI.DrawRectangle(spriteBatch, rect, newColor*alpha, true);
|
||||
//DrawChildren(spriteBatch);
|
||||
}
|
||||
|
||||
public void DrawToolTip(SpriteBatch spriteBatch)
|
||||
{
|
||||
int width = 200;
|
||||
if (toolTipBlock==null || (string)toolTipBlock.userData != ToolTip)
|
||||
{
|
||||
string wrappedText = ToolBox.WrapText(ToolTip, width, GUI.SmallFont);
|
||||
toolTipBlock = new GUITextBlock(new Rectangle(0,0,width, wrappedText.Split('\n').Length*15), ToolTip, GUI.style, null, true);
|
||||
toolTipBlock.userData = ToolTip;
|
||||
}
|
||||
|
||||
toolTipBlock.rect = new Rectangle((int)PlayerInput.MousePosition.X, (int)PlayerInput.MousePosition.Y, toolTipBlock.rect.Width, toolTipBlock.rect.Height);
|
||||
toolTipBlock.Draw(spriteBatch);
|
||||
}
|
||||
|
||||
public virtual void Update(float deltaTime)
|
||||
{
|
||||
if (CanBeFocused)
|
||||
{
|
||||
if (rect.Contains(PlayerInput.MousePosition))
|
||||
{
|
||||
MouseOn = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MouseOn == this) MouseOn = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
foreach (GUIComponent child in children)
|
||||
{
|
||||
child.Update(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void UpdateDimensions(GUIComponent parent = null)
|
||||
{
|
||||
Rectangle parentRect = (parent==null) ? new Rectangle(0,0,Game1.GraphicsWidth, Game1.GraphicsHeight) : parent.rect;
|
||||
|
||||
Vector4 padding = (parent == null) ? Vector4.Zero : parent.padding;
|
||||
|
||||
if (rect.Width == 0) rect.Width = parentRect.Width - rect.X
|
||||
- (int)padding.X - (int)padding.Z;
|
||||
|
||||
if (rect.Height == 0) rect.Height = parentRect.Height - rect.Y
|
||||
- (int)padding.Y - (int)padding.W;
|
||||
|
||||
if (alignment.HasFlag(Alignment.CenterX))
|
||||
{
|
||||
rect.X += parentRect.X + (int)parentRect.Width/2 - (int)rect.Width/2;
|
||||
}
|
||||
else if (alignment.HasFlag(Alignment.Right))
|
||||
{
|
||||
rect.X += parentRect.X + (int)parentRect.Width - (int)padding.Z - (int)rect.Width;
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.X += parentRect.X + (int)padding.X;
|
||||
}
|
||||
|
||||
if (alignment.HasFlag(Alignment.CenterY))
|
||||
{
|
||||
rect.Y += parentRect.Y + (int)parentRect.Height / 2 - (int)rect.Height / 2;
|
||||
}
|
||||
else if (alignment.HasFlag(Alignment.Bottom))
|
||||
{
|
||||
rect.Y += parentRect.Y + (int)parentRect.Height - (int)padding.W - (int)rect.Height;
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.Y += parentRect.Y + (int)padding.Y;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ApplyStyle(GUIComponentStyle style)
|
||||
{
|
||||
color = style.Color;
|
||||
hoverColor = style.HoverColor;
|
||||
selectedColor = style.SelectedColor;
|
||||
|
||||
padding = style.Padding;
|
||||
sprites = style.Sprites;
|
||||
|
||||
OutlineColor = style.OutlineColor;
|
||||
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
public virtual void DrawChildren(SpriteBatch spriteBatch)
|
||||
{
|
||||
for (int i = 0; i < children.Count; i++ )
|
||||
{
|
||||
children[i].Draw(spriteBatch);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void AddChild(GUIComponent child)
|
||||
{
|
||||
child.parent = this;
|
||||
child.UpdateDimensions(this);
|
||||
|
||||
children.Add(child);
|
||||
}
|
||||
|
||||
public virtual void RemoveChild(GUIComponent child)
|
||||
{
|
||||
if (children.Contains(child)) children.Remove(child);
|
||||
}
|
||||
|
||||
public virtual void ClearChildren()
|
||||
{
|
||||
children.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
61
Subsurface/Source/GUI/GUIFrame.cs
Normal file
61
Subsurface/Source/GUI/GUIFrame.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
class GUIFrame : GUIComponent
|
||||
{
|
||||
public GUIFrame(Rectangle rect, GUIStyle style = null, GUIComponent parent = null)
|
||||
: this(rect, null, (Alignment.Left | Alignment.Top), style, parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public GUIFrame(Rectangle rect, Color color, GUIStyle style = null, GUIComponent parent = null)
|
||||
: this(rect, color, (Alignment.Left | Alignment.Top), style, parent)
|
||||
{
|
||||
}
|
||||
|
||||
public GUIFrame(Rectangle rect, Color? color, Alignment alignment, GUIStyle style = null, GUIComponent parent = null)
|
||||
: base(style)
|
||||
{
|
||||
this.rect = rect;
|
||||
|
||||
this.alignment = alignment;
|
||||
|
||||
if (color!=null) this.color = (Color)color;
|
||||
|
||||
if (parent != null)
|
||||
{
|
||||
parent.AddChild(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateDimensions();
|
||||
}
|
||||
|
||||
//if (style != null) ApplyStyle(style);
|
||||
}
|
||||
|
||||
public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
|
||||
{
|
||||
|
||||
|
||||
Color currColor = color;
|
||||
if (state == ComponentState.Selected) currColor = selectedColor;
|
||||
if (state == ComponentState.Hover) currColor = hoverColor;
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, rect, currColor * (currColor.A/255.0f), true);
|
||||
base.Draw(spriteBatch);
|
||||
|
||||
if (OutlineColor != Color.Transparent)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, rect, OutlineColor * (OutlineColor.A/255.0f), false);
|
||||
}
|
||||
|
||||
|
||||
DrawChildren(spriteBatch);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
85
Subsurface/Source/GUI/GUIImage.cs
Normal file
85
Subsurface/Source/GUI/GUIImage.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
class GUIImage : GUIComponent
|
||||
{
|
||||
Sprite sprite;
|
||||
|
||||
Rectangle sourceRect;
|
||||
|
||||
bool crop;
|
||||
|
||||
public bool Crop
|
||||
{
|
||||
get
|
||||
{
|
||||
return crop;
|
||||
}
|
||||
set
|
||||
{
|
||||
crop = value;
|
||||
if (crop)
|
||||
{
|
||||
sourceRect.Width = Math.Min(sprite.SourceRect.Width, Rect.Width);
|
||||
sourceRect.Height = Math.Min(sprite.SourceRect.Height, Rect.Height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float Scale
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public Rectangle SourceRect
|
||||
{
|
||||
get { return sourceRect; }
|
||||
set { sourceRect = value; }
|
||||
}
|
||||
|
||||
public GUIImage(Rectangle rect, string spritePath, Alignment alignment, GUIComponent parent = null)
|
||||
: this(rect, new Sprite(spritePath, Vector2.Zero), alignment, parent)
|
||||
{
|
||||
}
|
||||
|
||||
public GUIImage(Rectangle rect, Sprite sprite, Alignment alignment, GUIComponent parent = null)
|
||||
: base(null)
|
||||
{
|
||||
this.rect = rect;
|
||||
|
||||
this.alignment = alignment;
|
||||
|
||||
color = Color.White;
|
||||
|
||||
//alpha = 1.0f;
|
||||
|
||||
Scale = 1.0f;
|
||||
|
||||
this.sprite = sprite;
|
||||
|
||||
if (rect.Width == 0) this.rect.Width = (int)sprite.size.X;
|
||||
if (rect.Height == 0) this.rect.Height = (int)Math.Min(sprite.size.Y, sprite.size.Y * (this.rect.Width / sprite.size.X));
|
||||
|
||||
sourceRect = sprite.SourceRect;
|
||||
|
||||
if (parent != null)
|
||||
parent.AddChild(this);
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
Color currColor = color;
|
||||
if (state == ComponentState.Hover) currColor = hoverColor;
|
||||
if (state == ComponentState.Selected) currColor = selectedColor;
|
||||
|
||||
spriteBatch.Draw(sprite.Texture, new Vector2(rect.X, rect.Y), sourceRect, currColor * (currColor.A / 255.0f), 0.0f, Vector2.Zero,
|
||||
Scale, SpriteEffects.None, 0.0f);
|
||||
|
||||
DrawChildren(spriteBatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
302
Subsurface/Source/GUI/GUIListBox.cs
Normal file
302
Subsurface/Source/GUI/GUIListBox.cs
Normal file
@@ -0,0 +1,302 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
class GUIListBox : GUIComponent
|
||||
{
|
||||
protected GUIComponent selected;
|
||||
|
||||
public delegate bool OnSelectedHandler(object obj);
|
||||
public OnSelectedHandler OnSelected;
|
||||
|
||||
public delegate object CheckSelectedHandler();
|
||||
public CheckSelectedHandler CheckSelected;
|
||||
|
||||
private GUIScrollBar scrollBar;
|
||||
private GUIFrame frame;
|
||||
|
||||
private int totalSize;
|
||||
|
||||
private int spacing;
|
||||
|
||||
private bool scrollBarEnabled;
|
||||
private bool scrollBarHidden;
|
||||
|
||||
private bool enabled;
|
||||
|
||||
public object SelectedData
|
||||
{
|
||||
get
|
||||
{
|
||||
return (selected == null) ? null : selected.UserData;
|
||||
}
|
||||
}
|
||||
|
||||
public int SelectedIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
if (selected == null) return -1;
|
||||
return children.FindIndex(x => x == selected);
|
||||
}
|
||||
}
|
||||
|
||||
public float BarScroll
|
||||
{
|
||||
get { return scrollBar.BarScroll; }
|
||||
set { scrollBar.BarScroll = value; }
|
||||
}
|
||||
|
||||
public float BarSize
|
||||
{
|
||||
get { return scrollBar.BarSize; }
|
||||
}
|
||||
|
||||
public int Spacing
|
||||
{
|
||||
get { return spacing; }
|
||||
set { spacing = value; }
|
||||
}
|
||||
|
||||
public bool Enabled
|
||||
{
|
||||
get { return enabled; }
|
||||
set { enabled = value; }
|
||||
}
|
||||
|
||||
public bool ScrollBarEnabled
|
||||
{
|
||||
get { return scrollBarEnabled; }
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
if (!scrollBarEnabled && scrollBarHidden) ShowScrollBar();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (scrollBarEnabled && !scrollBarHidden) HideScrollBar();
|
||||
}
|
||||
|
||||
scrollBarEnabled = value;
|
||||
}
|
||||
}
|
||||
|
||||
public GUIListBox(Rectangle rect, GUIStyle style, GUIComponent parent = null)
|
||||
: this(rect, style, Alignment.TopLeft, parent)
|
||||
{
|
||||
}
|
||||
|
||||
public GUIListBox(Rectangle rect, GUIStyle style, Alignment alignment, GUIComponent parent = null)
|
||||
: this(rect, null, style, parent)
|
||||
{
|
||||
}
|
||||
|
||||
public GUIListBox(Rectangle rect, Color? color, GUIStyle style = null, GUIComponent parent = null)
|
||||
: this(rect, color, (Alignment.Left | Alignment.Top), style, parent)
|
||||
{
|
||||
}
|
||||
|
||||
public GUIListBox(Rectangle rect, Color? color, Alignment alignment, GUIStyle style = null, GUIComponent parent = null)
|
||||
: base(style)
|
||||
{
|
||||
this.rect = rect;
|
||||
this.alignment = alignment;
|
||||
|
||||
if (color!=null) this.color = (Color)color;
|
||||
|
||||
if (parent != null)
|
||||
parent.AddChild(this);
|
||||
|
||||
scrollBarHidden = true;
|
||||
|
||||
scrollBar = new GUIScrollBar(
|
||||
new Rectangle(this.rect.X + this.rect.Width-20, this.rect.Y, 20, this.rect.Height), color, 1.0f, style);
|
||||
|
||||
frame = new GUIFrame(Rectangle.Empty, style, this);
|
||||
if (style != null) style.Apply(frame, this);
|
||||
|
||||
UpdateScrollBarSize();
|
||||
|
||||
enabled = true;
|
||||
|
||||
scrollBarEnabled = true;
|
||||
|
||||
scrollBar.BarScroll = 0.0f;
|
||||
}
|
||||
|
||||
public void Select(object selection)
|
||||
{
|
||||
foreach (GUIComponent child in children)
|
||||
{
|
||||
if (child.UserData != selection) continue;
|
||||
|
||||
selected = child;
|
||||
if (OnSelected != null) OnSelected(selected.UserData);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
|
||||
scrollBar.Update(deltaTime);
|
||||
}
|
||||
|
||||
public void Select(int childIndex)
|
||||
{
|
||||
//children[0] is the GUIFrame, ignore it
|
||||
childIndex += 1;
|
||||
|
||||
if (childIndex >= children.Count || childIndex<0) return;
|
||||
|
||||
selected = children[childIndex];
|
||||
if (OnSelected != null) OnSelected(selected.UserData);
|
||||
}
|
||||
|
||||
public void Deselect()
|
||||
{
|
||||
selected = null;
|
||||
}
|
||||
|
||||
public void UpdateScrollBarSize()
|
||||
{
|
||||
totalSize = 0;
|
||||
foreach (GUIComponent child in children)
|
||||
{
|
||||
if (child == frame) continue;
|
||||
totalSize += (scrollBar.IsHorizontal) ? child.Rect.Width : child.Rect.Height;
|
||||
totalSize += spacing;
|
||||
}
|
||||
|
||||
scrollBar.BarSize = scrollBar.IsHorizontal ?
|
||||
Math.Min((float)rect.Width / (float)totalSize, 1.0f) :
|
||||
Math.Min((float)rect.Height / (float)totalSize, 1.0f);
|
||||
|
||||
if (scrollBar.BarSize < 1.0f && scrollBarHidden) ShowScrollBar();
|
||||
if (scrollBar.BarSize >= 1.0f && !scrollBarHidden) HideScrollBar();
|
||||
}
|
||||
|
||||
public override void AddChild(GUIComponent child)
|
||||
{
|
||||
base.AddChild(child);
|
||||
|
||||
//float oldScroll = scrollBar.BarScroll;
|
||||
//float oldSize = scrollBar.BarSize;
|
||||
UpdateScrollBarSize();
|
||||
|
||||
//if (oldSize == 1.0f && scrollBar.BarScroll == 0.0f) scrollBar.BarScroll = 1.0f;
|
||||
|
||||
//if (scrollBar.BarSize < 1.0f && oldScroll == 1.0f)
|
||||
//{
|
||||
// scrollBar.BarScroll = 1.0f;
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
public override void ClearChildren()
|
||||
{
|
||||
base.ClearChildren();
|
||||
selected = null;
|
||||
}
|
||||
|
||||
public override void RemoveChild(GUIComponent child)
|
||||
{
|
||||
base.RemoveChild(child);
|
||||
|
||||
if (selected == child) selected = null;
|
||||
|
||||
UpdateScrollBarSize();
|
||||
}
|
||||
|
||||
private void ShowScrollBar()
|
||||
{
|
||||
if (scrollBarHidden) Rect = new Rectangle(rect.X, rect.Y, rect.Width - scrollBar.Rect.Width, rect.Height);
|
||||
scrollBarHidden = false;
|
||||
|
||||
}
|
||||
|
||||
private void HideScrollBar()
|
||||
{
|
||||
if (!scrollBarHidden) Rect = new Rectangle(rect.X, rect.Y, rect.Width + scrollBar.Rect.Width, rect.Height);
|
||||
scrollBarHidden = true;
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
base.Draw(spriteBatch);
|
||||
|
||||
frame.Draw(spriteBatch);
|
||||
//GUI.DrawRectangle(spriteBatch, rect, color*alpha, true);
|
||||
|
||||
int x = rect.X, y = rect.Y;
|
||||
|
||||
if (!scrollBarHidden)
|
||||
{
|
||||
scrollBar.Draw(spriteBatch);
|
||||
if (scrollBar.IsHorizontal)
|
||||
{
|
||||
x -= (int)((totalSize - rect.Height) * scrollBar.BarScroll);
|
||||
}
|
||||
else
|
||||
{
|
||||
y -= (int)((totalSize - rect.Height) * scrollBar.BarScroll);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < children.Count; i++ )
|
||||
{
|
||||
GUIComponent child = children[i];
|
||||
if (child == frame) continue;
|
||||
|
||||
child.Rect = new Rectangle(child.Rect.X, y, child.Rect.Width, child.Rect.Height);
|
||||
y += child.Rect.Height + spacing;
|
||||
|
||||
if (child.Rect.Y + child.Rect.Height < rect.Y) continue;
|
||||
if (child.Rect.Y + child.Rect.Height > rect.Y + rect.Height) break;
|
||||
|
||||
if (child.Rect.Y < rect.Y && child.Rect.Y + child.Rect.Height >= rect.Y)
|
||||
{
|
||||
y = rect.Y;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (selected == child)
|
||||
{
|
||||
child.State = ComponentState.Selected;
|
||||
|
||||
if (CheckSelected != null)
|
||||
{
|
||||
if (CheckSelected() != selected.UserData) selected = null;
|
||||
}
|
||||
}
|
||||
else if (enabled && (MouseOn == this || (MouseOn != null && this.IsParentOf(MouseOn))) && child.Rect.Contains(PlayerInput.GetMouseState.Position))
|
||||
{
|
||||
child.State = ComponentState.Hover;
|
||||
if (PlayerInput.LeftButtonClicked())
|
||||
{
|
||||
Debug.WriteLine("clicked");
|
||||
selected = child;
|
||||
if (OnSelected != null)
|
||||
{
|
||||
if (!OnSelected(child.UserData)) selected = null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
child.State = ComponentState.None;
|
||||
}
|
||||
|
||||
child.Draw(spriteBatch);
|
||||
}
|
||||
|
||||
//GUI.DrawRectangle(spriteBatch, rect, Color.Black, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
56
Subsurface/Source/GUI/GUIMessage.cs
Normal file
56
Subsurface/Source/GUI/GUIMessage.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
class GUIMessage
|
||||
{
|
||||
ColoredText coloredText;
|
||||
Vector2 pos;
|
||||
|
||||
float lifeTime;
|
||||
|
||||
Vector2 size;
|
||||
|
||||
|
||||
public string Text
|
||||
{
|
||||
get { return coloredText.text; }
|
||||
}
|
||||
|
||||
public Color Color
|
||||
{
|
||||
get { return coloredText.color; }
|
||||
}
|
||||
|
||||
public Vector2 Pos
|
||||
{
|
||||
get { return pos; }
|
||||
set { pos = value; }
|
||||
}
|
||||
|
||||
public Vector2 Size
|
||||
{
|
||||
get { return size; }
|
||||
}
|
||||
|
||||
|
||||
public float LifeTime
|
||||
{
|
||||
get { return lifeTime; }
|
||||
set { lifeTime = value; }
|
||||
}
|
||||
|
||||
public GUIMessage(string text, Color color, Vector2 position, float lifeTime)
|
||||
{
|
||||
coloredText = new ColoredText(text, color);
|
||||
pos = position;
|
||||
this.lifeTime = lifeTime;
|
||||
|
||||
size = GUI.Font.MeasureString(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
65
Subsurface/Source/GUI/GUIMessageBox.cs
Normal file
65
Subsurface/Source/GUI/GUIMessageBox.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
class GUIMessageBox : GUIFrame
|
||||
{
|
||||
public static Queue<GUIMessageBox> messageBoxes = new Queue<GUIMessageBox>();
|
||||
|
||||
const int DefaultWidth=400, DefaultHeight=200;
|
||||
|
||||
//public delegate bool OnClickedHandler(GUIButton button, object obj);
|
||||
//public OnClickedHandler OnClicked;
|
||||
|
||||
//GUIFrame frame;
|
||||
public GUIButton[] Buttons;
|
||||
|
||||
public GUIMessageBox(string header, string text)
|
||||
: this(header, text, new string[] {"OK"})
|
||||
{
|
||||
this.Buttons[0].OnClicked = Close;
|
||||
}
|
||||
|
||||
public GUIMessageBox(string header, string text, int width, int height)
|
||||
: this(header, text, new string[] { "OK" }, width, height)
|
||||
{
|
||||
this.Buttons[0].OnClicked = Close;
|
||||
}
|
||||
|
||||
public GUIMessageBox(string header, string text, string[] buttons, int width=DefaultWidth, int height=DefaultHeight, Alignment textAlignment = Alignment.TopLeft)
|
||||
: base(new Rectangle(0,0, width, height),
|
||||
null, Alignment.Center, GUI.style, null)
|
||||
{
|
||||
//Padding = GUI.style.smallPadding;
|
||||
|
||||
//if (buttons == null || buttons.Length == 0)
|
||||
//{
|
||||
// DebugConsole.ThrowError("Creating a message box with no buttons isn't allowed");
|
||||
// return;
|
||||
//}
|
||||
|
||||
new GUITextBlock(new Rectangle(0, 0, 0, 30), header, Color.Transparent, Color.White, textAlignment, GUI.style, this, true);
|
||||
new GUITextBlock(new Rectangle(0, 30, 0, height - 70), text, Color.Transparent, Color.White, textAlignment, GUI.style, this, true);
|
||||
|
||||
int x = 0;
|
||||
this.Buttons = new GUIButton[buttons.Length];
|
||||
for (int i = 0; i < buttons.Length; i++)
|
||||
{
|
||||
this.Buttons[i] = new GUIButton(new Rectangle(x, 0, 150, 30), buttons[i], Alignment.Left | Alignment.Bottom, GUI.style, this);
|
||||
|
||||
x += this.Buttons[i].Rect.Width + 20;
|
||||
}
|
||||
|
||||
messageBoxes.Enqueue(this);
|
||||
}
|
||||
|
||||
public bool Close(GUIButton button, object obj)
|
||||
{
|
||||
if (parent != null) parent.RemoveChild(this);
|
||||
|
||||
messageBoxes.Dequeue();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
78
Subsurface/Source/GUI/GUIProgressBar.cs
Normal file
78
Subsurface/Source/GUI/GUIProgressBar.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
class GUIProgressBar : GUIComponent
|
||||
{
|
||||
private bool isHorizontal;
|
||||
|
||||
private GUIFrame frame;
|
||||
private float barSize;
|
||||
|
||||
private int margin;
|
||||
|
||||
public delegate float ProgressGetterHandler();
|
||||
public ProgressGetterHandler ProgressGetter;
|
||||
|
||||
public bool IsHorizontal
|
||||
{
|
||||
get { return isHorizontal; }
|
||||
}
|
||||
|
||||
public float BarSize
|
||||
{
|
||||
get { return barSize; }
|
||||
set
|
||||
{
|
||||
float oldBarSize = barSize;
|
||||
barSize = MathHelper.Clamp(value, 0.0f, 1.0f);
|
||||
if (barSize!=oldBarSize) UpdateRect();
|
||||
}
|
||||
}
|
||||
|
||||
public GUIProgressBar(Rectangle rect, Color color, float barSize, GUIComponent parent = null)
|
||||
: this(rect,color,barSize, (Alignment.Left | Alignment.Top), parent)
|
||||
{
|
||||
}
|
||||
|
||||
public GUIProgressBar(Rectangle rect, Color color, float barSize, Alignment alignment, GUIComponent parent = null)
|
||||
: base(null)
|
||||
{
|
||||
this.rect = rect;
|
||||
this.color = color;
|
||||
isHorizontal = (rect.Width > rect.Height);
|
||||
|
||||
this.alignment = alignment;
|
||||
|
||||
margin = 5;
|
||||
|
||||
if (parent != null)
|
||||
parent.AddChild(this);
|
||||
|
||||
frame = new GUIFrame(new Rectangle(0,0,0,0), Color.White, null, this);
|
||||
|
||||
this.barSize = barSize;
|
||||
UpdateRect();
|
||||
}
|
||||
|
||||
private void UpdateRect()
|
||||
{
|
||||
rect = new Rectangle(
|
||||
frame.Rect.X + margin,
|
||||
frame.Rect.Y + margin,
|
||||
isHorizontal ? (int)((frame.Rect.Width - margin * 2) * barSize) : (frame.Rect.Width - margin * 2),
|
||||
isHorizontal ? (frame.Rect.Height - margin * 2) : (int)((frame.Rect.Height - margin * 2) * barSize));
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
if (ProgressGetter != null) BarSize = ProgressGetter();
|
||||
|
||||
DrawChildren(spriteBatch);
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, rect, color * (color.A / 255.0f), true);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
178
Subsurface/Source/GUI/GUIScrollBar.cs
Normal file
178
Subsurface/Source/GUI/GUIScrollBar.cs
Normal file
@@ -0,0 +1,178 @@
|
||||
using System;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
class GUIScrollBar : GUIComponent
|
||||
{
|
||||
public static GUIScrollBar draggingBar;
|
||||
|
||||
private bool isHorizontal;
|
||||
|
||||
private GUIFrame frame;
|
||||
private GUIButton bar;
|
||||
private float barSize;
|
||||
private float barScroll;
|
||||
|
||||
private bool enabled;
|
||||
|
||||
public delegate bool OnMovedHandler(object obj);
|
||||
public OnMovedHandler OnMoved;
|
||||
|
||||
public bool IsHorizontal
|
||||
{
|
||||
get { return isHorizontal; }
|
||||
}
|
||||
|
||||
public bool Enabled
|
||||
{
|
||||
get { return enabled; }
|
||||
set { enabled = value; }
|
||||
}
|
||||
|
||||
public float BarScroll
|
||||
{
|
||||
get { return barScroll; }
|
||||
set
|
||||
{
|
||||
barScroll = MathHelper.Clamp(value, 0.0f, 1.0f);
|
||||
int newX = bar.Rect.X - frame.Rect.X, newY = bar.Rect.Y - frame.Rect.Y;
|
||||
if (isHorizontal)
|
||||
{
|
||||
newX = (int)(barScroll *(frame.Rect.Width - bar.Rect.Width));
|
||||
newX = Math.Max(newX, 0);
|
||||
newX = Math.Min(newX, frame.Rect.Width - bar.Rect.Width);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
newY = (int)(barScroll * (frame.Rect.Height- bar.Rect.Height));
|
||||
newY = Math.Max(newY, 0);
|
||||
newY = Math.Min(newY, frame.Rect.Height - bar.Rect.Height);
|
||||
|
||||
}
|
||||
bar.Rect = new Rectangle(newX + frame.Rect.X, newY + frame.Rect.Y, bar.Rect.Width, bar.Rect.Height);
|
||||
}
|
||||
}
|
||||
|
||||
public float BarSize
|
||||
{
|
||||
get { return barSize; }
|
||||
set
|
||||
{
|
||||
float oldBarSize = barSize;
|
||||
barSize = Math.Min(Math.Max(value, 0.0f), 1.0f);
|
||||
if (barSize != oldBarSize) UpdateRect();
|
||||
}
|
||||
}
|
||||
|
||||
public GUIScrollBar(Rectangle rect, GUIStyle style, float barSize, GUIComponent parent = null)
|
||||
: this(rect, null, barSize, style, parent)
|
||||
{
|
||||
}
|
||||
|
||||
public GUIScrollBar(Rectangle rect, Color? color, float barSize, GUIStyle style = null, GUIComponent parent = null)
|
||||
: this(rect, color, barSize, Alignment.TopLeft, style, parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public GUIScrollBar(Rectangle rect, Color? color, float barSize, Alignment alignment, GUIStyle style = null, GUIComponent parent = null)
|
||||
: base(style)
|
||||
{
|
||||
this.rect = rect;
|
||||
//GetDimensions(parent);
|
||||
|
||||
this.alignment = alignment;
|
||||
|
||||
if (parent != null)
|
||||
parent.AddChild(this);
|
||||
|
||||
isHorizontal = (rect.Width > rect.Height);
|
||||
frame = new GUIFrame(new Rectangle(0,0,0,0), Color.White, style, this);
|
||||
//AddChild(frame);
|
||||
|
||||
//System.Diagnostics.Debug.WriteLine(frame.rect);
|
||||
|
||||
bar = new GUIButton(new Rectangle(0, 0, 0, 0), "", color, style, this);
|
||||
|
||||
bar.OnPressed = SelectBar;
|
||||
//AddChild(bar);
|
||||
|
||||
enabled = true;
|
||||
|
||||
UpdateRect();
|
||||
}
|
||||
|
||||
private void UpdateRect()
|
||||
{
|
||||
|
||||
bar.Rect = new Rectangle(
|
||||
bar.Rect.X,
|
||||
bar.Rect.Y,
|
||||
isHorizontal ? (int)(frame.Rect.Width * barSize) : frame.Rect.Width,
|
||||
isHorizontal ? frame.Rect.Height : (int)(frame.Rect.Height * barSize));
|
||||
|
||||
foreach (GUIComponent child in bar.children)
|
||||
{
|
||||
child.Rect = bar.Rect;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
|
||||
if (draggingBar != this) return;
|
||||
if (!PlayerInput.LeftButtonDown()) draggingBar = null;
|
||||
|
||||
MoveButton();
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
DrawChildren(spriteBatch);
|
||||
}
|
||||
|
||||
private bool SelectBar()
|
||||
{
|
||||
if (!enabled) return false;
|
||||
if (barSize == 1.0f) return false;
|
||||
|
||||
draggingBar = this;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
private void MoveButton()
|
||||
{
|
||||
//if (!enabled) return false;
|
||||
//if (barSize == 1.0f) return false;
|
||||
|
||||
int newX = bar.Rect.X - frame.Rect.X, newY = bar.Rect.Y - frame.Rect.Y;
|
||||
int moveAmount;
|
||||
if (isHorizontal)
|
||||
{
|
||||
moveAmount = PlayerInput.GetMouseState.Position.X - PlayerInput.GetOldMouseState.Position.X;
|
||||
newX = Math.Min(Math.Max(newX + moveAmount, 0), frame.Rect.Width - bar.Rect.Width);
|
||||
|
||||
barScroll = (float)newX / ((float)frame.Rect.Width - (float)bar.Rect.Width);
|
||||
}
|
||||
else
|
||||
{
|
||||
moveAmount = PlayerInput.GetMouseState.Position.Y - PlayerInput.GetOldMouseState.Position.Y;
|
||||
newY = Math.Min(Math.Max(newY+moveAmount, 0), frame.Rect.Height - bar.Rect.Height);
|
||||
|
||||
barScroll = (float)newY / ((float)frame.Rect.Height - (float)bar.Rect.Height);
|
||||
}
|
||||
|
||||
if (moveAmount != 0 && OnMoved != null) OnMoved(moveAmount);
|
||||
|
||||
bar.Rect = new Rectangle(newX + frame.Rect.X, newY + frame.Rect.Y, bar.Rect.Width, bar.Rect.Height);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
67
Subsurface/Source/GUI/GUIStyle.cs
Normal file
67
Subsurface/Source/GUI/GUIStyle.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
class GUIStyle
|
||||
{
|
||||
private Dictionary<string, GUIComponentStyle> componentStyles;
|
||||
|
||||
public GUIStyle(string file)
|
||||
{
|
||||
|
||||
componentStyles = new Dictionary<string, GUIComponentStyle>();
|
||||
|
||||
XDocument doc;
|
||||
try { doc = XDocument.Load(file); }
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Loading style ''" + file + "'' failed", e);
|
||||
return;
|
||||
}
|
||||
|
||||
//smallPadding = ToolBox.GetAttributeVector4(doc.Root, "smallpadding", Vector4.Zero);
|
||||
//largePadding = ToolBox.GetAttributeVector4(doc.Root, "largepadding", Vector4.Zero);
|
||||
|
||||
//Vector4 colorVector = ToolBox.GetAttributeVector4(doc.Root, "backgroundcolor", new Vector4(0.0f,0.0f,0.0f,1.0f));
|
||||
//backGroundColor = new Color(colorVector.X, colorVector.Y, colorVector.Z, colorVector.W);
|
||||
|
||||
//colorVector = ToolBox.GetAttributeVector4(doc.Root, "foregroundcolor", new Vector4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
//foreGroundColor = new Color(colorVector.X, colorVector.Y, colorVector.Z, colorVector.W);
|
||||
|
||||
//colorVector = ToolBox.GetAttributeVector4(doc.Root, "textcolor", new Vector4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
//textColor = new Color(colorVector.X, colorVector.Y, colorVector.Z, colorVector.W);
|
||||
|
||||
//colorVector = ToolBox.GetAttributeVector4(doc.Root, "hovercolor", new Vector4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
//hoverColor = new Color(colorVector.X, colorVector.Y, colorVector.Z, colorVector.W);
|
||||
|
||||
//colorVector = ToolBox.GetAttributeVector4(doc.Root, "selectedcolor", new Vector4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
//selectedColor = new Color(colorVector.X, colorVector.Y, colorVector.Z, colorVector.W);
|
||||
|
||||
foreach (XElement subElement in doc.Root.Elements())
|
||||
{
|
||||
GUIComponentStyle componentStyle = new GUIComponentStyle(subElement);
|
||||
componentStyles.Add(subElement.Name.ToString().ToLower(), componentStyle);
|
||||
}
|
||||
}
|
||||
|
||||
public void Apply(GUIComponent targetComponent, GUIComponent parent = null)
|
||||
{
|
||||
GUIComponentStyle componentStyle = null;
|
||||
string name = (parent==null) ? targetComponent.GetType().Name.ToLower() : parent.GetType().Name.ToLower();
|
||||
componentStyles.TryGetValue(name, out componentStyle);
|
||||
|
||||
if (componentStyle==null)
|
||||
{
|
||||
DebugConsole.ThrowError("Couldn't find a GUI style for "+targetComponent.GetType().Name);
|
||||
return;
|
||||
}
|
||||
|
||||
targetComponent.ApplyStyle(componentStyle);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
228
Subsurface/Source/GUI/GUITextBlock.cs
Normal file
228
Subsurface/Source/GUI/GUITextBlock.cs
Normal file
@@ -0,0 +1,228 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
class GUITextBlock : GUIComponent
|
||||
{
|
||||
protected string text;
|
||||
|
||||
protected Alignment textAlignment;
|
||||
|
||||
protected Vector2 textPos;
|
||||
protected Vector2 origin;
|
||||
|
||||
protected Vector2 caretPos;
|
||||
|
||||
protected Color textColor;
|
||||
|
||||
public delegate string TextGetterHandler();
|
||||
public TextGetterHandler TextGetter;
|
||||
|
||||
public bool Wrap;
|
||||
|
||||
|
||||
|
||||
public override Vector4 Padding
|
||||
{
|
||||
get { return padding; }
|
||||
set
|
||||
{
|
||||
padding = value;
|
||||
SetTextPos();
|
||||
}
|
||||
}
|
||||
|
||||
public string Text
|
||||
{
|
||||
get { return text; }
|
||||
set
|
||||
{
|
||||
text = value;
|
||||
SetTextPos();
|
||||
}
|
||||
}
|
||||
|
||||
public bool LimitText
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public Vector2 TextPos
|
||||
{
|
||||
get { return textPos; }
|
||||
}
|
||||
|
||||
public Vector2 Origin
|
||||
{
|
||||
get { return origin; }
|
||||
}
|
||||
|
||||
public Color TextColor
|
||||
{
|
||||
get { return textColor; }
|
||||
set { textColor = value; }
|
||||
}
|
||||
|
||||
public Vector2 CaretPos
|
||||
{
|
||||
get { return caretPos; }
|
||||
}
|
||||
|
||||
public GUITextBlock(Rectangle rect, string text, GUIStyle style, GUIComponent parent = null, bool wrap = false)
|
||||
: this(rect, text, style, Alignment.TopLeft, Alignment.TopLeft, parent, wrap)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public GUITextBlock(Rectangle rect, string text, GUIStyle style, Alignment alignment = Alignment.TopLeft, Alignment textAlignment = Alignment.TopLeft, GUIComponent parent = null, bool wrap = false)
|
||||
: this (rect, text, null, null, alignment, textAlignment, style, parent, wrap)
|
||||
{
|
||||
}
|
||||
|
||||
public GUITextBlock(Rectangle rect, string text, Color? color, Color? textColor, Alignment textAlignment = Alignment.Left, GUIStyle style = null, GUIComponent parent = null, bool wrap = false)
|
||||
: this(rect, text,color, textColor, Alignment.TopLeft, textAlignment, style, parent, wrap)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void UpdateDimensions(GUIComponent parent)
|
||||
{
|
||||
base.UpdateDimensions(parent);
|
||||
|
||||
SetTextPos();
|
||||
}
|
||||
|
||||
public override void ApplyStyle(GUIComponentStyle style)
|
||||
{
|
||||
base.ApplyStyle(style);
|
||||
|
||||
textColor = style.textColor;
|
||||
}
|
||||
|
||||
|
||||
public GUITextBlock(Rectangle rect, string text, Color? color, Color? textColor, Alignment alignment, Alignment textAlignment = Alignment.Left, GUIStyle style = null, GUIComponent parent = null, bool wrap = false)
|
||||
:base (style)
|
||||
{
|
||||
this.rect = rect;
|
||||
|
||||
if (color!=null) this.color = (Color)color;
|
||||
if (textColor!=null) this.textColor = (Color)textColor;
|
||||
this.text = text;
|
||||
|
||||
this.alignment = alignment;
|
||||
|
||||
this.textAlignment = textAlignment;
|
||||
|
||||
if (parent != null)
|
||||
parent.AddChild(this);
|
||||
|
||||
//if (wrap)
|
||||
//{
|
||||
this.Wrap = wrap;
|
||||
// this.text = ToolBox.WrapText(this.text, rect.Width);
|
||||
//}
|
||||
|
||||
SetTextPos();
|
||||
}
|
||||
|
||||
private void SetTextPos()
|
||||
{
|
||||
if (text==null) return;
|
||||
|
||||
Vector2 size = MeasureText(text);
|
||||
|
||||
if (Wrap && rect.Width>0)
|
||||
{
|
||||
//text = text.Replace("\n"," ");
|
||||
text = ToolBox.WrapText(text, rect.Width, Font);
|
||||
|
||||
Vector2 newSize = MeasureText(text);
|
||||
|
||||
//Rectangle newRect = rect;
|
||||
|
||||
//newRect.Width += (int)(newSize.X-size.X);
|
||||
//newRect.Height += (int)(newSize.Y - size.Y);
|
||||
|
||||
//Rect = newRect;
|
||||
size = newSize;
|
||||
}
|
||||
|
||||
if (LimitText && text.Length>1 && size.Y > rect.Height)
|
||||
{
|
||||
string[] lines = text.Split('\n');
|
||||
text = string.Join("\n", lines, 0, lines.Length-1);
|
||||
}
|
||||
|
||||
textPos = new Vector2(rect.Width / 2.0f, rect.Height / 2.0f);
|
||||
origin = size * 0.5f;
|
||||
|
||||
if (textAlignment.HasFlag(Alignment.Left))
|
||||
origin.X += (rect.Width / 2.0f - padding.X) - size.X / 2;
|
||||
|
||||
if (textAlignment.HasFlag(Alignment.Right))
|
||||
origin.X -= (rect.Width / 2.0f - padding.Z) - size.X / 2;
|
||||
|
||||
if (textAlignment.HasFlag(Alignment.Top))
|
||||
origin.Y += (rect.Height / 2.0f - padding.Y) - size.Y / 2;
|
||||
|
||||
if (textAlignment.HasFlag(Alignment.Bottom))
|
||||
origin.Y -= (rect.Height / 2.0f - padding.W) - size.Y / 2;
|
||||
|
||||
origin.X = (int)origin.X;
|
||||
origin.Y = (int)origin.Y;
|
||||
|
||||
textPos.X = (int)textPos.X;
|
||||
textPos.Y = (int)textPos.Y;
|
||||
|
||||
if (text.Contains("\n"))
|
||||
{
|
||||
string[] lines = text.Split('\n');
|
||||
Vector2 lastLineSize = MeasureText(lines[lines.Length-1]);
|
||||
caretPos = new Vector2(rect.X + lastLineSize.X, rect.Y + size.Y - lastLineSize.Y) + textPos - origin;
|
||||
}
|
||||
else
|
||||
{
|
||||
caretPos = new Vector2(rect.X + size.X, rect.Y) + textPos - origin;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Vector2 MeasureText(string text)
|
||||
{
|
||||
Vector2 size = Vector2.Zero;
|
||||
while (size == Vector2.Zero)
|
||||
{
|
||||
try { size = Font.MeasureString((text == "") ? " " : text); }
|
||||
catch { text = text.Substring(0, text.Length - 1); }
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
Color currColor = color;
|
||||
if (state == ComponentState.Hover) currColor = hoverColor;
|
||||
if (state == ComponentState.Selected) currColor = selectedColor;
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, rect, currColor*(currColor.A/255.0f), true);
|
||||
|
||||
base.Draw(spriteBatch);
|
||||
|
||||
if (TextGetter != null) text = TextGetter();
|
||||
|
||||
if (!string.IsNullOrEmpty(text))
|
||||
{
|
||||
spriteBatch.DrawString(Font,
|
||||
text,
|
||||
new Vector2(rect.X, rect.Y) + textPos,
|
||||
textColor * (textColor.A / 255.0f),
|
||||
0.0f, origin, 1.0f,
|
||||
SpriteEffects.None, 0.0f);
|
||||
}
|
||||
|
||||
DrawChildren(spriteBatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
245
Subsurface/Source/GUI/GUITextBox.cs
Normal file
245
Subsurface/Source/GUI/GUITextBox.cs
Normal file
@@ -0,0 +1,245 @@
|
||||
using System;
|
||||
using EventInput;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
|
||||
delegate void TextBoxEvent(GUITextBox sender);
|
||||
|
||||
class GUITextBox : GUIComponent, IKeyboardSubscriber
|
||||
{
|
||||
public event TextBoxEvent Clicked;
|
||||
|
||||
bool caretVisible;
|
||||
float caretTimer;
|
||||
|
||||
GUITextBlock textBlock;
|
||||
|
||||
public delegate bool OnEnterHandler(GUITextBox textBox, string text);
|
||||
public OnEnterHandler OnEnter;
|
||||
|
||||
public delegate bool OnTextChangedHandler(GUITextBox textBox, string text);
|
||||
public OnTextChangedHandler OnTextChanged;
|
||||
|
||||
public GUITextBlock.TextGetterHandler TextGetter
|
||||
{
|
||||
get { return textBlock.TextGetter; }
|
||||
set { textBlock.TextGetter = value; }
|
||||
}
|
||||
|
||||
public bool Wrap
|
||||
{
|
||||
get { return textBlock.Wrap; }
|
||||
set { textBlock.Wrap = value; }
|
||||
}
|
||||
|
||||
public bool LimitText
|
||||
{
|
||||
get { return textBlock.LimitText; }
|
||||
set { textBlock.LimitText = value; }
|
||||
}
|
||||
|
||||
public bool Enabled
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public override SpriteFont Font
|
||||
{
|
||||
set
|
||||
{
|
||||
base.Font = value;
|
||||
if (textBlock == null) return;
|
||||
textBlock.Font = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override Color Color
|
||||
{
|
||||
get { return color; }
|
||||
set
|
||||
{
|
||||
color = value;
|
||||
textBlock.Color = color;
|
||||
}
|
||||
}
|
||||
|
||||
public String Text
|
||||
{
|
||||
get
|
||||
{
|
||||
return textBlock.Text;
|
||||
}
|
||||
set
|
||||
{
|
||||
textBlock.Text = value;
|
||||
if (textBlock.Text == null) textBlock.Text = "";
|
||||
|
||||
if (textBlock.Text != "")
|
||||
{
|
||||
//if you attempt to display a character that is not in your font
|
||||
//you will get an exception, so we filter the characters
|
||||
//remove the filtering if you're using a default character in your spritefont
|
||||
String filtered = "";
|
||||
foreach (char c in value)
|
||||
{
|
||||
if (Font.Characters.Contains(c)) filtered += c;
|
||||
}
|
||||
|
||||
textBlock.Text = filtered;
|
||||
|
||||
if (!Wrap && Font.MeasureString(textBlock.Text).X > rect.Width)
|
||||
{
|
||||
//ensure that text cannot be larger than the box
|
||||
Text = textBlock.Text.Substring(0, textBlock.Text.Length - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public GUITextBox(Rectangle rect, GUIStyle style = null, GUIComponent parent = null)
|
||||
: this(rect, null, null, Alignment.Left, Alignment.Left, style, parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public GUITextBox(Rectangle rect, Alignment alignment = Alignment.Left, GUIStyle style = null, GUIComponent parent = null)
|
||||
: this(rect, null, null, alignment, Alignment.Left, style, parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public GUITextBox(Rectangle rect, Color? color, Color? textColor, Alignment alignment, Alignment textAlignment = Alignment.Left, GUIStyle style = null, GUIComponent parent = null)
|
||||
: base(style)
|
||||
{
|
||||
Enabled = true;
|
||||
|
||||
this.rect = rect;
|
||||
|
||||
if (color != null) this.color = (Color)color;
|
||||
|
||||
this.alignment = alignment;
|
||||
|
||||
//this.textAlignment = textAlignment;
|
||||
|
||||
if (parent != null)
|
||||
parent.AddChild(this);
|
||||
|
||||
textBlock = new GUITextBlock(new Rectangle(0,0,0,0), "", color, textColor, textAlignment, style, this);
|
||||
textBlock.Padding = new Vector4(10.0f, 0.0f, 10.0f, 0.0f);
|
||||
if (style != null) style.Apply(textBlock, this);
|
||||
|
||||
previousMouse = PlayerInput.GetMouseState;
|
||||
//SetTextPos();
|
||||
}
|
||||
|
||||
public void Select()
|
||||
{
|
||||
Selected = true;
|
||||
keyboardDispatcher.Subscriber = this;
|
||||
if (Clicked != null) Clicked(this);
|
||||
}
|
||||
|
||||
public void Deselect()
|
||||
{
|
||||
if (keyboardDispatcher.Subscriber == this) keyboardDispatcher.Subscriber = null;
|
||||
}
|
||||
|
||||
MouseState previousMouse;
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
if (!Enabled) return;
|
||||
|
||||
caretTimer += deltaTime;
|
||||
caretVisible = ((caretTimer*1000.0f) % 1000) < 500;
|
||||
|
||||
if (rect.Contains(PlayerInput.GetMouseState.Position))
|
||||
{
|
||||
state = ComponentState.Hover;
|
||||
if (PlayerInput.LeftButtonClicked()) Select();
|
||||
}
|
||||
else
|
||||
{
|
||||
state = ComponentState.None;
|
||||
}
|
||||
|
||||
if (keyboardDispatcher.Subscriber == this)
|
||||
{
|
||||
Character.DisableControls = true;
|
||||
if (OnEnter != null && PlayerInput.KeyHit(Keys.Enter))
|
||||
{
|
||||
string input = Text;
|
||||
Text = "";
|
||||
OnEnter(this, input);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
DrawChildren(spriteBatch);
|
||||
|
||||
Vector2 caretPos = textBlock.CaretPos;
|
||||
|
||||
if (caretVisible && Selected)
|
||||
{
|
||||
GUI.DrawLine(spriteBatch,
|
||||
new Vector2((int)caretPos.X + 2, caretPos.Y + 3),
|
||||
new Vector2((int)caretPos.X + 2, caretPos.Y + Font.MeasureString("I").Y - 3),
|
||||
textBlock.TextColor * (textBlock.TextColor.A / 255.0f));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void ReceiveTextInput(char inputChar)
|
||||
{
|
||||
Text = Text + inputChar;
|
||||
|
||||
if (OnTextChanged!=null) OnTextChanged(this, Text);
|
||||
}
|
||||
public void ReceiveTextInput(string text)
|
||||
{
|
||||
Text = Text + text;
|
||||
|
||||
if (OnTextChanged != null) OnTextChanged(this, Text);
|
||||
}
|
||||
public void ReceiveCommandInput(char command)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case '\b': //backspace
|
||||
if (Text.Length > 0)
|
||||
Text = Text.Substring(0, Text.Length - 1);
|
||||
break;
|
||||
case '\r': //return
|
||||
if (OnEnterPressed != null)
|
||||
OnEnterPressed(this);
|
||||
break;
|
||||
case '\t': //tab
|
||||
if (OnTabPressed != null)
|
||||
OnTabPressed(this);
|
||||
break;
|
||||
}
|
||||
|
||||
if (OnTextChanged != null) OnTextChanged(this, Text);
|
||||
}
|
||||
|
||||
public void ReceiveSpecialInput(Keys key)
|
||||
{
|
||||
}
|
||||
|
||||
public event TextBoxEvent OnEnterPressed;
|
||||
public event TextBoxEvent OnTabPressed;
|
||||
|
||||
public bool Selected
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
}
|
||||
}
|
||||
78
Subsurface/Source/GUI/GUITickBox.cs
Normal file
78
Subsurface/Source/GUI/GUITickBox.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
class GUITickBox : GUIComponent
|
||||
{
|
||||
GUIFrame box;
|
||||
GUITextBlock text;
|
||||
|
||||
public delegate bool OnSelectedHandler(object obj);
|
||||
public OnSelectedHandler OnSelected;
|
||||
|
||||
private bool selected;
|
||||
|
||||
public bool Selected
|
||||
{
|
||||
get { return selected; }
|
||||
set
|
||||
{
|
||||
if (value == selected) return;
|
||||
selected = value;
|
||||
state = (selected) ? ComponentState.Selected : ComponentState.None;
|
||||
}
|
||||
}
|
||||
|
||||
public GUITickBox(Rectangle rect, string label, Alignment alignment, GUIComponent parent)
|
||||
: base(null)
|
||||
{
|
||||
if (parent != null)
|
||||
parent.AddChild(this);
|
||||
|
||||
box = new GUIFrame(rect, Color.DarkGray, null, this);
|
||||
box.HoverColor = Color.Gray;
|
||||
box.SelectedColor = Color.DarkGray;
|
||||
|
||||
text = new GUITextBlock(new Rectangle(rect.X + 40, rect.Y, 200, 30), label, Color.Transparent, Color.White, Alignment.TopLeft, null, this);
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
|
||||
if (box.Rect.Contains(PlayerInput.GetMouseState.Position))
|
||||
{
|
||||
box.State = ComponentState.Hover;
|
||||
|
||||
if (PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed)
|
||||
{
|
||||
box.State = ComponentState.Selected;
|
||||
}
|
||||
|
||||
|
||||
if (PlayerInput.LeftButtonClicked())
|
||||
{
|
||||
Selected = !Selected;
|
||||
if (OnSelected != null) OnSelected(this);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
box.State = ComponentState.None;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
DrawChildren(spriteBatch);
|
||||
|
||||
if (Selected)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(box.Rect.X + 2, box.Rect.Y + 2, box.Rect.Width - 4, box.Rect.Height - 4), Color.Green * 0.8f, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
101
Subsurface/Source/GUI/TitleScreen.cs
Normal file
101
Subsurface/Source/GUI/TitleScreen.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
class TitleScreen
|
||||
{
|
||||
private Texture2D backgroundTexture,monsterTexture,titleTexture;
|
||||
|
||||
readonly RenderTarget2D renderTarget;
|
||||
|
||||
float state;
|
||||
|
||||
public Vector2 Position;
|
||||
|
||||
public TitleScreen(GraphicsDevice graphics)
|
||||
{
|
||||
backgroundTexture = Game1.TextureLoader.FromFile("Content/UI/titleBackground.png");
|
||||
monsterTexture = Game1.TextureLoader.FromFile("Content/UI/titleMonster.png");
|
||||
titleTexture = Game1.TextureLoader.FromFile("Content/UI/titleText.png");
|
||||
|
||||
renderTarget = new RenderTarget2D(graphics, Game1.GraphicsWidth, Game1.GraphicsHeight);
|
||||
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, GraphicsDevice graphics, float loadState, float deltaTime)
|
||||
{
|
||||
//if (stopwatch == null)
|
||||
//{
|
||||
// stopwatch = new Stopwatch();
|
||||
// stopwatch.Start();
|
||||
//}
|
||||
|
||||
graphics.SetRenderTarget(renderTarget);
|
||||
//Debug.WriteLine(stopwatch.Elapsed.TotalMilliseconds);
|
||||
|
||||
float scale = Game1.GraphicsHeight/2048.0f;
|
||||
|
||||
state += deltaTime;
|
||||
|
||||
Vector2 center = new Vector2(Game1.GraphicsWidth*0.3f, Game1.GraphicsHeight/2.0f) + Position*scale;
|
||||
|
||||
Vector2 titlePos = center + new Vector2(-0.0f + (float)Math.Sqrt(state) * 220.0f, 0.0f) * scale;
|
||||
titlePos.X = Math.Min(titlePos.X, (float)Game1.GraphicsWidth / 2.0f);
|
||||
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied);
|
||||
graphics.Clear(Color.Black);
|
||||
|
||||
spriteBatch.Draw(backgroundTexture, center, null, Color.White * Math.Min(state / 5.0f, 1.0f), 0.0f,
|
||||
new Vector2(backgroundTexture.Width / 2.0f, backgroundTexture.Height / 2.0f),
|
||||
scale, SpriteEffects.None, 0.2f);
|
||||
|
||||
spriteBatch.Draw(monsterTexture,
|
||||
center + new Vector2(state * 100.0f - 1200.0f, state * 30.0f - 100.0f) * scale, null,
|
||||
Color.White, 0.0f, Vector2.Zero, scale, SpriteEffects.None, 0.1f);
|
||||
|
||||
spriteBatch.Draw(titleTexture,
|
||||
titlePos, null,
|
||||
Color.White * Math.Min((state - 1.0f) / 5.0f, 1.0f), 0.0f, new Vector2(titleTexture.Width / 2.0f, titleTexture.Height / 2.0f), scale, SpriteEffects.None, 0.0f);
|
||||
|
||||
spriteBatch.End();
|
||||
|
||||
graphics.SetRenderTarget(null);
|
||||
|
||||
Matrix transform = Matrix.CreateTranslation(
|
||||
new Vector3(Game1.GraphicsWidth / 2.0f,
|
||||
Game1.GraphicsHeight / 2.0f, 0));
|
||||
|
||||
Hull.renderer.RenderBack(graphics, renderTarget, transform);
|
||||
|
||||
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied);
|
||||
|
||||
spriteBatch.Draw(titleTexture,
|
||||
titlePos, null,
|
||||
Color.White * Math.Min((state - 3.0f) / 5.0f, 1.0f), 0.0f, new Vector2(titleTexture.Width / 2.0f, titleTexture.Height / 2.0f), scale, SpriteEffects.None, 0.0f);
|
||||
|
||||
string loadText = "";
|
||||
if (loadState == 100.0f)
|
||||
{
|
||||
loadText = "Press any key to continue";
|
||||
|
||||
}
|
||||
else if (loadState > 0.0f)
|
||||
{
|
||||
loadText = "Loading... " + (int)loadState + " %";
|
||||
}
|
||||
|
||||
spriteBatch.DrawString(GUI.Font, loadText, new Vector2(Game1.GraphicsWidth/2.0f - 50.0f, Game1.GraphicsHeight*0.8f), Color.White);
|
||||
|
||||
spriteBatch.End();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user