123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- #nullable enable
- using System.Collections;
- using System.Diagnostics;
- using System.Text.Json.Serialization;
- namespace Terminal.Gui;
- /// <summary>Contains a dictionary of the <see cref="ThemeManager.Theme"/>s for a Terminal.Gui application.</summary>
- /// <remarks>
- /// <para>A Theme is a collection of settings that are named. The default theme is named "Default".</para>
- /// <para>The <see cref="ThemeManager.Theme"/> property is used to detemrine the currently active theme.</para>
- /// </remarks>
- /// <para>
- /// <see cref="ThemeManager"/> is a singleton class. It is created when the first <see cref="ThemeManager"/> property
- /// is accessed. Accessing <see cref="ThemeManager.Instance"/> is the same as accessing
- /// <see cref="ConfigurationManager.Themes"/>.
- /// </para>
- /// <example>
- /// <code>
- /// "Themes": [
- /// {
- /// "Default": {
- /// "ColorSchemes": [
- /// {
- /// "TopLevel": {
- /// "Normal": {
- /// "Foreground": "BrightGreen",
- /// "Background": "Black"
- /// },
- /// "Focus": {
- /// "Foreground": "White",
- /// "Background": "Cyan"
- ///
- /// },
- /// "HotNormal": {
- /// "Foreground": "Yellow",
- /// "Background": "Black"
- ///
- /// },
- /// "HotFocus": {
- /// "Foreground": "Blue",
- /// "Background": "Cyan"
- /// },
- /// "Disabled": {
- /// "Foreground": "DarkGray",
- /// "Background": "Black"
- ///
- /// }
- /// }
- /// }
- /// </code>
- /// </example>
- public class ThemeManager : IDictionary<string, ThemeScope>
- {
- private static string _theme = string.Empty;
- static ThemeManager () { } // Make sure it's truly lazy
- private ThemeManager () { } // Prevent instantiation outside
- /// <summary>Class is a singleton...</summary>
- public static ThemeManager Instance { get; } = new ();
- /// <summary>Gets or sets the currently selected theme. The value is persisted to the "Theme" property.</summary>
- [JsonIgnore]
- public string Theme
- {
- get => SelectedTheme;
- set => SelectedTheme = value;
- }
- /// <summary>Holds the <see cref="ThemeScope"/> definitions.</summary>
- [JsonInclude]
- [JsonConverter (typeof (DictionaryJsonConverter<ThemeScope>))]
- [SerializableConfigurationProperty (Scope = typeof (SettingsScope), OmitClassName = true)]
- public static Dictionary<string, ThemeScope>? Themes
- {
- get => Settings? ["Themes"]
- ?.PropertyValue as
- Dictionary<string, ThemeScope>; // themes ?? new Dictionary<string, ThemeScope> ();
- set =>
- //if (themes == null || value == null) {
- // themes = value;
- //} else {
- // themes = (Dictionary<string, ThemeScope>)DeepMemberwiseCopy (value!, themes!)!;
- //}
- Settings! ["Themes"].PropertyValue = value;
- }
- /// <summary>The currently selected theme. This is the internal version; see <see cref="Theme"/>.</summary>
- [JsonInclude]
- [SerializableConfigurationProperty (Scope = typeof (SettingsScope), OmitClassName = true)]
- [JsonPropertyName ("Theme")]
- internal static string SelectedTheme
- {
- get => _theme;
- set
- {
- string oldTheme = _theme;
- _theme = value;
- if (oldTheme != _theme && Settings! ["Themes"]?.PropertyValue is Dictionary<string, ThemeScope> themes && themes.ContainsKey (_theme))
- {
- Settings! ["Theme"].PropertyValue = _theme;
- Instance.OnThemeChanged (oldTheme);
- }
- }
- }
- /// <summary>Event fired he selected theme has changed. application.</summary>
- public event EventHandler<ThemeManagerEventArgs>? ThemeChanged;
- internal static void GetHardCodedDefaults ()
- {
- Debug.WriteLine ("Themes.GetHardCodedDefaults()");
- var theme = new ThemeScope ();
- theme.RetrieveValues ();
- Themes = new Dictionary<string, ThemeScope> (StringComparer.InvariantCultureIgnoreCase)
- {
- { "Default", theme }
- };
- SelectedTheme = "Default";
- }
- /// <summary>Called when the selected theme has changed. Fires the <see cref="ThemeChanged"/> event.</summary>
- internal void OnThemeChanged (string theme)
- {
- Debug.WriteLine ($"Themes.OnThemeChanged({theme}) -> {Theme}");
- ThemeChanged?.Invoke (this, new ThemeManagerEventArgs (theme));
- }
- internal static void Reset ()
- {
- Debug.WriteLine ("Themes.Reset()");
- Colors.Reset ();
- Themes?.Clear ();
- SelectedTheme = string.Empty;
- }
- #region IDictionary
- #pragma warning disable 1591
- public ICollection<string> Keys => ((IDictionary<string, ThemeScope>)Themes!).Keys;
- public ICollection<ThemeScope> Values => ((IDictionary<string, ThemeScope>)Themes!).Values;
- public int Count => ((ICollection<KeyValuePair<string, ThemeScope>>)Themes!).Count;
- public bool IsReadOnly => ((ICollection<KeyValuePair<string, ThemeScope>>)Themes!).IsReadOnly;
- public ThemeScope this [string key]
- {
- get => ((IDictionary<string, ThemeScope>)Themes!) [key];
- set => ((IDictionary<string, ThemeScope>)Themes!) [key] = value;
- }
- public void Add (string key, ThemeScope value) { ((IDictionary<string, ThemeScope>)Themes!).Add (key, value); }
- public bool ContainsKey (string key) { return ((IDictionary<string, ThemeScope>)Themes!).ContainsKey (key); }
- public bool Remove (string key) { return ((IDictionary<string, ThemeScope>)Themes!).Remove (key); }
- public bool TryGetValue (string key, out ThemeScope value) { return ((IDictionary<string, ThemeScope>)Themes!).TryGetValue (key, out value!); }
- public void Add (KeyValuePair<string, ThemeScope> item) { ((ICollection<KeyValuePair<string, ThemeScope>>)Themes!).Add (item); }
- public void Clear () { ((ICollection<KeyValuePair<string, ThemeScope>>)Themes!).Clear (); }
- public bool Contains (KeyValuePair<string, ThemeScope> item) { return ((ICollection<KeyValuePair<string, ThemeScope>>)Themes!).Contains (item); }
- public void CopyTo (KeyValuePair<string, ThemeScope> [] array, int arrayIndex)
- {
- ((ICollection<KeyValuePair<string, ThemeScope>>)Themes!).CopyTo (array, arrayIndex);
- }
- public bool Remove (KeyValuePair<string, ThemeScope> item) { return ((ICollection<KeyValuePair<string, ThemeScope>>)Themes!).Remove (item); }
- public IEnumerator<KeyValuePair<string, ThemeScope>> GetEnumerator () { return ((IEnumerable<KeyValuePair<string, ThemeScope>>)Themes!).GetEnumerator (); }
- IEnumerator IEnumerable.GetEnumerator () { return ((IEnumerable)Themes!).GetEnumerator (); }
- #pragma warning restore 1591
- #endregion
- }
|