diff --git a/RGB.NET.Core/Positioning/Rectangle.cs b/RGB.NET.Core/Positioning/Rectangle.cs index 72b8e5c..17bb690 100644 --- a/RGB.NET.Core/Positioning/Rectangle.cs +++ b/RGB.NET.Core/Positioning/Rectangle.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Diagnostics; using System.Linq; @@ -25,9 +26,17 @@ namespace RGB.NET.Core get => _location; set { + Point oldValue = _location; if (SetProperty(ref _location, value)) - // ReSharper disable once ExplicitCallerInfoArgument - OnPropertyChanged(nameof(Center)); + { + if (oldValue != null) + oldValue.PropertyChanged -= LocationPropertyChanged; + + if (_location != null) + _location.PropertyChanged += LocationPropertyChanged; + + OnLocationChanged(); + } } } @@ -40,9 +49,17 @@ namespace RGB.NET.Core get => _size; set { + Size oldValue = _size; if (SetProperty(ref _size, value)) - // ReSharper disable once ExplicitCallerInfoArgument - OnPropertyChanged(nameof(Center)); + { + if (oldValue != null) + oldValue.PropertyChanged -= SizePropertyChanged; + + if (_size != null) + _size.PropertyChanged += SizePropertyChanged; + + OnSizeChanged(); + } } } @@ -59,6 +76,14 @@ namespace RGB.NET.Core #endregion + #region Events + + public event EventHandler LocationChanged; + public event EventHandler SizeChanged; + public event EventHandler Changed; + + #endregion + #region Constructors /// @@ -219,10 +244,7 @@ namespace RGB.NET.Core /// /// The to test. /// - public bool Contains(Point point) - { - return Contains(point.X, point.Y); - } + public bool Contains(Point point) => Contains(point.X, point.Y); /// /// Determines if the specified location is contained within this . @@ -230,30 +252,21 @@ namespace RGB.NET.Core /// The X-location to test. /// The Y-location to test. /// - public bool Contains(double x, double y) - { - return (Location.X <= x) && (x < (Location.X + Size.Width)) && (Location.Y <= y) && (y < (Location.Y + Size.Height)); - } + public bool Contains(double x, double y) => (Location.X <= x) && (x < (Location.X + Size.Width)) && (Location.Y <= y) && (y < (Location.Y + Size.Height)); /// /// Determines if the specified is contained within this . /// /// The to test. /// - public bool Contains(Rectangle rect) - { - return (Location.X <= rect.Location.X) && ((rect.Location.X + rect.Size.Width) <= (Location.X + Size.Width)) - && (Location.Y <= rect.Location.Y) && ((rect.Location.Y + rect.Size.Height) <= (Location.Y + Size.Height)); - } + public bool Contains(Rectangle rect) => (Location.X <= rect.Location.X) && ((rect.Location.X + rect.Size.Width) <= (Location.X + Size.Width)) + && (Location.Y <= rect.Location.Y) && ((rect.Location.Y + rect.Size.Height) <= (Location.Y + Size.Height)); /// /// Converts the - and -position of this to a human-readable string. /// /// A string that contains the and of this . For example "[Location: [X: 100, Y: 10], Size: [Width: 20, Height: [40]]". - public override string ToString() - { - return $"[Location: {Location}, Size: {Size}]"; - } + public override string ToString() => $"[Location: {Location}, Size: {Size}]"; /// /// Tests whether the specified object is a and is equivalent to this . @@ -289,6 +302,24 @@ namespace RGB.NET.Core } } + private void LocationPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) => OnLocationChanged(); + private void OnLocationChanged() + { + // ReSharper disable once ExplicitCallerInfoArgument + OnPropertyChanged(nameof(Center)); + LocationChanged?.Invoke(this, new EventArgs()); + Changed?.Invoke(this, new EventArgs()); + } + + private void SizePropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) => OnSizeChanged(); + private void OnSizeChanged() + { + // ReSharper disable once ExplicitCallerInfoArgument + OnPropertyChanged(nameof(Center)); + SizeChanged?.Invoke(this, new EventArgs()); + Changed?.Invoke(this, new EventArgs()); + } + #endregion #region Operators @@ -299,10 +330,7 @@ namespace RGB.NET.Core /// The first to compare. /// The second to compare. /// true if and are equal; otherwise, false. - public static bool operator ==(Rectangle rectangle1, Rectangle rectangle2) - { - return ReferenceEquals(rectangle1, null) ? ReferenceEquals(rectangle2, null) : rectangle1.Equals(rectangle2); - } + public static bool operator ==(Rectangle rectangle1, Rectangle rectangle2) => ReferenceEquals(rectangle1, null) ? ReferenceEquals(rectangle2, null) : rectangle1.Equals(rectangle2); /// /// Returns a value that indicates whether two specified are equal. @@ -310,10 +338,7 @@ namespace RGB.NET.Core /// The first to compare. /// The second to compare. /// true if and are not equal; otherwise, false. - public static bool operator !=(Rectangle rectangle1, Rectangle rectangle2) - { - return !(rectangle1 == rectangle2); - } + public static bool operator !=(Rectangle rectangle1, Rectangle rectangle2) => !(rectangle1 == rectangle2); #endregion } diff --git a/RGB.NET.Groups/Groups/RectangleLedGroup.cs b/RGB.NET.Groups/Groups/RectangleLedGroup.cs index c8b9f5d..4d64940 100644 --- a/RGB.NET.Groups/Groups/RectangleLedGroup.cs +++ b/RGB.NET.Groups/Groups/RectangleLedGroup.cs @@ -2,6 +2,7 @@ // ReSharper disable AutoPropertyCanBeMadeGetOnly.Global // ReSharper disable UnusedMember.Global +using System; using System.Collections.Generic; using System.Linq; using RGB.NET.Core; @@ -26,8 +27,17 @@ namespace RGB.NET.Groups get => _rectangle; set { - _rectangle = value; - InvalidateCache(); + Rectangle oldValue = _rectangle; + if (SetProperty(ref _rectangle, value)) + { + if (oldValue != null) + oldValue.Changed -= RectangleChanged; + + if (_rectangle != null) + _rectangle.Changed += RectangleChanged; + + InvalidateCache(); + } } } @@ -40,8 +50,8 @@ namespace RGB.NET.Groups get => _minOverlayPercentage; set { - _minOverlayPercentage = value; - InvalidateCache(); + if (SetProperty(ref _minOverlayPercentage, value)) + InvalidateCache(); } } @@ -100,35 +110,22 @@ namespace RGB.NET.Groups #region Methods /// - public override void OnAttach() - { - RGBSurface.Instance.SurfaceLayoutChanged += RGBSurfaceOnSurfaceLayoutChanged; - } + public override void OnAttach() => RGBSurface.Instance.SurfaceLayoutChanged += RGBSurfaceOnSurfaceLayoutChanged; /// - public override void OnDetach() - { - RGBSurface.Instance.SurfaceLayoutChanged -= RGBSurfaceOnSurfaceLayoutChanged; - } + public override void OnDetach() => RGBSurface.Instance.SurfaceLayoutChanged -= RGBSurfaceOnSurfaceLayoutChanged; - private void RGBSurfaceOnSurfaceLayoutChanged(SurfaceLayoutChangedEventArgs args) - { - InvalidateCache(); - } + private void RGBSurfaceOnSurfaceLayoutChanged(SurfaceLayoutChangedEventArgs args) => InvalidateCache(); + + private void RectangleChanged(object sender, EventArgs eventArgs) => InvalidateCache(); /// /// Gets a list containing all of this . /// /// The list containing all of this . - public override IEnumerable GetLeds() - { - return _ledCache ?? (_ledCache = RGBSurface.Instance.Leds.Where(x => x.LedRectangle.CalculateIntersectPercentage(Rectangle) >= MinOverlayPercentage).ToList()); - } + public override IEnumerable GetLeds() => _ledCache ?? (_ledCache = RGBSurface.Instance.Leds.Where(x => x.LedRectangle.CalculateIntersectPercentage(Rectangle) >= MinOverlayPercentage).ToList()); - private void InvalidateCache() - { - _ledCache = null; - } + private void InvalidateCache() => _ledCache = null; #endregion }