From 64845b7fd87cba2156b9d9f24bf93f0e3b48480f Mon Sep 17 00:00:00 2001 From: Clint Rutkas Date: Sun, 27 Oct 2024 15:21:27 -0700 Subject: [PATCH] Updating navigation tree for settings with groupings (#35559) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * adjusting stuff from here to there * No longer crashing! a win! * Resources now * spelling * adjusting comments for xaml formatting * added in new top level icons * Fixing * adjusting the core container logic based on feedback. this is actually simplier and just leverages the builti in stuff as well * getting frame_nav functional again, thanks @davidegiacometti * making a one time hit for union * Update src/settings-ui/Settings.UI/ViewModels/ShellViewModel.cs Co-authored-by: Jeremy Sinclair <4016293+snickler@users.noreply.github.com> * expanding code that @davidegiacometti suggestedion. 🔥 * ensure parent is always expanded when page is changed * don't use static --------- Co-authored-by: Ethan Fang Co-authored-by: Jeremy Sinclair <4016293+snickler@users.noreply.github.com> Co-authored-by: Davide Giacometti Co-authored-by: Jaime Bernardo --- .../Assets/Settings/Icons/Advanced.png | Bin 0 -> 1264 bytes .../Assets/Settings/Icons/FileManagement.png | Bin 0 -> 1458 bytes .../Assets/Settings/Icons/InputOutput.png | Bin 0 -> 2058 bytes .../Assets/Settings/Icons/SystemTools.png | Bin 0 -> 1447 bytes .../Settings/Icons/WindowingAndLayouts.png | Bin 0 -> 1497 bytes .../SettingsXAML/Views/ShellPage.xaml | 264 ++++++++++-------- .../SettingsXAML/Views/ShellPage.xaml.cs | 33 ++- .../Settings.UI/Strings/en-us/Resources.resw | 22 +- .../Settings.UI/ViewModels/ShellViewModel.cs | 19 +- 9 files changed, 199 insertions(+), 139 deletions(-) create mode 100644 src/settings-ui/Settings.UI/Assets/Settings/Icons/Advanced.png create mode 100644 src/settings-ui/Settings.UI/Assets/Settings/Icons/FileManagement.png create mode 100644 src/settings-ui/Settings.UI/Assets/Settings/Icons/InputOutput.png create mode 100644 src/settings-ui/Settings.UI/Assets/Settings/Icons/SystemTools.png create mode 100644 src/settings-ui/Settings.UI/Assets/Settings/Icons/WindowingAndLayouts.png diff --git a/src/settings-ui/Settings.UI/Assets/Settings/Icons/Advanced.png b/src/settings-ui/Settings.UI/Assets/Settings/Icons/Advanced.png new file mode 100644 index 0000000000000000000000000000000000000000..da8abaded64afad8dd334df532a71cc695f8ad1a GIT binary patch literal 1264 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 literal 0 HcmV?d00001 diff --git a/src/settings-ui/Settings.UI/Assets/Settings/Icons/SystemTools.png b/src/settings-ui/Settings.UI/Assets/Settings/Icons/SystemTools.png new file mode 100644 index 0000000000000000000000000000000000000000..2db25f1278d885b6d43bc63dd8c546a5faae76a4 GIT binary patch literal 1447 zcmV;Y1z7rtP)L)e{&w3d|F$f2Lq%D6=~}oOV{({DwTtBb zdDPWNf9dkn=hXD7E)b|3X0VU?x7+K>V4?kR7jApItT45&&KIWTsQu7(qBs73x@X;N z?z{Rz73f#9GLW)wg#kV%rk~U`VN4}pv^8P_E(bA#~(GK4e`@r63P zXIBv4_M@Swe~Z9V!NNd*bTYtE>wbuP#I(c$1Z`;>cW5aBayD#7b$?$2Ewjy8B zNJ^9)A=WAJ8|^LBrhuZfbqFjZGGpbv zrYfwQgCSA=mGlZ$4@ZdT5RGuMjH3vjJ}Gup62AVA}kxI ztIRV@8_p3BYABQ>N1oZZ&>JD=*%0R-Hxj+A4}ciA9tjAt${YziC-Z1AQ(KUcFGUwR z5_eEYLs>lqBNEynONQl4cB=jpjU9b0%9_UhY&lc%>mWrOL2_`SffgaD zfvqPa35#{7L>y~p@|(sqNlb<_QfL%fgS9(2P0*(zkCNyp^P?=!9GjWADr71Il&`}z zjw?>8gDjKlVy{+&y6)&@b3OOj<%tM`cB?`|we~cjtQU^fV@)WgV=&4myPHowj37vn0lm|1z z(2+mR#+1z%We`d7Tk_%Fd;=)~^^aSQWA{&kNeZt{okU3V+L`ut=5{@a^$?f5uzs1sv(KYN$=tbrERDb3-CImLyn_GyhJ zDiQAMZ@)?1ptxb&f1qD~@d^~HYMky_ z6`BlRUIfQ`|9gJ%SfB1!KD~379zMF@-Nj?N|KN;H|GihK!tdPr`EFl+G7_5#ngauL zlT(N&(Toa`J$4T#C6jZLUjQJ(>Jhlt`aj?Ga{JM}$-6cx8kg?yG#FTQv(D#DAIDXB z46ENV5jrCLUx1xdaK9(8J)uJTbKI8OboIPy&ohw*gQqN7o8kZf002ovPDHLkV1i7! Bpick* literal 0 HcmV?d00001 diff --git a/src/settings-ui/Settings.UI/Assets/Settings/Icons/WindowingAndLayouts.png b/src/settings-ui/Settings.UI/Assets/Settings/Icons/WindowingAndLayouts.png new file mode 100644 index 0000000000000000000000000000000000000000..9e0bd706f95ca8a9743a0bf192be577968c66f7a GIT binary patch literal 1497 zcmV;~1t$85P)C|NvfT+HMObaqgqWt3hJsTiV7mFi|Vpc_fm`E&Yde|Tq(prT?Z=u1KD*U zDu|^-v9=Z(ni@*bkx8abGN11r?>*<<`))qwrJF{C9%l09y?5_9zw>c_=LFz^{Lci< zpOKkc9{{Cq5+Wgyeii}$Fdwr>KL`8VeDrTJ5BaJ$0Vt3c$}9G|BK=$`dyklzR-2*x zTs{B9hXvWKzA)I>I%6cU%Xd}>Mq0bp$$E%CM!m6WR%v8rtx;jTK(9*)c2>q9(3(Km zPae_B`YV7~JsJ4Mq--_%IVfVwfJVR9n)AvG77HJ&5%lpl0b=wVA=aGf_lyH`nnlmVg!N_j~szY@KXMS*K1>qt*h2iN^?yyFm4t z1C4eIszQ`fMy(hxy$ zFmsyAM&2{ek#7+eP>=#H__XJC328CqnP9{o94}DHo8Y#=sgHzqb*phsl8cw`iQxV6 z`~YEuTwgNRUK7Tq_Cj2Uz{56ZFor*_uTrYh!5Y#I#5aEd)XXk9_0fcM{20)lVLW~y zf~$YEb<`7^RUrc3qHN1?eL4W-eE{mTvHWNmwv&jen5sk^OH+#fS=o-MA#JSz3_c8% zS4UxDxCozqy9{4nTholpz@#uOd7>1x-yeA`($8{Fj{vvMLFV$o*@IKHVTZru&Hlr%X&k3gl8?HsUs_ApF0S@z5g^+Ufhf0rLGAJ z+Hg6t&H!a&ghoRu$Mb++RR48ZxoqXD_nsexxpy9ix2K8#y|(aF&^jC-3hU?|3_&iV zt9)G(`v%~vw~oNob4THgiCEWTPqt)$>?CHmM)Od!-h|G2d(*cAy{=FOx0t9vR2npe zy5$Q|Aq!`Y7+~L=ISLm}K7!*zX~sj2)fi(ufY&eoEyuu*i}pkp2FT7hXpAl7WmUo11o!v(Ju*9kVxN>LiX{ z>2%X)DE!wd5~L($FVB>VK)5Ejnm2YI^g8jOJ@Lo-Zp^%Cx7*iRt=64#x%`^je*T3+ zaOwAI<;Ru58+!jD+-E5?o6R56G_BWawT~tzCkHB(%DB0wK-SjQ=JeVGc0r=W#l@4e zv$La+wWwHw`;0cp!otES*d?)}MkWSex7%F`0W}(pixBqJU6yEme*Sa_s9LSQ3-`cR z_fv|?%gg81*VixFbj9w)e~HSaC>TB-$j + + x:Uid="Shell_TopLevelSystemTools" + Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/SystemTools.png}" + SelectsOnInvoked="False"> + + + + + + + + + + + + x:Uid="Shell_TopLevelWindowsAndLayouts " + Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/WindowingAndLayouts.png}" + SelectsOnInvoked="False"> + + + + + + + + + x:Uid="Shell_TopLevelInputOutput" + Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/InputOutput.png}" + SelectsOnInvoked="False"> + + + + + + + + + + + + + x:Uid="Shell_TopLevelFileManagement" + Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/FileManagement.png}" + SelectsOnInvoked="False"> + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + x:Uid="Shell_TopLevelAdvanced" + Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/Advanced.png}" + SelectsOnInvoked="False"> + + + + + + + diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/ShellPage.xaml.cs b/src/settings-ui/Settings.UI/SettingsXAML/Views/ShellPage.xaml.cs index eac8029b2e..9ff088b787 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Views/ShellPage.xaml.cs +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/ShellPage.xaml.cs @@ -4,7 +4,7 @@ using System; using System.Collections.Generic; - +using System.Linq; using ManagedCommon; using Microsoft.PowerToys.Settings.UI.Helpers; using Microsoft.PowerToys.Settings.UI.Services; @@ -122,6 +122,8 @@ namespace Microsoft.PowerToys.Settings.UI.Views public static bool IsUserAnAdmin { get; set; } + private Dictionary _navViewParentLookup = new Dictionary(); + /// /// Initializes a new instance of the class. /// Shell page constructor. @@ -138,6 +140,21 @@ namespace Microsoft.PowerToys.Settings.UI.Views // shellFrame.Navigate(typeof(GeneralPage)); IPCResponseHandleList.Add(ReceiveMessage); SetTitleBar(); + + if (_navViewParentLookup.Count > 0) + { + _navViewParentLookup.Clear(); + } + + var topLevelItems = navigationView.MenuItems.OfType().ToArray(); + + foreach (var parent in topLevelItems) + { + foreach (var child in parent.MenuItems.OfType()) + { + _navViewParentLookup.TryAdd(child.GetValue(NavHelper.NavigateToProperty) as Type, parent); + } + } } public static int SendDefaultIPCMessage(string msg) @@ -277,7 +294,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views private bool navigationViewInitialStateProcessed; // avoid announcing initial state of the navigation pane. - private void NavigationView_PaneOpened(Microsoft.UI.Xaml.Controls.NavigationView sender, object args) + private void NavigationView_PaneOpened(NavigationView sender, object args) { if (!navigationViewInitialStateProcessed) { @@ -293,7 +310,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views if (AutomationPeer.ListenerExists(AutomationEvents.MenuOpened)) { - var loader = Helpers.ResourceLoaderInstance.ResourceLoader; + var loader = ResourceLoaderInstance.ResourceLoader; peer.RaiseNotificationEvent( AutomationNotificationKind.ActionCompleted, AutomationNotificationProcessing.ImportantMostRecent, @@ -302,7 +319,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views } } - private void NavigationView_PaneClosed(Microsoft.UI.Xaml.Controls.NavigationView sender, object args) + private void NavigationView_PaneClosed(NavigationView sender, object args) { if (!navigationViewInitialStateProcessed) { @@ -318,7 +335,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views if (AutomationPeer.ListenerExists(AutomationEvents.MenuClosed)) { - var loader = Helpers.ResourceLoaderInstance.ResourceLoader; + var loader = ResourceLoaderInstance.ResourceLoader; peer.RaiseNotificationEvent( AutomationNotificationKind.ActionCompleted, AutomationNotificationProcessing.ImportantMostRecent, @@ -348,6 +365,12 @@ namespace Microsoft.PowerToys.Settings.UI.Views if (selectedItem != null) { Type pageType = selectedItem.GetValue(NavHelper.NavigateToProperty) as Type; + + if (_navViewParentLookup.TryGetValue(pageType, out var parentItem) && !parentItem.IsExpanded) + { + parentItem.IsExpanded = true; + } + NavigationService.Navigate(pageType); } } diff --git a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw index cb7d064579..85e5a8a986 100644 --- a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw +++ b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw @@ -59,10 +59,7 @@ : using a System.ComponentModel.TypeConverter : and then encoded with base64 encoding. --> - + @@ -4563,4 +4560,19 @@ Activate by holding the key for the character you want to add an accent to, then Restart - + + Advanced + + + File Management + + + Input / Output + + + Windowing & Layouts + + + System Tools + + \ No newline at end of file diff --git a/src/settings-ui/Settings.UI/ViewModels/ShellViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/ShellViewModel.cs index f02127ea38..0779293204 100644 --- a/src/settings-ui/Settings.UI/ViewModels/ShellViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/ShellViewModel.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.IO.Abstractions; using System.Linq; using System.Threading.Tasks; using System.Windows.Input; @@ -32,6 +31,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels private NavigationViewItem selected; private ICommand loadedCommand; private ICommand itemInvokedCommand; + private NavigationViewItem[] _fullListOfNavViewItems; public bool IsBackEnabled { @@ -76,6 +76,8 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels NavigationService.NavigationFailed += Frame_NavigationFailed; NavigationService.Navigated += Frame_Navigated; this.navigationView.BackRequested += OnBackRequested; + var topLevelItems = navigationView.MenuItems.OfType(); + _fullListOfNavViewItems = topLevelItems.Union(topLevelItems.SelectMany(menuItem => menuItem.MenuItems.OfType())).ToArray(); } private static KeyboardAccelerator BuildKeyboardAccelerator(VirtualKey key, VirtualKeyModifiers? modifiers = null) @@ -107,11 +109,12 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels private void OnItemInvoked(NavigationViewItemInvokedEventArgs args) { - var item = navigationView.MenuItems - .OfType() - .First(menuItem => (string)menuItem.Content == (string)args.InvokedItem); - var pageType = item.GetValue(NavHelper.NavigateToProperty) as Type; - NavigationService.Navigate(pageType); + var pageType = args.InvokedItemContainer.GetValue(NavHelper.NavigateToProperty) as Type; + + if (pageType != null) + { + NavigationService.Navigate(pageType); + } } private void OnBackRequested(NavigationView sender, NavigationViewBackRequestedEventArgs args) @@ -127,9 +130,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels private void Frame_Navigated(object sender, NavigationEventArgs e) { IsBackEnabled = NavigationService.CanGoBack; - Selected = navigationView.MenuItems - .OfType() - .FirstOrDefault(menuItem => IsMenuItemForPageType(menuItem, e.SourcePageType)); + Selected = _fullListOfNavViewItems.FirstOrDefault(menuItem => IsMenuItemForPageType(menuItem, e.SourcePageType)); } private static bool IsMenuItemForPageType(NavigationViewItem menuItem, Type sourcePageType)