From e376da44820f3ac69602cce1f5e66c5c920af1b2 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 2 Oct 2025 19:29:46 +0800 Subject: [PATCH 1/5] Save settings before shutdown/restart to prevent data loss Added a call to `Context.API.SaveAppAllSettings()` before executing system shutdown, restart, or advanced restart operations. This ensures that any unsaved settings are persisted, reducing the risk of data loss during these actions. --- Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs index 89067d44c..d0eb339fe 100644 --- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs @@ -211,6 +211,9 @@ namespace Flow.Launcher.Plugin.Sys Localize.flowlauncher_plugin_sys_shutdown_computer(), MessageBoxButton.YesNo, MessageBoxImage.Warning); + // Save settings before shutdown to avoid data loss + Context.API.SaveAppAllSettings(); + if (result == MessageBoxResult.Yes) if (EnableShutdownPrivilege()) PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_SHUTDOWN | EXIT_WINDOWS_FLAGS.EWX_POWEROFF, REASON); @@ -232,6 +235,9 @@ namespace Flow.Launcher.Plugin.Sys Localize.flowlauncher_plugin_sys_restart_computer(), MessageBoxButton.YesNo, MessageBoxImage.Warning); + // Save settings before restart to avoid data loss + Context.API.SaveAppAllSettings(); + if (result == MessageBoxResult.Yes) if (EnableShutdownPrivilege()) PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT, REASON); @@ -253,6 +259,9 @@ namespace Flow.Launcher.Plugin.Sys Localize.flowlauncher_plugin_sys_restart_computer(), MessageBoxButton.YesNo, MessageBoxImage.Warning); + // Save settings before restart to avoid data loss + Context.API.SaveAppAllSettings(); + if (result == MessageBoxResult.Yes) if (EnableShutdownPrivilege()) PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT | EXIT_WINDOWS_FLAGS.EWX_BOOTOPTIONS, REASON); From 167570559f82c8c7fa5bf51a5b33a0ca78c7c26d Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 2 Oct 2025 19:42:24 +0800 Subject: [PATCH 2/5] Move settings save to post-confirmation for actions Previously, `Context.API.SaveAppAllSettings()` was called unconditionally before user confirmation for shutdown, restart, and advanced restart actions. This change ensures settings are only saved if the user confirms the action by clicking "Yes" in the confirmation dialog. For all three functionalities: - Moved the settings save call inside the `if (result == MessageBoxResult.Yes)` block. - Retained the existing logic for executing the respective system commands, with checks for `EnableShutdownPrivilege()` to determine whether to use `PInvoke.ExitWindowsEx` or the `shutdown` command. This change prevents unnecessary settings saves when the user cancels the action. --- Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 30 ++++++++++++------------ 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs index d0eb339fe..b53c0261b 100644 --- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs @@ -210,16 +210,16 @@ namespace Flow.Launcher.Plugin.Sys Localize.flowlauncher_plugin_sys_dlgtext_shutdown_computer(), Localize.flowlauncher_plugin_sys_shutdown_computer(), MessageBoxButton.YesNo, MessageBoxImage.Warning); - - // Save settings before shutdown to avoid data loss - Context.API.SaveAppAllSettings(); - if (result == MessageBoxResult.Yes) + { + // Save settings before shutdown to avoid data loss + Context.API.SaveAppAllSettings(); + if (EnableShutdownPrivilege()) PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_SHUTDOWN | EXIT_WINDOWS_FLAGS.EWX_POWEROFF, REASON); else Process.Start("shutdown", "/s /t 0"); - + } return true; } }, @@ -234,16 +234,16 @@ namespace Flow.Launcher.Plugin.Sys Localize.flowlauncher_plugin_sys_dlgtext_restart_computer(), Localize.flowlauncher_plugin_sys_restart_computer(), MessageBoxButton.YesNo, MessageBoxImage.Warning); - - // Save settings before restart to avoid data loss - Context.API.SaveAppAllSettings(); - if (result == MessageBoxResult.Yes) + { + // Save settings before restart to avoid data loss + Context.API.SaveAppAllSettings(); + if (EnableShutdownPrivilege()) PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT, REASON); else Process.Start("shutdown", "/r /t 0"); - + } return true; } }, @@ -258,16 +258,16 @@ namespace Flow.Launcher.Plugin.Sys Localize.flowlauncher_plugin_sys_dlgtext_restart_computer_advanced(), Localize.flowlauncher_plugin_sys_restart_computer(), MessageBoxButton.YesNo, MessageBoxImage.Warning); - - // Save settings before restart to avoid data loss - Context.API.SaveAppAllSettings(); - if (result == MessageBoxResult.Yes) + { + // Save settings before restart to avoid data loss + Context.API.SaveAppAllSettings(); + if (EnableShutdownPrivilege()) PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_REBOOT | EXIT_WINDOWS_FLAGS.EWX_BOOTOPTIONS, REASON); else Process.Start("shutdown", "/r /o /t 0"); - + } return true; } }, From d08ee30a7a17c23f481302dad350ff7c042eb42e Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Thu, 2 Oct 2025 19:43:31 +0800 Subject: [PATCH 3/5] Refactor plugin actions to simplify logic Removed logoff operation logic and associated return statement. Eliminated return statement after recycle bin error handling. Removed async plugin data reload and success message logic. Simplified theme selector query handling by removing `return false`. These changes streamline the code and improve maintainability. --- Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs index b53c0261b..cb3acf77f 100644 --- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs @@ -282,10 +282,8 @@ namespace Flow.Launcher.Plugin.Sys Localize.flowlauncher_plugin_sys_dlgtext_logoff_computer(), Localize.flowlauncher_plugin_sys_log_off(), MessageBoxButton.YesNo, MessageBoxImage.Warning); - if (result == MessageBoxResult.Yes) PInvoke.ExitWindowsEx(EXIT_WINDOWS_FLAGS.EWX_LOGOFF, REASON); - return true; } }, @@ -351,7 +349,6 @@ namespace Flow.Launcher.Plugin.Sys Localize.flowlauncher_plugin_sys_dlgtitle_error(), MessageBoxButton.OK, MessageBoxImage.Error); } - return true; } }, @@ -425,13 +422,11 @@ namespace Flow.Launcher.Plugin.Sys { // Hide the window first then show msg after done because sometimes the reload could take a while, so not to make user think it's frozen. Context.API.HideMainWindow(); - _ = Context.API.ReloadAllPluginData().ContinueWith(_ => Context.API.ShowMsg( Localize.flowlauncher_plugin_sys_dlgtitle_success(), Localize.flowlauncher_plugin_sys_dlgtext_all_applicableplugins_reloaded()), TaskScheduler.Current); - return true; } }, @@ -511,7 +506,6 @@ namespace Flow.Launcher.Plugin.Sys else { Context.API.ChangeQuery($"{query.ActionKeyword}{Plugin.Query.ActionKeywordSeparator}{ThemeSelector.Keyword}{Plugin.Query.ActionKeywordSeparator}"); - } return false; } From 5b0a30774e711fececa2088316657cc9338e01c8 Mon Sep 17 00:00:00 2001 From: Jack Ye Date: Thu, 2 Oct 2025 19:45:08 +0800 Subject: [PATCH 4/5] Fix code comment typo Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- Plugins/Flow.Launcher.Plugin.Sys/Main.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs index cb3acf77f..57b9749f7 100644 --- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs @@ -260,7 +260,7 @@ namespace Flow.Launcher.Plugin.Sys MessageBoxButton.YesNo, MessageBoxImage.Warning); if (result == MessageBoxResult.Yes) { - // Save settings before restart to avoid data loss + // Save settings before advanced restart to avoid data loss Context.API.SaveAppAllSettings(); if (EnableShutdownPrivilege()) From 5ae159de5b69950df4f82b413ba91f4860f43f35 Mon Sep 17 00:00:00 2001 From: Jack Ye Date: Sun, 5 Oct 2025 18:44:40 +0800 Subject: [PATCH 5/5] Move to iNKORE.UI.WPF.Modern UI Framework (#3593) --- .../Resource/LocalizedDescriptionAttribute.cs | 24 - Flow.Launcher.Core/Resource/Theme.cs | 14 +- Flow.Launcher/App.xaml | 18 +- Flow.Launcher/App.xaml.cs | 4 + .../BoolToIMEConversionModeConverter.cs | 4 +- .../Converters/CornerRadiusFilterConverter.cs | 91 + .../Converters/PlacementRectangleConverter.cs | 32 + .../Converters/SharedSizeGroupConverter.cs | 19 + .../Converters/StringToKeyBindingConverter.cs | 2 +- Flow.Launcher/Flow.Launcher.csproj | 4 +- Flow.Launcher/Helper/BorderHelper.cs | 33 + Flow.Launcher/HotkeyControlDialog.xaml | 2 +- Flow.Launcher/HotkeyControlDialog.xaml.cs | 2 +- Flow.Launcher/MainWindow.xaml | 2 +- Flow.Launcher/MainWindow.xaml.cs | 7 +- Flow.Launcher/PluginUpdateWindow.xaml | 5 +- Flow.Launcher/PublicAPIInstance.cs | 2 +- Flow.Launcher/ReleaseNotesWindow.xaml | 24 +- Flow.Launcher/ReleaseNotesWindow.xaml.cs | 13 +- Flow.Launcher/Resources/Controls/Card.xaml | 139 - Flow.Launcher/Resources/Controls/Card.xaml.cs | 67 - .../Resources/Controls/CardGroup.xaml | 32 - .../Resources/Controls/CardGroup.xaml.cs | 47 - .../Controls/CardGroupCardStyleSelector.cs | 21 - .../Controls/CustomScrollViewerEx.cs | 253 ++ Flow.Launcher/Resources/Controls/ExCard.xaml | 312 -- .../Resources/Controls/ExCard.xaml.cs | 57 - .../Resources/Controls/HyperLink.xaml | 14 - .../Resources/Controls/HyperLink.xaml.cs | 39 - Flow.Launcher/Resources/Controls/InfoBar.xaml | 81 - .../Resources/Controls/InfoBar.xaml.cs | 222 - .../Controls/InstalledPluginDisplay.xaml | 4 +- .../Controls/InstalledPluginDisplay.xaml.cs | 2 +- .../Resources/CustomControlTemplate.xaml | 3811 +++-------------- Flow.Launcher/Resources/Dark.xaml | 1549 +------ Flow.Launcher/Resources/Light.xaml | 1552 +------ .../Resources/Pages/WelcomePage1.xaml | 11 +- .../Resources/Pages/WelcomePage2.xaml | 17 +- .../Resources/Pages/WelcomePage3.xaml | 153 +- .../Resources/Pages/WelcomePage4.xaml | 9 +- .../Resources/Pages/WelcomePage5.xaml | 13 +- .../Resources/SettingWindowStyle.xaml | 435 +- Flow.Launcher/ResultListBox.xaml | 1 + Flow.Launcher/SelectBrowserWindow.xaml | 2 +- Flow.Launcher/SelectFileManagerWindow.xaml | 6 +- Flow.Launcher/SelectFileManagerWindow.xaml.cs | 6 - .../ViewModels/SettingsPaneAboutViewModel.cs | 6 + .../SettingsPanePluginsViewModel.cs | 2 +- .../ViewModels/SettingsPaneThemeViewModel.cs | 13 +- .../SettingPages/Views/SettingsPaneAbout.xaml | 180 +- .../Views/SettingsPaneAbout.xaml.cs | 6 - .../Views/SettingsPaneGeneral.xaml | 725 ++-- .../Views/SettingsPaneHotkey.xaml | 736 ++-- .../Views/SettingsPanePluginStore.xaml | 102 +- .../Views/SettingsPanePlugins.xaml | 55 +- .../SettingPages/Views/SettingsPaneProxy.xaml | 77 +- .../SettingPages/Views/SettingsPaneTheme.xaml | 666 +-- Flow.Launcher/SettingWindow.xaml | 5 +- Flow.Launcher/SettingWindow.xaml.cs | 9 +- Flow.Launcher/Themes/Base.xaml | 23 +- Flow.Launcher/Themes/BlurWhite.xaml | 2 +- Flow.Launcher/Themes/Circle System.xaml | 2 +- Flow.Launcher/Themes/Cyan Dark.xaml | 12 +- Flow.Launcher/Themes/Dracula.xaml | 6 +- Flow.Launcher/Themes/Gray.xaml | 8 +- Flow.Launcher/Themes/Sublime.xaml | 6 +- Flow.Launcher/Themes/Win10System.xaml | 2 +- Flow.Launcher/Themes/Win11Light.xaml | 2 +- Flow.Launcher/ViewModel/MainViewModel.cs | 2 +- Flow.Launcher/WelcomeWindow.xaml | 7 +- Flow.Launcher/WelcomeWindow.xaml.cs | 2 +- Flow.Launcher/packages.lock.json | 20 +- .../Views/ExplorerSettings.xaml | 15 +- .../ProgramSuffixes.xaml | 2 +- .../SettingsControl.xaml | 42 +- .../SettingsControl.xaml.cs | 23 + README.md | 14 +- 77 files changed, 2846 insertions(+), 9083 deletions(-) delete mode 100644 Flow.Launcher.Core/Resource/LocalizedDescriptionAttribute.cs create mode 100644 Flow.Launcher/Converters/CornerRadiusFilterConverter.cs create mode 100644 Flow.Launcher/Converters/PlacementRectangleConverter.cs create mode 100644 Flow.Launcher/Converters/SharedSizeGroupConverter.cs create mode 100644 Flow.Launcher/Helper/BorderHelper.cs delete mode 100644 Flow.Launcher/Resources/Controls/Card.xaml delete mode 100644 Flow.Launcher/Resources/Controls/Card.xaml.cs delete mode 100644 Flow.Launcher/Resources/Controls/CardGroup.xaml delete mode 100644 Flow.Launcher/Resources/Controls/CardGroup.xaml.cs delete mode 100644 Flow.Launcher/Resources/Controls/CardGroupCardStyleSelector.cs create mode 100644 Flow.Launcher/Resources/Controls/CustomScrollViewerEx.cs delete mode 100644 Flow.Launcher/Resources/Controls/ExCard.xaml delete mode 100644 Flow.Launcher/Resources/Controls/ExCard.xaml.cs delete mode 100644 Flow.Launcher/Resources/Controls/HyperLink.xaml delete mode 100644 Flow.Launcher/Resources/Controls/HyperLink.xaml.cs delete mode 100644 Flow.Launcher/Resources/Controls/InfoBar.xaml delete mode 100644 Flow.Launcher/Resources/Controls/InfoBar.xaml.cs diff --git a/Flow.Launcher.Core/Resource/LocalizedDescriptionAttribute.cs b/Flow.Launcher.Core/Resource/LocalizedDescriptionAttribute.cs deleted file mode 100644 index acd9d9eb7..000000000 --- a/Flow.Launcher.Core/Resource/LocalizedDescriptionAttribute.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.ComponentModel; - -namespace Flow.Launcher.Core.Resource -{ - public class LocalizedDescriptionAttribute : DescriptionAttribute - { - private readonly string _resourceKey; - - public LocalizedDescriptionAttribute(string resourceKey) - { - _resourceKey = resourceKey; - } - - public override string Description - { - get - { - string description = PublicApi.Instance.GetTranslation(_resourceKey); - return string.IsNullOrWhiteSpace(description) ? - string.Format("[[{0}]]", _resourceKey) : description; - } - } - } -} diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs index d1f7da2a2..c3bb6190f 100644 --- a/Flow.Launcher.Core/Resource/Theme.cs +++ b/Flow.Launcher.Core/Resource/Theme.cs @@ -449,9 +449,19 @@ namespace Flow.Launcher.Core.Resource } return false; } - catch (XamlParseException) + catch (XamlParseException e) { - _api.LogError(ClassName, $"Theme <{theme}> fail to parse"); + _api.LogException(ClassName, $"Theme <{theme}> fail to parse xaml", e); + if (theme != Constant.DefaultTheme) + { + _api.ShowMsgBox(Localize.theme_load_failure_parse_error(theme)); + ChangeTheme(Constant.DefaultTheme); + } + return false; + } + catch (Exception e) + { + _api.LogException(ClassName, $"Theme <{theme}> fail to load", e); if (theme != Constant.DefaultTheme) { _api.ShowMsgBox(Localize.theme_load_failure_parse_error(theme)); diff --git a/Flow.Launcher/App.xaml b/Flow.Launcher/App.xaml index 565bbe3c7..e922cd558 100644 --- a/Flow.Launcher/App.xaml +++ b/Flow.Launcher/App.xaml @@ -2,7 +2,8 @@ x:Class="Flow.Launcher.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - xmlns:ui="http://schemas.modernwpf.com/2019" + xmlns:sys="clr-namespace:System;assembly=mscorlib" + xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern" ShutdownMode="OnMainWindowClose" Startup="OnStartup"> @@ -10,17 +11,17 @@ - + - + - + @@ -33,6 +34,15 @@ + + + 2 + 0 + 0 + 40 + 0 + 36 + \ No newline at end of file diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs index 58f8438d2..1ca3ce2c6 100644 --- a/Flow.Launcher/App.xaml.cs +++ b/Flow.Launcher/App.xaml.cs @@ -22,6 +22,7 @@ using Flow.Launcher.Infrastructure.UserSettings; using Flow.Launcher.Plugin; using Flow.Launcher.SettingPages.ViewModels; using Flow.Launcher.ViewModel; +using iNKORE.UI.WPF.Modern.Common; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.VisualStudio.Threading; @@ -56,6 +57,9 @@ namespace Flow.Launcher public App() { + // Do not use bitmap cache since it can cause WPF second window freezing issue + ShadowAssist.UseBitmapCache = false; + // Initialize settings _settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled(); diff --git a/Flow.Launcher/Converters/BoolToIMEConversionModeConverter.cs b/Flow.Launcher/Converters/BoolToIMEConversionModeConverter.cs index 41e879913..82da6d936 100644 --- a/Flow.Launcher/Converters/BoolToIMEConversionModeConverter.cs +++ b/Flow.Launcher/Converters/BoolToIMEConversionModeConverter.cs @@ -5,7 +5,7 @@ using System.Windows.Input; namespace Flow.Launcher.Converters; -internal class BoolToIMEConversionModeConverter : IValueConverter +public class BoolToIMEConversionModeConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { @@ -22,7 +22,7 @@ internal class BoolToIMEConversionModeConverter : IValueConverter } } -internal class BoolToIMEStateConverter : IValueConverter +public class BoolToIMEStateConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { diff --git a/Flow.Launcher/Converters/CornerRadiusFilterConverter.cs b/Flow.Launcher/Converters/CornerRadiusFilterConverter.cs new file mode 100644 index 000000000..fd43cafac --- /dev/null +++ b/Flow.Launcher/Converters/CornerRadiusFilterConverter.cs @@ -0,0 +1,91 @@ +using System; +using System.Globalization; +using System.Windows; +using System.Windows.Data; + +namespace Flow.Launcher.Converters; + +public class CornerRadiusFilterConverter : DependencyObject, IValueConverter +{ + public CornerRadiusFilterKind Filter { get; set; } + + public double Scale { get; set; } = 1.0; + + public static CornerRadius Convert(CornerRadius radius, CornerRadiusFilterKind filterKind) + { + CornerRadius result = radius; + + switch (filterKind) + { + case CornerRadiusFilterKind.Top: + result.BottomLeft = 0; + result.BottomRight = 0; + break; + case CornerRadiusFilterKind.Right: + result.TopLeft = 0; + result.BottomLeft = 0; + break; + case CornerRadiusFilterKind.Bottom: + result.TopLeft = 0; + result.TopRight = 0; + break; + case CornerRadiusFilterKind.Left: + result.TopRight = 0; + result.BottomRight = 0; + break; + } + + return result; + } + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + var cornerRadius = (CornerRadius)value; + + var scale = Scale; + if (!double.IsNaN(scale)) + { + cornerRadius.TopLeft *= scale; + cornerRadius.TopRight *= scale; + cornerRadius.BottomRight *= scale; + cornerRadius.BottomLeft *= scale; + } + + var filterType = Filter; + if (filterType == CornerRadiusFilterKind.TopLeftValue || + filterType == CornerRadiusFilterKind.BottomRightValue) + { + return GetDoubleValue(cornerRadius, filterType); + } + + return Convert(cornerRadius, filterType); + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + + private static double GetDoubleValue(CornerRadius radius, CornerRadiusFilterKind filterKind) + { + switch (filterKind) + { + case CornerRadiusFilterKind.TopLeftValue: + return radius.TopLeft; + case CornerRadiusFilterKind.BottomRightValue: + return radius.BottomRight; + } + return 0; + } +} + +public enum CornerRadiusFilterKind +{ + None, + Top, + Right, + Bottom, + Left, + TopLeftValue, + BottomRightValue +} diff --git a/Flow.Launcher/Converters/PlacementRectangleConverter.cs b/Flow.Launcher/Converters/PlacementRectangleConverter.cs new file mode 100644 index 000000000..130d04e16 --- /dev/null +++ b/Flow.Launcher/Converters/PlacementRectangleConverter.cs @@ -0,0 +1,32 @@ +using System; +using System.Globalization; +using System.Windows; +using System.Windows.Data; + +namespace Flow.Launcher.Converters; + +public class PlacementRectangleConverter : IMultiValueConverter +{ + public Thickness Margin { get; set; } + + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + if (values.Length == 2 && + values[0] is double width && + values[1] is double height) + { + var margin = Margin; + var topLeft = new Point(margin.Left, margin.Top); + var bottomRight = new Point(width - margin.Right, height - margin.Bottom); + var rect = new Rect(topLeft, bottomRight); + return rect; + } + + return Rect.Empty; + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } +} diff --git a/Flow.Launcher/Converters/SharedSizeGroupConverter.cs b/Flow.Launcher/Converters/SharedSizeGroupConverter.cs new file mode 100644 index 000000000..594787027 --- /dev/null +++ b/Flow.Launcher/Converters/SharedSizeGroupConverter.cs @@ -0,0 +1,19 @@ +using System; +using System.Globalization; +using System.Windows; +using System.Windows.Data; + +namespace Flow.Launcher.Converters; + +public class SharedSizeGroupConverter : IValueConverter +{ + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + return (Visibility)value != Visibility.Collapsed ? (string)parameter : null; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } +} diff --git a/Flow.Launcher/Converters/StringToKeyBindingConverter.cs b/Flow.Launcher/Converters/StringToKeyBindingConverter.cs index 21bf584e7..b7bca41c5 100644 --- a/Flow.Launcher/Converters/StringToKeyBindingConverter.cs +++ b/Flow.Launcher/Converters/StringToKeyBindingConverter.cs @@ -5,7 +5,7 @@ using System.Windows.Input; namespace Flow.Launcher.Converters; -class StringToKeyBindingConverter : IValueConverter +public class StringToKeyBindingConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj index aa8e95429..8c7670426 100644 --- a/Flow.Launcher/Flow.Launcher.csproj +++ b/Flow.Launcher/Flow.Launcher.csproj @@ -138,6 +138,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + @@ -146,9 +147,6 @@ - - - all diff --git a/Flow.Launcher/Helper/BorderHelper.cs b/Flow.Launcher/Helper/BorderHelper.cs new file mode 100644 index 000000000..0f2a78e7d --- /dev/null +++ b/Flow.Launcher/Helper/BorderHelper.cs @@ -0,0 +1,33 @@ +using System.Windows; +using System.Windows.Controls; + +namespace Flow.Launcher.Helper; + +public static class BorderHelper +{ + #region Child + + public static readonly DependencyProperty ChildProperty = + DependencyProperty.RegisterAttached( + "Child", + typeof(UIElement), + typeof(BorderHelper), + new PropertyMetadata(default(UIElement), OnChildChanged)); + + public static UIElement GetChild(Border border) + { + return (UIElement)border.GetValue(ChildProperty); + } + + public static void SetChild(Border border, UIElement value) + { + border.SetValue(ChildProperty, value); + } + + private static void OnChildChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((Border)d).Child = (UIElement)e.NewValue; + } + + #endregion +} diff --git a/Flow.Launcher/HotkeyControlDialog.xaml b/Flow.Launcher/HotkeyControlDialog.xaml index d416f1bdc..9fdfda865 100644 --- a/Flow.Launcher/HotkeyControlDialog.xaml +++ b/Flow.Launcher/HotkeyControlDialog.xaml @@ -2,7 +2,7 @@ x:Class="Flow.Launcher.HotkeyControlDialog" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - xmlns:ui="http://schemas.modernwpf.com/2019" + xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern" Background="{DynamicResource PopuBGColor}" BorderBrush="{DynamicResource PopupButtonAreaBorderColor}" BorderThickness="0 1 0 0" diff --git a/Flow.Launcher/HotkeyControlDialog.xaml.cs b/Flow.Launcher/HotkeyControlDialog.xaml.cs index 740425f8b..e1fc86f95 100644 --- a/Flow.Launcher/HotkeyControlDialog.xaml.cs +++ b/Flow.Launcher/HotkeyControlDialog.xaml.cs @@ -9,7 +9,7 @@ using Flow.Launcher.Helper; using Flow.Launcher.Infrastructure.Hotkey; using Flow.Launcher.Infrastructure.UserSettings; using Flow.Launcher.Plugin; -using ModernWpf.Controls; +using iNKORE.UI.WPF.Modern.Controls; namespace Flow.Launcher; diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml index 132ec8389..dd47f9d4e 100644 --- a/Flow.Launcher/MainWindow.xaml +++ b/Flow.Launcher/MainWindow.xaml @@ -6,7 +6,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:flowlauncher="clr-namespace:Flow.Launcher" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:ui="http://schemas.modernwpf.com/2019" + xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern" xmlns:vm="clr-namespace:Flow.Launcher.ViewModel" Name="FlowMainWindow" Title="Flow Launcher" diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs index 01a7dc9bd..b2ba33269 100644 --- a/Flow.Launcher/MainWindow.xaml.cs +++ b/Flow.Launcher/MainWindow.xaml.cs @@ -25,7 +25,8 @@ using Flow.Launcher.Plugin; using Flow.Launcher.Plugin.SharedCommands; using Flow.Launcher.Plugin.SharedModels; using Flow.Launcher.ViewModel; -using ModernWpf.Controls; +using iNKORE.UI.WPF.Modern; +using iNKORE.UI.WPF.Modern.Controls; using DataObject = System.Windows.DataObject; using Key = System.Windows.Input.Key; using MouseButtons = System.Windows.Forms.MouseButtons; @@ -191,11 +192,11 @@ namespace Flow.Launcher // Initialize color scheme if (_settings.ColorScheme == Constant.Light) { - ModernWpf.ThemeManager.Current.ApplicationTheme = ModernWpf.ApplicationTheme.Light; + ThemeManager.Current.ApplicationTheme = ApplicationTheme.Light; } else if (_settings.ColorScheme == Constant.Dark) { - ModernWpf.ThemeManager.Current.ApplicationTheme = ModernWpf.ApplicationTheme.Dark; + ThemeManager.Current.ApplicationTheme = ApplicationTheme.Dark; } // Initialize position diff --git a/Flow.Launcher/PluginUpdateWindow.xaml b/Flow.Launcher/PluginUpdateWindow.xaml index 04cd1f7bc..a4bb06431 100644 --- a/Flow.Launcher/PluginUpdateWindow.xaml +++ b/Flow.Launcher/PluginUpdateWindow.xaml @@ -4,6 +4,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:flowlauncher="clr-namespace:Flow.Launcher" + xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern" Title="{DynamicResource updateAllPluginsButtonContent}" Width="530" Background="{DynamicResource PopuBGColor}" @@ -66,13 +67,13 @@ Text="{DynamicResource updateAllPluginsButtonContent}" TextAlignment="Left" /> - - + - + @@ -161,18 +162,23 @@ Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="5" - Margin="18 0 18 0"> - + Margin="6 0 18 0"> + - + Height="500" + Margin="15 0 0 0" + Padding="0 0 15 0" + HorizontalAlignment="Stretch"> @@ -193,11 +199,11 @@ VerticalScrollBarVisibility="Disabled" Visibility="Collapsed" /> - + - + Properties.Settings.Default.GithubRepo + "/releases"; public ReleaseNotesWindow() { InitializeComponent(); - SeeMore.Uri = ReleaseNotes; - ModernWpf.ThemeManager.Current.ActualApplicationThemeChanged += ThemeManager_ActualApplicationThemeChanged; + ThemeManager.Current.ActualApplicationThemeChanged += ThemeManager_ActualApplicationThemeChanged; } #region Window Events - private void ThemeManager_ActualApplicationThemeChanged(ModernWpf.ThemeManager sender, object args) + private void ThemeManager_ActualApplicationThemeChanged(ThemeManager sender, object args) { Application.Current.Dispatcher.Invoke(() => { - if (ModernWpf.ThemeManager.Current.ActualApplicationTheme == ModernWpf.ApplicationTheme.Light) + if (ThemeManager.Current.ActualApplicationTheme == ApplicationTheme.Light) { MarkdownViewer.MarkdownStyle = (Style)Application.Current.Resources["DocumentStyleGithubLikeLight"]; MarkdownViewer.Foreground = Brushes.Black; @@ -58,7 +58,7 @@ namespace Flow.Launcher private void Window_Closed(object sender, EventArgs e) { - ModernWpf.ThemeManager.Current.ActualApplicationThemeChanged -= ThemeManager_ActualApplicationThemeChanged; + ThemeManager.Current.ActualApplicationThemeChanged -= ThemeManager_ActualApplicationThemeChanged; } #endregion @@ -147,7 +147,6 @@ namespace Flow.Launcher private void Grid_SizeChanged(object sender, SizeChangedEventArgs e) { MarkdownScrollViewer.Height = e.NewSize.Height; - MarkdownScrollViewer.Width = e.NewSize.Width; } private void MarkdownViewer_MouseWheel(object sender, MouseWheelEventArgs e) diff --git a/Flow.Launcher/Resources/Controls/Card.xaml b/Flow.Launcher/Resources/Controls/Card.xaml deleted file mode 100644 index e3c5f8194..000000000 --- a/Flow.Launcher/Resources/Controls/Card.xaml +++ /dev/null @@ -1,139 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Flow.Launcher/Resources/Controls/Card.xaml.cs b/Flow.Launcher/Resources/Controls/Card.xaml.cs deleted file mode 100644 index 6a70dded2..000000000 --- a/Flow.Launcher/Resources/Controls/Card.xaml.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System.Windows; -using UserControl = System.Windows.Controls.UserControl; - -namespace Flow.Launcher.Resources.Controls -{ - public partial class Card : UserControl - { - public enum CardType - { - Default, - Inside, - InsideFit, - First, - Middle, - Last - } - - public Card() - { - InitializeComponent(); - } - - public string Title - { - get { return (string)GetValue(TitleProperty); } - set { SetValue(TitleProperty, value); } - } - public static readonly DependencyProperty TitleProperty = - DependencyProperty.Register(nameof(Title), typeof(string), typeof(Card), new PropertyMetadata(string.Empty)); - - public string Sub - { - get { return (string)GetValue(SubProperty); } - set { SetValue(SubProperty, value); } - } - public static readonly DependencyProperty SubProperty = - DependencyProperty.Register(nameof(Sub), typeof(string), typeof(Card), new PropertyMetadata(string.Empty)); - - public string Icon - { - get { return (string)GetValue(IconProperty); } - set { SetValue(IconProperty, value); } - } - public static readonly DependencyProperty IconProperty = - DependencyProperty.Register(nameof(Icon), typeof(string), typeof(Card), new PropertyMetadata(string.Empty)); - - /// - /// Gets or sets additional content for the UserControl - /// - public object AdditionalContent - { - get { return (object)GetValue(AdditionalContentProperty); } - set { SetValue(AdditionalContentProperty, value); } - } - public static readonly DependencyProperty AdditionalContentProperty = - DependencyProperty.Register(nameof(AdditionalContent), typeof(object), typeof(Card), - new PropertyMetadata(null)); - public CardType Type - { - get { return (CardType)GetValue(TypeProperty); } - set { SetValue(TypeProperty, value); } - } - public static readonly DependencyProperty TypeProperty = - DependencyProperty.Register(nameof(Type), typeof(CardType), typeof(Card), - new PropertyMetadata(CardType.Default)); - } -} diff --git a/Flow.Launcher/Resources/Controls/CardGroup.xaml b/Flow.Launcher/Resources/Controls/CardGroup.xaml deleted file mode 100644 index f48bf4b6c..000000000 --- a/Flow.Launcher/Resources/Controls/CardGroup.xaml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - diff --git a/Flow.Launcher/Resources/Controls/CardGroup.xaml.cs b/Flow.Launcher/Resources/Controls/CardGroup.xaml.cs deleted file mode 100644 index b9588275c..000000000 --- a/Flow.Launcher/Resources/Controls/CardGroup.xaml.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Collections.ObjectModel; -using System.Windows; -using System.Windows.Controls; - -namespace Flow.Launcher.Resources.Controls; - -public partial class CardGroup : UserControl -{ - public enum CardGroupPosition - { - NotInGroup, - First, - Middle, - Last - } - - public new ObservableCollection Content - { - get { return (ObservableCollection)GetValue(ContentProperty); } - set { SetValue(ContentProperty, value); } - } - - public static new readonly DependencyProperty ContentProperty = - DependencyProperty.Register(nameof(Content), typeof(ObservableCollection), typeof(CardGroup)); - - public static readonly DependencyProperty PositionProperty = DependencyProperty.RegisterAttached( - "Position", typeof(CardGroupPosition), typeof(CardGroup), - new FrameworkPropertyMetadata(CardGroupPosition.NotInGroup, FrameworkPropertyMetadataOptions.AffectsRender) - ); - - public static void SetPosition(UIElement element, CardGroupPosition value) - { - element.SetValue(PositionProperty, value); - } - - public static CardGroupPosition GetPosition(UIElement element) - { - return (CardGroupPosition)element.GetValue(PositionProperty); - } - - public CardGroup() - { - InitializeComponent(); - Content = new ObservableCollection(); - } -} diff --git a/Flow.Launcher/Resources/Controls/CardGroupCardStyleSelector.cs b/Flow.Launcher/Resources/Controls/CardGroupCardStyleSelector.cs deleted file mode 100644 index 605934e80..000000000 --- a/Flow.Launcher/Resources/Controls/CardGroupCardStyleSelector.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Windows; -using System.Windows.Controls; - -namespace Flow.Launcher.Resources.Controls; - -public class CardGroupCardStyleSelector : StyleSelector -{ - public Style FirstStyle { get; set; } - public Style MiddleStyle { get; set; } - public Style LastStyle { get; set; } - - public override Style SelectStyle(object item, DependencyObject container) - { - var itemsControl = ItemsControl.ItemsControlFromItemContainer(container); - var index = itemsControl.ItemContainerGenerator.IndexFromContainer(container); - - if (index == 0) return FirstStyle; - if (index == itemsControl.Items.Count - 1) return LastStyle; - return MiddleStyle; - } -} diff --git a/Flow.Launcher/Resources/Controls/CustomScrollViewerEx.cs b/Flow.Launcher/Resources/Controls/CustomScrollViewerEx.cs new file mode 100644 index 000000000..78985108c --- /dev/null +++ b/Flow.Launcher/Resources/Controls/CustomScrollViewerEx.cs @@ -0,0 +1,253 @@ +using iNKORE.UI.WPF.Modern.Controls; +using iNKORE.UI.WPF.Modern.Controls.Helpers; +using iNKORE.UI.WPF.Modern.Controls.Primitives; +using System; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; + +namespace Flow.Launcher.Resources.Controls +{ + // TODO: Use IsScrollAnimationEnabled property in future: https://github.com/iNKORE-NET/UI.WPF.Modern/pull/347 + public class CustomScrollViewerEx : ScrollViewer + { + private double LastVerticalLocation = 0; + private double LastHorizontalLocation = 0; + + public CustomScrollViewerEx() + { + Loaded += OnLoaded; + var valueSource = DependencyPropertyHelper.GetValueSource(this, AutoPanningMode.IsEnabledProperty).BaseValueSource; + if (valueSource == BaseValueSource.Default) + { + AutoPanningMode.SetIsEnabled(this, true); + } + } + + #region Orientation + + public static readonly DependencyProperty OrientationProperty = + DependencyProperty.Register( + nameof(Orientation), + typeof(Orientation), + typeof(CustomScrollViewerEx), + new PropertyMetadata(Orientation.Vertical)); + + public Orientation Orientation + { + get => (Orientation)GetValue(OrientationProperty); + set => SetValue(OrientationProperty, value); + } + + #endregion + + #region AutoHideScrollBars + + public static readonly DependencyProperty AutoHideScrollBarsProperty = + ScrollViewerHelper.AutoHideScrollBarsProperty + .AddOwner( + typeof(CustomScrollViewerEx), + new PropertyMetadata(true, OnAutoHideScrollBarsChanged)); + + public bool AutoHideScrollBars + { + get => (bool)GetValue(AutoHideScrollBarsProperty); + set => SetValue(AutoHideScrollBarsProperty, value); + } + + private static void OnAutoHideScrollBarsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is CustomScrollViewerEx sv) + { + sv.UpdateVisualState(); + } + } + + #endregion + + private void OnLoaded(object sender, RoutedEventArgs e) + { + LastVerticalLocation = VerticalOffset; + LastHorizontalLocation = HorizontalOffset; + UpdateVisualState(false); + } + + /// + protected override void OnInitialized(EventArgs e) + { + base.OnInitialized(e); + + if (Style == null && ReadLocalValue(StyleProperty) == DependencyProperty.UnsetValue) + { + SetResourceReference(StyleProperty, typeof(ScrollViewer)); + } + } + + /// + protected override void OnMouseWheel(MouseWheelEventArgs e) + { + var Direction = GetDirection(); + ScrollViewerBehavior.SetIsAnimating(this, true); + + if (Direction == Orientation.Vertical) + { + if (ScrollableHeight > 0) + { + e.Handled = true; + } + + var WheelChange = e.Delta * (ViewportHeight / 1.5) / ActualHeight; + var newOffset = LastVerticalLocation - WheelChange; + + if (newOffset < 0) + { + newOffset = 0; + } + + if (newOffset > ScrollableHeight) + { + newOffset = ScrollableHeight; + } + + if (newOffset == LastVerticalLocation) + { + return; + } + + ScrollToVerticalOffset(LastVerticalLocation); + + ScrollToValue(newOffset, Direction); + LastVerticalLocation = newOffset; + } + else + { + if (ScrollableWidth > 0) + { + e.Handled = true; + } + + var WheelChange = e.Delta * (ViewportWidth / 1.5) / ActualWidth; + var newOffset = LastHorizontalLocation - WheelChange; + + if (newOffset < 0) + { + newOffset = 0; + } + + if (newOffset > ScrollableWidth) + { + newOffset = ScrollableWidth; + } + + if (newOffset == LastHorizontalLocation) + { + return; + } + + ScrollToHorizontalOffset(LastHorizontalLocation); + + ScrollToValue(newOffset, Direction); + LastHorizontalLocation = newOffset; + } + } + + /// + protected override void OnScrollChanged(ScrollChangedEventArgs e) + { + base.OnScrollChanged(e); + if (!ScrollViewerBehavior.GetIsAnimating(this)) + { + LastVerticalLocation = VerticalOffset; + LastHorizontalLocation = HorizontalOffset; + } + } + + private Orientation GetDirection() + { + var isShiftDown = Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift); + + if (Orientation == Orientation.Horizontal) + { + return isShiftDown ? Orientation.Vertical : Orientation.Horizontal; + } + else + { + return isShiftDown ? Orientation.Horizontal : Orientation.Vertical; + } + } + + /// + /// Causes the to load a new view into the viewport using the specified offsets and zoom factor. + /// + /// A value between 0 and that specifies the distance the content should be scrolled horizontally. + /// A value between 0 and that specifies the distance the content should be scrolled vertically. + /// A value between MinZoomFactor and MaxZoomFactor that specifies the required target ZoomFactor. + /// if the view is changed; otherwise, . + public bool ChangeView(double? horizontalOffset, double? verticalOffset, float? zoomFactor) + { + return ChangeView(horizontalOffset, verticalOffset, zoomFactor, false); + } + + /// + /// Causes the to load a new view into the viewport using the specified offsets and zoom factor, and optionally disables scrolling animation. + /// + /// A value between 0 and that specifies the distance the content should be scrolled horizontally. + /// A value between 0 and that specifies the distance the content should be scrolled vertically. + /// A value between MinZoomFactor and MaxZoomFactor that specifies the required target ZoomFactor. + /// to disable zoom/pan animations while changing the view; otherwise, . The default is false. + /// if the view is changed; otherwise, . + public bool ChangeView(double? horizontalOffset, double? verticalOffset, float? zoomFactor, bool disableAnimation) + { + if (disableAnimation) + { + if (horizontalOffset.HasValue) + { + ScrollToHorizontalOffset(horizontalOffset.Value); + } + + if (verticalOffset.HasValue) + { + ScrollToVerticalOffset(verticalOffset.Value); + } + } + else + { + if (horizontalOffset.HasValue) + { + ScrollToHorizontalOffset(LastHorizontalLocation); + ScrollToValue(Math.Min(ScrollableWidth, horizontalOffset.Value), Orientation.Horizontal); + LastHorizontalLocation = horizontalOffset.Value; + } + + if (verticalOffset.HasValue) + { + ScrollToVerticalOffset(LastVerticalLocation); + ScrollToValue(Math.Min(ScrollableHeight, verticalOffset.Value), Orientation.Vertical); + LastVerticalLocation = verticalOffset.Value; + } + } + + return true; + } + + private void ScrollToValue(double value, Orientation Direction) + { + if (Direction == Orientation.Vertical) + { + ScrollToVerticalOffset(value); + } + else + { + ScrollToHorizontalOffset(value); + } + + ScrollViewerBehavior.SetIsAnimating(this, false); + } + + private void UpdateVisualState(bool useTransitions = true) + { + var stateName = AutoHideScrollBars ? "NoIndicator" : "MouseIndicator"; + VisualStateManager.GoToState(this, stateName, useTransitions); + } + } +} diff --git a/Flow.Launcher/Resources/Controls/ExCard.xaml b/Flow.Launcher/Resources/Controls/ExCard.xaml deleted file mode 100644 index a70c0f4ea..000000000 --- a/Flow.Launcher/Resources/Controls/ExCard.xaml +++ /dev/null @@ -1,312 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Flow.Launcher/Resources/Controls/ExCard.xaml.cs b/Flow.Launcher/Resources/Controls/ExCard.xaml.cs deleted file mode 100644 index f149951f0..000000000 --- a/Flow.Launcher/Resources/Controls/ExCard.xaml.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System.Windows; -using System.Windows.Controls; - -namespace Flow.Launcher.Resources.Controls -{ - public partial class ExCard : UserControl - { - public ExCard() - { - InitializeComponent(); - } - public string Title - { - get { return (string)GetValue(TitleProperty); } - set { SetValue(TitleProperty, value); } - } - public static readonly DependencyProperty TitleProperty = - DependencyProperty.Register(nameof(Title), typeof(string), typeof(ExCard), new PropertyMetadata(string.Empty)); - - public string Sub - { - get { return (string)GetValue(SubProperty); } - set { SetValue(SubProperty, value); } - } - public static readonly DependencyProperty SubProperty = - DependencyProperty.Register(nameof(Sub), typeof(string), typeof(ExCard), new PropertyMetadata(string.Empty)); - - public string Icon - { - get { return (string)GetValue(IconProperty); } - set { SetValue(IconProperty, value); } - } - public static readonly DependencyProperty IconProperty = - DependencyProperty.Register(nameof(Icon), typeof(string), typeof(ExCard), new PropertyMetadata(string.Empty)); - - /// - /// Gets or sets additional content for the UserControl - /// - public object AdditionalContent - { - get { return (object)GetValue(AdditionalContentProperty); } - set { SetValue(AdditionalContentProperty, value); } - } - public static readonly DependencyProperty AdditionalContentProperty = - DependencyProperty.Register(nameof(AdditionalContent), typeof(object), typeof(ExCard), - new PropertyMetadata(null)); - - public object SideContent - { - get { return (object)GetValue(SideContentProperty); } - set { SetValue(SideContentProperty, value); } - } - public static readonly DependencyProperty SideContentProperty = - DependencyProperty.Register(nameof(SideContent), typeof(object), typeof(ExCard), - new PropertyMetadata(null)); - } -} diff --git a/Flow.Launcher/Resources/Controls/HyperLink.xaml b/Flow.Launcher/Resources/Controls/HyperLink.xaml deleted file mode 100644 index 9ea550afd..000000000 --- a/Flow.Launcher/Resources/Controls/HyperLink.xaml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - diff --git a/Flow.Launcher/Resources/Controls/HyperLink.xaml.cs b/Flow.Launcher/Resources/Controls/HyperLink.xaml.cs deleted file mode 100644 index 855cccdbd..000000000 --- a/Flow.Launcher/Resources/Controls/HyperLink.xaml.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Windows; -using System.Windows.Controls; -using System.Windows.Navigation; - -namespace Flow.Launcher.Resources.Controls; - -public partial class HyperLink : UserControl -{ - public static readonly DependencyProperty UriProperty = DependencyProperty.Register( - nameof(Uri), typeof(string), typeof(HyperLink), new PropertyMetadata(default(string)) - ); - - public string Uri - { - get => (string)GetValue(UriProperty); - set => SetValue(UriProperty, value); - } - - public static readonly DependencyProperty TextProperty = DependencyProperty.Register( - nameof(Text), typeof(string), typeof(HyperLink), new PropertyMetadata(default(string)) - ); - - public string Text - { - get => (string)GetValue(TextProperty); - set => SetValue(TextProperty, value); - } - - public HyperLink() - { - InitializeComponent(); - } - - private void Hyperlink_OnRequestNavigate(object sender, RequestNavigateEventArgs e) - { - App.API.OpenUrl(e.Uri); - e.Handled = true; - } -} diff --git a/Flow.Launcher/Resources/Controls/InfoBar.xaml b/Flow.Launcher/Resources/Controls/InfoBar.xaml deleted file mode 100644 index 2ddcbdd0c..000000000 --- a/Flow.Launcher/Resources/Controls/InfoBar.xaml +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - + + + + + +