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

@@ -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<App> _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> consoleApplicationConfiguration,
ILogger<App> 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();
}

View File

@@ -41,11 +41,10 @@ public class MainWindow
private readonly IOptions<ConsoleApplicationConfiguration> _consoleApplicationConfiguration;
private readonly Lazy<IView> _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;

View File

@@ -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<StyleConfigurationRoot> _styleConfiguration;
[Notify] private ITheme _currentTheme = null!;
public ThemeProvider(
ITheme defaultTheme,
IColorProvider colorProvider,
IOptionsMonitor<StyleConfigurationRoot> 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;
}
}

View File

@@ -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<IRootViewModel, RootViewModel>();
services.TryAddSingleton<IDialogService, DialogService>();
services.TryAddSingleton<IUserCommunicationService>(sp => sp.GetRequiredService<IDialogService>());
services.AddSingleton<IUserCommandHandler, ConsoleUserCommandHandler>();
services.TryAddSingleton<IUserCommandHandler, ConsoleUserCommandHandler>();
services.AddSingleton<IStartupHandler, StartupHandler>();
services.TryAddSingleton<IThemeProvider, ThemeProvider>();
services.Configure<ConsoleApplicationConfiguration>(configuration);
services.Configure<StyleConfigurationRoot>(configuration.GetSection("Style"));
return services;
}