Merge pull request #2679 from onesounds/240430PreviewSetting

Improve Explorer Preview Panel
This commit is contained in:
DB P 2024-05-25 09:41:19 +09:00 committed by GitHub
commit 3436c57f93
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 437 additions and 29 deletions

View file

@ -204,7 +204,7 @@ namespace Flow.Launcher.Plugin
Score = Score,
TitleHighlightData = TitleHighlightData,
OriginQuery = OriginQuery,
PluginDirectory = PluginDirectory
PluginDirectory = PluginDirectory,
};
}
@ -258,7 +258,7 @@ namespace Flow.Launcher.Plugin
public string ProgressBarColor { get; set; } = "#26a0da";
/// <summary>
/// Contains data used to populate the the preview section of this result.
/// Contains data used to populate the preview section of this result.
/// </summary>
public PreviewInfo Preview { get; set; } = PreviewInfo.Default;

View file

@ -417,4 +417,8 @@
<system:String x:Key="RecommendAcronyms">sn</system:String>
<system:String x:Key="RecommendAcronymsDesc">Sticky Notes</system:String>
<!-- Preview Area -->
<system:String x:Key="FileSize">File Size</system:String>
<system:String x:Key="Created">Created</system:String>
<system:String x:Key="LastModified">Last Modified</system:String>
</ResourceDictionary>

View file

@ -7,6 +7,7 @@
xmlns:flowlauncher="clr-namespace:Flow.Launcher"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:ui="http://schemas.modernwpf.com/2019"
xmlns:vm="clr-namespace:Flow.Launcher.ViewModel"
Name="FlowMainWindow"
@ -514,4 +515,4 @@
</StackPanel>
</Border>
</Grid>
</Window>
</Window>

View file

@ -29,6 +29,12 @@
<system:String x:Key="plugin_explorer_manageactionkeywords_header">Customise Action Keywords</system:String>
<system:String x:Key="plugin_explorer_quickaccesslinks_header">Quick Access Links</system:String>
<system:String x:Key="plugin_explorer_everything_setting_header">Everything Setting</system:String>
<system:String x:Key="plugin_explorer_previewpanel_setting_header">Preview Panel</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_size_checkbox">Size</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_creation_checkbox">Creation date</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_modification_checkbox">Modification date</system:String>
<system:String x:Key="plugin_explorer_previewpanel_file_info_label">Display File Info</system:String>
<system:String x:Key="plugin_explorer_previewpanel_date_and_time_format_label">Date and time format</system:String>
<system:String x:Key="plugin_explorer_everything_sort_option">Sort Option:</system:String>
<system:String x:Key="plugin_explorer_everything_installed_path">Everything Path:</system:String>
<system:String x:Key="plugin_explorer_launch_hidden">Launch Hidden</system:String>
@ -105,10 +111,11 @@
<system:String x:Key="plugin_explorer_openwith">Open With</system:String>
<system:String x:Key="plugin_explorer_openwith_subtitle">Select a program to open with</system:String>
<!-- Special Results-->
<!-- Special Results -->
<system:String x:Key="plugin_explorer_diskfreespace">{0} free of {1}</system:String>
<system:String x:Key="plugin_explorer_openresultfolder">Open in Default File Manager</system:String>
<system:String x:Key="plugin_explorer_openresultfolder_subtitle">Use '>' to search in this directory, '*' to search for file extensions or '>*' to combine both searches.</system:String>
<system:String x:Key="plugin_explorer_openresultfolder_subtitle">
Use '>' to search in this directory, '*' to search for file extensions or '>*' to combine both searches.</system:String>
<!-- Everything -->
<system:String x:Key="flowlauncher_plugin_everything_sdk_issue">Failed to load Everything SDK</system:String>
@ -133,7 +140,7 @@
<system:String x:Key="flowlauncher_plugin_everything_nonfastsort_warning">Warning: This is not a Fast Sort option, searches may be slow</system:String>
<system:String x:Key="flowlauncher_plugin_everything_search_fullpath">Search Full Path</system:String>
<system:String x:Key="flowlauncher_plugin_everything_click_to_launch_or_install">Click to launch or install Everything</system:String>
<system:String x:Key="flowlauncher_plugin_everything_installing_title">Everything Installation</system:String>
<system:String x:Key="flowlauncher_plugin_everything_installing_subtitle">Installing Everything service. Please wait...</system:String>

