mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Merge pull request #2082 from VictoriousRaptor/quicklook
Add external preview (QuickLook) support
This commit is contained in:
commit
ea65c8fcbb
9 changed files with 300 additions and 66 deletions
1
.github/actions/spelling/expect.txt
vendored
1
.github/actions/spelling/expect.txt
vendored
|
|
@ -98,6 +98,7 @@ Português
|
||||||
Português (Brasil)
|
Português (Brasil)
|
||||||
Italiano
|
Italiano
|
||||||
Slovenský
|
Slovenský
|
||||||
|
quicklook
|
||||||
Tiếng Việt
|
Tiếng Việt
|
||||||
Droplex
|
Droplex
|
||||||
Preinstalled
|
Preinstalled
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using Flow.Launcher.Core.ExternalPlugins;
|
using Flow.Launcher.Core.ExternalPlugins;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
@ -90,6 +90,48 @@ namespace Flow.Launcher.Core.Plugin
|
||||||
}).ToArray());
|
}).ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async Task OpenExternalPreviewAsync(string path, bool sendFailToast = true)
|
||||||
|
{
|
||||||
|
await Task.WhenAll(AllPlugins.Select(plugin => plugin.Plugin switch
|
||||||
|
{
|
||||||
|
IAsyncExternalPreview p => p.OpenPreviewAsync(path, sendFailToast),
|
||||||
|
_ => Task.CompletedTask,
|
||||||
|
}).ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task CloseExternalPreviewAsync()
|
||||||
|
{
|
||||||
|
await Task.WhenAll(AllPlugins.Select(plugin => plugin.Plugin switch
|
||||||
|
{
|
||||||
|
IAsyncExternalPreview p => p.ClosePreviewAsync(),
|
||||||
|
_ => Task.CompletedTask,
|
||||||
|
}).ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task SwitchExternalPreviewAsync(string path, bool sendFailToast = true)
|
||||||
|
{
|
||||||
|
await Task.WhenAll(AllPlugins.Select(plugin => plugin.Plugin switch
|
||||||
|
{
|
||||||
|
IAsyncExternalPreview p => p.SwitchPreviewAsync(path, sendFailToast),
|
||||||
|
_ => Task.CompletedTask,
|
||||||
|
}).ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool UseExternalPreview()
|
||||||
|
{
|
||||||
|
return GetPluginsForInterface<IAsyncExternalPreview>().Any(x => !x.Metadata.Disabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool AllowAlwaysPreview()
|
||||||
|
{
|
||||||
|
var plugin = GetPluginsForInterface<IAsyncExternalPreview>().FirstOrDefault(x => !x.Metadata.Disabled);
|
||||||
|
|
||||||
|
if (plugin is null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return ((IAsyncExternalPreview)plugin.Plugin).AllowAlwaysPreview();
|
||||||
|
}
|
||||||
|
|
||||||
static PluginManager()
|
static PluginManager()
|
||||||
{
|
{
|
||||||
// validate user directory
|
// validate user directory
|
||||||
|
|
|
||||||
|
|
@ -185,7 +185,9 @@ namespace Flow.Launcher.Infrastructure.UserSettings
|
||||||
/// when false Alphabet static service will always return empty results
|
/// when false Alphabet static service will always return empty results
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ShouldUsePinyin { get; set; } = false;
|
public bool ShouldUsePinyin { get; set; } = false;
|
||||||
|
|
||||||
public bool AlwaysPreview { get; set; } = false;
|
public bool AlwaysPreview { get; set; } = false;
|
||||||
|
|
||||||
public bool AlwaysStartEn { get; set; } = false;
|
public bool AlwaysStartEn { get; set; } = false;
|
||||||
|
|
||||||
private SearchPrecisionScore _querySearchPrecision = SearchPrecisionScore.Regular;
|
private SearchPrecisionScore _querySearchPrecision = SearchPrecisionScore.Regular;
|
||||||
|
|
|
||||||
40
Flow.Launcher.Plugin/Interfaces/IAsyncExternalPreview.cs
Normal file
40
Flow.Launcher.Plugin/Interfaces/IAsyncExternalPreview.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Flow.Launcher.Plugin
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This interface is for plugins that wish to provide file preview (external preview)
|
||||||
|
/// via a third party app instead of the default preview.
|
||||||
|
/// </summary>
|
||||||
|
public interface IAsyncExternalPreview : IFeatures
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Method for opening/showing the preview.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">The file path to open the preview for</param>
|
||||||
|
/// <param name="sendFailToast">Whether to send a toast message notification on failure for the user</param>
|
||||||
|
public Task OpenPreviewAsync(string path, bool sendFailToast = true);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Method for closing/hiding the preview.
|
||||||
|
/// </summary>
|
||||||
|
public Task ClosePreviewAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Method for switching the preview to the next file result.
|
||||||
|
/// This requires the external preview be already open/showing
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">The file path to switch the preview for</param>
|
||||||
|
/// <param name="sendFailToast">Whether to send a toast message notification on failure for the user</param>
|
||||||
|
public Task SwitchPreviewAsync(string path, bool sendFailToast = true);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Allows the preview plugin to override the AlwaysPreview setting. Typically useful if plugin's preview does not
|
||||||
|
/// fully work well with being shown together when the query window appears with results.
|
||||||
|
/// When AlwaysPreview setting is on and this is set to false, the preview will not be shown when query
|
||||||
|
/// window appears with results, instead the internal preview will be shown.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool AllowAlwaysPreview();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -270,12 +270,12 @@ namespace Flow.Launcher.Plugin
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Full image used for preview panel
|
/// Full image used for preview panel
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string PreviewImagePath { get; set; }
|
public string PreviewImagePath { get; set; } = null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if the preview image should occupy the full width of the preview panel.
|
/// Determines if the preview image should occupy the full width of the preview panel.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsMedia { get; set; }
|
public bool IsMedia { get; set; } = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Result description text that is shown at the bottom of the preview panel.
|
/// Result description text that is shown at the bottom of the preview panel.
|
||||||
|
|
@ -283,12 +283,17 @@ namespace Flow.Launcher.Plugin
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// When a value is not set, the <see cref="SubTitle"/> will be used.
|
/// When a value is not set, the <see cref="SubTitle"/> will be used.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public string Description { get; set; }
|
public string Description { get; set; } = null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Delegate to get the preview panel's image
|
/// Delegate to get the preview panel's image
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IconDelegate PreviewDelegate { get; set; }
|
public IconDelegate PreviewDelegate { get; set; } = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// File path of the result. For third-party programs providing external preview.
|
||||||
|
/// </summary>
|
||||||
|
public string FilePath { get; set; } = null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default instance of <see cref="PreviewInfo"/>
|
/// Default instance of <see cref="PreviewInfo"/>
|
||||||
|
|
@ -299,6 +304,7 @@ namespace Flow.Launcher.Plugin
|
||||||
Description = null,
|
Description = null,
|
||||||
IsMedia = false,
|
IsMedia = false,
|
||||||
PreviewDelegate = null,
|
PreviewDelegate = null,
|
||||||
|
FilePath = null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -427,7 +427,7 @@
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
Background="Transparent"
|
Background="Transparent"
|
||||||
ShowsPreview="True"
|
ShowsPreview="True"
|
||||||
Visibility="{Binding PreviewVisible, Converter={StaticResource BoolToVisibilityConverter}}">
|
Visibility="{Binding InternalPreviewVisible, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||||
<GridSplitter.Template>
|
<GridSplitter.Template>
|
||||||
<ControlTemplate TargetType="{x:Type GridSplitter}">
|
<ControlTemplate TargetType="{x:Type GridSplitter}">
|
||||||
<Border Style="{DynamicResource PreviewBorderStyle}" />
|
<Border Style="{DynamicResource PreviewBorderStyle}" />
|
||||||
|
|
@ -439,7 +439,7 @@
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
Style="{DynamicResource PreviewArea}"
|
Style="{DynamicResource PreviewArea}"
|
||||||
Visibility="{Binding PreviewVisible, Converter={StaticResource BoolToVisibilityConverter}}">
|
Visibility="{Binding InternalPreviewVisible, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||||
<Border
|
<Border
|
||||||
MinHeight="380"
|
MinHeight="380"
|
||||||
d:DataContext="{d:DesignInstance vm:ResultViewModel}"
|
d:DataContext="{d:DesignInstance vm:ResultViewModel}"
|
||||||
|
|
|
||||||
|
|
@ -630,7 +630,7 @@ namespace Flow.Launcher
|
||||||
if (_settings.UseAnimation)
|
if (_settings.UseAnimation)
|
||||||
await Task.Delay(100);
|
await Task.Delay(100);
|
||||||
|
|
||||||
if (_settings.HideWhenDeactivated)
|
if (_settings.HideWhenDeactivated && !_viewModel.ExternalPreviewVisible)
|
||||||
{
|
{
|
||||||
_viewModel.Hide();
|
_viewModel.Hide();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
@ -407,6 +407,10 @@ namespace Flow.Launcher.ViewModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region BasicCommands
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
private void OpenSetting()
|
private void OpenSetting()
|
||||||
{
|
{
|
||||||
|
|
@ -581,56 +585,6 @@ namespace Flow.Launcher.ViewModel
|
||||||
Settings.MaxResultsToShow -= 1;
|
Settings.MaxResultsToShow -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
|
||||||
public void TogglePreview()
|
|
||||||
{
|
|
||||||
if (!PreviewVisible)
|
|
||||||
{
|
|
||||||
ShowPreview();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HidePreview();
|
|
||||||
}
|
|
||||||
|
|
||||||
ContextMenu.IsPreviewOn = PreviewVisible;
|
|
||||||
History.IsPreviewOn = PreviewVisible;
|
|
||||||
Results.IsPreviewOn = PreviewVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ShowPreview()
|
|
||||||
{
|
|
||||||
ResultAreaColumn = 1;
|
|
||||||
PreviewVisible = true;
|
|
||||||
Results.SelectedItem?.LoadPreviewImage();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HidePreview()
|
|
||||||
{
|
|
||||||
ResultAreaColumn = 3;
|
|
||||||
PreviewVisible = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ResetPreview()
|
|
||||||
{
|
|
||||||
if (Settings.AlwaysPreview == true)
|
|
||||||
{
|
|
||||||
ShowPreview();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HidePreview();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdatePreview()
|
|
||||||
{
|
|
||||||
if (PreviewVisible)
|
|
||||||
{
|
|
||||||
Results.SelectedItem?.LoadPreviewImage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// we need move cursor to end when we manually changed query
|
/// we need move cursor to end when we manually changed query
|
||||||
/// but we don't want to move cursor to end when query is updated from TextBox
|
/// but we don't want to move cursor to end when query is updated from TextBox
|
||||||
|
|
@ -805,10 +759,186 @@ namespace Flow.Launcher.ViewModel
|
||||||
public string Image => Constant.QueryTextBoxIconImagePath;
|
public string Image => Constant.QueryTextBoxIconImagePath;
|
||||||
|
|
||||||
public bool StartWithEnglishMode => Settings.AlwaysStartEn;
|
public bool StartWithEnglishMode => Settings.AlwaysStartEn;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
public bool PreviewVisible { get; set; } = false;
|
#region Preview
|
||||||
|
|
||||||
public int ResultAreaColumn { get; set; } = 1;
|
public bool InternalPreviewVisible
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (ResultAreaColumn == ResultAreaColumnPreviewShown)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (ResultAreaColumn == ResultAreaColumnPreviewHidden)
|
||||||
|
return false;
|
||||||
|
#if DEBUG
|
||||||
|
throw new NotImplementedException("ResultAreaColumn should match ResultAreaColumnPreviewShown/ResultAreaColumnPreviewHidden value");
|
||||||
|
#else
|
||||||
|
Log.Error("MainViewModel", "ResultAreaColumnPreviewHidden/ResultAreaColumnPreviewShown int value not implemented", "InternalPreviewVisible");
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly int ResultAreaColumnPreviewShown = 1;
|
||||||
|
|
||||||
|
private static readonly int ResultAreaColumnPreviewHidden = 3;
|
||||||
|
|
||||||
|
public int ResultAreaColumn { get; set; } = ResultAreaColumnPreviewShown;
|
||||||
|
|
||||||
|
// This is not a reliable indicator of whether external preview is visible due to the
|
||||||
|
// ability of manually closing/exiting the external preview program which, does not inform flow that
|
||||||
|
// preview is no longer available.
|
||||||
|
public bool ExternalPreviewVisible { get; set; } = false;
|
||||||
|
|
||||||
|
private void ShowPreview()
|
||||||
|
{
|
||||||
|
var useExternalPreview = PluginManager.UseExternalPreview();
|
||||||
|
|
||||||
|
switch (useExternalPreview)
|
||||||
|
{
|
||||||
|
case true
|
||||||
|
when CanExternalPreviewSelectedResult(out var path):
|
||||||
|
// Internal preview may still be on when user switches to external
|
||||||
|
if (InternalPreviewVisible)
|
||||||
|
HideInternalPreview();
|
||||||
|
OpenExternalPreview(path);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case true
|
||||||
|
when !CanExternalPreviewSelectedResult(out var _):
|
||||||
|
if (ExternalPreviewVisible)
|
||||||
|
CloseExternalPreview();
|
||||||
|
ShowInternalPreview();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case false:
|
||||||
|
ShowInternalPreview();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HidePreview()
|
||||||
|
{
|
||||||
|
if (PluginManager.UseExternalPreview())
|
||||||
|
CloseExternalPreview();
|
||||||
|
|
||||||
|
if (InternalPreviewVisible)
|
||||||
|
HideInternalPreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
private void TogglePreview()
|
||||||
|
{
|
||||||
|
if (InternalPreviewVisible || ExternalPreviewVisible)
|
||||||
|
{
|
||||||
|
HidePreview();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ShowPreview();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ToggleInternalPreview()
|
||||||
|
{
|
||||||
|
if (!InternalPreviewVisible)
|
||||||
|
{
|
||||||
|
ShowInternalPreview();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HideInternalPreview();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenExternalPreview(string path, bool sendFailToast = true)
|
||||||
|
{
|
||||||
|
_ = PluginManager.OpenExternalPreviewAsync(path, sendFailToast).ConfigureAwait(false);
|
||||||
|
ExternalPreviewVisible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CloseExternalPreview()
|
||||||
|
{
|
||||||
|
_ = PluginManager.CloseExternalPreviewAsync().ConfigureAwait(false);
|
||||||
|
ExternalPreviewVisible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SwitchExternalPreview(string path, bool sendFailToast = true)
|
||||||
|
{
|
||||||
|
_ = PluginManager.SwitchExternalPreviewAsync(path,sendFailToast).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowInternalPreview()
|
||||||
|
{
|
||||||
|
ResultAreaColumn = ResultAreaColumnPreviewShown;
|
||||||
|
Results.SelectedItem?.LoadPreviewImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HideInternalPreview()
|
||||||
|
{
|
||||||
|
ResultAreaColumn = ResultAreaColumnPreviewHidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetPreview()
|
||||||
|
{
|
||||||
|
switch (Settings.AlwaysPreview)
|
||||||
|
{
|
||||||
|
case true
|
||||||
|
when PluginManager.AllowAlwaysPreview() && CanExternalPreviewSelectedResult(out var path):
|
||||||
|
OpenExternalPreview(path);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case true:
|
||||||
|
ShowInternalPreview();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case false:
|
||||||
|
HidePreview();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdatePreview()
|
||||||
|
{
|
||||||
|
switch (PluginManager.UseExternalPreview())
|
||||||
|
{
|
||||||
|
case true
|
||||||
|
when CanExternalPreviewSelectedResult(out var path):
|
||||||
|
if (ExternalPreviewVisible)
|
||||||
|
{
|
||||||
|
SwitchExternalPreview(path, false);
|
||||||
|
}
|
||||||
|
else if (InternalPreviewVisible)
|
||||||
|
{
|
||||||
|
HideInternalPreview();
|
||||||
|
OpenExternalPreview(path);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case true
|
||||||
|
when !CanExternalPreviewSelectedResult(out var _):
|
||||||
|
if (ExternalPreviewVisible)
|
||||||
|
{
|
||||||
|
CloseExternalPreview();
|
||||||
|
ShowInternalPreview();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case false
|
||||||
|
when InternalPreviewVisible:
|
||||||
|
Results.SelectedItem?.LoadPreviewImage();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CanExternalPreviewSelectedResult(out string path)
|
||||||
|
{
|
||||||
|
path = Results.SelectedItem?.Result?.Preview.FilePath;
|
||||||
|
return !string.IsNullOrEmpty(path);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
@ -1232,6 +1362,9 @@ namespace Flow.Launcher.ViewModel
|
||||||
lastContextMenuResult = new Result();
|
lastContextMenuResult = new Result();
|
||||||
lastContextMenuResults = new List<Result>();
|
lastContextMenuResults = new List<Result>();
|
||||||
|
|
||||||
|
if (ExternalPreviewVisible)
|
||||||
|
CloseExternalPreview();
|
||||||
|
|
||||||
if (!SelectedIsFromQueryResults())
|
if (!SelectedIsFromQueryResults())
|
||||||
{
|
{
|
||||||
SelectedResults = Results;
|
SelectedResults = Results;
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,10 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
||||||
AutoCompleteText = GetAutoCompleteText(title, query, path, ResultType.Folder),
|
AutoCompleteText = GetAutoCompleteText(title, query, path, ResultType.Folder),
|
||||||
TitleHighlightData = StringMatcher.FuzzySearch(query.Search, title).MatchData,
|
TitleHighlightData = StringMatcher.FuzzySearch(query.Search, title).MatchData,
|
||||||
CopyText = path,
|
CopyText = path,
|
||||||
|
Preview = new Result.PreviewInfo
|
||||||
|
{
|
||||||
|
FilePath = path,
|
||||||
|
},
|
||||||
Action = c =>
|
Action = c =>
|
||||||
{
|
{
|
||||||
if (c.SpecialKeyState.ToModifierKeys() == ModifierKeys.Alt)
|
if (c.SpecialKeyState.ToModifierKeys() == ModifierKeys.Alt)
|
||||||
|
|
@ -192,6 +196,10 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
||||||
Score = 500,
|
Score = 500,
|
||||||
ProgressBar = progressValue,
|
ProgressBar = progressValue,
|
||||||
ProgressBarColor = progressBarColor,
|
ProgressBarColor = progressBarColor,
|
||||||
|
Preview = new Result.PreviewInfo
|
||||||
|
{
|
||||||
|
FilePath = path,
|
||||||
|
},
|
||||||
Action = _ =>
|
Action = _ =>
|
||||||
{
|
{
|
||||||
OpenFolder(path);
|
OpenFolder(path);
|
||||||
|
|
@ -261,10 +269,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
||||||
|
|
||||||
internal static Result CreateFileResult(string filePath, Query query, int score = 0, bool windowsIndexed = false)
|
internal static Result CreateFileResult(string filePath, Query query, int score = 0, bool windowsIndexed = false)
|
||||||
{
|
{
|
||||||
Result.PreviewInfo preview = IsMedia(Path.GetExtension(filePath))
|
bool isMedia = IsMedia(Path.GetExtension(filePath));
|
||||||
? new Result.PreviewInfo { IsMedia = true, PreviewImagePath = filePath, }
|
|
||||||
: Result.PreviewInfo.Default;
|
|
||||||
|
|
||||||
var title = Path.GetFileName(filePath);
|
var title = Path.GetFileName(filePath);
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -275,7 +280,12 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
||||||
Title = title,
|
Title = title,
|
||||||
SubTitle = Path.GetDirectoryName(filePath),
|
SubTitle = Path.GetDirectoryName(filePath),
|
||||||
IcoPath = filePath,
|
IcoPath = filePath,
|
||||||
Preview = preview,
|
Preview = new Result.PreviewInfo
|
||||||
|
{
|
||||||
|
IsMedia = isMedia,
|
||||||
|
PreviewImagePath = isMedia ? filePath : null,
|
||||||
|
FilePath = filePath,
|
||||||
|
},
|
||||||
AutoCompleteText = GetAutoCompleteText(title, query, filePath, ResultType.File),
|
AutoCompleteText = GetAutoCompleteText(title, query, filePath, ResultType.File),
|
||||||
TitleHighlightData = StringMatcher.FuzzySearch(query.Search, title).MatchData,
|
TitleHighlightData = StringMatcher.FuzzySearch(query.Search, title).MatchData,
|
||||||
Score = score,
|
Score = score,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue