Meta - Replace WPF projects with Avalonia projects

This commit is contained in:
Robert committed 2022-03-27 11:55:26 +02:00
1 parent fcf0376a9a
commit d7f3ee1190
1110 files changed
+10872 -52240

No files matched your search

@@ -0,0 +1,25 @@
using Avalonia.Controls;
using Avalonia.LogicalTree;
namespace Artemis.UI.Shared.Extensions
{
/// <summary>
/// Provides extension methods for Avalonia's <see cref="Control" /> type
/// </summary>
public static class ControlExtensions
{
/// <summary>
/// Clears all data validation errors on the given control and any of it's logical siblings
/// </summary>
/// <param name="target">The target control</param>
public static void ClearAllDataValidationErrors(this Control target)
{
DataValidationErrors.ClearErrors(target);
foreach (ILogical logicalChild in target.GetLogicalChildren())
{
if (logicalChild is Control childControl)
childControl.ClearAllDataValidationErrors();
}
}
}
}
@@ -0,0 +1,104 @@
using System.Linq;
using Artemis.Core;
using SkiaSharp;
namespace Artemis.UI.Shared.Extensions;
/// <summary>
/// Provides utilities when working with layers in UI elements.
/// </summary>
public static class LayerExtensions
{
/// <summary>
/// Returns the layer's bounds in real coordinates.
/// </summary>
public static SKRect GetLayerBounds(this Layer layer)
{
if (!layer.Leds.Any())
return SKRect.Empty;
return new SKRect(
layer.Leds.Min(l => l.RgbLed.AbsoluteBoundary.Location.X),
layer.Leds.Min(l => l.RgbLed.AbsoluteBoundary.Location.Y),
layer.Leds.Max(l => l.RgbLed.AbsoluteBoundary.Location.X + l.RgbLed.AbsoluteBoundary.Size.Width),
layer.Leds.Max(l => l.RgbLed.AbsoluteBoundary.Location.Y + l.RgbLed.AbsoluteBoundary.Size.Height)
);
}
/// <summary>
/// Returns the layer's anchor in real coordinates.
/// </summary>
public static SKPoint GetLayerAnchorPosition(this Layer layer, SKPoint? positionOverride = null)
{
SKRect layerBounds = GetLayerBounds(layer);
SKPoint positionProperty = layer.Transform.Position.CurrentValue;
if (positionOverride != null)
positionProperty = positionOverride.Value;
// Start at the top left of the shape
SKPoint position = new(layerBounds.Left, layerBounds.Top);
// Apply translation
position.X += positionProperty.X * layerBounds.Width;
position.Y += positionProperty.Y * layerBounds.Height;
return position;
}
/// <summary>
/// Returns an absolute and scaled rectangular path for the given layer in real coordinates.
/// </summary>
public static SKPath GetLayerPath(this Layer layer, bool includeTranslation, bool includeScale, bool includeRotation)
{
SKRect layerBounds = GetLayerBounds(layer);
SKMatrix transform = layer.GetTransformMatrix(false, includeTranslation, includeScale, includeRotation, layerBounds);
SKPath path = new();
path.AddRect(layerBounds);
path.Transform(transform);
return path;
}
/// <summary>
/// Returns a new point normalized to 0.0-1.0
/// </summary>
public static SKPoint GetNormalizedPoint(this Layer layer, SKPoint point, bool absolute)
{
SKRect bounds = GetLayerBounds(layer);
if (absolute)
return new SKPoint(
100 / bounds.Width * (point.X - bounds.Left) / 100,
100 / bounds.Height * (point.Y - bounds.Top) / 100
);
return new SKPoint(
100 / bounds.Width * point.X / 100,
100 / bounds.Height * point.Y / 100
);
}
/// <summary>
/// Returns the offset from the given point to the closest sides of the layer's shape bounds
/// </summary>
public static SKPoint GetDragOffset(this Layer layer, SKPoint dragStart)
{
SKRect bounds = layer.GetLayerPath(true, true, false).Bounds;
SKPoint anchor = layer.GetLayerAnchorPosition();
float xOffset = 0f, yOffset = 0f;
// X offset
if (dragStart.X < anchor.X)
xOffset = bounds.Left - dragStart.X;
else if (dragStart.X > anchor.X)
xOffset = bounds.Right - dragStart.X;
// Y offset
if (dragStart.Y < anchor.Y)
yOffset = bounds.Top - dragStart.Y;
else if (dragStart.Y > anchor.Y)
yOffset = bounds.Bottom - dragStart.Y;
return new SKPoint(xOffset, yOffset);
}
}
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Avalonia;
namespace Artemis.UI.Shared.Extensions
{
public static class PointExtensions
{
public static Point Empty = new(0, 0);
}
}
@@ -0,0 +1,20 @@
using Avalonia.Media;
using SkiaSharp;
namespace Artemis.UI.Shared.Extensions;
/// <summary>
/// Provides extension methods for the <see cref="SKColor"/> type.
/// </summary>
public static class SKColorExtensions
{
/// <summary>
/// Converts a SkiaSharp <see cref="SKColor"/> to an Avalonia <see cref="Color"/>.
/// </summary>
/// <param name="color">The color to convert.</param>
/// <returns>The resulting color.</returns>
public static Color ToColor(this SKColor color)
{
return new Color(color.Alpha, color.Red, color.Green, color.Blue);
}
}
@@ -0,0 +1,19 @@
using Avalonia;
using SkiaSharp;
namespace Artemis.UI.Shared.Extensions;
public static class SKMatrixExtensions
{
public static Matrix ToMatrix(this SKMatrix matrix)
{
return new Matrix(
matrix.ScaleX,
matrix.SkewY,
matrix.SkewX,
matrix.ScaleY,
matrix.TransX,
matrix.TransY
);
}
}
@@ -0,0 +1,17 @@
using Avalonia;
using SkiaSharp;
namespace Artemis.UI.Shared.Extensions;
public static class SKRectExtensions
{
public static Rect ToRect(this SKRect rect)
{
return new Rect(rect.Left, rect.Top, rect.Width, rect.Height);
}
public static Rect ToRect(this SKRectI rect)
{
return new Rect(rect.Left, rect.Top, rect.Width, rect.Height);
}
}
@@ -0,0 +1,37 @@
using Artemis.Core;
using Material.Icons;
using SkiaSharp;
using System;
namespace Artemis.UI.Shared.Extensions
{
/// <summary>
/// Provides utilities when working with types in UI elements.
/// </summary>
public static class TypeExtensions
{
/// <summary>
/// Finds an appropriate Material Design icon for the given <paramref name="type"/>.
/// </summary>
/// <param name="type">The type to retrieve an icon for.</param>
/// <returns>An appropriate Material Design icon for the given <paramref name="type"/>.</returns>
public static MaterialIconKind GetTypeIcon(this Type? type)
{
if (type == null)
return MaterialIconKind.QuestionMarkCircle;
if (type.TypeIsNumber())
return MaterialIconKind.CalculatorVariantOutline;
if (type.IsEnum)
return MaterialIconKind.FormatListBulletedSquare;
if (type == typeof(bool))
return MaterialIconKind.CircleHalfFull;
if (type == typeof(string))
return MaterialIconKind.Text;
if (type == typeof(SKColor))
return MaterialIconKind.Palette;
if (type.IsAssignableTo(typeof(IDataModelEvent)))
return MaterialIconKind.LightningBolt;
return MaterialIconKind.Matrix;
}
}
}
@@ -0,0 +1,62 @@
using System.Collections.Generic;
using System.Linq;
using Avalonia;
using Avalonia.VisualTree;
namespace Artemis.UI.Shared.Extensions;
/// <summary>
/// Provides extension methods for Avalonia's <see cref="IVisual" /> type
/// </summary>
public static class VisualExtensions
{
/// <summary>
/// Returns a recursive list of all visual children of type <typeparamref name="T" />.
/// </summary>
/// <typeparam name="T">The type the children should have.</typeparam>
/// <param name="root">The root visual at which to start searching.</param>
/// <returns>A recursive list of all visual children of type <typeparamref name="T" />.</returns>
public static List<T> GetVisualChildrenOfType<T>(this IVisual root)
{
List<T> result = new();
List<IVisual>? visualChildren = root.GetVisualChildren()?.ToList();
if (visualChildren == null || !visualChildren.Any())
return result;
foreach (IVisual visualChild in visualChildren)
{
if (visualChild is T toFind)
result.Add(toFind);
result.AddRange(GetVisualChildrenOfType<T>(visualChild));
}
return result;
}
/// <summary>
/// Returns a recursive list of all visual children with a data context of type <typeparamref name="T" />.
/// </summary>
/// <typeparam name="T">The type of data context the children should have.</typeparam>
/// <param name="root">The root visual at which to start searching.</param>
/// <returns>A recursive list of all visual children with a data context of type <typeparamref name="T" />.</returns>
public static List<T> GetVisualChildrenOfDataContextType<T>(this IVisual root)
{
List<T> result = new();
List<IVisual>? visualChildren = root.GetVisualChildren()?.ToList();
if (visualChildren == null || !visualChildren.Any())
return result;
foreach (IVisual visualChild in visualChildren)
{
if (visualChild is IDataContextProvider dataContextProvider && dataContextProvider.DataContext is T toFind)
result.Add(toFind);
result.AddRange(GetVisualChildrenOfType<T>(visualChild));
}
return result;
}
}