Merge branch 'master' into master

This commit is contained in:
Vladimir Sokolov 2025-02-12 13:27:41 +10:00 committed by GitHub
commit 22299e69c6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 91 additions and 80 deletions

View File

@ -158,13 +158,15 @@ namespace Ryujinx.HLE.HOS.Applets.Error
string[] buttons = GetButtonsText(module, description, "DlgBtn"); string[] buttons = GetButtonsText(module, description, "DlgBtn");
bool showDetails = _horizon.Device.UIHandler.DisplayErrorAppletDialog($"Error Code: {module}-{description:0000}", "\n" + message, buttons); (uint Module, uint Description) errorCodeTuple = (module, uint.Parse(description.ToString("0000")));
bool showDetails = _horizon.Device.UIHandler.DisplayErrorAppletDialog($"Error Code: {module}-{description:0000}", "\n" + message, buttons, errorCodeTuple);
if (showDetails) if (showDetails)
{ {
message = GetMessageText(module, description, "FlvMsg"); message = GetMessageText(module, description, "FlvMsg");
buttons = GetButtonsText(module, description, "FlvBtn"); buttons = GetButtonsText(module, description, "FlvBtn");
_horizon.Device.UIHandler.DisplayErrorAppletDialog($"Details: {module}-{description:0000}", "\n" + message, buttons); _horizon.Device.UIHandler.DisplayErrorAppletDialog($"Details: {module}-{description:0000}", "\n" + message, buttons, errorCodeTuple);
} }
} }

View File

@ -45,10 +45,12 @@ namespace Ryujinx.HLE.UI
/// <param name="value">The value associated to the <paramref name="kind"/>.</param> /// <param name="value">The value associated to the <paramref name="kind"/>.</param>
void ExecuteProgram(Switch device, ProgramSpecifyKind kind, ulong value); void ExecuteProgram(Switch device, ProgramSpecifyKind kind, ulong value);
/// <summary>
/// Displays a Message Dialog box specific to Error Applet and blocks until it is closed. /// Displays a Message Dialog box specific to Error Applet and blocks until it is closed.
/// </summary> /// </summary>
/// <returns>False when OK is pressed, True when another button (Details) is pressed.</returns> /// <returns>False when OK is pressed, True when another button (Details) is pressed.</returns>
bool DisplayErrorAppletDialog(string title, string message, string[] buttonsText); // ReSharper disable once UnusedParameter.Global
bool DisplayErrorAppletDialog(string title, string message, string[] buttonsText, (uint Module, uint Description)? errorCode = null);
/// <summary> /// <summary>
/// Creates a handler to process keyboard inputs into text strings. /// Creates a handler to process keyboard inputs into text strings.

View File

