mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-06-07 09:28:03 +08:00
Merge branch 'dev/build-features' into dev/traies/build_features_launcher_integration
This commit is contained in:
commit
e6b43e19c2
@ -817,14 +817,6 @@ Global
|
||||
{A7D5099E-F0FD-4BF3-8522-5A682759F915}.Release|ARM64.ActiveCfg = Release|Win32
|
||||
{A7D5099E-F0FD-4BF3-8522-5A682759F915}.Release|x64.ActiveCfg = Release|x64
|
||||
{A7D5099E-F0FD-4BF3-8522-5A682759F915}.Release|x64.Build.0 = Release|x64
|
||||
{A7D5099E-F0FD-4BF3-8522-5A682759F915}.Release|x64.Deploy.0 = Release|x64
|
||||
{A7D5099E-F0FD-4BF3-8522-5A682759F915}.Release|x86.ActiveCfg = Release|Win32
|
||||
{A7D5099E-F0FD-4BF3-8522-5A682759F915}.Release|x86.Build.0 = Release|Win32
|
||||
{A7D5099E-F0FD-4BF3-8522-5A682759F915}.Release|x86.Deploy.0 = Release|Win32
|
||||
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Debug|ARM64.ActiveCfg = Debug|Any CPU
|
||||
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Debug|ARM64.Build.0 = Debug|Any CPU
|
||||
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Debug|x64.Build.0 = Debug|x64
|
||||
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
|
@ -71,7 +71,7 @@
|
||||
<RegistrySearch Id="ExistingExtPath" Root="HKCR" Key="CLSID\{0440049F-D1DC-4E46-B27B-98393D79486B}\InprocServer32" Type="raw"/>
|
||||
</Property>
|
||||
<Property Id ="EXISTINGIMAGERESIZERPATH">
|
||||
<RegistrySearch Id="ExistingImageResizerPath" Root="HKCU" Key="Software\Classes\CLSID\{51B4D7E5-7568-4234-B4BB-47FB3C016A69}\InprocServer32" Type="raw"/>
|
||||
<RegistrySearch Id="ExistingImageResizerPath" Root="HKCR" Key="CLSID\{51B4D7E5-7568-4234-B4BB-47FB3C016A69}\InprocServer32" Type="raw"/>
|
||||
</Property>
|
||||
|
||||
<InstallUISequence>
|
||||
@ -255,6 +255,16 @@
|
||||
<Directory Id="LauncherPropertiesFolder" Name="Properties" />
|
||||
</Directory>
|
||||
</Directory>
|
||||
<Directory Id="SettingsV2InstallFolder" Name="SettingsUIRunner">
|
||||
<Directory Id="SettingsV2ViewsInstallFolder" Name="Views"/>
|
||||
<Directory Id="SettingsV2StylesInstallFolder" Name="Styles"/>
|
||||
<Directory Id="SettingsV2PropertiesInstallFolder" Name="Properties"/>
|
||||
<Directory Id="SettingsV2AssetsInstallFolder" Name="Assets"/>
|
||||
<Directory Id="SettingsV2ControlsInstallFolder" Name="Controls"/>
|
||||
<Directory Id="SettingsV2XamlInstallFolder" Name="Microsoft.UI.Xaml">
|
||||
<Directory Id="SettingsV2XamlAssetsInstallFolder" Name="Assets" />
|
||||
</Directory>
|
||||
</Directory>
|
||||
<Directory Id="SettingsHtmlInstallFolder" Name="settings-html">
|
||||
<Directory Id="SettingsHtmlDistInstallFolder" Name="dist"/>
|
||||
</Directory>
|
||||
@ -268,7 +278,7 @@
|
||||
<Fragment>
|
||||
<DirectoryRef Id="INSTALLFOLDER" FileSource="$(var.BinX64Dir)">
|
||||
<Component Id="powertoys_toast_clsid" Win64="yes">
|
||||
<RegistryKey Root="HKCU" Key="Software\Classes\CLSID\{DD5CACDA-7C2E-4997-A62A-04A597B58F76}">
|
||||
<RegistryKey Root="HKCR" Key="Software\Classes\CLSID\{DD5CACDA-7C2E-4997-A62A-04A597B58F76}">
|
||||
<RegistryValue Type="string" Value="PowerToys Toast Notifications Background Activator" />
|
||||
<RegistryValue Type="string" Key="LocalServer32" Value="[INSTALLFOLDER]PowerToys.exe -ToastActivated" />
|
||||
<RegistryValue Type="string" Key="LocalServer32" Name="ThreadingModel" Value="Apartment" />
|
||||
@ -314,6 +324,9 @@
|
||||
<Component Id="License_rtf" Guid="3E5AE43B-CFB4-449B-A346-94CAAFF3312E" Win64="yes">
|
||||
<File Source="$(var.RepoDir)\installer\License.rtf" Id="License.rtf" KeyPath="yes" />
|
||||
</Component>
|
||||
<Component Id="powertoysinterop_dll" Guid="B7DD2DF4-C8F2-46FA-9571-D6EF1588ADF3" Win64="yes">
|
||||
<File Id="PowerToysInterop.dll" KeyPath="yes" Checksum="yes" />
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
<DirectoryRef Id="SvgsInstallFolder" FileSource="$(var.BinX64Dir)\svgs\">
|
||||
<Component Id="PowerToysSvgs" Guid="7C4D4EED-9338-423D-992C-DCE02F3E2D35" Win64="yes">
|
||||
@ -378,6 +391,10 @@
|
||||
<File Source="$(var.BinX64Dir)\modules\Microsoft.Launcher.dll" />
|
||||
</Component>
|
||||
|
||||
<Component Id="Module_KeyboardManager" Guid="9279BD82-786F-4F0B-8E49-DB484EE34C9B" Win64="yes">
|
||||
<File Source="$(var.BinX64Dir)\modules\KeyboardManager.dll" />
|
||||
</Component>
|
||||
|
||||
<Component Id="Module_ImageResizer" Guid="96E63289-759C-4A73-A56B-EE7429932F72" Win64="yes">
|
||||
<File Source="$(var.BinX64Dir)\modules\ImageResizer.exe">
|
||||
<netfx:NativeImage Id="ImageResizer.exe" Platform="all" Priority="0" />
|
||||
@ -393,68 +410,68 @@
|
||||
<File Source="$(var.BinX64Dir)\modules\ImageResizerExt.dll" KeyPath="yes" />
|
||||
</Component>
|
||||
<Component Id="Module_ImageResizer_Registry" Guid="8B593E2C-2D9B-4EBC-93F7-A2B69707DAC9" Win64="yes">
|
||||
<RegistryKey Root="HKCU" Key="Software\Classes\CLSID\{51B4D7E5-7568-4234-B4BB-47FB3C016A69}\InprocServer32">
|
||||
<RegistryKey Root="HKCR" Key="CLSID\{51B4D7E5-7568-4234-B4BB-47FB3C016A69}\InprocServer32">
|
||||
<RegistryValue Value="[ModulesInstallFolder]ImageResizerExt.dll" Type="string" />
|
||||
<RegistryValue Name="ThreadingModel" Value="Apartment" Type="string" />
|
||||
</RegistryKey>
|
||||
<!-- Registry Key for the drag and drop handler -->
|
||||
<RegistryValue Root="HKCU"
|
||||
Key="Software\Classes\Directory\ShellEx\DragDropHandlers\ImageResizer"
|
||||
<RegistryValue Root="HKCR"
|
||||
Key="Directory\ShellEx\DragDropHandlers\ImageResizer"
|
||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||
Type="string" />
|
||||
<!-- Registry Keys for the context menu handler for each of the following image formats: bmp, dib, gif, jfif, jpe, jpeg, jpg, jxr, png, rle, tif, tiff, wdp -->
|
||||
<RegistryValue Root="HKCU"
|
||||
Key="Software\Classes\SystemFileAssociations\.bmp\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
<RegistryValue Root="HKCR"
|
||||
Key="SystemFileAssociations\.bmp\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||
Type="string" />
|
||||
<RegistryValue Root="HKCU"
|
||||
Key="Software\Classes\SystemFileAssociations\.dib\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
<RegistryValue Root="HKCR"
|
||||
Key="SystemFileAssociations\.dib\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||
Type="string" />
|
||||
<RegistryValue Root="HKCU"
|
||||
Key="Software\Classes\SystemFileAssociations\.gif\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
<RegistryValue Root="HKCR"
|
||||
Key="SystemFileAssociations\.gif\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||
Type="string" />
|
||||
<RegistryValue Root="HKCU"
|
||||
Key="Software\Classes\SystemFileAssociations\.jfif\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
<RegistryValue Root="HKCR"
|
||||
Key="SystemFileAssociations\.jfif\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||
Type="string" />
|
||||
<RegistryValue Root="HKCU"
|
||||
Key="Software\Classes\SystemFileAssociations\.jpe\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
<RegistryValue Root="HKCR"
|
||||
Key="SystemFileAssociations\.jpe\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||
Type="string" />
|
||||
<RegistryValue Root="HKCU"
|
||||
Key="Software\Classes\SystemFileAssociations\.jpeg\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
<RegistryValue Root="HKCR"
|
||||
Key="SystemFileAssociations\.jpeg\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||
Type="string" />
|
||||
<RegistryValue Root="HKCU"
|
||||
Key="Software\Classes\SystemFileAssociations\.jpg\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
<RegistryValue Root="HKCR"
|
||||
Key="SystemFileAssociations\.jpg\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||
Type="string" />
|
||||
<RegistryValue Root="HKCU"
|
||||
Key="Software\Classes\SystemFileAssociations\.jxr\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
<RegistryValue Root="HKCR"
|
||||
Key="SystemFileAssociations\.jxr\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||
Type="string" />
|
||||
<RegistryValue Root="HKCU"
|
||||
Key="Software\Classes\SystemFileAssociations\.png\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
<RegistryValue Root="HKCR"
|
||||
Key="SystemFileAssociations\.png\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||
Type="string" />
|
||||
<RegistryValue Root="HKCU"
|
||||
Key="Software\Classes\SystemFileAssociations\.rle\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
<RegistryValue Root="HKCR"
|
||||
Key="SystemFileAssociations\.rle\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||
Type="string" />
|
||||
<RegistryValue Root="HKCR"
|
||||
Key="SystemFileAssociations\.tif\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||
Type="string" />
|
||||
<RegistryValue Root="HKCR"
|
||||
Key="SystemFileAssociations\.tiff\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||
Type="string" />
|
||||
<RegistryValue Root="HKCR"
|
||||
Key="SystemFileAssociations\.wdp\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||
Type="string" />
|
||||
<RegistryValue Root="HKCU"
|
||||
Key="Software\Classes\SystemFileAssociations\.tif\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||
Type="string" />
|
||||
<RegistryValue Root="HKCU"
|
||||
Key="Software\Classes\SystemFileAssociations\.tiff\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||
Type="string" />
|
||||
<RegistryValue Root="HKCU"
|
||||
Key="Software\Classes\SystemFileAssociations\.wdp\ShellEx\ContextMenuHandlers\ImageResizer"
|
||||
Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}"
|
||||
Type="string" />
|
||||
</Component>
|
||||
<Component Id="Module_PowerPreview" Guid="FF1700D5-1B07-4E07-9A62-4D206645EEA9" Win64="yes">
|
||||
<!-- Component to include PowerPreview Module Source dll's -->
|
||||
@ -472,7 +489,7 @@
|
||||
<Component Id="Module_PowerPreview_PerUserRegistry" Guid="CD90ADC0-7CD5-4A62-B0AF-23545C1E6DD3" Win64="yes">
|
||||
<!-- Added a separate component for Per-User registry changes -->
|
||||
<!-- Registry Key for Class Registration of Svg Preview Handler -->
|
||||
<RegistryKey Root="HKCU" Key="Software\Classes\CLSID\{ddee2b8a-6807-48a6-bb20-2338174ff779}">
|
||||
<RegistryKey Root="HKCR" Key="CLSID\{ddee2b8a-6807-48a6-bb20-2338174ff779}">
|
||||
<RegistryValue Type="string" Value="SvgPreviewHandler.SvgPreviewHandler" />
|
||||
<RegistryValue Type="string" Name="DisplayName" Value="Svg Preview Handler" />
|
||||
<RegistryValue Type="string" Name="AppID" Value="{CF142243-F059-45AF-8842-DBBE9783DB14}" />
|
||||
@ -489,7 +506,7 @@
|
||||
<RegistryValue Type="string" Key="InprocServer32\$(var.Version).0" Name="CodeBase" Value="file:///[ModulesInstallFolder]SvgPreviewHandler.dll" />
|
||||
</RegistryKey>
|
||||
<!-- Registry Key for Class Registration of Markdown Preview Handler -->
|
||||
<RegistryKey Root="HKCU" Key="Software\Classes\CLSID\{45769bcc-e8fd-42d0-947e-02beef77a1f5}">
|
||||
<RegistryKey Root="HKCR" Key="CLSID\{45769bcc-e8fd-42d0-947e-02beef77a1f5}">
|
||||
<RegistryValue Type="string" Value="MarkdownPreviewHandler.MarkdownPreviewHandler" />
|
||||
<RegistryValue Type="string" Name="DisplayName" Value="Markdown Preview Handler" />
|
||||
<RegistryValue Type="string" Name="AppID" Value="{CF142243-F059-45AF-8842-DBBE9783DB14}" />
|
||||
@ -506,31 +523,104 @@
|
||||
<RegistryValue Type="string" Key="InprocServer32\$(var.Version).0" Name="CodeBase" Value="file:///[ModulesInstallFolder]MarkdownPreviewHandler.dll" />
|
||||
</RegistryKey>
|
||||
<!-- Registry Key for AppID registration -->
|
||||
<RegistryKey Root="HKCU" Key="Software\Classes\AppID\{CF142243-F059-45AF-8842-DBBE9783DB14}">
|
||||
<RegistryKey Root="HKCR" Key="AppID\{CF142243-F059-45AF-8842-DBBE9783DB14}">
|
||||
<RegistryValue Type="expandable" Name="DllSurrogate" Value="%SystemRoot%\system32\prevhost.exe" />
|
||||
</RegistryKey>
|
||||
<!-- Add Svg preview handler to preview handlers list -->
|
||||
<RegistryKey Root="HKCU" Key="Software\Microsoft\Windows\CurrentVersion\PreviewHandlers">
|
||||
<RegistryKey Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\PreviewHandlers">
|
||||
<RegistryValue Type="string" Name="{ddee2b8a-6807-48a6-bb20-2338174ff779}" Value="Svg Preview Handler" />
|
||||
</RegistryKey>
|
||||
<!-- Add Markdown preview handler to preview handlers list -->
|
||||
<RegistryKey Root="HKCU" Key="Software\Microsoft\Windows\CurrentVersion\PreviewHandlers">
|
||||
<RegistryKey Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\PreviewHandlers">
|
||||
<RegistryValue Type="string" Name="{45769bcc-e8fd-42d0-947e-02beef77a1f5}" Value="Markdown Preview Handler" />
|
||||
</RegistryKey>
|
||||
<!-- Add file type association for Svg Preview Handler -->
|
||||
<RegistryKey Root="HKCU" Key="Software\Classes\.svg\shellex">
|
||||
<RegistryKey Root="HKCR" Key=".svg\shellex">
|
||||
<RegistryValue Type="string" Key="{8895b1c6-b41f-4c1c-a562-0d564250836f}" Value="{ddee2b8a-6807-48a6-bb20-2338174ff779}" />
|
||||
</RegistryKey>
|
||||
<!-- Add file type association for Markdown Preview Handler -->
|
||||
<RegistryKey Root="HKCU" Key="Software\Classes\.md\shellex">
|
||||
<RegistryKey Root="HKCR" Key=".md\shellex">
|
||||
<RegistryValue Type="string" Key="{8895b1c6-b41f-4c1c-a562-0d564250836f}" Value="{45769bcc-e8fd-42d0-947e-02beef77a1f5}" />
|
||||
</RegistryKey>
|
||||
<!-- Update Key to use IE11 for prevhost.exe -->
|
||||
<RegistryKey Root="HKCU" Key="Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION">
|
||||
<RegistryKey Root="HKLM" Key="Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION">
|
||||
<RegistryValue Type="integer" Name="prevhost.exe" Value="11000" />
|
||||
</RegistryKey>
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
|
||||
<!-- SettingsV2 components -->
|
||||
<DirectoryRef Id="SettingsV2InstallFolder" FileSource="$(var.BinX64Dir)\SettingsUIRunner\">
|
||||
<Component Id="SettingsV2" Guid="4B108DC0-4B2C-4AC4-AAA9-1B2DC8399F7C" Win64="yes">
|
||||
<!-- exe -->
|
||||
<File Source="$(var.BinX64Dir)\SettingsUIRunner\Microsoft.PowerToys.Settings.UI.Runner.exe"/>
|
||||
<File Source="$(var.BinX64Dir)\SettingsUIRunner\Microsoft.PowerToys.Settings.UI.exe"/>
|
||||
<!-- dll -->
|
||||
<?foreach File in concrt140_app.dll;Microsoft.Bcl.AsyncInterfaces.dll;Microsoft.PowerToys.Settings.UI.Lib.dll;Microsoft.PowerToys.Settings.UI.Runner.dll;Microsoft.Toolkit.dll;Microsoft.Toolkit.Uwp.dll;Microsoft.Toolkit.Uwp.UI.dll;Microsoft.Toolkit.Win32.UI.XamlHost.dll;Microsoft.Toolkit.Win32.UI.XamlHost.Managed.dll;Microsoft.Toolkit.Wpf.UI.Controls.dll;Microsoft.Toolkit.Wpf.UI.XamlHost.dll;Microsoft.UI.Xaml.dll;Microsoft.Xaml.Interactions.dll;Microsoft.Xaml.Interactivity.dll;msvcp140_1_app.dll;msvcp140_2_app.dll;msvcp140_app.dll;Newtonsoft.Json.dll;PowerToysInterop.dll;System.Runtime.CompilerServices.Unsafe.dll;System.Runtime.dll;System.Text.Encodings.Web.dll;System.Text.Json.dll;vcamp140_app.dll;vccorlib140_app.dll;vcomp140_app.dll;vcruntime140_1_app.dll;vcruntime140_app.dll?>
|
||||
<File Id="SettingsV2_$(var.File)" Source="$(var.BinX64Dir)\SettingsUIRunner\$(var.File)" />
|
||||
<?endforeach?>
|
||||
<!-- json -->
|
||||
<File Source="$(var.BinX64Dir)\SettingsUIRunner\Microsoft.PowerToys.Settings.UI.Runner.deps.json"/>
|
||||
<File Source="$(var.BinX64Dir)\SettingsUIRunner\Microsoft.PowerToys.Settings.UI.Runner.runtimeconfig.json"/>
|
||||
<!-- png -->
|
||||
<File Id="SettingsV2_NoiseAsset_256x256_PNG.png" Source="$(var.BinX64Dir)\SettingsUIRunner\NoiseAsset_256x256_PNG.png"/>
|
||||
<!-- pri -->
|
||||
<?foreach File in Microsoft.Toolkit.Uwp.pri;Microsoft.Toolkit.Uwp.UI.pri;Microsoft.Toolkit.Win32.UI.XamlHost.pri;Microsoft.UI.Xaml.pri;Microsoft.Xaml.Interactions.pri;Microsoft.Xaml.Interactivity.pri;resources.pri?>
|
||||
<File Id="SettingsV2_$(var.File)" Source="$(var.BinX64Dir)\SettingsUIRunner\$(var.File)" />
|
||||
<?endforeach?>
|
||||
<!-- winmd -->
|
||||
<File Id="SettingsV2_Microsoft.Toolkit.Win32.UI.XamlHost.winmd" Source="$(var.BinX64Dir)\SettingsUIRunner\Microsoft.Toolkit.Win32.UI.XamlHost.winmd"/>
|
||||
<File Id="SettingsV2_Microsoft.UI.Xaml.winmd" Source="$(var.BinX64Dir)\SettingsUIRunner\Microsoft.UI.Xaml.winmd"/>
|
||||
<!-- xbf -->
|
||||
<File Id="SettingsV2_App.xbf" Source="$(var.BinX64Dir)\SettingsUIRunner\App.xbf"/>
|
||||
<!-- xml -->
|
||||
<File Id="SettingsV2_Microsoft.PowerToys.Settings.UI.xr.xml" Source="$(var.BinX64Dir)\SettingsUIRunner\Microsoft.PowerToys.Settings.UI.xr.xml"/>
|
||||
<File Id="SettingsV2_Microsoft.Toolkit.Win32.UI.XamlHost.xml" Source="$(var.BinX64Dir)\SettingsUIRunner\Microsoft.Toolkit.Win32.UI.XamlHost.xml"/>
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
<DirectoryRef Id="SettingsV2AssetsInstallFolder" FileSource="$(var.BinX64Dir)\SettingsUIRunner\Assets">
|
||||
<Component Id="SettingsV2Assets" Guid="705B863B-D813-49B9-BAA1-210DA913F765" Win64="yes">
|
||||
<?foreach File in Logo.scale-200.png;SplashScreen.png;Square150x150Logo.scale-200.png;Square44x44Logo.scale-200.png;Square44x44Logo.targetsize-24_altform-unplated.png;StoreLogo.scale-100.png;Wide310x150Logo.scale-200.png?>
|
||||
<File Source="$(var.BinX64Dir)\SettingsUIRunner\Assets\$(var.File)" />
|
||||
<?endforeach?>
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
<DirectoryRef Id="SettingsV2ControlsInstallFolder" FileSource="$(var.BinX64Dir)\SettingsUIRunner\Controls">
|
||||
<Component Id="SettingsV2Controls" Guid="05C55C88-B59A-4450-A07C-EB7626E0781A" Win64="yes">
|
||||
<?foreach File in HotkeySettingsControl.xbf?>
|
||||
<File Id="SettingsV2_Controls_$(var.File)" Source="$(var.BinX64Dir)\SettingsUIRunner\Controls\$(var.File)" />
|
||||
<?endforeach?>
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
<DirectoryRef Id="SettingsV2PropertiesInstallFolder" FileSource="$(var.BinX64Dir)\SettingsUIRunner\Properties">
|
||||
<Component Id="SettingsV2Properties" Guid="8F910A41-B27B-4289-8FAC-9AB34F070CF6" Win64="yes">
|
||||
<?foreach File in Default.rd.xml?>
|
||||
<File Id="SettingsV2_Properties_$(var.File)" Source="$(var.BinX64Dir)\SettingsUIRunner\Properties\$(var.File)" />
|
||||
<?endforeach?>
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
<DirectoryRef Id="SettingsV2StylesInstallFolder" FileSource="$(var.BinX64Dir)\SettingsUIRunner\Styles">
|
||||
<Component Id="SettingsV2Styles" Guid="44B5C0E0-76DA-4604-BB86-FCD27A00EB71" Win64="yes">
|
||||
<?foreach File in Page.xbf;TextBlock.xbf;_Colors.xbf;_FontSizes.xbf;_Sizes.xbf;_Thickness.xbf?>
|
||||
<File Id="SettingsV2_Styles_$(var.File)" Source="$(var.BinX64Dir)\SettingsUIRunner\Styles\$(var.File)" />
|
||||
<?endforeach?>
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
<DirectoryRef Id="SettingsV2ViewsInstallFolder" FileSource="$(var.BinX64Dir)\SettingsUIRunner\Views">
|
||||
<Component Id="SettingsV2Views" Guid="C140BFBA-6370-4F67-862C-5B42660385CD" Win64="yes">
|
||||
<?foreach File in FancyZonesPage.xbf;GeneralPage.xbf;ImageResizerPage.xbf;KeyboardManagerPage.xbf;PowerLauncherPage.xbf;PowerPreviewPage.xbf;PowerRenamePage.xbf;ShellPage.xbf;ShortcutGuidePage.xbf?>
|
||||
<File Id="SettingsV2_Views_$(var.File)" Source="$(var.BinX64Dir)\SettingsUIRunner\Views\$(var.File)" />
|
||||
<?endforeach?>
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
<DirectoryRef Id="SettingsV2XamlAssetsInstallFolder" FileSource="$(var.BinX64Dir)\SettingsUIRunner\Microsoft.UI.Xaml\Assets">
|
||||
<Component Id="SettingsV2XamlAssets" Guid="98A136DB-C1BD-42B1-9AB4-0E16F0ECE86A" Win64="yes">
|
||||
<?foreach File in NoiseAsset_256X256_PNG.png?>
|
||||
<File Id="SettingsV2_XamlAssets_$(var.File)" Source="$(var.BinX64Dir)\SettingsUIRunner\Microsoft.UI.Xaml\Assets\$(var.File)" />
|
||||
<?endforeach?>
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
|
||||
<DirectoryRef Id="SettingsHtmlInstallFolder" FileSource="$(var.RepoDir)\settings\settings-html\">
|
||||
<Component Id="settings_html" Guid="87881A99-E917-4B0D-B1D8-5C6EB9709F96" Win64="yes">
|
||||
<File Source="$(var.RepoDir)\src\settings\settings-html\index.html" KeyPath="yes" />
|
||||
@ -572,6 +662,7 @@
|
||||
<ComponentRef Id="action_runner_exe" />
|
||||
<ComponentRef Id="powertoys_toast_clsid" />
|
||||
<ComponentRef Id="License_rtf" />
|
||||
<ComponentRef Id="powertoysinterop_dll" />
|
||||
<ComponentRef Id="PowerToysSvgs" />
|
||||
<ComponentRef Id="Module_ShortcutGuide" />
|
||||
<ComponentRef Id="Module_FancyZones" />
|
||||
@ -583,6 +674,14 @@
|
||||
<ComponentRef Id="Module_PowerPreview_PerUserRegistry" />
|
||||
<ComponentRef Id="Module_WindowWalker" />
|
||||
<ComponentRef Id="Module_Launcher" />
|
||||
<ComponentRef Id="Module_KeyboardManager" />
|
||||
<ComponentRef Id="SettingsV2" />
|
||||
<ComponentRef Id="SettingsV2Assets" />
|
||||
<ComponentRef Id="SettingsV2Controls" />
|
||||
<ComponentRef Id="SettingsV2Properties" />
|
||||
<ComponentRef Id="SettingsV2Styles" />
|
||||
<ComponentRef Id="SettingsV2Views" />
|
||||
<ComponentRef Id="SettingsV2XamlAssets" />
|
||||
<ComponentRef Id="settings_exe" />
|
||||
<ComponentRef Id="settings_html" />
|
||||
<ComponentRef Id="settings_dark_html" />
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Version>0.16.2</Version>
|
||||
<Version>0.17.0</Version>
|
||||
<DefineConstants>Version=$(Version);</DefineConstants>
|
||||
</PropertyGroup>
|
||||
</Project>
|
@ -27,3 +27,14 @@ VersionHelper::VersionHelper(int major, int minor, int revision) :
|
||||
revision(revision)
|
||||
{
|
||||
}
|
||||
|
||||
std::wstring VersionHelper::toWstring() const
|
||||
{
|
||||
std::wstring result{ L"v" };
|
||||
result += std::to_wstring(major);
|
||||
result += L'.';
|
||||
result += std::to_wstring(minor);
|
||||
result += L'.';
|
||||
result += std::to_wstring(revision);
|
||||
return result;
|
||||
}
|
||||
|
@ -13,4 +13,6 @@ struct VersionHelper
|
||||
int major;
|
||||
int minor;
|
||||
int revision;
|
||||
|
||||
std::wstring toWstring() const;
|
||||
};
|
||||
|
@ -215,19 +215,6 @@ std::vector<DWORD> LayoutMap::LayoutMapImpl::GetKeyCodeList(const bool isShortcu
|
||||
std::vector<DWORD> keyCodes;
|
||||
if (!isKeyCodeListGenerated)
|
||||
{
|
||||
// Add modifier keys
|
||||
keyCodes.push_back(CommonSharedConstants::VK_WIN_BOTH);
|
||||
keyCodes.push_back(VK_LWIN);
|
||||
keyCodes.push_back(VK_RWIN);
|
||||
keyCodes.push_back(VK_CONTROL);
|
||||
keyCodes.push_back(VK_LCONTROL);
|
||||
keyCodes.push_back(VK_RCONTROL);
|
||||
keyCodes.push_back(VK_MENU);
|
||||
keyCodes.push_back(VK_LMENU);
|
||||
keyCodes.push_back(VK_RMENU);
|
||||
keyCodes.push_back(VK_SHIFT);
|
||||
keyCodes.push_back(VK_LSHIFT);
|
||||
keyCodes.push_back(VK_RSHIFT);
|
||||
// Add character keys
|
||||
for (auto& it : unicodeKeys)
|
||||
{
|
||||
@ -237,7 +224,23 @@ std::vector<DWORD> LayoutMap::LayoutMapImpl::GetKeyCodeList(const bool isShortcu
|
||||
keyCodes.push_back(it.first);
|
||||
}
|
||||
}
|
||||
|
||||
// Add modifier keys in alphabetical order
|
||||
keyCodes.push_back(VK_MENU);
|
||||
keyCodes.push_back(VK_LMENU);
|
||||
keyCodes.push_back(VK_RMENU);
|
||||
keyCodes.push_back(VK_CONTROL);
|
||||
keyCodes.push_back(VK_LCONTROL);
|
||||
keyCodes.push_back(VK_RCONTROL);
|
||||
keyCodes.push_back(VK_SHIFT);
|
||||
keyCodes.push_back(VK_LSHIFT);
|
||||
keyCodes.push_back(VK_RSHIFT);
|
||||
keyCodes.push_back(CommonSharedConstants::VK_WIN_BOTH);
|
||||
keyCodes.push_back(VK_LWIN);
|
||||
keyCodes.push_back(VK_RWIN);
|
||||
|
||||
// Add all other special keys
|
||||
std::vector<DWORD> specialKeys;
|
||||
for (int i = 1; i < 256; i++)
|
||||
{
|
||||
// If it is not already been added (i.e. it was either a modifier or had a unicode representation)
|
||||
@ -247,14 +250,24 @@ std::vector<DWORD> LayoutMap::LayoutMapImpl::GetKeyCodeList(const bool isShortcu
|
||||
auto it = unknownKeys.find(i);
|
||||
if (it == unknownKeys.end())
|
||||
{
|
||||
keyCodes.push_back(i);
|
||||
specialKeys.push_back(i);
|
||||
}
|
||||
else if (unknownKeys[i] != keyboardLayoutMap[i])
|
||||
{
|
||||
keyCodes.push_back(i);
|
||||
specialKeys.push_back(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort the special keys in alphabetical order
|
||||
std::sort(specialKeys.begin(), specialKeys.end(), [&](const DWORD& lhs, const DWORD& rhs) {
|
||||
return keyboardLayoutMap[lhs] < keyboardLayoutMap[rhs];
|
||||
});
|
||||
for (int i = 0; i < specialKeys.size(); i++)
|
||||
{
|
||||
keyCodes.push_back(specialKeys[i]);
|
||||
}
|
||||
|
||||
// Add unknown keys
|
||||
for (auto& it : unknownKeys)
|
||||
{
|
||||
@ -285,20 +298,21 @@ std::vector<std::wstring> LayoutMap::LayoutMapImpl::GetKeyNameList(const bool is
|
||||
{
|
||||
std::vector<std::wstring> keyNames;
|
||||
std::vector<DWORD> keyCodes = GetKeyCodeList(isShortcut);
|
||||
std::lock_guard<std::mutex> lock(keyboardLayoutMap_mutex);
|
||||
// If it is a key list for the shortcut control then we add a "None" key at the start
|
||||
if (isShortcut)
|
||||
{
|
||||
keyNames.push_back(L"None");
|
||||
for (int i = 1; i < keyCodes.size(); i++)
|
||||
{
|
||||
keyNames.push_back(GetKeyName(keyCodes[i]));
|
||||
keyNames.push_back(keyboardLayoutMap[keyCodes[i]]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < keyCodes.size(); i++)
|
||||
{
|
||||
keyNames.push_back(GetKeyName(keyCodes[i]));
|
||||
keyNames.push_back(keyboardLayoutMap[keyCodes[i]]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,11 @@ namespace
|
||||
constexpr std::wstring_view WIN32_AUMID = L"Microsoft.PowerToysWin32";
|
||||
}
|
||||
|
||||
namespace localized_strings
|
||||
{
|
||||
constexpr std::wstring_view SNOOZE_BUTTON = L"Snooze";
|
||||
}
|
||||
|
||||
static DWORD loop_thread_id()
|
||||
{
|
||||
static const DWORD thread_id = GetCurrentThreadId();
|
||||
@ -213,7 +218,14 @@ void notifications::show_toast_with_activations(std::wstring message, std::wstri
|
||||
toast_xml += selection_id;
|
||||
toast_xml += LR"(" type="selection" defaultInput=")";
|
||||
toast_xml += std::to_wstring(b.durations[0].minutes);
|
||||
toast_xml += LR"(">)";
|
||||
toast_xml += L'"';
|
||||
if (!b.snooze_title.empty())
|
||||
{
|
||||
toast_xml += LR"( title=")";
|
||||
toast_xml += b.snooze_title;
|
||||
toast_xml += L'"';
|
||||
}
|
||||
toast_xml += L'>';
|
||||
for (const auto& duration : b.durations)
|
||||
{
|
||||
toast_xml += LR"(<selection id=")";
|
||||
@ -269,7 +281,9 @@ void notifications::show_toast_with_activations(std::wstring message, std::wstri
|
||||
toast_xml += selection_id;
|
||||
toast_xml += '"';
|
||||
}
|
||||
toast_xml += LR"( content="" />)";
|
||||
toast_xml += LR"( content=")";
|
||||
toast_xml += localized_strings::SNOOZE_BUTTON;
|
||||
toast_xml += LR"(" />)";
|
||||
} },
|
||||
actions[i]);
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ namespace notifications
|
||||
|
||||
struct snooze_button
|
||||
{
|
||||
std::wstring snooze_title;
|
||||
std::vector<snooze_duration> durations;
|
||||
};
|
||||
|
||||
|
@ -28,6 +28,10 @@ namespace
|
||||
const wchar_t LATEST_RELEASE_ENDPOINT[] = L"https://api.github.com/repos/microsoft/PowerToys/releases/latest";
|
||||
const wchar_t MSIX_PACKAGE_NAME[] = L"Microsoft.PowerToys";
|
||||
const wchar_t MSIX_PACKAGE_PUBLISHER[] = L"CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US";
|
||||
|
||||
const wchar_t UPDATE_NOTIFY_TOAST_TAG[] = L"PTUpdateNotifyTag";
|
||||
const wchar_t UPDATE_READY_TOAST_TAG[] = L"PTUpdateReadyTag";
|
||||
const size_t MAX_DOWNLOAD_ATTEMPTS = 3;
|
||||
}
|
||||
|
||||
namespace localized_strings
|
||||
@ -37,12 +41,14 @@ namespace localized_strings
|
||||
const wchar_t UNINSTALLATION_SUCCESS[] = L"Previous version of PowerToys was uninstalled successfully.";
|
||||
const wchar_t UNINSTALLATION_UNKNOWN_ERROR[] = L"Error: please uninstall the previous version of PowerToys manually.";
|
||||
|
||||
const wchar_t GITHUB_NEW_VERSION_READY_TO_INSTALL[] = L"An update to PowerToys is ready to install.";
|
||||
const wchar_t GITHUB_NEW_VERSION_READY_TO_INSTALL[] = L"An update to PowerToys is ready to install.\n";
|
||||
const wchar_t GITHUB_NEW_VERSION_DOWNLOAD_INSTALL_ERROR[] = L"Error: couldn't download PowerToys installer. Visit our GitHub page to update.\n";
|
||||
const wchar_t GITHUB_NEW_VERSION_UPDATE_NOW[] = L"Update now";
|
||||
const wchar_t GITHUB_NEW_VERSION_UPDATE_AFTER_RESTART[] = L"At next launch";
|
||||
|
||||
const wchar_t GITHUB_NEW_VERSION_AVAILABLE_OFFER_VISIT[] = L"An update to PowerToys is available. Visit our GitHub page to get ";
|
||||
const wchar_t GITHUB_NEW_VERSION_AVAILABLE_OFFER_VISIT[] = L"An update to PowerToys is available. Visit our GitHub page to update.\n";
|
||||
const wchar_t GITHUB_NEW_VERSION_AGREE[] = L"Visit";
|
||||
const wchar_t GITHUB_NEW_VERSION_SNOOZE_TITLE[] = L"Click Snooze to be reminded in:";
|
||||
const wchar_t GITHUB_NEW_VERSION_UPDATE_SNOOZE_1D[] = L"1 day";
|
||||
const wchar_t GITHUB_NEW_VERSION_UPDATE_SNOOZE_5D[] = L"5 days";
|
||||
}
|
||||
@ -204,6 +210,17 @@ namespace updating
|
||||
return { std::move(path_str) };
|
||||
}
|
||||
|
||||
std::future<void> attempt_to_download_installer(const std::filesystem::path& destination, const winrt::Windows::Foundation::Uri& url)
|
||||
{
|
||||
namespace storage = winrt::Windows::Storage;
|
||||
|
||||
auto client = create_http_client();
|
||||
auto response = co_await client.GetAsync(url);
|
||||
(void)response.EnsureSuccessStatusCode();
|
||||
auto msi_installer_file_stream = co_await storage::Streams::FileRandomAccessStream::OpenAsync(destination.c_str(), storage::FileAccessMode::ReadWrite, storage::StorageOpenOptions::AllowReadersAndWriters, storage::Streams::FileOpenDisposition::CreateAlways);
|
||||
co_await response.Content().WriteToStreamAsync(msi_installer_file_stream);
|
||||
}
|
||||
|
||||
std::future<void> try_autoupdate(const bool download_updates_automatically)
|
||||
{
|
||||
const auto new_version = co_await get_new_github_version_info_async();
|
||||
@ -212,32 +229,58 @@ namespace updating
|
||||
co_return;
|
||||
}
|
||||
using namespace localized_strings;
|
||||
namespace storage = winrt::Windows::Storage;
|
||||
auto current_version_to_next_version = VersionHelper{ VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION }.toWstring();
|
||||
current_version_to_next_version += L" -> ";
|
||||
current_version_to_next_version += new_version->version_string;
|
||||
|
||||
if (download_updates_automatically && !could_be_costly_connection())
|
||||
{
|
||||
auto client = create_http_client();
|
||||
auto response = co_await client.GetAsync(new_version->msi_download_url);
|
||||
(void)response.EnsureSuccessStatusCode();
|
||||
|
||||
auto download_dst = get_pending_updates_path();
|
||||
auto installer_download_dst = get_pending_updates_path();
|
||||
std::error_code _;
|
||||
std::filesystem::create_directories(download_dst, _);
|
||||
download_dst /= new_version->msi_filename;
|
||||
auto msi_installer_file_stream = co_await storage::Streams::FileRandomAccessStream::OpenAsync(download_dst.c_str(), storage::FileAccessMode::ReadWrite, storage::StorageOpenOptions::AllowReadersAndWriters, storage::Streams::FileOpenDisposition::CreateAlways);
|
||||
co_await response.Content().WriteToStreamAsync(msi_installer_file_stream);
|
||||
notifications::toast_params toast_params{ L"PTUpdateReadyTag", false };
|
||||
std::filesystem::create_directories(installer_download_dst, _);
|
||||
installer_download_dst /= new_version->msi_filename;
|
||||
|
||||
bool download_success = false;
|
||||
for (size_t i = 0; i < MAX_DOWNLOAD_ATTEMPTS; ++i)
|
||||
{
|
||||
try
|
||||
{
|
||||
co_await attempt_to_download_installer(installer_download_dst, new_version->msi_download_url);
|
||||
download_success = true;
|
||||
break;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// reattempt to download or do nothing
|
||||
}
|
||||
}
|
||||
if (!download_success)
|
||||
{
|
||||
notifications::toast_params toast_params{ UPDATE_NOTIFY_TOAST_TAG, false };
|
||||
std::wstring contents = GITHUB_NEW_VERSION_DOWNLOAD_INSTALL_ERROR;
|
||||
contents += current_version_to_next_version;
|
||||
|
||||
notifications::show_toast_with_activations(std::move(contents), {}, { notifications::link_button{ GITHUB_NEW_VERSION_AGREE, new_version->release_page_uri.ToString().c_str() } }, std::move(toast_params));
|
||||
|
||||
co_return;
|
||||
}
|
||||
|
||||
notifications::toast_params toast_params{ UPDATE_READY_TOAST_TAG, false };
|
||||
std::wstring new_version_ready{ GITHUB_NEW_VERSION_READY_TO_INSTALL };
|
||||
new_version_ready += L" ";
|
||||
new_version_ready += new_version->version_string;
|
||||
notifications::show_toast_with_activations(std::move(new_version_ready), {}, { notifications::link_button{ GITHUB_NEW_VERSION_UPDATE_NOW, L"powertoys://update_now/" }, notifications::link_button{ GITHUB_NEW_VERSION_UPDATE_AFTER_RESTART, L"powertoys://schedule_update/" }, notifications::snooze_button{ { { GITHUB_NEW_VERSION_UPDATE_SNOOZE_1D, 24 * 60 }, { GITHUB_NEW_VERSION_UPDATE_SNOOZE_5D, 120 * 60 } } } }, std::move(toast_params));
|
||||
new_version_ready += current_version_to_next_version;
|
||||
|
||||
notifications::show_toast_with_activations(std::move(new_version_ready),
|
||||
{},
|
||||
{ notifications::link_button{ GITHUB_NEW_VERSION_UPDATE_NOW, L"powertoys://update_now/" },
|
||||
notifications::link_button{ GITHUB_NEW_VERSION_UPDATE_AFTER_RESTART, L"powertoys://schedule_update/" },
|
||||
notifications::snooze_button{ GITHUB_NEW_VERSION_SNOOZE_TITLE, { { GITHUB_NEW_VERSION_UPDATE_SNOOZE_1D, 24 * 60 }, { GITHUB_NEW_VERSION_UPDATE_SNOOZE_5D, 120 * 60 } } } },
|
||||
std::move(toast_params));
|
||||
}
|
||||
else
|
||||
{
|
||||
notifications::toast_params toast_params{ L"PTUpdateNotifyTag", false };
|
||||
notifications::toast_params toast_params{ UPDATE_NOTIFY_TOAST_TAG, false };
|
||||
std::wstring contents = GITHUB_NEW_VERSION_AVAILABLE_OFFER_VISIT;
|
||||
contents += new_version->version_string;
|
||||
contents += L'.';
|
||||
contents += current_version_to_next_version;
|
||||
notifications::show_toast_with_activations(std::move(contents), {}, { notifications::link_button{ GITHUB_NEW_VERSION_AGREE, new_version->release_page_uri.ToString().c_str() } }, std::move(toast_params));
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
this.Value = false;
|
||||
}
|
||||
|
||||
public BoolProperty(bool value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
[JsonPropertyName("value")]
|
||||
public bool Value { get; set; }
|
||||
|
||||
|
@ -16,6 +16,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
this.Value = 0.0;
|
||||
}
|
||||
|
||||
public DoubleProperty(double value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
// Gets or sets the double value of the settings configuration.
|
||||
[JsonPropertyName("value")]
|
||||
public double Value { get; set; }
|
||||
|
@ -22,7 +22,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
[JsonPropertyName("FancyZones")]
|
||||
public bool FancyZones { get; set; }
|
||||
|
||||
[JsonPropertyName("ImageResizer")]
|
||||
[JsonPropertyName("Image Resizer")]
|
||||
public bool ImageResizer { get; set; }
|
||||
|
||||
[JsonPropertyName("File Explorer Preview")]
|
||||
|
@ -0,0 +1,112 @@
|
||||
// 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;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
{
|
||||
public class ImageResizerProperties
|
||||
{
|
||||
public ImageResizerProperties()
|
||||
{
|
||||
ImageresizerSelectedSizeIndex = new IntProperty(0);
|
||||
ImageresizerShrinkOnly = new BoolProperty(false);
|
||||
ImageresizerReplace = new BoolProperty(false);
|
||||
ImageresizerIgnoreOrientation = new BoolProperty(true);
|
||||
ImageresizerJpegQualityLevel = new IntProperty(90);
|
||||
ImageresizerPngInterlaceOption = new IntProperty();
|
||||
ImageresizerTiffCompressOption = new IntProperty();
|
||||
ImageresizerFileName = new StringProperty("%1 (%2)");
|
||||
|
||||
ImageresizerSizes = new ImageresizerSizes(new ObservableCollection<ImageSize>()
|
||||
{
|
||||
new ImageSize(0, "Small", ResizeFit.Fit, 854, 480, ResizeUnit.Pixel),
|
||||
new ImageSize(1, "Medium", ResizeFit.Fit, 1366, 768, ResizeUnit.Pixel),
|
||||
new ImageSize(2, "Large", ResizeFit.Fit, 1920, 1080, ResizeUnit.Pixel),
|
||||
new ImageSize(3, "Phone", ResizeFit.Fit, 320, 568, ResizeUnit.Pixel),
|
||||
});
|
||||
|
||||
ImageresizerKeepDateModified = new BoolProperty();
|
||||
ImageresizerFallbackEncoder = new StringProperty(new System.Guid("19e4a5aa-5662-4fc5-a0c0-1758028e1057").ToString());
|
||||
ImageresizerCustomSize = new ImageresizerCustomSizeProperty(new ImageSize(4, "custom", ResizeFit.Fit, 1024, 640, ResizeUnit.Pixel));
|
||||
}
|
||||
|
||||
[JsonPropertyName("imageresizer_selectedSizeIndex")]
|
||||
public IntProperty ImageresizerSelectedSizeIndex { get; set; }
|
||||
|
||||
[JsonPropertyName("imageresizer_shrinkOnly")]
|
||||
public BoolProperty ImageresizerShrinkOnly { get; set; }
|
||||
|
||||
[JsonPropertyName("imageresizer_replace")]
|
||||
public BoolProperty ImageresizerReplace { get; set; }
|
||||
|
||||
[JsonPropertyName("imageresizer_ignoreOrientation")]
|
||||
public BoolProperty ImageresizerIgnoreOrientation { get; set; }
|
||||
|
||||
[JsonPropertyName("imageresizer_jpegQualityLevel")]
|
||||
public IntProperty ImageresizerJpegQualityLevel { get; set; }
|
||||
|
||||
[JsonPropertyName("imageresizer_pngInterlaceOption")]
|
||||
public IntProperty ImageresizerPngInterlaceOption { get; set; }
|
||||
|
||||
[JsonPropertyName("imageresizer_tiffCompressOption")]
|
||||
public IntProperty ImageresizerTiffCompressOption { get; set; }
|
||||
|
||||
[JsonPropertyName("imageresizer_fileName")]
|
||||
public StringProperty ImageresizerFileName { get; set; }
|
||||
|
||||
[JsonPropertyName("imageresizer_sizes")]
|
||||
public ImageresizerSizes ImageresizerSizes { get; set; }
|
||||
|
||||
[JsonPropertyName("imageresizer_keepDateModified")]
|
||||
public BoolProperty ImageresizerKeepDateModified { get; set; }
|
||||
|
||||
[JsonPropertyName("imageresizer_fallbackEncoder")]
|
||||
public StringProperty ImageresizerFallbackEncoder { get; set; }
|
||||
|
||||
[JsonPropertyName("imageresizer_customSize")]
|
||||
public ImageresizerCustomSizeProperty ImageresizerCustomSize { get; set; }
|
||||
|
||||
public string ToJsonString()
|
||||
{
|
||||
return JsonSerializer.Serialize(this);
|
||||
}
|
||||
}
|
||||
|
||||
public enum ResizeFit
|
||||
{
|
||||
Fill = 0,
|
||||
Fit = 1,
|
||||
Stretch = 2,
|
||||
}
|
||||
|
||||
public enum ResizeUnit
|
||||
{
|
||||
Centimeter = 0,
|
||||
Inch = 1,
|
||||
Percent = 2,
|
||||
Pixel = 3,
|
||||
}
|
||||
|
||||
public enum PngInterlaceOption
|
||||
{
|
||||
Default = 0,
|
||||
On = 1,
|
||||
Off = 2,
|
||||
}
|
||||
|
||||
public enum TiffCompressOption
|
||||
{
|
||||
Default = 0,
|
||||
None = 1,
|
||||
Ccitt3 = 2,
|
||||
Ccitt4 = 3,
|
||||
Lzw = 4,
|
||||
Rle = 5,
|
||||
Zip = 6,
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
// 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.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
{
|
||||
public class ImageResizerSettings
|
||||
{
|
||||
[JsonPropertyName("version")]
|
||||
public string Version { get; set; }
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[JsonPropertyName("properties")]
|
||||
public ImageResizerProperties Properties { get; set; }
|
||||
|
||||
public ImageResizerSettings()
|
||||
{
|
||||
this.Version = "1";
|
||||
this.Name = "Image Resizer";
|
||||
this.Properties = new ImageResizerProperties();
|
||||
}
|
||||
|
||||
public string ToJsonString()
|
||||
{
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
WriteIndented = true,
|
||||
};
|
||||
return JsonSerializer.Serialize(this, options);
|
||||
}
|
||||
}
|
||||
}
|
187
src/core/Microsoft.PowerToys.Settings.UI.Lib/ImageSize.cs
Normal file
187
src/core/Microsoft.PowerToys.Settings.UI.Lib/ImageSize.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.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
{
|
||||
public class ImageSize : INotifyPropertyChanged
|
||||
{
|
||||
public ImageSize(int id)
|
||||
{
|
||||
Id = id;
|
||||
Name = string.Empty;
|
||||
Fit = (int)ResizeFit.Fit;
|
||||
Width = 0;
|
||||
Height = 0;
|
||||
Unit = (int)ResizeUnit.Pixel;
|
||||
}
|
||||
|
||||
public ImageSize()
|
||||
{
|
||||
Id = 0;
|
||||
Name = string.Empty;
|
||||
Fit = (int)ResizeFit.Fit;
|
||||
Width = 0;
|
||||
Height = 0;
|
||||
Unit = (int)ResizeUnit.Pixel;
|
||||
}
|
||||
|
||||
public ImageSize(int id, string name, ResizeFit fit, double width, double height, ResizeUnit unit)
|
||||
{
|
||||
Id = id;
|
||||
Name = name;
|
||||
Fit = (int)fit;
|
||||
Width = width;
|
||||
Height = height;
|
||||
Unit = (int)unit;
|
||||
}
|
||||
|
||||
private int _id;
|
||||
private string _name;
|
||||
private int _fit;
|
||||
private double _height;
|
||||
private double _width;
|
||||
private int _unit;
|
||||
|
||||
public int Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (_id != value)
|
||||
{
|
||||
_id = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (_name != value)
|
||||
{
|
||||
_name = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[JsonPropertyName("fit")]
|
||||
public int Fit
|
||||
{
|
||||
get
|
||||
{
|
||||
return _fit;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (_fit != value)
|
||||
{
|
||||
_fit = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[JsonPropertyName("width")]
|
||||
public double Width
|
||||
{
|
||||
get
|
||||
{
|
||||
return _width;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (_width != value)
|
||||
{
|
||||
_width = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[JsonPropertyName("height")]
|
||||
public double Height
|
||||
{
|
||||
get
|
||||
{
|
||||
return _height;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (_height != value)
|
||||
{
|
||||
_height = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[JsonPropertyName("unit")]
|
||||
public int Unit
|
||||
{
|
||||
get
|
||||
{
|
||||
return _unit;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (_unit != value)
|
||||
{
|
||||
_unit = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
var handler = PropertyChanged;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(ImageSize modifiedSize)
|
||||
{
|
||||
Id = modifiedSize.Id;
|
||||
Name = modifiedSize.Name;
|
||||
Fit = modifiedSize.Fit;
|
||||
Width = modifiedSize.Width;
|
||||
Height = modifiedSize.Height;
|
||||
Unit = modifiedSize.Unit;
|
||||
}
|
||||
|
||||
public string ToJsonString()
|
||||
{
|
||||
return JsonSerializer.Serialize(this);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
{
|
||||
|
||||
public class ImageresizerCustomSizeProperty
|
||||
{
|
||||
[JsonPropertyName("value")]
|
||||
public ImageSize Value { get; set; }
|
||||
|
||||
public ImageresizerCustomSizeProperty()
|
||||
{
|
||||
this.Value = new ImageSize();
|
||||
}
|
||||
|
||||
public ImageresizerCustomSizeProperty(ImageSize value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
{
|
||||
|
||||
public class ImageresizerFallbackEncoder
|
||||
{
|
||||
[JsonPropertyName("value")]
|
||||
public string Value { get; set; }
|
||||
|
||||
public ImageresizerFallbackEncoder()
|
||||
{
|
||||
this.Value = string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
{
|
||||
|
||||
public class ImageresizerKeepDateModified
|
||||
{
|
||||
[JsonPropertyName("value")]
|
||||
public bool Value { get; set; }
|
||||
|
||||
public ImageresizerKeepDateModified()
|
||||
{
|
||||
this.Value = false;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
// 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.Collections.ObjectModel;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
{
|
||||
|
||||
public class ImageresizerSizes
|
||||
{
|
||||
[JsonPropertyName("value")]
|
||||
public ObservableCollection<ImageSize> Value { get; set; }
|
||||
|
||||
public ImageresizerSizes()
|
||||
{
|
||||
this.Value = new ObservableCollection<ImageSize>();
|
||||
}
|
||||
|
||||
public ImageresizerSizes(ObservableCollection<ImageSize> value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public string ToJsonString()
|
||||
{
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
WriteIndented = true,
|
||||
};
|
||||
return JsonSerializer.Serialize(this, options);
|
||||
}
|
||||
}
|
||||
}
|
@ -15,6 +15,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
this.Value = 0;
|
||||
}
|
||||
|
||||
public IntProperty(int value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
// Gets or sets the integer value of the settings configuration.
|
||||
[JsonPropertyName("value")]
|
||||
public int Value { get; set; }
|
||||
|
@ -28,7 +28,7 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Text.Json" Version="4.7.1" />
|
||||
<PackageReference Include="System.Text.Json" Version="4.7.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -3,21 +3,22 @@
|
||||
// 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.Lib
|
||||
{
|
||||
public class OutGoingGeneralSettings
|
||||
{
|
||||
public GeneralSettings general { get; set; }
|
||||
[JsonPropertyName("general")]
|
||||
public GeneralSettings GeneralSettings { get; set; }
|
||||
|
||||
public OutGoingGeneralSettings()
|
||||
{
|
||||
general = null;
|
||||
}
|
||||
|
||||
public OutGoingGeneralSettings(GeneralSettings generalSettings)
|
||||
{
|
||||
general = generalSettings;
|
||||
GeneralSettings = generalSettings;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
@ -25,4 +26,4 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
return JsonSerializer.Serialize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,10 +2,14 @@
|
||||
// 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;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
{
|
||||
public class PowerLauncherSettings : BasePTModuleSettings
|
||||
{
|
||||
public const string POWERTOYNAME = "PowerLauncher";
|
||||
|
||||
public PowerLauncherProperties properties { get; set; }
|
||||
|
||||
public PowerLauncherSettings()
|
||||
@ -14,5 +18,16 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
version = "1";
|
||||
name = "_unset_";
|
||||
}
|
||||
|
||||
public virtual void Save()
|
||||
{
|
||||
// Save settings to file
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
WriteIndented = true,
|
||||
};
|
||||
|
||||
SettingsUtils.SaveSettings(JsonSerializer.Serialize(this, options), POWERTOYNAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
{
|
||||
properties = new PowerPreviewProperties();
|
||||
version = "1";
|
||||
name = "_unset_";
|
||||
name = "File Explorer";
|
||||
}
|
||||
|
||||
public PowerPreviewSettings(string ptName)
|
||||
|
@ -81,4 +81,4 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
// 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.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
{
|
||||
public class ShortcutGuideSettingsIPCMessage
|
||||
{
|
||||
[JsonPropertyName("powertoys")]
|
||||
public SndShortcutGuideSettings Powertoys { get; set; }
|
||||
|
||||
public ShortcutGuideSettingsIPCMessage()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ShortcutGuideSettingsIPCMessage(SndShortcutGuideSettings settings)
|
||||
{
|
||||
this.Powertoys = settings;
|
||||
}
|
||||
|
||||
public string ToJsonString()
|
||||
{
|
||||
return JsonSerializer.Serialize(this);
|
||||
}
|
||||
}
|
||||
}
|
@ -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 System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
{
|
||||
|
||||
public class SndImageResizerSettings
|
||||
{
|
||||
[JsonPropertyName("Image Resizer")]
|
||||
public ImageResizerSettings ImageResizer { get; set; }
|
||||
|
||||
public SndImageResizerSettings(ImageResizerSettings settings)
|
||||
{
|
||||
this.ImageResizer = settings;
|
||||
}
|
||||
|
||||
public string ToJsonString()
|
||||
{
|
||||
return JsonSerializer.Serialize(this);
|
||||
}
|
||||
}
|
||||
}
|
@ -13,6 +13,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
{
|
||||
public T powertoys { get; set; }
|
||||
|
||||
public SndModuleSettings()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public SndModuleSettings(T settings)
|
||||
{
|
||||
this.powertoys = settings;
|
||||
@ -23,4 +28,4 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
return JsonSerializer.Serialize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -12,6 +12,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
[JsonPropertyName("Shortcut Guide")]
|
||||
public ShortcutGuideSettings ShortcutGuide { get; set; }
|
||||
|
||||
public SndShortcutGuideSettings()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public SndShortcutGuideSettings(ShortcutGuideSettings settings)
|
||||
{
|
||||
this.ShortcutGuide = settings;
|
||||
@ -22,4 +27,4 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
return JsonSerializer.Serialize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -18,6 +18,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
this.Value = string.Empty;
|
||||
}
|
||||
|
||||
public StringProperty(string value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
// Gets or sets the integer value of the settings configuration.
|
||||
[JsonPropertyName("value")]
|
||||
public string Value { get; set; }
|
||||
|
@ -6,6 +6,7 @@ using System;
|
||||
using System.Windows;
|
||||
using Microsoft.PowerToys.Settings.UI.Views;
|
||||
using Microsoft.Toolkit.Wpf.UI.XamlHost;
|
||||
using Windows.UI.Popups;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Runner
|
||||
{
|
||||
|
@ -18,34 +18,27 @@
|
||||
<Platforms>x64</Platforms>
|
||||
<ApplicationIcon>icon.ico</ApplicationIcon>
|
||||
<Win32Resource />
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
|
||||
<!-- crutkas TODO: added for fallback, may need to be removed for WinUI3 -->
|
||||
<AssetTargetFallback>uap10.0.18362</AssetTargetFallback>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutputPath>..\..\..\$(Platform)\$(Configuration)\</OutputPath>
|
||||
<OutputPath>..\..\..\$(Platform)\$(Configuration)\SettingsUIRunner</OutputPath>
|
||||
<Optimize>false</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutputPath>..\..\..\$(Platform)\$(Configuration)\</OutputPath>
|
||||
<OutputPath>..\..\..\$(Platform)\$(Configuration)\SettingsUIRunner</OutputPath>
|
||||
<Optimize>true</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="..\..\codeAnalysis\StyleCop.json" Link="StyleCop.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<COMReference Include="TwoWayIPCLibLib.dll">
|
||||
<Guid>7e00d5a3-11df-45c1-a675-96e408bd5bf5</Guid>
|
||||
<VersionMajor>1</VersionMajor>
|
||||
<VersionMinor>0</VersionMinor>
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>tlbimp</WrapperTool>
|
||||
<Isolated>false</Isolated>
|
||||
</COMReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="..\..\codeAnalysis\StyleCop.json" Link="StyleCop.json" />
|
||||
</ItemGroup>
|
||||
@ -62,8 +55,10 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Toolkit.Wpf.UI.Controls" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Toolkit.Wpf.UI.XamlHost" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Toolkit.UI.XamlHost" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.Toolkit.Uwp.UI" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Toolkit.Wpf.UI.Controls" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.Toolkit.Wpf.UI.XamlHost" Version="6.0.1" />
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Configuration Condition=" '$(Configuration)' == 'x64' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x64</Platform>
|
||||
<ProjectGuid>{A7D5099E-F0FD-4BF3-8522-5A682759F915}</ProjectGuid>
|
||||
<OutputType>AppContainerExe</OutputType>
|
||||
|
@ -154,7 +154,7 @@
|
||||
<comment>Navigation view item name for FancyZones</comment>
|
||||
</data>
|
||||
<data name="Shell_ImageResizer.Content" xml:space="preserve">
|
||||
<value>Image Resizer [Not Functional]</value>
|
||||
<value>Image Resizer</value>
|
||||
<comment>Navigation view item name for Image Resizer</comment>
|
||||
</data>
|
||||
<data name="Shell_KeyboardManager.Content" xml:space="preserve">
|
||||
@ -425,4 +425,103 @@
|
||||
<data name="ShortcutGuide_OverlayOpacity.Header" xml:space="preserve">
|
||||
<value>Opacity of the Shortcut Guide's overlay background (%)</value>
|
||||
</data>
|
||||
<data name="ImageResizer_CustomSizes.Text" xml:space="preserve">
|
||||
<value>Image Sizes</value>
|
||||
</data>
|
||||
<data name="ImageResizer_Description.Text" xml:space="preserve">
|
||||
<value>Lets you resize images by right-clicking.</value>
|
||||
</data>
|
||||
<data name="ImageResizer_EnableGroupSettingsHeader.Text" xml:space="preserve">
|
||||
<value>Enable</value>
|
||||
</data>
|
||||
<data name="ImageResizer_EnableToggle.Header" xml:space="preserve">
|
||||
<value>Enable Image Resizer</value>
|
||||
</data>
|
||||
<data name="ImageResizer_AddSizeButton.Label" xml:space="preserve">
|
||||
<value>Add Size</value>
|
||||
</data>
|
||||
<data name="ImageResizer_SaveSizeButton.Label" xml:space="preserve">
|
||||
<value>Save Sizes</value>
|
||||
</data>
|
||||
<data name="ImageResizer_Encoding.Text" xml:space="preserve">
|
||||
<value>JPEG Quality level</value>
|
||||
</data>
|
||||
<data name="ImageResizer_PNGInterlacing.Header" xml:space="preserve">
|
||||
<value>PNG interlacing</value>
|
||||
</data>
|
||||
<data name="ImageResizer_TIFFCompression.Header" xml:space="preserve">
|
||||
<value>TIFF Compression</value>
|
||||
</data>
|
||||
<data name="File.Text" xml:space="preserve">
|
||||
<value>File</value>
|
||||
</data>
|
||||
<data name="Default.Content" xml:space="preserve">
|
||||
<value>Default</value>
|
||||
</data>
|
||||
<data name="ImageResizer_ENCODER_TIFF_CCITT3.Content" xml:space="preserve">
|
||||
<value>CCITT3</value>
|
||||
</data>
|
||||
<data name="ImageResizer_ENCODER_TIFF_CCITT4.Content" xml:space="preserve">
|
||||
<value>CCITT4</value>
|
||||
</data>
|
||||
<data name="ImageResizer_ENCODER_TIFF_Default.Content" xml:space="preserve">
|
||||
<value>Default</value>
|
||||
</data>
|
||||
<data name="ImageResizer_ENCODER_TIFF_LZW.Content" xml:space="preserve">
|
||||
<value>LZW</value>
|
||||
</data>
|
||||
<data name="ImageResizer_ENCODER_TIFF_None.Content" xml:space="preserve">
|
||||
<value>None</value>
|
||||
</data>
|
||||
<data name="ImageResizer_ENCODER_TIFF_RLE.Content" xml:space="preserve">
|
||||
<value>RLE</value>
|
||||
</data>
|
||||
<data name="ImageResizer_ENCODER_TIFF_Zip.Content" xml:space="preserve">
|
||||
<value>Zip</value>
|
||||
</data>
|
||||
<data name="ImageResizer_FallbackEncoder_BMP.Content" xml:space="preserve">
|
||||
<value>BMP Encoder</value>
|
||||
</data>
|
||||
<data name="ImageResizer_FallbackEncoder_GIF.Content" xml:space="preserve">
|
||||
<value>GIF Encoder</value>
|
||||
</data>
|
||||
<data name="ImageResizer_FallbackEncoder_JPEG.Content" xml:space="preserve">
|
||||
<value>JPEG Encoder</value>
|
||||
</data>
|
||||
<data name="ImageResizer_FallbackEncoder_PNG.Content" xml:space="preserve">
|
||||
<value>PNG Encoder</value>
|
||||
</data>
|
||||
<data name="ImageResizer_FallbackEncoder_TIFF.Content" xml:space="preserve">
|
||||
<value>TIFF Encoder</value>
|
||||
</data>
|
||||
<data name="ImageResizer_FallbackEncoder_WMPhoto.Content" xml:space="preserve">
|
||||
<value>WMPhoto Encoder</value>
|
||||
</data>
|
||||
<data name="ImageResizer_Sizes_Fit_Fill.Content" xml:space="preserve">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="ImageResizer_Sizes_Fit_Fit.Content" xml:space="preserve">
|
||||
<value>Fit</value>
|
||||
</data>
|
||||
<data name="ImageResizer_Sizes_Fit_Stretch.Content" xml:space="preserve">
|
||||
<value>Stretch</value>
|
||||
</data>
|
||||
<data name="ImageResizer_Sizes_Units_CM.Content" xml:space="preserve">
|
||||
<value>Centimeters</value>
|
||||
</data>
|
||||
<data name="ImageResizer_Sizes_Units_Inches.Content" xml:space="preserve">
|
||||
<value>Inches</value>
|
||||
</data>
|
||||
<data name="ImageResizer_Sizes_Units_Percent.Content" xml:space="preserve">
|
||||
<value>Percent</value>
|
||||
</data>
|
||||
<data name="ImageResizer_Sizes_Units_Pixels.Content" xml:space="preserve">
|
||||
<value>Pixels</value>
|
||||
</data>
|
||||
<data name="Off.Content" xml:space="preserve">
|
||||
<value>Off</value>
|
||||
</data>
|
||||
<data name="On.Content" xml:space="preserve">
|
||||
<value>On</value>
|
||||
</data>
|
||||
</root>
|
@ -2,14 +2,375 @@
|
||||
// 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.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Input;
|
||||
using Microsoft.PowerToys.Settings.UI.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.Lib;
|
||||
using Microsoft.PowerToys.Settings.UI.Views;
|
||||
using Windows.UI.Popups;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
{
|
||||
public class ImageResizerViewModel : Observable
|
||||
{
|
||||
private ImageResizerSettings Settings { get; set; }
|
||||
|
||||
private const string ModuleName = "ImageResizer";
|
||||
|
||||
public ImageResizerViewModel()
|
||||
{
|
||||
try
|
||||
{
|
||||
Settings = SettingsUtils.GetSettings<ImageResizerSettings>(ModuleName);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Settings = new ImageResizerSettings();
|
||||
SettingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName);
|
||||
}
|
||||
|
||||
GeneralSettings generalSettings;
|
||||
|
||||
try
|
||||
{
|
||||
generalSettings = SettingsUtils.GetSettings<GeneralSettings>(string.Empty);
|
||||
}
|
||||
catch
|
||||
{
|
||||
generalSettings = new GeneralSettings();
|
||||
SettingsUtils.SaveSettings(generalSettings.ToJsonString(), string.Empty);
|
||||
}
|
||||
|
||||
this._isEnabled = generalSettings.Enabled.ImageResizer;
|
||||
this._advancedSizes = Settings.Properties.ImageresizerSizes.Value;
|
||||
this._jpegQualityLevel = Settings.Properties.ImageresizerJpegQualityLevel.Value;
|
||||
this._pngInterlaceOption = Settings.Properties.ImageresizerPngInterlaceOption.Value;
|
||||
this._tiffCompressOption = Settings.Properties.ImageresizerTiffCompressOption.Value;
|
||||
this._fileName = Settings.Properties.ImageresizerFileName.Value;
|
||||
this._keepDateModified = Settings.Properties.ImageresizerKeepDateModified.Value;
|
||||
this._encoderGuidId = GetEncoderIndex(Settings.Properties.ImageresizerFallbackEncoder.Value);
|
||||
|
||||
int i = 0;
|
||||
foreach (ImageSize size in _advancedSizes)
|
||||
{
|
||||
size.Id = i;
|
||||
i++;
|
||||
size.PropertyChanged += Size_PropertyChanged;
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isEnabled = false;
|
||||
private ObservableCollection<ImageSize> _advancedSizes = new ObservableCollection<ImageSize>();
|
||||
private int _jpegQualityLevel = 0;
|
||||
private int _pngInterlaceOption;
|
||||
private int _tiffCompressOption;
|
||||
private string _fileName;
|
||||
private bool _keepDateModified;
|
||||
private int _encoderGuidId = 0;
|
||||
|
||||
public bool IsEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return _isEnabled;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (value != _isEnabled)
|
||||
{
|
||||
_isEnabled = value;
|
||||
GeneralSettings generalSettings = SettingsUtils.GetSettings<GeneralSettings>(string.Empty);
|
||||
generalSettings.Enabled.ImageResizer = value;
|
||||
OutGoingGeneralSettings snd = new OutGoingGeneralSettings(generalSettings);
|
||||
ShellPage.DefaultSndMSGCallback(snd.ToString());
|
||||
OnPropertyChanged("IsEnabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<ImageSize> Sizes
|
||||
{
|
||||
get
|
||||
{
|
||||
return _advancedSizes;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SettingsUtils.SaveSettings(Settings.Properties.ImageresizerSizes.ToJsonString(), ModuleName, "sizes.json");
|
||||
_advancedSizes = value;
|
||||
Settings.Properties.ImageresizerSizes = new ImageresizerSizes(value);
|
||||
SettingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName);
|
||||
OnPropertyChanged("Sizes");
|
||||
}
|
||||
}
|
||||
|
||||
public int JPEGQualityLevel
|
||||
{
|
||||
get
|
||||
{
|
||||
return _jpegQualityLevel;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (_jpegQualityLevel != value)
|
||||
{
|
||||
_jpegQualityLevel = value;
|
||||
Settings.Properties.ImageresizerJpegQualityLevel.Value = value;
|
||||
SettingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName);
|
||||
OnPropertyChanged("JPEGQualityLevel");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int PngInterlaceOption
|
||||
{
|
||||
get
|
||||
{
|
||||
return _pngInterlaceOption;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (_pngInterlaceOption != value)
|
||||
{
|
||||
_pngInterlaceOption = value;
|
||||
Settings.Properties.ImageresizerPngInterlaceOption.Value = value;
|
||||
SettingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName);
|
||||
OnPropertyChanged("PngInterlaceOption");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int TiffCompressOption
|
||||
{
|
||||
get
|
||||
{
|
||||
return _tiffCompressOption;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (_tiffCompressOption != value)
|
||||
{
|
||||
_tiffCompressOption = value;
|
||||
Settings.Properties.ImageresizerTiffCompressOption.Value = value;
|
||||
SettingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName);
|
||||
OnPropertyChanged("TiffCompressOption");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string FileName
|
||||
{
|
||||
get
|
||||
{
|
||||
return _fileName;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
var regex = @"[%]{1}[1-6]{1} [(]{1}[%]{1}[1-6]{1}[)]{1}";
|
||||
Match match = Regex.Match(value.Trim(), regex);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(value) && match.Success)
|
||||
{
|
||||
_fileName = value;
|
||||
Settings.Properties.ImageresizerFileName.Value = value;
|
||||
SettingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName);
|
||||
OnPropertyChanged("FileName");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool KeepDateModified
|
||||
{
|
||||
get
|
||||
{
|
||||
return _keepDateModified;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_keepDateModified = value;
|
||||
Settings.Properties.ImageresizerKeepDateModified.Value = value;
|
||||
SettingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName);
|
||||
OnPropertyChanged("KeepDateModified");
|
||||
}
|
||||
}
|
||||
|
||||
public int Encoder
|
||||
{
|
||||
get
|
||||
{
|
||||
return _encoderGuidId;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (_encoderGuidId != value)
|
||||
{
|
||||
_encoderGuidId = value;
|
||||
SettingsUtils.SaveSettings(Settings.Properties.ImageresizerSizes.ToJsonString(), ModuleName, "sizes.json");
|
||||
Settings.Properties.ImageresizerFallbackEncoder.Value = GetEncoderGuid(value);
|
||||
SettingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName);
|
||||
OnPropertyChanged("Encoder");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand SaveSizesEventHandler
|
||||
{
|
||||
get
|
||||
{
|
||||
return new RelayCommand(SavesImageSizes);
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand DeleteImageSizeEventHandler
|
||||
{
|
||||
get
|
||||
{
|
||||
return new RelayCommand<int>(DeleteImageSize);
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand AddImageSizeEventHandler
|
||||
{
|
||||
get
|
||||
{
|
||||
return new RelayCommand(AddRow);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddRow()
|
||||
{
|
||||
ObservableCollection<ImageSize> imageSizes = Sizes;
|
||||
ImageSize maxSize = imageSizes.OrderBy(x => x.Id).Last();
|
||||
ImageSize newSize = new ImageSize(maxSize.Id + 1);
|
||||
newSize.PropertyChanged += Size_PropertyChanged;
|
||||
imageSizes.Add(newSize);
|
||||
Sizes = imageSizes;
|
||||
OnPropertyChanged("Sizes");
|
||||
}
|
||||
|
||||
public void DeleteImageSize(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
ImageSize size = Sizes.Where<ImageSize>(x => x.Id == id).First();
|
||||
ObservableCollection<ImageSize> imageSizes = Sizes;
|
||||
imageSizes.Remove(size);
|
||||
Sizes = imageSizes;
|
||||
OnPropertyChanged("Sizes");
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public void SavesImageSizes()
|
||||
{
|
||||
SettingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName);
|
||||
}
|
||||
|
||||
public string GetEncoderGuid(int value)
|
||||
{
|
||||
// PNG Encoder guid
|
||||
if (value == 0)
|
||||
{
|
||||
return "1b7cfaf4-713f-473c-bbcd-6137425faeaf";
|
||||
}
|
||||
|
||||
// Bitmap Encoder guid
|
||||
else if (value == 1)
|
||||
{
|
||||
return "0af1d87e-fcfe-4188-bdeb-a7906471cbe3";
|
||||
}
|
||||
|
||||
// JPEG Encoder guid
|
||||
else if (value == 2)
|
||||
{
|
||||
return "19e4a5aa-5662-4fc5-a0c0-1758028e1057";
|
||||
}
|
||||
|
||||
// Tiff encoder guid.
|
||||
else if (value == 3)
|
||||
{
|
||||
return "163bcc30-e2e9-4f0b-961d-a3e9fdb788a3";
|
||||
}
|
||||
|
||||
// Tiff encoder guid.
|
||||
else if (value == 4)
|
||||
{
|
||||
return "57a37caa-367a-4540-916b-f183c5093a4b";
|
||||
}
|
||||
|
||||
// Gif encoder guid.
|
||||
else if (value == 5)
|
||||
{
|
||||
return "1f8a5601-7d4d-4cbd-9c82-1bc8d4eeb9a5";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public int GetEncoderIndex(string guid)
|
||||
{
|
||||
// PNG Encoder guid
|
||||
if (guid == "1b7cfaf4-713f-473c-bbcd-6137425faeaf")
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Bitmap Encoder guid
|
||||
else if (guid == "0af1d87e-fcfe-4188-bdeb-a7906471cbe3")
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
// JPEG Encoder guid
|
||||
else if (guid == "19e4a5aa-5662-4fc5-a0c0-1758028e1057")
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Tiff encoder guid.
|
||||
else if (guid == "163bcc30-e2e9-4f0b-961d-a3e9fdb788a3")
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
// Tiff encoder guid.
|
||||
else if (guid == "57a37caa-367a-4540-916b-f183c5093a4b")
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
// Gif encoder guid.
|
||||
else if (guid == "1f8a5601-7d4d-4cbd-9c82-1bc8d4eeb9a5")
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void Size_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
ImageSize modifiedSize = (ImageSize)sender;
|
||||
ObservableCollection<ImageSize> imageSizes = Sizes;
|
||||
imageSizes.Where<ImageSize>(x => x.Id == modifiedSize.Id).First().Update(modifiedSize);
|
||||
Sizes = imageSizes;
|
||||
OnPropertyChanged("Sizes");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,15 +12,18 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
{
|
||||
public class PowerLauncherViewModel : Observable
|
||||
{
|
||||
private const string POWERTOYNAME = "Launcher";
|
||||
private PowerLauncherSettings settings;
|
||||
private GeneralSettings generalSettings;
|
||||
|
||||
public delegate void SendCallback(PowerLauncherSettings settings);
|
||||
|
||||
private readonly SendCallback callback;
|
||||
|
||||
public PowerLauncherViewModel()
|
||||
{
|
||||
if (SettingsUtils.SettingsExists(POWERTOYNAME))
|
||||
if (SettingsUtils.SettingsExists(PowerLauncherSettings.POWERTOYNAME))
|
||||
{
|
||||
settings = SettingsUtils.GetSettings<PowerLauncherSettings>(POWERTOYNAME);
|
||||
settings = SettingsUtils.GetSettings<PowerLauncherSettings>(PowerLauncherSettings.POWERTOYNAME);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -36,6 +39,19 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
generalSettings = new GeneralSettings();
|
||||
SettingsUtils.SaveSettings(generalSettings.ToJsonString(), string.Empty);
|
||||
}
|
||||
callback = (PowerLauncherSettings settings) =>
|
||||
{
|
||||
// Propagate changes to Power Launcher through IPC
|
||||
var propertiesJson = JsonSerializer.Serialize(settings.properties);
|
||||
ShellPage.DefaultSndMSGCallback(
|
||||
string.Format("{{ \"{0}\": {1} }}", PowerLauncherSettings.POWERTOYNAME, JsonSerializer.Serialize(settings.properties)));
|
||||
};
|
||||
}
|
||||
|
||||
public PowerLauncherViewModel(PowerLauncherSettings settings, SendCallback callback)
|
||||
{
|
||||
this.settings = settings;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
private void UpdateSettings([CallerMemberName] string propertyName = null)
|
||||
@ -43,14 +59,8 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
// Notify UI of property change
|
||||
OnPropertyChanged(propertyName);
|
||||
|
||||
// Save settings to file
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
WriteIndented = true,
|
||||
};
|
||||
SettingsUtils.SaveSettings(JsonSerializer.Serialize(settings, options), POWERTOYNAME);
|
||||
|
||||
// Propagate changes to Power Launcher through IPC
|
||||
settings.Save();
|
||||
callback(settings);
|
||||
}
|
||||
|
||||
public bool EnablePowerLauncher
|
||||
|
@ -11,7 +11,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
{
|
||||
public class PowerPreviewViewModel : Observable
|
||||
{
|
||||
private const string ModuleName = "File Explorer Preview";
|
||||
private const string ModuleName = "File Explorer";
|
||||
|
||||
private PowerPreviewSettings Settings { get; set; }
|
||||
|
||||
|
@ -81,9 +81,8 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
GeneralSettings generalSettings = SettingsUtils.GetSettings<GeneralSettings>(string.Empty);
|
||||
generalSettings.Enabled.ShortcutGuide = value;
|
||||
OutGoingGeneralSettings snd = new OutGoingGeneralSettings(generalSettings);
|
||||
|
||||
ShellPage.DefaultSndMSGCallback(snd.ToString());
|
||||
RaisePropertyChanged();
|
||||
OnPropertyChanged("IsEnabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,13 +2,18 @@
|
||||
x:Class="Microsoft.PowerToys.Settings.UI.Views.ImageResizerPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:Microsoft.PowerToys.Settings.UI.Views"
|
||||
xmlns:viewModel="using:Microsoft.PowerToys.Settings.UI.ViewModels"
|
||||
xmlns:models="using:Microsoft.PowerToys.Settings.UI.Lib"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
||||
mc:Ignorable="d"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
|
||||
<Page.Resources>
|
||||
<viewModel:ImageResizerViewModel x:Key="ViewModel"/>
|
||||
</Page.Resources>
|
||||
|
||||
<Grid ColumnSpacing="{StaticResource DefaultColumnSpacing}" RowSpacing="{StaticResource DefaultRowSpacing}">
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="LayoutVisualStates">
|
||||
@ -40,107 +45,182 @@
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock Text="Lets you resize images by right-clicking."
|
||||
<StackPanel Orientation="Vertical" x:Name="ImageResizerView">
|
||||
|
||||
<TextBlock x:Uid="ImageResizer_Description"
|
||||
TextWrapping="Wrap"/>
|
||||
|
||||
<ToggleSwitch Header="Enable Image Resizer"
|
||||
IsOn="True"
|
||||
Margin="{StaticResource SmallTopMargin}" />
|
||||
|
||||
<TextBlock Text="Sizes"
|
||||
<TextBlock x:Uid="ImageResizer_EnableGroupSettingsHeader"
|
||||
Style="{StaticResource SettingsGroupTitleStyle}"/>
|
||||
|
||||
<!-- TO DO: Don't know if a listview with these items is the best solution here. Maybe a data grid is better? -->
|
||||
<!--<ListView Margin="{StaticResource SmallTopMargin}" Padding="-12,0,0,0" SelectionMode="None" ItemsSource="{x:Bind Sizes, Mode=OneWay}">
|
||||
<!--x:Uid="ImageResizer_EnableToggle"-->
|
||||
<ToggleSwitch IsOn="{ Binding Mode=TwoWay, Path=IsEnabled, Source={StaticResource ViewModel}}"
|
||||
Margin="{StaticResource SmallTopMargin}" />
|
||||
|
||||
<TextBlock x:Uid="ImageResizer_CustomSizes"
|
||||
Style="{StaticResource SettingsGroupTitleStyle}"/>
|
||||
|
||||
|
||||
<ListView x:Name="ImagesSizesListView"
|
||||
ItemsSource="{Binding Sizes, Mode=TwoWay, Source={StaticResource ViewModel}}"
|
||||
Padding="0"
|
||||
IsEnabled="{ Binding Mode=TwoWay, Path=IsEnabled, Source={StaticResource ViewModel}}"
|
||||
Margin="0"
|
||||
>
|
||||
|
||||
<ListView.ItemContainerStyle>
|
||||
<Style TargetType="ListViewItem">
|
||||
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
|
||||
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
|
||||
<Setter Property="Background" Value="{ThemeResource ListViewItemBackground}"/>
|
||||
<Setter Property="Foreground" Value="{ThemeResource ListViewItemForeground}"/>
|
||||
<Setter Property="TabNavigation" Value="Local"/>
|
||||
<Setter Property="IsHoldingEnabled" Value="True"/>
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||
<Setter Property="MinWidth" Value="{ThemeResource ListViewItemMinWidth}"/>
|
||||
<Setter Property="MinHeight" Value="0"/>
|
||||
<Setter Property="AllowDrop" Value="False"/>
|
||||
<Setter Property="UseSystemFocusVisuals" Value="True"/>
|
||||
<Setter Property="FocusVisualMargin" Value="0"/>
|
||||
<Setter Property="FocusVisualPrimaryBrush" Value="{ThemeResource ListViewItemFocusVisualPrimaryBrush}"/>
|
||||
<Setter Property="FocusVisualPrimaryThickness" Value="2"/>
|
||||
<Setter Property="FocusVisualSecondaryBrush" Value="{ThemeResource ListViewItemFocusVisualSecondaryBrush}"/>
|
||||
<Setter Property="FocusVisualSecondaryThickness" Value="1"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ListViewItem">
|
||||
<ListViewItemPresenter CheckBrush="{ThemeResource ListViewItemCheckBrush}" ContentMargin="{TemplateBinding Padding}" CheckMode="{ThemeResource ListViewItemCheckMode}" ContentTransitions="{TemplateBinding ContentTransitions}" CheckBoxBrush="{ThemeResource ListViewItemCheckBoxBrush}" DragForeground="{ThemeResource ListViewItemDragForeground}" DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}" DragBackground="{ThemeResource ListViewItemDragBackground}" DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}" FocusVisualPrimaryBrush="{TemplateBinding FocusVisualPrimaryBrush}" FocusVisualSecondaryThickness="{TemplateBinding FocusVisualSecondaryThickness}" FocusBorderBrush="{ThemeResource ListViewItemFocusBorderBrush}" FocusVisualMargin="{TemplateBinding FocusVisualMargin}" FocusVisualPrimaryThickness="{TemplateBinding FocusVisualPrimaryThickness}" FocusSecondaryBorderBrush="{ThemeResource ListViewItemFocusSecondaryBorderBrush}" FocusVisualSecondaryBrush="{TemplateBinding FocusVisualSecondaryBrush}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Control.IsTemplateFocusTarget="True" PointerOverForeground="{ThemeResource ListViewItemForegroundPointerOver}" PressedBackground="{ThemeResource ListViewItemBackgroundPressed}" PlaceholderBackground="{ThemeResource ListViewItemPlaceholderBackground}" PointerOverBackground="{ThemeResource ListViewItemBackgroundPointerOver}" ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}" SelectedPressedBackground="{ThemeResource ListViewItemBackgroundSelectedPressed}" SelectionCheckMarkVisualEnabled="{ThemeResource ListViewItemSelectionCheckMarkVisualEnabled}" SelectedForeground="{ThemeResource ListViewItemForegroundSelected}" SelectedPointerOverBackground="{ThemeResource ListViewItemBackgroundSelectedPointerOver}" SelectedBackground="{ThemeResource ListViewItemBackgroundSelected}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
</ListView.ItemContainerStyle>
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:DataType="local:ResizeSize">
|
||||
<StackPanel Orientation="Horizontal" Spacing="4">
|
||||
<TextBox Text="{x:Bind Title}" Width="68"/>
|
||||
<ComboBox SelectedIndex="1" Width="88">
|
||||
<ComboBoxItem>Fill</ComboBoxItem>
|
||||
<ComboBoxItem>Fit</ComboBoxItem>
|
||||
<ComboBoxItem>Stretch</ComboBoxItem>
|
||||
<DataTemplate x:Name="SingleLineDataTemplate" x:DataType="models:ImageSize" >
|
||||
<StackPanel Orientation="Horizontal" Padding="0" Spacing="4">
|
||||
<TextBox Text="{x:Bind Path=Name, Mode=TwoWay}"
|
||||
Width="90"
|
||||
Height="35"
|
||||
Margin="{StaticResource SmallTopMargin}"/>
|
||||
|
||||
<ComboBox SelectedIndex="{x:Bind Path=Fit, Mode=TwoWay}"
|
||||
Width="90"
|
||||
Height="35"
|
||||
Margin="{StaticResource SmallTopMargin}">
|
||||
<ComboBoxItem x:Uid="ImageResizer_Sizes_Fit_Fill" />
|
||||
<ComboBoxItem x:Uid="ImageResizer_Sizes_Fit_Fit" />
|
||||
<ComboBoxItem x:Uid="ImageResizer_Sizes_Fit_Stretch" />
|
||||
</ComboBox>
|
||||
<muxc:NumberBox Value="{x:Bind Width}"/>
|
||||
<TextBlock Text="x" FontWeight="SemiBold" Margin="0,4,0,0"/>
|
||||
<muxc:NumberBox Value="{x:Bind Height}"/>
|
||||
<ComboBox SelectedIndex="3">
|
||||
<ComboBoxItem>Centimeters</ComboBoxItem>
|
||||
<ComboBoxItem>Inches</ComboBoxItem>
|
||||
<ComboBoxItem>Percent</ComboBoxItem>
|
||||
<ComboBoxItem>Pixels</ComboBoxItem>
|
||||
|
||||
<muxc:NumberBox Value="{x:Bind Path=Width, Mode=TwoWay}"
|
||||
Width="68"
|
||||
Height="34"
|
||||
Margin="{StaticResource SmallTopMargin}"/>
|
||||
|
||||
<TextBlock Text="x"
|
||||
FontWeight="SemiBold"
|
||||
TextAlignment="Center"
|
||||
Margin="{StaticResource SmallTopMargin}"
|
||||
Width="25"
|
||||
Height="35"/>
|
||||
|
||||
<muxc:NumberBox Value="{x:Bind Path=Height, Mode=TwoWay}"
|
||||
Width="68"
|
||||
Height="34"
|
||||
Margin="{StaticResource SmallTopMargin}"/>
|
||||
|
||||
<ComboBox SelectedIndex="{Binding Path=Unit, Mode=TwoWay}"
|
||||
Width="90"
|
||||
Height="35"
|
||||
Margin="{StaticResource SmallTopMargin}">
|
||||
<ComboBoxItem x:Uid="ImageResizer_Sizes_Units_CM" />
|
||||
<ComboBoxItem x:Uid="ImageResizer_Sizes_Units_Inches" />
|
||||
<ComboBoxItem x:Uid="ImageResizer_Sizes_Units_Percent" />
|
||||
<ComboBoxItem x:Uid="ImageResizer_Sizes_Units_Pixels" />
|
||||
</ComboBox>
|
||||
<Button x:Name="RemoveButton" Background="Transparent" Click="RemoveButton_Click">
|
||||
<Button.Content>
|
||||
<FontIcon Opacity="0.8" Glyph=""/>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<AppBarButton x:Name="RemoveButton"
|
||||
Background="Transparent"
|
||||
Command = "{Binding DeleteImageSizeEventHandler, Source={StaticResource ViewModel}}"
|
||||
CommandParameter="{Binding Id}"
|
||||
Icon="Delete"
|
||||
Width="52"
|
||||
Height="32"
|
||||
Margin="{StaticResource SmallTopMargin}" Padding="0,0,50,100" UseLayoutRounding="False"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>-->
|
||||
</ListView>
|
||||
|
||||
<Button x:Name="AddSizeButton" Content="Add new size" Margin="{StaticResource SmallTopMargin}"/>
|
||||
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<AppBarButton Icon="Add"
|
||||
x:Name="AddSizeButton"
|
||||
IsEnabled="{ Binding Mode=TwoWay, Path=IsEnabled, Source={StaticResource ViewModel}}"
|
||||
Label="Add Size"
|
||||
Margin="{StaticResource SmallTopMargin}"
|
||||
Command = "{Binding AddImageSizeEventHandler, Source={StaticResource ViewModel}}"
|
||||
/>
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock Text="Encoding"
|
||||
Style="{StaticResource SettingsGroupTitleStyle}"/>
|
||||
|
||||
<ComboBox Header="Fallback encoder"
|
||||
SelectedIndex="1"
|
||||
SelectedIndex="{Binding Path=Encoder, Mode=TwoWay, Source={StaticResource ViewModel}}"
|
||||
MinWidth="240"
|
||||
Margin="{StaticResource SmallTopMargin}">
|
||||
<ComboBoxItem>BMP Encoder</ComboBoxItem>
|
||||
<ComboBoxItem>GIF Encoder</ComboBoxItem>
|
||||
<ComboBoxItem>JPEG Encoder</ComboBoxItem>
|
||||
<ComboBoxItem>PNG Encoder</ComboBoxItem>
|
||||
<ComboBoxItem>TIFF Encoder</ComboBoxItem>
|
||||
<ComboBoxItem>WMPhoto Encoder</ComboBoxItem>
|
||||
Margin="{StaticResource SmallTopMargin}"
|
||||
IsEnabled="{ Binding Mode=TwoWay, Path=IsEnabled, Source={StaticResource ViewModel}}">
|
||||
<ComboBoxItem x:Uid="ImageResizer_FallbackEncoder_PNG" />
|
||||
<ComboBoxItem x:Uid="ImageResizer_FallbackEncoder_BMP" />
|
||||
<ComboBoxItem x:Uid="ImageResizer_FallbackEncoder_JPEG" />
|
||||
<ComboBoxItem x:Uid="ImageResizer_FallbackEncoder_TIFF" />
|
||||
<ComboBoxItem x:Uid="ImageResizer_FallbackEncoder_WMPhoto" />
|
||||
<ComboBoxItem x:Uid="ImageResizer_FallbackEncoder_GIF" />
|
||||
</ComboBox>
|
||||
|
||||
|
||||
<muxc:NumberBox Header="JPEG Quality level"
|
||||
Minimum="0"
|
||||
Maximum="100"
|
||||
Value="90"
|
||||
Value="{ Binding Mode=TwoWay, Path=JPEGQualityLevel, Source={StaticResource ViewModel}}"
|
||||
MinWidth="240"
|
||||
SpinButtonPlacementMode="Inline"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="{StaticResource SmallTopMargin}" />
|
||||
Margin="{StaticResource SmallTopMargin}"
|
||||
IsEnabled="{ Binding Mode=TwoWay, Path=IsEnabled, Source={StaticResource ViewModel}}"/>
|
||||
|
||||
<ComboBox Header="PNG interlacing"
|
||||
SelectedIndex="0"
|
||||
SelectedIndex="{ Binding Mode=TwoWay, Path=PngInterlaceOption, Source={StaticResource ViewModel}}"
|
||||
MinWidth="240"
|
||||
Margin="{StaticResource SmallTopMargin}">
|
||||
<ComboBoxItem>Default</ComboBoxItem>
|
||||
<ComboBoxItem>On</ComboBoxItem>
|
||||
<ComboBoxItem>Off</ComboBoxItem>
|
||||
Margin="{StaticResource SmallTopMargin}"
|
||||
IsEnabled="{ Binding Mode=TwoWay, Path=IsEnabled, Source={StaticResource ViewModel}}">
|
||||
<ComboBoxItem x:Uid="Default"/>
|
||||
<ComboBoxItem x:Uid="On"/>
|
||||
<ComboBoxItem x:Uid="Off"/>
|
||||
</ComboBox>
|
||||
|
||||
<ComboBox Header="TIFF Compression"
|
||||
SelectedIndex="0"
|
||||
SelectedIndex="{ Binding Mode=TwoWay, Path=TiffCompressOption, Source={StaticResource ViewModel}}"
|
||||
MinWidth="240"
|
||||
Margin="{StaticResource SmallTopMargin}">
|
||||
<ComboBoxItem>Default</ComboBoxItem>
|
||||
<ComboBoxItem>None</ComboBoxItem>
|
||||
<ComboBoxItem>CCITT3</ComboBoxItem>
|
||||
<ComboBoxItem>CCITT4</ComboBoxItem>
|
||||
<ComboBoxItem>LZW</ComboBoxItem>
|
||||
<ComboBoxItem>RLE</ComboBoxItem>
|
||||
<ComboBoxItem>Zip</ComboBoxItem>
|
||||
Margin="{StaticResource SmallTopMargin}"
|
||||
IsEnabled="{ Binding Mode=TwoWay, Path=IsEnabled, Source={StaticResource ViewModel}}">
|
||||
<ComboBoxItem x:Uid="ImageResizer_ENCODER_TIFF_Default"/>
|
||||
<ComboBoxItem x:Uid="ImageResizer_ENCODER_TIFF_None"/>
|
||||
<ComboBoxItem x:Uid="ImageResizer_ENCODER_TIFF_CCITT3"/>
|
||||
<ComboBoxItem x:Uid="ImageResizer_ENCODER_TIFF_CCITT4"/>
|
||||
<ComboBoxItem x:Uid="ImageResizer_ENCODER_TIFF_LZW"/>
|
||||
<ComboBoxItem x:Uid="ImageResizer_ENCODER_TIFF_RLE"/>
|
||||
<ComboBoxItem x:Uid="ImageResizer_ENCODER_TIFF_Zip"/>
|
||||
</ComboBox>
|
||||
|
||||
<TextBlock Text="File"
|
||||
Style="{StaticResource SettingsGroupTitleStyle}"/>
|
||||
|
||||
|
||||
<TextBox Header="Filename format"
|
||||
Text="%1 (%2)"
|
||||
HorizontalAlignment="Left"
|
||||
MinWidth="240"
|
||||
Margin="{StaticResource SmallTopMargin}"/>
|
||||
|
||||
<TextBlock Text="The following parameters can be used:"
|
||||
Margin="{StaticResource SmallTopBottomMargin}"/>
|
||||
Margin="{StaticResource SmallTopBottomMargin}"/>
|
||||
|
||||
<TextBlock FontSize="12">
|
||||
<Run FontWeight="Bold">%1</Run>
|
||||
@ -167,11 +247,20 @@
|
||||
<Run> - Actual width</Run>
|
||||
</TextBlock>
|
||||
|
||||
<CheckBox Content="Use original date modified"
|
||||
<TextBox Header="Filename format"
|
||||
Text="{ Binding Mode=TwoWay, Path=FileName, Source={StaticResource ViewModel}}"
|
||||
HorizontalAlignment="Left"
|
||||
MinWidth="240"
|
||||
IsEnabled="{ Binding Mode=TwoWay, Path=IsEnabled, Source={StaticResource ViewModel}}"
|
||||
Margin="{StaticResource SmallTopMargin}"/>
|
||||
|
||||
<CheckBox Content="Use original date modified"
|
||||
IsEnabled="{ Binding Mode=TwoWay, Path=IsEnabled, Source={StaticResource ViewModel}}"
|
||||
Margin="{StaticResource SmallTopMargin}"
|
||||
IsChecked="{Binding Mode=TwoWay, Path=KeepDateModified, Source={StaticResource ViewModel}}"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel
|
||||
<StackPanel
|
||||
x:Name="SidePanel"
|
||||
Orientation="Vertical"
|
||||
HorizontalAlignment="Left"
|
||||
@ -179,19 +268,26 @@
|
||||
Grid.Column="1">
|
||||
|
||||
<TextBlock
|
||||
Text="About this feature"
|
||||
x:Uid="About_This_Feature"
|
||||
Style="{StaticResource SettingsGroupTitleStyle}"
|
||||
Margin="{StaticResource XSmallBottomMargin}"/>
|
||||
|
||||
<HyperlinkButton Content="Module overview"/>
|
||||
<HyperlinkButton
|
||||
x:Uid="Module_overview"
|
||||
NavigateUri="https://github.com/microsoft/PowerToys/blob/master/src/modules/imageresizer/README.md"/>
|
||||
|
||||
<HyperlinkButton x:Uid="Give_Feedback"
|
||||
NavigateUri="https://github.com/microsoft/PowerToys/issues"/>
|
||||
|
||||
<TextBlock
|
||||
Text="Attribution"
|
||||
x:Uid="AttributionTitle"
|
||||
Style="{StaticResource SettingsGroupTitleStyle}" />
|
||||
|
||||
<HyperlinkButton
|
||||
Content="Brice Lams's Image Resizer"
|
||||
Content="Brice Lambson"
|
||||
NavigateUri="https://github.com/bricelam/ImageResizer/" />
|
||||
|
||||
</StackPanel>
|
||||
|
||||
</Grid>
|
||||
</Page>
|
@ -9,11 +9,12 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
{
|
||||
public sealed partial class ImageResizerPage : Page
|
||||
{
|
||||
public ImageResizerViewModel ViewModel { get; } = new ImageResizerViewModel();
|
||||
public ImageResizerViewModel ViewModel { get; set; }
|
||||
|
||||
public ImageResizerPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
ViewModel = new ImageResizerViewModel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,8 @@
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock x:Uid="PowerLauncher_Description" Style="{StaticResource BodyTextBlockStyle}"
|
||||
<TextBlock x:Uid="PowerLauncher_Description"
|
||||
Style="{StaticResource BodyTextBlockStyle}"
|
||||
TextWrapping="Wrap"/>
|
||||
|
||||
<ToggleSwitch x:Uid="PowerLauncher_EnablePowerLauncher"
|
||||
|
@ -1,184 +1,186 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProjectGuid>{A80355C2-780D-4245-BD80-25B8DE698EE3}</ProjectGuid>
|
||||
<OutputType>AppContainerExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Microsoft.PowerToys.Settings.UnitTest</RootNamespace>
|
||||
<AssemblyName>Microsoft.PowerToys.Settings.UnitTest</AssemblyName>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
||||
<TargetPlatformVersion>10.0.18362.0</TargetPlatformVersion>
|
||||
<TargetPlatformMinVersion>10.0.18362.0</TargetPlatformMinVersion>
|
||||
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<UnitTestPlatformVersion Condition="'$(UnitTestPlatformVersion)' == ''">$(VisualStudioVersion)</UnitTestPlatformVersion>
|
||||
<AppxPackageSigningEnabled>false</AppxPackageSigningEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\ARM\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>ARM</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
|
||||
<OutputPath>bin\ARM\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>ARM</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\ARM64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>ARM64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM64'">
|
||||
<OutputPath>bin\ARM64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>ARM64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\Test\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>false</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<SDKReference Include="TestPlatform.Universal, Version=$(UnitTestPlatformVersion)" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ModelsTests\BasePTModuleSettingsTest.cs" />
|
||||
<Compile Include="ModelsTests\BasePTSettingsTest.cs" />
|
||||
<Compile Include="ModelsTests\SettingsUtilsTests.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="UnitTestApp.xaml.cs">
|
||||
<DependentUpon>UnitTestApp.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="ViewModelTests\ShortcutGuideViewModelTest.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="UnitTestApp.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="Package.appxmanifest">
|
||||
<SubType>Designer</SubType>
|
||||
</AppxManifest>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Assets\LockScreenLogo.scale-200.png" />
|
||||
<Content Include="Assets\SplashScreen.scale-200.png" />
|
||||
<Content Include="Assets\Square150x150Logo.scale-200.png" />
|
||||
<Content Include="Assets\Square44x44Logo.scale-200.png" />
|
||||
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
|
||||
<Content Include="Assets\StoreLogo.png" />
|
||||
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
|
||||
<Version>6.2.9</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MSTest.TestAdapter">
|
||||
<Version>2.1.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MSTest.TestFramework">
|
||||
<Version>2.1.1</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.PowerToys.Settings.UI.Lib\Microsoft.PowerToys.Settings.UI.Lib.csproj">
|
||||
<Project>{b1bcc8c6-46b5-4bfa-8f22-20f32d99ec6a}</Project>
|
||||
<Name>Microsoft.PowerToys.Settings.UI.Lib</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Microsoft.PowerToys.Settings.UI\Microsoft.PowerToys.Settings.UI.csproj">
|
||||
<Project>{a7d5099e-f0fd-4bf3-8522-5a682759f915}</Project>
|
||||
<Name>Microsoft.PowerToys.Settings.UI</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProjectGuid>{A80355C2-780D-4245-BD80-25B8DE698EE3}</ProjectGuid>
|
||||
<OutputType>AppContainerExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Microsoft.PowerToys.Settings.UnitTest</RootNamespace>
|
||||
<AssemblyName>Microsoft.PowerToys.Settings.UnitTest</AssemblyName>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
||||
<TargetPlatformVersion>10.0.18362.0</TargetPlatformVersion>
|
||||
<TargetPlatformMinVersion>10.0.18362.0</TargetPlatformMinVersion>
|
||||
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<UnitTestPlatformVersion Condition="'$(UnitTestPlatformVersion)' == ''">$(VisualStudioVersion)</UnitTestPlatformVersion>
|
||||
<AppxPackageSigningEnabled>false</AppxPackageSigningEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\ARM\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>ARM</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
|
||||
<OutputPath>bin\ARM\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>ARM</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\ARM64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>ARM64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM64'">
|
||||
<OutputPath>bin\ARM64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>ARM64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\Test\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>false</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<SDKReference Include="TestPlatform.Universal, Version=$(UnitTestPlatformVersion)" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ViewModelTests\ImageResizer.cs" />
|
||||
<Compile Include="ModelsTests\BasePTModuleSettingsTest.cs" />
|
||||
<Compile Include="ModelsTests\BasePTSettingsTest.cs" />
|
||||
<Compile Include="ModelsTests\SettingsUtilsTests.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="UnitTestApp.xaml.cs">
|
||||
<DependentUpon>UnitTestApp.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="ViewModelTests\ShortcutGuide.cs" />
|
||||
<Compile Include="ViewModelTests\PowerLauncherViewModelTest.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="UnitTestApp.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="Package.appxmanifest">
|
||||
<SubType>Designer</SubType>
|
||||
</AppxManifest>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Assets\LockScreenLogo.scale-200.png" />
|
||||
<Content Include="Assets\SplashScreen.scale-200.png" />
|
||||
<Content Include="Assets\Square150x150Logo.scale-200.png" />
|
||||
<Content Include="Assets\Square44x44Logo.scale-200.png" />
|
||||
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
|
||||
<Content Include="Assets\StoreLogo.png" />
|
||||
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
|
||||
<Version>6.2.9</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MSTest.TestAdapter">
|
||||
<Version>2.1.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MSTest.TestFramework">
|
||||
<Version>2.1.1</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.PowerToys.Settings.UI.Lib\Microsoft.PowerToys.Settings.UI.Lib.csproj">
|
||||
<Project>{b1bcc8c6-46b5-4bfa-8f22-20f32d99ec6a}</Project>
|
||||
<Name>Microsoft.PowerToys.Settings.UI.Lib</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Microsoft.PowerToys.Settings.UI\Microsoft.PowerToys.Settings.UI.csproj">
|
||||
<Project>{a7d5099e-f0fd-4bf3-8522-5a682759f915}</Project>
|
||||
<Name>Microsoft.PowerToys.Settings.UI</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
@ -1,10 +1,11 @@
|
||||
using Microsoft.PowerToys.Settings.UI.Lib;
|
||||
using Microsoft.PowerToys.Settings.UnitTest;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Schema;
|
||||
using System;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UnitTest
|
||||
namespace CommonLibTest
|
||||
{
|
||||
[TestClass]
|
||||
public class BasePTModuleSettingsTest
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Microsoft.PowerToys.Settings.UI.Lib;
|
||||
using Microsoft.PowerToys.Settings.UnitTest;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
@ -7,7 +8,7 @@ using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UnitTest
|
||||
namespace CommonLibTest
|
||||
{
|
||||
[TestClass]
|
||||
public class SettingsUtilsTests
|
||||
|
@ -0,0 +1,214 @@
|
||||
using Microsoft.PowerToys.Settings.UI.Lib;
|
||||
using Microsoft.PowerToys.Settings.UI.ViewModels;
|
||||
using Microsoft.PowerToys.Settings.UI.Views;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ViewModelTests
|
||||
{
|
||||
[TestClass]
|
||||
public class ImageResizer
|
||||
{
|
||||
public const string Module = "ImageResizer";
|
||||
[TestInitialize]
|
||||
public void Setup()
|
||||
{
|
||||
// initialize creation of test settings file.
|
||||
// Test base path:
|
||||
// C:\Users\<user name>\AppData\Local\Packages\08e1807b-8b6d-4bfa-adc4-79c64aae8e78_9abkseg265h2m\LocalState\Microsoft\PowerToys\
|
||||
GeneralSettings generalSettings = new GeneralSettings();
|
||||
ImageResizerSettings imageResizer = new ImageResizerSettings();
|
||||
|
||||
SettingsUtils.SaveSettings(generalSettings.ToJsonString());
|
||||
SettingsUtils.SaveSettings(imageResizer.ToJsonString(), imageResizer.Name);
|
||||
}
|
||||
|
||||
[TestCleanup]
|
||||
public void CleanUp()
|
||||
{
|
||||
// delete folder created.
|
||||
string generalSettings_file_name = string.Empty;
|
||||
if (SettingsUtils.SettingsFolderExists(generalSettings_file_name))
|
||||
{
|
||||
DeleteFolder(generalSettings_file_name);
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteFolder(string powertoy)
|
||||
{
|
||||
Directory.Delete(Path.Combine(SettingsUtils.LocalApplicationDataFolder(), $"Microsoft\\PowerToys\\{powertoy}"), true);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IsEnabled_ShouldEnableModule_WhenSuccessful()
|
||||
{
|
||||
// arrange
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel();
|
||||
|
||||
// Assert
|
||||
ShellPage.DefaultSndMSGCallback = msg =>
|
||||
{
|
||||
OutGoingGeneralSettings snd = JsonSerializer.Deserialize<OutGoingGeneralSettings>(msg);
|
||||
Assert.IsTrue(snd.GeneralSettings.Enabled.ImageResizer);
|
||||
};
|
||||
|
||||
// act
|
||||
viewModel.IsEnabled = true;
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void JPEGQualityLevel_ShouldSetValueToTen_WhenSuccefull()
|
||||
{
|
||||
// arrange
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel();
|
||||
|
||||
// act
|
||||
viewModel.JPEGQualityLevel = 10;
|
||||
|
||||
// Assert
|
||||
viewModel = new ImageResizerViewModel();
|
||||
Assert.AreEqual(10, viewModel.JPEGQualityLevel);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void PngInterlaceOption_ShouldSetValueToTen_WhenSuccefull()
|
||||
{
|
||||
// arrange
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel();
|
||||
|
||||
// act
|
||||
viewModel.PngInterlaceOption = 10;
|
||||
|
||||
// Assert
|
||||
viewModel = new ImageResizerViewModel();
|
||||
Assert.AreEqual(10, viewModel.PngInterlaceOption);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TiffCompressOption_ShouldSetValueToTen_WhenSuccefull()
|
||||
{
|
||||
// arrange
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel();
|
||||
|
||||
// act
|
||||
viewModel.TiffCompressOption = 10;
|
||||
|
||||
// Assert
|
||||
viewModel = new ImageResizerViewModel();
|
||||
Assert.AreEqual(10, viewModel.TiffCompressOption);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FileName_ShouldUpdateValue_WhenSuccefull()
|
||||
{
|
||||
// arrange
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel();
|
||||
string exptectedValue = "%1 (%3)";
|
||||
|
||||
// act
|
||||
viewModel.FileName = exptectedValue;
|
||||
|
||||
// Assert
|
||||
viewModel = new ImageResizerViewModel();
|
||||
Assert.AreEqual(exptectedValue, viewModel.FileName);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FileName_ShouldNOTUpdateValue_WhenNameIsInValid ()
|
||||
{
|
||||
// arrange
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel();
|
||||
string[] invalidNames =
|
||||
{
|
||||
string.Empty,
|
||||
" ", // no name.
|
||||
"%1", // single name value.
|
||||
"%7 (%5)", // name max index exceeded.
|
||||
"%8 (%8)", // name max index exceeded.
|
||||
"%5 (%3 )", // name contains extra spaces.
|
||||
"%5 (%3)", // name contains extra spaces.
|
||||
"%5 ( %3)", // name contains extra spaces.
|
||||
"% 5 ( %3)", // name contains extra spaces.
|
||||
"%5 (% 3)", // name contains extra spaces.
|
||||
"%5 ( %3 )", // name contains extra spaces.
|
||||
};
|
||||
|
||||
// act and Assert
|
||||
foreach (string invalidName in invalidNames)
|
||||
{
|
||||
viewModel = new ImageResizerViewModel();
|
||||
viewModel.FileName = invalidName;
|
||||
Assert.AreNotEqual(invalidName, viewModel.FileName);
|
||||
|
||||
ImageResizerSettings settings = SettingsUtils.GetSettings<ImageResizerSettings>(Module);
|
||||
Assert.AreNotEqual(invalidName, settings.Properties.ImageresizerFileName.Value);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void KeepDateModified_ShouldUpdateValue_WhenSuccefull()
|
||||
{
|
||||
// arrange
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel();
|
||||
|
||||
// act
|
||||
viewModel.KeepDateModified = true;
|
||||
|
||||
// Assert
|
||||
ImageResizerSettings settings = SettingsUtils.GetSettings<ImageResizerSettings>(Module);
|
||||
Assert.AreEqual(true, settings.Properties.ImageresizerKeepDateModified.Value);
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void Encoder_ShouldUpdateValue_WhenSuccefull()
|
||||
{
|
||||
// arrange
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel();
|
||||
|
||||
// act
|
||||
viewModel.Encoder = 3;
|
||||
|
||||
// Assert
|
||||
viewModel = new ImageResizerViewModel();
|
||||
Assert.AreEqual("163bcc30-e2e9-4f0b-961d-a3e9fdb788a3", viewModel.GetEncoderGuid(viewModel.Encoder));
|
||||
Assert.AreEqual(3, viewModel.Encoder);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void AddRow_ShouldAddEmptyImageSize_WhenSuccefull()
|
||||
{
|
||||
// arrange
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel();
|
||||
int sizeOfOriginalArray = viewModel.Sizes.Count;
|
||||
|
||||
// act
|
||||
viewModel.AddRow();
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(viewModel.Sizes.Count, sizeOfOriginalArray + 1);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void DeleteImageSize_ShouldDeleteImageSize_WhenSuccefull()
|
||||
{
|
||||
// arrange
|
||||
ImageResizerViewModel viewModel = new ImageResizerViewModel();
|
||||
int sizeOfOriginalArray = viewModel.Sizes.Count;
|
||||
ImageSize deleteCandidate = viewModel.Sizes.Where<ImageSize>(x => x.Id == 0).First();
|
||||
|
||||
// act
|
||||
viewModel.DeleteImageSize(0);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(viewModel.Sizes.Count, sizeOfOriginalArray - 1);
|
||||
Assert.IsFalse(viewModel.Sizes.Contains(deleteCandidate));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,159 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Microsoft.PowerToys.Settings.UI.ViewModels;
|
||||
using Microsoft.PowerToys.Settings.UI.Lib;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace ViewModelTests
|
||||
{
|
||||
[TestClass]
|
||||
public class PowerLauncher
|
||||
{
|
||||
class PowerLauncherSettingsMock : PowerLauncherSettings
|
||||
{
|
||||
public int TimesSaved { get; set; }
|
||||
public override void Save()
|
||||
{
|
||||
TimesSaved++;
|
||||
}
|
||||
}
|
||||
|
||||
class SendCallbackMock
|
||||
{
|
||||
public int TimesSent { get; set; }
|
||||
public void OnSend(PowerLauncherSettings settings)
|
||||
{
|
||||
TimesSent++;
|
||||
}
|
||||
}
|
||||
private PowerLauncherViewModel viewModel;
|
||||
private PowerLauncherSettingsMock mockSettings;
|
||||
private SendCallbackMock sendCallbackMock;
|
||||
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
mockSettings = new PowerLauncherSettingsMock();
|
||||
sendCallbackMock = new SendCallbackMock();
|
||||
|
||||
viewModel = new PowerLauncherViewModel(
|
||||
mockSettings,
|
||||
new PowerLauncherViewModel.SendCallback(sendCallbackMock.OnSend)
|
||||
);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IsEnabled_ShouldEnableModule()
|
||||
{
|
||||
viewModel.EnablePowerLauncher = true;
|
||||
|
||||
Assert.AreEqual(sendCallbackMock.TimesSent, 1);
|
||||
Assert.AreEqual(mockSettings.TimesSaved, 1);
|
||||
|
||||
Assert.IsTrue(mockSettings.properties.enable_powerlauncher == true);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void SearchPreference_ShouldUpdatePreferences()
|
||||
{
|
||||
viewModel.SearchResultPreference = "SearchOptionsAreNotValidated";
|
||||
viewModel.SearchTypePreference = "SearchOptionsAreNotValidated";
|
||||
|
||||
Assert.AreEqual(sendCallbackMock.TimesSent, 2);
|
||||
Assert.AreEqual(mockSettings.TimesSaved, 2);
|
||||
|
||||
Assert.IsTrue(mockSettings.properties.search_result_preference == "SearchOptionsAreNotValidated");
|
||||
Assert.IsTrue(mockSettings.properties.search_type_preference == "SearchOptionsAreNotValidated");
|
||||
}
|
||||
|
||||
public void AssertHotkeySettings(HotkeySettings setting, bool win, bool ctrl, bool alt, bool shift, int code)
|
||||
{
|
||||
Assert.AreEqual(setting.Win, win);
|
||||
Assert.AreEqual(setting.Ctrl, ctrl);
|
||||
Assert.AreEqual(setting.Alt, alt);
|
||||
Assert.AreEqual(setting.Shift, shift);
|
||||
Assert.AreEqual(setting.Code, code);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Hotkeys_ShouldUpdateHotkeys()
|
||||
{
|
||||
var openPowerLauncher = new HotkeySettings();
|
||||
openPowerLauncher.Win = true;
|
||||
openPowerLauncher.Code = (int)Windows.System.VirtualKey.S;
|
||||
|
||||
|
||||
var openFileLocation = new HotkeySettings();
|
||||
openFileLocation.Ctrl = true;
|
||||
openFileLocation.Code = (int)Windows.System.VirtualKey.A;
|
||||
|
||||
var openConsole = new HotkeySettings();
|
||||
openConsole.Alt = true;
|
||||
openConsole.Code = (int)Windows.System.VirtualKey.D;
|
||||
|
||||
var copyFileLocation = new HotkeySettings();
|
||||
copyFileLocation.Shift = true;
|
||||
copyFileLocation.Code = (int)Windows.System.VirtualKey.F;
|
||||
|
||||
viewModel.OpenPowerLauncher = openPowerLauncher;
|
||||
viewModel.OpenFileLocation = openFileLocation;
|
||||
viewModel.OpenConsole = openConsole;
|
||||
viewModel.CopyPathLocation = copyFileLocation;
|
||||
|
||||
Assert.AreEqual(mockSettings.TimesSaved, 4);
|
||||
Assert.AreEqual(sendCallbackMock.TimesSent, 4);
|
||||
|
||||
AssertHotkeySettings(
|
||||
mockSettings.properties.open_powerlauncher,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
(int)Windows.System.VirtualKey.S
|
||||
);
|
||||
AssertHotkeySettings(
|
||||
mockSettings.properties.open_file_location,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
(int)Windows.System.VirtualKey.A
|
||||
);
|
||||
AssertHotkeySettings(
|
||||
mockSettings.properties.open_console,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
(int)Windows.System.VirtualKey.D
|
||||
);
|
||||
AssertHotkeySettings(
|
||||
mockSettings.properties.copy_path_location,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
(int)Windows.System.VirtualKey.F
|
||||
);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Override_ShouldUpdateOverrides()
|
||||
{
|
||||
viewModel.OverrideWinRKey = true;
|
||||
viewModel.OverrideWinSKey = false;
|
||||
|
||||
|
||||
Assert.AreEqual(sendCallbackMock.TimesSent, 1);
|
||||
Assert.AreEqual(mockSettings.TimesSaved, 1);
|
||||
|
||||
Assert.IsTrue(mockSettings.properties.override_win_r_key);
|
||||
Assert.IsFalse(mockSettings.properties.override_win_s_key);
|
||||
}
|
||||
}
|
||||
}
|
@ -10,10 +10,10 @@ using System.IO;
|
||||
using System.Text.Json;
|
||||
using Windows.UI.Popups;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UnitTest.ViewModelTests
|
||||
namespace ViewModelTests
|
||||
{
|
||||
[TestClass]
|
||||
public class ShortcutGuideViewModelTest
|
||||
public class ShortcutGuide
|
||||
{
|
||||
[TestInitialize]
|
||||
public void Setup()
|
||||
@ -28,6 +28,22 @@ namespace Microsoft.PowerToys.Settings.UnitTest.ViewModelTests
|
||||
SettingsUtils.SaveSettings(shortcutGuide.ToJsonString(), shortcutGuide.Name);
|
||||
}
|
||||
|
||||
[TestCleanup]
|
||||
public void CleanUp()
|
||||
{
|
||||
// delete folder created.
|
||||
string file_name = "\\test";
|
||||
if (SettingsUtils.SettingsFolderExists(file_name))
|
||||
{
|
||||
DeleteFolder(file_name);
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteFolder(string powertoy)
|
||||
{
|
||||
Directory.Delete(Path.Combine(SettingsUtils.LocalApplicationDataFolder(), $"Microsoft\\PowerToys\\{powertoy}"), true);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IsEnabled_ShouldEnableModule_WhenSuccessful()
|
||||
{
|
||||
@ -39,7 +55,7 @@ namespace Microsoft.PowerToys.Settings.UnitTest.ViewModelTests
|
||||
ShellPage.DefaultSndMSGCallback = msg =>
|
||||
{
|
||||
OutGoingGeneralSettings snd = JsonSerializer.Deserialize<OutGoingGeneralSettings>(msg);
|
||||
Assert.IsTrue(snd.general.Enabled.ShortcutGuide);
|
||||
Assert.IsTrue(snd.GeneralSettings.Enabled.ShortcutGuide);
|
||||
};
|
||||
|
||||
// Act
|
||||
@ -56,9 +72,8 @@ namespace Microsoft.PowerToys.Settings.UnitTest.ViewModelTests
|
||||
// Initilize mock function of sending IPC message.
|
||||
ShellPage.DefaultSndMSGCallback = msg =>
|
||||
{
|
||||
SndModuleSettings<ShortcutGuideSettings> snd = JsonSerializer.Deserialize<SndModuleSettings<ShortcutGuideSettings>>(msg);
|
||||
Assert.AreEqual("dark", snd.powertoys.Properties.Theme.Value);
|
||||
Assert.AreEqual("hey", msg);
|
||||
ShortcutGuideSettingsIPCMessage snd = JsonSerializer.Deserialize<ShortcutGuideSettingsIPCMessage>(msg);
|
||||
Assert.AreEqual("dark", snd.Powertoys.ShortcutGuide.Properties.Theme.Value);
|
||||
};
|
||||
|
||||
// Act
|
||||
@ -75,9 +90,8 @@ namespace Microsoft.PowerToys.Settings.UnitTest.ViewModelTests
|
||||
// Initilize mock function of sending IPC message.
|
||||
ShellPage.DefaultSndMSGCallback = msg =>
|
||||
{
|
||||
SndModuleSettings<ShortcutGuideSettings> snd = JsonSerializer.Deserialize<SndModuleSettings<ShortcutGuideSettings>>(msg);
|
||||
// https://stackoverflow.com/questions/59198417/deserialization-of-reference-types-without-parameterless-constructor-is-not-supp
|
||||
Assert.AreEqual(100, snd.powertoys.Properties.PressTime.Value);
|
||||
ShortcutGuideSettingsIPCMessage snd = JsonSerializer.Deserialize<ShortcutGuideSettingsIPCMessage>(msg);
|
||||
Assert.AreEqual(100, snd.Powertoys.ShortcutGuide.Properties.PressTime.Value);
|
||||
};
|
||||
|
||||
// Act
|
||||
@ -94,14 +108,13 @@ namespace Microsoft.PowerToys.Settings.UnitTest.ViewModelTests
|
||||
// Initilize mock function of sending IPC message.
|
||||
ShellPage.DefaultSndMSGCallback = msg =>
|
||||
{
|
||||
SndModuleSettings<ShortcutGuideSettings> snd = JsonSerializer.Deserialize<SndModuleSettings<ShortcutGuideSettings>>(msg);
|
||||
ShortcutGuideSettingsIPCMessage snd = JsonSerializer.Deserialize<ShortcutGuideSettingsIPCMessage>(msg);
|
||||
// Serialisation not working as expected in the test project:
|
||||
// https://stackoverflow.com/questions/59198417/deserialization-of-reference-types-without-parameterless-constructor-is-not-supp
|
||||
Assert.AreEqual(100, snd.powertoys.Properties.OverlayOpacity.Value);
|
||||
Assert.AreEqual(100, snd.Powertoys.ShortcutGuide.Properties.OverlayOpacity.Value);
|
||||
};
|
||||
|
||||
// Act
|
||||
viewModel.OverlayOpacity = 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -52,6 +52,8 @@
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
<None Include="packages.config">
|
||||
<Filter>Source Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) Brice Lambson
|
||||
// The Brice Lambson licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
|
||||
// ShowAdvancedCommand = new RelayCommand(ShowAdvanced);
|
||||
|
||||
using System.Windows.Input;
|
||||
using GalaSoft.MvvmLight;
|
||||
@ -32,7 +33,6 @@ namespace ImageResizer.ViewModels
|
||||
|
||||
ResizeCommand = new RelayCommand(Resize);
|
||||
CancelCommand = new RelayCommand(Cancel);
|
||||
ShowAdvancedCommand = new RelayCommand(ShowAdvanced);
|
||||
}
|
||||
|
||||
public Settings Settings { get; }
|
||||
@ -51,8 +51,5 @@ namespace ImageResizer.ViewModels
|
||||
|
||||
public void Cancel()
|
||||
=> _mainView.Close();
|
||||
|
||||
public void ShowAdvanced()
|
||||
=> _mainView.ShowAdvanced(new AdvancedViewModel(Settings));
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) Brice Lambson
|
||||
// The Brice Lambson licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
|
||||
// void ShowAdvanced(AdvancedViewModel viewModel);
|
||||
|
||||
using System.Collections.Generic;
|
||||
using ImageResizer.ViewModels;
|
||||
@ -11,8 +12,6 @@ namespace ImageResizer.Views
|
||||
{
|
||||
void Close();
|
||||
|
||||
void ShowAdvanced(AdvancedViewModel viewModel);
|
||||
|
||||
IEnumerable<string> OpenPictureFiles();
|
||||
}
|
||||
}
|
||||
|
@ -129,11 +129,13 @@
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<!--
|
||||
<TextBlock VerticalAlignment="Center">
|
||||
<Hyperlink Command="{Binding ShowAdvancedCommand}">
|
||||
<Run Text="{x:Static p:Resources.Input_ShowAdvanced}"/>
|
||||
</Hyperlink>
|
||||
</TextBlock>
|
||||
-->
|
||||
<Button Grid.Column="1"
|
||||
Height="23"
|
||||
MinWidth="75"
|
||||
|
@ -39,9 +39,10 @@ namespace ImageResizer.Views
|
||||
return openFileDialog.FileNames;
|
||||
}
|
||||
|
||||
/*
|
||||
public void ShowAdvanced(AdvancedViewModel viewModel)
|
||||
=> viewModel.Close(new AdvancedWindow(viewModel).ShowDialog() == true);
|
||||
|
||||
*/
|
||||
void IMainView.Close()
|
||||
=> Dispatcher.Invoke((Action)Close);
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ namespace KeyboardManagerHelper
|
||||
}
|
||||
|
||||
// Function to return if the key is an extended key which requires the use of the extended key flag
|
||||
bool isExtendedKey(DWORD key)
|
||||
bool IsExtendedKey(DWORD key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
@ -79,6 +79,7 @@ namespace KeyboardManagerHelper
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Collections::IVector<IInspectable> ToBoxValue(const std::vector<std::wstring>& list)
|
||||
{
|
||||
Collections::IVector<IInspectable> boxList = single_threaded_vector<IInspectable>();
|
||||
@ -89,4 +90,73 @@ namespace KeyboardManagerHelper
|
||||
|
||||
return boxList;
|
||||
}
|
||||
|
||||
// Function to check if two keys are equal or cover the same set of keys. Return value depends on type of overlap
|
||||
ErrorType DoKeysOverlap(DWORD first, DWORD second)
|
||||
{
|
||||
// If the keys are same
|
||||
if (first == second)
|
||||
{
|
||||
return ErrorType::SameKeyPreviouslyMapped;
|
||||
}
|
||||
else if ((GetKeyType(first) == GetKeyType(second)) && GetKeyType(first) != KeyType::Action)
|
||||
{
|
||||
// If the keys are of the same modifier type and overlapping, i.e. one is L/R and other is common
|
||||
if ((first == VK_LWIN && second == VK_RWIN) || (first == VK_LCONTROL && second == VK_RCONTROL) || (first == VK_LMENU && second == VK_RMENU) || (first == VK_LSHIFT && second == VK_RSHIFT))
|
||||
{
|
||||
return ErrorType::NoError;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ErrorType::ConflictingModifierKey;
|
||||
}
|
||||
}
|
||||
// If no overlap
|
||||
else
|
||||
{
|
||||
return ErrorType::NoError;
|
||||
}
|
||||
}
|
||||
|
||||
// Function to return the error message
|
||||
winrt::hstring GetErrorMessage(ErrorType errorType)
|
||||
{
|
||||
switch (errorType)
|
||||
{
|
||||
case ErrorType::NoError:
|
||||
return L"Remapping successful";
|
||||
case ErrorType::SameKeyPreviouslyMapped:
|
||||
return L"Cannot remap a key more than once";
|
||||
case ErrorType::MapToSameKey:
|
||||
return L"Cannot remap a key to itself";
|
||||
case ErrorType::ConflictingModifierKey:
|
||||
return L"Cannot remap this key as it conflicts with another remapped key";
|
||||
case ErrorType::SameShortcutPreviouslyMapped:
|
||||
return L"Cannot remap a shortcut more than once";
|
||||
case ErrorType::MapToSameShortcut:
|
||||
return L"Cannot remap a shortcut to itself";
|
||||
case ErrorType::ConflictingModifierShortcut:
|
||||
return L"Cannot remap this shortcut as it conflicts with another remapped shortcut";
|
||||
case ErrorType::WinL:
|
||||
return L"Cannot remap from/to Win L";
|
||||
case ErrorType::CtrlAltDel:
|
||||
return L"Cannot remap from/to Ctrl Alt Del";
|
||||
case ErrorType::RemapUnsuccessful:
|
||||
return L"Some remappings were not applied";
|
||||
case ErrorType::SaveFailed:
|
||||
return L"Failed to save the remappings";
|
||||
case ErrorType::MissingKey:
|
||||
return L"Incomplete remapping";
|
||||
case ErrorType::ShortcutStartWithModifier:
|
||||
return L"Shortcut must start with a modifier key";
|
||||
case ErrorType::ShortcutCannotHaveRepeatedModifier:
|
||||
return L"Shortcut cannot contain a repeated modifier";
|
||||
case ErrorType::ShortcutAtleast2Keys:
|
||||
return L"Shortcut must have atleast 2 keys";
|
||||
case ErrorType::ShortcutOneActionKey:
|
||||
return L"Shortcut must contain an action key";
|
||||
case ErrorType::ShortcutNotMoreThanOneActionKey:
|
||||
return L"Shortcut cannot have more than one action key";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,28 @@ namespace KeyboardManagerHelper
|
||||
Action
|
||||
};
|
||||
|
||||
// Type to store codes for different errors
|
||||
enum class ErrorType
|
||||
{
|
||||
NoError,
|
||||
SameKeyPreviouslyMapped,
|
||||
MapToSameKey,
|
||||
ConflictingModifierKey,
|
||||
SameShortcutPreviouslyMapped,
|
||||
MapToSameShortcut,
|
||||
ConflictingModifierShortcut,
|
||||
WinL,
|
||||
CtrlAltDel,
|
||||
RemapUnsuccessful,
|
||||
SaveFailed,
|
||||
MissingKey,
|
||||
ShortcutStartWithModifier,
|
||||
ShortcutCannotHaveRepeatedModifier,
|
||||
ShortcutAtleast2Keys,
|
||||
ShortcutOneActionKey,
|
||||
ShortcutNotMoreThanOneActionKey
|
||||
};
|
||||
|
||||
// Function to split a wstring based on a delimiter and return a vector of split strings
|
||||
std::vector<std::wstring> splitwstring(const std::wstring& input, wchar_t delimiter);
|
||||
|
||||
@ -22,7 +44,7 @@ namespace KeyboardManagerHelper
|
||||
winrt::Windows::Foundation::IInspectable getSiblingElement(winrt::Windows::Foundation::IInspectable const& element);
|
||||
|
||||
// Function to return if the key is an extended key which requires the use of the extended key flag
|
||||
bool isExtendedKey(DWORD key);
|
||||
bool IsExtendedKey(DWORD key);
|
||||
|
||||
// Function to check if the key is a modifier key
|
||||
bool IsModifierKey(DWORD key);
|
||||
@ -30,8 +52,11 @@ namespace KeyboardManagerHelper
|
||||
// Function to get the type of the key
|
||||
KeyType GetKeyType(DWORD key);
|
||||
|
||||
// Function to return if the key is an extended key which requires the use of the extended key flag
|
||||
bool isExtendedKey(DWORD key);
|
||||
// Function to check if two keys are equal or cover the same set of keys. Return value depends on type of overlap
|
||||
ErrorType DoKeysOverlap(DWORD first, DWORD second);
|
||||
|
||||
// Function to return the error message
|
||||
winrt::hstring GetErrorMessage(ErrorType errorType);
|
||||
|
||||
// Function to return the list of key name in the order for the drop down based on the key codes
|
||||
winrt::Windows::Foundation::Collections::IVector<winrt::Windows::Foundation::IInspectable> ToBoxValue(const std::vector<std::wstring>& list);
|
||||
|
@ -35,4 +35,7 @@ namespace KeyboardManagerConstants
|
||||
|
||||
// Name of the dummy update file.
|
||||
inline const std::wstring DummyUpdateFileName = L"settings-updated.json";
|
||||
|
||||
// Initial value for tooltip
|
||||
inline const winrt::hstring ToolTipInitialContent = L"Initialised";
|
||||
}
|
@ -764,3 +764,56 @@ int Shortcut::GetCommonModifiersCount(const Shortcut& input) const
|
||||
|
||||
return commonElements;
|
||||
}
|
||||
|
||||
// Function to check if the two shortcuts are equal or cover the same set of keys. Return value depends on type of overlap
|
||||
KeyboardManagerHelper::ErrorType Shortcut::DoKeysOverlap(const Shortcut& first, const Shortcut& second)
|
||||
{
|
||||
if (first.IsValidShortcut() && second.IsValidShortcut())
|
||||
{
|
||||
// If the shortcuts are equal
|
||||
if (first == second)
|
||||
{
|
||||
return KeyboardManagerHelper::ErrorType::SameShortcutPreviouslyMapped;
|
||||
}
|
||||
// If both have win key modifiers and one is the both version then there will be an overlap
|
||||
else if (first.winKey != ModifierKey::Disabled && second.winKey != ModifierKey::Disabled && (first.winKey == ModifierKey::Both || second.winKey == ModifierKey::Both))
|
||||
{
|
||||
return KeyboardManagerHelper::ErrorType::ConflictingModifierShortcut;
|
||||
}
|
||||
// If both have ctrl key modifiers and one is the both version then there will be an overlap
|
||||
else if (first.ctrlKey != ModifierKey::Disabled && second.ctrlKey != ModifierKey::Disabled && (first.ctrlKey == ModifierKey::Both || second.ctrlKey == ModifierKey::Both))
|
||||
{
|
||||
return KeyboardManagerHelper::ErrorType::ConflictingModifierShortcut;
|
||||
}
|
||||
// If both have alt key modifiers and one is the both version then there will be an overlap
|
||||
else if (first.altKey != ModifierKey::Disabled && second.altKey != ModifierKey::Disabled && (first.altKey == ModifierKey::Both || second.altKey == ModifierKey::Both))
|
||||
{
|
||||
return KeyboardManagerHelper::ErrorType::ConflictingModifierShortcut;
|
||||
}
|
||||
// If both have shift key modifiers and one is the both version then there will be an overlap
|
||||
else if (first.shiftKey != ModifierKey::Disabled && second.shiftKey != ModifierKey::Disabled && (first.shiftKey == ModifierKey::Both || second.shiftKey == ModifierKey::Both))
|
||||
{
|
||||
return KeyboardManagerHelper::ErrorType::ConflictingModifierShortcut;
|
||||
}
|
||||
}
|
||||
|
||||
return KeyboardManagerHelper::ErrorType::NoError;
|
||||
}
|
||||
|
||||
// Function to check if the shortcut is illegal (i.e. Win+L or Ctrl+Alt+Del)
|
||||
KeyboardManagerHelper::ErrorType Shortcut::IsShortcutIllegal() const
|
||||
{
|
||||
// Win+L
|
||||
if (winKey != ModifierKey::Disabled && ctrlKey == ModifierKey::Disabled && altKey == ModifierKey::Disabled && shiftKey == ModifierKey::Disabled && actionKey == 0x4C)
|
||||
{
|
||||
return KeyboardManagerHelper::ErrorType::WinL;
|
||||
}
|
||||
|
||||
// Ctrl+Alt+Del
|
||||
if (winKey == ModifierKey::Disabled && ctrlKey != ModifierKey::Disabled && altKey != ModifierKey::Disabled && shiftKey == ModifierKey::Disabled && actionKey == VK_DELETE)
|
||||
{
|
||||
return KeyboardManagerHelper::ErrorType::CtrlAltDel;
|
||||
}
|
||||
|
||||
return KeyboardManagerHelper::ErrorType::NoError;
|
||||
}
|
||||
|
@ -41,6 +41,12 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// == operator
|
||||
inline bool operator==(const Shortcut& sc) const
|
||||
{
|
||||
return (winKey == sc.winKey && ctrlKey == sc.ctrlKey && altKey == sc.altKey && shiftKey == sc.shiftKey && actionKey == sc.actionKey);
|
||||
}
|
||||
|
||||
// Less than operator must be defined to use with std::map.
|
||||
inline bool operator<(const Shortcut& sc) const
|
||||
{
|
||||
@ -168,4 +174,10 @@ public:
|
||||
|
||||
// Function to get the number of modifiers that are common between the current shortcut and the shortcut in the argument
|
||||
int GetCommonModifiersCount(const Shortcut& input) const;
|
||||
|
||||
// Function to check if the two shortcuts are equal or cover the same set of keys. Return value depends on type of overlap
|
||||
static KeyboardManagerHelper::ErrorType DoKeysOverlap(const Shortcut& first, const Shortcut& second);
|
||||
|
||||
// Function to check if the shortcut is illegal (i.e. Win+L or Ctrl+Alt+Del)
|
||||
KeyboardManagerHelper::ErrorType IsShortcutIllegal() const;
|
||||
};
|
||||
|
@ -396,7 +396,7 @@ public:
|
||||
keyEventArray[index].type = inputType;
|
||||
keyEventArray[index].ki.wVk = keyCode;
|
||||
keyEventArray[index].ki.dwFlags = flags;
|
||||
if (KeyboardManagerHelper::isExtendedKey(keyCode))
|
||||
if (KeyboardManagerHelper::IsExtendedKey(keyCode))
|
||||
{
|
||||
keyEventArray[index].ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;
|
||||
}
|
||||
|
@ -73,9 +73,6 @@ void createEditKeyboardWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMan
|
||||
// Update the xaml island window size becuase initially is 0,0
|
||||
SetWindowPos(hWndXamlIslandEditKeyboardWindow, 0, 0, 0, 400, 400, SWP_SHOWWINDOW);
|
||||
|
||||
// Creating the Xaml content. xamlContainer is the parent UI element
|
||||
Windows::UI::Xaml::Controls::StackPanel xamlContainer;
|
||||
|
||||
// Header for the window
|
||||
Windows::UI::Xaml::Controls::RelativePanel header;
|
||||
header.Margin({ 10, 10, 10, 30 });
|
||||
@ -106,12 +103,16 @@ void createEditKeyboardWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMan
|
||||
ColumnDefinition firstColumn;
|
||||
ColumnDefinition secondColumn;
|
||||
ColumnDefinition thirdColumn;
|
||||
thirdColumn.MaxWidth(100);
|
||||
ColumnDefinition fourthColumn;
|
||||
fourthColumn.MaxWidth(100);
|
||||
keyRemapTable.Margin({ 10, 10, 10, 20 });
|
||||
keyRemapTable.HorizontalAlignment(HorizontalAlignment::Stretch);
|
||||
keyRemapTable.ColumnSpacing(10);
|
||||
keyRemapTable.ColumnDefinitions().Append(firstColumn);
|
||||
keyRemapTable.ColumnDefinitions().Append(secondColumn);
|
||||
keyRemapTable.ColumnDefinitions().Append(thirdColumn);
|
||||
keyRemapTable.ColumnDefinitions().Append(fourthColumn);
|
||||
keyRemapTable.RowDefinitions().Append(RowDefinition());
|
||||
|
||||
// First header textblock in the header row of the keys remap table
|
||||
@ -208,7 +209,7 @@ void createEditKeyboardWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMan
|
||||
header.SetLeftOf(cancelButton, applyButton);
|
||||
applyButton.Flyout(applyFlyout);
|
||||
applyButton.Click([&](winrt::Windows::Foundation::IInspectable const& sender, RoutedEventArgs const&) {
|
||||
bool isSuccess = true;
|
||||
KeyboardManagerHelper::ErrorType isSuccess = KeyboardManagerHelper::ErrorType::NoError;
|
||||
// Clear existing Key Remaps
|
||||
keyboardManagerState.ClearSingleKeyRemaps();
|
||||
|
||||
@ -250,30 +251,31 @@ void createEditKeyboardWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMan
|
||||
|
||||
if (!result)
|
||||
{
|
||||
isSuccess = false;
|
||||
isSuccess = KeyboardManagerHelper::ErrorType::RemapUnsuccessful;
|
||||
// Tooltip is already shown for this row
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
isSuccess = false;
|
||||
isSuccess = KeyboardManagerHelper::ErrorType::RemapUnsuccessful;
|
||||
// Show tooltip warning on the problematic row
|
||||
uint32_t warningIndex;
|
||||
// 2 at start, 4 in each row, and last element of each row
|
||||
warningIndex = 1 + (i + 1) * 4;
|
||||
FontIcon warning = keyRemapTable.Children().GetAt(warningIndex).as<FontIcon>();
|
||||
ToolTip t = ToolTipService::GetToolTip(warning).as<ToolTip>();
|
||||
t.Content(box_value(KeyboardManagerHelper::GetErrorMessage(KeyboardManagerHelper::ErrorType::MissingKey)));
|
||||
warning.Visibility(Visibility::Visible);
|
||||
}
|
||||
}
|
||||
|
||||
// Save the updated shortcuts remaps to file.
|
||||
auto saveResult = keyboardManagerState.SaveConfigToFile();
|
||||
|
||||
if (isSuccess && saveResult)
|
||||
bool saveResult = keyboardManagerState.SaveConfigToFile();
|
||||
if (!saveResult)
|
||||
{
|
||||
settingsMessage.Text(L"Remapping successful!");
|
||||
}
|
||||
else if (!isSuccess && saveResult)
|
||||
{
|
||||
settingsMessage.Text(L"All remappings were not successfully applied.");
|
||||
}
|
||||
else
|
||||
{
|
||||
settingsMessage.Text(L"Failed to save the remappings.");
|
||||
isSuccess = KeyboardManagerHelper::ErrorType::SaveFailed;
|
||||
}
|
||||
settingsMessage.Text(KeyboardManagerHelper::GetErrorMessage(isSuccess));
|
||||
});
|
||||
|
||||
header.Children().Append(headerText);
|
||||
@ -286,15 +288,29 @@ void createEditKeyboardWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMan
|
||||
plusSymbol.FontFamily(Xaml::Media::FontFamily(L"Segoe MDL2 Assets"));
|
||||
plusSymbol.Glyph(L"\xE109");
|
||||
addRemapKey.Content(plusSymbol);
|
||||
addRemapKey.Margin({ 10 });
|
||||
addRemapKey.Margin({ 10, 0, 0, 25 });
|
||||
addRemapKey.Click([&](winrt::Windows::Foundation::IInspectable const& sender, RoutedEventArgs const&) {
|
||||
SingleKeyRemapControl::AddNewControlKeyRemapRow(keyRemapTable, keyboardRemapControlObjects);
|
||||
});
|
||||
|
||||
StackPanel mappingsPanel;
|
||||
mappingsPanel.Children().Append(keyRemapInfoHeader);
|
||||
mappingsPanel.Children().Append(keyRemapTable);
|
||||
mappingsPanel.Children().Append(addRemapKey);
|
||||
|
||||
ScrollViewer scrollViewer;
|
||||
scrollViewer.Content(mappingsPanel);
|
||||
|
||||
// Creating the Xaml content. xamlContainer is the parent UI element
|
||||
RelativePanel xamlContainer;
|
||||
xamlContainer.SetBelow(scrollViewer, header);
|
||||
xamlContainer.SetAlignLeftWithPanel(header, true);
|
||||
xamlContainer.SetAlignRightWithPanel(header, true);
|
||||
xamlContainer.SetAlignLeftWithPanel(scrollViewer, true);
|
||||
xamlContainer.SetAlignRightWithPanel(scrollViewer, true);
|
||||
xamlContainer.Children().Append(header);
|
||||
xamlContainer.Children().Append(keyRemapInfoHeader);
|
||||
xamlContainer.Children().Append(keyRemapTable);
|
||||
xamlContainer.Children().Append(addRemapKey);
|
||||
xamlContainer.Children().Append(scrollViewer);
|
||||
|
||||
xamlContainer.UpdateLayout();
|
||||
desktopSource.Content(xamlContainer);
|
||||
|
||||
|
@ -74,9 +74,6 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa
|
||||
// Update the xaml island window size becuase initially is 0,0
|
||||
SetWindowPos(hWndXamlIslandEditShortcutsWindow, 0, 0, 0, 400, 400, SWP_SHOWWINDOW);
|
||||
|
||||
// Creating the Xaml content. xamlContainer is the parent UI element
|
||||
Windows::UI::Xaml::Controls::StackPanel xamlContainer;
|
||||
|
||||
// Header for the window
|
||||
Windows::UI::Xaml::Controls::RelativePanel header;
|
||||
header.Margin({ 10, 10, 10, 30 });
|
||||
@ -102,12 +99,16 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa
|
||||
ColumnDefinition firstColumn;
|
||||
ColumnDefinition secondColumn;
|
||||
ColumnDefinition thirdColumn;
|
||||
thirdColumn.MaxWidth(100);
|
||||
ColumnDefinition fourthColumn;
|
||||
fourthColumn.MaxWidth(100);
|
||||
shortcutTable.Margin({ 10, 10, 10, 20 });
|
||||
shortcutTable.HorizontalAlignment(HorizontalAlignment::Stretch);
|
||||
shortcutTable.ColumnSpacing(10);
|
||||
shortcutTable.ColumnDefinitions().Append(firstColumn);
|
||||
shortcutTable.ColumnDefinitions().Append(secondColumn);
|
||||
shortcutTable.ColumnDefinitions().Append(thirdColumn);
|
||||
shortcutTable.ColumnDefinitions().Append(fourthColumn);
|
||||
shortcutTable.RowDefinitions().Append(RowDefinition());
|
||||
|
||||
// First header textblock in the header row of the shortcut table
|
||||
@ -123,8 +124,8 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa
|
||||
newShortcutHeader.Margin({ 0, 0, 0, 10 });
|
||||
|
||||
shortcutTable.SetColumn(originalShortcutHeader, 0);
|
||||
shortcutTable.SetRow(newShortcutHeader, 0);
|
||||
shortcutTable.SetColumn(originalShortcutHeader, 1);
|
||||
shortcutTable.SetRow(originalShortcutHeader, 0);
|
||||
shortcutTable.SetColumn(newShortcutHeader, 1);
|
||||
shortcutTable.SetRow(newShortcutHeader, 0);
|
||||
|
||||
shortcutTable.Children().Append(originalShortcutHeader);
|
||||
@ -160,7 +161,7 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa
|
||||
header.SetLeftOf(cancelButton, applyButton);
|
||||
applyButton.Flyout(applyFlyout);
|
||||
applyButton.Click([&](winrt::Windows::Foundation::IInspectable const& sender, RoutedEventArgs const&) {
|
||||
bool isSuccess = true;
|
||||
KeyboardManagerHelper::ErrorType isSuccess = KeyboardManagerHelper::ErrorType::NoError;
|
||||
// Clear existing shortcuts
|
||||
keyboardManagerState.ClearOSLevelShortcuts();
|
||||
|
||||
@ -175,30 +176,31 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa
|
||||
bool result = keyboardManagerState.AddOSLevelShortcut(originalShortcut, newShortcut);
|
||||
if (!result)
|
||||
{
|
||||
isSuccess = false;
|
||||
isSuccess = KeyboardManagerHelper::ErrorType::RemapUnsuccessful;
|
||||
// Tooltip is already shown for this row
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
isSuccess = false;
|
||||
isSuccess = KeyboardManagerHelper::ErrorType::RemapUnsuccessful;
|
||||
// Show tooltip warning on the problematic row
|
||||
uint32_t warningIndex;
|
||||
// 2 at start, 4 in each row, and last element of each row
|
||||
warningIndex = 1 + (i + 1) * 4;
|
||||
FontIcon warning = shortcutTable.Children().GetAt(warningIndex).as<FontIcon>();
|
||||
ToolTip t = ToolTipService::GetToolTip(warning).as<ToolTip>();
|
||||
t.Content(box_value(KeyboardManagerHelper::GetErrorMessage(KeyboardManagerHelper::ErrorType::MissingKey)));
|
||||
warning.Visibility(Visibility::Visible);
|
||||
}
|
||||
}
|
||||
|
||||
// Save the updated key remaps to file.
|
||||
auto saveResult = keyboardManagerState.SaveConfigToFile();
|
||||
|
||||
if (isSuccess && saveResult)
|
||||
bool saveResult = keyboardManagerState.SaveConfigToFile();
|
||||
if (!saveResult)
|
||||
{
|
||||
settingsMessage.Text(L"Remapping successful!");
|
||||
}
|
||||
else if (!isSuccess && saveResult)
|
||||
{
|
||||
settingsMessage.Text(L"All remappings were not successfully applied.");
|
||||
}
|
||||
else
|
||||
{
|
||||
settingsMessage.Text(L"Failed to save the remappings.");
|
||||
isSuccess = KeyboardManagerHelper::ErrorType::SaveFailed;
|
||||
}
|
||||
settingsMessage.Text(KeyboardManagerHelper::GetErrorMessage(isSuccess));
|
||||
});
|
||||
|
||||
header.Children().Append(headerText);
|
||||
@ -211,14 +213,27 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa
|
||||
plusSymbol.FontFamily(Xaml::Media::FontFamily(L"Segoe MDL2 Assets"));
|
||||
plusSymbol.Glyph(L"\xE109");
|
||||
addShortcut.Content(plusSymbol);
|
||||
addShortcut.Margin({ 10 });
|
||||
addShortcut.Margin({ 10, 0, 0, 25 });
|
||||
addShortcut.Click([&](winrt::Windows::Foundation::IInspectable const& sender, RoutedEventArgs const&) {
|
||||
ShortcutControl::AddNewShortcutControlRow(shortcutTable, keyboardRemapControlObjects);
|
||||
});
|
||||
|
||||
StackPanel mappingsPanel;
|
||||
mappingsPanel.Children().Append(shortcutTable);
|
||||
mappingsPanel.Children().Append(addShortcut);
|
||||
|
||||
ScrollViewer scrollViewer;
|
||||
scrollViewer.Content(mappingsPanel);
|
||||
|
||||
RelativePanel xamlContainer;
|
||||
xamlContainer.SetBelow(scrollViewer, header);
|
||||
xamlContainer.SetAlignLeftWithPanel(header, true);
|
||||
xamlContainer.SetAlignRightWithPanel(header, true);
|
||||
xamlContainer.SetAlignLeftWithPanel(scrollViewer, true);
|
||||
xamlContainer.SetAlignRightWithPanel(scrollViewer, true);
|
||||
xamlContainer.Children().Append(header);
|
||||
xamlContainer.Children().Append(shortcutTable);
|
||||
xamlContainer.Children().Append(addShortcut);
|
||||
xamlContainer.Children().Append(scrollViewer);
|
||||
|
||||
xamlContainer.UpdateLayout();
|
||||
desktopSource.Content(xamlContainer);
|
||||
|
||||
|
@ -37,8 +37,9 @@ void KeyDropDownControl::CheckAndUpdateKeyboardLayout(ComboBox currentDropDown,
|
||||
}
|
||||
|
||||
// Function to set selection handler for single key remap drop down. Needs to be called after the constructor since the singleKeyControl StackPanel is null if called in the constructor
|
||||
void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel& singleKeyControl, size_t colIndex, std::vector<std::vector<DWORD>>& singleKeyRemapBuffer)
|
||||
void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel& singleKeyControl, int colIndex, std::vector<std::vector<DWORD>>& singleKeyRemapBuffer)
|
||||
{
|
||||
// drop down selection handler
|
||||
dropDown.SelectionChanged([&, table, singleKeyControl, colIndex](winrt::Windows::Foundation::IInspectable const& sender, SelectionChangedEventArgs const& args) {
|
||||
ComboBox currentDropDown = sender.as<ComboBox>();
|
||||
int selectedKeyIndex = currentDropDown.SelectedIndex();
|
||||
@ -47,31 +48,73 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel& singleKeyC
|
||||
bool indexFound = table.Children().IndexOf(singleKeyControl, controlIndex);
|
||||
if (indexFound)
|
||||
{
|
||||
int rowIndex = (controlIndex - 2) / 3;
|
||||
KeyboardManagerHelper::ErrorType errorType = KeyboardManagerHelper::ErrorType::NoError;
|
||||
int rowIndex = (controlIndex - 2) / 4;
|
||||
// Check if the element was not found or the index exceeds the known keys
|
||||
if (selectedKeyIndex != -1 && keyCodeList.size() > selectedKeyIndex)
|
||||
{
|
||||
singleKeyRemapBuffer[rowIndex][colIndex] = keyCodeList[selectedKeyIndex];
|
||||
// Check if the value being set is the same as the other column
|
||||
if (singleKeyRemapBuffer[rowIndex][std::abs(int(colIndex) - 1)] == keyCodeList[selectedKeyIndex])
|
||||
{
|
||||
errorType = KeyboardManagerHelper::ErrorType::MapToSameKey;
|
||||
}
|
||||
|
||||
if (errorType == KeyboardManagerHelper::ErrorType::NoError && colIndex == 0)
|
||||
{
|
||||
// Check if the key is already remapped to something else
|
||||
for (int i = 0; i < singleKeyRemapBuffer.size(); i++)
|
||||
{
|
||||
if (i != rowIndex)
|
||||
{
|
||||
KeyboardManagerHelper::ErrorType result = KeyboardManagerHelper::DoKeysOverlap(singleKeyRemapBuffer[i][0], keyCodeList[selectedKeyIndex]);
|
||||
if (result != KeyboardManagerHelper::ErrorType::NoError)
|
||||
{
|
||||
errorType = result;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there is no error, set the buffer
|
||||
if (errorType == KeyboardManagerHelper::ErrorType::NoError)
|
||||
{
|
||||
singleKeyRemapBuffer[rowIndex][colIndex] = keyCodeList[selectedKeyIndex];
|
||||
}
|
||||
else
|
||||
{
|
||||
singleKeyRemapBuffer[rowIndex][colIndex] = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reset to null if the key is not found
|
||||
singleKeyRemapBuffer[rowIndex][colIndex] = NULL;
|
||||
}
|
||||
|
||||
if (errorType != KeyboardManagerHelper::ErrorType::NoError)
|
||||
{
|
||||
SetDropDownError(currentDropDown, KeyboardManagerHelper::GetErrorMessage(errorType));
|
||||
}
|
||||
|
||||
// If either of the keys are invalid and the tooltip content has been modified after initialization, display the warning
|
||||
if ((singleKeyRemapBuffer[rowIndex][0] == NULL || singleKeyRemapBuffer[rowIndex][1] == NULL) && toolTip.Content().as<winrt::Windows::Foundation::IPropertyValue>().GetString() != KeyboardManagerConstants::ToolTipInitialContent)
|
||||
{
|
||||
warning.Visibility(Visibility::Visible);
|
||||
}
|
||||
else
|
||||
{
|
||||
warning.Visibility(Visibility::Collapsed);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Function to set selection handler for shortcut drop down. Needs to be called after the constructor since the shortcutControl StackPanel is null if called in the constructor
|
||||
void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel& shortcutControl, StackPanel parent, size_t colIndex, std::vector<std::vector<Shortcut>>& shortcutRemapBuffer, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects)
|
||||
void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel& shortcutControl, StackPanel parent, int colIndex, std::vector<std::vector<Shortcut>>& shortcutRemapBuffer, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects)
|
||||
{
|
||||
Flyout warningFlyout;
|
||||
TextBlock warningMessage;
|
||||
warningFlyout.Content(warningMessage);
|
||||
dropDown.ContextFlyout().SetAttachedFlyout((FrameworkElement)dropDown, warningFlyout);
|
||||
|
||||
// drop down selection handler
|
||||
dropDown.SelectionChanged([&, table, shortcutControl, colIndex, parent, warningMessage](winrt::Windows::Foundation::IInspectable const& sender, SelectionChangedEventArgs const&) {
|
||||
dropDown.SelectionChanged([&, table, shortcutControl, colIndex, parent](winrt::Windows::Foundation::IInspectable const& sender, SelectionChangedEventArgs const&) {
|
||||
ComboBox currentDropDown = sender.as<ComboBox>();
|
||||
int selectedKeyIndex = currentDropDown.SelectedIndex();
|
||||
uint32_t dropDownIndex = -1;
|
||||
@ -79,47 +122,48 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel& shortcutCo
|
||||
// Get row index of the single key control
|
||||
uint32_t controlIndex;
|
||||
bool controlIindexFound = table.Children().IndexOf(shortcutControl, controlIndex);
|
||||
KeyboardManagerHelper::ErrorType errorType = KeyboardManagerHelper::ErrorType::NoError;
|
||||
|
||||
if (controlIindexFound)
|
||||
{
|
||||
int rowIndex = (controlIndex - 2) / 3;
|
||||
int rowIndex = (controlIndex - 2) / 4;
|
||||
if (selectedKeyIndex != -1 && keyCodeList.size() > selectedKeyIndex && dropDownFound)
|
||||
{
|
||||
// If only 1 drop down and action key is chosen: Warn that a modifier must be chosen
|
||||
if (parent.Children().Size() == 1 && !KeyboardManagerHelper::IsModifierKey(keyCodeList[selectedKeyIndex]))
|
||||
{
|
||||
// warn and reset the drop down
|
||||
SetDropDownError(currentDropDown, warningMessage, L"Shortcut must start with a modifier key");
|
||||
errorType = KeyboardManagerHelper::ErrorType::ShortcutStartWithModifier;
|
||||
}
|
||||
// If it is the last drop down
|
||||
else if (dropDownIndex == parent.Children().Size() - 1)
|
||||
{
|
||||
// If last drop down and a modifier is selected: add a new drop down (max of 5 drop downs should be enforced)
|
||||
if (KeyboardManagerHelper::IsModifierKey(keyCodeList[selectedKeyIndex]) && parent.Children().Size() < 5)
|
||||
if (KeyboardManagerHelper::IsModifierKey(keyCodeList[selectedKeyIndex]) && parent.Children().Size() < 3)
|
||||
{
|
||||
// If it matched any of the previous modifiers then reset that drop down
|
||||
if (CheckRepeatedModifier(parent, dropDownIndex, selectedKeyIndex, keyCodeList))
|
||||
{
|
||||
// warn and reset the drop down
|
||||
SetDropDownError(currentDropDown, warningMessage, L"Shortcut cannot contain a repeated modifier");
|
||||
errorType = KeyboardManagerHelper::ErrorType::ShortcutCannotHaveRepeatedModifier;
|
||||
}
|
||||
// If not, add a new drop down
|
||||
else
|
||||
{
|
||||
AddDropDown(table, shortcutControl, parent, colIndex, shortcutRemapBuffer, keyDropDownControlObjects);
|
||||
AddDropDown(table, shortcutControl, parent, colIndex, shortcutRemapBuffer, keyDropDownControlObjects, warning, toolTip);
|
||||
}
|
||||
}
|
||||
// If last drop down and a modifier is selected but there are already 5 drop downs: warn the user
|
||||
else if (KeyboardManagerHelper::IsModifierKey(keyCodeList[selectedKeyIndex]) && parent.Children().Size() >= 5)
|
||||
else if (KeyboardManagerHelper::IsModifierKey(keyCodeList[selectedKeyIndex]) && parent.Children().Size() >= 3)
|
||||
{
|
||||
// warn and reset the drop down
|
||||
SetDropDownError(currentDropDown, warningMessage, L"Shortcut must contain an action key");
|
||||
errorType = KeyboardManagerHelper::ErrorType::ShortcutOneActionKey;
|
||||
}
|
||||
// If None is selected but it's the last index: warn
|
||||
else if (keyCodeList[selectedKeyIndex] == 0)
|
||||
{
|
||||
// warn and reset the drop down
|
||||
SetDropDownError(currentDropDown, warningMessage, L"Shortcut must contain an action key");
|
||||
errorType = KeyboardManagerHelper::ErrorType::ShortcutOneActionKey;
|
||||
}
|
||||
// If none of the above, then the action key will be set
|
||||
}
|
||||
@ -132,7 +176,7 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel& shortcutCo
|
||||
if (CheckRepeatedModifier(parent, dropDownIndex, selectedKeyIndex, keyCodeList))
|
||||
{
|
||||
// warn and reset the drop down
|
||||
SetDropDownError(currentDropDown, warningMessage, L"Shortcut cannot contain a repeated modifier");
|
||||
errorType = KeyboardManagerHelper::ErrorType::ShortcutCannotHaveRepeatedModifier;
|
||||
}
|
||||
// If not, the modifier key will be set
|
||||
}
|
||||
@ -148,7 +192,7 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel& shortcutCo
|
||||
else if (keyCodeList[selectedKeyIndex] == 0 && parent.Children().Size() <= 2)
|
||||
{
|
||||
// warn and reset the drop down
|
||||
SetDropDownError(currentDropDown, warningMessage, L"Shortcut must have atleast 2 keys");
|
||||
errorType = KeyboardManagerHelper::ErrorType::ShortcutAtleast2Keys;
|
||||
}
|
||||
// If the user tries to set an action key check if all drop down menus after this are empty if it is not the first key
|
||||
else if (dropDownIndex != 0)
|
||||
@ -156,8 +200,8 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel& shortcutCo
|
||||
bool isClear = true;
|
||||
for (int i = dropDownIndex + 1; i < (int)parent.Children().Size(); i++)
|
||||
{
|
||||
ComboBox currentDropDown = parent.Children().GetAt(i).as<ComboBox>();
|
||||
if (currentDropDown.SelectedIndex() != -1)
|
||||
ComboBox ItDropDown = parent.Children().GetAt(i).as<ComboBox>();
|
||||
if (ItDropDown.SelectedIndex() != -1)
|
||||
{
|
||||
isClear = false;
|
||||
break;
|
||||
@ -178,20 +222,68 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel& shortcutCo
|
||||
else
|
||||
{
|
||||
// warn and reset the drop down
|
||||
SetDropDownError(currentDropDown, warningMessage, L"Shortcut cannot have more than one action key");
|
||||
errorType = KeyboardManagerHelper::ErrorType::ShortcutNotMoreThanOneActionKey;
|
||||
}
|
||||
}
|
||||
// If there an action key is chosen on the first drop down and there are more than one drop down menus
|
||||
else
|
||||
{
|
||||
// warn and reset the drop down
|
||||
SetDropDownError(currentDropDown, warningMessage, L"Shortcut must start with a modifier key");
|
||||
errorType = KeyboardManagerHelper::ErrorType::ShortcutStartWithModifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// After validating the shortcut, now for errors like remap to same shortcut, remap shortcut more than once, Win L and Ctrl Alt Del
|
||||
if (errorType == KeyboardManagerHelper::ErrorType::NoError)
|
||||
{
|
||||
Shortcut tempShortcut;
|
||||
tempShortcut.SetKeyCodes(GetKeysFromStackPanel(parent));
|
||||
// Check if the value being set is the same as the other column
|
||||
if (shortcutRemapBuffer[rowIndex][std::abs(int(colIndex) - 1)] == tempShortcut)
|
||||
{
|
||||
errorType = KeyboardManagerHelper::ErrorType::MapToSameShortcut;
|
||||
}
|
||||
|
||||
if (errorType == KeyboardManagerHelper::ErrorType::NoError && colIndex == 0)
|
||||
{
|
||||
// Check if the key is already remapped to something else
|
||||
for (int i = 0; i < shortcutRemapBuffer.size(); i++)
|
||||
{
|
||||
if (i != rowIndex)
|
||||
{
|
||||
KeyboardManagerHelper::ErrorType result = Shortcut::DoKeysOverlap(shortcutRemapBuffer[i][0], tempShortcut);
|
||||
if (result != KeyboardManagerHelper::ErrorType::NoError)
|
||||
{
|
||||
errorType = result;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (errorType == KeyboardManagerHelper::ErrorType::NoError)
|
||||
{
|
||||
errorType = tempShortcut.IsShortcutIllegal();
|
||||
}
|
||||
}
|
||||
|
||||
if (errorType != KeyboardManagerHelper::ErrorType::NoError)
|
||||
{
|
||||
SetDropDownError(currentDropDown, KeyboardManagerHelper::GetErrorMessage(errorType));
|
||||
}
|
||||
// Reset the buffer based on the new selected drop down items
|
||||
shortcutRemapBuffer[rowIndex][colIndex].SetKeyCodes(GetKeysFromStackPanel(parent));
|
||||
|
||||
// If either of the shortcuts are invalid and the tooltip content has been modified after initialization, display the warning
|
||||
if ((!shortcutRemapBuffer[rowIndex][0].IsValidShortcut() || !shortcutRemapBuffer[rowIndex][1].IsValidShortcut()) && toolTip.Content().as<winrt::Windows::Foundation::IPropertyValue>().GetString() != KeyboardManagerConstants::ToolTipInitialContent)
|
||||
{
|
||||
warning.Visibility(Visibility::Visible);
|
||||
}
|
||||
else
|
||||
{
|
||||
warning.Visibility(Visibility::Collapsed);
|
||||
}
|
||||
}
|
||||
|
||||
// If the user searches for a key the selection handler gets invoked however if they click away it reverts back to the previous state. This can result in dangling references to added drop downs which were then reset.
|
||||
@ -221,13 +313,9 @@ ComboBox KeyDropDownControl::GetComboBox()
|
||||
}
|
||||
|
||||
// Function to add a drop down to the shortcut stack panel
|
||||
void KeyDropDownControl::AddDropDown(Grid table, StackPanel shortcutControl, StackPanel parent, const size_t colIndex, std::vector<std::vector<Shortcut>>& shortcutRemapBuffer, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects)
|
||||
void KeyDropDownControl::AddDropDown(Grid table, StackPanel shortcutControl, StackPanel parent, const int colIndex, std::vector<std::vector<Shortcut>>& shortcutRemapBuffer, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, FontIcon warning, ToolTip toolTip)
|
||||
{
|
||||
keyDropDownControlObjects.push_back(std::move(std::unique_ptr<KeyDropDownControl>(new KeyDropDownControl(true))));
|
||||
// Flyout to display the warning on the drop down element
|
||||
Flyout warningFlyout;
|
||||
TextBlock warningMessage;
|
||||
warningFlyout.Content(warningMessage);
|
||||
keyDropDownControlObjects.push_back(std::move(std::unique_ptr<KeyDropDownControl>(new KeyDropDownControl(true, warning, toolTip))));
|
||||
parent.Children().Append(keyDropDownControlObjects[keyDropDownControlObjects.size() - 1]->GetComboBox());
|
||||
keyDropDownControlObjects[keyDropDownControlObjects.size() - 1]->SetSelectionHandler(table, shortcutControl, parent, colIndex, shortcutRemapBuffer, keyDropDownControlObjects);
|
||||
parent.UpdateLayout();
|
||||
@ -278,10 +366,9 @@ bool KeyDropDownControl::CheckRepeatedModifier(StackPanel parent, uint32_t dropD
|
||||
return matchPreviousModifier;
|
||||
}
|
||||
|
||||
// Function to set the flyout warning message
|
||||
void KeyDropDownControl::SetDropDownError(ComboBox dropDown, TextBlock messageBlock, hstring message)
|
||||
// Function to set the warning message
|
||||
void KeyDropDownControl::SetDropDownError(ComboBox currentDropDown, hstring message)
|
||||
{
|
||||
messageBlock.Text(message);
|
||||
dropDown.ContextFlyout().ShowAttachedFlyout((FrameworkElement)dropDown);
|
||||
dropDown.SelectedIndex(-1);
|
||||
currentDropDown.SelectedIndex(-1);
|
||||
toolTip.Content(box_value(message));
|
||||
}
|
||||
|
@ -11,6 +11,10 @@ private:
|
||||
HKL previousLayout = 0;
|
||||
// Stores the key code list
|
||||
std::vector<DWORD> keyCodeList;
|
||||
// Stores the warning control
|
||||
FontIcon warning;
|
||||
// Stores the tooltip for the warning control
|
||||
ToolTip toolTip;
|
||||
|
||||
// Function to set properties apart from the SelectionChanged event handler
|
||||
void SetDefaultProperties(bool isShortcut);
|
||||
@ -22,17 +26,18 @@ public:
|
||||
// Pointer to the keyboard manager state
|
||||
static KeyboardManagerState* keyboardManagerState;
|
||||
|
||||
// Constructor for single key drop down
|
||||
KeyDropDownControl(bool isShortcut)
|
||||
// Constructor
|
||||
KeyDropDownControl(bool isShortcut, FontIcon warning, ToolTip toolTip) :
|
||||
warning(warning), toolTip(toolTip)
|
||||
{
|
||||
SetDefaultProperties(isShortcut);
|
||||
}
|
||||
|
||||
// Function to set selection handler for single key remap drop down. Needs to be called after the constructor since the singleKeyControl StackPanel is null if called in the constructor
|
||||
void SetSelectionHandler(Grid& table, StackPanel& singleKeyControl, size_t colIndex, std::vector<std::vector<DWORD>>& singleKeyRemapBuffer);
|
||||
void SetSelectionHandler(Grid& table, StackPanel& singleKeyControl, int colIndex, std::vector<std::vector<DWORD>>& singleKeyRemapBuffer);
|
||||
|
||||
// Function to set selection handler for shortcut drop down. Needs to be called after the constructor since the shortcutControl StackPanel is null if called in the constructor
|
||||
void SetSelectionHandler(Grid& table, StackPanel& shortcutControl, StackPanel parent, size_t colIndex, std::vector<std::vector<Shortcut>>& shortcutRemapBuffer, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects);
|
||||
void SetSelectionHandler(Grid& table, StackPanel& shortcutControl, StackPanel parent, int colIndex, std::vector<std::vector<Shortcut>>& shortcutRemapBuffer, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects);
|
||||
|
||||
// Function to set the selected index of the drop down
|
||||
void SetSelectedIndex(int32_t index);
|
||||
@ -41,7 +46,7 @@ public:
|
||||
ComboBox GetComboBox();
|
||||
|
||||
// Function to add a drop down to the shortcut stack panel
|
||||
static void AddDropDown(Grid table, StackPanel shortcutControl, StackPanel parent, const size_t colIndex, std::vector<std::vector<Shortcut>>& shortcutRemapBuffer, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects);
|
||||
static void AddDropDown(Grid table, StackPanel shortcutControl, StackPanel parent, const int colIndex, std::vector<std::vector<Shortcut>>& shortcutRemapBuffer, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, FontIcon warning, ToolTip toolTip);
|
||||
|
||||
// Function to get the list of key codes from the shortcut combo box stack panel
|
||||
std::vector<DWORD> GetKeysFromStackPanel(StackPanel parent);
|
||||
@ -49,6 +54,6 @@ public:
|
||||
// Function to check if a modifier has been repeated in the previous drop downs
|
||||
bool CheckRepeatedModifier(StackPanel parent, uint32_t dropDownIndex, int selectedKeyIndex, const std::vector<DWORD>& keyCodeList);
|
||||
|
||||
// Function to set the flyout warning message
|
||||
void SetDropDownError(ComboBox dropDown, TextBlock messageBlock, hstring message);
|
||||
// Function to set the warning message
|
||||
void SetDropDownError(ComboBox currentDropDown, hstring message);
|
||||
};
|
||||
|
@ -11,10 +11,16 @@ std::vector<std::vector<Shortcut>> ShortcutControl::shortcutRemapBuffer;
|
||||
// Function to add a new row to the shortcut table. If the originalKeys and newKeys args are provided, then the displayed shortcuts are set to those values.
|
||||
void ShortcutControl::AddNewShortcutControlRow(Grid& parent, std::vector<std::vector<std::unique_ptr<ShortcutControl>>>& keyboardRemapControlObjects, Shortcut originalKeys, Shortcut newKeys)
|
||||
{
|
||||
// Warning icon for the row
|
||||
ToolTip warningMessage;
|
||||
FontIcon warningIcon;
|
||||
warningIcon.Visibility(Visibility::Collapsed);
|
||||
warningMessage.Content(box_value(KeyboardManagerConstants::ToolTipInitialContent));
|
||||
|
||||
// Create new ShortcutControl objects dynamically so that we does not get destructed
|
||||
std::vector<std::unique_ptr<ShortcutControl>> newrow;
|
||||
newrow.push_back(std::move(std::unique_ptr<ShortcutControl>(new ShortcutControl(parent, 0))));
|
||||
newrow.push_back(std::move(std::unique_ptr<ShortcutControl>(new ShortcutControl(parent, 1))));
|
||||
newrow.push_back(std::move(std::unique_ptr<ShortcutControl>(new ShortcutControl(parent, 0, warningIcon, warningMessage))));
|
||||
newrow.push_back(std::move(std::unique_ptr<ShortcutControl>(new ShortcutControl(parent, 1, warningIcon, warningMessage))));
|
||||
keyboardRemapControlObjects.push_back(std::move(newrow));
|
||||
|
||||
// Add to grid
|
||||
@ -40,18 +46,20 @@ void ShortcutControl::AddNewShortcutControlRow(Grid& parent, std::vector<std::ve
|
||||
// Get index of delete button
|
||||
UIElementCollection children = parent.Children();
|
||||
children.IndexOf(currentButton, index);
|
||||
uint32_t lastIndexInRow = index + 1;
|
||||
// Change the row index of elements appearing after the current row, as we will delete the row definition
|
||||
for (uint32_t i = index + 1; i < children.Size(); i++)
|
||||
for (uint32_t i = lastIndexInRow + 1; i < children.Size(); i++)
|
||||
{
|
||||
int32_t elementRowIndex = parent.GetRow(children.GetAt(i).as<FrameworkElement>());
|
||||
parent.SetRow(children.GetAt(i).as<FrameworkElement>(), elementRowIndex - 1);
|
||||
}
|
||||
parent.Children().RemoveAt(index);
|
||||
parent.Children().RemoveAt(index - 1);
|
||||
parent.Children().RemoveAt(index - 2);
|
||||
parent.Children().RemoveAt(lastIndexInRow);
|
||||
parent.Children().RemoveAt(lastIndexInRow - 1);
|
||||
parent.Children().RemoveAt(lastIndexInRow - 2);
|
||||
parent.Children().RemoveAt(lastIndexInRow - 3);
|
||||
|
||||
// Calculate row index in the buffer from the grid child index (first two children are header elements and then three children in each row)
|
||||
int bufferIndex = (index - 2) / 3;
|
||||
int bufferIndex = (lastIndexInRow - 2) / 4;
|
||||
// Delete the row definition
|
||||
parent.RowDefinitions().RemoveAt(bufferIndex + 1);
|
||||
// delete the row from the buffer
|
||||
@ -62,14 +70,22 @@ void ShortcutControl::AddNewShortcutControlRow(Grid& parent, std::vector<std::ve
|
||||
parent.SetColumn(deleteShortcut, 2);
|
||||
parent.SetRow(deleteShortcut, parent.RowDefinitions().Size() - 1);
|
||||
parent.Children().Append(deleteShortcut);
|
||||
|
||||
warningIcon.FontFamily(Xaml::Media::FontFamily(L"Segoe MDL2 Assets"));
|
||||
warningIcon.Glyph(L"\xE783");
|
||||
warningIcon.HorizontalAlignment(HorizontalAlignment::Left);
|
||||
ToolTipService::SetToolTip(warningIcon, warningMessage);
|
||||
parent.SetColumn(warningIcon, 3);
|
||||
parent.SetRow(warningIcon, parent.RowDefinitions().Size() - 1);
|
||||
parent.Children().Append(warningIcon);
|
||||
parent.UpdateLayout();
|
||||
|
||||
// Set the shortcut text if the two vectors are not empty (i.e. default args)
|
||||
if (originalKeys.IsValidShortcut() && newKeys.IsValidShortcut())
|
||||
{
|
||||
shortcutRemapBuffer.push_back(std::vector<Shortcut>{ Shortcut(), Shortcut() });
|
||||
keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][0]->AddShortcutToControl(originalKeys, parent, keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][0]->shortcutDropDownStackPanel, *keyboardManagerState, 0);
|
||||
keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->AddShortcutToControl(newKeys, parent, keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->shortcutDropDownStackPanel, *keyboardManagerState, 1);
|
||||
keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][0]->AddShortcutToControl(originalKeys, parent, keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][0]->shortcutDropDownStackPanel, *keyboardManagerState, 0, warningIcon, warningMessage);
|
||||
keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->AddShortcutToControl(newKeys, parent, keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->shortcutDropDownStackPanel, *keyboardManagerState, 1, warningIcon, warningMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -79,7 +95,7 @@ void ShortcutControl::AddNewShortcutControlRow(Grid& parent, std::vector<std::ve
|
||||
}
|
||||
|
||||
// Function to add a shortcut to the shortcut control as combo boxes
|
||||
void ShortcutControl::AddShortcutToControl(Shortcut& shortcut, Grid table, StackPanel parent, KeyboardManagerState& keyboardManagerState, const size_t colIndex)
|
||||
void ShortcutControl::AddShortcutToControl(Shortcut& shortcut, Grid table, StackPanel parent, KeyboardManagerState& keyboardManagerState, const int colIndex, FontIcon warning, ToolTip toolTip)
|
||||
{
|
||||
// Delete the existing drop down menus
|
||||
parent.Children().Clear();
|
||||
@ -90,7 +106,7 @@ void ShortcutControl::AddShortcutToControl(Shortcut& shortcut, Grid table, Stack
|
||||
std::vector<DWORD> keyCodeList = keyboardManagerState.keyboardMap.GetKeyCodeList(true);
|
||||
if (shortcutKeyCodes.size() != 0)
|
||||
{
|
||||
KeyDropDownControl::AddDropDown(table, shortcutControlLayout, parent, colIndex, shortcutRemapBuffer, keyDropDownControlObjects);
|
||||
KeyDropDownControl::AddDropDown(table, shortcutControlLayout, parent, colIndex, shortcutRemapBuffer, keyDropDownControlObjects, warning, toolTip);
|
||||
for (int i = 0; i < shortcutKeyCodes.size(); i++)
|
||||
{
|
||||
// New drop down gets added automatically when the SelectedIndex is set
|
||||
@ -115,7 +131,7 @@ StackPanel ShortcutControl::getShortcutControl()
|
||||
}
|
||||
|
||||
// Function to create the detect shortcut UI window
|
||||
void ShortcutControl::createDetectShortcutWindow(winrt::Windows::Foundation::IInspectable const& sender, XamlRoot xamlRoot, std::vector<std::vector<Shortcut>>& shortcutRemapBuffer, KeyboardManagerState& keyboardManagerState, const size_t colIndex, Grid table)
|
||||
void ShortcutControl::createDetectShortcutWindow(winrt::Windows::Foundation::IInspectable const& sender, XamlRoot xamlRoot, std::vector<std::vector<Shortcut>>& shortcutRemapBuffer, KeyboardManagerState& keyboardManagerState, const int colIndex, Grid table, FontIcon warning, ToolTip toolTip)
|
||||
{
|
||||
// ContentDialog for detecting shortcuts. This is the parent UI element.
|
||||
ContentDialog detectShortcutBox;
|
||||
@ -148,14 +164,16 @@ void ShortcutControl::createDetectShortcutWindow(winrt::Windows::Foundation::IIn
|
||||
&shortcutRemapBuffer,
|
||||
unregisterKeys,
|
||||
colIndex,
|
||||
table] {
|
||||
table,
|
||||
warning,
|
||||
toolTip] {
|
||||
// Save the detected shortcut in the linked text block
|
||||
Shortcut detectedShortcutKeys = keyboardManagerState.GetDetectedShortcut();
|
||||
|
||||
if (!detectedShortcutKeys.IsEmpty())
|
||||
{
|
||||
// The shortcut buffer gets set in this function
|
||||
AddShortcutToControl(detectedShortcutKeys, table, linkedShortcutStackPanel, keyboardManagerState, colIndex);
|
||||
AddShortcutToControl(detectedShortcutKeys, table, linkedShortcutStackPanel, keyboardManagerState, colIndex, warning, toolTip);
|
||||
}
|
||||
|
||||
// Reset the keyboard manager UI state
|
||||
|
@ -29,16 +29,16 @@ public:
|
||||
// Vector to store dynamically allocated KeyDropDownControl objects to avoid early destruction
|
||||
std::vector<std::unique_ptr<KeyDropDownControl>> keyDropDownControlObjects;
|
||||
|
||||
ShortcutControl(Grid table, const size_t colIndex)
|
||||
ShortcutControl(Grid table, const int colIndex, FontIcon warning, ToolTip toolTip)
|
||||
{
|
||||
shortcutDropDownStackPanel.Spacing(10);
|
||||
shortcutDropDownStackPanel.Orientation(Windows::UI::Xaml::Controls::Orientation::Horizontal);
|
||||
|
||||
typeShortcut.Content(winrt::box_value(L"Type Shortcut"));
|
||||
typeShortcut.Click([&, table, colIndex](winrt::Windows::Foundation::IInspectable const& sender, RoutedEventArgs const&) {
|
||||
typeShortcut.Click([&, table, colIndex, warning, toolTip](winrt::Windows::Foundation::IInspectable const& sender, RoutedEventArgs const&) {
|
||||
keyboardManagerState->SetUIState(KeyboardManagerUIState::DetectShortcutWindowActivated, EditShortcutsWindowHandle);
|
||||
// Using the XamlRoot of the typeShortcut to get the root of the XAML host
|
||||
createDetectShortcutWindow(sender, sender.as<Button>().XamlRoot(), shortcutRemapBuffer, *keyboardManagerState, colIndex, table);
|
||||
createDetectShortcutWindow(sender, sender.as<Button>().XamlRoot(), shortcutRemapBuffer, *keyboardManagerState, colIndex, table, warning, toolTip);
|
||||
});
|
||||
|
||||
shortcutControlLayout.Margin({ 0, 0, 0, 10 });
|
||||
@ -46,7 +46,7 @@ public:
|
||||
|
||||
shortcutControlLayout.Children().Append(typeShortcut);
|
||||
shortcutControlLayout.Children().Append(shortcutDropDownStackPanel);
|
||||
KeyDropDownControl::AddDropDown(table, shortcutControlLayout, shortcutDropDownStackPanel, colIndex, shortcutRemapBuffer, keyDropDownControlObjects);
|
||||
KeyDropDownControl::AddDropDown(table, shortcutControlLayout, shortcutDropDownStackPanel, colIndex, shortcutRemapBuffer, keyDropDownControlObjects, warning, toolTip);
|
||||
shortcutControlLayout.UpdateLayout();
|
||||
}
|
||||
|
||||
@ -54,11 +54,11 @@ public:
|
||||
static void AddNewShortcutControlRow(Grid& parent, std::vector<std::vector<std::unique_ptr<ShortcutControl>>>& keyboardRemapControlObjects, Shortcut originalKeys = Shortcut(), Shortcut newKeys = Shortcut());
|
||||
|
||||
// Function to add a shortcut to the shortcut control as combo boxes
|
||||
void AddShortcutToControl(Shortcut& shortcut, Grid table, StackPanel parent, KeyboardManagerState& keyboardManagerState, const size_t colIndex);
|
||||
void AddShortcutToControl(Shortcut& shortcut, Grid table, StackPanel parent, KeyboardManagerState& keyboardManagerState, const int colIndex, FontIcon warning, ToolTip toolTip);
|
||||
|
||||
// Function to return the stack panel element of the ShortcutControl. This is the externally visible UI element which can be used to add it to other layouts
|
||||
StackPanel getShortcutControl();
|
||||
|
||||
// Function to create the detect shortcut UI window
|
||||
void createDetectShortcutWindow(winrt::Windows::Foundation::IInspectable const& sender, XamlRoot xamlRoot, std::vector<std::vector<Shortcut>>& shortcutRemapBuffer, KeyboardManagerState& keyboardManagerState, const size_t colIndex, Grid table);
|
||||
void createDetectShortcutWindow(winrt::Windows::Foundation::IInspectable const& sender, XamlRoot xamlRoot, std::vector<std::vector<Shortcut>>& shortcutRemapBuffer, KeyboardManagerState& keyboardManagerState, const int colIndex, Grid table, FontIcon warning, ToolTip toolTip);
|
||||
};
|
||||
|
@ -11,10 +11,16 @@ std::vector<std::vector<DWORD>> SingleKeyRemapControl::singleKeyRemapBuffer;
|
||||
// Function to add a new row to the remap keys table. If the originalKey and newKey args are provided, then the displayed remap keys are set to those values.
|
||||
void SingleKeyRemapControl::AddNewControlKeyRemapRow(Grid& parent, std::vector<std::vector<std::unique_ptr<SingleKeyRemapControl>>>& keyboardRemapControlObjects, const DWORD originalKey, const DWORD newKey)
|
||||
{
|
||||
// Warning icon for the row
|
||||
ToolTip warningMessage;
|
||||
FontIcon warningIcon;
|
||||
warningIcon.Visibility(Visibility::Collapsed);
|
||||
warningMessage.Content(box_value(KeyboardManagerConstants::ToolTipInitialContent));
|
||||
|
||||
// Create new SingleKeyRemapControl objects dynamically so that we does not get destructed
|
||||
std::vector<std::unique_ptr<SingleKeyRemapControl>> newrow;
|
||||
newrow.push_back(std::move(std::unique_ptr<SingleKeyRemapControl>(new SingleKeyRemapControl(parent, 0))));
|
||||
newrow.push_back(std::move(std::unique_ptr<SingleKeyRemapControl>(new SingleKeyRemapControl(parent, 1))));
|
||||
newrow.push_back(std::move(std::unique_ptr<SingleKeyRemapControl>(new SingleKeyRemapControl(parent, 0, warningIcon, warningMessage))));
|
||||
newrow.push_back(std::move(std::unique_ptr<SingleKeyRemapControl>(new SingleKeyRemapControl(parent, 1, warningIcon, warningMessage))));
|
||||
keyboardRemapControlObjects.push_back(std::move(newrow));
|
||||
|
||||
// Add to grid
|
||||
@ -63,18 +69,20 @@ void SingleKeyRemapControl::AddNewControlKeyRemapRow(Grid& parent, std::vector<s
|
||||
// Get index of delete button
|
||||
UIElementCollection children = parent.Children();
|
||||
children.IndexOf(currentButton, index);
|
||||
uint32_t lastIndexInRow = index + 1;
|
||||
// Change the row index of elements appearing after the current row, as we will delete the row definition
|
||||
for (uint32_t i = index + 1; i < children.Size(); i++)
|
||||
for (uint32_t i = lastIndexInRow + 1; i < children.Size(); i++)
|
||||
{
|
||||
int32_t elementRowIndex = parent.GetRow(children.GetAt(i).as<FrameworkElement>());
|
||||
parent.SetRow(children.GetAt(i).as<FrameworkElement>(), elementRowIndex - 1);
|
||||
}
|
||||
parent.Children().RemoveAt(index);
|
||||
parent.Children().RemoveAt(index - 1);
|
||||
parent.Children().RemoveAt(index - 2);
|
||||
parent.Children().RemoveAt(lastIndexInRow);
|
||||
parent.Children().RemoveAt(lastIndexInRow - 1);
|
||||
parent.Children().RemoveAt(lastIndexInRow - 2);
|
||||
parent.Children().RemoveAt(lastIndexInRow - 3);
|
||||
|
||||
// Calculate row index in the buffer from the grid child index (first two children are header elements and then three children in each row)
|
||||
int bufferIndex = (index - 2) / 3;
|
||||
int bufferIndex = (lastIndexInRow - 2) / 4;
|
||||
// Delete the row definition
|
||||
parent.RowDefinitions().RemoveAt(bufferIndex + 1);
|
||||
// delete the row from the buffer.
|
||||
@ -85,6 +93,15 @@ void SingleKeyRemapControl::AddNewControlKeyRemapRow(Grid& parent, std::vector<s
|
||||
parent.SetColumn(deleteRemapKeys, 2);
|
||||
parent.SetRow(deleteRemapKeys, parent.RowDefinitions().Size() - 1);
|
||||
parent.Children().Append(deleteRemapKeys);
|
||||
|
||||
warningIcon.FontFamily(Xaml::Media::FontFamily(L"Segoe MDL2 Assets"));
|
||||
warningIcon.Glyph(L"\xE783");
|
||||
warningIcon.HorizontalAlignment(HorizontalAlignment::Left);
|
||||
ToolTipService::SetToolTip(warningIcon, warningMessage);
|
||||
parent.SetColumn(warningIcon, 3);
|
||||
parent.SetRow(warningIcon, parent.RowDefinitions().Size() - 1);
|
||||
parent.Children().Append(warningIcon);
|
||||
parent.UpdateLayout();
|
||||
}
|
||||
|
||||
// Function to return the stack panel element of the SingleKeyRemapControl. This is the externally visible UI element which can be used to add it to other layouts
|
||||
|
@ -22,8 +22,8 @@ public:
|
||||
// Stores the current list of remappings
|
||||
static std::vector<std::vector<DWORD>> singleKeyRemapBuffer;
|
||||
|
||||
SingleKeyRemapControl(Grid table, const size_t colIndex) :
|
||||
singleKeyRemapDropDown(false)
|
||||
SingleKeyRemapControl(Grid table, const int colIndex, FontIcon warning, ToolTip toolTip) :
|
||||
singleKeyRemapDropDown(false, warning, toolTip)
|
||||
{
|
||||
typeKey.Content(winrt::box_value(L"Type Key"));
|
||||
typeKey.Click([&](winrt::Windows::Foundation::IInspectable const& sender, RoutedEventArgs const&) {
|
||||
|
@ -67,12 +67,13 @@ json::JsonObject load_general_settings()
|
||||
|
||||
GeneralSettings get_general_settings()
|
||||
{
|
||||
const bool is_user_admin = check_user_is_admin();
|
||||
GeneralSettings settings{
|
||||
.isPackaged = winstore::running_as_packaged(),
|
||||
.isElevated = is_process_elevated(),
|
||||
.isRunElevated = run_as_elevated,
|
||||
.isAdmin = check_user_is_admin(),
|
||||
.downloadUpdatesAutomatically = download_updates_automatically,
|
||||
.isAdmin = is_user_admin,
|
||||
.downloadUpdatesAutomatically = download_updates_automatically && is_user_admin,
|
||||
.theme = settings_theme,
|
||||
.systemTheme = WindowsColors::is_dark_mode() ? L"dark" : L"light",
|
||||
.powerToysVersion = get_product_version()
|
||||
|
@ -222,7 +222,7 @@ void run_settings_window()
|
||||
|
||||
// Arg 1: executable path.
|
||||
std::wstring executable_path = get_module_folderpath();
|
||||
executable_path.append(L"\\netcoreapp3.1\\Microsoft.PowerToys.Settings.UI.Runner.exe");
|
||||
executable_path.append(L"\\SettingsUIRunner\\Microsoft.PowerToys.Settings.UI.Runner.exe");
|
||||
|
||||
// Arg 2: pipe server. Generate unique names for the pipes, if getting a UUID is possible.
|
||||
std::wstring powertoys_pipe_name(L"\\\\.\\pipe\\powertoys_runner_");
|
||||
|
@ -44,7 +44,7 @@ export class GeneralSettings extends React.Component <any, any> {
|
||||
});
|
||||
let result : any = {};
|
||||
result[this.state.settings_key]= {
|
||||
download_updates_automatically: this.download_updates_automatically_reference.get_value().value,
|
||||
download_updates_automatically: this.download_updates_automatically_reference != null && this.download_updates_automatically_reference.get_value().value,
|
||||
startup: this.startup_reference.get_value().value,
|
||||
run_elevated: this.elevated_reference != null && this.elevated_reference.get_value().value,
|
||||
theme: this.theme_reference.get_value().value,
|
||||
@ -125,14 +125,16 @@ export class GeneralSettings extends React.Component <any, any> {
|
||||
<Separator />
|
||||
<Text variant='xLarge'>General</Text>
|
||||
|
||||
<Stack>
|
||||
{this.state.settings.general.is_admin &&
|
||||
(<Stack>
|
||||
<Label>Download updates automatically</Label>
|
||||
<BoolToggleSettingsControl
|
||||
setting={{value: this.state.settings.general.download_updates_automatically}}
|
||||
disabled={!this.state.settings.general.is_admin}
|
||||
on_change={this.parent_on_change}
|
||||
ref={(input) => {this.download_updates_automatically_reference=input;}}
|
||||
/>
|
||||
</Stack>
|
||||
</Stack>)}
|
||||
|
||||
|
||||
<Stack>
|
||||
|
@ -129,6 +129,7 @@ void send_message_to_powertoys_runner(const std::wstring& msg)
|
||||
{
|
||||
if (g_message_pipe != nullptr)
|
||||
{
|
||||
MessageBox(g_main_wnd, msg.c_str(), L"From Webview", MB_OK);
|
||||
g_message_pipe->send(msg);
|
||||
}
|
||||
else
|
||||
|
2
src/settings/settings-html/dist/bundle.js
vendored
2
src/settings/settings-html/dist/bundle.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user