Просмотр исходного кода

misc: Add CommunityToolkit.Mvvm for observable property generation; apply it to MainWindowViewModel for now.

Evan Husted 1 год назад
Родитель
Сommit
61ae427a4d

+ 1 - 0
Directory.Packages.props

@@ -17,6 +17,7 @@
     <PackageVersion Include="Projektanker.Icons.Avalonia.FontAwesome" Version="9.4.0"/>
     <PackageVersion Include="Projektanker.Icons.Avalonia.MaterialDesign" Version="9.4.0"/>
     <PackageVersion Include="CommandLineParser" Version="2.9.1" />
+    <PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0"/>
     <PackageVersion Include="Concentus" Version="2.2.0" />
     <PackageVersion Include="DiscordRichPresence" Version="1.2.1.24" />
     <PackageVersion Include="DynamicData" Version="9.0.4" />

+ 1 - 1
src/Ryujinx/AppHost.cs

@@ -314,7 +314,7 @@ namespace Ryujinx.Ava
             
             _renderer.Window?.ChangeVSyncMode(e.NewValue);
 
-            _viewModel.ShowCustomVSyncIntervalPicker = (e.NewValue == VSyncMode.Custom);
+            _viewModel.UpdateVSyncIntervalPicker();
         }
 
         public void VSyncModeToggle()

+ 2 - 1
src/Ryujinx/Ryujinx.csproj

@@ -49,6 +49,7 @@
     <PackageReference Include="Avalonia.Svg" />
     <PackageReference Include="Avalonia.Svg.Skia" />
     <PackageReference Include="CommandLineParser" />
+    <PackageReference Include="CommunityToolkit.Mvvm" />
     <PackageReference Include="DiscordRichPresence" />
     <PackageReference Include="DynamicData" />
     <PackageReference Include="FluentAvaloniaUI" />
@@ -162,4 +163,4 @@
   <ItemGroup>
     <AdditionalFiles Include="Assets\locales.json" />
   </ItemGroup>
-</Project>
+</Project>

+ 2 - 10
src/Ryujinx/UI/ViewModels/BaseModel.cs

@@ -1,18 +1,10 @@
+using CommunityToolkit.Mvvm.ComponentModel;
 using System;
