Finish animation and PDF viewer, still need refinement

This commit is contained in:
Paddy Xu
2017-04-12 23:28:12 +03:00
parent 7e2001bc4d
commit 7388c3874a
27 changed files with 252 additions and 170 deletions

View File

@@ -15,7 +15,7 @@
<ProjectGuid>{D31EE321-C2B0-4984-B749-736F7DE509F1}</ProjectGuid> <ProjectGuid>{D31EE321-C2B0-4984-B749-736F7DE509F1}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>QuickLookShell32Helper</RootNamespace> <RootNamespace>QuickLookShell32Helper</RootNamespace>
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
<ProjectName>QuickLook.Native.Shell32</ProjectName> <ProjectName>QuickLook.Native.Shell32</ProjectName>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

View File

@@ -47,17 +47,19 @@ void Shell32::GetCurrentSelectionBuffer(PWCHAR buffer)
wcscpy_s(pos - 1, 1, L""); wcscpy_s(pos - 1, 1, L"");
} }
void Shell32::SaveSelectedFromExplorer() { void Shell32::SaveSelectedFromExplorer()
{
CoInitialize(nullptr); CoInitialize(nullptr);
CComPtr<IShellWindows> psw; CComPtr<IShellWindows> psw;
HRESULT ret=psw.CoCreateInstance(CLSID_ShellWindows); HRESULT ret = psw.CoCreateInstance(CLSID_ShellWindows);
auto hwndFGW = GetForegroundWindow(); auto hwndFGW = GetForegroundWindow();
auto fFound = FALSE; auto fFound = FALSE;
for (int i = 0; !fFound; i++) { for (int i = 0; !fFound; i++)
{
VARIANT vi; VARIANT vi;
V_VT(&vi) = VT_I4; V_VT(&vi) = VT_I4;
V_I4(&vi) = i; V_I4(&vi) = i;
@@ -67,13 +69,16 @@ void Shell32::SaveSelectedFromExplorer() {
if (SUCCEEDED(psw->Item(vi, &pdisp))) if (SUCCEEDED(psw->Item(vi, &pdisp)))
{ {
CComPtr<IWebBrowserApp> pwba; CComPtr<IWebBrowserApp> pwba;
if (SUCCEEDED(pdisp->QueryInterface(IID_IWebBrowserApp, reinterpret_cast<void**>(&pwba)))) { if (SUCCEEDED(pdisp->QueryInterface(IID_IWebBrowserApp, reinterpret_cast<void**>(&pwba))))
{
HWND hwndWBA; HWND hwndWBA;
if (SUCCEEDED(pwba->get_HWND(reinterpret_cast<LONG_PTR*>(&hwndWBA))) && hwndWBA == hwndFGW) { if (SUCCEEDED(pwba->get_HWND(reinterpret_cast<LONG_PTR*>(&hwndWBA))) && hwndWBA == hwndFGW)
{
fFound = TRUE; fFound = TRUE;
CComPtr<IDispatch> ppdisp; CComPtr<IDispatch> ppdisp;
if (SUCCEEDED(pwba->get_Document(&ppdisp))) { if (SUCCEEDED(pwba->get_Document(&ppdisp)))
{
CComPtr<IShellFolderViewDual2> pshvd; CComPtr<IShellFolderViewDual2> pshvd;
if (SUCCEEDED(ppdisp->QueryInterface(IID_IShellFolderViewDual2, reinterpret_cast<void**>(&pshvd)))) if (SUCCEEDED(ppdisp->QueryInterface(IID_IShellFolderViewDual2, reinterpret_cast<void**>(&pshvd))))
{ {
@@ -120,7 +125,7 @@ CComQIPtr<IWebBrowser2> Shell32::AttachDesktopShellWindow()
if (SUCCEEDED(psw.CoCreateInstance(CLSID_ShellWindows))) if (SUCCEEDED(psw.CoCreateInstance(CLSID_ShellWindows)))
{ {
VARIANT pvarLoc = { VT_EMPTY }; VARIANT pvarLoc = {VT_EMPTY};
long phwnd; long phwnd;
psw->FindWindowSW(&pvarLoc, &pvarLoc, SWC_DESKTOP, &phwnd, SWFO_NEEDDISPATCH, reinterpret_cast<IDispatch**>(&pdispOut)); psw->FindWindowSW(&pvarLoc, &pvarLoc, SWC_DESKTOP, &phwnd, SWFO_NEEDDISPATCH, reinterpret_cast<IDispatch**>(&pdispOut));
} }
@@ -135,10 +140,10 @@ void Shell32::SaveSelectedFromDesktop()
return; return;
CComQIPtr<IServiceProvider> psp(pWebBrowser2); CComQIPtr<IServiceProvider> psp(pWebBrowser2);
CComPtr<IShellBrowser> psb; CComPtr<IShellBrowser> psb;
CComPtr<IShellView> psv; CComPtr<IShellView> psv;
CComPtr<IFolderView> pfv; CComPtr<IFolderView> pfv;
CComPtr<IPersistFolder2> ppf2; CComPtr<IPersistFolder2> ppf2;
if (!psp) return; if (!psp) return;
@@ -164,7 +169,8 @@ void Shell32::SaveSelectedFromDesktop()
} }
} }
void Shell32::vectorFromDataObject(CComPtr<IDataObject> dao) { void Shell32::vectorFromDataObject(CComPtr<IDataObject> dao)
{
FORMATETC formatetc; FORMATETC formatetc;
STGMEDIUM medium; STGMEDIUM medium;

View File

@@ -26,4 +26,3 @@ private:
static CComQIPtr<IWebBrowser2> AttachDesktopShellWindow(); static CComQIPtr<IWebBrowser2> AttachDesktopShellWindow();
static void vectorFromDataObject(CComPtr<IDataObject> dao); static void vectorFromDataObject(CComPtr<IDataObject> dao);
}; };

View File

@@ -2,7 +2,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "Shell32.h" #include "Shell32.h"
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{ {
switch (ul_reason_for_call) switch (ul_reason_for_call)
{ {
@@ -15,4 +15,3 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReser
} }
return TRUE; return TRUE;
} }

View File

@@ -12,7 +12,6 @@
#include <windows.h> #include <windows.h>
// TODO: reference additional headers your program requires here // TODO: reference additional headers your program requires here
#include<atlcomcli.h> #include<atlcomcli.h>
#include<Exdisp.h> #include<Exdisp.h>

View File

@@ -1,52 +1,40 @@
using System; using System.Linq;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Threading;
using MoonPdfLib; using MoonPdfLib;
using QuickLook.ExtensionMethods;
namespace QuickLook.Plugin.PDFViewer namespace QuickLook.Plugin.PDFViewer
{ {
public class Class1:IViewer public class Class1 : IViewer
{ {
public bool CanView(string path, byte[] sample) public PluginType Type => PluginType.ByExtension | PluginType.ByContent;
public string[] SupportExtensions => new[] {".pdf"};
public bool CheckSupportByContent(byte[] sample)
{ {
if (String.IsNullOrEmpty(path)) return Encoding.ASCII.GetString(sample.Take(4).ToArray()) == "%PDF";
return false;
if (Path.GetExtension(path).ToLower() == ".pdf")
return true;
if (Encoding.ASCII.GetString(sample.Take(4).ToArray()) == "%PDF")
return true;
return false;
} }
public void View(string path, ViewContentContainer container) public void View(string path, ViewContentContainer container)
{ {
MoonPdfPanel pdfPanel = new MoonPdfPanel var pdfPanel = new MoonPdfPanel
{ {
ViewType = ViewType.SinglePage, ViewType = ViewType.SinglePage,
PageRowDisplay = PageRowDisplayType.ContinuousPageRows, PageRowDisplay = PageRowDisplayType.ContinuousPageRows,
PageMargin = new System.Windows.Thickness(0, 2, 4, 2), PageMargin = new Thickness(0, 2, 4, 2),
Background = new SolidColorBrush(Colors.LightGray) Background = new SolidColorBrush(Colors.LightGray)
}; };
container.SetContent(pdfPanel); container.SetContent(pdfPanel);
Task.Delay(200).ContinueWith(t => container.Dispatcher.Invoke(() => pdfPanel.OpenFile(path))); container.Dispatcher.Delay(100, o => pdfPanel.OpenFile(path));
//container.Dispatcher.Delay(200, o => pdfPanel.ZoomToWidth());
Task.Delay(400).ContinueWith(t => container.Dispatcher.Invoke(() => pdfPanel.ZoomToWidth()));
} }
public void Close() public void Close()
{ {
return;
} }
} }
} }

View File

@@ -1,5 +1,4 @@
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following // General Information about an assembly is controlled through the following

View File

@@ -20,6 +20,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants> <DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>

View File

@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="MoonPdfLib-x86" version="0.3.0" targetFramework="net452" /> <package id="MoonPdfLib-x86" version="0.3.0" targetFramework="net452" />
</packages> </packages>

View File

@@ -14,46 +14,20 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.PDFViewer"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86 Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86 Release|x86 = Release|x86
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Debug|x64.ActiveCfg = Debug|Any CPU
{8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Debug|x64.Build.0 = Debug|Any CPU
{8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Debug|x86.ActiveCfg = Debug|Any CPU {8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Debug|x86.ActiveCfg = Debug|Any CPU
{8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Debug|x86.Build.0 = Debug|Any CPU {8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Debug|x86.Build.0 = Debug|Any CPU
{8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Release|Any CPU.Build.0 = Release|Any CPU
{8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Release|x64.ActiveCfg = Release|Any CPU
{8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Release|x64.Build.0 = Release|Any CPU
{8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Release|x86.ActiveCfg = Release|Any CPU {8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Release|x86.ActiveCfg = Release|Any CPU
{8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Release|x86.Build.0 = Release|Any CPU {8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Release|x86.Build.0 = Release|Any CPU
{D31EE321-C2B0-4984-B749-736F7DE509F1}.Debug|Any CPU.ActiveCfg = Debug|Win32
{D31EE321-C2B0-4984-B749-736F7DE509F1}.Debug|Any CPU.Build.0 = Debug|Win32
{D31EE321-C2B0-4984-B749-736F7DE509F1}.Debug|x64.ActiveCfg = Debug|Win32
{D31EE321-C2B0-4984-B749-736F7DE509F1}.Debug|x86.ActiveCfg = Debug|Win32 {D31EE321-C2B0-4984-B749-736F7DE509F1}.Debug|x86.ActiveCfg = Debug|Win32
{D31EE321-C2B0-4984-B749-736F7DE509F1}.Debug|x86.Build.0 = Debug|Win32 {D31EE321-C2B0-4984-B749-736F7DE509F1}.Debug|x86.Build.0 = Debug|Win32
{D31EE321-C2B0-4984-B749-736F7DE509F1}.Release|Any CPU.ActiveCfg = Release|Win32
{D31EE321-C2B0-4984-B749-736F7DE509F1}.Release|Any CPU.Build.0 = Release|Win32
{D31EE321-C2B0-4984-B749-736F7DE509F1}.Release|x64.ActiveCfg = Release|Win32
{D31EE321-C2B0-4984-B749-736F7DE509F1}.Release|x86.ActiveCfg = Release|Win32 {D31EE321-C2B0-4984-B749-736F7DE509F1}.Release|x86.ActiveCfg = Release|Win32
{D31EE321-C2B0-4984-B749-736F7DE509F1}.Release|x86.Build.0 = Release|Win32 {D31EE321-C2B0-4984-B749-736F7DE509F1}.Release|x86.Build.0 = Release|Win32
{A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Debug|x64.ActiveCfg = Debug|Any CPU
{A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Debug|x64.Build.0 = Debug|Any CPU
{A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Debug|x86.ActiveCfg = Debug|Any CPU {A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Debug|x86.ActiveCfg = Debug|Any CPU
{A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Debug|x86.Build.0 = Debug|Any CPU {A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Debug|x86.Build.0 = Debug|Any CPU
{A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Release|Any CPU.Build.0 = Release|Any CPU
{A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Release|x64.ActiveCfg = Release|Any CPU
{A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Release|x64.Build.0 = Release|Any CPU
{A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Release|x86.ActiveCfg = Release|Any CPU {A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Release|x86.ActiveCfg = Release|Any CPU
{A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Release|x86.Build.0 = Release|Any CPU {A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection

View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8"?>
<configuration> <configuration>
<startup> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" /> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup> </startup>
</configuration> </configuration>

View File

@@ -2,7 +2,8 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:QuickLook" xmlns:local="clr-namespace:QuickLook"
Startup="Application_Startup"> Startup="Application_Startup"
ShutdownMode="OnExplicitShutdown">
<Application.Resources> <Application.Resources>
</Application.Resources> </Application.Resources>

View File

@@ -1,19 +1,11 @@
using System; using System.IO;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks;
using System.Windows; using System.Windows;
using QuickLook.Plugin;
using QuickLook.Utilities;
namespace QuickLook namespace QuickLook
{ {
/// <summary> /// <summary>
/// Interaction logic for App.xaml /// Interaction logic for App.xaml
/// </summary> /// </summary>
public partial class App : Application public partial class App : Application
{ {

View File

@@ -1,5 +1,6 @@
using System.Text; using System;
using System.Threading; using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using QuickLook.Utilities; using QuickLook.Utilities;
@@ -18,16 +19,20 @@ namespace QuickLook
private void HotkeyEventHandler(object sender, KeyEventArgs e) private void HotkeyEventHandler(object sender, KeyEventArgs e)
{ {
string[] paths; var paths = new string[0];
// communicate with COM in a separate thread // communicate with COM in a separate thread
var tCom = new Thread(() => paths = GetCurrentSelection()); Task.Run(() => paths = GetCurrentSelection()).Wait();
tCom.Start(); var ddd = PathToPluginMatcher.FindMatch(paths);
tCom.Join();
var mw = new MainWindow(); var mw = new MainWindow();
ddd.View(paths[0], mw.ViewContentContainer);
mw.Show(); mw.Show();
mw.ShowFinishLoadingAnimation(TimeSpan.FromMilliseconds(200));
} }
private void InstallHook(KeyEventHandler handler) private void InstallHook(KeyEventHandler handler)

View File

@@ -4,7 +4,7 @@ using System.Windows.Threading;
namespace QuickLook.ExtensionMethods namespace QuickLook.ExtensionMethods
{ {
internal static class DispatcherExtensions public static class DispatcherExtensions
{ {
public static void Delay(this Dispatcher disp, int delayMs, public static void Delay(this Dispatcher disp, int delayMs,
Action<object> action, object parm = null) Action<object> action, object parm = null)

View File

@@ -9,21 +9,61 @@
xmlns:plugin="clr-namespace:QuickLook.Plugin" xmlns:plugin="clr-namespace:QuickLook.Plugin"
mc:Ignorable="d" x:Class="QuickLook.MainWindow" x:Name="mainWindow" AllowsTransparency="True" WindowStyle="None" mc:Ignorable="d" x:Class="QuickLook.MainWindow" x:Name="mainWindow" AllowsTransparency="True" WindowStyle="None"
UseLayoutRounding="True" UseLayoutRounding="True"
Topmost="True" d:DesignWidth="624" d:DesignHeight="700" Width="624" Height="700" WindowStartupLocation="CenterScreen" Topmost="True" d:DesignWidth="624" d:DesignHeight="700"
WindowStartupLocation="CenterScreen"
x:ClassModifier="internal"> x:ClassModifier="internal">
<Window.Background> <Window.Background>
<SolidColorBrush Color="#00FFFFFF" /> <SolidColorBrush Color="#00FFFFFF" />
</Window.Background> </Window.Background>
<Grid Name="WindowContainer"> <Grid Name="WindowContainer">
<Grid.Background> <Grid.Background>
<SolidColorBrush Color="#AAB0B0B0" /> <SolidColorBrush Color="#FFFFFFFF" />
</Grid.Background> </Grid.Background>
<Grid Name="LoadingIcon" Height="50" Width="50" HorizontalAlignment="Center" VerticalAlignment="Center" > <Grid>
<fa:ImageAwesome Icon="CircleOutlineNotch" Spin="True" SpinDuration="2" /> <Grid>
<plugin:ViewContentContainer x:Name="ViewContentContainer" Width="624" Height="700" />
</Grid>
<DockPanel Name="Titlebar" Height="40" VerticalAlignment="Top" Opacity="0">
<DockPanel.Background>
<SolidColorBrush Color="#FFFFFFFF" />
</DockPanel.Background>
<DockPanel.Style>
<Style TargetType="{x:Type DockPanel}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.1" Storyboard.TargetProperty="Opacity"
To="1" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.6" Storyboard.TargetProperty="Opacity"
To="0" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</DockPanel.Style>
<fa:ImageAwesome DockPanel.Dock="Right" Name="Close" Icon="WindowClose" Height="20" Margin="10,0"
Cursor="Hand" MouseLeftButtonUp="Close_MouseLeftButtonUp" />
<Label Content="Filename placeholder" FontSize="16" HorizontalContentAlignment="Center"
VerticalContentAlignment="Center" />
</DockPanel>
</Grid> </Grid>
<Grid Name="ContentContainer" Width="624" Height="700"> <Grid Name="LoadingIconLayer">
<plugin:ViewContentContainer x:Name="ViewContentContainer"/> <Grid.Background>
<SolidColorBrush Color="#FFFFFFFF" />
</Grid.Background>
<Grid Name="LoadingIcon" Height="50" Width="50" HorizontalAlignment="Center" VerticalAlignment="Center">
<fa:ImageAwesome Icon="CircleOutlineNotch" Spin="True" SpinDuration="2" />
</Grid>
</Grid> </Grid>
<Button Content="Button" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click" />
</Grid> </Grid>
</Window> </Window>

View File

@@ -1,35 +1,14 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Remoting.Channels;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Animation; using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading; using System.Windows.Threading;
using QuickLook.ExtensionMethods; using QuickLook.ExtensionMethods;
using QuickLook.Plugin;
using QuickLook.Utilities;
using MessageBox = System.Windows.MessageBox;
using Path = System.IO.Path;
namespace QuickLook namespace QuickLook
{ {
/// <summary> /// <summary>
/// Interaction logic for MainWindow.xaml /// Interaction logic for MainWindow.xaml
/// </summary> /// </summary>
internal partial class MainWindow : Window internal partial class MainWindow : Window
{ {
@@ -39,46 +18,83 @@ namespace QuickLook
WindowContainer.Width = LoadingIcon.Width; WindowContainer.Width = LoadingIcon.Width;
WindowContainer.Height = LoadingIcon.Height; WindowContainer.Height = LoadingIcon.Height;
ContentContainer.Visibility = Visibility.Hidden; ViewContentContainer.Opacity = 0;
} }
private void ZoomToPreferedSize() internal new void Show()
{ {
Storyboard sb = new Storyboard { }; Height = ViewContentContainer.Height;
ParallelTimeline ptl = new ParallelTimeline(); Width = ViewContentContainer.Width;
DoubleAnimation animationWidth = new DoubleAnimation base.Show();
}
internal void ShowFinishLoadingAnimation(TimeSpan delay = new TimeSpan())
{
var speed = 200;
var sb = new Storyboard();
var ptl = new ParallelTimeline {BeginTime = delay};
var aWidth = new DoubleAnimation
{ {
From = WindowContainer.Width, From = WindowContainer.Width,
To = ContentContainer.Width, To = ViewContentContainer.Width,
Duration = TimeSpan.FromSeconds(0.2), Duration = TimeSpan.FromMilliseconds(speed),
DecelerationRatio = 0.3 DecelerationRatio = 0.3
}; };
DoubleAnimation animationHeight = new DoubleAnimation var aHeight = new DoubleAnimation
{ {
From = WindowContainer.Height, From = WindowContainer.Height,
To = ContentContainer.Height, To = ViewContentContainer.Height,
Duration = TimeSpan.FromSeconds(0.2), Duration = TimeSpan.FromMilliseconds(speed),
DecelerationRatio = 0.3 DecelerationRatio = 0.3
}; };
Storyboard.SetTarget(animationWidth, WindowContainer); var aOpacity = new DoubleAnimation
Storyboard.SetTarget(animationHeight, WindowContainer); {
Storyboard.SetTargetProperty(animationWidth, new PropertyPath(WidthProperty)); From = 0,
Storyboard.SetTargetProperty(animationHeight, new PropertyPath(HeightProperty)); To = 1,
BeginTime = TimeSpan.FromMilliseconds(speed * 0.25),
Duration = TimeSpan.FromMilliseconds(speed * 0.75)
};
ptl.Children.Add(animationWidth); var aOpacityR = new DoubleAnimation
ptl.Children.Add(animationHeight); {
From = 1,
To = 0,
Duration = TimeSpan.FromMilliseconds(speed * 2)
};
Storyboard.SetTarget(aWidth, WindowContainer);
Storyboard.SetTarget(aHeight, WindowContainer);
Storyboard.SetTarget(aOpacity, ViewContentContainer);
Storyboard.SetTarget(aOpacityR, LoadingIconLayer);
Storyboard.SetTargetProperty(aWidth, new PropertyPath(WidthProperty));
Storyboard.SetTargetProperty(aHeight, new PropertyPath(HeightProperty));
Storyboard.SetTargetProperty(aOpacity, new PropertyPath(OpacityProperty));
Storyboard.SetTargetProperty(aOpacityR, new PropertyPath(OpacityProperty));
ptl.Children.Add(aWidth);
ptl.Children.Add(aHeight);
ptl.Children.Add(aOpacity);
ptl.Children.Add(aOpacityR);
sb.Children.Add(ptl); sb.Children.Add(ptl);
sb.Begin(); sb.Begin();
Dispatcher.DelayWithPriority(speed * 2, o => LoadingIconLayer.Visibility = Visibility.Hidden, null,
DispatcherPriority.Render);
} }
private void Button_Click(object sender, RoutedEventArgs e) private void Close_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{ {
ZoomToPreferedSize(); Close();
// useless code to make everyone happy
GC.Collect();
} }
} }
} }

View File

@@ -1,12 +1,58 @@
using System; using System.IO;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using QuickLook.Plugin;
using System.Threading.Tasks;
namespace QuickLook namespace QuickLook
{ {
class PathToPluginMatcher internal static class PathToPluginMatcher
{ {
internal static IViewer FindMatch(string[] paths)
{
if (paths.Length == 0)
return null;
//TODO: Handle multiple files?
var path = paths.First();
return FindByExtension(path) ?? FindByContent(path);
}
private static IViewer FindByExtension(string path)
{
if (string.IsNullOrEmpty(path))
return null;
var ext = Path.GetExtension(path).ToLower();
return PluginManager.GetInstance()
.LoadedPlugins.FirstOrDefault(plugin =>
{
if ((plugin.Type & PluginType.ByExtension) == 0)
return false;
return plugin.SupportExtensions.Any(e => e == ext);
});
}
private static IViewer FindByContent(string path)
{
if (string.IsNullOrEmpty(path))
return null;
byte[] sample;
using (var br = new BinaryReader(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
{
sample = br.ReadBytes(256);
}
return PluginManager.GetInstance()
.LoadedPlugins.FirstOrDefault(plugin =>
{
if ((plugin.Type & PluginType.ByContent) == 0)
return false;
return plugin.CheckSupportByContent(sample);
});
}
} }
} }

View File

@@ -2,7 +2,9 @@
{ {
public interface IViewer public interface IViewer
{ {
bool CanView(string path, byte[] sample); PluginType Type { get; }
string[] SupportExtensions { get; }
bool CheckSupportByContent(byte[] sample);
void View(string path, ViewContentContainer container); void View(string path, ViewContentContainer container);
void Close(); void Close();
} }

View File

@@ -0,0 +1,11 @@
using System;
namespace QuickLook.Plugin
{
[Flags]
public enum PluginType
{
ByExtension = 0x01,
ByContent = 0x10
}
}

View File

@@ -7,8 +7,9 @@
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"> d:DesignHeight="300" d:DesignWidth="300">
<Grid> <Grid>
<ContentControl Name="Container" > <ContentControl Name="Container">
<Label Content="ContentControl Placeholder" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Background="LightGray" /> <Label Content="ContentControl Placeholder" VerticalContentAlignment="Center"
HorizontalContentAlignment="Center" Background="LightGray" />
</ContentControl> </ContentControl>
</Grid> </Grid>
</UserControl> </UserControl>

View File

@@ -3,7 +3,7 @@
namespace QuickLook.Plugin namespace QuickLook.Plugin
{ {
/// <summary> /// <summary>
/// Interaction logic for ViewContentContainer.xaml /// Interaction logic for ViewContentContainer.xaml
/// </summary> /// </summary>
public partial class ViewContentContainer : UserControl public partial class ViewContentContainer : UserControl
{ {

View File

@@ -1,6 +1,4 @@
using System.Reflection; using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Windows; using System.Windows;
@@ -33,11 +31,11 @@ using System.Windows;
[assembly: ThemeInfo( [assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page, //(used if a resource is not found in the page,
// or application resource dictionaries) // or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page, //(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries) // app, or any theme specific resource dictionaries)
)] )]

View File

@@ -1,4 +1,5 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)"> <SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
<Profiles> <Profiles>
<Profile Name="(Default)" /> <Profile Name="(Default)" />

View File

@@ -76,6 +76,7 @@
<Compile Include="PathToPluginMatcher.cs" /> <Compile Include="PathToPluginMatcher.cs" />
<Compile Include="PluginManager.cs" /> <Compile Include="PluginManager.cs" />
<Compile Include="Plugin\IViewer.cs" /> <Compile Include="Plugin\IViewer.cs" />
<Compile Include="Plugin\PluginPriority.cs" />
<Compile Include="Plugin\ViewContentContainer.xaml.cs"> <Compile Include="Plugin\ViewContentContainer.xaml.cs">
<DependentUpon>ViewContentContainer.xaml</DependentUpon> <DependentUpon>ViewContentContainer.xaml</DependentUpon>
</Compile> </Compile>

View File

@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="FontAwesome.WPF" version="4.7.0.9" targetFramework="net452" /> <package id="FontAwesome.WPF" version="4.7.0.9" targetFramework="net452" />
</packages> </packages>