// ReSharper disable MemberCanBePrivate.Global // ReSharper disable AutoPropertyCanBeMadeGetOnly.Global // ReSharper disable UnusedMember.Global using System; using System.Collections.Generic; using System.Linq; using RGB.NET.Core; namespace RGB.NET.Presets.Groups; /// /// /// Represents a containing which physically lay inside a . /// public sealed class RectangleLedGroup : AbstractLedGroup { #region Properties & Fields private IList? _ledCache; private Rectangle _rectangle; /// /// Gets or sets the the should be taken from. /// public Rectangle Rectangle { get => _rectangle; set { if (SetProperty(ref _rectangle, value)) InvalidateCache(); } } private double _minOverlayPercentage; /// /// Gets or sets the minimal percentage overlay a must have with the to be taken into the . /// public double MinOverlayPercentage { get => _minOverlayPercentage; set { if (SetProperty(ref _minOverlayPercentage, value)) InvalidateCache(); } } #endregion #region Constructors /// /// /// Initializes a new instance of the class. /// /// Specifies the surface to attach this group to or null if the group should not be attached on creation. /// They first to calculate the of this from. /// They second to calculate the of this from. /// (optional) The minimal percentage overlay a must have with the to be taken into the . (default: 0.5) public RectangleLedGroup(RGBSurface? surface, Led fromLed, Led toLed, double minOverlayPercentage = 0.5) : this(surface, new Rectangle(fromLed.Boundary, toLed.Boundary), minOverlayPercentage) { } /// /// /// Initializes a new instance of the class. /// /// Specifies the surface to attach this group to or null if the group should not be attached on creation. /// They first point to calculate the of this from. /// They second point to calculate the of this from. /// (optional) The minimal percentage overlay a must have with the to be taken into the . (default: 0.5) public RectangleLedGroup(RGBSurface? surface, Point fromPoint, Point toPoint, double minOverlayPercentage = 0.5) : this(surface, new Rectangle(fromPoint, toPoint), minOverlayPercentage) { } /// /// /// Initializes a new instance of the class. /// /// Specifies the surface to attach this group to or null if the group should not be attached on creation. /// The of this . /// (optional) The minimal percentage overlay a must have with the to be taken into the . (default: 0.5) public RectangleLedGroup(RGBSurface? surface, Rectangle rectangle, double minOverlayPercentage = 0.5) : base(surface) { this.Rectangle = rectangle; this.MinOverlayPercentage = minOverlayPercentage; } #endregion #region Methods /// public override void OnAttach() { base.OnAttach(); Surface!.SurfaceLayoutChanged += RGBSurfaceOnSurfaceLayoutChanged; } /// public override void OnDetach() { Surface!.SurfaceLayoutChanged -= RGBSurfaceOnSurfaceLayoutChanged; base.OnDetach(); } private void RGBSurfaceOnSurfaceLayoutChanged(SurfaceLayoutChangedEventArgs args) => InvalidateCache(); /// /// /// Gets a list containing all of this . /// /// The list containing all of this . protected override IEnumerable GetLeds() => ToList(); /// /// /// Gets a list containing all of this . /// /// The list containing all of this . public override IList ToList() => _ledCache ??= ((IList?)Surface?.Leds.Where(led => led.AbsoluteBoundary.CalculateIntersectPercentage(Rectangle) >= MinOverlayPercentage).ToList() ?? Array.Empty()); private void InvalidateCache() => _ledCache = null; #endregion }