From e06c08b7c5487cc1cceec34620d5b3dee25dd2e9 Mon Sep 17 00:00:00 2001 From: Evgeny Gorbovoy Date: Wed, 25 Dec 2024 05:32:49 +0100 Subject: [PATCH 01/23] Half way to remove ConsoleBrush --- .../Controls/Dialog/DialogWrap.axaml | 2 +- src/Consolonia.Core/Drawing/ConsoleBrush.cs | 101 ++---------------- .../Drawing/DrawingContextImpl.cs | 30 ++---- .../PixelBufferImplementation/Pixel.cs | 60 +++++------ .../PixelBackground.cs | 18 +--- .../PixelBackgroundMode.cs | 2 +- src/Consolonia.NUnit/UnitTestConsole.cs | 2 +- .../Helpers/ConsoloniaTextPresenter.cs | 9 +- 8 files changed, 52 insertions(+), 172 deletions(-) diff --git a/src/Consolonia.Core/Controls/Dialog/DialogWrap.axaml b/src/Consolonia.Core/Controls/Dialog/DialogWrap.axaml index 89fcd51e..489839d8 100644 --- a/src/Consolonia.Core/Controls/Dialog/DialogWrap.axaml +++ b/src/Consolonia.Core/Controls/Dialog/DialogWrap.axaml @@ -4,7 +4,7 @@ x:Class="Consolonia.Core.Controls.Dialog.DialogWrap"> - diff --git a/src/Consolonia.Core/Drawing/ConsoleBrush.cs b/src/Consolonia.Core/Drawing/ConsoleBrush.cs index a2d3bc88..c13ddf50 100644 --- a/src/Consolonia.Core/Drawing/ConsoleBrush.cs +++ b/src/Consolonia.Core/Drawing/ConsoleBrush.cs @@ -7,90 +7,10 @@ namespace Consolonia.Core.Drawing { - [DebuggerDisplay("{Color} [{Mode}]")] - public class ConsoleBrush : AvaloniaObject, IImmutableBrush + public static class ConsoleBrush2 { - public static readonly StyledProperty ColorProperty = - AvaloniaProperty.Register(nameof(Color)); - - public static readonly StyledProperty ModeProperty = - AvaloniaProperty.Register(nameof(Mode)); - - // ReSharper disable once UnusedMember.Global - public ConsoleBrush(Color color, PixelBackgroundMode mode) : this(color) - { - Mode = mode; - } - - public ConsoleBrush(Color color) - { - Color = color; - } - - public ConsoleBrush() - { - } - - public PixelBackgroundMode Mode - { - get => GetValue(ModeProperty); - set => SetValue(ModeProperty, value); - } - - public Color Color - { - get => GetValue(ColorProperty); - set => SetValue(ColorProperty, value); - } - - public double Opacity => 1; - public ITransform Transform => null; - public RelativePoint TransformOrigin => RelativePoint.TopLeft; - - /// - /// Convert a IBrush to a Brush. - /// - /// - /// NOTE: If it's a ConsoleBrush it will be passed through unchanged, unless mode is set then it will convert - /// consolebrush to mode - /// - /// - /// Default is Colored. - /// - public static ConsoleBrush FromBrush(IBrush brush, PixelBackgroundMode? mode = null) - { - ArgumentNullException.ThrowIfNull(brush, nameof(brush)); - - switch (brush) - { - case ConsoleBrush consoleBrush: - if (mode != null && consoleBrush.Mode != mode) - return new ConsoleBrush(consoleBrush.Color, mode.Value); - return consoleBrush; - - case LineBrush lineBrush: - switch (lineBrush.Brush) - { - case ConsoleBrush consoleBrush: - return consoleBrush; - case ISolidColorBrush br: - return new ConsoleBrush(br.Color, mode ?? PixelBackgroundMode.Colored); - default: - ConsoloniaPlatform.RaiseNotSupported(6); - return null; - } - - case ISolidColorBrush solidBrush: - return new ConsoleBrush(solidBrush.Color, mode ?? PixelBackgroundMode.Colored); - - default: - ConsoloniaPlatform.RaiseNotSupported(6); - return null; - } - } - - public static ConsoleBrush FromPosition(IBrush brush, int x, int y, int width, int height) - { + public static Color FromPosition(IBrush brush, int x, int y, int width, int height) + {//todo: apply brush opacity ArgumentNullException.ThrowIfNull(brush); if (x < 0 || x > width) throw new ArgumentOutOfRangeException(nameof(x), "x is out bounds"); @@ -115,7 +35,7 @@ public static ConsoleBrush FromPosition(IBrush brush, int x, int y, int width, i // Average the two colors to get the final color Color color = BlendColors(horizontalColor, verticalColor); - return new ConsoleBrush(color); + return color; } case IRadialGradientBrush radialBrush: { @@ -142,7 +62,7 @@ public static ConsoleBrush FromPosition(IBrush brush, int x, int y, int width, i // Interpolate the color based on the normalized distance Color color = InterpolateColor(radialBrush, normalizedDistance); - return new ConsoleBrush(color); + return color; } case IConicGradientBrush conicBrush: { @@ -160,21 +80,14 @@ public static ConsoleBrush FromPosition(IBrush brush, int x, int y, int width, i // Average the two colors to get the final color Color color = BlendColors(horizontalColor, verticalColor); - return new ConsoleBrush(color); + return color; } default: - return FromBrush(brush); + return ((SolidColorBrush)brush).Color; } } - // ReSharper disable once UnusedMember.Global used by Avalonia - // ReSharper disable once UnusedParameter.Global - public IBrush ProvideValue(IServiceProvider _) - { - return this; - } - private static Color InterpolateColor(IGradientBrush brush, double relativePosition) { IGradientStop before = null; diff --git a/src/Consolonia.Core/Drawing/DrawingContextImpl.cs b/src/Consolonia.Core/Drawing/DrawingContextImpl.cs index 3582dee6..a75eaf9e 100644 --- a/src/Consolonia.Core/Drawing/DrawingContextImpl.cs +++ b/src/Consolonia.Core/Drawing/DrawingContextImpl.cs @@ -528,12 +528,11 @@ private void FillRectangleWithBrush(IBrush brush, IPen pen, Rect r) int px = (int)(r2.TopLeft.X + x); int py = (int)(r2.TopLeft.Y + y); - ConsoleBrush backgroundBrush = ConsoleBrush.FromPosition(brush, x, y, (int)width, (int)height); + Color backgroundColor = ConsoleBrush2.FromPosition(brush, x, y, (int)width, (int)height); CurrentClip.ExecuteWithClipping(new Point(px, py), () => { _pixelBuffer.Set(new PixelBufferCoordinate((ushort)px, (ushort)py), - pixel => pixel.Blend(new Pixel(new PixelBackground(backgroundBrush.Mode, - backgroundBrush.Color)))); + pixel => pixel.Blend(new Pixel(new PixelBackground(backgroundColor)))); }); } } @@ -653,9 +652,9 @@ private Line TransformLineInternal(Line line) lineStyle = null; if (pen is not { - Brush: ConsoleBrush or LineBrush or ImmutableSolidColorBrush, + Brush: LineBrush or ImmutableSolidColorBrush, // Thickness: 1, - DashStyle: null or { Dashes: { Count: 0 } }, + DashStyle: null or { Dashes.Count: 0 }, LineCap: PenLineCap.Flat, LineJoin: PenLineJoin.Miter }) @@ -667,20 +666,9 @@ private Line TransformLineInternal(Line line) if (pen.Brush is LineBrush lineBrush) lineStyle = lineBrush.LineStyle; - ConsoleBrush consoleBrush = ConsoleBrush.FromBrush(pen.Brush); - switch (consoleBrush.Mode) - { - case PixelBackgroundMode.Colored: - return consoleBrush.Color; - case PixelBackgroundMode.Transparent: - return null; - case PixelBackgroundMode.Shaded: - ConsoloniaPlatform.RaiseNotSupported(8); - return null; - default: - throw new ArgumentOutOfRangeException(nameof(pen)); - } + Color consoleBrush = ((ImmutableSolidColorBrush)pen.Brush).Color; + return consoleBrush; } /// @@ -731,8 +719,8 @@ private void DrawLineSymbolAndMoveHead(ref Point head, bool isVertical, ISymbol private void DrawStringInternal(IBrush foreground, string text, IGlyphTypeface typeface, Point origin = new()) { - foreground = ConsoleBrush.FromBrush(foreground); - if (foreground is not ConsoleBrush { Mode: PixelBackgroundMode.Colored } consoleBrush) + + if (foreground is not ImmutableSolidColorBrush immutableSolidColorBrush) { ConsoloniaPlatform.RaiseNotSupported(4); return; @@ -751,7 +739,7 @@ private void DrawLineSymbolAndMoveHead(ref Point head, bool isVertical, ISymbol { Point characterPoint = whereToDraw.Transform(Matrix.CreateTranslation(currentXPosition, currentYPosition)); - Color foregroundColor = consoleBrush.Color; + Color foregroundColor = immutableSolidColorBrush.Color; switch (glyph) { diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs index 595a3bcf..f798ccb5 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs @@ -40,7 +40,7 @@ public Pixel(ISymbol symbol, FontWeight weight = FontWeight.Normal, TextDecorationLocation? textDecorations = null) : this( new PixelForeground(symbol, foregroundColor, weight, style, textDecorations), - new PixelBackground(PixelBackgroundMode.Transparent)) + new PixelBackground()) { } @@ -102,43 +102,35 @@ public bool Equals(Pixel other) public Pixel Blend(Pixel pixelAbove) { PixelForeground newForeground; - PixelBackground newBackground; - if (pixelAbove.IsCaret) return new Pixel(Foreground, Background, true); + var newBackground = new PixelBackground(MergeColors(Background.Color, pixelAbove.Background.Color)); - switch (pixelAbove.Background.Mode) + bool newIsCaret; + + if (pixelAbove.Background.Color.A == 0x0 /*todo: can be approximate, extract to extension method*/) + { + newForeground = pixelAbove.Foreground.Color == Colors.Transparent + ? Foreground + : Foreground.Blend(pixelAbove.Foreground); + newIsCaret = pixelAbove.IsCaret | IsCaret; + } + else { - case PixelBackgroundMode.Colored: - // merge pixelAbove into this pixel using alpha channel. - Color mergedColors = MergeColors(Background.Color, pixelAbove.Background.Color); + if (!pixelAbove.IsEmpty()) + { newForeground = pixelAbove.Foreground; - newBackground = new PixelBackground(mergedColors); - return new Pixel(newForeground, newBackground, pixelAbove.IsCaret); - - case PixelBackgroundMode.Transparent: - // if the foreground is transparent, ignore pixelAbove foreground. - newForeground = pixelAbove.Foreground.Color != Colors.Transparent - ? Foreground.Blend(pixelAbove.Foreground) - : Foreground; - - // background is transparent, ignore pixelAbove background. - newBackground = Background; - break; - case PixelBackgroundMode.Shaded: - // shade the current pixel - (newForeground, newBackground) = Shade(); - - // blend the pixelAbove foreground into the shaded pixel - newForeground = newForeground.Blend(pixelAbove.Foreground); - - // resulting in new pixel with shaded background and blended foreground - return new Pixel(newForeground, newBackground); - - default: throw new ArgumentOutOfRangeException(nameof(pixelAbove)); + } + else + { + newForeground = new PixelForeground(Foreground.Symbol, + MergeColors(Foreground.Color, pixelAbove.Background.Color), Foreground.Weight, + Foreground.Style, + Foreground.TextDecoration); + } + + newIsCaret = pixelAbove.IsCaret; } - bool newIsCaret = IsCaret | pixelAbove.IsCaret; - return new Pixel(newForeground, newBackground, newIsCaret); } @@ -147,10 +139,10 @@ public bool IsEmpty() return Foreground.Symbol.Width == 0; } - private (PixelForeground, PixelBackground) Shade() + /*private (PixelForeground, PixelBackground) Shade() { return (Foreground.Shade(), Background.Shade()); - } + }*/ /// /// merge colors with alpha blending diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackground.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackground.cs index b2f72afd..05a0b000 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackground.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackground.cs @@ -11,34 +11,24 @@ namespace Consolonia.Core.Drawing.PixelBufferImplementation { public PixelBackground() { - Mode = PixelBackgroundMode.Transparent; Color = Colors.Transparent; } public PixelBackground(Color color) { - Mode = color.A == 0 ? PixelBackgroundMode.Transparent : PixelBackgroundMode.Colored; Color = color; } - public PixelBackground(PixelBackgroundMode mode, Color? color = null) - { - Color = color ?? Colors.Transparent; - Mode = mode; - } [JsonConverter(typeof(ColorConverter))] public Color Color { get; init; } - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public PixelBackgroundMode Mode { get; init; } - public bool Equals(PixelBackground other) { - return Color.Equals(other.Color) && Mode == other.Mode; + return Color.Equals(other.Color); } - public PixelBackground Shade() + /*public PixelBackground Shade() { Color newColor = Color; PixelBackgroundMode newMode = Mode; @@ -59,7 +49,7 @@ public PixelBackground Shade() } return new PixelBackground(newMode, newColor); - } + }*/ public override bool Equals([NotNullWhen(true)] object obj) { @@ -68,7 +58,7 @@ public override bool Equals([NotNullWhen(true)] object obj) public override int GetHashCode() { - return HashCode.Combine(Color, Mode); + return HashCode.Combine(Color); } public static bool operator ==(PixelBackground left, PixelBackground right) diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs index 86173494..fd332381 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs @@ -1,6 +1,6 @@ namespace Consolonia.Core.Drawing.PixelBufferImplementation { - public enum PixelBackgroundMode : byte + public enum PixelBackgroundMode2 : byte { Colored, Transparent, diff --git a/src/Consolonia.NUnit/UnitTestConsole.cs b/src/Consolonia.NUnit/UnitTestConsole.cs index 58566d59..95922054 100644 --- a/src/Consolonia.NUnit/UnitTestConsole.cs +++ b/src/Consolonia.NUnit/UnitTestConsole.cs @@ -71,7 +71,7 @@ void IConsole.Print(PixelBufferCoordinate bufferPoint, Color background, Color f new Pixel( new PixelForeground(new SimpleSymbol(rune), foreground, style: style, weight: weight, textDecoration: textDecoration), - new PixelBackground(PixelBackgroundMode.Colored, background))); + new PixelBackground(background))); i++; } } diff --git a/src/Consolonia.Themes/Templates/Controls/Helpers/ConsoloniaTextPresenter.cs b/src/Consolonia.Themes/Templates/Controls/Helpers/ConsoloniaTextPresenter.cs index dc863d96..db21dfc8 100644 --- a/src/Consolonia.Themes/Templates/Controls/Helpers/ConsoloniaTextPresenter.cs +++ b/src/Consolonia.Themes/Templates/Controls/Helpers/ConsoloniaTextPresenter.cs @@ -58,10 +58,7 @@ static ConsoloniaTextPresenter() // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local //todo: what does this mean? args => { - ConsoleBrush brush = - ConsoleBrush.FromBrush(args.NewValue.Value, PixelBackgroundMode.Transparent); - - if (brush.Mode != PixelBackgroundMode.Transparent) + if (args.NewValue.Value.Opacity != 0 && ((ISolidColorBrush)args.NewValue.Value).Color.A != 0x0) throw new NotSupportedException( "CaretBrush must have a transparent background. This ensures proper rendering of the caret over text content."); })); @@ -79,8 +76,8 @@ public ConsoloniaTextPresenter() .MaxValue); //see DispatcherTimer.Interval, since we can not disable it, setting it to the longest interval possible caretTickTimer!.Tick += (_, _) => throw new NotImplementedException("How to disable timer completely?"); } - - CaretBrush = new ConsoleBrush(Colors.Black, PixelBackgroundMode.Transparent); // we want to draw own caret + + CaretBrush = Brushes.Transparent; // we want to draw own caret } public Point CaretPosition From 5de905a9a496eff156e8898f8c309a470d84bd8b Mon Sep 17 00:00:00 2001 From: Evgeny Gorbovoy Date: Wed, 25 Dec 2024 16:57:32 +0100 Subject: [PATCH 02/23] the rest --- src/.editorconfig | 2 +- src/Consolonia.Core/Drawing/ConsoleBrush.cs | 2 +- .../Drawing/DrawingContextImpl.cs | 15 +++--- .../GalleryViews/GalleryColors.axaml.cs | 6 +-- .../GalleryViews/GalleryDataGrid.axaml.cs | 6 +-- .../Fluent/FluentColors.axaml | 49 +++++++++---------- .../Material/MaterialColors.axaml | 47 +++++++++--------- .../Templates/Controls/CalendarItem.axaml | 4 +- .../Templates/Controls/DataGrid.axaml | 7 +-- .../Templates/Controls/DialogWindow.axaml | 4 +- .../Templates/Controls/Popup.axaml | 6 +-- .../Templates/TurboVisionDefaultColors.axaml | 48 +++++++++--------- .../TurboVisionBlackColors.axaml | 48 +++++++++--------- .../TurboVisionDarkColors.axaml | 47 +++++++++--------- src/Example/Views/DataGridTestWindow.axaml | 6 +-- .../PixelBackgroundTests.cs | 25 +++------- src/Tests/Consolonia.Core.Tests/PixelTests.cs | 8 +-- 17 files changed, 152 insertions(+), 178 deletions(-) diff --git a/src/.editorconfig b/src/.editorconfig index f8c01848..85fa8dcd 100644 --- a/src/.editorconfig +++ b/src/.editorconfig @@ -2677,7 +2677,7 @@ resharper_int_variable_overflow_in_unchecked_context_highlighting = warning resharper_invalid_value_type_highlighting = warning resharper_invalid_xml_doc_comment_highlighting = warning resharper_invert_condition_1_highlighting = hint -resharper_invert_if_highlighting = hint +resharper_invert_if_highlighting = none resharper_invocation_is_skipped_highlighting = hint resharper_invoke_as_extension_method_highlighting = suggestion resharper_is_expression_always_false_highlighting = warning diff --git a/src/Consolonia.Core/Drawing/ConsoleBrush.cs b/src/Consolonia.Core/Drawing/ConsoleBrush.cs index c13ddf50..6196ae2a 100644 --- a/src/Consolonia.Core/Drawing/ConsoleBrush.cs +++ b/src/Consolonia.Core/Drawing/ConsoleBrush.cs @@ -84,7 +84,7 @@ public static Color FromPosition(IBrush brush, int x, int y, int width, int heig } default: - return ((SolidColorBrush)brush).Color; + return ((ISolidColorBrush)brush).Color; } } diff --git a/src/Consolonia.Core/Drawing/DrawingContextImpl.cs b/src/Consolonia.Core/Drawing/DrawingContextImpl.cs index a75eaf9e..e14941ab 100644 --- a/src/Consolonia.Core/Drawing/DrawingContextImpl.cs +++ b/src/Consolonia.Core/Drawing/DrawingContextImpl.cs @@ -652,7 +652,7 @@ private Line TransformLineInternal(Line line) lineStyle = null; if (pen is not { - Brush: LineBrush or ImmutableSolidColorBrush, + Brush: LineBrush or ISolidColorBrush, // Thickness: 1, DashStyle: null or { Dashes.Count: 0 }, LineCap: PenLineCap.Flat, @@ -663,12 +663,15 @@ private Line TransformLineInternal(Line line) return null; } - if (pen.Brush is LineBrush lineBrush) + IBrush brush = pen.Brush; + + if (brush is LineBrush lineBrush) + { lineStyle = lineBrush.LineStyle; + brush = lineBrush.Brush; + } - - Color consoleBrush = ((ImmutableSolidColorBrush)pen.Brush).Color; - return consoleBrush; + return ((ISolidColorBrush)brush).Color; } /// @@ -720,7 +723,7 @@ private void DrawLineSymbolAndMoveHead(ref Point head, bool isVertical, ISymbol private void DrawStringInternal(IBrush foreground, string text, IGlyphTypeface typeface, Point origin = new()) { - if (foreground is not ImmutableSolidColorBrush immutableSolidColorBrush) + if (foreground is not ISolidColorBrush immutableSolidColorBrush) { ConsoloniaPlatform.RaiseNotSupported(4); return; diff --git a/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryColors.axaml.cs b/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryColors.axaml.cs index d94ed00a..9d206f8d 100644 --- a/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryColors.axaml.cs +++ b/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryColors.axaml.cs @@ -49,7 +49,7 @@ private void Blue_Click(object sender, RoutedEventArgs e) public class RgbModel : INotifyPropertyChanged { - private ConsoleBrush _brush; + private IBrush _brush; private Color _color; @@ -59,11 +59,11 @@ public Color Color set { _color = value; - Brush = new ConsoleBrush(_color); + Brush = new SolidColorBrush(_color); } } - public ConsoleBrush Brush + public IBrush Brush { get => _brush; set diff --git a/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryDataGrid.axaml.cs b/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryDataGrid.axaml.cs index 762f0076..8ee649cb 100644 --- a/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryDataGrid.axaml.cs +++ b/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryDataGrid.axaml.cs @@ -600,10 +600,10 @@ public object Convert(object value, Type targetType, object parameter, CultureIn if (value is int gdp) { if (gdp <= 5000) - return new ConsoleBrush(Colors.Yellow); + return new SolidColorBrush(Colors.Yellow); if (gdp <= 10000) - return new ConsoleBrush(Colors.DarkGoldenrod); - return new ConsoleBrush(Colors.Green); + return new SolidColorBrush(Colors.DarkGoldenrod); + return new SolidColorBrush(Colors.Green); } return value; diff --git a/src/Consolonia.Themes/Fluent/FluentColors.axaml b/src/Consolonia.Themes/Fluent/FluentColors.axaml index 98def9c1..bb60af1e 100644 --- a/src/Consolonia.Themes/Fluent/FluentColors.axaml +++ b/src/Consolonia.Themes/Fluent/FluentColors.axaml @@ -5,41 +5,40 @@ 1 - + - + - + - + - + - + - + - + - + - + - + - + \ No newline at end of file diff --git a/src/Consolonia.Themes/Material/MaterialColors.axaml b/src/Consolonia.Themes/Material/MaterialColors.axaml index e4ab8cd1..5dd6384b 100644 --- a/src/Consolonia.Themes/Material/MaterialColors.axaml +++ b/src/Consolonia.Themes/Material/MaterialColors.axaml @@ -5,41 +5,40 @@ 1 - - + - + - + - + - + - + - + - + - + - + - + \ No newline at end of file diff --git a/src/Consolonia.Themes/Templates/Controls/CalendarItem.axaml b/src/Consolonia.Themes/Templates/Controls/CalendarItem.axaml index c4b288d8..a723948c 100644 --- a/src/Consolonia.Themes/Templates/Controls/CalendarItem.axaml +++ b/src/Consolonia.Themes/Templates/Controls/CalendarItem.axaml @@ -22,7 +22,7 @@ diff --git a/src/Tests/Consolonia.Core.Tests/PixelBackgroundTests.cs b/src/Tests/Consolonia.Core.Tests/PixelBackgroundTests.cs index 89f37f70..7f43b8ca 100644 --- a/src/Tests/Consolonia.Core.Tests/PixelBackgroundTests.cs +++ b/src/Tests/Consolonia.Core.Tests/PixelBackgroundTests.cs @@ -13,7 +13,6 @@ public void Constructor() { var pixelBackground = new PixelBackground(); Assert.That(pixelBackground.Color, Is.EqualTo(Colors.Transparent)); - Assert.That(pixelBackground.Mode, Is.EqualTo(PixelBackgroundMode.Transparent)); } [Test] @@ -21,18 +20,6 @@ public void ConstructorWithColor() { var pixelBackground = new PixelBackground(Colors.Red); Assert.That(pixelBackground.Color, Is.EqualTo(Colors.Red)); - Assert.That(pixelBackground.Mode, Is.EqualTo(PixelBackgroundMode.Colored)); - } - - [Test] - [TestCase(PixelBackgroundMode.Transparent)] - [TestCase(PixelBackgroundMode.Colored)] - [TestCase(PixelBackgroundMode.Shaded)] - public void ConstructorWithMode(PixelBackgroundMode mode) - { - var pixelBackground = new PixelBackground(mode, Colors.Red); - Assert.That(pixelBackground.Color.Equals(Colors.Red)); - Assert.That(pixelBackground.Mode.Equals(mode)); } [Test] @@ -44,8 +31,8 @@ public void Equality() Assert.That(pixelBackground.Equals(pixelBackground2)); Assert.That(pixelBackground == pixelBackground2); - pixelBackground = new PixelBackground(PixelBackgroundMode.Transparent, Colors.Blue); - pixelBackground2 = new PixelBackground(PixelBackgroundMode.Transparent, Colors.Blue); + pixelBackground = new PixelBackground(Color.Parse("#000000FF")); + pixelBackground2 = new PixelBackground(Color.Parse("#000000FF")); Assert.That(pixelBackground.Equals((object)pixelBackground2)); Assert.That(pixelBackground.Equals(pixelBackground2)); Assert.That(pixelBackground == pixelBackground2); @@ -59,8 +46,8 @@ public void Inequality() Assert.That(!pixelBackground.Equals(pixelBackground2)); Assert.That(pixelBackground != pixelBackground2); - pixelBackground = new PixelBackground(PixelBackgroundMode.Colored, Colors.Red); - pixelBackground2 = new PixelBackground(PixelBackgroundMode.Transparent, Colors.Red); + pixelBackground = new PixelBackground(Colors.Red); + pixelBackground2 = new PixelBackground(Color.Parse("#7FFF0000")); Assert.That(!pixelBackground.Equals((object)pixelBackground2)); Assert.That(!pixelBackground.Equals(pixelBackground2)); Assert.That(pixelBackground != pixelBackground2); @@ -73,8 +60,8 @@ public void HashCode() var pixelBackground2 = new PixelBackground(Colors.Red); Assert.That(pixelBackground.GetHashCode(), Is.EqualTo(pixelBackground2.GetHashCode())); - pixelBackground = new PixelBackground(PixelBackgroundMode.Transparent, Colors.Blue); - pixelBackground2 = new PixelBackground(PixelBackgroundMode.Transparent, Colors.Blue); + pixelBackground = new PixelBackground(Color.Parse("#000000FF")); + pixelBackground2 = new PixelBackground(Color.Parse("#000000FF")); Assert.That(pixelBackground.GetHashCode(), Is.EqualTo(pixelBackground2.GetHashCode())); // inequal hashcode diff --git a/src/Tests/Consolonia.Core.Tests/PixelTests.cs b/src/Tests/Consolonia.Core.Tests/PixelTests.cs index eeae1b37..7a539057 100644 --- a/src/Tests/Consolonia.Core.Tests/PixelTests.cs +++ b/src/Tests/Consolonia.Core.Tests/PixelTests.cs @@ -23,7 +23,6 @@ public void ConstructorColorOnly() { var pixel = new Pixel(new PixelBackground(Colors.Red)); Assert.That(pixel.Background.Color, Is.EqualTo(Colors.Red)); - Assert.That(pixel.Background.Mode, Is.EqualTo(PixelBackgroundMode.Colored)); } [Test] @@ -36,7 +35,6 @@ public void ConstructorColorAndSymbol() Assert.That(pixel.Foreground.Weight, Is.EqualTo(FontWeight.Normal)); Assert.That(pixel.Foreground.TextDecoration, Is.Null); Assert.That(pixel.Background.Color, Is.EqualTo(Colors.Transparent)); - Assert.That(pixel.Background.Mode, Is.EqualTo(PixelBackgroundMode.Transparent)); } [Test] @@ -49,7 +47,6 @@ public void ConstructorDrawingBoxSymbol() Assert.That(pixel.Foreground.Weight, Is.EqualTo(FontWeight.Normal)); Assert.That(pixel.Foreground.TextDecoration, Is.Null); Assert.That(pixel.Background.Color, Is.EqualTo(Colors.Transparent)); - Assert.That(pixel.Background.Mode, Is.EqualTo(PixelBackgroundMode.Transparent)); } [Test] @@ -63,7 +60,6 @@ public void ConstructorDrawingBoxSymbolAndColor() Assert.IsNull(pixel.Foreground.Weight); Assert.IsNull(pixel.Foreground.TextDecoration); Assert.That(pixel.Background.Color, Is.EqualTo(Colors.Blue)); - Assert.That(pixel.Background.Mode, Is.EqualTo(PixelBackgroundMode.Colored)); } [Test] @@ -147,7 +143,7 @@ public void BlendShadedBackground() { var pixel = new Pixel(new PixelForeground(new SimpleSymbol("x"), Colors.Gray), new PixelBackground(Colors.White)); - var pixel2 = new Pixel(new PixelBackground(PixelBackgroundMode.Shaded)); + var pixel2 = new Pixel(new PixelBackground(Color.Parse("#7F0000FF"))); Pixel newPixel = pixel.Blend(pixel2); Assert.True(newPixel.Foreground.Symbol.Text == "x"); // foreground should be lighter than original @@ -165,7 +161,7 @@ public void BlendShadedBackground2() { var pixel = new Pixel(new PixelForeground(new SimpleSymbol("x"), Colors.Gray), new PixelBackground(Colors.Black)); - var pixel2 = new Pixel(new PixelBackground(PixelBackgroundMode.Shaded)); + var pixel2 = new Pixel(new PixelBackground(Color.Parse("#7F0000FF"))); Pixel newPixel = pixel.Blend(pixel2); Assert.True(newPixel.Foreground.Symbol.Text == "x"); // foreground should be darker than original From 8390c5013c977871c55def572f73bda3333cab66 Mon Sep 17 00:00:00 2001 From: Evgeny Gorbovoy Date: Wed, 25 Dec 2024 17:41:01 +0100 Subject: [PATCH 03/23] last bug left --- .../PixelBufferImplementation/Pixel.cs | 32 +++++++++++++++---- .../PixelBackground.cs | 2 +- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs index f798ccb5..2f146f09 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs @@ -116,7 +116,7 @@ public Pixel Blend(Pixel pixelAbove) } else { - if (!pixelAbove.IsEmpty()) + if (!string.IsNullOrWhiteSpace(pixelAbove.Foreground.Symbol.Text) && pixelAbove.Foreground.Color.A != 0x0) { newForeground = pixelAbove.Foreground; } @@ -144,6 +144,7 @@ public bool IsEmpty() return (Foreground.Shade(), Background.Shade()); }*/ + /// /// merge colors with alpha blending /// @@ -152,14 +153,31 @@ public bool IsEmpty() /// source blended into target private static Color MergeColors(Color target, Color source) { - float alphaB = source.A / 255.0f; - float inverseAlphaB = 1.0f - alphaB; + // Convert alpha from [0..255] to [0..1] + float fgAlpha = source.A / 255f; + float bgAlpha = target.A / 255f; + + // Compute output alpha + float outAlpha = fgAlpha + bgAlpha * (1 - fgAlpha); + + // If there's no alpha in the result, return transparent + if (outAlpha <= 0f) + { + return Color.FromArgb(0, 0, 0, 0); + } + + // Calculate the composited color channels, also converting channels to [0..1] + float outR = (source.R / 255f * fgAlpha + target.R / 255f * bgAlpha * (1 - fgAlpha)) / outAlpha; + float outG = (source.G / 255f * fgAlpha + target.G / 255f * bgAlpha * (1 - fgAlpha)) / outAlpha; + float outB = (source.B / 255f * fgAlpha + target.B / 255f * bgAlpha * (1 - fgAlpha)) / outAlpha; - byte red = (byte)(target.R * inverseAlphaB + source.R * alphaB); - byte green = (byte)(target.G * inverseAlphaB + source.G * alphaB); - byte blue = (byte)(target.B * inverseAlphaB + source.B * alphaB); + // Convert back to [0..255] + byte a = (byte)(outAlpha * 255f); + byte r = (byte)(outR * 255f); + byte g = (byte)(outG * 255f); + byte b = (byte)(outB * 255f); - return new Color(0xFF, red, green, blue); + return Color.FromArgb(a, r, g, b); } public override bool Equals([NotNullWhen(true)] object obj) diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackground.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackground.cs index 05a0b000..b2e278a4 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackground.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackground.cs @@ -6,7 +6,7 @@ namespace Consolonia.Core.Drawing.PixelBufferImplementation { - [DebuggerDisplay("[{Color}, {Mode}]")] + [DebuggerDisplay("[{Color}]")] public readonly struct PixelBackground : IEquatable { public PixelBackground() From 7887e43d7145188d704fa733aed504d29f4ea6d1 Mon Sep 17 00:00:00 2001 From: Evgeny Gorbovoy Date: Wed, 25 Dec 2024 18:08:18 +0100 Subject: [PATCH 04/23] better like this. But something happens to drawing box lines --- .../Drawing/PixelBufferImplementation/Pixel.cs | 2 +- .../Drawing/PixelBufferImplementation/PixelForeground.cs | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs index 2f146f09..3e63b102 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs @@ -116,7 +116,7 @@ public Pixel Blend(Pixel pixelAbove) } else { - if (!string.IsNullOrWhiteSpace(pixelAbove.Foreground.Symbol.Text) && pixelAbove.Foreground.Color.A != 0x0) + if (!pixelAbove.Foreground.NothingToDraw()) { newForeground = pixelAbove.Foreground; } diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelForeground.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelForeground.cs index 92b85a70..1b221d88 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelForeground.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelForeground.cs @@ -96,5 +96,14 @@ public override int GetHashCode() { return !left.Equals(right); } + + public bool NothingToDraw() + { + if (Color.A == 0x0) + return true; + if (Symbol is SimpleSymbol simpleSymbol) + return string.IsNullOrWhiteSpace(simpleSymbol.Text); + return Symbol.IsWhiteSpace(); + } } } \ No newline at end of file From 58e4f422cbcda2b11d0d64982edcb2fb76fe3deb Mon Sep 17 00:00:00 2001 From: Evgeny Gorbovoy Date: Wed, 25 Dec 2024 18:46:42 +0100 Subject: [PATCH 05/23] Seems everything works --- .../Drawing/PixelBufferImplementation/Pixel.cs | 11 +++++++++-- src/Tests/Consolonia.Core.Tests/PixelTests.cs | 14 +++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs index 3e63b102..6c98106e 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs @@ -109,7 +109,7 @@ public Pixel Blend(Pixel pixelAbove) if (pixelAbove.Background.Color.A == 0x0 /*todo: can be approximate, extract to extension method*/) { - newForeground = pixelAbove.Foreground.Color == Colors.Transparent + newForeground = pixelAbove.Foreground.NothingToDraw() ? Foreground : Foreground.Blend(pixelAbove.Foreground); newIsCaret = pixelAbove.IsCaret | IsCaret; @@ -123,9 +123,16 @@ public Pixel Blend(Pixel pixelAbove) else { newForeground = new PixelForeground(Foreground.Symbol, - MergeColors(Foreground.Color, pixelAbove.Background.Color), Foreground.Weight, + MergeColors(Foreground.Color, pixelAbove.Background.Color), + Foreground.Weight, Foreground.Style, Foreground.TextDecoration); + + if (pixelAbove.Background.Color.A == 0xFF) + { + // non-transparent layer above + newForeground = new PixelForeground(); + } } newIsCaret = pixelAbove.IsCaret; diff --git a/src/Tests/Consolonia.Core.Tests/PixelTests.cs b/src/Tests/Consolonia.Core.Tests/PixelTests.cs index 7a539057..7441329e 100644 --- a/src/Tests/Consolonia.Core.Tests/PixelTests.cs +++ b/src/Tests/Consolonia.Core.Tests/PixelTests.cs @@ -143,10 +143,10 @@ public void BlendShadedBackground() { var pixel = new Pixel(new PixelForeground(new SimpleSymbol("x"), Colors.Gray), new PixelBackground(Colors.White)); - var pixel2 = new Pixel(new PixelBackground(Color.Parse("#7F0000FF"))); + var pixel2 = new Pixel(new PixelBackground(Color.Parse("#7F000000"))); Pixel newPixel = pixel.Blend(pixel2); Assert.True(newPixel.Foreground.Symbol.Text == "x"); - // foreground should be lighter than original + // foreground should be darker than original Assert.True(newPixel.Foreground.Color.R < pixel.Foreground.Color.R && newPixel.Foreground.Color.G < pixel.Foreground.Color.G && newPixel.Foreground.Color.B < pixel.Foreground.Color.B); @@ -161,17 +161,17 @@ public void BlendShadedBackground2() { var pixel = new Pixel(new PixelForeground(new SimpleSymbol("x"), Colors.Gray), new PixelBackground(Colors.Black)); - var pixel2 = new Pixel(new PixelBackground(Color.Parse("#7F0000FF"))); + var pixel2 = new Pixel(new PixelBackground(Color.Parse("#7F000000"))); Pixel newPixel = pixel.Blend(pixel2); Assert.True(newPixel.Foreground.Symbol.Text == "x"); // foreground should be darker than original Assert.True(newPixel.Foreground.Color.R < pixel.Foreground.Color.R && newPixel.Foreground.Color.G < pixel.Foreground.Color.G && newPixel.Foreground.Color.B < pixel.Foreground.Color.B); - // background should be darker than original - Assert.True(newPixel.Background.Color.R > pixel.Background.Color.R && - newPixel.Background.Color.G > pixel.Background.Color.G && - newPixel.Background.Color.B > pixel.Background.Color.B); + // background should be not lighter than original + Assert.True(newPixel.Background.Color.R <= pixel.Background.Color.R && + newPixel.Background.Color.G <= pixel.Background.Color.G && + newPixel.Background.Color.B <= pixel.Background.Color.B); } [Test] From 6e693a45110f0a618e37071f792aa5316cfd7e84 Mon Sep 17 00:00:00 2001 From: Evgeny Gorbovoy Date: Wed, 25 Dec 2024 18:54:05 +0100 Subject: [PATCH 06/23] Now looks better --- .../Drawing/PixelBufferImplementation/PixelForeground.cs | 4 ++-- .../Drawing/PixelBufferImplementation/SimpleSymbol.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelForeground.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelForeground.cs index 1b221d88..d2e877ae 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelForeground.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelForeground.cs @@ -101,8 +101,8 @@ public bool NothingToDraw() { if (Color.A == 0x0) return true; - if (Symbol is SimpleSymbol simpleSymbol) - return string.IsNullOrWhiteSpace(simpleSymbol.Text); + /*if (Symbol is SimpleSymbol simpleSymbol) + return string.IsNullOrWhiteSpace(simpleSymbol.Text);*/ return Symbol.IsWhiteSpace(); } } diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/SimpleSymbol.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/SimpleSymbol.cs index fb6b103b..c97f29d3 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/SimpleSymbol.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/SimpleSymbol.cs @@ -47,7 +47,7 @@ public bool Equals(SimpleSymbol other) public bool IsWhiteSpace() { - return string.IsNullOrEmpty(Text); + return string.IsNullOrWhiteSpace(Text); } public ISymbol Blend(ref ISymbol symbolAbove) From 275069ed16aa62352f0c66585760c3b67e688dea Mon Sep 17 00:00:00 2001 From: Evgeny Gorbovoy Date: Wed, 25 Dec 2024 19:07:25 +0100 Subject: [PATCH 07/23] brought back space != whitespace --- .../PixelBufferImplementation/DrawingBoxSymbol.cs | 4 ++-- .../Drawing/PixelBufferImplementation/ISymbol.cs | 2 +- .../Drawing/PixelBufferImplementation/Pixel.cs | 11 ----------- .../PixelBufferImplementation/PixelForeground.cs | 6 +----- .../Drawing/PixelBufferImplementation/SimpleSymbol.cs | 6 +++--- src/Tests/Consolonia.Core.Tests/SimpleSymbolTests.cs | 6 +++--- 6 files changed, 10 insertions(+), 25 deletions(-) diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/DrawingBoxSymbol.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/DrawingBoxSymbol.cs index eaaf67e0..0a7b3461 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/DrawingBoxSymbol.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/DrawingBoxSymbol.cs @@ -33,14 +33,14 @@ public bool Equals(DrawingBoxSymbol other) [JsonIgnore] public ushort Width { get; } = 1; - public bool IsWhiteSpace() + public bool NothingToDraw() { return UpRightDownLeft == EmptySymbol; } public ISymbol Blend(ref ISymbol symbolAbove) { - if (symbolAbove.IsWhiteSpace()) return this; + if (symbolAbove.NothingToDraw()) return this; if (symbolAbove is not DrawingBoxSymbol drawingBoxSymbol) return symbolAbove; diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/ISymbol.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/ISymbol.cs index 7d58fc27..4065766c 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/ISymbol.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/ISymbol.cs @@ -15,7 +15,7 @@ public interface ISymbol /// ushort Width { get; } - bool IsWhiteSpace(); + bool NothingToDraw(); /// /// Blend 2 symbols together diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs index 6c98106e..440f14b3 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs @@ -141,17 +141,6 @@ public Pixel Blend(Pixel pixelAbove) return new Pixel(newForeground, newBackground, newIsCaret); } - public bool IsEmpty() - { - return Foreground.Symbol.Width == 0; - } - - /*private (PixelForeground, PixelBackground) Shade() - { - return (Foreground.Shade(), Background.Shade()); - }*/ - - /// /// merge colors with alpha blending /// diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelForeground.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelForeground.cs index d2e877ae..73f74f2b 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelForeground.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelForeground.cs @@ -99,11 +99,7 @@ public override int GetHashCode() public bool NothingToDraw() { - if (Color.A == 0x0) - return true; - /*if (Symbol is SimpleSymbol simpleSymbol) - return string.IsNullOrWhiteSpace(simpleSymbol.Text);*/ - return Symbol.IsWhiteSpace(); + return Color.A == 0x0 || Symbol.NothingToDraw(); } } } \ No newline at end of file diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/SimpleSymbol.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/SimpleSymbol.cs index c97f29d3..251edd20 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/SimpleSymbol.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/SimpleSymbol.cs @@ -45,14 +45,14 @@ public bool Equals(SimpleSymbol other) [JsonIgnore] public ushort Width { get; init; } - public bool IsWhiteSpace() + public bool NothingToDraw() { - return string.IsNullOrWhiteSpace(Text); + return string.IsNullOrEmpty(Text); } public ISymbol Blend(ref ISymbol symbolAbove) { - return symbolAbove.IsWhiteSpace() ? this : symbolAbove; + return symbolAbove.NothingToDraw() ? this : symbolAbove; } public override bool Equals([NotNullWhen(true)] object obj) diff --git a/src/Tests/Consolonia.Core.Tests/SimpleSymbolTests.cs b/src/Tests/Consolonia.Core.Tests/SimpleSymbolTests.cs index 639b2085..c068ca23 100644 --- a/src/Tests/Consolonia.Core.Tests/SimpleSymbolTests.cs +++ b/src/Tests/Consolonia.Core.Tests/SimpleSymbolTests.cs @@ -106,9 +106,9 @@ public void HashCode() [Test] public void IsWhiteSpace() { - Assert.That(new SimpleSymbol(string.Empty).IsWhiteSpace(), Is.True); - Assert.That(new SimpleSymbol(" ").IsWhiteSpace(), Is.False); - Assert.That(new SimpleSymbol("a").IsWhiteSpace(), Is.False); + Assert.That(new SimpleSymbol(string.Empty).NothingToDraw(), Is.True); + Assert.That(new SimpleSymbol(" ").NothingToDraw(), Is.False); + Assert.That(new SimpleSymbol("a").NothingToDraw(), Is.False); } [Test] From 5c54ff95ac3b7f291e0c828c5097359f405aabd7 Mon Sep 17 00:00:00 2001 From: Evgeny Gorbovoy Date: Wed, 25 Dec 2024 19:18:10 +0100 Subject: [PATCH 08/23] final adjustments --- src/Consolonia.Core/Drawing/ConsoleBrush.cs | 8 +++-- .../Drawing/DrawingContextImpl.cs | 9 +++-- .../DrawingBoxSymbol.cs | 2 +- .../PixelBufferImplementation/Pixel.cs | 1 + .../PixelBackground.cs | 35 ++----------------- .../PixelBackgroundMode.cs | 5 ++- 6 files changed, 19 insertions(+), 41 deletions(-) diff --git a/src/Consolonia.Core/Drawing/ConsoleBrush.cs b/src/Consolonia.Core/Drawing/ConsoleBrush.cs index 6196ae2a..78d5389f 100644 --- a/src/Consolonia.Core/Drawing/ConsoleBrush.cs +++ b/src/Consolonia.Core/Drawing/ConsoleBrush.cs @@ -7,7 +7,7 @@ namespace Consolonia.Core.Drawing { - public static class ConsoleBrush2 + public static class BrushExtensions { public static Color FromPosition(IBrush brush, int x, int y, int width, int height) {//todo: apply brush opacity @@ -83,8 +83,12 @@ public static Color FromPosition(IBrush brush, int x, int y, int width, int heig return color; } + case ISolidColorBrush solidColorBrush: + return solidColorBrush.Color; + default: - return ((ISolidColorBrush)brush).Color; + ConsoloniaPlatform.RaiseNotSupported(751, brush); //todo: allow RaiseNotSupported to return a result + return new Color(); } } diff --git a/src/Consolonia.Core/Drawing/DrawingContextImpl.cs b/src/Consolonia.Core/Drawing/DrawingContextImpl.cs index e14941ab..6d29e290 100644 --- a/src/Consolonia.Core/Drawing/DrawingContextImpl.cs +++ b/src/Consolonia.Core/Drawing/DrawingContextImpl.cs @@ -528,7 +528,7 @@ private void FillRectangleWithBrush(IBrush brush, IPen pen, Rect r) int px = (int)(r2.TopLeft.X + x); int py = (int)(r2.TopLeft.Y + y); - Color backgroundColor = ConsoleBrush2.FromPosition(brush, x, y, (int)width, (int)height); + Color backgroundColor = BrushExtensions.FromPosition(brush, x, y, (int)width, (int)height); CurrentClip.ExecuteWithClipping(new Point(px, py), () => { _pixelBuffer.Set(new PixelBufferCoordinate((ushort)px, (ushort)py), @@ -722,14 +722,13 @@ private void DrawLineSymbolAndMoveHead(ref Point head, bool isVertical, ISymbol private void DrawStringInternal(IBrush foreground, string text, IGlyphTypeface typeface, Point origin = new()) { - - if (foreground is not ISolidColorBrush immutableSolidColorBrush) + if (foreground is not ISolidColorBrush solidColorBrush) { ConsoloniaPlatform.RaiseNotSupported(4); return; } - // if (!Transform.IsTranslateOnly()) ConsoloniaPlatform.RaiseNotSupported(15); + // if (!Transform.IsTranslateOnly()) ConsoloniaPlatform.RaiseNotSupported(15); //todo: what to do if a rotation? Point whereToDraw = origin.Transform(Transform); int currentXPosition = 0; @@ -742,7 +741,7 @@ private void DrawLineSymbolAndMoveHead(ref Point head, bool isVertical, ISymbol { Point characterPoint = whereToDraw.Transform(Matrix.CreateTranslation(currentXPosition, currentYPosition)); - Color foregroundColor = immutableSolidColorBrush.Color; + Color foregroundColor = solidColorBrush.Color; switch (glyph) { diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/DrawingBoxSymbol.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/DrawingBoxSymbol.cs index 0a7b3461..056dd982 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/DrawingBoxSymbol.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/DrawingBoxSymbol.cs @@ -31,7 +31,7 @@ public bool Equals(DrawingBoxSymbol other) [JsonIgnore] public string Text { get; init; } - [JsonIgnore] public ushort Width { get; } = 1; + [JsonIgnore] public ushort Width => 1; public bool NothingToDraw() { diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs index 440f14b3..0890064d 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs @@ -149,6 +149,7 @@ public Pixel Blend(Pixel pixelAbove) /// source blended into target private static Color MergeColors(Color target, Color source) { + // by chatGPT o1 // Convert alpha from [0..255] to [0..1] float fgAlpha = source.A / 255f; float bgAlpha = target.A / 255f; diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackground.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackground.cs index b2e278a4..c55a39f5 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackground.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackground.cs @@ -7,50 +7,21 @@ namespace Consolonia.Core.Drawing.PixelBufferImplementation { [DebuggerDisplay("[{Color}]")] - public readonly struct PixelBackground : IEquatable + public readonly struct PixelBackground(Color color) : IEquatable { - public PixelBackground() + public PixelBackground() : this(Colors.Transparent) { - Color = Colors.Transparent; - } - - public PixelBackground(Color color) - { - Color = color; } [JsonConverter(typeof(ColorConverter))] - public Color Color { get; init; } + public Color Color { get; init; } = color; public bool Equals(PixelBackground other) { return Color.Equals(other.Color); } - /*public PixelBackground Shade() - { - Color newColor = Color; - PixelBackgroundMode newMode = Mode; - switch (Mode) - { - case PixelBackgroundMode.Colored: - newColor = Color.Shade(); - break; - case PixelBackgroundMode.Transparent: - newMode = PixelBackgroundMode.Shaded; - break; - case PixelBackgroundMode.Shaded: - newMode = PixelBackgroundMode.Colored; - newColor = Colors.Black; - break; - default: - throw new ArgumentOutOfRangeException(); - } - - return new PixelBackground(newMode, newColor); - }*/ - public override bool Equals([NotNullWhen(true)] object obj) { return obj is PixelBackground other && Equals(other); diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs index fd332381..c0d4f0a6 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs @@ -1,6 +1,9 @@ namespace Consolonia.Core.Drawing.PixelBufferImplementation { - public enum PixelBackgroundMode2 : byte + /// + /// todo: use it for EGA extension + /// + public enum PixelBackgroundMode : byte { Colored, Transparent, From 49a312aea2bdb47728a6f337f027f60f55df3894 Mon Sep 17 00:00:00 2001 From: Evgeny Gorbovoy Date: Wed, 25 Dec 2024 19:25:06 +0100 Subject: [PATCH 09/23] code rabbit --- src/Consolonia.Themes/Fluent/FluentColors.axaml | 1 - src/Consolonia.Themes/Material/MaterialColors.axaml | 5 ++--- src/Consolonia.Themes/Templates/Controls/CalendarItem.axaml | 3 +-- src/Consolonia.Themes/Templates/Controls/DataGrid.axaml | 1 - src/Consolonia.Themes/Templates/Controls/Popup.axaml | 5 ++--- .../Templates/TurboVisionDefaultColors.axaml | 3 +-- .../TurboVisionBlack/TurboVisionBlackColors.axaml | 1 - src/Example/Views/DataGridTestWindow.axaml | 1 - 8 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/Consolonia.Themes/Fluent/FluentColors.axaml b/src/Consolonia.Themes/Fluent/FluentColors.axaml index bb60af1e..67d0c2f6 100644 --- a/src/Consolonia.Themes/Fluent/FluentColors.axaml +++ b/src/Consolonia.Themes/Fluent/FluentColors.axaml @@ -1,6 +1,5 @@ 1 diff --git a/src/Consolonia.Themes/Material/MaterialColors.axaml b/src/Consolonia.Themes/Material/MaterialColors.axaml index 5dd6384b..52a41606 100644 --- a/src/Consolonia.Themes/Material/MaterialColors.axaml +++ b/src/Consolonia.Themes/Material/MaterialColors.axaml @@ -1,12 +1,11 @@ 1 + Color="#212121" /> @@ -33,7 +32,7 @@ Color="#FFC107" /> + Color="#7F757575" /> diff --git a/src/Consolonia.Themes/Templates/Controls/CalendarItem.axaml b/src/Consolonia.Themes/Templates/Controls/CalendarItem.axaml index a723948c..f28ad201 100644 --- a/src/Consolonia.Themes/Templates/Controls/CalendarItem.axaml +++ b/src/Consolonia.Themes/Templates/Controls/CalendarItem.axaml @@ -1,7 +1,6 @@ + xmlns:helpers="clr-namespace:Consolonia.Themes.Templates.Controls.Helpers;assembly=Consolonia.Themes"> diff --git a/src/Consolonia.Themes/Templates/Controls/Popup.axaml b/src/Consolonia.Themes/Templates/Controls/Popup.axaml index 746da811..364b0f16 100644 --- a/src/Consolonia.Themes/Templates/Controls/Popup.axaml +++ b/src/Consolonia.Themes/Templates/Controls/Popup.axaml @@ -1,6 +1,5 @@ + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> - + 1 1 diff --git a/src/Example/Views/DataGridTestWindow.axaml b/src/Example/Views/DataGridTestWindow.axaml index 69399c12..38338974 100644 --- a/src/Example/Views/DataGridTestWindow.axaml +++ b/src/Example/Views/DataGridTestWindow.axaml @@ -1,6 +1,5 @@ From 8a0447706ed95e47350ad7c0d7392be2f0e38269 Mon Sep 17 00:00:00 2001 From: Evgeny Gorbovoy Date: Wed, 25 Dec 2024 19:34:27 +0100 Subject: [PATCH 10/23] pr fix --- src/Consolonia.Core/Controls/Dialog/DialogWrap.axaml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Consolonia.Core/Controls/Dialog/DialogWrap.axaml b/src/Consolonia.Core/Controls/Dialog/DialogWrap.axaml index 489839d8..fa2d13c1 100644 --- a/src/Consolonia.Core/Controls/Dialog/DialogWrap.axaml +++ b/src/Consolonia.Core/Controls/Dialog/DialogWrap.axaml @@ -1,6 +1,5 @@ From 07b046934fdae54ded3ce3b1cd3891507f1624f5 Mon Sep 17 00:00:00 2001 From: Evgeny Gorbovoy Date: Wed, 25 Dec 2024 19:40:08 +0100 Subject: [PATCH 11/23] more linter --- src/Consolonia.Core/Drawing/ConsoleBrush.cs | 3 --- src/Consolonia.Core/Drawing/DrawingContextImpl.cs | 1 - .../Templates/Controls/Helpers/ConsoloniaTextPresenter.cs | 2 -- 3 files changed, 6 deletions(-) diff --git a/src/Consolonia.Core/Drawing/ConsoleBrush.cs b/src/Consolonia.Core/Drawing/ConsoleBrush.cs index 78d5389f..d0c1a112 100644 --- a/src/Consolonia.Core/Drawing/ConsoleBrush.cs +++ b/src/Consolonia.Core/Drawing/ConsoleBrush.cs @@ -1,8 +1,5 @@ using System; -using System.Diagnostics; -using Avalonia; using Avalonia.Media; -using Consolonia.Core.Drawing.PixelBufferImplementation; using Consolonia.Core.Infrastructure; namespace Consolonia.Core.Drawing diff --git a/src/Consolonia.Core/Drawing/DrawingContextImpl.cs b/src/Consolonia.Core/Drawing/DrawingContextImpl.cs index 6d29e290..8714cca4 100644 --- a/src/Consolonia.Core/Drawing/DrawingContextImpl.cs +++ b/src/Consolonia.Core/Drawing/DrawingContextImpl.cs @@ -4,7 +4,6 @@ using System.Text; using Avalonia; using Avalonia.Media; -using Avalonia.Media.Immutable; using Avalonia.Media.TextFormatting; using Avalonia.Platform; using Consolonia.Core.Drawing.PixelBufferImplementation; diff --git a/src/Consolonia.Themes/Templates/Controls/Helpers/ConsoloniaTextPresenter.cs b/src/Consolonia.Themes/Templates/Controls/Helpers/ConsoloniaTextPresenter.cs index db21dfc8..81f21b7d 100644 --- a/src/Consolonia.Themes/Templates/Controls/Helpers/ConsoloniaTextPresenter.cs +++ b/src/Consolonia.Themes/Templates/Controls/Helpers/ConsoloniaTextPresenter.cs @@ -6,8 +6,6 @@ using Avalonia.Media; using Avalonia.Reactive; using Avalonia.Threading; -using Consolonia.Core.Drawing; -using Consolonia.Core.Drawing.PixelBufferImplementation; using Consolonia.Core.Helpers; namespace Consolonia.Themes.Templates.Controls.Helpers From fab6f72519580df2e854bc3f7fff9b99c4eb6eae Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 25 Dec 2024 18:46:10 +0000 Subject: [PATCH 12/23] Automated JetBrains cleanup Co-authored-by: <+@users.noreply.github.com> --- src/Consolonia.Core/Drawing/ConsoleBrush.cs | 3 ++- src/Consolonia.Core/Drawing/DrawingContextImpl.cs | 2 +- .../Drawing/PixelBufferImplementation/Pixel.cs | 9 ++------- .../PixelBufferImplementation/PixelBackgroundMode.cs | 2 +- .../Gallery/GalleryViews/GalleryColors.axaml.cs | 1 - .../Gallery/GalleryViews/GalleryDataGrid.axaml.cs | 1 - .../Controls/Helpers/ConsoloniaTextPresenter.cs | 5 +++-- .../Templates/TurboVisionDefaultColors.axaml | 4 ++-- .../TurboVisionDark/TurboVisionDarkColors.axaml | 2 +- src/Example/Views/DataGridTestWindow.axaml | 3 ++- 10 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/Consolonia.Core/Drawing/ConsoleBrush.cs b/src/Consolonia.Core/Drawing/ConsoleBrush.cs index d0c1a112..4c8a2c14 100644 --- a/src/Consolonia.Core/Drawing/ConsoleBrush.cs +++ b/src/Consolonia.Core/Drawing/ConsoleBrush.cs @@ -7,7 +7,8 @@ namespace Consolonia.Core.Drawing public static class BrushExtensions { public static Color FromPosition(IBrush brush, int x, int y, int width, int height) - {//todo: apply brush opacity + { + //todo: apply brush opacity ArgumentNullException.ThrowIfNull(brush); if (x < 0 || x > width) throw new ArgumentOutOfRangeException(nameof(x), "x is out bounds"); diff --git a/src/Consolonia.Core/Drawing/DrawingContextImpl.cs b/src/Consolonia.Core/Drawing/DrawingContextImpl.cs index 8714cca4..f36346e0 100644 --- a/src/Consolonia.Core/Drawing/DrawingContextImpl.cs +++ b/src/Consolonia.Core/Drawing/DrawingContextImpl.cs @@ -663,7 +663,7 @@ private Line TransformLineInternal(Line line) } IBrush brush = pen.Brush; - + if (brush is LineBrush lineBrush) { lineStyle = lineBrush.LineStyle; diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs index 0890064d..dcb76264 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs @@ -123,16 +123,14 @@ public Pixel Blend(Pixel pixelAbove) else { newForeground = new PixelForeground(Foreground.Symbol, - MergeColors(Foreground.Color, pixelAbove.Background.Color), + MergeColors(Foreground.Color, pixelAbove.Background.Color), Foreground.Weight, Foreground.Style, Foreground.TextDecoration); if (pixelAbove.Background.Color.A == 0xFF) - { // non-transparent layer above newForeground = new PixelForeground(); - } } newIsCaret = pixelAbove.IsCaret; @@ -158,10 +156,7 @@ private static Color MergeColors(Color target, Color source) float outAlpha = fgAlpha + bgAlpha * (1 - fgAlpha); // If there's no alpha in the result, return transparent - if (outAlpha <= 0f) - { - return Color.FromArgb(0, 0, 0, 0); - } + if (outAlpha <= 0f) return Color.FromArgb(0, 0, 0, 0); // Calculate the composited color channels, also converting channels to [0..1] float outR = (source.R / 255f * fgAlpha + target.R / 255f * bgAlpha * (1 - fgAlpha)) / outAlpha; diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs index c0d4f0a6..89057053 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs @@ -1,7 +1,7 @@ namespace Consolonia.Core.Drawing.PixelBufferImplementation { /// - /// todo: use it for EGA extension + /// todo: use it for EGA extension /// public enum PixelBackgroundMode : byte { diff --git a/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryColors.axaml.cs b/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryColors.axaml.cs index 9d206f8d..f1b10391 100644 --- a/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryColors.axaml.cs +++ b/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryColors.axaml.cs @@ -4,7 +4,6 @@ using Avalonia.Controls; using Avalonia.Interactivity; using Avalonia.Media; -using Consolonia.Core.Drawing; namespace Consolonia.Gallery.Gallery.GalleryViews { diff --git a/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryDataGrid.axaml.cs b/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryDataGrid.axaml.cs index 8ee649cb..37ecd056 100644 --- a/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryDataGrid.axaml.cs +++ b/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryDataGrid.axaml.cs @@ -9,7 +9,6 @@ using Avalonia.Data; using Avalonia.Data.Converters; using Avalonia.Media; -using Consolonia.Core.Drawing; // ReSharper disable UnusedMember.Global diff --git a/src/Consolonia.Themes/Templates/Controls/Helpers/ConsoloniaTextPresenter.cs b/src/Consolonia.Themes/Templates/Controls/Helpers/ConsoloniaTextPresenter.cs index 81f21b7d..f267df41 100644 --- a/src/Consolonia.Themes/Templates/Controls/Helpers/ConsoloniaTextPresenter.cs +++ b/src/Consolonia.Themes/Templates/Controls/Helpers/ConsoloniaTextPresenter.cs @@ -56,7 +56,8 @@ static ConsoloniaTextPresenter() // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local //todo: what does this mean? args => { - if (args.NewValue.Value.Opacity != 0 && ((ISolidColorBrush)args.NewValue.Value).Color.A != 0x0) + if (args.NewValue.Value.Opacity != 0 && + ((ISolidColorBrush)args.NewValue.Value).Color.A != 0x0) throw new NotSupportedException( "CaretBrush must have a transparent background. This ensures proper rendering of the caret over text content."); })); @@ -74,7 +75,7 @@ public ConsoloniaTextPresenter() .MaxValue); //see DispatcherTimer.Interval, since we can not disable it, setting it to the longest interval possible caretTickTimer!.Tick += (_, _) => throw new NotImplementedException("How to disable timer completely?"); } - + CaretBrush = Brushes.Transparent; // we want to draw own caret } diff --git a/src/Consolonia.Themes/Templates/TurboVisionDefaultColors.axaml b/src/Consolonia.Themes/Templates/TurboVisionDefaultColors.axaml index da7786cc..10aeef41 100644 --- a/src/Consolonia.Themes/Templates/TurboVisionDefaultColors.axaml +++ b/src/Consolonia.Themes/Templates/TurboVisionDefaultColors.axaml @@ -4,7 +4,7 @@ 1 + Color="Black" /> + Color="Red" /> \ No newline at end of file diff --git a/src/Consolonia.Themes/TurboVisionDark/TurboVisionDarkColors.axaml b/src/Consolonia.Themes/TurboVisionDark/TurboVisionDarkColors.axaml index 9377dd7c..cbb7b307 100644 --- a/src/Consolonia.Themes/TurboVisionDark/TurboVisionDarkColors.axaml +++ b/src/Consolonia.Themes/TurboVisionDark/TurboVisionDarkColors.axaml @@ -4,7 +4,7 @@ 1 + Color="White" /> From 52c55b2a1eea8968cb7b2990b3f671c7c38f2f5c Mon Sep 17 00:00:00 2001 From: Evgeny Gorbovoy Date: Wed, 25 Dec 2024 19:59:18 +0100 Subject: [PATCH 13/23] more blending tests --- src/Tests/Consolonia.Core.Tests/PixelTests.cs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/Tests/Consolonia.Core.Tests/PixelTests.cs b/src/Tests/Consolonia.Core.Tests/PixelTests.cs index 7441329e..7d828778 100644 --- a/src/Tests/Consolonia.Core.Tests/PixelTests.cs +++ b/src/Tests/Consolonia.Core.Tests/PixelTests.cs @@ -174,6 +174,26 @@ public void BlendShadedBackground2() newPixel.Background.Color.B <= pixel.Background.Color.B); } + [Test] + public void TextBelowSemiTransparentBackgroundIsStillVisible() + { + var pixel = new Pixel(new PixelForeground(new SimpleSymbol("x"), Colors.Gray), + new PixelBackground(Colors.White)); + var pixel2 = new Pixel(new PixelBackground(Color.Parse("#7F000000"))); + Pixel newPixel = pixel2.Blend(pixel); + Assert.True(newPixel.Foreground.Symbol.Text == "x"); + } + + [Test] + public void TextBelowNoneTransparentNullCharacterIsStillVisible() + { + var pixel = new Pixel(new PixelForeground(new SimpleSymbol("x"), Colors.Gray), + new PixelBackground(Colors.White)); + var pixel2 = new Pixel(new PixelForeground(new SimpleSymbol(char.MinValue), Colors.White),new PixelBackground(Color.Parse("#7F000000"))); + Pixel newPixel = pixel2.Blend(pixel); + Assert.True(newPixel.Foreground.Symbol.Text == "x"); + } + [Test] public void HashCode() { From 0fc7c7430f1374168716c6e071164636d7efa871 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 25 Dec 2024 19:03:52 +0000 Subject: [PATCH 14/23] Automated JetBrains cleanup Co-authored-by: <+@users.noreply.github.com> --- src/Tests/Consolonia.Core.Tests/PixelTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Tests/Consolonia.Core.Tests/PixelTests.cs b/src/Tests/Consolonia.Core.Tests/PixelTests.cs index 7d828778..89d52dd7 100644 --- a/src/Tests/Consolonia.Core.Tests/PixelTests.cs +++ b/src/Tests/Consolonia.Core.Tests/PixelTests.cs @@ -189,7 +189,8 @@ public void TextBelowNoneTransparentNullCharacterIsStillVisible() { var pixel = new Pixel(new PixelForeground(new SimpleSymbol("x"), Colors.Gray), new PixelBackground(Colors.White)); - var pixel2 = new Pixel(new PixelForeground(new SimpleSymbol(char.MinValue), Colors.White),new PixelBackground(Color.Parse("#7F000000"))); + var pixel2 = new Pixel(new PixelForeground(new SimpleSymbol(char.MinValue), Colors.White), + new PixelBackground(Color.Parse("#7F000000"))); Pixel newPixel = pixel2.Blend(pixel); Assert.True(newPixel.Foreground.Symbol.Text == "x"); } From f8adc2841da3fc683d6b473d43350cadc9538c59 Mon Sep 17 00:00:00 2001 From: Evgeny Gorbovoy Date: Wed, 25 Dec 2024 22:43:43 +0100 Subject: [PATCH 15/23] pr comment fixes --- .../{ConsoleBrush.cs => BrushExtensions.cs} | 4 ++-- src/Consolonia.Core/Drawing/DrawingContextImpl.cs | 2 +- .../Drawing/PixelBufferImplementation/Pixel.cs | 14 ++++++++------ 3 files changed, 11 insertions(+), 9 deletions(-) rename src/Consolonia.Core/Drawing/{ConsoleBrush.cs => BrushExtensions.cs} (96%) diff --git a/src/Consolonia.Core/Drawing/ConsoleBrush.cs b/src/Consolonia.Core/Drawing/BrushExtensions.cs similarity index 96% rename from src/Consolonia.Core/Drawing/ConsoleBrush.cs rename to src/Consolonia.Core/Drawing/BrushExtensions.cs index 4c8a2c14..8c37d15c 100644 --- a/src/Consolonia.Core/Drawing/ConsoleBrush.cs +++ b/src/Consolonia.Core/Drawing/BrushExtensions.cs @@ -4,9 +4,9 @@ namespace Consolonia.Core.Drawing { - public static class BrushExtensions + public static class BrushExtensions //todo: investigate why resharper does not complain about wrong file naming { - public static Color FromPosition(IBrush brush, int x, int y, int width, int height) + public static Color FromPosition(this IBrush brush, int x, int y, int width, int height) { //todo: apply brush opacity ArgumentNullException.ThrowIfNull(brush); diff --git a/src/Consolonia.Core/Drawing/DrawingContextImpl.cs b/src/Consolonia.Core/Drawing/DrawingContextImpl.cs index f36346e0..0c82b258 100644 --- a/src/Consolonia.Core/Drawing/DrawingContextImpl.cs +++ b/src/Consolonia.Core/Drawing/DrawingContextImpl.cs @@ -527,7 +527,7 @@ private void FillRectangleWithBrush(IBrush brush, IPen pen, Rect r) int px = (int)(r2.TopLeft.X + x); int py = (int)(r2.TopLeft.Y + y); - Color backgroundColor = BrushExtensions.FromPosition(brush, x, y, (int)width, (int)height); + Color backgroundColor = brush.FromPosition(x, y, (int)width, (int)height); CurrentClip.ExecuteWithClipping(new Point(px, py), () => { _pixelBuffer.Set(new PixelBufferCoordinate((ushort)px, (ushort)py), diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs index dcb76264..cd50a7b0 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs @@ -122,15 +122,17 @@ public Pixel Blend(Pixel pixelAbove) } else { - newForeground = new PixelForeground(Foreground.Symbol, - MergeColors(Foreground.Color, pixelAbove.Background.Color), - Foreground.Weight, - Foreground.Style, - Foreground.TextDecoration); - + // merge the PixelForeground color with the pixelAbove background color + if (pixelAbove.Background.Color.A == 0xFF) // non-transparent layer above newForeground = new PixelForeground(); + else + newForeground = new PixelForeground(Foreground.Symbol, + MergeColors(Foreground.Color, pixelAbove.Background.Color), + Foreground.Weight, + Foreground.Style, + Foreground.TextDecoration); } newIsCaret = pixelAbove.IsCaret; From 1c32687a0bd4d1b507dc035acab72e0a6b683caa Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 25 Dec 2024 21:52:51 +0000 Subject: [PATCH 16/23] Automated JetBrains cleanup Co-authored-by: <+@users.noreply.github.com> --- .../Drawing/PixelBufferImplementation/Pixel.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs index cd50a7b0..79ea9cb3 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs @@ -123,16 +123,16 @@ public Pixel Blend(Pixel pixelAbove) else { // merge the PixelForeground color with the pixelAbove background color - + if (pixelAbove.Background.Color.A == 0xFF) // non-transparent layer above newForeground = new PixelForeground(); else - newForeground = new PixelForeground(Foreground.Symbol, - MergeColors(Foreground.Color, pixelAbove.Background.Color), - Foreground.Weight, - Foreground.Style, - Foreground.TextDecoration); + newForeground = new PixelForeground(Foreground.Symbol, + MergeColors(Foreground.Color, pixelAbove.Background.Color), + Foreground.Weight, + Foreground.Style, + Foreground.TextDecoration); } newIsCaret = pixelAbove.IsCaret; From 3bfff0683e0df964e8e4d9045865bb1491663015 Mon Sep 17 00:00:00 2001 From: Evgeny Gorbovoy Date: Thu, 26 Dec 2024 01:32:01 +0100 Subject: [PATCH 17/23] Ega color implemented --- src/Consolonia.Core/ApplicationStartup.cs | 9 +- .../EgaConsoleColor/EgaColorMode.cs | 9 ++ .../EgaConsoleColor/EgaConsoleColorMode.cs | 126 ++++++++++++++++++ .../IConsoleColorMode.cs | 11 ++ .../PixelBufferImplementation/Pixel.cs | 26 +--- .../PixelBackgroundMode.cs | 9 -- .../RgbConsoleColorMode.cs | 57 ++++++++ src/Consolonia.Core/Drawing/RenderTarget.cs | 2 +- .../InputLessDefaultNetConsole.cs | 17 +-- src/Consolonia.Gallery/App.cs | 4 +- src/Consolonia.Gallery/Program.cs | 4 +- .../View/ControlsListView.axaml | 5 +- .../PlatformSupportExtensions.cs | 33 ++++- 13 files changed, 260 insertions(+), 52 deletions(-) create mode 100644 src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaColorMode.cs create mode 100644 src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaConsoleColorMode.cs create mode 100644 src/Consolonia.Core/Drawing/PixelBufferImplementation/IConsoleColorMode.cs create mode 100644 src/Consolonia.Core/Drawing/PixelBufferImplementation/RgbConsoleColorMode.cs diff --git a/src/Consolonia.Core/ApplicationStartup.cs b/src/Consolonia.Core/ApplicationStartup.cs index 498dcb68..645f21b4 100644 --- a/src/Consolonia.Core/ApplicationStartup.cs +++ b/src/Consolonia.Core/ApplicationStartup.cs @@ -3,6 +3,8 @@ using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Platform; using Consolonia.Core.Drawing; +using Consolonia.Core.Drawing.PixelBufferImplementation; +using Consolonia.Core.Drawing.PixelBufferImplementation.EgaConsoleColor; using Consolonia.Core.Infrastructure; // ReSharper disable UnusedMember.Global //todo: how to disable it for public methods? @@ -27,7 +29,7 @@ public static class ApplicationStartup public static AppBuilder UseStandardConsole(this AppBuilder builder) { - return builder.UseConsole(new DefaultNetConsole()); + return builder.UseConsole(new DefaultNetConsole()).UseConsoleColorMode(new EgaConsoleColorMode()); } public static AppBuilder UseConsole(this AppBuilder builder, IConsole console) @@ -35,6 +37,11 @@ public static AppBuilder UseConsole(this AppBuilder builder, IConsole console) return builder.With(console); } + public static AppBuilder UseConsoleColorMode(this AppBuilder builder, IConsoleColorMode consoleColorMode) + { + return builder.With(consoleColorMode); + } + public static AppBuilder UseConsolonia(this AppBuilder builder) { return builder diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaColorMode.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaColorMode.cs new file mode 100644 index 00000000..7a25f4a6 --- /dev/null +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaColorMode.cs @@ -0,0 +1,9 @@ +namespace Consolonia.Core.Drawing.PixelBufferImplementation.EgaConsoleColor +{ + public enum EgaColorMode : byte + { + Colored, + Transparent, + Shaded + } +} \ No newline at end of file diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaConsoleColorMode.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaConsoleColorMode.cs new file mode 100644 index 00000000..954e6735 --- /dev/null +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaConsoleColorMode.cs @@ -0,0 +1,126 @@ +using System; +using System.Linq; +using Avalonia.Media; +using Consolonia.Core.Infrastructure; + +namespace Consolonia.Core.Drawing.PixelBufferImplementation.EgaConsoleColor +{ + public class EgaConsoleColorMode : IConsoleColorMode + { + private static readonly (ConsoleColor Color, (int R, int G, int B) Rgb)[] ConsoleColorMap = + [ + (ConsoleColor.Black, (0, 0, 0)), + (ConsoleColor.DarkBlue, (0, 0, 128)), + (ConsoleColor.DarkGreen, (0, 128, 0)), + (ConsoleColor.DarkCyan, (0, 128, 128)), + (ConsoleColor.DarkRed, (128, 0, 0)), + (ConsoleColor.DarkMagenta, (128, 0, 128)), + (ConsoleColor.DarkYellow, (128, 128, 0)), + (ConsoleColor.Gray, (192, 192, 192)), + (ConsoleColor.DarkGray, (128, 128, 128)), + (ConsoleColor.Blue, (0, 0, 255)), + (ConsoleColor.Green, (0, 255, 0)), + (ConsoleColor.Cyan, (0, 255, 255)), + (ConsoleColor.Red, (255, 0, 0)), + (ConsoleColor.Magenta, (255, 0, 255)), + (ConsoleColor.Yellow, (255, 255, 0)), + (ConsoleColor.White, (255, 255, 255)) + ]; + + public Color Blend(Color color1, Color color2) + { + (ConsoleColor consoleColor1, EgaColorMode mode1) = ConvertToConsoleColorMode(color1); + (ConsoleColor consoleColor2, EgaColorMode mode2) = ConvertToConsoleColorMode(color2); + + switch (mode2) + { + case EgaColorMode.Transparent: + return color1; + + case EgaColorMode.Shaded when mode1 == EgaColorMode.Shaded: + { + ConsoleColor doubleShadedColor = Shade(Shade(consoleColor1)); + return ConvertToAvaloniaColor(doubleShadedColor); + } + case EgaColorMode.Shaded: + { + ConsoleColor shadedColor = Shade(consoleColor1); + return ConvertToAvaloniaColor(shadedColor); + } + case EgaColorMode.Colored: + default: + return ConvertToAvaloniaColor(consoleColor2); + } + } + + public void SetAttributes(InputLessDefaultNetConsole console, Color background, Color foreground, + FontWeight? weight) + { + (ConsoleColor backgroundConsoleColor, EgaColorMode mode) = ConvertToConsoleColorMode(background); + /* todo: bring back and below + if (mode is not EgaColorMode.Colored) + ConsoloniaPlatform.RaiseNotSupported(62143, background);*/ + + (ConsoleColor foregroundConsoleColor, mode) = ConvertToConsoleColorMode(foreground); + /*if (mode is not EgaColorMode.Colored) + ConsoloniaPlatform.RaiseNotSupported(62144, foreground);*/ + + Console.ForegroundColor = foregroundConsoleColor; + Console.BackgroundColor = backgroundConsoleColor; + } + + private static (ConsoleColor, EgaColorMode) ConvertToConsoleColorMode(Color color) + { + ConsoleColor consoleColor = MapToConsoleColor(color); + + EgaColorMode mode = color.A switch + { + <= 63 => EgaColorMode.Transparent, + <= 191 => EgaColorMode.Shaded, + _ => EgaColorMode.Colored + }; + + return (consoleColor, mode); + } + + private static ConsoleColor MapToConsoleColor(Color color) + { + int r = color.R, g = color.G, b = color.B; + + // Find the nearest ConsoleColor by RGB distance + return ConsoleColorMap + .OrderBy(c => Math.Pow(c.Rgb.R - r, 2) + Math.Pow(c.Rgb.G - g, 2) + Math.Pow(c.Rgb.B - b, 2)) + .First().Color; + } + + private static ConsoleColor Shade(ConsoleColor color) + { + return color switch + { + ConsoleColor.White => ConsoleColor.Gray, + ConsoleColor.Gray => ConsoleColor.DarkGray, + ConsoleColor.Blue => ConsoleColor.DarkBlue, + ConsoleColor.Green => ConsoleColor.DarkGreen, + ConsoleColor.Cyan => ConsoleColor.DarkCyan, + ConsoleColor.Red => ConsoleColor.DarkRed, + ConsoleColor.Magenta => ConsoleColor.DarkMagenta, + ConsoleColor.Yellow => ConsoleColor.DarkYellow, + ConsoleColor.DarkBlue or + ConsoleColor.DarkGreen or + ConsoleColor.DarkCyan or + ConsoleColor.DarkRed or + ConsoleColor.DarkMagenta or + ConsoleColor.DarkYellow or + ConsoleColor.DarkGray or + ConsoleColor.Black => ConsoleColor.Black, + _ => ConsoleColor.Black + }; + } + + private static Color ConvertToAvaloniaColor(ConsoleColor consoleColor) + { + (ConsoleColor _, (int R, int G, int B) rgb) = ConsoleColorMap.First(c => c.Color == consoleColor); + return Color.FromRgb((byte)rgb.R, (byte)rgb.G, (byte)rgb.B); + } + } +} \ No newline at end of file diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/IConsoleColorMode.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/IConsoleColorMode.cs new file mode 100644 index 00000000..fcee61e9 --- /dev/null +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/IConsoleColorMode.cs @@ -0,0 +1,11 @@ +using Avalonia.Media; +using Consolonia.Core.Infrastructure; + +namespace Consolonia.Core.Drawing.PixelBufferImplementation +{ + public interface IConsoleColorMode + { + Color Blend(Color color1, Color color2); + void SetAttributes(InputLessDefaultNetConsole console, Color background, Color foreground, FontWeight? weight); + } +} \ No newline at end of file diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs index 79ea9cb3..5d9f1720 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs @@ -1,6 +1,7 @@ using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using Avalonia; using Avalonia.Media; using Newtonsoft.Json; @@ -149,29 +150,8 @@ public Pixel Blend(Pixel pixelAbove) /// source blended into target private static Color MergeColors(Color target, Color source) { - // by chatGPT o1 - // Convert alpha from [0..255] to [0..1] - float fgAlpha = source.A / 255f; - float bgAlpha = target.A / 255f; - - // Compute output alpha - float outAlpha = fgAlpha + bgAlpha * (1 - fgAlpha); - - // If there's no alpha in the result, return transparent - if (outAlpha <= 0f) return Color.FromArgb(0, 0, 0, 0); - - // Calculate the composited color channels, also converting channels to [0..1] - float outR = (source.R / 255f * fgAlpha + target.R / 255f * bgAlpha * (1 - fgAlpha)) / outAlpha; - float outG = (source.G / 255f * fgAlpha + target.G / 255f * bgAlpha * (1 - fgAlpha)) / outAlpha; - float outB = (source.B / 255f * fgAlpha + target.B / 255f * bgAlpha * (1 - fgAlpha)) / outAlpha; - - // Convert back to [0..255] - byte a = (byte)(outAlpha * 255f); - byte r = (byte)(outR * 255f); - byte g = (byte)(outG * 255f); - byte b = (byte)(outB * 255f); - - return Color.FromArgb(a, r, g, b); + var consoleColorMode = AvaloniaLocator.Current.GetRequiredService(); + return consoleColorMode.Blend(target, source); } public override bool Equals([NotNullWhen(true)] object obj) diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs index 89057053..5846b7ab 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs @@ -1,12 +1,3 @@ namespace Consolonia.Core.Drawing.PixelBufferImplementation { - /// - /// todo: use it for EGA extension - /// - public enum PixelBackgroundMode : byte - { - Colored, - Transparent, - Shaded - } } \ No newline at end of file diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/RgbConsoleColorMode.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/RgbConsoleColorMode.cs new file mode 100644 index 00000000..dbfe33bd --- /dev/null +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/RgbConsoleColorMode.cs @@ -0,0 +1,57 @@ +using System; +using System.Text; +using Avalonia.Media; +using Consolonia.Core.Infrastructure; +using Consolonia.Core.Text; + +namespace Consolonia.Core.Drawing.PixelBufferImplementation +{ + public class RgbConsoleColorMode : IConsoleColorMode + { + public Color Blend(Color color1, Color color2) + { + // by chatGPT o1 + // Convert alpha from [0..255] to [0..1] + float fgAlpha = color2.A / 255f; + float bgAlpha = color1.A / 255f; + + // Compute output alpha + float outAlpha = fgAlpha + bgAlpha * (1 - fgAlpha); + + // If there's no alpha in the result, return transparent + if (outAlpha <= 0f) return Color.FromArgb(0, 0, 0, 0); + + // Calculate the composited color channels, also converting channels to [0..1] + float outR = (color2.R / 255f * fgAlpha + color1.R / 255f * bgAlpha * (1 - fgAlpha)) / outAlpha; + float outG = (color2.G / 255f * fgAlpha + color1.G / 255f * bgAlpha * (1 - fgAlpha)) / outAlpha; + float outB = (color2.B / 255f * fgAlpha + color1.B / 255f * bgAlpha * (1 - fgAlpha)) / outAlpha; + + // Convert back to [0..255] + byte a = (byte)(outAlpha * 255f); + byte r = (byte)(outR * 255f); + byte g = (byte)(outG * 255f); + byte b = (byte)(outB * 255f); + + return Color.FromArgb(a, r, g, b); + } + + public void SetAttributes(InputLessDefaultNetConsole console, Color background, Color foreground, + FontWeight? weight) + { + var sb = new StringBuilder(); + sb.Append(Esc.Background(background)); + + sb.Append(Esc.Foreground(weight switch + { + FontWeight.Medium or FontWeight.SemiBold or FontWeight.Bold or FontWeight.ExtraBold or FontWeight.Black + or FontWeight.ExtraBlack + => foreground.Brighten(background), + FontWeight.Thin or FontWeight.ExtraLight or FontWeight.Light + => foreground.Shade(background), + _ => foreground + })); + + console.WriteText(sb.ToString()); + } + } +} \ No newline at end of file diff --git a/src/Consolonia.Core/Drawing/RenderTarget.cs b/src/Consolonia.Core/Drawing/RenderTarget.cs index 5bb18d05..bf9932f6 100644 --- a/src/Consolonia.Core/Drawing/RenderTarget.cs +++ b/src/Consolonia.Core/Drawing/RenderTarget.cs @@ -143,7 +143,7 @@ private void RenderToDevice() { _console.SetCaretPosition((PixelBufferCoordinate)caretPosition); _console.WriteText(pixelBuffer.CaretStyle switch - { + {//todo: may be better to move low level stuff to IConsole CaretStyle.BlinkingBar => Esc.BlinkingBarCursor, CaretStyle.SteadyBar => Esc.SteadyBarCursor, CaretStyle.BlinkingBlock => Esc.BlinkingBlockCursor, diff --git a/src/Consolonia.Core/Infrastructure/InputLessDefaultNetConsole.cs b/src/Consolonia.Core/Infrastructure/InputLessDefaultNetConsole.cs index d5c39dab..8b65c95a 100644 --- a/src/Consolonia.Core/Infrastructure/InputLessDefaultNetConsole.cs +++ b/src/Consolonia.Core/Infrastructure/InputLessDefaultNetConsole.cs @@ -69,6 +69,8 @@ public PixelBufferCoordinate GetCaretPosition() public void Print(PixelBufferCoordinate bufferPoint, Color background, Color foreground, FontStyle? style, FontWeight? weight, TextDecorationLocation? textDecoration, string str) { + var consoleColorMode = AvaloniaLocator.Current.GetRequiredService(); + PauseTask?.Wait(); SetCaretPosition(bufferPoint); @@ -82,18 +84,11 @@ public void Print(PixelBufferCoordinate bufferPoint, Color background, Color for if (style == FontStyle.Italic) sb.Append(Esc.Italic); - sb.Append(Esc.Background(background)); - - sb.Append(Esc.Foreground(weight switch - { - FontWeight.Medium or FontWeight.SemiBold or FontWeight.Bold or FontWeight.ExtraBold or FontWeight.Black - or FontWeight.ExtraBlack - => foreground.Brighten(background), - FontWeight.Thin or FontWeight.ExtraLight or FontWeight.Light - => foreground.Shade(background), - _ => foreground - })); + WriteText(sb.ToString()); + sb.Clear(); + consoleColorMode.SetAttributes(this, background, foreground, weight); + sb.Append(str); sb.Append(Esc.Reset); diff --git a/src/Consolonia.Gallery/App.cs b/src/Consolonia.Gallery/App.cs index 3f594b7a..75395690 100644 --- a/src/Consolonia.Gallery/App.cs +++ b/src/Consolonia.Gallery/App.cs @@ -15,10 +15,10 @@ static App() public App() { - /*Styles.Add(new TurboVisionTheme());*/ + Styles.Add(new TurboVisionTheme()); /*Styles.Add(new TurboVisionBlackTheme());*/ /*Styles.Add(new TurboVisionDarkTheme());*/ - Styles.Add(new FluentTheme()); + /*Styles.Add(new FluentTheme());*/ /*Styles.Add(new MaterialTheme());*/ } } diff --git a/src/Consolonia.Gallery/Program.cs b/src/Consolonia.Gallery/Program.cs index 69292c2f..e5e281de 100644 --- a/src/Consolonia.Gallery/Program.cs +++ b/src/Consolonia.Gallery/Program.cs @@ -1,5 +1,6 @@ using System; using Avalonia; +using Consolonia.Core.Drawing.PixelBufferImplementation.EgaConsoleColor; namespace Consolonia.Gallery { @@ -17,7 +18,8 @@ public static AppBuilder BuildAvaloniaApp() { return AppBuilder.Configure() .UseConsolonia() - .UseAutoDetectedConsole() + .UseStandardConsole() + /*.UseConsoleColorMode(new EgaConsoleColorMode())*/ .LogToException(); } } diff --git a/src/Consolonia.Gallery/View/ControlsListView.axaml b/src/Consolonia.Gallery/View/ControlsListView.axaml index 61cb2f52..d4536cb8 100644 --- a/src/Consolonia.Gallery/View/ControlsListView.axaml +++ b/src/Consolonia.Gallery/View/ControlsListView.axaml @@ -31,10 +31,9 @@ SelectionChanged="ComboBox_SelectionChanged" IsTabStop="false" HorizontalContentAlignment="Stretch"> - + + - diff --git a/src/Consolonia.PlatformSupport/PlatformSupportExtensions.cs b/src/Consolonia.PlatformSupport/PlatformSupportExtensions.cs index e9082653..0bb748e0 100644 --- a/src/Consolonia.PlatformSupport/PlatformSupportExtensions.cs +++ b/src/Consolonia.PlatformSupport/PlatformSupportExtensions.cs @@ -1,6 +1,8 @@ using System; using Avalonia; using Avalonia.Controls; +using Consolonia.Core.Drawing.PixelBufferImplementation; +using Consolonia.Core.Drawing.PixelBufferImplementation.EgaConsoleColor; using Consolonia.Core.Dummy; using Consolonia.Core.Infrastructure; using Consolonia.PlatformSupport; @@ -25,7 +27,36 @@ public static AppBuilder UseAutoDetectedConsole(this AppBuilder builder) _ => new DefaultNetConsole() }; - return builder.UseConsole(console); + return builder.UseConsole(console).UseAutoDetectConsoleColorMode(); + } + + public static AppBuilder UseAutoDetectConsoleColorMode(this AppBuilder builder) + { + IConsoleColorMode result; + if (Design.IsDesignMode) + result = new RgbConsoleColorMode(); + else + switch (Environment.OSVersion.Platform) + { + case PlatformID.Win32S or PlatformID.Win32Windows or PlatformID.Win32NT: + case PlatformID.MacOSX: + result = new RgbConsoleColorMode(); + break; + case PlatformID.Unix: + string term = Environment.GetEnvironmentVariable("TERM"); + result = term switch + { + "linux" or "xterm-direct" or "xterm-color" => new EgaConsoleColorMode(), + "xterm-256color" or "screen-256color" or "tmux-256color" => new RgbConsoleColorMode(), + _ => new EgaConsoleColorMode() + }; + break; + default: + result = new EgaConsoleColorMode(); + break; + } + + return builder.UseConsoleColorMode(result); } } } \ No newline at end of file From 66e72ea81d7225b17729e0678ea08d2ef87e78cb Mon Sep 17 00:00:00 2001 From: Evgeny Gorbovoy Date: Thu, 26 Dec 2024 04:22:28 +0100 Subject: [PATCH 18/23] al works fine --- src/Consolonia.Core/ApplicationStartup.cs | 1 + .../EgaConsoleColor/EgaColor.cs | 38 ++++++++++ .../EgaConsoleColor/EgaColorMode.cs | 3 +- .../EgaConsoleColor/EgaConsoleColorMode.cs | 75 ++++++++++++++++--- .../PixelBufferImplementation/PixelBuffer.cs | 3 +- src/Consolonia.Gallery/App.cs | 6 +- .../Gallery/GalleryViews/GalleryColors.axaml | 28 ++++++- .../GalleryViews/GalleryColors.axaml.cs | 22 ++++++ src/Consolonia.Gallery/Program.cs | 3 +- .../View/ControlsListView.axaml | 7 +- .../View/ControlsListView.axaml.cs | 4 +- .../Templates/TurboVisionDefaultColors.axaml | 29 +++---- 12 files changed, 180 insertions(+), 39 deletions(-) create mode 100644 src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaColor.cs diff --git a/src/Consolonia.Core/ApplicationStartup.cs b/src/Consolonia.Core/ApplicationStartup.cs index 645f21b4..09a2bce2 100644 --- a/src/Consolonia.Core/ApplicationStartup.cs +++ b/src/Consolonia.Core/ApplicationStartup.cs @@ -75,6 +75,7 @@ private static ClassicDesktopStyleApplicationLifetime CreateLifetime(AppBuilder ShutdownMode = ShutdownMode.OnMainWindowClose }; builder.SetupWithLifetime(lifetime); + return lifetime; } diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaColor.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaColor.cs new file mode 100644 index 00000000..5ce7113c --- /dev/null +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaColor.cs @@ -0,0 +1,38 @@ +using System; +using Avalonia.Markup.Xaml; +using Consolonia.Core.Drawing.PixelBufferImplementation.EgaConsoleColor; + +// ReSharper disable once CheckNamespace +namespace Consolonia +{ + //todo: define xaml namespace for out classes + /// + /// Avalonia axaml extension which consumes ConsoleColor and produce AvaloniaColor + /// + public class EgaColorExtension : MarkupExtension + { + public EgaColorExtension() + { + Color = ConsoleColor.Black; + } + + public EgaColorExtension(ConsoleColor color) + { + Color = color; + } + + public EgaColorExtension(EgaColorMode mode) + { + Color = ConsoleColor.Black; + Mode = mode; + } + + public ConsoleColor Color { get; set; } + public EgaColorMode Mode { get; set; } + + public override object ProvideValue(IServiceProvider serviceProvider) + { + return EgaConsoleColorMode.ConvertToAvaloniaColor(Color, Mode); + } + } +} \ No newline at end of file diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaColorMode.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaColorMode.cs index 7a25f4a6..70a3927e 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaColorMode.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaColorMode.cs @@ -1,4 +1,5 @@ -namespace Consolonia.Core.Drawing.PixelBufferImplementation.EgaConsoleColor +// ReSharper disable once CheckNamespace +namespace Consolonia { public enum EgaColorMode : byte { diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaConsoleColorMode.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaConsoleColorMode.cs index 954e6735..e2df2424 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaConsoleColorMode.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaConsoleColorMode.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Text; using Avalonia.Media; using Consolonia.Core.Infrastructure; @@ -57,19 +58,58 @@ public void SetAttributes(InputLessDefaultNetConsole console, Color background, FontWeight? weight) { (ConsoleColor backgroundConsoleColor, EgaColorMode mode) = ConvertToConsoleColorMode(background); - /* todo: bring back and below - if (mode is not EgaColorMode.Colored) - ConsoloniaPlatform.RaiseNotSupported(62143, background);*/ + if (mode is not EgaColorMode.Colored) + ConsoloniaPlatform.RaiseNotSupported(62144, foreground); + (ConsoleColor foregroundConsoleColor, mode) = ConvertToConsoleColorMode(foreground); - /*if (mode is not EgaColorMode.Colored) - ConsoloniaPlatform.RaiseNotSupported(62144, foreground);*/ + //todo: if mode is transparent, don't print foreground. if shaded - shade it - Console.ForegroundColor = foregroundConsoleColor; - Console.BackgroundColor = backgroundConsoleColor; - } + var sb = new StringBuilder(); + + // Append ANSI escape sequence for background color + sb.Append(GetAnsiCode(backgroundConsoleColor, true)); - private static (ConsoleColor, EgaColorMode) ConvertToConsoleColorMode(Color color) + // Append ANSI escape sequence for foreground color + sb.Append(GetAnsiCode(foregroundConsoleColor, false)); + console.WriteText(sb.ToString()); + return; + + // Function to map ConsoleColor to ANSI code + static string GetAnsiCode(ConsoleColor color, bool isBackground) + { + int ansiCode = color switch + { + ConsoleColor.Black => 0, + ConsoleColor.DarkRed => 1, + ConsoleColor.DarkGreen => 2, + ConsoleColor.DarkYellow => 3, + ConsoleColor.DarkBlue => 4, + ConsoleColor.DarkMagenta => 5, + ConsoleColor.DarkCyan => 6, + ConsoleColor.Gray => 7, + ConsoleColor.DarkGray => 8, + ConsoleColor.Red => 9, + ConsoleColor.Green => 10, + ConsoleColor.Yellow => 11, + ConsoleColor.Blue => 12, + ConsoleColor.Magenta => 13, + ConsoleColor.Cyan => 14, + ConsoleColor.White => 15, + _ => 7 // Default to white if unknown + }; + + return ansiCode < 8 + ? + // Standard colors + $"\x1b[{(isBackground ? 40 + ansiCode : 30 + ansiCode)}m" + : + // Bright colors + $"\x1b[{(isBackground ? 100 + (ansiCode - 8) : 90 + (ansiCode - 8))}m"; + } + } + + public static (ConsoleColor, EgaColorMode) ConvertToConsoleColorMode(Color color) { ConsoleColor consoleColor = MapToConsoleColor(color); @@ -117,10 +157,21 @@ ConsoleColor.DarkGray or }; } - private static Color ConvertToAvaloniaColor(ConsoleColor consoleColor) + public static Color ConvertToAvaloniaColor(ConsoleColor consoleColor, + EgaColorMode mode = EgaColorMode.Colored) { - (ConsoleColor _, (int R, int G, int B) rgb) = ConsoleColorMap.First(c => c.Color == consoleColor); - return Color.FromRgb((byte)rgb.R, (byte)rgb.G, (byte)rgb.B); + switch (mode) + { + case EgaColorMode.Transparent: + return Color.FromArgb(0, 0, 0, 0); + case EgaColorMode.Shaded: + return Color.FromArgb(127, 0, 0, 0); + case EgaColorMode.Colored: + (ConsoleColor _, (int R, int G, int B) rgb) = ConsoleColorMap.First(c => c.Color == consoleColor); + return Color.FromRgb((byte)rgb.R, (byte)rgb.G, (byte)rgb.B); + default: + throw new ArgumentOutOfRangeException(nameof(mode), mode, null); + } } } } \ No newline at end of file diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBuffer.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBuffer.cs index 618c7e38..6a06f64e 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBuffer.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBuffer.cs @@ -1,5 +1,6 @@ using System; using Avalonia; +using Avalonia.Media; using Newtonsoft.Json; // ReSharper disable UnusedMember.Global @@ -26,7 +27,7 @@ public PixelBuffer(ushort width, ushort height) // blended into it. for (ushort y = 0; y < height; y++) for (ushort x = 0; x < width; x++) - _buffer[x, y] = Pixel.Space; + _buffer[x, y] = new Pixel(new PixelBackground(Colors.Black)); } public ushort Width { get; } diff --git a/src/Consolonia.Gallery/App.cs b/src/Consolonia.Gallery/App.cs index 75395690..a9804fc1 100644 --- a/src/Consolonia.Gallery/App.cs +++ b/src/Consolonia.Gallery/App.cs @@ -15,10 +15,12 @@ static App() public App() { - Styles.Add(new TurboVisionTheme()); /*Styles.Add(new TurboVisionBlackTheme());*/ /*Styles.Add(new TurboVisionDarkTheme());*/ - /*Styles.Add(new FluentTheme());*/ + + Styles.Add(new FluentTheme()); + //todo: automatically switch to turbovision if only 16 colors are supported + /*Styles.Add(new TurboVisionTheme());*/ /*Styles.Add(new MaterialTheme());*/ } } diff --git a/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryColors.axaml b/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryColors.axaml index 00a4d93c..f6ad6e94 100644 --- a/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryColors.axaml +++ b/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryColors.axaml @@ -2,6 +2,7 @@ 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:galleryViews="clr-namespace:Consolonia.Gallery.Gallery.GalleryViews" mc:Ignorable="d" x:Class="Consolonia.Gallery.Gallery.GalleryViews.GalleryColors"> @@ -16,7 +17,7 @@ - + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryColors.axaml.cs b/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryColors.axaml.cs index f1b10391..182726f1 100644 --- a/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryColors.axaml.cs +++ b/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryColors.axaml.cs @@ -1,9 +1,11 @@ using System; using System.Collections.ObjectModel; using System.ComponentModel; +using System.Linq; using Avalonia.Controls; using Avalonia.Interactivity; using Avalonia.Media; +using Consolonia.Core.Drawing.PixelBufferImplementation.EgaConsoleColor; namespace Consolonia.Gallery.Gallery.GalleryViews { @@ -15,6 +17,8 @@ public GalleryColors() Random rnd = Random.Shared; DataContext = new RgbModel { Color = Color.FromRgb((byte)rnd.Next(255), (byte)rnd.Next(255), (byte)rnd.Next(255)) }; + + FourBitControl.ItemsSource = ConsoleColorItem.GetAll(); } private void Random_Click(object sender, RoutedEventArgs e) @@ -83,4 +87,22 @@ public class Swatch public Color Color { get; set; } } + + public class ConsoleColorItem + { + public Brush Brush { get; set; } + + public string Name { get; set; } + + public static ConsoleColorItem[] GetAll() + { + return Enum.GetValues() + .Select(c => new ConsoleColorItem + { + Brush = new SolidColorBrush(EgaConsoleColorMode.ConvertToAvaloniaColor(c)), + Name = c.ToString() + }) + .ToArray(); + } + } } \ No newline at end of file diff --git a/src/Consolonia.Gallery/Program.cs b/src/Consolonia.Gallery/Program.cs index e5e281de..dd69192b 100644 --- a/src/Consolonia.Gallery/Program.cs +++ b/src/Consolonia.Gallery/Program.cs @@ -18,8 +18,7 @@ public static AppBuilder BuildAvaloniaApp() { return AppBuilder.Configure() .UseConsolonia() - .UseStandardConsole() - /*.UseConsoleColorMode(new EgaConsoleColorMode())*/ + .UseAutoDetectedConsole() .LogToException(); } } diff --git a/src/Consolonia.Gallery/View/ControlsListView.axaml b/src/Consolonia.Gallery/View/ControlsListView.axaml index d4536cb8..fabdc2d4 100644 --- a/src/Consolonia.Gallery/View/ControlsListView.axaml +++ b/src/Consolonia.Gallery/View/ControlsListView.axaml @@ -30,10 +30,11 @@ x:Name="ThemeCombo" SelectionChanged="ComboBox_SelectionChanged" IsTabStop="false" + SelectedIndex="0" HorizontalContentAlignment="Stretch"> - - - + + + diff --git a/src/Consolonia.Gallery/View/ControlsListView.axaml.cs b/src/Consolonia.Gallery/View/ControlsListView.axaml.cs index 018cb425..b7021939 100644 --- a/src/Consolonia.Gallery/View/ControlsListView.axaml.cs +++ b/src/Consolonia.Gallery/View/ControlsListView.axaml.cs @@ -42,8 +42,6 @@ public ControlsListView() else _commandLineArgs = []; - Styles.Add(new MaterialTheme()); - TrySetupSelected(); } @@ -110,7 +108,7 @@ selectedItem.Content is not string themeName || !Enum.TryParse(themeName, out Themes selectedTheme)) return; - Styles[0] = selectedTheme switch + Application.Current.Styles[0] = selectedTheme switch { Themes.Material => new MaterialTheme(), Themes.Fluent => new FluentTheme(), diff --git a/src/Consolonia.Themes/Templates/TurboVisionDefaultColors.axaml b/src/Consolonia.Themes/Templates/TurboVisionDefaultColors.axaml index 10aeef41..2907d708 100644 --- a/src/Consolonia.Themes/Templates/TurboVisionDefaultColors.axaml +++ b/src/Consolonia.Themes/Templates/TurboVisionDefaultColors.axaml @@ -1,32 +1,33 @@ + xmlns:system="clr-namespace:System;assembly=System.Runtime" + xmlns:consolonia="clr-namespace:Consolonia;assembly=Consolonia.Core"> 1 + Color="{consolonia:EgaColor Black}" /> + Color="{consolonia:EgaColor Gray}" /> + Color="{consolonia:EgaColor Cyan}" /> + Color="{consolonia:EgaColor Green}" /> + Color="{consolonia:EgaColor DarkBlue}" /> + Color="{consolonia:EgaColor White}" /> + Color="{consolonia:EgaColor White}" /> + Color="{consolonia:EgaColor DarkGray}" /> + Color="{consolonia:EgaColor DarkGray}" /> + Color="{consolonia:EgaColor Mode=Shaded}" /> + Color="{consolonia:EgaColor Black}" /> + Color="{consolonia:EgaColor Red}" /> + Color="{consolonia:EgaColor Mode=Transparent}" /> \ No newline at end of file From beb2fbf3cfd0e17ad92c3905ff247b77a36f30bc Mon Sep 17 00:00:00 2001 From: Evgeny Gorbovoy Date: Thu, 26 Dec 2024 04:54:17 +0100 Subject: [PATCH 19/23] tests fixed --- src/Consolonia.Core/ApplicationStartup.cs | 9 +-- src/Consolonia.NUnit/ConsoloniaAppTestBase.cs | 2 +- .../{ => WithLifetimeFixture}/Assembly.cs | 2 +- .../{ => WithLifetimeFixture}/ColorTests.cs | 2 +- .../DrawingBoxSymbolTests.cs | 2 +- .../DrawingContextImplTests.cs | 66 +++---------------- .../{ => WithLifetimeFixture}/GlyphTests.cs | 2 +- .../LifetimeSetupFixture.cs | 66 +++++++++++++++++++ .../{ => WithLifetimeFixture}/MiscTests.cs | 2 +- .../PixelBackgroundTests.cs | 2 +- .../PixelBufferTests.cs | 2 +- .../PixelForegroundTests.cs | 2 +- .../{ => WithLifetimeFixture}/PixelTests.cs | 2 +- .../SimpleSymbolTests.cs | 2 +- 14 files changed, 90 insertions(+), 73 deletions(-) rename src/Tests/Consolonia.Core.Tests/{ => WithLifetimeFixture}/Assembly.cs (91%) rename src/Tests/Consolonia.Core.Tests/{ => WithLifetimeFixture}/ColorTests.cs (98%) rename src/Tests/Consolonia.Core.Tests/{ => WithLifetimeFixture}/DrawingBoxSymbolTests.cs (98%) rename src/Tests/Consolonia.Core.Tests/{ => WithLifetimeFixture}/DrawingContextImplTests.cs (92%) rename src/Tests/Consolonia.Core.Tests/{ => WithLifetimeFixture}/GlyphTests.cs (98%) create mode 100644 src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/LifetimeSetupFixture.cs rename src/Tests/Consolonia.Core.Tests/{ => WithLifetimeFixture}/MiscTests.cs (91%) rename src/Tests/Consolonia.Core.Tests/{ => WithLifetimeFixture}/PixelBackgroundTests.cs (98%) rename src/Tests/Consolonia.Core.Tests/{ => WithLifetimeFixture}/PixelBufferTests.cs (98%) rename src/Tests/Consolonia.Core.Tests/{ => WithLifetimeFixture}/PixelForegroundTests.cs (99%) rename src/Tests/Consolonia.Core.Tests/{ => WithLifetimeFixture}/PixelTests.cs (99%) rename src/Tests/Consolonia.Core.Tests/{ => WithLifetimeFixture}/SimpleSymbolTests.cs (99%) diff --git a/src/Consolonia.Core/ApplicationStartup.cs b/src/Consolonia.Core/ApplicationStartup.cs index 09a2bce2..6655e6f0 100644 --- a/src/Consolonia.Core/ApplicationStartup.cs +++ b/src/Consolonia.Core/ApplicationStartup.cs @@ -17,12 +17,12 @@ public static class ApplicationStartup { public static void StartConsolonia(params string[] args) where TApp : Application, new() { - StartConsolonia(new DefaultNetConsole(), args); + StartConsolonia(new DefaultNetConsole(), new EgaConsoleColorMode(), args); } - public static void StartConsolonia(IConsole console, params string[] args) where TApp : Application, new() + public static void StartConsolonia(IConsole console, IConsoleColorMode consoleColorMode, params string[] args) where TApp : Application, new() { - ClassicDesktopStyleApplicationLifetime lifetime = BuildLifetime(console, args); + ClassicDesktopStyleApplicationLifetime lifetime = BuildLifetime(console, consoleColorMode, args); lifetime.Start(args); } @@ -56,12 +56,13 @@ public static AppBuilder UseConsolonia(this AppBuilder builder) }, nameof(ConsoloniaRenderInterface)); } - public static ClassicDesktopStyleApplicationLifetime BuildLifetime(IConsole console, string[] args) + public static ClassicDesktopStyleApplicationLifetime BuildLifetime(IConsole console, IConsoleColorMode consoleColorMode, string[] args) where TApp : Application, new() { AppBuilder consoloniaAppBuilder = AppBuilder.Configure() .UseConsole(console) .UseConsolonia() + .UseConsoleColorMode(consoleColorMode) .LogToException(); return CreateLifetime(consoloniaAppBuilder, args); diff --git a/src/Consolonia.NUnit/ConsoloniaAppTestBase.cs b/src/Consolonia.NUnit/ConsoloniaAppTestBase.cs index 0a1285a7..c27767e3 100644 --- a/src/Consolonia.NUnit/ConsoloniaAppTestBase.cs +++ b/src/Consolonia.NUnit/ConsoloniaAppTestBase.cs @@ -45,7 +45,7 @@ public async Task GlobalSetup() { _disposeTaskCompletionSource = new TaskCompletionSource(); _scope = AvaloniaLocator.EnterScope(); - _lifetime = ApplicationStartup.BuildLifetime(UITest, Args); + _lifetime = ApplicationStartup.BuildLifetime(UITest, new RgbConsoleColorMode(), Args); UITest.SetupLifetime(_lifetime); setupTaskSource.SetResult(); _lifetime.Start(Args); diff --git a/src/Tests/Consolonia.Core.Tests/Assembly.cs b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/Assembly.cs similarity index 91% rename from src/Tests/Consolonia.Core.Tests/Assembly.cs rename to src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/Assembly.cs index 5d141236..7b081b4f 100644 --- a/src/Tests/Consolonia.Core.Tests/Assembly.cs +++ b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/Assembly.cs @@ -7,7 +7,7 @@ [assembly: CLSCompliant(false)] //todo: should we make it compliant? -namespace Consolonia.Core.Tests +namespace Consolonia.Core.Tests.WithLifetimeFixture { [SetUpFixture] public class AllTests diff --git a/src/Tests/Consolonia.Core.Tests/ColorTests.cs b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/ColorTests.cs similarity index 98% rename from src/Tests/Consolonia.Core.Tests/ColorTests.cs rename to src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/ColorTests.cs index b71be7e2..f3bbf65c 100644 --- a/src/Tests/Consolonia.Core.Tests/ColorTests.cs +++ b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/ColorTests.cs @@ -2,7 +2,7 @@ using Consolonia.Core.Drawing.PixelBufferImplementation; using NUnit.Framework; -namespace Consolonia.Core.Tests +namespace Consolonia.Core.Tests.WithLifetimeFixture { [TestFixture] public class ColorTests diff --git a/src/Tests/Consolonia.Core.Tests/DrawingBoxSymbolTests.cs b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/DrawingBoxSymbolTests.cs similarity index 98% rename from src/Tests/Consolonia.Core.Tests/DrawingBoxSymbolTests.cs rename to src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/DrawingBoxSymbolTests.cs index 4fdb50dc..cbb8cedf 100644 --- a/src/Tests/Consolonia.Core.Tests/DrawingBoxSymbolTests.cs +++ b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/DrawingBoxSymbolTests.cs @@ -4,7 +4,7 @@ using Newtonsoft.Json; using NUnit.Framework; -namespace Consolonia.Core.Tests +namespace Consolonia.Core.Tests.WithLifetimeFixture { [TestFixture] public class DrawingBoxSymbolTests diff --git a/src/Tests/Consolonia.Core.Tests/DrawingContextImplTests.cs b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/DrawingContextImplTests.cs similarity index 92% rename from src/Tests/Consolonia.Core.Tests/DrawingContextImplTests.cs rename to src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/DrawingContextImplTests.cs index 1d996e61..6627b063 100644 --- a/src/Tests/Consolonia.Core.Tests/DrawingContextImplTests.cs +++ b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/DrawingContextImplTests.cs @@ -1,42 +1,25 @@ using System; using System.Diagnostics; using Avalonia; -using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Media; using Avalonia.Media.TextFormatting; using Avalonia.Platform; using Consolonia.Core.Drawing; using Consolonia.Core.Drawing.PixelBufferImplementation; -using Consolonia.Core.Dummy; using Consolonia.Core.Infrastructure; using NUnit.Framework; #pragma warning disable CA1305 // Specify IFormatProvider -namespace Consolonia.Core.Tests +namespace Consolonia.Core.Tests.WithLifetimeFixture { - public class ContextApp : Application - { - } - [TestFixture] - public class DrawingContextImplTests : IDisposable + public class DrawingContextImplTests { - [OneTimeSetUp] - public void Setup() - { - _scope = AvaloniaLocator.EnterScope(); - _lifetime = ApplicationStartup.BuildLifetime(new DummyConsole(), Array.Empty()); - } - - private IDisposable _scope; - private ClassicDesktopStyleApplicationLifetime _lifetime; - private bool _disposedValue; - [Test] public void BufferInitialized() { - ArgumentNullException.ThrowIfNull(_lifetime); + ArgumentNullException.ThrowIfNull(Application.Current.ApplicationLifetime); var consoleWindow = new ConsoleWindow(); PixelBuffer buffer = consoleWindow.PixelBuffer; @@ -47,7 +30,7 @@ public void BufferInitialized() Assert.IsTrue(pixel.Width == 1); Assert.IsTrue(pixel.Foreground.Symbol.Text == " "); Assert.IsTrue(pixel.Foreground.Color == Colors.Transparent); - Assert.IsTrue(pixel.Background.Color == Colors.Transparent); + Assert.IsTrue(pixel.Background.Color == Colors.Black); } } @@ -345,13 +328,13 @@ public void DrawSolidRectangle() { Assert.IsTrue(buffer[x, y].Foreground.Symbol.Text == " "); Assert.IsTrue(buffer[x, y].Foreground.Color == Colors.Transparent); - Assert.IsTrue(buffer[x, y].Background.Color == Colors.Transparent); + Assert.IsTrue(buffer[x, y].Background.Color == Colors.Black); } else if (y == 0 || y == bottom) { Assert.IsTrue(buffer[x, y].Foreground.Symbol.Text == " "); Assert.IsTrue(buffer[x, y].Foreground.Color == Colors.Transparent); - Assert.IsTrue(buffer[x, y].Background.Color == Colors.Transparent); + Assert.IsTrue(buffer[x, y].Background.Color == Colors.Black); } else { @@ -388,7 +371,7 @@ public void DrawSingleBox() // outside of box Assert.IsTrue(buffer[x, y].Foreground.Symbol.Text == " "); Assert.IsTrue(buffer[x, y].Foreground.Color == Colors.Transparent); - Assert.IsTrue(buffer[x, y].Background.Color == Colors.Transparent); + Assert.IsTrue(buffer[x, y].Background.Color == Colors.Black); } else if (x == left && y == top) { @@ -484,7 +467,7 @@ public void DrawDoubleBox() // outside of box Assert.IsTrue(buffer[x, y].Foreground.Symbol.Text == " "); Assert.IsTrue(buffer[x, y].Foreground.Color == Colors.Transparent); - Assert.IsTrue(buffer[x, y].Background.Color == Colors.Transparent); + Assert.IsTrue(buffer[x, y].Background.Color == Colors.Black); } else if (x == left && y == top) { @@ -578,38 +561,5 @@ internal static PixelBufferCoordinate SetOrigin(DrawingContextImpl dc, ushort x, dc.Transform = new Matrix(1, 0, 0, 1, x, y); return new PixelBufferCoordinate(x, y); } - - protected virtual void Dispose(bool disposing) - { - if (!_disposedValue) - { - if (disposing) - { - // dispose managed state (managed objects) - _scope?.Dispose(); - _lifetime?.Dispose(); - _scope = null; - _lifetime = null; - } - - // TODO: free unmanaged resources (unmanaged objects) and override finalizer - // TODO: set large fields to null - _disposedValue = true; - } - } - - // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources - // ~DrawingContextImplTests() - // { - // // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method - // Dispose(disposing: false); - // } - - public void Dispose() - { - // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method - Dispose(true); - GC.SuppressFinalize(this); - } } } \ No newline at end of file diff --git a/src/Tests/Consolonia.Core.Tests/GlyphTests.cs b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/GlyphTests.cs similarity index 98% rename from src/Tests/Consolonia.Core.Tests/GlyphTests.cs rename to src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/GlyphTests.cs index 551bfb8e..c1e32de4 100644 --- a/src/Tests/Consolonia.Core.Tests/GlyphTests.cs +++ b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/GlyphTests.cs @@ -1,7 +1,7 @@ using Consolonia.Core.Helpers; using NUnit.Framework; -namespace Consolonia.Core.Tests +namespace Consolonia.Core.Tests.WithLifetimeFixture { [TestFixture] public class GlyphTests diff --git a/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/LifetimeSetupFixture.cs b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/LifetimeSetupFixture.cs new file mode 100644 index 00000000..df7517c4 --- /dev/null +++ b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/LifetimeSetupFixture.cs @@ -0,0 +1,66 @@ +using System; +using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; +using Consolonia.Core.Drawing.PixelBufferImplementation; +using Consolonia.Core.Dummy; +using NUnit.Framework; +using static System.GC; + +namespace Consolonia.Core.Tests.WithLifetimeFixture +{ + [SetUpFixture] + public class LifetimeSetupFixture : IDisposable + { + private class ContextApp2 : Application; + + [OneTimeSetUp] + public void Setup() + {//todo: setup copypasted from another test. Can be extracted to a base class? + _scope = AvaloniaLocator.EnterScope(); + _lifetime = ApplicationStartup.BuildLifetime(new DummyConsole(), new RgbConsoleColorMode(), []); + } + + [OneTimeTearDown] + public void TearDown() + { + Dispose(); + } + + private IDisposable _scope; + private ClassicDesktopStyleApplicationLifetime _lifetime; + private bool _disposedValue; + + protected virtual void Dispose(bool disposing) + { + if (!_disposedValue) + { + if (disposing) + { + // dispose managed state (managed objects) + _scope?.Dispose(); + _lifetime?.Dispose(); + _scope = null; + _lifetime = null; + } + + // TODO: free unmanaged resources (unmanaged objects) and override finalizer + // TODO: set large fields to null + _disposedValue = true; + } + } + + // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources + // ~DrawingContextImplTests() + // { + // // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + // Dispose(disposing: false); + // } + + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(true); + SuppressFinalize(this); + } + } +} \ No newline at end of file diff --git a/src/Tests/Consolonia.Core.Tests/MiscTests.cs b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/MiscTests.cs similarity index 91% rename from src/Tests/Consolonia.Core.Tests/MiscTests.cs rename to src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/MiscTests.cs index d502cd80..07526f05 100644 --- a/src/Tests/Consolonia.Core.Tests/MiscTests.cs +++ b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/MiscTests.cs @@ -2,7 +2,7 @@ using Consolonia.Core.Infrastructure; using NUnit.Framework; -namespace Consolonia.Core.Tests +namespace Consolonia.Core.Tests.WithLifetimeFixture { [TestFixture] public class MiscTests diff --git a/src/Tests/Consolonia.Core.Tests/PixelBackgroundTests.cs b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/PixelBackgroundTests.cs similarity index 98% rename from src/Tests/Consolonia.Core.Tests/PixelBackgroundTests.cs rename to src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/PixelBackgroundTests.cs index 7f43b8ca..c7bcb962 100644 --- a/src/Tests/Consolonia.Core.Tests/PixelBackgroundTests.cs +++ b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/PixelBackgroundTests.cs @@ -3,7 +3,7 @@ using Newtonsoft.Json; using NUnit.Framework; -namespace Consolonia.Core.Tests +namespace Consolonia.Core.Tests.WithLifetimeFixture { [TestFixture] public class PixelBackgroundTests diff --git a/src/Tests/Consolonia.Core.Tests/PixelBufferTests.cs b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/PixelBufferTests.cs similarity index 98% rename from src/Tests/Consolonia.Core.Tests/PixelBufferTests.cs rename to src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/PixelBufferTests.cs index d0379183..6eebde94 100644 --- a/src/Tests/Consolonia.Core.Tests/PixelBufferTests.cs +++ b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/PixelBufferTests.cs @@ -3,7 +3,7 @@ using Newtonsoft.Json; using NUnit.Framework; -namespace Consolonia.Core.Tests +namespace Consolonia.Core.Tests.WithLifetimeFixture { [TestFixture] public class PixelBufferTests diff --git a/src/Tests/Consolonia.Core.Tests/PixelForegroundTests.cs b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/PixelForegroundTests.cs similarity index 99% rename from src/Tests/Consolonia.Core.Tests/PixelForegroundTests.cs rename to src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/PixelForegroundTests.cs index 73ebefec..c63a4d21 100644 --- a/src/Tests/Consolonia.Core.Tests/PixelForegroundTests.cs +++ b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/PixelForegroundTests.cs @@ -5,7 +5,7 @@ using Newtonsoft.Json; using NUnit.Framework; -namespace Consolonia.Core.Tests +namespace Consolonia.Core.Tests.WithLifetimeFixture { [TestFixture] public class PixelForegroundTests diff --git a/src/Tests/Consolonia.Core.Tests/PixelTests.cs b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/PixelTests.cs similarity index 99% rename from src/Tests/Consolonia.Core.Tests/PixelTests.cs rename to src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/PixelTests.cs index 89d52dd7..21e3ce48 100644 --- a/src/Tests/Consolonia.Core.Tests/PixelTests.cs +++ b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/PixelTests.cs @@ -4,7 +4,7 @@ using Newtonsoft.Json; using NUnit.Framework; -namespace Consolonia.Core.Tests +namespace Consolonia.Core.Tests.WithLifetimeFixture { [TestFixture] public class PixelTests diff --git a/src/Tests/Consolonia.Core.Tests/SimpleSymbolTests.cs b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/SimpleSymbolTests.cs similarity index 99% rename from src/Tests/Consolonia.Core.Tests/SimpleSymbolTests.cs rename to src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/SimpleSymbolTests.cs index c068ca23..922d7a79 100644 --- a/src/Tests/Consolonia.Core.Tests/SimpleSymbolTests.cs +++ b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/SimpleSymbolTests.cs @@ -5,7 +5,7 @@ using Newtonsoft.Json; using NUnit.Framework; -namespace Consolonia.Core.Tests +namespace Consolonia.Core.Tests.WithLifetimeFixture { [TestFixture] public class SimpleSymbolTests From bf44216a7f04b725ebae2bc9490bbd2db5c77d10 Mon Sep 17 00:00:00 2001 From: Evgeny Gorbovoy Date: Thu, 26 Dec 2024 05:01:00 +0100 Subject: [PATCH 20/23] merge --- .../PixelBufferImplementation/EgaConsoleColor/EgaColor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaColor.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaColor.cs index 5ce7113c..8b20b4b9 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaColor.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaColor.cs @@ -7,7 +7,7 @@ namespace Consolonia { //todo: define xaml namespace for out classes /// - /// Avalonia axaml extension which consumes ConsoleColor and produce AvaloniaColor + /// Avalonia axaml extension which consumes ConsoleColor and produces AvaloniaColor /// public class EgaColorExtension : MarkupExtension { From 5fb6096de4e4a69a39c0568c9570959a45460451 Mon Sep 17 00:00:00 2001 From: Evgeny Gorbovoy Date: Thu, 26 Dec 2024 05:10:47 +0100 Subject: [PATCH 21/23] More fixes --- .../PixelBackgroundMode.cs | 3 --- .../InputLessDefaultNetConsole.cs | 1 + src/Consolonia.Gallery/App.cs | 6 +++--- src/Consolonia.Gallery/Program.cs | 1 - .../View/ControlsListView.axaml | 4 ++-- .../WithLifetimeFixture/Assembly.cs | 21 +------------------ .../LifetimeSetupFixture.cs | 7 ++++++- 7 files changed, 13 insertions(+), 30 deletions(-) delete mode 100644 src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs deleted file mode 100644 index 5846b7ab..00000000 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace Consolonia.Core.Drawing.PixelBufferImplementation -{ -} \ No newline at end of file diff --git a/src/Consolonia.Core/Infrastructure/InputLessDefaultNetConsole.cs b/src/Consolonia.Core/Infrastructure/InputLessDefaultNetConsole.cs index 8b65c95a..ac102a43 100644 --- a/src/Consolonia.Core/Infrastructure/InputLessDefaultNetConsole.cs +++ b/src/Consolonia.Core/Infrastructure/InputLessDefaultNetConsole.cs @@ -69,6 +69,7 @@ public PixelBufferCoordinate GetCaretPosition() public void Print(PixelBufferCoordinate bufferPoint, Color background, Color foreground, FontStyle? style, FontWeight? weight, TextDecorationLocation? textDecoration, string str) { + //todo: performance of retrieval of the service, at least can be retrieved once var consoleColorMode = AvaloniaLocator.Current.GetRequiredService(); PauseTask?.Wait(); diff --git a/src/Consolonia.Gallery/App.cs b/src/Consolonia.Gallery/App.cs index a9804fc1..8824840b 100644 --- a/src/Consolonia.Gallery/App.cs +++ b/src/Consolonia.Gallery/App.cs @@ -17,11 +17,11 @@ public App() { /*Styles.Add(new TurboVisionBlackTheme());*/ /*Styles.Add(new TurboVisionDarkTheme());*/ - - Styles.Add(new FluentTheme()); + /*Styles.Add(new FluentTheme());*/ + Styles.Add(new MaterialTheme()); //todo: automatically switch to turbovision if only 16 colors are supported /*Styles.Add(new TurboVisionTheme());*/ - /*Styles.Add(new MaterialTheme());*/ + } } } \ No newline at end of file diff --git a/src/Consolonia.Gallery/Program.cs b/src/Consolonia.Gallery/Program.cs index dd69192b..69292c2f 100644 --- a/src/Consolonia.Gallery/Program.cs +++ b/src/Consolonia.Gallery/Program.cs @@ -1,6 +1,5 @@ using System; using Avalonia; -using Consolonia.Core.Drawing.PixelBufferImplementation.EgaConsoleColor; namespace Consolonia.Gallery { diff --git a/src/Consolonia.Gallery/View/ControlsListView.axaml b/src/Consolonia.Gallery/View/ControlsListView.axaml index fabdc2d4..edd5c113 100644 --- a/src/Consolonia.Gallery/View/ControlsListView.axaml +++ b/src/Consolonia.Gallery/View/ControlsListView.axaml @@ -32,9 +32,9 @@ IsTabStop="false" SelectedIndex="0" HorizontalContentAlignment="Stretch"> - + + - diff --git a/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/Assembly.cs b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/Assembly.cs index 7b081b4f..e39f450e 100644 --- a/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/Assembly.cs +++ b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/Assembly.cs @@ -1,22 +1,3 @@ using System; -using Avalonia; -using Consolonia.Core.Drawing.PixelBufferImplementation; -using Consolonia.Core.Infrastructure; -using Consolonia.NUnit; -using NUnit.Framework; -[assembly: CLSCompliant(false)] //todo: should we make it compliant? - -namespace Consolonia.Core.Tests.WithLifetimeFixture -{ - [SetUpFixture] - public class AllTests - { - [OneTimeSetUp] - public void OneTimeSetUp() - { - AvaloniaLocator.Current = new AvaloniaLocator() - .Bind().ToConstant(new UnitTestConsole(new PixelBufferSize(100, 100))); - } - } -} \ No newline at end of file +[assembly: CLSCompliant(false)] //todo: should we make it compliant? \ No newline at end of file diff --git a/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/LifetimeSetupFixture.cs b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/LifetimeSetupFixture.cs index df7517c4..bc556154 100644 --- a/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/LifetimeSetupFixture.cs +++ b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/LifetimeSetupFixture.cs @@ -3,6 +3,8 @@ using Avalonia.Controls.ApplicationLifetimes; using Consolonia.Core.Drawing.PixelBufferImplementation; using Consolonia.Core.Dummy; +using Consolonia.Core.Infrastructure; +using Consolonia.NUnit; using NUnit.Framework; using static System.GC; @@ -15,7 +17,10 @@ private class ContextApp2 : Application; [OneTimeSetUp] public void Setup() - {//todo: setup copypasted from another test. Can be extracted to a base class? + { + AvaloniaLocator.Current = new AvaloniaLocator() + .Bind().ToConstant(new UnitTestConsole(new PixelBufferSize(100, 100))); + _scope = AvaloniaLocator.EnterScope(); _lifetime = ApplicationStartup.BuildLifetime(new DummyConsole(), new RgbConsoleColorMode(), []); } From 25384c6ba2e7658c7732f14b2c9ee99eacb02823 Mon Sep 17 00:00:00 2001 From: Evgeny Gorbovoy Date: Thu, 26 Dec 2024 05:17:22 +0100 Subject: [PATCH 22/23] resharper PR fix --- .../EgaConsoleColor/EgaConsoleColorMode.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaConsoleColorMode.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaConsoleColorMode.cs index e2df2424..77098bd9 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaConsoleColorMode.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaConsoleColorMode.cs @@ -62,7 +62,7 @@ public void SetAttributes(InputLessDefaultNetConsole console, Color background, ConsoloniaPlatform.RaiseNotSupported(62144, foreground); - (ConsoleColor foregroundConsoleColor, mode) = ConvertToConsoleColorMode(foreground); + (ConsoleColor foregroundConsoleColor, _) = ConvertToConsoleColorMode(foreground); //todo: if mode is transparent, don't print foreground. if shaded - shade it var sb = new StringBuilder(); From febcb3bfb282697e461cca16fac6cc7f48ce5f23 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 26 Dec 2024 04:24:14 +0000 Subject: [PATCH 23/23] Automated JetBrains cleanup Co-authored-by: <+@users.noreply.github.com> --- src/Consolonia.Core/ApplicationStartup.cs | 8 ++-- .../EgaConsoleColor/EgaColorMode.cs | 1 + .../EgaConsoleColor/EgaConsoleColorMode.cs | 4 +- .../RgbConsoleColorMode.cs | 1 - src/Consolonia.Core/Drawing/RenderTarget.cs | 3 +- .../InputLessDefaultNetConsole.cs | 2 +- src/Consolonia.Gallery/App.cs | 1 - .../Gallery/GalleryViews/GalleryColors.axaml | 8 ++-- .../View/ControlsListView.axaml | 3 +- .../PlatformSupportExtensions.cs | 2 +- .../LifetimeSetupFixture.cs | 46 ++++++++++--------- 11 files changed, 42 insertions(+), 37 deletions(-) diff --git a/src/Consolonia.Core/ApplicationStartup.cs b/src/Consolonia.Core/ApplicationStartup.cs index 6655e6f0..5050f2de 100644 --- a/src/Consolonia.Core/ApplicationStartup.cs +++ b/src/Consolonia.Core/ApplicationStartup.cs @@ -20,7 +20,8 @@ public static class ApplicationStartup StartConsolonia(new DefaultNetConsole(), new EgaConsoleColorMode(), args); } - public static void StartConsolonia(IConsole console, IConsoleColorMode consoleColorMode, params string[] args) where TApp : Application, new() + public static void StartConsolonia(IConsole console, IConsoleColorMode consoleColorMode, + params string[] args) where TApp : Application, new() { ClassicDesktopStyleApplicationLifetime lifetime = BuildLifetime(console, consoleColorMode, args); @@ -56,7 +57,8 @@ public static AppBuilder UseConsolonia(this AppBuilder builder) }, nameof(ConsoloniaRenderInterface)); } - public static ClassicDesktopStyleApplicationLifetime BuildLifetime(IConsole console, IConsoleColorMode consoleColorMode, string[] args) + public static ClassicDesktopStyleApplicationLifetime BuildLifetime(IConsole console, + IConsoleColorMode consoleColorMode, string[] args) where TApp : Application, new() { AppBuilder consoloniaAppBuilder = AppBuilder.Configure() @@ -76,7 +78,7 @@ private static ClassicDesktopStyleApplicationLifetime CreateLifetime(AppBuilder ShutdownMode = ShutdownMode.OnMainWindowClose }; builder.SetupWithLifetime(lifetime); - + return lifetime; } diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaColorMode.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaColorMode.cs index 70a3927e..477d660b 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaColorMode.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaColorMode.cs @@ -1,4 +1,5 @@ // ReSharper disable once CheckNamespace + namespace Consolonia { public enum EgaColorMode : byte diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaConsoleColorMode.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaConsoleColorMode.cs index 77098bd9..61971b21 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaConsoleColorMode.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/EgaConsoleColor/EgaConsoleColorMode.cs @@ -60,7 +60,7 @@ public void SetAttributes(InputLessDefaultNetConsole console, Color background, (ConsoleColor backgroundConsoleColor, EgaColorMode mode) = ConvertToConsoleColorMode(background); if (mode is not EgaColorMode.Colored) ConsoloniaPlatform.RaiseNotSupported(62144, foreground); - + (ConsoleColor foregroundConsoleColor, _) = ConvertToConsoleColorMode(foreground); //todo: if mode is transparent, don't print foreground. if shaded - shade it @@ -108,7 +108,7 @@ static string GetAnsiCode(ConsoleColor color, bool isBackground) $"\x1b[{(isBackground ? 100 + (ansiCode - 8) : 90 + (ansiCode - 8))}m"; } } - + public static (ConsoleColor, EgaColorMode) ConvertToConsoleColorMode(Color color) { ConsoleColor consoleColor = MapToConsoleColor(color); diff --git a/src/Consolonia.Core/Drawing/PixelBufferImplementation/RgbConsoleColorMode.cs b/src/Consolonia.Core/Drawing/PixelBufferImplementation/RgbConsoleColorMode.cs index dbfe33bd..3af791a2 100644 --- a/src/Consolonia.Core/Drawing/PixelBufferImplementation/RgbConsoleColorMode.cs +++ b/src/Consolonia.Core/Drawing/PixelBufferImplementation/RgbConsoleColorMode.cs @@ -1,4 +1,3 @@ -using System; using System.Text; using Avalonia.Media; using Consolonia.Core.Infrastructure; diff --git a/src/Consolonia.Core/Drawing/RenderTarget.cs b/src/Consolonia.Core/Drawing/RenderTarget.cs index bf9932f6..78a11818 100644 --- a/src/Consolonia.Core/Drawing/RenderTarget.cs +++ b/src/Consolonia.Core/Drawing/RenderTarget.cs @@ -143,7 +143,8 @@ private void RenderToDevice() { _console.SetCaretPosition((PixelBufferCoordinate)caretPosition); _console.WriteText(pixelBuffer.CaretStyle switch - {//todo: may be better to move low level stuff to IConsole + { + //todo: may be better to move low level stuff to IConsole CaretStyle.BlinkingBar => Esc.BlinkingBarCursor, CaretStyle.SteadyBar => Esc.SteadyBarCursor, CaretStyle.BlinkingBlock => Esc.BlinkingBlockCursor, diff --git a/src/Consolonia.Core/Infrastructure/InputLessDefaultNetConsole.cs b/src/Consolonia.Core/Infrastructure/InputLessDefaultNetConsole.cs index ac102a43..32959687 100644 --- a/src/Consolonia.Core/Infrastructure/InputLessDefaultNetConsole.cs +++ b/src/Consolonia.Core/Infrastructure/InputLessDefaultNetConsole.cs @@ -89,7 +89,7 @@ public void Print(PixelBufferCoordinate bufferPoint, Color background, Color for sb.Clear(); consoleColorMode.SetAttributes(this, background, foreground, weight); - + sb.Append(str); sb.Append(Esc.Reset); diff --git a/src/Consolonia.Gallery/App.cs b/src/Consolonia.Gallery/App.cs index 8824840b..713f99bc 100644 --- a/src/Consolonia.Gallery/App.cs +++ b/src/Consolonia.Gallery/App.cs @@ -21,7 +21,6 @@ public App() Styles.Add(new MaterialTheme()); //todo: automatically switch to turbovision if only 16 colors are supported /*Styles.Add(new TurboVisionTheme());*/ - } } } \ No newline at end of file diff --git a/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryColors.axaml b/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryColors.axaml index f6ad6e94..069b4be1 100644 --- a/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryColors.axaml +++ b/src/Consolonia.Gallery/Gallery/GalleryViews/GalleryColors.axaml @@ -468,26 +468,26 @@ Foreground="YellowGreen" Text="YellowGreen" /> - + + Orientation="Vertical" /> - + diff --git a/src/Consolonia.Gallery/View/ControlsListView.axaml b/src/Consolonia.Gallery/View/ControlsListView.axaml index edd5c113..4e9571ac 100644 --- a/src/Consolonia.Gallery/View/ControlsListView.axaml +++ b/src/Consolonia.Gallery/View/ControlsListView.axaml @@ -32,7 +32,8 @@ IsTabStop="false" SelectedIndex="0" HorizontalContentAlignment="Stretch"> - + diff --git a/src/Consolonia.PlatformSupport/PlatformSupportExtensions.cs b/src/Consolonia.PlatformSupport/PlatformSupportExtensions.cs index 0bb748e0..c78c51ab 100644 --- a/src/Consolonia.PlatformSupport/PlatformSupportExtensions.cs +++ b/src/Consolonia.PlatformSupport/PlatformSupportExtensions.cs @@ -55,7 +55,7 @@ public static AppBuilder UseAutoDetectConsoleColorMode(this AppBuilder builder) result = new EgaConsoleColorMode(); break; } - + return builder.UseConsoleColorMode(result); } } diff --git a/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/LifetimeSetupFixture.cs b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/LifetimeSetupFixture.cs index bc556154..3fb888c2 100644 --- a/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/LifetimeSetupFixture.cs +++ b/src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/LifetimeSetupFixture.cs @@ -13,16 +13,34 @@ namespace Consolonia.Core.Tests.WithLifetimeFixture [SetUpFixture] public class LifetimeSetupFixture : IDisposable { - private class ContextApp2 : Application; - + private bool _disposedValue; + private ClassicDesktopStyleApplicationLifetime _lifetime; + + private IDisposable _scope; + + // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources + // ~DrawingContextImplTests() + // { + // // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + // Dispose(disposing: false); + // } + + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(true); + SuppressFinalize(this); + } + [OneTimeSetUp] public void Setup() { AvaloniaLocator.Current = new AvaloniaLocator() .Bind().ToConstant(new UnitTestConsole(new PixelBufferSize(100, 100))); - + _scope = AvaloniaLocator.EnterScope(); - _lifetime = ApplicationStartup.BuildLifetime(new DummyConsole(), new RgbConsoleColorMode(), []); + _lifetime = ApplicationStartup.BuildLifetime(new DummyConsole(), new RgbConsoleColorMode(), + []); } [OneTimeTearDown] @@ -30,11 +48,7 @@ public void TearDown() { Dispose(); } - - private IDisposable _scope; - private ClassicDesktopStyleApplicationLifetime _lifetime; - private bool _disposedValue; - + protected virtual void Dispose(bool disposing) { if (!_disposedValue) @@ -54,18 +68,6 @@ protected virtual void Dispose(bool disposing) } } - // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources - // ~DrawingContextImplTests() - // { - // // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method - // Dispose(disposing: false); - // } - - public void Dispose() - { - // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method - Dispose(true); - SuppressFinalize(this); - } + private class ContextApp2 : Application; } } \ No newline at end of file