View file

@ -8,11 +8,15 @@ using System.Threading.Tasks;
using System.Windows;
using Flow.Launcher.Plugin.Explorer.Search.Everything;
using System.Windows.Input;
using Path = System.IO.Path;
using System.Windows.Controls;
using Flow.Launcher.Plugin.Explorer.Views;
namespace Flow.Launcher.Plugin.Explorer.Search
{
public static class ResultManager
{
private static readonly string[] SizeUnits = { "B", "KB", "MB", "GB", "TB" };
private static PluginInitContext Context;
private static Settings Settings { get; set; }
@ -172,36 +176,28 @@ namespace Flow.Launcher.Plugin.Explorer.Search
};
}
private static string ToReadableSize(long pDrvSize, int pi)
internal static string ToReadableSize(long sizeOnDrive, int pi)
{
int mok = 0;
double drvSize = pDrvSize;
string uom = "Byte"; // Unit Of Measurement
var unitIndex = 0;
double readableSize = sizeOnDrive;
while (drvSize > 1024.0)
while (readableSize > 1024.0 && unitIndex < SizeUnits.Length - 1)
{
drvSize /= 1024.0;
mok++;
readableSize /= 1024.0;
unitIndex++;
}
if (mok == 1)
uom = "KB";
else if (mok == 2)
uom = " MB";
else if (mok == 3)
uom = " GB";
else if (mok == 4)
uom = " TB";
var unit = SizeUnits[unitIndex] ?? "";
var returnStr = $"{Convert.ToInt32(drvSize)}{uom}";
if (mok != 0)
var returnStr = $"{Convert.ToInt32(readableSize)} {unit}";
if (unitIndex != 0)
{
returnStr = pi switch
{
1 => $"{drvSize:F1}{uom}",
2 => $"{drvSize:F2}{uom}",
3 => $"{drvSize:F3}{uom}",
_ => $"{Convert.ToInt32(drvSize)}{uom}"
1 => $"{readableSize:F1} {unit}",
2 => $"{readableSize:F2} {unit}",
3 => $"{readableSize:F3} {unit}",
_ => $"{Convert.ToInt32(readableSize)} {unit}"
};
}
@ -239,6 +235,9 @@ namespace Flow.Launcher.Plugin.Explorer.Search
var title = Path.GetFileName(filePath);
/* Preview Detail */
var result = new Result
{
Title = title,
@ -249,6 +248,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
TitleHighlightData = StringMatcher.FuzzySearch(query.Search, title).MatchData,
Score = score,
CopyText = filePath,
PreviewPanel = new Lazy<UserControl>(() => new PreviewPanel(Settings, filePath)),
Action = c =>
{
try

View file

@ -55,6 +55,16 @@ namespace Flow.Launcher.Plugin.Explorer
public bool WarnWindowsSearchServiceOff { get; set; } = true;
public bool ShowFileSizeInPreviewPanel { get; set; } = true;
public bool ShowCreatedDateInPreviewPanel { get; set; } = true;
public bool ShowModifiedDateInPreviewPanel { get; set; } = true;
public string PreviewPanelDateFormat { get; set; } = "yyyy-MM-dd";
public string PreviewPanelTimeFormat { get; set; } = "HH:mm";
private EverythingSearchManager _everythingManagerInstance;
private WindowsIndexSearchManager _windowsIndexSearchManager;
@ -137,7 +147,7 @@ namespace Flow.Launcher.Plugin.Explorer
ContentSearchEngine == ContentIndexSearchEngineOption.Everything;
public bool EverythingSearchFullPath { get; set; } = false;
#endregion
internal enum ActionKeyword

View file

@ -8,6 +8,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows;
@ -101,7 +102,107 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
#endregion
#region Preview Panel
public bool ShowFileSizeInPreviewPanel
{
get => Settings.ShowFileSizeInPreviewPanel;
set
{
Settings.ShowFileSizeInPreviewPanel = value;
OnPropertyChanged();
}
}
public bool ShowCreatedDateInPreviewPanel
{
get => Settings.ShowCreatedDateInPreviewPanel;
set
{
Settings.ShowCreatedDateInPreviewPanel = value;
OnPropertyChanged();
OnPropertyChanged(nameof(ShowPreviewPanelDateTimeChoices));
OnPropertyChanged(nameof(PreviewPanelDateTimeChoicesVisibility));
}
}
public bool ShowModifiedDateInPreviewPanel
{
get => Settings.ShowModifiedDateInPreviewPanel;
set
{
Settings.ShowModifiedDateInPreviewPanel = value;
OnPropertyChanged();
OnPropertyChanged(nameof(ShowPreviewPanelDateTimeChoices));
OnPropertyChanged(nameof(PreviewPanelDateTimeChoicesVisibility));
}
}
public string PreviewPanelDateFormat
{
get => Settings.PreviewPanelDateFormat;
set
{
Settings.PreviewPanelDateFormat = value;
OnPropertyChanged();
OnPropertyChanged(nameof(PreviewPanelDateFormatDemo));
}
}
public string PreviewPanelTimeFormat
{
get => Settings.PreviewPanelTimeFormat;
set
{
Settings.PreviewPanelTimeFormat = value;
OnPropertyChanged();
OnPropertyChanged(nameof(PreviewPanelTimeFormatDemo));
}
}
public string PreviewPanelDateFormatDemo => DateTime.Now.ToString(PreviewPanelDateFormat, CultureInfo.CurrentCulture);
public string PreviewPanelTimeFormatDemo => DateTime.Now.ToString(PreviewPanelTimeFormat, CultureInfo.CurrentCulture);
public bool ShowPreviewPanelDateTimeChoices => ShowCreatedDateInPreviewPanel || ShowModifiedDateInPreviewPanel;
public Visibility PreviewPanelDateTimeChoicesVisibility => ShowCreatedDateInPreviewPanel || ShowModifiedDateInPreviewPanel ? Visibility.Visible : Visibility.Collapsed;
public List<string> TimeFormatList { get; } = new()
{
"h:mm",
"hh:mm",
"H:mm",
"HH:mm",
"tt h:mm",
"tt hh:mm",
"h:mm tt",
"hh:mm tt",
"hh:mm:ss tt",
"HH:mm:ss"
};
public List<string> DateFormatList { get; } = new()
{
"dd/MM/yyyy",
"dd/MM/yyyy ddd",
"dd/MM/yyyy, dddd",
"dd-MM-yyyy",
"dd-MM-yyyy ddd",
"dd-MM-yyyy, dddd",
"dd.MM.yyyy",
"dd.MM.yyyy ddd",
"dd.MM.yyyy, dddd",
"MM/dd/yyyy",
"MM/dd/yyyy ddd",
"MM/dd/yyyy, dddd",
"yyyy-MM-dd",
"yyyy-MM-dd ddd",
"yyyy-MM-dd, dddd",
};
#endregion
#region ActionKeyword

View file

@ -348,6 +348,57 @@
</StackPanel>
</StackPanel>
</TabItem>
<TabItem
Width="Auto"
Header="{DynamicResource plugin_explorer_previewpanel_setting_header}"
Style="{DynamicResource ExplorerTabItem}">
<StackPanel Margin="30,20,0,10">
<TextBlock Foreground="{DynamicResource Color05B}" Text="{DynamicResource plugin_explorer_previewpanel_file_info_label}" />
<CheckBox
Margin="0,10,0,0"
Content="{DynamicResource plugin_explorer_previewpanel_display_file_size_checkbox}"
IsChecked="{Binding ShowFileSizeInPreviewPanel}" />
<CheckBox
Margin="0,10,0,0"
Content="{DynamicResource plugin_explorer_previewpanel_display_file_creation_checkbox}"
IsChecked="{Binding ShowCreatedDateInPreviewPanel}" />
<CheckBox
Margin="0,10,0,0"
Content="{DynamicResource plugin_explorer_previewpanel_display_file_modification_checkbox}"
IsChecked="{Binding ShowModifiedDateInPreviewPanel}" />
<StackPanel
Margin="0,20,0,0"
IsEnabled="{Binding ShowPreviewPanelDateTimeChoices}"
Visibility="{Binding PreviewPanelDateTimeChoicesVisibility}">
<TextBlock Foreground="{DynamicResource Color05B}" Text="{DynamicResource plugin_explorer_previewpanel_date_and_time_format_label}" />
<StackPanel Margin="0,10,0,0" Orientation="Horizontal">
<ComboBox
Width="200"
ItemsSource="{Binding DateFormatList}"
SelectedItem="{Binding PreviewPanelDateFormat}" />
<TextBlock
Margin="12,0,0,0"
VerticalAlignment="Center"
Foreground="{DynamicResource Color05B}"
Text="{Binding PreviewPanelDateFormatDemo}" />
</StackPanel>
<StackPanel Margin="0,10,0,10" Orientation="Horizontal">
<ComboBox
Width="200"
ItemsSource="{Binding TimeFormatList}"
SelectedItem="{Binding PreviewPanelTimeFormat}" />
<TextBlock
Margin="12,0,0,0"
VerticalAlignment="Center"
Foreground="{DynamicResource Color05B}"
Text="{Binding PreviewPanelTimeFormatDemo}" />
</StackPanel>
</StackPanel>
</StackPanel>
</TabItem>
<TabItem
Width="Auto"
Header="{DynamicResource plugin_explorer_everything_setting_header}"
@ -403,7 +454,7 @@
<TextBox
Grid.Row="2"
Grid.Column="1"
Width="250"
MinWidth="350"
Margin="0,15,0,0"
Text="{Binding EverythingInstalledPath}" />
</Grid>

View file

@ -0,0 +1,133 @@
<UserControl
x:Class="Flow.Launcher.Plugin.Explorer.Views.PreviewPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:sys="clr-namespace:System;assembly=System.Runtime"
d:DesignHeight="300"
d:DesignWidth="300"
mc:Ignorable="d">
<Grid
x:Name="PreviewGrid"
Margin="20 0 10 0"
VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" VerticalAlignment="Center">
<Image
Margin="0 16 0 0"
HorizontalAlignment="Stretch"
Source="{Binding PreviewImage, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"
StretchDirection="DownOnly">
<Image.Style>
<Style TargetType="Image">
<Setter Property="MaxWidth" Value="96" />
<Setter Property="MaxHeight" Value="320" />
<Style.Triggers>
<DataTrigger Binding="{Binding UseBigThumbnail}" Value="True">
<Setter Property="MaxWidth" Value="{Binding ElementName=PreviewGrid, Path=ActualWidth}" />
<Setter Property="MaxHeight" Value="{Binding ElementName=PreviewGrid, Path=ActualHeight}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<TextBlock
Margin="0 6 0 16"
HorizontalAlignment="Stretch"
Style="{DynamicResource PreviewItemTitleStyle}"
Text="{Binding Result.Title}"
TextAlignment="Center"
TextWrapping="Wrap" />
</StackPanel>
<StackPanel Grid.Row="1">
<StackPanel.Style>
<Style TargetType="StackPanel">
<Style.Triggers>
<DataTrigger Binding="{Binding Result.SubTitle.Length}" Value="0">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<Separator />
<TextBlock Style="{DynamicResource PreviewItemSubTitleStyle}" Text="{Binding Result.SubTitle}" />
<StackPanel Visibility="{Binding FileInfoVisibility, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}">
<Grid Margin="0 10 0 0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock
Grid.Row="0"
Grid.Column="0"
Margin="0 0 8 0"
VerticalAlignment="Top"
Style="{DynamicResource PreviewItemSubTitleStyle}"
Text="{DynamicResource FileSize}"
TextWrapping="Wrap"
Visibility="{Binding FileSizeVisibility, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" />
<TextBlock
Grid.Row="0"
Grid.Column="1"
Margin="0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Style="{DynamicResource PreviewItemSubTitleStyle}"
Text="{Binding FileSize, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"
TextWrapping="Wrap"
Visibility="{Binding FileSizeVisibility, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" />
<TextBlock
Grid.Row="1"
Grid.Column="0"
Margin="0 0 8 0"
VerticalAlignment="Top"
Style="{DynamicResource PreviewItemSubTitleStyle}"
Text="{DynamicResource Created}"
TextWrapping="Wrap"
Visibility="{Binding CreatedAtVisibility, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" />
<TextBlock
Grid.Row="1"
Grid.Column="1"
Margin="0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Style="{DynamicResource PreviewItemSubTitleStyle}"
Text="{Binding CreatedAt, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"
TextWrapping="Wrap"
Visibility="{Binding CreatedAtVisibility, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" />
<TextBlock
Grid.Row="2"
Grid.Column="0"
Margin="0 0 8 0"
VerticalAlignment="Top"
Style="{DynamicResource PreviewItemSubTitleStyle}"
Text="{DynamicResource LastModified}"
TextWrapping="Wrap"
Visibility="{Binding LastModifiedAtVisibility, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" />
<TextBlock
Grid.Row="2"
Grid.Column="1"
Margin="0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Style="{DynamicResource PreviewItemSubTitleStyle}"
Text="{Binding LastModifiedAt, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"
TextWrapping="Wrap"
Visibility="{Binding LastModifiedAtVisibility, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" />
</Grid>
</StackPanel>
</StackPanel>
</Grid>
</UserControl>

View file

@ -0,0 +1,101 @@
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Flow.Launcher.Infrastructure.Image;
using Flow.Launcher.Plugin.Explorer.Search;
namespace Flow.Launcher.Plugin.Explorer.Views;
#nullable enable
public partial class PreviewPanel : UserControl, INotifyPropertyChanged
{
private string FilePath { get; }
public string FileSize { get; } = "";
public string CreatedAt { get; } = "";
public string LastModifiedAt { get; } = "";
private ImageSource _previewImage = new BitmapImage();
private Settings Settings { get; }
public ImageSource PreviewImage
{
get => _previewImage;
private set
{
_previewImage = value;
OnPropertyChanged();
}
}
public Visibility FileSizeVisibility => Settings.ShowFileSizeInPreviewPanel
? Visibility.Visible
: Visibility.Collapsed;
public Visibility CreatedAtVisibility => Settings.ShowCreatedDateInPreviewPanel
? Visibility.Visible
: Visibility.Collapsed;
public Visibility LastModifiedAtVisibility => Settings.ShowModifiedDateInPreviewPanel
? Visibility.Visible
: Visibility.Collapsed;
public Visibility FileInfoVisibility =>
Settings.ShowFileSizeInPreviewPanel ||
Settings.ShowCreatedDateInPreviewPanel ||
Settings.ShowModifiedDateInPreviewPanel
? Visibility.Visible
: Visibility.Collapsed;
public PreviewPanel(Settings settings, string filePath)
{
InitializeComponent();
Settings = settings;
FilePath = filePath;
if (Settings.ShowFileSizeInPreviewPanel)
{
var fileSize = new FileInfo(filePath).Length;
FileSize = ResultManager.ToReadableSize(fileSize, 2);
}
if (Settings.ShowCreatedDateInPreviewPanel)
{
CreatedAt = File
.GetCreationTime(filePath)
.ToString(
$"{Settings.PreviewPanelDateFormat} {Settings.PreviewPanelTimeFormat}",
CultureInfo.CurrentCulture
);
}
if (Settings.ShowModifiedDateInPreviewPanel)
{
LastModifiedAt = File
.GetLastWriteTime(filePath)
.ToString(
$"{Settings.PreviewPanelDateFormat} {Settings.PreviewPanelTimeFormat}",
CultureInfo.CurrentCulture
);
}
_ = LoadImageAsync();
}
private async Task LoadImageAsync()
{
PreviewImage = await ImageLoader.LoadAsync(FilePath, true).ConfigureAwait(false);
}
public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}