aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIsaac Marovitz <42140194+IsaacMarovitz@users.noreply.github.com>2023-08-12 01:47:22 +0100
committerGitHub <noreply@github.com>2023-08-12 02:47:22 +0200
commit7b2225c6b0939b9720c56a89cb0c91311b2e19e5 (patch)
treeb4f44692dc843b720ae73c94688d51f7dc9a0ae4 /src
parentfe15c77d30b94a8b720b520dcacf39a0c832d58f (diff)
Ava UI: Avalonia 11 & FluentAvalonia 2 Support (#4362)1.1.980
* It builds (Doesn’t run waiting on FluentAvalonia Preview 5 Release) * Enable CompiledBindings by default * Ignore `PointerPressedEventArgs` Init warning * Define MIME and UTI Types * Update `UserProfileImageSelectorView` to StorageProvider API * PFS0 Magic * Update `MainWindowViewModel` to StorageProvider API * Update `SettingsUIView` to StorageProvider API * Update `ApplicationHelper` to StorageProvider API * Use `IsCheckChanged` * Rename events * Update Fluent Avalonia to Preivew 5 * More package updates * Fix long selection bar * return glyph value directly, instead of using a binding * fix menu item checkboxes * Fix build * Update to Preview 6 Unicorn conflict Fix remaining package oopsie * Fix issues from merge * Fix some warnings * Warnings * Squashed commit of the following: commit 79d1c190dba48e405a833f654691e47509a29792 Author: Mary <mary@mary.zone> Date: Sun Apr 16 11:38:07 2023 +0200 chore: Update Silk.NET to 2.17.1 (#4686) commit 2bc88467eb377a0ca1a8b51700300422422c8c37 Author: Ac_K <Acoustik666@gmail.com> Date: Sun Apr 16 09:37:31 2023 +0000 Update README.md commit baf8752e74488a419074ae1d484e54a00bc01973 Author: Vincenzo Nizza <vincenzonizzaufficio@gmail.com> Date: Sun Apr 16 11:19:33 2023 +0200 Ensure the updater doesn't delete hidden or system files (#4626) * Copy desktop.ini to update directory if it exists in HomeDir * EnumerateFilesToDelete() exclude files with "Hidden" and "System" attributes commit d5e4378aea086d9219f890e33cf81d566d96b9ae Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun Apr 16 09:02:06 2023 +0000 nuget: bump DynamicData from 7.13.1 to 7.13.5 (#4654) Bumps [DynamicData](https://github.com/reactiveui/DynamicData) from 7.13.1 to 7.13.5. - [Release notes](https://github.com/reactiveui/DynamicData/releases) - [Changelog](https://github.com/reactivemarbles/DynamicData/blob/main/ReleaseNotes.md) - [Commits](https://github.com/reactiveui/DynamicData/compare/7.13.1...7.13.5) --- updated-dependencies: - dependency-name: DynamicData dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit 6dbcdfea47e60aadefd59a75e43549793481f853 Author: TSRBerry <20988865+TSRBerry@users.noreply.github.com> Date: Sun Apr 16 09:09:02 2023 +0200 Ava: Fix nca extraction window never closing & minor cleanup (#4569) * ava: Remove unused doWhileDeferred parameters * ava: Minimally improve swkbd dialog It's currently impossible to get the dialog to redirect focus to the InputBox. * ava: Fix nca extraction dialog never closing Also contains some minor cleanup commit c5258cf082b10f335f81487f22b7eeb86075e09e Author: NitroTears <73270647+NitroTears@users.noreply.github.com> Date: Sun Apr 16 11:03:35 2023 +1000 Ability to hide file types in Game List (#4555) * Added HiddenFileTypes to config state, and check to file enumeration * Added hiddenfiletypes checkboxes to the UI * Added Ava version of HiddenFileTypes * Inverted Hide to Show with file types, minor formatting * all variables with a reference to 'hidden' is now 'shown' * one more variable name changed * review feedback * added FileTypes extension methof to get the correlating config value * moved extension method to new folder and file in Ryujinx.Ui.Common * added default case for ToggleFileType * changed exception type to OutOfRangeException commit 5c89e22bb98072adc240c2eb2d26d25fa119fe7d Author: Daniel Shala <daniel.shala08@gmail.com> Date: Sat Apr 15 18:11:24 2023 +0200 Added check for eventual symlink when displaying game files. (#4526) * Added check for eventual symlink when displaying game files. * Moved symlink check logic * Moved symlink check logic * Fixed prev commit --------- Co-authored-by: Daniel Shala <danielshala00@gmail.com> commit 11ecff2ff04633d261b9a43db792f6438df63f40 Author: Alex Barney <thealexbarney@gmail.com> Date: Fri Apr 14 16:00:34 2023 -0700 Rename Hipc to Cmif where appropriate (#3880) commit 4c3f09644a033dbf70258c4c0e5a848263b16bbd Author: MutantAura <44103205+MutantAura@users.noreply.github.com> Date: Wed Apr 12 20:18:40 2023 +0100 Move swkbd message null check into constructor (#4671) commit e187a8870a6f19ac0a85b08aece3c1a1e196e379 Author: TSRBerry <20988865+TSRBerry@users.noreply.github.com> Date: Wed Apr 12 03:09:47 2023 +0200 HLE: Deal with empty title names properly (#4643) * hle: Deal with empty titleNames in some languages * gui: Fix displaying the wrong title name * Remove unnecessary bounds check * Fix a NRE when getting the version string * Restore empty string logic commit a64fee29dc6b8e523d61abb7e79ceaa95a558c6c Author: riperiperi <rhy3756547@hotmail.com> Date: Tue Apr 11 08:23:41 2023 +0100 Vulkan: add situational "Fast Flush" mode (#4667) * Flush in the middle of long command buffers. * Vulkan: add situational "Fast Flush" mode The AutoFlushCounter class was added to periodically flush Vulkan command buffers throughout a frame, which reduces latency to the GPU as commands are submitted and processed much sooner. This was done by allowing command buffers to flush when framebuffer attachments changed. However, some games have incredibly long render passes with a large number of draws, and really aggressive data access that forces GPU sync. The Vulkan backend could potentially end up building a single command buffer for 4-5ms if a pass has enough draws, such as in BOTW. In the scenario where sync is waited on immediately after submission, this would have to wait for the completion of a much longer command buffer than usual. The solution is to force command buffer submission periodically in a "fast flush" mode. This will end up splitting render passes, but it will only enable if sync is aggressive enough. This should improve performance in GPU limited scenarios, or in games that aggressively wait on synchronization. In some games, it may only kick in when res scaling. It won't trigger in games like SMO where sync is not an issue. Improves performance in Pokemon Scarlet/Violet (res scaled) and BOTW (in general). * Add conversions in milliseconds next to flush timers. commit 9ef94c8292beda825fa76e05ad2e561c6d571c95 Author: riperiperi <rhy3756547@hotmail.com> Date: Tue Apr 11 07:55:04 2023 +0100 ARMeilleure: Move TPIDR_EL0 and TPIDRRO_EL0 to NativeContext (#4661) * ARMeilleure: Move TPIDR_EL0 and TPIDRRO_EL0 to NativeContext Some games access these system registers several tens of thousands of times in a second from many different threads. While this isn't really crippling, it is a lot of wasted time spent in a reverse pinvoke transition. Example games are Pokemon Scarlet/Violet and BOTW. These games have a lot of different potential bottlenecks so it's unlikely you will see a consistent improvement, but it definitely disappears from the cpu profile. * Remove unreachable code. * Add ulong conversion for offsets * Nit commit 915d6d044cbf8c89935f14b8c7e085ad729f0e28 Author: riperiperi <rhy3756547@hotmail.com> Date: Tue Apr 11 07:32:31 2023 +0100 OpenGL: Fix OBS/Overlays again by binding FB before present (#4668) This seems to have been removed by the Post-Processing PR, but it is required for the display in OBS to be the right way up and properly scaled. I've tested this with AA and FSR on MK8D and it seems to behave properly. Testing is welcome. commit a4780ab33b9ca6b698917ded3ef6db6e6716cad1 Author: MutantAura <44103205+MutantAura@users.noreply.github.com> Date: Mon Apr 10 23:04:31 2023 +0100 Force activate parent window before dialog is shown (#4663) * Fix build Extraction dialogue not working * Avalonia Preview 7 Needs Fluent Avalonia update still… * Fix Render Scaling * Update Fluent Avalonia * Remove `pfs0` as runnable file type * Restore Info.plist formatting * Plist Format * Update Avalonia.Svg.Skia * Update theme code (TODO) * swtich to using theme variants for light dark * Fix crashes * Text centering issues * Update `TitleUpdateViewModel` to StorageProvider API * Fixed for new PR (Will crash on launch) * Fixes… * UI: Fix sections extraction (#4820) * UI: Fix sections extraction There is currently an issue when the update NCA doesn't contains the section we want to extract, this is fixed by adding a check. I have fixed the inverted handler of ExeFs/Logo introduced in #4755. Fixes #4521 * Addresses feedback * Fix issues… * Preview 8 * Fix fuck ups * Fixes * More cleanup * Ava 11 RC Maybe there is a god * Update FluentAvalonia * update svg * Second RC (kill me) * It builds * Ava 11 * Remove unnecessary usings * Fix build * Formatting * GAS GAS GAS!!!! * Fix DLC Window Crash * Linux runner try not to crash challenge (impossible) * Add app.manifest * Fix accidental Silk.NET.Vulkan bump * Try fix truncation * Linux fix popup Windows * Fix cutoff text on windows * Status bar styling fixes * Volume Toggle Split Button Fixes * Fix load bar color * Fix shortcuts * Best we're gonna get * Fix spacing Co-authored-by: Exhigh <exhigh01@gmail.com> * Formatting * Fix Profile Dropdown * Fix Window Startup Position * Format Fixes * Fix stupid mistake * Fix accidental change * Scaling Handler (peri pls make sure is working) * Remove Locale Reflection Binding Use + Unsued Usings * Fix formatting Code styling Ughhhh Fix interface Make TimeZoneConverter internal * Remove bell workaround (no longer needed) * Disable accent menu * Update to Ava 11.0.2 * Peri suggestions * Formatting * Cleanup a bunch of jank * Dependency update * Berry fixes and suggestions * Final suggestions * Rename assemblyIdentity to Ryujinx.Emulator.Avalonia --------- Co-authored-by: Emmanuel Hansen <emmausssss@gmail.com> Co-authored-by: Ac_K <Acoustik666@gmail.com> Co-authored-by: Exhigh <exhigh01@gmail.com> Co-authored-by: TSR Berry <20988865+TSRBerry@users.noreply.github.com>
Diffstat (limited to 'src')
-rw-r--r--src/Ryujinx.Ava/App.axaml8
-rw-r--r--src/Ryujinx.Ava/App.axaml.cs39
-rw-r--r--src/Ryujinx.Ava/AppHost.cs41
-rw-r--r--src/Ryujinx.Ava/Assets/Styles/BaseDark.xaml65
-rw-r--r--src/Ryujinx.Ava/Assets/Styles/BaseLight.xaml57
-rw-r--r--src/Ryujinx.Ava/Assets/Styles/Styles.xaml361
-rw-r--r--src/Ryujinx.Ava/Assets/Styles/Themes.xaml85
-rw-r--r--src/Ryujinx.Ava/Common/ApplicationHelper.cs225
-rw-r--r--src/Ryujinx.Ava/Input/AvaloniaKeyboardDriver.cs7
-rw-r--r--src/Ryujinx.Ava/Program.cs9
-rw-r--r--src/Ryujinx.Ava/Ryujinx.Ava.csproj13
-rw-r--r--src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml2
-rw-r--r--src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml.cs10
-rw-r--r--src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml6
-rw-r--r--src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml4
-rw-r--r--src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs18
-rw-r--r--src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml22
-rw-r--r--src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs8
-rw-r--r--src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml18
-rw-r--r--src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs8
-rw-r--r--src/Ryujinx.Ava/UI/Helpers/GlyphValueConverter.cs10
-rw-r--r--src/Ryujinx.Ava/UI/Helpers/HotKeyControl.cs52
-rw-r--r--src/Ryujinx.Ava/UI/Helpers/LoggerAdapter.cs15
-rw-r--r--src/Ryujinx.Ava/UI/Helpers/OffscreenTextBox.cs1
-rw-r--r--src/Ryujinx.Ava/UI/Helpers/TimeZoneConverter.cs28
-rw-r--r--src/Ryujinx.Ava/UI/Models/UserProfile.cs4
-rw-r--r--src/Ryujinx.Ava/UI/Renderer/EmbeddedWindow.cs14
-rw-r--r--src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml.cs10
-rw-r--r--src/Ryujinx.Ava/UI/ViewModels/AboutWindowViewModel.cs19
-rw-r--r--src/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs36
-rw-r--r--src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs215
-rw-r--r--src/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs37
-rw-r--r--src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml19
-rw-r--r--src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml.cs69
-rw-r--r--src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml1
-rw-r--r--src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml1
-rw-r--r--src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml89
-rw-r--r--src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs6
-rw-r--r--src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml39
-rw-r--r--src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml.cs6
-rw-r--r--src/Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml13
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsAudioView.axaml3
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsCPUView.axaml1
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml5
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml5
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml.cs2
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml1
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsLoggingView.axaml1
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsNetworkView.axaml3
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsSystemView.axaml110
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsSystemView.axaml.cs19
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml3
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml.cs40
-rw-r--r--src/Ryujinx.Ava/UI/Views/User/UserEditorView.axaml1
-rw-r--r--src/Ryujinx.Ava/UI/Views/User/UserFirmwareAvatarSelectorView.axaml5
-rw-r--r--src/Ryujinx.Ava/UI/Views/User/UserProfileImageSelectorView.axaml1
-rw-r--r--src/Ryujinx.Ava/UI/Views/User/UserProfileImageSelectorView.axaml.cs38
-rw-r--r--src/Ryujinx.Ava/UI/Views/User/UserRecovererView.axaml3
-rw-r--r--src/Ryujinx.Ava/UI/Views/User/UserSaveManagerView.axaml6
-rw-r--r--src/Ryujinx.Ava/UI/Views/User/UserSelectorView.axaml9
-rw-r--r--src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml7
-rw-r--r--src/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml15
-rw-r--r--src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml12
-rw-r--r--src/Ryujinx.Ava/UI/Windows/ContentDialogOverlayWindow.axaml.cs9
-rw-r--r--src/Ryujinx.Ava/UI/Windows/DownloadableContentManagerWindow.axaml8
-rw-r--r--src/Ryujinx.Ava/UI/Windows/MainWindow.axaml20
-rw-r--r--src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs65
-rw-r--r--src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml29
-rw-r--r--src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml.cs6
-rw-r--r--src/Ryujinx.Ava/UI/Windows/StyleableWindow.cs4
-rw-r--r--src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml6
-rw-r--r--src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml.cs2
-rw-r--r--src/Ryujinx.Ava/app.manifest10
73 files changed, 1103 insertions, 1036 deletions
diff --git a/src/Ryujinx.Ava/App.axaml b/src/Ryujinx.Ava/App.axaml
index 72bc0dee..eab318b7 100644
--- a/src/Ryujinx.Ava/App.axaml
+++ b/src/Ryujinx.Ava/App.axaml
@@ -3,7 +3,15 @@
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sty="using:FluentAvalonia.Styling">
+ <Application.Resources>
+ <ResourceDictionary>
+ <ResourceDictionary.MergedDictionaries>
+ <MergeResourceInclude Source="/Assets/Styles/Themes.xaml"/>
+ </ResourceDictionary.MergedDictionaries>
+ </ResourceDictionary>
+ </Application.Resources>
<Application.Styles>
<sty:FluentAvaloniaTheme PreferSystemTheme="False" />
+ <StyleInclude Source="/Assets/Styles/Styles.xaml"/>
</Application.Styles>
</Application> \ No newline at end of file
diff --git a/src/Ryujinx.Ava/App.axaml.cs b/src/Ryujinx.Ava/App.axaml.cs
index 4ecc424a..031e7e44 100644
--- a/src/Ryujinx.Ava/App.axaml.cs
+++ b/src/Ryujinx.Ava/App.axaml.cs
@@ -3,7 +3,6 @@ using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using Avalonia.Styling;
using Avalonia.Threading;
-using FluentAvalonia.Styling;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Windows;
@@ -24,6 +23,11 @@ namespace Ryujinx.Ava
Name = $"Ryujinx {Program.Version}";
AvaloniaXamlLoader.Load(this);
+
+ if (OperatingSystem.IsMacOS())
+ {
+ Process.Start("/usr/bin/defaults", "write org.ryujinx.Ryujinx ApplePressAndHoldEnabled -bool false");
+ }
}
public override void OnFrameworkInitializationCompleted()
@@ -89,8 +93,6 @@ namespace Ryujinx.Ava
string themePath = ConfigurationState.Instance.Ui.CustomThemePath;
bool enableCustomTheme = ConfigurationState.Instance.Ui.EnableCustomTheme;
- const string BaseStyleUrl = "avares://Ryujinx.Ava/Assets/Styles/Base{0}.xaml";
-
if (string.IsNullOrWhiteSpace(baseStyle))
{
ConfigurationState.Instance.Ui.BaseStyle.Value = "Dark";
@@ -98,31 +100,12 @@ namespace Ryujinx.Ava
baseStyle = ConfigurationState.Instance.Ui.BaseStyle;
}
- var theme = AvaloniaLocator.Current.GetService<FluentAvaloniaTheme>();
-
- theme.RequestedTheme = baseStyle;
-
- var currentStyles = this.Styles;
-
- // Remove all styles except the base style.
- if (currentStyles.Count > 1)
+ RequestedThemeVariant = baseStyle switch
{
- currentStyles.RemoveRange(1, currentStyles.Count - 1);
- }
-
- IStyle newStyles = null;
-
- // Load requested style, and fallback to Dark theme if loading failed.
- try
- {
- newStyles = (Styles)AvaloniaXamlLoader.Load(new Uri(string.Format(BaseStyleUrl, baseStyle), UriKind.Absolute));
- }
- catch (XamlLoadException)
- {
- newStyles = (Styles)AvaloniaXamlLoader.Load(new Uri(string.Format(BaseStyleUrl, "Dark"), UriKind.Absolute));
- }
-
- currentStyles.Add(newStyles);
+ "Light" => ThemeVariant.Light,
+ "Dark" => ThemeVariant.Dark,
+ _ => ThemeVariant.Default
+ };
if (enableCustomTheme)
{
@@ -133,7 +116,7 @@ namespace Ryujinx.Ava
var themeContent = File.ReadAllText(themePath);
var customStyle = AvaloniaRuntimeXamlLoader.Parse<IStyle>(themeContent);
- currentStyles.Add(customStyle);
+ Styles.Add(customStyle);
}
catch (Exception ex)
{
diff --git a/src/Ryujinx.Ava/AppHost.cs b/src/Ryujinx.Ava/AppHost.cs
index 786b4507..a8388e9c 100644
--- a/src/Ryujinx.Ava/AppHost.cs
+++ b/src/Ryujinx.Ava/AppHost.cs
@@ -3,6 +3,7 @@ using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Input;
+using Avalonia.Rendering;
using Avalonia.Threading;
using LibHac.Tools.FsSystem;
using Ryujinx.Audio.Backends.Dummy;
@@ -54,6 +55,7 @@ using static Ryujinx.Ava.UI.Helpers.Win32NativeInterop;
using AntiAliasing = Ryujinx.Common.Configuration.AntiAliasing;
using Image = SixLabors.ImageSharp.Image;
using InputManager = Ryujinx.Input.HLE.InputManager;
+using IRenderer = Ryujinx.Graphics.GAL.IRenderer;
using Key = Ryujinx.Input.Key;
using MouseButton = Ryujinx.Input.MouseButton;
using ScalingFilter = Ryujinx.Common.Configuration.ScalingFilter;
@@ -167,9 +169,9 @@ namespace Ryujinx.Ava
ConfigurationState.Instance.HideCursor.Event += HideCursorState_Changed;
- _topLevel.PointerMoved += TopLevel_PointerEnterOrMoved;
- _topLevel.PointerEnter += TopLevel_PointerEnterOrMoved;
- _topLevel.PointerLeave += TopLevel_PointerLeave;
+ _topLevel.PointerMoved += TopLevel_PointerEnteredOrMoved;
+ _topLevel.PointerEntered += TopLevel_PointerEnteredOrMoved;
+ _topLevel.PointerExited += TopLevel_PointerExited;
if (OperatingSystem.IsWindows())
{
@@ -194,26 +196,23 @@ namespace Ryujinx.Ava
_gpuDoneEvent = new ManualResetEvent(false);
}
- private void TopLevel_PointerEnterOrMoved(object sender, PointerEventArgs e)
+ private void TopLevel_PointerEnteredOrMoved(object sender, PointerEventArgs e)
{
if (sender is MainWindow window)
{
_lastCursorMoveTime = Stopwatch.GetTimestamp();
- if (RendererHost.EmbeddedWindow.TransformedBounds != null)
- {
- var point = e.GetCurrentPoint(window).Position;
- var bounds = RendererHost.EmbeddedWindow.TransformedBounds.Value.Clip;
+ var point = e.GetCurrentPoint(window).Position;
+ var bounds = RendererHost.EmbeddedWindow.Bounds;
- _isCursorInRenderer = point.X >= bounds.X &&
- point.X <= bounds.Width + bounds.X &&
- point.Y >= bounds.Y &&
- point.Y <= bounds.Height + bounds.Y;
- }
+ _isCursorInRenderer = point.X >= bounds.X &&
+ point.X <= bounds.Width + bounds.X &&
+ point.Y >= bounds.Y &&
+ point.Y <= bounds.Height + bounds.Y;
}
}
- private void TopLevel_PointerLeave(object sender, PointerEventArgs e)
+ private void TopLevel_PointerExited(object sender, PointerEventArgs e)
{
_isCursorInRenderer = false;
}
@@ -265,7 +264,7 @@ namespace Ryujinx.Ava
{
if (_renderer != null)
{
- double scale = _topLevel.PlatformImpl.RenderScaling;
+ double scale = _topLevel.RenderScaling;
_renderer.Window?.SetSize((int)(size.Width * scale), (int)(size.Height * scale));
}
@@ -359,7 +358,7 @@ namespace Ryujinx.Ava
_viewModel.SetUiProgressHandlers(Device);
- RendererHost.SizeChanged += Window_SizeChanged;
+ RendererHost.BoundsChanged += Window_BoundsChanged;
_isActive = true;
@@ -469,9 +468,9 @@ namespace Ryujinx.Ava
ConfigurationState.Instance.Graphics.AntiAliasing.Event -= UpdateAntiAliasing;
ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough.Event -= UpdateColorSpacePassthrough;
- _topLevel.PointerMoved -= TopLevel_PointerEnterOrMoved;
- _topLevel.PointerEnter -= TopLevel_PointerEnterOrMoved;
- _topLevel.PointerLeave -= TopLevel_PointerLeave;
+ _topLevel.PointerMoved -= TopLevel_PointerEnteredOrMoved;
+ _topLevel.PointerEntered -= TopLevel_PointerEnteredOrMoved;
+ _topLevel.PointerExited -= TopLevel_PointerExited;
_gpuCancellationTokenSource.Cancel();
_gpuCancellationTokenSource.Dispose();
@@ -849,7 +848,7 @@ namespace Ryujinx.Ava
return deviceDriver;
}
- private void Window_SizeChanged(object sender, Size e)
+ private void Window_BoundsChanged(object sender, Size e)
{
Width = (int)e.Width;
Height = (int)e.Height;
@@ -899,7 +898,7 @@ namespace Ryujinx.Ava
Width = (int)RendererHost.Bounds.Width;
Height = (int)RendererHost.Bounds.Height;
- _renderer.Window.SetSize((int)(Width * _topLevel.PlatformImpl.RenderScaling), (int)(Height * _topLevel.PlatformImpl.RenderScaling));
+ _renderer.Window.SetSize((int)(Width * _topLevel.RenderScaling), (int)(Height * _topLevel.RenderScaling));
_chrono.Start();
diff --git a/src/Ryujinx.Ava/Assets/Styles/BaseDark.xaml b/src/Ryujinx.Ava/Assets/Styles/BaseDark.xaml
deleted file mode 100644
index c7f6266f..00000000
--- a/src/Ryujinx.Ava/Assets/Styles/BaseDark.xaml
+++ /dev/null
@@ -1,65 +0,0 @@
-<Styles xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
- <StyleInclude Source="avares://Ryujinx.Ava/Assets/Styles/Styles.xaml" />
- <Design.PreviewWith>
- <Border Height="2000" Padding="20">
- <StackPanel Spacing="5">
- <TextBlock Text="Code Font Family" />
- <Grid RowDefinitions="*,Auto">
- <Menu Grid.Row="1" Width="100">
- <MenuItem Header="File">
- <MenuItem Header="Test 1" />
- <MenuItem Header="Test 2" />
- <MenuItem Header="Test 3">
- <MenuItem.Icon>
- <CheckBox Margin="0" IsChecked="{Binding Checkbox, Mode=TwoWay}" />
- </MenuItem.Icon>
- </MenuItem>
- </MenuItem>
- </Menu>
- <StackPanel Orientation="Horizontal">
- <Button
- Name="btnAdd"
- HorizontalAlignment="Right"
- Content="Add" />
- <Button
- Name="btnRem"
- HorizontalAlignment="Right"
- Content="Add" />
- <TextBox
- Width="100"
- VerticalAlignment="Center"
- Text="Rrrrr"
- UseFloatingWatermark="True"
- Watermark="Hello" />
- <CheckBox>Test Check</CheckBox>
- </StackPanel>
- </Grid>
- </StackPanel>
- </Border>
- </Design.PreviewWith>
- <Styles.Resources>
- <SolidColorBrush x:Key="DataGridSelectionBackgroundBrush" Color="{DynamicResource DataGridSelectionColor}" />
- <SolidColorBrush x:Key="ThemeAccentColorBrush" Color="{DynamicResource SystemAccentColor}" />
- <SolidColorBrush x:Key="ThemeAccentBrush4" Color="{DynamicResource ThemeAccentColor4}" />
- <Color x:Key="ControlFillColorSecondary">#008AA8</Color>
- <SolidColorBrush x:Key="ControlFillColorSecondaryBrush" Color="{StaticResource ControlFillColorSecondary}" />
- <StaticResource x:Key="ButtonBackgroundPointerOver" ResourceKey="ControlFillColorSecondaryBrush" />
- <Color x:Key="SystemAccentColor">#FF00C3E3</Color>
- <Color x:Key="SystemAccentColorDark1">#FF99b000</Color>
- <Color x:Key="SystemAccentColorDark2">#FF006d7d</Color>
- <Color x:Key="SystemAccentColorDark3">#FF00525E</Color>
- <Color x:Key="SystemAccentColorLight1">#FF00dbff</Color>
- <Color x:Key="SystemAccentColorLight2">#FF19dfff</Color>
- <Color x:Key="SystemAccentColorLight3">#FF33e3ff</Color>
- <Color x:Key="DataGridSelectionColor">#FF00FABB</Color>
- <Color x:Key="ThemeContentBackgroundColor">#FF2D2D2D</Color>
- <Color x:Key="ThemeControlBorderColor">#FF505050</Color>
- <Color x:Key="TextOnAccentFillColorPrimary">#FFFFFFFF</Color>
- <Color x:Key="SystemChromeWhiteColor">#FFFFFFFF</Color>
- <Color x:Key="ThemeForegroundColor">#FFFFFFFF</Color>
- <Color x:Key="MenuFlyoutPresenterBorderColor">#3D3D3D</Color>
- <Color x:Key="AppListBackgroundColor">#0FFFFFFF</Color>
- <Color x:Key="AppListHoverBackgroundColor">#1EFFFFFF</Color>
- <Color x:Key="SecondaryTextColor">#A0FFFFFF</Color>
- </Styles.Resources>
-</Styles> \ No newline at end of file
diff --git a/src/Ryujinx.Ava/Assets/Styles/BaseLight.xaml b/src/Ryujinx.Ava/Assets/Styles/BaseLight.xaml
deleted file mode 100644
index 70cb051c..00000000
--- a/src/Ryujinx.Ava/Assets/Styles/BaseLight.xaml
+++ /dev/null
@@ -1,57 +0,0 @@
-<Styles xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
- <StyleInclude Source="avares://Ryujinx.Ava/Assets/Styles/Styles.xaml" />
- <Design.PreviewWith>
- <Border Height="2000" Padding="20">
- <StackPanel Spacing="5">
- <TextBlock Text="Code Font Family" />
- <Grid RowDefinitions="*,Auto">
- <Menu Grid.Row="1" Width="100">
- <MenuItem Header="File">
- <MenuItem Header="Test 1" />
- <MenuItem Header="Test 2" />
- <MenuItem Header="Test 3">
- <MenuItem.Icon>
- <CheckBox Margin="0" IsChecked="{Binding Checkbox, Mode=TwoWay}" />
- </MenuItem.Icon>
- </MenuItem>
- </MenuItem>
- </Menu>
- <StackPanel Orientation="Horizontal">
- <Button
- Name="btnAdd"
- HorizontalAlignment="Right"
- Content="Add" />
- <Button
- Name="btnRem"
- HorizontalAlignment="Right"
- Content="Add" />
- <TextBox
- Width="100"
- VerticalAlignment="Center"
- Text="Rrrrr"
- UseFloatingWatermark="True"
- Watermark="Hello" />
- <CheckBox>Test Check</CheckBox>
- </StackPanel>
- </Grid>
- </StackPanel>
- </Border>
- </Design.PreviewWith>
- <Styles.Resources>
- <SolidColorBrush x:Key="DataGridSelectionBackgroundBrush" Color="{DynamicResource DataGridSelectionColor}" />
- <SolidColorBrush x:Key="ThemeAccentColorBrush" Color="{DynamicResource SystemAccentColor}" />
- <SolidColorBrush x:Key="ThemeAccentBrush4" Color="{DynamicResource ThemeAccentColor4}" />
- <Color x:Key="SystemAccentColor">#FF00C3E3</Color>
- <Color x:Key="ThemeAccentColor4">#FFe8e8e8</Color>
- <Color x:Key="DataGridSelectionColor">#FF00FABB</Color>
- <Color x:Key="ThemeContentBackgroundColor">#FFF0F0F0</Color>
- <Color x:Key="ThemeControlBorderColor">#FFd6d6d6</Color>
- <Color x:Key="TextOnAccentFillColorPrimary">#FFFFFFFF</Color>
- <Color x:Key="SystemChromeWhiteColor">#FFFFFFFF</Color>
- <Color x:Key="ThemeForegroundColor">#FF000000</Color>
- <Color x:Key="MenuFlyoutPresenterBorderColor">#C1C1C1</Color>
- <Color x:Key="AppListBackgroundColor">#b3ffffff</Color>
- <Color x:Key="AppListHoverBackgroundColor">#80cccccc</Color>
- <Color x:Key="SecondaryTextColor">#A0000000</Color>
- </Styles.Resources>
-</Styles> \ No newline at end of file
diff --git a/src/Ryujinx.Ava/Assets/Styles/Styles.xaml b/src/Ryujinx.Ava/Assets/Styles/Styles.xaml
index 681b4fea..146e60b5 100644
--- a/src/Ryujinx.Ava/Assets/Styles/Styles.xaml
+++ b/src/Ryujinx.Ava/Assets/Styles/Styles.xaml
@@ -3,17 +3,20 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia">
<Design.PreviewWith>
- <Border Height="2000" Padding="20">
+ <Border Height="2000"
+ Padding="20">
<StackPanel Spacing="5">
<TextBlock Text="Code Font Family" />
<Grid RowDefinitions="*,Auto">
- <Menu Grid.Row="1" Width="100">
+ <Menu Grid.Row="1"
+ Width="100">
<MenuItem Header="File">
<MenuItem Header="Test 1" />
<MenuItem Header="Test 2" />
<MenuItem Header="Test 3">
<MenuItem.Icon>
- <CheckBox Margin="0" IsChecked="{Binding Checkbox, Mode=TwoWay}" />
+ <CheckBox Margin="0"
+ IsChecked="{ReflectionBinding Checkbox, Mode=TwoWay}" />
</MenuItem.Icon>
</MenuItem>
</MenuItem>
@@ -42,57 +45,80 @@
</Border>
</Design.PreviewWith>
<Style Selector="Border.small">
- <Setter Property="Width" Value="100" />
+ <Setter Property="Width"
+ Value="100" />
</Style>
<Style Selector="Border.normal">
- <Setter Property="Width" Value="130" />
+ <Setter Property="Width"
+ Value="130" />
</Style>
<Style Selector="Border.large">
- <Setter Property="Width" Value="160" />
+ <Setter Property="Width"
+ Value="160" />
</Style>
<Style Selector="Border.huge">
- <Setter Property="Width" Value="200" />
+ <Setter Property="Width"
+ Value="200" />
</Style>
<Style Selector="Border.settings">
- <Setter Property="Background" Value="{DynamicResource ThemeDarkColor}" />
- <Setter Property="BorderBrush" Value="{DynamicResource MenuFlyoutPresenterBorderColor}" />
- <Setter Property="BorderThickness" Value="1" />
- <Setter Property="CornerRadius" Value="5" />
+ <Setter Property="Background"
+ Value="{DynamicResource ThemeDarkColor}" />
+ <Setter Property="BorderBrush"
+ Value="{DynamicResource MenuFlyoutPresenterBorderColor}" />
+ <Setter Property="BorderThickness"
+ Value="1" />
+ <Setter Property="CornerRadius"
+ Value="5" />
</Style>
<Style Selector="Image.small">
- <Setter Property="Width" Value="50" />
+ <Setter Property="Width"
+ Value="50" />
</Style>
<Style Selector="Image.normal">
- <Setter Property="Width" Value="80" />
+ <Setter Property="Width"
+ Value="80" />
</Style>
<Style Selector="Image.large">
- <Setter Property="Width" Value="100" />
+ <Setter Property="Width"
+ Value="100" />
</Style>
<Style Selector="Image.huge">
- <Setter Property="Width" Value="120" />
+ <Setter Property="Width"
+ Value="120" />
</Style>
<Style Selector="#TitleBarHost &gt; Image">
- <Setter Property="Margin" Value="10" />
+ <Setter Property="Margin"
+ Value="10" />
</Style>
<Style Selector="#TitleBarHost &gt; Label">
- <Setter Property="Margin" Value="5" />
- <Setter Property="FontSize" Value="14" />
+ <Setter Property="Margin"
+ Value="5" />
+ <Setter Property="FontSize"
+ Value="14" />
</Style>
<Style Selector="Button.SystemCaption">
- <Setter Property="MinWidth" Value="10" />
+ <Setter Property="MinWidth"
+ Value="10" />
</Style>
<Style Selector="DataGridColumnHeader">
- <Setter Property="Foreground" Value="{DynamicResource ThemeForegroundBrush}" />
- <Setter Property="HorizontalContentAlignment" Value="Center" />
- <Setter Property="BorderThickness" Value="1" />
- <Setter Property="VerticalContentAlignment" Value="Center" />
- <Setter Property="Background" Value="{DynamicResource ThemeControlBorderColor}" />
- <Setter Property="SeparatorBrush" Value="{DynamicResource ThemeControlBorderColor}" />
- <Setter Property="Padding" Value="5" />
- <Setter Property="Background" Value="{DynamicResource ThemeContentBackgroundColor}" />
+ <Setter Property="Foreground"
+ Value="{DynamicResource ThemeForegroundBrush}" />
+ <Setter Property="HorizontalContentAlignment"
+ Value="Center" />
+ <Setter Property="BorderThickness"
+ Value="1" />
+ <Setter Property="VerticalContentAlignment"
+ Value="Center" />
+ <Setter Property="SeparatorBrush"
+ Value="{DynamicResource ThemeControlBorderColor}" />
+ <Setter Property="Padding"
+ Value="5" />
+ <Setter Property="Background"
+ Value="{DynamicResource ThemeContentBackgroundColor}" />
<Setter Property="Template">
<ControlTemplate>
- <Grid Background="{TemplateBinding Background}" ColumnDefinitions="*,Auto">
+ <Grid Background="{TemplateBinding Background}"
+ ColumnDefinitions="*,Auto">
<Grid
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
@@ -122,193 +148,262 @@
</Setter>
</Style>
<Style Selector="DataGrid">
- <Setter Property="RowBackground" Value="{DynamicResource ThemeAccentBrush4}" />
- <Setter Property="AlternatingRowBackground" Value="#00FFFFFF" />
- <Setter Property="Background" Value="{DynamicResource ThemeBackgroundBrush}" />
- <Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderLowColor}" />
- <Setter Property="BorderThickness" Value="{DynamicResource ThemeBorderThickness}" />
+ <Setter Property="RowBackground"
+ Value="{DynamicResource ThemeAccentBrush4}" />
+ <Setter Property="Background"
+ Value="{DynamicResource ThemeBackgroundBrush}" />
+ <Setter Property="BorderBrush"
+ Value="{DynamicResource ThemeBorderLowColor}" />
+ <Setter Property="BorderThickness"
+ Value="{DynamicResource ThemeBorderThickness}" />
</Style>
<Style Selector="DataGridRow:selected:focus /template/ Rectangle#BackgroundRectangle">
- <Setter Property="Fill" Value="{DynamicResource SystemAccentColor}" />
- <Setter Property="Opacity" Value="{DynamicResource DataGridRowSelectedBackgroundOpacity}" />
+ <Setter Property="Fill"
+ Value="{DynamicResource SystemAccentColor}" />
+ <Setter Property="Opacity"
+ Value="{DynamicResource DataGridRowSelectedBackgroundOpacity}" />
</Style>
<Style Selector="DataGridRow:pointerover /template/ Rectangle#BackgroundRectangle">
- <Setter Property="Fill" Value="{DynamicResource SystemListLowColor}" />
+ <Setter Property="Fill"
+ Value="{DynamicResource SystemListLowColor}" />
</Style>
<Style Selector="DataGridRow:selected /template/ Rectangle#BackgroundRectangle">
- <Setter Property="Fill" Value="{DynamicResource SystemAccentColor}" />
- <Setter Property="Opacity" Value="{DynamicResource DataGridRowSelectedUnfocusedBackgroundOpacity}" />
+ <Setter Property="Fill"
+ Value="{DynamicResource SystemAccentColor}" />
+ <Setter Property="Opacity"
+ Value="{DynamicResource DataGridRowSelectedUnfocusedBackgroundOpacity}" />
</Style>
<Style Selector="DataGridRow:selected:pointerover /template/ Rectangle#BackgroundRectangle">
- <Setter Property="Fill" Value="{DynamicResource SystemAccentColor}" />
- <Setter Property="Opacity" Value="{DynamicResource DataGridRowSelectedHoveredUnfocusedBackgroundOpacity}" />
+ <Setter Property="Fill"
+ Value="{DynamicResource SystemAccentColor}" />
+ <Setter Property="Opacity"
+ Value="{DynamicResource DataGridRowSelectedHoveredUnfocusedBackgroundOpacity}" />
</Style>
<Style Selector="DataGridRow:selected:pointerover:focus /template/ Rectangle#BackgroundRectangle">
- <Setter Property="Fill" Value="{DynamicResource SystemAccentColor}" />
- <Setter Property="Opacity" Value="{DynamicResource DataGridRowSelectedHoveredBackgroundOpacity}" />
+ <Setter Property="Fill"
+ Value="{DynamicResource SystemAccentColor}" />
+ <Setter Property="Opacity"
+ Value="{DynamicResource DataGridRowSelectedHoveredBackgroundOpacity}" />
</Style>
<Style Selector="DataGridCell">
- <Setter Property="HorizontalAlignment" Value="Center" />
- <Setter Property="HorizontalContentAlignment" Value="Center" />
+ <Setter Property="HorizontalAlignment"
+ Value="Center" />
+ <Setter Property="HorizontalContentAlignment"
+ Value="Center" />
</Style>
<Style Selector="DataGridCell.Left">
- <Setter Property="HorizontalAlignment" Value="Left" />
+ <Setter Property="HorizontalAlignment"
+ Value="Left" />
</Style>
<Style Selector="CheckBox">
- <Setter Property="BorderThickness" Value="1" />
+ <Setter Property="BorderThickness"
+ Value="1" />
</Style>
<Style Selector="MenuItem">
- <Setter Property="Height" Value="{DynamicResource MenuItemHeight}" />
- <Setter Property="Padding" Value="{DynamicResource MenuItemPadding}" />
- <Setter Property="FontSize" Value="12" />
+ <Setter Property="Height"
+ Value="{DynamicResource MenuItemHeight}" />
+ <Setter Property="Padding"
+ Value="{DynamicResource MenuItemPadding}" />
+ <Setter Property="FontSize"
+ Value="12" />
</Style>
<Style Selector="MenuItem:selected /template/ Border#root">
- <Setter Property="Background" Value="{DynamicResource ThemeControlBorderColor}" />
- <Setter Property="BorderBrush" Value="{DynamicResource ThemeControlBorderColor}" />
+ <Setter Property="Background"
+ Value="{DynamicResource ThemeControlBorderColor}" />
+ <Setter Property="BorderBrush"
+ Value="{DynamicResource ThemeControlBorderColor}" />
</Style>
<Style Selector="TabItem > ScrollViewer">
- <Setter Property="Background" Value="{DynamicResource ThemeBackgroundColor}" />
- <Setter Property="Margin" Value="0,-5,0,0" />
+ <Setter Property="Background"
+ Value="{DynamicResource ThemeBackgroundColor}" />
+ <Setter Property="Margin"
+ Value="0,-5,0,0" />
</Style>
<Style Selector="TabItem > ScrollViewer > Border">
- <Setter Property="BorderThickness" Value="0,1,0,0" />
- <Setter Property="Background" Value="{DynamicResource ThemeBackgroundColor}" />
- <Setter Property="BorderBrush" Value="{DynamicResource HighlightBrush}" />
+ <Setter Property="BorderThickness"
+ Value="0,1,0,0" />
+ <Setter Property="Background"
+ Value="{DynamicResource ThemeBackgroundColor}" />
+ <Setter Property="BorderBrush"
+ Value="{DynamicResource HighlightBrush}" />
</Style>
<Style Selector="Button">
- <Setter Property="MinWidth" Value="80" />
+ <Setter Property="MinWidth"
+ Value="80" />
</Style>
<Style Selector="ProgressBar /template/ Border#ProgressBarTrack">
- <Setter Property="IsVisible" Value="False" />
+ <Setter Property="IsVisible"
+ Value="False" />
</Style>
<Style Selector="ToggleButton">
- <Setter Property="Padding" Value="0,-5,0,0" />
+ <Setter Property="Padding"
+ Value="0,-5,0,0" />
</Style>
<Style Selector="TabItem">
- <Setter Property="FontSize" Value="14" />
- <Setter Property="BorderThickness" Value="0,0,1,0" />
- <Setter Property="BorderBrush" Value="{DynamicResource ThemeButtonForegroundColor}" />
- <Setter Property="Background" Value="{DynamicResource HighlightColor}" />
+ <Setter Property="FontSize"
+ Value="14" />
+ <Setter Property="BorderThickness"
+ Value="0,0,1,0" />
+ <Setter Property="BorderBrush"
+ Value="{DynamicResource ThemeButtonForegroundColor}" />
+ <Setter Property="Background"
+ Value="{DynamicResource SystemAccentColorLight2}" />
</Style>
<Style Selector="TabItem:pointerover">
- <Setter Property="Foreground" Value="{DynamicResource ThemeButtonForegroundColor}" />
+ <Setter Property="Foreground"
+ Value="{DynamicResource ThemeButtonForegroundColor}" />
</Style>
<Style Selector="TabItem:selected">
- <Setter Property="Background" Value="{DynamicResource HighlightColor}" />
- <Setter Property="Foreground" Value="{DynamicResource ThemeBackgroundColor}" />
+ <Setter Property="Background"
+ Value="{DynamicResource SystemAccentColorLight2}" />
+ <Setter Property="Foreground"
+ Value="{DynamicResource ThemeBackgroundColor}" />
</Style>
<Style Selector="TextBlock">
- <Setter Property="Margin" Value="{DynamicResource TextMargin}" />
- <Setter Property="FontSize" Value="{DynamicResource FontSize}" />
- <Setter Property="VerticalAlignment" Value="Center" />
- <Setter Property="TextWrapping" Value="WrapWithOverflow" />
+ <Setter Property="Margin"
+ Value="{DynamicResource TextMargin}" />
+ <Setter Property="FontSize"
+ Value="{DynamicResource FontSize}" />
+ <Setter Property="VerticalAlignment"
+ Value="Center" />
+ <Setter Property="TextWrapping"
+ Value="WrapWithOverflow" />
</Style>
<Style Selector="TextBlock.h1">
- <Setter Property="Margin" Value="{DynamicResource TextMargin}" />
- <Setter Property="VerticalAlignment" Value="Center" />
- <Setter Property="FontWeight" Value="Bold" />
- <Setter Property="FontSize" Value="16" />
- <Setter Property="TextWrapping" Value="WrapWithOverflow" />
+ <Setter Property="Margin"
+ Value="{DynamicResource TextMargin}" />
+ <Setter Property="VerticalAlignment"
+ Value="Center" />
+ <Setter Property="FontWeight"
+ Value="Bold" />
+ <Setter Property="FontSize"
+ Value="16" />
+ <Setter Property="TextWrapping"
+ Value="WrapWithOverflow" />
</Style>
<Style Selector="Separator">
- <Setter Property="Background" Value="{DynamicResource ThemeControlBorderColor}" />
- <Setter Property="Foreground" Value="{DynamicResource ThemeControlBorderColor}" />
- <Setter Property="MinHeight" Value="1" />
+ <Setter Property="Background"
+ Value="{DynamicResource ThemeControlBorderColor}" />
+ <Setter Property="Foreground"
+ Value="{DynamicResource ThemeControlBorderColor}" />
+ <Setter Property="MinHeight"
+ Value="1" />
</Style>
<Style Selector=":is(Button).DateTimeFlyoutButtonStyle">
- <Setter Property="Background" Value="{DynamicResource HighlightColor}" />
- <Setter Property="Foreground" Value="{DynamicResource ThemeBackgroundColor}" />
+ <Setter Property="Background"
+ Value="{DynamicResource SystemAccentColorLight2}" />
+ <Setter Property="Foreground"
+ Value="{DynamicResource ThemeBackgroundColor}" />
</Style>
<Style Selector="DatePickerPresenter">
- <Setter Property="BorderThickness" Value="1" />
- <Setter Property="BorderBrush" Value="{DynamicResource ThemeButtonForegroundColor}" />
+ <Setter Property="BorderThickness"
+ Value="1" />
+ <Setter Property="BorderBrush"
+ Value="{DynamicResource ThemeButtonForegroundColor}" />
</Style>
<Style Selector="DataGridCell">
- <Setter Property="FontSize" Value="14" />
+ <Setter Property="FontSize"
+ Value="14" />
</Style>
<Style Selector="CheckBox TextBlock">
- <Setter Property="Margin" Value="0,5,0,0" />
+ <Setter Property="Margin"
+ Value="0,5,0,0" />
</Style>
<Style Selector="ContextMenu">
- <Setter Property="BorderBrush" Value="{DynamicResource MenuFlyoutPresenterBorderBrush}" />
- <Setter Property="BorderThickness" Value="{DynamicResource MenuFlyoutPresenterBorderThemeThickness}" />
+ <Setter Property="BorderBrush"
+ Value="{DynamicResource MenuFlyoutPresenterBorderBrush}" />
+ <Setter Property="BorderThickness"
+ Value="{DynamicResource MenuFlyoutPresenterBorderThemeThickness}" />
</Style>
<Style Selector="TextBox">
- <Setter Property="VerticalContentAlignment" Value="Center" />
+ <Setter Property="VerticalContentAlignment"
+ Value="Center" />
</Style>
<Style Selector="TextBox.NumberBoxTextBoxStyle">
- <Setter Property="Foreground" Value="{DynamicResource ThemeForegroundColor}" />
+ <Setter Property="Foreground"
+ Value="{DynamicResource ThemeForegroundColor}" />
</Style>
<Style Selector="ListBox ListBoxItem">
- <Setter Property="Padding" Value="0" />
- <Setter Property="Margin" Value="0" />
- <Setter Property="CornerRadius" Value="5" />
- <Setter Property="Background" Value="{DynamicResource AppListBackgroundColor}" />
- <Setter Property="BorderThickness" Value="2"/>
+ <Setter Property="Padding"
+ Value="0" />
+ <Setter Property="Margin"
+ Value="0" />
+ <Setter Property="CornerRadius"
+ Value="5" />
+ <Setter Property="Background"
+ Value="{DynamicResource AppListBackgroundColor}" />
+ <Setter Property="BorderThickness"
+ Value="2"/>
<Style.Animations>
<Animation Duration="0:0:0.7">
<KeyFrame Cue="0%">
- <Setter Property="MaxHeight" Value="0" />
- <Setter Property="Opacity" Value="0.0" />
+ <Setter Property="MaxHeight"
+ Value="0" />
+ <Setter Property="Opacity"
+ Value="0.0" />
</KeyFrame>
<KeyFrame Cue="50%">
- <Setter Property="MaxHeight" Value="1000" />
- <Setter Property="Opacity" Value="0.3" />
+ <Setter Property="MaxHeight"
+ Value="1000" />
+ <Setter Property="Opacity"
+ Value="0.3" />
</KeyFrame>
<KeyFrame Cue="100%">
- <Setter Property="MaxHeight" Value="1000" />
- <Setter Property="Opacity" Value="1.0" />
+ <Setter Property="MaxHeight"
+ Value="1000" />
+ <Setter Property="Opacity"
+ Value="1.0" />
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
<Style Selector="ListBox ListBoxItem:selected /template/ ContentPresenter">
- <Setter Property="Background" Value="{DynamicResource AppListBackgroundColor}" />
+ <Setter Property="Background"
+ Value="{DynamicResource AppListBackgroundColor}" />
+ </Style>
+ <Style Selector="ListBox">
+ <Setter Property="Background"
+ Value="{DynamicResource ThemeContentBackgroundColor}" />
+ </Style>
+ <Style Selector="FlyoutPresenter, ContextMenu, MenuFlyoutPresenter">
+ <Setter Property="BorderBrush"
+ Value="{DynamicResource MenuFlyoutPresenterBorderColor}" />
</Style>
<Style Selector="ListBox ListBoxItem:pointerover /template/ ContentPresenter">
- <Setter Property="Background" Value="{DynamicResource AppListHoverBackgroundColor}" />
+ <Setter Property="Background"
+ Value="{DynamicResource AppListHoverBackgroundColor}" />
</Style>
<Styles.Resources>
- <SolidColorBrush x:Key="ThemeAccentColorBrush" Color="{DynamicResource SystemAccentColor}" />
- <StaticResource x:Key="ListViewItemBackgroundSelected" ResourceKey="ThemeAccentColorBrush" />
- <StaticResource x:Key="ListViewItemBackgroundPressed" ResourceKey="SystemAccentColorDark1" />
- <StaticResource x:Key="ListViewItemBackgroundPointerOver" ResourceKey="SystemAccentColorDark2" />
- <StaticResource x:Key="ListViewItemBackgroundSelectedPressed" ResourceKey="ThemeAccentColorBrush" />
- <StaticResource x:Key="ListViewItemBackgroundSelectedPointerOver" ResourceKey="SystemAccentColorDark2" />
+ <SolidColorBrush x:Key="ThemeAccentColorBrush"
+ Color="{DynamicResource SystemAccentColor}" />
+ <StaticResource x:Key="ListViewItemBackgroundSelected"
+ ResourceKey="ThemeAccentColorBrush" />
+ <StaticResource x:Key="ListViewItemBackgroundPressed"
+ ResourceKey="SystemAccentColorDark1" />
+ <StaticResource x:Key="ListViewItemBackgroundPointerOver"
+ ResourceKey="SystemAccentColorDark2" />
+ <StaticResource x:Key="ListViewItemBackgroundSelectedPressed"
+ ResourceKey="ThemeAccentColorBrush" />
+ <StaticResource x:Key="ListViewItemBackgroundSelectedPointerOver"
+ ResourceKey="SystemAccentColorDark2" />
<SolidColorBrush
x:Key="DataGridGridLinesBrush"
Opacity="0.4"
Color="{DynamicResource SystemBaseMediumLowColor}" />
- <SolidColorBrush x:Key="DataGridSelectionBackgroundBrush" Color="{DynamicResource DataGridSelectionColor}" />
- <SolidColorBrush x:Key="MenuFlyoutPresenterBorderBrush" Color="{DynamicResource MenuFlyoutPresenterBorderColor}" />
- <SolidColorBrush x:Key="FlyoutBorderThemeBrush" Color="{DynamicResource MenuFlyoutPresenterBorderColor}" />
- <SolidColorBrush x:Key="ListBoxBackground" Color="{DynamicResource ThemeContentBackgroundColor}" />
- <SolidColorBrush x:Key="ThemeForegroundBrush" Color="{DynamicResource ThemeForegroundColor}" />
- <SolidColorBrush x:Key="ThemeAccentBrush4" Color="{DynamicResource ThemeAccentColor4}" />
- <SolidColorBrush x:Key="SplitButtonBackgroundChecked" Color="#00E81123" />
- <SolidColorBrush x:Key="SplitButtonBackgroundCheckedPointerOver" Color="#00E81123" />
- <SolidColorBrush x:Key="SplitButtonBackgroundCheckedPressed" Color="#00E81123" />
- <SolidColorBrush x:Key="SplitButtonBackgroundCheckedDisabled" Color="#00E81123" />
+ <SolidColorBrush x:Key="DataGridSelectionBackgroundBrush"
+ Color="{DynamicResource DataGridSelectionColor}" />
+ <SolidColorBrush x:Key="SplitButtonBackgroundChecked"
+ Color="#00E81123" />
+ <SolidColorBrush x:Key="SplitButtonBackgroundCheckedPointerOver"
+ Color="#00E81123" />
+ <SolidColorBrush x:Key="SplitButtonBackgroundCheckedPressed"
+ Color="#00E81123" />
+ <SolidColorBrush x:Key="SplitButtonBackgroundCheckedDisabled"
+ Color="#00E81123" />
<Thickness x:Key="PageMargin">40 0 40 0</Thickness>
<Thickness x:Key="Margin">0 5 0 5</Thickness>
<Thickness x:Key="MenuItemPadding">5 0 5 0</Thickness>
- <Color x:Key="MenuFlyoutPresenterBorderColor">#00000000</Color>
- <Color x:Key="SystemAccentColor">#FF00C3E3</Color>
- <Color x:Key="SystemAccentColorDark1">#FF00C3E3</Color>
- <Color x:Key="SystemAccentColorDark2">#FF00C3E3</Color>
- <Color x:Key="SystemAccentColorDark3">#FF00C3E3</Color>
- <Color x:Key="SystemAccentColorLight1">#FF00C3E3</Color>
- <Color x:Key="SystemAccentColorLight2">#FF00C3E3</Color>
- <Color x:Key="SystemAccentColorLight3">#FF00C3E3</Color>
- <Color x:Key="DataGridSelectionColor">#FF00FABB</Color>
- <Color x:Key="ThemeContentBackgroundColor">#FF2D2D2D</Color>
- <Color x:Key="ThemeControlBorderColor">#FF505050</Color>
- <Color x:Key="VsyncEnabled">#FF2EEAC9</Color>
- <Color x:Key="VsyncDisabled">#FFFF4554</Color>
- <Color x:Key="AppListBackgroundColor">#0FFFFFFF</Color>
- <Color x:Key="AppListHoverBackgroundColor">#1EFFFFFF</Color>
- <Color x:Key="SecondaryTextColor">#A0FFFFFF</Color>
<x:Double x:Key="ScrollBarThickness">15</x:Double>
<x:Double x:Key="FontSizeSmall">8</x:Double>
<x:Double x:Key="FontSizeNormal">10</x:Double>
diff --git a/src/Ryujinx.Ava/Assets/Styles/Themes.xaml b/src/Ryujinx.Ava/Assets/Styles/Themes.xaml
new file mode 100644
index 00000000..0f323f84
--- /dev/null
+++ b/src/Ryujinx.Ava/Assets/Styles/Themes.xaml
@@ -0,0 +1,85 @@
+<ResourceDictionary xmlns="https://github.com/avaloniaui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+ <ResourceDictionary.ThemeDictionaries>
+ <ResourceDictionary x:Key="Default">
+ <SolidColorBrush x:Key="DataGridSelectionBackgroundBrush"
+ Color="{DynamicResource DataGridSelectionColor}" />
+ <SolidColorBrush x:Key="ThemeAccentColorBrush"
+ Color="{DynamicResource SystemAccentColor}" />
+ <SolidColorBrush x:Key="ThemeAccentBrush4"
+ Color="{DynamicResource ThemeAccentColor4}" />
+ <Color x:Key="SystemAccentColor">#FF00C3E3</Color>
+ <Color x:Key="SystemAccentColorDark1">#FF00C3E3</Color>
+ <Color x:Key="SystemAccentColorDark2">#FF00C3E3</Color>
+ <Color x:Key="SystemAccentColorDark3">#FF00C3E3</Color>
+ <Color x:Key="SystemAccentColorLight1">#FF00C3E3</Color>
+ <Color x:Key="SystemAccentColorLight2">#FF00C3E3</Color>
+ <Color x:Key="SystemAccentColorLight3">#FF00C3E3</Color>
+ <Color x:Key="ThemeAccentColor4">#FFe8e8e8</Color>
+ <Color x:Key="DataGridSelectionColor">#FF00FABB</Color>
+ <Color x:Key="ThemeContentBackgroundColor">#FFF0F0F0</Color>
+ <Color x:Key="ThemeControlBorderColor">#FFd6d6d6</Color>
+ <Color x:Key="TextOnAccentFillColorPrimary">#FFFFFFFF</Color>
+ <Color x:Key="SystemChromeWhiteColor">#FFFFFFFF</Color>
+ <Color x:Key="ThemeForegroundColor">#FF000000</Color>
+ <Color x:Key="MenuFlyoutPresenterBorderColor">#C1C1C1</Color>
+ <Color x:Key="AppListBackgroundColor">#b3ffffff</Color>
+ <Color x:Key="AppListHoverBackgroundColor">#80cccccc</Color>
+ <Color x:Key="SecondaryTextColor">#A0000000</Color>
+ <Color x:Key="VsyncEnabled">#FF2EEAC9</Color>
+ <Color x:Key="VsyncDisabled">#FFFF4554</Color>
+ </ResourceDictionary>
+ <ResourceDictionary x:Key="Light">
+ <SolidColorBrush x:Key="DataGridSelectionBackgroundBrush"
+ Color="{DynamicResource DataGridSelectionColor}" />
+ <SolidColorBrush x:Key="ThemeAccentColorBrush"
+ Color="{DynamicResource SystemAccentColor}" />
+ <SolidColorBrush x:Key="ThemeAccentBrush4"
+ Color="{DynamicResource ThemeAccentColor4}" />
+ <Color x:Key="SystemAccentColor">#FF00C3E3</Color>
+ <Color x:Key="SystemAccentColorDark1">#FF00C3E3</Color>
+ <Color x:Key="SystemAccentColorDark2">#FF00C3E3</Color>
+ <Color x:Key="SystemAccentColorDark3">#FF00C3E3</Color>
+ <Color x:Key="SystemAccentColorLight1">#FF00C3E3</Color>
+ <Color x:Key="SystemAccentColorLight2">#FF00C3E3</Color>
+ <Color x:Key="SystemAccentColorLight3">#FF00C3E3</Color>
+ <Color x:Key="ThemeAccentColor4">#FFe8e8e8</Color>
+ <Color x:Key="DataGridSelectionColor">#FF00FABB</Color>
+ <Color x:Key="ThemeContentBackgroundColor">#FFF0F0F0</Color>
+ <Color x:Key="ThemeControlBorderColor">#FFd6d6d6</Color>
+ <Color x:Key="TextOnAccentFillColorPrimary">#FFFFFFFF</Color>
+ <Color x:Key="SystemChromeWhiteColor">#FFFFFFFF</Color>
+ <Color x:Key="ThemeForegroundColor">#FF000000</Color>
+ <Color x:Key="MenuFlyoutPresenterBorderColor">#C1C1C1</Color>
+ <Color x:Key="AppListBackgroundColor">#b3ffffff</Color>
+ <Color x:Key="AppListHoverBackgroundColor">#80cccccc</Color>
+ <Color x:Key="SecondaryTextColor">#A0000000</Color>
+ </ResourceDictionary>
+ <ResourceDictionary x:Key="Dark">
+ <SolidColorBrush x:Key="DataGridSelectionBackgroundBrush"
+ Color="{DynamicResource DataGridSelectionColor}" />
+ <SolidColorBrush x:Key="ThemeAccentColorBrush"
+ Color="{DynamicResource SystemAccentColor}" />
+ <SolidColorBrush x:Key="ThemeAccentBrush4"
+ Color="{DynamicResource ThemeAccentColor4}" />
+ <Color x:Key="ControlFillColorSecondary">#008AA8</Color>
+ <Color x:Key="SystemAccentColor">#FF00C3E3</Color>
+ <Color x:Key="SystemAccentColorDark1">#FF99b000</Color>
+ <Color x:Key="SystemAccentColorDark2">#FF006d7d</Color>
+ <Color x:Key="SystemAccentColorDark3">#FF00525E</Color>
+ <Color x:Key="SystemAccentColorLight1">#FF00dbff</Color>
+ <Color x:Key="SystemAccentColorLight2">#FF19dfff</Color>
+ <Color x:Key="SystemAccentColorLight3">#FF33e3ff</Color>
+ <Color x:Key="DataGridSelectionColor">#FF00FABB</Color>
+ <Color x:Key="ThemeContentBackgroundColor">#FF2D2D2D</Color>
+ <Color x:Key="ThemeControlBorderColor">#FF505050</Color>
+ <Color x:Key="TextOnAccentFillColorPrimary">#FFFFFFFF</Color>
+ <Color x:Key="SystemChromeWhiteColor">#FFFFFFFF</Color>
+ <Color x:Key="ThemeForegroundColor">#FFFFFFFF</Color>
+ <Color x:Key="MenuFlyoutPresenterBorderColor">#3D3D3D</Color>
+ <Color x:Key="AppListBackgroundColor">#0FFFFFFF</Color>
+ <Color x:Key="AppListHoverBackgroundColor">#1EFFFFFF</Color>
+ <Color x:Key="SecondaryTextColor">#A0FFFFFF</Color>
+ </ResourceDictionary>
+ </ResourceDictionary.ThemeDictionaries>
+</ResourceDictionary>
diff --git a/src/Ryujinx.Ava/Common/ApplicationHelper.cs b/src/Ryujinx.Ava/Common/ApplicationHelper.cs
index d28d5aac..9e475753 100644
--- a/src/Ryujinx.Ava/Common/ApplicationHelper.cs
+++ b/src/Ryujinx.Ava/Common/ApplicationHelper.cs
@@ -1,5 +1,5 @@
-using Avalonia.Controls;
using Avalonia.Controls.Notifications;
+using Avalonia.Platform.Storage;
using Avalonia.Threading;
using LibHac;
using LibHac.Account;
@@ -143,14 +143,20 @@ namespace Ryujinx.Ava.Common
}
}
- public static async Task ExtractSection(NcaSectionType ncaSectionType, string titleFilePath, string titleName, int programIndex = 0)
+ public static async Task ExtractSection(IStorageProvider storageProvider, NcaSectionType ncaSectionType, string titleFilePath, string titleName, int programIndex = 0)
{
- OpenFolderDialog folderDialog = new()
+ var result = await storageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
{
Title = LocaleManager.Instance[LocaleKeys.FolderDialogExtractTitle],
- };
+ AllowMultiple = false
+ });
- string destination = await folderDialog.ShowAsync(_owner);
+ if (result.Count == 0)
+ {
+ return;
+ }
+
+ var destination = result[0].Path.LocalPath;
var cancellationToken = new CancellationTokenSource();
UpdateWaitWindow waitingDialog = new(
@@ -158,148 +164,145 @@ namespace Ryujinx.Ava.Common
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogNcaExtractionMessage, ncaSectionType, Path.GetFileName(titleFilePath)),
cancellationToken);
- if (!string.IsNullOrWhiteSpace(destination))
+ Thread extractorThread = new(() =>
{
- Thread extractorThread = new(() =>
- {
- Dispatcher.UIThread.Post(waitingDialog.Show);
+ Dispatcher.UIThread.Post(waitingDialog.Show);
- using FileStream file = new(titleFilePath, FileMode.Open, FileAccess.Read);
+ using FileStream file = new(titleFilePath, FileMode.Open, FileAccess.Read);
- Nca mainNca = null;
- Nca patchNca = null;
+ Nca mainNca = null;
+ Nca patchNca = null;
- string extension = Path.GetExtension(titleFilePath).ToLower();
- if (extension == ".nsp" || extension == ".pfs0" || extension == ".xci")
- {
- PartitionFileSystem pfs;
+ string extension = Path.GetExtension(titleFilePath).ToLower();
+ if (extension == ".nsp" || extension == ".pfs0" || extension == ".xci")
+ {
+ PartitionFileSystem pfs;
- if (extension == ".xci")
- {
- pfs = new Xci(_virtualFileSystem.KeySet, file.AsStorage()).OpenPartition(XciPartitionType.Secure);
- }
- else
- {
- pfs = new PartitionFileSystem(file.AsStorage());
- }
+ if (extension == ".xci")
+ {
+ pfs = new Xci(_virtualFileSystem.KeySet, file.AsStorage()).OpenPartition(XciPartitionType.Secure);
+ }
+ else
+ {
+ pfs = new PartitionFileSystem(file.AsStorage());
+ }
- foreach (DirectoryEntryEx fileEntry in pfs.EnumerateEntries("/", "*.nca"))
- {
- using var ncaFile = new UniqueRef<IFile>();
+ foreach (DirectoryEntryEx fileEntry in pfs.EnumerateEntries("/", "*.nca"))
+ {
+ using var ncaFile = new UniqueRef<IFile>();
- pfs.OpenFile(ref ncaFile.Ref, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
+ pfs.OpenFile(ref ncaFile.Ref, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
- Nca nca = new(_virtualFileSystem.KeySet, ncaFile.Get.AsStorage());
- if (nca.Header.ContentType == NcaContentType.Program)
+ Nca nca = new(_virtualFileSystem.KeySet, ncaFile.Get.AsStorage());
+ if (nca.Header.ContentType == NcaContentType.Program)
+ {
+ int dataIndex = Nca.GetSectionIndexFromType(NcaSectionType.Data, NcaContentType.Program);
+ if (nca.SectionExists(NcaSectionType.Data) && nca.Header.GetFsHeader(dataIndex).IsPatchSection())
+ {
+ patchNca = nca;
+ }
+ else
{
- int dataIndex = Nca.GetSectionIndexFromType(NcaSectionType.Data, NcaContentType.Program);
- if (nca.SectionExists(NcaSectionType.Data) && nca.Header.GetFsHeader(dataIndex).IsPatchSection())
- {
- patchNca = nca;
- }
- else
- {
- mainNca = nca;
- }
+ mainNca = nca;
}
}
}
- else if (extension == ".nca")
- {
- mainNca = new Nca(_virtualFileSystem.KeySet, file.AsStorage());
- }
+ }
+ else if (extension == ".nca")
+ {
+ mainNca = new Nca(_virtualFileSystem.KeySet, file.AsStorage());
+ }
- if (mainNca == null)
- {
- Logger.Error?.Print(LogClass.Application, "Extraction failure. The main NCA was not present in the selected file");
+ if (mainNca == null)
+ {
+ Logger.Error?.Print(LogClass.Application, "Extraction failure. The main NCA was not present in the selected file");
- Dispatcher.UIThread.InvokeAsync(async () =>
- {
- waitingDialog.Close();
+ Dispatcher.UIThread.InvokeAsync(async () =>
+ {
+ waitingDialog.Close();
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogNcaExtractionMainNcaNotFoundErrorMessage]);
- });
+ await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogNcaExtractionMainNcaNotFoundErrorMessage]);
+ });
- return;
- }
+ return;
+ }
- (Nca updatePatchNca, _) = ApplicationLibrary.GetGameUpdateData(_virtualFileSystem, mainNca.Header.TitleId.ToString("x16"), programIndex, out _);
- if (updatePatchNca != null)
- {
- patchNca = updatePatchNca;
- }
+ (Nca updatePatchNca, _) = ApplicationLibrary.GetGameUpdateData(_virtualFileSystem, mainNca.Header.TitleId.ToString("x16"), programIndex, out _);
+ if (updatePatchNca != null)
+ {
+ patchNca = updatePatchNca;
+ }
- int index = Nca.GetSectionIndexFromType(ncaSectionType, mainNca.Header.ContentType);
+ int index = Nca.GetSectionIndexFromType(ncaSectionType, mainNca.Header.ContentType);
- try
+ try
+ {
+ bool sectionExistsInPatch = false;
+ if (patchNca != null)
{
- bool sectionExistsInPatch = false;
- if (patchNca != null)
- {
- sectionExistsInPatch = patchNca.CanOpenSection(index);
- }
+ sectionExistsInPatch = patchNca.CanOpenSection(index);
+ }
- IFileSystem ncaFileSystem = sectionExistsInPatch ? mainNca.OpenFileSystemWithPatch(patchNca, index, IntegrityCheckLevel.ErrorOnInvalid)
- : mainNca.OpenFileSystem(index, IntegrityCheckLevel.ErrorOnInvalid);
+ IFileSystem ncaFileSystem = sectionExistsInPatch ? mainNca.OpenFileSystemWithPatch(patchNca, index, IntegrityCheckLevel.ErrorOnInvalid)
+ : mainNca.OpenFileSystem(index, IntegrityCheckLevel.ErrorOnInvalid);
- FileSystemClient fsClient = _horizonClient.Fs;
+ FileSystemClient fsClient = _horizonClient.Fs;
- string source = DateTime.Now.ToFileTime().ToString()[10..];
- string output = DateTime.Now.ToFileTime().ToString()[10..];
+ string source = DateTime.Now.ToFileTime().ToString()[10..];
+ string output = DateTime.Now.ToFileTime().ToString()[10..];
- using var uniqueSourceFs = new UniqueRef<IFileSystem>(ncaFileSystem);
- using var uniqueOutputFs = new UniqueRef<IFileSystem>(new LocalFileSystem(destination));
+ using var uniqueSourceFs = new UniqueRef<IFileSystem>(ncaFileSystem);
+ using var uniqueOutputFs = new UniqueRef<IFileSystem>(new LocalFileSystem(destination));
- fsClient.Register(source.ToU8Span(), ref uniqueSourceFs.Ref);
- fsClient.Register(output.ToU8Span(), ref uniqueOutputFs.Ref);
+ fsClient.Register(source.ToU8Span(), ref uniqueSourceFs.Ref);
+ fsClient.Register(output.ToU8Span(), ref uniqueOutputFs.Ref);
- (Result? resultCode, bool canceled) = CopyDirectory(fsClient, $"{source}:/", $"{output}:/", cancellationToken.Token);
+ (Result? resultCode, bool canceled) = CopyDirectory(fsClient, $"{source}:/", $"{output}:/", cancellationToken.Token);
- if (!canceled)
+ if (!canceled)
+ {
+ if (resultCode.Value.IsFailure())
{
- if (resultCode.Value.IsFailure())
- {
- Logger.Error?.Print(LogClass.Application, $"LibHac returned error code: {resultCode.Value.ErrorCode}");
-
- Dispatcher.UIThread.InvokeAsync(async () =>
- {
- waitingDialog.Close();
+ Logger.Error?.Print(LogClass.Application, $"LibHac returned error code: {resultCode.Value.ErrorCode}");
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogNcaExtractionCheckLogErrorMessage]);
- });
- }
- else if (resultCode.Value.IsSuccess())
+ Dispatcher.UIThread.InvokeAsync(async () =>
{
- Dispatcher.UIThread.Post(waitingDialog.Close);
+ waitingDialog.Close();
- NotificationHelper.Show(
- LocaleManager.Instance[LocaleKeys.DialogNcaExtractionTitle],
- $"{titleName}\n\n{LocaleManager.Instance[LocaleKeys.DialogNcaExtractionSuccessMessage]}",
- NotificationType.Information);
- }
+ await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogNcaExtractionCheckLogErrorMessage]);
+ });
}
-
- fsClient.Unmount(source.ToU8Span());
- fsClient.Unmount(output.ToU8Span());
- }
- catch (ArgumentException ex)
- {
- Logger.Error?.Print(LogClass.Application, $"{ex.Message}");
-
- Dispatcher.UIThread.InvokeAsync(async () =>
+ else if (resultCode.Value.IsSuccess())
{
- waitingDialog.Close();
+ Dispatcher.UIThread.Post(waitingDialog.Close);
- await ContentDialogHelper.CreateErrorDialog(ex.Message);
- });
+ NotificationHelper.Show(
+ LocaleManager.Instance[LocaleKeys.DialogNcaExtractionTitle],
+ $"{titleName}\n\n{LocaleManager.Instance[LocaleKeys.DialogNcaExtractionSuccessMessage]}",
+ NotificationType.Information);
+ }
}
- })
+
+ fsClient.Unmount(source.ToU8Span());
+ fsClient.Unmount(output.ToU8Span());
+ }
+ catch (ArgumentException ex)
{
- Name = "GUI.NcaSectionExtractorThread",
- IsBackground = true,
- };
- extractorThread.Start();
- }
+ Logger.Error?.Print(LogClass.Application, $"{ex.Message}");
+
+ Dispatcher.UIThread.InvokeAsync(async () =>
+ {
+ waitingDialog.Close();
+
+ await ContentDialogHelper.CreateErrorDialog(ex.Message);
+ });
+ }
+ })
+ {
+ Name = "GUI.NcaSectionExtractorThread",
+ IsBackground = true,
+ };
+ extractorThread.Start();
}
public static (Result? result, bool canceled) CopyDirectory(FileSystemClient fs, string sourcePath, string destPath, CancellationToken token)
diff --git a/src/Ryujinx.Ava/Input/AvaloniaKeyboardDriver.cs b/src/Ryujinx.Ava/Input/AvaloniaKeyboardDriver.cs
index f12d0214..856ed6f7 100644
--- a/src/Ryujinx.Ava/Input/AvaloniaKeyboardDriver.cs
+++ b/src/Ryujinx.Ava/Input/AvaloniaKeyboardDriver.cs
@@ -31,7 +31,6 @@ namespace Ryujinx.Ava.Input
_control.KeyDown += OnKeyPress;
_control.KeyUp += OnKeyRelease;
_control.TextInput += Control_TextInput;
- _control.AddHandler(InputElement.TextInputEvent, Control_LastChanceTextInput, RoutingStrategies.Bubble);
}
private void Control_TextInput(object sender, TextInputEventArgs e)
@@ -39,12 +38,6 @@ namespace Ryujinx.Ava.Input
TextInput?.Invoke(this, e.Text);
}
- private void Control_LastChanceTextInput(object sender, TextInputEventArgs e)
- {
- // Swallow event
- e.Handled = true;
- }
-
public event Action<string> OnGamepadConnected
{
add { }
diff --git a/src/Ryujinx.Ava/Program.cs b/src/Ryujinx.Ava/Program.cs
index 5241f91f..86f38c34 100644
--- a/src/Ryujinx.Ava/Program.cs
+++ b/src/Ryujinx.Ava/Program.cs
@@ -59,15 +59,12 @@ namespace Ryujinx.Ava
{
EnableMultiTouch = true,
EnableIme = true,
- UseEGL = false,
- UseGpu = true,
+ RenderingMode = new[] { X11RenderingMode.Glx, X11RenderingMode.Software },
})
.With(new Win32PlatformOptions
{
- EnableMultitouch = true,
- UseWgl = false,
- AllowEglInitialization = false,
- CompositionBackdropCornerRadius = 8.0f,
+ WinUICompositionBackdropCornerRadius = 8.0f,
+ RenderingMode = new[] { Win32RenderingMode.AngleEgl, Win32RenderingMode.Software },
})
.UseSkia();
}
diff --git a/src/Ryujinx.Ava/Ryujinx.Ava.csproj b/src/Ryujinx.Ava/Ryujinx.Ava.csproj
index 1fac5400..a4c1ebf1 100644
--- a/src/Ryujinx.Ava/Ryujinx.Ava.csproj
+++ b/src/Ryujinx.Ava/Ryujinx.Ava.csproj
@@ -10,6 +10,8 @@
<RootNamespace>Ryujinx.Ava</RootNamespace>
<ApplicationIcon>Ryujinx.ico</ApplicationIcon>
<TieredPGO>true</TieredPGO>
+ <AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
+ <ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="$([MSBuild]::IsOSPlatform('OSX'))">
@@ -26,7 +28,7 @@
<ItemGroup>
<PackageReference Include="Avalonia" />
<PackageReference Include="Avalonia.Desktop" />
- <PackageReference Include="Avalonia.Diagnostics" />
+ <PackageReference Include="Avalonia.Diagnostics" Condition="'$(Configuration)'=='Debug'" />
<PackageReference Include="Avalonia.Controls.DataGrid" />
<PackageReference Include="Avalonia.Markup.Xaml.Loader" />
<PackageReference Include="Avalonia.Svg" />
@@ -34,7 +36,6 @@
<PackageReference Include="jp2masa.Avalonia.Flexbox" />
<PackageReference Include="DynamicData" />
<PackageReference Include="FluentAvaloniaUI" />
- <PackageReference Include="XamlNameReferenceGenerator" />
<PackageReference Include="OpenTK.Core" />
<PackageReference Include="Ryujinx.Audio.OpenAL.Dependencies" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'osx-x64' AND '$(RuntimeIdentifier)' != 'osx-arm64'" />
@@ -97,10 +98,7 @@
<SubType>Designer</SubType>
</AvaloniaResource>
<AvaloniaResource Include="Assets\Fonts\SegoeFluentIcons.ttf" />
- <AvaloniaResource Include="Assets\Styles\BaseLight.xaml">
- <Generator>MSBuild:Compile</Generator>
- </AvaloniaResource>
- <AvaloniaResource Include="Assets\Styles\BaseDark.xaml">
+ <AvaloniaResource Include="Assets\Styles\Themes.xaml">
<Generator>MSBuild:Compile</Generator>
</AvaloniaResource>
<AvaloniaResource Include="Assets\Styles\Styles.xaml" />
@@ -123,8 +121,7 @@
<None Remove="Assets\Locales\zh_CN.json" />
<None Remove="Assets\Locales\zh_TW.json" />
<None Remove="Assets\Styles\Styles.xaml" />
- <None Remove="Assets\Styles\BaseDark.xaml" />
- <None Remove="Assets\Styles\BaseLight.xaml" />
+ <None Remove="Assets\Styles\Themes.xaml" />
</ItemGroup>
<ItemGroup>
diff --git a/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml b/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml
index 211b4725..a70fc8d4 100644
--- a/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml
+++ b/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml
@@ -38,7 +38,7 @@
Grid.Column="1"
Margin="10"
VerticalAlignment="Stretch"
- Text="{Binding Message}"
+ Text="{ReflectionBinding Message}"
TextWrapping="Wrap" />
<StackPanel
Name="ButtonStack"
diff --git a/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml.cs b/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml.cs
index b77cc402..ec6f7682 100644
--- a/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml.cs
@@ -4,9 +4,6 @@ using Avalonia.Threading;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Windows;
using System.Threading.Tasks;
-#if DEBUG
-using Avalonia;
-#endif
namespace Ryujinx.Ava.UI.Applet
{
@@ -21,9 +18,7 @@ namespace Ryujinx.Ava.UI.Applet
Message = message;
DataContext = this;
InitializeComponent();
-#if DEBUG
- this.AttachDevTools();
-#endif
+
int responseId = 0;
if (buttons != null)
@@ -44,9 +39,6 @@ namespace Ryujinx.Ava.UI.Applet
{
DataContext = this;
InitializeComponent();
-#if DEBUG
- this.AttachDevTools();
-#endif
}
public string Message { get; set; }
diff --git a/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml b/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml
index 65504569..64b23f98 100644
--- a/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml
+++ b/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml
@@ -34,13 +34,13 @@
Grid.Row="1"
Grid.Column="1"
Margin="5"
- Text="{Binding MainText}"
+ Text="{ReflectionBinding MainText}"
TextWrapping="Wrap" />
<TextBlock
Grid.Row="2"
Grid.Column="1"
Margin="5"
- Text="{Binding SecondaryText}"
+ Text="{ReflectionBinding SecondaryText}"
TextWrapping="Wrap" />
<TextBox
Name="Input"
@@ -50,7 +50,7 @@
VerticalAlignment="Center"
Focusable="True"
KeyUp="Message_KeyUp"
- Text="{Binding Message}"
+ Text="{ReflectionBinding Message}"
TextInput="Message_TextInput"
TextWrapping="Wrap"
UseFloatingWatermark="True" />
diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml b/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml
index 29547f5f..93638fc5 100644
--- a/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml
+++ b/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml
@@ -2,7 +2,9 @@
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: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}" />
diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs b/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs
index 77b4f520..f54e9df8 100644
--- a/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs
@@ -299,7 +299,11 @@ namespace Ryujinx.Ava.UI.Controls
if (viewModel?.SelectedApplication != null)
{
- await ApplicationHelper.ExtractSection(NcaSectionType.Code, viewModel.SelectedApplication.Path, viewModel.SelectedApplication.TitleName);
+ await ApplicationHelper.ExtractSection(
+ viewModel.StorageProvider,
+ NcaSectionType.Code,
+ viewModel.SelectedApplication.Path,
+ viewModel.SelectedApplication.TitleName);
}
}
@@ -309,7 +313,11 @@ namespace Ryujinx.Ava.UI.Controls
if (viewModel?.SelectedApplication != null)
{
- await ApplicationHelper.ExtractSection(NcaSectionType.Data, viewModel.SelectedApplication.Path, viewModel.SelectedApplication.TitleName);
+ await ApplicationHelper.ExtractSection(
+ viewModel.StorageProvider,
+ NcaSectionType.Data,
+ viewModel.SelectedApplication.Path,
+ viewModel.SelectedApplication.TitleName);
}
}
@@ -319,7 +327,11 @@ namespace Ryujinx.Ava.UI.Controls
if (viewModel?.SelectedApplication != null)
{
- await ApplicationHelper.ExtractSection(NcaSectionType.Logo, viewModel.SelectedApplication.Path, viewModel.SelectedApplication.TitleName);
+ await ApplicationHelper.ExtractSection(
+ viewModel.StorageProvider,
+ NcaSectionType.Logo,
+ viewModel.SelectedApplication.Path,
+ viewModel.SelectedApplication.TitleName);
}
}
diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml b/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml
index 3d55793f..214fc075 100644
--- a/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml
+++ b/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml
@@ -11,7 +11,9 @@
d:DesignHeight="450"
d:DesignWidth="800"
Focusable="True"
- mc:Ignorable="d">
+ 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" />
@@ -27,7 +29,7 @@
VerticalAlignment="Stretch"
ContextFlyout="{StaticResource ApplicationContextMenu}"
DoubleTapped="GameList_DoubleTapped"
- Items="{Binding AppsObservableList}"
+ ItemsSource="{Binding AppsObservableList}"
SelectionChanged="GameList_SelectionChanged">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
@@ -43,8 +45,8 @@
<Setter Property="Margin" Value="5" />
<Setter Property="CornerRadius" Value="4" />
</Style>
- <Style Selector="ListBoxItem:selected /template/ Border#SelectionIndicator">
- <Setter Property="MinHeight" Value="{Binding $parent[UserControl].DataContext.GridItemSelectorSize}" />
+ <Style Selector="ListBoxItem:selected /template/ Rectangle#SelectionIndicator">
+ <Setter Property="MinHeight" Value="{ReflectionBinding $parent[UserControl].DataContext.GridItemSelectorSize}" />
</Style>
</ListBox.Styles>
<ListBox.ItemTemplate>
@@ -54,10 +56,10 @@
Margin="10"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
- Classes.huge="{Binding $parent[UserControl].DataContext.IsGridHuge}"
- Classes.large="{Binding $parent[UserControl].DataContext.IsGridLarge}"
- Classes.normal="{Binding $parent[UserControl].DataContext.IsGridMedium}"
- Classes.small="{Binding $parent[UserControl].DataContext.IsGridSmall}"
+ Classes.huge="{ReflectionBinding $parent[UserControl].DataContext.IsGridHuge}"
+ Classes.large="{ReflectionBinding $parent[UserControl].DataContext.IsGridLarge}"
+ Classes.normal="{ReflectionBinding $parent[UserControl].DataContext.IsGridMedium}"
+ Classes.small="{ReflectionBinding $parent[UserControl].DataContext.IsGridSmall}"
ClipToBounds="True"
CornerRadius="4">
<Grid>
@@ -76,9 +78,9 @@
Margin="0,10,0,0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
- IsVisible="{Binding $parent[UserControl].DataContext.ShowNames}">
+ IsVisible="{ReflectionBinding $parent[UserControl].DataContext.ShowNames}">
<TextBlock
- HorizontalAlignment="Stretch"
+ HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="{Binding TitleName}"
TextAlignment="Center"
diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs b/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs
index efdc9ab0..821d6fd9 100644
--- a/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs
@@ -1,7 +1,6 @@
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
-using Avalonia.Markup.Xaml;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ui.App.Common;
@@ -25,12 +24,7 @@ namespace Ryujinx.Ava.UI.Controls
InitializeComponent();
}
- private void InitializeComponent()
- {
- AvaloniaXamlLoader.Load(this);
- }
-
- public void GameList_DoubleTapped(object sender, RoutedEventArgs args)
+ public void GameList_DoubleTapped(object sender, TappedEventArgs args)
{
if (sender is ListBox listBox)
{
diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml b/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml
index 227b4723..75bbf9d0 100644
--- a/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml
+++ b/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml
@@ -10,7 +10,9 @@
d:DesignHeight="450"
d:DesignWidth="800"
Focusable="True"
- mc:Ignorable="d">
+ 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" />
@@ -27,7 +29,7 @@
VerticalAlignment="Stretch"
ContextFlyout="{StaticResource ApplicationContextMenu}"
DoubleTapped="GameList_DoubleTapped"
- Items="{Binding AppsObservableList}"
+ ItemsSource="{Binding AppsObservableList}"
SelectionChanged="GameList_SelectionChanged">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
@@ -39,8 +41,8 @@
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.Styles>
- <Style Selector="ListBoxItem:selected /template/ Border#SelectionIndicator">
- <Setter Property="MinHeight" Value="{Binding $parent[UserControl].DataContext.ListItemSelectorSize}" />
+ <Style Selector="ListBoxItem:selected /template/ Rectangle#SelectionIndicator">
+ <Setter Property="MinHeight" Value="{ReflectionBinding $parent[UserControl].DataContext.ListItemSelectorSize}" />
</Style>
</ListBox.Styles>
<ListBox.ItemTemplate>
@@ -65,10 +67,10 @@
Grid.RowSpan="3"
Grid.Column="0"
Margin="0"
- Classes.huge="{Binding $parent[UserControl].DataContext.IsGridHuge}"
- Classes.large="{Binding $parent[UserControl].DataContext.IsGridLarge}"
- Classes.normal="{Binding $parent[UserControl].DataContext.IsGridMedium}"
- Classes.small="{Binding $parent[UserControl].DataContext.IsGridSmall}"
+ Classes.huge="{ReflectionBinding $parent[UserControl].DataContext.IsGridHuge}"
+ Classes.large="{ReflectionBinding $parent[UserControl].DataContext.IsGridLarge}"
+ Classes.normal="{ReflectionBinding $parent[UserControl].DataContext.IsGridMedium}"
+ Classes.small="{ReflectionBinding $parent[UserControl].DataContext.IsGridSmall}"
Source="{Binding Icon, Converter={StaticResource ByteImage}}" />
<Border
Grid.Column="2"
diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs b/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs
index 1646fc1b..dd60503a 100644
--- a/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs
@@ -1,7 +1,6 @@
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
-using Avalonia.Markup.Xaml;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ui.App.Common;
@@ -25,12 +24,7 @@ namespace Ryujinx.Ava.UI.Controls
InitializeComponent();
}
- private void InitializeComponent()
- {
- AvaloniaXamlLoader.Load(this);
- }
-
- public void GameList_DoubleTapped(object sender, RoutedEventArgs args)
+ public void GameList_DoubleTapped(object sender, TappedEventArgs args)
{
if (sender is ListBox listBox)
{
diff --git a/src/Ryujinx.Ava/UI/Helpers/GlyphValueConverter.cs b/src/Ryujinx.Ava/UI/Helpers/GlyphValueConverter.cs
index 4e4b971e..7da23648 100644
--- a/src/Ryujinx.Ava/UI/Helpers/GlyphValueConverter.cs
+++ b/src/Ryujinx.Ava/UI/Helpers/GlyphValueConverter.cs
@@ -1,6 +1,4 @@
-using Avalonia.Data;
using Avalonia.Markup.Xaml;
-using Avalonia.Markup.Xaml.MarkupExtensions;
using FluentAvalonia.UI.Controls;
using System;
using System.Collections.Generic;
@@ -38,13 +36,7 @@ namespace Ryujinx.Ava.UI.Helpers
public override object ProvideValue(IServiceProvider serviceProvider)
{
- ReflectionBindingExtension binding = new($"[{_key}]")
- {
- Mode = BindingMode.OneWay,
- Source = this,
- };
-
- return binding.ProvideValue(serviceProvider);
+ return this[_key];
}
}
}
diff --git a/src/Ryujinx.Ava/UI/Helpers/HotKeyControl.cs b/src/Ryujinx.Ava/UI/Helpers/HotKeyControl.cs
deleted file mode 100644
index 4ae903b4..00000000
--- a/src/Ryujinx.Ava/UI/Helpers/HotKeyControl.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Input;
-using System;
-using System.Windows.Input;
-
-namespace Ryujinx.Ava.UI.Helpers
-{
- public class HotKeyControl : ContentControl, ICommandSource
- {
- public static readonly StyledProperty<object> CommandParameterProperty =
- AvaloniaProperty.Register<HotKeyControl, object>(nameof(CommandParameter));
-
- public static readonly DirectProperty<HotKeyControl, ICommand> CommandProperty =
- AvaloniaProperty.RegisterDirect<HotKeyControl, ICommand>(nameof(Command),
- control => control.Command, (control, command) => control.Command = command, enableDataValidation: true);
-
- public static readonly StyledProperty<KeyGesture> HotKeyProperty = HotKeyManager.HotKeyProperty.AddOwner<Button>();
-
- private ICommand _command;
- private bool _commandCanExecute;
-
- public ICommand Command
- {
- get { return _command; }
- set { SetAndRaise(CommandProperty, ref _command, value); }
- }
-
- public KeyGesture HotKey
- {
- get { return GetValue(HotKeyProperty); }
- set { SetValue(HotKeyProperty, value); }
- }
-
- public object CommandParameter
- {
- get { return GetValue(CommandParameterProperty); }
- set { SetValue(CommandParameterProperty, value); }
- }
-
- public void CanExecuteChanged(object sender, EventArgs e)
- {
- var canExecute = Command == null || Command.CanExecute(CommandParameter);
-
- if (canExecute != _commandCanExecute)
- {
- _commandCanExecute = canExecute;
- UpdateIsEffectivelyEnabled();
- }
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/Helpers/LoggerAdapter.cs b/src/Ryujinx.Ava/UI/Helpers/LoggerAdapter.cs
index dc8e3f94..0b178988 100644
--- a/src/Ryujinx.Ava/UI/Helpers/LoggerAdapter.cs
+++ b/src/Ryujinx.Ava/UI/Helpers/LoggerAdapter.cs
@@ -42,21 +42,6 @@ namespace Ryujinx.Ava.UI.Helpers
GetLog(level)?.PrintMsg(RyuLogClass.Ui, Format(level, area, messageTemplate, source, null));
}
- public void Log<T0>(AvaLogLevel level, string area, object source, string messageTemplate, T0 propertyValue0)
- {
- GetLog(level)?.PrintMsg(RyuLogClass.Ui, Format(level, area, messageTemplate, source, new object[] { propertyValue0 }));
- }
-
- public void Log<T0, T1>(AvaLogLevel level, string area, object source, string messageTemplate, T0 propertyValue0, T1 propertyValue1)
- {
- GetLog(level)?.PrintMsg(RyuLogClass.Ui, Format(level, area, messageTemplate, source, new object[] { propertyValue0, propertyValue1 }));
- }
-
- public void Log<T0, T1, T2>(AvaLogLevel level, string area, object source, string messageTemplate, T0 propertyValue0, T1 propertyValue1, T2 propertyValue2)
- {
- GetLog(level)?.PrintMsg(RyuLogClass.Ui, Format(level, area, messageTemplate, source, new object[] { propertyValue0, propertyValue1, propertyValue2 }));
- }
-
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));
diff --git a/src/Ryujinx.Ava/UI/Helpers/OffscreenTextBox.cs b/src/Ryujinx.Ava/UI/Helpers/OffscreenTextBox.cs
index 670d3b36..a055f335 100644
--- a/src/Ryujinx.Ava/UI/Helpers/OffscreenTextBox.cs
+++ b/src/Ryujinx.Ava/UI/Helpers/OffscreenTextBox.cs
@@ -31,7 +31,6 @@ namespace Ryujinx.Ava.UI.Helpers
OnTextInput(new TextInputEventArgs
{
Text = text,
- Device = KeyboardDevice.Instance,
Source = this,
RoutedEvent = TextInputEvent,
});
diff --git a/src/Ryujinx.Ava/UI/Helpers/TimeZoneConverter.cs b/src/Ryujinx.Ava/UI/Helpers/TimeZoneConverter.cs
new file mode 100644
index 00000000..4ec0ff30
--- /dev/null
+++ b/src/Ryujinx.Ava/UI/Helpers/TimeZoneConverter.cs
@@ -0,0 +1,28 @@
+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/Models/UserProfile.cs b/src/Ryujinx.Ava/UI/Models/UserProfile.cs
index e1698b4d..7a9237fe 100644
--- a/src/Ryujinx.Ava/UI/Models/UserProfile.cs
+++ b/src/Ryujinx.Ava/UI/Models/UserProfile.cs
@@ -1,4 +1,3 @@
-using Avalonia;
using Avalonia.Media;
using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.ViewModels;
@@ -88,7 +87,8 @@ namespace Ryujinx.Ava.UI.Models
private void UpdateBackground()
{
- Application.Current.Styles.TryGetResource("ControlFillColorSecondary", out object color);
+ var currentApplication = Avalonia.Application.Current;
+ currentApplication.Styles.TryGetResource("ControlFillColorSecondary", currentApplication.ActualThemeVariant, out object color);
if (color is not null)
{
diff --git a/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindow.cs b/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindow.cs
index e324b484..fa55c8d3 100644
--- a/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindow.cs
+++ b/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindow.cs
@@ -34,7 +34,7 @@ namespace Ryujinx.Ava.UI.Renderer
private UpdateBoundsCallbackDelegate _updateBoundsCallback;
public event EventHandler<IntPtr> WindowCreated;
- public event EventHandler<Size> SizeChanged;
+ public event EventHandler<Size> BoundsChanged;
public EmbeddedWindow()
{
@@ -67,7 +67,7 @@ namespace Ryujinx.Ava.UI.Renderer
private void StateChanged(Rect rect)
{
- SizeChanged?.Invoke(this, rect.Size);
+ BoundsChanged?.Invoke(this, rect.Size);
_updateBoundsCallback?.Invoke(rect);
}
@@ -149,9 +149,10 @@ namespace Ryujinx.Ava.UI.Renderer
msg == WindowsMessages.Rbuttonup ||
msg == WindowsMessages.Mousemove)
{
- Point rootVisualPosition = this.TranslatePoint(new Point((long)lParam & 0xFFFF, (long)lParam >> 16 & 0xFFFF), VisualRoot).Value;
+ 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:
@@ -164,7 +165,7 @@ namespace Ryujinx.Ava.UI.Renderer
var evnt = new PointerPressedEventArgs(
this,
pointer,
- VisualRoot,
+ this,
rootVisualPosition,
(ulong)Environment.TickCount64,
properties,
@@ -184,7 +185,7 @@ namespace Ryujinx.Ava.UI.Renderer
var evnt = new PointerReleasedEventArgs(
this,
pointer,
- VisualRoot,
+ this,
rootVisualPosition,
(ulong)Environment.TickCount64,
properties,
@@ -201,7 +202,7 @@ namespace Ryujinx.Ava.UI.Renderer
PointerMovedEvent,
this,
pointer,
- VisualRoot,
+ this,
rootVisualPosition,
(ulong)Environment.TickCount64,
new PointerPointProperties(RawInputModifiers.None, PointerUpdateKind.Other),
@@ -212,6 +213,7 @@ namespace Ryujinx.Ava.UI.Renderer
break;
}
}
+#pragma warning restore CS0618
}
}
diff --git a/src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml.cs b/src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml.cs
index b74265a3..12c18e4a 100644
--- a/src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml.cs
@@ -11,7 +11,7 @@ namespace Ryujinx.Ava.UI.Renderer
public readonly EmbeddedWindow EmbeddedWindow;
public event EventHandler<EventArgs> WindowCreated;
- public event Action<object, Size> SizeChanged;
+ public event Action<object, Size> BoundsChanged;
public RendererHost()
{
@@ -32,7 +32,7 @@ namespace Ryujinx.Ava.UI.Renderer
private void Initialize()
{
EmbeddedWindow.WindowCreated += CurrentWindow_WindowCreated;
- EmbeddedWindow.SizeChanged += CurrentWindow_SizeChanged;
+ EmbeddedWindow.BoundsChanged += CurrentWindow_BoundsChanged;
Content = EmbeddedWindow;
}
@@ -42,7 +42,7 @@ namespace Ryujinx.Ava.UI.Renderer
if (EmbeddedWindow != null)
{
EmbeddedWindow.WindowCreated -= CurrentWindow_WindowCreated;
- EmbeddedWindow.SizeChanged -= CurrentWindow_SizeChanged;
+ EmbeddedWindow.BoundsChanged -= CurrentWindow_BoundsChanged;
}
GC.SuppressFinalize(this);
@@ -55,9 +55,9 @@ namespace Ryujinx.Ava.UI.Renderer
Dispose();
}
- private void CurrentWindow_SizeChanged(object sender, Size e)
+ private void CurrentWindow_BoundsChanged(object sender, Size e)
{
- SizeChanged?.Invoke(sender, e);
+ BoundsChanged?.Invoke(sender, e);
}
private void CurrentWindow_WindowCreated(object sender, IntPtr e)
diff --git a/src/Ryujinx.Ava/UI/ViewModels/AboutWindowViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/AboutWindowViewModel.cs
index fddcd71a..70ede4c1 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/AboutWindowViewModel.cs
+++ b/src/Ryujinx.Ava/UI/ViewModels/AboutWindowViewModel.cs
@@ -1,4 +1,3 @@
-using Avalonia;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
using Avalonia.Threading;
@@ -88,21 +87,19 @@ namespace Ryujinx.Ava.UI.ViewModels
{
Version = Program.Version;
- var assets = AvaloniaLocator.Current.GetService<IAssetLoader>();
-
if (ConfigurationState.Instance.Ui.BaseStyle.Value == "Light")
{
- GithubLogo = new Bitmap(assets.Open(new Uri("resm:Ryujinx.Ui.Common.Resources.Logo_GitHub_Light.png?assembly=Ryujinx.Ui.Common")));
- DiscordLogo = new Bitmap(assets.Open(new Uri("resm:Ryujinx.Ui.Common.Resources.Logo_Discord_Light.png?assembly=Ryujinx.Ui.Common")));
- PatreonLogo = new Bitmap(assets.Open(new Uri("resm:Ryujinx.Ui.Common.Resources.Logo_Patreon_Light.png?assembly=Ryujinx.Ui.Common")));
- TwitterLogo = new Bitmap(assets.Open(new Uri("resm:Ryujinx.Ui.Common.Resources.Logo_Twitter_Light.png?assembly=Ryujinx.Ui.Common")));
+ 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(assets.Open(new Uri("resm:Ryujinx.Ui.Common.Resources.Logo_GitHub_Dark.png?assembly=Ryujinx.Ui.Common")));
- DiscordLogo = new Bitmap(assets.Open(new Uri("resm:Ryujinx.Ui.Common.Resources.Logo_Discord_Dark.png?assembly=Ryujinx.Ui.Common")));
- PatreonLogo = new Bitmap(assets.Open(new Uri("resm:Ryujinx.Ui.Common.Resources.Logo_Patreon_Dark.png?assembly=Ryujinx.Ui.Common")));
- TwitterLogo = new Bitmap(assets.Open(new Uri("resm:Ryujinx.Ui.Common.Resources.Logo_Twitter_Dark.png?assembly=Ryujinx.Ui.Common")));
+ 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);
diff --git a/src/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs
index f2f56947..74b73751 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs
+++ b/src/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs
@@ -1,6 +1,6 @@
using Avalonia.Collections;
-using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
+using Avalonia.Platform.Storage;
using Avalonia.Threading;
using DynamicData;
using LibHac.Common;
@@ -90,12 +90,19 @@ namespace Ryujinx.Ava.UI.ViewModels
get => string.Format(LocaleManager.Instance[LocaleKeys.DlcWindowHeading], DownloadableContents.Count);
}
+ public IStorageProvider StorageProvider;
+
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
@@ -195,29 +202,24 @@ namespace Ryujinx.Ava.UI.ViewModels
public async void Add()
{
- OpenFileDialog dialog = new()
+ var result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
{
Title = LocaleManager.Instance[LocaleKeys.SelectDlcDialogTitle],
AllowMultiple = true,
- };
-
- dialog.Filters.Add(new FileDialogFilter
- {
- Name = "NSP",
- Extensions = { "nsp" },
- });
-
- if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
- {
- string[] files = await dialog.ShowAsync(desktop.MainWindow);
-
- if (files != null)
+ FileTypeFilter = new List<FilePickerFileType>
{
- foreach (string file in files)
+ new("NSP")
{
- await AddDownloadableContent(file);
+ Patterns = new[] { "*.nsp" },
+ AppleUniformTypeIdentifiers = new[] { "com.ryujinx.nsp" },
+ MimeTypes = new[] { "application/x-nx-nsp" }
}
}
+ });
+
+ foreach (var file in result)
+ {
+ await AddDownloadableContent(file.Path.LocalPath);
}
}
diff --git a/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs
index e8d68f76..aa6e0326 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs
+++ b/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs
@@ -3,6 +3,7 @@ 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;
@@ -105,8 +106,6 @@ namespace Ryujinx.Ava.UI.ViewModels
public ApplicationData ListSelectedApplication;
public ApplicationData GridSelectedApplication;
- public event Action ReloadGameList;
-
private string TitleName { get; set; }
internal AppHost AppHost { get; set; }
@@ -131,6 +130,7 @@ namespace Ryujinx.Ava.UI.ViewModels
public void Initialize(
ContentManager contentManager,
+ IStorageProvider storageProvider,
ApplicationLibrary applicationLibrary,
VirtualFileSystem virtualFileSystem,
AccountManager accountManager,
@@ -144,6 +144,7 @@ namespace Ryujinx.Ava.UI.ViewModels
TopLevel topLevel)
{
ContentManager = contentManager;
+ StorageProvider = storageProvider;
ApplicationLibrary = applicationLibrary;
VirtualFileSystem = virtualFileSystem;
AccountManager = accountManager;
@@ -891,6 +892,7 @@ namespace Ryujinx.Ava.UI.ViewModels
}
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; }
@@ -1188,7 +1190,9 @@ namespace Ryujinx.Ava.UI.ViewModels
{
Application.Current.Styles.TryGetResource(args.VSyncEnabled
? "VsyncEnabled"
- : "VsyncDisabled", out object color);
+ : "VsyncDisabled",
+ Avalonia.Application.Current.ActualThemeVariant,
+ out object color);
if (color is not null)
{
@@ -1259,6 +1263,16 @@ namespace Ryujinx.Ava.UI.ViewModels
ShowMenuAndStatusBar = false;
}
+ public void ToggleStartGamesInFullscreen()
+ {
+ StartGamesInFullscreen = !StartGamesInFullscreen;
+ }
+
+ public void ToggleShowConsole()
+ {
+ ShowConsole = !ShowConsole;
+ }
+
public void SetListMode()
{
Glyph = Glyph.List;
@@ -1271,43 +1285,57 @@ namespace Ryujinx.Ava.UI.ViewModels
public async void InstallFirmwareFromFile()
{
- if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
+ var result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
{
- OpenFileDialog dialog = new() { AllowMultiple = false };
- dialog.Filters.Add(new FileDialogFilter { Name = LocaleManager.Instance[LocaleKeys.FileDialogAllTypes], Extensions = { "xci", "zip" } });
- dialog.Filters.Add(new FileDialogFilter { Name = "XCI", Extensions = { "xci" } });
- dialog.Filters.Add(new FileDialogFilter { Name = "ZIP", Extensions = { "zip" } });
-
- string[] file = await dialog.ShowAsync(desktop.MainWindow);
-
- if (file != null && file.Length > 0)
+ AllowMultiple = false,
+ FileTypeFilter = new List<FilePickerFileType>
{
- await HandleFirmwareInstallation(file[0]);
+ 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 void InstallFirmwareFromFolder()
{
- if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
+ var result = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
{
- OpenFolderDialog dialog = new();
-
- string folder = await dialog.ShowAsync(desktop.MainWindow);
+ AllowMultiple = false
+ });
- if (!string.IsNullOrEmpty(folder))
- {
- await HandleFirmwareInstallation(folder);
- }
+ if (result.Count > 0)
+ {
+ await HandleFirmwareInstallation(result[0].Path.LocalPath);
}
}
- public static void OpenRyujinxFolder()
+ public void OpenRyujinxFolder()
{
OpenHelper.OpenFolder(AppDataManager.BaseDirPath);
}
- public static void OpenLogsFolder()
+ public void OpenLogsFolder()
{
string logPath = Path.Combine(ReleaseInformation.GetBaseApplicationDirectory(), "Logs");
@@ -1349,25 +1377,6 @@ namespace Ryujinx.Ava.UI.ViewModels
}
}
- 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();
- }
-
public async void ManageProfiles()
{
await NavigationDialogHost.Show(AccountManager, ContentManager, VirtualFileSystem, LibHacHorizonManager.RyujinxClient);
@@ -1378,78 +1387,84 @@ namespace Ryujinx.Ava.UI.ViewModels
AppHost.Device.System.SimulateWakeUpMessage();
}
- public async void LoadApplications()
- {
- await Dispatcher.UIThread.InvokeAsync(() =>
- {
- Applications.Clear();
-
- StatusBarVisible = true;
- StatusBarProgressMaximum = 0;
- StatusBarProgressValue = 0;
-
- LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.StatusBarGamesLoaded, 0, 0);
- });
-
- ReloadGameList?.Invoke();
- }
-
public async void OpenFile()
{
- if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
+ var result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
{
- OpenFileDialog dialog = new()
+ Title = LocaleManager.Instance[LocaleKeys.OpenFileDialogTitle],
+ AllowMultiple = false,
+ FileTypeFilter = new List<FilePickerFileType>
{
- Title = LocaleManager.Instance[LocaleKeys.OpenFileDialogTitle],
- };
-
- dialog.Filters.Add(new FileDialogFilter
- {
- Name = LocaleManager.Instance[LocaleKeys.AllSupportedFormats],
- Extensions =
+ 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")
{
- "nsp",
- "pfs0",
- "xci",
- "nca",
- "nro",
- "nso",
+ 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" }
},
- });
-
-#pragma warning disable IDE0055 // Disable formatting
- dialog.Filters.Add(new FileDialogFilter { Name = "NSP", Extensions = { "nsp" } });
- dialog.Filters.Add(new FileDialogFilter { Name = "PFS0", Extensions = { "pfs0" } });
- dialog.Filters.Add(new FileDialogFilter { Name = "XCI", Extensions = { "xci" } });
- dialog.Filters.Add(new FileDialogFilter { Name = "NCA", Extensions = { "nca" } });
- dialog.Filters.Add(new FileDialogFilter { Name = "NRO", Extensions = { "nro" } });
- dialog.Filters.Add(new FileDialogFilter { Name = "NSO", Extensions = { "nso" } });
-#pragma warning restore IDE0055
-
- string[] files = await dialog.ShowAsync(desktop.MainWindow);
-
- if (files != null && files.Length > 0)
- {
- LoadApplication(files[0]);
}
+ });
+
+ if (result.Count > 0)
+ {
+ LoadApplication(result[0].Path.LocalPath);
}
}
public async void OpenFolder()
{
- if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
+ var result = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
{
- OpenFolderDialog dialog = new()
- {
- Title = LocaleManager.Instance[LocaleKeys.OpenFolderDialogTitle],
- };
-
- string folder = await dialog.ShowAsync(desktop.MainWindow);
+ Title = LocaleManager.Instance[LocaleKeys.OpenFolderDialogTitle],
+ AllowMultiple = false
+ });
- if (!string.IsNullOrWhiteSpace(folder) && Directory.Exists(folder))
- {
- LoadApplication(folder);
- }
+ if (result.Count > 0)
+ {
+ LoadApplication(result[0].Path.LocalPath);
}
}
diff --git a/src/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs
index 740d888b..e3bca205 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs
+++ b/src/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs
@@ -1,7 +1,7 @@
using Avalonia;
using Avalonia.Collections;
-using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
+using Avalonia.Platform.Storage;
using Avalonia.Threading;
using LibHac.Common;
using LibHac.Fs;
@@ -70,12 +70,19 @@ namespace Ryujinx.Ava.UI.ViewModels
}
}
+ 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
@@ -202,29 +209,23 @@ namespace Ryujinx.Ava.UI.ViewModels
public async void Add()
{
- OpenFileDialog dialog = new()
+ var result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
{
- Title = LocaleManager.Instance[LocaleKeys.SelectUpdateDialogTitle],
AllowMultiple = true,
- };
-
- dialog.Filters.Add(new FileDialogFilter
- {
- Name = "NSP",
- Extensions = { "nsp" },
- });
-
- if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
- {
- string[] files = await dialog.ShowAsync(desktop.MainWindow);
-
- if (files != null)
+ FileTypeFilter = new List<FilePickerFileType>
{
- foreach (string file in files)
+ new(LocaleManager.Instance[LocaleKeys.AllSupportedFormats])
{
- AddUpdate(file);
+ Patterns = new[] { "*.nsp" },
+ AppleUniformTypeIdentifiers = new[] { "com.ryujinx.nsp" },
+ MimeTypes = new[] { "application/x-nx-nsp" }
}
}
+ });
+
+ foreach (var file in result)
+ {
+ AddUpdate(file.Path.LocalPath);
}
SortUpdates();
diff --git a/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml b/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml
index 2395b353..65a66d9e 100644
--- a/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml
@@ -14,7 +14,6 @@
d:DesignWidth="800"
x:Class="Ryujinx.Ava.UI.Views.Input.ControllerInputView"
x:DataType="viewModels:ControllerInputViewModel"
- x:CompileBindings="True"
mc:Ignorable="d"
Focusable="True">
<Design.DataContext>
@@ -66,7 +65,7 @@
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
SelectionChanged="PlayerIndexBox_OnSelectionChanged"
- Items="{Binding PlayerIndexes}"
+ ItemsSource="{Binding PlayerIndexes}"
SelectedIndex="{Binding PlayerId}">
<ComboBox.ItemTemplate>
<DataTemplate>
@@ -94,15 +93,15 @@
HorizontalAlignment="Left"
VerticalAlignment="Center"
Text="{locale:Locale ControllerSettingsProfile}" />
- <ui:ComboBox
+ <ui:FAComboBox
Grid.Column="1"
IsEditable="True"
Name="ProfileBox"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
SelectedIndex="0"
- Items="{Binding ProfilesList}"
- Text="{Binding ProfileName}" />
+ ItemsSource="{Binding ProfilesList}"
+ Text="{Binding ProfileName, Mode=TwoWay}" />
<Button
Grid.Column="2"
MinWidth="0"
@@ -170,7 +169,7 @@
Name="DeviceBox"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
- Items="{Binding DeviceList}"
+ ItemsSource="{Binding DeviceList}"
SelectedIndex="{Binding Device}" />
<Button
Grid.Column="2"
@@ -203,8 +202,8 @@
<ComboBox
Grid.Column="1"
HorizontalAlignment="Stretch"
- Items="{ReflectionBinding Controllers}"
- SelectedIndex="{ReflectionBinding Controller}">
+ ItemsSource="{Binding Controllers}"
+ SelectedIndex="{Binding Controller}">
<ComboBox.ItemTemplate>
<DataTemplate DataType="models:ControllerModel">
<TextBlock Text="{Binding Name}" />
@@ -723,7 +722,7 @@
<Button
Margin="10"
Grid.Column="1"
- Command="{ReflectionBinding ShowMotionConfig}">
+ Command="{Binding ShowMotionConfig}">
<TextBlock Text="{locale:Locale ControllerSettingsConfigureGeneral}" />
</Button>
</Grid>
@@ -750,7 +749,7 @@
<Button
Margin="10"
Grid.Column="1"
- Command="{ReflectionBinding ShowRumbleConfig}">
+ Command="{Binding ShowRumbleConfig}">
<TextBlock Text="{locale:Locale ControllerSettingsConfigureGeneral}" />
</Button>
</Grid>
diff --git a/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml.cs
index 19009f5f..35129706 100644
--- a/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml.cs
@@ -31,8 +31,7 @@ namespace Ryujinx.Ava.UI.Views.Input
{
if (visual is ToggleButton button && visual is not CheckBox)
{
- button.Checked += Button_Checked;
- button.Unchecked += Button_Unchecked;
+ button.IsCheckedChanged += Button_IsCheckedChanged;
}
}
}
@@ -47,48 +46,56 @@ namespace Ryujinx.Ava.UI.Views.Input
}
}
- private void Button_Checked(object sender, RoutedEventArgs e)
+ private void Button_IsCheckedChanged(object sender, RoutedEventArgs e)
{
if (sender is ToggleButton button)
{
- if (_currentAssigner != null && button == _currentAssigner.ToggledButton)
+ if ((bool)button.IsChecked)
{
- return;
- }
+ if (_currentAssigner != null && button == _currentAssigner.ToggledButton)
+ {
+ return;
+ }
- bool isStick = button.Tag != null && button.Tag.ToString() == "stick";
+ bool isStick = button.Tag != null && button.Tag.ToString() == "stick";
- if (_currentAssigner == null && (bool)button.IsChecked)
- {
- _currentAssigner = new ButtonKeyAssigner(button);
+ if (_currentAssigner == null)
+ {
+ _currentAssigner = new ButtonKeyAssigner(button);
- FocusManager.Instance.Focus(this, NavigationMethod.Pointer);
+ this.Focus(NavigationMethod.Pointer);
- PointerPressed += MouseClick;
+ PointerPressed += MouseClick;
- IKeyboard keyboard = (IKeyboard)ViewModel.AvaloniaKeyboardDriver.GetGamepad("0"); // Open Avalonia keyboard for cancel operations.
- IButtonAssigner assigner = CreateButtonAssigner(isStick);
+ IKeyboard keyboard = (IKeyboard)ViewModel.AvaloniaKeyboardDriver.GetGamepad("0"); // Open Avalonia keyboard for cancel operations.
+ IButtonAssigner assigner = CreateButtonAssigner(isStick);
- _currentAssigner.ButtonAssigned += (sender, e) =>
+ _currentAssigner.ButtonAssigned += (sender, e) =>
+ {
+ if (e.IsAssigned)
+ {
+ ViewModel.IsModified = true;
+ }
+ };
+
+ _currentAssigner.GetInputAndAssign(assigner, keyboard);
+ }
+ else
{
- if (e.IsAssigned)
+ if (_currentAssigner != null)
{
- ViewModel.IsModified = true;
- }
- };
+ ToggleButton oldButton = _currentAssigner.ToggledButton;
- _currentAssigner.GetInputAndAssign(assigner, keyboard);
+ _currentAssigner.Cancel();
+ _currentAssigner = null;
+ button.IsChecked = false;
+ }
+ }
}
else
{
- if (_currentAssigner != null)
- {
- ToggleButton oldButton = _currentAssigner.ToggledButton;
-
- _currentAssigner.Cancel();
- _currentAssigner = null;
- button.IsChecked = false;
- }
+ _currentAssigner?.Cancel();
+ _currentAssigner = null;
}
}
}
@@ -120,12 +127,6 @@ namespace Ryujinx.Ava.UI.Views.Input
return assigner;
}
- private void Button_Unchecked(object sender, RoutedEventArgs e)
- {
- _currentAssigner?.Cancel();
- _currentAssigner = null;
- }
-
private void MouseClick(object sender, PointerPressedEventArgs e)
{
bool shouldUnbind = false;
diff --git a/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml b/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml
index b1832437..71d5d746 100644
--- a/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml
@@ -8,7 +8,6 @@
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
mc:Ignorable="d"
x:Class="Ryujinx.Ava.UI.Views.Input.MotionInputView"
- x:CompileBindings="True"
x:DataType="viewModels:MotionInputViewModel"
Focusable="True">
<Grid Margin="10">
diff --git a/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml b/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml
index 3882ebe2..16190d39 100644
--- a/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml
@@ -8,7 +8,6 @@
mc:Ignorable="d"
x:Class="Ryujinx.Ava.UI.Views.Input.RumbleInputView"
x:DataType="viewModels:RumbleInputViewModel"
- x:CompileBindings="True"
Focusable="True">
<Grid Margin="10">
<Grid.RowDefinitions>
diff --git a/src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml b/src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml
index d5b5efcd..30358ada 100644
--- a/src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml
@@ -7,8 +7,7 @@
mc:Ignorable="d"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
x:DataType="viewModels:MainWindowViewModel"
- x:Class="Ryujinx.Ava.UI.Views.Main.MainMenuBarView"
- x:CompileBindings="True">
+ x:Class="Ryujinx.Ava.UI.Views.Main.MainMenuBarView">
<Design.DataContext>
<viewModels:MainWindowViewModel />
</Design.DataContext>
@@ -25,12 +24,12 @@
</Menu.ItemsPanel>
<MenuItem VerticalAlignment="Center" Header="{locale:Locale MenuBarFile}">
<MenuItem
- Command="{ReflectionBinding OpenFile}"
+ Command="{Binding OpenFile}"
Header="{locale:Locale MenuBarFileOpenFromFile}"
IsEnabled="{Binding EnableNonGameRunningControls}"
ToolTip.Tip="{locale:Locale LoadApplicationFileTooltip}" />
<MenuItem
- Command="{ReflectionBinding OpenFolder}"
+ Command="{Binding OpenFolder}"
Header="{locale:Locale MenuBarFileOpenUnpacked}"
IsEnabled="{Binding EnableNonGameRunningControls}"
ToolTip.Tip="{locale:Locale LoadApplicationFolderTooltip}" />
@@ -42,11 +41,11 @@
</MenuItem>
<Separator />
<MenuItem
- Command="{ReflectionBinding OpenRyujinxFolder}"
+ Command="{Binding OpenRyujinxFolder}"
Header="{locale:Locale MenuBarFileOpenEmuFolder}"
ToolTip.Tip="{locale:Locale OpenRyujinxFolderTooltip}" />
<MenuItem
- Command="{ReflectionBinding OpenLogsFolder}"
+ Command="{Binding OpenLogsFolder}"
Header="{locale:Locale MenuBarFileOpenLogsFolder}"
ToolTip.Tip="{locale:Locale OpenRyujinxLogsTooltip}" />
<Separator />
@@ -57,35 +56,75 @@
</MenuItem>
<MenuItem VerticalAlignment="Center" Header="{locale:Locale MenuBarOptions}">
<MenuItem
- Command="{ReflectionBinding ToggleFullscreen}"
+ Padding="-10,0,0,0"
+ Command="{Binding ToggleFullscreen}"
Header="{locale:Locale MenuBarOptionsToggleFullscreen}"
InputGesture="F11" />
- <MenuItem>
+ <MenuItem
+ Padding="0"
+ Command="{Binding ToggleStartGamesInFullscreen}"
+ Header="{locale:Locale MenuBarOptionsStartGamesInFullscreen}">
<MenuItem.Icon>
- <CheckBox IsChecked="{Binding StartGamesInFullscreen, Mode=TwoWay}"
- MinWidth="250">
- <TextBlock Text="{locale:Locale MenuBarOptionsStartGamesInFullscreen}"/>
- </CheckBox>
+ <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 IsVisible="{Binding ShowConsoleVisible}">
+ <MenuItem
+ Padding="0"
+ IsVisible="{Binding ShowConsoleVisible}"
+ Command="{Binding ToggleShowConsole}"
+ Header="{locale:Locale MenuBarOptionsShowConsole}">
<MenuItem.Icon>
- <CheckBox IsChecked="{Binding ShowConsole, Mode=TwoWay}"
- MinWidth="250">
- <TextBlock Text="{locale:Locale MenuBarOptionsShowConsole}"/>
- </CheckBox>
+ <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" Header="{locale:Locale MenuBarOptionsChangeLanguage}" />
- <MenuItem Name="ToggleFileTypesMenuItem" Header="{locale:Locale MenuBarShowFileTypes}" />
+ <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="{ReflectionBinding ManageProfiles}"
+ Command="{Binding ManageProfiles}"
+ Padding="-10,0,0,0"
Header="{locale:Locale MenuBarOptionsManageUserProfiles}"
IsEnabled="{Binding EnableNonGameRunningControls}"
ToolTip.Tip="{locale:Locale OpenProfileManagerTooltip}" />
@@ -113,7 +152,7 @@
InputGesture="Escape"
IsEnabled="{Binding IsGameRunning}"
ToolTip.Tip="{locale:Locale StopEmulationTooltip}" />
- <MenuItem Command="{ReflectionBinding SimulateWakeUpMessage}" Header="{locale:Locale MenuBarOptionsSimulateWakeUpMessage}" />
+ <MenuItem Command="{Binding SimulateWakeUpMessage}" Header="{locale:Locale MenuBarOptionsSimulateWakeUpMessage}" />
<Separator />
<MenuItem
Name="ScanAmiiboMenuItem"
@@ -122,12 +161,12 @@
Header="{locale:Locale MenuBarActionsScanAmiibo}"
IsEnabled="{Binding IsAmiiboRequested}" />
<MenuItem
- Command="{ReflectionBinding TakeScreenshot}"
+ Command="{Binding TakeScreenshot}"
Header="{locale:Locale MenuBarFileToolsTakeScreenshot}"
InputGesture="{Binding ScreenshotKey}"
IsEnabled="{Binding IsGameRunning}" />
<MenuItem
- Command="{ReflectionBinding HideUi}"
+ Command="{Binding HideUi}"
Header="{locale:Locale MenuBarFileToolsHideUi}"
InputGesture="{Binding ShowUiKey}"
IsEnabled="{Binding IsGameRunning}" />
@@ -138,8 +177,8 @@
</MenuItem>
<MenuItem VerticalAlignment="Center" Header="{locale:Locale MenuBarTools}">
<MenuItem Header="{locale:Locale MenuBarToolsInstallFirmware}" IsEnabled="{Binding EnableNonGameRunningControls}">
- <MenuItem Command="{ReflectionBinding InstallFirmwareFromFile}" Header="{locale:Locale MenuBarFileToolsInstallFirmwareFromFile}" />
- <MenuItem Command="{ReflectionBinding InstallFirmwareFromFolder}" Header="{locale:Locale MenuBarFileToolsInstallFirmwareFromDirectory}" />
+ <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"/>
diff --git a/src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs
index ae52f071..af8c4dab 100644
--- a/src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs
@@ -30,8 +30,8 @@ namespace Ryujinx.Ava.UI.Views.Main
{
InitializeComponent();
- ToggleFileTypesMenuItem.Items = GenerateToggleFileTypeItems();
- ChangeLanguageMenuItem.Items = GenerateLanguageMenuItems();
+ ToggleFileTypesMenuItem.ItemsSource = GenerateToggleFileTypeItems();
+ ChangeLanguageMenuItem.ItemsSource = GenerateLanguageMenuItems();
}
private CheckBox[] GenerateToggleFileTypeItems()
@@ -45,7 +45,7 @@ namespace Ryujinx.Ava.UI.Views.Main
{
Content = $".{fileName}",
IsChecked = ((FileTypes)item).GetConfigValue(ConfigurationState.Instance.Ui.ShownFileTypes),
- Command = MiniCommand.Create(() => ViewModel.ToggleFileType(fileName)),
+ Command = MiniCommand.Create(() => Window.ToggleFileType(fileName)),
});
}
diff --git a/src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml b/src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml
index 16705695..58e06a1c 100644
--- a/src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml
@@ -8,7 +8,6 @@
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Ryujinx.Ava.UI.Views.Main.MainStatusBarView"
- x:CompileBindings="True"
x:DataType="viewModels:MainWindowViewModel">
<Design.DataContext>
<viewModels:MainWindowViewModel />
@@ -46,7 +45,7 @@
Margin="0,0,5,0"
VerticalAlignment="Center"
Background="Transparent"
- Command="{ReflectionBinding LoadApplications}">
+ Click="Refresh_OnClick">
<ui:SymbolIcon
Width="50"
Height="100"
@@ -64,7 +63,7 @@
Grid.Column="2"
Height="6"
VerticalAlignment="Center"
- Foreground="{DynamicResource HighlightColor}"
+ Foreground="{DynamicResource SystemAccentColorLight2}"
IsVisible="{Binding StatusBarVisible}"
Maximum="{Binding StatusBarProgressMaximum}"
Value="{Binding StatusBarProgressValue}" />
@@ -93,6 +92,7 @@
Height="12"
Margin="0"
BorderBrush="Gray"
+ Background="Gray"
BorderThickness="1"
IsVisible="{Binding !ShowLoadProgress}" />
<TextBlock
@@ -109,6 +109,7 @@
Height="12"
Margin="0"
BorderBrush="Gray"
+ Background="Gray"
BorderThickness="1"
IsVisible="{Binding !ShowLoadProgress}" />
<TextBlock
@@ -125,20 +126,32 @@
Height="12"
Margin="0"
BorderBrush="Gray"
+ Background="Gray"
BorderThickness="1"
IsVisible="{Binding !ShowLoadProgress}" />
- <ui:ToggleSplitButton
+ <ToggleSplitButton
Name="VolumeStatus"
Padding="5,0,5,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
VerticalContentAlignment="Center"
- Background="{DynamicResource ThemeContentBackgroundColor}"
- BorderThickness="0"
Content="{Binding VolumeStatusText}"
IsChecked="{Binding VolumeMuted}"
- IsVisible="{Binding !ShowLoadProgress}">
- <ui:ToggleSplitButton.Flyout>
+ IsVisible="{Binding !ShowLoadProgress}"
+ 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">
<Slider
@@ -156,13 +169,14 @@
Value="{Binding Volume}" />
</Grid>
</Flyout>
- </ui:ToggleSplitButton.Flyout>
- </ui:ToggleSplitButton>
+ </ToggleSplitButton.Flyout>
+ </ToggleSplitButton>
<Border
Width="2"
Height="12"
Margin="0"
BorderBrush="Gray"
+ Background="Gray"
BorderThickness="1"
IsVisible="{Binding !ShowLoadProgress}" />
<TextBlock
@@ -177,6 +191,7 @@
Height="12"
Margin="0"
BorderBrush="Gray"
+ Background="Gray"
BorderThickness="1"
IsVisible="{Binding !ShowLoadProgress}" />
<TextBlock
@@ -191,6 +206,7 @@
Height="12"
Margin="0"
BorderBrush="Gray"
+ Background="Gray"
BorderThickness="1"
IsVisible="{Binding !ShowLoadProgress}" />
<TextBlock
@@ -205,6 +221,7 @@
Height="12"
Margin="0"
BorderBrush="Gray"
+ Background="Gray"
BorderThickness="1"
IsVisible="{Binding !ShowLoadProgress}" />
<TextBlock
@@ -229,4 +246,4 @@
Text="{locale:Locale StatusBarSystemVersion}" />
</StackPanel>
</Grid>
-</UserControl> \ No newline at end of file
+</UserControl>
diff --git a/src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml.cs
index 0640869c..a0acc277 100644
--- a/src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml.cs
@@ -1,6 +1,7 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;
+using Avalonia.Interactivity;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
@@ -48,5 +49,10 @@ namespace Ryujinx.Ava.UI.Views.Main
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();
+ }
}
}
diff --git a/src/Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml b/src/Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml
index f7dbf2b2..f5a17742 100644
--- a/src/Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml
+++ b/src/Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml
@@ -9,7 +9,6 @@
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:CompileBindings="True"
x:DataType="viewModels:MainWindowViewModel">
<Design.DataContext>
<viewModels:MainWindowViewModel />
@@ -23,7 +22,7 @@
MinWidth="40"
Margin="5,2,0,2"
VerticalAlignment="Stretch"
- Command="{ReflectionBinding SetListMode}"
+ Command="{Binding SetListMode}"
IsEnabled="{Binding IsGrid}">
<ui:FontIcon
Margin="0"
@@ -37,7 +36,7 @@
MinWidth="40"
Margin="5,2,5,2"
VerticalAlignment="Stretch"
- Command="{ReflectionBinding SetGridMode}"
+ Command="{Binding SetGridMode}"
IsEnabled="{Binding IsList}">
<ui:FontIcon
Margin="0"
@@ -79,13 +78,13 @@
KeyUp="SearchBox_OnKeyUp"
Text="{Binding SearchText}"
Watermark="{locale:Locale MenuSearch}" />
- <ui:DropDownButton
+ <DropDownButton
Width="150"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Content="{Binding SortName}"
DockPanel.Dock="Right">
- <ui:DropDownButton.Flyout>
+ <DropDownButton.Flyout>
<Flyout Placement="Bottom">
<StackPanel
Margin="0"
@@ -164,8 +163,8 @@
Tag="Descending" />
</StackPanel>
</Flyout>
- </ui:DropDownButton.Flyout>
- </ui:DropDownButton>
+ </DropDownButton.Flyout>
+ </DropDownButton>
<TextBlock
Margin="10,0"
HorizontalAlignment="Right"
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsAudioView.axaml b/src/Ryujinx.Ava/UI/Views/Settings/SettingsAudioView.axaml
index 35283353..5dc0fef5 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsAudioView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/Settings/SettingsAudioView.axaml
@@ -1,4 +1,4 @@
-<UserControl
+<UserControl
x:Class="Ryujinx.Ava.UI.Views.Settings.SettingsAudioView"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
@@ -8,7 +8,6 @@
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
mc:Ignorable="d"
- x:CompileBindings="True"
x:DataType="viewModels:SettingsViewModel">
<Design.DataContext>
<viewModels:SettingsViewModel />
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsCPUView.axaml b/src/Ryujinx.Ava/UI/Views/Settings/SettingsCPUView.axaml
index e98b963c..c74d3dd5 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsCPUView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/Settings/SettingsCPUView.axaml
@@ -7,7 +7,6 @@
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
mc:Ignorable="d"
- x:CompileBindings="True"
x:DataType="viewModels:SettingsViewModel">
<Design.DataContext>
<viewModels:SettingsViewModel />
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml b/src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml
index 670de69c..9dc67dad 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml
@@ -1,4 +1,4 @@
-<UserControl
+<UserControl
x:Class="Ryujinx.Ava.UI.Views.Settings.SettingsGraphicsView"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
@@ -9,7 +9,6 @@
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
Design.Width="1000"
mc:Ignorable="d"
- x:CompileBindings="True"
x:DataType="viewModels:SettingsViewModel">
<Design.DataContext>
<viewModels:SettingsViewModel />
@@ -54,7 +53,7 @@
HorizontalContentAlignment="Left"
ToolTip.Tip="{locale:Locale SettingsTabGraphicsPreferredGpuTooltip}"
SelectedIndex="{Binding PreferredGpuIndex}"
- Items="{Binding AvailableGpus}"/>
+ ItemsSource="{Binding AvailableGpus}"/>
</StackPanel>
</StackPanel>
<Separator Height="1" />
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml b/src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml
index 361125bf..a53c1dfe 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml
@@ -1,4 +1,4 @@
-<UserControl
+<UserControl
x:Class="Ryujinx.Ava.UI.Views.Settings.SettingsHotkeysView"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
@@ -8,7 +8,6 @@
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
mc:Ignorable="d"
- x:CompileBindings="True"
x:DataType="viewModels:SettingsViewModel"
Focusable="True">
<Design.DataContext>
@@ -17,7 +16,7 @@
<UserControl.Resources>
<helpers:KeyValueConverter x:Key="Key" />
</UserControl.Resources>
- <ScrollViewer
+ <ScrollViewer
Name="HotkeysPage"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml.cs
index 4bbd0133..b6f2d6c0 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml.cs
@@ -42,7 +42,7 @@ namespace Ryujinx.Ava.UI.Views.Settings
{
_currentAssigner = new ButtonKeyAssigner(button);
- FocusManager.Instance?.Focus(this, NavigationMethod.Pointer);
+ this.Focus(NavigationMethod.Pointer);
PointerPressed += MouseClick;
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml b/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml
index 22ff38f5..81f4b68b 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml
@@ -8,7 +8,6 @@
xmlns:views="clr-namespace:Ryujinx.Ava.UI.Views.Input"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
mc:Ignorable="d"
- x:CompileBindings="True"
x:DataType="viewModels:SettingsViewModel">
<Design.DataContext>
<viewModels:SettingsViewModel />
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsLoggingView.axaml b/src/Ryujinx.Ava/UI/Views/Settings/SettingsLoggingView.axaml
index 948e7181..0fc9ea1b 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsLoggingView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/Settings/SettingsLoggingView.axaml
@@ -8,7 +8,6 @@
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
mc:Ignorable="d"
- x:CompileBindings="True"
x:DataType="viewModels:SettingsViewModel">
<Design.DataContext>
<viewModels:SettingsViewModel />
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsNetworkView.axaml b/src/Ryujinx.Ava/UI/Views/Settings/SettingsNetworkView.axaml
index ab8a7f6d..6ce1bb94 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsNetworkView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/Settings/SettingsNetworkView.axaml
@@ -7,7 +7,6 @@
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
mc:Ignorable="d"
- x:CompileBindings="True"
x:DataType="viewModels:SettingsViewModel">
<Design.DataContext>
<viewModels:SettingsViewModel />
@@ -37,7 +36,7 @@
<ComboBox SelectedIndex="{Binding NetworkInterfaceIndex}"
ToolTip.Tip="{locale:Locale NetworkInterfaceTooltip}"
HorizontalContentAlignment="Left"
- Items="{Binding NetworkInterfaceList}"
+ ItemsSource="{Binding NetworkInterfaceList}"
Width="250" />
</StackPanel>
</StackPanel>
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsSystemView.axaml b/src/Ryujinx.Ava/UI/Views/Settings/SettingsSystemView.axaml
index cc60ef24..e6f7c6e4 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsSystemView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/Settings/SettingsSystemView.axaml
@@ -3,12 +3,15 @@
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:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- x:CompileBindings="True"
- x:DataType="viewModels:SettingsViewModel"
- mc:Ignorable="d">
+ 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>
@@ -24,18 +27,24 @@
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
+ Classes="h1"
+ Text="{locale:Locale SettingsTabSystemCore}" />
+ <StackPanel
+ Margin="10,0,0,0"
+ Orientation="Vertical">
+ <StackPanel
+ Margin="0,0,0,10"
+ Orientation="Horizontal">
<TextBlock
- Width="250"
VerticalAlignment="Center"
- Text="{locale:Locale SettingsTabSystemSystemRegion}" />
+ Text="{locale:Locale SettingsTabSystemSystemRegion}"
+ Width="250" />
<ComboBox
- Width="350"
- HorizontalContentAlignment="Left"
SelectedIndex="{Binding Region}"
- ToolTip.Tip="{locale:Locale RegionTooltip}">
+ ToolTip.Tip="{locale:Locale RegionTooltip}"
+ HorizontalContentAlignment="Left"
+ Width="350">
<ComboBoxItem>
<TextBlock Text="{locale:Locale SettingsTabSystemSystemRegionJapan}" />
</ComboBoxItem>
@@ -59,17 +68,19 @@
</ComboBoxItem>
</ComboBox>
</StackPanel>
- <StackPanel Margin="0,0,0,10" Orientation="Horizontal">
+ <StackPanel
+ Margin="0,0,0,10"
+ Orientation="Horizontal">
<TextBlock
- Width="250"
VerticalAlignment="Center"
Text="{locale:Locale SettingsTabSystemSystemLanguage}"
- ToolTip.Tip="{locale:Locale LanguageTooltip}" />
+ ToolTip.Tip="{locale:Locale LanguageTooltip}"
+ Width="250" />
<ComboBox
- Width="350"
- HorizontalContentAlignment="Left"
SelectedIndex="{Binding Language}"
- ToolTip.Tip="{locale:Locale LanguageTooltip}">
+ ToolTip.Tip="{locale:Locale LanguageTooltip}"
+ HorizontalContentAlignment="Left"
+ Width="350">
<ComboBoxItem>
<TextBlock Text="{locale:Locale SettingsTabSystemSystemLanguageJapanese}" />
</ComboBoxItem>
@@ -126,63 +137,84 @@
</ComboBoxItem>
</ComboBox>
</StackPanel>
- <StackPanel Margin="0,0,0,10" Orientation="Horizontal">
+ <StackPanel
+ Margin="0,0,0,10"
+ Orientation="Horizontal">
<TextBlock
- Width="250"
VerticalAlignment="Center"
Text="{locale:Locale SettingsTabSystemSystemTimeZone}"
- ToolTip.Tip="{locale:Locale TimezoneTooltip}" />
+ ToolTip.Tip="{locale:Locale TimezoneTooltip}"
+ Width="250" />
<AutoCompleteBox
Name="TimeZoneBox"
Width="350"
- FilterMode="Contains"
- Items="{Binding TimeZones}"
MaxDropDownHeight="500"
+ FilterMode="Contains"
+ ItemsSource="{Binding TimeZones}"
SelectionChanged="TimeZoneBox_OnSelectionChanged"
Text="{Binding Path=TimeZone, Mode=OneWay}"
TextChanged="TimeZoneBox_OnTextChanged"
- ToolTip.Tip="{locale:Locale TimezoneTooltip}" />
+ ToolTip.Tip="{locale:Locale TimezoneTooltip}"
+ ValueMemberBinding="{Binding Mode=OneWay, Converter={StaticResource TimeZone}}" />
</StackPanel>
- <StackPanel Margin="0,0,0,10" Orientation="Horizontal">
+ <StackPanel
+ Margin="0,0,0,10"
+ Orientation="Horizontal">
<TextBlock
- Width="250"
VerticalAlignment="Center"
Text="{locale:Locale SettingsTabSystemSystemTime}"
- ToolTip.Tip="{locale:Locale TimeTooltip}" />
+ ToolTip.Tip="{locale:Locale TimeTooltip}"
+ Width="250"/>
<DatePicker
- Width="350"
- VerticalAlignment="Center"
+ VerticalAlignment="Center"
SelectedDate="{Binding CurrentDate}"
- ToolTip.Tip="{locale:Locale TimeTooltip}" />
+ ToolTip.Tip="{locale:Locale TimeTooltip}"
+ Width="350" />
</StackPanel>
- <StackPanel Margin="250,0,0,10" Orientation="Horizontal">
+ <StackPanel
+ Margin="250,0,0,10"
+ Orientation="Horizontal">
<TimePicker
- Width="350"
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}" />
+ <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}" />
+ <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
+ 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}">
+ <CheckBox
+ IsChecked="{Binding ExpandDramSize}"
+ ToolTip.Tip="{locale:Locale DRamTooltip}">
<TextBlock Text="{locale:Locale SettingsTabSystemExpandDramSize}" />
</CheckBox>
- <CheckBox IsChecked="{Binding IgnoreMissingServices}" ToolTip.Tip="{locale:Locale IgnoreMissingServicesTooltip}">
+ <CheckBox
+ IsChecked="{Binding IgnoreMissingServices}"
+ ToolTip.Tip="{locale:Locale IgnoreMissingServicesTooltip}">
<TextBlock Text="{locale:Locale SettingsTabSystemIgnoreMissingServices}" />
</CheckBox>
</StackPanel>
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsSystemView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Settings/SettingsSystemView.axaml.cs
index 4acf2f44..216561dc 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsSystemView.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Views/Settings/SettingsSystemView.axaml.cs
@@ -1,9 +1,5 @@
using Avalonia.Controls;
-using Avalonia.Data;
-using Avalonia.Data.Converters;
using Ryujinx.Ava.UI.ViewModels;
-using System;
-using System.Linq;
using TimeZone = Ryujinx.Ava.UI.Models.TimeZone;
namespace Ryujinx.Ava.UI.Views.Settings
@@ -15,15 +11,6 @@ namespace Ryujinx.Ava.UI.Views.Settings
public SettingsSystemView()
{
InitializeComponent();
-
- FuncMultiValueConverter<string, string> converter = new(parts => string.Format("{0} {1} {2}", parts.ToArray()).Trim());
- MultiBinding tzMultiBinding = new() { Converter = converter };
-
- tzMultiBinding.Bindings.Add(new Binding("UtcDifference"));
- tzMultiBinding.Bindings.Add(new Binding("Location"));
- tzMultiBinding.Bindings.Add(new Binding("Abbreviation"));
-
- TimeZoneBox.ValueMemberBinding = tzMultiBinding;
}
private void TimeZoneBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
@@ -39,13 +26,11 @@ namespace Ryujinx.Ava.UI.Views.Settings
}
}
- private void TimeZoneBox_OnTextChanged(object sender, EventArgs e)
+ private void TimeZoneBox_OnTextChanged(object sender, TextChangedEventArgs e)
{
if (sender is AutoCompleteBox box && box.SelectedItem is TimeZone timeZone)
{
- {
- ViewModel.ValidateAndSetTimeZone(timeZone.Location);
- }
+ ViewModel.ValidateAndSetTimeZone(timeZone.Location);
}
}
}
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml b/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml
index c92d5672..b7471d38 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml
@@ -7,7 +7,6 @@
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
mc:Ignorable="d"
- x:CompileBindings="True"
x:DataType="viewModels:SettingsViewModel">
<Design.DataContext>
<viewModels:SettingsViewModel />
@@ -66,7 +65,7 @@
<ListBox
Name="GameList"
MinHeight="230"
- Items="{Binding GameDirectories}">
+ ItemsSource="{Binding GameDirectories}">
<ListBox.Styles>
<Style Selector="ListBoxItem">
<Setter Property="Padding" Value="10" />
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml.cs
index 132435e0..a38a8865 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml.cs
@@ -1,7 +1,7 @@
-using Avalonia;
using Avalonia.Controls;
-using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Interactivity;
+using Avalonia.Platform.Storage;
+using Avalonia.VisualTree;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.ViewModels;
using System.Collections.Generic;
@@ -30,13 +30,16 @@ namespace Ryujinx.Ava.UI.Views.Settings
}
else
{
- if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
+ if (this.GetVisualRoot() is Window window)
{
- path = await new OpenFolderDialog().ShowAsync(desktop.MainWindow);
+ var result = await window.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
+ {
+ AllowMultiple = false
+ });
- if (!string.IsNullOrWhiteSpace(path))
+ if (result.Count > 0)
{
- ViewModel.GameDirectories.Add(path);
+ ViewModel.GameDirectories.Add(result[0].Path.LocalPath);
ViewModel.DirectoryChanged = true;
}
}
@@ -61,22 +64,25 @@ namespace Ryujinx.Ava.UI.Views.Settings
public async void BrowseTheme(object sender, RoutedEventArgs e)
{
- var dialog = new OpenFileDialog
+ var window = this.GetVisualRoot() as Window;
+ var result = await window.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
{
Title = LocaleManager.Instance[LocaleKeys.SettingsSelectThemeFileDialogTitle],
AllowMultiple = false,
- };
-
- dialog.Filters.Add(new FileDialogFilter { Extensions = { "xaml" }, Name = LocaleManager.Instance[LocaleKeys.SettingsXamlThemeFile] });
-
- if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
- {
- var file = await dialog.ShowAsync(desktop.MainWindow);
-
- if (file != null && file.Length > 0)
+ FileTypeFilter = new List<FilePickerFileType>
{
- ViewModel.CustomThemePath = file[0];
+ new("xml")
+ {
+ Patterns = new[] { "*.xaml" },
+ AppleUniformTypeIdentifiers = new[] { "com.ryujinx.xaml" },
+ MimeTypes = new[] { "application/xaml+xml" }
+ }
}
+ });
+
+ if (result.Count > 0)
+ {
+ ViewModel.CustomThemePath = result[0].Path.LocalPath;
}
}
}
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserEditorView.axaml b/src/Ryujinx.Ava/UI/Views/User/UserEditorView.axaml
index 7e55f25e..ab83c2cd 100644
--- a/src/Ryujinx.Ava/UI/Views/User/UserEditorView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/User/UserEditorView.axaml
@@ -13,7 +13,6 @@
Padding="0"
mc:Ignorable="d"
Focusable="True"
- x:CompileBindings="True"
x:DataType="models:TempProfile">
<UserControl.Resources>
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserFirmwareAvatarSelectorView.axaml b/src/Ryujinx.Ava/UI/Views/User/UserFirmwareAvatarSelectorView.axaml
index d46fcefc..21dfc909 100644
--- a/src/Ryujinx.Ava/UI/Views/User/UserFirmwareAvatarSelectorView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/User/UserFirmwareAvatarSelectorView.axaml
@@ -12,7 +12,6 @@
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:CompileBindings="True"
x:DataType="viewModels:UserFirmwareAvatarSelectorViewModel"
Focusable="True">
<Design.DataContext>
@@ -36,7 +35,7 @@
BorderThickness="0"
SelectedIndex="{Binding SelectedIndex}"
Height="400"
- Items="{Binding Images}"
+ ItemsSource="{Binding Images}"
HorizontalAlignment="Stretch"
VerticalAlignment="Center">
<ListBox.ItemsPanel>
@@ -54,7 +53,7 @@
<Setter Property="MaxWidth" Value="85" />
<Setter Property="MinWidth" Value="85" />
</Style>
- <Style Selector="ListBoxItem /template/ Border#SelectionIndicator">
+ <Style Selector="ListBoxItem /template/ Rectangle#SelectionIndicator">
<Setter Property="MinHeight" Value="70" />
</Style>
</ListBox.Styles>
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserProfileImageSelectorView.axaml b/src/Ryujinx.Ava/UI/Views/User/UserProfileImageSelectorView.axaml
index b9f51fdc..65fbd443 100644
--- a/src/Ryujinx.Ava/UI/Views/User/UserProfileImageSelectorView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/User/UserProfileImageSelectorView.axaml
@@ -9,7 +9,6 @@
Focusable="True"
mc:Ignorable="d"
x:Class="Ryujinx.Ava.UI.Views.User.UserProfileImageSelectorView"
- x:CompileBindings="True"
x:DataType="viewModles:UserProfileImageSelectorViewModel"
Width="500"
d:DesignWidth="500">
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserProfileImageSelectorView.axaml.cs b/src/Ryujinx.Ava/UI/Views/User/UserProfileImageSelectorView.axaml.cs
index 26b77dcd..e9bf4408 100644
--- a/src/Ryujinx.Ava/UI/Views/User/UserProfileImageSelectorView.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Views/User/UserProfileImageSelectorView.axaml.cs
@@ -1,5 +1,6 @@
using Avalonia.Controls;
using Avalonia.Interactivity;
+using Avalonia.Platform.Storage;
using Avalonia.VisualTree;
using FluentAvalonia.UI.Controls;
using FluentAvalonia.UI.Navigation;
@@ -10,6 +11,7 @@ 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;
@@ -63,33 +65,25 @@ namespace Ryujinx.Ava.UI.Views.User
private async void Import_OnClick(object sender, RoutedEventArgs e)
{
- OpenFileDialog dialog = new();
- dialog.Filters.Add(new FileDialogFilter
+ var window = this.GetVisualRoot() as Window;
+ var result = await window.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
{
- Name = LocaleManager.Instance[LocaleKeys.AllSupportedFormats],
- Extensions = { "jpg", "jpeg", "png", "bmp" },
- });
- dialog.Filters.Add(new FileDialogFilter { Name = "JPEG", Extensions = { "jpg", "jpeg" } });
- dialog.Filters.Add(new FileDialogFilter { Name = "PNG", Extensions = { "png" } });
- dialog.Filters.Add(new FileDialogFilter { Name = "BMP", Extensions = { "bmp" } });
-
- dialog.AllowMultiple = false;
-
- string[] image = await dialog.ShowAsync(((TopLevel)_parent.GetVisualRoot()) as Window);
-
- if (image != null)
- {
- if (image.Length > 0)
+ AllowMultiple = false,
+ FileTypeFilter = new List<FilePickerFileType>
{
- string imageFile = image[0];
-
- _profile.Image = ProcessProfileImage(File.ReadAllBytes(imageFile));
-
- if (_profile.Image != null)
+ new(LocaleManager.Instance[LocaleKeys.AllSupportedFormats])
{
- _parent.GoBack();
+ 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();
}
}
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserRecovererView.axaml b/src/Ryujinx.Ava/UI/Views/User/UserRecovererView.axaml
index 62b5e184..debf4b84 100644
--- a/src/Ryujinx.Ava/UI/Views/User/UserRecovererView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/User/UserRecovererView.axaml
@@ -12,7 +12,6 @@
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:CompileBindings="True"
x:DataType="viewModels:UserProfileViewModel"
Focusable="True">
<Design.DataContext>
@@ -33,7 +32,7 @@
<ListBox
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
- Items="{Binding LostProfiles}">
+ ItemsSource="{Binding LostProfiles}">
<ListBox.ItemTemplate>
<DataTemplate>
<Border
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserSaveManagerView.axaml b/src/Ryujinx.Ava/UI/Views/User/UserSaveManagerView.axaml
index ec931dd9..8bc5125a 100644
--- a/src/Ryujinx.Ava/UI/Views/User/UserSaveManagerView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/User/UserSaveManagerView.axaml
@@ -14,7 +14,6 @@
Height="450"
Width="550"
x:Class="Ryujinx.Ava.UI.Views.User.UserSaveManagerView"
- x:CompileBindings="True"
x:DataType="viewModels:UserSaveManagerViewModel"
Focusable="True">
<Design.DataContext>
@@ -107,8 +106,7 @@
VerticalAlignment="Stretch">
<ListBox
Name="SaveList"
- VirtualizationMode="None"
- Items="{Binding Views}"
+ ItemsSource="{Binding Views}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<ListBox.Styles>
@@ -117,7 +115,7 @@
<Setter Property="Margin" Value="5" />
<Setter Property="CornerRadius" Value="4" />
</Style>
- <Style Selector="ListBoxItem:selected /template/ Border#SelectionIndicator">
+ <Style Selector="ListBoxItem:selected /template/ Rectangle#SelectionIndicator">
<Setter Property="IsVisible" Value="False" />
</Style>
</ListBox.Styles>
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserSelectorView.axaml b/src/Ryujinx.Ava/UI/Views/User/UserSelectorView.axaml
index 9a6ba054..818a21d6 100644
--- a/src/Ryujinx.Ava/UI/Views/User/UserSelectorView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/User/UserSelectorView.axaml
@@ -15,7 +15,6 @@
d:DesignWidth="800"
mc:Ignorable="d"
Focusable="True"
- x:CompileBindings="True"
x:DataType="viewModels:UserProfileViewModel">
<UserControl.Resources>
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
@@ -38,7 +37,7 @@
VerticalAlignment="Center"
SelectionChanged="ProfilesList_SelectionChanged"
Background="Transparent"
- Items="{Binding Profiles}">
+ ItemsSource="{Binding Profiles}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<flex:FlexPanel
@@ -53,7 +52,7 @@
<Setter Property="Margin" Value="5 5 0 5" />
<Setter Property="CornerRadius" Value="5" />
</Style>
- <Style Selector="Border#SelectionIndicator">
+ <Style Selector="Rectangle#SelectionIndicator">
<Setter Property="Opacity" Value="0" />
</Style>
</ListBox.Styles>
@@ -61,8 +60,8 @@
<DataTemplate
DataType="models:UserProfile">
<Grid
- PointerEnter="Grid_PointerEntered"
- PointerLeave="Grid_OnPointerExited">
+ PointerEntered="Grid_PointerEntered"
+ PointerExited="Grid_OnPointerExited">
<Border
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
diff --git a/src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml b/src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml
index cc7556a6..a8fd11b2 100644
--- a/src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml
+++ b/src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml
@@ -13,7 +13,6 @@
Margin="0,-12,0,0"
d:DesignHeight="260"
d:DesignWidth="550"
- x:CompileBindings="True"
x:DataType="viewModel:AboutWindowViewModel"
Focusable="True"
mc:Ignorable="d">
@@ -64,14 +63,14 @@
FontWeight="Bold"
Text="Ryujinx"
TextAlignment="Center"
- Width="100" />
+ Width="110" />
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="11"
Text="(REE-YOU-JINX)"
TextAlignment="Center"
- Width="100" />
+ Width="110" />
</flex:FlexPanel>
</Grid>
<TextBlock
@@ -265,4 +264,4 @@
</StackPanel>
</Grid>
</Grid>
-</UserControl> \ No newline at end of file
+</UserControl>
diff --git a/src/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml b/src/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml
index 90d47b8e..caf7c1f3 100644
--- a/src/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml
+++ b/src/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml
@@ -1,4 +1,4 @@
-<window:StyleableWindow
+<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"
@@ -6,14 +6,15 @@
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"
+ 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"
+ Width="800"
+ MinHeight="650"
Height="650"
SizeToContent="Manual"
MinWidth="600"
@@ -35,11 +36,11 @@
</Grid.ColumnDefinitions>
<StackPanel Spacing="10" Orientation="Horizontal" HorizontalAlignment="Left">
<TextBlock VerticalAlignment="Center" Text="{locale:Locale AmiiboSeriesLabel}" />
- <ComboBox SelectedIndex="{Binding SeriesSelectedIndex}" Items="{Binding AmiiboSeries}" MinWidth="100" />
+ <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" Items="{Binding AmiiboList}" />
+ <ComboBox SelectedIndex="{Binding AmiiboSelectedIndex}" MinWidth="100" ItemsSource="{Binding AmiiboList}" />
</StackPanel>
</Grid>
<StackPanel Margin="20" Grid.Row="2">
diff --git a/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml b/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml
index 11e86211..b9cbcb9c 100644
--- a/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml
+++ b/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml
@@ -40,7 +40,7 @@
HorizontalAlignment="Center"
VerticalAlignment="Center"
LineHeight="18"
- Text="{Binding Heading}"
+ Text="{ReflectionBinding Heading}"
TextAlignment="Center"
TextWrapping="Wrap" />
<TextBlock
@@ -61,7 +61,7 @@
MinWidth="160"
HorizontalAlignment="Center"
VerticalAlignment="Center"
- Text="{Binding BuildId}"
+ Text="{ReflectionBinding BuildId}"
IsReadOnly="True" />
<Border
Grid.Row="3"
@@ -77,7 +77,7 @@
MinHeight="300"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
- Items="{Binding LoadedCheats}">
+ ItemsSource="{ReflectionBinding LoadedCheats}">
<TreeView.Styles>
<Styles>
<Style Selector="TreeViewItem:empty /template/ ItemsPresenter">
@@ -120,15 +120,15 @@
Name="SaveButton"
MinWidth="90"
Margin="5"
- Command="{Binding Save}"
- IsVisible="{Binding !NoCheatsFound}">
+ Command="{ReflectionBinding Save}"
+ IsVisible="{ReflectionBinding !NoCheatsFound}">
<TextBlock Text="{locale:Locale SettingsButtonSave}" />
</Button>
<Button
Name="CancelButton"
MinWidth="90"
Margin="5"
- Command="{Binding Close}">
+ Command="{ReflectionBinding Close}">
<TextBlock Text="{locale:Locale InputDialogCancel}" />
</Button>
</DockPanel>
diff --git a/src/Ryujinx.Ava/UI/Windows/ContentDialogOverlayWindow.axaml.cs b/src/Ryujinx.Ava/UI/Windows/ContentDialogOverlayWindow.axaml.cs
index a33ee518..2b12d72f 100644
--- a/src/Ryujinx.Ava/UI/Windows/ContentDialogOverlayWindow.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Windows/ContentDialogOverlayWindow.axaml.cs
@@ -1,8 +1,5 @@
using Avalonia.Controls;
using Avalonia.Media;
-#if DEBUG
-using Avalonia;
-#endif
namespace Ryujinx.Ava.UI.Windows
{
@@ -11,11 +8,9 @@ namespace Ryujinx.Ava.UI.Windows
public ContentDialogOverlayWindow()
{
InitializeComponent();
-#if DEBUG
- this.AttachDevTools();
-#endif
+
ExtendClientAreaToDecorationsHint = true;
- TransparencyLevelHint = WindowTransparencyLevel.Transparent;
+ TransparencyLevelHint = new[] { WindowTransparencyLevel.Transparent };
WindowStartupLocation = WindowStartupLocation.Manual;
SystemDecorations = SystemDecorations.None;
ExtendClientAreaTitleBarHeightHint = 0;
diff --git a/src/Ryujinx.Ava/UI/Windows/DownloadableContentManagerWindow.axaml b/src/Ryujinx.Ava/UI/Windows/DownloadableContentManagerWindow.axaml
index f4ba4f9c..1f57f34c 100644
--- a/src/Ryujinx.Ava/UI/Windows/DownloadableContentManagerWindow.axaml
+++ b/src/Ryujinx.Ava/UI/Windows/DownloadableContentManagerWindow.axaml
@@ -11,7 +11,6 @@
Width="500"
Height="380"
mc:Ignorable="d"
- x:CompileBindings="True"
x:DataType="viewModels:DownloadableContentManagerViewModel"
Focusable="True">
<Grid>
@@ -53,8 +52,8 @@
</StackPanel>
<TextBox
Grid.Column="2"
- MinHeight="27"
- MaxHeight="27"
+ MinHeight="29"
+ MaxHeight="29"
HorizontalAlignment="Stretch"
Watermark="{locale:Locale Search}"
Text="{Binding Search}" />
@@ -71,12 +70,11 @@
Padding="2.5">
<ListBox
AutoScrollToSelectedItem="False"
- VirtualizationMode="None"
SelectionMode="Multiple, Toggle"
Background="Transparent"
SelectionChanged="OnSelectionChanged"
SelectedItems="{Binding SelectedDownloadableContents, Mode=TwoWay}"
- Items="{Binding Views}">
+ ItemsSource="{Binding Views}">
<ListBox.DataTemplates>
<DataTemplate
DataType="models:DownloadableContentModel">
diff --git a/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml b/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml
index fa07d977..0d9a5949 100644
--- a/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml
+++ b/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml
@@ -18,9 +18,9 @@
MinHeight="672"
d:DesignHeight="720"
d:DesignWidth="1280"
- x:CompileBindings="True"
x:DataType="viewModels:MainWindowViewModel"
mc:Ignorable="d"
+ WindowStartupLocation="Manual"
Focusable="True">
<Window.Styles>
<Style Selector="TitleBar:fullscreen">
@@ -33,19 +33,19 @@
<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" />
- <StackPanel Grid.Row="0" IsVisible="False">
- <helpers:HotKeyControl Name="FullscreenHotKey" Command="{ReflectionBinding ToggleFullscreen}" />
- <helpers:HotKeyControl Name="FullscreenHotKey2" Command="{ReflectionBinding ToggleFullscreen}" />
- <helpers:HotKeyControl Name="FullscreenHotKeyMacOS" Command="{ReflectionBinding ToggleFullscreen}" />
- <helpers:HotKeyControl Name="DockToggleHotKey" Command="{ReflectionBinding ToggleDockMode}" />
- <helpers:HotKeyControl Name="ExitHotKey" Command="{ReflectionBinding ExitCurrentState}" />
- </StackPanel>
<Grid
Grid.Row="1"
HorizontalAlignment="Stretch"
@@ -67,7 +67,7 @@
VerticalAlignment="Stretch"
IsVisible="{Binding ShowMenuAndStatusBar}"
Orientation="Vertical">
- <main:MainMenuBarView
+ <main:MainMenuBarView
Name="MenuBarView" />
</StackPanel>
<ContentControl
@@ -197,7 +197,7 @@
</Grid>
</Grid>
</Grid>
- <main:MainStatusBarView
+ <main:MainStatusBarView
Name="StatusBarView"
Grid.Row="2" />
</Grid>
diff --git a/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs b/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs
index d79bdc56..d32360e0 100644
--- a/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs
@@ -1,6 +1,7 @@
using Avalonia;
using Avalonia.Controls;
-using Avalonia.Input;
+using Avalonia.Controls.Primitives;
+using Avalonia.Interactivity;
using Avalonia.Threading;
using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common;
@@ -21,7 +22,6 @@ using Ryujinx.Ui.Common;
using Ryujinx.Ui.Common.Configuration;
using Ryujinx.Ui.Common.Helper;
using System;
-using System.ComponentModel;
using System.IO;
using System.Runtime.Versioning;
using System.Threading.Tasks;
@@ -85,6 +85,7 @@ namespace Ryujinx.Ava.UI.Windows
ViewModel.Initialize(
ContentManager,
+ StorageProvider,
ApplicationLibrary,
VirtualFileSystem,
AccountManager,
@@ -102,11 +103,16 @@ namespace Ryujinx.Ava.UI.Windows
LoadGameList();
this.GetObservable(IsActiveProperty).Subscribe(IsActiveChanged);
+ this.ScalingChanged += OnScalingChanged;
}
ApplicationLibrary.ApplicationCountUpdated += ApplicationLibrary_ApplicationCountUpdated;
ApplicationLibrary.ApplicationAdded += ApplicationLibrary_ApplicationAdded;
- ViewModel.ReloadGameList += ReloadGameList;
+ }
+
+ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
+ {
+ base.OnApplyTemplate(e);
NotificationHelper.SetNotificationManager(this);
}
@@ -130,10 +136,9 @@ namespace Ryujinx.Ava.UI.Windows
_isLoading = false;
}
- protected override void HandleScalingChanged(double scale)
+ private void OnScalingChanged(object sender, EventArgs e)
{
- Program.DesktopScaleFactor = scale;
- base.HandleScalingChanged(scale);
+ Program.DesktopScaleFactor = this.RenderScaling;
}
public void AddApplication(ApplicationData applicationData)
@@ -221,16 +226,6 @@ namespace Ryujinx.Ava.UI.Windows
});
}
- protected override void HandleWindowStateChanged(WindowState state)
- {
- ViewModel.WindowState = state;
-
- if (state != WindowState.Minimized)
- {
- Renderer.Start();
- }
- }
-
private void Initialize()
{
_userChannelPersistence = new UserChannelPersistence();
@@ -367,14 +362,12 @@ namespace Ryujinx.Ava.UI.Windows
ApplicationList.ApplicationOpened += Application_Opened;
ApplicationList.DataContext = ViewModel;
-
- LoadHotKeys();
}
private void SetWindowSizePosition()
{
PixelPoint savedPoint = new(ConfigurationState.Instance.Ui.WindowStartup.WindowPositionX,
- ConfigurationState.Instance.Ui.WindowStartup.WindowPositionY);
+ ConfigurationState.Instance.Ui.WindowStartup.WindowPositionY);
ViewModel.WindowHeight = ConfigurationState.Instance.Ui.WindowStartup.WindowSizeHeight * Program.WindowScaleFactor;
ViewModel.WindowWidth = ConfigurationState.Instance.Ui.WindowStartup.WindowSizeWidth * Program.WindowScaleFactor;
@@ -447,18 +440,7 @@ namespace Ryujinx.Ava.UI.Windows
#pragma warning restore IDE0055
}
- public void LoadHotKeys()
- {
-#pragma warning disable IDE0055 // Disable formatting
- HotKeyManager.SetHotKey(FullscreenHotKey, new KeyGesture(Key.Enter, KeyModifiers.Alt));
- HotKeyManager.SetHotKey(FullscreenHotKey2, new KeyGesture(Key.F11));
- HotKeyManager.SetHotKey(FullscreenHotKeyMacOS, new KeyGesture(Key.F, KeyModifiers.Control | KeyModifiers.Meta));
- HotKeyManager.SetHotKey(DockToggleHotKey, new KeyGesture(Key.F9));
- HotKeyManager.SetHotKey(ExitHotKey, new KeyGesture(Key.Escape));
-#pragma warning restore IDE0055
- }
-
- private void VolumeStatus_CheckedChanged(object sender, SplitButtonClickEventArgs e)
+ private void VolumeStatus_CheckedChanged(object sender, RoutedEventArgs e)
{
var volumeSplitButton = sender as ToggleSplitButton;
if (ViewModel.IsGameRunning)
@@ -476,7 +458,7 @@ namespace Ryujinx.Ava.UI.Windows
}
}
- protected override void OnClosing(CancelEventArgs e)
+ protected override void OnClosing(WindowClosingEventArgs e)
{
if (!ViewModel.IsClosing && ViewModel.AppHost != null && ConfigurationState.Instance.ShowConfirmExit)
{
@@ -548,6 +530,25 @@ namespace Ryujinx.Ava.UI.Windows
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)
diff --git a/src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml b/src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml
index 4b248db7..a0a75f61 100644
--- a/src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml
+++ b/src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml
@@ -15,7 +15,6 @@
MinWidth="800"
MinHeight="480"
WindowStartupLocation="CenterOwner"
- x:CompileBindings="True"
x:DataType="viewModels:SettingsViewModel"
mc:Ignorable="d"
Focusable="True">
@@ -59,44 +58,44 @@
IsSelected="True"
Content="{locale:Locale SettingsTabGeneral}"
Tag="UiPage"
- Icon="New" />
+ IconSource="New" />
<ui:NavigationViewItem
Content="{locale:Locale SettingsTabInput}"
Tag="InputPage"
- Icon="Games" />
+ IconSource="Games" />
<ui:NavigationViewItem
Content="{locale:Locale SettingsTabHotkeys}"
Tag="HotkeysPage"
- Icon="Keyboard" />
+ IconSource="Keyboard" />
<ui:NavigationViewItem
Content="{locale:Locale SettingsTabSystem}"
Tag="SystemPage"
- Icon="Settings" />
+ IconSource="Settings" />
<ui:NavigationViewItem
Content="{locale:Locale SettingsTabCpu}"
Tag="CpuPage">
- <ui:NavigationViewItem.Icon>
- <ui:FontIcon
+ <ui:NavigationViewItem.IconSource>
+ <ui:FontIconSource
FontFamily="avares://Ryujinx.Ava/Assets/Fonts#Segoe Fluent Icons"
Glyph="{helpers:GlyphValueConverter Chip}" />
- </ui:NavigationViewItem.Icon>
+ </ui:NavigationViewItem.IconSource>
</ui:NavigationViewItem>
<ui:NavigationViewItem
Content="{locale:Locale SettingsTabGraphics}"
Tag="GraphicsPage"
- Icon="Image" />
+ IconSource="Image" />
<ui:NavigationViewItem
Content="{locale:Locale SettingsTabAudio}"
- Icon="Audio"
+ IconSource="Audio"
Tag="AudioPage" />
<ui:NavigationViewItem
Content="{locale:Locale SettingsTabNetwork}"
Tag="NetworkPage"
- Icon="Globe" />
+ IconSource="Globe" />
<ui:NavigationViewItem
Content="{locale:Locale SettingsTabLogging}"
Tag="LoggingPage"
- Icon="Document" />
+ IconSource="Document" />
</ui:NavigationView.MenuItems>
<ui:NavigationView.Styles>
<Style Selector="Grid#PlaceholderGrid">
@@ -115,14 +114,14 @@
HotKey="Enter"
Classes="accent"
Content="{locale:Locale SettingsButtonOk}"
- Command="{ReflectionBinding OkButton}" />
+ Command="{Binding OkButton}" />
<Button
HotKey="Escape"
Content="{locale:Locale SettingsButtonCancel}"
- Command="{ReflectionBinding CancelButton}" />
+ Command="{Binding CancelButton}" />
<Button
Content="{locale:Locale SettingsButtonApply}"
- Command="{ReflectionBinding ApplyButton}" />
+ 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
index 518c2d32..d7bb0b88 100644
--- a/src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml.cs
@@ -1,10 +1,10 @@
+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;
-using System.ComponentModel;
namespace Ryujinx.Ava.UI.Windows
{
@@ -41,7 +41,7 @@ namespace Ryujinx.Ava.UI.Windows
if (Owner is MainWindow window && ViewModel.DirectoryChanged)
{
- window.ViewModel.LoadApplications();
+ window.LoadApplications();
}
}
@@ -93,7 +93,7 @@ namespace Ryujinx.Ava.UI.Windows
}
}
- protected override void OnClosing(CancelEventArgs e)
+ protected override void OnClosing(WindowClosingEventArgs e)
{
HotkeysPage.Dispose();
InputPage.Dispose();
diff --git a/src/Ryujinx.Ava/UI/Windows/StyleableWindow.cs b/src/Ryujinx.Ava/UI/Windows/StyleableWindow.cs
index ca23a5ba..43e42804 100644
--- a/src/Ryujinx.Ava/UI/Windows/StyleableWindow.cs
+++ b/src/Ryujinx.Ava/UI/Windows/StyleableWindow.cs
@@ -11,12 +11,12 @@ namespace Ryujinx.Ava.UI.Windows
{
public class StyleableWindow : Window
{
- public IBitmap IconImage { get; set; }
+ public Bitmap IconImage { get; set; }
public StyleableWindow()
{
WindowStartupLocation = WindowStartupLocation.CenterOwner;
- TransparencyLevelHint = WindowTransparencyLevel.None;
+ TransparencyLevelHint = new[] { WindowTransparencyLevel.None };
using Stream stream = Assembly.GetAssembly(typeof(ConfigurationState)).GetManifestResourceStream("Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png");
diff --git a/src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml b/src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml
index e9858038..78fc6b28 100644
--- a/src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml
+++ b/src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml
@@ -11,7 +11,6 @@
Width="500"
Height="300"
mc:Ignorable="d"
- x:CompileBindings="True"
x:DataType="viewModels:TitleUpdateViewModel"
Focusable="True">
<Grid>
@@ -29,10 +28,9 @@
CornerRadius="5"
Padding="2.5">
<ListBox
- VirtualizationMode="None"
Background="Transparent"
SelectedItem="{Binding SelectedUpdate, Mode=TwoWay}"
- Items="{Binding Views}">
+ ItemsSource="{Binding Views}">
<ListBox.DataTemplates>
<DataTemplate
DataType="models:TitleUpdateModel">
@@ -103,7 +101,7 @@
<Button
Name="AddButton"
MinWidth="90"
- Command="{ReflectionBinding Add}">
+ Command="{Binding Add}">
<TextBlock Text="{locale:Locale SettingsTabGeneralAdd}" />
</Button>
<Button
diff --git a/src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml.cs b/src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml.cs
index f4fcad31..7ece6335 100644
--- a/src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml.cs
@@ -61,7 +61,7 @@ namespace Ryujinx.Ava.UI.Windows
if (VisualRoot is MainWindow window)
{
- window.ViewModel.LoadApplications();
+ window.LoadApplications();
}
((ContentDialog)Parent).Hide();
diff --git a/src/Ryujinx.Ava/app.manifest b/src/Ryujinx.Ava/app.manifest
new file mode 100644
index 00000000..920136fb
--- /dev/null
+++ b/src/Ryujinx.Ava/app.manifest
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
+ <assemblyIdentity version="1.0.0.0" name="Ryujinx.Emulator.Avalonia"/>
+ <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+ <application>
+ <!-- Windows 10 & 11 -->
+ <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
+ </application>
+ </compatibility>
+</assembly>