@ -513,7 +513,7 @@ namespace Ryujinx.Headless
Exit(); Exit();
} }
public bool DisplayErrorAppletDialog(string title, string message, string[] buttonsText) public bool DisplayErrorAppletDialog(string title, string message, string[] buttonsText, (uint Module, uint Description)? errorCode = null)
{ {
SDL_MessageBoxData data = new() SDL_MessageBoxData data = new()
{ {
@ -521,7 +521,7 @@ namespace Ryujinx.Headless
message = message, message = message,
buttons = new SDL_MessageBoxButtonData[buttonsText.Length], buttons = new SDL_MessageBoxButtonData[buttonsText.Length],
numbuttons = buttonsText.Length, numbuttons = buttonsText.Length,
window = WindowHandle, window = WindowHandle
}; };
for (int i = 0; i < buttonsText.Length; i++) for (int i = 0; i < buttonsText.Length; i++)

View File

@ -92,7 +92,8 @@ namespace Ryujinx.Ava.UI.Applet
opened = true; opened = true;
_parent.SettingsWindow = new SettingsWindow(_parent.VirtualFileSystem, _parent.ContentManager); _parent.SettingsWindow =
new SettingsWindow(_parent.VirtualFileSystem, _parent.ContentManager);
await _parent.SettingsWindow.ShowDialog(window); await _parent.SettingsWindow.ShowDialog(window);
@ -110,7 +111,9 @@ namespace Ryujinx.Ava.UI.Applet
} }
catch (Exception ex) catch (Exception ex)
{ {
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogMessageDialogErrorExceptionMessage, ex)); await ContentDialogHelper.CreateErrorDialog(
LocaleManager.Instance.UpdateAndGetDynamicValue(
LocaleKeys.DialogMessageDialogErrorExceptionMessage, ex));
dialogCloseEvent.Set(); dialogCloseEvent.Set();
} }
@ -134,7 +137,9 @@ namespace Ryujinx.Ava.UI.Applet
try try
{ {
_parent.ViewModel.AppHost.NpadManager.BlockInputUpdates(); _parent.ViewModel.AppHost.NpadManager.BlockInputUpdates();
(UserResult result, string userInput) = await SwkbdAppletDialog.ShowInputDialog(LocaleManager.Instance[LocaleKeys.SoftwareKeyboard], args); (UserResult result, string userInput) =
await SwkbdAppletDialog.ShowInputDialog(LocaleManager.Instance[LocaleKeys.SoftwareKeyboard],
args);
if (result == UserResult.Ok) if (result == UserResult.Ok)
{ {
@ -146,7 +151,9 @@ namespace Ryujinx.Ava.UI.Applet
{ {
error = true; error = true;
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogSoftwareKeyboardErrorExceptionMessage, ex)); await ContentDialogHelper.CreateErrorDialog(
LocaleManager.Instance.UpdateAndGetDynamicValue(
LocaleKeys.DialogSoftwareKeyboardErrorExceptionMessage, ex));
} }
finally finally
{ {
@ -177,7 +184,8 @@ namespace Ryujinx.Ava.UI.Applet
args.InitialText = "Ryujinx"; args.InitialText = "Ryujinx";
args.StringLengthMin = 1; args.StringLengthMin = 1;
args.StringLengthMax = 25; args.StringLengthMax = 25;
(UserResult result, string userInput) = await SwkbdAppletDialog.ShowInputDialog(LocaleManager.Instance[LocaleKeys.CabinetDialog], args); (UserResult result, string userInput) =
await SwkbdAppletDialog.ShowInputDialog(LocaleManager.Instance[LocaleKeys.CabinetDialog], args);
if (result == UserResult.Ok) if (result == UserResult.Ok)
{ {
inputText = userInput; inputText = userInput;
@ -201,11 +209,13 @@ namespace Ryujinx.Ava.UI.Applet
Dispatcher.UIThread.InvokeAsync(async () => Dispatcher.UIThread.InvokeAsync(async () =>
{ {
dialogCloseEvent.Set(); dialogCloseEvent.Set();
await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.CabinetScanDialog], await ContentDialogHelper.CreateInfoDialog(
LocaleManager.Instance[LocaleKeys.CabinetScanDialog],
string.Empty, string.Empty,
LocaleManager.Instance[LocaleKeys.InputDialogOk], LocaleManager.Instance[LocaleKeys.InputDialogOk],
string.Empty, string.Empty,
LocaleManager.Instance[LocaleKeys.CabinetTitle]); LocaleManager.Instance[LocaleKeys.CabinetTitle]
);
}); });
dialogCloseEvent.WaitOne(); dialogCloseEvent.WaitOne();
} }
@ -217,7 +227,8 @@ namespace Ryujinx.Ava.UI.Applet
_parent.ViewModel.AppHost?.Stop(); _parent.ViewModel.AppHost?.Stop();
} }
public bool DisplayErrorAppletDialog(string title, string message, string[] buttons) public bool DisplayErrorAppletDialog(string title, string message, string[] buttons,
(uint Module, uint Description)? errorCode = null)
{ {
ManualResetEvent dialogCloseEvent = new(false); ManualResetEvent dialogCloseEvent = new(false);
@ -229,9 +240,7 @@ namespace Ryujinx.Ava.UI.Applet
{ {
ErrorAppletWindow msgDialog = new(_parent, buttons, message) ErrorAppletWindow msgDialog = new(_parent, buttons, message)
{ {
Title = title, Title = title, WindowStartupLocation = WindowStartupLocation.CenterScreen, Width = 400
WindowStartupLocation = WindowStartupLocation.CenterScreen,
Width = 400
}; };
object response = await msgDialog.Run(); object response = await msgDialog.Run();
@ -249,7 +258,9 @@ namespace Ryujinx.Ava.UI.Applet
{ {
dialogCloseEvent.Set(); dialogCloseEvent.Set();
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogErrorAppletErrorExceptionMessage, ex)); await ContentDialogHelper.CreateErrorDialog(
LocaleManager.Instance.UpdateAndGetDynamicValue(
LocaleKeys.DialogErrorAppletErrorExceptionMessage, ex));
} }
}); });
@ -278,13 +289,11 @@ namespace Ryujinx.Ava.UI.Applet
.ForEach(profile => profiles.Add(new Models.UserProfile(profile, nav))); .ForEach(profile => profiles.Add(new Models.UserProfile(profile, nav)));
profiles.Add(new Models.UserProfile(guest, nav)); profiles.Add(new Models.UserProfile(guest, nav));
UserSelectorDialogViewModel viewModel = new() ProfileSelectorDialogViewModel viewModel = new()
{ {
Profiles = profiles, Profiles = profiles, SelectedUserId = _parent.AccountManager.LastOpenedUser.UserId
SelectedUserId = _parent.AccountManager.LastOpenedUser.UserId
}; };
UserSelectorDialog content = new(viewModel); (selected, _) = await ProfileSelectorDialog.ShowInputDialog(viewModel);
(selected, _) = await UserSelectorDialog.ShowInputDialog(content);
dialogCloseEvent.Set(); dialogCloseEvent.Set();
}); });
@ -311,6 +320,7 @@ namespace Ryujinx.Ava.UI.Applet
} }
} }
} }
return profile; return profile;
} }
} }

