diff --git a/src/Artemis.Core/Models/Profile/Layer.cs b/src/Artemis.Core/Models/Profile/Layer.cs
index a34d7a40a..089379fc2 100644
--- a/src/Artemis.Core/Models/Profile/Layer.cs
+++ b/src/Artemis.Core/Models/Profile/Layer.cs
@@ -1,4 +1,5 @@
-using System;
+
+using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
@@ -156,11 +157,18 @@ namespace Artemis.Core.Models.Profile
public override void Update(double deltaTime)
{
foreach (var property in Properties)
- {
property.KeyframeEngine?.Update(deltaTime);
- // This is a placeholder method of repeating the animation until repeat modes are implemented
- if (property.KeyframeEngine != null && property.IsUsingKeyframes && property.KeyframeEngine.NextKeyframe == null)
- property.KeyframeEngine.OverrideProgress(TimeSpan.Zero);
+
+ // For now, reset all keyframe engines after the last keyframe was hit
+ // This is a placeholder method of repeating the animation until repeat modes are implemented
+ var lastKeyframe = Properties.SelectMany(p => p.UntypedKeyframes).OrderByDescending(t => t.Position).FirstOrDefault();
+ if (lastKeyframe != null)
+ {
+ if (Properties.Any(p => p.KeyframeEngine?.Progress > lastKeyframe.Position))
+ {
+ foreach (var baseLayerProperty in Properties)
+ baseLayerProperty.KeyframeEngine?.OverrideProgress(TimeSpan.Zero);
+ }
}
LayerBrush?.Update(deltaTime);
diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj
index 4394e7bc9..07ef904df 100644
--- a/src/Artemis.UI/Artemis.UI.csproj
+++ b/src/Artemis.UI/Artemis.UI.csproj
@@ -216,7 +216,7 @@
-
+
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerView.xaml
index 589442a93..7d0d287d0 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerView.xaml
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerView.xaml
@@ -16,7 +16,7 @@
-
+
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerViewModel.cs
index a7d931ed4..3a98d529b 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerViewModel.cs
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerViewModel.cs
@@ -190,14 +190,11 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
private void OnSelectedProfileElementUpdated(object sender, EventArgs e)
{
- if (IsSelected)
- Update();
+ Update();
}
private void ProfileEditorServiceOnProfilePreviewUpdated(object sender, EventArgs e)
{
- if (!IsSelected)
- return;
CreateShapeGeometry();
CreateViewportRectangle();
}
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolViewModel.cs
index fa01bd363..72b88ddeb 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolViewModel.cs
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolViewModel.cs
@@ -3,6 +3,7 @@ using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using Artemis.Core.Models.Profile;
+using Artemis.Core.Models.Profile.LayerProperties;
using Artemis.UI.Events;
using Artemis.UI.Services.Interfaces;
using SkiaSharp;
@@ -16,7 +17,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
private readonly ILayerEditorService _layerEditorService;
private SKPoint _dragOffset;
private SKPoint _dragStart;
- private SKSize _dragStartScale;
private SKPoint _topLeft;
public EditToolViewModel(ProfileViewModel profileViewModel, IProfileEditorService profileEditorService, ILayerEditorService layerEditorService)
@@ -112,33 +112,24 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
#region Size
private bool _isResizing;
+ private SKSize _dragStartScale;
public void ResizeMouseDown(object sender, ShapeControlEventArgs e)
{
if (_isResizing || !(ProfileEditorService.SelectedProfileElement is Layer layer))
return;
- // The path starts at 0,0 so there's no simple way to get the position relative to the top-left of the path
- _dragStart = GetRelativePosition(sender, e.MouseEventArgs).ToSKPoint();
+ var dragStart = GetRelativePosition(sender, e.MouseEventArgs).ToSKPoint();
+ _dragOffset = _layerEditorService.GetDragOffset(layer, dragStart);
+ _dragStart = dragStart + _dragOffset;
_dragStartScale = layer.ScaleProperty.CurrentValue;
- // Store the original position and do a test to figure out the mouse offset
- var originalPosition = layer.PositionProperty.CurrentValue;
- var scaledDragStart = _layerEditorService.GetScaledPoint(layer, _dragStart, true);
- layer.PositionProperty.SetCurrentValue(scaledDragStart, ProfileEditorService.CurrentTime);
-
- // TopLeft is not updated yet and acts as a snapshot of the top-left before changing the position
- // GetLayerPath will return the updated position with all transformations applied, the difference is the offset
- _dragOffset = _topLeft - _layerEditorService.GetLayerPath(layer, true, true, true).Points[0];
- _dragStart += _dragOffset;
-
- // Restore the position back to before the test was done
- layer.PositionProperty.SetCurrentValue(originalPosition, ProfileEditorService.CurrentTime);
_isResizing = true;
}
public void ResizeMouseUp(object sender, ShapeControlEventArgs e)
{
+ ProfileEditorService.UpdateSelectedProfileElement();
_isResizing = false;
}
@@ -248,23 +239,9 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
if (e.ShapeControlPoint == ShapeControlPoint.LayerShape)
{
- // The path starts at 0,0 so there's no simple way to get the position relative to the top-left of the path
- _dragStart = GetRelativePosition(sender, e.MouseEventArgs).ToSKPoint();
- _dragStartScale = layer.ScaleProperty.CurrentValue;
-
- // Store the original position and do a test to figure out the mouse offset
- var originalPosition = layer.PositionProperty.CurrentValue;
- var scaledDragStart = _layerEditorService.GetScaledPoint(layer, _dragStart, true);
- layer.PositionProperty.SetCurrentValue(scaledDragStart, ProfileEditorService.CurrentTime);
-
- // TopLeft is not updated yet and acts as a snapshot of the top-left before changing the position
- // GetLayerPath will return the updated position with all transformations applied, the difference is the offset
- _dragOffset = _topLeft - _layerEditorService.GetLayerPath(layer, true, true, true).Points[0];
- _dragStart += _dragOffset;
-
- // Restore the position back to before the test was done
- layer.PositionProperty.SetCurrentValue(originalPosition, ProfileEditorService.CurrentTime);
-
+ var dragStart = GetRelativePosition(sender, e.MouseEventArgs).ToSKPoint();
+ _dragOffset = _layerEditorService.GetDragOffset(layer, dragStart);
+ _dragStart = dragStart + _dragOffset;
_movingShape = true;
}
else if (e.ShapeControlPoint == ShapeControlPoint.Anchor)
@@ -287,6 +264,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
public void MoveMouseUp(object sender, ShapeControlEventArgs e)
{
+ ProfileEditorService.UpdateSelectedProfileElement();
_movingShape = false;
_movingAnchor = false;
}
@@ -393,8 +371,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
{
var layerBounds = _layerEditorService.GetLayerBounds(layer);
var start = _layerEditorService.GetLayerAnchorPosition(layer);
- start.X += layerBounds.Left;
- start.Y += layerBounds.Top;
var arrival = GetRelativePosition(mouseEventSender, mouseEvent);
var radian = (float) Math.Atan2(start.Y - arrival.Y, start.X - arrival.X);
diff --git a/src/Artemis.UI/Services/Interfaces/ILayerEditorService.cs b/src/Artemis.UI/Services/Interfaces/ILayerEditorService.cs
index f400a5793..7c426925f 100644
--- a/src/Artemis.UI/Services/Interfaces/ILayerEditorService.cs
+++ b/src/Artemis.UI/Services/Interfaces/ILayerEditorService.cs
@@ -18,8 +18,9 @@ namespace Artemis.UI.Services.Interfaces
/// Returns the layer's anchor, corrected for the current render scale.
///
///
+ ///
///
- Point GetLayerAnchorPosition(Layer layer);
+ Point GetLayerAnchorPosition(Layer layer, SKPoint? positionOverride = null);
///
/// Creates a WPF transform group that contains all the transformations required to render the provided layer.
@@ -36,8 +37,9 @@ namespace Artemis.UI.Services.Interfaces
///
///
///
+ ///
///
- SKPath GetLayerPath(Layer layer, bool includeTranslation, bool includeScale, bool includeRotation);
+ SKPath GetLayerPath(Layer layer, bool includeTranslation, bool includeScale, bool includeRotation, SKPoint? anchorOverride = null);
///
/// Returns a new point scaled to the layer.
@@ -47,5 +49,7 @@ namespace Artemis.UI.Services.Interfaces
///
///
SKPoint GetScaledPoint(Layer layer, SKPoint point, bool absolute);
+
+ SKPoint GetDragOffset(Layer layer, SKPoint dragStart);
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Services/LayerShapeService.cs b/src/Artemis.UI/Services/LayerEditorService.cs
similarity index 83%
rename from src/Artemis.UI/Services/LayerShapeService.cs
rename to src/Artemis.UI/Services/LayerEditorService.cs
index 4ab18b804..8efcaeb13 100644
--- a/src/Artemis.UI/Services/LayerShapeService.cs
+++ b/src/Artemis.UI/Services/LayerEditorService.cs
@@ -32,10 +32,12 @@ namespace Artemis.UI.Services
}
///
- public Point GetLayerAnchorPosition(Layer layer)
+ public Point GetLayerAnchorPosition(Layer layer, SKPoint? positionOverride = null)
{
var layerBounds = GetLayerBounds(layer).ToSKRect();
var positionProperty = layer.PositionProperty.CurrentValue;
+ if (positionOverride != null)
+ positionProperty = positionOverride.Value;
// Start at the center of the shape
var position = new Point(layerBounds.MidX, layerBounds.MidY);
@@ -72,12 +74,15 @@ namespace Artemis.UI.Services
}
///
- public SKPath GetLayerPath(Layer layer, bool includeTranslation, bool includeScale, bool includeRotation)
+ public SKPath GetLayerPath(Layer layer, bool includeTranslation, bool includeScale, bool includeRotation, SKPoint? anchorOverride = null)
{
var layerBounds = GetLayerBounds(layer).ToSKRect();
// Apply transformation like done by the core during layer rendering (same differences apply as in GetLayerTransformGroup)
var anchorPosition = GetLayerAnchorPosition(layer).ToSKPoint();
+ if (anchorOverride != null)
+ anchorPosition = anchorOverride.Value;
+
var anchorProperty = layer.AnchorPointProperty.CurrentValue;
// Translation originates from the unscaled center of the shape and is tied to the anchor
@@ -113,5 +118,19 @@ namespace Artemis.UI.Services
100f / layer.Bounds.Height * (float) (point.Y * renderScale) / 100f
);
}
+
+ public SKPoint GetDragOffset(Layer layer, SKPoint dragStart)
+ {
+ // Figure out what the top left will be if the shape moves to the current cursor position
+ var scaledDragStart = GetScaledPoint(layer, dragStart, true);
+ var tempAnchor = GetLayerAnchorPosition(layer, scaledDragStart).ToSKPoint();
+ var tempTopLeft = GetLayerPath(layer, true, true, true, tempAnchor)[0];
+
+ // Get the shape's position
+ var topLeft = GetLayerPath(layer, true, true, true)[0];
+
+ // The difference between the two is the offset
+ return topLeft - tempTopLeft;
+ }
}
}
\ No newline at end of file