diff --git a/src/Artemis.ConsoleUI/packages.lock.json b/src/Artemis.ConsoleUI/packages.lock.json
index 2c3004e65..45239c58c 100644
--- a/src/Artemis.ConsoleUI/packages.lock.json
+++ b/src/Artemis.ConsoleUI/packages.lock.json
@@ -74,47 +74,10 @@
"System.Xml.XmlDocument": "4.3.0"
}
},
- "EmbedIO": {
- "type": "Transitive",
- "resolved": "3.4.3",
- "contentHash": "YM6hpZNAfvbbixfG9T4lWDGfF0D/TqutbTROL4ogVcHKwPF1hp+xS3ABwd3cxxTxvDFkj/zZl57QgWuFA8Igxw==",
- "dependencies": {
- "Unosquare.Swan.Lite": "3.0.0"
- }
- },
- "HidSharp": {
- "type": "Transitive",
- "resolved": "2.1.0",
- "contentHash": "UTdxWvbgp2xzT1Ajaa2va+Qi3oNHJPasYmVhbKI2VVdu1VYP6yUG+RikhsHvpD7iM0S8e8UYb5Qm/LTWxx9QAA=="
- },
- "LiteDB": {
- "type": "Transitive",
- "resolved": "5.0.11",
- "contentHash": "6cL4bOmVCUB0gIK+6qIr68HeqjjHZicPDGQjvJ87mIOvkFsEsJWkIps3yoKNeLpHhJQur++yoQ9Q8gxsdos0xQ=="
- },
- "McMaster.NETCore.Plugins": {
- "type": "Transitive",
- "resolved": "1.4.0",
- "contentHash": "UKw5Z2/QHhkR7kiAJmqdCwVDMQV0lwsfj10+FG676r8DsJWIpxtachtEjE0qBs9WoK5GUQIqxgyFeYUSwuPszg==",
- "dependencies": {
- "Microsoft.DotNet.PlatformAbstractions": "3.1.6",
- "Microsoft.Extensions.DependencyModel": "5.0.0"
- }
- },
- "Microsoft.DotNet.PlatformAbstractions": {
- "type": "Transitive",
- "resolved": "3.1.6",
- "contentHash": "jek4XYaQ/PGUwDKKhwR8K47Uh1189PFzMeLqO83mXrXQVIpARZCcfuDedH50YDTepBkfijCZN5U/vZi++erxtg=="
- },
- "Microsoft.Extensions.DependencyModel": {
- "type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "umBECCoMC+sOUgm083yFr8SxTobUOcPFH4AXigdO2xJiszCHAnmeDl4qPphJt+oaJ/XIfV1wOjIts2nRnki61Q=="
- },
"Microsoft.NETCore.Platforms": {
"type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "VyPlqzH2wavqquTcYpkIIAQ6WdenuKoFN0BdYBbCWsclXacSOHNQn66Gt4z5NBqEYW0FAPm5rlvki9ZiCij5xQ=="
+ "resolved": "1.1.0",
+ "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A=="
},
"Microsoft.NETCore.Targets": {
"type": "Transitive",
@@ -182,19 +145,6 @@
"System.Xml.XDocument": "4.3.0"
}
},
- "Newtonsoft.Json": {
- "type": "Transitive",
- "resolved": "13.0.1",
- "contentHash": "ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A=="
- },
- "Ninject.Extensions.ChildKernel": {
- "type": "Transitive",
- "resolved": "3.3.0",
- "contentHash": "vl/p3f8sIaCCHiKsjhq9R8n3bH705Hu1WJXNpMEz1UC79EV51Mk5TWYXQbRnsK20hxF48CiAgUBb9pMKfX6sLw==",
- "dependencies": {
- "Ninject": "3.3.4"
- }
- },
"Ninject.Extensions.Factory": {
"type": "Transitive",
"resolved": "3.3.2",
@@ -204,27 +154,6 @@
"Ninject": "3.3.3"
}
},
- "RGB.NET.Core": {
- "type": "Transitive",
- "resolved": "1.0.0-prerelease7",
- "contentHash": "IIja5sC4QZ5pbSNckRCG7TlY4U6j/dRbrl4e2FZqsTGgsevaVB3IqonUQLFY1GGst4xNSl2oh0A23coXQxXGbQ=="
- },
- "RGB.NET.Layout": {
- "type": "Transitive",
- "resolved": "1.0.0-prerelease7",
- "contentHash": "S0kfWVa8EfMOAl2WPHsq98dwaO+SNz9TWr1AtMkdo8aZuYIVhaJ1c+mSAMMnH1V+mSbxDWPHWkNzi9ITszJucA==",
- "dependencies": {
- "RGB.NET.Core": "1.0.0-prerelease7"
- }
- },
- "RGB.NET.Presets": {
- "type": "Transitive",
- "resolved": "1.0.0-prerelease7",
- "contentHash": "NgShvOPQM0miOsdqMKjkNunngJUZMwr8KR8ME2/Ksir7wgIQfgJj1YwZy8aIj+ar7fDo6VZJZenAshs/Ul+04A==",
- "dependencies": {
- "RGB.NET.Core": "1.0.0-prerelease7"
- }
- },
"runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.0",
@@ -332,38 +261,6 @@
"resolved": "4.3.0",
"contentHash": "VB5cn/7OzUfzdnC8tqAIMQciVLiq2epm2NrAm1E9OjNRyG4lVhfR61SMcLizejzQP8R8Uf/0l5qOIbUEi+RdEg=="
},
- "Serilog.Sinks.Console": {
- "type": "Transitive",
- "resolved": "4.0.0",
- "contentHash": "yJQit9sTJ4xGLKgCujqDJsaGqBNJwGB/H898z+xYlMG06twy4//6LLnSrsmpduZxcHIG4im7cv+JmXLzXz2EkQ==",
- "dependencies": {
- "Serilog": "2.10.0"
- }
- },
- "Serilog.Sinks.Debug": {
- "type": "Transitive",
- "resolved": "2.0.0",
- "contentHash": "Y6g3OBJ4JzTyyw16fDqtFcQ41qQAydnEvEqmXjhwhgjsnG/FaJ8GUqF5ldsC/bVkK8KYmqrPhDO+tm4dF6xx4A==",
- "dependencies": {
- "Serilog": "2.10.0"
- }
- },
- "Serilog.Sinks.File": {
- "type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "uwV5hdhWPwUH1szhO8PJpFiahqXmzPzJT/sOijH/kFgUx+cyoDTMM8MHD0adw9+Iem6itoibbUXHYslzXsLEAg==",
- "dependencies": {
- "Serilog": "2.10.0"
- }
- },
- "SkiaSharp": {
- "type": "Transitive",
- "resolved": "2.80.3",
- "contentHash": "qX6tGNP3+MXNYe2pKm0PCRiJ/cx+LTeLaggwZifB7sUMXhECfKKKHJq45VqZKt37xQegnCCdf1jHXwmHeJQs5Q==",
- "dependencies": {
- "System.Memory": "4.5.3"
- }
- },
"System.AppContext": {
"type": "Transitive",
"resolved": "4.3.0",
@@ -656,15 +553,6 @@
"System.Threading.Tasks": "4.3.0"
}
},
- "System.IO.FileSystem.AccessControl": {
- "type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "SxHB3nuNrpptVk+vZ/F+7OHEpoHUIKKMl02bUmYHQr1r+glbZQxs7pRtsf4ENO29TVm2TH3AEeep2fJcy92oYw==",
- "dependencies": {
- "System.Security.AccessControl": "5.0.0",
- "System.Security.Principal.Windows": "5.0.0"
- }
- },
"System.IO.FileSystem.Primitives": {
"type": "Transitive",
"resolved": "4.3.0",
@@ -709,11 +597,6 @@
"System.Threading": "4.3.0"
}
},
- "System.Memory": {
- "type": "Transitive",
- "resolved": "4.5.3",
- "contentHash": "3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA=="
- },
"System.Net.Http": {
"type": "Transitive",
"resolved": "4.3.0",
@@ -839,11 +722,6 @@
"System.Runtime": "4.3.0"
}
},
- "System.Reflection.Metadata": {
- "type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "5NecZgXktdGg34rh1OenY1rFNDCI8xSjFr+Z4OU4cU06AQHUdRnIIEeWENu3Wl4YowbzkymAIMvi3WyK9U53pQ=="
- },
"System.Reflection.Primitives": {
"type": "Transitive",
"resolved": "4.3.0",
@@ -942,15 +820,6 @@
"System.Runtime.Extensions": "4.3.0"
}
},
- "System.Security.AccessControl": {
- "type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "dagJ1mHZO3Ani8GH0PHpPEe/oYO+rVdbQjvjJkBRNQkX4t0r1iaeGn8+/ybkSLEan3/slM0t59SVdHzuHf2jmw==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "5.0.0",
- "System.Security.Principal.Windows": "5.0.0"
- }
- },
"System.Security.Cryptography.Algorithms": {
"type": "Transitive",
"resolved": "4.3.0",
@@ -1095,11 +964,6 @@
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
}
},
- "System.Security.Principal.Windows": {
- "type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA=="
- },
"System.Text.Encoding": {
"type": "Transitive",
"resolved": "4.3.0",
@@ -1226,45 +1090,8 @@
"System.Xml.ReaderWriter": "4.3.0"
}
},
- "Unosquare.Swan.Lite": {
- "type": "Transitive",
- "resolved": "3.0.0",
- "contentHash": "noPwJJl1Q9uparXy1ogtkmyAPGNfSGb0BLT1292nFH1jdMKje6o2kvvrQUvF9Xklj+IoiAI0UzF6Aqxlvo10lw=="
- },
"artemis.core": {
- "type": "Project",
- "dependencies": {
- "Artemis.Storage": "1.0.0",
- "EmbedIO": "3.4.3",
- "HidSharp": "2.1.0",
- "Humanizer.Core": "2.11.10",
- "LiteDB": "5.0.11",
- "McMaster.NETCore.Plugins": "1.4.0",
- "Newtonsoft.Json": "13.0.1",
- "Ninject": "3.3.4",
- "Ninject.Extensions.ChildKernel": "3.3.0",
- "Ninject.Extensions.Conventions": "3.3.0",
- "RGB.NET.Core": "1.0.0-prerelease7",
- "RGB.NET.Layout": "1.0.0-prerelease7",
- "RGB.NET.Presets": "1.0.0-prerelease7",
- "Serilog": "2.10.0",
- "Serilog.Sinks.Console": "4.0.0",
- "Serilog.Sinks.Debug": "2.0.0",
- "Serilog.Sinks.File": "5.0.0",
- "SkiaSharp": "2.80.3",
- "System.Buffers": "4.5.1",
- "System.IO.FileSystem.AccessControl": "5.0.0",
- "System.Numerics.Vectors": "4.5.0",
- "System.Reflection.Metadata": "5.0.0",
- "System.ValueTuple": "4.5.0"
- }
- },
- "artemis.storage": {
- "type": "Project",
- "dependencies": {
- "LiteDB": "5.0.11",
- "Serilog": "2.10.0"
- }
+ "type": "Project"
}
}
}
diff --git a/src/Artemis.Core/Models/Profile/Folder.cs b/src/Artemis.Core/Models/Profile/Folder.cs
index dd00ed756..e77a5a6ad 100644
--- a/src/Artemis.Core/Models/Profile/Folder.cs
+++ b/src/Artemis.Core/Models/Profile/Folder.cs
@@ -94,6 +94,12 @@ namespace Artemis.Core
if (Disposed)
throw new ObjectDisposedException("Folder");
+ if (Timeline.IsOverridden)
+ {
+ Timeline.ClearOverride();
+ return;
+ }
+
UpdateDisplayCondition();
UpdateTimeline(deltaTime);
diff --git a/src/Artemis.Core/Models/Profile/Layer.cs b/src/Artemis.Core/Models/Profile/Layer.cs
index 3512496f3..11a34940c 100644
--- a/src/Artemis.Core/Models/Profile/Layer.cs
+++ b/src/Artemis.Core/Models/Profile/Layer.cs
@@ -338,6 +338,12 @@ namespace Artemis.Core
if (Disposed)
throw new ObjectDisposedException("Layer");
+ if (Timeline.IsOverridden)
+ {
+ Timeline.ClearOverride();
+ return;
+ }
+
UpdateDisplayCondition();
UpdateTimeline(deltaTime);
diff --git a/src/Artemis.Core/Models/Profile/Timeline.cs b/src/Artemis.Core/Models/Profile/Timeline.cs
index 4e17d746f..606f0ba8b 100644
--- a/src/Artemis.Core/Models/Profile/Timeline.cs
+++ b/src/Artemis.Core/Models/Profile/Timeline.cs
@@ -20,7 +20,7 @@ public class Timeline : CorePropertyChanged, IStorageModel
{
Entity = new TimelineEntity();
MainSegmentLength = TimeSpan.FromSeconds(5);
-
+
Save();
}
@@ -36,7 +36,7 @@ public class Timeline : CorePropertyChanged, IStorageModel
{
return $"Progress: {Position}/{Length} - delta: {Delta}";
}
-
+
#region Properties
private TimeSpan _position;
@@ -46,7 +46,8 @@ public class Timeline : CorePropertyChanged, IStorageModel
private TimeSpan _startSegmentLength;
private TimeSpan _mainSegmentLength;
private TimeSpan _endSegmentLength;
-
+ private TimeSpan _lastOverride;
+
///
/// Gets the current position of the timeline
///
@@ -65,7 +66,7 @@ public class Timeline : CorePropertyChanged, IStorageModel
get => _lastDelta;
private set => SetAndNotify(ref _lastDelta, value);
}
-
+
///
/// Gets or sets the mode in which the render element starts its timeline when display conditions are met
///
@@ -251,8 +252,6 @@ public class Timeline : CorePropertyChanged, IStorageModel
#region Updating
- private TimeSpan _lastOverridePosition;
-
///
/// Updates the timeline, applying the provided to the
///
@@ -262,12 +261,12 @@ public class Timeline : CorePropertyChanged, IStorageModel
{
lock (_lock)
{
+ if (IsOverridden)
+ throw new ArtemisCoreException("Can't update an overridden timeline, call ClearOverride first.");
+
Delta += delta;
Position += delta;
- IsOverridden = false;
- _lastOverridePosition = Position;
-
if (!stickToMainSegment || Position <= MainSegmentEndPosition)
return;
@@ -334,16 +333,19 @@ public class Timeline : CorePropertyChanged, IStorageModel
{
lock (_lock)
{
- Delta += position - _lastOverridePosition;
- Position = position;
+ if (_lastOverride == TimeSpan.Zero)
+ Delta = Position - position;
+ else
+ Delta = position - _lastOverride;
+ Position = position;
IsOverridden = true;
- _lastOverridePosition = position;
+ _lastOverride = position;
if (!stickToMainSegment || Position < MainSegmentStartPosition)
return;
- bool atSegmentStart = Position == MainSegmentStartPosition;
+ bool atSegmentStart = Position >= MainSegmentStartPosition;
if (MainSegmentLength > TimeSpan.Zero)
{
Position = MainSegmentStartPosition + TimeSpan.FromMilliseconds(Position.TotalMilliseconds % MainSegmentLength.TotalMilliseconds);
@@ -359,6 +361,12 @@ public class Timeline : CorePropertyChanged, IStorageModel
}
}
+ internal void ClearOverride()
+ {
+ IsOverridden = false;
+ _lastOverride = TimeSpan.Zero;
+ }
+
///
/// Sets the to
///
diff --git a/src/Artemis.Core/Plugins/LayerBrushes/Internal/BaseLayerBrush.cs b/src/Artemis.Core/Plugins/LayerBrushes/Internal/BaseLayerBrush.cs
index 69027def6..24d54ae82 100644
--- a/src/Artemis.Core/Plugins/LayerBrushes/Internal/BaseLayerBrush.cs
+++ b/src/Artemis.Core/Plugins/LayerBrushes/Internal/BaseLayerBrush.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
using Artemis.Storage.Entities.Profile;
using SkiaSharp;
diff --git a/src/Artemis.Core/Services/CoreService.cs b/src/Artemis.Core/Services/CoreService.cs
index f8b0ffbcd..15a9a71a5 100644
--- a/src/Artemis.Core/Services/CoreService.cs
+++ b/src/Artemis.Core/Services/CoreService.cs
@@ -218,6 +218,7 @@ namespace Artemis.Core.Services
);
_logger.Information("Startup arguments: {args}", StartupArguments);
_logger.Information("Elevated permissions: {perms}", IsElevated);
+ _logger.Information("Stopwatch high resolution: {perms}", Stopwatch.IsHighResolution);
ApplyLoggingLevel();
diff --git a/src/Avalonia/Artemis.UI.Shared/Controls/SelectionRectangle.cs b/src/Avalonia/Artemis.UI.Shared/Controls/SelectionRectangle.cs
index 3866dcfb1..c51659c1b 100644
--- a/src/Avalonia/Artemis.UI.Shared/Controls/SelectionRectangle.cs
+++ b/src/Avalonia/Artemis.UI.Shared/Controls/SelectionRectangle.cs
@@ -43,6 +43,13 @@ public class SelectionRectangle : Control
public static readonly StyledProperty InputElementProperty =
AvaloniaProperty.Register(nameof(InputElement), notifying: OnInputElementChanged);
+ ///
+ /// Defines the property.
+ ///
+ public static readonly StyledProperty ZoomRatioProperty =
+ AvaloniaProperty.Register(nameof(ZoomRatio), 1);
+
+
///
/// Defines the read-only property.
///
@@ -108,6 +115,15 @@ public class SelectionRectangle : Control
set => SetValue(InputElementProperty, value);
}
+ ///
+ /// Gets or sets the zoom ratio to counteract when drawing
+ ///
+ public double ZoomRatio
+ {
+ get => GetValue(ZoomRatioProperty);
+ set => SetValue(ZoomRatioProperty, value);
+ }
+
///
/// Gets a boolean indicating whether the selection rectangle is currently performing a selection.
///
@@ -149,6 +165,7 @@ public class SelectionRectangle : Control
{
((SelectionRectangle) sender).SubscribeToInputElement();
}
+
private void ParentOnPointerPressed(object? sender, PointerPressedEventArgs e)
{
@@ -227,7 +244,7 @@ public class SelectionRectangle : Control
public override void Render(DrawingContext drawingContext)
{
if (_displayRect != null)
- drawingContext.DrawRectangle(Background, new Pen(BorderBrush, BorderThickness), _displayRect.Value, BorderRadius, BorderRadius);
+ drawingContext.DrawRectangle(Background, new Pen(BorderBrush, BorderThickness / ZoomRatio), _displayRect.Value, BorderRadius / ZoomRatio, BorderRadius / ZoomRatio);
}
///
diff --git a/src/Avalonia/Artemis.UI.Shared/Services/ProfileEditor/Commands/ToggleLayerPropertyKeyframes.cs b/src/Avalonia/Artemis.UI.Shared/Services/ProfileEditor/Commands/ToggleLayerPropertyKeyframes.cs
index d5c77b3ac..cea583b33 100644
--- a/src/Avalonia/Artemis.UI.Shared/Services/ProfileEditor/Commands/ToggleLayerPropertyKeyframes.cs
+++ b/src/Avalonia/Artemis.UI.Shared/Services/ProfileEditor/Commands/ToggleLayerPropertyKeyframes.cs
@@ -1,4 +1,5 @@
using System;
+using System.Linq;
using Artemis.Core;
namespace Artemis.UI.Shared.Services.ProfileEditor.Commands;
@@ -32,16 +33,37 @@ public class ToggleLayerPropertyKeyframes : IProfileEditorCommand
///
public void Execute()
{
- _keyframe ??= new LayerPropertyKeyframe(_layerProperty.CurrentValue, _time, Easings.Functions.Linear, _layerProperty);
- _layerProperty.KeyframesEnabled = _enable;
- _layerProperty.AddKeyframe(_keyframe);
+ if (_enable)
+ {
+ _layerProperty.KeyframesEnabled = true;
+
+ // If there weren't any keyframes yet, add one with the current value at the current time
+ if (!_layerProperty.Keyframes.Any())
+ {
+ // If executed before, reuse the previous keyframe
+ _keyframe ??= new LayerPropertyKeyframe(_layerProperty.CurrentValue, _time, Easings.Functions.Linear, _layerProperty);
+ _layerProperty.AddKeyframe(_keyframe);
+ }
+ }
+ else
+ {
+ _layerProperty.KeyframesEnabled = false;
+ }
}
///
public void Undo()
{
- _layerProperty.RemoveKeyframe(_keyframe!);
- _layerProperty.KeyframesEnabled = !_enable;
+ if (_enable)
+ {
+ if (_keyframe != null)
+ _layerProperty.RemoveKeyframe(_keyframe);
+ _layerProperty.KeyframesEnabled = false;
+ }
+ else
+ {
+ _layerProperty.KeyframesEnabled = true;
+ }
}
#endregion
diff --git a/src/Avalonia/Artemis.UI.Shared/Styles/Button.axaml b/src/Avalonia/Artemis.UI.Shared/Styles/Button.axaml
index 8c3eadb1b..adb50e2b4 100644
--- a/src/Avalonia/Artemis.UI.Shared/Styles/Button.axaml
+++ b/src/Avalonia/Artemis.UI.Shared/Styles/Button.axaml
@@ -33,6 +33,12 @@
+
+
+ Button.window-button
+
@@ -69,4 +75,15 @@
+
+
+
\ No newline at end of file
diff --git a/src/Avalonia/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugView.axaml b/src/Avalonia/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugView.axaml
index ccd646ccf..adb0fd87f 100644
--- a/src/Avalonia/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugView.axaml
+++ b/src/Avalonia/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugView.axaml
@@ -5,7 +5,7 @@
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Debugger.Performance.PerformanceDebugView">
-
+
Performance
@@ -21,7 +21,19 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugViewModel.cs b/src/Avalonia/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugViewModel.cs
index 781ff7e3c..1afef3043 100644
--- a/src/Avalonia/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugViewModel.cs
+++ b/src/Avalonia/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugViewModel.cs
@@ -8,16 +8,23 @@ using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.Shared;
using ReactiveUI;
+using SkiaSharp;
namespace Artemis.UI.Screens.Debugger.Performance
{
public class PerformanceDebugViewModel : ActivatableViewModelBase, IRoutableViewModel
{
+ private readonly ICoreService _coreService;
private readonly IPluginManagementService _pluginManagementService;
+ private double _currentFps;
+ private string? _renderer;
+ private int _renderHeight;
+ private int _renderWidth;
- public PerformanceDebugViewModel(IScreen hostScreen, IPluginManagementService pluginManagementService)
+ public PerformanceDebugViewModel(IScreen hostScreen, ICoreService coreService, IPluginManagementService pluginManagementService)
{
HostScreen = hostScreen;
+ _coreService = coreService;
_pluginManagementService = pluginManagementService;
Timer updateTimer = new(500);
@@ -38,6 +45,7 @@ namespace Artemis.UI.Screens.Debugger.Performance
.Subscribe(_ => Repopulate())
.DisposeWith(disposables);
+ HandleActivation();
PopulateItems();
updateTimer.Start();
@@ -45,21 +53,57 @@ namespace Artemis.UI.Screens.Debugger.Performance
{
updateTimer.Stop();
Items.Clear();
+ HandleDeactivation();
}).DisposeWith(disposables);
});
}
- public ObservableCollection Items { get; } = new();
-
+
public string UrlPathSegment => "performance";
public IScreen HostScreen { get; }
+ public ObservableCollection Items { get; } = new();
+
+ public double CurrentFps
+ {
+ get => _currentFps;
+ set => this.RaiseAndSetIfChanged(ref _currentFps, value);
+ }
+
+ public int RenderWidth
+ {
+ get => _renderWidth;
+ set => this.RaiseAndSetIfChanged(ref _renderWidth, value);
+ }
+
+ public int RenderHeight
+ {
+ get => _renderHeight;
+ set => this.RaiseAndSetIfChanged(ref _renderHeight, value);
+ }
+
+ public string? Renderer
+ {
+ get => _renderer;
+ set => this.RaiseAndSetIfChanged(ref _renderer, value);
+ }
+
+ private void HandleActivation()
+ {
+ Renderer = Constants.ManagedGraphicsContext != null ? Constants.ManagedGraphicsContext.GetType().Name : "Software";
+ _coreService.FrameRendered += CoreServiceOnFrameRendered;
+ }
+
+ private void HandleDeactivation()
+ {
+ _coreService.FrameRendered -= CoreServiceOnFrameRendered;
+ }
private void PopulateItems()
{
foreach (PerformanceDebugPluginViewModel performanceDebugPluginViewModel in _pluginManagementService.GetAllPlugins()
- .Where(p => p.IsEnabled && p.Profilers.Any(pr => pr.Measurements.Any()))
- .OrderBy(p => p.Info.Name)
- .Select(p => new PerformanceDebugPluginViewModel(p)))
+ .Where(p => p.IsEnabled && p.Profilers.Any(pr => pr.Measurements.Any()))
+ .OrderBy(p => p.Info.Name)
+ .Select(p => new PerformanceDebugPluginViewModel(p)))
Items.Add(performanceDebugPluginViewModel);
}
@@ -69,10 +113,19 @@ namespace Artemis.UI.Screens.Debugger.Performance
PopulateItems();
}
- private void UpdateTimerOnElapsed(object sender, ElapsedEventArgs e)
+ private void UpdateTimerOnElapsed(object? sender, ElapsedEventArgs e)
{
foreach (PerformanceDebugPluginViewModel viewModel in Items)
viewModel.Update();
}
+
+ private void CoreServiceOnFrameRendered(object? sender, FrameRenderedEventArgs e)
+ {
+ CurrentFps = _coreService.FrameRate;
+ SKImageInfo bitmapInfo = e.Texture.ImageInfo;
+
+ RenderHeight = bitmapInfo.Height;
+ RenderWidth = bitmapInfo.Width;
+ }
}
}
\ No newline at end of file
diff --git a/src/Avalonia/Artemis.UI/Screens/Debugger/Tabs/Render/RenderDebugView.axaml b/src/Avalonia/Artemis.UI/Screens/Debugger/Tabs/Render/RenderDebugView.axaml
index 3143eeecf..e29e77355 100644
--- a/src/Avalonia/Artemis.UI/Screens/Debugger/Tabs/Render/RenderDebugView.axaml
+++ b/src/Avalonia/Artemis.UI/Screens/Debugger/Tabs/Render/RenderDebugView.axaml
@@ -24,6 +24,21 @@
-
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Avalonia/Artemis.UI/Screens/Debugger/Tabs/Render/RenderDebugViewModel.cs b/src/Avalonia/Artemis.UI/Screens/Debugger/Tabs/Render/RenderDebugViewModel.cs
index 6729680c5..51d1bf5a7 100644
--- a/src/Avalonia/Artemis.UI/Screens/Debugger/Tabs/Render/RenderDebugViewModel.cs
+++ b/src/Avalonia/Artemis.UI/Screens/Debugger/Tabs/Render/RenderDebugViewModel.cs
@@ -102,7 +102,6 @@ namespace Artemis.UI.Screens.Debugger.Render
}
}
-
public string UrlPathSegment => "render";
public IScreen HostScreen { get; }
}
diff --git a/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionAddToolView.axaml b/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionAddToolView.axaml
index 2e3c5aaae..f6246fcce 100644
--- a/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionAddToolView.axaml
+++ b/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionAddToolView.axaml
@@ -9,7 +9,9 @@
+ BorderThickness="2"
+ SelectionFinished="SelectionRectangle_OnSelectionFinished"
+ ZoomRatio="{Binding $parent[ZoomBorder].ZoomX}">
diff --git a/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionAddToolView.axaml.cs b/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionAddToolView.axaml.cs
index 0110136ed..b8938f4f5 100644
--- a/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionAddToolView.axaml.cs
+++ b/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionAddToolView.axaml.cs
@@ -1,4 +1,5 @@
using Artemis.UI.Shared.Events;
+using Avalonia.Input;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
using Avalonia.Skia;
@@ -19,6 +20,6 @@ public class SelectionAddToolView : ReactiveUserControl leds = _rgbService.EnabledDevices.SelectMany(d => d.Leds).Where(l => l.AbsoluteRectangle.IntersectsWith(rect)).ToList();
- _profileEditorService.ExecuteCommand(new ChangeLayerLeds(_layer, leds));
+ if (inverse)
+ {
+ List toRemove = _layer.Leds.Where(l => l.AbsoluteRectangle.IntersectsWith(rect)).ToList();
+ List toAdd = _rgbService.EnabledDevices.SelectMany(d => d.Leds).Where(l => l.AbsoluteRectangle.IntersectsWith(rect)).Except(toRemove).ToList();
+ List leds = _layer.Leds.Except(toRemove).ToList();
+ leds.AddRange(toAdd);
+
+ _profileEditorService.ExecuteCommand(new ChangeLayerLeds(_layer, leds));
+ }
+ else
+ {
+ List leds = _rgbService.EnabledDevices.SelectMany(d => d.Leds).Where(l => l.AbsoluteRectangle.IntersectsWith(rect)).ToList();
+ if (expand)
+ leds.AddRange(_layer.Leds);
+ _profileEditorService.ExecuteCommand(new ChangeLayerLeds(_layer, leds.Distinct().ToList()));
+ }
}
}
\ No newline at end of file
diff --git a/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionRemoveToolView.axaml b/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionRemoveToolView.axaml
index 0823320a9..69dbdc20e 100644
--- a/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionRemoveToolView.axaml
+++ b/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionRemoveToolView.axaml
@@ -11,7 +11,9 @@
+ BorderThickness="2"
+ SelectionFinished="SelectionRectangle_OnSelectionFinished"
+ ZoomRatio="{Binding $parent[ZoomBorder].ZoomX}">
diff --git a/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerShapeVisualizerView.axaml b/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerShapeVisualizerView.axaml
index 4ea1dd32d..703ec1b30 100644
--- a/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerShapeVisualizerView.axaml
+++ b/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerShapeVisualizerView.axaml
@@ -10,38 +10,53 @@
-
+
\ No newline at end of file
diff --git a/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerShapeVisualizerView.axaml.cs b/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerShapeVisualizerView.axaml.cs
index cbef48437..c2e8936c0 100644
--- a/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerShapeVisualizerView.axaml.cs
+++ b/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerShapeVisualizerView.axaml.cs
@@ -1,3 +1,10 @@
+using System;
+using System.Linq;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.PanAndZoom;
+using Avalonia.Controls.Shapes;
+using Avalonia.LogicalTree;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
@@ -5,14 +12,50 @@ namespace Artemis.UI.Screens.ProfileEditor.VisualEditor.Visualizers
{
public partial class LayerShapeVisualizerView : ReactiveUserControl
{
+ private ZoomBorder? _zoomBorder;
+ private readonly Path _layerVisualizerUnbound;
+ private readonly Path _layerVisualizer;
+
public LayerShapeVisualizerView()
{
InitializeComponent();
+ _layerVisualizer = this.Get("LayerVisualizer");
+ _layerVisualizerUnbound = this.Get("LayerVisualizerUnbound");
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
+
+ #region Overrides of TemplatedControl
+
+ ///
+ protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
+ {
+ _zoomBorder = (ZoomBorder?) this.GetLogicalAncestors().FirstOrDefault(l => l is ZoomBorder);
+ if (_zoomBorder != null)
+ _zoomBorder.PropertyChanged += ZoomBorderOnPropertyChanged;
+ base.OnAttachedToLogicalTree(e);
+ }
+
+ ///
+ protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
+ {
+ if (_zoomBorder != null)
+ _zoomBorder.PropertyChanged -= ZoomBorderOnPropertyChanged;
+ base.OnDetachedFromLogicalTree(e);
+ }
+
+ private void ZoomBorderOnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
+ {
+ if (e.Property != ZoomBorder.ZoomXProperty || _zoomBorder == null)
+ return;
+
+ _layerVisualizer.StrokeThickness = Math.Max(1, 4 / _zoomBorder.ZoomX);
+ _layerVisualizerUnbound.StrokeThickness = _layerVisualizer.StrokeThickness;
+ }
+
+ #endregion
}
-}
+}
\ No newline at end of file
diff --git a/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerVisualizerView.axaml b/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerVisualizerView.axaml
index 1ba74c263..b5cc6011c 100644
--- a/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerVisualizerView.axaml
+++ b/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerVisualizerView.axaml
@@ -15,14 +15,14 @@
-
-
+
\ No newline at end of file
diff --git a/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerVisualizerView.axaml.cs b/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerVisualizerView.axaml.cs
index ba1264dea..bb00950f2 100644
--- a/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerVisualizerView.axaml.cs
+++ b/src/Avalonia/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerVisualizerView.axaml.cs
@@ -1,18 +1,58 @@
+using System;
+using System.Linq;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.PanAndZoom;
+using Avalonia.Controls.Shapes;
+using Avalonia.LogicalTree;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
+using Avalonia.VisualTree;
namespace Artemis.UI.Screens.ProfileEditor.VisualEditor.Visualizers
{
public partial class LayerVisualizerView : ReactiveUserControl
{
+ private ZoomBorder? _zoomBorder;
+ private readonly Path _layerVisualizer;
+
public LayerVisualizerView()
{
InitializeComponent();
+ _layerVisualizer = this.Get("LayerVisualizer");
}
+ #region Overrides of TemplatedControl
+
+ ///
+ protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
+ {
+ _zoomBorder = (ZoomBorder?) this.GetLogicalAncestors().FirstOrDefault(l => l is ZoomBorder);
+ if (_zoomBorder != null)
+ _zoomBorder.PropertyChanged += ZoomBorderOnPropertyChanged;
+ base.OnAttachedToLogicalTree(e);
+ }
+
+ ///
+ protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
+ {
+ if (_zoomBorder != null)
+ _zoomBorder.PropertyChanged -= ZoomBorderOnPropertyChanged;
+ base.OnDetachedFromLogicalTree(e);
+ }
+
+ private void ZoomBorderOnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
+ {
+ if (e.Property != ZoomBorder.ZoomXProperty || _zoomBorder == null)
+ return;
+ _layerVisualizer.StrokeThickness = Math.Max(1, 4 / _zoomBorder.ZoomX);
+ }
+
+ #endregion
+
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
-}
+}
\ No newline at end of file
diff --git a/src/Avalonia/Artemis.UI/Screens/Root/DefaultTitleBarView.axaml b/src/Avalonia/Artemis.UI/Screens/Root/DefaultTitleBarView.axaml
index 3ff09a332..3c98dac8b 100644
--- a/src/Avalonia/Artemis.UI/Screens/Root/DefaultTitleBarView.axaml
+++ b/src/Avalonia/Artemis.UI/Screens/Root/DefaultTitleBarView.axaml
@@ -5,7 +5,7 @@
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Root.DefaultTitleBarView">
-