From 741eba279897cda3982107d0559f97a9994a7314 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Sat, 19 Oct 2024 16:39:21 -0500 Subject: [PATCH] UI: Add keybinds to useful things --- src/Ryujinx/UI/Models/SaveModel.cs | 2 +- .../UI/ViewModels/AmiiboWindowViewModel.cs | 20 ++++++++++-- .../UI/ViewModels/MainWindowViewModel.cs | 32 ++++++++++++++++--- .../UI/Views/Main/MainMenuBarView.axaml | 1 + .../UI/Views/Main/MainMenuBarView.axaml.cs | 23 ++----------- src/Ryujinx/UI/Windows/AmiiboWindow.axaml | 15 ++++++--- src/Ryujinx/UI/Windows/AmiiboWindow.axaml.cs | 27 +++------------- src/Ryujinx/UI/Windows/CheatWindow.axaml | 4 ++- src/Ryujinx/UI/Windows/MainWindow.axaml | 1 + src/Ryujinx/UI/Windows/MainWindow.axaml.cs | 19 ++++++++--- .../UI/Windows/ModManagerWindow.axaml.cs | 2 +- .../UI/Windows/SettingsWindow.axaml.cs | 8 ++--- src/Ryujinx/UI/Windows/StyleableWindow.cs | 4 --- 13 files changed, 88 insertions(+), 70 deletions(-) diff --git a/src/Ryujinx/UI/Models/SaveModel.cs b/src/Ryujinx/UI/Models/SaveModel.cs index cfc397c6e..55408ac3a 100644 --- a/src/Ryujinx/UI/Models/SaveModel.cs +++ b/src/Ryujinx/UI/Models/SaveModel.cs @@ -47,7 +47,7 @@ namespace Ryujinx.Ava.UI.Models TitleId = info.ProgramId; UserId = info.UserId; - var appData = MainWindow.MainWindowViewModel.Applications.FirstOrDefault(x => x.IdString.Equals(TitleIdString, StringComparison.OrdinalIgnoreCase)); + var appData = App.MainWindow.ViewModel.Applications.FirstOrDefault(x => x.IdString.Equals(TitleIdString, StringComparison.OrdinalIgnoreCase)); InGameList = appData != null; diff --git a/src/Ryujinx/UI/ViewModels/AmiiboWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/AmiiboWindowViewModel.cs index 6afaaea04..5ea38b8ab 100644 --- a/src/Ryujinx/UI/ViewModels/AmiiboWindowViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/AmiiboWindowViewModel.cs @@ -33,7 +33,7 @@ namespace Ryujinx.Ava.UI.ViewModels private readonly string _amiiboJsonPath; private readonly byte[] _amiiboLogoBytes; private readonly HttpClient _httpClient; - private readonly StyleableAppWindow _owner; + private readonly AmiiboWindow _owner; private Bitmap _amiiboImage; private List _amiiboList; @@ -49,7 +49,7 @@ namespace Ryujinx.Ava.UI.ViewModels private static readonly AmiiboJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions()); - public AmiiboWindowViewModel(StyleableAppWindow owner, string lastScannedAmiiboId, string titleId) + public AmiiboWindowViewModel(AmiiboWindow owner, string lastScannedAmiiboId, string titleId) { _owner = owner; @@ -186,6 +186,22 @@ namespace Ryujinx.Ava.UI.ViewModels } } + public void Scan() + { + if (AmiiboSelectedIndex > -1) + { + _owner.ScannedAmiibo = AmiiboList[AmiiboSelectedIndex]; + _owner.IsScanned = true; + _owner.Close(); + } + } + + public void Cancel() + { + _owner.IsScanned = false; + _owner.Close(); + } + public void Dispose() { GC.SuppressFinalize(this); diff --git a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs index e9f8563c7..23e977fab 100644 --- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs @@ -110,6 +110,8 @@ namespace Ryujinx.Ava.UI.ViewModels public ApplicationData ListSelectedApplication; public ApplicationData GridSelectedApplication; + public MainWindow Window { get; init; } + internal AppHost AppHost { get; set; } public MainWindowViewModel() @@ -1424,7 +1426,7 @@ namespace Ryujinx.Ava.UI.ViewModels public async Task ExitCurrentState() { - if (WindowState == WindowState.FullScreen) + if (WindowState == MainWindow.FullScreenWindowState) { ToggleFullscreen(); } @@ -1710,6 +1712,28 @@ namespace Ryujinx.Ava.UI.ViewModels }); } + public async Task OpenAmiiboWindow() + { + if (!IsAmiiboRequested) + return; + + if (AppHost.Device.System.SearchingForAmiibo(out int deviceId)) + { + string titleId = AppHost.Device.Processes.ActiveApplication.ProgramIdText.ToUpper(); + AmiiboWindow window = new(ShowAll, LastScannedAmiiboId, titleId); + + await window.ShowDialog(Window); + + if (window.IsScanned) + { + ShowAll = window.ViewModel.ShowAllAmiibo; + LastScannedAmiiboId = window.ScannedAmiibo.GetId(); + + AppHost.Device.System.ScanAmiibo(deviceId, LastScannedAmiiboId, window.ViewModel.UseRandomUuid); + } + } + } + public void ToggleFullscreen() { if (Environment.TickCount64 - LastFullscreenToggle < HotKeyPressDelayMs) @@ -1719,7 +1743,7 @@ namespace Ryujinx.Ava.UI.ViewModels LastFullscreenToggle = Environment.TickCount64; - if (WindowState == WindowState.FullScreen) + if (WindowState is not WindowState.Normal) { WindowState = WindowState.Normal; @@ -1730,7 +1754,7 @@ namespace Ryujinx.Ava.UI.ViewModels } else { - WindowState = WindowState.FullScreen; + WindowState = MainWindow.FullScreenWindowState; if (IsGameRunning) { @@ -1738,7 +1762,7 @@ namespace Ryujinx.Ava.UI.ViewModels } } - IsFullScreen = WindowState == WindowState.FullScreen; + IsFullScreen = WindowState == MainWindow.FullScreenWindowState; } public static void SaveConfig() diff --git a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml index 1c13440d8..4e29702e6 100644 --- a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml +++ b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml @@ -240,6 +240,7 @@ Click="OpenAmiiboWindow" Header="{locale:Locale MenuBarActionsScanAmiibo}" Icon="{icon:Icon mdi-cube-scan}" + InputGesture="Ctrl + A" IsEnabled="{Binding IsAmiiboRequested}" /> await ViewModel.OpenAmiiboWindow(); public async void OpenCheatManagerForCurrentApp(object sender, RoutedEventArgs e) { diff --git a/src/Ryujinx/UI/Windows/AmiiboWindow.axaml b/src/Ryujinx/UI/Windows/AmiiboWindow.axaml index 63bcd70c9..180eb4a88 100644 --- a/src/Ryujinx/UI/Windows/AmiiboWindow.axaml +++ b/src/Ryujinx/UI/Windows/AmiiboWindow.axaml @@ -45,16 +45,23 @@ - - - diff --git a/src/Ryujinx/UI/Windows/MainWindow.axaml b/src/Ryujinx/UI/Windows/MainWindow.axaml index c97fc7044..39ffe8e4d 100644 --- a/src/Ryujinx/UI/Windows/MainWindow.axaml +++ b/src/Ryujinx/UI/Windows/MainWindow.axaml @@ -40,6 +40,7 @@ + diff --git a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs index 0bbfeba66..9d633253a 100644 --- a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs +++ b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs @@ -37,8 +37,6 @@ namespace Ryujinx.Ava.UI.Windows { public partial class MainWindow : StyleableAppWindow { - internal static MainWindowViewModel MainWindowViewModel { get; private set; } - public MainWindowViewModel ViewModel { get; } internal readonly AvaHostUIHandler UiHandler; @@ -69,9 +67,20 @@ namespace Ryujinx.Ava.UI.Windows public readonly double StatusBarHeight; public readonly double MenuBarHeight; + // The special window decoration from AppWindow in FluentAvalonia is only present on Windows; + // and as such optimizing for the fact that the menu bar and the title bar are the same is only needed on Windows. + // Maximized is considered superior to FullScreen on Windows in this case because you get the benefits of being in full screen, + // while still being able to use the standard 3 window controls in the top right to minimize, make the window smaller, or close the app. + + public static readonly WindowState FullScreenWindowState = + OperatingSystem.IsWindows() ? WindowState.Maximized : WindowState.FullScreen; + public MainWindow() { - DataContext = ViewModel = MainWindowViewModel = new MainWindowViewModel(); + DataContext = ViewModel = new MainWindowViewModel + { + Window = this + }; InitializeComponent(); Load(); @@ -184,7 +193,7 @@ namespace Ryujinx.Ava.UI.Windows ViewModel.ShowContent = true; ViewModel.IsLoadingIndeterminate = false; - if (startFullscreen && ViewModel.WindowState != WindowState.FullScreen) + if (startFullscreen && ViewModel.WindowState != MainWindow.FullScreenWindowState) { ViewModel.ToggleFullscreen(); } @@ -196,7 +205,7 @@ namespace Ryujinx.Ava.UI.Windows ViewModel.ShowLoadProgress = true; ViewModel.IsLoadingIndeterminate = true; - if (startFullscreen && ViewModel.WindowState != WindowState.FullScreen) + if (startFullscreen && ViewModel.WindowState != MainWindow.FullScreenWindowState) { ViewModel.ToggleFullscreen(); } diff --git a/src/Ryujinx/UI/Windows/ModManagerWindow.axaml.cs b/src/Ryujinx/UI/Windows/ModManagerWindow.axaml.cs index 98f694db8..94bd6660d 100644 --- a/src/Ryujinx/UI/Windows/ModManagerWindow.axaml.cs +++ b/src/Ryujinx/UI/Windows/ModManagerWindow.axaml.cs @@ -14,7 +14,7 @@ namespace Ryujinx.Ava.UI.Windows { public partial class ModManagerWindow : UserControl { - public ModManagerViewModel ViewModel; + public readonly ModManagerViewModel ViewModel; public ModManagerWindow() { diff --git a/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs b/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs index 2a6835078..1a177d182 100644 --- a/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs +++ b/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs @@ -10,14 +10,13 @@ namespace Ryujinx.Ava.UI.Windows { public partial class SettingsWindow : StyleableAppWindow { - internal SettingsViewModel ViewModel { get; set; } + internal readonly SettingsViewModel ViewModel; public SettingsWindow(VirtualFileSystem virtualFileSystem, ContentManager contentManager) { Title = App.FormatTitle(LocaleKeys.Settings); - ViewModel = new SettingsViewModel(virtualFileSystem, contentManager); - DataContext = ViewModel; + DataContext = ViewModel = new SettingsViewModel(virtualFileSystem, contentManager); ViewModel.CloseWindow += Close; ViewModel.SaveSettingsEvent += SaveSettings; @@ -28,8 +27,7 @@ namespace Ryujinx.Ava.UI.Windows public SettingsWindow() { - ViewModel = new SettingsViewModel(); - DataContext = ViewModel; + DataContext = ViewModel = new SettingsViewModel(); InitializeComponent(); Load(); diff --git a/src/Ryujinx/UI/Windows/StyleableWindow.cs b/src/Ryujinx/UI/Windows/StyleableWindow.cs index bc6e53cb0..099c56bce 100644 --- a/src/Ryujinx/UI/Windows/StyleableWindow.cs +++ b/src/Ryujinx/UI/Windows/StyleableWindow.cs @@ -1,13 +1,9 @@ using Avalonia.Controls; using Avalonia.Controls.Primitives; using Avalonia.Media; -using Avalonia.Media.Imaging; using Avalonia.Platform; using FluentAvalonia.UI.Windowing; using Ryujinx.Ava.Common.Locale; -using Ryujinx.UI.Common.Configuration; -using System.IO; -using System.Reflection; namespace Ryujinx.Ava.UI.Windows {