Nodes - Added type color registration system

Nodes - Generate (stable) type colors for undefined types
This commit is contained in:
Robert committed 2021-08-19 11:40:50 +02:00
1 parent 5675d1895b
commit b8077ca589
12 files changed
+297 -147

No files matched your search

@@ -20,10 +20,10 @@ namespace Artemis.UI.Shared.Services
{
private readonly IKernel _kernel;
private readonly ILogger _logger;
private readonly IModuleService _moduleService;
private readonly IProfileService _profileService;
private readonly List<PropertyInputRegistration> _registeredPropertyEditors;
private readonly IRgbService _rgbService;
private readonly IModuleService _moduleService;
private readonly object _selectedProfileElementLock = new();
private readonly object _selectedProfileLock = new();
private TimeSpan _currentTime;
@@ -31,7 +31,8 @@ namespace Artemis.UI.Shared.Services
private int _pixelsPerSecond;
private bool _suspendEditing;
public ProfileEditorService(IKernel kernel, ILogger logger, IProfileService profileService, ICoreService coreService, IRgbService rgbService, IModuleService moduleService)
public ProfileEditorService(IKernel kernel, ILogger logger, ICoreService coreService, IProfileService profileService, IRgbService rgbService, IModuleService moduleService,
INodeService nodeService)
{
_kernel = kernel;
_logger = logger;
@@ -40,9 +41,56 @@ namespace Artemis.UI.Shared.Services
_moduleService = moduleService;
_registeredPropertyEditors = new List<PropertyInputRegistration>();
coreService.FrameRendered += CoreServiceOnFrameRendered;
TypeUtilities.NodeService = nodeService;
PixelsPerSecond = 100;
}
protected virtual void OnSelectedProfileChanged(ProfileConfigurationEventArgs e)
{
SelectedProfileChanged?.Invoke(this, e);
}
protected virtual void OnSelectedProfileUpdated(ProfileConfigurationEventArgs e)
{
SelectedProfileSaved?.Invoke(this, e);
}
protected virtual void OnSelectedProfileElementChanged(RenderProfileElementEventArgs e)
{
SelectedProfileElementChanged?.Invoke(this, e);
}
protected virtual void OnSelectedProfileElementUpdated(RenderProfileElementEventArgs e)
{
SelectedProfileElementSaved?.Invoke(this, e);
}
protected virtual void OnCurrentTimeChanged()
{
CurrentTimeChanged?.Invoke(this, EventArgs.Empty);
}
protected virtual void OnPixelsPerSecondChanged()
{
PixelsPerSecondChanged?.Invoke(this, EventArgs.Empty);
}
protected virtual void OnSuspendEditingChanged()
{
SuspendEditingChanged?.Invoke(this, EventArgs.Empty);
}
protected virtual void OnProfilePreviewUpdated()
{
ProfilePreviewUpdated?.Invoke(this, EventArgs.Empty);
}
protected virtual void OnSelectedDataBindingChanged()
{
SelectedDataBindingChanged?.Invoke(this, EventArgs.Empty);
}
private void CoreServiceOnFrameRendered(object? sender, FrameRenderedEventArgs e)
{
if (!_doTick) return;
@@ -89,7 +137,9 @@ namespace Artemis.UI.Shared.Services
return;
if (renderElement.Suspended)
{
renderElement.Disable();
}
else
{
renderElement.Enable();
@@ -104,7 +154,6 @@ namespace Artemis.UI.Shared.Services
}
public ReadOnlyCollection<PropertyInputRegistration> RegisteredPropertyEditors => _registeredPropertyEditors.AsReadOnly();
public bool Playing { get; set; }
public bool SuspendEditing
@@ -183,10 +232,10 @@ namespace Artemis.UI.Shared.Services
// No need to deactivate the profile, if needed it will be deactivated next update
if (SelectedProfileConfiguration != null)
SelectedProfileConfiguration.IsBeingEdited = false;
PreviousSelectedProfileConfiguration = SelectedProfileConfiguration;
SelectedProfileConfiguration = profileConfiguration;
// The new profile may need activation
if (SelectedProfileConfiguration != null)
{
@@ -319,10 +368,8 @@ namespace Artemis.UI.Shared.Services
if (existing != null)
{
if (existing.Plugin != plugin)
{
throw new ArtemisSharedUIException($"Cannot register property editor for type {supportedType.Name} because an editor was already " +
$"registered by {existing.Plugin}");
}
return existing;
}
@@ -367,10 +414,8 @@ namespace Artemis.UI.Shared.Services
if (snapToCurrentTime)
// Snap to the current time
{
if (Math.Abs(time.TotalMilliseconds - CurrentTime.TotalMilliseconds) < tolerance.TotalMilliseconds)
return CurrentTime;
}
if (snapTimes != null)
{
@@ -406,9 +451,13 @@ namespace Artemis.UI.Shared.Services
viewModelType = registration.ViewModelType.MakeGenericType(layerProperty.GetType().GenericTypeArguments);
}
else if (registration != null)
{
viewModelType = registration.ViewModelType;
}
else
{
return null;
}
if (viewModelType == null)
return null;
@@ -428,6 +477,16 @@ namespace Artemis.UI.Shared.Services
.ToList();
}
public event EventHandler<ProfileConfigurationEventArgs>? SelectedProfileChanged;
public event EventHandler<ProfileConfigurationEventArgs>? SelectedProfileSaved;
public event EventHandler<RenderProfileElementEventArgs>? SelectedProfileElementChanged;
public event EventHandler<RenderProfileElementEventArgs>? SelectedProfileElementSaved;
public event EventHandler? SelectedDataBindingChanged;
public event EventHandler? CurrentTimeChanged;
public event EventHandler? PixelsPerSecondChanged;
public event EventHandler? SuspendEditingChanged;
public event EventHandler? ProfilePreviewUpdated;
#region Copy/paste
public ProfileElement? DuplicateProfileElement(ProfileElement profileElement)
@@ -507,64 +566,5 @@ namespace Artemis.UI.Shared.Services
}
#endregion
#region Events
public event EventHandler<ProfileConfigurationEventArgs>? SelectedProfileChanged;
public event EventHandler<ProfileConfigurationEventArgs>? SelectedProfileSaved;
public event EventHandler<RenderProfileElementEventArgs>? SelectedProfileElementChanged;
public event EventHandler<RenderProfileElementEventArgs>? SelectedProfileElementSaved;
public event EventHandler? SelectedDataBindingChanged;
public event EventHandler? CurrentTimeChanged;
public event EventHandler? PixelsPerSecondChanged;
public event EventHandler? SuspendEditingChanged;
public event EventHandler? ProfilePreviewUpdated;
protected virtual void OnSelectedProfileChanged(ProfileConfigurationEventArgs e)
{
SelectedProfileChanged?.Invoke(this, e);
}
protected virtual void OnSelectedProfileUpdated(ProfileConfigurationEventArgs e)
{
SelectedProfileSaved?.Invoke(this, e);
}
protected virtual void OnSelectedProfileElementChanged(RenderProfileElementEventArgs e)
{
SelectedProfileElementChanged?.Invoke(this, e);
}
protected virtual void OnSelectedProfileElementUpdated(RenderProfileElementEventArgs e)
{
SelectedProfileElementSaved?.Invoke(this, e);
}
protected virtual void OnCurrentTimeChanged()
{
CurrentTimeChanged?.Invoke(this, EventArgs.Empty);
}
protected virtual void OnPixelsPerSecondChanged()
{
PixelsPerSecondChanged?.Invoke(this, EventArgs.Empty);
}
protected virtual void OnSuspendEditingChanged()
{
SuspendEditingChanged?.Invoke(this, EventArgs.Empty);
}
protected virtual void OnProfilePreviewUpdated()
{
ProfilePreviewUpdated?.Invoke(this, EventArgs.Empty);
}
protected virtual void OnSelectedDataBindingChanged()
{
SelectedDataBindingChanged?.Invoke(this, EventArgs.Empty);
}
#endregion
}
}
@@ -0,0 +1,43 @@
using System;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Media;
using Artemis.Core;
using Artemis.Core.Services;
using SkiaSharp;
using SkiaSharp.Views.WPF;
namespace Artemis.UI.Shared
{
/// <summary>
/// Provides UI-oriented utilities for types
/// </summary>
public static class TypeUtilities
{
internal static INodeService? NodeService;
/// <summary>
/// Creates a tuple containing a color and a slightly darkened color for a given type
/// </summary>
/// <param name="type">The type to create the color for</param>
public static (Color, Color) GetTypeColors(Type type)
{
if (type == typeof(object))
return (new SKColor(0xFFFFFF).ToColor(), new SKColor(0xFFFFFF).Darken(0.35f).ToColor());
TypeColorRegistration? typeColorRegistration = NodeService?.GetTypeColor(type);
if (typeColorRegistration != null)
return (typeColorRegistration.Color.ToColor(), typeColorRegistration.DarkenedColor.ToColor());
// Come up with a random color based on the type name that should be the same each time
MD5 md5Hasher = MD5.Create();
byte[] hashed = md5Hasher.ComputeHash(Encoding.UTF8.GetBytes(type.FullName!));
int hash = BitConverter.ToInt32(hashed, 0);
SKColor baseColor = SKColor.FromHsl(hash % 255, 50 + hash % 50, 50);
SKColor darkenedColor = baseColor.Darken(0.35f);
return (baseColor.ToColor(), darkenedColor.ToColor());
}
}
}