diff --git a/src/Ryujinx/UI/ViewModels/AmiiboWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/AmiiboWindowViewModel.cs index 948bde544..e9dbb3d6b 100644 --- a/src/Ryujinx/UI/ViewModels/AmiiboWindowViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/AmiiboWindowViewModel.cs @@ -30,7 +30,7 @@ namespace Ryujinx.Ava.UI.ViewModels private readonly string _amiiboJsonPath; private readonly byte[] _amiiboLogoBytes; private readonly HttpClient _httpClient; - private readonly StyleableWindow _owner; + private readonly AmiiboWindow _owner; private Bitmap _amiiboImage; private List _amiiboList; @@ -46,7 +46,7 @@ namespace Ryujinx.Ava.UI.ViewModels private static readonly AmiiboJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions()); - public AmiiboWindowViewModel(StyleableWindow owner, string lastScannedAmiiboId, string titleId) + public AmiiboWindowViewModel(AmiiboWindow owner, string lastScannedAmiiboId, string titleId) { _owner = owner; @@ -183,6 +183,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 d7d772323..6bcafb6d5 100644 --- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs @@ -156,6 +156,8 @@ namespace Ryujinx.Ava.UI.ViewModels public IEnumerable LastLdnGameData; + public MainWindow Window { get; init; } + internal AppHost AppHost { get; set; } public MainWindowViewModel() @@ -1782,7 +1784,7 @@ namespace Ryujinx.Ava.UI.ViewModels public async Task ExitCurrentState() { - if (WindowState == WindowState.FullScreen) + if (WindowState == MainWindow.FullScreenWindowState) { ToggleFullscreen(); } @@ -2097,6 +2099,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() { @@ -2107,7 +2131,7 @@ namespace Ryujinx.Ava.UI.ViewModels LastFullscreenToggle = Environment.TickCount64; - if (WindowState == WindowState.FullScreen) + if (WindowState is not WindowState.Normal) { WindowState = WindowState.Normal; @@ -2118,7 +2142,7 @@ namespace Ryujinx.Ava.UI.ViewModels } else { - WindowState = WindowState.FullScreen; + WindowState = MainWindow.FullScreenWindowState; if (IsGameRunning) { @@ -2126,7 +2150,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 097c8c252..50862bff5 100644 --- a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml +++ b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml @@ -170,6 +170,7 @@ AttachedToVisualTree="ScanAmiiboMenuItem_AttachedToVisualTree" Click="OpenAmiiboWindow" Header="{locale:Locale MenuBarActionsScanAmiibo}" + InputGesture="Ctrl + A" IsEnabled="{Binding IsAmiiboRequested}" /> - - - diff --git a/src/Ryujinx/UI/Windows/MainWindow.axaml b/src/Ryujinx/UI/Windows/MainWindow.axaml index 3a942ca08..150f47bf8 100644 --- a/src/Ryujinx/UI/Windows/MainWindow.axaml +++ b/src/Ryujinx/UI/Windows/MainWindow.axaml @@ -39,6 +39,7 @@ + diff --git a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs index d1abb1cf8..d79c95efd 100644 --- a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs +++ b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs @@ -38,7 +38,7 @@ namespace Ryujinx.Ava.UI.Windows public partial class MainWindow : StyleableWindow { internal static MainWindowViewModel MainWindowViewModel { get; private set; } - + private bool _isLoading; private bool _applicationsLoadedOnce; @@ -67,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() { - ViewModel = new MainWindowViewModel(); + DataContext = ViewModel = new MainWindowViewModel + { + Window = this + }; MainWindowViewModel = ViewModel; @@ -220,7 +231,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(); } @@ -232,7 +243,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 8828d9052..118d6bde9 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 : StyleableWindow { - internal SettingsViewModel ViewModel { get; set; } + internal readonly SettingsViewModel ViewModel; public SettingsWindow(VirtualFileSystem virtualFileSystem, ContentManager contentManager) { Title = $"Ryujinx {Program.Version} - {LocaleManager.Instance[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();