From 1539fc6ed3f623064008aa3a55e4b532045384ba Mon Sep 17 00:00:00 2001 From: Isaac Daly Date: Tue, 17 Sep 2024 23:19:24 +1000 Subject: [PATCH] LayoutPreviewPlugin YAML config (#1029) Added a declarative config for the LayoutPreviewPlugin. --- docs/docs/customize/yaml.md | 12 ++ .../YamlLoader_LoadFocusIndicatorTests.cs | 2 +- .../YamlLoader_LoadLayoutPreviewTests.cs | 114 ++++++++++++++++++ src/Whim.Yaml/Whim.Yaml.csproj | 1 + src/Whim.Yaml/YamlPluginLoader.cs | 21 ++++ src/Whim.Yaml/schema.json | 18 +++ 6 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 src/Whim.Yaml.Tests/YamlLoader_LoadLayoutPreviewTests.cs diff --git a/docs/docs/customize/yaml.md b/docs/docs/customize/yaml.md index 786f550f7..8f3c29d4d 100644 --- a/docs/docs/customize/yaml.md +++ b/docs/docs/customize/yaml.md @@ -445,3 +445,15 @@ The color can be any valid RGB or RGBA hex color. The following named colors are | `white_smoke` | `#FFF5F5F5` | | | `yellow` | `#FFFFFF00` | | | `yellow_green` | `#FF9ACD32` | | + +### Layout Preview Plugin + +The `LayoutPreviewPlugin` adds a layout preview to Whim. + +![Layout preview demo](../../images/layout-preview-demo.gif) + +```yaml +plugins: + layout_preview: + is_enabled: true +``` diff --git a/src/Whim.Yaml.Tests/YamlLoader_LoadFocusIndicatorTests.cs b/src/Whim.Yaml.Tests/YamlLoader_LoadFocusIndicatorTests.cs index 855bad6bd..525afbb02 100644 --- a/src/Whim.Yaml.Tests/YamlLoader_LoadFocusIndicatorTests.cs +++ b/src/Whim.Yaml.Tests/YamlLoader_LoadFocusIndicatorTests.cs @@ -188,7 +188,7 @@ IContext ctx } public static TheoryData DisabledFocusIndicatorConfig => - new TheoryData() + new() { // YAML, is_enabled set to false { diff --git a/src/Whim.Yaml.Tests/YamlLoader_LoadLayoutPreviewTests.cs b/src/Whim.Yaml.Tests/YamlLoader_LoadLayoutPreviewTests.cs new file mode 100644 index 000000000..388806347 --- /dev/null +++ b/src/Whim.Yaml.Tests/YamlLoader_LoadLayoutPreviewTests.cs @@ -0,0 +1,114 @@ +using NSubstitute; +using Whim.LayoutPreview; +using Whim.TestUtils; +using Xunit; + +namespace Whim.Yaml.Tests; + +public class YamlLoader_LoadLayoutPreviewTests +{ + public static TheoryData LayoutPreviewConfig => + new() + { + // YAML, enabled' + { + """ + plugins: + layout_preview: + is_enabled: true + """, + true, + true + }, + // JSON, enabled + { + """ + { + "plugins": { + "layout_preview": { + "is_enabled": true + } + } + } + """, + false, + true + }, + // YAML, no values set + { + """ + plugins: + layout_preview: {} + """, + true, + false + }, + // JSON, no values set + { + """ + { + "plugins": { + "layout_preview": {} + } + } + """, + false, + false + }, + }; + + [Theory, MemberAutoSubstituteData(nameof(LayoutPreviewConfig))] + public void LoadLayoutPreviewPlugin(string yaml, bool isYaml, bool isEnabled, IContext ctx) + { + // Given a a YAML config with the layout preview plugin + YamlLoaderTestUtils.SetupFileConfig(ctx, yaml, isYaml); + + // When loading the config + bool result = YamlLoader.Load(ctx); + + // Then the result is true, and the layout preview plugin is set + Assert.True(result); + ctx.PluginManager.Received().AddPlugin(Arg.Any()); + } + + public static TheoryData DisabledLayoutPreviewConfig => + new() + { + // YAML + { + """ + plugins: + layout_preview: + is_enabled: false + """, + true + }, + // JSON + { + """ + { + "plugins": { + "layout_preview": { + "is_enabled": false + } + } + } + """, + false + }, + }; + + [Theory, MemberAutoSubstituteData(nameof(DisabledLayoutPreviewConfig))] + public void LoadLayoutPreviewPlugin_ConfigIsNotEnabled_PluginIsNotLoaded(string schema, bool isYaml, IContext ctx) + { + // Given a valid config with the layout preview plugin not enabled + YamlLoaderTestUtils.SetupFileConfig(ctx, schema, isYaml); + + // When loading the config + bool result = YamlLoader.Load(ctx); + + // Then the result is true, and the layout preview plugin is not set + Assert.True(result); + ctx.PluginManager.DidNotReceive().AddPlugin(Arg.Any()); + } +} diff --git a/src/Whim.Yaml/Whim.Yaml.csproj b/src/Whim.Yaml/Whim.Yaml.csproj index 8ca879321..439643985 100644 --- a/src/Whim.Yaml/Whim.Yaml.csproj +++ b/src/Whim.Yaml/Whim.Yaml.csproj @@ -33,6 +33,7 @@ + diff --git a/src/Whim.Yaml/YamlPluginLoader.cs b/src/Whim.Yaml/YamlPluginLoader.cs index 58e9e8fa3..78598669a 100644 --- a/src/Whim.Yaml/YamlPluginLoader.cs +++ b/src/Whim.Yaml/YamlPluginLoader.cs @@ -4,6 +4,7 @@ using Whim.CommandPalette; using Whim.FocusIndicator; using Whim.Gaps; +using Whim.LayoutPreview; namespace Whim.Yaml; @@ -22,6 +23,7 @@ public static void LoadPlugins(IContext ctx, Schema schema) LoadGapsPlugin(ctx, schema); LoadCommandPalettePlugin(ctx, schema); LoadFocusIndicatorPlugin(ctx, schema); + LoadLayoutPreviewPlugin(ctx, schema); } private static void LoadGapsPlugin(IContext ctx, Schema schema) @@ -150,4 +152,23 @@ private static void LoadFocusIndicatorPlugin(IContext ctx, Schema schema) ctx.PluginManager.AddPlugin(new FocusIndicatorPlugin(ctx, config)); } + + private static void LoadLayoutPreviewPlugin(IContext ctx, Schema schema) + { + var layoutPreview = schema.Plugins.LayoutPreview; + + if (!layoutPreview.IsValid()) + { + Logger.Debug("LayoutPreview plugin is not valid."); + return; + } + + if (layoutPreview.IsEnabled.AsOptional() is { } isEnabled && !isEnabled) + { + Logger.Debug("LayoutPreview plugin is not enabled."); + return; + } + + ctx.PluginManager.AddPlugin(new LayoutPreviewPlugin(ctx)); + } } diff --git a/src/Whim.Yaml/schema.json b/src/Whim.Yaml/schema.json index 528976606..d35a3468a 100644 --- a/src/Whim.Yaml/schema.json +++ b/src/Whim.Yaml/schema.json @@ -66,6 +66,11 @@ "focus_indicator": { "$ref": "#/$defs/FocusIndicatorPlugin", "description": "Plugin to add a focus indicator" + }, + + "layout_preview": { + "$ref": "#/$defs/LayoutPreviewPlugin", + "description": "Plugin to add a layout preview" } } } @@ -306,6 +311,19 @@ } }, + "LayoutPreviewPlugin": { + "type": "object", + "description": "Plugin to add a layout preview. For more, see https://dalyisaac.github.io/Whim/docs/plugins/layout-preview.html", + "additionalProperties": false, + "properties": { + "is_enabled": { + "type": "boolean", + "description": "Whether the plugin is enabled", + "default": true + } + } + }, + "Color": { "anyOf": [ {