mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Merge branch 'external_preview_plugin_support' into quicklook
This commit is contained in:
commit
b345944b0d
5 changed files with 154 additions and 69 deletions
|
|
@ -88,6 +88,38 @@ namespace Flow.Launcher.Core.Plugin
|
|||
}).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);
|
||||
}
|
||||
|
||||
static PluginManager()
|
||||
{
|
||||
// validate user directory
|
||||
|
|
|
|||
15
Flow.Launcher.Plugin/Interfaces/IAsyncExternalPreview.cs
Normal file
15
Flow.Launcher.Plugin/Interfaces/IAsyncExternalPreview.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
using System.Threading.Tasks;
|
||||
|
||||
namespace Flow.Launcher.Plugin
|
||||
{
|
||||
public interface IAsyncExternalPreview: IFeatures
|
||||
{
|
||||
public Task TogglePreviewAsync(string path);
|
||||
|
||||
public Task OpenPreviewAsync(string path, bool sendFailToast = true);
|
||||
|
||||
public Task ClosePreviewAsync();
|
||||
|
||||
public Task SwitchPreviewAsync(string path, bool sendFailToast = true);
|
||||
}
|
||||
}
|
||||
|
|
@ -399,7 +399,7 @@
|
|||
</StackPanel>
|
||||
<GridSplitter
|
||||
Grid.Column="1"
|
||||
Width="{Binding PreviewVisible, Converter={StaticResource SplitterConverter}}"
|
||||
Width="{Binding InternalPreviewVisible, Converter={StaticResource SplitterConverter}}"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Stretch"
|
||||
Background="Transparent"
|
||||
|
|
@ -409,7 +409,7 @@
|
|||
Grid.Column="2"
|
||||
VerticalAlignment="Stretch"
|
||||
Style="{DynamicResource PreviewArea}"
|
||||
Visibility="{Binding PreviewVisible, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
Visibility="{Binding InternalPreviewVisible, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<Border
|
||||
d:DataContext="{d:DesignInstance vm:ResultViewModel}"
|
||||
DataContext="{Binding SelectedItem, ElementName=ResultListBox}"
|
||||
|
|
|
|||
|
|
@ -502,7 +502,7 @@ namespace Flow.Launcher
|
|||
if (_settings.UseAnimation)
|
||||
await Task.Delay(100);
|
||||
|
||||
if (_settings.HideWhenDeactivated && !_viewModel.ExternalPreviewOpen)
|
||||
if (_settings.HideWhenDeactivated && !_viewModel.ExternalPreviewVisible)
|
||||
{
|
||||
_viewModel.Hide();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -572,39 +572,86 @@ namespace Flow.Launcher.ViewModel
|
|||
public string Image => Constant.QueryTextBoxIconImagePath;
|
||||
|
||||
public bool StartWithEnglishMode => Settings.AlwaysStartEn;
|
||||
|
||||
public bool PreviewVisible { get; set; } = false;
|
||||
|
||||
public int ResultAreaColumn { get; set; } = 1;
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Preview
|
||||
|
||||
// Not accurate
|
||||
public bool ExternalPreviewOpen { get; set; } = false;
|
||||
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, and this does not inform flow that
|
||||
// preview is no longer available.
|
||||
public bool ExternalPreviewVisible { get; set; } = false;
|
||||
|
||||
private void ShowPreview()
|
||||
{
|
||||
var useExternalPreview = PluginManager.UseExternalPreview();
|
||||
|
||||
if (!useExternalPreview)
|
||||
ShowInternalPreview();
|
||||
|
||||
if (useExternalPreview)
|
||||
{
|
||||
// Internal preview may still be on when user switches to external
|
||||
if (InternalPreviewVisible)
|
||||
HideInternalPreview();
|
||||
|
||||
if (CanExternalPreviewSelectedResult(out var path))
|
||||
OpenExternalPreview(path);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void HidePreview()
|
||||
{
|
||||
if (PluginManager.UseExternalPreview())
|
||||
CloseExternalPreview();
|
||||
|
||||
if (InternalPreviewVisible)
|
||||
HideInternalPreview();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void TogglePreview()
|
||||
{
|
||||
if (PreviewVisible)
|
||||
switch (InternalPreviewVisible || ExternalPreviewVisible)
|
||||
{
|
||||
// To deal with always preview
|
||||
HideInternalPreview();
|
||||
}
|
||||
else if(Settings.UseExternalPreview && CanExternalPreviewSelectedResult(out var path))
|
||||
{
|
||||
_ = ToggleExternalPreviewAsync(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowInternalPreview();
|
||||
case true:
|
||||
HidePreview();
|
||||
break;
|
||||
|
||||
case false:
|
||||
ShowPreview();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void ToggleInternalPreview()
|
||||
{
|
||||
if (!PreviewVisible)
|
||||
if (!InternalPreviewVisible)
|
||||
{
|
||||
ShowInternalPreview();
|
||||
}
|
||||
|
|
@ -614,81 +661,72 @@ namespace Flow.Launcher.ViewModel
|
|||
}
|
||||
}
|
||||
|
||||
private async Task ToggleExternalPreviewAsync(string path)
|
||||
private void OpenExternalPreview(string path, bool sendFailToast = true)
|
||||
{
|
||||
bool success = await QuickLookHelper.ToggleQuickLookAsync(path).ConfigureAwait(false);
|
||||
if (success)
|
||||
{
|
||||
ExternalPreviewOpen = !ExternalPreviewOpen;
|
||||
}
|
||||
_ = PluginManager.OpenExternalPreviewAsync(path, sendFailToast).ConfigureAwait(false);
|
||||
ExternalPreviewVisible = true;
|
||||
}
|
||||
|
||||
private async Task OpenExternalPreviewAsync(string path, bool sendFailToast = true)
|
||||
private void CloseExternalPreview()
|
||||
{
|
||||
bool success = await QuickLookHelper.OpenQuickLookAsync(path, sendFailToast).ConfigureAwait(false);
|
||||
if (success)
|
||||
{
|
||||
ExternalPreviewOpen = false;
|
||||
}
|
||||
_ = PluginManager.CloseExternalPreviewAsync().ConfigureAwait(false);
|
||||
ExternalPreviewVisible = false;
|
||||
}
|
||||
|
||||
private async Task CloseExternalPreviewAsync()
|
||||
private void SwitchExternalPreview(string path, bool sendFailToast = true)
|
||||
{
|
||||
bool success = await QuickLookHelper.CloseQuickLookAsync().ConfigureAwait(false);
|
||||
if (success)
|
||||
{
|
||||
ExternalPreviewOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SwitchExternalPreviewAsync(string path, bool sendFailToast = true)
|
||||
{
|
||||
// Switches preview content
|
||||
// When external is off, do nothing
|
||||
_ = QuickLookHelper.SwitchQuickLookAsync(path, sendFailToast).ConfigureAwait(false);
|
||||
_ = PluginManager.SwitchExternalPreviewAsync(path,sendFailToast).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private void ShowInternalPreview()
|
||||
{
|
||||
ResultAreaColumn = 1;
|
||||
PreviewVisible = true;
|
||||
ResultAreaColumn = ResultAreaColumnPreviewShown;
|
||||
Results.SelectedItem?.LoadPreviewImage();
|
||||
}
|
||||
|
||||
private void HideInternalPreview()
|
||||
{
|
||||
ResultAreaColumn = 3;
|
||||
PreviewVisible = false;
|
||||
ResultAreaColumn = ResultAreaColumnPreviewHidden;
|
||||
}
|
||||
|
||||
public void ResetPreview()
|
||||
{
|
||||
if (Settings.AlwaysPreview == true && !PreviewVisible)
|
||||
switch (Settings.AlwaysPreview)
|
||||
{
|
||||
ShowInternalPreview();
|
||||
}
|
||||
else
|
||||
{
|
||||
HideInternalPreview();
|
||||
case true:
|
||||
ShowPreview();
|
||||
break;
|
||||
|
||||
case false:
|
||||
HidePreview();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdatePreview()
|
||||
{
|
||||
if (PreviewVisible)
|
||||
if (InternalPreviewVisible)
|
||||
{
|
||||
Results.SelectedItem?.LoadPreviewImage();
|
||||
return;
|
||||
}
|
||||
else if (Settings.UseExternalPreview)
|
||||
|
||||
switch (PluginManager.UseExternalPreview())
|
||||
{
|
||||
if (CanExternalPreviewSelectedResult(out var path))
|
||||
{
|
||||
_ = SwitchExternalPreviewAsync(path, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
_ = CloseExternalPreviewAsync();
|
||||
}
|
||||
case true
|
||||
when ExternalPreviewVisible && CanExternalPreviewSelectedResult(out var path):
|
||||
SwitchExternalPreview(path, false);
|
||||
break;
|
||||
|
||||
case true
|
||||
when !ExternalPreviewVisible && Settings.AlwaysPreview && CanExternalPreviewSelectedResult(out var path):
|
||||
ShowPreview();
|
||||
break;
|
||||
|
||||
case true
|
||||
when !CanExternalPreviewSelectedResult(out var _):
|
||||
HidePreview();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1104,8 +1142,8 @@ namespace Flow.Launcher.ViewModel
|
|||
// Trick for no delay
|
||||
MainWindowOpacity = 0;
|
||||
|
||||
if (Settings.UseExternalPreview)
|
||||
_ = CloseExternalPreviewAsync();
|
||||
if (ExternalPreviewVisible)
|
||||
CloseExternalPreview();
|
||||
|
||||
if (!SelectedIsFromQueryResults())
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue