UI: Move ApplicationContextMenu in a separated class (#4755)
* 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
This commit is contained in:
parent
4250732353
commit
3b8ac1641a
11 changed files with 526 additions and 578 deletions
320
src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs
Normal file
320
src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue