1
0
mirror of https://github.com/DarthAffe/RGB.NET.git synced 2025-12-12 17:48:31 +00:00

Added base class for location/size-handling and refactored devices and leds to make use of it

This commit is contained in:
Darth Affe 2021-02-09 23:11:01 +01:00
parent 6a4ebb3d2a
commit d44223ee6a
21 changed files with 349 additions and 322 deletions

View File

@ -13,12 +13,25 @@ namespace RGB.NET.Core
/// <summary>
/// Represents a generic RGB-device.
/// </summary>
public abstract class AbstractRGBDevice<TDeviceInfo> : AbstractBindable, IRGBDevice<TDeviceInfo>
public abstract class AbstractRGBDevice<TDeviceInfo> : Placeable, IRGBDevice<TDeviceInfo>
where TDeviceInfo : class, IRGBDeviceInfo
{
private RGBSurface? _surface;
#region Properties & Fields
RGBSurface? IRGBDevice.Surface { get; set; }
RGBSurface? IRGBDevice.Surface
{
get => _surface;
set
{
if (SetProperty(ref _surface, value))
{
if (value == null) OnDetached();
else OnAttached();
}
}
}
/// <inheritdoc />
public abstract TDeviceInfo DeviceInfo { get; }
@ -26,70 +39,6 @@ namespace RGB.NET.Core
/// <inheritdoc />
IRGBDeviceInfo IRGBDevice.DeviceInfo => DeviceInfo;
private Point _location = new(0, 0);
/// <inheritdoc />
public Point Location
{
get => _location;
set
{
if (SetProperty(ref _location, value))
UpdateActualData();
}
}
private Size _size = Size.Invalid;
/// <inheritdoc />
public Size Size
{
get => _size;
set
{
if (SetProperty(ref _size, value))
UpdateActualData();
}
}
private Size _actualSize;
/// <inheritdoc />
public Size ActualSize
{
get => _actualSize;
private set => SetProperty(ref _actualSize, value);
}
private Rectangle _deviceRectangle;
/// <inheritdoc />
public Rectangle DeviceRectangle
{
get => _deviceRectangle;
private set => SetProperty(ref _deviceRectangle, value);
}
private Scale _scale = new(1);
/// <inheritdoc />
public Scale Scale
{
get => _scale;
set
{
if (SetProperty(ref _scale, value))
UpdateActualData();
}
}
private Rotation _rotation = new(0);
/// <inheritdoc />
public Rotation Rotation
{
get => _rotation;
set
{
if (SetProperty(ref _rotation, value))
UpdateActualData();
}
}
/// <summary>
/// Gets or sets if the device needs to be flushed on every update.
/// </summary>
@ -106,11 +55,11 @@ namespace RGB.NET.Core
Led? IRGBDevice.this[LedId ledId] => LedMapping.TryGetValue(ledId, out Led? led) ? led : null;
/// <inheritdoc />
Led? IRGBDevice.this[Point location] => LedMapping.Values.FirstOrDefault(x => x.LedRectangle.Contains(location));
Led? IRGBDevice.this[Point location] => LedMapping.Values.FirstOrDefault(x => x.Boundry.Contains(location));
/// <inheritdoc />
IEnumerable<Led> IRGBDevice.this[Rectangle referenceRect, double minOverlayPercentage]
=> LedMapping.Values.Where(x => referenceRect.CalculateIntersectPercentage(x.LedRectangle) >= minOverlayPercentage);
=> LedMapping.Values.Where(x => referenceRect.CalculateIntersectPercentage(x.Boundry) >= minOverlayPercentage);
#endregion
@ -118,12 +67,6 @@ namespace RGB.NET.Core
#region Methods
private void UpdateActualData()
{
ActualSize = Size * Scale;
DeviceRectangle = new Rectangle(Location, new Rectangle(new Rectangle(Location, ActualSize).Rotate(Rotation)).Size);
}
/// <inheritdoc />
public virtual void Update(bool flushLeds = false)
{
@ -188,6 +131,18 @@ namespace RGB.NET.Core
protected virtual object? GetLedCustomData(LedId ledId) => null;
protected virtual void OnAttached()
{
if (Location == Point.Invalid) Location = new Point(0, 0);
if (Size == Size.Invalid)
{
Rectangle ledRectangle = new(this.Select(x => x.Boundry));
Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y);
}
}
protected virtual void OnDetached() { }
#region Enumerator
/// <inheritdoc />

View File

@ -9,7 +9,7 @@ namespace RGB.NET.Core
/// <summary>
/// Represents a generic RGB-device.
/// </summary>
public interface IRGBDevice : IEnumerable<Led>, IBindable, IDisposable
public interface IRGBDevice : IEnumerable<Led>, IPlaceable, IBindable, IDisposable
{
#region Properties
@ -19,38 +19,7 @@ namespace RGB.NET.Core
/// Gets generic information about the <see cref="IRGBDevice"/>.
/// </summary>
IRGBDeviceInfo DeviceInfo { get; }
/// <summary>
/// Gets or sets the location of the <see cref="IRGBDevice"/>.
/// </summary>
Point Location { get; set; }
/// <summary>
/// Gets the <see cref="Size"/> of the <see cref="IRGBDevice"/>.
/// </summary>
Size Size { get; set; }
/// <summary>
/// Gets the actual <see cref="Size"/> of the <see cref="IRGBDevice"/>.
/// This includes the <see cref="Scale"/>.
/// </summary>
Size ActualSize { get; }
/// <summary>
/// Gets a <see cref="Rectangle"/> representing the logical location of the <see cref="DeviceRectangle"/> relative to the <see cref="RGBSurface"/>.
/// </summary>
Rectangle DeviceRectangle { get; }
/// <summary>
/// Gets or sets the scale of the <see cref="IRGBDevice"/>.
/// </summary>
Scale Scale { get; set; }
/// <summary>
/// Gets or sets the rotation of the <see cref="IRGBDevice"/>.
/// </summary>
Rotation Rotation { get; set; }
#endregion
#region Indexer

View File

@ -17,7 +17,7 @@ namespace RGB.NET.Core
/// <summary>
/// Gets the <see cref="IRGBDevice"/> that caused the change. Returns null if the change isn't caused by a <see cref="IRGBDevice"/>.
/// </summary>
public IEnumerable<IRGBDevice> Devices { get; }
public IRGBDevice? Devices { get; }
/// <summary>
/// Gets a value indicating if the event is caused by the addition of a new <see cref="IRGBDevice"/> to the <see cref="RGBSurface"/>.
@ -25,9 +25,14 @@ namespace RGB.NET.Core
public bool DeviceAdded { get; }
/// <summary>
/// Gets a value indicating if the event is caused by a changed location of one of the devices on the <see cref="RGBSurface"/>.
/// Gets a value indicating if the event is caused by the removal of a <see cref="IRGBDevice"/> to the <see cref="RGBSurface"/>.
/// </summary>
public bool DeviceLocationChanged { get; }
public bool DeviceRemoved { get; }
/// <summary>
/// Gets a value indicating if the event is caused by a changed location or size of one of the <see cref="IRGBDevice"/> on the <see cref="RGBSurface"/>.
/// </summary>
public bool DeviceChanged { get; }
#endregion
@ -40,13 +45,23 @@ namespace RGB.NET.Core
/// <param name="devices">The <see cref="T:RGB.NET.Core.IRGBDevice" /> that caused the change.</param>
/// <param name="deviceAdded">A value indicating if the event is caused by the addition of a new <see cref="T:RGB.NET.Core.IRGBDevice" /> to the <see cref="T:RGB.NET.Core.RGBSurface" />.</param>
/// <param name="deviceLocationChanged">A value indicating if the event is caused by a changed location of one of the devices on the <see cref="T:RGB.NET.Core.RGBSurface" />.</param>
public SurfaceLayoutChangedEventArgs(IEnumerable<IRGBDevice> devices, bool deviceAdded, bool deviceLocationChanged)
private SurfaceLayoutChangedEventArgs(IRGBDevice? devices, bool deviceAdded, bool deviceRemoved, bool deviceChanged)
{
this.Devices = devices;
this.DeviceAdded = deviceAdded;
this.DeviceLocationChanged = deviceLocationChanged;
this.DeviceRemoved = deviceRemoved;
this.DeviceChanged = deviceChanged;
}
#endregion
#region Factory
internal static SurfaceLayoutChangedEventArgs FromAddedDevice(IRGBDevice device) => new(device, true, false, false);
internal static SurfaceLayoutChangedEventArgs FromRemovedDevice(IRGBDevice device) => new(device, false, true, false);
internal static SurfaceLayoutChangedEventArgs FromChangedDevice(IRGBDevice device) => new(device, false, false, true);
internal static SurfaceLayoutChangedEventArgs Misc() => new(null, false, false, false);
#endregion
}
}

