1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

UI - My poor UI :< I regret starting this refactor

This commit is contained in:
SpoinkyNL 2020-04-30 00:12:24 +02:00
parent e97fc046f5
commit 41b3c77210
13 changed files with 130 additions and 59 deletions

View File

@ -122,6 +122,7 @@ namespace Artemis.Core.Models.Profile
LayerEntity.Order = Order; LayerEntity.Order = Order;
LayerEntity.Name = Name; LayerEntity.Name = Name;
LayerEntity.ProfileId = Profile.EntityId; LayerEntity.ProfileId = Profile.EntityId;
General.ApplyToEntity(); General.ApplyToEntity();
Transform.ApplyToEntity(); Transform.ApplyToEntity();
LayerBrush.ApplyToEntity(); LayerBrush.ApplyToEntity();
@ -184,27 +185,36 @@ namespace Artemis.Core.Models.Profile
if (LayerBrush == null) if (LayerBrush == null)
return; return;
General.Update(deltaTime);
Transform.Update(deltaTime);
LayerBrush.UpdateProperties(deltaTime);
var properties = new List<BaseLayerProperty>(General.GetAllLayerProperties()); var properties = new List<BaseLayerProperty>(General.GetAllLayerProperties());
properties.AddRange(Transform.GetAllLayerProperties()); properties.AddRange(Transform.GetAllLayerProperties());
properties.AddRange(LayerBrush.GetAllLayerProperties()); properties.AddRange(LayerBrush.GetAllLayerProperties());
// For now, reset all keyframe engines after the last keyframe was hit // For now, reset all keyframe engines after the last keyframe was hit
// This is a placeholder method of repeating the animation until repeat modes are implemented // This is a placeholder method of repeating the animation until repeat modes are implemented
var timeLineEnd = properties.Max(p => p.GetLastKeyframePosition()); var timeLineEnd = properties.Max(p => p.BaseKeyframes.Max(k => k.Position));
if (properties.Any(p => p.TimelineProgress >= timeLineEnd)) if (properties.Any(p => p.TimelineProgress >= timeLineEnd))
{ {
General.Override(TimeSpan.Zero); General.Override(TimeSpan.Zero);
Transform.Override(TimeSpan.Zero); Transform.Override(TimeSpan.Zero);
LayerBrush.OverrideProperties(TimeSpan.Zero); LayerBrush.OverrideProperties(TimeSpan.Zero);
} }
else
{
General.Update(deltaTime);
Transform.Update(deltaTime);
LayerBrush.UpdateProperties(deltaTime);
}
LayerBrush.Update(deltaTime); LayerBrush.Update(deltaTime);
} }
public void OverrideProgress(TimeSpan timeOverride)
{
General.Override(timeOverride);
Transform.Override(timeOverride);
LayerBrush.OverrideProperties(timeOverride);
}
/// <inheritdoc /> /// <inheritdoc />
public override void Render(double deltaTime, SKCanvas canvas, SKImageInfo canvasInfo) public override void Render(double deltaTime, SKCanvas canvas, SKImageInfo canvasInfo)
{ {

View File

@ -9,12 +9,9 @@ namespace Artemis.Core.Models.Profile.LayerProperties
/// </summary> /// </summary>
public abstract class BaseLayerProperty public abstract class BaseLayerProperty
{ {
/// <summary> internal BaseLayerProperty()
/// Used to declare that this property doesn't belong to a plugin and should use the core plugin GUID {
/// </summary> }
internal bool IsCoreProperty { get; set; }
internal PropertyEntity PropertyEntity { get; set; }
internal LayerPropertyGroup LayerPropertyGroup { get; set; }
/// <summary> /// <summary>
/// Gets whether keyframes are supported on this property /// Gets whether keyframes are supported on this property
@ -42,6 +39,15 @@ namespace Artemis.Core.Models.Profile.LayerProperties
/// </summary> /// </summary>
public TimeSpan TimelineProgress { get; internal set; } public TimeSpan TimelineProgress { get; internal set; }
/// <summary>
/// Used to declare that this property doesn't belong to a plugin and should use the core plugin GUID
/// </summary>
internal bool IsCoreProperty { get; set; }
internal PropertyEntity PropertyEntity { get; set; }
internal LayerPropertyGroup LayerPropertyGroup { get; set; }
internal abstract IReadOnlyList<BaseLayerPropertyKeyframe> BaseKeyframes { get; }
/// <summary> /// <summary>
/// Applies the provided property entity to the layer property by deserializing the JSON base value and keyframe values /// Applies the provided property entity to the layer property by deserializing the JSON base value and keyframe values
/// </summary> /// </summary>
@ -54,8 +60,5 @@ namespace Artemis.Core.Models.Profile.LayerProperties
/// <see cref="ApplyToLayerProperty" /> /// <see cref="ApplyToLayerProperty" />
/// </summary> /// </summary>
internal abstract void ApplyToEntity(); internal abstract void ApplyToEntity();
internal abstract List<TimeSpan> GetKeyframePositions();
internal abstract TimeSpan GetLastKeyframePosition();
} }
} }

