NavigationView NEW tag with attribute

This commit is contained in:
Davide Giacometti
2025-10-23 22:46:51 +02:00
parent f28d009131
commit 88b216032e
4 changed files with 57 additions and 15 deletions

View File

@@ -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;
}
}
}

View File

@@ -21,10 +21,10 @@ using PowerToys.GPOWrapper;
using Settings.UI.Library; using Settings.UI.Library;
using Settings.UI.Library.Helpers; using Settings.UI.Library.Helpers;
using Windows.Devices.Geolocation; using Windows.Devices.Geolocation;
using Windows.Services.Maps;
namespace Microsoft.PowerToys.Settings.UI.Views namespace Microsoft.PowerToys.Settings.UI.Views
{ {
[NewUtility("v0.95")]
public sealed partial class LightSwitchPage : Page public sealed partial class LightSwitchPage : Page
{ {
private readonly string _appName = "LightSwitch"; private readonly string _appName = "LightSwitch";

View File

@@ -177,9 +177,6 @@
AutomationProperties.AutomationId="SystemToolsNavItem" AutomationProperties.AutomationId="SystemToolsNavItem"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/SystemTools.png}" Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/SystemTools.png}"
SelectsOnInvoked="False"> SelectsOnInvoked="False">
<NavigationViewItem.InfoBadge>
<InfoBadge Style="{StaticResource NewInfoBadge}" />
</NavigationViewItem.InfoBadge>
<NavigationViewItem.MenuItems> <NavigationViewItem.MenuItems>
<NavigationViewItem <NavigationViewItem
x:Name="AdvancedPasteNavigationItem" x:Name="AdvancedPasteNavigationItem"
@@ -210,11 +207,7 @@
x:Uid="Shell_LightSwitch" x:Uid="Shell_LightSwitch"
helpers:NavHelper.NavigateTo="views:LightSwitchPage" helpers:NavHelper.NavigateTo="views:LightSwitchPage"
AutomationProperties.AutomationId="LightSwitchNavItem" AutomationProperties.AutomationId="LightSwitchNavItem"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/LightSwitch.png}"> Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/LightSwitch.png}" />
<NavigationViewItem.InfoBadge>
<InfoBadge Style="{StaticResource NewInfoBadge}" />
</NavigationViewItem.InfoBadge>
</NavigationViewItem>
<NavigationViewItem <NavigationViewItem
x:Name="PowerLauncherNavigationItem" x:Name="PowerLauncherNavigationItem"
x:Uid="Shell_PowerLauncher" x:Uid="Shell_PowerLauncher"

View File

@@ -5,17 +5,15 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Common.Search;
using Common.Search.FuzzSearch;
using ManagedCommon; using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Controls;
using Microsoft.PowerToys.Settings.UI.Helpers; using Microsoft.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
using Microsoft.PowerToys.Settings.UI.Services; using Microsoft.PowerToys.Settings.UI.Services;
using Microsoft.PowerToys.Settings.UI.ViewModels; using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml; using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Automation.Peers; using Microsoft.UI.Xaml.Automation.Peers;
using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Controls;
@@ -23,7 +21,6 @@ using Microsoft.UI.Xaml.Input;
using Settings.UI.Library; using Settings.UI.Library;
using Windows.Data.Json; using Windows.Data.Json;
using Windows.System; using Windows.System;
using WinRT.Interop;
namespace Microsoft.PowerToys.Settings.UI.Views namespace Microsoft.PowerToys.Settings.UI.Views
{ {
@@ -134,6 +131,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
public Controls.TitleBar TitleBar => AppTitleBar; public Controls.TitleBar TitleBar => AppTitleBar;
private static string _version = Helper.GetProductVersion();
private Dictionary<Type, NavigationViewItem> _navViewParentLookup = new Dictionary<Type, NavigationViewItem>(); private Dictionary<Type, NavigationViewItem> _navViewParentLookup = new Dictionary<Type, NavigationViewItem>();
private List<string> _searchSuggestions = []; private List<string> _searchSuggestions = [];
@@ -168,15 +166,26 @@ namespace Microsoft.PowerToys.Settings.UI.Views
} }
var topLevelItems = navigationView.MenuItems.OfType<NavigationViewItem>().ToArray(); var topLevelItems = navigationView.MenuItems.OfType<NavigationViewItem>().ToArray();
var newTopLevelItems = new HashSet<NavigationViewItem>();
foreach (var parent in topLevelItems) foreach (var parent in topLevelItems)
{ {
foreach (var child in parent.MenuItems.OfType<NavigationViewItem>()) foreach (var child in parent.MenuItems.OfType<NavigationViewItem>())
{ {
_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()); _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) public static int SendDefaultIPCMessage(string msg)
@@ -717,6 +726,27 @@ namespace Microsoft.PowerToys.Settings.UI.Views
NavigationService.Navigate<SearchResultsPage>(searchParams); NavigationService.Navigate<SearchResultsPage>(searchParams);
} }
private bool AddNewTagIfNeeded(NavigationViewItem item, Type pageType)
{
var newUtility = pageType.GetCustomAttribute<NewUtilityAttribute>();
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() public void Dispose()
{ {
if (_disposed) if (_disposed)