Console Styling

This commit is contained in:
2023-08-21 12:27:02 +02:00
parent 793f653db0
commit fff07e5da7
26 changed files with 572 additions and 160 deletions

View File

@@ -15,6 +15,8 @@ var services = new ServiceCollection()
.AddSingleton<IRenderEngine, MockRenderEngine>();
IServiceProvider provider = services.BuildServiceProvider();
var colorProvider = new ConsoleColorProvider();
var applicationContext = provider.GetRequiredService<IApplicationContext>();
applicationContext.Theme = new Theme
{
@@ -22,7 +24,7 @@ applicationContext.Theme = new Theme
{
ProgressBar = new ProgressBarTheme
{
ForegroundColor = ConsoleColors.Foregrounds.Blue
ForegroundColor = colorProvider.BlueForeground
}
}
};

View File

@@ -0,0 +1,86 @@
namespace TerminalUI.Color;
public class AnsiColorProvider : ColorProviderBase
{
public override IColor Parse(string color, ColorType type)
{
var finalColor = ParseInternal(color, type);
finalColor ??= ParseHexColor(color, type);
if (finalColor is not null) return finalColor;
throw new NotSupportedException($"Color can not be parsed. {color}");
}
private static IColor? ParseHexColor(string color, ColorType colorType)
{
if (!color.StartsWith("#")) return null;
if (color.Length == 4)
{
var r = ColorCharToColorByte(color[1]);
var g = ColorCharToColorByte(color[2]);
var b = ColorCharToColorByte(color[3]);
r += (byte) (r << 4);
g += (byte) (g << 4);
b += (byte) (b << 4);
return new ColorRgb(r, g, b, colorType);
}
if (color.Length == 7)
{
var r = (byte) (ColorCharToColorByte(color[1]) << 4 | ColorCharToColorByte(color[2]));
var g = (byte) (ColorCharToColorByte(color[3]) << 4 | ColorCharToColorByte(color[4]));
var b = (byte) (ColorCharToColorByte(color[5]) << 4 | ColorCharToColorByte(color[6]));
return new ColorRgb(r, g, b, colorType);
}
throw new NotSupportedException($"Hex color can not be parsed. {color}");
}
private static byte ColorCharToColorByte(char color) =>
color switch
{
>= '0' and <= '9' => (byte) (color - '0'),
>= 'A' and <= 'F' => (byte) (color - 'A' + 10),
>= 'a' and <= 'f' => (byte) (color - 'a' + 10),
_ => throw new NotSupportedException($"Hex color can not be parsed. {color}")
};
public override IColor BlackForeground { get; } = new Color256(0, ColorType.Foreground);
public override IColor BlueForeground { get; } = new Color256(12, ColorType.Foreground);
public override IColor CyanForeground { get; } = new Color256(14, ColorType.Foreground);
public override IColor DarkBlueForeground { get; } = new Color256(4, ColorType.Foreground);
public override IColor DarkCyanForeground { get; } = new Color256(6, ColorType.Foreground);
public override IColor DarkGrayForeground { get; } = new Color256(8, ColorType.Foreground);
public override IColor DarkGreenForeground { get; } = new Color256(2, ColorType.Foreground);
public override IColor DarkMagentaForeground { get; } = new Color256(5, ColorType.Foreground);
public override IColor DarkRedForeground { get; } = new Color256(1, ColorType.Foreground);
public override IColor DarkYellowForeground { get; } = new Color256(3, ColorType.Foreground);
public override IColor GrayForeground { get; } = new Color256(7, ColorType.Foreground);
public override IColor GreenForeground { get; } = new Color256(10, ColorType.Foreground);
public override IColor MagentaForeground { get; } = new Color256(13, ColorType.Foreground);
public override IColor RedForeground { get; } = new Color256(9, ColorType.Foreground);
public override IColor WhiteForeground { get; } = new Color256(15, ColorType.Foreground);
public override IColor YellowForeground { get; } = new Color256(11, ColorType.Foreground);
public override IColor BlackBackground { get; } = new Color256(0, ColorType.Background);
public override IColor BlueBackground { get; } = new Color256(12, ColorType.Background);
public override IColor CyanBackground { get; } = new Color256(14, ColorType.Background);
public override IColor DarkBlueBackground { get; } = new Color256(4, ColorType.Background);
public override IColor DarkCyanBackground { get; } = new Color256(6, ColorType.Background);
public override IColor DarkGrayBackground { get; } = new Color256(8, ColorType.Background);
public override IColor DarkGreenBackground { get; } = new Color256(2, ColorType.Background);
public override IColor DarkMagentaBackground { get; } = new Color256(5, ColorType.Background);
public override IColor DarkRedBackground { get; } = new Color256(1, ColorType.Background);
public override IColor DarkYellowBackground { get; } = new Color256(3, ColorType.Background);
public override IColor GrayBackground { get; } = new Color256(7, ColorType.Background);
public override IColor GreenBackground { get; } = new Color256(10, ColorType.Background);
public override IColor MagentaBackground { get; } = new Color256(13, ColorType.Background);
public override IColor RedBackground { get; } = new Color256(9, ColorType.Background);
public override IColor WhiteBackground { get; } = new Color256(15, ColorType.Background);
public override IColor YellowBackground { get; } = new Color256(11, ColorType.Background);
}

