Skip to content

Commit

Permalink
Themable components (#231)
Browse files Browse the repository at this point in the history
Co-authored-by: AtomicLiquid <[email protected]>
  • Loading branch information
snixtho and AtomicLiquid authored Dec 12, 2023
1 parent 72072e6 commit e072604
Show file tree
Hide file tree
Showing 176 changed files with 3,881 additions and 1,124 deletions.
5 changes: 4 additions & 1 deletion EvoSC.sln
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EvoSC.Manialinks.Tests", "t
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SetName", "src\Modules\SetName\SetName.csproj", "{568D81FE-858A-4052-B59B-9381E0FE604C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FastestCp", "src\Modules\FastestCp\FastestCp.csproj", "{9E1335F9-6C39-4B3F-9CEB-A65EEDDF798D}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FastestCpModule", "src\Modules\FastestCpModule\FastestCpModule.csproj", "{9E1335F9-6C39-4B3F-9CEB-A65EEDDF798D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Modules", "Modules", "{6D75D6A2-6ECD-4DE4-96C5-CAD7D134407A}"
EndProject
Expand Down Expand Up @@ -104,6 +104,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModuleManagerModule", "src\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatchTrackerModule.Tests", "tests\Modules\MatchTrackerModule.Tests\MatchTrackerModule.Tests.csproj", "{9EF4D340-0C49-4A15-9BCF-6CD9508AA7DE}"
EndProject



Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down
1 change: 0 additions & 1 deletion src/EvoSC.Commands/Parser/ChatCommandParser.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using EvoSC.Commands.Exceptions;
using EvoSC.Commands.Interfaces;
using EvoSC.Common.Interfaces.Parsing;

namespace EvoSC.Commands.Parser;

Expand Down
8 changes: 7 additions & 1 deletion src/EvoSC.Common/Application/AppFeature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,5 +115,11 @@ public enum AppFeature
/// Manage, add, remove, display manialinks and respond to actions. The manialink framework.
/// </summary>
[Identifier(NoPrefix = true)]
Manialinks
Manialinks,

/// <summary>
/// Add, remove and manage themes using the theme manager.
/// </summary>
[Identifier(NoPrefix = true)]
Themes
}
5 changes: 3 additions & 2 deletions src/EvoSC.Common/Config/Configuration.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using Config.Net;
using EvoSC.Common.Config.Models;
using EvoSC.Common.Config.Stores;
using EvoSC.Common.Config.Mapping;
using EvoSC.Common.Config.Mapping.Toml;
using EvoSC.Common.Config.Models;
using EvoSC.Common.Config.Stores;

namespace EvoSC.Common.Config;

Expand All @@ -23,6 +23,7 @@ public static IEvoScBaseConfig GetBaseConfig(string configFile, Dictionary<strin
.UseEvoScConfig(MainConfigFile, cliOptions)
.UseTypeParser(new TextColorTypeParser())
.UseTypeParser(new VersionParser())
.UseTypeParser(new ThemeOptionsParser())
.Build();

return baseConfig;
Expand Down
47 changes: 47 additions & 0 deletions src/EvoSC.Common/Config/Mapping/ThemeOptionsParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System.Diagnostics.CodeAnalysis;
using Config.Net;
using EvoSC.Common.Themes;
using Tomlet;
using Tomlet.Models;

namespace EvoSC.Common.Config.Mapping;

public class ThemeOptionsParser : ITypeParser
{
public bool TryParse(string? value, Type t, [UnscopedRef] out object? result)
{
var parser = new TomlParser();
var doc = parser.Parse(value);
var options = new Dictionary<string, object>();

foreach (var entry in doc.Entries)
{
GetEntriesRecursive(entry.Key, entry.Value, options);
}

result = new DynamicThemeOptions(options);
return true;
}

public string? ToRawString(object? value)
{
return "";
}

public IEnumerable<Type> SupportedTypes => new[] { typeof(DynamicThemeOptions) };

private void GetEntriesRecursive(string name, TomlValue tomlValue, Dictionary<string, object> options)
{
if (tomlValue is TomlTable table)
{
foreach (var entry in table.Entries)
{
GetEntriesRecursive($"{name}.{entry.Key}", entry.Value, options);
}
}
else
{
options[name] = tomlValue.StringValue;
}
}
}
1 change: 1 addition & 0 deletions src/EvoSC.Common/Config/Mapping/Toml/ConfigMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ public static void AddMapper<T>(ITomlTypeMapper<T> mapper) =>
public static void SetupDefaultMappers()
{
AddMapper(new TextColorTomlMapper());
AddMapper(new ThemeConfigOptionsMapper());
}
}
82 changes: 82 additions & 0 deletions src/EvoSC.Common/Config/Mapping/Toml/ThemeConfigOptionsMapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
using EvoSC.Common.Interfaces.Config.Mapping;
using EvoSC.Common.Themes;
using Tomlet;
using Tomlet.Models;

namespace EvoSC.Common.Config.Mapping.Toml;

public class ThemeConfigOptionsMapper : ITomlTypeMapper<DynamicThemeOptions>
{
public TomlValue Serialize(DynamicThemeOptions? typeValue)
{
var doc = TomlDocument.CreateEmpty();

foreach (var option in typeValue)
{
BuildTomlDocument(doc, option.Key.Split('.'), option.Value);
}

return doc;
}

public DynamicThemeOptions Deserialize(TomlValue tomlValue)
{
var doc = tomlValue as TomlDocument;

if (doc == null)
{
throw new InvalidOperationException("Value is not a document");
}

var options = new DynamicThemeOptions();

foreach (var entry in doc.Entries)
{
BuildOptionsObject(options, entry.Key, entry.Value);
}

return options;
}

private void BuildTomlDocument(TomlDocument doc, IEnumerable<string> optionParts, object value)
{
var parts = optionParts as string[] ?? optionParts.ToArray();

if (parts.Length == 1)
{
var tomlValue = TomletMain.ValueFrom(value);
doc.Entries[parts.First()] = tomlValue;
return;
}

foreach (var part in parts)
{
if (doc.ContainsKey(part))
{
BuildTomlDocument((TomlDocument)doc.Entries[part], parts.Skip(1), value);
}
else
{
var newDoc = TomlDocument.CreateEmpty();
doc.Entries[part] = newDoc;
BuildTomlDocument(newDoc, parts.Skip(1), value);
}
}
}

private void BuildOptionsObject(DynamicThemeOptions options, string key, TomlValue tomlValue)
{
var doc = tomlValue as TomlDocument;

if (doc == null)
{
options[key] = tomlValue.StringValue;
return;
}

foreach (var entry in doc.Entries)
{
BuildOptionsObject(options, $"{key}.{entry.Key}", entry.Value);
}
}
}
8 changes: 6 additions & 2 deletions src/EvoSC.Common/Config/Models/IEvoScBaseConfig.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
namespace EvoSC.Common.Config.Models;
using EvoSC.Common.Themes;

namespace EvoSC.Common.Config.Models;

public interface IEvoScBaseConfig
{
public IDatabaseConfig Database { get; set; }
public ILoggingConfig Logging { get; set; }
public IServerConfig Server { get; set; }
public IPathConfig Path { get; set; }
public IThemeConfig Theme { get; set; }

public IModuleConfig Modules { get; set; }
public ILocaleConfig Locale { get; set; }

public DynamicThemeOptions Theme { get; set; }
}
21 changes: 16 additions & 5 deletions src/EvoSC.Common/Config/Stores/TomlConfigStore.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Globalization;
using System.Reflection;
using Config.Net;
using EvoSC.Common.Themes;
using EvoSC.Common.Util;
using EvoSC.Common.Util.TextFormatting;
using Tomlet;
using Tomlet.Exceptions;
using Tomlet.Models;

namespace EvoSC.Common.Config.Stores;
Expand Down Expand Up @@ -53,6 +52,11 @@ private TomlDocument BuildSubDocument(TomlDocument document, Type type, string n
{
foreach (var property in type.GetProperties())
{
if (property.PropertyType == typeof(DynamicThemeOptions))
{
continue;
}

if (property.PropertyType.IsInterface)
{
document = BuildSubDocument(document, property.PropertyType, name == "" ? property.Name : $"{name}.{property.Name}");
Expand All @@ -68,7 +72,9 @@ private TomlDocument BuildSubDocument(TomlDocument document, Type type, string n

var tomlValue = optionAttr?.DefaultValue ?? property.PropertyType.GetDefaultTypeValue();
if (property.PropertyType == typeof(TextColor))
{
tomlValue = new TextColor(tomlValue.ToString());
}

// get property value
var value = TomletMain.ValueFrom(property.PropertyType,
Expand Down Expand Up @@ -100,13 +106,13 @@ public void Dispose()
if (lastDotIndex > 0 && key.Length > lastDotIndex + 1 && !char.IsAsciiLetterOrDigit(key[lastDotIndex + 1]))
{
var value = _document.GetValue(key[..lastDotIndex]) as TomlArray;
return value.Count.ToString();
return value.Count.ToString(CultureInfo.InvariantCulture);
}

if (key.EndsWith("]", StringComparison.Ordinal))
{
var indexStart = key.IndexOf("[", StringComparison.Ordinal);
var index = int.Parse(key[(indexStart + 1)..^1]);
var index = int.Parse(key[(indexStart + 1)..^1], CultureInfo.InvariantCulture);
var value = _document.GetValue(key[..indexStart]) as TomlArray;

return value?.Skip(index)?.FirstOrDefault()?.StringValue;
Expand All @@ -118,6 +124,11 @@ public void Dispose()
{
return string.Join(" ", arrayValue.Select(v => v.StringValue));
}

if (keyValue is TomlTable tableValue)
{
return tableValue.SerializeNonInlineTable("Theme", false);
}

return keyValue.StringValue;
}
Expand Down
1 change: 0 additions & 1 deletion src/EvoSC.Common/Database/Repository/DbRepository.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

using EvoSC.Common.Interfaces.Database;
using LinqToDB;
using LinqToDB.Data;

namespace EvoSC.Common.Database.Repository;

Expand Down
1 change: 1 addition & 0 deletions src/EvoSC.Common/EvoSC.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="ColorMinePortable" Version="2.0.4" />
<PackageReference Include="Config.Net" Version="5.1.4" />
<PackageReference Include="FluentMigrator" Version="3.3.2" />
<PackageReference Include="FluentMigrator.Runner" Version="3.3.2" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using LinqToDB;
using LinqToDB.Data;

namespace EvoSC.Common.Interfaces.Database;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,6 @@ public interface IServiceContainerManager
/// <param name="moduleId">The ID of the module that requires the dependency.</param>
/// <param name="dependencyId">The ID of the dependency.</param>
public void RegisterDependency(Guid moduleId, Guid dependencyId);

public Container GetContainer(Guid moduleId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using EvoSC.Common.Themes;

namespace EvoSC.Common.Interfaces.Themes.Builders;

public interface IReplaceComponentBuilder<out TTheme>
where TTheme : Theme<TTheme>
{
/// <summary>
/// Replace a component with the provided component.
/// </summary>
/// <param name="newComponent">Name of the new component that will replace the old component.</param>
/// <returns></returns>
public TTheme With(string newComponent);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using EvoSC.Common.Themes;

namespace EvoSC.Common.Interfaces.Themes.Builders;

public interface ISetThemeOptionBuilder<TTheme> where TTheme : Theme<TTheme>
{
/// <summary>
/// Set a theme option value.
/// </summary>
/// <param name="value">Value of the theme option.</param>
/// <returns></returns>
public TTheme To(object value);
}
Loading

0 comments on commit e072604

Please sign in to comment.