diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj
index 3527006e4..e34ff68d3 100644
--- a/src/Artemis.UI/Artemis.UI.csproj
+++ b/src/Artemis.UI/Artemis.UI.csproj
@@ -184,6 +184,10 @@
+
+ ProfileLayerView.xaml
+
+
EllipseToolView.xaml
@@ -332,6 +336,10 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerView.xaml
new file mode 100644
index 000000000..951ee9dcf
--- /dev/null
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerView.xaml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerView.xaml.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerView.xaml.cs
new file mode 100644
index 000000000..5ed8f1f0c
--- /dev/null
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerView.xaml.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
+{
+ ///
+ /// Interaction logic for ProfileLayerView.xaml
+ ///
+ public partial class ProfileLayerView : UserControl
+ {
+ public ProfileLayerView()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerViewModel.cs
new file mode 100644
index 000000000..78430d528
--- /dev/null
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerViewModel.cs
@@ -0,0 +1,101 @@
+using System;
+using System.Linq;
+using System.Windows;
+using System.Windows.Media;
+using Artemis.Core.Models.Profile;
+using Artemis.Core.Models.Surface;
+using Artemis.UI.Extensions;
+using RGB.NET.Core;
+
+namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
+{
+ public class ProfileLayerViewModel : CanvasViewModel
+ {
+ public ProfileLayerViewModel(Layer layer)
+ {
+ Layer = layer;
+
+ CreateLayerGeometry();
+ Layer.RenderPropertiesUpdated += (sender, args) => CreateLayerGeometry();
+ }
+
+ public Layer Layer { get; }
+
+ public Geometry LayerGeometry { get; set; }
+
+ private void CreateLayerGeometry()
+ {
+ var layerGeometry = Geometry.Empty;
+
+ foreach (var led in Layer.Leds)
+ {
+ Geometry geometry;
+ switch (led.RgbLed.Shape)
+ {
+ case Shape.Custom:
+ if (led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keyboard || led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keypad)
+ geometry = CreateCustomGeometry(led, 2.0);
+ else
+ geometry = CreateCustomGeometry(led, 1.0);
+ break;
+ case Shape.Rectangle:
+ if (led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keyboard || led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keypad)
+ geometry = CreateKeyCapGeometry(led);
+ else
+ geometry = CreateRectangleGeometry(led);
+ break;
+ case Shape.Circle:
+ geometry = CreateCircleGeometry(led);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+
+ layerGeometry = Geometry.Combine(layerGeometry, geometry, GeometryCombineMode.Union, null, 5, ToleranceType.Absolute);
+ }
+
+ LayerGeometry = layerGeometry;
+ LayerGeometry.Freeze();
+ }
+
+ private Geometry CreateRectangleGeometry(ArtemisLed led)
+ {
+ return new RectangleGeometry(led.RgbLed.AbsoluteLedRectangle.ToWindowsRect(1));
+ }
+
+ private Geometry CreateCircleGeometry(ArtemisLed led)
+ {
+ return new EllipseGeometry(led.RgbLed.AbsoluteLedRectangle.ToWindowsRect(1));
+ }
+
+ private Geometry CreateKeyCapGeometry(ArtemisLed led)
+ {
+ return new RectangleGeometry(led.RgbLed.AbsoluteLedRectangle.ToWindowsRect(1), 1.6, 1.6);
+ }
+
+ private Geometry CreateCustomGeometry(ArtemisLed led, double deflateAmount)
+ {
+ try
+ {
+ var geometry = Geometry.Combine(
+ Geometry.Empty,
+ Geometry.Parse(led.RgbLed.ShapeData),
+ GeometryCombineMode.Union,
+ new TransformGroup
+ {
+ Children = new TransformCollection
+ {
+ new ScaleTransform(led.RgbLed.ActualSize.Width - deflateAmount, led.RgbLed.ActualSize.Height - deflateAmount),
+ new TranslateTransform(deflateAmount / 2, deflateAmount / 2)
+ }
+ }
+ );
+ return geometry;
+ }
+ catch (Exception)
+ {
+ return CreateRectangleGeometry(led);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileViewModel.cs
index 4d30e85e8..76c88f52e 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileViewModel.cs
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileViewModel.cs
@@ -42,14 +42,17 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
});
ApplySurfaceConfiguration(surfaceService.ActiveSurface);
+ ApplyActiveProfile();
CreateUpdateTrigger();
ActivateToolByIndex(0);
+ _profileEditorService.SelectedProfileChanged += OnSelectedProfileChanged;
_profileEditorService.SelectedProfileElementChanged += OnSelectedProfileElementChanged;
- _profileEditorService.SelectedProfileElementUpdated += OnSelectedProfileElementChanged;
+ _profileEditorService.SelectedProfileElementUpdated += OnSelectedProfileElementUpdated;
eventAggregator.Subscribe(this);
}
+
public bool IsInitializing { get; private set; }
public ObservableCollection CanvasViewModels { get; set; }
public PanZoomViewModel PanZoomViewModel { get; set; }
@@ -116,6 +119,31 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
ApplySurfaceConfiguration(e.Surface);
}
+ private void ApplyActiveProfile()
+ {
+ Execute.PostToUIThread(() =>
+ {
+ lock (CanvasViewModels)
+ {
+ var layerViewModels = CanvasViewModels.Where(vm => vm is ProfileLayerViewModel).Cast().ToList();
+ var layers = _profileEditorService.SelectedProfile?.GetAllLayers() ?? new List();
+
+
+ // Add new layers missing a VM
+ foreach (var layer in layers)
+ {
+ if (layerViewModels.All(vm => vm.Layer != layer))
+ CanvasViewModels.Add(new ProfileLayerViewModel(layer));
+ }
+
+ // Remove layers that no longer exist
+ var toRemove = layerViewModels.Where(vm => !layers.Contains(vm.Layer));
+ foreach (var profileLayerViewModel in toRemove)
+ CanvasViewModels.Remove(profileLayerViewModel);
+ }
+ });
+ }
+
private void ApplySurfaceConfiguration(ArtemisSurface surface)
{
var devices = new List();
@@ -324,12 +352,24 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
UpdateLedsDimStatus();
}
+ private void OnSelectedProfileChanged(object sender, EventArgs e)
+ {
+ ApplyActiveProfile();
+ }
+
private void OnSelectedProfileElementChanged(object sender, EventArgs e)
{
UpdateLedsDimStatus();
CanApplyToLayer = _profileEditorService.SelectedProfileElement is Layer;
}
+ private void OnSelectedProfileElementUpdated(object sender, EventArgs e)
+ {
+ ApplyActiveProfile();
+ UpdateLedsDimStatus();
+ CanApplyToLayer = _profileEditorService.SelectedProfileElement is Layer;
+ }
+
public void Handle(MainWindowFocusChangedEvent message)
{
if (PauseRenderingOnFocusLoss == null || ScreenState != ScreenState.Active)