1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-12 13:28:33 +00:00

Merge branch 'development'

This commit is contained in:
Robert 2023-05-22 20:54:29 +02:00
commit 9cfa45972d
20 changed files with 119 additions and 123 deletions

View File

@ -43,9 +43,9 @@
<PackageReference Include="LiteDB" Version="5.0.16" />
<PackageReference Include="McMaster.NETCore.Plugins" Version="1.4.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="RGB.NET.Core" Version="2.0.0-prerelease.53" />
<PackageReference Include="RGB.NET.Layout" Version="2.0.0-prerelease.53" />
<PackageReference Include="RGB.NET.Presets" 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.69" />
<PackageReference Include="RGB.NET.Presets" Version="2.0.0-prerelease.69" />
<PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.Debug" Version="2.0.0" />

View File

@ -396,7 +396,7 @@ internal class PluginManagementService : IPluginManagementService
List<Type> featureTypes;
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)
{

View File

@ -20,7 +20,7 @@
<PackageReference Include="Material.Icons.Avalonia" Version="2.0.0-preview3" />
<PackageReference Include="ReactiveUI" Version="18.4.26" />
<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" />
</ItemGroup>
<ItemGroup>

View File

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
@ -13,6 +12,10 @@ using Avalonia.LogicalTree;
using Avalonia.Media;
using Avalonia.Media.Imaging;
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;
@ -21,20 +24,20 @@ namespace Artemis.UI.Shared;
/// </summary>
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 DispatcherTimer _timer;
private Rect _deviceBounds;
private RenderTargetBitmap? _deviceImage;
private List<DeviceVisualizerLed>? _dimmedLeds;
private List<DeviceVisualizerLed>? _highlightedLeds;
private ArtemisDevice? _oldDevice;
private bool _loading;
private Color[] _previousState = Array.Empty<Color>();
/// <inheritdoc />
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>();
PointerReleased += OnPointerReleased;
@ -77,7 +80,7 @@ public class DeviceVisualizer : Control
// Apply device scale
using DrawingContext.PushedState scalePush = drawingContext.PushTransform(Matrix.CreateScale(Device.Scale, Device.Scale));
foreach (DeviceVisualizerLed deviceVisualizerLed in _deviceVisualizerLeds)
deviceVisualizerLed.RenderGeometry(drawingContext, false);
deviceVisualizerLed.RenderGeometry(drawingContext);
}
}
finally
@ -112,6 +115,31 @@ public class DeviceVisualizer : Control
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()
{
InvalidateVisual();
@ -131,7 +159,7 @@ public class DeviceVisualizer : Control
private void TimerOnTick(object? sender, EventArgs e)
{
if (ShowColors && IsVisible && Opacity > 0)
if (IsDirty() && ShowColors && IsVisible && Opacity > 0)
Update();
}
@ -200,23 +228,6 @@ public class DeviceVisualizer : Control
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
#region Lifetime management
@ -254,9 +265,6 @@ public class DeviceVisualizer : Control
private void SetupForDevice()
{
_highlightedLeds = new List<DeviceVisualizerLed>();
_dimmedLeds = new List<DeviceVisualizerLed>();
lock (_deviceVisualizerLeds)
{
_deviceVisualizerLeds.Clear();
@ -305,7 +313,7 @@ public class DeviceVisualizer : Control
using DrawingContext context = renderTargetBitmap.CreateDrawingContext();
using Bitmap bitmap = new(device.Layout.Image.LocalPath);
using Bitmap scaledBitmap = bitmap.CreateScaledBitmap(renderTargetBitmap.PixelSize);
context.DrawImage(scaledBitmap, new Rect(scaledBitmap.Size));
lock (_deviceVisualizerLeds)
{

View File

@ -20,13 +20,7 @@ internal class DeviceVisualizerLed
public DeviceVisualizerLed(ArtemisLed 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();
_penBrush = new SolidColorBrush();
_pen = new Pen(_penBrush) {LineJoin = PenLineJoin.Round};
@ -35,7 +29,6 @@ internal class DeviceVisualizerLed
}
public ArtemisLed Led { get; }
public Rect LedRect { get; set; }
public Geometry? DisplayGeometry { get; private set; }
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)
return;
@ -66,17 +59,8 @@ internal class DeviceVisualizerLed
byte r = Led.RgbLed.Color.GetR();
byte g = Led.RgbLed.Color.GetG();
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);
_penBrush.Color = new Color(255, r, g, b);
}
_fillBrush.Color = new Color(100, r, g, b);
_penBrush.Color = new Color(255, r, g, b);
// Render the LED geometry
drawingContext.DrawGeometry(_fillBrush, _pen, DisplayGeometry);

View File

@ -32,8 +32,7 @@
SimpleNumberFormat="{CompiledBinding $parent[sharedControls:DraggableNumberBox].SimpleNumberFormat}"
attachedProperties:NumberBoxAssist.PrefixText="{CompiledBinding $parent[sharedControls:DraggableNumberBox].Prefix}"
attachedProperties:NumberBoxAssist.SuffixText="{CompiledBinding $parent[sharedControls:DraggableNumberBox].Suffix}"
HorizontalAlignment="{CompiledBinding $parent[sharedControls:DraggableNumberBox].HorizontalAlignment}"
ValueChanged="NumberBox_OnValueChanged"/>
HorizontalAlignment="{CompiledBinding $parent[sharedControls:DraggableNumberBox].HorizontalAlignment}"/>
<Rectangle Name="DragCollider" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Fill="Transparent"></Rectangle>
</Panel>

View File

@ -4,7 +4,7 @@ using Avalonia.Controls;
using Avalonia.Data;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Avalonia.LogicalTree;
using Avalonia.VisualTree;
using FluentAvalonia.Core;
using FluentAvalonia.UI.Controls;
@ -68,13 +68,12 @@ public partial class DraggableNumberBox : UserControl
public DraggableNumberBox()
{
InitializeComponent();
InnerNumberBox.Value = Value;
PointerPressed += OnPointerPressed;
PointerMoved += OnPointerMoved;
PointerReleased += OnPointerReleased;
PropertyChanged += OnPropertyChanged;
AddHandler(KeyUpEvent, HandleKeyUp, RoutingStrategies.Direct | RoutingStrategies.Tunnel | RoutingStrategies.Bubble, true);
}
@ -159,7 +158,22 @@ public partial class DraggableNumberBox : UserControl
/// Occurs when the user finishes dragging over the control.
/// </summary>
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)
{
if (!(Math.Abs(InnerNumberBox.Value - Value) > 0.00001))
@ -243,14 +257,14 @@ public partial class DraggableNumberBox : UserControl
e.Handled = true;
}
private void OnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
{
if (e.Property == ValueProperty)
SetNumberBoxValue(Value);
}
private void NumberBox_OnValueChanged(NumberBox sender, NumberBoxValueChangedEventArgs args)
private void InnerNumberBoxOnValueChanged(NumberBox sender, NumberBoxValueChangedEventArgs args)
{
if (_updating)
return;

View File

@ -78,6 +78,6 @@ public class OpenFileDialogBuilder
public async Task<string[]?> ShowAsync()
{
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();
}
}

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Reactive.Disposables;
using System.Reactive.Linq;
@ -193,7 +194,7 @@ public abstract class PropertyInputViewModel<T> : PropertyInputViewModel
_updating = true;
// Avoid unnecessary UI updates and validator cycles
if (Equals(_inputValue, LayerProperty.CurrentValue))
if (EqualityComparer<T>.Default.Equals(_inputValue, LayerProperty.CurrentValue))
return;
// Override the input value

