mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +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.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using Artemis.Core.Models.Surface;
|
||||
@ -15,29 +16,20 @@ namespace Artemis.UI.Shared.Controls
|
||||
new FrameworkPropertyMetadata(default(ArtemisDevice), FrameworkPropertyMetadataOptions.AffectsRender, DevicePropertyChangedCallback));
|
||||
|
||||
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 List<DeviceVisualizerLed> _deviceVisualizerLeds;
|
||||
private BitmapImage _deviceImage;
|
||||
private RGBSurface _subscribedSurface;
|
||||
|
||||
public DeviceVisualizer()
|
||||
{
|
||||
_backingStore = new DrawingGroup();
|
||||
_deviceVisualizerLeds = new List<DeviceVisualizerLed>();
|
||||
|
||||
SubscribeToSurfaceUpdate();
|
||||
Unloaded += (sender, args) => Dispose();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_subscribedSurface != null)
|
||||
{
|
||||
_subscribedSurface.Updated -= RgbSurfaceOnUpdated;
|
||||
_subscribedSurface = null;
|
||||
}
|
||||
}
|
||||
|
||||
public ArtemisDevice Device
|
||||
{
|
||||
@ -51,6 +43,11 @@ namespace Artemis.UI.Shared.Controls
|
||||
set => SetValue(ShowColorsProperty, value);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
RGBSurface.Instance.Updated -= RgbSurfaceOnUpdated;
|
||||
}
|
||||
|
||||
protected override void OnRender(DrawingContext drawingContext)
|
||||
{
|
||||
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));
|
||||
|
||||
foreach (var deviceVisualizerLed in _deviceVisualizerLeds)
|
||||
deviceVisualizerLed.Render(drawingContext, false);
|
||||
deviceVisualizerLed.RenderImage(drawingContext);
|
||||
|
||||
drawingContext.DrawDrawing(_backingStore);
|
||||
}
|
||||
@ -80,15 +77,16 @@ namespace Artemis.UI.Shared.Controls
|
||||
private static void DevicePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var deviceVisualizer = (DeviceVisualizer) d;
|
||||
deviceVisualizer.Dispatcher.Invoke(() =>
|
||||
{
|
||||
deviceVisualizer.SubscribeToSurfaceUpdate((ArtemisDevice) e.NewValue);
|
||||
deviceVisualizer.Initialize();
|
||||
});
|
||||
deviceVisualizer.Dispatcher.Invoke(() => { deviceVisualizer.SetupForDevice(); });
|
||||
}
|
||||
|
||||
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;
|
||||
_deviceVisualizerLeds.Clear();
|
||||
@ -101,29 +99,50 @@ namespace Artemis.UI.Shared.Controls
|
||||
_deviceImage = new BitmapImage(Device.RgbDevice.DeviceInfo.Image);
|
||||
|
||||
// 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 (newValue.Surface.RgbSurface == _subscribedSurface)
|
||||
if (!ShowColors)
|
||||
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;
|
||||
// Create the opacity drawing group
|
||||
var opacityDrawingGroup = new DrawingGroup();
|
||||
var drawingContext = opacityDrawingGroup.Open();
|
||||
foreach (var deviceVisualizerLed in _deviceVisualizerLeds)
|
||||
deviceVisualizerLed.RenderOpacityMask(drawingContext);
|
||||
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)
|
||||
{
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
if (ShowColors) Render();
|
||||
if (ShowColors && Visibility == Visibility.Visible)
|
||||
Render();
|
||||
});
|
||||
}
|
||||
|
||||
@ -132,7 +151,7 @@ namespace Artemis.UI.Shared.Controls
|
||||
var drawingContext = _backingStore.Open();
|
||||
|
||||
foreach (var deviceVisualizerLed in _deviceVisualizerLeds)
|
||||
deviceVisualizerLed.Render(drawingContext, true);
|
||||
deviceVisualizerLed.RenderColor(drawingContext);
|
||||
|
||||
drawingContext.Close();
|
||||
}
|
||||
|
||||
@ -14,24 +14,26 @@ namespace Artemis.UI.Shared.Controls
|
||||
public DeviceVisualizerLed(ArtemisLed 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))
|
||||
LedImage = new BitmapImage(Led.RgbLed.Image);
|
||||
|
||||
CreateLedGeometry();
|
||||
}
|
||||
|
||||
|
||||
public ArtemisLed Led { get; }
|
||||
public Rect LedRect { get; set; }
|
||||
public BitmapImage LedImage { get; set; }
|
||||
|
||||
public Geometry DisplayGeometry { get; private set; }
|
||||
|
||||
internal void Render(DrawingContext drawingContext, bool renderGeometry)
|
||||
{
|
||||
if (!renderGeometry)
|
||||
RenderImage(drawingContext);
|
||||
else
|
||||
RenderGeometry(drawingContext);
|
||||
}
|
||||
|
||||
private void CreateLedGeometry()
|
||||
{
|
||||
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)
|
||||
return;
|
||||
@ -109,27 +111,29 @@ namespace Artemis.UI.Shared.Controls
|
||||
var r = Led.RgbLed.Color.GetR();
|
||||
var g = Led.RgbLed.Color.GetG();
|
||||
var b = Led.RgbLed.Color.GetB();
|
||||
|
||||
var fillBrush = new SolidColorBrush(Color.FromArgb(100, r,g,b));
|
||||
fillBrush.Freeze();
|
||||
var penBrush = new SolidColorBrush(Color.FromArgb(255, r, g, b));
|
||||
penBrush.Freeze();
|
||||
|
||||
drawingContext.DrawGeometry(fillBrush, new Pen(penBrush, 1), DisplayGeometry);
|
||||
|
||||
drawingContext.DrawRectangle(new SolidColorBrush(Color.FromRgb(r, g, b)), null, LedRect);
|
||||
}
|
||||
|
||||
private void RenderImage(DrawingContext drawingContext)
|
||||
public void RenderImage(DrawingContext drawingContext)
|
||||
{
|
||||
if (LedImage == null)
|
||||
return;
|
||||
|
||||
var ledRect = new Rect(
|
||||
Led.RgbLed.LedRectangle.Location.X,
|
||||
Led.RgbLed.LedRectangle.Location.Y,
|
||||
Led.RgbLed.LedRectangle.Size.Width,
|
||||
Led.RgbLed.LedRectangle.Size.Height
|
||||
);
|
||||
drawingContext.DrawImage(LedImage, ledRect);
|
||||
drawingContext.DrawImage(LedImage, LedRect);
|
||||
}
|
||||
|
||||
public void RenderOpacityMask(DrawingContext drawingContext)
|
||||
{
|
||||
if (DisplayGeometry == null)
|
||||
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"
|
||||
Orientation="Vertical"
|
||||
Minimum="10"
|
||||
Maximum="400"
|
||||
Maximum="250"
|
||||
Height="100"
|
||||
FocusVisualStyle="{x:Null}"
|
||||
Value="{Binding PanZoomViewModel.ZoomPercentage}"
|
||||
|
||||
@ -181,7 +181,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
private void ApplySurfaceConfiguration(ArtemisSurface surface)
|
||||
{
|
||||
Devices.Clear();
|
||||
Devices.AddRange(surface.Devices);
|
||||
Devices.AddRange(surface.Devices.OrderBy(d => d.ZIndex));
|
||||
}
|
||||
|
||||
private void UpdateLedsDimStatus()
|
||||
|
||||
@ -40,8 +40,8 @@ namespace Artemis.UI.Screens.Shared
|
||||
else
|
||||
Zoom *= 0.9;
|
||||
|
||||
// Limit to a min of 0.1 and a max of 4 (10% - 400% in the view)
|
||||
Zoom = Math.Max(0.1, Math.Min(4, Zoom));
|
||||
// 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(2.5, Zoom));
|
||||
|
||||
// Update the PanX/Y to enable zooming relative to cursor
|
||||
if (LimitToZero)
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
<RotateTransform Angle="{Binding Device.Rotation}" />
|
||||
</Grid.LayoutTransform>
|
||||
|
||||
<controls:DeviceVisualizer Device="{Binding Device}"></controls:DeviceVisualizer>
|
||||
<controls:DeviceVisualizer Device="{Binding Device}"/>
|
||||
|
||||
<Rectangle Fill="{DynamicResource MaterialDesignCardBackground}"
|
||||
Stroke="{DynamicResource MaterialDesignTextBoxBorder}"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user