From 3b8ac1641a8a40849915396813e26384b5894911 Mon Sep 17 00:00:00 2001 From: Ac_K Date: Thu, 4 May 2023 16:41:06 +0200 Subject: 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 --- .../UI/Controls/ApplicationContextMenu.axaml | 80 ++++++ .../UI/Controls/ApplicationContextMenu.axaml.cs | 320 +++++++++++++++++++++ .../UI/Controls/ApplicationGridView.axaml | 102 +++++++ .../UI/Controls/ApplicationGridView.axaml.cs | 57 ++++ .../UI/Controls/ApplicationListView.axaml | 158 ++++++++++ .../UI/Controls/ApplicationListView.axaml.cs | 57 ++++ src/Ryujinx.Ava/UI/Controls/GameGridView.axaml | 177 ------------ src/Ryujinx.Ava/UI/Controls/GameGridView.axaml.cs | 57 ---- src/Ryujinx.Ava/UI/Controls/GameListView.axaml | 233 --------------- src/Ryujinx.Ava/UI/Controls/GameListView.axaml.cs | 57 ---- 10 files changed, 774 insertions(+), 524 deletions(-) create mode 100644 src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml create mode 100644 src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs create mode 100644 src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml create mode 100644 src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs create mode 100644 src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml create mode 100644 src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs delete mode 100644 src/Ryujinx.Ava/UI/Controls/GameGridView.axaml delete mode 100644 src/Ryujinx.Ava/UI/Controls/GameGridView.axaml.cs delete mode 100644 src/Ryujinx.Ava/UI/Controls/GameListView.axaml delete mode 100644 src/Ryujinx.Ava/UI/Controls/GameListView.axaml.cs (limited to 'src/Ryujinx.Ava/UI/Controls') 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ 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 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 oldCacheDirectories = new(); + List 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs b/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs new file mode 100644 index 00000000..c30c75b3 --- /dev/null +++ b/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs @@ -0,0 +1,57 @@ +using Avalonia.Controls; +using Avalonia.Input; +using Avalonia.Interactivity; +using Avalonia.Markup.Xaml; +using Ryujinx.Ava.UI.Helpers; +using Ryujinx.Ava.UI.ViewModels; +using Ryujinx.Ui.App.Common; +using System; + +namespace Ryujinx.Ava.UI.Controls +{ + public partial class ApplicationGridView : UserControl + { + public static readonly RoutedEvent ApplicationOpenedEvent = + RoutedEvent.Register(nameof(ApplicationOpened), RoutingStrategies.Bubble); + + public event EventHandler ApplicationOpened + { + add { AddHandler(ApplicationOpenedEvent, value); } + remove { RemoveHandler(ApplicationOpenedEvent, value); } + } + + public ApplicationGridView() + { + InitializeComponent(); + } + + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + } + + public void GameList_DoubleTapped(object sender, RoutedEventArgs args) + { + if (sender is ListBox listBox) + { + if (listBox.SelectedItem is ApplicationData selected) + { + RaiseEvent(new ApplicationOpenedEventArgs(selected, ApplicationOpenedEvent)); + } + } + } + + public void GameList_SelectionChanged(object sender, SelectionChangedEventArgs args) + { + if (sender is ListBox listBox) + { + (DataContext as MainWindowViewModel).GridSelectedApplication = listBox.SelectedItem as ApplicationData; + } + } + + private void SearchBox_OnKeyUp(object sender, KeyEventArgs args) + { + (DataContext as MainWindowViewModel).SearchText = (sender as TextBox).Text; + } + } +} diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml b/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml new file mode 100644 index 00000000..fa8ebf62 --- /dev/null +++ b/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs b/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs new file mode 100644 index 00000000..1a07c425 --- /dev/null +++ b/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs @@ -0,0 +1,57 @@ +using Avalonia.Controls; +using Avalonia.Input; +using Avalonia.Interactivity; +using Avalonia.Markup.Xaml; +using Ryujinx.Ava.UI.Helpers; +using Ryujinx.Ava.UI.ViewModels; +using Ryujinx.Ui.App.Common; +using System; + +namespace Ryujinx.Ava.UI.Controls +{ + public partial class ApplicationListView : UserControl + { + public static readonly RoutedEvent ApplicationOpenedEvent = + RoutedEvent.Register(nameof(ApplicationOpened), RoutingStrategies.Bubble); + + public event EventHandler ApplicationOpened + { + add { AddHandler(ApplicationOpenedEvent, value); } + remove { RemoveHandler(ApplicationOpenedEvent, value); } + } + + public ApplicationListView() + { + InitializeComponent(); + } + + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + } + + public void GameList_DoubleTapped(object sender, RoutedEventArgs args) + { + if (sender is ListBox listBox) + { + if (listBox.SelectedItem is ApplicationData selected) + { + RaiseEvent(new ApplicationOpenedEventArgs(selected, ApplicationOpenedEvent)); + } + } + } + + public void GameList_SelectionChanged(object sender, SelectionChangedEventArgs args) + { + if (sender is ListBox listBox) + { + (DataContext as MainWindowViewModel).ListSelectedApplication = listBox.SelectedItem as ApplicationData; + } + } + + 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 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Ryujinx.Ava/UI/Controls/GameGridView.axaml.cs b/src/Ryujinx.Ava/UI/Controls/GameGridView.axaml.cs deleted file mode 100644 index aa76b7c9..00000000 --- a/src/Ryujinx.Ava/UI/Controls/GameGridView.axaml.cs +++ /dev/null @@ -1,57 +0,0 @@ -using Avalonia.Controls; -using Avalonia.Input; -using Avalonia.Interactivity; -using Avalonia.Markup.Xaml; -using Ryujinx.Ava.UI.Helpers; -using Ryujinx.Ava.UI.ViewModels; -using Ryujinx.Ui.App.Common; -using System; - -namespace Ryujinx.Ava.UI.Controls -{ - public partial class GameGridView : UserControl - { - public static readonly RoutedEvent ApplicationOpenedEvent = - RoutedEvent.Register(nameof(ApplicationOpened), RoutingStrategies.Bubble); - - public event EventHandler ApplicationOpened - { - add { AddHandler(ApplicationOpenedEvent, value); } - remove { RemoveHandler(ApplicationOpenedEvent, value); } - } - - public GameGridView() - { - InitializeComponent(); - } - - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } - - public void GameList_DoubleTapped(object sender, RoutedEventArgs args) - { - if (sender is ListBox listBox) - { - if (listBox.SelectedItem is ApplicationData selected) - { - RaiseEvent(new ApplicationOpenedEventArgs(selected, ApplicationOpenedEvent)); - } - } - } - - public void GameList_SelectionChanged(object sender, SelectionChangedEventArgs args) - { - if (sender is ListBox listBox) - { - (DataContext as MainWindowViewModel).GridSelectedApplication = listBox.SelectedItem as ApplicationData; - } - } - - private void SearchBox_OnKeyUp(object sender, KeyEventArgs e) - { - (DataContext as MainWindowViewModel).SearchText = (sender as TextBox).Text; - } - } -} diff --git a/src/Ryujinx.Ava/UI/Controls/GameListView.axaml b/src/Ryujinx.Ava/UI/Controls/GameListView.axaml deleted file mode 100644 index c13eaae8..00000000 --- a/src/Ryujinx.Ava/UI/Controls/GameListView.axaml +++ /dev/null @@ -1,233 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Ryujinx.Ava/UI/Controls/GameListView.axaml.cs b/src/Ryujinx.Ava/UI/Controls/GameListView.axaml.cs deleted file mode 100644 index a6449709..00000000 --- a/src/Ryujinx.Ava/UI/Controls/GameListView.axaml.cs +++ /dev/null @@ -1,57 +0,0 @@ -using Avalonia.Controls; -using Avalonia.Input; -using Avalonia.Interactivity; -using Avalonia.Markup.Xaml; -using Ryujinx.Ava.UI.Helpers; -using Ryujinx.Ava.UI.ViewModels; -using Ryujinx.Ui.App.Common; -using System; - -namespace Ryujinx.Ava.UI.Controls -{ - public partial class GameListView : UserControl - { - public static readonly RoutedEvent ApplicationOpenedEvent = - RoutedEvent.Register(nameof(ApplicationOpened), RoutingStrategies.Bubble); - - public event EventHandler ApplicationOpened - { - add { AddHandler(ApplicationOpenedEvent, value); } - remove { RemoveHandler(ApplicationOpenedEvent, value); } - } - - public GameListView() - { - InitializeComponent(); - } - - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } - - public void GameList_DoubleTapped(object sender, RoutedEventArgs args) - { - if (sender is ListBox listBox) - { - if (listBox.SelectedItem is ApplicationData selected) - { - RaiseEvent(new ApplicationOpenedEventArgs(selected, ApplicationOpenedEvent)); - } - } - } - - public void GameList_SelectionChanged(object sender, SelectionChangedEventArgs args) - { - if (sender is ListBox listBox) - { - (DataContext as MainWindowViewModel).ListSelectedApplication = listBox.SelectedItem as ApplicationData; - } - } - - private void SearchBox_OnKeyUp(object sender, KeyEventArgs e) - { - (DataContext as MainWindowViewModel).SearchText = (sender as TextBox).Text; - } - } -} -- cgit v1.2.3