Profile editor - Redesigned adding/removing timeline segments

General module - Added some basic window information to the data model
Profiles - Don't render when opacity is 0
Profile editor - Render non-selected layers in their main segment
Profile editor - Condition editor fixes
This commit is contained in:
SpoinkyNL committed 2020-07-24 23:04:21 +02:00
1 parent 527fef3dc6
commit 72d606f40d
39 files changed
+831 -261

No files matched your search

@@ -159,7 +159,7 @@ namespace Artemis.Core.Models.Profile.Conditions
if (DisplayConditionPredicateEntity.LeftDataModelGuid != null)
{
var dataModel = dataModelService.GetPluginDataModelByGuid(DisplayConditionPredicateEntity.LeftDataModelGuid.Value);
if (dataModel != null)
if (dataModel != null && dataModel.ContainsPath(DisplayConditionPredicateEntity.LeftPropertyPath))
UpdateLeftSide(dataModel, DisplayConditionPredicateEntity.LeftPropertyPath);
}
@@ -175,7 +175,7 @@ namespace Artemis.Core.Models.Profile.Conditions
if (DisplayConditionPredicateEntity.RightDataModelGuid != null)
{
var dataModel = dataModelService.GetPluginDataModelByGuid(DisplayConditionPredicateEntity.RightDataModelGuid.Value);
if (dataModel != null)
if (dataModel != null && dataModel.ContainsPath(DisplayConditionPredicateEntity.RightPropertyPath))
UpdateRightSide(dataModel, DisplayConditionPredicateEntity.RightPropertyPath);
}
// Right side static
+64 -13
View File
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Artemis.Core.Models.Profile.LayerProperties;
using Artemis.Core.Plugins.LayerEffect.Abstract;
using Artemis.Storage.Entities.Profile;
using Artemis.Storage.Entities.Profile.Abstract;
@@ -69,8 +68,15 @@ namespace Artemis.Core.Models.Profile
UpdateDisplayCondition();
// Update the layer timeline, this will give us a new delta time which could be negative in case the main segment wrapped back
// to it's start
var timelineDeltaTime = UpdateTimeline(deltaTime);
foreach (var baseLayerEffect in LayerEffects.Where(e => e.Enabled))
baseLayerEffect.Update(deltaTime);
{
baseLayerEffect.BaseProperties?.Update();
baseLayerEffect.Update(timelineDeltaTime);
}
// Iterate the children in reverse because that's how they must be rendered too
for (var index = Children.Count - 1; index > -1; index--)
@@ -80,9 +86,49 @@ namespace Artemis.Core.Models.Profile
}
}
public override void OverrideProgress(TimeSpan timeOverride, bool stickToMainSegment)
{
if (!Enabled)
return;
var beginTime = TimelinePosition;
if (stickToMainSegment)
{
if (!RepeatMainSegment)
{
var position = timeOverride + StartSegmentLength;
if (position > StartSegmentLength + EndSegmentLength)
TimelinePosition = StartSegmentLength + EndSegmentLength;
}
else
{
var progress = timeOverride.TotalMilliseconds % MainSegmentLength.TotalMilliseconds;
if (progress > 0)
TimelinePosition = TimeSpan.FromMilliseconds(progress) + StartSegmentLength;
else
TimelinePosition = StartSegmentLength;
}
}
else
TimelinePosition = timeOverride;
var delta = (TimelinePosition - beginTime).TotalSeconds;
foreach (var baseLayerEffect in LayerEffects.Where(e => e.Enabled))
{
baseLayerEffect.BaseProperties?.Update();
baseLayerEffect.Update(delta);
}
}
public override void Render(double deltaTime, SKCanvas canvas, SKImageInfo canvasInfo)
{
if (!Enabled || Path == null || !Children.Any(c => c.Enabled))
if (Path == null || !Enabled || !Children.Any(c => c.Enabled))
return;
// No need to render if at the end of the timeline
if (TimelinePosition > TimelineLength)
return;
if (_folderBitmap == null)
@@ -103,6 +149,10 @@ namespace Artemis.Core.Models.Profile
foreach (var baseLayerEffect in LayerEffects.Where(e => e.Enabled))
baseLayerEffect.PreProcess(folderCanvas, _folderBitmap.Info, folderPath, folderPaint);
// No point rendering if the alpha was set to zero by one of the effects
if (folderPaint.Color.Alpha == 0)
return;
// Iterate the children in reverse because the first layer must be rendered last to end up on top
for (var index = Children.Count - 1; index > -1; index--)
{
@@ -176,6 +226,7 @@ namespace Artemis.Core.Models.Profile
OnRenderPropertiesUpdated();
}
internal override void ApplyToEntity()
{
FolderEntity.Id = EntityId;
@@ -196,6 +247,16 @@ namespace Artemis.Core.Models.Profile
DisplayConditionGroup?.ApplyToEntity();
}
internal void Deactivate()
{
_folderBitmap?.Dispose();
_folderBitmap = null;
var layerEffects = new List<BaseLayerEffect>(LayerEffects);
foreach (var baseLayerEffect in layerEffects)
DeactivateLayerEffect(baseLayerEffect);
}
#region Events
public event EventHandler RenderPropertiesUpdated;
@@ -206,15 +267,5 @@ namespace Artemis.Core.Models.Profile
}
#endregion
internal void Deactivate()
{
_folderBitmap?.Dispose();
_folderBitmap = null;
var layerEffects = new List<BaseLayerEffect>(LayerEffects);
foreach (var baseLayerEffect in layerEffects)
DeactivateLayerEffect(baseLayerEffect);
}
}
}
+55 -19
View File
@@ -117,7 +117,7 @@ namespace Artemis.Core.Models.Profile
get => _layerBrush;
internal set => SetAndNotify(ref _layerBrush, value);
}
public override string ToString()
{
return $"[Layer] {nameof(Name)}: {Name}, {nameof(Order)}: {Order}";
@@ -134,7 +134,7 @@ namespace Artemis.Core.Models.Profile
keyframes.AddRange(baseLayerProperty.BaseKeyframes);
foreach (var baseLayerProperty in LayerBrush.BaseProperties.GetAllLayerProperties())
keyframes.AddRange(baseLayerProperty.BaseKeyframes);
return keyframes;
}
@@ -214,34 +214,66 @@ namespace Artemis.Core.Models.Profile
/// <inheritdoc />
public override void Update(double deltaTime)
{
if (!Enabled)
return;
if (LayerBrush?.BaseProperties == null || !LayerBrush.BaseProperties.PropertiesInitialized)
if (!Enabled || LayerBrush?.BaseProperties == null || !LayerBrush.BaseProperties.PropertiesInitialized)
return;
// Ensure the layer must still be displayed
UpdateDisplayCondition();
deltaTime = UpdateTimeline(deltaTime);
General.Update(deltaTime);
Transform.Update(deltaTime);
LayerBrush.BaseProperties?.Update(deltaTime);
LayerBrush.Update(deltaTime);
// TODO: No point updating further than this if the layer is not going to be rendered
// Update the layer timeline, this will give us a new delta time which could be negative in case the main segment wrapped back
// to it's start
var timelineDeltaTime = UpdateTimeline(deltaTime);
General.Update();
Transform.Update();
LayerBrush.BaseProperties?.Update();
LayerBrush.Update(timelineDeltaTime);
foreach (var baseLayerEffect in LayerEffects.Where(e => e.Enabled))
{
baseLayerEffect.BaseProperties?.Update(deltaTime);
baseLayerEffect.Update(deltaTime);
baseLayerEffect.BaseProperties?.Update();
baseLayerEffect.Update(timelineDeltaTime);
}
}
public void OverrideProgress(TimeSpan timeOverride)
public override void OverrideProgress(TimeSpan timeOverride, bool stickToMainSegment)
{
General.Override(timeOverride);
Transform.Override(timeOverride);
LayerBrush?.BaseProperties?.Override(timeOverride);
foreach (var baseLayerEffect in LayerEffects)
baseLayerEffect.BaseProperties?.Override(timeOverride);
if (!Enabled || LayerBrush?.BaseProperties == null || !LayerBrush.BaseProperties.PropertiesInitialized)
return;
var beginTime = TimelinePosition;
if (stickToMainSegment)
{
if (!RepeatMainSegment)
{
var position = timeOverride + StartSegmentLength;
if (position > StartSegmentLength + EndSegmentLength)
TimelinePosition = StartSegmentLength + EndSegmentLength;
}
else
{
var progress = timeOverride.TotalMilliseconds % MainSegmentLength.TotalMilliseconds;
TimelinePosition = TimeSpan.FromMilliseconds(progress) + StartSegmentLength;
}
}
else
TimelinePosition = timeOverride;
var delta = (TimelinePosition - beginTime).TotalSeconds;
General.Update();
Transform.Update();
LayerBrush.BaseProperties?.Update();
LayerBrush.Update(delta);
foreach (var baseLayerEffect in LayerEffects.Where(e => e.Enabled))
{
baseLayerEffect.BaseProperties?.Update();
baseLayerEffect.Update(delta);
}
}
/// <inheritdoc />
@@ -280,6 +312,10 @@ namespace Artemis.Core.Models.Profile
foreach (var baseLayerEffect in LayerEffects.Where(e => e.Enabled))
baseLayerEffect.PreProcess(layerCanvas, _layerBitmap.Info, layerPath, layerPaint);
// No point rendering if the alpha was set to zero by one of the effects
if (layerPaint.Color.Alpha == 0)
return;
layerCanvas.ClipPath(layerPath);
if (!LayerBrush.SupportsTransformation)
@@ -65,11 +65,6 @@ namespace Artemis.Core.Models.Profile.LayerProperties
/// </summary>
public bool IsLoadedFromStorage { get; internal set; }
/// <summary>
/// Gets the total progress on the timeline
/// </summary>
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>
@@ -101,7 +101,7 @@ namespace Artemis.Core.Models.Profile.LayerProperties
currentKeyframe.Value = value;
// Update the property so that the new keyframe is reflected on the current value
Update(0);
Update();
}
}
@@ -184,17 +184,15 @@ namespace Artemis.Core.Models.Profile.LayerProperties
}
/// <summary>
/// Updates the property, moving the timeline forwards by the provided <paramref name="deltaTime" />
/// Updates the property, applying keyframes to the current value
/// </summary>
/// <param name="deltaTime">The amount of time to move the timeline forwards</param>
internal void Update(double deltaTime)
internal void Update()
{
TimelineProgress = TimelineProgress.Add(TimeSpan.FromSeconds(deltaTime));
if (!KeyframesSupported || !KeyframesEnabled)
return;
// The current keyframe is the last keyframe before the current time
CurrentKeyframe = _keyframes.LastOrDefault(k => k.Position <= TimelineProgress);
CurrentKeyframe = _keyframes.LastOrDefault(k => k.Position <= ProfileElement.TimelinePosition);
// Keyframes are sorted by position so we can safely assume the next keyframe's position is after the current
var nextIndex = _keyframes.IndexOf(CurrentKeyframe) + 1;
NextKeyframe = _keyframes.Count > nextIndex ? _keyframes[nextIndex] : null;
@@ -208,7 +206,7 @@ namespace Artemis.Core.Models.Profile.LayerProperties
else
{
var timeDiff = NextKeyframe.Position - CurrentKeyframe.Position;
var keyframeProgress = (float)((TimelineProgress - CurrentKeyframe.Position).TotalMilliseconds / timeDiff.TotalMilliseconds);
var keyframeProgress = (float)((ProfileElement.TimelinePosition - CurrentKeyframe.Position).TotalMilliseconds / timeDiff.TotalMilliseconds);
var keyframeProgressEased = (float)Easings.Interpolate(keyframeProgress, CurrentKeyframe.EasingFunction);
UpdateCurrentValue(keyframeProgress, keyframeProgressEased);
}
@@ -216,16 +214,6 @@ namespace Artemis.Core.Models.Profile.LayerProperties
OnUpdated();
}
/// <summary>
/// Overrides the timeline progress to match the provided <paramref name="overrideTime" />
/// </summary>
/// <param name="overrideTime">The new progress to set the layer property timeline to.</param>
internal void OverrideProgress(TimeSpan overrideTime)
{
TimelineProgress = TimeSpan.Zero;
Update(overrideTime.TotalSeconds);
}
/// <summary>
/// Sorts the keyframes in ascending order by position
/// </summary>
@@ -242,8 +230,7 @@ namespace Artemis.Core.Models.Profile.LayerProperties
PropertyEntity = entity;
LayerPropertyGroup = layerPropertyGroup;
LayerPropertyGroup.PropertyGroupUpdating += (sender, args) => Update(args.DeltaTime);
LayerPropertyGroup.PropertyGroupOverriding += (sender, args) => OverrideProgress(args.OverrideTime);
LayerPropertyGroup.PropertyGroupUpdating += (sender, args) => Update();
try
{
@@ -223,19 +223,13 @@ namespace Artemis.Core.Models.Profile
}
}
internal void Update(double deltaTime)
internal void Update()
{
// Since at this point we don't know what properties the group has without using reflection,
// let properties subscribe to the update event and update themselves
OnPropertyGroupUpdating(new PropertyGroupUpdatingEventArgs(deltaTime));
OnPropertyGroupUpdating();
}
internal void Override(TimeSpan overrideTime)
{
// Same as above, but now the progress is overridden
OnPropertyGroupOverriding(new PropertyGroupUpdatingEventArgs(overrideTime));
}
private void InitializeProperty(RenderProfileElement profileElement, string path, BaseLayerProperty instance)
{
Guid pluginGuid;
@@ -260,8 +254,7 @@ namespace Artemis.Core.Models.Profile
#region Events
internal event EventHandler<PropertyGroupUpdatingEventArgs> PropertyGroupUpdating;
internal event EventHandler<PropertyGroupUpdatingEventArgs> PropertyGroupOverriding;
internal event EventHandler PropertyGroupUpdating;
public event EventHandler PropertyGroupInitialized;
/// <summary>
@@ -269,14 +262,9 @@ namespace Artemis.Core.Models.Profile
/// </summary>
public event EventHandler VisibilityChanged;
internal virtual void OnPropertyGroupUpdating(PropertyGroupUpdatingEventArgs e)
protected virtual void OnPropertyGroupUpdating()
{
PropertyGroupUpdating?.Invoke(this, e);
}
protected virtual void OnPropertyGroupOverriding(PropertyGroupUpdatingEventArgs e)
{
PropertyGroupOverriding?.Invoke(this, e);
PropertyGroupUpdating?.Invoke(this, EventArgs.Empty);
}
protected virtual void OnVisibilityChanged()
@@ -164,7 +164,7 @@ namespace Artemis.Core.Models.Profile
public TimeSpan TimelinePosition
{
get => _timelinePosition;
private set => SetAndNotify(ref _timelinePosition, value);
protected set => SetAndNotify(ref _timelinePosition, value);
}
/// <summary>
@@ -212,13 +212,19 @@ namespace Artemis.Core.Models.Profile
// Skip to the last segment if conditions are no longer met
if (!AlwaysFinishTimeline && TimelinePosition < mainSegmentEnd)
TimelinePosition = mainSegmentEnd;
else if (TimelinePosition >= TimelineLength)
TimelinePosition = TimelineLength;
}
return (TimelinePosition - oldPosition).TotalSeconds;
}
/// <summary>
/// Overrides the progress of the element
/// </summary>
/// <param name="timeOverride"></param>
/// <param name="stickToMainSegment"></param>
public abstract void OverrideProgress(TimeSpan timeOverride, bool stickToMainSegment);
#endregion
#region Effects