aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Ava/UI
diff options
context:
space:
mode:
authorMary Guillemard <mary@mary.zone>2024-03-02 12:51:05 +0100
committerGitHub <noreply@github.com>2024-03-02 12:51:05 +0100
commitec6cb0abb4b7669895b6e96fd7581c93b5abd691 (patch)
tree128c862ff5faea0b219467656d4023bee7faefb5 /src/Ryujinx.Ava/UI
parent53b5985da6b9d7b281d9fc25b93bfd1d1918a107 (diff)
infra: Make Avalonia the default UI (#6375)
* misc: Move Ryujinx project to Ryujinx.Gtk3 This breaks release CI for now but that's fine. Signed-off-by: Mary Guillemard <mary@mary.zone> * misc: Move Ryujinx.Ava project to Ryujinx This breaks CI for now, but it's fine. Signed-off-by: Mary Guillemard <mary@mary.zone> * infra: Make Avalonia the default UI Should fix CI after the previous changes. GTK3 isn't build by the release job anymore, only by PR CI. This also ensure that the test-ava update package is still generated to allow update from the old testing channel. Signed-off-by: Mary Guillemard <mary@mary.zone> * Fix missing copy in create_app_bundle.sh Signed-off-by: Mary Guillemard <mary@mary.zone> * Fix syntax error Signed-off-by: Mary Guillemard <mary@mary.zone> --------- Signed-off-by: Mary Guillemard <mary@mary.zone>
Diffstat (limited to 'src/Ryujinx.Ava/UI')
-rw-r--r--src/Ryujinx.Ava/UI/Applet/AvaHostUIHandler.cs204
-rw-r--r--src/Ryujinx.Ava/UI/Applet/AvaloniaDynamicTextInputHandler.cs162
-rw-r--r--src/Ryujinx.Ava/UI/Applet/AvaloniaHostUITheme.cs41
-rw-r--r--src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml145
-rw-r--r--src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml.cs140
-rw-r--r--src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml54
-rw-r--r--src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml.cs74
-rw-r--r--src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml67
-rw-r--r--src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs183
-rw-r--r--src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml95
-rw-r--r--src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs371
-rw-r--r--src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml102
-rw-r--r--src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs51
-rw-r--r--src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml160
-rw-r--r--src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs51
-rw-r--r--src/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml17
-rw-r--r--src/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml.cs217
-rw-r--r--src/Ryujinx.Ava/UI/Controls/SliderScroll.axaml.cs31
-rw-r--r--src/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml42
-rw-r--r--src/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml.cs31
-rw-r--r--src/Ryujinx.Ava/UI/Helpers/ApplicationOpenedEventArgs.cs16
-rw-r--r--src/Ryujinx.Ava/UI/Helpers/BitmapArrayValueConverter.cs36
-rw-r--r--src/Ryujinx.Ava/UI/Helpers/ButtonKeyAssigner.cs118
-rw-r--r--src/Ryujinx.Ava/UI/Helpers/ContentDialogHelper.cs425
-rw-r--r--src/Ryujinx.Ava/UI/Helpers/Glyph.cs9
-rw-r--r--src/Ryujinx.Ava/UI/Helpers/GlyphValueConverter.cs42
-rw-r--r--src/Ryujinx.Ava/UI/Helpers/KeyValueConverter.cs46
-rw-r--r--src/Ryujinx.Ava/UI/Helpers/LocalizedNeverConverter.cs43
-rw-r--r--src/Ryujinx.Ava/UI/Helpers/LoggerAdapter.cs102
-rw-r--r--src/Ryujinx.Ava/UI/Helpers/MiniCommand.cs71
-rw-r--r--src/Ryujinx.Ava/UI/Helpers/NotificationHelper.cs70
-rw-r--r--src/Ryujinx.Ava/UI/Helpers/OffscreenTextBox.cs39
-rw-r--r--src/Ryujinx.Ava/UI/Helpers/TimeZoneConverter.cs28
-rw-r--r--src/Ryujinx.Ava/UI/Helpers/UserErrorDialog.cs90
-rw-r--r--src/Ryujinx.Ava/UI/Helpers/UserResult.cs12
-rw-r--r--src/Ryujinx.Ava/UI/Helpers/Win32NativeInterop.cs125
-rw-r--r--src/Ryujinx.Ava/UI/Models/CheatNode.cs57
-rw-r--r--src/Ryujinx.Ava/UI/Models/ControllerModel.cs6
-rw-r--r--src/Ryujinx.Ava/UI/Models/DeviceType.cs9
-rw-r--r--src/Ryujinx.Ava/UI/Models/DownloadableContentModel.cs35
-rw-r--r--src/Ryujinx.Ava/UI/Models/Generic/LastPlayedSortComparer.cs31
-rw-r--r--src/Ryujinx.Ava/UI/Models/Generic/TimePlayedSortComparer.cs31
-rw-r--r--src/Ryujinx.Ava/UI/Models/InputConfiguration.cs456
-rw-r--r--src/Ryujinx.Ava/UI/Models/ModModel.cs32
-rw-r--r--src/Ryujinx.Ava/UI/Models/PlayerModel.cs6
-rw-r--r--src/Ryujinx.Ava/UI/Models/ProfileImageModel.cs32
-rw-r--r--src/Ryujinx.Ava/UI/Models/SaveModel.cs96
-rw-r--r--src/Ryujinx.Ava/UI/Models/StatusUpdatedEventArgs.cs28
-rw-r--r--src/Ryujinx.Ava/UI/Models/TempProfile.cs61
-rw-r--r--src/Ryujinx.Ava/UI/Models/TimeZone.cs16
-rw-r--r--src/Ryujinx.Ava/UI/Models/TitleUpdateModel.cs19
-rw-r--r--src/Ryujinx.Ava/UI/Models/UserProfile.cs104
-rw-r--r--src/Ryujinx.Ava/UI/Renderer/EmbeddedWindow.cs294
-rw-r--r--src/Ryujinx.Ava/UI/Renderer/EmbeddedWindowOpenGL.cs94
-rw-r--r--src/Ryujinx.Ava/UI/Renderer/EmbeddedWindowVulkan.cs42
-rw-r--r--src/Ryujinx.Ava/UI/Renderer/OpenTKBindingsContext.cs20
-rw-r--r--src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml12
-rw-r--r--src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml.cs68
-rw-r--r--src/Ryujinx.Ava/UI/Renderer/SPBOpenGLContext.cs49
-rw-r--r--src/Ryujinx.Ava/UI/ViewModels/AboutWindowViewModel.cs131
-rw-r--r--src/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs518
-rw-r--r--src/Ryujinx.Ava/UI/ViewModels/BaseModel.cs15
-rw-r--r--src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs897
-rw-r--r--src/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs340
-rw-r--r--src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs1708
-rw-r--r--src/Ryujinx.Ava/UI/ViewModels/ModManagerViewModel.cs336
-rw-r--r--src/Ryujinx.Ava/UI/ViewModels/MotionInputViewModel.cs93
-rw-r--r--src/Ryujinx.Ava/UI/ViewModels/RumbleInputViewModel.cs27
-rw-r--r--src/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs614
-rw-r--r--src/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs249
-rw-r--r--src/Ryujinx.Ava/UI/ViewModels/UserFirmwareAvatarSelectorViewModel.cs222
-rw-r--r--src/Ryujinx.Ava/UI/ViewModels/UserProfileImageSelectorViewModel.cs18
-rw-r--r--src/Ryujinx.Ava/UI/ViewModels/UserProfileViewModel.cs28
-rw-r--r--src/Ryujinx.Ava/UI/ViewModels/UserSaveManagerViewModel.cs117
-rw-r--r--src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml1130
-rw-r--r--src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml.cs181
-rw-r--r--src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml171
-rw-r--r--src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml.cs68
-rw-r--r--src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml62
-rw-r--r--src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml.cs58
-rw-r--r--src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml203
-rw-r--r--src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs232
-rw-r--r--src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml289
-rw-r--r--src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml.cs72
-rw-r--r--src/Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml177
-rw-r--r--src/Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml.cs54
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsAudioView.axaml81
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsAudioView.axaml.cs12
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsCPUView.axaml77
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsCPUView.axaml.cs12
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml301
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml.cs12
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml103
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml.cs81
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml67
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml.cs17
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsLoggingView.axaml120
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsLoggingView.axaml.cs12
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsNetworkView.axaml58
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsNetworkView.axaml.cs12
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsSystemView.axaml224
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsSystemView.axaml.cs37
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml128
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml.cs65
-rw-r--r--src/Ryujinx.Ava/UI/Views/User/UserEditorView.axaml122
-rw-r--r--src/Ryujinx.Ava/UI/Views/User/UserEditorView.axaml.cs165
-rw-r--r--src/Ryujinx.Ava/UI/Views/User/UserFirmwareAvatarSelectorView.axaml113
-rw-r--r--src/Ryujinx.Ava/UI/Views/User/UserFirmwareAvatarSelectorView.axaml.cs89
-rw-r--r--src/Ryujinx.Ava/UI/Views/User/UserProfileImageSelectorView.axaml62
-rw-r--r--src/Ryujinx.Ava/UI/Views/User/UserProfileImageSelectorView.axaml.cs116
-rw-r--r--src/Ryujinx.Ava/UI/Views/User/UserRecovererView.axaml82
-rw-r--r--src/Ryujinx.Ava/UI/Views/User/UserRecovererView.axaml.cs51
-rw-r--r--src/Ryujinx.Ava/UI/Views/User/UserSaveManagerView.axaml213
-rw-r--r--src/Ryujinx.Ava/UI/Views/User/UserSaveManagerView.axaml.cs148
-rw-r--r--src/Ryujinx.Ava/UI/Views/User/UserSelectorView.axaml162
-rw-r--r--src/Ryujinx.Ava/UI/Views/User/UserSelectorView.axaml.cs129
-rw-r--r--src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml270
-rw-r--r--src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml.cs63
-rw-r--r--src/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml75
-rw-r--r--src/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml.cs60
-rw-r--r--src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml126
-rw-r--r--src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml.cs123
-rw-r--r--src/Ryujinx.Ava/UI/Windows/ContentDialogOverlayWindow.axaml25
-rw-r--r--src/Ryujinx.Ava/UI/Windows/ContentDialogOverlayWindow.axaml.cs21
-rw-r--r--src/Ryujinx.Ava/UI/Windows/DownloadableContentManagerWindow.axaml192
-rw-r--r--src/Ryujinx.Ava/UI/Windows/DownloadableContentManagerWindow.axaml.cs115
-rw-r--r--src/Ryujinx.Ava/UI/Windows/IconColorPicker.cs194
-rw-r--r--src/Ryujinx.Ava/UI/Windows/MainWindow.axaml205
-rw-r--r--src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs551
-rw-r--r--src/Ryujinx.Ava/UI/Windows/ModManagerWindow.axaml179
-rw-r--r--src/Ryujinx.Ava/UI/Windows/ModManagerWindow.axaml.cs139
-rw-r--r--src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml130
-rw-r--r--src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml.cs103
-rw-r--r--src/Ryujinx.Ava/UI/Windows/StyleableWindow.cs44
-rw-r--r--src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml133
-rw-r--r--src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml.cs96
136 files changed, 0 insertions, 18833 deletions
diff --git a/src/Ryujinx.Ava/UI/Applet/AvaHostUIHandler.cs b/src/Ryujinx.Ava/UI/Applet/AvaHostUIHandler.cs
deleted file mode 100644
index 4bcc35a7..00000000
--- a/src/Ryujinx.Ava/UI/Applet/AvaHostUIHandler.cs
+++ /dev/null
@@ -1,204 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Threading;
-using FluentAvalonia.UI.Controls;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Controls;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.Windows;
-using Ryujinx.HLE;
-using Ryujinx.HLE.HOS.Applets;
-using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy.Types;
-using Ryujinx.HLE.UI;
-using System;
-using System.Threading;
-
-namespace Ryujinx.Ava.UI.Applet
-{
- internal class AvaHostUIHandler : IHostUIHandler
- {
- private readonly MainWindow _parent;
-
- public IHostUITheme HostUITheme { get; }
-
- public AvaHostUIHandler(MainWindow parent)
- {
- _parent = parent;
-
- HostUITheme = new AvaloniaHostUITheme(parent);
- }
-
- public bool DisplayMessageDialog(ControllerAppletUIArgs args)
- {
- ManualResetEvent dialogCloseEvent = new(false);
-
- bool okPressed = false;
-
- Dispatcher.UIThread.InvokeAsync(async () =>
- {
- var response = await ControllerAppletDialog.ShowControllerAppletDialog(_parent, args);
- if (response == UserResult.Ok)
- {
- okPressed = true;
- }
-
- dialogCloseEvent.Set();
- });
-
- dialogCloseEvent.WaitOne();
-
- return okPressed;
- }
-
- public bool DisplayMessageDialog(string title, string message)
- {
- ManualResetEvent dialogCloseEvent = new(false);
-
- bool okPressed = false;
-
- Dispatcher.UIThread.InvokeAsync(async () =>
- {
- try
- {
- ManualResetEvent deferEvent = new(false);
-
- bool opened = false;
-
- UserResult response = await ContentDialogHelper.ShowDeferredContentDialog(_parent,
- title,
- message,
- "",
- LocaleManager.Instance[LocaleKeys.DialogOpenSettingsWindowLabel],
- "",
- LocaleManager.Instance[LocaleKeys.SettingsButtonClose],
- (int)Symbol.Important,
- deferEvent,
- async window =>
- {
- if (opened)
- {
- return;
- }
-
- opened = true;
-
- _parent.SettingsWindow = new SettingsWindow(_parent.VirtualFileSystem, _parent.ContentManager);
-
- await _parent.SettingsWindow.ShowDialog(window);
-
- _parent.SettingsWindow = null;
-
- opened = false;
- });
-
- if (response == UserResult.Ok)
- {
- okPressed = true;
- }
-
- dialogCloseEvent.Set();
- }
- catch (Exception ex)
- {
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogMessageDialogErrorExceptionMessage, ex));
-
- dialogCloseEvent.Set();
- }
- });
-
- dialogCloseEvent.WaitOne();
-
- return okPressed;
- }
-
- public bool DisplayInputDialog(SoftwareKeyboardUIArgs args, out string userText)
- {
- ManualResetEvent dialogCloseEvent = new(false);
-
- bool okPressed = false;
- bool error = false;
- string inputText = args.InitialText ?? "";
-
- Dispatcher.UIThread.InvokeAsync(async () =>
- {
- try
- {
- var response = await SwkbdAppletDialog.ShowInputDialog(LocaleManager.Instance[LocaleKeys.SoftwareKeyboard], args);
-
- if (response.Result == UserResult.Ok)
- {
- inputText = response.Input;
- okPressed = true;
- }
- }
- catch (Exception ex)
- {
- error = true;
-
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogSoftwareKeyboardErrorExceptionMessage, ex));
- }
- finally
- {
- dialogCloseEvent.Set();
- }
- });
-
- dialogCloseEvent.WaitOne();
-
- userText = error ? null : inputText;
-
- return error || okPressed;
- }
-
- public void ExecuteProgram(Switch device, ProgramSpecifyKind kind, ulong value)
- {
- device.Configuration.UserChannelPersistence.ExecuteProgram(kind, value);
- _parent.ViewModel.AppHost?.Stop();
- }
-
- public bool DisplayErrorAppletDialog(string title, string message, string[] buttons)
- {
- ManualResetEvent dialogCloseEvent = new(false);
-
- bool showDetails = false;
-
- Dispatcher.UIThread.InvokeAsync(async () =>
- {
- try
- {
- ErrorAppletWindow msgDialog = new(_parent, buttons, message)
- {
- Title = title,
- WindowStartupLocation = WindowStartupLocation.CenterScreen,
- Width = 400,
- };
-
- object response = await msgDialog.Run();
-
- if (response != null && buttons != null && buttons.Length > 1 && (int)response != buttons.Length - 1)
- {
- showDetails = true;
- }
-
- dialogCloseEvent.Set();
-
- msgDialog.Close();
- }
- catch (Exception ex)
- {
- dialogCloseEvent.Set();
-
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogErrorAppletErrorExceptionMessage, ex));
- }
- });
-
- dialogCloseEvent.WaitOne();
-
- return showDetails;
- }
-
- public IDynamicTextInputHandler CreateDynamicTextInputHandler()
- {
- return new AvaloniaDynamicTextInputHandler(_parent);
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Applet/AvaloniaDynamicTextInputHandler.cs b/src/Ryujinx.Ava/UI/Applet/AvaloniaDynamicTextInputHandler.cs
deleted file mode 100644
index 531d0061..00000000
--- a/src/Ryujinx.Ava/UI/Applet/AvaloniaDynamicTextInputHandler.cs
+++ /dev/null
@@ -1,162 +0,0 @@
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Input;
-using Avalonia.Threading;
-using Ryujinx.Ava.Input;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.Windows;
-using Ryujinx.HLE.UI;
-using System;
-using System.Threading;
-using HidKey = Ryujinx.Common.Configuration.Hid.Key;
-
-namespace Ryujinx.Ava.UI.Applet
-{
- class AvaloniaDynamicTextInputHandler : IDynamicTextInputHandler
- {
- private MainWindow _parent;
- private readonly OffscreenTextBox _hiddenTextBox;
- private bool _canProcessInput;
- private IDisposable _textChangedSubscription;
- private IDisposable _selectionStartChangedSubscription;
- private IDisposable _selectionEndtextChangedSubscription;
-
- public AvaloniaDynamicTextInputHandler(MainWindow parent)
- {
- _parent = parent;
-
- (_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).KeyPressed += AvaloniaDynamicTextInputHandler_KeyPressed;
- (_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).KeyRelease += AvaloniaDynamicTextInputHandler_KeyRelease;
- (_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).TextInput += AvaloniaDynamicTextInputHandler_TextInput;
-
- _hiddenTextBox = _parent.HiddenTextBox;
-
- Dispatcher.UIThread.Post(() =>
- {
- _textChangedSubscription = _hiddenTextBox.GetObservable(TextBox.TextProperty).Subscribe(TextChanged);
- _selectionStartChangedSubscription = _hiddenTextBox.GetObservable(TextBox.SelectionStartProperty).Subscribe(SelectionChanged);
- _selectionEndtextChangedSubscription = _hiddenTextBox.GetObservable(TextBox.SelectionEndProperty).Subscribe(SelectionChanged);
- });
- }
-
- private void TextChanged(string text)
- {
- TextChangedEvent?.Invoke(text ?? string.Empty, _hiddenTextBox.SelectionStart, _hiddenTextBox.SelectionEnd, true);
- }
-
- private void SelectionChanged(int selection)
- {
- if (_hiddenTextBox.SelectionEnd < _hiddenTextBox.SelectionStart)
- {
- _hiddenTextBox.SelectionStart = _hiddenTextBox.SelectionEnd;
- }
-
- TextChangedEvent?.Invoke(_hiddenTextBox.Text ?? string.Empty, _hiddenTextBox.SelectionStart, _hiddenTextBox.SelectionEnd, true);
- }
-
- private void AvaloniaDynamicTextInputHandler_TextInput(object sender, string text)
- {
- Dispatcher.UIThread.InvokeAsync(() =>
- {
- if (_canProcessInput)
- {
- _hiddenTextBox.SendText(text);
- }
- });
- }
-
- private void AvaloniaDynamicTextInputHandler_KeyRelease(object sender, KeyEventArgs e)
- {
- var key = (HidKey)AvaloniaKeyboardMappingHelper.ToInputKey(e.Key);
-
- if (!(KeyReleasedEvent?.Invoke(key)).GetValueOrDefault(true))
- {
- return;
- }
-
- e.RoutedEvent = OffscreenTextBox.GetKeyUpRoutedEvent();
-
- Dispatcher.UIThread.InvokeAsync(() =>
- {
- if (_canProcessInput)
- {
- _hiddenTextBox.SendKeyUpEvent(e);
- }
- });
- }
-
- private void AvaloniaDynamicTextInputHandler_KeyPressed(object sender, KeyEventArgs e)
- {
- var key = (HidKey)AvaloniaKeyboardMappingHelper.ToInputKey(e.Key);
-
- if (!(KeyPressedEvent?.Invoke(key)).GetValueOrDefault(true))
- {
- return;
- }
-
- e.RoutedEvent = OffscreenTextBox.GetKeyUpRoutedEvent();
-
- Dispatcher.UIThread.InvokeAsync(() =>
- {
- if (_canProcessInput)
- {
- _hiddenTextBox.SendKeyDownEvent(e);
- }
- });
- }
-
- public bool TextProcessingEnabled
- {
- get
- {
- return Volatile.Read(ref _canProcessInput);
- }
- set
- {
- Volatile.Write(ref _canProcessInput, value);
- }
- }
-
- public event DynamicTextChangedHandler TextChangedEvent;
- public event KeyPressedHandler KeyPressedEvent;
- public event KeyReleasedHandler KeyReleasedEvent;
-
- public void Dispose()
- {
- (_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).KeyPressed -= AvaloniaDynamicTextInputHandler_KeyPressed;
- (_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).KeyRelease -= AvaloniaDynamicTextInputHandler_KeyRelease;
- (_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).TextInput -= AvaloniaDynamicTextInputHandler_TextInput;
-
- _textChangedSubscription?.Dispose();
- _selectionStartChangedSubscription?.Dispose();
- _selectionEndtextChangedSubscription?.Dispose();
-
- Dispatcher.UIThread.Post(() =>
- {
- _hiddenTextBox.Clear();
- _parent.ViewModel.RendererHostControl.Focus();
-
- _parent = null;
- });
- }
-
- public void SetText(string text, int cursorBegin)
- {
- Dispatcher.UIThread.Post(() =>
- {
- _hiddenTextBox.Text = text;
- _hiddenTextBox.CaretIndex = cursorBegin;
- });
- }
-
- public void SetText(string text, int cursorBegin, int cursorEnd)
- {
- Dispatcher.UIThread.Post(() =>
- {
- _hiddenTextBox.Text = text;
- _hiddenTextBox.SelectionStart = cursorBegin;
- _hiddenTextBox.SelectionEnd = cursorEnd;
- });
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Applet/AvaloniaHostUITheme.cs b/src/Ryujinx.Ava/UI/Applet/AvaloniaHostUITheme.cs
deleted file mode 100644
index 016fb484..00000000
--- a/src/Ryujinx.Ava/UI/Applet/AvaloniaHostUITheme.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using Avalonia.Media;
-using Ryujinx.Ava.UI.Windows;
-using Ryujinx.HLE.UI;
-using System;
-
-namespace Ryujinx.Ava.UI.Applet
-{
- class AvaloniaHostUITheme : IHostUITheme
- {
- public AvaloniaHostUITheme(MainWindow parent)
- {
- FontFamily = OperatingSystem.IsWindows() && OperatingSystem.IsWindowsVersionAtLeast(10, 0, 22000) ? "Segoe UI Variable" : parent.FontFamily.Name;
- DefaultBackgroundColor = BrushToThemeColor(parent.Background);
- DefaultForegroundColor = BrushToThemeColor(parent.Foreground);
- DefaultBorderColor = BrushToThemeColor(parent.BorderBrush);
- SelectionBackgroundColor = BrushToThemeColor(parent.ViewControls.SearchBox.SelectionBrush);
- SelectionForegroundColor = BrushToThemeColor(parent.ViewControls.SearchBox.SelectionForegroundBrush);
- }
-
- public string FontFamily { get; }
-
- public ThemeColor DefaultBackgroundColor { get; }
- public ThemeColor DefaultForegroundColor { get; }
- public ThemeColor DefaultBorderColor { get; }
- public ThemeColor SelectionBackgroundColor { get; }
- public ThemeColor SelectionForegroundColor { get; }
-
- private static ThemeColor BrushToThemeColor(IBrush brush)
- {
- if (brush is SolidColorBrush solidColor)
- {
- return new ThemeColor((float)solidColor.Color.A / 255,
- (float)solidColor.Color.R / 255,
- (float)solidColor.Color.G / 255,
- (float)solidColor.Color.B / 255);
- }
-
- return new ThemeColor();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml b/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml
deleted file mode 100644
index b2c22f6b..00000000
--- a/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml
+++ /dev/null
@@ -1,145 +0,0 @@
-<UserControl
- x:Class="Ryujinx.Ava.UI.Applet.ControllerAppletDialog"
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:applet="using:Ryujinx.Ava.UI.Applet"
- mc:Ignorable="d"
- Width="400"
- Focusable="True"
- x:DataType="applet:ControllerAppletDialog">
- <Grid
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="*" />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="*" />
- <ColumnDefinition Width="Auto" />
- </Grid.ColumnDefinitions>
- <Border
- Grid.Column="0"
- Grid.Row="0"
- Grid.ColumnSpan="2"
- Margin="0 0 0 10"
- BorderBrush="{DynamicResource ThemeControlBorderColor}"
- BorderThickness="1"
- CornerRadius="5">
- <StackPanel
- Spacing="10"
- Margin="10">
- <TextBlock
- Text="{locale:Locale ControllerAppletDescription}" />
- <TextBlock
- IsVisible="{Binding IsDocked}"
- FontWeight="Bold"
- Text="{locale:Locale ControllerAppletDocked}" />
- </StackPanel>
- </Border>
- <Border
- Grid.Column="0"
- Grid.Row="1"
- BorderBrush="{DynamicResource ThemeControlBorderColor}"
- BorderThickness="1"
- CornerRadius="5"
- Margin="0 0 10 0">
- <StackPanel
- Margin="10"
- Spacing="10"
- Orientation="Vertical">
- <TextBlock
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- TextAlignment="Center"
- FontWeight="Bold"
- Text="{locale:Locale ControllerAppletControllers}" />
- <StackPanel
- Spacing="10"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Orientation="Horizontal">
- <Image
- Height="50"
- Width="50"
- Stretch="Uniform"
- Source="{Binding ProControllerImage}"
- IsVisible="{Binding SupportsProController}" />
- <Image
- Height="50"
- Width="50"
- Stretch="Uniform"
- Source="{Binding JoyconPairImage}"
- IsVisible="{Binding SupportsJoyconPair}" />
- <Image
- Height="50"
- Width="50"
- Stretch="Uniform"
- Source="{Binding JoyconLeftImage}"
- IsVisible="{Binding SupportsLeftJoycon}" />
- <Image
- Height="50"
- Width="50"
- Stretch="Uniform"
- Source="{Binding JoyconRightImage}"
- IsVisible="{Binding SupportsRightJoycon}" />
- </StackPanel>
- </StackPanel>
- </Border>
- <Border
- Grid.Column="1"
- Grid.Row="1"
- BorderBrush="{DynamicResource ThemeControlBorderColor}"
- BorderThickness="1"
- CornerRadius="5">
- <StackPanel
- Margin="10"
- Spacing="10"
- Orientation="Vertical">
- <TextBlock
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- TextAlignment="Center"
- FontWeight="Bold"
- Text="{locale:Locale ControllerAppletPlayers}" />
- <Border Height="50">
- <TextBlock
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- TextAlignment="Center"
- FontSize="40"
- FontWeight="Thin"
- Text="{Binding PlayerCount}" />
- </Border>
- </StackPanel>
- </Border>
- <Panel
- Margin="0 24 0 0"
- Grid.Column="0"
- Grid.Row="2"
- Grid.ColumnSpan="2">
- <StackPanel
- Orientation="Horizontal"
- Spacing="10"
- HorizontalAlignment="Right">
- <Button
- Name="SaveButton"
- MinWidth="90"
- Command="{Binding OpenSettingsWindow}">
- <TextBlock Text="{locale:Locale DialogOpenSettingsWindowLabel}" />
- </Button>
- <Button
- Name="CancelButton"
- MinWidth="90"
- Command="{Binding Close}">
- <TextBlock Text="{locale:Locale SettingsButtonClose}" />
- </Button>
- </StackPanel>
- </Panel>
- </Grid>
-</UserControl>
-
diff --git a/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml.cs b/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml.cs
deleted file mode 100644
index 279af07c..00000000
--- a/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml.cs
+++ /dev/null
@@ -1,140 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Styling;
-using Avalonia.Svg.Skia;
-using Avalonia.Threading;
-using FluentAvalonia.UI.Controls;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.Windows;
-using Ryujinx.Common;
-using Ryujinx.HLE.HOS.Applets;
-using Ryujinx.HLE.HOS.Services.Hid;
-using System;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace Ryujinx.Ava.UI.Applet
-{
- internal partial class ControllerAppletDialog : UserControl
- {
- private const string ProControllerResource = "Ryujinx.Ava/Assets/Icons/Controller_ProCon.svg";
- private const string JoyConPairResource = "Ryujinx.Ava/Assets/Icons/Controller_JoyConPair.svg";
- private const string JoyConLeftResource = "Ryujinx.Ava/Assets/Icons/Controller_JoyConLeft.svg";
- private const string JoyConRightResource = "Ryujinx.Ava/Assets/Icons/Controller_JoyConRight.svg";
-
- public static SvgImage ProControllerImage => GetResource(ProControllerResource);
- public static SvgImage JoyconPairImage => GetResource(JoyConPairResource);
- public static SvgImage JoyconLeftImage => GetResource(JoyConLeftResource);
- public static SvgImage JoyconRightImage => GetResource(JoyConRightResource);
-
- public string PlayerCount { get; set; } = "";
- public bool SupportsProController { get; set; }
- public bool SupportsLeftJoycon { get; set; }
- public bool SupportsRightJoycon { get; set; }
- public bool SupportsJoyconPair { get; set; }
- public bool IsDocked { get; set; }
-
- private readonly MainWindow _mainWindow;
-
- public ControllerAppletDialog(MainWindow mainWindow, ControllerAppletUIArgs args)
- {
- if (args.PlayerCountMin == args.PlayerCountMax)
- {
- PlayerCount = args.PlayerCountMin.ToString();
- }
- else
- {
- PlayerCount = $"{args.PlayerCountMin} - {args.PlayerCountMax}";
- }
-
- SupportsProController = (args.SupportedStyles & ControllerType.ProController) != 0;
- SupportsLeftJoycon = (args.SupportedStyles & ControllerType.JoyconLeft) != 0;
- SupportsRightJoycon = (args.SupportedStyles & ControllerType.JoyconRight) != 0;
- SupportsJoyconPair = (args.SupportedStyles & ControllerType.JoyconPair) != 0;
-
- IsDocked = args.IsDocked;
-
- _mainWindow = mainWindow;
-
- DataContext = this;
-
- InitializeComponent();
- }
-
- public ControllerAppletDialog(MainWindow mainWindow)
- {
- _mainWindow = mainWindow;
- DataContext = this;
-
- InitializeComponent();
- }
-
- public static async Task<UserResult> ShowControllerAppletDialog(MainWindow window, ControllerAppletUIArgs args)
- {
- ContentDialog contentDialog = new();
- UserResult result = UserResult.Cancel;
- ControllerAppletDialog content = new(window, args);
-
- contentDialog.Title = LocaleManager.Instance[LocaleKeys.DialogControllerAppletTitle];
- contentDialog.Content = content;
-
- void Handler(ContentDialog sender, ContentDialogClosedEventArgs eventArgs)
- {
- if (eventArgs.Result == ContentDialogResult.Primary)
- {
- result = UserResult.Ok;
- }
- }
-
- contentDialog.Closed += Handler;
-
- Style bottomBorder = new(x => x.OfType<Grid>().Name("DialogSpace").Child().OfType<Border>());
- bottomBorder.Setters.Add(new Setter(IsVisibleProperty, false));
-
- contentDialog.Styles.Add(bottomBorder);
-
- await ContentDialogHelper.ShowAsync(contentDialog);
-
- return result;
- }
-
- private static SvgImage GetResource(string path)
- {
- SvgImage image = new();
-
- if (!string.IsNullOrWhiteSpace(path))
- {
- SvgSource source = new(default(Uri));
-
- source.Load(EmbeddedResources.GetStream(path));
-
- image.Source = source;
- }
-
- return image;
- }
-
- public void OpenSettingsWindow()
- {
- if (_mainWindow.SettingsWindow == null)
- {
- Dispatcher.UIThread.InvokeAsync(async () =>
- {
- _mainWindow.SettingsWindow = new SettingsWindow(_mainWindow.VirtualFileSystem, _mainWindow.ContentManager);
- _mainWindow.SettingsWindow.NavPanel.Content = _mainWindow.SettingsWindow.InputPage;
- _mainWindow.SettingsWindow.NavPanel.SelectedItem = _mainWindow.SettingsWindow.NavPanel.MenuItems.ElementAt(1);
-
- await ContentDialogHelper.ShowWindowAsync(_mainWindow.SettingsWindow, _mainWindow);
- _mainWindow.SettingsWindow = null;
- this.Close();
- });
- }
- }
-
- public void Close()
- {
- ((ContentDialog)Parent)?.Hide();
- }
- }
-}
-
diff --git a/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml b/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml
deleted file mode 100644
index 51f37051..00000000
--- a/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml
+++ /dev/null
@@ -1,54 +0,0 @@
-<Window
- x:Class="Ryujinx.Ava.UI.Applet.ErrorAppletWindow"
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- Title="{locale:Locale ErrorWindowTitle}"
- xmlns:views="using:Ryujinx.Ava.UI.Applet"
- Width="450"
- Height="340"
- CanResize="False"
- x:DataType="views:ErrorAppletWindow"
- SizeToContent="Height"
- mc:Ignorable="d"
- Focusable="True">
- <Grid
- Margin="20"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="*" />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition />
- </Grid.ColumnDefinitions>
- <Image
- Grid.Row="1"
- Grid.RowSpan="2"
- Grid.Column="0"
- Height="80"
- MinWidth="50"
- Margin="5,10,20,10"
- Source="resm:Ryujinx.UI.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.UI.Common" />
- <TextBlock
- Grid.Row="1"
- Grid.Column="1"
- Margin="10"
- VerticalAlignment="Stretch"
- Text="{Binding Message}"
- TextWrapping="Wrap" />
- <StackPanel
- Name="ButtonStack"
- Grid.Row="2"
- Grid.Column="1"
- Margin="10"
- HorizontalAlignment="Right"
- Orientation="Horizontal"
- Spacing="10" />
- </Grid>
-</Window>
diff --git a/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml.cs b/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml.cs
deleted file mode 100644
index ec6f7682..00000000
--- a/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Interactivity;
-using Avalonia.Threading;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Windows;
-using System.Threading.Tasks;
-
-namespace Ryujinx.Ava.UI.Applet
-{
- internal partial class ErrorAppletWindow : StyleableWindow
- {
- private readonly Window _owner;
- private object _buttonResponse;
-
- public ErrorAppletWindow(Window owner, string[] buttons, string message)
- {
- _owner = owner;
- Message = message;
- DataContext = this;
- InitializeComponent();
-
- int responseId = 0;
-
- if (buttons != null)
- {
- foreach (string buttonText in buttons)
- {
- AddButton(buttonText, responseId);
- responseId++;
- }
- }
- else
- {
- AddButton(LocaleManager.Instance[LocaleKeys.InputDialogOk], 0);
- }
- }
-
- public ErrorAppletWindow()
- {
- DataContext = this;
- InitializeComponent();
- }
-
- public string Message { get; set; }
-
- private void AddButton(string label, object tag)
- {
- Dispatcher.UIThread.InvokeAsync(() =>
- {
- Button button = new() { Content = label, Tag = tag };
-
- button.Click += Button_Click;
- ButtonStack.Children.Add(button);
- });
- }
-
- private void Button_Click(object sender, RoutedEventArgs e)
- {
- if (sender is Button button)
- {
- _buttonResponse = button.Tag;
- }
-
- Close();
- }
-
- public async Task<object> Run()
- {
- await ShowDialog(_owner);
-
- return _buttonResponse;
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml b/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml
deleted file mode 100644
index b1c84734..00000000
--- a/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml
+++ /dev/null
@@ -1,67 +0,0 @@
-<UserControl
- x:Class="Ryujinx.Ava.UI.Controls.SwkbdAppletDialog"
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:views="using:Ryujinx.Ava.UI.Controls"
- Width="400"
- x:DataType="views:SwkbdAppletDialog"
- mc:Ignorable="d"
- Focusable="True">
- <Grid
- Margin="20"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition />
- </Grid.ColumnDefinitions>
- <Image
- Grid.Row="1"
- Grid.RowSpan="5"
- Height="80"
- MinWidth="50"
- Margin="5,10,20,10"
- VerticalAlignment="Center"
- Source="resm:Ryujinx.UI.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.UI.Common" />
- <TextBlock
- Grid.Row="1"
- Grid.Column="1"
- Margin="5"
- Text="{Binding MainText}"
- TextWrapping="Wrap" />
- <TextBlock
- Grid.Row="2"
- Grid.Column="1"
- Margin="5"
- Text="{Binding SecondaryText}"
- TextWrapping="Wrap" />
- <TextBox
- Name="Input"
- Grid.Row="3"
- Grid.Column="1"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Center"
- Focusable="True"
- KeyUp="Message_KeyUp"
- Text="{Binding Message}"
- TextInput="Message_TextInput"
- TextWrapping="Wrap"
- UseFloatingWatermark="True" />
- <TextBlock
- Name="Error"
- Grid.Row="4"
- Grid.Column="1"
- Margin="5"
- HorizontalAlignment="Stretch"
- TextWrapping="Wrap" />
- </Grid>
-</UserControl>
diff --git a/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs b/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs
deleted file mode 100644
index af3837e4..00000000
--- a/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs
+++ /dev/null
@@ -1,183 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Input;
-using Avalonia.Interactivity;
-using Avalonia.Media;
-using FluentAvalonia.UI.Controls;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.HLE.HOS.Applets;
-using Ryujinx.HLE.HOS.Applets.SoftwareKeyboard;
-using System;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace Ryujinx.Ava.UI.Controls
-{
- internal partial class SwkbdAppletDialog : UserControl
- {
- private Predicate<int> _checkLength = _ => true;
- private Predicate<string> _checkInput = _ => true;
- private int _inputMax;
- private int _inputMin;
- private readonly string _placeholder;
-
- private ContentDialog _host;
-
- public SwkbdAppletDialog(string mainText, string secondaryText, string placeholder, string message)
- {
- MainText = mainText;
- SecondaryText = secondaryText;
- Message = message ?? "";
- DataContext = this;
- _placeholder = placeholder;
- InitializeComponent();
-
- Input.Watermark = _placeholder;
-
- Input.AddHandler(TextInputEvent, Message_TextInput, RoutingStrategies.Tunnel, true);
- }
-
- public SwkbdAppletDialog()
- {
- DataContext = this;
- InitializeComponent();
- }
-
- protected override void OnGotFocus(GotFocusEventArgs e)
- {
- // FIXME: This does not work. Might be a bug in Avalonia with DialogHost
- // Currently focus will be redirected to the overlay window instead.
- Input.Focus();
- }
-
- public string Message { get; set; } = "";
- public string MainText { get; set; } = "";
- public string SecondaryText { get; set; } = "";
-
- public static async Task<(UserResult Result, string Input)> ShowInputDialog(string title, SoftwareKeyboardUIArgs args)
- {
- ContentDialog contentDialog = new();
-
- UserResult result = UserResult.Cancel;
-
- SwkbdAppletDialog content = new(args.HeaderText, args.SubtitleText, args.GuideText, args.InitialText);
-
- string input = string.Empty;
-
- content.SetInputLengthValidation(args.StringLengthMin, args.StringLengthMax);
- content.SetInputValidation(args.KeyboardMode);
-
- content._host = contentDialog;
- contentDialog.Title = title;
- contentDialog.PrimaryButtonText = args.SubmitText;
- contentDialog.IsPrimaryButtonEnabled = content._checkLength(content.Message.Length);
- contentDialog.SecondaryButtonText = "";
- contentDialog.CloseButtonText = LocaleManager.Instance[LocaleKeys.InputDialogCancel];
- contentDialog.Content = content;
-
- void Handler(ContentDialog sender, ContentDialogClosedEventArgs eventArgs)
- {
- if (eventArgs.Result == ContentDialogResult.Primary)
- {
- result = UserResult.Ok;
- input = content.Input.Text;
- }
- }
-
- contentDialog.Closed += Handler;
-
- await ContentDialogHelper.ShowAsync(contentDialog);
-
- return (result, input);
- }
-
- private void ApplyValidationInfo(string text)
- {
- Error.IsVisible = !string.IsNullOrEmpty(text);
- Error.Text = text;
- }
-
- public void SetInputLengthValidation(int min, int max)
- {
- _inputMin = Math.Min(min, max);
- _inputMax = Math.Max(min, max);
-
- Error.IsVisible = false;
- Error.FontStyle = FontStyle.Italic;
-
- string validationInfoText = "";
-
- if (_inputMin <= 0 && _inputMax == int.MaxValue) // Disable.
- {
- Error.IsVisible = false;
-
- _checkLength = length => true;
- }
- else if (_inputMin > 0 && _inputMax == int.MaxValue)
- {
- validationInfoText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SwkbdMinCharacters, _inputMin);
-
- _checkLength = length => _inputMin <= length;
- }
- else
- {
- validationInfoText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SwkbdMinRangeCharacters, _inputMin, _inputMax);
-
- _checkLength = length => _inputMin <= length && length <= _inputMax;
- }
-
- ApplyValidationInfo(validationInfoText);
- Message_TextInput(this, new TextInputEventArgs());
- }
-
- private void SetInputValidation(KeyboardMode mode)
- {
- string validationInfoText = Error.Text;
- string localeText;
- switch (mode)
- {
- case KeyboardMode.Numeric:
- localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeNumeric);
- validationInfoText = string.IsNullOrEmpty(validationInfoText) ? localeText : string.Join("\n", validationInfoText, localeText);
- _checkInput = text => text.All(NumericCharacterValidation.IsNumeric);
- break;
- case KeyboardMode.Alphabet:
- localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeAlphabet);
- validationInfoText = string.IsNullOrEmpty(validationInfoText) ? localeText : string.Join("\n", validationInfoText, localeText);
- _checkInput = text => text.All(value => !CJKCharacterValidation.IsCJK(value));
- break;
- case KeyboardMode.ASCII:
- localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeASCII);
- validationInfoText = string.IsNullOrEmpty(validationInfoText) ? localeText : string.Join("\n", validationInfoText, localeText);
- _checkInput = text => text.All(char.IsAscii);
- break;
- default:
- _checkInput = _ => true;
- break;
- }
-
- ApplyValidationInfo(validationInfoText);
- Message_TextInput(this, new TextInputEventArgs());
- }
-
- private void Message_TextInput(object sender, TextInputEventArgs e)
- {
- if (_host != null)
- {
- _host.IsPrimaryButtonEnabled = _checkLength(Message.Length) && _checkInput(Message);
- }
- }
-
- private void Message_KeyUp(object sender, KeyEventArgs e)
- {
- if (e.Key == Key.Enter && _host.IsPrimaryButtonEnabled)
- {
- _host.Hide(ContentDialogResult.Primary);
- }
- else
- {
- _host.IsPrimaryButtonEnabled = _checkLength(Message.Length) && _checkInput(Message);
- }
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml b/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml
deleted file mode 100644
index dd0926fc..00000000
--- a/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml
+++ /dev/null
@@ -1,95 +0,0 @@
-<MenuFlyout
- x:Class="Ryujinx.Ava.UI.Controls.ApplicationContextMenu"
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- x:DataType="viewModels:MainWindowViewModel">
- <MenuItem
- Click="RunApplication_Click"
- Header="{locale:Locale GameListContextMenuRunApplication}" />
- <MenuItem
- Click="ToggleFavorite_Click"
- Header="{locale:Locale GameListContextMenuToggleFavorite}"
- ToolTip.Tip="{locale:Locale GameListContextMenuToggleFavoriteToolTip}" />
- <MenuItem
- Click="CreateApplicationShortcut_Click"
- Header="{locale:Locale GameListContextMenuCreateShortcut}"
- IsEnabled="{Binding CreateShortcutEnabled}"
- ToolTip.Tip="{OnPlatform Default={locale:Locale GameListContextMenuCreateShortcutToolTip}, macOS={locale:Locale GameListContextMenuCreateShortcutToolTipMacOS}}" />
- <Separator />
- <MenuItem
- Click="OpenUserSaveDirectory_Click"
- Header="{locale:Locale GameListContextMenuOpenUserSaveDirectory}"
- IsEnabled="{Binding OpenUserSaveDirectoryEnabled}"
- ToolTip.Tip="{locale:Locale GameListContextMenuOpenUserSaveDirectoryToolTip}" />
- <MenuItem
- Click="OpenDeviceSaveDirectory_Click"
- Header="{locale:Locale GameListContextMenuOpenDeviceSaveDirectory}"
- IsEnabled="{Binding OpenDeviceSaveDirectoryEnabled}"
- ToolTip.Tip="{locale:Locale GameListContextMenuOpenDeviceSaveDirectoryToolTip}" />
- <MenuItem
- Click="OpenBcatSaveDirectory_Click"
- Header="{locale:Locale GameListContextMenuOpenBcatSaveDirectory}"
- IsEnabled="{Binding OpenBcatSaveDirectoryEnabled}"
- ToolTip.Tip="{locale:Locale GameListContextMenuOpenBcatSaveDirectoryToolTip}" />
- <Separator />
- <MenuItem
- Click="OpenTitleUpdateManager_Click"
- Header="{locale:Locale GameListContextMenuManageTitleUpdates}"
- ToolTip.Tip="{locale:Locale GameListContextMenuManageTitleUpdatesToolTip}" />
- <MenuItem
- Click="OpenDownloadableContentManager_Click"
- Header="{locale:Locale GameListContextMenuManageDlc}"
- ToolTip.Tip="{locale:Locale GameListContextMenuManageDlcToolTip}" />
- <MenuItem
- Click="OpenCheatManager_Click"
- Header="{locale:Locale GameListContextMenuManageCheat}"
- ToolTip.Tip="{locale:Locale GameListContextMenuManageCheatToolTip}" />
- <MenuItem
- Click="OpenModManager_Click"
- Header="{locale:Locale GameListContextMenuManageMod}"
- ToolTip.Tip="{locale:Locale GameListContextMenuManageModToolTip}" />
- <Separator />
- <MenuItem
- Click="OpenModsDirectory_Click"
- Header="{locale:Locale GameListContextMenuOpenModsDirectory}"
- ToolTip.Tip="{locale:Locale GameListContextMenuOpenModsDirectoryToolTip}" />
- <MenuItem
- Click="OpenSdModsDirectory_Click"
- Header="{locale:Locale GameListContextMenuOpenSdModsDirectory}"
- ToolTip.Tip="{locale:Locale GameListContextMenuOpenSdModsDirectoryToolTip}" />
- <Separator />
- <MenuItem Header="{locale:Locale GameListContextMenuCacheManagement}">
- <MenuItem
- Click="PurgePtcCache_Click"
- Header="{locale:Locale GameListContextMenuCacheManagementPurgePptc}"
- ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementPurgePptcToolTip}" />
- <MenuItem
- Click="PurgeShaderCache_Click"
- Header="{locale:Locale GameListContextMenuCacheManagementPurgeShaderCache}"
- ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementPurgeShaderCacheToolTip}" />
- <MenuItem
- Click="OpenPtcDirectory_Click"
- Header="{locale:Locale GameListContextMenuCacheManagementOpenPptcDirectory}"
- ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementOpenPptcDirectoryToolTip}" />
- <MenuItem
- Click="OpenShaderCacheDirectory_Click"
- Header="{locale:Locale GameListContextMenuCacheManagementOpenShaderCacheDirectory}"
- ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip}" />
- </MenuItem>
- <MenuItem Header="{locale:Locale GameListContextMenuExtractData}">
- <MenuItem
- Click="ExtractApplicationExeFs_Click"
- Header="{locale:Locale GameListContextMenuExtractDataExeFS}"
- ToolTip.Tip="{locale:Locale GameListContextMenuExtractDataExeFSToolTip}" />
- <MenuItem
- Click="ExtractApplicationRomFs_Click"
- Header="{locale:Locale GameListContextMenuExtractDataRomFS}"
- ToolTip.Tip="{locale:Locale GameListContextMenuExtractDataRomFSToolTip}" />
- <MenuItem
- Click="ExtractApplicationLogo_Click"
- Header="{locale:Locale GameListContextMenuExtractDataLogo}"
- ToolTip.Tip="{locale:Locale GameListContextMenuExtractDataLogoToolTip}" />
- </MenuItem>
-</MenuFlyout>
diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs b/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs
deleted file mode 100644
index 894ac6c1..00000000
--- a/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs
+++ /dev/null
@@ -1,371 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Interactivity;
-using Avalonia.Markup.Xaml;
-using Avalonia.Threading;
-using LibHac.Fs;
-using LibHac.Tools.FsSystem.NcaUtils;
-using Ryujinx.Ava.Common;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.Ava.UI.Windows;
-using Ryujinx.Common.Configuration;
-using Ryujinx.HLE.HOS;
-using Ryujinx.UI.App.Common;
-using Ryujinx.UI.Common.Helper;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using Path = System.IO.Path;
-
-namespace Ryujinx.Ava.UI.Controls
-{
- public class ApplicationContextMenu : MenuFlyout
- {
- public ApplicationContextMenu()
- {
- InitializeComponent();
- }
-
- private void InitializeComponent()
- {
- AvaloniaXamlLoader.Load(this);
- }
-
- public void ToggleFavorite_Click(object sender, RoutedEventArgs args)
- {
- var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
-
- if (viewModel?.SelectedApplication != null)
- {
- viewModel.SelectedApplication.Favorite = !viewModel.SelectedApplication.Favorite;
-
- ApplicationLibrary.LoadAndSaveMetaData(viewModel.SelectedApplication.TitleId, appMetadata =>
- {
- appMetadata.Favorite = viewModel.SelectedApplication.Favorite;
- });
-
- viewModel.RefreshView();
- }
- }
-
- public void OpenUserSaveDirectory_Click(object sender, RoutedEventArgs args)
- {
- if (sender is MenuItem { DataContext: MainWindowViewModel viewModel })
- {
- OpenSaveDirectory(viewModel, SaveDataType.Account, new UserId((ulong)viewModel.AccountManager.LastOpenedUser.UserId.High, (ulong)viewModel.AccountManager.LastOpenedUser.UserId.Low));
- }
- }
-
- public void OpenDeviceSaveDirectory_Click(object sender, RoutedEventArgs args)
- {
- var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
-
- OpenSaveDirectory(viewModel, SaveDataType.Device, default);
- }
-
- public void OpenBcatSaveDirectory_Click(object sender, RoutedEventArgs args)
- {
- var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
-
- OpenSaveDirectory(viewModel, SaveDataType.Bcat, default);
- }
-
- private static void OpenSaveDirectory(MainWindowViewModel viewModel, SaveDataType saveDataType, UserId userId)
- {
- if (viewModel?.SelectedApplication != null)
- {
- if (!ulong.TryParse(viewModel.SelectedApplication.TitleId, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out ulong titleIdNumber))
- {
- Dispatcher.UIThread.InvokeAsync(async () =>
- {
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogRyujinxErrorMessage], LocaleManager.Instance[LocaleKeys.DialogInvalidTitleIdErrorMessage]);
- });
-
- return;
- }
-
- var saveDataFilter = SaveDataFilter.Make(titleIdNumber, saveDataType, userId, saveDataId: default, index: default);
-
- ApplicationHelper.OpenSaveDir(in saveDataFilter, titleIdNumber, viewModel.SelectedApplication.ControlHolder, viewModel.SelectedApplication.TitleName);
- }
- }
-
- public async void OpenTitleUpdateManager_Click(object sender, RoutedEventArgs args)
- {
- var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
-
- if (viewModel?.SelectedApplication != null)
- {
- await TitleUpdateWindow.Show(viewModel.VirtualFileSystem, ulong.Parse(viewModel.SelectedApplication.TitleId, NumberStyles.HexNumber), viewModel.SelectedApplication.TitleName);
- }
- }
-
- public async void OpenDownloadableContentManager_Click(object sender, RoutedEventArgs args)
- {
- var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
-
- if (viewModel?.SelectedApplication != null)
- {
- await DownloadableContentManagerWindow.Show(viewModel.VirtualFileSystem, ulong.Parse(viewModel.SelectedApplication.TitleId, NumberStyles.HexNumber), viewModel.SelectedApplication.TitleName);
- }
- }
-
- public async void OpenCheatManager_Click(object sender, RoutedEventArgs args)
- {
- var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
-
- if (viewModel?.SelectedApplication != null)
- {
- await new CheatWindow(
- viewModel.VirtualFileSystem,
- viewModel.SelectedApplication.TitleId,
- viewModel.SelectedApplication.TitleName,
- viewModel.SelectedApplication.Path).ShowDialog(viewModel.TopLevel as Window);
- }
- }
-
- public void OpenModsDirectory_Click(object sender, RoutedEventArgs args)
- {
- var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
-
- if (viewModel?.SelectedApplication != null)
- {
- string modsBasePath = ModLoader.GetModsBasePath();
- string titleModsPath = ModLoader.GetApplicationDir(modsBasePath, viewModel.SelectedApplication.TitleId);
-
- OpenHelper.OpenFolder(titleModsPath);
- }
- }
-
- public void OpenSdModsDirectory_Click(object sender, RoutedEventArgs args)
- {
- var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
-
- if (viewModel?.SelectedApplication != null)
- {
- string sdModsBasePath = ModLoader.GetSdModsBasePath();
- string titleModsPath = ModLoader.GetApplicationDir(sdModsBasePath, viewModel.SelectedApplication.TitleId);
-
- OpenHelper.OpenFolder(titleModsPath);
- }
- }
-
- public async void OpenModManager_Click(object sender, RoutedEventArgs args)
- {
- var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
-
- if (viewModel?.SelectedApplication != null)
- {
- await ModManagerWindow.Show(ulong.Parse(viewModel.SelectedApplication.TitleId, NumberStyles.HexNumber), viewModel.SelectedApplication.TitleName);
- }
- }
-
- public async void PurgePtcCache_Click(object sender, RoutedEventArgs args)
- {
- var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
-
- if (viewModel?.SelectedApplication != null)
- {
- UserResult result = await ContentDialogHelper.CreateConfirmationDialog(
- LocaleManager.Instance[LocaleKeys.DialogWarning],
- LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCDeletionMessage, viewModel.SelectedApplication.TitleName),
- LocaleManager.Instance[LocaleKeys.InputDialogYes],
- LocaleManager.Instance[LocaleKeys.InputDialogNo],
- LocaleManager.Instance[LocaleKeys.RyujinxConfirm]);
-
- if (result == UserResult.Yes)
- {
- DirectoryInfo mainDir = new(Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.TitleId, "cache", "cpu", "0"));
- DirectoryInfo backupDir = new(Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.TitleId, "cache", "cpu", "1"));
-
- List<FileInfo> cacheFiles = new();
-
- if (mainDir.Exists)
- {
- cacheFiles.AddRange(mainDir.EnumerateFiles("*.cache"));
- }
-
- if (backupDir.Exists)
- {
- cacheFiles.AddRange(backupDir.EnumerateFiles("*.cache"));
- }
-
- if (cacheFiles.Count > 0)
- {
- foreach (FileInfo file in cacheFiles)
- {
- try
- {
- file.Delete();
- }
- catch (Exception ex)
- {
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCDeletionErrorMessage, file.Name, ex));
- }
- }
- }
- }
- }
- }
-
- public async void PurgeShaderCache_Click(object sender, RoutedEventArgs args)
- {
- var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
-
- if (viewModel?.SelectedApplication != null)
- {
- UserResult result = await ContentDialogHelper.CreateConfirmationDialog(
- LocaleManager.Instance[LocaleKeys.DialogWarning],
- LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogShaderDeletionMessage, viewModel.SelectedApplication.TitleName),
- LocaleManager.Instance[LocaleKeys.InputDialogYes],
- LocaleManager.Instance[LocaleKeys.InputDialogNo],
- LocaleManager.Instance[LocaleKeys.RyujinxConfirm]);
-
- if (result == UserResult.Yes)
- {
- DirectoryInfo shaderCacheDir = new(Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.TitleId, "cache", "shader"));
-
- List<DirectoryInfo> oldCacheDirectories = new();
- List<FileInfo> newCacheFiles = new();
-
- if (shaderCacheDir.Exists)
- {
- oldCacheDirectories.AddRange(shaderCacheDir.EnumerateDirectories("*"));
- newCacheFiles.AddRange(shaderCacheDir.GetFiles("*.toc"));
- newCacheFiles.AddRange(shaderCacheDir.GetFiles("*.data"));
- }
-
- if ((oldCacheDirectories.Count > 0 || newCacheFiles.Count > 0))
- {
- foreach (DirectoryInfo directory in oldCacheDirectories)
- {
- try
- {
- directory.Delete(true);
- }
- catch (Exception ex)
- {
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCDeletionErrorMessage, directory.Name, ex));
- }
- }
-
- foreach (FileInfo file in newCacheFiles)
- {
- try
- {
- file.Delete();
- }
- catch (Exception ex)
- {
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.ShaderCachePurgeError, file.Name, ex));
- }
- }
- }
- }
- }
- }
-
- public void OpenPtcDirectory_Click(object sender, RoutedEventArgs args)
- {
- var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
-
- if (viewModel?.SelectedApplication != null)
- {
- string ptcDir = Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.TitleId, "cache", "cpu");
- string mainDir = Path.Combine(ptcDir, "0");
- string backupDir = Path.Combine(ptcDir, "1");
-
- if (!Directory.Exists(ptcDir))
- {
- Directory.CreateDirectory(ptcDir);
- Directory.CreateDirectory(mainDir);
- Directory.CreateDirectory(backupDir);
- }
-
- OpenHelper.OpenFolder(ptcDir);
- }
- }
-
- public void OpenShaderCacheDirectory_Click(object sender, RoutedEventArgs args)
- {
- var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
-
- if (viewModel?.SelectedApplication != null)
- {
- string shaderCacheDir = Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.TitleId, "cache", "shader");
-
- if (!Directory.Exists(shaderCacheDir))
- {
- Directory.CreateDirectory(shaderCacheDir);
- }
-
- OpenHelper.OpenFolder(shaderCacheDir);
- }
- }
-
- public async void ExtractApplicationExeFs_Click(object sender, RoutedEventArgs args)
- {
- var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
-
- if (viewModel?.SelectedApplication != null)
- {
- await ApplicationHelper.ExtractSection(
- viewModel.StorageProvider,
- NcaSectionType.Code,
- viewModel.SelectedApplication.Path,
- viewModel.SelectedApplication.TitleName);
- }
- }
-
- public async void ExtractApplicationRomFs_Click(object sender, RoutedEventArgs args)
- {
- var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
-
- if (viewModel?.SelectedApplication != null)
- {
- await ApplicationHelper.ExtractSection(
- viewModel.StorageProvider,
- NcaSectionType.Data,
- viewModel.SelectedApplication.Path,
- viewModel.SelectedApplication.TitleName);
- }
- }
-
- public async void ExtractApplicationLogo_Click(object sender, RoutedEventArgs args)
- {
- var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
-
- if (viewModel?.SelectedApplication != null)
- {
- await ApplicationHelper.ExtractSection(
- viewModel.StorageProvider,
- NcaSectionType.Logo,
- viewModel.SelectedApplication.Path,
- viewModel.SelectedApplication.TitleName);
- }
- }
-
- public void CreateApplicationShortcut_Click(object sender, RoutedEventArgs args)
- {
- var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
-
- if (viewModel?.SelectedApplication != null)
- {
- ApplicationData selectedApplication = viewModel.SelectedApplication;
- ShortcutHelper.CreateAppShortcut(selectedApplication.Path, selectedApplication.TitleName, selectedApplication.TitleId, selectedApplication.Icon);
- }
- }
-
- public async void RunApplication_Click(object sender, RoutedEventArgs args)
- {
- var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
-
- if (viewModel?.SelectedApplication != null)
- {
- await viewModel.LoadApplication(viewModel.SelectedApplication.Path);
- }
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml b/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml
deleted file mode 100644
index 2dc95662..00000000
--- a/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml
+++ /dev/null
@@ -1,102 +0,0 @@
-<UserControl
- x:Class="Ryujinx.Ava.UI.Controls.ApplicationGridView"
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
- d:DesignHeight="450"
- d:DesignWidth="800"
- Focusable="True"
- mc:Ignorable="d"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- x:DataType="viewModels:MainWindowViewModel">
- <UserControl.Resources>
- <helpers:BitmapArrayValueConverter x:Key="ByteImage" />
- <controls:ApplicationContextMenu x:Key="ApplicationContextMenu" />
- </UserControl.Resources>
- <Grid>
- <Grid.RowDefinitions>
- <RowDefinition Height="*" />
- </Grid.RowDefinitions>
- <ListBox
- Grid.Row="0"
- Padding="8"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- ContextFlyout="{StaticResource ApplicationContextMenu}"
- DoubleTapped="GameList_DoubleTapped"
- ItemsSource="{Binding AppsObservableList}"
- SelectionChanged="GameList_SelectionChanged">
- <ListBox.ItemsPanel>
- <ItemsPanelTemplate>
- <WrapPanel
- HorizontalAlignment="Center"
- VerticalAlignment="Top"
- Orientation="Horizontal" />
- </ItemsPanelTemplate>
- </ListBox.ItemsPanel>
- <ListBox.Styles>
- <Style Selector="ListBoxItem">
- <Setter Property="Margin" Value="5" />
- <Setter Property="CornerRadius" Value="4" />
- </Style>
- <Style Selector="ListBoxItem:selected /template/ Rectangle#SelectionIndicator">
- <Setter Property="MinHeight" Value="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).GridItemSelectorSize}" />
- </Style>
- </ListBox.Styles>
- <ListBox.ItemTemplate>
- <DataTemplate>
- <Grid>
- <Border
- Margin="10"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- Classes.huge="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridHuge}"
- Classes.large="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridLarge}"
- Classes.normal="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridMedium}"
- Classes.small="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridSmall}"
- ClipToBounds="True"
- CornerRadius="4">
- <Grid>
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <Image
- Grid.Row="0"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Top"
- Source="{Binding Icon, Converter={StaticResource ByteImage}}" />
- <Panel
- Grid.Row="1"
- Height="50"
- Margin="0,10,0,0"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- IsVisible="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).ShowNames}">
- <TextBlock
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{Binding TitleName}"
- TextAlignment="Center"
- TextWrapping="Wrap" />
- </Panel>
- </Grid>
- </Border>
- <ui:SymbolIcon
- Margin="5,5,0,0"
- HorizontalAlignment="Left"
- VerticalAlignment="Top"
- FontSize="16"
- Foreground="{DynamicResource SystemAccentColor}"
- IsVisible="{Binding Favorite}"
- Symbol="StarFilled" />
- </Grid>
- </DataTemplate>
- </ListBox.ItemTemplate>
- </ListBox>
- </Grid>
-</UserControl>
diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs b/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs
deleted file mode 100644
index ee15bc8d..00000000
--- a/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Input;
-using Avalonia.Interactivity;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.UI.App.Common;
-using System;
-
-namespace Ryujinx.Ava.UI.Controls
-{
- public partial class ApplicationGridView : UserControl
- {
- public static readonly RoutedEvent<ApplicationOpenedEventArgs> ApplicationOpenedEvent =
- RoutedEvent.Register<ApplicationGridView, ApplicationOpenedEventArgs>(nameof(ApplicationOpened), RoutingStrategies.Bubble);
-
- public event EventHandler<ApplicationOpenedEventArgs> ApplicationOpened
- {
- add { AddHandler(ApplicationOpenedEvent, value); }
- remove { RemoveHandler(ApplicationOpenedEvent, value); }
- }
-
- public ApplicationGridView()
- {
- InitializeComponent();
- }
-
- public void GameList_DoubleTapped(object sender, TappedEventArgs args)
- {
- if (sender is ListBox listBox)
- {
- if (listBox.SelectedItem is ApplicationData selected)
- {
- RaiseEvent(new ApplicationOpenedEventArgs(selected, ApplicationOpenedEvent));
- }
- }
- }
-
- public void GameList_SelectionChanged(object sender, SelectionChangedEventArgs args)
- {
- if (sender is ListBox listBox)
- {
- (DataContext as MainWindowViewModel).GridSelectedApplication = listBox.SelectedItem as ApplicationData;
- }
- }
-
- private void SearchBox_OnKeyUp(object sender, KeyEventArgs args)
- {
- (DataContext as MainWindowViewModel).SearchText = (sender as TextBox).Text;
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml b/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml
deleted file mode 100644
index fecf0888..00000000
--- a/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml
+++ /dev/null
@@ -1,160 +0,0 @@
-<UserControl
- x:Class="Ryujinx.Ava.UI.Controls.ApplicationListView"
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
- d:DesignHeight="450"
- d:DesignWidth="800"
- Focusable="True"
- mc:Ignorable="d"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- x:DataType="viewModels:MainWindowViewModel">
- <UserControl.Resources>
- <helpers:BitmapArrayValueConverter x:Key="ByteImage" />
- <controls:ApplicationContextMenu x:Key="ApplicationContextMenu" />
- </UserControl.Resources>
- <Grid>
- <Grid.RowDefinitions>
- <RowDefinition Height="*" />
- </Grid.RowDefinitions>
- <ListBox
- Name="GameListBox"
- Grid.Row="0"
- Padding="8"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- ContextFlyout="{StaticResource ApplicationContextMenu}"
- DoubleTapped="GameList_DoubleTapped"
- ItemsSource="{Binding AppsObservableList}"
- SelectionChanged="GameList_SelectionChanged">
- <ListBox.ItemsPanel>
- <ItemsPanelTemplate>
- <StackPanel
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- Orientation="Vertical"
- Spacing="2" />
- </ItemsPanelTemplate>
- </ListBox.ItemsPanel>
- <ListBox.Styles>
- <Style Selector="ListBoxItem:selected /template/ Rectangle#SelectionIndicator">
- <Setter Property="MinHeight" Value="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).ListItemSelectorSize}" />
- </Style>
- </ListBox.Styles>
- <ListBox.ItemTemplate>
- <DataTemplate>
- <Grid>
- <Border
- Margin="0"
- Padding="10"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- ClipToBounds="True"
- CornerRadius="5">
- <Grid>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="10" />
- <ColumnDefinition Width="*" />
- <ColumnDefinition Width="150" />
- <ColumnDefinition Width="100" />
- </Grid.ColumnDefinitions>
- <Image
- Grid.RowSpan="3"
- Grid.Column="0"
- Margin="0"
- Classes.huge="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridHuge}"
- Classes.large="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridLarge}"
- Classes.normal="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridMedium}"
- Classes.small="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridSmall}"
- Source="{Binding Icon, Converter={StaticResource ByteImage}}" />
- <Border
- Grid.Column="2"
- Margin="0,0,5,0"
- BorderBrush="{DynamicResource ThemeControlBorderColor}"
- BorderThickness="0,0,1,0">
- <StackPanel
- HorizontalAlignment="Left"
- VerticalAlignment="Top"
- Orientation="Vertical"
- Spacing="5">
- <TextBlock
- HorizontalAlignment="Stretch"
- FontWeight="Bold"
- Text="{Binding TitleName}"
- TextAlignment="Start"
- TextWrapping="Wrap" />
- <TextBlock
- HorizontalAlignment="Stretch"
- Text="{Binding Developer}"
- TextAlignment="Start"
- TextWrapping="Wrap" />
- <TextBlock
- HorizontalAlignment="Stretch"
- Text="{Binding Version}"
- TextAlignment="Start"
- TextWrapping="Wrap" />
- </StackPanel>
- </Border>
- <StackPanel
- Grid.Column="3"
- Margin="10,0,0,0"
- HorizontalAlignment="Left"
- VerticalAlignment="Top"
- Orientation="Vertical"
- Spacing="5">
- <TextBlock
- HorizontalAlignment="Stretch"
- Text="{Binding TitleId}"
- TextAlignment="Start"
- TextWrapping="Wrap" />
- <TextBlock
- HorizontalAlignment="Stretch"
- Text="{Binding FileExtension}"
- TextAlignment="Start"
- TextWrapping="Wrap" />
- </StackPanel>
- <StackPanel
- Grid.Column="4"
- HorizontalAlignment="Right"
- VerticalAlignment="Top"
- Orientation="Vertical"
- Spacing="5">
- <TextBlock
- HorizontalAlignment="Stretch"
- Text="{Binding TimePlayedString}"
- TextAlignment="End"
- TextWrapping="Wrap" />
- <TextBlock
- HorizontalAlignment="Stretch"
- Text="{Binding LastPlayedString, Converter={helpers:LocalizedNeverConverter}}"
- TextAlignment="End"
- TextWrapping="Wrap" />
- <TextBlock
- HorizontalAlignment="Stretch"
- Text="{Binding FileSizeString}"
- TextAlignment="End"
- TextWrapping="Wrap" />
- </StackPanel>
- <ui:SymbolIcon
- Grid.Row="0"
- Grid.Column="0"
- Margin="-5,-5,0,0"
- HorizontalAlignment="Left"
- VerticalAlignment="Top"
- FontSize="16"
- Foreground="{DynamicResource SystemAccentColor}"
- IsVisible="{Binding Favorite}"
- Symbol="StarFilled" />
- </Grid>
- </Border>
- </Grid>
- </DataTemplate>
- </ListBox.ItemTemplate>
- </ListBox>
- </Grid>
-</UserControl>
diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs b/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs
deleted file mode 100644
index 8681158f..00000000
--- a/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Input;
-using Avalonia.Interactivity;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.UI.App.Common;
-using System;
-
-namespace Ryujinx.Ava.UI.Controls
-{
- public partial class ApplicationListView : UserControl
- {
- public static readonly RoutedEvent<ApplicationOpenedEventArgs> ApplicationOpenedEvent =
- RoutedEvent.Register<ApplicationListView, ApplicationOpenedEventArgs>(nameof(ApplicationOpened), RoutingStrategies.Bubble);
-
- public event EventHandler<ApplicationOpenedEventArgs> ApplicationOpened
- {
- add { AddHandler(ApplicationOpenedEvent, value); }
- remove { RemoveHandler(ApplicationOpenedEvent, value); }
- }
-
- public ApplicationListView()
- {
- InitializeComponent();
- }
-
- public void GameList_DoubleTapped(object sender, TappedEventArgs args)
- {
- if (sender is ListBox listBox)
- {
- if (listBox.SelectedItem is ApplicationData selected)
- {
- RaiseEvent(new ApplicationOpenedEventArgs(selected, ApplicationOpenedEvent));
- }
- }
- }
-
- public void GameList_SelectionChanged(object sender, SelectionChangedEventArgs args)
- {
- if (sender is ListBox listBox)
- {
- (DataContext as MainWindowViewModel).ListSelectedApplication = listBox.SelectedItem as ApplicationData;
- }
- }
-
- private void SearchBox_OnKeyUp(object sender, KeyEventArgs args)
- {
- (DataContext as MainWindowViewModel).SearchText = (sender as TextBox).Text;
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml b/src/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml
deleted file mode 100644
index bf34b303..00000000
--- a/src/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml
+++ /dev/null
@@ -1,17 +0,0 @@
-<UserControl
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
- mc:Ignorable="d"
- d:DesignWidth="800"
- d:DesignHeight="450"
- x:Class="Ryujinx.Ava.UI.Controls.NavigationDialogHost"
- Focusable="True">
- <ui:Frame
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- x:Name="ContentFrame">
- </ui:Frame>
-</UserControl> \ No newline at end of file
diff --git a/src/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml.cs b/src/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml.cs
deleted file mode 100644
index a32c052b..00000000
--- a/src/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml.cs
+++ /dev/null
@@ -1,217 +0,0 @@
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Styling;
-using Avalonia.Threading;
-using FluentAvalonia.UI.Controls;
-using LibHac;
-using LibHac.Common;
-using LibHac.Fs;
-using LibHac.Fs.Shim;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.Ava.UI.Views.User;
-using Ryujinx.HLE.FileSystem;
-using Ryujinx.HLE.HOS.Services.Account.Acc;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using UserId = Ryujinx.HLE.HOS.Services.Account.Acc.UserId;
-using UserProfile = Ryujinx.Ava.UI.Models.UserProfile;
-
-namespace Ryujinx.Ava.UI.Controls
-{
- public partial class NavigationDialogHost : UserControl
- {
- public AccountManager AccountManager { get; }
- public ContentManager ContentManager { get; }
- public VirtualFileSystem VirtualFileSystem { get; }
- public HorizonClient HorizonClient { get; }
- public UserProfileViewModel ViewModel { get; set; }
-
- public NavigationDialogHost()
- {
- InitializeComponent();
- }
-
- public NavigationDialogHost(AccountManager accountManager, ContentManager contentManager,
- VirtualFileSystem virtualFileSystem, HorizonClient horizonClient)
- {
- AccountManager = accountManager;
- ContentManager = contentManager;
- VirtualFileSystem = virtualFileSystem;
- HorizonClient = horizonClient;
- ViewModel = new UserProfileViewModel();
- LoadProfiles();
-
- if (contentManager.GetCurrentFirmwareVersion() != null)
- {
- Task.Run(() =>
- {
- UserFirmwareAvatarSelectorViewModel.PreloadAvatars(contentManager, virtualFileSystem);
- });
- }
- InitializeComponent();
- }
-
- public void GoBack()
- {
- if (ContentFrame.BackStack.Count > 0)
- {
- ContentFrame.GoBack();
- }
-
- LoadProfiles();
- }
-
- public void Navigate(Type sourcePageType, object parameter)
- {
- ContentFrame.Navigate(sourcePageType, parameter);
- }
-
- public static async Task Show(AccountManager ownerAccountManager, ContentManager ownerContentManager,
- VirtualFileSystem ownerVirtualFileSystem, HorizonClient ownerHorizonClient)
- {
- var content = new NavigationDialogHost(ownerAccountManager, ownerContentManager, ownerVirtualFileSystem, ownerHorizonClient);
- ContentDialog contentDialog = new()
- {
- Title = LocaleManager.Instance[LocaleKeys.UserProfileWindowTitle],
- PrimaryButtonText = "",
- SecondaryButtonText = "",
- CloseButtonText = "",
- Content = content,
- Padding = new Thickness(0),
- };
-
- contentDialog.Closed += (sender, args) =>
- {
- content.ViewModel.Dispose();
- };
-
- Style footer = new(x => x.Name("DialogSpace").Child().OfType<Border>());
- footer.Setters.Add(new Setter(IsVisibleProperty, false));
-
- contentDialog.Styles.Add(footer);
-
- await contentDialog.ShowAsync();
- }
-
- protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
- {
- base.OnAttachedToVisualTree(e);
-
- Navigate(typeof(UserSelectorViews), this);
- }
-
- public void LoadProfiles()
- {
- ViewModel.Profiles.Clear();
- ViewModel.LostProfiles.Clear();
-
- var profiles = AccountManager.GetAllUsers().OrderBy(x => x.Name);
-
- foreach (var profile in profiles)
- {
- ViewModel.Profiles.Add(new UserProfile(profile, this));
- }
-
- var saveDataFilter = SaveDataFilter.Make(programId: default, saveType: SaveDataType.Account, default, saveDataId: default, index: default);
-
- using var saveDataIterator = new UniqueRef<SaveDataIterator>();
-
- HorizonClient.Fs.OpenSaveDataIterator(ref saveDataIterator.Ref, SaveDataSpaceId.User, in saveDataFilter).ThrowIfFailure();
-
- Span<SaveDataInfo> saveDataInfo = stackalloc SaveDataInfo[10];
-
- HashSet<UserId> lostAccounts = new();
-
- while (true)
- {
- saveDataIterator.Get.ReadSaveDataInfo(out long readCount, saveDataInfo).ThrowIfFailure();
-
- if (readCount == 0)
- {
- break;
- }
-
- for (int i = 0; i < readCount; i++)
- {
- var save = saveDataInfo[i];
- var id = new UserId((long)save.UserId.Id.Low, (long)save.UserId.Id.High);
- if (ViewModel.Profiles.Cast<UserProfile>().FirstOrDefault(x => x.UserId == id) == null)
- {
- lostAccounts.Add(id);
- }
- }
- }
-
- foreach (var account in lostAccounts)
- {
- ViewModel.LostProfiles.Add(new UserProfile(new HLE.HOS.Services.Account.Acc.UserProfile(account, "", null), this));
- }
-
- ViewModel.Profiles.Add(new BaseModel());
- }
-
- public async void DeleteUser(UserProfile userProfile)
- {
- var lastUserId = AccountManager.LastOpenedUser.UserId;
-
- if (userProfile.UserId == lastUserId)
- {
- // If we are deleting the currently open profile, then we must open something else before deleting.
- var profile = ViewModel.Profiles.Cast<UserProfile>().FirstOrDefault(x => x.UserId != lastUserId);
-
- if (profile == null)
- {
- static async void Action()
- {
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogUserProfileDeletionWarningMessage]);
- }
-
- Dispatcher.UIThread.Post(Action);
-
- return;
- }
-
- AccountManager.OpenUser(profile.UserId);
- }
-
- var result = await ContentDialogHelper.CreateConfirmationDialog(
- LocaleManager.Instance[LocaleKeys.DialogUserProfileDeletionConfirmMessage],
- "",
- LocaleManager.Instance[LocaleKeys.InputDialogYes],
- LocaleManager.Instance[LocaleKeys.InputDialogNo],
- "");
-
- if (result == UserResult.Yes)
- {
- GoBack();
- AccountManager.DeleteUser(userProfile.UserId);
- }
-
- LoadProfiles();
- }
-
- public void AddUser()
- {
- Navigate(typeof(UserEditorView), (this, (UserProfile)null, true));
- }
-
- public void EditUser(UserProfile userProfile)
- {
- Navigate(typeof(UserEditorView), (this, userProfile, false));
- }
-
- public void RecoverLostAccounts()
- {
- Navigate(typeof(UserRecovererView), this);
- }
-
- public void ManageSaves()
- {
- Navigate(typeof(UserSaveManagerView), (this, AccountManager, HorizonClient, VirtualFileSystem));
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Controls/SliderScroll.axaml.cs b/src/Ryujinx.Ava/UI/Controls/SliderScroll.axaml.cs
deleted file mode 100644
index b57c6f0a..00000000
--- a/src/Ryujinx.Ava/UI/Controls/SliderScroll.axaml.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Input;
-using System;
-
-namespace Ryujinx.Ava.UI.Controls
-{
- public class SliderScroll : Slider
- {
- protected override Type StyleKeyOverride => typeof(Slider);
-
- protected override void OnPointerWheelChanged(PointerWheelEventArgs e)
- {
- var newValue = Value + e.Delta.Y * TickFrequency;
-
- if (newValue < Minimum)
- {
- Value = Minimum;
- }
- else if (newValue > Maximum)
- {
- Value = Maximum;
- }
- else
- {
- Value = newValue;
- }
-
- e.Handled = true;
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml b/src/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml
deleted file mode 100644
index 09fa0404..00000000
--- a/src/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml
+++ /dev/null
@@ -1,42 +0,0 @@
-<Window
- x:Class="Ryujinx.Ava.UI.Controls.UpdateWaitWindow"
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- Title="Ryujinx - Waiting"
- SizeToContent="WidthAndHeight"
- WindowStartupLocation="CenterOwner"
- mc:Ignorable="d"
- Focusable="True">
- <Grid
- Margin="20"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition />
- </Grid.ColumnDefinitions>
- <Image
- Grid.Row="1"
- Height="70"
- MinWidth="50"
- Margin="5,10,20,10"
- Source="resm:Ryujinx.UI.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.UI.Common" />
- <StackPanel
- Grid.Row="1"
- Grid.Column="1"
- VerticalAlignment="Center"
- Orientation="Vertical">
- <TextBlock Name="PrimaryText" Margin="5" />
- <TextBlock
- Name="SecondaryText"
- Margin="5"
- VerticalAlignment="Center" />
- </StackPanel>
- </Grid>
-</Window>
diff --git a/src/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml.cs b/src/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml.cs
deleted file mode 100644
index 7ad1ee33..00000000
--- a/src/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using Avalonia.Controls;
-using Ryujinx.Ava.UI.Windows;
-using System.Threading;
-
-namespace Ryujinx.Ava.UI.Controls
-{
- public partial class UpdateWaitWindow : StyleableWindow
- {
- public UpdateWaitWindow(string primaryText, string secondaryText, CancellationTokenSource cancellationToken) : this(primaryText, secondaryText)
- {
- SystemDecorations = SystemDecorations.Full;
- ShowInTaskbar = true;
-
- Closing += (_, _) => cancellationToken.Cancel();
- }
-
- public UpdateWaitWindow(string primaryText, string secondaryText) : this()
- {
- PrimaryText.Text = primaryText;
- SecondaryText.Text = secondaryText;
- WindowStartupLocation = WindowStartupLocation.CenterOwner;
- SystemDecorations = SystemDecorations.BorderOnly;
- ShowInTaskbar = false;
- }
-
- public UpdateWaitWindow()
- {
- InitializeComponent();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Helpers/ApplicationOpenedEventArgs.cs b/src/Ryujinx.Ava/UI/Helpers/ApplicationOpenedEventArgs.cs
deleted file mode 100644
index bc5622b5..00000000
--- a/src/Ryujinx.Ava/UI/Helpers/ApplicationOpenedEventArgs.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using Avalonia.Interactivity;
-using Ryujinx.UI.App.Common;
-
-namespace Ryujinx.Ava.UI.Helpers
-{
- public class ApplicationOpenedEventArgs : RoutedEventArgs
- {
- public ApplicationData Application { get; }
-
- public ApplicationOpenedEventArgs(ApplicationData application, RoutedEvent routedEvent)
- {
- Application = application;
- RoutedEvent = routedEvent;
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Helpers/BitmapArrayValueConverter.cs b/src/Ryujinx.Ava/UI/Helpers/BitmapArrayValueConverter.cs
deleted file mode 100644
index 42bd8d5a..00000000
--- a/src/Ryujinx.Ava/UI/Helpers/BitmapArrayValueConverter.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using Avalonia.Data.Converters;
-using Avalonia.Media;
-using Avalonia.Media.Imaging;
-using System;
-using System.Globalization;
-using System.IO;
-
-namespace Ryujinx.Ava.UI.Helpers
-{
- internal class BitmapArrayValueConverter : IValueConverter
- {
- public static BitmapArrayValueConverter Instance = new();
-
- public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
- {
- if (value == null)
- {
- return null;
- }
-
- if (value is byte[] buffer && targetType == typeof(IImage))
- {
- MemoryStream mem = new(buffer);
-
- return new Bitmap(mem);
- }
-
- throw new NotSupportedException();
- }
-
- public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
- {
- throw new NotSupportedException();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Helpers/ButtonKeyAssigner.cs b/src/Ryujinx.Ava/UI/Helpers/ButtonKeyAssigner.cs
deleted file mode 100644
index 7e8ba734..00000000
--- a/src/Ryujinx.Ava/UI/Helpers/ButtonKeyAssigner.cs
+++ /dev/null
@@ -1,118 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Controls.Primitives;
-using Avalonia.LogicalTree;
-using Avalonia.Threading;
-using Ryujinx.Input;
-using Ryujinx.Input.Assigner;
-using System;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace Ryujinx.Ava.UI.Helpers
-{
- internal class ButtonKeyAssigner
- {
- internal class ButtonAssignedEventArgs : EventArgs
- {
- public ToggleButton Button { get; }
- public bool IsAssigned { get; }
-
- public ButtonAssignedEventArgs(ToggleButton button, bool isAssigned)
- {
- Button = button;
- IsAssigned = isAssigned;
- }
- }
-
- public ToggleButton ToggledButton { get; set; }
-
- private bool _isWaitingForInput;
- private bool _shouldUnbind;
- public event EventHandler<ButtonAssignedEventArgs> ButtonAssigned;
-
- public ButtonKeyAssigner(ToggleButton toggleButton)
- {
- ToggledButton = toggleButton;
- }
-
- public async void GetInputAndAssign(IButtonAssigner assigner, IKeyboard keyboard = null)
- {
- Dispatcher.UIThread.Post(() =>
- {
- ToggledButton.IsChecked = true;
- });
-
- if (_isWaitingForInput)
- {
- Dispatcher.UIThread.Post(() =>
- {
- Cancel();
- });
-
- return;
- }
-
- _isWaitingForInput = true;
-
- assigner.Initialize();
-
- await Task.Run(async () =>
- {
- while (true)
- {
- if (!_isWaitingForInput)
- {
- return;
- }
-
- await Task.Delay(10);
-
- assigner.ReadInput();
-
- if (assigner.HasAnyButtonPressed() || assigner.ShouldCancel() || (keyboard != null && keyboard.IsPressed(Key.Escape)))
- {
- break;
- }
- }
- });
-
- await Dispatcher.UIThread.InvokeAsync(() =>
- {
- string pressedButton = assigner.GetPressedButton();
-
- if (_shouldUnbind)
- {
- SetButtonText(ToggledButton, "Unbound");
- }
- else if (pressedButton != "")
- {
- SetButtonText(ToggledButton, pressedButton);
- }
-
- _shouldUnbind = false;
- _isWaitingForInput = false;
-
- ToggledButton.IsChecked = false;
-
- ButtonAssigned?.Invoke(this, new ButtonAssignedEventArgs(ToggledButton, pressedButton != null));
-
- static void SetButtonText(ToggleButton button, string text)
- {
- ILogical textBlock = button.GetLogicalDescendants().First(x => x is TextBlock);
-
- if (textBlock != null && textBlock is TextBlock block)
- {
- block.Text = text;
- }
- }
- });
- }
-
- public void Cancel(bool shouldUnbind = false)
- {
- _isWaitingForInput = false;
- ToggledButton.IsChecked = false;
- _shouldUnbind = shouldUnbind;
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Helpers/ContentDialogHelper.cs b/src/Ryujinx.Ava/UI/Helpers/ContentDialogHelper.cs
deleted file mode 100644
index 15b7ddd1..00000000
--- a/src/Ryujinx.Ava/UI/Helpers/ContentDialogHelper.cs
+++ /dev/null
@@ -1,425 +0,0 @@
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Controls.ApplicationLifetimes;
-using Avalonia.Layout;
-using Avalonia.Media;
-using Avalonia.Threading;
-using FluentAvalonia.Core;
-using FluentAvalonia.UI.Controls;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Windows;
-using Ryujinx.Common.Logging;
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Ryujinx.Ava.UI.Helpers
-{
- public static class ContentDialogHelper
- {
- private static bool _isChoiceDialogOpen;
- private static ContentDialogOverlayWindow _contentDialogOverlayWindow;
-
- private async static Task<UserResult> ShowContentDialog(
- string title,
- object content,
- string primaryButton,
- string secondaryButton,
- string closeButton,
- UserResult primaryButtonResult = UserResult.Ok,
- ManualResetEvent deferResetEvent = null,
- TypedEventHandler<ContentDialog, ContentDialogButtonClickEventArgs> deferCloseAction = null)
- {
- UserResult result = UserResult.None;
-
- ContentDialog contentDialog = new()
- {
- Title = title,
- PrimaryButtonText = primaryButton,
- SecondaryButtonText = secondaryButton,
- CloseButtonText = closeButton,
- Content = content,
- PrimaryButtonCommand = MiniCommand.Create(() =>
- {
- result = primaryButtonResult;
- }),
- };
-
- contentDialog.SecondaryButtonCommand = MiniCommand.Create(() =>
- {
- result = UserResult.No;
- contentDialog.PrimaryButtonClick -= deferCloseAction;
- });
-
- contentDialog.CloseButtonCommand = MiniCommand.Create(() =>
- {
- result = UserResult.Cancel;
- contentDialog.PrimaryButtonClick -= deferCloseAction;
- });
-
- if (deferResetEvent != null)
- {
- contentDialog.PrimaryButtonClick += deferCloseAction;
- }
-
- await ShowAsync(contentDialog);
-
- return result;
- }
-
- public async static Task<UserResult> ShowTextDialog(
- string title,
- string primaryText,
- string secondaryText,
- string primaryButton,
- string secondaryButton,
- string closeButton,
- int iconSymbol,
- UserResult primaryButtonResult = UserResult.Ok,
- ManualResetEvent deferResetEvent = null,
- TypedEventHandler<ContentDialog, ContentDialogButtonClickEventArgs> deferCloseAction = null)
- {
- Grid content = CreateTextDialogContent(primaryText, secondaryText, iconSymbol);
-
- return await ShowContentDialog(title, content, primaryButton, secondaryButton, closeButton, primaryButtonResult, deferResetEvent, deferCloseAction);
- }
-
- public async static Task<UserResult> ShowDeferredContentDialog(
- StyleableWindow window,
- string title,
- string primaryText,
- string secondaryText,
- string primaryButton,
- string secondaryButton,
- string closeButton,
- int iconSymbol,
- ManualResetEvent deferResetEvent,
- Func<Window, Task> doWhileDeferred = null)
- {
- bool startedDeferring = false;
-
- return await ShowTextDialog(
- title,
- primaryText,
- secondaryText,
- primaryButton,
- secondaryButton,
- closeButton,
- iconSymbol,
- primaryButton == LocaleManager.Instance[LocaleKeys.InputDialogYes] ? UserResult.Yes : UserResult.Ok,
- deferResetEvent,
- DeferClose);
-
- async void DeferClose(ContentDialog sender, ContentDialogButtonClickEventArgs args)
- {
- if (startedDeferring)
- {
- return;
- }
-
- sender.PrimaryButtonClick -= DeferClose;
-
- startedDeferring = true;
-
- var deferral = args.GetDeferral();
-
- sender.PrimaryButtonClick -= DeferClose;
-
- _ = Task.Run(() =>
- {
- deferResetEvent.WaitOne();
-
- Dispatcher.UIThread.Post(() =>
- {
- deferral.Complete();
- });
- });
-
- if (doWhileDeferred != null)
- {
- await doWhileDeferred(window);
-
- deferResetEvent.Set();
- }
- }
- }
-
- private static Grid CreateTextDialogContent(string primaryText, string secondaryText, int symbol)
- {
- Grid content = new()
- {
- RowDefinitions = new RowDefinitions { new(), new() },
- ColumnDefinitions = new ColumnDefinitions { new(GridLength.Auto), new() },
-
- MinHeight = 80,
- };
-
- SymbolIcon icon = new()
- {
- Symbol = (Symbol)symbol,
- Margin = new Thickness(10),
- FontSize = 40,
- VerticalAlignment = VerticalAlignment.Center,
- };
-
- Grid.SetColumn(icon, 0);
- Grid.SetRowSpan(icon, 2);
- Grid.SetRow(icon, 0);
-
- TextBlock primaryLabel = new()
- {
- Text = primaryText,
- Margin = new Thickness(5),
- TextWrapping = TextWrapping.Wrap,
- MaxWidth = 450,
- };
-
- TextBlock secondaryLabel = new()
- {
- Text = secondaryText,
- Margin = new Thickness(5),
- TextWrapping = TextWrapping.Wrap,
- MaxWidth = 450,
- };
-
- Grid.SetColumn(primaryLabel, 1);
- Grid.SetColumn(secondaryLabel, 1);
- Grid.SetRow(primaryLabel, 0);
- Grid.SetRow(secondaryLabel, 1);
-
- content.Children.Add(icon);
- content.Children.Add(primaryLabel);
- content.Children.Add(secondaryLabel);
-
- return content;
- }
-
- public static async Task<UserResult> CreateInfoDialog(
- string primary,
- string secondaryText,
- string acceptButton,
- string closeButton,
- string title)
- {
- return await ShowTextDialog(
- title,
- primary,
- secondaryText,
- acceptButton,
- "",
- closeButton,
- (int)Symbol.Important);
- }
-
- internal static async Task<UserResult> CreateConfirmationDialog(
- string primaryText,
- string secondaryText,
- string acceptButtonText,
- string cancelButtonText,
- string title,
- UserResult primaryButtonResult = UserResult.Yes)
- {
- return await ShowTextDialog(
- string.IsNullOrWhiteSpace(title) ? LocaleManager.Instance[LocaleKeys.DialogConfirmationTitle] : title,
- primaryText,
- secondaryText,
- acceptButtonText,
- "",
- cancelButtonText,
- (int)Symbol.Help,
- primaryButtonResult);
- }
-
- internal static async Task CreateUpdaterInfoDialog(string primary, string secondaryText)
- {
- await ShowTextDialog(
- LocaleManager.Instance[LocaleKeys.DialogUpdaterTitle],
- primary,
- secondaryText,
- "",
- "",
- LocaleManager.Instance[LocaleKeys.InputDialogOk],
- (int)Symbol.Important);
- }
-
- internal static async Task CreateWarningDialog(string primary, string secondaryText)
- {
- await ShowTextDialog(
- LocaleManager.Instance[LocaleKeys.DialogWarningTitle],
- primary,
- secondaryText,
- "",
- "",
- LocaleManager.Instance[LocaleKeys.InputDialogOk],
- (int)Symbol.Important);
- }
-
- internal static async Task CreateErrorDialog(string errorMessage, string secondaryErrorMessage = "")
- {
- Logger.Error?.Print(LogClass.Application, errorMessage);
-
- await ShowTextDialog(
- LocaleManager.Instance[LocaleKeys.DialogErrorTitle],
- LocaleManager.Instance[LocaleKeys.DialogErrorMessage],
- errorMessage,
- secondaryErrorMessage,
- "",
- LocaleManager.Instance[LocaleKeys.InputDialogOk],
- (int)Symbol.Dismiss);
- }
-
- internal static async Task<bool> CreateChoiceDialog(string title, string primary, string secondaryText)
- {
- if (_isChoiceDialogOpen)
- {
- return false;
- }
-
- _isChoiceDialogOpen = true;
-
- UserResult response = await ShowTextDialog(
- title,
- primary,
- secondaryText,
- LocaleManager.Instance[LocaleKeys.InputDialogYes],
- "",
- LocaleManager.Instance[LocaleKeys.InputDialogNo],
- (int)Symbol.Help,
- UserResult.Yes);
-
- _isChoiceDialogOpen = false;
-
- return response == UserResult.Yes;
- }
-
- internal static async Task<bool> CreateExitDialog()
- {
- return await CreateChoiceDialog(
- LocaleManager.Instance[LocaleKeys.DialogExitTitle],
- LocaleManager.Instance[LocaleKeys.DialogExitMessage],
- LocaleManager.Instance[LocaleKeys.DialogExitSubMessage]);
- }
-
- internal static async Task<bool> CreateStopEmulationDialog()
- {
- return await CreateChoiceDialog(
- LocaleManager.Instance[LocaleKeys.DialogStopEmulationTitle],
- LocaleManager.Instance[LocaleKeys.DialogStopEmulationMessage],
- LocaleManager.Instance[LocaleKeys.DialogExitSubMessage]);
- }
-
- public static async Task<ContentDialogResult> ShowAsync(ContentDialog contentDialog)
- {
- ContentDialogResult result;
- bool isTopDialog = true;
-
- Window parent = GetMainWindow();
-
- if (_contentDialogOverlayWindow != null)
- {
- isTopDialog = false;
- }
-
- if (parent is MainWindow window)
- {
- parent.Activate();
-
- _contentDialogOverlayWindow = new ContentDialogOverlayWindow
- {
- Height = parent.Bounds.Height,
- Width = parent.Bounds.Width,
- Position = parent.PointToScreen(new Point()),
- ShowInTaskbar = false,
- };
-
- parent.PositionChanged += OverlayOnPositionChanged;
-
- void OverlayOnPositionChanged(object sender, PixelPointEventArgs e)
- {
- if (_contentDialogOverlayWindow is null)
- {
- return;
- }
-
- _contentDialogOverlayWindow.Position = parent.PointToScreen(new Point());
- }
-
- _contentDialogOverlayWindow.ContentDialog = contentDialog;
-
- bool opened = false;
-
- _contentDialogOverlayWindow.Opened += OverlayOnActivated;
-
- async void OverlayOnActivated(object sender, EventArgs e)
- {
- if (opened)
- {
- return;
- }
-
- opened = true;
-
- _contentDialogOverlayWindow.Position = parent.PointToScreen(new Point());
-
- result = await ShowDialog();
- }
-
- result = await _contentDialogOverlayWindow.ShowDialog<ContentDialogResult>(parent);
- }
- else
- {
- result = await ShowDialog();
- }
-
- async Task<ContentDialogResult> ShowDialog()
- {
- if (_contentDialogOverlayWindow is not null)
- {
- result = await contentDialog.ShowAsync(_contentDialogOverlayWindow);
-
- _contentDialogOverlayWindow!.Close();
- }
- else
- {
- result = ContentDialogResult.None;
-
- Logger.Warning?.Print(LogClass.UI, "Content dialog overlay failed to populate. Default value has been returned.");
- }
-
- return result;
- }
-
- if (isTopDialog && _contentDialogOverlayWindow is not null)
- {
- _contentDialogOverlayWindow.Content = null;
- _contentDialogOverlayWindow.Close();
- _contentDialogOverlayWindow = null;
- }
-
- return result;
- }
-
- public static Task ShowWindowAsync(Window dialogWindow, Window mainWindow = null)
- {
- mainWindow ??= GetMainWindow();
-
- return dialogWindow.ShowDialog(_contentDialogOverlayWindow ?? mainWindow);
- }
-
- private static Window GetMainWindow()
- {
- if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime al)
- {
- foreach (Window item in al.Windows)
- {
- if (item is MainWindow window)
- {
- return window;
- }
- }
- }
-
- return null;
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Helpers/Glyph.cs b/src/Ryujinx.Ava/UI/Helpers/Glyph.cs
deleted file mode 100644
index f257dc02..00000000
--- a/src/Ryujinx.Ava/UI/Helpers/Glyph.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Ryujinx.Ava.UI.Helpers
-{
- public enum Glyph
- {
- List,
- Grid,
- Chip,
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Helpers/GlyphValueConverter.cs b/src/Ryujinx.Ava/UI/Helpers/GlyphValueConverter.cs
deleted file mode 100644
index 7da23648..00000000
--- a/src/Ryujinx.Ava/UI/Helpers/GlyphValueConverter.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using Avalonia.Markup.Xaml;
-using FluentAvalonia.UI.Controls;
-using System;
-using System.Collections.Generic;
-
-namespace Ryujinx.Ava.UI.Helpers
-{
- public class GlyphValueConverter : MarkupExtension
- {
- private readonly string _key;
-
- private static readonly Dictionary<Glyph, string> _glyphs = new()
- {
- { Glyph.List, char.ConvertFromUtf32((int)Symbol.List) },
- { Glyph.Grid, char.ConvertFromUtf32((int)Symbol.ViewAll) },
- { Glyph.Chip, char.ConvertFromUtf32(59748) },
- };
-
- public GlyphValueConverter(string key)
- {
- _key = key;
- }
-
- public string this[string key]
- {
- get
- {
- if (_glyphs.TryGetValue(Enum.Parse<Glyph>(key), out var val))
- {
- return val;
- }
-
- return string.Empty;
- }
- }
-
- public override object ProvideValue(IServiceProvider serviceProvider)
- {
- return this[_key];
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Helpers/KeyValueConverter.cs b/src/Ryujinx.Ava/UI/Helpers/KeyValueConverter.cs
deleted file mode 100644
index 028ed6bf..00000000
--- a/src/Ryujinx.Ava/UI/Helpers/KeyValueConverter.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using Avalonia.Data.Converters;
-using Ryujinx.Common.Configuration.Hid;
-using Ryujinx.Common.Configuration.Hid.Controller;
-using System;
-using System.Globalization;
-
-namespace Ryujinx.Ava.UI.Helpers
-{
- internal class KeyValueConverter : IValueConverter
- {
- public static KeyValueConverter Instance = new();
-
- public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
- {
- if (value == null)
- {
- return null;
- }
-
- return value.ToString();
- }
-
- public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
- {
- object key = null;
-
- if (value != null)
- {
- if (targetType == typeof(Key))
- {
- key = Enum.Parse<Key>(value.ToString());
- }
- else if (targetType == typeof(GamepadInputId))
- {
- key = Enum.Parse<GamepadInputId>(value.ToString());
- }
- else if (targetType == typeof(StickInputId))
- {
- key = Enum.Parse<StickInputId>(value.ToString());
- }
- }
-
- return key;
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Helpers/LocalizedNeverConverter.cs b/src/Ryujinx.Ava/UI/Helpers/LocalizedNeverConverter.cs
deleted file mode 100644
index 26fe36c4..00000000
--- a/src/Ryujinx.Ava/UI/Helpers/LocalizedNeverConverter.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-using Avalonia.Data.Converters;
-using Avalonia.Markup.Xaml;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.UI.Common.Helper;
-using System;
-using System.Globalization;
-
-namespace Ryujinx.Ava.UI.Helpers
-{
- /// <summary>
- /// This <see cref="IValueConverter"/> makes sure that the string "Never" that's returned by <see cref="ValueFormatUtils.FormatDateTime"/> is properly localized in the Avalonia UI.
- /// After the Avalonia UI has been made the default and the GTK UI is removed, <see cref="ValueFormatUtils"/> should be updated to directly return a localized string.
- /// </summary>
- internal class LocalizedNeverConverter : MarkupExtension, IValueConverter
- {
- private static readonly LocalizedNeverConverter _instance = new();
-
- public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
- {
- if (value is not string valStr)
- {
- return "";
- }
-
- if (valStr == "Never")
- {
- return LocaleManager.Instance[LocaleKeys.Never];
- }
-
- return valStr;
- }
-
- public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
- {
- throw new NotSupportedException();
- }
-
- public override object ProvideValue(IServiceProvider serviceProvider)
- {
- return _instance;
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Helpers/LoggerAdapter.cs b/src/Ryujinx.Ava/UI/Helpers/LoggerAdapter.cs
deleted file mode 100644
index fc714541..00000000
--- a/src/Ryujinx.Ava/UI/Helpers/LoggerAdapter.cs
+++ /dev/null
@@ -1,102 +0,0 @@
-using Avalonia.Logging;
-using Avalonia.Utilities;
-using Ryujinx.Common.Logging;
-using System;
-using System.Text;
-
-namespace Ryujinx.Ava.UI.Helpers
-{
- using AvaLogger = Avalonia.Logging.Logger;
- using AvaLogLevel = LogEventLevel;
- using RyuLogClass = LogClass;
- using RyuLogger = Ryujinx.Common.Logging.Logger;
-
- internal class LoggerAdapter : ILogSink
- {
- public static void Register()
- {
- AvaLogger.Sink = new LoggerAdapter();
- }
-
- private static RyuLogger.Log? GetLog(AvaLogLevel level)
- {
- return level switch
- {
- AvaLogLevel.Verbose => RyuLogger.Debug,
- AvaLogLevel.Debug => RyuLogger.Debug,
- AvaLogLevel.Information => RyuLogger.Debug,
- AvaLogLevel.Warning => RyuLogger.Debug,
- AvaLogLevel.Error => RyuLogger.Error,
- AvaLogLevel.Fatal => RyuLogger.Error,
- _ => throw new ArgumentOutOfRangeException(nameof(level), level, null),
- };
- }
-
- public bool IsEnabled(AvaLogLevel level, string area)
- {
- return GetLog(level) != null;
- }
-
- public void Log(AvaLogLevel level, string area, object source, string messageTemplate)
- {
- GetLog(level)?.PrintMsg(RyuLogClass.UI, Format(level, area, messageTemplate, source, null));
- }
-
- public void Log(AvaLogLevel level, string area, object source, string messageTemplate, params object[] propertyValues)
- {
- GetLog(level)?.PrintMsg(RyuLogClass.UI, Format(level, area, messageTemplate, source, propertyValues));
- }
-
- private static string Format(AvaLogLevel level, string area, string template, object source, object[] v)
- {
- var result = new StringBuilder();
- var r = new CharacterReader(template.AsSpan());
- int i = 0;
-
- result.Append('[');
- result.Append(level);
- result.Append("] ");
-
- result.Append('[');
- result.Append(area);
- result.Append("] ");
-
- while (!r.End)
- {
- var c = r.Take();
-
- if (c != '{')
- {
- result.Append(c);
- }
- else
- {
- if (r.Peek != '{')
- {
- result.Append('\'');
- result.Append(i < v.Length ? v[i++] : null);
- result.Append('\'');
- r.TakeUntil('}');
- r.Take();
- }
- else
- {
- result.Append('{');
- r.Take();
- }
- }
- }
-
- if (source != null)
- {
- result.Append(" (");
- result.Append(source.GetType().Name);
- result.Append(" #");
- result.Append(source.GetHashCode());
- result.Append(')');
- }
-
- return result.ToString();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Helpers/MiniCommand.cs b/src/Ryujinx.Ava/UI/Helpers/MiniCommand.cs
deleted file mode 100644
index 7e1bb9a6..00000000
--- a/src/Ryujinx.Ava/UI/Helpers/MiniCommand.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-using System;
-using System.Threading.Tasks;
-using System.Windows.Input;
-
-namespace Ryujinx.Ava.UI.Helpers
-{
- public sealed class MiniCommand<T> : MiniCommand, ICommand
- {
- private readonly Action<T> _callback;
- private bool _busy;
- private readonly Func<T, Task> _asyncCallback;
-
- public MiniCommand(Action<T> callback)
- {
- _callback = callback;
- }
-
- public MiniCommand(Func<T, Task> callback)
- {
- _asyncCallback = callback;
- }
-
- private bool Busy
- {
- get => _busy;
- set
- {
- _busy = value;
- CanExecuteChanged?.Invoke(this, EventArgs.Empty);
- }
- }
-
- public override event EventHandler CanExecuteChanged;
- public override bool CanExecute(object parameter) => !_busy;
-
- public override async void Execute(object parameter)
- {
- if (Busy)
- {
- return;
- }
- try
- {
- Busy = true;
- if (_callback != null)
- {
- _callback((T)parameter);
- }
- else
- {
- await _asyncCallback((T)parameter);
- }
- }
- finally
- {
- Busy = false;
- }
- }
- }
-
- public abstract class MiniCommand : ICommand
- {
- public static MiniCommand Create(Action callback) => new MiniCommand<object>(_ => callback());
- public static MiniCommand Create<TArg>(Action<TArg> callback) => new MiniCommand<TArg>(callback);
- public static MiniCommand CreateFromTask(Func<Task> callback) => new MiniCommand<object>(_ => callback());
-
- public abstract bool CanExecute(object parameter);
- public abstract void Execute(object parameter);
- public abstract event EventHandler CanExecuteChanged;
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Helpers/NotificationHelper.cs b/src/Ryujinx.Ava/UI/Helpers/NotificationHelper.cs
deleted file mode 100644
index 656a8b52..00000000
--- a/src/Ryujinx.Ava/UI/Helpers/NotificationHelper.cs
+++ /dev/null
@@ -1,70 +0,0 @@
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Controls.Notifications;
-using Avalonia.Threading;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Common;
-using System;
-using System.Collections.Concurrent;
-using System.Threading;
-
-namespace Ryujinx.Ava.UI.Helpers
-{
- public static class NotificationHelper
- {
- private const int MaxNotifications = 4;
- private const int NotificationDelayInMs = 5000;
-
- private static WindowNotificationManager _notificationManager;
-
- private static readonly BlockingCollection<Notification> _notifications = new();
-
- public static void SetNotificationManager(Window host)
- {
- _notificationManager = new WindowNotificationManager(host)
- {
- Position = NotificationPosition.BottomRight,
- MaxItems = MaxNotifications,
- Margin = new Thickness(0, 0, 15, 40),
- };
-
- var maybeAsyncWorkQueue = new Lazy<AsyncWorkQueue<Notification>>(
- () => new AsyncWorkQueue<Notification>(notification =>
- {
- Dispatcher.UIThread.Post(() =>
- {
- _notificationManager.Show(notification);
- });
- },
- "UI.NotificationThread",
- _notifications),
- LazyThreadSafetyMode.ExecutionAndPublication);
-
- _notificationManager.TemplateApplied += (sender, args) =>
- {
- // NOTE: Force creation of the AsyncWorkQueue.
- _ = maybeAsyncWorkQueue.Value;
- };
-
- host.Closing += (sender, args) =>
- {
- if (maybeAsyncWorkQueue.IsValueCreated)
- {
- maybeAsyncWorkQueue.Value.Dispose();
- }
- };
- }
-
- public static void Show(string title, string text, NotificationType type, bool waitingExit = false, Action onClick = null, Action onClose = null)
- {
- var delay = waitingExit ? TimeSpan.FromMilliseconds(0) : TimeSpan.FromMilliseconds(NotificationDelayInMs);
-
- _notifications.Add(new Notification(title, text, type, delay, onClick, onClose));
- }
-
- public static void ShowError(string message)
- {
- Show(LocaleManager.Instance[LocaleKeys.DialogErrorTitle], $"{LocaleManager.Instance[LocaleKeys.DialogErrorMessage]}\n\n{message}", NotificationType.Error);
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Helpers/OffscreenTextBox.cs b/src/Ryujinx.Ava/UI/Helpers/OffscreenTextBox.cs
deleted file mode 100644
index a055f335..00000000
--- a/src/Ryujinx.Ava/UI/Helpers/OffscreenTextBox.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Input;
-using Avalonia.Interactivity;
-
-namespace Ryujinx.Ava.UI.Helpers
-{
- public class OffscreenTextBox : TextBox
- {
- public static RoutedEvent<KeyEventArgs> GetKeyDownRoutedEvent()
- {
- return KeyDownEvent;
- }
-
- public static RoutedEvent<KeyEventArgs> GetKeyUpRoutedEvent()
- {
- return KeyUpEvent;
- }
-
- public void SendKeyDownEvent(KeyEventArgs keyEvent)
- {
- OnKeyDown(keyEvent);
- }
-
- public void SendKeyUpEvent(KeyEventArgs keyEvent)
- {
- OnKeyUp(keyEvent);
- }
-
- public void SendText(string text)
- {
- OnTextInput(new TextInputEventArgs
- {
- Text = text,
- Source = this,
- RoutedEvent = TextInputEvent,
- });
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Helpers/TimeZoneConverter.cs b/src/Ryujinx.Ava/UI/Helpers/TimeZoneConverter.cs
deleted file mode 100644
index 876d51f7..00000000
--- a/src/Ryujinx.Ava/UI/Helpers/TimeZoneConverter.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using Avalonia.Data.Converters;
-using System;
-using System.Globalization;
-using TimeZone = Ryujinx.Ava.UI.Models.TimeZone;
-
-namespace Ryujinx.Ava.UI.Helpers
-{
- internal class TimeZoneConverter : IValueConverter
- {
- public static TimeZoneConverter Instance = new();
-
- public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
- {
- if (value == null)
- {
- return null;
- }
-
- var timeZone = (TimeZone)value;
- return string.Format("{0} {1} {2}", timeZone.UtcDifference, timeZone.Location, timeZone.Abbreviation);
- }
-
- public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
- {
- throw new NotImplementedException();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Helpers/UserErrorDialog.cs b/src/Ryujinx.Ava/UI/Helpers/UserErrorDialog.cs
deleted file mode 100644
index 9a44b862..00000000
--- a/src/Ryujinx.Ava/UI/Helpers/UserErrorDialog.cs
+++ /dev/null
@@ -1,90 +0,0 @@
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.UI.Common;
-using Ryujinx.UI.Common.Helper;
-using System.Threading.Tasks;
-
-namespace Ryujinx.Ava.UI.Helpers
-{
- internal class UserErrorDialog
- {
- private const string SetupGuideUrl = "https://github.com/Ryujinx/Ryujinx/wiki/Ryujinx-Setup-&-Configuration-Guide";
-
- private static string GetErrorCode(UserError error)
- {
- return $"RYU-{(uint)error:X4}";
- }
-
- private static string GetErrorTitle(UserError error)
- {
- return error switch
- {
- UserError.NoKeys => LocaleManager.Instance[LocaleKeys.UserErrorNoKeys],
- UserError.NoFirmware => LocaleManager.Instance[LocaleKeys.UserErrorNoFirmware],
- UserError.FirmwareParsingFailed => LocaleManager.Instance[LocaleKeys.UserErrorFirmwareParsingFailed],
- UserError.ApplicationNotFound => LocaleManager.Instance[LocaleKeys.UserErrorApplicationNotFound],
- UserError.Unknown => LocaleManager.Instance[LocaleKeys.UserErrorUnknown],
- _ => LocaleManager.Instance[LocaleKeys.UserErrorUndefined],
- };
- }
-
- private static string GetErrorDescription(UserError error)
- {
- return error switch
- {
- UserError.NoKeys => LocaleManager.Instance[LocaleKeys.UserErrorNoKeysDescription],
- UserError.NoFirmware => LocaleManager.Instance[LocaleKeys.UserErrorNoFirmwareDescription],
- UserError.FirmwareParsingFailed => LocaleManager.Instance[LocaleKeys.UserErrorFirmwareParsingFailedDescription],
- UserError.ApplicationNotFound => LocaleManager.Instance[LocaleKeys.UserErrorApplicationNotFoundDescription],
- UserError.Unknown => LocaleManager.Instance[LocaleKeys.UserErrorUnknownDescription],
- _ => LocaleManager.Instance[LocaleKeys.UserErrorUndefinedDescription],
- };
- }
-
- private static bool IsCoveredBySetupGuide(UserError error)
- {
- return error switch
- {
- UserError.NoKeys or
- UserError.NoFirmware or
- UserError.FirmwareParsingFailed => true,
- _ => false,
- };
- }
-
- private static string GetSetupGuideUrl(UserError error)
- {
- if (!IsCoveredBySetupGuide(error))
- {
- return null;
- }
-
- return error switch
- {
- UserError.NoKeys => SetupGuideUrl + "#initial-setup---placement-of-prodkeys",
- UserError.NoFirmware => SetupGuideUrl + "#initial-setup-continued---installation-of-firmware",
- _ => SetupGuideUrl,
- };
- }
-
- public static async Task ShowUserErrorDialog(UserError error)
- {
- string errorCode = GetErrorCode(error);
-
- bool isInSetupGuide = IsCoveredBySetupGuide(error);
-
- string setupButtonLabel = isInSetupGuide ? LocaleManager.Instance[LocaleKeys.OpenSetupGuideMessage] : "";
-
- var result = await ContentDialogHelper.CreateInfoDialog(
- LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogUserErrorDialogMessage, errorCode, GetErrorTitle(error)),
- GetErrorDescription(error) + (isInSetupGuide
- ? LocaleManager.Instance[LocaleKeys.DialogUserErrorDialogInfoMessage]
- : ""), setupButtonLabel, LocaleManager.Instance[LocaleKeys.InputDialogOk],
- LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogUserErrorDialogTitle, errorCode));
-
- if (result == UserResult.Ok)
- {
- OpenHelper.OpenUrl(GetSetupGuideUrl(error));
- }
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Helpers/UserResult.cs b/src/Ryujinx.Ava/UI/Helpers/UserResult.cs
deleted file mode 100644
index 2fcd35ae..00000000
--- a/src/Ryujinx.Ava/UI/Helpers/UserResult.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace Ryujinx.Ava.UI.Helpers
-{
- public enum UserResult
- {
- Ok,
- Yes,
- No,
- Abort,
- Cancel,
- None,
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Helpers/Win32NativeInterop.cs b/src/Ryujinx.Ava/UI/Helpers/Win32NativeInterop.cs
deleted file mode 100644
index 4834df80..00000000
--- a/src/Ryujinx.Ava/UI/Helpers/Win32NativeInterop.cs
+++ /dev/null
@@ -1,125 +0,0 @@
-using System;
-using System.Diagnostics.CodeAnalysis;
-using System.Runtime.InteropServices;
-using System.Runtime.Versioning;
-
-namespace Ryujinx.Ava.UI.Helpers
-{
- [SupportedOSPlatform("windows")]
- internal partial class Win32NativeInterop
- {
- [Flags]
- public enum ClassStyles : uint
- {
- CsClassdc = 0x40,
- CsOwndc = 0x20,
- }
-
- [Flags]
- public enum WindowStyles : uint
- {
- WsChild = 0x40000000,
- }
-
- public enum Cursors : uint
- {
- IdcArrow = 32512,
- }
-
- [SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
- public enum WindowsMessages : uint
- {
- Mousemove = 0x0200,
- Lbuttondown = 0x0201,
- Lbuttonup = 0x0202,
- Lbuttondblclk = 0x0203,
- Rbuttondown = 0x0204,
- Rbuttonup = 0x0205,
- Rbuttondblclk = 0x0206,
- Mbuttondown = 0x0207,
- Mbuttonup = 0x0208,
- Mbuttondblclk = 0x0209,
- Mousewheel = 0x020A,
- Xbuttondown = 0x020B,
- Xbuttonup = 0x020C,
- Xbuttondblclk = 0x020D,
- Mousehwheel = 0x020E,
- Mouselast = 0x020E,
- }
-
- [UnmanagedFunctionPointer(CallingConvention.Winapi)]
- internal delegate IntPtr WindowProc(IntPtr hWnd, WindowsMessages msg, IntPtr wParam, IntPtr lParam);
-
- [StructLayout(LayoutKind.Sequential)]
- public struct WndClassEx
- {
- public int cbSize;
- public ClassStyles style;
- public IntPtr lpfnWndProc; // not WndProc
- public int cbClsExtra;
- public int cbWndExtra;
- public IntPtr hInstance;
- public IntPtr hIcon;
- public IntPtr hCursor;
- public IntPtr hbrBackground;
- public IntPtr lpszMenuName;
- public IntPtr lpszClassName;
- public IntPtr hIconSm;
-
- public WndClassEx()
- {
- cbSize = Marshal.SizeOf<WndClassEx>();
- }
- }
-
- public static IntPtr CreateEmptyCursor()
- {
- return CreateCursor(IntPtr.Zero, 0, 0, 1, 1, new byte[] { 0xFF }, new byte[] { 0x00 });
- }
-
- public static IntPtr CreateArrowCursor()
- {
- return LoadCursor(IntPtr.Zero, (IntPtr)Cursors.IdcArrow);
- }
-
- [LibraryImport("user32.dll")]
- public static partial IntPtr SetCursor(IntPtr handle);
-
- [LibraryImport("user32.dll")]
- public static partial IntPtr CreateCursor(IntPtr hInst, int xHotSpot, int yHotSpot, int nWidth, int nHeight, [In] byte[] pvAndPlane, [In] byte[] pvXorPlane);
-
- [LibraryImport("user32.dll", SetLastError = true, EntryPoint = "RegisterClassExW")]
- public static partial ushort RegisterClassEx(ref WndClassEx param);
-
- [LibraryImport("user32.dll", SetLastError = true, EntryPoint = "UnregisterClassW")]
- public static partial short UnregisterClass([MarshalAs(UnmanagedType.LPWStr)] string lpClassName, IntPtr instance);
-
- [LibraryImport("user32.dll", EntryPoint = "DefWindowProcW")]
- public static partial IntPtr DefWindowProc(IntPtr hWnd, WindowsMessages msg, IntPtr wParam, IntPtr lParam);
-
- [LibraryImport("kernel32.dll", EntryPoint = "GetModuleHandleA")]
- public static partial IntPtr GetModuleHandle([MarshalAs(UnmanagedType.LPStr)] string lpModuleName);
-
- [LibraryImport("user32.dll", SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static partial bool DestroyWindow(IntPtr hwnd);
-
- [LibraryImport("user32.dll", SetLastError = true, EntryPoint = "LoadCursorA")]
- public static partial IntPtr LoadCursor(IntPtr hInstance, IntPtr lpCursorName);
-
- [LibraryImport("user32.dll", SetLastError = true, EntryPoint = "CreateWindowExW")]
- public static partial IntPtr CreateWindowEx(
- uint dwExStyle,
- [MarshalAs(UnmanagedType.LPWStr)] string lpClassName,
- [MarshalAs(UnmanagedType.LPWStr)] string lpWindowName,
- WindowStyles dwStyle,
- int x,
- int y,
- int nWidth,
- int nHeight,
- IntPtr hWndParent,
- IntPtr hMenu,
- IntPtr hInstance,
- IntPtr lpParam);
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Models/CheatNode.cs b/src/Ryujinx.Ava/UI/Models/CheatNode.cs
deleted file mode 100644
index 8e9aee25..00000000
--- a/src/Ryujinx.Ava/UI/Models/CheatNode.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using Ryujinx.Ava.UI.ViewModels;
-using System.Collections.ObjectModel;
-using System.Collections.Specialized;
-using System.Linq;
-
-namespace Ryujinx.Ava.UI.Models
-{
- public class CheatNode : BaseModel
- {
- private bool _isEnabled = false;
- public ObservableCollection<CheatNode> SubNodes { get; } = new();
- public string CleanName => Name[1..^7];
- public string BuildIdKey => $"{BuildId}-{Name}";
- public bool IsRootNode { get; }
- public string Name { get; }
- public string BuildId { get; }
- public string Path { get; }
- public bool IsEnabled
- {
- get
- {
- if (SubNodes.Count > 0)
- {
- return SubNodes.ToList().TrueForAll(x => x.IsEnabled);
- }
-
- return _isEnabled;
- }
- set
- {
- foreach (var cheat in SubNodes)
- {
- cheat.IsEnabled = value;
- cheat.OnPropertyChanged();
- }
-
- _isEnabled = value;
- }
- }
-
- public CheatNode(string name, string buildId, string path, bool isRootNode, bool isEnabled = false)
- {
- Name = name;
- BuildId = buildId;
- Path = path;
- IsEnabled = isEnabled;
- IsRootNode = isRootNode;
-
- SubNodes.CollectionChanged += CheatsList_CollectionChanged;
- }
-
- private void CheatsList_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
- {
- OnPropertyChanged(nameof(IsEnabled));
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Models/ControllerModel.cs b/src/Ryujinx.Ava/UI/Models/ControllerModel.cs
deleted file mode 100644
index 98de7757..00000000
--- a/src/Ryujinx.Ava/UI/Models/ControllerModel.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-using Ryujinx.Common.Configuration.Hid;
-
-namespace Ryujinx.Ava.UI.Models
-{
- internal record ControllerModel(ControllerType Type, string Name);
-}
diff --git a/src/Ryujinx.Ava/UI/Models/DeviceType.cs b/src/Ryujinx.Ava/UI/Models/DeviceType.cs
deleted file mode 100644
index bb4fc3b3..00000000
--- a/src/Ryujinx.Ava/UI/Models/DeviceType.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Ryujinx.Ava.UI.Models
-{
- public enum DeviceType
- {
- None,
- Keyboard,
- Controller,
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Models/DownloadableContentModel.cs b/src/Ryujinx.Ava/UI/Models/DownloadableContentModel.cs
deleted file mode 100644
index 9e400441..00000000
--- a/src/Ryujinx.Ava/UI/Models/DownloadableContentModel.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using Ryujinx.Ava.UI.ViewModels;
-using System.IO;
-
-namespace Ryujinx.Ava.UI.Models
-{
- public class DownloadableContentModel : BaseModel
- {
- private bool _enabled;
-
- public bool Enabled
- {
- get => _enabled;
- set
- {
- _enabled = value;
-
- OnPropertyChanged();
- }
- }
-
- public string TitleId { get; }
- public string ContainerPath { get; }
- public string FullPath { get; }
-
- public string FileName => Path.GetFileName(ContainerPath);
-
- public DownloadableContentModel(string titleId, string containerPath, string fullPath, bool enabled)
- {
- TitleId = titleId;
- ContainerPath = containerPath;
- FullPath = fullPath;
- Enabled = enabled;
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Models/Generic/LastPlayedSortComparer.cs b/src/Ryujinx.Ava/UI/Models/Generic/LastPlayedSortComparer.cs
deleted file mode 100644
index 224f78f4..00000000
--- a/src/Ryujinx.Ava/UI/Models/Generic/LastPlayedSortComparer.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using Ryujinx.UI.App.Common;
-using System;
-using System.Collections.Generic;
-
-namespace Ryujinx.Ava.UI.Models.Generic
-{
- internal class LastPlayedSortComparer : IComparer<ApplicationData>
- {
- public LastPlayedSortComparer() { }
- public LastPlayedSortComparer(bool isAscending) { IsAscending = isAscending; }
-
- public bool IsAscending { get; }
-
- public int Compare(ApplicationData x, ApplicationData y)
- {
- DateTime aValue = DateTime.UnixEpoch, bValue = DateTime.UnixEpoch;
-
- if (x?.LastPlayed != null)
- {
- aValue = x.LastPlayed.Value;
- }
-
- if (y?.LastPlayed != null)
- {
- bValue = y.LastPlayed.Value;
- }
-
- return (IsAscending ? 1 : -1) * DateTime.Compare(aValue, bValue);
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Models/Generic/TimePlayedSortComparer.cs b/src/Ryujinx.Ava/UI/Models/Generic/TimePlayedSortComparer.cs
deleted file mode 100644
index f0fb035d..00000000
--- a/src/Ryujinx.Ava/UI/Models/Generic/TimePlayedSortComparer.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using Ryujinx.UI.App.Common;
-using System;
-using System.Collections.Generic;
-
-namespace Ryujinx.Ava.UI.Models.Generic
-{
- internal class TimePlayedSortComparer : IComparer<ApplicationData>
- {
- public TimePlayedSortComparer() { }
- public TimePlayedSortComparer(bool isAscending) { IsAscending = isAscending; }
-
- public bool IsAscending { get; }
-
- public int Compare(ApplicationData x, ApplicationData y)
- {
- TimeSpan aValue = TimeSpan.Zero, bValue = TimeSpan.Zero;
-
- if (x?.TimePlayed != null)
- {
- aValue = x.TimePlayed;
- }
-
- if (y?.TimePlayed != null)
- {
- bValue = y.TimePlayed;
- }
-
- return (IsAscending ? 1 : -1) * TimeSpan.Compare(aValue, bValue);
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Models/InputConfiguration.cs b/src/Ryujinx.Ava/UI/Models/InputConfiguration.cs
deleted file mode 100644
index f1352c6d..00000000
--- a/src/Ryujinx.Ava/UI/Models/InputConfiguration.cs
+++ /dev/null
@@ -1,456 +0,0 @@
-using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.Common.Configuration.Hid;
-using Ryujinx.Common.Configuration.Hid.Controller;
-using Ryujinx.Common.Configuration.Hid.Controller.Motion;
-using Ryujinx.Common.Configuration.Hid.Keyboard;
-using System;
-
-namespace Ryujinx.Ava.UI.Models
-{
- internal class InputConfiguration<TKey, TStick> : BaseModel
- {
- private float _deadzoneRight;
- private float _triggerThreshold;
- private float _deadzoneLeft;
- private double _gyroDeadzone;
- private int _sensitivity;
- private bool _enableMotion;
- private float _weakRumble;
- private float _strongRumble;
- private float _rangeLeft;
- private float _rangeRight;
-
- public InputBackendType Backend { get; set; }
-
- /// <summary>
- /// Controller id
- /// </summary>
- public string Id { get; set; }
-
- /// <summary>
- /// Controller's Type
- /// </summary>
- public ControllerType ControllerType { get; set; }
-
- /// <summary>
- /// Player's Index for the controller
- /// </summary>
- public PlayerIndex PlayerIndex { get; set; }
-
- public TStick LeftJoystick { get; set; }
- public bool LeftInvertStickX { get; set; }
- public bool LeftInvertStickY { get; set; }
- public bool RightRotate90 { get; set; }
- public TKey LeftControllerStickButton { get; set; }
-
- public TStick RightJoystick { get; set; }
- public bool RightInvertStickX { get; set; }
- public bool RightInvertStickY { get; set; }
- public bool LeftRotate90 { get; set; }
- public TKey RightControllerStickButton { get; set; }
-
- public float DeadzoneLeft
- {
- get => _deadzoneLeft;
- set
- {
- _deadzoneLeft = MathF.Round(value, 3);
-
- OnPropertyChanged();
- }
- }
-
- public float RangeLeft
- {
- get => _rangeLeft;
- set
- {
- _rangeLeft = MathF.Round(value, 3);
-
- OnPropertyChanged();
- }
- }
-
- public float DeadzoneRight
- {
- get => _deadzoneRight;
- set
- {
- _deadzoneRight = MathF.Round(value, 3);
-
- OnPropertyChanged();
- }
- }
-
- public float RangeRight
- {
- get => _rangeRight;
- set
- {
- _rangeRight = MathF.Round(value, 3);
-
- OnPropertyChanged();
- }
- }
-
- public float TriggerThreshold
- {
- get => _triggerThreshold;
- set
- {
- _triggerThreshold = MathF.Round(value, 3);
-
- OnPropertyChanged();
- }
- }
-
- public MotionInputBackendType MotionBackend { get; set; }
-
- public TKey ButtonMinus { get; set; }
- public TKey ButtonL { get; set; }
- public TKey ButtonZl { get; set; }
- public TKey LeftButtonSl { get; set; }
- public TKey LeftButtonSr { get; set; }
- public TKey DpadUp { get; set; }
- public TKey DpadDown { get; set; }
- public TKey DpadLeft { get; set; }
- public TKey DpadRight { get; set; }
-
- public TKey ButtonPlus { get; set; }
- public TKey ButtonR { get; set; }
- public TKey ButtonZr { get; set; }
- public TKey RightButtonSl { get; set; }
- public TKey RightButtonSr { get; set; }
- public TKey ButtonX { get; set; }
- public TKey ButtonB { get; set; }
- public TKey ButtonY { get; set; }
- public TKey ButtonA { get; set; }
-
- public TKey LeftStickUp { get; set; }
- public TKey LeftStickDown { get; set; }
- public TKey LeftStickLeft { get; set; }
- public TKey LeftStickRight { get; set; }
- public TKey LeftKeyboardStickButton { get; set; }
-
- public TKey RightStickUp { get; set; }
- public TKey RightStickDown { get; set; }
- public TKey RightStickLeft { get; set; }
- public TKey RightStickRight { get; set; }
- public TKey RightKeyboardStickButton { get; set; }
-
- public int Sensitivity
- {
- get => _sensitivity;
- set
- {
- _sensitivity = value;
-
- OnPropertyChanged();
- }
- }
-
- public double GyroDeadzone
- {
- get => _gyroDeadzone;
- set
- {
- _gyroDeadzone = Math.Round(value, 3);
-
- OnPropertyChanged();
- }
- }
-
- public bool EnableMotion
- {
- get => _enableMotion; set
- {
- _enableMotion = value;
-
- OnPropertyChanged();
- }
- }
-
- public bool EnableCemuHookMotion { get; set; }
- public int Slot { get; set; }
- public int AltSlot { get; set; }
- public bool MirrorInput { get; set; }
- public string DsuServerHost { get; set; }
- public int DsuServerPort { get; set; }
-
- public bool EnableRumble { get; set; }
- public float WeakRumble
- {
- get => _weakRumble; set
- {
- _weakRumble = value;
-
- OnPropertyChanged();
- }
- }
- public float StrongRumble
- {
- get => _strongRumble; set
- {
- _strongRumble = value;
-
- OnPropertyChanged();
- }
- }
-
- public InputConfiguration(InputConfig config)
- {
- if (config != null)
- {
- Backend = config.Backend;
- Id = config.Id;
- ControllerType = config.ControllerType;
- PlayerIndex = config.PlayerIndex;
-
- if (config is StandardKeyboardInputConfig keyboardConfig)
- {
- LeftStickUp = (TKey)(object)keyboardConfig.LeftJoyconStick.StickUp;
- LeftStickDown = (TKey)(object)keyboardConfig.LeftJoyconStick.StickDown;
- LeftStickLeft = (TKey)(object)keyboardConfig.LeftJoyconStick.StickLeft;
- LeftStickRight = (TKey)(object)keyboardConfig.LeftJoyconStick.StickRight;
- LeftKeyboardStickButton = (TKey)(object)keyboardConfig.LeftJoyconStick.StickButton;
-
- RightStickUp = (TKey)(object)keyboardConfig.RightJoyconStick.StickUp;
- RightStickDown = (TKey)(object)keyboardConfig.RightJoyconStick.StickDown;
- RightStickLeft = (TKey)(object)keyboardConfig.RightJoyconStick.StickLeft;
- RightStickRight = (TKey)(object)keyboardConfig.RightJoyconStick.StickRight;
- RightKeyboardStickButton = (TKey)(object)keyboardConfig.RightJoyconStick.StickButton;
-
- ButtonA = (TKey)(object)keyboardConfig.RightJoycon.ButtonA;
- ButtonB = (TKey)(object)keyboardConfig.RightJoycon.ButtonB;
- ButtonX = (TKey)(object)keyboardConfig.RightJoycon.ButtonX;
- ButtonY = (TKey)(object)keyboardConfig.RightJoycon.ButtonY;
- ButtonR = (TKey)(object)keyboardConfig.RightJoycon.ButtonR;
- RightButtonSl = (TKey)(object)keyboardConfig.RightJoycon.ButtonSl;
- RightButtonSr = (TKey)(object)keyboardConfig.RightJoycon.ButtonSr;
- ButtonZr = (TKey)(object)keyboardConfig.RightJoycon.ButtonZr;
- ButtonPlus = (TKey)(object)keyboardConfig.RightJoycon.ButtonPlus;
-
- DpadUp = (TKey)(object)keyboardConfig.LeftJoycon.DpadUp;
- DpadDown = (TKey)(object)keyboardConfig.LeftJoycon.DpadDown;
- DpadLeft = (TKey)(object)keyboardConfig.LeftJoycon.DpadLeft;
- DpadRight = (TKey)(object)keyboardConfig.LeftJoycon.DpadRight;
- ButtonMinus = (TKey)(object)keyboardConfig.LeftJoycon.ButtonMinus;
- LeftButtonSl = (TKey)(object)keyboardConfig.LeftJoycon.ButtonSl;
- LeftButtonSr = (TKey)(object)keyboardConfig.LeftJoycon.ButtonSr;
- ButtonZl = (TKey)(object)keyboardConfig.LeftJoycon.ButtonZl;
- ButtonL = (TKey)(object)keyboardConfig.LeftJoycon.ButtonL;
- }
- else if (config is StandardControllerInputConfig controllerConfig)
- {
- LeftJoystick = (TStick)(object)controllerConfig.LeftJoyconStick.Joystick;
- LeftInvertStickX = controllerConfig.LeftJoyconStick.InvertStickX;
- LeftInvertStickY = controllerConfig.LeftJoyconStick.InvertStickY;
- LeftRotate90 = controllerConfig.LeftJoyconStick.Rotate90CW;
- LeftControllerStickButton = (TKey)(object)controllerConfig.LeftJoyconStick.StickButton;
-
- RightJoystick = (TStick)(object)controllerConfig.RightJoyconStick.Joystick;
- RightInvertStickX = controllerConfig.RightJoyconStick.InvertStickX;
- RightInvertStickY = controllerConfig.RightJoyconStick.InvertStickY;
- RightRotate90 = controllerConfig.RightJoyconStick.Rotate90CW;
- RightControllerStickButton = (TKey)(object)controllerConfig.RightJoyconStick.StickButton;
-
- ButtonA = (TKey)(object)controllerConfig.RightJoycon.ButtonA;
- ButtonB = (TKey)(object)controllerConfig.RightJoycon.ButtonB;
- ButtonX = (TKey)(object)controllerConfig.RightJoycon.ButtonX;
- ButtonY = (TKey)(object)controllerConfig.RightJoycon.ButtonY;
- ButtonR = (TKey)(object)controllerConfig.RightJoycon.ButtonR;
- RightButtonSl = (TKey)(object)controllerConfig.RightJoycon.ButtonSl;
- RightButtonSr = (TKey)(object)controllerConfig.RightJoycon.ButtonSr;
- ButtonZr = (TKey)(object)controllerConfig.RightJoycon.ButtonZr;
- ButtonPlus = (TKey)(object)controllerConfig.RightJoycon.ButtonPlus;
-
- DpadUp = (TKey)(object)controllerConfig.LeftJoycon.DpadUp;
- DpadDown = (TKey)(object)controllerConfig.LeftJoycon.DpadDown;
- DpadLeft = (TKey)(object)controllerConfig.LeftJoycon.DpadLeft;
- DpadRight = (TKey)(object)controllerConfig.LeftJoycon.DpadRight;
- ButtonMinus = (TKey)(object)controllerConfig.LeftJoycon.ButtonMinus;
- LeftButtonSl = (TKey)(object)controllerConfig.LeftJoycon.ButtonSl;
- LeftButtonSr = (TKey)(object)controllerConfig.LeftJoycon.ButtonSr;
- ButtonZl = (TKey)(object)controllerConfig.LeftJoycon.ButtonZl;
- ButtonL = (TKey)(object)controllerConfig.LeftJoycon.ButtonL;
-
- DeadzoneLeft = controllerConfig.DeadzoneLeft;
- DeadzoneRight = controllerConfig.DeadzoneRight;
- RangeLeft = controllerConfig.RangeLeft;
- RangeRight = controllerConfig.RangeRight;
- TriggerThreshold = controllerConfig.TriggerThreshold;
-
- if (controllerConfig.Motion != null)
- {
- EnableMotion = controllerConfig.Motion.EnableMotion;
- MotionBackend = controllerConfig.Motion.MotionBackend;
- GyroDeadzone = controllerConfig.Motion.GyroDeadzone;
- Sensitivity = controllerConfig.Motion.Sensitivity;
-
- if (controllerConfig.Motion is CemuHookMotionConfigController cemuHook)
- {
- EnableCemuHookMotion = true;
- DsuServerHost = cemuHook.DsuServerHost;
- DsuServerPort = cemuHook.DsuServerPort;
- Slot = cemuHook.Slot;
- AltSlot = cemuHook.AltSlot;
- MirrorInput = cemuHook.MirrorInput;
- }
-
- if (controllerConfig.Rumble != null)
- {
- EnableRumble = controllerConfig.Rumble.EnableRumble;
- WeakRumble = controllerConfig.Rumble.WeakRumble;
- StrongRumble = controllerConfig.Rumble.StrongRumble;
- }
- }
- }
- }
- }
-
- public InputConfiguration()
- {
- }
-
- public InputConfig GetConfig()
- {
- if (Backend == InputBackendType.WindowKeyboard)
- {
- return new StandardKeyboardInputConfig
- {
- Id = Id,
- Backend = Backend,
- PlayerIndex = PlayerIndex,
- ControllerType = ControllerType,
- LeftJoycon = new LeftJoyconCommonConfig<Key>
- {
- DpadUp = (Key)(object)DpadUp,
- DpadDown = (Key)(object)DpadDown,
- DpadLeft = (Key)(object)DpadLeft,
- DpadRight = (Key)(object)DpadRight,
- ButtonL = (Key)(object)ButtonL,
- ButtonZl = (Key)(object)ButtonZl,
- ButtonSl = (Key)(object)LeftButtonSl,
- ButtonSr = (Key)(object)LeftButtonSr,
- ButtonMinus = (Key)(object)ButtonMinus,
- },
- RightJoycon = new RightJoyconCommonConfig<Key>
- {
- ButtonA = (Key)(object)ButtonA,
- ButtonB = (Key)(object)ButtonB,
- ButtonX = (Key)(object)ButtonX,
- ButtonY = (Key)(object)ButtonY,
- ButtonPlus = (Key)(object)ButtonPlus,
- ButtonSl = (Key)(object)RightButtonSl,
- ButtonSr = (Key)(object)RightButtonSr,
- ButtonR = (Key)(object)ButtonR,
- ButtonZr = (Key)(object)ButtonZr,
- },
- LeftJoyconStick = new JoyconConfigKeyboardStick<Key>
- {
- StickUp = (Key)(object)LeftStickUp,
- StickDown = (Key)(object)LeftStickDown,
- StickRight = (Key)(object)LeftStickRight,
- StickLeft = (Key)(object)LeftStickLeft,
- StickButton = (Key)(object)LeftKeyboardStickButton,
- },
- RightJoyconStick = new JoyconConfigKeyboardStick<Key>
- {
- StickUp = (Key)(object)RightStickUp,
- StickDown = (Key)(object)RightStickDown,
- StickLeft = (Key)(object)RightStickLeft,
- StickRight = (Key)(object)RightStickRight,
- StickButton = (Key)(object)RightKeyboardStickButton,
- },
- Version = InputConfig.CurrentVersion,
- };
-
- }
-
- if (Backend == InputBackendType.GamepadSDL2)
- {
- var config = new StandardControllerInputConfig
- {
- Id = Id,
- Backend = Backend,
- PlayerIndex = PlayerIndex,
- ControllerType = ControllerType,
- LeftJoycon = new LeftJoyconCommonConfig<GamepadInputId>
- {
- DpadUp = (GamepadInputId)(object)DpadUp,
- DpadDown = (GamepadInputId)(object)DpadDown,
- DpadLeft = (GamepadInputId)(object)DpadLeft,
- DpadRight = (GamepadInputId)(object)DpadRight,
- ButtonL = (GamepadInputId)(object)ButtonL,
- ButtonZl = (GamepadInputId)(object)ButtonZl,
- ButtonSl = (GamepadInputId)(object)LeftButtonSl,
- ButtonSr = (GamepadInputId)(object)LeftButtonSr,
- ButtonMinus = (GamepadInputId)(object)ButtonMinus,
- },
- RightJoycon = new RightJoyconCommonConfig<GamepadInputId>
- {
- ButtonA = (GamepadInputId)(object)ButtonA,
- ButtonB = (GamepadInputId)(object)ButtonB,
- ButtonX = (GamepadInputId)(object)ButtonX,
- ButtonY = (GamepadInputId)(object)ButtonY,
- ButtonPlus = (GamepadInputId)(object)ButtonPlus,
- ButtonSl = (GamepadInputId)(object)RightButtonSl,
- ButtonSr = (GamepadInputId)(object)RightButtonSr,
- ButtonR = (GamepadInputId)(object)ButtonR,
- ButtonZr = (GamepadInputId)(object)ButtonZr,
- },
- LeftJoyconStick = new JoyconConfigControllerStick<GamepadInputId, StickInputId>
- {
- Joystick = (StickInputId)(object)LeftJoystick,
- InvertStickX = LeftInvertStickX,
- InvertStickY = LeftInvertStickY,
- Rotate90CW = LeftRotate90,
- StickButton = (GamepadInputId)(object)LeftControllerStickButton,
- },
- RightJoyconStick = new JoyconConfigControllerStick<GamepadInputId, StickInputId>
- {
- Joystick = (StickInputId)(object)RightJoystick,
- InvertStickX = RightInvertStickX,
- InvertStickY = RightInvertStickY,
- Rotate90CW = RightRotate90,
- StickButton = (GamepadInputId)(object)RightControllerStickButton,
- },
- Rumble = new RumbleConfigController
- {
- EnableRumble = EnableRumble,
- WeakRumble = WeakRumble,
- StrongRumble = StrongRumble,
- },
- Version = InputConfig.CurrentVersion,
- DeadzoneLeft = DeadzoneLeft,
- DeadzoneRight = DeadzoneRight,
- RangeLeft = RangeLeft,
- RangeRight = RangeRight,
- TriggerThreshold = TriggerThreshold,
- Motion = EnableCemuHookMotion
- ? new CemuHookMotionConfigController
- {
- DsuServerHost = DsuServerHost,
- DsuServerPort = DsuServerPort,
- Slot = Slot,
- AltSlot = AltSlot,
- MirrorInput = MirrorInput,
- MotionBackend = MotionInputBackendType.CemuHook,
- }
- : new StandardMotionConfigController
- {
- MotionBackend = MotionInputBackendType.GamepadDriver,
- },
- };
-
- config.Motion.Sensitivity = Sensitivity;
- config.Motion.EnableMotion = EnableMotion;
- config.Motion.GyroDeadzone = GyroDeadzone;
-
- return config;
- }
-
- return null;
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Models/ModModel.cs b/src/Ryujinx.Ava/UI/Models/ModModel.cs
deleted file mode 100644
index ee28ca5f..00000000
--- a/src/Ryujinx.Ava/UI/Models/ModModel.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using Ryujinx.Ava.UI.ViewModels;
-using System.IO;
-
-namespace Ryujinx.Ava.UI.Models
-{
- public class ModModel : BaseModel
- {
- private bool _enabled;
-
- public bool Enabled
- {
- get => _enabled;
- set
- {
- _enabled = value;
- OnPropertyChanged();
- }
- }
-
- public bool InSd { get; }
- public string Path { get; }
- public string Name { get; }
-
- public ModModel(string path, string name, bool enabled, bool inSd)
- {
- Path = path;
- Name = name;
- Enabled = enabled;
- InSd = inSd;
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Models/PlayerModel.cs b/src/Ryujinx.Ava/UI/Models/PlayerModel.cs
deleted file mode 100644
index a19852b9..00000000
--- a/src/Ryujinx.Ava/UI/Models/PlayerModel.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-using Ryujinx.Common.Configuration.Hid;
-
-namespace Ryujinx.Ava.UI.Models
-{
- public record PlayerModel(PlayerIndex Id, string Name);
-}
diff --git a/src/Ryujinx.Ava/UI/Models/ProfileImageModel.cs b/src/Ryujinx.Ava/UI/Models/ProfileImageModel.cs
deleted file mode 100644
index 99365dfc..00000000
--- a/src/Ryujinx.Ava/UI/Models/ProfileImageModel.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using Avalonia.Media;
-using Ryujinx.Ava.UI.ViewModels;
-
-namespace Ryujinx.Ava.UI.Models
-{
- public class ProfileImageModel : BaseModel
- {
- public ProfileImageModel(string name, byte[] data)
- {
- Name = name;
- Data = data;
- }
-
- public string Name { get; set; }
- public byte[] Data { get; set; }
-
- private SolidColorBrush _backgroundColor = new(Colors.White);
-
- public SolidColorBrush BackgroundColor
- {
- get
- {
- return _backgroundColor;
- }
- set
- {
- _backgroundColor = value;
- OnPropertyChanged();
- }
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Models/SaveModel.cs b/src/Ryujinx.Ava/UI/Models/SaveModel.cs
deleted file mode 100644
index d6dea2f6..00000000
--- a/src/Ryujinx.Ava/UI/Models/SaveModel.cs
+++ /dev/null
@@ -1,96 +0,0 @@
-using LibHac.Fs;
-using LibHac.Ncm;
-using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.Ava.UI.Windows;
-using Ryujinx.HLE.FileSystem;
-using Ryujinx.UI.App.Common;
-using Ryujinx.UI.Common.Helper;
-using System.IO;
-using System.Linq;
-using System.Threading.Tasks;
-using Path = System.IO.Path;
-
-namespace Ryujinx.Ava.UI.Models
-{
- public class SaveModel : BaseModel
- {
- private long _size;
-
- public ulong SaveId { get; }
- public ProgramId TitleId { get; }
- public string TitleIdString => $"{TitleId.Value:X16}";
- public UserId UserId { get; }
- public bool InGameList { get; }
- public string Title { get; }
- public byte[] Icon { get; }
-
- public long Size
- {
- get => _size; set
- {
- _size = value;
- SizeAvailable = true;
- OnPropertyChanged();
- OnPropertyChanged(nameof(SizeString));
- OnPropertyChanged(nameof(SizeAvailable));
- }
- }
-
- public bool SizeAvailable { get; set; }
-
- public string SizeString => ValueFormatUtils.FormatFileSize(Size);
-
- public SaveModel(SaveDataInfo info)
- {
- SaveId = info.SaveDataId;
- TitleId = info.ProgramId;
- UserId = info.UserId;
-
- var appData = MainWindow.MainWindowViewModel.Applications.FirstOrDefault(x => x.TitleId.ToUpper() == TitleIdString);
-
- InGameList = appData != null;
-
- if (InGameList)
- {
- Icon = appData.Icon;
- Title = appData.TitleName;
- }
- else
- {
- var appMetadata = ApplicationLibrary.LoadAndSaveMetaData(TitleIdString);
- Title = appMetadata.Title ?? TitleIdString;
- }
-
- Task.Run(() =>
- {
- var saveRoot = Path.Combine(VirtualFileSystem.GetNandPath(), $"user/save/{info.SaveDataId:x16}");
-
- long totalSize = GetDirectorySize(saveRoot);
-
- static long GetDirectorySize(string path)
- {
- long size = 0;
- if (Directory.Exists(path))
- {
- var directories = Directory.GetDirectories(path);
- foreach (var directory in directories)
- {
- size += GetDirectorySize(directory);
- }
-
- var files = Directory.GetFiles(path);
- foreach (var file in files)
- {
- size += new FileInfo(file).Length;
- }
- }
-
- return size;
- }
-
- Size = totalSize;
- });
-
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Models/StatusUpdatedEventArgs.cs b/src/Ryujinx.Ava/UI/Models/StatusUpdatedEventArgs.cs
deleted file mode 100644
index 7f04c0ee..00000000
--- a/src/Ryujinx.Ava/UI/Models/StatusUpdatedEventArgs.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System;
-
-namespace Ryujinx.Ava.UI.Models
-{
- internal class StatusUpdatedEventArgs : EventArgs
- {
- public bool VSyncEnabled { get; }
- public string VolumeStatus { get; }
- public string GpuBackend { get; }
- public string AspectRatio { get; }
- public string DockedMode { get; }
- public string FifoStatus { get; }
- public string GameStatus { get; }
- public string GpuName { get; }
-
- public StatusUpdatedEventArgs(bool vSyncEnabled, string volumeStatus, string gpuBackend, string dockedMode, string aspectRatio, string gameStatus, string fifoStatus, string gpuName)
- {
- VSyncEnabled = vSyncEnabled;
- VolumeStatus = volumeStatus;
- GpuBackend = gpuBackend;
- DockedMode = dockedMode;
- AspectRatio = aspectRatio;
- GameStatus = gameStatus;
- FifoStatus = fifoStatus;
- GpuName = gpuName;
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Models/TempProfile.cs b/src/Ryujinx.Ava/UI/Models/TempProfile.cs
deleted file mode 100644
index 659092e6..00000000
--- a/src/Ryujinx.Ava/UI/Models/TempProfile.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-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;
- private string _name = String.Empty;
- private UserId _userId;
-
- public static uint MaxProfileNameLength => 0x20;
-
- public byte[] Image
- {
- get => _image;
- set
- {
- _image = value;
- OnPropertyChanged();
- }
- }
-
- public UserId UserId
- {
- get => _userId;
- set
- {
- _userId = value;
- OnPropertyChanged();
- OnPropertyChanged(nameof(UserIdString));
- }
- }
-
- public string UserIdString => _userId.ToString();
-
- public string Name
- {
- get => _name;
- set
- {
- _name = value;
- OnPropertyChanged();
- }
- }
-
- public TempProfile(UserProfile profile)
- {
- _profile = profile;
-
- if (_profile != null)
- {
- Image = profile.Image;
- Name = profile.Name;
- UserId = profile.UserId;
- }
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Models/TimeZone.cs b/src/Ryujinx.Ava/UI/Models/TimeZone.cs
deleted file mode 100644
index 950fbce4..00000000
--- a/src/Ryujinx.Ava/UI/Models/TimeZone.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-namespace Ryujinx.Ava.UI.Models
-{
- internal class TimeZone
- {
- public TimeZone(string utcDifference, string location, string abbreviation)
- {
- UtcDifference = utcDifference;
- Location = location;
- Abbreviation = abbreviation;
- }
-
- public string UtcDifference { get; set; }
- public string Location { get; set; }
- public string Abbreviation { get; set; }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Models/TitleUpdateModel.cs b/src/Ryujinx.Ava/UI/Models/TitleUpdateModel.cs
deleted file mode 100644
index c270c9ed..00000000
--- a/src/Ryujinx.Ava/UI/Models/TitleUpdateModel.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using LibHac.Ns;
-using Ryujinx.Ava.Common.Locale;
-
-namespace Ryujinx.Ava.UI.Models
-{
- public class TitleUpdateModel
- {
- public ApplicationControlProperty Control { get; }
- public string Path { get; }
-
- public string Label => LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.TitleUpdateVersionLabel, Control.DisplayVersionString.ToString());
-
- public TitleUpdateModel(ApplicationControlProperty control, string path)
- {
- Control = control;
- Path = path;
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Models/UserProfile.cs b/src/Ryujinx.Ava/UI/Models/UserProfile.cs
deleted file mode 100644
index 7a9237fe..00000000
--- a/src/Ryujinx.Ava/UI/Models/UserProfile.cs
+++ /dev/null
@@ -1,104 +0,0 @@
-using Avalonia.Media;
-using Ryujinx.Ava.UI.Controls;
-using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.Ava.UI.Views.User;
-using Ryujinx.HLE.HOS.Services.Account.Acc;
-using Profile = Ryujinx.HLE.HOS.Services.Account.Acc.UserProfile;
-
-namespace Ryujinx.Ava.UI.Models
-{
- public class UserProfile : BaseModel
- {
- private readonly Profile _profile;
- private readonly NavigationDialogHost _owner;
- private byte[] _image;
- private string _name;
- private UserId _userId;
- private bool _isPointerOver;
- private IBrush _backgroundColor;
-
- 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 bool IsPointerOver
- {
- get => _isPointerOver;
- set
- {
- _isPointerOver = value;
- OnPropertyChanged();
- }
- }
-
- public IBrush BackgroundColor
- {
- get => _backgroundColor;
- set
- {
- _backgroundColor = value;
- OnPropertyChanged();
- }
- }
-
- public UserProfile(Profile profile, NavigationDialogHost owner)
- {
- _profile = profile;
- _owner = owner;
-
- UpdateBackground();
-
- Image = profile.Image;
- Name = profile.Name;
- UserId = profile.UserId;
- }
-
- public void UpdateState()
- {
- UpdateBackground();
- OnPropertyChanged(nameof(Name));
- }
-
- private void UpdateBackground()
- {
- var currentApplication = Avalonia.Application.Current;
- currentApplication.Styles.TryGetResource("ControlFillColorSecondary", currentApplication.ActualThemeVariant, out object color);
-
- if (color is not null)
- {
- BackgroundColor = _profile.AccountState == AccountState.Open ? new SolidColorBrush((Color)color) : Brushes.Transparent;
- }
- }
-
- public void Recover(UserProfile userProfile)
- {
- _owner.Navigate(typeof(UserEditorView), (_owner, userProfile, true));
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindow.cs b/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindow.cs
deleted file mode 100644
index 3bf19b43..00000000
--- a/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindow.cs
+++ /dev/null
@@ -1,294 +0,0 @@
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Input;
-using Avalonia.Platform;
-using Ryujinx.Common.Configuration;
-using Ryujinx.UI.Common.Configuration;
-using Ryujinx.UI.Common.Helper;
-using SPB.Graphics;
-using SPB.Platform;
-using SPB.Platform.GLX;
-using SPB.Platform.X11;
-using SPB.Windowing;
-using System;
-using System.Runtime.InteropServices;
-using System.Runtime.Versioning;
-using System.Threading.Tasks;
-using static Ryujinx.Ava.UI.Helpers.Win32NativeInterop;
-
-namespace Ryujinx.Ava.UI.Renderer
-{
- public class EmbeddedWindow : NativeControlHost
- {
- private WindowProc _wndProcDelegate;
- private string _className;
-
- protected GLXWindow X11Window { get; set; }
-
- protected IntPtr WindowHandle { get; set; }
- protected IntPtr X11Display { get; set; }
- protected IntPtr NsView { get; set; }
- protected IntPtr MetalLayer { get; set; }
-
- public delegate void UpdateBoundsCallbackDelegate(Rect rect);
- private UpdateBoundsCallbackDelegate _updateBoundsCallback;
-
- public event EventHandler<IntPtr> WindowCreated;
- public event EventHandler<Size> BoundsChanged;
-
- public EmbeddedWindow()
- {
- this.GetObservable(BoundsProperty).Subscribe(StateChanged);
-
- Initialized += OnNativeEmbeddedWindowCreated;
- }
-
- public virtual void OnWindowCreated() { }
-
- protected virtual void OnWindowDestroyed() { }
-
- protected virtual void OnWindowDestroying()
- {
- WindowHandle = IntPtr.Zero;
- X11Display = IntPtr.Zero;
- NsView = IntPtr.Zero;
- MetalLayer = IntPtr.Zero;
- }
-
- private void OnNativeEmbeddedWindowCreated(object sender, EventArgs e)
- {
- OnWindowCreated();
-
- Task.Run(() =>
- {
- WindowCreated?.Invoke(this, WindowHandle);
- });
- }
-
- private void StateChanged(Rect rect)
- {
- BoundsChanged?.Invoke(this, rect.Size);
- _updateBoundsCallback?.Invoke(rect);
- }
-
- protected override IPlatformHandle CreateNativeControlCore(IPlatformHandle control)
- {
- if (OperatingSystem.IsLinux())
- {
- return CreateLinux(control);
- }
-
- if (OperatingSystem.IsWindows())
- {
- return CreateWin32(control);
- }
-
- if (OperatingSystem.IsMacOS())
- {
- return CreateMacOS();
- }
-
- return base.CreateNativeControlCore(control);
- }
-
- protected override void DestroyNativeControlCore(IPlatformHandle control)
- {
- OnWindowDestroying();
-
- if (OperatingSystem.IsLinux())
- {
- DestroyLinux();
- }
- else if (OperatingSystem.IsWindows())
- {
- DestroyWin32(control);
- }
- else if (OperatingSystem.IsMacOS())
- {
- DestroyMacOS();
- }
- else
- {
- base.DestroyNativeControlCore(control);
- }
-
- OnWindowDestroyed();
- }
-
- [SupportedOSPlatform("linux")]
- private IPlatformHandle CreateLinux(IPlatformHandle control)
- {
- if (ConfigurationState.Instance.Graphics.GraphicsBackend.Value == GraphicsBackend.Vulkan)
- {
- X11Window = new GLXWindow(new NativeHandle(X11.DefaultDisplay), new NativeHandle(control.Handle));
- X11Window.Hide();
- }
- else
- {
- X11Window = PlatformHelper.CreateOpenGLWindow(new FramebufferFormat(new ColorFormat(8, 8, 8, 0), 16, 0, ColorFormat.Zero, 0, 2, false), 0, 0, 100, 100) as GLXWindow;
- }
-
- WindowHandle = X11Window.WindowHandle.RawHandle;
- X11Display = X11Window.DisplayHandle.RawHandle;
-
- return new PlatformHandle(WindowHandle, "X11");
- }
-
- [SupportedOSPlatform("windows")]
- IPlatformHandle CreateWin32(IPlatformHandle control)
- {
- _className = "NativeWindow-" + Guid.NewGuid();
-
- _wndProcDelegate = delegate (IntPtr hWnd, WindowsMessages msg, IntPtr wParam, IntPtr lParam)
- {
- if (VisualRoot != null)
- {
- if (msg == WindowsMessages.Lbuttondown ||
- msg == WindowsMessages.Rbuttondown ||
- msg == WindowsMessages.Lbuttonup ||
- msg == WindowsMessages.Rbuttonup ||
- msg == WindowsMessages.Mousemove)
- {
- Point rootVisualPosition = this.TranslatePoint(new Point((long)lParam & 0xFFFF, (long)lParam >> 16 & 0xFFFF), this).Value;
- Pointer pointer = new(0, PointerType.Mouse, true);
-
-#pragma warning disable CS0618 // Type or member is obsolete (As of Avalonia 11, the constructors for PointerPressedEventArgs & PointerEventArgs are marked as obsolete)
- switch (msg)
- {
- case WindowsMessages.Lbuttondown:
- case WindowsMessages.Rbuttondown:
- {
- bool isLeft = msg == WindowsMessages.Lbuttondown;
- RawInputModifiers pointerPointModifier = isLeft ? RawInputModifiers.LeftMouseButton : RawInputModifiers.RightMouseButton;
- PointerPointProperties properties = new(pointerPointModifier, isLeft ? PointerUpdateKind.LeftButtonPressed : PointerUpdateKind.RightButtonPressed);
-
- var evnt = new PointerPressedEventArgs(
- this,
- pointer,
- this,
- rootVisualPosition,
- (ulong)Environment.TickCount64,
- properties,
- KeyModifiers.None);
-
- RaiseEvent(evnt);
-
- break;
- }
- case WindowsMessages.Lbuttonup:
- case WindowsMessages.Rbuttonup:
- {
- bool isLeft = msg == WindowsMessages.Lbuttonup;
- RawInputModifiers pointerPointModifier = isLeft ? RawInputModifiers.LeftMouseButton : RawInputModifiers.RightMouseButton;
- PointerPointProperties properties = new(pointerPointModifier, isLeft ? PointerUpdateKind.LeftButtonReleased : PointerUpdateKind.RightButtonReleased);
-
- var evnt = new PointerReleasedEventArgs(
- this,
- pointer,
- this,
- rootVisualPosition,
- (ulong)Environment.TickCount64,
- properties,
- KeyModifiers.None,
- isLeft ? MouseButton.Left : MouseButton.Right);
-
- RaiseEvent(evnt);
-
- break;
- }
- case WindowsMessages.Mousemove:
- {
- var evnt = new PointerEventArgs(
- PointerMovedEvent,
- this,
- pointer,
- this,
- rootVisualPosition,
- (ulong)Environment.TickCount64,
- new PointerPointProperties(RawInputModifiers.None, PointerUpdateKind.Other),
- KeyModifiers.None);
-
- RaiseEvent(evnt);
-
- break;
- }
- }
-#pragma warning restore CS0618
- }
- }
-
- return DefWindowProc(hWnd, msg, wParam, lParam);
- };
-
- WndClassEx wndClassEx = new()
- {
- cbSize = Marshal.SizeOf<WndClassEx>(),
- hInstance = GetModuleHandle(null),
- lpfnWndProc = Marshal.GetFunctionPointerForDelegate(_wndProcDelegate),
- style = ClassStyles.CsOwndc,
- lpszClassName = Marshal.StringToHGlobalUni(_className),
- hCursor = CreateArrowCursor(),
- };
-
- RegisterClassEx(ref wndClassEx);
-
- WindowHandle = CreateWindowEx(0, _className, "NativeWindow", WindowStyles.WsChild, 0, 0, 640, 480, control.Handle, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
-
- Marshal.FreeHGlobal(wndClassEx.lpszClassName);
-
- return new PlatformHandle(WindowHandle, "HWND");
- }
-
- [SupportedOSPlatform("macos")]
- IPlatformHandle CreateMacOS()
- {
- // Create a new CAMetalLayer.
- ObjectiveC.Object layerObject = new("CAMetalLayer");
- ObjectiveC.Object metalLayer = layerObject.GetFromMessage("alloc");
- metalLayer.SendMessage("init");
-
- // Create a child NSView to render into.
- ObjectiveC.Object nsViewObject = new("NSView");
- ObjectiveC.Object child = nsViewObject.GetFromMessage("alloc");
- child.SendMessage("init", new ObjectiveC.NSRect(0, 0, 0, 0));
-
- // Make its renderer our metal layer.
- child.SendMessage("setWantsLayer:", 1);
- child.SendMessage("setLayer:", metalLayer);
- metalLayer.SendMessage("setContentsScale:", Program.DesktopScaleFactor);
-
- // Ensure the scale factor is up to date.
- _updateBoundsCallback = rect =>
- {
- metalLayer.SendMessage("setContentsScale:", Program.DesktopScaleFactor);
- };
-
- IntPtr nsView = child.ObjPtr;
- MetalLayer = metalLayer.ObjPtr;
- NsView = nsView;
-
- return new PlatformHandle(nsView, "NSView");
- }
-
- [SupportedOSPlatform("Linux")]
- void DestroyLinux()
- {
- X11Window?.Dispose();
- }
-
- [SupportedOSPlatform("windows")]
- void DestroyWin32(IPlatformHandle handle)
- {
- DestroyWindow(handle.Handle);
- UnregisterClass(_className, GetModuleHandle(null));
- }
-
- [SupportedOSPlatform("macos")]
-#pragma warning disable CA1822 // Mark member as static
- void DestroyMacOS()
- {
- // TODO
- }
-#pragma warning restore CA1822
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindowOpenGL.cs b/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindowOpenGL.cs
deleted file mode 100644
index 3842301d..00000000
--- a/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindowOpenGL.cs
+++ /dev/null
@@ -1,94 +0,0 @@
-using OpenTK.Graphics.OpenGL;
-using Ryujinx.Common.Configuration;
-using Ryujinx.Common.Logging;
-using Ryujinx.Graphics.GAL;
-using Ryujinx.Graphics.OpenGL;
-using Ryujinx.UI.Common.Configuration;
-using SPB.Graphics;
-using SPB.Graphics.Exceptions;
-using SPB.Graphics.OpenGL;
-using SPB.Platform;
-using SPB.Platform.WGL;
-using SPB.Windowing;
-using System;
-
-namespace Ryujinx.Ava.UI.Renderer
-{
- public class EmbeddedWindowOpenGL : EmbeddedWindow
- {
- private SwappableNativeWindowBase _window;
-
- public OpenGLContextBase Context { get; set; }
-
- protected override void OnWindowDestroying()
- {
- Context.Dispose();
-
- base.OnWindowDestroying();
- }
-
- public override void OnWindowCreated()
- {
- base.OnWindowCreated();
-
- if (OperatingSystem.IsWindows())
- {
- _window = new WGLWindow(new NativeHandle(WindowHandle));
- }
- else if (OperatingSystem.IsLinux())
- {
- _window = X11Window;
- }
- else
- {
- throw new PlatformNotSupportedException();
- }
-
- var flags = OpenGLContextFlags.Compat;
- if (ConfigurationState.Instance.Logger.GraphicsDebugLevel != GraphicsDebugLevel.None)
- {
- flags |= OpenGLContextFlags.Debug;
- }
-
- var graphicsMode = Environment.OSVersion.Platform == PlatformID.Unix ? new FramebufferFormat(new ColorFormat(8, 8, 8, 0), 16, 0, ColorFormat.Zero, 0, 2, false) : FramebufferFormat.Default;
-
- Context = PlatformHelper.CreateOpenGLContext(graphicsMode, 3, 3, flags);
-
- Context.Initialize(_window);
- Context.MakeCurrent(_window);
-
- GL.LoadBindings(new OpenTKBindingsContext(Context.GetProcAddress));
-
- Context.MakeCurrent(null);
- }
-
- public void MakeCurrent(bool unbind = false, bool shouldThrow = true)
- {
- try
- {
- Context?.MakeCurrent(!unbind ? _window : null);
- }
- catch (ContextException e)
- {
- if (shouldThrow)
- {
- throw;
- }
-
- Logger.Warning?.Print(LogClass.UI, $"Failed to {(!unbind ? "bind" : "unbind")} OpenGL context: {e}");
- }
- }
-
- public void SwapBuffers()
- {
- _window?.SwapBuffers();
- }
-
- public void InitializeBackgroundContext(IRenderer renderer)
- {
- (renderer as OpenGLRenderer)?.InitializeBackgroundContext(SPBOpenGLContext.CreateBackgroundContext(Context));
-
- MakeCurrent();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindowVulkan.cs b/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindowVulkan.cs
deleted file mode 100644
index fafbec20..00000000
--- a/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindowVulkan.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using Silk.NET.Vulkan;
-using SPB.Graphics.Vulkan;
-using SPB.Platform.Metal;
-using SPB.Platform.Win32;
-using SPB.Platform.X11;
-using SPB.Windowing;
-using System;
-
-namespace Ryujinx.Ava.UI.Renderer
-{
- public class EmbeddedWindowVulkan : EmbeddedWindow
- {
- public SurfaceKHR CreateSurface(Instance instance)
- {
- NativeWindowBase nativeWindowBase;
-
- if (OperatingSystem.IsWindows())
- {
- nativeWindowBase = new SimpleWin32Window(new NativeHandle(WindowHandle));
- }
- else if (OperatingSystem.IsLinux())
- {
- nativeWindowBase = new SimpleX11Window(new NativeHandle(X11Display), new NativeHandle(WindowHandle));
- }
- else if (OperatingSystem.IsMacOS())
- {
- nativeWindowBase = new SimpleMetalWindow(new NativeHandle(NsView), new NativeHandle(MetalLayer));
- }
- else
- {
- throw new PlatformNotSupportedException();
- }
-
- return new SurfaceKHR((ulong?)VulkanHelper.CreateWindowSurface(instance.Handle, nativeWindowBase));
- }
-
- public SurfaceKHR CreateSurface(Instance instance, Vk _)
- {
- return CreateSurface(instance);
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Renderer/OpenTKBindingsContext.cs b/src/Ryujinx.Ava/UI/Renderer/OpenTKBindingsContext.cs
deleted file mode 100644
index 85e8585f..00000000
--- a/src/Ryujinx.Ava/UI/Renderer/OpenTKBindingsContext.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using OpenTK;
-using System;
-
-namespace Ryujinx.Ava.UI.Renderer
-{
- internal class OpenTKBindingsContext : IBindingsContext
- {
- private readonly Func<string, IntPtr> _getProcAddress;
-
- public OpenTKBindingsContext(Func<string, IntPtr> getProcAddress)
- {
- _getProcAddress = getProcAddress;
- }
-
- public IntPtr GetProcAddress(string procName)
- {
- return _getProcAddress(procName);
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml b/src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml
deleted file mode 100644
index e0b586b4..00000000
--- a/src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml
+++ /dev/null
@@ -1,12 +0,0 @@
-<UserControl
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- mc:Ignorable="d"
- d:DesignWidth="800"
- d:DesignHeight="450"
- x:Class="Ryujinx.Ava.UI.Renderer.RendererHost"
- FlowDirection="LeftToRight"
- Focusable="True">
-</UserControl>
diff --git a/src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml.cs b/src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml.cs
deleted file mode 100644
index d055d9ea..00000000
--- a/src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-using Avalonia;
-using Avalonia.Controls;
-using Ryujinx.Common.Configuration;
-using Ryujinx.UI.Common.Configuration;
-using System;
-
-namespace Ryujinx.Ava.UI.Renderer
-{
- public partial class RendererHost : UserControl, IDisposable
- {
- public readonly EmbeddedWindow EmbeddedWindow;
-
- public event EventHandler<EventArgs> WindowCreated;
- public event Action<object, Size> BoundsChanged;
-
- public RendererHost()
- {
- InitializeComponent();
-
- if (ConfigurationState.Instance.Graphics.GraphicsBackend.Value == GraphicsBackend.OpenGl)
- {
- EmbeddedWindow = new EmbeddedWindowOpenGL();
- }
- else
- {
- EmbeddedWindow = new EmbeddedWindowVulkan();
- }
-
- Initialize();
- }
-
- private void Initialize()
- {
- EmbeddedWindow.WindowCreated += CurrentWindow_WindowCreated;
- EmbeddedWindow.BoundsChanged += CurrentWindow_BoundsChanged;
-
- Content = EmbeddedWindow;
- }
-
- public void Dispose()
- {
- if (EmbeddedWindow != null)
- {
- EmbeddedWindow.WindowCreated -= CurrentWindow_WindowCreated;
- EmbeddedWindow.BoundsChanged -= CurrentWindow_BoundsChanged;
- }
-
- GC.SuppressFinalize(this);
- }
-
- protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
- {
- base.OnDetachedFromVisualTree(e);
-
- Dispose();
- }
-
- private void CurrentWindow_BoundsChanged(object sender, Size e)
- {
- BoundsChanged?.Invoke(sender, e);
- }
-
- private void CurrentWindow_WindowCreated(object sender, IntPtr e)
- {
- WindowCreated?.Invoke(this, EventArgs.Empty);
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Renderer/SPBOpenGLContext.cs b/src/Ryujinx.Ava/UI/Renderer/SPBOpenGLContext.cs
deleted file mode 100644
index 63bf6cf7..00000000
--- a/src/Ryujinx.Ava/UI/Renderer/SPBOpenGLContext.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using OpenTK.Graphics.OpenGL;
-using Ryujinx.Graphics.OpenGL;
-using SPB.Graphics;
-using SPB.Graphics.OpenGL;
-using SPB.Platform;
-using SPB.Windowing;
-
-namespace Ryujinx.Ava.UI.Renderer
-{
- class SPBOpenGLContext : IOpenGLContext
- {
- private readonly OpenGLContextBase _context;
- private readonly NativeWindowBase _window;
-
- private SPBOpenGLContext(OpenGLContextBase context, NativeWindowBase window)
- {
- _context = context;
- _window = window;
- }
-
- public void Dispose()
- {
- _context.Dispose();
- _window.Dispose();
- }
-
- public void MakeCurrent()
- {
- _context.MakeCurrent(_window);
- }
-
- public bool HasContext() => _context.IsCurrent;
-
- public static SPBOpenGLContext CreateBackgroundContext(OpenGLContextBase sharedContext)
- {
- OpenGLContextBase context = PlatformHelper.CreateOpenGLContext(FramebufferFormat.Default, 3, 3, OpenGLContextFlags.Compat, true, sharedContext);
- NativeWindowBase window = PlatformHelper.CreateOpenGLWindow(FramebufferFormat.Default, 0, 0, 100, 100);
-
- context.Initialize(window);
- context.MakeCurrent(window);
-
- GL.LoadBindings(new OpenTKBindingsContext(context.GetProcAddress));
-
- context.MakeCurrent(null);
-
- return new SPBOpenGLContext(context, window);
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/ViewModels/AboutWindowViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/AboutWindowViewModel.cs
deleted file mode 100644
index 6020f40e..00000000
--- a/src/Ryujinx.Ava/UI/ViewModels/AboutWindowViewModel.cs
+++ /dev/null
@@ -1,131 +0,0 @@
-using Avalonia.Media.Imaging;
-using Avalonia.Platform;
-using Avalonia.Threading;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Common.Utilities;
-using Ryujinx.UI.Common.Configuration;
-using System;
-using System.Net.Http;
-using System.Net.NetworkInformation;
-using System.Threading.Tasks;
-
-namespace Ryujinx.Ava.UI.ViewModels
-{
- public class AboutWindowViewModel : BaseModel
- {
- private Bitmap _githubLogo;
- private Bitmap _discordLogo;
- private Bitmap _patreonLogo;
- private Bitmap _twitterLogo;
-
- private string _version;
- private string _supporters;
-
- public Bitmap GithubLogo
- {
- get => _githubLogo;
- set
- {
- _githubLogo = value;
- OnPropertyChanged();
- }
- }
-
- public Bitmap DiscordLogo
- {
- get => _discordLogo;
- set
- {
- _discordLogo = value;
- OnPropertyChanged();
- }
- }
-
- public Bitmap PatreonLogo
- {
- get => _patreonLogo;
- set
- {
- _patreonLogo = value;
- OnPropertyChanged();
- }
- }
-
- public Bitmap TwitterLogo
- {
- get => _twitterLogo;
- set
- {
- _twitterLogo = value;
- OnPropertyChanged();
- }
- }
-
- public string Supporters
- {
- get => _supporters;
- set
- {
- _supporters = value;
- OnPropertyChanged();
- }
- }
-
- public string Version
- {
- get => _version;
- set
- {
- _version = value;
- OnPropertyChanged();
- }
- }
-
- public string Developers => LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.AboutPageDeveloperListMore, "gdkchan, Ac_K, marysaka, rip in peri peri, LDj3SNuD, emmaus, Thealexbarney, GoffyDude, TSRBerry, IsaacMarovitz");
-
- public AboutWindowViewModel()
- {
- Version = Program.Version;
-
- if (ConfigurationState.Instance.UI.BaseStyle.Value == "Light")
- {
- GithubLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_GitHub_Light.png?assembly=Ryujinx.UI.Common")));
- DiscordLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_Discord_Light.png?assembly=Ryujinx.UI.Common")));
- PatreonLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_Patreon_Light.png?assembly=Ryujinx.UI.Common")));
- TwitterLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_Twitter_Light.png?assembly=Ryujinx.UI.Common")));
- }
- else
- {
- GithubLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_GitHub_Dark.png?assembly=Ryujinx.UI.Common")));
- DiscordLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_Discord_Dark.png?assembly=Ryujinx.UI.Common")));
- PatreonLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_Patreon_Dark.png?assembly=Ryujinx.UI.Common")));
- TwitterLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_Twitter_Dark.png?assembly=Ryujinx.UI.Common")));
- }
-
- Dispatcher.UIThread.InvokeAsync(DownloadPatronsJson);
- }
-
- private async Task DownloadPatronsJson()
- {
- if (!NetworkInterface.GetIsNetworkAvailable())
- {
- Supporters = LocaleManager.Instance[LocaleKeys.ConnectionError];
-
- return;
- }
-
- HttpClient httpClient = new();
-
- try
- {
- string patreonJsonString = await httpClient.GetStringAsync("https://patreon.ryujinx.org/");
-
- Supporters = string.Join(", ", JsonHelper.Deserialize(patreonJsonString, CommonJsonContext.Default.StringArray)) + "\n\n";
- }
- catch
- {
- Supporters = LocaleManager.Instance[LocaleKeys.ApiError];
- }
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs
deleted file mode 100644
index 8f09568a..00000000
--- a/src/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs
+++ /dev/null
@@ -1,518 +0,0 @@
-using Avalonia;
-using Avalonia.Collections;
-using Avalonia.Media.Imaging;
-using Avalonia.Threading;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.Windows;
-using Ryujinx.Common;
-using Ryujinx.Common.Configuration;
-using Ryujinx.Common.Logging;
-using Ryujinx.Common.Utilities;
-using Ryujinx.UI.Common.Models.Amiibo;
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.IO;
-using System.Linq;
-using System.Net.Http;
-using System.Text;
-using System.Text.Json;
-using System.Threading.Tasks;
-
-namespace Ryujinx.Ava.UI.ViewModels
-{
- public class AmiiboWindowViewModel : BaseModel, IDisposable
- {
- private const string DefaultJson = "{ \"amiibo\": [] }";
- private const float AmiiboImageSize = 350f;
-
- private readonly string _amiiboJsonPath;
- private readonly byte[] _amiiboLogoBytes;
- private readonly HttpClient _httpClient;
- private readonly StyleableWindow _owner;
-
- private Bitmap _amiiboImage;
- private List<AmiiboApi> _amiiboList;
- private AvaloniaList<AmiiboApi> _amiibos;
- private ObservableCollection<string> _amiiboSeries;
-
- private int _amiiboSelectedIndex;
- private int _seriesSelectedIndex;
- private bool _enableScanning;
- private bool _showAllAmiibo;
- private bool _useRandomUuid;
- private string _usage;
-
- private static readonly AmiiboJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
-
- public AmiiboWindowViewModel(StyleableWindow owner, string lastScannedAmiiboId, string titleId)
- {
- _owner = owner;
-
- _httpClient = new HttpClient
- {
- Timeout = TimeSpan.FromSeconds(30),
- };
-
- LastScannedAmiiboId = lastScannedAmiiboId;
- TitleId = titleId;
-
- Directory.CreateDirectory(Path.Join(AppDataManager.BaseDirPath, "system", "amiibo"));
-
- _amiiboJsonPath = Path.Join(AppDataManager.BaseDirPath, "system", "amiibo", "Amiibo.json");
- _amiiboList = new List<AmiiboApi>();
- _amiiboSeries = new ObservableCollection<string>();
- _amiibos = new AvaloniaList<AmiiboApi>();
-
- _amiiboLogoBytes = EmbeddedResources.Read("Ryujinx.UI.Common/Resources/Logo_Amiibo.png");
-
- _ = LoadContentAsync();
- }
-
- public AmiiboWindowViewModel() { }
-
- public string TitleId { get; set; }
- public string LastScannedAmiiboId { get; set; }
-
- public UserResult Response { get; private set; }
-
- public bool UseRandomUuid
- {
- get => _useRandomUuid;
- set
- {
- _useRandomUuid = value;
-
- OnPropertyChanged();
- }
- }
-
- public bool ShowAllAmiibo
- {
- get => _showAllAmiibo;
- set
- {
- _showAllAmiibo = value;
-
- ParseAmiiboData();
-
- OnPropertyChanged();
- }
- }
-
- public AvaloniaList<AmiiboApi> AmiiboList
- {
- get => _amiibos;
- set
- {
- _amiibos = value;
-
- OnPropertyChanged();
- }
- }
-
- public ObservableCollection<string> AmiiboSeries
- {
- get => _amiiboSeries;
- set
- {
- _amiiboSeries = value;
- OnPropertyChanged();
- }
- }
-
- public int SeriesSelectedIndex
- {
- get => _seriesSelectedIndex;
- set
- {
- _seriesSelectedIndex = value;
-
- FilterAmiibo();
-
- OnPropertyChanged();
- }
- }
-
- public int AmiiboSelectedIndex
- {
- get => _amiiboSelectedIndex;
- set
- {
- _amiiboSelectedIndex = value;
-
- EnableScanning = _amiiboSelectedIndex >= 0 && _amiiboSelectedIndex < _amiibos.Count;
-
- SetAmiiboDetails();
-
- OnPropertyChanged();
- }
- }
-
- public Bitmap AmiiboImage
- {
- get => _amiiboImage;
- set
- {
- _amiiboImage = value;
-
- OnPropertyChanged();
- }
- }
-
- public string Usage
- {
- get => _usage;
- set
- {
- _usage = value;
-
- OnPropertyChanged();
- }
- }
-
- public bool EnableScanning
- {
- get => _enableScanning;
- set
- {
- _enableScanning = value;
-
- OnPropertyChanged();
- }
- }
-
- public void Dispose()
- {
- GC.SuppressFinalize(this);
- _httpClient.Dispose();
- }
-
- private static bool TryGetAmiiboJson(string json, out AmiiboJson amiiboJson)
- {
- if (string.IsNullOrEmpty(json))
- {
- amiiboJson = JsonHelper.Deserialize(DefaultJson, _serializerContext.AmiiboJson);
-
- return false;
- }
-
- try
- {
- amiiboJson = JsonHelper.Deserialize(json, _serializerContext.AmiiboJson);
-
- return true;
- }
- catch (JsonException exception)
- {
- Logger.Error?.Print(LogClass.Application, $"Unable to deserialize amiibo data: {exception}");
- amiiboJson = JsonHelper.Deserialize(DefaultJson, _serializerContext.AmiiboJson);
-
- return false;
- }
- }
-
- private async Task<AmiiboJson> GetMostRecentAmiiboListOrDefaultJson()
- {
- bool localIsValid = false;
- bool remoteIsValid = false;
- AmiiboJson amiiboJson = new();
-
- try
- {
- try
- {
- if (File.Exists(_amiiboJsonPath))
- {
- localIsValid = TryGetAmiiboJson(await File.ReadAllTextAsync(_amiiboJsonPath), out amiiboJson);
- }
- }
- catch (Exception exception)
- {
- Logger.Warning?.Print(LogClass.Application, $"Unable to read data from '{_amiiboJsonPath}': {exception}");
- }
-
- if (!localIsValid || await NeedsUpdate(amiiboJson.LastUpdated))
- {
- remoteIsValid = TryGetAmiiboJson(await DownloadAmiiboJson(), out amiiboJson);
- }
- }
- catch (Exception exception)
- {
- if (!(localIsValid || remoteIsValid))
- {
- Logger.Error?.Print(LogClass.Application, $"Couldn't get valid amiibo data: {exception}");
-
- // Neither local or remote files are valid JSON, close window.
- ShowInfoDialog();
- Close();
- }
- else if (!remoteIsValid)
- {
- Logger.Warning?.Print(LogClass.Application, $"Couldn't update amiibo data: {exception}");
-
- // Only the local file is valid, the local one should be used
- // but the user should be warned.
- ShowInfoDialog();
- }
- }
-
- return amiiboJson;
- }
-
- private async Task LoadContentAsync()
- {
- AmiiboJson amiiboJson = await GetMostRecentAmiiboListOrDefaultJson();
-
- _amiiboList = amiiboJson.Amiibo.OrderBy(amiibo => amiibo.AmiiboSeries).ToList();
-
- ParseAmiiboData();
- }
-
- private void ParseAmiiboData()
- {
- _amiiboSeries.Clear();
- _amiibos.Clear();
-
- for (int i = 0; i < _amiiboList.Count; i++)
- {
- if (!_amiiboSeries.Contains(_amiiboList[i].AmiiboSeries))
- {
- if (!ShowAllAmiibo)
- {
- foreach (AmiiboApiGamesSwitch game in _amiiboList[i].GamesSwitch)
- {
- if (game != null)
- {
- if (game.GameId.Contains(TitleId))
- {
- AmiiboSeries.Add(_amiiboList[i].AmiiboSeries);
-
- break;
- }
- }
- }
- }
- else
- {
- AmiiboSeries.Add(_amiiboList[i].AmiiboSeries);
- }
- }
- }
-
- if (LastScannedAmiiboId != "")
- {
- SelectLastScannedAmiibo();
- }
- else
- {
- SeriesSelectedIndex = 0;
- }
- }
-
- private void SelectLastScannedAmiibo()
- {
- AmiiboApi scanned = _amiiboList.Find(amiibo => amiibo.GetId() == LastScannedAmiiboId);
-
- SeriesSelectedIndex = AmiiboSeries.IndexOf(scanned.AmiiboSeries);
- AmiiboSelectedIndex = AmiiboList.IndexOf(scanned);
- }
-
- private void FilterAmiibo()
- {
- _amiibos.Clear();
-
- if (_seriesSelectedIndex < 0)
- {
- return;
- }
-
- List<AmiiboApi> amiiboSortedList = _amiiboList
- .Where(amiibo => amiibo.AmiiboSeries == _amiiboSeries[SeriesSelectedIndex])
- .OrderBy(amiibo => amiibo.Name).ToList();
-
- for (int i = 0; i < amiiboSortedList.Count; i++)
- {
- if (!_amiibos.Contains(amiiboSortedList[i]))
- {
- if (!_showAllAmiibo)
- {
- foreach (AmiiboApiGamesSwitch game in amiiboSortedList[i].GamesSwitch)
- {
- if (game != null)
- {
- if (game.GameId.Contains(TitleId))
- {
- _amiibos.Add(amiiboSortedList[i]);
-
- break;
- }
- }
- }
- }
- else
- {
- _amiibos.Add(amiiboSortedList[i]);
- }
- }
- }
-
- AmiiboSelectedIndex = 0;
- }
-
- private void SetAmiiboDetails()
- {
- ResetAmiiboPreview();
-
- Usage = string.Empty;
-
- if (_amiiboSelectedIndex < 0)
- {
- return;
- }
-
- AmiiboApi selected = _amiibos[_amiiboSelectedIndex];
-
- string imageUrl = _amiiboList.Find(amiibo => amiibo.Equals(selected)).Image;
-
- StringBuilder usageStringBuilder = new();
-
- for (int i = 0; i < _amiiboList.Count; i++)
- {
- if (_amiiboList[i].Equals(selected))
- {
- bool writable = false;
-
- foreach (AmiiboApiGamesSwitch item in _amiiboList[i].GamesSwitch)
- {
- if (item.GameId.Contains(TitleId))
- {
- foreach (AmiiboApiUsage usageItem in item.AmiiboUsage)
- {
- usageStringBuilder.Append($"{Environment.NewLine}- {usageItem.Usage.Replace("/", Environment.NewLine + "-")}");
-
- writable = usageItem.Write;
- }
- }
- }
-
- if (usageStringBuilder.Length == 0)
- {
- usageStringBuilder.Append($"{LocaleManager.Instance[LocaleKeys.Unknown]}.");
- }
-
- Usage = $"{LocaleManager.Instance[LocaleKeys.Usage]} {(writable ? $" ({LocaleManager.Instance[LocaleKeys.Writable]})" : "")} : {usageStringBuilder}";
- }
- }
-
- _ = UpdateAmiiboPreview(imageUrl);
- }
-
- private async Task<bool> NeedsUpdate(DateTime oldLastModified)
- {
- try
- {
- HttpResponseMessage response = await _httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, "https://amiibo.ryujinx.org/"));
-
- if (response.IsSuccessStatusCode)
- {
- return response.Content.Headers.LastModified != oldLastModified;
- }
- }
- catch (HttpRequestException exception)
- {
- Logger.Error?.Print(LogClass.Application, $"Unable to check for amiibo data updates: {exception}");
- }
-
- return false;
- }
-
- private async Task<string> DownloadAmiiboJson()
- {
- try
- {
- HttpResponseMessage response = await _httpClient.GetAsync("https://amiibo.ryujinx.org/");
-
- if (response.IsSuccessStatusCode)
- {
- string amiiboJsonString = await response.Content.ReadAsStringAsync();
-
- try
- {
- using FileStream dlcJsonStream = File.Create(_amiiboJsonPath, 4096, FileOptions.WriteThrough);
- dlcJsonStream.Write(Encoding.UTF8.GetBytes(amiiboJsonString));
- }
- catch (Exception exception)
- {
- Logger.Warning?.Print(LogClass.Application, $"Couldn't write amiibo data to file '{_amiiboJsonPath}: {exception}'");
- }
-
- return amiiboJsonString;
- }
-
- Logger.Error?.Print(LogClass.Application, $"Failed to download amiibo data. Response status code: {response.StatusCode}");
- }
- catch (HttpRequestException exception)
- {
- Logger.Error?.Print(LogClass.Application, $"Failed to request amiibo data: {exception}");
- }
-
- await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.DialogAmiiboApiTitle],
- LocaleManager.Instance[LocaleKeys.DialogAmiiboApiFailFetchMessage],
- LocaleManager.Instance[LocaleKeys.InputDialogOk],
- "",
- LocaleManager.Instance[LocaleKeys.RyujinxInfo]);
-
- return null;
- }
-
- private void Close()
- {
- Dispatcher.UIThread.Post(_owner.Close);
- }
-
- private async Task UpdateAmiiboPreview(string imageUrl)
- {
- HttpResponseMessage response = await _httpClient.GetAsync(imageUrl);
-
- if (response.IsSuccessStatusCode)
- {
- byte[] amiiboPreviewBytes = await response.Content.ReadAsByteArrayAsync();
- using MemoryStream memoryStream = new(amiiboPreviewBytes);
-
- Bitmap bitmap = new(memoryStream);
-
- double ratio = Math.Min(AmiiboImageSize / bitmap.Size.Width,
- AmiiboImageSize / bitmap.Size.Height);
-
- int resizeHeight = (int)(bitmap.Size.Height * ratio);
- int resizeWidth = (int)(bitmap.Size.Width * ratio);
-
- AmiiboImage = bitmap.CreateScaledBitmap(new PixelSize(resizeWidth, resizeHeight));
- }
- else
- {
- Logger.Error?.Print(LogClass.Application, $"Failed to get amiibo preview. Response status code: {response.StatusCode}");
- }
- }
-
- private void ResetAmiiboPreview()
- {
- using MemoryStream memoryStream = new(_amiiboLogoBytes);
-
- Bitmap bitmap = new(memoryStream);
-
- AmiiboImage = bitmap;
- }
-
- private static async void ShowInfoDialog()
- {
- await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.DialogAmiiboApiTitle],
- LocaleManager.Instance[LocaleKeys.DialogAmiiboApiConnectErrorMessage],
- LocaleManager.Instance[LocaleKeys.InputDialogOk],
- "",
- LocaleManager.Instance[LocaleKeys.RyujinxInfo]);
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/ViewModels/BaseModel.cs b/src/Ryujinx.Ava/UI/ViewModels/BaseModel.cs
deleted file mode 100644
index 4db9cf81..00000000
--- a/src/Ryujinx.Ava/UI/ViewModels/BaseModel.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System.ComponentModel;
-using System.Runtime.CompilerServices;
-
-namespace Ryujinx.Ava.UI.ViewModels
-{
- public class BaseModel : INotifyPropertyChanged
- {
- public event PropertyChangedEventHandler PropertyChanged;
-
- protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs
deleted file mode 100644
index 71ad2c12..00000000
--- a/src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs
+++ /dev/null
@@ -1,897 +0,0 @@
-using Avalonia;
-using Avalonia.Collections;
-using Avalonia.Controls;
-using Avalonia.Controls.ApplicationLifetimes;
-using Avalonia.Svg.Skia;
-using Avalonia.Threading;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.Input;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.Models;
-using Ryujinx.Ava.UI.Views.Input;
-using Ryujinx.Ava.UI.Windows;
-using Ryujinx.Common;
-using Ryujinx.Common.Configuration;
-using Ryujinx.Common.Configuration.Hid;
-using Ryujinx.Common.Configuration.Hid.Controller;
-using Ryujinx.Common.Configuration.Hid.Controller.Motion;
-using Ryujinx.Common.Configuration.Hid.Keyboard;
-using Ryujinx.Common.Logging;
-using Ryujinx.Common.Utilities;
-using Ryujinx.Input;
-using Ryujinx.UI.Common.Configuration;
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.IO;
-using System.Linq;
-using System.Text.Json;
-using ConfigGamepadInputId = Ryujinx.Common.Configuration.Hid.Controller.GamepadInputId;
-using ConfigStickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId;
-using Key = Ryujinx.Common.Configuration.Hid.Key;
-
-namespace Ryujinx.Ava.UI.ViewModels
-{
- public class ControllerInputViewModel : BaseModel, IDisposable
- {
- private const string Disabled = "disabled";
- private const string ProControllerResource = "Ryujinx.UI.Common/Resources/Controller_ProCon.svg";
- private const string JoyConPairResource = "Ryujinx.UI.Common/Resources/Controller_JoyConPair.svg";
- private const string JoyConLeftResource = "Ryujinx.UI.Common/Resources/Controller_JoyConLeft.svg";
- private const string JoyConRightResource = "Ryujinx.UI.Common/Resources/Controller_JoyConRight.svg";
- private const string KeyboardString = "keyboard";
- private const string ControllerString = "controller";
- private readonly MainWindow _mainWindow;
-
- private PlayerIndex _playerId;
- private int _controller;
- private int _controllerNumber;
- private string _controllerImage;
- private int _device;
- private object _configuration;
- private string _profileName;
- private bool _isLoaded;
-
- private static readonly InputConfigJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
-
- public IGamepadDriver AvaloniaKeyboardDriver { get; }
- public IGamepad SelectedGamepad { get; private set; }
-
- public ObservableCollection<PlayerModel> PlayerIndexes { get; set; }
- public ObservableCollection<(DeviceType Type, string Id, string Name)> Devices { get; set; }
- internal ObservableCollection<ControllerModel> Controllers { get; set; }
- public AvaloniaList<string> ProfilesList { get; set; }
- public AvaloniaList<string> DeviceList { get; set; }
-
- // XAML Flags
- public bool ShowSettings => _device > 0;
- public bool IsController => _device > 1;
- public bool IsKeyboard => !IsController;
- public bool IsRight { get; set; }
- public bool IsLeft { get; set; }
-
- public bool IsModified { get; set; }
-
- public object Configuration
- {
- get => _configuration;
- set
- {
- _configuration = value;
-
- OnPropertyChanged();
- }
- }
-
- public PlayerIndex PlayerId
- {
- get => _playerId;
- set
- {
- if (IsModified)
- {
- return;
- }
-
- IsModified = false;
- _playerId = value;
-
- if (!Enum.IsDefined(typeof(PlayerIndex), _playerId))
- {
- _playerId = PlayerIndex.Player1;
- }
-
- LoadConfiguration();
- LoadDevice();
- LoadProfiles();
-
- _isLoaded = true;
-
- OnPropertyChanged();
- }
- }
-
- public int Controller
- {
- get => _controller;
- set
- {
- _controller = value;
-
- if (_controller == -1)
- {
- _controller = 0;
- }
-
- if (Controllers.Count > 0 && value < Controllers.Count && _controller > -1)
- {
- ControllerType controller = Controllers[_controller].Type;
-
- IsLeft = true;
- IsRight = true;
-
- switch (controller)
- {
- case ControllerType.Handheld:
- ControllerImage = JoyConPairResource;
- break;
- case ControllerType.ProController:
- ControllerImage = ProControllerResource;
- break;
- case ControllerType.JoyconPair:
- ControllerImage = JoyConPairResource;
- break;
- case ControllerType.JoyconLeft:
- ControllerImage = JoyConLeftResource;
- IsRight = false;
- break;
- case ControllerType.JoyconRight:
- ControllerImage = JoyConRightResource;
- IsLeft = false;
- break;
- }
-
- LoadInputDriver();
- LoadProfiles();
- }
-
- OnPropertyChanged();
- NotifyChanges();
- }
- }
-
- public string ControllerImage
- {
- get => _controllerImage;
- set
- {
- _controllerImage = value;
-
- OnPropertyChanged();
- OnPropertyChanged(nameof(Image));
- }
- }
-
- public SvgImage Image
- {
- get
- {
- SvgImage image = new();
-
- if (!string.IsNullOrWhiteSpace(_controllerImage))
- {
- SvgSource source = new(default(Uri));
-
- source.Load(EmbeddedResources.GetStream(_controllerImage));
-
- image.Source = source;
- }
-
- return image;
- }
- }
-
- public string ProfileName
- {
- get => _profileName; set
- {
- _profileName = value;
-
- OnPropertyChanged();
- }
- }
-
- public int Device
- {
- get => _device;
- set
- {
- _device = value < 0 ? 0 : value;
-
- if (_device >= Devices.Count)
- {
- return;
- }
-
- var selected = Devices[_device].Type;
-
- if (selected != DeviceType.None)
- {
- LoadControllers();
-
- if (_isLoaded)
- {
- LoadConfiguration(LoadDefaultConfiguration());
- }
- }
-
- OnPropertyChanged();
- NotifyChanges();
- }
- }
-
- public InputConfig Config { get; set; }
-
- public ControllerInputViewModel(UserControl owner) : this()
- {
- if (Program.PreviewerDetached)
- {
- _mainWindow =
- (MainWindow)((IClassicDesktopStyleApplicationLifetime)Application.Current
- .ApplicationLifetime).MainWindow;
-
- AvaloniaKeyboardDriver = new AvaloniaKeyboardDriver(owner);
-
- _mainWindow.InputManager.GamepadDriver.OnGamepadConnected += HandleOnGamepadConnected;
- _mainWindow.InputManager.GamepadDriver.OnGamepadDisconnected += HandleOnGamepadDisconnected;
-
- _mainWindow.ViewModel.AppHost?.NpadManager.BlockInputUpdates();
-
- _isLoaded = false;
-
- LoadDevices();
-
- PlayerId = PlayerIndex.Player1;
- }
- }
-
- public ControllerInputViewModel()
- {
- PlayerIndexes = new ObservableCollection<PlayerModel>();
- Controllers = new ObservableCollection<ControllerModel>();
- Devices = new ObservableCollection<(DeviceType Type, string Id, string Name)>();
- ProfilesList = new AvaloniaList<string>();
- DeviceList = new AvaloniaList<string>();
-
- ControllerImage = ProControllerResource;
-
- PlayerIndexes.Add(new(PlayerIndex.Player1, LocaleManager.Instance[LocaleKeys.ControllerSettingsPlayer1]));
- PlayerIndexes.Add(new(PlayerIndex.Player2, LocaleManager.Instance[LocaleKeys.ControllerSettingsPlayer2]));
- PlayerIndexes.Add(new(PlayerIndex.Player3, LocaleManager.Instance[LocaleKeys.ControllerSettingsPlayer3]));
- PlayerIndexes.Add(new(PlayerIndex.Player4, LocaleManager.Instance[LocaleKeys.ControllerSettingsPlayer4]));
- PlayerIndexes.Add(new(PlayerIndex.Player5, LocaleManager.Instance[LocaleKeys.ControllerSettingsPlayer5]));
- PlayerIndexes.Add(new(PlayerIndex.Player6, LocaleManager.Instance[LocaleKeys.ControllerSettingsPlayer6]));
- PlayerIndexes.Add(new(PlayerIndex.Player7, LocaleManager.Instance[LocaleKeys.ControllerSettingsPlayer7]));
- PlayerIndexes.Add(new(PlayerIndex.Player8, LocaleManager.Instance[LocaleKeys.ControllerSettingsPlayer8]));
- PlayerIndexes.Add(new(PlayerIndex.Handheld, LocaleManager.Instance[LocaleKeys.ControllerSettingsHandheld]));
- }
-
- private void LoadConfiguration(InputConfig inputConfig = null)
- {
- Config = inputConfig ?? ConfigurationState.Instance.Hid.InputConfig.Value.Find(inputConfig => inputConfig.PlayerIndex == _playerId);
-
- if (Config is StandardKeyboardInputConfig keyboardInputConfig)
- {
- Configuration = new InputConfiguration<Key, ConfigStickInputId>(keyboardInputConfig);
- }
-
- if (Config is StandardControllerInputConfig controllerInputConfig)
- {
- Configuration = new InputConfiguration<ConfigGamepadInputId, ConfigStickInputId>(controllerInputConfig);
- }
- }
-
- public void LoadDevice()
- {
- if (Config == null || Config.Backend == InputBackendType.Invalid)
- {
- Device = 0;
- }
- else
- {
- var type = DeviceType.None;
-
- if (Config is StandardKeyboardInputConfig)
- {
- type = DeviceType.Keyboard;
- }
-
- if (Config is StandardControllerInputConfig)
- {
- type = DeviceType.Controller;
- }
-
- var item = Devices.FirstOrDefault(x => x.Type == type && x.Id == Config.Id);
- if (item != default)
- {
- Device = Devices.ToList().FindIndex(x => x.Id == item.Id);
- }
- else
- {
- Device = 0;
- }
- }
- }
-
- public async void ShowMotionConfig()
- {
- await MotionInputView.Show(this);
- }
-
- public async void ShowRumbleConfig()
- {
- await RumbleInputView.Show(this);
- }
-
- private void LoadInputDriver()
- {
- if (_device < 0)
- {
- return;
- }
-
- string id = GetCurrentGamepadId();
- var type = Devices[Device].Type;
-
- if (type == DeviceType.None)
- {
- return;
- }
-
- if (type == DeviceType.Keyboard)
- {
- if (_mainWindow.InputManager.KeyboardDriver is AvaloniaKeyboardDriver)
- {
- // NOTE: To get input in this window, we need to bind a custom keyboard driver instead of using the InputManager one as the main window isn't focused...
- SelectedGamepad = AvaloniaKeyboardDriver.GetGamepad(id);
- }
- else
- {
- SelectedGamepad = _mainWindow.InputManager.KeyboardDriver.GetGamepad(id);
- }
- }
- else
- {
- SelectedGamepad = _mainWindow.InputManager.GamepadDriver.GetGamepad(id);
- }
- }
-
- private void HandleOnGamepadDisconnected(string id)
- {
- Dispatcher.UIThread.Post(() =>
- {
- LoadDevices();
- });
- }
-
- private void HandleOnGamepadConnected(string id)
- {
- Dispatcher.UIThread.Post(() =>
- {
- LoadDevices();
- });
- }
-
- private string GetCurrentGamepadId()
- {
- if (_device < 0)
- {
- return string.Empty;
- }
-
- var device = Devices[Device];
-
- if (device.Type == DeviceType.None)
- {
- return null;
- }
-
- return device.Id.Split(" ")[0];
- }
-
- public void LoadControllers()
- {
- Controllers.Clear();
-
- if (_playerId == PlayerIndex.Handheld)
- {
- Controllers.Add(new(ControllerType.Handheld, LocaleManager.Instance[LocaleKeys.ControllerSettingsControllerTypeHandheld]));
-
- Controller = 0;
- }
- else
- {
- Controllers.Add(new(ControllerType.ProController, LocaleManager.Instance[LocaleKeys.ControllerSettingsControllerTypeProController]));
- Controllers.Add(new(ControllerType.JoyconPair, LocaleManager.Instance[LocaleKeys.ControllerSettingsControllerTypeJoyConPair]));
- Controllers.Add(new(ControllerType.JoyconLeft, LocaleManager.Instance[LocaleKeys.ControllerSettingsControllerTypeJoyConLeft]));
- Controllers.Add(new(ControllerType.JoyconRight, LocaleManager.Instance[LocaleKeys.ControllerSettingsControllerTypeJoyConRight]));
-
- if (Config != null && Controllers.ToList().FindIndex(x => x.Type == Config.ControllerType) != -1)
- {
- Controller = Controllers.ToList().FindIndex(x => x.Type == Config.ControllerType);
- }
- else
- {
- Controller = 0;
- }
- }
- }
-
- private static string GetShortGamepadName(string str)
- {
- const string Ellipsis = "...";
- const int MaxSize = 50;
-
- if (str.Length > MaxSize)
- {
- return $"{str.AsSpan(0, MaxSize - Ellipsis.Length)}{Ellipsis}";
- }
-
- return str;
- }
-
- private static string GetShortGamepadId(string str)
- {
- const string Hyphen = "-";
- const int Offset = 1;
-
- return str[(str.IndexOf(Hyphen) + Offset)..];
- }
-
- public void LoadDevices()
- {
- lock (Devices)
- {
- Devices.Clear();
- DeviceList.Clear();
- Devices.Add((DeviceType.None, Disabled, LocaleManager.Instance[LocaleKeys.ControllerSettingsDeviceDisabled]));
-
- foreach (string id in _mainWindow.InputManager.KeyboardDriver.GamepadsIds)
- {
- using IGamepad gamepad = _mainWindow.InputManager.KeyboardDriver.GetGamepad(id);
-
- if (gamepad != null)
- {
- Devices.Add((DeviceType.Keyboard, id, $"{GetShortGamepadName(gamepad.Name)}"));
- }
- }
-
- foreach (string id in _mainWindow.InputManager.GamepadDriver.GamepadsIds)
- {
- using IGamepad gamepad = _mainWindow.InputManager.GamepadDriver.GetGamepad(id);
-
- if (gamepad != null)
- {
- if (Devices.Any(controller => GetShortGamepadId(controller.Id) == GetShortGamepadId(gamepad.Id)))
- {
- _controllerNumber++;
- }
-
- Devices.Add((DeviceType.Controller, id, $"{GetShortGamepadName(gamepad.Name)} ({_controllerNumber})"));
- }
- }
-
- _controllerNumber = 0;
-
- DeviceList.AddRange(Devices.Select(x => x.Name));
- Device = Math.Min(Device, DeviceList.Count);
- }
- }
-
- private string GetProfileBasePath()
- {
- string path = AppDataManager.ProfilesDirPath;
- var type = Devices[Device == -1 ? 0 : Device].Type;
-
- if (type == DeviceType.Keyboard)
- {
- path = Path.Combine(path, KeyboardString);
- }
- else if (type == DeviceType.Controller)
- {
- path = Path.Combine(path, ControllerString);
- }
-
- return path;
- }
-
- private void LoadProfiles()
- {
- ProfilesList.Clear();
-
- string basePath = GetProfileBasePath();
-
- if (!Directory.Exists(basePath))
- {
- Directory.CreateDirectory(basePath);
- }
-
- ProfilesList.Add((LocaleManager.Instance[LocaleKeys.ControllerSettingsProfileDefault]));
-
- foreach (string profile in Directory.GetFiles(basePath, "*.json", SearchOption.AllDirectories))
- {
- ProfilesList.Add(Path.GetFileNameWithoutExtension(profile));
- }
-
- if (string.IsNullOrWhiteSpace(ProfileName))
- {
- ProfileName = LocaleManager.Instance[LocaleKeys.ControllerSettingsProfileDefault];
- }
- }
-
- public InputConfig LoadDefaultConfiguration()
- {
- var activeDevice = Devices.FirstOrDefault();
-
- if (Devices.Count > 0 && Device < Devices.Count && Device >= 0)
- {
- activeDevice = Devices[Device];
- }
-
- InputConfig config;
- if (activeDevice.Type == DeviceType.Keyboard)
- {
- string id = activeDevice.Id;
-
- config = new StandardKeyboardInputConfig
- {
- Version = InputConfig.CurrentVersion,
- Backend = InputBackendType.WindowKeyboard,
- Id = id,
- ControllerType = ControllerType.ProController,
- LeftJoycon = new LeftJoyconCommonConfig<Key>
- {
- DpadUp = Key.Up,
- DpadDown = Key.Down,
- DpadLeft = Key.Left,
- DpadRight = Key.Right,
- ButtonMinus = Key.Minus,
- ButtonL = Key.E,
- ButtonZl = Key.Q,
- ButtonSl = Key.Unbound,
- ButtonSr = Key.Unbound,
- },
- LeftJoyconStick =
- new JoyconConfigKeyboardStick<Key>
- {
- StickUp = Key.W,
- StickDown = Key.S,
- StickLeft = Key.A,
- StickRight = Key.D,
- StickButton = Key.F,
- },
- RightJoycon = new RightJoyconCommonConfig<Key>
- {
- ButtonA = Key.Z,
- ButtonB = Key.X,
- ButtonX = Key.C,
- ButtonY = Key.V,
- ButtonPlus = Key.Plus,
- ButtonR = Key.U,
- ButtonZr = Key.O,
- ButtonSl = Key.Unbound,
- ButtonSr = Key.Unbound,
- },
- RightJoyconStick = new JoyconConfigKeyboardStick<Key>
- {
- StickUp = Key.I,
- StickDown = Key.K,
- StickLeft = Key.J,
- StickRight = Key.L,
- StickButton = Key.H,
- },
- };
- }
- else if (activeDevice.Type == DeviceType.Controller)
- {
- bool isNintendoStyle = Devices.ToList().Find(x => x.Id == activeDevice.Id).Name.Contains("Nintendo");
-
- string id = activeDevice.Id.Split(" ")[0];
-
- config = new StandardControllerInputConfig
- {
- Version = InputConfig.CurrentVersion,
- Backend = InputBackendType.GamepadSDL2,
- Id = id,
- ControllerType = ControllerType.ProController,
- DeadzoneLeft = 0.1f,
- DeadzoneRight = 0.1f,
- RangeLeft = 1.0f,
- RangeRight = 1.0f,
- TriggerThreshold = 0.5f,
- LeftJoycon = new LeftJoyconCommonConfig<ConfigGamepadInputId>
- {
- DpadUp = ConfigGamepadInputId.DpadUp,
- DpadDown = ConfigGamepadInputId.DpadDown,
- DpadLeft = ConfigGamepadInputId.DpadLeft,
- DpadRight = ConfigGamepadInputId.DpadRight,
- ButtonMinus = ConfigGamepadInputId.Minus,
- ButtonL = ConfigGamepadInputId.LeftShoulder,
- ButtonZl = ConfigGamepadInputId.LeftTrigger,
- ButtonSl = ConfigGamepadInputId.Unbound,
- ButtonSr = ConfigGamepadInputId.Unbound,
- },
- LeftJoyconStick = new JoyconConfigControllerStick<ConfigGamepadInputId, ConfigStickInputId>
- {
- Joystick = ConfigStickInputId.Left,
- StickButton = ConfigGamepadInputId.LeftStick,
- InvertStickX = false,
- InvertStickY = false,
- },
- RightJoycon = new RightJoyconCommonConfig<ConfigGamepadInputId>
- {
- ButtonA = isNintendoStyle ? ConfigGamepadInputId.A : ConfigGamepadInputId.B,
- ButtonB = isNintendoStyle ? ConfigGamepadInputId.B : ConfigGamepadInputId.A,
- ButtonX = isNintendoStyle ? ConfigGamepadInputId.X : ConfigGamepadInputId.Y,
- ButtonY = isNintendoStyle ? ConfigGamepadInputId.Y : ConfigGamepadInputId.X,
- ButtonPlus = ConfigGamepadInputId.Plus,
- ButtonR = ConfigGamepadInputId.RightShoulder,
- ButtonZr = ConfigGamepadInputId.RightTrigger,
- ButtonSl = ConfigGamepadInputId.Unbound,
- ButtonSr = ConfigGamepadInputId.Unbound,
- },
- RightJoyconStick = new JoyconConfigControllerStick<ConfigGamepadInputId, ConfigStickInputId>
- {
- Joystick = ConfigStickInputId.Right,
- StickButton = ConfigGamepadInputId.RightStick,
- InvertStickX = false,
- InvertStickY = false,
- },
- Motion = new StandardMotionConfigController
- {
- MotionBackend = MotionInputBackendType.GamepadDriver,
- EnableMotion = true,
- Sensitivity = 100,
- GyroDeadzone = 1,
- },
- Rumble = new RumbleConfigController
- {
- StrongRumble = 1f,
- WeakRumble = 1f,
- EnableRumble = false,
- },
- };
- }
- else
- {
- config = new InputConfig();
- }
-
- config.PlayerIndex = _playerId;
-
- return config;
- }
-
- public async void LoadProfile()
- {
- if (Device == 0)
- {
- return;
- }
-
- InputConfig config = null;
-
- if (string.IsNullOrWhiteSpace(ProfileName))
- {
- return;
- }
-
- if (ProfileName == LocaleManager.Instance[LocaleKeys.ControllerSettingsProfileDefault])
- {
- config = LoadDefaultConfiguration();
- }
- else
- {
- string path = Path.Combine(GetProfileBasePath(), ProfileName + ".json");
-
- if (!File.Exists(path))
- {
- var index = ProfilesList.IndexOf(ProfileName);
- if (index != -1)
- {
- ProfilesList.RemoveAt(index);
- }
- return;
- }
-
- try
- {
- config = JsonHelper.DeserializeFromFile(path, _serializerContext.InputConfig);
- }
- catch (JsonException) { }
- catch (InvalidOperationException)
- {
- Logger.Error?.Print(LogClass.Configuration, $"Profile {ProfileName} is incompatible with the current input configuration system.");
-
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogProfileInvalidProfileErrorMessage, ProfileName));
-
- return;
- }
- }
-
- if (config != null)
- {
- _isLoaded = false;
-
- LoadConfiguration(config);
-
- LoadDevice();
-
- _isLoaded = true;
-
- NotifyChanges();
- }
- }
-
- public async void SaveProfile()
- {
- if (Device == 0)
- {
- return;
- }
-
- if (Configuration == null)
- {
- return;
- }
-
- if (ProfileName == LocaleManager.Instance[LocaleKeys.ControllerSettingsProfileDefault])
- {
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogProfileDefaultProfileOverwriteErrorMessage]);
-
- return;
- }
-
- bool validFileName = ProfileName.IndexOfAny(Path.GetInvalidFileNameChars()) == -1;
-
- if (validFileName)
- {
- string path = Path.Combine(GetProfileBasePath(), ProfileName + ".json");
-
- InputConfig config = null;
-
- if (IsKeyboard)
- {
- config = (Configuration as InputConfiguration<Key, ConfigStickInputId>).GetConfig();
- }
- else if (IsController)
- {
- config = (Configuration as InputConfiguration<GamepadInputId, ConfigStickInputId>).GetConfig();
- }
-
- config.ControllerType = Controllers[_controller].Type;
-
- string jsonString = JsonHelper.Serialize(config, _serializerContext.InputConfig);
-
- await File.WriteAllTextAsync(path, jsonString);
-
- LoadProfiles();
- }
- else
- {
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogProfileInvalidProfileNameErrorMessage]);
- }
- }
-
- public async void RemoveProfile()
- {
- if (Device == 0 || ProfileName == LocaleManager.Instance[LocaleKeys.ControllerSettingsProfileDefault] || ProfilesList.IndexOf(ProfileName) == -1)
- {
- return;
- }
-
- UserResult result = await ContentDialogHelper.CreateConfirmationDialog(
- LocaleManager.Instance[LocaleKeys.DialogProfileDeleteProfileTitle],
- LocaleManager.Instance[LocaleKeys.DialogProfileDeleteProfileMessage],
- LocaleManager.Instance[LocaleKeys.InputDialogYes],
- LocaleManager.Instance[LocaleKeys.InputDialogNo],
- LocaleManager.Instance[LocaleKeys.RyujinxConfirm]);
-
- if (result == UserResult.Yes)
- {
- string path = Path.Combine(GetProfileBasePath(), ProfileName + ".json");
-
- if (File.Exists(path))
- {
- File.Delete(path);
- }
-
- LoadProfiles();
- }
- }
-
- public void Save()
- {
- IsModified = false;
-
- List<InputConfig> newConfig = new();
-
- newConfig.AddRange(ConfigurationState.Instance.Hid.InputConfig.Value);
-
- newConfig.Remove(newConfig.Find(x => x == null));
-
- if (Device == 0)
- {
- newConfig.Remove(newConfig.Find(x => x.PlayerIndex == this.PlayerId));
- }
- else
- {
- var device = Devices[Device];
-
- if (device.Type == DeviceType.Keyboard)
- {
- var inputConfig = Configuration as InputConfiguration<Key, ConfigStickInputId>;
- inputConfig.Id = device.Id;
- }
- else
- {
- var inputConfig = Configuration as InputConfiguration<GamepadInputId, ConfigStickInputId>;
- inputConfig.Id = device.Id.Split(" ")[0];
- }
-
- var config = !IsController
- ? (Configuration as InputConfiguration<Key, ConfigStickInputId>).GetConfig()
- : (Configuration as InputConfiguration<GamepadInputId, ConfigStickInputId>).GetConfig();
- config.ControllerType = Controllers[_controller].Type;
- config.PlayerIndex = _playerId;
-
- int i = newConfig.FindIndex(x => x.PlayerIndex == PlayerId);
- if (i == -1)
- {
- newConfig.Add(config);
- }
- else
- {
- newConfig[i] = config;
- }
- }
-
- _mainWindow.ViewModel.AppHost?.NpadManager.ReloadConfiguration(newConfig, ConfigurationState.Instance.Hid.EnableKeyboard, ConfigurationState.Instance.Hid.EnableMouse);
-
- // Atomically replace and signal input change.
- // NOTE: Do not modify InputConfig.Value directly as other code depends on the on-change event.
- ConfigurationState.Instance.Hid.InputConfig.Value = newConfig;
-
- ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
- }
-
- public void NotifyChange(string property)
- {
- OnPropertyChanged(property);
- }
-
- public void NotifyChanges()
- {
- OnPropertyChanged(nameof(Configuration));
- OnPropertyChanged(nameof(IsController));
- OnPropertyChanged(nameof(ShowSettings));
- OnPropertyChanged(nameof(IsKeyboard));
- OnPropertyChanged(nameof(IsRight));
- OnPropertyChanged(nameof(IsLeft));
- }
-
- public void Dispose()
- {
- GC.SuppressFinalize(this);
-
- _mainWindow.InputManager.GamepadDriver.OnGamepadConnected -= HandleOnGamepadConnected;
- _mainWindow.InputManager.GamepadDriver.OnGamepadDisconnected -= HandleOnGamepadDisconnected;
-
- _mainWindow.ViewModel.AppHost?.NpadManager.UnblockInputUpdates();
-
- SelectedGamepad?.Dispose();
-
- AvaloniaKeyboardDriver.Dispose();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs
deleted file mode 100644
index 2cd714f4..00000000
--- a/src/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs
+++ /dev/null
@@ -1,340 +0,0 @@
-using Avalonia.Collections;
-using Avalonia.Controls.ApplicationLifetimes;
-using Avalonia.Platform.Storage;
-using Avalonia.Threading;
-using DynamicData;
-using LibHac.Common;
-using LibHac.Fs;
-using LibHac.Fs.Fsa;
-using LibHac.FsSystem;
-using LibHac.Tools.Fs;
-using LibHac.Tools.FsSystem;
-using LibHac.Tools.FsSystem.NcaUtils;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.Models;
-using Ryujinx.Common.Configuration;
-using Ryujinx.Common.Logging;
-using Ryujinx.Common.Utilities;
-using Ryujinx.HLE.FileSystem;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Threading.Tasks;
-using Application = Avalonia.Application;
-using Path = System.IO.Path;
-
-namespace Ryujinx.Ava.UI.ViewModels
-{
- public class DownloadableContentManagerViewModel : BaseModel
- {
- private readonly List<DownloadableContentContainer> _downloadableContentContainerList;
- private readonly string _downloadableContentJsonPath;
-
- private readonly VirtualFileSystem _virtualFileSystem;
- private AvaloniaList<DownloadableContentModel> _downloadableContents = new();
- private AvaloniaList<DownloadableContentModel> _views = new();
- private AvaloniaList<DownloadableContentModel> _selectedDownloadableContents = new();
-
- private string _search;
- private readonly ulong _titleId;
- private readonly IStorageProvider _storageProvider;
-
- private static readonly DownloadableContentJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
-
- public AvaloniaList<DownloadableContentModel> DownloadableContents
- {
- get => _downloadableContents;
- set
- {
- _downloadableContents = value;
- OnPropertyChanged();
- OnPropertyChanged(nameof(UpdateCount));
- Sort();
- }
- }
-
- public AvaloniaList<DownloadableContentModel> Views
- {
- get => _views;
- set
- {
- _views = value;
- OnPropertyChanged();
- }
- }
-
- public AvaloniaList<DownloadableContentModel> SelectedDownloadableContents
- {
- get => _selectedDownloadableContents;
- set
- {
- _selectedDownloadableContents = value;
- OnPropertyChanged();
- }
- }
-
- public string Search
- {
- get => _search;
- set
- {
- _search = value;
- OnPropertyChanged();
- Sort();
- }
- }
-
- public string UpdateCount
- {
- get => string.Format(LocaleManager.Instance[LocaleKeys.DlcWindowHeading], DownloadableContents.Count);
- }
-
- public DownloadableContentManagerViewModel(VirtualFileSystem virtualFileSystem, ulong titleId)
- {
- _virtualFileSystem = virtualFileSystem;
-
- _titleId = titleId;
-
- if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
- {
- _storageProvider = desktop.MainWindow.StorageProvider;
- }
-
- _downloadableContentJsonPath = Path.Combine(AppDataManager.GamesDirPath, titleId.ToString("x16"), "dlc.json");
-
- try
- {
- _downloadableContentContainerList = JsonHelper.DeserializeFromFile(_downloadableContentJsonPath, _serializerContext.ListDownloadableContentContainer);
- }
- catch
- {
- Logger.Error?.Print(LogClass.Configuration, "Downloadable Content JSON failed to deserialize.");
- _downloadableContentContainerList = new List<DownloadableContentContainer>();
- }
-
- LoadDownloadableContents();
- }
-
- private void LoadDownloadableContents()
- {
- foreach (DownloadableContentContainer downloadableContentContainer in _downloadableContentContainerList)
- {
- if (File.Exists(downloadableContentContainer.ContainerPath))
- {
- using FileStream containerFile = File.OpenRead(downloadableContentContainer.ContainerPath);
-
- PartitionFileSystem partitionFileSystem = new();
- partitionFileSystem.Initialize(containerFile.AsStorage()).ThrowIfFailure();
-
- _virtualFileSystem.ImportTickets(partitionFileSystem);
-
- foreach (DownloadableContentNca downloadableContentNca in downloadableContentContainer.DownloadableContentNcaList)
- {
- using UniqueRef<IFile> ncaFile = new();
-
- partitionFileSystem.OpenFile(ref ncaFile.Ref, downloadableContentNca.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
-
- Nca nca = TryOpenNca(ncaFile.Get.AsStorage(), downloadableContentContainer.ContainerPath);
- if (nca != null)
- {
- var content = new DownloadableContentModel(nca.Header.TitleId.ToString("X16"),
- downloadableContentContainer.ContainerPath,
- downloadableContentNca.FullPath,
- downloadableContentNca.Enabled);
-
- DownloadableContents.Add(content);
-
- if (content.Enabled)
- {
- SelectedDownloadableContents.Add(content);
- }
-
- OnPropertyChanged(nameof(UpdateCount));
- }
- }
- }
- }
-
- // NOTE: Save the list again to remove leftovers.
- Save();
- Sort();
- }
-
- public void Sort()
- {
- DownloadableContents.AsObservableChangeSet()
- .Filter(Filter)
- .Bind(out var view).AsObservableList();
-
- _views.Clear();
- _views.AddRange(view);
- OnPropertyChanged(nameof(Views));
- }
-
- private bool Filter(object arg)
- {
- if (arg is DownloadableContentModel content)
- {
- return string.IsNullOrWhiteSpace(_search) || content.FileName.ToLower().Contains(_search.ToLower()) || content.TitleId.ToLower().Contains(_search.ToLower());
- }
-
- return false;
- }
-
- private Nca TryOpenNca(IStorage ncaStorage, string containerPath)
- {
- try
- {
- return new Nca(_virtualFileSystem.KeySet, ncaStorage);
- }
- catch (Exception ex)
- {
- Dispatcher.UIThread.InvokeAsync(async () =>
- {
- await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance[LocaleKeys.DialogLoadFileErrorMessage], ex.Message, containerPath));
- });
- }
-
- return null;
- }
-
- public async void Add()
- {
- var result = await _storageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
- {
- Title = LocaleManager.Instance[LocaleKeys.SelectDlcDialogTitle],
- AllowMultiple = true,
- FileTypeFilter = new List<FilePickerFileType>
- {
- new("NSP")
- {
- Patterns = new[] { "*.nsp" },
- AppleUniformTypeIdentifiers = new[] { "com.ryujinx.nsp" },
- MimeTypes = new[] { "application/x-nx-nsp" },
- },
- },
- });
-
- foreach (var file in result)
- {
- await AddDownloadableContent(file.Path.LocalPath);
- }
- }
-
- private async Task AddDownloadableContent(string path)
- {
- if (!File.Exists(path) || DownloadableContents.FirstOrDefault(x => x.ContainerPath == path) != null)
- {
- return;
- }
-
- using FileStream containerFile = File.OpenRead(path);
-
- PartitionFileSystem partitionFileSystem = new();
- partitionFileSystem.Initialize(containerFile.AsStorage()).ThrowIfFailure();
- bool containsDownloadableContent = false;
-
- _virtualFileSystem.ImportTickets(partitionFileSystem);
-
- foreach (DirectoryEntryEx fileEntry in partitionFileSystem.EnumerateEntries("/", "*.nca"))
- {
- using var ncaFile = new UniqueRef<IFile>();
-
- partitionFileSystem.OpenFile(ref ncaFile.Ref, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
-
- Nca nca = TryOpenNca(ncaFile.Get.AsStorage(), path);
- if (nca == null)
- {
- continue;
- }
-
- if (nca.Header.ContentType == NcaContentType.PublicData)
- {
- if ((nca.Header.TitleId & 0xFFFFFFFFFFFFE000) != _titleId)
- {
- break;
- }
-
- var content = new DownloadableContentModel(nca.Header.TitleId.ToString("X16"), path, fileEntry.FullPath, true);
- DownloadableContents.Add(content);
- SelectedDownloadableContents.Add(content);
-
- OnPropertyChanged(nameof(UpdateCount));
- Sort();
-
- containsDownloadableContent = true;
- }
- }
-
- if (!containsDownloadableContent)
- {
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogDlcNoDlcErrorMessage]);
- }
- }
-
- public void Remove(DownloadableContentModel model)
- {
- DownloadableContents.Remove(model);
- OnPropertyChanged(nameof(UpdateCount));
- Sort();
- }
-
- public void RemoveAll()
- {
- DownloadableContents.Clear();
- OnPropertyChanged(nameof(UpdateCount));
- Sort();
- }
-
- public void EnableAll()
- {
- SelectedDownloadableContents = new(DownloadableContents);
- }
-
- public void DisableAll()
- {
- SelectedDownloadableContents.Clear();
- }
-
- public void Save()
- {
- _downloadableContentContainerList.Clear();
-
- DownloadableContentContainer container = default;
-
- foreach (DownloadableContentModel downloadableContent in DownloadableContents)
- {
- if (container.ContainerPath != downloadableContent.ContainerPath)
- {
- if (!string.IsNullOrWhiteSpace(container.ContainerPath))
- {
- _downloadableContentContainerList.Add(container);
- }
-
- container = new DownloadableContentContainer
- {
- ContainerPath = downloadableContent.ContainerPath,
- DownloadableContentNcaList = new List<DownloadableContentNca>(),
- };
- }
-
- container.DownloadableContentNcaList.Add(new DownloadableContentNca
- {
- Enabled = downloadableContent.Enabled,
- TitleId = Convert.ToUInt64(downloadableContent.TitleId, 16),
- FullPath = downloadableContent.FullPath,
- });
- }
-
- if (!string.IsNullOrWhiteSpace(container.ContainerPath))
- {
- _downloadableContentContainerList.Add(container);
- }
-
- JsonHelper.SerializeToFile(_downloadableContentJsonPath, _downloadableContentContainerList, _serializerContext.ListDownloadableContentContainer);
- }
-
- }
-}
diff --git a/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs
deleted file mode 100644
index 17bd69b1..00000000
--- a/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs
+++ /dev/null
@@ -1,1708 +0,0 @@
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Controls.ApplicationLifetimes;
-using Avalonia.Input;
-using Avalonia.Media;
-using Avalonia.Platform.Storage;
-using Avalonia.Threading;
-using DynamicData;
-using DynamicData.Binding;
-using LibHac.Common;
-using Ryujinx.Ava.Common;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.Input;
-using Ryujinx.Ava.UI.Controls;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.Models;
-using Ryujinx.Ava.UI.Models.Generic;
-using Ryujinx.Ava.UI.Renderer;
-using Ryujinx.Ava.UI.Windows;
-using Ryujinx.Common;
-using Ryujinx.Common.Configuration;
-using Ryujinx.Common.Logging;
-using Ryujinx.Cpu;
-using Ryujinx.HLE;
-using Ryujinx.HLE.FileSystem;
-using Ryujinx.HLE.HOS;
-using Ryujinx.HLE.HOS.Services.Account.Acc;
-using Ryujinx.HLE.UI;
-using Ryujinx.Input.HLE;
-using Ryujinx.Modules;
-using Ryujinx.UI.App.Common;
-using Ryujinx.UI.Common;
-using Ryujinx.UI.Common.Configuration;
-using Ryujinx.UI.Common.Helper;
-using SixLabors.ImageSharp.PixelFormats;
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.IO;
-using System.Threading;
-using System.Threading.Tasks;
-using Image = SixLabors.ImageSharp.Image;
-using Key = Ryujinx.Input.Key;
-using MissingKeyException = LibHac.Common.Keys.MissingKeyException;
-using ShaderCacheLoadingState = Ryujinx.Graphics.Gpu.Shader.ShaderCacheState;
-
-namespace Ryujinx.Ava.UI.ViewModels
-{
- public class MainWindowViewModel : BaseModel
- {
- private const int HotKeyPressDelayMs = 500;
-
- private ObservableCollection<ApplicationData> _applications;
- private string _aspectStatusText;
-
- private string _loadHeading;
- private string _cacheLoadStatus;
- private string _searchText;
- private Timer _searchTimer;
- private string _dockedStatusText;
- private string _fifoStatusText;
- private string _gameStatusText;
- private string _volumeStatusText;
- private string _gpuStatusText;
- private bool _isAmiiboRequested;
- private bool _isGameRunning;
- private bool _isFullScreen;
- private int _progressMaximum;
- private int _progressValue;
- private long _lastFullscreenToggle = Environment.TickCount64;
- private bool _showLoadProgress;
- private bool _showMenuAndStatusBar = true;
- private bool _showStatusSeparator;
- private Brush _progressBarForegroundColor;
- private Brush _progressBarBackgroundColor;
- private Brush _vsyncColor;
- private byte[] _selectedIcon;
- private bool _isAppletMenuActive;
- private int _statusBarProgressMaximum;
- private int _statusBarProgressValue;
- private bool _isPaused;
- private bool _showContent = true;
- private bool _isLoadingIndeterminate = true;
- private bool _showAll;
- private string _lastScannedAmiiboId;
- private bool _statusBarVisible;
- private ReadOnlyObservableCollection<ApplicationData> _appsObservableList;
-
- private string _showUiKey = "F4";
- private string _pauseKey = "F5";
- private string _screenshotKey = "F8";
- private float _volume;
- private float _volumeBeforeMute;
- private string _backendText;
-
- private bool _canUpdate = true;
- private Cursor _cursor;
- private string _title;
- private string _currentEmulatedGamePath;
- private readonly AutoResetEvent _rendererWaitEvent;
- private WindowState _windowState;
- private double _windowWidth;
- private double _windowHeight;
-
- private bool _isActive;
-
- public ApplicationData ListSelectedApplication;
- public ApplicationData GridSelectedApplication;
-
- private string TitleName { get; set; }
- internal AppHost AppHost { get; set; }
-
- public MainWindowViewModel()
- {
- Applications = new ObservableCollection<ApplicationData>();
-
- Applications.ToObservableChangeSet()
- .Filter(Filter)
- .Sort(GetComparer())
- .Bind(out _appsObservableList).AsObservableList();
-
- _rendererWaitEvent = new AutoResetEvent(false);
-
- if (Program.PreviewerDetached)
- {
- LoadConfigurableHotKeys();
-
- Volume = ConfigurationState.Instance.System.AudioVolume;
- }
- }
-
- public void Initialize(
- ContentManager contentManager,
- IStorageProvider storageProvider,
- ApplicationLibrary applicationLibrary,
- VirtualFileSystem virtualFileSystem,
- AccountManager accountManager,
- InputManager inputManager,
- UserChannelPersistence userChannelPersistence,
- LibHacHorizonManager libHacHorizonManager,
- IHostUIHandler uiHandler,
- Action<bool> showLoading,
- Action<bool> switchToGameControl,
- Action<Control> setMainContent,
- TopLevel topLevel)
- {
- ContentManager = contentManager;
- StorageProvider = storageProvider;
- ApplicationLibrary = applicationLibrary;
- VirtualFileSystem = virtualFileSystem;
- AccountManager = accountManager;
- InputManager = inputManager;
- UserChannelPersistence = userChannelPersistence;
- LibHacHorizonManager = libHacHorizonManager;
- UiHandler = uiHandler;
-
- ShowLoading = showLoading;
- SwitchToGameControl = switchToGameControl;
- SetMainContent = setMainContent;
- TopLevel = topLevel;
- }
-
- #region Properties
-
- public string SearchText
- {
- get => _searchText;
- set
- {
- _searchText = value;
-
- _searchTimer?.Dispose();
-
- _searchTimer = new Timer(TimerCallback, null, 1000, 0);
- }
- }
-
- private void TimerCallback(object obj)
- {
- RefreshView();
-
- _searchTimer.Dispose();
- _searchTimer = null;
- }
-
- public bool CanUpdate
- {
- get => _canUpdate && EnableNonGameRunningControls && Updater.CanUpdate(false);
- set
- {
- _canUpdate = value;
- OnPropertyChanged();
- }
- }
-
- public Cursor Cursor
- {
- get => _cursor;
- set
- {
- _cursor = value;
- OnPropertyChanged();
- }
- }
-
- public ReadOnlyObservableCollection<ApplicationData> AppsObservableList
- {
- get => _appsObservableList;
- set
- {
- _appsObservableList = value;
-
- OnPropertyChanged();
- }
- }
-
- public bool IsPaused
- {
- get => _isPaused;
- set
- {
- _isPaused = value;
-
- OnPropertyChanged();
- }
- }
-
- public long LastFullscreenToggle
- {
- get => _lastFullscreenToggle;
- set
- {
- _lastFullscreenToggle = value;
-
- OnPropertyChanged();
- }
- }
-
- public bool StatusBarVisible
- {
- get => _statusBarVisible && EnableNonGameRunningControls;
- set
- {
- _statusBarVisible = value;
-
- OnPropertyChanged();
- }
- }
-
- public bool EnableNonGameRunningControls => !IsGameRunning;
-
- public bool ShowFirmwareStatus => !ShowLoadProgress;
-
- public bool IsGameRunning
- {
- get => _isGameRunning;
- set
- {
- _isGameRunning = value;
-
- if (!value)
- {
- ShowMenuAndStatusBar = false;
- }
-
- OnPropertyChanged();
- OnPropertyChanged(nameof(EnableNonGameRunningControls));
- OnPropertyChanged(nameof(IsAppletMenuActive));
- OnPropertyChanged(nameof(StatusBarVisible));
- OnPropertyChanged(nameof(ShowFirmwareStatus));
- }
- }
-
- public bool IsAmiiboRequested
- {
- get => _isAmiiboRequested && _isGameRunning;
- set
- {
- _isAmiiboRequested = value;
-
- OnPropertyChanged();
- }
- }
-
- public bool ShowLoadProgress
- {
- get => _showLoadProgress;
- set
- {
- _showLoadProgress = value;
-
- OnPropertyChanged();
- OnPropertyChanged(nameof(ShowFirmwareStatus));
- }
- }
-
- public string GameStatusText
- {
- get => _gameStatusText;
- set
- {
- _gameStatusText = value;
-
- OnPropertyChanged();
- }
- }
-
- public bool IsFullScreen
- {
- get => _isFullScreen;
- set
- {
- _isFullScreen = value;
-
- OnPropertyChanged();
- }
- }
-
- public bool ShowAll
- {
- get => _showAll;
- set
- {
- _showAll = value;
-
- OnPropertyChanged();
- }
- }
-
- public string LastScannedAmiiboId
- {
- get => _lastScannedAmiiboId;
- set
- {
- _lastScannedAmiiboId = value;
-
- OnPropertyChanged();
- }
- }
-
- public ApplicationData SelectedApplication
- {
- get
- {
- return Glyph switch
- {
- Glyph.List => ListSelectedApplication,
- Glyph.Grid => GridSelectedApplication,
- _ => null,
- };
- }
- }
-
- public bool OpenUserSaveDirectoryEnabled => !SelectedApplication.ControlHolder.ByteSpan.IsZeros() && SelectedApplication.ControlHolder.Value.UserAccountSaveDataSize > 0;
-
- public bool OpenDeviceSaveDirectoryEnabled => !SelectedApplication.ControlHolder.ByteSpan.IsZeros() && SelectedApplication.ControlHolder.Value.DeviceSaveDataSize > 0;
-
- public bool OpenBcatSaveDirectoryEnabled => !SelectedApplication.ControlHolder.ByteSpan.IsZeros() && SelectedApplication.ControlHolder.Value.BcatDeliveryCacheStorageSize > 0;
-
- public bool CreateShortcutEnabled => !ReleaseInformation.IsFlatHubBuild;
-
- public string LoadHeading
- {
- get => _loadHeading;
- set
- {
- _loadHeading = value;
-
- OnPropertyChanged();
- }
- }
-
- public string CacheLoadStatus
- {
- get => _cacheLoadStatus;
- set
- {
- _cacheLoadStatus = value;
-
- OnPropertyChanged();
- }
- }
-
- public Brush ProgressBarBackgroundColor
- {
- get => _progressBarBackgroundColor;
- set
- {
- _progressBarBackgroundColor = value;
-
- OnPropertyChanged();
- }
- }
-
- public Brush ProgressBarForegroundColor
- {
- get => _progressBarForegroundColor;
- set
- {
- _progressBarForegroundColor = value;
-
- OnPropertyChanged();
- }
- }
-
- public Brush VsyncColor
- {
- get => _vsyncColor;
- set
- {
- _vsyncColor = value;
-
- OnPropertyChanged();
- }
- }
-
- public byte[] SelectedIcon
- {
- get => _selectedIcon;
- set
- {
- _selectedIcon = value;
-
- OnPropertyChanged();
- }
- }
-
- public int ProgressMaximum
- {
- get => _progressMaximum;
- set
- {
- _progressMaximum = value;
-
- OnPropertyChanged();
- }
- }
-
- public int ProgressValue
- {
- get => _progressValue;
- set
- {
- _progressValue = value;
-
- OnPropertyChanged();
- }
- }
-
- public int StatusBarProgressMaximum
- {
- get => _statusBarProgressMaximum;
- set
- {
- _statusBarProgressMaximum = value;
-
- OnPropertyChanged();
- }
- }
-
- public int StatusBarProgressValue
- {
- get => _statusBarProgressValue;
- set
- {
- _statusBarProgressValue = value;
-
- OnPropertyChanged();
- }
- }
-
- public string FifoStatusText
- {
- get => _fifoStatusText;
- set
- {
- _fifoStatusText = value;
-
- OnPropertyChanged();
- }
- }
-
- public string GpuNameText
- {
- get => _gpuStatusText;
- set
- {
- _gpuStatusText = value;
-
- OnPropertyChanged();
- }
- }
-
- public string BackendText
- {
- get => _backendText;
- set
- {
- _backendText = value;
-
- OnPropertyChanged();
- }
- }
-
- public string DockedStatusText
- {
- get => _dockedStatusText;
- set
- {
- _dockedStatusText = value;
-
- OnPropertyChanged();
- }
- }
-
- public string AspectRatioStatusText
- {
- get => _aspectStatusText;
- set
- {
- _aspectStatusText = value;
-
- OnPropertyChanged();
- }
- }
-
- public string VolumeStatusText
- {
- get => _volumeStatusText;
- set
- {
- _volumeStatusText = value;
-
- OnPropertyChanged();
- }
- }
-
- public bool VolumeMuted => _volume == 0;
-
- public float Volume
- {
- get => _volume;
- set
- {
- _volume = value;
-
- if (_isGameRunning)
- {
- AppHost.Device.SetVolume(_volume);
- }
-
- OnPropertyChanged(nameof(VolumeStatusText));
- OnPropertyChanged(nameof(VolumeMuted));
- OnPropertyChanged();
- }
- }
-
- public float VolumeBeforeMute
- {
- get => _volumeBeforeMute;
- set
- {
- _volumeBeforeMute = value;
-
- OnPropertyChanged();
- }
- }
-
- public bool ShowStatusSeparator
- {
- get => _showStatusSeparator;
- set
- {
- _showStatusSeparator = value;
-
- OnPropertyChanged();
- }
- }
-
- public bool ShowMenuAndStatusBar
- {
- get => _showMenuAndStatusBar;
- set
- {
- _showMenuAndStatusBar = value;
-
- OnPropertyChanged();
- }
- }
-
- public bool IsLoadingIndeterminate
- {
- get => _isLoadingIndeterminate;
- set
- {
- _isLoadingIndeterminate = value;
-
- OnPropertyChanged();
- }
- }
-
- public bool IsActive
- {
- get => _isActive;
- set
- {
- _isActive = value;
-
- OnPropertyChanged();
- }
- }
-
-
- public bool ShowContent
- {
- get => _showContent;
- set
- {
- _showContent = value;
-
- OnPropertyChanged();
- }
- }
-
- public bool IsAppletMenuActive
- {
- get => _isAppletMenuActive && EnableNonGameRunningControls;
- set
- {
- _isAppletMenuActive = value;
-
- OnPropertyChanged();
- }
- }
-
- public WindowState WindowState
- {
- get => _windowState;
- internal set
- {
- _windowState = value;
-
- OnPropertyChanged();
- }
- }
-
- public double WindowWidth
- {
- get => _windowWidth;
- set
- {
- _windowWidth = value;
-
- OnPropertyChanged();
- }
- }
-
- public double WindowHeight
- {
- get => _windowHeight;
- set
- {
- _windowHeight = value;
-
- OnPropertyChanged();
- }
- }
-
- public bool IsGrid => Glyph == Glyph.Grid;
- public bool IsList => Glyph == Glyph.List;
-
- internal void Sort(bool isAscending)
- {
- IsAscending = isAscending;
-
- RefreshView();
- }
-
- internal void Sort(ApplicationSort sort)
- {
- SortMode = sort;
-
- RefreshView();
- }
-
- public bool StartGamesInFullscreen
- {
- get => ConfigurationState.Instance.UI.StartFullscreen;
- set
- {
- ConfigurationState.Instance.UI.StartFullscreen.Value = value;
-
- ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
-
- OnPropertyChanged();
- }
- }
-
- public bool ShowConsole
- {
- get => ConfigurationState.Instance.UI.ShowConsole;
- set
- {
- ConfigurationState.Instance.UI.ShowConsole.Value = value;
-
- ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
-
- OnPropertyChanged();
- }
- }
-
- public string Title
- {
- get => _title;
- set
- {
- _title = value;
-
- OnPropertyChanged();
- }
- }
-
- public bool ShowConsoleVisible
- {
- get => ConsoleHelper.SetConsoleWindowStateSupported;
- }
-
- public bool ManageFileTypesVisible
- {
- get => FileAssociationHelper.IsTypeAssociationSupported;
- }
-
- public ObservableCollection<ApplicationData> Applications
- {
- get => _applications;
- set
- {
- _applications = value;
-
- OnPropertyChanged();
- }
- }
-
- public Glyph Glyph
- {
- get => (Glyph)ConfigurationState.Instance.UI.GameListViewMode.Value;
- set
- {
- ConfigurationState.Instance.UI.GameListViewMode.Value = (int)value;
-
- OnPropertyChanged();
- OnPropertyChanged(nameof(IsGrid));
- OnPropertyChanged(nameof(IsList));
-
- ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
- }
- }
-
- public bool ShowNames
- {
- get => ConfigurationState.Instance.UI.ShowNames && ConfigurationState.Instance.UI.GridSize > 1; set
- {
- ConfigurationState.Instance.UI.ShowNames.Value = value;
-
- OnPropertyChanged();
- OnPropertyChanged(nameof(GridSizeScale));
- OnPropertyChanged(nameof(GridItemSelectorSize));
-
- ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
- }
- }
-
- internal ApplicationSort SortMode
- {
- get => (ApplicationSort)ConfigurationState.Instance.UI.ApplicationSort.Value;
- private set
- {
- ConfigurationState.Instance.UI.ApplicationSort.Value = (int)value;
-
- OnPropertyChanged();
- OnPropertyChanged(nameof(SortName));
-
- ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
- }
- }
-
- public int ListItemSelectorSize
- {
- get
- {
- return ConfigurationState.Instance.UI.GridSize.Value switch
- {
- 1 => 78,
- 2 => 100,
- 3 => 120,
- 4 => 140,
- _ => 16,
- };
- }
- }
-
- public int GridItemSelectorSize
- {
- get
- {
- return ConfigurationState.Instance.UI.GridSize.Value switch
- {
- 1 => 120,
- 2 => ShowNames ? 210 : 150,
- 3 => ShowNames ? 240 : 180,
- 4 => ShowNames ? 280 : 220,
- _ => 16,
- };
- }
- }
-
- public int GridSizeScale
- {
- get => ConfigurationState.Instance.UI.GridSize;
- set
- {
- ConfigurationState.Instance.UI.GridSize.Value = value;
-
- if (value < 2)
- {
- ShowNames = false;
- }
-
- OnPropertyChanged();
- OnPropertyChanged(nameof(IsGridSmall));
- OnPropertyChanged(nameof(IsGridMedium));
- OnPropertyChanged(nameof(IsGridLarge));
- OnPropertyChanged(nameof(IsGridHuge));
- OnPropertyChanged(nameof(ListItemSelectorSize));
- OnPropertyChanged(nameof(GridItemSelectorSize));
- OnPropertyChanged(nameof(ShowNames));
-
- ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
- }
- }
-
- public string SortName
- {
- get
- {
- return SortMode switch
- {
- ApplicationSort.Title => LocaleManager.Instance[LocaleKeys.GameListHeaderApplication],
- ApplicationSort.Developer => LocaleManager.Instance[LocaleKeys.GameListHeaderDeveloper],
- ApplicationSort.LastPlayed => LocaleManager.Instance[LocaleKeys.GameListHeaderLastPlayed],
- ApplicationSort.TotalTimePlayed => LocaleManager.Instance[LocaleKeys.GameListHeaderTimePlayed],
- ApplicationSort.FileType => LocaleManager.Instance[LocaleKeys.GameListHeaderFileExtension],
- ApplicationSort.FileSize => LocaleManager.Instance[LocaleKeys.GameListHeaderFileSize],
- ApplicationSort.Path => LocaleManager.Instance[LocaleKeys.GameListHeaderPath],
- ApplicationSort.Favorite => LocaleManager.Instance[LocaleKeys.CommonFavorite],
- _ => string.Empty,
- };
- }
- }
-
- public bool IsAscending
- {
- get => ConfigurationState.Instance.UI.IsAscendingOrder;
- private set
- {
- ConfigurationState.Instance.UI.IsAscendingOrder.Value = value;
-
- OnPropertyChanged();
- OnPropertyChanged(nameof(SortMode));
- OnPropertyChanged(nameof(SortName));
-
- ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
- }
- }
-
- public KeyGesture ShowUiKey
- {
- get => KeyGesture.Parse(_showUiKey);
- set
- {
- _showUiKey = value.ToString();
-
- OnPropertyChanged();
- }
- }
-
- public KeyGesture ScreenshotKey
- {
- get => KeyGesture.Parse(_screenshotKey);
- set
- {
- _screenshotKey = value.ToString();
-
- OnPropertyChanged();
- }
- }
-
- public KeyGesture PauseKey
- {
- get => KeyGesture.Parse(_pauseKey); set
- {
- _pauseKey = value.ToString();
-
- OnPropertyChanged();
- }
- }
-
- public ContentManager ContentManager { get; private set; }
- public IStorageProvider StorageProvider { get; private set; }
- public ApplicationLibrary ApplicationLibrary { get; private set; }
- public VirtualFileSystem VirtualFileSystem { get; private set; }
- public AccountManager AccountManager { get; private set; }
- public InputManager InputManager { get; private set; }
- public UserChannelPersistence UserChannelPersistence { get; private set; }
- public Action<bool> ShowLoading { get; private set; }
- public Action<bool> SwitchToGameControl { get; private set; }
- public Action<Control> SetMainContent { get; private set; }
- public TopLevel TopLevel { get; private set; }
- public RendererHost RendererHostControl { get; private set; }
- public bool IsClosing { get; set; }
- public LibHacHorizonManager LibHacHorizonManager { get; internal set; }
- public IHostUIHandler UiHandler { get; internal set; }
- public bool IsSortedByFavorite => SortMode == ApplicationSort.Favorite;
- public bool IsSortedByTitle => SortMode == ApplicationSort.Title;
- public bool IsSortedByDeveloper => SortMode == ApplicationSort.Developer;
- public bool IsSortedByLastPlayed => SortMode == ApplicationSort.LastPlayed;
- public bool IsSortedByTimePlayed => SortMode == ApplicationSort.TotalTimePlayed;
- public bool IsSortedByType => SortMode == ApplicationSort.FileType;
- public bool IsSortedBySize => SortMode == ApplicationSort.FileSize;
- public bool IsSortedByPath => SortMode == ApplicationSort.Path;
- public bool IsGridSmall => ConfigurationState.Instance.UI.GridSize == 1;
- public bool IsGridMedium => ConfigurationState.Instance.UI.GridSize == 2;
- public bool IsGridLarge => ConfigurationState.Instance.UI.GridSize == 3;
- public bool IsGridHuge => ConfigurationState.Instance.UI.GridSize == 4;
-
- #endregion
-
- #region PrivateMethods
-
- private IComparer<ApplicationData> GetComparer()
- {
- return SortMode switch
- {
-#pragma warning disable IDE0055 // Disable formatting
- ApplicationSort.Title => IsAscending ? SortExpressionComparer<ApplicationData>.Ascending(app => app.TitleName)
- : SortExpressionComparer<ApplicationData>.Descending(app => app.TitleName),
- ApplicationSort.Developer => IsAscending ? SortExpressionComparer<ApplicationData>.Ascending(app => app.Developer)
- : SortExpressionComparer<ApplicationData>.Descending(app => app.Developer),
- ApplicationSort.LastPlayed => new LastPlayedSortComparer(IsAscending),
- ApplicationSort.TotalTimePlayed => new TimePlayedSortComparer(IsAscending),
- ApplicationSort.FileType => IsAscending ? SortExpressionComparer<ApplicationData>.Ascending(app => app.FileExtension)
- : SortExpressionComparer<ApplicationData>.Descending(app => app.FileExtension),
- ApplicationSort.FileSize => IsAscending ? SortExpressionComparer<ApplicationData>.Ascending(app => app.FileSize)
- : SortExpressionComparer<ApplicationData>.Descending(app => app.FileSize),
- ApplicationSort.Path => IsAscending ? SortExpressionComparer<ApplicationData>.Ascending(app => app.Path)
- : SortExpressionComparer<ApplicationData>.Descending(app => app.Path),
- ApplicationSort.Favorite => !IsAscending ? SortExpressionComparer<ApplicationData>.Ascending(app => app.Favorite)
- : SortExpressionComparer<ApplicationData>.Descending(app => app.Favorite),
- _ => null,
-#pragma warning restore IDE0055
- };
- }
-
- public void RefreshView()
- {
- RefreshGrid();
- }
-
- private void RefreshGrid()
- {
- Applications.ToObservableChangeSet()
- .Filter(Filter)
- .Sort(GetComparer())
- .Bind(out _appsObservableList).AsObservableList();
-
- OnPropertyChanged(nameof(AppsObservableList));
- }
-
- private bool Filter(object arg)
- {
- if (arg is ApplicationData app)
- {
- return string.IsNullOrWhiteSpace(_searchText) || app.TitleName.ToLower().Contains(_searchText.ToLower());
- }
-
- return false;
- }
-
- private async Task HandleFirmwareInstallation(string filename)
- {
- try
- {
- SystemVersion firmwareVersion = ContentManager.VerifyFirmwarePackage(filename);
-
- if (firmwareVersion == null)
- {
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogFirmwareInstallerFirmwareNotFoundErrorMessage, filename));
-
- return;
- }
-
- string dialogTitle = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogFirmwareInstallerFirmwareInstallTitle, firmwareVersion.VersionString);
- string dialogMessage = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogFirmwareInstallerFirmwareInstallMessage, firmwareVersion.VersionString);
-
- SystemVersion currentVersion = ContentManager.GetCurrentFirmwareVersion();
- if (currentVersion != null)
- {
- dialogMessage += LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogFirmwareInstallerFirmwareInstallSubMessage, currentVersion.VersionString);
- }
-
- dialogMessage += LocaleManager.Instance[LocaleKeys.DialogFirmwareInstallerFirmwareInstallConfirmMessage];
-
- UserResult result = await ContentDialogHelper.CreateConfirmationDialog(
- dialogTitle,
- dialogMessage,
- LocaleManager.Instance[LocaleKeys.InputDialogYes],
- LocaleManager.Instance[LocaleKeys.InputDialogNo],
- LocaleManager.Instance[LocaleKeys.RyujinxConfirm]);
-
- UpdateWaitWindow waitingDialog = new(dialogTitle, LocaleManager.Instance[LocaleKeys.DialogFirmwareInstallerFirmwareInstallWaitMessage]);
-
- if (result == UserResult.Yes)
- {
- Logger.Info?.Print(LogClass.Application, $"Installing firmware {firmwareVersion.VersionString}");
-
- Thread thread = new(() =>
- {
- Dispatcher.UIThread.InvokeAsync(delegate
- {
- waitingDialog.Show();
- });
-
- try
- {
- ContentManager.InstallFirmware(filename);
-
- Dispatcher.UIThread.InvokeAsync(async delegate
- {
- waitingDialog.Close();
-
- string message = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogFirmwareInstallerFirmwareInstallSuccessMessage, firmwareVersion.VersionString);
-
- await ContentDialogHelper.CreateInfoDialog(dialogTitle, message, LocaleManager.Instance[LocaleKeys.InputDialogOk], "", LocaleManager.Instance[LocaleKeys.RyujinxInfo]);
-
- Logger.Info?.Print(LogClass.Application, message);
-
- // Purge Applet Cache.
-
- DirectoryInfo miiEditorCacheFolder = new(Path.Combine(AppDataManager.GamesDirPath, "0100000000001009", "cache"));
-
- if (miiEditorCacheFolder.Exists)
- {
- miiEditorCacheFolder.Delete(true);
- }
- });
- }
- catch (Exception ex)
- {
- Dispatcher.UIThread.InvokeAsync(async () =>
- {
- waitingDialog.Close();
-
- await ContentDialogHelper.CreateErrorDialog(ex.Message);
- });
- }
- finally
- {
- RefreshFirmwareStatus();
- }
- })
- {
- Name = "GUI.FirmwareInstallerThread",
- };
-
- thread.Start();
- }
- }
- catch (MissingKeyException ex)
- {
- if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
- {
- Logger.Error?.Print(LogClass.Application, ex.ToString());
-
- await UserErrorDialog.ShowUserErrorDialog(UserError.NoKeys);
- }
- }
- catch (Exception ex)
- {
- await ContentDialogHelper.CreateErrorDialog(ex.Message);
- }
- }
-
- private void ProgressHandler<T>(T state, int current, int total) where T : Enum
- {
- Dispatcher.UIThread.Post((() =>
- {
- ProgressMaximum = total;
- ProgressValue = current;
-
- switch (state)
- {
- case LoadState ptcState:
- CacheLoadStatus = $"{current} / {total}";
- switch (ptcState)
- {
- case LoadState.Unloaded:
- case LoadState.Loading:
- LoadHeading = LocaleManager.Instance[LocaleKeys.CompilingPPTC];
- IsLoadingIndeterminate = false;
- break;
- case LoadState.Loaded:
- LoadHeading = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.LoadingHeading, TitleName);
- IsLoadingIndeterminate = true;
- CacheLoadStatus = "";
- break;
- }
- break;
- case ShaderCacheLoadingState shaderCacheState:
- CacheLoadStatus = $"{current} / {total}";
- switch (shaderCacheState)
- {
- case ShaderCacheLoadingState.Start:
- case ShaderCacheLoadingState.Loading:
- LoadHeading = LocaleManager.Instance[LocaleKeys.CompilingShaders];
- IsLoadingIndeterminate = false;
- break;
- case ShaderCacheLoadingState.Packaging:
- LoadHeading = LocaleManager.Instance[LocaleKeys.PackagingShaders];
- IsLoadingIndeterminate = false;
- break;
- case ShaderCacheLoadingState.Loaded:
- LoadHeading = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.LoadingHeading, TitleName);
- IsLoadingIndeterminate = true;
- CacheLoadStatus = "";
- break;
- }
- break;
- default:
- throw new ArgumentException($"Unknown Progress Handler type {typeof(T)}");
- }
- }));
- }
-
- private void PrepareLoadScreen()
- {
- using MemoryStream stream = new(SelectedIcon);
- using var gameIconBmp = Image.Load<Bgra32>(stream);
-
- var dominantColor = IconColorPicker.GetFilteredColor(gameIconBmp).ToPixel<Bgra32>();
-
- const float ColorMultiple = 0.5f;
-
- Color progressFgColor = Color.FromRgb(dominantColor.R, dominantColor.G, dominantColor.B);
- Color progressBgColor = Color.FromRgb(
- (byte)(dominantColor.R * ColorMultiple),
- (byte)(dominantColor.G * ColorMultiple),
- (byte)(dominantColor.B * ColorMultiple));
-
- ProgressBarForegroundColor = new SolidColorBrush(progressFgColor);
- ProgressBarBackgroundColor = new SolidColorBrush(progressBgColor);
- }
-
- private void InitializeGame()
- {
- RendererHostControl.WindowCreated += RendererHost_Created;
-
- AppHost.StatusUpdatedEvent += Update_StatusBar;
- AppHost.AppExit += AppHost_AppExit;
-
- _rendererWaitEvent.WaitOne();
-
- AppHost?.Start();
-
- AppHost?.DisposeContext();
- }
-
- private async Task HandleRelaunch()
- {
- if (UserChannelPersistence.PreviousIndex != -1 && UserChannelPersistence.ShouldRestart)
- {
- UserChannelPersistence.ShouldRestart = false;
-
- await LoadApplication(_currentEmulatedGamePath);
- }
- else
- {
- // Otherwise, clear state.
- UserChannelPersistence = new UserChannelPersistence();
- _currentEmulatedGamePath = null;
- }
- }
-
- private void Update_StatusBar(object sender, StatusUpdatedEventArgs args)
- {
- if (ShowMenuAndStatusBar && !ShowLoadProgress)
- {
- Dispatcher.UIThread.InvokeAsync(() =>
- {
- Application.Current.Styles.TryGetResource(args.VSyncEnabled
- ? "VsyncEnabled"
- : "VsyncDisabled",
- Application.Current.ActualThemeVariant,
- out object color);
-
- if (color is not null)
- {
- VsyncColor = new SolidColorBrush((Color)color);
- }
-
- DockedStatusText = args.DockedMode;
- AspectRatioStatusText = args.AspectRatio;
- GameStatusText = args.GameStatus;
- VolumeStatusText = args.VolumeStatus;
- FifoStatusText = args.FifoStatus;
- GpuNameText = args.GpuName;
- BackendText = args.GpuBackend;
-
- ShowStatusSeparator = true;
- });
- }
- }
-
- private void RendererHost_Created(object sender, EventArgs e)
- {
- ShowLoading(false);
-
- _rendererWaitEvent.Set();
- }
-
- #endregion
-
- #region PublicMethods
-
- public void SetUiProgressHandlers(Switch emulationContext)
- {
- if (emulationContext.Processes.ActiveApplication.DiskCacheLoadState != null)
- {
- emulationContext.Processes.ActiveApplication.DiskCacheLoadState.StateChanged -= ProgressHandler;
- emulationContext.Processes.ActiveApplication.DiskCacheLoadState.StateChanged += ProgressHandler;
- }
-
- emulationContext.Gpu.ShaderCacheStateChanged -= ProgressHandler;
- emulationContext.Gpu.ShaderCacheStateChanged += ProgressHandler;
- }
-
- public void LoadConfigurableHotKeys()
- {
- if (AvaloniaKeyboardMappingHelper.TryGetAvaKey((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.ShowUI, out var showUiKey))
- {
- ShowUiKey = new KeyGesture(showUiKey);
- }
-
- if (AvaloniaKeyboardMappingHelper.TryGetAvaKey((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.Screenshot, out var screenshotKey))
- {
- ScreenshotKey = new KeyGesture(screenshotKey);
- }
-
- if (AvaloniaKeyboardMappingHelper.TryGetAvaKey((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.Pause, out var pauseKey))
- {
- PauseKey = new KeyGesture(pauseKey);
- }
- }
-
- public void TakeScreenshot()
- {
- AppHost.ScreenshotRequested = true;
- }
-
- public void HideUi()
- {
- ShowMenuAndStatusBar = false;
- }
-
- public void ToggleStartGamesInFullscreen()
- {
- StartGamesInFullscreen = !StartGamesInFullscreen;
- }
-
- public void ToggleShowConsole()
- {
- ShowConsole = !ShowConsole;
- }
-
- public void SetListMode()
- {
- Glyph = Glyph.List;
- }
-
- public void SetGridMode()
- {
- Glyph = Glyph.Grid;
- }
-
- public void SetAspectRatio(AspectRatio aspectRatio)
- {
- ConfigurationState.Instance.Graphics.AspectRatio.Value = aspectRatio;
- }
-
- public async Task InstallFirmwareFromFile()
- {
- var result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
- {
- AllowMultiple = false,
- FileTypeFilter = new List<FilePickerFileType>
- {
- new(LocaleManager.Instance[LocaleKeys.FileDialogAllTypes])
- {
- Patterns = new[] { "*.xci", "*.zip" },
- AppleUniformTypeIdentifiers = new[] { "com.ryujinx.xci", "public.zip-archive" },
- MimeTypes = new[] { "application/x-nx-xci", "application/zip" },
- },
- new("XCI")
- {
- Patterns = new[] { "*.xci" },
- AppleUniformTypeIdentifiers = new[] { "com.ryujinx.xci" },
- MimeTypes = new[] { "application/x-nx-xci" },
- },
- new("ZIP")
- {
- Patterns = new[] { "*.zip" },
- AppleUniformTypeIdentifiers = new[] { "public.zip-archive" },
- MimeTypes = new[] { "application/zip" },
- },
- },
- });
-
- if (result.Count > 0)
- {
- await HandleFirmwareInstallation(result[0].Path.LocalPath);
- }
- }
-
- public async Task InstallFirmwareFromFolder()
- {
- var result = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
- {
- AllowMultiple = false,
- });
-
- if (result.Count > 0)
- {
- await HandleFirmwareInstallation(result[0].Path.LocalPath);
- }
- }
-
- public void OpenRyujinxFolder()
- {
- OpenHelper.OpenFolder(AppDataManager.BaseDirPath);
- }
-
- public void OpenLogsFolder()
- {
- string logPath = AppDataManager.GetOrCreateLogsDir();
- if (!string.IsNullOrEmpty(logPath))
- {
- OpenHelper.OpenFolder(logPath);
- }
- }
-
- public void ToggleDockMode()
- {
- if (IsGameRunning)
- {
- ConfigurationState.Instance.System.EnableDockedMode.Value = !ConfigurationState.Instance.System.EnableDockedMode.Value;
- }
- }
-
- public async Task ExitCurrentState()
- {
- if (WindowState == WindowState.FullScreen)
- {
- ToggleFullscreen();
- }
- else if (IsGameRunning)
- {
- await Task.Delay(100);
-
- AppHost?.ShowExitPrompt();
- }
- }
-
- public static void ChangeLanguage(object languageCode)
- {
- LocaleManager.Instance.LoadLanguage((string)languageCode);
-
- if (Program.PreviewerDetached)
- {
- ConfigurationState.Instance.UI.LanguageCode.Value = (string)languageCode;
- ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
- }
- }
-
- public async Task ManageProfiles()
- {
- await NavigationDialogHost.Show(AccountManager, ContentManager, VirtualFileSystem, LibHacHorizonManager.RyujinxClient);
- }
-
- public void SimulateWakeUpMessage()
- {
- AppHost.Device.System.SimulateWakeUpMessage();
- }
-
- public async Task OpenFile()
- {
- var result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
- {
- Title = LocaleManager.Instance[LocaleKeys.OpenFileDialogTitle],
- AllowMultiple = false,
- FileTypeFilter = new List<FilePickerFileType>
- {
- new(LocaleManager.Instance[LocaleKeys.AllSupportedFormats])
- {
- Patterns = new[] { "*.nsp", "*.xci", "*.nca", "*.nro", "*.nso" },
- AppleUniformTypeIdentifiers = new[]
- {
- "com.ryujinx.nsp",
- "com.ryujinx.xci",
- "com.ryujinx.nca",
- "com.ryujinx.nro",
- "com.ryujinx.nso",
- },
- MimeTypes = new[]
- {
- "application/x-nx-nsp",
- "application/x-nx-xci",
- "application/x-nx-nca",
- "application/x-nx-nro",
- "application/x-nx-nso",
- },
- },
- new("NSP")
- {
- Patterns = new[] { "*.nsp" },
- AppleUniformTypeIdentifiers = new[] { "com.ryujinx.nsp" },
- MimeTypes = new[] { "application/x-nx-nsp" },
- },
- new("XCI")
- {
- Patterns = new[] { "*.xci" },
- AppleUniformTypeIdentifiers = new[] { "com.ryujinx.xci" },
- MimeTypes = new[] { "application/x-nx-xci" },
- },
- new("NCA")
- {
- Patterns = new[] { "*.nca" },
- AppleUniformTypeIdentifiers = new[] { "com.ryujinx.nca" },
- MimeTypes = new[] { "application/x-nx-nca" },
- },
- new("NRO")
- {
- Patterns = new[] { "*.nro" },
- AppleUniformTypeIdentifiers = new[] { "com.ryujinx.nro" },
- MimeTypes = new[] { "application/x-nx-nro" },
- },
- new("NSO")
- {
- Patterns = new[] { "*.nso" },
- AppleUniformTypeIdentifiers = new[] { "com.ryujinx.nso" },
- MimeTypes = new[] { "application/x-nx-nso" },
- },
- },
- });
-
- if (result.Count > 0)
- {
- await LoadApplication(result[0].Path.LocalPath);
- }
- }
-
- public async Task OpenFolder()
- {
- var result = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
- {
- Title = LocaleManager.Instance[LocaleKeys.OpenFolderDialogTitle],
- AllowMultiple = false,
- });
-
- if (result.Count > 0)
- {
- await LoadApplication(result[0].Path.LocalPath);
- }
- }
-
- public async Task LoadApplication(string path, bool startFullscreen = false, string titleName = "")
- {
- if (AppHost != null)
- {
- await ContentDialogHelper.CreateInfoDialog(
- LocaleManager.Instance[LocaleKeys.DialogLoadAppGameAlreadyLoadedMessage],
- LocaleManager.Instance[LocaleKeys.DialogLoadAppGameAlreadyLoadedSubMessage],
- LocaleManager.Instance[LocaleKeys.InputDialogOk],
- "",
- LocaleManager.Instance[LocaleKeys.RyujinxInfo]);
-
- return;
- }
-
-#if RELEASE
- await PerformanceCheck();
-#endif
-
- Logger.RestartTime();
-
- SelectedIcon ??= ApplicationLibrary.GetApplicationIcon(path, ConfigurationState.Instance.System.Language);
-
- PrepareLoadScreen();
-
- RendererHostControl = new RendererHost();
-
- AppHost = new AppHost(
- RendererHostControl,
- InputManager,
- path,
- VirtualFileSystem,
- ContentManager,
- AccountManager,
- UserChannelPersistence,
- this,
- TopLevel);
-
- if (!await AppHost.LoadGuestApplication())
- {
- AppHost.DisposeContext();
- AppHost = null;
-
- return;
- }
-
- CanUpdate = false;
-
- LoadHeading = TitleName = titleName;
-
- if (string.IsNullOrWhiteSpace(titleName))
- {
- LoadHeading = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.LoadingHeading, AppHost.Device.Processes.ActiveApplication.Name);
- TitleName = AppHost.Device.Processes.ActiveApplication.Name;
- }
-
- SwitchToRenderer(startFullscreen);
-
- _currentEmulatedGamePath = path;
-
- Thread gameThread = new(InitializeGame) { Name = "GUI.WindowThread" };
- gameThread.Start();
- }
-
- public void SwitchToRenderer(bool startFullscreen)
- {
- Dispatcher.UIThread.Post(() =>
- {
- SwitchToGameControl(startFullscreen);
-
- SetMainContent(RendererHostControl);
-
- RendererHostControl.Focus();
- });
- }
-
- public static void UpdateGameMetadata(string titleId)
- {
- ApplicationLibrary.LoadAndSaveMetaData(titleId, appMetadata =>
- {
- appMetadata.UpdatePostGame();
- });
- }
-
- public void RefreshFirmwareStatus()
- {
- SystemVersion version = null;
- try
- {
- version = ContentManager.GetCurrentFirmwareVersion();
- }
- catch (Exception) { }
-
- bool hasApplet = false;
-
- if (version != null)
- {
- LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.StatusBarSystemVersion, version.VersionString);
-
- hasApplet = version.Major > 3;
- }
- else
- {
- LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.StatusBarSystemVersion, "0.0");
- }
-
- IsAppletMenuActive = hasApplet;
- }
-
- public void AppHost_AppExit(object sender, EventArgs e)
- {
- if (IsClosing)
- {
- return;
- }
-
- IsGameRunning = false;
-
- Dispatcher.UIThread.InvokeAsync(async () =>
- {
- ShowMenuAndStatusBar = true;
- ShowContent = true;
- ShowLoadProgress = false;
- IsLoadingIndeterminate = false;
- CanUpdate = true;
- Cursor = Cursor.Default;
-
- SetMainContent(null);
-
- AppHost = null;
-
- await HandleRelaunch();
- });
-
- RendererHostControl.WindowCreated -= RendererHost_Created;
- RendererHostControl = null;
-
- SelectedIcon = null;
-
- Dispatcher.UIThread.InvokeAsync(() =>
- {
- Title = $"Ryujinx {Program.Version}";
- });
- }
-
- public void ToggleFullscreen()
- {
- if (Environment.TickCount64 - LastFullscreenToggle < HotKeyPressDelayMs)
- {
- return;
- }
-
- LastFullscreenToggle = Environment.TickCount64;
-
- if (WindowState == WindowState.FullScreen)
- {
- WindowState = WindowState.Normal;
-
- if (IsGameRunning)
- {
- ShowMenuAndStatusBar = true;
- }
- }
- else
- {
- WindowState = WindowState.FullScreen;
-
- if (IsGameRunning)
- {
- ShowMenuAndStatusBar = false;
- }
- }
-
- IsFullScreen = WindowState == WindowState.FullScreen;
- }
-
- public static void SaveConfig()
- {
- ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
- }
-
- public static async Task PerformanceCheck()
- {
- if (ConfigurationState.Instance.Logger.EnableTrace.Value)
- {
- string mainMessage = LocaleManager.Instance[LocaleKeys.DialogPerformanceCheckLoggingEnabledMessage];
- string secondaryMessage = LocaleManager.Instance[LocaleKeys.DialogPerformanceCheckLoggingEnabledConfirmMessage];
-
- UserResult result = await ContentDialogHelper.CreateConfirmationDialog(
- mainMessage,
- secondaryMessage,
- LocaleManager.Instance[LocaleKeys.InputDialogYes],
- LocaleManager.Instance[LocaleKeys.InputDialogNo],
- LocaleManager.Instance[LocaleKeys.RyujinxConfirm]);
-
- if (result == UserResult.Yes)
- {
- ConfigurationState.Instance.Logger.EnableTrace.Value = false;
-
- SaveConfig();
- }
- }
-
- if (!string.IsNullOrWhiteSpace(ConfigurationState.Instance.Graphics.ShadersDumpPath.Value))
- {
- string mainMessage = LocaleManager.Instance[LocaleKeys.DialogPerformanceCheckShaderDumpEnabledMessage];
- string secondaryMessage = LocaleManager.Instance[LocaleKeys.DialogPerformanceCheckShaderDumpEnabledConfirmMessage];
-
- UserResult result = await ContentDialogHelper.CreateConfirmationDialog(
- mainMessage,
- secondaryMessage,
- LocaleManager.Instance[LocaleKeys.InputDialogYes],
- LocaleManager.Instance[LocaleKeys.InputDialogNo],
- LocaleManager.Instance[LocaleKeys.RyujinxConfirm]);
-
- if (result == UserResult.Yes)
- {
- ConfigurationState.Instance.Graphics.ShadersDumpPath.Value = "";
-
- SaveConfig();
- }
- }
- }
- #endregion
- }
-}
diff --git a/src/Ryujinx.Ava/UI/ViewModels/ModManagerViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/ModManagerViewModel.cs
deleted file mode 100644
index 8321bf89..00000000
--- a/src/Ryujinx.Ava/UI/ViewModels/ModManagerViewModel.cs
+++ /dev/null
@@ -1,336 +0,0 @@
-using Avalonia;
-using Avalonia.Collections;
-using Avalonia.Controls.ApplicationLifetimes;
-using Avalonia.Platform.Storage;
-using Avalonia.Threading;
-using DynamicData;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.Models;
-using Ryujinx.Common.Configuration;
-using Ryujinx.Common.Logging;
-using Ryujinx.Common.Utilities;
-using Ryujinx.HLE.HOS;
-using System;
-using System.IO;
-using System.Linq;
-
-namespace Ryujinx.Ava.UI.ViewModels
-{
- public class ModManagerViewModel : BaseModel
- {
- private readonly string _modJsonPath;
-
- private AvaloniaList<ModModel> _mods = new();
- private AvaloniaList<ModModel> _views = new();
- private AvaloniaList<ModModel> _selectedMods = new();
-
- private string _search;
- private readonly ulong _applicationId;
- private readonly IStorageProvider _storageProvider;
-
- private static readonly ModMetadataJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
-
- public AvaloniaList<ModModel> Mods
- {
- get => _mods;
- set
- {
- _mods = value;
- OnPropertyChanged();
- OnPropertyChanged(nameof(ModCount));
- Sort();
- }
- }
-
- public AvaloniaList<ModModel> Views
- {
- get => _views;
- set
- {
- _views = value;
- OnPropertyChanged();
- }
- }
-
- public AvaloniaList<ModModel> SelectedMods
- {
- get => _selectedMods;
- set
- {
- _selectedMods = value;
- OnPropertyChanged();
- }
- }
-
- public string Search
- {
- get => _search;
- set
- {
- _search = value;
- OnPropertyChanged();
- Sort();
- }
- }
-
- public string ModCount
- {
- get => string.Format(LocaleManager.Instance[LocaleKeys.ModWindowHeading], Mods.Count);
- }
-
- public ModManagerViewModel(ulong applicationId)
- {
- _applicationId = applicationId;
-
- _modJsonPath = Path.Combine(AppDataManager.GamesDirPath, applicationId.ToString("x16"), "mods.json");
-
- if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
- {
- _storageProvider = desktop.MainWindow.StorageProvider;
- }
-
- LoadMods(applicationId);
- }
-
- private void LoadMods(ulong applicationId)
- {
- Mods.Clear();
- SelectedMods.Clear();
-
- string[] modsBasePaths = [ModLoader.GetSdModsBasePath(), ModLoader.GetModsBasePath()];
-
- foreach (var path in modsBasePaths)
- {
- var inSd = path == ModLoader.GetSdModsBasePath();
- var modCache = new ModLoader.ModCache();
-
- ModLoader.QueryContentsDir(modCache, new DirectoryInfo(Path.Combine(path, "contents")), applicationId);
-
- foreach (var mod in modCache.RomfsDirs)
- {
- var modModel = new ModModel(mod.Path.Parent.FullName, mod.Name, mod.Enabled, inSd);
- if (Mods.All(x => x.Path != mod.Path.Parent.FullName))
- {
- Mods.Add(modModel);
- }
- }
-
- foreach (var mod in modCache.RomfsContainers)
- {
- Mods.Add(new ModModel(mod.Path.FullName, mod.Name, mod.Enabled, inSd));
- }
-
- foreach (var mod in modCache.ExefsDirs)
- {
- var modModel = new ModModel(mod.Path.Parent.FullName, mod.Name, mod.Enabled, inSd);
- if (Mods.All(x => x.Path != mod.Path.Parent.FullName))
- {
- Mods.Add(modModel);
- }
- }
-
- foreach (var mod in modCache.ExefsContainers)
- {
- Mods.Add(new ModModel(mod.Path.FullName, mod.Name, mod.Enabled, inSd));
- }
- }
-
- Sort();
- }
-
- public void Sort()
- {
- Mods.AsObservableChangeSet()
- .Filter(Filter)
- .Bind(out var view).AsObservableList();
-
- _views.Clear();
- _views.AddRange(view);
-
- SelectedMods = new(Views.Where(x => x.Enabled));
-
- OnPropertyChanged(nameof(ModCount));
- OnPropertyChanged(nameof(Views));
- OnPropertyChanged(nameof(SelectedMods));
- }
-
- private bool Filter(object arg)
- {
- if (arg is ModModel content)
- {
- return string.IsNullOrWhiteSpace(_search) || content.Name.ToLower().Contains(_search.ToLower());
- }
-
- return false;
- }
-
- public void Save()
- {
- ModMetadata modData = new();
-
- foreach (ModModel mod in Mods)
- {
- modData.Mods.Add(new Mod
- {
- Name = mod.Name,
- Path = mod.Path,
- Enabled = SelectedMods.Contains(mod),
- });
- }
-
- JsonHelper.SerializeToFile(_modJsonPath, modData, _serializerContext.ModMetadata);
- }
-
- public void Delete(ModModel model)
- {
- var isSubdir = true;
- var pathToDelete = model.Path;
- var basePath = model.InSd ? ModLoader.GetSdModsBasePath() : ModLoader.GetModsBasePath();
- var modsDir = ModLoader.GetApplicationDir(basePath, _applicationId.ToString("x16"));
-
- if (new DirectoryInfo(model.Path).Parent?.FullName == modsDir)
- {
- isSubdir = false;
- }
-
- if (isSubdir)
- {
- var parentDir = String.Empty;
-
- foreach (var dir in Directory.GetDirectories(modsDir, "*", SearchOption.TopDirectoryOnly))
- {
- if (Directory.GetDirectories(dir, "*", SearchOption.AllDirectories).Contains(model.Path))
- {
- parentDir = dir;
- break;
- }
- }
-
- if (parentDir == String.Empty)
- {
- Dispatcher.UIThread.Post(async () =>
- {
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(
- LocaleKeys.DialogModDeleteNoParentMessage,
- model.Path));
- });
- return;
- }
- }
-
- Logger.Info?.Print(LogClass.Application, $"Deleting mod at \"{pathToDelete}\"");
- Directory.Delete(pathToDelete, true);
-
- Mods.Remove(model);
- OnPropertyChanged(nameof(ModCount));
- Sort();
- }
-
- private void AddMod(DirectoryInfo directory)
- {
- string[] directories;
-
- try
- {
- directories = Directory.GetDirectories(directory.ToString(), "*", SearchOption.AllDirectories);
- }
- catch (Exception exception)
- {
- Dispatcher.UIThread.Post(async () =>
- {
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(
- LocaleKeys.DialogLoadFileErrorMessage,
- exception.ToString(),
- directory));
- });
- return;
- }
-
- var destinationDir = ModLoader.GetApplicationDir(ModLoader.GetSdModsBasePath(), _applicationId.ToString("x16"));
-
- // TODO: More robust checking for valid mod folders
- var isDirectoryValid = true;
-
- if (directories.Length == 0)
- {
- isDirectoryValid = false;
- }
-
- if (!isDirectoryValid)
- {
- Dispatcher.UIThread.Post(async () =>
- {
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogModInvalidMessage]);
- });
- return;
- }
-
- foreach (var dir in directories)
- {
- string dirToCreate = dir.Replace(directory.Parent.ToString(), destinationDir);
-
- // Mod already exists
- if (Directory.Exists(dirToCreate))
- {
- Dispatcher.UIThread.Post(async () =>
- {
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(
- LocaleKeys.DialogLoadFileErrorMessage,
- LocaleManager.Instance[LocaleKeys.DialogModAlreadyExistsMessage],
- dirToCreate));
- });
-
- return;
- }
-
- Directory.CreateDirectory(dirToCreate);
- }
-
- var files = Directory.GetFiles(directory.ToString(), "*", SearchOption.AllDirectories);
-
- foreach (var file in files)
- {
- File.Copy(file, file.Replace(directory.Parent.ToString(), destinationDir), true);
- }
-
- LoadMods(_applicationId);
- }
-
- public async void Add()
- {
- var result = await _storageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
- {
- Title = LocaleManager.Instance[LocaleKeys.SelectModDialogTitle],
- AllowMultiple = true,
- });
-
- foreach (var folder in result)
- {
- AddMod(new DirectoryInfo(folder.Path.LocalPath));
- }
- }
-
- public void DeleteAll()
- {
- foreach (var mod in Mods)
- {
- Delete(mod);
- }
-
- Mods.Clear();
- OnPropertyChanged(nameof(ModCount));
- Sort();
- }
-
- public void EnableAll()
- {
- SelectedMods = new(Mods);
- }
-
- public void DisableAll()
- {
- SelectedMods.Clear();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/ViewModels/MotionInputViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/MotionInputViewModel.cs
deleted file mode 100644
index 0b12a51f..00000000
--- a/src/Ryujinx.Ava/UI/ViewModels/MotionInputViewModel.cs
+++ /dev/null
@@ -1,93 +0,0 @@
-namespace Ryujinx.Ava.UI.ViewModels
-{
- public class MotionInputViewModel : BaseModel
- {
- private int _slot;
- public int Slot
- {
- get => _slot;
- set
- {
- _slot = value;
- OnPropertyChanged();
- }
- }
-
- private int _altSlot;
- public int AltSlot
- {
- get => _altSlot;
- set
- {
- _altSlot = value;
- OnPropertyChanged();
- }
- }
-
- private string _dsuServerHost;
- public string DsuServerHost
- {
- get => _dsuServerHost;
- set
- {
- _dsuServerHost = value;
- OnPropertyChanged();
- }
- }
-
- private int _dsuServerPort;
- public int DsuServerPort
- {
- get => _dsuServerPort;
- set
- {
- _dsuServerPort = value;
- OnPropertyChanged();
- }
- }
-
- private bool _mirrorInput;
- public bool MirrorInput
- {
- get => _mirrorInput;
- set
- {
- _mirrorInput = value;
- OnPropertyChanged();
- }
- }
-
- private int _sensitivity;
- public int Sensitivity
- {
- get => _sensitivity;
- set
- {
- _sensitivity = value;
- OnPropertyChanged();
- }
- }
-
- private double _gryoDeadzone;
- public double GyroDeadzone
- {
- get => _gryoDeadzone;
- set
- {
- _gryoDeadzone = value;
- OnPropertyChanged();
- }
- }
-
- private bool _enableCemuHookMotion;
- public bool EnableCemuHookMotion
- {
- get => _enableCemuHookMotion;
- set
- {
- _enableCemuHookMotion = value;
- OnPropertyChanged();
- }
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/ViewModels/RumbleInputViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/RumbleInputViewModel.cs
deleted file mode 100644
index 49de1993..00000000
--- a/src/Ryujinx.Ava/UI/ViewModels/RumbleInputViewModel.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-namespace Ryujinx.Ava.UI.ViewModels
-{
- public class RumbleInputViewModel : BaseModel
- {
- private float _strongRumble;
- public float StrongRumble
- {
- get => _strongRumble;
- set
- {
- _strongRumble = value;
- OnPropertyChanged();
- }
- }
-
- private float _weakRumble;
- public float WeakRumble
- {
- get => _weakRumble;
- set
- {
- _weakRumble = value;
- OnPropertyChanged();
- }
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs
deleted file mode 100644
index bcaa0860..00000000
--- a/src/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs
+++ /dev/null
@@ -1,614 +0,0 @@
-using Avalonia.Collections;
-using Avalonia.Controls;
-using Avalonia.Threading;
-using LibHac.Tools.FsSystem;
-using Ryujinx.Audio.Backends.OpenAL;
-using Ryujinx.Audio.Backends.SDL2;
-using Ryujinx.Audio.Backends.SoundIo;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.Windows;
-using Ryujinx.Common.Configuration;
-using Ryujinx.Common.Configuration.Hid;
-using Ryujinx.Common.Configuration.Multiplayer;
-using Ryujinx.Common.GraphicsDriver;
-using Ryujinx.Common.Logging;
-using Ryujinx.Graphics.Vulkan;
-using Ryujinx.HLE.FileSystem;
-using Ryujinx.HLE.HOS.Services.Time.TimeZone;
-using Ryujinx.UI.Common.Configuration;
-using Ryujinx.UI.Common.Configuration.System;
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
-using System.Net.NetworkInformation;
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
-using TimeZone = Ryujinx.Ava.UI.Models.TimeZone;
-
-namespace Ryujinx.Ava.UI.ViewModels
-{
- public class SettingsViewModel : BaseModel
- {
- private readonly VirtualFileSystem _virtualFileSystem;
- private readonly ContentManager _contentManager;
- private TimeZoneContentManager _timeZoneContentManager;
-
- private readonly List<string> _validTzRegions;
-
- private readonly Dictionary<string, string> _networkInterfaces;
-
- private float _customResolutionScale;
- private int _resolutionScale;
- private int _graphicsBackendMultithreadingIndex;
- private float _volume;
- private bool _isVulkanAvailable = true;
- private bool _directoryChanged;
- private readonly List<string> _gpuIds = new();
- private KeyboardHotkeys _keyboardHotkeys;
- private int _graphicsBackendIndex;
- private int _scalingFilter;
- private int _scalingFilterLevel;
-
- public event Action CloseWindow;
- public event Action SaveSettingsEvent;
- private int _networkInterfaceIndex;
- private int _multiplayerModeIndex;
-
- public int ResolutionScale
- {
- get => _resolutionScale;
- set
- {
- _resolutionScale = value;
-
- OnPropertyChanged(nameof(CustomResolutionScale));
- OnPropertyChanged(nameof(IsCustomResolutionScaleActive));
- }
- }
-
- public int GraphicsBackendMultithreadingIndex
- {
- get => _graphicsBackendMultithreadingIndex;
- set
- {
- _graphicsBackendMultithreadingIndex = value;
-
- if (_graphicsBackendMultithreadingIndex != (int)ConfigurationState.Instance.Graphics.BackendThreading.Value)
- {
- Dispatcher.UIThread.InvokeAsync(() =>
- ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.DialogSettingsBackendThreadingWarningMessage],
- "",
- "",
- LocaleManager.Instance[LocaleKeys.InputDialogOk],
- LocaleManager.Instance[LocaleKeys.DialogSettingsBackendThreadingWarningTitle])
- );
- }
-
- OnPropertyChanged();
- }
- }
-
- public float CustomResolutionScale
- {
- get => _customResolutionScale;
- set
- {
- _customResolutionScale = MathF.Round(value, 1);
-
- OnPropertyChanged();
- }
- }
-
- public bool IsVulkanAvailable
- {
- get => _isVulkanAvailable;
- set
- {
- _isVulkanAvailable = value;
-
- OnPropertyChanged();
- }
- }
-
- public bool IsOpenGLAvailable => !OperatingSystem.IsMacOS();
-
- public bool IsHypervisorAvailable => OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64;
-
- public bool DirectoryChanged
- {
- get => _directoryChanged;
- set
- {
- _directoryChanged = value;
-
- OnPropertyChanged();
- }
- }
-
- public bool IsMacOS => OperatingSystem.IsMacOS();
-
- public bool EnableDiscordIntegration { get; set; }
- public bool CheckUpdatesOnStart { get; set; }
- public bool ShowConfirmExit { get; set; }
- public int HideCursor { get; set; }
- public bool EnableDockedMode { get; set; }
- public bool EnableKeyboard { get; set; }
- public bool EnableMouse { get; set; }
- public bool EnableVsync { get; set; }
- public bool EnablePptc { get; set; }
- public bool EnableInternetAccess { get; set; }
- public bool EnableFsIntegrityChecks { get; set; }
- public bool IgnoreMissingServices { get; set; }
- public bool ExpandDramSize { get; set; }
- public bool EnableShaderCache { get; set; }
- public bool EnableTextureRecompression { get; set; }
- public bool EnableMacroHLE { get; set; }
- public bool EnableColorSpacePassthrough { get; set; }
- public bool ColorSpacePassthroughAvailable => IsMacOS;
- public bool EnableFileLog { get; set; }
- public bool EnableStub { get; set; }
- public bool EnableInfo { get; set; }
- public bool EnableWarn { get; set; }
- public bool EnableError { get; set; }
- public bool EnableTrace { get; set; }
- public bool EnableGuest { get; set; }
- public bool EnableFsAccessLog { get; set; }
- public bool EnableDebug { get; set; }
- public bool IsOpenAlEnabled { get; set; }
- public bool IsSoundIoEnabled { get; set; }
- public bool IsSDL2Enabled { get; set; }
- public bool IsCustomResolutionScaleActive => _resolutionScale == 4;
- public bool IsScalingFilterActive => _scalingFilter == (int)Ryujinx.Common.Configuration.ScalingFilter.Fsr;
-
- public bool IsVulkanSelected => GraphicsBackendIndex == 0;
- public bool UseHypervisor { get; set; }
-
- public string TimeZone { get; set; }
- public string ShaderDumpPath { get; set; }
-
- public int Language { get; set; }
- public int Region { get; set; }
- public int FsGlobalAccessLogMode { get; set; }
- public int AudioBackend { get; set; }
- public int MaxAnisotropy { get; set; }
- public int AspectRatio { get; set; }
- public int AntiAliasingEffect { get; set; }
- public string ScalingFilterLevelText => ScalingFilterLevel.ToString("0");
- public int ScalingFilterLevel
- {
- get => _scalingFilterLevel;
- set
- {
- _scalingFilterLevel = value;
- OnPropertyChanged();
- OnPropertyChanged(nameof(ScalingFilterLevelText));
- }
- }
- public int OpenglDebugLevel { get; set; }
- public int MemoryMode { get; set; }
- public int BaseStyleIndex { get; set; }
- public int GraphicsBackendIndex
- {
- get => _graphicsBackendIndex;
- set
- {
- _graphicsBackendIndex = value;
- OnPropertyChanged();
- OnPropertyChanged(nameof(IsVulkanSelected));
- }
- }
- public int ScalingFilter
- {
- get => _scalingFilter;
- set
- {
- _scalingFilter = value;
- OnPropertyChanged();
- OnPropertyChanged(nameof(IsScalingFilterActive));
- }
- }
-
- public int PreferredGpuIndex { get; set; }
-
- public float Volume
- {
- get => _volume;
- set
- {
- _volume = value;
-
- ConfigurationState.Instance.System.AudioVolume.Value = _volume / 100;
-
- OnPropertyChanged();
- }
- }
-
- public DateTimeOffset CurrentDate { get; set; }
- public TimeSpan CurrentTime { get; set; }
-
- internal AvaloniaList<TimeZone> TimeZones { get; set; }
- public AvaloniaList<string> GameDirectories { get; set; }
- public ObservableCollection<ComboBoxItem> AvailableGpus { get; set; }
-
- public AvaloniaList<string> NetworkInterfaceList
- {
- get => new(_networkInterfaces.Keys);
- }
-
- public AvaloniaList<string> MultiplayerModes
- {
- get => new(Enum.GetNames<MultiplayerMode>());
- }
-
- public KeyboardHotkeys KeyboardHotkeys
- {
- get => _keyboardHotkeys;
- set
- {
- _keyboardHotkeys = value;
-
- OnPropertyChanged();
- }
- }
-
- public int NetworkInterfaceIndex
- {
- get => _networkInterfaceIndex;
- set
- {
- _networkInterfaceIndex = value != -1 ? value : 0;
- ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value = _networkInterfaces[NetworkInterfaceList[_networkInterfaceIndex]];
- }
- }
-
- public int MultiplayerModeIndex
- {
- get => _multiplayerModeIndex;
- set
- {
- _multiplayerModeIndex = value;
- ConfigurationState.Instance.Multiplayer.Mode.Value = (MultiplayerMode)_multiplayerModeIndex;
- }
- }
-
- public SettingsViewModel(VirtualFileSystem virtualFileSystem, ContentManager contentManager) : this()
- {
- _virtualFileSystem = virtualFileSystem;
- _contentManager = contentManager;
- if (Program.PreviewerDetached)
- {
- Task.Run(LoadTimeZones);
- }
- }
-
- public SettingsViewModel()
- {
- GameDirectories = new AvaloniaList<string>();
- TimeZones = new AvaloniaList<TimeZone>();
- AvailableGpus = new ObservableCollection<ComboBoxItem>();
- _validTzRegions = new List<string>();
- _networkInterfaces = new Dictionary<string, string>();
-
- Task.Run(CheckSoundBackends);
- Task.Run(PopulateNetworkInterfaces);
-
- if (Program.PreviewerDetached)
- {
- Task.Run(LoadAvailableGpus);
- LoadCurrentConfiguration();
- }
- }
-
- public async Task CheckSoundBackends()
- {
- IsOpenAlEnabled = OpenALHardwareDeviceDriver.IsSupported;
- IsSoundIoEnabled = SoundIoHardwareDeviceDriver.IsSupported;
- IsSDL2Enabled = SDL2HardwareDeviceDriver.IsSupported;
-
- await Dispatcher.UIThread.InvokeAsync(() =>
- {
- OnPropertyChanged(nameof(IsOpenAlEnabled));
- OnPropertyChanged(nameof(IsSoundIoEnabled));
- OnPropertyChanged(nameof(IsSDL2Enabled));
- });
- }
-
- private async Task LoadAvailableGpus()
- {
- AvailableGpus.Clear();
-
- var devices = VulkanRenderer.GetPhysicalDevices();
-
- if (devices.Length == 0)
- {
- IsVulkanAvailable = false;
- GraphicsBackendIndex = 1;
- }
- else
- {
- foreach (var device in devices)
- {
- await Dispatcher.UIThread.InvokeAsync(() =>
- {
- _gpuIds.Add(device.Id);
-
- AvailableGpus.Add(new ComboBoxItem { Content = $"{device.Name} {(device.IsDiscrete ? "(dGPU)" : "")}" });
- });
- }
- }
-
- // GPU configuration needs to be loaded during the async method or it will always return 0.
- PreferredGpuIndex = _gpuIds.Contains(ConfigurationState.Instance.Graphics.PreferredGpu) ?
- _gpuIds.IndexOf(ConfigurationState.Instance.Graphics.PreferredGpu) : 0;
-
- Dispatcher.UIThread.Post(() => OnPropertyChanged(nameof(PreferredGpuIndex)));
- }
-
- public async Task LoadTimeZones()
- {
- _timeZoneContentManager = new TimeZoneContentManager();
-
- _timeZoneContentManager.InitializeInstance(_virtualFileSystem, _contentManager, IntegrityCheckLevel.None);
-
- foreach ((int offset, string location, string abbr) in _timeZoneContentManager.ParseTzOffsets())
- {
- int hours = Math.DivRem(offset, 3600, out int seconds);
- int minutes = Math.Abs(seconds) / 60;
-
- string abbr2 = abbr.StartsWith('+') || abbr.StartsWith('-') ? string.Empty : abbr;
-
- await Dispatcher.UIThread.InvokeAsync(() =>
- {
- TimeZones.Add(new TimeZone($"UTC{hours:+0#;-0#;+00}:{minutes:D2}", location, abbr2));
-
- _validTzRegions.Add(location);
- });
- }
-
- Dispatcher.UIThread.Post(() => OnPropertyChanged(nameof(TimeZone)));
- }
-
- private async Task PopulateNetworkInterfaces()
- {
- _networkInterfaces.Clear();
- _networkInterfaces.Add(LocaleManager.Instance[LocaleKeys.NetworkInterfaceDefault], "0");
-
- foreach (NetworkInterface networkInterface in NetworkInterface.GetAllNetworkInterfaces())
- {
- await Dispatcher.UIThread.InvokeAsync(() =>
- {
- _networkInterfaces.Add(networkInterface.Name, networkInterface.Id);
- });
- }
-
- // Network interface index needs to be loaded during the async method or it will always return 0.
- NetworkInterfaceIndex = _networkInterfaces.Values.ToList().IndexOf(ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value);
-
- Dispatcher.UIThread.Post(() => OnPropertyChanged(nameof(NetworkInterfaceIndex)));
- }
-
- public void ValidateAndSetTimeZone(string location)
- {
- if (_validTzRegions.Contains(location))
- {
- TimeZone = location;
- }
- }
-
- public void LoadCurrentConfiguration()
- {
- ConfigurationState config = ConfigurationState.Instance;
-
- // User Interface
- EnableDiscordIntegration = config.EnableDiscordIntegration;
- CheckUpdatesOnStart = config.CheckUpdatesOnStart;
- ShowConfirmExit = config.ShowConfirmExit;
- HideCursor = (int)config.HideCursor.Value;
-
- GameDirectories.Clear();
- GameDirectories.AddRange(config.UI.GameDirs.Value);
-
- BaseStyleIndex = config.UI.BaseStyle == "Light" ? 0 : 1;
-
- // Input
- EnableDockedMode = config.System.EnableDockedMode;
- EnableKeyboard = config.Hid.EnableKeyboard;
- EnableMouse = config.Hid.EnableMouse;
-
- // Keyboard Hotkeys
- KeyboardHotkeys = config.Hid.Hotkeys.Value;
-
- // System
- Region = (int)config.System.Region.Value;
- Language = (int)config.System.Language.Value;
- TimeZone = config.System.TimeZone;
-
- DateTime currentDateTime = DateTime.Now;
-
- CurrentDate = currentDateTime.Date;
- CurrentTime = currentDateTime.TimeOfDay.Add(TimeSpan.FromSeconds(config.System.SystemTimeOffset));
-
- EnableVsync = config.Graphics.EnableVsync;
- EnableFsIntegrityChecks = config.System.EnableFsIntegrityChecks;
- ExpandDramSize = config.System.ExpandRam;
- IgnoreMissingServices = config.System.IgnoreMissingServices;
-
- // CPU
- EnablePptc = config.System.EnablePtc;
- MemoryMode = (int)config.System.MemoryManagerMode.Value;
- UseHypervisor = config.System.UseHypervisor;
-
- // Graphics
- GraphicsBackendIndex = (int)config.Graphics.GraphicsBackend.Value;
- // Physical devices are queried asynchronously hence the prefered index config value is loaded in LoadAvailableGpus().
- EnableShaderCache = config.Graphics.EnableShaderCache;
- EnableTextureRecompression = config.Graphics.EnableTextureRecompression;
- EnableMacroHLE = config.Graphics.EnableMacroHLE;
- EnableColorSpacePassthrough = config.Graphics.EnableColorSpacePassthrough;
- ResolutionScale = config.Graphics.ResScale == -1 ? 4 : config.Graphics.ResScale - 1;
- CustomResolutionScale = config.Graphics.ResScaleCustom;
- MaxAnisotropy = config.Graphics.MaxAnisotropy == -1 ? 0 : (int)(MathF.Log2(config.Graphics.MaxAnisotropy));
- AspectRatio = (int)config.Graphics.AspectRatio.Value;
- GraphicsBackendMultithreadingIndex = (int)config.Graphics.BackendThreading.Value;
- ShaderDumpPath = config.Graphics.ShadersDumpPath;
- AntiAliasingEffect = (int)config.Graphics.AntiAliasing.Value;
- ScalingFilter = (int)config.Graphics.ScalingFilter.Value;
- ScalingFilterLevel = config.Graphics.ScalingFilterLevel.Value;
-
- // Audio
- AudioBackend = (int)config.System.AudioBackend.Value;
- Volume = config.System.AudioVolume * 100;
-
- // Network
- EnableInternetAccess = config.System.EnableInternetAccess;
- // LAN interface index is loaded asynchronously in PopulateNetworkInterfaces()
-
- // Logging
- EnableFileLog = config.Logger.EnableFileLog;
- EnableStub = config.Logger.EnableStub;
- EnableInfo = config.Logger.EnableInfo;
- EnableWarn = config.Logger.EnableWarn;
- EnableError = config.Logger.EnableError;
- EnableTrace = config.Logger.EnableTrace;
- EnableGuest = config.Logger.EnableGuest;
- EnableDebug = config.Logger.EnableDebug;
- EnableFsAccessLog = config.Logger.EnableFsAccessLog;
- FsGlobalAccessLogMode = config.System.FsGlobalAccessLogMode;
- OpenglDebugLevel = (int)config.Logger.GraphicsDebugLevel.Value;
-
- MultiplayerModeIndex = (int)config.Multiplayer.Mode.Value;
- }
-
- public void SaveSettings()
- {
- ConfigurationState config = ConfigurationState.Instance;
-
- // User Interface
- config.EnableDiscordIntegration.Value = EnableDiscordIntegration;
- config.CheckUpdatesOnStart.Value = CheckUpdatesOnStart;
- config.ShowConfirmExit.Value = ShowConfirmExit;
- config.HideCursor.Value = (HideCursorMode)HideCursor;
-
- if (_directoryChanged)
- {
- List<string> gameDirs = new(GameDirectories);
- config.UI.GameDirs.Value = gameDirs;
- }
-
- config.UI.BaseStyle.Value = BaseStyleIndex == 0 ? "Light" : "Dark";
-
- // Input
- config.System.EnableDockedMode.Value = EnableDockedMode;
- config.Hid.EnableKeyboard.Value = EnableKeyboard;
- config.Hid.EnableMouse.Value = EnableMouse;
-
- // Keyboard Hotkeys
- config.Hid.Hotkeys.Value = KeyboardHotkeys;
-
- // System
- config.System.Region.Value = (Region)Region;
- config.System.Language.Value = (Language)Language;
-
- if (_validTzRegions.Contains(TimeZone))
- {
- config.System.TimeZone.Value = TimeZone;
- }
-
- config.System.SystemTimeOffset.Value = Convert.ToInt64((CurrentDate.ToUnixTimeSeconds() + CurrentTime.TotalSeconds) - DateTimeOffset.Now.ToUnixTimeSeconds());
- config.Graphics.EnableVsync.Value = EnableVsync;
- config.System.EnableFsIntegrityChecks.Value = EnableFsIntegrityChecks;
- config.System.ExpandRam.Value = ExpandDramSize;
- config.System.IgnoreMissingServices.Value = IgnoreMissingServices;
-
- // CPU
- config.System.EnablePtc.Value = EnablePptc;
- config.System.MemoryManagerMode.Value = (MemoryManagerMode)MemoryMode;
- config.System.UseHypervisor.Value = UseHypervisor;
-
- // Graphics
- config.Graphics.GraphicsBackend.Value = (GraphicsBackend)GraphicsBackendIndex;
- config.Graphics.PreferredGpu.Value = _gpuIds.ElementAtOrDefault(PreferredGpuIndex);
- config.Graphics.EnableShaderCache.Value = EnableShaderCache;
- config.Graphics.EnableTextureRecompression.Value = EnableTextureRecompression;
- config.Graphics.EnableMacroHLE.Value = EnableMacroHLE;
- config.Graphics.EnableColorSpacePassthrough.Value = EnableColorSpacePassthrough;
- config.Graphics.ResScale.Value = ResolutionScale == 4 ? -1 : ResolutionScale + 1;
- config.Graphics.ResScaleCustom.Value = CustomResolutionScale;
- config.Graphics.MaxAnisotropy.Value = MaxAnisotropy == 0 ? -1 : MathF.Pow(2, MaxAnisotropy);
- config.Graphics.AspectRatio.Value = (AspectRatio)AspectRatio;
- config.Graphics.AntiAliasing.Value = (AntiAliasing)AntiAliasingEffect;
- config.Graphics.ScalingFilter.Value = (ScalingFilter)ScalingFilter;
- config.Graphics.ScalingFilterLevel.Value = ScalingFilterLevel;
-
- if (ConfigurationState.Instance.Graphics.BackendThreading != (BackendThreading)GraphicsBackendMultithreadingIndex)
- {
- DriverUtilities.ToggleOGLThreading(GraphicsBackendMultithreadingIndex == (int)BackendThreading.Off);
- }
-
- config.Graphics.BackendThreading.Value = (BackendThreading)GraphicsBackendMultithreadingIndex;
- config.Graphics.ShadersDumpPath.Value = ShaderDumpPath;
-
- // Audio
- AudioBackend audioBackend = (AudioBackend)AudioBackend;
- if (audioBackend != config.System.AudioBackend.Value)
- {
- config.System.AudioBackend.Value = audioBackend;
-
- Logger.Info?.Print(LogClass.Application, $"AudioBackend toggled to: {audioBackend}");
- }
-
- config.System.AudioVolume.Value = Volume / 100;
-
- // Network
- config.System.EnableInternetAccess.Value = EnableInternetAccess;
-
- // Logging
- config.Logger.EnableFileLog.Value = EnableFileLog;
- config.Logger.EnableStub.Value = EnableStub;
- config.Logger.EnableInfo.Value = EnableInfo;
- config.Logger.EnableWarn.Value = EnableWarn;
- config.Logger.EnableError.Value = EnableError;
- config.Logger.EnableTrace.Value = EnableTrace;
- config.Logger.EnableGuest.Value = EnableGuest;
- config.Logger.EnableDebug.Value = EnableDebug;
- config.Logger.EnableFsAccessLog.Value = EnableFsAccessLog;
- config.System.FsGlobalAccessLogMode.Value = FsGlobalAccessLogMode;
- config.Logger.GraphicsDebugLevel.Value = (GraphicsDebugLevel)OpenglDebugLevel;
-
- config.Multiplayer.LanInterfaceId.Value = _networkInterfaces[NetworkInterfaceList[NetworkInterfaceIndex]];
- config.Multiplayer.Mode.Value = (MultiplayerMode)MultiplayerModeIndex;
-
- config.ToFileFormat().SaveConfig(Program.ConfigurationPath);
-
- MainWindow.UpdateGraphicsConfig();
-
- SaveSettingsEvent?.Invoke();
-
- _directoryChanged = false;
- }
-
- private static void RevertIfNotSaved()
- {
- Program.ReloadConfig();
- }
-
- public void ApplyButton()
- {
- SaveSettings();
- }
-
- public void OkButton()
- {
- SaveSettings();
- CloseWindow?.Invoke();
- }
-
- public void CancelButton()
- {
- RevertIfNotSaved();
- CloseWindow?.Invoke();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs
deleted file mode 100644
index 5989ce09..00000000
--- a/src/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs
+++ /dev/null
@@ -1,249 +0,0 @@
-using Avalonia;
-using Avalonia.Collections;
-using Avalonia.Controls.ApplicationLifetimes;
-using Avalonia.Platform.Storage;
-using Avalonia.Threading;
-using LibHac.Common;
-using LibHac.Fs;
-using LibHac.Fs.Fsa;
-using LibHac.FsSystem;
-using LibHac.Ns;
-using LibHac.Tools.FsSystem;
-using LibHac.Tools.FsSystem.NcaUtils;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.Models;
-using Ryujinx.Common.Configuration;
-using Ryujinx.Common.Logging;
-using Ryujinx.Common.Utilities;
-using Ryujinx.HLE.FileSystem;
-using Ryujinx.UI.App.Common;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Threading.Tasks;
-using Path = System.IO.Path;
-using SpanHelpers = LibHac.Common.SpanHelpers;
-
-namespace Ryujinx.Ava.UI.ViewModels
-{
- public class TitleUpdateViewModel : BaseModel
- {
- public TitleUpdateMetadata TitleUpdateWindowData;
- public readonly string TitleUpdateJsonPath;
- private VirtualFileSystem VirtualFileSystem { get; }
- private ulong TitleId { get; }
-
- private AvaloniaList<TitleUpdateModel> _titleUpdates = new();
- private AvaloniaList<object> _views = new();
- private object _selectedUpdate;
-
- private static readonly TitleUpdateMetadataJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
-
- public AvaloniaList<TitleUpdateModel> TitleUpdates
- {
- get => _titleUpdates;
- set
- {
- _titleUpdates = value;
- OnPropertyChanged();
- }
- }
-
- public AvaloniaList<object> Views
- {
- get => _views;
- set
- {
- _views = value;
- OnPropertyChanged();
- }
- }
-
- public object SelectedUpdate
- {
- get => _selectedUpdate;
- set
- {
- _selectedUpdate = value;
- OnPropertyChanged();
- }
- }
-
- public IStorageProvider StorageProvider;
-
- public TitleUpdateViewModel(VirtualFileSystem virtualFileSystem, ulong titleId)
- {
- VirtualFileSystem = virtualFileSystem;
-
- TitleId = titleId;
-
- if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
- {
- StorageProvider = desktop.MainWindow.StorageProvider;
- }
-
- TitleUpdateJsonPath = Path.Combine(AppDataManager.GamesDirPath, titleId.ToString("x16"), "updates.json");
-
- try
- {
- TitleUpdateWindowData = JsonHelper.DeserializeFromFile(TitleUpdateJsonPath, _serializerContext.TitleUpdateMetadata);
- }
- catch
- {
- Logger.Warning?.Print(LogClass.Application, $"Failed to deserialize title update data for {TitleId} at {TitleUpdateJsonPath}");
-
- TitleUpdateWindowData = new TitleUpdateMetadata
- {
- Selected = "",
- Paths = new List<string>(),
- };
-
- Save();
- }
-
- LoadUpdates();
- }
-
- private void LoadUpdates()
- {
- foreach (string path in TitleUpdateWindowData.Paths)
- {
- AddUpdate(path);
- }
-
- TitleUpdateModel selected = TitleUpdates.FirstOrDefault(x => x.Path == TitleUpdateWindowData.Selected, null);
-
- SelectedUpdate = selected;
-
- // NOTE: Save the list again to remove leftovers.
- Save();
- SortUpdates();
- }
-
- public void SortUpdates()
- {
- var list = TitleUpdates.ToList();
-
- list.Sort((first, second) =>
- {
- if (string.IsNullOrEmpty(first.Control.DisplayVersionString.ToString()))
- {
- return -1;
- }
-
- if (string.IsNullOrEmpty(second.Control.DisplayVersionString.ToString()))
- {
- return 1;
- }
-
- return Version.Parse(first.Control.DisplayVersionString.ToString()).CompareTo(Version.Parse(second.Control.DisplayVersionString.ToString())) * -1;
- });
-
- Views.Clear();
- Views.Add(new BaseModel());
- Views.AddRange(list);
-
- if (SelectedUpdate == null)
- {
- SelectedUpdate = Views[0];
- }
- else if (!TitleUpdates.Contains(SelectedUpdate))
- {
- if (Views.Count > 1)
- {
- SelectedUpdate = Views[1];
- }
- else
- {
- SelectedUpdate = Views[0];
- }
- }
- }
-
- private void AddUpdate(string path)
- {
- if (File.Exists(path) && TitleUpdates.All(x => x.Path != path))
- {
- using FileStream file = new(path, FileMode.Open, FileAccess.Read);
-
- try
- {
- var pfs = new PartitionFileSystem();
- pfs.Initialize(file.AsStorage()).ThrowIfFailure();
- (Nca patchNca, Nca controlNca) = ApplicationLibrary.GetGameUpdateDataFromPartition(VirtualFileSystem, pfs, TitleId.ToString("x16"), 0);
-
- if (controlNca != null && patchNca != null)
- {
- ApplicationControlProperty controlData = new();
-
- using UniqueRef<IFile> nacpFile = new();
-
- controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None).OpenFile(ref nacpFile.Ref, "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure();
- nacpFile.Get.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None).ThrowIfFailure();
-
- TitleUpdates.Add(new TitleUpdateModel(controlData, path));
- }
- else
- {
- Dispatcher.UIThread.InvokeAsync(() => ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogUpdateAddUpdateErrorMessage]));
- }
- }
- catch (Exception ex)
- {
- Dispatcher.UIThread.InvokeAsync(() => ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogLoadFileErrorMessage, ex.Message, path)));
- }
- }
- }
-
- public void RemoveUpdate(TitleUpdateModel update)
- {
- TitleUpdates.Remove(update);
-
- SortUpdates();
- }
-
- public async Task Add()
- {
- var result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
- {
- AllowMultiple = true,
- FileTypeFilter = new List<FilePickerFileType>
- {
- new(LocaleManager.Instance[LocaleKeys.AllSupportedFormats])
- {
- Patterns = new[] { "*.nsp" },
- AppleUniformTypeIdentifiers = new[] { "com.ryujinx.nsp" },
- MimeTypes = new[] { "application/x-nx-nsp" },
- },
- },
- });
-
- foreach (var file in result)
- {
- AddUpdate(file.Path.LocalPath);
- }
-
- SortUpdates();
- }
-
- public void Save()
- {
- TitleUpdateWindowData.Paths.Clear();
- TitleUpdateWindowData.Selected = "";
-
- foreach (TitleUpdateModel update in TitleUpdates)
- {
- TitleUpdateWindowData.Paths.Add(update.Path);
-
- if (update == SelectedUpdate)
- {
- TitleUpdateWindowData.Selected = update.Path;
- }
- }
-
- JsonHelper.SerializeToFile(TitleUpdateJsonPath, TitleUpdateWindowData, _serializerContext.TitleUpdateMetadata);
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/ViewModels/UserFirmwareAvatarSelectorViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/UserFirmwareAvatarSelectorViewModel.cs
deleted file mode 100644
index 89b59122..00000000
--- a/src/Ryujinx.Ava/UI/ViewModels/UserFirmwareAvatarSelectorViewModel.cs
+++ /dev/null
@@ -1,222 +0,0 @@
-using Avalonia.Media;
-using LibHac.Common;
-using LibHac.Fs;
-using LibHac.Fs.Fsa;
-using LibHac.FsSystem;
-using LibHac.Ncm;
-using LibHac.Tools.Fs;
-using LibHac.Tools.FsSystem;
-using LibHac.Tools.FsSystem.NcaUtils;
-using Ryujinx.Ava.UI.Models;
-using Ryujinx.HLE.FileSystem;
-using SixLabors.ImageSharp;
-using SixLabors.ImageSharp.PixelFormats;
-using System;
-using System.Buffers.Binary;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.IO;
-using Color = Avalonia.Media.Color;
-
-namespace Ryujinx.Ava.UI.ViewModels
-{
- internal class UserFirmwareAvatarSelectorViewModel : BaseModel
- {
- private static readonly Dictionary<string, byte[]> _avatarStore = new();
-
- private ObservableCollection<ProfileImageModel> _images;
- private Color _backgroundColor = Colors.White;
-
- private int _selectedIndex;
-
- public UserFirmwareAvatarSelectorViewModel()
- {
- _images = new ObservableCollection<ProfileImageModel>();
-
- LoadImagesFromStore();
- }
-
- public Color BackgroundColor
- {
- get => _backgroundColor;
- set
- {
- _backgroundColor = value;
- OnPropertyChanged();
- ChangeImageBackground();
- }
- }
-
- public ObservableCollection<ProfileImageModel> Images
- {
- get => _images;
- set
- {
- _images = value;
- OnPropertyChanged();
- }
- }
-
- public int SelectedIndex
- {
- get => _selectedIndex;
- set
- {
- _selectedIndex = value;
-
- if (_selectedIndex == -1)
- {
- SelectedImage = null;
- }
- else
- {
- SelectedImage = _images[_selectedIndex].Data;
- }
-
- OnPropertyChanged();
- }
- }
-
- public byte[] SelectedImage { get; private set; }
-
- private void LoadImagesFromStore()
- {
- Images.Clear();
-
- foreach (var image in _avatarStore)
- {
- Images.Add(new ProfileImageModel(image.Key, image.Value));
- }
- }
-
- private void ChangeImageBackground()
- {
- foreach (var image in Images)
- {
- image.BackgroundColor = new SolidColorBrush(BackgroundColor);
- }
- }
-
- public static void PreloadAvatars(ContentManager contentManager, VirtualFileSystem virtualFileSystem)
- {
- if (_avatarStore.Count > 0)
- {
- return;
- }
-
- string contentPath = contentManager.GetInstalledContentPath(0x010000000000080A, StorageId.BuiltInSystem, NcaContentType.Data);
- string avatarPath = VirtualFileSystem.SwitchPathToSystemPath(contentPath);
-
- if (!string.IsNullOrWhiteSpace(avatarPath))
- {
- using IStorage ncaFileStream = new LocalStorage(avatarPath, FileAccess.Read, FileMode.Open);
-
- Nca nca = new(virtualFileSystem.KeySet, ncaFileStream);
- IFileSystem romfs = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
-
- foreach (DirectoryEntryEx item in romfs.EnumerateEntries())
- {
- // TODO: Parse DatabaseInfo.bin and table.bin files for more accuracy.
- if (item.Type == DirectoryEntryType.File && item.FullPath.Contains("chara") && item.FullPath.Contains("szs"))
- {
- using var file = new UniqueRef<IFile>();
-
- romfs.OpenFile(ref file.Ref, ("/" + item.FullPath).ToU8Span(), OpenMode.Read).ThrowIfFailure();
-
- using MemoryStream stream = new();
- using MemoryStream streamPng = new();
-
- file.Get.AsStream().CopyTo(stream);
-
- stream.Position = 0;
-
- Image avatarImage = Image.LoadPixelData<Rgba32>(DecompressYaz0(stream), 256, 256);
-
- avatarImage.SaveAsPng(streamPng);
-
- _avatarStore.Add(item.FullPath, streamPng.ToArray());
- }
- }
- }
- }
-
- private static byte[] DecompressYaz0(Stream stream)
- {
- using BinaryReader reader = new(stream);
-
- reader.ReadInt32(); // Magic
-
- uint decodedLength = BinaryPrimitives.ReverseEndianness(reader.ReadUInt32());
-
- reader.ReadInt64(); // Padding
-
- byte[] input = new byte[stream.Length - stream.Position];
- stream.Read(input, 0, input.Length);
-
- uint inputOffset = 0;
-
- byte[] output = new byte[decodedLength];
- uint outputOffset = 0;
-
- ushort mask = 0;
- byte header = 0;
-
- while (outputOffset < decodedLength)
- {
- if ((mask >>= 1) == 0)
- {
- header = input[inputOffset++];
- mask = 0x80;
- }
-
- if ((header & mask) != 0)
- {
- if (outputOffset == output.Length)
- {
- break;
- }
-
- output[outputOffset++] = input[inputOffset++];
- }
- else
- {
- byte byte1 = input[inputOffset++];
- byte byte2 = input[inputOffset++];
-
- uint dist = (uint)((byte1 & 0xF) << 8) | byte2;
- uint position = outputOffset - (dist + 1);
-
- uint length = (uint)byte1 >> 4;
- if (length == 0)
- {
- length = (uint)input[inputOffset++] + 0x12;
- }
- else
- {
- length += 2;
- }
-
- uint gap = outputOffset - position;
- uint nonOverlappingLength = length;
-
- if (nonOverlappingLength > gap)
- {
- nonOverlappingLength = gap;
- }
-
- Buffer.BlockCopy(output, (int)position, output, (int)outputOffset, (int)nonOverlappingLength);
- outputOffset += nonOverlappingLength;
- position += nonOverlappingLength;
- length -= nonOverlappingLength;
-
- while (length-- > 0)
- {
- output[outputOffset++] = output[position++];
- }
- }
- }
-
- return output;
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/ViewModels/UserProfileImageSelectorViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/UserProfileImageSelectorViewModel.cs
deleted file mode 100644
index 8e7d41a5..00000000
--- a/src/Ryujinx.Ava/UI/ViewModels/UserProfileImageSelectorViewModel.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace Ryujinx.Ava.UI.ViewModels
-{
- internal class UserProfileImageSelectorViewModel : BaseModel
- {
- private bool _firmwareFound;
-
- public bool FirmwareFound
- {
- get => _firmwareFound;
-
- set
- {
- _firmwareFound = value;
- OnPropertyChanged();
- }
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/ViewModels/UserProfileViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/UserProfileViewModel.cs
deleted file mode 100644
index 70274847..00000000
--- a/src/Ryujinx.Ava/UI/ViewModels/UserProfileViewModel.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using Microsoft.IdentityModel.Tokens;
-using Ryujinx.Ava.UI.Models;
-using System;
-using System.Collections.ObjectModel;
-
-namespace Ryujinx.Ava.UI.ViewModels
-{
- public class UserProfileViewModel : BaseModel, IDisposable
- {
- public UserProfileViewModel()
- {
- Profiles = new ObservableCollection<BaseModel>();
- LostProfiles = new ObservableCollection<UserProfile>();
- IsEmpty = LostProfiles.IsNullOrEmpty();
- }
-
- public ObservableCollection<BaseModel> Profiles { get; set; }
-
- public ObservableCollection<UserProfile> LostProfiles { get; set; }
-
- public bool IsEmpty { get; set; }
-
- public void Dispose()
- {
- GC.SuppressFinalize(this);
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/ViewModels/UserSaveManagerViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/UserSaveManagerViewModel.cs
deleted file mode 100644
index 85adef00..00000000
--- a/src/Ryujinx.Ava/UI/ViewModels/UserSaveManagerViewModel.cs
+++ /dev/null
@@ -1,117 +0,0 @@
-using DynamicData;
-using DynamicData.Binding;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Models;
-using Ryujinx.HLE.HOS.Services.Account.Acc;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-
-namespace Ryujinx.Ava.UI.ViewModels
-{
- public class UserSaveManagerViewModel : BaseModel
- {
- private int _sortIndex;
- private int _orderIndex;
- private string _search;
- private ObservableCollection<SaveModel> _saves = new();
- private ObservableCollection<SaveModel> _views = new();
- private readonly AccountManager _accountManager;
-
- public string SaveManagerHeading => LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SaveManagerHeading, _accountManager.LastOpenedUser.Name, _accountManager.LastOpenedUser.UserId);
-
- public int SortIndex
- {
- get => _sortIndex;
- set
- {
- _sortIndex = value;
- OnPropertyChanged();
- Sort();
- }
- }
-
- public int OrderIndex
- {
- get => _orderIndex;
- set
- {
- _orderIndex = value;
- OnPropertyChanged();
- Sort();
- }
- }
-
- public string Search
- {
- get => _search;
- set
- {
- _search = value;
- OnPropertyChanged();
- Sort();
- }
- }
-
- public ObservableCollection<SaveModel> Saves
- {
- get => _saves;
- set
- {
- _saves = value;
- OnPropertyChanged();
- Sort();
- }
- }
-
- public ObservableCollection<SaveModel> Views
- {
- get => _views;
- set
- {
- _views = value;
- OnPropertyChanged();
- }
- }
-
- public UserSaveManagerViewModel(AccountManager accountManager)
- {
- _accountManager = accountManager;
- }
-
- public void Sort()
- {
- Saves.AsObservableChangeSet()
- .Filter(Filter)
- .Sort(GetComparer())
- .Bind(out var view).AsObservableList();
-
- _views.Clear();
- _views.AddRange(view);
- OnPropertyChanged(nameof(Views));
- }
-
- private bool Filter(object arg)
- {
- if (arg is SaveModel save)
- {
- return string.IsNullOrWhiteSpace(_search) || save.Title.ToLower().Contains(_search.ToLower());
- }
-
- return false;
- }
-
- private IComparer<SaveModel> GetComparer()
- {
- return SortIndex switch
- {
- 0 => OrderIndex == 0
- ? SortExpressionComparer<SaveModel>.Ascending(save => save.Title)
- : SortExpressionComparer<SaveModel>.Descending(save => save.Title),
- 1 => OrderIndex == 0
- ? SortExpressionComparer<SaveModel>.Ascending(save => save.Size)
- : SortExpressionComparer<SaveModel>.Descending(save => save.Size),
- _ => null,
- };
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml b/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml
deleted file mode 100644
index 99f2b6b6..00000000
--- a/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml
+++ /dev/null
@@ -1,1130 +0,0 @@
-<UserControl
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
- xmlns:models="clr-namespace:Ryujinx.Ava.UI.Models"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- d:DesignHeight="800"
- d:DesignWidth="800"
- x:Class="Ryujinx.Ava.UI.Views.Input.ControllerInputView"
- x:DataType="viewModels:ControllerInputViewModel"
- mc:Ignorable="d"
- Focusable="True">
- <Design.DataContext>
- <viewModels:ControllerInputViewModel />
- </Design.DataContext>
- <UserControl.Resources>
- <helpers:KeyValueConverter x:Key="Key" />
- </UserControl.Resources>
- <UserControl.Styles>
- <Style Selector="ToggleButton">
- <Setter Property="Width" Value="90" />
- <Setter Property="Height" Value="27" />
- <Setter Property="HorizontalAlignment" Value="Stretch" />
- </Style>
- </UserControl.Styles>
- <StackPanel
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- Orientation="Vertical">
- <StackPanel
- Margin="0 0 0 5"
- Orientation="Vertical"
- Spacing="5">
- <Grid>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="*" />
- <ColumnDefinition Width="10" />
- <ColumnDefinition Width="*" />
- </Grid.ColumnDefinitions>
- <!-- Player Selection -->
- <Grid
- Grid.Column="0"
- Margin="2"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Center">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto"/>
- <ColumnDefinition Width="*" />
- </Grid.ColumnDefinitions>
- <TextBlock
- Margin="5,0,10,0"
- Width="90"
- HorizontalAlignment="Left"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsPlayer}" />
- <ComboBox
- Grid.Column="1"
- Name="PlayerIndexBox"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Center"
- SelectionChanged="PlayerIndexBox_OnSelectionChanged"
- ItemsSource="{Binding PlayerIndexes}"
- SelectedIndex="{Binding PlayerId}">
- <ComboBox.ItemTemplate>
- <DataTemplate>
- <TextBlock Text="{Binding Name}" />
- </DataTemplate>
- </ComboBox.ItemTemplate>
- </ComboBox>
- </Grid>
- <!-- Profile Selection -->
- <Grid
- Grid.Column="2"
- Margin="2"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Center">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto"/>
- <ColumnDefinition Width="*" />
- <ColumnDefinition Width="Auto"/>
- <ColumnDefinition Width="Auto"/>
- <ColumnDefinition Width="Auto"/>
- </Grid.ColumnDefinitions>
- <TextBlock
- Margin="5,0,10,0"
- Width="90"
- HorizontalAlignment="Left"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsProfile}" />
- <ui:FAComboBox
- Grid.Column="1"
- IsEditable="True"
- Name="ProfileBox"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Center"
- SelectedIndex="0"
- ItemsSource="{Binding ProfilesList}"
- Text="{Binding ProfileName, Mode=TwoWay}" />
- <Button
- Grid.Column="2"
- MinWidth="0"
- Margin="5,0,0,0"
- VerticalAlignment="Center"
- ToolTip.Tip="{locale:Locale ControllerSettingsLoadProfileToolTip}"
- Command="{ReflectionBinding LoadProfile}">
- <ui:SymbolIcon
- Symbol="Upload"
- FontSize="15"
- Height="20" />
- </Button>
- <Button
- Grid.Column="3"
- MinWidth="0"
- Margin="5,0,0,0"
- VerticalAlignment="Center"
- ToolTip.Tip="{locale:Locale ControllerSettingsSaveProfileToolTip}"
- Command="{ReflectionBinding SaveProfile}">
- <ui:SymbolIcon
- Symbol="Save"
- FontSize="15"
- Height="20" />
- </Button>
- <Button
- Grid.Column="4"
- MinWidth="0"
- Margin="5,0,0,0"
- VerticalAlignment="Center"
- ToolTip.Tip="{locale:Locale ControllerSettingsRemoveProfileToolTip}"
- Command="{ReflectionBinding RemoveProfile}">
- <ui:SymbolIcon
- Symbol="Delete"
- FontSize="15"
- Height="20" />
- </Button>
- </Grid>
- </Grid>
- <Separator />
- <Grid>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="*" />
- <ColumnDefinition Width="10" />
- <ColumnDefinition Width="*" />
- </Grid.ColumnDefinitions>
- <!-- Input Device -->
- <Grid
- Grid.Column="0"
- Margin="2"
- HorizontalAlignment="Stretch">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto"/>
- <ColumnDefinition Width="*"/>
- <ColumnDefinition Width="Auto" />
- </Grid.ColumnDefinitions>
- <TextBlock
- Grid.Column="0"
- Margin="5,0,10,0"
- Width="90"
- HorizontalAlignment="Left"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsInputDevice}" />
- <ComboBox
- Grid.Column="1"
- Name="DeviceBox"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Center"
- ItemsSource="{Binding DeviceList}"
- SelectedIndex="{Binding Device}" />
- <Button
- Grid.Column="2"
- MinWidth="0"
- Margin="5,0,0,0"
- VerticalAlignment="Center"
- Command="{ReflectionBinding LoadDevices}">
- <ui:SymbolIcon
- Symbol="Refresh"
- FontSize="15"
- Height="20"/>
- </Button>
- </Grid>
- <!-- Controller Type -->
- <Grid
- Grid.Column="2"
- Margin="2"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Center">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto"/>
- <ColumnDefinition Width="*" />
- </Grid.ColumnDefinitions>
- <TextBlock
- Margin="5,0,10,0"
- Width="90"
- HorizontalAlignment="Left"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsControllerType}" />
- <ComboBox
- Grid.Column="1"
- HorizontalAlignment="Stretch"
- ItemsSource="{Binding Controllers}"
- SelectedIndex="{Binding Controller}">
- <ComboBox.ItemTemplate>
- <DataTemplate DataType="models:ControllerModel">
- <TextBlock Text="{Binding Name}" />
- </DataTemplate>
- </ComboBox.ItemTemplate>
- </ComboBox>
- </Grid>
- </Grid>
- </StackPanel>
- <!-- Button / JoyStick Settings -->
- <Grid
- Name="SettingButtons"
- MinHeight="450"
- FlowDirection="LeftToRight"
- IsVisible="{Binding ShowSettings}">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="*" />
- <ColumnDefinition Width="Auto" />
- </Grid.ColumnDefinitions>
- <!-- Left Controls -->
- <StackPanel
- Orientation="Vertical"
- Margin="0,0,5,0"
- Grid.Column="0">
- <!-- Left Triggers -->
- <Border
- BorderBrush="{DynamicResource ThemeControlBorderColor}"
- BorderThickness="1"
- IsVisible="{Binding IsLeft}"
- MinHeight="90"
- CornerRadius="5">
- <Grid
- Margin="10"
- HorizontalAlignment="Stretch">
- <Grid.ColumnDefinitions>
- <ColumnDefinition />
- <ColumnDefinition />
- </Grid.ColumnDefinitions>
- <Grid.RowDefinitions>
- <RowDefinition />
- <RowDefinition />
- </Grid.RowDefinitions>
- <StackPanel
- Grid.Column="0"
- Grid.Row="0"
- Orientation="Horizontal">
- <TextBlock
- Width="20"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsTriggerZL}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.ButtonZl, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <StackPanel
- Grid.Column="0"
- Grid.Row="1"
- Orientation="Horizontal">
- <TextBlock
- Width="20"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsTriggerL}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.ButtonL, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <StackPanel
- Grid.Column="1"
- Grid.Row="1"
- Orientation="Horizontal">
- <TextBlock
- Width="20"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsButtonMinus}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.ButtonMinus, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- </Grid>
- </Border>
- <!-- Left Joystick -->
- <Border
- BorderBrush="{DynamicResource ThemeControlBorderColor}"
- BorderThickness="1"
- IsVisible="{Binding IsLeft}"
- Margin="0,5,0,0"
- CornerRadius="5">
- <StackPanel
- Margin="10"
- Orientation="Vertical">
- <TextBlock
- Margin="0,0,0,10"
- HorizontalAlignment="Center"
- Text="{locale:Locale ControllerSettingsLStick}" />
- <!-- Left Joystick Keyboard -->
- <StackPanel
- IsVisible="{Binding !IsController}"
- Orientation="Vertical">
- <!-- Left Joystick Button -->
- <StackPanel
- Margin="0,0,0,4"
- Orientation="Horizontal">
- <TextBlock
- Margin="0,0,10,0"
- Width="120"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsStickButton}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.LeftKeyboardStickButton, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <!-- Left Joystick Up -->
- <StackPanel
- Margin="0,0,0,4"
- Orientation="Horizontal">
- <TextBlock
- Margin="0,0,10,0"
- Width="120"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsStickUp}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.LeftStickUp, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <!-- Left Joystick Down -->
- <StackPanel
- Margin="0,0,0,4"
- Orientation="Horizontal">
- <TextBlock
- Margin="0,0,10,0"
- Width="120"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsStickDown}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.LeftStickDown, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <!-- Left Joystick Left -->
- <StackPanel
- Margin="0,0,0,4"
- Orientation="Horizontal">
- <TextBlock
- Margin="0,0,10,0"
- Width="120"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsStickLeft}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.LeftStickLeft, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <!-- Left Joystick Right -->
- <StackPanel
- Margin="0,0,0,4"
- Orientation="Horizontal">
- <TextBlock
- Margin="0,0,10,0"
- Width="120"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsStickRight}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.LeftStickRight, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- </StackPanel>
- <!-- Left Joystick Controller -->
- <StackPanel
- IsVisible="{Binding IsController}"
- Orientation="Vertical">
- <!-- Left Joystick Button -->
- <StackPanel
- Orientation="Horizontal">
- <TextBlock
- Margin="0,0,10,0"
- Width="120"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsStickButton}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.LeftControllerStickButton, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <!-- Left Joystick Stick -->
- <StackPanel
- Margin="0,4,0,4"
- Orientation="Horizontal">
- <TextBlock
- Margin="0,0,10,0"
- Width="120"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsStickStick}"
- TextAlignment="Center" />
- <ToggleButton Tag="stick">
- <TextBlock
- Text="{ReflectionBinding Configuration.LeftJoystick, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <Separator
- Margin="0,8,0,8"
- Height="1" />
- <CheckBox IsChecked="{ReflectionBinding Configuration.LeftInvertStickX}">
- <TextBlock Text="{locale:Locale ControllerSettingsStickInvertXAxis}" />
- </CheckBox>
- <CheckBox IsChecked="{ReflectionBinding Configuration.LeftInvertStickY}">
- <TextBlock Text="{locale:Locale ControllerSettingsStickInvertYAxis}" />
- </CheckBox>
- <CheckBox IsChecked="{ReflectionBinding Configuration.LeftRotate90}">
- <TextBlock Text="{locale:Locale ControllerSettingsRotate90}" />
- </CheckBox>
- <Separator
- Margin="0,8,0,8"
- Height="1" />
- <StackPanel Orientation="Vertical">
- <TextBlock
- HorizontalAlignment="Center"
- Text="{locale:Locale ControllerSettingsStickDeadzone}" />
- <StackPanel
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Orientation="Horizontal">
- <controls:SliderScroll
- Width="130"
- Maximum="1"
- TickFrequency="0.01"
- IsSnapToTickEnabled="True"
- SmallChange="0.01"
- Minimum="0"
- Value="{ReflectionBinding Configuration.DeadzoneLeft, Mode=TwoWay}" />
- <TextBlock
- VerticalAlignment="Center"
- Width="25"
- Text="{ReflectionBinding Configuration.DeadzoneLeft, StringFormat=\{0:0.00\}}" />
- </StackPanel>
- <TextBlock
- HorizontalAlignment="Center"
- Text="{locale:Locale ControllerSettingsStickRange}" />
- <StackPanel
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Orientation="Horizontal">
- <controls:SliderScroll
- Width="130"
- Maximum="2"
- TickFrequency="0.01"
- IsSnapToTickEnabled="True"
- SmallChange="0.01"
- Minimum="0"
- Value="{ReflectionBinding Configuration.RangeLeft, Mode=TwoWay}" />
- <TextBlock
- VerticalAlignment="Center"
- Width="25"
- Text="{ReflectionBinding Configuration.RangeLeft, StringFormat=\{0:0.00\}}" />
- </StackPanel>
- </StackPanel>
- </StackPanel>
- </StackPanel>
- </Border>
- <!-- Left DPad -->
- <Border
- BorderBrush="{DynamicResource ThemeControlBorderColor}"
- BorderThickness="1"
- VerticalAlignment="Top"
- IsVisible="{Binding IsLeft}"
- Margin="0,5,0,0"
- CornerRadius="5">
- <StackPanel
- Margin="10"
- Orientation="Vertical">
- <TextBlock
- Margin="0,0,0,10"
- HorizontalAlignment="Center"
- Text="{locale:Locale ControllerSettingsDPad}" />
- <StackPanel Orientation="Vertical">
- <!-- Left DPad Up -->
- <StackPanel
- Margin="0,0,0,4"
- Orientation="Horizontal">
- <TextBlock
- Margin="0,0,10,0"
- Width="120"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsDPadUp}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.DpadUp, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <!-- Left DPad Down -->
- <StackPanel
- Margin="0,0,0,4"
- Orientation="Horizontal">
- <TextBlock
- Margin="0,0,10,0"
- Width="120"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsDPadDown}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.DpadDown, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <!-- Left DPad Left -->
- <StackPanel
- Margin="0,0,0,4"
- Orientation="Horizontal">
- <TextBlock
- Margin="0,0,10,0"
- Width="120"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsDPadLeft}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.DpadLeft, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <!-- Left DPad Right -->
- <StackPanel
- Margin="0,0,0,4"
- Orientation="Horizontal">
- <TextBlock
- Margin="0,0,10,0"
- Width="120"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsDPadRight}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.DpadRight, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- </StackPanel>
- </StackPanel>
- </Border>
- </StackPanel>
- <!-- Triggers & Side Buttons -->
- <StackPanel
- Grid.Column="1"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch">
- <Border
- BorderBrush="{DynamicResource ThemeControlBorderColor}"
- BorderThickness="1"
- CornerRadius="5"
- MinHeight="90">
- <StackPanel
- Margin="8"
- Orientation="Vertical">
- <TextBlock
- HorizontalAlignment="Center"
- Text="{locale:Locale ControllerSettingsTriggerThreshold}" />
- <StackPanel
- HorizontalAlignment="Center"
- Orientation="Horizontal">
- <controls:SliderScroll
- Width="130"
- Maximum="1"
- TickFrequency="0.01"
- IsSnapToTickEnabled="True"
- SmallChange="0.01"
- Minimum="0"
- Value="{ReflectionBinding Configuration.TriggerThreshold, Mode=TwoWay}" />
- <TextBlock
- Width="25"
- Text="{ReflectionBinding Configuration.TriggerThreshold, StringFormat=\{0:0.00\}}" />
- </StackPanel>
- <StackPanel
- Margin="0,4,0,0"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- IsVisible="{Binding !IsRight}"
- Orientation="Horizontal">
- <TextBlock
- Width="20"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsLeftSR}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.LeftButtonSr, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <StackPanel
- Margin="0,4,0,0"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- IsVisible="{Binding !IsRight}"
- Orientation="Horizontal">
- <TextBlock
- Width="20"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsLeftSL}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.LeftButtonSl, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <StackPanel
- Margin="0,4,0,0"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- IsVisible="{Binding !IsLeft}"
- Orientation="Horizontal">
- <TextBlock
- Width="20"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsRightSR}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.RightButtonSr, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <StackPanel
- Margin="0,4,0,0"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- IsVisible="{Binding !IsLeft}"
- Orientation="Horizontal">
- <TextBlock
- Width="20"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsRightSL}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.RightButtonSl, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- </StackPanel>
- </Border>
- <!-- Controller Picture -->
- <Image
- Margin="0,10,0,0"
- MaxHeight="300"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- Source="{Binding Image}" />
- <!-- Motion + Rumble -->
- <StackPanel
- Margin="0,10,0,0"
- Spacing="5"
- Orientation="Vertical"
- VerticalAlignment="Bottom">
- <Border
- BorderBrush="{DynamicResource ThemeControlBorderColor}"
- BorderThickness="1"
- CornerRadius="5"
- VerticalAlignment="Bottom"
- HorizontalAlignment="Stretch"
- IsVisible="{Binding IsController}">
- <Grid>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="*" />
- <ColumnDefinition Width="Auto" />
- </Grid.ColumnDefinitions>
- <CheckBox
- Margin="10"
- MinWidth="0"
- Grid.Column="0"
- IsChecked="{ReflectionBinding Configuration.EnableMotion, Mode=TwoWay}">
- <TextBlock Text="{locale:Locale ControllerSettingsMotion}" />
- </CheckBox>
- <Button
- Margin="10"
- Grid.Column="1"
- Command="{Binding ShowMotionConfig}">
- <TextBlock Text="{locale:Locale ControllerSettingsConfigureGeneral}" />
- </Button>
- </Grid>
- </Border>
- <Border
- BorderBrush="{DynamicResource ThemeControlBorderColor}"
- BorderThickness="1"
- CornerRadius="5"
- HorizontalAlignment="Stretch"
- IsVisible="{Binding IsController}"
- Margin="0,-1,0,0">
- <Grid>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="*" />
- <ColumnDefinition Width="Auto" />
- </Grid.ColumnDefinitions>
- <CheckBox
- Margin="10"
- MinWidth="0"
- Grid.Column="0"
- IsChecked="{ReflectionBinding Configuration.EnableRumble, Mode=TwoWay}">
- <TextBlock Text="{locale:Locale ControllerSettingsRumble}" />
- </CheckBox>
- <Button
- Margin="10"
- Grid.Column="1"
- Command="{Binding ShowRumbleConfig}">
- <TextBlock Text="{locale:Locale ControllerSettingsConfigureGeneral}" />
- </Button>
- </Grid>
- </Border>
- </StackPanel>
- </StackPanel>
- <!-- Right Controls -->
- <StackPanel
- Orientation="Vertical"
- Margin="5,0,0,0"
- Grid.Column="2">
- <!-- Right Triggers -->
- <Border
- BorderBrush="{DynamicResource ThemeControlBorderColor}"
- BorderThickness="1"
- IsVisible="{Binding IsRight}"
- MinHeight="90"
- CornerRadius="5">
- <Grid
- Margin="10"
- HorizontalAlignment="Stretch">
- <Grid.ColumnDefinitions>
- <ColumnDefinition />
- <ColumnDefinition />
- </Grid.ColumnDefinitions>
- <Grid.RowDefinitions>
- <RowDefinition />
- <RowDefinition />
- </Grid.RowDefinitions>
- <StackPanel
- Grid.Column="1"
- Grid.Row="0"
- Orientation="Horizontal">
- <TextBlock
- Width="20"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsTriggerZR}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.ButtonZr, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <StackPanel
- Grid.Column="1"
- Grid.Row="1"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Orientation="Horizontal">
- <TextBlock
- Width="20"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsTriggerR}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.ButtonR, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <StackPanel
- Grid.Column="0"
- Grid.Row="1"
- HorizontalAlignment="Right"
- VerticalAlignment="Center"
- Orientation="Horizontal">
- <TextBlock
- Width="20"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsButtonPlus}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.ButtonPlus, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- </Grid>
- </Border>
- <!-- Right Joystick -->
- <Border
- BorderBrush="{DynamicResource ThemeControlBorderColor}"
- BorderThickness="1"
- IsVisible="{Binding IsRight}"
- Margin="0,5,0,0"
- CornerRadius="5">
- <StackPanel
- Margin="10"
- Orientation="Vertical">
- <TextBlock
- Margin="0,0,0,10"
- HorizontalAlignment="Center"
- Text="{locale:Locale ControllerSettingsButtons}" />
- <StackPanel
- Orientation="Vertical">
- <!-- Right Buttons A -->
- <StackPanel
- Margin="0,0,0,4"
- Orientation="Horizontal">
- <TextBlock
- Width="120"
- Margin="0,0,10,0"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsButtonA}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.ButtonA, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <!-- Right Buttons B -->
- <StackPanel
- Margin="0,0,0,4"
- Orientation="Horizontal">
- <TextBlock
- Width="120"
- Margin="0,0,10,0"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsButtonB}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.ButtonB, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <!-- Right Buttons X -->
- <StackPanel
- Margin="0,0,0,4"
- Orientation="Horizontal">
- <TextBlock
- Width="120"
- Margin="0,0,10,0"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsButtonX}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.ButtonX, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <!-- Right Buttons Y -->
- <StackPanel
- Margin="0,0,0,4"
- Orientation="Horizontal">
- <TextBlock
- Width="120"
- Margin="0,0,10,0"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsButtonY}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.ButtonY, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- </StackPanel>
- </StackPanel>
- </Border>
- <!-- Right DPad -->
- <Border
- Padding="10"
- BorderBrush="{DynamicResource ThemeControlBorderColor}"
- BorderThickness="1"
- CornerRadius="5"
- IsVisible="{Binding IsRight}"
- Margin="0,5,0,0">
- <StackPanel Orientation="Vertical">
- <TextBlock
- Margin="0,0,0,10"
- HorizontalAlignment="Center"
- Text="{locale:Locale ControllerSettingsRStick}" />
- <!-- Right Joystick Keyboard -->
- <StackPanel
- IsVisible="{Binding !IsController}"
- Orientation="Vertical">
- <!-- Right Joystick Button -->
- <StackPanel
- Margin="0,0,0,4"
- Orientation="Horizontal">
- <TextBlock
- Margin="0,0,10,0"
- Width="120"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsStickButton}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.RightKeyboardStickButton, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <!-- Right Joystick Up -->
- <StackPanel
- Margin="0,0,0,4"
- Orientation="Horizontal">
- <TextBlock
- Margin="0,0,10,0"
- Width="120"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsStickUp}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.RightStickUp, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <!-- Right Joystick Down -->
- <StackPanel
- Margin="0,0,0,4"
- Orientation="Horizontal">
- <TextBlock
- Margin="0,0,10,0"
- Width="120"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsStickDown}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.RightStickDown, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <!-- Right Joystick Left -->
- <StackPanel
- Margin="0,0,0,4"
- Orientation="Horizontal">
- <TextBlock
- Margin="0,0,10,0"
- Width="120"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsStickLeft}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.RightStickLeft, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <!-- Right Joystick Right -->
- <StackPanel
- Margin="0,0,0,4"
- Orientation="Horizontal">
- <TextBlock
- Margin="0,0,10,0"
- Width="120"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsStickRight}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.RightStickRight, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- </StackPanel>
- <!-- Right Joystick Controller -->
- <StackPanel
- IsVisible="{Binding IsController}"
- Orientation="Vertical">
- <!-- Right Joystick Button -->
- <StackPanel
- Orientation="Horizontal">
- <TextBlock
- Margin="0,0,10,0"
- Width="120"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsStickButton}"
- TextAlignment="Center" />
- <ToggleButton>
- <TextBlock
- Text="{ReflectionBinding Configuration.RightControllerStickButton, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <!-- Right Joystick Stick -->
- <StackPanel
- Margin="0,4,0,4"
- Background="{DynamicResource ThemeDarkColor}"
- Orientation="Horizontal">
- <TextBlock
- Margin="0,0,10,0"
- Width="120"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsStickStick}"
- TextAlignment="Center" />
- <ToggleButton Tag="stick">
- <TextBlock
- Text="{ReflectionBinding Configuration.RightJoystick, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <Separator Margin="0,8,0,8" Height="1" />
- <CheckBox IsChecked="{ReflectionBinding Configuration.RightInvertStickX}">
- <TextBlock Text="{locale:Locale ControllerSettingsStickInvertXAxis}" />
- </CheckBox>
- <CheckBox IsChecked="{ReflectionBinding Configuration.RightInvertStickY}">
- <TextBlock Text="{locale:Locale ControllerSettingsStickInvertYAxis}" />
- </CheckBox>
- <CheckBox IsChecked="{ReflectionBinding Configuration.RightRotate90}">
- <TextBlock Text="{locale:Locale ControllerSettingsRotate90}" />
- </CheckBox>
- <Separator Margin="0,8,0,8" Height="1" />
- <StackPanel Orientation="Vertical">
- <TextBlock
- HorizontalAlignment="Center"
- Text="{locale:Locale ControllerSettingsStickDeadzone}" />
- <StackPanel
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Orientation="Horizontal">
- <controls:SliderScroll
- Width="130"
- Maximum="1"
- TickFrequency="0.01"
- IsSnapToTickEnabled="True"
- SmallChange="0.01"
- Padding="0"
- VerticalAlignment="Center"
- Minimum="0"
- Value="{ReflectionBinding Configuration.DeadzoneRight, Mode=TwoWay}" />
- <TextBlock
- VerticalAlignment="Center"
- Width="25"
- Text="{ReflectionBinding Configuration.DeadzoneRight, StringFormat=\{0:0.00\}}" />
- </StackPanel>
- <TextBlock
- HorizontalAlignment="Center"
- Text="{locale:Locale ControllerSettingsStickRange}" />
- <StackPanel
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Orientation="Horizontal">
- <controls:SliderScroll
- Width="130"
- Maximum="2"
- TickFrequency="0.01"
- IsSnapToTickEnabled="True"
- SmallChange="0.01"
- Minimum="0"
- Value="{ReflectionBinding Configuration.RangeRight, Mode=TwoWay}" />
- <TextBlock
- VerticalAlignment="Center"
- Width="25"
- Text="{ReflectionBinding Configuration.RangeRight, StringFormat=\{0:0.00\}}" />
- </StackPanel>
- </StackPanel>
- </StackPanel>
- </StackPanel>
- </Border>
- </StackPanel>
- </Grid>
- </StackPanel>
-</UserControl>
diff --git a/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml.cs
deleted file mode 100644
index 35129706..00000000
--- a/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml.cs
+++ /dev/null
@@ -1,181 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Controls.Primitives;
-using Avalonia.Input;
-using Avalonia.Interactivity;
-using Avalonia.LogicalTree;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.Models;
-using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.Common.Configuration.Hid.Controller;
-using Ryujinx.Input;
-using Ryujinx.Input.Assigner;
-using System;
-
-namespace Ryujinx.Ava.UI.Views.Input
-{
- public partial class ControllerInputView : UserControl
- {
- private bool _dialogOpen;
-
- private ButtonKeyAssigner _currentAssigner;
- internal ControllerInputViewModel ViewModel { get; set; }
-
- public ControllerInputView()
- {
- DataContext = ViewModel = new ControllerInputViewModel(this);
-
- InitializeComponent();
-
- foreach (ILogical visual in SettingButtons.GetLogicalDescendants())
- {
- if (visual is ToggleButton button && visual is not CheckBox)
- {
- button.IsCheckedChanged += Button_IsCheckedChanged;
- }
- }
- }
-
- protected override void OnPointerReleased(PointerReleasedEventArgs e)
- {
- base.OnPointerReleased(e);
-
- if (_currentAssigner != null && _currentAssigner.ToggledButton != null && !_currentAssigner.ToggledButton.IsPointerOver)
- {
- _currentAssigner.Cancel();
- }
- }
-
- private void Button_IsCheckedChanged(object sender, RoutedEventArgs e)
- {
- if (sender is ToggleButton button)
- {
- if ((bool)button.IsChecked)
- {
- if (_currentAssigner != null && button == _currentAssigner.ToggledButton)
- {
- return;
- }
-
- bool isStick = button.Tag != null && button.Tag.ToString() == "stick";
-
- if (_currentAssigner == null)
- {
- _currentAssigner = new ButtonKeyAssigner(button);
-
- this.Focus(NavigationMethod.Pointer);
-
- PointerPressed += MouseClick;
-
- IKeyboard keyboard = (IKeyboard)ViewModel.AvaloniaKeyboardDriver.GetGamepad("0"); // Open Avalonia keyboard for cancel operations.
- IButtonAssigner assigner = CreateButtonAssigner(isStick);
-
- _currentAssigner.ButtonAssigned += (sender, e) =>
- {
- if (e.IsAssigned)
- {
- ViewModel.IsModified = true;
- }
- };
-
- _currentAssigner.GetInputAndAssign(assigner, keyboard);
- }
- else
- {
- if (_currentAssigner != null)
- {
- ToggleButton oldButton = _currentAssigner.ToggledButton;
-
- _currentAssigner.Cancel();
- _currentAssigner = null;
- button.IsChecked = false;
- }
- }
- }
- else
- {
- _currentAssigner?.Cancel();
- _currentAssigner = null;
- }
- }
- }
-
- public void SaveCurrentProfile()
- {
- ViewModel.Save();
- }
-
- private IButtonAssigner CreateButtonAssigner(bool forStick)
- {
- IButtonAssigner assigner;
-
- var device = ViewModel.Devices[ViewModel.Device];
-
- if (device.Type == DeviceType.Keyboard)
- {
- assigner = new KeyboardKeyAssigner((IKeyboard)ViewModel.SelectedGamepad);
- }
- else if (device.Type == DeviceType.Controller)
- {
- assigner = new GamepadButtonAssigner(ViewModel.SelectedGamepad, (ViewModel.Config as StandardControllerInputConfig).TriggerThreshold, forStick);
- }
- else
- {
- throw new Exception("Controller not supported");
- }
-
- return assigner;
- }
-
- private void MouseClick(object sender, PointerPressedEventArgs e)
- {
- bool shouldUnbind = false;
-
- if (e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed)
- {
- shouldUnbind = true;
- }
-
- _currentAssigner?.Cancel(shouldUnbind);
-
- PointerPressed -= MouseClick;
- }
-
- private async void PlayerIndexBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
- {
- if (ViewModel.IsModified && !_dialogOpen)
- {
- _dialogOpen = true;
-
- var result = await ContentDialogHelper.CreateConfirmationDialog(
- LocaleManager.Instance[LocaleKeys.DialogControllerSettingsModifiedConfirmMessage],
- LocaleManager.Instance[LocaleKeys.DialogControllerSettingsModifiedConfirmSubMessage],
- LocaleManager.Instance[LocaleKeys.InputDialogYes],
- LocaleManager.Instance[LocaleKeys.InputDialogNo],
- LocaleManager.Instance[LocaleKeys.RyujinxConfirm]);
-
- if (result == UserResult.Yes)
- {
- ViewModel.Save();
- }
-
- _dialogOpen = false;
-
- ViewModel.IsModified = false;
-
- if (e.AddedItems.Count > 0)
- {
- var player = (PlayerModel)e.AddedItems[0];
- ViewModel.PlayerId = player.Id;
- }
- }
- }
-
- public void Dispose()
- {
- _currentAssigner?.Cancel();
- _currentAssigner = null;
- ViewModel.Dispose();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml b/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml
deleted file mode 100644
index a6b587f6..00000000
--- a/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml
+++ /dev/null
@@ -1,171 +0,0 @@
-<UserControl
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
- xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- mc:Ignorable="d"
- x:Class="Ryujinx.Ava.UI.Views.Input.MotionInputView"
- x:DataType="viewModels:MotionInputViewModel"
- Focusable="True">
- <Grid Margin="10">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition />
- </Grid.RowDefinitions>
- <StackPanel Orientation="Vertical">
- <StackPanel
- Orientation="Horizontal"
- HorizontalAlignment="Center">
- <TextBlock
- Margin="0"
- HorizontalAlignment="Center"
- Text="{locale:Locale ControllerSettingsMotionGyroSensitivity}" />
- <controls:SliderScroll
- Margin="0,-5,0,-5"
- Width="150"
- MaxWidth="150"
- TickFrequency="1"
- IsSnapToTickEnabled="True"
- SmallChange="0.01"
- Maximum="100"
- Minimum="0"
- Value="{Binding Sensitivity, Mode=TwoWay}" />
- <TextBlock
- HorizontalAlignment="Center"
- Margin="5, 0"
- Text="{Binding Sensitivity, StringFormat=\{0:0\}%}" />
- </StackPanel>
- <StackPanel
- Orientation="Horizontal"
- HorizontalAlignment="Center">
- <TextBlock
- Margin="0"
- HorizontalAlignment="Center"
- Text="{locale:Locale ControllerSettingsMotionGyroDeadzone}" />
- <controls:SliderScroll
- Margin="0,-5,0,-5"
- Width="150"
- MaxWidth="150"
- TickFrequency="1"
- IsSnapToTickEnabled="True"
- SmallChange="0.01"
- Maximum="100"
- Minimum="0"
- Value="{Binding GyroDeadzone, Mode=TwoWay}" />
- <TextBlock
- VerticalAlignment="Center"
- Margin="5, 0"
- Text="{Binding GyroDeadzone, StringFormat=\{0:0.00\}}" />
- </StackPanel>
- <Separator
- Height="1"
- Margin="0,5" />
- <CheckBox
- Margin="5"
- IsChecked="{Binding EnableCemuHookMotion}">
- <TextBlock
- Margin="0,3,0,0"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsMotionUseCemuhookCompatibleMotion}" />
- </CheckBox>
- </StackPanel>
- <Border
- Grid.Row="1"
- Padding="20,5"
- BorderBrush="{DynamicResource ThemeControlBorderColor}"
- BorderThickness="1"
- CornerRadius="5"
- HorizontalAlignment="Stretch">
- <Grid VerticalAlignment="Top">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="*" />
- </Grid.RowDefinitions>
- <StackPanel
- Grid.Row="1"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Orientation="Vertical">
- <StackPanel
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Orientation="Horizontal">
- <TextBlock
- Margin="5"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsMotionServerHost}" />
- <TextBox
- Height="30"
- MinWidth="100"
- MaxWidth="100"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{Binding DsuServerHost, Mode=TwoWay}" />
- <TextBlock
- Margin="5"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text=":" />
- <TextBox
- Height="30"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{Binding DsuServerPort, Mode=TwoWay}" />
- </StackPanel>
- <StackPanel Orientation="Vertical">
- <Grid>
- <Grid.RowDefinitions>
- <RowDefinition />
- <RowDefinition />
- </Grid.RowDefinitions>
- <Grid.ColumnDefinitions>
- <ColumnDefinition />
- <ColumnDefinition />
- </Grid.ColumnDefinitions>
- <TextBlock
- Margin="0,10,0,0"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsMotionControllerSlot}" />
- <ui:NumberBox
- Grid.Row="0"
- Grid.Column="1"
- Name="CemuHookSlotUpDown"
- SmallChange="1"
- LargeChange="1"
- Maximum="4"
- Minimum="0"
- Value="{Binding Slot}" />
- <TextBlock
- Margin="0,10,0,0"
- Grid.Row="1"
- Grid.Column="0"
- VerticalAlignment="Center"
- Text="{locale:Locale ControllerSettingsMotionRightJoyConSlot}" />
- <ui:NumberBox
- Grid.Row="1"
- Grid.Column="1"
- Name="CemuHookRightJoyConSlotUpDown"
- SmallChange="1"
- LargeChange="1"
- Maximum="4"
- Minimum="0"
- Value="{Binding AltSlot}" />
- </Grid>
- </StackPanel>
- <CheckBox
- HorizontalAlignment="Center"
- IsChecked="{Binding MirrorInput, Mode=TwoWay}">
- <TextBlock
- HorizontalAlignment="Center"
- Text="{locale:Locale ControllerSettingsMotionMirrorInput}" />
- </CheckBox>
- </StackPanel>
- </Grid>
- </Border>
- </Grid>
-</UserControl>
diff --git a/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml.cs
deleted file mode 100644
index 1b340752..00000000
--- a/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-using Avalonia.Controls;
-using FluentAvalonia.UI.Controls;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Models;
-using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.Common.Configuration.Hid.Controller;
-using System.Threading.Tasks;
-
-namespace Ryujinx.Ava.UI.Views.Input
-{
- public partial class MotionInputView : UserControl
- {
- private readonly MotionInputViewModel _viewModel;
-
- public MotionInputView()
- {
- InitializeComponent();
- }
-
- public MotionInputView(ControllerInputViewModel viewModel)
- {
- var config = viewModel.Configuration as InputConfiguration<GamepadInputId, StickInputId>;
-
- _viewModel = new MotionInputViewModel
- {
- Slot = config.Slot,
- AltSlot = config.AltSlot,
- DsuServerHost = config.DsuServerHost,
- DsuServerPort = config.DsuServerPort,
- MirrorInput = config.MirrorInput,
- Sensitivity = config.Sensitivity,
- GyroDeadzone = config.GyroDeadzone,
- EnableCemuHookMotion = config.EnableCemuHookMotion,
- };
-
- InitializeComponent();
- DataContext = _viewModel;
- }
-
- public static async Task Show(ControllerInputViewModel viewModel)
- {
- MotionInputView content = new(viewModel);
-
- ContentDialog contentDialog = new()
- {
- Title = LocaleManager.Instance[LocaleKeys.ControllerMotionTitle],
- PrimaryButtonText = LocaleManager.Instance[LocaleKeys.ControllerSettingsSave],
- SecondaryButtonText = "",
- CloseButtonText = LocaleManager.Instance[LocaleKeys.ControllerSettingsClose],
- Content = content,
- };
- contentDialog.PrimaryButtonClick += (sender, args) =>
- {
- var config = viewModel.Configuration as InputConfiguration<GamepadInputId, StickInputId>;
- config.Slot = content._viewModel.Slot;
- config.Sensitivity = content._viewModel.Sensitivity;
- config.GyroDeadzone = content._viewModel.GyroDeadzone;
- config.AltSlot = content._viewModel.AltSlot;
- config.DsuServerHost = content._viewModel.DsuServerHost;
- config.DsuServerPort = content._viewModel.DsuServerPort;
- config.EnableCemuHookMotion = content._viewModel.EnableCemuHookMotion;
- config.MirrorInput = content._viewModel.MirrorInput;
- };
-
- await contentDialog.ShowAsync();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml b/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml
deleted file mode 100644
index 5b7087a4..00000000
--- a/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml
+++ /dev/null
@@ -1,62 +0,0 @@
-<UserControl
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- mc:Ignorable="d"
- x:Class="Ryujinx.Ava.UI.Views.Input.RumbleInputView"
- x:DataType="viewModels:RumbleInputViewModel"
- Focusable="True">
- <Grid Margin="10">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition />
- </Grid.RowDefinitions>
- <StackPanel Orientation="Vertical">
- <StackPanel Orientation="Horizontal">
- <TextBlock
- Width="100"
- TextWrapping="WrapWithOverflow"
- HorizontalAlignment="Center"
- Text="{locale:Locale ControllerSettingsRumbleStrongMultiplier}" />
- <controls:SliderScroll
- Margin="0,-5,0,-5"
- Width="200"
- TickFrequency="0.01"
- IsSnapToTickEnabled="True"
- SmallChange="0.01"
- Maximum="10"
- Minimum="0"
- Value="{Binding StrongRumble, Mode=TwoWay}" />
- <TextBlock
- VerticalAlignment="Center"
- Margin="5,0"
- Text="{Binding StrongRumble, StringFormat=\{0:0.00\}}" />
- </StackPanel>
- <StackPanel Orientation="Horizontal">
- <TextBlock
- Width="100"
- TextWrapping="WrapWithOverflow"
- HorizontalAlignment="Center"
- Text="{locale:Locale ControllerSettingsRumbleWeakMultiplier}" />
- <controls:SliderScroll
- Margin="0,-5,0,-5"
- Width="200"
- MaxWidth="200"
- Maximum="10"
- TickFrequency="0.01"
- IsSnapToTickEnabled="True"
- SmallChange="0.01"
- Minimum="0"
- Value="{Binding WeakRumble, Mode=TwoWay}" />
- <TextBlock
- VerticalAlignment="Center"
- Margin="5,0"
- Text="{Binding WeakRumble, StringFormat=\{0:0.00\}}" />
- </StackPanel>
- </StackPanel>
- </Grid>
-</UserControl>
diff --git a/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml.cs
deleted file mode 100644
index 9307f872..00000000
--- a/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-using Avalonia.Controls;
-using FluentAvalonia.UI.Controls;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Models;
-using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.Common.Configuration.Hid.Controller;
-using System.Threading.Tasks;
-
-namespace Ryujinx.Ava.UI.Views.Input
-{
- public partial class RumbleInputView : UserControl
- {
- private readonly RumbleInputViewModel _viewModel;
-
- public RumbleInputView()
- {
- InitializeComponent();
- }
-
- public RumbleInputView(ControllerInputViewModel viewModel)
- {
- var config = viewModel.Configuration as InputConfiguration<GamepadInputId, StickInputId>;
-
- _viewModel = new RumbleInputViewModel
- {
- StrongRumble = config.StrongRumble,
- WeakRumble = config.WeakRumble,
- };
-
- InitializeComponent();
-
- DataContext = _viewModel;
- }
-
- public static async Task Show(ControllerInputViewModel viewModel)
- {
- RumbleInputView content = new(viewModel);
-
- ContentDialog contentDialog = new()
- {
- Title = LocaleManager.Instance[LocaleKeys.ControllerRumbleTitle],
- PrimaryButtonText = LocaleManager.Instance[LocaleKeys.ControllerSettingsSave],
- SecondaryButtonText = "",
- CloseButtonText = LocaleManager.Instance[LocaleKeys.ControllerSettingsClose],
- Content = content,
- };
-
- contentDialog.PrimaryButtonClick += (sender, args) =>
- {
- var config = viewModel.Configuration as InputConfiguration<GamepadInputId, StickInputId>;
- config.StrongRumble = content._viewModel.StrongRumble;
- config.WeakRumble = content._viewModel.WeakRumble;
- };
-
- await contentDialog.ShowAsync();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml b/src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml
deleted file mode 100644
index 30358ada..00000000
--- a/src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml
+++ /dev/null
@@ -1,203 +0,0 @@
-<UserControl
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- mc:Ignorable="d"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- x:DataType="viewModels:MainWindowViewModel"
- x:Class="Ryujinx.Ava.UI.Views.Main.MainMenuBarView">
- <Design.DataContext>
- <viewModels:MainWindowViewModel />
- </Design.DataContext>
- <DockPanel HorizontalAlignment="Stretch">
- <Menu
- Name="Menu"
- Height="35"
- Margin="0"
- HorizontalAlignment="Left">
- <Menu.ItemsPanel>
- <ItemsPanelTemplate>
- <DockPanel Margin="0" HorizontalAlignment="Stretch" />
- </ItemsPanelTemplate>
- </Menu.ItemsPanel>
- <MenuItem VerticalAlignment="Center" Header="{locale:Locale MenuBarFile}">
- <MenuItem
- Command="{Binding OpenFile}"
- Header="{locale:Locale MenuBarFileOpenFromFile}"
- IsEnabled="{Binding EnableNonGameRunningControls}"
- ToolTip.Tip="{locale:Locale LoadApplicationFileTooltip}" />
- <MenuItem
- Command="{Binding OpenFolder}"
- Header="{locale:Locale MenuBarFileOpenUnpacked}"
- IsEnabled="{Binding EnableNonGameRunningControls}"
- ToolTip.Tip="{locale:Locale LoadApplicationFolderTooltip}" />
- <MenuItem Header="{locale:Locale MenuBarFileOpenApplet}" IsEnabled="{Binding IsAppletMenuActive}">
- <MenuItem
- Click="OpenMiiApplet"
- Header="Mii Edit Applet"
- ToolTip.Tip="{locale:Locale MenuBarFileOpenAppletOpenMiiAppletToolTip}" />
- </MenuItem>
- <Separator />
- <MenuItem
- Command="{Binding OpenRyujinxFolder}"
- Header="{locale:Locale MenuBarFileOpenEmuFolder}"
- ToolTip.Tip="{locale:Locale OpenRyujinxFolderTooltip}" />
- <MenuItem
- Command="{Binding OpenLogsFolder}"
- Header="{locale:Locale MenuBarFileOpenLogsFolder}"
- ToolTip.Tip="{locale:Locale OpenRyujinxLogsTooltip}" />
- <Separator />
- <MenuItem
- Click="CloseWindow"
- Header="{locale:Locale MenuBarFileExit}"
- ToolTip.Tip="{locale:Locale ExitTooltip}" />
- </MenuItem>
- <MenuItem VerticalAlignment="Center" Header="{locale:Locale MenuBarOptions}">
- <MenuItem
- Padding="-10,0,0,0"
- Command="{Binding ToggleFullscreen}"
- Header="{locale:Locale MenuBarOptionsToggleFullscreen}"
- InputGesture="F11" />
- <MenuItem
- Padding="0"
- Command="{Binding ToggleStartGamesInFullscreen}"
- Header="{locale:Locale MenuBarOptionsStartGamesInFullscreen}">
- <MenuItem.Icon>
- <CheckBox
- MinWidth="{DynamicResource CheckBoxSize}"
- MinHeight="{DynamicResource CheckBoxSize}"
- IsChecked="{Binding StartGamesInFullscreen, Mode=TwoWay}"
- Padding="0" />
- </MenuItem.Icon>
- <MenuItem.Styles>
- <Style Selector="Viewbox#PART_IconPresenter">
- <Setter Property="MaxHeight" Value="36" />
- <Setter Property="MinHeight" Value="36" />
- <Setter Property="MaxWidth" Value="36" />
- <Setter Property="MinWidth" Value="36" />
- </Style>
- <Style Selector="ContentPresenter#PART_HeaderPresenter">
- <Setter Property="Padding" Value="-10,0,0,0" />
- </Style>
- </MenuItem.Styles>
- </MenuItem>
- <MenuItem
- Padding="0"
- IsVisible="{Binding ShowConsoleVisible}"
- Command="{Binding ToggleShowConsole}"
- Header="{locale:Locale MenuBarOptionsShowConsole}">
- <MenuItem.Icon>
- <CheckBox
- MinWidth="{DynamicResource CheckBoxSize}"
- MinHeight="{DynamicResource CheckBoxSize}"
- IsChecked="{Binding ShowConsole, Mode=TwoWay}"
- Padding="0" />
- </MenuItem.Icon>
- <MenuItem.Styles>
- <Style Selector="Viewbox#PART_IconPresenter">
- <Setter Property="MaxHeight" Value="36" />
- <Setter Property="MinHeight" Value="36" />
- <Setter Property="MaxWidth" Value="36" />
- <Setter Property="MinWidth" Value="36" />
- </Style>
- <Style Selector="ContentPresenter#PART_HeaderPresenter">
- <Setter Property="Padding" Value="-10,0,0,0" />
- </Style>
- </MenuItem.Styles>
- </MenuItem>
- <Separator />
- <MenuItem
- Name="ChangeLanguageMenuItem"
- Padding="-10,0,0,0"
- Header="{locale:Locale MenuBarOptionsChangeLanguage}" />
- <MenuItem
- Name="ToggleFileTypesMenuItem"
- Padding="-10,0,0,0"
- Header="{locale:Locale MenuBarShowFileTypes}" />
- <Separator />
- <MenuItem
- Click="OpenSettings"
- Padding="-10,0,0,0"
- Header="{locale:Locale MenuBarOptionsSettings}"
- ToolTip.Tip="{locale:Locale OpenSettingsTooltip}" />
- <MenuItem
- Command="{Binding ManageProfiles}"
- Padding="-10,0,0,0"
- Header="{locale:Locale MenuBarOptionsManageUserProfiles}"
- IsEnabled="{Binding EnableNonGameRunningControls}"
- ToolTip.Tip="{locale:Locale OpenProfileManagerTooltip}" />
- </MenuItem>
- <MenuItem
- Name="ActionsMenuItem"
- VerticalAlignment="Center"
- Header="{locale:Locale MenuBarActions}"
- IsEnabled="{Binding IsGameRunning}">
- <MenuItem
- Click="PauseEmulation_Click"
- Header="{locale:Locale MenuBarOptionsPauseEmulation}"
- InputGesture="{Binding PauseKey}"
- IsEnabled="{Binding !IsPaused}"
- IsVisible="{Binding !IsPaused}" />
- <MenuItem
- Click="ResumeEmulation_Click"
- Header="{locale:Locale MenuBarOptionsResumeEmulation}"
- InputGesture="{Binding PauseKey}"
- IsEnabled="{Binding IsPaused}"
- IsVisible="{Binding IsPaused}" />
- <MenuItem
- Click="StopEmulation_Click"
- Header="{locale:Locale MenuBarOptionsStopEmulation}"
- InputGesture="Escape"
- IsEnabled="{Binding IsGameRunning}"
- ToolTip.Tip="{locale:Locale StopEmulationTooltip}" />
- <MenuItem Command="{Binding SimulateWakeUpMessage}" Header="{locale:Locale MenuBarOptionsSimulateWakeUpMessage}" />
- <Separator />
- <MenuItem
- Name="ScanAmiiboMenuItem"
- AttachedToVisualTree="ScanAmiiboMenuItem_AttachedToVisualTree"
- Click="OpenAmiiboWindow"
- Header="{locale:Locale MenuBarActionsScanAmiibo}"
- IsEnabled="{Binding IsAmiiboRequested}" />
- <MenuItem
- Command="{Binding TakeScreenshot}"
- Header="{locale:Locale MenuBarFileToolsTakeScreenshot}"
- InputGesture="{Binding ScreenshotKey}"
- IsEnabled="{Binding IsGameRunning}" />
- <MenuItem
- Command="{Binding HideUi}"
- Header="{locale:Locale MenuBarFileToolsHideUi}"
- InputGesture="{Binding ShowUiKey}"
- IsEnabled="{Binding IsGameRunning}" />
- <MenuItem
- Click="OpenCheatManagerForCurrentApp"
- Header="{locale:Locale GameListContextMenuManageCheat}"
- IsEnabled="{Binding IsGameRunning}" />
- </MenuItem>
- <MenuItem VerticalAlignment="Center" Header="{locale:Locale MenuBarTools}">
- <MenuItem Header="{locale:Locale MenuBarToolsInstallFirmware}" IsEnabled="{Binding EnableNonGameRunningControls}">
- <MenuItem Command="{Binding InstallFirmwareFromFile}" Header="{locale:Locale MenuBarFileToolsInstallFirmwareFromFile}" />
- <MenuItem Command="{Binding InstallFirmwareFromFolder}" Header="{locale:Locale MenuBarFileToolsInstallFirmwareFromDirectory}" />
- </MenuItem>
- <MenuItem Header="{locale:Locale MenuBarToolsManageFileTypes}" IsVisible="{Binding ManageFileTypesVisible}">
- <MenuItem Header="{locale:Locale MenuBarToolsInstallFileTypes}" Click="InstallFileTypes_Click"/>
- <MenuItem Header="{locale:Locale MenuBarToolsUninstallFileTypes}" Click="UninstallFileTypes_Click"/>
- </MenuItem>
- </MenuItem>
- <MenuItem VerticalAlignment="Center" Header="{locale:Locale MenuBarHelp}">
- <MenuItem
- Name="UpdateMenuItem"
- IsEnabled="{Binding CanUpdate}"
- Click="CheckForUpdates"
- Header="{locale:Locale MenuBarHelpCheckForUpdates}"
- ToolTip.Tip="{locale:Locale CheckUpdatesTooltip}" />
- <Separator />
- <MenuItem
- Click="OpenAboutWindow"
- Header="{locale:Locale MenuBarHelpAbout}"
- ToolTip.Tip="{locale:Locale OpenAboutTooltip}" />
- </MenuItem>
- </Menu>
- </DockPanel>
-</UserControl>
diff --git a/src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs
deleted file mode 100644
index 8dff5086..00000000
--- a/src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs
+++ /dev/null
@@ -1,232 +0,0 @@
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Interactivity;
-using LibHac.Ncm;
-using LibHac.Tools.FsSystem.NcaUtils;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.Ava.UI.Windows;
-using Ryujinx.Common;
-using Ryujinx.Common.Utilities;
-using Ryujinx.Modules;
-using Ryujinx.UI.Common;
-using Ryujinx.UI.Common.Configuration;
-using Ryujinx.UI.Common.Helper;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-
-namespace Ryujinx.Ava.UI.Views.Main
-{
- public partial class MainMenuBarView : UserControl
- {
- public MainWindow Window { get; private set; }
- public MainWindowViewModel ViewModel { get; private set; }
-
- public MainMenuBarView()
- {
- InitializeComponent();
-
- ToggleFileTypesMenuItem.ItemsSource = GenerateToggleFileTypeItems();
- ChangeLanguageMenuItem.ItemsSource = GenerateLanguageMenuItems();
- }
-
- private CheckBox[] GenerateToggleFileTypeItems()
- {
- List<CheckBox> checkBoxes = new();
-
- foreach (var item in Enum.GetValues(typeof(FileTypes)))
- {
- string fileName = Enum.GetName(typeof(FileTypes), item);
- checkBoxes.Add(new CheckBox
- {
- Content = $".{fileName}",
- IsChecked = ((FileTypes)item).GetConfigValue(ConfigurationState.Instance.UI.ShownFileTypes),
- Command = MiniCommand.Create(() => Window.ToggleFileType(fileName)),
- });
- }
-
- return checkBoxes.ToArray();
- }
-
- private static MenuItem[] GenerateLanguageMenuItems()
- {
- List<MenuItem> menuItems = new();
-
- string localePath = "Ryujinx.Ava/Assets/Locales";
- string localeExt = ".json";
-
- string[] localesPath = EmbeddedResources.GetAllAvailableResources(localePath, localeExt);
-
- Array.Sort(localesPath);
-
- foreach (string locale in localesPath)
- {
- string languageCode = Path.GetFileNameWithoutExtension(locale).Split('.').Last();
- string languageJson = EmbeddedResources.ReadAllText($"{localePath}/{languageCode}{localeExt}");
- var strings = JsonHelper.Deserialize(languageJson, CommonJsonContext.Default.StringDictionary);
-
- if (!strings.TryGetValue("Language", out string languageName))
- {
- languageName = languageCode;
- }
-
- MenuItem menuItem = new()
- {
- Header = languageName,
- Command = MiniCommand.Create(() =>
- {
- MainWindowViewModel.ChangeLanguage(languageCode);
- }),
- };
-
- menuItems.Add(menuItem);
- }
-
- return menuItems.ToArray();
- }
-
- protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
- {
- base.OnAttachedToVisualTree(e);
-
- if (VisualRoot is MainWindow window)
- {
- Window = window;
- }
-
- ViewModel = Window.ViewModel;
- DataContext = ViewModel;
- }
-
- private async void StopEmulation_Click(object sender, RoutedEventArgs e)
- {
- await Window.ViewModel.AppHost?.ShowExitPrompt();
- }
-
- private void PauseEmulation_Click(object sender, RoutedEventArgs e)
- {
- Window.ViewModel.AppHost?.Pause();
- }
-
- private void ResumeEmulation_Click(object sender, RoutedEventArgs e)
- {
- Window.ViewModel.AppHost?.Resume();
- }
-
- public async void OpenSettings(object sender, RoutedEventArgs e)
- {
- Window.SettingsWindow = new(Window.VirtualFileSystem, Window.ContentManager);
-
- await Window.SettingsWindow.ShowDialog(Window);
-
- Window.SettingsWindow = null;
-
- ViewModel.LoadConfigurableHotKeys();
- }
-
- public async void OpenMiiApplet(object sender, RoutedEventArgs e)
- {
- string contentPath = ViewModel.ContentManager.GetInstalledContentPath(0x0100000000001009, StorageId.BuiltInSystem, NcaContentType.Program);
-
- if (!string.IsNullOrEmpty(contentPath))
- {
- await ViewModel.LoadApplication(contentPath, false, "Mii Applet");
- }
- }
-
- public async void OpenAmiiboWindow(object sender, RoutedEventArgs e)
- {
- if (!ViewModel.IsAmiiboRequested)
- {
- return;
- }
-
- if (ViewModel.AppHost.Device.System.SearchingForAmiibo(out int deviceId))
- {
- string titleId = ViewModel.AppHost.Device.Processes.ActiveApplication.ProgramIdText.ToUpper();
- AmiiboWindow window = new(ViewModel.ShowAll, ViewModel.LastScannedAmiiboId, titleId);
-
- await window.ShowDialog(Window);
-
- if (window.IsScanned)
- {
- ViewModel.ShowAll = window.ViewModel.ShowAllAmiibo;
- ViewModel.LastScannedAmiiboId = window.ScannedAmiibo.GetId();
-
- ViewModel.AppHost.Device.System.ScanAmiibo(deviceId, ViewModel.LastScannedAmiiboId, window.ViewModel.UseRandomUuid);
- }
- }
- }
-
- public async void OpenCheatManagerForCurrentApp(object sender, RoutedEventArgs e)
- {
- if (!ViewModel.IsGameRunning)
- {
- return;
- }
-
- string name = ViewModel.AppHost.Device.Processes.ActiveApplication.ApplicationControlProperties.Title[(int)ViewModel.AppHost.Device.System.State.DesiredTitleLanguage].NameString.ToString();
-
- await new CheatWindow(
- Window.VirtualFileSystem,
- ViewModel.AppHost.Device.Processes.ActiveApplication.ProgramIdText,
- name,
- Window.ViewModel.SelectedApplication.Path).ShowDialog(Window);
-
- ViewModel.AppHost.Device.EnableCheats();
- }
-
- private void ScanAmiiboMenuItem_AttachedToVisualTree(object sender, VisualTreeAttachmentEventArgs e)
- {
- if (sender is MenuItem)
- {
- ViewModel.IsAmiiboRequested = Window.ViewModel.AppHost.Device.System.SearchingForAmiibo(out _);
- }
- }
-
- private async void InstallFileTypes_Click(object sender, RoutedEventArgs e)
- {
- if (FileAssociationHelper.Install())
- {
- await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.DialogInstallFileTypesSuccessMessage], string.Empty, LocaleManager.Instance[LocaleKeys.InputDialogOk], string.Empty, string.Empty);
- }
- else
- {
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogInstallFileTypesErrorMessage]);
- }
- }
-
- private async void UninstallFileTypes_Click(object sender, RoutedEventArgs e)
- {
- if (FileAssociationHelper.Uninstall())
- {
- await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.DialogUninstallFileTypesSuccessMessage], string.Empty, LocaleManager.Instance[LocaleKeys.InputDialogOk], string.Empty, string.Empty);
- }
- else
- {
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogUninstallFileTypesErrorMessage]);
- }
- }
-
- public async void CheckForUpdates(object sender, RoutedEventArgs e)
- {
- if (Updater.CanUpdate(true))
- {
- await Updater.BeginParse(Window, true);
- }
- }
-
- public async void OpenAboutWindow(object sender, RoutedEventArgs e)
- {
- await AboutWindow.Show();
- }
-
- public void CloseWindow(object sender, RoutedEventArgs e)
- {
- Window.Close();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml b/src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml
deleted file mode 100644
index f9e192e6..00000000
--- a/src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml
+++ /dev/null
@@ -1,289 +0,0 @@
-<UserControl
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- xmlns:config="clr-namespace:Ryujinx.Common.Configuration;assembly=Ryujinx.Common"
- mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
- x:Class="Ryujinx.Ava.UI.Views.Main.MainStatusBarView"
- x:DataType="viewModels:MainWindowViewModel">
- <Design.DataContext>
- <viewModels:MainWindowViewModel />
- </Design.DataContext>
- <Grid
- Name="StatusBar"
- Margin="0"
- MinHeight="22"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Bottom"
- Background="{DynamicResource ThemeContentBackgroundColor}"
- DockPanel.Dock="Bottom"
- IsVisible="{Binding ShowMenuAndStatusBar}">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="*" />
- <ColumnDefinition Width="Auto" />
- </Grid.ColumnDefinitions>
- <StackPanel
- Grid.Column="0"
- Margin="5"
- VerticalAlignment="Center"
- IsVisible="{Binding EnableNonGameRunningControls}">
- <Grid Margin="0">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition />
- </Grid.ColumnDefinitions>
- <Button
- Width="25"
- Height="25"
- MinWidth="0"
- Margin="0,0,5,0"
- VerticalAlignment="Center"
- Background="Transparent"
- Click="Refresh_OnClick">
- <ui:SymbolIcon
- Width="50"
- Height="100"
- Symbol="Refresh" />
- </Button>
- <TextBlock
- Name="LoadStatus"
- Grid.Column="1"
- Margin="0,0,5,0"
- VerticalAlignment="Center"
- IsVisible="{Binding EnableNonGameRunningControls}"
- Text="{locale:Locale StatusBarGamesLoaded}" />
- <ProgressBar
- Name="LoadProgressBar"
- Grid.Column="2"
- Height="6"
- VerticalAlignment="Center"
- Foreground="{DynamicResource SystemAccentColorLight2}"
- IsVisible="{Binding StatusBarVisible}"
- Maximum="{Binding StatusBarProgressMaximum}"
- Value="{Binding StatusBarProgressValue}" />
- </Grid>
- </StackPanel>
- <StackPanel
- Grid.Column="1"
- Margin="0,2"
- HorizontalAlignment="Left"
- VerticalAlignment="Center"
- IsVisible="{Binding IsGameRunning}"
- MaxHeight="18"
- Orientation="Horizontal">
- <TextBlock
- Name="VsyncStatus"
- Margin="5,0,5,0"
- HorizontalAlignment="Left"
- VerticalAlignment="Center"
- Foreground="{Binding VsyncColor}"
- IsVisible="{Binding !ShowLoadProgress}"
- PointerReleased="VsyncStatus_PointerReleased"
- Text="VSync"
- TextAlignment="Start" />
- <Border
- Width="2"
- Height="12"
- Margin="0"
- BorderBrush="Gray"
- Background="Gray"
- BorderThickness="1"
- IsVisible="{Binding !ShowLoadProgress}" />
- <TextBlock
- Name="DockedStatus"
- Margin="5,0,5,0"
- HorizontalAlignment="Left"
- VerticalAlignment="Center"
- IsVisible="{Binding !ShowLoadProgress}"
- PointerReleased="DockedStatus_PointerReleased"
- Text="{Binding DockedStatusText}"
- TextAlignment="Start" />
- <Border
- Width="2"
- Height="12"
- Margin="0"
- BorderBrush="Gray"
- Background="Gray"
- BorderThickness="1"
- IsVisible="{Binding !ShowLoadProgress}" />
- <SplitButton
- Name="AspectRatioStatus"
- Padding="5,0,5,0"
- HorizontalAlignment="Left"
- VerticalAlignment="Center"
- Background="Transparent"
- BorderThickness="0"
- CornerRadius="0"
- IsVisible="{Binding !ShowLoadProgress}"
- Content="{Binding AspectRatioStatusText}"
- Click="AspectRatioStatus_OnClick"
- ToolTip.Tip="{locale:Locale AspectRatioTooltip}">
- <SplitButton.Styles>
- <Style Selector="Border#SeparatorBorder">
- <Setter Property="Opacity" Value="0" />
- </Style>
- </SplitButton.Styles>
- <SplitButton.Flyout>
- <MenuFlyout Placement="Bottom" ShowMode="TransientWithDismissOnPointerMoveAway">
- <MenuItem
- Header="{locale:Locale SettingsTabGraphicsAspectRatio4x3}"
- Command="{Binding SetAspectRatio}"
- CommandParameter="{x:Static config:AspectRatio.Fixed4x3}"/>
- <MenuItem
- Header="{locale:Locale SettingsTabGraphicsAspectRatio16x9}"
- Command="{Binding SetAspectRatio}"
- CommandParameter="{x:Static config:AspectRatio.Fixed16x9}"/>
- <MenuItem
- Header="{locale:Locale SettingsTabGraphicsAspectRatio16x10}"
- Command="{Binding SetAspectRatio}"
- CommandParameter="{x:Static config:AspectRatio.Fixed16x10}"/>
- <MenuItem
- Header="{locale:Locale SettingsTabGraphicsAspectRatio21x9}"
- Command="{Binding SetAspectRatio}"
- CommandParameter="{x:Static config:AspectRatio.Fixed21x9}"/>
- <MenuItem
- Header="{locale:Locale SettingsTabGraphicsAspectRatio32x9}"
- Command="{Binding SetAspectRatio}"
- CommandParameter="{x:Static config:AspectRatio.Fixed32x9}"/>
- <MenuItem
- Header="{locale:Locale SettingsTabGraphicsAspectRatioStretch}"
- Command="{Binding SetAspectRatio}"
- CommandParameter="{x:Static config:AspectRatio.Stretched}"/>
- </MenuFlyout>
- </SplitButton.Flyout>
- </SplitButton>
- <Border
- Width="2"
- Height="12"
- Margin="0"
- BorderBrush="Gray"
- Background="Gray"
- BorderThickness="1"
- IsVisible="{Binding !ShowLoadProgress}" />
- <ToggleSplitButton
- Name="VolumeStatus"
- Padding="5,0,5,0"
- HorizontalAlignment="Left"
- VerticalAlignment="Center"
- VerticalContentAlignment="Center"
- Content="{Binding VolumeStatusText}"
- IsChecked="{Binding VolumeMuted}"
- IsVisible="{Binding !ShowLoadProgress}"
- PointerWheelChanged="VolumeStatus_OnPointerWheelChanged"
- Background="Transparent"
- BorderThickness="0"
- CornerRadius="0">
- <ToggleSplitButton.Styles>
- <Style Selector=":checked">
- <Style Selector="^:checked ContentPresenter">
- <Setter Property="Foreground" Value="{DynamicResource ThemeForegroundColor}" />
- </Style>
- </Style>
- <Style Selector="Border#SeparatorBorder">
- <Setter Property="Opacity" Value="0" />
- </Style>
- </ToggleSplitButton.Styles>
- <ToggleSplitButton.Flyout>
- <Flyout Placement="Bottom" ShowMode="TransientWithDismissOnPointerMoveAway">
- <Grid Margin="0">
- <controls:SliderScroll
- MaxHeight="40"
- Width="150"
- Margin="0"
- Padding="0"
- IsSnapToTickEnabled="True"
- LargeChange="0.05"
- Maximum="1"
- Minimum="0"
- SmallChange="0.01"
- TickFrequency="0.05"
- ToolTip.Tip="{locale:Locale AudioVolumeTooltip}"
- Value="{Binding Volume}" />
- </Grid>
- </Flyout>
- </ToggleSplitButton.Flyout>
- </ToggleSplitButton>
- <Border
- Width="2"
- Height="12"
- Margin="0"
- BorderBrush="Gray"
- Background="Gray"
- BorderThickness="1"
- IsVisible="{Binding !ShowLoadProgress}" />
- <TextBlock
- Margin="5,0,5,0"
- HorizontalAlignment="Left"
- VerticalAlignment="Center"
- IsVisible="{Binding !ShowLoadProgress}"
- Text="{Binding GameStatusText}"
- TextAlignment="Start" />
- <Border
- Width="2"
- Height="12"
- Margin="0"
- BorderBrush="Gray"
- Background="Gray"
- BorderThickness="1"
- IsVisible="{Binding !ShowLoadProgress}" />
- <TextBlock
- Margin="5,0,5,0"
- HorizontalAlignment="Left"
- VerticalAlignment="Center"
- IsVisible="{Binding !ShowLoadProgress}"
- Text="{Binding FifoStatusText}"
- TextAlignment="Start" />
- <Border
- Width="2"
- Height="12"
- Margin="0"
- BorderBrush="Gray"
- Background="Gray"
- BorderThickness="1"
- IsVisible="{Binding !ShowLoadProgress}" />
- <TextBlock
- Margin="5,0,5,0"
- HorizontalAlignment="Left"
- VerticalAlignment="Center"
- IsVisible="{Binding !ShowLoadProgress}"
- Text="{Binding BackendText}"
- TextAlignment="Start" />
- <Border
- Width="2"
- Height="12"
- Margin="0"
- BorderBrush="Gray"
- Background="Gray"
- BorderThickness="1"
- IsVisible="{Binding !ShowLoadProgress}" />
- <TextBlock
- Margin="5,0,5,0"
- HorizontalAlignment="Left"
- VerticalAlignment="Center"
- IsVisible="{Binding !ShowLoadProgress}"
- Text="{Binding GpuNameText}"
- TextAlignment="Start" />
- </StackPanel>
- <StackPanel
- Grid.Column="3"
- Margin="0,0,5,0"
- VerticalAlignment="Center"
- IsVisible="{Binding ShowFirmwareStatus}"
- Orientation="Horizontal">
- <TextBlock
- Name="FirmwareStatus"
- Margin="0"
- HorizontalAlignment="Right"
- VerticalAlignment="Center"
- Text="{locale:Locale StatusBarSystemVersion}" />
- </StackPanel>
- </Grid>
-</UserControl>
diff --git a/src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml.cs
deleted file mode 100644
index 239a7cbf..00000000
--- a/src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Input;
-using Avalonia.Interactivity;
-using Ryujinx.Ava.UI.Windows;
-using Ryujinx.Common.Configuration;
-using Ryujinx.Common.Logging;
-using Ryujinx.UI.Common.Configuration;
-using System;
-
-namespace Ryujinx.Ava.UI.Views.Main
-{
- public partial class MainStatusBarView : UserControl
- {
- public MainWindow Window;
-
- public MainStatusBarView()
- {
- InitializeComponent();
- }
-
- protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
- {
- base.OnAttachedToVisualTree(e);
-
- if (VisualRoot is MainWindow window)
- {
- Window = window;
- }
-
- DataContext = Window.ViewModel;
- }
-
- private void VsyncStatus_PointerReleased(object sender, PointerReleasedEventArgs e)
- {
- Window.ViewModel.AppHost.Device.EnableDeviceVsync = !Window.ViewModel.AppHost.Device.EnableDeviceVsync;
-
- Logger.Info?.Print(LogClass.Application, $"VSync toggled to: {Window.ViewModel.AppHost.Device.EnableDeviceVsync}");
- }
-
- private void DockedStatus_PointerReleased(object sender, PointerReleasedEventArgs e)
- {
- ConfigurationState.Instance.System.EnableDockedMode.Value = !ConfigurationState.Instance.System.EnableDockedMode.Value;
- }
-
- private void AspectRatioStatus_OnClick(object sender, RoutedEventArgs e)
- {
- AspectRatio aspectRatio = ConfigurationState.Instance.Graphics.AspectRatio.Value;
- ConfigurationState.Instance.Graphics.AspectRatio.Value = (int)aspectRatio + 1 > Enum.GetNames(typeof(AspectRatio)).Length - 1 ? AspectRatio.Fixed4x3 : aspectRatio + 1;
- }
-
- private void Refresh_OnClick(object sender, RoutedEventArgs e)
- {
- Window.LoadApplications();
- }
-
- private void VolumeStatus_OnPointerWheelChanged(object sender, PointerWheelEventArgs e)
- {
- // Change the volume by 5% at a time
- float newValue = Window.ViewModel.Volume + (float)e.Delta.Y * 0.05f;
-
- Window.ViewModel.Volume = newValue switch
- {
- < 0 => 0,
- > 1 => 1,
- _ => newValue,
- };
-
- e.Handled = true;
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml b/src/Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml
deleted file mode 100644
index cc21b5c6..00000000
--- a/src/Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml
+++ /dev/null
@@ -1,177 +0,0 @@
-<UserControl
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
- xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
- xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
- x:Class="Ryujinx.Ava.UI.Views.Main.MainViewControls"
- x:DataType="viewModels:MainWindowViewModel">
- <Design.DataContext>
- <viewModels:MainWindowViewModel />
- </Design.DataContext>
- <DockPanel
- Margin="0,0,0,5"
- Height="35"
- HorizontalAlignment="Stretch">
- <Button
- Width="40"
- MinWidth="40"
- Margin="5,2,0,2"
- VerticalAlignment="Stretch"
- Command="{Binding SetListMode}"
- IsEnabled="{Binding IsGrid}">
- <ui:FontIcon
- Margin="0"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Center"
- FontFamily="avares://FluentAvalonia/Fonts#Symbols"
- Glyph="{helpers:GlyphValueConverter List}" />
- </Button>
- <Button
- Width="40"
- MinWidth="40"
- Margin="5,2,5,2"
- VerticalAlignment="Stretch"
- Command="{Binding SetGridMode}"
- IsEnabled="{Binding IsList}">
- <ui:FontIcon
- Margin="0"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Center"
- FontFamily="avares://FluentAvalonia/Fonts#Symbols"
- Glyph="{helpers:GlyphValueConverter Grid}" />
- </Button>
- <TextBlock
- Margin="10,0"
- VerticalAlignment="Center"
- Text="{locale:Locale IconSize}"
- ToolTip.Tip="{locale:Locale IconSizeTooltip}" />
- <controls:SliderScroll
- Width="150"
- Height="35"
- Margin="5,-10,5,0"
- VerticalAlignment="Center"
- IsSnapToTickEnabled="True"
- SmallChange="1"
- Maximum="4"
- Minimum="1"
- TickFrequency="1"
- ToolTip.Tip="{locale:Locale IconSizeTooltip}"
- Value="{Binding GridSizeScale}" />
- <CheckBox
- Margin="0"
- VerticalAlignment="Center"
- IsChecked="{Binding ShowNames, Mode=TwoWay}"
- IsVisible="{Binding IsGrid}">
- <TextBlock Margin="5,3,0,0" Text="{locale:Locale CommonShowNames}" />
- </CheckBox>
- <TextBox
- Name="SearchBox"
- MinWidth="200"
- Margin="5,0,5,0"
- HorizontalAlignment="Right"
- VerticalAlignment="Center"
- DockPanel.Dock="Right"
- KeyUp="SearchBox_OnKeyUp"
- Text="{Binding SearchText}"
- Watermark="{locale:Locale MenuSearch}" />
- <DropDownButton
- Width="150"
- HorizontalAlignment="Right"
- VerticalAlignment="Center"
- Content="{Binding SortName}"
- DockPanel.Dock="Right">
- <DropDownButton.Flyout>
- <Flyout Placement="Bottom">
- <StackPanel
- Margin="0"
- HorizontalAlignment="Stretch"
- Orientation="Vertical">
- <StackPanel>
- <RadioButton
- Checked="Sort_Checked"
- Content="{locale:Locale CommonFavorite}"
- GroupName="Sort"
- IsChecked="{Binding IsSortedByFavorite, Mode=OneTime}"
- Tag="Favorite" />
- <RadioButton
- Checked="Sort_Checked"
- Content="{locale:Locale GameListHeaderApplication}"
- GroupName="Sort"
- IsChecked="{Binding IsSortedByTitle, Mode=OneTime}"
- Tag="Title" />
- <RadioButton
- Checked="Sort_Checked"
- Content="{locale:Locale GameListHeaderDeveloper}"
- GroupName="Sort"
- IsChecked="{Binding IsSortedByDeveloper, Mode=OneTime}"
- Tag="Developer" />
- <RadioButton
- Checked="Sort_Checked"
- Content="{locale:Locale GameListHeaderTimePlayed}"
- GroupName="Sort"
- IsChecked="{Binding IsSortedByTimePlayed, Mode=OneTime}"
- Tag="TotalTimePlayed" />
- <RadioButton
- Checked="Sort_Checked"
- Content="{locale:Locale GameListHeaderLastPlayed}"
- GroupName="Sort"
- IsChecked="{Binding IsSortedByLastPlayed, Mode=OneTime}"
- Tag="LastPlayed" />
- <RadioButton
- Checked="Sort_Checked"
- Content="{locale:Locale GameListHeaderFileExtension}"
- GroupName="Sort"
- IsChecked="{Binding IsSortedByType, Mode=OneTime}"
- Tag="FileType" />
- <RadioButton
- Checked="Sort_Checked"
- Content="{locale:Locale GameListHeaderFileSize}"
- GroupName="Sort"
- IsChecked="{Binding IsSortedBySize, Mode=OneTime}"
- Tag="FileSize" />
- <RadioButton
- Checked="Sort_Checked"
- Content="{locale:Locale GameListHeaderPath}"
- GroupName="Sort"
- IsChecked="{Binding IsSortedByPath, Mode=OneTime}"
- Tag="Path" />
- </StackPanel>
- <Border
- Width="60"
- Height="2"
- Margin="5"
- HorizontalAlignment="Stretch"
- BorderBrush="White"
- BorderThickness="0,1,0,0">
- <Separator Height="0" HorizontalAlignment="Stretch" />
- </Border>
- <RadioButton
- Checked="Order_Checked"
- Content="{locale:Locale OrderAscending}"
- GroupName="Order"
- IsChecked="{Binding IsAscending, Mode=OneTime}"
- Tag="Ascending" />
- <RadioButton
- Checked="Order_Checked"
- Content="{locale:Locale OrderDescending}"
- GroupName="Order"
- IsChecked="{Binding !IsAscending, Mode=OneTime}"
- Tag="Descending" />
- </StackPanel>
- </Flyout>
- </DropDownButton.Flyout>
- </DropDownButton>
- <TextBlock
- Margin="10,0"
- HorizontalAlignment="Right"
- VerticalAlignment="Center"
- DockPanel.Dock="Right"
- Text="{locale:Locale CommonSort}" />
- </DockPanel>
-</UserControl>
diff --git a/src/Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml.cs b/src/Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml.cs
deleted file mode 100644
index 02fd1bf5..00000000
--- a/src/Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Input;
-using Avalonia.Interactivity;
-using Ryujinx.Ava.Common;
-using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.Ava.UI.Windows;
-using System;
-
-namespace Ryujinx.Ava.UI.Views.Main
-{
- public partial class MainViewControls : UserControl
- {
- public MainWindowViewModel ViewModel;
-
- public MainViewControls()
- {
- InitializeComponent();
- }
-
- protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
- {
- base.OnAttachedToVisualTree(e);
-
- if (VisualRoot is MainWindow window)
- {
- ViewModel = window.ViewModel;
- }
-
- DataContext = ViewModel;
- }
-
- public void Sort_Checked(object sender, RoutedEventArgs args)
- {
- if (sender is RadioButton button)
- {
- ViewModel.Sort(Enum.Parse<ApplicationSort>(button.Tag.ToString()));
- }
- }
-
- public void Order_Checked(object sender, RoutedEventArgs args)
- {
- if (sender is RadioButton button)
- {
- ViewModel.Sort(button.Tag.ToString() != "Descending");
- }
- }
-
- private void SearchBox_OnKeyUp(object sender, KeyEventArgs e)
- {
- ViewModel.SearchText = SearchBox.Text;
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsAudioView.axaml b/src/Ryujinx.Ava/UI/Views/Settings/SettingsAudioView.axaml
deleted file mode 100644
index 657e07ee..00000000
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsAudioView.axaml
+++ /dev/null
@@ -1,81 +0,0 @@
-<UserControl
- x:Class="Ryujinx.Ava.UI.Views.Settings.SettingsAudioView"
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
- xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- mc:Ignorable="d"
- x:DataType="viewModels:SettingsViewModel">
- <Design.DataContext>
- <viewModels:SettingsViewModel />
- </Design.DataContext>
- <ScrollViewer
- Name="AudioPage"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- HorizontalScrollBarVisibility="Disabled"
- VerticalScrollBarVisibility="Auto">
- <Border Classes="settings">
- <StackPanel
- Margin="10"
- HorizontalAlignment="Stretch"
- Orientation="Vertical"
- Spacing="10">
- <TextBlock Classes="h1" Text="{locale:Locale SettingsTabAudio}" />
- <StackPanel Margin="10,0,0,0" Orientation="Horizontal">
- <TextBlock VerticalAlignment="Center"
- Text="{locale:Locale SettingsTabSystemAudioBackend}"
- ToolTip.Tip="{locale:Locale AudioBackendTooltip}"
- Width="250" />
- <ComboBox SelectedIndex="{Binding AudioBackend}"
- Width="350"
- HorizontalContentAlignment="Left">
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemAudioBackendDummy}" />
- </ComboBoxItem>
- <ComboBoxItem IsEnabled="{Binding IsOpenAlEnabled}">
- <TextBlock Text="{locale:Locale SettingsTabSystemAudioBackendOpenAL}" />
- </ComboBoxItem>
- <ComboBoxItem IsEnabled="{Binding IsSoundIoEnabled}">
- <TextBlock Text="{locale:Locale SettingsTabSystemAudioBackendSoundIO}" />
- </ComboBoxItem>
- <ComboBoxItem IsEnabled="{Binding IsSDL2Enabled}">
- <TextBlock Text="{locale:Locale SettingsTabSystemAudioBackendSDL2}" />
- </ComboBoxItem>
- </ComboBox>
- </StackPanel>
- <StackPanel Margin="10,0,0,0" Orientation="Horizontal">
- <TextBlock VerticalAlignment="Center"
- Text="{locale:Locale SettingsTabSystemAudioVolume}"
- ToolTip.Tip="{locale:Locale AudioVolumeTooltip}"
- Width="250" />
- <ui:NumberBox Value="{Binding Volume}"
- ToolTip.Tip="{locale:Locale AudioVolumeTooltip}"
- Width="350"
- SmallChange="1"
- LargeChange="10"
- SimpleNumberFormat="F0"
- SpinButtonPlacementMode="Inline"
- Minimum="0"
- Maximum="100" />
- </StackPanel>
- <StackPanel Margin="10,0,0,0" Orientation="Horizontal">
- <controls:SliderScroll Value="{Binding Volume}"
- Margin="250,0,0,0"
- ToolTip.Tip="{locale:Locale AudioVolumeTooltip}"
- Minimum="0"
- Maximum="100"
- SmallChange="1"
- TickFrequency="1"
- IsSnapToTickEnabled="True"
- LargeChange="10"
- Width="350" />
- </StackPanel>
- </StackPanel>
- </Border>
- </ScrollViewer>
-</UserControl>
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsAudioView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Settings/SettingsAudioView.axaml.cs
deleted file mode 100644
index b672a0f2..00000000
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsAudioView.axaml.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using Avalonia.Controls;
-
-namespace Ryujinx.Ava.UI.Views.Settings
-{
- public partial class SettingsAudioView : UserControl
- {
- public SettingsAudioView()
- {
- InitializeComponent();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsCPUView.axaml b/src/Ryujinx.Ava/UI/Views/Settings/SettingsCPUView.axaml
deleted file mode 100644
index c74d3dd5..00000000
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsCPUView.axaml
+++ /dev/null
@@ -1,77 +0,0 @@
-<UserControl
- x:Class="Ryujinx.Ava.UI.Views.Settings.SettingsCPUView"
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- mc:Ignorable="d"
- x:DataType="viewModels:SettingsViewModel">
- <Design.DataContext>
- <viewModels:SettingsViewModel />
- </Design.DataContext>
- <ScrollViewer
- Name="CpuPage"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- HorizontalScrollBarVisibility="Disabled"
- VerticalScrollBarVisibility="Auto">
- <Border Classes="settings">
- <StackPanel
- Margin="10"
- HorizontalAlignment="Stretch"
- Orientation="Vertical"
- Spacing="10">
- <TextBlock Classes="h1" Text="{locale:Locale SettingsTabCpuCache}" />
- <StackPanel
- Margin="10,0,0,0"
- HorizontalAlignment="Stretch"
- Orientation="Vertical">
- <CheckBox IsChecked="{Binding EnablePptc}">
- <TextBlock Text="{locale:Locale SettingsTabSystemEnablePptc}"
- ToolTip.Tip="{locale:Locale PptcToggleTooltip}" />
- </CheckBox>
- </StackPanel>
- <Separator Height="1" />
- <TextBlock Classes="h1" Text="{locale:Locale SettingsTabCpuMemory}" />
- <StackPanel
- Margin="10,0,0,0"
- HorizontalAlignment="Stretch"
- Orientation="Vertical">
- <StackPanel Orientation="Horizontal">
- <TextBlock VerticalAlignment="Center"
- Text="{locale:Locale SettingsTabSystemMemoryManagerMode}"
- ToolTip.Tip="{locale:Locale MemoryManagerTooltip}"
- Width="250" />
- <ComboBox SelectedIndex="{Binding MemoryMode}"
- ToolTip.Tip="{locale:Locale MemoryManagerTooltip}"
- HorizontalContentAlignment="Left"
- Width="350">
- <ComboBoxItem
- ToolTip.Tip="{locale:Locale MemoryManagerSoftwareTooltip}">
- <TextBlock
- Text="{locale:Locale SettingsTabSystemMemoryManagerModeSoftware}" />
- </ComboBoxItem>
- <ComboBoxItem
- ToolTip.Tip="{locale:Locale MemoryManagerHostTooltip}">
- <TextBlock Text="{locale:Locale SettingsTabSystemMemoryManagerModeHost}" />
- </ComboBoxItem>
- <ComboBoxItem
- ToolTip.Tip="{locale:Locale MemoryManagerUnsafeTooltip}">
- <TextBlock
- Text="{locale:Locale SettingsTabSystemMemoryManagerModeHostUnchecked}" />
- </ComboBoxItem>
- </ComboBox>
- </StackPanel>
- <CheckBox IsChecked="{Binding UseHypervisor}"
- IsVisible="{Binding IsHypervisorAvailable}"
- ToolTip.Tip="{locale:Locale UseHypervisorTooltip}">
- <TextBlock Text="{locale:Locale SettingsTabSystemUseHypervisor}"
- ToolTip.Tip="{locale:Locale UseHypervisorTooltip}" />
- </CheckBox>
- </StackPanel>
- </StackPanel>
- </Border>
- </ScrollViewer>
-</UserControl>
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsCPUView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Settings/SettingsCPUView.axaml.cs
deleted file mode 100644
index a475971a..00000000
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsCPUView.axaml.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using Avalonia.Controls;
-
-namespace Ryujinx.Ava.UI.Views.Settings
-{
- public partial class SettingsCPUView : UserControl
- {
- public SettingsCPUView()
- {
- InitializeComponent();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml b/src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml
deleted file mode 100644
index 22449478..00000000
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml
+++ /dev/null
@@ -1,301 +0,0 @@
-<UserControl
- x:Class="Ryujinx.Ava.UI.Views.Settings.SettingsGraphicsView"
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
- xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- Design.Width="1000"
- mc:Ignorable="d"
- x:DataType="viewModels:SettingsViewModel">
- <Design.DataContext>
- <viewModels:SettingsViewModel />
- </Design.DataContext>
- <ScrollViewer
- Name="GraphicsPage"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- HorizontalScrollBarVisibility="Disabled"
- VerticalScrollBarVisibility="Auto">
- <Border Classes="settings">
- <StackPanel
- Margin="10"
- HorizontalAlignment="Stretch"
- Orientation="Vertical"
- Spacing="10">
- <TextBlock Classes="h1" Text="{locale:Locale SettingsTabGraphicsAPI}" />
- <StackPanel Margin="10,0,0,0" Orientation="Vertical" Spacing="10">
- <StackPanel Orientation="Horizontal">
- <TextBlock VerticalAlignment="Center"
- ToolTip.Tip="{locale:Locale SettingsTabGraphicsBackendTooltip}"
- Text="{locale:Locale SettingsTabGraphicsBackend}"
- Width="250" />
- <ComboBox Width="350"
- HorizontalContentAlignment="Left"
- ToolTip.Tip="{locale:Locale SettingsTabGraphicsBackendTooltip}"
- SelectedIndex="{Binding GraphicsBackendIndex}">
- <ComboBoxItem IsVisible="{Binding IsVulkanAvailable}">
- <TextBlock Text="Vulkan" />
- </ComboBoxItem>
- <ComboBoxItem IsEnabled="{Binding IsOpenGLAvailable}">
- <TextBlock Text="OpenGL" />
- </ComboBoxItem>
- </ComboBox>
- </StackPanel>
- <StackPanel Orientation="Horizontal" IsVisible="{Binding IsVulkanSelected}">
- <TextBlock VerticalAlignment="Center"
- ToolTip.Tip="{locale:Locale SettingsTabGraphicsPreferredGpuTooltip}"
- Text="{locale:Locale SettingsTabGraphicsPreferredGpu}"
- Width="250" />
- <ComboBox Width="350"
- HorizontalContentAlignment="Left"
- ToolTip.Tip="{locale:Locale SettingsTabGraphicsPreferredGpuTooltip}"
- SelectedIndex="{Binding PreferredGpuIndex}"
- ItemsSource="{Binding AvailableGpus}"/>
- </StackPanel>
- </StackPanel>
- <Separator Height="1" />
- <TextBlock Classes="h1" Text="{locale:Locale SettingsTabGraphicsFeatures}" />
- <StackPanel Margin="10,0,0,0" Orientation="Vertical" Spacing="10">
- <StackPanel Orientation="Vertical">
- <CheckBox IsChecked="{Binding EnableShaderCache}"
- ToolTip.Tip="{locale:Locale ShaderCacheToggleTooltip}">
- <TextBlock Text="{locale:Locale SettingsTabGraphicsEnableShaderCache}" />
- </CheckBox>
- <CheckBox IsChecked="{Binding EnableTextureRecompression}"
- ToolTip.Tip="{locale:Locale SettingsEnableTextureRecompressionTooltip}">
- <TextBlock Text="{locale:Locale SettingsEnableTextureRecompression}" />
- </CheckBox>
- <CheckBox IsChecked="{Binding EnableMacroHLE}"
- ToolTip.Tip="{locale:Locale SettingsEnableMacroHLETooltip}">
- <TextBlock Text="{locale:Locale SettingsEnableMacroHLE}" />
- </CheckBox>
- <CheckBox IsChecked="{Binding EnableColorSpacePassthrough}"
- IsVisible="{Binding ColorSpacePassthroughAvailable}"
- ToolTip.Tip="{locale:Locale SettingsEnableColorSpacePassthroughTooltip}">
- <TextBlock Text="{locale:Locale SettingsEnableColorSpacePassthrough}" />
- </CheckBox>
- </StackPanel>
- <StackPanel Orientation="Horizontal">
- <TextBlock VerticalAlignment="Center"
- ToolTip.Tip="{locale:Locale ResolutionScaleTooltip}"
- Text="{locale:Locale SettingsTabGraphicsResolutionScale}"
- Width="250" />
- <ComboBox SelectedIndex="{Binding ResolutionScale}"
- Width="350"
- HorizontalContentAlignment="Left"
- ToolTip.Tip="{locale:Locale ResolutionScaleTooltip}">
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabGraphicsResolutionScaleNative}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabGraphicsResolutionScale2x}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabGraphicsResolutionScale3x}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabGraphicsResolutionScale4x}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabGraphicsResolutionScaleCustom}" />
- </ComboBoxItem>
- </ComboBox>
- <ui:NumberBox
- Margin="10,0,0,0"
- ToolTip.Tip="{locale:Locale ResolutionScaleEntryTooltip}"
- MinWidth="150"
- SmallChange="0.1"
- LargeChange="1"
- SimpleNumberFormat="F2"
- SpinButtonPlacementMode="Inline"
- IsVisible="{Binding IsCustomResolutionScaleActive}"
- Maximum="100"
- Minimum="0.1"
- Value="{Binding CustomResolutionScale}" />
- </StackPanel>
- <StackPanel
- HorizontalAlignment="Stretch"
- Orientation="Vertical"
- Spacing="10">
- <StackPanel Orientation="Horizontal">
- <TextBlock VerticalAlignment="Center"
- ToolTip.Tip="{locale:Locale GraphicsAATooltip}"
- Text="{locale:Locale GraphicsAALabel}"
- Width="250" />
- <ComboBox Width="350"
- HorizontalContentAlignment="Left"
- ToolTip.Tip="{locale:Locale GraphicsAATooltip}"
- SelectedIndex="{Binding AntiAliasingEffect}">
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabLoggingGraphicsBackendLogLevelNone}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="FXAA" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SmaaLow}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SmaaMedium}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SmaaHigh}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SmaaUltra}" />
- </ComboBoxItem>
- </ComboBox>
- </StackPanel>
- </StackPanel>
- <StackPanel
- HorizontalAlignment="Stretch"
- Orientation="Vertical"
- Spacing="10">
- <StackPanel Orientation="Horizontal">
- <TextBlock VerticalAlignment="Center"
- ToolTip.Tip="{locale:Locale GraphicsScalingFilterTooltip}"
- Text="{locale:Locale GraphicsScalingFilterLabel}"
- Width="250" />
- <ComboBox Width="350"
- HorizontalContentAlignment="Left"
- ToolTip.Tip="{locale:Locale GraphicsScalingFilterTooltip}"
- SelectedIndex="{Binding ScalingFilter}">
- <ComboBoxItem>
- <TextBlock Text="Bilinear" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="Nearest" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="FSR" />
- </ComboBoxItem>
- </ComboBox>
- <controls:SliderScroll Value="{Binding ScalingFilterLevel}"
- ToolTip.Tip="{locale:Locale GraphicsScalingFilterLevelTooltip}"
- MinWidth="150"
- Margin="10,-3,0,0"
- Height="32"
- Padding="0,-5"
- IsVisible="{Binding IsScalingFilterActive}"
- TickFrequency="1"
- IsSnapToTickEnabled="True"
- LargeChange="10"
- SmallChange="1"
- VerticalAlignment="Center"
- Minimum="0"
- Maximum="100" />
- <TextBlock Margin="5,0"
- Width="40"
- IsVisible="{Binding IsScalingFilterActive}"
- Text="{Binding ScalingFilterLevelText}"/>
- </StackPanel>
- </StackPanel>
- <StackPanel Orientation="Horizontal">
- <TextBlock VerticalAlignment="Center"
- ToolTip.Tip="{locale:Locale AnisotropyTooltip}"
- Text="{locale:Locale SettingsTabGraphicsAnisotropicFiltering}"
- Width="250" />
- <ComboBox SelectedIndex="{Binding MaxAnisotropy}"
- Width="350"
- HorizontalContentAlignment="Left"
- ToolTip.Tip="{locale:Locale AnisotropyTooltip}">
- <ComboBoxItem>
- <TextBlock
- Text="{locale:Locale SettingsTabGraphicsAnisotropicFilteringAuto}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabGraphicsAnisotropicFiltering2x}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabGraphicsAnisotropicFiltering4x}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabGraphicsAnisotropicFiltering8x}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock
- Text="{locale:Locale SettingsTabGraphicsAnisotropicFiltering16x}" />
- </ComboBoxItem>
- </ComboBox>
- </StackPanel>
- <StackPanel Orientation="Horizontal">
- <TextBlock VerticalAlignment="Center"
- ToolTip.Tip="{locale:Locale AspectRatioTooltip}"
- Text="{locale:Locale SettingsTabGraphicsAspectRatio}"
- Width="250" />
- <ComboBox SelectedIndex="{Binding AspectRatio}"
- Width="350"
- HorizontalContentAlignment="Left"
- ToolTip.Tip="{locale:Locale AspectRatioTooltip}">
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabGraphicsAspectRatio4x3}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabGraphicsAspectRatio16x9}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabGraphicsAspectRatio16x10}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabGraphicsAspectRatio21x9}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabGraphicsAspectRatio32x9}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabGraphicsAspectRatioStretch}" />
- </ComboBoxItem>
- </ComboBox>
- </StackPanel>
- </StackPanel>
- <StackPanel
- Margin="10,0,0,0"
- HorizontalAlignment="Stretch"
- Orientation="Vertical"
- Spacing="10">
- <StackPanel Orientation="Horizontal">
- <TextBlock VerticalAlignment="Center"
- ToolTip.Tip="{locale:Locale GraphicsBackendThreadingTooltip}"
- Text="{locale:Locale SettingsTabGraphicsBackendMultithreading}"
- Width="250" />
- <ComboBox Width="350"
- HorizontalContentAlignment="Left"
- ToolTip.Tip="{locale:Locale GalThreadingTooltip}"
- SelectedIndex="{Binding GraphicsBackendMultithreadingIndex}">
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale CommonAuto}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale CommonOff}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale CommonOn}" />
- </ComboBoxItem>
- </ComboBox>
- </StackPanel>
- </StackPanel>
- <Separator Height="1" />
- <TextBlock Classes="h1" Text="{locale:Locale SettingsTabGraphicsDeveloperOptions}" />
- <StackPanel
- Margin="10,0,0,0"
- HorizontalAlignment="Stretch"
- Orientation="Vertical"
- Spacing="10">
- <StackPanel Orientation="Horizontal">
- <TextBlock VerticalAlignment="Center"
- ToolTip.Tip="{locale:Locale ShaderDumpPathTooltip}"
- Text="{locale:Locale SettingsTabGraphicsShaderDumpPath}"
- Width="250" />
- <TextBox Text="{Binding ShaderDumpPath}"
- Width="350"
- ToolTip.Tip="{locale:Locale ShaderDumpPathTooltip}" />
- </StackPanel>
- </StackPanel>
- </StackPanel>
- </Border>
- </ScrollViewer>
-</UserControl>
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml.cs
deleted file mode 100644
index 67341330..00000000
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using Avalonia.Controls;
-
-namespace Ryujinx.Ava.UI.Views.Settings
-{
- public partial class SettingsGraphicsView : UserControl
- {
- public SettingsGraphicsView()
- {
- InitializeComponent();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml b/src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml
deleted file mode 100644
index b4eae01e..00000000
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml
+++ /dev/null
@@ -1,103 +0,0 @@
-<UserControl
- x:Class="Ryujinx.Ava.UI.Views.Settings.SettingsHotkeysView"
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
- mc:Ignorable="d"
- x:DataType="viewModels:SettingsViewModel"
- Focusable="True">
- <Design.DataContext>
- <viewModels:SettingsViewModel />
- </Design.DataContext>
- <UserControl.Resources>
- <helpers:KeyValueConverter x:Key="Key" />
- </UserControl.Resources>
- <ScrollViewer
- Name="HotkeysPage"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- HorizontalScrollBarVisibility="Disabled"
- VerticalScrollBarVisibility="Auto">
- <Border Classes="settings">
- <StackPanel Margin="10" Orientation="Vertical" Spacing="10">
- <TextBlock Classes="h1" Text="{locale:Locale SettingsTabHotkeysHotkeys}" />
- <StackPanel Margin="10,0,0,0" Orientation="Horizontal">
- <TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysToggleVsyncHotkey}" Width="230" />
- <ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
- <TextBlock
- Text="{Binding KeyboardHotkeys.ToggleVsync, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <StackPanel Margin="10,0,0,0" Orientation="Horizontal">
- <TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysScreenshotHotkey}" Width="230" />
- <ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
- <TextBlock
- Text="{Binding KeyboardHotkeys.Screenshot, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <StackPanel Margin="10,0,0,0" Orientation="Horizontal">
- <TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysShowUiHotkey}" Width="230" />
- <ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
- <TextBlock
- Text="{Binding KeyboardHotkeys.ShowUI, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <StackPanel Margin="10,0,0,0" Orientation="Horizontal">
- <TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysPauseHotkey}" Width="230" />
- <ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
- <TextBlock
- Text="{Binding KeyboardHotkeys.Pause, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <StackPanel Margin="10,0,0,0" Orientation="Horizontal">
- <TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysToggleMuteHotkey}" Width="230" />
- <ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
- <TextBlock
- Text="{Binding KeyboardHotkeys.ToggleMute, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <StackPanel Margin="10,0,0,0" Orientation="Horizontal">
- <TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysResScaleUpHotkey}" Width="230" />
- <ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
- <TextBlock
- Text="{Binding KeyboardHotkeys.ResScaleUp, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <StackPanel Margin="10,0,0,0" Orientation="Horizontal">
- <TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysResScaleDownHotkey}" Width="230" />
- <ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
- <TextBlock
- Text="{Binding KeyboardHotkeys.ResScaleDown, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <StackPanel Margin="10,0,0,0" Orientation="Horizontal">
- <TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysVolumeUpHotkey}" Width="230" />
- <ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
- <TextBlock
- Text="{Binding KeyboardHotkeys.VolumeUp, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- <StackPanel Margin="10,0,0,0" Orientation="Horizontal">
- <TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysVolumeDownHotkey}" Width="230" />
- <ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
- <TextBlock
- Text="{Binding KeyboardHotkeys.VolumeDown, Mode=TwoWay, Converter={StaticResource Key}}"
- TextAlignment="Center" />
- </ToggleButton>
- </StackPanel>
- </StackPanel>
- </Border>
- </ScrollViewer>
-</UserControl> \ No newline at end of file
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml.cs
deleted file mode 100644
index b006d703..00000000
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml.cs
+++ /dev/null
@@ -1,81 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Controls.Primitives;
-using Avalonia.Input;
-using Avalonia.Interactivity;
-using Ryujinx.Ava.Input;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Input;
-using Ryujinx.Input.Assigner;
-
-namespace Ryujinx.Ava.UI.Views.Settings
-{
- public partial class SettingsHotkeysView : UserControl
- {
- private ButtonKeyAssigner _currentAssigner;
- private readonly IGamepadDriver _avaloniaKeyboardDriver;
-
- public SettingsHotkeysView()
- {
- InitializeComponent();
- _avaloniaKeyboardDriver = new AvaloniaKeyboardDriver(this);
- }
-
- private void MouseClick(object sender, PointerPressedEventArgs e)
- {
- bool shouldUnbind = e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed;
-
- _currentAssigner?.Cancel(shouldUnbind);
-
- PointerPressed -= MouseClick;
- }
-
- private void Button_Checked(object sender, RoutedEventArgs e)
- {
- if (sender is ToggleButton button)
- {
- if (_currentAssigner != null && button == _currentAssigner.ToggledButton)
- {
- return;
- }
-
- if (_currentAssigner == null && button.IsChecked != null && (bool)button.IsChecked)
- {
- _currentAssigner = new ButtonKeyAssigner(button);
-
- this.Focus(NavigationMethod.Pointer);
-
- PointerPressed += MouseClick;
-
- var keyboard = (IKeyboard)_avaloniaKeyboardDriver.GetGamepad(_avaloniaKeyboardDriver.GamepadsIds[0]);
- IButtonAssigner assigner = new KeyboardKeyAssigner(keyboard);
-
- _currentAssigner.GetInputAndAssign(assigner);
- }
- else
- {
- if (_currentAssigner != null)
- {
- ToggleButton oldButton = _currentAssigner.ToggledButton;
-
- _currentAssigner.Cancel();
- _currentAssigner = null;
-
- button.IsChecked = false;
- }
- }
- }
- }
-
- private void Button_Unchecked(object sender, RoutedEventArgs e)
- {
- _currentAssigner?.Cancel();
- _currentAssigner = null;
- }
-
- public void Dispose()
- {
- _currentAssigner?.Cancel();
- _currentAssigner = null;
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml b/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml
deleted file mode 100644
index 81f4b68b..00000000
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml
+++ /dev/null
@@ -1,67 +0,0 @@
-<UserControl
- x:Class="Ryujinx.Ava.UI.Views.Settings.SettingsInputView"
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:views="clr-namespace:Ryujinx.Ava.UI.Views.Input"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- mc:Ignorable="d"
- x:DataType="viewModels:SettingsViewModel">
- <Design.DataContext>
- <viewModels:SettingsViewModel />
- </Design.DataContext>
- <ScrollViewer
- Name="InputPage"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- HorizontalScrollBarVisibility="Disabled"
- VerticalScrollBarVisibility="Auto">
- <Border Classes="settings">
- <Panel
- Margin="10">
- <Grid>
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="*" />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <views:ControllerInputView
- Grid.Row="0"
- Name="ControllerSettings" />
- <StackPanel
- Orientation="Vertical"
- Grid.Row="2">
- <Separator
- Margin="0 10"
- Height="1" />
- <StackPanel
- Orientation="Horizontal"
- Spacing="10">
- <CheckBox
- ToolTip.Tip="{locale:Locale DockModeToggleTooltip}"
- MinWidth="0"
- IsChecked="{Binding EnableDockedMode}">
- <TextBlock
- Text="{locale:Locale SettingsTabInputEnableDockedMode}" />
- </CheckBox>
- <CheckBox
- ToolTip.Tip="{locale:Locale DirectKeyboardTooltip}"
- IsChecked="{Binding EnableKeyboard}">
- <TextBlock
- Text="{locale:Locale SettingsTabInputDirectKeyboardAccess}" />
- </CheckBox>
- <CheckBox
- ToolTip.Tip="{locale:Locale DirectMouseTooltip}"
- IsChecked="{Binding EnableMouse}">
- <TextBlock
- Text="{locale:Locale SettingsTabInputDirectMouseAccess}" />
- </CheckBox>
- </StackPanel>
- </StackPanel>
- </Grid>
- </Panel>
- </Border>
- </ScrollViewer>
-</UserControl> \ No newline at end of file
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml.cs
deleted file mode 100644
index e75c9f0c..00000000
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using Avalonia.Controls;
-
-namespace Ryujinx.Ava.UI.Views.Settings
-{
- public partial class SettingsInputView : UserControl
- {
- public SettingsInputView()
- {
- InitializeComponent();
- }
-
- public void Dispose()
- {
- ControllerSettings.Dispose();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsLoggingView.axaml b/src/Ryujinx.Ava/UI/Views/Settings/SettingsLoggingView.axaml
deleted file mode 100644
index 0fc9ea1b..00000000
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsLoggingView.axaml
+++ /dev/null
@@ -1,120 +0,0 @@
-<UserControl
- x:Class="Ryujinx.Ava.UI.Views.Settings.SettingsLoggingView"
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- mc:Ignorable="d"
- x:DataType="viewModels:SettingsViewModel">
- <Design.DataContext>
- <viewModels:SettingsViewModel />
- </Design.DataContext>
- <ScrollViewer
- Name="LoggingPage"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- HorizontalScrollBarVisibility="Disabled"
- VerticalScrollBarVisibility="Auto">
- <Border Classes="settings">
- <StackPanel
- Margin="10"
- HorizontalAlignment="Stretch"
- Orientation="Vertical"
- Spacing="10">
- <TextBlock Classes="h1" Text="{locale:Locale SettingsTabLoggingLogging}" />
- <StackPanel Margin="10,0,0,0" Orientation="Vertical">
- <CheckBox IsChecked="{Binding EnableFileLog}"
- ToolTip.Tip="{locale:Locale FileLogTooltip}">
- <TextBlock Text="{locale:Locale SettingsTabLoggingEnableLoggingToFile}" />
- </CheckBox>
- <CheckBox IsChecked="{Binding EnableStub}"
- ToolTip.Tip="{locale:Locale StubLogTooltip}">
- <TextBlock Text="{locale:Locale SettingsTabLoggingEnableStubLogs}" />
- </CheckBox>
- <CheckBox IsChecked="{Binding EnableInfo}"
- ToolTip.Tip="{locale:Locale InfoLogTooltip}">
- <TextBlock Text="{locale:Locale SettingsTabLoggingEnableInfoLogs}" />
- </CheckBox>
- <CheckBox IsChecked="{Binding EnableWarn}"
- ToolTip.Tip="{locale:Locale WarnLogTooltip}">
- <TextBlock Text="{locale:Locale SettingsTabLoggingEnableWarningLogs}" />
- </CheckBox>
- <CheckBox IsChecked="{Binding EnableError}"
- ToolTip.Tip="{locale:Locale ErrorLogTooltip}">
- <TextBlock Text="{locale:Locale SettingsTabLoggingEnableErrorLogs}" />
- </CheckBox>
- <CheckBox IsChecked="{Binding EnableGuest}"
- ToolTip.Tip="{locale:Locale GuestLogTooltip}">
- <TextBlock Text="{locale:Locale SettingsTabLoggingEnableGuestLogs}" />
- </CheckBox>
- </StackPanel>
- <Separator Height="1" />
- <StackPanel Orientation="Vertical" Spacing="2">
- <TextBlock Classes="h1" Text="{locale:Locale SettingsTabLoggingDeveloperOptions}" />
- <TextBlock Foreground="{DynamicResource SecondaryTextColor}" Text="{locale:Locale SettingsTabLoggingDeveloperOptionsNote}" />
- </StackPanel>
- <StackPanel
- Margin="10,0,0,0"
- HorizontalAlignment="Stretch"
- Orientation="Vertical"
- Spacing="10">
- <StackPanel Orientation="Vertical">
- <CheckBox IsChecked="{Binding EnableTrace}"
- ToolTip.Tip="{locale:Locale TraceLogTooltip}">
- <TextBlock Text="{locale:Locale SettingsTabLoggingEnableTraceLogs}" />
- </CheckBox>
- <CheckBox IsChecked="{Binding EnableFsAccessLog}"
- ToolTip.Tip="{locale:Locale FileAccessLogTooltip}">
- <TextBlock Text="{locale:Locale SettingsTabLoggingEnableFsAccessLogs}" />
- </CheckBox>
- <CheckBox IsChecked="{Binding EnableDebug}"
- ToolTip.Tip="{locale:Locale DebugLogTooltip}">
- <TextBlock Text="{locale:Locale SettingsTabLoggingEnableDebugLogs}" />
- </CheckBox>
- <StackPanel Margin="0,10,0,0" Orientation="Horizontal" VerticalAlignment="Stretch">
- <TextBlock VerticalAlignment="Center"
- ToolTip.Tip="{locale:Locale FSAccessLogModeTooltip}"
- Text="{locale:Locale SettingsTabLoggingFsGlobalAccessLogMode}"
- Width="285" />
- <ui:NumberBox
- Maximum="3"
- Minimum="0"
- Width="150"
- SpinButtonPlacementMode="Inline"
- SmallChange="1"
- LargeChange="1"
- Value="{Binding FsGlobalAccessLogMode}" />
- </StackPanel>
- <StackPanel Margin="0,10,0,0" Orientation="Horizontal">
- <TextBlock VerticalAlignment="Center"
- Text="{locale:Locale SettingsTabLoggingGraphicsBackendLogLevel}"
- ToolTip.Tip="{locale:Locale OpenGlLogLevel}"
- Width="285" />
- <ComboBox SelectedIndex="{Binding OpenglDebugLevel}"
- Width="150"
- HorizontalContentAlignment="Left"
- ToolTip.Tip="{locale:Locale OpenGlLogLevel}">
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabLoggingGraphicsBackendLogLevelNone}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabLoggingGraphicsBackendLogLevelError}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock
- Text="{locale:Locale SettingsTabLoggingGraphicsBackendLogLevelPerformance}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabLoggingGraphicsBackendLogLevelAll}" />
- </ComboBoxItem>
- </ComboBox>
- </StackPanel>
- </StackPanel>
- </StackPanel>
- </StackPanel>
- </Border>
- </ScrollViewer>
-</UserControl> \ No newline at end of file
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsLoggingView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Settings/SettingsLoggingView.axaml.cs
deleted file mode 100644
index c8df46b3..00000000
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsLoggingView.axaml.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using Avalonia.Controls;
-
-namespace Ryujinx.Ava.UI.Views.Settings
-{
- public partial class SettingsLoggingView : UserControl
- {
- public SettingsLoggingView()
- {
- InitializeComponent();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsNetworkView.axaml b/src/Ryujinx.Ava/UI/Views/Settings/SettingsNetworkView.axaml
deleted file mode 100644
index 9bb81463..00000000
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsNetworkView.axaml
+++ /dev/null
@@ -1,58 +0,0 @@
-<UserControl
- x:Class="Ryujinx.Ava.UI.Views.Settings.SettingsNetworkView"
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- mc:Ignorable="d"
- x:DataType="viewModels:SettingsViewModel">
- <Design.DataContext>
- <viewModels:SettingsViewModel />
- </Design.DataContext>
- <ScrollViewer
- Name="NetworkPage"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- HorizontalScrollBarVisibility="Disabled"
- VerticalScrollBarVisibility="Auto">
- <Border Classes="settings">
- <StackPanel
- Margin="10"
- HorizontalAlignment="Stretch"
- Orientation="Vertical"
- Spacing="10">
- <TextBlock Classes="h1" Text="{locale:Locale SettingsTabNetworkMultiplayer}" />
- <StackPanel Margin="10,0,0,0" Orientation="Horizontal">
- <TextBlock VerticalAlignment="Center"
- Text="{locale:Locale MultiplayerMode}"
- ToolTip.Tip="{locale:Locale MultiplayerModeTooltip}"
- Width="200" />
- <ComboBox SelectedIndex="{Binding MultiplayerModeIndex}"
- ToolTip.Tip="{locale:Locale MultiplayerModeTooltip}"
- HorizontalContentAlignment="Left"
- ItemsSource="{Binding MultiplayerModes}"
- Width="250" />
- </StackPanel>
- <Separator Height="1" />
- <TextBlock Classes="h1" Text="{locale:Locale SettingsTabNetworkConnection}" />
- <CheckBox Margin="10,0,0,0" IsChecked="{Binding EnableInternetAccess}">
- <TextBlock Text="{locale:Locale SettingsTabSystemEnableInternetAccess}"
- ToolTip.Tip="{locale:Locale EnableInternetAccessTooltip}" />
- </CheckBox>
- <StackPanel Margin="10,0,0,0" Orientation="Horizontal">
- <TextBlock VerticalAlignment="Center"
- Text="{locale:Locale SettingsTabNetworkInterface}"
- ToolTip.Tip="{locale:Locale NetworkInterfaceTooltip}"
- Width="200" />
- <ComboBox SelectedIndex="{Binding NetworkInterfaceIndex}"
- ToolTip.Tip="{locale:Locale NetworkInterfaceTooltip}"
- HorizontalContentAlignment="Left"
- ItemsSource="{Binding NetworkInterfaceList}"
- Width="250" />
- </StackPanel>
- </StackPanel>
- </Border>
- </ScrollViewer>
-</UserControl>
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsNetworkView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Settings/SettingsNetworkView.axaml.cs
deleted file mode 100644
index b771933e..00000000
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsNetworkView.axaml.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using Avalonia.Controls;
-
-namespace Ryujinx.Ava.UI.Views.Settings
-{
- public partial class SettingsNetworkView : UserControl
- {
- public SettingsNetworkView()
- {
- InitializeComponent();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsSystemView.axaml b/src/Ryujinx.Ava/UI/Views/Settings/SettingsSystemView.axaml
deleted file mode 100644
index e6f7c6e4..00000000
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsSystemView.axaml
+++ /dev/null
@@ -1,224 +0,0 @@
-<UserControl
- x:Class="Ryujinx.Ava.UI.Views.Settings.SettingsSystemView"
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
- mc:Ignorable="d"
- x:DataType="viewModels:SettingsViewModel">
- <UserControl.Resources>
- <helpers:TimeZoneConverter x:Key="TimeZone" />
- </UserControl.Resources>
- <Design.DataContext>
- <viewModels:SettingsViewModel />
- </Design.DataContext>
- <ScrollViewer
- Name="SystemPage"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- HorizontalScrollBarVisibility="Disabled"
- VerticalScrollBarVisibility="Auto">
- <Border Classes="settings">
- <StackPanel
- Margin="10"
- HorizontalAlignment="Stretch"
- Orientation="Vertical"
- Spacing="10">
- <TextBlock
- Classes="h1"
- Text="{locale:Locale SettingsTabSystemCore}" />
- <StackPanel
- Margin="10,0,0,0"
- Orientation="Vertical">
- <StackPanel
- Margin="0,0,0,10"
- Orientation="Horizontal">
- <TextBlock
- VerticalAlignment="Center"
- Text="{locale:Locale SettingsTabSystemSystemRegion}"
- Width="250" />
- <ComboBox
- SelectedIndex="{Binding Region}"
- ToolTip.Tip="{locale:Locale RegionTooltip}"
- HorizontalContentAlignment="Left"
- Width="350">
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemSystemRegionJapan}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemSystemRegionUSA}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemSystemRegionEurope}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemSystemRegionAustralia}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemSystemRegionChina}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemSystemRegionKorea}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemSystemRegionTaiwan}" />
- </ComboBoxItem>
- </ComboBox>
- </StackPanel>
- <StackPanel
- Margin="0,0,0,10"
- Orientation="Horizontal">
- <TextBlock
- VerticalAlignment="Center"
- Text="{locale:Locale SettingsTabSystemSystemLanguage}"
- ToolTip.Tip="{locale:Locale LanguageTooltip}"
- Width="250" />
- <ComboBox
- SelectedIndex="{Binding Language}"
- ToolTip.Tip="{locale:Locale LanguageTooltip}"
- HorizontalContentAlignment="Left"
- Width="350">
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageJapanese}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageAmericanEnglish}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageFrench}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageGerman}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageItalian}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageSpanish}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageChinese}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageKorean}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageDutch}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguagePortuguese}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageRussian}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageTaiwanese}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageBritishEnglish}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageCanadianFrench}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageLatinAmericanSpanish}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageSimplifiedChinese}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageTraditionalChinese}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageBrazilianPortuguese}" />
- </ComboBoxItem>
- </ComboBox>
- </StackPanel>
- <StackPanel
- Margin="0,0,0,10"
- Orientation="Horizontal">
- <TextBlock
- VerticalAlignment="Center"
- Text="{locale:Locale SettingsTabSystemSystemTimeZone}"
- ToolTip.Tip="{locale:Locale TimezoneTooltip}"
- Width="250" />
- <AutoCompleteBox
- Name="TimeZoneBox"
- Width="350"
- MaxDropDownHeight="500"
- FilterMode="Contains"
- ItemsSource="{Binding TimeZones}"
- SelectionChanged="TimeZoneBox_OnSelectionChanged"
- Text="{Binding Path=TimeZone, Mode=OneWay}"
- TextChanged="TimeZoneBox_OnTextChanged"
- ToolTip.Tip="{locale:Locale TimezoneTooltip}"
- ValueMemberBinding="{Binding Mode=OneWay, Converter={StaticResource TimeZone}}" />
- </StackPanel>
- <StackPanel
- Margin="0,0,0,10"
- Orientation="Horizontal">
- <TextBlock
- VerticalAlignment="Center"
- Text="{locale:Locale SettingsTabSystemSystemTime}"
- ToolTip.Tip="{locale:Locale TimeTooltip}"
- Width="250"/>
- <DatePicker
- VerticalAlignment="Center"
- SelectedDate="{Binding CurrentDate}"
- ToolTip.Tip="{locale:Locale TimeTooltip}"
- Width="350" />
- </StackPanel>
- <StackPanel
- Margin="250,0,0,10"
- Orientation="Horizontal">
- <TimePicker
- VerticalAlignment="Center"
- ClockIdentifier="24HourClock"
- SelectedTime="{Binding CurrentTime}"
- Width="350"
- ToolTip.Tip="{locale:Locale TimeTooltip}" />
- </StackPanel>
- <CheckBox IsChecked="{Binding EnableVsync}">
- <TextBlock
- Text="{locale:Locale SettingsTabSystemEnableVsync}"
- ToolTip.Tip="{locale:Locale VSyncToggleTooltip}" />
- </CheckBox>
- <CheckBox IsChecked="{Binding EnableFsIntegrityChecks}">
- <TextBlock
- Text="{locale:Locale SettingsTabSystemEnableFsIntegrityChecks}"
- ToolTip.Tip="{locale:Locale FsIntegrityToggleTooltip}" />
- </CheckBox>
- </StackPanel>
- <Separator Height="1" />
- <StackPanel
- Orientation="Vertical"
- Spacing="2">
- <TextBlock
- Classes="h1"
- Text="{locale:Locale SettingsTabSystemHacks}" />
- <TextBlock
- Foreground="{DynamicResource SecondaryTextColor}"
- Text="{locale:Locale SettingsTabSystemHacksNote}" />
- </StackPanel>
- <StackPanel
- Margin="10,0,0,0"
- HorizontalAlignment="Stretch"
- Orientation="Vertical">
- <CheckBox
- IsChecked="{Binding ExpandDramSize}"
- ToolTip.Tip="{locale:Locale DRamTooltip}">
- <TextBlock Text="{locale:Locale SettingsTabSystemExpandDramSize}" />
- </CheckBox>
- <CheckBox
- IsChecked="{Binding IgnoreMissingServices}"
- ToolTip.Tip="{locale:Locale IgnoreMissingServicesTooltip}">
- <TextBlock Text="{locale:Locale SettingsTabSystemIgnoreMissingServices}" />
- </CheckBox>
- </StackPanel>
- </StackPanel>
- </Border>
- </ScrollViewer>
-</UserControl> \ No newline at end of file
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsSystemView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Settings/SettingsSystemView.axaml.cs
deleted file mode 100644
index 2c9eac28..00000000
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsSystemView.axaml.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using Avalonia.Controls;
-using Ryujinx.Ava.UI.ViewModels;
-using TimeZone = Ryujinx.Ava.UI.Models.TimeZone;
-
-namespace Ryujinx.Ava.UI.Views.Settings
-{
- public partial class SettingsSystemView : UserControl
- {
- public SettingsViewModel ViewModel;
-
- public SettingsSystemView()
- {
- InitializeComponent();
- }
-
- private void TimeZoneBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
- {
- if (e.AddedItems != null && e.AddedItems.Count > 0)
- {
- if (e.AddedItems[0] is TimeZone timeZone)
- {
- e.Handled = true;
-
- ViewModel.ValidateAndSetTimeZone(timeZone.Location);
- }
- }
- }
-
- private void TimeZoneBox_OnTextChanged(object sender, TextChangedEventArgs e)
- {
- if (sender is AutoCompleteBox box && box.SelectedItem is TimeZone timeZone)
- {
- ViewModel.ValidateAndSetTimeZone(timeZone.Location);
- }
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml b/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml
deleted file mode 100644
index 6504637e..00000000
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml
+++ /dev/null
@@ -1,128 +0,0 @@
-<UserControl
- x:Class="Ryujinx.Ava.UI.Views.Settings.SettingsUiView"
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- mc:Ignorable="d"
- x:DataType="viewModels:SettingsViewModel">
- <Design.DataContext>
- <viewModels:SettingsViewModel />
- </Design.DataContext>
- <ScrollViewer
- Name="UiPage"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- HorizontalScrollBarVisibility="Disabled"
- VerticalScrollBarVisibility="Auto">
- <Border Classes="settings">
- <StackPanel
- Margin="10"
- HorizontalAlignment="Stretch"
- Orientation="Vertical"
- Spacing="10">
- <TextBlock Classes="h1" Text="{locale:Locale SettingsTabGeneralGeneral}" />
- <StackPanel Margin="10,0,0,0" Orientation="Vertical">
- <CheckBox IsChecked="{Binding EnableDiscordIntegration}">
- <TextBlock VerticalAlignment="Center"
- ToolTip.Tip="{locale:Locale ToggleDiscordTooltip}"
- Text="{locale:Locale SettingsTabGeneralEnableDiscordRichPresence}" />
- </CheckBox>
- <CheckBox IsChecked="{Binding CheckUpdatesOnStart}">
- <TextBlock Text="{locale:Locale SettingsTabGeneralCheckUpdatesOnLaunch}" />
- </CheckBox>
- <CheckBox IsChecked="{Binding ShowConfirmExit}">
- <TextBlock Text="{locale:Locale SettingsTabGeneralShowConfirmExitDialog}" />
- </CheckBox>
- <StackPanel Margin="0, 15, 0, 0" Orientation="Horizontal">
- <TextBlock VerticalAlignment="Center"
- Text="{locale:Locale SettingsTabGeneralHideCursor}"
- Width="150" />
- <ComboBox SelectedIndex="{Binding HideCursor}"
- HorizontalContentAlignment="Left"
- MinWidth="100">
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabGeneralHideCursorNever}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabGeneralHideCursorOnIdle}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabGeneralHideCursorAlways}" />
- </ComboBoxItem>
- </ComboBox>
- </StackPanel>
- <StackPanel Margin="0, 15, 0, 10" Orientation="Horizontal">
- <TextBlock
- VerticalAlignment="Center"
- Text="{locale:Locale SettingsTabGeneralTheme}"
- Width="150" />
- <ComboBox SelectedIndex="{Binding BaseStyleIndex}"
- HorizontalContentAlignment="Left"
- MinWidth="100">
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabGeneralThemeLight}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <TextBlock Text="{locale:Locale SettingsTabGeneralThemeDark}" />
- </ComboBoxItem>
- </ComboBox>
- </StackPanel>
- </StackPanel>
- <Separator Height="1" />
- <TextBlock Classes="h1" Text="{locale:Locale SettingsTabGeneralGameDirectories}" />
- <StackPanel
- Margin="10,0,0,0"
- HorizontalAlignment="Stretch"
- Orientation="Vertical"
- Spacing="10">
- <ListBox
- Name="GameList"
- MinHeight="230"
- ItemsSource="{Binding GameDirectories}">
- <ListBox.Styles>
- <Style Selector="ListBoxItem">
- <Setter Property="Padding" Value="10" />
- <Setter Property="Background" Value="{DynamicResource ListBoxBackground}" />
- </Style>
- </ListBox.Styles>
- </ListBox>
- <Grid HorizontalAlignment="Stretch">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="*" />
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="Auto" />
- </Grid.ColumnDefinitions>
- <TextBox
- Name="PathBox"
- Margin="0"
- ToolTip.Tip="{locale:Locale AddGameDirBoxTooltip}"
- VerticalAlignment="Stretch" />
- <Button
- Name="AddButton"
- Grid.Column="1"
- MinWidth="90"
- Margin="10,0,0,0"
- ToolTip.Tip="{locale:Locale AddGameDirTooltip}"
- Click="AddButton_OnClick">
- <TextBlock HorizontalAlignment="Center"
- Text="{locale:Locale SettingsTabGeneralAdd}" />
- </Button>
- <Button
- Name="RemoveButton"
- Grid.Column="2"
- MinWidth="90"
- Margin="10,0,0,0"
- ToolTip.Tip="{locale:Locale RemoveGameDirTooltip}"
- Click="RemoveButton_OnClick">
- <TextBlock HorizontalAlignment="Center"
- Text="{locale:Locale SettingsTabGeneralRemove}" />
- </Button>
- </Grid>
- </StackPanel>
- </StackPanel>
- </Border>
- </ScrollViewer>
-</UserControl>
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml.cs
deleted file mode 100644
index 996d15cd..00000000
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Interactivity;
-using Avalonia.Platform.Storage;
-using Avalonia.VisualTree;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.ViewModels;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-
-namespace Ryujinx.Ava.UI.Views.Settings
-{
- public partial class SettingsUiView : UserControl
- {
- public SettingsViewModel ViewModel;
-
- public SettingsUiView()
- {
- InitializeComponent();
- }
-
- private async void AddButton_OnClick(object sender, RoutedEventArgs e)
- {
- string path = PathBox.Text;
-
- if (!string.IsNullOrWhiteSpace(path) && Directory.Exists(path) && !ViewModel.GameDirectories.Contains(path))
- {
- ViewModel.GameDirectories.Add(path);
- ViewModel.DirectoryChanged = true;
- }
- else
- {
- if (this.GetVisualRoot() is Window window)
- {
- var result = await window.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
- {
- AllowMultiple = false,
- });
-
- if (result.Count > 0)
- {
- ViewModel.GameDirectories.Add(result[0].Path.LocalPath);
- ViewModel.DirectoryChanged = true;
- }
- }
- }
- }
-
- private void RemoveButton_OnClick(object sender, RoutedEventArgs e)
- {
- int oldIndex = GameList.SelectedIndex;
-
- foreach (string path in new List<string>(GameList.SelectedItems.Cast<string>()))
- {
- ViewModel.GameDirectories.Remove(path);
- ViewModel.DirectoryChanged = true;
- }
-
- if (GameList.ItemCount > 0)
- {
- GameList.SelectedIndex = oldIndex < GameList.ItemCount ? oldIndex : 0;
- }
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserEditorView.axaml b/src/Ryujinx.Ava/UI/Views/User/UserEditorView.axaml
deleted file mode 100644
index ab83c2cd..00000000
--- a/src/Ryujinx.Ava/UI/Views/User/UserEditorView.axaml
+++ /dev/null
@@ -1,122 +0,0 @@
-<UserControl
- x:Class="Ryujinx.Ava.UI.Views.User.UserEditorView"
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
- xmlns:models="clr-namespace:Ryujinx.Ava.UI.Models"
- Margin="0"
- MinWidth="500"
- Padding="0"
- mc:Ignorable="d"
- Focusable="True"
- x:DataType="models:TempProfile">
- <UserControl.Resources>
- <helpers:BitmapArrayValueConverter x:Key="ByteImage" />
- </UserControl.Resources>
- <Grid Margin="0">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition />
- </Grid.ColumnDefinitions>
- <Grid.RowDefinitions>
- <RowDefinition Height="*" />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <StackPanel
- Grid.Row="0"
- Grid.Column="0"
- HorizontalAlignment="Stretch"
- Orientation="Vertical"
- Spacing="10">
- <TextBlock Text="{locale:Locale UserProfilesName}" />
- <TextBox
- Name="NameBox"
- Width="300"
- HorizontalAlignment="Stretch"
- MaxLength="{Binding MaxProfileNameLength}"
- Watermark="{locale:Locale ProfileNameSelectionWatermark}"
- Text="{Binding Name}" />
- <TextBlock Name="IdText" Text="{locale:Locale UserProfilesUserId}" />
- <TextBox
- Name="IdLabel"
- Width="300"
- HorizontalAlignment="Stretch"
- IsReadOnly="True"
- Text="{Binding UserIdString}" />
- </StackPanel>
- <StackPanel
- Grid.Row="0"
- Grid.Column="1"
- HorizontalAlignment="Right"
- VerticalAlignment="Stretch"
- Orientation="Vertical">
- <Border
- BorderBrush="{DynamicResource AppListHoverBackgroundColor}"
- BorderThickness="1">
- <Panel>
- <ui:SymbolIcon
- FontSize="60"
- Width="96"
- Height="96"
- Margin="0"
- Foreground="{DynamicResource AppListHoverBackgroundColor}"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Top"
- Symbol="Camera" />
- <Image
- Name="ProfileImage"
- Width="96"
- Height="96"
- Margin="0"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Top"
- Source="{Binding Image, Converter={StaticResource ByteImage}}" />
- </Panel>
- </Border>
- </StackPanel>
- <StackPanel
- Grid.Row="1"
- Grid.Column="0"
- Grid.ColumnSpan="2"
- HorizontalAlignment="Left"
- Orientation="Horizontal"
- Margin="0 24 0 0"
- Spacing="10">
- <Button
- Width="50"
- MinWidth="50"
- Click="BackButton_Click">
- <ui:SymbolIcon Symbol="Back" />
- </Button>
- </StackPanel>
- <StackPanel
- Grid.Row="1"
- Grid.Column="0"
- Grid.ColumnSpan="2"
- HorizontalAlignment="Right"
- Orientation="Horizontal"
- Margin="0 24 0 0"
- Spacing="10">
- <Button
- Name="DeleteButton"
- Click="DeleteButton_Click"
- Content="{locale:Locale UserProfilesDelete}" />
- <Button
- Name="ChangePictureButton"
- Click="ChangePictureButton_Click"
- Content="{locale:Locale UserProfilesChangeProfileImage}" />
- <Button
- Name="AddPictureButton"
- Click="ChangePictureButton_Click"
- Content="{locale:Locale UserProfilesSetProfileImage}" />
- <Button
- Name="SaveButton"
- Click="SaveButton_Click"
- Content="{locale:Locale Save}" />
- </StackPanel>
- </Grid>
-</UserControl> \ No newline at end of file
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserEditorView.axaml.cs b/src/Ryujinx.Ava/UI/Views/User/UserEditorView.axaml.cs
deleted file mode 100644
index 588fa471..00000000
--- a/src/Ryujinx.Ava/UI/Views/User/UserEditorView.axaml.cs
+++ /dev/null
@@ -1,165 +0,0 @@
-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.Controls;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.Models;
-using Ryujinx.HLE.HOS.Services.Account.Acc;
-using System;
-using UserProfile = Ryujinx.Ava.UI.Models.UserProfile;
-
-namespace Ryujinx.Ava.UI.Views.User
-{
- public partial class UserEditorView : UserControl
- {
- private NavigationDialogHost _parent;
- private UserProfile _profile;
- private bool _isNewUser;
-
- public TempProfile TempProfile { get; set; }
- public static uint MaxProfileNameLength => 0x20;
- public bool IsDeletable => _profile.UserId != AccountManager.DefaultUserId;
-
- public UserEditorView()
- {
- 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 (parent, profile, isNewUser) = ((NavigationDialogHost parent, UserProfile profile, bool isNewUser))arg.Parameter;
- _isNewUser = isNewUser;
- _profile = profile;
- TempProfile = new TempProfile(_profile);
-
- _parent = parent;
- break;
- }
-
- ((ContentDialog)_parent.Parent).Title = $"{LocaleManager.Instance[LocaleKeys.UserProfileWindowTitle]} - " +
- $"{(_isNewUser ? LocaleManager.Instance[LocaleKeys.UserEditorTitleCreate] : LocaleManager.Instance[LocaleKeys.UserEditorTitle])}";
-
- DataContext = TempProfile;
-
- AddPictureButton.IsVisible = _isNewUser;
- ChangePictureButton.IsVisible = !_isNewUser;
- IdLabel.IsVisible = _profile != null;
- IdText.IsVisible = _profile != null;
- if (!_isNewUser && IsDeletable)
- {
- DeleteButton.IsVisible = true;
- }
- else
- {
- DeleteButton.IsVisible = false;
- }
- }
- }
-
- private async void BackButton_Click(object sender, RoutedEventArgs e)
- {
- if (_isNewUser)
- {
- if (TempProfile.Name != String.Empty || TempProfile.Image != null)
- {
- if (await ContentDialogHelper.CreateChoiceDialog(
- LocaleManager.Instance[LocaleKeys.DialogUserProfileUnsavedChangesTitle],
- LocaleManager.Instance[LocaleKeys.DialogUserProfileUnsavedChangesMessage],
- LocaleManager.Instance[LocaleKeys.DialogUserProfileUnsavedChangesSubMessage]))
- {
- _parent?.GoBack();
- }
- }
- else
- {
- _parent?.GoBack();
- }
- }
- else
- {
- if (_profile.Name != TempProfile.Name || _profile.Image != TempProfile.Image)
- {
- if (await ContentDialogHelper.CreateChoiceDialog(
- LocaleManager.Instance[LocaleKeys.DialogUserProfileUnsavedChangesTitle],
- LocaleManager.Instance[LocaleKeys.DialogUserProfileUnsavedChangesMessage],
- LocaleManager.Instance[LocaleKeys.DialogUserProfileUnsavedChangesSubMessage]))
- {
- _parent?.GoBack();
- }
- }
- else
- {
- _parent?.GoBack();
- }
- }
- }
-
- private void DeleteButton_Click(object sender, RoutedEventArgs e)
- {
- _parent.DeleteUser(_profile);
- }
-
- private void SaveButton_Click(object sender, RoutedEventArgs e)
- {
- DataValidationErrors.ClearErrors(NameBox);
-
- if (string.IsNullOrWhiteSpace(TempProfile.Name))
- {
- DataValidationErrors.SetError(NameBox, new DataValidationException(LocaleManager.Instance[LocaleKeys.UserProfileEmptyNameError]));
-
- return;
- }
-
- if (TempProfile.Image == null)
- {
- _parent.Navigate(typeof(UserProfileImageSelectorView), (_parent, TempProfile));
-
- return;
- }
-
- if (_profile != null && !_isNewUser)
- {
- _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, TempProfile.UserId);
- }
- else
- {
- return;
- }
-
- _parent?.GoBack();
- }
-
- public void SelectProfileImage()
- {
- _parent.Navigate(typeof(UserProfileImageSelectorView), (_parent, TempProfile));
- }
-
- private void ChangePictureButton_Click(object sender, RoutedEventArgs e)
- {
- if (_profile != null || _isNewUser)
- {
- SelectProfileImage();
- }
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserFirmwareAvatarSelectorView.axaml b/src/Ryujinx.Ava/UI/Views/User/UserFirmwareAvatarSelectorView.axaml
deleted file mode 100644
index 21dfc909..00000000
--- a/src/Ryujinx.Ava/UI/Views/User/UserFirmwareAvatarSelectorView.axaml
+++ /dev/null
@@ -1,113 +0,0 @@
-<UserControl
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- mc:Ignorable="d"
- Width="528"
- d:DesignWidth="578"
- d:DesignHeight="350"
- x:Class="Ryujinx.Ava.UI.Views.User.UserFirmwareAvatarSelectorView"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
- x:DataType="viewModels:UserFirmwareAvatarSelectorViewModel"
- Focusable="True">
- <Design.DataContext>
- <viewModels:UserFirmwareAvatarSelectorViewModel />
- </Design.DataContext>
- <UserControl.Resources>
- <helpers:BitmapArrayValueConverter x:Key="ByteImage" />
- </UserControl.Resources>
- <Grid
- Margin="0"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="*" />
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <ListBox
- Grid.Row="1"
- BorderThickness="0"
- SelectedIndex="{Binding SelectedIndex}"
- Height="400"
- ItemsSource="{Binding Images}"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Center">
- <ListBox.ItemsPanel>
- <ItemsPanelTemplate>
- <WrapPanel
- Orientation="Horizontal"
- Margin="0"
- HorizontalAlignment="Center" />
- </ItemsPanelTemplate>
- </ListBox.ItemsPanel>
- <ListBox.Styles>
- <Style Selector="ListBoxItem">
- <Setter Property="CornerRadius" Value="4" />
- <Setter Property="Width" Value="85" />
- <Setter Property="MaxWidth" Value="85" />
- <Setter Property="MinWidth" Value="85" />
- </Style>
- <Style Selector="ListBoxItem /template/ Rectangle#SelectionIndicator">
- <Setter Property="MinHeight" Value="70" />
- </Style>
- </ListBox.Styles>
- <ListBox.ItemTemplate>
- <DataTemplate>
- <Panel
- Background="{Binding BackgroundColor}"
- Margin="5">
- <Image Source="{Binding Data, Converter={StaticResource ByteImage}}" />
- </Panel>
- </DataTemplate>
- </ListBox.ItemTemplate>
- </ListBox>
- <StackPanel
- Grid.Row="3"
- Orientation="Horizontal"
- Spacing="10"
- Margin="0 24 0 0"
- HorizontalAlignment="Left">
- <Button
- Width="50"
- MinWidth="50"
- Height="35"
- Click="GoBack">
- <ui:SymbolIcon Symbol="Back" />
- </Button>
- </StackPanel>
- <StackPanel
- Grid.Row="3"
- Orientation="Horizontal"
- Spacing="10"
- Margin="0 24 0 0"
- HorizontalAlignment="Right">
- <ui:ColorPickerButton
- FlyoutPlacement="Top"
- IsMoreButtonVisible="False"
- UseColorPalette="False"
- UseColorTriangle="False"
- UseColorWheel="False"
- ShowAcceptDismissButtons="False"
- IsAlphaEnabled="False"
- Color="{Binding BackgroundColor, Mode=TwoWay}"
- Name="ColorButton">
- <ui:ColorPickerButton.Styles>
- <Style Selector="Grid#Root > DockPanel > Grid">
- <Setter Property="IsVisible" Value="False" />
- </Style>
- </ui:ColorPickerButton.Styles>
- </ui:ColorPickerButton>
- <Button
- Content="{locale:Locale AvatarChoose}"
- Height="35"
- Name="ChooseButton"
- Click="ChooseButton_OnClick" />
- </StackPanel>
- </Grid>
-</UserControl> \ No newline at end of file
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserFirmwareAvatarSelectorView.axaml.cs b/src/Ryujinx.Ava/UI/Views/User/UserFirmwareAvatarSelectorView.axaml.cs
deleted file mode 100644
index b6376866..00000000
--- a/src/Ryujinx.Ava/UI/Views/User/UserFirmwareAvatarSelectorView.axaml.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Interactivity;
-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 SixLabors.ImageSharp;
-using SixLabors.ImageSharp.Formats.Png;
-using SixLabors.ImageSharp.PixelFormats;
-using SixLabors.ImageSharp.Processing;
-using System.IO;
-using Image = SixLabors.ImageSharp.Image;
-
-namespace Ryujinx.Ava.UI.Views.User
-{
- public partial class UserFirmwareAvatarSelectorView : UserControl
- {
- private NavigationDialogHost _parent;
- private TempProfile _profile;
-
- public UserFirmwareAvatarSelectorView(ContentManager contentManager)
- {
- ContentManager = contentManager;
-
- DataContext = ViewModel;
-
- InitializeComponent();
- }
-
- public UserFirmwareAvatarSelectorView()
- {
- InitializeComponent();
-
- AddHandler(Frame.NavigatedToEvent, (s, e) =>
- {
- NavigatedTo(e);
- }, RoutingStrategies.Direct);
- }
-
- private void NavigatedTo(NavigationEventArgs arg)
- {
- if (Program.PreviewerDetached)
- {
- if (arg.NavigationMode == NavigationMode.New)
- {
- (_parent, _profile) = ((NavigationDialogHost, TempProfile))arg.Parameter;
- ContentManager = _parent.ContentManager;
- if (Program.PreviewerDetached)
- {
- ViewModel = new UserFirmwareAvatarSelectorViewModel();
- }
-
- DataContext = ViewModel;
- }
- }
- }
-
- public ContentManager ContentManager { get; private set; }
-
- internal UserFirmwareAvatarSelectorViewModel ViewModel { get; set; }
-
- private void GoBack(object sender, RoutedEventArgs e)
- {
- _parent.GoBack();
- }
-
- private void ChooseButton_OnClick(object sender, RoutedEventArgs e)
- {
- if (ViewModel.SelectedImage != null)
- {
- MemoryStream streamJpg = new();
- Image avatarImage = Image.Load(ViewModel.SelectedImage, new PngDecoder());
-
- avatarImage.Mutate(x => x.BackgroundColor(new Rgba32(
- ViewModel.BackgroundColor.R,
- ViewModel.BackgroundColor.G,
- ViewModel.BackgroundColor.B,
- ViewModel.BackgroundColor.A)));
- avatarImage.SaveAsJpeg(streamJpg);
-
- _profile.Image = streamJpg.ToArray();
-
- _parent.GoBack();
- }
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserProfileImageSelectorView.axaml b/src/Ryujinx.Ava/UI/Views/User/UserProfileImageSelectorView.axaml
deleted file mode 100644
index b1786430..00000000
--- a/src/Ryujinx.Ava/UI/Views/User/UserProfileImageSelectorView.axaml
+++ /dev/null
@@ -1,62 +0,0 @@
-<UserControl
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:viewModles="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- Focusable="True"
- mc:Ignorable="d"
- x:Class="Ryujinx.Ava.UI.Views.User.UserProfileImageSelectorView"
- x:DataType="viewModles:UserProfileImageSelectorViewModel"
- Width="500"
- d:DesignWidth="500">
- <Design.DataContext>
- <viewModles:UserProfileImageSelectorViewModel />
- </Design.DataContext>
- <Grid
- HorizontalAlignment="Stretch"
- VerticalAlignment="Center">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="70" />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <TextBlock
- Grid.Row="0"
- TextWrapping="Wrap"
- HorizontalAlignment="Left"
- TextAlignment="Start"
- Text="{locale:Locale ProfileImageSelectionNote}" />
- <StackPanel
- Grid.Row="2"
- Spacing="10"
- HorizontalAlignment="Left"
- Orientation="Horizontal">
- <Button
- Width="50"
- MinWidth="50"
- Click="GoBack">
- <ui:SymbolIcon Symbol="Back" />
- </Button>
- </StackPanel>
- <StackPanel
- Grid.Row="2"
- Spacing="10"
- HorizontalAlignment="Right"
- Orientation="Horizontal">
- <Button
- Name="Import"
- Click="Import_OnClick">
- <TextBlock Text="{locale:Locale ProfileImageSelectionImportImage}" />
- </Button>
- <Button
- Name="SelectFirmwareImage"
- IsEnabled="{Binding FirmwareFound}"
- Click="SelectFirmwareImage_OnClick">
- <TextBlock Text="{locale:Locale ProfileImageSelectionSelectAvatar}" />
- </Button>
- </StackPanel>
- </Grid>
-</UserControl>
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserProfileImageSelectorView.axaml.cs b/src/Ryujinx.Ava/UI/Views/User/UserProfileImageSelectorView.axaml.cs
deleted file mode 100644
index fabfaa4e..00000000
--- a/src/Ryujinx.Ava/UI/Views/User/UserProfileImageSelectorView.axaml.cs
+++ /dev/null
@@ -1,116 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Interactivity;
-using Avalonia.Platform.Storage;
-using Avalonia.VisualTree;
-using FluentAvalonia.UI.Controls;
-using FluentAvalonia.UI.Navigation;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Controls;
-using Ryujinx.Ava.UI.Models;
-using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.HLE.FileSystem;
-using SixLabors.ImageSharp;
-using SixLabors.ImageSharp.Processing;
-using System.Collections.Generic;
-using System.IO;
-using Image = SixLabors.ImageSharp.Image;
-
-namespace Ryujinx.Ava.UI.Views.User
-{
- public partial class UserProfileImageSelectorView : UserControl
- {
- private ContentManager _contentManager;
- private NavigationDialogHost _parent;
- private TempProfile _profile;
-
- internal UserProfileImageSelectorViewModel ViewModel { get; private set; }
-
- public UserProfileImageSelectorView()
- {
- InitializeComponent();
- AddHandler(Frame.NavigatedToEvent, (s, e) =>
- {
- NavigatedTo(e);
- }, RoutingStrategies.Direct);
- }
-
- private void NavigatedTo(NavigationEventArgs arg)
- {
- if (Program.PreviewerDetached)
- {
- switch (arg.NavigationMode)
- {
- case NavigationMode.New:
- (_parent, _profile) = ((NavigationDialogHost, TempProfile))arg.Parameter;
- _contentManager = _parent.ContentManager;
-
- ((ContentDialog)_parent.Parent).Title = $"{LocaleManager.Instance[LocaleKeys.UserProfileWindowTitle]} - {LocaleManager.Instance[LocaleKeys.ProfileImageSelectionHeader]}";
-
- if (Program.PreviewerDetached)
- {
- DataContext = ViewModel = new UserProfileImageSelectorViewModel();
- ViewModel.FirmwareFound = _contentManager.GetCurrentFirmwareVersion() != null;
- }
-
- break;
- case NavigationMode.Back:
- if (_profile.Image != null)
- {
- _parent.GoBack();
- }
- break;
- }
- }
- }
-
- private async void Import_OnClick(object sender, RoutedEventArgs e)
- {
- var window = this.GetVisualRoot() as Window;
- var result = await window.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
- {
- AllowMultiple = false,
- FileTypeFilter = new List<FilePickerFileType>
- {
- new(LocaleManager.Instance[LocaleKeys.AllSupportedFormats])
- {
- Patterns = new[] { "*.jpg", "*.jpeg", "*.png", "*.bmp" },
- AppleUniformTypeIdentifiers = new[] { "public.jpeg", "public.png", "com.microsoft.bmp" },
- MimeTypes = new[] { "image/jpeg", "image/png", "image/bmp" },
- },
- },
- });
-
- if (result.Count > 0)
- {
- _profile.Image = ProcessProfileImage(File.ReadAllBytes(result[0].Path.LocalPath));
- _parent.GoBack();
- }
- }
-
- private void GoBack(object sender, RoutedEventArgs e)
- {
- _parent.GoBack();
- }
-
- private void SelectFirmwareImage_OnClick(object sender, RoutedEventArgs e)
- {
- if (ViewModel.FirmwareFound)
- {
- _parent.Navigate(typeof(UserFirmwareAvatarSelectorView), (_parent, _profile));
- }
- }
-
- private static byte[] ProcessProfileImage(byte[] buffer)
- {
- using Image image = Image.Load(buffer);
-
- image.Mutate(x => x.Resize(256, 256));
-
- using MemoryStream streamJpg = new();
-
- image.SaveAsJpeg(streamJpg);
-
- return streamJpg.ToArray();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserRecovererView.axaml b/src/Ryujinx.Ava/UI/Views/User/UserRecovererView.axaml
deleted file mode 100644
index 3fdb4ab9..00000000
--- a/src/Ryujinx.Ava/UI/Views/User/UserRecovererView.axaml
+++ /dev/null
@@ -1,82 +0,0 @@
-<UserControl
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- mc:Ignorable="d"
- d:DesignWidth="550"
- d:DesignHeight="450"
- Width="500"
- Height="400"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- x:Class="Ryujinx.Ava.UI.Views.User.UserRecovererView"
- x:DataType="viewModels:UserProfileViewModel"
- Focusable="True">
- <Design.DataContext>
- <viewModels:UserProfileViewModel />
- </Design.DataContext>
- <Grid HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch">
- <Grid.RowDefinitions>
- <RowDefinition/>
- <RowDefinition Height="Auto"/>
- </Grid.RowDefinitions>
- <Border
- CornerRadius="5"
- BorderBrush="{DynamicResource AppListHoverBackgroundColor}"
- BorderThickness="1"
- Grid.Row="0">
- <Panel>
- <ListBox
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- ItemsSource="{Binding LostProfiles}">
- <ListBox.ItemTemplate>
- <DataTemplate>
- <Border
- Margin="2"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- ClipToBounds="True"
- CornerRadius="5">
- <Grid Margin="0">
- <Grid.ColumnDefinitions>
- <ColumnDefinition/>
- <ColumnDefinition Width="Auto"/>
- </Grid.ColumnDefinitions>
- <TextBlock
- HorizontalAlignment="Stretch"
- Text="{Binding UserId}"
- TextAlignment="Start"
- TextWrapping="Wrap" />
- <Button Grid.Column="1"
- HorizontalAlignment="Right"
- Click="Recover"
- CommandParameter="{Binding}"
- Content="{locale:Locale Recover}"/>
- </Grid>
- </Border>
- </DataTemplate>
- </ListBox.ItemTemplate>
- </ListBox>
- <TextBlock
- IsVisible="{Binding IsEmpty}"
- TextAlignment="Center"
- Text="{locale:Locale UserProfilesRecoverEmptyList}"/>
- </Panel>
- </Border>
- <StackPanel
- Grid.Row="1"
- Margin="0 24 0 0"
- Orientation="Horizontal">
- <Button
- Width="50"
- MinWidth="50"
- Click="GoBack">
- <ui:SymbolIcon Symbol="Back"/>
- </Button>
- </StackPanel>
- </Grid>
-</UserControl>
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserRecovererView.axaml.cs b/src/Ryujinx.Ava/UI/Views/User/UserRecovererView.axaml.cs
deleted file mode 100644
index 31934349..00000000
--- a/src/Ryujinx.Ava/UI/Views/User/UserRecovererView.axaml.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Interactivity;
-using FluentAvalonia.UI.Controls;
-using FluentAvalonia.UI.Navigation;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Controls;
-
-namespace Ryujinx.Ava.UI.Views.User
-{
- public partial class UserRecovererView : UserControl
- {
- private NavigationDialogHost _parent;
-
- public UserRecovererView()
- {
- 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 parent = (NavigationDialogHost)arg.Parameter;
-
- _parent = parent;
-
- ((ContentDialog)_parent.Parent).Title = $"{LocaleManager.Instance[LocaleKeys.UserProfileWindowTitle]} - {LocaleManager.Instance[LocaleKeys.UserProfilesRecoverHeading]}";
-
- break;
- }
- }
- }
-
- private void GoBack(object sender, RoutedEventArgs e)
- {
- _parent?.GoBack();
- }
-
- private void Recover(object sender, RoutedEventArgs e)
- {
- _parent?.RecoverLostAccounts();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserSaveManagerView.axaml b/src/Ryujinx.Ava/UI/Views/User/UserSaveManagerView.axaml
deleted file mode 100644
index 8bc5125a..00000000
--- a/src/Ryujinx.Ava/UI/Views/User/UserSaveManagerView.axaml
+++ /dev/null
@@ -1,213 +0,0 @@
-<UserControl
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
- xmlns:models="clr-namespace:Ryujinx.Ava.UI.Models"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- mc:Ignorable="d"
- d:DesignWidth="600"
- d:DesignHeight="500"
- Height="450"
- Width="550"
- x:Class="Ryujinx.Ava.UI.Views.User.UserSaveManagerView"
- x:DataType="viewModels:UserSaveManagerViewModel"
- Focusable="True">
- <Design.DataContext>
- <viewModels:UserSaveManagerViewModel />
- </Design.DataContext>
- <UserControl.Resources>
- <helpers:BitmapArrayValueConverter x:Key="ByteImage" />
- </UserControl.Resources>
- <Grid>
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <Grid
- Grid.Row="0"
- HorizontalAlignment="Stretch">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition />
- </Grid.ColumnDefinitions>
- <StackPanel
- Spacing="10"
- Orientation="Horizontal"
- HorizontalAlignment="Left"
- VerticalAlignment="Center">
- <Label Content="{locale:Locale CommonSort}" VerticalAlignment="Center" />
- <ComboBox SelectedIndex="{Binding SortIndex}" Width="100">
- <ComboBoxItem>
- <Label
- VerticalAlignment="Center"
- HorizontalContentAlignment="Left"
- Content="{locale:Locale Name}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <Label
- VerticalAlignment="Center"
- HorizontalContentAlignment="Left"
- Content="{locale:Locale Size}" />
- </ComboBoxItem>
- <ComboBox.Styles>
- <Style Selector="ContentControl#ContentPresenter">
- <Setter Property="HorizontalAlignment" Value="Left" />
- </Style>
- </ComboBox.Styles>
- </ComboBox>
- <ComboBox SelectedIndex="{Binding OrderIndex}" Width="150">
- <ComboBoxItem>
- <Label
- VerticalAlignment="Center"
- HorizontalContentAlignment="Left"
- Content="{locale:Locale OrderAscending}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <Label
- VerticalAlignment="Center"
- HorizontalContentAlignment="Left"
- Content="{locale:Locale OrderDescending}" />
- </ComboBoxItem>
- <ComboBox.Styles>
- <Style Selector="ContentControl#ContentPresenter">
- <Setter Property="HorizontalAlignment" Value="Left" />
- </Style>
- </ComboBox.Styles>
- </ComboBox>
- </StackPanel>
- <Grid
- Grid.Column="1"
- HorizontalAlignment="Stretch"
- Margin="10,0, 0, 0">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto"/>
- <ColumnDefinition/>
- </Grid.ColumnDefinitions>
- <Label Content="{locale:Locale Search}" VerticalAlignment="Center" />
- <TextBox
- Margin="5,0,0,0"
- Grid.Column="1"
- HorizontalAlignment="Stretch"
- Text="{Binding Search}" />
- </Grid>
- </Grid>
- <Border
- Grid.Row="1"
- Margin="0,5"
- BorderThickness="1"
- BorderBrush="{DynamicResource AppListHoverBackgroundColor}"
- CornerRadius="5"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch">
- <ListBox
- Name="SaveList"
- ItemsSource="{Binding Views}"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch">
- <ListBox.Styles>
- <Style Selector="ListBoxItem">
- <Setter Property="Padding" Value="10" />
- <Setter Property="Margin" Value="5" />
- <Setter Property="CornerRadius" Value="4" />
- </Style>
- <Style Selector="ListBoxItem:selected /template/ Rectangle#SelectionIndicator">
- <Setter Property="IsVisible" Value="False" />
- </Style>
- </ListBox.Styles>
- <ListBox.ItemTemplate>
- <DataTemplate x:DataType="models:SaveModel">
- <Grid HorizontalAlignment="Stretch">
- <Grid.ColumnDefinitions>
- <ColumnDefinition />
- <ColumnDefinition Width="Auto" />
- </Grid.ColumnDefinitions>
- <StackPanel
- Grid.Column="0"
- Orientation="Horizontal"
- Spacing="5">
- <Border
- Height="42"
- Width="42"
- Padding="10"
- BorderBrush="{DynamicResource AppListHoverBackgroundColor}"
- BorderThickness="1"
- IsVisible="{Binding !InGameList}">
- <ui:SymbolIcon
- Symbol="Help"
- FontSize="30"
- HorizontalAlignment="Center"
- VerticalAlignment="Center" />
- </Border>
- <Image
- IsVisible="{Binding InGameList}"
- Width="42"
- Height="42"
- Source="{Binding Icon, Converter={StaticResource ByteImage}}" />
- <TextBlock
- MaxLines="3"
- Width="320"
- Margin="5"
- TextWrapping="Wrap"
- Text="{Binding Title}"
- VerticalAlignment="Center" />
- </StackPanel>
- <StackPanel
- Grid.Column="1"
- Spacing="10"
- HorizontalAlignment="Right"
- Orientation="Horizontal">
- <Label
- Content="{Binding SizeString}"
- IsVisible="{Binding SizeAvailable}"
- VerticalAlignment="Center"
- HorizontalAlignment="Right" />
- <Button
- VerticalAlignment="Center"
- HorizontalAlignment="Right"
- Padding="10"
- MinWidth="0"
- MinHeight="0"
- Name="OpenLocation"
- Click="OpenLocation">
- <ui:SymbolIcon
- Symbol="OpenFolder"
- HorizontalAlignment="Center"
- VerticalAlignment="Center" />
- </Button>
- <Button
- VerticalAlignment="Center"
- HorizontalAlignment="Right"
- Padding="10"
- MinWidth="0"
- MinHeight="0"
- Name="Delete"
- Click="Delete">
- <ui:SymbolIcon
- Symbol="Delete"
- HorizontalAlignment="Center"
- VerticalAlignment="Center" />
- </Button>
- </StackPanel>
- </Grid>
- </DataTemplate>
- </ListBox.ItemTemplate>
- </ListBox>
- </Border>
- <StackPanel
- Grid.Row="2"
- Margin="0 24 0 0"
- Orientation="Horizontal">
- <Button
- Width="50"
- MinWidth="50"
- Click="GoBack">
- <ui:SymbolIcon Symbol="Back" />
- </Button>
- </StackPanel>
- </Grid>
-</UserControl> \ No newline at end of file
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserSaveManagerView.axaml.cs b/src/Ryujinx.Ava/UI/Views/User/UserSaveManagerView.axaml.cs
deleted file mode 100644
index 00a229fa..00000000
--- a/src/Ryujinx.Ava/UI/Views/User/UserSaveManagerView.axaml.cs
+++ /dev/null
@@ -1,148 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Interactivity;
-using Avalonia.Threading;
-using FluentAvalonia.UI.Controls;
-using FluentAvalonia.UI.Navigation;
-using LibHac;
-using LibHac.Common;
-using LibHac.Fs;
-using LibHac.Fs.Shim;
-using Ryujinx.Ava.Common;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Controls;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.Models;
-using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.HLE.FileSystem;
-using Ryujinx.HLE.HOS.Services.Account.Acc;
-using System;
-using System.Collections.ObjectModel;
-using System.Threading.Tasks;
-using Button = Avalonia.Controls.Button;
-using UserId = LibHac.Fs.UserId;
-
-namespace Ryujinx.Ava.UI.Views.User
-{
- public partial class UserSaveManagerView : UserControl
- {
- internal UserSaveManagerViewModel ViewModel { get; private set; }
-
- private AccountManager _accountManager;
- private HorizonClient _horizonClient;
- private VirtualFileSystem _virtualFileSystem;
- private NavigationDialogHost _parent;
-
- public UserSaveManagerView()
- {
- 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 (parent, accountManager, client, virtualFileSystem) = ((NavigationDialogHost parent, AccountManager accountManager, HorizonClient client, VirtualFileSystem virtualFileSystem))arg.Parameter;
- _accountManager = accountManager;
- _horizonClient = client;
- _virtualFileSystem = virtualFileSystem;
-
- _parent = parent;
- break;
- }
-
- DataContext = ViewModel = new UserSaveManagerViewModel(_accountManager);
- ((ContentDialog)_parent.Parent).Title = $"{LocaleManager.Instance[LocaleKeys.UserProfileWindowTitle]} - {ViewModel.SaveManagerHeading}";
-
- Task.Run(LoadSaves);
- }
- }
-
- public void LoadSaves()
- {
- ViewModel.Saves.Clear();
- var saves = new ObservableCollection<SaveModel>();
- var saveDataFilter = SaveDataFilter.Make(
- programId: default,
- saveType: SaveDataType.Account,
- new UserId((ulong)_accountManager.LastOpenedUser.UserId.High, (ulong)_accountManager.LastOpenedUser.UserId.Low),
- saveDataId: default,
- index: default);
-
- using var saveDataIterator = new UniqueRef<SaveDataIterator>();
-
- _horizonClient.Fs.OpenSaveDataIterator(ref saveDataIterator.Ref, SaveDataSpaceId.User, in saveDataFilter).ThrowIfFailure();
-
- Span<SaveDataInfo> saveDataInfo = stackalloc SaveDataInfo[10];
-
- while (true)
- {
- saveDataIterator.Get.ReadSaveDataInfo(out long readCount, saveDataInfo).ThrowIfFailure();
-
- if (readCount == 0)
- {
- break;
- }
-
- for (int i = 0; i < readCount; i++)
- {
- var save = saveDataInfo[i];
- if (save.ProgramId.Value != 0)
- {
- var saveModel = new SaveModel(save);
- saves.Add(saveModel);
- }
- }
- }
-
- Dispatcher.UIThread.Post(() =>
- {
- ViewModel.Saves = saves;
- ViewModel.Sort();
- });
- }
-
- private void GoBack(object sender, RoutedEventArgs e)
- {
- _parent?.GoBack();
- }
-
- private void OpenLocation(object sender, RoutedEventArgs e)
- {
- if (sender is Button button)
- {
- if (button.DataContext is SaveModel saveModel)
- {
- ApplicationHelper.OpenSaveDir(saveModel.SaveId);
- }
- }
- }
-
- private async void Delete(object sender, RoutedEventArgs e)
- {
- if (sender is Button button)
- {
- if (button.DataContext is SaveModel saveModel)
- {
- var result = await ContentDialogHelper.CreateConfirmationDialog(LocaleManager.Instance[LocaleKeys.DeleteUserSave],
- LocaleManager.Instance[LocaleKeys.IrreversibleActionNote],
- LocaleManager.Instance[LocaleKeys.InputDialogYes],
- LocaleManager.Instance[LocaleKeys.InputDialogNo], "");
-
- if (result == UserResult.Yes)
- {
- _horizonClient.Fs.DeleteSaveData(SaveDataSpaceId.User, saveModel.SaveId);
- ViewModel.Saves.Remove(saveModel);
- ViewModel.Sort();
- }
- }
- }
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserSelectorView.axaml b/src/Ryujinx.Ava/UI/Views/User/UserSelectorView.axaml
deleted file mode 100644
index 3a9de303..00000000
--- a/src/Ryujinx.Ava/UI/Views/User/UserSelectorView.axaml
+++ /dev/null
@@ -1,162 +0,0 @@
-<UserControl
- x:Class="Ryujinx.Ava.UI.Views.User.UserSelectorViews"
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
- xmlns:models="clr-namespace:Ryujinx.Ava.UI.Models"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
- d:DesignHeight="450"
- MinWidth="500"
- d:DesignWidth="800"
- mc:Ignorable="d"
- Focusable="True"
- x:DataType="viewModels:UserProfileViewModel">
- <UserControl.Resources>
- <helpers:BitmapArrayValueConverter x:Key="ByteImage" />
- </UserControl.Resources>
- <Design.DataContext>
- <viewModels:UserProfileViewModel />
- </Design.DataContext>
- <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
- <Grid.RowDefinitions>
- <RowDefinition />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <Border
- CornerRadius="5"
- BorderBrush="{DynamicResource AppListHoverBackgroundColor}"
- BorderThickness="1">
- <ListBox
- MaxHeight="300"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Center"
- SelectionChanged="ProfilesList_SelectionChanged"
- Background="Transparent"
- ItemsSource="{Binding Profiles}">
- <ListBox.ItemsPanel>
- <ItemsPanelTemplate>
- <WrapPanel
- HorizontalAlignment="Left"
- VerticalAlignment="Center"
- Orientation="Horizontal"/>
- </ItemsPanelTemplate>
- </ListBox.ItemsPanel>
- <ListBox.Styles>
- <Style Selector="ListBoxItem">
- <Setter Property="Margin" Value="5 5 0 5" />
- <Setter Property="CornerRadius" Value="5" />
- </Style>
- <Style Selector="Rectangle#SelectionIndicator">
- <Setter Property="Opacity" Value="0" />
- </Style>
- </ListBox.Styles>
- <ListBox.DataTemplates>
- <DataTemplate
- DataType="models:UserProfile">
- <Grid
- PointerEntered="Grid_PointerEntered"
- PointerExited="Grid_OnPointerExited">
- <Border
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- ClipToBounds="True"
- CornerRadius="5"
- Background="{Binding BackgroundColor}">
- <StackPanel
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch">
- <Image
- Width="96"
- Height="96"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Top"
- Source="{Binding Image, Converter={StaticResource ByteImage}}" />
- <TextBlock
- HorizontalAlignment="Stretch"
- MaxWidth="90"
- Text="{Binding Name}"
- TextAlignment="Center"
- TextWrapping="Wrap"
- TextTrimming="CharacterEllipsis"
- MaxLines="2"
- Margin="5" />
- </StackPanel>
- </Border>
- <Border
- Margin="2"
- Height="24"
- Width="24"
- CornerRadius="12"
- HorizontalAlignment="Right"
- VerticalAlignment="Top"
- Background="{DynamicResource ThemeContentBackgroundColor}"
- IsVisible="{Binding IsPointerOver}">
- <Button
- MaxHeight="24"
- MaxWidth="24"
- MinHeight="24"
- MinWidth="24"
- CornerRadius="12"
- Padding="0"
- Click="EditUser">
- <ui:SymbolIcon Symbol="Edit" />
- </Button>
- </Border>
- </Grid>
- </DataTemplate>
- <DataTemplate
- DataType="viewModels:BaseModel">
- <Panel
- Height="118"
- Width="96">
- <Button
- MinWidth="50"
- MinHeight="50"
- MaxWidth="50"
- MaxHeight="50"
- CornerRadius="25"
- Margin="10"
- Padding="0"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Click="AddUser">
- <ui:SymbolIcon Symbol="Add" />
- </Button>
- <Panel.Styles>
- <Style Selector="Panel">
- <Setter Property="Background" Value="{DynamicResource ListBoxBackground}"/>
- </Style>
- </Panel.Styles>
- </Panel>
- </DataTemplate>
- </ListBox.DataTemplates>
- </ListBox>
- </Border>
- <StackPanel
- Grid.Row="1"
- Margin="0 24 0 0"
- HorizontalAlignment="Left"
- Orientation="Horizontal"
- Spacing="10">
- <Button
- Click="ManageSaves"
- Content="{locale:Locale UserProfilesManageSaves}" />
- <Button
- Click="RecoverLostAccounts"
- Content="{locale:Locale UserProfilesRecoverLostAccounts}" />
- </StackPanel>
- <StackPanel
- Grid.Row="1"
- Margin="0 24 0 0"
- HorizontalAlignment="Right"
- Orientation="Horizontal">
- <Button
- Click="Close"
- Content="{locale:Locale UserProfilesClose}" />
- </StackPanel>
- </Grid>
-</UserControl>
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserSelectorView.axaml.cs b/src/Ryujinx.Ava/UI/Views/User/UserSelectorView.axaml.cs
deleted file mode 100644
index fa3383aa..00000000
--- a/src/Ryujinx.Ava/UI/Views/User/UserSelectorView.axaml.cs
+++ /dev/null
@@ -1,129 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Input;
-using Avalonia.Interactivity;
-using FluentAvalonia.UI.Controls;
-using FluentAvalonia.UI.Navigation;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Controls;
-using Ryujinx.Ava.UI.Models;
-using Ryujinx.Ava.UI.ViewModels;
-using Button = Avalonia.Controls.Button;
-
-namespace Ryujinx.Ava.UI.Views.User
-{
- public partial class UserSelectorViews : UserControl
- {
- private NavigationDialogHost _parent;
-
- public UserProfileViewModel ViewModel { get; set; }
-
- public UserSelectorViews()
- {
- InitializeComponent();
-
- if (Program.PreviewerDetached)
- {
- AddHandler(Frame.NavigatedToEvent, (s, e) =>
- {
- NavigatedTo(e);
- }, RoutingStrategies.Direct);
- }
- }
-
- private void NavigatedTo(NavigationEventArgs arg)
- {
- if (Program.PreviewerDetached)
- {
- if (arg.NavigationMode == NavigationMode.New)
- {
- _parent = (NavigationDialogHost)arg.Parameter;
- ViewModel = _parent.ViewModel;
- }
-
- if (arg.NavigationMode == NavigationMode.Back)
- {
- ((ContentDialog)_parent.Parent).Title = LocaleManager.Instance[LocaleKeys.UserProfileWindowTitle];
- }
-
- DataContext = ViewModel;
- }
- }
-
- private void Grid_PointerEntered(object sender, PointerEventArgs e)
- {
- if (sender is Grid grid)
- {
- if (grid.DataContext is UserProfile profile)
- {
- profile.IsPointerOver = true;
- }
- }
- }
-
- private void Grid_OnPointerExited(object sender, PointerEventArgs e)
- {
- if (sender is Grid grid)
- {
- if (grid.DataContext is UserProfile profile)
- {
- profile.IsPointerOver = false;
- }
- }
- }
-
- private void ProfilesList_SelectionChanged(object sender, SelectionChangedEventArgs e)
- {
- if (sender is ListBox listBox)
- {
- int selectedIndex = listBox.SelectedIndex;
-
- if (selectedIndex >= 0 && selectedIndex < ViewModel.Profiles.Count)
- {
- if (ViewModel.Profiles[selectedIndex] is UserProfile userProfile)
- {
- _parent?.AccountManager?.OpenUser(userProfile.UserId);
-
- foreach (BaseModel profile in ViewModel.Profiles)
- {
- if (profile is UserProfile uProfile)
- {
- uProfile.UpdateState();
- }
- }
- }
- }
- }
- }
-
- private void AddUser(object sender, RoutedEventArgs e)
- {
- _parent.AddUser();
- }
-
- private void EditUser(object sender, RoutedEventArgs e)
- {
- if (sender is Button button)
- {
- if (button.DataContext is UserProfile userProfile)
- {
- _parent.EditUser(userProfile);
- }
- }
- }
-
- private void ManageSaves(object sender, RoutedEventArgs e)
- {
- _parent.ManageSaves();
- }
-
- private void RecoverLostAccounts(object sender, RoutedEventArgs e)
- {
- _parent.RecoverLostAccounts();
- }
-
- private void Close(object sender, RoutedEventArgs e)
- {
- ((ContentDialog)_parent.Parent).Hide();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml b/src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml
deleted file mode 100644
index 69fa8251..00000000
--- a/src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml
+++ /dev/null
@@ -1,270 +0,0 @@
-<UserControl
- x:Class="Ryujinx.Ava.UI.Windows.AboutWindow"
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
- xmlns:viewModel="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- Width="550"
- Height="260"
- Margin="0,-12,0,0"
- d:DesignHeight="260"
- d:DesignWidth="550"
- x:DataType="viewModel:AboutWindowViewModel"
- Focusable="True"
- mc:Ignorable="d">
- <Design.DataContext>
- <viewModel:AboutWindowViewModel />
- </Design.DataContext>
- <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="*" />
- </Grid.ColumnDefinitions>
- <Grid
- Grid.Column="0"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="*" />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <StackPanel
- Grid.Row="0"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- Spacing="10">
- <Grid>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="*" />
- <ColumnDefinition Width="Auto" />
- </Grid.ColumnDefinitions>
- <StackPanel
- Grid.Column="1"
- Orientation="Horizontal"
- HorizontalAlignment="Center"
- Spacing="10">
- <Image
- Height="80"
- Source="resm:Ryujinx.UI.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.UI.Common"
- HorizontalAlignment="Center"
- IsHitTestVisible="True" />
- <WrapPanel
- HorizontalAlignment="Right"
- VerticalAlignment="Center"
- Orientation="Vertical">
- <TextBlock
- FontSize="28"
- FontWeight="Bold"
- Text="Ryujinx"
- TextAlignment="Start"
- Width="110"
- HorizontalAlignment="Center"
- VerticalAlignment="Center" />
- <TextBlock
- FontSize="11"
- Text="(REE-YOU-JINX)"
- TextAlignment="Start"
- Width="110"
- HorizontalAlignment="Center"
- VerticalAlignment="Center" />
- </WrapPanel>
- </StackPanel>
- </Grid>
- <TextBlock
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- FontSize="10"
- LineHeight="12"
- Text="{Binding Version}"
- TextAlignment="Center" />
- <Button
- Padding="5"
- HorizontalAlignment="Center"
- Background="Transparent"
- Click="Button_OnClick"
- Tag="https://github.com/Ryujinx/Ryujinx/wiki/Changelog#ryujinx-changelog">
- <TextBlock
- FontSize="10"
- Text="{locale:Locale AboutChangelogButton}"
- TextAlignment="Center"
- ToolTip.Tip="{locale:Locale AboutChangelogButtonTooltipMessage}" />
- </Button>
- </StackPanel>
- <StackPanel
- Grid.Row="2"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- Spacing="10">
- <TextBlock
- Width="200"
- HorizontalAlignment="Center"
- FontSize="10"
- LineHeight="12"
- Text="{locale:Locale AboutDisclaimerMessage}"
- TextAlignment="Center"
- TextWrapping="Wrap" />
- <TextBlock
- Name="AmiiboLabel"
- Width="200"
- HorizontalAlignment="Center"
- FontSize="10"
- LineHeight="12"
- PointerPressed="AmiiboLabel_OnPointerPressed"
- Text="{locale:Locale AboutAmiiboDisclaimerMessage}"
- TextAlignment="Center"
- TextWrapping="Wrap" />
- <StackPanel
- HorizontalAlignment="Center"
- Orientation="Horizontal"
- Spacing="10">
- <Button
- MinWidth="30"
- MinHeight="30"
- MaxWidth="30"
- MaxHeight="30"
- Padding="8"
- Background="Transparent"
- Click="Button_OnClick"
- CornerRadius="15"
- Tag="https://www.patreon.com/ryujinx"
- ToolTip.Tip="{locale:Locale AboutPatreonUrlTooltipMessage}">
- <Image Source="{Binding PatreonLogo}" />
- </Button>
- <Button
- MinWidth="30"
- MinHeight="30"
- MaxWidth="30"
- MaxHeight="30"
- Padding="8"
- Background="Transparent"
- Click="Button_OnClick"
- CornerRadius="15"
- Tag="https://github.com/Ryujinx/Ryujinx"
- ToolTip.Tip="{locale:Locale AboutGithubUrlTooltipMessage}">
- <Image Source="{Binding GithubLogo}" />
- </Button>
- <Button
- MinWidth="30"
- MinHeight="30"
- MaxWidth="30"
- MaxHeight="30"
- Padding="8"
- Background="Transparent"
- Click="Button_OnClick"
- CornerRadius="15"
- Tag="https://discordapp.com/invite/N2FmfVc"
- ToolTip.Tip="{locale:Locale AboutDiscordUrlTooltipMessage}">
- <Image Source="{Binding DiscordLogo}" />
- </Button>
- <Button
- MinWidth="30"
- MinHeight="30"
- MaxWidth="30"
- MaxHeight="30"
- Padding="8"
- Background="Transparent"
- Click="Button_OnClick"
- CornerRadius="15"
- Tag="https://twitter.com/RyujinxEmu"
- ToolTip.Tip="{locale:Locale AboutTwitterUrlTooltipMessage}">
- <Image Source="{Binding TwitterLogo}" />
- </Button>
- <Button
- MinWidth="30"
- MinHeight="30"
- MaxWidth="30"
- MaxHeight="30"
- Padding="8"
- Background="Transparent"
- Click="Button_OnClick"
- CornerRadius="15"
- Tag="https://www.ryujinx.org"
- ToolTip.Tip="{locale:Locale AboutUrlTooltipMessage}">
- <ui:SymbolIcon Foreground="{DynamicResource ThemeForegroundColor}" Symbol="Link" />
- </Button>
- </StackPanel>
- </StackPanel>
- </Grid>
- <Border
- Grid.Column="1"
- Width="1"
- Margin="20,0"
- VerticalAlignment="Stretch"
- BorderBrush="{DynamicResource ThemeControlBorderColor}"
- BorderThickness="1,0,0,0" />
- <Grid
- Grid.Column="2"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <StackPanel
- Grid.Row="0"
- Margin="0,10,0,0"
- Spacing="2">
- <TextBlock
- FontSize="15"
- FontWeight="Bold"
- Text="{locale:Locale AboutRyujinxAboutTitle}" />
- <TextBlock
- FontSize="10"
- Text="{locale:Locale AboutRyujinxAboutContent}"
- TextWrapping="Wrap" />
- </StackPanel>
- <StackPanel
- Grid.Row="1"
- Margin="0,10,0,0"
- Spacing="2">
- <TextBlock
- FontSize="15"
- FontWeight="Bold"
- Text="{locale:Locale AboutRyujinxMaintainersTitle}" />
- <TextBlock
- FontSize="10"
- Text="{Binding Developers}"
- TextWrapping="Wrap" />
- <Button
- Padding="5"
- HorizontalAlignment="Left"
- Background="Transparent"
- Click="Button_OnClick"
- Tag="https://github.com/Ryujinx/Ryujinx/graphs/contributors?type=a">
- <TextBlock
- FontSize="10"
- Text="{locale:Locale AboutRyujinxContributorsButtonHeader}"
- TextAlignment="End"
- ToolTip.Tip="{locale:Locale AboutRyujinxMaintainersContentTooltipMessage}" />
- </Button>
- </StackPanel>
- <StackPanel
- Grid.Row="2"
- Margin="0,10,0,0"
- Spacing="2">
- <TextBlock
- FontSize="15"
- FontWeight="Bold"
- Text="{locale:Locale AboutRyujinxSupprtersTitle}" />
- <ScrollViewer
- Height="70"
- HorizontalScrollBarVisibility="Disabled"
- VerticalScrollBarVisibility="Visible">
- <TextBlock
- Name="SupportersTextBlock"
- VerticalAlignment="Top"
- FontSize="10"
- Text="{Binding Supporters}"
- TextWrapping="Wrap" />
- </ScrollViewer>
- </StackPanel>
- </Grid>
- </Grid>
-</UserControl>
diff --git a/src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml.cs b/src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml.cs
deleted file mode 100644
index c32661b0..00000000
--- a/src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Input;
-using Avalonia.Interactivity;
-using Avalonia.Layout;
-using Avalonia.Styling;
-using FluentAvalonia.UI.Controls;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.UI.Common.Helper;
-using System.Threading.Tasks;
-using Button = Avalonia.Controls.Button;
-
-namespace Ryujinx.Ava.UI.Windows
-{
- public partial class AboutWindow : UserControl
- {
- public AboutWindow()
- {
- DataContext = new AboutWindowViewModel();
-
- InitializeComponent();
- }
-
- public static async Task Show()
- {
- ContentDialog contentDialog = new()
- {
- PrimaryButtonText = "",
- SecondaryButtonText = "",
- CloseButtonText = LocaleManager.Instance[LocaleKeys.UserProfilesClose],
- Content = new AboutWindow(),
- };
-
- Style closeButton = new(x => x.Name("CloseButton"));
- closeButton.Setters.Add(new Setter(WidthProperty, 80d));
-
- Style closeButtonParent = new(x => x.Name("CommandSpace"));
- closeButtonParent.Setters.Add(new Setter(HorizontalAlignmentProperty, HorizontalAlignment.Right));
-
- contentDialog.Styles.Add(closeButton);
- contentDialog.Styles.Add(closeButtonParent);
-
- await ContentDialogHelper.ShowAsync(contentDialog);
- }
-
- private void Button_OnClick(object sender, RoutedEventArgs e)
- {
- if (sender is Button button)
- {
- OpenHelper.OpenUrl(button.Tag.ToString());
- }
- }
-
- private void AmiiboLabel_OnPointerPressed(object sender, PointerPressedEventArgs e)
- {
- if (sender is TextBlock)
- {
- OpenHelper.OpenUrl("https://amiiboapi.com");
- }
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml b/src/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml
deleted file mode 100644
index c587aa87..00000000
--- a/src/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml
+++ /dev/null
@@ -1,75 +0,0 @@
-<window:StyleableWindow
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:window="clr-namespace:Ryujinx.Ava.UI.Windows"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- mc:Ignorable="d"
- d:DesignWidth="400"
- d:DesignHeight="350"
- x:Class="Ryujinx.Ava.UI.Windows.AmiiboWindow"
- x:DataType="viewModels:AmiiboWindowViewModel"
- CanResize="False"
- WindowStartupLocation="CenterOwner"
- Width="800"
- MinHeight="650"
- Height="650"
- SizeToContent="Manual"
- MinWidth="600"
- Focusable="True">
- <Design.DataContext>
- <viewModels:AmiiboWindowViewModel />
- </Design.DataContext>
- <Grid Margin="15" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- <RowDefinition Height="*" />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <Grid Grid.Row="1" HorizontalAlignment="Stretch">
- <Grid.ColumnDefinitions>
- <ColumnDefinition />
- <ColumnDefinition />
- </Grid.ColumnDefinitions>
- <StackPanel Spacing="10" Orientation="Horizontal" HorizontalAlignment="Left">
- <TextBlock VerticalAlignment="Center" Text="{locale:Locale AmiiboSeriesLabel}" />
- <ComboBox SelectedIndex="{Binding SeriesSelectedIndex}" ItemsSource="{Binding AmiiboSeries}" MinWidth="100" />
- </StackPanel>
- <StackPanel Spacing="10" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
- <TextBlock VerticalAlignment="Center" Text="{locale:Locale AmiiboCharacterLabel}" />
- <ComboBox SelectedIndex="{Binding AmiiboSelectedIndex}" MinWidth="100" ItemsSource="{Binding AmiiboList}" />
- </StackPanel>
- </Grid>
- <StackPanel Margin="20" Grid.Row="2">
- <Image Source="{Binding AmiiboImage}" Height="350" Width="350" HorizontalAlignment="Center" />
- <ScrollViewer MaxHeight="120" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto"
- Margin="20" VerticalAlignment="Top" HorizontalAlignment="Stretch">
- <TextBlock TextWrapping="Wrap" Text="{Binding Usage}" HorizontalAlignment="Center"
- TextAlignment="Center" />
- </ScrollViewer>
- </StackPanel>
- <Grid Grid.Row="3">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="*" />
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="Auto" />
- </Grid.ColumnDefinitions>
- <CheckBox Margin="10" Grid.Column="0" VerticalContentAlignment="Center" IsChecked="{Binding ShowAllAmiibo}"
- Content="{locale:Locale AmiiboOptionsShowAllLabel}" />
- <CheckBox Margin="10" VerticalContentAlignment="Center" Grid.Column="1" IsChecked="{Binding UseRandomUuid}"
- Content="{locale:Locale AmiiboOptionsUsRandomTagLabel}" />
-
- <Button Grid.Column="3" IsEnabled="{Binding EnableScanning}" Width="80"
- Content="{locale:Locale AmiiboScanButtonLabel}" Name="ScanButton"
- Click="ScanButton_Click" />
- <Button Grid.Column="4" Margin="10,0" Width="80" Content="{locale:Locale InputDialogCancel}"
- Name="CancelButton"
- Click="CancelButton_Click" />
- </Grid>
- </Grid>
-</window:StyleableWindow>
diff --git a/src/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml.cs b/src/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml.cs
deleted file mode 100644
index 8829cb10..00000000
--- a/src/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-using Avalonia.Interactivity;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.UI.Common.Models.Amiibo;
-
-namespace Ryujinx.Ava.UI.Windows
-{
- public partial class AmiiboWindow : StyleableWindow
- {
- public AmiiboWindow(bool showAll, string lastScannedAmiiboId, string titleId)
- {
- ViewModel = new AmiiboWindowViewModel(this, lastScannedAmiiboId, titleId)
- {
- ShowAllAmiibo = showAll,
- };
-
- DataContext = ViewModel;
-
- InitializeComponent();
-
- Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance[LocaleKeys.Amiibo];
- }
-
- public AmiiboWindow()
- {
- ViewModel = new AmiiboWindowViewModel(this, string.Empty, string.Empty);
-
- DataContext = ViewModel;
-
- InitializeComponent();
-
- if (Program.PreviewerDetached)
- {
- Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance[LocaleKeys.Amiibo];
- }
- }
-
- public bool IsScanned { get; set; }
- public AmiiboApi ScannedAmiibo { get; set; }
- public AmiiboWindowViewModel ViewModel { get; set; }
-
- private void ScanButton_Click(object sender, RoutedEventArgs e)
- {
- if (ViewModel.AmiiboSelectedIndex > -1)
- {
- AmiiboApi amiibo = ViewModel.AmiiboList[ViewModel.AmiiboSelectedIndex];
- ScannedAmiibo = amiibo;
- IsScanned = true;
- Close();
- }
- }
-
- private void CancelButton_Click(object sender, RoutedEventArgs e)
- {
- IsScanned = false;
-
- Close();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml b/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml
deleted file mode 100644
index 57d5f7ef..00000000
--- a/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml
+++ /dev/null
@@ -1,126 +0,0 @@
-<window:StyleableWindow
- x:Class="Ryujinx.Ava.UI.Windows.CheatWindow"
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:model="clr-namespace:Ryujinx.Ava.UI.Models"
- xmlns:window="clr-namespace:Ryujinx.Ava.UI.Windows"
- Width="500"
- Height="500"
- MinWidth="500"
- MinHeight="500"
- x:DataType="window:CheatWindow"
- WindowStartupLocation="CenterOwner"
- mc:Ignorable="d"
- Focusable="True">
- <Window.Styles>
- <Style Selector="TreeViewItem">
- <Setter Property="IsExpanded" Value="True" />
- </Style>
- </Window.Styles>
- <Grid Name="CheatGrid" Margin="15">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- <RowDefinition Height="*" />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="*" />
- <ColumnDefinition Width="*" />
- </Grid.ColumnDefinitions>
- <TextBlock
- Grid.Row="1"
- Grid.Column="0"
- Grid.ColumnSpan="2"
- MaxWidth="500"
- Margin="20,15,20,5"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- LineHeight="18"
- Text="{Binding Heading}"
- TextAlignment="Center"
- TextWrapping="Wrap" />
- <TextBlock
- Grid.Row="2"
- Grid.Column="0"
- MaxWidth="500"
- Margin="140,15,20,5"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- LineHeight="30"
- Text="{locale:Locale BuildId}"
- TextAlignment="Center"
- TextWrapping="Wrap" />
- <TextBox
- Grid.Row="2"
- Grid.Column="1"
- Margin="0,5,110,5"
- MinWidth="160"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="{Binding BuildId}"
- IsReadOnly="True" />
- <Border
- Grid.Row="3"
- Grid.Column="0"
- Grid.ColumnSpan="2"
- Margin="5"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- BorderBrush="Gray"
- BorderThickness="1">
- <TreeView
- Name="CheatsView"
- MinHeight="300"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- ItemsSource="{Binding LoadedCheats}">
- <TreeView.Styles>
- <Styles>
- <Style Selector="TreeViewItem:empty /template/ ItemsPresenter">
- <Setter Property="IsVisible" Value="False" />
- </Style>
- </Styles>
- </TreeView.Styles>
- <TreeView.ItemTemplate>
- <TreeDataTemplate ItemsSource="{Binding SubNodes}">
- <StackPanel HorizontalAlignment="Left" Orientation="Horizontal">
- <CheckBox MinWidth="20" IsChecked="{Binding IsEnabled}" />
- <TextBlock Width="150" Text="{Binding CleanName}" IsVisible="{Binding !IsRootNode}" />
- <TextBlock Width="150" Text="{Binding BuildId}" IsVisible="{Binding IsRootNode}" />
- <TextBlock Text="{Binding Path}" IsVisible="{Binding IsRootNode}" />
- </StackPanel>
- </TreeDataTemplate>
- </TreeView.ItemTemplate>
- </TreeView>
- </Border>
- <DockPanel
- Grid.Row="4"
- Grid.Column="0"
- Grid.ColumnSpan="2"
- Margin="0"
- HorizontalAlignment="Stretch">
- <DockPanel Margin="0" HorizontalAlignment="Right">
- <Button
- Name="SaveButton"
- MinWidth="90"
- Margin="5"
- Command="{Binding Save}"
- IsVisible="{Binding !NoCheatsFound}">
- <TextBlock Text="{locale:Locale SettingsButtonSave}" />
- </Button>
- <Button
- Name="CancelButton"
- MinWidth="90"
- Margin="5"
- Command="{Binding Close}">
- <TextBlock Text="{locale:Locale InputDialogCancel}" />
- </Button>
- </DockPanel>
- </DockPanel>
- </Grid>
-</window:StyleableWindow>
diff --git a/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml.cs b/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml.cs
deleted file mode 100644
index d78e48a4..00000000
--- a/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml.cs
+++ /dev/null
@@ -1,123 +0,0 @@
-using Avalonia.Collections;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Models;
-using Ryujinx.HLE.FileSystem;
-using Ryujinx.HLE.HOS;
-using Ryujinx.UI.App.Common;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-
-namespace Ryujinx.Ava.UI.Windows
-{
- public partial class CheatWindow : StyleableWindow
- {
- private readonly string _enabledCheatsPath;
- public bool NoCheatsFound { get; }
-
- public AvaloniaList<CheatNode> LoadedCheats { get; }
-
- public string Heading { get; }
- public string BuildId { get; }
-
- public CheatWindow()
- {
- DataContext = this;
-
- InitializeComponent();
-
- Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance[LocaleKeys.CheatWindowTitle];
- }
-
- public CheatWindow(VirtualFileSystem virtualFileSystem, string titleId, string titleName, string titlePath)
- {
- LoadedCheats = new AvaloniaList<CheatNode>();
-
- Heading = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.CheatWindowHeading, titleName, titleId.ToUpper());
- BuildId = ApplicationData.GetApplicationBuildId(virtualFileSystem, titlePath);
-
- InitializeComponent();
-
- string modsBasePath = ModLoader.GetModsBasePath();
- string titleModsPath = ModLoader.GetApplicationDir(modsBasePath, titleId);
- ulong titleIdValue = ulong.Parse(titleId, NumberStyles.HexNumber);
-
- _enabledCheatsPath = Path.Combine(titleModsPath, "cheats", "enabled.txt");
-
- string[] enabled = Array.Empty<string>();
-
- if (File.Exists(_enabledCheatsPath))
- {
- enabled = File.ReadAllLines(_enabledCheatsPath);
- }
-
- int cheatAdded = 0;
-
- var mods = new ModLoader.ModCache();
-
- ModLoader.QueryContentsDir(mods, new DirectoryInfo(Path.Combine(modsBasePath, "contents")), titleIdValue);
-
- string currentCheatFile = string.Empty;
- string buildId = string.Empty;
-
- CheatNode currentGroup = null;
-
- foreach (var cheat in mods.Cheats)
- {
- if (cheat.Path.FullName != currentCheatFile)
- {
- currentCheatFile = cheat.Path.FullName;
- string parentPath = currentCheatFile.Replace(titleModsPath, "");
-
- buildId = Path.GetFileNameWithoutExtension(currentCheatFile).ToUpper();
- currentGroup = new CheatNode("", buildId, parentPath, true);
-
- LoadedCheats.Add(currentGroup);
- }
-
- var model = new CheatNode(cheat.Name, buildId, "", false, enabled.Contains($"{buildId}-{cheat.Name}"));
- currentGroup?.SubNodes.Add(model);
-
- cheatAdded++;
- }
-
- if (cheatAdded == 0)
- {
- NoCheatsFound = true;
- }
-
- DataContext = this;
-
- Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance[LocaleKeys.CheatWindowTitle];
- }
-
- public void Save()
- {
- if (NoCheatsFound)
- {
- return;
- }
-
- List<string> enabledCheats = new();
-
- foreach (var cheats in LoadedCheats)
- {
- foreach (var cheat in cheats.SubNodes)
- {
- if (cheat.IsEnabled)
- {
- enabledCheats.Add(cheat.BuildIdKey);
- }
- }
- }
-
- Directory.CreateDirectory(Path.GetDirectoryName(_enabledCheatsPath));
-
- File.WriteAllLines(_enabledCheatsPath, enabledCheats);
-
- Close();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Windows/ContentDialogOverlayWindow.axaml b/src/Ryujinx.Ava/UI/Windows/ContentDialogOverlayWindow.axaml
deleted file mode 100644
index 8b52bade..00000000
--- a/src/Ryujinx.Ava/UI/Windows/ContentDialogOverlayWindow.axaml
+++ /dev/null
@@ -1,25 +0,0 @@
-<window:StyleableWindow
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
- xmlns:window="clr-namespace:Ryujinx.Ava.UI.Windows"
- mc:Ignorable="d"
- d:DesignWidth="800"
- d:DesignHeight="450"
- x:Class="Ryujinx.Ava.UI.Windows.ContentDialogOverlayWindow"
- Title="ContentDialogOverlayWindow"
- Focusable="False">
- <window:StyleableWindow.Styles>
- <Style Selector="ui|ContentDialog /template/ Panel#LayoutRoot">
- <Setter Property="Background"
- Value="Transparent" />
- </Style>
- </window:StyleableWindow.Styles>
- <ui:ContentDialog Name="ContentDialog"
- IsPrimaryButtonEnabled="True"
- IsSecondaryButtonEnabled="True"
- IsVisible="False"
- Focusable="True"/>
-</window:StyleableWindow>
diff --git a/src/Ryujinx.Ava/UI/Windows/ContentDialogOverlayWindow.axaml.cs b/src/Ryujinx.Ava/UI/Windows/ContentDialogOverlayWindow.axaml.cs
deleted file mode 100644
index 2b12d72f..00000000
--- a/src/Ryujinx.Ava/UI/Windows/ContentDialogOverlayWindow.axaml.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Media;
-
-namespace Ryujinx.Ava.UI.Windows
-{
- public partial class ContentDialogOverlayWindow : StyleableWindow
- {
- public ContentDialogOverlayWindow()
- {
- InitializeComponent();
-
- ExtendClientAreaToDecorationsHint = true;
- TransparencyLevelHint = new[] { WindowTransparencyLevel.Transparent };
- WindowStartupLocation = WindowStartupLocation.Manual;
- SystemDecorations = SystemDecorations.None;
- ExtendClientAreaTitleBarHeightHint = 0;
- Background = Brushes.Transparent;
- CanResize = false;
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Windows/DownloadableContentManagerWindow.axaml b/src/Ryujinx.Ava/UI/Windows/DownloadableContentManagerWindow.axaml
deleted file mode 100644
index 99cf28e7..00000000
--- a/src/Ryujinx.Ava/UI/Windows/DownloadableContentManagerWindow.axaml
+++ /dev/null
@@ -1,192 +0,0 @@
-<UserControl
- x:Class="Ryujinx.Ava.UI.Windows.DownloadableContentManagerWindow"
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- xmlns:models="clr-namespace:Ryujinx.Ava.UI.Models"
- xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
- Width="500"
- Height="380"
- mc:Ignorable="d"
- x:DataType="viewModels:DownloadableContentManagerViewModel"
- Focusable="True">
- <Grid>
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="*" />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <Panel
- Margin="0 0 0 10"
- Grid.Row="0">
- <Grid>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="*" />
- </Grid.ColumnDefinitions>
- <TextBlock
- Grid.Column="0"
- Text="{Binding UpdateCount}" />
- <StackPanel
- Margin="10 0"
- Grid.Column="1"
- Orientation="Horizontal">
- <Button
- Name="EnableAllButton"
- MinWidth="90"
- Margin="5"
- Command="{Binding EnableAll}">
- <TextBlock Text="{locale:Locale DlcManagerEnableAllButton}" />
- </Button>
- <Button
- Name="DisableAllButton"
- MinWidth="90"
- Margin="5"
- Command="{Binding DisableAll}">
- <TextBlock Text="{locale:Locale DlcManagerDisableAllButton}" />
- </Button>
- </StackPanel>
- <TextBox
- Grid.Column="2"
- MinHeight="29"
- MaxHeight="29"
- HorizontalAlignment="Stretch"
- Watermark="{locale:Locale Search}"
- Text="{Binding Search}" />
- </Grid>
- </Panel>
- <Border
- Grid.Row="1"
- Margin="0 0 0 24"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- BorderBrush="{DynamicResource AppListHoverBackgroundColor}"
- BorderThickness="1"
- CornerRadius="5"
- Padding="2.5">
- <ListBox
- AutoScrollToSelectedItem="False"
- SelectionMode="Multiple, Toggle"
- Background="Transparent"
- SelectionChanged="OnSelectionChanged"
- SelectedItems="{Binding SelectedDownloadableContents, Mode=TwoWay}"
- ItemsSource="{Binding Views}">
- <ListBox.DataTemplates>
- <DataTemplate
- DataType="models:DownloadableContentModel">
- <Panel Margin="10">
- <Grid>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="*" />
- <ColumnDefinition Width="Auto" />
- </Grid.ColumnDefinitions>
- <Grid
- Grid.Column="0">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="*" />
- <ColumnDefinition Width="Auto" />
- </Grid.ColumnDefinitions>
- <TextBlock
- Grid.Column="0"
- HorizontalAlignment="Left"
- VerticalAlignment="Center"
- MaxLines="2"
- TextWrapping="Wrap"
- TextTrimming="CharacterEllipsis"
- Text="{Binding FileName}" />
- <TextBlock
- Grid.Column="1"
- Margin="10 0"
- HorizontalAlignment="Left"
- VerticalAlignment="Center"
- Text="{Binding TitleId}" />
- </Grid>
- <StackPanel
- Grid.Column="1"
- Spacing="10"
- Orientation="Horizontal"
- HorizontalAlignment="Right">
- <Button
- VerticalAlignment="Center"
- HorizontalAlignment="Right"
- Padding="10"
- MinWidth="0"
- MinHeight="0"
- Click="OpenLocation">
- <ui:SymbolIcon
- Symbol="OpenFolder"
- HorizontalAlignment="Center"
- VerticalAlignment="Center" />
- </Button>
- <Button
- VerticalAlignment="Center"
- HorizontalAlignment="Right"
- Padding="10"
- MinWidth="0"
- MinHeight="0"
- Click="RemoveDLC">
- <ui:SymbolIcon
- Symbol="Cancel"
- HorizontalAlignment="Center"
- VerticalAlignment="Center" />
- </Button>
- </StackPanel>
- </Grid>
- </Panel>
- </DataTemplate>
- </ListBox.DataTemplates>
- <ListBox.Styles>
- <Style Selector="ListBoxItem">
- <Setter Property="Background" Value="Transparent" />
- </Style>
- </ListBox.Styles>
- </ListBox>
- </Border>
- <Panel
- Grid.Row="2"
- HorizontalAlignment="Stretch">
- <StackPanel
- Orientation="Horizontal"
- Spacing="10"
- HorizontalAlignment="Left">
- <Button
- Name="AddButton"
- MinWidth="90"
- Margin="5"
- Command="{Binding Add}">
- <TextBlock Text="{locale:Locale SettingsTabGeneralAdd}" />
- </Button>
- <Button
- Name="RemoveAllButton"
- MinWidth="90"
- Margin="5"
- Command="{Binding RemoveAll}">
- <TextBlock Text="{locale:Locale DlcManagerRemoveAllButton}" />
- </Button>
- </StackPanel>
- <StackPanel
- Orientation="Horizontal"
- Spacing="10"
- HorizontalAlignment="Right">
- <Button
- Name="SaveButton"
- MinWidth="90"
- Margin="5"
- Click="SaveAndClose">
- <TextBlock Text="{locale:Locale SettingsButtonSave}" />
- </Button>
- <Button
- Name="CancelButton"
- MinWidth="90"
- Margin="5"
- Click="Close">
- <TextBlock Text="{locale:Locale InputDialogCancel}" />
- </Button>
- </StackPanel>
- </Panel>
- </Grid>
-</UserControl>
diff --git a/src/Ryujinx.Ava/UI/Windows/DownloadableContentManagerWindow.axaml.cs b/src/Ryujinx.Ava/UI/Windows/DownloadableContentManagerWindow.axaml.cs
deleted file mode 100644
index 0c02fa0f..00000000
--- a/src/Ryujinx.Ava/UI/Windows/DownloadableContentManagerWindow.axaml.cs
+++ /dev/null
@@ -1,115 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Interactivity;
-using Avalonia.Styling;
-using FluentAvalonia.UI.Controls;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.Models;
-using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.HLE.FileSystem;
-using Ryujinx.UI.Common.Helper;
-using System.Threading.Tasks;
-using Button = Avalonia.Controls.Button;
-
-namespace Ryujinx.Ava.UI.Windows
-{
- public partial class DownloadableContentManagerWindow : UserControl
- {
- public DownloadableContentManagerViewModel ViewModel;
-
- public DownloadableContentManagerWindow()
- {
- DataContext = this;
-
- InitializeComponent();
- }
-
- public DownloadableContentManagerWindow(VirtualFileSystem virtualFileSystem, ulong titleId)
- {
- DataContext = ViewModel = new DownloadableContentManagerViewModel(virtualFileSystem, titleId);
-
- InitializeComponent();
- }
-
- public static async Task Show(VirtualFileSystem virtualFileSystem, ulong titleId, string titleName)
- {
- ContentDialog contentDialog = new()
- {
- PrimaryButtonText = "",
- SecondaryButtonText = "",
- CloseButtonText = "",
- Content = new DownloadableContentManagerWindow(virtualFileSystem, titleId),
- Title = string.Format(LocaleManager.Instance[LocaleKeys.DlcWindowTitle], titleName, titleId.ToString("X16")),
- };
-
- Style bottomBorder = new(x => x.OfType<Grid>().Name("DialogSpace").Child().OfType<Border>());
- bottomBorder.Setters.Add(new Setter(IsVisibleProperty, false));
-
- contentDialog.Styles.Add(bottomBorder);
-
- await ContentDialogHelper.ShowAsync(contentDialog);
- }
-
- private void SaveAndClose(object sender, RoutedEventArgs routedEventArgs)
- {
- ViewModel.Save();
- ((ContentDialog)Parent).Hide();
- }
-
- private void Close(object sender, RoutedEventArgs e)
- {
- ((ContentDialog)Parent).Hide();
- }
-
- private void RemoveDLC(object sender, RoutedEventArgs e)
- {
- if (sender is Button button)
- {
- if (button.DataContext is DownloadableContentModel model)
- {
- ViewModel.Remove(model);
- }
- }
- }
-
- private void OpenLocation(object sender, RoutedEventArgs e)
- {
- if (sender is Button button)
- {
- if (button.DataContext is DownloadableContentModel model)
- {
- OpenHelper.LocateFile(model.ContainerPath);
- }
- }
- }
-
- private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
- {
- foreach (var content in e.AddedItems)
- {
- if (content is DownloadableContentModel model)
- {
- var index = ViewModel.DownloadableContents.IndexOf(model);
-
- if (index != -1)
- {
- ViewModel.DownloadableContents[index].Enabled = true;
- }
- }
- }
-
- foreach (var content in e.RemovedItems)
- {
- if (content is DownloadableContentModel model)
- {
- var index = ViewModel.DownloadableContents.IndexOf(model);
-
- if (index != -1)
- {
- ViewModel.DownloadableContents[index].Enabled = false;
- }
- }
- }
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Windows/IconColorPicker.cs b/src/Ryujinx.Ava/UI/Windows/IconColorPicker.cs
deleted file mode 100644
index 4c75a5ff..00000000
--- a/src/Ryujinx.Ava/UI/Windows/IconColorPicker.cs
+++ /dev/null
@@ -1,194 +0,0 @@
-using SixLabors.ImageSharp;
-using SixLabors.ImageSharp.PixelFormats;
-using System;
-using System.Collections.Generic;
-
-namespace Ryujinx.Ava.UI.Windows
-{
- static class IconColorPicker
- {
- private const int ColorsPerLine = 64;
- private const int TotalColors = ColorsPerLine * ColorsPerLine;
-
- private const int UvQuantBits = 3;
- private const int UvQuantShift = BitsPerComponent - UvQuantBits;
-
- private const int SatQuantBits = 5;
- private const int SatQuantShift = BitsPerComponent - SatQuantBits;
-
- private const int BitsPerComponent = 8;
-
- private const int CutOffLuminosity = 64;
-
- private readonly struct PaletteColor
- {
- public int Qck { get; }
- public byte R { get; }
- public byte G { get; }
- public byte B { get; }
-
- public PaletteColor(int qck, byte r, byte g, byte b)
- {
- Qck = qck;
- R = r;
- G = g;
- B = b;
- }
- }
-
- public static Color GetFilteredColor(Image<Bgra32> image)
- {
- var color = GetColor(image).ToPixel<Bgra32>();
-
- // We don't want colors that are too dark.
- // If the color is too dark, make it brighter by reducing the range
- // and adding a constant color.
- int luminosity = GetColorApproximateLuminosity(color.R, color.G, color.B);
- if (luminosity < CutOffLuminosity)
- {
- color = Color.FromRgb(
- (byte)Math.Min(CutOffLuminosity + color.R, byte.MaxValue),
- (byte)Math.Min(CutOffLuminosity + color.G, byte.MaxValue),
- (byte)Math.Min(CutOffLuminosity + color.B, byte.MaxValue));
- }
-
- return color;
- }
-
- public static Color GetColor(Image<Bgra32> image)
- {
- var colors = new PaletteColor[TotalColors];
-
- var dominantColorBin = new Dictionary<int, int>();
-
- var buffer = GetBuffer(image);
-
- int w = image.Width;
-
- int w8 = w << 8;
- int h8 = image.Height << 8;
-
-#pragma warning disable IDE0059 // Unnecessary assignment
- int xStep = w8 / ColorsPerLine;
- int yStep = h8 / ColorsPerLine;
-#pragma warning restore IDE0059
-
- int i = 0;
- int maxHitCount = 0;
-
- for (int y = 0; y < image.Height; y++)
- {
- int yOffset = y * image.Width;
-
- for (int x = 0; x < image.Width && i < TotalColors; x++)
- {
- int offset = x + yOffset;
-
- byte cb = buffer[offset].B;
- byte cg = buffer[offset].G;
- byte cr = buffer[offset].R;
-
- var qck = GetQuantizedColorKey(cr, cg, cb);
-
- if (dominantColorBin.TryGetValue(qck, out int hitCount))
- {
- dominantColorBin[qck] = hitCount + 1;
-
- if (maxHitCount < hitCount)
- {
- maxHitCount = hitCount;
- }
- }
- else
- {
- dominantColorBin.Add(qck, 1);
- }
-
- colors[i++] = new PaletteColor(qck, cr, cg, cb);
- }
- }
-
- int highScore = -1;
- PaletteColor bestCandidate = default;
-
- for (i = 0; i < TotalColors; i++)
- {
- var score = GetColorScore(dominantColorBin, maxHitCount, colors[i]);
-
- if (highScore < score)
- {
- highScore = score;
- bestCandidate = colors[i];
- }
- }
-
- return Color.FromRgb(bestCandidate.R, bestCandidate.G, bestCandidate.B);
- }
-
- public static Bgra32[] GetBuffer(Image<Bgra32> image)
- {
- return image.TryGetSinglePixelSpan(out var data) ? data.ToArray() : Array.Empty<Bgra32>();
- }
-
- private static int GetColorScore(Dictionary<int, int> dominantColorBin, int maxHitCount, PaletteColor color)
- {
- var hitCount = dominantColorBin[color.Qck];
- var balancedHitCount = BalanceHitCount(hitCount, maxHitCount);
- var quantSat = (GetColorSaturation(color) >> SatQuantShift) << SatQuantShift;
- var value = GetColorValue(color);
-
- // If the color is rarely used on the image,
- // then chances are that theres a better candidate, even if the saturation value
- // is high. By multiplying the saturation value with a weight, we can lower
- // it if the color is almost never used (hit count is low).
- var satWeighted = quantSat;
- var satWeight = balancedHitCount << 5;
- if (satWeight < 0x100)
- {
- satWeighted = (satWeighted * satWeight) >> 8;
- }
-
- // Compute score from saturation and dominance of the color.
- // We prefer more vivid colors over dominant ones, so give more weight to the saturation.
- var score = ((satWeighted << 1) + balancedHitCount) * value;
-
- return score;
- }
-
- private static int BalanceHitCount(int hitCount, int maxHitCount)
- {
- return (hitCount << 8) / maxHitCount;
- }
-
- private static int GetColorApproximateLuminosity(byte r, byte g, byte b)
- {
- return (r + g + b) / 3;
- }
-
- private static int GetColorSaturation(PaletteColor color)
- {
- int cMax = Math.Max(Math.Max(color.R, color.G), color.B);
-
- if (cMax == 0)
- {
- return 0;
- }
-
- int cMin = Math.Min(Math.Min(color.R, color.G), color.B);
- int delta = cMax - cMin;
- return (delta << 8) / cMax;
- }
-
- private static int GetColorValue(PaletteColor color)
- {
- return Math.Max(Math.Max(color.R, color.G), color.B);
- }
-
- private static int GetQuantizedColorKey(byte r, byte g, byte b)
- {
- int u = ((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128;
- int v = ((112 * r - 94 * g - 18 * b + 128) >> 8) + 128;
- return (v >> UvQuantShift) | ((u >> UvQuantShift) << UvQuantBits);
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml b/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml
deleted file mode 100644
index 4def7c28..00000000
--- a/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml
+++ /dev/null
@@ -1,205 +0,0 @@
-<window:StyleableWindow
- x:Class="Ryujinx.Ava.UI.Windows.MainWindow"
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:window="clr-namespace:Ryujinx.Ava.UI.Windows"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
- xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
- xmlns:main="clr-namespace:Ryujinx.Ava.UI.Views.Main"
- Cursor="{Binding Cursor}"
- Title="{Binding Title}"
- WindowState="{Binding WindowState}"
- Width="{Binding WindowWidth}"
- Height="{Binding WindowHeight}"
- MinWidth="1092"
- MinHeight="672"
- d:DesignHeight="720"
- d:DesignWidth="1280"
- x:DataType="viewModels:MainWindowViewModel"
- mc:Ignorable="d"
- WindowStartupLocation="Manual"
- Focusable="True">
- <Window.Styles>
- <Style Selector="TitleBar:fullscreen">
- <Setter Property="Background" Value="#000000" />
- </Style>
- </Window.Styles>
- <Design.DataContext>
- <viewModels:MainWindowViewModel />
- </Design.DataContext>
- <Window.Resources>
- <helpers:BitmapArrayValueConverter x:Key="ByteImage" />
- </Window.Resources>
- <Window.KeyBindings>
- <KeyBinding Gesture="Alt+Return" Command="{Binding ToggleFullscreen}" />
- <KeyBinding Gesture="F11" Command="{Binding ToggleFullscreen}" />
- <KeyBinding Gesture="Ctrl+Cmd+F" Command="{Binding ToggleFullscreen}" />
- <KeyBinding Gesture="F9" Command="{Binding ToggleDockMode}" />
- <KeyBinding Gesture="Escape" Command="{Binding ExitCurrentState}" />
- </Window.KeyBindings>
- <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="*" />
- </Grid.RowDefinitions>
- <helpers:OffscreenTextBox Name="HiddenTextBox" Grid.Row="0" />
- <Grid
- Grid.Row="1"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="*" />
- </Grid.ColumnDefinitions>
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="*" />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <StackPanel
- Name="MenuBar"
- MinHeight="35"
- Grid.Row="0"
- Margin="0"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- IsVisible="{Binding ShowMenuAndStatusBar}"
- Orientation="Vertical">
- <main:MainMenuBarView
- Name="MenuBarView" />
- </StackPanel>
- <ContentControl
- Name="MainContent"
- Grid.Row="1"
- Padding="0"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- BorderBrush="{DynamicResource ThemeControlBorderColor}"
- BorderThickness="0,0,0,0"
- DockPanel.Dock="Top"
- IsVisible="{Binding ShowContent}">
- <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Name="GameLibrary">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="*" />
- </Grid.RowDefinitions>
- <main:MainViewControls
- Name="ViewControls"
- Grid.Row="0"/>
- <controls:ApplicationListView
- x:Name="ApplicationList"
- Grid.Row="1"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- HorizontalContentAlignment="Stretch"
- VerticalContentAlignment="Stretch"
- IsVisible="{Binding IsList}" />
- <controls:ApplicationGridView
- x:Name="ApplicationGrid"
- Grid.Row="1"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- HorizontalContentAlignment="Stretch"
- VerticalContentAlignment="Stretch"
- IsVisible="{Binding IsGrid}" />
- </Grid>
- </ContentControl>
- <Grid
- Grid.Row="1"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- Background="{DynamicResource ThemeContentBackgroundColor}"
- IsVisible="{Binding ShowLoadProgress}"
- Name="LoadingView"
- ZIndex="1000">
- <Grid
- Margin="40"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- IsVisible="{Binding ShowLoadProgress}">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="*" />
- </Grid.ColumnDefinitions>
- <Border
- Grid.RowSpan="2"
- Grid.Column="0"
- Width="256"
- Height="256"
- Margin="10"
- Padding="4"
- BorderBrush="Black"
- BorderThickness="2"
- BoxShadow="4 4 32 8 #40000000"
- CornerRadius="3"
- IsVisible="{Binding ShowLoadProgress}">
- <Image
- Width="256"
- Height="256"
- IsVisible="{Binding ShowLoadProgress}"
- Source="{Binding SelectedIcon, Converter={StaticResource ByteImage}}" />
- </Border>
- <Grid
- Grid.Column="1"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Center"
- IsVisible="{Binding ShowLoadProgress}">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <TextBlock
- Grid.Row="0"
- Margin="10"
- FontSize="30"
- FontWeight="Bold"
- IsVisible="{Binding ShowLoadProgress}"
- Text="{Binding LoadHeading}"
- TextAlignment="Start"
- TextWrapping="Wrap"
- MaxWidth="500" />
- <Border
- Grid.Row="1"
- Margin="10"
- Padding="0"
- HorizontalAlignment="Stretch"
- BorderBrush="{Binding ProgressBarBackgroundColor}"
- BorderThickness="1"
- ClipToBounds="True"
- CornerRadius="5"
- IsVisible="{Binding ShowLoadProgress}">
- <ProgressBar
- Height="10"
- MinWidth="500"
- Margin="0"
- Padding="0"
- HorizontalAlignment="Stretch"
- ClipToBounds="True"
- CornerRadius="5"
- Foreground="{Binding ProgressBarForegroundColor}"
- IsIndeterminate="{Binding IsLoadingIndeterminate}"
- IsVisible="{Binding ShowLoadProgress}"
- Maximum="{Binding ProgressMaximum}"
- Minimum="0"
- Value="{Binding ProgressValue}" />
- </Border>
- <TextBlock
- Grid.Row="2"
- Margin="10"
- FontSize="18"
- IsVisible="{Binding ShowLoadProgress}"
- Text="{Binding CacheLoadStatus}"
- TextAlignment="Start"
- MaxWidth="500" />
- </Grid>
- </Grid>
- </Grid>
- <main:MainStatusBarView
- Name="StatusBarView"
- Grid.Row="2" />
- </Grid>
- </Grid>
-</window:StyleableWindow>
diff --git a/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs b/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs
deleted file mode 100644
index 33a9af5b..00000000
--- a/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs
+++ /dev/null
@@ -1,551 +0,0 @@
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Controls.Primitives;
-using Avalonia.Interactivity;
-using Avalonia.Threading;
-using FluentAvalonia.UI.Controls;
-using Ryujinx.Ava.Common;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.Input;
-using Ryujinx.Ava.UI.Applet;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.Common.Logging;
-using Ryujinx.Graphics.Gpu;
-using Ryujinx.HLE.FileSystem;
-using Ryujinx.HLE.HOS;
-using Ryujinx.HLE.HOS.Services.Account.Acc;
-using Ryujinx.Input.HLE;
-using Ryujinx.Input.SDL2;
-using Ryujinx.Modules;
-using Ryujinx.UI.App.Common;
-using Ryujinx.UI.Common;
-using Ryujinx.UI.Common.Configuration;
-using Ryujinx.UI.Common.Helper;
-using System;
-using System.IO;
-using System.Runtime.Versioning;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Ryujinx.Ava.UI.Windows
-{
- public partial class MainWindow : StyleableWindow
- {
- internal static MainWindowViewModel MainWindowViewModel { get; private set; }
-
- private bool _isLoading;
-
- private UserChannelPersistence _userChannelPersistence;
- private static bool _deferLoad;
- private static string _launchPath;
- private static bool _startFullscreen;
- internal readonly AvaHostUIHandler UiHandler;
-
- public VirtualFileSystem VirtualFileSystem { get; private set; }
- public ContentManager ContentManager { get; private set; }
- public AccountManager AccountManager { get; private set; }
-
- public LibHacHorizonManager LibHacHorizonManager { get; private set; }
-
- public InputManager InputManager { get; private set; }
-
- internal MainWindowViewModel ViewModel { get; private set; }
- public SettingsWindow SettingsWindow { get; set; }
-
- public static bool ShowKeyErrorOnLoad { get; set; }
- public ApplicationLibrary ApplicationLibrary { get; set; }
-
- public MainWindow()
- {
- ViewModel = new MainWindowViewModel();
-
- MainWindowViewModel = ViewModel;
-
- DataContext = ViewModel;
-
- SetWindowSizePosition();
-
- InitializeComponent();
- Load();
-
- UiHandler = new AvaHostUIHandler(this);
-
- ViewModel.Title = $"Ryujinx {Program.Version}";
-
- // NOTE: Height of MenuBar and StatusBar is not usable here, since it would still be 0 at this point.
- double barHeight = MenuBar.MinHeight + StatusBarView.StatusBar.MinHeight;
- Height = ((Height - barHeight) / Program.WindowScaleFactor) + barHeight;
- Width /= Program.WindowScaleFactor;
-
- if (Program.PreviewerDetached)
- {
- InputManager = new InputManager(new AvaloniaKeyboardDriver(this), new SDL2GamepadDriver());
-
- this.GetObservable(IsActiveProperty).Subscribe(IsActiveChanged);
- this.ScalingChanged += OnScalingChanged;
- }
- }
-
- protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
- {
- base.OnApplyTemplate(e);
-
- NotificationHelper.SetNotificationManager(this);
- }
-
- private void IsActiveChanged(bool obj)
- {
- ViewModel.IsActive = obj;
- }
-
- private void OnScalingChanged(object sender, EventArgs e)
- {
- Program.DesktopScaleFactor = this.RenderScaling;
- }
-
- private void ApplicationLibrary_ApplicationAdded(object sender, ApplicationAddedEventArgs e)
- {
- Dispatcher.UIThread.Post(() =>
- {
- ViewModel.Applications.Add(e.AppData);
- });
- }
-
- private void ApplicationLibrary_ApplicationCountUpdated(object sender, ApplicationCountUpdatedEventArgs e)
- {
- LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.StatusBarGamesLoaded, e.NumAppsLoaded, e.NumAppsFound);
-
- Dispatcher.UIThread.Post(() =>
- {
- ViewModel.StatusBarProgressValue = e.NumAppsLoaded;
- ViewModel.StatusBarProgressMaximum = e.NumAppsFound;
-
- if (e.NumAppsFound == 0)
- {
- StatusBarView.LoadProgressBar.IsVisible = false;
- }
-
- if (e.NumAppsLoaded == e.NumAppsFound)
- {
- StatusBarView.LoadProgressBar.IsVisible = false;
- }
- });
- }
-
- public void Application_Opened(object sender, ApplicationOpenedEventArgs args)
- {
- if (args.Application != null)
- {
- ViewModel.SelectedIcon = args.Application.Icon;
-
- string path = new FileInfo(args.Application.Path).FullName;
-
- ViewModel.LoadApplication(path).Wait();
- }
-
- args.Handled = true;
- }
-
- internal static void DeferLoadApplication(string launchPathArg, bool startFullscreenArg)
- {
- _deferLoad = true;
- _launchPath = launchPathArg;
- _startFullscreen = startFullscreenArg;
- }
-
- public void SwitchToGameControl(bool startFullscreen = false)
- {
- ViewModel.ShowLoadProgress = false;
- ViewModel.ShowContent = true;
- ViewModel.IsLoadingIndeterminate = false;
-
- if (startFullscreen && ViewModel.WindowState != WindowState.FullScreen)
- {
- ViewModel.ToggleFullscreen();
- }
- }
-
- public void ShowLoading(bool startFullscreen = false)
- {
- ViewModel.ShowContent = false;
- ViewModel.ShowLoadProgress = true;
- ViewModel.IsLoadingIndeterminate = true;
-
- if (startFullscreen && ViewModel.WindowState != WindowState.FullScreen)
- {
- ViewModel.ToggleFullscreen();
- }
- }
-
- private void Initialize()
- {
- _userChannelPersistence = new UserChannelPersistence();
- VirtualFileSystem = VirtualFileSystem.CreateInstance();
- LibHacHorizonManager = new LibHacHorizonManager();
- ContentManager = new ContentManager(VirtualFileSystem);
-
- LibHacHorizonManager.InitializeFsServer(VirtualFileSystem);
- LibHacHorizonManager.InitializeArpServer();
- LibHacHorizonManager.InitializeBcatServer();
- LibHacHorizonManager.InitializeSystemClients();
-
- ApplicationLibrary = new ApplicationLibrary(VirtualFileSystem);
-
- // Save data created before we supported extra data in directory save data will not work properly if
- // given empty extra data. Luckily some of that extra data can be created using the data from the
- // save data indexer, which should be enough to check access permissions for user saves.
- // Every single save data's extra data will be checked and fixed if needed each time the emulator is opened.
- // Consider removing this at some point in the future when we don't need to worry about old saves.
- VirtualFileSystem.FixExtraData(LibHacHorizonManager.RyujinxClient);
-
- AccountManager = new AccountManager(LibHacHorizonManager.RyujinxClient, CommandLineState.Profile);
-
- VirtualFileSystem.ReloadKeySet();
-
- ApplicationHelper.Initialize(VirtualFileSystem, AccountManager, LibHacHorizonManager.RyujinxClient);
- }
-
- [SupportedOSPlatform("linux")]
- private static async Task ShowVmMaxMapCountWarning()
- {
- LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.LinuxVmMaxMapCountWarningTextSecondary,
- LinuxHelper.VmMaxMapCount, LinuxHelper.RecommendedVmMaxMapCount);
-
- await ContentDialogHelper.CreateWarningDialog(
- LocaleManager.Instance[LocaleKeys.LinuxVmMaxMapCountWarningTextPrimary],
- LocaleManager.Instance[LocaleKeys.LinuxVmMaxMapCountWarningTextSecondary]
- );
- }
-
- [SupportedOSPlatform("linux")]
- private static async Task ShowVmMaxMapCountDialog()
- {
- LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.LinuxVmMaxMapCountDialogTextPrimary,
- LinuxHelper.RecommendedVmMaxMapCount);
-
- UserResult response = await ContentDialogHelper.ShowTextDialog(
- $"Ryujinx - {LocaleManager.Instance[LocaleKeys.LinuxVmMaxMapCountDialogTitle]}",
- LocaleManager.Instance[LocaleKeys.LinuxVmMaxMapCountDialogTextPrimary],
- LocaleManager.Instance[LocaleKeys.LinuxVmMaxMapCountDialogTextSecondary],
- LocaleManager.Instance[LocaleKeys.LinuxVmMaxMapCountDialogButtonUntilRestart],
- LocaleManager.Instance[LocaleKeys.LinuxVmMaxMapCountDialogButtonPersistent],
- LocaleManager.Instance[LocaleKeys.InputDialogNo],
- (int)Symbol.Help
- );
-
- int rc;
-
- switch (response)
- {
- case UserResult.Ok:
- rc = LinuxHelper.RunPkExec($"echo {LinuxHelper.RecommendedVmMaxMapCount} > {LinuxHelper.VmMaxMapCountPath}");
- if (rc == 0)
- {
- Logger.Info?.Print(LogClass.Application, $"vm.max_map_count set to {LinuxHelper.VmMaxMapCount} until the next restart.");
- }
- else
- {
- Logger.Error?.Print(LogClass.Application, $"Unable to change vm.max_map_count. Process exited with code: {rc}");
- }
- break;
- case UserResult.No:
- rc = LinuxHelper.RunPkExec($"echo \"vm.max_map_count = {LinuxHelper.RecommendedVmMaxMapCount}\" > {LinuxHelper.SysCtlConfigPath} && sysctl -p {LinuxHelper.SysCtlConfigPath}");
- if (rc == 0)
- {
- Logger.Info?.Print(LogClass.Application, $"vm.max_map_count set to {LinuxHelper.VmMaxMapCount}. Written to config: {LinuxHelper.SysCtlConfigPath}");
- }
- else
- {
- Logger.Error?.Print(LogClass.Application, $"Unable to write new value for vm.max_map_count to config. Process exited with code: {rc}");
- }
- break;
- }
- }
-
- private async Task CheckLaunchState()
- {
- if (OperatingSystem.IsLinux() && LinuxHelper.VmMaxMapCount < LinuxHelper.RecommendedVmMaxMapCount)
- {
- Logger.Warning?.Print(LogClass.Application, $"The value of vm.max_map_count is lower than {LinuxHelper.RecommendedVmMaxMapCount}. ({LinuxHelper.VmMaxMapCount})");
-
- if (LinuxHelper.PkExecPath is not null)
- {
- await Dispatcher.UIThread.InvokeAsync(ShowVmMaxMapCountDialog);
- }
- else
- {
- await Dispatcher.UIThread.InvokeAsync(ShowVmMaxMapCountWarning);
- }
- }
-
- if (!ShowKeyErrorOnLoad)
- {
- if (_deferLoad)
- {
- _deferLoad = false;
-
- ViewModel.LoadApplication(_launchPath, _startFullscreen).Wait();
- }
- }
- else
- {
- ShowKeyErrorOnLoad = false;
-
- await Dispatcher.UIThread.InvokeAsync(async () => await UserErrorDialog.ShowUserErrorDialog(UserError.NoKeys));
- }
-
- if (ConfigurationState.Instance.CheckUpdatesOnStart.Value && Updater.CanUpdate(false))
- {
- await Updater.BeginParse(this, false).ContinueWith(task =>
- {
- Logger.Error?.Print(LogClass.Application, $"Updater Error: {task.Exception}");
- }, TaskContinuationOptions.OnlyOnFaulted);
- }
- }
-
- private void Load()
- {
- StatusBarView.VolumeStatus.Click += VolumeStatus_CheckedChanged;
-
- ApplicationGrid.ApplicationOpened += Application_Opened;
-
- ApplicationGrid.DataContext = ViewModel;
-
- ApplicationList.ApplicationOpened += Application_Opened;
-
- ApplicationList.DataContext = ViewModel;
- }
-
- private void SetWindowSizePosition()
- {
- PixelPoint savedPoint = new(ConfigurationState.Instance.UI.WindowStartup.WindowPositionX,
- ConfigurationState.Instance.UI.WindowStartup.WindowPositionY);
-
- ViewModel.WindowHeight = ConfigurationState.Instance.UI.WindowStartup.WindowSizeHeight * Program.WindowScaleFactor;
- ViewModel.WindowWidth = ConfigurationState.Instance.UI.WindowStartup.WindowSizeWidth * Program.WindowScaleFactor;
-
- ViewModel.WindowState = ConfigurationState.Instance.UI.WindowStartup.WindowMaximized.Value ? WindowState.Maximized : WindowState.Normal;
-
- if (CheckScreenBounds(savedPoint))
- {
- Position = savedPoint;
- }
- else
- {
- WindowStartupLocation = WindowStartupLocation.CenterScreen;
- }
- }
-
- private bool CheckScreenBounds(PixelPoint configPoint)
- {
- for (int i = 0; i < Screens.ScreenCount; i++)
- {
- if (Screens.All[i].Bounds.Contains(configPoint))
- {
- return true;
- }
- }
-
- Logger.Warning?.Print(LogClass.Application, "Failed to find valid start-up coordinates. Defaulting to primary monitor center.");
- return false;
- }
-
- private void SaveWindowSizePosition()
- {
- ConfigurationState.Instance.UI.WindowStartup.WindowSizeHeight.Value = (int)Height;
- ConfigurationState.Instance.UI.WindowStartup.WindowSizeWidth.Value = (int)Width;
-
- ConfigurationState.Instance.UI.WindowStartup.WindowPositionX.Value = Position.X;
- ConfigurationState.Instance.UI.WindowStartup.WindowPositionY.Value = Position.Y;
-
- ConfigurationState.Instance.UI.WindowStartup.WindowMaximized.Value = WindowState == WindowState.Maximized;
-
- MainWindowViewModel.SaveConfig();
- }
-
- protected override void OnOpened(EventArgs e)
- {
- base.OnOpened(e);
-
- Initialize();
-
- ViewModel.Initialize(
- ContentManager,
- StorageProvider,
- ApplicationLibrary,
- VirtualFileSystem,
- AccountManager,
- InputManager,
- _userChannelPersistence,
- LibHacHorizonManager,
- UiHandler,
- ShowLoading,
- SwitchToGameControl,
- SetMainContent,
- this);
-
- ApplicationLibrary.ApplicationCountUpdated += ApplicationLibrary_ApplicationCountUpdated;
- ApplicationLibrary.ApplicationAdded += ApplicationLibrary_ApplicationAdded;
-
- ViewModel.RefreshFirmwareStatus();
-
- LoadApplications();
-
-#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
- CheckLaunchState();
-#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
- }
-
- private void SetMainContent(Control content = null)
- {
- content ??= GameLibrary;
-
- if (MainContent.Content != content)
- {
- MainContent.Content = content;
- }
- }
-
- public static void UpdateGraphicsConfig()
- {
-#pragma warning disable IDE0055 // Disable formatting
- GraphicsConfig.ResScale = ConfigurationState.Instance.Graphics.ResScale == -1 ? ConfigurationState.Instance.Graphics.ResScaleCustom : ConfigurationState.Instance.Graphics.ResScale;
- GraphicsConfig.MaxAnisotropy = ConfigurationState.Instance.Graphics.MaxAnisotropy;
- GraphicsConfig.ShadersDumpPath = ConfigurationState.Instance.Graphics.ShadersDumpPath;
- GraphicsConfig.EnableShaderCache = ConfigurationState.Instance.Graphics.EnableShaderCache;
- GraphicsConfig.EnableTextureRecompression = ConfigurationState.Instance.Graphics.EnableTextureRecompression;
- GraphicsConfig.EnableMacroHLE = ConfigurationState.Instance.Graphics.EnableMacroHLE;
-#pragma warning restore IDE0055
- }
-
- private void VolumeStatus_CheckedChanged(object sender, RoutedEventArgs e)
- {
- var volumeSplitButton = sender as ToggleSplitButton;
- if (ViewModel.IsGameRunning)
- {
- if (!volumeSplitButton.IsChecked)
- {
- ViewModel.AppHost.Device.SetVolume(ViewModel.VolumeBeforeMute);
- }
- else
- {
- ViewModel.VolumeBeforeMute = ViewModel.AppHost.Device.GetVolume();
- ViewModel.AppHost.Device.SetVolume(0);
- }
-
- ViewModel.Volume = ViewModel.AppHost.Device.GetVolume();
- }
- }
-
- protected override void OnClosing(WindowClosingEventArgs e)
- {
- if (!ViewModel.IsClosing && ViewModel.AppHost != null && ConfigurationState.Instance.ShowConfirmExit)
- {
- e.Cancel = true;
-
- ConfirmExit();
-
- return;
- }
-
- ViewModel.IsClosing = true;
-
- if (ViewModel.AppHost != null)
- {
- ViewModel.AppHost.AppExit -= ViewModel.AppHost_AppExit;
- ViewModel.AppHost.AppExit += (sender, e) =>
- {
- ViewModel.AppHost = null;
-
- Dispatcher.UIThread.Post(() =>
- {
- MainContent = null;
-
- Close();
- });
- };
- ViewModel.AppHost?.Stop();
-
- e.Cancel = true;
-
- return;
- }
-
- SaveWindowSizePosition();
-
- ApplicationLibrary.CancelLoading();
- InputManager.Dispose();
- Program.Exit();
-
- base.OnClosing(e);
- }
-
- private void ConfirmExit()
- {
- Dispatcher.UIThread.InvokeAsync(async () =>
- {
- ViewModel.IsClosing = await ContentDialogHelper.CreateExitDialog();
-
- if (ViewModel.IsClosing)
- {
- Close();
- }
- });
- }
-
- public void LoadApplications()
- {
- ViewModel.Applications.Clear();
-
- StatusBarView.LoadProgressBar.IsVisible = true;
- ViewModel.StatusBarProgressMaximum = 0;
- ViewModel.StatusBarProgressValue = 0;
-
- LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.StatusBarGamesLoaded, 0, 0);
-
- ReloadGameList();
- }
-
- public void ToggleFileType(string fileType)
- {
- _ = fileType switch
- {
-#pragma warning disable IDE0055 // Disable formatting
- "NSP" => ConfigurationState.Instance.UI.ShownFileTypes.NSP.Value = !ConfigurationState.Instance.UI.ShownFileTypes.NSP,
- "PFS0" => ConfigurationState.Instance.UI.ShownFileTypes.PFS0.Value = !ConfigurationState.Instance.UI.ShownFileTypes.PFS0,
- "XCI" => ConfigurationState.Instance.UI.ShownFileTypes.XCI.Value = !ConfigurationState.Instance.UI.ShownFileTypes.XCI,
- "NCA" => ConfigurationState.Instance.UI.ShownFileTypes.NCA.Value = !ConfigurationState.Instance.UI.ShownFileTypes.NCA,
- "NRO" => ConfigurationState.Instance.UI.ShownFileTypes.NRO.Value = !ConfigurationState.Instance.UI.ShownFileTypes.NRO,
- "NSO" => ConfigurationState.Instance.UI.ShownFileTypes.NSO.Value = !ConfigurationState.Instance.UI.ShownFileTypes.NSO,
- _ => throw new ArgumentOutOfRangeException(fileType),
-#pragma warning restore IDE0055
- };
-
- ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
- LoadApplications();
- }
-
- private void ReloadGameList()
- {
- if (_isLoading)
- {
- return;
- }
-
- _isLoading = true;
-
- Thread applicationLibraryThread = new(() =>
- {
- ApplicationLibrary.LoadApplications(ConfigurationState.Instance.UI.GameDirs, ConfigurationState.Instance.System.Language);
-
- _isLoading = false;
- })
- {
- Name = "GUI.ApplicationLibraryThread",
- IsBackground = true,
- };
- applicationLibraryThread.Start();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Windows/ModManagerWindow.axaml b/src/Ryujinx.Ava/UI/Windows/ModManagerWindow.axaml
deleted file mode 100644
index 0ed05ce3..00000000
--- a/src/Ryujinx.Ava/UI/Windows/ModManagerWindow.axaml
+++ /dev/null
@@ -1,179 +0,0 @@
-<UserControl
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- xmlns:models="clr-namespace:Ryujinx.Ava.UI.Models"
- xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
- Width="500"
- Height="380"
- mc:Ignorable="d"
- x:Class="Ryujinx.Ava.UI.Windows.ModManagerWindow"
- x:CompileBindings="True"
- x:DataType="viewModels:ModManagerViewModel"
- Focusable="True">
- <Grid>
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="*" />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <Panel
- Margin="0 0 0 10"
- Grid.Row="0">
- <Grid>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="*" />
- </Grid.ColumnDefinitions>
- <TextBlock
- Grid.Column="0"
- Text="{Binding ModCount}" />
- <StackPanel
- Margin="10 0"
- Grid.Column="1"
- Orientation="Horizontal">
- <Button
- Name="EnableAllButton"
- MinWidth="90"
- Margin="5"
- Command="{Binding EnableAll}">
- <TextBlock Text="{locale:Locale DlcManagerEnableAllButton}" />
- </Button>
- <Button
- Name="DisableAllButton"
- MinWidth="90"
- Margin="5"
- Command="{Binding DisableAll}">
- <TextBlock Text="{locale:Locale DlcManagerDisableAllButton}" />
- </Button>
- </StackPanel>
- <TextBox
- Grid.Column="2"
- MinHeight="27"
- MaxHeight="27"
- HorizontalAlignment="Stretch"
- Watermark="{locale:Locale Search}"
- Text="{Binding Search}" />
- </Grid>
- </Panel>
- <Border
- Grid.Row="1"
- Margin="0 0 0 24"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- BorderBrush="{DynamicResource AppListHoverBackgroundColor}"
- BorderThickness="1"
- CornerRadius="5"
- Padding="2.5">
- <ListBox
- AutoScrollToSelectedItem="False"
- SelectionMode="Multiple, Toggle"
- Background="Transparent"
- SelectionChanged="OnSelectionChanged"
- SelectedItems="{Binding SelectedMods, Mode=TwoWay}"
- ItemsSource="{Binding Views}">
- <ListBox.DataTemplates>
- <DataTemplate
- DataType="models:ModModel">
- <Panel Margin="10">
- <Grid>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="*" />
- <ColumnDefinition Width="Auto" />
- </Grid.ColumnDefinitions>
- <TextBlock
- HorizontalAlignment="Left"
- VerticalAlignment="Center"
- MaxLines="2"
- TextWrapping="Wrap"
- TextTrimming="CharacterEllipsis"
- Text="{Binding Name}" />
- <StackPanel
- Grid.Column="1"
- Spacing="10"
- Orientation="Horizontal"
- HorizontalAlignment="Right">
- <Button
- VerticalAlignment="Center"
- HorizontalAlignment="Right"
- Padding="10"
- MinWidth="0"
- MinHeight="0"
- Click="OpenLocation">
- <ui:SymbolIcon
- Symbol="OpenFolder"
- HorizontalAlignment="Center"
- VerticalAlignment="Center" />
- </Button>
- <Button
- VerticalAlignment="Center"
- HorizontalAlignment="Right"
- Padding="10"
- MinWidth="0"
- MinHeight="0"
- Click="DeleteMod">
- <ui:SymbolIcon
- Symbol="Cancel"
- HorizontalAlignment="Center"
- VerticalAlignment="Center" />
- </Button>
- </StackPanel>
- </Grid>
- </Panel>
- </DataTemplate>
- </ListBox.DataTemplates>
- <ListBox.Styles>
- <Style Selector="ListBoxItem">
- <Setter Property="Background" Value="Transparent" />
- </Style>
- </ListBox.Styles>
- </ListBox>
- </Border>
- <Panel
- Grid.Row="2"
- HorizontalAlignment="Stretch">
- <StackPanel
- Orientation="Horizontal"
- Spacing="10"
- HorizontalAlignment="Left">
- <Button
- Name="AddButton"
- MinWidth="90"
- Margin="5"
- Command="{Binding Add}">
- <TextBlock Text="{locale:Locale SettingsTabGeneralAdd}" />
- </Button>
- <Button
- Name="RemoveAllButton"
- MinWidth="90"
- Margin="5"
- Click="DeleteAll">
- <TextBlock Text="{locale:Locale ModManagerDeleteAllButton}" />
- </Button>
- </StackPanel>
- <StackPanel
- Orientation="Horizontal"
- Spacing="10"
- HorizontalAlignment="Right">
- <Button
- Name="SaveButton"
- MinWidth="90"
- Margin="5"
- Click="SaveAndClose">
- <TextBlock Text="{locale:Locale SettingsButtonSave}" />
- </Button>
- <Button
- Name="CancelButton"
- MinWidth="90"
- Margin="5"
- Click="Close">
- <TextBlock Text="{locale:Locale InputDialogCancel}" />
- </Button>
- </StackPanel>
- </Panel>
- </Grid>
-</UserControl>
diff --git a/src/Ryujinx.Ava/UI/Windows/ModManagerWindow.axaml.cs b/src/Ryujinx.Ava/UI/Windows/ModManagerWindow.axaml.cs
deleted file mode 100644
index d9ae0d4f..00000000
--- a/src/Ryujinx.Ava/UI/Windows/ModManagerWindow.axaml.cs
+++ /dev/null
@@ -1,139 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Interactivity;
-using Avalonia.Styling;
-using FluentAvalonia.UI.Controls;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.Models;
-using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.UI.Common.Helper;
-using System.Threading.Tasks;
-using Button = Avalonia.Controls.Button;
-
-namespace Ryujinx.Ava.UI.Windows
-{
- public partial class ModManagerWindow : UserControl
- {
- public ModManagerViewModel ViewModel;
-
- public ModManagerWindow()
- {
- DataContext = this;
-
- InitializeComponent();
- }
-
- public ModManagerWindow(ulong titleId)
- {
- DataContext = ViewModel = new ModManagerViewModel(titleId);
-
- InitializeComponent();
- }
-
- public static async Task Show(ulong titleId, string titleName)
- {
- ContentDialog contentDialog = new()
- {
- PrimaryButtonText = "",
- SecondaryButtonText = "",
- CloseButtonText = "",
- Content = new ModManagerWindow(titleId),
- Title = string.Format(LocaleManager.Instance[LocaleKeys.ModWindowHeading], titleName, titleId.ToString("X16")),
- };
-
- Style bottomBorder = new(x => x.OfType<Grid>().Name("DialogSpace").Child().OfType<Border>());
- bottomBorder.Setters.Add(new Setter(IsVisibleProperty, false));
-
- contentDialog.Styles.Add(bottomBorder);
-
- await contentDialog.ShowAsync();
- }
-
- private void SaveAndClose(object sender, RoutedEventArgs e)
- {
- ViewModel.Save();
- ((ContentDialog)Parent).Hide();
- }
-
- private void Close(object sender, RoutedEventArgs e)
- {
- ((ContentDialog)Parent).Hide();
- }
-
- private async void DeleteMod(object sender, RoutedEventArgs e)
- {
- if (sender is Button button)
- {
- if (button.DataContext is ModModel model)
- {
- var result = await ContentDialogHelper.CreateConfirmationDialog(
- LocaleManager.Instance[LocaleKeys.DialogWarning],
- LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogModManagerDeletionWarningMessage, model.Name),
- LocaleManager.Instance[LocaleKeys.InputDialogYes],
- LocaleManager.Instance[LocaleKeys.InputDialogNo],
- LocaleManager.Instance[LocaleKeys.RyujinxConfirm]);
-
- if (result == UserResult.Yes)
- {
- ViewModel.Delete(model);
- }
- }
- }
- }
-
- private async void DeleteAll(object sender, RoutedEventArgs e)
- {
- var result = await ContentDialogHelper.CreateConfirmationDialog(
- LocaleManager.Instance[LocaleKeys.DialogWarning],
- LocaleManager.Instance[LocaleKeys.DialogModManagerDeletionAllWarningMessage],
- LocaleManager.Instance[LocaleKeys.InputDialogYes],
- LocaleManager.Instance[LocaleKeys.InputDialogNo],
- LocaleManager.Instance[LocaleKeys.RyujinxConfirm]);
-
- if (result == UserResult.Yes)
- {
- ViewModel.DeleteAll();
- }
- }
-
- private void OpenLocation(object sender, RoutedEventArgs e)
- {
- if (sender is Button button)
- {
- if (button.DataContext is ModModel model)
- {
- OpenHelper.OpenFolder(model.Path);
- }
- }
- }
-
- private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
- {
- foreach (var content in e.AddedItems)
- {
- if (content is ModModel model)
- {
- var index = ViewModel.Mods.IndexOf(model);
-
- if (index != -1)
- {
- ViewModel.Mods[index].Enabled = true;
- }
- }
- }
-
- foreach (var content in e.RemovedItems)
- {
- if (content is ModModel model)
- {
- var index = ViewModel.Mods.IndexOf(model);
-
- if (index != -1)
- {
- ViewModel.Mods[index].Enabled = false;
- }
- }
- }
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml b/src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml
deleted file mode 100644
index 40cac90d..00000000
--- a/src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml
+++ /dev/null
@@ -1,130 +0,0 @@
-<window:StyleableWindow
- x:Class="Ryujinx.Ava.UI.Windows.SettingsWindow"
- xmlns="https://github.com/avaloniaui"
- xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:window="clr-namespace:Ryujinx.Ava.UI.Windows"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- xmlns:settings="clr-namespace:Ryujinx.Ava.UI.Views.Settings"
- xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
- Width="1100"
- Height="768"
- MinWidth="800"
- MinHeight="480"
- WindowStartupLocation="CenterOwner"
- x:DataType="viewModels:SettingsViewModel"
- mc:Ignorable="d"
- Focusable="True">
- <Design.DataContext>
- <viewModels:SettingsViewModel />
- </Design.DataContext>
- <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MinWidth="600">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <ContentPresenter
- x:Name="ContentPresenter"
- Grid.Row="1"
- IsVisible="False"
- KeyboardNavigation.IsTabStop="False"/>
- <Grid Name="Pages" IsVisible="False" Grid.Row="2">
- <settings:SettingsUiView Name="UiPage" />
- <settings:SettingsInputView Name="InputPage" />
- <settings:SettingsHotkeysView Name="HotkeysPage" />
- <settings:SettingsSystemView Name="SystemPage" />
- <settings:SettingsCPUView Name="CpuPage" />
- <settings:SettingsGraphicsView Name="GraphicsPage" />
- <settings:SettingsAudioView Name="AudioPage" />
- <settings:SettingsNetworkView Name="NetworkPage" />
- <settings:SettingsLoggingView Name="LoggingPage" />
- </Grid>
- <ui:NavigationView
- Grid.Row="1"
- IsSettingsVisible="False"
- Name="NavPanel"
- IsBackEnabled="False"
- PaneDisplayMode="Left"
- Margin="2,10,10,0"
- VerticalAlignment="Stretch"
- HorizontalAlignment="Stretch"
- OpenPaneLength="200">
- <ui:NavigationView.MenuItems>
- <ui:NavigationViewItem
- IsSelected="True"
- Content="{locale:Locale SettingsTabGeneral}"
- Tag="UiPage"
- IconSource="New" />
- <ui:NavigationViewItem
- Content="{locale:Locale SettingsTabInput}"
- Tag="InputPage"
- IconSource="Games" />
- <ui:NavigationViewItem
- Content="{locale:Locale SettingsTabHotkeys}"
- Tag="HotkeysPage"
- IconSource="Keyboard" />
- <ui:NavigationViewItem
- Content="{locale:Locale SettingsTabSystem}"
- Tag="SystemPage"
- IconSource="Settings" />
- <ui:NavigationViewItem
- Content="{locale:Locale SettingsTabCpu}"
- Tag="CpuPage">
- <ui:NavigationViewItem.IconSource>
- <ui:FontIconSource
- FontFamily="avares://Ryujinx.Ava/Assets/Fonts#Segoe Fluent Icons"
- Glyph="{helpers:GlyphValueConverter Chip}" />
- </ui:NavigationViewItem.IconSource>
- </ui:NavigationViewItem>
- <ui:NavigationViewItem
- Content="{locale:Locale SettingsTabGraphics}"
- Tag="GraphicsPage"
- IconSource="Image" />
- <ui:NavigationViewItem
- Content="{locale:Locale SettingsTabAudio}"
- IconSource="Audio"
- Tag="AudioPage" />
- <ui:NavigationViewItem
- Content="{locale:Locale SettingsTabNetwork}"
- Tag="NetworkPage"
- IconSource="Globe" />
- <ui:NavigationViewItem
- Content="{locale:Locale SettingsTabLogging}"
- Tag="LoggingPage"
- IconSource="Document" />
- </ui:NavigationView.MenuItems>
- <ui:NavigationView.Styles>
- <Style Selector="Grid#PlaceholderGrid">
- <Setter Property="Height" Value="40" />
- </Style>
- <Style Selector="ui|NavigationViewItem ui|SymbolIcon">
- <Setter Property="FlowDirection" Value="LeftToRight" />
- </Style>
- </ui:NavigationView.Styles>
- </ui:NavigationView>
- <ReversibleStackPanel
- Grid.Row="2"
- Margin="10"
- Spacing="10"
- Orientation="Horizontal"
- HorizontalAlignment="Right"
- ReverseOrder="{Binding IsMacOS}">
- <Button
- HotKey="Enter"
- Classes="accent"
- Content="{locale:Locale SettingsButtonOk}"
- Command="{Binding OkButton}" />
- <Button
- HotKey="Escape"
- Content="{locale:Locale SettingsButtonCancel}"
- Command="{Binding CancelButton}" />
- <Button
- Content="{locale:Locale SettingsButtonApply}"
- Command="{Binding ApplyButton}" />
- </ReversibleStackPanel>
- </Grid>
-</window:StyleableWindow>
diff --git a/src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml.cs b/src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml.cs
deleted file mode 100644
index d7bb0b88..00000000
--- a/src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml.cs
+++ /dev/null
@@ -1,103 +0,0 @@
-using Avalonia.Controls;
-using FluentAvalonia.Core;
-using FluentAvalonia.UI.Controls;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.HLE.FileSystem;
-using System;
-
-namespace Ryujinx.Ava.UI.Windows
-{
- public partial class SettingsWindow : StyleableWindow
- {
- internal SettingsViewModel ViewModel { get; set; }
-
- public SettingsWindow(VirtualFileSystem virtualFileSystem, ContentManager contentManager)
- {
- Title = $"Ryujinx {Program.Version} - {LocaleManager.Instance[LocaleKeys.Settings]}";
-
- ViewModel = new SettingsViewModel(virtualFileSystem, contentManager);
- DataContext = ViewModel;
-
- ViewModel.CloseWindow += Close;
- ViewModel.SaveSettingsEvent += SaveSettings;
-
- InitializeComponent();
- Load();
- }
-
- public SettingsWindow()
- {
- ViewModel = new SettingsViewModel();
- DataContext = ViewModel;
-
- InitializeComponent();
- Load();
- }
-
- public void SaveSettings()
- {
- InputPage.ControllerSettings?.SaveCurrentProfile();
-
- if (Owner is MainWindow window && ViewModel.DirectoryChanged)
- {
- window.LoadApplications();
- }
- }
-
- private void Load()
- {
- Pages.Children.Clear();
- NavPanel.SelectionChanged += NavPanelOnSelectionChanged;
- NavPanel.SelectedItem = NavPanel.MenuItems.ElementAt(0);
- }
-
- private void NavPanelOnSelectionChanged(object sender, NavigationViewSelectionChangedEventArgs e)
- {
- if (e.SelectedItem is NavigationViewItem navItem && navItem.Tag is not null)
- {
- switch (navItem.Tag.ToString())
- {
- case "UiPage":
- UiPage.ViewModel = ViewModel;
- NavPanel.Content = UiPage;
- break;
- case "InputPage":
- NavPanel.Content = InputPage;
- break;
- case "HotkeysPage":
- NavPanel.Content = HotkeysPage;
- break;
- case "SystemPage":
- SystemPage.ViewModel = ViewModel;
- NavPanel.Content = SystemPage;
- break;
- case "CpuPage":
- NavPanel.Content = CpuPage;
- break;
- case "GraphicsPage":
- NavPanel.Content = GraphicsPage;
- break;
- case "AudioPage":
- NavPanel.Content = AudioPage;
- break;
- case "NetworkPage":
- NavPanel.Content = NetworkPage;
- break;
- case "LoggingPage":
- NavPanel.Content = LoggingPage;
- break;
- default:
- throw new NotImplementedException();
- }
- }
- }
-
- protected override void OnClosing(WindowClosingEventArgs e)
- {
- HotkeysPage.Dispose();
- InputPage.Dispose();
- base.OnClosing(e);
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Windows/StyleableWindow.cs b/src/Ryujinx.Ava/UI/Windows/StyleableWindow.cs
deleted file mode 100644
index a12d2b3e..00000000
--- a/src/Ryujinx.Ava/UI/Windows/StyleableWindow.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Controls.Primitives;
-using Avalonia.Media;
-using Avalonia.Media.Imaging;
-using Avalonia.Platform;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.UI.Common.Configuration;
-using System.IO;
-using System.Reflection;
-
-namespace Ryujinx.Ava.UI.Windows
-{
- public class StyleableWindow : Window
- {
- public Bitmap IconImage { get; set; }
-
- public StyleableWindow()
- {
- WindowStartupLocation = WindowStartupLocation.CenterOwner;
- TransparencyLevelHint = new[] { WindowTransparencyLevel.None };
-
- using Stream stream = Assembly.GetAssembly(typeof(ConfigurationState)).GetManifestResourceStream("Ryujinx.UI.Common.Resources.Logo_Ryujinx.png");
-
- Icon = new WindowIcon(stream);
- stream.Position = 0;
- IconImage = new Bitmap(stream);
-
- LocaleManager.Instance.LocaleChanged += LocaleChanged;
- LocaleChanged();
- }
-
- private void LocaleChanged()
- {
- FlowDirection = LocaleManager.Instance.IsRTL() ? FlowDirection.RightToLeft : FlowDirection.LeftToRight;
- }
-
- protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
- {
- base.OnApplyTemplate(e);
-
- ExtendClientAreaChromeHints = ExtendClientAreaChromeHints.SystemChrome | ExtendClientAreaChromeHints.OSXThickTitleBar;
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml b/src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml
deleted file mode 100644
index 3eff389f..00000000
--- a/src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml
+++ /dev/null
@@ -1,133 +0,0 @@
-<UserControl
- x:Class="Ryujinx.Ava.UI.Windows.TitleUpdateWindow"
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- xmlns:models="clr-namespace:Ryujinx.Ava.UI.Models"
- xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
- Width="500"
- Height="300"
- mc:Ignorable="d"
- x:DataType="viewModels:TitleUpdateViewModel"
- Focusable="True">
- <Grid>
- <Grid.RowDefinitions>
- <RowDefinition Height="*" />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <Border
- Grid.Row="0"
- Margin="0 0 0 24"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- BorderBrush="{DynamicResource AppListHoverBackgroundColor}"
- BorderThickness="1"
- CornerRadius="5"
- Padding="2.5">
- <ListBox
- Background="Transparent"
- SelectedItem="{Binding SelectedUpdate, Mode=TwoWay}"
- ItemsSource="{Binding Views}">
- <ListBox.DataTemplates>
- <DataTemplate
- DataType="models:TitleUpdateModel">
- <Panel Margin="10">
- <TextBlock
- HorizontalAlignment="Left"
- VerticalAlignment="Center"
- TextWrapping="Wrap"
- Text="{Binding Label}" />
- <StackPanel
- Spacing="10"
- Orientation="Horizontal"
- HorizontalAlignment="Right">
- <Button
- VerticalAlignment="Center"
- HorizontalAlignment="Right"
- Padding="10"
- MinWidth="0"
- MinHeight="0"
- Click="OpenLocation">
- <ui:SymbolIcon
- Symbol="OpenFolder"
- HorizontalAlignment="Center"
- VerticalAlignment="Center" />
- </Button>
- <Button
- VerticalAlignment="Center"
- HorizontalAlignment="Right"
- Padding="10"
- MinWidth="0"
- MinHeight="0"
- Click="RemoveUpdate">
- <ui:SymbolIcon
- Symbol="Cancel"
- HorizontalAlignment="Center"
- VerticalAlignment="Center" />
- </Button>
- </StackPanel>
- </Panel>
- </DataTemplate>
- <DataTemplate
- DataType="viewModels:BaseModel">
- <Panel
- Height="33"
- Margin="10">
- <TextBlock
- HorizontalAlignment="Left"
- VerticalAlignment="Center"
- TextWrapping="Wrap"
- Text="{locale:Locale NoUpdate}" />
- </Panel>
- </DataTemplate>
- </ListBox.DataTemplates>
- <ListBox.Styles>
- <Style Selector="ListBoxItem">
- <Setter Property="Background" Value="Transparent" />
- </Style>
- </ListBox.Styles>
- </ListBox>
- </Border>
- <Panel
- Grid.Row="1"
- HorizontalAlignment="Stretch">
- <StackPanel
- Orientation="Horizontal"
- Spacing="10"
- HorizontalAlignment="Left">
- <Button
- Name="AddButton"
- MinWidth="90"
- Command="{Binding Add}">
- <TextBlock Text="{locale:Locale SettingsTabGeneralAdd}" />
- </Button>
- <Button
- Name="RemoveAllButton"
- MinWidth="90"
- Click="RemoveAll">
- <TextBlock Text="{locale:Locale DlcManagerRemoveAllButton}" />
- </Button>
- </StackPanel>
- <StackPanel
- Orientation="Horizontal"
- Spacing="10"
- HorizontalAlignment="Right">
- <Button
- Name="SaveButton"
- MinWidth="90"
- Click="Save">
- <TextBlock Text="{locale:Locale SettingsButtonSave}" />
- </Button>
- <Button
- Name="CancelButton"
- MinWidth="90"
- Click="Close">
- <TextBlock Text="{locale:Locale InputDialogCancel}" />
- </Button>
- </StackPanel>
- </Panel>
- </Grid>
-</UserControl>
diff --git a/src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml.cs b/src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml.cs
deleted file mode 100644
index f3ac6960..00000000
--- a/src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml.cs
+++ /dev/null
@@ -1,96 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Interactivity;
-using Avalonia.Styling;
-using FluentAvalonia.UI.Controls;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.Models;
-using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.HLE.FileSystem;
-using Ryujinx.UI.Common.Helper;
-using System.Threading.Tasks;
-using Button = Avalonia.Controls.Button;
-
-namespace Ryujinx.Ava.UI.Windows
-{
- public partial class TitleUpdateWindow : UserControl
- {
- public TitleUpdateViewModel ViewModel;
-
- public TitleUpdateWindow()
- {
- DataContext = this;
-
- InitializeComponent();
- }
-
- public TitleUpdateWindow(VirtualFileSystem virtualFileSystem, ulong titleId)
- {
- DataContext = ViewModel = new TitleUpdateViewModel(virtualFileSystem, titleId);
-
- InitializeComponent();
- }
-
- public static async Task Show(VirtualFileSystem virtualFileSystem, ulong titleId, string titleName)
- {
- ContentDialog contentDialog = new()
- {
- PrimaryButtonText = "",
- SecondaryButtonText = "",
- CloseButtonText = "",
- Content = new TitleUpdateWindow(virtualFileSystem, titleId),
- Title = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.GameUpdateWindowHeading, titleName, titleId.ToString("X16")),
- };
-
- Style bottomBorder = new(x => x.OfType<Grid>().Name("DialogSpace").Child().OfType<Border>());
- bottomBorder.Setters.Add(new Setter(IsVisibleProperty, false));
-
- contentDialog.Styles.Add(bottomBorder);
-
- await ContentDialogHelper.ShowAsync(contentDialog);
- }
-
- private void Close(object sender, RoutedEventArgs e)
- {
- ((ContentDialog)Parent).Hide();
- }
-
- public void Save(object sender, RoutedEventArgs e)
- {
- ViewModel.Save();
-
- if (VisualRoot is MainWindow window)
- {
- window.LoadApplications();
- }
-
- ((ContentDialog)Parent).Hide();
- }
-
- private void OpenLocation(object sender, RoutedEventArgs e)
- {
- if (sender is Button button)
- {
- if (button.DataContext is TitleUpdateModel model)
- {
- OpenHelper.LocateFile(model.Path);
- }
- }
- }
-
- private void RemoveUpdate(object sender, RoutedEventArgs e)
- {
- if (sender is Button button)
- {
- ViewModel.RemoveUpdate((TitleUpdateModel)button.DataContext);
- }
- }
-
- private void RemoveAll(object sender, RoutedEventArgs e)
- {
- ViewModel.TitleUpdates.Clear();
-
- ViewModel.SortUpdates();
- }
- }
-}