View File

@ -32,8 +32,8 @@
<PackageReference Include="Octopus.Octodiff" Version="2.0.261" />
<PackageReference Include="ReactiveUI" Version="18.4.26" />
<PackageReference Include="ReactiveUI.Validation" Version="3.1.7" />
<PackageReference Include="RGB.NET.Core" Version="2.0.0-prerelease.53" />
<PackageReference Include="RGB.NET.Layout" 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.69" />
<PackageReference Include="SkiaSharp" Version="2.88.3" />
<PackageReference Include="Splat.DryIoc" Version="14.6.8" />
</ItemGroup>

View File

@ -30,12 +30,12 @@
</VisualBrush>
</Grid.Background>
<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}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
ShowColors="True"
Margin="20"
RenderOptions.BitmapInterpolationMode="MediumQuality"
LedClicked="DeviceVisualizer_OnLedClicked"
Clicked="DeviceVisualizer_OnClicked" />

View File

@ -18,7 +18,7 @@
Margin="10"
ShowColors="False"
Device="{CompiledBinding Device}"
RenderOptions.BitmapInterpolationMode="HighQuality" />
RenderOptions.BitmapInterpolationMode="MediumQuality" />
<Button Grid.Row="0"
Classes="icon-button icon-button-large"
VerticalAlignment="Bottom"

