This commit is contained in:
Regalis
2015-07-31 21:05:55 +03:00
parent 23d847a4ac
commit 85b0cda4ca
181 changed files with 4455 additions and 4073 deletions

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

View 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]);
}
}
}

View 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);
}
}
}

View 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();
}
}
}

View 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);
}
}
}

View 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);
}
}
}

View 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);
}
}
}

View 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);
}
}
}

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

View 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);
}
}
}

View 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);
}
}
}

View 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);
}
}
}

View 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);
}
}
}

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

View 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);
}
}
}
}

View 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();
}
}
}