View File

@@ -0,0 +1,80 @@
namespace TerminalUI.Color;
public abstract class ColorProviderBase : IColorProvider
{
public abstract IColor Parse(string color, ColorType type);
protected IColor? ParseInternal(string color, ColorType type)
=> (color.ToLower(), type) switch
{
("black", ColorType.Foreground) => BlackForeground,
("blue", ColorType.Foreground) => BlueForeground,
("cyan", ColorType.Foreground) => CyanForeground,
("darkblue", ColorType.Foreground) => DarkBlueForeground,
("darkcyan", ColorType.Foreground) => DarkCyanForeground,
("darkgray", ColorType.Foreground) => DarkGrayForeground,
("darkgreen", ColorType.Foreground) => DarkGreenForeground,
("darkmagenta", ColorType.Foreground) => DarkMagentaForeground,
("darkred", ColorType.Foreground) => DarkRedForeground,
("darkyellow", ColorType.Foreground) => DarkYellowForeground,
("gray", ColorType.Foreground) => GrayForeground,
("green", ColorType.Foreground) => GreenForeground,
("magenta", ColorType.Foreground) => MagentaForeground,
("red", ColorType.Foreground) => RedForeground,
("white", ColorType.Foreground) => WhiteForeground,
("yellow", ColorType.Foreground) => YellowForeground,
("black", ColorType.Background) => BlackBackground,
("blue", ColorType.Background) => BlueBackground,
("cyan", ColorType.Background) => CyanBackground,
("darkblue", ColorType.Background) => DarkBlueBackground,
("darkcyan", ColorType.Background) => DarkCyanBackground,
("darkgray", ColorType.Background) => DarkGrayBackground,
("darkgreen", ColorType.Background) => DarkGreenBackground,
("darkmagenta", ColorType.Background) => DarkMagentaBackground,
("darkred", ColorType.Background) => DarkRedBackground,
("darkyellow", ColorType.Background) => DarkYellowBackground,
("gray", ColorType.Background) => GrayBackground,
("green", ColorType.Background) => GreenBackground,
("magenta", ColorType.Background) => MagentaBackground,
("red", ColorType.Background) => RedBackground,
("white", ColorType.Background) => WhiteBackground,
("yellow", ColorType.Background) => YellowBackground,
_ => null
};
public abstract IColor BlackForeground { get; }
public abstract IColor BlueForeground { get; }
public abstract IColor CyanForeground { get; }
public abstract IColor DarkBlueForeground { get; }
public abstract IColor DarkCyanForeground { get; }
public abstract IColor DarkGrayForeground { get; }
public abstract IColor DarkGreenForeground { get; }
public abstract IColor DarkMagentaForeground { get; }
public abstract IColor DarkRedForeground { get; }
public abstract IColor DarkYellowForeground { get; }
public abstract IColor GrayForeground { get; }
public abstract IColor GreenForeground { get; }
public abstract IColor MagentaForeground { get; }
public abstract IColor RedForeground { get; }
public abstract IColor WhiteForeground { get; }
public abstract IColor YellowForeground { get; }
public abstract IColor BlackBackground { get; }
public abstract IColor BlueBackground { get; }
public abstract IColor CyanBackground { get; }
public abstract IColor DarkBlueBackground { get; }
public abstract IColor DarkCyanBackground { get; }
public abstract IColor DarkGrayBackground { get; }
public abstract IColor DarkGreenBackground { get; }
public abstract IColor DarkMagentaBackground { get; }
public abstract IColor DarkRedBackground { get; }
public abstract IColor DarkYellowBackground { get; }
public abstract IColor GrayBackground { get; }
public abstract IColor GreenBackground { get; }
public abstract IColor MagentaBackground { get; }
public abstract IColor RedBackground { get; }
public abstract IColor WhiteBackground { get; }
public abstract IColor YellowBackground { get; }
}

View File

@@ -1,85 +0,0 @@
namespace TerminalUI.Color;
public static class Color256Colors
{
public static class Backgrounds
{
public static readonly Color256 Black = new(0, ColorType.Background);
public static readonly Color256 Blue = new(12, ColorType.Background);
public static readonly Color256 Cyan = new(14, ColorType.Background);
public static readonly Color256 DarkBlue = new(4, ColorType.Background);
public static readonly Color256 DarkCyan = new(6, ColorType.Background);
public static readonly Color256 DarkGray = new(8, ColorType.Background);
public static readonly Color256 DarkGreen = new(2, ColorType.Background);
public static readonly Color256 DarkMagenta = new(5, ColorType.Background);
public static readonly Color256 DarkRed = new(1, ColorType.Background);
public static readonly Color256 DarkYellow = new(3, ColorType.Background);
public static readonly Color256 Gray = new(7, ColorType.Background);
public static readonly Color256 Green = new(10, ColorType.Background);
public static readonly Color256 Magenta = new(13, ColorType.Background);
public static readonly Color256 Red = new(9, ColorType.Background);
public static readonly Color256 White = new(15, ColorType.Background);
public static readonly Color256 Yellow = new(11, ColorType.Background);
}
public static class Foregrounds
{
public static readonly Color256 Black = new(0, ColorType.Foreground);
public static readonly Color256 Blue = new(12, ColorType.Foreground);
public static readonly Color256 Cyan = new(14, ColorType.Foreground);
public static readonly Color256 DarkBlue = new(4, ColorType.Foreground);
public static readonly Color256 DarkCyan = new(6, ColorType.Foreground);
public static readonly Color256 DarkGray = new(8, ColorType.Foreground);
public static readonly Color256 DarkGreen = new(2, ColorType.Foreground);
public static readonly Color256 DarkMagenta = new(5, ColorType.Foreground);
public static readonly Color256 DarkRed = new(1, ColorType.Foreground);
public static readonly Color256 DarkYellow = new(3, ColorType.Foreground);
public static readonly Color256 Gray = new(7, ColorType.Foreground);
public static readonly Color256 Green = new(10, ColorType.Foreground);
public static readonly Color256 Magenta = new(13, ColorType.Foreground);
public static readonly Color256 Red = new(9, ColorType.Foreground);
public static readonly Color256 White = new(15, ColorType.Foreground);
public static readonly Color256 Yellow = new(11, ColorType.Foreground);
}
}
public static class ConsoleColors
{
public static class Backgrounds
{
public static readonly ConsoleColor Black = new(System.ConsoleColor.Black, ColorType.Background);
public static readonly ConsoleColor Blue = new(System.ConsoleColor.Blue, ColorType.Background);
public static readonly ConsoleColor Cyan = new(System.ConsoleColor.Cyan, ColorType.Background);
public static readonly ConsoleColor DarkBlue = new(System.ConsoleColor.DarkBlue, ColorType.Background);
public static readonly ConsoleColor DarkCyan = new(System.ConsoleColor.DarkCyan, ColorType.Background);
public static readonly ConsoleColor DarkGray = new(System.ConsoleColor.DarkGray, ColorType.Background);
public static readonly ConsoleColor DarkGreen = new(System.ConsoleColor.DarkGreen, ColorType.Background);
public static readonly ConsoleColor DarkMagenta = new(System.ConsoleColor.DarkMagenta, ColorType.Background);
public static readonly ConsoleColor DarkRed = new(System.ConsoleColor.DarkRed, ColorType.Background);
public static readonly ConsoleColor DarkYellow = new(System.ConsoleColor.DarkYellow, ColorType.Background);
public static readonly ConsoleColor Gray = new(System.ConsoleColor.Gray, ColorType.Background);
public static readonly ConsoleColor Green = new(System.ConsoleColor.Green, ColorType.Background);
public static readonly ConsoleColor Magenta = new(System.ConsoleColor.Magenta, ColorType.Background);
public static readonly ConsoleColor Red = new(System.ConsoleColor.Red, ColorType.Background);
public static readonly ConsoleColor White = new(System.ConsoleColor.White, ColorType.Background);
public static readonly ConsoleColor Yellow = new(System.ConsoleColor.Yellow, ColorType.Background);
}
public static class Foregrounds
{
public static readonly ConsoleColor Black = new(System.ConsoleColor.Black, ColorType.Foreground);
public static readonly ConsoleColor Blue = new(System.ConsoleColor.Blue, ColorType.Foreground);
public static readonly ConsoleColor Cyan = new(System.ConsoleColor.Cyan, ColorType.Foreground);
public static readonly ConsoleColor DarkBlue = new(System.ConsoleColor.DarkBlue, ColorType.Foreground);
public static readonly ConsoleColor DarkCyan = new(System.ConsoleColor.DarkCyan, ColorType.Foreground);
public static readonly ConsoleColor DarkGray = new(System.ConsoleColor.DarkGray, ColorType.Foreground);
public static readonly ConsoleColor DarkGreen = new(System.ConsoleColor.DarkGreen, ColorType.Foreground);
public static readonly ConsoleColor DarkMagenta = new(System.ConsoleColor.DarkMagenta, ColorType.Foreground);
public static readonly ConsoleColor DarkRed = new(System.ConsoleColor.DarkRed, ColorType.Foreground);
public static readonly ConsoleColor DarkYellow = new(System.ConsoleColor.DarkYellow, ColorType.Foreground);
public static readonly ConsoleColor Gray = new(System.ConsoleColor.Gray, ColorType.Foreground);
public static readonly ConsoleColor Green = new(System.ConsoleColor.Green, ColorType.Foreground);
public static readonly ConsoleColor Magenta = new(System.ConsoleColor.Magenta, ColorType.Foreground);
public static readonly ConsoleColor Red = new(System.ConsoleColor.Red, ColorType.Foreground);
public static readonly ConsoleColor White = new(System.ConsoleColor.White, ColorType.Foreground);
public static readonly ConsoleColor Yellow = new(System.ConsoleColor.Yellow, ColorType.Foreground);
}
}

View File

@@ -0,0 +1,48 @@
namespace TerminalUI.Color;
public class ConsoleColorProvider : ColorProviderBase
{
public override IColor Parse(string color, ColorType type)
{
var finalColor = ParseInternal(color, type);
if (finalColor is not null) return finalColor;
//TODO get closest color
throw new NotSupportedException($"Color can not be parsed. {color}");
}
public override IColor BlackForeground { get; } = new ConsoleColor(System.ConsoleColor.Black, ColorType.Foreground);
public override IColor BlueForeground { get; } = new ConsoleColor(System.ConsoleColor.Blue, ColorType.Foreground);
public override IColor CyanForeground { get; } = new ConsoleColor(System.ConsoleColor.Cyan, ColorType.Foreground);
public override IColor DarkBlueForeground { get; } = new ConsoleColor(System.ConsoleColor.DarkBlue, ColorType.Foreground);
public override IColor DarkCyanForeground { get; } = new ConsoleColor(System.ConsoleColor.DarkCyan, ColorType.Foreground);
public override IColor DarkGrayForeground { get; } = new ConsoleColor(System.ConsoleColor.DarkGray, ColorType.Foreground);
public override IColor DarkGreenForeground { get; } = new ConsoleColor(System.ConsoleColor.DarkGreen, ColorType.Foreground);
public override IColor DarkMagentaForeground { get; } = new ConsoleColor(System.ConsoleColor.DarkMagenta, ColorType.Foreground);
public override IColor DarkRedForeground { get; } = new ConsoleColor(System.ConsoleColor.DarkRed, ColorType.Foreground);
public override IColor DarkYellowForeground { get; } = new ConsoleColor(System.ConsoleColor.DarkYellow, ColorType.Foreground);
public override IColor GrayForeground { get; } = new ConsoleColor(System.ConsoleColor.Gray, ColorType.Foreground);
public override IColor GreenForeground { get; } = new ConsoleColor(System.ConsoleColor.Green, ColorType.Foreground);
public override IColor MagentaForeground { get; } = new ConsoleColor(System.ConsoleColor.Magenta, ColorType.Foreground);
public override IColor RedForeground { get; } = new ConsoleColor(System.ConsoleColor.Red, ColorType.Foreground);
public override IColor WhiteForeground { get; } = new ConsoleColor(System.ConsoleColor.White, ColorType.Foreground);
public override IColor YellowForeground { get; } = new ConsoleColor(System.ConsoleColor.Yellow, ColorType.Foreground);
public override IColor BlackBackground => new ConsoleColor(System.ConsoleColor.Black, ColorType.Background);
public override IColor BlueBackground => new ConsoleColor(System.ConsoleColor.Blue, ColorType.Background);
public override IColor CyanBackground => new ConsoleColor(System.ConsoleColor.Cyan, ColorType.Background);
public override IColor DarkBlueBackground => new ConsoleColor(System.ConsoleColor.DarkBlue, ColorType.Background);
public override IColor DarkCyanBackground => new ConsoleColor(System.ConsoleColor.DarkCyan, ColorType.Background);
public override IColor DarkGrayBackground => new ConsoleColor(System.ConsoleColor.DarkGray, ColorType.Background);
public override IColor DarkGreenBackground => new ConsoleColor(System.ConsoleColor.DarkGreen, ColorType.Background);
public override IColor DarkMagentaBackground => new ConsoleColor(System.ConsoleColor.DarkMagenta, ColorType.Background);
public override IColor DarkRedBackground => new ConsoleColor(System.ConsoleColor.DarkRed, ColorType.Background);
public override IColor DarkYellowBackground => new ConsoleColor(System.ConsoleColor.DarkYellow, ColorType.Background);
public override IColor GrayBackground => new ConsoleColor(System.ConsoleColor.Gray, ColorType.Background);
public override IColor GreenBackground => new ConsoleColor(System.ConsoleColor.Green, ColorType.Background);
public override IColor MagentaBackground => new ConsoleColor(System.ConsoleColor.Magenta, ColorType.Background);
public override IColor RedBackground => new ConsoleColor(System.ConsoleColor.Red, ColorType.Background);
public override IColor WhiteBackground => new ConsoleColor(System.ConsoleColor.White, ColorType.Background);
public override IColor YellowBackground => new ConsoleColor(System.ConsoleColor.Yellow, ColorType.Background);
}

