Merge remote-tracking branch 'origin/main' into dev/snickler/net8-upgrade

This commit is contained in:
Jeremy Sinclair 2023-08-27 11:08:38 -04:00
commit 4b06237af0
39 changed files with 324 additions and 153 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -27,6 +27,7 @@ namespace Common.UI
MeasureTool,
PowerOCR,
RegistryPreview,
CropAndLock,
}
private static string SettingsWindowNameToString(SettingsWindow value)
@ -65,6 +66,8 @@ namespace Common.UI
return "PowerOCR";
case SettingsWindow.RegistryPreview:
return "RegistryPreview";
case SettingsWindow.CropAndLock:
return "CropAndLock";
default:
{
return string.Empty;

View File

@ -254,5 +254,13 @@ public
static String ^ ShowHostsAdminSharedEvent() {
return gcnew String(CommonSharedConstants::SHOW_HOSTS_ADMIN_EVENT);
}
static String ^ CropAndLockThumbnailEvent() {
return gcnew String(CommonSharedConstants::CROP_AND_LOCK_THUMBNAIL_EVENT);
}
static String ^ CropAndLockReparentEvent() {
return gcnew String(CommonSharedConstants::CROP_AND_LOCK_REPARENT_EVENT);
}
};
}

View File

@ -192,7 +192,7 @@ void FindMyMouse::parse_settings(PowerToysSettings::PowerToyValues& settings)
}
else
{
throw;
throw std::runtime_error("Invalid Activation Method value");
}
}
@ -258,7 +258,7 @@ void FindMyMouse::parse_settings(PowerToysSettings::PowerToyValues& settings)
}
else
{
throw;
throw std::runtime_error("Invalid Overlay Opacity value");
}
}
catch (...)
@ -276,7 +276,7 @@ void FindMyMouse::parse_settings(PowerToysSettings::PowerToyValues& settings)
}
else
{
throw;
throw std::runtime_error("Invalid Spotlight Radius value");
}
}
catch (...)
@ -294,7 +294,7 @@ void FindMyMouse::parse_settings(PowerToysSettings::PowerToyValues& settings)
}
else
{
throw;
throw std::runtime_error("Invalid Animation Duration value");
}
}
catch (...)
@ -312,7 +312,7 @@ void FindMyMouse::parse_settings(PowerToysSettings::PowerToyValues& settings)
}
else
{
throw;
throw std::runtime_error("Invalid Spotlight Initial Zoom value");
}
}
catch (...)
@ -355,7 +355,7 @@ void FindMyMouse::parse_settings(PowerToysSettings::PowerToyValues& settings)
}
else
{
throw;
throw std::runtime_error("Invalid Shaking Minimum Distance value");
}
}
catch (...)

View File

@ -238,7 +238,7 @@ public:
}
else
{
throw;
throw std::runtime_error("Invalid Opacity value");
}
}
catch (...)
@ -314,7 +314,7 @@ public:
}
else
{
throw;
throw std::runtime_error("Invalid Radius value");
}
}
catch (...)
@ -332,7 +332,7 @@ public:
}
else
{
throw;
throw std::runtime_error("Invalid Fade Delay value");
}
}
catch (...)
@ -350,7 +350,7 @@ public:
}
else
{
throw;
throw std::runtime_error("Invalid Fade Duration value");
}
}
catch (...)

View File

@ -233,7 +233,7 @@ public:
}
else
{
throw;
throw std::runtime_error("Invalid Opacity value");
}
}
catch (...)
@ -270,7 +270,7 @@ public:
}
else
{
throw;
throw std::runtime_error("Invalid Radius value");
}
}
@ -289,7 +289,7 @@ public:
}
else
{
throw;
throw std::runtime_error("Invalid Thickness value");
}
}
@ -327,7 +327,7 @@ public:
}
else
{
throw;
throw std::runtime_error("Invalid Border Color value");
}
}
catch (...)
@ -366,7 +366,7 @@ public:
}
else
{
throw;
throw std::runtime_error("Invalid Fixed Length value");
}
}
catch (...)

View File

