1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

169 lines
4.9 KiB
C#

using System;
using System.Collections.ObjectModel;
using System.Linq;
using Artemis.Storage.Entities.Surface;
using RGB.NET.Core;
using SkiaSharp;
using Stylet;
namespace Artemis.Core
{
public class ArtemisDevice : PropertyChangedBase
{
private ReadOnlyCollection<ArtemisLed> _leds;
private SKPath _renderPath;
private SKRect _renderRectangle;
internal ArtemisDevice(IRGBDevice rgbDevice, PluginImplementation pluginImplementation, ArtemisSurface surface)
{
RgbDevice = rgbDevice;
PluginImplementation = pluginImplementation;
Surface = surface;
DeviceEntity = new DeviceEntity();
Leds = rgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly();
Rotation = 0;
Scale = 1;
ZIndex = 1;
ApplyToEntity();
CalculateRenderProperties();
}
internal ArtemisDevice(IRGBDevice rgbDevice, PluginImplementation pluginImplementation, ArtemisSurface surface, DeviceEntity deviceEntity)
{
RgbDevice = rgbDevice;
PluginImplementation = pluginImplementation;
Surface = surface;
DeviceEntity = deviceEntity;
Leds = rgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly();
}
public SKRect RenderRectangle
{
get => _renderRectangle;
private set => SetAndNotify(ref _renderRectangle, value);
}
public SKPath RenderPath
{
get => _renderPath;
private set => SetAndNotify(ref _renderPath, value);
}
public IRGBDevice RgbDevice { get; }
public PluginImplementation PluginImplementation { get; }
public ArtemisSurface Surface { get; }
public DeviceEntity DeviceEntity { get; }
public ReadOnlyCollection<ArtemisLed> Leds
{
get => _leds;
set => SetAndNotify(ref _leds, value);
}
public double X
{
get => DeviceEntity.X;
set
{
DeviceEntity.X = value;
NotifyOfPropertyChange(nameof(X));
}
}
public double Y
{
get => DeviceEntity.Y;
set
{
DeviceEntity.Y = value;
NotifyOfPropertyChange(nameof(Y));
}
}
public double Rotation
{
get => DeviceEntity.Rotation;
set
{
DeviceEntity.Rotation = value;
NotifyOfPropertyChange(nameof(Rotation));
}
}
public double Scale
{
get => DeviceEntity.Scale;
set
{
DeviceEntity.Scale = value;
NotifyOfPropertyChange(nameof(Scale));
}
}
public int ZIndex
{
get => DeviceEntity.ZIndex;
set
{
DeviceEntity.ZIndex = value;
NotifyOfPropertyChange(nameof(ZIndex));
}
}
public override string ToString()
{
return $"[{RgbDevice.DeviceInfo.DeviceType}] {RgbDevice.DeviceInfo.DeviceName} - {X}.{Y}.{ZIndex}";
}
public event EventHandler DeviceUpdated;
protected virtual void OnDeviceUpdated()
{
DeviceUpdated?.Invoke(this, EventArgs.Empty);
}
internal void ApplyToEntity()
{
// Other properties are computed
DeviceEntity.DeviceIdentifier = RgbDevice.GetDeviceIdentifier();
}
internal void ApplyToRgbDevice()
{
RgbDevice.Rotation = DeviceEntity.Rotation;
RgbDevice.Scale = DeviceEntity.Scale;
// Workaround for device rotation not applying
if (DeviceEntity.X == 0 && DeviceEntity.Y == 0)
RgbDevice.Location = new Point(1, 1);
RgbDevice.Location = new Point(DeviceEntity.X, DeviceEntity.Y);
CalculateRenderProperties();
OnDeviceUpdated();
}
internal void CalculateRenderProperties()
{
RenderRectangle = SKRect.Create(
(RgbDevice.Location.X * Surface.Scale).RoundToInt(),
(RgbDevice.Location.Y * Surface.Scale).RoundToInt(),
(RgbDevice.DeviceRectangle.Size.Width * Surface.Scale).RoundToInt(),
(RgbDevice.DeviceRectangle.Size.Height * Surface.Scale).RoundToInt()
);
if (!Leds.Any())
return;
foreach (ArtemisLed led in Leds)
led.CalculateRenderRectangle();
SKPath path = new SKPath {FillType = SKPathFillType.Winding};
foreach (ArtemisLed artemisLed in Leds)
path.AddRect(artemisLed.AbsoluteRenderRectangle);
RenderPath = path;
}
}
}