diff --git a/PowerToys.sln b/PowerToys.sln
index 94b05bacb7..b794636e50 100644
--- a/PowerToys.sln
+++ b/PowerToys.sln
@@ -470,8 +470,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GPOWrapperProjection", "src
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Peek", "Peek", "{17B4FA70-001E-4D33-BBBB-0D142DBC2E20}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Peek.UI.WPF", "src\modules\peek\Peek.UI.WPF\Peek.UI.WPF.csproj", "{C0240BC3-95AF-4B38-811A-76E3FD56B576}"
-EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Peek", "src\modules\peek\peek\peek.vcxproj", "{A1425B53-3D61-4679-8623-E64A0D3D0A48}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Peek.UI", "src\modules\peek\Peek.UI\Peek.UI.csproj", "{9D7A6DE0-7D27-424D-ABAE-41B2161F9A03}"
@@ -1927,18 +1925,6 @@ Global
{00EE9BA6-4E8F-43CA-960D-D4882F0FBB97}.Release|x64.Build.0 = Release|x64
{00EE9BA6-4E8F-43CA-960D-D4882F0FBB97}.Release|x86.ActiveCfg = Release|x64
{00EE9BA6-4E8F-43CA-960D-D4882F0FBB97}.Release|x86.Build.0 = Release|x64
- {C0240BC3-95AF-4B38-811A-76E3FD56B576}.Debug|ARM64.ActiveCfg = Debug|ARM64
- {C0240BC3-95AF-4B38-811A-76E3FD56B576}.Debug|ARM64.Build.0 = Debug|ARM64
- {C0240BC3-95AF-4B38-811A-76E3FD56B576}.Debug|x64.ActiveCfg = Debug|x64
- {C0240BC3-95AF-4B38-811A-76E3FD56B576}.Debug|x64.Build.0 = Debug|x64
- {C0240BC3-95AF-4B38-811A-76E3FD56B576}.Debug|x86.ActiveCfg = Debug|x64
- {C0240BC3-95AF-4B38-811A-76E3FD56B576}.Debug|x86.Build.0 = Debug|x64
- {C0240BC3-95AF-4B38-811A-76E3FD56B576}.Release|ARM64.ActiveCfg = Release|ARM64
- {C0240BC3-95AF-4B38-811A-76E3FD56B576}.Release|ARM64.Build.0 = Release|ARM64
- {C0240BC3-95AF-4B38-811A-76E3FD56B576}.Release|x64.ActiveCfg = Release|x64
- {C0240BC3-95AF-4B38-811A-76E3FD56B576}.Release|x64.Build.0 = Release|x64
- {C0240BC3-95AF-4B38-811A-76E3FD56B576}.Release|x86.ActiveCfg = Release|x64
- {C0240BC3-95AF-4B38-811A-76E3FD56B576}.Release|x86.Build.0 = Release|x64
{A1425B53-3D61-4679-8623-E64A0D3D0A48}.Debug|ARM64.ActiveCfg = Debug|ARM64
{A1425B53-3D61-4679-8623-E64A0D3D0A48}.Debug|ARM64.Build.0 = Debug|ARM64
{A1425B53-3D61-4679-8623-E64A0D3D0A48}.Debug|x64.ActiveCfg = Debug|x64
@@ -2275,7 +2261,6 @@ Global
{E599C30B-9DC8-4E5A-BF27-93D4CCEDE788} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{00EE9BA6-4E8F-43CA-960D-D4882F0FBB97} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{17B4FA70-001E-4D33-BBBB-0D142DBC2E20} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
- {C0240BC3-95AF-4B38-811A-76E3FD56B576} = {17B4FA70-001E-4D33-BBBB-0D142DBC2E20}
{A1425B53-3D61-4679-8623-E64A0D3D0A48} = {17B4FA70-001E-4D33-BBBB-0D142DBC2E20}
{9D7A6DE0-7D27-424D-ABAE-41B2161F9A03} = {17B4FA70-001E-4D33-BBBB-0D142DBC2E20}
{17A99C7C-0BFF-45BB-A9FD-63A0DDC105BB} = {17B4FA70-001E-4D33-BBBB-0D142DBC2E20}
diff --git a/src/modules/peek/Peek.UI.WPF/App.xaml b/src/modules/peek/Peek.UI.WPF/App.xaml
deleted file mode 100644
index 1fc9407448..0000000000
--- a/src/modules/peek/Peek.UI.WPF/App.xaml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/modules/peek/Peek.UI.WPF/App.xaml.cs b/src/modules/peek/Peek.UI.WPF/App.xaml.cs
deleted file mode 100644
index 54225caef6..0000000000
--- a/src/modules/peek/Peek.UI.WPF/App.xaml.cs
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) Microsoft Corporation
-// The Microsoft Corporation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Threading;
-using System.Windows;
-using Common.UI;
-using ManagedCommon;
-
-namespace Peek.UI
-{
- ///
- /// Interaction logic for App.xaml
- ///
- public partial class App : Application, IDisposable
- {
- private ThemeManager? _themeManager;
-
- private Mutex? _instanceMutex;
- private static string[] _args = Array.Empty();
- private int _powerToysRunnerPid;
- private bool disposedValue;
-
- // TODO: Make sure no window appears or blinks at startup
- protected override void OnStartup(StartupEventArgs e)
- {
- _args = e?.Args ?? Array.Empty();
-
- // allow only one instance of peek
- _instanceMutex = new Mutex(true, @"Local\PowerToys_Peek_InstanceMutex", out bool createdNew);
- if (!createdNew)
- {
- _instanceMutex = null;
- Environment.Exit(0);
- return;
- }
-
- if (_args?.Length > 0)
- {
- _ = int.TryParse(_args[0], out _powerToysRunnerPid);
-
- RunnerHelper.WaitForPowerToysRunner(_powerToysRunnerPid, () =>
- {
- Environment.Exit(0);
- });
- }
- else
- {
- _powerToysRunnerPid = -1;
- }
-
- _themeManager = new ThemeManager(this);
- base.OnStartup(e);
- }
-
- protected override void OnExit(ExitEventArgs e)
- {
- if (_instanceMutex != null)
- {
- _instanceMutex.ReleaseMutex();
- }
-
- base.OnExit(e);
- }
-
- protected virtual void Dispose(bool disposing)
- {
- if (!disposedValue)
- {
- if (disposing)
- {
- _instanceMutex?.Dispose();
- }
-
- // TODO: free unmanaged resources (unmanaged objects) and override finalizer
- // TODO: set large fields to null
- disposedValue = true;
- }
- }
-
- public void Dispose()
- {
- // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- public bool IsRunningDetachedFromPowerToys()
- {
- return _powerToysRunnerPid == -1;
- }
- }
-}
diff --git a/src/modules/peek/Peek.UI.WPF/AssemblyInfo.cs b/src/modules/peek/Peek.UI.WPF/AssemblyInfo.cs
deleted file mode 100644
index bcac370d7d..0000000000
--- a/src/modules/peek/Peek.UI.WPF/AssemblyInfo.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) Microsoft Corporation
-// The Microsoft Corporation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Windows;
-
-[assembly: ThemeInfo(
- ResourceDictionaryLocation.None, // where theme specific resource dictionaries are located (used if a resource is not found in the page, or application resource dictionaries)
- ResourceDictionaryLocation.SourceAssembly) // where the generic resource dictionary is locate (used if a resource is not found in the page, app, or any theme specific resource dictionaries)
-]
diff --git a/src/modules/peek/Peek.UI.WPF/Assets/error.png b/src/modules/peek/Peek.UI.WPF/Assets/error.png
deleted file mode 100644
index c2eb2fc2df..0000000000
Binary files a/src/modules/peek/Peek.UI.WPF/Assets/error.png and /dev/null differ
diff --git a/src/modules/peek/Peek.UI.WPF/Extensions/LinkedListNodeExtensions.cs b/src/modules/peek/Peek.UI.WPF/Extensions/LinkedListNodeExtensions.cs
deleted file mode 100644
index 5e740726e4..0000000000
--- a/src/modules/peek/Peek.UI.WPF/Extensions/LinkedListNodeExtensions.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) Microsoft Corporation
-// The Microsoft Corporation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Collections.Generic;
-
-namespace Peek.UI.Extensions
-{
- public static class LinkedListNodeExtensions
- {
- public static LinkedListNode? GetNextOrFirst(this LinkedListNode current)
- {
- return current.Next ?? current.List?.First;
- }
-
- public static LinkedListNode? GetPreviousOrLast(this LinkedListNode current)
- {
- return current.Previous ?? current.List?.Last;
- }
- }
-}
diff --git a/src/modules/peek/Peek.UI.WPF/Extensions/SizeExtensions.cs b/src/modules/peek/Peek.UI.WPF/Extensions/SizeExtensions.cs
deleted file mode 100644
index 19ac26c8b9..0000000000
--- a/src/modules/peek/Peek.UI.WPF/Extensions/SizeExtensions.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) Microsoft Corporation
-// The Microsoft Corporation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Windows;
-
-namespace Peek.UI.Extensions
-{
- public static class SizeExtensions
- {
- public static Rect Fit(this Size sizeToFit, Rect bounds, Size maxSize, Size minSize, Size allowedGap, double reservedHeight)
- {
- double resultingWidth = sizeToFit.Width;
- double resultingHeight = sizeToFit.Height;
-
- var ratioWidth = sizeToFit.Width / maxSize.Width;
- var ratioHeight = sizeToFit.Height / maxSize.Height;
-
- if (ratioWidth > ratioHeight)
- {
- if (ratioWidth > 1)
- {
- resultingWidth = maxSize.Width;
- resultingHeight = sizeToFit.Height / ratioWidth;
- }
- }
- else
- {
- if (ratioHeight > 1)
- {
- resultingWidth = sizeToFit.Width / ratioHeight;
- resultingHeight = maxSize.Height;
- }
- }
-
- if (resultingWidth < minSize.Width - allowedGap.Width)
- {
- resultingWidth = minSize.Width;
- }
-
- if (resultingHeight < minSize.Height - allowedGap.Height)
- {
- resultingHeight = minSize.Height;
- }
-
- resultingHeight += reservedHeight;
-
- // Calculate offsets to center content
- double offsetX = (maxSize.Width - resultingWidth) / 2;
- double offsetY = (maxSize.Height - resultingHeight) / 2;
-
- var maxWindowLeft = bounds.Left + ((bounds.Right - bounds.Left - maxSize.Width) / 2);
- var maxWindowTop = bounds.Top + ((bounds.Bottom - bounds.Top - maxSize.Height) / 2);
-
- var resultingLeft = maxWindowLeft + offsetX;
- var resultingTop = maxWindowTop + offsetY;
-
- return new Rect(resultingLeft, resultingTop, resultingWidth, resultingHeight);
- }
- }
-}
diff --git a/src/modules/peek/Peek.UI.WPF/Extensions/WindowExtensions.cs b/src/modules/peek/Peek.UI.WPF/Extensions/WindowExtensions.cs
deleted file mode 100644
index 17abcda12c..0000000000
--- a/src/modules/peek/Peek.UI.WPF/Extensions/WindowExtensions.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) Microsoft Corporation
-// The Microsoft Corporation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Windows;
-using System.Windows.Interop;
-using Peek.UI.Native;
-using static Peek.UI.Native.NativeModels;
-
-namespace Peek.UI.Extensions
-{
- public static class WindowExtensions
- {
- public static void SetToolStyle(this Window window)
- {
- var handle = new WindowInteropHelper(window).Handle;
- _ = NativeMethods.SetWindowLong(handle, GwlExStyle, NativeMethods.GetWindowLong(handle, GwlExStyle) | WsExToolWindow);
- }
-
- public static void BringToForeground(this Window window)
- {
- // Use SendInput hack to allow Activate to work - required to resolve focus issue https://github.com/microsoft/PowerToys/issues/4270
- Input input = new Input { Type = InputType.InputMouse, Data = { } };
- Input[] inputs = new Input[] { input };
-
- // Send empty mouse event. This makes this thread the last to send input, and hence allows it to pass foreground permission checks
- _ = NativeMethods.SendInput(1, inputs, Input.Size);
-
- window.Activate();
- }
-
- public static void RoundCorners(this Window window)
- {
- IntPtr hWnd = new System.Windows.Interop.WindowInteropHelper(Window.GetWindow(window)).EnsureHandle();
- var attribute = DwmWindowAttributed.DwmaWindowCornerPreference;
- var preference = DwmWindowCornerPreference.DwmCpRound;
- NativeMethods.DwmSetWindowAttribute(hWnd, attribute, ref preference, sizeof(uint));
- }
- }
-}
diff --git a/src/modules/peek/Peek.UI.WPF/Helpers/FileExplorerHelper.cs b/src/modules/peek/Peek.UI.WPF/Helpers/FileExplorerHelper.cs
deleted file mode 100644
index c5262a3279..0000000000
--- a/src/modules/peek/Peek.UI.WPF/Helpers/FileExplorerHelper.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) Microsoft Corporation
-// The Microsoft Corporation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Collections.Generic;
-
-namespace Peek.UI.Helpers
-{
- public static class FileExplorerHelper
- {
- public static IEnumerable GetSelectedItems(IntPtr handle)
- {
- var selectedItems = new List();
- var shell = new Shell32.Shell();
- foreach (SHDocVw.InternetExplorer window in shell.Windows())
- {
- if (window.HWND == (int)handle)
- {
- Shell32.FolderItems items = ((Shell32.IShellFolderViewDual2)window.Document).SelectedItems();
- if (items != null && items.Count > 0)
- {
- foreach (Shell32.FolderItem item in items)
- {
- selectedItems.Add(item.Path);
- }
- }
- }
- }
-
- return selectedItems;
- }
- }
-}
diff --git a/src/modules/peek/Peek.UI.WPF/Helpers/FileLoadHelper.cs b/src/modules/peek/Peek.UI.WPF/Helpers/FileLoadHelper.cs
deleted file mode 100644
index e43e7d72c2..0000000000
--- a/src/modules/peek/Peek.UI.WPF/Helpers/FileLoadHelper.cs
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright (c) Microsoft Corporation
-// The Microsoft Corporation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Drawing.Imaging;
-using System.IO;
-using System.Linq;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Media.Imaging;
-using Peek.UI.Models;
-
-namespace Peek.UI.Helpers
-{
- public static class FileLoadHelper
- {
- public static Task LoadDimensionsAsync(string filename)
- {
- return Task.Run(() =>
- {
- Size size = new Size(0, 0);
- try
- {
- using (FileStream stream = File.OpenRead(filename))
- {
- string extension = Path.GetExtension(stream.Name);
- if (FileTypeHelper.IsSupportedImage(extension))
- {
- using (System.Drawing.Image sourceImage = System.Drawing.Image.FromStream(stream, false, false))
- {
- var rotation = EvaluateRotationToApply(sourceImage);
- if (rotation == Rotation.Rotate90 || rotation == Rotation.Rotate270)
- {
- size = new Size(sourceImage.Height, sourceImage.Width);
- }
- else
- {
- size = new Size(sourceImage.Width, sourceImage.Height);
- }
-
- return Task.FromResult(new DimensionData { Size = size, Rotation = rotation });
- }
- }
- else
- {
- return Task.FromResult(new DimensionData { Size = size, Rotation = Rotation.Rotate0 });
- }
- }
- }
- catch (Exception)
- {
- return Task.FromResult(new DimensionData { Size = size, Rotation = Rotation.Rotate0 });
- }
- });
- }
-
- public static async Task LoadThumbnailAsync(string filename, bool iconFallback)
- {
- var thumbnail = await Task.Run(() =>
- {
- var bitmapSource = ThumbnailHelper.GetThumbnail(filename, iconFallback);
- bitmapSource.Freeze();
- return bitmapSource;
- });
-
- return thumbnail;
- }
-
- public static Task LoadIconAsync(string filename)
- {
- return Task.Run(() =>
- {
- var bitmapSource = ThumbnailHelper.GetIcon(filename);
- bitmapSource.Freeze();
- return bitmapSource;
- });
- }
-
- public static Task LoadFullImageAsync(string filename, Rotation rotation)
- {
- return Task.Run(() =>
- {
- var bitmap = new BitmapImage();
- bitmap.BeginInit();
- bitmap.CacheOption = BitmapCacheOption.OnLoad;
- bitmap.UriSource = new Uri(filename);
- bitmap.Rotation = rotation;
- bitmap.EndInit();
- bitmap.Freeze();
- return bitmap;
- });
- }
-
- private static Rotation EvaluateRotationToApply(System.Drawing.Image image)
- {
- PropertyItem? property = image.PropertyItems?.FirstOrDefault(p => p.Id == 274);
-
- if (property != null && property.Value != null && property.Value.Length > 0)
- {
- int orientation = property.Value[0];
-
- if (orientation == 6)
- {
- return Rotation.Rotate90;
- }
-
- if (orientation == 3)
- {
- return Rotation.Rotate180;
- }
-
- if (orientation == 8)
- {
- return Rotation.Rotate270;
- }
- }
-
- return Rotation.Rotate0;
- }
- }
-}
diff --git a/src/modules/peek/Peek.UI.WPF/Helpers/FileTypeHelper.cs b/src/modules/peek/Peek.UI.WPF/Helpers/FileTypeHelper.cs
deleted file mode 100644
index 40b6a2ad23..0000000000
--- a/src/modules/peek/Peek.UI.WPF/Helpers/FileTypeHelper.cs
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) Microsoft Corporation
-// The Microsoft Corporation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using Peek.UI.Native;
-using static Peek.UI.Native.NativeModels;
-
-namespace Peek.UI.Helpers
-{
- public static class FileTypeHelper
- {
- public static bool IsSupportedImage(string extension) => extension switch
- {
- ".bmp" => true,
- ".gif" => true,
- ".jpg" => true,
- ".jfif" => true,
- ".jfi" => true,
- ".jif" => true,
- ".jpeg" => true,
- ".jpe" => true,
- ".png" => true,
- ".tif" => true,
- ".tiff" => true,
- _ => false,
- };
-
- public static bool IsMedia(string extension)
- {
- return IsImage(extension) || IsVideo(extension);
- }
-
- public static bool IsImage(string extension)
- {
- return IsPerceivedType(extension, PerceivedType.Image);
- }
-
- public static bool IsVideo(string extension)
- {
- return IsPerceivedType(extension, PerceivedType.Video);
- }
-
- public static bool IsDocument(string extension)
- {
- return IsPerceivedType(extension, PerceivedType.Document);
- }
-
- internal static bool IsPerceivedType(string extension, PerceivedType perceivedType)
- {
- if (string.IsNullOrEmpty(extension))
- {
- return false;
- }
-
- PerceivedType perceived;
- Perceived flag;
- bool isPerceivedType = false;
-
- try
- {
- if (NativeMethods.AssocGetPerceivedType(extension, out perceived, out flag, IntPtr.Zero) == HResult.Ok)
- {
- isPerceivedType = perceived == perceivedType;
- }
- }
- catch (Exception)
- {
- // TODO: AssocGetPerceivedType throws on some file types (json, ps1, exe, etc.)
- // Properly handle these
- return false;
- }
-
- return isPerceivedType;
- }
- }
-}
diff --git a/src/modules/peek/Peek.UI.WPF/Helpers/ThumbnailHelper.cs b/src/modules/peek/Peek.UI.WPF/Helpers/ThumbnailHelper.cs
deleted file mode 100644
index 77a9bcf099..0000000000
--- a/src/modules/peek/Peek.UI.WPF/Helpers/ThumbnailHelper.cs
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (c) Microsoft Corporation
-// The Microsoft Corporation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.IO;
-using System.Reflection;
-using System.Runtime.InteropServices;
-using System.Windows;
-using System.Windows.Interop;
-using System.Windows.Media.Imaging;
-using Peek.UI.Models;
-using Peek.UI.Native;
-using static Peek.UI.Native.NativeModels;
-
-namespace Peek.UI.Helpers
-{
- public static class ThumbnailHelper
- {
- private static readonly Assembly Assembly = Assembly.GetExecutingAssembly();
- public static readonly string ProgramDirectory = Directory.GetParent(Assembly.Location)!.ToString();
- public static readonly string ErrorIcon = Path.Combine(ProgramDirectory, "Assets", "error.png");
-
- // Based on https://stackoverflow.com/questions/21751747/extract-thumbnail-for-any-file-in-windows
- private const string IShellItem2Guid = "7E9FB0D3-919F-4307-AB2E-9B1860310C93";
-
- public static BitmapSource GetIcon(string fileName)
- {
- IntPtr hbitmap;
- HResult hr = GetIconImpl(Path.GetFullPath(fileName), out hbitmap);
-
- if (hr != HResult.Ok)
- {
- return new BitmapImage(new Uri(ErrorIcon));
- }
-
- try
- {
- return Imaging.CreateBitmapSourceFromHBitmap(hbitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
- }
- finally
- {
- // delete HBitmap to avoid memory leaks
- NativeMethods.DeleteObject(hbitmap);
- }
- }
-
- public static BitmapSource GetThumbnail(string fileName, bool iconFallback)
- {
- IntPtr hbitmap;
- HResult hr = GetThumbnailImpl(Path.GetFullPath(fileName), out hbitmap);
-
- if (hr != HResult.Ok && iconFallback)
- {
- return GetIcon(fileName);
- }
-
- try
- {
- return Imaging.CreateBitmapSourceFromHBitmap(hbitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
- }
- finally
- {
- // delete HBitmap to avoid memory leaks
- NativeMethods.DeleteObject(hbitmap);
- }
- }
-
- private static HResult GetIconImpl(string filename, out IntPtr hbitmap)
- {
- Guid shellItem2Guid = new Guid(IShellItem2Guid);
- int retCode = NativeMethods.SHCreateItemFromParsingName(filename, IntPtr.Zero, ref shellItem2Guid, out IShellItem nativeShellItem);
-
- if (retCode != 0)
- {
- throw Marshal.GetExceptionForHR(retCode)!;
- }
-
- NativeSize large = new NativeSize { Width = 256, Height = 256 };
- var options = ThumbnailOptions.BiggerSizeOk | ThumbnailOptions.IconOnly;
-
- HResult hr = ((IShellItemImageFactory)nativeShellItem).GetImage(large, options, out hbitmap);
-
- Marshal.ReleaseComObject(nativeShellItem);
-
- return hr;
- }
-
- private static HResult GetThumbnailImpl(string filename, out IntPtr hbitmap)
- {
- Guid shellItem2Guid = new Guid(IShellItem2Guid);
- int retCode = NativeMethods.SHCreateItemFromParsingName(filename, IntPtr.Zero, ref shellItem2Guid, out IShellItem nativeShellItem);
-
- if (retCode != 0)
- {
- throw Marshal.GetExceptionForHR(retCode)!;
- }
-
- var extraLarge = new NativeSize { Width = 1024, Height = 1024, };
- var large = new NativeSize { Width = 256, Height = 256 };
- var medium = new NativeSize { Width = 96, Height = 96 };
- var small = new NativeSize { Width = 32, Height = 32 };
-
- var options = ThumbnailOptions.BiggerSizeOk | ThumbnailOptions.ThumbnailOnly | ThumbnailOptions.ScaleUp;
-
- HResult hr = ((IShellItemImageFactory)nativeShellItem).GetImage(extraLarge, options, out hbitmap);
-
- if (hr != HResult.Ok)
- {
- hr = ((IShellItemImageFactory)nativeShellItem).GetImage(large, options, out hbitmap);
- }
-
- if (hr != HResult.Ok)
- {
- hr = ((IShellItemImageFactory)nativeShellItem).GetImage(medium, options, out hbitmap);
- }
-
- if (hr != HResult.Ok)
- {
- hr = ((IShellItemImageFactory)nativeShellItem).GetImage(small, options, out hbitmap);
- }
-
- Marshal.ReleaseComObject(nativeShellItem);
-
- return hr;
- }
- }
-}
diff --git a/src/modules/peek/Peek.UI.WPF/Models/DimensionData.cs b/src/modules/peek/Peek.UI.WPF/Models/DimensionData.cs
deleted file mode 100644
index 42d0567238..0000000000
--- a/src/modules/peek/Peek.UI.WPF/Models/DimensionData.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) Microsoft Corporation
-// The Microsoft Corporation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Drawing.Imaging;
-using System.IO;
-using System.Linq;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Media.Imaging;
-
-namespace Peek.UI.Models
-{
- public class DimensionData
- {
- public Size Size { get; set; }
-
- public Rotation Rotation { get; set; }
- }
-}
diff --git a/src/modules/peek/Peek.UI.WPF/Models/IShellItem.cs b/src/modules/peek/Peek.UI.WPF/Models/IShellItem.cs
deleted file mode 100644
index 908e79428c..0000000000
--- a/src/modules/peek/Peek.UI.WPF/Models/IShellItem.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) Microsoft Corporation
-// The Microsoft Corporation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Runtime.InteropServices;
-using static Peek.UI.Native.NativeModels;
-
-namespace Peek.UI.Models
-{
- [ComImport]
- [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- [Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe")]
- internal interface IShellItem
- {
- void BindToHandler(
- IntPtr pbc,
- [MarshalAs(UnmanagedType.LPStruct)] Guid bhid,
- [MarshalAs(UnmanagedType.LPStruct)] Guid riid,
- out IntPtr ppv);
-
- void GetParent(out IShellItem ppsi);
-
- void GetDisplayName(Sigdn sigdnName, out IntPtr ppszName);
-
- void GetAttributes(uint sfgaoMask, out uint psfgaoAttribs);
-
- void Compare(IShellItem psi, uint hint, out int piOrder);
- }
-}
diff --git a/src/modules/peek/Peek.UI.WPF/Models/ObservableObject.cs b/src/modules/peek/Peek.UI.WPF/Models/ObservableObject.cs
deleted file mode 100644
index 8925029cbd..0000000000
--- a/src/modules/peek/Peek.UI.WPF/Models/ObservableObject.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) Microsoft Corporation
-// The Microsoft Corporation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.ComponentModel;
-using System.Runtime.CompilerServices;
-
-namespace Peek.UI.Models
-{
- public abstract class ObservableObject : INotifyPropertyChanged
- {
- public event PropertyChangedEventHandler? PropertyChanged;
-
- protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
- }
-}
diff --git a/src/modules/peek/Peek.UI.WPF/Models/ObservableRectangle.cs b/src/modules/peek/Peek.UI.WPF/Models/ObservableRectangle.cs
deleted file mode 100644
index 3a9c91c523..0000000000
--- a/src/modules/peek/Peek.UI.WPF/Models/ObservableRectangle.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright (c) Microsoft Corporation
-// The Microsoft Corporation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace Peek.UI.Models
-{
- public class ObservableRectangle : ObservableObject
- {
- private double _left;
-
- public double Left
- {
- get
- {
- return _left;
- }
-
- set
- {
- if (_left != value)
- {
- _left = value;
- OnPropertyChanged(nameof(Left));
- }
- }
- }
-
- private double _top;
-
- public double Top
- {
- get
- {
- return _top;
- }
-
- set
- {
- if (_top != value)
- {
- _top = value;
- OnPropertyChanged(nameof(Top));
- }
- }
- }
-
- private double _height;
-
- public double Height
- {
- get
- {
- return _height;
- }
-
- set
- {
- if (_height != value)
- {
- _height = value;
- OnPropertyChanged(nameof(Height));
- }
- }
- }
-
- private double _width;
-
- public double Width
- {
- get
- {
- return _width;
- }
-
- set
- {
- if (_width != value)
- {
- _width = value;
- OnPropertyChanged(nameof(Width));
- }
- }
- }
- }
-}
diff --git a/src/modules/peek/Peek.UI.WPF/Models/ObservableWindowData.cs b/src/modules/peek/Peek.UI.WPF/Models/ObservableWindowData.cs
deleted file mode 100644
index 0aab543369..0000000000
--- a/src/modules/peek/Peek.UI.WPF/Models/ObservableWindowData.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) Microsoft Corporation
-// The Microsoft Corporation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Windows;
-
-namespace Peek.UI.Models
-{
- public class ObservableWindowData : ObservableObject
- {
- private double _titleBarHeight;
-
- public double TitleBarHeight
- {
- get
- {
- return _titleBarHeight;
- }
-
- set
- {
- if (_titleBarHeight != value)
- {
- _titleBarHeight = value;
- OnPropertyChanged(nameof(TitleBarHeight));
- }
- }
- }
-
- private ObservableRectangle _rectangle = new ObservableRectangle();
-
- public ObservableRectangle Rectangle
- {
- get
- {
- return _rectangle;
- }
-
- set
- {
- if (_rectangle != value)
- {
- _rectangle = value;
- OnPropertyChanged(nameof(Rectangle));
- }
- }
- }
-
- private string _title = string.Empty;
-
- public string Title
- {
- get
- {
- return _title;
- }
-
- set
- {
- if (_title != value)
- {
- _title = value;
- OnPropertyChanged(nameof(Title));
- }
- }
- }
-
- private Visibility _visibility;
-
- public Visibility Visibility
- {
- get
- {
- return _visibility;
- }
-
- set
- {
- if (_visibility != value)
- {
- _visibility = value;
-
- OnPropertyChanged(nameof(Visibility));
- }
- }
- }
- }
-}
diff --git a/src/modules/peek/Peek.UI.WPF/Native/NativeEventWaiter.cs b/src/modules/peek/Peek.UI.WPF/Native/NativeEventWaiter.cs
deleted file mode 100644
index efb07bf413..0000000000
--- a/src/modules/peek/Peek.UI.WPF/Native/NativeEventWaiter.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) Microsoft Corporation
-// The Microsoft Corporation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Threading;
-using System.Windows;
-
-namespace Peek.UI.Native
-{
- public static class NativeEventWaiter
- {
- public static void WaitForEventLoop(string eventName, Action callback)
- {
- new Thread(() =>
- {
- var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, eventName);
- while (true)
- {
- if (eventHandle.WaitOne())
- {
- Application.Current.Dispatcher.Invoke(callback);
- }
- }
- }).Start();
- }
- }
-}
diff --git a/src/modules/peek/Peek.UI.WPF/Native/NativeMethods.cs b/src/modules/peek/Peek.UI.WPF/Native/NativeMethods.cs
deleted file mode 100644
index 2be17a45d1..0000000000
--- a/src/modules/peek/Peek.UI.WPF/Native/NativeMethods.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) Microsoft Corporation
-// The Microsoft Corporation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Runtime.InteropServices;
-using Peek.UI.Models;
-using static Peek.UI.Native.NativeModels;
-
-namespace Peek.UI.Native
-{
- public static class NativeMethods
- {
- [DllImport("dwmapi.dll", CharSet = CharSet.Unicode, SetLastError = true)]
- internal static extern long DwmSetWindowAttribute(
- IntPtr hwnd,
- DwmWindowAttributed attribute,
- ref DwmWindowCornerPreference pvAttribute,
- uint cbAttribute);
-
- [DllImport("gdi32.dll")]
- [return: MarshalAs(UnmanagedType.Bool)]
- internal static extern bool DeleteObject(IntPtr hObject);
-
- [DllImport("Shlwapi.dll", ExactSpelling = true, PreserveSig = false)]
- internal static extern HResult AssocGetPerceivedType(
- [MarshalAs(UnmanagedType.LPWStr)] string extension,
- out PerceivedType perceivedType,
- out Perceived perceivedFlags,
- IntPtr ptrType);
-
- [DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
- internal static extern int SHCreateItemFromParsingName(
- [MarshalAs(UnmanagedType.LPWStr)] string path,
- IntPtr pbc,
- ref Guid riid,
- [MarshalAs(UnmanagedType.Interface)] out IShellItem shellItem);
-
- [DllImport("user32.dll", SetLastError = true)]
- internal static extern int GetWindowLong(IntPtr hWnd, int nIndex);
-
- [DllImport("user32.dll")]
- internal static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
-
- [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
- internal static extern IntPtr GetForegroundWindow();
-
- [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- internal static extern int GetWindowThreadProcessId(IntPtr handle, out int processId);
-
- [DllImport("user32.dll")]
- internal static extern uint SendInput(uint nInputs, Input[] pInputs, int cbSize);
- }
-}
diff --git a/src/modules/peek/Peek.UI.WPF/Native/NativeModels.cs b/src/modules/peek/Peek.UI.WPF/Native/NativeModels.cs
deleted file mode 100644
index 1cb3b6421e..0000000000
--- a/src/modules/peek/Peek.UI.WPF/Native/NativeModels.cs
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright (c) Microsoft Corporation
-// The Microsoft Corporation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Runtime.InteropServices;
-
-namespace Peek.UI.Native
-{
- public class NativeModels
- {
- public const int GwlExStyle = -20;
- public const int WsExToolWindow = 0x00000080;
-
- public enum PerceivedType
- {
- Folder = -1,
- Unknown = 0,
- Image = 2,
- Video = 4,
- Document = 6,
- }
-
- public enum Perceived
- {
- Undefined = 0x0000,
- Softcoded = 0x0001,
- Hardcoded = 0x0002,
- NativeSupport = 0x0004,
- GdiPlus = 0x0010,
- WMSDK = 0x0020,
- ZipFolder = 0x0040,
- }
-
- public enum HResult
- {
- Ok = 0x0000,
- False = 0x0001,
- InvalidArguments = unchecked((int)0x80070057),
- OutOfMemory = unchecked((int)0x8007000E),
- NoInterface = unchecked((int)0x80004002),
- Fail = unchecked((int)0x80004005),
- ExtractionFailed = unchecked((int)0x8004B200),
- ElementNotFound = unchecked((int)0x80070490),
- TypeElementNotFound = unchecked((int)0x8002802B),
- NoObject = unchecked((int)0x800401E5),
- Win32ErrorCanceled = 1223,
- Canceled = unchecked((int)0x800704C7),
- ResourceInUse = unchecked((int)0x800700AA),
- AccessDenied = unchecked((int)0x80030005),
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public struct Input
- {
- public InputType Type;
- public InputUnion Data;
-
- public static int Size
- {
- get { return Marshal.SizeOf(typeof(Input)); }
- }
- }
-
- [StructLayout(LayoutKind.Explicit)]
- public struct InputUnion
- {
- [FieldOffset(0)]
- public MouseInput Mi;
-
- [FieldOffset(0)]
- public KeybdInput Ki;
-
- [FieldOffset(0)]
- public HardwareInput Hi;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public struct MouseInput
- {
- public int Dx;
- public int Dy;
- public int MouseData;
- public uint DwFlags;
- public uint Time;
- public UIntPtr DwExtraInfo;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public struct KeybdInput
- {
- public short WVk;
- public short WScan;
- public uint DwFlags;
- public int Time;
- public UIntPtr DwExtraInfo;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public struct HardwareInput
- {
- public int UMsg;
- public short WParamL;
- public short WParamH;
- }
-
- public enum InputType : uint
- {
- InputMouse = 0,
- InputKeyboard = 1,
- InputHardware = 2,
- }
-
- public enum Sigdn : uint
- {
- NormalDisplay = 0,
- ParentRelativeParsing = 0x80018001,
- ParentRelativeForAddressBar = 0x8001c001,
- DesktopAbsoluteParsing = 0x80028000,
- ParentRelativeEditing = 0x80031001,
- DesktopAbsoluteEditing = 0x8004c000,
- FileSysPath = 0x80058000,
- Url = 0x80068000,
- }
-
- public enum DwmWindowAttributed
- {
- DwmaWindowCornerPreference = 33,
- }
-
- // The DWM_WINDOW_CORNER_PREFERENCE enum for DwmSetWindowAttribute's third parameter, which tells the function
- // what value of the enum to set.
- public enum DwmWindowCornerPreference
- {
- DwmCpDefault = 0,
- DwmCpDoNotRound = 1,
- DwmCpRound = 2,
- DwmCpRoundSmall = 3,
- }
-
- [Flags]
- public enum ThumbnailOptions
- {
- None = 0x00,
- BiggerSizeOk = 0x01,
- InMemoryOnly = 0x02,
- IconOnly = 0x04,
- ThumbnailOnly = 0x08,
- InCacheOnly = 0x10,
- ScaleUp = 0x100,
- }
-
- [ComImport]
- [Guid("bcc18b79-ba16-442f-80c4-8a59c30c463b")]
- [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- internal interface IShellItemImageFactory
- {
- [PreserveSig]
- HResult GetImage(
- [In, MarshalAs(UnmanagedType.Struct)] NativeSize size,
- [In] ThumbnailOptions flags,
- [Out] out IntPtr phbm);
- }
-
- [StructLayout(LayoutKind.Sequential)]
- internal struct NativeSize
- {
- private int width;
- private int height;
-
- public int Width
- {
- set { width = value; }
- }
-
- public int Height
- {
- set { height = value; }
- }
- }
- }
-}
diff --git a/src/modules/peek/Peek.UI.WPF/Peek.UI.WPF.csproj b/src/modules/peek/Peek.UI.WPF/Peek.UI.WPF.csproj
deleted file mode 100644
index 8bda35d12b..0000000000
--- a/src/modules/peek/Peek.UI.WPF/Peek.UI.WPF.csproj
+++ /dev/null
@@ -1,90 +0,0 @@
-
-
-
- WinExe
- net7.0-windows10.0.19041.0
- PowerToys.Peek.UI.WPF
- enable
- true
- false
- false
- ..\..\..\..\$(Platform)\$(Configuration)\modules\Peek.WPF\
- True
- Resources\FluentIconsPeek.ico
-
-
-
-
- tlbimp
- 0
- 1
- 50a7e9b0-70ef-11d1-b75a-00a0c90564fe
- 0
- false
- true
-
-
- tlbimp
- 1
- 1
- eab22ac0-30c1-11cf-a7eb-0000c05bae0b
- 0
- false
- true
-
-
-
-
- Resources\Peek.ico
-
-
-
-
-
-
-
-
- Always
-
-
- Always
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- $(DefaultXamlRuntime)
-
-
- $(DefaultXamlRuntime)
-
-
- $(DefaultXamlRuntime)
-
-
- $(DefaultXamlRuntime)
-
-
- $(DefaultXamlRuntime)
-
-
- $(DefaultXamlRuntime)
-
-
-
-
-
-
-
-
diff --git a/src/modules/peek/Peek.UI.WPF/Resources/Peek.ico b/src/modules/peek/Peek.UI.WPF/Resources/Peek.ico
deleted file mode 100644
index daf81fdeb3..0000000000
Binary files a/src/modules/peek/Peek.UI.WPF/Resources/Peek.ico and /dev/null differ
diff --git a/src/modules/peek/Peek.UI.WPF/Themes/Dark.xaml b/src/modules/peek/Peek.UI.WPF/Themes/Dark.xaml
deleted file mode 100644
index 14204cfe7f..0000000000
--- a/src/modules/peek/Peek.UI.WPF/Themes/Dark.xaml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
- Dark.Accent1
- PowerToysPeek
- Accent1 (Dark)
- Dark
- Accent1
- Black
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/modules/peek/Peek.UI.WPF/Themes/HighContrast1.xaml b/src/modules/peek/Peek.UI.WPF/Themes/HighContrast1.xaml
deleted file mode 100644
index cf168baaae..0000000000
--- a/src/modules/peek/Peek.UI.WPF/Themes/HighContrast1.xaml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
- HighContrast.Accent2
- PowerToysPeek
- Accent2 (HighContrast)
- HighContrast
- Accent2
- White
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/modules/peek/Peek.UI.WPF/Themes/HighContrast2.xaml b/src/modules/peek/Peek.UI.WPF/Themes/HighContrast2.xaml
deleted file mode 100644
index 65d8065e29..0000000000
--- a/src/modules/peek/Peek.UI.WPF/Themes/HighContrast2.xaml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
- HighContrast.Accent3
- PowerToysPeek
- Accent3 (HighContrast)
- HighContrast
- Accent3
- White
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/modules/peek/Peek.UI.WPF/Themes/HighContrastBlack.xaml b/src/modules/peek/Peek.UI.WPF/Themes/HighContrastBlack.xaml
deleted file mode 100644
index 402f414db6..0000000000
--- a/src/modules/peek/Peek.UI.WPF/Themes/HighContrastBlack.xaml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
- HighContrast.Accent4
- PowerToysPeek
- Accent4 (HighContrast)
- HighContrast
- Accent4
- White
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/modules/peek/Peek.UI.WPF/Themes/HighContrastWhite.xaml b/src/modules/peek/Peek.UI.WPF/Themes/HighContrastWhite.xaml
deleted file mode 100644
index bfe85de54f..0000000000
--- a/src/modules/peek/Peek.UI.WPF/Themes/HighContrastWhite.xaml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
- HighContrast.Accent5
- PowerToysPeek
- Accent5 (HighContrast)
- HighContrast
- Accent5
- White
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/modules/peek/Peek.UI.WPF/Themes/Light.xaml b/src/modules/peek/Peek.UI.WPF/Themes/Light.xaml
deleted file mode 100644
index 4ca102d2fe..0000000000
--- a/src/modules/peek/Peek.UI.WPF/Themes/Light.xaml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
- Light.Accent1
- PowerToysPeek
- Accent1 (Light)
- Light
- Accent1
- White
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/modules/peek/Peek.UI.WPF/ViewModels/MainViewModel.cs b/src/modules/peek/Peek.UI.WPF/ViewModels/MainViewModel.cs
deleted file mode 100644
index 406a36b4a3..0000000000
--- a/src/modules/peek/Peek.UI.WPF/ViewModels/MainViewModel.cs
+++ /dev/null
@@ -1,301 +0,0 @@
-// Copyright (c) Microsoft Corporation
-// The Microsoft Corporation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Media.Imaging;
-using Peek.UI.Extensions;
-using Peek.UI.Helpers;
-using Peek.UI.Models;
-using Peek.UI.Native;
-using WpfScreenHelper;
-using Size = System.Windows.Size;
-
-namespace Peek.UI.ViewModels
-{
- public class MainViewModel : ObservableObject, IDisposable
- {
- private const double ImageScale = 0.75;
- private static readonly Size MinWindowSize = new Size(720, 720);
- private static readonly Size AllowedContentGap = new Size(220, 220);
-
- private CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
-
- private CancellationToken CancellationToken => _cancellationTokenSource.Token;
-
- public IntPtr ForegroundWindowHandle { get; internal set; }
-
- public Image ImageControl { get; set; }
-
- public LinkedList SelectedFilePaths { get; set; } = new LinkedList();
-
- private BitmapSource? _bitmap;
-
- public BitmapSource? Bitmap
- {
- get
- {
- return _bitmap;
- }
-
- set
- {
- if (_bitmap != value)
- {
- _bitmap = value;
- OnPropertyChanged(nameof(Bitmap));
- }
- }
- }
-
- private LinkedListNode? _currentSelectedFilePath;
-
- public LinkedListNode? CurrentSelectedFilePath
- {
- get
- {
- return _currentSelectedFilePath;
- }
-
- set
- {
- if (_currentSelectedFilePath != value)
- {
- _currentSelectedFilePath = value;
- var title = Path.GetFileName(_currentSelectedFilePath?.Value ?? string.Empty);
- MainWindowData.Title = title;
- OnPropertyChanged(nameof(CurrentSelectedFilePath));
- }
- }
- }
-
- public Visibility IsImageReady => IsLoading ? Visibility.Collapsed : Visibility.Visible;
-
- private bool _isLoading = true;
-
- public bool IsLoading
- {
- get
- {
- return _isLoading;
- }
-
- set
- {
- if (_isLoading != value)
- {
- _isLoading = value;
- OnPropertyChanged(nameof(IsLoading));
- OnPropertyChanged(nameof(IsImageReady));
- }
- }
- }
-
- private ObservableWindowData _mainWindowData = new ObservableWindowData();
-
- public ObservableWindowData MainWindowData
- {
- get
- {
- return _mainWindowData;
- }
-
- set
- {
- if (_mainWindowData != value)
- {
- _mainWindowData = value;
- OnPropertyChanged(nameof(MainWindowData));
- }
- }
- }
-
- public MainViewModel(Image imageControl)
- {
- ImageControl = imageControl;
- }
-
- // TODO: Implement proper disposal pattern
- public void Dispose()
- {
- _cancellationTokenSource.Dispose();
- GC.SuppressFinalize(this);
- }
-
- public void ClearSelection()
- {
- _cancellationTokenSource.Cancel();
- _cancellationTokenSource = new CancellationTokenSource();
-
- CurrentSelectedFilePath = null;
- MainWindowData.Visibility = Visibility.Collapsed;
- }
-
- public bool TryUpdateSelectedFilePaths()
- {
- ForegroundWindowHandle = NativeMethods.GetForegroundWindow();
-
- // TODO: Get all neighborings files in correct sorted order
- var selectedItems = FileExplorerHelper.GetSelectedItems(ForegroundWindowHandle);
-
- var isDifferentSelectedItems = !SelectedFilePaths.SequenceEqual(selectedItems);
-
- if (isDifferentSelectedItems)
- {
- SelectedFilePaths = new LinkedList(selectedItems);
- }
-
- CurrentSelectedFilePath = SelectedFilePaths.First;
-
- return isDifferentSelectedItems;
- }
-
- // TODO: Implement proper cancellation pattern to support quick navigation
- public async Task RenderImageToWindowAsync(string filename)
- {
- IsLoading = true;
-
- var screen = Screen.FromHandle(ForegroundWindowHandle);
- Size maxWindowSize = new Size(screen.WpfBounds.Width * ImageScale, screen.WpfBounds.Height * ImageScale);
-
- // TODO: Support preview or thumbnail for document files
- if (FileTypeHelper.IsSupportedImage(Path.GetExtension(filename)))
- {
- await RenderSupportedImageToWindowAsync(filename, screen.Bounds, maxWindowSize);
- }
- else if (FileTypeHelper.IsMedia(Path.GetExtension(filename)) || FileTypeHelper.IsDocument(Path.GetExtension(filename)))
- {
- await RenderMediaOrDocumentToWindowAsync(filename, screen.Bounds, maxWindowSize);
- }
- else
- {
- await RenderUnsupportedFileToWindowAsync(filename, screen.Bounds, maxWindowSize);
- }
- }
-
- private async Task RenderSupportedImageToWindowAsync(string filename, Rect windowBounds, Size maxWindowSize)
- {
- DimensionData dimensionData = await FileLoadHelper.LoadDimensionsAsync(filename);
- if (CancellationToken.IsCancellationRequested)
- {
- _cancellationTokenSource = new CancellationTokenSource();
- return;
- }
-
- var windowRect = dimensionData.Size.Fit(windowBounds, maxWindowSize, MinWindowSize, AllowedContentGap, MainWindowData.TitleBarHeight);
-
- MainWindowData.Rectangle.Width = windowRect.Width;
- MainWindowData.Rectangle.Height = windowRect.Height;
- MainWindowData.Rectangle.Left = windowRect.Left;
- MainWindowData.Rectangle.Top = windowRect.Top;
-
- if (dimensionData.Size.Width > MainWindowData.Rectangle.Width || dimensionData.Size.Height > MainWindowData.Rectangle.Height)
- {
- ImageControl.StretchDirection = StretchDirection.Both;
- }
- else
- {
- ImageControl.StretchDirection = StretchDirection.DownOnly;
- }
-
- await LoadImageAsync(filename, ImageControl, dimensionData.Rotation, CancellationToken);
- }
-
- private async Task RenderMediaOrDocumentToWindowAsync(string filename, Rect windowBounds, Size maxWindowSize)
- {
- var bitmap = await FileLoadHelper.LoadThumbnailAsync(filename, true);
- if (CancellationToken.IsCancellationRequested)
- {
- _cancellationTokenSource = new CancellationTokenSource();
- return;
- }
-
- Bitmap = bitmap;
-
- var imageSize = new Size(bitmap.PixelWidth, bitmap.PixelHeight);
- var windowRect = imageSize.Fit(windowBounds, maxWindowSize, MinWindowSize, AllowedContentGap, MainWindowData.TitleBarHeight);
-
- MainWindowData.Rectangle.Width = windowRect.Width;
- MainWindowData.Rectangle.Height = windowRect.Height;
- MainWindowData.Rectangle.Left = windowRect.Left;
- MainWindowData.Rectangle.Top = windowRect.Top;
-
- MainWindowData.Visibility = Visibility.Visible;
- IsLoading = false;
- }
-
- private async Task RenderUnsupportedFileToWindowAsync(string filename, Rect windowBounds, Size maxWindowSize)
- {
- var contentSize = new Size(0, 0);
- var windowRect = contentSize.Fit(windowBounds, maxWindowSize, MinWindowSize, AllowedContentGap, MainWindowData.TitleBarHeight);
-
- MainWindowData.Rectangle.Width = windowRect.Width;
- MainWindowData.Rectangle.Height = windowRect.Height;
- MainWindowData.Rectangle.Left = windowRect.Left;
- MainWindowData.Rectangle.Top = windowRect.Top;
-
- var bitmap = await FileLoadHelper.LoadIconAsync(filename);
- if (CancellationToken.IsCancellationRequested)
- {
- _cancellationTokenSource = new CancellationTokenSource();
- return;
- }
-
- Bitmap = bitmap;
- MainWindowData.Visibility = Visibility.Visible;
- IsLoading = false;
- }
-
- private Task LoadImageAsync(string filename, System.Windows.Controls.Image imageControl, Rotation rotation, CancellationToken cancellationToken)
- {
- bool isFullImageLoaded = false;
- bool isThumbnailLoaded = false;
- var thumbnailLoadTask = imageControl.Dispatcher.Invoke(async () =>
- {
- var bitmap = await FileLoadHelper.LoadThumbnailAsync(filename, false);
- isThumbnailLoaded = true;
-
- if (CancellationToken.IsCancellationRequested)
- {
- _cancellationTokenSource = new CancellationTokenSource();
- return;
- }
-
- if (!isFullImageLoaded)
- {
- Bitmap = bitmap;
- MainWindowData.Visibility = Visibility.Visible;
- IsLoading = false;
- }
- });
-
- var fullImageLoadTask = imageControl.Dispatcher.Invoke(async () =>
- {
- var bitmap = await FileLoadHelper.LoadFullImageAsync(filename, rotation);
- isFullImageLoaded = true;
-
- if (CancellationToken.IsCancellationRequested)
- {
- _cancellationTokenSource = new CancellationTokenSource();
- return;
- }
-
- Bitmap = bitmap;
- if (!isThumbnailLoaded)
- {
- MainWindowData.Visibility = Visibility.Visible;
- IsLoading = false;
- }
- });
-
- return Task.WhenAll(thumbnailLoadTask, fullImageLoadTask);
- }
- }
-}
diff --git a/src/modules/peek/Peek.UI.WPF/Views/MainWindow.xaml b/src/modules/peek/Peek.UI.WPF/Views/MainWindow.xaml
deleted file mode 100644
index 6da3d32725..0000000000
--- a/src/modules/peek/Peek.UI.WPF/Views/MainWindow.xaml
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/modules/peek/Peek.UI.WPF/Views/MainWindow.xaml.cs b/src/modules/peek/Peek.UI.WPF/Views/MainWindow.xaml.cs
deleted file mode 100644
index dcfbc5cd53..0000000000
--- a/src/modules/peek/Peek.UI.WPF/Views/MainWindow.xaml.cs
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) Microsoft Corporation
-// The Microsoft Corporation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Windows;
-using System.Windows.Input;
-using interop;
-using ModernWpf.Controls;
-using Peek.UI.Extensions;
-using Peek.UI.Native;
-using Peek.UI.ViewModels;
-
-namespace Peek.UI.Views
-{
- ///
- /// Interaction logic for MainWindow.xaml
- ///
- public partial class MainWindow : Window, IDisposable
- {
- private readonly MainViewModel _viewModel;
-
- public MainWindow()
- {
- InitializeComponent();
-
- this.RoundCorners();
-
- _viewModel = new MainViewModel(ImageControl);
- _viewModel.PropertyChanged += MainViewModel_PropertyChanged;
-
- DataContext = _viewModel;
-
- NativeEventWaiter.WaitForEventLoop(Constants.ShowPeekEvent(), OnPeekHotkey);
-
- Loaded += MainWindow_Loaded;
- Closing += MainWindow_Closing;
- KeyDown += MainWindow_KeyDown;
- }
-
- private void MainWindow_Loaded(object sender, RoutedEventArgs e)
- {
- _viewModel.MainWindowData.Visibility = Visibility.Collapsed;
- _viewModel.MainWindowData.TitleBarHeight = TitleBar.GetHeight(this);
- _viewModel.ImageControl = ImageControl;
- }
-
- private void MainWindow_Closing(object? sender, System.ComponentModel.CancelEventArgs e)
- {
- _viewModel.MainWindowData.Visibility = Visibility.Collapsed;
- e.Cancel = true;
- }
-
- private void MainWindow_KeyDown(object? sender, KeyEventArgs e)
- {
- if (!e.IsRepeat && _viewModel.CurrentSelectedFilePath != null)
- {
- switch (e.Key)
- {
- case Key.Left:
- _viewModel.CurrentSelectedFilePath = _viewModel.CurrentSelectedFilePath.GetPreviousOrLast();
- e.Handled = true;
- break;
-
- case Key.Right:
- _viewModel.CurrentSelectedFilePath = _viewModel.CurrentSelectedFilePath.GetNextOrFirst();
- e.Handled = true;
- break;
-
- default: break;
- }
- }
- }
-
- public void Dispose()
- {
- _viewModel.Dispose();
- GC.SuppressFinalize(this);
- }
-
- protected override void OnSourceInitialized(EventArgs e)
- {
- base.OnSourceInitialized(e);
- this.SetToolStyle();
- }
-
- private async void MainViewModel_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
- {
- switch (e.PropertyName)
- {
- case nameof(MainViewModel.CurrentSelectedFilePath):
- if (_viewModel.CurrentSelectedFilePath != null)
- {
- await _viewModel.RenderImageToWindowAsync(_viewModel.CurrentSelectedFilePath.Value);
- }
-
- break;
- }
- }
-
- private void OnPeekHotkey()
- {
- if (IsActive && _viewModel.MainWindowData.Visibility == Visibility.Visible)
- {
- _viewModel.ClearSelection();
- }
- else
- {
- _viewModel.TryUpdateSelectedFilePaths();
- }
-
- this.BringToForeground();
- }
- }
-}