First commit
This commit is contained in:
@@ -0,0 +1,344 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
[Flags]
|
||||
public enum Alignment { CenterX = 1, Left = 2, Right = 4, CenterY = 8, Top = 16, Bottom = 32 }
|
||||
|
||||
|
||||
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 pos, float lifeTime)
|
||||
{
|
||||
this.coloredText = new ColoredText(text, color);
|
||||
this.pos = pos;
|
||||
this.lifeTime = lifeTime;
|
||||
|
||||
this.size = GUI.font.MeasureString(text);
|
||||
}
|
||||
}
|
||||
|
||||
class GUI
|
||||
{
|
||||
public static GUIStyle style;
|
||||
|
||||
static Texture2D t;
|
||||
public static SpriteFont font;
|
||||
|
||||
private static GUIProgressBar drowningBar;
|
||||
|
||||
private static GraphicsDevice graphicsDevice;
|
||||
|
||||
|
||||
private static List<GUIMessage> messages = new List<GUIMessage>();
|
||||
|
||||
|
||||
private static Sound[] sounds;
|
||||
|
||||
|
||||
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
|
||||
|
||||
int width = 200, height = 20;
|
||||
drowningBar = new GUIProgressBar(new Rectangle(Game1.GraphicsWidth / 2 - width / 2, 20, width, height), Color.Blue, 1.0f);
|
||||
|
||||
|
||||
style = new GUIStyle("Content/HUD/style.xml");
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
spriteBatch.DrawString(font,
|
||||
"FPS: " + (int)Game1.frameCounter.AverageFramesPerSecond
|
||||
+ " - physics: " + Game1.world.UpdateTime
|
||||
+ " - bodies: " + Game1.world.BodyList.Count,
|
||||
new Vector2(10, 10), Color.White);
|
||||
|
||||
if (Character.Controlled != null)
|
||||
{
|
||||
drowningBar.BarSize = Character.Controlled.Oxygen/100.0f;
|
||||
if (drowningBar.BarSize<1.0f)
|
||||
drowningBar.Draw(spriteBatch);
|
||||
|
||||
if (Character.Controlled.Inventory!=null)
|
||||
Character.Controlled.Inventory.Draw(spriteBatch);
|
||||
}
|
||||
|
||||
DrawMessages(spriteBatch, (float)deltaTime);
|
||||
|
||||
DebugConsole.Draw(spriteBatch);
|
||||
}
|
||||
|
||||
public static void DrawCharacterHUD(SpriteBatch spriteBatch, Character character)
|
||||
{
|
||||
drowningBar.BarSize = character.Oxygen/100.0f;
|
||||
|
||||
drowningBar.Draw(spriteBatch);
|
||||
}
|
||||
|
||||
public static void AddMessage(string message, Color color, float lifeTime = 3.0f)
|
||||
{
|
||||
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));
|
||||
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 = ToolBox.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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
class GUIButton : GUIComponent
|
||||
{
|
||||
protected GUITextBlock textBlock;
|
||||
|
||||
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, Alignment alignment, GUIComponent parent = null)
|
||||
: this(rect, text, style.foreGroundColor, alignment, parent)
|
||||
{
|
||||
hoverColor = style.hoverColor;
|
||||
selectedColor = style.selectedColor;
|
||||
}
|
||||
|
||||
public GUIButton(Rectangle rect, string text, Color color, GUIComponent parent = null)
|
||||
: this(rect, text, color, (Alignment.Left | Alignment.Top), parent)
|
||||
{
|
||||
}
|
||||
|
||||
public GUIButton(Rectangle rect, string text, Color color, Alignment alignment, GUIComponent parent = null)
|
||||
{
|
||||
this.rect = rect;
|
||||
this.color = color;
|
||||
this.alignment = alignment;
|
||||
|
||||
Enabled = true;
|
||||
|
||||
if (parent != null)
|
||||
parent.AddChild(this);
|
||||
|
||||
this.textBlock = new GUITextBlock(new Rectangle(0,0,0,0), text, Color.Transparent, Color.Black, (Alignment.CenterX | Alignment.CenterY), this);
|
||||
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
if (rect.Contains(PlayerInput.GetMouseState.Position) && Enabled)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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*alpha, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
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;
|
||||
|
||||
public enum ComponentState { None, Hover, Selected};
|
||||
|
||||
protected Alignment alignment;
|
||||
|
||||
protected static KeyboardDispatcher keyboardDispatcher;
|
||||
|
||||
protected object userData;
|
||||
|
||||
protected Rectangle rect;
|
||||
|
||||
protected Vector4 padding;
|
||||
|
||||
protected Color color;
|
||||
protected Color hoverColor;
|
||||
protected Color selectedColor;
|
||||
|
||||
protected GUIComponent parent;
|
||||
public List<GUIComponent> children;
|
||||
|
||||
protected ComponentState state;
|
||||
|
||||
protected float alpha;
|
||||
|
||||
public GUIComponent Parent
|
||||
{
|
||||
get { return parent; }
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
alpha = 1.0f;
|
||||
|
||||
children = new List<GUIComponent>();
|
||||
}
|
||||
|
||||
public static void Init(GameWindow window)
|
||||
{
|
||||
keyboardDispatcher = new KeyboardDispatcher(window);
|
||||
}
|
||||
|
||||
public GUIComponent GetChild(object obj)
|
||||
{
|
||||
foreach (GUIComponent child in children)
|
||||
{
|
||||
if (child.UserData == obj) return child;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
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 virtual void Update(float deltaTime)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (parent!=null)
|
||||
{
|
||||
if (rect.Width == 0) rect.Width = parent.Rect.Width - rect.X
|
||||
- (int)parent.Padding.X - (int)parent.Padding.Z;
|
||||
|
||||
if (rect.Height == 0) rect.Height = parent.Rect.Height - rect.Y
|
||||
- (int)parent.Padding.Y - (int)parent.Padding.W;
|
||||
|
||||
if (alignment.HasFlag(Alignment.CenterX))
|
||||
{
|
||||
rect.X += parent.Rect.X + (int)parent.Rect.Width/2 - (int)rect.Width/2;
|
||||
}
|
||||
else if (alignment.HasFlag(Alignment.Right))
|
||||
{
|
||||
rect.X += parent.Rect.X + (int)parent.Rect.Width - (int)parent.Padding.Z - (int)rect.Width;
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.X += parent.Rect.X + (int)parent.Padding.X;
|
||||
}
|
||||
|
||||
if (alignment.HasFlag(Alignment.CenterY))
|
||||
{
|
||||
rect.Y += parent.Rect.Y + (int)parent.Rect.Height / 2 - (int)rect.Height / 2;
|
||||
}
|
||||
else if (alignment.HasFlag(Alignment.Bottom))
|
||||
{
|
||||
rect.Y += parent.Rect.Y + (int)parent.Rect.Height - (int)parent.Padding.W - (int)rect.Height;
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.Y += parent.Rect.Y + (int)parent.Padding.Y;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void DrawChildren(SpriteBatch spriteBatch)
|
||||
{
|
||||
foreach (GUIComponent child in children)
|
||||
{
|
||||
child.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 void ClearChildren()
|
||||
{
|
||||
children.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
class GUIFrame : GUIComponent
|
||||
{
|
||||
public GUIFrame(Rectangle rect, Color color, Alignment alignment, GUIStyle style, GUIComponent parent = null)
|
||||
: this(rect, color, alignment, parent)
|
||||
{
|
||||
hoverColor = style.hoverColor;
|
||||
selectedColor = style.selectedColor;
|
||||
}
|
||||
|
||||
public GUIFrame(Rectangle rect, Color color, GUIComponent parent = null)
|
||||
: this(rect,color,(Alignment.Left | Alignment.Top), parent)
|
||||
{
|
||||
}
|
||||
|
||||
public GUIFrame(Rectangle rect, Color color, Alignment alignment, GUIComponent parent = null)
|
||||
{
|
||||
this.rect = rect;
|
||||
|
||||
this.alignment = alignment;
|
||||
|
||||
this.color = color;
|
||||
if (parent!=null)
|
||||
parent.AddChild(this);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
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)
|
||||
{
|
||||
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 * alpha, 0.0f, Vector2.Zero,
|
||||
Scale, SpriteEffects.None, 0.0f);
|
||||
|
||||
DrawChildren(spriteBatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
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 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 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, Alignment alignment, GUIComponent parent = null)
|
||||
: this(rect, style.foreGroundColor, alignment, parent)
|
||||
{
|
||||
}
|
||||
|
||||
public GUIListBox(Rectangle rect, Color color, GUIComponent parent = null)
|
||||
: this(rect, color, (Alignment.Left | Alignment.Top), parent)
|
||||
{
|
||||
}
|
||||
|
||||
public GUIListBox(Rectangle rect, Color color, Alignment alignment, GUIComponent parent = null)
|
||||
{
|
||||
this.rect = rect;
|
||||
this.alignment = alignment;
|
||||
|
||||
this.color = color;
|
||||
|
||||
if (parent != null)
|
||||
parent.AddChild(this);
|
||||
|
||||
this.rect.Width -= 20;
|
||||
|
||||
scrollBar = new GUIScrollBar(
|
||||
new Rectangle(this.rect.X + this.rect.Width, this.rect.Y, 20, this.rect.Height), color, 1.0f);
|
||||
|
||||
UpdateScrollBarSize();
|
||||
|
||||
enabled = true;
|
||||
|
||||
scrollBarEnabled = true;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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 (scrollBar.BarSize<1.0f && (oldSize>=1.0f || oldScroll==1.0f))
|
||||
{
|
||||
scrollBar.BarScroll = 1.0f;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override void RemoveChild(GUIComponent child)
|
||||
{
|
||||
base.RemoveChild(child);
|
||||
|
||||
UpdateScrollBarSize();
|
||||
|
||||
}
|
||||
|
||||
private void ShowScrollBar()
|
||||
{
|
||||
scrollBarHidden = false;
|
||||
Rect = new Rectangle(rect.X, rect.Y, rect.Width - scrollBar.Rect.Width, rect.Height);
|
||||
}
|
||||
|
||||
private void HideScrollBar()
|
||||
{
|
||||
scrollBarHidden = true;
|
||||
Rect = new Rectangle(rect.X, rect.Y, rect.Width + scrollBar.Rect.Width, rect.Height);
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch 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];
|
||||
|
||||
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 (child.Rect.Contains(PlayerInput.GetMouseState.Position) && enabled)
|
||||
{
|
||||
child.State = ComponentState.Hover;
|
||||
if (PlayerInput.LeftButtonClicked())
|
||||
{
|
||||
Debug.WriteLine("clicked");
|
||||
selected = child;
|
||||
if (OnSelected != null)
|
||||
OnSelected(child.UserData);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
child.State = ComponentState.None;
|
||||
}
|
||||
|
||||
child.Draw(spriteBatch);
|
||||
}
|
||||
|
||||
//GUI.DrawRectangle(spriteBatch, rect, Color.Black, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
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)
|
||||
{
|
||||
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, 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*alpha, true);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
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, style.foreGroundColor, barSize, parent)
|
||||
{
|
||||
}
|
||||
|
||||
public GUIScrollBar(Rectangle rect, Color color, float barSize, GUIComponent parent = null)
|
||||
: this(rect, color, barSize, (Alignment.Left | Alignment.Top), parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public GUIScrollBar(Rectangle rect, Color color, float barSize, Alignment alignment, GUIComponent parent = null)
|
||||
{
|
||||
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, this);
|
||||
//AddChild(frame);
|
||||
|
||||
//System.Diagnostics.Debug.WriteLine(frame.rect);
|
||||
|
||||
bar = new GUIButton(new Rectangle(0, 0, 0, 0), "", color, this);
|
||||
bar.OnPressed = SelectBar;
|
||||
//AddChild(bar);
|
||||
|
||||
enabled = true;
|
||||
|
||||
UpdateRect();
|
||||
}
|
||||
|
||||
private void UpdateRect()
|
||||
{
|
||||
bar.Rect = new Rectangle(
|
||||
frame.Rect.X,
|
||||
frame.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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
class GUIStyle
|
||||
{
|
||||
public readonly Vector4 smallPadding;
|
||||
public readonly Vector4 largePadding;
|
||||
|
||||
public readonly Color backGroundColor;
|
||||
public readonly Color foreGroundColor;
|
||||
|
||||
public readonly Color textColor;
|
||||
|
||||
public readonly Color hoverColor;
|
||||
public readonly Color selectedColor;
|
||||
|
||||
public GUIStyle(string file)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
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;
|
||||
|
||||
private bool wrap;
|
||||
|
||||
public override Vector4 Padding
|
||||
{
|
||||
get { return padding; }
|
||||
set
|
||||
{
|
||||
padding = value;
|
||||
SetTextPos();
|
||||
}
|
||||
}
|
||||
|
||||
public string Text
|
||||
{
|
||||
get { return text; }
|
||||
set
|
||||
{
|
||||
text = value;
|
||||
SetTextPos();
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 TextPos
|
||||
{
|
||||
get { return textPos; }
|
||||
}
|
||||
|
||||
public Vector2 Origin
|
||||
{
|
||||
get { return origin; }
|
||||
}
|
||||
|
||||
public Color TextColor
|
||||
{
|
||||
get { return textColor; }
|
||||
}
|
||||
|
||||
public Vector2 CaretPos
|
||||
{
|
||||
get { return caretPos; }
|
||||
}
|
||||
|
||||
public GUITextBlock(Rectangle rect, string text, GUIStyle style, Alignment alignment, Alignment textAlignment, GUIComponent parent = null, bool wrap = false)
|
||||
: this (rect, text, style.foreGroundColor, style.textColor, alignment, textAlignment, parent, wrap)
|
||||
{
|
||||
hoverColor = style.hoverColor;
|
||||
selectedColor = style.selectedColor;
|
||||
}
|
||||
|
||||
public GUITextBlock(Rectangle rect, string text, Color color, Color textColor, Alignment textAlignment = Alignment.Left, GUIComponent parent = null, bool wrap = false)
|
||||
: this(rect, text,color, textColor, (Alignment.Left | Alignment.Top), textAlignment, parent, wrap)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void UpdateDimensions(GUIComponent parent)
|
||||
{
|
||||
base.UpdateDimensions(parent);
|
||||
|
||||
SetTextPos();
|
||||
}
|
||||
|
||||
|
||||
public GUITextBlock(Rectangle rect, string text, Color color, Color textColor, Alignment alignment, Alignment textAlignment = Alignment.Left, GUIComponent parent = null, bool wrap = false)
|
||||
{
|
||||
this.rect = rect;
|
||||
|
||||
this.color = color;
|
||||
this.textColor = 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();
|
||||
|
||||
if (wrap && rect.Width>0)
|
||||
{
|
||||
text = text.Replace("\n"," ");
|
||||
this.text = ToolBox.WrapText(this.text, rect.Width);
|
||||
|
||||
Vector2 newSize = MeasureText();
|
||||
|
||||
Rectangle newRect = rect;
|
||||
|
||||
//newRect.Width += (int)(newSize.X-size.X);
|
||||
newRect.Height += (int)(newSize.Y - size.Y);
|
||||
|
||||
Rect = newRect;
|
||||
size = newSize;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
caretPos = new Vector2(rect.X + size.X, rect.Y) + textPos - origin;
|
||||
}
|
||||
|
||||
private Vector2 MeasureText()
|
||||
{
|
||||
Vector2 size = Vector2.Zero;
|
||||
while (size == Vector2.Zero)
|
||||
{
|
||||
try { size = GUI.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*alpha, true);
|
||||
|
||||
if (TextGetter != null) text = TextGetter();
|
||||
|
||||
if (!string.IsNullOrEmpty(text))
|
||||
{
|
||||
spriteBatch.DrawString(GUI.font,
|
||||
text,
|
||||
new Vector2(rect.X, rect.Y) + textPos,
|
||||
textColor * alpha,
|
||||
0.0f, origin, 1.0f,
|
||||
SpriteEffects.None, 0.0f);
|
||||
}
|
||||
|
||||
DrawChildren(spriteBatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
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 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 (GUI.font.Characters.Contains(c))
|
||||
filtered += c;
|
||||
}
|
||||
|
||||
textBlock.Text = filtered;
|
||||
|
||||
if (GUI.font.MeasureString(textBlock.Text).X > rect.Width)
|
||||
{
|
||||
//recursion to ensure that text cannot be larger than the box
|
||||
Text = textBlock.Text.Substring(0, textBlock.Text.Length - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public GUITextBox(Rectangle rect, Color color, Color textColor, Alignment alignment, Alignment textAlignment = Alignment.Left, GUIComponent parent = null)
|
||||
{
|
||||
this.rect = rect;
|
||||
|
||||
this.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, this);
|
||||
textBlock.Padding = new Vector4(10.0f, 0.0f, 10.0f, 0.0f);
|
||||
|
||||
_previousMouse = PlayerInput.GetMouseState;
|
||||
//SetTextPos();
|
||||
}
|
||||
|
||||
public void Select()
|
||||
{
|
||||
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)
|
||||
{
|
||||
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 + rect.Height - 3),
|
||||
textBlock.TextColor * alpha);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
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;
|
||||
|
||||
bool selected;
|
||||
|
||||
public GUITickBox(Rectangle rect, string label, Alignment alignment, GUIComponent parent)
|
||||
{
|
||||
if (parent != null)
|
||||
parent.AddChild(this);
|
||||
|
||||
box = new GUIFrame(new Rectangle(rect.X, rect.Y, 30, 30), Color.LightGray, this);
|
||||
text = new GUITextBlock(new Rectangle(rect.X + 40, rect.Y, 200, 30), label, Color.Transparent, Color.White, Alignment.Left | Alignment.CenterY, 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 + 5, box.Rect.Y + 5, box.Rect.Width - 10, box.Rect.Height - 10), Color.Green * alpha, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user