mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 11:56:30 +00:00
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:
1 parent
732ee2f429
commit
64a1010100
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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user