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