mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Merge branch 'RGB.NET_update'
This commit is contained in:
commit
acbe994410
@ -64,18 +64,15 @@
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="RGB.NET.Brushes">
|
||||
<HintPath>..\..\..\RGB.NET\bin\net5.0\RGB.NET.Brushes.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RGB.NET.Core">
|
||||
<HintPath>..\..\..\RGB.NET\bin\net5.0\RGB.NET.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RGB.NET.Groups">
|
||||
<HintPath>..\..\..\RGB.NET\bin\net5.0\RGB.NET.Groups.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RGB.NET.Layout">
|
||||
<HintPath>..\..\..\RGB.NET\bin\net5.0\RGB.NET.Layout.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RGB.NET.Presets">
|
||||
<HintPath>..\..\..\RGB.NET\bin\net5.0\RGB.NET.Presets.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="Resources\intro-profile.json">
|
||||
|
||||
@ -8,16 +8,16 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
public class FrameRenderedEventArgs : EventArgs
|
||||
{
|
||||
internal FrameRenderedEventArgs(BitmapBrush bitmapBrush, RGBSurface rgbSurface)
|
||||
internal FrameRenderedEventArgs(SKTexture texture, RGBSurface rgbSurface)
|
||||
{
|
||||
BitmapBrush = bitmapBrush;
|
||||
Texture = texture;
|
||||
RgbSurface = rgbSurface;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the bitmap brush used to render this frame
|
||||
/// Gets the texture used to render this frame
|
||||
/// </summary>
|
||||
public BitmapBrush BitmapBrush { get; }
|
||||
public SKTexture Texture { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the RGB surface used to render this frame
|
||||
|
||||
@ -106,7 +106,7 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Gets or sets the X-position of the device
|
||||
/// </summary>
|
||||
public double X
|
||||
public float X
|
||||
{
|
||||
get => DeviceEntity.X;
|
||||
set
|
||||
@ -119,7 +119,7 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Gets or sets the Y-position of the device
|
||||
/// </summary>
|
||||
public double Y
|
||||
public float Y
|
||||
{
|
||||
get => DeviceEntity.Y;
|
||||
set
|
||||
@ -132,7 +132,7 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Gets or sets the rotation of the device
|
||||
/// </summary>
|
||||
public double Rotation
|
||||
public float Rotation
|
||||
{
|
||||
get => DeviceEntity.Rotation;
|
||||
set
|
||||
@ -145,7 +145,7 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Gets or sets the scale of the device
|
||||
/// </summary>
|
||||
public double Scale
|
||||
public float Scale
|
||||
{
|
||||
get => DeviceEntity.Scale;
|
||||
set
|
||||
@ -171,7 +171,7 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Gets or sets the scale of the red color component used for calibration
|
||||
/// </summary>
|
||||
public double RedScale
|
||||
public float RedScale
|
||||
{
|
||||
get => DeviceEntity.RedScale;
|
||||
set
|
||||
@ -184,7 +184,7 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Gets or sets the scale of the green color component used for calibration
|
||||
/// </summary>
|
||||
public double GreenScale
|
||||
public float GreenScale
|
||||
{
|
||||
get => DeviceEntity.GreenScale;
|
||||
set
|
||||
@ -197,7 +197,7 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Gets or sets the scale of the blue color component used for calibration
|
||||
/// </summary>
|
||||
public double BlueScale
|
||||
public float BlueScale
|
||||
{
|
||||
get => DeviceEntity.BlueScale;
|
||||
set
|
||||
@ -340,18 +340,20 @@ namespace Artemis.Core
|
||||
|
||||
DeviceEntity.InputIdentifiers.Clear();
|
||||
foreach (ArtemisDeviceInputIdentifier identifier in InputIdentifiers)
|
||||
{
|
||||
DeviceEntity.InputIdentifiers.Add(new DeviceInputIdentifierEntity
|
||||
{
|
||||
InputProvider = identifier.InputProvider,
|
||||
Identifier = identifier.Identifier
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
@ -361,6 +363,9 @@ namespace Artemis.Core
|
||||
foreach (DeviceInputIdentifierEntity identifierEntity in DeviceEntity.InputIdentifiers)
|
||||
InputIdentifiers.Add(new ArtemisDeviceInputIdentifier(identifierEntity.InputProvider, identifierEntity.Identifier));
|
||||
|
||||
if (!RgbDevice.ColorCorrections.Any())
|
||||
RgbDevice.ColorCorrections.Add(new ScaleColorCorrection(this));
|
||||
|
||||
CalculateRenderProperties();
|
||||
OnDeviceUpdated();
|
||||
}
|
||||
|
||||
@ -53,16 +53,7 @@ namespace Artemis.Core
|
||||
{
|
||||
return RgbLed.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the color of this led, reverting the correction done to the parent device
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Color GetOriginalColor()
|
||||
{
|
||||
return RgbLed.Color.DivideRGB(Device.RedScale, Device.GreenScale, Device.BlueScale);
|
||||
}
|
||||
|
||||
|
||||
internal void CalculateRectangles()
|
||||
{
|
||||
Rectangle = RgbLed.Boundary.ToSKRect();
|
||||
|
||||
@ -4,7 +4,6 @@ using System.Linq;
|
||||
using Artemis.Core.Services;
|
||||
using Ninject;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Groups;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace Artemis.Core.LayerBrushes
|
||||
@ -50,7 +49,7 @@ namespace Artemis.Core.LayerBrushes
|
||||
LedGroup.ZIndex = 1;
|
||||
|
||||
List<Led> missingLeds = Layer.Leds.Where(l => !LedGroup.ContainsLed(l.RgbLed)).Select(l => l.RgbLed).ToList();
|
||||
List<Led> extraLeds = LedGroup.GetLeds().Where(l => Layer.Leds.All(layerLed => layerLed.RgbLed != l)).ToList();
|
||||
List<Led> extraLeds = LedGroup.Where(l => Layer.Leds.All(layerLed => layerLed.RgbLed != l)).ToList();
|
||||
LedGroup.AddLeds(missingLeds);
|
||||
LedGroup.RemoveLeds(extraLeds);
|
||||
LedGroup.Brush = GetBrush();
|
||||
@ -79,7 +78,7 @@ namespace Artemis.Core.LayerBrushes
|
||||
throw new ArtemisCoreException("Cannot dispose RGB.NET layer brush because RgbService is not set");
|
||||
|
||||
Layer.RenderPropertiesUpdated -= LayerOnRenderPropertiesUpdated;
|
||||
LedGroup?.Detach(RgbService.Surface);
|
||||
LedGroup?.Detach();
|
||||
LedGroup = null;
|
||||
}
|
||||
|
||||
|
||||
@ -1,197 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Artemis.Core.Services;
|
||||
using RGB.NET.Core;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// The RGB.NET brush Artemis uses to map the SkiaSharp bitmap to LEDs
|
||||
/// </summary>
|
||||
public sealed class BitmapBrush : AbstractDecoratable<IBrushDecorator>, IBrush, IDisposable
|
||||
{
|
||||
private readonly object _disposeLock;
|
||||
private readonly PluginSetting<int> _sampleSizeSetting;
|
||||
private readonly IRgbService _rgbService;
|
||||
|
||||
#region Constructors
|
||||
|
||||
internal BitmapBrush(Scale scale, PluginSetting<int> sampleSizeSetting, IRgbService rgbService)
|
||||
{
|
||||
_disposeLock = new object();
|
||||
_sampleSizeSetting = sampleSizeSetting;
|
||||
_rgbService = rgbService;
|
||||
Scale = scale;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties & Fields
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsEnabled { get; set; } = true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public BrushCalculationMode BrushCalculationMode { get; set; } = BrushCalculationMode.Absolute;
|
||||
|
||||
/// <inheritdoc />
|
||||
public double Brightness { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public double Opacity { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IList<IColorCorrection> ColorCorrections { get; } = new List<IColorCorrection>();
|
||||
|
||||
/// <inheritdoc />
|
||||
public Rectangle RenderedRectangle { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public Dictionary<BrushRenderTarget, Color> RenderedTargets { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the desired scale of the bitmap brush
|
||||
/// </summary>
|
||||
public Scale Scale { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last rendered scale of the bitmap brush
|
||||
/// </summary>
|
||||
public Scale RenderedScale { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the bitmap used to sample the brush
|
||||
/// </summary>
|
||||
public SKBitmap? Bitmap { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
public void PerformRender(Rectangle rectangle, IEnumerable<BrushRenderTarget> renderTargets)
|
||||
{
|
||||
lock (_disposeLock)
|
||||
{
|
||||
// Can happen during surface change
|
||||
if (IsDisposed)
|
||||
return;
|
||||
|
||||
if (RenderedRectangle != rectangle || RenderedScale != Scale)
|
||||
Bitmap = null;
|
||||
|
||||
RenderedRectangle = rectangle;
|
||||
RenderedScale = Scale;
|
||||
RenderedTargets.Clear();
|
||||
|
||||
if (Bitmap == null)
|
||||
CreateBitmap(RenderedRectangle);
|
||||
|
||||
if (_sampleSizeSetting.Value == 1)
|
||||
TakeCenter(renderTargets);
|
||||
else
|
||||
TakeSamples(renderTargets);
|
||||
}
|
||||
}
|
||||
|
||||
private void TakeCenter(IEnumerable<BrushRenderTarget> renderTargets)
|
||||
{
|
||||
if (Bitmap == null)
|
||||
return;
|
||||
|
||||
foreach (BrushRenderTarget renderTarget in renderTargets)
|
||||
{
|
||||
Point scaledLocation = renderTarget.Point * Scale;
|
||||
if (scaledLocation.X < Bitmap.Width && scaledLocation.Y < Bitmap.Height)
|
||||
{
|
||||
Color pixel = Bitmap.GetPixel(scaledLocation.X.RoundToInt(), scaledLocation.Y.RoundToInt()).ToRgbColor();
|
||||
ArtemisDevice? artemisDevice = _rgbService.GetLed(renderTarget.Led)?.Device;
|
||||
if (artemisDevice != null)
|
||||
pixel = pixel.MultiplyRGB(artemisDevice.RedScale, artemisDevice.GreenScale, artemisDevice.BlueScale);
|
||||
RenderedTargets[renderTarget] = pixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void TakeSamples(IEnumerable<BrushRenderTarget> renderTargets)
|
||||
{
|
||||
if (Bitmap == null)
|
||||
return;
|
||||
|
||||
int sampleSize = _sampleSizeSetting.Value;
|
||||
int sampleDepth = Math.Sqrt(sampleSize).RoundToInt();
|
||||
|
||||
int bitmapWidth = Bitmap.Width;
|
||||
int bitmapHeight = Bitmap.Height;
|
||||
|
||||
using SKPixmap pixmap = Bitmap.PeekPixels();
|
||||
foreach (BrushRenderTarget renderTarget in renderTargets)
|
||||
{
|
||||
// SKRect has all the good stuff we need
|
||||
int left = (int) ((renderTarget.Rectangle.Location.X + 4) * Scale.Horizontal);
|
||||
int top = (int) ((renderTarget.Rectangle.Location.Y + 4) * Scale.Vertical);
|
||||
int width = (int) ((renderTarget.Rectangle.Size.Width - 8) * Scale.Horizontal);
|
||||
int height = (int) ((renderTarget.Rectangle.Size.Height - 8) * Scale.Vertical);
|
||||
|
||||
int verticalSteps = height / (sampleDepth - 1);
|
||||
int horizontalSteps = width / (sampleDepth - 1);
|
||||
|
||||
int a = 0, r = 0, g = 0, b = 0;
|
||||
for (int horizontalStep = 0; horizontalStep < sampleDepth; horizontalStep++)
|
||||
{
|
||||
for (int verticalStep = 0; verticalStep < sampleDepth; verticalStep++)
|
||||
{
|
||||
int x = left + horizontalSteps * horizontalStep;
|
||||
int y = top + verticalSteps * verticalStep;
|
||||
if (x < 0 || x >= bitmapWidth || y < 0 || y >= bitmapHeight)
|
||||
continue;
|
||||
|
||||
SKColor color = pixmap.GetPixelColor(x, y);
|
||||
a += color.Alpha;
|
||||
r += color.Red;
|
||||
g += color.Green;
|
||||
b += color.Blue;
|
||||
|
||||
// Uncomment to view the sample pixels in the debugger, need a checkbox in the actual debugger but this was a quickie
|
||||
// Bitmap.SetPixel(x, y, new SKColor(0, 255, 0));
|
||||
}
|
||||
}
|
||||
|
||||
Color pixel = new(a / sampleSize, r / sampleSize, g / sampleSize, b / sampleSize);
|
||||
|
||||
ArtemisDevice? artemisDevice = _rgbService.GetLed(renderTarget.Led)?.Device;
|
||||
if (artemisDevice is not null)
|
||||
pixel = pixel.MultiplyRGB(artemisDevice.RedScale, artemisDevice.GreenScale, artemisDevice.BlueScale);
|
||||
|
||||
RenderedTargets[renderTarget] = pixel;
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateBitmap(Rectangle rectangle)
|
||||
{
|
||||
double width = Math.Min((rectangle.Location.X + rectangle.Size.Width) * Scale.Horizontal, 4096);
|
||||
double height = Math.Min((rectangle.Location.Y + rectangle.Size.Height) * Scale.Vertical, 4096);
|
||||
Bitmap = new SKBitmap(new SKImageInfo(width.RoundToInt(), height.RoundToInt(), SKColorType.Rgb888x));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void PerformFinalize()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
lock (_disposeLock)
|
||||
{
|
||||
Bitmap?.Dispose();
|
||||
IsDisposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsDisposed { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
53
src/Artemis.Core/RGB.NET/SKTexture.cs
Normal file
53
src/Artemis.Core/RGB.NET/SKTexture.cs
Normal file
@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Presets.Textures.Sampler;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a SkiaSharp-based RGB.NET PixelTexture
|
||||
/// </summary>
|
||||
public sealed class SKTexture : PixelTexture<byte>, IDisposable
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
internal SKTexture(SKBitmap bitmap)
|
||||
: base(bitmap.Width, bitmap.Height, 4, new AverageByteSampler())
|
||||
{
|
||||
Bitmap = bitmap;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override Color GetColor(in ReadOnlySpan<byte> pixel)
|
||||
{
|
||||
return new(pixel[0], pixel[1], pixel[2]);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties & Fields
|
||||
|
||||
/// <summary>
|
||||
/// Gets the SKBitmap backing this texture
|
||||
/// </summary>
|
||||
public SKBitmap Bitmap { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the color data in RGB format
|
||||
/// </summary>
|
||||
protected override ReadOnlySpan<byte> Data => Bitmap.GetPixelSpan();
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
Bitmap.Dispose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
19
src/Artemis.Core/RGB.NET/ScaleColorCorrection.cs
Normal file
19
src/Artemis.Core/RGB.NET/ScaleColorCorrection.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using RGB.NET.Core;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
internal class ScaleColorCorrection : IColorCorrection
|
||||
{
|
||||
private readonly ArtemisDevice _device;
|
||||
|
||||
public ScaleColorCorrection(ArtemisDevice device)
|
||||
{
|
||||
_device = device;
|
||||
}
|
||||
|
||||
public void ApplyTo(ref Color color)
|
||||
{
|
||||
color = color.MultiplyRGB(_device.RedScale, _device.GreenScale, _device.BlueScale);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,16 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Ninject;
|
||||
using Artemis.Core.Services.Core;
|
||||
using Artemis.Storage;
|
||||
using HidSharp;
|
||||
using Newtonsoft.Json;
|
||||
using Ninject;
|
||||
using RGB.NET.Core;
|
||||
using Serilog;
|
||||
@ -38,6 +35,8 @@ namespace Artemis.Core.Services
|
||||
private List<BaseDataModelExpansion> _dataModelExpansions = new();
|
||||
private DateTime _lastExceptionLog;
|
||||
private List<Module> _modules = new();
|
||||
private SKBitmap? _bitmap;
|
||||
private readonly object _bitmapLock = new();
|
||||
|
||||
// ReSharper disable UnusedParameter.Local
|
||||
public CoreService(IKernel kernel,
|
||||
@ -66,11 +65,14 @@ namespace Artemis.Core.Services
|
||||
|
||||
_rgbService.Surface.Updating += SurfaceOnUpdating;
|
||||
_rgbService.Surface.Updated += SurfaceOnUpdated;
|
||||
_rgbService.Surface.SurfaceLayoutChanged += SurfaceOnSurfaceLayoutChanged;
|
||||
_loggingLevel.SettingChanged += (sender, args) => ApplyLoggingLevel();
|
||||
_renderScale.SettingChanged += RenderScaleSettingChanged;
|
||||
|
||||
_pluginManagementService.PluginFeatureEnabled += (sender, args) => UpdatePluginCache();
|
||||
_pluginManagementService.PluginFeatureDisabled += (sender, args) => UpdatePluginCache();
|
||||
}
|
||||
|
||||
// ReSharper restore UnusedParameter.Local
|
||||
|
||||
public TimeSpan FrameTime { get; private set; }
|
||||
@ -169,8 +171,8 @@ namespace Artemis.Core.Services
|
||||
string[] parts = argument.Split('=');
|
||||
if (parts.Length == 2 && Enum.TryParse(typeof(LogEventLevel), parts[1], true, out object? logLevelArgument))
|
||||
{
|
||||
_logger.Information("Setting logging level to {loggingLevel} from startup argument", (LogEventLevel) logLevelArgument!);
|
||||
LoggerProvider.LoggingLevelSwitch.MinimumLevel = (LogEventLevel) logLevelArgument;
|
||||
_logger.Information("Setting logging level to {loggingLevel} from startup argument", (LogEventLevel)logLevelArgument!);
|
||||
LoggerProvider.LoggingLevelSwitch.MinimumLevel = (LogEventLevel)logLevelArgument;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -214,23 +216,22 @@ namespace Artemis.Core.Services
|
||||
foreach (Module module in modules)
|
||||
module.InternalUpdate(args.DeltaTime);
|
||||
|
||||
// If there is no ready bitmap brush, skip the frame
|
||||
if (_rgbService.BitmapBrush == null)
|
||||
return;
|
||||
|
||||
lock (_rgbService.BitmapBrush)
|
||||
lock (_bitmapLock)
|
||||
{
|
||||
if (_rgbService.BitmapBrush.Bitmap == null)
|
||||
return;
|
||||
if (_bitmap == null)
|
||||
{
|
||||
_bitmap = CreateBitmap();
|
||||
_rgbService.UpdateTexture(_bitmap);
|
||||
}
|
||||
|
||||
// Render all active modules
|
||||
using SKCanvas canvas = new(_rgbService.BitmapBrush.Bitmap);
|
||||
canvas.Scale((float) _renderScale.Value);
|
||||
using SKCanvas canvas = new(_bitmap);
|
||||
canvas.Scale((float)_renderScale.Value);
|
||||
canvas.Clear(new SKColor(0, 0, 0));
|
||||
if (!ModuleRenderingDisabled)
|
||||
// While non-activated modules may be updated above if they expand the main data model, they may never render
|
||||
foreach (Module module in modules.Where(m => m.IsActivated))
|
||||
module.InternalRender(args.DeltaTime, canvas, _rgbService.BitmapBrush.Bitmap.Info);
|
||||
module.InternalRender(args.DeltaTime, canvas, _bitmap.Info);
|
||||
|
||||
OnFrameRendering(new FrameRenderingEventArgs(canvas, args.DeltaTime, _rgbService.Surface));
|
||||
}
|
||||
@ -248,6 +249,24 @@ namespace Artemis.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
private SKBitmap CreateBitmap()
|
||||
{
|
||||
float width = MathF.Min(_rgbService.Surface.Boundary.Size.Width * (float)_renderScale.Value, 4096);
|
||||
float height = MathF.Min(_rgbService.Surface.Boundary.Size.Height * (float)_renderScale.Value, 4096);
|
||||
return new SKBitmap(new SKImageInfo(width.RoundToInt(), height.RoundToInt(), SKColorType.Rgb888x));
|
||||
}
|
||||
|
||||
private void InvalidateBitmap()
|
||||
{
|
||||
lock (_bitmapLock)
|
||||
{
|
||||
_bitmap = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void SurfaceOnSurfaceLayoutChanged(SurfaceLayoutChangedEventArgs args) => InvalidateBitmap();
|
||||
private void RenderScaleSettingChanged(object? sender, EventArgs e) => InvalidateBitmap();
|
||||
|
||||
private void LogUpdateExceptions()
|
||||
{
|
||||
// Only log update exceptions every 10 seconds to avoid spamming the logs
|
||||
@ -271,7 +290,7 @@ namespace Artemis.Core.Services
|
||||
if (_rgbService.IsRenderPaused)
|
||||
return;
|
||||
|
||||
OnFrameRendered(new FrameRenderedEventArgs(_rgbService.BitmapBrush!, _rgbService.Surface));
|
||||
OnFrameRendered(new FrameRenderedEventArgs(_rgbService.Texture!, _rgbService.Surface));
|
||||
}
|
||||
|
||||
#region Events
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using RGB.NET.Brushes;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Groups;
|
||||
|
||||
namespace Artemis.Core.Services
|
||||
{
|
||||
@ -33,7 +31,7 @@ namespace Artemis.Core.Services
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(200);
|
||||
ledGroup.Detach(_rgbService.Surface);
|
||||
ledGroup.Detach();
|
||||
|
||||
if (blinkCount < 5)
|
||||
{
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using RGB.NET.Core;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace Artemis.Core.Services
|
||||
{
|
||||
@ -31,9 +32,14 @@ namespace Artemis.Core.Services
|
||||
RGBSurface Surface { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the bitmap brush used to convert the rendered frame to LED-colors
|
||||
/// Gets the texture brush used to convert the rendered frame to LED-colors
|
||||
/// </summary>
|
||||
BitmapBrush? BitmapBrush { get; }
|
||||
TextureBrush TextureBrush { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the texture used to convert the rendered frame to LED-colors
|
||||
/// </summary>
|
||||
SKTexture? Texture { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the update trigger that drives the render loop
|
||||
@ -45,6 +51,12 @@ namespace Artemis.Core.Services
|
||||
/// </summary>
|
||||
bool IsRenderPaused { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Recreates the Texture to use the given <see cref="SKBitmap"/>
|
||||
/// </summary>
|
||||
/// <param name="bitmap"></param>
|
||||
void UpdateTexture(SKBitmap bitmap);
|
||||
|
||||
/// <summary>
|
||||
/// Adds the given device provider to the <see cref="Surface" />
|
||||
/// </summary>
|
||||
|
||||
@ -7,8 +7,8 @@ using Artemis.Core.Services.Models;
|
||||
using Artemis.Storage.Entities.Surface;
|
||||
using Artemis.Storage.Repositories.Interfaces;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Groups;
|
||||
using Serilog;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace Artemis.Core.Services
|
||||
{
|
||||
@ -24,9 +24,7 @@ namespace Artemis.Core.Services
|
||||
private readonly ILogger _logger;
|
||||
private readonly IPluginManagementService _pluginManagementService;
|
||||
private readonly IDeviceRepository _deviceRepository;
|
||||
private readonly PluginSetting<double> _renderScaleSetting;
|
||||
private readonly PluginSetting<int> _targetFrameRateSetting;
|
||||
private readonly PluginSetting<int> _sampleSizeSetting;
|
||||
private ListLedGroup? _surfaceLedGroup;
|
||||
private bool _modifyingProviders;
|
||||
|
||||
@ -35,21 +33,19 @@ namespace Artemis.Core.Services
|
||||
_logger = logger;
|
||||
_pluginManagementService = pluginManagementService;
|
||||
_deviceRepository = deviceRepository;
|
||||
_renderScaleSetting = settingsService.GetSetting("Core.RenderScale", 0.5);
|
||||
_targetFrameRateSetting = settingsService.GetSetting("Core.TargetFrameRate", 25);
|
||||
_sampleSizeSetting = settingsService.GetSetting("Core.SampleSize", 1);
|
||||
|
||||
Surface = new RGBSurface();
|
||||
|
||||
// Let's throw these for now
|
||||
Surface.Exception += SurfaceOnException;
|
||||
_renderScaleSetting.SettingChanged += RenderScaleSettingOnSettingChanged;
|
||||
Surface.SurfaceLayoutChanged += SurfaceOnLayoutChanged;
|
||||
_targetFrameRateSetting.SettingChanged += TargetFrameRateSettingOnSettingChanged;
|
||||
_enabledDevices = new List<ArtemisDevice>();
|
||||
_devices = new List<ArtemisDevice>();
|
||||
_ledMap = new Dictionary<Led, ArtemisLed>();
|
||||
|
||||
UpdateTrigger = new TimerUpdateTrigger {UpdateFrequency = 1.0 / _targetFrameRateSetting.Value};
|
||||
UpdateTrigger = new TimerUpdateTrigger { UpdateFrequency = 1.0 / _targetFrameRateSetting.Value };
|
||||
Surface.RegisterUpdateTrigger(UpdateTrigger);
|
||||
}
|
||||
|
||||
@ -61,7 +57,8 @@ namespace Artemis.Core.Services
|
||||
public RGBSurface Surface { get; set; }
|
||||
|
||||
public TimerUpdateTrigger UpdateTrigger { get; }
|
||||
public BitmapBrush? BitmapBrush { get; private set; }
|
||||
public TextureBrush TextureBrush { get; private set; } = new(ITexture.Empty) { CalculationMode = RenderMode.Absolute };
|
||||
public SKTexture? Texture { get; private set; }
|
||||
|
||||
public bool IsRenderPaused { get; set; }
|
||||
|
||||
@ -104,7 +101,7 @@ namespace Artemis.Core.Services
|
||||
finally
|
||||
{
|
||||
_modifyingProviders = false;
|
||||
UpdateBitmapBrush();
|
||||
UpdateLedGroup();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -132,12 +129,23 @@ namespace Artemis.Core.Services
|
||||
finally
|
||||
{
|
||||
_modifyingProviders = false;
|
||||
UpdateBitmapBrush();
|
||||
UpdateLedGroup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateBitmapBrush()
|
||||
public void UpdateTexture(SKBitmap bitmap)
|
||||
{
|
||||
SKTexture? oldTexture = Texture;
|
||||
Texture = new SKTexture(bitmap);
|
||||
TextureBrush.Texture = Texture;
|
||||
|
||||
oldTexture?.Dispose();
|
||||
}
|
||||
|
||||
private void SurfaceOnLayoutChanged(SurfaceLayoutChangedEventArgs args) => UpdateLedGroup();
|
||||
|
||||
private void UpdateLedGroup()
|
||||
{
|
||||
lock (_devices)
|
||||
{
|
||||
@ -146,11 +154,9 @@ namespace Artemis.Core.Services
|
||||
|
||||
_ledMap = new Dictionary<Led, ArtemisLed>(_devices.SelectMany(d => d.Leds).ToDictionary(l => l.RgbLed));
|
||||
|
||||
if (_surfaceLedGroup == null || BitmapBrush == null)
|
||||
if (_surfaceLedGroup == null)
|
||||
{
|
||||
// Apply the application wide brush and decorator
|
||||
BitmapBrush = new BitmapBrush(new Scale(_renderScaleSetting.Value), _sampleSizeSetting, this);
|
||||
_surfaceLedGroup = new ListLedGroup(Surface, LedMap.Select(l => l.Key)) {Brush = BitmapBrush};
|
||||
_surfaceLedGroup = new ListLedGroup(Surface, LedMap.Select(l => l.Key)) { Brush = TextureBrush };
|
||||
OnLedsChanged();
|
||||
return;
|
||||
}
|
||||
@ -158,11 +164,10 @@ namespace Artemis.Core.Services
|
||||
lock (_surfaceLedGroup)
|
||||
{
|
||||
// Clean up the old background
|
||||
_surfaceLedGroup.Detach(Surface);
|
||||
_surfaceLedGroup.Detach();
|
||||
|
||||
// Apply the application wide brush and decorator
|
||||
BitmapBrush.Scale = new Scale(_renderScaleSetting.Value);
|
||||
_surfaceLedGroup = new ListLedGroup(Surface, LedMap.Select(l => l.Key)) {Brush = BitmapBrush};
|
||||
_surfaceLedGroup = new ListLedGroup(Surface, LedMap.Select(l => l.Key)) { Brush = TextureBrush };
|
||||
OnLedsChanged();
|
||||
}
|
||||
}
|
||||
@ -234,10 +239,8 @@ namespace Artemis.Core.Services
|
||||
public void ApplyDeviceLayout(ArtemisDevice device, ArtemisLayout layout, bool createMissingLeds, bool removeExessiveLeds)
|
||||
{
|
||||
device.ApplyLayout(layout, createMissingLeds, removeExessiveLeds);
|
||||
// Applying layouts can affect LEDs, update LED group
|
||||
UpdateBitmapBrush();
|
||||
}
|
||||
|
||||
|
||||
public ArtemisDevice? GetDevice(IRGBDevice rgbDevice)
|
||||
{
|
||||
return _devices.FirstOrDefault(d => d.RgbDevice == rgbDevice);
|
||||
@ -259,7 +262,6 @@ namespace Artemis.Core.Services
|
||||
device.ApplyToEntity();
|
||||
_deviceRepository.Save(device.DeviceEntity);
|
||||
|
||||
UpdateBitmapBrush();
|
||||
OnDeviceAdded(new DeviceEventArgs(device));
|
||||
}
|
||||
|
||||
@ -273,7 +275,6 @@ namespace Artemis.Core.Services
|
||||
device.ApplyToEntity();
|
||||
_deviceRepository.Save(device.DeviceEntity);
|
||||
|
||||
UpdateBitmapBrush();
|
||||
OnDeviceRemoved(new DeviceEventArgs(device));
|
||||
}
|
||||
|
||||
@ -298,7 +299,6 @@ namespace Artemis.Core.Services
|
||||
if (device.IsEnabled)
|
||||
_enabledDevices.Remove(device);
|
||||
|
||||
UpdateBitmapBrush();
|
||||
OnDeviceRemoved(new DeviceEventArgs(device));
|
||||
}
|
||||
|
||||
@ -349,12 +349,6 @@ namespace Artemis.Core.Services
|
||||
|
||||
#region Event handlers
|
||||
|
||||
private void RenderScaleSettingOnSettingChanged(object? sender, EventArgs e)
|
||||
{
|
||||
// The surface hasn't changed so we can safely reuse it
|
||||
UpdateBitmapBrush();
|
||||
}
|
||||
|
||||
private void TargetFrameRateSettingOnSettingChanged(object? sender, EventArgs e)
|
||||
{
|
||||
UpdateTrigger.UpdateFrequency = 1.0 / _targetFrameRateSetting.Value;
|
||||
|
||||
@ -95,8 +95,8 @@ namespace Artemis.Core.Services.Models
|
||||
surfaceArrangementType.Arrange(devices);
|
||||
|
||||
// See if we need to move the surface to keep X and Y values positive
|
||||
double x = devices.Min(d => d.RgbDevice.Location.X);
|
||||
double y = devices.Min(d => d.RgbDevice.Location.Y);
|
||||
float x = devices.Min(d => d.RgbDevice.Location.X);
|
||||
float y = devices.Min(d => d.RgbDevice.Location.Y);
|
||||
if (x < 0)
|
||||
{
|
||||
foreach (ArtemisDevice surfaceDevice in devices)
|
||||
|
||||
@ -52,11 +52,11 @@ namespace Artemis.Core.Services.Models
|
||||
if (stackVertically)
|
||||
{
|
||||
artemisDevice.X = previous.X;
|
||||
artemisDevice.Y = previous.RgbDevice.Location.Y + previous.RgbDevice.Size.Height + MarginTop / 2.0;
|
||||
artemisDevice.Y = previous.RgbDevice.Location.Y + previous.RgbDevice.Size.Height + MarginTop / 2f;
|
||||
}
|
||||
else
|
||||
{
|
||||
artemisDevice.X = previous.RgbDevice.Location.X + previous.RgbDevice.Size.Width + MarginLeft / 2.0;
|
||||
artemisDevice.X = previous.RgbDevice.Location.X + previous.RgbDevice.Size.Width + MarginLeft / 2f;
|
||||
artemisDevice.Y = previous.Y;
|
||||
}
|
||||
}
|
||||
@ -66,7 +66,7 @@ namespace Artemis.Core.Services.Models
|
||||
{
|
||||
HorizontalArrangementPosition.Left => startPoint.X - artemisDevice.RgbDevice.Size.Width - MarginRight,
|
||||
HorizontalArrangementPosition.Right => startPoint.X + MarginLeft,
|
||||
HorizontalArrangementPosition.Center => startPoint.X - artemisDevice.RgbDevice.Size.Width / 2,
|
||||
HorizontalArrangementPosition.Center => startPoint.X - artemisDevice.RgbDevice.Size.Width / 2f,
|
||||
HorizontalArrangementPosition.Equal => startPoint.X,
|
||||
_ => artemisDevice.X
|
||||
};
|
||||
@ -74,7 +74,7 @@ namespace Artemis.Core.Services.Models
|
||||
{
|
||||
VerticalArrangementPosition.Top => startPoint.Y - artemisDevice.RgbDevice.Size.Height - MarginBottom,
|
||||
VerticalArrangementPosition.Bottom => startPoint.Y + MarginTop,
|
||||
VerticalArrangementPosition.Center => startPoint.Y - artemisDevice.RgbDevice.Size.Height / 2,
|
||||
VerticalArrangementPosition.Center => startPoint.Y - artemisDevice.RgbDevice.Size.Height / 2f,
|
||||
VerticalArrangementPosition.Equal => startPoint.Y,
|
||||
_ => artemisDevice.X
|
||||
};
|
||||
|
||||
@ -62,18 +62,18 @@ namespace Artemis.Core.Services.Models
|
||||
if (!devices.Any())
|
||||
return new Point();
|
||||
|
||||
double x = horizontalPosition switch
|
||||
float x = horizontalPosition switch
|
||||
{
|
||||
HorizontalArrangementPosition.Left => devices.Min(d => d.RgbDevice.Location.X) - (AppliedConfiguration?.MarginLeft ?? 0.0),
|
||||
HorizontalArrangementPosition.Right => devices.Max(d => d.RgbDevice.Location.X + d.RgbDevice.Size.Width) + (AppliedConfiguration?.MarginRight ?? 0.0),
|
||||
HorizontalArrangementPosition.Left => devices.Min(d => d.RgbDevice.Location.X) - (AppliedConfiguration?.MarginLeft ?? 0.0f),
|
||||
HorizontalArrangementPosition.Right => devices.Max(d => d.RgbDevice.Location.X + d.RgbDevice.Size.Width) + (AppliedConfiguration?.MarginRight ?? 0.0f),
|
||||
HorizontalArrangementPosition.Center => devices.First().RgbDevice.Boundary.Center.X,
|
||||
HorizontalArrangementPosition.Equal => devices.First().RgbDevice.Location.X,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(horizontalPosition), horizontalPosition, null)
|
||||
};
|
||||
double y = verticalPosition switch
|
||||
float y = verticalPosition switch
|
||||
{
|
||||
VerticalArrangementPosition.Top => devices.Min(d => d.RgbDevice.Location.Y) - (AppliedConfiguration?.MarginTop ?? 0.0),
|
||||
VerticalArrangementPosition.Bottom => devices.Max(d => d.RgbDevice.Location.Y + d.RgbDevice.Size.Height) + (AppliedConfiguration?.MarginBottom ?? 0.0),
|
||||
VerticalArrangementPosition.Top => devices.Min(d => d.RgbDevice.Location.Y) - (AppliedConfiguration?.MarginTop ?? 0.0f),
|
||||
VerticalArrangementPosition.Bottom => devices.Max(d => d.RgbDevice.Location.Y + d.RgbDevice.Size.Height) + (AppliedConfiguration?.MarginBottom ?? 0.0f),
|
||||
VerticalArrangementPosition.Center => devices.First().RgbDevice.Boundary.Center.Y,
|
||||
VerticalArrangementPosition.Equal => devices.First().RgbDevice.Location.Y,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(verticalPosition), verticalPosition, null)
|
||||
|
||||
@ -10,14 +10,14 @@ namespace Artemis.Storage.Entities.Surface
|
||||
}
|
||||
|
||||
public string Id { get; set; }
|
||||
public double X { get; set; }
|
||||
public double Y { get; set; }
|
||||
public double Rotation { get; set; }
|
||||
public double Scale { get; set; }
|
||||
public float X { get; set; }
|
||||
public float Y { get; set; }
|
||||
public float Rotation { get; set; }
|
||||
public float Scale { get; set; }
|
||||
public int ZIndex { get; set; }
|
||||
public double RedScale { get; set; }
|
||||
public double GreenScale { get; set; }
|
||||
public double BlueScale { get; set; }
|
||||
public float RedScale { get; set; }
|
||||
public float GreenScale { get; set; }
|
||||
public float BlueScale { get; set; }
|
||||
public bool IsEnabled { get; set; }
|
||||
|
||||
public int PhysicalLayout { get; set; }
|
||||
|
||||
@ -6,6 +6,7 @@ using System.Windows.Media.Imaging;
|
||||
using Artemis.Core;
|
||||
using RGB.NET.Core;
|
||||
using Color = System.Windows.Media.Color;
|
||||
using SolidColorBrush = System.Windows.Media.SolidColorBrush;
|
||||
|
||||
namespace Artemis.UI.Shared
|
||||
{
|
||||
@ -26,7 +27,7 @@ namespace Artemis.UI.Shared
|
||||
|
||||
if (Led.Layout?.Image != null && File.Exists(Led.Layout.Image.LocalPath))
|
||||
LedImage = new BitmapImage(Led.Layout.Image);
|
||||
|
||||
|
||||
CreateLedGeometry();
|
||||
}
|
||||
|
||||
@ -43,10 +44,9 @@ namespace Artemis.UI.Shared
|
||||
|
||||
_renderColorBrush ??= new SolidColorBrush();
|
||||
|
||||
RGB.NET.Core.Color originalColor = Led.GetOriginalColor();
|
||||
byte r = originalColor.GetR();
|
||||
byte g = originalColor.GetG();
|
||||
byte b = originalColor.GetB();
|
||||
byte r = Led.RgbLed.Color.GetR();
|
||||
byte g = Led.RgbLed.Color.GetG();
|
||||
byte b = Led.RgbLed.Color.GetB();
|
||||
|
||||
_renderColor.A = isDimmed ? 100 : 255;
|
||||
_renderColor.R = r;
|
||||
|
||||
@ -56,17 +56,11 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<!-- TODO: Remove when moving to Nuget, this is so the plugin templates have the DLL to reference -->
|
||||
<Reference Include="RGB.NET.Brushes">
|
||||
<HintPath>..\..\..\RGB.NET\bin\net5.0\RGB.NET.Brushes.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RGB.NET.Core">
|
||||
<HintPath>..\..\..\RGB.NET\bin\net5.0\RGB.NET.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RGB.NET.Groups">
|
||||
<HintPath>..\..\..\RGB.NET\bin\net5.0\RGB.NET.Groups.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RGB.NET.Layout">
|
||||
<HintPath>..\..\..\RGB.NET\bin\net5.0\RGB.NET.Layout.dll</HintPath>
|
||||
<HintPath>..\..\..\RGB.NET\bin\net5.0\RGB.NET.Layout.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Management" />
|
||||
</ItemGroup>
|
||||
|
||||
@ -52,22 +52,22 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
|
||||
{
|
||||
Execute.PostToUIThread(() =>
|
||||
{
|
||||
if (e.BitmapBrush?.Bitmap == null || e.BitmapBrush.Bitmap.Pixels.Length == 0)
|
||||
if (e.Texture.Bitmap.Pixels.Length == 0)
|
||||
return;
|
||||
|
||||
SKImageInfo bitmapInfo = e.BitmapBrush.Bitmap.Info;
|
||||
SKImageInfo bitmapInfo = e.Texture.Bitmap.Info;
|
||||
|
||||
if (!(CurrentFrame is WriteableBitmap writeableBitmap) ||
|
||||
writeableBitmap.Width != bitmapInfo.Width ||
|
||||
writeableBitmap.Height != bitmapInfo.Height)
|
||||
{
|
||||
CurrentFrame = e.BitmapBrush.Bitmap.ToWriteableBitmap();
|
||||
CurrentFrame = e.Texture.Bitmap.ToWriteableBitmap();
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using (SKImage skiaImage = SKImage.FromPixels(e.BitmapBrush.Bitmap.PeekPixels()))
|
||||
using (SKImage skiaImage = SKImage.FromPixels(e.Texture.Bitmap.PeekPixels()))
|
||||
{
|
||||
SKImageInfo info = new(skiaImage.Width, skiaImage.Height);
|
||||
writeableBitmap.Lock();
|
||||
|
||||
@ -16,16 +16,16 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
|
||||
private readonly ICoreService _coreService;
|
||||
private readonly IMessageService _messageService;
|
||||
private readonly IRgbService _rgbService;
|
||||
private double _blueScale;
|
||||
private float _blueScale;
|
||||
private SKColor _currentColor;
|
||||
private bool _displayOnDevices;
|
||||
private double _greenScale;
|
||||
private double _initialBlueScale;
|
||||
private double _initialGreenScale;
|
||||
private double _initialRedScale;
|
||||
private double _redScale;
|
||||
private float _greenScale;
|
||||
private float _initialBlueScale;
|
||||
private float _initialGreenScale;
|
||||
private float _initialRedScale;
|
||||
private float _redScale;
|
||||
private int _rotation;
|
||||
private double _scale;
|
||||
private float _scale;
|
||||
private int _x;
|
||||
private int _y;
|
||||
|
||||
@ -57,7 +57,7 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
|
||||
set => SetAndNotify(ref _y, value);
|
||||
}
|
||||
|
||||
public double Scale
|
||||
public float Scale
|
||||
{
|
||||
get => _scale;
|
||||
set => SetAndNotify(ref _scale, value);
|
||||
@ -69,19 +69,19 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
|
||||
set => SetAndNotify(ref _rotation, value);
|
||||
}
|
||||
|
||||
public double RedScale
|
||||
public float RedScale
|
||||
{
|
||||
get => _redScale;
|
||||
set => SetAndNotify(ref _redScale, value);
|
||||
}
|
||||
|
||||
public double GreenScale
|
||||
public float GreenScale
|
||||
{
|
||||
get => _greenScale;
|
||||
set => SetAndNotify(ref _greenScale, value);
|
||||
}
|
||||
|
||||
public double BlueScale
|
||||
public float BlueScale
|
||||
{
|
||||
get => _blueScale;
|
||||
set => SetAndNotify(ref _blueScale, value);
|
||||
@ -101,9 +101,9 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
|
||||
|
||||
public void ApplyScaling()
|
||||
{
|
||||
Device.RedScale = RedScale / 100d;
|
||||
Device.GreenScale = GreenScale / 100d;
|
||||
Device.BlueScale = BlueScale / 100d;
|
||||
Device.RedScale = RedScale / 100f;
|
||||
Device.GreenScale = GreenScale / 100f;
|
||||
Device.BlueScale = BlueScale / 100f;
|
||||
}
|
||||
|
||||
public void BrowseCustomLayout(object sender, MouseEventArgs e)
|
||||
@ -139,9 +139,9 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
|
||||
Device.Y = Y;
|
||||
Device.Scale = Scale;
|
||||
Device.Rotation = Rotation;
|
||||
Device.RedScale = RedScale / 100d;
|
||||
Device.GreenScale = GreenScale / 100d;
|
||||
Device.BlueScale = BlueScale / 100d;
|
||||
Device.RedScale = RedScale / 100f;
|
||||
Device.GreenScale = GreenScale / 100f;
|
||||
Device.BlueScale = BlueScale / 100f;
|
||||
|
||||
_coreService.ModuleRenderingDisabled = false;
|
||||
}
|
||||
@ -159,9 +159,9 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
|
||||
Y = (int) Device.Y;
|
||||
Scale = Device.Scale;
|
||||
Rotation = (int) Device.Rotation;
|
||||
RedScale = Device.RedScale * 100d;
|
||||
GreenScale = Device.GreenScale * 100d;
|
||||
BlueScale = Device.BlueScale * 100d;
|
||||
RedScale = Device.RedScale * 100f;
|
||||
GreenScale = Device.GreenScale * 100f;
|
||||
BlueScale = Device.BlueScale * 100f;
|
||||
//we need to store the initial values to be able to restore them when the user clicks "Cancel"
|
||||
_initialRedScale = Device.RedScale;
|
||||
_initialGreenScale = Device.GreenScale;
|
||||
|
||||
@ -10,7 +10,7 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
|
||||
|
||||
RuleFor(m => m.Y).GreaterThanOrEqualTo(0).WithMessage("Y-coordinate must be 0 or greater");
|
||||
|
||||
RuleFor(m => m.Scale).GreaterThanOrEqualTo(0.2).WithMessage("Scale must be 0.2 or greater");
|
||||
RuleFor(m => m.Scale).GreaterThanOrEqualTo(0.2f).WithMessage("Scale must be 0.2 or greater");
|
||||
|
||||
RuleFor(m => m.Rotation).GreaterThanOrEqualTo(0).WithMessage("Rotation must be 0 or greater");
|
||||
RuleFor(m => m.Rotation).LessThanOrEqualTo(359).WithMessage("Rotation must be 359 or less");
|
||||
|
||||
@ -347,27 +347,6 @@
|
||||
<ComboBox Width="80" SelectedItem="{Binding SelectedTargetFrameRate}" ItemsSource="{Binding TargetFrameRates}" DisplayMemberPath="Item1" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 5" />
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">LED sample size</TextBlock>
|
||||
<TextBlock Style="{StaticResource MaterialDesignTextBlock}" Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}" TextWrapping="Wrap">
|
||||
Sets the amount of samples that is taken to determine each LEDs color. This means a LED can be semi off if it is not completely covered by a color.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<ComboBox Width="80" SelectedItem="{Binding SampleSize}" ItemsSource="{Binding SampleSizes}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</materialDesign:Card>
|
||||
|
||||
|
||||
@ -3,11 +3,9 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Mime;
|
||||
using System.Security.Principal;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.XPath;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.LayerBrushes;
|
||||
using Artemis.Core.Services;
|
||||
@ -16,7 +14,6 @@ using Artemis.UI.Screens.StartupWizard;
|
||||
using Artemis.UI.Services;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using MaterialDesignThemes.Wpf;
|
||||
using Ninject;
|
||||
using Serilog.Events;
|
||||
using Stylet;
|
||||
@ -26,17 +23,16 @@ namespace Artemis.UI.Screens.Settings.Tabs.General
|
||||
public class GeneralSettingsTabViewModel : Screen
|
||||
{
|
||||
private readonly IDebugService _debugService;
|
||||
private readonly IKernel _kernel;
|
||||
private readonly IWindowManager _windowManager;
|
||||
private readonly PluginSetting<LayerBrushReference> _defaultLayerBrushDescriptor;
|
||||
private readonly IDialogService _dialogService;
|
||||
private readonly IKernel _kernel;
|
||||
private readonly IMessageService _messageService;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly IUpdateService _updateService;
|
||||
private readonly IMessageService _messageService;
|
||||
private List<Tuple<string, double>> _renderScales;
|
||||
private List<int> _sampleSizes;
|
||||
private List<Tuple<string, int>> _targetFrameRates;
|
||||
private readonly PluginSetting<LayerBrushReference> _defaultLayerBrushDescriptor;
|
||||
private readonly IWindowManager _windowManager;
|
||||
private bool _canOfferUpdatesIfFound = true;
|
||||
private List<Tuple<string, double>> _renderScales;
|
||||
private List<Tuple<string, int>> _targetFrameRates;
|
||||
|
||||
public GeneralSettingsTabViewModel(
|
||||
IKernel kernel,
|
||||
@ -68,9 +64,6 @@ namespace Artemis.UI.Screens.Settings.Tabs.General
|
||||
for (int i = 10; i <= 30; i += 5)
|
||||
TargetFrameRates.Add(new Tuple<string, int>(i + " FPS", i));
|
||||
|
||||
// Anything else is kinda broken right now
|
||||
SampleSizes = new List<int> {1, 9};
|
||||
|
||||
List<LayerBrushProvider> layerBrushProviders = pluginManagementService.GetFeaturesOfType<LayerBrushProvider>();
|
||||
|
||||
LayerBrushDescriptors = new BindableCollection<LayerBrushDescriptor>(layerBrushProviders.SelectMany(l => l.LayerBrushDescriptors));
|
||||
@ -111,12 +104,6 @@ namespace Artemis.UI.Screens.Settings.Tabs.General
|
||||
set => SetAndNotify(ref _renderScales, value);
|
||||
}
|
||||
|
||||
public List<int> SampleSizes
|
||||
{
|
||||
get => _sampleSizes;
|
||||
set => SetAndNotify(ref _sampleSizes, value);
|
||||
}
|
||||
|
||||
public bool StartWithWindows
|
||||
{
|
||||
get => _settingsService.GetSetting("UI.AutoRun", false).Value;
|
||||
@ -239,16 +226,6 @@ namespace Artemis.UI.Screens.Settings.Tabs.General
|
||||
}
|
||||
}
|
||||
|
||||
public int SampleSize
|
||||
{
|
||||
get => _settingsService.GetSetting("Core.SampleSize", 1).Value;
|
||||
set
|
||||
{
|
||||
_settingsService.GetSetting("Core.SampleSize", 1).Value = value;
|
||||
_settingsService.GetSetting("Core.SampleSize", 1).Save();
|
||||
}
|
||||
}
|
||||
|
||||
public PluginSetting<int> WebServerPortSetting { get; }
|
||||
|
||||
public bool CanOfferUpdatesIfFound
|
||||
@ -320,7 +297,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.General
|
||||
File.Delete(autoRunFile);
|
||||
|
||||
// TODO: Don't do anything if running a development build, only auto-run release builds
|
||||
|
||||
|
||||
// Create or remove the task if necessary
|
||||
try
|
||||
{
|
||||
@ -363,13 +340,13 @@ namespace Artemis.UI.Screens.Settings.Tabs.General
|
||||
task.Descendants().First(d => d.Name.LocalName == "RegistrationInfo").Descendants().First(d => d.Name.LocalName == "Date")
|
||||
.SetValue(DateTime.Now);
|
||||
task.Descendants().First(d => d.Name.LocalName == "RegistrationInfo").Descendants().First(d => d.Name.LocalName == "Author")
|
||||
.SetValue(System.Security.Principal.WindowsIdentity.GetCurrent().Name);
|
||||
.SetValue(WindowsIdentity.GetCurrent().Name);
|
||||
|
||||
task.Descendants().First(d => d.Name.LocalName == "Triggers").Descendants().First(d => d.Name.LocalName == "LogonTrigger").Descendants().First(d => d.Name.LocalName == "Delay")
|
||||
.SetValue(TimeSpan.FromSeconds(AutoRunDelay));
|
||||
|
||||
task.Descendants().First(d => d.Name.LocalName == "Principals").Descendants().First(d => d.Name.LocalName == "Principal").Descendants().First(d => d.Name.LocalName == "UserId")
|
||||
.SetValue(System.Security.Principal.WindowsIdentity.GetCurrent().User.Value);
|
||||
.SetValue(WindowsIdentity.GetCurrent().User.Value);
|
||||
|
||||
task.Descendants().First(d => d.Name.LocalName == "Actions").Descendants().First(d => d.Name.LocalName == "Exec").Descendants().First(d => d.Name.LocalName == "WorkingDirectory")
|
||||
.SetValue(Constants.ApplicationFolder);
|
||||
|
||||
@ -4,9 +4,7 @@ using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using MaterialDesignThemes.Wpf;
|
||||
using RGB.NET.Brushes;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Groups;
|
||||
|
||||
namespace Artemis.UI.Screens.SurfaceEditor.Dialogs
|
||||
{
|
||||
@ -45,7 +43,7 @@ namespace Artemis.UI.Screens.SurfaceEditor.Dialogs
|
||||
{
|
||||
base.OnDialogClosed(sender, e);
|
||||
_inputService.DeviceIdentified -= InputServiceOnDeviceIdentified;
|
||||
_ledGroup.Detach(_rgbService.Surface);
|
||||
_ledGroup.Detach();
|
||||
}
|
||||
|
||||
private void InputServiceOnDeviceIdentified(object sender, EventArgs e)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user