View File

@ -2,11 +2,11 @@
using System.Reactive;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Timers;
using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Services.ProfileEditor;
using Avalonia.Threading;
using ReactiveUI;
namespace Artemis.UI.Screens.ProfileEditor.Playback;
@ -53,13 +53,17 @@ public class PlaybackViewModel : ActivatableViewModelBase
_formattedCurrentTime = _profileEditorService.Time.Select(t => $"{Math.Floor(t.TotalSeconds):00}.{t.Milliseconds:000}").ToProperty(this, vm => vm.FormattedCurrentTime).DisposeWith(d);
_playing = _profileEditorService.Playing.ToProperty(this, vm => vm.Playing).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;
DispatcherTimer updateTimer = new(TimeSpan.FromMilliseconds(60.0 / 1000), DispatcherPriority.Background, Update);
updateTimer.Start();
Disposable.Create(() =>
{
updateTimer.Stop();
_settingsService.GetSetting("ProfileEditor.RepeatTimeline", true).Value = _repeating && _repeatTimeline;
_settingsService.GetSetting("ProfileEditor.RepeatSegment", false).Value = _repeating && _repeatSegment;
}).DisposeWith(d);
@ -206,13 +210,10 @@ public class PlaybackViewModel : ActivatableViewModelBase
return TimeSpan.Zero;
}
private void Update(object? sender, EventArgs e)
private void Update()
{
try
{
if (!Playing)
return;
if (_lastUpdate == DateTime.MinValue)
_lastUpdate = DateTime.Now;

View File

@ -2,6 +2,7 @@
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Threading.Tasks;
using System.Timers;
using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.DryIoc.Factories;
@ -50,20 +51,16 @@ public class DataBindingViewModel : ActivatableViewModelBase
.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);
// TODO: Remove in favor of saving each time a node editor command is executed
DispatcherTimer saveTimer = new(TimeSpan.FromMinutes(2), DispatcherPriority.Normal, Save);
Timer updateTimer = new(TimeSpan.FromMilliseconds(25.0 / 1000));
Timer saveTimer = new(TimeSpan.FromMinutes(2));
updateTimer.Elapsed += (_, _) => Update();
saveTimer.Elapsed += (_, _) => Save();
updateTimer.Start();
saveTimer.Start();
Disposable.Create(() =>
{
updateTimer.Stop();
saveTimer.Stop();
_profileEditorService.SaveProfile();
}).DisposeWith(d);
updateTimer.DisposeWith(d);
saveTimer.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 || !_alwaysApplyDataBindings.Value)
@ -106,7 +103,7 @@ public class DataBindingViewModel : ActivatableViewModelBase
LayerProperty?.UpdateDataBinding();
}
private void Save(object? sender, EventArgs e)
private void Save()
{
if (!_editorOpen)
_profileEditorService.SaveProfile();

View File

@ -53,7 +53,7 @@
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="core:ArtemisDevice">
<shared:DeviceVisualizer Device="{CompiledBinding}" ShowColors="True" RenderOptions.BitmapInterpolationMode="HighQuality" />
<shared:DeviceVisualizer Device="{CompiledBinding}" ShowColors="True" RenderOptions.BitmapInterpolationMode="MediumQuality" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

View File

@ -1,8 +1,8 @@
using System;
using System.Reactive.Disposables;
using System.Timers;
using Artemis.Core.Modules;
using Artemis.UI.Shared;
using Avalonia.Threading;
using Humanizer;
using ReactiveUI;
@ -13,7 +13,6 @@ public class ModuleActivationRequirementViewModel : ActivatableViewModelBase
private readonly IModuleActivationRequirement _activationRequirement;
private string _requirementDescription;
private bool _requirementMet;
private DispatcherTimer? _updateTimer;
public ModuleActivationRequirementViewModel(IModuleActivationRequirement activationRequirement)
{
@ -23,14 +22,10 @@ public class ModuleActivationRequirementViewModel : ActivatableViewModelBase
this.WhenActivated(d =>
{
_updateTimer = new DispatcherTimer(TimeSpan.FromMilliseconds(500), DispatcherPriority.Background, Update);
_updateTimer.Start();
Disposable.Create(() =>
{
_updateTimer?.Stop();
_updateTimer = null;
}).DisposeWith(d);
Timer updateTimer = new(TimeSpan.FromMilliseconds(500));
updateTimer.Elapsed += (_, _) => Update();
updateTimer.Start();
updateTimer.DisposeWith(d);
});
}
@ -48,7 +43,7 @@ public class ModuleActivationRequirementViewModel : ActivatableViewModelBase
set => RaiseAndSetIfChanged(ref _requirementMet, value);
}
private void Update(object? sender, EventArgs e)
private void Update()
{
RequirementDescription = _activationRequirement.GetUserFriendlyDescription();
RequirementMet = _activationRequirement.Evaluate();

View File

@ -9,7 +9,7 @@
x:DataType="surfaceEditor:ListDeviceViewModel">
<Grid ColumnDefinitions="Auto,*,Auto" RowDefinitions="*,*">
<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>
<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" />

View File

@ -27,7 +27,7 @@
</Style>
</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"
Classes="selection-border"
Classes.selected="{CompiledBinding IsSelected}"

View File

@ -5,6 +5,7 @@ using System.IO;
using System.Reactive;
using System.Reactive.Disposables;
using System.Threading.Tasks;
using System.Timers;
using Artemis.Core;
using Artemis.Core.Services;
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.Commands;
using Avalonia;
using Avalonia.Threading;
using DynamicData;
using DynamicData.List;
using ReactiveUI;
namespace Artemis.UI.Screens.VisualScripting;
@ -66,19 +65,17 @@ public class NodeScriptWindowViewModel : NodeScriptWindowViewModelBase
this.WhenActivated(d =>
{
_keyBindingsEnabled = Shared.UI.KeyBindingsEnabled.ToProperty(this, vm => vm.KeyBindingsEnabled).DisposeWith(d);
DispatcherTimer updateTimer = new(TimeSpan.FromMilliseconds(25.0 / 1000), DispatcherPriority.Background, Update);
// TODO: Remove in favor of saving each time a node editor command is executed
DispatcherTimer saveTimer = new(TimeSpan.FromMinutes(2), DispatcherPriority.Background, Save);
Timer updateTimer = new(TimeSpan.FromMilliseconds(25.0 / 1000));
Timer saveTimer = new(TimeSpan.FromMinutes(2));
updateTimer.Elapsed += (_, _) => Update();
saveTimer.Elapsed += (_, _) => Save();
updateTimer.Start();
saveTimer.Start();
Disposable.Create(() =>
{
updateTimer.Stop();
saveTimer.Stop();
}).DisposeWith(d);
updateTimer.DisposeWith(d);
saveTimer.DisposeWith(d);
});
}
@ -93,7 +90,7 @@ public class NodeScriptWindowViewModel : NodeScriptWindowViewModelBase
public ReactiveCommand<Unit, Unit> Export { get; }
public ReactiveCommand<Unit, Unit> Import { get; }
public bool KeyBindingsEnabled => _keyBindingsEnabled?.Value ?? false;
public PluginSetting<bool> ShowDataModelValues => _settingsService.GetSetting("ProfileEditor.ShowDataModelValues", false);
public PluginSetting<bool> ShowFullPaths => _settingsService.GetSetting("ProfileEditor.ShowFullPaths", false);
public PluginSetting<bool> AlwaysShowValues => _settingsService.GetSetting("ProfileEditor.AlwaysShowValues", true);
@ -157,7 +154,7 @@ public class NodeScriptWindowViewModel : NodeScriptWindowViewModelBase
.HavingFilter(f => f.WithExtension("json").WithName("Artemis node script"))
.ShowAsync();
if (result == null)
if (result == null || result.Length == 0)
return;
try
@ -176,13 +173,13 @@ public class NodeScriptWindowViewModel : NodeScriptWindowViewModelBase
}
}
private void Update(object? sender, EventArgs e)
private void Update()
{
if (!_pauseUpdate)
NodeScript.Run();
}
private void Save(object? sender, EventArgs e)
private void Save()
{
if (NodeScript.Context is Profile profile)
_profileService.SaveProfile(profile, true);

View File

@ -1,7 +1,6 @@
using System.Reactive.Disposables;
using Artemis.Core;
using Artemis.UI.Shared.VisualScripting;
using Avalonia.Threading;
using ReactiveUI;
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
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();
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 void Update(object? sender, EventArgs e)
private void Update()
{
try
{