mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Merge branch 'development'
This commit is contained in:
commit
9cfa45972d
@ -43,9 +43,9 @@
|
|||||||
<PackageReference Include="LiteDB" Version="5.0.16" />
|
<PackageReference Include="LiteDB" Version="5.0.16" />
|
||||||
<PackageReference Include="McMaster.NETCore.Plugins" Version="1.4.0" />
|
<PackageReference Include="McMaster.NETCore.Plugins" Version="1.4.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
<PackageReference Include="RGB.NET.Core" Version="2.0.0-prerelease.53" />
|
<PackageReference Include="RGB.NET.Core" Version="2.0.0-prerelease.69" />
|
||||||
<PackageReference Include="RGB.NET.Layout" Version="2.0.0-prerelease.53" />
|
<PackageReference Include="RGB.NET.Layout" Version="2.0.0-prerelease.69" />
|
||||||
<PackageReference Include="RGB.NET.Presets" Version="2.0.0-prerelease.53" />
|
<PackageReference Include="RGB.NET.Presets" Version="2.0.0-prerelease.69" />
|
||||||
<PackageReference Include="Serilog" Version="2.12.0" />
|
<PackageReference Include="Serilog" Version="2.12.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
|
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.Debug" Version="2.0.0" />
|
<PackageReference Include="Serilog.Sinks.Debug" Version="2.0.0" />
|
||||||
|
|||||||
@ -396,7 +396,7 @@ internal class PluginManagementService : IPluginManagementService
|
|||||||
List<Type> featureTypes;
|
List<Type> featureTypes;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
featureTypes = plugin.Assembly.GetTypes().Where(t => typeof(PluginFeature).IsAssignableFrom(t)).ToList();
|
featureTypes = plugin.Assembly.GetTypes().Where(t => typeof(PluginFeature).IsAssignableFrom(t) && !t.IsAbstract).ToList();
|
||||||
}
|
}
|
||||||
catch (ReflectionTypeLoadException e)
|
catch (ReflectionTypeLoadException e)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
<PackageReference Include="Material.Icons.Avalonia" Version="2.0.0-preview3" />
|
<PackageReference Include="Material.Icons.Avalonia" Version="2.0.0-preview3" />
|
||||||
<PackageReference Include="ReactiveUI" Version="18.4.26" />
|
<PackageReference Include="ReactiveUI" Version="18.4.26" />
|
||||||
<PackageReference Include="ReactiveUI.Validation" Version="3.1.7" />
|
<PackageReference Include="ReactiveUI.Validation" Version="3.1.7" />
|
||||||
<PackageReference Include="RGB.NET.Core" Version="2.0.0-prerelease.53" />
|
<PackageReference Include="RGB.NET.Core" Version="2.0.0-prerelease.69" />
|
||||||
<PackageReference Include="SkiaSharp" Version="2.88.3" />
|
<PackageReference Include="SkiaSharp" Version="2.88.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@ -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.Render) {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();
|
||||||
|
|||||||
@ -20,12 +20,6 @@ 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();
|
||||||
@ -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();
|
||||||
|
|
||||||
if (dimmed)
|
|
||||||
{
|
|
||||||
_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);
|
_fillBrush.Color = new Color(100, r, g, b);
|
||||||
_penBrush.Color = new Color(255, 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);
|
||||||
|
|||||||
@ -32,8 +32,7 @@
|
|||||||
SimpleNumberFormat="{CompiledBinding $parent[sharedControls:DraggableNumberBox].SimpleNumberFormat}"
|
SimpleNumberFormat="{CompiledBinding $parent[sharedControls:DraggableNumberBox].SimpleNumberFormat}"
|
||||||
attachedProperties:NumberBoxAssist.PrefixText="{CompiledBinding $parent[sharedControls:DraggableNumberBox].Prefix}"
|
attachedProperties:NumberBoxAssist.PrefixText="{CompiledBinding $parent[sharedControls:DraggableNumberBox].Prefix}"
|
||||||
attachedProperties:NumberBoxAssist.SuffixText="{CompiledBinding $parent[sharedControls:DraggableNumberBox].Suffix}"
|
attachedProperties:NumberBoxAssist.SuffixText="{CompiledBinding $parent[sharedControls:DraggableNumberBox].Suffix}"
|
||||||
HorizontalAlignment="{CompiledBinding $parent[sharedControls:DraggableNumberBox].HorizontalAlignment}"
|
HorizontalAlignment="{CompiledBinding $parent[sharedControls:DraggableNumberBox].HorizontalAlignment}"/>
|
||||||
ValueChanged="NumberBox_OnValueChanged"/>
|
|
||||||
<Rectangle Name="DragCollider" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Fill="Transparent"></Rectangle>
|
<Rectangle Name="DragCollider" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Fill="Transparent"></Rectangle>
|
||||||
</Panel>
|
</Panel>
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@ using Avalonia.Controls;
|
|||||||
using Avalonia.Data;
|
using Avalonia.Data;
|
||||||
using Avalonia.Input;
|
using Avalonia.Input;
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.LogicalTree;
|
||||||
using Avalonia.VisualTree;
|
using Avalonia.VisualTree;
|
||||||
using FluentAvalonia.Core;
|
using FluentAvalonia.Core;
|
||||||
using FluentAvalonia.UI.Controls;
|
using FluentAvalonia.UI.Controls;
|
||||||
@ -68,7 +68,6 @@ public partial class DraggableNumberBox : UserControl
|
|||||||
public DraggableNumberBox()
|
public DraggableNumberBox()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
InnerNumberBox.Value = Value;
|
|
||||||
|
|
||||||
PointerPressed += OnPointerPressed;
|
PointerPressed += OnPointerPressed;
|
||||||
PointerMoved += OnPointerMoved;
|
PointerMoved += OnPointerMoved;
|
||||||
@ -160,6 +159,21 @@ public partial class DraggableNumberBox : UserControl
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public event TypedEventHandler<DraggableNumberBox, EventArgs>? DragFinished;
|
public event TypedEventHandler<DraggableNumberBox, EventArgs>? DragFinished;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
|
||||||
|
{
|
||||||
|
InnerNumberBox.Value = Value;
|
||||||
|
InnerNumberBox.ValueChanged += InnerNumberBoxOnValueChanged;
|
||||||
|
base.OnAttachedToLogicalTree(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
|
||||||
|
{
|
||||||
|
InnerNumberBox.ValueChanged -= InnerNumberBoxOnValueChanged;
|
||||||
|
base.OnDetachedFromLogicalTree(e);
|
||||||
|
}
|
||||||
|
|
||||||
private void SetNumberBoxValue(double value)
|
private void SetNumberBoxValue(double value)
|
||||||
{
|
{
|
||||||
if (!(Math.Abs(InnerNumberBox.Value - Value) > 0.00001))
|
if (!(Math.Abs(InnerNumberBox.Value - Value) > 0.00001))
|
||||||
@ -250,7 +264,7 @@ public partial class DraggableNumberBox : UserControl
|
|||||||
SetNumberBoxValue(Value);
|
SetNumberBoxValue(Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void NumberBox_OnValueChanged(NumberBox sender, NumberBoxValueChangedEventArgs args)
|
private void InnerNumberBoxOnValueChanged(NumberBox sender, NumberBoxValueChangedEventArgs args)
|
||||||
{
|
{
|
||||||
if (_updating)
|
if (_updating)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -78,6 +78,6 @@ public class OpenFileDialogBuilder
|
|||||||
public async Task<string[]?> ShowAsync()
|
public async Task<string[]?> ShowAsync()
|
||||||
{
|
{
|
||||||
IReadOnlyList<IStorageFile> files = await _parent.StorageProvider.OpenFilePickerAsync(_options);
|
IReadOnlyList<IStorageFile> files = await _parent.StorageProvider.OpenFilePickerAsync(_options);
|
||||||
return files.Select(f => f.Path.LocalPath).ToArray();
|
return files.Count == 0 ? null : files.Select(f => f.Path.LocalPath).ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
using System.Reactive.Linq;
|
using System.Reactive.Linq;
|
||||||
@ -193,7 +194,7 @@ public abstract class PropertyInputViewModel<T> : PropertyInputViewModel
|
|||||||
_updating = true;
|
_updating = true;
|
||||||
|
|
||||||
// Avoid unnecessary UI updates and validator cycles
|
// Avoid unnecessary UI updates and validator cycles
|
||||||
if (Equals(_inputValue, LayerProperty.CurrentValue))
|
if (EqualityComparer<T>.Default.Equals(_inputValue, LayerProperty.CurrentValue))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Override the input value
|
// Override the input value
|
||||||
|
|||||||
@ -32,8 +32,8 @@
|
|||||||
<PackageReference Include="Octopus.Octodiff" Version="2.0.261" />
|
<PackageReference Include="Octopus.Octodiff" Version="2.0.261" />
|
||||||
<PackageReference Include="ReactiveUI" Version="18.4.26" />
|
<PackageReference Include="ReactiveUI" Version="18.4.26" />
|
||||||
<PackageReference Include="ReactiveUI.Validation" Version="3.1.7" />
|
<PackageReference Include="ReactiveUI.Validation" Version="3.1.7" />
|
||||||
<PackageReference Include="RGB.NET.Core" Version="2.0.0-prerelease.53" />
|
<PackageReference Include="RGB.NET.Core" Version="2.0.0-prerelease.69" />
|
||||||
<PackageReference Include="RGB.NET.Layout" Version="2.0.0-prerelease.53" />
|
<PackageReference Include="RGB.NET.Layout" Version="2.0.0-prerelease.69" />
|
||||||
<PackageReference Include="SkiaSharp" Version="2.88.3" />
|
<PackageReference Include="SkiaSharp" Version="2.88.3" />
|
||||||
<PackageReference Include="Splat.DryIoc" Version="14.6.8" />
|
<PackageReference Include="Splat.DryIoc" Version="14.6.8" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@ -30,12 +30,12 @@
|
|||||||
</VisualBrush>
|
</VisualBrush>
|
||||||
</Grid.Background>
|
</Grid.Background>
|
||||||
<Grid Grid.Column="0" Name="DeviceDisplayGrid" PointerReleased="DeviceDisplayGrid_OnPointerReleased">
|
<Grid Grid.Column="0" Name="DeviceDisplayGrid" PointerReleased="DeviceDisplayGrid_OnPointerReleased">
|
||||||
<!-- No need to provide LEDs to highlight as LEDs are already physically highlighted -->
|
|
||||||
<shared:DeviceVisualizer Device="{CompiledBinding Device}"
|
<shared:DeviceVisualizer Device="{CompiledBinding Device}"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
ShowColors="True"
|
ShowColors="True"
|
||||||
Margin="20"
|
Margin="20"
|
||||||
|
RenderOptions.BitmapInterpolationMode="MediumQuality"
|
||||||
LedClicked="DeviceVisualizer_OnLedClicked"
|
LedClicked="DeviceVisualizer_OnLedClicked"
|
||||||
Clicked="DeviceVisualizer_OnClicked" />
|
Clicked="DeviceVisualizer_OnClicked" />
|
||||||
|
|
||||||
|
|||||||
@ -18,7 +18,7 @@
|
|||||||
Margin="10"
|
Margin="10"
|
||||||
ShowColors="False"
|
ShowColors="False"
|
||||||
Device="{CompiledBinding Device}"
|
Device="{CompiledBinding Device}"
|
||||||
RenderOptions.BitmapInterpolationMode="HighQuality" />
|
RenderOptions.BitmapInterpolationMode="MediumQuality" />
|
||||||
<Button Grid.Row="0"
|
<Button Grid.Row="0"
|
||||||
Classes="icon-button icon-button-large"
|
Classes="icon-button icon-button-large"
|
||||||
VerticalAlignment="Bottom"
|
VerticalAlignment="Bottom"
|
||||||
|
|||||||
@ -2,11 +2,11 @@
|
|||||||
using System.Reactive;
|
using System.Reactive;
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
using System.Reactive.Linq;
|
using System.Reactive.Linq;
|
||||||
|
using System.Timers;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
using Artemis.UI.Shared;
|
using Artemis.UI.Shared;
|
||||||
using Artemis.UI.Shared.Services.ProfileEditor;
|
using Artemis.UI.Shared.Services.ProfileEditor;
|
||||||
using Avalonia.Threading;
|
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.ProfileEditor.Playback;
|
namespace Artemis.UI.Screens.ProfileEditor.Playback;
|
||||||
@ -54,12 +54,16 @@ public class PlaybackViewModel : ActivatableViewModelBase
|
|||||||
_playing = _profileEditorService.Playing.ToProperty(this, vm => vm.Playing).DisposeWith(d);
|
_playing = _profileEditorService.Playing.ToProperty(this, vm => vm.Playing).DisposeWith(d);
|
||||||
_keyBindingsEnabled = Shared.UI.KeyBindingsEnabled.ToProperty(this, vm => vm.KeyBindingsEnabled).DisposeWith(d);
|
_keyBindingsEnabled = Shared.UI.KeyBindingsEnabled.ToProperty(this, vm => vm.KeyBindingsEnabled).DisposeWith(d);
|
||||||
|
|
||||||
|
// Update timer
|
||||||
|
Timer updateTimer = new(TimeSpan.FromMilliseconds(60.0 / 1000));
|
||||||
|
updateTimer.Elapsed += (_, _) => Update();
|
||||||
|
updateTimer.DisposeWith(d);
|
||||||
|
_profileEditorService.Playing.Subscribe(_ => _lastUpdate = DateTime.Now).DisposeWith(d);
|
||||||
|
_profileEditorService.Playing.Subscribe(p => updateTimer.Enabled = p).DisposeWith(d);
|
||||||
_lastUpdate = DateTime.MinValue;
|
_lastUpdate = DateTime.MinValue;
|
||||||
DispatcherTimer updateTimer = new(TimeSpan.FromMilliseconds(60.0 / 1000), DispatcherPriority.Background, Update);
|
|
||||||
updateTimer.Start();
|
|
||||||
Disposable.Create(() =>
|
Disposable.Create(() =>
|
||||||
{
|
{
|
||||||
updateTimer.Stop();
|
|
||||||
_settingsService.GetSetting("ProfileEditor.RepeatTimeline", true).Value = _repeating && _repeatTimeline;
|
_settingsService.GetSetting("ProfileEditor.RepeatTimeline", true).Value = _repeating && _repeatTimeline;
|
||||||
_settingsService.GetSetting("ProfileEditor.RepeatSegment", false).Value = _repeating && _repeatSegment;
|
_settingsService.GetSetting("ProfileEditor.RepeatSegment", false).Value = _repeating && _repeatSegment;
|
||||||
}).DisposeWith(d);
|
}).DisposeWith(d);
|
||||||
@ -206,13 +210,10 @@ public class PlaybackViewModel : ActivatableViewModelBase
|
|||||||
return TimeSpan.Zero;
|
return TimeSpan.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update(object? sender, EventArgs e)
|
private void Update()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!Playing)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (_lastUpdate == DateTime.MinValue)
|
if (_lastUpdate == DateTime.MinValue)
|
||||||
_lastUpdate = DateTime.Now;
|
_lastUpdate = DateTime.Now;
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
using System.Reactive.Linq;
|
using System.Reactive.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Timers;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
using Artemis.UI.DryIoc.Factories;
|
using Artemis.UI.DryIoc.Factories;
|
||||||
@ -50,20 +51,16 @@ public class DataBindingViewModel : ActivatableViewModelBase
|
|||||||
.DisposeWith(d);
|
.DisposeWith(d);
|
||||||
_profileEditorService.Playing.CombineLatest(_profileEditorService.SuspendedEditing).Subscribe(tuple => _playing = tuple.First || tuple.Second).DisposeWith(d);
|
_profileEditorService.Playing.CombineLatest(_profileEditorService.SuspendedEditing).Subscribe(tuple => _playing = tuple.First || tuple.Second).DisposeWith(d);
|
||||||
|
|
||||||
DispatcherTimer updateTimer = new(TimeSpan.FromMilliseconds(25.0 / 1000), DispatcherPriority.Background, Update);
|
Timer updateTimer = new(TimeSpan.FromMilliseconds(25.0 / 1000));
|
||||||
// TODO: Remove in favor of saving each time a node editor command is executed
|
Timer saveTimer = new(TimeSpan.FromMinutes(2));
|
||||||
DispatcherTimer saveTimer = new(TimeSpan.FromMinutes(2), DispatcherPriority.Normal, Save);
|
|
||||||
|
|
||||||
|
updateTimer.Elapsed += (_, _) => Update();
|
||||||
|
saveTimer.Elapsed += (_, _) => Save();
|
||||||
updateTimer.Start();
|
updateTimer.Start();
|
||||||
saveTimer.Start();
|
saveTimer.Start();
|
||||||
|
|
||||||
Disposable.Create(() =>
|
updateTimer.DisposeWith(d);
|
||||||
{
|
saveTimer.DisposeWith(d);
|
||||||
updateTimer.Stop();
|
|
||||||
saveTimer.Stop();
|
|
||||||
|
|
||||||
_profileEditorService.SaveProfile();
|
|
||||||
}).DisposeWith(d);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +94,7 @@ public class DataBindingViewModel : ActivatableViewModelBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update(object? sender, EventArgs e)
|
private void Update()
|
||||||
{
|
{
|
||||||
// If playing the data binding will already be updated, no need to do it here
|
// If playing the data binding will already be updated, no need to do it here
|
||||||
if (_playing || !_alwaysApplyDataBindings.Value)
|
if (_playing || !_alwaysApplyDataBindings.Value)
|
||||||
@ -106,7 +103,7 @@ public class DataBindingViewModel : ActivatableViewModelBase
|
|||||||
LayerProperty?.UpdateDataBinding();
|
LayerProperty?.UpdateDataBinding();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Save(object? sender, EventArgs e)
|
private void Save()
|
||||||
{
|
{
|
||||||
if (!_editorOpen)
|
if (!_editorOpen)
|
||||||
_profileEditorService.SaveProfile();
|
_profileEditorService.SaveProfile();
|
||||||
|
|||||||
@ -53,7 +53,7 @@
|
|||||||
</ItemsControl.ItemsPanel>
|
</ItemsControl.ItemsPanel>
|
||||||
<ItemsControl.ItemTemplate>
|
<ItemsControl.ItemTemplate>
|
||||||
<DataTemplate DataType="core:ArtemisDevice">
|
<DataTemplate DataType="core:ArtemisDevice">
|
||||||
<shared:DeviceVisualizer Device="{CompiledBinding}" ShowColors="True" RenderOptions.BitmapInterpolationMode="HighQuality" />
|
<shared:DeviceVisualizer Device="{CompiledBinding}" ShowColors="True" RenderOptions.BitmapInterpolationMode="MediumQuality" />
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ItemsControl.ItemTemplate>
|
</ItemsControl.ItemTemplate>
|
||||||
</ItemsControl>
|
</ItemsControl>
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
|
using System.Timers;
|
||||||
using Artemis.Core.Modules;
|
using Artemis.Core.Modules;
|
||||||
using Artemis.UI.Shared;
|
using Artemis.UI.Shared;
|
||||||
using Avalonia.Threading;
|
|
||||||
using Humanizer;
|
using Humanizer;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
|
|
||||||
@ -13,7 +13,6 @@ public class ModuleActivationRequirementViewModel : ActivatableViewModelBase
|
|||||||
private readonly IModuleActivationRequirement _activationRequirement;
|
private readonly IModuleActivationRequirement _activationRequirement;
|
||||||
private string _requirementDescription;
|
private string _requirementDescription;
|
||||||
private bool _requirementMet;
|
private bool _requirementMet;
|
||||||
private DispatcherTimer? _updateTimer;
|
|
||||||
|
|
||||||
public ModuleActivationRequirementViewModel(IModuleActivationRequirement activationRequirement)
|
public ModuleActivationRequirementViewModel(IModuleActivationRequirement activationRequirement)
|
||||||
{
|
{
|
||||||
@ -23,14 +22,10 @@ public class ModuleActivationRequirementViewModel : ActivatableViewModelBase
|
|||||||
|
|
||||||
this.WhenActivated(d =>
|
this.WhenActivated(d =>
|
||||||
{
|
{
|
||||||
_updateTimer = new DispatcherTimer(TimeSpan.FromMilliseconds(500), DispatcherPriority.Background, Update);
|
Timer updateTimer = new(TimeSpan.FromMilliseconds(500));
|
||||||
_updateTimer.Start();
|
updateTimer.Elapsed += (_, _) => Update();
|
||||||
|
updateTimer.Start();
|
||||||
Disposable.Create(() =>
|
updateTimer.DisposeWith(d);
|
||||||
{
|
|
||||||
_updateTimer?.Stop();
|
|
||||||
_updateTimer = null;
|
|
||||||
}).DisposeWith(d);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +43,7 @@ public class ModuleActivationRequirementViewModel : ActivatableViewModelBase
|
|||||||
set => RaiseAndSetIfChanged(ref _requirementMet, value);
|
set => RaiseAndSetIfChanged(ref _requirementMet, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update(object? sender, EventArgs e)
|
private void Update()
|
||||||
{
|
{
|
||||||
RequirementDescription = _activationRequirement.GetUserFriendlyDescription();
|
RequirementDescription = _activationRequirement.GetUserFriendlyDescription();
|
||||||
RequirementMet = _activationRequirement.Evaluate();
|
RequirementMet = _activationRequirement.Evaluate();
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
x:DataType="surfaceEditor:ListDeviceViewModel">
|
x:DataType="surfaceEditor:ListDeviceViewModel">
|
||||||
<Grid ColumnDefinitions="Auto,*,Auto" RowDefinitions="*,*">
|
<Grid ColumnDefinitions="Auto,*,Auto" RowDefinitions="*,*">
|
||||||
<Border Grid.Column="0" Grid.RowSpan="2" Width="64" Height="50" Margin="0 0 10 0">
|
<Border Grid.Column="0" Grid.RowSpan="2" Width="64" Height="50" Margin="0 0 10 0">
|
||||||
<shared:DeviceVisualizer Device="{CompiledBinding Device}" ShowColors="True" VerticalAlignment="Center" HorizontalAlignment="Center"/>
|
<shared:DeviceVisualizer Device="{CompiledBinding Device}" ShowColors="True" VerticalAlignment="Center" HorizontalAlignment="Center" RenderOptions.BitmapInterpolationMode="MediumQuality"/>
|
||||||
</Border>
|
</Border>
|
||||||
<TextBlock Grid.Column="1" Grid.Row="0" Text="{CompiledBinding Device.RgbDevice.DeviceInfo.DeviceName}" VerticalAlignment="Bottom" />
|
<TextBlock Grid.Column="1" Grid.Row="0" Text="{CompiledBinding Device.RgbDevice.DeviceInfo.DeviceName}" VerticalAlignment="Bottom" />
|
||||||
<TextBlock Grid.Column="1" Grid.Row="1" Classes="subtitle" Text="{CompiledBinding Device.RgbDevice.DeviceInfo.Manufacturer}" VerticalAlignment="Top" />
|
<TextBlock Grid.Column="1" Grid.Row="1" Classes="subtitle" Text="{CompiledBinding Device.RgbDevice.DeviceInfo.Manufacturer}" VerticalAlignment="Top" />
|
||||||
|
|||||||
@ -27,7 +27,7 @@
|
|||||||
</Style>
|
</Style>
|
||||||
</Grid.Styles>
|
</Grid.Styles>
|
||||||
|
|
||||||
<shared:DeviceVisualizer Device="{CompiledBinding Device}" ShowColors="True" RenderOptions.BitmapInterpolationMode="HighQuality"/>
|
<shared:DeviceVisualizer Device="{CompiledBinding Device}" ShowColors="True" RenderOptions.BitmapInterpolationMode="MediumQuality"/>
|
||||||
<Border x:Name="SurfaceDeviceBorder"
|
<Border x:Name="SurfaceDeviceBorder"
|
||||||
Classes="selection-border"
|
Classes="selection-border"
|
||||||
Classes.selected="{CompiledBinding IsSelected}"
|
Classes.selected="{CompiledBinding IsSelected}"
|
||||||
|
|||||||
@ -5,6 +5,7 @@ using System.IO;
|
|||||||
using System.Reactive;
|
using System.Reactive;
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Timers;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
using Artemis.UI.DryIoc.Factories;
|
using Artemis.UI.DryIoc.Factories;
|
||||||
@ -12,9 +13,7 @@ using Artemis.UI.Shared.Services;
|
|||||||
using Artemis.UI.Shared.Services.NodeEditor;
|
using Artemis.UI.Shared.Services.NodeEditor;
|
||||||
using Artemis.UI.Shared.Services.NodeEditor.Commands;
|
using Artemis.UI.Shared.Services.NodeEditor.Commands;
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Threading;
|
|
||||||
using DynamicData;
|
using DynamicData;
|
||||||
using DynamicData.List;
|
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.VisualScripting;
|
namespace Artemis.UI.Screens.VisualScripting;
|
||||||
@ -67,18 +66,16 @@ public class NodeScriptWindowViewModel : NodeScriptWindowViewModelBase
|
|||||||
{
|
{
|
||||||
_keyBindingsEnabled = Shared.UI.KeyBindingsEnabled.ToProperty(this, vm => vm.KeyBindingsEnabled).DisposeWith(d);
|
_keyBindingsEnabled = Shared.UI.KeyBindingsEnabled.ToProperty(this, vm => vm.KeyBindingsEnabled).DisposeWith(d);
|
||||||
|
|
||||||
DispatcherTimer updateTimer = new(TimeSpan.FromMilliseconds(25.0 / 1000), DispatcherPriority.Background, Update);
|
Timer updateTimer = new(TimeSpan.FromMilliseconds(25.0 / 1000));
|
||||||
// TODO: Remove in favor of saving each time a node editor command is executed
|
Timer saveTimer = new(TimeSpan.FromMinutes(2));
|
||||||
DispatcherTimer saveTimer = new(TimeSpan.FromMinutes(2), DispatcherPriority.Background, Save);
|
|
||||||
|
|
||||||
|
updateTimer.Elapsed += (_, _) => Update();
|
||||||
|
saveTimer.Elapsed += (_, _) => Save();
|
||||||
updateTimer.Start();
|
updateTimer.Start();
|
||||||
saveTimer.Start();
|
saveTimer.Start();
|
||||||
|
|
||||||
Disposable.Create(() =>
|
updateTimer.DisposeWith(d);
|
||||||
{
|
saveTimer.DisposeWith(d);
|
||||||
updateTimer.Stop();
|
|
||||||
saveTimer.Stop();
|
|
||||||
}).DisposeWith(d);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +154,7 @@ public class NodeScriptWindowViewModel : NodeScriptWindowViewModelBase
|
|||||||
.HavingFilter(f => f.WithExtension("json").WithName("Artemis node script"))
|
.HavingFilter(f => f.WithExtension("json").WithName("Artemis node script"))
|
||||||
.ShowAsync();
|
.ShowAsync();
|
||||||
|
|
||||||
if (result == null)
|
if (result == null || result.Length == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try
|
try
|
||||||
@ -176,13 +173,13 @@ public class NodeScriptWindowViewModel : NodeScriptWindowViewModelBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update(object? sender, EventArgs e)
|
private void Update()
|
||||||
{
|
{
|
||||||
if (!_pauseUpdate)
|
if (!_pauseUpdate)
|
||||||
NodeScript.Run();
|
NodeScript.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Save(object? sender, EventArgs e)
|
private void Save()
|
||||||
{
|
{
|
||||||
if (NodeScript.Context is Profile profile)
|
if (NodeScript.Context is Profile profile)
|
||||||
_profileService.SaveProfile(profile, true);
|
_profileService.SaveProfile(profile, true);
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.UI.Shared.VisualScripting;
|
using Artemis.UI.Shared.VisualScripting;
|
||||||
using Avalonia.Threading;
|
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
|
|
||||||
namespace Artemis.VisualScripting.Nodes.Static.Screens;
|
namespace Artemis.VisualScripting.Nodes.Static.Screens;
|
||||||
@ -18,9 +17,10 @@ public class DisplayValueNodeCustomViewModel : CustomNodeViewModel
|
|||||||
// Because the DisplayValueNode has no output it never evaluates, manually do so here
|
// Because the DisplayValueNode has no output it never evaluates, manually do so here
|
||||||
this.WhenActivated(d =>
|
this.WhenActivated(d =>
|
||||||
{
|
{
|
||||||
DispatcherTimer updateTimer = new(TimeSpan.FromMilliseconds(25.0 / 1000), DispatcherPriority.Background, Update);
|
System.Timers.Timer updateTimer = new(TimeSpan.FromMilliseconds(25.0 / 1000));
|
||||||
|
updateTimer.Elapsed += (_, _) => Update();
|
||||||
updateTimer.Start();
|
updateTimer.Start();
|
||||||
Disposable.Create(() => updateTimer.Stop()).DisposeWith(d);
|
updateTimer.DisposeWith(d);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ public class DisplayValueNodeCustomViewModel : CustomNodeViewModel
|
|||||||
private set => this.RaiseAndSetIfChanged(ref _currentValue, value);
|
private set => this.RaiseAndSetIfChanged(ref _currentValue, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update(object? sender, EventArgs e)
|
private void Update()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user