First commit

This commit is contained in:
Regalis
2015-05-25 01:04:03 +03:00
commit fadb89ae9e
320 changed files with 32186 additions and 0 deletions
+344
View File
@@ -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]);
}
}
}
+93
View File
@@ -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);
}
}
}
+237
View File
@@ -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();
}
}
}
+31
View File
@@ -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);
}
}
}
+84
View File
@@ -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);
}
}
}
+257
View File
@@ -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);
}
}
}
+77
View File
@@ -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);
}
}
}
+175
View File
@@ -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);
}
}
}
+50
View File
@@ -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);
}
}
}
+194
View File
@@ -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);
}
}
}
+198
View File
@@ -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;
}
}
}
+60
View File
@@ -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);
}
}
}
}