From 88b216032efb307f3bba2896e1a10efc42a3c13a Mon Sep 17 00:00:00 2001 From: Davide Giacometti Date: Thu, 23 Oct 2025 22:46:51 +0200 Subject: [PATCH] NavigationView NEW tag with attribute --- .../Settings.UI/NewUtilityAttribute.cs | 19 +++++++++ .../Views/LightSwitchPage.xaml.cs | 2 +- .../SettingsXAML/Views/ShellPage.xaml | 9 +--- .../SettingsXAML/Views/ShellPage.xaml.cs | 42 ++++++++++++++++--- 4 files changed, 57 insertions(+), 15 deletions(-) create mode 100644 src/settings-ui/Settings.UI/NewUtilityAttribute.cs diff --git a/src/settings-ui/Settings.UI/NewUtilityAttribute.cs b/src/settings-ui/Settings.UI/NewUtilityAttribute.cs new file mode 100644 index 0000000000..c7b557971c --- /dev/null +++ b/src/settings-ui/Settings.UI/NewUtilityAttribute.cs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +namespace Microsoft.PowerToys.Settings.UI +{ + [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] + public sealed class NewUtilityAttribute : Attribute + { + public string Version { get; } + + public NewUtilityAttribute(string version) + { + Version = version; + } + } +} diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/LightSwitchPage.xaml.cs b/src/settings-ui/Settings.UI/SettingsXAML/Views/LightSwitchPage.xaml.cs index d970700484..0f87cb170b 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Views/LightSwitchPage.xaml.cs +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/LightSwitchPage.xaml.cs @@ -21,10 +21,10 @@ using PowerToys.GPOWrapper; using Settings.UI.Library; using Settings.UI.Library.Helpers; using Windows.Devices.Geolocation; -using Windows.Services.Maps; namespace Microsoft.PowerToys.Settings.UI.Views { + [NewUtility("v0.95")] public sealed partial class LightSwitchPage : Page { private readonly string _appName = "LightSwitch"; diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/ShellPage.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Views/ShellPage.xaml index c2de045ed2..84843bb1f4 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Views/ShellPage.xaml +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/ShellPage.xaml @@ -177,9 +177,6 @@ AutomationProperties.AutomationId="SystemToolsNavItem" Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/SystemTools.png}" SelectsOnInvoked="False"> - - - - - - - + Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/LightSwitch.png}" /> AppTitleBar; + private static string _version = Helper.GetProductVersion(); private Dictionary _navViewParentLookup = new Dictionary(); private List _searchSuggestions = []; @@ -168,15 +166,26 @@ namespace Microsoft.PowerToys.Settings.UI.Views } var topLevelItems = navigationView.MenuItems.OfType().ToArray(); + var newTopLevelItems = new HashSet(); foreach (var parent in topLevelItems) { foreach (var child in parent.MenuItems.OfType()) { - _navViewParentLookup.TryAdd(child.GetValue(NavHelper.NavigateToProperty) as Type, parent); + var pageType = child.GetValue(NavHelper.NavigateToProperty) as Type; + _navViewParentLookup.TryAdd(pageType, parent); _searchSuggestions.Add(child.Content?.ToString()); + if (AddNewTagIfNeeded(child, pageType)) + { + newTopLevelItems.Add(parent); + } } } + + foreach (var parent in newTopLevelItems) + { + parent.InfoBadge = GetNewInfoBadge(); + } } public static int SendDefaultIPCMessage(string msg) @@ -717,6 +726,27 @@ namespace Microsoft.PowerToys.Settings.UI.Views NavigationService.Navigate(searchParams); } + private bool AddNewTagIfNeeded(NavigationViewItem item, Type pageType) + { + var newUtility = pageType.GetCustomAttribute(); + + if (newUtility != null && _version.StartsWith(newUtility.Version, StringComparison.InvariantCulture)) + { + item.InfoBadge = GetNewInfoBadge(); + return true; + } + + return false; + } + + private InfoBadge GetNewInfoBadge() + { + return new InfoBadge + { + Style = (Style)Application.Current.Resources["NewInfoBadge"], + }; + } + public void Dispose() { if (_disposed)