From eeb2af9953f48479c3a902664f31634e6a2148be Mon Sep 17 00:00:00 2001 From: Isaac Marovitz <42140194+IsaacMarovitz@users.noreply.github.com> Date: Sun, 8 Jan 2023 12:46:25 -0500 Subject: Ava GUI: `MainWindow` Refactor (#4178) * Fix redundancies * Add back elses * `MainWindow` Refactor * Switch commands to `ReflectionBinding` Not required in Ava 11 * Update Ryujinx.Ava/AppHost.cs Co-authored-by: Ac_K * Update Ryujinx.Ava/AppHost.cs Co-authored-by: Ac_K * Update Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs Co-authored-by: Ac_K * Update Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs Co-authored-by: Ac_K * Update Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs Co-authored-by: Ac_K * Update Ryujinx.Ava/AppHost.cs Co-authored-by: Ac_K * Update Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml.cs Co-authored-by: Ac_K * Update Ryujinx.Ava/AppHost.cs Co-authored-by: Ac_K * Update Ryujinx.Ava/AppHost.cs Co-authored-by: Ac_K * Update Ryujinx.Ava/AppHost.cs Co-authored-by: Ac_K * Update Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs Co-authored-by: Ac_K * Update Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs Co-authored-by: Ac_K * Update Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs Co-authored-by: Ac_K * Update Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs Co-authored-by: Ac_K * Update Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs Co-authored-by: Ac_K * Update Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs Co-authored-by: Ac_K * Update Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs Co-authored-by: Ac_K * Update Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs Co-authored-by: Ac_K * Update Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs Co-authored-by: Ac_K * Update Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs Co-authored-by: Ac_K * Update Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs Co-authored-by: Ac_K * Update Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs Co-authored-by: Ac_K * Update Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml.cs Co-authored-by: Ac_K * Resolve issues * Remove Ava 11 Fix * Update Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs Co-authored-by: gdkchan * Update Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs Co-authored-by: gdkchan * Fix whitespace + other suggestions * Move Vsync colours to `Styles.xaml` * Remove catch all * Use `switch` instead of `if` * Update locale keys * Use block-scoped namespaces * Fix improper Ava api usage then * Static PTC * Fix `GridItemSelectorSize` with `ShowNames` * Update for new About Window * Add back search fix Co-authored-by: Ac_K Co-authored-by: gdkchan --- Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml | 216 +++++++++++++++++++ Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs | 146 +++++++++++++ Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml | 232 +++++++++++++++++++++ .../UI/Views/Main/MainStatusBarView.axaml.cs | 52 +++++ Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml | 176 ++++++++++++++++ .../UI/Views/Main/MainViewControls.axaml.cs | 54 +++++ 6 files changed, 876 insertions(+) create mode 100644 Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml create mode 100644 Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs create mode 100644 Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml create mode 100644 Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml.cs create mode 100644 Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml create mode 100644 Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml.cs (limited to 'Ryujinx.Ava/UI/Views/Main') diff --git a/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml b/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml new file mode 100644 index 00000000..0d0ae119 --- /dev/null +++ b/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs b/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs new file mode 100644 index 00000000..8c28abff --- /dev/null +++ b/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs @@ -0,0 +1,146 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Interactivity; +using Ryujinx.Ava.UI.ViewModels; +using Ryujinx.Ava.UI.Windows; +using System.Threading.Tasks; +using LibHac.FsSystem; +using LibHac.Ncm; +using Ryujinx.HLE.HOS; +using Ryujinx.Modules; + +namespace Ryujinx.Ava.UI.Views.Main +{ + public partial class MainMenuBarView : UserControl + { + public MainWindow Window { get; private set; } + public MainWindowViewModel ViewModel { get; private set; } + + public MainMenuBarView() + { + InitializeComponent(); + } + + protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) + { + base.OnAttachedToVisualTree(e); + + if (this.VisualRoot is MainWindow window) + { + Window = window; + } + + ViewModel = Window.ViewModel; + DataContext = ViewModel; + } + + private async void StopEmulation_Click(object sender, RoutedEventArgs e) + { + await Task.Run(() => + { + Window.ViewModel.AppHost?.ShowExitPrompt(); + }); + } + + private async void PauseEmulation_Click(object sender, RoutedEventArgs e) + { + await Task.Run(() => + { + Window.ViewModel.AppHost?.Pause(); + }); + } + + private async void ResumeEmulation_Click(object sender, RoutedEventArgs e) + { + await Task.Run(() => + { + Window.ViewModel.AppHost?.Resume(); + }); + } + + public async void OpenSettings(object sender, RoutedEventArgs e) + { + Window.SettingsWindow = new(Window.VirtualFileSystem, Window.ContentManager); + + await Window.SettingsWindow.ShowDialog(Window); + + ViewModel.LoadConfigurableHotKeys(); + } + + public void OpenMiiApplet(object sender, RoutedEventArgs e) + { + string contentPath = ViewModel.ContentManager.GetInstalledContentPath(0x0100000000001009, StorageId.BuiltInSystem, NcaContentType.Program); + + if (!string.IsNullOrEmpty(contentPath)) + { + ViewModel.LoadApplication(contentPath, false, "Mii Applet"); + } + } + + public async void OpenAmiiboWindow(object sender, RoutedEventArgs e) + { + if (!ViewModel.IsAmiiboRequested) + { + return; + } + + if (ViewModel.AppHost.Device.System.SearchingForAmiibo(out int deviceId)) + { + string titleId = ViewModel.AppHost.Device.Application.TitleIdText.ToUpper(); + AmiiboWindow window = new(ViewModel.ShowAll, ViewModel.LastScannedAmiiboId, titleId); + + await window.ShowDialog(Window); + + if (window.IsScanned) + { + ViewModel.ShowAll = window.ViewModel.ShowAllAmiibo; + ViewModel.LastScannedAmiiboId = window.ScannedAmiibo.GetId(); + + ViewModel.AppHost.Device.System.ScanAmiibo(deviceId, ViewModel.LastScannedAmiiboId, window.ViewModel.UseRandomUuid); + } + } + } + + public async void OpenCheatManagerForCurrentApp(object sender, RoutedEventArgs e) + { + if (!ViewModel.IsGameRunning) + { + return; + } + + ApplicationLoader application = ViewModel.AppHost.Device.Application; + if (application != null) + { + await new CheatWindow(Window.VirtualFileSystem, application.TitleIdText, application.TitleName).ShowDialog(Window); + + ViewModel.AppHost.Device.EnableCheats(); + } + } + + private void ScanAmiiboMenuItem_AttachedToVisualTree(object sender, VisualTreeAttachmentEventArgs e) + { + if (sender is MenuItem) + { + ViewModel.IsAmiiboRequested = Window.ViewModel.AppHost.Device.System.SearchingForAmiibo(out _); + } + } + + public async void CheckForUpdates(object sender, RoutedEventArgs e) + { + if (Updater.CanUpdate(true, Window)) + { + await Updater.BeginParse(Window, true); + } + } + + public async void OpenAboutWindow(object sender, RoutedEventArgs e) + { + await AboutWindow.Show(); + } + + public void CloseWindow(object sender, RoutedEventArgs e) + { + Window.Close(); + } + } +} \ No newline at end of file diff --git a/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml b/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml new file mode 100644 index 00000000..16705695 --- /dev/null +++ b/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml @@ -0,0 +1,232 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml.cs b/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml.cs new file mode 100644 index 00000000..d1050ddd --- /dev/null +++ b/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml.cs @@ -0,0 +1,52 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Input; +using Ryujinx.Ava.UI.Windows; +using Ryujinx.Common.Configuration; +using Ryujinx.Common.Logging; +using Ryujinx.Ui.Common.Configuration; +using System; + +namespace Ryujinx.Ava.UI.Views.Main +{ + public partial class MainStatusBarView : UserControl + { + public MainWindow Window; + + public MainStatusBarView() + { + InitializeComponent(); + } + + protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) + { + base.OnAttachedToVisualTree(e); + + if (this.VisualRoot is MainWindow window) + { + Window = window; + } + + DataContext = Window.ViewModel; + } + + private void VsyncStatus_PointerReleased(object sender, PointerReleasedEventArgs e) + { + Window.ViewModel.AppHost.Device.EnableDeviceVsync = !Window.ViewModel.AppHost.Device.EnableDeviceVsync; + + Logger.Info?.Print(LogClass.Application, $"VSync toggled to: {Window.ViewModel.AppHost.Device.EnableDeviceVsync}"); + } + + private void DockedStatus_PointerReleased(object sender, PointerReleasedEventArgs e) + { + ConfigurationState.Instance.System.EnableDockedMode.Value = !ConfigurationState.Instance.System.EnableDockedMode.Value; + } + + private void AspectRatioStatus_PointerReleased(object sender, PointerReleasedEventArgs e) + { + AspectRatio aspectRatio = ConfigurationState.Instance.Graphics.AspectRatio.Value; + + ConfigurationState.Instance.Graphics.AspectRatio.Value = (int)aspectRatio + 1 > Enum.GetNames(typeof(AspectRatio)).Length - 1 ? AspectRatio.Fixed4x3 : aspectRatio + 1; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml b/Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml new file mode 100644 index 00000000..e83a6504 --- /dev/null +++ b/Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml.cs b/Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml.cs new file mode 100644 index 00000000..841d59de --- /dev/null +++ b/Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml.cs @@ -0,0 +1,54 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Input; +using Avalonia.Interactivity; +using Ryujinx.Ava.Common; +using Ryujinx.Ava.UI.ViewModels; +using Ryujinx.Ava.UI.Windows; +using System; + +namespace Ryujinx.Ava.UI.Views.Main +{ + public partial class MainViewControls : UserControl + { + public MainWindowViewModel ViewModel; + + public MainViewControls() + { + InitializeComponent(); + } + + protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) + { + base.OnAttachedToVisualTree(e); + + if (this.VisualRoot is MainWindow window) + { + ViewModel = window.ViewModel; + } + + DataContext = ViewModel; + } + + public void Sort_Checked(object sender, RoutedEventArgs args) + { + if (sender is RadioButton button) + { + ViewModel.Sort(Enum.Parse(button.Tag.ToString())); + } + } + + public void Order_Checked(object sender, RoutedEventArgs args) + { + if (sender is RadioButton button) + { + ViewModel.Sort(button.Tag.ToString() != "Descending"); + } + } + + private void SearchBox_OnKeyUp(object sender, KeyEventArgs e) + { + ViewModel.SearchText = SearchBox.Text; + } + } +} \ No newline at end of file -- cgit v1.2.3