-using System.ComponentModel;
-using System.Runtime.CompilerServices;
 
 namespace Ryujinx.Ava.UI.ViewModels
 {
-    public class BaseModel : INotifyPropertyChanged
+    public class BaseModel : ObservableObject
     {
-        public event PropertyChangedEventHandler PropertyChanged;
-
-        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
-        {
-            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
-        }
-        
         protected void OnPropertiesChanged(string firstPropertyName, params ReadOnlySpan<string> propertyNames)
         {
             OnPropertyChanged(firstPropertyName);

+ 68 - 549
src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs

@@ -6,6 +6,7 @@ using Avalonia.Media;
 using Avalonia.Media.Imaging;
 using Avalonia.Platform.Storage;
 using Avalonia.Threading;
+using CommunityToolkit.Mvvm.ComponentModel;
 using DynamicData;
 using DynamicData.Binding;
 using FluentAvalonia.UI.Controls;
@@ -54,80 +55,76 @@ using ShaderCacheLoadingState = Ryujinx.Graphics.Gpu.Shader.ShaderCacheState;
 
 namespace Ryujinx.Ava.UI.ViewModels
 {
-    public class MainWindowViewModel : BaseModel
+    public partial class MainWindowViewModel : BaseModel
     {
         private const int HotKeyPressDelayMs = 500;
         private delegate int LoadContentFromFolderDelegate(List<string> dirs, out int numRemoved);
 
-        private ObservableCollectionExtended<ApplicationData> _applications;
-        private string _aspectStatusText;
-
-        private string _loadHeading;
-        private string _cacheLoadStatus;
+        [ObservableProperty] private ObservableCollectionExtended<ApplicationData> _applications;
+        [ObservableProperty] private string _aspectRatioStatusText;
+        [ObservableProperty] private string _loadHeading;
+        [ObservableProperty] private string _cacheLoadStatus;
+        [ObservableProperty] private string _dockedStatusText;
+        [ObservableProperty] private string _fifoStatusText;
+        [ObservableProperty] private string _gameStatusText;
+        [ObservableProperty] private string _volumeStatusText;
+        [ObservableProperty] private string _gpuNameText;
+        [ObservableProperty] private string _backendText;
+        [ObservableProperty] private string _shaderCountText;
+        [ObservableProperty] private bool _showShaderCompilationHint;
+        [ObservableProperty] private bool _isFullScreen;
+        [ObservableProperty] private int _progressMaximum;
+        [ObservableProperty] private int _progressValue;
+        [ObservableProperty] private bool _showMenuAndStatusBar = true;
+        [ObservableProperty] private bool _showStatusSeparator;
+        [ObservableProperty] private Brush _progressBarForegroundColor;
+        [ObservableProperty] private Brush _progressBarBackgroundColor;
+        [ObservableProperty] private Brush _vSyncModeColor;
+        [ObservableProperty] private byte[] _selectedIcon;
+        [ObservableProperty] private int _statusBarProgressMaximum;
+        [ObservableProperty] private int _statusBarProgressValue;
+        [ObservableProperty] private string _statusBarProgressStatusText;
+        [ObservableProperty] private bool _statusBarProgressStatusVisible;
+        [ObservableProperty] private bool _isPaused;
+        [ObservableProperty] private bool _isLoadingIndeterminate = true;
+        [ObservableProperty] private bool _showAll;
+        [ObservableProperty] private string _lastScannedAmiiboId;
+        [ObservableProperty] private ReadOnlyObservableCollection<ApplicationData> _appsObservableList;
+        [ObservableProperty] private long _lastFullscreenToggle = Environment.TickCount64;
+        [ObservableProperty] private bool _showContent = true;
+        [ObservableProperty] private float _volumeBeforeMute;
+        [ObservableProperty] private bool _areMimeTypesRegistered = FileAssociationHelper.AreMimeTypesRegistered;
+        [ObservableProperty] private Cursor _cursor;
+        [ObservableProperty] private string _title;
+        [ObservableProperty] private WindowState _windowState;
+        [ObservableProperty] private double _windowWidth;
+        [ObservableProperty] private double _windowHeight;
+        [ObservableProperty] private bool _isActive;
+        [ObservableProperty] private bool _isSubMenuOpen;
+        [ObservableProperty] private ApplicationContextMenu _listAppContextMenu;
+        [ObservableProperty] private ApplicationContextMenu _gridAppContextMenu;
+        
+        private bool _showLoadProgress;
+        private bool _isGameRunning;
+        private bool _isAmiiboRequested;
+        private bool _isAmiiboBinRequested;
         private string _searchText;
         private Timer _searchTimer;
-        private string _dockedStatusText;
         private string _vSyncModeText;
-        private string _fifoStatusText;
-        private string _gameStatusText;
-        private string _volumeStatusText;
-        private string _gpuStatusText;
-        private string _shaderCountText;
-        private bool _isAmiiboRequested;
-        private bool _isAmiiboBinRequested;
-        private bool _showShaderCompilationHint;
-        private bool _isGameRunning;
-        private bool _isFullScreen;
-        private int _progressMaximum;
-        private int _progressValue;
-        private long _lastFullscreenToggle = Environment.TickCount64;
-        private bool _showLoadProgress;
-        private bool _showMenuAndStatusBar = true;
-        private bool _showStatusSeparator;
-        private Brush _progressBarForegroundColor;
-        private Brush _progressBarBackgroundColor;
-        private Brush _vSyncModeColor;
-        private byte[] _selectedIcon;
-        private bool _isAppletMenuActive;
-        private int _statusBarProgressMaximum;
-        private int _statusBarProgressValue;
-        private string _statusBarProgressStatusText;
-        private bool _statusBarProgressStatusVisible;
-        private bool _isPaused;
-        private bool _showContent = true;
-        private bool _isLoadingIndeterminate = true;
-        private bool _showAll;
-        private string _lastScannedAmiiboId;
-        private bool _statusBarVisible;
-        private ReadOnlyObservableCollection<ApplicationData> _appsObservableList;
-
         private string _showUiKey = "F4";
         private string _pauseKey = "F5";
         private string _screenshotKey = "F8";
         private float _volume;
-        private float _volumeBeforeMute;
-        private string _backendText;
-
-        private bool _areMimeTypesRegistered = FileAssociationHelper.AreMimeTypesRegistered;
+        private bool _isAppletMenuActive;
+        private bool _statusBarVisible;
         private bool _canUpdate = true;
-        private Cursor _cursor;
-        private string _title;
         private ApplicationData _currentApplicationData;
         private readonly AutoResetEvent _rendererWaitEvent;
-        private WindowState _windowState;
-        private double _windowWidth;
-        private double _windowHeight;
         private int _customVSyncInterval;
         private int _customVSyncIntervalPercentageProxy;
-
-        private bool _isActive;
-        private bool _isSubMenuOpen;
-
         private ApplicationData _listSelectedApplication;
         private ApplicationData _gridSelectedApplication;
-        private ApplicationContextMenu _listAppContextMenu;
-        private ApplicationContextMenu _gridAppContextMenu;
-
+        
         public ApplicationData ListSelectedApplication
         {
             get => _listSelectedApplication;
@@ -135,10 +132,13 @@ namespace Ryujinx.Ava.UI.ViewModels
             {
                 _listSelectedApplication = value;
 
+#pragma warning disable MVVMTK0034
                 if (_listSelectedApplication != null && _listAppContextMenu == null)
+
                     ListAppContextMenu = new ApplicationContextMenu();
                 else if (_listSelectedApplication == null && _listAppContextMenu != null)
-                    ListAppContextMenu = null;
+                    ListAppContextMenu = null!;
+#pragma warning restore MVVMTK0034
 
                 OnPropertyChanged();
             }
@@ -151,10 +151,12 @@ namespace Ryujinx.Ava.UI.ViewModels
             {
                 _gridSelectedApplication = value;
 
+#pragma warning disable MVVMTK0034
                 if (_gridSelectedApplication != null && _gridAppContextMenu == null)
                     GridAppContextMenu = new ApplicationContextMenu();
                 else if (_gridSelectedApplication == null && _gridAppContextMenu != null)
-                    GridAppContextMenu = null;
+                    GridAppContextMenu = null!;
+#pragma warning restore MVVMTK0034
                 
                 OnPropertyChanged();
             }
@@ -260,71 +262,6 @@ namespace Ryujinx.Ava.UI.ViewModels
             }
         }
 
-        public Cursor Cursor
-        {
-            get => _cursor;
-            set
-            {
-                _cursor = value;
-                OnPropertyChanged();
-            }
-        }
-
-        public ReadOnlyObservableCollection<ApplicationData> AppsObservableList
-        {
-            get => _appsObservableList;
-            set
-            {
-                _appsObservableList = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public ApplicationContextMenu ListAppContextMenu
-        {
-            get => _listAppContextMenu;
-            set
-            {
-                _listAppContextMenu = value;
-                
-                OnPropertyChanged();
-            }
-        }
-        
-        public ApplicationContextMenu GridAppContextMenu
-        {
-            get => _gridAppContextMenu;
-            set
-            {
-                _gridAppContextMenu = value;
-                
-                OnPropertyChanged();
-            }
-        }
-
-        public bool IsPaused
-        {
-            get => _isPaused;
-            set
-            {
-                _isPaused = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public long LastFullscreenToggle
-        {
-            get => _lastFullscreenToggle;
-            set
-            {
-                _lastFullscreenToggle = value;
-
-                OnPropertyChanged();
-            }
-        }
-
         public bool StatusBarVisible
         {
             get => _statusBarVisible && EnableNonGameRunningControls;
@@ -340,17 +277,6 @@ namespace Ryujinx.Ava.UI.ViewModels
 
         public bool ShowFirmwareStatus => !ShowLoadProgress;
 
-        public bool ShowShaderCompilationHint
-        {
-            get => _showShaderCompilationHint;
-            set
-            {
-                _showShaderCompilationHint = value;
-
-                OnPropertyChanged();
-            }
-        }
-
         public bool IsGameRunning
         {
             get => _isGameRunning;
@@ -393,7 +319,7 @@ namespace Ryujinx.Ava.UI.ViewModels
         }
 
         public bool CanScanAmiiboBinaries => AmiiboBinReader.HasAmiiboKeyFile;
-        
+
         public bool ShowLoadProgress
         {
             get => _showLoadProgress;
@@ -406,61 +332,6 @@ namespace Ryujinx.Ava.UI.ViewModels
             }
         }
 
-        public string GameStatusText
-        {
-            get => _gameStatusText;
-            set
-            {
-                _gameStatusText = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public bool IsFullScreen
-        {
-            get => _isFullScreen;
-            set
-            {
-                _isFullScreen = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public bool IsSubMenuOpen
-        {
-            get => _isSubMenuOpen;
-            set
-            {
-                _isSubMenuOpen = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public bool ShowAll
-        {
-            get => _showAll;
-            set
-            {
-                _showAll = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public string LastScannedAmiiboId
-        {
-            get => _lastScannedAmiiboId;
-            set
-            {
-                _lastScannedAmiiboId = value;
-
-                OnPropertyChanged();
-            }
-        }
-
         public ApplicationData SelectedApplication
         {
             get
@@ -482,79 +353,12 @@ namespace Ryujinx.Ava.UI.ViewModels
 
         public bool OpenBcatSaveDirectoryEnabled => SelectedApplication.HasControlHolder && SelectedApplication.ControlHolder.Value.BcatDeliveryCacheStorageSize > 0;
 
-        public string LoadHeading
-        {
-            get => _loadHeading;
-            set
-            {
-                _loadHeading = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public string CacheLoadStatus
-        {
-            get => _cacheLoadStatus;
-            set
-            {
-                _cacheLoadStatus = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public Brush ProgressBarBackgroundColor
-        {
-            get => _progressBarBackgroundColor;
-            set
-            {
-                _progressBarBackgroundColor = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public Brush ProgressBarForegroundColor
-        {
-            get => _progressBarForegroundColor;
-            set
-            {
-                _progressBarForegroundColor = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public Brush VSyncModeColor
-        {
-            get => _vSyncModeColor;
-            set
-            {
-                _vSyncModeColor = value;
-
-                OnPropertyChanged();
-            }
-        }
+        public bool ShowCustomVSyncIntervalPicker 
+            => _isGameRunning && AppHost.Device.VSyncMode == VSyncMode.Custom;
 
-        public bool ShowCustomVSyncIntervalPicker
+        public void UpdateVSyncIntervalPicker()
         {
-            get
-            {
-                if (_isGameRunning)
-                {
-                    return AppHost.Device.VSyncMode ==
-                           VSyncMode.Custom;
-                }
-                else
-                {
-                    return false;
-                }
-            }
-            set
-            {
-                OnPropertyChanged();
-            }
+            OnPropertyChanged(nameof(ShowCustomVSyncIntervalPicker));
         }
 
         public int CustomVSyncIntervalPercentageProxy
@@ -607,126 +411,6 @@ namespace Ryujinx.Ava.UI.ViewModels
             }
         }
 
-        public byte[] SelectedIcon
-        {
-            get => _selectedIcon;
-            set
-            {
-                _selectedIcon = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public int ProgressMaximum
-        {
-            get => _progressMaximum;
-            set
-            {
-                _progressMaximum = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public int ProgressValue
-        {
-            get => _progressValue;
-            set
-            {
-                _progressValue = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public int StatusBarProgressMaximum
-        {
-            get => _statusBarProgressMaximum;
-            set
-            {
-                _statusBarProgressMaximum = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public int StatusBarProgressValue
-        {
-            get => _statusBarProgressValue;
-            set
-            {
-                _statusBarProgressValue = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public bool StatusBarProgressStatusVisible
-        {
-            get => _statusBarProgressStatusVisible;
-            set
-            {
-                _statusBarProgressStatusVisible = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public string StatusBarProgressStatusText
-        {
-            get => _statusBarProgressStatusText;
-            set
-            {
-                _statusBarProgressStatusText = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public string FifoStatusText
-        {
-            get => _fifoStatusText;
-            set
-            {
-                _fifoStatusText = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public string GpuNameText
-        {
-            get => _gpuStatusText;
-            set
-            {
-                _gpuStatusText = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public string ShaderCountText
-        {
-            get => _shaderCountText;
-            set
-            {
-                _shaderCountText = value;
-                OnPropertyChanged();
-            }
-        }
-
-        public string BackendText
-        {
-            get => _backendText;
-            set
-            {
-                _backendText = value;
-
-                OnPropertyChanged();
-            }
-        }
-
         public string VSyncModeText
         {
             get => _vSyncModeText;
@@ -735,39 +419,7 @@ namespace Ryujinx.Ava.UI.ViewModels
                 _vSyncModeText = value;
 
                 OnPropertyChanged();
-            }
-        }
-
-        public string DockedStatusText
-        {
-            get => _dockedStatusText;
-            set
-            {
-                _dockedStatusText = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public string AspectRatioStatusText
-        {
-            get => _aspectStatusText;
-            set
-            {
-                _aspectStatusText = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public string VolumeStatusText
-        {
-            get => _volumeStatusText;
-            set
-            {
-                _volumeStatusText = value;
-
-                OnPropertyChanged();
+                OnPropertyChanged(nameof(ShowCustomVSyncIntervalPicker));
             }
         }
 
@@ -791,73 +443,6 @@ namespace Ryujinx.Ava.UI.ViewModels
             }
         }
 
-        public float VolumeBeforeMute
-        {
-            get => _volumeBeforeMute;
-            set
-            {
-                _volumeBeforeMute = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public bool ShowStatusSeparator
-        {
-            get => _showStatusSeparator;
-            set
-            {
-                _showStatusSeparator = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public bool ShowMenuAndStatusBar
-        {
-            get => _showMenuAndStatusBar;
-            set
-            {
-                _showMenuAndStatusBar = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public bool IsLoadingIndeterminate
-        {
-            get => _isLoadingIndeterminate;
-            set
-            {
-                _isLoadingIndeterminate = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public bool IsActive
-        {
-            get => _isActive;
-            set
-            {
-                _isActive = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-
-        public bool ShowContent
-        {
-            get => _showContent;
-            set
-            {
-                _showContent = value;
-
-                OnPropertyChanged();
-            }
-        }
-
         public bool IsAppletMenuActive
         {
             get => _isAppletMenuActive && EnableNonGameRunningControls;
@@ -869,39 +454,6 @@ namespace Ryujinx.Ava.UI.ViewModels
             }
         }
 
-        public WindowState WindowState
-        {
-            get => _windowState;
-            internal set
-            {
-                _windowState = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public double WindowWidth
-        {
-            get => _windowWidth;
-            set
-            {
-                _windowWidth = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public double WindowHeight
-        {
-            get => _windowHeight;
-            set
-            {
-                _windowHeight = value;
-
-                OnPropertyChanged();
-            }
-        }
-
         public bool IsGrid => Glyph == Glyph.Grid;
         public bool IsList => Glyph == Glyph.List;
 
@@ -945,17 +497,6 @@ namespace Ryujinx.Ava.UI.ViewModels
             }
         }
 
-        public string Title
-        {
-            get => _title;
-            set
-            {
-                _title = value;
-
-                OnPropertyChanged();
-            }
-        }
-
         public bool ShowConsoleVisible
         {
             get => ConsoleHelper.SetConsoleWindowStateSupported;
@@ -966,27 +507,6 @@ namespace Ryujinx.Ava.UI.ViewModels
             get => FileAssociationHelper.IsTypeAssociationSupported;
         }
 
-        public bool AreMimeTypesRegistered
-        {
-            get => _areMimeTypesRegistered;
-            set {
-                _areMimeTypesRegistered = value;
-
-                OnPropertyChanged();
-            }
-        }
-
-        public ObservableCollectionExtended<ApplicationData> Applications
-        {
-            get => _applications;
-            set
-            {
-                _applications = value;
-
-                OnPropertyChanged();
-            }
-        }
-
         public Glyph Glyph
         {
             get => (Glyph)ConfigurationState.Instance.UI.GameListViewMode.Value;
@@ -1004,7 +524,8 @@ namespace Ryujinx.Ava.UI.ViewModels
 
         public bool ShowNames
         {
-            get => ConfigurationState.Instance.UI.ShowNames && ConfigurationState.Instance.UI.GridSize > 1; set
+            get => ConfigurationState.Instance.UI.ShowNames && ConfigurationState.Instance.UI.GridSize > 1; 
+            set
             {
                 ConfigurationState.Instance.UI.ShowNames.Value = value;
 
@@ -1564,8 +1085,6 @@ namespace Ryujinx.Ava.UI.ViewModels
                     }
 
                     VSyncModeText = args.VSyncMode == "Custom" ? "Custom" : "VSync";
-                    ShowCustomVSyncIntervalPicker =
-                        args.VSyncMode == VSyncMode.Custom.ToString();
                     DockedStatusText = args.DockedMode;
                     AspectRatioStatusText = args.AspectRatio;
                     GameStatusText = args.GameStatus;