From e294a79975b2d269eede07e6307f4e0ba3439ecb Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Tue, 25 Feb 2025 23:12:45 -0600 Subject: [PATCH] UI: dev: [ci skip] Add Avalonia DevTools support to all Windows defined by Ryujinx, accessible via Ctrl + F12 when running in Debug. --- src/Ryujinx/Program.cs | 10 --------- src/Ryujinx/UI/Applet/AvaHostUIHandler.cs | 2 +- .../Controls/ApplicationContextMenu.axaml.cs | 17 ++++++++------- src/Ryujinx/UI/Helpers/ContentDialogHelper.cs | 5 +++++ .../UI/ViewModels/MainWindowViewModel.cs | 2 +- .../UI/Views/Main/MainMenuBarView.axaml.cs | 21 +++++++++++-------- .../GameSpecificSettingsWindow.axaml.cs | 5 ----- .../UI/Windows/SettingsWindow.axaml.cs | 7 ------- src/Ryujinx/UI/Windows/StyleableWindow.cs | 19 +++++++++++++++++ 9 files changed, 48 insertions(+), 40 deletions(-) diff --git a/src/Ryujinx/Program.cs b/src/Ryujinx/Program.cs index 195a6c066..edd46a7db 100644 --- a/src/Ryujinx/Program.cs +++ b/src/Ryujinx/Program.cs @@ -158,16 +158,6 @@ namespace Ryujinx.Ava } } - public static bool FindGameConfig(string gameDir) - { - if (File.Exists(gameDir)) - { - return true; - } - - return false; - } - public static string GetDirGameUserConfig(string gameId, bool rememberGlobalDir = false, bool changeFolderForGame = false) { if (string.IsNullOrEmpty(gameId)) diff --git a/src/Ryujinx/UI/Applet/AvaHostUIHandler.cs b/src/Ryujinx/UI/Applet/AvaHostUIHandler.cs index c9bd08fa3..a8a6f24c6 100644 --- a/src/Ryujinx/UI/Applet/AvaHostUIHandler.cs +++ b/src/Ryujinx/UI/Applet/AvaHostUIHandler.cs @@ -95,7 +95,7 @@ namespace Ryujinx.Ava.UI.Applet _parent.SettingsWindow = new SettingsWindow(_parent.VirtualFileSystem, _parent.ContentManager); - await _parent.SettingsWindow.ShowDialog(window); + await StyleableAppWindow.ShowAsync(_parent.SettingsWindow, window); _parent.SettingsWindow = null; diff --git a/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs b/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs index 4929e1a19..b2beb23e0 100644 --- a/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs +++ b/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs @@ -91,11 +91,14 @@ namespace Ryujinx.Ava.UI.Controls public async void OpenCheatManager_Click(object sender, RoutedEventArgs args) { if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel }) - await new CheatWindow( - viewModel.VirtualFileSystem, - viewModel.SelectedApplication.IdString, - viewModel.SelectedApplication.Name, - viewModel.SelectedApplication.Path).ShowDialog((Window)viewModel.TopLevel); + await StyleableAppWindow.ShowAsync( + new CheatWindow( + viewModel.VirtualFileSystem, + viewModel.SelectedApplication.IdString, + viewModel.SelectedApplication.Name, + viewModel.SelectedApplication.Path + ) + ); } public void OpenModsDirectory_Click(object sender, RoutedEventArgs args) @@ -391,9 +394,9 @@ namespace Ryujinx.Ava.UI.Controls { if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel }) { - await new GameSpecificSettingsWindow(viewModel).ShowDialog((Window)viewModel.TopLevel); + await StyleableAppWindow.ShowAsync(new GameSpecificSettingsWindow(viewModel)); - //just checking for file presence + // just checking for file presence viewModel.SelectedApplication.HasIndependentConfiguration = File.Exists(Program.GetDirGameUserConfig(viewModel.SelectedApplication.IdString,false,false)); viewModel.RefreshView(); diff --git a/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs b/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs index ae83f9e98..b523e1143 100644 --- a/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs +++ b/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs @@ -1,6 +1,7 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Input; using Avalonia.Layout; using Avalonia.Media; using Avalonia.Threading; @@ -384,6 +385,10 @@ namespace Ryujinx.Ava.UI.Helpers Position = parent.PointToScreen(new Point()), ShowInTaskbar = false, }; + +#if DEBUG + _contentDialogOverlayWindow.AttachDevTools(new KeyGesture(Key.F12, KeyModifiers.Control)); +#endif parent.PositionChanged += OverlayOnPositionChanged; diff --git a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs index 9cf29d1a1..2c42a1a1d 100644 --- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs @@ -1747,7 +1747,7 @@ namespace Ryujinx.Ava.UI.ViewModels string titleId = AppHost.Device.Processes.ActiveApplication.ProgramIdText.ToUpper(); AmiiboWindow window = new(ShowAll, LastScannedAmiiboId, titleId); - await window.ShowDialog(Window); + await StyleableAppWindow.ShowAsync(window); if (window.IsScanned) { diff --git a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs index f1bb2de55..2cab0915d 100644 --- a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs +++ b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs @@ -19,6 +19,7 @@ using Ryujinx.Common.Utilities; using Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Threading.Tasks; @@ -133,20 +134,20 @@ namespace Ryujinx.Ava.UI.Views.Main if (ViewModel.SelectedApplication is null) // Checks if game data exists { - await Window.SettingsWindow.ShowDialog(Window); + await StyleableAppWindow.ShowAsync(Window.SettingsWindow); } else { - bool userConfigExist = Program.FindGameConfig(Program.GetDirGameUserConfig(ViewModel.SelectedApplication.IdString, false, false)); + bool customConfigExists = File.Exists(Program.GetDirGameUserConfig(ViewModel.SelectedApplication.IdString)); - if (!ViewModel.IsGameRunning || !userConfigExist) + if (!ViewModel.IsGameRunning || !customConfigExists) { await Window.SettingsWindow.ShowDialog(Window); // The game is not running, or if the user configuration does not exist } else { // If there is a custom configuration in the folder - await new GameSpecificSettingsWindow(ViewModel, userConfigExist).ShowDialog((Window)ViewModel.TopLevel); + await StyleableAppWindow.ShowAsync(new GameSpecificSettingsWindow(ViewModel, customConfigExists)); } } @@ -175,11 +176,13 @@ namespace Ryujinx.Ava.UI.Views.Main string name = ViewModel.AppHost.Device.Processes.ActiveApplication.ApplicationControlProperties.Title[(int)ViewModel.AppHost.Device.System.State.DesiredTitleLanguage].NameString.ToString(); - await new CheatWindow( - Window.VirtualFileSystem, - ViewModel.AppHost.Device.Processes.ActiveApplication.ProgramIdText, - name, - ViewModel.SelectedApplication.Path).ShowDialog(Window); + await StyleableAppWindow.ShowAsync( + new CheatWindow( + Window.VirtualFileSystem, + ViewModel.AppHost.Device.Processes.ActiveApplication.ProgramIdText, + name, + ViewModel.SelectedApplication.Path) + ); ViewModel.AppHost.Device.EnableCheats(); } diff --git a/src/Ryujinx/UI/Windows/GameSpecificSettingsWindow.axaml.cs b/src/Ryujinx/UI/Windows/GameSpecificSettingsWindow.axaml.cs index 11b7479b4..a28099257 100644 --- a/src/Ryujinx/UI/Windows/GameSpecificSettingsWindow.axaml.cs +++ b/src/Ryujinx/UI/Windows/GameSpecificSettingsWindow.axaml.cs @@ -47,11 +47,6 @@ namespace Ryujinx.Ava.UI.Windows InitializeComponent(); Load(); - -#if DEBUG - this.AttachDevTools(new KeyGesture(Key.F12, KeyModifiers.Alt)); -#endif - } public void SaveSettings() diff --git a/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs b/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs index 4d1fa899a..747849fc3 100644 --- a/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs +++ b/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs @@ -1,6 +1,4 @@ -using Avalonia; using Avalonia.Controls; -using Avalonia.Input; using FluentAvalonia.UI.Controls; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.UI.ViewModels; @@ -8,7 +6,6 @@ using Ryujinx.HLE.FileSystem; using Ryujinx.Input; using System; using System.Linq; -using Key = Avalonia.Input.Key; namespace Ryujinx.Ava.UI.Windows { @@ -27,10 +24,6 @@ namespace Ryujinx.Ava.UI.Windows InitializeComponent(); Load(); - -#if DEBUG - this.AttachDevTools(new KeyGesture(Key.F12, KeyModifiers.Alt)); -#endif } public SettingsWindow() diff --git a/src/Ryujinx/UI/Windows/StyleableWindow.cs b/src/Ryujinx/UI/Windows/StyleableWindow.cs index 9e4eed2e4..0f3291226 100644 --- a/src/Ryujinx/UI/Windows/StyleableWindow.cs +++ b/src/Ryujinx/UI/Windows/StyleableWindow.cs @@ -1,15 +1,26 @@ +using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Primitives; +using Avalonia.Input; using Avalonia.Media; using Avalonia.Platform; using FluentAvalonia.UI.Windowing; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.UI.ViewModels; +using System.Threading.Tasks; namespace Ryujinx.Ava.UI.Windows { public abstract class StyleableAppWindow : AppWindow { + public static async Task ShowAsync(StyleableAppWindow appWindow, Window owner = null) + { +#if DEBUG + appWindow.AttachDevTools(new KeyGesture(Key.F12, KeyModifiers.Control)); +#endif + await appWindow.ShowDialog(owner ?? RyujinxApp.MainWindow); + } + protected StyleableAppWindow() { WindowStartupLocation = WindowStartupLocation.CenterOwner; @@ -36,6 +47,14 @@ namespace Ryujinx.Ava.UI.Windows public abstract class StyleableWindow : Window { + public static async Task ShowAsync(StyleableWindow window, Window owner = null) + { +#if DEBUG + window.AttachDevTools(new KeyGesture(Key.F12, KeyModifiers.Control)); +#endif + await window.ShowDialog(owner ?? RyujinxApp.MainWindow); + } + protected StyleableWindow() { WindowStartupLocation = WindowStartupLocation.CenterOwner;