[Settings] Optimizing and cleaning up code (#44721)

<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request

- Removing dead experiments code
- Refactoring and simplifying OOBE/SCOOBE windowing code
- Removing dead assets
- Optimizing CmdPal assets to lower res shaving off a few MBs
- Scrolling works better on the What's new page
- Should be merged after: #44638

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [X] Closes: #44958
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx

<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed

---------

Co-authored-by: Gordon Lam (SH) <yeelam@microsoft.com>
This commit is contained in:
Niels Laute
2026-02-12 03:35:58 +01:00
committed by GitHub
parent 3385d1d741
commit 528fb524d0
78 changed files with 800 additions and 2479 deletions

View File

@@ -18,15 +18,16 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobeAdvancedPaste()
{
this.InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.AdvancedPaste]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.AdvancedPaste);
DataContext = ViewModel;
}
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(AdvancedPastePage));
OobeWindow.OpenMainWindowCallback(typeof(AdvancedPastePage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -18,15 +18,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobeAlwaysOnTop()
{
InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.AlwaysOnTop]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.AlwaysOnTop);
DataContext = ViewModel;
}
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(AlwaysOnTopPage));
OobeWindow.OpenMainWindowCallback(typeof(AlwaysOnTopPage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -17,15 +17,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobeAwake()
{
InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.Awake]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.Awake);
DataContext = ViewModel;
}
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(AwakePage));
OobeWindow.OpenMainWindowCallback(typeof(AwakePage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -18,15 +18,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobeCmdNotFound()
{
this.InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.CmdNotFound]);
ViewModel = ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.CmdNotFound);
DataContext = ViewModel;
}
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(CmdNotFoundPage));
OobeWindow.OpenMainWindowCallback(typeof(CmdNotFoundPage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -18,15 +18,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobeCmdPal()
{
this.InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.CmdPal]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.CmdPal);
DataContext = ViewModel;
}
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(CmdPalPage));
OobeWindow.OpenMainWindowCallback(typeof(CmdPalPage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -21,15 +21,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobeColorPicker()
{
this.InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.ColorPicker]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.ColorPicker);
DataContext = ViewModel;
}
private void Start_ColorPicker_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.ColorPickerSharedEventCallback != null)
if (OobeWindow.ColorPickerSharedEventCallback != null)
{
using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, OobeShellPage.ColorPickerSharedEventCallback()))
using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, OobeWindow.ColorPickerSharedEventCallback()))
{
eventHandle.Set();
}
@@ -40,9 +40,9 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(ColorPickerPage));
OobeWindow.OpenMainWindowCallback(typeof(ColorPickerPage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -18,15 +18,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobeCropAndLock()
{
InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.CropAndLock]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.CropAndLock);
DataContext = ViewModel;
}
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(CropAndLockPage));
OobeWindow.OpenMainWindowCallback(typeof(CropAndLockPage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -22,7 +22,7 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobeEnvironmentVariables()
{
InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.EnvironmentVariables]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.EnvironmentVariables);
DataContext = ViewModel;
}
@@ -55,9 +55,9 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
private void Launch_Settings_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(EnvironmentVariablesPage));
OobeWindow.OpenMainWindowCallback(typeof(EnvironmentVariablesPage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -18,15 +18,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobeFancyZones()
{
this.InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.FancyZones]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.FancyZones);
DataContext = ViewModel;
}
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(FancyZonesPage));
OobeWindow.OpenMainWindowCallback(typeof(FancyZonesPage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -10,9 +10,6 @@ using Microsoft.UI.Xaml.Navigation;
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class OobeFileExplorer : Page
{
public OobePowerToysModule ViewModel { get; set; }
@@ -20,15 +17,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobeFileExplorer()
{
this.InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.FileExplorer]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.FileExplorer);
DataContext = ViewModel;
}
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(PowerPreviewPage));
OobeWindow.OpenMainWindowCallback(typeof(PowerPreviewPage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -10,9 +10,6 @@ using Microsoft.UI.Xaml.Navigation;
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class OobeFileLocksmith : Page
{
public OobePowerToysModule ViewModel { get; set; }
@@ -20,15 +17,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobeFileLocksmith()
{
this.InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.FileLocksmith]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.FileLocksmith);
DataContext = ViewModel;
}
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(FileLocksmithPage));
OobeWindow.OpenMainWindowCallback(typeof(FileLocksmithPage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -22,7 +22,7 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobeHosts()
{
InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.Hosts]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.Hosts);
DataContext = ViewModel;
}
@@ -55,9 +55,9 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
private void Launch_Settings_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(HostsPage));
OobeWindow.OpenMainWindowCallback(typeof(HostsPage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -10,9 +10,6 @@ using Microsoft.UI.Xaml.Navigation;
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class OobeImageResizer : Page
{
public OobePowerToysModule ViewModel { get; set; }
@@ -20,15 +17,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobeImageResizer()
{
this.InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.ImageResizer]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.ImageResizer);
DataContext = ViewModel;
}
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(ImageResizerPage));
OobeWindow.OpenMainWindowCallback(typeof(ImageResizerPage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -10,9 +10,6 @@ using Microsoft.UI.Xaml.Navigation;
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class OobeKBM : Page
{
public OobePowerToysModule ViewModel { get; set; }
@@ -20,15 +17,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobeKBM()
{
this.InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.KBM]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.KBM);
DataContext = ViewModel;
}
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(KeyboardManagerPage));
OobeWindow.OpenMainWindowCallback(typeof(KeyboardManagerPage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -17,14 +17,14 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobeLightSwitch()
{
this.InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.LightSwitch]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.LightSwitch);
}
private void SettingsLaunchButton_Click(object sender, RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(LightSwitchPage));
OobeWindow.OpenMainWindowCallback(typeof(LightSwitchPage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -11,9 +11,6 @@ using Microsoft.UI.Xaml.Navigation;
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class OobeMeasureTool : Page
{
public OobePowerToysModule ViewModel { get; set; }
@@ -21,15 +18,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobeMeasureTool()
{
this.InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.MeasureTool]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.MeasureTool);
DataContext = ViewModel;
}
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(MeasureToolPage));
OobeWindow.OpenMainWindowCallback(typeof(MeasureToolPage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -17,15 +17,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobeMouseUtils()
{
this.InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.MouseUtils]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.MouseUtils);
DataContext = ViewModel;
}
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(MouseUtilsPage));
OobeWindow.OpenMainWindowCallback(typeof(MouseUtilsPage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -10,9 +10,6 @@ using Microsoft.UI.Xaml.Navigation;
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class OobeMouseWithoutBorders : Page
{
public OobePowerToysModule ViewModel { get; set; }
@@ -20,15 +17,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobeMouseWithoutBorders()
{
this.InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.MouseWithoutBorders]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.MouseWithoutBorders);
DataContext = ViewModel;
}
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(MouseWithoutBordersPage));
OobeWindow.OpenMainWindowCallback(typeof(MouseWithoutBordersPage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -10,9 +10,6 @@ using Microsoft.UI.Xaml.Navigation;
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class OobeNewPlus : Page
{
public OobePowerToysModule ViewModel { get; set; }
@@ -20,15 +17,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobeNewPlus()
{
this.InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.NewPlus]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.NewPlus);
DataContext = ViewModel;
}
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(NewPlusPage));
OobeWindow.OpenMainWindowCallback(typeof(NewPlusPage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -52,26 +52,8 @@
</tkcontrols:SettingsCard.Description>
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind EnableDataDiagnostics, Mode=TwoWay}" />
</tkcontrols:SettingsCard>
<!-- Show title and description only when there are conflicts -->
<TextBlock
x:Uid="Oobe_Overview_Hotkey_Conflict_Title"
Margin="0,24,0,8"
Style="{StaticResource BodyStrongTextBlockStyle}" />
<!-- Always show shortcut status card -->
<tkcontrols:SettingsCard Description="{x:Bind ConflictDescription, Mode=OneWay}" Header="{x:Bind ConflictText, Mode=OneWay}">
<tkcontrols:SettingsCard.HeaderIcon>
<FontIcon Foreground="{x:Bind IconForeground, Mode=OneWay}" Glyph="{x:Bind IconGlyph, Mode=OneWay}" />
</tkcontrols:SettingsCard.HeaderIcon>
<!-- Only show button when there are conflicts -->
<Button
x:Uid="ResolveConflicts_Button"
Click="ShortcutConflictBtn_Click"
Visibility="{x:Bind HasConflicts, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" />
</tkcontrols:SettingsCard>
</StackPanel>
</StackPanel>
</controls:OOBEPageControl.PageContent>
</controls:OOBEPageControl>
</Page>
</Page>

View File

@@ -4,18 +4,11 @@
using System.ComponentModel;
using global::PowerToys.GPOWrapper;
using Microsoft.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.Library.HotkeyConflicts;
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
using Microsoft.PowerToys.Settings.UI.OOBE.Enums;
using Microsoft.PowerToys.Settings.UI.OOBE.ViewModel;
using Microsoft.PowerToys.Settings.UI.Services;
using Microsoft.PowerToys.Settings.UI.SettingsXAML.Controls.Dashboard;
using Microsoft.PowerToys.Settings.UI.Views;
using Microsoft.PowerToys.Telemetry;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
@@ -25,10 +18,6 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobePowerToysModule ViewModel { get; set; }
private bool _enableDataDiagnostics;
private AllHotkeyConflictsData _allHotkeyConflictsData = new AllHotkeyConflictsData();
private Windows.ApplicationModel.Resources.ResourceLoader resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader;
private int _conflictCount;
public bool EnableDataDiagnostics
{
@@ -53,165 +42,6 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
}
}
public AllHotkeyConflictsData AllHotkeyConflictsData
{
get => _allHotkeyConflictsData;
set
{
if (_allHotkeyConflictsData != value)
{
_allHotkeyConflictsData = value;
UpdateConflictCount();
OnPropertyChanged(nameof(AllHotkeyConflictsData));
OnPropertyChanged(nameof(ConflictCount));
OnPropertyChanged(nameof(ConflictText));
OnPropertyChanged(nameof(ConflictDescription));
OnPropertyChanged(nameof(HasConflicts));
OnPropertyChanged(nameof(IconGlyph));
OnPropertyChanged(nameof(IconForeground));
}
}
}
public int ConflictCount => _conflictCount;
private void UpdateConflictCount()
{
int count = 0;
if (AllHotkeyConflictsData == null)
{
_conflictCount = count;
}
if (AllHotkeyConflictsData.InAppConflicts != null)
{
foreach (var inAppConflict in AllHotkeyConflictsData.InAppConflicts)
{
var hotkey = inAppConflict.Hotkey;
var hotkeySettings = new HotkeySettings(hotkey.Win, hotkey.Ctrl, hotkey.Alt, hotkey.Shift, hotkey.Key);
if (!HotkeyConflictIgnoreHelper.IsIgnoringConflicts(hotkeySettings))
{
count++;
}
}
}
if (AllHotkeyConflictsData.SystemConflicts != null)
{
foreach (var systemConflict in AllHotkeyConflictsData.SystemConflicts)
{
var hotkey = systemConflict.Hotkey;
var hotkeySettings = new HotkeySettings(hotkey.Win, hotkey.Ctrl, hotkey.Alt, hotkey.Shift, hotkey.Key);
if (!HotkeyConflictIgnoreHelper.IsIgnoringConflicts(hotkeySettings))
{
count++;
}
}
}
_conflictCount = count;
}
public string ConflictText
{
get
{
var count = ConflictCount;
if (count == 0)
{
// Return no-conflict message
try
{
return resourceLoader.GetString("ShortcutConflictControl_NoConflictsFound");
}
catch
{
return "No conflicts found";
}
}
else if (count == 1)
{
// Try to get localized string
try
{
return resourceLoader.GetString("ShortcutConflictControl_SingleConflictFound");
}
catch
{
return "1 shortcut conflict";
}
}
else
{
// Try to get localized string
try
{
var template = resourceLoader.GetString("ShortcutConflictControl_MultipleConflictsFound");
return string.Format(System.Globalization.CultureInfo.CurrentCulture, template, count);
}
catch
{
return $"{count} shortcut conflicts";
}
}
}
}
public string ConflictDescription
{
get
{
var count = ConflictCount;
if (count == 0)
{
// Return no-conflict description
try
{
return resourceLoader.GetString("ShortcutConflictWindow_NoConflictsDescription");
}
catch
{
return "All shortcuts function correctly";
}
}
else
{
// Return conflict description
try
{
return resourceLoader.GetString("Oobe_Overview_Hotkey_Conflict_Card_Description");
}
catch
{
return "Shortcuts configured by PowerToys are conflicting";
}
}
}
}
public bool HasConflicts => ConflictCount > 0;
public string IconGlyph => HasConflicts ? "\uE814" : "\uE73E";
public SolidColorBrush IconForeground
{
get
{
if (HasConflicts)
{
// Red color for conflicts
return (SolidColorBrush)App.Current.Resources["SystemFillColorCriticalBrush"];
}
else
{
// Green color for no conflicts
return (SolidColorBrush)App.Current.Resources["SystemFillColorSuccessBrush"];
}
}
}
public bool ShowDataDiagnosticsSetting => GetIsDataDiagnosticsInfoBarEnabled();
public event PropertyChangedEventHandler PropertyChanged;
@@ -229,23 +59,8 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
_enableDataDiagnostics = DataDiagnosticsSettings.GetEnabledValue();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.Overview]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.Overview);
DataContext = this;
// Subscribe to hotkey conflict updates
if (GlobalHotkeyConflictManager.Instance != null)
{
GlobalHotkeyConflictManager.Instance.ConflictsUpdated += OnConflictsUpdated;
GlobalHotkeyConflictManager.Instance.RequestAllConflicts();
}
}
private void OnConflictsUpdated(object sender, AllHotkeyConflictsEventArgs e)
{
this.DispatcherQueue.TryEnqueue(Microsoft.UI.Dispatching.DispatcherQueuePriority.Normal, () =>
{
AllHotkeyConflictsData = e.Conflicts ?? new AllHotkeyConflictsData();
});
}
private void OnPropertyChanged(string propertyName)
@@ -255,9 +70,9 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(DashboardPage));
OobeWindow.OpenMainWindowCallback(typeof(DashboardPage));
}
ViewModel.LogOpeningSettingsEvent();
@@ -265,26 +80,14 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
private void GeneralSettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(GeneralPage));
OobeWindow.OpenMainWindowCallback(typeof(GeneralPage));
}
ViewModel.LogOpeningSettingsEvent();
}
private void ShortcutConflictBtn_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (AllHotkeyConflictsData == null || !HasConflicts)
{
return;
}
// Create and show the shortcut conflict window
var conflictWindow = new ShortcutConflictWindow();
conflictWindow.Activate();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
ViewModel.LogOpeningModuleEvent();
@@ -293,12 +96,6 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
ViewModel.LogClosingModuleEvent();
// Unsubscribe from conflict updates when leaving the page
if (GlobalHotkeyConflictManager.Instance != null)
{
GlobalHotkeyConflictManager.Instance.ConflictsUpdated -= OnConflictsUpdated;
}
}
}
}

View File

@@ -1,191 +0,0 @@
<Page
x:Class="Microsoft.PowerToys.Settings.UI.OOBE.Views.OobeOverviewAlternate"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<controls:OOBEPageControl
x:Uid="Oobe_Overview"
HeroImage="ms-appx:///Assets/Settings/Modules/OOBE/PTHeroShort.png"
HeroImageHeight="120">
<controls:OOBEPageControl.PageContent>
<StackPanel Orientation="Vertical" Spacing="12">
<TextBlock
x:Uid="Alternate_OOBE_Description"
Margin="0,24,0,12"
FontWeight="SemiBold" />
<GridView SelectionMode="None">
<GridViewItem>
<Grid
Width="280"
Margin="8"
Padding="16,16,16,10"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
BorderThickness="1"
CornerRadius="8"
RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image
Width="36"
HorizontalAlignment="Left"
Source="ms-appx:///Assets/Settings/Icons/FancyZones.png" />
<TextBlock
x:Uid="Alternate_OOBE_FancyZones_Title"
Grid.Row="1"
Margin="0,12,0,6"
HorizontalAlignment="Left"
FontSize="16"
FontWeight="SemiBold"
TextWrapping="Wrap" />
<TextBlock
x:Uid="Alternate_OOBE_FancyZones_Description"
Grid.Row="2"
FontSize="12"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
TextWrapping="Wrap" />
<controls:ShortcutWithTextLabelControl
x:Name="FancyZonesHotkeyControl"
Grid.Row="3"
Margin="0,8,0,0" />
</Grid>
</GridViewItem>
<GridViewItem>
<Grid
Width="280"
Padding="16,16,16,10"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
BorderThickness="1"
CornerRadius="8"
RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image
Width="36"
HorizontalAlignment="Left"
Source="ms-appx:///Assets/Settings/Icons/PowerToysRun.png" />
<TextBlock
x:Uid="Alternate_OOBE_Run_Title"
Grid.Row="1"
Margin="0,12,0,6"
HorizontalAlignment="Left"
FontSize="16"
FontWeight="SemiBold"
TextWrapping="Wrap" />
<TextBlock
x:Uid="Alternate_OOBE_Run_Description"
Grid.Row="2"
FontSize="12"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
TextWrapping="Wrap" />
<controls:ShortcutWithTextLabelControl
x:Name="RunHotkeyControl"
Grid.Row="3"
Margin="0,8,0,0" />
</Grid>
</GridViewItem>
<GridViewItem>
<Grid
Width="280"
Padding="16,16,16,10"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
BorderThickness="1"
CornerRadius="8"
RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image
Width="36"
HorizontalAlignment="Left"
Source="ms-appx:///Assets/Settings/Icons/ColorPicker.png" />
<TextBlock
x:Uid="Alternate_OOBE_ColorPicker_Title"
Grid.Row="1"
Margin="0,12,0,6"
HorizontalAlignment="Left"
FontSize="16"
FontWeight="SemiBold"
TextWrapping="Wrap" />
<TextBlock
x:Uid="Alternate_OOBE_ColorPicker_Description"
Grid.Row="2"
FontSize="12"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
TextWrapping="Wrap" />
<controls:ShortcutWithTextLabelControl
x:Name="ColorPickerHotkeyControl"
Grid.Row="3"
Margin="0,8,0,0" />
</Grid>
</GridViewItem>
<GridViewItem>
<Grid
Width="280"
Padding="16,16,16,10"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
BorderThickness="1"
CornerRadius="8"
RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image
Width="36"
HorizontalAlignment="Left"
Source="ms-appx:///Assets/Settings/Icons/AlwaysOnTop.png" />
<TextBlock
x:Uid="Alternate_OOBE_AlwaysOnTop_Title"
Grid.Row="1"
Margin="0,12,0,6"
HorizontalAlignment="Left"
FontSize="16"
FontWeight="SemiBold"
TextWrapping="Wrap" />
<TextBlock
x:Uid="Alternate_OOBE_AlwaysOnTop_Description"
Grid.Row="2"
FontSize="12"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
TextWrapping="Wrap" />
<controls:ShortcutWithTextLabelControl
x:Name="AlwaysOnTopHotkeyControl"
Grid.Row="3"
Margin="0,8,0,0" />
</Grid>
</GridViewItem>
</GridView>
</StackPanel>
</controls:OOBEPageControl.PageContent>
</controls:OOBEPageControl>
</Page>

