Compare commits

...

30 Commits

Author SHA1 Message Date
Niels Laute
340aa381b4 Adding ToC 2025-09-18 11:17:51 +02:00
Niels Laute
09d8e03062 Adding new OOBE experience 2025-09-18 10:10:26 +02:00
Niels Laute
3b4b149145 Update README.md 2025-09-17 14:56:39 +02:00
Niels Laute
8848814d68 Update README.md 2025-09-17 14:37:11 +02:00
Niels Laute
b7a11c1843 Update 2025-09-17 14:30:50 +02:00
Niels Laute
2ee96ef6b9 Update README.md 2025-09-17 14:25:22 +02:00
Niels Laute
a674204796 Update README.md 2025-09-17 14:24:04 +02:00
Niels Laute
51c04187d1 Update README.md 2025-09-17 14:17:25 +02:00
Niels Laute
54839f2ea3 Update README.md 2025-09-17 14:15:47 +02:00
Niels Laute
c365dbc48f Update README.md 2025-09-17 14:15:24 +02:00
Niels Laute
8ce4e704fc Update README.md 2025-09-17 14:15:04 +02:00
Niels Laute
32a62f21d9 Update README.md 2025-09-17 14:11:26 +02:00
Niels Laute
b7fb21c54f Update README.md 2025-09-17 14:03:57 +02:00
Niels Laute
982ac16953 Replacing header 2025-09-17 14:03:25 +02:00
Niels Laute
3f20ad0d7d Update README.md 2025-09-17 13:57:04 +02:00
Niels Laute
415ccb1e8d Update README.md 2025-09-17 13:48:07 +02:00
Niels Laute
a9d14984e4 Update README.md 2025-09-17 13:47:45 +02:00
Niels Laute
ada8840e34 Update README.md 2025-09-17 13:46:43 +02:00
Niels Laute
da8434152c Update README.md 2025-09-17 13:43:15 +02:00
Niels Laute
52c99d5399 Update README.md 2025-09-17 13:38:02 +02:00
Niels Laute
beae652394 Update README.md 2025-09-17 13:37:24 +02:00
Niels Laute
d6881f7828 Update README.md 2025-09-17 11:25:42 +02:00
Niels Laute
ea9f8b9ad1 Updated readme 2025-09-17 11:25:17 +02:00
Niels Laute
91efbad05f Test 2025-09-17 11:03:29 +02:00
Niels Laute
a3fa412202 Merge branch 'main' into niels9001/integrated-docs 2025-09-16 14:27:40 +02:00
Niels Laute
c39660edb7 Merge remote-tracking branch 'upstream/main' into niels9001/integrated-docs 2025-09-16 11:45:24 +02:00
Niels Laute
e5ae165ab8 Merge branch 'main' into niels9001/integrated-docs 2025-09-10 19:20:58 +02:00
Niels Laute
e22041a88d Merge branch 'main' into niels9001/integrated-docs 2025-08-20 17:30:55 +02:00
Niels Laute
d3dd2ebfb1 Merge branch 'main' into niels9001/integrated-docs 2025-08-19 17:17:11 +02:00
Niels Laute
02d5d506d5 Adding readme 2025-07-29 09:10:44 +02:00
27 changed files with 2485 additions and 162 deletions

View File

@@ -19,6 +19,7 @@
<PackageVersion Include="CommunityToolkit.WinUI.Controls.Segmented" Version="8.2.250402" />
<PackageVersion Include="CommunityToolkit.WinUI.Controls.Sizers" Version="8.2.250402" />
<PackageVersion Include="CommunityToolkit.WinUI.Converters" Version="8.2.250402" />
<PackageVersion Include="CommunityToolkit.WinUI.Media" Version="8.2.250402" />
<PackageVersion Include="CommunityToolkit.WinUI.Extensions" Version="8.2.250402" />
<PackageVersion Include="CommunityToolkit.WinUI.UI.Controls.DataGrid" Version="7.1.2" />
<PackageVersion Include="CommunityToolkit.WinUI.UI.Controls.Markdown" Version="7.1.2" />
@@ -38,6 +39,7 @@
<!-- Including Microsoft.Bcl.AsyncInterfaces to force version, since it's used by Microsoft.SemanticKernel. -->
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.8" />
<PackageVersion Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="3.1.16" />
<PackageVersion Include="Microsoft.Graphics.Win2D" Version="1.3.2" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="9.0.8" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.8" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.8" />

127
README.md
View File

