diff --git a/Ryujinx.Ava/App.axaml.cs b/Ryujinx.Ava/App.axaml.cs
index ef295a611e..180c74b438 100644
--- a/Ryujinx.Ava/App.axaml.cs
+++ b/Ryujinx.Ava/App.axaml.cs
@@ -55,7 +55,6 @@ namespace Ryujinx.Ava
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
var result = await ContentDialogHelper.CreateConfirmationDialog(
- (desktop.MainWindow as MainWindow).SettingsWindow,
LocaleManager.Instance["DialogThemeRestartMessage"],
LocaleManager.Instance["DialogThemeRestartSubMessage"],
LocaleManager.Instance["InputDialogYes"],
diff --git a/Ryujinx.Ava/AppHost.cs b/Ryujinx.Ava/AppHost.cs
index 55693ed381..c6f2265ccf 100644
--- a/Ryujinx.Ava/AppHost.cs
+++ b/Ryujinx.Ava/AppHost.cs
@@ -417,10 +417,12 @@ namespace Ryujinx.Ava
{
if (userError == UserError.NoFirmware)
{
- string message = string.Format(LocaleManager.Instance["DialogFirmwareInstallEmbeddedMessage"], firmwareVersion.VersionString);
+ string message = string.Format(LocaleManager.Instance["DialogFirmwareInstallEmbeddedMessage"],
+ firmwareVersion.VersionString);
- UserResult result = await ContentDialogHelper.CreateConfirmationDialog(_parent,
- LocaleManager.Instance["DialogFirmwareNoFirmwareInstalledMessage"], message, LocaleManager.Instance["InputDialogYes"], LocaleManager.Instance["InputDialogNo"], "");
+ UserResult result = await ContentDialogHelper.CreateConfirmationDialog(
+ LocaleManager.Instance["DialogFirmwareNoFirmwareInstalledMessage"], message,
+ LocaleManager.Instance["InputDialogYes"], LocaleManager.Instance["InputDialogNo"], "");
if (result != UserResult.Yes)
{
@@ -450,12 +452,12 @@ namespace Ryujinx.Ava
string message = string.Format(LocaleManager.Instance["DialogFirmwareInstallEmbeddedSuccessMessage"], firmwareVersion.VersionString);
- await ContentDialogHelper.CreateInfoDialog(_parent,
- string.Format(LocaleManager.Instance["DialogFirmwareInstalledMessage"], firmwareVersion.VersionString),
- message,
- LocaleManager.Instance["InputDialogOk"],
- "",
- LocaleManager.Instance["RyujinxInfo"]);
+ await ContentDialogHelper.CreateInfoDialog(
+ string.Format(LocaleManager.Instance["DialogFirmwareInstalledMessage"], firmwareVersion.VersionString),
+ message,
+ LocaleManager.Instance["InputDialogOk"],
+ "",
+ LocaleManager.Instance["RyujinxInfo"]);
}
}
else
@@ -879,7 +881,7 @@ namespace Ryujinx.Ava
}
_dialogShown = true;
- shouldExit = await ContentDialogHelper.CreateStopEmulationDialog(_parent);
+ shouldExit = await ContentDialogHelper.CreateStopEmulationDialog();
_dialogShown = false;
}
@@ -896,7 +898,7 @@ namespace Ryujinx.Ava
{
Dispatcher.UIThread.Post(() =>
{
- _parent.Cursor = _isMouseInRenderer ? InvisibleCursor : Cursor.Default;
+ _parent.Cursor = _isMouseInRenderer ? InvisibleCursor : Cursor.Default;
});
}
else
diff --git a/Ryujinx.Ava/Assets/Locales/en_US.json b/Ryujinx.Ava/Assets/Locales/en_US.json
index 2aaf52e096..dd18dd9eee 100644
--- a/Ryujinx.Ava/Assets/Locales/en_US.json
+++ b/Ryujinx.Ava/Assets/Locales/en_US.json
@@ -256,8 +256,8 @@
"UserProfilesSaveProfileName": "Save Profile Name",
"UserProfilesChangeProfileImage": "Change Profile Image",
"UserProfilesAvailableUserProfiles": "Available User Profiles:",
- "UserProfilesAddNewProfile": "Add New Profile",
- "UserProfilesDeleteSelectedProfile": "Delete Selected Profile",
+ "UserProfilesAddNewProfile": "Create Profile",
+ "UserProfilesDeleteSelectedProfile": "Delete Selected",
"UserProfilesClose": "Close",
"ProfileImageSelectionTitle": "Profile Image Selection",
"ProfileImageSelectionHeader": "Choose a profile Image",
@@ -568,5 +568,12 @@
"UpdateWindowTitle": "Manage Game Updates",
"CheatWindowHeading": "Cheats Available for {0} [{1}]",
"DlcWindowHeading": "DLC Available for {0} [{1}]",
+ "UserProfilesEditProfile": "Edit Selected",
+ "Cancel": "Cancel",
+ "Save": "Save",
+ "Discard": "Discard",
+ "UserProfilesSetProfileImage": "Set Profile Image",
+ "UserProfileEmptyNameError": "Name is required",
+ "UserProfileNoImageError": "Profile image must be set",
"GameUpdateWindowHeading": "Updates Available for {0} [{1}]"
}
diff --git a/Ryujinx.Ava/Common/ApplicationHelper.cs b/Ryujinx.Ava/Common/ApplicationHelper.cs
index d83ca2c115..6cbe9d160f 100644
--- a/Ryujinx.Ava/Common/ApplicationHelper.cs
+++ b/Ryujinx.Ava/Common/ApplicationHelper.cs
@@ -81,7 +81,6 @@ namespace Ryujinx.Ava.Common
Dispatcher.UIThread.Post(async () =>
{
await ContentDialogHelper.CreateErrorDialog(
- _owner,
string.Format(LocaleManager.Instance["DialogMessageCreateSaveErrorMessage"], result.ToStringWithName()));
});
@@ -101,8 +100,7 @@ namespace Ryujinx.Ava.Common
Dispatcher.UIThread.Post(async () =>
{
- await ContentDialogHelper.CreateErrorDialog(_owner,
- string.Format(LocaleManager.Instance["DialogMessageFindSaveErrorMessage"], result.ToStringWithName()));
+ await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance["DialogMessageFindSaveErrorMessage"], result.ToStringWithName()));
});
return false;
@@ -161,7 +159,6 @@ namespace Ryujinx.Ava.Common
Dispatcher.UIThread.Post(async () =>
{
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(
- _owner,
string.Format(LocaleManager.Instance["DialogNcaExtractionMessage"], ncaSectionType, Path.GetFileName(titleFilePath)),
"",
"",
@@ -232,7 +229,7 @@ namespace Ryujinx.Ava.Common
"Extraction failure. The main NCA was not present in the selected file");
Dispatcher.UIThread.InvokeAsync(async () =>
{
- await ContentDialogHelper.CreateErrorDialog(_owner, LocaleManager.Instance["DialogNcaExtractionMainNcaNotFoundErrorMessage"]);
+ await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogNcaExtractionMainNcaNotFoundErrorMessage"]);
});
return;
}
@@ -273,7 +270,7 @@ namespace Ryujinx.Ava.Common
$"LibHac returned error code: {resultCode.Value.ErrorCode}");
Dispatcher.UIThread.InvokeAsync(async () =>
{
- await ContentDialogHelper.CreateErrorDialog(_owner, LocaleManager.Instance["DialogNcaExtractionCheckLogErrorMessage"]);
+ await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogNcaExtractionCheckLogErrorMessage"]);
});
}
else if (resultCode.Value.IsSuccess())
@@ -281,7 +278,6 @@ namespace Ryujinx.Ava.Common
Dispatcher.UIThread.InvokeAsync(async () =>
{
await ContentDialogHelper.CreateInfoDialog(
- _owner,
LocaleManager.Instance["DialogNcaExtractionSuccessMessage"],
"",
LocaleManager.Instance["InputDialogOk"],
@@ -298,7 +294,7 @@ namespace Ryujinx.Ava.Common
{
Dispatcher.UIThread.InvokeAsync(async () =>
{
- await ContentDialogHelper.CreateErrorDialog(_owner, ex.Message);
+ await ContentDialogHelper.CreateErrorDialog(ex.Message);
});
}
}
diff --git a/Ryujinx.Ava/Modules/Updater/Updater.cs b/Ryujinx.Ava/Modules/Updater/Updater.cs
index 362435c872..bbcf667905 100644
--- a/Ryujinx.Ava/Modules/Updater/Updater.cs
+++ b/Ryujinx.Ava/Modules/Updater/Updater.cs
@@ -76,7 +76,7 @@ namespace Ryujinx.Modules
Logger.Error?.Print(LogClass.Application, "Failed to convert the current Ryujinx version!");
Dispatcher.UIThread.Post(async () =>
{
- await ContentDialogHelper.CreateWarningDialog(mainWindow, LocaleManager.Instance["DialogUpdaterConvertFailedMessage"], LocaleManager.Instance["DialogUpdaterCancelUpdateMessage"]);
+ await ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance["DialogUpdaterConvertFailedMessage"], LocaleManager.Instance["DialogUpdaterCancelUpdateMessage"]);
});
return;
@@ -111,7 +111,7 @@ namespace Ryujinx.Modules
{
Dispatcher.UIThread.Post(async () =>
{
- await ContentDialogHelper.CreateUpdaterInfoDialog(mainWindow, LocaleManager.Instance["DialogUpdaterAlreadyOnLatestVersionMessage"], "");
+ await ContentDialogHelper.CreateUpdaterInfoDialog(LocaleManager.Instance["DialogUpdaterAlreadyOnLatestVersionMessage"], "");
});
}
@@ -129,7 +129,7 @@ namespace Ryujinx.Modules
{
Dispatcher.UIThread.Post(async () =>
{
- await ContentDialogHelper.CreateUpdaterInfoDialog(mainWindow, LocaleManager.Instance["DialogUpdaterAlreadyOnLatestVersionMessage"], "");
+ await ContentDialogHelper.CreateUpdaterInfoDialog(LocaleManager.Instance["DialogUpdaterAlreadyOnLatestVersionMessage"], "");
});
}
@@ -142,7 +142,7 @@ namespace Ryujinx.Modules
Logger.Error?.Print(LogClass.Application, exception.Message);
Dispatcher.UIThread.Post(async () =>
{
- await ContentDialogHelper.CreateErrorDialog(mainWindow, LocaleManager.Instance["DialogUpdaterFailedToGetVersionMessage"]);
+ await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogUpdaterFailedToGetVersionMessage"]);
});
return;
@@ -157,7 +157,7 @@ namespace Ryujinx.Modules
Logger.Error?.Print(LogClass.Application, "Failed to convert the received Ryujinx version from Github!");
Dispatcher.UIThread.Post(async () =>
{
- await ContentDialogHelper.CreateWarningDialog(mainWindow, LocaleManager.Instance["DialogUpdaterConvertFailedGithubMessage"], LocaleManager.Instance["DialogUpdaterCancelUpdateMessage"]);
+ await ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance["DialogUpdaterConvertFailedGithubMessage"], LocaleManager.Instance["DialogUpdaterCancelUpdateMessage"]);
});
return;
@@ -169,7 +169,7 @@ namespace Ryujinx.Modules
{
Dispatcher.UIThread.Post(async () =>
{
- await ContentDialogHelper.CreateUpdaterInfoDialog(mainWindow, LocaleManager.Instance["DialogUpdaterAlreadyOnLatestVersionMessage"], "");
+ await ContentDialogHelper.CreateUpdaterInfoDialog(LocaleManager.Instance["DialogUpdaterAlreadyOnLatestVersionMessage"], "");
});
}
@@ -550,7 +550,7 @@ namespace Ryujinx.Modules
{
if (showWarnings)
{
- ContentDialogHelper.CreateWarningDialog(parent, LocaleManager.Instance["DialogUpdaterArchNotSupportedMessage"],
+ ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance["DialogUpdaterArchNotSupportedMessage"],
LocaleManager.Instance["DialogUpdaterArchNotSupportedSubMessage"]);
}
@@ -561,7 +561,7 @@ namespace Ryujinx.Modules
{
if (showWarnings)
{
- ContentDialogHelper.CreateWarningDialog(parent, LocaleManager.Instance["DialogUpdaterNoInternetMessage"],
+ ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance["DialogUpdaterNoInternetMessage"],
LocaleManager.Instance["DialogUpdaterNoInternetSubMessage"]);
}
@@ -572,7 +572,7 @@ namespace Ryujinx.Modules
{
if (showWarnings)
{
- ContentDialogHelper.CreateWarningDialog(parent, LocaleManager.Instance["DialogUpdaterDirtyBuildMessage"],
+ ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance["DialogUpdaterDirtyBuildMessage"],
LocaleManager.Instance["DialogUpdaterDirtyBuildSubMessage"]);
}
@@ -585,13 +585,11 @@ namespace Ryujinx.Modules
{
if (ReleaseInformations.IsFlatHubBuild())
{
- ContentDialogHelper.CreateWarningDialog(parent,
- LocaleManager.Instance["UpdaterDisabledWarningTitle"], LocaleManager.Instance["DialogUpdaterFlatpakNotSupportedMessage"]);
+ ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance["UpdaterDisabledWarningTitle"], LocaleManager.Instance["DialogUpdaterFlatpakNotSupportedMessage"]);
}
else
{
- ContentDialogHelper.CreateWarningDialog(parent,
- LocaleManager.Instance["UpdaterDisabledWarningTitle"], LocaleManager.Instance["DialogUpdaterDirtyBuildSubMessage"]);
+ ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance["UpdaterDisabledWarningTitle"], LocaleManager.Instance["DialogUpdaterDirtyBuildSubMessage"]);
}
}
diff --git a/Ryujinx.Ava/Ryujinx.Ava.csproj b/Ryujinx.Ava/Ryujinx.Ava.csproj
index 2f0f342d42..67e159f623 100644
--- a/Ryujinx.Ava/Ryujinx.Ava.csproj
+++ b/Ryujinx.Ava/Ryujinx.Ava.csproj
@@ -26,6 +26,7 @@
+
diff --git a/Ryujinx.Ava/Ui/Applet/AvaHostUiHandler.cs b/Ryujinx.Ava/Ui/Applet/AvaHostUiHandler.cs
index f129cd710c..133bcc038c 100644
--- a/Ryujinx.Ava/Ui/Applet/AvaHostUiHandler.cs
+++ b/Ryujinx.Ava/Ui/Applet/AvaHostUiHandler.cs
@@ -92,7 +92,7 @@ namespace Ryujinx.Ava.Ui.Applet
}
catch (Exception ex)
{
- await ContentDialogHelper.CreateErrorDialog(_parent, string.Format(LocaleManager.Instance["DialogMessageDialogErrorExceptionMessage"], ex));
+ await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance["DialogMessageDialogErrorExceptionMessage"], ex));
dialogCloseEvent.Set();
}
@@ -126,7 +126,7 @@ namespace Ryujinx.Ava.Ui.Applet
catch (Exception ex)
{
error = true;
- await ContentDialogHelper.CreateErrorDialog(_parent, string.Format(LocaleManager.Instance["DialogSoftwareKeyboardErrorExceptionMessage"], ex));
+ await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance["DialogSoftwareKeyboardErrorExceptionMessage"], ex));
}
finally
{
@@ -181,7 +181,7 @@ namespace Ryujinx.Ava.Ui.Applet
catch (Exception ex)
{
dialogCloseEvent.Set();
- await ContentDialogHelper.CreateErrorDialog(_parent, string.Format(LocaleManager.Instance["DialogErrorAppletErrorExceptionMessage"], ex));
+ await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance["DialogErrorAppletErrorExceptionMessage"], ex));
}
});
diff --git a/Ryujinx.Ava/Ui/Applet/ErrorAppletWindow.axaml.cs b/Ryujinx.Ava/Ui/Applet/ErrorAppletWindow.axaml.cs
index 12fb8b0fa5..b4acd155c2 100644
--- a/Ryujinx.Ava/Ui/Applet/ErrorAppletWindow.axaml.cs
+++ b/Ryujinx.Ava/Ui/Applet/ErrorAppletWindow.axaml.cs
@@ -9,7 +9,7 @@ using System.Threading.Tasks;
namespace Ryujinx.Ava.Ui.Applet
{
- internal class ErrorAppletWindow : StyleableWindow
+ internal partial class ErrorAppletWindow : StyleableWindow
{
private readonly Window _owner;
private object _buttonResponse;
@@ -50,8 +50,6 @@ namespace Ryujinx.Ava.Ui.Applet
public string Message { get; set; }
- public StackPanel ButtonStack { get; set; }
-
private void AddButton(string label, object tag)
{
Dispatcher.UIThread.InvokeAsync(() =>
@@ -79,11 +77,5 @@ namespace Ryujinx.Ava.Ui.Applet
return _buttonResponse;
}
-
- private void InitializeComponent()
- {
- AvaloniaXamlLoader.Load(this);
- ButtonStack = this.FindControl("ButtonStack");
- }
}
}
\ No newline at end of file
diff --git a/Ryujinx.Ava/Ui/Applet/SwkbdAppletDialog.axaml.cs b/Ryujinx.Ava/Ui/Applet/SwkbdAppletDialog.axaml.cs
index 2d56c0b5a0..d7bb4b74e2 100644
--- a/Ryujinx.Ava/Ui/Applet/SwkbdAppletDialog.axaml.cs
+++ b/Ryujinx.Ava/Ui/Applet/SwkbdAppletDialog.axaml.cs
@@ -13,7 +13,7 @@ using System.Threading.Tasks;
namespace Ryujinx.Ava.Ui.Controls
{
- internal class SwkbdAppletDialog : UserControl
+ internal partial class SwkbdAppletDialog : UserControl
{
private Predicate _checkLength;
private int _inputMax;
@@ -30,6 +30,10 @@ namespace Ryujinx.Ava.Ui.Controls
_placeholder = placeholder;
InitializeComponent();
+ Input.Watermark = _placeholder;
+
+ Input.AddHandler(TextInputEvent, Message_TextInput, RoutingStrategies.Tunnel, true);
+
SetInputLengthValidation(0, int.MaxValue); // Disable by default.
}
@@ -43,23 +47,9 @@ namespace Ryujinx.Ava.Ui.Controls
public string MainText { get; set; } = "";
public string SecondaryText { get; set; } = "";
- public TextBlock Error { get; private set; }
- public TextBox Input { get; set; }
-
- private void InitializeComponent()
- {
- AvaloniaXamlLoader.Load(this);
- Error = this.FindControl("Error");
- Input = this.FindControl("Input");
-
- Input.Watermark = _placeholder;
-
- Input.AddHandler(TextInputEvent, Message_TextInput, RoutingStrategies.Tunnel, true);
- }
-
public static async Task<(UserResult Result, string Input)> ShowInputDialog(StyleableWindow window, string title, SoftwareKeyboardUiArgs args)
{
- ContentDialog contentDialog = window.ContentDialog;
+ ContentDialog contentDialog = new ContentDialog();
UserResult result = UserResult.Cancel;
diff --git a/Ryujinx.Ava/Ui/Controls/ContentDialogHelper.cs b/Ryujinx.Ava/Ui/Controls/ContentDialogHelper.cs
index cdc5de93ea..15ecaa77b0 100644
--- a/Ryujinx.Ava/Ui/Controls/ContentDialogHelper.cs
+++ b/Ryujinx.Ava/Ui/Controls/ContentDialogHelper.cs
@@ -16,7 +16,6 @@ namespace Ryujinx.Ava.Ui.Controls
private static bool _isChoiceDialogOpen;
private async static Task ShowContentDialog(
- StyleableWindow window,
string title,
string primaryText,
string secondaryText,
@@ -28,35 +27,32 @@ namespace Ryujinx.Ava.Ui.Controls
{
UserResult result = UserResult.None;
- ContentDialog contentDialog = window.ContentDialog;
+ ContentDialog contentDialog = new ContentDialog();
await ShowDialog();
async Task ShowDialog()
{
- if (contentDialog != null)
+ contentDialog.Title = title;
+ contentDialog.PrimaryButtonText = primaryButton;
+ contentDialog.SecondaryButtonText = secondaryButton;
+ contentDialog.CloseButtonText = closeButton;
+ contentDialog.Content = CreateDialogTextContent(primaryText, secondaryText, iconSymbol);
+
+ contentDialog.PrimaryButtonCommand = MiniCommand.Create(() =>
{
- contentDialog.Title = title;
- contentDialog.PrimaryButtonText = primaryButton;
- contentDialog.SecondaryButtonText = secondaryButton;
- contentDialog.CloseButtonText = closeButton;
- contentDialog.Content = CreateDialogTextContent(primaryText, secondaryText, iconSymbol);
+ result = primaryButtonResult;
+ });
+ contentDialog.SecondaryButtonCommand = MiniCommand.Create(() =>
+ {
+ result = UserResult.No;
+ });
+ contentDialog.CloseButtonCommand = MiniCommand.Create(() =>
+ {
+ result = UserResult.Cancel;
+ });
- contentDialog.PrimaryButtonCommand = MiniCommand.Create(() =>
- {
- result = primaryButtonResult;
- });
- contentDialog.SecondaryButtonCommand = MiniCommand.Create(() =>
- {
- result = UserResult.No;
- });
- contentDialog.CloseButtonCommand = MiniCommand.Create(() =>
- {
- result = UserResult.Cancel;
- });
-
- await contentDialog.ShowAsync(ContentDialogPlacement.Popup);
- };
+ await contentDialog.ShowAsync(ContentDialogPlacement.Popup);
}
return result;
@@ -78,35 +74,30 @@ namespace Ryujinx.Ava.Ui.Controls
UserResult result = UserResult.None;
- ContentDialog contentDialog = window.ContentDialog;
-
- Window overlay = window;
-
- if (contentDialog != null)
+ ContentDialog contentDialog = new ContentDialog
{
- contentDialog.PrimaryButtonClick += DeferClose;
- contentDialog.Title = title;
- contentDialog.PrimaryButtonText = primaryButton;
- contentDialog.SecondaryButtonText = secondaryButton;
- contentDialog.CloseButtonText = closeButton;
- contentDialog.Content = CreateDialogTextContent(primaryText, secondaryText, iconSymbol);
-
- contentDialog.PrimaryButtonCommand = MiniCommand.Create(() =>
+ Title = title,
+ PrimaryButtonText = primaryButton,
+ SecondaryButtonText = secondaryButton,
+ CloseButtonText = closeButton,
+ Content = CreateDialogTextContent(primaryText, secondaryText, iconSymbol),
+ PrimaryButtonCommand = MiniCommand.Create(() =>
{
result = primaryButton == LocaleManager.Instance["InputDialogYes"] ? UserResult.Yes : UserResult.Ok;
- });
- contentDialog.SecondaryButtonCommand = MiniCommand.Create(() =>
- {
- contentDialog.PrimaryButtonClick -= DeferClose;
- result = UserResult.No;
- });
- contentDialog.CloseButtonCommand = MiniCommand.Create(() =>
- {
- contentDialog.PrimaryButtonClick -= DeferClose;
- result = UserResult.Cancel;
- });
- await contentDialog.ShowAsync(ContentDialogPlacement.Popup);
+ }),
};
+ contentDialog.SecondaryButtonCommand = MiniCommand.Create(() =>
+ {
+ contentDialog.PrimaryButtonClick -= DeferClose;
+ result = UserResult.No;
+ });
+ contentDialog.CloseButtonCommand = MiniCommand.Create(() =>
+ {
+ contentDialog.PrimaryButtonClick -= DeferClose;
+ result = UserResult.Cancel;
+ });
+ contentDialog.PrimaryButtonClick += DeferClose;
+ await contentDialog.ShowAsync(ContentDialogPlacement.Popup);
return result;
@@ -141,7 +132,7 @@ namespace Ryujinx.Ava.Ui.Controls
if (doWhileDeferred != null)
{
- await doWhileDeferred(overlay);
+ await doWhileDeferred(window);
deferResetEvent.Set();
}
@@ -191,7 +182,6 @@ namespace Ryujinx.Ava.Ui.Controls
}
public static async Task CreateInfoDialog(
- StyleableWindow window,
string primary,
string secondaryText,
string acceptButton,
@@ -199,7 +189,6 @@ namespace Ryujinx.Ava.Ui.Controls
string title)
{
return await ShowContentDialog(
- window,
title,
primary,
secondaryText,
@@ -210,7 +199,6 @@ namespace Ryujinx.Ava.Ui.Controls
}
internal static async Task CreateConfirmationDialog(
- StyleableWindow window,
string primaryText,
string secondaryText,
string acceptButtonText,
@@ -219,7 +207,6 @@ namespace Ryujinx.Ava.Ui.Controls
UserResult primaryButtonResult = UserResult.Yes)
{
return await ShowContentDialog(
- window,
string.IsNullOrWhiteSpace(title) ? LocaleManager.Instance["DialogConfirmationTitle"] : title,
primaryText,
secondaryText,
@@ -235,10 +222,9 @@ namespace Ryujinx.Ava.Ui.Controls
return new(mainText, secondaryText);
}
- internal static async Task CreateUpdaterInfoDialog(StyleableWindow window, string primary, string secondaryText)
+ internal static async Task CreateUpdaterInfoDialog(string primary, string secondaryText)
{
await ShowContentDialog(
- window,
LocaleManager.Instance["DialogUpdaterTitle"],
primary,
secondaryText,
@@ -248,24 +234,9 @@ namespace Ryujinx.Ava.Ui.Controls
(int)Symbol.Important);
}
- internal static async Task ShowNotAvailableMessage(StyleableWindow window)
- {
- // Temporary placeholder for features to be added
- await ShowContentDialog(
- window,
- "Feature Not Available",
- "The selected feature is not available in this version.",
- "",
- "",
- "",
- LocaleManager.Instance["InputDialogOk"],
- (int)Symbol.Important);
- }
-
- internal static async Task CreateWarningDialog(StyleableWindow window, string primary, string secondaryText)
+ internal static async Task CreateWarningDialog(string primary, string secondaryText)
{
await ShowContentDialog(
- window,
LocaleManager.Instance["DialogWarningTitle"],
primary,
secondaryText,
@@ -275,12 +246,11 @@ namespace Ryujinx.Ava.Ui.Controls
(int)Symbol.Important);
}
- internal static async Task CreateErrorDialog(StyleableWindow owner, string errorMessage, string secondaryErrorMessage = "")
+ internal static async Task CreateErrorDialog(string errorMessage, string secondaryErrorMessage = "")
{
Logger.Error?.Print(LogClass.Application, errorMessage);
await ShowContentDialog(
- owner,
LocaleManager.Instance["DialogErrorTitle"],
LocaleManager.Instance["DialogErrorMessage"],
errorMessage,
@@ -290,7 +260,7 @@ namespace Ryujinx.Ava.Ui.Controls
(int)Symbol.Dismiss);
}
- internal static async Task CreateChoiceDialog(StyleableWindow window, string title, string primary, string secondaryText)
+ internal static async Task CreateChoiceDialog(string title, string primary, string secondaryText)
{
if (_isChoiceDialogOpen)
{
@@ -301,7 +271,6 @@ namespace Ryujinx.Ava.Ui.Controls
UserResult response =
await ShowContentDialog(
- window,
title,
primary,
secondaryText,
@@ -316,19 +285,17 @@ namespace Ryujinx.Ava.Ui.Controls
return response == UserResult.Yes;
}
- internal static async Task CreateExitDialog(StyleableWindow owner)
+ internal static async Task CreateExitDialog()
{
return await CreateChoiceDialog(
- owner,
LocaleManager.Instance["DialogExitTitle"],
LocaleManager.Instance["DialogExitMessage"],
LocaleManager.Instance["DialogExitSubMessage"]);
}
- internal static async Task CreateStopEmulationDialog(StyleableWindow owner)
+ internal static async Task CreateStopEmulationDialog()
{
return await CreateChoiceDialog(
- owner,
LocaleManager.Instance["DialogStopEmulationTitle"],
LocaleManager.Instance["DialogStopEmulationMessage"],
LocaleManager.Instance["DialogExitSubMessage"]);
@@ -338,12 +305,10 @@ namespace Ryujinx.Ava.Ui.Controls
string title,
string mainText,
string subText,
- StyleableWindow owner,
uint maxLength = int.MaxValue,
string input = "")
{
var result = await InputDialog.ShowInputDialog(
- owner,
title,
mainText,
input,
diff --git a/Ryujinx.Ava/Ui/Controls/InputDialog.axaml.cs b/Ryujinx.Ava/Ui/Controls/InputDialog.axaml.cs
index b9bbb66da1..e4b37decf9 100644
--- a/Ryujinx.Ava/Ui/Controls/InputDialog.axaml.cs
+++ b/Ryujinx.Ava/Ui/Controls/InputDialog.axaml.cs
@@ -8,7 +8,7 @@ using System.Threading.Tasks;
namespace Ryujinx.Ava.Ui.Controls
{
- public class InputDialog : UserControl
+ public partial class InputDialog : UserControl
{
public string Message { get; set; }
public string Input { get; set; }
@@ -24,8 +24,6 @@ namespace Ryujinx.Ava.Ui.Controls
MaxLength = maxLength;
DataContext = this;
-
- InitializeComponent();
}
public InputDialog()
@@ -33,33 +31,26 @@ namespace Ryujinx.Ava.Ui.Controls
InitializeComponent();
}
- private void InitializeComponent()
+ public static async Task<(UserResult Result, string Input)> ShowInputDialog(string title, string message,
+ string input = "", string subMessage = "", uint maxLength = int.MaxValue)
{
- AvaloniaXamlLoader.Load(this);
- }
-
- public static async Task<(UserResult Result, string Input)> ShowInputDialog(StyleableWindow window, string title, string message, string input = "", string subMessage = "", uint maxLength = int.MaxValue)
- {
- ContentDialog contentDialog = window.ContentDialog;
-
UserResult result = UserResult.Cancel;
- InputDialog content = new InputDialog(message, input = "", subMessage = "", maxLength);
-
- if (contentDialog != null)
+ InputDialog content = new InputDialog(message, input, subMessage, maxLength);
+ ContentDialog contentDialog = new ContentDialog
{
- contentDialog.Title = title;
- contentDialog.PrimaryButtonText = LocaleManager.Instance["InputDialogOk"];
- contentDialog.SecondaryButtonText = "";
- contentDialog.CloseButtonText = LocaleManager.Instance["InputDialogCancel"];
- contentDialog.Content = content;
- contentDialog.PrimaryButtonCommand = MiniCommand.Create(() =>
+ Title = title,
+ PrimaryButtonText = LocaleManager.Instance["InputDialogOk"],
+ SecondaryButtonText = "",
+ CloseButtonText = LocaleManager.Instance["InputDialogCancel"],
+ Content = content,
+ PrimaryButtonCommand = MiniCommand.Create(() =>
{
result = UserResult.Ok;
input = content.Input;
- });
- await contentDialog.ShowAsync();
- }
+ })
+ };
+ await contentDialog.ShowAsync();
return (result, input);
}
diff --git a/Ryujinx.Ava/Ui/Controls/NavigationDialogHost.axaml b/Ryujinx.Ava/Ui/Controls/NavigationDialogHost.axaml
new file mode 100644
index 0000000000..b0ab5d301f
--- /dev/null
+++ b/Ryujinx.Ava/Ui/Controls/NavigationDialogHost.axaml
@@ -0,0 +1,10 @@
+
+
+
\ No newline at end of file
diff --git a/Ryujinx.Ava/Ui/Controls/NavigationDialogHost.axaml.cs b/Ryujinx.Ava/Ui/Controls/NavigationDialogHost.axaml.cs
new file mode 100644
index 0000000000..9ba631ad74
--- /dev/null
+++ b/Ryujinx.Ava/Ui/Controls/NavigationDialogHost.axaml.cs
@@ -0,0 +1,85 @@
+using Avalonia;
+using Avalonia.Controls;
+using FluentAvalonia.UI.Controls;
+using Ryujinx.Ava.Common.Locale;
+using Ryujinx.Ava.Ui.ViewModels;
+using Ryujinx.HLE.FileSystem;
+using Ryujinx.HLE.HOS.Services.Account.Acc;
+using System;
+using System.Threading.Tasks;
+
+namespace Ryujinx.Ava.Ui.Controls
+{
+ public partial class NavigationDialogHost : UserControl
+ {
+ public AccountManager AccountManager { get; }
+ public ContentManager ContentManager { get; }
+ public UserProfileViewModel ViewModel { get; set; }
+
+ public NavigationDialogHost()
+ {
+ InitializeComponent();
+ }
+
+ public NavigationDialogHost(AccountManager accountManager, ContentManager contentManager,
+ VirtualFileSystem virtualFileSystem)
+ {
+ AccountManager = accountManager;
+ ContentManager = contentManager;
+ ViewModel = new UserProfileViewModel(this);
+
+
+ if (contentManager.GetCurrentFirmwareVersion() != null)
+ {
+ Task.Run(() =>
+ {
+ AvatarProfileViewModel.PreloadAvatars(contentManager, virtualFileSystem);
+ });
+ }
+ InitializeComponent();
+ }
+
+ public void GoBack(object parameter = null)
+ {
+ if (ContentFrame.BackStack.Count > 0)
+ {
+ ContentFrame.GoBack();
+ }
+
+ ViewModel.LoadProfiles();
+ }
+
+ public void Navigate(Type sourcePageType, object parameter)
+ {
+ ContentFrame.Navigate(sourcePageType, parameter);
+ }
+
+ public static async Task Show(AccountManager ownerAccountManager, ContentManager ownerContentManager, VirtualFileSystem ownerVirtualFileSystem)
+ {
+ var content = new NavigationDialogHost(ownerAccountManager, ownerContentManager, ownerVirtualFileSystem);
+ ContentDialog contentDialog = new ContentDialog
+ {
+ Title = LocaleManager.Instance["UserProfileWindowTitle"],
+ PrimaryButtonText = "",
+ SecondaryButtonText = "",
+ CloseButtonText = LocaleManager.Instance["UserProfilesClose"],
+ Content = content,
+ Padding = new Thickness(0)
+ };
+
+ contentDialog.Closed += (sender, args) =>
+ {
+ content.ViewModel.Dispose();
+ };
+
+ await contentDialog.ShowAsync();
+ }
+
+ protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
+ {
+ base.OnAttachedToVisualTree(e);
+
+ Navigate(typeof(UserSelector), this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Ryujinx.Ava/Ui/Controls/ProfileImageSelectionDialog.axaml b/Ryujinx.Ava/Ui/Controls/ProfileImageSelectionDialog.axaml
index c6f43f43f8..750edf8b00 100644
--- a/Ryujinx.Ava/Ui/Controls/ProfileImageSelectionDialog.axaml
+++ b/Ryujinx.Ava/Ui/Controls/ProfileImageSelectionDialog.axaml
@@ -1,14 +1,10 @@
-
+ x:Class="Ryujinx.Ava.Ui.Controls.ProfileImageSelectionDialog">
@@ -32,4 +28,4 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/Ryujinx.Ava/Ui/Controls/ProfileImageSelectionDialog.axaml.cs b/Ryujinx.Ava/Ui/Controls/ProfileImageSelectionDialog.axaml.cs
index 728b890695..5d361af92f 100644
--- a/Ryujinx.Ava/Ui/Controls/ProfileImageSelectionDialog.axaml.cs
+++ b/Ryujinx.Ava/Ui/Controls/ProfileImageSelectionDialog.axaml.cs
@@ -1,8 +1,10 @@
-using Avalonia;
using Avalonia.Controls;
using Avalonia.Interactivity;
-using Avalonia.Markup.Xaml;
+using Avalonia.VisualTree;
+using FluentAvalonia.UI.Controls;
+using FluentAvalonia.UI.Navigation;
using Ryujinx.Ava.Common.Locale;
+using Ryujinx.Ava.Ui.Models;
using Ryujinx.Ava.Ui.Windows;
using Ryujinx.HLE.FileSystem;
using SixLabors.ImageSharp;
@@ -12,36 +14,40 @@ using Image = SixLabors.ImageSharp.Image;
namespace Ryujinx.Ava.Ui.Controls
{
- public class ProfileImageSelectionDialog : StyleableWindow
+ public partial class ProfileImageSelectionDialog : UserControl
{
- private readonly ContentManager _contentManager;
+ private ContentManager _contentManager;
+ private NavigationDialogHost _parent;
+ private TempProfile _profile;
public bool FirmwareFound => _contentManager.GetCurrentFirmwareVersion() != null;
- public byte[] BufferImageProfile { get; set; }
-
- public ProfileImageSelectionDialog(ContentManager contentManager)
- {
- _contentManager = contentManager;
- DataContext = this;
- InitializeComponent();
-#if DEBUG
- this.AttachDevTools();
-#endif
- }
-
public ProfileImageSelectionDialog()
{
- DataContext = this;
InitializeComponent();
-#if DEBUG
- this.AttachDevTools();
-#endif
+ AddHandler(Frame.NavigatedToEvent, (s, e) =>
+ {
+ NavigatedTo(e);
+ }, RoutingStrategies.Direct);
}
- private void InitializeComponent()
+ private void NavigatedTo(NavigationEventArgs arg)
{
- AvaloniaXamlLoader.Load(this);
+ if (Program.PreviewerDetached)
+ {
+ switch (arg.NavigationMode)
+ {
+ case NavigationMode.New:
+ (_parent, _profile) = ((NavigationDialogHost, TempProfile))arg.Parameter;
+ _contentManager = _parent.ContentManager;
+ break;
+ case NavigationMode.Back:
+ _parent.GoBack();
+ break;
+ }
+
+ DataContext = this;
+ }
}
private async void Import_OnClick(object sender, RoutedEventArgs e)
@@ -58,7 +64,7 @@ namespace Ryujinx.Ava.Ui.Controls
dialog.AllowMultiple = false;
- string[] image = await dialog.ShowAsync(this);
+ string[] image = await dialog.ShowAsync(((TopLevel)_parent.GetVisualRoot()) as Window);
if (image != null)
{
@@ -66,28 +72,22 @@ namespace Ryujinx.Ava.Ui.Controls
{
string imageFile = image[0];
- ProcessProfileImage(File.ReadAllBytes(imageFile));
+ _profile.Image = ProcessProfileImage(File.ReadAllBytes(imageFile));
}
- Close();
+ _parent.GoBack();
}
}
- private async void SelectFirmwareImage_OnClick(object sender, RoutedEventArgs e)
+ private void SelectFirmwareImage_OnClick(object sender, RoutedEventArgs e)
{
if (FirmwareFound)
{
- AvatarWindow window = new(_contentManager);
-
- await window.ShowDialog(this);
-
- BufferImageProfile = window.SelectedImage;
-
- Close();
+ _parent.Navigate(typeof(AvatarWindow), (_parent, _profile));
}
}
- private void ProcessProfileImage(byte[] buffer)
+ private static byte[] ProcessProfileImage(byte[] buffer)
{
using (Image image = Image.Load(buffer))
{
@@ -97,7 +97,7 @@ namespace Ryujinx.Ava.Ui.Controls
{
image.SaveAsJpeg(streamJpg);
- BufferImageProfile = streamJpg.ToArray();
+ return streamJpg.ToArray();
}
}
}
diff --git a/Ryujinx.Ava/Ui/Controls/UpdateWaitWindow.axaml.cs b/Ryujinx.Ava/Ui/Controls/UpdateWaitWindow.axaml.cs
index e4108ba400..eff15c7ba3 100644
--- a/Ryujinx.Ava/Ui/Controls/UpdateWaitWindow.axaml.cs
+++ b/Ryujinx.Ava/Ui/Controls/UpdateWaitWindow.axaml.cs
@@ -5,7 +5,7 @@ using Ryujinx.Ava.Ui.Windows;
namespace Ryujinx.Ava.Ui.Controls
{
- public class UpdateWaitWindow : StyleableWindow
+ public partial class UpdateWaitWindow : StyleableWindow
{
public UpdateWaitWindow(string primaryText, string secondaryText) : this()
{
@@ -21,15 +21,5 @@ namespace Ryujinx.Ava.Ui.Controls
this.AttachDevTools();
#endif
}
-
- public TextBlock PrimaryText { get; private set; }
- public TextBlock SecondaryText { get; private set; }
-
- private void InitializeComponent()
- {
- AvaloniaXamlLoader.Load(this);
- PrimaryText = this.FindControl("PrimaryText");
- SecondaryText = this.FindControl("SecondaryText");
- }
}
}
\ No newline at end of file
diff --git a/Ryujinx.Ava/Ui/Controls/UserEditor.axaml b/Ryujinx.Ava/Ui/Controls/UserEditor.axaml
new file mode 100644
index 0000000000..fed5f8cb2d
--- /dev/null
+++ b/Ryujinx.Ava/Ui/Controls/UserEditor.axaml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ryujinx.Ava/Ui/Controls/UserEditor.axaml.cs b/Ryujinx.Ava/Ui/Controls/UserEditor.axaml.cs
new file mode 100644
index 0000000000..1bc1b325f4
--- /dev/null
+++ b/Ryujinx.Ava/Ui/Controls/UserEditor.axaml.cs
@@ -0,0 +1,123 @@
+using Avalonia.Controls;
+using Avalonia.Data;
+using Avalonia.Interactivity;
+using FluentAvalonia.UI.Controls;
+using FluentAvalonia.UI.Navigation;
+using Ryujinx.Ava.Common.Locale;
+using Ryujinx.Ava.Ui.Models;
+using UserProfile = Ryujinx.Ava.Ui.Models.UserProfile;
+
+namespace Ryujinx.Ava.Ui.Controls
+{
+ public partial class UserEditor : UserControl
+ {
+ private NavigationDialogHost _parent;
+ private UserProfile _profile;
+ private bool _isNewUser;
+
+ public TempProfile TempProfile { get; set; }
+ public uint MaxProfileNameLength => 0x20;
+
+ public UserEditor()
+ {
+ InitializeComponent();
+ AddHandler(Frame.NavigatedToEvent, (s, e) =>
+ {
+ NavigatedTo(e);
+ }, RoutingStrategies.Direct);
+ }
+
+ private void NavigatedTo(NavigationEventArgs arg)
+ {
+ if (Program.PreviewerDetached)
+ {
+ switch (arg.NavigationMode)
+ {
+ case NavigationMode.New:
+ var args = ((NavigationDialogHost parent, UserProfile profile, bool isNewUser))arg.Parameter;
+ _isNewUser = args.isNewUser;
+ if (!_isNewUser)
+ {
+ _profile = args.profile;
+ TempProfile = new TempProfile(_profile);
+ }
+ else
+ {
+ TempProfile = new TempProfile();
+ }
+
+ _parent = args.parent;
+ break;
+ }
+
+ DataContext = TempProfile;
+
+ AddPictureButton.IsVisible = _isNewUser;
+ IdLabel.IsVisible = !_isNewUser;
+ ChangePictureButton.IsVisible = !_isNewUser;
+ }
+ }
+
+ private void CloseButton_Click(object sender, RoutedEventArgs e)
+ {
+ _parent?.GoBack();
+ }
+
+ private void SaveButton_Click(object sender, RoutedEventArgs e)
+ {
+ DataValidationErrors.ClearErrors(NameBox);
+ bool isInvalid = false;
+
+ if (string.IsNullOrWhiteSpace(TempProfile.Name))
+ {
+ DataValidationErrors.SetError(NameBox, new DataValidationException(LocaleManager.Instance["UserProfileEmptyNameError"]));
+
+ isInvalid = true;
+ }
+
+ if (TempProfile.Image == null)
+ {
+ ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance["UserProfileNoImageError"], "");
+
+ isInvalid = true;
+ }
+
+ if(isInvalid)
+ {
+ return;
+ }
+
+ if (_profile != null)
+ {
+ _profile.Name = TempProfile.Name;
+ _profile.Image = TempProfile.Image;
+ _profile.UpdateState();
+ _parent.AccountManager.SetUserName(_profile.UserId, _profile.Name);
+ _parent.AccountManager.SetUserImage(_profile.UserId, _profile.Image);
+ }
+ else if (_isNewUser)
+ {
+ _parent.AccountManager.AddUser(TempProfile.Name, TempProfile.Image);
+ }
+ else
+ {
+ return;
+ }
+
+ _parent?.GoBack();
+ }
+
+ public void SelectProfileImage()
+ {
+ _parent.Navigate(typeof(ProfileImageSelectionDialog), (_parent, TempProfile));
+ }
+
+ private void ChangePictureButton_Click(object sender, RoutedEventArgs e)
+ {
+ if (_profile != null || _isNewUser)
+ {
+ SelectProfileImage();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Ryujinx.Ava/Ui/Controls/UserErrorDialog.cs b/Ryujinx.Ava/Ui/Controls/UserErrorDialog.cs
index 1f8f68e303..0b2d2c1172 100644
--- a/Ryujinx.Ava/Ui/Controls/UserErrorDialog.cs
+++ b/Ryujinx.Ava/Ui/Controls/UserErrorDialog.cs
@@ -75,7 +75,7 @@ namespace Ryujinx.Ava.Ui.Controls
string setupButtonLabel = isInSetupGuide ? LocaleManager.Instance["OpenSetupGuideMessage"] : "";
- var result = await ContentDialogHelper.CreateInfoDialog(owner,
+ var result = await ContentDialogHelper.CreateInfoDialog(
string.Format(LocaleManager.Instance["DialogUserErrorDialogMessage"], errorCode, GetErrorTitle(error)),
GetErrorDescription(error) + (isInSetupGuide
? LocaleManager.Instance["DialogUserErrorDialogInfoMessage"]
diff --git a/Ryujinx.Ava/Ui/Controls/UserSelector.axaml b/Ryujinx.Ava/Ui/Controls/UserSelector.axaml
new file mode 100644
index 0000000000..3bca7d7d89
--- /dev/null
+++ b/Ryujinx.Ava/Ui/Controls/UserSelector.axaml
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Ryujinx.Ava/Ui/Controls/UserSelector.axaml.cs b/Ryujinx.Ava/Ui/Controls/UserSelector.axaml.cs
new file mode 100644
index 0000000000..027351eef3
--- /dev/null
+++ b/Ryujinx.Ava/Ui/Controls/UserSelector.axaml.cs
@@ -0,0 +1,79 @@
+using Avalonia.Controls;
+using Avalonia.Interactivity;
+using FluentAvalonia.UI.Controls;
+using FluentAvalonia.UI.Navigation;
+using Ryujinx.Ava.Ui.ViewModels;
+using UserProfile = Ryujinx.Ava.Ui.Models.UserProfile;
+
+namespace Ryujinx.Ava.Ui.Controls
+{
+ public partial class UserSelector : UserControl
+ {
+ private NavigationDialogHost _parent;
+ public UserProfileViewModel ViewModel { get; set; }
+
+ public UserSelector()
+ {
+ InitializeComponent();
+
+ if (Program.PreviewerDetached)
+ {
+ AddHandler(Frame.NavigatedToEvent, (s, e) =>
+ {
+ NavigatedTo(e);
+ }, Avalonia.Interactivity.RoutingStrategies.Direct);
+ }
+ }
+
+ private void NavigatedTo(NavigationEventArgs arg)
+ {
+ if (Program.PreviewerDetached)
+ {
+ switch (arg.NavigationMode)
+ {
+ case NavigationMode.New:
+ _parent = (NavigationDialogHost)arg.Parameter;
+ ViewModel = _parent.ViewModel;
+ break;
+ }
+
+ DataContext = ViewModel;
+ }
+ }
+
+ private void ProfilesList_DoubleTapped(object sender, RoutedEventArgs e)
+ {
+ if (sender is ListBox listBox)
+ {
+ int selectedIndex = listBox.SelectedIndex;
+
+ if (selectedIndex >= 0 && selectedIndex < ViewModel.Profiles.Count)
+ {
+ ViewModel.SelectedProfile = ViewModel.Profiles[selectedIndex];
+
+ _parent?.AccountManager?.OpenUser(ViewModel.SelectedProfile.UserId);
+
+ ViewModel.LoadProfiles();
+
+ foreach (UserProfile profile in ViewModel.Profiles)
+ {
+ profile.UpdateState();
+ }
+ }
+ }
+ }
+
+ private void SelectingItemsControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (sender is ListBox listBox)
+ {
+ int selectedIndex = listBox.SelectedIndex;
+
+ if (selectedIndex >= 0 && selectedIndex < ViewModel.Profiles.Count)
+ {
+ ViewModel.HighlightedProfile = ViewModel.Profiles[selectedIndex];
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Ryujinx.Ava/Ui/Models/TempProfile.cs b/Ryujinx.Ava/Ui/Models/TempProfile.cs
new file mode 100644
index 0000000000..e943687a16
--- /dev/null
+++ b/Ryujinx.Ava/Ui/Models/TempProfile.cs
@@ -0,0 +1,55 @@
+using Ryujinx.Ava.Ui.ViewModels;
+using Ryujinx.HLE.HOS.Services.Account.Acc;
+using System;
+
+namespace Ryujinx.Ava.Ui.Models
+{
+ public class TempProfile : BaseModel
+ {
+ private readonly UserProfile _profile;
+ private byte[] _image = null;
+ private string _name = String.Empty;
+ private UserId _userId;
+
+ public byte[] Image
+ {
+ get => _image;
+ set
+ {
+ _image = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public UserId UserId
+ {
+ get => _userId;
+ set
+ {
+ _userId = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public string Name
+ {
+ get => _name;
+ set
+ {
+ _name = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public TempProfile(UserProfile profile)
+ {
+ _profile = profile;
+
+ Image = profile.Image;
+ Name = profile.Name;
+ UserId = profile.UserId;
+ }
+
+ public TempProfile(){}
+ }
+}
\ No newline at end of file
diff --git a/Ryujinx.Ava/Ui/ViewModels/AmiiboWindowViewModel.cs b/Ryujinx.Ava/Ui/ViewModels/AmiiboWindowViewModel.cs
index 9f411ba2aa..7015df44e6 100644
--- a/Ryujinx.Ava/Ui/ViewModels/AmiiboWindowViewModel.cs
+++ b/Ryujinx.Ava/Ui/ViewModels/AmiiboWindowViewModel.cs
@@ -390,7 +390,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
return amiiboJsonString;
}
- await ContentDialogHelper.CreateInfoDialog(_owner, LocaleManager.Instance["DialogAmiiboApiTitle"],
+ await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance["DialogAmiiboApiTitle"],
LocaleManager.Instance["DialogAmiiboApiFailFetchMessage"],
LocaleManager.Instance["InputDialogOk"],
"",
@@ -440,7 +440,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
private async void ShowInfoDialog()
{
- await ContentDialogHelper.CreateInfoDialog(_owner, LocaleManager.Instance["DialogAmiiboApiTitle"],
+ await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance["DialogAmiiboApiTitle"],
LocaleManager.Instance["DialogAmiiboApiConnectErrorMessage"],
LocaleManager.Instance["InputDialogOk"],
"",
diff --git a/Ryujinx.Ava/Ui/ViewModels/ControllerSettingsViewModel.cs b/Ryujinx.Ava/Ui/ViewModels/ControllerSettingsViewModel.cs
index c570aa8dad..a3abdd3b42 100644
--- a/Ryujinx.Ava/Ui/ViewModels/ControllerSettingsViewModel.cs
+++ b/Ryujinx.Ava/Ui/ViewModels/ControllerSettingsViewModel.cs
@@ -327,12 +327,12 @@ namespace Ryujinx.Ava.Ui.ViewModels
public async void ShowMotionConfig()
{
- await MotionSettingsWindow.Show(this, _owner.GetVisualRoot() as StyleableWindow);
+ await MotionSettingsWindow.Show(this);
}
public async void ShowRumbleConfig()
{
- await RumbleSettingsWindow.Show(this, _owner.GetVisualRoot() as StyleableWindow);
+ await RumbleSettingsWindow.Show(this);
}
private void LoadInputDriver()
@@ -701,8 +701,8 @@ namespace Ryujinx.Ava.Ui.ViewModels
catch (InvalidOperationException)
{
Logger.Error?.Print(LogClass.Configuration, $"Profile {ProfileName} is incompatible with the current input configuration system.");
- await ContentDialogHelper.CreateErrorDialog(_owner.GetVisualRoot() as StyleableWindow,
- String.Format(LocaleManager.Instance["DialogProfileInvalidProfileErrorMessage"], ProfileName));
+
+ await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance["DialogProfileInvalidProfileErrorMessage"], ProfileName));
return;
}
@@ -736,7 +736,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
if (ProfileName == LocaleManager.Instance["ControllerSettingsProfileDefault"])
{
- await ContentDialogHelper.CreateErrorDialog(_owner.GetVisualRoot() as StyleableWindow, LocaleManager.Instance["DialogProfileDefaultProfileOverwriteErrorMessage"]);
+ await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogProfileDefaultProfileOverwriteErrorMessage"]);
return;
}
@@ -769,7 +769,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
}
else
{
- await ContentDialogHelper.CreateErrorDialog(_owner.GetVisualRoot() as StyleableWindow, LocaleManager.Instance["DialogProfileInvalidProfileNameErrorMessage"]);
+ await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogProfileInvalidProfileNameErrorMessage"]);
}
}
}
@@ -782,7 +782,6 @@ namespace Ryujinx.Ava.Ui.ViewModels
}
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(
- _owner.GetVisualRoot() as StyleableWindow,
LocaleManager.Instance["DialogProfileDeleteProfileTitle"],
LocaleManager.Instance["DialogProfileDeleteProfileMessage"],
LocaleManager.Instance["InputDialogYes"],
diff --git a/Ryujinx.Ava/Ui/ViewModels/MainWindowViewModel.cs b/Ryujinx.Ava/Ui/ViewModels/MainWindowViewModel.cs
index 9c02777374..7e6452f989 100644
--- a/Ryujinx.Ava/Ui/ViewModels/MainWindowViewModel.cs
+++ b/Ryujinx.Ava/Ui/ViewModels/MainWindowViewModel.cs
@@ -708,7 +708,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
{
return;
}
-
+
if (_owner.AppHost.Device.System.SearchingForAmiibo(out int deviceId))
{
string titleId = _owner.AppHost.Device.Application.TitleIdText.ToUpper();
@@ -975,9 +975,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
public async void ManageProfiles()
{
- UserProfileWindow window = new(_owner.AccountManager, _owner.ContentManager, _owner.VirtualFileSystem);
-
- await window.ShowDialog(_owner);
+ await NavigationDialogHost.Show(_owner.AccountManager, _owner.ContentManager, _owner.VirtualFileSystem);
}
public async void OpenAboutWindow()
@@ -1054,8 +1052,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
{
Dispatcher.UIThread.Post(async () =>
{
- await ContentDialogHelper.CreateErrorDialog(_owner,
- LocaleManager.Instance["DialogRyujinxErrorMessage"], LocaleManager.Instance["DialogInvalidTitleIdErrorMessage"]);
+ await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogRyujinxErrorMessage"], LocaleManager.Instance["DialogInvalidTitleIdErrorMessage"]);
});
return;
@@ -1138,7 +1135,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
DirectoryInfo backupDir = new(Path.Combine(AppDataManager.GamesDirPath, selection.TitleId, "cache", "cpu", "1"));
// FIXME: Found a way to reproduce the bold effect on the title name (fork?).
- UserResult result = await ContentDialogHelper.CreateConfirmationDialog(_owner, LocaleManager.Instance["DialogWarning"],
+ UserResult result = await ContentDialogHelper.CreateConfirmationDialog(LocaleManager.Instance["DialogWarning"],
string.Format(LocaleManager.Instance["DialogPPTCDeletionMessage"], selection.TitleName), LocaleManager.Instance["InputDialogYes"], LocaleManager.Instance["InputDialogNo"], LocaleManager.Instance["RyujinxConfirm"]);
List cacheFiles = new();
@@ -1163,7 +1160,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
}
catch (Exception e)
{
- await ContentDialogHelper.CreateErrorDialog(_owner, string.Format(LocaleManager.Instance["DialogPPTCDeletionErrorMessage"], file.Name, e));
+ await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance["DialogPPTCDeletionErrorMessage"], file.Name, e));
}
}
}
@@ -1201,7 +1198,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
DirectoryInfo shaderCacheDir = new(Path.Combine(AppDataManager.GamesDirPath, selection.TitleId, "cache", "shader"));
// FIXME: Found a way to reproduce the bold effect on the title name (fork?).
- UserResult result = await ContentDialogHelper.CreateConfirmationDialog(_owner, LocaleManager.Instance["DialogWarning"],
+ UserResult result = await ContentDialogHelper.CreateConfirmationDialog(LocaleManager.Instance["DialogWarning"],
string.Format(LocaleManager.Instance["DialogShaderDeletionMessage"], selection.TitleName), LocaleManager.Instance["InputDialogYes"], LocaleManager.Instance["InputDialogNo"], LocaleManager.Instance["RyujinxConfirm"]);
List oldCacheDirectories = new List();
@@ -1224,7 +1221,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
}
catch (Exception e)
{
- await ContentDialogHelper.CreateErrorDialog(_owner, string.Format(LocaleManager.Instance["DialogPPTCDeletionErrorMessage"], directory.Name, e));
+ await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance["DialogPPTCDeletionErrorMessage"], directory.Name, e));
}
}
}
@@ -1237,7 +1234,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
}
catch (Exception e)
{
- await ContentDialogHelper.CreateErrorDialog(_owner, string.Format(LocaleManager.Instance["ShaderCachePurgeError"], file.Name, e));
+ await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance["ShaderCachePurgeError"], file.Name, e));
}
}
}
@@ -1316,12 +1313,11 @@ namespace Ryujinx.Ava.Ui.ViewModels
Task.Run(() =>
{
if (!ulong.TryParse(selection.TitleId, NumberStyles.HexNumber, CultureInfo.InvariantCulture,
- out ulong titleIdNumber))
+ out ulong titleIdNumber))
{
Dispatcher.UIThread.Post(async () =>
{
- await ContentDialogHelper.CreateErrorDialog(_owner,
- LocaleManager.Instance["DialogRyujinxErrorMessage"], LocaleManager.Instance["DialogInvalidTitleIdErrorMessage"]);
+ await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogRyujinxErrorMessage"], LocaleManager.Instance["DialogInvalidTitleIdErrorMessage"]);
});
return;
@@ -1342,12 +1338,11 @@ namespace Ryujinx.Ava.Ui.ViewModels
Task.Run(() =>
{
if (!ulong.TryParse(selection.TitleId, NumberStyles.HexNumber, CultureInfo.InvariantCulture,
- out ulong titleIdNumber))
+ out ulong titleIdNumber))
{
Dispatcher.UIThread.Post(async () =>
{
- await ContentDialogHelper.CreateErrorDialog(_owner,
- LocaleManager.Instance["DialogRyujinxErrorMessage"], LocaleManager.Instance["DialogInvalidTitleIdErrorMessage"]);
+ await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogRyujinxErrorMessage"], LocaleManager.Instance["DialogInvalidTitleIdErrorMessage"]);
});
return;
@@ -1406,7 +1401,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
if (firmwareVersion == null)
{
- await ContentDialogHelper.CreateErrorDialog(_owner, string.Format(LocaleManager.Instance["DialogFirmwareInstallerFirmwareNotFoundErrorMessage"], filename));
+ await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance["DialogFirmwareInstallerFirmwareNotFoundErrorMessage"], filename));
return;
}
@@ -1426,7 +1421,6 @@ namespace Ryujinx.Ava.Ui.ViewModels
dialogMessage += LocaleManager.Instance["DialogFirmwareInstallerFirmwareInstallConfirmMessage"];
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(
- _owner,
dialogTitle,
dialogMessage,
LocaleManager.Instance["InputDialogYes"],
@@ -1456,7 +1450,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
string message = string.Format(LocaleManager.Instance["DialogFirmwareInstallerFirmwareInstallSuccessMessage"], firmwareVersion.VersionString);
- await ContentDialogHelper.CreateInfoDialog(_owner, dialogTitle, message, LocaleManager.Instance["InputDialogOk"], "", LocaleManager.Instance["RyujinxInfo"]);
+ await ContentDialogHelper.CreateInfoDialog(dialogTitle, message, LocaleManager.Instance["InputDialogOk"], "", LocaleManager.Instance["RyujinxInfo"]);
Logger.Info?.Print(LogClass.Application, message);
// Purge Applet Cache.
@@ -1475,7 +1469,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
{
waitingDialog.Close();
- await ContentDialogHelper.CreateErrorDialog(_owner, ex.Message);
+ await ContentDialogHelper.CreateErrorDialog(ex.Message);
});
}
finally
@@ -1496,7 +1490,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
}
catch (Exception ex)
{
- await ContentDialogHelper.CreateErrorDialog(_owner, ex.Message);
+ await ContentDialogHelper.CreateErrorDialog(ex.Message);
}
}
diff --git a/Ryujinx.Ava/Ui/ViewModels/SettingsViewModel.cs b/Ryujinx.Ava/Ui/ViewModels/SettingsViewModel.cs
index ef7a53e608..7b175f08c6 100644
--- a/Ryujinx.Ava/Ui/ViewModels/SettingsViewModel.cs
+++ b/Ryujinx.Ava/Ui/ViewModels/SettingsViewModel.cs
@@ -63,8 +63,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
{
Dispatcher.UIThread.Post(async () =>
{
- await ContentDialogHelper.CreateInfoDialog(_owner,
- LocaleManager.Instance["DialogSettingsBackendThreadingWarningMessage"],
+ await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance["DialogSettingsBackendThreadingWarningMessage"],
"",
"",
LocaleManager.Instance["InputDialogOk"],
diff --git a/Ryujinx.Ava/Ui/ViewModels/UserProfileViewModel.cs b/Ryujinx.Ava/Ui/ViewModels/UserProfileViewModel.cs
index 66fa7e34d6..f7a500777d 100644
--- a/Ryujinx.Ava/Ui/ViewModels/UserProfileViewModel.cs
+++ b/Ryujinx.Ava/Ui/ViewModels/UserProfileViewModel.cs
@@ -1,31 +1,27 @@
using Avalonia.Threading;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Ui.Controls;
-using Ryujinx.Ava.Ui.Windows;
using Ryujinx.HLE.HOS.Services.Account.Acc;
using System;
using System.Collections.ObjectModel;
using System.Linq;
-using System.Threading.Tasks;
using UserProfile = Ryujinx.Ava.Ui.Models.UserProfile;
namespace Ryujinx.Ava.Ui.ViewModels
{
public class UserProfileViewModel : BaseModel, IDisposable
{
- private const uint MaxProfileNameLength = 0x20;
-
- private readonly UserProfileWindow _owner;
+ private readonly NavigationDialogHost _owner;
private UserProfile _selectedProfile;
- private string _tempUserName;
+ private UserProfile _highlightedProfile;
public UserProfileViewModel()
{
Profiles = new ObservableCollection();
}
- public UserProfileViewModel(UserProfileWindow owner) : this()
+ public UserProfileViewModel(NavigationDialogHost owner) : this()
{
_owner = owner;
@@ -42,12 +38,29 @@ namespace Ryujinx.Ava.Ui.ViewModels
_selectedProfile = value;
OnPropertyChanged(nameof(SelectedProfile));
- OnPropertyChanged(nameof(IsSelectedProfileDeletable));
+ OnPropertyChanged(nameof(IsHighlightedProfileDeletable));
+ OnPropertyChanged(nameof(IsHighlightedProfileEditable));
}
}
- public bool IsSelectedProfileDeletable =>
- _selectedProfile != null && _selectedProfile.UserId != AccountManager.DefaultUserId;
+ public bool IsHighlightedProfileEditable =>
+ _highlightedProfile != null;
+
+ public bool IsHighlightedProfileDeletable =>
+ _highlightedProfile != null && _highlightedProfile.UserId != AccountManager.DefaultUserId;
+
+ public UserProfile HighlightedProfile
+ {
+ get => _highlightedProfile;
+ set
+ {
+ _highlightedProfile = value;
+
+ OnPropertyChanged(nameof(HighlightedProfile));
+ OnPropertyChanged(nameof(IsHighlightedProfileDeletable));
+ OnPropertyChanged(nameof(IsHighlightedProfileEditable));
+ }
+ }
public void Dispose()
{
@@ -78,64 +91,24 @@ namespace Ryujinx.Ava.Ui.ViewModels
}
}
- public async void ChooseProfileImage()
+ public void AddUser()
{
- await SelectProfileImage();
+ UserProfile userProfile = null;
+ _owner.Navigate(typeof(UserEditor), (this._owner, userProfile, true));
}
- public async Task SelectProfileImage(bool isNewUser = false)
+ public void EditUser()
{
- ProfileImageSelectionDialog selectionDialog = new(_owner.ContentManager);
-
- await selectionDialog.ShowDialog(_owner);
-
- if (selectionDialog.BufferImageProfile != null)
- {
- if (isNewUser)
- {
- if (!string.IsNullOrWhiteSpace(_tempUserName))
- {
- _owner.AccountManager.AddUser(_tempUserName, selectionDialog.BufferImageProfile);
- }
- }
- else if (SelectedProfile != null)
- {
- _owner.AccountManager.SetUserImage(SelectedProfile.UserId, selectionDialog.BufferImageProfile);
- SelectedProfile.Image = selectionDialog.BufferImageProfile;
-
- SelectedProfile = null;
- }
-
- LoadProfiles();
- }
- }
-
- public async void AddUser()
- {
- var dlgTitle = LocaleManager.Instance["InputDialogAddNewProfileTitle"];
- var dlgMainText = LocaleManager.Instance["InputDialogAddNewProfileHeader"];
- var dlgSubText = string.Format(LocaleManager.Instance["InputDialogAddNewProfileSubtext"],
- MaxProfileNameLength);
-
- _tempUserName =
- await ContentDialogHelper.CreateInputDialog(dlgTitle, dlgMainText, dlgSubText, _owner,
- MaxProfileNameLength);
-
- if (!string.IsNullOrWhiteSpace(_tempUserName))
- {
- await SelectProfileImage(true);
- }
-
- _tempUserName = String.Empty;
+ _owner.Navigate(typeof(UserEditor), (this._owner, _highlightedProfile ?? SelectedProfile, false));
}
public async void DeleteUser()
{
- if (_selectedProfile != null)
+ if (_highlightedProfile != null)
{
var lastUserId = _owner.AccountManager.LastOpenedUser.UserId;
- if (_selectedProfile.UserId == lastUserId)
+ if (_highlightedProfile.UserId == lastUserId)
{
// If we are deleting the currently open profile, then we must open something else before deleting.
var profile = Profiles.FirstOrDefault(x => x.UserId != lastUserId);
@@ -144,8 +117,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
{
Dispatcher.UIThread.Post(async () =>
{
- await ContentDialogHelper.CreateErrorDialog(_owner,
- LocaleManager.Instance["DialogUserProfileDeletionWarningMessage"]);
+ await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogUserProfileDeletionWarningMessage"]);
});
return;
@@ -155,13 +127,12 @@ namespace Ryujinx.Ava.Ui.ViewModels
}
var result =
- await ContentDialogHelper.CreateConfirmationDialog(_owner,
- LocaleManager.Instance["DialogUserProfileDeletionConfirmMessage"], "",
+ await ContentDialogHelper.CreateConfirmationDialog(LocaleManager.Instance["DialogUserProfileDeletionConfirmMessage"], "",
LocaleManager.Instance["InputDialogYes"], LocaleManager.Instance["InputDialogNo"], "");
if (result == UserResult.Yes)
{
- _owner.AccountManager.DeleteUser(_selectedProfile.UserId);
+ _owner.AccountManager.DeleteUser(_highlightedProfile.UserId);
}
}
diff --git a/Ryujinx.Ava/Ui/Windows/AboutWindow.axaml b/Ryujinx.Ava/Ui/Windows/AboutWindow.axaml
index aeaac5daa7..505b8004e9 100644
--- a/Ryujinx.Ava/Ui/Windows/AboutWindow.axaml
+++ b/Ryujinx.Ava/Ui/Windows/AboutWindow.axaml
@@ -17,43 +17,43 @@
SizeToContent="Width"
WindowStartupLocation="CenterOwner"
mc:Ignorable="d">
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
-
-
-
-
-
+
+
+
diff --git a/Ryujinx.Ava/Ui/Windows/AboutWindow.axaml.cs b/Ryujinx.Ava/Ui/Windows/AboutWindow.axaml.cs
index 3f93ccb75f..75e9901b02 100644
--- a/Ryujinx.Ava/Ui/Windows/AboutWindow.axaml.cs
+++ b/Ryujinx.Ava/Ui/Windows/AboutWindow.axaml.cs
@@ -13,7 +13,7 @@ using System.Threading.Tasks;
namespace Ryujinx.Ava.Ui.Windows
{
- public class AboutWindow : StyleableWindow
+ public partial class AboutWindow : StyleableWindow
{
public AboutWindow()
{
@@ -39,15 +39,6 @@ namespace Ryujinx.Ava.Ui.Windows
public string Developers => string.Format(LocaleManager.Instance["AboutPageDeveloperListMore"], "gdkchan, Ac_K, Thog, rip in peri peri, LDj3SNuD, emmaus, Thealexbarney, Xpl0itR, GoffyDude, »jD«");
- public TextBlock SupportersTextBlock { get; set; }
-
- private void InitializeComponent()
- {
- AvaloniaXamlLoader.Load(this);
-
- SupportersTextBlock = this.FindControl("SupportersTextBlock");
- }
-
private void Button_OnClick(object sender, RoutedEventArgs e)
{
if (sender is Button button)
diff --git a/Ryujinx.Ava/Ui/Windows/AmiiboWindow.axaml.cs b/Ryujinx.Ava/Ui/Windows/AmiiboWindow.axaml.cs
index bd0935a9c4..5ed845710d 100644
--- a/Ryujinx.Ava/Ui/Windows/AmiiboWindow.axaml.cs
+++ b/Ryujinx.Ava/Ui/Windows/AmiiboWindow.axaml.cs
@@ -7,7 +7,7 @@ using Ryujinx.Ava.Ui.ViewModels;
namespace Ryujinx.Ava.Ui.Windows
{
- public class AmiiboWindow : StyleableWindow
+ public partial class AmiiboWindow : StyleableWindow
{
public AmiiboWindow(bool showAll, string lastScannedAmiiboId, string titleId)
{
@@ -44,11 +44,6 @@ namespace Ryujinx.Ava.Ui.Windows
public Amiibo.AmiiboApi ScannedAmiibo { get; set; }
public AmiiboWindowViewModel ViewModel { get; set; }
- private void InitializeComponent()
- {
- AvaloniaXamlLoader.Load(this);
- }
-
private void ScanButton_Click(object sender, RoutedEventArgs e)
{
if (ViewModel.AmiiboSelectedIndex > -1)
diff --git a/Ryujinx.Ava/Ui/Windows/AvatarWindow.axaml b/Ryujinx.Ava/Ui/Windows/AvatarWindow.axaml
index 6c7576bc0a..0be6513002 100644
--- a/Ryujinx.Ava/Ui/Windows/AvatarWindow.axaml
+++ b/Ryujinx.Ava/Ui/Windows/AvatarWindow.axaml
@@ -1,36 +1,35 @@
-
+ x:DataType="viewModels:AvatarProfileViewModel">
-
-
-
-
+
+
+
+
-
-
+
@@ -45,9 +44,9 @@
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/Ryujinx.Ava/Ui/Windows/AvatarWindow.axaml.cs b/Ryujinx.Ava/Ui/Windows/AvatarWindow.axaml.cs
index 25e89846c8..2189f47d85 100644
--- a/Ryujinx.Ava/Ui/Windows/AvatarWindow.axaml.cs
+++ b/Ryujinx.Ava/Ui/Windows/AvatarWindow.axaml.cs
@@ -1,70 +1,76 @@
-using Avalonia;
+using Avalonia.Controls;
using Avalonia.Interactivity;
-using Avalonia.Markup.Xaml;
-using Ryujinx.Ava.Common.Locale;
+using FluentAvalonia.UI.Controls;
+using FluentAvalonia.UI.Navigation;
+using Ryujinx.Ava.Ui.Controls;
+using Ryujinx.Ava.Ui.Models;
using Ryujinx.Ava.Ui.ViewModels;
using Ryujinx.HLE.FileSystem;
-using System;
namespace Ryujinx.Ava.Ui.Windows
{
- public class AvatarWindow : StyleableWindow
+ public partial class AvatarWindow : UserControl
{
+ private NavigationDialogHost _parent;
+ private TempProfile _profile;
+
public AvatarWindow(ContentManager contentManager)
{
ContentManager = contentManager;
- ViewModel = new AvatarProfileViewModel(() => ViewModel.ReloadImages());
DataContext = ViewModel;
InitializeComponent();
-#if DEBUG
- this.AttachDevTools();
-#endif
- Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["AvatarWindowTitle"];
}
public AvatarWindow()
{
InitializeComponent();
-#if DEBUG
- this.AttachDevTools();
-#endif
+
+ AddHandler(Frame.NavigatedToEvent, (s, e) =>
+ {
+ NavigatedTo(e);
+ }, RoutingStrategies.Direct);
+ }
+
+ private void NavigatedTo(NavigationEventArgs arg)
+ {
if (Program.PreviewerDetached)
{
- Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["AvatarWindowTitle"];
+ if (arg.NavigationMode == NavigationMode.New)
+ {
+ (_parent, _profile) = ((NavigationDialogHost, TempProfile))arg.Parameter;
+ ContentManager = _parent.ContentManager;
+ if (Program.PreviewerDetached)
+ {
+ ViewModel = new AvatarProfileViewModel(() => ViewModel.ReloadImages());
+ }
+
+ DataContext = ViewModel;
+ }
}
}
- public ContentManager ContentManager { get; }
-
- public byte[] SelectedImage { get; set; }
+ public ContentManager ContentManager { get; private set; }
internal AvatarProfileViewModel ViewModel { get; set; }
- private void InitializeComponent()
- {
- AvaloniaXamlLoader.Load(this);
- }
-
- protected override void OnClosed(EventArgs e)
- {
- ViewModel.Dispose();
- base.OnClosed(e);
- }
-
private void CloseButton_OnClick(object sender, RoutedEventArgs e)
{
- Close();
+ ViewModel.Dispose();
+
+ _parent.GoBack();
}
private void ChooseButton_OnClick(object sender, RoutedEventArgs e)
{
if (ViewModel.SelectedIndex > -1)
{
- SelectedImage = ViewModel.SelectedImage;
+ _profile.Image = ViewModel.SelectedImage;
- Close();
+ ViewModel.Dispose();
+
+ _parent.GoBack();
}
}
}
diff --git a/Ryujinx.Ava/Ui/Windows/CheatWindow.axaml.cs b/Ryujinx.Ava/Ui/Windows/CheatWindow.axaml.cs
index 33abeb8d7a..e3cccdd3bc 100644
--- a/Ryujinx.Ava/Ui/Windows/CheatWindow.axaml.cs
+++ b/Ryujinx.Ava/Ui/Windows/CheatWindow.axaml.cs
@@ -12,7 +12,7 @@ using System.Linq;
namespace Ryujinx.Ava.Ui.Windows
{
- public class CheatWindow : StyleableWindow
+ public partial class CheatWindow : StyleableWindow
{
private readonly string _enabledCheatsPath;
public bool NoCheatsFound { get; }
@@ -102,11 +102,6 @@ namespace Ryujinx.Ava.Ui.Windows
this.AttachDevTools();
}
- private void InitializeComponent()
- {
- AvaloniaXamlLoader.Load(this);
- }
-
public void Save()
{
if (NoCheatsFound)
diff --git a/Ryujinx.Ava/Ui/Windows/ControllerSettingsWindow.axaml.cs b/Ryujinx.Ava/Ui/Windows/ControllerSettingsWindow.axaml.cs
index 0321359963..45262bcd5d 100644
--- a/Ryujinx.Ava/Ui/Windows/ControllerSettingsWindow.axaml.cs
+++ b/Ryujinx.Ava/Ui/Windows/ControllerSettingsWindow.axaml.cs
@@ -24,11 +24,10 @@ using Key = Ryujinx.Input.Key;
namespace Ryujinx.Ava.Ui.Windows
{
- public class ControllerSettingsWindow : UserControl
+ public partial class ControllerSettingsWindow : UserControl
{
private bool _dialogOpen;
- public Grid SettingButtons { get; set; }
private ButtonKeyAssigner _currentAssigner;
internal ControllerSettingsViewModel ViewModel { get; set; }
@@ -48,13 +47,6 @@ namespace Ryujinx.Ava.Ui.Windows
}
}
- private void InitializeComponent()
- {
- AvaloniaXamlLoader.Load(this);
-
- SettingButtons = this.FindControl("SettingButtons");
- }
-
protected override void OnPointerReleased(PointerReleasedEventArgs e)
{
base.OnPointerReleased(e);
@@ -165,7 +157,6 @@ namespace Ryujinx.Ava.Ui.Windows
_dialogOpen = true;
var result = await ContentDialogHelper.CreateConfirmationDialog(
- this.GetVisualRoot() as StyleableWindow,
LocaleManager.Instance["DialogControllerSettingsModifiedConfirmMessage"],
LocaleManager.Instance["DialogControllerSettingsModifiedConfirmSubMessage"],
LocaleManager.Instance["InputDialogYes"],
diff --git a/Ryujinx.Ava/Ui/Windows/DlcManagerWindow.axaml.cs b/Ryujinx.Ava/Ui/Windows/DlcManagerWindow.axaml.cs
index 7450c64fc6..09b221e3fc 100644
--- a/Ryujinx.Ava/Ui/Windows/DlcManagerWindow.axaml.cs
+++ b/Ryujinx.Ava/Ui/Windows/DlcManagerWindow.axaml.cs
@@ -1,7 +1,6 @@
using Avalonia;
using Avalonia.Collections;
using Avalonia.Controls;
-using Avalonia.Markup.Xaml;
using Avalonia.Threading;
using LibHac.Common;
using LibHac.Fs;
@@ -27,7 +26,7 @@ using Path = System.IO.Path;
namespace Ryujinx.Ava.Ui.Windows
{
- public class DlcManagerWindow : StyleableWindow
+ public partial class DlcManagerWindow : StyleableWindow
{
private readonly List _dlcContainerList;
private readonly string _dlcJsonPath;
@@ -35,7 +34,6 @@ namespace Ryujinx.Ava.Ui.Windows
public VirtualFileSystem VirtualFileSystem { get; }
public AvaloniaList Dlcs { get; set; }
- public Grid DlcGrid { get; private set; }
public ulong TitleId { get; }
public string TitleName { get; }
@@ -47,7 +45,7 @@ namespace Ryujinx.Ava.Ui.Windows
InitializeComponent();
AttachDebugDevTools();
-
+
Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["DlcWindowTitle"];
}
@@ -72,7 +70,7 @@ namespace Ryujinx.Ava.Ui.Windows
InitializeComponent();
AttachDebugDevTools();
-
+
Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["DlcWindowTitle"];
LoadDlcs();
@@ -84,15 +82,6 @@ namespace Ryujinx.Ava.Ui.Windows
this.AttachDevTools();
}
- private void InitializeComponent()
- {
- Dlcs = new AvaloniaList();
-
- AvaloniaXamlLoader.Load(this);
-
- DlcGrid = this.FindControl("DlcGrid");
- }
-
private void LoadDlcs()
{
foreach (DlcContainer dlcContainer in _dlcContainerList)
@@ -129,8 +118,7 @@ namespace Ryujinx.Ava.Ui.Windows
{
Dispatcher.UIThread.InvokeAsync(async () =>
{
- await ContentDialogHelper.CreateErrorDialog(this,
- string.Format(LocaleManager.Instance[
+ await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance[
"DialogDlcLoadNcaErrorMessage"], ex.Message, containerPath));
});
}
@@ -180,7 +168,7 @@ namespace Ryujinx.Ava.Ui.Windows
if (!containsDlc)
{
- await ContentDialogHelper.CreateErrorDialog(this, LocaleManager.Instance["DialogDlcNoDlcErrorMessage"]);
+ await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogDlcNoDlcErrorMessage"]);
}
}
}
@@ -189,7 +177,7 @@ namespace Ryujinx.Ava.Ui.Windows
{
if (removeSelectedOnly)
{
- Dlcs.RemoveAll(Dlcs.Where(x => x.IsEnabled).ToList());
+ Dlcs.RemoveAll(Dlcs.Where(x => x.IsEnabled).ToList());
}
else
{
diff --git a/Ryujinx.Ava/Ui/Windows/MainWindow.axaml b/Ryujinx.Ava/Ui/Windows/MainWindow.axaml
index f79b4f79eb..f02cd00192 100644
--- a/Ryujinx.Ava/Ui/Windows/MainWindow.axaml
+++ b/Ryujinx.Ava/Ui/Windows/MainWindow.axaml
@@ -38,18 +38,6 @@
-
-
-
diff --git a/Ryujinx.Ava/Ui/Windows/MainWindow.axaml.cs b/Ryujinx.Ava/Ui/Windows/MainWindow.axaml.cs
index 2b5c10e206..d55dd41325 100644
--- a/Ryujinx.Ava/Ui/Windows/MainWindow.axaml.cs
+++ b/Ryujinx.Ava/Ui/Windows/MainWindow.axaml.cs
@@ -36,7 +36,7 @@ using InputManager = Ryujinx.Input.HLE.InputManager;
using ProgressBar = Avalonia.Controls.ProgressBar;
namespace Ryujinx.Ava.Ui.Windows
{
- public class MainWindow : StyleableWindow
+ public partial class MainWindow : StyleableWindow
{
private bool _canUpdate;
private bool _isClosing;
@@ -62,22 +62,6 @@ namespace Ryujinx.Ava.Ui.Windows
public InputManager InputManager { get; private set; }
internal RendererControl GlRenderer { get; private set; }
- public ContentControl ContentFrame { get; private set; }
- public TextBlock LoadStatus { get; private set; }
- public TextBlock FirmwareStatus { get; private set; }
- public TextBox SearchBox { get; private set; }
- public ProgressBar LoadProgressBar { get; private set; }
- public Menu Menu { get; private set; }
- public MenuItem UpdateMenuItem { get; private set; }
- public MenuItem ActionsMenuItem { get; private set; }
- public GameGridView GameGrid { get; private set; }
- public GameListView GameList { get; private set; }
- public OffscreenTextBox HiddenTextBox { get; private set; }
- public HotKeyControl FullscreenHotKey { get; private set; }
- public HotKeyControl FullscreenHotKey2 { get; private set; }
- public HotKeyControl DockToggleHotKey { get; private set; }
- public HotKeyControl ExitHotKey { get; private set; }
- public ToggleSplitButton VolumeStatus { get; set; }
internal MainWindowViewModel ViewModel { get; private set; }
public SettingsWindow SettingsWindow { get; set; }
@@ -102,6 +86,7 @@ namespace Ryujinx.Ava.Ui.Windows
DataContext = ViewModel;
InitializeComponent();
+ Load();
AttachDebugDevTools();
UiHandler = new AvaHostUiHandler(this);
@@ -192,7 +177,9 @@ namespace Ryujinx.Ava.Ui.Windows
string mainMessage = LocaleManager.Instance["DialogPerformanceCheckLoggingEnabledMessage"];
string secondaryMessage = LocaleManager.Instance["DialogPerformanceCheckLoggingEnabledConfirmMessage"];
- UserResult result = await ContentDialogHelper.CreateConfirmationDialog(this, mainMessage, secondaryMessage, LocaleManager.Instance["InputDialogYes"], LocaleManager.Instance["InputDialogNo"], LocaleManager.Instance["RyujinxConfirm"]);
+ UserResult result = await ContentDialogHelper.CreateConfirmationDialog(mainMessage, secondaryMessage,
+ LocaleManager.Instance["InputDialogYes"], LocaleManager.Instance["InputDialogNo"],
+ LocaleManager.Instance["RyujinxConfirm"]);
if (result != UserResult.Yes)
{
@@ -205,9 +192,12 @@ namespace Ryujinx.Ava.Ui.Windows
if (!string.IsNullOrWhiteSpace(ConfigurationState.Instance.Graphics.ShadersDumpPath.Value))
{
string mainMessage = LocaleManager.Instance["DialogPerformanceCheckShaderDumpEnabledMessage"];
- string secondaryMessage = LocaleManager.Instance["DialogPerformanceCheckShaderDumpEnabledConfirmMessage"];
+ string secondaryMessage =
+ LocaleManager.Instance["DialogPerformanceCheckShaderDumpEnabledConfirmMessage"];
- UserResult result = await ContentDialogHelper.CreateConfirmationDialog(this, mainMessage, secondaryMessage, LocaleManager.Instance["InputDialogYes"], LocaleManager.Instance["InputDialogNo"], LocaleManager.Instance["RyujinxConfirm"]);
+ UserResult result = await ContentDialogHelper.CreateConfirmationDialog(mainMessage, secondaryMessage,
+ LocaleManager.Instance["InputDialogYes"], LocaleManager.Instance["InputDialogNo"],
+ LocaleManager.Instance["RyujinxConfirm"]);
if (result != UserResult.Yes)
{
@@ -231,7 +221,7 @@ namespace Ryujinx.Ava.Ui.Windows
{
if (AppHost != null)
{
- await ContentDialogHelper.CreateInfoDialog(this,
+ await ContentDialogHelper.CreateInfoDialog(
LocaleManager.Instance["DialogLoadAppGameAlreadyLoadedMessage"],
LocaleManager.Instance["DialogLoadAppGameAlreadyLoadedSubMessage"],
LocaleManager.Instance["InputDialogOk"],
@@ -254,7 +244,7 @@ namespace Ryujinx.Ava.Ui.Windows
PrepareLoadScreen();
- _mainViewContent = ContentFrame.Content as Control;
+ _mainViewContent = Content.Content as Control;
GlRenderer = new RendererControl(3, 3, ConfigurationState.Instance.Logger.GraphicsDebugLevel);
AppHost = new AppHost(GlRenderer, InputManager, path, VirtualFileSystem, ContentManager, AccountManager, _userChannelPersistence, this);
@@ -321,7 +311,7 @@ namespace Ryujinx.Ava.Ui.Windows
Dispatcher.UIThread.InvokeAsync(() =>
{
- ContentFrame.Content = GlRenderer;
+ Content.Content = GlRenderer;
if (startFullscreen && WindowState != WindowState.FullScreen)
{
@@ -365,9 +355,9 @@ namespace Ryujinx.Ava.Ui.Windows
Dispatcher.UIThread.InvokeAsync(() =>
{
- if (ContentFrame.Content != _mainViewContent)
+ if (Content.Content != _mainViewContent)
{
- ContentFrame.Content = _mainViewContent;
+ Content.Content = _mainViewContent;
}
ViewModel.ShowMenuAndStatusBar = true;
@@ -501,27 +491,8 @@ namespace Ryujinx.Ava.Ui.Windows
ViewModel.IsAppletMenuActive = hasApplet;
}
- private void InitializeComponent()
+ private void Load()
{
- AvaloniaXamlLoader.Load(this);
-
- ContentFrame = this.FindControl("Content");
- GameList = this.FindControl("GameList");
- LoadStatus = this.FindControl("LoadStatus");
- FirmwareStatus = this.FindControl("FirmwareStatus");
- LoadProgressBar = this.FindControl("LoadProgressBar");
- SearchBox = this.FindControl("SearchBox");
- Menu = this.FindControl