View File

@@ -1,50 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.OOBE.Enums;
using Microsoft.PowerToys.Settings.UI.OOBE.ViewModel;
using Microsoft.PowerToys.Settings.UI.Views;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Navigation;
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
{
public sealed partial class OobeOverviewAlternate : Page
{
public OobePowerToysModule ViewModel { get; set; }
public OobeOverviewAlternate()
{
this.InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.Overview]);
DataContext = ViewModel;
FancyZonesHotkeyControl.Keys = SettingsRepository<FancyZonesSettings>.GetInstance(SettingsUtils.Default).SettingsConfig.Properties.FancyzonesEditorHotkey.Value.GetKeysList();
RunHotkeyControl.Keys = SettingsRepository<PowerLauncherSettings>.GetInstance(SettingsUtils.Default).SettingsConfig.Properties.OpenPowerLauncher.GetKeysList();
ColorPickerHotkeyControl.Keys = SettingsRepository<ColorPickerSettings>.GetInstance(SettingsUtils.Default).SettingsConfig.Properties.ActivationShortcut.GetKeysList();
AlwaysOnTopHotkeyControl.Keys = SettingsRepository<AlwaysOnTopSettings>.GetInstance(SettingsUtils.Default).SettingsConfig.Properties.Hotkey.Value.GetKeysList();
}
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(DashboardPage));
}
ViewModel.LogOpeningSettingsEvent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
ViewModel.LogOpeningModuleEvent();
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
ViewModel.LogClosingModuleEvent();
}
}
}

View File

@@ -1,19 +0,0 @@
<!-- Copyright (c) Microsoft Corporation. All rights reserved. -->
<!-- Licensed under the MIT License. See LICENSE in the project root for license information. -->
<Page
x:Class="Microsoft.PowerToys.Settings.UI.OOBE.Views.OobeOverviewPlaceholder"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Loaded="Page_Loaded"
mc:Ignorable="d">
<ProgressRing
x:Name="LoadingProgressRing"
HorizontalAlignment="Center"
VerticalAlignment="Center"
IsIndeterminate="True"
Visibility="Visible" />
</Page>

View File

@@ -1,74 +0,0 @@
// 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.Threading.Tasks;
using AllExperiments;
using Microsoft.PowerToys.Settings.UI.OOBE.Enums;
using Microsoft.PowerToys.Settings.UI.OOBE.ViewModel;
using Microsoft.PowerToys.Settings.UI.Services;
using Microsoft.PowerToys.Settings.UI.Views;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Navigation;
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
{
public sealed partial class OobeOverviewPlaceholder : Page
{
public OobePowerToysModule ViewModel { get; set; }
public OobeOverviewPlaceholder()
{
this.InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.Overview]);
DataContext = ViewModel;
}
private static async Task<bool> GetIsExperiment()
{
Experiments landingPageExp = new Experiments();
var experimentEnabled = await landingPageExp.EnableLandingPageExperimentAsync();
return experimentEnabled;
}
private async void Reload()
{
var isExperiment = await GetIsExperiment();
if (isExperiment)
{
this.Frame.Navigate(typeof(OobeOverviewAlternate));
}
else
{
this.Frame.Navigate(typeof(OobeOverview));
}
}
private void Page_Loaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
Reload();
}
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(DashboardPage));
}
ViewModel.LogOpeningSettingsEvent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
ViewModel.LogOpeningModuleEvent();
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
ViewModel.LogClosingModuleEvent();
}
}
}

View File

@@ -11,9 +11,6 @@ using Microsoft.UI.Xaml.Navigation;
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class OobePeek : Page
{
public OobePowerToysModule ViewModel { get; set; }
@@ -21,15 +18,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobePeek()
{
this.InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.Peek]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.Peek);
DataContext = ViewModel;
}
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(PeekPage));
OobeWindow.OpenMainWindowCallback(typeof(PeekPage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -17,15 +17,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobePowerAccent()
{
InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.QuickAccent]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.QuickAccent);
DataContext = ViewModel;
}
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(PowerAccentPage));
OobeWindow.OpenMainWindowCallback(typeof(PowerAccentPage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -14,9 +14,6 @@ using PowerToys.Interop;
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class OobePowerDisplay : Page
{
public OobePowerToysModule ViewModel { get; set; }
@@ -24,7 +21,7 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobePowerDisplay()
{
this.InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.PowerDisplay]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.PowerDisplay);
DataContext = ViewModel;
}
@@ -38,9 +35,9 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(PowerDisplayPage));
OobeWindow.OpenMainWindowCallback(typeof(PowerDisplayPage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -18,15 +18,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobePowerOCR()
{
this.InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.TextExtractor]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.TextExtractor);
DataContext = ViewModel;
}
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(PowerOcrPage));
OobeWindow.OpenMainWindowCallback(typeof(PowerOcrPage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -10,9 +10,6 @@ using Microsoft.UI.Xaml.Navigation;
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class OobePowerRename : Page
{
public OobePowerToysModule ViewModel { get; set; }
@@ -20,15 +17,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobePowerRename()
{
this.InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.PowerRename]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.PowerRename);
DataContext = ViewModel;
}
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(PowerRenamePage));
OobeWindow.OpenMainWindowCallback(typeof(PowerRenamePage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -12,9 +12,6 @@ using Microsoft.UI.Xaml.Navigation;
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class OobeRegistryPreview : Page
{
public OobePowerToysModule ViewModel { get; set; }
@@ -22,7 +19,7 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobeRegistryPreview()
{
this.InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.RegistryPreview]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.RegistryPreview);
DataContext = ViewModel;
}
@@ -33,9 +30,9 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(RegistryPreviewPage));
OobeWindow.OpenMainWindowCallback(typeof(RegistryPreviewPage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -14,9 +14,6 @@ using Microsoft.UI.Xaml.Navigation;
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class OobeRun : Page
{
public OobePowerToysModule ViewModel { get; set; }
@@ -24,15 +21,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobeRun()
{
this.InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.Run]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.Run);
DataContext = ViewModel;
}
private void Start_Run_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.RunSharedEventCallback != null)
if (OobeWindow.RunSharedEventCallback != null)
{
using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, OobeShellPage.RunSharedEventCallback()))
using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, OobeWindow.RunSharedEventCallback()))
{
eventHandle.Set();
}
@@ -43,9 +40,9 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(PowerLauncherPage));
OobeWindow.OpenMainWindowCallback(typeof(PowerLauncherPage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -1,177 +0,0 @@
<Page
x:Class="Microsoft.PowerToys.Settings.UI.OOBE.Views.OobeShellPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI"
HighContrastAdjustment="None"
Loaded="ShellPage_Loaded"
mc:Ignorable="d">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="48" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TitleBar
x:Name="AppTitleBar"
x:Uid="OobeWindow_TitleTxt"
IsBackButtonVisible="False"
IsPaneToggleButtonVisible="False"
PaneToggleRequested="TitleBar_PaneButtonClick">
<!-- This is a workaround for https://github.com/microsoft/microsoft-ui-xaml/issues/10374, once fixed we should just be using IconSource -->
<TitleBar.LeftHeader>
<ImageIcon
x:Name="TitleBarIcon"
Height="16"
Margin="16,0,0,0"
Source="/Assets/Settings/icon.ico" />
</TitleBar.LeftHeader>
</TitleBar>
<NavigationView
x:Name="navigationView"
Grid.Row="1"
CompactModeThresholdWidth="1007"
DisplayModeChanged="NavigationView_DisplayModeChanged"
ExpandedModeThresholdWidth="1007"
IsBackButtonVisible="Collapsed"
IsPaneOpen="True"
IsPaneToggleButtonVisible="False"
IsSettingsVisible="False"
OpenPaneLength="296"
SelectionChanged="NavigationView_SelectionChanged">
<NavigationView.MenuItems>
<NavigationViewItem
x:Uid="Shell_General"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/PowerToys.png}"
Tag="Overview" />
<NavigationViewItem
x:Uid="Shell_AdvancedPaste"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/AdvancedPaste.png}"
Tag="AdvancedPaste" />
<NavigationViewItem
x:Uid="Shell_AlwaysOnTop"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/AlwaysOnTop.png}"
Tag="AlwaysOnTop" />
<NavigationViewItem
x:Uid="Shell_Awake"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/Awake.png}"
Tag="Awake" />
<NavigationViewItem
x:Uid="Shell_ColorPicker"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/ColorPicker.png}"
Tag="ColorPicker" />
<NavigationViewItem
x:Uid="Shell_CmdPal"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/CmdPal.png}"
Tag="CmdPal" />
<NavigationViewItem
x:Uid="Shell_CmdNotFound"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/CommandNotFound.png}"
Tag="CmdNotFound" />
<NavigationViewItem
x:Uid="Shell_CropAndLock"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/CropAndLock.png}"
Tag="CropAndLock" />
<NavigationViewItem
x:Uid="Shell_EnvironmentVariables"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/EnvironmentVariables.png}"
Tag="EnvironmentVariables" />
<NavigationViewItem
x:Uid="Shell_FancyZones"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/FancyZones.png}"
Tag="FancyZones" />
<NavigationViewItem
x:Uid="Shell_FileLocksmith"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/FileLocksmith.png}"
Tag="FileLocksmith" />
<NavigationViewItem
x:Uid="Shell_PowerPreview"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/FileExplorerPreview.png}"
Tag="FileExplorer" />
<NavigationViewItem
x:Uid="Shell_Hosts"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/Hosts.png}"
Tag="Hosts" />
<NavigationViewItem
x:Uid="Shell_ImageResizer"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/ImageResizer.png}"
Tag="ImageResizer" />
<NavigationViewItem
x:Uid="Shell_KeyboardManager"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/KeyboardManager.png}"
Tag="KBM" />
<NavigationViewItem
x:Uid="Shell_LightSwitch"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/LightSwitch.png}"
Tag="LightSwitch" />
<NavigationViewItem
x:Uid="Shell_MouseUtilities"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/MouseUtils.png}"
Tag="MouseUtils" />
<NavigationViewItem
x:Uid="Shell_PowerDisplay"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/PowerDisplay.png}"
Tag="PowerDisplay" />
<NavigationViewItem
x:Uid="Shell_MouseWithoutBorders"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/MouseWithoutBorders.png}"
Tag="MouseWithoutBorders" />
<NavigationViewItem
x:Uid="NewPlus_Product_Name"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/NewPlus.png}"
Tag="NewPlus" />
<NavigationViewItem
x:Uid="Shell_Peek"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/Peek.png}"
Tag="Peek" />
<NavigationViewItem
x:Uid="Shell_PowerRename"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/PowerRename.png}"
Tag="PowerRename" />
<NavigationViewItem
x:Uid="Shell_PowerLauncher"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/PowerToysRun.png}"
Tag="Run" />
<NavigationViewItem
x:Uid="Shell_QuickAccent"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/QuickAccent.png}"
Tag="QuickAccent" />
<NavigationViewItem
x:Uid="Shell_RegistryPreview"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/RegistryPreview.png}"
Tag="RegistryPreview" />
<NavigationViewItem
x:Uid="Shell_MeasureTool"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/ScreenRuler.png}"
Tag="MeasureTool" />
<NavigationViewItem
x:Uid="Shell_ShortcutGuide"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/ShortcutGuide.png}"
Tag="ShortcutGuide" />
<NavigationViewItem
x:Uid="Shell_TextExtractor"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/TextExtractor.png}"
Tag="TextExtractor" />
<NavigationViewItem
x:Uid="Shell_Workspaces"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/Workspaces.png}"
Tag="Workspaces" />
<NavigationViewItem
x:Uid="Shell_ZoomIt"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/ZoomIt.png}"
Tag="ZoomIt" />
</NavigationView.MenuItems>
<NavigationView.PaneFooter>
<NavigationViewItem
x:Uid="Shell_WhatsNew"
AutomationProperties.AutomationId="WhatIsNewNavItem"
Icon="{ui:FontIcon Glyph=&#xE789;}"
Tapped="WhatIsNewItem_Tapped" />
</NavigationView.PaneFooter>
<NavigationView.Content>
<Frame x:Name="NavigationFrame" />
</NavigationView.Content>
</NavigationView>
</Grid>
</Page>

