Implemented translations properly on top of the layer shape

This commit is contained in:
Robert committed 2020-01-16 19:20:19 +01:00
1 parent 5069be4af4
commit 58297aa5e4
17 files changed
+300 -168

No files matched your search

@@ -5,9 +5,13 @@ using System.Windows.Media;
using Artemis.Core.Models.Profile;
using Artemis.Core.Models.Profile.LayerShapes;
using Artemis.Core.Models.Surface;
using Artemis.Core.Services;
using Artemis.UI.Extensions;
using Artemis.UI.Services;
using Artemis.UI.Services.Interfaces;
using RGB.NET.Core;
using SkiaSharp.Views.WPF;
using Stylet;
using Rectangle = Artemis.Core.Models.Profile.LayerShapes.Rectangle;
namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
@@ -15,10 +19,12 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
public class ProfileLayerViewModel : CanvasViewModel
{
private readonly IProfileEditorService _profileEditorService;
private readonly ILayerEditorService _layerEditorService;
public ProfileLayerViewModel(Layer layer, IProfileEditorService profileEditorService)
public ProfileLayerViewModel(Layer layer, IProfileEditorService profileEditorService, ILayerEditorService layerEditorService)
{
_profileEditorService = profileEditorService;
_layerEditorService = layerEditorService;
Layer = layer;
Update();
@@ -98,33 +104,31 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
return;
}
var skRect = Layer.LayerShape.GetUnscaledRectangle();
var rect = new Rect(skRect.Left, skRect.Top, Math.Max(0, skRect.Width), Math.Max(0, skRect.Height));
var shapeGeometry = Geometry.Empty;
switch (Layer.LayerShape)
Execute.PostToUIThread(() =>
{
case Ellipse _:
shapeGeometry = new EllipseGeometry(rect);
break;
case Fill _:
shapeGeometry = LayerGeometry;
break;
case Polygon _:
// TODO
shapeGeometry = new RectangleGeometry(rect);
break;
case Rectangle _:
shapeGeometry = new RectangleGeometry(rect);
break;
}
// Apply transformation like done by the core during layer rendering
var anchor = Layer.LayerShape.GetUnscaledAnchor();
shapeGeometry.Transform = new RotateTransform(Layer.RotationProperty.CurrentValue, anchor.X, anchor.Y);
shapeGeometry.Freeze();
ShapeGeometry = shapeGeometry;
var rect = _layerEditorService.GetShapeRenderRect(Layer.LayerShape);
var shapeGeometry = Geometry.Empty;
switch (Layer.LayerShape)
{
case Ellipse _:
shapeGeometry = new EllipseGeometry(rect);
break;
case Fill _:
shapeGeometry = LayerGeometry;
break;
case Polygon _:
// TODO
shapeGeometry = new RectangleGeometry(rect);
break;
case Rectangle _:
shapeGeometry = new RectangleGeometry(rect);
break;
}
shapeGeometry.Transform = _layerEditorService.GetLayerTransformGroup(Layer);
shapeGeometry.Freeze();
ShapeGeometry = shapeGeometry;
});
}
private void CreateViewportRectangle()
@@ -14,6 +14,7 @@ using Artemis.UI.Events;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools;
using Artemis.UI.Screens.Shared;
using Artemis.UI.Services;
using Artemis.UI.Services.Interfaces;
using RGB.NET.Core;
using Stylet;
@@ -23,6 +24,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
public class ProfileViewModel : ProfileEditorPanelViewModel, IHandle<MainWindowFocusChangedEvent>, IHandle<MainWindowKeyEvent>
{
private readonly IProfileEditorService _profileEditorService;
private readonly ILayerEditorService _layerEditorService;
private readonly IProfileLayerViewModelFactory _profileLayerViewModelFactory;
private readonly ISettingsService _settingsService;
private readonly ISurfaceService _surfaceService;
@@ -32,12 +34,14 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
private TimerUpdateTrigger _updateTrigger;
public ProfileViewModel(IProfileEditorService profileEditorService,
ILayerEditorService layerEditorService,
ISurfaceService surfaceService,
ISettingsService settingsService,
IEventAggregator eventAggregator,
IProfileLayerViewModelFactory profileLayerViewModelFactory)
{
_profileEditorService = profileEditorService;
_layerEditorService = layerEditorService;
_surfaceService = surfaceService;
_settingsService = settingsService;
_profileLayerViewModelFactory = profileLayerViewModelFactory;
@@ -246,16 +250,17 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
private void ActivateToolByIndex(int value)
{
// Consider using DI if dependencies start to add up
switch (value)
{
case 0:
ActiveToolViewModel = new ViewpointMoveToolViewModel(this, _profileEditorService);
break;
case 1:
ActiveToolViewModel = new EditToolViewModel(this, _profileEditorService);
ActiveToolViewModel = new EditToolViewModel(this, _profileEditorService, _layerEditorService);
break;
case 2:
ActiveToolViewModel = new SelectionToolViewModel(this, _profileEditorService);
ActiveToolViewModel = new SelectionToolViewModel(this, _profileEditorService, _layerEditorService);
break;
case 3:
ActiveToolViewModel = new SelectionAddToolViewModel(this, _profileEditorService);
@@ -264,10 +269,10 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
ActiveToolViewModel = new SelectionRemoveToolViewModel(this, _profileEditorService);
break;
case 6:
ActiveToolViewModel = new EllipseToolViewModel(this, _profileEditorService);
ActiveToolViewModel = new EllipseToolViewModel(this, _profileEditorService, _layerEditorService);
break;
case 7:
ActiveToolViewModel = new RectangleToolViewModel(this, _profileEditorService);
ActiveToolViewModel = new RectangleToolViewModel(this, _profileEditorService, _layerEditorService);
break;
case 8:
ActiveToolViewModel = new PolygonToolViewModel(this, _profileEditorService);
@@ -10,10 +10,10 @@
d:DesignWidth="800"
d:DataContext="{d:DesignInstance {x:Type local:EditToolViewModel}}">
<Canvas UseLayoutRounding="False">
<Canvas >
<Canvas>
<!-- The rectangle around the shape that allows modification -->
<Canvas.RenderTransform>
<RotateTransform Angle="{Binding RotationAngle}" CenterX="{Binding AnchorSkPoint.X}" CenterY="{Binding AnchorSkPoint.Y}" />
<TransformGroup Children="{Binding LayerTransformChildren}" />
</Canvas.RenderTransform>
<Rectangle Width="{Binding ShapeSkRect.Width}"
Height="{Binding ShapeSkRect.Height}"
@@ -3,13 +3,17 @@ using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using Artemis.Core.Models.Profile;
using Artemis.UI.Services;
using Artemis.UI.Services.Interfaces;
using SkiaSharp;
using SkiaSharp.Views.WPF;
using Stylet;
namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
{
public class EditToolViewModel : VisualizationToolViewModel
{
private readonly ILayerEditorService _layerEditorService;
private bool _draggingHorizontally;
private bool _draggingVertically;
private double _dragOffsetX;
@@ -17,8 +21,10 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
private Point _dragStart;
private bool _isDragging;
public EditToolViewModel(ProfileViewModel profileViewModel, IProfileEditorService profileEditorService) : base(profileViewModel, profileEditorService)
public EditToolViewModel(ProfileViewModel profileViewModel, IProfileEditorService profileEditorService, ILayerEditorService layerEditorService)
: base(profileViewModel, profileEditorService)
{
_layerEditorService = layerEditorService;
Cursor = Cursors.Arrow;
Update();
@@ -29,7 +35,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
public SKRect ShapeSkRect { get; set; }
public SKPoint AnchorSkPoint { get; set; }
public int RotationAngle { get; set; }
public TransformCollection LayerTransformChildren { get; set; }
private void Update()
{
@@ -37,13 +43,14 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
{
if (layer.LayerShape != null)
{
ShapeSkRect = layer.LayerShape.GetUnscaledRectangle();
ShapeSkRect = _layerEditorService.GetShapeRenderRect(layer.LayerShape).ToSKRect();
AnchorSkPoint = layer.LayerShape.GetUnscaledAnchor();
RotationAngle = layer.RotationProperty.CurrentValue;
Execute.PostToUIThread(() => LayerTransformChildren = _layerEditorService.GetLayerTransformGroup(layer).Children);
}
}
}
public void ShapeEditMouseDown(object sender, MouseButtonEventArgs e)
{
if (_isDragging)
@@ -53,7 +60,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
if (ProfileEditorService.SelectedProfileElement is Layer layer)
{
var dragStartPosition = GetRelativePosition(sender, e);
var skRect = layer.LayerShape.GetUnscaledRectangle();
var skRect = layer.LayerShape.RenderRectangle;
_dragOffsetX = skRect.Left - dragStartPosition.X;
_dragOffsetY = skRect.Top - dragStartPosition.Y;
_dragStart = dragStartPosition;
@@ -110,24 +117,25 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
return;
var position = GetRelativePosition(sender, e);
var skRect = layer.LayerShape.GetUnscaledRectangle();
var skRect = layer.LayerShape.RenderRectangle;
var x = (float) (position.X + _dragOffsetX);
var y = (float) (position.Y + _dragOffsetY);
if (!Keyboard.IsKeyDown(Key.LeftShift) && !Keyboard.IsKeyDown(Key.RightShift))
layer.LayerShape.SetFromUnscaledRectangle(SKRect.Create(x, y, skRect.Width, skRect.Height), ProfileEditorService.CurrentTime);
else
{
if (_draggingVertically)
layer.LayerShape.SetFromUnscaledRectangle(SKRect.Create(skRect.Left, y, skRect.Width, skRect.Height), ProfileEditorService.CurrentTime);
else if (_draggingHorizontally)
layer.LayerShape.SetFromUnscaledRectangle(SKRect.Create(x, skRect.Top, skRect.Width, skRect.Height), ProfileEditorService.CurrentTime);
else
{
_draggingHorizontally = Math.Abs(position.X - _dragStart.X) > Math.Abs(position.Y - _dragStart.Y);
_draggingVertically = Math.Abs(position.X - _dragStart.X) < Math.Abs(position.Y - _dragStart.Y);
}
}
// TODO: Update the translation
// if (!Keyboard.IsKeyDown(Key.LeftShift) && !Keyboard.IsKeyDown(Key.RightShift))
// layer.LayerShape.SetFromUnscaledRectangle(SKRect.Create(x, y, skRect.Width, skRect.Height), ProfileEditorService.CurrentTime);
// else
// {
// if (_draggingVertically)
// layer.LayerShape.SetFromUnscaledRectangle(SKRect.Create(skRect.Left, y, skRect.Width, skRect.Height), ProfileEditorService.CurrentTime);
// else if (_draggingHorizontally)
// layer.LayerShape.SetFromUnscaledRectangle(SKRect.Create(x, skRect.Top, skRect.Width, skRect.Height), ProfileEditorService.CurrentTime);
// else
// {
// _draggingHorizontally = Math.Abs(position.X - _dragStart.X) > Math.Abs(position.Y - _dragStart.Y);
// _draggingVertically = Math.Abs(position.X - _dragStart.X) < Math.Abs(position.Y - _dragStart.Y);
// }
// }
ProfileEditorService.UpdateProfilePreview();
}
@@ -142,7 +150,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
return;
var position = GetRelativePosition(sender, e);
var skRect = layer.LayerShape.GetUnscaledRectangle();
var skRect = layer.LayerShape.RenderRectangle;
if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
{
// Take the greatest difference
@@ -164,7 +172,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
var position = GetRelativePosition(sender, e);
var skRect = layer.LayerShape.GetUnscaledRectangle();
var skRect = layer.LayerShape.RenderRectangle;
skRect.Top = (float) Math.Min(position.Y, skRect.Bottom);
ApplyShapeResize(skRect);
}
@@ -179,7 +187,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
return;
var position = GetRelativePosition(sender, e);
var skRect = layer.LayerShape.GetUnscaledRectangle();
var skRect = layer.LayerShape.RenderRectangle;
if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
{
// Take the greatest difference
@@ -201,7 +209,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
var position = GetRelativePosition(sender, e);
var skRect = layer.LayerShape.GetUnscaledRectangle();
var skRect = layer.LayerShape.RenderRectangle;
skRect.Right = (float) Math.Max(position.X, skRect.Left);
ApplyShapeResize(skRect);
}
@@ -216,7 +224,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
return;
var position = GetRelativePosition(sender, e);
var skRect = layer.LayerShape.GetUnscaledRectangle();
var skRect = layer.LayerShape.RenderRectangle;
if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
{
// Take the greatest difference
@@ -238,7 +246,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
var position = GetRelativePosition(sender, e);
var skRect = layer.LayerShape.GetUnscaledRectangle();
var skRect = layer.LayerShape.RenderRectangle;
skRect.Bottom = (float) Math.Max(position.Y, skRect.Top);
ApplyShapeResize(skRect);
}
@@ -253,7 +261,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
return;
var position = GetRelativePosition(sender, e);
var skRect = layer.LayerShape.GetUnscaledRectangle();
var skRect = layer.LayerShape.RenderRectangle;
if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
{
// Take the greatest difference
@@ -275,7 +283,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
var position = GetRelativePosition(sender, e);
var skRect = layer.LayerShape.GetUnscaledRectangle();
var skRect = layer.LayerShape.RenderRectangle;
skRect.Left = (float) Math.Min(position.X, skRect.Right);
ApplyShapeResize(skRect);
}
@@ -291,15 +299,16 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
if (!(ProfileEditorService.SelectedProfileElement is Layer layer))
return;
// TODO: Apply the translation
// Store the original position to create an offset for the anchor
var original = layer.PositionProperty.CurrentValue;
layer.LayerShape.SetFromUnscaledRectangle(newRect, ProfileEditorService.CurrentTime);
var updated = layer.PositionProperty.CurrentValue;
// Apply the offset to the anchor so it stays in at same spot
layer.AnchorPointProperty.SetCurrentValue(new SKPoint(
layer.AnchorPointProperty.CurrentValue.X + (original.X - updated.X),
layer.AnchorPointProperty.CurrentValue.Y + (original.Y - updated.Y)
), ProfileEditorService.CurrentTime);
// var original = layer.PositionProperty.CurrentValue;
// layer.LayerShape.SetFromUnscaledRectangle(newRect, ProfileEditorService.CurrentTime);
// var updated = layer.PositionProperty.CurrentValue;
// // Apply the offset to the anchor so it stays in at same spot
// layer.AnchorPointProperty.SetCurrentValue(new SKPoint(
// layer.AnchorPointProperty.CurrentValue.X + (original.X - updated.X),
// layer.AnchorPointProperty.CurrentValue.Y + (original.Y - updated.Y)
// ), ProfileEditorService.CurrentTime);
// Update the preview
ProfileEditorService.UpdateProfilePreview();
@@ -4,6 +4,7 @@ using System.Windows.Input;
using Artemis.Core.Models.Profile;
using Artemis.Core.Models.Profile.LayerShapes;
using Artemis.UI.Properties;
using Artemis.UI.Services;
using Artemis.UI.Services.Interfaces;
using SkiaSharp.Views.WPF;
@@ -11,10 +12,13 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
{
public class EllipseToolViewModel : VisualizationToolViewModel
{
private readonly ILayerEditorService _layerEditorService;
private bool _shiftDown;
public EllipseToolViewModel(ProfileViewModel profileViewModel, IProfileEditorService profileEditorService) : base(profileViewModel, profileEditorService)
public EllipseToolViewModel(ProfileViewModel profileViewModel, IProfileEditorService profileEditorService, ILayerEditorService layerEditorService)
: base(profileViewModel, profileEditorService)
{
_layerEditorService = layerEditorService;
using (var stream = new MemoryStream(Resources.aero_crosshair))
{
Cursor = new Cursor(stream);
@@ -48,7 +52,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
layer.LayerShape = new Ellipse(layer);
// Apply the drag rectangle
layer.LayerShape.SetFromUnscaledRectangle(DragRectangle.ToSKRect(), ProfileEditorService.CurrentTime);
_layerEditorService.SetShapeRenderRect(layer.LayerShape, DragRectangle);
ProfileEditorService.UpdateSelectedProfileElement();
}
}
@@ -4,6 +4,7 @@ using System.Windows.Input;
using Artemis.Core.Models.Profile;
using Artemis.Core.Models.Profile.LayerShapes;
using Artemis.UI.Properties;
using Artemis.UI.Services;
using Artemis.UI.Services.Interfaces;
using SkiaSharp.Views.WPF;
@@ -11,10 +12,13 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
{
public class RectangleToolViewModel : VisualizationToolViewModel
{
private readonly ILayerEditorService _layerEditorService;
private bool _shiftDown;
public RectangleToolViewModel(ProfileViewModel profileViewModel, IProfileEditorService profileEditorService) : base(profileViewModel, profileEditorService)
public RectangleToolViewModel(ProfileViewModel profileViewModel, IProfileEditorService profileEditorService, ILayerEditorService layerEditorService)
: base(profileViewModel, profileEditorService)
{
_layerEditorService = layerEditorService;
using (var stream = new MemoryStream(Resources.aero_crosshair))
{
Cursor = new Cursor(stream);
@@ -48,7 +52,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
layer.LayerShape = new Rectangle(layer);
// Apply the drag rectangle
layer.LayerShape.SetFromUnscaledRectangle(DragRectangle.ToSKRect(), ProfileEditorService.CurrentTime);
_layerEditorService.SetShapeRenderRect(layer.LayerShape, DragRectangle);
ProfileEditorService.UpdateSelectedProfileElement();
}
}
@@ -6,6 +6,7 @@ using Artemis.Core.Models.Profile;
using Artemis.Core.Models.Surface;
using Artemis.UI.Extensions;
using Artemis.UI.Properties;
using Artemis.UI.Services;
using Artemis.UI.Services.Interfaces;
using SkiaSharp;
@@ -13,8 +14,12 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
{
public class SelectionToolViewModel : VisualizationToolViewModel
{
public SelectionToolViewModel(ProfileViewModel profileViewModel, IProfileEditorService profileEditorService) : base(profileViewModel, profileEditorService)
private readonly ILayerEditorService _layerEditorService;
public SelectionToolViewModel(ProfileViewModel profileViewModel, IProfileEditorService profileEditorService, ILayerEditorService layerEditorService)
: base(profileViewModel, profileEditorService)
{
_layerEditorService = layerEditorService;
using (var stream = new MemoryStream(Resources.aero_crosshair))
{
Cursor = new Cursor(stream);
@@ -48,14 +53,14 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
if (ProfileEditorService.SelectedProfileElement is Layer layer)
{
// If the layer has a shape, save it's size
var shapeSize = SKRect.Empty;
var shapeSize = Rect.Empty;
if (layer.LayerShape != null)
shapeSize = layer.LayerShape.GetUnscaledRectangle();
shapeSize = _layerEditorService.GetShapeRenderRect(layer.LayerShape);
layer.ClearLeds();
layer.AddLeds(selectedLeds);
// Restore the saved size
if (layer.LayerShape != null)
layer.LayerShape.SetFromUnscaledRectangle(shapeSize, ProfileEditorService.CurrentTime);
_layerEditorService.SetShapeRenderRect(layer.LayerShape, shapeSize);
ProfileEditorService.UpdateSelectedProfileElement();
}