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 d43d01340..1e4b8621e 100644 Binary files a/src/Artemis.UI/Resources/aero_rotate_bl.cur and b/src/Artemis.UI/Resources/aero_rotate_bl.cur differ diff --git a/src/Artemis.UI/Resources/aero_rotate_br.cur b/src/Artemis.UI/Resources/aero_rotate_br.cur index ab0c1e67c..7edf55d96 100644 Binary files a/src/Artemis.UI/Resources/aero_rotate_br.cur and b/src/Artemis.UI/Resources/aero_rotate_br.cur differ diff --git a/src/Artemis.UI/Resources/aero_rotate_tl.cur b/src/Artemis.UI/Resources/aero_rotate_tl.cur index 3bc159688..292957c87 100644 Binary files a/src/Artemis.UI/Resources/aero_rotate_tl.cur and b/src/Artemis.UI/Resources/aero_rotate_tl.cur differ diff --git a/src/Artemis.UI/Resources/aero_rotate_tr.cur b/src/Artemis.UI/Resources/aero_rotate_tr.cur index 8d0e2f055..614009c1c 100644 Binary files a/src/Artemis.UI/Resources/aero_rotate_tr.cur and b/src/Artemis.UI/Resources/aero_rotate_tr.cur differ diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerView.xaml index 1dc437c9b..cae9201c2 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerView.xaml +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerView.xaml @@ -4,6 +4,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.Visualization" + xmlns:s="https://github.com/canton7/Stylet" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" @@ -63,13 +64,5 @@ - - - \ 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