Merge branch 'master' into xeyes

This commit is contained in:
Evan Husted
2025-01-26 17:33:58 -06:00
committed by GitHub
527 changed files with 7960 additions and 6917 deletions

View File

@@ -172,7 +172,7 @@ namespace Ryujinx.Ava.UI.Applet
try
{
_parent.ViewModel.AppHost.NpadManager.BlockInputUpdates();
SoftwareKeyboardUIArgs args = new SoftwareKeyboardUIArgs();
SoftwareKeyboardUIArgs args = new();
args.KeyboardMode = KeyboardMode.Default;
args.InitialText = "Ryujinx";
args.StringLengthMin = 1;
@@ -264,7 +264,7 @@ namespace Ryujinx.Ava.UI.Applet
{
UserId selected = UserId.Null;
byte[] defaultGuestImage = EmbeddedResources.Read("Ryujinx.HLE/HOS/Services/Account/Acc/GuestUserImage.jpg");
UserProfile guest = new UserProfile(new UserId("00000000000000000000000000000080"), "Guest", defaultGuestImage);
UserProfile guest = new(new UserId("00000000000000000000000000000080"), "Guest", defaultGuestImage);
ManualResetEvent dialogCloseEvent = new(false);

View File

@@ -64,7 +64,7 @@ namespace Ryujinx.Ava.UI.Applet
{
if (item is UserProfile originalItem)
{
UserProfileSft profile = new UserProfileSft(originalItem.UserId, originalItem.Name, originalItem.Image);
UserProfileSft profile = new(originalItem.UserId, originalItem.Name, originalItem.Image);
if (profile.UserId == ViewModel.SelectedUserId)
{

View File

@@ -146,7 +146,7 @@ namespace Ryujinx.Ava.UI.Controls
DirectoryInfo mainDir = new(Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.IdString, "cache", "cpu", "0"));
DirectoryInfo backupDir = new(Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.IdString, "cache", "cpu", "1"));
List<FileInfo> cacheFiles = new();
List<FileInfo> cacheFiles = [];
if (mainDir.Exists)
{
@@ -189,8 +189,8 @@ namespace Ryujinx.Ava.UI.Controls
{
DirectoryInfo shaderCacheDir = new(Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.IdString, "cache", "shader"));
List<DirectoryInfo> oldCacheDirectories = new();
List<FileInfo> newCacheFiles = new();
List<DirectoryInfo> oldCacheDirectories = [];
List<FileInfo> newCacheFiles = [];
if (shaderCacheDir.Exists)
{

View File

@@ -108,13 +108,13 @@ namespace Ryujinx.Ava.UI.Controls
SaveDataFilter saveDataFilter = SaveDataFilter.Make(programId: default, saveType: SaveDataType.Account, default, saveDataId: default, index: default);
using UniqueRef<SaveDataIterator> saveDataIterator = new UniqueRef<SaveDataIterator>();
using UniqueRef<SaveDataIterator> saveDataIterator = new();
HorizonClient.Fs.OpenSaveDataIterator(ref saveDataIterator.Ref, SaveDataSpaceId.User, in saveDataFilter).ThrowIfFailure();
Span<SaveDataInfo> saveDataInfo = stackalloc SaveDataInfo[10];
HashSet<UserId> lostAccounts = new();
HashSet<UserId> lostAccounts = [];
while (true)
{
@@ -128,7 +128,7 @@ namespace Ryujinx.Ava.UI.Controls
for (int i = 0; i < readCount; i++)
{
SaveDataInfo save = saveDataInfo[i];
UserId id = new UserId((long)save.UserId.Id.Low, (long)save.UserId.Id.High);
UserId id = new((long)save.UserId.Id.Low, (long)save.UserId.Id.High);
if (ViewModel.Profiles.Cast<UserProfile>().FirstOrDefault(x => x.UserId == id) == null)
{
lostAccounts.Add(id);

View File

@@ -50,8 +50,8 @@ namespace Ryujinx.Ava.UI.Helpers
private static string Format(AvaLogLevel level, string area, string template, object source, object[] v)
{
StringBuilder result = new StringBuilder();
CharacterReader r = new CharacterReader(template.AsSpan());
StringBuilder result = new();
CharacterReader r = new(template.AsSpan());
int i = 0;
result.Append('[');

View File

@@ -28,7 +28,7 @@ namespace Ryujinx.Ava.UI.Helpers
Margin = new Thickness(0, 0, 15, 40),
};
Lazy<AsyncWorkQueue<Notification>> maybeAsyncWorkQueue = new Lazy<AsyncWorkQueue<Notification>>(
Lazy<AsyncWorkQueue<Notification>> maybeAsyncWorkQueue = new(
() => new AsyncWorkQueue<Notification>(notification =>
{
Dispatcher.UIThread.Post(() =>

View File

@@ -8,7 +8,7 @@ namespace Ryujinx.Ava.UI.Models
public class CheatNode : BaseModel
{
private bool _isEnabled = false;
public ObservableCollection<CheatNode> SubNodes { get; } = new();
public ObservableCollection<CheatNode> SubNodes { get; } = [];
public string CleanName => Name[1..^7];
public string BuildIdKey => $"{BuildId}-{Name}";
public bool IsRootNode { get; }

View File

@@ -367,7 +367,7 @@ namespace Ryujinx.Ava.UI.Models.Input
public InputConfig GetConfig()
{
StandardKeyboardInputConfig config = new StandardKeyboardInputConfig
StandardKeyboardInputConfig config = new()
{
Id = Id,
Backend = InputBackendType.WindowKeyboard,

View File

@@ -64,9 +64,9 @@ namespace Ryujinx.Ava.UI.ViewModels
Directory.CreateDirectory(Path.Join(AppDataManager.BaseDirPath, "system", "amiibo"));
_amiiboJsonPath = Path.Join(AppDataManager.BaseDirPath, "system", "amiibo", "Amiibo.json");
_amiiboList = new List<AmiiboApi>();
_amiiboSeries = new ObservableCollection<string>();
_amiibos = new AvaloniaList<AmiiboApi>();
_amiiboList = [];
_amiiboSeries = [];
_amiibos = [];
_amiiboLogoBytes = EmbeddedResources.Read("Ryujinx/Assets/UIImages/Logo_Amiibo.png");

View File

@@ -22,9 +22,9 @@ namespace Ryujinx.Ava.UI.ViewModels
public partial class DownloadableContentManagerViewModel : BaseModel
{
private readonly ApplicationLibrary _applicationLibrary;
private AvaloniaList<DownloadableContentModel> _downloadableContents = new();
[ObservableProperty] private AvaloniaList<DownloadableContentModel> _selectedDownloadableContents = new();
[ObservableProperty] private AvaloniaList<DownloadableContentModel> _views = new();
private AvaloniaList<DownloadableContentModel> _downloadableContents = [];
[ObservableProperty] private AvaloniaList<DownloadableContentModel> _selectedDownloadableContents = [];
[ObservableProperty] private AvaloniaList<DownloadableContentModel> _views = [];
[ObservableProperty] private bool _showBundledContentNotice = false;
private string _search;
@@ -139,9 +139,9 @@ namespace Ryujinx.Ava.UI.ViewModels
{
new("NSP")
{
Patterns = new[] { "*.nsp" },
AppleUniformTypeIdentifiers = new[] { "com.ryujinx.nsp" },
MimeTypes = new[] { "application/x-nx-nsp" },
Patterns = ["*.nsp"],
AppleUniformTypeIdentifiers = ["com.ryujinx.nsp"],
MimeTypes = ["application/x-nx-nsp"],
},
},
});

View File

@@ -6,6 +6,7 @@ using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.Input;
using Ryujinx.Ava.UI.Models.Input;
using Ryujinx.Ava.UI.Views.Input;
using Ryujinx.UI.Views.Input;
namespace Ryujinx.Ava.UI.ViewModels.Input
{
@@ -84,15 +85,10 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
await RumbleInputView.Show(this);
}
public RelayCommand LedDisabledChanged => Commands.Create(() =>
public async void ShowLedConfig()
{
if (!Config.EnableLedChanging) return;
if (Config.TurnOffLed)
ParentModel.SelectedGamepad.ClearLed();
else
ParentModel.SelectedGamepad.SetLed(Config.LedColor.ToUInt32());
});
await LedInputView.Show(this);
}
public void OnParentModelChanged()
{

View File

@@ -271,11 +271,11 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public InputViewModel()
{
PlayerIndexes = new ObservableCollection<PlayerModel>();
Controllers = new ObservableCollection<ControllerModel>();
Devices = new ObservableCollection<(DeviceType Type, string Id, string Name)>();
ProfilesList = new AvaloniaList<string>();
DeviceList = new AvaloniaList<string>();
PlayerIndexes = [];
Controllers = [];
Devices = [];
ProfilesList = [];
DeviceList = [];
VisualStick = new StickVisualizer(this);
ControllerImage = ProControllerResource;
@@ -825,7 +825,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
{
IsModified = false;
List<InputConfig> newConfig = new();
List<InputConfig> newConfig = [];
newConfig.AddRange(ConfigurationState.Instance.Hid.InputConfig.Value);

View File

@@ -0,0 +1,53 @@
using Avalonia.Media;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Ryujinx.Ava.UI.Helpers;
namespace Ryujinx.Ava.UI.ViewModels.Input
{
public partial class LedInputViewModel : BaseModel
{
public required InputViewModel ParentModel { get; init; }
public RelayCommand LedDisabledChanged => Commands.Create(() =>
{
if (!EnableLedChanging) return;
if (TurnOffLed)
ParentModel.SelectedGamepad.ClearLed();
else
ParentModel.SelectedGamepad.SetLed(LedColor.ToUInt32());
});
[ObservableProperty] private bool _enableLedChanging;
[ObservableProperty] private Color _ledColor;
public bool ShowLedColorPicker => !TurnOffLed && !UseRainbowLed;
private bool _turnOffLed;
public bool TurnOffLed
{
get => _turnOffLed;
set
{
_turnOffLed = value;
OnPropertyChanged();
OnPropertyChanged(nameof(ShowLedColorPicker));
}
}
private bool _useRainbowLed;
public bool UseRainbowLed
{
get => _useRainbowLed;
set
{
_useRainbowLed = value;
OnPropertyChanged();
OnPropertyChanged(nameof(ShowLedColorPicker));
}
}
}
}

View File

@@ -1245,21 +1245,21 @@ namespace Ryujinx.Ava.UI.ViewModels
{
new(LocaleManager.Instance[LocaleKeys.FileDialogAllTypes])
{
Patterns = new[] { "*.xci", "*.zip" },
AppleUniformTypeIdentifiers = new[] { "com.ryujinx.xci", "public.zip-archive" },
MimeTypes = new[] { "application/x-nx-xci", "application/zip" },
Patterns = ["*.xci", "*.zip"],
AppleUniformTypeIdentifiers = ["com.ryujinx.xci", "public.zip-archive"],
MimeTypes = ["application/x-nx-xci", "application/zip"],
},
new("XCI")
{
Patterns = new[] { "*.xci" },
AppleUniformTypeIdentifiers = new[] { "com.ryujinx.xci" },
MimeTypes = new[] { "application/x-nx-xci" },
Patterns = ["*.xci"],
AppleUniformTypeIdentifiers = ["com.ryujinx.xci"],
MimeTypes = ["application/x-nx-xci"],
},
new("ZIP")
{
Patterns = new[] { "*.zip" },
AppleUniformTypeIdentifiers = new[] { "public.zip-archive" },
MimeTypes = new[] { "application/zip" },
Patterns = ["*.zip"],
AppleUniformTypeIdentifiers = ["public.zip-archive"],
MimeTypes = ["application/zip"],
},
},
});
@@ -1292,21 +1292,21 @@ namespace Ryujinx.Ava.UI.ViewModels
{
new(LocaleManager.Instance[LocaleKeys.FileDialogAllTypes])
{
Patterns = new[] { "*.keys", "*.zip" },
AppleUniformTypeIdentifiers = new[] { "com.ryujinx.xci", "public.zip-archive" },
MimeTypes = new[] { "application/keys", "application/zip" },
Patterns = ["*.keys", "*.zip"],
AppleUniformTypeIdentifiers = ["com.ryujinx.xci", "public.zip-archive"],
MimeTypes = ["application/keys", "application/zip"],
},
new("KEYS")
{
Patterns = new[] { "*.keys" },
AppleUniformTypeIdentifiers = new[] { "com.ryujinx.xci" },
MimeTypes = new[] { "application/keys" },
Patterns = ["*.keys"],
AppleUniformTypeIdentifiers = ["com.ryujinx.xci"],
MimeTypes = ["application/keys"],
},
new("ZIP")
{
Patterns = new[] { "*.zip" },
AppleUniformTypeIdentifiers = new[] { "public.zip-archive" },
MimeTypes = new[] { "application/zip" },
Patterns = ["*.zip"],
AppleUniformTypeIdentifiers = ["public.zip-archive"],
MimeTypes = ["application/zip"],
},
},
});
@@ -1418,53 +1418,53 @@ namespace Ryujinx.Ava.UI.ViewModels
{
new(LocaleManager.Instance[LocaleKeys.AllSupportedFormats])
{
Patterns = new[] { "*.nsp", "*.xci", "*.nca", "*.nro", "*.nso" },
AppleUniformTypeIdentifiers = new[]
{
Patterns = ["*.nsp", "*.xci", "*.nca", "*.nro", "*.nso"],
AppleUniformTypeIdentifiers =
[
"com.ryujinx.nsp",
"com.ryujinx.xci",
"com.ryujinx.nca",
"com.ryujinx.nro",
"com.ryujinx.nso",
},
MimeTypes = new[]
{
"com.ryujinx.nso"
],
MimeTypes =
[
"application/x-nx-nsp",
"application/x-nx-xci",
"application/x-nx-nca",
"application/x-nx-nro",
"application/x-nx-nso",
},
"application/x-nx-nso"
],
},
new("NSP")
{
Patterns = new[] { "*.nsp" },
AppleUniformTypeIdentifiers = new[] { "com.ryujinx.nsp" },
MimeTypes = new[] { "application/x-nx-nsp" },
Patterns = ["*.nsp"],
AppleUniformTypeIdentifiers = ["com.ryujinx.nsp"],
MimeTypes = ["application/x-nx-nsp"],
},
new("XCI")
{
Patterns = new[] { "*.xci" },
AppleUniformTypeIdentifiers = new[] { "com.ryujinx.xci" },
MimeTypes = new[] { "application/x-nx-xci" },
Patterns = ["*.xci"],
AppleUniformTypeIdentifiers = ["com.ryujinx.xci"],
MimeTypes = ["application/x-nx-xci"],
},
new("NCA")
{
Patterns = new[] { "*.nca" },
AppleUniformTypeIdentifiers = new[] { "com.ryujinx.nca" },
MimeTypes = new[] { "application/x-nx-nca" },
Patterns = ["*.nca"],
AppleUniformTypeIdentifiers = ["com.ryujinx.nca"],
MimeTypes = ["application/x-nx-nca"],
},
new("NRO")
{
Patterns = new[] { "*.nro" },
AppleUniformTypeIdentifiers = new[] { "com.ryujinx.nro" },
MimeTypes = new[] { "application/x-nx-nro" },
Patterns = ["*.nro"],
AppleUniformTypeIdentifiers = ["com.ryujinx.nro"],
MimeTypes = ["application/x-nx-nro"],
},
new("NSO")
{
Patterns = new[] { "*.nso" },
AppleUniformTypeIdentifiers = new[] { "com.ryujinx.nso" },
MimeTypes = new[] { "application/x-nx-nso" },
Patterns = ["*.nso"],
AppleUniformTypeIdentifiers = ["com.ryujinx.nso"],
MimeTypes = ["application/x-nx-nso"],
},
},
});
@@ -1690,7 +1690,7 @@ namespace Ryujinx.Ava.UI.ViewModels
{
new(LocaleManager.Instance[LocaleKeys.AllSupportedFormats])
{
Patterns = new[] { "*.bin" },
Patterns = ["*.bin"],
}
}
});
@@ -1802,7 +1802,7 @@ namespace Ryujinx.Ava.UI.ViewModels
return;
}
XCIFileTrimmer trimmer = new XCIFileTrimmer(filename, new XCITrimmerLog.MainWindow(this));
XCIFileTrimmer trimmer = new(filename, new XCITrimmerLog.MainWindow(this));
if (trimmer.CanBeTrimmed)
{

View File

@@ -23,9 +23,9 @@ namespace Ryujinx.Ava.UI.ViewModels
{
private readonly string _modJsonPath;
private AvaloniaList<ModModel> _mods = new();
[ObservableProperty] private AvaloniaList<ModModel> _views = new();
[ObservableProperty] private AvaloniaList<ModModel> _selectedMods = new();
private AvaloniaList<ModModel> _mods = [];
[ObservableProperty] private AvaloniaList<ModModel> _views = [];
[ObservableProperty] private AvaloniaList<ModModel> _selectedMods = [];
private string _search;
private readonly ulong _applicationId;
@@ -82,13 +82,13 @@ namespace Ryujinx.Ava.UI.ViewModels
foreach (string path in modsBasePaths)
{
bool inSd = path == ModLoader.GetSdModsBasePath();
ModLoader.ModCache modCache = new ModLoader.ModCache();
ModLoader.ModCache modCache = new();
ModLoader.QueryContentsDir(modCache, new DirectoryInfo(Path.Combine(path, "contents")), applicationId);
foreach (ModLoader.Mod<DirectoryInfo> mod in modCache.RomfsDirs)
{
ModModel modModel = new ModModel(mod.Path.Parent.FullName, mod.Name, mod.Enabled, inSd);
ModModel modModel = new(mod.Path.Parent.FullName, mod.Name, mod.Enabled, inSd);
if (Mods.All(x => x.Path != mod.Path.Parent.FullName))
{
Mods.Add(modModel);
@@ -102,7 +102,7 @@ namespace Ryujinx.Ava.UI.ViewModels
foreach (ModLoader.Mod<DirectoryInfo> mod in modCache.ExefsDirs)
{
ModModel modModel = new ModModel(mod.Path.Parent.FullName, mod.Name, mod.Enabled, inSd);
ModModel modModel = new(mod.Path.Parent.FullName, mod.Name, mod.Enabled, inSd);
if (Mods.All(x => x.Path != mod.Path.Parent.FullName))
{
Mods.Add(modModel);

View File

@@ -51,7 +51,7 @@ namespace Ryujinx.Ava.UI.ViewModels
[ObservableProperty] private bool _isVulkanAvailable = true;
[ObservableProperty] private bool _gameDirectoryChanged;
[ObservableProperty] private bool _autoloadDirectoryChanged;
private readonly List<string> _gpuIds = new();
private readonly List<string> _gpuIds = [];
private int _graphicsBackendIndex;
private int _scalingFilter;
private int _scalingFilterLevel;

View File

@@ -21,8 +21,8 @@ namespace Ryujinx.Ava.UI.ViewModels
private ApplicationLibrary ApplicationLibrary { get; }
private ApplicationData ApplicationData { get; }
[ObservableProperty] private AvaloniaList<TitleUpdateModel> _titleUpdates = new();
[ObservableProperty] private AvaloniaList<object> _views = new();
[ObservableProperty] private AvaloniaList<TitleUpdateModel> _titleUpdates = [];
[ObservableProperty] private AvaloniaList<object> _views = [];
[ObservableProperty] private object _selectedUpdate = new TitleUpdateViewModelNoUpdate();
[ObservableProperty] private bool _showBundledContentNotice;
@@ -149,9 +149,9 @@ namespace Ryujinx.Ava.UI.ViewModels
{
new(LocaleManager.Instance[LocaleKeys.AllSupportedFormats])
{
Patterns = new[] { "*.nsp" },
AppleUniformTypeIdentifiers = new[] { "com.ryujinx.nsp" },
MimeTypes = new[] { "application/x-nx-nsp" },
Patterns = ["*.nsp"],
AppleUniformTypeIdentifiers = ["com.ryujinx.nsp"],
MimeTypes = ["application/x-nx-nsp"],
},
},
});

View File

@@ -32,7 +32,7 @@ namespace Ryujinx.Ava.UI.ViewModels
public UserFirmwareAvatarSelectorViewModel()
{
_images = new ObservableCollection<ProfileImageModel>();
_images = [];
LoadImagesFromStore();
PropertyChanged += (_, args) =>
@@ -104,7 +104,7 @@ namespace Ryujinx.Ava.UI.ViewModels
// TODO: Parse DatabaseInfo.bin and table.bin files for more accuracy.
if (item.Type == DirectoryEntryType.File && item.FullPath.Contains("chara") && item.FullPath.Contains("szs"))
{
using UniqueRef<IFile> file = new UniqueRef<IFile>();
using UniqueRef<IFile> file = new();
romfs.OpenFile(ref file.Ref, ("/" + item.FullPath).ToU8Span(), OpenMode.Read).ThrowIfFailure();

View File

@@ -9,8 +9,8 @@ namespace Ryujinx.Ava.UI.ViewModels
{
public UserProfileViewModel()
{
Profiles = new ObservableCollection<BaseModel>();
LostProfiles = new ObservableCollection<UserProfile>();
Profiles = [];
LostProfiles = [];
IsEmpty = !LostProfiles.Any();
}

View File

@@ -14,8 +14,8 @@ namespace Ryujinx.Ava.UI.ViewModels
[ObservableProperty] private int _sortIndex;
[ObservableProperty] private int _orderIndex;
[ObservableProperty] private string _search;
[ObservableProperty] private ObservableCollection<SaveModel> _saves = new();
[ObservableProperty] private ObservableCollection<SaveModel> _views = new();
[ObservableProperty] private ObservableCollection<SaveModel> _saves = [];
[ObservableProperty] private ObservableCollection<SaveModel> _views = [];
private readonly AccountManager _accountManager;
public string SaveManagerHeading => LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SaveManagerHeading, _accountManager.LastOpenedUser.Name, _accountManager.LastOpenedUser.UserId);

View File

@@ -36,9 +36,9 @@ namespace Ryujinx.Ava.UI.ViewModels
private readonly Ryujinx.Common.Logging.XCIFileTrimmerLog _logger;
private ApplicationLibrary ApplicationLibrary => _mainWindowViewModel.ApplicationLibrary;
private Optional<XCITrimmerFileModel> _processingApplication = null;
private AvaloniaList<XCITrimmerFileModel> _allXCIFiles = new();
private AvaloniaList<XCITrimmerFileModel> _selectedXCIFiles = new();
private AvaloniaList<XCITrimmerFileModel> _displayedXCIFiles = new();
private AvaloniaList<XCITrimmerFileModel> _allXCIFiles = [];
private AvaloniaList<XCITrimmerFileModel> _selectedXCIFiles = [];
private AvaloniaList<XCITrimmerFileModel> _displayedXCIFiles = [];
private MainWindowViewModel _mainWindowViewModel;
private CancellationTokenSource _cancellationTokenSource;
private string _search;
@@ -183,7 +183,7 @@ namespace Ryujinx.Ava.UI.ViewModels
if (cancellationToken.IsCancellationRequested)
break;
XCIFileTrimmer trimmer = new XCIFileTrimmer(xciApp.Path, _logger);
XCIFileTrimmer trimmer = new(xciApp.Path, _logger);
Dispatcher.UIThread.Post(() =>
{

View File

@@ -581,8 +581,6 @@
Margin="0,-1,0,0">
<Grid IsVisible="{Binding ParentModel.HasLed}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
@@ -591,39 +589,14 @@
MinWidth="0"
Grid.Column="0"
IsChecked="{Binding Config.EnableLedChanging, Mode=TwoWay}">
<TextBlock Text="{ext:Locale ControllerSettingsLedColor}" />
<TextBlock Text="{ext:Locale ControllerSettingsLed}" />
</CheckBox>
<CheckBox
Margin="5, 10, 5, 10"
MinWidth="0"
<Button
Margin="10"
Grid.Column="1"
IsVisible="{Binding ParentModel.CanClearLed}"
IsChecked="{Binding Config.TurnOffLed, Mode=TwoWay}"
Command="{Binding LedDisabledChanged}">
<TextBlock Text="{ext:Locale ControllerSettingsLedColorDisable}" />
</CheckBox>
<CheckBox
Margin="5, 10 5,10"
MinWidth="0"
Grid.Column="2"
IsEnabled="{Binding !Config.TurnOffLed}"
IsChecked="{Binding Config.UseRainbowLed, Mode=TwoWay}">
<TextBlock Text="{ext:Locale ControllerSettingsLedColorRainbow}" />
</CheckBox>
<ui:ColorPickerButton
Grid.Column="3"
IsEnabled="{Binding Config.ShowLedColorPicker}"
Margin="5, 10, 10, 10"
IsMoreButtonVisible="False"
UseColorPalette="False"
UseColorTriangle="False"
UseColorWheel="False"
ShowAcceptDismissButtons="False"
IsAlphaEnabled="False"
AttachedToVisualTree="ColorPickerButton_OnAttachedToVisualTree"
ColorChanged="ColorPickerButton_OnColorChanged"
Color="{Binding Config.LedColor, Mode=TwoWay}">
</ui:ColorPickerButton>
Command="{Binding ShowLedConfig}">
<TextBlock Text="{ext:Locale ControllerSettingsConfigureGeneral}" />
</Button>
</Grid>
</Border>
</StackPanel>

View File

@@ -6,12 +6,10 @@ using Avalonia.Interactivity;
using Avalonia.LogicalTree;
using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.UI.ViewModels.Input;
using Ryujinx.Common.Configuration.Hid.Controller;
using Ryujinx.Input;
using Ryujinx.Input.Assigner;
using System.Linq;
using Button = Ryujinx.Input.Button;
using StickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId;
@@ -246,24 +244,5 @@ namespace Ryujinx.Ava.UI.Views.Input
_currentAssigner?.Cancel();
_currentAssigner = null;
}
private void ColorPickerButton_OnColorChanged(ColorPickerButton sender, ColorButtonColorChangedEventArgs args)
{
if (!args.NewColor.HasValue) return;
if (DataContext is not ControllerInputViewModel cVm) return;
if (!cVm.Config.EnableLedChanging) return;
if (cVm.Config.TurnOffLed) return;
cVm.ParentModel.SelectedGamepad.SetLed(args.NewColor.Value.ToUInt32());
}
private void ColorPickerButton_OnAttachedToVisualTree(object sender, VisualTreeAttachmentEventArgs e)
{
if (DataContext is not ControllerInputViewModel cVm) return;
if (!cVm.Config.EnableLedChanging) return;
if (cVm.Config.TurnOffLed) return;
cVm.ParentModel.SelectedGamepad.SetLed(cVm.Config.LedColor.ToUInt32());
}
}
}

View File

@@ -0,0 +1,46 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels.Input"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:DataType="viewModels:LedInputViewModel"
x:Class="Ryujinx.UI.Views.Input.LedInputView">
<StackPanel Orientation="Vertical" HorizontalAlignment="Center">
<StackPanel Orientation="Horizontal" IsVisible="{Binding ParentModel.CanClearLed}">
<TextBlock MinWidth="75" MaxWidth="150" Text="{ext:Locale ControllerSettingsLedColorDisable}" />
<CheckBox
Margin="5"
MinWidth="0"
IsChecked="{Binding TurnOffLed, Mode=TwoWay}"
Command="{Binding LedDisabledChanged}">
</CheckBox>
</StackPanel>
<StackPanel Orientation="Horizontal" IsEnabled="{Binding !TurnOffLed}">
<TextBlock MinWidth="75" MaxWidth="150" Text="{ext:Locale ControllerSettingsLedColorRainbow}" />
<CheckBox
Margin="5"
MinWidth="0"
IsChecked="{Binding UseRainbowLed, Mode=TwoWay}">
</CheckBox>
</StackPanel>
<StackPanel Orientation="Horizontal" IsEnabled="{Binding ShowLedColorPicker}">
<TextBlock MinWidth="75" MaxWidth="150" Text="{ext:Locale ControllerSettingsLedColor}" />
<ui:ColorPickerButton
Margin="5"
IsMoreButtonVisible="False"
UseColorPalette="False"
UseColorTriangle="False"
UseColorWheel="False"
ShowAcceptDismissButtons="False"
IsAlphaEnabled="False"
AttachedToVisualTree="ColorPickerButton_OnAttachedToVisualTree"
ColorChanged="ColorPickerButton_OnColorChanged"
Color="{Binding LedColor, Mode=TwoWay}">
</ui:ColorPickerButton>
</StackPanel>
</StackPanel>
</UserControl>

View File

@@ -0,0 +1,75 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Models.Input;
using Ryujinx.Ava.UI.ViewModels.Input;
using Ryujinx.Ava.UI.Views.Input;
using System.Threading.Tasks;
namespace Ryujinx.UI.Views.Input
{
public partial class LedInputView : UserControl
{
private readonly LedInputViewModel _viewModel;
public LedInputView(ControllerInputViewModel viewModel)
{
DataContext = _viewModel = new LedInputViewModel
{
ParentModel = viewModel.ParentModel,
TurnOffLed = viewModel.Config.TurnOffLed,
EnableLedChanging = viewModel.Config.EnableLedChanging,
LedColor = viewModel.Config.LedColor,
UseRainbowLed = viewModel.Config.UseRainbowLed,
};
InitializeComponent();
}
private void ColorPickerButton_OnColorChanged(ColorPickerButton sender, ColorButtonColorChangedEventArgs args)
{
if (!args.NewColor.HasValue) return;
if (DataContext is not LedInputViewModel lvm) return;
if (!lvm.EnableLedChanging) return;
if (lvm.TurnOffLed) return;
lvm.ParentModel.SelectedGamepad.SetLed(args.NewColor.Value.ToUInt32());
}
private void ColorPickerButton_OnAttachedToVisualTree(object sender, VisualTreeAttachmentEventArgs e)
{
if (DataContext is not LedInputViewModel lvm) return;
if (!lvm.EnableLedChanging) return;
if (lvm.TurnOffLed) return;
lvm.ParentModel.SelectedGamepad.SetLed(lvm.LedColor.ToUInt32());
}
public static async Task Show(ControllerInputViewModel viewModel)
{
LedInputView content = new(viewModel);
ContentDialog contentDialog = new()
{
Title = LocaleManager.Instance[LocaleKeys.ControllerLedTitle],
PrimaryButtonText = LocaleManager.Instance[LocaleKeys.ControllerSettingsSave],
SecondaryButtonText = string.Empty,
CloseButtonText = LocaleManager.Instance[LocaleKeys.ControllerSettingsClose],
Content = content,
};
contentDialog.PrimaryButtonClick += (sender, args) =>
{
GamepadInputConfig config = viewModel.Config;
config.EnableLedChanging = content._viewModel.EnableLedChanging;
config.LedColor = content._viewModel.LedColor;
config.UseRainbowLed = content._viewModel.UseRainbowLed;
config.TurnOffLed = content._viewModel.TurnOffLed;
};
await contentDialog.ShowAsync();
}
}
}

View File

@@ -66,11 +66,11 @@ namespace Ryujinx.Ava.UI.Views.User
{
if (ViewModel.SelectedImage != null)
{
using MemoryStream streamJpg = new MemoryStream();
using MemoryStream streamJpg = new();
using SKBitmap bitmap = SKBitmap.Decode(ViewModel.SelectedImage);
using SKBitmap newBitmap = new SKBitmap(bitmap.Width, bitmap.Height);
using SKBitmap newBitmap = new(bitmap.Width, bitmap.Height);
using (SKCanvas canvas = new SKCanvas(newBitmap))
using (SKCanvas canvas = new(newBitmap))
{
canvas.Clear(new SKColor(
ViewModel.BackgroundColor.R,

View File

@@ -70,9 +70,9 @@ namespace Ryujinx.Ava.UI.Views.User
{
new(LocaleManager.Instance[LocaleKeys.AllSupportedFormats])
{
Patterns = new[] { "*.jpg", "*.jpeg", "*.png", "*.bmp" },
AppleUniformTypeIdentifiers = new[] { "public.jpeg", "public.png", "com.microsoft.bmp" },
MimeTypes = new[] { "image/jpeg", "image/png", "image/bmp" },
Patterns = ["*.jpg", "*.jpeg", "*.png", "*.bmp"],
AppleUniformTypeIdentifiers = ["public.jpeg", "public.png", "com.microsoft.bmp"],
MimeTypes = ["image/jpeg", "image/png", "image/bmp"],
},
},
});
@@ -103,7 +103,7 @@ namespace Ryujinx.Ava.UI.Views.User
SKBitmap resizedBitmap = bitmap.Resize(new SKImageInfo(256, 256), SKFilterQuality.High);
using MemoryStream streamJpg = new MemoryStream();
using MemoryStream streamJpg = new();
if (resizedBitmap != null)
{

View File

@@ -67,7 +67,7 @@ namespace Ryujinx.Ava.UI.Views.User
public void LoadSaves()
{
ViewModel.Saves.Clear();
ObservableCollection<SaveModel> saves = new ObservableCollection<SaveModel>();
ObservableCollection<SaveModel> saves = [];
SaveDataFilter saveDataFilter = SaveDataFilter.Make(
programId: default,
saveType: SaveDataType.Account,
@@ -75,7 +75,7 @@ namespace Ryujinx.Ava.UI.Views.User
saveDataId: default,
index: default);
using UniqueRef<SaveDataIterator> saveDataIterator = new UniqueRef<SaveDataIterator>();
using UniqueRef<SaveDataIterator> saveDataIterator = new();
_horizonClient.Fs.OpenSaveDataIterator(ref saveDataIterator.Ref, SaveDataSpaceId.User, in saveDataFilter).ThrowIfFailure();
@@ -95,7 +95,7 @@ namespace Ryujinx.Ava.UI.Views.User
SaveDataInfo save = saveDataInfo[i];
if (save.ProgramId.Value != 0)
{
SaveModel saveModel = new SaveModel(save);
SaveModel saveModel = new(save);
saves.Add(saveModel);
}
}

View File

@@ -34,7 +34,7 @@ namespace Ryujinx.Ava.UI.Windows
public CheatWindow(VirtualFileSystem virtualFileSystem, string titleId, string titleName, string titlePath)
{
LoadedCheats = new AvaloniaList<CheatNode>();
LoadedCheats = [];
IntegrityCheckLevel checkLevel = ConfigurationState.Instance.System.EnableFsIntegrityChecks
? IntegrityCheckLevel.ErrorOnInvalid
: IntegrityCheckLevel.None;
@@ -59,7 +59,7 @@ namespace Ryujinx.Ava.UI.Windows
int cheatAdded = 0;
ModLoader.ModCache mods = new ModLoader.ModCache();
ModLoader.ModCache mods = new();
ModLoader.QueryContentsDir(mods, new DirectoryInfo(Path.Combine(modsBasePath, "contents")), titleIdValue);
@@ -81,7 +81,7 @@ namespace Ryujinx.Ava.UI.Windows
LoadedCheats.Add(currentGroup);
}
CheatNode model = new CheatNode(cheat.Name, buildId, string.Empty, false, enabled.Contains($"{buildId}-{cheat.Name}"));
CheatNode model = new(cheat.Name, buildId, string.Empty, false, enabled.Contains($"{buildId}-{cheat.Name}"));
currentGroup?.SubNodes.Add(model);
cheatAdded++;

View File

@@ -50,7 +50,7 @@ namespace Ryujinx.Ava.UI.Windows
public static SKColor GetColor(SKBitmap image)
{
PaletteColor[] colors = new PaletteColor[TotalColors];
Dictionary<int, int> dominantColorBin = new Dictionary<int, int>();
Dictionary<int, int> dominantColorBin = new();
SKColor[] buffer = GetBuffer(image);

View File

@@ -712,12 +712,13 @@ namespace Ryujinx.Ava.UI.Windows
private void ShowNewContentAddedDialog(int numDlcAdded, int numDlcRemoved, int numUpdatesAdded, int numUpdatesRemoved)
{
string[] messages = {
string[] messages =
[
numDlcRemoved > 0 ? string.Format(LocaleManager.Instance[LocaleKeys.AutoloadDlcRemovedMessage], numDlcRemoved): null,
numDlcAdded > 0 ? string.Format(LocaleManager.Instance[LocaleKeys.AutoloadDlcAddedMessage], numDlcAdded): null,
numUpdatesRemoved > 0 ? string.Format(LocaleManager.Instance[LocaleKeys.AutoloadUpdateRemovedMessage], numUpdatesRemoved): null,
numUpdatesAdded > 0 ? string.Format(LocaleManager.Instance[LocaleKeys.AutoloadUpdateAddedMessage], numUpdatesAdded) : null
};
];
string msg = String.Join("\r\n", messages);