View File

@@ -1,349 +0,0 @@
// 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.ObjectModel;
using System.Globalization;
using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.OOBE.Enums;
using Microsoft.PowerToys.Settings.UI.OOBE.ViewModel;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
{
public sealed partial class OobeShellPage : Page
{
public static Func<string> RunSharedEventCallback { get; set; }
public static void SetRunSharedEventCallback(Func<string> implementation)
{
RunSharedEventCallback = implementation;
}
public static Func<string> ColorPickerSharedEventCallback { get; set; }
public static void SetColorPickerSharedEventCallback(Func<string> implementation)
{
ColorPickerSharedEventCallback = implementation;
}
public static Action<Type> OpenMainWindowCallback { get; set; }
public static void SetOpenMainWindowCallback(Action<Type> implementation)
{
OpenMainWindowCallback = implementation;
}
/// <summary>
/// Gets view model.
/// </summary>
public OobeShellViewModel ViewModel { get; } = new OobeShellViewModel();
/// <summary>
/// Gets or sets a shell handler to be used to update contents of the shell dynamically from page within the frame.
/// </summary>
public static OobeShellPage OobeShellHandler { get; set; }
public ObservableCollection<OobePowerToysModule> Modules { get; }
private static SettingsUtils settingsUtils = SettingsUtils.Default;
/* NOTE: Experimentation for OOBE is currently turned off on server side. Keeping this code in a comment to allow future experiments.
private bool ExperimentationToggleSwitchEnabled { get; set; } = true;
*/
public OobeShellPage()
{
InitializeComponent();
// NOTE: Experimentation for OOBE is currently turned off on server side. Keeping this code in a comment to allow future experiments.
// ExperimentationToggleSwitchEnabled = SettingsRepository<GeneralSettings>.GetInstance(settingsUtils).SettingsConfig.EnableExperimentation;
DataContext = ViewModel;
OobeShellHandler = this;
Modules = new ObservableCollection<OobePowerToysModule>();
Modules.Insert((int)PowerToysModules.Overview, new OobePowerToysModule()
{
ModuleName = "Overview",
IsNew = false,
});
Modules.Insert((int)PowerToysModules.AdvancedPaste, new OobePowerToysModule()
{
ModuleName = "AdvancedPaste",
IsNew = true,
});
Modules.Insert((int)PowerToysModules.AlwaysOnTop, new OobePowerToysModule()
{
ModuleName = "AlwaysOnTop",
IsNew = false,
});
Modules.Insert((int)PowerToysModules.Awake, new OobePowerToysModule()
{
ModuleName = "Awake",
IsNew = false,
});
Modules.Insert((int)PowerToysModules.CmdNotFound, new OobePowerToysModule()
{
ModuleName = "CmdNotFound",
IsNew = false,
});
Modules.Insert((int)PowerToysModules.CmdPal, new OobePowerToysModule()
{
ModuleName = "CmdPal",
IsNew = true,
});
Modules.Insert((int)PowerToysModules.ColorPicker, new OobePowerToysModule()
{
ModuleName = "ColorPicker",
IsNew = false,
});
Modules.Insert((int)PowerToysModules.CropAndLock, new OobePowerToysModule()
{
ModuleName = "CropAndLock",
IsNew = false,
});
Modules.Insert((int)PowerToysModules.EnvironmentVariables, new OobePowerToysModule()
{
ModuleName = "EnvironmentVariables",
IsNew = false,
});
Modules.Insert((int)PowerToysModules.FancyZones, new OobePowerToysModule()
{
ModuleName = "FancyZones",
IsNew = false,
});
Modules.Insert((int)PowerToysModules.FileLocksmith, new OobePowerToysModule()
{
ModuleName = "FileLocksmith",
IsNew = false,
});
Modules.Insert((int)PowerToysModules.FileExplorer, new OobePowerToysModule()
{
ModuleName = "FileExplorer",
IsNew = false,
});
Modules.Insert((int)PowerToysModules.ImageResizer, new OobePowerToysModule()
{
ModuleName = "ImageResizer",
IsNew = false,
});
Modules.Insert((int)PowerToysModules.KBM, new OobePowerToysModule()
{
ModuleName = "KBM",
IsNew = false,
});
Modules.Insert((int)PowerToysModules.LightSwitch, new OobePowerToysModule()
{
ModuleName = "LightSwitch",
IsNew = true,
});
Modules.Insert((int)PowerToysModules.MouseUtils, new OobePowerToysModule()
{
ModuleName = "MouseUtils",
IsNew = false,
});
Modules.Insert((int)PowerToysModules.MouseWithoutBorders, new OobePowerToysModule()
{
ModuleName = "MouseWithoutBorders",
IsNew = false,
});
Modules.Insert((int)PowerToysModules.Peek, new OobePowerToysModule()
{
ModuleName = "Peek",
IsNew = false,
});
Modules.Insert((int)PowerToysModules.PowerRename, new OobePowerToysModule()
{
ModuleName = "PowerRename",
IsNew = false,
});
Modules.Insert((int)PowerToysModules.Run, new OobePowerToysModule()
{
ModuleName = "Run",
IsNew = false,
});
Modules.Insert((int)PowerToysModules.QuickAccent, new OobePowerToysModule()
{
ModuleName = "QuickAccent",
IsNew = false,
});
Modules.Insert((int)PowerToysModules.ShortcutGuide, new OobePowerToysModule()
{
ModuleName = "ShortcutGuide",
IsNew = false,
});
Modules.Insert((int)PowerToysModules.TextExtractor, new OobePowerToysModule()
{
ModuleName = "TextExtractor",
IsNew = false,
});
Modules.Insert((int)PowerToysModules.MeasureTool, new OobePowerToysModule()
{
ModuleName = "MeasureTool",
IsNew = false,
});
Modules.Insert((int)PowerToysModules.Hosts, new OobePowerToysModule()
{
ModuleName = "Hosts",
IsNew = false,
});
Modules.Insert((int)PowerToysModules.Workspaces, new OobePowerToysModule()
{
ModuleName = "Workspaces",
IsNew = true,
});
Modules.Insert((int)PowerToysModules.RegistryPreview, new OobePowerToysModule()
{
ModuleName = "RegistryPreview",
IsNew = false,
});
Modules.Insert((int)PowerToysModules.PowerDisplay, new OobePowerToysModule()
{
ModuleName = "PowerDisplay",
IsNew = true,
});
Modules.Insert((int)PowerToysModules.NewPlus, new OobePowerToysModule()
{
ModuleName = "NewPlus",
IsNew = true,
});
Modules.Insert((int)PowerToysModules.ZoomIt, new OobePowerToysModule()
{
ModuleName = "ZoomIt",
IsNew = true,
});
}
public void OnClosing()
{
NavigationViewItem selectedItem = this.navigationView.SelectedItem as NavigationViewItem;
if (selectedItem != null)
{
Modules[(int)(PowerToysModules)Enum.Parse(typeof(PowerToysModules), (string)selectedItem.Tag, true)].LogClosingModuleEvent();
}
}
public void NavigateToModule(PowerToysModules selectedModule)
{
navigationView.SelectedItem = navigationView.MenuItems[(int)selectedModule];
}
private static void OpenScoobeWindow()
{
if (App.GetScoobeWindow() == null)
{
App.SetScoobeWindow(new ScoobeWindow());
}
App.GetScoobeWindow().Activate();
}
private void NavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
NavigationViewItem selectedItem = args.SelectedItem as NavigationViewItem;
if (selectedItem != null)
{
switch (selectedItem.Tag)
{
case "Overview": NavigationFrame.Navigate(typeof(OobeOverview)); break;
/* NOTE: Experimentation for OOBE is currently turned off on server side. Keeping this code in a comment to allow future experiments.
if (ExperimentationToggleSwitchEnabled && GPOWrapper.GetAllowExperimentationValue() != GpoRuleConfigured.Disabled)
{
switch (AllExperiments.Experiments.LandingPageExperiment)
{
case Experiments.ExperimentState.Enabled:
NavigationFrame.Navigate(typeof(OobeOverviewAlternate)); break;
case Experiments.ExperimentState.Disabled:
NavigationFrame.Navigate(typeof(OobeOverview)); break;
case Experiments.ExperimentState.NotLoaded:
NavigationFrame.Navigate(typeof(OobeOverviewPlaceholder)); break;
}
break;
}
else
{
NavigationFrame.Navigate(typeof(OobeOverview));
break;
}
*/
case "AdvancedPaste": NavigationFrame.Navigate(typeof(OobeAdvancedPaste)); break;
case "AlwaysOnTop": NavigationFrame.Navigate(typeof(OobeAlwaysOnTop)); break;
case "Awake": NavigationFrame.Navigate(typeof(OobeAwake)); break;
case "CmdNotFound": NavigationFrame.Navigate(typeof(OobeCmdNotFound)); break;
case "CmdPal": NavigationFrame.Navigate(typeof(OobeCmdPal)); break;
case "ColorPicker": NavigationFrame.Navigate(typeof(OobeColorPicker)); break;
case "CropAndLock": NavigationFrame.Navigate(typeof(OobeCropAndLock)); break;
case "EnvironmentVariables": NavigationFrame.Navigate(typeof(OobeEnvironmentVariables)); break;
case "FancyZones": NavigationFrame.Navigate(typeof(OobeFancyZones)); break;
case "FileLocksmith": NavigationFrame.Navigate(typeof(OobeFileLocksmith)); break;
case "Run": NavigationFrame.Navigate(typeof(OobeRun)); break;
case "ImageResizer": NavigationFrame.Navigate(typeof(OobeImageResizer)); break;
case "KBM": NavigationFrame.Navigate(typeof(OobeKBM)); break;
case "LightSwitch": NavigationFrame.Navigate(typeof(OobeLightSwitch)); break;
case "PowerRename": NavigationFrame.Navigate(typeof(OobePowerRename)); break;
case "QuickAccent": NavigationFrame.Navigate(typeof(OobePowerAccent)); break;
case "FileExplorer": NavigationFrame.Navigate(typeof(OobeFileExplorer)); break;
case "ShortcutGuide": NavigationFrame.Navigate(typeof(OobeShortcutGuide)); break;
case "TextExtractor": NavigationFrame.Navigate(typeof(OobePowerOCR)); break;
case "MouseUtils": NavigationFrame.Navigate(typeof(OobeMouseUtils)); break;
case "MouseWithoutBorders": NavigationFrame.Navigate(typeof(OobeMouseWithoutBorders)); break;
case "MeasureTool": NavigationFrame.Navigate(typeof(OobeMeasureTool)); break;
case "Hosts": NavigationFrame.Navigate(typeof(OobeHosts)); break;
case "RegistryPreview": NavigationFrame.Navigate(typeof(OobeRegistryPreview)); break;
case "Peek": NavigationFrame.Navigate(typeof(OobePeek)); break;
case "NewPlus": NavigationFrame.Navigate(typeof(OobeNewPlus)); break;
case "Workspaces": NavigationFrame.Navigate(typeof(OobeWorkspaces)); break;
case "PowerDisplay": NavigationFrame.Navigate(typeof(OobePowerDisplay)); break;
case "ZoomIt": NavigationFrame.Navigate(typeof(OobeZoomIt)); break;
}
}
}
private void ShellPage_Loaded(object sender, RoutedEventArgs e)
{
// Select the first module by default
if (navigationView.MenuItems.Count > 0)
{
navigationView.SelectedItem = navigationView.MenuItems[0];
}
}
private void NavigationView_DisplayModeChanged(NavigationView sender, NavigationViewDisplayModeChangedEventArgs args)
{
if (args.DisplayMode == NavigationViewDisplayMode.Compact || args.DisplayMode == NavigationViewDisplayMode.Minimal)
{
TitleBarIcon.Margin = new Thickness(0, 0, 8, 0); // Workaround, see XAML comment
AppTitleBar.IsPaneToggleButtonVisible = true;
}
else
{
TitleBarIcon.Margin = new Thickness(16, 0, 0, 0); // Workaround, see XAML comment
AppTitleBar.IsPaneToggleButtonVisible = false;
}
}
private void TitleBar_PaneButtonClick(TitleBar sender, object args)
{
navigationView.IsPaneOpen = !navigationView.IsPaneOpen;
}
private void WhatIsNewItem_Tapped(object sender, TappedRoutedEventArgs e)
{
OpenScoobeWindow();
}
}
}

