Compare commits
15 commits
main
...
stefan/set
Author | SHA1 | Date | |
---|---|---|---|
c4a0364d57 | |||
e6c6a8a046 | |||
a466bb3c14 | |||
b57b40bf2f | |||
128106e603 | |||
2f698aae4c | |||
9d6bb2fc43 | |||
c49d41d6a8 | |||
24474f82a9 | |||
85922cef2c | |||
5fce8863d8 | |||
9ad691a282 | |||
79bd4031be | |||
ea7341bd1b | |||
00a2651664 |
|
@ -371,6 +371,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MouseUtils", "MouseUtils",
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FindMyMouse", "src\modules\MouseUtils\FindMyMouse\FindMyMouse.vcxproj", "{E94FD11C-0591-456F-899F-EFC0CA548336}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FindMyMouse", "src\modules\MouseUtils\FindMyMouse\FindMyMouse.vcxproj", "{E94FD11C-0591-456F-899F-EFC0CA548336}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.PowerToys.Settings.UI.WinUI3", "src\settings-ui\Microsoft.PowerToys.Settings.UI.WinUI3\Microsoft.PowerToys.Settings.UI.WinUI3.csproj", "{496AB2AA-4BF0-4C1D-9598-DCCDA2B6E289}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|x64 = Debug|x64
|
Debug|x64 = Debug|x64
|
||||||
|
@ -986,6 +988,12 @@ Global
|
||||||
{E94FD11C-0591-456F-899F-EFC0CA548336}.Release|x64.ActiveCfg = Release|x64
|
{E94FD11C-0591-456F-899F-EFC0CA548336}.Release|x64.ActiveCfg = Release|x64
|
||||||
{E94FD11C-0591-456F-899F-EFC0CA548336}.Release|x64.Build.0 = Release|x64
|
{E94FD11C-0591-456F-899F-EFC0CA548336}.Release|x64.Build.0 = Release|x64
|
||||||
{E94FD11C-0591-456F-899F-EFC0CA548336}.Release|x86.ActiveCfg = Release|x64
|
{E94FD11C-0591-456F-899F-EFC0CA548336}.Release|x86.ActiveCfg = Release|x64
|
||||||
|
{496AB2AA-4BF0-4C1D-9598-DCCDA2B6E289}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{496AB2AA-4BF0-4C1D-9598-DCCDA2B6E289}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{496AB2AA-4BF0-4C1D-9598-DCCDA2B6E289}.Debug|x86.ActiveCfg = Debug|x64
|
||||||
|
{496AB2AA-4BF0-4C1D-9598-DCCDA2B6E289}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{496AB2AA-4BF0-4C1D-9598-DCCDA2B6E289}.Release|x64.Build.0 = Release|x64
|
||||||
|
{496AB2AA-4BF0-4C1D-9598-DCCDA2B6E289}.Release|x86.ActiveCfg = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -1105,6 +1113,7 @@ Global
|
||||||
{4642D596-723F-4BFC-894C-46811219AC4A} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
|
{4642D596-723F-4BFC-894C-46811219AC4A} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
|
||||||
{322566EF-20DC-43A6-B9F8-616AF942579A} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
{322566EF-20DC-43A6-B9F8-616AF942579A} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||||
{E94FD11C-0591-456F-899F-EFC0CA548336} = {322566EF-20DC-43A6-B9F8-616AF942579A}
|
{E94FD11C-0591-456F-899F-EFC0CA548336} = {322566EF-20DC-43A6-B9F8-616AF942579A}
|
||||||
|
{496AB2AA-4BF0-4C1D-9598-DCCDA2B6E289} = {C3081D9A-1586-441A-B5F4-ED815B3719C1}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}
|
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}
|
||||||
|
|
|
@ -277,7 +277,7 @@ void run_settings_window(bool show_oobe_window, std::optional<std::wstring> sett
|
||||||
// Arg 1: executable path.
|
// Arg 1: executable path.
|
||||||
std::wstring executable_path = get_module_folderpath();
|
std::wstring executable_path = get_module_folderpath();
|
||||||
|
|
||||||
executable_path.append(L"\\Settings\\PowerToys.Settings.exe");
|
executable_path.append(L"\\SettingsUI\\net5.0-windows10.0.19041.0\\Microsoft.PowerToys.Settings.UI.WinUI3.exe");
|
||||||
|
|
||||||
// Args 2,3: pipe server. Generate unique names for the pipes, if getting a UUID is possible.
|
// Args 2,3: pipe server. Generate unique names for the pipes, if getting a UUID is possible.
|
||||||
std::wstring powertoys_pipe_name(L"\\\\.\\pipe\\powertoys_runner_");
|
std::wstring powertoys_pipe_name(L"\\\\.\\pipe\\powertoys_runner_");
|
||||||
|
|
|
@ -71,9 +71,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
long seconds = long.Parse(LastCheckedDate, CultureInfo.CurrentCulture);
|
if (LastCheckedDate != null)
|
||||||
var date = DateTimeOffset.FromUnixTimeSeconds(seconds).UtcDateTime;
|
{
|
||||||
return date.ToLocalTime().ToString(CultureInfo.CurrentCulture);
|
long seconds = long.Parse(LastCheckedDate, CultureInfo.CurrentCulture);
|
||||||
|
var date = DateTimeOffset.FromUnixTimeSeconds(seconds).UtcDateTime;
|
||||||
|
return date.ToLocalTime().ToString(CultureInfo.CurrentCulture);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#pragma warning disable CA1031 // Do not catch general exception types
|
#pragma warning disable CA1031 // Do not catch general exception types
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
// 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.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Activation
|
||||||
|
{
|
||||||
|
// For more information on understanding and extending activation flow see
|
||||||
|
// https://github.com/Microsoft/WindowsTemplateStudio/blob/master/docs/activation.md
|
||||||
|
internal abstract class ActivationHandler
|
||||||
|
{
|
||||||
|
public abstract bool CanHandle(object args);
|
||||||
|
|
||||||
|
public abstract Task HandleAsync(object args);
|
||||||
|
}
|
||||||
|
|
||||||
|
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "abstract T and abstract")]
|
||||||
|
internal abstract class ActivationHandler<T> : ActivationHandler
|
||||||
|
where T : class
|
||||||
|
{
|
||||||
|
public override async Task HandleAsync(object args)
|
||||||
|
{
|
||||||
|
await HandleInternalAsync(args as T).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanHandle(object args)
|
||||||
|
{
|
||||||
|
// CanHandle checks the args is of type you have configured
|
||||||
|
return args is T && CanHandleInternal(args as T);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Override this method to add the activation logic in your activation handler
|
||||||
|
protected abstract Task HandleInternalAsync(T args);
|
||||||
|
|
||||||
|
// You can override this method to add extra validation on activation args
|
||||||
|
// to determine if your ActivationHandler should handle this activation args
|
||||||
|
protected virtual bool CanHandleInternal(T args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.PowerToys.Settings.UI.WinUI3.Services;
|
||||||
|
using Windows.ApplicationModel.Activation;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Activation
|
||||||
|
{
|
||||||
|
internal class DefaultActivationHandler : ActivationHandler<IActivatedEventArgs>
|
||||||
|
{
|
||||||
|
private readonly Type navElement;
|
||||||
|
|
||||||
|
public DefaultActivationHandler(Type navElement)
|
||||||
|
{
|
||||||
|
this.navElement = navElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task HandleInternalAsync(IActivatedEventArgs args)
|
||||||
|
{
|
||||||
|
// When the navigation stack isn't restored, navigate to the first page and configure
|
||||||
|
// the new page by passing required information in the navigation parameter
|
||||||
|
object arguments = null;
|
||||||
|
if (args is LaunchActivatedEventArgs launchArgs)
|
||||||
|
{
|
||||||
|
arguments = launchArgs.Arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
NavigationService.Navigate(navElement, arguments);
|
||||||
|
await Task.CompletedTask.ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool CanHandleInternal(IActivatedEventArgs args)
|
||||||
|
{
|
||||||
|
// None of the ActivationHandlers has handled the app activation
|
||||||
|
return NavigationService.Frame.Content == null && navElement != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
<Application
|
||||||
|
x:Class="Microsoft.PowerToys.Settings.UI.WinUI3.App"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.WinUI3.Controls">
|
||||||
|
<Application.Resources>
|
||||||
|
<ResourceDictionary>
|
||||||
|
<ResourceDictionary.MergedDictionaries>
|
||||||
|
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls"/>
|
||||||
|
<ResourceDictionary Source="/Controls/KeyVisual/KeyVisual.xaml" />
|
||||||
|
<ResourceDictionary Source="/Controls/IsEnabledTextBlock/IsEnabledTextBlock.xaml" />
|
||||||
|
<ResourceDictionary Source="/Styles/TextBlock.xaml" />
|
||||||
|
<ResourceDictionary Source="/Styles/Button.xaml"/>
|
||||||
|
<ResourceDictionary Source="/Themes/Colors.xaml"/>
|
||||||
|
<ResourceDictionary Source="/Themes/SettingsExpanderStyles.xaml"/>
|
||||||
|
</ResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
|
<SolidColorBrush x:Key="WindowCaptionBackground">Green</SolidColorBrush>
|
||||||
|
<SolidColorBrush x:Key="WindowCaptionBackgroundDisabled">LightGreen</SolidColorBrush>
|
||||||
|
<SolidColorBrush x:Key="WindowCaptionForeground">Red</SolidColorBrush>
|
||||||
|
<SolidColorBrush x:Key="WindowCaptionForegroundDisabled">Pink</SolidColorBrush>
|
||||||
|
|
||||||
|
<Thickness x:Key="InfoBarIconMargin">6,16,16,16</Thickness>
|
||||||
|
<Thickness x:Key="InfoBarContentRootPadding">16,0,0,0</Thickness>
|
||||||
|
<x:Double x:Key="SettingActionControlMinWidth">240</x:Double>
|
||||||
|
|
||||||
|
<Style TargetType="ListViewItem" >
|
||||||
|
<Setter Property="Margin" Value="0,0,0,2" />
|
||||||
|
<Setter Property="Padding" Value="0,0,0,0" />
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style TargetType="controls:CheckBoxWithDescriptionControl" BasedOn="{StaticResource DefaultCheckBoxStyle}" />
|
||||||
|
|
||||||
|
</ResourceDictionary>
|
||||||
|
</Application.Resources>
|
||||||
|
</Application>
|
|
@ -0,0 +1,147 @@
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using System.Globalization;
|
||||||
|
using Microsoft.PowerToys.Settings.UI.Library;
|
||||||
|
|
||||||
|
using interop;
|
||||||
|
using System;
|
||||||
|
using ManagedCommon;
|
||||||
|
using Windows.UI.ViewManagement;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
// To learn more about WinUI, the WinUI project structure,
|
||||||
|
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides application-specific behavior to supplement the default Application class.
|
||||||
|
/// </summary>
|
||||||
|
public partial class App : Application
|
||||||
|
{
|
||||||
|
private enum Arguments
|
||||||
|
{
|
||||||
|
PTPipeName = 1,
|
||||||
|
SettingsPipeName,
|
||||||
|
PTPid,
|
||||||
|
Theme, // used in the old settings
|
||||||
|
ElevatedStatus,
|
||||||
|
IsUserAdmin,
|
||||||
|
ShowOobeWindow,
|
||||||
|
SettingsWindow,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Quantity of arguments
|
||||||
|
private const int RequiredArgumentsQty = 8;
|
||||||
|
private const int RequiredAndOptionalArgumentsQty = 9;
|
||||||
|
|
||||||
|
// Create an instance of the IPC wrapper.
|
||||||
|
private static TwoWayPipeMessageIPCManaged ipcmanager;
|
||||||
|
|
||||||
|
public static bool IsElevated { get; set; }
|
||||||
|
|
||||||
|
public static bool IsUserAnAdmin { get; set; }
|
||||||
|
|
||||||
|
public static int PowerToysPID { get; set; }
|
||||||
|
|
||||||
|
public static Action<string> IPCMessageReceivedCallback { get; set; }
|
||||||
|
public bool ShowOobe { get; set; }
|
||||||
|
public Type StartupPage { get; set; } = typeof(Microsoft.PowerToys.Settings.UI.WinUI3.Views.GeneralPage);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the singleton application object. This is the first line of authored code
|
||||||
|
/// executed, and as such is the logical equivalent of main() or WinMain().
|
||||||
|
/// </summary>
|
||||||
|
public App()
|
||||||
|
{
|
||||||
|
this.InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked when the application is launched normally by the end user. Other entry points
|
||||||
|
/// will be used such as when the application is launched to open a specific file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="args">Details about the launch request and process.</param>
|
||||||
|
|
||||||
|
private MainWindow m_window;
|
||||||
|
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
|
||||||
|
{
|
||||||
|
m_window = new MainWindow();
|
||||||
|
m_window.Title = "PowerToys Settings";
|
||||||
|
m_window.Activate();
|
||||||
|
|
||||||
|
var cmdArgs = Environment.GetCommandLineArgs();
|
||||||
|
|
||||||
|
if (cmdArgs != null && cmdArgs.Length >= RequiredArgumentsQty)
|
||||||
|
{
|
||||||
|
_ = int.TryParse(cmdArgs[(int)Arguments.PTPid], out int powerToysPID);
|
||||||
|
PowerToysPID = powerToysPID;
|
||||||
|
|
||||||
|
IsElevated = cmdArgs[(int)Arguments.ElevatedStatus] == "true";
|
||||||
|
IsUserAnAdmin = cmdArgs[(int)Arguments.IsUserAdmin] == "true";
|
||||||
|
ShowOobe = cmdArgs[(int)Arguments.ShowOobeWindow] == "true";
|
||||||
|
|
||||||
|
if (cmdArgs.Length == RequiredAndOptionalArgumentsQty)
|
||||||
|
{
|
||||||
|
// open specific window
|
||||||
|
switch (cmdArgs[(int)Arguments.SettingsWindow])
|
||||||
|
{
|
||||||
|
case "Overview": StartupPage = typeof(Microsoft.PowerToys.Settings.UI.WinUI3.Views.GeneralPage); break;
|
||||||
|
case "Awake": StartupPage = typeof(Microsoft.PowerToys.Settings.UI.WinUI3.Views.AwakePage); break;
|
||||||
|
case "ColorPicker": StartupPage = typeof(Microsoft.PowerToys.Settings.UI.WinUI3.Views.ColorPickerPage); break;
|
||||||
|
case "FancyZones": StartupPage = typeof(Microsoft.PowerToys.Settings.UI.WinUI3.Views.FancyZonesPage); break;
|
||||||
|
case "Run": StartupPage = typeof(Microsoft.PowerToys.Settings.UI.WinUI3.Views.PowerLauncherPage); break;
|
||||||
|
case "ImageResizer": StartupPage = typeof(Microsoft.PowerToys.Settings.UI.WinUI3.Views.ImageResizerPage); break;
|
||||||
|
case "KBM": StartupPage = typeof(Microsoft.PowerToys.Settings.UI.WinUI3.Views.KeyboardManagerPage); break;
|
||||||
|
case "MouseUtils": StartupPage = typeof(Microsoft.PowerToys.Settings.UI.WinUI3.Views.MouseUtilsPage); break;
|
||||||
|
case "PowerRename": StartupPage = typeof(Microsoft.PowerToys.Settings.UI.WinUI3.Views.PowerRenamePage); break;
|
||||||
|
case "FileExplorer": StartupPage = typeof(Microsoft.PowerToys.Settings.UI.WinUI3.Views.PowerPreviewPage); break;
|
||||||
|
case "ShortcutGuide": StartupPage = typeof(Microsoft.PowerToys.Settings.UI.WinUI3.Views.ShortcutGuidePage); break;
|
||||||
|
case "VideoConference": StartupPage = typeof(Microsoft.PowerToys.Settings.UI.WinUI3.Views.VideoConferencePage); break;
|
||||||
|
default: Debug.Assert(false, "Unexpected SettingsWindow argument value"); break;
|
||||||
|
}
|
||||||
|
m_window.NavigateToSection(StartupPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
RunnerHelper.WaitForPowerToysRunner(PowerToysPID, () =>
|
||||||
|
{
|
||||||
|
Environment.Exit(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcmanager = new TwoWayPipeMessageIPCManaged(cmdArgs[(int)Arguments.SettingsPipeName], cmdArgs[(int)Arguments.PTPipeName], (string message) =>
|
||||||
|
{
|
||||||
|
if (IPCMessageReceivedCallback != null && message.Length > 0)
|
||||||
|
{
|
||||||
|
m_window.DispatcherQueue.TryEnqueue(() =>
|
||||||
|
{
|
||||||
|
IPCMessageReceivedCallback(message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ipcmanager.Start();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO(stefan) MessageBox not available
|
||||||
|
/* MessageBox.Show(
|
||||||
|
"The application cannot be run as a standalone process. Please start the application through the runner.",
|
||||||
|
"Forbidden",
|
||||||
|
MessageBoxButton.OK);
|
||||||
|
app.Shutdown();
|
||||||
|
*/ }
|
||||||
|
}
|
||||||
|
public static TwoWayPipeMessageIPCManaged GetTwoWayIPCManager()
|
||||||
|
{
|
||||||
|
return ipcmanager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsDarkTheme()
|
||||||
|
{
|
||||||
|
var selectedTheme = SettingsRepository<GeneralSettings>.GetInstance(settingsUtils).SettingsConfig.Theme.ToUpper(CultureInfo.InvariantCulture);
|
||||||
|
var defaultTheme = new UISettings();
|
||||||
|
var uiTheme = defaultTheme.GetColorValue(UIColorType.Background).ToString(System.Globalization.CultureInfo.InvariantCulture);
|
||||||
|
return selectedTheme == "DARK" || (selectedTheme == "SYSTEM" && uiTheme == "#FF000000");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ISettingsUtils settingsUtils = new SettingsUtils();
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 3 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 432 B |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 64 KiB |
After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 87 KiB |
After Width: | Height: | Size: 59 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 230 KiB |
After Width: | Height: | Size: 797 KiB |
After Width: | Height: | Size: 438 KiB |
After Width: | Height: | Size: 237 KiB |
After Width: | Height: | Size: 1.2 MiB |
After Width: | Height: | Size: 862 KiB |
After Width: | Height: | Size: 1.4 MiB |
After Width: | Height: | Size: 447 KiB |
After Width: | Height: | Size: 256 KiB |
After Width: | Height: | Size: 2.2 MiB |
After Width: | Height: | Size: 1.2 MiB |
After Width: | Height: | Size: 156 KiB |
After Width: | Height: | Size: 111 KiB |
After Width: | Height: | Size: 68 KiB |
After Width: | Height: | Size: 87 KiB |
After Width: | Height: | Size: 94 KiB |
After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 68 KiB |
After Width: | Height: | Size: 7.5 KiB |
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 637 B |
After Width: | Height: | Size: 283 B |
After Width: | Height: | Size: 456 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 2 KiB |
After Width: | Height: | Size: 7.1 KiB |
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 2.6 KiB |
|
@ -0,0 +1,138 @@
|
||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using Microsoft.PowerToys.Settings.UI.WinUI3.Services;
|
||||||
|
using Microsoft.Xaml.Interactivity;
|
||||||
|
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using Microsoft.UI.Xaml.Navigation;
|
||||||
|
|
||||||
|
using WinUI = Microsoft.UI.Xaml.Controls;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Behaviors
|
||||||
|
{
|
||||||
|
public class NavigationViewHeaderBehavior : Behavior<WinUI.NavigationView>
|
||||||
|
{
|
||||||
|
private static NavigationViewHeaderBehavior current;
|
||||||
|
private Page currentPage;
|
||||||
|
|
||||||
|
public DataTemplate DefaultHeaderTemplate { get; set; }
|
||||||
|
|
||||||
|
public object DefaultHeader
|
||||||
|
{
|
||||||
|
get { return GetValue(DefaultHeaderProperty); }
|
||||||
|
set { SetValue(DefaultHeaderProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty DefaultHeaderProperty = DependencyProperty.Register("DefaultHeader", typeof(object), typeof(NavigationViewHeaderBehavior), new PropertyMetadata(null, (d, e) => current.UpdateHeader()));
|
||||||
|
|
||||||
|
public static NavigationViewHeaderMode GetHeaderMode(Page item)
|
||||||
|
{
|
||||||
|
return (NavigationViewHeaderMode)item?.GetValue(HeaderModeProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetHeaderMode(Page item, NavigationViewHeaderMode value)
|
||||||
|
{
|
||||||
|
item?.SetValue(HeaderModeProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty HeaderModeProperty =
|
||||||
|
DependencyProperty.RegisterAttached("HeaderMode", typeof(bool), typeof(NavigationViewHeaderBehavior), new PropertyMetadata(NavigationViewHeaderMode.Always, (d, e) => current.UpdateHeader()));
|
||||||
|
|
||||||
|
public static object GetHeaderContext(Page item)
|
||||||
|
{
|
||||||
|
return item?.GetValue(HeaderContextProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetHeaderContext(Page item, object value)
|
||||||
|
{
|
||||||
|
item?.SetValue(HeaderContextProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty HeaderContextProperty =
|
||||||
|
DependencyProperty.RegisterAttached("HeaderContext", typeof(object), typeof(NavigationViewHeaderBehavior), new PropertyMetadata(null, (d, e) => current.UpdateHeader()));
|
||||||
|
|
||||||
|
public static DataTemplate GetHeaderTemplate(Page item)
|
||||||
|
{
|
||||||
|
return (DataTemplate)item?.GetValue(HeaderTemplateProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetHeaderTemplate(Page item, DataTemplate value)
|
||||||
|
{
|
||||||
|
item?.SetValue(HeaderTemplateProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty HeaderTemplateProperty =
|
||||||
|
DependencyProperty.RegisterAttached("HeaderTemplate", typeof(DataTemplate), typeof(NavigationViewHeaderBehavior), new PropertyMetadata(null, (d, e) => current.UpdateHeaderTemplate()));
|
||||||
|
|
||||||
|
protected override void OnAttached()
|
||||||
|
{
|
||||||
|
base.OnAttached();
|
||||||
|
current = this;
|
||||||
|
NavigationService.Navigated += OnNavigated;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDetaching()
|
||||||
|
{
|
||||||
|
base.OnDetaching();
|
||||||
|
NavigationService.Navigated -= OnNavigated;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnNavigated(object sender, NavigationEventArgs e)
|
||||||
|
{
|
||||||
|
var frame = sender as Frame;
|
||||||
|
if (frame.Content is Page page)
|
||||||
|
{
|
||||||
|
currentPage = page;
|
||||||
|
|
||||||
|
UpdateHeader();
|
||||||
|
UpdateHeaderTemplate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateHeader()
|
||||||
|
{
|
||||||
|
if (currentPage != null)
|
||||||
|
{
|
||||||
|
var headerMode = GetHeaderMode(currentPage);
|
||||||
|
if (headerMode == NavigationViewHeaderMode.Never)
|
||||||
|
{
|
||||||
|
AssociatedObject.Header = null;
|
||||||
|
AssociatedObject.AlwaysShowHeader = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var headerFromPage = GetHeaderContext(currentPage);
|
||||||
|
if (headerFromPage != null)
|
||||||
|
{
|
||||||
|
AssociatedObject.Header = headerFromPage;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AssociatedObject.Header = DefaultHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headerMode == NavigationViewHeaderMode.Always)
|
||||||
|
{
|
||||||
|
AssociatedObject.AlwaysShowHeader = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AssociatedObject.AlwaysShowHeader = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateHeaderTemplate()
|
||||||
|
{
|
||||||
|
if (currentPage != null)
|
||||||
|
{
|
||||||
|
var headerTemplate = GetHeaderTemplate(currentPage);
|
||||||
|
AssociatedObject.HeaderTemplate = headerTemplate ?? DefaultHeaderTemplate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Behaviors
|
||||||
|
{
|
||||||
|
public enum NavigationViewHeaderMode
|
||||||
|
{
|
||||||
|
Always,
|
||||||
|
Never,
|
||||||
|
Minimal,
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System.ComponentModel;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Automation;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using Microsoft.UI.Xaml.Media;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Controls
|
||||||
|
{
|
||||||
|
public class CheckBoxWithDescriptionControl : CheckBox
|
||||||
|
{
|
||||||
|
private CheckBoxWithDescriptionControl _checkBoxSubTextControl;
|
||||||
|
|
||||||
|
public CheckBoxWithDescriptionControl()
|
||||||
|
{
|
||||||
|
_checkBoxSubTextControl = (CheckBoxWithDescriptionControl)this;
|
||||||
|
this.Loaded += CheckBoxSubTextControl_Loaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnApplyTemplate()
|
||||||
|
{
|
||||||
|
Update();
|
||||||
|
base.OnApplyTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(Header))
|
||||||
|
{
|
||||||
|
AutomationProperties.SetName(this, Header);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CheckBoxSubTextControl_Loaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
StackPanel panel = new StackPanel() { Orientation = Orientation.Vertical };
|
||||||
|
panel.Children.Add(new TextBlock() { Margin = new Thickness(0, 10, 0, 0), Text = Header });
|
||||||
|
panel.Children.Add(new IsEnabledTextBlock() { FontSize = (double)App.Current.Resources["SecondaryTextFontSize"], Foreground = (SolidColorBrush)App.Current.Resources["TextFillColorSecondaryBrush"], Text = Description });
|
||||||
|
_checkBoxSubTextControl.Content = panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(
|
||||||
|
"Header",
|
||||||
|
typeof(string),
|
||||||
|
typeof(CheckBoxWithDescriptionControl),
|
||||||
|
new PropertyMetadata(default(string)));
|
||||||
|
|
||||||
|
public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register(
|
||||||
|
"Description",
|
||||||
|
typeof(object),
|
||||||
|
typeof(CheckBoxWithDescriptionControl),
|
||||||
|
new PropertyMetadata(default(string)));
|
||||||
|
|
||||||
|
[Localizable(true)]
|
||||||
|
public string Header
|
||||||
|
{
|
||||||
|
get => (string)GetValue(HeaderProperty);
|
||||||
|
set => SetValue(HeaderProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Localizable(true)]
|
||||||
|
public string Description
|
||||||
|
{
|
||||||
|
get => (string)GetValue(DescriptionProperty);
|
||||||
|
set => SetValue(DescriptionProperty, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
<UserControl
|
||||||
|
x:Class="Microsoft.PowerToys.Settings.UI.WinUI3.Controls.ColorPickerButton"
|
||||||
|
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.Controls"
|
||||||
|
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"
|
||||||
|
xmlns:clr="using:Windows.UI"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
|
||||||
|
d:DesignHeight="300"
|
||||||
|
d:DesignWidth="400">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<!--TODO(stefan) ColorHelper.ToDisplayName() not available in WinUI3
|
||||||
|
<muxc:DropDownButton Padding="4,4,8,4" AutomationProperties.FullDescription="{x:Bind clr:ColorHelper.ToDisplayName(SelectedColor), Mode=OneWay }">
|
||||||
|
-->
|
||||||
|
<muxc:DropDownButton Padding="4,4,8,4">
|
||||||
|
<Border x:Name="ColorPreviewBorder"
|
||||||
|
Width="48"
|
||||||
|
CornerRadius="2"
|
||||||
|
Height="24"
|
||||||
|
BorderBrush="{ThemeResource CardBorderBrush}"
|
||||||
|
BorderThickness="{ThemeResource CardBorderThickness}">
|
||||||
|
<Border.Background>
|
||||||
|
<SolidColorBrush Color="{x:Bind SelectedColor, Mode=OneWay}"/>
|
||||||
|
</Border.Background>
|
||||||
|
</Border>
|
||||||
|
<muxc:DropDownButton.Flyout>
|
||||||
|
<Flyout>
|
||||||
|
<muxc:ColorPicker IsColorSliderVisible="True"
|
||||||
|
IsColorChannelTextInputVisible="True"
|
||||||
|
IsHexInputVisible="True"
|
||||||
|
IsAlphaEnabled="False"
|
||||||
|
IsAlphaSliderVisible="False"
|
||||||
|
IsAlphaTextInputVisible="False"
|
||||||
|
Color="{x:Bind SelectedColor, Mode=TwoWay}" />
|
||||||
|
</Flyout>
|
||||||
|
</muxc:DropDownButton.Flyout>
|
||||||
|
</muxc:DropDownButton>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
|
@ -0,0 +1,59 @@
|
||||||
|
// 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 Windows.UI;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Controls
|
||||||
|
{
|
||||||
|
public sealed partial class ColorPickerButton : UserControl
|
||||||
|
{
|
||||||
|
private Color _selectedColor;
|
||||||
|
|
||||||
|
public Color SelectedColor
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _selectedColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_selectedColor != value)
|
||||||
|
{
|
||||||
|
_selectedColor = value;
|
||||||
|
SetValue(SelectedColorProperty, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty SelectedColorProperty = DependencyProperty.Register("SelectedColor", typeof(Color), typeof(ColorPickerButton), new PropertyMetadata(null));
|
||||||
|
|
||||||
|
public ColorPickerButton()
|
||||||
|
{
|
||||||
|
this.InitializeComponent();
|
||||||
|
IsEnabledChanged -= ColorPickerButton_IsEnabledChanged;
|
||||||
|
SetEnabledState();
|
||||||
|
IsEnabledChanged += ColorPickerButton_IsEnabledChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ColorPickerButton_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
SetEnabledState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetEnabledState()
|
||||||
|
{
|
||||||
|
if (this.IsEnabled)
|
||||||
|
{
|
||||||
|
ColorPreviewBorder.Opacity = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ColorPreviewBorder.Opacity = 0.2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System.ComponentModel;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Controls
|
||||||
|
{
|
||||||
|
[TemplateVisualState(Name = "Normal", GroupName = "CommonStates")]
|
||||||
|
[TemplateVisualState(Name = "Disabled", GroupName = "CommonStates")]
|
||||||
|
public class IsEnabledTextBlock : Control
|
||||||
|
{
|
||||||
|
public IsEnabledTextBlock()
|
||||||
|
{
|
||||||
|
this.DefaultStyleKey = typeof(IsEnabledTextBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnApplyTemplate()
|
||||||
|
{
|
||||||
|
IsEnabledChanged -= IsEnabledTextBlock_IsEnabledChanged;
|
||||||
|
SetEnabledState();
|
||||||
|
IsEnabledChanged += IsEnabledTextBlock_IsEnabledChanged;
|
||||||
|
base.OnApplyTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
|
||||||
|
"Text",
|
||||||
|
typeof(string),
|
||||||
|
typeof(IsEnabledTextBlock),
|
||||||
|
null);
|
||||||
|
|
||||||
|
[Localizable(true)]
|
||||||
|
public string Text
|
||||||
|
{
|
||||||
|
get => (string)GetValue(TextProperty);
|
||||||
|
set => SetValue(TextProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void IsEnabledTextBlock_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
SetEnabledState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetEnabledState()
|
||||||
|
{
|
||||||
|
VisualStateManager.GoToState(this, IsEnabled ? "Normal" : "Disabled", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
<ResourceDictionary
|
||||||
|
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.WinUI3.Controls">
|
||||||
|
|
||||||
|
<Style TargetType="local:IsEnabledTextBlock">
|
||||||
|
<Setter Property="Foreground" Value="{ThemeResource DefaultTextForegroundThemeBrush}" />
|
||||||
|
<Setter Property="IsTabStop" Value="False" />
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="local:IsEnabledTextBlock">
|
||||||
|
<Grid>
|
||||||
|
<VisualStateManager.VisualStateGroups>
|
||||||
|
<VisualStateGroup x:Name="CommonStates">
|
||||||
|
<VisualState x:Name="Normal"/>
|
||||||
|
<VisualState x:Name="Disabled">
|
||||||
|
<VisualState.Setters>
|
||||||
|
<Setter Target="Label.Foreground" Value="{ThemeResource TextFillColorDisabledBrush}" />
|
||||||
|
</VisualState.Setters>
|
||||||
|
</VisualState>
|
||||||
|
</VisualStateGroup>
|
||||||
|
</VisualStateManager.VisualStateGroups>
|
||||||
|
<TextBlock x:Name="Label"
|
||||||
|
FontSize="{TemplateBinding FontSize}"
|
||||||
|
FontWeight="{TemplateBinding FontWeight}"
|
||||||
|
FontFamily="{TemplateBinding FontFamily}"
|
||||||
|
Foreground="{TemplateBinding Foreground}"
|
||||||
|
TextWrapping="WrapWholeWords"
|
||||||
|
Text="{TemplateBinding Text}" />
|
||||||
|
</Grid>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
</ResourceDictionary>
|
|
@ -0,0 +1,186 @@
|
||||||
|
// 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 Windows.System;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using Microsoft.UI.Xaml.Markup;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Controls
|
||||||
|
{
|
||||||
|
[TemplatePart(Name = KeyPresenter, Type = typeof(ContentPresenter))]
|
||||||
|
[TemplateVisualState(Name = "Normal", GroupName = "CommonStates")]
|
||||||
|
[TemplateVisualState(Name = "Disabled", GroupName = "CommonStates")]
|
||||||
|
[TemplateVisualState(Name = "Default", GroupName = "StateStates")]
|
||||||
|
[TemplateVisualState(Name = "Error", GroupName = "StateStates")]
|
||||||
|
public sealed class KeyVisual : Control
|
||||||
|
{
|
||||||
|
private const string KeyPresenter = "KeyPresenter";
|
||||||
|
private KeyVisual _keyVisual;
|
||||||
|
private ContentPresenter _keyPresenter;
|
||||||
|
|
||||||
|
public object Content
|
||||||
|
{
|
||||||
|
get => (object)GetValue(ContentProperty);
|
||||||
|
set => SetValue(ContentProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty ContentProperty = DependencyProperty.Register("Content", typeof(object), typeof(KeyVisual), new PropertyMetadata(default(string), OnContentChanged));
|
||||||
|
|
||||||
|
public VisualType VisualType
|
||||||
|
{
|
||||||
|
get => (VisualType)GetValue(VisualTypeProperty);
|
||||||
|
set => SetValue(VisualTypeProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty VisualTypeProperty = DependencyProperty.Register("VisualType", typeof(VisualType), typeof(KeyVisual), new PropertyMetadata(default(VisualType), OnSizeChanged));
|
||||||
|
|
||||||
|
public bool IsError
|
||||||
|
{
|
||||||
|
get => (bool)GetValue(IsErrorProperty);
|
||||||
|
set => SetValue(IsErrorProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty IsErrorProperty = DependencyProperty.Register("IsError", typeof(bool), typeof(KeyVisual), new PropertyMetadata(false, OnIsErrorChanged));
|
||||||
|
|
||||||
|
public KeyVisual()
|
||||||
|
{
|
||||||
|
this.DefaultStyleKey = typeof(KeyVisual);
|
||||||
|
this.Style = GetStyleSize("TextKeyVisualStyle");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnApplyTemplate()
|
||||||
|
{
|
||||||
|
IsEnabledChanged -= KeyVisual_IsEnabledChanged;
|
||||||
|
_keyVisual = (KeyVisual)this;
|
||||||
|
_keyPresenter = (ContentPresenter)_keyVisual.GetTemplateChild(KeyPresenter);
|
||||||
|
Update();
|
||||||
|
SetEnabledState();
|
||||||
|
SetErrorState();
|
||||||
|
IsEnabledChanged += KeyVisual_IsEnabledChanged;
|
||||||
|
base.OnApplyTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
((KeyVisual)d).Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnSizeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
((KeyVisual)d).Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnIsErrorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
((KeyVisual)d).SetErrorState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
if (_keyVisual == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_keyVisual.Content != null)
|
||||||
|
{
|
||||||
|
if (_keyVisual.Content.GetType() == typeof(string))
|
||||||
|
{
|
||||||
|
_keyVisual.Style = GetStyleSize("TextKeyVisualStyle");
|
||||||
|
_keyVisual._keyPresenter.Content = _keyVisual.Content;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_keyVisual.Style = GetStyleSize("IconKeyVisualStyle");
|
||||||
|
|
||||||
|
switch ((int)_keyVisual.Content)
|
||||||
|
{
|
||||||
|
/* We can enable other glyphs in the future
|
||||||
|
case 13: // The Enter key or button.
|
||||||
|
_keyVisual._keyPresenter.Content = "\uE751"; break;
|
||||||
|
|
||||||
|
case 8: // The Back key or button.
|
||||||
|
_keyVisual._keyPresenter.Content = "\uE750"; break;
|
||||||
|
|
||||||
|
case 16: // The right Shift key or button.
|
||||||
|
case 160: // The left Shift key or button.
|
||||||
|
case 161: // The Shift key or button.
|
||||||
|
_keyVisual._keyPresenter.Content = "\uE752"; break; */
|
||||||
|
|
||||||
|
case 38: _keyVisual._keyPresenter.Content = "\uE0E4"; break; // The Up Arrow key or button.
|
||||||
|
case 40: _keyVisual._keyPresenter.Content = "\uE0E5"; break; // The Down Arrow key or button.
|
||||||
|
case 37: _keyVisual._keyPresenter.Content = "\uE0E2"; break; // The Left Arrow key or button.
|
||||||
|
case 39: _keyVisual._keyPresenter.Content = "\uE0E3"; break; // The Right Arrow key or button.
|
||||||
|
|
||||||
|
case 91: // The left Windows key
|
||||||
|
case 92: // The right Windows key
|
||||||
|
PathIcon winIcon = XamlReader.Load(@"<PathIcon xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" Data=""M9,17V9h8v8ZM0,17V9H8v8ZM9,8V0h8V8ZM0,8V0H8V8Z"" />") as PathIcon;
|
||||||
|
Viewbox winIconContainer = new Viewbox();
|
||||||
|
winIconContainer.Child = winIcon;
|
||||||
|
winIconContainer.HorizontalAlignment = HorizontalAlignment.Center;
|
||||||
|
winIconContainer.VerticalAlignment = VerticalAlignment.Center;
|
||||||
|
|
||||||
|
double iconDimensions = GetIconSize();
|
||||||
|
winIconContainer.Height = iconDimensions;
|
||||||
|
winIconContainer.Width = iconDimensions;
|
||||||
|
_keyVisual._keyPresenter.Content = winIconContainer;
|
||||||
|
break;
|
||||||
|
default: _keyVisual._keyPresenter.Content = ((VirtualKey)_keyVisual.Content).ToString(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Style GetStyleSize(string styleName)
|
||||||
|
{
|
||||||
|
if (VisualType == VisualType.Small)
|
||||||
|
{
|
||||||
|
return (Style)App.Current.Resources["Small" + styleName];
|
||||||
|
}
|
||||||
|
else if (VisualType == VisualType.SmallOutline)
|
||||||
|
{
|
||||||
|
return (Style)App.Current.Resources["SmallOutline" + styleName];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (Style)App.Current.Resources["Default" + styleName];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public double GetIconSize()
|
||||||
|
{
|
||||||
|
if (VisualType == VisualType.Small || VisualType == VisualType.SmallOutline)
|
||||||
|
{
|
||||||
|
return (double)App.Current.Resources["SmallIconSize"];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (double)App.Current.Resources["DefaultIconSize"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void KeyVisual_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
SetEnabledState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetErrorState()
|
||||||
|
{
|
||||||
|
VisualStateManager.GoToState(this, IsError ? "Error" : "Default", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetEnabledState()
|
||||||
|
{
|
||||||
|
VisualStateManager.GoToState(this, IsEnabled ? "Normal" : "Disabled", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum VisualType
|
||||||
|
{
|
||||||
|
Small,
|
||||||
|
SmallOutline,
|
||||||
|
Large,
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,124 @@
|
||||||
|
<ResourceDictionary 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.WinUI3.Controls">
|
||||||
|
|
||||||
|
<x:Double x:Key="DefaultIconSize">16</x:Double>
|
||||||
|
<x:Double x:Key="SmallIconSize">12</x:Double>
|
||||||
|
<Style x:Key="DefaultTextKeyVisualStyle" TargetType="local:KeyVisual">
|
||||||
|
<Setter Property="MinWidth" Value="56" />
|
||||||
|
<Setter Property="MinHeight" Value="48" />
|
||||||
|
<Setter Property="Background" Value="{ThemeResource AccentButtonBackground}" />
|
||||||
|
<Setter Property="Foreground" Value="{ThemeResource AccentButtonForeground}" />
|
||||||
|
<Setter Property="BorderBrush" Value="{ThemeResource AccentButtonBorderBrush}" />
|
||||||
|
<Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}" />
|
||||||
|
<Setter Property="Padding" Value="16,8,16,8" />
|
||||||
|
<Setter Property="FontWeight" Value="SemiBold" />
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Center" />
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Center" />
|
||||||
|
<Setter Property="FontSize" Value="18" />
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="local:KeyVisual">
|
||||||
|
<Grid>
|
||||||
|
<VisualStateManager.VisualStateGroups>
|
||||||
|
<VisualStateGroup x:Name="CommonStates">
|
||||||
|
<VisualState x:Name="Normal"/>
|
||||||
|
<VisualState x:Name="Disabled">
|
||||||
|
<VisualState.Setters>
|
||||||
|
<Setter Target="ContentHolder.Fill" Value="{ThemeResource AccentButtonBackgroundDisabled}" />
|
||||||
|
<Setter Target="KeyPresenter.Foreground" Value="{ThemeResource AccentButtonForegroundDisabled}" />
|
||||||
|
<Setter Target="ContentHolder.Stroke" Value="{ThemeResource AccentButtonBorderBrushDisabled}" />
|
||||||
|
<!--<Setter Target="ContentHolder.StrokeThickness" Value="{TemplateBinding BorderThickness}" />-->
|
||||||
|
</VisualState.Setters>
|
||||||
|
</VisualState>
|
||||||
|
</VisualStateGroup>
|
||||||
|
<VisualStateGroup x:Name="StateStates">
|
||||||
|
<VisualState x:Name="Default"/>
|
||||||
|
<VisualState x:Name="Error">
|
||||||
|
<VisualState.Setters>
|
||||||
|
<Setter Target="ContentHolder.Fill" Value="{ThemeResource InfoBarErrorSeverityBackgroundBrush}" />
|
||||||
|
<Setter Target="KeyPresenter.Foreground" Value="{ThemeResource InfoBarErrorSeverityIconBackground}" />
|
||||||
|
<Setter Target="ContentHolder.Stroke" Value="{ThemeResource InfoBarErrorSeverityIconBackground}" />
|
||||||
|
<Setter Target="ContentHolder.StrokeThickness" Value="2" />
|
||||||
|
</VisualState.Setters>
|
||||||
|
</VisualState>
|
||||||
|
</VisualStateGroup>
|
||||||
|
</VisualStateManager.VisualStateGroups>
|
||||||
|
<Grid>
|
||||||
|
<Rectangle x:Name="ContentHolder"
|
||||||
|
Fill="{TemplateBinding Background}"
|
||||||
|
Stroke="{TemplateBinding BorderBrush}"
|
||||||
|
StrokeThickness="{TemplateBinding BorderThickness}"
|
||||||
|
RadiusX="4"
|
||||||
|
RadiusY="4"
|
||||||
|
Height="{TemplateBinding Height}"
|
||||||
|
MinWidth="{TemplateBinding MinWidth}"/>
|
||||||
|
<ContentPresenter x:Name="KeyPresenter"
|
||||||
|
FontWeight="{TemplateBinding FontWeight}"
|
||||||
|
Foreground="{TemplateBinding Foreground}"
|
||||||
|
Content="{TemplateBinding Content}"
|
||||||
|
Margin="{TemplateBinding Padding}"
|
||||||
|
FontSize="{TemplateBinding FontSize}"
|
||||||
|
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||||
|
VerticalAlignment="Center" />
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="SmallTextKeyVisualStyle" TargetType="local:KeyVisual" BasedOn="{StaticResource DefaultTextKeyVisualStyle}">
|
||||||
|
<Setter Property="MinWidth" Value="40" />
|
||||||
|
<Setter Property="Height" Value="36" />
|
||||||
|
<Setter Property="FontWeight" Value="SemiBold" />
|
||||||
|
<Setter Property="Padding" Value="12,0,12,2" />
|
||||||
|
<Setter Property="FontSize" Value="14" />
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Center" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="SmallOutlineTextKeyVisualStyle" TargetType="local:KeyVisual" BasedOn="{StaticResource DefaultTextKeyVisualStyle}">
|
||||||
|
<Setter Property="MinWidth" Value="40" />
|
||||||
|
<Setter Property="Background" Value="{ThemeResource ButtonBackground}" />
|
||||||
|
<Setter Property="Foreground" Value="{ThemeResource ButtonForeground}" />
|
||||||
|
<Setter Property="BorderBrush" Value="{ThemeResource ButtonBorderBrush}" />
|
||||||
|
<Setter Property="Height" Value="36" />
|
||||||
|
<Setter Property="FontWeight" Value="SemiBold" />
|
||||||
|
<Setter Property="Padding" Value="8,0,8,2" />
|
||||||
|
<Setter Property="FontSize" Value="13" />
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Center" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
|
||||||
|
<Style x:Key="DefaultIconKeyVisualStyle" TargetType="local:KeyVisual" BasedOn="{StaticResource DefaultTextKeyVisualStyle}">
|
||||||
|
<Setter Property="MinWidth" Value="56" />
|
||||||
|
<Setter Property="MinHeight" Value="48" />
|
||||||
|
<Setter Property="FontFamily" Value="{ThemeResource SymbolThemeFontFamily}" />
|
||||||
|
<Setter Property="Padding" Value="16,8,16,8" />
|
||||||
|
<Setter Property="FontSize" Value="14" />
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Center" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="SmallIconKeyVisualStyle" TargetType="local:KeyVisual" BasedOn="{StaticResource DefaultTextKeyVisualStyle}">
|
||||||
|
<Setter Property="MinWidth" Value="40" />
|
||||||
|
<Setter Property="Height" Value="36" />
|
||||||
|
<Setter Property="FontFamily" Value="{ThemeResource SymbolThemeFontFamily}" />
|
||||||
|
<Setter Property="FontWeight" Value="Normal" />
|
||||||
|
<Setter Property="Padding" Value="0" />
|
||||||
|
<Setter Property="FontSize" Value="10" />
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Center" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="SmallOutlineIconKeyVisualStyle" TargetType="local:KeyVisual" BasedOn="{StaticResource DefaultTextKeyVisualStyle}">
|
||||||
|
<Setter Property="MinWidth" Value="40" />
|
||||||
|
<Setter Property="Background" Value="{ThemeResource ButtonBackground}" />
|
||||||
|
<Setter Property="Foreground" Value="{ThemeResource ButtonForeground}" />
|
||||||
|
<Setter Property="BorderBrush" Value="{ThemeResource ButtonBorderBrush}" />
|
||||||
|
<Setter Property="FontFamily" Value="{ThemeResource SymbolThemeFontFamily}" />
|
||||||
|
<Setter Property="Height" Value="36" />
|
||||||
|
<Setter Property="FontWeight" Value="SemiBold" />
|
||||||
|
<Setter Property="Padding" Value="0" />
|
||||||
|
<Setter Property="FontSize" Value="9" />
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Center" />
|
||||||
|
</Style>
|
||||||
|
</ResourceDictionary>
|
|
@ -0,0 +1,47 @@
|
||||||
|
<UserControl
|
||||||
|
x:Class="Microsoft.PowerToys.Settings.UI.WinUI3.Controls.OOBEPageControl"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
|
||||||
|
d:DesignHeight="300"
|
||||||
|
d:DesignWidth="400">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="280" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<Image x:Name="HeaderImage"
|
||||||
|
Source="{x:Bind ModuleImageSource}"
|
||||||
|
Stretch="UniformToFill" />
|
||||||
|
|
||||||
|
<ScrollViewer Grid.Row="1"
|
||||||
|
VerticalScrollBarVisibility="Auto"
|
||||||
|
Padding="32,24,32,24">
|
||||||
|
<StackPanel Orientation="Vertical"
|
||||||
|
VerticalAlignment="Top">
|
||||||
|
|
||||||
|
<TextBlock x:Name="TitleTxt"
|
||||||
|
Text="{x:Bind ModuleTitle}"
|
||||||
|
AutomationProperties.HeadingLevel="Level1"
|
||||||
|
Style="{StaticResource TitleTextBlockStyle}" />
|
||||||
|
|
||||||
|
<TextBlock x:Name="DescriptionTxt"
|
||||||
|
Margin="0,8,0,0"
|
||||||
|
Text="{x:Bind ModuleDescription}"
|
||||||
|
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
|
||||||
|
<ContentPresenter x:Name="ModuleContentPresenter"
|
||||||
|
Content="{x:Bind ModuleContent}"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
HorizontalContentAlignment="Stretch"
|
||||||
|
Margin="0,12,0,0"/>
|
||||||
|
</StackPanel>
|
||||||
|
</ScrollViewer>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
|
@ -0,0 +1,46 @@
|
||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Controls
|
||||||
|
{
|
||||||
|
public sealed partial class OOBEPageControl : UserControl
|
||||||
|
{
|
||||||
|
public OOBEPageControl()
|
||||||
|
{
|
||||||
|
this.InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ModuleTitle
|
||||||
|
{
|
||||||
|
get { return (string)GetValue(ModuleTitleProperty); }
|
||||||
|
set { SetValue(ModuleTitleProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ModuleDescription
|
||||||
|
{
|
||||||
|
get => (string)GetValue(ModuleDescriptionProperty);
|
||||||
|
set => SetValue(ModuleDescriptionProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ModuleImageSource
|
||||||
|
{
|
||||||
|
get => (string)GetValue(ModuleImageSourceProperty);
|
||||||
|
set => SetValue(ModuleImageSourceProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ModuleContent
|
||||||
|
{
|
||||||
|
get { return (object)GetValue(ModuleContentProperty); }
|
||||||
|
set { SetValue(ModuleContentProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty ModuleTitleProperty = DependencyProperty.Register("ModuleTitle", typeof(string), typeof(SettingsPageControl), new PropertyMetadata(default(string)));
|
||||||
|
public static readonly DependencyProperty ModuleDescriptionProperty = DependencyProperty.Register("ModuleDescription", typeof(string), typeof(SettingsPageControl), new PropertyMetadata(default(string)));
|
||||||
|
public static readonly DependencyProperty ModuleImageSourceProperty = DependencyProperty.Register("ModuleImageSource", typeof(string), typeof(SettingsPageControl), new PropertyMetadata(default(string)));
|
||||||
|
public static readonly DependencyProperty ModuleContentProperty = DependencyProperty.Register("ModuleContent", typeof(object), typeof(SettingsPageControl), new PropertyMetadata(new Grid()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,157 @@
|
||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System.ComponentModel;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Automation;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Controls
|
||||||
|
{
|
||||||
|
[TemplateVisualState(Name = "Normal", GroupName = "CommonStates")]
|
||||||
|
[TemplateVisualState(Name = "Disabled", GroupName = "CommonStates")]
|
||||||
|
[TemplatePart(Name = PartIconPresenter, Type = typeof(ContentPresenter))]
|
||||||
|
[TemplatePart(Name = PartDescriptionPresenter, Type = typeof(ContentPresenter))]
|
||||||
|
public class Setting : ContentControl
|
||||||
|
{
|
||||||
|
private const string PartIconPresenter = "IconPresenter";
|
||||||
|
private const string PartDescriptionPresenter = "DescriptionPresenter";
|
||||||
|
private ContentPresenter _iconPresenter;
|
||||||
|
private ContentPresenter _descriptionPresenter;
|
||||||
|
private Setting _setting;
|
||||||
|
|
||||||
|
public Setting()
|
||||||
|
{
|
||||||
|
this.DefaultStyleKey = typeof(Setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(
|
||||||
|
"Header",
|
||||||
|
typeof(string),
|
||||||
|
typeof(Setting),
|
||||||
|
new PropertyMetadata(default(string), OnHeaderChanged));
|
||||||
|
|
||||||
|
public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register(
|
||||||
|
"Description",
|
||||||
|
typeof(object),
|
||||||
|
typeof(Setting),
|
||||||
|
new PropertyMetadata(null, OnDescriptionChanged));
|
||||||
|
|
||||||
|
public static readonly DependencyProperty IconProperty = DependencyProperty.Register(
|
||||||
|
"Icon",
|
||||||
|
typeof(object),
|
||||||
|
typeof(Setting),
|
||||||
|
new PropertyMetadata(default(string), OnIconChanged));
|
||||||
|
|
||||||
|
public static readonly DependencyProperty ActionContentProperty = DependencyProperty.Register(
|
||||||
|
"ActionContent",
|
||||||
|
typeof(object),
|
||||||
|
typeof(Setting),
|
||||||
|
null);
|
||||||
|
|
||||||
|
[Localizable(true)]
|
||||||
|
public string Header
|
||||||
|
{
|
||||||
|
get => (string)GetValue(HeaderProperty);
|
||||||
|
set => SetValue(HeaderProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Localizable(true)]
|
||||||
|
public object Description
|
||||||
|
{
|
||||||
|
get => (object)GetValue(DescriptionProperty);
|
||||||
|
set => SetValue(DescriptionProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object Icon
|
||||||
|
{
|
||||||
|
get => (object)GetValue(IconProperty);
|
||||||
|
set => SetValue(IconProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ActionContent
|
||||||
|
{
|
||||||
|
get => (object)GetValue(ActionContentProperty);
|
||||||
|
set => SetValue(ActionContentProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnApplyTemplate()
|
||||||
|
{
|
||||||
|
IsEnabledChanged -= Setting_IsEnabledChanged;
|
||||||
|
_setting = (Setting)this;
|
||||||
|
_iconPresenter = (ContentPresenter)_setting.GetTemplateChild(PartIconPresenter);
|
||||||
|
_descriptionPresenter = (ContentPresenter)_setting.GetTemplateChild(PartDescriptionPresenter);
|
||||||
|
Update();
|
||||||
|
SetEnabledState();
|
||||||
|
IsEnabledChanged += Setting_IsEnabledChanged;
|
||||||
|
base.OnApplyTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnHeaderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
((Setting)d).Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnIconChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
((Setting)d).Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnDescriptionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
((Setting)d).Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Setting_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
SetEnabledState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetEnabledState()
|
||||||
|
{
|
||||||
|
VisualStateManager.GoToState(this, IsEnabled ? "Normal" : "Disabled", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
if (_setting == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_setting.ActionContent != null)
|
||||||
|
{
|
||||||
|
if (_setting.ActionContent.GetType() != typeof(Button))
|
||||||
|
{
|
||||||
|
// We do not want to override the default AutomationProperties.Name of a button. Its Content property already describes what it does.
|
||||||
|
if (!string.IsNullOrEmpty(_setting.Header))
|
||||||
|
{
|
||||||
|
AutomationProperties.SetName((UIElement)_setting.ActionContent, _setting.Header);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_setting._iconPresenter != null)
|
||||||
|
{
|
||||||
|
if (_setting.Icon == null)
|
||||||
|
{
|
||||||
|
_setting._iconPresenter.Visibility = Visibility.Collapsed;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_setting._iconPresenter.Visibility = Visibility.Visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_setting.Description == null)
|
||||||
|
{
|
||||||
|
_setting._descriptionPresenter.Visibility = Visibility.Collapsed;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_setting._descriptionPresenter.Visibility = Visibility.Visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
<ResourceDictionary
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.WinUI3.Controls">
|
||||||
|
|
||||||
|
<Style TargetType="controls:Setting">
|
||||||
|
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}"/>
|
||||||
|
<Setter Property="Background" Value="{ThemeResource CardBackgroundBrush}" />
|
||||||
|
<Setter Property="BorderThickness" Value="{ThemeResource CardBorderThickness}" />
|
||||||
|
<Setter Property="BorderBrush" Value="{ThemeResource CardStrokeColorDefaultBrush}" />
|
||||||
|
<Setter Property="IsTabStop" Value="False" />
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||||
|
<Setter Property="Padding" Value="16" />
|
||||||
|
<Setter Property="Margin" Value="0,0,0,0"/>
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="controls:Setting">
|
||||||
|
<Grid x:Name="RootGrid"
|
||||||
|
CornerRadius="{TemplateBinding CornerRadius}"
|
||||||
|
Background="{TemplateBinding Background}"
|
||||||
|
BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
|
Padding="{TemplateBinding Padding}"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
MinHeight="48">
|
||||||
|
<VisualStateManager.VisualStateGroups>
|
||||||
|
<VisualStateGroup x:Name="CommonStates">
|
||||||
|
<VisualState x:Name="Normal"/>
|
||||||
|
<VisualState x:Name="Disabled">
|
||||||
|
<VisualState.Setters>
|
||||||
|
<Setter Target="HeaderPresenter.Foreground" Value="{ThemeResource TextFillColorDisabledBrush}" />
|
||||||
|
<Setter Target="DescriptionPresenter.Foreground" Value="{ThemeResource TextFillColorDisabledBrush}" />
|
||||||
|
<Setter Target="IconPresenter.Foreground" Value="{ThemeResource TextFillColorDisabledBrush}" />
|
||||||
|
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource TextFillColorDisabledBrush}" />
|
||||||
|
</VisualState.Setters>
|
||||||
|
</VisualState>
|
||||||
|
</VisualStateGroup>
|
||||||
|
</VisualStateManager.VisualStateGroups>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<!-- Icon -->
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<!-- Header and subtitle -->
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<!-- Action control -->
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<ContentPresenter x:Name="IconPresenter"
|
||||||
|
Content="{TemplateBinding Icon}"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
FontSize="20"
|
||||||
|
Margin="2,0,18,0"
|
||||||
|
MaxWidth="26"
|
||||||
|
AutomationProperties.AccessibilityView="Raw"
|
||||||
|
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||||
|
Foreground="{ThemeResource CardPrimaryForegroundBrush}"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
|
|
||||||
|
<StackPanel
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Grid.Column="1"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
Margin="0,0,16,0">
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
x:Name="HeaderPresenter"
|
||||||
|
Text="{TemplateBinding Header}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Foreground="{ThemeResource CardPrimaryForegroundBrush}" />
|
||||||
|
|
||||||
|
<ContentPresenter
|
||||||
|
x:Name="DescriptionPresenter"
|
||||||
|
Content="{TemplateBinding Description}"
|
||||||
|
FontSize="{StaticResource SecondaryTextFontSize}"
|
||||||
|
TextWrapping="WrapWholeWords"
|
||||||
|
Foreground="{ThemeResource TextFillColorSecondaryBrush}">
|
||||||
|
<ContentPresenter.Resources>
|
||||||
|
<Style TargetType="TextBlock" BasedOn="{StaticResource CaptionTextBlockStyle}">
|
||||||
|
<Style.Setters>
|
||||||
|
<Setter Property="TextWrapping" Value="WrapWholeWords"/>
|
||||||
|
</Style.Setters>
|
||||||
|
</Style>
|
||||||
|
<Style TargetType="HyperlinkButton" BasedOn="{StaticResource TextButtonStyle}">
|
||||||
|
<Style.Setters>
|
||||||
|
<Setter Property="FontSize" Value="12"/>
|
||||||
|
<Setter Property="Padding" Value="0,0,0,0"/>
|
||||||
|
</Style.Setters>
|
||||||
|
</Style>
|
||||||
|
</ContentPresenter.Resources>
|
||||||
|
</ContentPresenter>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<ContentPresenter
|
||||||
|
x:Name="ContentPresenter"
|
||||||
|
Content="{TemplateBinding ActionContent}"
|
||||||
|
Grid.Column="2"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
HorizontalAlignment="Right" />
|
||||||
|
</Grid>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
</ResourceDictionary>
|
|
@ -0,0 +1,38 @@
|
||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Automation;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Controls
|
||||||
|
{
|
||||||
|
public partial class SettingExpander : Expander
|
||||||
|
{
|
||||||
|
public SettingExpander()
|
||||||
|
{
|
||||||
|
DefaultStyleKey = typeof(Expander);
|
||||||
|
this.Style = (Style)App.Current.Resources["SettingExpanderStyle"];
|
||||||
|
this.RegisterPropertyChangedCallback(Expander.HeaderProperty, OnHeaderChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnHeaderChanged(DependencyObject d, DependencyProperty dp)
|
||||||
|
{
|
||||||
|
SettingExpander self = (SettingExpander)d;
|
||||||
|
if (self.Header != null)
|
||||||
|
{
|
||||||
|
if (self.Header.GetType() == typeof(Setting))
|
||||||
|
{
|
||||||
|
Setting selfSetting = (Setting)self.Header;
|
||||||
|
selfSetting.Style = (Style)App.Current.Resources["ExpanderHeaderSettingStyle"];
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(selfSetting.Header))
|
||||||
|
{
|
||||||
|
AutomationProperties.SetName(self, selfSetting.Header);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System.ComponentModel;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Automation.Peers;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Controls
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a control that can contain multiple settings (or other) controls
|
||||||
|
/// </summary>
|
||||||
|
[TemplateVisualState(Name = "Normal", GroupName = "CommonStates")]
|
||||||
|
[TemplateVisualState(Name = "Disabled", GroupName = "CommonStates")]
|
||||||
|
public partial class SettingsGroup : ItemsControl
|
||||||
|
{
|
||||||
|
public SettingsGroup()
|
||||||
|
{
|
||||||
|
DefaultStyleKey = typeof(SettingsGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(
|
||||||
|
"Header",
|
||||||
|
typeof(string),
|
||||||
|
typeof(SettingsGroup),
|
||||||
|
new PropertyMetadata(default(string)));
|
||||||
|
|
||||||
|
[Localizable(true)]
|
||||||
|
public string Header
|
||||||
|
{
|
||||||
|
get => (string)GetValue(HeaderProperty);
|
||||||
|
set => SetValue(HeaderProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnApplyTemplate()
|
||||||
|
{
|
||||||
|
IsEnabledChanged -= SettingsGroup_IsEnabledChanged;
|
||||||
|
SetEnabledState();
|
||||||
|
IsEnabledChanged += SettingsGroup_IsEnabledChanged;
|
||||||
|
base.OnApplyTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SettingsGroup_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
SetEnabledState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetEnabledState()
|
||||||
|
{
|
||||||
|
VisualStateManager.GoToState(this, IsEnabled ? "Normal" : "Disabled", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override AutomationPeer OnCreateAutomationPeer()
|
||||||
|
{
|
||||||
|
return new SettingsGroupAutomationPeer(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
<ResourceDictionary
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.WinUI3.Controls">
|
||||||
|
|
||||||
|
<Style TargetType="controls:SettingsGroup">
|
||||||
|
<Setter Property="ItemsPanel">
|
||||||
|
<Setter.Value>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<StackPanel Orientation="Vertical"
|
||||||
|
Spacing="2"/>
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
<Setter Property="IsTabStop" Value="False" />
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="controls:SettingsGroup">
|
||||||
|
<Grid HorizontalAlignment="Stretch">
|
||||||
|
<VisualStateManager.VisualStateGroups>
|
||||||
|
<VisualStateGroup x:Name="CommonStates">
|
||||||
|
<VisualState x:Name="Normal"/>
|
||||||
|
<VisualState x:Name="Disabled">
|
||||||
|
<VisualState.Setters>
|
||||||
|
<Setter Target="HeaderPresenter.Foreground" Value="{ThemeResource TextFillColorDisabledBrush}" />
|
||||||
|
</VisualState.Setters>
|
||||||
|
</VisualState>
|
||||||
|
</VisualStateGroup>
|
||||||
|
</VisualStateManager.VisualStateGroups>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<TextBlock x:Name="HeaderPresenter"
|
||||||
|
Text="{TemplateBinding Header}"
|
||||||
|
Grid.Row="0"
|
||||||
|
Style="{ThemeResource BodyStrongTextBlockStyle}"
|
||||||
|
Margin="1,32,0,8"
|
||||||
|
AutomationProperties.HeadingLevel="Level2"/>
|
||||||
|
<ItemsPresenter Grid.Row="1"/>
|
||||||
|
</Grid>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
</ResourceDictionary>
|
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using Microsoft.UI.Xaml.Automation.Peers;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Controls
|
||||||
|
{
|
||||||
|
public class SettingsGroupAutomationPeer : FrameworkElementAutomationPeer
|
||||||
|
{
|
||||||
|
public SettingsGroupAutomationPeer(SettingsGroup owner)
|
||||||
|
: base(owner)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string GetNameCore()
|
||||||
|
{
|
||||||
|
var selectedSettingsGroup = (SettingsGroup)Owner;
|
||||||
|
return selectedSettingsGroup.Header;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Controls
|
||||||
|
{
|
||||||
|
public class PageLink
|
||||||
|
{
|
||||||
|
public string Text { get; set; }
|
||||||
|
|
||||||
|
public Uri Link { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
<UserControl
|
||||||
|
x:Class="Microsoft.PowerToys.Settings.UI.WinUI3.Controls.SettingsPageControl"
|
||||||
|
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.WinUI3.Controls"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:converters="using:CommunityToolkit.WinUI.UI.Converters"
|
||||||
|
xmlns:controls="using:CommunityToolkit.WinUI.UI.Controls"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
|
||||||
|
<UserControl.Resources>
|
||||||
|
<converters:DoubleToVisibilityConverter x:Name="doubleToVisibilityConverter" GreaterThan="0" TrueValue="Visible" FalseValue="Collapsed" />
|
||||||
|
</UserControl.Resources>
|
||||||
|
|
||||||
|
<Grid RowSpacing="24" Padding="20,0,0,0">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*"/>
|
||||||
|
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<TextBlock x:Name="Header"
|
||||||
|
Text="{x:Bind ModuleTitle}"
|
||||||
|
AutomationProperties.HeadingLevel="1"
|
||||||
|
Style="{StaticResource TitleTextBlockStyle}"
|
||||||
|
Margin="0,44,0,0"
|
||||||
|
VerticalAlignment="Stretch"/>
|
||||||
|
|
||||||
|
<ScrollViewer Grid.Row="1">
|
||||||
|
<Grid RowSpacing="24"
|
||||||
|
Padding="0,0,20,48" >
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition MaxWidth="1048" Width="*"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<!-- Top panel -->
|
||||||
|
<Grid ColumnSpacing="16">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="160"/>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Border CornerRadius="4" VerticalAlignment="Top">
|
||||||
|
<Image AutomationProperties.AccessibilityView="Raw">
|
||||||
|
<Image.Source>
|
||||||
|
<BitmapImage UriSource="{x:Bind ModuleImageSource}" />
|
||||||
|
</Image.Source>
|
||||||
|
</Image>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<StackPanel Grid.Column="1">
|
||||||
|
<TextBlock x:Name="AboutDescription"
|
||||||
|
Text="{x:Bind ModuleDescription}"
|
||||||
|
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||||
|
TextWrapping="Wrap"/>
|
||||||
|
|
||||||
|
<ItemsControl ItemsSource="{x:Bind PrimaryLinks}" IsTabStop="False" Margin="0,8,0,0">
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate x:DataType="local:PageLink">
|
||||||
|
<HyperlinkButton NavigateUri="{x:Bind Link}" Style="{StaticResource TextButtonStyle}">
|
||||||
|
<TextBlock Text="{x:Bind Text}" TextWrapping="Wrap" />
|
||||||
|
</HyperlinkButton>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
<ItemsControl.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<controls:WrapPanel Orientation="Horizontal" HorizontalSpacing="24"/>
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ItemsControl.ItemsPanel>
|
||||||
|
</ItemsControl>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<!-- Content panel -->
|
||||||
|
<ContentPresenter x:Name="ModuleContentPresenter"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
HorizontalContentAlignment="Stretch"
|
||||||
|
Content="{x:Bind ModuleContent}"
|
||||||
|
MaxWidth="1048"
|
||||||
|
Margin="0,12,0,0" Grid.Row="1"/>
|
||||||
|
|
||||||
|
<!-- Bottom panel -->
|
||||||
|
<StackPanel x:Name="SecondaryLinksPanel"
|
||||||
|
Grid.Row="2"
|
||||||
|
Visibility="{x:Bind SecondaryLinks.Count, Converter={StaticResource doubleToVisibilityConverter}}"
|
||||||
|
Orientation="Vertical">
|
||||||
|
<TextBlock Text="{x:Bind SecondaryLinksHeader}"
|
||||||
|
Style="{ThemeResource BodyStrongTextBlockStyle}"
|
||||||
|
Margin="2,8,0,0"
|
||||||
|
AutomationProperties.HeadingLevel="Level2"/>
|
||||||
|
|
||||||
|
<ItemsControl x:Name="SecondaryLinksItemControl" IsTabStop="False" Margin="2,0,0,0" ItemsSource="{x:Bind SecondaryLinks}">
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate x:DataType="local:PageLink">
|
||||||
|
<HyperlinkButton NavigateUri="{x:Bind Link}" Style="{StaticResource TextButtonStyle}">
|
||||||
|
<TextBlock Text="{x:Bind Text}" TextWrapping="Wrap" />
|
||||||
|
</HyperlinkButton>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
<ItemsControl.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<controls:WrapPanel Orientation="Horizontal" HorizontalSpacing="24"/>
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ItemsControl.ItemsPanel>
|
||||||
|
</ItemsControl>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</ScrollViewer>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
|
@ -0,0 +1,74 @@
|
||||||
|
// 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.ObjectModel;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Controls
|
||||||
|
{
|
||||||
|
public sealed partial class SettingsPageControl : UserControl
|
||||||
|
{
|
||||||
|
public SettingsPageControl()
|
||||||
|
{
|
||||||
|
this.InitializeComponent();
|
||||||
|
PrimaryLinks = new ObservableCollection<PageLink>();
|
||||||
|
SecondaryLinks = new ObservableCollection<PageLink>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ModuleTitle
|
||||||
|
{
|
||||||
|
get { return (string)GetValue(ModuleTitleProperty); }
|
||||||
|
set { SetValue(ModuleTitleProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ModuleDescription
|
||||||
|
{
|
||||||
|
get => (string)GetValue(ModuleDescriptionProperty);
|
||||||
|
set => SetValue(ModuleDescriptionProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ModuleImageSource
|
||||||
|
{
|
||||||
|
get => (string)GetValue(ModuleImageSourceProperty);
|
||||||
|
set => SetValue(ModuleImageSourceProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CA2227 // Collection properties should be read only
|
||||||
|
public ObservableCollection<PageLink> PrimaryLinks
|
||||||
|
#pragma warning restore CA2227 // Collection properties should be read only
|
||||||
|
{
|
||||||
|
get => (ObservableCollection<PageLink>)GetValue(PrimaryLinksProperty);
|
||||||
|
set => SetValue(PrimaryLinksProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string SecondaryLinksHeader
|
||||||
|
{
|
||||||
|
get { return (string)GetValue(SecondaryLinksHeaderProperty); }
|
||||||
|
set { SetValue(SecondaryLinksHeaderProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CA2227 // Collection properties should be read only
|
||||||
|
public ObservableCollection<PageLink> SecondaryLinks
|
||||||
|
#pragma warning restore CA2227 // Collection properties should be read only
|
||||||
|
{
|
||||||
|
get => (ObservableCollection<PageLink>)GetValue(SecondaryLinksProperty);
|
||||||
|
set => SetValue(SecondaryLinksProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ModuleContent
|
||||||
|
{
|
||||||
|
get { return (object)GetValue(ModuleContentProperty); }
|
||||||
|
set { SetValue(ModuleContentProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty ModuleTitleProperty = DependencyProperty.Register("ModuleTitle", typeof(string), typeof(SettingsPageControl), new PropertyMetadata(default(string)));
|
||||||
|
public static readonly DependencyProperty ModuleDescriptionProperty = DependencyProperty.Register("ModuleDescription", typeof(string), typeof(SettingsPageControl), new PropertyMetadata(default(string)));
|
||||||
|
public static readonly DependencyProperty ModuleImageSourceProperty = DependencyProperty.Register("ModuleImageSource", typeof(string), typeof(SettingsPageControl), new PropertyMetadata(default(string)));
|
||||||
|
public static readonly DependencyProperty PrimaryLinksProperty = DependencyProperty.Register("PrimaryLinks", typeof(ObservableCollection<PageLink>), typeof(SettingsPageControl), new PropertyMetadata(new ObservableCollection<PageLink>()));
|
||||||
|
public static readonly DependencyProperty SecondaryLinksHeaderProperty = DependencyProperty.Register("SecondaryLinksHeader", typeof(string), typeof(SettingsPageControl), new PropertyMetadata(default(string)));
|
||||||
|
public static readonly DependencyProperty SecondaryLinksProperty = DependencyProperty.Register("SecondaryLinks", typeof(ObservableCollection<PageLink>), typeof(SettingsPageControl), new PropertyMetadata(new ObservableCollection<PageLink>()));
|
||||||
|
public static readonly DependencyProperty ModuleContentProperty = DependencyProperty.Register("ModuleContent", typeof(object), typeof(SettingsPageControl), new PropertyMetadata(new Grid()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
<UserControl
|
||||||
|
x:Class="Microsoft.PowerToys.Settings.UI.WinUI3.Controls.ShortcutControl"
|
||||||
|
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.WinUI3.Controls"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
x:Name="LayoutRoot"
|
||||||
|
d:DesignHeight="300"
|
||||||
|
d:DesignWidth="400">
|
||||||
|
|
||||||
|
<Grid HorizontalAlignment="Right">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Button x:Name="EditButton"
|
||||||
|
Background="Transparent"
|
||||||
|
BorderBrush="Transparent"
|
||||||
|
Click="OpenDialogButton_Click" >
|
||||||
|
<StackPanel Orientation="Horizontal"
|
||||||
|
Spacing="16">
|
||||||
|
<ItemsControl x:Name="PreviewKeysControl"
|
||||||
|
IsEnabled="{Binding ElementName=EditButton, Path=IsEnabled}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
IsTabStop="False">
|
||||||
|
<ItemsControl.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<StackPanel Orientation="Horizontal" Spacing="4" />
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ItemsControl.ItemsPanel>
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<local:KeyVisual IsTabStop="False"
|
||||||
|
AutomationProperties.AccessibilityView="Raw"
|
||||||
|
VisualType="Small"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Content="{Binding}" />
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
<FontIcon Glyph=""
|
||||||
|
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||||
|
FontSize="14"
|
||||||
|
Margin="0,0,4,0" />
|
||||||
|
</StackPanel>
|
||||||
|
</Button>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
|
@ -0,0 +1,399 @@
|
||||||
|
// 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 Microsoft.PowerToys.Settings.UI.WinUI3.Helpers;
|
||||||
|
using Microsoft.PowerToys.Settings.UI.Library;
|
||||||
|
using Windows.ApplicationModel.Resources;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Automation;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using Microsoft.UI.Xaml.Input;
|
||||||
|
using Windows.System;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Controls
|
||||||
|
{
|
||||||
|
public sealed partial class ShortcutControl : UserControl, IDisposable
|
||||||
|
{
|
||||||
|
private readonly UIntPtr ignoreKeyEventFlag = (UIntPtr)0x5555;
|
||||||
|
private bool _shiftKeyDownOnEntering;
|
||||||
|
private bool _shiftToggled;
|
||||||
|
private bool _enabled;
|
||||||
|
private HotkeySettings hotkeySettings;
|
||||||
|
private HotkeySettings internalSettings;
|
||||||
|
private HotkeySettings lastValidSettings;
|
||||||
|
private HotkeySettingsControlHook hook;
|
||||||
|
private bool _isActive;
|
||||||
|
private bool disposedValue;
|
||||||
|
|
||||||
|
public string Header { get; set; }
|
||||||
|
|
||||||
|
public string Keys { get; set; }
|
||||||
|
|
||||||
|
public static readonly DependencyProperty IsActiveProperty = DependencyProperty.Register("Enabled", typeof(bool), typeof(ShortcutControl), null);
|
||||||
|
public static readonly DependencyProperty HotkeySettingsProperty = DependencyProperty.Register("HotkeySettings", typeof(HotkeySettings), typeof(ShortcutControl), null);
|
||||||
|
|
||||||
|
private ShortcutDialogContentControl c = new ShortcutDialogContentControl();
|
||||||
|
private ContentDialog shortcutDialog;
|
||||||
|
|
||||||
|
public bool Enabled
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
SetValue(IsActiveProperty, value);
|
||||||
|
_enabled = value;
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
EditButton.IsEnabled = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EditButton.IsEnabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public HotkeySettings HotkeySettings
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return hotkeySettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (hotkeySettings != value)
|
||||||
|
{
|
||||||
|
hotkeySettings = value;
|
||||||
|
SetValue(HotkeySettingsProperty, value);
|
||||||
|
PreviewKeysControl.ItemsSource = HotkeySettings.GetKeysList();
|
||||||
|
AutomationProperties.SetHelpText(EditButton, HotkeySettings.ToString());
|
||||||
|
c.Keys = HotkeySettings.GetKeysList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ShortcutControl()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
internalSettings = new HotkeySettings();
|
||||||
|
|
||||||
|
this.Unloaded += ShortcutControl_Unloaded;
|
||||||
|
hook = new HotkeySettingsControlHook(Hotkey_KeyDown, Hotkey_KeyUp, Hotkey_IsActive, FilterAccessibleKeyboardEvents);
|
||||||
|
ResourceLoader resourceLoader = ResourceLoader.GetForViewIndependentUse();
|
||||||
|
|
||||||
|
// We create the Dialog in C# because doing it in XAML is giving WinUI/XAML Island bugs when using dark theme.
|
||||||
|
shortcutDialog = new ContentDialog
|
||||||
|
{
|
||||||
|
XamlRoot = this.XamlRoot,
|
||||||
|
Title = resourceLoader.GetString("Activation_Shortcut_Title"),
|
||||||
|
Content = c,
|
||||||
|
PrimaryButtonText = resourceLoader.GetString("Activation_Shortcut_Save"),
|
||||||
|
CloseButtonText = resourceLoader.GetString("Activation_Shortcut_Cancel"),
|
||||||
|
DefaultButton = ContentDialogButton.Primary,
|
||||||
|
};
|
||||||
|
shortcutDialog.PrimaryButtonClick += ShortcutDialog_PrimaryButtonClick;
|
||||||
|
shortcutDialog.Opened += ShortcutDialog_Opened;
|
||||||
|
shortcutDialog.Closing += ShortcutDialog_Closing;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShortcutControl_Unloaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
shortcutDialog.PrimaryButtonClick -= ShortcutDialog_PrimaryButtonClick;
|
||||||
|
shortcutDialog.Opened -= ShortcutDialog_Opened;
|
||||||
|
shortcutDialog.Closing -= ShortcutDialog_Closing;
|
||||||
|
|
||||||
|
// Dispose the HotkeySettingsControlHook object to terminate the hook threads when the textbox is unloaded
|
||||||
|
hook.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void KeyEventHandler(int key, bool matchValue, int matchValueCode)
|
||||||
|
{
|
||||||
|
switch ((VirtualKey)key)
|
||||||
|
{
|
||||||
|
case VirtualKey.LeftWindows:
|
||||||
|
case VirtualKey.RightWindows:
|
||||||
|
internalSettings.Win = matchValue;
|
||||||
|
break;
|
||||||
|
case VirtualKey.Control:
|
||||||
|
case VirtualKey.LeftControl:
|
||||||
|
case VirtualKey.RightControl:
|
||||||
|
internalSettings.Ctrl = matchValue;
|
||||||
|
break;
|
||||||
|
case VirtualKey.Menu:
|
||||||
|
case VirtualKey.LeftMenu:
|
||||||
|
case VirtualKey.RightMenu:
|
||||||
|
internalSettings.Alt = matchValue;
|
||||||
|
break;
|
||||||
|
case VirtualKey.Shift:
|
||||||
|
case VirtualKey.LeftShift:
|
||||||
|
case VirtualKey.RightShift:
|
||||||
|
_shiftToggled = true;
|
||||||
|
internalSettings.Shift = matchValue;
|
||||||
|
break;
|
||||||
|
case VirtualKey.Escape:
|
||||||
|
internalSettings = new HotkeySettings();
|
||||||
|
shortcutDialog.IsPrimaryButtonEnabled = false;
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
internalSettings.Code = matchValueCode;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to send a single key event to the system which would be ignored by the hotkey control.
|
||||||
|
private void SendSingleKeyboardInput(short keyCode, uint keyStatus)
|
||||||
|
{
|
||||||
|
NativeKeyboardHelper.INPUT inputShift = new NativeKeyboardHelper.INPUT
|
||||||
|
{
|
||||||
|
type = NativeKeyboardHelper.INPUTTYPE.INPUT_KEYBOARD,
|
||||||
|
data = new NativeKeyboardHelper.InputUnion
|
||||||
|
{
|
||||||
|
ki = new NativeKeyboardHelper.KEYBDINPUT
|
||||||
|
{
|
||||||
|
wVk = keyCode,
|
||||||
|
dwFlags = keyStatus,
|
||||||
|
|
||||||
|
// Any keyevent with the extraInfo set to this value will be ignored by the keyboard hook and sent to the system instead.
|
||||||
|
dwExtraInfo = ignoreKeyEventFlag,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
NativeKeyboardHelper.INPUT[] inputs = new NativeKeyboardHelper.INPUT[] { inputShift };
|
||||||
|
|
||||||
|
_ = NativeMethods.SendInput(1, inputs, NativeKeyboardHelper.INPUT.Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool FilterAccessibleKeyboardEvents(int key, UIntPtr extraInfo)
|
||||||
|
{
|
||||||
|
// A keyboard event sent with this value in the extra Information field should be ignored by the hook so that it can be captured by the system instead.
|
||||||
|
if (extraInfo == ignoreKeyEventFlag)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the current key press is tab, based on the other keys ignore the key press so as to shift focus out of the hotkey control.
|
||||||
|
if ((VirtualKey)key == VirtualKey.Tab)
|
||||||
|
{
|
||||||
|
// Shift was not pressed while entering and Shift is not pressed while leaving the hotkey control, treat it as a normal tab key press.
|
||||||
|
if (!internalSettings.Shift && !_shiftKeyDownOnEntering && !internalSettings.Win && !internalSettings.Alt && !internalSettings.Ctrl)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shift was not pressed while entering but it was pressed while leaving the hotkey, therefore simulate a shift key press as the system does not know about shift being pressed in the hotkey.
|
||||||
|
else if (internalSettings.Shift && !_shiftKeyDownOnEntering && !internalSettings.Win && !internalSettings.Alt && !internalSettings.Ctrl)
|
||||||
|
{
|
||||||
|
// This is to reset the shift key press within the control as it was not used within the control but rather was used to leave the hotkey.
|
||||||
|
internalSettings.Shift = false;
|
||||||
|
|
||||||
|
SendSingleKeyboardInput((short)VirtualKey.Shift, (uint)NativeKeyboardHelper.KeyEventF.KeyDown);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shift was pressed on entering and remained pressed, therefore only ignore the tab key so that it can be passed to the system.
|
||||||
|
// As the shift key is already assumed to be pressed by the system while it entered the hotkey control, shift would still remain pressed, hence ignoring the tab input would simulate a Shift+Tab key press.
|
||||||
|
else if (!internalSettings.Shift && _shiftKeyDownOnEntering && !_shiftToggled && !internalSettings.Win && !internalSettings.Alt && !internalSettings.Ctrl)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shift was pressed on entering but it was released and later pressed again.
|
||||||
|
// Ignore the tab key and the system already has the shift key pressed, therefore this would simulate Shift+Tab.
|
||||||
|
// However, since the last shift key was only used to move out of the control, reset the status of shift within the control.
|
||||||
|
else if (internalSettings.Shift && _shiftKeyDownOnEntering && _shiftToggled && !internalSettings.Win && !internalSettings.Alt && !internalSettings.Ctrl)
|
||||||
|
{
|
||||||
|
internalSettings.Shift = false;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shift was pressed on entering and was later released.
|
||||||
|
// The system still has shift in the key pressed status, therefore pass a Shift KeyUp message to the system, to release the shift key, therefore simulating only the Tab key press.
|
||||||
|
else if (!internalSettings.Shift && _shiftKeyDownOnEntering && _shiftToggled && !internalSettings.Win && !internalSettings.Alt && !internalSettings.Ctrl)
|
||||||
|
{
|
||||||
|
SendSingleKeyboardInput((short)VirtualKey.Shift, (uint)NativeKeyboardHelper.KeyEventF.KeyUp);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Either the cancel or save button has keyboard focus.
|
||||||
|
if (FocusManager.GetFocusedElement(LayoutRoot.XamlRoot).GetType() == typeof(Button))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Hotkey_KeyDown(int key)
|
||||||
|
{
|
||||||
|
KeyEventHandler(key, true, key);
|
||||||
|
|
||||||
|
c.Keys = internalSettings.GetKeysList();
|
||||||
|
|
||||||
|
if (internalSettings.GetKeysList().Count == 0)
|
||||||
|
{
|
||||||
|
// Empty, disable save button
|
||||||
|
shortcutDialog.IsPrimaryButtonEnabled = false;
|
||||||
|
}
|
||||||
|
else if (internalSettings.GetKeysList().Count == 1)
|
||||||
|
{
|
||||||
|
// 1 key, disable save button
|
||||||
|
shortcutDialog.IsPrimaryButtonEnabled = false;
|
||||||
|
|
||||||
|
// Check if the one key is a hotkey
|
||||||
|
if (internalSettings.Shift || internalSettings.Win || internalSettings.Alt || internalSettings.Ctrl)
|
||||||
|
{
|
||||||
|
c.IsError = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c.IsError = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tab and Shift+Tab are accessible keys and should not be displayed in the hotkey control.
|
||||||
|
if (internalSettings.Code > 0 && !internalSettings.IsAccessibleShortcut())
|
||||||
|
{
|
||||||
|
lastValidSettings = internalSettings.Clone();
|
||||||
|
|
||||||
|
if (!ComboIsValid(lastValidSettings))
|
||||||
|
{
|
||||||
|
DisableKeys();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EnableKeys();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EnableKeys()
|
||||||
|
{
|
||||||
|
shortcutDialog.IsPrimaryButtonEnabled = true;
|
||||||
|
c.IsError = false;
|
||||||
|
|
||||||
|
// WarningLabel.Style = (Style)App.Current.Resources["SecondaryTextStyle"];
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DisableKeys()
|
||||||
|
{
|
||||||
|
shortcutDialog.IsPrimaryButtonEnabled = false;
|
||||||
|
c.IsError = true;
|
||||||
|
|
||||||
|
// WarningLabel.Style = (Style)App.Current.Resources["SecondaryWarningTextStyle"];
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Hotkey_KeyUp(int key)
|
||||||
|
{
|
||||||
|
KeyEventHandler(key, false, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool Hotkey_IsActive()
|
||||||
|
{
|
||||||
|
return _isActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CA1801 // Review unused parameters
|
||||||
|
private void ShortcutDialog_Opened(ContentDialog sender, ContentDialogOpenedEventArgs args)
|
||||||
|
#pragma warning restore CA1801 // Review unused parameters
|
||||||
|
{
|
||||||
|
if (!ComboIsValid(hotkeySettings))
|
||||||
|
{
|
||||||
|
DisableKeys();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EnableKeys();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the status on entering the hotkey each time.
|
||||||
|
_shiftKeyDownOnEntering = false;
|
||||||
|
_shiftToggled = false;
|
||||||
|
|
||||||
|
// To keep track of the shift key, whether it was pressed on entering.
|
||||||
|
if ((NativeMethods.GetAsyncKeyState((int)VirtualKey.Shift) & 0x8000) != 0)
|
||||||
|
{
|
||||||
|
_shiftKeyDownOnEntering = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_isActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void OpenDialogButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
c.Keys = null;
|
||||||
|
c.Keys = HotkeySettings.GetKeysList();
|
||||||
|
|
||||||
|
shortcutDialog.XamlRoot = this.XamlRoot;
|
||||||
|
await shortcutDialog.ShowAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CA1801 // Review unused parameters
|
||||||
|
private void ShortcutDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
|
||||||
|
#pragma warning restore CA1801 // Review unused parameters
|
||||||
|
{
|
||||||
|
if (ComboIsValid(lastValidSettings))
|
||||||
|
{
|
||||||
|
HotkeySettings = lastValidSettings.Clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
PreviewKeysControl.ItemsSource = hotkeySettings.GetKeysList();
|
||||||
|
AutomationProperties.SetHelpText(EditButton, HotkeySettings.ToString());
|
||||||
|
shortcutDialog.Hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool ComboIsValid(HotkeySettings settings)
|
||||||
|
{
|
||||||
|
if (settings != null && (settings.IsValid() || settings.IsEmpty()))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CA1801 // Review unused parameters
|
||||||
|
private void ShortcutDialog_Closing(ContentDialog sender, ContentDialogClosingEventArgs args)
|
||||||
|
#pragma warning restore CA1801 // Review unused parameters
|
||||||
|
{
|
||||||
|
_isActive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (!disposedValue)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
// TODO: dispose managed state (managed objects)
|
||||||
|
hook.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: free unmanaged resources (unmanaged objects) and override finalizer
|
||||||
|
// TODO: set large fields to null
|
||||||
|
disposedValue = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||||
|
Dispose(disposing: true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
<UserControl
|
||||||
|
x:Class="Microsoft.PowerToys.Settings.UI.WinUI3.Controls.ShortcutDialogContentControl"
|
||||||
|
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.WinUI3.Controls"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:toolkitcontrols="using:CommunityToolkit.WinUI.UI.Controls"
|
||||||
|
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
||||||
|
xmlns:converters="using:CommunityToolkit.WinUI.UI.Converters"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
x:Name="ShortcutContentControl">
|
||||||
|
<UserControl.Resources>
|
||||||
|
<converters:BoolToVisibilityConverter x:Key="boolToVisibilityConverter" FalseValue="Collapsed" TrueValue="Visible" />
|
||||||
|
</UserControl.Resources>
|
||||||
|
<Grid MinWidth="498" MinHeight="220">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition MinHeight="110"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<TextBlock x:Uid="Activation_Shortcut_Description" Grid.Row="0" />
|
||||||
|
|
||||||
|
<ItemsControl x:Name="KeysControl"
|
||||||
|
Height="56"
|
||||||
|
Grid.Row="1"
|
||||||
|
Margin="0,64,0,0"
|
||||||
|
HorizontalContentAlignment="Center"
|
||||||
|
ItemsSource="{x:Bind Keys, Mode=OneWay}"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Top">
|
||||||
|
<ItemsControl.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<StackPanel Orientation="Horizontal" Spacing="8"/>
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ItemsControl.ItemsPanel>
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<local:KeyVisual AutomationProperties.AccessibilityView="Raw"
|
||||||
|
Height="56"
|
||||||
|
VisualType="Large"
|
||||||
|
IsError="{Binding ElementName=ShortcutContentControl, Path=IsError, Mode=OneWay}"
|
||||||
|
IsTabStop="False"
|
||||||
|
Content="{Binding}" />
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
|
||||||
|
<StackPanel Orientation="Vertical"
|
||||||
|
Grid.Row="2"
|
||||||
|
Spacing="8"
|
||||||
|
|
||||||
|
Margin="0,24,0,0"
|
||||||
|
VerticalAlignment="Top">
|
||||||
|
<Grid Height="36">
|
||||||
|
|
||||||
|
<Border x:Name="WarningBanner"
|
||||||
|
Background="{ThemeResource InfoBarErrorSeverityBackgroundBrush}"
|
||||||
|
CornerRadius="{ThemeResource ControlCornerRadius}"
|
||||||
|
BorderBrush="{ThemeResource InfoBarBorderBrush}"
|
||||||
|
BorderThickness="{ThemeResource InfoBarBorderThickness}"
|
||||||
|
Padding="8"
|
||||||
|
Margin="-2,0,0,0"
|
||||||
|
Visibility="{Binding ElementName=ShortcutContentControl, Path=IsError, Mode=OneWay, Converter={StaticResource boolToVisibilityConverter}}">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<!--TODO(stefan) InfoBadge not available
|
||||||
|
<muxc:InfoBadge AutomationProperties.AccessibilityView="Raw"
|
||||||
|
Margin="2,0,12,0"
|
||||||
|
Style="{StaticResource CriticalIconInfoBadgeStyle}" />
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<TextBlock x:Name="InvalidShortcutWarningLabel"
|
||||||
|
x:Uid="InvalidShortcut"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Margin="0,-1,0,0"
|
||||||
|
Foreground="{ThemeResource InfoBarTitleForeground}"
|
||||||
|
FontWeight="{ThemeResource InfoBarTitleFontWeight}"
|
||||||
|
Grid.Column="1" />
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
|
<toolkitcontrols:MarkdownTextBlock x:Uid="InvalidShortcutWarningLabel"
|
||||||
|
FontSize="12"
|
||||||
|
Background="Transparent"
|
||||||
|
Foreground="{ThemeResource TextFillColorSecondaryBrush}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
|
@ -0,0 +1,36 @@
|
||||||
|
// 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 Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Controls
|
||||||
|
{
|
||||||
|
public sealed partial class ShortcutDialogContentControl : UserControl
|
||||||
|
{
|
||||||
|
public ShortcutDialogContentControl()
|
||||||
|
{
|
||||||
|
this.InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CA2227 // Collection properties should be read only
|
||||||
|
public List<object> Keys
|
||||||
|
#pragma warning restore CA2227 // Collection properties should be read only
|
||||||
|
{
|
||||||
|
get { return (List<object>)GetValue(KeysProperty); }
|
||||||
|
set { SetValue(KeysProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty KeysProperty = DependencyProperty.Register("Keys", typeof(List<object>), typeof(SettingsPageControl), new PropertyMetadata(default(string)));
|
||||||
|
|
||||||
|
public bool IsError
|
||||||
|
{
|
||||||
|
get => (bool)GetValue(IsErrorProperty);
|
||||||
|
set => SetValue(IsErrorProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty IsErrorProperty = DependencyProperty.Register("IsError", typeof(bool), typeof(ShortcutDialogContentControl), new PropertyMetadata(false));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
<UserControl
|
||||||
|
x:Class="Microsoft.PowerToys.Settings.UI.WinUI3.Controls.ShortcutWithTextLabelControl"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.WinUI3.Controls"
|
||||||
|
xmlns:toolkitcontrols="using:CommunityToolkit.WinUI.UI.Controls"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
d:DesignHeight="300"
|
||||||
|
d:DesignWidth="400">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<ItemsControl AutomationProperties.AccessibilityView="Raw"
|
||||||
|
ItemsSource="{x:Bind Keys}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
IsTabStop="False">
|
||||||
|
<ItemsControl.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<StackPanel Orientation="Horizontal" Spacing="4" />
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ItemsControl.ItemsPanel>
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<controls:KeyVisual IsTabStop="False"
|
||||||
|
AutomationProperties.AccessibilityView="Raw"
|
||||||
|
VisualType="SmallOutline"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Content="{Binding}" />
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
<toolkitcontrols:MarkdownTextBlock Background="Transparent"
|
||||||
|
Text="{x:Bind Text}"
|
||||||
|
Margin="8,0,0,0"
|
||||||
|
Grid.Column="1"
|
||||||
|
VerticalAlignment="Center" />
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
|
@ -0,0 +1,36 @@
|
||||||
|
// 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 Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Controls
|
||||||
|
{
|
||||||
|
public sealed partial class ShortcutWithTextLabelControl : UserControl
|
||||||
|
{
|
||||||
|
public string Text
|
||||||
|
{
|
||||||
|
get { return (string)GetValue(TextProperty); }
|
||||||
|
set { SetValue(TextProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(ShortcutWithTextLabelControl), new PropertyMetadata(default(string)));
|
||||||
|
|
||||||
|
#pragma warning disable CA2227 // Collection properties should be read only
|
||||||
|
public List<object> Keys
|
||||||
|
#pragma warning restore CA2227 // Collection properties should be read only
|
||||||
|
{
|
||||||
|
get { return (List<object>)GetValue(KeysProperty); }
|
||||||
|
set { SetValue(KeysProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty KeysProperty = DependencyProperty.Register("Keys", typeof(List<object>), typeof(ShortcutWithTextLabelControl), new PropertyMetadata(default(string)));
|
||||||
|
|
||||||
|
public ShortcutWithTextLabelControl()
|
||||||
|
{
|
||||||
|
this.InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
// 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 Microsoft.PowerToys.Settings.UI.Library;
|
||||||
|
using Microsoft.UI.Xaml.Data;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Converters
|
||||||
|
{
|
||||||
|
public sealed class AwakeModeToIntConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
var mode = (AwakeMode)value;
|
||||||
|
return (int)mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
return (AwakeMode)Enum.ToObject(typeof(AwakeMode), (int)value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using Windows.ApplicationModel.Resources;
|
||||||
|
using Microsoft.UI.Xaml.Data;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Converters
|
||||||
|
{
|
||||||
|
public sealed class ImageResizerFitToStringConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
var toLower = false;
|
||||||
|
if ((string)parameter == "ToLower")
|
||||||
|
{
|
||||||
|
toLower = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
string targetValue = string.Empty;
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case 0: targetValue = ResourceLoader.GetForViewIndependentUse().GetString("ImageResizer_Fit_Fill_ThirdPersonSingular"); break;
|
||||||
|
case 1: targetValue = ResourceLoader.GetForViewIndependentUse().GetString("ImageResizer_Fit_Fit_ThirdPersonSingular"); break;
|
||||||
|
case 2: targetValue = ResourceLoader.GetForViewIndependentUse().GetString("ImageResizer_Fit_Stretch_ThirdPersonSingular"); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toLower)
|
||||||
|
{
|
||||||
|
targetValue = targetValue.ToLower(CultureInfo.CurrentCulture);
|
||||||
|
}
|
||||||
|
|
||||||
|
return targetValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using Windows.ApplicationModel.Resources;
|
||||||
|
using Microsoft.UI.Xaml.Data;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Converters
|
||||||
|
{
|
||||||
|
public sealed class ImageResizerUnitToStringConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
var toLower = false;
|
||||||
|
if ((string)parameter == "ToLower")
|
||||||
|
{
|
||||||
|
toLower = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
string targetValue = string.Empty;
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case 0: targetValue = ResourceLoader.GetForViewIndependentUse().GetString("ImageResizer_Unit_Centimeter"); break;
|
||||||
|
case 1: targetValue = ResourceLoader.GetForViewIndependentUse().GetString("ImageResizer_Unit_Inch"); break;
|
||||||
|
case 2: targetValue = ResourceLoader.GetForViewIndependentUse().GetString("ImageResizer_Unit_Percent"); break;
|
||||||
|
case 3: targetValue = ResourceLoader.GetForViewIndependentUse().GetString("ImageResizer_Unit_Pixel"); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toLower)
|
||||||
|
{
|
||||||
|
targetValue = targetValue.ToLower(CultureInfo.CurrentCulture);
|
||||||
|
}
|
||||||
|
|
||||||
|
return targetValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
// 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 Microsoft.UI.Xaml.Data;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Converters
|
||||||
|
{
|
||||||
|
public sealed class UpdateStateToBoolConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
if (value == null || parameter == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (value.ToString() == (string)parameter)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Helpers
|
||||||
|
{
|
||||||
|
internal static class NativeKeyboardHelper
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")]
|
||||||
|
internal struct INPUT
|
||||||
|
{
|
||||||
|
internal INPUTTYPE type;
|
||||||
|
internal InputUnion data;
|
||||||
|
|
||||||
|
internal static int Size
|
||||||
|
{
|
||||||
|
get { return Marshal.SizeOf(typeof(INPUT)); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")]
|
||||||
|
internal struct InputUnion
|
||||||
|
{
|
||||||
|
[FieldOffset(0)]
|
||||||
|
internal MOUSEINPUT mi;
|
||||||
|
[FieldOffset(0)]
|
||||||
|
internal KEYBDINPUT ki;
|
||||||
|
[FieldOffset(0)]
|
||||||
|
internal HARDWAREINPUT hi;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")]
|
||||||
|
internal struct MOUSEINPUT
|
||||||
|
{
|
||||||
|
internal int dx;
|
||||||
|
internal int dy;
|
||||||
|
internal int mouseData;
|
||||||
|
internal uint dwFlags;
|
||||||
|
internal uint time;
|
||||||
|
internal UIntPtr dwExtraInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")]
|
||||||
|
internal struct KEYBDINPUT
|
||||||
|
{
|
||||||
|
internal short wVk;
|
||||||
|
internal short wScan;
|
||||||
|
internal uint dwFlags;
|
||||||
|
internal int time;
|
||||||
|
internal UIntPtr dwExtraInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")]
|
||||||
|
internal struct HARDWAREINPUT
|
||||||
|
{
|
||||||
|
internal int uMsg;
|
||||||
|
internal short wParamL;
|
||||||
|
internal short wParamH;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum INPUTTYPE : uint
|
||||||
|
{
|
||||||
|
INPUT_MOUSE = 0,
|
||||||
|
INPUT_KEYBOARD = 1,
|
||||||
|
INPUT_HARDWARE = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
internal enum KeyEventF
|
||||||
|
{
|
||||||
|
KeyDown = 0x0000,
|
||||||
|
ExtendedKey = 0x0001,
|
||||||
|
KeyUp = 0x0002,
|
||||||
|
Unicode = 0x0004,
|
||||||
|
Scancode = 0x0008,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Helpers
|
||||||
|
{
|
||||||
|
public static class NativeMethods
|
||||||
|
{
|
||||||
|
private const int GWL_STYLE = -16;
|
||||||
|
private const int WS_POPUP = 1 << 31; // 0x80000000
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
internal static extern uint SendInput(uint nInputs, NativeKeyboardHelper.INPUT[] pInputs, int cbSize);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
|
||||||
|
internal static extern short GetAsyncKeyState(int vKey);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
|
internal static extern int GetWindowLong(IntPtr hWnd, int nIndex);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
internal static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
|
||||||
|
|
||||||
|
#pragma warning disable CA1401 // P/Invokes should not be visible
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern bool ShowWindow(System.IntPtr hWnd, int nCmdShow);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern bool AllowSetForegroundWindow(int dwProcessId);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
|
||||||
|
public static extern IntPtr LoadLibrary(string dllToLoad);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
|
||||||
|
public static extern bool FreeLibrary(IntPtr hModule);
|
||||||
|
#pragma warning restore CA1401 // P/Invokes should not be visible
|
||||||
|
|
||||||
|
public static void SetPopupStyle(IntPtr hwnd)
|
||||||
|
{
|
||||||
|
_ = SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) | WS_POPUP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 Microsoft.UI.Xaml.Controls;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Helpers
|
||||||
|
{
|
||||||
|
public static class NavHelper
|
||||||
|
{
|
||||||
|
// This helper class allows to specify the page that will be shown when you click on a NavigationViewItem
|
||||||
|
//
|
||||||
|
// Usage in xaml:
|
||||||
|
// <winui:NavigationViewItem x:Uid="Shell_Main" Icon="Document" helpers:NavHelper.NavigateTo="views:MainPage" />
|
||||||
|
//
|
||||||
|
// Usage in code:
|
||||||
|
// NavHelper.SetNavigateTo(navigationViewItem, typeof(MainPage));
|
||||||
|
public static Type GetNavigateTo(NavigationViewItem item)
|
||||||
|
{
|
||||||
|
return (Type)item?.GetValue(NavigateToProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetNavigateTo(NavigationViewItem item, Type value)
|
||||||
|
{
|
||||||
|
item?.SetValue(NavigateToProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty NavigateToProperty =
|
||||||
|
DependencyProperty.RegisterAttached("NavigateTo", typeof(Type), typeof(NavHelper), new PropertyMetadata(null));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Helpers
|
||||||
|
{
|
||||||
|
public class Observable : INotifyPropertyChanged
|
||||||
|
{
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
|
protected void Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
|
||||||
|
{
|
||||||
|
if (Equals(storage, value))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
storage = value;
|
||||||
|
OnPropertyChanged(propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Windows.Input;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Helpers
|
||||||
|
{
|
||||||
|
public class RelayCommand : ICommand
|
||||||
|
{
|
||||||
|
private readonly Action _execute;
|
||||||
|
private readonly Func<bool> _canExecute;
|
||||||
|
|
||||||
|
public event EventHandler CanExecuteChanged;
|
||||||
|
|
||||||
|
public RelayCommand(Action execute)
|
||||||
|
: this(execute, null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public RelayCommand(Action execute, Func<bool> canExecute)
|
||||||
|
{
|
||||||
|
_execute = execute ?? throw new ArgumentNullException(nameof(execute));
|
||||||
|
_canExecute = canExecute;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CanExecute(object parameter) => _canExecute == null || _canExecute();
|
||||||
|
|
||||||
|
public void Execute(object parameter) => _execute();
|
||||||
|
|
||||||
|
public void OnCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "abstract T and abstract")]
|
||||||
|
public class RelayCommand<T> : ICommand
|
||||||
|
{
|
||||||
|
private readonly Action<T> execute;
|
||||||
|
|
||||||
|
private readonly Func<T, bool> canExecute;
|
||||||
|
|
||||||
|
public event EventHandler CanExecuteChanged;
|
||||||
|
|
||||||
|
public RelayCommand(Action<T> execute)
|
||||||
|
: this(execute, null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public RelayCommand(Action<T> execute, Func<T, bool> canExecute)
|
||||||
|
{
|
||||||
|
this.execute = execute ?? throw new ArgumentNullException(nameof(execute));
|
||||||
|
this.canExecute = canExecute;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CanExecute(object parameter) => canExecute == null || canExecute((T)parameter);
|
||||||
|
|
||||||
|
public void Execute(object parameter) => execute((T)parameter);
|
||||||
|
|
||||||
|
public void OnCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
// 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 Windows.ApplicationModel.Resources;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Helpers
|
||||||
|
{
|
||||||
|
internal static class ResourceExtensions
|
||||||
|
{
|
||||||
|
private static readonly ResourceLoader ResLoader = new ResourceLoader();
|
||||||
|
|
||||||
|
public static string GetLocalized(this string resourceKey)
|
||||||
|
{
|
||||||
|
return ResLoader.GetString(resourceKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
// 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.Diagnostics;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3.Helpers
|
||||||
|
{
|
||||||
|
public static class StartProcessHelper
|
||||||
|
{
|
||||||
|
public const string ColorsSettings = "ms-settings:colors";
|
||||||
|
|
||||||
|
public static void Start(string process)
|
||||||
|
{
|
||||||
|
Process.Start(new ProcessStartInfo(process) { UseShellExecute = true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
// 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.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3
|
||||||
|
{
|
||||||
|
[ComImport]
|
||||||
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
|
[Guid("45D64A29-A63E-4CB6-B498-5781D298CB4F")]
|
||||||
|
internal interface ICoreWindowInterop
|
||||||
|
{
|
||||||
|
System.IntPtr WindowHandle { get; }
|
||||||
|
|
||||||
|
void MessageHandled(bool value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
// 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.Runtime.InteropServices;
|
||||||
|
|
||||||
|
using WinCore = Windows.UI.Core;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3
|
||||||
|
{
|
||||||
|
internal static class Interop
|
||||||
|
{
|
||||||
|
public static ICoreWindowInterop GetInterop(this WinCore.CoreWindow @this)
|
||||||
|
{
|
||||||
|
var unkIntPtr = Marshal.GetIUnknownForObject(@this);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var interopObj = Marshal.GetTypedObjectForIUnknown(unkIntPtr, typeof(ICoreWindowInterop)) as ICoreWindowInterop;
|
||||||
|
return interopObj;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Marshal.Release(unkIntPtr);
|
||||||
|
unkIntPtr = System.IntPtr.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Interop naming consistency")]
|
||||||
|
public const int SW_HIDE = 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"Projects": [
|
||||||
|
{
|
||||||
|
"LanguageSet": "Azure_Languages",
|
||||||
|
"LocItems": [
|
||||||
|
{
|
||||||
|
"SourceFile": "src\\settings-ui\\Microsoft.PowerToys.Settings.UI.WinUI3\\Strings\\en-us\\Resources.resw",
|
||||||
|
"CopyOption": "LangIDOnName",
|
||||||
|
"OutputPath": "src\\settings-ui\\Microsoft.PowerToys.Settings.UI.WinUI3\\Strings"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
<Window
|
||||||
|
x:Class="Microsoft.PowerToys.Settings.UI.WinUI3.MainWindow"
|
||||||
|
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.WinUI3.Views"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="36"/>
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<StackPanel x:Name="CustomTitleBar" Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Stretch">
|
||||||
|
<Image Source="ms-appx:///Assets/FluentIcons/FluentIconsPowerToys.png" Width="16" />
|
||||||
|
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" Margin="12,0,0,0" Text="PowerToys" />
|
||||||
|
</StackPanel>
|
||||||
|
<local:ShellPage Grid.Row="1"/>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
|
@ -0,0 +1,84 @@
|
||||||
|
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
|
||||||
|
using Microsoft.PowerToys.Settings.UI.WinUI3.Views;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using System;
|
||||||
|
using Windows.Data.Json;
|
||||||
|
using Windows.ApplicationModel.Resources;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
|
||||||
|
// To learn more about WinUI, the WinUI project structure,
|
||||||
|
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.Settings.UI.WinUI3
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An empty window that can be used on its own or navigated to within a Frame.
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class MainWindow : Window
|
||||||
|
{
|
||||||
|
public MainWindow()
|
||||||
|
{
|
||||||
|
this.InitializeComponent();
|
||||||
|
ExtendsContentIntoTitleBar = true;
|
||||||
|
SetTitleBar(CustomTitleBar); // This should work according to docs, but it doesn't.... So disabling for now together with ExtendsContentIntoTitleBar
|
||||||
|
|
||||||
|
// send IPC Message
|
||||||
|
ShellPage.SetDefaultSndMessageCallback(msg =>
|
||||||
|
{
|
||||||
|
// IPC Manager is null when launching runner directly
|
||||||
|
App.GetTwoWayIPCManager()?.Send(msg);
|
||||||
|
});
|
||||||
|
|
||||||
|
// send IPC Message
|
||||||
|
ShellPage.SetRestartAdminSndMessageCallback(msg =>
|
||||||
|
{
|
||||||
|
App.GetTwoWayIPCManager()?.Send(msg);
|
||||||
|
Environment.Exit(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
// send IPC Message
|
||||||
|
ShellPage.SetCheckForUpdatesMessageCallback(msg =>
|
||||||
|
{
|
||||||
|
App.GetTwoWayIPCManager()?.Send(msg);
|
||||||
|
});
|
||||||
|
|
||||||
|
// open oobe
|
||||||
|
ShellPage.SetOpenOobeCallback(() =>
|
||||||
|
{
|
||||||
|
/* var oobe = new OobeWindow();
|
||||||
|
oobe.Show();
|
||||||
|
*/ });
|
||||||
|
|
||||||
|
// receive IPC Message
|
||||||
|
App.IPCMessageReceivedCallback = (string msg) =>
|
||||||
|
{
|
||||||
|
if (ShellPage.ShellHandler.IPCResponseHandleList != null)
|
||||||
|
{
|
||||||
|
var success = JsonObject.TryParse(msg, out JsonObject json);
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
foreach (Action<JsonObject> handle in ShellPage.ShellHandler.IPCResponseHandleList)
|
||||||
|
{
|
||||||
|
handle(json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger.LogError("Failed to parse JSON from IPC message.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ShellPage.SetElevationStatus(App.IsElevated);
|
||||||
|
ShellPage.SetIsUserAnAdmin(App.IsUserAnAdmin);
|
||||||
|
//shellPage.Refresh();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void NavigateToSection(Type type)
|
||||||
|
{
|
||||||
|
Activate();
|
||||||
|
ShellPage.Navigate(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<TargetFramework>net5.0-windows10.0.19041.0</TargetFramework>
|
||||||
|
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||||
|
<RootNamespace>Microsoft.PowerToys.Settings.UI.WinUI3</RootNamespace>
|
||||||
|
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||||
|
<Platforms>x64;</Platforms>
|
||||||
|
<RuntimeIdentifiers>win10-x64;</RuntimeIdentifiers>
|
||||||
|
<PublishProfile>win10-$(Platform).pubxml</PublishProfile>
|
||||||
|
<UseWinUI>true</UseWinUI>
|
||||||
|
<EnablePreviewMsixTooling>false</EnablePreviewMsixTooling>
|
||||||
|
<WindowsPackageType>None</WindowsPackageType>
|
||||||
|
<ApplicationIcon>icon.ico</ApplicationIcon>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
|
||||||
|
<OutputPath></OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<OutputPath>..\..\..\x64\Debug\SettingsUI\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<OutputPath>..\..\..\x64\Release\SettingsUI\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Assets\SplashScreen.scale-200.png" />
|
||||||
|
<Content Include="Assets\LockScreenLogo.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="CommunityToolkit.WinUI.UI" Version="7.1.1-preview3.1" />
|
||||||
|
<PackageReference Include="CommunityToolkit.WinUI.UI.Controls" Version="7.1.1-preview3.1" />
|
||||||
|
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22504-preview" />
|
||||||
|
<PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" Version="2.0.8" />
|
||||||
|
<Manifest Include="$(ApplicationManifest)" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\common\ManagedTelemetry\Telemetry\ManagedTelemetry.csproj" />
|
||||||
|
<ProjectReference Include="..\Microsoft.PowerToys.Settings.UI.Library\Microsoft.PowerToys.Settings.UI.Library.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|