From 22d77f03ff72dca09d12f741f59a548b5e59c5ba Mon Sep 17 00:00:00 2001 From: Luke44565 Date: Tue, 12 Mar 2024 20:57:23 -0400 Subject: [PATCH] Initial Implementation --- .../App/ApplicationLibrary.cs | 49 +++++++++++++++++- .../Resources/Icon_Folder.png | Bin 0 -> 2091 bytes .../Ryujinx.UI.Common.csproj | 2 + src/Ryujinx/UI/Helpers/Glyph.cs | 1 + src/Ryujinx/UI/Helpers/GlyphValueConverter.cs | 1 + .../UI/ViewModels/MainWindowViewModel.cs | 30 +++++++++++ .../UI/Views/Main/MainViewControls.axaml | 13 +++++ src/Ryujinx/UI/Windows/MainWindow.axaml.cs | 5 ++ 8 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 src/Ryujinx.UI.Common/Resources/Icon_Folder.png diff --git a/src/Ryujinx.UI.Common/App/ApplicationLibrary.cs b/src/Ryujinx.UI.Common/App/ApplicationLibrary.cs index 65cf7a9e6..ccd707058 100644 --- a/src/Ryujinx.UI.Common/App/ApplicationLibrary.cs +++ b/src/Ryujinx.UI.Common/App/ApplicationLibrary.cs @@ -41,6 +41,7 @@ namespace Ryujinx.UI.App.Common private readonly byte[] _ncaIcon; private readonly byte[] _nroIcon; private readonly byte[] _nsoIcon; + private readonly byte[] _folderIcon; private readonly VirtualFileSystem _virtualFileSystem; private Language _desiredTitleLanguage; @@ -58,6 +59,7 @@ namespace Ryujinx.UI.App.Common _ncaIcon = GetResourceBytes("Ryujinx.UI.Common.Resources.Icon_NCA.png"); _nroIcon = GetResourceBytes("Ryujinx.UI.Common.Resources.Icon_NRO.png"); _nsoIcon = GetResourceBytes("Ryujinx.UI.Common.Resources.Icon_NSO.png"); + _folderIcon = GetResourceBytes("Ryujinx.UI.Common.Resources.Icon_Folder.png"); } private static byte[] GetResourceBytes(string resourceName) @@ -113,7 +115,31 @@ namespace Ryujinx.UI.App.Common try { - IEnumerable files = Directory.EnumerateFiles(appDir, "*", SearchOption.AllDirectories).Where(file => + IEnumerable folders = Directory.EnumerateDirectories(appDir, "*", SearchOption.TopDirectoryOnly); + foreach (string folder in folders) + { + if (_cancellationToken.Token.IsCancellationRequested) + { + return; + } + + var fileInfo = new FileInfo(folder); + + var fullPath = fileInfo.ResolveLinkTarget(true)?.FullName ?? fileInfo.FullName; + ApplicationData folderData = new() + { + TitleName = fileInfo.Name, + FileExtension = "Folder", + Path = fullPath, + Icon = _folderIcon, + }; + OnApplicationAdded(new ApplicationAddedEventArgs + { + AppData = folderData, + }); + } + + IEnumerable files = Directory.EnumerateFiles(appDir, "*", SearchOption.TopDirectoryOnly).Where(file => { return (Path.GetExtension(file).ToLower() is ".nsp" && ConfigurationState.Instance.UI.ShownFileTypes.NSP.Value) || @@ -163,7 +189,26 @@ namespace Ryujinx.UI.App.Common return; } - long fileSize = new FileInfo(applicationPath).Length; + var fileInfo = new FileInfo(applicationPath); + + if ((fileInfo.Attributes & FileAttributes.Directory) == FileAttributes.Directory) + { + Console.WriteLine($"Found directory 2: {fileInfo.Name}"); + ApplicationData folder = new() + { + TitleName = fileInfo.Name, + FileExtension = "Folder", + Developer = "null", + Path = applicationPath, + Icon = _nsoIcon, + }; + OnApplicationAdded(new ApplicationAddedEventArgs + { + AppData = folder, + }); + } + + long fileSize = fileInfo.Length; string titleName = "Unknown"; string titleId = "0000000000000000"; string developer = "Unknown"; diff --git a/src/Ryujinx.UI.Common/Resources/Icon_Folder.png b/src/Ryujinx.UI.Common/Resources/Icon_Folder.png new file mode 100644 index 0000000000000000000000000000000000000000..dba7ff44d74db4fbf1ef51bfee016c55d43d1bd7 GIT binary patch literal 2091 zcmb_cc~Dd57C$$+1Z2HDP?oS<(js(NOh93z0ztz7tpr{~P^lP1q1qy}4=a(UTq(6s zH?XZ$#1iU=Rz&DSpzL|CQbb0QirN%{M4n5PC5$L234HxxXFBa4{ik;3%vpYCz31F} zi{r&nR_4y;0ALjpEs_ARuu7Dfv9S=>TV!KFW<!~v)R&{u#e0m)wwHnD>F?-8v3hX3lt z=I^Q18MSdyivwzQK&=bWcOIzI4K+|ku-g+gE<|0gqBbYg;)MQ7qi-Ehrz>j3@lNP} zG-`4{?Ob%0gK8{MqdjVMG6rw9jc6gY2TXgvq<9N7ToejEVA80tn#fuQ-NW^P^ zAD&;)DOJ*0wK{5(@JReHlPxc)Q*?Lk-?3u)zI)$%lK$dJUG|`&T=#L`6_uuT_`&}b zj8Ih~rM3JzIW?Ib-+Ob^cpPH$n^7VtGI5Q@hG|YrY^3Qu!qr+}9ky(r2Ee30Mih~d zJ1{TP-;G*$CKs;htfW$#ga{%7BJjW}DX2X3P&y&0Ms zYkM#@BzYvSfDKHv!6Ha3U}_Ab0FGhCv6_g zA7oN;vV3PU$(;7eQjOA9buR;TH!EL}pWGAhWgzih_nZakbb!x)%3bd%9C4I zJynhU2c)h$)IFAr`zMyac%JqzgR*W`C!m#dS7Tw$;8 z=EN}2Cdni6WS~fv%VWpc*`(zjOW)_N@tXV7kjp9@zv&OV81)Qu)SX36j0QmzquA5W z(MC$gRtbCTd0$*_+E3|EGCE6-_v;_#tt!&kJdDEpt=S%mH^XZWC{)h~0VpuHkbY0` zg7II8B?L1dXdoF3vtG`KuO-@o3a_+_r}k6LGGm{YEcka70DzZ!vcGE(g2toZui~%m z`^H&VgfD9WBGY(5;gz*eWKBD*yeoO*Ko!;06~uU^6%9(bivI{MXEs|&yBtRvuX9Qg zuX#MSRd~?PZ0R%SBSbYVriws%d$oR4w^Mjyku`j4D(Ya5B?cZSx*2w%(_y8c+Q3#Q z3wS|DH#^8G$bv>j%VqrNSx$*$NVIuvc+33P-=r@t-SCbJyQFOYKfX>6DgBpJzTNA` z;Z^h#wj!2(Y(>j_9Opsn@A!<9>y2#9R3kr)RydRP`E%T27>#3|hQG-yDKys@nn!j1 z)DwfQL3me>igo1N8aY#wc>SYyo}J3RbAFk`%P((P!ns>}#jdv|D}G=#+=xDvw9~`) z>b=@B|0I)rJl}lJjUC&E)=TRu=ALeE*>Gs!s^)c9ViR#wMV>n_HfIo*J`i>p3cmO?Jk;=_36M6S!(lA5zMB<=mJ zSU> + @@ -33,6 +34,7 @@ + diff --git a/src/Ryujinx/UI/Helpers/Glyph.cs b/src/Ryujinx/UI/Helpers/Glyph.cs index f257dc02c..d44f0875a 100644 --- a/src/Ryujinx/UI/Helpers/Glyph.cs +++ b/src/Ryujinx/UI/Helpers/Glyph.cs @@ -4,6 +4,7 @@ namespace Ryujinx.Ava.UI.Helpers { List, Grid, + Back, Chip, } } diff --git a/src/Ryujinx/UI/Helpers/GlyphValueConverter.cs b/src/Ryujinx/UI/Helpers/GlyphValueConverter.cs index 7da23648e..9731123e9 100644 --- a/src/Ryujinx/UI/Helpers/GlyphValueConverter.cs +++ b/src/Ryujinx/UI/Helpers/GlyphValueConverter.cs @@ -13,6 +13,7 @@ namespace Ryujinx.Ava.UI.Helpers { { Glyph.List, char.ConvertFromUtf32((int)Symbol.List) }, { Glyph.Grid, char.ConvertFromUtf32((int)Symbol.ViewAll) }, + { Glyph.Back, char.ConvertFromUtf32((int)Symbol.Back) }, { Glyph.Chip, char.ConvertFromUtf32(59748) }, }; diff --git a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs index 17bd69b14..c5de76f5a 100644 --- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs @@ -51,6 +51,7 @@ namespace Ryujinx.Ava.UI.ViewModels private const int HotKeyPressDelayMs = 500; private ObservableCollection _applications; + private Queue _pathHistory; private string _aspectStatusText; private string _loadHeading; @@ -120,6 +121,7 @@ namespace Ryujinx.Ava.UI.ViewModels .Bind(out _appsObservableList).AsObservableList(); _rendererWaitEvent = new AutoResetEvent(false); + _pathHistory = new Queue(); if (Program.PreviewerDetached) { @@ -1281,6 +1283,34 @@ namespace Ryujinx.Ava.UI.ViewModels ShowConsole = !ShowConsole; } + public void OpenFolder(string path) + { + _pathHistory.Enqueue(path); + Applications.Clear(); + List SearchPaths = new List(); + SearchPaths.Add(path); + ApplicationLibrary.LoadApplications(SearchPaths, ConfigurationState.Instance.System.Language); + } + + public void NavigateBack() + { + if (_pathHistory.Count != 0) + { + string path = _pathHistory.Dequeue(); + Applications.Clear(); + if (_pathHistory.Count == 0) + { + ApplicationLibrary.LoadApplications(ConfigurationState.Instance.UI.GameDirs, ConfigurationState.Instance.System.Language); + } + else + { + List SearchPaths = new List(); + SearchPaths.Add(path); + ApplicationLibrary.LoadApplications(SearchPaths, ConfigurationState.Instance.System.Language); + } + } + } + public void SetListMode() { Glyph = Glyph.List; diff --git a/src/Ryujinx/UI/Views/Main/MainViewControls.axaml b/src/Ryujinx/UI/Views/Main/MainViewControls.axaml index cc21b5c60..b49aaacc2 100644 --- a/src/Ryujinx/UI/Views/Main/MainViewControls.axaml +++ b/src/Ryujinx/UI/Views/Main/MainViewControls.axaml @@ -18,6 +18,19 @@ Margin="0,0,0,5" Height="35" HorizontalAlignment="Stretch"> +