Finish ImageViewer; mouse drag to scroll

This commit is contained in:
Paddy Xu
2017-04-26 00:48:40 +03:00
parent c38c640af5
commit fa764b2e69
20 changed files with 445 additions and 61 deletions

View File

@@ -0,0 +1,15 @@
<UserControl x:Class="QuickLook.Plugin.ImageViewer.ImagePanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:QuickLook.Plugin.ImageViewer"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<ScrollViewer x:Name="viewPanel" BorderThickness="0" HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto" Focusable="False">
<Image x:Name="viewPanelImage" Stretch="None" RenderOptions.BitmapScalingMode="HighQuality" />
</ScrollViewer>
</Grid>
</UserControl>

View File

@@ -0,0 +1,108 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace QuickLook.Plugin.ImageViewer
{
/// <summary>
/// Interaction logic for ImagePanel.xaml
/// </summary>
public partial class ImagePanel : UserControl
{
private Point? _dragInitPos;
private double _minZoomFactor = 1d;
private double _zoomFactor = 1d;
public ImagePanel(string path)
{
InitializeComponent();
viewPanelImage.Source = new BitmapImage(new Uri(path));
Loaded += (sender, e) => { ZoomToFit(); };
viewPanel.PreviewMouseWheel += ViewPanel_PreviewMouseWheel;
viewPanel.PreviewMouseLeftButtonDown += ViewPanel_PreviewMouseLeftButtonDown;
viewPanel.PreviewMouseMove += ViewPanel_PreviewMouseMove;
}
private void ViewPanel_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
_dragInitPos = e.GetPosition(viewPanel);
var temp = _dragInitPos.Value; // Point is a type value
temp.Offset(viewPanel.HorizontalOffset, viewPanel.VerticalOffset);
_dragInitPos = temp;
}
private void ViewPanel_PreviewMouseMove(object sender, MouseEventArgs e)
{
if (!_dragInitPos.HasValue)
return;
if (e.LeftButton == MouseButtonState.Released)
{
_dragInitPos = null;
return;
}
e.Handled = true;
var delta = _dragInitPos.Value - e.GetPosition(viewPanel);
viewPanel.ScrollToHorizontalOffset(delta.X);
viewPanel.ScrollToVerticalOffset(delta.Y);
}
private void ViewPanel_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
if ((Keyboard.Modifiers & ModifierKeys.Control) == 0)
return;
e.Handled = true;
var newZoom = _zoomFactor + e.Delta / 120 * 0.1;
newZoom = Math.Max(newZoom, _minZoomFactor);
newZoom = Math.Min(newZoom, 3);
Zoom(newZoom, false);
}
private void ZoomToFit()
{
var factor = Math.Min(viewPanel.ActualWidth / viewPanelImage.Source.Width,
viewPanel.ActualHeight / viewPanelImage.Source.Height);
_minZoomFactor = factor;
Zoom(factor, true);
}
private void Zoom(double factor, bool fromCenter)
{
_zoomFactor = factor;
var position = fromCenter
? new Point(viewPanelImage.Source.Width / 2, viewPanelImage.Source.Height / 2)
: Mouse.GetPosition(viewPanelImage);
viewPanelImage.LayoutTransform = new ScaleTransform(factor, factor);
viewPanel.InvalidateMeasure();
// critical for calcuating offset
viewPanel.ScrollToHorizontalOffset(0);
viewPanel.ScrollToVerticalOffset(0);
UpdateLayout();
var offset = viewPanelImage.TranslatePoint(position, viewPanel) - Mouse.GetPosition(viewPanel);
viewPanel.ScrollToHorizontalOffset(offset.X);
viewPanel.ScrollToVerticalOffset(offset.Y);
UpdateLayout();
}
}
}

View File

