Profile editor - Only save profile on drag-edit when mouse is released

Profile editor - Format all numbers with 3 decimals 
Profile editor - Fixed drag-edit rounding errors with very small steps
Logging - Output logs to debug
Settings - Added logging level setting
Nuget - Updated Serilog and the used sinks
This commit is contained in:
Robert committed 2020-02-19 17:17:35 +01:00
1 parent 05cf1f0b53
commit 318a679744
26 files changed
+323 -161

No files matched your search

@@ -9,11 +9,11 @@
d:DesignHeight="25"
d:DesignWidth="800"
d:DataContext="{d:DesignInstance local:PropertyTimelineViewModel}">
<Canvas Background="{DynamicResource MaterialDesignToolBarBackground}"
<Grid Background="{DynamicResource MaterialDesignToolBarBackground}"
MouseDown="{s:Action TimelineCanvasMouseDown}"
MouseUp="{s:Action TimelineCanvasMouseUp}"
MouseMove="{s:Action TimelineCanvasMouseMove}">
<Canvas.Triggers>
<Grid.Triggers>
<EventTrigger RoutedEvent="UIElement.MouseLeftButtonDown">
<BeginStoryboard>
<Storyboard Storyboard.TargetName="MultiSelectionPath" Storyboard.TargetProperty="Opacity">
@@ -28,7 +28,7 @@
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
</Grid.Triggers>
<ItemsControl ItemsSource="{Binding PropertyTrackViewModels}"
Width="{Binding Width}"
@@ -51,5 +51,5 @@
<SolidColorBrush Color="{DynamicResource Primary400}" Opacity="0.25" />
</Path.Fill>
</Path>
</Canvas>
</Grid>
</UserControl>
@@ -7,6 +7,7 @@ using System.Windows.Media;
using System.Windows.Shapes;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Services.Interfaces;
using Artemis.UI.Utilities;
using Stylet;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
@@ -95,26 +96,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
UpdateEndTime();
}
#region Keyframe movement
public void MoveSelectedKeyframes(TimeSpan offset)
{
var keyframeViewModels = PropertyTrackViewModels.SelectMany(t => t.KeyframeViewModels.OrderBy(k => k.Keyframe.Position)).ToList();
foreach (var keyframeViewModel in keyframeViewModels.Where(k => k.IsSelected))
{
// TODO: Not ideal as this stacks them all if they get to 0, oh well
if (keyframeViewModel.Keyframe.Position + offset > TimeSpan.Zero)
{
keyframeViewModel.Keyframe.Position += offset;
keyframeViewModel.Update(LayerPropertiesViewModel.PixelsPerSecond);
}
}
_profileEditorService.UpdateProfilePreview();
}
#endregion
private void CreateViewModels(LayerPropertyViewModel property)
{
PropertyTrackViewModels.Add(_propertyTrackVmFactory.Create(this, property));
@@ -122,6 +103,30 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
CreateViewModels(child);
}
#region Keyframe movement
public void MoveSelectedKeyframes(TimeSpan cursorTime)
{
// Ensure the selection rectangle doesn't show, the view isn't aware of different types of dragging
SelectionRectangle.Rect = new Rect();
var keyframeViewModels = PropertyTrackViewModels.SelectMany(t => t.KeyframeViewModels.OrderBy(k => k.Keyframe.Position)).ToList();
foreach (var keyframeViewModel in keyframeViewModels.Where(k => k.IsSelected))
keyframeViewModel.ApplyMovement(cursorTime);
_profileEditorService.UpdateProfilePreview();
}
public void ReleaseSelectedKeyframes()
{
var keyframeViewModels = PropertyTrackViewModels.SelectMany(t => t.KeyframeViewModels.OrderBy(k => k.Keyframe.Position)).ToList();
foreach (var keyframeViewModel in keyframeViewModels.Where(k => k.IsSelected))
keyframeViewModel.ReleaseMovement();
}
#endregion
#region Keyframe selection
private Point _mouseDragStartPoint;
@@ -130,6 +135,9 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
// ReSharper disable once UnusedMember.Global - Called from view
public void TimelineCanvasMouseDown(object sender, MouseButtonEventArgs e)
{
if (e.LeftButton == MouseButtonState.Released)
return;
((IInputElement) sender).CaptureMouse();
SelectionRectangle.Rect = new Rect();
@@ -148,18 +156,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
var selectedRect = new Rect(_mouseDragStartPoint, position);
SelectionRectangle.Rect = selectedRect;
// Find all keyframes in the rectangle
var selectedKeyframes = new List<PropertyTrackKeyframeViewModel>();
var hitTestParams = new GeometryHitTestParameters(SelectionRectangle);
var resultCallback = new HitTestResultCallback(result => HitTestResultBehavior.Continue);
var filterCallback = new HitTestFilterCallback(element =>
{
if (element is Ellipse ellipse)
selectedKeyframes.Add((PropertyTrackKeyframeViewModel) ellipse.DataContext);
return HitTestFilterBehavior.Continue;
});
VisualTreeHelper.HitTest((Visual) sender, filterCallback, resultCallback, hitTestParams);
var selectedKeyframes = HitTestUtilities.GetHitViewModels<PropertyTrackKeyframeViewModel>((Visual) sender, SelectionRectangle);
var keyframeViewModels = PropertyTrackViewModels.SelectMany(t => t.KeyframeViewModels.OrderBy(k => k.Keyframe.Position)).ToList();
foreach (var keyframeViewModel in keyframeViewModels)
keyframeViewModel.IsSelected = selectedKeyframes.Contains(keyframeViewModel);
@@ -49,7 +49,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
if (e.LeftButton == MouseButtonState.Released)
return;
((IInputElement)sender).CaptureMouse();
((IInputElement) sender).CaptureMouse();
if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift) && !IsSelected)
PropertyTrackViewModel.PropertyTimelineViewModel.SelectKeyframe(this, true, false);
else if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
@@ -63,42 +63,45 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
public void KeyframeMouseUp(object sender, MouseButtonEventArgs e)
{
_profileEditorService.UpdateSelectedProfileElement();
PropertyTrackViewModel.PropertyTimelineViewModel.ReleaseSelectedKeyframes();
((IInputElement)sender).ReleaseMouseCapture();
e.Handled = true;
((IInputElement) sender).ReleaseMouseCapture();
}
public void KeyframeMouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
// Get the parent grid, need that for our position
var x = Math.Max(0, e.GetPosition(ParentView).X);
var newTime = TimeSpan.FromSeconds(x / _pixelsPerSecond);
// Round the time to something that fits the current zoom level
if (_pixelsPerSecond < 200)
newTime = TimeSpan.FromMilliseconds(Math.Round(newTime.TotalMilliseconds / 5.0) * 5.0);
else if (_pixelsPerSecond < 500)
newTime = TimeSpan.FromMilliseconds(Math.Round(newTime.TotalMilliseconds / 2.0) * 2.0);
else
newTime = TimeSpan.FromMilliseconds(Math.Round(newTime.TotalMilliseconds));
// If shift is held, snap to the current time
// Take a tolerance of 5 pixels (half a keyframe width)
if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
{
var tolerance = 1000f / _pixelsPerSecond * 5;
if (Math.Abs(_profileEditorService.CurrentTime.TotalMilliseconds - newTime.TotalMilliseconds) < tolerance)
newTime = _profileEditorService.CurrentTime;
}
PropertyTrackViewModel.PropertyTimelineViewModel.MoveSelectedKeyframes(newTime - Keyframe.Position);
}
PropertyTrackViewModel.PropertyTimelineViewModel.MoveSelectedKeyframes(GetCursorTime(e.GetPosition(ParentView)));
e.Handled = true;
}
private TimeSpan GetCursorTime(Point position)
{
// Get the parent grid, need that for our position
var x = Math.Max(0, position.X);
var time = TimeSpan.FromSeconds(x / _pixelsPerSecond);
// Round the time to something that fits the current zoom level
if (_pixelsPerSecond < 200)
time = TimeSpan.FromMilliseconds(Math.Round(time.TotalMilliseconds / 5.0) * 5.0);
else if (_pixelsPerSecond < 500)
time = TimeSpan.FromMilliseconds(Math.Round(time.TotalMilliseconds / 2.0) * 2.0);
else
time = TimeSpan.FromMilliseconds(Math.Round(time.TotalMilliseconds));
// If shift is held, snap to the current time
// Take a tolerance of 5 pixels (half a keyframe width)
if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
{
var tolerance = 1000f / _pixelsPerSecond * 5;
if (Math.Abs(_profileEditorService.CurrentTime.TotalMilliseconds - time.TotalMilliseconds) < tolerance)
time = _profileEditorService.CurrentTime;
}
return time;
}
#endregion
#region Context menu actions
@@ -137,5 +140,34 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
}
#endregion
#region Movement
private bool _movementReleased = true;
private TimeSpan _startOffset;
public void ApplyMovement(TimeSpan cursorTime)
{
if (_movementReleased)
{
_movementReleased = false;
_startOffset = cursorTime - Keyframe.Position;
}
else
{
Keyframe.Position = cursorTime - _startOffset;
if (Keyframe.Position < TimeSpan.Zero)
Keyframe.Position = TimeSpan.Zero;
Update(_pixelsPerSecond);
}
}
public void ReleaseMovement()
{
_movementReleased = true;
}
#endregion
}
}