@ -342,7 +342,7 @@ private:
}
else
{
throw;
throw std::runtime_error("Invalid Press Time Windows Shortcuts value");
}
value = static_cast<int>(jsonPressTimeForTaskbarIconShortcutsObject.GetNamedNumber(L"value"));
if (value >= 0)
@ -351,7 +351,7 @@ private:
}
else
{
throw;
throw std::runtime_error("Invalid Press Time Taskbar Shortcuts value");
}
}
catch (...)

View File

@ -90,10 +90,10 @@ void FrameDrawer::Show()
Render();
}
void FrameDrawer::SetBorderRect(RECT windowRect, COLORREF color, int thickness, float radius)
void FrameDrawer::SetBorderRect(RECT windowRect, COLORREF rgb, float alpha, int thickness, float radius)
{
auto newSceneRect = DrawableRect{
.borderColor = ConvertColor(color),
.borderColor = ConvertColor(rgb, alpha),
.thickness = thickness,
};
@ -175,12 +175,12 @@ IDWriteFactory* FrameDrawer::GetWriteFactory()
return pDWriteFactory;
}
D2D1_COLOR_F FrameDrawer::ConvertColor(COLORREF color)
D2D1_COLOR_F FrameDrawer::ConvertColor(COLORREF color, float alpha)
{
return D2D1::ColorF(GetRValue(color) / 255.f,
GetGValue(color) / 255.f,
GetBValue(color) / 255.f,
1.f);
alpha);
}
D2D1_ROUNDED_RECT FrameDrawer::ConvertRect(RECT rect, int thickness, float radius)

View File

@ -18,7 +18,7 @@ public:
void Show();
void Hide();
void SetBorderRect(RECT windowRect, COLORREF color, int thickness, float radius);
void SetBorderRect(RECT windowRect, COLORREF rgb, float alpha, int thickness, float radius);
private:
bool CreateRenderTargets(const RECT& clientRect);
@ -33,7 +33,7 @@ private:
static ID2D1Factory* GetD2DFactory();
static IDWriteFactory* GetWriteFactory();
static D2D1_COLOR_F ConvertColor(COLORREF color);
static D2D1_COLOR_F ConvertColor(COLORREF color, float alpha);
static D2D1_ROUNDED_RECT ConvertRect(RECT rect, int thickness, float radius);
static D2D1_RECT_F ConvertRect(RECT rect, int thickness);
void Render();

View File

@ -17,6 +17,7 @@ namespace NonLocalizable
const static wchar_t* FrameEnabledID = L"frame-enabled";
const static wchar_t* FrameThicknessID = L"frame-thickness";
const static wchar_t* FrameColorID = L"frame-color";
const static wchar_t* FrameOpacityID = L"frame-opacity";
const static wchar_t* BlockInGameModeID = L"do-not-activate-on-game-mode";
const static wchar_t* ExcludedAppsID = L"excluded-apps";
const static wchar_t* FrameAccentColor = L"frame-accent-color";
@ -134,6 +135,16 @@ void AlwaysOnTopSettings::LoadSettings()
}
}
if (const auto jsonVal = values.get_int_value(NonLocalizable::FrameOpacityID))
{
auto val = *jsonVal;
if (m_settings.frameOpacity != val)
{
m_settings.frameOpacity = val;
NotifyObservers(SettingId::FrameOpacity);
}
}
if (const auto jsonVal = values.get_bool_value(NonLocalizable::FrameEnabledID))
{
auto val = *jsonVal;

View File

@ -21,6 +21,7 @@ struct Settings
bool blockInGameMode = true;
bool frameAccentColor = true;
int frameThickness = 15;
int frameOpacity = 100;
COLORREF frameColor = RGB(0, 173, 239);
std::vector<std::wstring> excludedApps{};
};

View File

@ -7,6 +7,7 @@ enum class SettingId
FrameEnabled,
FrameThickness,
FrameColor,
FrameOpacity,
BlockInGameMode,
ExcludeApps,
FrameAccentColor,

View File