View File

@ -1,7 +1,5 @@
// ReSharper disable MemberCanBePrivate.Global
using System;
using System.ComponentModel;
using System.Diagnostics;
namespace RGB.NET.Core
@ -11,7 +9,7 @@ namespace RGB.NET.Core
/// Represents a single LED of a RGB-device.
/// </summary>
[DebuggerDisplay("{Id} {Color}")]
public class Led : AbstractBindable
public class Led : Placeable
{
#region Properties & Fields
@ -45,80 +43,14 @@ namespace RGB.NET.Core
set => SetProperty(ref _shapeData, value);
}
private Point _location;
/// <summary>
/// Gets or sets the relative location of the <see cref="Led"/>.
/// </summary>
public Point Location
{
get => _location;
set
{
if (SetProperty(ref _location, value))
{
UpdateActualData();
UpdateAbsoluteData();
}
}
}
private Size _size;
/// <summary>
/// Gets or sets the size of the <see cref="Led"/>.
/// </summary>
public Size Size
{
get => _size;
set
{
if (SetProperty(ref _size, value))
{
UpdateActualData();
UpdateAbsoluteData();
}
}
}
private Point _actualLocation;
/// <summary>
/// Gets the actual location of the <see cref="Led"/>.
/// This includes device-scaling and rotation.
/// </summary>
public Point ActualLocation
{
get => _actualLocation;
private set => SetProperty(ref _actualLocation, value);
}
private Size _actualSize;
/// <summary>
/// Gets the actual size of the <see cref="Led"/>.
/// This includes device-scaling.
/// </summary>
public Size ActualSize
{
get => _actualSize;
private set => SetProperty(ref _actualSize, value);
}
private Rectangle _ledRectangle;
/// <summary>
/// Gets a rectangle representing the logical location of the <see cref="Led"/> relative to the <see cref="Device"/>.
/// </summary>
public Rectangle LedRectangle
{
get => _ledRectangle;
private set => SetProperty(ref _ledRectangle, value);
}
private Rectangle _absoluteLedRectangle;
private Rectangle _absoluteBoundry;
/// <summary>
/// Gets a rectangle representing the logical location of the <see cref="Led"/> on the <see cref="RGBSurface"/>.
/// </summary>
public Rectangle AbsoluteLedRectangle
public Rectangle AbsoluteBoundry
{
get => _absoluteLedRectangle;
private set => SetProperty(ref _absoluteLedRectangle, value);
get => _absoluteBoundry;
private set => SetProperty(ref _absoluteBoundry, value);
}
/// <summary>
@ -159,11 +91,6 @@ namespace RGB.NET.Core
}
}
/// <summary>
/// Gets the URI of an image of the <see cref="Led"/> or null if there is no image.
/// </summary>
public Uri? Image { get; set; }
/// <summary>
/// Gets the provider-specific data associated with this led.
/// </summary>
@ -184,59 +111,24 @@ namespace RGB.NET.Core
/// <param name="size">The size of the <see cref="Led"/>.</param>
/// <param name="customData">The provider-specific data associated with this led.</param>
internal Led(IRGBDevice device, LedId id, Point location, Size size, object? customData = null)
: base(device)
{
this.Device = device;
this.Id = id;
this.Location = location;
this.Size = size;
this.CustomData = customData;
device.PropertyChanged += DevicePropertyChanged;
}
#endregion
#region Methods
private void DevicePropertyChanged(object? sender, PropertyChangedEventArgs e)
protected override void UpdateActualPlaceableData()
{
switch (e.PropertyName)
{
case nameof(IRGBDevice.Location):
UpdateAbsoluteData();
break;
base.UpdateActualPlaceableData();
case nameof(IRGBDevice.DeviceRectangle):
UpdateActualData();
UpdateAbsoluteData();
break;
}
}
private void UpdateActualData()
{
ActualSize = Size * Device.Scale;
Point actualLocation = (Location * Device.Scale);
Rectangle ledRectangle = new(Location * Device.Scale, Size * Device.Scale);
if (Device.Rotation.IsRotated)
{
Point deviceCenter = new Rectangle(Device.ActualSize).Center;
Point actualDeviceCenter = new Rectangle(Device.DeviceRectangle.Size).Center;
Point centerOffset = new(actualDeviceCenter.X - deviceCenter.X, actualDeviceCenter.Y - deviceCenter.Y);
actualLocation = actualLocation.Rotate(Device.Rotation, new Rectangle(Device.ActualSize).Center) + centerOffset;
ledRectangle = new Rectangle(ledRectangle.Rotate(Device.Rotation, new Rectangle(Device.ActualSize).Center)).Translate(centerOffset);
}
ActualLocation = actualLocation;
LedRectangle = ledRectangle;
}
private void UpdateAbsoluteData()
{
AbsoluteLedRectangle = LedRectangle.Translate(Device.Location);
AbsoluteBoundry = Boundry.Translate(Device.Location);
}
/// <summary>
@ -285,7 +177,7 @@ namespace RGB.NET.Core
/// Converts a <see cref="Led" /> to a <see cref="Rectangle" />.
/// </summary>
/// <param name="led">The <see cref="Led"/> to convert.</param>
public static implicit operator Rectangle(Led led) => led.LedRectangle;
public static implicit operator Rectangle(Led led) => led.Boundry;
#endregion
}

