mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-31 09:43:46 +00:00
Device visualization - Improved performance to a good level for now
This commit is contained in:
parent
ae48ebc13a
commit
5dea0b25e5
@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
using Artemis.Core.Models.Surface;
|
using Artemis.Core.Models.Surface;
|
||||||
@ -15,30 +16,21 @@ namespace Artemis.UI.Shared.Controls
|
|||||||
new FrameworkPropertyMetadata(default(ArtemisDevice), FrameworkPropertyMetadataOptions.AffectsRender, DevicePropertyChangedCallback));
|
new FrameworkPropertyMetadata(default(ArtemisDevice), FrameworkPropertyMetadataOptions.AffectsRender, DevicePropertyChangedCallback));
|
||||||
|
|
||||||
public static readonly DependencyProperty ShowColorsProperty = DependencyProperty.Register(nameof(ShowColors), typeof(bool), typeof(DeviceVisualizer),
|
public static readonly DependencyProperty ShowColorsProperty = DependencyProperty.Register(nameof(ShowColors), typeof(bool), typeof(DeviceVisualizer),
|
||||||
new FrameworkPropertyMetadata(default(bool), FrameworkPropertyMetadataOptions.AffectsRender));
|
new FrameworkPropertyMetadata(default(bool), FrameworkPropertyMetadataOptions.AffectsRender, ShowColorsPropertyChangedCallback));
|
||||||
|
|
||||||
private readonly DrawingGroup _backingStore;
|
private readonly DrawingGroup _backingStore;
|
||||||
private readonly List<DeviceVisualizerLed> _deviceVisualizerLeds;
|
private readonly List<DeviceVisualizerLed> _deviceVisualizerLeds;
|
||||||
private BitmapImage _deviceImage;
|
private BitmapImage _deviceImage;
|
||||||
private RGBSurface _subscribedSurface;
|
|
||||||
|
|
||||||
public DeviceVisualizer()
|
public DeviceVisualizer()
|
||||||
{
|
{
|
||||||
_backingStore = new DrawingGroup();
|
_backingStore = new DrawingGroup();
|
||||||
_deviceVisualizerLeds = new List<DeviceVisualizerLed>();
|
_deviceVisualizerLeds = new List<DeviceVisualizerLed>();
|
||||||
|
|
||||||
|
SubscribeToSurfaceUpdate();
|
||||||
Unloaded += (sender, args) => Dispose();
|
Unloaded += (sender, args) => Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
if (_subscribedSurface != null)
|
|
||||||
{
|
|
||||||
_subscribedSurface.Updated -= RgbSurfaceOnUpdated;
|
|
||||||
_subscribedSurface = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArtemisDevice Device
|
public ArtemisDevice Device
|
||||||
{
|
{
|
||||||
get => (ArtemisDevice) GetValue(DeviceProperty);
|
get => (ArtemisDevice) GetValue(DeviceProperty);
|
||||||
@ -51,6 +43,11 @@ namespace Artemis.UI.Shared.Controls
|
|||||||
set => SetValue(ShowColorsProperty, value);
|
set => SetValue(ShowColorsProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
RGBSurface.Instance.Updated -= RgbSurfaceOnUpdated;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnRender(DrawingContext drawingContext)
|
protected override void OnRender(DrawingContext drawingContext)
|
||||||
{
|
{
|
||||||
if (Device == null)
|
if (Device == null)
|
||||||
@ -72,7 +69,7 @@ namespace Artemis.UI.Shared.Controls
|
|||||||
drawingContext.DrawImage(_deviceImage, new Rect(0, 0, Device.RgbDevice.Size.Width, Device.RgbDevice.Size.Height));
|
drawingContext.DrawImage(_deviceImage, new Rect(0, 0, Device.RgbDevice.Size.Width, Device.RgbDevice.Size.Height));
|
||||||
|
|
||||||
foreach (var deviceVisualizerLed in _deviceVisualizerLeds)
|
foreach (var deviceVisualizerLed in _deviceVisualizerLeds)
|
||||||
deviceVisualizerLed.Render(drawingContext, false);
|
deviceVisualizerLed.RenderImage(drawingContext);
|
||||||
|
|
||||||
drawingContext.DrawDrawing(_backingStore);
|
drawingContext.DrawDrawing(_backingStore);
|
||||||
}
|
}
|
||||||
@ -80,15 +77,16 @@ namespace Artemis.UI.Shared.Controls
|
|||||||
private static void DevicePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
private static void DevicePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
var deviceVisualizer = (DeviceVisualizer) d;
|
var deviceVisualizer = (DeviceVisualizer) d;
|
||||||
deviceVisualizer.Dispatcher.Invoke(() =>
|
deviceVisualizer.Dispatcher.Invoke(() => { deviceVisualizer.SetupForDevice(); });
|
||||||
{
|
|
||||||
deviceVisualizer.SubscribeToSurfaceUpdate((ArtemisDevice) e.NewValue);
|
|
||||||
deviceVisualizer.Initialize();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void ShowColorsPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var deviceVisualizer = (DeviceVisualizer) d;
|
||||||
|
deviceVisualizer.Dispatcher.Invoke(() => { deviceVisualizer.SetupForDevice(); });
|
||||||
|
}
|
||||||
|
|
||||||
private void Initialize()
|
private void SetupForDevice()
|
||||||
{
|
{
|
||||||
_deviceImage = null;
|
_deviceImage = null;
|
||||||
_deviceVisualizerLeds.Clear();
|
_deviceVisualizerLeds.Clear();
|
||||||
@ -101,29 +99,50 @@ namespace Artemis.UI.Shared.Controls
|
|||||||
_deviceImage = new BitmapImage(Device.RgbDevice.DeviceInfo.Image);
|
_deviceImage = new BitmapImage(Device.RgbDevice.DeviceInfo.Image);
|
||||||
|
|
||||||
// Create all the LEDs
|
// Create all the LEDs
|
||||||
foreach (var artemisLed in Device.Leds) _deviceVisualizerLeds.Add(new DeviceVisualizerLed(artemisLed));
|
foreach (var artemisLed in Device.Leds)
|
||||||
}
|
_deviceVisualizerLeds.Add(new DeviceVisualizerLed(artemisLed));
|
||||||
|
|
||||||
private void SubscribeToSurfaceUpdate(ArtemisDevice newValue)
|
if (!ShowColors)
|
||||||
{
|
|
||||||
if (newValue.Surface.RgbSurface == _subscribedSurface)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Remove subscription from old surface
|
// Create the opacity drawing group
|
||||||
if (_subscribedSurface != null)
|
var opacityDrawingGroup = new DrawingGroup();
|
||||||
_subscribedSurface.Updated -= RgbSurfaceOnUpdated;
|
var drawingContext = opacityDrawingGroup.Open();
|
||||||
// Subscribe to new surface
|
foreach (var deviceVisualizerLed in _deviceVisualizerLeds)
|
||||||
if (newValue.Surface.RgbSurface != null)
|
deviceVisualizerLed.RenderOpacityMask(drawingContext);
|
||||||
newValue.Surface.RgbSurface.Updated += RgbSurfaceOnUpdated;
|
drawingContext.Close();
|
||||||
|
|
||||||
_subscribedSurface = newValue.Surface.RgbSurface;
|
// Render the store as a bitmap
|
||||||
|
var drawingImage = new DrawingImage(opacityDrawingGroup);
|
||||||
|
var image = new Image {Source = drawingImage};
|
||||||
|
var bitmap = new RenderTargetBitmap(
|
||||||
|
(int) (opacityDrawingGroup.Bounds.Width * 2.5),
|
||||||
|
(int) (opacityDrawingGroup.Bounds.Height * 2.5),
|
||||||
|
96,
|
||||||
|
96,
|
||||||
|
PixelFormats.Pbgra32
|
||||||
|
);
|
||||||
|
image.Arrange(new Rect(0, 0, bitmap.Width, bitmap.Height));
|
||||||
|
bitmap.Render(image);
|
||||||
|
bitmap.Freeze();
|
||||||
|
|
||||||
|
// Set the bitmap as the opacity mask for the colors backing store
|
||||||
|
var bitmapBrush = new ImageBrush(bitmap);
|
||||||
|
bitmapBrush.Freeze();
|
||||||
|
_backingStore.OpacityMask = bitmapBrush;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SubscribeToSurfaceUpdate()
|
||||||
|
{
|
||||||
|
RGBSurface.Instance.Updated += RgbSurfaceOnUpdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RgbSurfaceOnUpdated(UpdatedEventArgs e)
|
private void RgbSurfaceOnUpdated(UpdatedEventArgs e)
|
||||||
{
|
{
|
||||||
Dispatcher.Invoke(() =>
|
Dispatcher.Invoke(() =>
|
||||||
{
|
{
|
||||||
if (ShowColors) Render();
|
if (ShowColors && Visibility == Visibility.Visible)
|
||||||
|
Render();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,7 +151,7 @@ namespace Artemis.UI.Shared.Controls
|
|||||||
var drawingContext = _backingStore.Open();
|
var drawingContext = _backingStore.Open();
|
||||||
|
|
||||||
foreach (var deviceVisualizerLed in _deviceVisualizerLeds)
|
foreach (var deviceVisualizerLed in _deviceVisualizerLeds)
|
||||||
deviceVisualizerLed.Render(drawingContext, true);
|
deviceVisualizerLed.RenderColor(drawingContext);
|
||||||
|
|
||||||
drawingContext.Close();
|
drawingContext.Close();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,24 +14,26 @@ namespace Artemis.UI.Shared.Controls
|
|||||||
public DeviceVisualizerLed(ArtemisLed led)
|
public DeviceVisualizerLed(ArtemisLed led)
|
||||||
{
|
{
|
||||||
Led = led;
|
Led = led;
|
||||||
|
LedRect = new Rect(
|
||||||
|
Led.RgbLed.LedRectangle.Location.X,
|
||||||
|
Led.RgbLed.LedRectangle.Location.Y,
|
||||||
|
Led.RgbLed.LedRectangle.Size.Width,
|
||||||
|
Led.RgbLed.LedRectangle.Size.Height
|
||||||
|
);
|
||||||
|
|
||||||
if (Led.RgbLed.Image != null && File.Exists(Led.RgbLed.Image.AbsolutePath))
|
if (Led.RgbLed.Image != null && File.Exists(Led.RgbLed.Image.AbsolutePath))
|
||||||
LedImage = new BitmapImage(Led.RgbLed.Image);
|
LedImage = new BitmapImage(Led.RgbLed.Image);
|
||||||
|
|
||||||
CreateLedGeometry();
|
CreateLedGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public ArtemisLed Led { get; }
|
public ArtemisLed Led { get; }
|
||||||
|
public Rect LedRect { get; set; }
|
||||||
public BitmapImage LedImage { get; set; }
|
public BitmapImage LedImage { get; set; }
|
||||||
|
|
||||||
public Geometry DisplayGeometry { get; private set; }
|
public Geometry DisplayGeometry { get; private set; }
|
||||||
|
|
||||||
internal void Render(DrawingContext drawingContext, bool renderGeometry)
|
|
||||||
{
|
|
||||||
if (!renderGeometry)
|
|
||||||
RenderImage(drawingContext);
|
|
||||||
else
|
|
||||||
RenderGeometry(drawingContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CreateLedGeometry()
|
private void CreateLedGeometry()
|
||||||
{
|
{
|
||||||
switch (Led.RgbLed.Shape)
|
switch (Led.RgbLed.Shape)
|
||||||
@ -101,7 +103,7 @@ namespace Artemis.UI.Shared.Controls
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RenderGeometry(DrawingContext drawingContext)
|
public void RenderColor(DrawingContext drawingContext)
|
||||||
{
|
{
|
||||||
if (DisplayGeometry == null)
|
if (DisplayGeometry == null)
|
||||||
return;
|
return;
|
||||||
@ -110,26 +112,28 @@ namespace Artemis.UI.Shared.Controls
|
|||||||
var g = Led.RgbLed.Color.GetG();
|
var g = Led.RgbLed.Color.GetG();
|
||||||
var b = Led.RgbLed.Color.GetB();
|
var b = Led.RgbLed.Color.GetB();
|
||||||
|
|
||||||
var fillBrush = new SolidColorBrush(Color.FromArgb(100, r,g,b));
|
drawingContext.DrawRectangle(new SolidColorBrush(Color.FromRgb(r, g, b)), null, LedRect);
|
||||||
fillBrush.Freeze();
|
|
||||||
var penBrush = new SolidColorBrush(Color.FromArgb(255, r, g, b));
|
|
||||||
penBrush.Freeze();
|
|
||||||
|
|
||||||
drawingContext.DrawGeometry(fillBrush, new Pen(penBrush, 1), DisplayGeometry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RenderImage(DrawingContext drawingContext)
|
public void RenderImage(DrawingContext drawingContext)
|
||||||
{
|
{
|
||||||
if (LedImage == null)
|
if (LedImage == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var ledRect = new Rect(
|
drawingContext.DrawImage(LedImage, LedRect);
|
||||||
Led.RgbLed.LedRectangle.Location.X,
|
}
|
||||||
Led.RgbLed.LedRectangle.Location.Y,
|
|
||||||
Led.RgbLed.LedRectangle.Size.Width,
|
public void RenderOpacityMask(DrawingContext drawingContext)
|
||||||
Led.RgbLed.LedRectangle.Size.Height
|
{
|
||||||
);
|
if (DisplayGeometry == null)
|
||||||
drawingContext.DrawImage(LedImage, ledRect);
|
return;
|
||||||
|
|
||||||
|
var fillBrush = new SolidColorBrush(Color.FromArgb(100, 255, 255, 255));
|
||||||
|
fillBrush.Freeze();
|
||||||
|
var penBrush = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
|
||||||
|
penBrush.Freeze();
|
||||||
|
|
||||||
|
drawingContext.DrawGeometry(fillBrush, new Pen(penBrush, 1), DisplayGeometry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,7 +173,7 @@
|
|||||||
<Slider Margin="0,0,14,0"
|
<Slider Margin="0,0,14,0"
|
||||||
Orientation="Vertical"
|
Orientation="Vertical"
|
||||||
Minimum="10"
|
Minimum="10"
|
||||||
Maximum="400"
|
Maximum="250"
|
||||||
Height="100"
|
Height="100"
|
||||||
FocusVisualStyle="{x:Null}"
|
FocusVisualStyle="{x:Null}"
|
||||||
Value="{Binding PanZoomViewModel.ZoomPercentage}"
|
Value="{Binding PanZoomViewModel.ZoomPercentage}"
|
||||||
|
|||||||
@ -181,7 +181,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
|||||||
private void ApplySurfaceConfiguration(ArtemisSurface surface)
|
private void ApplySurfaceConfiguration(ArtemisSurface surface)
|
||||||
{
|
{
|
||||||
Devices.Clear();
|
Devices.Clear();
|
||||||
Devices.AddRange(surface.Devices);
|
Devices.AddRange(surface.Devices.OrderBy(d => d.ZIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateLedsDimStatus()
|
private void UpdateLedsDimStatus()
|
||||||
|
|||||||
@ -40,8 +40,8 @@ namespace Artemis.UI.Screens.Shared
|
|||||||
else
|
else
|
||||||
Zoom *= 0.9;
|
Zoom *= 0.9;
|
||||||
|
|
||||||
// Limit to a min of 0.1 and a max of 4 (10% - 400% in the view)
|
// Limit to a min of 0.1 and a max of 2.5 (10% - 250% in the view)
|
||||||
Zoom = Math.Max(0.1, Math.Min(4, Zoom));
|
Zoom = Math.Max(0.1, Math.Min(2.5, Zoom));
|
||||||
|
|
||||||
// Update the PanX/Y to enable zooming relative to cursor
|
// Update the PanX/Y to enable zooming relative to cursor
|
||||||
if (LimitToZero)
|
if (LimitToZero)
|
||||||
|
|||||||
@ -26,7 +26,7 @@
|
|||||||
<RotateTransform Angle="{Binding Device.Rotation}" />
|
<RotateTransform Angle="{Binding Device.Rotation}" />
|
||||||
</Grid.LayoutTransform>
|
</Grid.LayoutTransform>
|
||||||
|
|
||||||
<controls:DeviceVisualizer Device="{Binding Device}"></controls:DeviceVisualizer>
|
<controls:DeviceVisualizer Device="{Binding Device}"/>
|
||||||
|
|
||||||
<Rectangle Fill="{DynamicResource MaterialDesignCardBackground}"
|
<Rectangle Fill="{DynamicResource MaterialDesignCardBackground}"
|
||||||
Stroke="{DynamicResource MaterialDesignTextBoxBorder}"
|
Stroke="{DynamicResource MaterialDesignTextBoxBorder}"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user