diff --git a/Directory.Packages.props b/Directory.Packages.props index 6191c498..fbae486c 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -3,21 +3,21 @@ true - - - - - - - + + + + + + + - + - + @@ -48,6 +48,5 @@ - \ No newline at end of file diff --git a/distribution/macos/Info.plist b/distribution/macos/Info.plist index 968814f9..6e068ba2 100644 --- a/distribution/macos/Info.plist +++ b/distribution/macos/Info.plist @@ -44,10 +44,115 @@ public.app-category.games LSMinimumSystemVersion 11.0 + UTExportedTypeDeclarations + + + UTTypeDescription + Extensible Application Markup Language + UTTypeConformsTo + + public.xml + + UTTypeIdentifier + com.ryujinx.xaml + UTTypeTagSpecification + + public.filename-extension + + xaml + + + + + UTTypeDescription + Nintendo Submission Package + UTTypeConformsTo + + public.data + + UTTypeIdentifier + com.ryujinx.nsp + UTTypeTagSpecification + + public.filename-extension + + nsp + + + + + UTTypeDescription + Nintendo Switch Cartridge + UTTypeConformsTo + + public.data + + UTTypeIdentifier + com.ryujinx.xci + UTTypeTagSpecification + + public.filename-extension + + xci + + + + + UTTypeDescription + Nintendo Content Archive + UTTypeConformsTo + + public.data + + UTTypeIdentifier + com.ryujinx.nca + UTTypeTagSpecification + + public.filename-extension + + nca + + + + + UTTypeDescription + Nintendo Relocatable Object + UTTypeConformsTo + + public.data + + UTTypeIdentifier + com.ryujinx.nro + UTTypeTagSpecification + + public.filename-extension + + nro + + + + + UTTypeDescription + Nintendo Shared Object + UTTypeConformsTo + + public.data + + UTTypeIdentifier + com.ryujinx.nso + UTTypeTagSpecification + + public.filename-extension + + nso + + + + LSEnvironment - COMPlus_DefaultStackSize + DOTNET_DefaultStackSize 200000 - + \ No newline at end of file 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"> + + + + + + + + \ 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(); - - 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(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 @@ - - - - - - - - - - - - - - - - - - - - @@ -750,7 +749,7 @@ 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; - } - - bool isStick = button.Tag != null && button.Tag.ToString() == "stick"; - - if (_currentAssigner == null && (bool)button.IsChecked) - { - _currentAssigner = new ButtonKeyAssigner(button); - - FocusManager.Instance.Focus(this, NavigationMethod.Pointer); - - PointerPressed += MouseClick; - - IKeyboard keyboard = (IKeyboard)ViewModel.AvaloniaKeyboardDriver.GetGamepad("0"); // Open Avalonia keyboard for cancel operations. - IButtonAssigner assigner = CreateButtonAssigner(isStick); - - _currentAssigner.ButtonAssigned += (sender, e) => + if (_currentAssigner != null && button == _currentAssigner.ToggledButton) { - if (e.IsAssigned) - { - ViewModel.IsModified = true; - } - }; + return; + } - _currentAssigner.GetInputAndAssign(assigner, keyboard); + bool isStick = button.Tag != null && button.Tag.ToString() == "stick"; + + if (_currentAssigner == null) + { + _currentAssigner = new ButtonKeyAssigner(button); + + this.Focus(NavigationMethod.Pointer); + + PointerPressed += MouseClick; + + IKeyboard keyboard = (IKeyboard)ViewModel.AvaloniaKeyboardDriver.GetGamepad("0"); // Open Avalonia keyboard for cancel operations. + IButtonAssigner assigner = CreateButtonAssigner(isStick); + + _currentAssigner.ButtonAssigned += (sender, e) => + { + if (e.IsAssigned) + { + ViewModel.IsModified = true; + } + }; + + _currentAssigner.GetInputAndAssign(assigner, keyboard); + } + else + { + if (_currentAssigner != null) + { + ToggleButton oldButton = _currentAssigner.ToggledButton; + + _currentAssigner.Cancel(); + _currentAssigner = null; + button.IsChecked = false; + } + } } else { - 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"> 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"> 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"> @@ -25,12 +24,12 @@ @@ -42,11 +41,11 @@ @@ -57,35 +56,75 @@ - + - - - + + + + + - + - - - + + + + + - - + + @@ -113,7 +152,7 @@ InputGesture="Escape" IsEnabled="{Binding IsGameRunning}" ToolTip.Tip="{locale:Locale StopEmulationTooltip}" /> - + @@ -138,8 +177,8 @@ - - + + 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"> @@ -46,7 +45,7 @@ Margin="0,0,5,0" VerticalAlignment="Center" Background="Transparent" - Command="{ReflectionBinding LoadApplications}"> + Click="Refresh_OnClick"> @@ -93,6 +92,7 @@ Height="12" Margin="0" BorderBrush="Gray" + Background="Gray" BorderThickness="1" IsVisible="{Binding !ShowLoadProgress}" /> - - + IsVisible="{Binding !ShowLoadProgress}" + Background="Transparent" + BorderThickness="0" + CornerRadius="0"> + + + + + + - - + + - \ No newline at end of file + 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"> @@ -23,7 +22,7 @@ MinWidth="40" Margin="5,2,0,2" VerticalAlignment="Stretch" - Command="{ReflectionBinding SetListMode}" + Command="{Binding SetListMode}" IsEnabled="{Binding IsGrid}"> - - + - - + + 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"> 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 @@ - @@ -54,7 +53,7 @@ HorizontalContentAlignment="Left" ToolTip.Tip="{locale:Locale SettingsTabGraphicsPreferredGpuTooltip}" SelectedIndex="{Binding PreferredGpuIndex}" - Items="{Binding AvailableGpus}"/> + ItemsSource="{Binding AvailableGpus}"/> 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 @@ - @@ -17,7 +16,7 @@ - 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"> 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"> @@ -37,7 +36,7 @@ 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"> + + + @@ -24,18 +27,24 @@ HorizontalAlignment="Stretch" Orientation="Vertical" Spacing="10"> - - - + + + + Text="{locale:Locale SettingsTabSystemSystemRegion}" + Width="250" /> + ToolTip.Tip="{locale:Locale RegionTooltip}" + HorizontalContentAlignment="Left" + Width="350"> @@ -59,17 +68,19 @@ - + + ToolTip.Tip="{locale:Locale LanguageTooltip}" + Width="250" /> + ToolTip.Tip="{locale:Locale LanguageTooltip}" + HorizontalContentAlignment="Left" + Width="350"> @@ -126,63 +137,84 @@ - + + ToolTip.Tip="{locale:Locale TimezoneTooltip}" + Width="250" /> + ToolTip.Tip="{locale:Locale TimezoneTooltip}" + ValueMemberBinding="{Binding Mode=OneWay, Converter={StaticResource TimeZone}}" /> - + + ToolTip.Tip="{locale:Locale TimeTooltip}" + Width="250"/> + ToolTip.Tip="{locale:Locale TimeTooltip}" + Width="350" /> - + - + - + - - - + + + - + - + 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 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"> @@ -66,7 +65,7 @@ + ItemsSource="{Binding GameDirectories}"> - 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 { - 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"> @@ -33,7 +32,7 @@ + ItemsSource="{Binding LostProfiles}"> @@ -107,8 +106,7 @@ VerticalAlignment="Stretch"> @@ -117,7 +115,7 @@ - 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"> @@ -38,7 +37,7 @@ VerticalAlignment="Center" SelectionChanged="ProfilesList_SelectionChanged" Background="Transparent" - Items="{Binding Profiles}"> + ItemsSource="{Binding Profiles}"> - @@ -61,8 +60,8 @@ + PointerEntered="Grid_PointerEntered" + PointerExited="Grid_OnPointerExited"> @@ -64,14 +63,14 @@ FontWeight="Bold" Text="Ryujinx" TextAlignment="Center" - Width="100" /> + Width="110" /> + Width="110" /> - \ No newline at end of file + 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 @@ - - + - + 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" /> + ItemsSource="{ReflectionBinding LoadedCheats}">