View File

@ -0,0 +1,61 @@
using System;
namespace RGB.NET.Core
{
public interface IPlaceable
{
#region Properties & Fields
/// <summary>
/// Gets or sets the location of the <see cref="IPlaceable"/>.
/// </summary>
Point Location { get; set; }
/// <summary>
/// Gets the size of the <see cref="IPlaceable"/>.
/// </summary>
Size Size { get; set; }
/// <summary>
/// Gets or sets the scale of the <see cref="IPlaceable"/>.
/// </summary>
Scale Scale { get; set; }
/// <summary>
/// Gets or sets the rotation of the <see cref="IPlaceable"/>.
/// </summary>
Rotation Rotation { get; set; }
/// <summary>
/// Gets the actual location of the <see cref="IPlaceable"/>.
/// This includes the <see cref="Rotation"/>.
/// </summary>
Point ActualLocation { get; }
/// <summary>
/// Gets the actual <see cref="Size"/> of the <see cref="IPlaceable"/>.
/// This includes the <see cref="Scale"/>.
/// </summary>
Size ActualSize { get; }
/// <summary>
/// Gets a rectangle containing the whole <see cref="IPlaceable"/>.
/// This includes <see cref="Location"/>, <see cref="Size"/>, <see cref="Scale"/> and <see cref="Rotation"/>.
/// </summary>
Rectangle Boundry { get; }
#endregion
#region Events
event EventHandler<EventArgs> LocationChanged;
event EventHandler<EventArgs> SizeChanged;
event EventHandler<EventArgs> ScaleChanged;
event EventHandler<EventArgs> RotationChanged;
event EventHandler<EventArgs> ActualLocationChanged;
event EventHandler<EventArgs> ActualSizeChanged;
event EventHandler<EventArgs> BoundryChanged;
#endregion
}
}

