From a138ec916dd715a0cb821ca3422a6301a827b6dc Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 13 Jan 2020 19:38:44 +0100 Subject: [PATCH] Added edit existing shape (WIP) --- src/Artemis.UI/Artemis.UI.csproj | 5 + src/Artemis.UI/Resources/aero_rotate_bl.cur | Bin 32102 -> 4286 bytes src/Artemis.UI/Resources/aero_rotate_br.cur | Bin 32102 -> 4286 bytes src/Artemis.UI/Resources/aero_rotate_tl.cur | Bin 32102 -> 4286 bytes src/Artemis.UI/Resources/aero_rotate_tr.cur | Bin 32102 -> 4286 bytes .../Visualization/ProfileLayerView.xaml | 9 +- .../Visualization/ProfileLayerViewModel.cs | 29 ++-- .../Visualization/ProfileView.xaml | 7 +- .../Visualization/ProfileViewModel.cs | 15 +- .../Visualization/Tools/EditToolView.xaml | 110 +++++++++++++ .../Visualization/Tools/EditToolViewModel.cs | 152 ++++++++++++++++++ 11 files changed, 300 insertions(+), 27 deletions(-) create mode 100644 src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolView.xaml create mode 100644 src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolViewModel.cs diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj index 7ad2b2c08..396eb369e 100644 --- a/src/Artemis.UI/Artemis.UI.csproj +++ b/src/Artemis.UI/Artemis.UI.csproj @@ -182,6 +182,7 @@ ProfileLayerView.xaml + EllipseToolView.xaml @@ -367,6 +368,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile diff --git a/src/Artemis.UI/Resources/aero_rotate_bl.cur b/src/Artemis.UI/Resources/aero_rotate_bl.cur index d43d0134090b9c64c0a0a5f91de6cace6dc546f8..1e4b8621e028a61f821bd51a9abee3f5e874d149 100644 GIT binary patch literal 4286 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 diff --git a/src/Artemis.UI/Resources/aero_rotate_tl.cur b/src/Artemis.UI/Resources/aero_rotate_tl.cur index 3bc1596886c14243cfc15e32bef1f2b71e8a1277..292957c87ead33dbd9cc2b70d2322952a8bfc6dd 100644 GIT binary patch literal 4286 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 Dma=}Y diff --git a/src/Artemis.UI/Resources/aero_rotate_tr.cur b/src/Artemis.UI/Resources/aero_rotate_tr.cur index 8d0e2f055d07d1f1a08399b2a32731e05da4de6a..614009c1c4e81bc1062d4bbfbdb62011ba49ebdd 100644 GIT binary patch literal 4286 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 - - - \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerViewModel.cs index 28a677578..a0331ebaf 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerViewModel.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Windows; +using System.Windows.Input; using System.Windows.Media; using Artemis.Core.Models.Profile; using Artemis.Core.Models.Profile.LayerShapes; @@ -8,6 +9,8 @@ using Artemis.Core.Models.Surface; using Artemis.UI.Extensions; using Artemis.UI.Services.Interfaces; using RGB.NET.Core; +using SkiaSharp; +using SkiaSharp.Views.WPF; using Rectangle = Artemis.Core.Models.Profile.LayerShapes.Rectangle; namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization @@ -27,13 +30,12 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization _profileEditorService.SelectedProfileElementUpdated += OnSelectedProfileElementUpdated; _profileEditorService.CurrentTimeChanged += ProfileEditorServiceOnCurrentTimeChanged; } - + public Layer Layer { get; } public Geometry LayerGeometry { get; set; } public Geometry OpacityGeometry { get; set; } public Geometry ShapeGeometry { get; set; } - public Rect ShapeRectangle { get; set; } public Rect ViewportRectangle { get; set; } public bool IsSelected { get; set; } @@ -100,29 +102,30 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization } var skRect = Layer.LayerShape.GetUnscaledRectangle(); - ShapeRectangle = new Rect(skRect.Left, skRect.Top, skRect.Width, skRect.Height); + 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) { case Ellipse _: - shapeGeometry = new EllipseGeometry(ShapeRectangle); + shapeGeometry = new EllipseGeometry(rect); break; case Fill _: shapeGeometry = LayerGeometry; break; case Polygon _: // TODO - shapeGeometry = new RectangleGeometry(ShapeRectangle); + shapeGeometry = new RectangleGeometry(rect); break; case Rectangle _: - shapeGeometry = new RectangleGeometry(ShapeRectangle); + shapeGeometry = new RectangleGeometry(rect); break; } shapeGeometry.Freeze(); ShapeGeometry = shapeGeometry; } - + private void CreateViewportRectangle() { if (!Layer.Leds.Any() || Layer.LayerShape == null) @@ -182,6 +185,13 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization } } + public void Dispose() + { + Layer.RenderPropertiesUpdated -= LayerOnRenderPropertiesUpdated; + } + + #region Event handlers + private void LayerOnRenderPropertiesUpdated(object sender, EventArgs e) { Update(); @@ -206,9 +216,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization CreateViewportRectangle(); } - public void Dispose() - { - Layer.RenderPropertiesUpdated -= LayerOnRenderPropertiesUpdated; - } + #endregion } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileView.xaml index 134b36506..1798a391f 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileView.xaml +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileView.xaml @@ -55,15 +55,18 @@ + + + - + - + diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileViewModel.cs index 785b69742..912df3104 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileViewModel.cs @@ -253,24 +253,27 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization ActiveToolViewModel = new ViewpointMoveToolViewModel(this, _profileEditorService); break; case 1: - ActiveToolViewModel = new SelectionToolViewModel(this, _profileEditorService); + ActiveToolViewModel = new EditToolViewModel(this, _profileEditorService); break; case 2: - ActiveToolViewModel = new SelectionAddToolViewModel(this, _profileEditorService); + ActiveToolViewModel = new SelectionToolViewModel(this, _profileEditorService); break; case 3: + ActiveToolViewModel = new SelectionAddToolViewModel(this, _profileEditorService); + break; + case 4: ActiveToolViewModel = new SelectionRemoveToolViewModel(this, _profileEditorService); break; - case 5: + case 6: ActiveToolViewModel = new EllipseToolViewModel(this, _profileEditorService); break; - case 6: + case 7: ActiveToolViewModel = new RectangleToolViewModel(this, _profileEditorService); break; - case 7: + case 8: ActiveToolViewModel = new PolygonToolViewModel(this, _profileEditorService); break; - case 8: + case 9: ActiveToolViewModel = new FillToolViewModel(this, _profileEditorService); break; } diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolView.xaml new file mode 100644 index 000000000..fdf497ff6 --- /dev/null +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolView.xaml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolViewModel.cs new file mode 100644 index 000000000..7076a08fd --- /dev/null +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolViewModel.cs @@ -0,0 +1,152 @@ +using System; +using System.Windows; +using System.Windows.Input; +using System.Windows.Media; +using Artemis.Core.Models.Profile; +using Artemis.UI.Services.Interfaces; +using SkiaSharp; + +namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools +{ + public class EditToolViewModel : VisualizationToolViewModel + { + private bool _mouseDown; + + public EditToolViewModel(ProfileViewModel profileViewModel, IProfileEditorService profileEditorService) : base(profileViewModel, profileEditorService) + { + Cursor = Cursors.Arrow; + Update(); + + profileEditorService.SelectedProfileChanged += (sender, args) => Update(); + profileEditorService.SelectedProfileElementUpdated += (sender, args) => Update(); + profileEditorService.CurrentTimeChanged += (sender, args) => Update(); + } + + private void Update() + { + if (ProfileEditorService.SelectedProfileElement is Layer layer) + { + ShapeSkRect = layer.LayerShape.GetUnscaledRectangle(); + } + } + + public SKRect ShapeSkRect { get; set; } + + public void ShapeEditMouseDown(object sender, MouseButtonEventArgs e) + { + ((IInputElement) sender).CaptureMouse(); + _mouseDown = true; + e.Handled = true; + } + + public void ShapeEditMouseUp(object sender, MouseButtonEventArgs e) + { + ((IInputElement) sender).ReleaseMouseCapture(); + _mouseDown = false; + e.Handled = true; + } + + public void TopLeftRotate(object sender, MouseEventArgs e) + { + } + + public void TopLeftResize(object sender, MouseEventArgs e) + { + + } + + public void TopCenterResize(object sender, MouseEventArgs e) + { + if (!_mouseDown) + return; + if (!(ProfileEditorService.SelectedProfileElement is Layer layer)) + return; + + var position = GetRelativePosition(sender, e); + + var skRect = layer.LayerShape.GetUnscaledRectangle(); + skRect.Top = (float) Math.Min(position.Y, skRect.Bottom); + layer.LayerShape.SetFromUnscaledRectangle(skRect); + + ProfileEditorService.UpdateSelectedProfileElement(); + } + + public void TopRightRotate(object sender, MouseEventArgs e) + { + } + + public void TopRightResize(object sender, MouseEventArgs e) + { + } + + public void CenterRightResize(object sender, MouseEventArgs e) + { + if (!_mouseDown) + return; + if (!(ProfileEditorService.SelectedProfileElement is Layer layer)) + return; + + var position = GetRelativePosition(sender, e); + + var skRect = layer.LayerShape.GetUnscaledRectangle(); + skRect.Right = (float) Math.Max(position.X, skRect.Left); + layer.LayerShape.SetFromUnscaledRectangle(skRect); + + ProfileEditorService.UpdateSelectedProfileElement(); + } + + private Point GetRelativePosition(object sender, MouseEventArgs mouseEventArgs) + { + var parent = VisualTreeHelper.GetParent((DependencyObject) sender); + return mouseEventArgs.GetPosition((IInputElement) parent); + } + + public void BottomRightRotate(object sender, MouseEventArgs e) + { + } + + public void BottomRightResize(object sender, MouseEventArgs e) + { + } + + public void BottomCenterResize(object sender, MouseEventArgs e) + { + if (!_mouseDown) + return; + if (!(ProfileEditorService.SelectedProfileElement is Layer layer)) + return; + + var position = GetRelativePosition(sender, e); + + var skRect = layer.LayerShape.GetUnscaledRectangle(); + skRect.Bottom = (float) Math.Max(position.Y, skRect.Top); + layer.LayerShape.SetFromUnscaledRectangle(skRect); + + ProfileEditorService.UpdateSelectedProfileElement(); + } + + public void BottomLeftRotate(object sender, MouseEventArgs e) + { + } + + public void BottomLeftResize(object sender, MouseEventArgs e) + { + } + + public void CenterLeftResize(object sender, MouseEventArgs e) + { + if (!_mouseDown) + return; + if (!(ProfileEditorService.SelectedProfileElement is Layer layer)) + return; + + var position = GetRelativePosition(sender, e); + + var skRect = layer.LayerShape.GetUnscaledRectangle(); + skRect.Left = (float) Math.Min(position.X, skRect.Right); + layer.LayerShape.SetFromUnscaledRectangle(skRect); + + ProfileEditorService.UpdateSelectedProfileElement(); + } + } +} \ No newline at end of file