View File

@ -0,0 +1,27 @@
using System;
using Artemis.Core.Utilities;
namespace Artemis.Core.Models.Profile.LayerProperties
{
/// <summary>
/// For internal use only, use <see cref="LayerPropertyKeyframe{T}" /> instead.
/// </summary>
public abstract class BaseLayerPropertyKeyframe
{
internal BaseLayerPropertyKeyframe()
{
}
/// <summary>
/// The position of this keyframe in the timeline
/// </summary>
public abstract TimeSpan Position { get; set; }
/// <summary>
/// The easing function applied on the value of the keyframe
/// </summary>
public abstract Easings.Functions EasingFunction { get; set; }
internal abstract BaseLayerProperty BaseLayerProperty { get; }
}
}

View File

@ -12,7 +12,8 @@ namespace Artemis.Core.Models.Profile.LayerProperties
/// <summary> /// <summary>
/// Represents a property on a layer. Properties are saved in storage and can optionally be modified from the UI. /// Represents a property on a layer. Properties are saved in storage and can optionally be modified from the UI.
/// <para> /// <para>
/// Note: You cannot initialize layer properties yourself. If properly placed and annotated, the Artemis core will initialize /// Note: You cannot initialize layer properties yourself. If properly placed and annotated, the Artemis core will
/// initialize
/// these for you. /// these for you.
/// </para> /// </para>
/// </summary> /// </summary>
@ -53,12 +54,12 @@ namespace Artemis.Core.Models.Profile.LayerProperties
get => !KeyframesEnabled || !KeyframesSupported ? BaseValue : _currentValue; get => !KeyframesEnabled || !KeyframesSupported ? BaseValue : _currentValue;
internal set => _currentValue = value; internal set => _currentValue = value;
} }
/// <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 IReadOnlyList<LayerPropertyKeyframe<T>> Keyframes => _keyframes.AsReadOnly(); public IReadOnlyList<LayerPropertyKeyframe<T>> Keyframes => _keyframes.AsReadOnly();
/// <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
/// </summary> /// </summary>
@ -68,7 +69,9 @@ namespace Artemis.Core.Models.Profile.LayerProperties
/// Gets the next keyframe in the timeline according to the current progress /// Gets the next keyframe in the timeline according to the current progress
/// </summary> /// </summary>
public LayerPropertyKeyframe<T> NextKeyframe { get; protected set; } public LayerPropertyKeyframe<T> NextKeyframe { get; protected set; }
internal override IReadOnlyList<BaseLayerPropertyKeyframe> BaseKeyframes => _keyframes.Cast<BaseLayerPropertyKeyframe>().ToList().AsReadOnly();
/// <summary> /// <summary>
/// Adds a keyframe to the layer property /// Adds a keyframe to the layer property
/// </summary> /// </summary>
@ -93,6 +96,16 @@ namespace Artemis.Core.Models.Profile.LayerProperties
OnKeyframeRemoved(); OnKeyframeRemoved();
} }
/// <summary>
/// Removes all keyframes from the layer property
/// </summary>
public void ClearKeyframes()
{
var keyframes = new List<LayerPropertyKeyframe<T>>(_keyframes);
foreach (var layerPropertyKeyframe in keyframes)
RemoveKeyframe(layerPropertyKeyframe);
}
/// <summary> /// <summary>
/// Called every update (if keyframes are both supported and enabled) to determine the new <see cref="CurrentValue" /> /// Called every update (if keyframes are both supported and enabled) to determine the new <see cref="CurrentValue" />
/// based on the provided progress /// based on the provided progress
@ -167,6 +180,7 @@ namespace Artemis.Core.Models.Profile.LayerProperties
IsLoadedFromStorage = true; IsLoadedFromStorage = true;
BaseValue = JsonConvert.DeserializeObject<T>(entity.Value); BaseValue = JsonConvert.DeserializeObject<T>(entity.Value);
CurrentValue = BaseValue; CurrentValue = BaseValue;
KeyframesEnabled = entity.KeyframesEnabled;
_keyframes.Clear(); _keyframes.Clear();
_keyframes.AddRange(entity.KeyframeEntities.Select(k => new LayerPropertyKeyframe<T>( _keyframes.AddRange(entity.KeyframeEntities.Select(k => new LayerPropertyKeyframe<T>(
@ -194,6 +208,7 @@ namespace Artemis.Core.Models.Profile.LayerProperties
throw new ArtemisCoreException("Layer property is not yet initialized"); throw new ArtemisCoreException("Layer property is not yet initialized");
PropertyEntity.Value = JsonConvert.SerializeObject(BaseValue); PropertyEntity.Value = JsonConvert.SerializeObject(BaseValue);
PropertyEntity.KeyframesEnabled = KeyframesEnabled;
PropertyEntity.KeyframeEntities.Clear(); PropertyEntity.KeyframeEntities.Clear();
PropertyEntity.KeyframeEntities.AddRange(Keyframes.Select(k => new KeyframeEntity PropertyEntity.KeyframeEntities.AddRange(Keyframes.Select(k => new KeyframeEntity
{ {
@ -203,16 +218,6 @@ namespace Artemis.Core.Models.Profile.LayerProperties
})); }));
} }
internal override List<TimeSpan> GetKeyframePositions()
{
return Keyframes.Select(k => k.Position).ToList();
}
internal override TimeSpan GetLastKeyframePosition()
{
return Keyframes.LastOrDefault()?.Position ?? TimeSpan.Zero;
}
#region Events #region Events
public event EventHandler Updated; public event EventHandler Updated;

View File

@ -3,7 +3,7 @@ using Artemis.Core.Utilities;
namespace Artemis.Core.Models.Profile.LayerProperties namespace Artemis.Core.Models.Profile.LayerProperties
{ {
public class LayerPropertyKeyframe<T> public class LayerPropertyKeyframe<T> : BaseLayerPropertyKeyframe
{ {
private TimeSpan _position; private TimeSpan _position;
@ -14,10 +14,18 @@ namespace Artemis.Core.Models.Profile.LayerProperties
EasingFunction = easingFunction; EasingFunction = easingFunction;
} }
/// <summary>
/// The layer property this keyframe is applied to
/// </summary>
public LayerProperty<T> LayerProperty { get; internal set; } public LayerProperty<T> LayerProperty { get; internal set; }
/// <summary>
/// The value of this keyframe
/// </summary>
public T Value { get; set; } public T Value { get; set; }
public TimeSpan Position /// <inheritdoc />
public override TimeSpan Position
{ {
get => _position; get => _position;
set set
@ -27,6 +35,9 @@ namespace Artemis.Core.Models.Profile.LayerProperties
} }
} }
public Easings.Functions EasingFunction { get; set; } /// <inheritdoc />
public sealed override Easings.Functions EasingFunction { get; set; }
internal override BaseLayerProperty BaseLayerProperty => LayerProperty;
} }
} }

View File

@ -29,6 +29,8 @@ namespace Artemis.Core.Plugins.LayerBrush
/// </summary> /// </summary>
public PluginInfo PluginInfo => Descriptor.LayerBrushProvider.PluginInfo; public PluginInfo PluginInfo => Descriptor.LayerBrushProvider.PluginInfo;
internal virtual LayerPropertyGroup BaseProperties => null;
/// <summary> /// <summary>
/// Called when the brush is being removed from the layer /// Called when the brush is being removed from the layer
/// </summary> /// </summary>

View File

@ -46,6 +46,9 @@ namespace Artemis.Core.Plugins.LayerBrush
{ {
} }
/// <inheritdoc/>
internal override LayerPropertyGroup BaseProperties => Properties;
internal override void InitializeProperties(ILayerService layerService, string path) internal override void InitializeProperties(ILayerService layerService, string path)
{ {
Properties.InitializeProperties(layerService, Layer, path); Properties.InitializeProperties(layerService, Layer, path);

View File

@ -1,4 +1,5 @@
using System.Linq; using System.Collections.Generic;
using System.Linq;
using Artemis.Core.Models.Profile; using Artemis.Core.Models.Profile;
using Artemis.Core.Plugins.LayerBrush; using Artemis.Core.Plugins.LayerBrush;
using Artemis.Core.Services.Interfaces; using Artemis.Core.Services.Interfaces;
@ -75,5 +76,10 @@ namespace Artemis.Core.Services
layer.LayerEntity.PropertyEntities.RemoveAll(p => p.PluginGuid == brush.PluginInfo.Guid); layer.LayerEntity.PropertyEntities.RemoveAll(p => p.PluginGuid == brush.PluginInfo.Guid);
} }
public void GetLayerPropertyGroups(Layer layer)
{
var groups = new List<LayerPropertyGroup> {layer.General, layer.Transform, layer.LayerBrush.BrushProperties};
}
} }
} }

View File

@ -14,7 +14,7 @@ namespace Artemis.Storage.Entities.Profile
public string Path { get; set; } public string Path { get; set; }
public string Value { get; set; } public string Value { get; set; }
public bool IsUsingKeyframes { get; set; } public bool KeyframesEnabled { get; set; }
public List<KeyframeEntity> KeyframeEntities { get; set; } public List<KeyframeEntity> KeyframeEntities { get; set; }
} }

View File

@ -70,6 +70,6 @@ namespace Artemis.UI.Ninject.Factories
public interface IPropertyTrackKeyframeVmFactory : IVmFactory public interface IPropertyTrackKeyframeVmFactory : IVmFactory
{ {
PropertyTrackKeyframeViewModel Create(PropertyTrackViewModel propertyTrackViewModel, BaseKeyframe keyframe); PropertyTrackKeyframeViewModel<T> Create<T>(PropertyTrackViewModel propertyTrackViewModel, LayerPropertyKeyframe<T> keyframe);
} }
} }

View File

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Artemis.Core.Models.Profile.LayerProperties; using Artemis.Core.Models.Profile.LayerProperties;
using Artemis.Core.Utilities;
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput; using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput;
using Artemis.UI.Services.Interfaces; using Artemis.UI.Services.Interfaces;
using Ninject; using Ninject;
@ -9,31 +10,30 @@ using Stylet;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
{ {
public class LayerPropertyViewModel : PropertyChangedBase public class LayerPropertyViewModel<T> : LayerPropertyViewModel
{ {
private readonly IKernel _kernel; private readonly IKernel _kernel;
private readonly IProfileEditorService _profileEditorService; private readonly IProfileEditorService _profileEditorService;
private bool _keyframesEnabled; private bool _keyframesEnabled;
private bool _isExpanded; private bool _isExpanded;
public LayerPropertyViewModel(BaseLayerProperty layerProperty, LayerPropertyViewModel parent, IKernel kernel, IProfileEditorService profileEditorService) public LayerPropertyViewModel(LayerProperty<T> layerProperty, LayerPropertyViewModel parent, IKernel kernel, IProfileEditorService profileEditorService)
{ {
_kernel = kernel; _kernel = kernel;
_profileEditorService = profileEditorService; _profileEditorService = profileEditorService;
_keyframesEnabled = layerProperty.IsUsingKeyframes; _keyframesEnabled = layerProperty.KeyframesEnabled;
LayerProperty = layerProperty; LayerProperty = layerProperty;
Parent = parent; Parent = parent;
Children = new List<LayerPropertyViewModel>(); Children = new List<LayerPropertyViewModel>();
IsExpanded = layerProperty.ExpandByDefault;
// TODO: Get from attribute
IsExpanded = false;
Parent?.Children.Add(this); Parent?.Children.Add(this);
} }
public BaseLayerProperty LayerProperty { get; } public LayerProperty<T> LayerProperty { get; }
public LayerPropertyViewModel Parent { get; }
public List<LayerPropertyViewModel> Children { get; }
public bool IsExpanded public bool IsExpanded
{ {
@ -58,7 +58,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
public PropertyInputViewModel GetPropertyInputViewModel() public PropertyInputViewModel GetPropertyInputViewModel()
{ {
// If the type is an enum type, search for Enum instead. // If the type is an enum type, search for Enum instead.
var type = LayerProperty.Type; var type = typeof(T);
if (type.IsEnum) if (type.IsEnum)
type = typeof(Enum); type = typeof(Enum);
@ -72,15 +72,16 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
private void UpdateKeyframes() private void UpdateKeyframes()
{ {
// Either create a new first keyframe or clear all the keyframes // Either create a new first keyframe or clear all the keyframes
if (_keyframesEnabled) if (_keyframesEnabled)
LayerProperty.CreateNewKeyframe(_profileEditorService.CurrentTime, LayerProperty.GetCurrentValue()); LayerProperty.AddKeyframe(new LayerPropertyKeyframe<T>(LayerProperty.CurrentValue, _profileEditorService.CurrentTime, Easings.Functions.Linear));
else else
LayerProperty.ClearKeyframes(); LayerProperty.ClearKeyframes();
// Force the keyframe engine to update, the new keyframe is the current keyframe // Force the keyframe engine to update, the new keyframe is the current keyframe
LayerProperty.IsUsingKeyframes = _keyframesEnabled; LayerProperty.KeyframesEnabled = _keyframesEnabled;
LayerProperty.KeyframeEngine?.Update(0); LayerProperty.Update(0);
_profileEditorService.UpdateSelectedProfileElement(); _profileEditorService.UpdateSelectedProfileElement();
} }
@ -88,6 +89,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
#region Events #region Events
public event EventHandler<EventArgs> ExpandedStateChanged; public event EventHandler<EventArgs> ExpandedStateChanged;
protected virtual void OnExpandedStateChanged() protected virtual void OnExpandedStateChanged()
{ {
ExpandedStateChanged?.Invoke(this, EventArgs.Empty); ExpandedStateChanged?.Invoke(this, EventArgs.Empty);
@ -97,4 +99,10 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
#endregion #endregion
} }
public class LayerPropertyViewModel : PropertyChangedBase
{
public LayerPropertyViewModel Parent { get; protected set; }
public List<LayerPropertyViewModel> Children { get; protected set; }
}
} }

View File

@ -1,5 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
@ -10,12 +9,12 @@ using Stylet;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
{ {
public class PropertyTrackKeyframeViewModel : PropertyChangedBase public class PropertyTrackKeyframeViewModel<T> : PropertyTrackKeyframeViewModel
{ {
private readonly IProfileEditorService _profileEditorService; private readonly IProfileEditorService _profileEditorService;
private int _pixelsPerSecond; private int _pixelsPerSecond;
public PropertyTrackKeyframeViewModel(PropertyTrackViewModel propertyTrackViewModel, BaseKeyframe keyframe, IProfileEditorService profileEditorService) public PropertyTrackKeyframeViewModel(PropertyTrackViewModel propertyTrackViewModel, LayerPropertyKeyframe<T> keyframe, IProfileEditorService profileEditorService)
{ {
_profileEditorService = profileEditorService; _profileEditorService = profileEditorService;
@ -27,7 +26,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
public bool IsSelected { get; set; } public bool IsSelected { get; set; }
public PropertyTrackViewModel PropertyTrackViewModel { get; } public PropertyTrackViewModel PropertyTrackViewModel { get; }
public BaseKeyframe Keyframe { get; } public LayerPropertyKeyframe<T> Keyframe { get; }
public BindableCollection<PropertyTrackEasingViewModel> EasingViewModels { get; set; } public BindableCollection<PropertyTrackEasingViewModel> EasingViewModels { get; set; }
public double X { get; set; } public double X { get; set; }
public string Timestamp { get; set; } public string Timestamp { get; set; }
@ -170,4 +169,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
#endregion #endregion
} }
public abstract class PropertyTrackKeyframeViewModel : PropertyChangedBase
{
}
} }

View File

@ -74,18 +74,11 @@ namespace Artemis.UI.Services
{ {
if (SelectedProfile == null) if (SelectedProfile == null)
return; return;
var delta = CurrentTime - _lastUpdateTime; var delta = CurrentTime - _lastUpdateTime;
foreach (var layer in SelectedProfile.GetAllLayers()) foreach (var layer in SelectedProfile.GetAllLayers())
{ {
// Override keyframe progress layer.OverrideProgress(CurrentTime);
foreach (var baseLayerProperty in layer.Properties)
baseLayerProperty.KeyframeEngine?.OverrideProgress(CurrentTime);
// Force layer shape to redraw
layer.LayerShape?.CalculateRenderProperties();
// Manually update the layer's engine and brush
foreach (var property in layer.Properties)
property.KeyframeEngine?.Update(delta.TotalSeconds);
layer.LayerBrush?.Update(delta.TotalSeconds); layer.LayerBrush?.Update(delta.TotalSeconds);
} }