@ -33,7 +33,7 @@ std::optional<RECT> GetFrameRect(HWND window)
}
WindowBorder::WindowBorder(HWND window) :
SettingsObserver({ SettingId::FrameColor, SettingId::FrameThickness, SettingId::FrameAccentColor, SettingId::RoundCornersEnabled }),
SettingsObserver({ SettingId::FrameColor, SettingId::FrameThickness, SettingId::FrameAccentColor, SettingId::FrameOpacity, SettingId::RoundCornersEnabled }),
m_window(nullptr),
m_trackingWindow(window),
m_frameDrawer(nullptr)
@ -113,6 +113,14 @@ bool WindowBorder::Init(HINSTANCE hinstance)
return false;
}
// make window transparent
int const pos = -GetSystemMetrics(SM_CXVIRTUALSCREEN) - 8;
if (wil::unique_hrgn hrgn{ CreateRectRgn(pos, 0, (pos + 1), 1) })
{
DWM_BLURBEHIND bh = { DWM_BB_ENABLE | DWM_BB_BLURREGION, TRUE, hrgn.get(), FALSE };
DwmEnableBlurBehindWindow(m_window, &bh);
}
if (!SetLayeredWindowAttributes(m_window, RGB(0, 0, 0), 0, LWA_COLORKEY))
{
return false;
@ -193,6 +201,7 @@ void WindowBorder::UpdateBorderProperties() const
color = AlwaysOnTopSettings::settings().frameColor;
}
float opacity = AlwaysOnTopSettings::settings().frameOpacity / 100.0f;
float scalingFactor = ScalingUtils::ScalingFactor(m_trackingWindow);
float thickness = AlwaysOnTopSettings::settings().frameThickness * scalingFactor;
float cornerRadius = 0.0;
@ -201,7 +210,7 @@ void WindowBorder::UpdateBorderProperties() const
cornerRadius = WindowCornerUtils::CornersRadius(m_trackingWindow) * scalingFactor;
}
m_frameDrawer->SetBorderRect(frameRect, color, static_cast<int>(thickness), cornerRadius);
m_frameDrawer->SetBorderRect(frameRect, color, opacity, static_cast<int>(thickness), cornerRadius);
}
LRESULT WindowBorder::WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept
@ -267,22 +276,14 @@ void WindowBorder::SettingsUpdate(SettingId id)
break;
case SettingId::FrameColor:
{
UpdateBorderProperties();
}
break;
case SettingId::FrameAccentColor:
{
UpdateBorderProperties();
}
break;
case SettingId::FrameOpacity:
case SettingId::RoundCornersEnabled:
{
UpdateBorderProperties();
}
break;
default:
break;
}

View File

@ -2,6 +2,7 @@
// 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.Threading;
using System.Windows.Input;
@ -15,17 +16,20 @@ namespace Microsoft.PowerToys.Run.Plugin.PowerToys.Components
{
public class Utility
{
public UtilityKey Key { get; }
public UtilityKey Key { get; private set; }
public string Name { get; }
public string Name { get; private set; }
public bool Enabled { get; private set; }
public Utility(UtilityKey key, string name, bool enabled)
public Func<ActionContext, bool> Action { get; private set; }
public Utility(UtilityKey key, string name, bool enabled, Func<ActionContext, bool> action)
{
Key = key;
Name = name;
Enabled = enabled;
Action = action;
}
public Result CreateResult(MatchResult matchResult)
@ -35,7 +39,7 @@ namespace Microsoft.PowerToys.Run.Plugin.PowerToys.Components
Title = Name,
SubTitle = Resources.Subtitle_Powertoys_Utility,
IcoPath = UtilityHelper.GetIcoPath(Key),
Action = UtilityHelper.GetAction(Key),
Action = Action,
ContextData = this,
Score = matchResult.Score,
TitleHighlightData = matchResult.MatchData,

View File

@ -2,11 +2,7 @@
// 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 Common.UI;
using interop;
using Wox.Plugin;
namespace Microsoft.PowerToys.Run.Plugin.PowerToys.Components
{
@ -23,6 +19,7 @@ namespace Microsoft.PowerToys.Run.Plugin.PowerToys.Components
UtilityKey.PowerOCR => "Images/PowerOcr.png",
UtilityKey.ShortcutGuide => "Images/ShortcutGuide.png",
UtilityKey.RegistryPreview => "Images/RegistryPreview.png",
UtilityKey.CropAndLock => "Images/CropAndLock.png",
_ => null,
};
}
@ -38,78 +35,9 @@ namespace Microsoft.PowerToys.Run.Plugin.PowerToys.Components
UtilityKey.PowerOCR => SettingsDeepLink.SettingsWindow.PowerOCR,
UtilityKey.ShortcutGuide => SettingsDeepLink.SettingsWindow.ShortcutGuide,
UtilityKey.RegistryPreview => SettingsDeepLink.SettingsWindow.RegistryPreview,
UtilityKey.CropAndLock => SettingsDeepLink.SettingsWindow.CropAndLock,
_ => null,
};
}
public static Func<ActionContext, bool> GetAction(UtilityKey key)
{
return (context) =>
{
switch (key)
{
case UtilityKey.ColorPicker: // Launch ColorPicker
using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.ShowColorPickerSharedEvent()))
{
eventHandle.Set();
}
break;
case UtilityKey.FancyZones: // Launch FancyZones Editor
using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.FZEToggleEvent()))
{
eventHandle.Set();
}
break;
case UtilityKey.Hosts: // Launch Hosts
{
using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.ShowHostsSharedEvent()))
{
eventHandle.Set();
}
}
break;
case UtilityKey.MeasureTool: // Launch Screen Ruler
using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.MeasureToolTriggerEvent()))
{
eventHandle.Set();
}
break;
case UtilityKey.PowerOCR: // Launch Text Extractor
using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.ShowPowerOCRSharedEvent()))
{
eventHandle.Set();
}
break;
case UtilityKey.ShortcutGuide: // Launch Shortcut Guide
using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.ShortcutGuideTriggerEvent()))
{
eventHandle.Set();
}
break;
case UtilityKey.RegistryPreview: // Launch Registry Preview
using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.RegistryPreviewTriggerEvent()))
{
eventHandle.Set();
}
break;
default:
break;
}
return true;
};
}
}
}

