mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 10:46:33 +02:00
[New Utility]Crop And Lock (#27832)
* [CropAndLock]Original POC code dump * Project rename and delete solution * Remove unused architectures * Update cppwinrt to be in line with the solution * Add to PowerToys solution and fix build errors * Initial module interface empty project * Module skeleton based on AlwaysOnTop * Add loggers to module interface * Add crop and lock to the runner * Enable starts and disable kills the process * Events reacting to hotkeys * Main application reacting to events * Initialize unhandled exception handling * Singleton in line with other projects * Also exit when PowerToys exit is detected * Create Settings page * React to shortcut changes in Settings * Disable Crop and Lock through an Event * Disable running Crop and Lock standalone * Remove Crop and Lock tray icon * Module Interface dll version * Fix main app resource file to include version * Make pch conditional on CI build * Add to signing * Remove settings screen opened by removed tray icon * Fix spellcheck * Yet another fix for spellcheck * Fix disabling utility * Fix solution build configurations * Fix C++ analyzer errors * Try to fix pre-compiled header CI errors * Fix crash while exiting with an active reparent window * Fix missing reference when building in release CI * Add OOBE page * GPO: Add admx and adml file changes * GPO: react to changes in GPO * Add quick access flyout menu entry * Use Crop And Lock icon * Use actual images for Settings and OOBE * Module and app telemetry * Add entry to README.md * Add to process lists * Additional logging * Attribution in Settings page * Add attribution to Community.md * Fix spellcheck * Fix typo in strings * Fix crash when window handle is no longer valid * Update COMMUNITY.md * Fix supportedOS in manifest * Don't show msgbox if detecting second instance * Remove unused hotkey * Tweak attribution * Fix attribution spellcheck
This commit is contained in:
27
src/settings-ui/Settings.UI.Library/CropAndLockProperties.cs
Normal file
27
src/settings-ui/Settings.UI.Library/CropAndLockProperties.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
// 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.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class CropAndLockProperties
|
||||
{
|
||||
public static readonly HotkeySettings DefaultReparentHotkeyValue = new HotkeySettings(true, true, false, true, 0x52); // Ctrl+Win+Shift+R
|
||||
public static readonly HotkeySettings DefaultThumbnailHotkeyValue = new HotkeySettings(true, true, false, true, 0x54); // Ctrl+Win+Shift+T
|
||||
|
||||
public CropAndLockProperties()
|
||||
{
|
||||
ReparentHotkey = new KeyboardKeysProperty(DefaultReparentHotkeyValue);
|
||||
ThumbnailHotkey = new KeyboardKeysProperty(DefaultThumbnailHotkeyValue);
|
||||
}
|
||||
|
||||
[JsonPropertyName("reparent-hotkey")]
|
||||
public KeyboardKeysProperty ReparentHotkey { get; set; }
|
||||
|
||||
[JsonPropertyName("thumbnail-hotkey")]
|
||||
public KeyboardKeysProperty ThumbnailHotkey { get; set; }
|
||||
}
|
||||
}
|
||||
35
src/settings-ui/Settings.UI.Library/CropAndLockSettings.cs
Normal file
35
src/settings-ui/Settings.UI.Library/CropAndLockSettings.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
// 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.Text.Json.Serialization;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class CropAndLockSettings : BasePTModuleSettings, ISettingsConfig
|
||||
{
|
||||
public const string ModuleName = "CropAndLock";
|
||||
public const string ModuleVersion = "0.0.1";
|
||||
|
||||
public CropAndLockSettings()
|
||||
{
|
||||
Name = ModuleName;
|
||||
Version = ModuleVersion;
|
||||
Properties = new CropAndLockProperties();
|
||||
}
|
||||
|
||||
[JsonPropertyName("properties")]
|
||||
public CropAndLockProperties Properties { get; set; }
|
||||
|
||||
public string GetModuleName()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
public bool UpgradeSettingsConfiguration()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -166,6 +166,23 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
}
|
||||
}
|
||||
|
||||
private bool cropAndLock = true;
|
||||
|
||||
[JsonPropertyName("CropAndLock")]
|
||||
public bool CropAndLock
|
||||
{
|
||||
get => cropAndLock;
|
||||
set
|
||||
{
|
||||
if (cropAndLock != value)
|
||||
{
|
||||
LogTelemetryEvent(value);
|
||||
cropAndLock = value;
|
||||
NotifyChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool awake;
|
||||
|
||||
[JsonPropertyName("Awake")]
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
@@ -10,6 +10,7 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Enums
|
||||
AlwaysOnTop,
|
||||
Awake,
|
||||
ColorPicker,
|
||||
CropAndLock,
|
||||
FancyZones,
|
||||
FileLocksmith,
|
||||
FileExplorer,
|
||||
|
||||
@@ -97,6 +97,9 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
case "ColorPicker":
|
||||
needToUpdate = generalSettingsConfig.Enabled.ColorPicker != isEnabled;
|
||||
generalSettingsConfig.Enabled.ColorPicker = isEnabled; break;
|
||||
case "CropAndLock":
|
||||
needToUpdate = generalSettingsConfig.Enabled.CropAndLock != isEnabled;
|
||||
generalSettingsConfig.Enabled.CropAndLock = isEnabled; break;
|
||||
case "FancyZones":
|
||||
needToUpdate = generalSettingsConfig.Enabled.FancyZones != isEnabled;
|
||||
generalSettingsConfig.Enabled.FancyZones = isEnabled; break;
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
<Page
|
||||
x:Class="Microsoft.PowerToys.Settings.UI.OOBE.Views.OobeCropAndLock"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:Microsoft.PowerToys.Settings.UI.OOBE.Views"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:toolkitcontrols="using:CommunityToolkit.WinUI.UI.Controls"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<controls:OOBEPageControl
|
||||
x:Uid="Oobe_CropAndLock"
|
||||
HeroImage="ms-appx:///Assets/Settings/Modules/OOBE/CropAndLock.gif">
|
||||
<controls:OOBEPageControl.PageContent>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock
|
||||
x:Uid="Oobe_HowToUse"
|
||||
Style="{ThemeResource OobeSubtitleStyle}" />
|
||||
|
||||
<controls:ShortcutWithTextLabelControl
|
||||
x:Name="ThumbnailHotkeyControl"
|
||||
x:Uid="Oobe_CropAndLock_HowToUse_Thumbnail" />
|
||||
|
||||
<controls:ShortcutWithTextLabelControl
|
||||
x:Name="ReparentHotkeyControl"
|
||||
x:Uid="Oobe_CropAndLock_HowToUse_Reparent" />
|
||||
|
||||
<StackPanel
|
||||
Margin="0,24,0,0"
|
||||
Orientation="Horizontal"
|
||||
Spacing="12">
|
||||
<Button
|
||||
x:Uid="OOBE_Settings"
|
||||
Click="SettingsLaunchButton_Click" />
|
||||
<HyperlinkButton
|
||||
NavigateUri="https://aka.ms/PowerToysOverview_CropAndLock"
|
||||
Style="{StaticResource TextButtonStyle}">
|
||||
<TextBlock
|
||||
x:Uid="LearnMore_CropAndLock"
|
||||
TextWrapping="Wrap" />
|
||||
</HyperlinkButton>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</controls:OOBEPageControl.PageContent>
|
||||
</controls:OOBEPageControl>
|
||||
</Page>
|
||||
@@ -0,0 +1,47 @@
|
||||
// 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 Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.OOBE.Enums;
|
||||
using Microsoft.PowerToys.Settings.UI.OOBE.ViewModel;
|
||||
using Microsoft.PowerToys.Settings.UI.Views;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Navigation;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
{
|
||||
public sealed partial class OobeCropAndLock : Page
|
||||
{
|
||||
public OobePowerToysModule ViewModel { get; set; }
|
||||
|
||||
public OobeCropAndLock()
|
||||
{
|
||||
InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.CropAndLock]);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(CropAndLockPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
}
|
||||
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
ViewModel.LogOpeningModuleEvent();
|
||||
ReparentHotkeyControl.Keys = SettingsRepository<CropAndLockSettings>.GetInstance(new SettingsUtils()).SettingsConfig.Properties.ReparentHotkey.Value.GetKeysList();
|
||||
ThumbnailHotkeyControl.Keys = SettingsRepository<CropAndLockSettings>.GetInstance(new SettingsUtils()).SettingsConfig.Properties.ThumbnailHotkey.Value.GetKeysList();
|
||||
}
|
||||
|
||||
protected override void OnNavigatedFrom(NavigationEventArgs e)
|
||||
{
|
||||
ViewModel.LogClosingModuleEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,6 +91,10 @@
|
||||
x:Uid="Shell_ColorPicker"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsColorPicker.png}"
|
||||
Tag="ColorPicker" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_CropAndLock"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsCropAndLock.png}"
|
||||
Tag="CropAndLock" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_FancyZones"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsFancyZones.png}"
|
||||
|
||||
@@ -84,6 +84,11 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
ModuleName = "ColorPicker",
|
||||
IsNew = false,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.CropAndLock, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "CropAndLock",
|
||||
IsNew = true,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.FancyZones, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "FancyZones",
|
||||
@@ -241,6 +246,7 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
case "AlwaysOnTop": NavigationFrame.Navigate(typeof(OobeAlwaysOnTop)); break;
|
||||
case "Awake": NavigationFrame.Navigate(typeof(OobeAwake)); break;
|
||||
case "ColorPicker": NavigationFrame.Navigate(typeof(OobeColorPicker)); break;
|
||||
case "CropAndLock": NavigationFrame.Navigate(typeof(OobeCropAndLock)); break;
|
||||
case "FancyZones": NavigationFrame.Navigate(typeof(OobeFancyZones)); break;
|
||||
case "FileLocksmith": NavigationFrame.Navigate(typeof(OobeFileLocksmith)); break;
|
||||
case "Run": NavigationFrame.Navigate(typeof(OobeRun)); break;
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
<Page
|
||||
x:Class="Microsoft.PowerToys.Settings.UI.Views.CropAndLockPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI.UI"
|
||||
AutomationProperties.LandmarkType="Main"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<controls:SettingsPageControl
|
||||
x:Uid="CropAndLock"
|
||||
IsTabStop="False"
|
||||
ModuleImageSource="ms-appx:///Assets/Settings/Modules/CropAndLock.png">
|
||||
<controls:SettingsPageControl.ModuleContent>
|
||||
<StackPanel Orientation="Vertical" ChildrenTransitions="{StaticResource SettingsCardsAnimations}">
|
||||
<labs:SettingsCard
|
||||
x:Uid="CropAndLock_EnableToggleControl_HeaderText"
|
||||
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsCropAndLock.png}"
|
||||
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
|
||||
<ToggleSwitch
|
||||
x:Uid="ToggleSwitch"
|
||||
IsOn="{x:Bind ViewModel.IsEnabled, Mode=TwoWay}" />
|
||||
</labs:SettingsCard>
|
||||
<InfoBar
|
||||
x:Uid="GPO_IsSettingForced"
|
||||
IsClosable="False"
|
||||
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
|
||||
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
|
||||
Severity="Informational" />
|
||||
<controls:SettingsGroup
|
||||
x:Uid="CropAndLock_Activation_GroupSettings"
|
||||
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
|
||||
|
||||
<labs:SettingsCard
|
||||
x:Uid="CropAndLock_ThumbnailActivation_Shortcut"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
|
||||
Glyph=}">
|
||||
<controls:ShortcutControl
|
||||
AllowDisable="True"
|
||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||
HotkeySettings="{x:Bind Path=ViewModel.ThumbnailActivationShortcut, Mode=TwoWay}" />
|
||||
</labs:SettingsCard>
|
||||
<labs:SettingsCard
|
||||
x:Uid="CropAndLock_ReparentActivation_Shortcut"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
|
||||
Glyph=}">
|
||||
<controls:ShortcutControl
|
||||
AllowDisable="True"
|
||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||
HotkeySettings="{x:Bind Path=ViewModel.ReparentActivationShortcut, Mode=TwoWay}" />
|
||||
</labs:SettingsCard>
|
||||
</controls:SettingsGroup>
|
||||
</StackPanel>
|
||||
</controls:SettingsPageControl.ModuleContent>
|
||||
|
||||
<controls:SettingsPageControl.PrimaryLinks>
|
||||
<controls:PageLink
|
||||
x:Uid="LearnMore_CropAndLock"
|
||||
Link="https://aka.ms/PowerToysOverview_CropAndLock" />
|
||||
</controls:SettingsPageControl.PrimaryLinks>
|
||||
<controls:SettingsPageControl.SecondaryLinks>
|
||||
<controls:PageLink
|
||||
Link="https://github.com/robmikh"
|
||||
Text="Robert Mikhayelyan" />
|
||||
<controls:PageLink
|
||||
Link="https://github.com/kevinguo305"
|
||||
Text="Kevin Guo" />
|
||||
</controls:SettingsPageControl.SecondaryLinks>
|
||||
</controls:SettingsPageControl>
|
||||
</Page>
|
||||
@@ -0,0 +1,29 @@
|
||||
// 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 Microsoft.PowerToys.Settings.UI.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.ViewModels;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
{
|
||||
public sealed partial class CropAndLockPage : Page, IRefreshablePage
|
||||
{
|
||||
private CropAndLockViewModel ViewModel { get; set; }
|
||||
|
||||
public CropAndLockPage()
|
||||
{
|
||||
var settingsUtils = new SettingsUtils();
|
||||
ViewModel = new CropAndLockViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), SettingsRepository<CropAndLockSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage);
|
||||
DataContext = ViewModel;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public void RefreshEnabledState()
|
||||
{
|
||||
ViewModel.RefreshEnabledState();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,6 +106,11 @@
|
||||
helpers:NavHelper.NavigateTo="views:ColorPickerPage"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsColorPicker.png}" />
|
||||
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_CropAndLock"
|
||||
helpers:NavHelper.NavigateTo="views:CropAndLockPage"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsCropAndLock.png}" />
|
||||
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_FancyZones"
|
||||
helpers:NavHelper.NavigateTo="views:FancyZonesPage"
|
||||
|
||||
@@ -2719,6 +2719,59 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
|
||||
<value>On</value>
|
||||
<comment>The state of a ToggleSwitch when it's on</comment>
|
||||
</data>
|
||||
<data name="CropAndLock.ModuleDescription" xml:space="preserve">
|
||||
<value>Crop And Lock allows you to crop a current application into a smaller window or just create a thumbnail. Focus the target window and press the shortcut to start cropping.</value>
|
||||
<comment>"Crop And Lock" is the name of the utility</comment>
|
||||
</data>
|
||||
<data name="CropAndLock.ModuleTitle" xml:space="preserve">
|
||||
<value>Crop And Lock </value>
|
||||
<comment>"Crop And Lock" is the name of the utility</comment>
|
||||
</data>
|
||||
<data name="CropAndLock_Activation_GroupSettings.Header" xml:space="preserve">
|
||||
<value>Activation</value>
|
||||
</data>
|
||||
<data name="CropAndLock_EnableToggleControl_HeaderText.Header" xml:space="preserve">
|
||||
<value>Enable Crop And Lock</value>
|
||||
<comment>"Crop And Lock" is the name of the utility</comment>
|
||||
</data>
|
||||
<data name="Shell_CropAndLock.Content" xml:space="preserve">
|
||||
<value>Crop And Lock</value>
|
||||
<comment>"Crop And Lock" is the name of the utility</comment>
|
||||
</data>
|
||||
<data name="LearnMore_CropAndLock.Text" xml:space="preserve">
|
||||
<value>Learn more about Crop And Lock</value>
|
||||
<comment>"Crop And Lock" is the name of the utility</comment>
|
||||
</data>
|
||||
<data name="CropAndLock_ReparentActivation_Shortcut.Header" xml:space="preserve">
|
||||
<value>Reparent shortcut</value>
|
||||
</data>
|
||||
<data name="CropAndLock_ReparentActivation_Shortcut.Description" xml:space="preserve">
|
||||
<value>Shortcut to crop an application's window into a cropped window. This is experimental and can cause issues with some applications, since the cropped window will contain the original application window.</value>
|
||||
</data>
|
||||
<data name="CropAndLock_ThumbnailActivation_Shortcut.Header" xml:space="preserve">
|
||||
<value>Thumbnail shortcut</value>
|
||||
</data>
|
||||
<data name="CropAndLock_ThumbnailActivation_Shortcut.Description" xml:space="preserve">
|
||||
<value>Shortcut to crop and create a thumbnail of another window. The application isn't controllable through the thumbnail but it'll have less compatibility issues. </value>
|
||||
</data>
|
||||
<data name="CropAndLock.SecondaryLinksHeader" xml:space="preserve">
|
||||
<value>Attribution</value>
|
||||
<comment>giving credit to the projects this utility was based on</comment>
|
||||
</data>
|
||||
<data name="Oobe_CropAndLock.Title" xml:space="preserve">
|
||||
<value>Crop And Lock</value>
|
||||
<comment>"Crop And Lock" is the name of the utility</comment>
|
||||
</data>
|
||||
<data name="Oobe_CropAndLock.Description" xml:space="preserve">
|
||||
<value>Crop And Lock allows you to crop a current application into a smaller window or just create a thumbnail. Focus the target window and press the shortcut to start cropping.</value>
|
||||
<comment>"Crop And Lock" is the name of the utility</comment>
|
||||
</data>
|
||||
<data name="Oobe_CropAndLock_HowToUse_Thumbnail.Text" xml:space="preserve">
|
||||
<value>to crop and create a thumbnail of another window. The application isn't controllable through the thumbnail but it'll have less compatibility issues.</value>
|
||||
</data>
|
||||
<data name="Oobe_CropAndLock_HowToUse_Reparent.Text" xml:space="preserve">
|
||||
<value>to crop an application's window into a cropped window. This is experimental and can cause issues with some applications, since the cropped window will contain the original application window.</value>
|
||||
</data>
|
||||
<data name="AlwaysOnTop.ModuleDescription" xml:space="preserve">
|
||||
<value>Always On Top is a quick and easy way to pin windows on top.</value>
|
||||
<comment>"Always On Top" is the name of the utility</comment>
|
||||
|
||||
187
src/settings-ui/Settings.UI/ViewModels/CropAndLockViewModel.cs
Normal file
187
src/settings-ui/Settings.UI/ViewModels/CropAndLockViewModel.cs
Normal file
@@ -0,0 +1,187 @@
|
||||
// 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.Globalization;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text.Json;
|
||||
using global::PowerToys.GPOWrapper;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
{
|
||||
public class CropAndLockViewModel : Observable
|
||||
{
|
||||
private ISettingsUtils SettingsUtils { get; set; }
|
||||
|
||||
private GeneralSettings GeneralSettingsConfig { get; set; }
|
||||
|
||||
private CropAndLockSettings Settings { get; set; }
|
||||
|
||||
private Func<string, int> SendConfigMSG { get; }
|
||||
|
||||
public CropAndLockViewModel(ISettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, ISettingsRepository<CropAndLockSettings> moduleSettingsRepository, Func<string, int> ipcMSGCallBackFunc)
|
||||
{
|
||||
if (settingsUtils == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(settingsUtils));
|
||||
}
|
||||
|
||||
SettingsUtils = settingsUtils;
|
||||
|
||||
// To obtain the general settings configurations of PowerToys Settings.
|
||||
if (settingsRepository == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(settingsRepository));
|
||||
}
|
||||
|
||||
GeneralSettingsConfig = settingsRepository.SettingsConfig;
|
||||
|
||||
InitializeEnabledValue();
|
||||
|
||||
// To obtain the settings configurations of CropAndLock.
|
||||
if (moduleSettingsRepository == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(moduleSettingsRepository));
|
||||
}
|
||||
|
||||
Settings = moduleSettingsRepository.SettingsConfig;
|
||||
|
||||
_reparentHotkey = Settings.Properties.ReparentHotkey.Value;
|
||||
_thumbnailHotkey = Settings.Properties.ThumbnailHotkey.Value;
|
||||
|
||||
// set the callback functions value to hangle outgoing IPC message.
|
||||
SendConfigMSG = ipcMSGCallBackFunc;
|
||||
}
|
||||
|
||||
private void InitializeEnabledValue()
|
||||
{
|
||||
_enabledGpoRuleConfiguration = GPOWrapper.GetConfiguredCropAndLockEnabledValue();
|
||||
if (_enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled)
|
||||
{
|
||||
// Get the enabled state from GPO.
|
||||
_enabledStateIsGPOConfigured = true;
|
||||
_isEnabled = _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled;
|
||||
}
|
||||
else
|
||||
{
|
||||
_isEnabled = GeneralSettingsConfig.Enabled.CropAndLock;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsEnabled
|
||||
{
|
||||
get => _isEnabled;
|
||||
|
||||
set
|
||||
{
|
||||
if (_enabledStateIsGPOConfigured)
|
||||
{
|
||||
// If it's GPO configured, shouldn't be able to change this state.
|
||||
return;
|
||||
}
|
||||
|
||||
if (value != _isEnabled)
|
||||
{
|
||||
_isEnabled = value;
|
||||
|
||||
// Set the status in the general settings configuration
|
||||
GeneralSettingsConfig.Enabled.CropAndLock = value;
|
||||
OutGoingGeneralSettings snd = new OutGoingGeneralSettings(GeneralSettingsConfig);
|
||||
|
||||
SendConfigMSG(snd.ToString());
|
||||
OnPropertyChanged(nameof(IsEnabled));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsEnabledGpoConfigured
|
||||
{
|
||||
get => _enabledStateIsGPOConfigured;
|
||||
}
|
||||
|
||||
public HotkeySettings ReparentActivationShortcut
|
||||
{
|
||||
get => _reparentHotkey;
|
||||
|
||||
set
|
||||
{
|
||||
if (value != _reparentHotkey)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
_reparentHotkey = CropAndLockProperties.DefaultReparentHotkeyValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
_reparentHotkey = value;
|
||||
}
|
||||
|
||||
Settings.Properties.ReparentHotkey.Value = _reparentHotkey;
|
||||
NotifyPropertyChanged();
|
||||
|
||||
// Using InvariantCulture as this is an IPC message
|
||||
SendConfigMSG(
|
||||
string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"{{ \"powertoys\": {{ \"{0}\": {1} }} }}",
|
||||
CropAndLockSettings.ModuleName,
|
||||
JsonSerializer.Serialize(Settings)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public HotkeySettings ThumbnailActivationShortcut
|
||||
{
|
||||
get => _thumbnailHotkey;
|
||||
|
||||
set
|
||||
{
|
||||
if (value != _thumbnailHotkey)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
_thumbnailHotkey = CropAndLockProperties.DefaultThumbnailHotkeyValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
_thumbnailHotkey = value;
|
||||
}
|
||||
|
||||
Settings.Properties.ThumbnailHotkey.Value = _thumbnailHotkey;
|
||||
NotifyPropertyChanged();
|
||||
|
||||
// Using InvariantCulture as this is an IPC message
|
||||
SendConfigMSG(
|
||||
string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"{{ \"powertoys\": {{ \"{0}\": {1} }} }}",
|
||||
CropAndLockSettings.ModuleName,
|
||||
JsonSerializer.Serialize(Settings)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
OnPropertyChanged(propertyName);
|
||||
SettingsUtils.SaveSettings(Settings.ToJsonString(), CropAndLockSettings.ModuleName);
|
||||
}
|
||||
|
||||
public void RefreshEnabledState()
|
||||
{
|
||||
InitializeEnabledValue();
|
||||
OnPropertyChanged(nameof(IsEnabled));
|
||||
}
|
||||
|
||||
private GpoRuleConfigured _enabledGpoRuleConfiguration;
|
||||
private bool _enabledStateIsGPOConfigured;
|
||||
private bool _isEnabled;
|
||||
private HotkeySettings _reparentHotkey;
|
||||
private HotkeySettings _thumbnailHotkey;
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,11 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
FlyoutMenuItems.Add(new FlyoutMenuItem() { Label = resourceLoader.GetString("ColorPicker/ModuleTitle"), IsEnabled = generalSettingsConfig.Enabled.ColorPicker, Tag = "ColorPicker", Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsColorPicker.png", EnabledChangedCallback = EnabledChangedOnUI });
|
||||
}
|
||||
|
||||
if ((gpo = GPOWrapper.GetConfiguredCropAndLockEnabledValue()) != GpoRuleConfigured.Disabled && gpo != GpoRuleConfigured.Enabled)
|
||||
{
|
||||
FlyoutMenuItems.Add(new FlyoutMenuItem() { Label = resourceLoader.GetString("CropAndLock/ModuleTitle"), IsEnabled = generalSettingsConfig.Enabled.CropAndLock, Tag = "CropAndLock", Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsCropAndLock.png", EnabledChangedCallback = EnabledChangedOnUI });
|
||||
}
|
||||
|
||||
if ((gpo = GPOWrapper.GetConfiguredFancyZonesEnabledValue()) != GpoRuleConfigured.Disabled && gpo != GpoRuleConfigured.Enabled)
|
||||
{
|
||||
FlyoutMenuItems.Add(new FlyoutMenuItem() { Label = resourceLoader.GetString("FancyZones/ModuleTitle"), IsEnabled = generalSettingsConfig.Enabled.FancyZones, Tag = "FancyZones", Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsFancyZones.png", EnabledChangedCallback = EnabledChangedOnUI });
|
||||
@@ -165,6 +170,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
case "AlwaysOnTop": item.IsEnabled = generalSettingsConfig.Enabled.AlwaysOnTop; break;
|
||||
case "Awake": item.IsEnabled = generalSettingsConfig.Enabled.Awake; break;
|
||||
case "ColorPicker": item.IsEnabled = generalSettingsConfig.Enabled.ColorPicker; break;
|
||||
case "CropAndLock": item.IsEnabled = generalSettingsConfig.Enabled.CropAndLock; break;
|
||||
case "FancyZones": item.IsEnabled = generalSettingsConfig.Enabled.FancyZones; break;
|
||||
case "FileLocksmith": item.IsEnabled = generalSettingsConfig.Enabled.FileLocksmith; break;
|
||||
case "FindMyMouse": item.IsEnabled = generalSettingsConfig.Enabled.FindMyMouse; break;
|
||||
|
||||
Reference in New Issue
Block a user