@@ -1,36 +1,58 @@
# Microsoft PowerToys
![Hero image for Microsoft PowerToys](doc/images/overview/Header-light.png)
![Hero image for Microsoft PowerToys](doc/images/overview/PT_hero_image.png)
<h1 align="center">
<img src="doc/images/icons/PowerToys icon/PNG/PowerToysAppList.targetsize-30.png"
alt="PowerToys logo" height="30" style="vertical-align:middle;margin-right:8px;">
<span style="vertical-align:middle;">Microsoft PowerToys</span>
</h1>
[How to use PowerToys][usingPowerToys-docs-link] | [Downloads & Release notes][github-release-link] | [Contributing to PowerToys](#contributing) | [What's Happening](#whats-happening) | [Roadmap](#powertoys-roadmap)
<h3 align="center">
<a href="https://aka.ms/powertoys-docs">Getting started</a>
<span> · </span>
<a href="https://aka.ms/powertoys-docs">Documentation</a>
<span> · </span>
<a href="#powertoys-roadmap">Release notes & roadmap</a>
</h3>
## About
Microsoft PowerToys is a set of utilities for power users to tune and streamline their Windows experience for greater productivity. For more info on [PowerToys overviews and how to use the utilities][usingPowerToys-docs-link]
Microsoft PowerToys is a set of utilities for power users to tune and streamline their Windows experience for greater productivity. For more info on [PowerToys overviews and how to use the utilities][usingPowerToys-docs-link], or any other tools and resources for [Windows development environments](https://learn.microsoft.com/windows/dev-environment/overview), head over to [learn.microsoft.com][usingPowerToys-docs-link]!
| | | |
|---|---|---|
| [<img src="doc/images/icons/AdvancedPaste.png" alt="PowerToys" height="16"> Advanced Paste](https://aka.ms/PowerToysOverview_AdvancedPaste) | [<img src="doc/images/icons/Always%20On%20Top.png" alt="PowerToys" height="16"> Always on Top](https://aka.ms/PowerToysOverview_AoT) | [<img src="doc/images/icons/Awake.png" alt="PowerToys" height="16"> PowerToys Awake](https://aka.ms/PowerToysOverview_Awake) |
| [<img src="doc/images/icons/Color%20Picker.png" alt="PowerToys" height="16"> Color Picker](https://aka.ms/PowerToysOverview_ColorPicker) | [<img src="doc/images/icons/Command%20Not%20Found.png" alt="PowerToys" height="16"> Command Not Found](https://aka.ms/PowerToysOverview_CmdNotFound) | [<img src="doc/images/icons/Peek.png" alt="PowerToys" height="16"> Command Palette](https://aka.ms/PowerToysOverview_CmdPal) |
| [<img src="doc/images/icons/Crop%20And%20Lock.png" alt="PowerToys" height="16"> Crop And Lock](https://aka.ms/PowerToysOverview_CropAndLock) | [<img src="doc/images/icons/Environment%20Manager.png" alt="PowerToys" height="16"> Environment Variables](https://aka.ms/PowerToysOverview_EnvironmentVariables) | [<img src="doc/images/icons/FancyZones.png" alt="PowerToys" height="16"> FancyZones](https://aka.ms/PowerToysOverview_FancyZones) |
| [<img src="doc/images/icons/File%20Explorer%20Preview.png" alt="PowerToys" height="16"> File Explorer Add-ons](https://aka.ms/PowerToysOverview_FileExplorerAddOns) | [<img src="doc/images/icons/File%20Locksmith.png" alt="PowerToys" height="16"> File Locksmith](https://aka.ms/PowerToysOverview_FileLocksmith) | [<img src="doc/images/icons/Host%20File%20Editor.png" alt="PowerToys" height="16"> Hosts File Editor](https://aka.ms/PowerToysOverview_HostsFileEditor) |
| [<img src="doc/images/icons/Image%20Resizer.png" alt="PowerToys" height="16"> Image Resizer](https://aka.ms/PowerToysOverview_ImageResizer) | [<img src="doc/images/icons/Keyboard%20Manager.png" alt="PowerToys" height="16"> Keyboard Manager](https://aka.ms/PowerToysOverview_KeyboardManager) | [<img src="doc/images/icons/Keyboard%20Manager.png" alt="PowerToys" height="16"> Mouse Utilities](https://aka.ms/PowerToysOverview_MouseUtilities) |
| [<img src="doc/images/icons/MouseWithoutBorders.png" alt="PowerToys" height="16"> Mouse Without Borders](https://aka.ms/PowerToysOverview_MouseWithoutBorders) | [<img src="doc/images/icons/NewPlus.png" alt="PowerToys" height="16"> New+](https://aka.ms/PowerToysOverview_NewPlus) | [<img src="doc/images/icons/AdvancedPaste.png" alt="PowerToys" height="16"> Paste as Plain Text](https://aka.ms/PowerToysOverview_PastePlain) |
| [<img src="doc/images/icons/Peek.png" alt="PowerToys" height="16"> Peek](https://aka.ms/PowerToysOverview_Peek) | [<img src="doc/images/icons/PowerRename.png" alt="PowerToys" height="16"> PowerRename](https://aka.ms/PowerToysOverview_PowerRename) | [<img src="doc/images/icons/PowerToys%20Run.png" alt="PowerToys" height="16"> PowerToys Run](https://aka.ms/PowerToysOverview_PowerToysRun) |
| [<img src="doc/images/icons/PowerAccent.png" alt="PowerToys" height="16"> Quick Accent](https://aka.ms/PowerToysOverview_QuickAccent) | [<img src="doc/images/icons/Registry%20Preview.png" alt="PowerToys" height="16"> Registry Preview](https://aka.ms/PowerToysOverview_RegistryPreview) | [<img src="doc/images/icons/MeasureTool.png" alt="PowerToys" height="16"> Screen Ruler](https://aka.ms/PowerToysOverview_ScreenRuler) |
| [<img src="doc/images/icons/Shortcut%20Guide.png" alt="PowerToys" height="16"> Shortcut Guide](https://aka.ms/PowerToysOverview_ShortcutGuide) | [<img src="doc/images/icons/PowerOCR.png" alt="PowerToys" height="16"> Text Extractor](https://aka.ms/PowerToysOverview_TextExtractor) | [<img src="doc/images/icons/Workspaces.png" alt="PowerToys" height="16"> Workspaces](https://aka.ms/PowerToysOverview_Workspaces) |
| [<img src="doc/images/icons/Peek.png" alt="PowerToys" height="16"> ZoomIt](https://aka.ms/PowerToysOverview_ZoomIt) | | |
| | Current utilities: | |
|--------------|--------------------|--------------|
| [Advanced Paste](https://aka.ms/PowerToysOverview_AdvancedPaste) | [Always on Top](https://aka.ms/PowerToysOverview_AoT) | [PowerToys Awake](https://aka.ms/PowerToysOverview_Awake) |
| [Color Picker](https://aka.ms/PowerToysOverview_ColorPicker) | [Command Not Found](https://aka.ms/PowerToysOverview_CmdNotFound) | [Command Palette](https://aka.ms/PowerToysOverview_CmdPal) |
| [Crop And Lock](https://aka.ms/PowerToysOverview_CropAndLock) | [Environment Variables](https://aka.ms/PowerToysOverview_EnvironmentVariables) | [FancyZones](https://aka.ms/PowerToysOverview_FancyZones) |
| [File Explorer Add-ons](https://aka.ms/PowerToysOverview_FileExplorerAddOns) | [File Locksmith](https://aka.ms/PowerToysOverview_FileLocksmith) | [Hosts File Editor](https://aka.ms/PowerToysOverview_HostsFileEditor) |
| [Image Resizer](https://aka.ms/PowerToysOverview_ImageResizer) | [Keyboard Manager](https://aka.ms/PowerToysOverview_KeyboardManager) | [Mouse Utilities](https://aka.ms/PowerToysOverview_MouseUtilities) |
| [Mouse Without Borders](https://aka.ms/PowerToysOverview_MouseWithoutBorders) | [New+](https://aka.ms/PowerToysOverview_NewPlus) | [Paste as Plain Text](https://aka.ms/PowerToysOverview_PastePlain) |
| [Peek](https://aka.ms/PowerToysOverview_Peek) | [PowerRename](https://aka.ms/PowerToysOverview_PowerRename) | [PowerToys Run](https://aka.ms/PowerToysOverview_PowerToysRun) |
| [Quick Accent](https://aka.ms/PowerToysOverview_QuickAccent) | [Registry Preview](https://aka.ms/PowerToysOverview_RegistryPreview) | [Screen Ruler](https://aka.ms/PowerToysOverview_ScreenRuler) |
| [Shortcut Guide](https://aka.ms/PowerToysOverview_ShortcutGuide) | [Text Extractor](https://aka.ms/PowerToysOverview_TextExtractor) | [Workspaces](https://aka.ms/PowerToysOverview_Workspaces) |
| [ZoomIt](https://aka.ms/PowerToysOverview_ZoomIt) |
## 📋 Installation
## Installing and running Microsoft PowerToys
To get started with PowerToys, ensure you have the right system requirements:
### Requirements
> [!NOTE]
> - Windows 11 or Windows 10 version 2004 (20H1 / build 19041) or newer
> - 64-bit processor: x64 or ARM64
> - Latest stable version of [Microsoft Edge WebView2 Runtime](https://go.microsoft.com/fwlink/p/?LinkId=2124703) is installed via the bootstrapper during setup
- Windows 11 or Windows 10 version 2004 (code name 20H1 / build number 19041) or newer.
- x64 or ARM64 processor
- Our installer will install the following items:
- [Microsoft Edge WebView2 Runtime](https://go.microsoft.com/fwlink/p/?LinkId=2124703) bootstrapper. This will install the latest version.
To install, there are multiple options:
### Via GitHub with EXE [Recommended]
<details>
<summary>Microsoft Store</summary>
You can easily install PowerToys from the Microsoft Store:
<p>
<a style="text-decoration:none" href="https://aka.ms/getPowertoy">
<picture>
<source media="(prefers-color-scheme: light)" srcset="doc/images/StoreBadge-dark.png" width="220" />
<img src="doc/images/StoreBadge-light.png" width="220" />
</picture></a>
</p>
</details>
<details>
<summary>Via GitHub with .exe</summary>
Go to the [Microsoft PowerToys GitHub releases page][github-release-link] and click on `Assets` at the bottom to show the files available in the release. Please use the appropriate PowerToys installer that matches your machine's architecture and install scope. For most, it is `x64` and per-user.
@@ -49,57 +71,36 @@ Go to the [Microsoft PowerToys GitHub releases page][github-release-link] and cl
| Machine wide - x64 | [PowerToysSetup-0.94.0-x64.exe][ptMachineX64] |
| Machine wide - ARM64 | [PowerToysSetup-0.94.0-arm64.exe][ptMachineArm64] |
This is our preferred method.
</details>
### Via Microsoft Store
<details>
<summary>WinGet</summary>
Install from the [Microsoft Store's PowerToys page][microsoft-store-link]. You must be using the [new Microsoft Store](https://blogs.windows.com/windowsExperience/2021/06/24/building-a-new-open-microsoft-store-on-windows-11/), which is available for both Windows 11 and Windows 10.
### Via WinGet
Download PowerToys from [WinGet][winget-link]. Updating PowerToys via winget will respect the current PowerToys installation scope. To install PowerToys, run the following command from the command line / PowerShell:
#### User scope installer [default]
*User scope installer [default]*
```powershell
winget install Microsoft.PowerToys -s winget
```
#### Machine-wide scope installer
*User scope installer [default]*
```powershell
winget install --scope machine Microsoft.PowerToys -s winget
```
</details>
### Other install methods
<details>
<summary>Other methods</summary>
There are [community driven install methods](./doc/unofficialInstallMethods.md) such as Chocolatey and Scoop. If these are your preferred install solutions, you can find the install instructions there.
</details>
## Third-Party Run Plugins
There is a collection of [third-party plugins](./doc/thirdPartyRunPlugins.md) created by the community that aren't distributed with PowerToys.
## Contributing
This project welcomes contributions of all types. Besides coding features / bug fixes, other ways to assist include spec writing, design, documentation, and finding bugs. We are excited to work with the power user community to build a set of tools for helping you get the most out of Windows.
We ask that **before you start work on a feature that you would like to contribute**, please read our [Contributor's Guide](CONTRIBUTING.md). We would be happy to work with you to figure out the best approach, provide guidance and mentorship throughout feature development, and help avoid any wasted or duplicate effort.
Most contributions require you to agree to a [Contributor License Agreement (CLA)][oss-CLA] declaring that you grant us the rights to use your contribution and that you have permission to do so.
For guidance on developing for PowerToys, please read the [developer docs](./doc/devdocs) for a detailed breakdown. This includes how to setup your computer to compile.
## What's Happening
### PowerToys Roadmap
Our [prioritized roadmap][roadmap] of features and utilities that the core team is focusing on.
### 0.94 - Sep 2025 Update
## ✨ What's new in 0.94 (September 2025)
In this release, we focused on new features, stability, optimization improvements, and automation.
For an in-depth look at the latest changes, visit the [release blog](https://aka.ms/powertoys-releaseblog).
**✨Highlights**
** Highlights**
- PowerToys Settings added a Settings search with fuzzy matching, suggestions, a results page, and UX polish to make finding options faster.
- A comprehensive hotkey conflict detection system was introduced in Settings to surface and help resolve conflicting shortcuts. Note that the default hotkey settings (Win+Ctrl+Shift+T, Win+Ctrl+V, Win+Ctrl+T, Win+Shift+T) may overlap with existing Windows system shortcuts. This is expected. You can resolve the conflict by assigning different hotkeys.
@@ -223,7 +224,9 @@ For an in-depth look at the latest changes, visit the [release blog](https://aka
- Cleans up AIgenerated tests; adds meaningful query tests across extensions.
- Removed the obsolete debug dialog from Settings for a smoother developer loop.
### What is being planned over the next few releases
## 🛣️ Roadmap
Our [prioritized roadmap][roadmap] of features and utilities that the core team is focusing on.
For [v0.95][github-next-release-work], we'll work on the items below:
@@ -239,6 +242,16 @@ For [v0.95][github-next-release-work], we'll work on the items below:
The PowerToys team is extremely grateful to have the [support of an amazing active community][community-link]. The work you do is incredibly important. PowerToys wouldnt be nearly what it is today without your help filing bugs, updating documentation, guiding the design, or writing features. We want to say thank you and take time to recognize your work. Month by month, you directly help make PowerToys a better piece of software.
## Contributing
This project welcomes contributions of all types. Besides coding features / bug fixes, other ways to assist include spec writing, design, documentation, and finding bugs. We are excited to work with the power user community to build a set of tools for helping you get the most out of Windows.
We ask that **before you start work on a feature that you would like to contribute**, please read our [Contributor's Guide](CONTRIBUTING.md). We would be happy to work with you to figure out the best approach, provide guidance and mentorship throughout feature development, and help avoid any wasted or duplicate effort.
Most contributions require you to agree to a [Contributor License Agreement (CLA)][oss-CLA] declaring that you grant us the rights to use your contribution and that you have permission to do so.
For guidance on developing for PowerToys, please read the [developer docs](./doc/devdocs) for a detailed breakdown. This includes how to setup your computer to compile.
## Code of Conduct
This project has adopted the [Microsoft Open Source Code of Conduct][oss-conduct-code].

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 529 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 580 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 580 KiB

View File

@@ -20,12 +20,18 @@
<ProjectPriFileName>PowerToys.Settings.pri</ProjectPriFileName>
</PropertyGroup>
<ItemGroup>
<None Remove="Assets\Settings\Header.png" />
<None Remove="Assets\Settings\Modules\APDialog.dark.png" />
<None Remove="Assets\Settings\Modules\APDialog.light.png" />
<None Remove="SettingsXAML\Controls\Dashboard\CheckUpdateControl.xaml" />
<None Remove="SettingsXAML\Controls\Dashboard\ShortcutConflictControl.xaml" />
<None Remove="SettingsXAML\Controls\KeyVisual\KeyCharPresenter.xaml" />
<None Remove="SettingsXAML\Controls\OOBE\OOBEControl.xaml" />
<None Remove="SettingsXAML\Controls\OOBE\RedirectVisualView.xaml" />
<None Remove="SettingsXAML\Controls\OpacityMaskView.xaml" />
<None Remove="SettingsXAML\Controls\TitleBar\TitleBar.xaml" />
<None Remove="SettingsXAML\Oobe2Window.xaml" />
<None Remove="SettingsXAML\ScoobeWindow.xaml" />
</ItemGroup>
<ItemGroup>
<Page Remove="SettingsXAML\App.xaml" />
@@ -63,6 +69,7 @@
<PackageReference Include="CommunityToolkit.WinUI.Animations" />
<PackageReference Include="CommunityToolkit.WinUI.Extensions" />
<PackageReference Include="CommunityToolkit.WinUI.Converters" />
<PackageReference Include="CommunityToolkit.WinUI.Media" />
<PackageReference Include="CommunityToolkit.WinUI.UI.Controls.Markdown" />
<PackageReference Include="System.Net.Http" />
<PackageReference Include="System.Private.Uri" />
@@ -73,6 +80,8 @@
<PackageReference Include="Microsoft.WindowsAppSDK" />
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" />
<PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" />
<PackageReference Include="Microsoft.Graphics.Win2D" />
<PackageReference Include="StreamJsonRpc" />
<!-- HACK: Microsoft.Extensions.Hosting is referenced, even if it is not used, to force dll versions to be the same as in other projects. Really only needed since the Experimentation APIs that are added in CI reference some net standard 2.0 assemblies. -->
<PackageReference Include="Microsoft.Extensions.Hosting" />
@@ -135,6 +144,12 @@
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Content Update="Assets\Settings\Header.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<None Update="Assets\Settings\icon.ico">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
@@ -156,7 +171,22 @@
</None>
<None Update="Assets\Settings\Scripts\DisableModule.ps1">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> <Page Update="SettingsXAML\Controls\TitleBar\TitleBar.xaml">
</None>
<Page Update="SettingsXAML\ScoobeWindow.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Update="SettingsXAML\Controls\OOBE\OOBEControl.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Update="SettingsXAML\Controls\OOBE\RedirectVisualView.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Update="SettingsXAML\Oobe2Window.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Update="SettingsXAML\Controls\OpacityMaskView.xaml">
<Generator>MSBuild:Compile</Generator>
</Page> <Page Update="SettingsXAML\Controls\TitleBar\TitleBar.xaml">
</Page>
<Page Update="SettingsXAML\Controls\KeyVisual\KeyCharPresenter.xaml">
<Generator>MSBuild:Compile</Generator>

View File

@@ -12,6 +12,8 @@
<ResourceDictionary Source="/SettingsXAML/Controls/KeyVisual/KeyVisual.xaml" />
<ResourceDictionary Source="/SettingsXAML/Controls/KeyVisual/KeyCharPresenter.xaml" />
<ResourceDictionary Source="/SettingsXAML/Controls/TitleBar/TitleBar.xaml" />
<ResourceDictionary Source="/SettingsXAML/Controls/OpacityMaskView.xaml" />
<ResourceDictionary Source="/SettingsXAML/Controls/OOBE/RedirectVisualView.xaml" />
<ResourceDictionary Source="/SettingsXAML/Styles/TextBlock.xaml" />
<ResourceDictionary Source="/SettingsXAML/Styles/Button.xaml" />
<ResourceDictionary Source="/SettingsXAML/Styles/InfoBadge.xaml" />
@@ -58,6 +60,16 @@
<tkconverters:StringVisibilityConverter x:Key="StringVisibilityConverter" />
<x:Double x:Key="SettingsCardSpacing">2</x:Double>
<Style x:Key="GridCardStyle" TargetType="Grid">
<Style.Setters>
<Setter Property="Background" Value="{ThemeResource CardBackgroundFillColorDefaultBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="CornerRadius" Value="{StaticResource OverlayCornerRadius}" />
<Setter Property="BorderBrush" Value="{ThemeResource CardStrokeColorDefaultBrush}" />
<Setter Property="Padding" Value="24" />
</Style.Setters>
</Style>
<!-- Overrides -->
<Thickness x:Key="InfoBarIconMargin">6,16,16,16</Thickness>
<Thickness x:Key="InfoBarContentRootPadding">16,0,0,0</Thickness>

View File

@@ -263,20 +263,12 @@ namespace Microsoft.PowerToys.Settings.UI
if (ShowOobe)
{
PowerToysTelemetry.Log.WriteEvent(new OobeStartedEvent());
OobeWindow oobeWindow = new OobeWindow(OOBE.Enums.PowerToysModules.Overview);
oobeWindow.Activate();
oobeWindow.ExtendsContentIntoTitleBar = true;
WindowHelpers.ForceTopBorder1PixelInsetOnWindows10(WindowNative.GetWindowHandle(settingsWindow));
SetOobeWindow(oobeWindow);
}
else if (ShowScoobe)
{
PowerToysTelemetry.Log.WriteEvent(new ScoobeStartedEvent());
OobeWindow scoobeWindow = new OobeWindow(OOBE.Enums.PowerToysModules.WhatsNew);
scoobeWindow.Activate();
scoobeWindow.ExtendsContentIntoTitleBar = true;
WindowHelpers.ForceTopBorder1PixelInsetOnWindows10(WindowNative.GetWindowHandle(settingsWindow));
SetOobeWindow(scoobeWindow);
}
else if (ShowFlyout)
{
@@ -363,7 +355,7 @@ namespace Microsoft.PowerToys.Settings.UI
public static ThemeService ThemeService => themeService;
private static MainWindow settingsWindow;
private static OobeWindow oobeWindow;
private static Oobe2Window oobeWindow;
private static FlyoutWindow flyoutWindow;
public static void ClearSettingsWindow()
@@ -376,7 +368,7 @@ namespace Microsoft.PowerToys.Settings.UI
return settingsWindow;
}
public static OobeWindow GetOobeWindow()
public static Oobe2Window GetOobeWindow()
{
return oobeWindow;
}
@@ -386,7 +378,7 @@ namespace Microsoft.PowerToys.Settings.UI
return flyoutWindow;
}
public static void SetOobeWindow(OobeWindow window)
public static void SetOobeWindow(Oobe2Window window)
{
oobeWindow = window;
}

View File

@@ -0,0 +1,291 @@
// 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.Composition;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Hosting;
namespace Microsoft.PowerToys.Settings.UI.Controls
{
public enum ScrollDirection
{
Left,
Right,
}
public partial class AutoScrollView : RedirectVisualView
{
public AutoScrollView()
{
RedirectVisualEnabled = false;
compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
propSet = compositor.CreatePropertySet();
propSet.InsertScalar(nameof(Spacing), (float)Spacing);
visual1 = compositor.CreateSpriteVisual();
visual1.Brush = ChildVisualBrush;
visual2 = compositor.CreateSpriteVisual();
visual2.Brush = ChildVisualBrush;
offsetBind1 = compositor.CreateExpressionAnimation("Vector3(visual.Offset.X, visual.Offset.Y, 0)");
sizeBind = compositor.CreateExpressionAnimation("visual.Size");
RootVisual.Brush = null;
RootVisual.Children.InsertAtTop(visual2);
RootVisual.Children.InsertAtTop(visual1);
RootVisual.IsPixelSnappingEnabled = true;
linearEasingFunc = compositor.CreateLinearEasingFunction();
MeasureChildInBoundingBox = IsPlaying;
this.Loaded += AutoScrollView_Loaded;
}
private Compositor compositor;
private CompositionPropertySet propSet;
private SpriteVisual visual1;
private SpriteVisual visual2;
private ExpressionAnimation offsetBind1;
private ExpressionAnimation offsetBind2;
private ExpressionAnimation sizeBind;
private LinearEasingFunction linearEasingFunc;
private ScalarKeyFrameAnimation animation;
protected override bool ChildVisualBrushOffsetEnabled => false;
private void AutoScrollView_Loaded(object sender, RoutedEventArgs e)
{
UpdateAnimationState();
UpdateAnimationSpeed();
}
protected override void OnAttachVisuals()
{
base.OnAttachVisuals();
if (ChildPresenter != null && LayoutRoot != null)
{
var childVisual = ElementCompositionPreview.GetElementVisual(ChildPresenter);
var rootVisual = ElementCompositionPreview.GetElementVisual(LayoutRoot);
rootVisual.Clip = compositor.CreateInsetClip();
offsetBind1.SetReferenceParameter("visual", childVisual);
sizeBind.SetReferenceParameter("visual", childVisual);
offsetBind2 = GetOffsetBind2ForDirection();
offsetBind2.SetReferenceParameter("visual", childVisual);
offsetBind2.SetReferenceParameter("propSet", propSet);
visual1.StartAnimation("Size", sizeBind);
visual2.StartAnimation("Size", sizeBind);
visual1.StartAnimation("Offset", offsetBind1);
visual2.StartAnimation("Offset", offsetBind2);
UpdateAnimationSpeed();
}
}
protected override void OnDetachVisuals()
{
base.OnDetachVisuals();
visual1.StopAnimation("Offset");
visual1.StopAnimation("Size");
visual2.StopAnimation("Offset");
visual2.StopAnimation("Size");
RootVisual.StopAnimation("Offset.X");
offsetBind1.ClearAllParameters();
offsetBind2?.ClearAllParameters();
sizeBind.ClearAllParameters();
animation?.ClearAllParameters();
}
protected override void OnUpdateSize()
{
base.OnUpdateSize();
DispatcherQueue.TryEnqueue(() =>
{
UpdateAnimationState();
UpdateAnimationSpeed();
});
}
private void UpdateAnimationState()
{
MeasureChildInBoundingBox = !IsPlaying;
if (IsLoaded && IsPlaying && ChildPresenter != null && LayoutRoot != null)
{
var childWidth = ChildPresenter.ActualWidth;
var rootWidth = LayoutRoot.ActualWidth - Padding.Left - Padding.Right;
RedirectVisualEnabled = childWidth > rootWidth;
}
else
{
RedirectVisualEnabled = false;
}
}
private void UpdateAnimationSpeed()
{
if (ChildPresenter == null || LayoutRoot == null)
{
return;
}
UpdateAnimationExpression();
var childVisual = ElementCompositionPreview.GetElementVisual(ChildPresenter);
var rootVisual = ElementCompositionPreview.GetElementVisual(LayoutRoot);
var progress = 0f;
if (RedirectVisualAttached)
{
var controller = RootVisual.TryGetAnimationController("Offset.X");
if (controller != null)
{
controller.Pause();
progress = controller.Progress;
}
RootVisual.StopAnimation("Offset.X");
}
animation.SetReferenceParameter("visual", childVisual);
animation.SetReferenceParameter("visual2", rootVisual);
animation.SetReferenceParameter("propSet", propSet);
animation.Duration = TimeSpan.FromSeconds(ChildPresenter.ActualWidth / ScrollingPixelsPerSecond);
RootVisual.StartAnimation("Offset.X", animation);
if (progress > 0)
{
var controller = RootVisual.TryGetAnimationController("Offset.X");
if (controller != null)
{
controller.Pause();
controller.Progress = progress;
controller.Resume();
}
}
}
private void UpdateAnimationExpression()
{
string expression = Direction == ScrollDirection.Left
? "-visual.Size.X - propSet.Spacing"
: "visual.Size.X + propSet.Spacing";
var newAnimation = compositor.CreateScalarKeyFrameAnimation();
newAnimation.InsertKeyFrame(0, 0);
newAnimation.InsertExpressionKeyFrame(1, expression, linearEasingFunc);
newAnimation.IterationBehavior = AnimationIterationBehavior.Forever;
newAnimation.SetReferenceParameter("propSet", propSet);
animation = newAnimation;
}
private ExpressionAnimation GetOffsetBind2ForDirection()
{
string expression = Direction == ScrollDirection.Left
? "Vector3(visual.Offset.X + visual.Size.X + propSet.Spacing, visual.Offset.Y, 0)"
: "Vector3(visual.Offset.X - visual.Size.X - propSet.Spacing, visual.Offset.Y, 0)";
var anim = compositor.CreateExpressionAnimation(expression);
anim.SetReferenceParameter("propSet", propSet);
return anim;
}
public static readonly DependencyProperty SpacingProperty =
DependencyProperty.Register(nameof(Spacing), typeof(double), typeof(AutoScrollView), new PropertyMetadata(0d, (s, a) =>
{
if (s is AutoScrollView sender && !Equals(a.NewValue, a.OldValue))
{
#pragma warning disable CA1305 // Specify IFormatProvider
var value = Convert.ToSingle(a.NewValue);
#pragma warning restore CA1305 // Specify IFormatProvider
if (value < 0)
{
throw new ArgumentException(nameof(Spacing));
}
sender.propSet.InsertScalar(nameof(Spacing), value);
}
}));
public static readonly DependencyProperty IsPlayingProperty =
DependencyProperty.Register(nameof(IsPlaying), typeof(bool), typeof(AutoScrollView), new PropertyMetadata(true, (s, a) =>
{
if (s is AutoScrollView sender && !Equals(a.NewValue, a.OldValue))
{
sender.UpdateAnimationState();
sender.UpdateAnimationSpeed();
}
}));
public static readonly DependencyProperty ScrollingPixelsPerSecondProperty =
DependencyProperty.Register(nameof(ScrollingPixelsPerSecond), typeof(double), typeof(AutoScrollView), new PropertyMetadata(30d, (s, a) =>
{
if (s is AutoScrollView sender && !Equals(a.NewValue, a.OldValue))
{
#pragma warning disable CA1305 // Specify IFormatProvider
var value = Convert.ToSingle(a.NewValue);
#pragma warning restore CA1305 // Specify IFormatProvider
if (value <= 0)
{
throw new ArgumentException(nameof(ScrollingPixelsPerSecond));
}
sender.UpdateAnimationSpeed();
}
}));
public static readonly DependencyProperty DirectionProperty =
DependencyProperty.Register(nameof(Direction), typeof(ScrollDirection), typeof(AutoScrollView), new PropertyMetadata(ScrollDirection.Left, (s, a) =>
{
if (s is AutoScrollView sender && !Equals(a.NewValue, a.OldValue))
{
sender.UpdateAnimationSpeed();
}
}));
public double Spacing
{
get => (double)GetValue(SpacingProperty);
set => SetValue(SpacingProperty, value);
}
public bool IsPlaying
{
get => (bool)GetValue(IsPlayingProperty);
set => SetValue(IsPlayingProperty, value);
}
public double ScrollingPixelsPerSecond
{
get => (double)GetValue(ScrollingPixelsPerSecondProperty);
set => SetValue(ScrollingPixelsPerSecondProperty, value);
}
public ScrollDirection Direction
{
get => (ScrollDirection)GetValue(DirectionProperty);
set => SetValue(DirectionProperty, value);
}
}
}

View File

@@ -0,0 +1,703 @@
<?xml version="1.0" encoding="utf-8" ?>
<UserControl
x:Class="Microsoft.PowerToys.Settings.UI.Controls.OOBEControl"
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:local="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<UserControl.Resources>
<StaticResource x:Key="ListViewItemSelectionIndicatorBrush" ResourceKey="SubtleFillColorTransparentBrush" />
<StaticResource x:Key="ListViewItemSelectionIndicatorPointerOverBrush" ResourceKey="SubtleFillColorTransparentBrush" />
<StaticResource x:Key="ListViewItemSelectionIndicatorPressedBrush" ResourceKey="SubtleFillColorTransparentBrush" />
<StaticResource x:Key="ListViewItemSelectionIndicatorDisabledBrush" ResourceKey="SubtleFillColorTransparentBrush" />
<Style x:Key="ExpandableListViewItemContainerStyle" TargetType="ListViewItem">
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="{ThemeResource ListViewItemForeground}" />
<Setter Property="TabNavigation" Value="Local" />
<Setter Property="IsHoldingEnabled" Value="True" />
<Setter Property="Padding" Value="4,4,4,4" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="MinWidth" Value="{ThemeResource ListViewItemMinWidth}" />
<Setter Property="MinHeight" Value="{ThemeResource ListViewItemMinHeight}" />
<Setter Property="AllowDrop" Value="False" />
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
<Setter Property="FocusVisualMargin" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Grid
x:Name="ContentBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Control.IsTemplateFocusTarget="True"
CornerRadius="{TemplateBinding CornerRadius}"
FocusVisualMargin="{TemplateBinding FocusVisualMargin}"
RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<ScaleTransform x:Name="ContentBorderScale" />
</Grid.RenderTransform>
<Rectangle
x:Name="BorderBackground"
Control.IsTemplateFocusTarget="True"
Fill="{ThemeResource ListViewItemBorderBackground}"
IsHitTestVisible="False"
Opacity="0"
StrokeThickness="0" />
<Grid x:Name="ContentPresenterGrid" Background="Transparent">
<Grid.RenderTransform>
<TranslateTransform x:Name="ContentPresenterTranslateTransform" />
</Grid.RenderTransform>
<ContentPresenter
x:Name="ContentPresenter"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}" />
</Grid>
<!--
The 'Xg' text simulates the amount of space one line of text will occupy.
In the DataPlaceholder state, the Content is not loaded yet so we
approximate the size of the item using placeholder text.
-->
<TextBlock
x:Name="PlaceholderTextBlock"
Margin="{TemplateBinding Padding}"
AutomationProperties.AccessibilityView="Raw"
Foreground="{x:Null}"
IsHitTestVisible="False"
Opacity="0"
Text="Xg" />
<Rectangle
x:Name="PlaceholderRect"
Fill="{ThemeResource ListViewItemPlaceholderBackground}"
Visibility="Collapsed" />
<Border
x:Name="MultiSelectSquare"
Width="20"
Height="20"
Margin="12,0,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
BorderBrush="{ThemeResource ListViewItemCheckBrush}"
BorderThickness="2"
Visibility="Collapsed">
<Border.Clip>
<RectangleGeometry Rect="0,0,20,20">
<RectangleGeometry.Transform>
<TranslateTransform x:Name="MultiSelectClipTransform" />
</RectangleGeometry.Transform>
</RectangleGeometry>
</Border.Clip>
<Border.RenderTransform>
<TranslateTransform x:Name="MultiSelectCheckBoxTransform" />
</Border.RenderTransform>
<FontIcon
x:Name="MultiSelectCheck"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="16"
Foreground="{ThemeResource ListViewItemCheckBrush}"
Glyph="&#xE73E;"
Opacity="0"
Visibility="Collapsed" />
</Border>
<Border
x:Name="MultiArrangeOverlayTextBorder"
Height="20"
MinWidth="20"
Margin="12,0,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Background="{ThemeResource ListViewItemMultiArrangeOverlayTextBackground}"
BorderBrush="{ThemeResource ListViewItemMultiArrangeOverlayTextBorder}"
BorderThickness="2"
IsHitTestVisible="False"
Opacity="0">
<TextBlock
x:Name="MultiArrangeOverlayText"
HorizontalAlignment="Center"
VerticalAlignment="Center"
AutomationProperties.AccessibilityView="Raw"
IsHitTestVisible="False"
Opacity="0"
Style="{ThemeResource CaptionTextBlockStyle}"
Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DragItemsCount}" />
</Border>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="BorderBackground"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0" />
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="RadiusX">
<DiscreteObjectKeyFrame KeyTime="0" Value="8" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="RadiusY">
<DiscreteObjectKeyFrame KeyTime="0" Value="8" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="Fill">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemBackgroundPointerOver}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemForegroundPointerOver}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectSquare" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemForegroundPointerOver}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectCheck" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemForegroundPointerOver}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="BorderBackground"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0" />
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="RadiusX">
<DiscreteObjectKeyFrame KeyTime="0" Value="8" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="RadiusY">
<DiscreteObjectKeyFrame KeyTime="0" Value="8" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="Fill">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemBackgroundPressed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemForegroundPressed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectSquare" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemForegroundPressed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectCheck" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemForegroundPressed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Selected">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="MultiSelectCheck"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0:0:0" />
<DoubleAnimation
Storyboard.TargetName="BorderBackground"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0" />
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="Fill">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ControlFillColorDefaultBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="Stroke">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ControlElevationBorderBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="StrokeThickness">
<DiscreteObjectKeyFrame KeyTime="0" Value="1" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="RadiusX">
<DiscreteObjectKeyFrame KeyTime="0" Value="8" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="RadiusY">
<DiscreteObjectKeyFrame KeyTime="0" Value="8" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemForegroundSelected}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectSquare" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemForegroundSelected}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectCheck" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemForegroundSelected}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="PointerOverSelected">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="MultiSelectCheck"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0:0:0" />
<DoubleAnimation
Storyboard.TargetName="BorderBackground"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0" />
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="Fill">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ControlFillColorSecondaryBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="Stroke">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource CardStrokeColorDefaultSolidBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="StrokeThickness">
<DiscreteObjectKeyFrame KeyTime="0" Value="1" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="RadiusX">
<DiscreteObjectKeyFrame KeyTime="0" Value="8" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="RadiusY">
<DiscreteObjectKeyFrame KeyTime="0" Value="8" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemForegroundSelectedPointerOver}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectSquare" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemForegroundSelectedPointerOver}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectCheck" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemForegroundSelectedPointerOver}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="PressedSelected">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="MultiSelectCheck"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0:0:0" />
<DoubleAnimation
Storyboard.TargetName="BorderBackground"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0" />
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="Fill">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ControlFillColorTertiaryBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="Stroke">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource CardStrokeColorDefaultSolidBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="StrokeThickness">
<DiscreteObjectKeyFrame KeyTime="0" Value="1" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="RadiusX">
<DiscreteObjectKeyFrame KeyTime="0" Value="8" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="RadiusY">
<DiscreteObjectKeyFrame KeyTime="0" Value="8" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemForegroundSelectedPressed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectSquare" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemForegroundSelectedPressed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectCheck" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemForegroundSelectedPressed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="DisabledStates">
<VisualState x:Name="Enabled" />
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="ContentBorder"
Storyboard.TargetProperty="Opacity"
To="{ThemeResource ListViewItemDisabledThemeOpacity}"
Duration="0" />
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="MultiSelectStates">
<VisualState x:Name="MultiSelectDisabled">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectCheckBoxTransform" Storyboard.TargetProperty="X">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="0" />
<SplineDoubleKeyFrame
KeySpline="0.1,0.9,0.2,1"
KeyTime="0:0:0.333"
Value="-32" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectClipTransform" Storyboard.TargetProperty="X">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="0" />
<SplineDoubleKeyFrame
KeySpline="0.1,0.9,0.2,1"
KeyTime="0:0:0.333"
Value="32" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenterTranslateTransform" Storyboard.TargetProperty="X">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="32" />
<SplineDoubleKeyFrame
KeySpline="0.1,0.9,0.2,1"
KeyTime="0:0:0.333"
Value="0" />
</DoubleAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectSquare" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
<DiscreteObjectKeyFrame KeyTime="0:0:0.333" Value="Collapsed" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="MultiSelectEnabled">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectCheckBoxTransform" Storyboard.TargetProperty="X">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="-32" />
<SplineDoubleKeyFrame
KeySpline="0.1,0.9,0.2,1"
KeyTime="0:0:0.333"
Value="0" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectClipTransform" Storyboard.TargetProperty="X">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="32" />
<SplineDoubleKeyFrame
KeySpline="0.1,0.9,0.2,1"
KeyTime="0:0:0.333"
Value="0" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenterTranslateTransform" Storyboard.TargetProperty="X">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="-32" />
<SplineDoubleKeyFrame
KeySpline="0.1,0.9,0.2,1"
KeyTime="0:0:0.333"
Value="0" />
</DoubleAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectSquare" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectCheck" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenterGrid" Storyboard.TargetProperty="Margin">
<DiscreteObjectKeyFrame KeyTime="0" Value="32,0,0,0" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="DataVirtualizationStates">
<VisualState x:Name="DataAvailable" />
<VisualState x:Name="DataPlaceholder">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderTextBlock" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderRect" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="ReorderHintStates">
<VisualState x:Name="NoReorderHint" />
<VisualState x:Name="BottomReorderHint">
<Storyboard>
<DragOverThemeAnimation
Direction="Bottom"
ToOffset="{ThemeResource ListViewItemReorderHintThemeOffset}"
TargetName="ContentBorder" />
</Storyboard>
</VisualState>
<VisualState x:Name="TopReorderHint">
<Storyboard>
<DragOverThemeAnimation
Direction="Top"
ToOffset="{ThemeResource ListViewItemReorderHintThemeOffset}"
TargetName="ContentBorder" />
</Storyboard>
</VisualState>
<VisualState x:Name="RightReorderHint">
<Storyboard>
<DragOverThemeAnimation
Direction="Right"
ToOffset="{ThemeResource ListViewItemReorderHintThemeOffset}"
TargetName="ContentBorder" />
</Storyboard>
</VisualState>
<VisualState x:Name="LeftReorderHint">
<Storyboard>
<DragOverThemeAnimation
Direction="Left"
ToOffset="{ThemeResource ListViewItemReorderHintThemeOffset}"
TargetName="ContentBorder" />
</Storyboard>
</VisualState>
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.2" To="NoReorderHint" />
</VisualStateGroup.Transitions>
</VisualStateGroup>
<VisualStateGroup x:Name="DragStates">
<VisualState x:Name="NotDragging" />
<VisualState x:Name="Dragging">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="ContentBorder"
Storyboard.TargetProperty="Opacity"
To="{ThemeResource ListViewItemDragThemeOpacity}"
Duration="0" />
<DragItemThemeAnimation TargetName="ContentBorder" />
</Storyboard>
</VisualState>
<VisualState x:Name="DraggingTarget" />
<VisualState x:Name="MultipleDraggingPrimary">
<Storyboard>
<!--
These two Opacity animations are required - the FadeInThemeAnimations
on the same elements animate an internal Opacity.
-->
<DoubleAnimation
Storyboard.TargetName="MultiArrangeOverlayText"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0" />
<DoubleAnimation
Storyboard.TargetName="MultiArrangeOverlayTextBorder"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0" />
<DoubleAnimation
Storyboard.TargetName="MultiSelectSquare"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="0" />
<DoubleAnimation
Storyboard.TargetName="MultiSelectCheck"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="0" />
<DoubleAnimation
Storyboard.TargetName="ContentBorder"
Storyboard.TargetProperty="Opacity"
To="{ThemeResource ListViewItemDragThemeOpacity}"
Duration="0" />
<FadeInThemeAnimation TargetName="MultiArrangeOverlayText" />
<FadeInThemeAnimation TargetName="MultiArrangeOverlayTextBorder" />
<DragItemThemeAnimation TargetName="ContentBorder" />
</Storyboard>
</VisualState>
<VisualState x:Name="MultipleDraggingSecondary" />
<VisualState x:Name="DraggedPlaceholder" />
<VisualState x:Name="Reordering">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="ContentBorder"
Storyboard.TargetProperty="Opacity"
To="{ThemeResource ListViewItemReorderThemeOpacity}"
Duration="0:0:0.240" />
</Storyboard>
</VisualState>
<VisualState x:Name="ReorderingTarget">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="ContentBorder"
Storyboard.TargetProperty="Opacity"
To="{ThemeResource ListViewItemReorderTargetThemeOpacity}"
Duration="0:0:0.240" />
<DoubleAnimation
Storyboard.TargetName="ContentBorderScale"
Storyboard.TargetProperty="ScaleX"
To="{ThemeResource ListViewItemReorderTargetThemeScale}"
Duration="0:0:0.240" />
<DoubleAnimation
Storyboard.TargetName="ContentBorderScale"
Storyboard.TargetProperty="ScaleY"
To="{ThemeResource ListViewItemReorderTargetThemeScale}"
Duration="0:0:0.240" />
</Storyboard>
</VisualState>
<VisualState x:Name="MultipleReorderingPrimary">
<Storyboard>
<!--
These two Opacity animations are required - the FadeInThemeAnimations
on the same elements animate an internal Opacity.
-->
<DoubleAnimation
Storyboard.TargetName="MultiArrangeOverlayText"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0" />
<DoubleAnimation
Storyboard.TargetName="MultiArrangeOverlayTextBorder"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0" />
<DoubleAnimation
Storyboard.TargetName="MultiSelectSquare"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="0" />
<DoubleAnimation
Storyboard.TargetName="MultiSelectCheck"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="0" />
<DoubleAnimation
Storyboard.TargetName="ContentBorder"
Storyboard.TargetProperty="Opacity"
To="{ThemeResource ListViewItemDragThemeOpacity}"
Duration="0:0:0.240" />
<FadeInThemeAnimation TargetName="MultiArrangeOverlayText" />
<FadeInThemeAnimation TargetName="MultiArrangeOverlayTextBorder" />
</Storyboard>
</VisualState>
<VisualState x:Name="ReorderedPlaceholder">
<Storyboard>
<FadeOutThemeAnimation TargetName="ContentBorder" />
</Storyboard>
</VisualState>
<VisualState x:Name="DragOver">
<Storyboard>
<DropTargetItemThemeAnimation TargetName="ContentBorder" />
</Storyboard>
</VisualState>
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.2" To="NotDragging" />
</VisualStateGroup.Transitions>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate x:Key="DefaultNavigationTemplate" x:DataType="local:OOBEItem">
<Grid Padding="16" ColumnSpacing="12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="24" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<FontIcon FontSize="16" Glyph="{x:Bind Icon}" />
<TextBlock Grid.Column="1" Text="{x:Bind Header}" />
</Grid>
</DataTemplate>
<DataTemplate x:Key="SelectedNavigationTemplate" x:DataType="local:OOBEItem">
<Grid
Padding="16"
ColumnSpacing="12"
RowSpacing="4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="24" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<FontIcon
FontSize="16"
Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}"
Glyph="{x:Bind Icon}" />
<TextBlock
Grid.Column="1"
FontWeight="SemiBold"
Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}"
Text="{x:Bind Header}" />
<TextBlock
Grid.Row="1"
Grid.Column="1"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{x:Bind Description}"
TextWrapping="Wrap" />
</Grid>
</DataTemplate>
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="448" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid
Background="{ThemeResource LayerFillColorDefaultBrush}"
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
BorderThickness="0,0,1,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Margin="32,64,32,32" Orientation="Vertical">
<Image
Width="64"
Height="64"
Source="{x:Bind Icon, Mode=OneWay}" />
<TextBlock
Margin="0,16,0,0"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="{x:Bind Subtitle, Mode=OneWay}"
TextAlignment="Center" />
<TextBlock
Margin="0,-4,0,0"
CharacterSpacing="36"
FontSize="36"
FontWeight="SemiBold"
Text="{x:Bind Title, Mode=OneWay}"
TextAlignment="Center" />
</StackPanel>
<ListView
x:Name="navigationList"
Grid.Row="1"
Margin="16,16,16,16"
ItemContainerStyle="{StaticResource ExpandableListViewItemContainerStyle}"
ItemTemplate="{StaticResource DefaultNavigationTemplate}"
ItemsSource="{x:Bind NavigationItems, Mode=OneWay}"
Loaded="NavigationList_Loaded"
SelectionChanged="NavigationList_SelectionChanged">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" Spacing="8">
<StackPanel.ChildrenTransitions>
<RepositionThemeTransition />
</StackPanel.ChildrenTransitions>
</StackPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
</Grid>
<FlipView
Grid.Column="1"
Background="Transparent"
ItemsSource="{x:Bind NavigationItems, Mode=OneWay}"
Loaded="FlipView_Loaded"
SelectedIndex="{Binding ElementName=navigationList, Path=SelectedIndex, Mode=TwoWay}">
<FlipView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</FlipView.ItemsPanel>
<FlipView.ItemTemplate>
<DataTemplate x:DataType="local:OOBEItem">
<Grid Margin="0,120,0,16">
<StackPanel Orientation="Vertical">
<ContentPresenter
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Content="{x:Bind Content, Mode=OneWay}" />
<HyperlinkButton
Margin="0,24,0,0"
Padding="0"
HorizontalAlignment="Center"
Click="NextButton_Click">
<StackPanel Orientation="Vertical" Spacing="8">
<TextBlock Text="Next" />
<FontIcon FontSize="12" Glyph="&#xE74B;" />
</StackPanel>
</HyperlinkButton>
</StackPanel>
</Grid>
</DataTemplate>
</FlipView.ItemTemplate>
</FlipView>
</Grid>
</UserControl>

View File

@@ -0,0 +1,121 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Microsoft.PowerToys.Settings.UI.Controls;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using Windows.Foundation;
using Windows.Foundation.Collections;
namespace Microsoft.PowerToys.Settings.UI.Controls
{
public sealed partial class OOBEControl : UserControl
{
public static readonly DependencyProperty IconProperty = DependencyProperty.Register(
nameof(Icon),
typeof(ImageSource),
typeof(OOBEControl),
new PropertyMetadata(defaultValue: null));
public ImageSource Icon
{
get => (ImageSource)GetValue(IconProperty);
set => SetValue(IconProperty, value);
}
public static readonly DependencyProperty TitleProperty = DependencyProperty.Register(
nameof(Title),
typeof(string),
typeof(OOBEControl),
new PropertyMetadata(defaultValue: null));
public string Title
{
get => (string)GetValue(TitleProperty);
set => SetValue(TitleProperty, value);
}
public static readonly DependencyProperty SubtitleProperty = DependencyProperty.Register(
nameof(Subtitle),
typeof(string),
typeof(OOBEControl),
new PropertyMetadata(defaultValue: null));
public string Subtitle
{
get => (string)GetValue(SubtitleProperty);
set => SetValue(SubtitleProperty, value);
}
public static readonly DependencyProperty NavigationItemsProperty = DependencyProperty.Register(
nameof(NavigationItems),
typeof(ObservableCollection<OOBEItem>),
typeof(OOBEControl),
new PropertyMetadata(defaultValue: new ObservableCollection<OOBEItem>()));
public ObservableCollection<OOBEItem> NavigationItems
{
get => (ObservableCollection<OOBEItem>)GetValue(NavigationItemsProperty);
set => SetValue(NavigationItemsProperty, value);
}
public OOBEControl()
{
InitializeComponent();
}
private void NavigationList_Loaded(object sender, RoutedEventArgs e)
{
navigationList.SelectedIndex = 0;
}
private void NavigationList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// Assign DataTemplate for selected items
foreach (var item in e.AddedItems)
{
if (sender is ListView lv && lv.ContainerFromItem(item) is ListViewItem lvi)
{
lvi.ContentTemplate = (DataTemplate)this.Resources["SelectedNavigationTemplate"];
}
}
// Remove DataTemplate for unselected items
foreach (var item in e.RemovedItems)
{
if (sender is ListView lv && lv.ContainerFromItem(item) is ListViewItem lvi)
{
lvi.ContentTemplate = (DataTemplate)this.Resources["DefaultNavigationTemplate"];
}
}
}
private void NextButton_Click(object sender, RoutedEventArgs e)
{
int count = navigationList.SelectedIndex + 1;
if (count >= navigationList.Items.Count)
{
count = 0;
}
navigationList.SelectedIndex = count;
}
private void FlipView_Loaded(object sender, RoutedEventArgs e)
{
}
}
}

View File

@@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.PowerToys.Settings.UI.Controls
{
public class OOBEItem
{
public string Header { get; set; }
public string Description { get; set; }
public string Icon { get; set; }
public object Content { get; set; }
}
}

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8" ?>
<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.Controls">
<Style BasedOn="{StaticResource DefaultRedirectVisualViewStyle}" TargetType="local:RedirectVisualView" />
<Style x:Key="DefaultRedirectVisualViewStyle" TargetType="local:RedirectVisualView">
<Setter Property="IsTabStop" Value="False" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="Padding" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:RedirectVisualView">
<Grid x:Name="LayoutRoot">
<Canvas
x:Name="OpacityMaskContainer"
Width="0"
Height="0"
Visibility="Collapsed" />
<Grid HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<Grid x:Name="ChildPresenterContainer">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ContentPresenter
x:Name="ChildPresenter"
Margin="{TemplateBinding Padding}"
Content="{TemplateBinding Child}" />
</Grid>
<Canvas
x:Name="ChildHost"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" />
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

View File

@@ -0,0 +1,369 @@
// 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.Numerics;
using Microsoft.UI.Composition;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Hosting;
using Microsoft.UI.Xaml.Markup;
#pragma warning disable CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
namespace Microsoft.PowerToys.Settings.UI.Controls
{
[ContentProperty(Name = nameof(Child))]
public partial class RedirectVisualView : Control
{
public RedirectVisualView()
{
this.DefaultStyleKey = typeof(RedirectVisualView);
childVisualBrushOffsetEnabled = ChildVisualBrushOffsetEnabled;
hostVisual = ElementCompositionPreview.GetElementVisual(this);
compositor = hostVisual.Compositor;
childVisualSurface = compositor.CreateVisualSurface();
childVisualBrush = compositor.CreateSurfaceBrush(childVisualSurface);
childVisualBrush.HorizontalAlignmentRatio = 0;
childVisualBrush.VerticalAlignmentRatio = 0;
childVisualBrush.Stretch = CompositionStretch.None;
redirectVisual = compositor.CreateSpriteVisual();
redirectVisual.RelativeSizeAdjustment = Vector2.One;
redirectVisual.Brush = childVisualBrush;
if (childVisualBrushOffsetEnabled)
{
offsetBind = compositor.CreateExpressionAnimation("Vector2(visual.Offset.X, visual.Offset.Y)");
}
this.Loaded += RedirectVisualView_Loaded;
this.Unloaded += RedirectVisualView_Unloaded;
RegisterPropertyChangedCallback(PaddingProperty, OnPaddingPropertyChanged);
}
protected virtual bool ChildVisualBrushOffsetEnabled => true;
private bool measureChildInBoundingBox = true;
protected bool MeasureChildInBoundingBox
{
get => measureChildInBoundingBox;
set
{
if (measureChildInBoundingBox != value)
{
measureChildInBoundingBox = value;
UpdateMeasureChildInBoundingBox();
}
}
}
protected bool RedirectVisualAttached => attached;
protected bool RedirectVisualEnabled
{
get => redirectVisualEnabled;
set
{
if (redirectVisualEnabled != value)
{
redirectVisualEnabled = value;
if (value)
{
if (IsLoaded)
{
AttachVisuals();
}
}
else
{
DetachVisuals();
}
}
}
}
private bool attached;
private bool redirectVisualEnabled = true;
private bool childVisualBrushOffsetEnabled;
private Grid? layoutRoot;
private ContentPresenter? childPresenter;
private Grid? childPresenterContainer;
private Canvas? childHost;
private Canvas? opacityMaskContainer;
protected Grid? LayoutRoot
{
get => layoutRoot;
private set
{
if (layoutRoot != value)
{
var old = layoutRoot;
layoutRoot = value;
if (old != null)
{
old.SizeChanged -= LayoutRoot_SizeChanged;
}
if (layoutRoot != null)
{
layoutRoot.SizeChanged += LayoutRoot_SizeChanged;
}
}
}
}
protected ContentPresenter? ChildPresenter
{
get => childPresenter;
private set
{
if (childPresenter != value)
{
var old = childPresenter;
childPresenter = value;
if (old != null)
{
old.SizeChanged -= ChildPresenter_SizeChanged;
}
if (childPresenter != null)
{
childPresenter.SizeChanged += ChildPresenter_SizeChanged;
}
}
}
}
protected Grid? ChildPresenterContainer
{
get => childPresenterContainer;
private set
{
if (childPresenterContainer != value)
{
childPresenterContainer = value;
UpdateMeasureChildInBoundingBox();
}
}
}
protected Canvas? OpacityMaskContainer
{
get => opacityMaskContainer;
private set => opacityMaskContainer = value;
}
private Visual hostVisual;
private Compositor compositor;
private CompositionVisualSurface childVisualSurface;
private CompositionSurfaceBrush childVisualBrush;
private SpriteVisual redirectVisual;
private ExpressionAnimation? offsetBind;
protected CompositionBrush ChildVisualBrush => childVisualBrush;
protected SpriteVisual RootVisual
{
get => redirectVisual;
set => redirectVisual = value;
}
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
DetachVisuals();
LayoutRoot = GetTemplateChild(nameof(LayoutRoot)) as Grid;
ChildPresenter = GetTemplateChild(nameof(ChildPresenter)) as ContentPresenter;
ChildPresenterContainer = GetTemplateChild(nameof(ChildPresenterContainer)) as Grid;
childHost = GetTemplateChild(nameof(childHost)) as Canvas;
OpacityMaskContainer = GetTemplateChild(nameof(OpacityMaskContainer)) as Canvas;
if (RedirectVisualEnabled)
{
AttachVisuals();
}
}
public UIElement? Child
{
get { return (UIElement?)GetValue(ChildProperty); }
set { SetValue(ChildProperty, value); }
}
public static readonly DependencyProperty ChildProperty =
DependencyProperty.Register("Child", typeof(UIElement), typeof(RedirectVisualView), new PropertyMetadata(null));
private void AttachVisuals()
{
if (attached)
{
return;
}
attached = true;
if (LayoutRoot != null)
{
if (ChildPresenter != null)
{
var childBorderVisual = ElementCompositionPreview.GetElementVisual(ChildPresenter);
childVisualSurface.SourceVisual = childBorderVisual;
if (offsetBind != null)
{
offsetBind.SetReferenceParameter("visual", childBorderVisual);
childVisualBrush.StartAnimation("Offset", offsetBind);
}
}
if (ChildPresenterContainer != null)
{
ElementCompositionPreview.GetElementVisual(ChildPresenterContainer).IsVisible = false;
}
if (OpacityMaskContainer != null)
{
ElementCompositionPreview.GetElementVisual(OpacityMaskContainer).IsVisible = false;
}
if (childHost != null)
{
ElementCompositionPreview.SetElementChildVisual(childHost, redirectVisual);
}
UpdateSize();
}
OnAttachVisuals();
}
private void DetachVisuals()
{
if (!attached)
{
return;
}
attached = false;
if (LayoutRoot != null)
{
childVisualSurface.SourceVisual = null;
if (offsetBind != null)
{
childVisualBrush.StopAnimation("Offset");
offsetBind.ClearAllParameters();
}
if (ChildPresenterContainer != null)
{
ElementCompositionPreview.GetElementVisual(ChildPresenterContainer).IsVisible = true;
}
if (OpacityMaskContainer != null)
{
ElementCompositionPreview.GetElementVisual(OpacityMaskContainer).IsVisible = true;
}
if (childHost != null)
{
ElementCompositionPreview.SetElementChildVisual(childHost, null);
}
}
OnDetachVisuals();
}
private void RedirectVisualView_Unloaded(object sender, RoutedEventArgs e)
{
DetachVisuals();
}
private void RedirectVisualView_Loaded(object sender, RoutedEventArgs e)
{
if (RedirectVisualEnabled)
{
AttachVisuals();
}
}
private void OnPaddingPropertyChanged(DependencyObject sender, DependencyProperty dp)
{
UpdateSize();
}
private void LayoutRoot_SizeChanged(object sender, SizeChangedEventArgs e)
{
UpdateSize();
}
private void ChildPresenter_SizeChanged(object sender, SizeChangedEventArgs e)
{
UpdateSize();
}
private void UpdateSize()
{
if (attached && LayoutRoot != null)
{
if (ChildPresenter != null)
{
childVisualSurface.SourceSize = new Vector2((float)ChildPresenter.ActualWidth, (float)ChildPresenter.ActualHeight);
}
}
OnUpdateSize();
}
private void UpdateMeasureChildInBoundingBox()
{
if (ChildPresenterContainer != null)
{
var value = MeasureChildInBoundingBox;
var length = new GridLength(1, value ? GridUnitType.Star : GridUnitType.Auto);
if (ChildPresenterContainer.RowDefinitions.Count > 0)
{
ChildPresenterContainer.RowDefinitions[0].Height = length;
}
if (ChildPresenterContainer.ColumnDefinitions.Count > 0)
{
ChildPresenterContainer.ColumnDefinitions[0].Width = length;
}
}
}
protected virtual void OnAttachVisuals()
{
}
protected virtual void OnDetachVisuals()
{
}
protected virtual void OnUpdateSize()
{
}
}
}
#pragma warning restore CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8" ?>
<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.Controls">
<Style BasedOn="{StaticResource DefaultOpacityMaskViewStyle}" TargetType="local:OpacityMaskView" />
<Style x:Key="DefaultOpacityMaskViewStyle" TargetType="local:OpacityMaskView">
<Setter Property="IsTabStop" Value="False" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Top" />
<Setter Property="CornerRadius" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:OpacityMaskView">
<Grid
x:Name="PART_RootGrid"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<Border
x:Name="PART_MaskContainer"
Child="{TemplateBinding OpacityMask}"
CornerRadius="{TemplateBinding CornerRadius}"
IsHitTestVisible="False" />
<ContentPresenter
x:Name="PART_ContentPresenter"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
CornerRadius="{TemplateBinding CornerRadius}" />
<Grid
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="{ThemeResource AcrylicBackgroundFillColorDefaultBrush}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

View File

@@ -0,0 +1,106 @@
// 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.Numerics;
using Microsoft.UI.Composition;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Hosting;
using Microsoft.UI.Xaml.Media;
namespace Microsoft.PowerToys.Settings.UI.Controls;
/// <summary>
/// A control that applies an opacity mask to its content.
/// </summary>
[TemplatePart(Name = RootGridTemplateName, Type = typeof(Grid))]
[TemplatePart(Name = MaskContainerTemplateName, Type = typeof(Border))]
[TemplatePart(Name = ContentPresenterTemplateName, Type = typeof(ContentPresenter))]
public partial class OpacityMaskView : ContentControl
{
// This is from Windows Community Toolkit Labs: https://github.com/CommunityToolkit/Labs-Windows/pull/491
/// <summary>
/// Identifies the <see cref="OpacityMask"/> property.
/// </summary>
public static readonly DependencyProperty OpacityMaskProperty =
DependencyProperty.Register(nameof(OpacityMask), typeof(UIElement), typeof(OpacityMaskView), new PropertyMetadata(null, OnOpacityMaskChanged));
private const string ContentPresenterTemplateName = "PART_ContentPresenter";
private const string MaskContainerTemplateName = "PART_MaskContainer";
private const string RootGridTemplateName = "PART_RootGrid";
private readonly Compositor _compositor = CompositionTarget.GetCompositorForCurrentThread();
private CompositionBrush _mask;
private CompositionMaskBrush _maskBrush;
/// <summary>
/// Initializes a new instance of the <see cref="OpacityMaskView"/> class.
/// Creates a new instance of the <see cref="OpacityMaskView"/> class.
/// </summary>
public OpacityMaskView()
{
DefaultStyleKey = typeof(OpacityMaskView);
}
/// <summary>
/// Gets or sets a <see cref="UIElement"/> as the opacity mask that is applied to alpha-channel masking for the rendered content of the content.
/// </summary>
public UIElement OpacityMask
{
get => (UIElement)GetValue(OpacityMaskProperty);
set => SetValue(OpacityMaskProperty, value);
}
/// <inheritdoc />
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
Grid rootGrid = (Grid)GetTemplateChild(RootGridTemplateName);
ContentPresenter contentPresenter = (ContentPresenter)GetTemplateChild(ContentPresenterTemplateName);
Border maskContainer = (Border)GetTemplateChild(MaskContainerTemplateName);
_maskBrush = _compositor.CreateMaskBrush();
_maskBrush.Source = GetVisualBrush(contentPresenter);
_mask = GetVisualBrush(maskContainer);
_maskBrush.Mask = OpacityMask is null ? null : _mask;
SpriteVisual redirectVisual = _compositor.CreateSpriteVisual();
redirectVisual.RelativeSizeAdjustment = Vector2.One;
redirectVisual.Brush = _maskBrush;
ElementCompositionPreview.SetElementChildVisual(rootGrid, redirectVisual);
}
private static CompositionBrush GetVisualBrush(UIElement element)
{
Visual visual = ElementCompositionPreview.GetElementVisual(element);
Compositor compositor = visual.Compositor;
CompositionVisualSurface visualSurface = compositor.CreateVisualSurface();
visualSurface.SourceVisual = visual;
ExpressionAnimation sourceSizeAnimation = compositor.CreateExpressionAnimation($"{nameof(visual)}.Size");
sourceSizeAnimation.SetReferenceParameter(nameof(visual), visual);
visualSurface.StartAnimation(nameof(visualSurface.SourceSize), sourceSizeAnimation);
CompositionSurfaceBrush brush = compositor.CreateSurfaceBrush(visualSurface);
visual.Opacity = 0;
return brush;
}
private static void OnOpacityMaskChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
OpacityMaskView self = (OpacityMaskView)d;
if (self._maskBrush is not { } maskBrush)
{
return;
}
UIElement opacityMask = (UIElement)e.NewValue;
maskBrush.Mask = opacityMask is null ? null : self._mask;
}
}

View File

@@ -2,104 +2,226 @@
x:Class="Microsoft.PowerToys.Settings.UI.Controls.SettingsPageControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:animations="using:CommunityToolkit.WinUI.Animations"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:converters="using:Microsoft.PowerToys.Settings.UI.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:media="using:CommunityToolkit.WinUI.Media"
xmlns:tk7controls="using:CommunityToolkit.WinUI.UI.Controls"
xmlns:tkconverters="using:CommunityToolkit.WinUI.Converters"
xmlns:toolkit="using:CommunityToolkit.WinUI.Controls"
Loaded="UserControl_Loaded"
mc:Ignorable="d">
<UserControl.Resources>
<x:Double x:Key="PageMaxWidth">1000</x:Double>
<x:Double x:Key="PageHeaderMaxWidth">1020</x:Double>
<converters:UriToImageSourceConverter x:Key="UriToImageSourceConverter" />
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<RadialGradientBrush x:Key="OverlayRadialGradient" Center="0.5,0.22" GradientOrigin="0.5,0" MappingMode="RelativeToBoundingBox" RadiusX="0.92" RadiusY="0.8200000000000001" SpreadMethod="Pad">
<GradientStop Offset="0" Color="#FFFFFFFF" />
<GradientStop Offset="0.05" Color="#FFFFFFFF" />
<GradientStop Offset="0.35" Color="#FFFFFFFF" />
<GradientStop Offset="0.55" Color="#FFFFFFFF" />
<GradientStop Offset="0.95" Color="#00FFFFFF" />
<GradientStop Offset="1" Color="#00FFFFFF" />
</RadialGradientBrush>
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<RadialGradientBrush x:Key="OverlayRadialGradient" Center="0.5,0.22" GradientOrigin="0.5,0.0" MappingMode="RelativeToBoundingBox" RadiusX="0.92" RadiusY="0.8200000000000001" SpreadMethod="Pad">
<GradientStop Offset="0" Color="#FF000000" />
<GradientStop Offset="0.05" Color="#FF000000" />
<GradientStop Offset="0.35" Color="#FF000000" />
<GradientStop Offset="0.55" Color="#FF000000" />
<GradientStop Offset="0.85" Color="#00000000" />
<GradientStop Offset="0.95" Color="#00000000" />
<GradientStop Offset="1" Color="#00000000" />
</RadialGradientBrush>
</ResourceDictionary>
<ResourceDictionary x:Key="HighContrast">
<RadialGradientBrush x:Key="OverlayRadialGradient" Center="0.5,0.22" GradientOrigin="0.5,0" MappingMode="RelativeToBoundingBox" RadiusX="0.92" RadiusY="0.8200000000000001" SpreadMethod="Pad">
<GradientStop Offset="0" Color="#FF000000" />
<GradientStop Offset="0.05" Color="#FF000000" />
<GradientStop Offset="0.35" Color="#FF000000" />
<GradientStop Offset="0.55" Color="#FF000000" />
<GradientStop Offset="0.95" Color="#00000000" />
<GradientStop Offset="1" Color="#00000000" />
</RadialGradientBrush>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
<x:Double x:Key="PageMaxWidth">1000</x:Double>
<x:Double x:Key="PageHeaderMaxWidth">1020</x:Double>
<tkconverters:DoubleToVisibilityConverter
x:Name="doubleToVisibilityConverter"
FalseValue="Collapsed"
GreaterThan="0"
TrueValue="Visible" />
<animations:ImplicitAnimationSet x:Name="ShowTransitions">
<animations:OffsetAnimation
EasingMode="EaseOut"
From="0,24,0"
To="0"
Duration="0:0:0.4" />
<animations:OpacityAnimation
EasingMode="EaseOut"
From="0"
To="1"
Duration="0:0:0.2" />
</animations:ImplicitAnimationSet>
<animations:ImplicitAnimationSet x:Name="HideTransitions">
<animations:OffsetAnimation
EasingMode="EaseOut"
From="0"
To="0,24,0"
Duration="0:0:0.2" />
<animations:OpacityAnimation
EasingMode="EaseOut"
From="1"
To="0"
Duration="0:0:0.1" />
</animations:ImplicitAnimationSet>
<converters:UriToImageSourceConverter x:Key="UriToImageSourceConverter" />
</ResourceDictionary>
</UserControl.Resources>
<Grid Padding="20,0,0,0" RowSpacing="24">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock
x:Name="Header"
MaxWidth="{StaticResource PageHeaderMaxWidth}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
AutomationProperties.HeadingLevel="1"
Style="{StaticResource TitleTextBlockStyle}"
Text="{x:Bind ModuleTitle}" />
<ScrollViewer Grid.Row="1">
<ScrollViewer Grid.Row="0">
<Grid
MaxWidth="{StaticResource PageHeaderMaxWidth}"
Padding="0,0,20,48"
ChildrenTransitions="{StaticResource SettingsCardsAnimations}"
RowSpacing="24">
RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<controls:OpacityMaskView
Grid.RowSpan="2"
MaxWidth="{StaticResource PageHeaderMaxWidth}"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
CornerRadius="8,8,8,0">
<controls:OpacityMaskView.OpacityMask>
<Rectangle Fill="{ThemeResource OverlayRadialGradient}" />
</controls:OpacityMaskView.OpacityMask>
<Grid>
<Image
x:Name="BackDropImage"
Height="186"
Source="{x:Bind ModuleImageSource, Converter={StaticResource UriToImageSourceConverter}, Mode=OneWay}"
Stretch="UniformToFill"
Visibility="Visible">
<media:UIElementExtensions.VisualFactory>
<media:PipelineVisualFactory>
<media:BlurEffect Amount="100.0" />
</media:PipelineVisualFactory>
</media:UIElementExtensions.VisualFactory>
</Image>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.Background>
<media:AcrylicBrush BlurAmount="100" />
</Grid.Background>
</Grid>
</Grid>
<!-- Top panel -->
<Grid MaxWidth="{StaticResource PageMaxWidth}" RowSpacing="16">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border
MaxWidth="160"
Margin="0,0,16,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
CornerRadius="{StaticResource OverlayCornerRadius}"
Visibility="{x:Bind ModuleImageSource, Converter={StaticResource EmptyObjectToObjectConverter}}">
<Image AutomationProperties.AccessibilityView="Raw" Source="{x:Bind ModuleImageSource, Converter={StaticResource UriToImageSourceConverter}, Mode=OneWay}" />
</Border>
<StackPanel x:Name="DescriptionPanel" Grid.Column="1">
<TextBlock
x:Name="AboutDescription"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="{x:Bind ModuleDescription}"
TextWrapping="Wrap" />
<ItemsControl
x:Name="PrimaryLinksControl"
Margin="0,8,0,0"
IsTabStop="False"
ItemsSource="{x:Bind PrimaryLinks}"
Visibility="{x:Bind PrimaryLinks.Count, Converter={StaticResource DoubleToVisibilityConverter}}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="controls:PageLink">
<HyperlinkButton NavigateUri="{x:Bind Link}" Style="{StaticResource TextButtonStyle}">
<TextBlock Text="{x:Bind Text}" TextWrapping="Wrap" />
</HyperlinkButton>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<tk7controls:WrapPanel HorizontalSpacing="24" Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</controls:OpacityMaskView>
<StackPanel
MaxWidth="{StaticResource PageHeaderMaxWidth}"
Margin="16,8,0,0"
Orientation="Vertical">
<StackPanel Orientation="Horizontal" Spacing="12">
<Image
Width="48"
VerticalAlignment="Top"
Source="/Assets/Settings/Icons/Awake.png" />
<StackPanel Orientation="Vertical">
<TextBlock
x:Name="Header"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
AutomationProperties.HeadingLevel="1"
Style="{StaticResource TitleTextBlockStyle}"
Text="{x:Bind ModuleTitle}" />
<TextBlock
x:Name="AboutDescription"
Grid.Row="1"
Margin="0,8,0,8"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="{x:Bind ModuleDescription}"
TextWrapping="Wrap" />
</StackPanel>
</StackPanel>
</Grid>
<!-- Content panel -->
<ContentPresenter
x:Name="ModuleContentPresenter"
<ToggleSwitch IsOn="True" />
</StackPanel>
<Border
MaxWidth="160"
Margin="0,16,16,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
CornerRadius="{StaticResource OverlayCornerRadius}"
Visibility="{x:Bind ModuleImageSource, Converter={StaticResource EmptyObjectToObjectConverter}}">
<Image AutomationProperties.AccessibilityView="Raw" Source="{x:Bind ModuleImageSource, Converter={StaticResource UriToImageSourceConverter}, Mode=OneWay}" />
</Border>
<Grid
Grid.Row="1"
MaxWidth="{StaticResource PageMaxWidth}"
Margin="0,12,0,0"
Content="{x:Bind ModuleContent}" />
Margin="0,56,0,0">
<SelectorBar x:Name="PivotBar">
<SelectorBarItem
IsSelected="True"
Tag="Settings"
Text="Settings" />
<SelectorBarItem Tag="Docs" Text="Documentation" />
</SelectorBar>
</Grid>
<toolkit:SwitchPresenter
Grid.Row="2"
MaxWidth="{StaticResource PageMaxWidth}"
Value="{Binding SelectedItem.Tag, ElementName=PivotBar}">
<toolkit:Case Value="Settings">
<!-- Content panel -->
<ContentPresenter
x:Name="ModuleContentPresenter"
Margin="0,12,0,0"
Content="{x:Bind ModuleContent}" />
</toolkit:Case>
<toolkit:Case Value="Docs">
<Grid
animations:Implicit.HideAnimations="{StaticResource HideTransitions}"
animations:Implicit.ShowAnimations="{StaticResource ShowTransitions}"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
BorderThickness="1"
CornerRadius="{StaticResource OverlayCornerRadius}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ListView
x:Name="TocList"
Grid.Column="1"
IsItemClickEnabled="True"
ItemClick="TocList_ItemClick"
SelectionMode="None" />
<ScrollViewer x:Name="DocScroll" Grid.Column="1" VerticalScrollMode="Auto" VerticalScrollBarVisibility="Auto">
<StackPanel x:Name="DocHost" Orientation="Vertical" />
</ScrollViewer>
<tk7controls:MarkdownTextBlock
x:Name="docsTextBlock"
Margin="16"
Background="Transparent" />
</Grid>
</toolkit:Case>
</toolkit:SwitchPresenter>
<!-- Bottom panel -->
<StackPanel
x:Name="SecondaryLinksPanel"
Grid.Row="2"
Grid.Row="3"
MaxWidth="{StaticResource PageMaxWidth}"
AutomationProperties.Name="{x:Bind SecondaryLinksHeader}"
Orientation="Vertical"
@@ -142,9 +264,9 @@
<AdaptiveTrigger MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="DescriptionPanel.(Grid.Row)" Value="1" />
<!--<Setter Target="DescriptionPanel.(Grid.Row)" Value="1" />
<Setter Target="DescriptionPanel.(Grid.Column)" Value="0" />
<Setter Target="DescriptionPanel.(Grid.ColumnSpan)" Value="2" />
<Setter Target="DescriptionPanel.(Grid.ColumnSpan)" Value="2" />-->
</VisualState.Setters>
</VisualState>
</VisualStateGroup>

View File

@@ -2,16 +2,21 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.ObjectModel;
using CommunityToolkit.WinUI.UI.Controls;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Net.Http;
using System.Text.RegularExpressions;
namespace Microsoft.PowerToys.Settings.UI.Controls
{
public sealed partial class SettingsPageControl : UserControl
{
private readonly Dictionary<string, FrameworkElement> _anchors = new();
public SettingsPageControl()
{
this.InitializeComponent();
@@ -69,9 +74,97 @@ namespace Microsoft.PowerToys.Settings.UI.Controls
public static readonly DependencyProperty SecondaryLinksProperty = DependencyProperty.Register(nameof(SecondaryLinks), typeof(ObservableCollection<PageLink>), typeof(SettingsPageControl), new PropertyMetadata(new ObservableCollection<PageLink>()));
public static readonly DependencyProperty ModuleContentProperty = DependencyProperty.Register(nameof(ModuleContent), typeof(object), typeof(SettingsPageControl), new PropertyMetadata(new Grid()));
private void UserControl_Loaded(object sender, RoutedEventArgs e)
private async void UserControl_Loaded(object sender, RoutedEventArgs e)
{
PrimaryLinksControl.Focus(FocusState.Programmatic);
// PrimaryLinksControl.Focus(FocusState.Programmatic);
var requestUrl = "https://raw.githubusercontent.com/MicrosoftDocs/windows-dev-docs/refs/heads/docs/hub/powertoys/advanced-paste.md";
using var client = new HttpClient();
var response = await client.GetAsync(requestUrl);
string content = await response.Content.ReadAsStringAsync();
docsTextBlock.Text = PreprocessMarkdown(content);
}
private sealed class TocItem
{
public string Id { get; init; } = string.Empty;
public string Title { get; init; } = string.Empty;
public int Level { get; init; }
}
private List<TocItem> BuildDocumentAndAnchors(string md)
{
DocHost.Children.Clear();
_anchors.Clear();
// Grab H1/H2
var headings = doc.Descendants<HeadingBlock>()
.Where(h => h.Level is 1 or 2)
.ToList();
var toc = new List<TocItem>();
if (headings.Count == 0)
{
DocHost.Children.Add(new MarkdownTextBlock { Text = md });
return toc;
}
// De-duplicate slugs like GitHub does
var seen = new Dictionary<string, int>();
for (int i = 0; i < headings.Count; i++)
{
var hb = headings[i];
// Char ranges for the slice belonging to this heading
int start = hb.Span.Start;
int end = (i + 1 < headings.Count) ? headings[i + 1].Span.Start : md.Length;
string sectionMd = md.Substring(start, end - start);
// Heading text
string title = hb.Inline?.FirstChild?.ToString() ?? "Section";
// Slug/anchor id
string id = MakeSlug(title);
if (seen.TryGetValue(id, out int n)) { n++; seen[id] = n; id = $"{id}-{n}"; }
else { seen[id] = 1; }
toc.Add(new TocItem { Id = id, Title = title, Level = hb.Level });
// Invisible anchor right before the slice so BringIntoView hits the correct spot
var anchor = new Border { Height = 1, Opacity = 0, Tag = id };
DocHost.Children.Add(anchor);
_anchors[id] = anchor;
// Render the sections markdown
var mdtb = new MarkdownTextBlock { Text = sectionMd };
mdtb.LinkClicked += Markdown_LinkClicked; // handle [links to #anchors] inside the doc
DocHost.Children.Add(mdtb);
}
return toc;
}
// Click in ToC -> scroll to anchor
private void TocList_ItemClick(object sender, ItemClickEventArgs e)
{
if (e.ClickedItem is TextBlock tb && tb.Tag is string id && _anchors.TryGetValue(id, out var target))
{
target.StartBringIntoView(); // Scrolls nearest ScrollViewer
}
}
public static string PreprocessMarkdown(string markdown)
{
markdown = Regex.Replace(markdown, @"\A---\n[\s\S]*?---\n", string.Empty, RegexOptions.Multiline);
markdown = Regex.Replace(markdown, @"^>\s*\[!IMPORTANT\]\s*> - Phi Silica is not available in China.\s*", string.Empty, RegexOptions.Multiline);
markdown = Regex.Replace(markdown, @"^>\s*\[!IMPORTANT\]", "> ** Important:**", RegexOptions.Multiline);
markdown = Regex.Replace(markdown, @"^>\s*\[!NOTE\]", "> **❗ Note:**", RegexOptions.Multiline);
markdown = Regex.Replace(markdown, @"^>\s*\[!TIP\]", "> **💡 Tip:**", RegexOptions.Multiline);
return markdown;
}
}
}

View File

@@ -104,7 +104,7 @@ namespace Microsoft.PowerToys.Settings.UI
{
if (App.GetOobeWindow() == null)
{
App.SetOobeWindow(new OobeWindow(OOBE.Enums.PowerToysModules.Overview));
App.SetOobeWindow(new Oobe2Window());
}
App.GetOobeWindow().Activate();
@@ -115,11 +115,10 @@ namespace Microsoft.PowerToys.Settings.UI
{
if (App.GetOobeWindow() == null)
{
App.SetOobeWindow(new OobeWindow(OOBE.Enums.PowerToysModules.WhatsNew));
}
else
{
App.GetOobeWindow().SetAppWindow(OOBE.Enums.PowerToysModules.WhatsNew);
App.SetOobeWindow(new Oobe2Window());
}
App.GetOobeWindow().Activate();

View File

@@ -0,0 +1,296 @@
<?xml version="1.0" encoding="utf-8" ?>
<winuiex:WindowEx
x:Class="Microsoft.PowerToys.Settings.UI.Oobe2Window"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Microsoft.PowerToys.Settings.UI.Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:toolkit="using:CommunityToolkit.WinUI.Controls"
xmlns:ui="using:CommunityToolkit.WinUI"
xmlns:winuiex="using:WinUIEx"
Title="Oobe2Window"
mc:Ignorable="d">
<Window.SystemBackdrop>
<MicaBackdrop />
</Window.SystemBackdrop>
<controls:OOBEControl
Title="PowerToys"
Icon="/Assets/Settings/logo150.png"
Subtitle="Get started with">
<controls:OOBEControl.NavigationItems>
<controls:OOBEItem
Description="Supercharge Windows. Your way."
Header="Overview"
Icon="&#xE80F;">
<controls:OOBEItem.Content>
<Grid
MinHeight="640"
MaxWidth="1920"
Margin="32"
Padding="0"
HorizontalAlignment="Center"
VerticalAlignment="Stretch"
CornerRadius="16"
Style="{StaticResource GridCardStyle}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Source="/Assets/Settings/Header.png" />
<Grid
Grid.Row="1"
Padding="48,32,48,0"
RowSpacing="12">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock
HorizontalAlignment="Center"
FontSize="28"
FontWeight="SemiBold"
Text="Microsoft PowerToys"
TextAlignment="Center"
TextWrapping="Wrap" />
<TextBlock
Grid.Row="1"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="A collection of advanced tools that boost productivity and unlock hidden capabilities in Windows."
TextAlignment="Center"
TextWrapping="Wrap" />
<StackPanel
Grid.Row="2"
Margin="0,36,0,32"
Orientation="Vertical"
Spacing="8">
<toolkit:SettingsCard Description="Diagnostic data helps us with bug fixes, performance, and product decisions" Header="Help us make PowerToys better">
<ToggleSwitch IsOn="True" />
</toolkit:SettingsCard>
<Button
Margin="0,48,0,0"
HorizontalAlignment="Center"
Content="Get started"
Style="{StaticResource AccentButtonStyle}" />
</StackPanel>
</Grid>
<Grid
HorizontalAlignment="Center"
VerticalAlignment="Top"
ColumnSpacing="24"
Visibility="Collapsed">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel
Margin="0,-24,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Orientation="Vertical">
<StackPanel Width="676" Orientation="Vertical">
<StackPanel
Padding="16"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
BorderThickness="1"
CornerRadius="{StaticResource OverlayCornerRadius}"
Orientation="Vertical">
<TextBlock
Margin="16,8,16,0"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="Tabs help you stay productive and in your flow. Configure your default shell to make sure you're always ready to go and be productive upon launch!"
TextWrapping="Wrap" />
<toolkit:SettingsCard
Margin="0,8,0,0"
Background="Transparent"
BorderThickness="0"
Header="Default profile">
<ComboBox SelectedIndex="0">
<ComboBoxItem>
<StackPanel Orientation="Horizontal" Spacing="8">
<Image Width="16" Source="/Assets/pwsh.png" />
<TextBlock Text="PowerShell" />
</StackPanel>
</ComboBoxItem>
</ComboBox>
</toolkit:SettingsCard>
</StackPanel>
</StackPanel>
</StackPanel>
</Grid>
</Grid>
</controls:OOBEItem.Content>
</controls:OOBEItem>
<controls:OOBEItem
Description="Smarter window control and layout tools to keep your desktop organized and efficient."
Header="Windowing &amp; layouts"
Icon="&#xEB91;">
<controls:OOBEItem.Content>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid HorizontalAlignment="Center" VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid x:Name="ShadowCastGrid" Grid.RowSpan="3" />
<Grid
Grid.Row="0"
Margin="32,0"
CornerRadius="8"
Translation="0,0,32">
<!--<controls:AnimatedImage
x:Name="HeroImage"
CornerRadius="8"
Loaded="HeroImage_Loaded" />-->
<!--<controls:CrossfadeTextBlock
x:Name="HeroTextBlock"
HorizontalAlignment="Left"
VerticalAlignment="Top"
FontSize="32"
FontWeight="SemiBold"
Text="Tralalala" />-->
<Grid.Shadow>
<ThemeShadow x:Name="PictureShadow" />
</Grid.Shadow>
</Grid>
<StackPanel
Grid.Row="1"
Margin="0,48,0,48"
Orientation="Vertical">
<TextBlock
FontWeight="SemiBold"
Style="{StaticResource SubtitleTextBlockStyle}"
Text="Explore these modules to make your more productive"
TextAlignment="Center" />
<TextBlock
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="Select which modules you want to enable."
TextAlignment="Center" />
</StackPanel>
</Grid>
</Grid>
</controls:OOBEItem.Content>
</controls:OOBEItem>
<controls:OOBEItem
Description="Enhanced keyboard and mouse tools to type, click, and control with precision."
Header="Mouse &amp; keyboard"
Icon="&#xE961;">
<controls:OOBEItem.Content>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid HorizontalAlignment="Center" VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel
Grid.Row="1"
Margin="0,48,0,48"
Orientation="Vertical">
<TextBlock
FontWeight="SemiBold"
Style="{StaticResource SubtitleTextBlockStyle}"
Text="Explore these modules to make your more productive"
TextAlignment="Center" />
<TextBlock
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="Select which modules you want to enable."
TextAlignment="Center" />
</StackPanel>
</Grid>
</Grid>
</controls:OOBEItem.Content>
</controls:OOBEItem>
<controls:OOBEItem
Description="Powerful tools to streamline, rename, resize, and unlock your file workflows."
Header="File management"
Icon="&#xEC50;">
<controls:OOBEItem.Content>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid HorizontalAlignment="Center" VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid x:Name="ShadowCastGrid2" Grid.RowSpan="3" />
<Grid
Grid.Row="0"
Margin="32,0"
CornerRadius="8"
Translation="0,0,32">
<!--<controls:CrossfadeTextBlock
x:Name="HeroTextBlock"
HorizontalAlignment="Left"
VerticalAlignment="Top"
FontSize="32"
FontWeight="SemiBold"
Text="Tralalala" />-->
<Grid.Shadow>
<ThemeShadow x:Name="PictureShadow2" />
</Grid.Shadow>
</Grid>
<StackPanel
Grid.Row="1"
Margin="0,48,0,48"
Orientation="Vertical">
<TextBlock
FontWeight="SemiBold"
Style="{StaticResource SubtitleTextBlockStyle}"
Text="Explore these modules to make your more productive"
TextAlignment="Center" />
<TextBlock
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="Select which modules you want to enable."
TextAlignment="Center" />
</StackPanel>
</Grid>
</Grid>
</controls:OOBEItem.Content>
</controls:OOBEItem>
<controls:OOBEItem
Description="Developer-focused tools for deeper control over your system and environment."
Header="Advanced tools"
Icon="&#xE835;">
<controls:OOBEItem.Content>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<StackPanel Width="676" Orientation="Vertical">
<Grid
HorizontalAlignment="Center"
VerticalAlignment="Top"
ColumnSpacing="24"
Style="{StaticResource GridCardStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MaxWidth="560" />
<ColumnDefinition Width="*" MaxWidth="480" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="1" TextWrapping="Wrap">
<Run
FontSize="20"
FontWeight="SemiBold"
Text="Rendering" /> <LineBreak /><Run Text="Windows Terminal has a powerful rendering engine that can support emojis, sixels, and shaders. You can even enable “Retro terminal effects” under your profile appearances. " />
</TextBlock>
</Grid>
</StackPanel>
</Grid>
</controls:OOBEItem.Content>
</controls:OOBEItem>
</controls:OOBEControl.NavigationItems>
</controls:OOBEControl>
</winuiex:WindowEx>

View File

@@ -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;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using Windows.Foundation;
using Windows.Foundation.Collections;
using WinUIEx;
namespace Microsoft.PowerToys.Settings.UI
{
public sealed partial class Oobe2Window : WindowEx
{
public Oobe2Window()
{
InitializeComponent();
this.ExtendsContentIntoTitleBar = true;
}
}
}

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<winuiex:WindowEx
x:Class="Microsoft.PowerToys.Settings.UI.ScoobeWindow"
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:local="using:Microsoft.PowerToys.Settings.UI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:winuiex="using:WinUIEx"
Title="ScoobeWindow"
mc:Ignorable="d">
<winuiex:WindowEx.SystemBackdrop>
<MicaBackdrop />
</winuiex:WindowEx.SystemBackdrop>
<Grid />
</winuiex:WindowEx>

View File

@@ -0,0 +1,20 @@
// 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 WinUIEx;
namespace Microsoft.PowerToys.Settings.UI
{
/// <summary>
/// An empty window that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class ScoobeWindow : WindowEx
{
public ScoobeWindow()
{
InitializeComponent();
}
}
}

View File

@@ -55,16 +55,8 @@ namespace Microsoft.PowerToys.Settings.UI.Views
private void WhatsNewButton_Click(object sender, RoutedEventArgs e)
{
if (App.GetOobeWindow() == null)
{
App.SetOobeWindow(new OobeWindow(PowerToysModules.WhatsNew));
}
else
{
App.GetOobeWindow().SetAppWindow(PowerToysModules.WhatsNew);
}
App.GetOobeWindow().Activate();
ScoobeWindow window = new ScoobeWindow();
window.Activate();
}
}
}

View File

@@ -363,7 +363,8 @@ namespace Microsoft.PowerToys.Settings.UI.Views
private void OOBEItem_Tapped(object sender, TappedRoutedEventArgs e)
{
OpenOobeWindowCallback();
Oobe2Window window = new Oobe2Window();
window.Activate();
}
private async void FeedbackItem_Tapped(object sender, TappedRoutedEventArgs e)
@@ -373,7 +374,6 @@ namespace Microsoft.PowerToys.Settings.UI.Views
private void WhatIsNewItem_Tapped(object sender, TappedRoutedEventArgs e)
{
OpenWhatIsNewWindowCallback();
}
private void NavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)