View File

@ -0,0 +1,199 @@
using System;
namespace RGB.NET.Core
{
public class Placeable : AbstractBindable, IPlaceable
{
#region Properties & Fields
protected IPlaceable? Parent { get; }
private Point _location = Point.Invalid;
/// <inheritdoc />
public Point Location
{
get => _location;
set
{
if (SetProperty(ref _location, value))
OnLocationChanged();
}
}
private Size _size = Size.Invalid;
/// <inheritdoc />
public Size Size
{
get => _size;
set
{
if (SetProperty(ref _size, value))
OnSizeChanged();
}
}
private Scale _scale = new(1);
/// <inheritdoc />
public Scale Scale
{
get => _scale;
set
{
if (SetProperty(ref _scale, value))
OnScaleChanged();
}
}
private Rotation _rotation = new(0);
/// <inheritdoc />
public Rotation Rotation
{
get => _rotation;
set
{
if (SetProperty(ref _rotation, value))
OnRotationChanged();
}
}
private Point _actualLocation = Point.Invalid;
/// <inheritdoc />
public Point ActualLocation
{
get => _actualLocation;
private set
{
if (SetProperty(ref _actualLocation, value))
OnActualLocationChanged();
}
}
private Size _actualSize = Size.Invalid;
/// <inheritdoc />
public Size ActualSize
{
get => _actualSize;
private set
{
if (SetProperty(ref _actualSize, value))
OnActualSizeChanged();
}
}
private Rectangle _boundry = new(Point.Invalid, Point.Invalid);
/// <inheritdoc />
public Rectangle Boundry
{
get => _boundry;
private set
{
if (SetProperty(ref _boundry, value))
OnBoundryChanged();
}
}
#endregion
#region Events
public event EventHandler<EventArgs>? LocationChanged;
public event EventHandler<EventArgs>? SizeChanged;
public event EventHandler<EventArgs>? ScaleChanged;
public event EventHandler<EventArgs>? RotationChanged;
public event EventHandler<EventArgs>? ActualLocationChanged;
public event EventHandler<EventArgs>? ActualSizeChanged;
public event EventHandler<EventArgs>? BoundryChanged;
#endregion
#region Constructors
public Placeable() { }
public Placeable(IPlaceable parent)
{
this.Parent = parent;
Parent.BoundryChanged += (_, _) => UpdateActualPlaceableData();
}
public Placeable(Point location, Size size)
{
this.Location = location;
this.Size = size;
}
public Placeable(IPlaceable parent, Point location, Size size)
{
this.Parent = parent;
this.Location = location;
this.Size = size;
Parent.BoundryChanged += (_, _) => UpdateActualPlaceableData();
}
#endregion
#region Methods
protected virtual void UpdateActualPlaceableData()
{
if (Parent != null)
{
Size actualSize = Size * Parent.Scale;
Point actualLocation = (Location * Parent.Scale);
Rectangle boundry = new(actualLocation, actualSize);
if (Parent.Rotation.IsRotated)
{
Point parentCenter = new Rectangle(Parent.ActualSize).Center;
Point actualParentCenter = new Rectangle(Parent.Boundry.Size).Center;
Point centerOffset = new(actualParentCenter.X - parentCenter.X, actualParentCenter.Y - parentCenter.Y);
actualLocation = actualLocation.Rotate(Parent.Rotation, new Rectangle(Parent.ActualSize).Center) + centerOffset;
boundry = new Rectangle(boundry.Rotate(Parent.Rotation, new Rectangle(Parent.ActualSize).Center)).Translate(centerOffset);
}
ActualLocation = actualLocation;
ActualSize = actualSize;
Boundry = boundry;
}
else
{
ActualLocation = Location;
ActualSize = Size * Scale;
Boundry = new Rectangle(Location, new Rectangle(new Rectangle(Location, ActualSize).Rotate(Rotation)).Size);
}
}
protected virtual void OnLocationChanged()
{
LocationChanged?.Invoke(this, new EventArgs());
UpdateActualPlaceableData();
}
protected virtual void OnSizeChanged()
{
SizeChanged?.Invoke(this, new EventArgs());
UpdateActualPlaceableData();
}
protected virtual void OnScaleChanged()
{
ScaleChanged?.Invoke(this, new EventArgs());
UpdateActualPlaceableData();
}
protected virtual void OnRotationChanged()
{
RotationChanged?.Invoke(this, new EventArgs());
UpdateActualPlaceableData();
}
protected virtual void OnActualLocationChanged() => ActualLocationChanged?.Invoke(this, new EventArgs());
protected virtual void OnActualSizeChanged() => ActualSizeChanged?.Invoke(this, new EventArgs());
protected virtual void OnBoundryChanged() => BoundryChanged?.Invoke(this, new EventArgs());
#endregion
}
}

