From 293f7c3d9078714c4ccfb3d6a5263fc3013cf1c9 Mon Sep 17 00:00:00 2001 From: Evgeny Gorbovoy Date: Sun, 15 Dec 2024 17:46:05 +0100 Subject: [PATCH] + more cleanup --- src/.editorconfig | 2 +- .../Drawing/ConsoloniaRenderInterface.cs | 136 ++++++++---------- .../Drawing/DrawingContextImpl.cs | 43 +++--- .../ColorConverter.cs | 4 +- .../DrawingBoxSymbol.cs | 2 +- .../PixelBufferImplementation/Pixel.cs | 4 +- .../PixelBufferCoordinate.cs | 12 +- .../PixelBufferSize.cs | 9 +- src/Consolonia.Core/Drawing/RenderTarget.cs | 2 +- .../Drawing/StreamGeometryImpl.cs | 12 +- src/Consolonia.Core/Helpers/Extensions.cs | 6 +- .../ArrowsAndKeyboardNavigationHandler.cs | 13 +- .../Infrastructure/ConsoleKeyboardDevice.cs | 4 +- .../Infrastructure/ConsoleWindow.cs | 10 +- .../Infrastructure/ConsoloniaApplication.cs | 2 +- .../Infrastructure/ExceptionSink.cs | 8 +- .../Infrastructure/ExceptionSinkExtensions.cs | 2 + .../Infrastructure/NotSupportedRequest.cs | 12 +- .../Infrastructure/SystemStorageFolder.cs | 47 +++--- .../InternalHelpers/FlagTranslator.cs | 13 +- .../Styles/ResourceIncludeBase.cs | 23 +-- src/Consolonia.Core/Text/GlyphTypeface.cs | 4 +- src/Consolonia.sln.DotSettings | 4 +- 23 files changed, 152 insertions(+), 222 deletions(-) diff --git a/src/.editorconfig b/src/.editorconfig index 6ac28d33..f8c01848 100644 --- a/src/.editorconfig +++ b/src/.editorconfig @@ -1064,7 +1064,7 @@ resharper_class_can_be_sealed_global_highlighting = none resharper_class_can_be_sealed_local_highlighting = none resharper_class_never_instantiated_global_highlighting = suggestion resharper_class_never_instantiated_local_highlighting = suggestion -resharper_class_with_virtual_members_never_inherited_global_highlighting = suggestion +resharper_class_with_virtual_members_never_inherited_global_highlighting = hint resharper_class_with_virtual_members_never_inherited_local_highlighting = suggestion resharper_clear_attribute_is_obsolete_all_highlighting = warning resharper_clear_attribute_is_obsolete_highlighting = warning diff --git a/src/Consolonia.Core/Drawing/ConsoloniaRenderInterface.cs b/src/Consolonia.Core/Drawing/ConsoloniaRenderInterface.cs index f77ce63b..c2f0b5f7 100644 --- a/src/Consolonia.Core/Drawing/ConsoloniaRenderInterface.cs +++ b/src/Consolonia.Core/Drawing/ConsoloniaRenderInterface.cs @@ -51,37 +51,35 @@ public IGeometryImpl CreateCombinedGeometry(GeometryCombineMode combineMode, IGe throw new ArgumentException("Only StreamGeometryImpl is supported"); IStreamGeometryImpl newGeometry = CreateStreamGeometry(); - using (IStreamGeometryContextImpl ctx = newGeometry.Open()) - { - // Resharper disable UnusedVariable - bool hasLeftStroke = stream2.Bounds.X.IsNearlyEqual(1); - bool hasTopStroke = stream2.Bounds.Y.IsNearlyEqual(1); - bool hasRightStroke = (stream1.Bounds.Width - stream2.Bounds.Width).IsNearlyEqual(stream2.Bounds.X + 1); - bool hasBottomStroke = - (stream1.Bounds.Height - stream2.Bounds.Height).IsNearlyEqual(stream2.Bounds.Y + 1); - Point topLeft = stream1.Bounds.TopLeft; - Point topRight = stream1.Bounds.TopRight; - Point bottomLeft = stream1.Bounds.BottomLeft; - Point bottomRight = stream1.Bounds.BottomRight; - Line topStroke = stream1.Strokes[0]; - Line rightStroke = stream1.Strokes[1]; - Line bottomStroke = stream1.Strokes[2]; - Line leftStroke = stream1.Strokes[3]; - // Resharper enable UnusedVariable - - // add "null" strokes to establish boundries of box even when there is a single real stroke. - AddStroke(ctx, topLeft, topLeft); - AddStroke(ctx, bottomRight, bottomRight); - - if (hasTopStroke) - AddStroke(ctx, topStroke.PStart, topStroke.PEnd + new Vector(-1, 0)); - if (hasRightStroke) - AddStroke(ctx, rightStroke.PStart + new Vector(-1, 0), rightStroke.PEnd + new Vector(-1, -1)); - if (hasBottomStroke) - AddStroke(ctx, bottomStroke.PStart + new Vector(0, -1), bottomStroke.PEnd + new Vector(-1, -1)); - if (hasLeftStroke) - AddStroke(ctx, leftStroke.PStart, leftStroke.PEnd + new Vector(0, -1)); - } + using IStreamGeometryContextImpl ctx = newGeometry.Open(); + // Resharper disable UnusedVariable + bool hasLeftStroke = stream2.Bounds.X.IsNearlyEqual(1); + bool hasTopStroke = stream2.Bounds.Y.IsNearlyEqual(1); + bool hasRightStroke = (stream1.Bounds.Width - stream2.Bounds.Width).IsNearlyEqual(stream2.Bounds.X + 1); + bool hasBottomStroke = + (stream1.Bounds.Height - stream2.Bounds.Height).IsNearlyEqual(stream2.Bounds.Y + 1); + Point topLeft = stream1.Bounds.TopLeft; + Point topRight = stream1.Bounds.TopRight; + Point bottomLeft = stream1.Bounds.BottomLeft; + Point bottomRight = stream1.Bounds.BottomRight; + Line topStroke = stream1.Strokes[0]; + Line rightStroke = stream1.Strokes[1]; + Line bottomStroke = stream1.Strokes[2]; + Line leftStroke = stream1.Strokes[3]; + // Resharper enable UnusedVariable + + // add "null" strokes to establish boundaries of box even when there is a single real stroke. + AddStroke(ctx, topLeft, topLeft); + AddStroke(ctx, bottomRight, bottomRight); + + if (hasTopStroke) + AddStroke(ctx, topStroke.PStart, topStroke.PEnd + new Vector(-1, 0)); + if (hasRightStroke) + AddStroke(ctx, rightStroke.PStart + new Vector(-1, 0), rightStroke.PEnd + new Vector(-1, -1)); + if (hasBottomStroke) + AddStroke(ctx, bottomStroke.PStart + new Vector(0, -1), bottomStroke.PEnd + new Vector(-1, -1)); + if (hasLeftStroke) + AddStroke(ctx, leftStroke.PStart, leftStroke.PEnd + new Vector(0, -1)); return newGeometry; } @@ -112,10 +110,8 @@ public IWriteableBitmapImpl CreateWriteableBitmap(PixelSize size, Vector dpi, Pi public IBitmapImpl LoadBitmap(string fileName) { - using (FileStream stream = File.OpenRead(fileName)) - { - return new BitmapImpl(stream); - } + using FileStream stream = File.OpenRead(fileName); + return new BitmapImpl(stream); } public IBitmapImpl LoadBitmap(Stream stream) @@ -126,68 +122,56 @@ public IBitmapImpl LoadBitmap(Stream stream) public IWriteableBitmapImpl LoadWriteableBitmapToHeight(Stream stream, int height, BitmapInterpolationMode interpolationMode) { - using (var skStream = new SKManagedStream(stream)) - { - SKBitmap originalBitmap = SKBitmap.Decode(skStream); - int width = (int)(height * ((double)originalBitmap.Width / originalBitmap.Height)); - SKBitmap resizedBitmap = - originalBitmap.Resize(new SKImageInfo(width, height), (SKFilterQuality)interpolationMode); - return new BitmapImpl(resizedBitmap); - } + using var skStream = new SKManagedStream(stream); + SKBitmap originalBitmap = SKBitmap.Decode(skStream); + int width = (int)(height * ((double)originalBitmap.Width / originalBitmap.Height)); + SKBitmap resizedBitmap = + originalBitmap.Resize(new SKImageInfo(width, height), (SKFilterQuality)interpolationMode); + return new BitmapImpl(resizedBitmap); } public IWriteableBitmapImpl LoadWriteableBitmapToWidth(Stream stream, int width, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality) { - using (var skStream = new SKManagedStream(stream)) - { - SKBitmap originalBitmap = SKBitmap.Decode(skStream); - int height = (int)(width * ((double)originalBitmap.Height / originalBitmap.Width)); - SKBitmap resizedBitmap = - originalBitmap.Resize(new SKImageInfo(width, height), (SKFilterQuality)interpolationMode); - return new BitmapImpl(resizedBitmap); - } + using var skStream = new SKManagedStream(stream); + SKBitmap originalBitmap = SKBitmap.Decode(skStream); + int height = (int)(width * ((double)originalBitmap.Height / originalBitmap.Width)); + SKBitmap resizedBitmap = + originalBitmap.Resize(new SKImageInfo(width, height), (SKFilterQuality)interpolationMode); + return new BitmapImpl(resizedBitmap); } public IWriteableBitmapImpl LoadWriteableBitmap(string fileName) { - using (FileStream stream = File.OpenRead(fileName)) - { - return LoadWriteableBitmap(stream); - } + using FileStream stream = File.OpenRead(fileName); + return LoadWriteableBitmap(stream); } public IWriteableBitmapImpl LoadWriteableBitmap(Stream stream) { - using (var skStream = new SKManagedStream(stream)) - { - SKBitmap originalBitmap = SKBitmap.Decode(skStream); - return new BitmapImpl(originalBitmap); - } + using var skStream = new SKManagedStream(stream); + SKBitmap originalBitmap = SKBitmap.Decode(skStream); + return new BitmapImpl(originalBitmap); } public IBitmapImpl LoadBitmapToWidth(Stream stream, int width, BitmapInterpolationMode interpolationMode) { - using (var skStream = new SKManagedStream(stream)) - { - SKBitmap originalBitmap = SKBitmap.Decode(skStream); - int height = (int)(width * ((double)originalBitmap.Height / originalBitmap.Width)); - SKBitmap resizedBitmap = - originalBitmap.Resize(new SKImageInfo(width, height), (SKFilterQuality)interpolationMode); - return new BitmapImpl(resizedBitmap); - } + using var skStream = new SKManagedStream(stream); + SKBitmap originalBitmap = SKBitmap.Decode(skStream); + int height = (int)(width * ((double)originalBitmap.Height / originalBitmap.Width)); + SKBitmap resizedBitmap = + originalBitmap.Resize(new SKImageInfo(width, height), (SKFilterQuality)interpolationMode); + return new BitmapImpl(resizedBitmap); } public IBitmapImpl LoadBitmapToHeight(Stream stream, int height, BitmapInterpolationMode interpolationMode) { - using (var skStream = new SKManagedStream(stream)) - { - SKBitmap originalBitmap = SKBitmap.Decode(skStream); - int width = (int)(height * ((double)originalBitmap.Width / originalBitmap.Height)); - SKBitmap resizedBitmap = - originalBitmap.Resize(new SKImageInfo(width, height), (SKFilterQuality)interpolationMode); - return new BitmapImpl(resizedBitmap); - } + using var skStream = new SKManagedStream(stream); + SKBitmap originalBitmap = SKBitmap.Decode(skStream); + int width = (int)(height * ((double)originalBitmap.Width / originalBitmap.Height)); + SKBitmap resizedBitmap = + originalBitmap.Resize(new SKImageInfo(width, height), (SKFilterQuality)interpolationMode); + return new BitmapImpl(resizedBitmap); } public IBitmapImpl ResizeBitmap(IBitmapImpl bitmapImpl, PixelSize destinationSize, diff --git a/src/Consolonia.Core/Drawing/DrawingContextImpl.cs b/src/Consolonia.Core/Drawing/DrawingContextImpl.cs index 735bae47..0230d727 100644 --- a/src/Consolonia.Core/Drawing/DrawingContextImpl.cs +++ b/src/Consolonia.Core/Drawing/DrawingContextImpl.cs @@ -44,12 +44,12 @@ internal class DrawingContextImpl : IDrawingContextImpl // top left, top right, bottom right, bottom left, private static readonly char[][] CornerChars = - { + [ // LineStyle=Edge we don't draw chars for edge corners [' ', ' ', ' ', ' '], // LineStyle=EdgeWide ['▗', '▖', '▘', '▝'] - }; + ]; private readonly Stack _clipStack = new(100); private readonly ConsoleWindow _consoleWindow; @@ -110,7 +110,7 @@ public void DrawBitmap(IBitmapImpl source, double opacity, Rect sourceRect, Rect bitmap.GetPixel(x, y + 1), bitmap.GetPixel(x + 1, y + 1) }; - // map it to a single char to represet the 4 pixels + // map it to a single char to represent the 4 pixels char quadPixel = GetQuadPixelCharacter(quadColors); // get the combined colors for the quad pixel @@ -160,15 +160,14 @@ public void DrawGeometry(IBrush brush, IPen pen, IGeometryImpl geometry) var color = (Color)extractColorCheckPlatformSupported; - if (lineStyle == null) - lineStyle = LineStyle.SingleLine; + lineStyle ??= LineStyle.SingleLine; - var strokePostions = InferStrokePositions(streamGeometry); + var strokePositions = InferStrokePositions(streamGeometry); - bool hasTop = strokePostions.Contains(RectangleLinePosition.Top); - bool hasRight = strokePostions.Contains(RectangleLinePosition.Right); - bool hasBottom = strokePostions.Contains(RectangleLinePosition.Bottom); - bool hasLeft = strokePostions.Contains(RectangleLinePosition.Left); + bool hasTop = strokePositions.Contains(RectangleLinePosition.Top); + bool hasRight = strokePositions.Contains(RectangleLinePosition.Right); + bool hasBottom = strokePositions.Contains(RectangleLinePosition.Bottom); + bool hasLeft = strokePositions.Contains(RectangleLinePosition.Left); if (lineStyle == LineStyle.Edge || lineStyle == LineStyle.EdgeWide) { @@ -179,10 +178,10 @@ public void DrawGeometry(IBrush brush, IPen pen, IGeometryImpl geometry) if (stroke.Bounds.Width > 0 || stroke.Bounds.Height > 0) { if (stroke.Vertical) - DrawEdgeLine(stroke, strokePostions[iStroke], lineStyle.Value, color, hasTop, + DrawEdgeLine(stroke, strokePositions[iStroke], lineStyle.Value, color, hasTop, hasBottom); else - DrawEdgeLine(stroke, strokePostions[iStroke], lineStyle.Value, color, hasLeft, + DrawEdgeLine(stroke, strokePositions[iStroke], lineStyle.Value, color, hasLeft, hasRight); } } @@ -196,7 +195,7 @@ public void DrawGeometry(IBrush brush, IPen pen, IGeometryImpl geometry) for (int iStroke = 0; iStroke < streamGeometry.Strokes.Count; iStroke++) { Line stroke = streamGeometry.Strokes[iStroke]; - RectangleLinePosition strokePosition = strokePostions[iStroke]; + RectangleLinePosition strokePosition = strokePositions[iStroke]; if (strokePosition == RectangleLinePosition.Left) strokeLeft = stroke; else if (strokePosition == RectangleLinePosition.Right) @@ -411,7 +410,7 @@ private static RectangleLinePosition[] InferStrokePositions(StreamGeometryImpl s for (int i = 0; i < streamGeometry.Strokes.Count; i++) { Line stroke = streamGeometry.Strokes[i]; - if (stroke.Bounds.Width == 0 && stroke.Bounds.Height == 0) + if (stroke.Bounds is { Width: 0, Height: 0 }) { // ignore zero length strokes strokePositions[i] = RectangleLinePosition.Unknown; @@ -547,7 +546,7 @@ private void DrawBoxLineInternal(IPen pen, Line line, RectangleLinePosition line if (lineStyle == null || linePosition == RectangleLinePosition.Unknown) lineStyle = LineStyle.SingleLine; - if (lineStyle == LineStyle.Edge || lineStyle == LineStyle.EdgeWide) + if (lineStyle is LineStyle.Edge or LineStyle.EdgeWide) { DrawEdgeLine(line, linePosition, lineStyle.Value, color, true, true); } @@ -670,7 +669,7 @@ private Line TransformLineInternal(Line line) } /// - /// Draw pixels for a line with linestyle and a pattern + /// Draw pixels for a line with line style and a pattern /// /// the current caret position /// line to render @@ -732,7 +731,7 @@ private void DrawLineSymbolAndMoveHead(ref Point head, bool isVertical, ISymbol // Each glyph maps to a pixel as a starting point. // Emoji's and Ligatures are complex strings, so they start at a point and then overlap following pixels - // the x and y are adjusted accodingly. + // the x and y are adjusted accordingly. foreach (string glyph in text.GetGlyphs(_consoleWindow.Console.SupportsComplexEmoji)) { Point characterPoint = @@ -840,6 +839,7 @@ private static char GetQuadPixelCharacter(params SKColor[] colors) { char character = GetColorsPattern(colors) switch { + // ReSharper disable StringLiteralTypo "FFFF" => ' ', "TFFF" => '▘', "FTFF" => '▝', @@ -856,6 +856,7 @@ private static char GetQuadPixelCharacter(params SKColor[] colors) "TFTT" => '▙', "FTTT" => '▟', "TTTT" => '█', + // ReSharper restore StringLiteralTypo _ => throw new NotImplementedException() }; return character; @@ -974,7 +975,7 @@ private static string GetColorsPattern(SKColor[] colors) if (colors.Length != 4) throw new ArgumentException("Array must contain exactly 4 colors."); // Initial guess: two clusters with the first two colors as centers - SKColor[] clusterCenters = { colors[0], colors[1] }; + SKColor[] clusterCenters = [colors[0], colors[1]]; int[] clusters = new int[colors.Length]; for (int iteration = 0; iteration < 10; iteration++) // limit iterations to avoid infinite loop @@ -989,9 +990,9 @@ private static string GetColorsPattern(SKColor[] colors) var clusteredColors = colors.Where((_, i) => clusters[i] == cluster).ToList(); if (clusteredColors.Any()) newClusterCenters[cluster] = GetAverageColor(clusteredColors); - if (clusteredColors.Count == 4) - if (clusteredColors.All(c => c.Alpha == 0)) - return "FFFF"; + if (clusteredColors.Count != 4) continue; + if (clusteredColors.All(c => c.Alpha == 0)) + return "FFFF"; // return "TTTT"; } diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/ColorConverter.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/ColorConverter.cs index 673456e7..6fe70a1c 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/ColorConverter.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/ColorConverter.cs @@ -9,9 +9,7 @@ public class ColorConverter : JsonConverter public override Color ReadJson(JsonReader reader, Type objectType, Color existingValue, bool hasExistingValue, JsonSerializer serializer) { - if (Color.TryParse(reader.Value!.ToString(), out Color color)) - return color; - return Colors.Transparent; + return Color.TryParse(reader.Value!.ToString(), out Color color) ? color : Colors.Transparent; } public override void WriteJson(JsonWriter writer, Color value, JsonSerializer serializer) diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/DrawingBoxSymbol.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/DrawingBoxSymbol.cs index 11f84590..eaaf67e0 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/DrawingBoxSymbol.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/DrawingBoxSymbol.cs @@ -56,7 +56,7 @@ public ISymbol Blend(ref ISymbol symbolAbove) /// private static char GetBoxSymbol(byte upRightDownLeft) { - //DOS linedraw characters are not ordered in any programmatic manner, and calculating a particular character shape needs to use a look-up table. from https://en.wikipedia.org/wiki/Box-drawing_character + //DOS line draw characters are not ordered in any programmatic manner, and calculating a particular character shape needs to use a look-up table. from https://en.wikipedia.org/wiki/Box-drawing_character byte leftPart = (byte)(upRightDownLeft & 0b1111_0000); bool hasLeftPart = leftPart > 0; diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs index 2f54c442..595a3bcf 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs @@ -94,7 +94,7 @@ public bool Equals(Pixel other) } /// - /// Blend the pixelAbove with the this pixel. + /// Blend the pixelAbove with this pixel. /// /// /// @@ -172,7 +172,7 @@ private static Color MergeColors(Color target, Color source) public override bool Equals([NotNullWhen(true)] object obj) { - return obj is Pixel && Equals((Pixel)obj); + return obj is Pixel pixel && Equals(pixel); } public override int GetHashCode() diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBufferCoordinate.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBufferCoordinate.cs index 2bd57735..24c69266 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBufferCoordinate.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBufferCoordinate.cs @@ -5,16 +5,10 @@ namespace Consolonia.Core.Drawing.PixelBufferImplementation { - public readonly struct PixelBufferCoordinate + public readonly struct PixelBufferCoordinate(ushort x, ushort y) { - public PixelBufferCoordinate(ushort x, ushort y) - { - X = x; - Y = y; - } - - public ushort X { get; } - public ushort Y { get; } + public ushort X { get; } = x; + public ushort Y { get; } = y; public void Deconstruct(out ushort x, out ushort y) { diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBufferSize.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBufferSize.cs index 1a1fed57..5de84aa4 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBufferSize.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBufferSize.cs @@ -1,13 +1,8 @@ namespace Consolonia.Core.Drawing.PixelBufferImplementation { - public readonly struct PixelBufferSize + public readonly struct PixelBufferSize(ushort width, ushort height) { - public PixelBufferSize(ushort width, ushort height) - { - RightBottom = new PixelBufferCoordinate(width, height); - } - - private PixelBufferCoordinate RightBottom { get; } + private PixelBufferCoordinate RightBottom { get; } = new(width, height); public ushort Width => RightBottom.X; public ushort Height => RightBottom.Y; diff --git a/src/Consolonia.Core/Drawing/RenderTarget.cs b/src/Consolonia.Core/Drawing/RenderTarget.cs index 9d5b4555..35665b86 100644 --- a/src/Consolonia.Core/Drawing/RenderTarget.cs +++ b/src/Consolonia.Core/Drawing/RenderTarget.cs @@ -90,7 +90,7 @@ private void OnResized(Size size, WindowResizeReason reason) { var cache = new Pixel?[width, height]; - // initalize the cache with Pixel.Empty as it literally means nothing + // initialize the cache with Pixel.Empty as it literally means nothing for (ushort y = 0; y < height; y++) for (ushort x = 0; x < width; x++) cache[x, y] = Pixel.Empty; diff --git a/src/Consolonia.Core/Drawing/StreamGeometryImpl.cs b/src/Consolonia.Core/Drawing/StreamGeometryImpl.cs index e2279c9f..6c0627ad 100644 --- a/src/Consolonia.Core/Drawing/StreamGeometryImpl.cs +++ b/src/Consolonia.Core/Drawing/StreamGeometryImpl.cs @@ -10,14 +10,8 @@ namespace Consolonia.Core.Drawing { internal class StreamGeometryImpl : IStreamGeometryImpl { - private readonly List _fills; - private readonly List _strokes; - - public StreamGeometryImpl() - { - _strokes = new List(); - _fills = new List(); - } + private readonly List _fills = []; + private readonly List _strokes = []; public IReadOnlyList Strokes => _strokes; @@ -94,7 +88,7 @@ public ITransformedGeometryImpl WithTransform(Matrix transform) } /// - /// A Conolonia implementation of a . + /// A Consolonia implementation of a . /// private class StreamGeometryContextImpl : IStreamGeometryContextImpl, IGeometryContext2 { diff --git a/src/Consolonia.Core/Helpers/Extensions.cs b/src/Consolonia.Core/Helpers/Extensions.cs index d1497233..02cf618c 100644 --- a/src/Consolonia.Core/Helpers/Extensions.cs +++ b/src/Consolonia.Core/Helpers/Extensions.cs @@ -49,8 +49,8 @@ public static void AddConsoloniaDesignMode(this Application application) }); // EXPERIMENTAL - // If you do RenderTRansform="scale(10.0,10.0) you can actually sort of see the UI get bigger - // but this doesn' seem to work when using these style setters. + // If you do RenderTransform="scale(10.0,10.0) you can actually sort of see the UI get bigger + // but this doesn't seem to work when using these style setters. //this.Styles.Add(new Style(x => x.Is()) //{ // Setters = @@ -138,7 +138,7 @@ public static IReadOnlyList GetGlyphs(this string text, bool supportsCom public static ushort MeasureText(this string text) { var console = AvaloniaLocator.Current.GetService(); - bool supportsComplexEmoji = console != null ? console.SupportsComplexEmoji : true; + bool supportsComplexEmoji = console == null || console.SupportsComplexEmoji; ushort width = 0; ushort lastWidth = 0; foreach (Rune rune in text.EnumerateRunes()) diff --git a/src/Consolonia.Core/Infrastructure/ArrowsAndKeyboardNavigationHandler.cs b/src/Consolonia.Core/Infrastructure/ArrowsAndKeyboardNavigationHandler.cs index dd4777fc..a8028631 100644 --- a/src/Consolonia.Core/Infrastructure/ArrowsAndKeyboardNavigationHandler.cs +++ b/src/Consolonia.Core/Infrastructure/ArrowsAndKeyboardNavigationHandler.cs @@ -9,18 +9,14 @@ namespace Consolonia.Core.Infrastructure { + // ReSharper disable once ClassNeverInstantiated.Global public class ArrowsAndKeyboardNavigationHandler : IKeyboardNavigationHandler { - private readonly IKeyboardNavigationHandler _keyboardNavigationHandler; + private readonly IKeyboardNavigationHandler _keyboardNavigationHandler = new KeyboardNavigationHandler(); //todo: check XTFocus https://github.com/jinek/Consolonia/issues/105#issuecomment-2089015880 private IInputRoot _owner; - public ArrowsAndKeyboardNavigationHandler() - { - _keyboardNavigationHandler = new KeyboardNavigationHandler(); - } - public void SetOwner(IInputRoot owner) { _keyboardNavigationHandler.SetOwner(owner); @@ -129,14 +125,13 @@ private void OnKeyDown(object sender, KeyEventArgs e) if (e.Key == Key.Escape) { - // if there is a overlay popup, close it + // if there is an overlay popup, close it OverlayPopupHost overlay = sender as OverlayPopupHost ?? ((Visual)sender).FindDescendantOfType(); if (overlay != null) { // it will have a popup as the parent. - var popup = overlay.Parent as Popup; - if (popup != null) + if (overlay.Parent is Popup popup) popup.Close(); e.Handled = true; return; diff --git a/src/Consolonia.Core/Infrastructure/ConsoleKeyboardDevice.cs b/src/Consolonia.Core/Infrastructure/ConsoleKeyboardDevice.cs index 951e5346..9f3635af 100644 --- a/src/Consolonia.Core/Infrastructure/ConsoleKeyboardDevice.cs +++ b/src/Consolonia.Core/Infrastructure/ConsoleKeyboardDevice.cs @@ -2,7 +2,5 @@ namespace Consolonia.Core.Infrastructure { - internal class ConsoleKeyboardDevice : KeyboardDevice - { - } + internal class ConsoleKeyboardDevice : KeyboardDevice; } \ No newline at end of file diff --git a/src/Consolonia.Core/Infrastructure/ConsoleWindow.cs b/src/Consolonia.Core/Infrastructure/ConsoleWindow.cs index e7082f4c..3dc48c69 100644 --- a/src/Consolonia.Core/Infrastructure/ConsoleWindow.cs +++ b/src/Consolonia.Core/Infrastructure/ConsoleWindow.cs @@ -41,7 +41,7 @@ public ConsoleWindow() PixelBuffer = new PixelBuffer(Console.Size); } - public PixelBuffer PixelBuffer { get; set; } + public PixelBuffer PixelBuffer { get; private set; } private IMouseDevice MouseDevice { get; } @@ -103,7 +103,7 @@ public Size ClientSize public Size? FrameSize => ClientSize; public double RenderScaling => 1; - public IEnumerable Surfaces => new[] { this }; + public IEnumerable Surfaces => [this]; public Action Input { get; set; } @@ -191,7 +191,7 @@ public void ShowTaskbarIcon(bool value) public void CanResize(bool value) { - // todo, enable/dsiable resizing of window + // todo, enable/disable resizing of window } public void BeginMoveDrag(PointerPressedEventArgs e) @@ -270,7 +270,7 @@ public object TryGetFeature(Type featureType) } // TODO ISystemNavigationManagerImpl should be implemented to handle BACK navigation between pages of controls like mobile apps do. - // TODO ITextInputMethodImplshould be implemented to handle text IME input + // TODO ITextInputMethodImpl should be implemented to handle text IME input Debug.WriteLine($"Missing Feature: {featureType.Name} is not implemented but someone is asking for it!"); return null; } @@ -352,7 +352,9 @@ private void OnConsoleOnResized() oldCts?.Cancel(); oldCts?.Dispose(); + // ReSharper disable once GrammarMistakeInComment // start a task which if no resize event comes for _resizeDelay will post the resize to the window + // ReSharper disable once MethodSupportsCancellation Task.Run(async () => { try diff --git a/src/Consolonia.Core/Infrastructure/ConsoloniaApplication.cs b/src/Consolonia.Core/Infrastructure/ConsoloniaApplication.cs index c537e0e1..31e034ed 100644 --- a/src/Consolonia.Core/Infrastructure/ConsoloniaApplication.cs +++ b/src/Consolonia.Core/Infrastructure/ConsoloniaApplication.cs @@ -23,7 +23,7 @@ public override void RegisterServices() public override void OnFrameworkInitializationCompleted() { - // override AccessText to use ConsoloniaAccessText as default contentpresenter for unknown data types (aka string) + // override AccessText to use ConsoloniaAccessText as default ContentPresenter for unknown data types (aka string) DataTemplates.Add(new FuncDataTemplate( (data, _) => { diff --git a/src/Consolonia.Core/Infrastructure/ExceptionSink.cs b/src/Consolonia.Core/Infrastructure/ExceptionSink.cs index 77c36bf8..2b620b3d 100644 --- a/src/Consolonia.Core/Infrastructure/ExceptionSink.cs +++ b/src/Consolonia.Core/Infrastructure/ExceptionSink.cs @@ -14,25 +14,25 @@ public bool IsEnabled(LogEventLevel level, string area) public void Log(LogEventLevel level, string area, object source, string messageTemplate) { - Log(level, area, source, messageTemplate, Array.Empty()); + Log(level, area, source, messageTemplate, []); } // ReSharper disable UnusedMember.Global public void Log(LogEventLevel level, string area, object source, string messageTemplate, T0 propertyValue0) { - Log(level, area, source, messageTemplate, new object[] { propertyValue0 }); + Log(level, area, source, messageTemplate, [propertyValue0]); } public void Log(LogEventLevel level, string area, object source, string messageTemplate, T0 propertyValue0, T1 propertyValue1) { - Log(level, area, source, messageTemplate, new object[] { propertyValue0, propertyValue1 }); + Log(level, area, source, messageTemplate, [propertyValue0, propertyValue1]); } public void Log(LogEventLevel level, string area, object source, string messageTemplate, T0 propertyValue0, T1 propertyValue1, T2 propertyValue2) { - Log(level, area, source, messageTemplate, new object[] { propertyValue0, propertyValue1, propertyValue2 }); + Log(level, area, source, messageTemplate, [propertyValue0, propertyValue1, propertyValue2]); } public void Log(LogEventLevel level, string area, object source, string messageTemplate, diff --git a/src/Consolonia.Core/Infrastructure/ExceptionSinkExtensions.cs b/src/Consolonia.Core/Infrastructure/ExceptionSinkExtensions.cs index ea4df246..9d70dbf1 100644 --- a/src/Consolonia.Core/Infrastructure/ExceptionSinkExtensions.cs +++ b/src/Consolonia.Core/Infrastructure/ExceptionSinkExtensions.cs @@ -3,7 +3,9 @@ using Consolonia.Core.Infrastructure; // ReSharper disable CheckNamespace +#pragma warning disable IDE0130 namespace Consolonia +#pragma warning restore IDE0130 // ReSharper disable once ArrangeNamespaceBody { public static class ExceptionSinkExtensions diff --git a/src/Consolonia.Core/Infrastructure/NotSupportedRequest.cs b/src/Consolonia.Core/Infrastructure/NotSupportedRequest.cs index 303ae466..f18ed49b 100644 --- a/src/Consolonia.Core/Infrastructure/NotSupportedRequest.cs +++ b/src/Consolonia.Core/Infrastructure/NotSupportedRequest.cs @@ -6,18 +6,12 @@ namespace Consolonia.Core.Infrastructure { - public sealed class NotSupportedRequest + public sealed class NotSupportedRequest(int errorCode, IList information) { - public NotSupportedRequest(int errorCode, IList information) - { - ErrorCode = errorCode; - Information = new ReadOnlyCollection(information); - } - public bool Handled { get; private set; } - public int ErrorCode { get; } + public int ErrorCode { get; } = errorCode; - public ReadOnlyCollection Information { get; } + public ReadOnlyCollection Information { get; } = new(information); [DebuggerStepThrough] internal void CheckHandled() diff --git a/src/Consolonia.Core/Infrastructure/SystemStorageFolder.cs b/src/Consolonia.Core/Infrastructure/SystemStorageFolder.cs index 2eba8955..6fb111c8 100644 --- a/src/Consolonia.Core/Infrastructure/SystemStorageFolder.cs +++ b/src/Consolonia.Core/Infrastructure/SystemStorageFolder.cs @@ -8,30 +8,19 @@ namespace Consolonia.Core.Infrastructure { [DebuggerDisplay("Folder: {Name}")] - public sealed class SystemStorageFolder : IStorageFolder + public sealed class SystemStorageFolder(DirectoryInfo directoryInfo, bool isParent = false) : IStorageFolder { - private readonly DirectoryInfo _directoryInfo; - private readonly bool _isParent; - - public SystemStorageFolder(string path) - { - _directoryInfo = new DirectoryInfo(path); - } - - public SystemStorageFolder(Uri uri) + public SystemStorageFolder(string path) : this(new DirectoryInfo(path)) { - _directoryInfo = new DirectoryInfo(uri.LocalPath); } - public SystemStorageFolder(DirectoryInfo directoryInfo, bool isParent = false) + public SystemStorageFolder(Uri uri) : this(new DirectoryInfo(uri.LocalPath)) { - _isParent = isParent; - _directoryInfo = directoryInfo; } - public string Name => _isParent ? ".." : _directoryInfo.Name; + public string Name => isParent ? ".." : directoryInfo.Name; - public Uri Path => new($"file://{_directoryInfo.FullName}"); + public Uri Path => new($"file://{directoryInfo.FullName}"); public bool CanBookmark => false; @@ -39,8 +28,8 @@ public async Task CreateFileAsync(string name) { await Task.CompletedTask; - string path = System.IO.Path.Combine(_directoryInfo.FullName, name); - using (FileStream stream = File.Create(path)) + string path = System.IO.Path.Combine(directoryInfo.FullName, name); + await using (FileStream stream = File.Create(path)) { await stream.WriteAsync(Array.Empty().AsMemory(0, 0)); } @@ -50,13 +39,13 @@ public async Task CreateFileAsync(string name) public Task CreateFolderAsync(string name) { - DirectoryInfo dirInfo = Directory.CreateDirectory(System.IO.Path.Combine(_directoryInfo.FullName, name)); + DirectoryInfo dirInfo = Directory.CreateDirectory(System.IO.Path.Combine(directoryInfo.FullName, name)); return Task.FromResult((IStorageFolder)new SystemStorageFolder(dirInfo)); } public Task DeleteAsync() { - return Task.Run(() => _directoryInfo.Delete()); + return Task.Run(directoryInfo.Delete); } public void Dispose() @@ -65,8 +54,8 @@ public void Dispose() public Task GetBasicPropertiesAsync() { - var properties = new StorageItemProperties(dateCreated: _directoryInfo.CreationTime, - dateModified: _directoryInfo.LastAccessTime); + var properties = new StorageItemProperties(dateCreated: directoryInfo.CreationTime, + dateModified: directoryInfo.LastAccessTime); return Task.FromResult(properties); } @@ -74,27 +63,27 @@ public async IAsyncEnumerable GetItemsAsync() { await Task.CompletedTask; - if (_directoryInfo.Exists) + if (directoryInfo.Exists) { - foreach (DirectoryInfo folder in _directoryInfo.GetDirectories()) + foreach (DirectoryInfo folder in directoryInfo.GetDirectories()) yield return new SystemStorageFolder(folder); - foreach (FileInfo file in _directoryInfo.GetFiles()) yield return new SystemStorageFile(file); + foreach (FileInfo file in directoryInfo.GetFiles()) yield return new SystemStorageFile(file); } } public Task GetParentAsync() { - if (_directoryInfo.Parent == null) + if (directoryInfo.Parent == null) return Task.FromResult((IStorageFolder)null); - return Task.FromResult((IStorageFolder)new SystemStorageFolder(_directoryInfo.Parent)); + return Task.FromResult((IStorageFolder)new SystemStorageFolder(directoryInfo.Parent)); } public Task MoveAsync(IStorageFolder destination) { - string targetPath = System.IO.Path.Combine(destination.Path.LocalPath, _directoryInfo.Name); - _directoryInfo.MoveTo(targetPath); + string targetPath = System.IO.Path.Combine(destination.Path.LocalPath, directoryInfo.Name); + directoryInfo.MoveTo(targetPath); return Task.FromResult((IStorageItem)new SystemStorageFolder(targetPath)); } diff --git a/src/Consolonia.Core/InternalHelpers/FlagTranslator.cs b/src/Consolonia.Core/InternalHelpers/FlagTranslator.cs index 84e3aa11..3c55cf2d 100644 --- a/src/Consolonia.Core/InternalHelpers/FlagTranslator.cs +++ b/src/Consolonia.Core/InternalHelpers/FlagTranslator.cs @@ -2,15 +2,10 @@ namespace Consolonia.Core.InternalHelpers { - public class FlagTranslator where TInput : Enum where TOutput : Enum + public class FlagTranslator((TInput inFlag, TOutput outFlag)[] mapping) + where TInput : Enum + where TOutput : Enum { - private readonly (TInput inFlag, TOutput outFlag)[] _mapping; - - public FlagTranslator((TInput inFlag, TOutput outFlag)[] mapping) - { - _mapping = mapping; - } - public TOutput Translate(TInput input) { return Translate(input, false); @@ -19,7 +14,7 @@ public TOutput Translate(TInput input) public TOutput Translate(TInput input, bool singleValueOnly) { TOutput output = default; - foreach ((TInput inFlag, TOutput outFlag) in _mapping) + foreach ((TInput inFlag, TOutput outFlag) in mapping) if (singleValueOnly) { if (input.Equals(inFlag)) diff --git a/src/Consolonia.Core/Styles/ResourceIncludeBase.cs b/src/Consolonia.Core/Styles/ResourceIncludeBase.cs index 0b41173d..898e4a28 100644 --- a/src/Consolonia.Core/Styles/ResourceIncludeBase.cs +++ b/src/Consolonia.Core/Styles/ResourceIncludeBase.cs @@ -9,20 +9,13 @@ namespace Consolonia.Core.Styles { // Copy-paste from FluentTheme from Avalonia - public abstract class ResourceIncludeBase : IResourceProvider, IStyle + public abstract class ResourceIncludeBase(Uri baseUri) : IResourceProvider, IStyle { - private readonly Uri _baseUri; private bool _isLoading; private IStyle[] _loaded; - protected ResourceIncludeBase(Uri baseUri) + protected ResourceIncludeBase(IServiceProvider serviceProvider) : this(((IUriContext)serviceProvider.GetService(typeof(IUriContext)))!.BaseUri) { - _baseUri = baseUri; - } - - protected ResourceIncludeBase(IServiceProvider serviceProvider) - { - _baseUri = ((IUriContext)serviceProvider.GetService(typeof(IUriContext)))!.BaseUri; } protected abstract Uri Uri { get; } @@ -38,8 +31,8 @@ public IStyle Loaded if (_loaded == null) { _isLoading = true; - var loaded = (IStyle)AvaloniaXamlLoader.Load(Uri, _baseUri); - _loaded = new[] { loaded }; + var loaded = (IStyle)AvaloniaXamlLoader.Load(Uri, baseUri); + _loaded = [loaded]; _isLoading = false; } @@ -81,13 +74,7 @@ public event EventHandler OwnerChanged if (Loaded is IResourceProvider rp) rp.OwnerChanged -= value; } } - - /*todo: remove - public SelectorMatchResult TryAttach(IStyleable target, IStyleHost host) - { - return Loaded.TryAttach(target, host); - }*/ - + public IReadOnlyList Children => _loaded ?? Array.Empty(); } } \ No newline at end of file diff --git a/src/Consolonia.Core/Text/GlyphTypeface.cs b/src/Consolonia.Core/Text/GlyphTypeface.cs index 9f5bee0b..67550068 100644 --- a/src/Consolonia.Core/Text/GlyphTypeface.cs +++ b/src/Consolonia.Core/Text/GlyphTypeface.cs @@ -63,8 +63,8 @@ public bool TryGetTable(uint tag, out byte[] table) } public string FamilyName { get; } = FontManagerImpl.GetTheOnlyFontFamilyName(); - public FontWeight Weight { get; set; } = FontWeight.Normal; - public FontStyle Style { get; set; } = FontStyle.Normal; + public FontWeight Weight { get; init; } = FontWeight.Normal; + public FontStyle Style { get; init; } = FontStyle.Normal; public FontStretch Stretch => FontStretch.Normal; public int GlyphCount => char.MaxValue; diff --git a/src/Consolonia.sln.DotSettings b/src/Consolonia.sln.DotSettings index 7d447234..601111e0 100644 --- a/src/Consolonia.sln.DotSettings +++ b/src/Consolonia.sln.DotSettings @@ -15,5 +15,7 @@ True True True + True True - True \ No newline at end of file + True + True \ No newline at end of file