mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 20:06:33 +00:00
Implemented basic keyframes
This commit is contained in:
1 parent
e8570a6dd9
commit
0958c3af9f
41 files changed
+951
-123
No files matched your search
+19
-26
@@ -15,29 +15,22 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
|
||||
private readonly ILayerPropertyViewModelFactory _layerPropertyViewModelFactory;
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
|
||||
public LayerPropertiesViewModel(IProfileEditorService profileEditorService, ILayerPropertyViewModelFactory layerPropertyViewModelFactory)
|
||||
public LayerPropertiesViewModel(IProfileEditorService profileEditorService,
|
||||
ILayerPropertyViewModelFactory layerPropertyViewModelFactory,
|
||||
IPropertyTreeViewModelFactory propertyTreeViewModelFactory,
|
||||
IPropertyTimelineViewModelFactory propertyTimelineViewModelFactory)
|
||||
{
|
||||
_profileEditorService = profileEditorService;
|
||||
_layerPropertyViewModelFactory = layerPropertyViewModelFactory;
|
||||
|
||||
CurrentTime = TimeSpan.Zero;
|
||||
PixelsPerSecond = 1;
|
||||
PropertyTree = new PropertyTreeViewModel(this);
|
||||
PropertyTimeline = new PropertyTimelineViewModel(this);
|
||||
PropertyTree = propertyTreeViewModelFactory.Create(this);
|
||||
PropertyTimeline = propertyTimelineViewModelFactory.Create(this);
|
||||
|
||||
PopulateProperties();
|
||||
|
||||
_profileEditorService.SelectedProfileElementChanged += (sender, args) => PopulateProperties();
|
||||
}
|
||||
|
||||
public TimeSpan CurrentTime
|
||||
{
|
||||
get => _currentTime;
|
||||
set
|
||||
{
|
||||
_currentTime = value;
|
||||
OnCurrentTimeChanged();
|
||||
}
|
||||
_profileEditorService.CurrentTimeChanged += ProfileEditorServiceOnCurrentTimeChanged;
|
||||
}
|
||||
|
||||
public string FormattedCurrentTime
|
||||
@@ -45,10 +38,10 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
|
||||
get
|
||||
{
|
||||
if (PixelsPerSecond > 200)
|
||||
return $"{Math.Floor(CurrentTime.TotalSeconds):00}.{CurrentTime.Milliseconds:000}";
|
||||
return $"{Math.Floor(_profileEditorService.CurrentTime.TotalSeconds):00}.{_profileEditorService.CurrentTime.Milliseconds:000}";
|
||||
if (PixelsPerSecond > 60)
|
||||
return $"{Math.Floor(CurrentTime.TotalSeconds):00}.{CurrentTime.Milliseconds:000}";
|
||||
return $"{Math.Floor(CurrentTime.TotalMinutes):0}:{CurrentTime.Seconds:00}";
|
||||
return $"{Math.Floor(_profileEditorService.CurrentTime.TotalSeconds):00}.{_profileEditorService.CurrentTime.Milliseconds:000}";
|
||||
return $"{Math.Floor(_profileEditorService.CurrentTime.TotalMinutes):0}:{_profileEditorService.CurrentTime.Seconds:00}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,8 +57,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
|
||||
|
||||
public Thickness TimeCaretPosition
|
||||
{
|
||||
get => new Thickness(CurrentTime.TotalSeconds * PixelsPerSecond, 0, 0, 0);
|
||||
set => CurrentTime = TimeSpan.FromSeconds(value.Left / PixelsPerSecond);
|
||||
get => new Thickness(_profileEditorService.CurrentTime.TotalSeconds * PixelsPerSecond, 0, 0, 0);
|
||||
set => _profileEditorService.CurrentTime = TimeSpan.FromSeconds(value.Left / PixelsPerSecond);
|
||||
}
|
||||
|
||||
public PropertyTreeViewModel PropertyTree { get; set; }
|
||||
@@ -91,15 +84,21 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
|
||||
}
|
||||
}
|
||||
|
||||
private void ProfileEditorServiceOnCurrentTimeChanged(object sender, EventArgs e)
|
||||
{
|
||||
NotifyOfPropertyChange(() => FormattedCurrentTime);
|
||||
NotifyOfPropertyChange(() => TimeCaretPosition);
|
||||
}
|
||||
|
||||
#region Caret movement
|
||||
|
||||
private double _caretStartMouseStartOffset;
|
||||
private bool _mouseOverCaret;
|
||||
private int _pixelsPerSecond;
|
||||
private TimeSpan _currentTime;
|
||||
|
||||
public void RightGridMouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
// TODO Preserve mouse offset
|
||||
_caretStartMouseStartOffset = e.GetPosition((IInputElement) sender).X - TimeCaretPosition.Left;
|
||||
}
|
||||
|
||||
@@ -124,14 +123,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
|
||||
|
||||
#region Events
|
||||
|
||||
public event EventHandler CurrentTimeChanged;
|
||||
public event EventHandler PixelsPerSecondChanged;
|
||||
|
||||
protected virtual void OnCurrentTimeChanged()
|
||||
{
|
||||
CurrentTimeChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
protected virtual void OnPixelsPerSecondChanged()
|
||||
{
|
||||
PixelsPerSecondChanged?.Invoke(this, EventArgs.Empty);
|
||||
|
||||
+15
-1
@@ -3,6 +3,7 @@ using System.Linq;
|
||||
using Artemis.Core.Models.Profile.LayerProperties;
|
||||
using Artemis.UI.Ninject.Factories;
|
||||
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput;
|
||||
using Artemis.UI.Services.Interfaces;
|
||||
using Ninject;
|
||||
using Stylet;
|
||||
|
||||
@@ -11,11 +12,14 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
|
||||
public class LayerPropertyViewModel : PropertyChangedBase
|
||||
{
|
||||
private readonly IKernel _kernel;
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private bool _keyframesEnabled;
|
||||
|
||||
public LayerPropertyViewModel(BaseLayerProperty layerProperty, LayerPropertyViewModel parent, ILayerPropertyViewModelFactory layerPropertyViewModelFactory, IKernel kernel)
|
||||
public LayerPropertyViewModel(BaseLayerProperty layerProperty, LayerPropertyViewModel parent, ILayerPropertyViewModelFactory layerPropertyViewModelFactory, IKernel kernel, IProfileEditorService profileEditorService)
|
||||
{
|
||||
_kernel = kernel;
|
||||
_profileEditorService = profileEditorService;
|
||||
_keyframesEnabled = layerProperty.UntypedKeyframes.Any();
|
||||
|
||||
LayerProperty = layerProperty;
|
||||
Parent = parent;
|
||||
@@ -44,6 +48,16 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
|
||||
|
||||
private void UpdateKeyframes()
|
||||
{
|
||||
// Either create a new first keyframe or clear all the keyframes
|
||||
if (_keyframesEnabled)
|
||||
LayerProperty.CreateNewKeyframe(_profileEditorService.CurrentTime);
|
||||
else
|
||||
LayerProperty.ClearKeyframes();
|
||||
|
||||
// Force the keyframe engine to update, the new keyframe is the current keyframe
|
||||
LayerProperty.KeyframeEngine.Update(0);
|
||||
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
}
|
||||
|
||||
public PropertyInputViewModel GetPropertyInputViewModel()
|
||||
|
||||
+1
@@ -15,6 +15,7 @@
|
||||
Padding="0 -1"
|
||||
materialDesign:ValidationAssist.UsePopup="True"
|
||||
HorizontalAlignment="Left"
|
||||
Text="{Binding FloatInputValue}"
|
||||
Cursor="/Resources/aero_drag_ew.cur" />
|
||||
<TextBlock Margin="5 0 0 0" Width="10" VerticalAlignment="Bottom" Text="{Binding LayerPropertyViewModel.LayerProperty.InputAffix}" />
|
||||
</StackPanel>
|
||||
|
||||
+21
-8
@@ -1,26 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Artemis.Core.Models.Profile.LayerProperties;
|
||||
using Artemis.UI.Services.Interfaces;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput
|
||||
{
|
||||
public class FloatPropertyInputViewModel : PropertyInputViewModel
|
||||
{
|
||||
public FloatPropertyInputViewModel(IProfileEditorService profileEditorService) : base(profileEditorService)
|
||||
{
|
||||
}
|
||||
|
||||
public sealed override List<Type> CompatibleTypes { get; } = new List<Type> {typeof(float)};
|
||||
|
||||
public float FloatInputValue
|
||||
{
|
||||
get => (float) InputValue;
|
||||
set => InputValue = value;
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
NotifyOfPropertyChange(() => FloatInputValue);
|
||||
}
|
||||
|
||||
protected override void UpdateBaseValue(object value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var layerProperty = (LayerProperty<float>) LayerPropertyViewModel.LayerProperty;
|
||||
layerProperty.Value = (float) value;
|
||||
}
|
||||
|
||||
protected override void UpdateKeyframeValue(BaseKeyframe keyframe, object value)
|
||||
protected override void UpdateKeyframeValue(BaseKeyframe baseKeyframe, object value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override void CreateKeyframeForValue(object value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var keyframe = (Keyframe<float>) baseKeyframe;
|
||||
keyframe.Value = (float) value;
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -15,6 +15,7 @@
|
||||
Padding="0 -1"
|
||||
materialDesign:ValidationAssist.UsePopup="True"
|
||||
HorizontalAlignment="Left"
|
||||
Text="{Binding IntInputValue}"
|
||||
Cursor="/Resources/aero_drag_ew.cur" />
|
||||
<TextBlock Margin="5 0 0 0" Width="10" VerticalAlignment="Bottom" Text="{Binding LayerPropertyViewModel.LayerProperty.InputAffix}" />
|
||||
</StackPanel>
|
||||
|
||||
+21
-8
@@ -1,26 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Artemis.Core.Models.Profile.LayerProperties;
|
||||
using Artemis.UI.Services.Interfaces;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput
|
||||
{
|
||||
public class IntPropertyInputViewModel : PropertyInputViewModel
|
||||
{
|
||||
public IntPropertyInputViewModel(IProfileEditorService profileEditorService) : base(profileEditorService)
|
||||
{
|
||||
}
|
||||
|
||||
public sealed override List<Type> CompatibleTypes { get; } = new List<Type> {typeof(int)};
|
||||
|
||||
public int IntInputValue
|
||||
{
|
||||
get => (int) InputValue;
|
||||
set => InputValue = value;
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
NotifyOfPropertyChange(() => IntInputValue);
|
||||
}
|
||||
|
||||
protected override void UpdateBaseValue(object value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var layerProperty = (LayerProperty<int>) LayerPropertyViewModel.LayerProperty;
|
||||
layerProperty.Value = (int) value;
|
||||
}
|
||||
|
||||
protected override void UpdateKeyframeValue(BaseKeyframe keyframe, object value)
|
||||
protected override void UpdateKeyframeValue(BaseKeyframe baseKeyframe, object value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override void CreateKeyframeForValue(object value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var keyframe = (Keyframe<int>) baseKeyframe;
|
||||
keyframe.Value = (int) value;
|
||||
}
|
||||
}
|
||||
}
|
||||
+23
-11
@@ -3,18 +3,26 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.Core.Models.Profile.LayerProperties;
|
||||
using Artemis.UI.Exceptions;
|
||||
using Artemis.UI.Services.Interfaces;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput
|
||||
{
|
||||
public abstract class PropertyInputViewModel : PropertyChangedBase
|
||||
{
|
||||
protected PropertyInputViewModel(IProfileEditorService profileEditorService)
|
||||
{
|
||||
ProfileEditorService = profileEditorService;
|
||||
}
|
||||
|
||||
protected IProfileEditorService ProfileEditorService { get; set; }
|
||||
|
||||
public bool Initialized { get; private set; }
|
||||
|
||||
public abstract List<Type> CompatibleTypes { get; }
|
||||
public LayerPropertyViewModel LayerPropertyViewModel { get; private set; }
|
||||
|
||||
public object InputValue
|
||||
protected object InputValue
|
||||
{
|
||||
get => LayerPropertyViewModel.LayerProperty.KeyframeEngine.GetCurrentValue();
|
||||
set => UpdateInputValue(value);
|
||||
@@ -33,11 +41,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.P
|
||||
Initialized = true;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
NotifyOfPropertyChange(() => InputValue);
|
||||
}
|
||||
|
||||
private void UpdateInputValue(object value)
|
||||
{
|
||||
// If keyframes are disabled, update the base value
|
||||
@@ -47,13 +50,22 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.P
|
||||
return;
|
||||
}
|
||||
|
||||
// If on a keyframe, update the keyframe TODO: Make decisions..
|
||||
// var currentKeyframe = LayerPropertyViewModel.LayerProperty.UntypedKeyframes.FirstOrDefault(k => k.Position == LayerPropertyViewModel.)
|
||||
// Otherwise, add a new keyframe at the current position
|
||||
// If on a keyframe, update the keyframe
|
||||
var currentKeyframe = LayerPropertyViewModel.LayerProperty.UntypedKeyframes.FirstOrDefault(k => k.Position == ProfileEditorService.CurrentTime);
|
||||
// Create a new keyframe if none found
|
||||
if (currentKeyframe == null)
|
||||
currentKeyframe = LayerPropertyViewModel.LayerProperty.CreateNewKeyframe(ProfileEditorService.CurrentTime);
|
||||
|
||||
UpdateKeyframeValue(currentKeyframe, value);
|
||||
// Force the keyframe engine to update, the edited keyframe might affect the current keyframe progress
|
||||
LayerPropertyViewModel.LayerProperty.KeyframeEngine.Update(0);
|
||||
|
||||
ProfileEditorService.UpdateSelectedProfileElement();
|
||||
|
||||
}
|
||||
|
||||
public abstract void Update();
|
||||
protected abstract void UpdateBaseValue(object value);
|
||||
protected abstract void UpdateKeyframeValue(BaseKeyframe keyframe, object value);
|
||||
protected abstract void CreateKeyframeForValue(object value);
|
||||
protected abstract void UpdateKeyframeValue(BaseKeyframe baseKeyframe, object value);
|
||||
}
|
||||
}
|
||||
+5
-3
@@ -8,7 +8,7 @@
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="25" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance local:SKPointPropertyInputViewModel}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<StackPanel Orientation="Horizontal" KeyboardNavigation.IsTabStop="True">
|
||||
<TextBlock Margin="0 0 5 0" Width="10" VerticalAlignment="Bottom" Text="{Binding LayerPropertyViewModel.LayerProperty.InputPrefix}" />
|
||||
<TextBox Width="60"
|
||||
Margin="0 2"
|
||||
@@ -16,7 +16,8 @@
|
||||
materialDesign:ValidationAssist.UsePopup="True"
|
||||
HorizontalAlignment="Left"
|
||||
ToolTip="X-coordinate (horizontal)"
|
||||
Cursor="/Resources/aero_drag_ew.cur" />
|
||||
Text="{Binding X}"
|
||||
Cursor="/Resources/aero_drag_ew.cur" KeyboardNavigation.IsTabStop="True" TabIndex="1" />
|
||||
<TextBlock Margin="5 0" VerticalAlignment="Bottom">,</TextBlock>
|
||||
<TextBox Width="60"
|
||||
Margin="0 2"
|
||||
@@ -24,7 +25,8 @@
|
||||
materialDesign:ValidationAssist.UsePopup="True"
|
||||
HorizontalAlignment="Left"
|
||||
ToolTip="Y-coordinate (vertical)"
|
||||
Cursor="/Resources/aero_drag_ew.cur" />
|
||||
Text="{Binding Y}"
|
||||
Cursor="/Resources/aero_drag_ew.cur" KeyboardNavigation.IsTabStop="True" TabIndex="2" />
|
||||
<TextBlock Margin="5 0 0 0" Width="10" VerticalAlignment="Bottom" Text="{Binding LayerPropertyViewModel.LayerProperty.InputAffix}" />
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
+32
-8
@@ -1,27 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Artemis.Core.Models.Profile.LayerProperties;
|
||||
using Artemis.UI.Services.Interfaces;
|
||||
using PropertyChanged;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput
|
||||
{
|
||||
public class SKPointPropertyInputViewModel : PropertyInputViewModel
|
||||
{
|
||||
public SKPointPropertyInputViewModel(IProfileEditorService profileEditorService) : base(profileEditorService)
|
||||
{
|
||||
}
|
||||
|
||||
public sealed override List<Type> CompatibleTypes { get; } = new List<Type> {typeof(SKPoint)};
|
||||
|
||||
// Since SKPoint is immutable we need to create properties that replace the SKPoint entirely
|
||||
[DependsOn(nameof(InputValue))]
|
||||
public float X
|
||||
{
|
||||
get => ((SKPoint) InputValue).X;
|
||||
set => InputValue = new SKPoint(value, Y);
|
||||
}
|
||||
|
||||
[DependsOn(nameof(InputValue))]
|
||||
public float Y
|
||||
{
|
||||
get => ((SKPoint) InputValue).Y;
|
||||
set => InputValue = new SKPoint(X, value);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
NotifyOfPropertyChange(() => X);
|
||||
NotifyOfPropertyChange(() => Y);
|
||||
}
|
||||
|
||||
protected override void UpdateBaseValue(object value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var layerProperty = (LayerProperty<SKPoint>) LayerPropertyViewModel.LayerProperty;
|
||||
layerProperty.Value = (SKPoint) value;
|
||||
}
|
||||
|
||||
protected override void UpdateKeyframeValue(BaseKeyframe keyframe, object value)
|
||||
protected override void UpdateKeyframeValue(BaseKeyframe baseKeyframe, object value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override void CreateKeyframeForValue(object value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var keyframe = (Keyframe<SKPoint>) baseKeyframe;
|
||||
keyframe.Value = (SKPoint) value;
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
@@ -16,6 +16,7 @@
|
||||
materialDesign:ValidationAssist.UsePopup="True"
|
||||
HorizontalAlignment="Left"
|
||||
ToolTip="Height"
|
||||
Text="{Binding Height}"
|
||||
Cursor="/Resources/aero_drag_ew.cur" />
|
||||
<TextBlock Margin="5 0" VerticalAlignment="Bottom">,</TextBlock>
|
||||
<TextBox Width="60"
|
||||
@@ -24,6 +25,7 @@
|
||||
materialDesign:ValidationAssist.UsePopup="True"
|
||||
HorizontalAlignment="Left"
|
||||
ToolTip="Width"
|
||||
Text="{Binding Width}"
|
||||
Cursor="/Resources/aero_drag_ew.cur" />
|
||||
<TextBlock Margin="5 0 0 0" Width="10" VerticalAlignment="Bottom" Text="{Binding LayerPropertyViewModel.LayerProperty.InputAffix}" />
|
||||
</StackPanel>
|
||||
|
||||
+32
-8
@@ -1,27 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Artemis.Core.Models.Profile.LayerProperties;
|
||||
using Artemis.UI.Services.Interfaces;
|
||||
using PropertyChanged;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput
|
||||
{
|
||||
public class SKSizePropertyInputViewModel : PropertyInputViewModel
|
||||
{
|
||||
public SKSizePropertyInputViewModel(IProfileEditorService profileEditorService) : base(profileEditorService)
|
||||
{
|
||||
}
|
||||
|
||||
public sealed override List<Type> CompatibleTypes { get; } = new List<Type> {typeof(SKSize)};
|
||||
|
||||
// Since SKSize is immutable we need to create properties that replace the SKPoint entirely
|
||||
[DependsOn(nameof(InputValue))]
|
||||
public float Width
|
||||
{
|
||||
get => ((SKSize) InputValue).Width;
|
||||
set => InputValue = new SKSize(value, Height);
|
||||
}
|
||||
|
||||
[DependsOn(nameof(InputValue))]
|
||||
public float Height
|
||||
{
|
||||
get => ((SKSize) InputValue).Height;
|
||||
set => InputValue = new SKSize(Width, value);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
NotifyOfPropertyChange(() => Width);
|
||||
NotifyOfPropertyChange(() => Height);
|
||||
}
|
||||
|
||||
protected override void UpdateBaseValue(object value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var layerProperty = (LayerProperty<SKSize>) LayerPropertyViewModel.LayerProperty;
|
||||
layerProperty.Value = (SKSize) value;
|
||||
}
|
||||
|
||||
protected override void UpdateKeyframeValue(BaseKeyframe keyframe, object value)
|
||||
protected override void UpdateKeyframeValue(BaseKeyframe baseKeyframe, object value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override void CreateKeyframeForValue(object value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var keyframe = (Keyframe<SKSize>) baseKeyframe;
|
||||
keyframe.Value = (SKSize) value;
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -22,7 +22,7 @@
|
||||
ToolTip="Toggle key-framing"
|
||||
Width="18"
|
||||
Height="18"
|
||||
IsChecked="{Binding KeyframesEnabled}"
|
||||
IsChecked="{Binding LayerPropertyViewModel.KeyframesEnabled}"
|
||||
VerticalAlignment="Center" Padding="-25">
|
||||
<materialDesign:PackIcon Kind="Stopwatch" Height="13" Width="13" />
|
||||
</ToggleButton>
|
||||
|
||||
+12
@@ -12,5 +12,17 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree
|
||||
|
||||
public LayerPropertyViewModel LayerPropertyViewModel { get; }
|
||||
public PropertyInputViewModel PropertyInputViewModel { get; set; }
|
||||
|
||||
public override void Update(bool forceUpdate)
|
||||
{
|
||||
if (forceUpdate)
|
||||
PropertyInputViewModel.Update();
|
||||
else
|
||||
{
|
||||
// Only update if visible and if keyframes are enabled
|
||||
if (LayerPropertyViewModel.Parent.IsExpanded && LayerPropertyViewModel.KeyframesEnabled)
|
||||
PropertyInputViewModel.Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-1
@@ -2,7 +2,12 @@
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree
|
||||
{
|
||||
public class PropertyTreeItemViewModel : PropertyChangedBase
|
||||
public abstract class PropertyTreeItemViewModel : PropertyChangedBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Updates the tree item's input if it is visible and has keyframes enabled
|
||||
/// </summary>
|
||||
/// <param name="forceUpdate">Force update regardless of visibility and keyframes</param>
|
||||
public abstract void Update(bool forceUpdate);
|
||||
}
|
||||
}
|
||||
+6
@@ -21,5 +21,11 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree
|
||||
|
||||
public LayerPropertyViewModel LayerPropertyViewModel { get; }
|
||||
public BindableCollection<PropertyTreeItemViewModel> Children { get; set; }
|
||||
|
||||
public override void Update(bool forceUpdate)
|
||||
{
|
||||
foreach (var child in Children)
|
||||
child.Update(forceUpdate);
|
||||
}
|
||||
}
|
||||
}
|
||||
+21
-2
@@ -1,15 +1,24 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.UI.Services.Interfaces;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree
|
||||
{
|
||||
public class PropertyTreeViewModel : PropertyChangedBase
|
||||
{
|
||||
public PropertyTreeViewModel(LayerPropertiesViewModel layerPropertiesViewModel)
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
|
||||
public PropertyTreeViewModel(LayerPropertiesViewModel layerPropertiesViewModel, IProfileEditorService profileEditorService)
|
||||
{
|
||||
_profileEditorService = profileEditorService;
|
||||
|
||||
LayerPropertiesViewModel = layerPropertiesViewModel;
|
||||
PropertyTreeItemViewModels = new BindableCollection<PropertyTreeItemViewModel>();
|
||||
|
||||
_profileEditorService.CurrentTimeChanged += (sender, args) => Update(false);
|
||||
_profileEditorService.SelectedProfileElementUpdated += (sender, args) => Update(true);
|
||||
}
|
||||
|
||||
public LayerPropertiesViewModel LayerPropertiesViewModel { get; }
|
||||
@@ -31,5 +40,15 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree
|
||||
{
|
||||
PropertyTreeItemViewModels.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the tree item's input if it is visible and has keyframes enabled
|
||||
/// </summary>
|
||||
/// <param name="forceUpdate">Force update regardless of visibility and keyframes</param>
|
||||
public void Update(bool forceUpdate)
|
||||
{
|
||||
foreach (var viewModel in PropertyTreeItemViewModels)
|
||||
viewModel.Update(forceUpdate);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
HorizontalAlignment="Left">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
|
||||
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" />
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
|
||||
+28
-3
@@ -1,16 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.UI.Services.Interfaces;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
|
||||
{
|
||||
public class PropertyTimelineViewModel : PropertyChangedBase
|
||||
{
|
||||
public PropertyTimelineViewModel(LayerPropertiesViewModel layerPropertiesViewModel)
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
|
||||
public PropertyTimelineViewModel(LayerPropertiesViewModel layerPropertiesViewModel, IProfileEditorService profileEditorService)
|
||||
{
|
||||
_profileEditorService = profileEditorService;
|
||||
|
||||
LayerPropertiesViewModel = layerPropertiesViewModel;
|
||||
PropertyTrackViewModels = new BindableCollection<PropertyTrackViewModel>();
|
||||
|
||||
_profileEditorService.SelectedProfileElementUpdated += (sender, args) => Update();
|
||||
LayerPropertiesViewModel.PixelsPerSecondChanged += (sender, args) => UpdateKeyframePositions();
|
||||
}
|
||||
|
||||
public LayerPropertiesViewModel LayerPropertiesViewModel { get; }
|
||||
@@ -27,8 +35,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
|
||||
Width = endTime.TotalSeconds * LayerPropertiesViewModel.PixelsPerSecond;
|
||||
|
||||
// Ensure the caret isn't outside the end time
|
||||
if (LayerPropertiesViewModel.CurrentTime > endTime)
|
||||
LayerPropertiesViewModel.CurrentTime = endTime;
|
||||
if (_profileEditorService.CurrentTime > endTime)
|
||||
_profileEditorService.CurrentTime = endTime;
|
||||
}
|
||||
|
||||
public void PopulateProperties(List<LayerPropertyViewModel> properties)
|
||||
@@ -51,5 +59,22 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
|
||||
{
|
||||
PropertyTrackViewModels.Clear();
|
||||
}
|
||||
|
||||
public void UpdateKeyframePositions()
|
||||
{
|
||||
foreach (var viewModel in PropertyTrackViewModels)
|
||||
viewModel.UpdateKeyframes(LayerPropertiesViewModel.PixelsPerSecond);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the time line's keyframes
|
||||
/// </summary>
|
||||
public void Update()
|
||||
{
|
||||
foreach (var viewModel in PropertyTrackViewModels)
|
||||
viewModel.PopulateKeyframes();
|
||||
|
||||
UpdateEndTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
-1
@@ -12,7 +12,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
|
||||
KeyframeViewModels = new BindableCollection<PropertyTrackKeyframeViewModel>();
|
||||
|
||||
PopulateKeyframes();
|
||||
UpdateKeyframes(propertyTimelineViewModel.LayerPropertiesViewModel.PixelsPerSecond);
|
||||
UpdateKeyframes(PropertyTimelineViewModel.LayerPropertiesViewModel.PixelsPerSecond);
|
||||
}
|
||||
|
||||
public PropertyTimelineViewModel PropertyTimelineViewModel { get; }
|
||||
@@ -21,12 +21,22 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
|
||||
|
||||
public void PopulateKeyframes()
|
||||
{
|
||||
// Remove old keyframes
|
||||
foreach (var viewModel in KeyframeViewModels.ToList())
|
||||
{
|
||||
if (!LayerPropertyViewModel.LayerProperty.UntypedKeyframes.Contains(viewModel.Keyframe))
|
||||
KeyframeViewModels.Remove(viewModel);
|
||||
}
|
||||
|
||||
// Add new keyframes
|
||||
foreach (var keyframe in LayerPropertyViewModel.LayerProperty.UntypedKeyframes)
|
||||
{
|
||||
if (KeyframeViewModels.Any(k => k.Keyframe == keyframe))
|
||||
continue;
|
||||
KeyframeViewModels.Add(new PropertyTrackKeyframeViewModel(keyframe));
|
||||
}
|
||||
|
||||
UpdateKeyframes(PropertyTimelineViewModel.LayerPropertiesViewModel.PixelsPerSecond);
|
||||
}
|
||||
|
||||
public void UpdateKeyframes(int pixelsPerSecond)
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
<!-- The part of the layer's shape that is inside the layer -->
|
||||
<Path Data="{Binding ShapeGeometry, Mode=OneWay}">
|
||||
<Path.Fill>
|
||||
<SolidColorBrush Color="{StaticResource Accent700}" Opacity="0.35" />
|
||||
<SolidColorBrush Color="{StaticResource Accent700}" Opacity="0.25" />
|
||||
</Path.Fill>
|
||||
<Path.Stroke>
|
||||
<SolidColorBrush Color="{StaticResource Accent700}" />
|
||||
|
||||
@@ -24,8 +24,10 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
Update();
|
||||
Layer.RenderPropertiesUpdated += LayerOnRenderPropertiesUpdated;
|
||||
_profileEditorService.SelectedProfileElementChanged += OnSelectedProfileElementChanged;
|
||||
_profileEditorService.SelectedProfileElementUpdated += OnSelectedProfileElementUpdated;
|
||||
_profileEditorService.CurrentTimeChanged += ProfileEditorServiceOnCurrentTimeChanged;
|
||||
}
|
||||
|
||||
|
||||
public Layer Layer { get; }
|
||||
|
||||
public Geometry LayerGeometry { get; set; }
|
||||
@@ -119,8 +121,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
shapeGeometry.Freeze();
|
||||
ShapeGeometry = shapeGeometry;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void CreateViewportRectangle()
|
||||
{
|
||||
if (!Layer.Leds.Any() || Layer.LayerShape == null)
|
||||
@@ -190,6 +191,20 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
IsSelected = _profileEditorService.SelectedProfileElement == Layer;
|
||||
}
|
||||
|
||||
private void OnSelectedProfileElementUpdated(object sender, EventArgs e)
|
||||
{
|
||||
if (IsSelected)
|
||||
Update();
|
||||
}
|
||||
|
||||
private void ProfileEditorServiceOnCurrentTimeChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (!IsSelected)
|
||||
return;
|
||||
CreateShapeGeometry();
|
||||
CreateViewportRectangle();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Layer.RenderPropertiesUpdated -= LayerOnRenderPropertiesUpdated;
|
||||
|
||||
Reference in new issue
Block a user