@@ -0,0 +1,58 @@
using System;
using System.IO;
using System.Windows;
using System.Windows.Media.Imaging;
namespace QuickLook.Plugin.ImageViewer
{
public class Plugin : IViewer
{
private ImagePanel _ip;
private BitmapDecoder decoder;
public int Priority { get; }
public bool CanHandle(string path)
{
// TODO: determine file type by content
if (Directory.Exists(path))
return false;
switch (Path.GetExtension(path).ToLower())
{
case ".bmp":
case ".gif":
case ".ico":
case ".jpg":
case ".png":
case ".wdp":
case ".tiff":
return true;
default:
return false;
}
}
public void Prepare(string path, ViewContentContainer container)
{
decoder = BitmapDecoder.Create(new Uri(path), BitmapCreateOptions.None, BitmapCacheOption.None);
var frame = decoder.Frames[0];
container.SetPreferedSizeFit(new Size {Width = frame.Width, Height = frame.Height}, 0.6);
}
public void View(string path, ViewContentContainer container)
{
_ip = new ImagePanel(path);
container.SetContent(_ip);
container.Title = $"{Path.GetFileName(path)}";
}
public void Close()
{
}
}
}

View File

@@ -0,0 +1,35 @@
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("QuickLook.Plugin.ImageViewer")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("QuickLook.Plugin.ImageViewer")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("fe5a5111-9607-4721-a7be-422754002ed8")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{FE5A5111-9607-4721-A7BE-422754002ED8}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>QuickLook.Plugin.ImageViewer</RootNamespace>
<AssemblyName>QuickLook.Plugin.ImageViewer</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\Build\Debug\Plugins\QuickLook.Plugin.ImageViewer\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\Build\Release\Plugins\QuickLook.Plugin.ImageViewer\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
<Reference Include="WpfAnimatedGif, Version=1.4.14.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\WpfAnimatedGif.1.4.14\lib\net\WpfAnimatedGif.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="ImagePanel.xaml.cs">
<DependentUpon>ImagePanel.xaml</DependentUpon>
</Compile>
<Compile Include="Plugin.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\QuickLook\QuickLook.csproj">
<Project>{8b4a9ce5-67b5-4a94-81cb-3771f688fdeb}</Project>
<Name>QuickLook</Name>
<Private>False</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Page Include="ImagePanel.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="WpfAnimatedGif" version="1.4.14" targetFramework="net452" />
</packages>

View File

@@ -1,4 +1,6 @@
using System.Windows.Controls; using System.IO;
using System.Threading.Tasks;
using System.Windows.Controls;
namespace QuickLook.Plugin.LastResort namespace QuickLook.Plugin.LastResort
{ {
@@ -7,9 +9,57 @@ namespace QuickLook.Plugin.LastResort
/// </summary> /// </summary>
public partial class InfoPanel : UserControl public partial class InfoPanel : UserControl
{ {
private bool _stop;
public InfoPanel() public InfoPanel()
{ {
InitializeComponent(); InitializeComponent();
} }
public bool Stop
{
set => _stop = value;
get => _stop;
}
public void DisplayInfo(string path)
{
var icon = IconHelper.GetBitmapFromPath(path, IconHelper.IconSizeEnum.ExtraLargeIcon).ToBitmapSource();
image.Source = icon;
var name = Path.GetFileName(path);
filename.Content = string.IsNullOrEmpty(name) ? path : name;
var last = File.GetLastWriteTime(path);
modDate.Content = $"{last.ToLongDateString()} {last.ToLongTimeString()}";
Stop = false;
Task.Run(() =>
{
if (File.Exists(path))
{
var size = new FileInfo(path).Length;
Dispatcher.Invoke(() => { totalSize.Content = size.ToPrettySize(2); });
}
else if (Directory.Exists(path))
{
long totalDirsL;
long totalFilesL;
long totalSizeL;
FileHelper.CountFolder(path, ref _stop, out totalDirsL, out totalFilesL, out totalSizeL);
if (!Stop)
Dispatcher.Invoke(() =>
{
totalSize.Content =
$"{totalSizeL.ToPrettySize(2)} ({totalDirsL} folders and {totalFilesL} files)";
});
}
});
}
} }
} }

View File

