mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Device visualizer - Only rerender dirty devices
This commit is contained in:
parent
fa710777d7
commit
e190059623
@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -13,6 +12,10 @@ using Avalonia.LogicalTree;
|
|||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
using Avalonia.Media.Imaging;
|
using Avalonia.Media.Imaging;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
|
using RGB.NET.Core;
|
||||||
|
using Color = RGB.NET.Core.Color;
|
||||||
|
using Point = Avalonia.Point;
|
||||||
|
using Size = Avalonia.Size;
|
||||||
|
|
||||||
namespace Artemis.UI.Shared;
|
namespace Artemis.UI.Shared;
|
||||||
|
|
||||||
@ -21,20 +24,20 @@ namespace Artemis.UI.Shared;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class DeviceVisualizer : Control
|
public class DeviceVisualizer : Control
|
||||||
{
|
{
|
||||||
private const double UpdateFrameRate = 25.0;
|
private const double UPDATE_FRAME_RATE = 25.0;
|
||||||
private readonly List<DeviceVisualizerLed> _deviceVisualizerLeds;
|
private readonly List<DeviceVisualizerLed> _deviceVisualizerLeds;
|
||||||
private readonly DispatcherTimer _timer;
|
private readonly DispatcherTimer _timer;
|
||||||
|
|
||||||
private Rect _deviceBounds;
|
private Rect _deviceBounds;
|
||||||
private RenderTargetBitmap? _deviceImage;
|
private RenderTargetBitmap? _deviceImage;
|
||||||
private List<DeviceVisualizerLed>? _dimmedLeds;
|
|
||||||
private List<DeviceVisualizerLed>? _highlightedLeds;
|
|
||||||
private ArtemisDevice? _oldDevice;
|
private ArtemisDevice? _oldDevice;
|
||||||
|
private bool _loading;
|
||||||
|
private Color[] _previousState = Array.Empty<Color>();
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public DeviceVisualizer()
|
public DeviceVisualizer()
|
||||||
{
|
{
|
||||||
_timer = new DispatcherTimer(DispatcherPriority.Background) {Interval = TimeSpan.FromMilliseconds(1000.0 / UpdateFrameRate)};
|
_timer = new DispatcherTimer(DispatcherPriority.Background) {Interval = TimeSpan.FromMilliseconds(1000.0 / UPDATE_FRAME_RATE)};
|
||||||
_deviceVisualizerLeds = new List<DeviceVisualizerLed>();
|
_deviceVisualizerLeds = new List<DeviceVisualizerLed>();
|
||||||
|
|
||||||
PointerReleased += OnPointerReleased;
|
PointerReleased += OnPointerReleased;
|
||||||
@ -77,7 +80,7 @@ public class DeviceVisualizer : Control
|
|||||||
// Apply device scale
|
// Apply device scale
|
||||||
using DrawingContext.PushedState scalePush = drawingContext.PushTransform(Matrix.CreateScale(Device.Scale, Device.Scale));
|
using DrawingContext.PushedState scalePush = drawingContext.PushTransform(Matrix.CreateScale(Device.Scale, Device.Scale));
|
||||||
foreach (DeviceVisualizerLed deviceVisualizerLed in _deviceVisualizerLeds)
|
foreach (DeviceVisualizerLed deviceVisualizerLed in _deviceVisualizerLeds)
|
||||||
deviceVisualizerLed.RenderGeometry(drawingContext, false);
|
deviceVisualizerLed.RenderGeometry(drawingContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@ -112,6 +115,31 @@ public class DeviceVisualizer : Control
|
|||||||
Clicked?.Invoke(this, e);
|
Clicked?.Invoke(this, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool IsDirty()
|
||||||
|
{
|
||||||
|
if (Device == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Color[] state = new Color[Device.RgbDevice.Count()];
|
||||||
|
bool difference = _previousState.Length != state.Length;
|
||||||
|
|
||||||
|
// Check all LEDs for differences and copy the colors to a new state
|
||||||
|
int index = 0;
|
||||||
|
foreach (Led led in Device.RgbDevice)
|
||||||
|
{
|
||||||
|
if (!difference && !led.Color.Equals(_previousState[index]))
|
||||||
|
difference = true;
|
||||||
|
|
||||||
|
state[index] = led.Color;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the new state for next time
|
||||||
|
_previousState = state;
|
||||||
|
|
||||||
|
return difference;
|
||||||
|
}
|
||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
InvalidateVisual();
|
InvalidateVisual();
|
||||||
@ -131,7 +159,7 @@ public class DeviceVisualizer : Control
|
|||||||
|
|
||||||
private void TimerOnTick(object? sender, EventArgs e)
|
private void TimerOnTick(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (ShowColors && IsVisible && Opacity > 0)
|
if (IsDirty() && ShowColors && IsVisible && Opacity > 0)
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,23 +228,6 @@ public class DeviceVisualizer : Control
|
|||||||
set => SetValue(ShowColorsProperty, value);
|
set => SetValue(ShowColorsProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a list of LEDs to highlight
|
|
||||||
/// </summary>
|
|
||||||
public static readonly StyledProperty<ObservableCollection<ArtemisLed>?> HighlightedLedsProperty =
|
|
||||||
AvaloniaProperty.Register<DeviceVisualizer, ObservableCollection<ArtemisLed>?>(nameof(HighlightedLeds));
|
|
||||||
|
|
||||||
private bool _loading;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a list of LEDs to highlight
|
|
||||||
/// </summary>
|
|
||||||
public ObservableCollection<ArtemisLed>? HighlightedLeds
|
|
||||||
{
|
|
||||||
get => GetValue(HighlightedLedsProperty);
|
|
||||||
set => SetValue(HighlightedLedsProperty, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Lifetime management
|
#region Lifetime management
|
||||||
@ -254,9 +265,6 @@ public class DeviceVisualizer : Control
|
|||||||
|
|
||||||
private void SetupForDevice()
|
private void SetupForDevice()
|
||||||
{
|
{
|
||||||
_highlightedLeds = new List<DeviceVisualizerLed>();
|
|
||||||
_dimmedLeds = new List<DeviceVisualizerLed>();
|
|
||||||
|
|
||||||
lock (_deviceVisualizerLeds)
|
lock (_deviceVisualizerLeds)
|
||||||
{
|
{
|
||||||
_deviceVisualizerLeds.Clear();
|
_deviceVisualizerLeds.Clear();
|
||||||
@ -305,7 +313,7 @@ public class DeviceVisualizer : Control
|
|||||||
using DrawingContext context = renderTargetBitmap.CreateDrawingContext();
|
using DrawingContext context = renderTargetBitmap.CreateDrawingContext();
|
||||||
using Bitmap bitmap = new(device.Layout.Image.LocalPath);
|
using Bitmap bitmap = new(device.Layout.Image.LocalPath);
|
||||||
using Bitmap scaledBitmap = bitmap.CreateScaledBitmap(renderTargetBitmap.PixelSize);
|
using Bitmap scaledBitmap = bitmap.CreateScaledBitmap(renderTargetBitmap.PixelSize);
|
||||||
|
|
||||||
context.DrawImage(scaledBitmap, new Rect(scaledBitmap.Size));
|
context.DrawImage(scaledBitmap, new Rect(scaledBitmap.Size));
|
||||||
lock (_deviceVisualizerLeds)
|
lock (_deviceVisualizerLeds)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -20,13 +20,7 @@ internal class DeviceVisualizerLed
|
|||||||
public DeviceVisualizerLed(ArtemisLed led)
|
public DeviceVisualizerLed(ArtemisLed led)
|
||||||
{
|
{
|
||||||
Led = led;
|
Led = led;
|
||||||
LedRect = new Rect(
|
|
||||||
Led.RgbLed.Location.X,
|
|
||||||
Led.RgbLed.Location.Y,
|
|
||||||
Led.RgbLed.Size.Width,
|
|
||||||
Led.RgbLed.Size.Height
|
|
||||||
);
|
|
||||||
|
|
||||||
_fillBrush = new SolidColorBrush();
|
_fillBrush = new SolidColorBrush();
|
||||||
_penBrush = new SolidColorBrush();
|
_penBrush = new SolidColorBrush();
|
||||||
_pen = new Pen(_penBrush) {LineJoin = PenLineJoin.Round};
|
_pen = new Pen(_penBrush) {LineJoin = PenLineJoin.Round};
|
||||||
@ -35,7 +29,6 @@ internal class DeviceVisualizerLed
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ArtemisLed Led { get; }
|
public ArtemisLed Led { get; }
|
||||||
public Rect LedRect { get; set; }
|
|
||||||
public Geometry? DisplayGeometry { get; private set; }
|
public Geometry? DisplayGeometry { get; private set; }
|
||||||
|
|
||||||
public void DrawBitmap(DrawingContext drawingContext, double scale)
|
public void DrawBitmap(DrawingContext drawingContext, double scale)
|
||||||
@ -58,7 +51,7 @@ internal class DeviceVisualizerLed
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RenderGeometry(DrawingContext drawingContext, bool dimmed)
|
public void RenderGeometry(DrawingContext drawingContext)
|
||||||
{
|
{
|
||||||
if (DisplayGeometry == null)
|
if (DisplayGeometry == null)
|
||||||
return;
|
return;
|
||||||
@ -66,17 +59,8 @@ internal class DeviceVisualizerLed
|
|||||||
byte r = Led.RgbLed.Color.GetR();
|
byte r = Led.RgbLed.Color.GetR();
|
||||||
byte g = Led.RgbLed.Color.GetG();
|
byte g = Led.RgbLed.Color.GetG();
|
||||||
byte b = Led.RgbLed.Color.GetB();
|
byte b = Led.RgbLed.Color.GetB();
|
||||||
|
_fillBrush.Color = new Color(100, r, g, b);
|
||||||
if (dimmed)
|
_penBrush.Color = new Color(255, r, g, b);
|
||||||
{
|
|
||||||
_fillBrush.Color = new Color(50, r, g, b);
|
|
||||||
_penBrush.Color = new Color(100, r, g, b);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_fillBrush.Color = new Color(100, r, g, b);
|
|
||||||
_penBrush.Color = new Color(255, r, g, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render the LED geometry
|
// Render the LED geometry
|
||||||
drawingContext.DrawGeometry(_fillBrush, _pen, DisplayGeometry);
|
drawingContext.DrawGeometry(_fillBrush, _pen, DisplayGeometry);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user