View File

@ -13,5 +13,6 @@ namespace Microsoft.PowerToys.Run.Plugin.PowerToys.Components
PowerOCR = 4,
ShortcutGuide = 5,
RegistryPreview = 6,
CropAndLock = 7,
}
}

View File

@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using interop;
using Microsoft.PowerToys.Run.Plugin.PowerToys.Components;
using Microsoft.PowerToys.Run.Plugin.PowerToys.Properties;
using Microsoft.PowerToys.Settings.UI.Library;
@ -32,37 +33,141 @@ namespace Microsoft.PowerToys.Run.Plugin.PowerToys
if (GPOWrapper.GetConfiguredColorPickerEnabledValue() != GpoRuleConfigured.Disabled)
{
_utilities.Add(new Utility(UtilityKey.ColorPicker, Resources.Color_Picker, generalSettings.Enabled.ColorPicker));
_utilities.Add(new Utility(
UtilityKey.ColorPicker,
Resources.Color_Picker,
generalSettings.Enabled.ColorPicker,
(_) =>
{
using var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.ShowColorPickerSharedEvent());
eventHandle.Set();
return true;
}));
}
if (GPOWrapper.GetConfiguredFancyZonesEnabledValue() != GpoRuleConfigured.Disabled)
{
_utilities.Add(new Utility(UtilityKey.FancyZones, Resources.FancyZones_Editor, generalSettings.Enabled.FancyZones));
_utilities.Add(new Utility(
UtilityKey.FancyZones,
Resources.FancyZones_Editor,
generalSettings.Enabled.FancyZones,
(_) =>
{
using var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.FZEToggleEvent());
eventHandle.Set();
return true;
}));
}
if (GPOWrapper.GetConfiguredHostsFileEditorEnabledValue() != GpoRuleConfigured.Disabled)
{
_utilities.Add(new Utility(UtilityKey.Hosts, Resources.Hosts_File_Editor, generalSettings.Enabled.Hosts));
_utilities.Add(new Utility(
UtilityKey.Hosts,
Resources.Hosts_File_Editor,
generalSettings.Enabled.Hosts,
(_) =>
{
using var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.ShowHostsSharedEvent());
eventHandle.Set();
return true;
}));
}
if (GPOWrapper.GetConfiguredScreenRulerEnabledValue() != GpoRuleConfigured.Disabled)
{
_utilities.Add(new Utility(UtilityKey.MeasureTool, Resources.Screen_Ruler, generalSettings.Enabled.MeasureTool));
_utilities.Add(new Utility(
UtilityKey.MeasureTool,
Resources.Screen_Ruler,
generalSettings.Enabled.MeasureTool,
(_) =>
{
using var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.MeasureToolTriggerEvent());
eventHandle.Set();
return true;
}));
}
if (GPOWrapper.GetConfiguredTextExtractorEnabledValue() != GpoRuleConfigured.Disabled)
{
_utilities.Add(new Utility(UtilityKey.PowerOCR, Resources.Text_Extractor, generalSettings.Enabled.PowerOCR));
_utilities.Add(new Utility(
UtilityKey.PowerOCR,
Resources.Text_Extractor,
generalSettings.Enabled.PowerOCR,
(_) =>
{
using var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.ShowPowerOCRSharedEvent());
eventHandle.Set();
return true;
}));
}
if (GPOWrapper.GetConfiguredShortcutGuideEnabledValue() != GpoRuleConfigured.Disabled)
{
_utilities.Add(new Utility(UtilityKey.ShortcutGuide, Resources.Shortcut_Guide, generalSettings.Enabled.ShortcutGuide));
_utilities.Add(new Utility(
UtilityKey.ShortcutGuide,
Resources.Shortcut_Guide,
generalSettings.Enabled.ShortcutGuide,
(_) =>
{
using var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.ShortcutGuideTriggerEvent());
eventHandle.Set();
return true;
}));
}
if (GPOWrapper.GetConfiguredRegistryPreviewEnabledValue() != GpoRuleConfigured.Disabled)
{
_utilities.Add(new Utility(UtilityKey.RegistryPreview, Resources.Registry_Preview, generalSettings.Enabled.RegistryPreview));
_utilities.Add(new Utility(
UtilityKey.RegistryPreview,
Resources.Registry_Preview,
generalSettings.Enabled.RegistryPreview,
(_) =>
{
using var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.RegistryPreviewTriggerEvent());
eventHandle.Set();
return true;
}));
}
if (GPOWrapper.GetConfiguredCropAndLockEnabledValue() != GpoRuleConfigured.Disabled)
{
_utilities.Add(new Utility(
UtilityKey.CropAndLock,
Resources.Crop_And_Lock_Thumbnail,
generalSettings.Enabled.CropAndLock,
(_) =>
{
// Wait for the Launcher window to be hidden and activate Crop And Lock in the correct window
var timer = new System.Timers.Timer(TimeSpan.FromMilliseconds(500));
timer.Elapsed += (_, _) =>
{
timer.Stop();
using var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.CropAndLockThumbnailEvent());
eventHandle.Set();
};
timer.Start();
return true;
}));
_utilities.Add(new Utility(
UtilityKey.CropAndLock,
Resources.Crop_And_Lock_Reparent,
generalSettings.Enabled.CropAndLock,
(_) =>
{
// Wait for the Launcher window to be hidden and activate Crop And Lock in the correct window
var timer = new System.Timers.Timer(TimeSpan.FromMilliseconds(500));
timer.Elapsed += (_, _) =>
{
timer.Stop();
using var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.CropAndLockReparentEvent());
eventHandle.Set();
};
timer.Start();
return true;
}));
}
_watcher = new FileSystemWatcher
@ -108,6 +213,7 @@ namespace Microsoft.PowerToys.Run.Plugin.PowerToys
case UtilityKey.MeasureTool: u.Enable(generalSettings.Enabled.MeasureTool); break;
case UtilityKey.ShortcutGuide: u.Enable(generalSettings.Enabled.ShortcutGuide); break;
case UtilityKey.RegistryPreview: u.Enable(generalSettings.Enabled.RegistryPreview); break;
case UtilityKey.CropAndLock: u.Enable(generalSettings.Enabled.CropAndLock); break;
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 968 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 921 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -66,33 +66,45 @@
</ItemGroup>
<ItemGroup>
<None Update="Images\ColorPicker.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\FancyZones.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\Hosts.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\PowerOcr.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\PowerToys.dark.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\PowerToys.light.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\RegistryPreview.png">
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\FluentIcons\FluentIconsColorPicker.png">
<Link>Images\ColorPicker.png</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\ScreenRuler.png">
</Content>
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\FluentIcons\FluentIconsFancyZones.png">
<Link>Images\FancyZones.png</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\ShortcutGuide.png">
</Content>
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\FluentIcons\FluentIconsCropAndLock.png">
<Link>Images\CropAndLock.png</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</Content>
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\FluentIcons\FluentIconsHosts.png">
<Link>Images\Hosts.png</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\FluentIcons\FluentIconsPowerOcr.png">
<Link>Images\PowerOcr.png</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\FluentIcons\FluentIconsRegistryPreview.png">
<Link>Images\RegistryPreview.png</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\FluentIcons\FluentIconsScreenRuler.png">
<Link>Images\ScreenRuler.png</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\FluentIcons\FluentIconsShortcutGuide.png">
<Link>Images\ShortcutGuide.png</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>

