mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 11:56:30 +00:00
Core - Add HidSharp to force plugins to share the HidSharp types
Core - For now, set default log level to debug ColorGradient- Improved GetColor performance ColorGradient - GetColor now handles colors not between two stops properly Home - Fix links Plugins - Only allow layer property registration through Brushes Color brush - Default to solid color
This commit is contained in:
1 parent
8c3212451b
commit
9f8fc9f70e
21 files changed
+279
-172
No files matched your search
@@ -22,6 +22,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Ben.Demystifier" Version="0.1.6" />
|
||||
<PackageReference Include="Castle.Core" Version="4.4.0" />
|
||||
<PackageReference Include="HidSharp" Version="2.1.0" />
|
||||
<PackageReference Include="LiteDB" Version="5.0.7" />
|
||||
<PackageReference Include="McMaster.NETCore.Plugins" Version="1.2.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
|
||||
@@ -28,6 +28,54 @@ namespace Artemis.Core.Models.Profile
|
||||
return Stops.OrderBy(c => c.Position).Select(c => c.Position).ToArray();
|
||||
}
|
||||
|
||||
public void OnColorValuesUpdated()
|
||||
{
|
||||
OnPropertyChanged(nameof(Stops));
|
||||
}
|
||||
|
||||
public SKColor GetColor(float position)
|
||||
{
|
||||
if (!Stops.Any())
|
||||
return SKColor.Empty;
|
||||
|
||||
var stops = Stops.OrderBy(x => x.Position).ToArray();
|
||||
if (position <= 0) return stops[0].Color;
|
||||
if (position >= 1) return stops[^1].Color;
|
||||
ColorGradientStop left = stops[0], right = null;
|
||||
foreach (var stop in stops)
|
||||
{
|
||||
if (stop.Position >= position)
|
||||
{
|
||||
right = stop;
|
||||
break;
|
||||
}
|
||||
|
||||
left = stop;
|
||||
}
|
||||
|
||||
if (right == null || left == right)
|
||||
return left.Color;
|
||||
|
||||
position = (float) Math.Round((position - left.Position) / (right.Position - left.Position), 2);
|
||||
var a = (byte) ((right.Color.Alpha - left.Color.Alpha) * position + left.Color.Alpha);
|
||||
var r = (byte) ((right.Color.Red - left.Color.Red) * position + left.Color.Red);
|
||||
var g = (byte) ((right.Color.Green - left.Color.Green) * position + left.Color.Green);
|
||||
var b = (byte) ((right.Color.Blue - left.Color.Blue) * position + left.Color.Blue);
|
||||
return new SKColor(r, g, b, a);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// [PH] Looping through HSV, adds 8 rainbow colors
|
||||
/// </summary>
|
||||
public void MakeFabulous()
|
||||
{
|
||||
for (var i = 0; i < 9; i++)
|
||||
{
|
||||
var color = i != 8 ? SKColor.FromHsv(i * 32, 100, 100) : SKColor.FromHsv(0, 100, 100);
|
||||
Stops.Add(new ColorGradientStop(color, 0.125f * i));
|
||||
}
|
||||
}
|
||||
|
||||
#region PropertyChanged
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
@@ -39,51 +87,6 @@ namespace Artemis.Core.Models.Profile
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void OnColorValuesUpdated()
|
||||
{
|
||||
OnPropertyChanged(nameof(Stops));
|
||||
}
|
||||
|
||||
public SKColor GetColor(float position)
|
||||
{
|
||||
if (!Stops.Any())
|
||||
return SKColor.Empty;
|
||||
|
||||
var point = Stops.FirstOrDefault(f => f.Position == position);
|
||||
if (point != null) return point.Color;
|
||||
|
||||
var before = Stops.First(w => w.Position == Stops.Min(m => m.Position));
|
||||
var after = Stops.First(w => w.Position == Stops.Max(m => m.Position));
|
||||
|
||||
foreach (var gs in Stops)
|
||||
{
|
||||
if (gs.Position < position && gs.Position > before.Position)
|
||||
before = gs;
|
||||
|
||||
if (gs.Position >= position && gs.Position < after.Position)
|
||||
after = gs;
|
||||
}
|
||||
|
||||
return new SKColor(
|
||||
(byte) ((position - before.Position) * (after.Color.Red - before.Color.Red) / (after.Position - before.Position) + before.Color.Red),
|
||||
(byte) ((position - before.Position) * (after.Color.Green - before.Color.Green) / (after.Position - before.Position) + before.Color.Green),
|
||||
(byte) ((position - before.Position) * (after.Color.Blue - before.Color.Blue) / (after.Position - before.Position) + before.Color.Blue),
|
||||
(byte) ((position - before.Position) * (after.Color.Alpha - before.Color.Alpha) / (after.Position - before.Position) + before.Color.Alpha)
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// [PH] Looping through HSV, adds 8 rainbow colors
|
||||
/// </summary>
|
||||
public void MakeFabulous()
|
||||
{
|
||||
for (var i = 0; i < 9; i++)
|
||||
{
|
||||
var color = i != 8 ? SKColor.FromHsv(i * 32, 100, 100) : SKColor.FromHsv(0, 100, 100);
|
||||
Stops.Add(new ColorGradientStop(color, 0.125f * i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ColorGradientStop : INotifyPropertyChanged
|
||||
|
||||
@@ -41,32 +41,6 @@ namespace Artemis.Core.Models.Profile.LayerProperties
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the provided layer property from the layer.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of value of the layer property</typeparam>
|
||||
/// <param name="layerProperty">The property to remove from the layer</param>
|
||||
public void RemoveLayerProperty<T>(LayerProperty<T> layerProperty)
|
||||
{
|
||||
RemoveLayerProperty((BaseLayerProperty) layerProperty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the provided layer property from the layer.
|
||||
/// </summary>
|
||||
/// <param name="layerProperty">The property to remove from the layer</param>
|
||||
public void RemoveLayerProperty(BaseLayerProperty layerProperty)
|
||||
{
|
||||
if (!_properties.ContainsKey((layerProperty.PluginInfo.Guid, layerProperty.Id)))
|
||||
throw new ArtemisCoreException($"Could not find a property with ID {layerProperty.Id}.");
|
||||
|
||||
var property = _properties[(layerProperty.PluginInfo.Guid, layerProperty.Id)];
|
||||
property.Parent?.Children.Remove(property);
|
||||
_properties.Remove((layerProperty.PluginInfo.Guid, layerProperty.Id));
|
||||
|
||||
OnLayerPropertyRemoved(new LayerPropertyEventArgs(property));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If found, returns the <see cref="LayerProperty{T}" /> matching the provided ID
|
||||
/// </summary>
|
||||
@@ -82,7 +56,33 @@ namespace Artemis.Core.Models.Profile.LayerProperties
|
||||
var property = _properties[(pluginInfo.Guid, id)];
|
||||
if (property.Type != typeof(T))
|
||||
throw new ArtemisCoreException($"Property type mismatch. Expected property {property} to have type {typeof(T)} but it has {property.Type} instead.");
|
||||
return (LayerProperty<T>) _properties[(pluginInfo.Guid, id)];
|
||||
return (LayerProperty<T>)_properties[(pluginInfo.Guid, id)];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the provided layer property from the layer.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of value of the layer property</typeparam>
|
||||
/// <param name="layerProperty">The property to remove from the layer</param>
|
||||
internal void RemoveLayerProperty<T>(LayerProperty<T> layerProperty)
|
||||
{
|
||||
RemoveLayerProperty((BaseLayerProperty) layerProperty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the provided layer property from the layer.
|
||||
/// </summary>
|
||||
/// <param name="layerProperty">The property to remove from the layer</param>
|
||||
internal void RemoveLayerProperty(BaseLayerProperty layerProperty)
|
||||
{
|
||||
if (!_properties.ContainsKey((layerProperty.PluginInfo.Guid, layerProperty.Id)))
|
||||
throw new ArtemisCoreException($"Could not find a property with ID {layerProperty.Id}.");
|
||||
|
||||
var property = _properties[(layerProperty.PluginInfo.Guid, layerProperty.Id)];
|
||||
property.Parent?.Children.Remove(property);
|
||||
_properties.Remove((layerProperty.PluginInfo.Guid, layerProperty.Id));
|
||||
|
||||
OnLayerPropertyRemoved(new LayerPropertyEventArgs(property));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -92,7 +92,7 @@ namespace Artemis.Core.Models.Profile.LayerProperties
|
||||
/// <typeparam name="T">The type of value of the layer property</typeparam>
|
||||
/// <param name="layerProperty">The property to apply to the layer</param>
|
||||
/// <returns>True if an existing value was found and applied, otherwise false.</returns>
|
||||
public bool RegisterLayerProperty<T>(LayerProperty<T> layerProperty)
|
||||
internal bool RegisterLayerProperty<T>(LayerProperty<T> layerProperty)
|
||||
{
|
||||
return RegisterLayerProperty((BaseLayerProperty) layerProperty);
|
||||
}
|
||||
@@ -103,7 +103,7 @@ namespace Artemis.Core.Models.Profile.LayerProperties
|
||||
/// </summary>
|
||||
/// <param name="layerProperty">The property to apply to the layer</param>
|
||||
/// <returns>True if an existing value was found and applied, otherwise false.</returns>
|
||||
public bool RegisterLayerProperty(BaseLayerProperty layerProperty)
|
||||
internal bool RegisterLayerProperty(BaseLayerProperty layerProperty)
|
||||
{
|
||||
if (_properties.ContainsKey((layerProperty.PluginInfo.Guid, layerProperty.Id)))
|
||||
throw new ArtemisCoreException($"Duplicate property ID detected. Layer already contains a property with ID {layerProperty.Id}.");
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Linq;
|
||||
using Artemis.Core.Models.Profile;
|
||||
using Artemis.Core.Models.Profile.LayerProperties;
|
||||
using Artemis.Core.Plugins.Exceptions;
|
||||
using Artemis.Core.Services.Interfaces;
|
||||
using SkiaSharp;
|
||||
|
||||
@@ -35,7 +36,7 @@ namespace Artemis.Core.Plugins.LayerBrush
|
||||
/// <summary>
|
||||
/// The main method of rendering anything to the layer. The provided <see cref="SKCanvas" /> is specific to the layer
|
||||
/// and matches it's width and height.
|
||||
/// <para>Called during rendering, in the order configured on the layer</para>
|
||||
/// <para>Called during rendering or layer preview, in the order configured on the layer</para>
|
||||
/// </summary>
|
||||
/// <param name="canvas">The layer canvas</param>
|
||||
/// <param name="canvasInfo"></param>
|
||||
@@ -77,6 +78,22 @@ namespace Artemis.Core.Plugins.LayerBrush
|
||||
/// <returns>The layer property</returns>
|
||||
protected LayerProperty<T> RegisterLayerProperty<T>(string id, string name, string description, T defaultValue = default)
|
||||
{
|
||||
// Check if the property already exists
|
||||
var existing = Layer.Properties.FirstOrDefault(p =>
|
||||
p.PluginInfo.Guid == Descriptor.LayerBrushProvider.PluginInfo.Guid &&
|
||||
p.Id == id &&
|
||||
p.Name == name &&
|
||||
p.Description == description);
|
||||
|
||||
if (existing != null)
|
||||
{
|
||||
// If it exists and the types match, return the existing property
|
||||
if (existing.Type == typeof(T))
|
||||
return (LayerProperty<T>) existing;
|
||||
// If it exists and the types are different, something is wrong
|
||||
throw new ArtemisPluginException($"Cannot register the property {id} with different types twice.");
|
||||
}
|
||||
|
||||
var property = new LayerProperty<T>(Layer, Descriptor.LayerBrushProvider.PluginInfo, Layer.Properties.BrushReference.Parent, id, name, description)
|
||||
{
|
||||
Value = defaultValue
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Artemis.Core.Services
|
||||
_rgbService = rgbService;
|
||||
_surfaceService = surfaceService;
|
||||
_profileService = profileService;
|
||||
_loggingLevel = settingsService.GetSetting("Core.LoggingLevel", LogEventLevel.Information);
|
||||
_loggingLevel = settingsService.GetSetting("Core.LoggingLevel", LogEventLevel.Debug);
|
||||
|
||||
_rgbService.Surface.Updating += SurfaceOnUpdating;
|
||||
_rgbService.Surface.Updated += SurfaceOnUpdated;
|
||||
|
||||
@@ -28,6 +28,8 @@ namespace Artemis.Core.Services.Interfaces
|
||||
/// </summary>
|
||||
IReadOnlyCollection<IRGBDevice> LoadedDevices { get; }
|
||||
|
||||
TimerUpdateTrigger UpdateTrigger { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Adds the given device provider to the <see cref="Surface" />
|
||||
/// </summary>
|
||||
|
||||
@@ -20,7 +20,6 @@ namespace Artemis.Core.Services
|
||||
private readonly PluginSetting<double> _renderScaleSetting;
|
||||
private readonly PluginSetting<int> _sampleSizeSetting;
|
||||
private readonly PluginSetting<int> _targetFrameRateSetting;
|
||||
private readonly TimerUpdateTrigger _updateTrigger;
|
||||
private ListLedGroup _surfaceLedGroup;
|
||||
|
||||
internal RgbService(ILogger logger, ISettingsService settingsService)
|
||||
@@ -37,17 +36,16 @@ namespace Artemis.Core.Services
|
||||
_renderScaleSetting.SettingChanged += RenderScaleSettingOnSettingChanged;
|
||||
_targetFrameRateSetting.SettingChanged += TargetFrameRateSettingOnSettingChanged;
|
||||
_loadedDevices = new List<IRGBDevice>();
|
||||
_updateTrigger = new TimerUpdateTrigger {UpdateFrequency = 1.0 / _targetFrameRateSetting.Value};
|
||||
Surface.RegisterUpdateTrigger(_updateTrigger);
|
||||
UpdateTrigger = new TimerUpdateTrigger {UpdateFrequency = 1.0 / _targetFrameRateSetting.Value};
|
||||
Surface.RegisterUpdateTrigger(UpdateTrigger);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public RGBSurface Surface { get; set; }
|
||||
|
||||
public TimerUpdateTrigger UpdateTrigger { get; }
|
||||
public BitmapBrush BitmapBrush { get; private set; }
|
||||
|
||||
public IReadOnlyCollection<IRGBDevice> LoadedDevices => _loadedDevices.AsReadOnly();
|
||||
|
||||
public double RenderScale => _renderScaleSetting.Value;
|
||||
|
||||
public void AddDeviceProvider(IRGBDeviceProvider deviceProvider)
|
||||
@@ -82,9 +80,9 @@ namespace Artemis.Core.Services
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Surface.UnregisterUpdateTrigger(_updateTrigger);
|
||||
Surface.UnregisterUpdateTrigger(UpdateTrigger);
|
||||
|
||||
_updateTrigger.Dispose();
|
||||
UpdateTrigger.Dispose();
|
||||
Surface.Dispose();
|
||||
}
|
||||
|
||||
@@ -95,7 +93,7 @@ namespace Artemis.Core.Services
|
||||
|
||||
private void TargetFrameRateSettingOnSettingChanged(object sender, EventArgs e)
|
||||
{
|
||||
_updateTrigger.UpdateFrequency = 1.0 / _targetFrameRateSetting.Value;
|
||||
UpdateTrigger.UpdateFrequency = 1.0 / _targetFrameRateSetting.Value;
|
||||
}
|
||||
|
||||
private void SurfaceOnException(ExceptionEventArgs args)
|
||||
|
||||
@@ -95,6 +95,7 @@ namespace Artemis.Core.Services.Storage
|
||||
// Update the RGB service's graphics decorator to work with the new surface entity
|
||||
_rgbService.UpdateSurfaceLedGroup();
|
||||
OnActiveSurfaceConfigurationChanged(new SurfaceConfigurationEventArgs(ActiveSurface));
|
||||
|
||||
}
|
||||
|
||||
public void UpdateSurfaceConfiguration(ArtemisSurface surface, bool includeDevices)
|
||||
|
||||
Reference in new issue
Block a user