diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj
index 1f336f351..50e19fad7 100644
--- a/src/Artemis.UI/Artemis.UI.csproj
+++ b/src/Artemis.UI/Artemis.UI.csproj
@@ -166,7 +166,8 @@
-
+
+
True
diff --git a/src/Artemis.UI/Ninject/Factories/ModuleViewModelFactory.cs b/src/Artemis.UI/Ninject/Factories/IModuleViewModelFactory.cs
similarity index 100%
rename from src/Artemis.UI/Ninject/Factories/ModuleViewModelFactory.cs
rename to src/Artemis.UI/Ninject/Factories/IModuleViewModelFactory.cs
diff --git a/src/Artemis.UI/Ninject/Factories/IProfileEditorViewModelFactory.cs b/src/Artemis.UI/Ninject/Factories/IProfileEditorViewModelFactory.cs
new file mode 100644
index 000000000..8708d0236
--- /dev/null
+++ b/src/Artemis.UI/Ninject/Factories/IProfileEditorViewModelFactory.cs
@@ -0,0 +1,10 @@
+using Artemis.Core.Plugins.Abstract;
+using Artemis.UI.ViewModels.Controls.ProfileEditor;
+
+namespace Artemis.UI.Ninject.Factories
+{
+ public interface IProfileEditorViewModelFactory
+ {
+ ProfileEditorViewModel CreateModuleViewModel(Module module);
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI/Ninject/UiModule.cs b/src/Artemis.UI/Ninject/UiModule.cs
index 38bf34559..a4c5d340e 100644
--- a/src/Artemis.UI/Ninject/UiModule.cs
+++ b/src/Artemis.UI/Ninject/UiModule.cs
@@ -36,7 +36,8 @@ namespace Artemis.UI.Ninject
// Bind the module VM
Bind().ToFactory();
-
+ Bind().ToFactory();
+
// Bind all UI services as singletons
Kernel.Bind(x =>
{
diff --git a/src/Artemis.UI/ViewModels/Controls/ProfileEditor/ProfileDeviceViewModel.cs b/src/Artemis.UI/ViewModels/Controls/ProfileEditor/ProfileDeviceViewModel.cs
index 4f81e64af..cfcd70bc2 100644
--- a/src/Artemis.UI/ViewModels/Controls/ProfileEditor/ProfileDeviceViewModel.cs
+++ b/src/Artemis.UI/ViewModels/Controls/ProfileEditor/ProfileDeviceViewModel.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
-using RGB.NET.Core;
+using System.Windows;
+using Artemis.Core.Models.Surface;
using Stylet;
namespace Artemis.UI.ViewModels.Controls.ProfileEditor
@@ -8,18 +9,44 @@ namespace Artemis.UI.ViewModels.Controls.ProfileEditor
{
private readonly List _leds;
- public ProfileDeviceViewModel(IRGBDevice device)
+ public ProfileDeviceViewModel(Device device)
{
Device = device;
_leds = new List();
- foreach (var led in Device)
- _leds.Add(new ProfileLedViewModel(led));
+ if (Device.RgbDevice != null)
+ {
+ foreach (var led in Device.RgbDevice)
+ _leds.Add(new ProfileLedViewModel(led));
+ }
+ }
+
+ public Device Device { get; set; }
+
+ public double X
+ {
+ get => Device.X;
+ set => Device.X = value;
+ }
+
+ public double Y
+ {
+ get => Device.Y;
+ set => Device.Y = value;
+ }
+
+ public int ZIndex
+ {
+ get => Device.ZIndex;
+ set => Device.ZIndex = value;
}
- public IRGBDevice Device { get; }
public IReadOnlyCollection Leds => _leds.AsReadOnly();
+ public Rect DeviceRectangle => Device.RgbDevice == null
+ ? new Rect()
+ : new Rect(X, Y, Device.RgbDevice.Size.Width, Device.RgbDevice.Size.Height);
+
public void Update()
{
foreach (var ledViewModel in _leds)
diff --git a/src/Artemis.UI/ViewModels/Controls/ProfileEditor/ProfileEditorViewModel.cs b/src/Artemis.UI/ViewModels/Controls/ProfileEditor/ProfileEditorViewModel.cs
index 1cda2e580..e25a147cf 100644
--- a/src/Artemis.UI/ViewModels/Controls/ProfileEditor/ProfileEditorViewModel.cs
+++ b/src/Artemis.UI/ViewModels/Controls/ProfileEditor/ProfileEditorViewModel.cs
@@ -1,16 +1,170 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Input;
+using System.Windows.Media;
+using Artemis.Core.Events;
+using Artemis.Core.Models.Surface;
using Artemis.Core.Plugins.Abstract;
+using Artemis.Core.Services.Interfaces;
+using Artemis.Core.Services.Storage;
+using Artemis.UI.ViewModels.Screens;
+using Artemis.UI.ViewModels.Utilities;
+using Stylet;
namespace Artemis.UI.ViewModels.Controls.ProfileEditor
{
- public class ProfileEditorViewModel : ModuleViewModel
+ public class ProfileEditorViewModel : ModuleViewModel
{
- public ProfileEditorViewModel(Module module) : base(module, "Profile Editor")
+ public ProfileEditorViewModel(Module module, ISurfaceService surfaceService, ICoreService coreService) : base(module, "Profile Editor")
{
+ surfaceService.ActiveSurfaceConfigurationChanged += OnActiveSurfaceConfigurationChanged;
+ coreService.FrameRendered += CoreServiceOnFrameRendered;
+ Devices = new ObservableCollection();
+ Execute.OnUIThread(() =>
+ {
+ SelectionRectangle = new RectangleGeometry();
+ PanZoomViewModel = new PanZoomViewModel();
+ });
+
+ ApplySurfaceConfiguration(surfaceService.ActiveSurface);
}
+
+ public ObservableCollection Devices { get; set; }
+ public RectangleGeometry SelectionRectangle { get; set; }
+ public PanZoomViewModel PanZoomViewModel { get; set; }
+
+ private void OnActiveSurfaceConfigurationChanged(object sender, SurfaceConfigurationEventArgs e)
+ {
+ ApplySurfaceConfiguration(e.Surface);
+ }
+
+ private void CoreServiceOnFrameRendered(object sender, FrameRenderedEventArgs e)
+ {
+ foreach (var profileDeviceViewModel in Devices)
+ profileDeviceViewModel.Update();
+ }
+
+ private void ApplySurfaceConfiguration(Surface surface)
+ {
+ // Make sure all devices have an up-to-date VM
+ foreach (var surfaceDeviceConfiguration in surface.Devices)
+ {
+ // Create VMs for missing devices
+ var viewModel = Devices.FirstOrDefault(vm => vm.Device.RgbDevice == surfaceDeviceConfiguration.RgbDevice);
+ if (viewModel == null)
+ Execute.OnUIThread(() => Devices.Add(new ProfileDeviceViewModel(surfaceDeviceConfiguration)));
+ // Update existing devices
+ else
+ viewModel.Device = surfaceDeviceConfiguration;
+ }
+ }
+
+ #region Selection
+
+ private MouseDragStatus _mouseDragStatus;
+ private Point _mouseDragStartPoint;
+
+ // ReSharper disable once UnusedMember.Global - Called from view
+ public void EditorGridMouseClick(object sender, MouseEventArgs e)
+ {
+ if (IsPanKeyDown())
+ return;
+
+ var position = e.GetPosition((IInputElement) sender);
+ var relative = PanZoomViewModel.GetRelativeMousePosition(sender, e);
+ if (e.LeftButton == MouseButtonState.Pressed)
+ StartMouseDrag(position, relative);
+ else
+ StopMouseDrag(position);
+ }
+
+ // ReSharper disable once UnusedMember.Global - Called from view
+ public void EditorGridMouseMove(object sender, MouseEventArgs e)
+ {
+ // If holding down Ctrl, pan instead of move/select
+ if (IsPanKeyDown())
+ {
+ Pan(sender, e);
+ return;
+ }
+
+ var position = e.GetPosition((IInputElement) sender);
+ if (_mouseDragStatus == MouseDragStatus.Selecting)
+ UpdateSelection(position);
+ }
+
+ private void StartMouseDrag(Point position, Point relative)
+ {
+ _mouseDragStatus = MouseDragStatus.Selecting;
+ _mouseDragStartPoint = position;
+
+ // Any time dragging starts, start with a new rect
+ SelectionRectangle.Rect = new Rect();
+ }
+
+ private void StopMouseDrag(Point position)
+ {
+ var selectedRect = new Rect(_mouseDragStartPoint, position);
+ // TODO: Select LEDs
+
+ Mouse.OverrideCursor = null;
+ _mouseDragStatus = MouseDragStatus.None;
+ }
+
+ private void UpdateSelection(Point position)
+ {
+ if (IsPanKeyDown())
+ return;
+
+ lock (Devices)
+ {
+ var selectedRect = new Rect(_mouseDragStartPoint, position);
+ SelectionRectangle.Rect = selectedRect;
+
+ // TODO: Highlight LEDs
+ }
+ }
+
+ #endregion
+
+ #region Panning and zooming
+
+ public void EditorGridMouseWheel(object sender, MouseWheelEventArgs e)
+ {
+ PanZoomViewModel.ProcessMouseScroll(sender, e);
+ }
+
+ public void EditorGridKeyDown(object sender, KeyEventArgs e)
+ {
+ if ((e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl) && e.IsDown)
+ Mouse.OverrideCursor = Cursors.ScrollAll;
+ }
+
+ public void EditorGridKeyUp(object sender, KeyEventArgs e)
+ {
+ if ((e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl) && e.IsUp)
+ Mouse.OverrideCursor = null;
+ }
+
+ public void Pan(object sender, MouseEventArgs e)
+ {
+ PanZoomViewModel.ProcessMouseMove(sender, e);
+
+ // Empty the selection rect since it's shown while mouse is down
+ SelectionRectangle.Rect = Rect.Empty;
+ }
+
+ public void ResetZoomAndPan()
+ {
+ PanZoomViewModel.Reset();
+ }
+
+ private bool IsPanKeyDown()
+ {
+ return Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl);
+ }
+
+ #endregion
}
-}
+}
\ No newline at end of file
diff --git a/src/Artemis.UI/ViewModels/Controls/ProfileEditor/ProfileLedViewModel.cs b/src/Artemis.UI/ViewModels/Controls/ProfileEditor/ProfileLedViewModel.cs
index 7e776b7e5..b3fa52017 100644
--- a/src/Artemis.UI/ViewModels/Controls/ProfileEditor/ProfileLedViewModel.cs
+++ b/src/Artemis.UI/ViewModels/Controls/ProfileEditor/ProfileLedViewModel.cs
@@ -13,7 +13,7 @@ namespace Artemis.UI.ViewModels.Controls.ProfileEditor
public ProfileLedViewModel(Led led)
{
Led = led;
-
+
Execute.OnUIThread(CreateLedGeometry);
Update();
}
@@ -92,13 +92,9 @@ namespace Artemis.UI.ViewModels.Controls.ProfileEditor
public void Update()
{
- if (ColorsEnabled)
- {
- if (Led.Id == LedId.Keyboard_Y)
- Console.WriteLine();
- var newColor = Led.Color.ToMediaColor();
- SetColor(newColor);
- }
+ var newColor = Led.Color.ToMediaColor();
+ if (!DisplayColor.Equals(newColor))
+ DisplayColor = newColor;
if (Math.Abs(Led.LedRectangle.X - X) > 0.1)
X = Led.LedRectangle.X;
@@ -112,11 +108,5 @@ namespace Artemis.UI.ViewModels.Controls.ProfileEditor
if (Math.Abs(Led.LedRectangle.Height - Height) > 0.1)
Height = Led.LedRectangle.Height;
}
-
- public void SetColor(Color color)
- {
- if (!DisplayColor.Equals(color))
- DisplayColor = color;
- }
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/ViewModels/Controls/SurfaceEditor/SurfaceDeviceViewModel.cs b/src/Artemis.UI/ViewModels/Controls/SurfaceEditor/SurfaceDeviceViewModel.cs
index 6978b91b4..0e9d4baaf 100644
--- a/src/Artemis.UI/ViewModels/Controls/SurfaceEditor/SurfaceDeviceViewModel.cs
+++ b/src/Artemis.UI/ViewModels/Controls/SurfaceEditor/SurfaceDeviceViewModel.cs
@@ -3,17 +3,15 @@ using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;
using Artemis.Core.Models.Surface;
-using RGB.NET.Core;
using Stylet;
-using Point = System.Windows.Point;
namespace Artemis.UI.ViewModels.Controls.SurfaceEditor
{
public class SurfaceDeviceViewModel : PropertyChangedBase
{
+ private readonly List _leds;
private double _dragOffsetX;
private double _dragOffsetY;
- private readonly List _leds;
public SurfaceDeviceViewModel(Device device)
{
diff --git a/src/Artemis.UI/ViewModels/Screens/ModuleRootViewModel.cs b/src/Artemis.UI/ViewModels/Screens/ModuleRootViewModel.cs
index 00eb1e8bf..302f8664f 100644
--- a/src/Artemis.UI/ViewModels/Screens/ModuleRootViewModel.cs
+++ b/src/Artemis.UI/ViewModels/Screens/ModuleRootViewModel.cs
@@ -1,4 +1,5 @@
using Artemis.Core.Plugins.Abstract;
+using Artemis.UI.Ninject.Factories;
using Artemis.UI.ViewModels.Controls.ProfileEditor;
using Stylet;
@@ -6,10 +7,10 @@ namespace Artemis.UI.ViewModels.Screens
{
public class ModuleRootViewModel : Screen
{
- public ModuleRootViewModel(Module module)
+ public ModuleRootViewModel(Module module, IProfileEditorViewModelFactory profileEditorViewModelFactory)
{
Module = module;
- ModuleViewModels = new BindableCollection {new ProfileEditorViewModel(Module)};
+ ModuleViewModels = new BindableCollection {profileEditorViewModelFactory.CreateModuleViewModel(Module)};
ModuleViewModels.AddRange(Module.GetViewModels());
}
diff --git a/src/Artemis.UI/ViewModels/Screens/SurfaceEditorViewModel.cs b/src/Artemis.UI/ViewModels/Screens/SurfaceEditorViewModel.cs
index fd5310a93..ba4543113 100644
--- a/src/Artemis.UI/ViewModels/Screens/SurfaceEditorViewModel.cs
+++ b/src/Artemis.UI/ViewModels/Screens/SurfaceEditorViewModel.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
@@ -33,10 +32,11 @@ namespace Artemis.UI.ViewModels.Screens
_dialogService = dialogService;
}
- public RectangleGeometry SelectionRectangle { get; set; }
public ObservableCollection Devices { get; set; }
public ObservableCollection SurfaceConfigurations { get; set; }
-
+ public RectangleGeometry SelectionRectangle { get; set; }
+ public PanZoomViewModel PanZoomViewModel { get; set; }
+
public Surface SelectedSurface
{
get => _selectedSurface;
@@ -47,7 +47,6 @@ namespace Artemis.UI.ViewModels.Screens
}
}
- public PanZoomViewModel PanZoomViewModel { get; set; }
public string Title => "Surface Editor";
public Surface CreateSurfaceConfiguration(string name)
@@ -189,7 +188,7 @@ namespace Artemis.UI.ViewModels.Screens
#endregion
- #region RgbDevice selection
+ #region Selection
private MouseDragStatus _mouseDragStatus;
private Point _mouseDragStartPoint;
diff --git a/src/Artemis.UI/Views/Controls/ProfileEditor/ProfileDeviceView.xaml b/src/Artemis.UI/Views/Controls/ProfileEditor/ProfileDeviceView.xaml
index b905ca0c7..e557a3777 100644
--- a/src/Artemis.UI/Views/Controls/ProfileEditor/ProfileDeviceView.xaml
+++ b/src/Artemis.UI/Views/Controls/ProfileEditor/ProfileDeviceView.xaml
@@ -1,23 +1,34 @@
-
+ d:DesignHeight="450" d:DesignWidth="800">
-
+
+
-
+
+
+
+
+
+
+
diff --git a/src/Artemis.UI/Views/Controls/ProfileEditor/ProfileEditorView.xaml b/src/Artemis.UI/Views/Controls/ProfileEditor/ProfileEditorView.xaml
index 97243184e..52372dbe8 100644
--- a/src/Artemis.UI/Views/Controls/ProfileEditor/ProfileEditorView.xaml
+++ b/src/Artemis.UI/Views/Controls/ProfileEditor/ProfileEditorView.xaml
@@ -5,10 +5,168 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Artemis.UI.Views.Controls.ProfileEditor"
xmlns:profileEditor="clr-namespace:Artemis.UI.ViewModels.Controls.ProfileEditor"
+ xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:s="https://github.com/canton7/Stylet"
+ xmlns:models="clr-namespace:Artemis.Core.Models.Surface;assembly=Artemis.Core"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance {x:Type profileEditor:ProfileEditorViewModel}}">
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Profile editor
+
+ The profile defines what colors the LEDs will have. Multiple groups of LEDs are defined into layers. On these layers you can apply effects.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Artemis.UI/Views/Controls/SurfaceEditor/SurfaceDeviceView.xaml b/src/Artemis.UI/Views/Controls/SurfaceEditor/SurfaceDeviceView.xaml
index f22c4dc3b..2aa1881cf 100644
--- a/src/Artemis.UI/Views/Controls/SurfaceEditor/SurfaceDeviceView.xaml
+++ b/src/Artemis.UI/Views/Controls/SurfaceEditor/SurfaceDeviceView.xaml
@@ -19,6 +19,7 @@
+
+
@@ -51,6 +53,7 @@
+