diff --git a/src/Artemis.Core/Services/PluginManagementService.cs b/src/Artemis.Core/Services/PluginManagementService.cs index 0b35235c1..a168d54ef 100644 --- a/src/Artemis.Core/Services/PluginManagementService.cs +++ b/src/Artemis.Core/Services/PluginManagementService.cs @@ -362,7 +362,7 @@ namespace Artemis.Core.Services { // Load the enabled state and if not found, default to true PluginFeatureEntity featureEntity = plugin.Entity.Features.FirstOrDefault(i => i.Type == featureType.FullName) ?? - new PluginFeatureEntity {IsEnabled = plugin.Info.AutoEnableFeatures, Type = featureType.FullName!}; + new PluginFeatureEntity {IsEnabled = true, Type = featureType.FullName!}; plugin.AddFeature(new PluginFeatureInfo(plugin, featureType, featureEntity, (PluginFeatureAttribute?) Attribute.GetCustomAttribute(featureType, typeof(PluginFeatureAttribute)))); } diff --git a/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.csproj b/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.csproj index a52cde147..b1320c3f5 100644 --- a/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.csproj +++ b/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.csproj @@ -7,11 +7,11 @@ - - - - - + + + + + diff --git a/src/Artemis.UI.Avalonia.Shared/Controls/DeviceVisualizer.cs b/src/Artemis.UI.Avalonia.Shared/Controls/DeviceVisualizer.cs index f0bff897a..35ecf547c 100644 --- a/src/Artemis.UI.Avalonia.Shared/Controls/DeviceVisualizer.cs +++ b/src/Artemis.UI.Avalonia.Shared/Controls/DeviceVisualizer.cs @@ -12,7 +12,10 @@ using Avalonia.Input; using Avalonia.LogicalTree; using Avalonia.Media; using Avalonia.Media.Imaging; +using Avalonia.Platform; +using Avalonia.Rendering; using Avalonia.Threading; +using Avalonia.Visuals.Media.Imaging; namespace Artemis.UI.Avalonia.Shared.Controls { @@ -21,10 +24,11 @@ namespace Artemis.UI.Avalonia.Shared.Controls /// public class DeviceVisualizer : Control { - private readonly DispatcherTimer _timer; + private const double UpdateFrameRate = 25.0; private readonly List _deviceVisualizerLeds; + private readonly DispatcherTimer _timer; - private Bitmap? _deviceImage; + private RenderTargetBitmap? _deviceImage; private List? _dimmedLeds; private List? _highlightedLeds; private ArtemisDevice? _oldDevice; @@ -32,8 +36,7 @@ namespace Artemis.UI.Avalonia.Shared.Controls /// public DeviceVisualizer() { - // Run an update timer at 25 fps - _timer = new DispatcherTimer(DispatcherPriority.Render) {Interval = TimeSpan.FromMilliseconds(40)}; + _timer = new DispatcherTimer(DispatcherPriority.Render) {Interval = TimeSpan.FromMilliseconds(1000.0 / UpdateFrameRate)}; _deviceVisualizerLeds = new List(); PointerReleased += OnPointerReleased; @@ -45,27 +48,35 @@ namespace Artemis.UI.Avalonia.Shared.Controls if (Device == null) return; + List pushes = new(4); + // Determine the scale required to fit the desired size of the control Rect measureSize = MeasureDevice(); double scale = Math.Min(Bounds.Width / measureSize.Width, Bounds.Height / measureSize.Height); // Scale the visualization in the desired bounding box if (Bounds.Width > 0 && Bounds.Height > 0) - drawingContext.PushPostTransform(Matrix.CreateScale(scale, scale)); + pushes.Add(drawingContext.PushPostTransform(Matrix.CreateScale(scale, scale))); // Apply device rotation - drawingContext.PushPostTransform(Matrix.CreateTranslation(0 - measureSize.Left, 0 - measureSize.Top)); - drawingContext.PushPostTransform(Matrix.CreateRotation(Device.Rotation)); + pushes.Add(drawingContext.PushPostTransform(Matrix.CreateTranslation(0 - measureSize.Left, 0 - measureSize.Top))); + pushes.Add(drawingContext.PushPostTransform(Matrix.CreateRotation(Device.Rotation))); // Apply device scale - drawingContext.PushPostTransform(Matrix.CreateScale(Device.Scale, Device.Scale)); + pushes.Add(drawingContext.PushPostTransform(Matrix.CreateScale(Device.Scale, Device.Scale))); // Render device and LED images if (_deviceImage != null) - drawingContext.DrawImage(_deviceImage, new Rect(0, 0, Device.RgbDevice.Size.Width, Device.RgbDevice.Size.Height)); + drawingContext.DrawImage(_deviceImage, new Rect(0, 0, Device.RgbDevice.ActualSize.Width, Device.RgbDevice.ActualSize.Height)); foreach (DeviceVisualizerLed deviceVisualizerLed in _deviceVisualizerLeds) - deviceVisualizerLed.RenderImage(drawingContext); + deviceVisualizerLed.RenderGeometry(drawingContext); + + for (int index = pushes.Count - 1; index >= 0; index--) + { + DrawingContext.PushedState pushedState = pushes[index]; + pushedState.Dispose(); + } } /// @@ -73,6 +84,13 @@ namespace Artemis.UI.Avalonia.Shared.Controls /// public event EventHandler? LedClicked; + protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e) + { + _deviceImage?.Dispose(); + _deviceImage = null; + base.OnDetachedFromVisualTree(e); + } + /// /// Invokes the event /// @@ -142,7 +160,13 @@ namespace Artemis.UI.Avalonia.Shared.Controls /// Gets or sets the to display /// public static readonly StyledProperty DeviceProperty = - AvaloniaProperty.Register(nameof(Device)); + AvaloniaProperty.Register(nameof(Device), notifying: DeviceUpdated); + + private static void DeviceUpdated(IAvaloniaObject sender, bool before) + { + if (!before) + ((DeviceVisualizer) sender).SetupForDevice(); + } /// /// Gets or sets the to display @@ -225,14 +249,32 @@ namespace Artemis.UI.Avalonia.Shared.Controls Device.DeviceUpdated += DeviceUpdated; UpdateTransform(); - // Load the device main image - if (Device.Layout?.Image != null && File.Exists(Device.Layout.Image.LocalPath)) - _deviceImage = new Bitmap(Device.Layout.Image.AbsolutePath); - // Create all the LEDs foreach (ArtemisLed artemisLed in Device.Leds) _deviceVisualizerLeds.Add(new DeviceVisualizerLed(artemisLed)); + // Load the device main image + if (Device.Layout?.Image != null && File.Exists(Device.Layout.Image.LocalPath)) + { + try + { + // Create a bitmap that'll be used to render the device and LED images just once + RenderTargetBitmap renderTargetBitmap = new(new PixelSize((int) Device.RgbDevice.Size.Width * 4, (int) Device.RgbDevice.Size.Height * 4)); + + using IDrawingContextImpl context = renderTargetBitmap.CreateDrawingContext(new ImmediateRenderer(this)); + using Bitmap bitmap = new(Device.Layout.Image.LocalPath); + context.DrawBitmap(bitmap.PlatformImpl, 1, new Rect(bitmap.Size), new Rect(renderTargetBitmap.Size), BitmapInterpolationMode.HighQuality); + foreach (DeviceVisualizerLed deviceVisualizerLed in _deviceVisualizerLeds) + deviceVisualizerLed.DrawBitmap(context); + + _deviceImage = renderTargetBitmap; + } + catch + { + // ignored + } + } + InvalidateMeasure(); } diff --git a/src/Artemis.UI.Avalonia.Shared/Controls/DeviceVisualizerLed.cs b/src/Artemis.UI.Avalonia.Shared/Controls/DeviceVisualizerLed.cs index ae6c6ff5e..0ce741d13 100644 --- a/src/Artemis.UI.Avalonia.Shared/Controls/DeviceVisualizerLed.cs +++ b/src/Artemis.UI.Avalonia.Shared/Controls/DeviceVisualizerLed.cs @@ -4,6 +4,8 @@ using Artemis.Core; using Avalonia; using Avalonia.Media; using Avalonia.Media.Imaging; +using Avalonia.Platform; +using Avalonia.Visuals.Media.Imaging; using RGB.NET.Core; using Color = Avalonia.Media.Color; using Point = Avalonia.Point; @@ -13,6 +15,9 @@ namespace Artemis.UI.Avalonia.Shared.Controls { internal class DeviceVisualizerLed { + private readonly SolidColorBrush _penBrush; + private readonly SolidColorBrush _fillBrush; + private readonly Pen _pen; private const byte Dimmed = 100; private const byte NonDimmed = 255; @@ -26,46 +31,54 @@ namespace Artemis.UI.Avalonia.Shared.Controls Led.RgbLed.Size.Height ); - if (Led.Layout?.Image != null && File.Exists(Led.Layout.Image.LocalPath)) - LedImage = new Bitmap(Led.Layout.Image.AbsolutePath); + _fillBrush = new SolidColorBrush(); + _penBrush = new SolidColorBrush(); + _pen = new Pen(_penBrush) {LineJoin = PenLineJoin.Round}; CreateLedGeometry(); } public ArtemisLed Led { get; } public Rect LedRect { get; set; } - public Bitmap? LedImage { get; set; } public Geometry? DisplayGeometry { get; private set; } - - public void RenderImage(DrawingContext drawingContext) + + public void DrawBitmap(IDrawingContextImpl drawingContext) { - if (LedImage == null) + if (Led.Layout?.Image == null || !File.Exists(Led.Layout.Image.LocalPath)) return; - drawingContext.DrawImage(LedImage, LedRect); + try + { + using Bitmap bitmap = new(Led.Layout.Image.LocalPath); + drawingContext.DrawBitmap( + bitmap.PlatformImpl, + 1, + new Rect(bitmap.Size), + new Rect(Led.RgbLed.Location.X * 4, Led.RgbLed.Location.Y * 4, Led.RgbLed.Size.Width * 4, Led.RgbLed.Size.Height * 4), + BitmapInterpolationMode.HighQuality + ); + } + catch + { + // ignored + } + } + public void RenderGeometry(DrawingContext drawingContext) + { byte r = Led.RgbLed.Color.GetR(); byte g = Led.RgbLed.Color.GetG(); byte b = Led.RgbLed.Color.GetB(); - SolidColorBrush fillBrush = new(new Color(100, r, g, b)); - SolidColorBrush penBrush = new(new Color(255, r, g, b)); + _fillBrush.Color = new Color(100, r, g, b); + _penBrush.Color = new Color(255, r, g, b); - // Create transparent pixels covering the entire LedRect so the image size matched the LedRect size - // drawingContext.DrawRectangle(new SolidColorBrush(Colors.Transparent), new Pen(new SolidColorBrush(Colors.Transparent), 1), LedRect); - // Translate to the top-left of the LedRect - using DrawingContext.PushedState push = drawingContext.PushPostTransform(Matrix.CreateTranslation(LedRect.X, LedRect.Y)); // Render the LED geometry - drawingContext.DrawGeometry(fillBrush, new Pen(penBrush) {LineJoin = PenLineJoin.Round}, DisplayGeometry); + drawingContext.DrawGeometry(_fillBrush, _pen, DisplayGeometry); } public bool HitTest(Point position) { - if (DisplayGeometry == null) - return false; - - Geometry translatedGeometry = DisplayGeometry.Clone(); - translatedGeometry.Transform = new TranslateTransform(Led.RgbLed.Location.X, Led.RgbLed.Location.Y); - return translatedGeometry.FillContains(position); + return DisplayGeometry != null && DisplayGeometry.FillContains(position); } private void CreateLedGeometry() @@ -98,26 +111,17 @@ namespace Artemis.UI.Avalonia.Shared.Controls private void CreateRectangleGeometry() { - DisplayGeometry = new RectangleGeometry(new Rect(0.5, 0.5, Led.RgbLed.Size.Width - 1, Led.RgbLed.Size.Height - 1)); + DisplayGeometry = new RectangleGeometry(new Rect(Led.RgbLed.Location.X + 0.5, Led.RgbLed.Location.Y + 0.5, Led.RgbLed.Size.Width - 1, Led.RgbLed.Size.Height - 1)); } private void CreateCircleGeometry() { - DisplayGeometry = new EllipseGeometry(new Rect(0.5, 0.5, Led.RgbLed.Size.Width - 1, Led.RgbLed.Size.Height - 1)); + DisplayGeometry = new EllipseGeometry(new Rect(Led.RgbLed.Location.X + 0.5, Led.RgbLed.Location.Y + 0.5, Led.RgbLed.Size.Width - 1, Led.RgbLed.Size.Height - 1)); } private void CreateKeyCapGeometry() { - PathGeometry path = PathGeometry.Parse($"M1,1" + - $"h{Led.RgbLed.Size.Width - 2} a10," + - $"10 0 0 1 10," + - $"10 v{Led.RgbLed.Size.Height - 2} a10," + - $"10 0 0 1 -10," + - $"10 h-{Led.RgbLed.Size.Width - 2} a10," + - $"10 0 0 1 -10," + - $"-10 v-{Led.RgbLed.Size.Height - 2} a10," + - $"10 0 0 1 10,-10 z"); - DisplayGeometry = path; + DisplayGeometry = new RectangleGeometry(new Rect(Led.RgbLed.Location.X + 1, Led.RgbLed.Location.Y + 1, Led.RgbLed.Size.Width - 2, Led.RgbLed.Size.Height - 2)); } private void CreateCustomGeometry(double deflateAmount) @@ -128,27 +132,15 @@ namespace Artemis.UI.Avalonia.Shared.Controls double height = Led.RgbLed.Size.Height - deflateAmount; Geometry geometry = Geometry.Parse(Led.RgbLed.ShapeData); - geometry.Transform = new ScaleTransform(width, height); - geometry = geometry.Clone(); - geometry.Transform = new TranslateTransform(deflateAmount / 2, deflateAmount / 2); - DisplayGeometry = geometry.Clone(); - - // TODO: Figure out wtf was going on here - // if (DisplayGeometry.Bounds.Width > width) - // { - // DisplayGeometry = Geometry.Combine(Geometry.Empty, DisplayGeometry, GeometryCombineMode.Union, new TransformGroup - // { - // Children = new TransformCollection {new ScaleTransform(width / DisplayGeometry.Bounds.Width, 1)} - // }); - // } - // - // if (DisplayGeometry.Bounds.Height > height) - // { - // DisplayGeometry = Geometry.Combine(Geometry.Empty, DisplayGeometry, GeometryCombineMode.Union, new TransformGroup - // { - // Children = new TransformCollection {new ScaleTransform(1, height / DisplayGeometry.Bounds.Height)} - // }); - // } + geometry.Transform = new TransformGroup + { + Children = new Transforms + { + new ScaleTransform(width, height), + new TranslateTransform(Led.RgbLed.Location.X + deflateAmount / 2, Led.RgbLed.Location.Y + deflateAmount / 2) + } + }; + DisplayGeometry = geometry; } catch (Exception) { diff --git a/src/Artemis.UI.Avalonia.Shared/Exceptions/ArtemisUIException.cs b/src/Artemis.UI.Avalonia.Shared/Exceptions/ArtemisUIException.cs new file mode 100644 index 000000000..c074020b7 --- /dev/null +++ b/src/Artemis.UI.Avalonia.Shared/Exceptions/ArtemisUIException.cs @@ -0,0 +1,22 @@ +using System; + +namespace Artemis.UI.Avalonia.Shared.Exceptions +{ + /// + /// Represents errors that occur within the Artemis Shared UI library + /// + public class ArtemisSharedUIException : Exception + { + internal ArtemisSharedUIException() + { + } + + internal ArtemisSharedUIException(string message) : base(message) + { + } + + internal ArtemisSharedUIException(string message, Exception inner) : base(message, inner) + { + } + } +} \ No newline at end of file diff --git a/src/Artemis.UI.Avalonia.Shared/Ninject/SharedUIModule.cs b/src/Artemis.UI.Avalonia.Shared/Ninject/SharedUIModule.cs new file mode 100644 index 000000000..ed8a56783 --- /dev/null +++ b/src/Artemis.UI.Avalonia.Shared/Ninject/SharedUIModule.cs @@ -0,0 +1,31 @@ +using System; +using Artemis.UI.Avalonia.Shared.Services.Interfaces; +using Ninject.Extensions.Conventions; +using Ninject.Modules; + +namespace Artemis.UI.Avalonia.Shared.Ninject +{ + /// + /// The main of the Artemis Shared UI toolkit that binds all services + /// + public class SharedUIModule : NinjectModule + { + /// + public override void Load() + { + if (Kernel == null) + throw new ArgumentNullException("Kernel shouldn't be null here."); + + // Bind all shared UI services as singletons + Kernel.Bind(x => + { + x.FromAssemblyContaining() + .IncludingNonPublicTypes() + .SelectAllClasses() + .InheritedFrom() + .BindAllInterfaces() + .Configure(c => c.InSingletonScope()); + }); + } + } +} \ No newline at end of file diff --git a/src/Artemis.UI.Avalonia.Shared/Services/Interfaces/IWindowService.cs b/src/Artemis.UI.Avalonia.Shared/Services/Interfaces/IWindowService.cs new file mode 100644 index 000000000..4dd4b4b98 --- /dev/null +++ b/src/Artemis.UI.Avalonia.Shared/Services/Interfaces/IWindowService.cs @@ -0,0 +1,20 @@ +namespace Artemis.UI.Avalonia.Shared.Services.Interfaces +{ + public interface IWindowService : IArtemisSharedUIService + { + T ShowWindow(); + + /// + /// Given a ViewModel, show its corresponding View as a window + /// + /// ViewModel to show the View for + void ShowWindow(object viewModel); + + /// + /// Given a ViewModel, show its corresponding View as a Dialog + /// + /// ViewModel to show the View for + /// DialogResult of the View + bool? ShowDialog(object viewModel); + } +} \ No newline at end of file diff --git a/src/Artemis.UI.Avalonia.Shared/Services/WindowService.cs b/src/Artemis.UI.Avalonia.Shared/Services/WindowService.cs new file mode 100644 index 000000000..d9368de12 --- /dev/null +++ b/src/Artemis.UI.Avalonia.Shared/Services/WindowService.cs @@ -0,0 +1,52 @@ +using System; +using Artemis.UI.Avalonia.Shared.Exceptions; +using Artemis.UI.Avalonia.Shared.Services.Interfaces; +using Avalonia.Controls; +using Ninject; + +namespace Artemis.UI.Avalonia.Shared.Services +{ + internal class WindowService : IWindowService + { + private readonly IKernel _kernel; + + public WindowService(IKernel kernel) + { + _kernel = kernel; + } + + #region Implementation of IWindowService + + /// + public T ShowWindow() + { + T viewModel = _kernel.Get()!; + ShowWindow(viewModel); + return viewModel; + } + + /// + public void ShowWindow(object viewModel) + { + string name = viewModel.GetType().FullName!.Split('`')[0].Replace("ViewModel", "View"); + Type? type = viewModel.GetType().Assembly.GetType(name); + + if (type == null) + throw new ArtemisSharedUIException($"Failed to find a window named {name}."); + if (!type.IsAssignableTo(typeof(Window))) + throw new ArtemisSharedUIException($"Type {name} is not a window."); + + Window window = (Window) Activator.CreateInstance(type)!; + window.DataContext = viewModel; + window.Show(); + } + + /// + public bool? ShowDialog(object viewModel) + { + throw new NotImplementedException(); + } + + #endregion + } +} \ No newline at end of file diff --git a/src/Artemis.UI.Avalonia.Shared/packages.lock.json b/src/Artemis.UI.Avalonia.Shared/packages.lock.json index 9b6039d9a..ea3da0ddc 100644 --- a/src/Artemis.UI.Avalonia.Shared/packages.lock.json +++ b/src/Artemis.UI.Avalonia.Shared/packages.lock.json @@ -4,11 +4,11 @@ ".NETCoreApp,Version=v5.0": { "Avalonia": { "type": "Direct", - "requested": "[0.10.7, )", - "resolved": "0.10.7", - "contentHash": "savkS5LlA3bGAXvP9RfPRLRjeGp7XXExNRNhM4BaxCHGsopsWOpRt0nNI6X7FrC9Ous3h+k+gKQu8kc+AZHj8A==", + "requested": "[0.10.8, )", + "resolved": "0.10.8", + "contentHash": "/m31yPKz7iqV5thzlLGi8ERgiTV+FYl7NePafwDpN41aLwz8u4rrTviWm9QJH78cwj8tGCf9Pqp8Nm0fckfAZA==", "dependencies": { - "Avalonia.Remote.Protocol": "0.10.7", + "Avalonia.Remote.Protocol": "0.10.8", "JetBrains.Annotations": "10.3.0", "System.ComponentModel.Annotations": "4.5.0", "System.Memory": "4.5.3", @@ -19,44 +19,44 @@ }, "Avalonia.Svg.Skia": { "type": "Direct", - "requested": "[0.10.7.2, )", - "resolved": "0.10.7.2", - "contentHash": "a5zt8IwrLeG+2hQ+Hs7/2zjPH5vujFQvcmOOWikM9iktm6Vjejqj8h1ssZK3n4TfGmIkq2AtbQcTBAC1nqFP6A==", + "requested": "[0.10.8.3, )", + "resolved": "0.10.8.3", + "contentHash": "w7RYf+8+gOI3uVZZJ59S0EP49LVsyr1jpnZQzVFQqKa3y/c/i2jT/EUoKOeaqPMhFIsQZyEF4iluqoo6aZ05Tw==", "dependencies": { - "Avalonia": "0.10.7", - "Avalonia.Skia": "0.10.7", + "Avalonia": "0.10.8", + "Avalonia.Skia": "0.10.8", "SkiaSharp": "2.80.2", - "Svg.Skia": "0.5.7.2" + "Svg.Skia": "0.5.8.3" } }, "Avalonia.Xaml.Behaviors": { "type": "Direct", - "requested": "[0.10.7.1, )", - "resolved": "0.10.7.1", - "contentHash": "Ef5PCejEA6F25GadMwVVqATeWrZ7XFouerQvbeIpH2FOD8iS8Vg8vEJFGkHLv1N6HHUF2nZUb01csfs6bOy4Jg==", + "requested": "[0.10.8, )", + "resolved": "0.10.8", + "contentHash": "3nkh36Qp9fK8/Fh/nxqaVMlAzj8iuH5RUcs2rTrcyqn1WPJTslwQrxk+HDMYneuBE9+Oi31ZWiZImEM9kEQN7w==", "dependencies": { - "Avalonia": "0.10.7", - "Avalonia.Xaml.Interactions": "0.10.7.1", - "Avalonia.Xaml.Interactivity": "0.10.7.1" + "Avalonia": "0.10.8", + "Avalonia.Xaml.Interactions": "0.10.8", + "Avalonia.Xaml.Interactivity": "0.10.8" } }, "Avalonia.Xaml.Interactions": { "type": "Direct", - "requested": "[0.10.7.1, )", - "resolved": "0.10.7.1", - "contentHash": "ZFgGnjUKbZofMAriGn8xPW/3rt1iww2pUTtOQW8+8YQDtFBjZtq2LaiE0ExX9HgPqgrFM8LYwGcf8SsYZb1pNg==", + "requested": "[0.10.8, )", + "resolved": "0.10.8", + "contentHash": "3pXshQ1pNr+ul7Q2Sn6jjWMHOgRM2uKsUCh95QD2O2wpjgxpRpqiNEy1xPv2+bX2FMWTQIaOdQ8eNM8EunAWMg==", "dependencies": { - "Avalonia": "0.10.7", - "Avalonia.Xaml.Interactivity": "0.10.7.1" + "Avalonia": "0.10.8", + "Avalonia.Xaml.Interactivity": "0.10.8" } }, "Avalonia.Xaml.Interactivity": { "type": "Direct", - "requested": "[0.10.7.1, )", - "resolved": "0.10.7.1", - "contentHash": "vLYy2lRISft55wwU7gKTXdBfbdkas1u/bznO05IYCFQzwVRo5ktSs1U1fy6ZzrK5z9Lq/e05GM7Q123n4Dfpow==", + "requested": "[0.10.8, )", + "resolved": "0.10.8", + "contentHash": "ObL26GjME53R3KRkGB97dIB3jwGzyNS/7Www8fZjCEbK4AnjXVgzyw7gkHNsHD9DEZArovvURQI0qvvz3tb24g==", "dependencies": { - "Avalonia": "0.10.7" + "Avalonia": "0.10.8" } }, "Material.Icons.Avalonia": { @@ -71,15 +71,15 @@ }, "Avalonia.Remote.Protocol": { "type": "Transitive", - "resolved": "0.10.7", - "contentHash": "w8Le0g2StgD1/32mEPYzP0MhMfDyeHvATHFV3IYA2oQTiPoicjUy3To+PuwAB9T9SSi9DtkLhwazlWZOqQGuAw==" + "resolved": "0.10.8", + "contentHash": "flpM/ZF2vkzbHbmSKdq6qWxy/bw/2C1k3Oc73ewlUdwBUWMov6mX99yUWNNI26oYrgD2fpaRhHMukcoSCYqbuQ==" }, "Avalonia.Skia": { "type": "Transitive", - "resolved": "0.10.7", - "contentHash": "dV6WXLk5ziYhnDAwf/fagoVRPTBN4LvFt1BMgikvVKCrkWlmtnQQ/Rav9ESJ13c887XpWMGcERYne3vzeLP6MA==", + "resolved": "0.10.8", + "contentHash": "FsCeOhzDCE4GJnqBGzH/54tqsn0j39Xpkdf3TmuC0MZzjW82Me3GUGeO25E9zs7sEMtX0MKWocmBx6c6ADcGXA==", "dependencies": { - "Avalonia": "0.10.7", + "Avalonia": "0.10.8", "HarfBuzzSharp": "2.6.1.7", "HarfBuzzSharp.NativeAssets.Linux": "2.6.1.7", "SkiaSharp": "2.80.2", @@ -438,8 +438,8 @@ }, "ShimSkiaSharp": { "type": "Transitive", - "resolved": "0.5.7.2", - "contentHash": "+KFniLMpqei3Hj1T586ZY/ZDZXXyl6NFLTXvSZ5LvEi96KIcEgbFCuSsNCVfTmnKQaLCn4Gn+KHjqroCJe2FFA==" + "resolved": "0.5.8.3", + "contentHash": "BWwwsIlYUFF0DUc8Pa9xONIXVDvEL9pOYc9YmWilpHrWC37dcK+H4+tfuxztZxtfJx559HGn+6iZmMDjfFoOxA==" }, "SkiaSharp": { "type": "Transitive", @@ -468,8 +468,8 @@ }, "Svg.Custom": { "type": "Transitive", - "resolved": "0.5.7.2", - "contentHash": "BLb8ViaXEWWsYvbxtGj+ITNO1CpZEszWT8sE5Xa1qkeoniIENog5PEKGTc5mAJ8MhFc4GYO33Vo9duH0KzizNQ==", + "resolved": "0.5.8.3", + "contentHash": "6FnbI4T3uCNN7DYJpfPFa4caTTJzp4YbhU3J4c/syX7wQNSeQ/1u7JZZ+dGgrRUauiWP8VsiCLKP8qinc5xI5w==", "dependencies": { "Fizzler": "1.2.0", "System.Drawing.Common": "5.0.0", @@ -480,22 +480,22 @@ }, "Svg.Model": { "type": "Transitive", - "resolved": "0.5.7.2", - "contentHash": "txH95pxkg75s2LBcONXFCmrpYp5flUC5aF1DaLwTtt33dv9WvOQQlxnasNyb0CN7t0yaXpX8CZoo+SU9u1E/eA==", + "resolved": "0.5.8.3", + "contentHash": "F/rimPwV5KF64P8oofXGMwOZ0T7b3z1A9OiC4mv5OdSpLpMpUxpSwGLAOkJ5DFqQgXqVjKKLhPdjIjQBwy0AjA==", "dependencies": { - "ShimSkiaSharp": "0.5.7.2", - "Svg.Custom": "0.5.7.2" + "ShimSkiaSharp": "0.5.8.3", + "Svg.Custom": "0.5.8.3" } }, "Svg.Skia": { "type": "Transitive", - "resolved": "0.5.7.2", - "contentHash": "QknpGmwSsns+/05W4efAuPvd77AsimuN5bAGTHGzHQPkPY/htgfXPm2YKywsEIpbXvUiTCfvzaSxSlkYHK8F2g==", + "resolved": "0.5.8.3", + "contentHash": "ajQ0aINQtEzWkqEXyJjnwqOFNusWNMHJVGrKa1ISbP21nrWJh+tApydLFVFGGjs91d7K3YOUbWDKlEzzdDQaOg==", "dependencies": { "SkiaSharp": "2.80.2", "SkiaSharp.HarfBuzz": "2.80.2", - "Svg.Custom": "0.5.7.2", - "Svg.Model": "0.5.7.2" + "Svg.Custom": "0.5.8.3", + "Svg.Model": "0.5.8.3" } }, "System.AppContext": { diff --git a/src/Artemis.UI.Avalonia/App.axaml.cs b/src/Artemis.UI.Avalonia/App.axaml.cs index 577d9f343..a299455b3 100644 --- a/src/Artemis.UI.Avalonia/App.axaml.cs +++ b/src/Artemis.UI.Avalonia/App.axaml.cs @@ -1,6 +1,7 @@ using Artemis.Core.Ninject; using Artemis.UI.Avalonia.Ninject; using Artemis.UI.Avalonia.Screens.Root.ViewModels; +using Artemis.UI.Avalonia.Shared.Ninject; using Avalonia; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; @@ -43,6 +44,7 @@ namespace Artemis.UI.Avalonia _kernel = new StandardKernel(); _kernel.Load(); _kernel.Load(); + _kernel.Load(); _kernel.UseNinjectDependencyResolver(); } diff --git a/src/Artemis.UI.Avalonia/Artemis.UI.Avalonia.csproj b/src/Artemis.UI.Avalonia/Artemis.UI.Avalonia.csproj index 8017343d6..5d7348079 100644 --- a/src/Artemis.UI.Avalonia/Artemis.UI.Avalonia.csproj +++ b/src/Artemis.UI.Avalonia/Artemis.UI.Avalonia.csproj @@ -13,16 +13,17 @@ - - - - - + + + + + + - + diff --git a/src/Artemis.UI.Avalonia/Screens/Root/Views/RootView.axaml b/src/Artemis.UI.Avalonia/Screens/Root/Views/RootView.axaml index 51f17fcc9..ad6fd266b 100644 --- a/src/Artemis.UI.Avalonia/Screens/Root/Views/RootView.axaml +++ b/src/Artemis.UI.Avalonia/Screens/Root/Views/RootView.axaml @@ -13,7 +13,7 @@ - + diff --git a/src/Artemis.UI.Avalonia/Screens/Settings/ViewModels/GeneralTabViewModel.cs b/src/Artemis.UI.Avalonia/Screens/Settings/ViewModels/GeneralTabViewModel.cs index c43a60339..15d481b4f 100644 --- a/src/Artemis.UI.Avalonia/Screens/Settings/ViewModels/GeneralTabViewModel.cs +++ b/src/Artemis.UI.Avalonia/Screens/Settings/ViewModels/GeneralTabViewModel.cs @@ -20,11 +20,13 @@ namespace Artemis.UI.Avalonia.Screens.Settings.ViewModels { private readonly PluginSetting _defaultLayerBrushDescriptor; private readonly ISettingsService _settingsService; + private readonly IDebugService _debugService; - public GeneralTabViewModel(ISettingsService settingsService, IPluginManagementService pluginManagementService, IDebugService debuggerService) + public GeneralTabViewModel(ISettingsService settingsService, IPluginManagementService pluginManagementService, IDebugService debugService) { DisplayName = "General"; _settingsService = settingsService; + _debugService = debugService; List layerBrushProviders = pluginManagementService.GetFeaturesOfType(); LayerBrushDescriptors = new ObservableCollection(layerBrushProviders.SelectMany(l => l.LayerBrushDescriptors)); @@ -137,8 +139,10 @@ namespace Artemis.UI.Avalonia.Screens.Settings.ViewModels private void ExecuteShowDebugger() { + _debugService.ShowDebugger(); } + private void ExecuteShowDataFolder() { OpenFolder(Constants.DataFolder); diff --git a/src/Artemis.UI.Avalonia/Screens/SurfaceEditor/ViewModels/SurfaceEditorViewModel.cs b/src/Artemis.UI.Avalonia/Screens/SurfaceEditor/ViewModels/SurfaceEditorViewModel.cs index 591998ec0..c1b67a640 100644 --- a/src/Artemis.UI.Avalonia/Screens/SurfaceEditor/ViewModels/SurfaceEditorViewModel.cs +++ b/src/Artemis.UI.Avalonia/Screens/SurfaceEditor/ViewModels/SurfaceEditorViewModel.cs @@ -1,12 +1,18 @@ -using ReactiveUI; +using System.Collections.ObjectModel; +using Artemis.Core; +using Artemis.Core.Services; +using ReactiveUI; namespace Artemis.UI.Avalonia.Screens.SurfaceEditor.ViewModels { public class SurfaceEditorViewModel : MainScreenViewModel { - public SurfaceEditorViewModel(IScreen hostScreen) : base(hostScreen, "surface-editor") + public SurfaceEditorViewModel(IScreen hostScreen, IRgbService rgbService) : base(hostScreen, "surface-editor") { DisplayName = "Surface Editor"; + Devices = new ObservableCollection(rgbService.Devices); } + + public ObservableCollection Devices { get; } } } \ No newline at end of file diff --git a/src/Artemis.UI.Avalonia/Screens/SurfaceEditor/Views/SurfaceEditorView.axaml b/src/Artemis.UI.Avalonia/Screens/SurfaceEditor/Views/SurfaceEditorView.axaml index cf30b3ef5..aae1ca21b 100644 --- a/src/Artemis.UI.Avalonia/Screens/SurfaceEditor/Views/SurfaceEditorView.axaml +++ b/src/Artemis.UI.Avalonia/Screens/SurfaceEditor/Views/SurfaceEditorView.axaml @@ -2,7 +2,50 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:controls="clr-namespace:Artemis.UI.Avalonia.Shared.Controls;assembly=Artemis.UI.Avalonia.Shared" + xmlns:paz="using:Avalonia.Controls.PanAndZoom" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Artemis.UI.Avalonia.Screens.SurfaceEditor.Views.SurfaceEditorView"> - Surface editor c: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Artemis.UI.Avalonia/Screens/SurfaceEditor/Views/SurfaceEditorView.axaml.cs b/src/Artemis.UI.Avalonia/Screens/SurfaceEditor/Views/SurfaceEditorView.axaml.cs index 2636b8057..7ace73ccf 100644 --- a/src/Artemis.UI.Avalonia/Screens/SurfaceEditor/Views/SurfaceEditorView.axaml.cs +++ b/src/Artemis.UI.Avalonia/Screens/SurfaceEditor/Views/SurfaceEditorView.axaml.cs @@ -1,19 +1,33 @@ using Artemis.UI.Avalonia.Screens.SurfaceEditor.ViewModels; +using Avalonia; +using Avalonia.Controls; +using Avalonia.Controls.PanAndZoom; using Avalonia.Markup.Xaml; +using Avalonia.Media; using Avalonia.ReactiveUI; namespace Artemis.UI.Avalonia.Screens.SurfaceEditor.Views { public class SurfaceEditorView : ReactiveUserControl { + private readonly ZoomBorder _zoomBorder; + public SurfaceEditorView() { InitializeComponent(); + + _zoomBorder = this.Find("ZoomBorder"); + ((VisualBrush)_zoomBorder.Background).DestinationRect = new RelativeRect(_zoomBorder.OffsetX * -1, _zoomBorder.OffsetY * -1, 20, 20, RelativeUnit.Absolute); } private void InitializeComponent() { AvaloniaXamlLoader.Load(this); } + + private void ZoomBorder_OnZoomChanged(object sender, ZoomChangedEventArgs e) + { + ((VisualBrush) _zoomBorder.Background).DestinationRect = new RelativeRect(_zoomBorder.OffsetX * -1, _zoomBorder.OffsetY * -1, 20, 20, RelativeUnit.Absolute); + } } } \ No newline at end of file diff --git a/src/Artemis.UI.Avalonia/Services/DebugService.cs b/src/Artemis.UI.Avalonia/Services/DebugService.cs index d894f2255..b6802edca 100644 --- a/src/Artemis.UI.Avalonia/Services/DebugService.cs +++ b/src/Artemis.UI.Avalonia/Services/DebugService.cs @@ -1,30 +1,38 @@ using Artemis.UI.Avalonia.Screens.Debug; using Artemis.UI.Avalonia.Services.Interfaces; -using Ninject; +using Artemis.UI.Avalonia.Shared.Services.Interfaces; namespace Artemis.UI.Avalonia.Services { public class DebugService : IDebugService { - private readonly IKernel _kernel; - private DebugWindow? _debugWindow; + private readonly IWindowService _windowService; + private DebugViewModel? _debugViewModel; - public DebugService(IKernel kernel) + public DebugService(IWindowService windowService) { - _kernel = kernel; + _windowService = windowService; } - private void CreateDebugger() + public void ClearDebugger() { + _debugViewModel = null; } private void BringDebuggerToForeground() { + if (_debugViewModel != null) + _debugViewModel.IsActive = true; + } + + private void CreateDebugger() + { + _debugViewModel = _windowService.ShowWindow(); } public void ShowDebugger() { - if (_debugWindow != null) + if (_debugViewModel != null) BringDebuggerToForeground(); else CreateDebugger(); diff --git a/src/Artemis.UI.Avalonia/Services/Interfaces/IDebugService.cs b/src/Artemis.UI.Avalonia/Services/Interfaces/IDebugService.cs index 6e2d34e74..7741e98ee 100644 --- a/src/Artemis.UI.Avalonia/Services/Interfaces/IDebugService.cs +++ b/src/Artemis.UI.Avalonia/Services/Interfaces/IDebugService.cs @@ -1,13 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Artemis.UI.Avalonia.Services.Interfaces +namespace Artemis.UI.Avalonia.Services.Interfaces { public interface IDebugService : IArtemisUIService { void ShowDebugger(); + void ClearDebugger(); } -} +} \ No newline at end of file diff --git a/src/Artemis.UI.Avalonia/Styles/Border.axaml b/src/Artemis.UI.Avalonia/Styles/Border.axaml index b48918dd5..822a4d097 100644 --- a/src/Artemis.UI.Avalonia/Styles/Border.axaml +++ b/src/Artemis.UI.Avalonia/Styles/Border.axaml @@ -17,7 +17,6 @@ - \ No newline at end of file diff --git a/src/Artemis.UI.Avalonia/packages.lock.json b/src/Artemis.UI.Avalonia/packages.lock.json index 3e0b97a9c..850af639e 100644 --- a/src/Artemis.UI.Avalonia/packages.lock.json +++ b/src/Artemis.UI.Avalonia/packages.lock.json @@ -4,11 +4,11 @@ ".NETCoreApp,Version=v5.0": { "Avalonia": { "type": "Direct", - "requested": "[0.10.7, )", - "resolved": "0.10.7", - "contentHash": "savkS5LlA3bGAXvP9RfPRLRjeGp7XXExNRNhM4BaxCHGsopsWOpRt0nNI6X7FrC9Ous3h+k+gKQu8kc+AZHj8A==", + "requested": "[0.10.8, )", + "resolved": "0.10.8", + "contentHash": "/m31yPKz7iqV5thzlLGi8ERgiTV+FYl7NePafwDpN41aLwz8u4rrTviWm9QJH78cwj8tGCf9Pqp8Nm0fckfAZA==", "dependencies": { - "Avalonia.Remote.Protocol": "0.10.7", + "Avalonia.Remote.Protocol": "0.10.8", "JetBrains.Annotations": "10.3.0", "System.ComponentModel.Annotations": "4.5.0", "System.Memory": "4.5.3", @@ -17,52 +17,61 @@ "System.ValueTuple": "4.5.0" } }, + "Avalonia.Controls.PanAndZoom": { + "type": "Direct", + "requested": "[4.2.0, )", + "resolved": "4.2.0", + "contentHash": "zIQhp86CdV7xmFXFkaQBDNDr0WSyumEdJvqvIrywG5SEQK3HzACt0gR85KX19DHTlkJlnUVjmfkTEiPjwvgGtA==", + "dependencies": { + "Avalonia": "0.10.8" + } + }, "Avalonia.Desktop": { "type": "Direct", - "requested": "[0.10.7, )", - "resolved": "0.10.7", - "contentHash": "pSVPwUkGB37mzz1ZCW55y2ddiLYVw2bbHu1tmdwbJq1ZgL6xhyEIwCqFemwt2VR/dr74eN8CFlQuU8cHwFZFPA==", + "requested": "[0.10.8, )", + "resolved": "0.10.8", + "contentHash": "DbY+6vMWR7i7mo5oVvPHhyui/LNsxfpXJaPNj3ka38EqcQOptZQI5DDrCHSAxGoFNrOsfNBTEs4Uv4rW5BW0Lg==", "dependencies": { - "Avalonia": "0.10.7", - "Avalonia.Native": "0.10.7", - "Avalonia.Skia": "0.10.7", - "Avalonia.Win32": "0.10.7", - "Avalonia.X11": "0.10.7" + "Avalonia": "0.10.8", + "Avalonia.Native": "0.10.8", + "Avalonia.Skia": "0.10.8", + "Avalonia.Win32": "0.10.8", + "Avalonia.X11": "0.10.8" } }, "Avalonia.Diagnostics": { "type": "Direct", - "requested": "[0.10.7, )", - "resolved": "0.10.7", - "contentHash": "SJHcdLfnIR0ImXxqDpQc5GzVcHWtRFJhPLU+kRDqt6z0JGdTbQviYBeVH/uywKVGzi/LgxCPOcC1gjSrV304Jw==", + "requested": "[0.10.8, )", + "resolved": "0.10.8", + "contentHash": "nBvcRd5RFDpRli5z/gEbuUKHEhp6NCTUo3PWQFEYi9hOIVIgCqwgEljc9oo7FGPBA6HDbUZGqoopwFhbLXi+pg==", "dependencies": { - "Avalonia": "0.10.7", - "Avalonia.Controls.DataGrid": "0.10.7", + "Avalonia": "0.10.8", + "Avalonia.Controls.DataGrid": "0.10.8", "Microsoft.CodeAnalysis.CSharp.Scripting": "3.4.0", "System.Reactive": "5.0.0" } }, "Avalonia.ReactiveUI": { "type": "Direct", - "requested": "[0.10.7, )", - "resolved": "0.10.7", - "contentHash": "OjmGmTNforTPS9X2/+WqSbuu2h4hNl+N+6SKV83V3KeMKC4HNq6TqOTPNLF2yx2HOm/498I3kVGVXVL4Xan+cA==", + "requested": "[0.10.8, )", + "resolved": "0.10.8", + "contentHash": "AnE4Rw9YQOLgHDK3TTkGXk3r4RCQgvYY/qMlspMfwdTyzJhvrjn7maDgAKhbs+m49Wr7dc9b1lfxqt7mNJWq/w==", "dependencies": { - "Avalonia": "0.10.7", + "Avalonia": "0.10.8", "ReactiveUI": "13.2.10", "System.Reactive": "5.0.0" } }, "Avalonia.Svg.Skia": { "type": "Direct", - "requested": "[0.10.7.2, )", - "resolved": "0.10.7.2", - "contentHash": "a5zt8IwrLeG+2hQ+Hs7/2zjPH5vujFQvcmOOWikM9iktm6Vjejqj8h1ssZK3n4TfGmIkq2AtbQcTBAC1nqFP6A==", + "requested": "[0.10.8.3, )", + "resolved": "0.10.8.3", + "contentHash": "w7RYf+8+gOI3uVZZJ59S0EP49LVsyr1jpnZQzVFQqKa3y/c/i2jT/EUoKOeaqPMhFIsQZyEF4iluqoo6aZ05Tw==", "dependencies": { - "Avalonia": "0.10.7", - "Avalonia.Skia": "0.10.7", + "Avalonia": "0.10.8", + "Avalonia.Skia": "0.10.8", "SkiaSharp": "2.80.2", - "Svg.Skia": "0.5.7.2" + "Svg.Skia": "0.5.8.3" } }, "FluentAvaloniaUI": { @@ -108,12 +117,12 @@ }, "Splat.Ninject": { "type": "Direct", - "requested": "[13.1.22, )", - "resolved": "13.1.22", - "contentHash": "wRqjUyT6L7G5v7oT75TzQs7knrtZgYF7pNyHoaeJ9sm0aLlzWwy9Z6faZWZ/3fXXJf3IokRFCSXmQSq18UyW4Q==", + "requested": "[13.1.30, )", + "resolved": "13.1.30", + "contentHash": "hYgyD12Syt2l8U/KccMzNUj4nmrdULjoRTF4g5Q9XtVWPrcdTYmLEdcX/prZEWaFT7vGNP6x9uFXvOlM7Jc+gg==", "dependencies": { "Ninject": "3.3.4", - "Splat": "13.1.22" + "Splat": "13.1.30" } }, "Avalonia.Angle.Windows.Natives": { @@ -123,43 +132,43 @@ }, "Avalonia.Controls.DataGrid": { "type": "Transitive", - "resolved": "0.10.7", - "contentHash": "AEQ/4We8qak7A3CAWboPvub7AyFH8SdXyoFGVWiJCHRQPy30/apNL5O/dccYnQ2ANO+yTwZxU0mL8RoAJgp+0Q==", + "resolved": "0.10.8", + "contentHash": "AWS/s+tEDUX0icnDdsMpk6NoLAZeq+QEIiDhleJkxMTitfwvYVJlXePaoOm4w8Oi134KV/fkj7aoiU3QRr/ltg==", "dependencies": { - "Avalonia": "0.10.7", - "Avalonia.Remote.Protocol": "0.10.7", + "Avalonia": "0.10.8", + "Avalonia.Remote.Protocol": "0.10.8", "JetBrains.Annotations": "10.3.0", "System.Reactive": "5.0.0" } }, "Avalonia.FreeDesktop": { "type": "Transitive", - "resolved": "0.10.7", - "contentHash": "zMjjAqujGe9TiBdst8iHTIAoR0cprR6bxiGrz2Pw/HqbghoM08vv5fHsqCtJVwexdSopkOkge5jkYsKlbl5pdQ==", + "resolved": "0.10.8", + "contentHash": "QvkzItAsww8zZmKyEKXMmhIN+ZnV8h3FGikNhqWjvVHSDQkaZ2FfltQ+MH7011lO7z+igkNshXRBfs+HB2syXw==", "dependencies": { - "Avalonia": "0.10.7", + "Avalonia": "0.10.8", "Tmds.DBus": "0.9.0" } }, "Avalonia.Native": { "type": "Transitive", - "resolved": "0.10.7", - "contentHash": "1rrTEtvMhIU4atfd6l1nI8npazX2E65cwZ3J66/7lxXaGc/xgYKbZ/uKFHODfv9TRdxRmvcwxk6azJV/Ej86Vg==", + "resolved": "0.10.8", + "contentHash": "FfIeLXDycQglDFqC6KnqgjPFCMZIemgPiB2ShZ8xzqwwFJFKd9WpOSDsEImASSqTVMra0se55vP/Ey2TO7ZVvA==", "dependencies": { - "Avalonia": "0.10.7" + "Avalonia": "0.10.8" } }, "Avalonia.Remote.Protocol": { "type": "Transitive", - "resolved": "0.10.7", - "contentHash": "w8Le0g2StgD1/32mEPYzP0MhMfDyeHvATHFV3IYA2oQTiPoicjUy3To+PuwAB9T9SSi9DtkLhwazlWZOqQGuAw==" + "resolved": "0.10.8", + "contentHash": "flpM/ZF2vkzbHbmSKdq6qWxy/bw/2C1k3Oc73ewlUdwBUWMov6mX99yUWNNI26oYrgD2fpaRhHMukcoSCYqbuQ==" }, "Avalonia.Skia": { "type": "Transitive", - "resolved": "0.10.7", - "contentHash": "dV6WXLk5ziYhnDAwf/fagoVRPTBN4LvFt1BMgikvVKCrkWlmtnQQ/Rav9ESJ13c887XpWMGcERYne3vzeLP6MA==", + "resolved": "0.10.8", + "contentHash": "FsCeOhzDCE4GJnqBGzH/54tqsn0j39Xpkdf3TmuC0MZzjW82Me3GUGeO25E9zs7sEMtX0MKWocmBx6c6ADcGXA==", "dependencies": { - "Avalonia": "0.10.7", + "Avalonia": "0.10.8", "HarfBuzzSharp": "2.6.1.7", "HarfBuzzSharp.NativeAssets.Linux": "2.6.1.7", "SkiaSharp": "2.80.2", @@ -168,10 +177,10 @@ }, "Avalonia.Win32": { "type": "Transitive", - "resolved": "0.10.7", - "contentHash": "pJvd+kYHyZ8OOvThrZ0BkRfTS9xky92pYJ4Aeu8qukdSpTPV06pp5razXNr6FrkVx3CK/3oB8XzLOJdxpRA/VQ==", + "resolved": "0.10.8", + "contentHash": "OUuzYGw4h+9KMvJZkX0bZbQ4T5TTkGdJSyfUdq/WTc4PFV0mp7fF+ofBMSVfFFDsw+7WmGJgN8ZqoPLGFFaPRw==", "dependencies": { - "Avalonia": "0.10.7", + "Avalonia": "0.10.8", "Avalonia.Angle.Windows.Natives": "2.1.0.2020091801", "System.Drawing.Common": "4.5.0", "System.Numerics.Vectors": "4.5.0" @@ -179,39 +188,39 @@ }, "Avalonia.X11": { "type": "Transitive", - "resolved": "0.10.7", - "contentHash": "rvmP/TiEUlCtWio4lJGquW/8+1AI+4MNCWNF4ygPlSj1Z9T38FjFXVPM8Cok2W6U8Y4HTrLo4frN4HTiJAtfdw==", + "resolved": "0.10.8", + "contentHash": "kjzH9q4ZfLIdSoVe9e5lABmpEGs85B7RSk3aynnMDHldwya8mDNOPD6urItNrxQgiU1vOzPXGNjt1WBtveyOkw==", "dependencies": { - "Avalonia": "0.10.7", - "Avalonia.FreeDesktop": "0.10.7", - "Avalonia.Skia": "0.10.7" + "Avalonia": "0.10.8", + "Avalonia.FreeDesktop": "0.10.8", + "Avalonia.Skia": "0.10.8" } }, "Avalonia.Xaml.Behaviors": { "type": "Transitive", - "resolved": "0.10.7.1", - "contentHash": "Ef5PCejEA6F25GadMwVVqATeWrZ7XFouerQvbeIpH2FOD8iS8Vg8vEJFGkHLv1N6HHUF2nZUb01csfs6bOy4Jg==", + "resolved": "0.10.8", + "contentHash": "3nkh36Qp9fK8/Fh/nxqaVMlAzj8iuH5RUcs2rTrcyqn1WPJTslwQrxk+HDMYneuBE9+Oi31ZWiZImEM9kEQN7w==", "dependencies": { - "Avalonia": "0.10.7", - "Avalonia.Xaml.Interactions": "0.10.7.1", - "Avalonia.Xaml.Interactivity": "0.10.7.1" + "Avalonia": "0.10.8", + "Avalonia.Xaml.Interactions": "0.10.8", + "Avalonia.Xaml.Interactivity": "0.10.8" } }, "Avalonia.Xaml.Interactions": { "type": "Transitive", - "resolved": "0.10.7.1", - "contentHash": "ZFgGnjUKbZofMAriGn8xPW/3rt1iww2pUTtOQW8+8YQDtFBjZtq2LaiE0ExX9HgPqgrFM8LYwGcf8SsYZb1pNg==", + "resolved": "0.10.8", + "contentHash": "3pXshQ1pNr+ul7Q2Sn6jjWMHOgRM2uKsUCh95QD2O2wpjgxpRpqiNEy1xPv2+bX2FMWTQIaOdQ8eNM8EunAWMg==", "dependencies": { - "Avalonia": "0.10.7", - "Avalonia.Xaml.Interactivity": "0.10.7.1" + "Avalonia": "0.10.8", + "Avalonia.Xaml.Interactivity": "0.10.8" } }, "Avalonia.Xaml.Interactivity": { "type": "Transitive", - "resolved": "0.10.7.1", - "contentHash": "vLYy2lRISft55wwU7gKTXdBfbdkas1u/bznO05IYCFQzwVRo5ktSs1U1fy6ZzrK5z9Lq/e05GM7Q123n4Dfpow==", + "resolved": "0.10.8", + "contentHash": "ObL26GjME53R3KRkGB97dIB3jwGzyNS/7Www8fZjCEbK4AnjXVgzyw7gkHNsHD9DEZArovvURQI0qvvz3tb24g==", "dependencies": { - "Avalonia": "0.10.7" + "Avalonia": "0.10.8" } }, "Castle.Core": { @@ -659,8 +668,8 @@ }, "ShimSkiaSharp": { "type": "Transitive", - "resolved": "0.5.7.2", - "contentHash": "+KFniLMpqei3Hj1T586ZY/ZDZXXyl6NFLTXvSZ5LvEi96KIcEgbFCuSsNCVfTmnKQaLCn4Gn+KHjqroCJe2FFA==" + "resolved": "0.5.8.3", + "contentHash": "BWwwsIlYUFF0DUc8Pa9xONIXVDvEL9pOYc9YmWilpHrWC37dcK+H4+tfuxztZxtfJx559HGn+6iZmMDjfFoOxA==" }, "SkiaSharp": { "type": "Transitive", @@ -689,13 +698,13 @@ }, "Splat": { "type": "Transitive", - "resolved": "13.1.22", - "contentHash": "0t7eWbu2Ub80kdZjkvXa6r/ZLDAPM/q6WDALkpK4urdGUHl5q2XAmuo5QM0CcIWaEt8AFff8mx0H7qE9PxkG7A==" + "resolved": "13.1.30", + "contentHash": "yaj3r8CvHQwtvhfTi+dp5LpIb3c4svqe/tL6LdAS8wWP+dXAp3fTCLjYx21TrW1QBFTBJcg9lrJqDPbheSzHbA==" }, "Svg.Custom": { "type": "Transitive", - "resolved": "0.5.7.2", - "contentHash": "BLb8ViaXEWWsYvbxtGj+ITNO1CpZEszWT8sE5Xa1qkeoniIENog5PEKGTc5mAJ8MhFc4GYO33Vo9duH0KzizNQ==", + "resolved": "0.5.8.3", + "contentHash": "6FnbI4T3uCNN7DYJpfPFa4caTTJzp4YbhU3J4c/syX7wQNSeQ/1u7JZZ+dGgrRUauiWP8VsiCLKP8qinc5xI5w==", "dependencies": { "Fizzler": "1.2.0", "System.Drawing.Common": "5.0.0", @@ -706,22 +715,22 @@ }, "Svg.Model": { "type": "Transitive", - "resolved": "0.5.7.2", - "contentHash": "txH95pxkg75s2LBcONXFCmrpYp5flUC5aF1DaLwTtt33dv9WvOQQlxnasNyb0CN7t0yaXpX8CZoo+SU9u1E/eA==", + "resolved": "0.5.8.3", + "contentHash": "F/rimPwV5KF64P8oofXGMwOZ0T7b3z1A9OiC4mv5OdSpLpMpUxpSwGLAOkJ5DFqQgXqVjKKLhPdjIjQBwy0AjA==", "dependencies": { - "ShimSkiaSharp": "0.5.7.2", - "Svg.Custom": "0.5.7.2" + "ShimSkiaSharp": "0.5.8.3", + "Svg.Custom": "0.5.8.3" } }, "Svg.Skia": { "type": "Transitive", - "resolved": "0.5.7.2", - "contentHash": "QknpGmwSsns+/05W4efAuPvd77AsimuN5bAGTHGzHQPkPY/htgfXPm2YKywsEIpbXvUiTCfvzaSxSlkYHK8F2g==", + "resolved": "0.5.8.3", + "contentHash": "ajQ0aINQtEzWkqEXyJjnwqOFNusWNMHJVGrKa1ISbP21nrWJh+tApydLFVFGGjs91d7K3YOUbWDKlEzzdDQaOg==", "dependencies": { "SkiaSharp": "2.80.2", "SkiaSharp.HarfBuzz": "2.80.2", - "Svg.Custom": "0.5.7.2", - "Svg.Model": "0.5.7.2" + "Svg.Custom": "0.5.8.3", + "Svg.Model": "0.5.8.3" } }, "System.AppContext": { @@ -1685,11 +1694,11 @@ "type": "Project", "dependencies": { "Artemis.Core": "1.0.0", - "Avalonia": "0.10.7", - "Avalonia.Svg.Skia": "0.10.7.2", - "Avalonia.Xaml.Behaviors": "0.10.7.1", - "Avalonia.Xaml.Interactions": "0.10.7.1", - "Avalonia.Xaml.Interactivity": "0.10.7.1", + "Avalonia": "0.10.8", + "Avalonia.Svg.Skia": "0.10.8.3", + "Avalonia.Xaml.Behaviors": "0.10.8", + "Avalonia.Xaml.Interactions": "0.10.8", + "Avalonia.Xaml.Interactivity": "0.10.8", "Material.Icons.Avalonia": "1.0.2" } }