View File

@ -9,6 +9,7 @@
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=devices_005Cupdate/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=effects/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=events/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=events_005Cplaceable/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=exceptions/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=extensions/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=groups/@EntryIndexedValue">True</s:Boolean>

View File

@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
@ -212,13 +211,13 @@ namespace RGB.NET.Core
switch (brush.BrushCalculationMode)
{
case BrushCalculationMode.Relative:
Rectangle brushRectangle = new(leds.Select(led => led.AbsoluteLedRectangle));
Rectangle brushRectangle = new(leds.Select(led => led.AbsoluteBoundry));
Point offset = new(-brushRectangle.Location.X, -brushRectangle.Location.Y);
brushRectangle = brushRectangle.SetLocation(new Point(0, 0));
brush.PerformRender(brushRectangle, leds.Select(led => new BrushRenderTarget(led, led.AbsoluteLedRectangle.Translate(offset))));
brush.PerformRender(brushRectangle, leds.Select(led => new BrushRenderTarget(led, led.AbsoluteBoundry.Translate(offset))));
break;
case BrushCalculationMode.Absolute:
brush.PerformRender(SurfaceRectangle, leds.Select(led => new BrushRenderTarget(led, led.AbsoluteLedRectangle)));
brush.PerformRender(SurfaceRectangle, leds.Select(led => new BrushRenderTarget(led, led.AbsoluteBoundry)));
break;
default:
throw new ArgumentException();
@ -281,11 +280,13 @@ namespace RGB.NET.Core
{
lock (_devices)
{
if (_devices.Contains(device)) throw new RGBSurfaceException($"The device '{device.DeviceInfo.Manufacturer} {device.DeviceInfo.Model}' is already attached.");
if (device.Surface != null) throw new RGBSurfaceException($"The device '{device.DeviceInfo.Manufacturer} {device.DeviceInfo.Model}' is already attached to a surface.");
device.Surface = this;
device.BoundryChanged += DeviceOnBoundryChanged;
_devices.Add(device);
OnSurfaceLayoutChanged(SurfaceLayoutChangedEventArgs.FromAddedDevice(device));
}
}
@ -302,11 +303,14 @@ namespace RGB.NET.Core
{
lock (_devices)
{
if (!_devices.Contains(device)) throw new RGBSurfaceException($"The device '{device.DeviceInfo.Manufacturer} {device.DeviceInfo.Model}' isn't attached.");
if (!_devices.Contains(device)) throw new RGBSurfaceException($"The device '{device.DeviceInfo.Manufacturer} {device.DeviceInfo.Model}' isn't not attached to this surface.");
device.BoundryChanged -= DeviceOnBoundryChanged;
device.Surface = null;
_devices.Remove(device);
OnSurfaceLayoutChanged(SurfaceLayoutChangedEventArgs.FromRemovedDevice(device));
}
}
@ -325,17 +329,21 @@ namespace RGB.NET.Core
// ReSharper restore UnusedMember.Global
private void DeviceOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
private void DeviceOnBoundryChanged(object? sender, EventArgs args)
=> OnSurfaceLayoutChanged((sender is IRGBDevice device) ? SurfaceLayoutChangedEventArgs.FromChangedDevice(device) : SurfaceLayoutChangedEventArgs.Misc());
private void OnSurfaceLayoutChanged(SurfaceLayoutChangedEventArgs args)
{
UpdateSurfaceRectangle();
SurfaceLayoutChanged?.Invoke(new SurfaceLayoutChangedEventArgs((sender is IRGBDevice device) ? new[] { device } : Array.Empty<IRGBDevice>(), false, true));
SurfaceLayoutChanged?.Invoke(args);
}
private void UpdateSurfaceRectangle()
{
lock (_devices)
{
Rectangle devicesRectangle = new(_devices.Select(d => d.DeviceRectangle));
Rectangle devicesRectangle = new(_devices.Select(d => d.Boundry));
SurfaceRectangle = SurfaceRectangle.SetSize(new Size(devicesRectangle.Location.X + devicesRectangle.Size.Width, devicesRectangle.Location.Y + devicesRectangle.Size.Height));
}
}

View File

@ -49,13 +49,7 @@ namespace RGB.NET.Devices.Asus
public void Initialize(IDeviceUpdateTrigger updateTrigger)
{
InitializeLayout();
if (Size == Size.Invalid)
{
Rectangle ledRectangle = new(this.Select(x => x.LedRectangle));
Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y);
}
UpdateQueue = new AsusUpdateQueue(updateTrigger);
UpdateQueue.Initialize(DeviceInfo.Device);
}

