aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAc_K <Acoustik666@gmail.com>2023-05-04 16:41:06 +0200
committerGitHub <noreply@github.com>2023-05-04 14:41:06 +0000
commit3b8ac1641a8a40849915396813e26384b5894911 (patch)
tree5355d6601917146809323990a1a0de8f3a7e893b
parent42507323535443ad79be071367f3d4815afca688 (diff)
UI: Move ApplicationContextMenu in a separated class (#4755)1.1.750
* UI: Move ApplicationContextMenu in a separated class This PR remove duplicated code related to the context menu on the Application list/grid by create a control for the menu which include related handler. I've renamed "GameList/GameGrid" by "Application" for consistencies. And I've removed all uneeded field from the project file too. While I cleaned up things, I've found an issue about purging Ptc/Shader cache, both methods list files even if the user say "No", shader cache is purged even if the user say "No". It's fixed. * Adresses feedbacks
-rw-r--r--src/Ryujinx.Ava/Ryujinx.Ava.csproj44
-rw-r--r--src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml80
-rw-r--r--src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs320
-rw-r--r--src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml102
-rw-r--r--src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs (renamed from src/Ryujinx.Ava/UI/Controls/GameGridView.axaml.cs)8
-rw-r--r--src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml (renamed from src/Ryujinx.Ava/UI/Controls/GameListView.axaml)83
-rw-r--r--src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs (renamed from src/Ryujinx.Ava/UI/Controls/GameListView.axaml.cs)8
-rw-r--r--src/Ryujinx.Ava/UI/Controls/GameGridView.axaml177
-rw-r--r--src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs266
-rw-r--r--src/Ryujinx.Ava/UI/Windows/MainWindow.axaml8
-rw-r--r--src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs8
11 files changed, 526 insertions, 578 deletions
diff --git a/src/Ryujinx.Ava/Ryujinx.Ava.csproj b/src/Ryujinx.Ava/Ryujinx.Ava.csproj
index 7509798b..2b6432e9 100644
--- a/src/Ryujinx.Ava/Ryujinx.Ava.csproj
+++ b/src/Ryujinx.Ava/Ryujinx.Ava.csproj
@@ -103,50 +103,6 @@
<Generator>MSBuild:Compile</Generator>
</AvaloniaResource>
<AvaloniaResource Include="Assets\Styles\Styles.xaml" />
-
- <Compile Update="App.axaml.cs">
- <DependentUpon>App.axaml</DependentUpon>
- <SubType>Code</SubType>
- </Compile>
- <Compile Update="Ui\Windows\MainWindow.axaml.cs">
- <DependentUpon>MainWindow.axaml</DependentUpon>
- <SubType>Code</SubType>
- </Compile>
- <Compile Update="Ui\Windows\AboutWindow.axaml.cs">
- <DependentUpon>AboutWindow.axaml</DependentUpon>
- <SubType>Code</SubType>
- </Compile>
- <Compile Update="Ui\Applet\ErrorAppletWindow.axaml.cs">
- <DependentUpon>ProfileWindow.axaml</DependentUpon>
- <SubType>Code</SubType>
- </Compile>
- <Compile Update="Ui\Applet\SwkbdAppletWindow.axaml.cs">
- <DependentUpon>ProfileWindow.axaml</DependentUpon>
- <SubType>Code</SubType>
- </Compile>
- <Compile Update="Ui\Controls\InputDialog.axaml.cs">
- <DependentUpon>InputDialog.axaml</DependentUpon>
- <SubType>Code</SubType>
- </Compile>
- <Compile Update="Ui\Windows\ContentDialogOverlay.xaml.cs">
- <DependentUpon>ContentDialogOverlay.xaml</DependentUpon>
- </Compile>
- <Compile Update="Ui\Controls\GameListView.axaml.cs">
- <DependentUpon>GameListView.axaml</DependentUpon>
- <SubType>Code</SubType>
- </Compile>
- <Compile Update="UI\Views\User\UserEditorView.axaml.cs">
- <DependentUpon>UserEditor.axaml</DependentUpon>
- <SubType>Code</SubType>
- </Compile>
- <Compile Update="UI\Views\User\UserRecovererView.axaml.cs">
- <DependentUpon>UserRecoverer.axaml</DependentUpon>
- <SubType>Code</SubType>
- </Compile>
- <Compile Update="UI\Views\User\UserSelectorView.axaml.cs">
- <DependentUpon>UserSelector.axaml</DependentUpon>
- <SubType>Code</SubType>
- </Compile>
</ItemGroup>
<ItemGroup>
diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml b/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml
new file mode 100644
index 00000000..1750e800
--- /dev/null
+++ b/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml
@@ -0,0 +1,80 @@
+<MenuFlyout
+ x:Class="Ryujinx.Ava.UI.Controls.ApplicationContextMenu"
+ xmlns="https://github.com/avaloniaui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale">
+ <MenuItem
+ Click="ToggleFavorite_Click"
+ Header="{locale:Locale GameListContextMenuToggleFavorite}"
+ ToolTip.Tip="{locale:Locale GameListContextMenuToggleFavoriteToolTip}" />
+ <Separator />
+ <MenuItem
+ Click="OpenUserSaveDirectory_Click"
+ Header="{locale:Locale GameListContextMenuOpenUserSaveDirectory}"
+ IsEnabled="{Binding OpenUserSaveDirectoryEnabled}"
+ ToolTip.Tip="{locale:Locale GameListContextMenuOpenUserSaveDirectoryToolTip}" />
+ <MenuItem
+ Click="OpenDeviceSaveDirectory_Click"
+ Header="{locale:Locale GameListContextMenuOpenDeviceSaveDirectory}"
+ IsEnabled="{Binding OpenDeviceSaveDirectoryEnabled}"
+ ToolTip.Tip="{locale:Locale GameListContextMenuOpenDeviceSaveDirectoryToolTip}" />
+ <MenuItem
+ Click="OpenBcatSaveDirectory_Click"
+ Header="{locale:Locale GameListContextMenuOpenBcatSaveDirectory}"
+ IsEnabled="{Binding OpenBcatSaveDirectoryEnabled}"
+ ToolTip.Tip="{locale:Locale GameListContextMenuOpenBcatSaveDirectoryToolTip}" />
+ <Separator />
+ <MenuItem
+ Click="OpenTitleUpdateManager_Click"
+ Header="{locale:Locale GameListContextMenuManageTitleUpdates}"
+ ToolTip.Tip="{locale:Locale GameListContextMenuManageTitleUpdatesToolTip}" />
+ <MenuItem
+ Click="OpenDownloadableContentManager_Click"
+ Header="{locale:Locale GameListContextMenuManageDlc}"
+ ToolTip.Tip="{locale:Locale GameListContextMenuManageDlcToolTip}" />
+ <MenuItem
+ Click="OpenCheatManager_Click"
+ Header="{locale:Locale GameListContextMenuManageCheat}"
+ ToolTip.Tip="{locale:Locale GameListContextMenuManageCheatToolTip}" />
+ <MenuItem
+ Click="OpenModsDirectory_Click"
+ Header="{locale:Locale GameListContextMenuOpenModsDirectory}"
+ ToolTip.Tip="{locale:Locale GameListContextMenuOpenModsDirectoryToolTip}" />
+ <MenuItem
+ Click="OpenSdModsDirectory_Click"
+ Header="{locale:Locale GameListContextMenuOpenSdModsDirectory}"
+ ToolTip.Tip="{locale:Locale GameListContextMenuOpenSdModsDirectoryToolTip}" />
+ <Separator />
+ <MenuItem Header="{locale:Locale GameListContextMenuCacheManagement}">
+ <MenuItem
+ Click="PurgePtcCache_Click"
+ Header="{locale:Locale GameListContextMenuCacheManagementPurgePptc}"
+ ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementPurgePptcToolTip}" />
+ <MenuItem
+ Click="PurgeShaderCache_Click"
+ Header="{locale:Locale GameListContextMenuCacheManagementPurgeShaderCache}"
+ ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementPurgeShaderCacheToolTip}" />
+ <MenuItem
+ Click="OpenPtcDirectory_Click"
+ Header="{locale:Locale GameListContextMenuCacheManagementOpenPptcDirectory}"
+ ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementOpenPptcDirectoryToolTip}" />
+ <MenuItem
+ Click="OpenShaderCacheDirectory_Click"
+ Header="{locale:Locale GameListContextMenuCacheManagementOpenShaderCacheDirectory}"
+ ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip}" />
+ </MenuItem>
+ <MenuItem Header="{locale:Locale GameListContextMenuExtractData}">
+ <MenuItem
+ Click="ExtractApplicationLogo_Click"
+ Header="{locale:Locale GameListContextMenuExtractDataExeFS}"
+ ToolTip.Tip="{locale:Locale GameListContextMenuExtractDataExeFSToolTip}" />
+ <MenuItem
+ Click="ExtractApplicationRomFs_Click"
+ Header="{locale:Locale GameListContextMenuExtractDataRomFS}"
+ ToolTip.Tip="{locale:Locale GameListContextMenuExtractDataRomFSToolTip}" />
+ <MenuItem
+ Click="ExtractApplicationExeFs_Click"
+ Header="{locale:Locale GameListContextMenuExtractDataLogo}"
+ ToolTip.Tip="{locale:Locale GameListContextMenuExtractDataLogoToolTip}" />
+ </MenuItem>
+</MenuFlyout> \ No newline at end of file
diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs b/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs
new file mode 100644
index 00000000..dc0dee2a
--- /dev/null
+++ b/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs
@@ -0,0 +1,320 @@
+using Avalonia.Controls;
+using Avalonia.Interactivity;
+using Avalonia.Markup.Xaml;
+using Avalonia.Threading;
+using LibHac.Fs;
+using LibHac.Tools.FsSystem.NcaUtils;
+using Ryujinx.Ava.Common;
+using Ryujinx.Ava.Common.Locale;
+using Ryujinx.Ava.UI.Helpers;
+using Ryujinx.Ava.UI.ViewModels;
+using Ryujinx.Ava.UI.Windows;
+using Ryujinx.Common.Configuration;
+using Ryujinx.Ui.Common.Helper;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using Path = System.IO.Path;
+using UserId = LibHac.Fs.UserId;
+
+namespace Ryujinx.Ava.UI.Controls
+{
+ public class ApplicationContextMenu : MenuFlyout
+ {
+ public ApplicationContextMenu()
+ {
+ InitializeComponent();
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+
+ public void ToggleFavorite_Click(object sender, RoutedEventArgs args)
+ {
+ var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
+
+ if (viewModel.SelectedApplication != null)
+ {
+ viewModel.SelectedApplication.Favorite = !viewModel.SelectedApplication.Favorite;
+
+ viewModel.ApplicationLibrary.LoadAndSaveMetaData(viewModel.SelectedApplication.TitleId, appMetadata =>
+ {
+ appMetadata.Favorite = viewModel.SelectedApplication.Favorite;
+ });
+
+ viewModel.RefreshView();
+ }
+ }
+
+ public void OpenUserSaveDirectory_Click(object sender, RoutedEventArgs args)
+ {
+ var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
+
+ OpenSaveDirectory(viewModel, SaveDataType.Account, userId: new UserId((ulong)viewModel.AccountManager.LastOpenedUser.UserId.High, (ulong)viewModel.AccountManager.LastOpenedUser.UserId.Low));
+ }
+
+ public void OpenDeviceSaveDirectory_Click(object sender, RoutedEventArgs args)
+ {
+ var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
+
+ OpenSaveDirectory(viewModel, SaveDataType.Device, userId: default);
+ }
+
+ public void OpenBcatSaveDirectory_Click(object sender, RoutedEventArgs args)
+ {
+ var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
+
+ OpenSaveDirectory(viewModel, SaveDataType.Bcat, userId: default);
+ }
+
+ private void OpenSaveDirectory(MainWindowViewModel viewModel, SaveDataType saveDataType, UserId userId)
+ {
+ if (viewModel.SelectedApplication != null)
+ {
+ if (!ulong.TryParse(viewModel.SelectedApplication.TitleId, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out ulong titleIdNumber))
+ {
+ Dispatcher.UIThread.InvokeAsync(async () =>
+ {
+ await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogRyujinxErrorMessage], LocaleManager.Instance[LocaleKeys.DialogInvalidTitleIdErrorMessage]);
+ });
+
+ return;
+ }
+
+ var saveDataFilter = SaveDataFilter.Make(titleIdNumber, saveDataType, userId, saveDataId: default, index: default);
+
+ ApplicationHelper.OpenSaveDir(in saveDataFilter, titleIdNumber, viewModel.SelectedApplication.ControlHolder, viewModel.SelectedApplication.TitleName);
+ }
+ }
+
+ public async void OpenTitleUpdateManager_Click(object sender, RoutedEventArgs args)
+ {
+ var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
+
+ if (viewModel.SelectedApplication != null)
+ {
+ await TitleUpdateWindow.Show(viewModel.VirtualFileSystem, ulong.Parse(viewModel.SelectedApplication.TitleId, NumberStyles.HexNumber), viewModel.SelectedApplication.TitleName);
+ }
+ }
+
+ public async void OpenDownloadableContentManager_Click(object sender, RoutedEventArgs args)
+ {
+ var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
+
+ if (viewModel.SelectedApplication != null)
+ {
+ await DownloadableContentManagerWindow.Show(viewModel.VirtualFileSystem, ulong.Parse(viewModel.SelectedApplication.TitleId, NumberStyles.HexNumber), viewModel.SelectedApplication.TitleName);
+ }
+ }
+
+ public async void OpenCheatManager_Click(object sender, RoutedEventArgs args)
+ {
+ var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
+
+ if (viewModel.SelectedApplication != null)
+ {
+ await new CheatWindow(viewModel.VirtualFileSystem, viewModel.SelectedApplication.TitleId, viewModel.SelectedApplication.TitleName).ShowDialog(viewModel.TopLevel as Window);
+ }
+ }
+
+ public void OpenModsDirectory_Click(object sender, RoutedEventArgs args)
+ {
+ var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
+
+ if (viewModel.SelectedApplication != null)
+ {
+ string modsBasePath = viewModel.VirtualFileSystem.ModLoader.GetModsBasePath();
+ string titleModsPath = viewModel.VirtualFileSystem.ModLoader.GetTitleDir(modsBasePath, viewModel.SelectedApplication.TitleId);
+
+ OpenHelper.OpenFolder(titleModsPath);
+ }
+ }
+
+ public void OpenSdModsDirectory_Click(object sender, RoutedEventArgs args)
+ {
+ var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
+
+ if (viewModel.SelectedApplication != null)
+ {
+ string sdModsBasePath = viewModel.VirtualFileSystem.ModLoader.GetSdModsBasePath();
+ string titleModsPath = viewModel.VirtualFileSystem.ModLoader.GetTitleDir(sdModsBasePath, viewModel.SelectedApplication.TitleId);
+
+ OpenHelper.OpenFolder(titleModsPath);
+ }
+ }
+
+ public async void PurgePtcCache_Click(object sender, RoutedEventArgs args)
+ {
+ var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
+
+ if (viewModel.SelectedApplication != null)
+ {
+ UserResult result = await ContentDialogHelper.CreateConfirmationDialog(LocaleManager.Instance[LocaleKeys.DialogWarning],
+ LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCDeletionMessage, viewModel.SelectedApplication.TitleName),
+ LocaleManager.Instance[LocaleKeys.InputDialogYes],
+ LocaleManager.Instance[LocaleKeys.InputDialogNo],
+ LocaleManager.Instance[LocaleKeys.RyujinxConfirm]);
+
+ if (result == UserResult.Yes)
+ {
+ DirectoryInfo mainDir = new(Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.TitleId, "cache", "cpu", "0"));
+ DirectoryInfo backupDir = new(Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.TitleId, "cache", "cpu", "1"));
+
+ List<FileInfo> cacheFiles = new();
+
+ if (mainDir.Exists)
+ {
+ cacheFiles.AddRange(mainDir.EnumerateFiles("*.cache"));
+ }
+
+ if (backupDir.Exists)
+ {
+ cacheFiles.AddRange(backupDir.EnumerateFiles("*.cache"));
+ }
+
+ if (cacheFiles.Count > 0)
+ {
+ foreach (FileInfo file in cacheFiles)
+ {
+ try
+ {
+ file.Delete();
+ }
+ catch (Exception ex)
+ {
+ await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCDeletionErrorMessage, file.Name, ex));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public async void PurgeShaderCache_Click(object sender, RoutedEventArgs args)
+ {
+ var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
+
+ if (viewModel.SelectedApplication != null)
+ {
+ UserResult result = await ContentDialogHelper.CreateConfirmationDialog(LocaleManager.Instance[LocaleKeys.DialogWarning],
+ LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogShaderDeletionMessage, viewModel.SelectedApplication.TitleName),
+ LocaleManager.Instance[LocaleKeys.InputDialogYes],
+ LocaleManager.Instance[LocaleKeys.InputDialogNo],
+ LocaleManager.Instance[LocaleKeys.RyujinxConfirm]);
+
+ if (result == UserResult.Yes)
+ {
+ DirectoryInfo shaderCacheDir = new(Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.TitleId, "cache", "shader"));
+
+ List<DirectoryInfo> oldCacheDirectories = new();
+ List<FileInfo> newCacheFiles = new();
+
+ if (shaderCacheDir.Exists)
+ {
+ oldCacheDirectories.AddRange(shaderCacheDir.EnumerateDirectories("*"));
+ newCacheFiles.AddRange(shaderCacheDir.GetFiles("*.toc"));
+ newCacheFiles.AddRange(shaderCacheDir.GetFiles("*.data"));
+ }
+
+ if ((oldCacheDirectories.Count > 0 || newCacheFiles.Count > 0))
+ {
+ foreach (DirectoryInfo directory in oldCacheDirectories)
+ {
+ try
+ {
+ directory.Delete(true);
+ }
+ catch (Exception ex)
+ {
+ await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCDeletionErrorMessage, directory.Name, ex));
+ }
+ }
+
+ foreach (FileInfo file in newCacheFiles)
+ {
+ try
+ {
+ file.Delete();
+ }
+ catch (Exception ex)
+ {
+ await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.ShaderCachePurgeError, file.Name, ex));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public void OpenPtcDirectory_Click(object sender, RoutedEventArgs args)
+ {
+ var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
+
+ if (viewModel.SelectedApplication != null)
+ {
+ string ptcDir = Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.TitleId, "cache", "cpu");
+ string mainDir = Path.Combine(ptcDir, "0");
+ string backupDir = Path.Combine(ptcDir, "1");
+
+ if (!Directory.Exists(ptcDir))
+ {
+ Directory.CreateDirectory(ptcDir);
+ Directory.CreateDirectory(mainDir);
+ Directory.CreateDirectory(backupDir);
+ }
+
+ OpenHelper.OpenFolder(ptcDir);
+ }
+ }
+
+ public void OpenShaderCacheDirectory_Click(object sender, RoutedEventArgs args)
+ {
+ var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
+
+ if (viewModel.SelectedApplication != null)
+ {
+ string shaderCacheDir = Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.TitleId, "cache", "shader");
+
+ if (!Directory.Exists(shaderCacheDir))
+ {
+ Directory.CreateDirectory(shaderCacheDir);
+ }
+
+ OpenHelper.OpenFolder(shaderCacheDir);
+ }
+ }
+
+ public async void ExtractApplicationLogo_Click(object sender, RoutedEventArgs args)
+ {
+ var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
+
+ if (viewModel.SelectedApplication != null)
+ {
+ await ApplicationHelper.ExtractSection(NcaSectionType.Logo, viewModel.SelectedApplication.Path, viewModel.SelectedApplication.TitleName);
+ }
+ }
+
+ public async void ExtractApplicationRomFs_Click(object sender, RoutedEventArgs args)
+ {
+ var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
+
+ if (viewModel.SelectedApplication != null)
+ {
+ await ApplicationHelper.ExtractSection(NcaSectionType.Data, viewModel.SelectedApplication.Path, viewModel.SelectedApplication.TitleName);
+ }
+ }
+
+ public async void ExtractApplicationExeFs_Click(object sender, RoutedEventArgs args)
+ {
+ var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
+
+ if (viewModel.SelectedApplication != null)
+ {
+ await ApplicationHelper.ExtractSection(NcaSectionType.Code, viewModel.SelectedApplication.Path, viewModel.SelectedApplication.TitleName);
+ }
+ }
+ }
+}
diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml b/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml
new file mode 100644
index 00000000..f7a120b1
--- /dev/null
+++ b/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml
@@ -0,0 +1,102 @@
+<UserControl
+ x:Class="Ryujinx.Ava.UI.Controls.ApplicationGridView"
+ xmlns="https://github.com/avaloniaui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:flex="clr-namespace:Avalonia.Flexbox;assembly=Avalonia.Flexbox"
+ xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
+ d:DesignHeight="450"
+ d:DesignWidth="800"
+ Focusable="True"
+ mc:Ignorable="d">
+ <UserControl.Resources>
+ <helpers:BitmapArrayValueConverter x:Key="ByteImage" />
+ <controls:ApplicationContextMenu x:Key="ApplicationContextMenu" />
+ </UserControl.Resources>
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="*" />
+ </Grid.RowDefinitions>
+ <ListBox
+ Grid.Row="0"
+ Padding="8"
+ HorizontalAlignment="Stretch"
+ VerticalAlignment="Stretch"
+ ContextFlyout="{StaticResource ApplicationContextMenu}"
+ DoubleTapped="GameList_DoubleTapped"
+ Items="{Binding AppsObservableList}"
+ SelectionChanged="GameList_SelectionChanged">
+ <ListBox.ItemsPanel>
+ <ItemsPanelTemplate>
+ <flex:FlexPanel
+ HorizontalAlignment="Stretch"
+ VerticalAlignment="Stretch"
+ AlignContent="FlexStart"
+ JustifyContent="Center" />
+ </ItemsPanelTemplate>
+ </ListBox.ItemsPanel>
+ <ListBox.Styles>
+ <Style Selector="ListBoxItem">
+ <Setter Property="Margin" Value="5" />
+ <Setter Property="CornerRadius" Value="4" />
+ </Style>
+ <Style Selector="ListBoxItem:selected /template/ Border#SelectionIndicator">
+ <Setter Property="MinHeight" Value="{Binding $parent[UserControl].DataContext.GridItemSelectorSize}" />
+ </Style>
+ </ListBox.Styles>
+ <ListBox.ItemTemplate>
+ <DataTemplate>
+ <Grid>
+ <Border
+ Margin="10"
+ HorizontalAlignment="Stretch"
+ VerticalAlignment="Stretch"
+ Classes.huge="{Binding $parent[UserControl].DataContext.IsGridHuge}"
+ Classes.large="{Binding $parent[UserControl].DataContext.IsGridLarge}"
+ Classes.normal="{Binding $parent[UserControl].DataContext.IsGridMedium}"
+ Classes.small="{Binding $parent[UserControl].DataContext.IsGridSmall}"
+ ClipToBounds="True"
+ CornerRadius="4">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <Image
+ Grid.Row="0"
+ HorizontalAlignment="Stretch"
+ VerticalAlignment="Top"
+ Source="{Binding Icon, Converter={StaticResource ByteImage}}" />
+ <Panel
+ Grid.Row="1"
+ Height="50"
+ Margin="0,10,0,0"
+ HorizontalAlignment="Stretch"
+ VerticalAlignment="Stretch"
+ IsVisible="{Binding $parent[UserControl].DataContext.ShowNames}">
+ <TextBlock
+ HorizontalAlignment="Stretch"
+ VerticalAlignment="Center"
+ Text="{Binding TitleName}"
+ TextAlignment="Center"
+ TextWrapping="Wrap" />
+ </Panel>
+ </Grid>
+ </Border>
+ <ui:SymbolIcon
+ Margin="5,5,0,0"
+ HorizontalAlignment="Left"
+ VerticalAlignment="Top"
+ FontSize="16"
+ Foreground="{DynamicResource SystemAccentColor}"
+ IsVisible="{Binding Favorite}"
+ Symbol="StarFilled" />
+ </Grid>
+ </DataTemplate>
+ </ListBox.ItemTemplate>
+ </ListBox>
+ </Grid>
+</UserControl> \ No newline at end of file
diff --git a/src/Ryujinx.Ava/UI/Controls/GameGridView.axaml.cs b/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs
index aa76b7c9..c30c75b3 100644
--- a/src/Ryujinx.Ava/UI/Controls/GameGridView.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs
@@ -9,10 +9,10 @@ using System;
namespace Ryujinx.Ava.UI.Controls
{
- public partial class GameGridView : UserControl
+ public partial class ApplicationGridView : UserControl
{
public static readonly RoutedEvent<ApplicationOpenedEventArgs> ApplicationOpenedEvent =
- RoutedEvent.Register<GameGridView, ApplicationOpenedEventArgs>(nameof(ApplicationOpened), RoutingStrategies.Bubble);
+ RoutedEvent.Register<ApplicationGridView, ApplicationOpenedEventArgs>(nameof(ApplicationOpened), RoutingStrategies.Bubble);
public event EventHandler<ApplicationOpenedEventArgs> ApplicationOpened
{
@@ -20,7 +20,7 @@ namespace Ryujinx.Ava.UI.Controls
remove { RemoveHandler(ApplicationOpenedEvent, value); }
}
- public GameGridView()
+ public ApplicationGridView()
{
InitializeComponent();
}
@@ -49,7 +49,7 @@ namespace Ryujinx.Ava.UI.Controls
}
}
- private void SearchBox_OnKeyUp(object sender, KeyEventArgs e)
+ private void SearchBox_OnKeyUp(object sender, KeyEventArgs args)
{
(DataContext as MainWindowViewModel).SearchText = (sender as TextBox).Text;
}
diff --git a/src/Ryujinx.Ava/UI/Controls/GameListView.axaml b/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml
index c13eaae8..fa8ebf62 100644
--- a/src/Ryujinx.Ava/UI/Controls/GameListView.axaml
+++ b/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml
@@ -1,10 +1,10 @@
<UserControl
- x:Class="Ryujinx.Ava.UI.Controls.GameListView"
+ x:Class="Ryujinx.Ava.UI.Controls.ApplicationListView"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
d:DesignHeight="450"
@@ -13,82 +13,7 @@
mc:Ignorable="d">
<UserControl.Resources>
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
- <MenuFlyout x:Key="GameContextMenu">
- <MenuItem
- Command="{Binding ToggleFavorite}"
- Header="{locale:Locale GameListContextMenuToggleFavorite}"
- ToolTip.Tip="{locale:Locale GameListContextMenuToggleFavoriteToolTip}" />
- <Separator />
- <MenuItem
- Command="{Binding OpenUserSaveDirectory}"
- IsEnabled="{Binding EnabledUserSaveDirectory}"
- Header="{locale:Locale GameListContextMenuOpenUserSaveDirectory}"
- ToolTip.Tip="{locale:Locale GameListContextMenuOpenUserSaveDirectoryToolTip}" />
- <MenuItem
- Command="{Binding OpenDeviceSaveDirectory}"
- IsEnabled="{Binding EnabledDeviceSaveDirectory}"
- Header="{locale:Locale GameListContextMenuOpenDeviceSaveDirectory}"
- ToolTip.Tip="{locale:Locale GameListContextMenuOpenDeviceSaveDirectoryToolTip}" />
- <MenuItem
- Command="{Binding OpenBcatSaveDirectory}"
- IsEnabled="{Binding EnabledBcatSaveDirectory}"
- Header="{locale:Locale GameListContextMenuOpenBcatSaveDirectory}"
- ToolTip.Tip="{locale:Locale GameListContextMenuOpenBcatSaveDirectoryToolTip}" />
- <Separator />
- <MenuItem
- Command="{Binding OpenTitleUpdateManager}"
- Header="{locale:Locale GameListContextMenuManageTitleUpdates}"
- ToolTip.Tip="{locale:Locale GameListContextMenuManageTitleUpdatesToolTip}" />
- <MenuItem
- Command="{Binding OpenDownloadableContentManager}"
- Header="{locale:Locale GameListContextMenuManageDlc}"
- ToolTip.Tip="{locale:Locale GameListContextMenuManageDlcToolTip}" />
- <MenuItem
- Command="{Binding OpenCheatManager}"
- Header="{locale:Locale GameListContextMenuManageCheat}"
- ToolTip.Tip="{locale:Locale GameListContextMenuManageCheatToolTip}" />
- <MenuItem
- Command="{Binding OpenModsDirectory}"
- Header="{locale:Locale GameListContextMenuOpenModsDirectory}"
- ToolTip.Tip="{locale:Locale GameListContextMenuOpenModsDirectoryToolTip}" />
- <MenuItem
- Command="{Binding OpenSdModsDirectory}"
- Header="{locale:Locale GameListContextMenuOpenSdModsDirectory}"
- ToolTip.Tip="{locale:Locale GameListContextMenuOpenSdModsDirectoryToolTip}" />
- <Separator />
- <MenuItem Header="{locale:Locale GameListContextMenuCacheManagement}">
- <MenuItem
- Command="{Binding PurgePtcCache}"
- Header="{locale:Locale GameListContextMenuCacheManagementPurgePptc}"
- ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementPurgePptcToolTip}" />
- <MenuItem
- Command="{Binding PurgeShaderCache}"
- Header="{locale:Locale GameListContextMenuCacheManagementPurgeShaderCache}"
- ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementPurgeShaderCacheToolTip}" />
- <MenuItem
- Command="{Binding OpenPtcDirectory}"
- Header="{locale:Locale GameListContextMenuCacheManagementOpenPptcDirectory}"
- ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementOpenPptcDirectoryToolTip}" />
- <MenuItem
- Command="{Binding OpenShaderCacheDirectory}"
- Header="{locale:Locale GameListContextMenuCacheManagementOpenShaderCacheDirectory}"
- ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip}" />
- </MenuItem>
- <MenuItem Header="{locale:Locale GameListContextMenuExtractData}">
- <MenuItem
- Command="{Binding ExtractExeFs}"
- Header="{locale:Locale GameListContextMenuExtractDataExeFS}"
- ToolTip.Tip="{locale:Locale GameListContextMenuExtractDataExeFSToolTip}" />
- <MenuItem
- Command="{Binding ExtractRomFs}"
- Header="{locale:Locale GameListContextMenuExtractDataRomFS}"
- ToolTip.Tip="{locale:Locale GameListContextMenuExtractDataRomFSToolTip}" />
- <MenuItem
- Command="{Binding ExtractLogo}"
- Header="{locale:Locale GameListContextMenuExtractDataLogo}"
- ToolTip.Tip="{locale:Locale GameListContextMenuExtractDataLogoToolTip}" />
- </MenuItem>
- </MenuFlyout>
+ <controls:ApplicationContextMenu x:Key="ApplicationContextMenu" />
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
@@ -100,7 +25,7 @@
Padding="8"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
- ContextFlyout="{StaticResource GameContextMenu}"
+ ContextFlyout="{StaticResource ApplicationContextMenu}"
DoubleTapped="GameList_DoubleTapped"
Items="{Binding AppsObservableList}"
SelectionChanged="GameList_SelectionChanged">
diff --git a/src/Ryujinx.Ava/UI/Controls/GameListView.axaml.cs b/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs
index a6449709..1a07c425 100644
--- a/src/Ryujinx.Ava/UI/Controls/GameListView.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs
@@ -9,10 +9,10 @@ using System;
namespace Ryujinx.Ava.UI.Controls
{
- public partial class GameListView : UserControl
+ public partial class ApplicationListView : UserControl
{
public static readonly RoutedEvent<ApplicationOpenedEventArgs> ApplicationOpenedEvent =
- RoutedEvent.Register<GameGridView, ApplicationOpenedEventArgs>(nameof(ApplicationOpened), RoutingStrategies.Bubble);
+ RoutedEvent.Register<ApplicationListView, ApplicationOpenedEventArgs>(nameof(ApplicationOpened), RoutingStrategies.Bubble);
public event EventHandler<ApplicationOpenedEventArgs> ApplicationOpened
{
@@ -20,7 +20,7 @@ namespace Ryujinx.Ava.UI.Controls
remove { RemoveHandler(ApplicationOpenedEvent, value); }
}
- public GameListView()
+ public ApplicationListView()
{
InitializeComponent();
}
@@ -49,7 +49,7 @@ namespace Ryujinx.Ava.UI.Controls
}
}
- private void SearchBox_OnKeyUp(object sender, KeyEventArgs e)
+ private void SearchBox_OnKeyUp(object sender, KeyEventArgs args)
{
(DataContext as MainWindowViewModel).SearchText = (sender as TextBox).Text;
}
diff --git a/src/Ryujinx.Ava/UI/Controls/GameGridView.axaml b/src/Ryujinx.Ava/UI/Controls/GameGridView.axaml
deleted file mode 100644
index 32cabfaa..00000000
--- a/src/Ryujinx.Ava/UI/Controls/GameGridView.axaml
+++ /dev/null
@@ -1,177 +0,0 @@
-<UserControl
- x:Class="Ryujinx.Ava.UI.Controls.GameGridView"
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:flex="clr-namespace:Avalonia.Flexbox;assembly=Avalonia.Flexbox"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
- xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
- d:DesignHeight="450"
- d:DesignWidth="800"
- mc:Ignorable="d"
- Focusable="True">
- <UserControl.Resources>
- <helpers:BitmapArrayValueConverter x:Key="ByteImage" />
- <MenuFlyout x:Key="GameContextMenu">
- <MenuItem
- Command="{Binding ToggleFavorite}"
- Header="{locale:Locale GameListContextMenuToggleFavorite}"
- ToolTip.Tip="{locale:Locale GameListContextMenuToggleFavoriteToolTip}" />
- <Separator />
- <MenuItem
- Command="{Binding OpenUserSaveDirectory}"
- IsEnabled="{Binding EnabledUserSaveDirectory}"
- Header="{locale:Locale GameListContextMenuOpenUserSaveDirectory}"
- ToolTip.Tip="{locale:Locale GameListContextMenuOpenUserSaveDirectoryToolTip}" />
- <MenuItem
- Command="{Binding OpenDeviceSaveDirectory}"
- IsEnabled="{Binding EnabledDeviceSaveDirectory}"
- Header="{locale:Locale GameListContextMenuOpenDeviceSaveDirectory}"
- ToolTip.Tip="{locale:Locale GameListContextMenuOpenDeviceSaveDirectoryToolTip}" />
- <MenuItem
- Command="{Binding OpenBcatSaveDirectory}"
- IsEnabled="{Binding EnabledBcatSaveDirectory}"
- Header="{locale:Locale GameListContextMenuOpenBcatSaveDirectory}"
- ToolTip.Tip="{locale:Locale GameListContextMenuOpenBcatSaveDirectoryToolTip}" />
- <Separator />
- <MenuItem
- Command="{Binding OpenTitleUpdateManager}"
- Header="{locale:Locale GameListContextMenuManageTitleUpdates}"
- ToolTip.Tip="{locale:Locale GameListContextMenuManageTitleUpdatesToolTip}" />
- <MenuItem
- Command="{Binding OpenDownloadableContentManager}"
- Header="{locale:Locale GameListContextMenuManageDlc}"
- ToolTip.Tip="{locale:Locale GameListContextMenuManageDlcToolTip}" />
- <MenuItem
- Command="{Binding OpenCheatManager}"
- Header="{locale:Locale GameListContextMenuManageCheat}"
- ToolTip.Tip="{locale:Locale GameListContextMenuManageCheatToolTip}" />
- <MenuItem
- Command="{Binding OpenModsDirectory}"
- Header="{locale:Locale GameListContextMenuOpenModsDirectory}"
- ToolTip.Tip="{locale:Locale GameListContextMenuOpenModsDirectoryToolTip}" />
- <MenuItem
- Command="{Binding OpenSdModsDirectory}"
- Header="{locale:Locale GameListContextMenuOpenSdModsDirectory}"
- ToolTip.Tip="{locale:Locale GameListContextMenuOpenSdModsDirectoryToolTip}" />
- <Separator />
- <MenuItem Header="{locale:Locale GameListContextMenuCacheManagement}">
- <MenuItem
- Command="{Binding PurgePtcCache}"
- Header="{locale:Locale GameListContextMenuCacheManagementPurgePptc}"
- ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementPurgePptcToolTip}" />
- <MenuItem
- Command="{Binding PurgeShaderCache}"
- Header="{locale:Locale GameListContextMenuCacheManagementPurgeShaderCache}"
- ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementPurgeShaderCacheToolTip}" />
- <MenuItem
- Command="{Binding OpenPtcDirectory}"
- Header="{locale:Locale GameListContextMenuCacheManagementOpenPptcDirectory}"
- ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementOpenPptcDirectoryToolTip}" />
- <MenuItem
- Command="{Binding OpenShaderCacheDirectory}"
- Header="{locale:Locale GameListContextMenuCacheManagementOpenShaderCacheDirectory}"
- ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip}" />
- </MenuItem>
- <MenuItem Header="{locale:Locale GameListContextMenuExtractData}">
- <MenuItem
- Command="{Binding ExtractExeFs}"
- Header="{locale:Locale GameListContextMenuExtractDataExeFS}"
- ToolTip.Tip="{locale:Locale GameListContextMenuExtractDataExeFSToolTip}" />
- <MenuItem
- Command="{Binding ExtractRomFs}"
- Header="{locale:Locale GameListContextMenuExtractDataRomFS}"
- ToolTip.Tip="{locale:Locale GameListContextMenuExtractDataRomFSToolTip}" />
- <MenuItem
- Command="{Binding ExtractLogo}"
- Header="{locale:Locale GameListContextMenuExtractDataLogo}"
- ToolTip.Tip="{locale:Locale GameListContextMenuExtractDataLogoToolTip}" />
- </MenuItem>
- </MenuFlyout>
- </UserControl.Resources>
- <Grid>
- <Grid.RowDefinitions>
- <RowDefinition Height="*" />
- </Grid.RowDefinitions>
- <ListBox
- Grid.Row="0"
- Padding="8"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- ContextFlyout="{StaticResource GameContextMenu}"
- DoubleTapped="GameList_DoubleTapped"
- Items="{Binding AppsObservableList}"
- SelectionChanged="GameList_SelectionChanged">
- <ListBox.ItemsPanel>
- <ItemsPanelTemplate>
- <flex:FlexPanel
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- AlignContent="FlexStart"
- JustifyContent="Center" />
- </ItemsPanelTemplate>
- </ListBox.ItemsPanel>
- <ListBox.Styles>
- <Style Selector="ListBoxItem">
- <Setter Property="Margin" Value="5" />
- <Setter Property="CornerRadius" Value="4" />
- </Style>
- <Style Selector="ListBoxItem:selected /template/ Border#SelectionIndicator">
- <Setter Property="MinHeight" Value="{Binding $parent[UserControl].DataContext.GridItemSelectorSize}" />
- </Style>
- </ListBox.Styles>
- <ListBox.ItemTemplate>
- <DataTemplate>
- <Grid>
- <Border
- Margin="10"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- Classes.huge="{Binding $parent[UserControl].DataContext.IsGridHuge}"
- Classes.large="{Binding $parent[UserControl].DataContext.IsGridLarge}"
- Classes.normal="{Binding $parent[UserControl].DataContext.IsGridMedium}"
- Classes.small="{Binding $parent[UserControl].DataContext.IsGridSmall}"
- ClipToBounds="True"
- CornerRadius="4">
- <Grid>
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <Image
- Grid.Row="0"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Top"
- Source="{Binding Icon, Converter={StaticResource ByteImage}}" />
- <Panel
- Grid.Row="1"
- Height="50"
- Margin="0 10 0 0"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- IsVisible="{Binding $parent[UserControl].DataContext.ShowNames}">
- <TextBlock
- HorizontalAlignment="Stretch"
- VerticalAlignment="Center"
- Text="{Binding TitleName}"
- TextAlignment="Center"
- TextWrapping="Wrap" />
- </Panel>
- </Grid>
- </Border>
- <ui:SymbolIcon
- Margin="5,5,0,0"
- HorizontalAlignment="Left"
- VerticalAlignment="Top"
- FontSize="16"
- Foreground="{DynamicResource SystemAccentColor}"
- IsVisible="{Binding Favorite}"
- Symbol="StarFilled" />
- </Grid>
- </DataTemplate>
- </ListBox.ItemTemplate>
- </ListBox>
- </Grid>
-</UserControl> \ No newline at end of file
diff --git a/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs
index f4556bc3..b5c82d65 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs
+++ b/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs
@@ -6,8 +6,6 @@ using Avalonia.Threading;
using DynamicData;
using DynamicData.Binding;
using LibHac.Common;
-using LibHac.Fs;
-using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Ava.Common;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Input;
@@ -33,13 +31,11 @@ using SixLabors.ImageSharp.PixelFormats;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
-using System.Globalization;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Path = System.IO.Path;
using ShaderCacheLoadingState = Ryujinx.Graphics.Gpu.Shader.ShaderCacheState;
-using UserId = LibHac.Fs.UserId;
namespace Ryujinx.Ava.UI.ViewModels
{
@@ -346,11 +342,11 @@ namespace Ryujinx.Ava.UI.ViewModels
}
}
- public bool EnabledUserSaveDirectory => !Utilities.IsZeros(SelectedApplication.ControlHolder.ByteSpan) && SelectedApplication.ControlHolder.Value.UserAccountSaveDataSize > 0;
+ public bool OpenUserSaveDirectoryEnabled => !Utilities.IsZeros(SelectedApplication.ControlHolder.ByteSpan) && SelectedApplication.ControlHolder.Value.UserAccountSaveDataSize > 0;
- public bool EnabledDeviceSaveDirectory => !Utilities.IsZeros(SelectedApplication.ControlHolder.ByteSpan) && SelectedApplication.ControlHolder.Value.DeviceSaveDataSize > 0;
+ public bool OpenDeviceSaveDirectoryEnabled => !Utilities.IsZeros(SelectedApplication.ControlHolder.ByteSpan) && SelectedApplication.ControlHolder.Value.DeviceSaveDataSize > 0;
- public bool EnabledBcatSaveDirectory => !Utilities.IsZeros(SelectedApplication.ControlHolder.ByteSpan) && SelectedApplication.ControlHolder.Value.BcatDeliveryCacheStorageSize > 0;
+ public bool OpenBcatSaveDirectoryEnabled => !Utilities.IsZeros(SelectedApplication.ControlHolder.ByteSpan) && SelectedApplication.ControlHolder.Value.BcatDeliveryCacheStorageSize > 0;
public string LoadHeading
{
@@ -941,7 +937,7 @@ namespace Ryujinx.Ava.UI.ViewModels
};
}
- private void RefreshView()
+ public void RefreshView()
{
RefreshGrid();
}
@@ -1116,30 +1112,6 @@ namespace Ryujinx.Ava.UI.ViewModels
}));
}
- private async void ExtractLogo()
- {
- if (SelectedApplication != null)
- {
- await ApplicationHelper.ExtractSection(NcaSectionType.Logo, SelectedApplication.Path, SelectedApplication.TitleName);
- }
- }
-
- private async void ExtractRomFs()
- {
- if (SelectedApplication != null)
- {
- await ApplicationHelper.ExtractSection(NcaSectionType.Data, SelectedApplication.Path, SelectedApplication.TitleName);
- }
- }
-
- private async void ExtractExeFs()
- {
- if (SelectedApplication != null)
- {
- await ApplicationHelper.ExtractSection(NcaSectionType.Code, SelectedApplication.Path, SelectedApplication.TitleName);
- }
- }
-
private void PrepareLoadScreen()
{
using MemoryStream stream = new(SelectedIcon);
@@ -1383,241 +1355,11 @@ namespace Ryujinx.Ava.UI.ViewModels
await NavigationDialogHost.Show(AccountManager, ContentManager, VirtualFileSystem, LibHacHorizonManager.RyujinxClient);
}
- public void OpenPtcDirectory()
- {
- ApplicationData selection = SelectedApplication;
- if (selection != null)
- {
- string ptcDir = Path.Combine(AppDataManager.GamesDirPath, selection.TitleId, "cache", "cpu");
- string mainPath = Path.Combine(ptcDir, "0");
- string backupPath = Path.Combine(ptcDir, "1");
-
- if (!Directory.Exists(ptcDir))
- {
- Directory.CreateDirectory(ptcDir);
- Directory.CreateDirectory(mainPath);
- Directory.CreateDirectory(backupPath);
- }
-
- OpenHelper.OpenFolder(ptcDir);
- }
- }
-
- public async void PurgePtcCache()
- {
- ApplicationData selection = SelectedApplication;
- if (selection != null)
- {
- DirectoryInfo mainDir = new(Path.Combine(AppDataManager.GamesDirPath, selection.TitleId, "cache", "cpu", "0"));
- DirectoryInfo backupDir = new(Path.Combine(AppDataManager.GamesDirPath, selection.TitleId, "cache", "cpu", "1"));
-
- // FIXME: Found a way to reproduce the bold effect on the title name (fork?).
- UserResult result = await ContentDialogHelper.CreateConfirmationDialog(LocaleManager.Instance[LocaleKeys.DialogWarning],
- LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCDeletionMessage, selection.TitleName),
- LocaleManager.Instance[LocaleKeys.InputDialogYes],
- LocaleManager.Instance[LocaleKeys.InputDialogNo],
- LocaleManager.Instance[LocaleKeys.RyujinxConfirm]);
-
- List<FileInfo> cacheFiles = new();
-
- if (mainDir.Exists)
- {
- cacheFiles.AddRange(mainDir.EnumerateFiles("*.cache"));
- }
-
- if (backupDir.Exists)
- {
- cacheFiles.AddRange(backupDir.EnumerateFiles("*.cache"));
- }
-
- if (cacheFiles.Count > 0 && result == UserResult.Yes)
- {
- foreach (FileInfo file in cacheFiles)
- {
- try
- {
- file.Delete();
- }
- catch (Exception e)
- {
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCDeletionErrorMessage, file.Name, e));
- }
- }
- }
- }
- }
-
- public void OpenShaderCacheDirectory()
- {
- ApplicationData selection = SelectedApplication;
- if (selection != null)
- {
- string shaderCacheDir = Path.Combine(AppDataManager.GamesDirPath, selection.TitleId, "cache", "shader");
-
- if (!Directory.Exists(shaderCacheDir))
- {
- Directory.CreateDirectory(shaderCacheDir);
- }
-
- OpenHelper.OpenFolder(shaderCacheDir);
- }
- }
-
public void SimulateWakeUpMessage()
{
AppHost.Device.System.SimulateWakeUpMessage();
}
- public async void PurgeShaderCache()
- {
- ApplicationData selection = SelectedApplication;
- if (selection != null)
- {
- DirectoryInfo shaderCacheDir = new(Path.Combine(AppDataManager.GamesDirPath, selection.TitleId, "cache", "shader"));
-
- // FIXME: Found a way to reproduce the bold effect on the title name (fork?).
- UserResult result = await ContentDialogHelper.CreateConfirmationDialog(LocaleManager.Instance[LocaleKeys.DialogWarning],
- LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogShaderDeletionMessage, selection.TitleName),
- LocaleManager.Instance[LocaleKeys.InputDialogYes],
- LocaleManager.Instance[LocaleKeys.InputDialogNo],
- LocaleManager.Instance[LocaleKeys.RyujinxConfirm]);
-
- List<DirectoryInfo> oldCacheDirectories = new();
- List<FileInfo> newCacheFiles = new();
-
- if (shaderCacheDir.Exists)
- {
- oldCacheDirectories.AddRange(shaderCacheDir.EnumerateDirectories("*"));
- newCacheFiles.AddRange(shaderCacheDir.GetFiles("*.toc"));
- newCacheFiles.AddRange(shaderCacheDir.GetFiles("*.data"));
- }
-
- if ((oldCacheDirectories.Count > 0 || newCacheFiles.Count > 0) && result == UserResult.Yes)
- {
- foreach (DirectoryInfo directory in oldCacheDirectories)
- {
- try
- {
- directory.Delete(true);
- }
- catch (Exception e)
- {
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCDeletionErrorMessage, directory.Name, e));
- }
- }
- }
-
- foreach (FileInfo file in newCacheFiles)
- {
- try
- {
- file.Delete();
- }
- catch (Exception e)
- {
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.ShaderCachePurgeError, file.Name, e));
- }
- }
- }
- }
-
- public void ToggleFavorite()
- {
- ApplicationData selection = SelectedApplication;
- if (selection != null)
- {
- selection.Favorite = !selection.Favorite;
-
- ApplicationLibrary.LoadAndSaveMetaData(selection.TitleId, appMetadata =>
- {
- appMetadata.Favorite = selection.Favorite;
- });
-
- RefreshView();
- }
- }
-
- public void OpenUserSaveDirectory()
- {
- OpenSaveDirectory(SaveDataType.Account, userId: new UserId((ulong)AccountManager.LastOpenedUser.UserId.High, (ulong)AccountManager.LastOpenedUser.UserId.Low));
- }
-
- public void OpenDeviceSaveDirectory()
- {
- OpenSaveDirectory(SaveDataType.Device, userId: default);
- }
-
- public void OpenBcatSaveDirectory()
- {
- OpenSaveDirectory(SaveDataType.Bcat, userId: default);
- }
-
- private void OpenSaveDirectory(SaveDataType saveDataType, UserId userId)
- {
- if (SelectedApplication != null)
- {
- if (!ulong.TryParse(SelectedApplication.TitleId, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out ulong titleIdNumber))
- {
- Dispatcher.UIThread.InvokeAsync(async () =>
- {
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogRyujinxErrorMessage], LocaleManager.Instance[LocaleKeys.DialogInvalidTitleIdErrorMessage]);
- });
-
- return;
- }
-
- var saveDataFilter = SaveDataFilter.Make(titleIdNumber, saveDataType, userId, saveDataId: default, index: default);
-
- ApplicationHelper.OpenSaveDir(in saveDataFilter, titleIdNumber, SelectedApplication.ControlHolder, SelectedApplication.TitleName);
- }
- }
-
- public void OpenModsDirectory()
- {
- if (SelectedApplication != null)
- {
- string modsBasePath = VirtualFileSystem.ModLoader.GetModsBasePath();
- string titleModsPath = VirtualFileSystem.ModLoader.GetTitleDir(modsBasePath, SelectedApplication.TitleId);
-
- OpenHelper.OpenFolder(titleModsPath);
- }
- }
-
- public void OpenSdModsDirectory()
- {
- if (SelectedApplication != null)
- {
- string sdModsBasePath = VirtualFileSystem.ModLoader.GetSdModsBasePath();
- string titleModsPath = VirtualFileSystem.ModLoader.GetTitleDir(sdModsBasePath, SelectedApplication.TitleId);
-
- OpenHelper.OpenFolder(titleModsPath);
- }
- }
-
- public async void OpenTitleUpdateManager()
- {
- if (SelectedApplication != null)
- {
- await TitleUpdateWindow.Show(VirtualFileSystem, ulong.Parse(SelectedApplication.TitleId, NumberStyles.HexNumber), SelectedApplication.TitleName);
- }
- }
-
- public async void OpenDownloadableContentManager()
- {
- if (SelectedApplication != null)
- {
- await DownloadableContentManagerWindow.Show(VirtualFileSystem, ulong.Parse(SelectedApplication.TitleId, NumberStyles.HexNumber), SelectedApplication.TitleName);
- }
- }
-
- public async void OpenCheatManager()
- {
- if (SelectedApplication != null)
- {
- await new CheatWindow(VirtualFileSystem, SelectedApplication.TitleId, SelectedApplication.TitleName).ShowDialog(TopLevel as Window);
- }
- }
-
public async void LoadApplications()
{
await Dispatcher.UIThread.InvokeAsync(() =>
diff --git a/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml b/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml
index de01f90f..fa07d977 100644
--- a/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml
+++ b/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml
@@ -88,16 +88,16 @@
<main:MainViewControls
Name="ViewControls"
Grid.Row="0"/>
- <controls:GameListView
- x:Name="GameList"
+ <controls:ApplicationListView
+ x:Name="ApplicationList"
Grid.Row="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
IsVisible="{Binding IsList}" />
- <controls:GameGridView
- x:Name="GameGrid"
+ <controls:ApplicationGridView
+ x:Name="ApplicationGrid"
Grid.Row="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
diff --git a/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs b/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs
index 404d4ee0..eec77479 100644
--- a/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs
@@ -288,13 +288,13 @@ namespace Ryujinx.Ava.UI.Windows
{
StatusBarView.VolumeStatus.Click += VolumeStatus_CheckedChanged;
- GameGrid.ApplicationOpened += Application_Opened;
+ ApplicationGrid.ApplicationOpened += Application_Opened;
- GameGrid.DataContext = ViewModel;
+ ApplicationGrid.DataContext = ViewModel;
- GameList.ApplicationOpened += Application_Opened;
+ ApplicationList.ApplicationOpened += Application_Opened;
- GameList.DataContext = ViewModel;
+ ApplicationList.DataContext = ViewModel;
LoadHotKeys();
}