View File

@ -1,5 +1,5 @@
<UserControl <UserControl
x:Class="Ryujinx.Ava.UI.Applet.UserSelectorDialog" x:Class="Ryujinx.Ava.UI.Applet.ProfileSelectorDialog"
xmlns="https://github.com/avaloniaui" xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
@ -12,9 +12,9 @@
d:DesignWidth="800" d:DesignWidth="800"
mc:Ignorable="d" mc:Ignorable="d"
Focusable="True" Focusable="True"
x:DataType="viewModels:UserSelectorDialogViewModel"> x:DataType="viewModels:ProfileSelectorDialogViewModel">
<Design.DataContext> <Design.DataContext>
<viewModels:UserSelectorDialogViewModel /> <viewModels:ProfileSelectorDialogViewModel />
</Design.DataContext> </Design.DataContext>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">

View File

@ -16,15 +16,15 @@ using UserProfileSft = Ryujinx.HLE.HOS.Services.Account.Acc.UserProfile;
namespace Ryujinx.Ava.UI.Applet namespace Ryujinx.Ava.UI.Applet
{ {
public partial class UserSelectorDialog : UserControl, INotifyPropertyChanged public partial class ProfileSelectorDialog : UserControl
{ {
public UserSelectorDialogViewModel ViewModel { get; set; } public ProfileSelectorDialogViewModel ViewModel { get; set; }
public UserSelectorDialog(UserSelectorDialogViewModel viewModel) public ProfileSelectorDialog(ProfileSelectorDialogViewModel viewModel)
{ {
DataContext = ViewModel = viewModel;
InitializeComponent(); InitializeComponent();
ViewModel = viewModel;
DataContext = ViewModel;
} }
private void Grid_PointerEntered(object sender, PointerEventArgs e) private void Grid_PointerEntered(object sender, PointerEventArgs e)
@ -54,7 +54,7 @@ namespace Ryujinx.Ava.UI.Applet
if (ViewModel.Profiles[selectedIndex] is UserProfile userProfile) if (ViewModel.Profiles[selectedIndex] is UserProfile userProfile)
{ {
ViewModel.SelectedUserId = userProfile.UserId; ViewModel.SelectedUserId = userProfile.UserId;
Logger.Info?.Print(LogClass.UI, $"Selected user: {userProfile.UserId}"); Logger.Info?.Print(LogClass.UI, $"Selected: {userProfile.UserId}", "ProfileSelector");
ObservableCollection<BaseModel> newProfiles = []; ObservableCollection<BaseModel> newProfiles = [];
@ -79,7 +79,7 @@ namespace Ryujinx.Ava.UI.Applet
} }
} }
public static async Task<(UserId Id, bool Result)> ShowInputDialog(UserSelectorDialog content) public static async Task<(UserId Id, bool Result)> ShowInputDialog(ProfileSelectorDialogViewModel viewModel)
{ {
ContentDialog contentDialog = new() ContentDialog contentDialog = new()
{ {
@ -87,35 +87,32 @@ namespace Ryujinx.Ava.UI.Applet
PrimaryButtonText = LocaleManager.Instance[LocaleKeys.Continue], PrimaryButtonText = LocaleManager.Instance[LocaleKeys.Continue],
SecondaryButtonText = string.Empty, SecondaryButtonText = string.Empty,
CloseButtonText = LocaleManager.Instance[LocaleKeys.Cancel], CloseButtonText = LocaleManager.Instance[LocaleKeys.Cancel],
Content = content, Content = new ProfileSelectorDialog(viewModel),
Padding = new Thickness(0) Padding = new Thickness(0)
}; };
UserId result = UserId.Null; UserId result = UserId.Null;
bool input = false; bool input = false;
contentDialog.Closed += Handler;
await ContentDialogHelper.ShowAsync(contentDialog);
return (result, input);
void Handler(ContentDialog sender, ContentDialogClosedEventArgs eventArgs) void Handler(ContentDialog sender, ContentDialogClosedEventArgs eventArgs)
{ {
if (eventArgs.Result == ContentDialogResult.Primary) if (eventArgs.Result == ContentDialogResult.Primary)
{ {
if (contentDialog.Content is UserSelectorDialog view) result = viewModel.SelectedUserId;
{
result = view.ViewModel.SelectedUserId;
input = true; input = true;
} }
}
else else
{ {
result = UserId.Null; result = UserId.Null;
input = false; input = false;
} }
} }
contentDialog.Closed += Handler;
await ContentDialogHelper.ShowAsync(contentDialog);
return (result, input);
} }
} }
} }