View File

@ -52,13 +52,7 @@ namespace RGB.NET.Devices.CoolerMaster
public void Initialize(IDeviceUpdateTrigger updateTrigger)
{
InitializeLayout();
if (Size == Size.Invalid)
{
Rectangle ledRectangle = new(this.Select(x => x.LedRectangle));
Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y);
}
UpdateQueue = new CoolerMasterUpdateQueue(updateTrigger, DeviceInfo.DeviceIndex);
}

View File

@ -75,12 +75,6 @@ namespace RGB.NET.Devices.Corsair
if (led.CustomData is CorsairLedId ledId && (ledId != CorsairLedId.Invalid))
InternalLedMapping.Add(ledId, led);
}
if (Size == Size.Invalid)
{
Rectangle ledRectangle = new(this.Select(x => x.LedRectangle));
Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y);
}
}
/// <summary>

View File

@ -39,13 +39,7 @@ namespace RGB.NET.Devices.DMX.E131
int count = 0;
foreach (LedId id in _ledMappings.Keys)
AddLed(id, new Point((count++) * 10, 0), new Size(10, 10));
if (Size == Size.Invalid)
{
Rectangle ledRectangle = new(this.Select(x => x.LedRectangle));
Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y);
}
_updateQueue = new E131UpdateQueue(updateTrigger, DeviceInfo.Hostname, DeviceInfo.Port);
_updateQueue.DataPacket.SetCID(DeviceInfo.CID);
_updateQueue.DataPacket.SetUniverse(DeviceInfo.Universe);

