mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Merge branch 'development' into VisualScripting
This commit is contained in:
commit
2a6c004aa6
@ -306,7 +306,7 @@ namespace Artemis.Core
|
|||||||
ChildrenList.Add(new Layer(Profile, this, childLayer));
|
ChildrenList.Add(new Layer(Profile, this, childLayer));
|
||||||
|
|
||||||
// Ensure order integrity, should be unnecessary but no one is perfect specially me
|
// Ensure order integrity, should be unnecessary but no one is perfect specially me
|
||||||
ChildrenList = ChildrenList.OrderBy(c => c.Order).ToList();
|
ChildrenList.Sort((a,b) => a.Order.CompareTo(b.Order));
|
||||||
for (int index = 0; index < ChildrenList.Count; index++)
|
for (int index = 0; index < ChildrenList.Count; index++)
|
||||||
ChildrenList[index].Order = index + 1;
|
ChildrenList[index].Order = index + 1;
|
||||||
|
|
||||||
|
|||||||
@ -43,6 +43,7 @@ namespace Artemis.Core
|
|||||||
_transform = new LayerTransformProperties();
|
_transform = new LayerTransformProperties();
|
||||||
|
|
||||||
_leds = new List<ArtemisLed>();
|
_leds = new List<ArtemisLed>();
|
||||||
|
Leds = new ReadOnlyCollection<ArtemisLed>(_leds);
|
||||||
|
|
||||||
Adapter = new LayerAdapter(this);
|
Adapter = new LayerAdapter(this);
|
||||||
Initialize();
|
Initialize();
|
||||||
@ -67,6 +68,7 @@ namespace Artemis.Core
|
|||||||
_transform = new LayerTransformProperties();
|
_transform = new LayerTransformProperties();
|
||||||
|
|
||||||
_leds = new List<ArtemisLed>();
|
_leds = new List<ArtemisLed>();
|
||||||
|
Leds = new ReadOnlyCollection<ArtemisLed>(_leds);
|
||||||
|
|
||||||
Adapter = new LayerAdapter(this);
|
Adapter = new LayerAdapter(this);
|
||||||
Load();
|
Load();
|
||||||
@ -76,7 +78,7 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A collection of all the LEDs this layer is assigned to.
|
/// A collection of all the LEDs this layer is assigned to.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReadOnlyCollection<ArtemisLed> Leds => _leds.AsReadOnly();
|
public ReadOnlyCollection<ArtemisLed> Leds { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines the shape that is rendered by the <see cref="LayerBrush" />.
|
/// Defines the shape that is rendered by the <see cref="LayerBrush" />.
|
||||||
@ -679,6 +681,7 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
_leds = leds;
|
_leds = leds;
|
||||||
|
Leds = new ReadOnlyCollection<ArtemisLed>(_leds);
|
||||||
CalculateRenderProperties();
|
CalculateRenderProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -45,6 +45,7 @@ namespace Artemis.Core
|
|||||||
_baseValue = default!;
|
_baseValue = default!;
|
||||||
|
|
||||||
_keyframes = new List<LayerPropertyKeyframe<T>>();
|
_keyframes = new List<LayerPropertyKeyframe<T>>();
|
||||||
|
Keyframes = new(_keyframes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -229,7 +230,7 @@ namespace Artemis.Core
|
|||||||
#region Keyframes
|
#region Keyframes
|
||||||
|
|
||||||
private bool _keyframesEnabled;
|
private bool _keyframesEnabled;
|
||||||
private List<LayerPropertyKeyframe<T>> _keyframes;
|
private readonly List<LayerPropertyKeyframe<T>> _keyframes;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets whether keyframes are supported on this type of property
|
/// Gets whether keyframes are supported on this type of property
|
||||||
@ -255,7 +256,7 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a read-only list of all the keyframes on this layer property
|
/// Gets a read-only list of all the keyframes on this layer property
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReadOnlyCollection<LayerPropertyKeyframe<T>> Keyframes => _keyframes.AsReadOnly();
|
public ReadOnlyCollection<LayerPropertyKeyframe<T>> Keyframes { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current keyframe in the timeline according to the current progress
|
/// Gets the current keyframe in the timeline according to the current progress
|
||||||
@ -328,7 +329,7 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal void SortKeyframes()
|
internal void SortKeyframes()
|
||||||
{
|
{
|
||||||
_keyframes = _keyframes.OrderBy(k => k.Position).ToList();
|
_keyframes.Sort((a, b) => a.Position.CompareTo(b.Position));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateKeyframes(Timeline timeline)
|
private void UpdateKeyframes(Timeline timeline)
|
||||||
|
|||||||
@ -37,6 +37,9 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
_layerProperties = new List<ILayerProperty>();
|
_layerProperties = new List<ILayerProperty>();
|
||||||
_layerPropertyGroups = new List<LayerPropertyGroup>();
|
_layerPropertyGroups = new List<LayerPropertyGroup>();
|
||||||
|
|
||||||
|
LayerProperties = new(_layerProperties);
|
||||||
|
LayerPropertyGroups = new(_layerPropertyGroups);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -96,12 +99,12 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A list of all layer properties in this group
|
/// A list of all layer properties in this group
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReadOnlyCollection<ILayerProperty> LayerProperties => _layerProperties.AsReadOnly();
|
public ReadOnlyCollection<ILayerProperty> LayerProperties { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A list of al child groups in this group
|
/// A list of al child groups in this group
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReadOnlyCollection<LayerPropertyGroup> LayerPropertyGroups => _layerPropertyGroups.AsReadOnly();
|
public ReadOnlyCollection<LayerPropertyGroup> LayerPropertyGroups { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Recursively gets all layer properties on this group and any subgroups
|
/// Recursively gets all layer properties on this group and any subgroups
|
||||||
|
|||||||
@ -24,12 +24,15 @@ namespace Artemis.Core
|
|||||||
{
|
{
|
||||||
_name = name;
|
_name = name;
|
||||||
Entity = new ProfileCategoryEntity();
|
Entity = new ProfileCategoryEntity();
|
||||||
|
ProfileConfigurations = new(_profileConfigurations);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal ProfileCategory(ProfileCategoryEntity entity)
|
internal ProfileCategory(ProfileCategoryEntity entity)
|
||||||
{
|
{
|
||||||
_name = null!;
|
_name = null!;
|
||||||
Entity = entity;
|
Entity = entity;
|
||||||
|
ProfileConfigurations = new(_profileConfigurations);
|
||||||
|
|
||||||
Load();
|
Load();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +76,7 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a read only collection of the profiles inside this category
|
/// Gets a read only collection of the profiles inside this category
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReadOnlyCollection<ProfileConfiguration> ProfileConfigurations => _profileConfigurations.AsReadOnly();
|
public ReadOnlyCollection<ProfileConfiguration> ProfileConfigurations { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the unique ID of this category
|
/// Gets the unique ID of this category
|
||||||
|
|||||||
@ -18,12 +18,13 @@ namespace Artemis.Core
|
|||||||
private Profile _profile;
|
private Profile _profile;
|
||||||
private bool _suspended;
|
private bool _suspended;
|
||||||
|
|
||||||
internal List<ProfileElement> ChildrenList;
|
internal readonly List<ProfileElement> ChildrenList;
|
||||||
|
|
||||||
internal ProfileElement(Profile profile)
|
internal ProfileElement(Profile profile)
|
||||||
{
|
{
|
||||||
_profile = profile;
|
_profile = profile;
|
||||||
ChildrenList = new List<ProfileElement>();
|
ChildrenList = new List<ProfileElement>();
|
||||||
|
Children = new(ChildrenList);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -56,16 +57,7 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The element's children
|
/// The element's children
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReadOnlyCollection<ProfileElement> Children
|
public ReadOnlyCollection<ProfileElement> Children { get; }
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
lock (ChildrenList)
|
|
||||||
{
|
|
||||||
return ChildrenList.AsReadOnly();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The order in which this element appears in the update loop and editor
|
/// The order in which this element appears in the update loop and editor
|
||||||
|
|||||||
@ -28,7 +28,8 @@ namespace Artemis.Core
|
|||||||
Timeline = new Timeline();
|
Timeline = new Timeline();
|
||||||
ExpandedPropertyGroups = new List<string>();
|
ExpandedPropertyGroups = new List<string>();
|
||||||
LayerEffectsList = new List<BaseLayerEffect>();
|
LayerEffectsList = new List<BaseLayerEffect>();
|
||||||
|
LayerEffects = new(LayerEffectsList);
|
||||||
|
|
||||||
LayerEffectStore.LayerEffectAdded += LayerEffectStoreOnLayerEffectAdded;
|
LayerEffectStore.LayerEffectAdded += LayerEffectStoreOnLayerEffectAdded;
|
||||||
LayerEffectStore.LayerEffectRemoved += LayerEffectStoreOnLayerEffectRemoved;
|
LayerEffectStore.LayerEffectRemoved += LayerEffectStoreOnLayerEffectRemoved;
|
||||||
}
|
}
|
||||||
@ -235,12 +236,12 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
#region Effect management
|
#region Effect management
|
||||||
|
|
||||||
internal List<BaseLayerEffect> LayerEffectsList;
|
internal readonly List<BaseLayerEffect> LayerEffectsList;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a read-only collection of the layer effects on this entity
|
/// Gets a read-only collection of the layer effects on this entity
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReadOnlyCollection<BaseLayerEffect> LayerEffects => LayerEffectsList.AsReadOnly();
|
public ReadOnlyCollection<BaseLayerEffect> LayerEffects { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a the layer effect described inthe provided <paramref name="descriptor" />
|
/// Adds a the layer effect described inthe provided <paramref name="descriptor" />
|
||||||
|
|||||||
@ -24,6 +24,7 @@ namespace Artemis.Core
|
|||||||
MainSegmentLength = TimeSpan.FromSeconds(5);
|
MainSegmentLength = TimeSpan.FromSeconds(5);
|
||||||
|
|
||||||
_extraTimelines = new List<Timeline>();
|
_extraTimelines = new List<Timeline>();
|
||||||
|
ExtraTimelines = new(_extraTimelines);
|
||||||
|
|
||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
@ -32,6 +33,7 @@ namespace Artemis.Core
|
|||||||
{
|
{
|
||||||
Entity = entity;
|
Entity = entity;
|
||||||
_extraTimelines = new List<Timeline>();
|
_extraTimelines = new List<Timeline>();
|
||||||
|
ExtraTimelines = new(_extraTimelines);
|
||||||
|
|
||||||
Load();
|
Load();
|
||||||
}
|
}
|
||||||
@ -45,6 +47,7 @@ namespace Artemis.Core
|
|||||||
EndSegmentLength = Parent.EndSegmentLength;
|
EndSegmentLength = Parent.EndSegmentLength;
|
||||||
|
|
||||||
_extraTimelines = new List<Timeline>();
|
_extraTimelines = new List<Timeline>();
|
||||||
|
ExtraTimelines = new(_extraTimelines);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -150,7 +153,7 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a list of extra copies of the timeline applied to this timeline
|
/// Gets a list of extra copies of the timeline applied to this timeline
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReadOnlyCollection<Timeline> ExtraTimelines => _extraTimelines.AsReadOnly();
|
public ReadOnlyCollection<Timeline> ExtraTimelines { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a boolean indicating whether the timeline has finished its run
|
/// Gets a boolean indicating whether the timeline has finished its run
|
||||||
|
|||||||
@ -59,8 +59,18 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
internal void CalculateRectangles()
|
internal void CalculateRectangles()
|
||||||
{
|
{
|
||||||
Rectangle = RgbLed.Boundary.ToSKRect();
|
Rectangle = Utilities.CreateScaleCompatibleRect(
|
||||||
AbsoluteRectangle = RgbLed.AbsoluteBoundary.ToSKRect();
|
RgbLed.Boundary.Location.X,
|
||||||
|
RgbLed.Boundary.Location.Y,
|
||||||
|
RgbLed.Boundary.Size.Width,
|
||||||
|
RgbLed.Boundary.Size.Height
|
||||||
|
);
|
||||||
|
AbsoluteRectangle = Utilities.CreateScaleCompatibleRect(
|
||||||
|
RgbLed.AbsoluteBoundary.Location.X,
|
||||||
|
RgbLed.AbsoluteBoundary.Location.Y,
|
||||||
|
RgbLed.AbsoluteBoundary.Size.Width,
|
||||||
|
RgbLed.AbsoluteBoundary.Size.Height
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -17,13 +17,14 @@ namespace Artemis.Core.LayerBrushes
|
|||||||
protected LayerBrushProvider()
|
protected LayerBrushProvider()
|
||||||
{
|
{
|
||||||
_layerBrushDescriptors = new List<LayerBrushDescriptor>();
|
_layerBrushDescriptors = new List<LayerBrushDescriptor>();
|
||||||
|
LayerBrushDescriptors = new(_layerBrushDescriptors);
|
||||||
Disabled += OnDisabled;
|
Disabled += OnDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A read-only collection of all layer brushes added with <see cref="RegisterLayerBrushDescriptor{T}" />
|
/// A read-only collection of all layer brushes added with <see cref="RegisterLayerBrushDescriptor{T}" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReadOnlyCollection<LayerBrushDescriptor> LayerBrushDescriptors => _layerBrushDescriptors.AsReadOnly();
|
public ReadOnlyCollection<LayerBrushDescriptor> LayerBrushDescriptors { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Registers a layer brush descriptor for a given layer brush, so that it appears in the UI.
|
/// Registers a layer brush descriptor for a given layer brush, so that it appears in the UI.
|
||||||
|
|||||||
@ -18,13 +18,14 @@ namespace Artemis.Core.LayerEffects
|
|||||||
protected LayerEffectProvider()
|
protected LayerEffectProvider()
|
||||||
{
|
{
|
||||||
_layerEffectDescriptors = new List<LayerEffectDescriptor>();
|
_layerEffectDescriptors = new List<LayerEffectDescriptor>();
|
||||||
|
LayerEffectDescriptors = new(_layerEffectDescriptors);
|
||||||
Disabled += OnDisabled;
|
Disabled += OnDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A read-only collection of all layer effects added with <see cref="RegisterLayerEffectDescriptor{T}" />
|
/// A read-only collection of all layer effects added with <see cref="RegisterLayerEffectDescriptor{T}" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReadOnlyCollection<LayerEffectDescriptor> LayerEffectDescriptors => _layerEffectDescriptors.AsReadOnly();
|
public ReadOnlyCollection<LayerEffectDescriptor> LayerEffectDescriptors { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a layer effect descriptor for a given layer effect, so that it appears in the UI.
|
/// Adds a layer effect descriptor for a given layer effect, so that it appears in the UI.
|
||||||
|
|||||||
@ -26,6 +26,9 @@ namespace Artemis.Core.Modules
|
|||||||
// These are both set right after construction to keep the constructor of inherited classes clean
|
// These are both set right after construction to keep the constructor of inherited classes clean
|
||||||
Module = null!;
|
Module = null!;
|
||||||
DataModelDescription = null!;
|
DataModelDescription = null!;
|
||||||
|
|
||||||
|
ActivePaths = new(_activePaths);
|
||||||
|
DynamicChildren = new(_dynamicChildren);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -52,13 +55,13 @@ namespace Artemis.Core.Modules
|
|||||||
/// Gets an read-only dictionary of all dynamic children
|
/// Gets an read-only dictionary of all dynamic children
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataModelIgnore]
|
[DataModelIgnore]
|
||||||
public ReadOnlyDictionary<string, DynamicChild> DynamicChildren => new(_dynamicChildren);
|
public ReadOnlyDictionary<string, DynamicChild> DynamicChildren { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a read-only list of <see cref="DataModelPath" />s targeting this data model
|
/// Gets a read-only list of <see cref="DataModelPath" />s targeting this data model
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataModelIgnore]
|
[DataModelIgnore]
|
||||||
public ReadOnlyCollection<DataModelPath> ActivePaths => _activePaths.AsReadOnly();
|
public ReadOnlyCollection<DataModelPath> ActivePaths { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a read-only collection of all properties in this datamodel that are to be ignored
|
/// Returns a read-only collection of all properties in this datamodel that are to be ignored
|
||||||
|
|||||||
@ -114,6 +114,12 @@ namespace Artemis.Core.Modules
|
|||||||
private readonly List<(DefaultCategoryName, string)> _defaultProfilePaths = new();
|
private readonly List<(DefaultCategoryName, string)> _defaultProfilePaths = new();
|
||||||
private readonly List<(DefaultCategoryName, string)> _pendingDefaultProfilePaths = new();
|
private readonly List<(DefaultCategoryName, string)> _pendingDefaultProfilePaths = new();
|
||||||
|
|
||||||
|
protected Module()
|
||||||
|
{
|
||||||
|
DefaultProfilePaths = new ReadOnlyCollection<(DefaultCategoryName, string)>(_defaultProfilePaths);
|
||||||
|
HiddenProperties = new(HiddenPropertiesList);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a list of all properties ignored at runtime using <c>IgnoreProperty(x => x.y)</c>
|
/// Gets a list of all properties ignored at runtime using <c>IgnoreProperty(x => x.y)</c>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -122,7 +128,7 @@ namespace Artemis.Core.Modules
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a read only collection of default profile paths
|
/// Gets a read only collection of default profile paths
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IReadOnlyCollection<(DefaultCategoryName, string)> DefaultProfilePaths => _defaultProfilePaths.AsReadOnly();
|
public IReadOnlyCollection<(DefaultCategoryName, string)> DefaultProfilePaths { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A list of activation requirements
|
/// A list of activation requirements
|
||||||
@ -176,7 +182,7 @@ namespace Artemis.Core.Modules
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a list of all properties ignored at runtime using <c>IgnoreProperty(x => x.y)</c>
|
/// Gets a list of all properties ignored at runtime using <c>IgnoreProperty(x => x.y)</c>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReadOnlyCollection<PropertyInfo> HiddenProperties => HiddenPropertiesList.AsReadOnly();
|
public ReadOnlyCollection<PropertyInfo> HiddenProperties { get; }
|
||||||
|
|
||||||
internal DataModel? InternalDataModel { get; set; }
|
internal DataModel? InternalDataModel { get; set; }
|
||||||
|
|
||||||
|
|||||||
@ -30,6 +30,9 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
_features = new List<PluginFeatureInfo>();
|
_features = new List<PluginFeatureInfo>();
|
||||||
_profilers = new List<Profiler>();
|
_profilers = new List<Profiler>();
|
||||||
|
|
||||||
|
Features = new(_features);
|
||||||
|
Profilers = new(_profilers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -64,12 +67,12 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a read-only collection of all features this plugin provides
|
/// Gets a read-only collection of all features this plugin provides
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReadOnlyCollection<PluginFeatureInfo> Features => _features.AsReadOnly();
|
public ReadOnlyCollection<PluginFeatureInfo> Features { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a read-only collection of profiles running on the plugin
|
/// Gets a read-only collection of profiles running on the plugin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReadOnlyCollection<Profiler> Profilers => _profilers.AsReadOnly();
|
public ReadOnlyCollection<Profiler> Profilers { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The assembly the plugin code lives in
|
/// The assembly the plugin code lives in
|
||||||
|
|||||||
@ -44,6 +44,11 @@ namespace Artemis.Core.ScriptingProviders
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class ScriptingProvider : PluginFeature
|
public abstract class ScriptingProvider : PluginFeature
|
||||||
{
|
{
|
||||||
|
protected ScriptingProvider()
|
||||||
|
{
|
||||||
|
Scripts = new(InternalScripts);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the name of the scripting language this provider provides
|
/// Gets the name of the scripting language this provider provides
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -52,7 +57,7 @@ namespace Artemis.Core.ScriptingProviders
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a list of all active scripts belonging to this scripting provider
|
/// Gets a list of all active scripts belonging to this scripting provider
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReadOnlyCollection<Script> Scripts => InternalScripts.AsReadOnly();
|
public ReadOnlyCollection<Script> Scripts { get; }
|
||||||
|
|
||||||
internal abstract Type GlobalScriptType { get; }
|
internal abstract Type GlobalScriptType { get; }
|
||||||
internal abstract Type ProfileScriptType { get; }
|
internal abstract Type ProfileScriptType { get; }
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
using System.Buffers;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Artemis.Core.SkiaSharp;
|
using Artemis.Core.SkiaSharp;
|
||||||
using RGB.NET.Core;
|
using RGB.NET.Core;
|
||||||
@ -13,22 +14,36 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class SKTexture : PixelTexture<byte>, IDisposable
|
public sealed class SKTexture : PixelTexture<byte>, IDisposable
|
||||||
{
|
{
|
||||||
private readonly bool _isScaledDown;
|
|
||||||
private readonly SKPixmap _pixelData;
|
private readonly SKPixmap _pixelData;
|
||||||
private readonly IntPtr _pixelDataPtr;
|
private readonly IntPtr _pixelDataPtr;
|
||||||
|
private readonly Dictionary<Led, SKRectI> _ledRects;
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
internal SKTexture(IManagedGraphicsContext? graphicsContext, int width, int height, float scale) : base(width, height, DATA_PER_PIXEL, new AverageByteSampler())
|
internal SKTexture(IManagedGraphicsContext? graphicsContext, int width, int height, float scale, IReadOnlyCollection<ArtemisDevice> devices) : base(width, height, DATA_PER_PIXEL,
|
||||||
|
new AverageByteSampler())
|
||||||
{
|
{
|
||||||
ImageInfo = new SKImageInfo(width, height);
|
ImageInfo = new SKImageInfo(width, height);
|
||||||
Surface = graphicsContext == null
|
Surface = graphicsContext == null
|
||||||
? SKSurface.Create(ImageInfo)
|
? SKSurface.Create(ImageInfo)
|
||||||
: SKSurface.Create(graphicsContext.GraphicsContext, true, ImageInfo);
|
: SKSurface.Create(graphicsContext.GraphicsContext, true, ImageInfo);
|
||||||
RenderScale = scale;
|
RenderScale = scale;
|
||||||
_isScaledDown = Math.Abs(scale - 1) > 0.001;
|
|
||||||
_pixelDataPtr = Marshal.AllocHGlobal(ImageInfo.BytesSize);
|
_pixelDataPtr = Marshal.AllocHGlobal(ImageInfo.BytesSize);
|
||||||
_pixelData = new SKPixmap(ImageInfo, _pixelDataPtr, ImageInfo.RowBytes);
|
_pixelData = new SKPixmap(ImageInfo, _pixelDataPtr, ImageInfo.RowBytes);
|
||||||
|
|
||||||
|
_ledRects = new Dictionary<Led, SKRectI>();
|
||||||
|
foreach (ArtemisDevice artemisDevice in devices)
|
||||||
|
{
|
||||||
|
foreach (ArtemisLed artemisLed in artemisDevice.Leds)
|
||||||
|
{
|
||||||
|
_ledRects[artemisLed.RgbLed] = SKRectI.Create(
|
||||||
|
(int) (artemisLed.AbsoluteRectangle.Left * RenderScale),
|
||||||
|
(int) (artemisLed.AbsoluteRectangle.Top * RenderScale),
|
||||||
|
(int) (artemisLed.AbsoluteRectangle.Width * RenderScale),
|
||||||
|
(int) (artemisLed.AbsoluteRectangle.Height * RenderScale)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -80,63 +95,11 @@ namespace Artemis.Core
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override Color GetColor(in ReadOnlySpan<byte> pixel)
|
protected override Color GetColor(in ReadOnlySpan<byte> pixel)
|
||||||
{
|
{
|
||||||
return new(pixel[2], pixel[1], pixel[0]);
|
return new Color(pixel[2], pixel[1], pixel[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override Color this[in Rectangle rectangle]
|
public override Color this[in Rectangle rectangle] => Color.Transparent;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (Data.Length == 0) return Color.Transparent;
|
|
||||||
|
|
||||||
SKRectI skRectI = CreatedFlooredRectI(
|
|
||||||
Size.Width * rectangle.Location.X.Clamp(0, 1),
|
|
||||||
Size.Height * rectangle.Location.Y.Clamp(0, 1),
|
|
||||||
Size.Width * rectangle.Size.Width.Clamp(0, 1),
|
|
||||||
Size.Height * rectangle.Size.Height.Clamp(0, 1)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (skRectI.Width == 0 || skRectI.Height == 0) return Color.Transparent;
|
|
||||||
if (skRectI.Width == 1 && skRectI.Height == 1) return GetColor(GetPixelData(skRectI.Left, skRectI.Top));
|
|
||||||
|
|
||||||
int bufferSize = skRectI.Width * skRectI.Height * DATA_PER_PIXEL;
|
|
||||||
if (bufferSize <= STACK_ALLOC_LIMIT)
|
|
||||||
{
|
|
||||||
Span<byte> buffer = stackalloc byte[bufferSize];
|
|
||||||
GetRegionData(skRectI.Left, skRectI.Top, skRectI.Width, skRectI.Height, buffer);
|
|
||||||
|
|
||||||
Span<byte> pixelData = stackalloc byte[DATA_PER_PIXEL];
|
|
||||||
Sampler.Sample(new SamplerInfo<byte>(skRectI.Width, skRectI.Height, buffer), pixelData);
|
|
||||||
|
|
||||||
return GetColor(pixelData);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
byte[] rent = ArrayPool<byte>.Shared.Rent(bufferSize);
|
|
||||||
|
|
||||||
Span<byte> buffer = new Span<byte>(rent).Slice(0, bufferSize);
|
|
||||||
GetRegionData(skRectI.Left, skRectI.Top, skRectI.Width, skRectI.Height, buffer);
|
|
||||||
|
|
||||||
Span<byte> pixelData = stackalloc byte[DATA_PER_PIXEL];
|
|
||||||
Sampler.Sample(new SamplerInfo<byte>(skRectI.Width, skRectI.Height, buffer), pixelData);
|
|
||||||
|
|
||||||
ArrayPool<byte>.Shared.Return(rent);
|
|
||||||
|
|
||||||
return GetColor(pixelData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static SKRectI CreatedFlooredRectI(float x, float y, float width, float height)
|
|
||||||
{
|
|
||||||
return new(
|
|
||||||
width <= 0.0 ? checked((int) Math.Floor(x)) : checked((int) Math.Ceiling(x)),
|
|
||||||
height <= 0.0 ? checked((int) Math.Floor(y)) : checked((int) Math.Ceiling(y)),
|
|
||||||
width >= 0.0 ? checked((int) Math.Floor(x + width)) : checked((int) Math.Ceiling(x + width)),
|
|
||||||
height >= 0.0 ? checked((int) Math.Floor(y + height)) : checked((int) Math.Ceiling(y + height))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -169,5 +132,40 @@ namespace Artemis.Core
|
|||||||
public bool IsInvalid { get; private set; }
|
public bool IsInvalid { get; private set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
internal Color GetColorAtRenderTarget(in RenderTarget renderTarget)
|
||||||
|
{
|
||||||
|
if (Data.Length == 0) return Color.Transparent;
|
||||||
|
SKRectI skRectI = _ledRects[renderTarget.Led];
|
||||||
|
|
||||||
|
if (skRectI.Width <= 0 || skRectI.Height <= 0)
|
||||||
|
return Color.Transparent;
|
||||||
|
|
||||||
|
int bufferSize = skRectI.Width * skRectI.Height * DATA_PER_PIXEL;
|
||||||
|
if (bufferSize <= STACK_ALLOC_LIMIT)
|
||||||
|
{
|
||||||
|
Span<byte> buffer = stackalloc byte[bufferSize];
|
||||||
|
GetRegionData(skRectI.Left, skRectI.Top, skRectI.Width, skRectI.Height, buffer);
|
||||||
|
|
||||||
|
Span<byte> pixelData = stackalloc byte[DATA_PER_PIXEL];
|
||||||
|
Sampler.Sample(new SamplerInfo<byte>(skRectI.Width, skRectI.Height, buffer), pixelData);
|
||||||
|
|
||||||
|
return GetColor(pixelData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byte[] rent = ArrayPool<byte>.Shared.Rent(bufferSize);
|
||||||
|
|
||||||
|
Span<byte> buffer = new Span<byte>(rent).Slice(0, bufferSize);
|
||||||
|
GetRegionData(skRectI.Left, skRectI.Top, skRectI.Width, skRectI.Height, buffer);
|
||||||
|
|
||||||
|
Span<byte> pixelData = stackalloc byte[DATA_PER_PIXEL];
|
||||||
|
Sampler.Sample(new SamplerInfo<byte>(skRectI.Width, skRectI.Height, buffer), pixelData);
|
||||||
|
|
||||||
|
ArrayPool<byte>.Shared.Return(rent);
|
||||||
|
|
||||||
|
return GetColor(pixelData);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
44
src/Artemis.Core/RGB.NET/SKTextureBrush.cs
Normal file
44
src/Artemis.Core/RGB.NET/SKTextureBrush.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
using RGB.NET.Core;
|
||||||
|
|
||||||
|
namespace Artemis.Core
|
||||||
|
{
|
||||||
|
internal class SKTextureBrush : AbstractBrush
|
||||||
|
{
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
|
private SKTexture? _texture;
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the texture drawn by this brush.
|
||||||
|
/// </summary>
|
||||||
|
public SKTexture? Texture
|
||||||
|
{
|
||||||
|
get => _texture;
|
||||||
|
set => SetProperty(ref _texture, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="TextureBrush" /> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="texture">The texture drawn by this brush.</param>
|
||||||
|
public SKTextureBrush(SKTexture? texture)
|
||||||
|
{
|
||||||
|
this.Texture = texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override Color GetColorAtPoint(in Rectangle rectangle, in RenderTarget renderTarget)
|
||||||
|
{
|
||||||
|
return Texture?.GetColorAtRenderTarget(renderTarget) ?? Color.Transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -25,7 +25,7 @@ namespace Artemis.Core.Services
|
|||||||
private readonly IPluginManagementService _pluginManagementService;
|
private readonly IPluginManagementService _pluginManagementService;
|
||||||
private readonly PluginSetting<double> _renderScaleSetting;
|
private readonly PluginSetting<double> _renderScaleSetting;
|
||||||
private readonly PluginSetting<int> _targetFrameRateSetting;
|
private readonly PluginSetting<int> _targetFrameRateSetting;
|
||||||
private readonly TextureBrush _textureBrush = new(ITexture.Empty) {CalculationMode = RenderMode.Absolute};
|
private readonly SKTextureBrush _textureBrush = new(null) {CalculationMode = RenderMode.Absolute};
|
||||||
private Dictionary<Led, ArtemisLed> _ledMap;
|
private Dictionary<Led, ArtemisLed> _ledMap;
|
||||||
private ListLedGroup? _surfaceLedGroup;
|
private ListLedGroup? _surfaceLedGroup;
|
||||||
private SKTexture? _texture;
|
private SKTexture? _texture;
|
||||||
@ -36,9 +36,10 @@ namespace Artemis.Core.Services
|
|||||||
_pluginManagementService = pluginManagementService;
|
_pluginManagementService = pluginManagementService;
|
||||||
_deviceRepository = deviceRepository;
|
_deviceRepository = deviceRepository;
|
||||||
_targetFrameRateSetting = settingsService.GetSetting("Core.TargetFrameRate", 25);
|
_targetFrameRateSetting = settingsService.GetSetting("Core.TargetFrameRate", 25);
|
||||||
_renderScaleSetting = settingsService.GetSetting("Core.RenderScale", 0.5);
|
_renderScaleSetting = settingsService.GetSetting("Core.RenderScale", 0.25);
|
||||||
|
|
||||||
Surface = new RGBSurface();
|
Surface = new RGBSurface();
|
||||||
|
Utilities.RenderScaleMultiplier = (int) (1 / _renderScaleSetting.Value);
|
||||||
|
|
||||||
// Let's throw these for now
|
// Let's throw these for now
|
||||||
Surface.Exception += SurfaceOnException;
|
Surface.Exception += SurfaceOnException;
|
||||||
@ -49,10 +50,14 @@ namespace Artemis.Core.Services
|
|||||||
_devices = new List<ArtemisDevice>();
|
_devices = new List<ArtemisDevice>();
|
||||||
_ledMap = new Dictionary<Led, ArtemisLed>();
|
_ledMap = new Dictionary<Led, ArtemisLed>();
|
||||||
|
|
||||||
|
EnabledDevices = new ReadOnlyCollection<ArtemisDevice>(_enabledDevices);
|
||||||
|
Devices = new ReadOnlyCollection<ArtemisDevice>(_devices);
|
||||||
|
LedMap = new ReadOnlyDictionary<Led, ArtemisLed>(_ledMap);
|
||||||
|
|
||||||
UpdateTrigger = new TimerUpdateTrigger {UpdateFrequency = 1.0 / _targetFrameRateSetting.Value};
|
UpdateTrigger = new TimerUpdateTrigger {UpdateFrequency = 1.0 / _targetFrameRateSetting.Value};
|
||||||
SetRenderPaused(true);
|
SetRenderPaused(true);
|
||||||
Surface.RegisterUpdateTrigger(UpdateTrigger);
|
Surface.RegisterUpdateTrigger(UpdateTrigger);
|
||||||
|
|
||||||
Utilities.ShutdownRequested += UtilitiesOnShutdownRequested;
|
Utilities.ShutdownRequested += UtilitiesOnShutdownRequested;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,10 +90,11 @@ namespace Artemis.Core.Services
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
_ledMap = new Dictionary<Led, ArtemisLed>(_devices.SelectMany(d => d.Leds).ToDictionary(l => l.RgbLed));
|
_ledMap = new Dictionary<Led, ArtemisLed>(_devices.SelectMany(d => d.Leds).ToDictionary(l => l.RgbLed));
|
||||||
|
LedMap = new ReadOnlyDictionary<Led, ArtemisLed>(_ledMap);
|
||||||
|
|
||||||
if (_surfaceLedGroup == null)
|
if (_surfaceLedGroup == null)
|
||||||
{
|
{
|
||||||
_surfaceLedGroup = new ListLedGroup(Surface, LedMap.Select(l => l.Key)) { Brush = _textureBrush };
|
_surfaceLedGroup = new ListLedGroup(Surface, LedMap.Select(l => l.Key)) {Brush = _textureBrush};
|
||||||
OnLedsChanged();
|
OnLedsChanged();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -99,7 +105,7 @@ namespace Artemis.Core.Services
|
|||||||
_surfaceLedGroup.Detach();
|
_surfaceLedGroup.Detach();
|
||||||
|
|
||||||
// Apply the application wide brush and decorator
|
// Apply the application wide brush and decorator
|
||||||
_surfaceLedGroup = new ListLedGroup(Surface, LedMap.Select(l => l.Key)) { Brush = _textureBrush };
|
_surfaceLedGroup = new ListLedGroup(Surface, LedMap.Select(l => l.Key)) {Brush = _textureBrush};
|
||||||
OnLedsChanged();
|
OnLedsChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,7 +114,6 @@ namespace Artemis.Core.Services
|
|||||||
if (changedRenderPaused)
|
if (changedRenderPaused)
|
||||||
SetRenderPaused(false);
|
SetRenderPaused(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TargetFrameRateSettingOnSettingChanged(object? sender, EventArgs e)
|
private void TargetFrameRateSettingOnSettingChanged(object? sender, EventArgs e)
|
||||||
@ -129,12 +134,17 @@ namespace Artemis.Core.Services
|
|||||||
|
|
||||||
private void RenderScaleSettingOnSettingChanged(object? sender, EventArgs e)
|
private void RenderScaleSettingOnSettingChanged(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
Utilities.RenderScaleMultiplier = (int) (1 / _renderScaleSetting.Value);
|
||||||
|
|
||||||
_texture?.Invalidate();
|
_texture?.Invalidate();
|
||||||
|
foreach (ArtemisDevice artemisDevice in Devices)
|
||||||
|
artemisDevice.CalculateRenderProperties();
|
||||||
|
OnLedsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IReadOnlyCollection<ArtemisDevice> EnabledDevices => _enabledDevices.AsReadOnly();
|
public IReadOnlyCollection<ArtemisDevice> EnabledDevices { get; }
|
||||||
public IReadOnlyCollection<ArtemisDevice> Devices => _devices.AsReadOnly();
|
public IReadOnlyCollection<ArtemisDevice> Devices { get; }
|
||||||
public IReadOnlyDictionary<Led, ArtemisLed> LedMap => new ReadOnlyDictionary<Led, ArtemisLed>(_ledMap);
|
public IReadOnlyDictionary<Led, ArtemisLed> LedMap { get; private set; }
|
||||||
|
|
||||||
public RGBSurface Surface { get; set; }
|
public RGBSurface Surface { get; set; }
|
||||||
public bool IsRenderPaused { get; set; }
|
public bool IsRenderPaused { get; set; }
|
||||||
@ -310,7 +320,7 @@ namespace Artemis.Core.Services
|
|||||||
int height = Math.Max(1, MathF.Min(evenHeight * renderScale, 4096).RoundToInt());
|
int height = Math.Max(1, MathF.Min(evenHeight * renderScale, 4096).RoundToInt());
|
||||||
|
|
||||||
_texture?.Dispose();
|
_texture?.Dispose();
|
||||||
_texture = new SKTexture(graphicsContext, width, height, renderScale);
|
_texture = new SKTexture(graphicsContext, width, height, renderScale, Devices);
|
||||||
_textureBrush.Texture = _texture;
|
_textureBrush.Texture = _texture;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -24,6 +24,7 @@ namespace Artemis.Core.Services
|
|||||||
_profileService = profileService;
|
_profileService = profileService;
|
||||||
|
|
||||||
InternalGlobalScripts = new List<GlobalScript>();
|
InternalGlobalScripts = new List<GlobalScript>();
|
||||||
|
GlobalScripts = new(InternalGlobalScripts);
|
||||||
|
|
||||||
_pluginManagementService.PluginFeatureEnabled += PluginManagementServiceOnPluginFeatureToggled;
|
_pluginManagementService.PluginFeatureEnabled += PluginManagementServiceOnPluginFeatureToggled;
|
||||||
_pluginManagementService.PluginFeatureDisabled += PluginManagementServiceOnPluginFeatureToggled;
|
_pluginManagementService.PluginFeatureDisabled += PluginManagementServiceOnPluginFeatureToggled;
|
||||||
@ -80,7 +81,7 @@ namespace Artemis.Core.Services
|
|||||||
CreateScriptInstance(profile, scriptConfiguration);
|
CreateScriptInstance(profile, scriptConfiguration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyCollection<GlobalScript> GlobalScripts => InternalGlobalScripts.AsReadOnly();
|
public ReadOnlyCollection<GlobalScript> GlobalScripts { get; }
|
||||||
|
|
||||||
public GlobalScript? CreateScriptInstance(ScriptConfiguration scriptConfiguration)
|
public GlobalScript? CreateScriptInstance(ScriptConfiguration scriptConfiguration)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -4,6 +4,7 @@ using System.Collections.ObjectModel;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Artemis.Core.Modules;
|
using Artemis.Core.Modules;
|
||||||
|
using Artemis.Core.Properties;
|
||||||
using Artemis.Storage.Entities.Profile;
|
using Artemis.Storage.Entities.Profile;
|
||||||
using Artemis.Storage.Repositories.Interfaces;
|
using Artemis.Storage.Repositories.Interfaces;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
@ -39,8 +40,7 @@ namespace Artemis.Core.Services
|
|||||||
_profileCategoryRepository = profileCategoryRepository;
|
_profileCategoryRepository = profileCategoryRepository;
|
||||||
_pluginManagementService = pluginManagementService;
|
_pluginManagementService = pluginManagementService;
|
||||||
_profileRepository = profileRepository;
|
_profileRepository = profileRepository;
|
||||||
_profileCategories = new List<ProfileCategory>(_profileCategoryRepository.GetAll()
|
_profileCategories = new List<ProfileCategory>(_profileCategoryRepository.GetAll().Select(c => new ProfileCategory(c)).OrderBy(c => c.Order));
|
||||||
.Select(c => new ProfileCategory(c)).OrderBy(c => c.Order));
|
|
||||||
|
|
||||||
_rgbService.LedsChanged += RgbServiceOnLedsChanged;
|
_rgbService.LedsChanged += RgbServiceOnLedsChanged;
|
||||||
_pluginManagementService.PluginFeatureEnabled += PluginManagementServiceOnPluginFeatureToggled;
|
_pluginManagementService.PluginFeatureEnabled += PluginManagementServiceOnPluginFeatureToggled;
|
||||||
|
|||||||
@ -4,6 +4,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.AccessControl;
|
using System.Security.AccessControl;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
|
using SkiaSharp;
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
@ -18,8 +19,8 @@ namespace Artemis.Core
|
|||||||
public static void PrepareFirstLaunch()
|
public static void PrepareFirstLaunch()
|
||||||
{
|
{
|
||||||
CreateAccessibleDirectory(Constants.DataFolder);
|
CreateAccessibleDirectory(Constants.DataFolder);
|
||||||
CreateAccessibleDirectory(Path.Combine(Constants.DataFolder ,"plugins"));
|
CreateAccessibleDirectory(Path.Combine(Constants.DataFolder, "plugins"));
|
||||||
CreateAccessibleDirectory(Path.Combine(Constants.DataFolder ,"user layouts"));
|
CreateAccessibleDirectory(Path.Combine(Constants.DataFolder, "user layouts"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -102,6 +103,30 @@ namespace Artemis.Core
|
|||||||
RestartRequested?.Invoke(null, e);
|
RestartRequested?.Invoke(null, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Scaling
|
||||||
|
|
||||||
|
internal static int RenderScaleMultiplier { get; set; } = 2;
|
||||||
|
|
||||||
|
internal static SKRectI CreateScaleCompatibleRect(float x, float y, float width, float height)
|
||||||
|
{
|
||||||
|
int roundX = (int) MathF.Floor(x);
|
||||||
|
int roundY = (int) MathF.Floor(y);
|
||||||
|
int roundWidth = (int) MathF.Ceiling(width);
|
||||||
|
int roundHeight = (int) MathF.Ceiling(height);
|
||||||
|
|
||||||
|
if (RenderScaleMultiplier == 1)
|
||||||
|
return SKRectI.Create(roundX, roundY, roundWidth, roundHeight);
|
||||||
|
|
||||||
|
return SKRectI.Create(
|
||||||
|
roundX - (roundX % RenderScaleMultiplier),
|
||||||
|
roundY - (roundY % RenderScaleMultiplier),
|
||||||
|
roundWidth - (roundWidth % RenderScaleMultiplier),
|
||||||
|
roundHeight - (roundHeight % RenderScaleMultiplier)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.Modules;
|
using Artemis.Core.Modules;
|
||||||
@ -23,10 +24,13 @@ namespace Artemis.UI.Shared.Services
|
|||||||
_kernel = kernel;
|
_kernel = kernel;
|
||||||
_registeredDataModelEditors = new List<DataModelVisualizationRegistration>();
|
_registeredDataModelEditors = new List<DataModelVisualizationRegistration>();
|
||||||
_registeredDataModelDisplays = new List<DataModelVisualizationRegistration>();
|
_registeredDataModelDisplays = new List<DataModelVisualizationRegistration>();
|
||||||
|
|
||||||
|
RegisteredDataModelEditors = new ReadOnlyCollection<DataModelVisualizationRegistration>(_registeredDataModelEditors);
|
||||||
|
RegisteredDataModelDisplays = new ReadOnlyCollection<DataModelVisualizationRegistration>(_registeredDataModelDisplays);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IReadOnlyCollection<DataModelVisualizationRegistration> RegisteredDataModelEditors => _registeredDataModelEditors.AsReadOnly();
|
public IReadOnlyCollection<DataModelVisualizationRegistration> RegisteredDataModelEditors { get; }
|
||||||
public IReadOnlyCollection<DataModelVisualizationRegistration> RegisteredDataModelDisplays => _registeredDataModelDisplays.AsReadOnly();
|
public IReadOnlyCollection<DataModelVisualizationRegistration> RegisteredDataModelDisplays { get; }
|
||||||
|
|
||||||
public DataModelPropertiesViewModel GetMainDataModelVisualization()
|
public DataModelPropertiesViewModel GetMainDataModelVisualization()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -39,6 +39,8 @@ namespace Artemis.UI.Shared.Services
|
|||||||
_rgbService = rgbService;
|
_rgbService = rgbService;
|
||||||
_moduleService = moduleService;
|
_moduleService = moduleService;
|
||||||
_registeredPropertyEditors = new List<PropertyInputRegistration>();
|
_registeredPropertyEditors = new List<PropertyInputRegistration>();
|
||||||
|
|
||||||
|
RegisteredPropertyEditors = new(_registeredPropertyEditors);
|
||||||
coreService.FrameRendered += CoreServiceOnFrameRendered;
|
coreService.FrameRendered += CoreServiceOnFrameRendered;
|
||||||
|
|
||||||
TypeUtilities.NodeService = nodeService;
|
TypeUtilities.NodeService = nodeService;
|
||||||
@ -154,7 +156,8 @@ namespace Artemis.UI.Shared.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyCollection<PropertyInputRegistration> RegisteredPropertyEditors => _registeredPropertyEditors.AsReadOnly();
|
public ReadOnlyCollection<PropertyInputRegistration> RegisteredPropertyEditors { get; }
|
||||||
|
|
||||||
public bool Playing { get; set; }
|
public bool Playing { get; set; }
|
||||||
|
|
||||||
public bool SuspendEditing
|
public bool SuspendEditing
|
||||||
|
|||||||
@ -343,8 +343,7 @@
|
|||||||
<StackPanel Grid.Column="0">
|
<StackPanel Grid.Column="0">
|
||||||
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Render scale</TextBlock>
|
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Render scale</TextBlock>
|
||||||
<TextBlock Style="{StaticResource MaterialDesignTextBlock}" Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}" TextWrapping="Wrap">
|
<TextBlock Style="{StaticResource MaterialDesignTextBlock}" Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}" TextWrapping="Wrap">
|
||||||
Sets the resolution Artemis renders at, higher scale means more CPU-usage, especially on large surfaces. <LineBreak />
|
Sets the resolution Artemis renders at, higher scale means more CPU-usage, especially on large surfaces.
|
||||||
<Run Foreground="GoldenRod">A scale of 25% may be required for very large surfaces but could cause LED dimming or bleeding.</Run>
|
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||||
|
|||||||
@ -216,11 +216,11 @@ namespace Artemis.UI.Screens.Settings.Tabs.General
|
|||||||
|
|
||||||
public double RenderScale
|
public double RenderScale
|
||||||
{
|
{
|
||||||
get => _settingsService.GetSetting("Core.RenderScale", 0.5).Value;
|
get => _settingsService.GetSetting("Core.RenderScale", 0.25).Value;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_settingsService.GetSetting("Core.RenderScale", 0.5).Value = value;
|
_settingsService.GetSetting("Core.RenderScale", 0.25).Value = value;
|
||||||
_settingsService.GetSetting("Core.RenderScale", 0.5).Save();
|
_settingsService.GetSetting("Core.RenderScale", 0.25).Save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -108,7 +108,7 @@ namespace Artemis.UI.Screens.SurfaceEditor
|
|||||||
set => SetAndNotify(ref _colorFirstLedOnly, value);
|
set => SetAndNotify(ref _colorFirstLedOnly, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double MaxTextureSize => 4096 / _settingsService.GetSetting("Core.RenderScale", 0.5).Value;
|
public double MaxTextureSize => 4096 / _settingsService.GetSetting("Core.RenderScale", 0.25).Value;
|
||||||
public double MaxTextureSizeIndicatorThickness => 2 / PanZoomViewModel.Zoom;
|
public double MaxTextureSizeIndicatorThickness => 2 / PanZoomViewModel.Zoom;
|
||||||
|
|
||||||
public void OpenHyperlink(object sender, RequestNavigateEventArgs e)
|
public void OpenHyperlink(object sender, RequestNavigateEventArgs e)
|
||||||
|
|||||||
@ -103,7 +103,7 @@ namespace Artemis.UI.Screens.SurfaceEditor.Visualization
|
|||||||
if (x < 0 || y < 0)
|
if (x < 0 || y < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
double maxTextureSize = 4096 / _settingsService.GetSetting("Core.RenderScale", 0.5).Value;
|
double maxTextureSize = 4096 / _settingsService.GetSetting("Core.RenderScale", 0.25).Value;
|
||||||
if (x + Device.Rectangle.Width > maxTextureSize || y + Device.Rectangle.Height > maxTextureSize)
|
if (x + Device.Rectangle.Width > maxTextureSize || y + Device.Rectangle.Height > maxTextureSize)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
|
using RGB.NET.Core;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
using SkiaSharp.Views.WPF;
|
using SkiaSharp.Views.WPF;
|
||||||
|
using Point = System.Windows.Point;
|
||||||
|
|
||||||
namespace Artemis.UI.Services
|
namespace Artemis.UI.Services
|
||||||
{
|
{
|
||||||
@ -12,12 +15,15 @@ namespace Artemis.UI.Services
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Rect GetLayerBounds(Layer layer)
|
public Rect GetLayerBounds(Layer layer)
|
||||||
{
|
{
|
||||||
// Adjust the render rectangle for the difference in render scale
|
return new Rect(
|
||||||
return new(
|
new Point(
|
||||||
layer.Bounds.Left,
|
layer.Leds.Min(l => l.RgbLed.AbsoluteBoundary.Location.X),
|
||||||
layer.Bounds.Top,
|
layer.Leds.Min(l => l.RgbLed.AbsoluteBoundary.Location.Y
|
||||||
Math.Max(0, layer.Bounds.Width),
|
)),
|
||||||
Math.Max(0, layer.Bounds.Height)
|
new Point(
|
||||||
|
layer.Leds.Max(l => l.RgbLed.AbsoluteBoundary.Location.X + l.RgbLed.AbsoluteBoundary.Size.Width),
|
||||||
|
layer.Leds.Max(l => l.RgbLed.AbsoluteBoundary.Location.Y + l.RgbLed.AbsoluteBoundary.Size.Height
|
||||||
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,15 +100,16 @@ namespace Artemis.UI.Services
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public SKPoint GetScaledPoint(Layer layer, SKPoint point, bool absolute)
|
public SKPoint GetScaledPoint(Layer layer, SKPoint point, bool absolute)
|
||||||
{
|
{
|
||||||
|
SKRect bounds = GetLayerBounds(layer).ToSKRect();
|
||||||
if (absolute)
|
if (absolute)
|
||||||
return new SKPoint(
|
return new SKPoint(
|
||||||
100f / layer.Bounds.Width * (point.X - layer.Bounds.Left) / 100f,
|
100 / bounds.Width * (point.X - bounds.Left) / 100,
|
||||||
100f / layer.Bounds.Height * (point.Y - layer.Bounds.Top) / 100f
|
100 / bounds.Height * (point.Y - bounds.Top) / 100
|
||||||
);
|
);
|
||||||
|
|
||||||
return new SKPoint(
|
return new SKPoint(
|
||||||
100f / layer.Bounds.Width * point.X / 100f,
|
100 / bounds.Width * point.X / 100,
|
||||||
100f / layer.Bounds.Height * point.Y / 100f
|
100 / bounds.Height * point.Y / 100
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user