View File

@ -264,7 +264,7 @@ namespace Ryujinx.Ava.UI.ViewModels
Logger.Error?.Print(LogClass.Application, $"Couldn't get valid amiibo data: {exception}"); Logger.Error?.Print(LogClass.Application, $"Couldn't get valid amiibo data: {exception}");
// Neither local or remote files are valid JSON, close window. // Neither local or remote files are valid JSON, close window.
ShowInfoDialog(); await ShowInfoDialog();
Close(); Close();
} }
else if (!remoteIsValid) else if (!remoteIsValid)
@ -273,7 +273,7 @@ namespace Ryujinx.Ava.UI.ViewModels
// Only the local file is valid, the local one should be used // Only the local file is valid, the local one should be used
// but the user should be warned. // but the user should be warned.
ShowInfoDialog(); await ShowInfoDialog();
} }
} }
@ -525,7 +525,7 @@ namespace Ryujinx.Ava.UI.ViewModels
AmiiboImage = bitmap; AmiiboImage = bitmap;
} }
private static async void ShowInfoDialog() private static async Task ShowInfoDialog()
{ {
await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.DialogAmiiboApiTitle], await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.DialogAmiiboApiTitle],
LocaleManager.Instance[LocaleKeys.DialogAmiiboApiConnectErrorMessage], LocaleManager.Instance[LocaleKeys.DialogAmiiboApiConnectErrorMessage],

View File

@ -4,7 +4,7 @@ using System.Collections.ObjectModel;
namespace Ryujinx.Ava.UI.ViewModels namespace Ryujinx.Ava.UI.ViewModels
{ {
public partial class UserSelectorDialogViewModel : BaseModel public partial class ProfileSelectorDialogViewModel : BaseModel
{ {
[ObservableProperty] private UserId _selectedUserId; [ObservableProperty] private UserId _selectedUserId;

View File

@ -290,12 +290,12 @@
<Binding Path="UpdateAvailable" /> <Binding Path="UpdateAvailable" />
</MultiBinding> </MultiBinding>
</StackPanel.IsVisible> </StackPanel.IsVisible>
<Button Margin="0, 0, 5, 0" <Button Margin="0, 0, 5, -2"
Command="{Binding UpdateCommand}" Command="{Binding UpdateCommand}"
Background="{DynamicResource SystemAccentColor}"> Background="{DynamicResource SystemAccentColor}">
<TextBlock <TextBlock
Margin="-5" Margin="-5"
Foreground="Black" Foreground="{StaticResource SystemColorButtonTextColor}"
HorizontalAlignment="Right" HorizontalAlignment="Right"
VerticalAlignment="Center" VerticalAlignment="Center"
Text="{ext:Locale UpdaterBackgroundStatusBarButtonText}" /> Text="{ext:Locale UpdaterBackgroundStatusBarButtonText}" />