View File

@@ -6,7 +6,6 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.Library.Helpers;
using Microsoft.PowerToys.Settings.UI.OOBE.Enums;
@@ -17,9 +16,6 @@ using Microsoft.UI.Xaml.Navigation;
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class OobeShortcutGuide : Page
{
public OobePowerToysModule ViewModel { get; set; }
@@ -27,7 +23,7 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobeShortcutGuide()
{
this.InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.ShortcutGuide]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.ShortcutGuide);
DataContext = ViewModel;
}
@@ -46,9 +42,9 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(ShortcutGuidePage));
OobeWindow.OpenMainWindowCallback(typeof(ShortcutGuidePage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -11,9 +11,6 @@ using Microsoft.UI.Xaml.Navigation;
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class OobeWorkspaces : Page
{
public OobePowerToysModule ViewModel { get; set; }
@@ -21,15 +18,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobeWorkspaces()
{
this.InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.Workspaces]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.Workspaces);
DataContext = ViewModel;
}
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(WorkspacesPage));
OobeWindow.OpenMainWindowCallback(typeof(WorkspacesPage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -18,15 +18,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
public OobeZoomIt()
{
this.InitializeComponent();
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.ZoomIt]);
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.ZoomIt);
DataContext = ViewModel;
}
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (OobeShellPage.OpenMainWindowCallback != null)
if (OobeWindow.OpenMainWindowCallback != null)
{
OobeShellPage.OpenMainWindowCallback(typeof(ZoomItPage));
OobeWindow.OpenMainWindowCallback(typeof(ZoomItPage));
}
ViewModel.LogOpeningSettingsEvent();

