From 6619de59abfa1434b5fe3da9f6c375ae347a79d9 Mon Sep 17 00:00:00 2001 From: _Neo_ Date: Thu, 25 Dec 2025 19:37:29 +0200 Subject: [PATCH] Testing new stuff --- src/Ryujinx/UI/Models/TempProfile.cs | 3 + .../UI/Views/User/UserEditorView.axaml | 31 ++++++ .../UI/Views/User/UserEditorView.axaml.cs | 95 ++++++++++++++++++- .../UserFirmwareAvatarSelectorView.axaml.cs | 7 ++ 4 files changed, 135 insertions(+), 1 deletion(-) diff --git a/src/Ryujinx/UI/Models/TempProfile.cs b/src/Ryujinx/UI/Models/TempProfile.cs index a4a4fe32f..d6d0adf83 100644 --- a/src/Ryujinx/UI/Models/TempProfile.cs +++ b/src/Ryujinx/UI/Models/TempProfile.cs @@ -10,6 +10,9 @@ namespace Ryujinx.Ava.UI.Models [ObservableProperty] public partial byte[] Image { get; set; } + [ObservableProperty] + public partial bool FirmwareFound { get; set; } + [ObservableProperty] public partial string Name { get; set; } = string.Empty; diff --git a/src/Ryujinx/UI/Views/User/UserEditorView.axaml b/src/Ryujinx/UI/Views/User/UserEditorView.axaml index 4155ae6f2..5c1e7d427 100644 --- a/src/Ryujinx/UI/Views/User/UserEditorView.axaml +++ b/src/Ryujinx/UI/Views/User/UserEditorView.axaml @@ -65,6 +65,37 @@ HorizontalAlignment="Stretch" VerticalAlignment="Top" Source="{Binding Image, Converter={x:Static helpers:BitmapArrayValueConverter.Instance}}" /> + + + diff --git a/src/Ryujinx/UI/Views/User/UserEditorView.axaml.cs b/src/Ryujinx/UI/Views/User/UserEditorView.axaml.cs index c2d52a905..c0d141188 100644 --- a/src/Ryujinx/UI/Views/User/UserEditorView.axaml.cs +++ b/src/Ryujinx/UI/Views/User/UserEditorView.axaml.cs @@ -9,13 +9,21 @@ using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Models; using Ryujinx.HLE.HOS.Services.Account.Acc; using UserProfile = Ryujinx.Ava.UI.Models.UserProfile; +using Avalonia.Platform.Storage; +using Ryujinx.HLE.FileSystem; +using SkiaSharp; +using System.Collections.Generic; +using System.IO; +using Avalonia.VisualTree; namespace Ryujinx.Ava.UI.Views.User { public partial class UserEditorView : RyujinxControl { private NavigationDialogHost _parent; + private ContentManager _contentManager; private UserProfile _profile; + private TempProfile _tempProfile; private bool _isNewUser; public static uint MaxProfileNameLength => 0x20; public bool IsDeletable => _profile.UserId != AccountManager.DefaultUserId; @@ -40,8 +48,13 @@ namespace Ryujinx.Ava.UI.Views.User _isNewUser = isNewUser; _profile = profile; ViewModel = new TempProfile(_profile); + _tempProfile = ViewModel; // <-- this is critical _parent = parent; + + _contentManager = _parent.ContentManager; + ViewModel.FirmwareFound = _contentManager.GetCurrentFirmwareVersion() != null; + break; } @@ -156,5 +169,85 @@ namespace Ryujinx.Ava.UI.Views.User SelectProfileImage(); } } + + private async void SelectFirmwareImage_OnClick(object sender, RoutedEventArgs e) + { + if (ViewModel.FirmwareFound) + { + _parent.Navigate(typeof(UserFirmwareAvatarSelectorView), (_parent, _tempProfile)); + } + } + + private async void Import_OnClick(object sender, RoutedEventArgs e) + { + var result = await ((Window)this.GetVisualRoot()!).StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions + { + Title = LocaleManager.Instance[LocaleKeys.LoadSupportedImageFormatDialogTitle], + AllowMultiple = false, + FileTypeFilter = new List + { + new(LocaleManager.Instance[LocaleKeys.AllSupportedFormats]) + { + Patterns = ["*.jpg", "*.jpeg", "*.png", "*.bmp"], + AppleUniformTypeIdentifiers = ["public.jpeg", "public.png", "com.microsoft.bmp"], + MimeTypes = ["image/jpeg", "image/png", "image/bmp"], + }, + new("JPG") + { + Patterns = ["*.jpg"], + AppleUniformTypeIdentifiers = ["public.jpeg"], + MimeTypes = ["image/jpeg"], + }, + new("JPEG") + { + Patterns = ["*.jpeg"], + AppleUniformTypeIdentifiers = ["public.jpeg"], + MimeTypes = ["image/jpeg"], + }, + new("PNG") + { + Patterns = ["*.png"], + AppleUniformTypeIdentifiers = ["public.png"], + MimeTypes = ["image/png"], + }, + new("BMP") + { + Patterns = ["*.bmp"], + AppleUniformTypeIdentifiers = ["com.microsoft.bmp"], + MimeTypes = ["image/bmp"], + }, + }, + }); + + if (result.Count == 0) + return; + + if (DataContext is not TempProfile temp) + return; + + temp.Image = ProcessProfileImage(File.ReadAllBytes(result[0].Path.LocalPath)); + + if (_profile != null) + _profile.Image = temp.Image; + } + + private static byte[] ProcessProfileImage(byte[] buffer) + { + using SKBitmap bitmap = SKBitmap.Decode(buffer); + + SKBitmap resizedBitmap = bitmap.Resize(new SKImageInfo(256, 256), SKFilterQuality.High); + + using MemoryStream streamJpg = new(); + + if (resizedBitmap != null) + { + using SKImage image = SKImage.FromBitmap(resizedBitmap); + using SKData dataJpeg = image.Encode(SKEncodedImageFormat.Jpeg, 100); + + dataJpeg.SaveTo(streamJpg); + } + + return streamJpg.ToArray(); + } } -} +} \ No newline at end of file diff --git a/src/Ryujinx/UI/Views/User/UserFirmwareAvatarSelectorView.axaml.cs b/src/Ryujinx/UI/Views/User/UserFirmwareAvatarSelectorView.axaml.cs index f34d8f603..f05feb98c 100644 --- a/src/Ryujinx/UI/Views/User/UserFirmwareAvatarSelectorView.axaml.cs +++ b/src/Ryujinx/UI/Views/User/UserFirmwareAvatarSelectorView.axaml.cs @@ -3,6 +3,7 @@ using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Navigation; using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.Models; +using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.UI.ViewModels; using Ryujinx.HLE.FileSystem; using SkiaSharp; @@ -14,12 +15,14 @@ namespace Ryujinx.Ava.UI.Views.User { private NavigationDialogHost _parent; private TempProfile _profile; + private ContentManager _contentManager; public UserFirmwareAvatarSelectorView(ContentManager contentManager) { ContentManager = contentManager; InitializeComponent(); + AddHandler(Frame.NavigatedToEvent, (s, e) => NavigatedTo(e), RoutingStrategies.Direct); } public UserFirmwareAvatarSelectorView() @@ -40,9 +43,13 @@ namespace Ryujinx.Ava.UI.Views.User { (_parent, _profile) = ((NavigationDialogHost, TempProfile))arg.Parameter; ContentManager = _parent.ContentManager; + + ((ContentDialog)_parent.Parent).Title = $"{LocaleManager.Instance[LocaleKeys.UserProfileWindowTitle]} - {LocaleManager.Instance[LocaleKeys.ProfileImageSelectionHeader]}"; + if (Program.PreviewerDetached) { ViewModel = new UserFirmwareAvatarSelectorViewModel(); + ViewModel.FirmwareFound = ContentManager.GetCurrentFirmwareVersion() != null; } DataContext = ViewModel;