From 2e8c91968f5f2fc4bc19c6a0d6912b88ae3109e2 Mon Sep 17 00:00:00 2001 From: Florian Grabmeier Date: Thu, 1 Feb 2024 16:38:44 +0100 Subject: [PATCH 01/74] Add local plugin installation Signed-off-by: Florian Grabmeier --- .../PluginsManager.cs | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs index 8cd58ac52..b9eaea2d4 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs @@ -14,6 +14,8 @@ using System.Net.Http; using System.Threading; using System.Threading.Tasks; using System.Windows; +using System.IO.Compression; +using Newtonsoft.Json; namespace Flow.Launcher.Plugin.PluginsManager { @@ -138,6 +140,12 @@ namespace Flow.Launcher.Plugin.PluginsManager MessageBoxButton.YesNo) == MessageBoxResult.No) return; + if (File.Exists(plugin.UrlDownload)) + { + Install(plugin, plugin.UrlDownload); + return; + } + // at minimum should provide a name, but handle plugin that is not downloaded from plugins manifest and is a url download var downloadFilename = string.IsNullOrEmpty(plugin.Version) ? $"{plugin.Name}-{Guid.NewGuid()}.zip" @@ -470,6 +478,54 @@ namespace Flow.Launcher.Plugin.PluginsManager return new List { result }; } + internal List InstallFromLocal(string path) + { + if (string.IsNullOrEmpty(path) || !File.Exists(path)) + { + return new List(); + } + + var plugin = null as UserPlugin; + + using (ZipArchive archive = ZipFile.OpenRead(path)) + { + var pluginJsonPath = archive.Entries.FirstOrDefault(x => x.Name == "plugin.json").ToString(); + ZipArchiveEntry pluginJsonEntry = archive.GetEntry(pluginJsonPath); + + if (pluginJsonEntry != null) + { + using (StreamReader reader = new StreamReader(pluginJsonEntry.Open())) + { + string pluginJsonContent = reader.ReadToEnd(); + plugin = JsonConvert.DeserializeObject(pluginJsonContent); + plugin.IcoPath = Path.Combine(path, pluginJsonEntry.FullName.Split('/')[0], plugin.IcoPath); + } + } + } + + if (plugin == null) + { + return new List(); + } + + plugin.UrlDownload = path; + + var result = new Result + { + Title = plugin.Name, + SubTitle = plugin.UrlDownload, + IcoPath = plugin.IcoPath, + Action = e => + { + Application.Current.MainWindow.Hide(); + _ = InstallOrUpdateAsync(plugin); + + return ShouldHideWindow; + } + }; + return new List { result }; + } + private bool InstallSourceKnown(string url) { var author = url.Split('/')[3]; @@ -489,6 +545,9 @@ namespace Flow.Launcher.Plugin.PluginsManager && search.Split('.').Last() == zip) return InstallFromWeb(search); + if (File.Exists(search) && search.Split('.').Last() == zip) + return InstallFromLocal(search); + var results = PluginsManifest .UserPlugins From 1dd526a2f984e1876f912a4d6a27f3f753f7a33e Mon Sep 17 00:00:00 2001 From: Florian Grabmeier Date: Sun, 4 Feb 2024 17:29:05 +0100 Subject: [PATCH 02/74] Add update from local file Signed-off-by: Florian Grabmeier --- .../Images/zipfolder.png | Bin 0 -> 2939 bytes .../PluginsManager.cs | 126 +++++++++++++++++- 2 files changed, 121 insertions(+), 5 deletions(-) create mode 100644 Plugins/Flow.Launcher.Plugin.PluginsManager/Images/zipfolder.png diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Images/zipfolder.png b/Plugins/Flow.Launcher.Plugin.PluginsManager/Images/zipfolder.png new file mode 100644 index 0000000000000000000000000000000000000000..5d3ed0ace3f8a26662b82611eccd95463f32f8c8 GIT binary patch literal 2939 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 x.Name == "plugin.json").ToString(); + ZipArchiveEntry pluginJsonEntry = archive.GetEntry(pluginJsonPath); + + if (pluginJsonEntry != null) + { + using (StreamReader reader = new StreamReader(pluginJsonEntry.Open())) + { + string pluginJsonContent = await reader.ReadToEndAsync(); + plugin = JsonConvert.DeserializeObject(pluginJsonContent); + plugin.IcoPath = "Images\\zipfolder.png"; + } + } + } + if (plugin == null) + { + return new List + { + new Result + { + Title = Context.API.GetTranslation("plugin_pluginsmanager_update_noresult_title"), + SubTitle = Context.API.GetTranslation("plugin_pluginsmanager_update_noresult_subtitle"), + IcoPath = icoPath + } + }; + } + + var pluginOld = Context.API.GetAllPlugins().FirstOrDefault(x => x.Metadata.ID == plugin.ID); + + return new List { + new Result + { + + Title = $"{plugin.Name} by {plugin.Author}", + SubTitle = $"Update from version {pluginOld.Metadata.Version} to {plugin.Version}", + IcoPath = pluginOld.Metadata.IcoPath, + Action = e => + { + string message; + if (Settings.AutoRestartAfterChanging) + { + message = string.Format( + Context.API.GetTranslation("plugin_pluginsmanager_update_prompt"), + plugin.Name, plugin.Author, + Environment.NewLine, Environment.NewLine); + } + else + { + message = string.Format( + Context.API.GetTranslation("plugin_pluginsmanager_update_prompt_no_restart"), + plugin.Name, plugin.Author, + Environment.NewLine); + } + + if (MessageBox.Show(message, + Context.API.GetTranslation("plugin_pluginsmanager_update_title"), + MessageBoxButton.YesNo) != MessageBoxResult.Yes) + { + return false; + } + + var downloadToFilePath = search; + + + PluginManager.UpdatePlugin(pluginOld.Metadata, plugin, + downloadToFilePath); + + if (Settings.AutoRestartAfterChanging) + { + Context.API.ShowMsg( + Context.API.GetTranslation("plugin_pluginsmanager_update_title"), + string.Format( + Context.API.GetTranslation( + "plugin_pluginsmanager_update_success_restart"), + plugin.Name)); + Context.API.RestartApp(); + } + else + { + Context.API.ShowMsg( + Context.API.GetTranslation("plugin_pluginsmanager_update_title"), + string.Format( + Context.API.GetTranslation( + "plugin_pluginsmanager_update_success_no_restart"), + plugin.Name)); + } + + return true; + + }, + ContextData = + new UserPlugin + { + Website = plugin.Website, + UrlSourceCode = plugin.UrlSourceCode + } + }}; + } + var resultsForUpdate = ( from existingPlugin in Context.API.GetAllPlugins() join pluginFromManifest in PluginsManifest.UserPlugins @@ -498,7 +610,7 @@ namespace Flow.Launcher.Plugin.PluginsManager { string pluginJsonContent = reader.ReadToEnd(); plugin = JsonConvert.DeserializeObject(pluginJsonContent); - plugin.IcoPath = Path.Combine(path, pluginJsonEntry.FullName.Split('/')[0], plugin.IcoPath); + plugin.IcoPath = "Images\\zipfolder.png"; } } } @@ -584,7 +696,11 @@ namespace Flow.Launcher.Plugin.PluginsManager try { PluginManager.InstallPlugin(plugin, downloadedFilePath); - File.Delete(downloadedFilePath); + if (downloadedFilePath.StartsWith(Path.GetTempPath())) + { + File.Delete(downloadedFilePath); + } + } catch (FileNotFoundException e) { From a140b118e59e782f1cf58034aec928718cc7f0e7 Mon Sep 17 00:00:00 2001 From: DB p Date: Sat, 27 Apr 2024 20:00:24 +0900 Subject: [PATCH 03/74] - Split Style Code to SettingWindowStyle - Adjust Navigation Style - Add General.xaml --- Flow.Launcher/Flow.Launcher.csproj | 4 + .../Resources/CustomControlTemplate.xaml | 1649 +++++ .../Resources/SettingWindowStyle.xaml | 440 ++ Flow.Launcher/SettingPages/General.xaml | 19 + Flow.Launcher/SettingPages/General.xaml.cs | 22 + .../ViewModels/GeneralViewModel.cs | 26 + Flow.Launcher/SettingWindow.xaml | 6422 ++++++++--------- Flow.Launcher/SettingWindow.xaml.cs | 24 + .../ViewModel/SettingWindowViewModel.cs | 7 + 9 files changed, 5261 insertions(+), 3352 deletions(-) create mode 100644 Flow.Launcher/Resources/SettingWindowStyle.xaml create mode 100644 Flow.Launcher/SettingPages/General.xaml create mode 100644 Flow.Launcher/SettingPages/General.xaml.cs create mode 100644 Flow.Launcher/SettingPages/ViewModels/GeneralViewModel.cs diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj index 53c1bafc7..c280c3c7e 100644 --- a/Flow.Launcher/Flow.Launcher.csproj +++ b/Flow.Launcher/Flow.Launcher.csproj @@ -111,6 +111,10 @@ + + + + diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml index 2ce53bfdb..e52143fa5 100644 --- a/Flow.Launcher/Resources/CustomControlTemplate.xaml +++ b/Flow.Launcher/Resources/CustomControlTemplate.xaml @@ -3695,4 +3695,1653 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + - - - - + + + + + + + + @@ -609,1579 +212,2195 @@ Grid.Row="0" Width="50" Height="50" + RenderOptions.BitmapScalingMode="HighQuality" Source="images/app.png" /> + TextAlignment="Center" /> - - - - - - - - - - - -  - - - - - - - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - - -  - - - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + +  + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + - - - - - - - -  - - - - - - - + - - + + + + + + + + + + + + + +  + + + + + + + + + + + + + + + +  + + + + + - - - - - - - - -  - - - - - + + + + + + + + + + +  + + + + + + + + + + + + + + + + + + + + + + + + +  + + + + + + + + + + + + + + + + +  + + + + + + + + + + + + + + + + + + + +  + + + + + + + + + + + + + +  + + + + + + + + + + - - - -  - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - -  - - - - - - + Click="OnTestProxyClick" + Content="{DynamicResource testProxy}" + IsEnabled="{Binding Settings.Proxy.Enabled}" /> + + + + - - - - - + + + + + + + + + +  + + + + + + + + + + + + + + + + + + + + + +  + + + + + + + + + + + + + + + +  + + + + + + + + + + + + + + + + + + + + + + +  + + + + + + + + + + + + + + + + + + + + + + +  + + + + + + + + + + + + + + + + +  + + + + + + + + + + + + + +  + + + + + + + + + + + + + diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs index 8144c8ff8..0bba24997 100644 --- a/Flow.Launcher/SettingWindow.xaml.cs +++ b/Flow.Launcher/SettingWindow.xaml.cs @@ -24,6 +24,7 @@ using KeyEventArgs = System.Windows.Input.KeyEventArgs; using MessageBox = System.Windows.MessageBox; using TextBox = System.Windows.Controls.TextBox; using ThemeManager = ModernWpf.ThemeManager; +using Flow.Launcher.SettingPages.Views; namespace Flow.Launcher { @@ -503,5 +504,28 @@ namespace Flow.Launcher { Keyboard.Focus(pluginFilterTxb); } + + /** For Navigation View **/ + private void NavigationView_SelectionChanged(ModernWpf.Controls.NavigationView sender, ModernWpf.Controls.NavigationViewSelectionChangedEventArgs args) + { + if (args.IsSettingsSelected) + { + contentFrame.Navigate(typeof(General)); + } + else + { + var selectedItem = (ModernWpf.Controls.NavigationViewItem)args.SelectedItem; + if (selectedItem == null) + { + return; + } + string selectedItemTag = (string)selectedItem.Tag; + + sender.Header = (string)selectedItem.Content; + string pageName = $"Flow.Launcher.SettingPages.Views.{selectedItemTag}"; + Type pageType = typeof(About).Assembly.GetType(pageName); + contentFrame.Navigate(pageType, settings); + } + } } } diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs index fe1ea4e7b..efd37b0e1 100644 --- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs +++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs @@ -24,6 +24,7 @@ using CommunityToolkit.Mvvm.Input; using System.Globalization; using System.Runtime.CompilerServices; using Flow.Launcher.Infrastructure.Hotkey; +using ModernWpf.Media.Animation; namespace Flow.Launcher.ViewModel { @@ -33,6 +34,12 @@ namespace Flow.Launcher.ViewModel private readonly IPortable _portable; private readonly FlowLauncherJsonStorage _storage; + /* For Navigation View */ + private NavigationTransitionInfo _transitionInfo = new SlideNavigationTransitionInfo() + { + Effect = SlideNavigationTransitionEffect.FromBottom + }; + public SettingWindowViewModel(Updater updater, IPortable portable) { _updater = updater; From b4570e9aaa497037abb8e97be2c3cf8ded7bc723 Mon Sep 17 00:00:00 2001 From: DB p Date: Sat, 27 Apr 2024 21:57:55 +0900 Subject: [PATCH 04/74] - Add Pages --- Flow.Launcher/Flow.Launcher.csproj | 4 - .../Resources/SettingWindowStyle.xaml | 4 + Flow.Launcher/SettingPages/General.xaml | 19 - Flow.Launcher/SettingPages/General.xaml.cs | 22 - .../ViewModels/GeneralViewModel.cs | 49 +- Flow.Launcher/SettingPages/Views/About.xaml | 232 ++ .../SettingPages/Views/About.xaml.cs | 37 + Flow.Launcher/SettingPages/Views/General.xaml | 517 +++ .../SettingPages/Views/General.xaml.cs | 51 + Flow.Launcher/SettingPages/Views/Hotkey.xaml | 471 +++ .../SettingPages/Views/Hotkey.xaml.cs | 28 + .../SettingPages/Views/PluginStore.xaml | 347 ++ .../SettingPages/Views/PluginStore.xaml.cs | 28 + Flow.Launcher/SettingPages/Views/Plugins.xaml | 384 +++ .../SettingPages/Views/Plugins.xaml.cs | 28 + Flow.Launcher/SettingPages/Views/Proxy.xaml | 180 + .../SettingPages/Views/Proxy.xaml.cs | 28 + Flow.Launcher/SettingPages/Views/Theme.xaml | 744 +++++ .../SettingPages/Views/Theme.xaml.cs | 25 + Flow.Launcher/SettingWindow.xaml | 2933 ----------------- Flow.Launcher/SettingWindow.xaml.cs | 166 +- .../ViewModel/SettingWindowViewModel.cs | 23 - 22 files changed, 3235 insertions(+), 3085 deletions(-) delete mode 100644 Flow.Launcher/SettingPages/General.xaml delete mode 100644 Flow.Launcher/SettingPages/General.xaml.cs create mode 100644 Flow.Launcher/SettingPages/Views/About.xaml create mode 100644 Flow.Launcher/SettingPages/Views/About.xaml.cs create mode 100644 Flow.Launcher/SettingPages/Views/General.xaml create mode 100644 Flow.Launcher/SettingPages/Views/General.xaml.cs create mode 100644 Flow.Launcher/SettingPages/Views/Hotkey.xaml create mode 100644 Flow.Launcher/SettingPages/Views/Hotkey.xaml.cs create mode 100644 Flow.Launcher/SettingPages/Views/PluginStore.xaml create mode 100644 Flow.Launcher/SettingPages/Views/PluginStore.xaml.cs create mode 100644 Flow.Launcher/SettingPages/Views/Plugins.xaml create mode 100644 Flow.Launcher/SettingPages/Views/Plugins.xaml.cs create mode 100644 Flow.Launcher/SettingPages/Views/Proxy.xaml create mode 100644 Flow.Launcher/SettingPages/Views/Proxy.xaml.cs create mode 100644 Flow.Launcher/SettingPages/Views/Theme.xaml create mode 100644 Flow.Launcher/SettingPages/Views/Theme.xaml.cs diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj index c280c3c7e..53c1bafc7 100644 --- a/Flow.Launcher/Flow.Launcher.csproj +++ b/Flow.Launcher/Flow.Launcher.csproj @@ -111,10 +111,6 @@ - - - - diff --git a/Flow.Launcher/Resources/SettingWindowStyle.xaml b/Flow.Launcher/Resources/SettingWindowStyle.xaml index 97671b088..485a0159d 100644 --- a/Flow.Launcher/Resources/SettingWindowStyle.xaml +++ b/Flow.Launcher/Resources/SettingWindowStyle.xaml @@ -20,6 +20,10 @@ + + + + + + +  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  + + + + + + + + + + + + + + +  + + + + + + + + + + + + +  + + + + + + + + + + + +  + + + + + + + + + + + + +  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  + + + + + + + + + + + + + + + + + + + diff --git a/Flow.Launcher/SettingPages/Views/PluginStore.xaml.cs b/Flow.Launcher/SettingPages/Views/PluginStore.xaml.cs new file mode 100644 index 000000000..3d756f6fa --- /dev/null +++ b/Flow.Launcher/SettingPages/Views/PluginStore.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Flow.Launcher.SettingPages.Views +{ + /// + /// PluginStore.xaml에 대한 상호 작용 논리 + /// + public partial class PluginStore : Page + { + public PluginStore() + { + InitializeComponent(); + } + } +} diff --git a/Flow.Launcher/SettingPages/Views/Plugins.xaml b/Flow.Launcher/SettingPages/Views/Plugins.xaml new file mode 100644 index 000000000..d0545de11 --- /dev/null +++ b/Flow.Launcher/SettingPages/Views/Plugins.xaml @@ -0,0 +1,384 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  + + + - - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - - -  - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - -  - - - - - - - - - - - - - -  - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - -  - - - - - - - - - - - - diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs index 0bba24997..8f3edc872 100644 --- a/Flow.Launcher/SettingWindow.xaml.cs +++ b/Flow.Launcher/SettingWindow.xaml.cs @@ -42,7 +42,7 @@ namespace Flow.Launcher API = api; InitializePosition(); InitializeComponent(); - + NavView.SelectedItem = NavView.MenuItems[0]; /* Set First Page */ } #region General @@ -54,28 +54,28 @@ namespace Flow.Launcher // https://stackoverflow.com/questions/4951058/software-rendering-mode-wpf HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource; HwndTarget hwndTarget = hwndSource.CompositionTarget; - hwndTarget.RenderMode = RenderMode.SoftwareOnly; + hwndTarget.RenderMode = RenderMode.Default; - pluginListView = (CollectionView)CollectionViewSource.GetDefaultView(Plugins.ItemsSource); - pluginListView.Filter = PluginListFilter; + //pluginListView = (CollectionView)CollectionViewSource.GetDefaultView(Plugins.ItemsSource); + //pluginListView.Filter = PluginListFilter; - pluginStoreView = (CollectionView)CollectionViewSource.GetDefaultView(StoreListBox.ItemsSource); - pluginStoreView.Filter = PluginStoreFilter; + //pluginStoreView = (CollectionView)CollectionViewSource.GetDefaultView(StoreListBox.ItemsSource); + //pluginStoreView.Filter = PluginStoreFilter; - viewModel.PropertyChanged += new PropertyChangedEventHandler(SettingsWindowViewModelChanged); + //viewModel.PropertyChanged += new PropertyChangedEventHandler(SettingsWindowViewModelChanged); InitializePosition(); } - private void SettingsWindowViewModelChanged(object sender, PropertyChangedEventArgs e) - { - if (e.PropertyName == nameof(viewModel.ExternalPlugins)) - { - pluginStoreView = (CollectionView)CollectionViewSource.GetDefaultView(StoreListBox.ItemsSource); - pluginStoreView.Filter = PluginStoreFilter; - pluginStoreView.Refresh(); - } - } + //private void SettingsWindowViewModelChanged(object sender, PropertyChangedEventArgs e) + //{ + // if (e.PropertyName == nameof(viewModel.ExternalPlugins)) + // { + // pluginStoreView = (CollectionView)CollectionViewSource.GetDefaultView(StoreListBox.ItemsSource); + // pluginStoreView.Filter = PluginStoreFilter; + // pluginStoreView.Refresh(); + // } + //} private void OnSelectPythonPathClick(object sender, RoutedEventArgs e) { @@ -375,75 +375,75 @@ namespace Flow.Launcher private CollectionView pluginListView; private CollectionView pluginStoreView; - private bool PluginListFilter(object item) - { - if (string.IsNullOrEmpty(pluginFilterTxb.Text)) - return true; - if (item is PluginViewModel model) - { - return StringMatcher.FuzzySearch(pluginFilterTxb.Text, model.PluginPair.Metadata.Name).IsSearchPrecisionScoreMet(); - } - return false; - } + //private bool PluginListFilter(object item) + //{ + // if (string.IsNullOrEmpty(pluginFilterTxb.Text)) + // return true; + // if (item is PluginViewModel model) + // { + // return StringMatcher.FuzzySearch(pluginFilterTxb.Text, model.PluginPair.Metadata.Name).IsSearchPrecisionScoreMet(); + // } + // return false; + //} - private bool PluginStoreFilter(object item) - { - if (string.IsNullOrEmpty(pluginStoreFilterTxb.Text)) - return true; - if (item is PluginStoreItemViewModel model) - { - return StringMatcher.FuzzySearch(pluginStoreFilterTxb.Text, model.Name).IsSearchPrecisionScoreMet() - || StringMatcher.FuzzySearch(pluginStoreFilterTxb.Text, model.Description).IsSearchPrecisionScoreMet(); - } - return false; - } + //private bool PluginStoreFilter(object item) + //{ + // if (string.IsNullOrEmpty(pluginStoreFilterTxb.Text)) + // return true; + // if (item is PluginStoreItemViewModel model) + // { + // return StringMatcher.FuzzySearch(pluginStoreFilterTxb.Text, model.Name).IsSearchPrecisionScoreMet() + // || StringMatcher.FuzzySearch(pluginStoreFilterTxb.Text, model.Description).IsSearchPrecisionScoreMet(); + // } + // return false; + //} private string lastPluginListSearch = ""; private string lastPluginStoreSearch = ""; - private void RefreshPluginListEventHandler(object sender, RoutedEventArgs e) - { - if (pluginFilterTxb.Text != lastPluginListSearch) - { - lastPluginListSearch = pluginFilterTxb.Text; - pluginListView.Refresh(); - } - } + //private void RefreshPluginListEventHandler(object sender, RoutedEventArgs e) + //{ + // if (pluginFilterTxb.Text != lastPluginListSearch) + // { + // lastPluginListSearch = pluginFilterTxb.Text; + // pluginListView.Refresh(); + // } + //} - private void RefreshPluginStoreEventHandler(object sender, RoutedEventArgs e) - { - if (pluginStoreFilterTxb.Text != lastPluginStoreSearch) - { - lastPluginStoreSearch = pluginStoreFilterTxb.Text; - pluginStoreView.Refresh(); - } - } + //private void RefreshPluginStoreEventHandler(object sender, RoutedEventArgs e) + //{ + // if (pluginStoreFilterTxb.Text != lastPluginStoreSearch) + // { + // lastPluginStoreSearch = pluginStoreFilterTxb.Text; + // pluginStoreView.Refresh(); + // } + //} - private void PluginFilterTxb_OnKeyDown(object sender, KeyEventArgs e) - { - if (e.Key == Key.Enter) - RefreshPluginListEventHandler(sender, e); - } + //private void PluginFilterTxb_OnKeyDown(object sender, KeyEventArgs e) + //{ + // if (e.Key == Key.Enter) + // RefreshPluginListEventHandler(sender, e); + //} - private void PluginStoreFilterTxb_OnKeyDown(object sender, KeyEventArgs e) - { - if (e.Key == Key.Enter) - RefreshPluginStoreEventHandler(sender, e); - } + //private void PluginStoreFilterTxb_OnKeyDown(object sender, KeyEventArgs e) + //{ + // if (e.Key == Key.Enter) + // RefreshPluginStoreEventHandler(sender, e); + //} - private void OnPluginSettingKeydown(object sender, KeyEventArgs e) - { - if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control && e.Key == Key.F) - pluginFilterTxb.Focus(); - } + //private void OnPluginSettingKeydown(object sender, KeyEventArgs e) + //{ + // if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control && e.Key == Key.F) + // pluginFilterTxb.Focus(); + //} - private void PluginStore_OnKeyDown(object sender, KeyEventArgs e) - { - if (e.Key == Key.F && (Keyboard.Modifiers & ModifierKeys.Control) != 0) - { - pluginStoreFilterTxb.Focus(); - } - } + //private void PluginStore_OnKeyDown(object sender, KeyEventArgs e) + //{ + // if (e.Key == Key.F && (Keyboard.Modifiers & ModifierKeys.Control) != 0) + // { + // pluginStoreFilterTxb.Focus(); + // } + //} public void InitializePosition() { @@ -495,15 +495,15 @@ namespace Flow.Launcher } - private void PluginStore_GotFocus(object sender, RoutedEventArgs e) - { - Keyboard.Focus(pluginStoreFilterTxb); - } + //private void PluginStore_GotFocus(object sender, RoutedEventArgs e) + //{ + // Keyboard.Focus(pluginStoreFilterTxb); + //} - private void Plugin_GotFocus(object sender, RoutedEventArgs e) - { - Keyboard.Focus(pluginFilterTxb); - } + //private void Plugin_GotFocus(object sender, RoutedEventArgs e) + //{ + // Keyboard.Focus(pluginFilterTxb); + //} /** For Navigation View **/ private void NavigationView_SelectionChanged(ModernWpf.Controls.NavigationView sender, ModernWpf.Controls.NavigationViewSelectionChangedEventArgs args) diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs index efd37b0e1..aa16e7cb7 100644 --- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs +++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs @@ -481,29 +481,6 @@ namespace Flow.Launcher.ViewModel } } - public class SearchWindowScreen - { - public string Display { get; set; } - public SearchWindowScreens Value { get; set; } - } - - public List SearchWindowScreens - { - get - { - List modes = new List(); - var enums = (SearchWindowScreens[])Enum.GetValues(typeof(SearchWindowScreens)); - foreach (var e in enums) - { - var key = $"SearchWindowScreen{e}"; - var display = _translater.GetTranslation(key); - var m = new SearchWindowScreen { Display = display, Value = e, }; - modes.Add(m); - } - - return modes; - } - } public class SearchWindowAlign { From 6a2f23cf6bb22707280c2d681243ea6fc30b8bc5 Mon Sep 17 00:00:00 2001 From: DB p Date: Sat, 27 Apr 2024 22:48:03 +0900 Subject: [PATCH 05/74] - Add Color Icons in Menu --- Flow.Launcher/Images/info.png | Bin 0 -> 1367 bytes Flow.Launcher/Images/keyboard.png | Bin 0 -> 873 bytes Flow.Launcher/Images/plugins.png | Bin 0 -> 804 bytes Flow.Launcher/Images/proxy.png | Bin 0 -> 1757 bytes Flow.Launcher/Images/store.png | Bin 0 -> 763 bytes Flow.Launcher/Images/theme.png | Bin 0 -> 1071 bytes .../Resources/CustomControlTemplate.xaml | 4 +++- Flow.Launcher/SettingWindow.xaml | 14 +++++++------- 8 files changed, 10 insertions(+), 8 deletions(-) create mode 100644 Flow.Launcher/Images/info.png create mode 100644 Flow.Launcher/Images/keyboard.png create mode 100644 Flow.Launcher/Images/plugins.png create mode 100644 Flow.Launcher/Images/proxy.png create mode 100644 Flow.Launcher/Images/store.png create mode 100644 Flow.Launcher/Images/theme.png diff --git a/Flow.Launcher/Images/info.png b/Flow.Launcher/Images/info.png new file mode 100644 index 0000000000000000000000000000000000000000..75ffe11e0e80ad0abda0b0c6be6bf4fbec510a10 GIT binary patch literal 1367 zcmV-d1*rOoP)e~1+`))7_;wTGnkk_g98p=tV&f=wH13HFy2=%nPJAMqM#@$Uo}43 zQ3uZ(tRDDFa~=JDZ{GLj`yPf}>eJEtKhxS4$U2OYs6} zEuJS=i*>~PA|26Ms3ShkyGN#D|A$oRyn^y&`kKN(|5mYdd|JLlLHQyDW%rMvRDTR5 z3nY}xlTdt*fFd0Mg>wWH-hB)OKR*Wf?9pEZcaFZ4-z8!r4ql{%*DH zu}ndj@F1T#g8Vy2kT>n4a<#r28Cq9#MBo*MCvPiO=sm>>4Lra@uGR;+w+}(4Ik3qz zzIV?RzS2m4qgbI|@C~0c#RwdNY|{IWRPFr{1Bl|693ZOF=x?bs`r-WG4?sF`0NH9U zNX9+ts=n3Nc;l}!`c;vG_kv{13t1y>4OR`W@B#l_#NkIhkU8RkjA2&;61>7ly~B0S z%e8LEQ=1`g+zfdd7YBGZWDL1Z(}q0nbAr#+!=*|ijdOu7(%3-#hyd#3Mc^6VAs~O; z5+3|5H>3}_A#Kp*lMLH0hb>UK;=jRZ<)=MR^Tz=M=cfl=kf~ka!b94C3sUd82TfugzW`TQv-OgpV&7aHgGEKw+T2=321%S}$B%c7zCg zqPK%|+!Z#wxGx|8qHagcnFT7A=`EDgCP!_9&zBr<7bgSHrwshCg*$wY15&yi&NCgW zWripDyd0Gp56DJsARV!ROzlR3ztYVJ*dejg_7?l<8>lZ(;d92UkUg*qlKx$g^zA@a z?+!?Y%t-LbopwlWw|>w51s0EoQGZeld~hUY#XEVJq%0$tlk z@Ja19NKje#*ah^Y6SX~%^gav`$mrZcf=_H?1T0Tk1xocKh1%O>^@IwfcWfcSC#tNF zptPJ~T6pz81&ZehKWbx^*}WYikk+w@2H$Fh%SsDiY;AVQJn2R4DqkwlzKIMU-(o&t z-9p7WVgt1$W(qbqscoBx@D_+`Hal4bispzZ)P9~R*x-m&8%Xf+%@&AlG%v9V6wDFd zq7EZW!G;L5ZXm(OHJKTKM)of-OI}5tq?m#Yj!3zV3J-z?^LwlU%rPaO^?A6Df$l)T z2Ior4Iug9F0rz9o_BYrCFbtE=_!_ywGe;#;u)#^Wxy~6rrojZldVCN&Yh+q)R_?U# zITv{5sALK@M4)+%Gki=Pek!cpFT=t~&TZcc&GQ*0Lp#n)w>m1?nXP4@6S=a&ri3#6loMzaLy}+JlwhgoLNsVieq}&Z3zRm=K z8vHtjl5F+CB95o!1?SP;GYX>@E>@&k!Fji-ys$E zIcLSaj#GZ%@x_?h{Q@k~N$Ihbi+b#1Dc$y`;ltx6G4-aY=sKMJuIJoEI(K3cyX+q% zx7#|C+H8L&s%-wyVZ`!xY@=y4w!zdVtlR(a{PsCd5j7tQg(|B^pmd}%f_%OAA{W8< Z&A)|h%;wC=< literal 0 HcmV?d00001 diff --git a/Flow.Launcher/Images/keyboard.png b/Flow.Launcher/Images/keyboard.png new file mode 100644 index 0000000000000000000000000000000000000000..5ac670419ab080f24aa88343a1054b92c78827d3 GIT binary patch literal 873 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 literal 0 HcmV?d00001 diff --git a/Flow.Launcher/Images/store.png b/Flow.Launcher/Images/store.png new file mode 100644 index 0000000000000000000000000000000000000000..a4b19c8f9337fd4f8282973b7dbe19defa593be5 GIT binary patch literal 763 zcmVwF@z3GK^8{ODX&W3rAi&0PGf(gh5Y)sf- zc;v<^Q#MCSNaUi)#*Yj(9SFi0@gESv0S3mz1Bw3uXX8l|V?e*AXlHG@bnUWtn7mK& zIXz3C_tU<~5F#NVA^GofqcnZgemD&pDPcKWG{N18Cb)xWg8RxQcu+#e;m=_!JWtq) z#`*n+lhe0rK0KS?&MFPnOMorIoz)~Eym|GJdJ6CmjdSm75s+M)8CRv>3HMpEK#4!7 z^gLnfuK@pDw}A9b=zd5ew^<^fKP>qIh+LtX!jdb55E>hgfe6B!F}>SuJF$iKlKy|! zx>4f6y)&_-D&XFG{Gs88JygcM_vl#t3+%==FRZ|BY+F^}+U~@7qYv6%fws5oq^f{@ zd)U^x{Qxc^uEI#GssI9X$+Z>v;wp~9MZ#Ge{f0R1vbq35$We$KI|~s|f=T&+n(6>1 z?ZwhL%Zz-i>hR~+Xd_&7Yz~7GbkYOV6A#c+9auU?nedyc1#Ii#8T;!nC?O1q;OOik z>*1%>3#^5PZR;UWLOO<{v;D!k7K&6aurhSh`f3Q2kdEQ#tRicnTU84~fBOSxhF#^l}gl2)}jIY0WsSo5x$8dDb0vTVw z_Ajv5cioif1v%0&9GxlC3&L463)r9guNW7-Ka7h$kV1)n`$-Sr=!^@#pDoK>SCO6= z=DjC|c`rzzXFGvPb^twl7jSfjdG86*8!CNoi=OL&MncW?6m$#F&w3n9sqOIw&H4ZU002ovPDHLkV1hVaWcC06 literal 0 HcmV?d00001 diff --git a/Flow.Launcher/Images/theme.png b/Flow.Launcher/Images/theme.png new file mode 100644 index 0000000000000000000000000000000000000000..9518343b7fe7f827d3c084c01bab9889257acdf1 GIT binary patch literal 1071 zcmV+~1kn45P)&+o!$oH5zeW;8OvWXsGHEn!LqlDdwJ zvNh8XmPO;(#is6%U8pl-W^p9jE<{sjYGetp4rb{%qy@?*g%%jama@$Qd&xB zY3X_WnqC-(imPkWr^J5#fG4kap6_$>0GVZ$S!T(Yck7NL9%02kEX8@YY!}Q4w@2Ki zi)T~sK`rr}zX-$6YY-lovcf*p!Tf?;-{e~L_eL7R{ ze)wQKpmC8p`53k2cS1syhB`h#2X5_44G;@;CbTuRUQAW1IjK2Ts?M3ltTe`y1 z=FUUlVjd~@?t0kVr$H_Wqs0QIK45hD)LVbYw|3d3as{6g{QNnr_cX#g*8qwqzlQhW9A2V!jRjL;}o}tckM#p8_BI+CT{f>|#G~7ofzoBm~TIf)94%IlmH= za6lysaT4HH;aD;PCU!9!R{=MZ6fl@_d`OMLKsP8U0hO#eyh zp8D}bK#gFM-hc$DUQmluK{Y7R0LxxB=Gc$NQ;PRrLQYVNU=jkxC-&nhqPPSjM0bz zbiV+1J;Lr<=v@+4;}k>W5U2PfU2J!+peL+HFmwsFkQTQBJ@_u5!UdlKr+sbs$Rk7f pd=q#!IUZZ|A(>^CS!Vx>{SLrHrRuzJJ*fZy002ovPDHLkV1in_16cq7 literal 0 HcmV?d00001 diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml index e52143fa5..17a9f1f64 100644 --- a/Flow.Launcher/Resources/CustomControlTemplate.xaml +++ b/Flow.Launcher/Resources/CustomControlTemplate.xaml @@ -3697,6 +3697,8 @@ + 48 + + 48 diff --git a/Flow.Launcher/Resources/SettingWindowStyle.xaml b/Flow.Launcher/Resources/SettingWindowStyle.xaml index 485a0159d..97671b088 100644 --- a/Flow.Launcher/Resources/SettingWindowStyle.xaml +++ b/Flow.Launcher/Resources/SettingWindowStyle.xaml @@ -20,10 +20,6 @@ - - - - diff --git a/Flow.Launcher/Resources/Controls/Card.xaml.cs b/Flow.Launcher/Resources/Controls/Card.xaml.cs index 06266c775..db4a136a3 100644 --- a/Flow.Launcher/Resources/Controls/Card.xaml.cs +++ b/Flow.Launcher/Resources/Controls/Card.xaml.cs @@ -12,10 +12,27 @@ namespace Flow.Launcher.Resources.Controls InsideFit } + public enum CardGroupPosition + { + NotInGroup, + First, + Middle, + Last + } + public Card() { InitializeComponent(); } + + public CardGroupPosition GroupPosition + { + get { return (CardGroupPosition)GetValue(GroupPositionProperty); } + set { SetValue(GroupPositionProperty, value); } + } + public static readonly DependencyProperty GroupPositionProperty = + DependencyProperty.Register(nameof(GroupPosition), typeof(CardGroupPosition), typeof(Card), new PropertyMetadata(CardGroupPosition.NotInGroup)); + public string Title { get { return (string)GetValue(TitleProperty); } diff --git a/Flow.Launcher/Resources/Controls/CardGroup.xaml b/Flow.Launcher/Resources/Controls/CardGroup.xaml new file mode 100644 index 000000000..d3383d20c --- /dev/null +++ b/Flow.Launcher/Resources/Controls/CardGroup.xaml @@ -0,0 +1,31 @@ + + + + + + + + + + + + diff --git a/Flow.Launcher/Resources/Controls/CardGroup.xaml.cs b/Flow.Launcher/Resources/Controls/CardGroup.xaml.cs new file mode 100644 index 000000000..6ddbf3597 --- /dev/null +++ b/Flow.Launcher/Resources/Controls/CardGroup.xaml.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.ObjectModel; +using System.Windows; +using System.Windows.Controls; + +namespace Flow.Launcher.Resources.Controls; + +public partial class CardGroup : UserControl +{ + public new ObservableCollection Content + { + get { return (ObservableCollection)GetValue(ContentProperty); } + set { SetValue(ContentProperty, value); } + } + + public static readonly DependencyProperty ContentProperty = + DependencyProperty.Register(nameof(Content), typeof(ObservableCollection), typeof(CardGroup)); + + public CardGroup() + { + InitializeComponent(); + DataContext = this; + Content = new ObservableCollection(); + } +} diff --git a/Flow.Launcher/Resources/Controls/CardGroupCardStyleSelector.cs b/Flow.Launcher/Resources/Controls/CardGroupCardStyleSelector.cs new file mode 100644 index 000000000..605934e80 --- /dev/null +++ b/Flow.Launcher/Resources/Controls/CardGroupCardStyleSelector.cs @@ -0,0 +1,21 @@ +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; + } +} From fb6b1bb5187d01035a95098147619f8bdb53f871 Mon Sep 17 00:00:00 2001 From: Yusyuriv Date: Wed, 1 May 2024 14:19:20 +0600 Subject: [PATCH 22/74] Fix CardGroup overwriting DataContext of its children --- Flow.Launcher/Resources/Controls/CardGroup.xaml | 3 ++- Flow.Launcher/Resources/Controls/CardGroup.xaml.cs | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Flow.Launcher/Resources/Controls/CardGroup.xaml b/Flow.Launcher/Resources/Controls/CardGroup.xaml index d3383d20c..5ea9d1e60 100644 --- a/Flow.Launcher/Resources/Controls/CardGroup.xaml +++ b/Flow.Launcher/Resources/Controls/CardGroup.xaml @@ -26,6 +26,7 @@ - + diff --git a/Flow.Launcher/Resources/Controls/CardGroup.xaml.cs b/Flow.Launcher/Resources/Controls/CardGroup.xaml.cs index 6ddbf3597..02f4ca013 100644 --- a/Flow.Launcher/Resources/Controls/CardGroup.xaml.cs +++ b/Flow.Launcher/Resources/Controls/CardGroup.xaml.cs @@ -13,13 +13,12 @@ public partial class CardGroup : UserControl set { SetValue(ContentProperty, value); } } - public static readonly DependencyProperty ContentProperty = + public static new readonly DependencyProperty ContentProperty = DependencyProperty.Register(nameof(Content), typeof(ObservableCollection), typeof(CardGroup)); public CardGroup() { InitializeComponent(); - DataContext = this; Content = new ObservableCollection(); } } From bd867db99aa041b7699e0450287327d0944685f3 Mon Sep 17 00:00:00 2001 From: DB p Date: Thu, 2 May 2024 07:24:33 +0900 Subject: [PATCH 23/74] Add WMP warning --- Flow.Launcher/Languages/en.xaml | 1 + Flow.Launcher/SettingWindow.xaml | 34 +++++++++++++++++++++++++++++ Flow.Launcher/SettingWindow.xaml.cs | 14 ++++++++++-- 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index bda86e481..7aca36e22 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -158,6 +158,7 @@ Play a small sound when the search window opens Sound Effect Volume Adjust the volume of the sound effect + Flow Launcher can't play sound because "Windows Media Player" doesn't exist on your system. If you need sound, install WMP. Animation Use Animation in UI Animation Speed diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index 84b91e312..fd999585d 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -2561,6 +2561,40 @@ + + + + + + + + + + diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs index 8144c8ff8..58ffbb149 100644 --- a/Flow.Launcher/SettingWindow.xaml.cs +++ b/Flow.Launcher/SettingWindow.xaml.cs @@ -24,6 +24,7 @@ using KeyEventArgs = System.Windows.Input.KeyEventArgs; using MessageBox = System.Windows.MessageBox; using TextBox = System.Windows.Controls.TextBox; using ThemeManager = ModernWpf.ThemeManager; +using System.Diagnostics; namespace Flow.Launcher { @@ -63,9 +64,18 @@ namespace Flow.Launcher viewModel.PropertyChanged += new PropertyChangedEventHandler(SettingsWindowViewModelChanged); + CheckMediaPlayer(); InitializePosition(); } + private void CheckMediaPlayer() + { + + if (!File.Exists(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "Windows Media Player", "wmplayer.exe"))) + { + /* Binding WMPWarning visibility */ + } + } private void SettingsWindowViewModelChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(viewModel.ExternalPlugins)) @@ -294,8 +304,8 @@ namespace Flow.Launcher } private void window_MouseDown(object sender, MouseButtonEventArgs e) /* for close hotkey popup */ - { - if (Keyboard.FocusedElement is not TextBox textBox) + { + if (Keyboard.FocusedElement is not TextBox textBox) { return; } From aaef48cd16cba97278b08168295e7d888ad627ac Mon Sep 17 00:00:00 2001 From: Yusyuriv Date: Thu, 2 May 2024 20:48:24 +0600 Subject: [PATCH 24/74] Replace Card.GroupPosition with CardGroup.Position attached property --- Flow.Launcher/Resources/Controls/Card.xaml | 6 ++--- Flow.Launcher/Resources/Controls/Card.xaml.cs | 16 ------------- .../Resources/Controls/CardGroup.xaml | 6 ++--- .../Resources/Controls/CardGroup.xaml.cs | 23 +++++++++++++++++++ 4 files changed, 29 insertions(+), 22 deletions(-) diff --git a/Flow.Launcher/Resources/Controls/Card.xaml b/Flow.Launcher/Resources/Controls/Card.xaml index 147c0e650..c29a5f602 100644 --- a/Flow.Launcher/Resources/Controls/Card.xaml +++ b/Flow.Launcher/Resources/Controls/Card.xaml @@ -38,21 +38,21 @@ - + - + - + diff --git a/Flow.Launcher/Resources/Controls/Card.xaml.cs b/Flow.Launcher/Resources/Controls/Card.xaml.cs index db4a136a3..c8f788aca 100644 --- a/Flow.Launcher/Resources/Controls/Card.xaml.cs +++ b/Flow.Launcher/Resources/Controls/Card.xaml.cs @@ -12,27 +12,11 @@ namespace Flow.Launcher.Resources.Controls InsideFit } - public enum CardGroupPosition - { - NotInGroup, - First, - Middle, - Last - } - public Card() { InitializeComponent(); } - public CardGroupPosition GroupPosition - { - get { return (CardGroupPosition)GetValue(GroupPositionProperty); } - set { SetValue(GroupPositionProperty, value); } - } - public static readonly DependencyProperty GroupPositionProperty = - DependencyProperty.Register(nameof(GroupPosition), typeof(CardGroupPosition), typeof(Card), new PropertyMetadata(CardGroupPosition.NotInGroup)); - public string Title { get { return (string)GetValue(TitleProperty); } diff --git a/Flow.Launcher/Resources/Controls/CardGroup.xaml b/Flow.Launcher/Resources/Controls/CardGroup.xaml index 5ea9d1e60..f48bf4b6c 100644 --- a/Flow.Launcher/Resources/Controls/CardGroup.xaml +++ b/Flow.Launcher/Resources/Controls/CardGroup.xaml @@ -9,13 +9,13 @@ d:DesignHeight="300" d:DesignWidth="300"> Content { get { return (ObservableCollection)GetValue(ContentProperty); } @@ -16,6 +24,21 @@ public partial class CardGroup : UserControl 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(); From a4f7a47fbb8dff0cec8a7db8ea5bfcffd991277e Mon Sep 17 00:00:00 2001 From: DB P Date: Fri, 3 May 2024 06:53:14 +0900 Subject: [PATCH 25/74] Update Flow.Launcher/Languages/en.xaml Co-authored-by: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> --- Flow.Launcher/Languages/en.xaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 7aca36e22..9962646c6 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -158,7 +158,7 @@ Play a small sound when the search window opens Sound Effect Volume Adjust the volume of the sound effect - Flow Launcher can't play sound because "Windows Media Player" doesn't exist on your system. If you need sound, install WMP. + Sound effect is unavailable because Windows Media Player is missing. Please install it if you need sound effect. Animation Use Animation in UI Animation Speed From 336e9726829a0df0246c65e80b01869f2d1d59f0 Mon Sep 17 00:00:00 2001 From: Yusyuriv Date: Fri, 3 May 2024 05:05:41 +0600 Subject: [PATCH 26/74] Fully functional Hotkey pane in the settings window --- Flow.Launcher/CustomShortcutSetting.xaml.cs | 2 +- .../SettingsPaneGeneralViewModel.cs | 10 +- .../ViewModels/SettingsPaneHotkeyViewModel.cs | 134 +++ .../Views/SettingsPaneHotkey.xaml | 841 +++++++++--------- .../Views/SettingsPaneHotkey.xaml.cs | 31 +- .../SettingPages/Views/SettingsPaneTheme.xaml | 8 + 6 files changed, 558 insertions(+), 468 deletions(-) create mode 100644 Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs diff --git a/Flow.Launcher/CustomShortcutSetting.xaml.cs b/Flow.Launcher/CustomShortcutSetting.xaml.cs index 097d6a53b..880c49787 100644 --- a/Flow.Launcher/CustomShortcutSetting.xaml.cs +++ b/Flow.Launcher/CustomShortcutSetting.xaml.cs @@ -47,7 +47,7 @@ namespace Flow.Launcher } // Check if key is modified or adding a new one if (((update && originalKey != Key) || !update) - && viewModel.ShortcutExists(Key)) + && (viewModel?.ShortcutExists(Key) ?? false)) // TODO Remove this check after removing unused code from SettingWindow.xaml.cs { MessageBox.Show(InternationalizationManager.Instance.GetTranslation("duplicateShortcut")); return; diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs index e405ccc96..a9718a0ac 100644 --- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs +++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs @@ -7,7 +7,6 @@ using Flow.Launcher.Core; using Flow.Launcher.Core.Configuration; using Flow.Launcher.Core.Resource; using Flow.Launcher.Helper; -using Flow.Launcher.Infrastructure; using Flow.Launcher.Infrastructure.UserSettings; using Flow.Launcher.Plugin; using Flow.Launcher.Plugin.SharedModels; @@ -16,7 +15,7 @@ namespace Flow.Launcher.SettingPages.ViewModels; public partial class SettingsPaneGeneralViewModel : BaseModel { - public Settings Settings { get; set; } + public Settings Settings { get; } private readonly Updater _updater; private readonly IPortable _portable; @@ -150,13 +149,6 @@ public partial class SettingsPaneGeneralViewModel : BaseModel .Select(v => v.ToString()) .ToList(); - public List OpenResultModifiersList => new List - { - KeyConstant.Alt, - KeyConstant.Ctrl, - $"{KeyConstant.Ctrl}+{KeyConstant.Alt}" - }; - public List Languages => InternationalizationManager.Instance.LoadAvailableLanguages(); public IEnumerable MaxResultsRange => Enumerable.Range(2, 16); diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs new file mode 100644 index 000000000..f56c4a971 --- /dev/null +++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs @@ -0,0 +1,134 @@ +using System.Windows; +using CommunityToolkit.Mvvm.Input; +using Flow.Launcher.Core.Resource; +using Flow.Launcher.Helper; +using Flow.Launcher.Infrastructure; +using Flow.Launcher.Infrastructure.Hotkey; +using Flow.Launcher.Infrastructure.UserSettings; +using Flow.Launcher.Plugin; + +namespace Flow.Launcher.SettingPages.ViewModels; + +public partial class SettingsPaneHotkeyViewModel : BaseModel +{ + public Settings Settings { get; } + + public CustomPluginHotkey SelectedCustomPluginHotkey { get; set; } + public CustomShortcutModel SelectedCustomShortcut { get; set; } + + public string[] OpenResultModifiersList => new[] + { + KeyConstant.Alt, + KeyConstant.Ctrl, + $"{KeyConstant.Ctrl}+{KeyConstant.Alt}" + }; + + public SettingsPaneHotkeyViewModel(Settings settings) + { + Settings = settings; + } + + [RelayCommand] + private void SetTogglingHotkey(HotkeyModel hotkey) + { + HotKeyMapper.SetHotkey(hotkey, HotKeyMapper.OnToggleHotkey); + } + + [RelayCommand] + private void CustomHotkeyDelete() + { + var item = SelectedCustomPluginHotkey; + if (item is null) + { + MessageBox.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem")); + return; + } + + var result = MessageBox.Show( + string.Format( + InternationalizationManager.Instance.GetTranslation("deleteCustomHotkeyWarning"), item.Hotkey + ), + InternationalizationManager.Instance.GetTranslation("delete"), + MessageBoxButton.YesNo + ); + + if (result is MessageBoxResult.Yes) + { + Settings.CustomPluginHotkeys.Remove(item); + HotKeyMapper.RemoveHotkey(item.Hotkey); + } + } + + [RelayCommand] + private void CustomHotkeyEdit() + { + var item = SelectedCustomPluginHotkey; + if (item is null) + { + MessageBox.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem")); + return; + } + + var window = new CustomQueryHotkeySetting(null, Settings); + window.UpdateItem(item); + window.ShowDialog(); + } + + [RelayCommand] + private void CustomHotkeyAdd() + { + new CustomQueryHotkeySetting(null, Settings).ShowDialog(); + } + + [RelayCommand] + private void CustomShortcutDelete() + { + var item = SelectedCustomShortcut; + if (item is null) + { + MessageBox.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem")); + return; + } + + var result = MessageBox.Show( + string.Format( + InternationalizationManager.Instance.GetTranslation("deleteCustomShortcutWarning"), item.Key, item.Value + ), + InternationalizationManager.Instance.GetTranslation("delete"), + MessageBoxButton.YesNo + ); + + if (result is MessageBoxResult.Yes) + { + Settings.CustomShortcuts.Remove(item); + } + } + + [RelayCommand] + private void CustomShortcutEdit() + { + var item = SelectedCustomShortcut; + if (item is null) + { + MessageBox.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem")); + return; + } + + var window = new CustomShortcutSetting(item.Key, item.Value, null); + if (window.ShowDialog() is not true) return; + + var index = Settings.CustomShortcuts.IndexOf(item); + Settings.CustomShortcuts[index] = new CustomShortcutModel(window.Key, window.Value); + } + + [RelayCommand] + private void CustomShortcutAdd() + { + var window = new CustomShortcutSetting(null); + if (window.ShowDialog() is true) + { + var shortcut = new CustomShortcutModel(window.Key, window.Value); + Settings.CustomShortcuts.Add(shortcut); + } + } +} diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml index 7afb7bdc7..170b596f0 100644 --- a/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml +++ b/Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml @@ -1,472 +1,433 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + Title="{DynamicResource OpenContainFolderHotkey}" + Icon="" + Type="Inside"> + + + + + + + + + + + + + HotkeySettings="{Binding Settings}" + DefaultHotkey="Ctrl+I" + Hotkey="{Binding Settings.OpenContextMenuHotkey}" + ValidateKeyGesture="False" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + - - - - - - - - + HorizontalAlignment="Right" + VerticalAlignment="Top" + Orientation="Horizontal"> + + + + + + + + + + + + +  + + + - - - - - - - - - - - - - - - - -  - - -