diff --git a/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs b/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs index 0a19bf490..e0b981cff 100644 --- a/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs +++ b/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs @@ -1,18 +1,15 @@ using System; using System.Collections.Generic; using System.IO; -using System.Text; using System.Windows; -using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Imaging; using Artemis.Core.Models.Surface; using RGB.NET.Core; -using Stylet; namespace Artemis.UI.Shared.Controls { - public class DeviceVisualizer : FrameworkElement + public class DeviceVisualizer : FrameworkElement, IDisposable { public static readonly DependencyProperty DeviceProperty = DependencyProperty.Register(nameof(Device), typeof(ArtemisDevice), typeof(DeviceVisualizer), new FrameworkPropertyMetadata(default(ArtemisDevice), FrameworkPropertyMetadataOptions.AffectsRender, DevicePropertyChangedCallback)); @@ -20,18 +17,26 @@ namespace Artemis.UI.Shared.Controls public static readonly DependencyProperty ShowColorsProperty = DependencyProperty.Register(nameof(ShowColors), typeof(bool), typeof(DeviceVisualizer), new FrameworkPropertyMetadata(default(bool), FrameworkPropertyMetadataOptions.AffectsRender)); + private readonly DrawingGroup _backingStore; + private readonly List _deviceVisualizerLeds; private BitmapImage _deviceImage; - private List _deviceVisualizerLeds; - private DrawingGroup _backingStore; + private RGBSurface _subscribedSurface; - private static void DevicePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) + public DeviceVisualizer() { - var deviceVisualizer = (DeviceVisualizer) d; - deviceVisualizer.Dispatcher.Invoke(() => + _backingStore = new DrawingGroup(); + _deviceVisualizerLeds = new List(); + + Unloaded += (sender, args) => Dispose(); + } + + public void Dispose() + { + if (_subscribedSurface != null) { - deviceVisualizer.SubscribeToSurfaceUpdate((ArtemisDevice) e.OldValue, (ArtemisDevice) e.NewValue); - deviceVisualizer.Initialize(); - }); + _subscribedSurface.Updated -= RgbSurfaceOnUpdated; + _subscribedSurface = null; + } } public ArtemisDevice Device @@ -46,61 +51,6 @@ namespace Artemis.UI.Shared.Controls set => SetValue(ShowColorsProperty, value); } - public DeviceVisualizer() - { - _backingStore = new DrawingGroup(); - _deviceVisualizerLeds = new List(); - } - - - private void Initialize() - { - _deviceImage = null; - _deviceVisualizerLeds.Clear(); - - if (Device == null) - return; - - // Load the device main image - if (Device.RgbDevice?.DeviceInfo?.Image?.AbsolutePath != null && File.Exists(Device.RgbDevice.DeviceInfo.Image.AbsolutePath)) - _deviceImage = new BitmapImage(Device.RgbDevice.DeviceInfo.Image); - - // Create all the LEDs - foreach (var artemisLed in Device.Leds) - { - _deviceVisualizerLeds.Add(new DeviceVisualizerLed(artemisLed)); - } - } - - private void SubscribeToSurfaceUpdate(ArtemisDevice oldValue, ArtemisDevice newValue) - { - if (oldValue != null) - oldValue.Surface.RgbSurface.Updated -= RgbSurfaceOnUpdated; - if (newValue != null) - newValue.Surface.RgbSurface.Updated += RgbSurfaceOnUpdated; - } - - private void RgbSurfaceOnUpdated(UpdatedEventArgs args) - { - Dispatcher.Invoke(() => - { - if (ShowColors) - { - Render(); - } - }); - } - - private void Render() - { - var drawingContext = _backingStore.Open(); - - foreach (var deviceVisualizerLed in _deviceVisualizerLeds) - deviceVisualizerLed.Render(drawingContext, true); - - drawingContext.Close(); - } - protected override void OnRender(DrawingContext drawingContext) { if (Device == null) @@ -109,7 +59,7 @@ namespace Artemis.UI.Shared.Controls // Determine the scale required to fit the desired size of the control var scale = Math.Min(DesiredSize.Width / Device.RgbDevice.Size.Width, DesiredSize.Height / Device.RgbDevice.Size.Height); var scaledRect = new Rect(0, 0, Device.RgbDevice.Size.Width * scale, Device.RgbDevice.Size.Height * scale); - + // Center and scale the visualization in the desired bounding box if (DesiredSize.Width > 0 && DesiredSize.Height > 0) { @@ -126,5 +76,65 @@ namespace Artemis.UI.Shared.Controls drawingContext.DrawDrawing(_backingStore); } + + private static void DevicePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var deviceVisualizer = (DeviceVisualizer) d; + deviceVisualizer.Dispatcher.Invoke(() => + { + deviceVisualizer.SubscribeToSurfaceUpdate((ArtemisDevice) e.NewValue); + deviceVisualizer.Initialize(); + }); + } + + + private void Initialize() + { + _deviceImage = null; + _deviceVisualizerLeds.Clear(); + + if (Device == null) + return; + + // Load the device main image + if (Device.RgbDevice?.DeviceInfo?.Image?.AbsolutePath != null && File.Exists(Device.RgbDevice.DeviceInfo.Image.AbsolutePath)) + _deviceImage = new BitmapImage(Device.RgbDevice.DeviceInfo.Image); + + // Create all the LEDs + foreach (var artemisLed in Device.Leds) _deviceVisualizerLeds.Add(new DeviceVisualizerLed(artemisLed)); + } + + private void SubscribeToSurfaceUpdate(ArtemisDevice newValue) + { + if (newValue.Surface.RgbSurface == _subscribedSurface) + return; + + // Remove subscription from old surface + if (_subscribedSurface != null) + _subscribedSurface.Updated -= RgbSurfaceOnUpdated; + // Subscribe to new surface + if (newValue.Surface.RgbSurface != null) + newValue.Surface.RgbSurface.Updated += RgbSurfaceOnUpdated; + + _subscribedSurface = newValue.Surface.RgbSurface; + } + + private void RgbSurfaceOnUpdated(UpdatedEventArgs e) + { + Dispatcher.Invoke(() => + { + if (ShowColors) Render(); + }); + } + + private void Render() + { + var drawingContext = _backingStore.Open(); + + foreach (var deviceVisualizerLed in _deviceVisualizerLeds) + deviceVisualizerLed.Render(drawingContext, true); + + drawingContext.Close(); + } } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerView.xaml index 2e739ff22..bdaccea00 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerView.xaml +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerView.xaml @@ -49,8 +49,8 @@