From bbec589838757f5c1da2e633010ffb4ebe6ca6d5 Mon Sep 17 00:00:00 2001 From: Dylan Wilson Date: Thu, 22 Feb 2018 22:49:31 +1000 Subject: [PATCH] improvements to the gui system --- .../Controls/GuiCheckBox.cs | 28 ++++++++++-- .../Controls/GuiControl.cs | 6 ++- .../MonoGame.Extended.Gui/Controls/GuiForm.cs | 7 ++- .../Controls/GuiLayoutControl.cs | 5 ++- .../MonoGame.Extended.Gui/GuiControlStyle.cs | 7 ++- Source/MonoGame.Extended.Gui/GuiElement.cs | 2 + Source/MonoGame.Extended.Gui/GuiSkin.cs | 12 ++++- Source/MonoGame.Extended.Gui/GuiSystem.cs | 45 +++++++++---------- 8 files changed, 77 insertions(+), 35 deletions(-) diff --git a/Source/MonoGame.Extended.Gui/Controls/GuiCheckBox.cs b/Source/MonoGame.Extended.Gui/Controls/GuiCheckBox.cs index 8888f2d8..7443522e 100644 --- a/Source/MonoGame.Extended.Gui/Controls/GuiCheckBox.cs +++ b/Source/MonoGame.Extended.Gui/Controls/GuiCheckBox.cs @@ -53,18 +53,38 @@ namespace MonoGame.Extended.Gui.Controls return base.OnPointerUp(context, args); } - protected override void DrawBackground(IGuiContext context, IGuiRenderer renderer, float deltaSeconds) + private Rectangle GetCheckRectangle() { var boundingRectangle = BoundingRectangle; - var checkRectangle = new Rectangle(boundingRectangle.X, boundingRectangle.Y, BackgroundRegion.Width, BackgroundRegion.Height); - renderer.DrawRegion(BackgroundRegion, checkRectangle, Color); + if (BackgroundRegion != null) + return new Rectangle(boundingRectangle.X, boundingRectangle.Y, BackgroundRegion.Width, BackgroundRegion.Height); + + return new Rectangle(boundingRectangle.X, boundingRectangle.Y, boundingRectangle.Height, boundingRectangle.Height); + } + + protected override void DrawBackground(IGuiContext context, IGuiRenderer renderer, float deltaSeconds) + { + if (BackgroundRegion != null) + renderer.DrawRegion(BackgroundRegion, GetCheckRectangle(), Color); + else + { + renderer.DrawRectangle(GetCheckRectangle(), BorderColor, BorderThickness); + + if (IsChecked) + { + var innerCheckRectangle = GetCheckRectangle(); + innerCheckRectangle.Inflate(-4, -4); + renderer.FillRectangle(innerCheckRectangle, TextColor); + } + } } protected override void DrawForeground(IGuiContext context, IGuiRenderer renderer, float deltaSeconds, TextInfo textInfo) { + var checkRectangle = GetCheckRectangle(); textInfo.Position = BoundingRectangle.Location.ToVector2() + - new Vector2(BackgroundRegion.Width + 5, BackgroundRegion.Height * 0.5f - textInfo.Font.LineHeight * 0.5f); + new Vector2(checkRectangle.Width + 5, checkRectangle.Height * 0.5f - textInfo.Font.LineHeight * 0.5f); base.DrawForeground(context, renderer, deltaSeconds, textInfo); } diff --git a/Source/MonoGame.Extended.Gui/Controls/GuiControl.cs b/Source/MonoGame.Extended.Gui/Controls/GuiControl.cs index 20561cae..753e5461 100644 --- a/Source/MonoGame.Extended.Gui/Controls/GuiControl.cs +++ b/Source/MonoGame.Extended.Gui/Controls/GuiControl.cs @@ -4,7 +4,6 @@ using Microsoft.Xna.Framework; using MonoGame.Extended.BitmapFonts; using MonoGame.Extended.Input.InputListeners; using MonoGame.Extended.TextureAtlases; -using Microsoft.Xna.Framework.Input; using Newtonsoft.Json; using System.Collections.Generic; using System.Linq; @@ -278,6 +277,11 @@ namespace MonoGame.Extended.Gui.Controls { if (BackgroundRegion != null) renderer.DrawRegion(BackgroundRegion, BoundingRectangle, Color); + else + renderer.FillRectangle(BoundingRectangle, Color); + + if(BorderThickness != 0) + renderer.DrawRectangle(BoundingRectangle, BorderColor, BorderThickness); } protected virtual void DrawForeground(IGuiContext context, IGuiRenderer renderer, float deltaSeconds, TextInfo textInfo) diff --git a/Source/MonoGame.Extended.Gui/Controls/GuiForm.cs b/Source/MonoGame.Extended.Gui/Controls/GuiForm.cs index cb8939a5..efe710d1 100644 --- a/Source/MonoGame.Extended.Gui/Controls/GuiForm.cs +++ b/Source/MonoGame.Extended.Gui/Controls/GuiForm.cs @@ -7,10 +7,13 @@ namespace MonoGame.Extended.Gui.Controls public class GuiForm : GuiStackPanel { public GuiForm() - : base() { } + { + } public GuiForm(GuiSkin skin) - : base(skin) { } + : base(skin) + { + } public override bool OnKeyPressed(IGuiContext context, KeyboardEventArgs args) { diff --git a/Source/MonoGame.Extended.Gui/Controls/GuiLayoutControl.cs b/Source/MonoGame.Extended.Gui/Controls/GuiLayoutControl.cs index 176dc678..e2cd8f3e 100644 --- a/Source/MonoGame.Extended.Gui/Controls/GuiLayoutControl.cs +++ b/Source/MonoGame.Extended.Gui/Controls/GuiLayoutControl.cs @@ -28,8 +28,9 @@ protected override void DrawBackground(IGuiContext context, IGuiRenderer renderer, float deltaSeconds) { - if (BackgroundRegion != null) - renderer.DrawRegion(BackgroundRegion, BoundingRectangle, Color); + base.DrawBackground(context, renderer, deltaSeconds); + //if (BackgroundRegion != null) + // renderer.DrawRegion(BackgroundRegion, BoundingRectangle, Color); } } } \ No newline at end of file diff --git a/Source/MonoGame.Extended.Gui/GuiControlStyle.cs b/Source/MonoGame.Extended.Gui/GuiControlStyle.cs index d045bede..7341bc6f 100644 --- a/Source/MonoGame.Extended.Gui/GuiControlStyle.cs +++ b/Source/MonoGame.Extended.Gui/GuiControlStyle.cs @@ -9,7 +9,12 @@ namespace MonoGame.Extended.Gui { public class GuiControlStyle : IDictionary { - private Dictionary> _previousStates = new Dictionary>(); + private readonly Dictionary> _previousStates = new Dictionary>(); + + public GuiControlStyle() + : this(typeof(GuiElement)) + { + } public GuiControlStyle(Type targetType) : this(targetType.FullName, targetType) diff --git a/Source/MonoGame.Extended.Gui/GuiElement.cs b/Source/MonoGame.Extended.Gui/GuiElement.cs index ac9045c5..789e30ae 100644 --- a/Source/MonoGame.Extended.Gui/GuiElement.cs +++ b/Source/MonoGame.Extended.Gui/GuiElement.cs @@ -13,6 +13,8 @@ namespace MonoGame.Extended.Gui public Vector2 Position { get; set; } public Vector2 Origin { get; set; } public Color Color { get; set; } + public Color BorderColor { get; set; } = Color.White; + public int BorderThickness { get; set; } = 0; public TextureRegion2D BackgroundRegion { get; set; } private Size2 _size; diff --git a/Source/MonoGame.Extended.Gui/GuiSkin.cs b/Source/MonoGame.Extended.Gui/GuiSkin.cs index db24abc6..c85d295d 100644 --- a/Source/MonoGame.Extended.Gui/GuiSkin.cs +++ b/Source/MonoGame.Extended.Gui/GuiSkin.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using MonoGame.Extended.BitmapFonts; using System.Linq; +using System.Reflection; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; using MonoGame.Extended.Collections; @@ -23,7 +24,6 @@ namespace MonoGame.Extended.Gui Styles = new KeyedCollection(s => s.Name ?? s.TargetType.Name); } - [JsonProperty(Order = 0)] public string Name { get; set; } @@ -52,7 +52,15 @@ namespace MonoGame.Extended.Gui public GuiControlStyle GetStyle(Type controlType) { - return Styles.FirstOrDefault(s => s.TargetType == controlType); + GuiControlStyle controlStyle = null; + + while (controlStyle == null && controlType != null) + { + controlStyle = Styles.FirstOrDefault(s => s.TargetType == controlType); + controlType = controlType.GetTypeInfo().BaseType; + } + + return controlStyle; } public static GuiSkin FromFile(ContentManager contentManager, string path, params Type[] customControlTypes) diff --git a/Source/MonoGame.Extended.Gui/GuiSystem.cs b/Source/MonoGame.Extended.Gui/GuiSystem.cs index 2f74ea8a..68c247f3 100644 --- a/Source/MonoGame.Extended.Gui/GuiSystem.cs +++ b/Source/MonoGame.Extended.Gui/GuiSystem.cs @@ -26,8 +26,6 @@ namespace MonoGame.Extended.Gui private readonly KeyboardListener _keyboardListener; private GuiControl _preFocusedControl; - private GuiControl _focusedControl; - private GuiControl _hoveredControl; public GuiSystem(ViewportAdapter viewportAdapter, IGuiRenderer renderer) { @@ -38,7 +36,7 @@ namespace MonoGame.Extended.Gui _mouseListener.MouseDown += (s, e) => OnPointerDown(GuiPointerEventArgs.FromMouseArgs(e)); _mouseListener.MouseMoved += (s, e) => OnPointerMoved(GuiPointerEventArgs.FromMouseArgs(e)); _mouseListener.MouseUp += (s, e) => OnPointerUp(GuiPointerEventArgs.FromMouseArgs(e)); - _mouseListener.MouseWheelMoved += (s, e) => _focusedControl?.OnScrolled(e.ScrollWheelDelta); + _mouseListener.MouseWheelMoved += (s, e) => FocusedControl?.OnScrolled(e.ScrollWheelDelta); _touchListener = new TouchListener(viewportAdapter); _touchListener.TouchStarted += (s, e) => OnPointerDown(GuiPointerEventArgs.FromTouchArgs(e)); @@ -46,15 +44,16 @@ namespace MonoGame.Extended.Gui _touchListener.TouchEnded += (s, e) => OnPointerUp(GuiPointerEventArgs.FromTouchArgs(e)); _keyboardListener = new KeyboardListener(); - _keyboardListener.KeyTyped += (sender, args) => PropagateDown(_focusedControl, x => x.OnKeyTyped(this, args)); - _keyboardListener.KeyPressed += (sender, args) => PropagateDown(_focusedControl, x => x.OnKeyPressed(this, args)); + _keyboardListener.KeyTyped += (sender, args) => PropagateDown(FocusedControl, x => x.OnKeyTyped(this, args)); + _keyboardListener.KeyPressed += (sender, args) => PropagateDown(FocusedControl, x => x.OnKeyPressed(this, args)); Screens = new GuiScreenCollection(this) { ItemAdded = InitializeScreen }; } public GuiScreenCollection Screens { get; } - public GuiControl FocusedControl { get { return _focusedControl; } } + public GuiControl FocusedControl { get; private set; } + public GuiControl HoveredControl { get; private set; } public GuiScreen ActiveScreen => Screens.LastOrDefault(); @@ -99,7 +98,7 @@ namespace MonoGame.Extended.Gui } } - var cursor = ActiveScreen.Skin?.Cursor; + var cursor = ActiveScreen?.Skin?.Cursor; if (cursor != null) _renderer.DrawRegion(cursor.TextureRegion, CursorPosition, cursor.Color); @@ -131,7 +130,7 @@ namespace MonoGame.Extended.Gui return; _preFocusedControl = FindControlAtPoint(args.Position); - PropagateDown(_hoveredControl, x => x.OnPointerDown(this, args)); + PropagateDown(HoveredControl, x => x.OnPointerDown(this, args)); } private void OnPointerUp(GuiPointerEventArgs args) @@ -147,7 +146,7 @@ namespace MonoGame.Extended.Gui } _preFocusedControl = null; - PropagateDown(_hoveredControl, x => x.OnPointerUp(this, args)); + PropagateDown(HoveredControl, x => x.OnPointerUp(this, args)); } private void OnPointerMoved(GuiPointerEventArgs args) @@ -159,35 +158,35 @@ namespace MonoGame.Extended.Gui var hoveredControl = FindControlAtPoint(args.Position); - if (_hoveredControl != hoveredControl) + if (HoveredControl != hoveredControl) { - if (_hoveredControl != null && (hoveredControl == null || !hoveredControl.HasParent(_hoveredControl))) - PropagateDown(_hoveredControl, x => x.OnPointerLeave(this, args)); - _hoveredControl = hoveredControl; - PropagateDown(_hoveredControl, x => x.OnPointerEnter(this, args)); + if (HoveredControl != null && (hoveredControl == null || !hoveredControl.HasParent(HoveredControl))) + PropagateDown(HoveredControl, x => x.OnPointerLeave(this, args)); + HoveredControl = hoveredControl; + PropagateDown(HoveredControl, x => x.OnPointerEnter(this, args)); } else { - PropagateDown(_hoveredControl, x => x.OnPointerMove(this, args)); + PropagateDown(HoveredControl, x => x.OnPointerMove(this, args)); } } public void SetFocus(GuiControl focusedControl) { - if (_focusedControl != focusedControl) + if (FocusedControl != focusedControl) { - if (_focusedControl != null) + if (FocusedControl != null) { - _focusedControl.IsFocused = false; - PropagateDown(_focusedControl, x => x.OnUnfocus(this)); + FocusedControl.IsFocused = false; + PropagateDown(FocusedControl, x => x.OnUnfocus(this)); } - _focusedControl = focusedControl; + FocusedControl = focusedControl; - if (_focusedControl != null) + if (FocusedControl != null) { - _focusedControl.IsFocused = true; - PropagateDown(_focusedControl, x => x.OnFocus(this)); + FocusedControl.IsFocused = true; + PropagateDown(FocusedControl, x => x.OnFocus(this)); } } }