@@ -1,13 +1,10 @@
using System.IO; using System.Windows;
using System.Threading.Tasks;
using System.Windows;
namespace QuickLook.Plugin.LastResort namespace QuickLook.Plugin.LastResort
{ {
public class Plugin : IViewer public class Plugin : IViewer
{ {
private InfoPanel _ip; private InfoPanel _ip;
private bool _stop;
public int Priority => int.MinValue; public int Priority => int.MinValue;
@@ -16,7 +13,7 @@ namespace QuickLook.Plugin.LastResort
return true; return true;
} }
public void BoundSize(string path, ViewContentContainer container) public void Prepare(string path, ViewContentContainer container)
{ {
_ip = new InfoPanel(); _ip = new InfoPanel();
@@ -26,55 +23,14 @@ namespace QuickLook.Plugin.LastResort
public void View(string path, ViewContentContainer container) public void View(string path, ViewContentContainer container)
{ {
DisplayInfo(path); _ip.DisplayInfo(path);
container.SetContent(_ip); container.SetContent(_ip);
} }
public void Close() public void Close()
{ {
_stop = true; _ip.Stop = true;
}
private void DisplayInfo(string path)
{
var icon = IconHelper.GetBitmapFromPath(path, IconHelper.IconSizeEnum.ExtraLargeIcon).ToBitmapSource();
_ip.image.Source = icon;
var name = Path.GetFileName(path);
_ip.filename.Content = string.IsNullOrEmpty(name) ? path : name;
var last = File.GetLastWriteTime(path);
_ip.modDate.Content = $"{last.ToLongDateString()} {last.ToLongTimeString()}";
_stop = false;
Task.Run(() =>
{
if (File.Exists(path))
{
var size = new FileInfo(path).Length;
_ip.Dispatcher.Invoke(() => { _ip.totalSize.Content = size.ToPrettySize(2); });
}
else if (Directory.Exists(path))
{
long totalDirs;
long totalFiles;
long totalSize;
FileHelper.CountFolder(path, ref _stop, out totalDirs, out totalFiles, out totalSize);
if (!_stop)
_ip.Dispatcher.Invoke(() =>
{
_ip.totalSize.Content =
$"{totalSize.ToPrettySize(2)} ({totalDirs} folders and {totalFiles} files.)";
});
}
});
} }
} }
} }

View File

