diff options
Diffstat (limited to 'src/SMAPI.Internal/ConsoleWriting')
-rw-r--r-- | src/SMAPI.Internal/ConsoleWriting/ColorfulConsoleWriter.cs | 138 | ||||
-rw-r--r-- | src/SMAPI.Internal/ConsoleWriting/LogLevel.cs | 30 | ||||
-rw-r--r-- | src/SMAPI.Internal/ConsoleWriting/MonitorColorScheme.cs | 15 |
3 files changed, 183 insertions, 0 deletions
diff --git a/src/SMAPI.Internal/ConsoleWriting/ColorfulConsoleWriter.cs b/src/SMAPI.Internal/ConsoleWriting/ColorfulConsoleWriter.cs new file mode 100644 index 00000000..c04cf0e7 --- /dev/null +++ b/src/SMAPI.Internal/ConsoleWriting/ColorfulConsoleWriter.cs @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; + +namespace StardewModdingAPI.Internal.ConsoleWriting +{ + /// <summary>Provides a wrapper for writing color-coded text to the console.</summary> + internal class ColorfulConsoleWriter + { + /********* + ** Properties + *********/ + /// <summary>The console text color for each log level.</summary> + private readonly IDictionary<ConsoleLogLevel, ConsoleColor> Colors; + + /// <summary>Whether the current console supports color formatting.</summary> + private readonly bool SupportsColor; + + + /********* + ** Public methods + *********/ + /// <summary>Construct an instance.</summary> + /// <param name="platform">The target platform.</param> + /// <param name="colorScheme">The console color scheme to use.</param> + public ColorfulConsoleWriter(Platform platform, MonitorColorScheme colorScheme) + { + this.SupportsColor = this.TestColorSupport(); + this.Colors = this.GetConsoleColorScheme(platform, colorScheme); + } + + /// <summary>Write a message line to the log.</summary> + /// <param name="message">The message to log.</param> + /// <param name="level">The log level.</param> + public void WriteLine(string message, ConsoleLogLevel level) + { + if (this.SupportsColor) + { + if (level == ConsoleLogLevel.Critical) + { + Console.BackgroundColor = ConsoleColor.Red; + Console.ForegroundColor = ConsoleColor.White; + Console.WriteLine(message); + Console.ResetColor(); + } + else + { + Console.ForegroundColor = this.Colors[level]; + Console.WriteLine(message); + Console.ResetColor(); + } + } + else + Console.WriteLine(message); + } + + + /********* + ** Private methods + *********/ + /// <summary>Test whether the current console supports color formatting.</summary> + private bool TestColorSupport() + { + try + { + Console.ForegroundColor = Console.ForegroundColor; + return true; + } + catch (Exception) + { + return false; // Mono bug + } + } + + /// <summary>Get the color scheme to use for the current console.</summary> + /// <param name="platform">The target platform.</param> + /// <param name="colorScheme">The console color scheme to use.</param> + private IDictionary<ConsoleLogLevel, ConsoleColor> GetConsoleColorScheme(Platform platform, MonitorColorScheme colorScheme) + { + // auto detect color scheme + if (colorScheme == MonitorColorScheme.AutoDetect) + { + colorScheme = platform == Platform.Mac + ? MonitorColorScheme.LightBackground // MacOS doesn't provide console background color info, but it's usually white. + : ColorfulConsoleWriter.IsDark(Console.BackgroundColor) ? MonitorColorScheme.DarkBackground : MonitorColorScheme.LightBackground; + } + + // get colors for scheme + switch (colorScheme) + { + case MonitorColorScheme.DarkBackground: + return new Dictionary<ConsoleLogLevel, ConsoleColor> + { + [ConsoleLogLevel.Trace] = ConsoleColor.DarkGray, + [ConsoleLogLevel.Debug] = ConsoleColor.DarkGray, + [ConsoleLogLevel.Info] = ConsoleColor.White, + [ConsoleLogLevel.Warn] = ConsoleColor.Yellow, + [ConsoleLogLevel.Error] = ConsoleColor.Red, + [ConsoleLogLevel.Alert] = ConsoleColor.Magenta, + [ConsoleLogLevel.Success] = ConsoleColor.DarkGreen + }; + + case MonitorColorScheme.LightBackground: + return new Dictionary<ConsoleLogLevel, ConsoleColor> + { + [ConsoleLogLevel.Trace] = ConsoleColor.DarkGray, + [ConsoleLogLevel.Debug] = ConsoleColor.DarkGray, + [ConsoleLogLevel.Info] = ConsoleColor.Black, + [ConsoleLogLevel.Warn] = ConsoleColor.DarkYellow, + [ConsoleLogLevel.Error] = ConsoleColor.Red, + [ConsoleLogLevel.Alert] = ConsoleColor.DarkMagenta, + [ConsoleLogLevel.Success] = ConsoleColor.DarkGreen + }; + + default: + throw new NotSupportedException($"Unknown color scheme '{colorScheme}'."); + } + } + + /// <summary>Get whether a console color should be considered dark, which is subjectively defined as 'white looks better than black on this text'.</summary> + /// <param name="color">The color to check.</param> + private static bool IsDark(ConsoleColor color) + { + switch (color) + { + case ConsoleColor.Black: + case ConsoleColor.Blue: + case ConsoleColor.DarkBlue: + case ConsoleColor.DarkMagenta: // Powershell + case ConsoleColor.DarkRed: + case ConsoleColor.Red: + return true; + + default: + return false; + } + } + } +} diff --git a/src/SMAPI.Internal/ConsoleWriting/LogLevel.cs b/src/SMAPI.Internal/ConsoleWriting/LogLevel.cs new file mode 100644 index 00000000..54564111 --- /dev/null +++ b/src/SMAPI.Internal/ConsoleWriting/LogLevel.cs @@ -0,0 +1,30 @@ +namespace StardewModdingAPI.Internal.ConsoleWriting +{ + /// <summary>The log severity levels.</summary> + internal enum ConsoleLogLevel + { + /// <summary>Tracing info intended for developers.</summary> + Trace, + + /// <summary>Troubleshooting info that may be relevant to the player.</summary> + Debug, + + /// <summary>Info relevant to the player. This should be used judiciously.</summary> + Info, + + /// <summary>An issue the player should be aware of. This should be used rarely.</summary> + Warn, + + /// <summary>A message indicating something went wrong.</summary> + Error, + + /// <summary>Important information to highlight for the player when player action is needed (e.g. new version available). This should be used rarely to avoid alert fatigue.</summary> + Alert, + + /// <summary>A critical issue that generally signals an immediate end to the application.</summary> + Critical, + + /// <summary>A success message that generally signals a successful end to a task.</summary> + Success + } +} diff --git a/src/SMAPI.Internal/ConsoleWriting/MonitorColorScheme.cs b/src/SMAPI.Internal/ConsoleWriting/MonitorColorScheme.cs new file mode 100644 index 00000000..bccb56d7 --- /dev/null +++ b/src/SMAPI.Internal/ConsoleWriting/MonitorColorScheme.cs @@ -0,0 +1,15 @@ +namespace StardewModdingAPI.Internal.ConsoleWriting +{ + /// <summary>A monitor color scheme to use.</summary> + internal enum MonitorColorScheme + { + /// <summary>Choose a color scheme automatically.</summary> + AutoDetect, + + /// <summary>Use lighter text colors that look better on a black or dark background.</summary> + DarkBackground, + + /// <summary>Use darker text colors that look better on a white or light background.</summary> + LightBackground + } +} |