diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs
index 4deea1f6648..cda125a39cb 100644
--- a/Flow.Launcher.Core/Resource/Theme.cs
+++ b/Flow.Launcher.Core/Resource/Theme.cs
@@ -12,7 +12,6 @@
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
-using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Plugin;
namespace Flow.Launcher.Core.Resource
@@ -35,6 +34,8 @@ public class Theme
private string DirectoryPath => Path.Combine(Constant.ProgramDirectory, Folder);
private string UserDirectoryPath => Path.Combine(DataLocation.DataDirectory(), Folder);
+ public string CurrentTheme => _settings.Theme;
+
public bool BlurEnabled { get; set; }
private double mainWindowWidth;
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj b/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj
index dbc36ad424b..266c2417008 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj
@@ -39,6 +39,7 @@
+
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Images/theme_selector.png b/Plugins/Flow.Launcher.Plugin.Sys/Images/theme_selector.png
new file mode 100644
index 00000000000..704e9474eb2
Binary files /dev/null and b/Plugins/Flow.Launcher.Plugin.Sys/Images/theme_selector.png differ
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml
index 91f32a844f8..2a266f8f651 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Languages/en.xaml
@@ -27,6 +27,7 @@
Flow Launcher Tips
Flow Launcher UserData Folder
Toggle Game Mode
+ Set the Flow Launcher Theme
Shutdown Computer
@@ -49,8 +50,9 @@
Visit Flow Launcher's documentation for more help and how to use tips
Open the location where Flow Launcher's settings are stored
Toggle Game Mode
+ Quickly change the Flow Launcher theme
-
+
Success
All Flow Launcher settings saved
Reloaded all applicable plugin data
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
index 2331ee68c05..28747cc7cf1 100644
--- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs
@@ -7,7 +7,6 @@
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
-using Flow.Launcher.Plugin.SharedCommands;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.Security;
@@ -20,6 +19,7 @@ namespace Flow.Launcher.Plugin.Sys
public class Main : IPlugin, ISettingProvider, IPluginI18n
{
private PluginInitContext context;
+ private ThemeSelector themeSelector;
private Dictionary KeywordTitleMappings = new Dictionary();
// SHTDN_REASON_MAJOR_OTHER indicates a generic shutdown reason that isn't categorized under hardware failure, software updates, or other predefined reasons.
@@ -34,6 +34,11 @@ public Control CreateSettingPanel()
public List Query(Query query)
{
+ if(query.Search.StartsWith(ThemeSelector.Keyword))
+ {
+ return themeSelector.Query(query);
+ }
+
var commands = Commands();
var results = new List();
foreach (var c in commands)
@@ -82,6 +87,7 @@ private string GetDynamicTitle(Query query, Result result)
public void Init(PluginInitContext context)
{
this.context = context;
+ themeSelector = new ThemeSelector(context);
KeywordTitleMappings = new Dictionary{
{"Shutdown", "flowlauncher_plugin_sys_shutdown_computer_cmd"},
{"Restart", "flowlauncher_plugin_sys_restart_computer_cmd"},
@@ -102,7 +108,8 @@ public void Init(PluginInitContext context)
{"Open Log Location", "flowlauncher_plugin_sys_open_log_location_cmd"},
{"Flow Launcher Tips", "flowlauncher_plugin_sys_open_docs_tips_cmd"},
{"Flow Launcher UserData Folder", "flowlauncher_plugin_sys_open_userdata_location_cmd"},
- {"Toggle Game Mode", "flowlauncher_plugin_sys_toggle_game_mode_cmd"}
+ {"Toggle Game Mode", "flowlauncher_plugin_sys_toggle_game_mode_cmd"},
+ {"Set Flow Launcher Theme", "flowlauncher_plugin_sys_theme_selector_cmd"}
};
}
@@ -451,6 +458,18 @@ private List Commands()
context.API.ToggleGameMode();
return true;
}
+ },
+ new Result
+ {
+ Title = "Set Flow Launcher Theme",
+ SubTitle = context.API.GetTranslation("flowlauncher_plugin_sys_theme_selector"),
+ IcoPath = "Images\\app.png",
+ Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\ue7fc"),
+ Action = c =>
+ {
+ context.API.ChangeQuery($"{ThemeSelector.Keyword} ");
+ return false;
+ }
}
});
diff --git a/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
new file mode 100644
index 00000000000..38619cbbc2c
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs
@@ -0,0 +1,115 @@
+using System.Collections.Generic;
+using System.Linq;
+using CommunityToolkit.Mvvm.DependencyInjection;
+using Flow.Launcher.Core.Resource;
+using Flow.Launcher.Infrastructure.UserSettings;
+
+namespace Flow.Launcher.Plugin.Sys
+{
+ public class ThemeSelector
+ {
+ public const string Keyword = "fltheme";
+
+ private readonly Settings _settings;
+ private readonly Theme _theme;
+ private readonly PluginInitContext _context;
+
+ #region Theme Selection
+
+ // Theme select codes simplified from SettingsPaneThemeViewModel.cs
+
+ private Theme.ThemeData _selectedTheme;
+ private Theme.ThemeData SelectedTheme
+ {
+ get => _selectedTheme ??= Themes.Find(v => v.FileNameWithoutExtension == _theme.CurrentTheme);
+ set
+ {
+ _selectedTheme = value;
+ _theme.ChangeTheme(value.FileNameWithoutExtension);
+
+ if (_theme.BlurEnabled && _settings.UseDropShadowEffect)
+ {
+ _theme.RemoveDropShadowEffectFromCurrentTheme();
+ _settings.UseDropShadowEffect = false;
+ }
+ }
+ }
+
+ private List Themes => _theme.LoadAvailableThemes();
+
+ #endregion
+
+ public ThemeSelector(PluginInitContext context)
+ {
+ _context = context;
+ _theme = Ioc.Default.GetRequiredService();
+ _settings = Ioc.Default.GetRequiredService();
+ }
+
+ public List Query(Query query)
+ {
+ var search = query.SecondToEndSearch;
+ if (string.IsNullOrWhiteSpace(search))
+ {
+ return Themes.Select(CreateThemeResult)
+ .OrderBy(x => x.Title)
+ .ToList();
+ }
+
+ return Themes.Select(theme => (theme, matchResult: _context.API.FuzzySearch(search, theme.Name)))
+ .Where(x => x.matchResult.IsSearchPrecisionScoreMet())
+ .Select(x => CreateThemeResult(x.theme, x.matchResult.Score, x.matchResult.MatchData))
+ .OrderBy(x => x.Title)
+ .ToList();
+ }
+
+ private Result CreateThemeResult(Theme.ThemeData theme) => CreateThemeResult(theme, 0, null);
+
+ private Result CreateThemeResult(Theme.ThemeData theme, int score, IList highlightData)
+ {
+ string themeName = theme.Name;
+ string title;
+ if (theme == SelectedTheme)
+ {
+ title = $"{theme.Name} ★";
+ // Set current theme to the top
+ score = 2000;
+ }
+ else
+ {
+ title = theme.Name;
+ // Set them to 1000 so that they are higher than other non-theme records
+ score = 1000;
+ }
+
+ string description = string.Empty;
+ if (theme.IsDark == true)
+ {
+ description += _context.API.GetTranslation("TypeIsDarkToolTip");
+ }
+
+ if (theme.HasBlur == true)
+ {
+ if (!string.IsNullOrEmpty(description))
+ description += " ";
+ description += _context.API.GetTranslation("TypeHasBlurToolTip");
+ }
+
+ return new Result
+ {
+ Title = title,
+ TitleHighlightData = highlightData,
+ SubTitle = description,
+ IcoPath = "Images\\theme_selector.png",
+ Glyph = new GlyphInfo("/Resources/#Segoe Fluent Icons", "\ue790"),
+ Score = score,
+ Action = c =>
+ {
+ SelectedTheme = theme;
+ _context.API.ReQuery();
+ return false;
+ }
+ };
+ }
+ }
+}