diff --git a/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Configuration/StyleConfigurationRoot.cs b/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Configuration/StyleConfigurationRoot.cs new file mode 100644 index 0000000..e12ec37 --- /dev/null +++ b/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Configuration/StyleConfigurationRoot.cs @@ -0,0 +1,9 @@ +using FileTime.ConsoleUI.App.Configuration.Theme; + +namespace FileTime.ConsoleUI.App.Configuration; + +public class StyleConfigurationRoot +{ + public string? Theme { get; set; } + public Dictionary Themes { get; set; } = new(); +} \ No newline at end of file diff --git a/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Configuration/Theme/ConsoleThemeConfiguration.cs b/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Configuration/Theme/ConsoleThemeConfiguration.cs new file mode 100644 index 0000000..a74a41e --- /dev/null +++ b/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Configuration/Theme/ConsoleThemeConfiguration.cs @@ -0,0 +1,6 @@ +namespace FileTime.ConsoleUI.App.Configuration.Theme; + +public class ConsoleThemeConfiguration +{ + public ControlThemesConfiguration ControlThemes { get; set; } = new(); +} \ No newline at end of file diff --git a/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Configuration/Theme/ControlThemesConfiguration.cs b/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Configuration/Theme/ControlThemesConfiguration.cs new file mode 100644 index 0000000..9dd33bf --- /dev/null +++ b/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Configuration/Theme/ControlThemesConfiguration.cs @@ -0,0 +1,6 @@ +namespace FileTime.ConsoleUI.App.Configuration.Theme; + +public class ControlThemesConfiguration +{ + public ProgressBarThemeConfiguration? ProgressBar { get; set; } +} \ No newline at end of file diff --git a/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Configuration/Theme/ListViewItemThemeConfiguration.cs b/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Configuration/Theme/ListViewItemThemeConfiguration.cs new file mode 100644 index 0000000..7ce77d1 --- /dev/null +++ b/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Configuration/Theme/ListViewItemThemeConfiguration.cs @@ -0,0 +1,7 @@ +namespace FileTime.ConsoleUI.App.Configuration.Theme; + +public class ListViewItemThemeConfiguration +{ + public string? SelectedForegroundColor { get; set; } + public string? SelectedBackgroundColor { get; set; } +} \ No newline at end of file diff --git a/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Configuration/Theme/ProgressBarThemeConfiguration.cs b/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Configuration/Theme/ProgressBarThemeConfiguration.cs new file mode 100644 index 0000000..36c0cd5 --- /dev/null +++ b/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Configuration/Theme/ProgressBarThemeConfiguration.cs @@ -0,0 +1,24 @@ +using TerminalUI.Models; + +namespace FileTime.ConsoleUI.App.Configuration.Theme; + +public class ProgressBarThemeConfiguration +{ + public string? ForegroundColor { get; set; } + public string? BackgroundColor { get; set; } + public string? UnfilledForeground { get; set; } + public string? UnfilledBackground { get; set; } + public SelectiveChar? FilledCharacter { get; set; } + public SelectiveChar? UnfilledCharacter { get; set; } + + public SelectiveChar? Fraction1Per8Character { get; set; } + public SelectiveChar? Fraction2Per8Character { get; set; } + public SelectiveChar? Fraction3Per8Character { get; set; } + public SelectiveChar? Fraction4Per8Character { get; set; } + public SelectiveChar? Fraction5Per8Character { get; set; } + public SelectiveChar? Fraction6Per8Character { get; set; } + public SelectiveChar? Fraction7Per8Character { get; set; } + public SelectiveChar? FractionFull { get; set; } + public SelectiveChar? LeftCap { get; set; } + public SelectiveChar? RightCap { get; set; } +} \ No newline at end of file diff --git a/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Configuration/Theme/ThemeConfiguration.cs b/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Configuration/Theme/ThemeConfiguration.cs new file mode 100644 index 0000000..9792889 --- /dev/null +++ b/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Configuration/Theme/ThemeConfiguration.cs @@ -0,0 +1,20 @@ +namespace FileTime.ConsoleUI.App.Configuration.Theme; + +public class ThemeConfiguration +{ + public string? DefaultForegroundColor { get; set; } + public string? DefaultForegroundAccentColor { get; set; } + public string? DefaultBackgroundColor { get; set; } + public string? ElementColor { get; set; } + public string? ContainerColor { get; set; } + public string? MarkedItemForegroundColor { get; set; } + public string? MarkedItemBackgroundColor { get; set; } + public string? MarkedSelectedItemForegroundColor { get; set; } + public string? MarkedSelectedItemBackgroundColor { get; set; } + public string? SelectedItemColor { get; set; } + public string? SelectedTabBackgroundColor { get; set; } + public string? WarningForegroundColor { get; set; } + public string? ErrorForegroundColor { get; set; } + public ConsoleThemeConfiguration? ConsoleTheme { get; set; } + public ListViewItemThemeConfiguration? ListViewItemTheme { get; set; } +} \ No newline at end of file diff --git a/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/IColorSampleProvider.cs b/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/IColorSampleProvider.cs deleted file mode 100644 index 9faeeea..0000000 --- a/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/IColorSampleProvider.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace FileTime.ConsoleUI.App; - -public interface IColorSampleProvider -{ - public Type? ForegroundColors { get; } - public Type? BackgroundColors { get; } -} \ No newline at end of file diff --git a/src/ConsoleApp/FileTime.ConsoleUI.Styles/DefaultTheme.cs b/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Styling/DefaultTheme.cs similarity index 90% rename from src/ConsoleApp/FileTime.ConsoleUI.Styles/DefaultTheme.cs rename to src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Styling/DefaultTheme.cs index 4d4bebd..066d072 100644 --- a/src/ConsoleApp/FileTime.ConsoleUI.Styles/DefaultTheme.cs +++ b/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Styling/DefaultTheme.cs @@ -1,11 +1,6 @@ -using FileTime.ConsoleUI.App; -using FileTime.ConsoleUI.App.Styling; -using TerminalUI.Color; -using TerminalUI.Styling; -using TerminalUI.Styling.Controls; -using ITheme = FileTime.ConsoleUI.App.Styling.ITheme; +using TerminalUI.Color; -namespace FileTime.ConsoleUI.Styles; +namespace FileTime.ConsoleUI.App.Styling; using IConsoleTheme = TerminalUI.Styling.ITheme; using ConsoleTheme = TerminalUI.Styling.Theme; @@ -25,11 +20,9 @@ public record Theme( IColor? WarningForegroundColor, IColor? ErrorForegroundColor, ListViewItemTheme ListViewItemTheme, - IConsoleTheme? ConsoleTheme, - Type? ForegroundColors, - Type? BackgroundColors) : ITheme, IColorSampleProvider; + IConsoleTheme? ConsoleTheme) : ITheme; -public static class DefaultThemes +/*public static class DefaultThemes { public static Theme Color256Theme => new( DefaultForegroundColor: null, @@ -100,4 +93,4 @@ public static class DefaultThemes ForegroundColors: typeof(ConsoleColors.Foregrounds), BackgroundColors: typeof(ConsoleColors.Backgrounds) ); -} \ No newline at end of file +}*/ \ No newline at end of file diff --git a/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Styling/IThemeProvider.cs b/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Styling/IThemeProvider.cs new file mode 100644 index 0000000..3a30466 --- /dev/null +++ b/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Styling/IThemeProvider.cs @@ -0,0 +1,6 @@ +namespace FileTime.ConsoleUI.App.Styling; + +public interface IThemeProvider +{ + ITheme CurrentTheme { get; } +} \ No newline at end of file diff --git a/src/ConsoleApp/FileTime.ConsoleUI.App/App.cs b/src/ConsoleApp/FileTime.ConsoleUI.App/App.cs index 9a24ff7..9109557 100644 --- a/src/ConsoleApp/FileTime.ConsoleUI.App/App.cs +++ b/src/ConsoleApp/FileTime.ConsoleUI.App/App.cs @@ -1,8 +1,10 @@ using System.Collections.Specialized; +using System.ComponentModel; using FileTime.App.Core.Services; using FileTime.App.Core.ViewModels; using FileTime.ConsoleUI.App.Configuration; using FileTime.ConsoleUI.App.KeyInputHandling; +using FileTime.ConsoleUI.App.Styling; using GeneralInputKey; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -26,6 +28,7 @@ public class App : IApplication private readonly IApplicationContext _applicationContext; private readonly IConsoleDriver _consoleDriver; private readonly IAppState _appState; + private readonly IThemeProvider _themeProvider; private readonly ILogger _logger; private readonly IKeyInputHandlerService _keyInputHandlerService; private readonly Thread _renderThread; @@ -38,6 +41,7 @@ public class App : IApplication IApplicationContext applicationContext, IConsoleDriver consoleDriver, IAppState appState, + IThemeProvider themeProvider, IOptions consoleApplicationConfiguration, ILogger logger) { @@ -48,13 +52,30 @@ public class App : IApplication _applicationContext = applicationContext; _consoleDriver = consoleDriver; _appState = appState; + _themeProvider = themeProvider; _logger = logger; + if (themeProvider is INotifyPropertyChanged notifyPropertyChanged) + notifyPropertyChanged.PropertyChanged += ThemeProviderPropertyChanged; + + _applicationContext.Theme = themeProvider.CurrentTheme.ConsoleTheme ?? _applicationContext.Theme; + _applicationContext.SupportUtf8Output = !consoleApplicationConfiguration.Value.DisableUtf8; _renderThread = new Thread(Render); } + private void ThemeProviderPropertyChanged(object? sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == nameof(IThemeProvider.CurrentTheme)) + { + UpdateConsoleTheme(); + } + } + + private void UpdateConsoleTheme() + => _applicationContext.Theme = _themeProvider.CurrentTheme.ConsoleTheme; + public void Run() { Task.Run(async () => await _lifecycleService.InitStartupHandlersAsync()).Wait(); @@ -117,7 +138,7 @@ public class App : IApplication Thread.Sleep(10); } - + Task.Run(async () => await _lifecycleService.ExitAsync()).Wait(); } diff --git a/src/ConsoleApp/FileTime.ConsoleUI.App/MainWindow.cs b/src/ConsoleApp/FileTime.ConsoleUI.App/MainWindow.cs index efeb740..c2c0ac6 100644 --- a/src/ConsoleApp/FileTime.ConsoleUI.App/MainWindow.cs +++ b/src/ConsoleApp/FileTime.ConsoleUI.App/MainWindow.cs @@ -41,11 +41,10 @@ public class MainWindow private readonly IOptions _consoleApplicationConfiguration; private readonly Lazy _root; - public MainWindow( IRootViewModel rootViewModel, IApplicationContext applicationContext, - ITheme theme, + IThemeProvider themeProvider, CommandPalette commandPalette, FrequencyNavigation frequencyNavigation, Dialogs dialogs, @@ -55,7 +54,7 @@ public class MainWindow { _rootViewModel = rootViewModel; _applicationContext = applicationContext; - _theme = theme; + _theme = themeProvider.CurrentTheme; _commandPalette = commandPalette; _frequencyNavigation = frequencyNavigation; _dialogs = dialogs; diff --git a/src/ConsoleApp/FileTime.ConsoleUI.App/Services/ThemeProvider.cs b/src/ConsoleApp/FileTime.ConsoleUI.App/Services/ThemeProvider.cs new file mode 100644 index 0000000..38ded51 --- /dev/null +++ b/src/ConsoleApp/FileTime.ConsoleUI.App/Services/ThemeProvider.cs @@ -0,0 +1,123 @@ +using FileTime.ConsoleUI.App.Configuration; +using FileTime.ConsoleUI.App.Configuration.Theme; +using FileTime.ConsoleUI.App.Styling; +using Microsoft.Extensions.Options; +using PropertyChanged.SourceGenerator; +using TerminalUI.Color; +using TerminalUI.Styling; +using TerminalUI.Styling.Controls; +using IConsoleTheme = TerminalUI.Styling.ITheme; +using ConsoleTheme = TerminalUI.Styling.Theme; +using ITheme = FileTime.ConsoleUI.App.Styling.ITheme; +using Theme = FileTime.ConsoleUI.App.Styling.Theme; + +namespace FileTime.ConsoleUI.App.Services; + +public partial class ThemeProvider : IThemeProvider +{ + private readonly ITheme _defaultTheme; + private readonly IColorProvider _colorProvider; + private readonly IOptionsMonitor _styleConfiguration; + + [Notify] private ITheme _currentTheme = null!; + + public ThemeProvider( + ITheme defaultTheme, + IColorProvider colorProvider, + IOptionsMonitor styleConfiguration + ) + { + _defaultTheme = defaultTheme; + _colorProvider = colorProvider; + _styleConfiguration = styleConfiguration; + styleConfiguration.OnChange(ThemeConfigurationChanged); + UpdateCurrentTheme(); + } + + private void ThemeConfigurationChanged(StyleConfigurationRoot arg1, string? arg2) => UpdateCurrentTheme(); + + private void UpdateCurrentTheme() + { + var currentThemeName = _styleConfiguration.CurrentValue.Theme; + ThemeConfiguration? currentTheme = null; + if (currentThemeName is not null + && _styleConfiguration.CurrentValue.Themes.TryGetValue(currentThemeName, out currentTheme) + || currentTheme is null) + { + CurrentTheme = _defaultTheme; + return; + } + + var theme = new Theme( + ParseColor(currentTheme.DefaultForegroundColor) ?? _defaultTheme.DefaultForegroundColor, + ParseColor(currentTheme.DefaultForegroundAccentColor) ?? _defaultTheme.DefaultForegroundAccentColor, + ParseColor(currentTheme.DefaultBackgroundColor) ?? _defaultTheme.DefaultBackgroundColor, + ParseColor(currentTheme.ElementColor) ?? _defaultTheme.ElementColor, + ParseColor(currentTheme.ContainerColor) ?? _defaultTheme.ContainerColor, + ParseColor(currentTheme.MarkedItemForegroundColor) ?? _defaultTheme.MarkedItemForegroundColor, + ParseColor(currentTheme.MarkedItemBackgroundColor) ?? _defaultTheme.MarkedItemBackgroundColor, + ParseColor(currentTheme.MarkedSelectedItemForegroundColor) ?? _defaultTheme.MarkedSelectedItemForegroundColor, + ParseColor(currentTheme.MarkedSelectedItemBackgroundColor) ?? _defaultTheme.MarkedSelectedItemBackgroundColor, + ParseColor(currentTheme.SelectedItemColor) ?? _defaultTheme.SelectedItemColor, + ParseColor(currentTheme.SelectedTabBackgroundColor) ?? _defaultTheme.SelectedTabBackgroundColor, + ParseColor(currentTheme.WarningForegroundColor) ?? _defaultTheme.WarningForegroundColor, + ParseColor(currentTheme.ErrorForegroundColor) ?? _defaultTheme.ErrorForegroundColor, + CreateListViewItemTheme(currentTheme.ListViewItemTheme), + CreateConsoleTheme(currentTheme.ConsoleTheme) + ); + + CurrentTheme = theme; + } + + private IColor? ParseColor(string? colorString, bool foreground = true) + => colorString is null + ? null + : _colorProvider.Parse(colorString, foreground ? ColorType.Foreground : ColorType.Background); + + private ListViewItemTheme CreateListViewItemTheme(ListViewItemThemeConfiguration? currentThemeListViewItemTheme) + { + var theme = new ListViewItemTheme( + ParseColor(currentThemeListViewItemTheme?.SelectedForegroundColor) ?? _defaultTheme.ListViewItemTheme.SelectedForegroundColor, + ParseColor(currentThemeListViewItemTheme?.SelectedBackgroundColor) ?? _defaultTheme.ListViewItemTheme.SelectedBackgroundColor + ); + + return theme; + } + + private IConsoleTheme CreateConsoleTheme(ConsoleThemeConfiguration? currentThemeConsoleTheme) + { + var controlThemes = currentThemeConsoleTheme?.ControlThemes; + var progressBarTheme = controlThemes?.ProgressBar; + + var defaultControlThemes = _defaultTheme.ConsoleTheme?.ControlThemes; + var defaultProgressBarTheme = defaultControlThemes?.ProgressBar; + + var theme = new ConsoleTheme + { + ControlThemes = new ControlThemes + { + ProgressBar = new ProgressBarTheme + { + ForegroundColor = ParseColor(progressBarTheme?.ForegroundColor) ?? defaultProgressBarTheme?.ForegroundColor, + BackgroundColor = ParseColor(progressBarTheme?.BackgroundColor) ?? defaultProgressBarTheme?.BackgroundColor, + UnfilledForeground = ParseColor(progressBarTheme?.UnfilledForeground) ?? defaultProgressBarTheme?.UnfilledForeground, + UnfilledBackground = ParseColor(progressBarTheme?.UnfilledBackground) ?? defaultProgressBarTheme?.UnfilledBackground, + FilledCharacter = progressBarTheme?.FilledCharacter ?? defaultProgressBarTheme?.FilledCharacter, + UnfilledCharacter = progressBarTheme?.UnfilledCharacter ?? defaultProgressBarTheme?.UnfilledCharacter, + Fraction1Per8Character = progressBarTheme?.Fraction1Per8Character ?? defaultProgressBarTheme?.Fraction1Per8Character, + Fraction2Per8Character = progressBarTheme?.Fraction2Per8Character ?? defaultProgressBarTheme?.Fraction2Per8Character, + Fraction3Per8Character = progressBarTheme?.Fraction3Per8Character ?? defaultProgressBarTheme?.Fraction3Per8Character, + Fraction4Per8Character = progressBarTheme?.Fraction4Per8Character ?? defaultProgressBarTheme?.Fraction4Per8Character, + Fraction5Per8Character = progressBarTheme?.Fraction5Per8Character ?? defaultProgressBarTheme?.Fraction5Per8Character, + Fraction6Per8Character = progressBarTheme?.Fraction6Per8Character ?? defaultProgressBarTheme?.Fraction6Per8Character, + Fraction7Per8Character = progressBarTheme?.Fraction7Per8Character ?? defaultProgressBarTheme?.Fraction7Per8Character, + FractionFull = progressBarTheme?.FractionFull ?? defaultProgressBarTheme?.FractionFull, + LeftCap = progressBarTheme?.LeftCap ?? defaultProgressBarTheme?.LeftCap, + RightCap = progressBarTheme?.RightCap ?? defaultProgressBarTheme?.RightCap, + } + } + }; + + return theme; + } +} \ No newline at end of file diff --git a/src/ConsoleApp/FileTime.ConsoleUI.App/Startup.cs b/src/ConsoleApp/FileTime.ConsoleUI.App/Startup.cs index 7f78ff1..e85d036 100644 --- a/src/ConsoleApp/FileTime.ConsoleUI.App/Startup.cs +++ b/src/ConsoleApp/FileTime.ConsoleUI.App/Startup.cs @@ -5,6 +5,7 @@ using FileTime.ConsoleUI.App.Configuration; using FileTime.ConsoleUI.App.Controls; using FileTime.ConsoleUI.App.KeyInputHandling; using FileTime.ConsoleUI.App.Services; +using FileTime.ConsoleUI.App.Styling; using FileTime.ConsoleUI.App.UserCommand; using FileTime.Core.Interactions; using Microsoft.Extensions.Configuration; @@ -20,6 +21,7 @@ public class StartupHandler : IStartupHandler identifiableUserCommandService.AddIdentifiableUserCommand(NextPreviewUserCommand.Instance); identifiableUserCommandService.AddIdentifiableUserCommand(PreviousPreviewUserCommand.Instance); } + public Task InitAsync() => Task.CompletedTask; } @@ -38,10 +40,12 @@ public static class Startup services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(sp => sp.GetRequiredService()); - services.AddSingleton(); + services.TryAddSingleton(); services.AddSingleton(); + services.TryAddSingleton(); services.Configure(configuration); + services.Configure(configuration.GetSection("Style")); return services; } diff --git a/src/ConsoleApp/FileTime.ConsoleUI.Styles/FileTime.ConsoleUI.Styles.csproj b/src/ConsoleApp/FileTime.ConsoleUI.Styles/FileTime.ConsoleUI.Styles.csproj deleted file mode 100644 index 079946b..0000000 --- a/src/ConsoleApp/FileTime.ConsoleUI.Styles/FileTime.ConsoleUI.Styles.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - net7.0 - enable - enable - - - - - - - diff --git a/src/ConsoleApp/FileTime.ConsoleUI/FileTime.ConsoleUI.csproj b/src/ConsoleApp/FileTime.ConsoleUI/FileTime.ConsoleUI.csproj index c51e521..2cd84e9 100644 --- a/src/ConsoleApp/FileTime.ConsoleUI/FileTime.ConsoleUI.csproj +++ b/src/ConsoleApp/FileTime.ConsoleUI/FileTime.ConsoleUI.csproj @@ -19,7 +19,6 @@ - @@ -39,4 +38,8 @@ + + + + diff --git a/src/ConsoleApp/FileTime.ConsoleUI/InfoProviders/ColorSchema.cs b/src/ConsoleApp/FileTime.ConsoleUI/InfoProviders/ColorSchema.cs index 59d8cf9..8c346d6 100644 --- a/src/ConsoleApp/FileTime.ConsoleUI/InfoProviders/ColorSchema.cs +++ b/src/ConsoleApp/FileTime.ConsoleUI/InfoProviders/ColorSchema.cs @@ -10,14 +10,15 @@ public static class ColorSchema { private const int ColorTextMargin = 5; - public static void PrintColorSchema(ITheme theme, IConsoleDriver consoleDriver) + public static void PrintColorSchema(IThemeProvider themeProvider, IColorProvider colorProvider, IConsoleDriver consoleDriver) { + var theme = themeProvider.CurrentTheme; + consoleDriver.Dispose(); consoleDriver.ResetStyle(); PrintThemeColors(theme, consoleDriver); - if (theme is IColorSampleProvider colorSampleProvider) - PrintColorPalette(colorSampleProvider, consoleDriver); + PrintColorPalette(colorProvider, consoleDriver); } private static void PrintThemeColors(ITheme theme, IConsoleDriver consoleDriver) @@ -50,37 +51,26 @@ public static class ColorSchema consoleDriver.Write(Environment.NewLine); } - private static void PrintColorPalette(IColorSampleProvider colorSampleProvider, IConsoleDriver consoleDriver) + private static void PrintColorPalette(IColorProvider colorSampleProvider, IConsoleDriver consoleDriver) { - if (colorSampleProvider.ForegroundColors is { } foregroundColors) - { - PrintColorPalette("foreground", foregroundColors, consoleDriver); - } + var colorPalette = colorSampleProvider.GetType(); - if (colorSampleProvider.BackgroundColors is { } backgroundColors) - { - PrintColorPalette("background", backgroundColors, consoleDriver); - } - } - - private static void PrintColorPalette(string paletteName, Type colorPalette, IConsoleDriver consoleDriver) - { var colorType = typeof(IColor); var colorFields = colorPalette .GetFields() - .Where(f => f.FieldType.IsAssignableTo(colorType) && f.IsStatic) - .ToDictionary(f => f.Name, f => (IColor?) f.GetValue(null)); + .Where(f => f.FieldType.IsAssignableTo(colorType) && !f.IsStatic) + .ToDictionary(f => f.Name, f => (IColor?) f.GetValue(colorSampleProvider)); var colorProperties = colorPalette .GetProperties() - .Where(p => p.PropertyType.IsAssignableTo(colorType) && (p.GetMethod?.IsStatic ?? false)) - .ToDictionary(p => p.Name, p => (IColor?) p.GetValue(null)); + .Where(p => p.PropertyType.IsAssignableTo(colorType) && p.GetMethod is {IsStatic: false}) + .ToDictionary(p => p.Name, p => (IColor?) p.GetValue(colorSampleProvider)); var colors = colorFields .Concat(colorProperties) .OrderBy(v => v.Key) .ToDictionary(k => k.Key, v => v.Value); - consoleDriver.Write("Color palette for " + paletteName + Environment.NewLine); + consoleDriver.Write("Color palette for " + colorPalette.Name + Environment.NewLine); if (colors.Count == 0) { @@ -94,7 +84,7 @@ public static class ColorSchema { PrintColor(consoleDriver, key, value, colorTextStartX); } - + consoleDriver.ResetStyle(); consoleDriver.Write(Environment.NewLine); } diff --git a/src/ConsoleApp/FileTime.ConsoleUI/Program.cs b/src/ConsoleApp/FileTime.ConsoleUI/Program.cs index 43ef4ea..2a67464 100644 --- a/src/ConsoleApp/FileTime.ConsoleUI/Program.cs +++ b/src/ConsoleApp/FileTime.ConsoleUI/Program.cs @@ -3,12 +3,14 @@ using FileTime.App.Core; using FileTime.App.Core.Configuration; using FileTime.ConsoleUI; using FileTime.ConsoleUI.App; +using FileTime.ConsoleUI.App.Styling; using FileTime.ConsoleUI.InfoProviders; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Serilog; using Serilog.Debugging; using TerminalUI; +using TerminalUI.Color; using TerminalUI.ConsoleDrivers; using ITheme = FileTime.ConsoleUI.App.Styling.ITheme; @@ -37,9 +39,9 @@ try driver.SetCursorVisible(false); var applicationContext = serviceProvider.GetRequiredService(); - var theme = serviceProvider.GetRequiredService(); + var defaultTheme = serviceProvider.GetRequiredService(); - applicationContext.Theme = theme.ConsoleTheme; + applicationContext.Theme = defaultTheme.ConsoleTheme; var app = serviceProvider.GetRequiredService(); app.Run(); @@ -79,6 +81,7 @@ static IConfigurationRoot CreateConfiguration(string[] strings) .AddInMemoryCollection(MainConsoleConfiguration.Configuration) #if DEBUG .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) + .AddJsonFile("appsettings.Local.json", optional: true, reloadOnChange: true) #endif ; @@ -103,7 +106,8 @@ static bool HandleInfoProviders(string[] args, IServiceProvider serviceProvider) { "--info=colors", () => ColorSchema.PrintColorSchema( - serviceProvider.GetRequiredService(), + serviceProvider.GetRequiredService(), + serviceProvider.GetRequiredService(), serviceProvider.GetRequiredService() ) }, diff --git a/src/ConsoleApp/FileTime.ConsoleUI/Startup.cs b/src/ConsoleApp/FileTime.ConsoleUI/Startup.cs index 8dccfef..ca13476 100644 --- a/src/ConsoleApp/FileTime.ConsoleUI/Startup.cs +++ b/src/ConsoleApp/FileTime.ConsoleUI/Startup.cs @@ -1,10 +1,15 @@ using FileTime.ConsoleUI.App.Configuration; -using FileTime.ConsoleUI.App.Styling; -using FileTime.ConsoleUI.Styles; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Options; +using TerminalUI.Color; using TerminalUI.ConsoleDrivers; +using TerminalUI.Styling; +using TerminalUI.Styling.Controls; +using IConsoleTheme = TerminalUI.Styling.ITheme; +using ConsoleTheme = TerminalUI.Styling.Theme; +using ITheme = FileTime.ConsoleUI.App.Styling.ITheme; +using Theme = FileTime.ConsoleUI.App.Styling.Theme; namespace FileTime.ConsoleUI; @@ -48,15 +53,54 @@ public static class Startup public static IServiceCollection AddTheme(this IServiceCollection serviceCollection) { serviceCollection.TryAddSingleton(sp => + { + var colorProvider = sp.GetRequiredService(); + + return new Theme( + DefaultForegroundColor: null, + DefaultForegroundAccentColor: colorProvider.RedForeground, + DefaultBackgroundColor: null, + ElementColor: colorProvider.GrayForeground, + ContainerColor: colorProvider.BlueForeground, + MarkedItemForegroundColor: colorProvider.YellowForeground, + MarkedItemBackgroundColor: null, + MarkedSelectedItemForegroundColor: colorProvider.BlackForeground, + MarkedSelectedItemBackgroundColor: colorProvider.YellowForeground, + SelectedItemColor: colorProvider.BlackForeground, + SelectedTabBackgroundColor: colorProvider.GreenBackground, + WarningForegroundColor: colorProvider.YellowForeground, + ErrorForegroundColor: colorProvider.RedForeground, + ListViewItemTheme: new( + SelectedBackgroundColor: colorProvider.GrayBackground, + SelectedForegroundColor: colorProvider.BlackForeground + ), + ConsoleTheme: new ConsoleTheme + { + ControlThemes = new ControlThemes + { + ProgressBar = new ProgressBarTheme + { + ForegroundColor = colorProvider.BlueForeground, + BackgroundColor = colorProvider.GrayBackground, + UnfilledForeground = colorProvider.GrayForeground, + UnfilledBackground = colorProvider.GrayBackground, + } + } + } + ); + }); + + serviceCollection.TryAddSingleton(sp => { var driver = sp.GetRequiredService(); return driver switch { - XTermDriver _ => DefaultThemes.Color256Theme, - DotnetDriver _ => DefaultThemes.ConsoleColorTheme, + XTermDriver _ => new AnsiColorProvider(), + DotnetDriver _ => new ConsoleColorProvider(), _ => throw new ArgumentOutOfRangeException(nameof(driver)) }; + }); return serviceCollection; diff --git a/src/FileTime.sln b/src/FileTime.sln index 64a163b..1f75577 100644 --- a/src/FileTime.sln +++ b/src/FileTime.sln @@ -121,8 +121,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TerminalUI", "Library\Termi EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CircularBuffer", "Library\CircularBuffer\CircularBuffer.csproj", "{AF4FE804-12D9-46E2-A584-BFF6D4509766}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileTime.ConsoleUI.Styles", "ConsoleApp\FileTime.ConsoleUI.Styles\FileTime.ConsoleUI.Styles.csproj", "{CCB6F86A-7E80-448E-B543-DF9DB337C42A}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ObservableComputations.Extensions", "Library\ObservableComputations.Extensions\ObservableComputations.Extensions.csproj", "{6C3C3151-9341-4792-9B0B-A11C0658524E}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GeneralInputKey", "Library\GeneralInputKey\GeneralInputKey.csproj", "{91AE5B64-042B-4660-A8E8-D247E6E14A1E}" @@ -339,10 +337,6 @@ Global {AF4FE804-12D9-46E2-A584-BFF6D4509766}.Debug|Any CPU.Build.0 = Debug|Any CPU {AF4FE804-12D9-46E2-A584-BFF6D4509766}.Release|Any CPU.ActiveCfg = Release|Any CPU {AF4FE804-12D9-46E2-A584-BFF6D4509766}.Release|Any CPU.Build.0 = Release|Any CPU - {CCB6F86A-7E80-448E-B543-DF9DB337C42A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CCB6F86A-7E80-448E-B543-DF9DB337C42A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CCB6F86A-7E80-448E-B543-DF9DB337C42A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CCB6F86A-7E80-448E-B543-DF9DB337C42A}.Release|Any CPU.Build.0 = Release|Any CPU {6C3C3151-9341-4792-9B0B-A11C0658524E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6C3C3151-9341-4792-9B0B-A11C0658524E}.Debug|Any CPU.Build.0 = Debug|Any CPU {6C3C3151-9341-4792-9B0B-A11C0658524E}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -419,7 +413,6 @@ Global {81F44BBB-6F89-41B4-89F1-4A3204843DB5} = {CAEEAD3C-41EB-405C-ACA9-BA1E4C352549} {2F01FC4C-D942-48B0-B61C-7C5BEAED4787} = {07CA18AA-B85D-4DEE-BB86-F569F6029853} {AF4FE804-12D9-46E2-A584-BFF6D4509766} = {07CA18AA-B85D-4DEE-BB86-F569F6029853} - {CCB6F86A-7E80-448E-B543-DF9DB337C42A} = {CAEEAD3C-41EB-405C-ACA9-BA1E4C352549} {6C3C3151-9341-4792-9B0B-A11C0658524E} = {07CA18AA-B85D-4DEE-BB86-F569F6029853} {91AE5B64-042B-4660-A8E8-D247E6E14A1E} = {07CA18AA-B85D-4DEE-BB86-F569F6029853} {E72F6430-0E6E-4818-BD5F-114893ACB18E} = {07CA18AA-B85D-4DEE-BB86-F569F6029853} diff --git a/src/Library/TerminalUI.Examples/Program.cs b/src/Library/TerminalUI.Examples/Program.cs index 6601068..a8579cd 100644 --- a/src/Library/TerminalUI.Examples/Program.cs +++ b/src/Library/TerminalUI.Examples/Program.cs @@ -15,6 +15,8 @@ var services = new ServiceCollection() .AddSingleton(); IServiceProvider provider = services.BuildServiceProvider(); +var colorProvider = new ConsoleColorProvider(); + var applicationContext = provider.GetRequiredService(); applicationContext.Theme = new Theme { @@ -22,7 +24,7 @@ applicationContext.Theme = new Theme { ProgressBar = new ProgressBarTheme { - ForegroundColor = ConsoleColors.Foregrounds.Blue + ForegroundColor = colorProvider.BlueForeground } } }; diff --git a/src/Library/TerminalUI/Color/AnsiColorProvider.cs b/src/Library/TerminalUI/Color/AnsiColorProvider.cs new file mode 100644 index 0000000..f51e80a --- /dev/null +++ b/src/Library/TerminalUI/Color/AnsiColorProvider.cs @@ -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); +} \ No newline at end of file diff --git a/src/Library/TerminalUI/Color/ColorProviderBase.cs b/src/Library/TerminalUI/Color/ColorProviderBase.cs new file mode 100644 index 0000000..44c5cec --- /dev/null +++ b/src/Library/TerminalUI/Color/ColorProviderBase.cs @@ -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; } +} \ No newline at end of file diff --git a/src/Library/TerminalUI/Color/Colors.cs b/src/Library/TerminalUI/Color/Colors.cs deleted file mode 100644 index 399b458..0000000 --- a/src/Library/TerminalUI/Color/Colors.cs +++ /dev/null @@ -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); - } -} \ No newline at end of file diff --git a/src/Library/TerminalUI/Color/ConsoleColorProvider.cs b/src/Library/TerminalUI/Color/ConsoleColorProvider.cs new file mode 100644 index 0000000..8a63373 --- /dev/null +++ b/src/Library/TerminalUI/Color/ConsoleColorProvider.cs @@ -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); +} \ No newline at end of file diff --git a/src/Library/TerminalUI/Color/IColorProvider.cs b/src/Library/TerminalUI/Color/IColorProvider.cs new file mode 100644 index 0000000..dc314d9 --- /dev/null +++ b/src/Library/TerminalUI/Color/IColorProvider.cs @@ -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; } +} \ No newline at end of file diff --git a/src/Library/TerminalUI/RenderEngine.cs b/src/Library/TerminalUI/RenderEngine.cs index c897069..8638fbf 100644 --- a/src/Library/TerminalUI/RenderEngine.cs +++ b/src/Library/TerminalUI/RenderEngine.cs @@ -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();