Skip to content

Commit

Permalink
begin adding JSON serialization capabilities to ColorSchemes
Browse files Browse the repository at this point in the history
  • Loading branch information
radj307 committed Feb 22, 2022
1 parent a0e4d0f commit 3f11919
Show file tree
Hide file tree
Showing 8 changed files with 263 additions and 111 deletions.
13 changes: 13 additions & 0 deletions UIComposites/ColorBinding.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//using static System.Windows.Forms.VisualStyles.VisualStyleElement.TrayNotify;

namespace UIComposites
{
public class ColorBinding<T> : ColorBindingBase where T : Control
{
public ColorBinding(Color? fg = null, Color? bg = null) : base(fg, bg) {}
public ColorBinding() {}

public override bool AppliesToControl(Control type)
=> type is T;
}
}
54 changes: 54 additions & 0 deletions UIComposites/ColorBindingBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//using static System.Windows.Forms.VisualStyles.VisualStyleElement.TrayNotify;

namespace UIComposites
{
public class ColorBindingBase : IColorBinding
{
protected ColorBindingBase((Color, bool) fg, (Color, bool) bg)
{
_fg = fg.Item1;
_fgEnabled = fg.Item2;
_bg = bg.Item1;
_bgEnabled = bg.Item2;
}
protected ColorBindingBase(Color? fg = null, Color? bg = null)
{
_fg = fg ?? Color.Transparent;
_fgEnabled = fg != null;
_bg = bg ?? Color.Transparent;
_bgEnabled = bg != null;
}
protected ColorBindingBase()
{
_fg = Color.Transparent;
_fgEnabled = false;
_bg = Color.Transparent;
_bgEnabled = false;
}

protected Color _fg, _bg;
protected bool _fgEnabled, _bgEnabled;

Color IColorBinding.Foreground { get => _fg; set => _fg = value; }
Color IColorBinding.Background { get => _bg; set => _bg = value; }
bool IColorBinding.EnableForeground { get => _fgEnabled; set => _fgEnabled = value; }
bool IColorBinding.EnableBackground { get => _bgEnabled; set => _bgEnabled = value; }

public Color GetForeColor() => _fg;
public bool GetForeColorEnabled() => _fgEnabled;
public Color GetBackColor() => _bg;
public bool GetBackColorEnabled() => _bgEnabled;

virtual public bool AppliesToControl(Control type)
{
throw new NotImplementedException("Cannot instantiate ColorBindingBase object.");
}

public Form ApplyToSingle(Form frm)
{
frm.ForeColor = _fg;
frm.BackColor = _bg;
return frm;
}
}
}
133 changes: 24 additions & 109 deletions UIComposites/ColorScheme.cs
Original file line number Diff line number Diff line change
@@ -1,113 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//using static System.Windows.Forms.VisualStyles.VisualStyleElement.TrayNotify;
using System.Text.Json;

namespace UIComposites
{
public interface IColorBinding
public partial class ColorScheme : IColorSchemeFile
{
public Color Foreground { get; set; }
public Color Background { get; set; }
public bool EnableForeground { get; set; }
public bool EnableBackground { get; set; }

/// <summary>
/// Predicate function that determines whether or not this binding may apply to the given control type.
/// </summary>
/// <param name="type">Control type to test.</param>
/// <returns>bool</returns>
public bool AppliesToControl(Control type);
/// <summary>
/// Apply this color binding to the given control reference.
/// Does NOT recurse.
/// </summary>
/// <param name="ctrl">Control Ref</param>
public Control ApplyTo(Control ctrl)
{
ctrl.ForeColor = Foreground;
ctrl.BackColor = Background;
return ctrl;
}
}

public class ColorBindingBase : IColorBinding
{
protected ColorBindingBase((Color, bool) fg, (Color, bool) bg)
{
_fg = fg.Item1;
_fgEnabled = fg.Item2;
_bg = bg.Item1;
_bgEnabled = bg.Item2;
}
protected ColorBindingBase(Color? fg = null, Color? bg = null)
{
_fg = fg ?? Color.Transparent;
_fgEnabled = fg != null;
_bg = bg ?? Color.Transparent;
_bgEnabled = bg != null;
}

protected Color _fg, _bg;
protected bool _fgEnabled, _bgEnabled;

Color IColorBinding.Foreground { get => _fg; set => _fg = value; }
Color IColorBinding.Background { get => _bg; set => _bg = value; }
bool IColorBinding.EnableForeground { get => _fgEnabled; set => _fgEnabled = value; }
bool IColorBinding.EnableBackground { get => _bgEnabled; set => _bgEnabled = value; }

public Color GetForeColor() => _fg;
public bool GetForeColorEnabled() => _fgEnabled;
public Color GetBackColor() => _bg;
public bool GetBackColorEnabled() => _bgEnabled;

virtual public bool AppliesToControl(Control type)
{
throw new NotImplementedException("Cannot instantiate ColorBindingBase object.");
}

public Form ApplyToSingle(Form frm)
{
frm.ForeColor = _fg;
frm.BackColor = _bg;
return frm;
}
}

public class DefaultColorBinding : ColorBindingBase
{
public DefaultColorBinding(Color? fg = null, Color? bg = null, List<Type>? exclude = null) : base(fg, bg)
{
excludeControls = exclude ?? new();
}

private readonly List<Type> excludeControls;

public override bool AppliesToControl(Control type)
{
foreach (Type t in excludeControls)
{
if (type.GetType() == t)
return false;
}
return true;
}
}

public class ColorBinding<T> : ColorBindingBase where T : Control
{
public ColorBinding(Color? fg, Color? bg) : base(fg, bg) {}

public override bool AppliesToControl(Control type)
=> type is T;
}


public partial class ColorScheme
{
public ColorScheme(DefaultColorBinding defaultColors, List<IColorBinding> colors)
public ColorScheme(ColorBinding<Control> defaultColors, List<IColorBinding> colors)
{
Theme = colors;
Default = defaultColors;
Expand All @@ -120,9 +17,13 @@ public ColorScheme()
BorderHighlight = new();
}

public ColorBinding<Control> Default;
public ColorBinding<Control> BorderHighlight;
public List<IColorBinding> Theme;
public DefaultColorBinding Default;
public DefaultColorBinding BorderHighlight;

public IColorBinding Primary { get => this.Default; set => this.Default = (ColorBinding<Control>)value; }
public IColorBinding Secondary { get => this.BorderHighlight; set => this.BorderHighlight = (ColorBinding<Control>)value; }
public List<IColorBinding> Components { get => this.Theme; set => this.Theme = value; }

private IColorBinding GetApplicableColor(Control type)
{
Expand All @@ -135,7 +36,7 @@ private IColorBinding GetApplicableColor(Control type)
}
return Default;
}

public void ApplyTo(Control.ControlCollection controls)
{
foreach (Control ctrl in controls)
Expand All @@ -145,5 +46,19 @@ public void ApplyTo(Control.ControlCollection controls)
ApplyTo(ctrl.Controls);
}
}

public static ColorScheme? LoadFromFile(string path)
{
return JSON.Read<ColorScheme>(path, new JsonSerializerOptions()
{
Converters =
{
new InterfaceConverterFactory(typeof(ColorBinding<Control>), typeof(IColorBinding)),
new IListInterfaceConverterFactory(typeof(IColorBinding))
}
});
}
public void SaveToFile(string path) => JSON.Write<ColorScheme>(path, this);
public static void SaveToFile(ColorScheme scheme, string path) => JSON.Write<ColorScheme>(path, scheme);
}
}
30 changes: 30 additions & 0 deletions UIComposites/ColorSchemeList.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
namespace UIComposites
{
public class ColorSchemeList
{
public ColorSchemeList(string dir)
{
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);

string[] filenames = Directory.GetFiles(dir, "*.json");

foreach (string file in filenames)
{
var scheme = ColorScheme.LoadFromFile(file);
if (scheme != null)
Schemes.Add(Path.GetFileNameWithoutExtension(file), scheme);
}
}

public Dictionary<string, ColorScheme> Schemes = new();

public ColorScheme? GetWithName(string schemeName, StringComparison strcomp = StringComparison.Ordinal)
{
foreach (KeyValuePair<string, ColorScheme> entry in Schemes)
if (entry.Key.Equals(schemeName, strcomp))
return entry.Value;
return null;
}
}
}
30 changes: 30 additions & 0 deletions UIComposites/IColorBinding.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//using static System.Windows.Forms.VisualStyles.VisualStyleElement.TrayNotify;