View File

@@ -47,7 +47,7 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
}
}
private static string GetVersionFromRelease(PowerToysReleaseInfo release)
internal static string GetVersionFromRelease(PowerToysReleaseInfo release)
{
// TagName is typically like "v0.96.0", Name might be "Release v0.96.0"
string version = release.TagName ?? release.Name ?? "Unknown";

View File

@@ -29,33 +29,35 @@
</Page.Resources>
<!-- Main layout container -->
<Grid MaxWidth="1000">
<ScrollViewer Padding="0,0,0,0" VerticalScrollBarVisibility="Auto">
<Grid Margin="0,0,0,24">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Image
x:Name="HeroImageHolder"
Height="186"
HorizontalAlignment="Left"
Stretch="UniformToFill" />
<Grid Grid.Row="1" Margin="24,16,24,24">
<ProgressRing
x:Name="LoadingProgressRing"
HorizontalAlignment="Center"
VerticalAlignment="Center"
IsIndeterminate="True"
Visibility="Visible" />
<tkcontrols:MarkdownTextBlock
x:Name="ReleaseNotesMarkdown"
Config="{StaticResource ReleaseNotesMarkdownConfig}"
UseAutoLinks="True"
UseEmphasisExtras="True"
UseListExtras="True"
UsePipeTables="True"
UseTaskLists="True" />
<Grid>
<ScrollViewer HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid MaxWidth="960">
<Grid Margin="0,0,0,24">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Image
x:Name="HeroImageHolder"
Height="186"
HorizontalAlignment="Left"
Stretch="UniformToFill" />
<Grid Grid.Row="1" Margin="24,16,24,24">
<ProgressRing
x:Name="LoadingProgressRing"
HorizontalAlignment="Center"
VerticalAlignment="Center"
IsIndeterminate="True"
Visibility="Visible" />
<tkcontrols:MarkdownTextBlock
x:Name="ReleaseNotesMarkdown"
Config="{StaticResource ReleaseNotesMarkdownConfig}"
UseAutoLinks="True"
UseEmphasisExtras="True"
UseListExtras="True"
UsePipeTables="True"
UseTaskLists="True" />
</Grid>
</Grid>
</Grid>
</ScrollViewer>

View File

@@ -1,96 +0,0 @@
<Page
x:Class="Microsoft.PowerToys.Settings.UI.OOBE.Views.ScoobeShellPage"
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.OOBE.Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
HighContrastAdjustment="None"
Loaded="ShellPage_Loaded"
mc:Ignorable="d">
<Page.Resources>
<!-- Template for NavigationViewItem content with version and date -->
<DataTemplate x:Key="ReleaseNavItemTemplate" x:DataType="local:ScoobeReleaseGroupViewModel">
<StackPanel
Margin="0,8,0,8"
Orientation="Vertical"
Spacing="4">
<TextBlock Style="{StaticResource BodyTextBlockStyle}" Text="{x:Bind DateText}" />
<TextBlock
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{x:Bind VersionText}" />
</StackPanel>
</DataTemplate>
</Page.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="48" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TitleBar
x:Name="AppTitleBar"
x:Uid="ScoobeWindow_TitleTxt"
IsBackButtonVisible="False"
IsPaneToggleButtonVisible="False"
PaneToggleRequested="TitleBar_PaneButtonClick">
<!-- This is a workaround for https://github.com/microsoft/microsoft-ui-xaml/issues/10374, once fixed we should just be using IconSource -->
<TitleBar.LeftHeader>
<ImageIcon
x:Name="TitleBarIcon"
Height="16"
Margin="16,0,0,0"
Source="/Assets/Settings/icon.ico" />
</TitleBar.LeftHeader>
</TitleBar>
<NavigationView
x:Name="navigationView"
Grid.Row="1"
CompactModeThresholdWidth="1007"
DisplayModeChanged="NavigationView_DisplayModeChanged"
ExpandedModeThresholdWidth="1007"
IsBackButtonVisible="Collapsed"
IsPaneOpen="True"
IsPaneToggleButtonVisible="False"
IsSettingsVisible="False"
MenuItemTemplate="{StaticResource ReleaseNavItemTemplate}"
OpenPaneLength="186"
SelectionChanged="NavigationView_SelectionChanged">
<NavigationView.MenuItems>
<!-- Items are added dynamically -->
</NavigationView.MenuItems>
<NavigationView.Content>
<Grid>
<ProgressRing
x:Name="LoadingProgressRing"
HorizontalAlignment="Center"
VerticalAlignment="Center"
IsIndeterminate="True"
Visibility="Collapsed" />
<InfoBar
x:Name="ErrorInfoBar"
x:Uid="Oobe_WhatsNew_LoadingError"
HorizontalAlignment="Center"
VerticalAlignment="Center"
IsClosable="False"
IsOpen="False"
Severity="Error">
<InfoBar.ActionButton>
<Button
x:Uid="RetryBtn"
HorizontalAlignment="Right"
Click="RetryButton_Click">
<StackPanel Orientation="Horizontal" Spacing="8">
<FontIcon FontSize="16" Glyph="&#xE72C;" />
<TextBlock x:Uid="RetryLabel" />
</StackPanel>
</Button>
</InfoBar.ActionButton>
</InfoBar>
<Frame x:Name="NavigationFrame" />
</Grid>
</NavigationView.Content>
</NavigationView>
</Grid>
</Page>

View File

@@ -1,194 +0,0 @@
// 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.Net;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.SerializationContext;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
{
public sealed partial class ScoobeShellPage : Page
{
public static Action<Type> OpenMainWindowCallback { get; set; }
public static void SetOpenMainWindowCallback(Action<Type> implementation)
{
OpenMainWindowCallback = implementation;
}
/// <summary>
/// Gets or sets a shell handler to be used to update contents of the shell dynamically from page within the frame.
/// </summary>
public static ScoobeShellPage ScoobeShellHandler { get; set; }
/// <summary>
/// Gets the list of release groups loaded from GitHub (grouped by major.minor version).
/// </summary>
public IList<IList<PowerToysReleaseInfo>> ReleaseGroups { get; private set; }
private bool _isLoading;
public ScoobeShellPage()
{
InitializeComponent();
ScoobeShellHandler = this;
}
private async void ShellPage_Loaded(object sender, RoutedEventArgs e)
{
SetTitleBar();
await LoadReleasesAsync();
}
private async Task LoadReleasesAsync()
{
if (_isLoading)
{
return;
}
_isLoading = true;
LoadingProgressRing.Visibility = Visibility.Visible;
ErrorInfoBar.IsOpen = false;
navigationView.MenuItems.Clear();
try
{
var releases = await FetchReleasesFromGitHubAsync();
ReleaseGroups = GroupReleasesByMajorMinor(releases);
PopulateNavigationItems();
}
catch (Exception ex)
{
Logger.LogError("Failed to load releases", ex);
ErrorInfoBar.IsOpen = true;
}
finally
{
LoadingProgressRing.Visibility = Visibility.Collapsed;
_isLoading = false;
}
}
private static async Task<IList<PowerToysReleaseInfo>> FetchReleasesFromGitHubAsync()
{
using var proxyClientHandler = new HttpClientHandler
{
DefaultProxyCredentials = CredentialCache.DefaultCredentials,
Proxy = WebRequest.GetSystemWebProxy(),
PreAuthenticate = true,
};
using var httpClient = new HttpClient(proxyClientHandler);
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "PowerToys");
string json = await httpClient.GetStringAsync("https://api.github.com/repos/microsoft/PowerToys/releases?per_page=20");
var allReleases = JsonSerializer.Deserialize<IList<PowerToysReleaseInfo>>(json, SourceGenerationContextContext.Default.IListPowerToysReleaseInfo);
return allReleases
.OrderByDescending(r => r.PublishedDate)
.ToList();
}
private static IList<IList<PowerToysReleaseInfo>> GroupReleasesByMajorMinor(IList<PowerToysReleaseInfo> releases)
{
return releases
.GroupBy(r => GetMajorMinorVersion(r))
.Select(g => g.OrderByDescending(r => r.PublishedDate).ToList() as IList<PowerToysReleaseInfo>)
.ToList();
}
private static string GetMajorMinorVersion(PowerToysReleaseInfo release)
{
string version = GetVersionFromRelease(release);
var parts = version.Split('.');
if (parts.Length >= 2)
{
return $"{parts[0]}.{parts[1]}";
}
return version;
}
private static string GetVersionFromRelease(PowerToysReleaseInfo release)
{
// TagName is typically like "v0.96.0", Name might be "Release v0.96.0"
string version = release.TagName ?? release.Name ?? "Unknown";
if (version.StartsWith("v", StringComparison.OrdinalIgnoreCase))
{
version = version.Substring(1);
}
return version;
}
private void PopulateNavigationItems()
{
if (ReleaseGroups == null || ReleaseGroups.Count == 0)
{
return;
}
foreach (var releaseGroup in ReleaseGroups)
{
var viewModel = new ScoobeReleaseGroupViewModel(releaseGroup);
navigationView.MenuItems.Add(viewModel);
}
// Select the first item to trigger navigation
navigationView.SelectedItem = navigationView.MenuItems[0];
}
private void NavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
if (args.SelectedItem is ScoobeReleaseGroupViewModel viewModel)
{
NavigationFrame.Navigate(typeof(ScoobeReleaseNotesPage), viewModel.Releases);
}
}
private async void RetryButton_Click(object sender, RoutedEventArgs e)
{
await LoadReleasesAsync();
}
private void SetTitleBar()
{
var window = App.GetScoobeWindow();
if (window != null)
{
window.ExtendsContentIntoTitleBar = true;
window.SetTitleBar(AppTitleBar);
}
}
private void NavigationView_DisplayModeChanged(NavigationView sender, NavigationViewDisplayModeChangedEventArgs args)
{
if (args.DisplayMode == NavigationViewDisplayMode.Compact || args.DisplayMode == NavigationViewDisplayMode.Minimal)
{
TitleBarIcon.Margin = new Thickness(0, 0, 8, 0); // Workaround, see XAML comment
AppTitleBar.IsPaneToggleButtonVisible = true;
}
else
{
TitleBarIcon.Margin = new Thickness(16, 0, 0, 0); // Workaround, see XAML comment
AppTitleBar.IsPaneToggleButtonVisible = false;
}
}
private void TitleBar_PaneButtonClick(TitleBar sender, object args)
{
navigationView.IsPaneOpen = !navigationView.IsPaneOpen;
}
}
}