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:
parent
6a4ebb3d2a
commit
d44223ee6a
@ -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 />
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
61
RGB.NET.Core/Positioning/IPlaceable.cs
Normal file
61
RGB.NET.Core/Positioning/IPlaceable.cs
Normal 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
|
||||
}
|
||||
}
|
||||
199
RGB.NET.Core/Positioning/Placeable.cs
Normal file
199
RGB.NET.Core/Positioning/Placeable.cs
Normal 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
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
|
||||
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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 />
|
||||
|
||||
@ -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 />
|
||||
|
||||
@ -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 />
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user