language feature: field keyword & partial properties for observable properties in the UI

partial properties are from C# 13 but weren't usable for these properties
This commit is contained in:
GreemDev
2025-09-12 13:58:01 -05:00
parent de49d1779e
commit a5a13271d5
22 changed files with 185 additions and 158 deletions

View File

@ -4,7 +4,6 @@ using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Threading; using Avalonia.Threading;
using DiscordRPC; using DiscordRPC;
using Gommon;
using LibHac.Common; using LibHac.Common;
using LibHac.Ns; using LibHac.Ns;
using Ryujinx.Audio.Backends.Dummy; using Ryujinx.Audio.Backends.Dummy;

View File

@ -1,7 +1,6 @@
using DynamicData; using DynamicData;
using DynamicData.Kernel; using DynamicData.Kernel;
using Gommon; using Gommon;
using LibHac;
using LibHac.Common; using LibHac.Common;
using LibHac.Fs; using LibHac.Fs;
using LibHac.Fs.Fsa; using LibHac.Fs.Fsa;

View File

@ -11,13 +11,17 @@ namespace Ryujinx.Ava.UI.ViewModels
{ {
public partial class AboutWindowViewModel : BaseModel, IDisposable public partial class AboutWindowViewModel : BaseModel, IDisposable
{ {
[ObservableProperty] private Bitmap _gitLabLogo; [ObservableProperty] public partial Bitmap GitLabLogo { get; set; }
[ObservableProperty] private Bitmap _discordLogo;
[ObservableProperty] private string _version;
public string Developers => "GreemDev, LotP"; [ObservableProperty] public partial Bitmap DiscordLogo { get; set; }
public string FormerDevelopers => LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.AboutPageDeveloperListMore, "gdkchan, Ac_K, marysaka, rip in peri peri, LDj3SNuD, emmaus, Thealexbarney, GoffyDude, TSRBerry, IsaacMarovitz"); [ObservableProperty] public partial string Version { get; set; }
public static string Developers => "GreemDev, LotP";
public static string FormerDevelopers => LocaleManager.Instance.UpdateAndGetDynamicValue(
LocaleKeys.AboutPageDeveloperListMore,
"gdkchan, Ac_K, marysaka, rip in peri peri, LDj3SNuD, emmaus, Thealexbarney, GoffyDude, TSRBerry, IsaacMarovitz");
public AboutWindowViewModel() public AboutWindowViewModel()
{ {
@ -36,7 +40,8 @@ namespace Ryujinx.Ava.UI.ViewModels
private void UpdateLogoTheme(string theme) private void UpdateLogoTheme(string theme)
{ {
bool isDarkTheme = theme == "Dark" || (theme == "Auto" && RyujinxApp.DetectSystemTheme() == ThemeVariant.Dark); bool isDarkTheme = theme == "Dark" ||
(theme == "Auto" && RyujinxApp.DetectSystemTheme() == ThemeVariant.Dark);
string themeName = isDarkTheme ? "Dark" : "Light"; string themeName = isDarkTheme ? "Dark" : "Light";

View File

@ -35,17 +35,13 @@ namespace Ryujinx.Ava.UI.ViewModels
private readonly HttpClient _httpClient; private readonly HttpClient _httpClient;
private readonly AmiiboWindow _owner; private readonly AmiiboWindow _owner;
private Bitmap _amiiboImage;
private List<AmiiboApi> _amiiboList; private List<AmiiboApi> _amiiboList;
private AvaloniaList<AmiiboApi> _amiibos; private AvaloniaList<AmiiboApi> _amiibos;
private ObservableCollection<string> _amiiboSeries; private ObservableCollection<string> _amiiboSeries;
private int _amiiboSelectedIndex; private int _amiiboSelectedIndex;
private int _seriesSelectedIndex; private int _seriesSelectedIndex;
private bool _enableScanning;
private bool _showAllAmiibo; private bool _showAllAmiibo;
private bool _useRandomUuid = _cachedUseRandomUuid;
private string _usage;
private static readonly AmiiboJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions()); private static readonly AmiiboJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
@ -82,14 +78,14 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool UseRandomUuid public bool UseRandomUuid
{ {
get => _useRandomUuid; get;
set set
{ {
_cachedUseRandomUuid = _useRandomUuid = value; _cachedUseRandomUuid = field = value;
OnPropertyChanged(); OnPropertyChanged();
} }
} } = _cachedUseRandomUuid;
public bool ShowAllAmiibo public bool ShowAllAmiibo
{ {
@ -155,10 +151,10 @@ namespace Ryujinx.Ava.UI.ViewModels
public Bitmap AmiiboImage public Bitmap AmiiboImage
{ {
get => _amiiboImage; get;
set set
{ {
_amiiboImage = value; field = value;
OnPropertyChanged(); OnPropertyChanged();
} }
@ -166,10 +162,10 @@ namespace Ryujinx.Ava.UI.ViewModels
public string Usage public string Usage
{ {
get => _usage; get;
set set
{ {
_usage = value; field = value;
OnPropertyChanged(); OnPropertyChanged();
} }
@ -177,10 +173,10 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool EnableScanning public bool EnableScanning
{ {
get => _enableScanning; get;
set set
{ {
_enableScanning = value; field = value;
OnPropertyChanged(); OnPropertyChanged();
} }

View File

@ -7,14 +7,16 @@ namespace Ryujinx.Ava.UI.ViewModels
{ {
public partial class DlcSelectViewModel : BaseModel public partial class DlcSelectViewModel : BaseModel
{ {
[ObservableProperty] private DownloadableContentModel[] _dlcs; [ObservableProperty]
public partial DownloadableContentModel[] Dlcs { get; set; }
#nullable enable #nullable enable
[ObservableProperty] private DownloadableContentModel? _selectedDlc; [ObservableProperty]
public partial DownloadableContentModel? SelectedDlc { get; set; }
#nullable disable #nullable disable
public DlcSelectViewModel(ulong titleId, ApplicationLibrary appLibrary) public DlcSelectViewModel(ulong titleId, ApplicationLibrary appLibrary)
{ {
_dlcs = appLibrary.FindDlcsFor(titleId) Dlcs = appLibrary.FindDlcsFor(titleId)
.OrderBy(it => it.IsBundled ? 0 : 1) .OrderBy(it => it.IsBundled ? 0 : 1)
.ThenBy(it => it.TitleId) .ThenBy(it => it.TitleId)
.ToArray(); .ToArray();

View File

@ -19,10 +19,14 @@ namespace Ryujinx.Ava.UI.ViewModels
public partial class DownloadableContentManagerViewModel : BaseModel public partial class DownloadableContentManagerViewModel : BaseModel
{ {
private readonly ApplicationLibrary _applicationLibrary; private readonly ApplicationLibrary _applicationLibrary;
private AvaloniaList<DownloadableContentModel> _downloadableContents = []; [ObservableProperty]
[ObservableProperty] private AvaloniaList<DownloadableContentModel> _selectedDownloadableContents = []; public partial AvaloniaList<DownloadableContentModel> SelectedDownloadableContents { get; set; } = [];
[ObservableProperty] private AvaloniaList<DownloadableContentModel> _views = [];
[ObservableProperty] private bool _showBundledContentNotice = false; [ObservableProperty]
public partial AvaloniaList<DownloadableContentModel> Views { get; set; } = [];
[ObservableProperty]
public partial bool ShowBundledContentNotice { get; set; } = false;
private string _search; private string _search;
private readonly ApplicationData _applicationData; private readonly ApplicationData _applicationData;
@ -30,15 +34,15 @@ namespace Ryujinx.Ava.UI.ViewModels
public AvaloniaList<DownloadableContentModel> DownloadableContents public AvaloniaList<DownloadableContentModel> DownloadableContents
{ {
get => _downloadableContents; get;
set set
{ {
_downloadableContents = value; field = value;
OnPropertyChanged(); OnPropertyChanged();
OnPropertyChanged(nameof(UpdateCount)); OnPropertyChanged(nameof(UpdateCount));
Sort(); Sort();
} }
} } = [];
public string Search public string Search
{ {
@ -51,10 +55,7 @@ namespace Ryujinx.Ava.UI.ViewModels
} }
} }
public string UpdateCount public string UpdateCount => string.Format(LocaleManager.Instance[LocaleKeys.DlcWindowHeading], DownloadableContents.Count);
{
get => string.Format(LocaleManager.Instance[LocaleKeys.DlcWindowHeading], DownloadableContents.Count);
}
public DownloadableContentManagerViewModel(ApplicationLibrary applicationLibrary, ApplicationData applicationData) public DownloadableContentManagerViewModel(ApplicationLibrary applicationLibrary, ApplicationData applicationData)
{ {

View File

@ -4,55 +4,50 @@ using Ryujinx.Ava.UI.Models.Input;
using Ryujinx.Ava.UI.Views.Input; using Ryujinx.Ava.UI.Views.Input;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using Ryujinx.UI.Views.Input; using Ryujinx.UI.Views.Input;
using System.Drawing;
namespace Ryujinx.Ava.UI.ViewModels.Input namespace Ryujinx.Ava.UI.ViewModels.Input
{ {
public partial class ControllerInputViewModel : BaseModel public partial class ControllerInputViewModel : BaseModel
{ {
private GamepadInputConfig _config;
public GamepadInputConfig Config public GamepadInputConfig Config
{ {
get => _config; get;
set set
{ {
_config = value; field = value;
OnPropertyChanged(); OnPropertyChanged();
} }
} }
private StickVisualizer _visualizer;
public StickVisualizer Visualizer public StickVisualizer Visualizer
{ {
get => _visualizer; get;
set set
{ {
_visualizer = value; field = value;
OnPropertyChanged(); OnPropertyChanged();
} }
} }
private bool _isLeft;
public bool IsLeft public bool IsLeft
{ {
get => _isLeft; get;
set set
{ {
_isLeft = value; field = value;
OnPropertyChanged(); OnPropertyChanged();
OnPropertyChanged(nameof(HasSides)); OnPropertyChanged(nameof(HasSides));
} }
} }
private bool _isRight;
public bool IsRight public bool IsRight
{ {
get => _isRight; get;
set set
{ {
_isRight = value; field = value;
OnPropertyChanged(); OnPropertyChanged();
OnPropertyChanged(nameof(HasSides)); OnPropertyChanged(nameof(HasSides));
} }
@ -60,8 +55,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public bool HasSides => IsLeft ^ IsRight; public bool HasSides => IsLeft ^ IsRight;
[ObservableProperty] private SvgImage _image; [ObservableProperty]
public partial SvgImage Image { get; set; }
public InputViewModel ParentModel { get; } public InputViewModel ParentModel { get; }
public ControllerInputViewModel(InputViewModel model, GamepadInputConfig config, StickVisualizer visualizer) public ControllerInputViewModel(InputViewModel model, GamepadInputConfig config, StickVisualizer visualizer)
@ -75,7 +70,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
if (args.PropertyName is nameof(Config.UseRainbowLed)) if (args.PropertyName is nameof(Config.UseRainbowLed))
{ {
if (Config is { UseRainbowLed: true, TurnOffLed: false, EnableLedChanging: true }) if (Config is { UseRainbowLed: true, TurnOffLed: false, EnableLedChanging: true })
Rainbow.Updated += (ref Color color) => ParentModel.SelectedGamepad.SetLed((uint)color.ToArgb()); Rainbow.Updated += (ref color) => ParentModel.SelectedGamepad.SetLed((uint)color.ToArgb());
else else
{ {
Rainbow.Reset(); Rainbow.Reset();

View File

@ -48,36 +48,41 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
private int _controller; private int _controller;
private string _controllerImage; private string _controllerImage;
private int _device; private int _device;
private object _configViewModel;
private bool _isChangeTrackingActive; private bool _isChangeTrackingActive;
private string _chosenProfile; [ObservableProperty]
[ObservableProperty] private bool _isModified; public partial bool IsModified { get; set; }
[ObservableProperty] private string _profileName;
[ObservableProperty] private bool _notificationIsVisible; // Automatically call the NotificationView property with OnPropertyChanged() [ObservableProperty]
[ObservableProperty] private string _notificationText; // Automatically call the NotificationText property with OnPropertyChanged() public partial string ProfileName { get; set; }
[ObservableProperty]
public partial bool NotificationIsVisible { get; set; } // Automatically call the NotificationView property with OnPropertyChanged()
[ObservableProperty]
public partial string NotificationText { get; set; } // Automatically call the NotificationText property with OnPropertyChanged()
private bool _isLoaded; private bool _isLoaded;
private static readonly InputConfigJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions()); private static readonly InputConfigJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
public IGamepadDriver AvaloniaKeyboardDriver { get; } public IGamepadDriver AvaloniaKeyboardDriver { get; }
private IGamepad _selectedGamepad;
public IGamepad SelectedGamepad public IGamepad SelectedGamepad
{ {
get => _selectedGamepad; get;
private set private set
{ {
Rainbow.Reset(); Rainbow.Reset();
_selectedGamepad = value; field = value;
if (ConfigViewModel is ControllerInputViewModel { Config.UseRainbowLed: true }) if (ConfigViewModel is ControllerInputViewModel { Config.UseRainbowLed: true })
Rainbow.Updated += (ref Color color) => _selectedGamepad.SetLed((uint)color.ToArgb()); Rainbow.Updated += (ref Color color) => field.SetLed((uint)color.ToArgb());
OnPropertiesChanged(nameof(HasLed), nameof(CanClearLed)); OnPropertiesChanged(nameof(HasLed), nameof(CanClearLed));
} }
} }
public StickVisualizer VisualStick { get; private set; } public StickVisualizer VisualStick { get; private set; }
public ObservableCollection<PlayerModel> PlayerIndexes { get; set; } public ObservableCollection<PlayerModel> PlayerIndexes { get; set; }
@ -99,15 +104,15 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public bool CanClearLed => SelectedGamepad.Name.ContainsIgnoreCase("DualSense"); public bool CanClearLed => SelectedGamepad.Name.ContainsIgnoreCase("DualSense");
public event Action NotifyChangesEvent; public event Action NotifyChangesEvent;
public string ChosenProfile public string ChosenProfile
{ {
get => _chosenProfile; get;
set set
{ {
// When you select a profile, the settings from the profile will be applied. // When you select a profile, the settings from the profile will be applied.
// To save the settings, you still need to click the apply button // To save the settings, you still need to click the apply button
_chosenProfile = value; field = value;
LoadProfile(); LoadProfile();
OnPropertyChanged(); OnPropertyChanged();
} }
@ -115,10 +120,10 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public object ConfigViewModel public object ConfigViewModel
{ {
get => _configViewModel; get;
set set
{ {
_configViewModel = value; field = value;
VisualStick.UpdateConfig(value); VisualStick.UpdateConfig(value);

View File

@ -6,49 +6,45 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
{ {
public partial class KeyboardInputViewModel : BaseModel public partial class KeyboardInputViewModel : BaseModel
{ {
private KeyboardInputConfig _config;
public KeyboardInputConfig Config public KeyboardInputConfig Config
{ {
get => _config; get;
set set
{ {
_config = value; field = value;
OnPropertyChanged(); OnPropertyChanged();
} }
} }
private StickVisualizer _visualizer;
public StickVisualizer Visualizer public StickVisualizer Visualizer
{ {
get => _visualizer; get;
set set
{ {
_visualizer = value; field = value;
OnPropertyChanged(); OnPropertyChanged();
} }
} }
private bool _isLeft;
public bool IsLeft public bool IsLeft
{ {
get => _isLeft; get;
set set
{ {
_isLeft = value; field = value;
OnPropertyChanged(); OnPropertyChanged();
OnPropertyChanged(nameof(HasSides)); OnPropertyChanged(nameof(HasSides));
} }
} }
private bool _isRight;
public bool IsRight public bool IsRight
{ {
get => _isRight; get;
set set
{ {
_isRight = value; field = value;
OnPropertyChanged(); OnPropertyChanged();
OnPropertyChanged(nameof(HasSides)); OnPropertyChanged(nameof(HasSides));
} }
@ -56,7 +52,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public bool HasSides => IsLeft ^ IsRight; public bool HasSides => IsLeft ^ IsRight;
[ObservableProperty] private SvgImage _image; [ObservableProperty]
public partial SvgImage Image { get; set; }
public readonly InputViewModel ParentModel; public readonly InputViewModel ParentModel;

View File

@ -23,8 +23,11 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
ParentModel.SelectedGamepad.SetLed(LedColor.ToUInt32()); ParentModel.SelectedGamepad.SetLed(LedColor.ToUInt32());
}); });
[ObservableProperty] private bool _enableLedChanging; [ObservableProperty]
[ObservableProperty] private Color _ledColor; public partial bool EnableLedChanging { get; set; }
[ObservableProperty]
public partial Color LedColor { get; set; }
public string RainbowSpeedText => RainbowSpeed.ToString(CultureInfo.CurrentCulture).Truncate(4, string.Empty); public string RainbowSpeedText => RainbowSpeed.ToString(CultureInfo.CurrentCulture).Truncate(4, string.Empty);
@ -41,27 +44,23 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public bool ShowLedColorPicker => !TurnOffLed && !UseRainbowLed; public bool ShowLedColorPicker => !TurnOffLed && !UseRainbowLed;
private bool _turnOffLed;
public bool TurnOffLed public bool TurnOffLed
{ {
get => _turnOffLed; get;
set set
{ {
_turnOffLed = value; field = value;
OnPropertyChanged(); OnPropertyChanged();
OnPropertyChanged(nameof(ShowLedColorPicker)); OnPropertyChanged(nameof(ShowLedColorPicker));
} }
} }
private bool _useRainbowLed;
public bool UseRainbowLed public bool UseRainbowLed
{ {
get => _useRainbowLed; get;
set set
{ {
_useRainbowLed = value; field = value;
OnPropertyChanged(); OnPropertyChanged();
OnPropertyChanged(nameof(ShowLedColorPicker)); OnPropertyChanged(nameof(ShowLedColorPicker));
} }

View File

@ -4,20 +4,28 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
{ {
public partial class MotionInputViewModel : BaseModel public partial class MotionInputViewModel : BaseModel
{ {
[ObservableProperty] private int _slot; [ObservableProperty]
public partial int Slot { get; set; }
[ObservableProperty] private int _altSlot; [ObservableProperty]
public partial int AltSlot { get; set; }
[ObservableProperty] private string _dsuServerHost; [ObservableProperty]
public partial string DsuServerHost { get; set; }
[ObservableProperty] private int _dsuServerPort; [ObservableProperty]
public partial int DsuServerPort { get; set; }
[ObservableProperty] private bool _mirrorInput; [ObservableProperty]
public partial bool MirrorInput { get; set; }
[ObservableProperty] private int _sensitivity; [ObservableProperty]
public partial int Sensitivity { get; set; }
[ObservableProperty] private double _gyroDeadzone; [ObservableProperty]
public partial double GyroDeadzone { get; set; }
[ObservableProperty] private bool _enableCemuHookMotion; [ObservableProperty]
public partial bool EnableCemuHookMotion { get; set; }
} }
} }

View File

@ -4,8 +4,10 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
{ {
public partial class RumbleInputViewModel : BaseModel public partial class RumbleInputViewModel : BaseModel
{ {
[ObservableProperty] private float _strongRumble; [ObservableProperty]
public partial float StrongRumble { get; set; }
[ObservableProperty] private float _weakRumble; [ObservableProperty]
public partial float WeakRumble { get; set; }
} }
} }

View File

@ -91,10 +91,8 @@ namespace Ryujinx.Ava.UI.ViewModels
OnPropertyChanged(nameof(VisibleEntries)); OnPropertyChanged(nameof(VisibleEntries));
} }
[ObservableProperty] private bool _isRefreshing; [ObservableProperty]
private bool _onlyShowForOwnedGames; public partial bool IsRefreshing { get; set; }
private bool _onlyShowPublicGames = true;
private bool _onlyShowJoinableGames = true;
public async Task RefreshAsync() public async Task RefreshAsync()
{ {
@ -109,12 +107,12 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool OnlyShowForOwnedGames public bool OnlyShowForOwnedGames
{ {
get => _onlyShowForOwnedGames; get;
set set
{ {
OnPropertyChanging(); OnPropertyChanging();
OnPropertyChanging(nameof(VisibleEntries)); OnPropertyChanging(nameof(VisibleEntries));
_onlyShowForOwnedGames = value; field = value;
OnPropertyChanged(); OnPropertyChanged();
OnPropertyChanged(nameof(VisibleEntries)); OnPropertyChanged(nameof(VisibleEntries));
} }
@ -122,29 +120,29 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool OnlyShowPublicGames public bool OnlyShowPublicGames
{ {
get => _onlyShowPublicGames; get;
set set
{ {
OnPropertyChanging(); OnPropertyChanging();
OnPropertyChanging(nameof(VisibleEntries)); OnPropertyChanging(nameof(VisibleEntries));
_onlyShowPublicGames = value; field = value;
OnPropertyChanged(); OnPropertyChanged();
OnPropertyChanged(nameof(VisibleEntries)); OnPropertyChanged(nameof(VisibleEntries));
} }
} } = true;
public bool OnlyShowJoinableGames public bool OnlyShowJoinableGames
{ {
get => _onlyShowJoinableGames; get;
set set
{ {
OnPropertyChanging(); OnPropertyChanging();
OnPropertyChanging(nameof(VisibleEntries)); OnPropertyChanging(nameof(VisibleEntries));
_onlyShowJoinableGames = value; field = value;
OnPropertyChanged(); OnPropertyChanged();
OnPropertyChanged(nameof(VisibleEntries)); OnPropertyChanged(nameof(VisibleEntries));
} }
} } = true;
public void NameSorting(int nameSort = 0) public void NameSorting(int nameSort = 0)

View File

@ -24,9 +24,11 @@ namespace Ryujinx.Ava.UI.ViewModels
{ {
private readonly string _modJsonPath; private readonly string _modJsonPath;
private AvaloniaList<ModModel> _mods = []; [ObservableProperty]
[ObservableProperty] private AvaloniaList<ModModel> _views = []; public partial AvaloniaList<ModModel> Views { get; set; } = [];
[ObservableProperty] private AvaloniaList<ModModel> _selectedMods = [];
[ObservableProperty]
public partial AvaloniaList<ModModel> SelectedMods { get; set; } = [];
private string _search; private string _search;
private readonly ulong _applicationId; private readonly ulong _applicationId;
@ -37,15 +39,15 @@ namespace Ryujinx.Ava.UI.ViewModels
public AvaloniaList<ModModel> Mods public AvaloniaList<ModModel> Mods
{ {
get => _mods; get;
set set
{ {
_mods = value; field = value;
OnPropertyChanged(); OnPropertyChanged();
OnPropertyChanged(nameof(ModCount)); OnPropertyChanged(nameof(ModCount));
Sort(); Sort();
} }
} } = [];
public string Search public string Search
{ {
@ -58,10 +60,7 @@ namespace Ryujinx.Ava.UI.ViewModels
} }
} }
public string ModCount public string ModCount => string.Format(LocaleManager.Instance[LocaleKeys.ModWindowHeading], Mods.Count);
{
get => string.Format(LocaleManager.Instance[LocaleKeys.ModWindowHeading], Mods.Count);
}
public ModManagerViewModel(ulong applicationId, ulong applicationIdBase, ApplicationLibrary appLibrary) public ModManagerViewModel(ulong applicationId, ulong applicationIdBase, ApplicationLibrary appLibrary)
{ {

View File

@ -7,8 +7,10 @@ namespace Ryujinx.Ava.UI.ViewModels
public partial class ProfileSelectorDialogViewModel : BaseModel public partial class ProfileSelectorDialogViewModel : BaseModel
{ {
[ObservableProperty] private UserId _selectedUserId; [ObservableProperty]
public partial UserId SelectedUserId { get; set; }
[ObservableProperty] private ObservableCollection<BaseModel> _profiles = []; [ObservableProperty]
public partial ObservableCollection<BaseModel> Profiles { get; set; } = [];
} }
} }

View File

@ -15,9 +15,13 @@ namespace Ryujinx.Ava.UI.ViewModels
_baseViewModel = settingsVm; _baseViewModel = settingsVm;
} }
[ObservableProperty] private bool _xc2MenuSoftlockFix = ConfigurationState.Instance.Hacks.Xc2MenuSoftlockFix; [ObservableProperty]
[ObservableProperty] private bool _nifmDisableIsAnyInternetRequestAccepted = ConfigurationState.Instance.Hacks.DisableNifmIsAnyInternetRequestAccepted; public partial bool Xc2MenuSoftlockFix { get; set; } = ConfigurationState.Instance.Hacks.Xc2MenuSoftlockFix;
[ObservableProperty]
public partial bool NifmDisableIsAnyInternetRequestAccepted { get; set; } = ConfigurationState.Instance.Hacks.DisableNifmIsAnyInternetRequestAccepted;
public static string Xc2MenuFixTooltip { get; } = Lambda.String(sb => public static string Xc2MenuFixTooltip { get; } = Lambda.String(sb =>
{ {
sb.AppendLine( sb.AppendLine(

View File

@ -53,7 +53,7 @@ namespace Ryujinx.Ava.UI.ViewModels
[ObservableProperty] private bool _isVulkanAvailable = true; [ObservableProperty] private bool _isVulkanAvailable = true;
[ObservableProperty] private bool _gameListNeedsRefresh; [ObservableProperty] private bool _gameListNeedsRefresh;
private readonly List<string> _gpuIds = []; private readonly List<string> _gpuIds = [];
public bool _useInputGlobalConfig; private bool _useInputGlobalConfig;
private int _graphicsBackendIndex; private int _graphicsBackendIndex;
private int _scalingFilter; private int _scalingFilter;
private int _scalingFilterLevel; private int _scalingFilterLevel;

View File

@ -21,10 +21,17 @@ namespace Ryujinx.Ava.UI.ViewModels
private ApplicationLibrary ApplicationLibrary { get; } private ApplicationLibrary ApplicationLibrary { get; }
private ApplicationData ApplicationData { get; } private ApplicationData ApplicationData { get; }
[ObservableProperty] private AvaloniaList<TitleUpdateModel> _titleUpdates = []; [ObservableProperty]
[ObservableProperty] private AvaloniaList<object> _views = []; public partial AvaloniaList<TitleUpdateModel> TitleUpdates { get; set; } = [];
[ObservableProperty] private object _selectedUpdate = new TitleUpdateViewModelNoUpdate();
[ObservableProperty] private bool _showBundledContentNotice; [ObservableProperty]
public partial AvaloniaList<object> Views { get; set; } = [];
[ObservableProperty]
public partial object SelectedUpdate { get; set; } = new TitleUpdateViewModelNoUpdate();
[ObservableProperty]
public partial bool ShowBundledContentNotice { get; set; }
private readonly IStorageProvider _storageProvider; private readonly IStorageProvider _storageProvider;

View File

@ -25,14 +25,15 @@ namespace Ryujinx.Ava.UI.ViewModels
{ {
private static readonly Dictionary<string, byte[]> _avatarStore = new(); private static readonly Dictionary<string, byte[]> _avatarStore = new();
[ObservableProperty] private ObservableCollection<ProfileImageModel> _images; [ObservableProperty]
[ObservableProperty] private Color _backgroundColor = Colors.White; public partial ObservableCollection<ProfileImageModel> Images { get; set; }
private int _selectedIndex; [ObservableProperty]
public partial Color BackgroundColor { get; set; } = Colors.White;
public UserFirmwareAvatarSelectorViewModel() public UserFirmwareAvatarSelectorViewModel()
{ {
_images = []; Images = [];
LoadImagesFromStore(); LoadImagesFromStore();
PropertyChanged += (_, args) => PropertyChanged += (_, args) =>
@ -44,21 +45,17 @@ namespace Ryujinx.Ava.UI.ViewModels
public int SelectedIndex public int SelectedIndex
{ {
get => _selectedIndex; get;
set set
{ {
_selectedIndex = value; field = value;
if (_selectedIndex == -1) SelectedImage = field == -1
{ ? null
SelectedImage = null; : Images[field].Data;
}
else
{
SelectedImage = Images[_selectedIndex].Data;
}
OnPropertyChanged(); OnPropertyChanged();
OnPropertyChanged(nameof(SelectedImage));
} }
} }

View File

@ -4,6 +4,7 @@ namespace Ryujinx.Ava.UI.ViewModels
{ {
public partial class UserProfileImageSelectorViewModel : BaseModel public partial class UserProfileImageSelectorViewModel : BaseModel
{ {
[ObservableProperty] private bool _firmwareFound; [ObservableProperty]
public partial bool FirmwareFound { get; set; }
} }
} }

View File

@ -10,11 +10,21 @@ namespace Ryujinx.Ava.UI.ViewModels
{ {
public partial class UserSaveManagerViewModel : BaseModel public partial class UserSaveManagerViewModel : BaseModel
{ {
[ObservableProperty] private int _sortIndex; [ObservableProperty]
[ObservableProperty] private int _orderIndex; public partial int SortIndex { get; set; }
[ObservableProperty] private string _search;
[ObservableProperty] private ObservableCollection<SaveModel> _saves = []; [ObservableProperty]
[ObservableProperty] private ObservableCollection<SaveModel> _views = []; public partial int OrderIndex { get; set; }
[ObservableProperty]
public partial string Search { get; set; }
[ObservableProperty]
public partial ObservableCollection<SaveModel> Saves { get; set; } = [];
[ObservableProperty]
public partial ObservableCollection<SaveModel> Views { get; set; } = [];
private readonly AccountManager _accountManager; private readonly AccountManager _accountManager;
public string SaveManagerHeading => LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SaveManagerHeading, _accountManager.LastOpenedUser.Name, _accountManager.LastOpenedUser.UserId); public string SaveManagerHeading => LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SaveManagerHeading, _accountManager.LastOpenedUser.Name, _accountManager.LastOpenedUser.UserId);

View File

@ -18,7 +18,8 @@ namespace Ryujinx.Ava.UI.ViewModels
{ {
public class XciTrimmerViewModel : BaseModel public class XciTrimmerViewModel : BaseModel
{ {
private const long _bytesPerMB = 1024 * 1024; private const long BytesPerMb = 1024 * 1024;
private enum ProcessingMode private enum ProcessingMode
{ {
Trimming, Trimming,
@ -44,7 +45,6 @@ namespace Ryujinx.Ava.UI.ViewModels
private string _search; private string _search;
private ProcessingMode _processingMode; private ProcessingMode _processingMode;
private SortField _sortField = SortField.Name; private SortField _sortField = SortField.Name;
private bool _sortAscending = true;
public XciTrimmerViewModel(MainWindowViewModel mainWindowViewModel) public XciTrimmerViewModel(MainWindowViewModel mainWindowViewModel)
{ {
@ -472,15 +472,16 @@ namespace Ryujinx.Ava.UI.ViewModels
}; };
} }
} }
public bool SortingAscending public bool SortingAscending
{ {
get => _sortAscending; get;
set set
{ {
_sortAscending = value; field = value;
SortingChanged(); SortingChanged();
} }
} } = true;
public bool IsSortedByName public bool IsSortedByName
{ {
@ -516,7 +517,7 @@ namespace Ryujinx.Ava.UI.ViewModels
{ {
get get
{ {
return string.Format(LocaleManager.Instance[LocaleKeys.XCITrimmerSavingsMb], AllXCIFiles.Sum(xci => xci.PotentialSavingsB / _bytesPerMB)); return string.Format(LocaleManager.Instance[LocaleKeys.XCITrimmerSavingsMb], AllXCIFiles.Sum(xci => xci.PotentialSavingsB / BytesPerMb));
} }
} }
@ -524,7 +525,7 @@ namespace Ryujinx.Ava.UI.ViewModels
{ {
get get
{ {
return string.Format(LocaleManager.Instance[LocaleKeys.XCITrimmerSavingsMb], AllXCIFiles.Sum(xci => xci.CurrentSavingsB / _bytesPerMB)); return string.Format(LocaleManager.Instance[LocaleKeys.XCITrimmerSavingsMb], AllXCIFiles.Sum(xci => xci.CurrentSavingsB / BytesPerMb));
} }
} }