mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Device visualizer - Unsubscribe from surface on unload
This commit is contained in:
parent
efa0f28231
commit
ae48ebc13a
@ -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<DeviceVisualizerLed> _deviceVisualizerLeds;
|
||||
private BitmapImage _deviceImage;
|
||||
private List<DeviceVisualizerLed> _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<DeviceVisualizerLed>();
|
||||
|
||||
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<DeviceVisualizerLed>();
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -49,8 +49,8 @@
|
||||
<Rectangle Width="{Binding LayerRect.Width}"
|
||||
Height="{Binding LayerRect.Height}"
|
||||
Margin="{Binding LayerRectMargin}"
|
||||
StrokeThickness="2"
|
||||
StrokeDashArray="1 1"
|
||||
StrokeThickness="1"
|
||||
StrokeDashArray="4 2"
|
||||
StrokeLineJoin="Round"
|
||||
x:Name="LayerPath">
|
||||
<Rectangle.Stroke>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user