diff --git a/src/Artemis.Core/Events/DynamicDataModelEventArgs.cs b/src/Artemis.Core/Events/DynamicDataModelChildEventArgs.cs
similarity index 52%
rename from src/Artemis.Core/Events/DynamicDataModelEventArgs.cs
rename to src/Artemis.Core/Events/DynamicDataModelChildEventArgs.cs
index c1b335adc..9248a716a 100644
--- a/src/Artemis.Core/Events/DynamicDataModelEventArgs.cs
+++ b/src/Artemis.Core/Events/DynamicDataModelChildEventArgs.cs
@@ -4,20 +4,20 @@ using Artemis.Core.DataModelExpansions;
namespace Artemis.Core
{
///
- /// Provides data about dynamic data model related events
+ /// Provides data about dynamic data model child related events
///
- public class DynamicDataModelEventArgs : EventArgs
+ public class DynamicDataModelChildEventArgs : EventArgs
{
- internal DynamicDataModelEventArgs(DataModel dynamicDataModel, string key)
+ internal DynamicDataModelChildEventArgs(DynamicChild dynamicChild, string key)
{
- DynamicDataModel = dynamicDataModel;
+ DynamicChild = dynamicChild;
Key = key;
}
///
- /// Gets the dynamic data model
+ /// Gets the dynamic data model child
///
- public DataModel DynamicDataModel { get; }
+ public DynamicChild DynamicChild { get; }
///
/// Gets the key of the dynamic data model on the parent
diff --git a/src/Artemis.Core/Models/Profile/DataModel/DataModelPathSegment.cs b/src/Artemis.Core/Models/Profile/DataModel/DataModelPathSegment.cs
index c8fd98d79..27f4294ed 100644
--- a/src/Artemis.Core/Models/Profile/DataModel/DataModelPathSegment.cs
+++ b/src/Artemis.Core/Models/Profile/DataModel/DataModelPathSegment.cs
@@ -15,6 +15,8 @@ namespace Artemis.Core
{
private Expression>? _accessorLambda;
private DataModel? _dynamicDataModel;
+ private Type? _dynamicDataModelType;
+ private DataModelPropertyAttribute? _dynamicDataModelAttribute;
internal DataModelPathSegment(DataModelPath dataModelPath, string identifier, string path)
{
@@ -49,12 +51,6 @@ namespace Artemis.Core
///
public DataModelPathSegmentType Type { get; private set; }
- ///
- /// Gets the type of dynamic data model this path points to
- /// Not used if the is
- ///
- public Type? DynamicDataModelType { get; private set; }
-
///
/// Gets the previous segment in the path
///
@@ -114,7 +110,7 @@ namespace Artemis.Core
{
// Dynamic types have a data model description
if (Type == DataModelPathSegmentType.Dynamic)
- return (GetValue() as DataModel)?.DataModelDescription;
+ return _dynamicDataModelAttribute;
if (IsStartSegment && DataModelPath.Target != null)
return DataModelPath.Target.DataModelDescription;
if (IsStartSegment)
@@ -187,12 +183,12 @@ namespace Artemis.Core
return CreateExpression(parameter, expression, nullCondition);
// If a dynamic data model is found the use that
- bool hasDynamicDataModel = _dynamicDataModel.DynamicDataModels.TryGetValue(Identifier, out DataModel? dynamicDataModel);
- if (hasDynamicDataModel && dynamicDataModel != null)
- DetermineDynamicType(dynamicDataModel);
+ bool hasDynamicChild = _dynamicDataModel.DynamicChildren.TryGetValue(Identifier, out DynamicChild? dynamicChild);
+ if (hasDynamicChild && dynamicChild?.BaseValue != null)
+ DetermineDynamicType(dynamicChild.BaseValue, dynamicChild.Attribute);
- _dynamicDataModel.DynamicDataModelAdded += DynamicDataModelOnDynamicDataModelAdded;
- _dynamicDataModel.DynamicDataModelRemoved += DynamicDataModelOnDynamicDataModelRemoved;
+ _dynamicDataModel.DynamicChildAdded += DynamicChildOnDynamicChildAdded;
+ _dynamicDataModel.DynamicChildRemoved += DynamicChildOnDynamicChildRemoved;
}
return CreateExpression(parameter, expression, nullCondition);
@@ -216,12 +212,14 @@ namespace Artemis.Core
accessorExpression = Expression.PropertyOrField(expression, Identifier);
// A dynamic segment calls the generic method DataModel.DynamicChild and provides the identifier as an argument
else
+ {
accessorExpression = Expression.Call(
expression,
- nameof(DataModel.DynamicChild),
- DynamicDataModelType != null ? new[] {DynamicDataModelType} : null,
+ nameof(DataModel.GetDynamicChildValue),
+ _dynamicDataModelType != null ? new[] { _dynamicDataModelType } : null,
Expression.Constant(Identifier)
);
+ }
_accessorLambda = Expression.Lambda>(
// Wrap with a null check
@@ -236,10 +234,11 @@ namespace Artemis.Core
return accessorExpression;
}
- private void DetermineDynamicType(DataModel dynamicDataModel)
+ private void DetermineDynamicType(object dynamicDataModel, DataModelPropertyAttribute attribute)
{
Type = DataModelPathSegmentType.Dynamic;
- DynamicDataModelType = dynamicDataModel.GetType();
+ _dynamicDataModelType = dynamicDataModel.GetType();
+ _dynamicDataModelAttribute = attribute;
}
private void DetermineStaticType(Type previousType)
@@ -263,8 +262,8 @@ namespace Artemis.Core
{
if (_dynamicDataModel != null)
{
- _dynamicDataModel.DynamicDataModelAdded -= DynamicDataModelOnDynamicDataModelAdded;
- _dynamicDataModel.DynamicDataModelRemoved -= DynamicDataModelOnDynamicDataModelRemoved;
+ _dynamicDataModel.DynamicChildAdded -= DynamicChildOnDynamicChildAdded;
+ _dynamicDataModel.DynamicChildRemoved -= DynamicChildOnDynamicChildRemoved;
}
Type = DataModelPathSegmentType.Invalid;
@@ -285,15 +284,15 @@ namespace Artemis.Core
#region Event handlers
- private void DynamicDataModelOnDynamicDataModelAdded(object? sender, DynamicDataModelEventArgs e)
+ private void DynamicChildOnDynamicChildAdded(object? sender, DynamicDataModelChildEventArgs e)
{
if (e.Key == Identifier)
DataModelPath.Initialize();
}
- private void DynamicDataModelOnDynamicDataModelRemoved(object? sender, DynamicDataModelEventArgs e)
+ private void DynamicChildOnDynamicChildRemoved(object? sender, DynamicDataModelChildEventArgs e)
{
- if (e.DynamicDataModel == _dynamicDataModel)
+ if (e.DynamicChild.BaseValue == _dynamicDataModel)
DataModelPath.Initialize();
}
diff --git a/src/Artemis.Core/Models/Profile/Folder.cs b/src/Artemis.Core/Models/Profile/Folder.cs
index f240a61c6..16231eed8 100644
--- a/src/Artemis.Core/Models/Profile/Folder.cs
+++ b/src/Artemis.Core/Models/Profile/Folder.cs
@@ -195,7 +195,7 @@ namespace Artemis.Core
baseLayerEffect.Update(Timeline.Delta.TotalSeconds);
}
- SKPaint layerPaint = new();
+ SKPaint layerPaint = new() {FilterQuality = SKFilterQuality.Low};
try
{
SKRectI rendererBounds = SKRectI.Create(0, 0, Bounds.Width, Bounds.Height);
diff --git a/src/Artemis.Core/Models/Profile/Layer.cs b/src/Artemis.Core/Models/Profile/Layer.cs
index 4ecf6298c..c7a17bc46 100644
--- a/src/Artemis.Core/Models/Profile/Layer.cs
+++ b/src/Artemis.Core/Models/Profile/Layer.cs
@@ -364,7 +364,7 @@ namespace Artemis.Core
if (LayerBrush?.BrushType != LayerBrushType.Regular)
return;
- SKPaint layerPaint = new();
+ SKPaint layerPaint = new() {FilterQuality = SKFilterQuality.Low};
try
{
canvas.Save();
diff --git a/src/Artemis.Core/Plugins/DataModelExpansions/DataModel.cs b/src/Artemis.Core/Plugins/DataModelExpansions/DataModel.cs
index e207c18eb..57f2c8b7e 100644
--- a/src/Artemis.Core/Plugins/DataModelExpansions/DataModel.cs
+++ b/src/Artemis.Core/Plugins/DataModelExpansions/DataModel.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using Artemis.Core.Modules;
@@ -14,7 +15,7 @@ namespace Artemis.Core.DataModelExpansions
///
public abstract class DataModel
{
- private readonly Dictionary _dynamicDataModels = new();
+ private readonly Dictionary _dynamicChildren = new();
///
/// Creates a new instance of the class
@@ -47,10 +48,10 @@ namespace Artemis.Core.DataModelExpansions
public bool IsExpansion { get; internal set; }
///
- /// Gets an read-only dictionary of all dynamic data models
+ /// Gets an read-only dictionary of all dynamic children
///
[DataModelIgnore]
- public ReadOnlyDictionary DynamicDataModels => new(_dynamicDataModels);
+ public ReadOnlyDictionary DynamicChildren => new(_dynamicChildren);
///
/// Returns a read-only collection of all properties in this datamodel that are to be ignored
@@ -67,122 +68,213 @@ namespace Artemis.Core.DataModelExpansions
}
///
- /// Adds a dynamic data model to this data model
+ /// Occurs when a dynamic child has been added to this data model
///
- /// The dynamic data model to add
- /// The key of the child, must be unique to this data model
- /// An optional name, if not provided the key will be used in a humanized form
- /// An optional description
- public T AddDynamicChild(T dynamicDataModel, string key, string? name = null, string? description = null) where T : DataModel
+ public event EventHandler? DynamicChildAdded;
+
+ ///
+ /// Occurs when a dynamic child has been removed from this data model
+ ///
+ public event EventHandler? DynamicChildRemoved;
+
+ ///
+ /// Invokes the event
+ ///
+ protected virtual void OnDynamicDataModelAdded(DynamicDataModelChildEventArgs e)
{
- if (dynamicDataModel == null)
- throw new ArgumentNullException(nameof(dynamicDataModel));
- if (key == null)
- throw new ArgumentNullException(nameof(key));
+ DynamicChildAdded?.Invoke(this, e);
+ }
+
+ ///
+ /// Invokes the event
+ ///
+ protected virtual void OnDynamicDataModelRemoved(DynamicDataModelChildEventArgs e)
+ {
+ DynamicChildRemoved?.Invoke(this, e);
+ }
+
+ #region Dynamic children
+
+ ///
+ /// Adds a dynamic child to this data model
+ ///
+ /// The key of the child, must be unique to this data model
+ /// The initial value of the dynamic child
+ /// The resulting dynamic child which can be used to further update the value
+ public DynamicChild AddDynamicChild(string key, T initialValue)
+ {
+ return AddDynamicChild(key, initialValue, new DataModelPropertyAttribute());
+ }
+
+ ///
+ /// Adds a dynamic child to this data model
+ ///
+ /// The key of the child, must be unique to this data model
+ /// The initial value of the dynamic child
+ /// A human readable name for your dynamic child, shown in the UI
+ /// An optional description, shown in the UI
+ /// The resulting dynamic child which can be used to further update the value
+ public DynamicChild AddDynamicChild(string key, T initialValue, string name, string? description = null)
+ {
+ return AddDynamicChild(key, initialValue, new DataModelPropertyAttribute {Name = name, Description = description});
+ }
+
+ ///
+ /// Adds a dynamic child to this data model
+ ///
+ /// The key of the child, must be unique to this data model
+ /// The initial value of the dynamic child
+ /// A data model property attribute describing the dynamic child
+ /// The resulting dynamic child which can be used to further update the value
+ public DynamicChild AddDynamicChild(string key, T initialValue, DataModelPropertyAttribute attribute)
+ {
+ if (key == null) throw new ArgumentNullException(nameof(key));
+ if (initialValue == null) throw new ArgumentNullException(nameof(initialValue));
+ if (attribute == null) throw new ArgumentNullException(nameof(attribute));
if (key.Contains('.'))
throw new ArtemisCoreException("The provided key contains an illegal character (.)");
- if (_dynamicDataModels.ContainsKey(key))
- throw new ArtemisCoreException($"Cannot add a dynamic data model with key '{key}' " +
- "because the key is already in use on by another dynamic property this data model.");
-
- if (_dynamicDataModels.ContainsValue(dynamicDataModel))
+ if (_dynamicChildren.ContainsKey(key))
{
- string existingKey = _dynamicDataModels.First(kvp => kvp.Value == dynamicDataModel).Key;
- throw new ArtemisCoreException($"Cannot add a dynamic data model with key '{key}' " +
- $"because the dynamic data model is already added with key '{existingKey}.");
+ throw new ArtemisCoreException($"Cannot add a dynamic child with key '{key}' " +
+ "because the key is already in use on by another dynamic property this data model.");
}
if (GetType().GetProperty(key) != null)
- throw new ArtemisCoreException($"Cannot add a dynamic data model with key '{key}' " +
- "because the key is already in use by a static property on this data model.");
-
- dynamicDataModel.Feature = Feature;
- dynamicDataModel.DataModelDescription = new DataModelPropertyAttribute
{
- Name = string.IsNullOrWhiteSpace(name) ? key.Humanize() : name,
- Description = description
- };
- _dynamicDataModels.Add(key, dynamicDataModel);
+ throw new ArtemisCoreException($"Cannot add a dynamic child with key '{key}' " +
+ "because the key is already in use by a static property on this data model.");
+ }
- OnDynamicDataModelAdded(new DynamicDataModelEventArgs(dynamicDataModel, key));
- return dynamicDataModel;
+ // Make sure a name is on the attribute or funny things might happen
+ attribute.Name ??= key.Humanize();
+ if (initialValue is DataModel dynamicDataModel)
+ {
+ dynamicDataModel.Feature = Feature;
+ dynamicDataModel.DataModelDescription = attribute;
+ }
+
+ DynamicChild dynamicChild = new(initialValue, key, attribute);
+ _dynamicChildren.Add(key, dynamicChild);
+
+ OnDynamicDataModelAdded(new DynamicDataModelChildEventArgs(dynamicChild, key));
+ return dynamicChild;
}
///
- /// Removes a dynamic data model from the data model by its key
+ /// Gets a previously added dynamic child by its key
///
- /// The key of the dynamic data model to remove
+ /// The key of the dynamic child
+ public DynamicChild GetDynamicChild(string key)
+ {
+ if (key == null) throw new ArgumentNullException(nameof(key));
+ return DynamicChildren[key];
+ }
+
+ ///
+ /// Gets a previously added dynamic child by its key
+ ///
+ /// The typer of dynamic child you are expecting
+ /// The key of the dynamic child
+ ///
+ public DynamicChild GetDynamicChild(string key)
+ {
+ if (key == null) throw new ArgumentNullException(nameof(key));
+ return (DynamicChild) DynamicChildren[key];
+ }
+
+ ///
+ /// Gets a previously added dynamic child by its key
+ ///
+ /// The key of the dynamic child
+ ///
+ /// When this method returns, the associated with the specified key,
+ /// if the key is found; otherwise, . This parameter is passed uninitialized.
+ ///
+ ///
+ /// if the data model contains the dynamic child; otherwise
+ ///
+ public bool TryGetDynamicChild(string key, [MaybeNullWhen(false)] out DynamicChild dynamicChild)
+ {
+ if (key == null) throw new ArgumentNullException(nameof(key));
+
+ dynamicChild = null;
+ if (!DynamicChildren.TryGetValue(key, out DynamicChild? value))
+ return false;
+
+ dynamicChild = value;
+ return true;
+ }
+
+ ///
+ /// Gets a previously added dynamic child by its key
+ ///
+ /// The typer of dynamic child you are expecting
+ /// The key of the dynamic child
+ ///
+ /// When this method returns, the associated with the specified
+ /// key, if the key is found and the type matches; otherwise, . This parameter is passed
+ /// uninitialized.
+ ///
+ ///
+ /// if the data model contains the dynamic child; otherwise
+ ///
+ public bool TryGetDynamicChild(string key, [MaybeNullWhen(false)] out DynamicChild dynamicChild)
+ {
+ if (key == null) throw new ArgumentNullException(nameof(key));
+
+ dynamicChild = null;
+ if (!DynamicChildren.TryGetValue(key, out DynamicChild? value))
+ return false;
+ if (value is not DynamicChild typedDynamicChild)
+ return false;
+ dynamicChild = typedDynamicChild;
+ return true;
+ }
+
+ ///
+ /// Removes a dynamic child from the data model by its key
+ ///
+ /// The key of the dynamic child to remove
public void RemoveDynamicChildByKey(string key)
{
- _dynamicDataModels.TryGetValue(key, out DataModel? childDataModel);
- if (childDataModel == null)
+ if (key == null) throw new ArgumentNullException(nameof(key));
+ if (!_dynamicChildren.TryGetValue(key, out DynamicChild? dynamicChild))
return;
- _dynamicDataModels.Remove(key);
- OnDynamicDataModelRemoved(new DynamicDataModelEventArgs(childDataModel, key));
+ _dynamicChildren.Remove(key);
+ OnDynamicDataModelRemoved(new DynamicDataModelChildEventArgs(dynamicChild, key));
}
///
- /// Removes a dynamic data model from this data model
+ /// Removes a dynamic child from this data model
///
- /// The dynamic data model to remove
- public void RemoveDynamicChild(DataModel dynamicDataModel)
+ /// The dynamic data child to remove
+ public void RemoveDynamicChild(DynamicChild dynamicChild)
{
- List keys = _dynamicDataModels.Where(kvp => kvp.Value == dynamicDataModel).Select(kvp => kvp.Key).ToList();
+ if (dynamicChild == null) throw new ArgumentNullException(nameof(dynamicChild));
+ List keys = _dynamicChildren.Where(kvp => kvp.Value.BaseValue == dynamicChild).Select(kvp => kvp.Key).ToList();
foreach (string key in keys)
{
- _dynamicDataModels.Remove(key);
- OnDynamicDataModelRemoved(new DynamicDataModelEventArgs(dynamicDataModel, key));
+ _dynamicChildren.Remove(key);
+ OnDynamicDataModelRemoved(new DynamicDataModelChildEventArgs(dynamicChild, key));
}
}
///
- /// Removes all dynamic data models from this data model
+ /// Removes all dynamic children from this data model
///
public void ClearDynamicChildren()
{
- while (_dynamicDataModels.Any())
- RemoveDynamicChildByKey(_dynamicDataModels.First().Key);
+ while (_dynamicChildren.Any())
+ RemoveDynamicChildByKey(_dynamicChildren.First().Key);
}
- ///
- /// Gets a dynamic data model of type by its key
- ///
- /// The type of data model you expect
- /// The unique key of the dynamic data model
- /// If found, the dynamic data model otherwise null
- public T? DynamicChild(string key) where T : DataModel
+ // Used a runtime by data model paths only
+ internal T? GetDynamicChildValue(string key)
{
- _dynamicDataModels.TryGetValue(key, out DataModel? value);
- return value as T;
- }
-
- #region Events
-
- ///
- /// Occurs when a dynamic data model has been added to this data model
- ///
- public event EventHandler? DynamicDataModelAdded;
-
- ///
- /// Occurs when a dynamic data model has been removed from this data model
- ///
- public event EventHandler? DynamicDataModelRemoved;
-
- ///
- /// Invokes the event
- ///
- protected virtual void OnDynamicDataModelAdded(DynamicDataModelEventArgs e)
- {
- DynamicDataModelAdded?.Invoke(this, e);
- }
-
- ///
- /// Invokes the event
- ///
- protected virtual void OnDynamicDataModelRemoved(DynamicDataModelEventArgs e)
- {
- DynamicDataModelRemoved?.Invoke(this, e);
+ if (TryGetDynamicChild(key, out DynamicChild? dynamicChild) && dynamicChild.BaseValue != null)
+ return (T) dynamicChild.BaseValue;
+ return default;
}
#endregion
diff --git a/src/Artemis.Core/Plugins/DataModelExpansions/DynamicChild.cs b/src/Artemis.Core/Plugins/DataModelExpansions/DynamicChild.cs
new file mode 100644
index 000000000..5e5732b55
--- /dev/null
+++ b/src/Artemis.Core/Plugins/DataModelExpansions/DynamicChild.cs
@@ -0,0 +1,66 @@
+using System;
+
+namespace Artemis.Core.DataModelExpansions
+{
+ ///
+ /// Represents a dynamic child value with its property attribute
+ ///
+ public class DynamicChild : DynamicChild
+ {
+ internal DynamicChild(T value, string key, DataModelPropertyAttribute attribute) : base(key, attribute, typeof(T))
+ {
+ Value = value;
+ }
+
+ ///
+ /// Gets or sets the current value of the dynamic child
+ ///
+ public new T Value { get; set; }
+
+ ///
+ protected override object? GetValue()
+ {
+ return Value;
+ }
+ }
+
+ ///
+ /// Represents a dynamic child value with its property attribute
+ ///
+ public abstract class DynamicChild
+ {
+ internal DynamicChild(string key, DataModelPropertyAttribute attribute, Type type)
+ {
+ if (type == null) throw new ArgumentNullException(nameof(type));
+ Key = key ?? throw new ArgumentNullException(nameof(key));
+ Attribute = attribute ?? throw new ArgumentNullException(nameof(attribute));
+ Type = type;
+ }
+
+ ///
+ /// Gets the key of the dynamic child
+ ///
+ public string Key { get; }
+
+ ///
+ /// Gets the attribute describing the dynamic child
+ ///
+ public DataModelPropertyAttribute Attribute { get; }
+
+ ///
+ /// Gets the type of
+ ///
+ public Type Type { get; }
+
+ ///
+ /// Gets the current value of the dynamic child
+ ///
+ public object? BaseValue => GetValue();
+
+ ///
+ /// Gets the current value of the dynamic child
+ ///
+ /// The current value of the dynamic child
+ protected abstract object? GetValue();
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/RgbService.cs b/src/Artemis.Core/Services/RgbService.cs
index 5e4a5066a..26c66ed54 100644
--- a/src/Artemis.Core/Services/RgbService.cs
+++ b/src/Artemis.Core/Services/RgbService.cs
@@ -113,7 +113,7 @@ namespace Artemis.Core.Services
private void SurfaceOnException(ExceptionEventArgs args)
{
- _logger.Warning("Surface threw e");
+ _logger.Warning(args.Exception, "Surface caught exception");
throw args.Exception;
}
diff --git a/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs b/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs
index fb3b77506..e3fd07f40 100644
--- a/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs
+++ b/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs
@@ -314,6 +314,7 @@ namespace Artemis.UI.Shared
ImageBrush bitmapBrush = new(bitmap);
bitmapBrush.Freeze();
_backingStore.OpacityMask = bitmapBrush;
+ _backingStore.Children.Clear();
InvalidateMeasure();
}
@@ -331,14 +332,19 @@ namespace Artemis.UI.Shared
private void Render()
{
DrawingContext drawingContext = _backingStore.Append();
- // DrawingContext drawingContext = _backingStore.Open();
if (HighlightedLeds != null && HighlightedLeds.Any())
+ {
+ // Faster on large devices, maybe a bit slower on smaller ones but that's ok
+ ILookup toHighlight = HighlightedLeds.ToLookup(l => l);
foreach (DeviceVisualizerLed deviceVisualizerLed in _deviceVisualizerLeds)
- deviceVisualizerLed.RenderColor(_backingStore, drawingContext, !HighlightedLeds.Contains(deviceVisualizerLed.Led));
+ deviceVisualizerLed.RenderColor(_backingStore, drawingContext, !toHighlight.Contains(deviceVisualizerLed.Led));
+ }
else
+ {
foreach (DeviceVisualizerLed deviceVisualizerLed in _deviceVisualizerLeds)
deviceVisualizerLed.RenderColor(_backingStore, drawingContext, false);
+ }
drawingContext.Close();
}
diff --git a/src/Artemis.UI.Shared/Controls/DeviceVisualizerLed.cs b/src/Artemis.UI.Shared/Controls/DeviceVisualizerLed.cs
index 45dc4ac41..cf0699306 100644
--- a/src/Artemis.UI.Shared/Controls/DeviceVisualizerLed.cs
+++ b/src/Artemis.UI.Shared/Controls/DeviceVisualizerLed.cs
@@ -14,10 +14,10 @@ namespace Artemis.UI.Shared
{
private const byte Dimmed = 100;
private const byte NonDimmed = 255;
- private GeometryDrawing? _geometryDrawing;
private Color _renderColor;
-
+ private GeometryDrawing? _geometryDrawing;
private SolidColorBrush? _renderColorBrush;
+ private DrawingGroup? _lastBackingStore;
public DeviceVisualizerLed(ArtemisLed led)
{
@@ -43,12 +43,12 @@ namespace Artemis.UI.Shared
public void RenderColor(DrawingGroup backingStore, DrawingContext drawingContext, bool isDimmed)
{
- if (DisplayGeometry == null)
+ if (DisplayGeometry == null || backingStore == null)
return;
_renderColorBrush ??= new SolidColorBrush();
_geometryDrawing ??= new GeometryDrawing(_renderColorBrush, null, new RectangleGeometry(LedRect));
-
+
byte r = Led.RgbLed.Color.GetR();
byte g = Led.RgbLed.Color.GetG();
byte b = Led.RgbLed.Color.GetB();
@@ -59,9 +59,12 @@ namespace Artemis.UI.Shared
_renderColor.B = b;
_renderColorBrush.Color = _renderColor;
-
- if (!backingStore.Children.Contains(_geometryDrawing))
+ if (_lastBackingStore != backingStore)
+ {
backingStore.Children.Add(_geometryDrawing);
+ _lastBackingStore = backingStore;
+ }
+
}
public void RenderImage(DrawingContext drawingContext)
diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs
index 56bbbf5e7..78490468a 100644
--- a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs
+++ b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs
@@ -239,9 +239,10 @@ namespace Artemis.UI.Shared
// Add missing dynamic children
object? value = Parent == null || Parent.IsRootViewModel ? DataModel : DataModelPath?.GetValue();
if (value is DataModel dataModel)
- foreach (KeyValuePair kvp in dataModel.DynamicDataModels)
+ {
+ foreach (var (key, dynamicChild) in dataModel.DynamicChildren)
{
- string childPath = AppendToPath(kvp.Key);
+ string childPath = AppendToPath(key);
if (Children.Any(c => c.Path != null && c.Path.Equals(childPath)))
continue;
@@ -249,6 +250,7 @@ namespace Artemis.UI.Shared
if (child != null)
Children.Add(child);
}
+ }
// Remove dynamic children that have been removed from the data model
List toRemoveDynamic = Children.Where(c => c.DataModelPath != null && !c.DataModelPath.IsValid).ToList();
diff --git a/src/Artemis.UI.Shared/DefaultTypes/DataModel/Display/DefaultDataModelDisplayView.xaml b/src/Artemis.UI.Shared/DefaultTypes/DataModel/Display/DefaultDataModelDisplayView.xaml
index a190a550a..b722b7d59 100644
--- a/src/Artemis.UI.Shared/DefaultTypes/DataModel/Display/DefaultDataModelDisplayView.xaml
+++ b/src/Artemis.UI.Shared/DefaultTypes/DataModel/Display/DefaultDataModelDisplayView.xaml
@@ -14,16 +14,19 @@
-
-
+
+
+
-
+
+
+
@@ -15,25 +16,49 @@
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file