namespace UIComposites
{
public interface IColorBinding
{
public Color Foreground { get; set; }
public Color Background { get; set; }
public bool EnableForeground { get; set; }
public bool EnableBackground { get; set; }

/// <summary>
/// Predicate function that determines whether or not this binding may apply to the given control type.
/// </summary>
/// <param name="type">Control type to test.</param>
/// <returns>bool</returns>
public bool AppliesToControl(Control type);
/// <summary>
/// Apply this color binding to the given control reference.
/// Does NOT recurse.
/// </summary>
/// <param name="ctrl">Control Ref</param>
public Control ApplyTo(Control ctrl)
{
ctrl.ForeColor = Foreground;
ctrl.BackColor = Background;
return ctrl;
}
}
}
84 changes: 84 additions & 0 deletions UIComposites/IColorSchemeFile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using System.Text.Json;
using System.Text.Json.Serialization;

namespace UIComposites
{
public class ColorBindingConverter<M, I> : JsonConverter<I> where M : class, I
{
public override I? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return JsonSerializer.Deserialize<M>(ref reader, options);
}

public override void Write(Utf8JsonWriter writer, I value, JsonSerializerOptions options) { }
}
public class ListConverter<M> : JsonConverter<IList<M>>
{
public override IList<M> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return JsonSerializer.Deserialize<List<M>>(ref reader, options);
}

public override void Write(Utf8JsonWriter writer, IList<M> value, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
}
public class IListInterfaceConverterFactory : JsonConverterFactory
{
public IListInterfaceConverterFactory(Type interfaceType)
{
this.InterfaceType = interfaceType;
}

public Type InterfaceType { get; }

public override bool CanConvert(Type typeToConvert)
{
if (typeToConvert.Equals(typeof(IList<>).MakeGenericType(this.InterfaceType))
&& typeToConvert.GenericTypeArguments[0].Equals(this.InterfaceType))
{
return true;
}

return false;
}

public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
return (JsonConverter)Activator.CreateInstance(
typeof(ListConverter<>).MakeGenericType(this.InterfaceType));
}
}
public class InterfaceConverterFactory : JsonConverterFactory
{
public InterfaceConverterFactory(Type concrete, Type interfaceType)
{
this.ConcreteType = concrete;
this.InterfaceType = interfaceType;
}

public Type ConcreteType { get; }
public Type InterfaceType { get; }

public override bool CanConvert(Type typeToConvert)
{
return typeToConvert == this.InterfaceType;
}

public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
var converterType = typeof(ColorBindingConverter<,>).MakeGenericType(this.ConcreteType, this.InterfaceType);

return (JsonConverter)Activator.CreateInstance(converterType);
}
}
public interface IColorSchemeFile
{
[JsonConverter(typeof(ColorBindingConverter<ColorBinding<Control>, IColorBinding>))]
public IColorBinding Primary { get; set; }
[JsonConverter(typeof(ColorBindingConverter<ColorBinding<Control>, IColorBinding>))]
public IColorBinding Secondary { get; set; }
public List<IColorBinding> Components { get; set; }
}
}
18 changes: 18 additions & 0 deletions UIComposites/JSON.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Text.Json;

namespace UIComposites
{
public static class JSON
{
public static async Task<T?> ReadAsync<T>(string path, JsonSerializerOptions? opt = null)
{
using FileStream stream = File.OpenRead(path);
return await JsonSerializer.DeserializeAsync<T>(stream, opt);
}
public static T? Read<T>(string path, JsonSerializerOptions? opt = null)
{
return JsonSerializer.Deserialize<T>(File.ReadAllText(path), opt);
}
public static void Write<T>(string path, T obj, JsonSerializerOptions? opt = null) => File.WriteAllText(path, JsonSerializer.Serialize<T>(obj, opt));
}
}
Loading

0 comments on commit 3f11919

Please sign in to comment.