diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/BaseLayerPropertyKeyframe.cs b/src/Artemis.Core/Models/Profile/LayerProperties/BaseLayerPropertyKeyframe.cs
index d54a254a4..d0537d8b1 100644
--- a/src/Artemis.Core/Models/Profile/LayerProperties/BaseLayerPropertyKeyframe.cs
+++ b/src/Artemis.Core/Models/Profile/LayerProperties/BaseLayerPropertyKeyframe.cs
@@ -18,11 +18,6 @@ namespace Artemis.Core.Models.Profile.LayerProperties
///
public BaseLayerProperty BaseLayerProperty { get; internal set; }
- ///
- /// The timeline this keyframe is contained in
- ///
- public abstract Timeline Timeline { get; set; }
-
///
/// The position of this keyframe in the timeline
///
@@ -33,11 +28,4 @@ namespace Artemis.Core.Models.Profile.LayerProperties
///
public Easings.Functions EasingFunction { get; set; }
}
-
- public enum Timeline
- {
- Start,
- Main,
- End
- }
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs
index e3f255975..8595a084a 100644
--- a/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs
+++ b/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs
@@ -23,16 +23,10 @@ namespace Artemis.Core.Models.Profile.LayerProperties
private T _currentValue;
private bool _isInitialized;
private List> _keyframes;
- private List> _startKeyframes;
- private List> _mainKeyframes;
- private List> _endKeyframes;
protected LayerProperty()
{
_keyframes = new List>();
- _startKeyframes = new List>();
- _mainKeyframes = new List>();
- _endKeyframes = new List>();
}
///
@@ -90,7 +84,7 @@ namespace Artemis.Core.Models.Profile.LayerProperties
/// The value to set.
///
/// An optional time to set the value add, if provided and property is using keyframes the value will be set to an new
- /// or existing keyframe in the currently active timeline.
+ /// or existing keyframe.
///
public void SetCurrentValue(T value, TimeSpan? time)
{
@@ -99,10 +93,10 @@ namespace Artemis.Core.Models.Profile.LayerProperties
else
{
// If on a keyframe, update the keyframe
- var currentKeyframe = Keyframes.FirstOrDefault(k => k.Position == time.Value && k.Timeline == ProfileElement.CurrentTimeline);
+ var currentKeyframe = Keyframes.FirstOrDefault(k => k.Position == time.Value);
// Create a new keyframe if none found
if (currentKeyframe == null)
- AddKeyframe(new LayerPropertyKeyframe(value, time.Value, ProfileElement.CurrentTimeline, Easings.Functions.Linear, this));
+ AddKeyframe(new LayerPropertyKeyframe(value, time.Value, Easings.Functions.Linear, this));
else
currentKeyframe.Value = value;
@@ -138,7 +132,6 @@ namespace Artemis.Core.Models.Profile.LayerProperties
var newKeyframe = new LayerPropertyKeyframe(
keyframe.Value,
keyframe.Position,
- keyframe.Timeline,
keyframe.EasingFunction,
keyframe.LayerProperty
);
@@ -200,43 +193,23 @@ namespace Artemis.Core.Models.Profile.LayerProperties
if (!KeyframesSupported || !KeyframesEnabled)
return;
- var keyframeSet = _keyframes;
- if (ProfileElement.CurrentTimeline == Timeline.Start)
- keyframeSet = _startKeyframes;
- else if (ProfileElement.CurrentTimeline == Timeline.Main)
- keyframeSet = _mainKeyframes;
- else if (ProfileElement.CurrentTimeline == Timeline.End)
- keyframeSet = _endKeyframes;
-
// The current keyframe is the last keyframe before the current time
- CurrentKeyframe = keyframeSet.LastOrDefault(k => k.Position <= TimelineProgress);
-
- // If the current keyframe is null, try to find it in previous timelines
- if (CurrentKeyframe == null && ProfileElement.CurrentTimeline == Timeline.Main)
- CurrentKeyframe = _startKeyframes.LastOrDefault();
- else if (CurrentKeyframe == null && ProfileElement.CurrentTimeline == Timeline.End)
- CurrentKeyframe = _mainKeyframes.LastOrDefault() ?? _startKeyframes.LastOrDefault();
-
+ CurrentKeyframe = _keyframes.LastOrDefault(k => k.Position <= TimelineProgress);
// Keyframes are sorted by position so we can safely assume the next keyframe's position is after the current
- var nextIndex = keyframeSet.IndexOf(CurrentKeyframe) + 1;
- NextKeyframe = keyframeSet.Count > nextIndex ? keyframeSet[nextIndex] : null;
+ var nextIndex = _keyframes.IndexOf(CurrentKeyframe) + 1;
+ NextKeyframe = _keyframes.Count > nextIndex ? _keyframes[nextIndex] : null;
// No need to update the current value if either of the keyframes are null
if (CurrentKeyframe == null)
- CurrentValue = keyframeSet.Any() ? keyframeSet[0].Value : BaseValue;
+ CurrentValue = _keyframes.Any() ? _keyframes[0].Value : BaseValue;
else if (NextKeyframe == null)
CurrentValue = CurrentKeyframe.Value;
// Only determine progress and current value if both keyframes are present
else
{
- // If the current keyframe belongs to a previous timeline, consider it starting at 0
- var currentKeyframePosition = CurrentKeyframe.Position;
- if (CurrentKeyframe.Timeline != ProfileElement.CurrentTimeline)
- currentKeyframePosition = TimeSpan.Zero;
-
- var timeDiff = NextKeyframe.Position - currentKeyframePosition;
- var keyframeProgress = (float) ((TimelineProgress - currentKeyframePosition).TotalMilliseconds / timeDiff.TotalMilliseconds);
- var keyframeProgressEased = (float) Easings.Interpolate(keyframeProgress, CurrentKeyframe.EasingFunction);
+ var timeDiff = NextKeyframe.Position - CurrentKeyframe.Position;
+ var keyframeProgress = (float)((TimelineProgress - CurrentKeyframe.Position).TotalMilliseconds / timeDiff.TotalMilliseconds);
+ var keyframeProgressEased = (float)Easings.Interpolate(keyframeProgress, CurrentKeyframe.EasingFunction);
UpdateCurrentValue(keyframeProgress, keyframeProgressEased);
}
@@ -254,15 +227,11 @@ namespace Artemis.Core.Models.Profile.LayerProperties
}
///
- /// Sorts the keyframes in ascending order by position and divides the keyframes into different timelines
+ /// Sorts the keyframes in ascending order by position
///
internal void SortKeyframes()
{
_keyframes = _keyframes.OrderBy(k => k.Position).ToList();
-
- _startKeyframes = _keyframes.Where(k => k.Timeline == Timeline.Start).ToList();
- _mainKeyframes = _keyframes.Where(k => k.Timeline == Timeline.Main).ToList();
- _endKeyframes = _keyframes.Where(k => k.Timeline == Timeline.End).ToList();
}
internal override void ApplyToLayerProperty(PropertyEntity entity, LayerPropertyGroup layerPropertyGroup, bool fromStorage)
@@ -289,8 +258,7 @@ namespace Artemis.Core.Models.Profile.LayerProperties
_keyframes.AddRange(entity.KeyframeEntities.Select(k => new LayerPropertyKeyframe(
JsonConvert.DeserializeObject(k.Value),
k.Position,
- (Timeline) k.Timeline,
- (Easings.Functions) k.EasingFunction,
+ (Easings.Functions)k.EasingFunction,
this
)));
}
@@ -319,8 +287,7 @@ namespace Artemis.Core.Models.Profile.LayerProperties
{
Value = JsonConvert.SerializeObject(k.Value),
Position = k.Position,
- Timeline = (int) k.Timeline,
- EasingFunction = (int) k.EasingFunction
+ EasingFunction = (int)k.EasingFunction
}));
}
}
diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/LayerPropertyKeyFrame.cs b/src/Artemis.Core/Models/Profile/LayerProperties/LayerPropertyKeyFrame.cs
index 9f6791a80..af37209aa 100644
--- a/src/Artemis.Core/Models/Profile/LayerProperties/LayerPropertyKeyFrame.cs
+++ b/src/Artemis.Core/Models/Profile/LayerProperties/LayerPropertyKeyFrame.cs
@@ -6,12 +6,10 @@ namespace Artemis.Core.Models.Profile.LayerProperties
public class LayerPropertyKeyframe : BaseLayerPropertyKeyframe
{
private TimeSpan _position;
- private Timeline _timeline;
- public LayerPropertyKeyframe(T value, TimeSpan position, Timeline timeline, Easings.Functions easingFunction, LayerProperty layerProperty) : base(layerProperty)
+ public LayerPropertyKeyframe(T value, TimeSpan position, Easings.Functions easingFunction, LayerProperty layerProperty) : base(layerProperty)
{
_position = position;
- _timeline = timeline;
Value = value;
LayerProperty = layerProperty;
EasingFunction = easingFunction;
@@ -27,17 +25,6 @@ namespace Artemis.Core.Models.Profile.LayerProperties
///
public T Value { get; set; }
- ///
- public override Timeline Timeline
- {
- get => _timeline;
- set
- {
- _timeline = value;
- LayerProperty.SortKeyframes();
- }
- }
-
///
public override TimeSpan Position
{
diff --git a/src/Artemis.Core/Models/Profile/RenderProfileElement.cs b/src/Artemis.Core/Models/Profile/RenderProfileElement.cs
index a8aa76848..bbc5206ad 100644
--- a/src/Artemis.Core/Models/Profile/RenderProfileElement.cs
+++ b/src/Artemis.Core/Models/Profile/RenderProfileElement.cs
@@ -19,11 +19,6 @@ namespace Artemis.Core.Models.Profile
private SKPath _path;
internal abstract RenderElementEntity RenderElementEntity { get; }
- ///
- /// Gets or sets the currently active timeline
- ///
- public Timeline CurrentTimeline { get; set; }
-
///
/// Gets the path containing all the LEDs this entity is applied to, any rendering outside the entity Path is
/// clipped.
@@ -71,6 +66,66 @@ namespace Artemis.Core.Models.Profile
#endregion
+ #region Timeline
+
+ private TimeSpan _startSegmentLength;
+ private TimeSpan _mainSegmentLength;
+ private TimeSpan _endSegmentLength;
+ private bool _repeatMainSegment;
+ private bool _alwaysFinishTimeline;
+
+ ///
+ /// Gets or sets the length of the start segment
+ ///
+ public TimeSpan StartSegmentLength
+ {
+ get => _startSegmentLength;
+ set => SetAndNotify(ref _startSegmentLength, value);
+ }
+
+ ///
+ /// Gets or sets the length of the main segment
+ ///
+ public TimeSpan MainSegmentLength
+ {
+ get => _mainSegmentLength;
+ set => SetAndNotify(ref _mainSegmentLength, value);
+ }
+
+ ///
+ /// Gets or sets the length of the end segment
+ ///
+ public TimeSpan EndSegmentLength
+ {
+ get => _endSegmentLength;
+ set => SetAndNotify(ref _endSegmentLength, value);
+ }
+
+ ///
+ /// Gets the total combined length of all three segments
+ ///
+ public TimeSpan TimelineLength => StartSegmentLength + MainSegmentLength + EndSegmentLength;
+
+ ///
+ /// Gets or sets whether main timeline should repeat itself as long as display conditions are met
+ ///
+ public bool RepeatMainSegment
+ {
+ get => _repeatMainSegment;
+ set => SetAndNotify(ref _repeatMainSegment, value);
+ }
+
+ ///
+ /// Gets or sets whether the timeline should finish when conditions are no longer met
+ ///
+ public bool AlwaysFinishTimeline
+ {
+ get => _alwaysFinishTimeline;
+ set => SetAndNotify(ref _alwaysFinishTimeline, value);
+ }
+
+ #endregion
+
#region Effects
protected List _layerEffects;
@@ -138,7 +193,7 @@ namespace Artemis.Core.Models.Profile
#region Conditions
private DisplayConditionGroup _displayConditionGroup;
-
+
///
/// Gets or sets the root display condition group
///
diff --git a/src/Artemis.UI.Shared/Services/Interfaces/IProfileEditorService.cs b/src/Artemis.UI.Shared/Services/Interfaces/IProfileEditorService.cs
index 9f627d4ea..c1fa98e4e 100644
--- a/src/Artemis.UI.Shared/Services/Interfaces/IProfileEditorService.cs
+++ b/src/Artemis.UI.Shared/Services/Interfaces/IProfileEditorService.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using Artemis.Core.Models.Profile;
-using Artemis.Core.Models.Profile.LayerProperties;
using Artemis.Core.Plugins.Abstract;
using Artemis.Core.Plugins.Models;
using Artemis.UI.Shared.Events;
@@ -15,7 +14,6 @@ namespace Artemis.UI.Shared.Services.Interfaces
Profile SelectedProfile { get; }
RenderProfileElement SelectedProfileElement { get; }
TimeSpan CurrentTime { get; set; }
- Timeline CurrentTimeline { get; set; }
int PixelsPerSecond { get; set; }
IReadOnlyList RegisteredPropertyEditors { get; }
IKernel Kernel { get; }
@@ -55,12 +53,7 @@ namespace Artemis.UI.Shared.Services.Interfaces
/// Occurs when the current editor time is changed
///
event EventHandler CurrentTimeChanged;
-
- ///
- /// Occurs when the current editor timeline is changed
- ///
- event EventHandler CurrentTimelineChanged;
-
+
///
/// Occurs when the pixels per second (zoom level) is changed
///
diff --git a/src/Artemis.UI.Shared/Services/ProfileEditorService.cs b/src/Artemis.UI.Shared/Services/ProfileEditorService.cs
index ad64bc88b..a7a80f022 100644
--- a/src/Artemis.UI.Shared/Services/ProfileEditorService.cs
+++ b/src/Artemis.UI.Shared/Services/ProfileEditorService.cs
@@ -25,7 +25,6 @@ namespace Artemis.UI.Shared.Services
private TimeSpan _currentTime;
private TimeSpan _lastUpdateTime;
private int _pixelsPerSecond;
- private Timeline _currentTimeline;
public ProfileEditorService(ICoreService coreService, IProfileService profileService, IKernel kernel, ILogger logger)
{
@@ -49,24 +48,15 @@ namespace Artemis.UI.Shared.Services
set
{
if (_currentTime.Equals(value)) return;
- _currentTime = value;
+ if (value > SelectedProfileElement.TimelineLength)
+ _currentTime = SelectedProfileElement.TimelineLength;
+ else
+ _currentTime = value;
UpdateProfilePreview();
OnCurrentTimeChanged();
}
}
- public Timeline CurrentTimeline
- {
- get => _currentTimeline;
- set
- {
- if (_currentTimeline.Equals(value)) return;
- _currentTimeline = value;
- UpdateProfilePreview();
- OnCurrentTimelineChanged();
- }
- }
-
public int PixelsPerSecond
{
get => _pixelsPerSecond;
@@ -126,14 +116,12 @@ namespace Artemis.UI.Shared.Services
var delta = CurrentTime - _lastUpdateTime;
foreach (var folder in SelectedProfile.GetAllFolders())
{
- folder.CurrentTimeline = CurrentTimeline;
foreach (var baseLayerEffect in folder.LayerEffects)
baseLayerEffect.Update(delta.TotalSeconds);
}
foreach (var layer in SelectedProfile.GetAllLayers())
{
- layer.CurrentTimeline = CurrentTimeline;
layer.OverrideProgress(CurrentTime);
layer.LayerBrush?.Update(delta.TotalSeconds);
foreach (var baseLayerEffect in layer.LayerEffects)
diff --git a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs
index 46772a6c6..e9770db83 100644
--- a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs
+++ b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs
@@ -1,5 +1,6 @@
using Artemis.Core.Models.Profile;
using Artemis.Core.Models.Profile.Conditions;
+using Artemis.Core.Models.Profile.LayerProperties;
using Artemis.Core.Models.Profile.LayerProperties.Attributes;
using Artemis.Core.Models.Surface;
using Artemis.Core.Plugins.Abstract;
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/DisplayConditions/DisplayConditionsView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/DisplayConditions/DisplayConditionsView.xaml
index 9df02ef19..86b6758ec 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/DisplayConditions/DisplayConditionsView.xaml
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/DisplayConditions/DisplayConditionsView.xaml
@@ -30,9 +30,10 @@
-
-
- Play once
+
+
+ Play once
+
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesView.xaml
index 6b14a0e04..ea35b1e5a 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesView.xaml
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesView.xaml
@@ -79,50 +79,49 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -135,7 +134,6 @@
-
@@ -169,28 +167,58 @@
-
-
+
+
-
@@ -201,17 +229,18 @@
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
ScrollChanged="TimelineScrollChanged">
-
-
+
-
+
-
+
+
@@ -291,59 +320,15 @@
-
-
-
-
-
- Select the enter timeline
- Played when the folder/layer starts displaying (condition is met)
-
-
-
-
-
- ENTER
-
-
-
-
-
-
- Select the main timeline
- Played after the enter timeline finishes, either on repeat or once
-
-
-
-
-
- MAIN
-
-
-
-
-
-
- Select the exit timeline
- Played when the folder/layer stops displaying (conditon no longer met)
-
-
-
-
-
-
- EXIT
-
-
-
-
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs
index 0013113d6..9fb2daac5 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs
@@ -27,14 +27,14 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
{
private readonly ILayerPropertyVmFactory _layerPropertyVmFactory;
private LayerPropertyGroupViewModel _brushPropertyGroup;
- private bool _repeatAfterLastKeyframe;
- private int _propertyTreeIndex;
- private RenderProfileElement _selectedProfileElement;
- private BindableCollection _layerPropertyGroups;
- private TreeViewModel _treeViewModel;
private EffectsViewModel _effectsViewModel;
- private TimelineViewModel _timelineViewModel;
+ private BindableCollection _layerPropertyGroups;
private bool _playing;
+ private int _propertyTreeIndex;
+ private bool _repeatAfterLastKeyframe;
+ private RenderProfileElement _selectedProfileElement;
+ private TimelineViewModel _timelineViewModel;
+ private TreeViewModel _treeViewModel;
public LayerPropertiesViewModel(IProfileEditorService profileEditorService, ICoreService coreService, ISettingsService settingsService,
ILayerPropertyVmFactory layerPropertyVmFactory)
@@ -84,16 +84,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
}
}
- public int CurrentTimelineIndex
- {
- get => (int) ProfileEditorService.CurrentTimeline;
- set
- {
- ProfileEditorService.CurrentTimeline = (Core.Models.Profile.LayerProperties.Timeline) value;
- ProfileEditorService.CurrentTime = TimeSpan.Zero;
- }
- }
-
public bool PropertyTreeVisible => PropertyTreeIndex == 0;
public RenderProfileElement SelectedProfileElement
@@ -133,14 +123,13 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
get => _timelineViewModel;
set => SetAndNotify(ref _timelineViewModel, value);
}
-
+
protected override void OnInitialActivate()
{
PopulateProperties(ProfileEditorService.SelectedProfileElement);
ProfileEditorService.ProfileElementSelected += ProfileEditorServiceOnProfileElementSelected;
ProfileEditorService.CurrentTimeChanged += ProfileEditorServiceOnCurrentTimeChanged;
- ProfileEditorService.CurrentTimelineChanged += ProfileEditorServiceOnCurrentTimelineChanged;
ProfileEditorService.PixelsPerSecondChanged += ProfileEditorServiceOnPixelsPerSecondChanged;
base.OnInitialActivate();
@@ -150,7 +139,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
{
ProfileEditorService.ProfileElementSelected -= ProfileEditorServiceOnProfileElementSelected;
ProfileEditorService.CurrentTimeChanged -= ProfileEditorServiceOnCurrentTimeChanged;
- ProfileEditorService.CurrentTimelineChanged -= ProfileEditorServiceOnCurrentTimelineChanged;
ProfileEditorService.PixelsPerSecondChanged -= ProfileEditorServiceOnPixelsPerSecondChanged;
PopulateProperties(null);
@@ -171,6 +159,14 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
private void ProfileEditorServiceOnProfileElementSelected(object sender, RenderProfileElementEventArgs e)
{
+ // Placeholder
+ if (e.RenderProfileElement != null)
+ {
+ e.RenderProfileElement.StartSegmentLength = TimeSpan.FromMilliseconds(1000);
+ e.RenderProfileElement.MainSegmentLength = TimeSpan.FromMilliseconds(5000);
+ e.RenderProfileElement.EndSegmentLength = TimeSpan.FromMilliseconds(1000);
+ }
+
PopulateProperties(e.RenderProfileElement);
}
@@ -180,11 +176,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
NotifyOfPropertyChange(nameof(TimeCaretPosition));
}
- private void ProfileEditorServiceOnCurrentTimelineChanged(object? sender, EventArgs e)
- {
- NotifyOfPropertyChange(nameof(CurrentTimelineIndex));
- TimelineViewModel.UpdateKeyframes();
- }
private void ProfileEditorServiceOnPixelsPerSecondChanged(object sender, EventArgs e)
{
@@ -239,6 +230,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
}
TreeViewModel = _layerPropertyVmFactory.TreeViewModel(this, LayerPropertyGroups);
+
+ TimelineViewModel?.Dispose();
TimelineViewModel = _layerPropertyVmFactory.TimelineViewModel(this, LayerPropertyGroups);
ApplyLayerBrush();
@@ -287,7 +280,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
}
SortProperties();
- TimelineViewModel.UpdateKeyframes();
+ UpdateKeyframes();
}
private void ApplyEffects()
@@ -322,7 +315,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
}
SortProperties();
- TimelineViewModel.UpdateKeyframes();
+ UpdateKeyframes();
}
private void SortProperties()
@@ -347,6 +340,11 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
}
}
+ private void UpdateKeyframes()
+ {
+ TimelineViewModel.Update();
+ }
+
#endregion
#region Drag and drop
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/Controls/PropertyTimelineHeader.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/Controls/PropertyTimelineHeader.cs
index 84fa4c76c..22490ddce 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/Controls/PropertyTimelineHeader.cs
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/Controls/PropertyTimelineHeader.cs
@@ -23,6 +23,9 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
public static readonly DependencyProperty VisibleWidthProperty = DependencyProperty.Register(nameof(VisibleWidth), typeof(double), typeof(PropertyTimelineHeader),
new FrameworkPropertyMetadata(default(double), FrameworkPropertyMetadataOptions.AffectsRender));
+ public static readonly DependencyProperty OffsetFirstValueProperty = DependencyProperty.Register(nameof(OffsetFirstValue), typeof(bool), typeof(PropertyTimelineHeader),
+ new FrameworkPropertyMetadata(default(bool), FrameworkPropertyMetadataOptions.AffectsRender));
+
private double _subd1;
private double _subd2;
private double _subd3;
@@ -57,6 +60,12 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
set => SetValue(VisibleWidthProperty, value);
}
+ public bool OffsetFirstValue
+ {
+ get => (bool) GetValue(OffsetFirstValueProperty);
+ set => SetValue(OffsetFirstValueProperty, value);
+ }
+
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
@@ -73,7 +82,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
var count = (width + offsetUnits) / units;
for (var i = 0; i < count; i++)
{
- var x = i * units - offsetUnits + 1;
+ var x = i * units - offsetUnits;
// Add a 100px margin to allow the text to partially render when needed
if (x < HorizontalOffset - 100 || x > HorizontalOffset + width)
continue;
@@ -95,8 +104,10 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
count = (width + offsetUnits) / units;
for (var i = 0; i < count; i++)
{
- var x = i * units - offsetUnits + 1;
- if (x > HorizontalOffset && x < HorizontalOffset + width)
+ var x = i * units - offsetUnits;
+ if (x == 0 && OffsetFirstValue)
+ drawingContext.DrawLine(linePen, new Point(1, 20), new Point(1, 30));
+ else if (x > HorizontalOffset && x < HorizontalOffset + width)
drawingContext.DrawLine(linePen, new Point(x, 20), new Point(x, 30));
}
@@ -107,7 +118,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
for (var i = 0; i < count; i++)
{
if (Math.Abs(i % mul) < 0.001) continue;
- var x = i * units - offsetUnits + 1;
+ var x = i * units - offsetUnits;
if (x > HorizontalOffset && x < HorizontalOffset + width)
drawingContext.DrawLine(linePen, new Point(x, 25), new Point(x, 30));
}
@@ -117,8 +128,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
{
var typeFace = new Typeface(FontFamily, new FontStyle(), new FontWeight(), new FontStretch());
var formattedText = new FormattedText(text, CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, typeFace, 9, Fill, null, VisualTreeHelper.GetDpi(this).PixelsPerDip);
- if (x == 1)
- drawingContext.DrawText(formattedText, new Point(x, 2));
+ if (x == 0 && OffsetFirstValue)
+ drawingContext.DrawText(formattedText, new Point(2, 2));
else
drawingContext.DrawText(formattedText, new Point(x - formattedText.Width / 2, 2));
}
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelineKeyframeViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelineKeyframeViewModel.cs
index 6273574bf..8e320fd77 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelineKeyframeViewModel.cs
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelineKeyframeViewModel.cs
@@ -27,7 +27,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
var newKeyframe = new LayerPropertyKeyframe(
LayerPropertyKeyframe.Value,
LayerPropertyKeyframe.Position,
- LayerPropertyKeyframe.Timeline,
LayerPropertyKeyframe.EasingFunction,
LayerPropertyKeyframe.LayerProperty
);
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelinePropertyGroupViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelinePropertyGroupViewModel.cs
index 7d4dab2f6..881e40045 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelinePropertyGroupViewModel.cs
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelinePropertyGroupViewModel.cs
@@ -35,7 +35,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
{
TimelineKeyframeViewModels.Clear();
TimelineKeyframeViewModels.AddRange(LayerPropertyGroupViewModel.GetKeyframes(false)
- .Where(k => k.Timeline == _profileEditorService.CurrentTimeline)
.Select(k => LayerPropertyGroupViewModel.ProfileEditorService.PixelsPerSecond * k.Position.TotalSeconds));
}
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelinePropertyViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelinePropertyViewModel.cs
index cfbb44aaa..2046a9e35 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelinePropertyViewModel.cs
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelinePropertyViewModel.cs
@@ -28,9 +28,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
// Only show keyframes if they are enabled
if (LayerPropertyViewModel.LayerProperty.KeyframesEnabled)
{
- var keyframes = LayerPropertyViewModel.LayerProperty.Keyframes
- .Where(k => k.Timeline == _profileEditorService.CurrentTimeline)
- .ToList();
+ var keyframes = LayerPropertyViewModel.LayerProperty.Keyframes.ToList();
var toRemove = TimelineKeyframeViewModels.Where(t => !keyframes.Contains(t.BaseLayerPropertyKeyframe)).ToList();
TimelineKeyframeViewModels.RemoveRange(toRemove);
TimelineKeyframeViewModels.AddRange(
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelineView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelineView.xaml
index 1e6549ac2..3878820b2 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelineView.xaml
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelineView.xaml
@@ -9,11 +9,11 @@
d:DesignHeight="25"
d:DesignWidth="800"
d:DataContext="{d:DesignInstance local:TimelineViewModel}">
-
+ MouseMove="{s:Action TimelineCanvasMouseMove}">
@@ -41,6 +41,29 @@
+
+
+
+
layerPropertyGroups,
- IProfileEditorService profileEditorService)
+ public TimelineViewModel(LayerPropertiesViewModel layerPropertiesViewModel, BindableCollection layerPropertyGroups, IProfileEditorService profileEditorService)
{
_layerPropertiesViewModel = layerPropertiesViewModel;
_profileEditorService = profileEditorService;
+
LayerPropertyGroups = layerPropertyGroups;
SelectionRectangle = new RectangleGeometry();
- UpdateKeyframes();
+ _profileEditorService.PixelsPerSecondChanged += ProfileEditorServiceOnPixelsPerSecondChanged;
+
+ Update();
}
public BindableCollection LayerPropertyGroups { get; }
@@ -38,7 +40,19 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
set => SetAndNotify(ref _selectionRectangle, value);
}
- public void UpdateKeyframes()
+ public double StartSegmentWidth => _profileEditorService.PixelsPerSecond * _profileEditorService.SelectedProfileElement?.StartSegmentLength.TotalSeconds ?? 0;
+ public double StartSegmentEndPosition => StartSegmentWidth;
+ public double MainSegmentWidth => _profileEditorService.PixelsPerSecond * _profileEditorService.SelectedProfileElement?.MainSegmentLength.TotalSeconds ?? 0;
+ public double MainSegmentEndPosition => StartSegmentWidth + MainSegmentWidth;
+ public double EndSegmentWidth => _profileEditorService.PixelsPerSecond * _profileEditorService.SelectedProfileElement?.EndSegmentLength.TotalSeconds ?? 0;
+ public double EndSegmentEndPosition => StartSegmentWidth + MainSegmentWidth + EndSegmentWidth;
+
+ public void Dispose()
+ {
+ _profileEditorService.PixelsPerSecondChanged -= ProfileEditorServiceOnPixelsPerSecondChanged;
+ }
+
+ public void Update()
{
foreach (var layerPropertyGroupViewModel in LayerPropertyGroups)
{
@@ -52,6 +66,16 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
}
}
+ private void ProfileEditorServiceOnPixelsPerSecondChanged(object sender, EventArgs e)
+ {
+ NotifyOfPropertyChange(nameof(StartSegmentWidth));
+ NotifyOfPropertyChange(nameof(StartSegmentEndPosition));
+ NotifyOfPropertyChange(nameof(MainSegmentWidth));
+ NotifyOfPropertyChange(nameof(MainSegmentEndPosition));
+ NotifyOfPropertyChange(nameof(EndSegmentWidth));
+ NotifyOfPropertyChange(nameof(EndSegmentEndPosition));
+ }
+
#region Command handlers
public void KeyframeMouseDown(object sender, MouseButtonEventArgs e)
@@ -274,5 +298,19 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
}
#endregion
+
+ #region IViewAware
+
+ public void AttachView(UIElement view)
+ {
+ if (View != null)
+ throw new InvalidOperationException(string.Format("Tried to attach View {0} to ViewModel {1}, but it already has a view attached", view.GetType().Name, GetType().Name));
+
+ View = view;
+ }
+
+ public UIElement View { get; set; }
+
+ #endregion
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/TreePropertyViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/TreePropertyViewModel.cs
index 6e4017456..c0470e579 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/TreePropertyViewModel.cs
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/TreePropertyViewModel.cs
@@ -50,7 +50,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree
LayerPropertyViewModel.LayerProperty.AddKeyframe(new LayerPropertyKeyframe(
LayerPropertyViewModel.LayerProperty.CurrentValue,
_profileEditorService.CurrentTime,
- _profileEditorService.CurrentTimeline,
Easings.Functions.Linear,
LayerPropertyViewModel.LayerProperty
));