diff --git a/MonogameLibrary/MonogameLibrary.csproj b/MonogameLibrary/MonogameLibrary.csproj new file mode 100644 index 0000000..d52ccc3 --- /dev/null +++ b/MonogameLibrary/MonogameLibrary.csproj @@ -0,0 +1,18 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + diff --git a/MonogameLibrary/UI/Base/DrawableTextedUiElement.cs b/MonogameLibrary/UI/Base/DrawableTextedUiElement.cs new file mode 100644 index 0000000..0d64052 --- /dev/null +++ b/MonogameLibrary/UI/Base/DrawableTextedUiElement.cs @@ -0,0 +1,119 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using MonogameLibrary.UI.Enums; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Xna.Framework.Content; + +namespace MonogameLibrary.UI.Base +{ + public class DrawableTextedUiElement : DrawableUIElement + { + protected SpriteFont spriteFont; + public string fontName; + public string text = ""; + public float scale = 0.5f; + public Color fontColor = Color.Black; + public TextAligment textAligment = TextAligment.Center; + + public DrawableTextedUiElement(UIManager manager, int layerIndex = 0, string textureName = "", string fontName = "") + : base(manager, layerIndex, textureName) + { + this.fontName = fontName; + } + + public override void LoadTexture(ContentManager content) + { + base.LoadTexture(content); + if (fontName != "") + { + try + { + spriteFont = content.Load(fontName); + } + catch + { + } + } + } + + public virtual void DrawText(SpriteBatch spriteBatch) + { + if (text == "") + return; + + if (spriteFont != null) + { + var measured = spriteFont.MeasureString(text) * scale; + + if (textAligment == TextAligment.Center) + { + Vector2 pos = rectangle.Location.ToVector2(); + pos.Y += (int)((rectangle.Height - measured.Y) / 2); + pos.X += (int)((rectangle.Width - measured.X) / 2); + spriteBatch.DrawString(spriteFont, text, pos, fontColor, 0, Vector2.Zero, scale, + SpriteEffects.None, 0); + } + else if (textAligment == TextAligment.Left) + { + Vector2 pos = rectangle.Location.ToVector2(); + pos.Y += (int)((rectangle.Height - measured.Y) / 2); + pos.X += (int)(2 * scale + rectangle.Width / 20); + spriteBatch.DrawString(spriteFont, text, pos, fontColor, 0, Vector2.Zero, scale, + SpriteEffects.None, 0); + } + else + { + Vector2 pos = rectangle.Location.ToVector2(); + pos.Y += (int)((rectangle.Height - measured.Y) / 2); + pos.X += (int)(rectangle.Width - measured.X - 2 * scale); + spriteBatch.DrawString(spriteFont, text, pos, fontColor, 0, Vector2.Zero, scale, + SpriteEffects.None, 0); + } + } + else + { + var measured = Manager.BaseFont.MeasureString(text) * scale; + measured.X -= measured.X % 10; + //measured.Y *= -1; + if (textAligment == TextAligment.Center) + { + Vector2 pos = rectangle.Location.ToVector2(); + pos.Y += (int)((rectangle.Height - measured.Y) / 2); + pos.X += (int)((rectangle.Width - measured.X) / 2); + spriteBatch.DrawString(Manager.BaseFont, text, pos, fontColor, 0, Vector2.Zero, scale, + SpriteEffects.None, 0); + } + else if (textAligment == TextAligment.Left) + { + //var rct = new Rectangle(rectangle.Location, rectangle.Size); + //rct.Width = (int)measured.X; + //rct.Height = (int)measured.Y; + //rct.Y += (int)((rectangle.Height - measured.Y) / 2); + //rct.X += (int)((rectangle.Width - measured.X) / 2); + + //_spriteBatch.Draw(texture, rct, new Color(255, 0, 0, 125)); + //_spriteBatch.DrawString(MonoClassManagerUI.MainBaseFont, text, rct.Location.ToVector2(), fontColor, 0, Vector2.Zero, scale, SpriteEffects.None, 0); + + + Vector2 pos = rectangle.Location.ToVector2(); + pos.Y += (int)((rectangle.Height - measured.Y) / 2); + pos.X += (int)(2 * scale); + spriteBatch.DrawString(Manager.BaseFont, text, pos, fontColor, 0, Vector2.Zero, scale, + SpriteEffects.None, 0); + } + else + { + Vector2 pos = rectangle.Location.ToVector2(); + pos.Y += (int)((rectangle.Height - measured.Y) / 2); + pos.X += (int)(rectangle.Width - measured.X - 2 * scale); + spriteBatch.DrawString(Manager.BaseFont, text, pos, fontColor, 0, Vector2.Zero, scale, + SpriteEffects.None, 0); + } + } + } + } +} \ No newline at end of file diff --git a/MonogameLibrary/UI/Base/DrawableUIElement.cs b/MonogameLibrary/UI/Base/DrawableUIElement.cs new file mode 100644 index 0000000..8835ce0 --- /dev/null +++ b/MonogameLibrary/UI/Base/DrawableUIElement.cs @@ -0,0 +1,53 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using MonogameLibrary.UI.Enums; +using System; +using System.Collections.Generic; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Threading; +using Microsoft.Xna.Framework.Content; + +namespace MonogameLibrary.UI.Base +{ + public class DrawableUIElement + { + protected Texture2D texture; + protected int layerIndex; + protected UIManager Manager; + public string textureName = ""; + public Rectangle rectangle = new Rectangle(0, 0, 10, 10); + public Color mainColor = Color.White; + + public DrawableUIElement(UIManager manager, int layerIndex = 0, string textureName = "") + { + Manager = manager; + this.textureName = textureName; + manager.Register(this, layerIndex); + } + public virtual void LoadTexture(ContentManager content) + { + if (textureName == "") + { + texture = new Texture2D(Manager.GraphicsDevice, 1, 1); + texture.SetData(new Color[] { mainColor }); + } + else + { + try + { + texture = content.Load(textureName); + } + catch + { + texture = new Texture2D(Manager.GraphicsDevice, 1, 1); + texture.SetData(new Color[] { mainColor }); + } + } + } + public virtual void Draw(SpriteBatch _spriteBatch) + { + _spriteBatch.Draw(texture, rectangle, mainColor); + } + } +} diff --git a/MonogameLibrary/UI/Base/UIManager.cs b/MonogameLibrary/UI/Base/UIManager.cs new file mode 100644 index 0000000..826a0a1 --- /dev/null +++ b/MonogameLibrary/UI/Base/UIManager.cs @@ -0,0 +1,105 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using MonogameLibrary.UI.Elements; +using MonogameLibrary.UI.Interfaces; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography.X509Certificates; +using static System.Net.Mime.MediaTypeNames; + +namespace MonogameLibrary.UI.Base +{ + public enum InputState { GamePad, Keyboard, Mouse } + public class UIManager + { + Dictionary> layerCollection = new(); + public GraphicsDevice GraphicsDevice { get; private set; } + public SpriteFont BaseFont { get; private set; } + public InputState inputState = InputState.Mouse; + public void Initialize(GraphicsDevice graphicsDevice) + { + GraphicsDevice = graphicsDevice; + + for (int i = -10; i < 11; i++) + { + layerCollection.Add(i, new List()); + } + } + public KeyboardState GetKeyboardState { get { return keyboardState; } } + static MouseState mouseState, prevmouseState; + static KeyboardState keyboardState; + public static Point resolutionInGame, resolution; + + + public void LoadContent(ContentManager content, string font) + { + + try + { + BaseFont = content.Load(font); + } + catch + { + } + foreach (var collection in layerCollection) + { + foreach (var item in collection.Value) + { + item.LoadTexture(content); + } + } + } + public GameTime gameTime; + public void Update(GameTime gameTime) + { + this.gameTime = gameTime; + try + { + keyboardState = Keyboard.GetState(); + mouseState = Mouse.GetState(); + mouseState = new MouseState((int)(mouseState.X*(float)resolutionInGame.X/resolution.X), + (int)(mouseState.Y * (float)resolutionInGame.Y / resolution.Y), mouseState.ScrollWheelValue, mouseState.LeftButton, mouseState.MiddleButton, mouseState.RightButton, mouseState.XButton1, mouseState.XButton2); + } + catch + { + + } + bool hasInteracted = false; + foreach (var collection in layerCollection) + { + foreach (var item in collection.Value) + { + if (item is IInteractable) + { + if (!hasInteracted) + { + hasInteracted = (item as IInteractable).InteractUpdate(mouseState, prevmouseState); + } + } + } + } + prevmouseState = mouseState; + } + public void Draw(SpriteBatch spriteBatch) + { + spriteBatch.Begin(); + foreach (var collection in layerCollection) + { + foreach (var item in collection.Value) + { + item.Draw(spriteBatch); + } + } + spriteBatch.End(); + } + public void Register(DrawableUIElement drawableUiElement, int layerIndex) + { + if (!layerCollection.ContainsKey(layerIndex)) + layerCollection.Add(layerIndex, new List()); + + layerCollection[layerIndex].Add(drawableUiElement); + } + } +} diff --git a/MonogameLibrary/UI/Compounds/BasicDrawableCompound.cs b/MonogameLibrary/UI/Compounds/BasicDrawableCompound.cs new file mode 100644 index 0000000..66185a3 --- /dev/null +++ b/MonogameLibrary/UI/Compounds/BasicDrawableCompound.cs @@ -0,0 +1,106 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using MonogameLibrary.UI.Base; +using MonogameLibrary.UI.Elements; +using MonogameLibrary.UI.Enums; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; +using System.Xml.Linq; +using Microsoft.Xna.Framework.Content; + +namespace MonogameLibrary.UI.Compounds +{ + public enum BasicDrawableCompound_Type { Vertical, Horizontal }; + public class BasicDrawableCompound : DrawableTextedUiElement + { + public BasicDrawableCompound(UIManager manager, int layerIndex = 0) : base(manager, layerIndex) + { + rectangle = new Rectangle(0, 0, 20, 20); + lastPos = new Vector2(0, offset.Y); + } + Dictionary drawables = new Dictionary(); + public Vector2 lastPos; + Vector2 offset = new Vector2(10, 10); + int mainWidth = 40; + public void Add(string name, DrawableTextedUiElement element) + { + //var a = Assembly.GetExecutingAssembly().GetTypes(); + //var b = a.Where(t => t.Get().Contains(type)); + //var element = ((MonoDrawableTextedUI)Assembly.GetExecutingAssembly().GetTypes() + // .Where(t => t.GetInterfaces().Contains(type)) + // .Select(x => Activator.CreateInstance(x) as ICommand).ToArray()[0]); + if (element is Slider) + { + element.rectangle = new Rectangle(0, 0, mainWidth * 3, 30); + } + if (element is Label) + { + element.rectangle = new Rectangle(0, 0, mainWidth * 2, 30); + } + if (element is TextBox) + { + element.rectangle = new Rectangle(0, 0, mainWidth * 2, 30); + } + if (element is Button) + { + element.rectangle = new Rectangle(0, 0, mainWidth, 30); + } + element.rectangle.Location = GetPositionOfElement(element).ToPoint(); + if (drawables.ContainsKey(name)) + { + int i = 1; + while (drawables.ContainsKey(name + $"({i})")) + { + i++; + } + name += $"({i})"; + } + drawables.Add(name, element); + } + public Vector2 GetPositionOfElement(DrawableTextedUiElement element) + { + Vector2 pos = lastPos + new Vector2(offset.X, 0); + lastPos = pos + new Vector2(element.rectangle.Width, 0); + if (lastPos.X>= rectangle.Width) + { + pos.X = offset.X; + pos.Y += offset.Y + element.rectangle.Height; + lastPos = pos + new Vector2(element.rectangle.Width, 0); + } + return rectangle.Location.ToVector2() + pos; + } + + public override void LoadTexture(ContentManager content) + { + base.LoadTexture(content); + if (fontName != "") + { + try + { + spriteFont = content.Load(fontName); + } + catch + { + } + } + foreach (var d in drawables) + { + d.Value.LoadTexture(content); + } + + } + public override void Draw(SpriteBatch spriteBatch) + { + spriteBatch.Draw(texture, rectangle, mainColor); + foreach (var d in drawables) + { + d.Value.Draw(spriteBatch); + } + } + } +} diff --git a/MonogameLibrary/UI/Elements/Button.cs b/MonogameLibrary/UI/Elements/Button.cs new file mode 100644 index 0000000..769335f --- /dev/null +++ b/MonogameLibrary/UI/Elements/Button.cs @@ -0,0 +1,85 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using MonogameLibrary.UI.Base; +using MonogameLibrary.UI.Enums; +using MonogameLibrary.UI.Interfaces; +using System; +using System.Collections.Generic; +using System.Text; +using static MonogameLibrary.UI.Elements.Button; + +namespace MonogameLibrary.UI.Elements +{ + public class Button : DrawableTextedUiElement, IInteractable + { + public delegate void OnButtonPressed(); + public event OnButtonPressed? RightButtonPressed; + public event OnButtonPressed? LeftButtonPressed; + public HoverState hoverState = HoverState.None; + + public Button(UIManager manager, int layerIndex = 0) : base(manager, layerIndex) + { + } + + public virtual bool InteractUpdate(MouseState mouseState, MouseState prevmouseState) + { + //if (Manager.) + if (rectangle.Intersects(new Rectangle(mouseState.Position, Point.Zero))) + { + if (mouseState.LeftButton == ButtonState.Pressed || mouseState.RightButton == ButtonState.Pressed) + { + hoverState = HoverState.Pressing; + } + else + { + hoverState = HoverState.Hovering; + } + if (prevmouseState.LeftButton == ButtonState.Pressed) + { + if (mouseState.LeftButton != prevmouseState.LeftButton) + { + hoverState = HoverState.Pressing; + CallLeftBtnEvent(); + return true; + } + } + else if(prevmouseState.RightButton == ButtonState.Pressed) + { + if (mouseState.RightButton != prevmouseState.RightButton) + { + RightButtonPressed?.Invoke(); + return true; + } + } + } + else + { + hoverState = HoverState.None; + } + return false; + } + public override void Draw(SpriteBatch _spriteBatch) + { + if (hoverState == HoverState.None) + { + _spriteBatch.Draw(texture, rectangle, Color.White); + } + else if (hoverState == HoverState.Hovering) + { + _spriteBatch.Draw(texture, rectangle, new Color(211, 211, 211)); + } + + else + { + _spriteBatch.Draw(texture, rectangle, new Color(112, 128, 144)); + } + + DrawText(_spriteBatch); + } + public void CallLeftBtnEvent() + { + LeftButtonPressed?.Invoke(); + } + } +} diff --git a/MonogameLibrary/UI/Elements/ButtonText.cs b/MonogameLibrary/UI/Elements/ButtonText.cs new file mode 100644 index 0000000..a5cc9c8 --- /dev/null +++ b/MonogameLibrary/UI/Elements/ButtonText.cs @@ -0,0 +1,71 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using MonogameLibrary.UI.Base; +using MonogameLibrary.UI.Enums; +using MonogameLibrary.UI.Interfaces; +using System; +using System.Collections.Generic; +using System.Text; +using static MonogameLibrary.UI.Elements.Button; + +namespace MonogameLibrary.UI.Elements +{ + public class ButtonText : Button + { + public ButtonText(UIManager manager, int layerIndex = 0) : base(manager, layerIndex) + { + } + float gameTime = 0; + public override bool InteractUpdate(MouseState mouseState, MouseState prevmouseState) + { + gameTime += (float)Manager.gameTime.ElapsedGameTime.TotalSeconds; + return base.InteractUpdate(mouseState, prevmouseState); + } + + public override void Draw(SpriteBatch _spriteBatch) + { + if (hoverState == HoverState.None) + { + var d = (float)(((Math.Sin(gameTime * 2 - Math.PI) + 1) / 2f) * 0.1 + 0.7f); + fontColor = Color.FromNonPremultiplied(new Vector4(0.8f,0.15f, 0.15f, 1) * d + ); + } + else if (hoverState == HoverState.Hovering) + { + var d2 = (float)(((Math.Sin(gameTime * 2 - Math.PI) + 1) / 2f) * 0.1 + 0.7f); + fontColor = Color.FromNonPremultiplied(new Vector4(0.8f, 0.15f, 0.15f, 1) * d2 + ); + } + else + { + //fontColor = new Color(112, 128, 144); + fontColor = new Color(212, 228, 244); + } + + if (hoverState == HoverState.Hovering) + { + scale += 0.005f; + var d = (float)(((Math.Sin(gameTime * 1 - Math.PI) + 1) / 2f) * 0.1 + 1f); + Color oldColor = fontColor; + fontColor = Color.FromNonPremultiplied(new Vector4(252 / 255f, 231 / 255f, 124 / 255f, 1) * d + ); + DrawText(_spriteBatch); + fontColor = oldColor; + fontColor.A = 255; + scale -= 0.005f; + scale -= 0.0002f; + } + if (hoverState == HoverState.Pressing) + { + scale -= 0.025f; + DrawText(_spriteBatch); + scale += 0.025f; + } + else + { + DrawText(_spriteBatch); + } + } + } +} diff --git a/MonogameLibrary/UI/Elements/CheckBox.cs b/MonogameLibrary/UI/Elements/CheckBox.cs new file mode 100644 index 0000000..5dc400f --- /dev/null +++ b/MonogameLibrary/UI/Elements/CheckBox.cs @@ -0,0 +1,81 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using MonogameLibrary.UI.Base; +using MonogameLibrary.UI.Enums; +using MonogameLibrary.UI.Interfaces; +using System; +using System.Collections.Generic; +using System.Text; + +namespace MonogameLibrary.UI.Elements +{ + public class CheckBox : DrawableTextedUiElement, IInteractable + { + public CheckBox(UIManager manager, int layerIndex = 0) : base(manager, layerIndex) + { + } + private Texture2D texture1; + private Texture2D texture2; + private Texture2D texture3; + public delegate void OnCheck(bool checkState); + public event OnCheck? Checked; + private bool isChecked; + HoverState hoverState = HoverState.None; + public bool GetChecked { get { return isChecked; } } + public bool InteractUpdate(MouseState mouseState, MouseState prevmouseState) + { + if (rectangle.Intersects(new Rectangle(mouseState.Position, Point.Zero))) + { + hoverState = HoverState.Hovering; + if (prevmouseState.LeftButton == ButtonState.Pressed) + { + hoverState = HoverState.Pressing; + if (mouseState.LeftButton != prevmouseState.LeftButton) + { + isChecked = !isChecked; + Checked?.Invoke(isChecked); + return true; + } + } + } + else + { + hoverState = HoverState.None; + } + return false; + } + + public override void LoadTexture(ContentManager content) + { + texture1 = content.Load("textures\\ui\\checkboxs_off"); + texture2 = content.Load("textures\\ui\\checkboxs_off-on"); + texture3 = content.Load("textures\\ui\\checkboxs_on"); + base.LoadTexture(content); + } + public override void Draw(SpriteBatch _spriteBatch) + { + if (isChecked) + { + if (hoverState == HoverState.None) + _spriteBatch.Draw(texture3, rectangle, Color.White); + else if (hoverState == HoverState.Hovering) + _spriteBatch.Draw(texture3, rectangle, Color.White); + else + _spriteBatch.Draw(texture2, rectangle, Color.White ); + } + else + { + if (hoverState == HoverState.None) + _spriteBatch.Draw(texture1, rectangle, Color.White); + else if (hoverState == HoverState.Hovering) + _spriteBatch.Draw(texture2, rectangle, Color.White); + else + _spriteBatch.Draw(texture2, rectangle, Color.White); + } + DrawText(_spriteBatch); + } + + } +} diff --git a/MonogameLibrary/UI/Elements/Label.cs b/MonogameLibrary/UI/Elements/Label.cs new file mode 100644 index 0000000..1a8871e --- /dev/null +++ b/MonogameLibrary/UI/Elements/Label.cs @@ -0,0 +1,56 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using MonogameLibrary.UI.Base; +using MonogameLibrary.UI.Enums; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MonogameLibrary.UI.Elements +{ + public class Label : DrawableTextedUiElement + { + + public Label(UIManager manager, int layerIndex = 0) : base(manager, layerIndex) + { + } + protected HoverState hoverState = HoverState.None; + + float gameTime = 0; + public virtual bool InteractUpdate(MouseState mouseState, MouseState prevmouseState) + { + gameTime += (float)Manager.gameTime.ElapsedGameTime.TotalSeconds; + if (rectangle.Intersects(new Rectangle(mouseState.Position, Point.Zero))) + { + if (mouseState.LeftButton == ButtonState.Pressed) + { + hoverState = HoverState.Pressing; + } + else + { + hoverState = HoverState.Hovering; + } + } + else + { + hoverState = HoverState.None; + } + return false; + } + public override void Draw(SpriteBatch _spriteBatch) + { + if (hoverState == HoverState.None) + { + _spriteBatch.Draw(texture, rectangle, new Color(235, 235, 235)); + } + else if (hoverState == HoverState.Hovering) + _spriteBatch.Draw(texture, rectangle, new Color(211, 211, 211)); + else + _spriteBatch.Draw(texture, rectangle, new Color(112, 128, 144)); + DrawText(_spriteBatch); + } + } +} diff --git a/MonogameLibrary/UI/Elements/Rect.cs b/MonogameLibrary/UI/Elements/Rect.cs new file mode 100644 index 0000000..d776fb7 --- /dev/null +++ b/MonogameLibrary/UI/Elements/Rect.cs @@ -0,0 +1,68 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using MonogameLibrary.UI.Base; +using MonogameLibrary.UI.Enums; +using MonogameLibrary.UI.Interfaces; +using System; +using System.Collections.Generic; +using System.Text; +using static MonogameLibrary.UI.Elements.Button; + +namespace MonogameLibrary.UI.Elements +{ + public class Rect : DrawableTextedUiElement, IInteractable + { + public delegate void OnButtonPressed(); + public event OnButtonPressed? RightButtonPressed; + public event OnButtonPressed? LeftButtonPressed; + protected HoverState hoverState = HoverState.None; + + public Rect(UIManager manager, int layerIndex = 0) : base(manager, layerIndex) + { + } + + public virtual bool InteractUpdate(MouseState mouseState, MouseState prevmouseState) + { + //if (Manager.) + if (rectangle.Intersects(new Rectangle(mouseState.Position, Point.Zero))) + { + if (mouseState.LeftButton == ButtonState.Pressed || mouseState.RightButton == ButtonState.Pressed) + { + hoverState = HoverState.Pressing; + } + else + { + hoverState = HoverState.Hovering; + } + if (prevmouseState.LeftButton == ButtonState.Pressed) + { + if (mouseState.LeftButton != prevmouseState.LeftButton) + { + hoverState = HoverState.Pressing; + LeftButtonPressed?.Invoke(); + return true; + } + } + else if(prevmouseState.RightButton == ButtonState.Pressed) + { + if (mouseState.RightButton != prevmouseState.RightButton) + { + RightButtonPressed?.Invoke(); + return true; + } + } + } + else + { + hoverState = HoverState.None; + } + return false; + } + public override void Draw(SpriteBatch _spriteBatch) + { + _spriteBatch.Draw(texture, rectangle, Color.White); + DrawText(_spriteBatch); + } + } +} diff --git a/MonogameLibrary/UI/Elements/Slider.cs b/MonogameLibrary/UI/Elements/Slider.cs new file mode 100644 index 0000000..b496cdf --- /dev/null +++ b/MonogameLibrary/UI/Elements/Slider.cs @@ -0,0 +1,84 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using MonogameLibrary.UI.Base; +using MonogameLibrary.UI.Enums; +using MonogameLibrary.UI.Interfaces; +using System; +using System.Collections.Generic; +using System.Text; + +namespace MonogameLibrary.UI.Elements +{ + public class Slider : DrawableTextedUiElement, IInteractable + { + public Slider(UIManager manager, int layerIndex = 0) : base(manager, layerIndex) + { + } + public delegate void OnSliderChanges(float value); + public event OnSliderChanges? SliderChanged; + public int indentation = 5; + + Texture2D texture2; + public Rectangle sliderRect = new Rectangle(0, 0, 30, 30); + private float sliderValue = 0; + private float minValue = 0, maxValue = 1; + SliderState sliderState = SliderState.None; + + public float GetValue { get { return minValue + sliderValue * (maxValue - minValue); } } + public float GetSliderValue { get { return sliderValue; } } + public float MinValue { get { return minValue; } set { minValue = value; } } + public float MaxValue { get { return maxValue; } set { maxValue = value; } } + + public bool InteractUpdate(MouseState mouseState, MouseState prevmouseState) + { + if (mouseState.LeftButton == ButtonState.Pressed) + { + if (sliderRect.Intersects(new Rectangle(mouseState.Position, Point.Zero)) || + rectangle.Intersects(new Rectangle(mouseState.Position, Point.Zero)) || + sliderState == SliderState.Moving) + { + sliderValue = Math.Clamp((mouseState.Position.X - rectangle.X - sliderRect.Width / 2f) / (rectangle.Width - sliderRect.Width), 0, 1); + sliderState = SliderState.Moving; + SliderChanged?.Invoke(GetValue); + return true; + } + } + else if (sliderRect.Intersects(new Rectangle(mouseState.Position, Point.Zero))) + { + sliderState = SliderState.HoveringOverSliderButton; + } + else + sliderState = SliderState.None; + return false; + } + + public override void LoadTexture(ContentManager content) + { + texture2 = content.Load("textures\\ui\\slider"); + base.LoadTexture(content); + } + + public void SetValue(float setvalue) + { + sliderValue = setvalue; + SliderChanged?.Invoke(GetValue); + } + + public override void Draw(SpriteBatch _spriteBatch) + { + base.Draw(_spriteBatch); + sliderRect.Location = rectangle.Location; + sliderRect.X += (int)(sliderValue * (rectangle.Width - sliderRect.Width - indentation * 2) + indentation); + sliderRect.Y -= sliderRect.Height / 2 - rectangle.Height / 2; + if (sliderState == SliderState.Moving) + _spriteBatch.Draw(texture2, sliderRect, Color.DarkRed); + else if(sliderState == SliderState.HoveringOverSliderButton) + _spriteBatch.Draw(texture2, sliderRect, new Color(200,0 ,0)); + else + _spriteBatch.Draw(texture2, sliderRect, Color.Red); + DrawText(_spriteBatch); + } + } +} diff --git a/MonogameLibrary/UI/Elements/TextBox.cs b/MonogameLibrary/UI/Elements/TextBox.cs new file mode 100644 index 0000000..87534eb --- /dev/null +++ b/MonogameLibrary/UI/Elements/TextBox.cs @@ -0,0 +1,310 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using MonogameLibrary.UI.Base; +using MonogameLibrary.UI.Enums; +using MonogameLibrary.UI.Interfaces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using static System.Net.Mime.MediaTypeNames; + +namespace MonogameLibrary.UI.Elements +{ + public class TextBox : DrawableTextedUiElement, IInteractable + { + public TextBox(UIManager manager, int layerIndex = 0) : base(manager, layerIndex) + { + OnEnter += (txt) => { + isSelected = IsSelected.NotSelected; + StopChanging?.Invoke(text); + }; + } + public delegate void OnTextChange(string text); + public event OnTextChange? TextChanged; + public event OnTextChange? StopChanging; + public event OnTextChange? OnEnter; + + public HoverState hoverState = HoverState.None; + protected IsSelected isSelected = IsSelected.NotSelected; + public bool shouldEndOnEnter; + public void SelectIt() + { + isSelected = IsSelected.Selected; + } + + public virtual bool InteractUpdate(MouseState mouseState, MouseState prevmouseState) + { + if (isSelected == IsSelected.Selected) + { + if (Keyboard.GetState().IsKeyDown(Keys.Enter)) + { + OnEnter?.Invoke(text); + if (shouldEndOnEnter) + { + return false; + } + } + + InputManager.GetInput(ref text); + } + if (rectangle.Intersects(new Rectangle(mouseState.Position, Point.Zero))) + { + if (mouseState.LeftButton == ButtonState.Pressed) + { + hoverState = HoverState.Pressing; + } + else + { + hoverState = HoverState.Hovering; + } + if (prevmouseState.LeftButton == ButtonState.Pressed) + { + if (mouseState.LeftButton != prevmouseState.LeftButton) + { + hoverState = HoverState.Pressing; + isSelected = IsSelected.Selected; + TextChanged?.Invoke(text); + return true; + } + } + } + else + { + + + if (mouseState.LeftButton == ButtonState.Pressed) + { + isSelected = IsSelected.NotSelected; + StopChanging?.Invoke(text); + } + + hoverState = HoverState.None; + } + return false; + } + public override void Draw(SpriteBatch _spriteBatch) + { + if (hoverState == HoverState.None) + { + if (isSelected == IsSelected.Selected) + _spriteBatch.Draw(texture, rectangle, new Color(220, 220, 220)); + else + _spriteBatch.Draw(texture, rectangle, new Color(245, 245, 245)); + } + else if (hoverState == HoverState.Hovering) + _spriteBatch.Draw(texture, rectangle, new Color(211, 211, 211)); + else + _spriteBatch.Draw(texture, rectangle, new Color(112, 128, 144)); + DrawText(_spriteBatch); + } + } + + + //TODO: add translation + public static class InputManager + { + static List pressed = new List(); + static float del = 0; + static bool isShiftPressed = false; + static bool isCTRLPressed = false; + static bool isALTPressed = false; + static bool isCAPSLOCKOn = false; + + public static void GetInput(ref string text) + { + var state = Keyboard.GetState(); + var keys = state.GetPressedKeys(); + isShiftPressed = state.IsKeyDown(Keys.LeftShift) || state.IsKeyDown(Keys.RightShift); + isCTRLPressed = state.IsKeyDown(Keys.LeftControl) || state.IsKeyDown(Keys.RightControl); + isALTPressed = state.IsKeyDown(Keys.LeftAlt) || state.IsKeyDown(Keys.RightAlt); + for (int i = 0; i < pressed.Count; i++) + { + if (!keys.Contains(pressed[i])) + { + pressed.RemoveAt(i); + i--; + } + } + foreach (var key in keys) + { + //System.Diagnostics.Debug.WriteLine(key.ToString()); + if (!pressed.Contains(key)) + { + pressed.Add(key); + + + + string getPressed = KeyDecode(key); + if (getPressed != null) + { + text += getPressed; + } + else + { + if (key == Keys.Back) + { + if (text.Length > 0) + { + text = text.Remove(text.Length - 1); + del = 0; + } + } + if (key == Keys.CapsLock) + { + isCAPSLOCKOn = !isCAPSLOCKOn; + } + } + + + } + if (IsKeySpecial(key)) + { + del++; + if (key == Keys.Back) + { + if (del>15) + { + if (text.Length > 0) + text = text.Remove(text.Length - 1); + del = 13; + } + } + } + } + } + public static string KeyDecode(Keys key) + { + string str = null; + if ((int)key >= 65 && (int)key <= 90) + { + str = key.ToString(); + } + else if ((int)key >= 48 && (int)key <= 57) + { + if (!isShiftPressed) + { + str = key.ToString().Trim('D'); + } + else + { + switch (key) + { + case Keys.D1: + return str = "!"; + case Keys.D2: + return str = "@"; + case Keys.D3: + return str = "#"; + case Keys.D4: + return str = "$"; + case Keys.D5: + return str = "%"; + case Keys.D6: + return str = "^"; + case Keys.D7: + return str = "&"; + case Keys.D8: + return str = "*"; + case Keys.D9: + return str = "("; + case Keys.D0: + return str = ")"; + } + } + } + else if ((int)key >= 96 && (int)key <= 105) + { + str = key.ToString().Remove(0, 6); + } + if (str != null) + { + if ((!isShiftPressed && !isCAPSLOCKOn) || (isShiftPressed && isCAPSLOCKOn)) + return str.ToLower(); + else + return str.ToUpper(); + } + + + if (!isShiftPressed) + { + switch (key) + { + case Keys.Space: + return " "; + case Keys.OemTilde: + return "`"; + case Keys.Enter: + return "\n"; + case Keys.OemPipe: + return "\\"; + case Keys.OemPlus: + return "="; + case Keys.OemMinus: + return "-"; + + + case Keys.OemComma: + return ","; + case Keys.OemQuestion: + return "."; + case Keys.OemPeriod: + return "/"; + case Keys.OemSemicolon: + return ";"; + case Keys.OemQuotes: + return "'"; + case Keys.OemOpenBrackets: + return "["; + case Keys.OemCloseBrackets: + return "]"; + } + } + else + { + switch (key) + { + case Keys.Space: + return " "; + case Keys.OemTilde: + return "~"; + case Keys.Enter: + return "\n"; + case Keys.OemPipe: + return "|"; + case Keys.OemPlus: + return "+"; + case Keys.OemMinus: + return "_"; + + + case Keys.OemComma: + return "<"; + case Keys.OemQuestion: + return ">"; + case Keys.OemPeriod: + return "?"; + case Keys.OemSemicolon: + return ":"; + case Keys.OemQuotes: + return "\""; + case Keys.OemOpenBrackets: + return "{"; + case Keys.OemCloseBrackets: + return "}"; + } + } + + //else if ((int)key >= 112 && (int)key <= 125) + //{ + // return key.ToString().Trim('F'); + //} + return null; + } + public static bool IsKeySpecial(Keys key) + { + return (key == Keys.Back) || (key == Keys.Space); + } + } +} diff --git a/MonogameLibrary/UI/Enums/Enums.cs b/MonogameLibrary/UI/Enums/Enums.cs new file mode 100644 index 0000000..3c7838a --- /dev/null +++ b/MonogameLibrary/UI/Enums/Enums.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MonogameLibrary.UI.Enums +{ + public enum HoverState { None, Hovering, Pressing } + public enum SliderState { None, Moving, HoveringOverSliderButton } + public enum IsSelected { NotSelected, Selected } + public enum TextAligment { Center, Left, Right } +} diff --git a/MonogameLibrary/UI/Interfaces/IInteractable.cs b/MonogameLibrary/UI/Interfaces/IInteractable.cs new file mode 100644 index 0000000..6f48b9f --- /dev/null +++ b/MonogameLibrary/UI/Interfaces/IInteractable.cs @@ -0,0 +1,12 @@ +using Microsoft.Xna.Framework.Input; +using System; +using System.Collections.Generic; +using System.Text; + +namespace MonogameLibrary.UI.Interfaces +{ + interface IInteractable + { + bool InteractUpdate(MouseState mouseState, MouseState prevmouseState); + } +} diff --git a/ZoFo.sln b/ZoFo.sln index 4dfae9f..d0636e2 100644 --- a/ZoFo.sln +++ b/ZoFo.sln @@ -2,6 +2,8 @@ Microsoft Visual Studio Solution File, Format Version 12.00 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZoFo", "ZoFo\ZoFo.csproj", "{D63272E5-A54D-4C24-AA48-2945CB1D0BBB}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonogameLibrary", "MonogameLibrary\MonogameLibrary.csproj", "{D6272E15-AD49-468A-BE0F-D812E8697FAC}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -12,5 +14,9 @@ Global {D63272E5-A54D-4C24-AA48-2945CB1D0BBB}.Debug|Any CPU.Build.0 = Debug|Any CPU {D63272E5-A54D-4C24-AA48-2945CB1D0BBB}.Release|Any CPU.ActiveCfg = Release|Any CPU {D63272E5-A54D-4C24-AA48-2945CB1D0BBB}.Release|Any CPU.Build.0 = Release|Any CPU + {D6272E15-AD49-468A-BE0F-D812E8697FAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D6272E15-AD49-468A-BE0F-D812E8697FAC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D6272E15-AD49-468A-BE0F-D812E8697FAC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D6272E15-AD49-468A-BE0F-D812E8697FAC}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/ZoFo/ZoFo.csproj b/ZoFo/ZoFo.csproj index a216165..ef2682f 100644 --- a/ZoFo/ZoFo.csproj +++ b/ZoFo/ZoFo.csproj @@ -22,6 +22,9 @@ + + +