mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-07-23 13:07:10 +02:00
misc: chore: Use explicit types in the Avalonia project
This commit is contained in:
parent
3b5f6170d1
commit
be3bd0bcb5
69 changed files with 367 additions and 348 deletions
|
@ -46,7 +46,7 @@ namespace Ryujinx.Ava.UI.Applet
|
|||
|
||||
Dispatcher.UIThread.InvokeAsync(async () =>
|
||||
{
|
||||
var response = await ControllerAppletDialog.ShowControllerAppletDialog(_parent, args);
|
||||
UserResult response = await ControllerAppletDialog.ShowControllerAppletDialog(_parent, args);
|
||||
if (response == UserResult.Ok)
|
||||
{
|
||||
okPressed = true;
|
||||
|
|
|
@ -65,7 +65,7 @@ namespace Ryujinx.Ava.UI.Applet
|
|||
|
||||
private void AvaloniaDynamicTextInputHandler_KeyRelease(object sender, KeyEventArgs e)
|
||||
{
|
||||
var key = (HidKey)AvaloniaKeyboardMappingHelper.ToInputKey(e.Key);
|
||||
HidKey key = (HidKey)AvaloniaKeyboardMappingHelper.ToInputKey(e.Key);
|
||||
|
||||
if (!(KeyReleasedEvent?.Invoke(key)).GetValueOrDefault(true))
|
||||
{
|
||||
|
@ -85,7 +85,7 @@ namespace Ryujinx.Ava.UI.Applet
|
|||
|
||||
private void AvaloniaDynamicTextInputHandler_KeyPressed(object sender, KeyEventArgs e)
|
||||
{
|
||||
var key = (HidKey)AvaloniaKeyboardMappingHelper.ToInputKey(e.Key);
|
||||
HidKey key = (HidKey)AvaloniaKeyboardMappingHelper.ToInputKey(e.Key);
|
||||
|
||||
if (!(KeyPressedEvent?.Invoke(key)).GetValueOrDefault(true))
|
||||
{
|
||||
|
|
|
@ -60,11 +60,11 @@ namespace Ryujinx.Ava.UI.Applet
|
|||
|
||||
ObservableCollection<BaseModel> newProfiles = [];
|
||||
|
||||
foreach (var item in ViewModel.Profiles)
|
||||
foreach (BaseModel item in ViewModel.Profiles)
|
||||
{
|
||||
if (item is UserProfile originalItem)
|
||||
{
|
||||
var profile = new UserProfileSft(originalItem.UserId, originalItem.Name, originalItem.Image);
|
||||
UserProfileSft profile = new UserProfileSft(originalItem.UserId, originalItem.Name, originalItem.Image);
|
||||
|
||||
if (profile.UserId == ViewModel.SelectedUserId)
|
||||
{
|
||||
|
|
|
@ -76,7 +76,7 @@ namespace Ryujinx.Ava.UI.Controls
|
|||
|
||||
private static void OpenSaveDirectory(MainWindowViewModel viewModel, SaveDataType saveDataType, UserId userId)
|
||||
{
|
||||
var saveDataFilter = SaveDataFilter.Make(viewModel.SelectedApplication.Id, saveDataType, userId, saveDataId: default, index: default);
|
||||
SaveDataFilter saveDataFilter = SaveDataFilter.Make(viewModel.SelectedApplication.Id, saveDataType, userId, saveDataId: default, index: default);
|
||||
|
||||
ApplicationHelper.OpenSaveDir(in saveDataFilter, viewModel.SelectedApplication.Id, viewModel.SelectedApplication.ControlHolder, viewModel.SelectedApplication.Name);
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ namespace Ryujinx.Ava.UI.Controls
|
|||
if (sender is not MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
||||
return;
|
||||
|
||||
var result = await viewModel.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
IReadOnlyList<IStorageFolder> result = await viewModel.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
{
|
||||
Title = LocaleManager.Instance[LocaleKeys.FolderDialogExtractTitle],
|
||||
AllowMultiple = false,
|
||||
|
@ -320,13 +320,13 @@ namespace Ryujinx.Ava.UI.Controls
|
|||
viewModel.SelectedApplication.Path,
|
||||
viewModel.SelectedApplication.Name);
|
||||
|
||||
var iconFile = await result[0].CreateFileAsync($"{viewModel.SelectedApplication.IdString}.png");
|
||||
await using var fileStream = await iconFile.OpenWriteAsync();
|
||||
IStorageFile iconFile = await result[0].CreateFileAsync($"{viewModel.SelectedApplication.IdString}.png");
|
||||
await using Stream fileStream = await iconFile.OpenWriteAsync();
|
||||
|
||||
using var bitmap = SKBitmap.Decode(viewModel.SelectedApplication.Icon)
|
||||
using SKBitmap bitmap = SKBitmap.Decode(viewModel.SelectedApplication.Icon)
|
||||
.Resize(new SKSizeI(512, 512), SKFilterQuality.High);
|
||||
|
||||
using var png = bitmap.Encode(SKEncodedImageFormat.Png, 100);
|
||||
using SKData png = bitmap.Encode(SKEncodedImageFormat.Png, 100);
|
||||
|
||||
png.SaveTo(fileStream);
|
||||
}
|
||||
|
@ -350,7 +350,7 @@ namespace Ryujinx.Ava.UI.Controls
|
|||
|
||||
public async void TrimXCI_Click(object sender, RoutedEventArgs args)
|
||||
{
|
||||
var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
|
||||
MainWindowViewModel viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
|
||||
|
||||
if (viewModel?.SelectedApplication != null)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Notifications;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Input.Platform;
|
||||
using Avalonia.Interactivity;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using Ryujinx.Ava.UI.Helpers;
|
||||
|
@ -38,10 +39,10 @@ namespace Ryujinx.Ava.UI.Controls
|
|||
if (sender is not Button { Content: TextBlock idText })
|
||||
return;
|
||||
|
||||
if (!RyujinxApp.IsClipboardAvailable(out var clipboard))
|
||||
if (!RyujinxApp.IsClipboardAvailable(out IClipboard clipboard))
|
||||
return;
|
||||
|
||||
var appData = mwvm.Applications.FirstOrDefault(it => it.IdString == idText.Text);
|
||||
ApplicationData appData = mwvm.Applications.FirstOrDefault(it => it.IdString == idText.Text);
|
||||
if (appData is null)
|
||||
return;
|
||||
|
||||
|
|
|
@ -106,9 +106,9 @@ namespace Ryujinx.Ava.UI.Controls
|
|||
.OrderBy(x => x.Name)
|
||||
.ForEach(profile => ViewModel.Profiles.Add(new UserProfile(profile, this)));
|
||||
|
||||
var saveDataFilter = SaveDataFilter.Make(programId: default, saveType: SaveDataType.Account, default, saveDataId: default, index: default);
|
||||
SaveDataFilter saveDataFilter = SaveDataFilter.Make(programId: default, saveType: SaveDataType.Account, default, saveDataId: default, index: default);
|
||||
|
||||
using var saveDataIterator = new UniqueRef<SaveDataIterator>();
|
||||
using UniqueRef<SaveDataIterator> saveDataIterator = new UniqueRef<SaveDataIterator>();
|
||||
|
||||
HorizonClient.Fs.OpenSaveDataIterator(ref saveDataIterator.Ref, SaveDataSpaceId.User, in saveDataFilter).ThrowIfFailure();
|
||||
|
||||
|
@ -127,8 +127,8 @@ namespace Ryujinx.Ava.UI.Controls
|
|||
|
||||
for (int i = 0; i < readCount; i++)
|
||||
{
|
||||
var save = saveDataInfo[i];
|
||||
var id = new UserId((long)save.UserId.Id.Low, (long)save.UserId.Id.High);
|
||||
SaveDataInfo save = saveDataInfo[i];
|
||||
UserId id = new UserId((long)save.UserId.Id.Low, (long)save.UserId.Id.High);
|
||||
if (ViewModel.Profiles.Cast<UserProfile>().FirstOrDefault(x => x.UserId == id) == null)
|
||||
{
|
||||
lostAccounts.Add(id);
|
||||
|
@ -136,7 +136,7 @@ namespace Ryujinx.Ava.UI.Controls
|
|||
}
|
||||
}
|
||||
|
||||
foreach (var account in lostAccounts)
|
||||
foreach (UserId account in lostAccounts)
|
||||
{
|
||||
ViewModel.LostProfiles.Add(new UserProfile(new HLE.HOS.Services.Account.Acc.UserProfile(account, string.Empty, null), this));
|
||||
}
|
||||
|
@ -146,12 +146,12 @@ namespace Ryujinx.Ava.UI.Controls
|
|||
|
||||
public async void DeleteUser(UserProfile userProfile)
|
||||
{
|
||||
var lastUserId = AccountManager.LastOpenedUser.UserId;
|
||||
UserId lastUserId = AccountManager.LastOpenedUser.UserId;
|
||||
|
||||
if (userProfile.UserId == lastUserId)
|
||||
{
|
||||
// If we are deleting the currently open profile, then we must open something else before deleting.
|
||||
var profile = ViewModel.Profiles.Cast<UserProfile>().FirstOrDefault(x => x.UserId != lastUserId);
|
||||
UserProfile profile = ViewModel.Profiles.Cast<UserProfile>().FirstOrDefault(x => x.UserId != lastUserId);
|
||||
|
||||
if (profile == null)
|
||||
{
|
||||
|
@ -165,7 +165,7 @@ namespace Ryujinx.Ava.UI.Controls
|
|||
AccountManager.OpenUser(profile.UserId);
|
||||
}
|
||||
|
||||
var result = await ContentDialogHelper.CreateConfirmationDialog(
|
||||
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(
|
||||
LocaleManager.Instance[LocaleKeys.DialogUserProfileDeletionConfirmMessage],
|
||||
string.Empty,
|
||||
LocaleManager.Instance[LocaleKeys.InputDialogYes],
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace Ryujinx.Ava.UI.Helpers
|
|||
/// </remarks>
|
||||
public static bool ReplaceWith<T>(this AvaloniaList<T> list, T item, bool addIfNotFound = true)
|
||||
{
|
||||
var index = list.IndexOf(item);
|
||||
int index = list.IndexOf(item);
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
|
@ -45,9 +45,9 @@ namespace Ryujinx.Ava.UI.Helpers
|
|||
/// <param name="matchingList">The items to use as matching records to search for in the `sourceList', if not found this item will be added instead</params>
|
||||
public static void AddOrReplaceMatching<T>(this AvaloniaList<T> list, IList<T> sourceList, IList<T> matchingList)
|
||||
{
|
||||
foreach (var match in matchingList)
|
||||
foreach (T match in matchingList)
|
||||
{
|
||||
var index = sourceList.IndexOf(match);
|
||||
int index = sourceList.IndexOf(match);
|
||||
if (index != -1)
|
||||
{
|
||||
list.ReplaceWith(sourceList[index]);
|
||||
|
|
|
@ -121,7 +121,7 @@ namespace Ryujinx.Ava.UI.Helpers
|
|||
|
||||
startedDeferring = true;
|
||||
|
||||
var deferral = args.GetDeferral();
|
||||
Deferral deferral = args.GetDeferral();
|
||||
|
||||
sender.PrimaryButtonClick -= DeferClose;
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace Ryujinx.Ava.UI.Helpers
|
|||
}
|
||||
|
||||
public string this[string key] =>
|
||||
_glyphs.TryGetValue(Enum.Parse<Glyph>(key), out var val)
|
||||
_glyphs.TryGetValue(Enum.Parse<Glyph>(key), out string val)
|
||||
? val
|
||||
: string.Empty;
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace Ryujinx.Ava.UI.Helpers
|
|||
return null;
|
||||
}
|
||||
|
||||
var key = isBundled ? LocaleKeys.TitleBundledUpdateVersionLabel : LocaleKeys.TitleUpdateVersionLabel;
|
||||
LocaleKeys key = isBundled ? LocaleKeys.TitleBundledUpdateVersionLabel : LocaleKeys.TitleUpdateVersionLabel;
|
||||
return LocaleManager.Instance.UpdateAndGetDynamicValue(key, label);
|
||||
}
|
||||
|
||||
|
|
|
@ -50,8 +50,8 @@ namespace Ryujinx.Ava.UI.Helpers
|
|||
|
||||
private static string Format(AvaLogLevel level, string area, string template, object source, object[] v)
|
||||
{
|
||||
var result = new StringBuilder();
|
||||
var r = new CharacterReader(template.AsSpan());
|
||||
StringBuilder result = new StringBuilder();
|
||||
CharacterReader r = new CharacterReader(template.AsSpan());
|
||||
int i = 0;
|
||||
|
||||
result.Append('[');
|
||||
|
@ -64,7 +64,7 @@ namespace Ryujinx.Ava.UI.Helpers
|
|||
|
||||
while (!r.End)
|
||||
{
|
||||
var c = r.Take();
|
||||
char c = r.Take();
|
||||
|
||||
if (c != '{')
|
||||
{
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace Ryujinx.Ava.UI.Helpers
|
|||
Margin = new Thickness(0, 0, 15, 40),
|
||||
};
|
||||
|
||||
var maybeAsyncWorkQueue = new Lazy<AsyncWorkQueue<Notification>>(
|
||||
Lazy<AsyncWorkQueue<Notification>> maybeAsyncWorkQueue = new Lazy<AsyncWorkQueue<Notification>>(
|
||||
() => new AsyncWorkQueue<Notification>(notification =>
|
||||
{
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
|
@ -57,7 +57,7 @@ namespace Ryujinx.Ava.UI.Helpers
|
|||
|
||||
public static void Show(string title, string text, NotificationType type, bool waitingExit = false, Action onClick = null, Action onClose = null)
|
||||
{
|
||||
var delay = waitingExit ? TimeSpan.FromMilliseconds(0) : TimeSpan.FromMilliseconds(NotificationDelayInMs);
|
||||
TimeSpan delay = waitingExit ? TimeSpan.FromMilliseconds(0) : TimeSpan.FromMilliseconds(NotificationDelayInMs);
|
||||
|
||||
_notifications.Add(new Notification(title, text, type, delay, onClick, onClose));
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace Ryujinx.Ava.UI.Models
|
|||
}
|
||||
set
|
||||
{
|
||||
foreach (var cheat in SubNodes)
|
||||
foreach (CheatNode cheat in SubNodes)
|
||||
{
|
||||
cheat.IsEnabled = value;
|
||||
cheat.OnPropertyChanged();
|
||||
|
|
|
@ -367,7 +367,7 @@ namespace Ryujinx.Ava.UI.Models.Input
|
|||
|
||||
public InputConfig GetConfig()
|
||||
{
|
||||
var config = new StandardKeyboardInputConfig
|
||||
StandardKeyboardInputConfig config = new StandardKeyboardInputConfig
|
||||
{
|
||||
Id = Id,
|
||||
Backend = InputBackendType.WindowKeyboard,
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace Ryujinx.Ava.UI.Models
|
|||
TitleId = info.ProgramId;
|
||||
UserId = info.UserId;
|
||||
|
||||
var appData = RyujinxApp.MainWindow.ViewModel.Applications.FirstOrDefault(x => x.IdString.EqualsIgnoreCase(TitleIdString));
|
||||
ApplicationData appData = RyujinxApp.MainWindow.ViewModel.Applications.FirstOrDefault(x => x.IdString.EqualsIgnoreCase(TitleIdString));
|
||||
|
||||
InGameList = appData != null;
|
||||
|
||||
|
@ -59,13 +59,13 @@ namespace Ryujinx.Ava.UI.Models
|
|||
}
|
||||
else
|
||||
{
|
||||
var appMetadata = ApplicationLibrary.LoadAndSaveMetaData(TitleIdString);
|
||||
ApplicationMetadata appMetadata = ApplicationLibrary.LoadAndSaveMetaData(TitleIdString);
|
||||
Title = appMetadata.Title ?? TitleIdString;
|
||||
}
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
var saveRoot = Path.Combine(VirtualFileSystem.GetNandPath(), $"user/save/{info.SaveDataId:x16}");
|
||||
string saveRoot = Path.Combine(VirtualFileSystem.GetNandPath(), $"user/save/{info.SaveDataId:x16}");
|
||||
|
||||
long totalSize = GetDirectorySize(saveRoot);
|
||||
|
||||
|
@ -74,14 +74,14 @@ namespace Ryujinx.Ava.UI.Models
|
|||
long size = 0;
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
var directories = Directory.GetDirectories(path);
|
||||
foreach (var directory in directories)
|
||||
string[] directories = Directory.GetDirectories(path);
|
||||
foreach (string directory in directories)
|
||||
{
|
||||
size += GetDirectorySize(directory);
|
||||
}
|
||||
|
||||
var files = Directory.GetFiles(path);
|
||||
foreach (var file in files)
|
||||
string[] files = Directory.GetFiles(path);
|
||||
foreach (string file in files)
|
||||
{
|
||||
size += new FileInfo(file).Length;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using Avalonia;
|
||||
using Avalonia.Media;
|
||||
using Ryujinx.Ava.UI.Controls;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
|
@ -87,7 +88,7 @@ namespace Ryujinx.Ava.UI.Models
|
|||
|
||||
private void UpdateBackground()
|
||||
{
|
||||
var currentApplication = Avalonia.Application.Current;
|
||||
Application currentApplication = Avalonia.Application.Current;
|
||||
currentApplication.Styles.TryGetResource("ControlFillColorSecondary", currentApplication.ActualThemeVariant, out object color);
|
||||
|
||||
if (color is not null)
|
||||
|
|
|
@ -44,13 +44,13 @@ namespace Ryujinx.Ava.UI.Renderer
|
|||
throw new PlatformNotSupportedException();
|
||||
}
|
||||
|
||||
var flags = OpenGLContextFlags.Compat;
|
||||
OpenGLContextFlags flags = OpenGLContextFlags.Compat;
|
||||
if (ConfigurationState.Instance.Logger.GraphicsDebugLevel != GraphicsDebugLevel.None)
|
||||
{
|
||||
flags |= OpenGLContextFlags.Debug;
|
||||
}
|
||||
|
||||
var graphicsMode = Environment.OSVersion.Platform == PlatformID.Unix ? new FramebufferFormat(new ColorFormat(8, 8, 8, 0), 16, 0, ColorFormat.Zero, 0, 2, false) : FramebufferFormat.Default;
|
||||
FramebufferFormat graphicsMode = Environment.OSVersion.Platform == PlatformID.Unix ? new FramebufferFormat(new ColorFormat(8, 8, 8, 0), 16, 0, ColorFormat.Zero, 0, 2, false) : FramebufferFormat.Default;
|
||||
|
||||
Context = PlatformHelper.CreateOpenGLContext(graphicsMode, 3, 3, flags);
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
protected void OnPropertiesChanged(string firstPropertyName, params ReadOnlySpan<string> propertyNames)
|
||||
{
|
||||
OnPropertyChanged(firstPropertyName);
|
||||
foreach (var propertyName in propertyNames)
|
||||
foreach (string propertyName in propertyNames)
|
||||
{
|
||||
OnPropertyChanged(propertyName);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ using Ryujinx.Ava.UI.Helpers;
|
|||
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -71,7 +72,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
private void LoadDownloadableContents()
|
||||
{
|
||||
var dlcs = _applicationLibrary.DownloadableContents.Items
|
||||
IEnumerable<(DownloadableContentModel Dlc, bool IsEnabled)> dlcs = _applicationLibrary.DownloadableContents.Items
|
||||
.Where(it => it.Dlc.TitleIdBase == _applicationData.IdBase);
|
||||
|
||||
bool hasBundledContent = false;
|
||||
|
@ -101,11 +102,11 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
.ThenBy(it => it.TitleId)
|
||||
.AsObservableChangeSet()
|
||||
.Filter(Filter)
|
||||
.Bind(out var view).AsObservableList();
|
||||
.Bind(out ReadOnlyObservableCollection<DownloadableContentModel> view).AsObservableList();
|
||||
|
||||
// NOTE(jpr): this works around a bug where calling _views.Clear also clears SelectedDownloadableContents for
|
||||
// some reason. so we save the items here and add them back after
|
||||
var items = SelectedDownloadableContents.ToArray();
|
||||
DownloadableContentModel[] items = SelectedDownloadableContents.ToArray();
|
||||
|
||||
Views.Clear();
|
||||
Views.AddRange(view);
|
||||
|
@ -130,7 +131,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
public async void Add()
|
||||
{
|
||||
var result = await _storageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
IReadOnlyList<IStorageFile> result = await _storageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
Title = LocaleManager.Instance[LocaleKeys.SelectDlcDialogTitle],
|
||||
AllowMultiple = true,
|
||||
|
@ -145,10 +146,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
},
|
||||
});
|
||||
|
||||
var totalDlcAdded = 0;
|
||||
foreach (var file in result)
|
||||
int totalDlcAdded = 0;
|
||||
foreach (IStorageFile file in result)
|
||||
{
|
||||
if (!AddDownloadableContent(file.Path.LocalPath, out var newDlcAdded))
|
||||
if (!AddDownloadableContent(file.Path.LocalPath, out int newDlcAdded))
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogDlcNoDlcErrorMessage]);
|
||||
}
|
||||
|
@ -171,18 +172,18 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!_applicationLibrary.TryGetDownloadableContentFromFile(path, out var dlcs) || dlcs.Count == 0)
|
||||
if (!_applicationLibrary.TryGetDownloadableContentFromFile(path, out List<DownloadableContentModel> dlcs) || dlcs.Count == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var dlcsForThisGame = dlcs.Where(it => it.TitleIdBase == _applicationData.IdBase).ToList();
|
||||
List<DownloadableContentModel> dlcsForThisGame = dlcs.Where(it => it.TitleIdBase == _applicationData.IdBase).ToList();
|
||||
if (dlcsForThisGame.Count == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var dlc in dlcsForThisGame)
|
||||
foreach (DownloadableContentModel dlc in dlcsForThisGame)
|
||||
{
|
||||
if (!DownloadableContents.Contains(dlc))
|
||||
{
|
||||
|
@ -246,13 +247,13 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
public void Save()
|
||||
{
|
||||
var dlcs = DownloadableContents.Select(it => (it, SelectedDownloadableContents.Contains(it))).ToList();
|
||||
List<(DownloadableContentModel it, bool)> dlcs = DownloadableContents.Select(it => (it, SelectedDownloadableContents.Contains(it))).ToList();
|
||||
_applicationLibrary.SaveDownloadableContentsForGame(_applicationData, dlcs);
|
||||
}
|
||||
|
||||
private Task ShowNewDlcAddedDialog(int numAdded)
|
||||
{
|
||||
var msg = string.Format(LocaleManager.Instance[LocaleKeys.DlcWindowDlcAddedMessage], numAdded);
|
||||
string msg = string.Format(LocaleManager.Instance[LocaleKeys.DlcWindowDlcAddedMessage], numAdded);
|
||||
return Dispatcher.UIThread.InvokeAsync(async () =>
|
||||
{
|
||||
await ContentDialogHelper.ShowTextDialog(
|
||||
|
|
|
@ -215,7 +215,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||
return;
|
||||
}
|
||||
|
||||
var selected = Devices[_device].Type;
|
||||
DeviceType selected = Devices[_device].Type;
|
||||
|
||||
if (selected != DeviceType.None)
|
||||
{
|
||||
|
@ -299,7 +299,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||
}
|
||||
else
|
||||
{
|
||||
var type = DeviceType.None;
|
||||
DeviceType type = DeviceType.None;
|
||||
|
||||
if (Config is StandardKeyboardInputConfig)
|
||||
{
|
||||
|
@ -311,7 +311,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||
type = DeviceType.Controller;
|
||||
}
|
||||
|
||||
var item = Devices.FirstOrDefault(x => x.Type == type && x.Id == Config.Id);
|
||||
(DeviceType Type, string Id, string Name) item = Devices.FirstOrDefault(x => x.Type == type && x.Id == Config.Id);
|
||||
if (item != default)
|
||||
{
|
||||
Device = Devices.ToList().FindIndex(x => x.Id == item.Id);
|
||||
|
@ -331,7 +331,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||
}
|
||||
|
||||
string id = GetCurrentGamepadId();
|
||||
var type = Devices[Device].Type;
|
||||
DeviceType type = Devices[Device].Type;
|
||||
|
||||
if (type == DeviceType.None)
|
||||
{
|
||||
|
@ -373,7 +373,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||
return string.Empty;
|
||||
}
|
||||
|
||||
var device = Devices[Device];
|
||||
(DeviceType Type, string Id, string Name) device = Devices[Device];
|
||||
|
||||
if (device.Type == DeviceType.None)
|
||||
{
|
||||
|
@ -485,7 +485,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||
private string GetProfileBasePath()
|
||||
{
|
||||
string path = AppDataManager.ProfilesDirPath;
|
||||
var type = Devices[Device == -1 ? 0 : Device].Type;
|
||||
DeviceType type = Devices[Device == -1 ? 0 : Device].Type;
|
||||
|
||||
if (type == DeviceType.Keyboard)
|
||||
{
|
||||
|
@ -525,7 +525,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||
|
||||
public InputConfig LoadDefaultConfiguration()
|
||||
{
|
||||
var activeDevice = Devices.FirstOrDefault();
|
||||
(DeviceType Type, string Id, string Name) activeDevice = Devices.FirstOrDefault();
|
||||
|
||||
if (Devices.Count > 0 && Device < Devices.Count && Device >= 0)
|
||||
{
|
||||
|
@ -822,20 +822,20 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||
}
|
||||
else
|
||||
{
|
||||
var device = Devices[Device];
|
||||
(DeviceType Type, string Id, string Name) device = Devices[Device];
|
||||
|
||||
if (device.Type == DeviceType.Keyboard)
|
||||
{
|
||||
var inputConfig = (ConfigViewModel as KeyboardInputViewModel).Config;
|
||||
KeyboardInputConfig inputConfig = (ConfigViewModel as KeyboardInputViewModel).Config;
|
||||
inputConfig.Id = device.Id;
|
||||
}
|
||||
else
|
||||
{
|
||||
var inputConfig = (ConfigViewModel as ControllerInputViewModel).Config;
|
||||
GamepadInputConfig inputConfig = (ConfigViewModel as ControllerInputViewModel).Config;
|
||||
inputConfig.Id = device.Id.Split(" ")[0];
|
||||
}
|
||||
|
||||
var config = !IsController
|
||||
InputConfig config = !IsController
|
||||
? (ConfigViewModel as KeyboardInputViewModel).Config.GetConfig()
|
||||
: (ConfigViewModel as ControllerInputViewModel).Config.GetConfig();
|
||||
config.ControllerType = Controllers[_controller].Type;
|
||||
|
|
|
@ -1046,9 +1046,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
private void PrepareLoadScreen()
|
||||
{
|
||||
using MemoryStream stream = new(SelectedIcon);
|
||||
using var gameIconBmp = SKBitmap.Decode(stream);
|
||||
using SKBitmap gameIconBmp = SKBitmap.Decode(stream);
|
||||
|
||||
var dominantColor = IconColorPicker.GetFilteredColor(gameIconBmp);
|
||||
SKColor dominantColor = IconColorPicker.GetFilteredColor(gameIconBmp);
|
||||
|
||||
const float ColorMultiple = 0.5f;
|
||||
|
||||
|
@ -1132,7 +1132,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
private async Task LoadContentFromFolder(LocaleKeys localeMessageAddedKey, LocaleKeys localeMessageRemovedKey, LoadContentFromFolderDelegate onDirsSelected)
|
||||
{
|
||||
var result = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
IReadOnlyList<IStorageFolder> result = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
{
|
||||
Title = LocaleManager.Instance[LocaleKeys.OpenFolderDialogTitle],
|
||||
AllowMultiple = true,
|
||||
|
@ -1140,10 +1140,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
if (result.Count > 0)
|
||||
{
|
||||
var dirs = result.Select(it => it.Path.LocalPath).ToList();
|
||||
var numAdded = onDirsSelected(dirs, out int numRemoved);
|
||||
List<string> dirs = result.Select(it => it.Path.LocalPath).ToList();
|
||||
int numAdded = onDirsSelected(dirs, out int numRemoved);
|
||||
|
||||
var msg = String.Join("\r\n", new string[] {
|
||||
string msg = String.Join("\r\n", new string[] {
|
||||
string.Format(LocaleManager.Instance[localeMessageRemovedKey], numRemoved),
|
||||
string.Format(LocaleManager.Instance[localeMessageAddedKey], numAdded)
|
||||
});
|
||||
|
@ -1180,17 +1180,17 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
public void LoadConfigurableHotKeys()
|
||||
{
|
||||
if (AvaloniaKeyboardMappingHelper.TryGetAvaKey((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.ShowUI, out var showUiKey))
|
||||
if (AvaloniaKeyboardMappingHelper.TryGetAvaKey((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.ShowUI, out Avalonia.Input.Key showUiKey))
|
||||
{
|
||||
ShowUiKey = new KeyGesture(showUiKey);
|
||||
}
|
||||
|
||||
if (AvaloniaKeyboardMappingHelper.TryGetAvaKey((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.Screenshot, out var screenshotKey))
|
||||
if (AvaloniaKeyboardMappingHelper.TryGetAvaKey((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.Screenshot, out Avalonia.Input.Key screenshotKey))
|
||||
{
|
||||
ScreenshotKey = new KeyGesture(screenshotKey);
|
||||
}
|
||||
|
||||
if (AvaloniaKeyboardMappingHelper.TryGetAvaKey((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.Pause, out var pauseKey))
|
||||
if (AvaloniaKeyboardMappingHelper.TryGetAvaKey((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.Pause, out Avalonia.Input.Key pauseKey))
|
||||
{
|
||||
PauseKey = new KeyGesture(pauseKey);
|
||||
}
|
||||
|
@ -1238,7 +1238,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
public async Task InstallFirmwareFromFile()
|
||||
{
|
||||
var result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
IReadOnlyList<IStorageFile> result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
AllowMultiple = false,
|
||||
FileTypeFilter = new List<FilePickerFileType>
|
||||
|
@ -1272,7 +1272,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
public async Task InstallFirmwareFromFolder()
|
||||
{
|
||||
var result = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
IReadOnlyList<IStorageFolder> result = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
{
|
||||
AllowMultiple = false,
|
||||
});
|
||||
|
@ -1285,7 +1285,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
public async Task InstallKeysFromFile()
|
||||
{
|
||||
var result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
IReadOnlyList<IStorageFile> result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
AllowMultiple = false,
|
||||
FileTypeFilter = new List<FilePickerFileType>
|
||||
|
@ -1319,7 +1319,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
public async Task InstallKeysFromFolder()
|
||||
{
|
||||
var result = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
IReadOnlyList<IStorageFolder> result = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
{
|
||||
AllowMultiple = false,
|
||||
});
|
||||
|
@ -1410,7 +1410,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
public async Task OpenFile()
|
||||
{
|
||||
var result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
IReadOnlyList<IStorageFile> result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
Title = LocaleManager.Instance[LocaleKeys.OpenFileDialogTitle],
|
||||
AllowMultiple = false,
|
||||
|
@ -1501,7 +1501,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
public async Task OpenFolder()
|
||||
{
|
||||
var result = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
IReadOnlyList<IStorageFolder> result = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
{
|
||||
Title = LocaleManager.Instance[LocaleKeys.OpenFolderDialogTitle],
|
||||
AllowMultiple = false,
|
||||
|
@ -1682,7 +1682,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
{
|
||||
if (AppHost.Device.System.SearchingForAmiibo(out _) && IsGameRunning)
|
||||
{
|
||||
var result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
IReadOnlyList<IStorageFile> result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
Title = LocaleManager.Instance[LocaleKeys.OpenFileDialogTitle],
|
||||
AllowMultiple = false,
|
||||
|
@ -1802,16 +1802,16 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
return;
|
||||
}
|
||||
|
||||
var trimmer = new XCIFileTrimmer(filename, new XCITrimmerLog.MainWindow(this));
|
||||
XCIFileTrimmer trimmer = new XCIFileTrimmer(filename, new XCITrimmerLog.MainWindow(this));
|
||||
|
||||
if (trimmer.CanBeTrimmed)
|
||||
{
|
||||
var savings = (double)trimmer.DiskSpaceSavingsB / 1024.0 / 1024.0;
|
||||
var currentFileSize = (double)trimmer.FileSizeB / 1024.0 / 1024.0;
|
||||
var cartDataSize = (double)trimmer.DataSizeB / 1024.0 / 1024.0;
|
||||
double savings = (double)trimmer.DiskSpaceSavingsB / 1024.0 / 1024.0;
|
||||
double currentFileSize = (double)trimmer.FileSizeB / 1024.0 / 1024.0;
|
||||
double cartDataSize = (double)trimmer.DataSizeB / 1024.0 / 1024.0;
|
||||
string secondaryText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.TrimXCIFileDialogSecondaryText, currentFileSize, cartDataSize, savings);
|
||||
|
||||
var result = await ContentDialogHelper.CreateConfirmationDialog(
|
||||
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(
|
||||
LocaleManager.Instance[LocaleKeys.TrimXCIFileDialogPrimaryText],
|
||||
secondaryText,
|
||||
LocaleManager.Instance[LocaleKeys.Continue],
|
||||
|
|
|
@ -12,6 +12,8 @@ using Ryujinx.Common.Logging;
|
|||
using Ryujinx.Common.Utilities;
|
||||
using Ryujinx.HLE.HOS;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
|
@ -77,37 +79,37 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
string[] modsBasePaths = [ModLoader.GetSdModsBasePath(), ModLoader.GetModsBasePath()];
|
||||
|
||||
foreach (var path in modsBasePaths)
|
||||
foreach (string path in modsBasePaths)
|
||||
{
|
||||
var inSd = path == ModLoader.GetSdModsBasePath();
|
||||
var modCache = new ModLoader.ModCache();
|
||||
bool inSd = path == ModLoader.GetSdModsBasePath();
|
||||
ModLoader.ModCache modCache = new ModLoader.ModCache();
|
||||
|
||||
ModLoader.QueryContentsDir(modCache, new DirectoryInfo(Path.Combine(path, "contents")), applicationId);
|
||||
|
||||
foreach (var mod in modCache.RomfsDirs)
|
||||
foreach (ModLoader.Mod<DirectoryInfo> mod in modCache.RomfsDirs)
|
||||
{
|
||||
var modModel = new ModModel(mod.Path.Parent.FullName, mod.Name, mod.Enabled, inSd);
|
||||
ModModel modModel = new ModModel(mod.Path.Parent.FullName, mod.Name, mod.Enabled, inSd);
|
||||
if (Mods.All(x => x.Path != mod.Path.Parent.FullName))
|
||||
{
|
||||
Mods.Add(modModel);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var mod in modCache.RomfsContainers)
|
||||
foreach (ModLoader.Mod<FileInfo> mod in modCache.RomfsContainers)
|
||||
{
|
||||
Mods.Add(new ModModel(mod.Path.FullName, mod.Name, mod.Enabled, inSd));
|
||||
}
|
||||
|
||||
foreach (var mod in modCache.ExefsDirs)
|
||||
foreach (ModLoader.Mod<DirectoryInfo> mod in modCache.ExefsDirs)
|
||||
{
|
||||
var modModel = new ModModel(mod.Path.Parent.FullName, mod.Name, mod.Enabled, inSd);
|
||||
ModModel modModel = new ModModel(mod.Path.Parent.FullName, mod.Name, mod.Enabled, inSd);
|
||||
if (Mods.All(x => x.Path != mod.Path.Parent.FullName))
|
||||
{
|
||||
Mods.Add(modModel);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var mod in modCache.ExefsContainers)
|
||||
foreach (ModLoader.Mod<FileInfo> mod in modCache.ExefsContainers)
|
||||
{
|
||||
Mods.Add(new ModModel(mod.Path.FullName, mod.Name, mod.Enabled, inSd));
|
||||
}
|
||||
|
@ -120,7 +122,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
{
|
||||
Mods.AsObservableChangeSet()
|
||||
.Filter(Filter)
|
||||
.Bind(out var view).AsObservableList();
|
||||
.Bind(out ReadOnlyObservableCollection<ModModel> view).AsObservableList();
|
||||
|
||||
#pragma warning disable MVVMTK0034 // Event to update is fired below
|
||||
_views.Clear();
|
||||
|
@ -163,10 +165,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
public void Delete(ModModel model, bool removeFromList = true)
|
||||
{
|
||||
var isSubdir = true;
|
||||
var pathToDelete = model.Path;
|
||||
var basePath = model.InSd ? ModLoader.GetSdModsBasePath() : ModLoader.GetModsBasePath();
|
||||
var modsDir = ModLoader.GetApplicationDir(basePath, _applicationId.ToString("x16"));
|
||||
bool isSubdir = true;
|
||||
string pathToDelete = model.Path;
|
||||
string basePath = model.InSd ? ModLoader.GetSdModsBasePath() : ModLoader.GetModsBasePath();
|
||||
string modsDir = ModLoader.GetApplicationDir(basePath, _applicationId.ToString("x16"));
|
||||
|
||||
if (new DirectoryInfo(model.Path).Parent?.FullName == modsDir)
|
||||
{
|
||||
|
@ -175,9 +177,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
if (isSubdir)
|
||||
{
|
||||
var parentDir = String.Empty;
|
||||
string parentDir = String.Empty;
|
||||
|
||||
foreach (var dir in Directory.GetDirectories(modsDir, "*", SearchOption.TopDirectoryOnly))
|
||||
foreach (string dir in Directory.GetDirectories(modsDir, "*", SearchOption.TopDirectoryOnly))
|
||||
{
|
||||
if (Directory.GetDirectories(dir, "*", SearchOption.AllDirectories).Contains(model.Path))
|
||||
{
|
||||
|
@ -229,10 +231,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
return;
|
||||
}
|
||||
|
||||
var destinationDir = ModLoader.GetApplicationDir(ModLoader.GetSdModsBasePath(), _applicationId.ToString("x16"));
|
||||
string destinationDir = ModLoader.GetApplicationDir(ModLoader.GetSdModsBasePath(), _applicationId.ToString("x16"));
|
||||
|
||||
// TODO: More robust checking for valid mod folders
|
||||
var isDirectoryValid = true;
|
||||
bool isDirectoryValid = true;
|
||||
|
||||
if (directories.Length == 0)
|
||||
{
|
||||
|
@ -248,7 +250,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
return;
|
||||
}
|
||||
|
||||
foreach (var dir in directories)
|
||||
foreach (string dir in directories)
|
||||
{
|
||||
string dirToCreate = dir.Replace(directory.Parent.ToString(), destinationDir);
|
||||
|
||||
|
@ -269,9 +271,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
Directory.CreateDirectory(dirToCreate);
|
||||
}
|
||||
|
||||
var files = Directory.GetFiles(directory.ToString(), "*", SearchOption.AllDirectories);
|
||||
string[] files = Directory.GetFiles(directory.ToString(), "*", SearchOption.AllDirectories);
|
||||
|
||||
foreach (var file in files)
|
||||
foreach (string file in files)
|
||||
{
|
||||
File.Copy(file, file.Replace(directory.Parent.ToString(), destinationDir), true);
|
||||
}
|
||||
|
@ -281,13 +283,13 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
public async void Add()
|
||||
{
|
||||
var result = await _storageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
IReadOnlyList<IStorageFolder> result = await _storageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
{
|
||||
Title = LocaleManager.Instance[LocaleKeys.SelectModDialogTitle],
|
||||
AllowMultiple = true,
|
||||
});
|
||||
|
||||
foreach (var folder in result)
|
||||
foreach (IStorageFolder folder in result)
|
||||
{
|
||||
AddMod(new DirectoryInfo(folder.Path.LocalPath));
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ using Ryujinx.Common.Configuration;
|
|||
using Ryujinx.Common.Configuration.Multiplayer;
|
||||
using Ryujinx.Common.GraphicsDriver;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Vulkan;
|
||||
using Ryujinx.HLE;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
|
@ -386,7 +387,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
{
|
||||
AvailableGpus.Clear();
|
||||
|
||||
var devices = VulkanRenderer.GetPhysicalDevices();
|
||||
DeviceInfo[] devices = VulkanRenderer.GetPhysicalDevices();
|
||||
|
||||
if (devices.Length == 0)
|
||||
{
|
||||
|
@ -395,7 +396,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
}
|
||||
else
|
||||
{
|
||||
foreach (var device in devices)
|
||||
foreach (DeviceInfo device in devices)
|
||||
{
|
||||
await Dispatcher.UIThread.InvokeAsync(() =>
|
||||
{
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
private void LoadUpdates()
|
||||
{
|
||||
var updates = ApplicationLibrary.TitleUpdates.Items
|
||||
IEnumerable<(TitleUpdateModel TitleUpdate, bool IsSelected)> updates = ApplicationLibrary.TitleUpdates.Items
|
||||
.Where(it => it.TitleUpdate.TitleIdBase == ApplicationData.IdBase);
|
||||
|
||||
bool hasBundledContent = false;
|
||||
|
@ -64,11 +64,11 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
public void SortUpdates()
|
||||
{
|
||||
var sortedUpdates = TitleUpdates.OrderByDescending(update => update.Version);
|
||||
IOrderedEnumerable<TitleUpdateModel> sortedUpdates = TitleUpdates.OrderByDescending(update => update.Version);
|
||||
|
||||
// NOTE(jpr): this works around a bug where calling Views.Clear also clears SelectedUpdate for
|
||||
// some reason. so we save the item here and restore it after
|
||||
var selected = SelectedUpdate;
|
||||
object selected = SelectedUpdate;
|
||||
|
||||
Views.Clear();
|
||||
Views.Add(new TitleUpdateViewModelNoUpdate());
|
||||
|
@ -96,18 +96,18 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!ApplicationLibrary.TryGetTitleUpdatesFromFile(path, out var updates))
|
||||
if (!ApplicationLibrary.TryGetTitleUpdatesFromFile(path, out List<TitleUpdateModel> updates))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var updatesForThisGame = updates.Where(it => it.TitleIdBase == ApplicationData.Id).ToList();
|
||||
List<TitleUpdateModel> updatesForThisGame = updates.Where(it => it.TitleIdBase == ApplicationData.Id).ToList();
|
||||
if (updatesForThisGame.Count == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var update in updatesForThisGame)
|
||||
foreach (TitleUpdateModel update in updatesForThisGame)
|
||||
{
|
||||
if (!TitleUpdates.Contains(update))
|
||||
{
|
||||
|
@ -142,7 +142,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
public async Task Add()
|
||||
{
|
||||
var result = await _storageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
IReadOnlyList<IStorageFile> result = await _storageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
AllowMultiple = true,
|
||||
FileTypeFilter = new List<FilePickerFileType>
|
||||
|
@ -156,10 +156,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
},
|
||||
});
|
||||
|
||||
var totalUpdatesAdded = 0;
|
||||
foreach (var file in result)
|
||||
int totalUpdatesAdded = 0;
|
||||
foreach (IStorageFile file in result)
|
||||
{
|
||||
if (!AddUpdate(file.Path.LocalPath, out var newUpdatesAdded))
|
||||
if (!AddUpdate(file.Path.LocalPath, out int newUpdatesAdded))
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogUpdateAddUpdateErrorMessage]);
|
||||
}
|
||||
|
@ -175,13 +175,13 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
public void Save()
|
||||
{
|
||||
var updates = TitleUpdates.Select(it => (it, it == SelectedUpdate as TitleUpdateModel)).ToList();
|
||||
List<(TitleUpdateModel it, bool)> updates = TitleUpdates.Select(it => (it, it == SelectedUpdate as TitleUpdateModel)).ToList();
|
||||
ApplicationLibrary.SaveTitleUpdatesForGame(ApplicationData, updates);
|
||||
}
|
||||
|
||||
private Task ShowNewUpdatesAddedDialog(int numAdded)
|
||||
{
|
||||
var msg = string.Format(LocaleManager.Instance[LocaleKeys.UpdateWindowUpdateAddedMessage], numAdded);
|
||||
string msg = string.Format(LocaleManager.Instance[LocaleKeys.UpdateWindowUpdateAddedMessage], numAdded);
|
||||
return Dispatcher.UIThread.InvokeAsync(async () =>
|
||||
await ContentDialogHelper.ShowTextDialog(
|
||||
LocaleManager.Instance[LocaleKeys.DialogConfirmationTitle],
|
||||
|
|
|
@ -68,7 +68,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
{
|
||||
Images.Clear();
|
||||
|
||||
foreach (var image in _avatarStore)
|
||||
foreach (KeyValuePair<string, byte[]> image in _avatarStore)
|
||||
{
|
||||
Images.Add(new ProfileImageModel(image.Key, image.Value));
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
private void ChangeImageBackground()
|
||||
{
|
||||
foreach (var image in Images)
|
||||
foreach (ProfileImageModel image in Images)
|
||||
{
|
||||
image.BackgroundColor = new SolidColorBrush(BackgroundColor);
|
||||
}
|
||||
|
@ -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 var file = new UniqueRef<IFile>();
|
||||
using UniqueRef<IFile> file = new UniqueRef<IFile>();
|
||||
|
||||
romfs.OpenFile(ref file.Ref, ("/" + item.FullPath).ToU8Span(), OpenMode.Read).ThrowIfFailure();
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
Saves.AsObservableChangeSet()
|
||||
.Filter(Filter)
|
||||
.Sort(GetComparer())
|
||||
.Bind(out var view).AsObservableList();
|
||||
.Bind(out ReadOnlyObservableCollection<SaveModel> view).AsObservableList();
|
||||
|
||||
#pragma warning disable MVVMTK0034
|
||||
_views.Clear();
|
||||
|
|
|
@ -9,6 +9,7 @@ using Ryujinx.Ava.UI.Helpers;
|
|||
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||
using Ryujinx.Common.Utilities;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using static Ryujinx.Common.Utilities.XCIFileTrimmer;
|
||||
|
@ -54,10 +55,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
private void LoadXCIApplications()
|
||||
{
|
||||
var apps = ApplicationLibrary.Applications.Items
|
||||
IEnumerable<ApplicationData> apps = ApplicationLibrary.Applications.Items
|
||||
.Where(app => app.FileExtension == _FileExtXCI);
|
||||
|
||||
foreach (var xciApp in apps)
|
||||
foreach (ApplicationData xciApp in apps)
|
||||
AddOrUpdateXCITrimmerFile(CreateXCITrimmerFile(xciApp.Path));
|
||||
|
||||
ApplicationsChanged();
|
||||
|
@ -67,7 +68,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
string path,
|
||||
OperationOutcome operationOutcome = OperationOutcome.Undetermined)
|
||||
{
|
||||
var xciApp = ApplicationLibrary.Applications.Items.First(app => app.FileExtension == _FileExtXCI && app.Path == path);
|
||||
ApplicationData xciApp = ApplicationLibrary.Applications.Items.First(app => app.FileExtension == _FileExtXCI && app.Path == path);
|
||||
return XCITrimmerFileModel.FromApplicationData(xciApp, _logger) with { ProcessingOutcome = operationOutcome };
|
||||
}
|
||||
|
||||
|
@ -156,17 +157,17 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
_processingMode = processingMode;
|
||||
Processing = true;
|
||||
var cancellationToken = _cancellationTokenSource.Token;
|
||||
CancellationToken cancellationToken = _cancellationTokenSource.Token;
|
||||
|
||||
Thread XCIFileTrimThread = new(() =>
|
||||
{
|
||||
var toProcess = Sort(SelectedXCIFiles
|
||||
List<XCITrimmerFileModel> toProcess = Sort(SelectedXCIFiles
|
||||
.Where(xci =>
|
||||
(processingMode == ProcessingMode.Untrimming && xci.Untrimmable) ||
|
||||
(processingMode == ProcessingMode.Trimming && xci.Trimmable)
|
||||
)).ToList();
|
||||
|
||||
var viewsSaved = DisplayedXCIFiles.ToList();
|
||||
List<XCITrimmerFileModel> viewsSaved = DisplayedXCIFiles.ToList();
|
||||
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
|
@ -177,19 +178,19 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
try
|
||||
{
|
||||
foreach (var xciApp in toProcess)
|
||||
foreach (XCITrimmerFileModel xciApp in toProcess)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
break;
|
||||
|
||||
var trimmer = new XCIFileTrimmer(xciApp.Path, _logger);
|
||||
XCIFileTrimmer trimmer = new XCIFileTrimmer(xciApp.Path, _logger);
|
||||
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
ProcessingApplication = xciApp;
|
||||
});
|
||||
|
||||
var outcome = OperationOutcome.Undetermined;
|
||||
OperationOutcome outcome = OperationOutcome.Undetermined;
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -347,7 +348,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
Sort(AllXCIFiles)
|
||||
.AsObservableChangeSet()
|
||||
.Filter(Filter)
|
||||
.Bind(out var view).AsObservableList();
|
||||
.Bind(out ReadOnlyObservableCollection<XCITrimmerFileModel> view).AsObservableList();
|
||||
|
||||
_displayedXCIFiles.Clear();
|
||||
_displayedXCIFiles.AddRange(view);
|
||||
|
|
|
@ -12,6 +12,7 @@ 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;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Views.Input
|
||||
|
@ -104,7 +105,7 @@ namespace Ryujinx.Ava.UI.Views.Input
|
|||
|
||||
PointerPressed += MouseClick;
|
||||
|
||||
var viewModel = (DataContext as ControllerInputViewModel);
|
||||
ControllerInputViewModel viewModel = (DataContext as ControllerInputViewModel);
|
||||
|
||||
IKeyboard keyboard =
|
||||
(IKeyboard)viewModel.ParentModel.AvaloniaKeyboardDriver
|
||||
|
@ -115,7 +116,7 @@ namespace Ryujinx.Ava.UI.Views.Input
|
|||
{
|
||||
if (e.ButtonValue.HasValue)
|
||||
{
|
||||
var buttonValue = e.ButtonValue.Value;
|
||||
Button buttonValue = e.ButtonValue.Value;
|
||||
viewModel.ParentModel.IsModified = true;
|
||||
|
||||
switch (button.Name)
|
||||
|
@ -223,7 +224,7 @@ namespace Ryujinx.Ava.UI.Views.Input
|
|||
{
|
||||
IButtonAssigner assigner;
|
||||
|
||||
var controllerInputViewModel = DataContext as ControllerInputViewModel;
|
||||
ControllerInputViewModel controllerInputViewModel = DataContext as ControllerInputViewModel;
|
||||
|
||||
assigner = new GamepadButtonAssigner(
|
||||
controllerInputViewModel.ParentModel.SelectedGamepad,
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace Ryujinx.Ava.UI.Views.Input
|
|||
{
|
||||
_dialogOpen = true;
|
||||
|
||||
var result = await ContentDialogHelper.CreateDeniableConfirmationDialog(
|
||||
UserResult result = await ContentDialogHelper.CreateDeniableConfirmationDialog(
|
||||
LocaleManager.Instance[LocaleKeys.DialogControllerSettingsModifiedConfirmMessage],
|
||||
LocaleManager.Instance[LocaleKeys.DialogControllerSettingsModifiedConfirmSubMessage],
|
||||
LocaleManager.Instance[LocaleKeys.InputDialogYes],
|
||||
|
|
|
@ -8,6 +8,7 @@ using Ryujinx.Ava.UI.Helpers;
|
|||
using Ryujinx.Ava.UI.ViewModels.Input;
|
||||
using Ryujinx.Input;
|
||||
using Ryujinx.Input.Assigner;
|
||||
using Button = Ryujinx.Input.Button;
|
||||
using Key = Ryujinx.Common.Configuration.Hid.Key;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Views.Input
|
||||
|
@ -71,7 +72,7 @@ namespace Ryujinx.Ava.UI.Views.Input
|
|||
{
|
||||
if (e.ButtonValue.HasValue)
|
||||
{
|
||||
var buttonValue = e.ButtonValue.Value;
|
||||
Button buttonValue = e.ButtonValue.Value;
|
||||
viewModel.ParentModel.IsModified = true;
|
||||
|
||||
switch (button.Name)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using Avalonia.Controls;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.UI.Models.Input;
|
||||
using Ryujinx.Ava.UI.ViewModels.Input;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
@ -17,7 +18,7 @@ namespace Ryujinx.Ava.UI.Views.Input
|
|||
|
||||
public MotionInputView(ControllerInputViewModel viewModel)
|
||||
{
|
||||
var config = viewModel.Config;
|
||||
GamepadInputConfig config = viewModel.Config;
|
||||
|
||||
_viewModel = new MotionInputViewModel
|
||||
{
|
||||
|
@ -49,7 +50,7 @@ namespace Ryujinx.Ava.UI.Views.Input
|
|||
};
|
||||
contentDialog.PrimaryButtonClick += (sender, args) =>
|
||||
{
|
||||
var config = viewModel.Config;
|
||||
GamepadInputConfig config = viewModel.Config;
|
||||
config.Slot = content._viewModel.Slot;
|
||||
config.Sensitivity = content._viewModel.Sensitivity;
|
||||
config.GyroDeadzone = content._viewModel.GyroDeadzone;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using Avalonia.Controls;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.UI.Models.Input;
|
||||
using Ryujinx.Ava.UI.ViewModels.Input;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
@ -17,7 +18,7 @@ namespace Ryujinx.Ava.UI.Views.Input
|
|||
|
||||
public RumbleInputView(ControllerInputViewModel viewModel)
|
||||
{
|
||||
var config = viewModel.Config;
|
||||
GamepadInputConfig config = viewModel.Config;
|
||||
|
||||
_viewModel = new RumbleInputViewModel
|
||||
{
|
||||
|
@ -45,7 +46,7 @@ namespace Ryujinx.Ava.UI.Views.Input
|
|||
|
||||
contentDialog.PrimaryButtonClick += (sender, args) =>
|
||||
{
|
||||
var config = viewModel.Config;
|
||||
GamepadInputConfig config = viewModel.Config;
|
||||
config.StrongRumble = content._viewModel.StrongRumble;
|
||||
config.WeakRumble = content._viewModel.WeakRumble;
|
||||
};
|
||||
|
|
|
@ -4,11 +4,14 @@ using Avalonia.Layout;
|
|||
using Avalonia.Threading;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Gommon;
|
||||
using LibHac.Common;
|
||||
using LibHac.Ns;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.UI.Helpers;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using Ryujinx.Ava.UI.Windows;
|
||||
using Ryujinx.Ava.Utilities;
|
||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||
using Ryujinx.Ava.Utilities.Compat;
|
||||
using Ryujinx.Ava.Utilities.Configuration;
|
||||
using Ryujinx.Common;
|
||||
|
@ -142,7 +145,7 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||
|
||||
public async Task OpenMiiApplet()
|
||||
{
|
||||
if (!MiiApplet.CanStart(out var appData, out var nacpData))
|
||||
if (!MiiApplet.CanStart(out ApplicationData appData, out BlitStruct<ApplicationControlProperty> nacpData))
|
||||
return;
|
||||
|
||||
await ViewModel.LoadApplication(appData, ViewModel.IsFullScreen || ViewModel.StartGamesInFullscreen, nacpData);
|
||||
|
|
|
@ -8,6 +8,7 @@ using Ryujinx.Ava.UI.Helpers;
|
|||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using Ryujinx.Input;
|
||||
using Ryujinx.Input.Assigner;
|
||||
using Button = Ryujinx.Input.Button;
|
||||
using Key = Ryujinx.Common.Configuration.Hid.Key;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Views.Settings
|
||||
|
@ -70,15 +71,15 @@ namespace Ryujinx.Ava.UI.Views.Settings
|
|||
|
||||
PointerPressed += MouseClick;
|
||||
|
||||
var keyboard = (IKeyboard)_avaloniaKeyboardDriver.GetGamepad("0");
|
||||
IKeyboard keyboard = (IKeyboard)_avaloniaKeyboardDriver.GetGamepad("0");
|
||||
IButtonAssigner assigner = new KeyboardKeyAssigner(keyboard);
|
||||
|
||||
_currentAssigner.ButtonAssigned += (sender, e) =>
|
||||
{
|
||||
if (e.ButtonValue.HasValue)
|
||||
{
|
||||
var viewModel = (DataContext) as SettingsViewModel;
|
||||
var buttonValue = e.ButtonValue.Value;
|
||||
SettingsViewModel viewModel = (DataContext) as SettingsViewModel;
|
||||
Button buttonValue = e.ButtonValue.Value;
|
||||
|
||||
switch (button.Name)
|
||||
{
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace Ryujinx.Ava.UI.Views.User
|
|||
switch (arg.NavigationMode)
|
||||
{
|
||||
case NavigationMode.New:
|
||||
var (parent, profile, isNewUser) = ((NavigationDialogHost parent, UserProfile profile, bool isNewUser))arg.Parameter;
|
||||
(NavigationDialogHost parent, UserProfile profile, bool isNewUser) = ((NavigationDialogHost parent, UserProfile profile, bool isNewUser))arg.Parameter;
|
||||
_isNewUser = isNewUser;
|
||||
_profile = profile;
|
||||
TempProfile = new TempProfile(_profile);
|
||||
|
|
|
@ -66,11 +66,11 @@ namespace Ryujinx.Ava.UI.Views.User
|
|||
{
|
||||
if (ViewModel.SelectedImage != null)
|
||||
{
|
||||
using var streamJpg = new MemoryStream();
|
||||
using var bitmap = SKBitmap.Decode(ViewModel.SelectedImage);
|
||||
using var newBitmap = new SKBitmap(bitmap.Width, bitmap.Height);
|
||||
using MemoryStream streamJpg = new MemoryStream();
|
||||
using SKBitmap bitmap = SKBitmap.Decode(ViewModel.SelectedImage);
|
||||
using SKBitmap newBitmap = new SKBitmap(bitmap.Width, bitmap.Height);
|
||||
|
||||
using (var canvas = new SKCanvas(newBitmap))
|
||||
using (SKCanvas canvas = new SKCanvas(newBitmap))
|
||||
{
|
||||
canvas.Clear(new SKColor(
|
||||
ViewModel.BackgroundColor.R,
|
||||
|
@ -80,8 +80,8 @@ namespace Ryujinx.Ava.UI.Views.User
|
|||
canvas.DrawBitmap(bitmap, 0, 0);
|
||||
}
|
||||
|
||||
using (var image = SKImage.FromBitmap(newBitmap))
|
||||
using (var dataJpeg = image.Encode(SKEncodedImageFormat.Jpeg, 100))
|
||||
using (SKImage image = SKImage.FromBitmap(newBitmap))
|
||||
using (SKData dataJpeg = image.Encode(SKEncodedImageFormat.Jpeg, 100))
|
||||
{
|
||||
dataJpeg.SaveTo(streamJpg);
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ namespace Ryujinx.Ava.UI.Views.User
|
|||
|
||||
private async void Import_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var result = await ((Window)this.GetVisualRoot()!).StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
IReadOnlyList<IStorageFile> result = await ((Window)this.GetVisualRoot()!).StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
AllowMultiple = false,
|
||||
FileTypeFilter = new List<FilePickerFileType>
|
||||
|
@ -99,16 +99,16 @@ namespace Ryujinx.Ava.UI.Views.User
|
|||
|
||||
private static byte[] ProcessProfileImage(byte[] buffer)
|
||||
{
|
||||
using var bitmap = SKBitmap.Decode(buffer);
|
||||
using SKBitmap bitmap = SKBitmap.Decode(buffer);
|
||||
|
||||
var resizedBitmap = bitmap.Resize(new SKImageInfo(256, 256), SKFilterQuality.High);
|
||||
SKBitmap resizedBitmap = bitmap.Resize(new SKImageInfo(256, 256), SKFilterQuality.High);
|
||||
|
||||
using var streamJpg = new MemoryStream();
|
||||
using MemoryStream streamJpg = new MemoryStream();
|
||||
|
||||
if (resizedBitmap != null)
|
||||
{
|
||||
using var image = SKImage.FromBitmap(resizedBitmap);
|
||||
using var dataJpeg = image.Encode(SKEncodedImageFormat.Jpeg, 100);
|
||||
using SKImage image = SKImage.FromBitmap(resizedBitmap);
|
||||
using SKData dataJpeg = image.Encode(SKEncodedImageFormat.Jpeg, 100);
|
||||
|
||||
dataJpeg.SaveTo(streamJpg);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace Ryujinx.Ava.UI.Views.User
|
|||
switch (arg.NavigationMode)
|
||||
{
|
||||
case NavigationMode.New:
|
||||
var parent = (NavigationDialogHost)arg.Parameter;
|
||||
NavigationDialogHost parent = (NavigationDialogHost)arg.Parameter;
|
||||
|
||||
_parent = parent;
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace Ryujinx.Ava.UI.Views.User
|
|||
switch (arg.NavigationMode)
|
||||
{
|
||||
case NavigationMode.New:
|
||||
var (parent, accountManager, client, virtualFileSystem) = ((NavigationDialogHost parent, AccountManager accountManager, HorizonClient client, VirtualFileSystem virtualFileSystem))arg.Parameter;
|
||||
(NavigationDialogHost parent, AccountManager accountManager, HorizonClient client, VirtualFileSystem virtualFileSystem) = ((NavigationDialogHost parent, AccountManager accountManager, HorizonClient client, VirtualFileSystem virtualFileSystem))arg.Parameter;
|
||||
_accountManager = accountManager;
|
||||
_horizonClient = client;
|
||||
_virtualFileSystem = virtualFileSystem;
|
||||
|
@ -67,15 +67,15 @@ namespace Ryujinx.Ava.UI.Views.User
|
|||
public void LoadSaves()
|
||||
{
|
||||
ViewModel.Saves.Clear();
|
||||
var saves = new ObservableCollection<SaveModel>();
|
||||
var saveDataFilter = SaveDataFilter.Make(
|
||||
ObservableCollection<SaveModel> saves = new ObservableCollection<SaveModel>();
|
||||
SaveDataFilter saveDataFilter = SaveDataFilter.Make(
|
||||
programId: default,
|
||||
saveType: SaveDataType.Account,
|
||||
new UserId((ulong)_accountManager.LastOpenedUser.UserId.High, (ulong)_accountManager.LastOpenedUser.UserId.Low),
|
||||
saveDataId: default,
|
||||
index: default);
|
||||
|
||||
using var saveDataIterator = new UniqueRef<SaveDataIterator>();
|
||||
using UniqueRef<SaveDataIterator> saveDataIterator = new UniqueRef<SaveDataIterator>();
|
||||
|
||||
_horizonClient.Fs.OpenSaveDataIterator(ref saveDataIterator.Ref, SaveDataSpaceId.User, in saveDataFilter).ThrowIfFailure();
|
||||
|
||||
|
@ -92,10 +92,10 @@ namespace Ryujinx.Ava.UI.Views.User
|
|||
|
||||
for (int i = 0; i < readCount; i++)
|
||||
{
|
||||
var save = saveDataInfo[i];
|
||||
SaveDataInfo save = saveDataInfo[i];
|
||||
if (save.ProgramId.Value != 0)
|
||||
{
|
||||
var saveModel = new SaveModel(save);
|
||||
SaveModel saveModel = new SaveModel(save);
|
||||
saves.Add(saveModel);
|
||||
}
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ namespace Ryujinx.Ava.UI.Views.User
|
|||
{
|
||||
if (button.DataContext is SaveModel saveModel)
|
||||
{
|
||||
var result = await ContentDialogHelper.CreateConfirmationDialog(LocaleManager.Instance[LocaleKeys.DeleteUserSave],
|
||||
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(LocaleManager.Instance[LocaleKeys.DeleteUserSave],
|
||||
LocaleManager.Instance[LocaleKeys.IrreversibleActionNote],
|
||||
LocaleManager.Instance[LocaleKeys.InputDialogYes],
|
||||
LocaleManager.Instance[LocaleKeys.InputDialogNo],
|
||||
|
|
|
@ -6,6 +6,7 @@ using Ryujinx.Ava.Utilities.AppLibrary;
|
|||
using Ryujinx.Ava.Utilities.Configuration;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.HLE.HOS;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
@ -58,7 +59,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
|
||||
int cheatAdded = 0;
|
||||
|
||||
var mods = new ModLoader.ModCache();
|
||||
ModLoader.ModCache mods = new ModLoader.ModCache();
|
||||
|
||||
ModLoader.QueryContentsDir(mods, new DirectoryInfo(Path.Combine(modsBasePath, "contents")), titleIdValue);
|
||||
|
||||
|
@ -67,7 +68,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
|
||||
CheatNode currentGroup = null;
|
||||
|
||||
foreach (var cheat in mods.Cheats)
|
||||
foreach (ModLoader.Cheat cheat in mods.Cheats)
|
||||
{
|
||||
if (cheat.Path.FullName != currentCheatFile)
|
||||
{
|
||||
|
@ -80,7 +81,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
LoadedCheats.Add(currentGroup);
|
||||
}
|
||||
|
||||
var model = new CheatNode(cheat.Name, buildId, string.Empty, false, enabled.Contains($"{buildId}-{cheat.Name}"));
|
||||
CheatNode model = new CheatNode(cheat.Name, buildId, string.Empty, false, enabled.Contains($"{buildId}-{cheat.Name}"));
|
||||
currentGroup?.SubNodes.Add(model);
|
||||
|
||||
cheatAdded++;
|
||||
|
@ -101,7 +102,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
if (NoCheatsFound)
|
||||
return;
|
||||
|
||||
var enabledCheats = LoadedCheats.SelectMany(it => it.SubNodes)
|
||||
IEnumerable<string> enabledCheats = LoadedCheats.SelectMany(it => it.SubNodes)
|
||||
.Where(it => it.IsEnabled)
|
||||
.Select(it => it.BuildIdKey);
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
|
||||
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
foreach (var content in e.AddedItems)
|
||||
foreach (object content in e.AddedItems)
|
||||
{
|
||||
if (content is DownloadableContentModel model)
|
||||
{
|
||||
|
@ -87,7 +87,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
}
|
||||
}
|
||||
|
||||
foreach (var content in e.RemovedItems)
|
||||
foreach (object content in e.RemovedItems)
|
||||
{
|
||||
if (content is DownloadableContentModel model)
|
||||
{
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
|
||||
public static SKColor GetFilteredColor(SKBitmap image)
|
||||
{
|
||||
var color = GetColor(image);
|
||||
SKColor color = GetColor(image);
|
||||
|
||||
|
||||
// We don't want colors that are too dark.
|
||||
|
@ -49,10 +49,10 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
|
||||
public static SKColor GetColor(SKBitmap image)
|
||||
{
|
||||
var colors = new PaletteColor[TotalColors];
|
||||
var dominantColorBin = new Dictionary<int, int>();
|
||||
PaletteColor[] colors = new PaletteColor[TotalColors];
|
||||
Dictionary<int, int> dominantColorBin = new Dictionary<int, int>();
|
||||
|
||||
var buffer = GetBuffer(image);
|
||||
SKColor[] buffer = GetBuffer(image);
|
||||
|
||||
int i = 0;
|
||||
int maxHitCount = 0;
|
||||
|
@ -70,7 +70,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
byte cg = pixel.Green;
|
||||
byte cb = pixel.Blue;
|
||||
|
||||
var qck = GetQuantizedColorKey(cr, cg, cb);
|
||||
int qck = GetQuantizedColorKey(cr, cg, cb);
|
||||
|
||||
if (dominantColorBin.TryGetValue(qck, out int hitCount))
|
||||
{
|
||||
|
@ -95,7 +95,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
|
||||
for (i = 0; i < TotalColors; i++)
|
||||
{
|
||||
var score = GetColorScore(dominantColorBin, maxHitCount, colors[i]);
|
||||
int score = GetColorScore(dominantColorBin, maxHitCount, colors[i]);
|
||||
|
||||
if (highScore < score)
|
||||
{
|
||||
|
@ -109,7 +109,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
|
||||
public static SKColor[] GetBuffer(SKBitmap image)
|
||||
{
|
||||
var pixels = new SKColor[image.Width * image.Height];
|
||||
SKColor[] pixels = new SKColor[image.Width * image.Height];
|
||||
|
||||
for (int y = 0; y < image.Height; y++)
|
||||
{
|
||||
|
@ -124,17 +124,17 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
|
||||
private static int GetColorScore(Dictionary<int, int> dominantColorBin, int maxHitCount, PaletteColor color)
|
||||
{
|
||||
var hitCount = dominantColorBin[color.Qck];
|
||||
var balancedHitCount = BalanceHitCount(hitCount, maxHitCount);
|
||||
var quantSat = (GetColorSaturation(color) >> SatQuantShift) << SatQuantShift;
|
||||
var value = GetColorValue(color);
|
||||
int hitCount = dominantColorBin[color.Qck];
|
||||
int balancedHitCount = BalanceHitCount(hitCount, maxHitCount);
|
||||
int quantSat = (GetColorSaturation(color) >> SatQuantShift) << SatQuantShift;
|
||||
int value = GetColorValue(color);
|
||||
|
||||
// If the color is rarely used on the image,
|
||||
// then chances are that there's a better candidate, even if the saturation value
|
||||
// is high. By multiplying the saturation value with a weight, we can lower
|
||||
// it if the color is almost never used (hit count is low).
|
||||
var satWeighted = quantSat;
|
||||
var satWeight = balancedHitCount << 5;
|
||||
int satWeighted = quantSat;
|
||||
int satWeight = balancedHitCount << 5;
|
||||
if (satWeight < 0x100)
|
||||
{
|
||||
satWeighted = (satWeighted * satWeight) >> 8;
|
||||
|
@ -142,7 +142,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
|
||||
// Compute score from saturation and dominance of the color.
|
||||
// We prefer more vivid colors over dominant ones, so give more weight to the saturation.
|
||||
var score = ((satWeighted << 1) + balancedHitCount) * value;
|
||||
int score = ((satWeighted << 1) + balancedHitCount) * value;
|
||||
|
||||
return score;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ using DynamicData;
|
|||
using FluentAvalonia.UI.Controls;
|
||||
using FluentAvalonia.UI.Windowing;
|
||||
using Gommon;
|
||||
using LibHac.Ns;
|
||||
using LibHac.Tools.FsSystem;
|
||||
using Ryujinx.Ava.Common;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
|
@ -171,11 +172,11 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
{
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
var ldnGameDataArray = e.LdnData.ToList();
|
||||
List<LdnGameData> ldnGameDataArray = e.LdnData.ToList();
|
||||
ViewModel.LdnData.Clear();
|
||||
foreach (var application in ViewModel.Applications.Where(it => it.HasControlHolder))
|
||||
foreach (ApplicationData application in ViewModel.Applications.Where(it => it.HasControlHolder))
|
||||
{
|
||||
ref var controlHolder = ref application.ControlHolder.Value;
|
||||
ref ApplicationControlProperty controlHolder = ref application.ControlHolder.Value;
|
||||
|
||||
ViewModel.LdnData[application.IdString] =
|
||||
LdnGameData.GetArrayForApp(
|
||||
|
@ -192,7 +193,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
|
||||
private void UpdateApplicationWithLdnData(ApplicationData application)
|
||||
{
|
||||
if (application.HasControlHolder && ViewModel.LdnData.TryGetValue(application.IdString, out var ldnGameDatas))
|
||||
if (application.HasControlHolder && ViewModel.LdnData.TryGetValue(application.IdString, out LdnGameData.Array ldnGameDatas))
|
||||
{
|
||||
application.PlayerCount = ldnGameDatas.PlayerCount;
|
||||
application.GameCount = ldnGameDatas.GameCount;
|
||||
|
@ -690,12 +691,12 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
|
||||
ApplicationLibrary.LoadApplications(ConfigurationState.Instance.UI.GameDirs);
|
||||
|
||||
var autoloadDirs = ConfigurationState.Instance.UI.AutoloadDirs.Value;
|
||||
List<string> autoloadDirs = ConfigurationState.Instance.UI.AutoloadDirs.Value;
|
||||
autoloadDirs.ForEach(dir => Logger.Info?.Print(LogClass.Application, $"Auto loading DLC & updates from: {dir}"));
|
||||
if (autoloadDirs.Count > 0)
|
||||
{
|
||||
var updatesLoaded = ApplicationLibrary.AutoLoadTitleUpdates(autoloadDirs, out int updatesRemoved);
|
||||
var dlcLoaded = ApplicationLibrary.AutoLoadDownloadableContents(autoloadDirs, out int dlcRemoved);
|
||||
int updatesLoaded = ApplicationLibrary.AutoLoadTitleUpdates(autoloadDirs, out int updatesRemoved);
|
||||
int dlcLoaded = ApplicationLibrary.AutoLoadDownloadableContents(autoloadDirs, out int dlcRemoved);
|
||||
|
||||
ShowNewContentAddedDialog(dlcLoaded, dlcRemoved, updatesLoaded, updatesRemoved);
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
{
|
||||
if (button.DataContext is ModModel model)
|
||||
{
|
||||
var result = await ContentDialogHelper.CreateConfirmationDialog(
|
||||
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(
|
||||
LocaleManager.Instance[LocaleKeys.DialogWarning],
|
||||
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogModManagerDeletionWarningMessage, model.Name),
|
||||
LocaleManager.Instance[LocaleKeys.InputDialogYes],
|
||||
|
@ -83,7 +83,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
|
||||
private async void DeleteAll(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var result = await ContentDialogHelper.CreateConfirmationDialog(
|
||||
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(
|
||||
LocaleManager.Instance[LocaleKeys.DialogWarning],
|
||||
LocaleManager.Instance[LocaleKeys.DialogModManagerDeletionAllWarningMessage],
|
||||
LocaleManager.Instance[LocaleKeys.InputDialogYes],
|
||||
|
@ -109,11 +109,11 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
|
||||
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
foreach (var content in e.AddedItems)
|
||||
foreach (object content in e.AddedItems)
|
||||
{
|
||||
if (content is ModModel model)
|
||||
{
|
||||
var index = ViewModel.Mods.IndexOf(model);
|
||||
int index = ViewModel.Mods.IndexOf(model);
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
|
@ -122,11 +122,11 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
}
|
||||
}
|
||||
|
||||
foreach (var content in e.RemovedItems)
|
||||
foreach (object content in e.RemovedItems)
|
||||
{
|
||||
if (content is ModModel model)
|
||||
{
|
||||
var index = ViewModel.Mods.IndexOf(model);
|
||||
int index = ViewModel.Mods.IndexOf(model);
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
|
|
|
@ -81,7 +81,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
|
||||
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
foreach (var content in e.AddedItems)
|
||||
foreach (object content in e.AddedItems)
|
||||
{
|
||||
if (content is XCITrimmerFileModel applicationData)
|
||||
{
|
||||
|
@ -89,7 +89,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
}
|
||||
}
|
||||
|
||||
foreach (var content in e.RemovedItems)
|
||||
foreach (object content in e.RemovedItems)
|
||||
{
|
||||
if (content is XCITrimmerFileModel applicationData)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue