diff --git a/src/Artemis.Core/Models/Profile/Layer.cs b/src/Artemis.Core/Models/Profile/Layer.cs index 9b6e44fac..51d3eb32a 100644 --- a/src/Artemis.Core/Models/Profile/Layer.cs +++ b/src/Artemis.Core/Models/Profile/Layer.cs @@ -160,18 +160,22 @@ namespace Artemis.Core.Models.Profile canvas.ClipPath(Path); // Apply transformations - var anchor = AnchorPointProperty.CurrentValue; var position = PositionProperty.CurrentValue; var size = SizeProperty.CurrentValue; var rotation = RotationProperty.CurrentValue; - // Scale the anchor and make it originate from the center of the untranslated layer shape - anchor.X = anchor.X * AbsoluteRectangle.Width + LayerShape.RenderRectangle.MidX; - anchor.Y = anchor.Y * AbsoluteRectangle.Height + LayerShape.RenderRectangle.MidY; - canvas.Translate(position.X * AbsoluteRectangle.Width, position.Y * AbsoluteRectangle.Height); + var anchor = GetLayerAnchor(true); + var relativeAnchor = GetLayerAnchor(false); + + // Translation originates from the unscaled center of the shape and is tied to the anchor + var x = position.X * Rectangle.Width - LayerShape.RenderRectangle.Width / 2 - relativeAnchor.X; + var y = position.Y * Rectangle.Height - LayerShape.RenderRectangle.Height / 2 - relativeAnchor.Y; + + canvas.RotateDegrees(rotation, anchor.X, anchor.Y); canvas.Scale(size.Width, size.Height, anchor.X, anchor.Y); - + canvas.Translate(x, y); + // Placeholder if (LayerShape?.RenderPath != null) { @@ -192,6 +196,22 @@ namespace Artemis.Core.Models.Profile canvas.Restore(); } + private SKPoint GetLayerAnchor(bool absolute) + { + if (!absolute) + { + var anchor = AnchorPointProperty.CurrentValue; + anchor.X = anchor.X * Rectangle.Width; + anchor.Y = anchor.Y * Rectangle.Height; + return new SKPoint(anchor.X, anchor.Y); + } + + var position = PositionProperty.CurrentValue; + position.X = position.X * Rectangle.Width; + position.Y = position.Y * Rectangle.Height; + return new SKPoint(position.X + LayerShape.RenderRectangle.Left, position.Y + LayerShape.RenderRectangle.Top); + } + internal override void ApplyToEntity() { // Properties diff --git a/src/Artemis.Core/Models/Profile/LayerShapes/LayerShape.cs b/src/Artemis.Core/Models/Profile/LayerShapes/LayerShape.cs index 261a5ef4e..78e29f8ef 100644 --- a/src/Artemis.Core/Models/Profile/LayerShapes/LayerShape.cs +++ b/src/Artemis.Core/Models/Profile/LayerShapes/LayerShape.cs @@ -58,10 +58,10 @@ namespace Artemis.Core.Models.Profile.LayerShapes return SKRect.Empty; return SKRect.Create( - Layer.AbsoluteRectangle.Left + Layer.AbsoluteRectangle.Width * ScaledRectangle.Left, - Layer.AbsoluteRectangle.Top + Layer.AbsoluteRectangle.Height * ScaledRectangle.Top, - Layer.AbsoluteRectangle.Width * ScaledRectangle.Width, - Layer.AbsoluteRectangle.Height * ScaledRectangle.Height + Layer.Rectangle.Left + Layer.Rectangle.Width * ScaledRectangle.Left, + Layer.Rectangle.Top + Layer.Rectangle.Height * ScaledRectangle.Top, + Layer.Rectangle.Width * ScaledRectangle.Width, + Layer.Rectangle.Height * ScaledRectangle.Height ); } @@ -75,8 +75,8 @@ namespace Artemis.Core.Models.Profile.LayerShapes } Layer.AnchorPointProperty.SetCurrentValue(new SKPoint( - 100f / Layer.AbsoluteRectangle.Width * (anchor.X - Layer.AbsoluteRectangle.Left - Layer.PositionProperty.CurrentValue.X) / 100f, - 100f / Layer.AbsoluteRectangle.Height * (anchor.Y - Layer.AbsoluteRectangle.Top - Layer.PositionProperty.CurrentValue.Y) / 100f + 100f / Layer.Rectangle.Width * (anchor.X - Layer.Rectangle.Left - Layer.PositionProperty.CurrentValue.X) / 100f, + 100f / Layer.Rectangle.Height * (anchor.Y - Layer.Rectangle.Top - Layer.PositionProperty.CurrentValue.Y) / 100f ), time); CalculateRenderProperties(); } @@ -87,8 +87,8 @@ namespace Artemis.Core.Models.Profile.LayerShapes return SKPoint.Empty; return new SKPoint( - Layer.AbsoluteRectangle.Left + Layer.AbsoluteRectangle.Width * (Layer.AnchorPointProperty.CurrentValue.X + Layer.PositionProperty.CurrentValue.X), - Layer.AbsoluteRectangle.Top + Layer.AbsoluteRectangle.Height * (Layer.AnchorPointProperty.CurrentValue.Y + Layer.PositionProperty.CurrentValue.Y) + Layer.Rectangle.Left + Layer.Rectangle.Width * (Layer.AnchorPointProperty.CurrentValue.X + Layer.PositionProperty.CurrentValue.X), + Layer.Rectangle.Top + Layer.Rectangle.Height * (Layer.AnchorPointProperty.CurrentValue.Y + Layer.PositionProperty.CurrentValue.Y) ); } } diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolView.xaml index 42956448e..b5eac343a 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolView.xaml +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolView.xaml @@ -5,12 +5,13 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools" xmlns:s="https://github.com/canton7/Stylet" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance {x:Type local:EditToolViewModel}}"> - + - + MouseMove="{s:Action Move}" /> @@ -34,11 +34,25 @@ + + Width="8" + Height="8" + Fill="Transparent" + Canvas.Left="{Binding ShapeAnchor.X}" + Canvas.Top="{Binding ShapeAnchor.Y}" + Margin="-4,-4,0,0" + Cursor="SizeAll"> + + @@ -48,45 +62,45 @@ - + @@ -95,62 +109,62 @@ MouseMove="{s:Action TopRightResize}" Width="6" Height="6" - Canvas.Left="{Binding ShapeRectangle.Right}" - Canvas.Top="{Binding ShapeRectangle.Top}" - Fill="Red" - Margin="-3,-3,0,0" + Canvas.Left="{Binding ShapeRectangle.Right}" + Canvas.Top="{Binding ShapeRectangle.Top}" + Fill="Transparent" + Margin="-3,-3,0,0" Cursor="SizeNESW" /> - + - + - + - + @@ -167,26 +181,26 @@ MouseUp="{s:Action ShapeEditMouseUp}" MouseMove="{s:Action BottomLeftResize}" Width="6" - Height="6" - Canvas.Left="{Binding ShapeRectangle.Left}" - Canvas.Top="{Binding ShapeRectangle.Bottom}" - Fill="Red" + Height="6" + Canvas.Left="{Binding ShapeRectangle.Left}" + Canvas.Top="{Binding ShapeRectangle.Bottom}" + Fill="Transparent" Margin="-3, -3, 0,0" Cursor="SizeNESW" /> - + - + \ No newline at end of file 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 b98cd4043..6895018df 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolViewModel.cs @@ -16,10 +16,10 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools private readonly ILayerEditorService _layerEditorService; private bool _draggingHorizontally; private bool _draggingVertically; - private double _dragOffsetX; - private double _dragOffsetY; - private Point _dragStart; private bool _isDragging; + private Point _dragStart; + private Point _dragOffset; + private SKPoint _dragStartAnchor; public EditToolViewModel(ProfileViewModel profileViewModel, IProfileEditorService profileEditorService, ILayerEditorService layerEditorService) : base(profileViewModel, profileEditorService) @@ -38,6 +38,15 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools public RectangleGeometry ShapeGeometry { get; set; } public TransformCollection ShapeTransformCollection { get; set; } + public SKPoint TopLeft { get; set; } + public SKPoint TopRight { get; set; } + public SKPoint BottomRight { get; set; } + public SKPoint BottomLeft { get; set; } + public SKPoint TopCenter { get; set; } + public SKPoint RightCenter { get; set; } + public SKPoint BottomCenter { get; set; } + public SKPoint LeftCenter { get; set; } + private void Update() { if (ProfileEditorService.SelectedProfileElement is Layer layer) @@ -71,27 +80,18 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools } } - public SKPoint TopLeft { get; set; } - public SKPoint TopRight { get; set; } - public SKPoint BottomRight { get; set; } - public SKPoint BottomLeft { get; set; } - public SKPoint TopCenter { get; set; } - public SKPoint RightCenter { get; set; } - public SKPoint BottomCenter { get; set; } - public SKPoint LeftCenter { get; set; } - public void ShapeEditMouseDown(object sender, MouseButtonEventArgs e) { if (_isDragging) return; - ((IInputElement) sender).CaptureMouse(); if (ProfileEditorService.SelectedProfileElement is Layer layer) { + // The path starts at 0,0 so there's no simple way to get the position relative to the top-left of the path var dragStartPosition = GetRelativePosition(sender, e); - var skRect = layer.LayerShape.RenderRectangle; - _dragOffsetX = skRect.Left - dragStartPosition.X; - _dragOffsetY = skRect.Top - dragStartPosition.Y; + var anchor = _layerEditorService.GetLayerAnchor(layer, true); + + _dragOffset = new Point(dragStartPosition.X - anchor.X - 1.45, dragStartPosition.Y - anchor.Y - 1.45); _dragStart = dragStartPosition; } @@ -99,21 +99,31 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools _draggingHorizontally = false; _draggingVertically = false; + ((IInputElement) sender).CaptureMouse(); e.Handled = true; } - + public void AnchorEditMouseDown(object sender, MouseButtonEventArgs e) { if (_isDragging) return; - // Use the regular mousedown - ShapeEditMouseDown(sender, e); - // Override the drag offset - var dragStartPosition = GetRelativePosition(sender, e); -// _dragOffsetX = AnchorSkPoint.X - dragStartPosition.X; -// _dragOffsetY = AnchorSkPoint.Y - dragStartPosition.Y; - _dragStart = dragStartPosition; + if (ProfileEditorService.SelectedProfileElement is Layer layer) + { + // The path starts at 0,0 so there's no simple way to get the position relative to the top-left of the path + var dragStartPosition = GetRelativePosition(sender, e); + + _dragOffset = new Point(TopLeft.X + (dragStartPosition.X - TopLeft.X), TopLeft.Y + (dragStartPosition.Y - TopLeft.Y)); + _dragStartAnchor = _layerEditorService.GetLayerAnchor(layer, false); + _dragStart = dragStartPosition; + } + + _isDragging = true; + _draggingHorizontally = false; + _draggingVertically = false; + + ((IInputElement) sender).CaptureMouse(); + e.Handled = true; } public void ShapeEditMouseUp(object sender, MouseButtonEventArgs e) @@ -134,9 +144,19 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools return; var position = GetRelativePosition(sender, e); - var x = (float) (position.X + _dragOffsetX); - var y = (float) (position.Y + _dragOffsetY); - layer.LayerShape.SetFromUnscaledAnchor(new SKPoint(x, y), ProfileEditorService.CurrentTime); + var x = (float)(position.X - _dragOffset.X + _dragStartAnchor.X); + var y = (float)(position.Y - _dragOffset.Y + _dragStartAnchor.Y); + + // Convert the desired X and Y position to a translation + var scaled = _layerEditorService.GetScaledPoint(layer, new SKPoint(x, y), false); + var currentAnchor = layer.AnchorPointProperty.CurrentValue; + var currentPos = layer.PositionProperty.CurrentValue; + + layer.AnchorPointProperty.SetCurrentValue(scaled, ProfileEditorService.CurrentTime); + + var positionOffsetX = (scaled.X - currentAnchor.X) * layer.SizeProperty.CurrentValue.Width; + var positionOffsetY = (scaled.Y - currentAnchor.Y) * layer.SizeProperty.CurrentValue.Height; + layer.PositionProperty.SetCurrentValue(new SKPoint(currentPos.X + positionOffsetX, currentPos.Y + positionOffsetY), ProfileEditorService.CurrentTime); ProfileEditorService.UpdateProfilePreview(); } @@ -146,16 +166,15 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools return; var position = GetRelativePosition(sender, e); - var skRect = _layerEditorService.GetShapeRenderRect(layer.LayerShape).ToSKRect(); - var x = (float) (position.X + _dragOffsetX); - var y = (float) (position.Y + _dragOffsetY); + var x = (float) (position.X - _dragOffset.X); + var y = (float) (position.Y - _dragOffset.Y); if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)) { if (_draggingVertically) - x = skRect.Left; + x = (float) (_dragStart.X - _dragOffset.X); else if (_draggingHorizontally) - y = skRect.Top; + y = (float) (_dragStart.Y - _dragOffset.Y); else { _draggingHorizontally = Math.Abs(position.X - _dragStart.X) > Math.Abs(position.Y - _dragStart.Y); @@ -164,11 +183,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools } } - // Convert the desired X and Y position to a translation - var layerRect = _layerEditorService.GetLayerRenderRect(layer).ToSKRect(); - var translation = layer.PositionProperty.CurrentValue; - var scaled = _layerEditorService.GetScaledPoint(layer, new SKPoint(x , y)); - Console.WriteLine(scaled); + var scaled = _layerEditorService.GetScaledPoint(layer, new SKPoint(x, y), true); layer.PositionProperty.SetCurrentValue(scaled, ProfileEditorService.CurrentTime); ProfileEditorService.UpdateProfilePreview(); diff --git a/src/Artemis.UI/Screens/Shared/PanZoomViewModel.cs b/src/Artemis.UI/Screens/Shared/PanZoomViewModel.cs index 45cc0ee60..f21832154 100644 --- a/src/Artemis.UI/Screens/Shared/PanZoomViewModel.cs +++ b/src/Artemis.UI/Screens/Shared/PanZoomViewModel.cs @@ -44,8 +44,16 @@ namespace Artemis.UI.Screens.Shared Zoom = Math.Max(0.1, Math.Min(4, Zoom)); // Update the PanX/Y to enable zooming relative to cursor - PanX = Math.Min(0, absoluteX - relative.X * Zoom); - PanY = Math.Min(0, absoluteY - relative.Y * Zoom); + if (LimitToZero) + { + PanX = Math.Min(0, absoluteX - relative.X * Zoom); + PanY = Math.Min(0, absoluteY - relative.Y * Zoom); + } + else + { + PanX = absoluteX - relative.X * Zoom; + PanY = absoluteY - relative.Y * Zoom; + } } public void ProcessMouseMove(object sender, MouseEventArgs e) diff --git a/src/Artemis.UI/Services/LayerShapeService.cs b/src/Artemis.UI/Services/LayerShapeService.cs index 06baf9529..ef7c9f3e5 100644 --- a/src/Artemis.UI/Services/LayerShapeService.cs +++ b/src/Artemis.UI/Services/LayerShapeService.cs @@ -33,6 +33,18 @@ namespace Artemis.UI.Services ); } + public Rect GetLayerRect(Layer layer) + { + // Adjust the render rectangle for the difference in render scale + var renderScale = _settingsService.GetSetting("Core.RenderScale", 1.0).Value; + return new Rect( + layer.Rectangle.Left / renderScale * 1, + layer.Rectangle.Top / renderScale * 1, + Math.Max(0, layer.Rectangle.Width / renderScale * 1), + Math.Max(0, layer.Rectangle.Height / renderScale * 1) + ); + } + /// public SKPath GetLayerPath(Layer layer) { @@ -40,57 +52,93 @@ namespace Artemis.UI.Services var shapeRect = GetShapeRenderRect(layer.LayerShape).ToSKRect(); // Apply transformation like done by the core during layer rendering - var anchor = GetLayerAnchor(layer, false); - var position = layer.PositionProperty.CurrentValue; - var size = layer.SizeProperty.CurrentValue; - var rotation = layer.RotationProperty.CurrentValue; + var anchor = GetLayerAnchor(layer, true); + var relativeAnchor = GetLayerAnchor(layer, false); + + // Translation originates from the unscaled center of the shape and is tied to the anchor + var x = layer.PositionProperty.CurrentValue.X * layerRect.Width - shapeRect.Width / 2 - relativeAnchor.X; + var y = layer.PositionProperty.CurrentValue.Y * layerRect.Height - shapeRect.Height / 2 - relativeAnchor.Y; var path = new SKPath(); path.AddRect(shapeRect); - - path.Transform(SKMatrix.MakeScale(size.Width, size.Height, anchor.X, anchor.Y)); - path.Transform(SKMatrix.MakeRotationDegrees(rotation, anchor.X, anchor.Y)); - path.Transform(SKMatrix.MakeTranslation(position.X * layerRect.Width, position.Y * layerRect.Height)); + path.Transform(SKMatrix.MakeTranslation(x, y)); + path.Transform(SKMatrix.MakeScale(layer.SizeProperty.CurrentValue.Width, layer.SizeProperty.CurrentValue.Height, anchor.X, anchor.Y)); + path.Transform(SKMatrix.MakeRotationDegrees(layer.RotationProperty.CurrentValue, anchor.X, anchor.Y)); return path; } - /// - public SKPoint GetLayerAnchor(Layer layer, bool includeTranslate) + public void ReverseLayerPath(Layer layer, SKPath path) { var layerRect = GetLayerRenderRect(layer).ToSKRect(); var shapeRect = GetShapeRenderRect(layer.LayerShape).ToSKRect(); - var anchor = layer.AnchorPointProperty.CurrentValue; - // Scale the anchor and make it originate from the center of the untranslated layer shape - anchor.X = anchor.X * layerRect.Width + shapeRect.MidX; - anchor.Y = anchor.Y * layerRect.Height + shapeRect.MidY; + // Apply transformation like done by the core during layer rendering + var anchor = GetLayerAnchor(layer, true); + var relativeAnchor = GetLayerAnchor(layer, false); - if (includeTranslate) + // Translation originates from the unscaled center of the shape and is tied to the anchor + var x = layer.PositionProperty.CurrentValue.X * layerRect.Width - shapeRect.Width / 2 - relativeAnchor.X; + var y = layer.PositionProperty.CurrentValue.Y * layerRect.Height - shapeRect.Height / 2 - relativeAnchor.Y; + + SKMatrix.MakeScale(layer.SizeProperty.CurrentValue.Width, layer.SizeProperty.CurrentValue.Height, anchor.X, anchor.Y).TryInvert(out var scale); + + path.Transform(SKMatrix.MakeRotationDegrees(layer.RotationProperty.CurrentValue * -1, anchor.X, anchor.Y)); + path.Transform(scale); + path.Transform(SKMatrix.MakeTranslation(x * -1, y * -1)); + } + + /// + public SKPoint GetLayerAnchor(Layer layer, bool absolute) + { + var layerRect = GetLayerRect(layer); + if (absolute) { var position = layer.PositionProperty.CurrentValue; - anchor.X += position.X * layerRect.Width; - anchor.Y += position.Y * layerRect.Height; + position.X = (float) (position.X * layerRect.Width); + position.Y = (float) (position.Y * layerRect.Height); + var shapeRect = GetShapeRenderRect(layer.LayerShape); + return new SKPoint((float) (position.X + shapeRect.Left), (float) (position.Y + shapeRect.Top)); } - return anchor; + var anchor = layer.AnchorPointProperty.CurrentValue; + anchor.X = (float) (anchor.X * layerRect.Width); + anchor.Y = (float) (anchor.Y * layerRect.Height); + return new SKPoint(anchor.X, anchor.Y); + } + + public void SetLayerAnchor(Layer layer, SKPoint point, bool absolute, TimeSpan? time) + { + var layerRect = GetLayerRect(layer); + if (absolute) + { + var shapeRect = GetShapeRenderRect(layer.LayerShape); + var position = new SKPoint((float) ((point.X - shapeRect.Left) / layerRect.Width), (float) ((point.Y - shapeRect.Top) / layerRect.Height)); + layer.PositionProperty.SetCurrentValue(position, time); + } + + var anchor = new SKPoint((float) (point.X / layerRect.Width), (float) (point.Y / layerRect.Height)); + layer.AnchorPointProperty.SetCurrentValue(anchor, time); } /// public TransformGroup GetLayerTransformGroup(Layer layer) { var layerRect = GetLayerRenderRect(layer).ToSKRect(); + var shapeRect = GetShapeRenderRect(layer.LayerShape).ToSKRect(); // Apply transformation like done by the core during layer rendering - var anchor = GetLayerAnchor(layer, false); - var position = layer.PositionProperty.CurrentValue; - var size = layer.SizeProperty.CurrentValue; - var rotation = layer.RotationProperty.CurrentValue; + var anchor = GetLayerAnchor(layer, true); + + // Translation originates from the unscaled center of the shape and is tied to the anchor + var x = layer.PositionProperty.CurrentValue.X * layerRect.Width - shapeRect.Width / 2 - GetLayerAnchor(layer, false).X; + var y = layer.PositionProperty.CurrentValue.Y * layerRect.Height - shapeRect.Height / 2 - GetLayerAnchor(layer, false).Y; var transformGroup = new TransformGroup(); - transformGroup.Children.Add(new ScaleTransform(size.Width, size.Height, anchor.X, anchor.Y)); - transformGroup.Children.Add(new RotateTransform(rotation, anchor.X, anchor.Y)); - transformGroup.Children.Add(new TranslateTransform(position.X * layerRect.Width, position.Y * layerRect.Height)); + transformGroup.Children.Add(new TranslateTransform(x, y)); + transformGroup.Children.Add(new ScaleTransform(layer.SizeProperty.CurrentValue.Width, layer.SizeProperty.CurrentValue.Height, anchor.X, anchor.Y)); + transformGroup.Children.Add(new RotateTransform(layer.RotationProperty.CurrentValue, anchor.X, anchor.Y)); + return transformGroup; } @@ -119,23 +167,29 @@ namespace Artemis.UI.Services // Adjust the provided rect for the difference in render scale var renderScale = _settingsService.GetSetting("Core.RenderScale", 1.0).Value; layerShape.ScaledRectangle = SKRect.Create( - 100f / layerShape.Layer.AbsoluteRectangle.Width * ((float) (rect.Left * renderScale) - layerShape.Layer.AbsoluteRectangle.Left) / 100f, - 100f / layerShape.Layer.AbsoluteRectangle.Height * ((float) (rect.Top * renderScale) - layerShape.Layer.AbsoluteRectangle.Top) / 100f, - 100f / layerShape.Layer.AbsoluteRectangle.Width * (float) (rect.Width * renderScale) / 100f, - 100f / layerShape.Layer.AbsoluteRectangle.Height * (float) (rect.Height * renderScale) / 100f + 100f / layerShape.Layer.Rectangle.Width * ((float) (rect.Left * renderScale) - layerShape.Layer.Rectangle.Left) / 100f, + 100f / layerShape.Layer.Rectangle.Height * ((float) (rect.Top * renderScale) - layerShape.Layer.Rectangle.Top) / 100f, + 100f / layerShape.Layer.Rectangle.Width * (float) (rect.Width * renderScale) / 100f, + 100f / layerShape.Layer.Rectangle.Height * (float) (rect.Height * renderScale) / 100f ); layerShape.CalculateRenderProperties(); } /// - public SKPoint GetScaledPoint(Layer layer, SKPoint point) + public SKPoint GetScaledPoint(Layer layer, SKPoint point, bool absolute) { - var rect = GetLayerRenderRect(layer).ToSKRect(); - // Adjust the provided rect for the difference in render scale var renderScale = _settingsService.GetSetting("Core.RenderScale", 1.0).Value; + if (absolute) + { + return new SKPoint( + 100f / layer.Rectangle.Width * ((float) (point.X * renderScale) - layer.Rectangle.Left) / 100f, + 100f / layer.Rectangle.Height * ((float) (point.Y * renderScale) - layer.Rectangle.Top) / 100f + ); + } + return new SKPoint( - 100f / layer.AbsoluteRectangle.Width * ((float) (point.X * renderScale) - rect.Left) / 100f, - 100f / layer.AbsoluteRectangle.Height * ((float) (point.Y * renderScale) - rect.Top) / 100f + 100f / layer.Rectangle.Width * (float)(point.X * renderScale) / 100f, + 100f / layer.Rectangle.Height * (float)(point.Y * renderScale) / 100f ); } } @@ -156,13 +210,17 @@ namespace Artemis.UI.Services /// SKPath GetLayerPath(Layer layer); + void ReverseLayerPath(Layer layer, SKPath path); + /// /// Returns an absolute and scaled anchor for the given layer, optionally with the translation applied. /// /// - /// + /// /// - SKPoint GetLayerAnchor(Layer layer, bool includeTranslate); + SKPoint GetLayerAnchor(Layer layer, bool absolute); + + void SetLayerAnchor(Layer layer, SKPoint point, bool absolute, TimeSpan? time); /// /// Creates a WPF transform group that contains all the transformations required to render the provided layer. @@ -191,7 +249,8 @@ namespace Artemis.UI.Services /// /// /// + /// /// - SKPoint GetScaledPoint(Layer layer, SKPoint point); + SKPoint GetScaledPoint(Layer layer, SKPoint point, bool absolute); } } \ No newline at end of file