@@ -15,6 +15,7 @@ namespace QuickLook.Plugin.PDFViewer
/// </summary> /// </summary>
public partial class PdfViewerControl : UserControl, INotifyPropertyChanged, IDisposable public partial class PdfViewerControl : UserControl, INotifyPropertyChanged, IDisposable
{ {
private Point? _dragInitPos;
private PreviewMouseWheelMonitor _whellMonitor; private PreviewMouseWheelMonitor _whellMonitor;
public PdfViewerControl() public PdfViewerControl()
@@ -36,6 +37,8 @@ namespace QuickLook.Plugin.PDFViewer
public double ZoomFactor { get; set; } public double ZoomFactor { get; set; }
public double MinZoomFactor { get; set; }
public int TotalPages => PdfHandle.TotalPages; public int TotalPages => PdfHandle.TotalPages;
public int CurrectPage public int CurrectPage
@@ -114,6 +117,8 @@ namespace QuickLook.Plugin.PDFViewer
pageViewPanelImage.LayoutTransform = new ScaleTransform(viewZoom, viewZoom); pageViewPanelImage.LayoutTransform = new ScaleTransform(viewZoom, viewZoom);
pageViewPanel.InvalidateMeasure();
// critical for calcuating offset // critical for calcuating offset
pageViewPanel.ScrollToHorizontalOffset(0); pageViewPanel.ScrollToHorizontalOffset(0);
pageViewPanel.ScrollToVerticalOffset(0); pageViewPanel.ScrollToVerticalOffset(0);
@@ -140,6 +145,8 @@ namespace QuickLook.Plugin.PDFViewer
// reset view zoom factor // reset view zoom factor
pageViewPanelImage.LayoutTransform = new ScaleTransform(); pageViewPanelImage.LayoutTransform = new ScaleTransform();
pageViewPanel.InvalidateMeasure();
GC.Collect(); GC.Collect();
} }
@@ -164,6 +171,7 @@ namespace QuickLook.Plugin.PDFViewer
var factor = Math.Min(pageViewPanel.ActualWidth / size.Width, pageViewPanel.ActualHeight / size.Height); var factor = Math.Min(pageViewPanel.ActualWidth / size.Width, pageViewPanel.ActualHeight / size.Height);
ZoomFactor = factor; ZoomFactor = factor;
MinZoomFactor = factor;
ReRenderCurrentPage(); ReRenderCurrentPage();
} }
@@ -175,7 +183,7 @@ namespace QuickLook.Plugin.PDFViewer
var size = tempHandle.GetPageSize(0, 1d); var size = tempHandle.GetPageSize(0, 1d);
tempHandle.Dispose(); tempHandle.Dispose();
size.Width += /*listThumbnails.ActualWidth*/ 150 + 1; size.Width += /*listThumbnails.ActualWidth*/ 150;
return size; return size;
} }
@@ -201,8 +209,39 @@ namespace QuickLook.Plugin.PDFViewer
// register events // register events
listThumbnails.SelectionChanged += UpdatePageViewWhenSelectionChanged; listThumbnails.SelectionChanged += UpdatePageViewWhenSelectionChanged;
//pageViewPanel.SizeChanged += ReRenderCurrentPageWhenSizeChanged; //pageViewPanel.SizeChanged += ReRenderCurrentPageWhenSizeChanged;
pageViewPanel.PreviewMouseWheel += NavigatePage; pageViewPanel.PreviewMouseWheel += NavigatePage;
StartMouseWhellDelayedZoomMonitor(pageViewPanel); StartMouseWhellDelayedZoomMonitor(pageViewPanel);
pageViewPanel.PreviewMouseLeftButtonDown += DragScrollStart;
pageViewPanel.PreviewMouseMove += DragScrolling;
}
private void DragScrolling(object sender, MouseEventArgs e)
{
if (!_dragInitPos.HasValue)
return;
if (e.LeftButton == MouseButtonState.Released)
{
_dragInitPos = null;
return;
}
e.Handled = true;
var delta = _dragInitPos.Value - e.GetPosition(pageViewPanel);
pageViewPanel.ScrollToHorizontalOffset(delta.X);
pageViewPanel.ScrollToVerticalOffset(delta.Y);
}
private void DragScrollStart(object sender, MouseButtonEventArgs e)
{
_dragInitPos = e.GetPosition(pageViewPanel);
var temp = _dragInitPos.Value; // Point is a type value
temp.Offset(pageViewPanel.HorizontalOffset, pageViewPanel.VerticalOffset);
_dragInitPos = temp;
} }
private void StartMouseWhellDelayedZoomMonitor(UIElement ui) private void StartMouseWhellDelayedZoomMonitor(UIElement ui)
@@ -230,7 +269,7 @@ namespace QuickLook.Plugin.PDFViewer
newZoom = newZoom + e.Delta / 120 * 0.1; newZoom = newZoom + e.Delta / 120 * 0.1;
newZoom = Math.Max(newZoom, 0.2); newZoom = Math.Max(newZoom, MinZoomFactor);
newZoom = Math.Min(newZoom, 3); newZoom = Math.Min(newZoom, 3);
ReRenderCurrentPageLowQuality(newZoom / ZoomFactor, false); ReRenderCurrentPageLowQuality(newZoom / ZoomFactor, false);

View File

@@ -22,14 +22,12 @@ namespace QuickLook.Plugin.PDFViewer
} }
} }
public void BoundSize(string path, ViewContentContainer container) public void Prepare(string path, ViewContentContainer container)
{ {
_pdfControl = new PdfViewerControl(); _pdfControl = new PdfViewerControl();
var desiredSize = _pdfControl.GetDesiredControlSizeByFirstPage(path); var desiredSize = _pdfControl.GetDesiredControlSizeByFirstPage(path);
desiredSize.Width += 150; // add thumbnails column
container.SetPreferedSizeFit(desiredSize, 0.7); container.SetPreferedSizeFit(desiredSize, 0.7);
} }

View File

@@ -41,7 +41,7 @@ namespace QuickLook.Plugin.TextViewer
} }
} }
public void BoundSize(string path, ViewContentContainer container) public void Prepare(string path, ViewContentContainer container)
{ {
container.PreferedSize = new Size {Width = 800, Height = 600}; container.PreferedSize = new Size {Width = 800, Height = 600};
} }

View File