View File

@ -51,12 +51,6 @@ namespace RGB.NET.Devices.Msi
DeviceUpdateQueue = updateQueue;
InitializeLayout(ledCount);
if (Size == Size.Invalid)
{
Rectangle ledRectangle = new(this.Select(x => x.LedRectangle));
Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y);
}
}
/// <summary>

View File

@ -50,13 +50,7 @@ namespace RGB.NET.Devices.Novation
public void Initialize(IDeviceUpdateTrigger updateTrigger)
{
InitializeLayout();
if (Size == Size.Invalid)
{
Rectangle ledRectangle = new(this.Select(x => x.LedRectangle));
Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y);
}
UpdateQueue = DeviceInfo.ColorCapabilities switch
{
NovationColorCapabilities.LimitedRG => new LimitedColorUpdateQueue(updateTrigger, DeviceInfo.DeviceId),

View File

@ -51,13 +51,7 @@ namespace RGB.NET.Devices.Razer
public void Initialize(IDeviceUpdateTrigger updateTrigger)
{
InitializeLayout();
if (Size == Size.Invalid)
{
Rectangle ledRectangle = new(this.Select(x => x.LedRectangle));
Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y);
}
UpdateQueue = CreateUpdateQueue(updateTrigger);
}

View File

@ -54,13 +54,7 @@ namespace RGB.NET.Devices.SteelSeries
int counter = 0;
foreach (KeyValuePair<LedId, SteelSeriesLedId> mapping in ledMapping)
AddLed(mapping.Key, new Point((counter++) * 10, 0), new Size(10, 10));
if (Size == Size.Invalid)
{
Rectangle ledRectangle = new(this.Select(x => x.LedRectangle));
Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y);
}
UpdateQueue = updateQueue;
}

View File

@ -54,12 +54,6 @@ namespace RGB.NET.Devices.WS281X.Arduino
{
for (int i = 0; i < ledCount; i++)
AddLed(LedId.LedStripe1 + i, new Point(i * 10, 0), new Size(10, 10));
if (Size == Size.Invalid)
{
Rectangle ledRectangle = new(this.Select(x => x.LedRectangle));
Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y);
}
}
/// <inheritdoc />

View File

@ -51,12 +51,6 @@ namespace RGB.NET.Devices.WS281X.Bitwizard
{
for (int i = 0; i < ledCount; i++)
AddLed(LedId.LedStripe1 + i, new Point(i * 10, 0), new Size(10, 10));
if (Size == Size.Invalid)
{
Rectangle ledRectangle = new(this.Select(x => x.LedRectangle));
Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y);
}
}
/// <inheritdoc />

View File

@ -54,12 +54,6 @@ namespace RGB.NET.Devices.WS281X.NodeMCU
{
for (int i = 0; i < ledCount; i++)
AddLed(LedId.LedStripe1 + i, new Point(i * 10, 0), new Size(10, 10));
if (Size == Size.Invalid)
{
Rectangle ledRectangle = new(this.Select(x => x.LedRectangle));
Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y);
}
}
/// <inheritdoc />

View File

@ -1,5 +1,4 @@
using System.Linq;
using RGB.NET.Core;
using RGB.NET.Core;
namespace RGB.NET.Devices.Wooting.Generic
{
@ -48,13 +47,7 @@ namespace RGB.NET.Devices.Wooting.Generic
public void Initialize(IDeviceUpdateTrigger updateTrigger)
{
InitializeLayout();
if (Size == Size.Invalid)
{
Rectangle ledRectangle = new(this.Select(x => x.LedRectangle));
Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y);
}
UpdateQueue = new WootingUpdateQueue(updateTrigger);
}

View File

@ -59,7 +59,7 @@ namespace RGB.NET.Groups
/// <param name="minOverlayPercentage">(optional) The minimal percentage overlay a <see cref="T:RGB.NET.Core.Led" /> must have with the <see cref="P:RGB.NET.Groups.RectangleLedGroup.Rectangle" /> to be taken into the <see cref="T:RGB.NET.Groups.RectangleLedGroup" />. (default: 0.5)</param>
/// <param name="autoAttach">(optional) Specifies whether this <see cref="T:RGB.NET.Groups.RectangleLedGroup" /> should be automatically attached or not. (default: true)</param>
public RectangleLedGroup(RGBSurface? surface, Led fromLed, Led toLed, double minOverlayPercentage = 0.5)
: this(surface, new Rectangle(fromLed.LedRectangle, toLed.LedRectangle), minOverlayPercentage)
: this(surface, new Rectangle(fromLed.Boundry, toLed.Boundry), minOverlayPercentage)
{ }
/// <inheritdoc />
@ -117,7 +117,7 @@ namespace RGB.NET.Groups
/// Gets a list containing all <see cref="T:RGB.NET.Core.Led" /> of this <see cref="T:RGB.NET.Groups.RectangleLedGroup" />.
/// </summary>
/// <returns>The list containing all <see cref="T:RGB.NET.Core.Led" /> of this <see cref="T:RGB.NET.Groups.RectangleLedGroup" />.</returns>
public override IList<Led> GetLeds() => _ledCache ??= (Surface?.Leds.Where(led => led.AbsoluteLedRectangle.CalculateIntersectPercentage(Rectangle) >= MinOverlayPercentage).ToList() ?? new List<Led>());
public override IList<Led> GetLeds() => _ledCache ??= (Surface?.Leds.Where(led => led.AbsoluteBoundry.CalculateIntersectPercentage(Rectangle) >= MinOverlayPercentage).ToList() ?? new List<Led>());
private void InvalidateCache() => _ledCache = null;