View File

@@ -0,0 +1,41 @@
namespace TerminalUI.Color;
public interface IColorProvider
{
IColor Parse(string color, ColorType type);
IColor BlackForeground { get; }
IColor BlueForeground { get; }
IColor CyanForeground { get; }
IColor DarkBlueForeground { get; }
IColor DarkCyanForeground { get; }
IColor DarkGrayForeground { get; }
IColor DarkGreenForeground { get; }
IColor DarkMagentaForeground { get; }
IColor DarkRedForeground { get; }
IColor DarkYellowForeground { get; }
IColor GrayForeground { get; }
IColor GreenForeground { get; }
IColor MagentaForeground { get; }
IColor RedForeground { get; }
IColor WhiteForeground { get; }
IColor YellowForeground { get; }
IColor BlackBackground { get; }
IColor BlueBackground { get; }
IColor CyanBackground { get; }
IColor DarkBlueBackground { get; }
IColor DarkCyanBackground { get; }
IColor DarkGrayBackground { get; }
IColor DarkGreenBackground { get; }
IColor DarkMagentaBackground { get; }
IColor DarkRedBackground { get; }
IColor DarkYellowBackground { get; }
IColor GrayBackground { get; }
IColor GreenBackground { get; }
IColor MagentaBackground { get; }
IColor RedBackground { get; }
IColor WhiteBackground { get; }
IColor YellowBackground { get; }
}

View File

@@ -1,5 +1,6 @@
using TerminalUI.Controls;
using TerminalUI.Models;
using TerminalUI.Styling;
using TerminalUI.TextFormat;
using TerminalUI.Traits;
@@ -19,6 +20,7 @@ public class RenderEngine : IRenderEngine
private bool[,]? _filledCells;
private bool[,]? _lastFilledCells;
private DateTime _renderRequestDetected;
private ITheme? _lastTheme;
public RenderEngine(IApplicationContext applicationContext, IEventLoop eventLoop)
{
@@ -92,6 +94,12 @@ public class RenderEngine : IRenderEngine
_forceRerenderAll = false;
}
if (_applicationContext.Theme != _lastTheme)
{
_lastTheme = _applicationContext.Theme;
forceRerenderAll = true;
}
var driver = _applicationContext.ConsoleDriver;
var initialPosition = new Position(0, 0);
var size = driver.GetWindowSize();