@@ -16,6 +16,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.LastResort
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.TextViewer", "QuickLook.Plugin.TextViewer\QuickLook.Plugin.TextViewer.csproj", "{AE041682-E3A1-44F6-8BB4-916A98D89FBE}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.TextViewer", "QuickLook.Plugin.TextViewer\QuickLook.Plugin.TextViewer.csproj", "{AE041682-E3A1-44F6-8BB4-916A98D89FBE}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.ImageViewer", "QuickLook.Plugin.ImageViewer\QuickLook.Plugin.ImageViewer.csproj", "{FE5A5111-9607-4721-A7BE-422754002ED8}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@@ -62,6 +64,14 @@ Global
{AE041682-E3A1-44F6-8BB4-916A98D89FBE}.Release|Any CPU.Build.0 = Release|Any CPU {AE041682-E3A1-44F6-8BB4-916A98D89FBE}.Release|Any CPU.Build.0 = Release|Any CPU
{AE041682-E3A1-44F6-8BB4-916A98D89FBE}.Release|x86.ActiveCfg = Release|Any CPU {AE041682-E3A1-44F6-8BB4-916A98D89FBE}.Release|x86.ActiveCfg = Release|Any CPU
{AE041682-E3A1-44F6-8BB4-916A98D89FBE}.Release|x86.Build.0 = Release|Any CPU {AE041682-E3A1-44F6-8BB4-916A98D89FBE}.Release|x86.Build.0 = Release|Any CPU
{FE5A5111-9607-4721-A7BE-422754002ED8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FE5A5111-9607-4721-A7BE-422754002ED8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FE5A5111-9607-4721-A7BE-422754002ED8}.Debug|x86.ActiveCfg = Debug|Any CPU
{FE5A5111-9607-4721-A7BE-422754002ED8}.Debug|x86.Build.0 = Debug|Any CPU
{FE5A5111-9607-4721-A7BE-422754002ED8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FE5A5111-9607-4721-A7BE-422754002ED8}.Release|Any CPU.Build.0 = Release|Any CPU
{FE5A5111-9607-4721-A7BE-422754002ED8}.Release|x86.ActiveCfg = Release|Any CPU
{FE5A5111-9607-4721-A7BE-422754002ED8}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@@ -58,7 +58,7 @@ namespace QuickLook
_showingWindow.viewContentContainer.ViewerPlugin = matched; _showingWindow.viewContentContainer.ViewerPlugin = matched;
// get window size before showing it // get window size before showing it
matched.BoundSize(path, _showingWindow.viewContentContainer); matched.Prepare(path, _showingWindow.viewContentContainer);
_showingWindow.Show(); _showingWindow.Show();

View File

@@ -10,13 +10,14 @@
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" Topmost="True" d:DesignWidth="624" d:DesignHeight="700"
MinWidth="275" MinHeight="150"
WindowStartupLocation="CenterScreen" WindowStartupLocation="CenterScreen"
ResizeMode="CanResizeWithGrip" ResizeMode="CanResizeWithGrip"
x:ClassModifier="internal"> x:ClassModifier="internal" Focusable="False" ShowActivated="False" ShowInTaskbar="False">
<Window.Background> <Window.Background>
<SolidColorBrush Color="#BFFFFFFF" /> <SolidColorBrush Color="#BFFFFFFF" />
</Window.Background> </Window.Background>
<Border BorderThickness="1" BorderBrush="#FF7B7B7B"> <Border x:Name="windowBorder" BorderThickness="1" BorderBrush="#FF7B7B7B">
<Grid> <Grid>
<DockPanel Opacity="1"> <DockPanel Opacity="1">
<DockPanel x:Name="titlebar" Height="28" Dock="Top"> <DockPanel x:Name="titlebar" Height="28" Dock="Top">

View File

@@ -3,6 +3,7 @@ using System.ComponentModel;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media.Animation; using System.Windows.Media.Animation;
using System.Windows.Threading; using System.Windows.Threading;
using QuickLook.Annotations; using QuickLook.Annotations;
@@ -34,18 +35,25 @@ namespace QuickLook
private void MainWindow_Closed(object sender, EventArgs e) private void MainWindow_Closed(object sender, EventArgs e)
{ {
viewContentContainer.ViewerPlugin.Close(); viewContentContainer.ViewerPlugin.Close();
viewContentContainer.ViewerPlugin = null;
GC.Collect();
} }
internal new void Show() internal new void Show()
{ {
loadingIconLayer.Opacity = 1; loadingIconLayer.Opacity = 1;
Height = viewContentContainer.PreferedSize.Height + titlebar.Height; Height = viewContentContainer.PreferedSize.Height + titlebar.Height + windowBorder.BorderThickness.Top +
Width = viewContentContainer.PreferedSize.Width; windowBorder.BorderThickness.Bottom;
Width = viewContentContainer.PreferedSize.Width + windowBorder.BorderThickness.Left +
windowBorder.BorderThickness.Right;
ResizeMode = viewContentContainer.CanResize ? ResizeMode.CanResizeWithGrip : ResizeMode.NoResize; ResizeMode = viewContentContainer.CanResize ? ResizeMode.CanResizeWithGrip : ResizeMode.NoResize;
base.Show(); base.Show();
NoactivateWindowHelper.SetNoactivate(new WindowInteropHelper(this));
} }
internal void ShowFinishLoadingAnimation() internal void ShowFinishLoadingAnimation()

View File

@@ -16,6 +16,12 @@ namespace QuickLook.NativeMethods
[DllImport("user32.dll")] [DllImport("user32.dll")]
internal static extern int CallNextHookEx(IntPtr idHook, int nCode, int wParam, ref KeyboardHookStruct lParam); internal static extern int CallNextHookEx(IntPtr idHook, int nCode, int wParam, ref KeyboardHookStruct lParam);
[DllImport("user32.dll")]
public static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll")]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
internal delegate int KeyboardHookProc(int code, int wParam, ref KeyboardHookStruct lParam); internal delegate int KeyboardHookProc(int code, int wParam, ref KeyboardHookStruct lParam);
[SuppressMessage("ReSharper", "InconsistentNaming")] [SuppressMessage("ReSharper", "InconsistentNaming")]
@@ -34,6 +40,8 @@ namespace QuickLook.NativeMethods
internal const int WM_KEYUP = 0x101; internal const int WM_KEYUP = 0x101;
internal const int WM_SYSKEYDOWN = 0x104; internal const int WM_SYSKEYDOWN = 0x104;
internal const int WM_SYSKEYUP = 0x105; internal const int WM_SYSKEYUP = 0x105;
internal const int GWL_EXSTYLE = -20;
internal const int WS_EX_NOACTIVATE = 0x08000000;
// ReSharper restore InconsistentNaming // ReSharper restore InconsistentNaming
} }
} }

View File

@@ -4,7 +4,7 @@
{ {
int Priority { get; } int Priority { get; }
bool CanHandle(string path); bool CanHandle(string path);
void BoundSize(string path, ViewContentContainer container); void Prepare(string path, ViewContentContainer container);
void View(string path, ViewContentContainer container); void View(string path, ViewContentContainer container);
void Close(); void Close();
} }

View File

@@ -54,6 +54,8 @@ namespace QuickLook.Plugin
var ratio = Math.Min(widthRatio, heightRatio); var ratio = Math.Min(widthRatio, heightRatio);
if (ratio > 1) ratio = 1;
PreferedSize = new Size {Width = size.Width * ratio, Height = size.Height * ratio}; PreferedSize = new Size {Width = size.Width * ratio, Height = size.Height * ratio};
return ratio; return ratio;

View File

@@ -79,6 +79,7 @@
<Compile Include="Plugin\ViewContentContainer.xaml.cs"> <Compile Include="Plugin\ViewContentContainer.xaml.cs">
<DependentUpon>ViewContentContainer.xaml</DependentUpon> <DependentUpon>ViewContentContainer.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Utilities\NoactivateWindowHelper.cs" />
<Page Include="Styles\ScrollBarStyleDictionary.xaml"> <Page Include="Styles\ScrollBarStyleDictionary.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>

View File

@@ -0,0 +1,15 @@
using System.Windows.Interop;
using QuickLook.NativeMethods;
namespace QuickLook.Utilities
{
internal class NoactivateWindowHelper
{
internal static void SetNoactivate(WindowInteropHelper window)
{
User32.SetWindowLong(window.Handle, User32.GWL_EXSTYLE,
User32.GetWindowLong(window.Handle, User32.GWL_EXSTYLE) |
User32.WS_EX_NOACTIVATE);
}
}
}