diff --git a/RGB.NET.Core/Devices/AbstractRGBDevice.cs b/RGB.NET.Core/Devices/AbstractRGBDevice.cs
index 90c97e1..59d0eae 100644
--- a/RGB.NET.Core/Devices/AbstractRGBDevice.cs
+++ b/RGB.NET.Core/Devices/AbstractRGBDevice.cs
@@ -175,9 +175,7 @@ namespace RGB.NET.Core
if (led != null)
{
- led.LedRectangle.Location = new Point(layoutLed.X, layoutLed.Y);
- led.LedRectangle.Size = new Size(layoutLed.Width, layoutLed.Height);
-
+ led.LedRectangle = new Rectangle(new Point(layoutLed.X, layoutLed.Y), new Size(layoutLed.Width, layoutLed.Height));
led.Shape = layoutLed.Shape;
led.ShapeData = layoutLed.ShapeData;
diff --git a/RGB.NET.Core/Extensions/RectangleExtensions.cs b/RGB.NET.Core/Extensions/RectangleExtensions.cs
new file mode 100644
index 0000000..7d2f85a
--- /dev/null
+++ b/RGB.NET.Core/Extensions/RectangleExtensions.cs
@@ -0,0 +1,115 @@
+using System;
+
+namespace RGB.NET.Core
+{
+ public static class RectangleExtensions
+ {
+ #region Methods
+
+ ///
+ /// Sets the of the given rectangle.
+ ///
+ /// The rectangle to modify.
+ /// The new location of the rectangle.
+ /// The modified .
+ public static Rectangle SetLocation(this Rectangle rect, Point location) => new Rectangle(location, rect.Size);
+
+ ///
+ /// Sets the of the of the given rectangle.
+ ///
+ /// The rectangle to modify.
+ /// The new x-location of the rectangle.
+ /// The modified .
+ public static Rectangle SetX(this Rectangle rect, double x) => new Rectangle(new Point(x, rect.Location.Y), rect.Size);
+
+ ///
+ /// Sets the of the of the given rectangle.
+ ///
+ /// The rectangle to modify.
+ /// The new y-location of the rectangle.
+ /// The modified .
+ public static Rectangle SetY(this Rectangle rect, double y) => new Rectangle(new Point(rect.Location.X, y), rect.Size);
+
+ ///
+ /// Sets the of the given rectangle.
+ ///
+ /// The rectangle to modify.
+ /// The new size of the rectangle.
+ /// The modified .
+ public static Rectangle SetSize(this Rectangle rect, Size size) => new Rectangle(rect.Location, size);
+
+ ///
+ /// Sets the of the of the given rectangle.
+ ///
+ /// The rectangle to modify.
+ /// The new width of the rectangle.
+ /// The modified .
+ public static Rectangle SetWidth(this Rectangle rect, double width) => new Rectangle(rect.Location, new Size(width, rect.Size.Height));
+
+ ///
+ /// Sets the of the of the given rectangle.
+ ///
+ /// The rectangle to modify.
+ /// The new height of the rectangle.
+ /// The modified .
+ public static Rectangle SetHeight(this Rectangle rect, double height) => new Rectangle(rect.Location, new Size(rect.Size.Width, height));
+
+ ///
+ /// Calculates the percentage of intersection of a rectangle.
+ ///
+ /// The intersecting rectangle.
+ /// The percentage of intersection.
+ public static double CalculateIntersectPercentage(this Rectangle rect, Rectangle intersectingRect)
+ {
+ if (rect.IsEmpty || intersectingRect.IsEmpty) return 0;
+
+ Rectangle intersection = rect.CalculateIntersection(intersectingRect);
+ return (intersection.Size.Width * intersection.Size.Height) / (rect.Size.Width * rect.Size.Height);
+ }
+
+ ///
+ /// Calculates the representing the intersection of this and the one provided as parameter.
+ ///
+ /// The intersecting
+ /// A new representing the intersection this and the one provided as parameter.
+ public static Rectangle CalculateIntersection(this Rectangle rect, Rectangle intersectingRectangle)
+ {
+ double x1 = Math.Max(rect.Location.X, intersectingRectangle.Location.X);
+ double x2 = Math.Min(rect.Location.X + rect.Size.Width, intersectingRectangle.Location.X + intersectingRectangle.Size.Width);
+
+ double y1 = Math.Max(rect.Location.Y, intersectingRectangle.Location.Y);
+ double y2 = Math.Min(rect.Location.Y + rect.Size.Height, intersectingRectangle.Location.Y + intersectingRectangle.Size.Height);
+
+ if ((x2 >= x1) && (y2 >= y1))
+ return new Rectangle(x1, y1, x2 - x1, y2 - y1);
+
+ return new Rectangle();
+ }
+
+ ///
+ /// Determines if the specified is contained within this .
+ ///
+ /// The to test.
+ ///
+ public static bool Contains(this Rectangle rect, Point point) => rect.Contains(point.X, point.Y);
+
+ ///
+ /// Determines if the specified location is contained within this .
+ ///
+ /// The X-location to test.
+ /// The Y-location to test.
+ ///
+ public static bool Contains(this Rectangle rect, double x, double y) => (rect.Location.X <= x) && (x < (rect.Location.X + rect.Size.Width))
+ && (rect.Location.Y <= y) && (y < (rect.Location.Y + rect.Size.Height));
+
+ ///
+ /// Determines if the specified is contained within this .
+ ///
+ /// The to test.
+ ///
+ public static bool Contains(this Rectangle rect, Rectangle rect2) => (rect.Location.X <= rect2.Location.X) && ((rect2.Location.X + rect2.Size.Width) <= (rect.Location.X + rect.Size.Width))
+ && (rect.Location.Y <= rect2.Location.Y) && ((rect2.Location.Y + rect2.Size.Height) <= (rect.Location.Y + rect.Size.Height));
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Core/Leds/Led.cs b/RGB.NET.Core/Leds/Led.cs
index b300065..27bf4ed 100644
--- a/RGB.NET.Core/Leds/Led.cs
+++ b/RGB.NET.Core/Leds/Led.cs
@@ -44,10 +44,19 @@ namespace RGB.NET.Core
set => SetProperty(ref _shapeData, value);
}
+ private Rectangle _ledRectangle;
///
/// Gets a rectangle representing the physical location of the relative to the .
///
- public Rectangle LedRectangle { get; }
+ public Rectangle LedRectangle
+ {
+ get => _ledRectangle;
+ set
+ {
+ if (SetProperty(ref _ledRectangle, value))
+ OnPropertyChanged(nameof(AbsoluteLedRectangle));
+ }
+ }
///
/// Gets a rectangle representing the physical location of the on the .
@@ -142,6 +151,12 @@ namespace RGB.NET.Core
this.Id = id;
this.LedRectangle = ledRectangle;
this.CustomData = customData;
+
+ device.PropertyChanged += (sender, args) =>
+ {
+ OnPropertyChanged(nameof(LedRectangle));
+ OnPropertyChanged(nameof(AbsoluteLedRectangle));
+ };
}
#endregion
@@ -195,7 +210,7 @@ namespace RGB.NET.Core
/// Converts a to a .
///
/// The to convert.
- public static implicit operator Rectangle(Led led) => led?.LedRectangle;
+ public static implicit operator Rectangle(Led led) => led?.LedRectangle ?? new Rectangle();
#endregion
}
diff --git a/RGB.NET.Core/Positioning/Rectangle.cs b/RGB.NET.Core/Positioning/Rectangle.cs
index ede55c3..7bf5330 100644
--- a/RGB.NET.Core/Positioning/Rectangle.cs
+++ b/RGB.NET.Core/Positioning/Rectangle.cs
@@ -8,155 +8,47 @@ using System.Linq;
namespace RGB.NET.Core
{
- ///
///
/// Represents a rectangle defined by it's position and it's size.
///
[DebuggerDisplay("[Location: {Location}, Size: {Size}]")]
- public class Rectangle : AbstractBindable
+ public struct Rectangle
{
#region Properties & Fields
- private double _x;
///
- /// Gets or sets the X-position of this .
+ /// Gets the representing the top-left corner of the .
///
- public double X
- {
- get => _x;
- set
- {
- if (SetProperty(ref _x, value))
- {
- OnPropertyChanged(nameof(Location));
- OnPropertyChanged(nameof(Center));
- }
- }
- }
-
- private double _y;
- ///
- /// Gets or sets the Y-position of this .
- ///
- public double Y
- {
- get => _y;
- set
- {
- if (SetProperty(ref _y, value))
- {
- OnPropertyChanged(nameof(Location));
- OnPropertyChanged(nameof(Center));
- }
- }
- }
-
- private double _width;
- ///
- /// Gets or sets the width of this .
- ///
- public double Width
- {
- get => _width;
- set
- {
- if (SetProperty(ref _width, Math.Max(0, value)))
- {
- OnPropertyChanged(nameof(Size));
- OnPropertyChanged(nameof(Center));
- OnPropertyChanged(nameof(IsEmpty));
- }
- }
- }
-
- private double _height;
- ///
- /// Gets or sets the height of this .
- ///
- public double Height
- {
- get => _height;
- set
- {
- if (SetProperty(ref _height, Math.Max(0, value)))
- {
- OnPropertyChanged(nameof(Size));
- OnPropertyChanged(nameof(Center));
- OnPropertyChanged(nameof(IsEmpty));
- }
- }
- }
+ public Point Location { get; }
///
- /// Gets or sets the representing the top-left corner of the .
+ /// Gets the of the .
///
- public Point Location
- {
- get => new Point(X, Y);
- set
- {
- if (Location != value)
- {
- _x = value.X;
- _y = value.Y;
-
- OnPropertyChanged(nameof(Location));
- OnPropertyChanged(nameof(Center));
- }
- }
- }
-
- ///
- /// Gets or sets the of the .
- ///
- public Size Size
- {
- get => new Size(Width, Height);
- set
- {
- if (Size != value)
- {
- _width = value.Width;
- _height = value.Height;
-
- OnPropertyChanged(nameof(Size));
- OnPropertyChanged(nameof(Center));
- OnPropertyChanged(nameof(IsEmpty));
- }
- }
- }
+ public Size Size { get; }
///
/// Gets a new representing the center-point of the .
///
- public Point Center => new Point(X + (Width / 2.0), Y + (Height / 2.0));
+ public Point Center { get; }
///
/// Gets a bool indicating if both, the width and the height of the rectangle is greater than zero.
/// True if the rectangle has a width or a height of zero; otherwise, false.
///
- public bool IsEmpty => (Width <= DoubleExtensions.TOLERANCE) || (Height <= DoubleExtensions.TOLERANCE);
+ public bool IsEmpty => (Size.Width <= DoubleExtensions.TOLERANCE) || (Size.Height <= DoubleExtensions.TOLERANCE);
#endregion
#region Constructors
- ///
- ///
- /// Initializes a new instance of the class.
- ///
- public Rectangle()
- : this(new Point(), new Size())
- { }
-
///
///
/// Initializes a new instance of the class using the provided values for ans .
///
- /// The -position of this .
- /// The -position of this .
- /// The of this .
- /// The of this .
+ /// The x-value of the of this .
+ /// The y-value of the -position of this .
+ /// The width of the of this .
+ /// The height of the of this .
public Rectangle(double x, double y, double width, double height)
: this(new Point(x, y), new Size(width, height))
{ }
@@ -170,6 +62,7 @@ namespace RGB.NET.Core
{
this.Location = location;
this.Size = size;
+ Center = new Point(Location.X + (Size.Width / 2.0), Location.Y + (Size.Height / 2.0));
}
///
@@ -205,10 +98,10 @@ namespace RGB.NET.Core
posY2 = Math.Max(posY2, rectangle.Location.Y + rectangle.Size.Height);
}
- if (hasPoint)
- InitializeFromPoints(new Point(posX, posY), new Point(posX2, posY2));
- else
- InitializeFromPoints(new Point(0, 0), new Point(0, 0));
+ (Point location, Size size) = hasPoint ? InitializeFromPoints(new Point(posX, posY), new Point(posX2, posY2)) : InitializeFromPoints(new Point(0, 0), new Point(0, 0));
+ Location = location;
+ Size = size;
+ Center = new Point(Location.X + (Size.Width / 2.0), Location.Y + (Size.Height / 2.0));
}
///
@@ -246,82 +139,27 @@ namespace RGB.NET.Core
posY2 = Math.Max(posY2, point.Y);
}
- if (hasPoint)
- InitializeFromPoints(new Point(posX, posY), new Point(posX2, posY2));
- else
- InitializeFromPoints(new Point(0, 0), new Point(0, 0));
+ (Point location, Size size) = hasPoint ? InitializeFromPoints(new Point(posX, posY), new Point(posX2, posY2)) : InitializeFromPoints(new Point(0, 0), new Point(0, 0));
+
+ Location = location;
+ Size = size;
+ Center = new Point(Location.X + (Size.Width / 2.0), Location.Y + (Size.Height / 2.0));
}
#endregion
#region Methods
- private void InitializeFromPoints(Point point1, Point point2)
+ private static (Point location, Size size) InitializeFromPoints(Point point1, Point point2)
{
double posX = Math.Min(point1.X, point2.X);
double posY = Math.Min(point1.Y, point2.Y);
double width = Math.Max(point1.X, point2.X) - posX;
double height = Math.Max(point1.Y, point2.Y) - posY;
- Location = new Point(posX, posY);
- Size = new Size(width, height);
+ return (new Point(posX, posY), new Size(width, height));
}
- ///
- /// Calculates the percentage of intersection of a rectangle.
- ///
- /// The intersecting rectangle.
- /// The percentage of intersection.
- public double CalculateIntersectPercentage(Rectangle intersectingRect)
- {
- if (IsEmpty || intersectingRect.IsEmpty) return 0;
-
- Rectangle intersection = CalculateIntersection(intersectingRect);
- return (intersection.Size.Width * intersection.Size.Height) / (Size.Width * Size.Height);
- }
-
- ///
- /// Calculates the representing the intersection of this and the one provided as parameter.
- ///
- /// The intersecting
- /// A new representing the intersection this and the one provided as parameter.
- public Rectangle CalculateIntersection(Rectangle intersectingRectangle)
- {
- double x1 = Math.Max(Location.X, intersectingRectangle.Location.X);
- double x2 = Math.Min(Location.X + Size.Width, intersectingRectangle.Location.X + intersectingRectangle.Size.Width);
-
- double y1 = Math.Max(Location.Y, intersectingRectangle.Location.Y);
- double y2 = Math.Min(Location.Y + Size.Height, intersectingRectangle.Location.Y + intersectingRectangle.Size.Height);
-
- if ((x2 >= x1) && (y2 >= y1))
- return new Rectangle(x1, y1, x2 - x1, y2 - y1);
-
- return new Rectangle();
- }
-
- ///
- /// Determines if the specified is contained within this .
- ///
- /// The to test.
- ///
- public bool Contains(Point point) => Contains(point.X, point.Y);
-
- ///
- /// Determines if the specified location is contained within this .
- ///
- /// The X-location to test.
- /// The Y-location to test.
- ///
- 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) => (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.
///
@@ -338,9 +176,6 @@ namespace RGB.NET.Core
if (!(obj is Rectangle compareRect))
return false;
- if (ReferenceEquals(this, compareRect))
- return true;
-
if (GetType() != compareRect.GetType())
return false;
@@ -371,7 +206,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) => rectangle1?.Equals(rectangle2) ?? ReferenceEquals(rectangle2, null);
+ public static bool operator ==(Rectangle rectangle1, Rectangle rectangle2) => rectangle1.Equals(rectangle2);
///
/// Returns a value that indicates whether two specified are equal.
diff --git a/RGB.NET.Core/RGBSurface.cs b/RGB.NET.Core/RGBSurface.cs
index d2933c7..1db3b08 100644
--- a/RGB.NET.Core/RGBSurface.cs
+++ b/RGB.NET.Core/RGBSurface.cs
@@ -33,8 +33,6 @@ namespace RGB.NET.Core
private readonly LinkedList _ledGroups = new LinkedList();
- private readonly Rectangle _surfaceRectangle = new Rectangle();
-
// ReSharper restore InconsistentNaming
///
@@ -50,7 +48,7 @@ namespace RGB.NET.Core
///
/// Gets a copy of the representing this .
///
- public Rectangle SurfaceRectangle => new Rectangle(_surfaceRectangle);
+ public Rectangle SurfaceRectangle { get; private set; }
///
/// Gets a list of all on this .
@@ -162,9 +160,8 @@ namespace RGB.NET.Core
case BrushCalculationMode.Relative:
Rectangle brushRectangle = new Rectangle(leds.Select(led => led.AbsoluteLedRectangle));
Point offset = new Point(-brushRectangle.Location.X, -brushRectangle.Location.Y);
- brushRectangle.Location = new Point(0, 0);
- brush.PerformRender(brushRectangle,
- leds.Select(x => new BrushRenderTarget(x, GetDeviceLedLocation(x, offset))));
+ brushRectangle = brushRectangle.SetLocation(new Point(0, 0));
+ brush.PerformRender(brushRectangle, leds.Select(x => new BrushRenderTarget(x, GetDeviceLedLocation(x, offset))));
break;
case BrushCalculationMode.Absolute:
brush.PerformRender(SurfaceRectangle, leds.Select(x => new BrushRenderTarget(x, x.AbsoluteLedRectangle)));
@@ -230,9 +227,7 @@ namespace RGB.NET.Core
private void UpdateSurfaceRectangle()
{
Rectangle devicesRectangle = new Rectangle(_devices.Select(d => new Rectangle(d.Location, d.Size)));
-
- _surfaceRectangle.Width = devicesRectangle.Location.X + devicesRectangle.Size.Width;
- _surfaceRectangle.Height = devicesRectangle.Location.Y + devicesRectangle.Size.Height;
+ SurfaceRectangle = SurfaceRectangle.SetSize(new Size(devicesRectangle.Location.X + devicesRectangle.Size.Width, devicesRectangle.Location.Y + devicesRectangle.Size.Height));
}
///
diff --git a/RGB.NET.Groups/Groups/RectangleLedGroup.cs b/RGB.NET.Groups/Groups/RectangleLedGroup.cs
index 63b5616..18ffb8c 100644
--- a/RGB.NET.Groups/Groups/RectangleLedGroup.cs
+++ b/RGB.NET.Groups/Groups/RectangleLedGroup.cs
@@ -2,7 +2,6 @@
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
// ReSharper disable UnusedMember.Global
-using System;
using System.Collections.Generic;
using System.Linq;
using RGB.NET.Core;
@@ -28,17 +27,8 @@ namespace RGB.NET.Groups
get => _rectangle;
set
{
- Rectangle oldValue = _rectangle;
if (SetProperty(ref _rectangle, value))
- {
- if (oldValue != null)
- oldValue.PropertyChanged -= RectangleChanged;
-
- if (_rectangle != null)
- _rectangle.PropertyChanged += RectangleChanged;
-
InvalidateCache();
- }
}
}
@@ -110,14 +100,12 @@ namespace RGB.NET.Groups
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() => _ledCache ?? (_ledCache = RGBSurface.Instance.Leds.Where(x => x.AbsoluteLedRectangle.CalculateIntersectPercentage(Rectangle) >= MinOverlayPercentage).ToList());
+ public override IEnumerable GetLeds() => _ledCache ??= RGBSurface.Instance.Leds.Where(x => x.AbsoluteLedRectangle.CalculateIntersectPercentage(Rectangle) >= MinOverlayPercentage).ToList();
private void InvalidateCache() => _ledCache = null;