diff options
75 files changed, 1219 insertions, 1048 deletions
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 @@ <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally> </PropertyGroup> <ItemGroup> - <PackageVersion Include="Avalonia" Version="0.10.21" /> - <PackageVersion Include="Avalonia.Controls.DataGrid" Version="0.10.21" /> - <PackageVersion Include="Avalonia.Desktop" Version="0.10.21" /> - <PackageVersion Include="Avalonia.Diagnostics" Version="0.10.21" /> - <PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="0.10.21" /> - <PackageVersion Include="Avalonia.Svg" Version="0.10.18" /> - <PackageVersion Include="Avalonia.Svg.Skia" Version="0.10.18" /> + <PackageVersion Include="Avalonia" Version="11.0.3" /> + <PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.0.3" /> + <PackageVersion Include="Avalonia.Desktop" Version="11.0.3" /> + <PackageVersion Include="Avalonia.Diagnostics" Version="11.0.3" /> + <PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.0.3" /> + <PackageVersion Include="Avalonia.Svg" Version="11.0.0" /> + <PackageVersion Include="Avalonia.Svg.Skia" Version="11.0.0" /> <PackageVersion Include="CommandLineParser" Version="2.9.1" /> <PackageVersion Include="Concentus" Version="1.1.7" /> <PackageVersion Include="DiscordRichPresence" Version="1.2.1.24" /> <PackageVersion Include="DynamicData" Version="7.14.2" /> - <PackageVersion Include="FluentAvaloniaUI" Version="1.4.5" /> + <PackageVersion Include="FluentAvaloniaUI" Version="2.0.1" /> <PackageVersion Include="GtkSharp.Dependencies" Version="1.1.1" /> <PackageVersion Include="GtkSharp.Dependencies.osx" Version="0.0.5" /> - <PackageVersion Include="jp2masa.Avalonia.Flexbox" Version="0.2.0" /> + <PackageVersion Include="jp2masa.Avalonia.Flexbox" Version="0.3.0-beta.4" /> <PackageVersion Include="LibHac" Version="0.18.0" /> <PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" /> <PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.6.0" /> @@ -48,6 +48,5 @@ <PackageVersion Include="System.IO.Hashing" Version="7.0.0" /> <PackageVersion Include="System.Management" Version="7.0.2" /> <PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" /> - <PackageVersion Include="XamlNameReferenceGenerator" Version="1.6.1" /> </ItemGroup> </Project>
\ 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 @@ <string>public.app-category.games</string> <key>LSMinimumSystemVersion</key> <string>11.0</string> + <key>UTExportedTypeDeclarations</key> + <array> + <dict> + <key>UTTypeDescription</key> + <string>Extensible Application Markup Language</string> + <key>UTTypeConformsTo</key> + <array> + <string>public.xml</string> + </array> + <key>UTTypeIdentifier</key> + <string>com.ryujinx.xaml</string> + <key>UTTypeTagSpecification</key> + <dict> + <key>public.filename-extension</key> + <array> + <string>xaml</string> + </array> + </dict> + </dict> + <dict> + <key>UTTypeDescription</key> + <string>Nintendo Submission Package</string> + <key>UTTypeConformsTo</key> + <array> + <string>public.data</string> + </array> + <key>UTTypeIdentifier</key> + <string>com.ryujinx.nsp</string> + <key>UTTypeTagSpecification</key> + <dict> + <key>public.filename-extension</key> + <array> + <string>nsp</string> + </array> + </dict> + </dict> + <dict> + <key>UTTypeDescription</key> + <string>Nintendo Switch Cartridge</string> + <key>UTTypeConformsTo</key> + <array> + <string>public.data</string> + </array> + <key>UTTypeIdentifier</key> + <string>com.ryujinx.xci</string> + <key>UTTypeTagSpecification</key> + <dict> + <key>public.filename-extension</key> + <array> + <string>xci</string> + </array> + </dict> + </dict> + <dict> + <key>UTTypeDescription</key> + <string>Nintendo Content Archive</string> + <key>UTTypeConformsTo</key> + <array> + <string>public.data</string> + </array> + <key>UTTypeIdentifier</key> + <string>com.ryujinx.nca</string> + <key>UTTypeTagSpecification</key> + <dict> + <key>public.filename-extension</key> + <array> + <string>nca</string> + </array> + </dict> + </dict> + <dict> + <key>UTTypeDescription</key> + <string>Nintendo Relocatable Object</string> + <key>UTTypeConformsTo</key> + <array> + <string>public.data</string> + </array> + <key>UTTypeIdentifier</key> + <string>com.ryujinx.nro</string> + <key>UTTypeTagSpecification</key> + <dict> + <key>public.filename-extension</key> + <array> + <string>nro</string> + </array> + </dict> + </dict> + <dict> + <key>UTTypeDescription</key> + <string>Nintendo Shared Object</string> + <key>UTTypeConformsTo</key> + <array> + <string>public.data</string> + </array> + <key>UTTypeIdentifier</key> + <string>com.ryujinx.nso</string> + <key>UTTypeTagSpecification</key> + <dict> + <key>public.filename-extension</key> + <array> + <string>nso</string> + </array> + </dict> + </dict> + </array> <key>LSEnvironment</key> <dict> - <key>COMPlus_DefaultStackSize</key> + <key>DOTNET_DefaultStackSize</key> <string>200000</string> </dict> </dict> -</plist> +</plist>
\ 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"> + <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 > Image"> - <Setter Property="Margin" Value="10" /> + <Setter Property="Margin" + Value="10" /> </Style> <Style Selector="#TitleBarHost > 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> |