mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
UI - Added device visualizer and rudementary panzoom
This commit is contained in:
parent
6bbe6b6bbe
commit
ff55168f23
@ -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))));
|
||||
}
|
||||
|
||||
|
||||
@ -7,11 +7,11 @@
|
||||
<StartupObject />
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" Version="0.10.7" />
|
||||
<PackageReference Include="Avalonia.Svg.Skia" Version="0.10.7.2" />
|
||||
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="0.10.7.1" />
|
||||
<PackageReference Include="Avalonia.Xaml.Interactions" Version="0.10.7.1" />
|
||||
<PackageReference Include="Avalonia.Xaml.Interactivity" Version="0.10.7.1" />
|
||||
<PackageReference Include="Avalonia" Version="0.10.8" />
|
||||
<PackageReference Include="Avalonia.Svg.Skia" Version="0.10.8.3" />
|
||||
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="0.10.8" />
|
||||
<PackageReference Include="Avalonia.Xaml.Interactions" Version="0.10.8" />
|
||||
<PackageReference Include="Avalonia.Xaml.Interactivity" Version="0.10.8" />
|
||||
<PackageReference Include="Material.Icons.Avalonia" Version="1.0.2" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@ -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
|
||||
/// </summary>
|
||||
public class DeviceVisualizer : Control
|
||||
{
|
||||
private readonly DispatcherTimer _timer;
|
||||
private const double UpdateFrameRate = 25.0;
|
||||
private readonly List<DeviceVisualizerLed> _deviceVisualizerLeds;
|
||||
private readonly DispatcherTimer _timer;
|
||||
|
||||
private Bitmap? _deviceImage;
|
||||
private RenderTargetBitmap? _deviceImage;
|
||||
private List<DeviceVisualizerLed>? _dimmedLeds;
|
||||
private List<DeviceVisualizerLed>? _highlightedLeds;
|
||||
private ArtemisDevice? _oldDevice;
|
||||
@ -32,8 +36,7 @@ namespace Artemis.UI.Avalonia.Shared.Controls
|
||||
/// <inheritdoc />
|
||||
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<DeviceVisualizerLed>();
|
||||
|
||||
PointerReleased += OnPointerReleased;
|
||||
@ -45,27 +48,35 @@ namespace Artemis.UI.Avalonia.Shared.Controls
|
||||
if (Device == null)
|
||||
return;
|
||||
|
||||
List<DrawingContext.PushedState> 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();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -73,6 +84,13 @@ namespace Artemis.UI.Avalonia.Shared.Controls
|
||||
/// </summary>
|
||||
public event EventHandler<LedClickedEventArgs>? LedClicked;
|
||||
|
||||
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
_deviceImage?.Dispose();
|
||||
_deviceImage = null;
|
||||
base.OnDetachedFromVisualTree(e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="LedClicked" /> event
|
||||
/// </summary>
|
||||
@ -142,7 +160,13 @@ namespace Artemis.UI.Avalonia.Shared.Controls
|
||||
/// Gets or sets the <see cref="ArtemisDevice" /> to display
|
||||
/// </summary>
|
||||
public static readonly StyledProperty<ArtemisDevice?> DeviceProperty =
|
||||
AvaloniaProperty.Register<DeviceVisualizer, ArtemisDevice?>(nameof(Device));
|
||||
AvaloniaProperty.Register<DeviceVisualizer, ArtemisDevice?>(nameof(Device), notifying: DeviceUpdated);
|
||||
|
||||
private static void DeviceUpdated(IAvaloniaObject sender, bool before)
|
||||
{
|
||||
if (!before)
|
||||
((DeviceVisualizer) sender).SetupForDevice();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="ArtemisDevice" /> 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();
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
using System;
|
||||
|
||||
namespace Artemis.UI.Avalonia.Shared.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents errors that occur within the Artemis Shared UI library
|
||||
/// </summary>
|
||||
public class ArtemisSharedUIException : Exception
|
||||
{
|
||||
internal ArtemisSharedUIException()
|
||||
{
|
||||
}
|
||||
|
||||
internal ArtemisSharedUIException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
internal ArtemisSharedUIException(string message, Exception inner) : base(message, inner)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
31
src/Artemis.UI.Avalonia.Shared/Ninject/SharedUIModule.cs
Normal file
31
src/Artemis.UI.Avalonia.Shared/Ninject/SharedUIModule.cs
Normal file
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// The main <see cref="NinjectModule" /> of the Artemis Shared UI toolkit that binds all services
|
||||
/// </summary>
|
||||
public class SharedUIModule : NinjectModule
|
||||
{
|
||||
/// <inheritdoc />
|
||||
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<IArtemisSharedUIService>()
|
||||
.IncludingNonPublicTypes()
|
||||
.SelectAllClasses()
|
||||
.InheritedFrom<IArtemisSharedUIService>()
|
||||
.BindAllInterfaces()
|
||||
.Configure(c => c.InSingletonScope());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
namespace Artemis.UI.Avalonia.Shared.Services.Interfaces
|
||||
{
|
||||
public interface IWindowService : IArtemisSharedUIService
|
||||
{
|
||||
T ShowWindow<T>();
|
||||
|
||||
/// <summary>
|
||||
/// Given a ViewModel, show its corresponding View as a window
|
||||
/// </summary>
|
||||
/// <param name="viewModel">ViewModel to show the View for</param>
|
||||
void ShowWindow(object viewModel);
|
||||
|
||||
/// <summary>
|
||||
/// Given a ViewModel, show its corresponding View as a Dialog
|
||||
/// </summary>
|
||||
/// <param name="viewModel">ViewModel to show the View for</param>
|
||||
/// <returns>DialogResult of the View</returns>
|
||||
bool? ShowDialog(object viewModel);
|
||||
}
|
||||
}
|
||||
52
src/Artemis.UI.Avalonia.Shared/Services/WindowService.cs
Normal file
52
src/Artemis.UI.Avalonia.Shared/Services/WindowService.cs
Normal file
@ -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
|
||||
|
||||
/// <inheritdoc />
|
||||
public T ShowWindow<T>()
|
||||
{
|
||||
T viewModel = _kernel.Get<T>()!;
|
||||
ShowWindow(viewModel);
|
||||
return viewModel;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool? ShowDialog(object viewModel)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -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": {
|
||||
|
||||
@ -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<CoreModule>();
|
||||
_kernel.Load<UIModule>();
|
||||
_kernel.Load<SharedUIModule>();
|
||||
|
||||
_kernel.UseNinjectDependencyResolver();
|
||||
}
|
||||
|
||||
@ -13,16 +13,17 @@
|
||||
<None Remove="Assets\Images\home-banner.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" Version="0.10.7" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="0.10.7" />
|
||||
<PackageReference Include="Avalonia.Diagnostics" Version="0.10.7" />
|
||||
<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.7" />
|
||||
<PackageReference Include="Avalonia.Svg.Skia" Version="0.10.7.2" />
|
||||
<PackageReference Include="Avalonia" Version="0.10.8" />
|
||||
<PackageReference Include="Avalonia.Controls.PanAndZoom" Version="4.2.0" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="0.10.8" />
|
||||
<PackageReference Include="Avalonia.Diagnostics" Version="0.10.8" />
|
||||
<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.8" />
|
||||
<PackageReference Include="Avalonia.Svg.Skia" Version="0.10.8.3" />
|
||||
<PackageReference Include="FluentAvaloniaUI" Version="1.1.3" />
|
||||
<PackageReference Include="Flurl.Http" Version="3.2.0" />
|
||||
<PackageReference Include="Live.Avalonia" Version="1.3.1" />
|
||||
<PackageReference Include="Material.Icons.Avalonia" Version="1.0.2" />
|
||||
<PackageReference Include="Splat.Ninject" Version="13.1.22" />
|
||||
<PackageReference Include="Splat.Ninject" Version="13.1.30" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Artemis.Core\Artemis.Core.csproj" />
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
<ContentControl Grid.Column="0" Content="{Binding SidebarViewModel}" />
|
||||
|
||||
<Border Classes="router-container" Grid.Column="1">
|
||||
<Border Classes="router-container" Grid.Column="1" Margin="0 40 0 0">
|
||||
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" >
|
||||
<reactiveUi:RoutedViewHost Router="{Binding Router}">
|
||||
<reactiveUi:RoutedViewHost.PageTransition>
|
||||
|
||||
@ -20,11 +20,13 @@ namespace Artemis.UI.Avalonia.Screens.Settings.ViewModels
|
||||
{
|
||||
private readonly PluginSetting<LayerBrushReference> _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<LayerBrushProvider> layerBrushProviders = pluginManagementService.GetFeaturesOfType<LayerBrushProvider>();
|
||||
LayerBrushDescriptors = new ObservableCollection<LayerBrushDescriptor>(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);
|
||||
|
||||
@ -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<ArtemisDevice>(rgbService.Devices);
|
||||
}
|
||||
|
||||
public ObservableCollection<ArtemisDevice> Devices { get; }
|
||||
}
|
||||
}
|
||||
@ -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:
|
||||
|
||||
<paz:ZoomBorder Name="ZoomBorder"
|
||||
Stretch="None"
|
||||
ZoomSpeed="1.2"
|
||||
ClipToBounds="True"
|
||||
Focusable="True"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch"
|
||||
ZoomChanged="ZoomBorder_OnZoomChanged">
|
||||
<paz:ZoomBorder.Background>
|
||||
<VisualBrush TileMode="Tile" Stretch="Uniform" SourceRect="0,0,25,25">
|
||||
<VisualBrush.Visual>
|
||||
<Grid Width="25" Height="25" RowDefinitions="*,*" ColumnDefinitions="*,*">
|
||||
<Rectangle Grid.Row="0" Grid.Column="0" Fill="Black" Opacity="0.15" />
|
||||
<Rectangle Grid.Row="0" Grid.Column="1" />
|
||||
<Rectangle Grid.Row="1" Grid.Column="0" />
|
||||
<Rectangle Grid.Row="1" Grid.Column="1" Fill="Black" Opacity="0.15" />
|
||||
</Grid>
|
||||
</VisualBrush.Visual>
|
||||
</VisualBrush>
|
||||
</paz:ZoomBorder.Background>
|
||||
<ItemsControl Items="{Binding Devices}">
|
||||
<ItemsControl.Styles>
|
||||
<Style Selector="ContentPresenter">
|
||||
<Setter Property="Canvas.Left" Value="{Binding X}" />
|
||||
<Setter Property="Canvas.Top" Value="{Binding Y}" />
|
||||
</Style>
|
||||
</ItemsControl.Styles>
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<Canvas />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<controls:DeviceVisualizer
|
||||
Device="{Binding}" ShowColors="True" />
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</paz:ZoomBorder>
|
||||
|
||||
</UserControl>
|
||||
@ -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<SurfaceEditorViewModel>
|
||||
{
|
||||
private readonly ZoomBorder _zoomBorder;
|
||||
|
||||
public SurfaceEditorView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_zoomBorder = this.Find<ZoomBorder>("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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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<DebugViewModel>();
|
||||
}
|
||||
|
||||
public void ShowDebugger()
|
||||
{
|
||||
if (_debugWindow != null)
|
||||
if (_debugViewModel != null)
|
||||
BringDebuggerToForeground();
|
||||
else
|
||||
CreateDebugger();
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -17,7 +17,6 @@
|
||||
|
||||
<!-- Add Styles Here -->
|
||||
<Style Selector="Border.router-container">
|
||||
<Setter Property="Margin" Value="0 40 0 0" />
|
||||
<Setter Property="Background" Value="{DynamicResource SolidBackgroundFillColorTertiary}" />
|
||||
<Setter Property="CornerRadius" Value="8 0 0 0" />
|
||||
<Setter Property="ClipToBounds" Value="True" />
|
||||
@ -29,10 +28,10 @@
|
||||
<Setter Property="CornerRadius" Value="10" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="Separator.card-separator">
|
||||
<Setter Property="Background" Value="{DynamicResource ControlFillColorDefaultBrush}" />
|
||||
<Style Selector="Separator.card-separator">
|
||||
<Setter Property="Background" Value="{DynamicResource ControlFillColorDefaultBrush}" />
|
||||
<Setter Property="Margin" Value="-12 15" />
|
||||
<Setter Property="Height" Value="1" />
|
||||
|
||||
<Setter Property="Height" Value="1" />
|
||||
|
||||
</Style>
|
||||
</Styles>
|
||||
@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user