diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj index 813a44527be..1e7f70b0a86 100644 --- a/Flow.Launcher/Flow.Launcher.csproj +++ b/Flow.Launcher/Flow.Launcher.csproj @@ -98,6 +98,7 @@ + @@ -120,7 +121,7 @@ - + diff --git a/Flow.Launcher/Resources/Dark.xaml b/Flow.Launcher/Resources/Dark.xaml index 445e07c6336..674e04debc2 100644 --- a/Flow.Launcher/Resources/Dark.xaml +++ b/Flow.Launcher/Resources/Dark.xaml @@ -69,6 +69,8 @@ + #272727 + #202020 #2b2b2b #1d1d1d diff --git a/Flow.Launcher/Resources/Light.xaml b/Flow.Launcher/Resources/Light.xaml index cee8b63cd94..8b04196dda0 100644 --- a/Flow.Launcher/Resources/Light.xaml +++ b/Flow.Launcher/Resources/Light.xaml @@ -62,6 +62,8 @@ + #f6f6f6 + #f3f3f3 #ffffff #e5e5e5 diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index 3c0905aa725..bfe061d7464 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -11,6 +11,7 @@ xmlns:ui="http://schemas.modernwpf.com/2019" xmlns:userSettings="clr-namespace:Flow.Launcher.Infrastructure.UserSettings;assembly=Flow.Launcher.Infrastructure" xmlns:vm="clr-namespace:Flow.Launcher.ViewModel" + xmlns:wpftk="clr-namespace:WpfToolkit.Controls;assembly=VirtualizingWrapPanel" Title="{DynamicResource flowlauncher_settings}" Width="{Binding SettingWindowWidth, Mode=TwoWay}" Height="{Binding SettingWindowHeight, Mode=TwoWay}" @@ -48,6 +49,18 @@ + + - + - - - - - - - - - - - - + Margin="4,0,0,0" + Padding="0,0,18,0" + ItemContainerStyle="{StaticResource StoreList}" + ItemsSource="{Binding ExternalPlugins}" + ScrollViewer.HorizontalScrollBarVisibility="Disabled" + SelectionMode="Single" + Style="{DynamicResource StoreListStyle}" + VirtualizingPanel.CacheLength="1,1" + VirtualizingPanel.CacheLengthUnit="Page" + VirtualizingPanel.IsVirtualizingWhenGrouping="True" + VirtualizingPanel.ScrollUnit="Pixel" + VirtualizingPanel.VirtualizationMode="Standard"> + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1763,7 +1677,9 @@ + ScrollViewer.CanContentScroll="True" + VirtualizingStackPanel.IsVirtualizing="True" + VirtualizingStackPanel.ScrollUnit="Pixel"> @@ -2339,14 +2255,16 @@ + ScrollViewer.CanContentScroll="True" + VirtualizingStackPanel.IsVirtualizing="True" + VirtualizingStackPanel.ScrollUnit="Pixel"> - + @@ -2510,7 +2428,7 @@ Click="OnAddCustomHotkeyClick" Content="{DynamicResource add}" /> - + + ScrollViewer.CanContentScroll="True" + VirtualizingStackPanel.IsVirtualizing="True" + VirtualizingStackPanel.ScrollUnit="Pixel"> @@ -2805,7 +2725,9 @@ + ScrollViewer.CanContentScroll="True" + VirtualizingStackPanel.IsVirtualizing="True" + VirtualizingStackPanel.ScrollUnit="Pixel"> (DependencyObject child) where T : DependencyObject { - _ = viewModel.RefreshExternalPluginsAsync(); - } + //get parent item + DependencyObject parentObject = VisualTreeHelper.GetParent(child); + + //we've reached the end of the tree + if (parentObject == null) return null; + //check if the parent matches the type we're looking for + T parent = parentObject as T; + if (parent != null) + return parent; + else + return FindParent(parentObject); + } + private void OnExternalPluginInstallClick(object sender, RoutedEventArgs e) { - if (sender is Button { DataContext: PluginStoreItemViewModel plugin }) + if (sender is not Button { DataContext: PluginStoreItemViewModel plugin } button) + { + return; + } + + if (storeClickedButton != null) { - viewModel.DisplayPluginQuery($"install {plugin.Name}", PluginManager.GetPluginForId("9f8f9b14-2518-4907-b211-35ab6290dee7")); + FlyoutService.GetFlyout(storeClickedButton).Hide(); } + + viewModel.DisplayPluginQuery($"install {plugin.Name}", PluginManager.GetPluginForId("9f8f9b14-2518-4907-b211-35ab6290dee7")); } private void OnExternalPluginUninstallClick(object sender, MouseButtonEventArgs e) @@ -317,18 +340,30 @@ private void OnExternalPluginUninstallClick(object sender, MouseButtonEventArgs viewModel.DisplayPluginQuery($"uninstall {name}", PluginManager.GetPluginForId("9f8f9b14-2518-4907-b211-35ab6290dee7")); } + } private void OnExternalPluginUninstallClick(object sender, RoutedEventArgs e) { + if (storeClickedButton != null) + { + FlyoutService.GetFlyout(storeClickedButton).Hide(); + } + if (sender is Button { DataContext: PluginStoreItemViewModel plugin }) viewModel.DisplayPluginQuery($"uninstall {plugin.Name}", PluginManager.GetPluginForId("9f8f9b14-2518-4907-b211-35ab6290dee7")); + } private void OnExternalPluginUpdateClick(object sender, RoutedEventArgs e) { + if (storeClickedButton != null) + { + FlyoutService.GetFlyout(storeClickedButton).Hide(); + } if (sender is Button { DataContext: PluginStoreItemViewModel plugin }) viewModel.DisplayPluginQuery($"update {plugin.Name}", PluginManager.GetPluginForId("9f8f9b14-2518-4907-b211-35ab6290dee7")); + } private void window_MouseDown(object sender, MouseButtonEventArgs e) /* for close hotkey popup */ @@ -541,5 +576,21 @@ public double WindowTop() return top; } + private Button storeClickedButton; + + private void StoreListItem_Click(object sender, RoutedEventArgs e) + { + if (sender is not Button button) + return; + + storeClickedButton = button; + + var flyout = FlyoutService.GetFlyout(button); + flyout.Closed += (_, _) => + { + storeClickedButton = null; + }; + + } } } diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs index 63b9c29c9f9..fa65205237f 100644 --- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs +++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs @@ -20,10 +20,11 @@ using Flow.Launcher.Plugin; using Flow.Launcher.Plugin.SharedModels; using System.Collections.ObjectModel; +using CommunityToolkit.Mvvm.Input; namespace Flow.Launcher.ViewModel { - public class SettingWindowViewModel : BaseModel + public partial class SettingWindowViewModel : BaseModel { private readonly Updater _updater; private readonly IPortable _portable; @@ -330,7 +331,8 @@ public Control SettingProvider } } - public async Task RefreshExternalPluginsAsync() + [RelayCommand] + private async Task RefreshExternalPluginsAsync() { await PluginsManifest.UpdateManifestAsync(); OnPropertyChanged(nameof(ExternalPlugins)); @@ -535,6 +537,8 @@ public Brush PreviewBackground var bitmap = new BitmapImage(); bitmap.BeginInit(); bitmap.StreamSource = memStream; + bitmap.DecodePixelWidth = 800; + bitmap.DecodePixelHeight = 600; bitmap.EndInit(); var brush = new ImageBrush(bitmap) {