View File

@ -87,6 +87,24 @@ namespace Microsoft.PowerToys.Run.Plugin.PowerToys.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Crop And Lock (Reparent).
/// </summary>
internal static string Crop_And_Lock_Reparent {
get {
return ResourceManager.GetString("Crop_And_Lock_Reparent", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Crop And Lock (Thumbnail).
/// </summary>
internal static string Crop_And_Lock_Thumbnail {
get {
return ResourceManager.GetString("Crop_And_Lock_Thumbnail", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to FancyZones Editor.
/// </summary>

View File

@ -127,6 +127,14 @@
<value>Color Picker</value>
<comment>"Color Picker" is the name of the utility</comment>
</data>
<data name="Crop_And_Lock_Reparent" xml:space="preserve">
<value>Crop And Lock (Reparent)</value>
<comment>"Crop And Lock" is the name of the utility, "Reparent" is the activation mode</comment>
</data>
<data name="Crop_And_Lock_Thumbnail" xml:space="preserve">
<value>Crop And Lock (Thumbnail)</value>
<comment>"Crop And Lock" is the name of the utility, "Thumbnail" is the activation mode</comment>
</data>
<data name="FancyZones_Editor" xml:space="preserve">
<value>FancyZones Editor</value>
<comment>"FancyZones" is the name of the utility</comment>

View File

@ -17,12 +17,23 @@ namespace Peek.FilePreviewer.Previewers.Helpers
{
public static async Task<BitmapSource> GetBitmapFromHBitmapAsync(IntPtr hbitmap, bool isSupportingTransparency, CancellationToken cancellationToken)
{
Bitmap? bitmap = null;
try
{
var bitmap = Image.FromHbitmap(hbitmap);
if (isSupportingTransparency)
bitmap = Image.FromHbitmap(hbitmap);
cancellationToken.ThrowIfCancellationRequested();
if (isSupportingTransparency && bitmap.PixelFormat == PixelFormat.Format32bppRgb)
{
bitmap.MakeTransparent();
var bitmapRectangle = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
var bitmapData = bitmap.LockBits(bitmapRectangle, ImageLockMode.ReadOnly, bitmap.PixelFormat);
var transparentBitmap = new Bitmap(bitmapData.Width, bitmapData.Height, bitmapData.Stride, PixelFormat.Format32bppArgb, bitmapData.Scan0);
bitmap.Dispose();
bitmap = transparentBitmap;
}
var bitmapImage = new BitmapImage();
@ -41,6 +52,8 @@ namespace Peek.FilePreviewer.Previewers.Helpers
}
finally
{
bitmap?.Dispose();
// delete HBitmap to avoid memory leaks
NativeMethods.DeleteObject(hbitmap);
}
@ -50,8 +63,8 @@ namespace Peek.FilePreviewer.Previewers.Helpers
{
try
{
var icon = (Icon)Icon.FromHandle(hicon).Clone();
var bitmap = icon.ToBitmap();
using var icon = (Icon)Icon.FromHandle(hicon).Clone();
using var bitmap = icon.ToBitmap();
var bitmapImage = new BitmapImage();

View File

@ -7,9 +7,7 @@ using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Media.Imaging;
using Peek.Common;
using Peek.Common.Extensions;
using Peek.Common.Models;
namespace Peek.FilePreviewer.Previewers.Helpers
@ -20,6 +18,16 @@ namespace Peek.FilePreviewer.Previewers.Helpers
private const string IShellItem2Guid = "7E9FB0D3-919F-4307-AB2E-9B1860310C93";
public static async Task<ImageSource?> GetIconAsync(string fileName, CancellationToken cancellationToken)
{
return await GetImageAsync(fileName, ThumbnailOptions.BiggerSizeOk | ThumbnailOptions.IconOnly, true, cancellationToken);
}
public static async Task<ImageSource?> GetThumbnailAsync(string fileName, CancellationToken cancellationToken)
{
return await GetImageAsync(fileName, ThumbnailOptions.ThumbnailOnly, true, cancellationToken);
}
public static async Task<ImageSource?> GetImageAsync(string fileName, ThumbnailOptions options, bool isSupportingTransparency, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(fileName))
{
@ -28,6 +36,7 @@ namespace Peek.FilePreviewer.Previewers.Helpers
ImageSource? imageSource = null;
IShellItem? nativeShellItem = null;
IntPtr hbitmap = IntPtr.Zero;
try
{
@ -40,16 +49,22 @@ namespace Peek.FilePreviewer.Previewers.Helpers
}
NativeSize large = new NativeSize { Width = 256, Height = 256 };
var options = ThumbnailOptions.BiggerSizeOk | ThumbnailOptions.IconOnly;
HResult hr = ((IShellItemImageFactory)nativeShellItem).GetImage(large, options, out IntPtr hbitmap);
HResult hr = ((IShellItemImageFactory)nativeShellItem).GetImage(large, options, out hbitmap);
cancellationToken.ThrowIfCancellationRequested();
imageSource = hr == HResult.Ok ? await BitmapHelper.GetBitmapFromHBitmapAsync(hbitmap, true, cancellationToken) : null;
imageSource = hr == HResult.Ok ? await BitmapHelper.GetBitmapFromHBitmapAsync(hbitmap, isSupportingTransparency, cancellationToken) : null;
hbitmap = IntPtr.Zero;
}
finally
{
if (hbitmap != IntPtr.Zero)
{
NativeMethods.DeleteObject(hbitmap);
}
if (nativeShellItem != null)
{
Marshal.ReleaseComObject(nativeShellItem);

View File

@ -4,11 +4,9 @@
using System;
using System.Globalization;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml.Media.Imaging;
using Peek.Common.Extensions;
@ -76,7 +74,7 @@ namespace Peek.FilePreviewer.Previewers
else
{
State = PreviewState.Loaded;
}
}
}
public async Task CopyAsync()
@ -99,7 +97,8 @@ namespace Peek.FilePreviewer.Previewers
{
cancellationToken.ThrowIfCancellationRequested();
var iconBitmap = await IconHelper.GetIconAsync(Item.Path, cancellationToken);
var iconBitmap = await IconHelper.GetThumbnailAsync(Item.Path, cancellationToken)
?? await IconHelper.GetIconAsync(Item.Path, cancellationToken);
cancellationToken.ThrowIfCancellationRequested();

View File

@ -685,6 +685,8 @@ std::string ESettingsWindowNames_to_string(ESettingsWindowNames value)
return "PowerOCR";
case ESettingsWindowNames::RegistryPreview:
return "RegistryPreview";
case ESettingsWindowNames::CropAndLock:
return "CropAndLock";
default:
{
Logger::error(L"Can't convert ESettingsWindowNames value={} to string", static_cast<int>(value));
@ -760,6 +762,10 @@ ESettingsWindowNames ESettingsWindowNames_from_string(std::string value)
{
return ESettingsWindowNames::RegistryPreview;
}
else if (value == "CropAndLock")
{
return ESettingsWindowNames::CropAndLock;
}
else
{
Logger::error(L"Can't convert string value={} to ESettingsWindowNames", winrt::to_hstring(value));

View File

@ -20,6 +20,7 @@ enum class ESettingsWindowNames
MeasureTool,
PowerOCR,
RegistryPreview,
CropAndLock,
};
std::string ESettingsWindowNames_to_string(ESettingsWindowNames value);

View File

@ -15,6 +15,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
public const int DefaultFrameThickness = 15;
public const string DefaultFrameColor = "#0099cc";
public const bool DefaultFrameAccentColor = true;
public const int DefaultFrameOpacity = 100;
public const bool DefaultSoundEnabled = true;
public const bool DefaultDoNotActivateOnGameMode = true;
public const bool DefaultRoundCornersEnabled = true;
@ -26,6 +27,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
FrameThickness = new IntProperty(DefaultFrameThickness);
FrameColor = new StringProperty(DefaultFrameColor);
FrameAccentColor = new BoolProperty(DefaultFrameAccentColor);
FrameOpacity = new IntProperty(DefaultFrameOpacity);
SoundEnabled = new BoolProperty(DefaultSoundEnabled);
DoNotActivateOnGameMode = new BoolProperty(DefaultDoNotActivateOnGameMode);
RoundCornersEnabled = new BoolProperty(DefaultRoundCornersEnabled);
@ -44,6 +46,9 @@ namespace Microsoft.PowerToys.Settings.UI.Library
[JsonPropertyName("frame-color")]
public StringProperty FrameColor { get; set; }
[JsonPropertyName("frame-opacity")]
public IntProperty FrameOpacity { get; set; }
[JsonPropertyName("frame-accent-color")]
public BoolProperty FrameAccentColor { get; set; }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -401,6 +401,7 @@ namespace Microsoft.PowerToys.Settings.UI
case "RegistryPreview": return typeof(RegistryPreviewPage);
case "PastePlain": return typeof(PastePlainPage);
case "Peek": return typeof(PeekPage);
case "CropAndLock": return typeof(CropAndLockPage);
default:
// Fallback to general
Debug.Assert(false, "Unexpected SettingsWindow argument value");

View File

@ -80,6 +80,15 @@
Visibility="{x:Bind Mode=OneWay, Path=ViewModel.FrameAccentColor, Converter={StaticResource ReverseBoolToVisibilityConverter}}">
<controls:ColorPickerButton SelectedColor="{x:Bind Path=ViewModel.FrameColor, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="AlwaysOnTop_FrameOpacity"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.FrameEnabled}">
<Slider
MinWidth="{StaticResource SettingActionControlMinWidth}"
Maximum="100"
Minimum="0"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.FrameOpacity}" />
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="AlwaysOnTop_FrameThickness"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.FrameEnabled}">

View File

@ -3655,4 +3655,7 @@ Activate by holding the key for the character you want to add an accent to, then
<data name="Run_PluginUseFindMorePlugins.Content" xml:space="preserve">
<value>Find more plugins</value>
</data>
<data name="AlwaysOnTop_FrameOpacity.Header" xml:space="preserve">
<value>Opacity (%)</value>
</data>
</root>

View File

@ -46,6 +46,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
_frameEnabled = Settings.Properties.FrameEnabled.Value;
_frameThickness = Settings.Properties.FrameThickness.Value;
_frameColor = Settings.Properties.FrameColor.Value;
_frameOpacity = Settings.Properties.FrameOpacity.Value;
_frameAccentColor = Settings.Properties.FrameAccentColor.Value;
_soundEnabled = Settings.Properties.SoundEnabled.Value;
_doNotActivateOnGameMode = Settings.Properties.DoNotActivateOnGameMode.Value;
@ -179,6 +180,21 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
}
}
public int FrameOpacity
{
get => _frameOpacity;
set
{
if (value != _frameOpacity)
{
_frameOpacity = value;
Settings.Properties.FrameOpacity.Value = value;
NotifyPropertyChanged();
}
}
}
public bool SoundEnabled
{
get => _soundEnabled;
@ -284,6 +300,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
private int _frameThickness;
private string _frameColor;
private bool _frameAccentColor;
private int _frameOpacity;
private bool _soundEnabled;
private bool _doNotActivateOnGameMode;
private bool _roundCornersEnabled;

View File

@ -42,7 +42,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
ArgumentNullException.ThrowIfNull(findMyMouseSettingsRepository);
FindMyMouseSettingsConfig = findMyMouseSettingsRepository.SettingsConfig;
_findMyMouseActivationMethod = FindMyMouseSettingsConfig.Properties.ActivationMethod.Value;
_findMyMouseActivationMethod = FindMyMouseSettingsConfig.Properties.ActivationMethod.Value < 2 ? FindMyMouseSettingsConfig.Properties.ActivationMethod.Value : 0;
_findMyMouseDoNotActivateOnGameMode = FindMyMouseSettingsConfig.Properties.DoNotActivateOnGameMode.Value;
string backgroundColor = FindMyMouseSettingsConfig.Properties.BackgroundColor.Value;