Compare commits

..

17 Commits

Author SHA1 Message Date
Vladimir Sokolov
e8235ccae6 Merge a964bf8f68 into 7bdf013ba6 2025-03-05 19:12:21 +10:00
Vladimir Sokolov
a964bf8f68 Merge branch 'master' into Master_PR 2025-03-05 19:12:19 +10:00
Vladimir Sokolov
89e4d287d6 Merge branch 'master' into Master_PR 2025-03-05 09:18:36 +10:00
Vladimir Sokolov
f34745a66c Merge branch 'master' into Master_PR 2025-03-04 21:31:56 +10:00
Vladimir Sokolov
d5b7851c9b Merge branch 'master' into Master_PR 2025-03-03 21:22:24 +10:00
Vova
1b7032b589 smal fix 2025-03-03 00:07:05 +10:00
Vova
e097ea71ff Fix: exclude device id when loading preset (independent presets)
fixed bug when selected gamepad disappears if another gamepad was disconnected
2025-03-02 23:49:40 +10:00
Vova
299f2144c8 Bug fixes, functionality improvements:
Now the profile changes immediately upon selection.
The icon for restoring settings has been changed.
A bug has been fixed where restoring settings did not restore the previously selected gamepad.
2025-03-02 19:07:49 +10:00
Vova
33e3ba9ff2 Fixed profiles on the input page:
- profiles are unlinked from controllers
- sometimes a new profile after saving changed to the previous one, had to select it again (fixed)
- when deleting, the profile now resets the name to "default"
2025-03-01 23:44:05 +10:00
Vladimir Sokolov
9dc36646c1 Merge branch 'master' into Master_PR 2025-02-28 20:54:11 +10:00
Vova
8eea75a6e8 Small fix 2025-02-23 16:44:10 +10:00
Vladimir Sokolov
57fbcc7aed Merge branch 'master' into Master_PR 2025-02-23 16:18:11 +10:00
Vova
d1c15f3562 Fixed a bug with the (undo last changes) button in the gamepad settings 2025-02-23 16:16:43 +10:00
Vova
0423fad7ff Merge branch 'Master_PR' of https://github.com/Goodfeat/Ryujinx_alt into Master_PR 2025-02-23 16:04:12 +10:00
Vova
1951fe0077 Added the ability to delete assigned buttons with the right mouse button in the settings.
- for keyboard
- for hotkeys
2025-02-23 15:59:03 +10:00
Vladimir Sokolov
7fd5a63a5d Merge branch 'master' into Master_PR 2025-02-23 14:18:24 +10:00
Vova
a0594e8169 Improved interaction with "Input" settings.
- paired devices have notifications that they are configured and require connection
- paired devices load the configuration when connected
- A notification appears when changing control configuration settings.
- Now control settings will be saved only when they are changed
- Added a button to roll back changes to the previously saved state
- Fixed a bug: when switching the "player", if the "input device" and "controller type" settings were changed, the save dialog box did not appear.
- "Motion", "Rumble" and "Led" also have events notifying about changes
2025-02-23 10:20:42 +10:00
89 changed files with 1274 additions and 936 deletions

View File

@@ -12,8 +12,7 @@ env:
RYUJINX_BASE_VERSION: "1.2" RYUJINX_BASE_VERSION: "1.2"
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "release" RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "release"
RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "Ryubing" RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "Ryubing"
RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO: "Ryujinx" RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Ryujinx"
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Stable-Releases"
RELEASE: 1 RELEASE: 1
jobs: jobs:
@@ -34,7 +33,7 @@ jobs:
script: | script: |
github.rest.git.createRef({ github.rest.git.createRef({
owner: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}", owner: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}",
repo: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}", repo: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}",
ref: 'refs/tags/${{ steps.version_info.outputs.build_version }}', ref: 'refs/tags/${{ steps.version_info.outputs.build_version }}',
sha: context.sha sha: context.sha
}) })
@@ -53,7 +52,7 @@ jobs:
| Linux ARM 64-bit | [Stable Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) | | Linux ARM 64-bit | [Stable Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
| macOS | [Stable macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) | | macOS | [Stable macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }} **Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}
omitBodyDuringUpdate: true omitBodyDuringUpdate: true
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }} owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }} repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
@@ -93,7 +92,7 @@ jobs:
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash shell: bash
@@ -174,7 +173,7 @@ jobs:
| Linux ARM 64-bit | [Stable Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) | | Linux ARM 64-bit | [Stable Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
| macOS | [Stable macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) | | macOS | [Stable macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }} **Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}
omitBodyDuringUpdate: true omitBodyDuringUpdate: true
allowUpdates: true allowUpdates: true
replacesArtifacts: true replacesArtifacts: true
@@ -223,7 +222,7 @@ jobs:
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash shell: bash

View File

@@ -1,14 +1,14 @@
<table align="center"> <table align="center">
<tr> <tr>
<td align="center" width="25%"> <td align="center" width="25%">
<img src="https://raw.githubusercontent.com/Ryubing/Assets/refs/heads/main/RyujinxApp_1024.png" alt="Ryujinx" > <img src="https://raw.githubusercontent.com/GreemDev/ryuassets/refs/heads/main/RyujinxApp_1024.png" alt="Ryujinx" >
</td> </td>
<td align="center" width="75%"> <td align="center" width="75%">
# Ryujinx # Ryujinx
[![Release workflow](https://github.com/Ryubing/Ryujinx/actions/workflows/release.yml/badge.svg)](https://github.com/Ryubing/Ryujinx/actions/workflows/release.yml) [![Release workflow](https://github.com/Ryubing/Ryujinx/actions/workflows/release.yml/badge.svg)](https://github.com/Ryubing/Ryujinx/actions/workflows/release.yml)
[![Latest release](https://img.shields.io/github/v/release/Ryubing/Ryujinx)](https://github.com/Ryubing/Ryujinx/releases/latest) [![Latest release](https://img.shields.io/github/v/release/GreemDev/Ryujinx)](https://github.com/Ryubing/Ryujinx/releases/latest)
<br> <br>
[![Canary workflow](https://github.com/Ryubing/Ryujinx/actions/workflows/canary.yml/badge.svg)](https://github.com/Ryubing/Ryujinx/actions/workflows/canary.yml) [![Canary workflow](https://github.com/Ryubing/Ryujinx/actions/workflows/canary.yml/badge.svg)](https://github.com/Ryubing/Ryujinx/actions/workflows/canary.yml)
[![Latest canary release](https://img.shields.io/github/v/release/Ryubing/Canary-Releases?label=canary)](https://github.com/Ryubing/Canary-Releases/releases/latest) [![Latest canary release](https://img.shields.io/github/v/release/Ryubing/Canary-Releases?label=canary)](https://github.com/Ryubing/Canary-Releases/releases/latest)

View File

@@ -9,8 +9,7 @@ namespace Ryujinx.Common.Configuration
public enum DirtyHack : byte public enum DirtyHack : byte
{ {
Xc2MenuSoftlockFix = 1, Xc2MenuSoftlockFix = 1,
// ShaderTranslationDelay = 2 ShaderTranslationDelay = 2
NifmServiceDisableIsAnyInternetRequestAccepted = 3
} }
public readonly struct EnabledDirtyHack(DirtyHack hack, int value) public readonly struct EnabledDirtyHack(DirtyHack hack, int value)

View File

@@ -37,9 +37,9 @@ namespace Ryujinx.Common
public static string GetChangelogUrl(Version currentVersion, Version newVersion) => public static string GetChangelogUrl(Version currentVersion, Version newVersion) =>
IsCanaryBuild IsCanaryBuild
? $"https://github.com/{ReleaseChannelOwner}/{ReleaseChannelSourceRepo}/compare/Canary-{currentVersion}...Canary-{newVersion}" ? $"https://github.com/{ReleaseChannelOwner}/{ReleaseChannelSourceRepo}/compare/Canary-{currentVersion}...Canary-{newVersion}"
: GetChangelogForVersion(newVersion); : $"https://github.com/{ReleaseChannelOwner}/{ReleaseChannelSourceRepo}/releases/tag/{newVersion}";
public static string GetChangelogForVersion(Version version) => public static string GetChangelogForVersion(Version version) =>
$"https://github.com/{ReleaseChannelOwner}/{ReleaseChannelRepo}/releases/{version}"; $"https://github.com/{ReleaseChannelOwner}/{ReleaseChannelRepo}/releases/tag/{version}";
} }
} }

View File

@@ -1,4 +1,7 @@
using Gommon; using Gommon;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Helper;
using System;
using System.Linq; using System.Linq;
namespace Ryujinx.Common namespace Ryujinx.Common

View File

@@ -13,7 +13,7 @@ namespace Ryujinx.HLE.HOS.Services.Nifm
// CreateGeneralServiceOld() -> object<nn::nifm::detail::IGeneralService> // CreateGeneralServiceOld() -> object<nn::nifm::detail::IGeneralService>
public ResultCode CreateGeneralServiceOld(ServiceCtx context) public ResultCode CreateGeneralServiceOld(ServiceCtx context)
{ {
MakeObject(context, new IGeneralService(context)); MakeObject(context, new IGeneralService());
return ResultCode.Success; return ResultCode.Success;
} }
@@ -22,7 +22,7 @@ namespace Ryujinx.HLE.HOS.Services.Nifm
// CreateGeneralService(u64, pid) -> object<nn::nifm::detail::IGeneralService> // CreateGeneralService(u64, pid) -> object<nn::nifm::detail::IGeneralService>
public ResultCode CreateGeneralService(ServiceCtx context) public ResultCode CreateGeneralService(ServiceCtx context)
{ {
MakeObject(context, new IGeneralService(context)); MakeObject(context, new IGeneralService());
return ResultCode.Success; return ResultCode.Success;
} }

View File

@@ -1,5 +1,4 @@
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using Ryujinx.HLE.HOS.Services.Nifm.StaticService.GeneralService; using Ryujinx.HLE.HOS.Services.Nifm.StaticService.GeneralService;
@@ -18,12 +17,12 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
private UnicastIPAddressInformation _targetAddressInfoCache = null; private UnicastIPAddressInformation _targetAddressInfoCache = null;
private string _cacheChosenInterface = null; private string _cacheChosenInterface = null;
public IGeneralService(ServiceCtx context) public IGeneralService()
{ {
_generalServiceDetail = new GeneralServiceDetail _generalServiceDetail = new GeneralServiceDetail
{ {
ClientId = GeneralServiceManager.Count, ClientId = GeneralServiceManager.Count,
IsAnyInternetRequestAccepted = !context.Device.DirtyHacks.IsEnabled(DirtyHack.NifmServiceDisableIsAnyInternetRequestAccepted), // NOTE: Why not accept any internet request? IsAnyInternetRequestAccepted = true, // NOTE: Why not accept any internet request?
}; };
NetworkChange.NetworkAddressChanged += LocalInterfaceCacheHandler; NetworkChange.NetworkAddressChanged += LocalInterfaceCacheHandler;

View File

@@ -1,5 +1,6 @@
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnRyu.Proxy; using Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnRyu.Proxy;
using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;

View File

@@ -6,6 +6,7 @@ using Avalonia.Threading;
using DiscordRPC; using DiscordRPC;
using LibHac.Common; using LibHac.Common;
using LibHac.Ns; using LibHac.Ns;
using LibHac.Tools.FsSystem;
using Ryujinx.Audio.Backends.Dummy; using Ryujinx.Audio.Backends.Dummy;
using Ryujinx.Audio.Backends.OpenAL; using Ryujinx.Audio.Backends.OpenAL;
using Ryujinx.Audio.Backends.SDL2; using Ryujinx.Audio.Backends.SDL2;
@@ -34,9 +35,11 @@ using Ryujinx.Graphics.GAL.Multithreading;
using Ryujinx.Graphics.Gpu; using Ryujinx.Graphics.Gpu;
using Ryujinx.Graphics.OpenGL; using Ryujinx.Graphics.OpenGL;
using Ryujinx.Graphics.Vulkan; using Ryujinx.Graphics.Vulkan;
using Ryujinx.HLE;
using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS; using Ryujinx.HLE.HOS;
using Ryujinx.HLE.HOS.Services.Account.Acc; using Ryujinx.HLE.HOS.Services.Account.Acc;
using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.Input; using Ryujinx.Input;
using Ryujinx.Input.HLE; using Ryujinx.Input.HLE;
using SkiaSharp; using SkiaSharp;
@@ -59,7 +62,7 @@ using Size = Avalonia.Size;
using Switch = Ryujinx.HLE.Switch; using Switch = Ryujinx.HLE.Switch;
using VSyncMode = Ryujinx.Common.Configuration.VSyncMode; using VSyncMode = Ryujinx.Common.Configuration.VSyncMode;
namespace Ryujinx.Ava.Systems namespace Ryujinx.Ava
{ {
internal class AppHost internal class AppHost
{ {
@@ -467,7 +470,7 @@ namespace Ryujinx.Ava.Systems
Dispatcher.UIThread.InvokeAsync(() => Dispatcher.UIThread.InvokeAsync(() =>
{ {
_viewModel.Title = TitleHelper.ActiveApplicationTitle(Device.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowOldUI); _viewModel.Title = TitleHelper.ActiveApplicationTitle(Device.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowTitleBar);
}); });
_viewModel.SetUiProgressHandlers(Device); _viewModel.SetUiProgressHandlers(Device);
@@ -869,7 +872,7 @@ namespace Ryujinx.Ava.Systems
Device?.System.TogglePauseEmulation(false); Device?.System.TogglePauseEmulation(false);
_viewModel.IsPaused = false; _viewModel.IsPaused = false;
_viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowOldUI); _viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowTitleBar);
Logger.Info?.Print(LogClass.Emulation, "Emulation was resumed"); Logger.Info?.Print(LogClass.Emulation, "Emulation was resumed");
} }
@@ -878,7 +881,7 @@ namespace Ryujinx.Ava.Systems
Device?.System.TogglePauseEmulation(true); Device?.System.TogglePauseEmulation(true);
_viewModel.IsPaused = true; _viewModel.IsPaused = true;
_viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowOldUI, LocaleManager.Instance[LocaleKeys.Paused]); _viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowTitleBar, LocaleManager.Instance[LocaleKeys.Paused]);
Logger.Info?.Print(LogClass.Emulation, "Emulation was paused"); Logger.Info?.Print(LogClass.Emulation, "Emulation was paused");
} }

View File

@@ -49,7 +49,6 @@
<TextBlock <TextBlock
Classes="globalConfigMarker"/> Classes="globalConfigMarker"/>
</StackPanel> </StackPanel>
</Border> </Border>
</Design.PreviewWith> </Design.PreviewWith>
<Style Selector="DropDownButton"> <Style Selector="DropDownButton">

View File

@@ -469,7 +469,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Відкрити теку скріншотів", "uk_UA": "Відкрити теку скріншотів",
"zh_CN": "打开截图文件夹", "zh_CN": "打开截图文件夹",
"zh_TW": "開啟螢幕擷取畫面資料夾" "zh_TW": ""
} }
}, },
{ {
@@ -619,7 +619,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Запускати ігри з прихованим інтерфейсом", "uk_UA": "Запускати ігри з прихованим інтерфейсом",
"zh_CN": "启动游戏时隐藏 UI", "zh_CN": "启动游戏时隐藏 UI",
"zh_TW": "開啟遊戲時隱藏 UI" "zh_TW": ""
} }
}, },
{ {
@@ -1569,7 +1569,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Розроблено: {0}", "uk_UA": "Розроблено: {0}",
"zh_CN": "由 {0} 开发", "zh_CN": "由 {0} 开发",
"zh_TW": "由 {0} 開發" "zh_TW": ""
} }
}, },
{ {
@@ -1664,7 +1664,7 @@
"pl_PL": "Rozszerzenie pliku: {0}", "pl_PL": "Rozszerzenie pliku: {0}",
"pt_BR": "Extensão: {0}", "pt_BR": "Extensão: {0}",
"ru_RU": "Расширение файла: {0}", "ru_RU": "Расширение файла: {0}",
"sv_SE": "Filändelse: {0}", "sv_SE": "Filänd: {0}",
"th_TH": "นามสกุลไฟล์: {0}", "th_TH": "นามสกุลไฟล์: {0}",
"tr_TR": "Dosya Uzantısı: {0}", "tr_TR": "Dosya Uzantısı: {0}",
"uk_UA": "Розширення файлу: {0}", "uk_UA": "Розширення файлу: {0}",
@@ -1789,7 +1789,7 @@
"pl_PL": "Rozszerzenie pliku", "pl_PL": "Rozszerzenie pliku",
"pt_BR": "Extensão", "pt_BR": "Extensão",
"ru_RU": "Расширение файла", "ru_RU": "Расширение файла",
"sv_SE": "Filändelse", "sv_SE": "Filänd",
"th_TH": "นามสกุลไฟล์", "th_TH": "นามสกุลไฟล์",
"tr_TR": "Dosya Uzantısı", "tr_TR": "Dosya Uzantısı",
"uk_UA": "Розширення файлу", "uk_UA": "Розширення файлу",
@@ -1869,7 +1869,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Сумісність:", "uk_UA": "Сумісність:",
"zh_CN": "兼容性:", "zh_CN": "兼容性:",
"zh_TW": "相容性:" "zh_TW": ""
} }
}, },
{ {
@@ -1894,7 +1894,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "ID гри:", "uk_UA": "ID гри:",
"zh_CN": "标题 ID:", "zh_CN": "标题 ID:",
"zh_TW": "標題 ID:" "zh_TW": ""
} }
}, },
{ {
@@ -1919,7 +1919,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Розміщені ігри: {0}", "uk_UA": "Розміщені ігри: {0}",
"zh_CN": "服务的游戏: {0}", "zh_CN": "服务的游戏: {0}",
"zh_TW": "LDN 上主持的遊戲數量: {0}" "zh_TW": ""
} }
}, },
{ {
@@ -1944,7 +1944,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Гравців онлайн: {0}", "uk_UA": "Гравців онлайн: {0}",
"zh_CN": "在线玩家: {0}", "zh_CN": "在线玩家: {0}",
"zh_TW": "LDN 上在線的玩家數量: {0}" "zh_TW": ""
} }
}, },
{ {
@@ -2294,7 +2294,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Очистити кеш PPTC", "uk_UA": "Очистити кеш PPTC",
"zh_CN": "清理 PPTC 缓存", "zh_CN": "清理 PPTC 缓存",
"zh_TW": "清除 PPTC" "zh_TW": ""
} }
}, },
{ {
@@ -2319,7 +2319,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Видаляє всі файли кешу PPTC для застосунку", "uk_UA": "Видаляє всі файли кешу PPTC для застосунку",
"zh_CN": "删除应用程序的所有 PPTC 缓存", "zh_CN": "删除应用程序的所有 PPTC 缓存",
"zh_TW": "清除應用程式的 PPTC" "zh_TW": ""
} }
}, },
{ {
@@ -2369,7 +2369,7 @@
"tr_TR": "Uygulamanın shader önbelleğini temizler", "tr_TR": "Uygulamanın shader önbelleğini temizler",
"uk_UA": "Видаляє кеш шейдерів застосунку (гри)", "uk_UA": "Видаляє кеш шейдерів застосунку (гри)",
"zh_CN": "删除游戏的着色器缓存文件,下次启动游戏时重新生成着色器缓存文件", "zh_CN": "删除游戏的着色器缓存文件,下次启动游戏时重新生成着色器缓存文件",
"zh_TW": "除應用程式的著色器快取檔案" "zh_TW": "除應用程式的著色器快取"
} }
}, },
{ {
@@ -2644,7 +2644,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Витягти RomFS з обраного файлу DLC", "uk_UA": "Витягти RomFS з обраного файлу DLC",
"zh_CN": "从选定的 DLC 文件中解压 RomFS", "zh_CN": "从选定的 DLC 文件中解压 RomFS",
"zh_TW": "從已選擇的 DLC 檔案中提取 RomFS" "zh_TW": ""
} }
}, },
{ {
@@ -2763,13 +2763,13 @@
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
"ru_RU": "Задать индивидуальные параметры", "ru_RU": "Создать пользовательскую конфигурацию",
"sv_SE": "", "sv_SE": "",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Створити користувацьку конфігурацію", "uk_UA": "",
"zh_CN": "创建自定义设置", "zh_CN": "",
"zh_TW": "建立遊戲獨立自訂 (per-game) 設定檔" "zh_TW": ""
} }
}, },
{ {
@@ -2788,13 +2788,13 @@
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
"ru_RU": "Изменить индивидуальные параметры", "ru_RU": "Изменить пользовательскую конфигурацию",
"sv_SE": "", "sv_SE": "",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Редагувати користувацьку конфігурацію", "uk_UA": "",
"zh_CN": "编辑自定义设置", "zh_CN": "",
"zh_TW": "編輯遊戲獨立自訂 (per-game) 設定檔" "zh_TW": ""
} }
}, },
{ {
@@ -2842,9 +2842,9 @@
"sv_SE": "Skapar en oberoende konfiguration för det aktuella spelet", "sv_SE": "Skapar en oberoende konfiguration för det aktuella spelet",
"th_TH": "สร้างการกำหนดค่าที่เป็นอิสระสำหรับเกมปัจจุบัน", "th_TH": "สร้างการกำหนดค่าที่เป็นอิสระสำหรับเกมปัจจุบัน",
"tr_TR": "Mevcut oyun için bağımsız bir yapılandırma oluşturur", "tr_TR": "Mevcut oyun için bağımsız bir yapılandırma oluşturur",
"uk_UA": "Створюйте незалежну конфігурацію для поточної гри", "uk_UA": "Створює незалежну конфігурацію для поточної гри",
"zh_CN": "为当前游戏创建独立的配置", "zh_CN": "为当前游戏创建独立的配置",
"zh_TW": "為已選擇的遊戲建立遊戲獨立自訂 (game-specific) 的設定檔" "zh_TW": "為當前遊戲創建獨立的配置"
} }
}, },
{ {
@@ -2863,13 +2863,13 @@
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
"ru_RU": "Отредактировать существующие независимые параметры для выбранной игры.", "ru_RU": "Отредактировать существующую независимую конфигурацию для выбранной игры.",
"sv_SE": "", "sv_SE": "",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Відредагувати наявну індивідуальну конфігурацію для цієї гри.", "uk_UA": "",
"zh_CN": "编辑选定游戏的现存独立配置", "zh_CN": "",
"zh_TW": "為已選擇的遊戲編輯遊戲獨立自訂 (game-specific) 的設定檔" "zh_TW": ""
} }
}, },
{ {
@@ -2894,7 +2894,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Iнформація про сумісність", "uk_UA": "Iнформація про сумісність",
"zh_CN": "显示兼容性项目", "zh_CN": "显示兼容性项目",
"zh_TW": "顯示相容性資訊" "zh_TW": ""
} }
}, },
{ {
@@ -2919,7 +2919,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Показати цю гру в Списку Сумісності. Список сумісності також можна зайти в меню Довідки.", "uk_UA": "Показати цю гру в Списку Сумісності. Список сумісності також можна зайти в меню Довідки.",
"zh_CN": "在兼容性列表中显示选定的游戏,您通常可以通过帮助菜单访问。", "zh_CN": "在兼容性列表中显示选定的游戏,您通常可以通过帮助菜单访问。",
"zh_TW": "在相容性列表中顯示已選擇的遊戲。你也可以透過「說明」選單開啟。" "zh_TW": ""
} }
}, },
{ {
@@ -2944,7 +2944,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Інформація про гру", "uk_UA": "Інформація про гру",
"zh_CN": "显示游戏信息", "zh_CN": "显示游戏信息",
"zh_TW": "顯示遊戲資訊" "zh_TW": ""
} }
}, },
{ {
@@ -2969,7 +2969,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Показати статистику та деталі обраної гри.", "uk_UA": "Показати статистику та деталі обраної гри.",
"zh_CN": "显示当前选定游戏的状态与详细信息。", "zh_CN": "显示当前选定游戏的状态与详细信息。",
"zh_TW": "顯示目前已選擇遊戲的狀態及詳細資訊。" "zh_TW": ""
} }
}, },
{ {
@@ -3442,7 +3442,7 @@
"sv_SE": "Användargränssnitt", "sv_SE": "Användargränssnitt",
"th_TH": "หน้าจอผู้ใช้", "th_TH": "หน้าจอผู้ใช้",
"tr_TR": "Kullancı Arayüzü", "tr_TR": "Kullancı Arayüzü",
"uk_UA": "Інтерфейс", "uk_UA": "Інтерфейс користувача",
"zh_CN": "用户界面", "zh_CN": "用户界面",
"zh_TW": "使用者介面" "zh_TW": "使用者介面"
} }
@@ -3519,7 +3519,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Перевірка оновлень:", "uk_UA": "Перевірка оновлень:",
"zh_CN": "检查更新", "zh_CN": "检查更新",
"zh_TW": "檢查更新:" "zh_TW": ""
} }
}, },
{ {
@@ -3544,7 +3544,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Вимкнути", "uk_UA": "Вимкнути",
"zh_CN": "关闭", "zh_CN": "关闭",
"zh_TW": "關閉" "zh_TW": ""
} }
}, },
{ {
@@ -3569,7 +3569,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Запитувати щоразу", "uk_UA": "Запитувати щоразу",
"zh_CN": "提示", "zh_CN": "提示",
"zh_TW": "提示" "zh_TW": ""
} }
}, },
{ {
@@ -3594,7 +3594,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Оновлювати в фоні", "uk_UA": "Оновлювати в фоні",
"zh_CN": "背景", "zh_CN": "背景",
"zh_TW": "背景" "zh_TW": ""
} }
}, },
{ {
@@ -3619,7 +3619,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "При втраті фокуса емулятором:", "uk_UA": "При втраті фокуса емулятором:",
"zh_CN": "当模拟器在后台时:", "zh_CN": "当模拟器在后台时:",
"zh_TW": "當模擬器「失去焦點」(如切換工作)時:" "zh_TW": ""
} }
}, },
{ {
@@ -3644,7 +3644,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Нічого не робити", "uk_UA": "Нічого не робити",
"zh_CN": "什么事情也不做", "zh_CN": "什么事情也不做",
"zh_TW": "沒有動作" "zh_TW": ""
} }
}, },
{ {
@@ -3669,7 +3669,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Блокувати введення", "uk_UA": "Блокувати введення",
"zh_CN": "禁用输入", "zh_CN": "禁用输入",
"zh_TW": "停用輸入" "zh_TW": ""
} }
}, },
{ {
@@ -3694,7 +3694,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Вимкнути звук", "uk_UA": "Вимкнути звук",
"zh_CN": "静音", "zh_CN": "静音",
"zh_TW": "靜音" "zh_TW": ""
} }
}, },
{ {
@@ -3719,7 +3719,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Блокувати введення та Вимкнути звук", "uk_UA": "Блокувати введення та Вимкнути звук",
"zh_CN": "阻止输入且静音", "zh_CN": "阻止输入且静音",
"zh_TW": "停用輸入且靜音" "zh_TW": ""
} }
}, },
{ {
@@ -3744,7 +3744,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Поставити на паузу", "uk_UA": "Поставити на паузу",
"zh_CN": "暂停模拟", "zh_CN": "暂停模拟",
"zh_TW": "暫停模擬" "zh_TW": ""
} }
}, },
{ {
@@ -3817,59 +3817,34 @@
"sv_SE": "Inaktivera inmatning när fokus tappas", "sv_SE": "Inaktivera inmatning när fokus tappas",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Вимкнути введення, якщо вікно неактивне", "uk_UA": "",
"zh_CN": "在后台时禁用输入", "zh_CN": "在后台时禁用输入",
"zh_TW": "在「失去焦點」時停用輸入"
}
},
{
"ID": "SettingsTabGeneralShowOldUI",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Show Original UI Style (Requires restart)",
"es_ES": "",
"fr_FR": "",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "Vis original UI-stil (krever omstart)",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "Включить оригинальный интерфейса (требуется перезагрузка)",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Показати оригінальний UI (Потрібен перезапуск)",
"zh_CN": "显示原始 UI 样式 (需要重启)",
"zh_TW": "" "zh_TW": ""
} }
}, },
{ {
"ID": "SettingsTabGeneralShowOldUIToolTip", "ID": "SettingsTabGeneralShowTitleBar",
"Translations": { "Translations": {
"ar_SA": "", "ar_SA": "",
"de_DE": "", "de_DE": "",
"el_GR": "", "el_GR": "",
"en_US": "Show the older Avalonia Ryujinx UI reminiscent of Ryujinx 1.1.1403. This is enabled by default on platforms that are not Windows.\nThe classic-style title bar is back and major window layout reworkings are reversed; such as the settings navigation placement above this tooltip.", "en_US": "Show Title Bar (Requires restart)",
"es_ES": "", "es_ES": "Mostrar Barra de Título (Requiere reinicio)",
"fr_FR": "", "fr_FR": "Afficher Barre de Titre (Nécessite redémarrage)",
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "Mostra barra del titolo (Richiede il riavvio)",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "제목 표시줄 표시(다시 시작해야 함)",
"no_NO": "Vis det eldre Avalonia Ryujinx-grensesnittet som minner om Ryujinx 1.1.1403. Dette er aktivert som standard på plattformer som ikke er Windows.\nTittellinjen i klassisk stil er tilbake, og store omarbeidinger av vindusoppsettet er reversert, for eksempel plasseringen av innstillingsnavigasjonen over dette verktøytipset.", "no_NO": "Vis tittellinje (krever omstart)",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "Mostrar Barra de Título (Requer reinicialização)",
"ru_RU": "Показать старый пользовательский интерфейс Avalonia Ryujinx, напоминающий Ryujinx 1.1.1403. Включено по умолчанию на платформах, отличных от Windows.\nСтрока заголовка в классическом стиле вернётся на место, а основные изменения в оформлении окна будут отменены; например, расположение навигации по настройкам над этой всплывающей подсказкой.", "ru_RU": "Показать строку заголовка (требуется перезапуск)",
"sv_SE": "", "sv_SE": "Visa titelrad (kräver omstart)",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Показати старий інтерфейс Avalonia Ryujinx, який був у Ryujinx 1.1.1403. Ця опція активна за замовчуванням на всіх інших, окрім Windows платформах.\nПовернеться класична панель заголовка, а всі суттєві зміни інтерфейсу будуть скасовані, зокрема горизонтальне розміщення навігації в налаштуваннях.", "uk_UA": "Показувати рядок заголовка (Потрібен перезапуск)",
"zh_CN": "显示旧的类似 Ryujinx 1.1.1403 的 Avalonia Ryujinx UI。在非 Windows 平台上默认启用此选项。\n经典样式的标题栏已回归并且恢复了对窗口布局的重大重构;例如在工具提示上方放置设置导航。", "zh_CN": "显示标题栏 (需要重启)",
"zh_TW": "" "zh_TW": "顯示「標題列」 (需要重新開啟Ryujinx)"
} }
}, },
{ {
@@ -4014,7 +3989,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Carregar Automaticamente Pasta de DLC e Atualizações", "pt_BR": "Carregar Automaticamente Pasta de DLC e Atualizações",
"ru_RU": "Автозагрузка папки с DLC/Обновлениями", "ru_RU": "Автозагрузка папки с DLC/Обновлениями",
"sv_SE": "Läs automatiskt in DLC/speluppdateringar", "sv_SE": "Läs automatisk in DLC/speluppdateringar",
"th_TH": "โหลดไดเรกทอรี DLC/ไฟล์อัปเดต อัตโนมัติ", "th_TH": "โหลดไดเรกทอรี DLC/ไฟล์อัปเดต อัตโนมัติ",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Автозавантаження теки DLC/Оновлень", "uk_UA": "Автозавантаження теки DLC/Оновлень",
@@ -4867,9 +4842,9 @@
"sv_SE": "Matcha systemtid", "sv_SE": "Matcha systemtid",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Синхронізувати з системним годинником", "uk_UA": "",
"zh_CN": "与系统时间同步", "zh_CN": "与系统时间同步",
"zh_TW": "與系統時間同步" "zh_TW": ""
} }
}, },
{ {
@@ -5038,7 +5013,7 @@
"no_NO": "Lyd Inn/Ut", "no_NO": "Lyd Inn/Ut",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
"ru_RU": "", "ru_RU": "Выход/Вход звука",
"sv_SE": "", "sv_SE": "",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
@@ -5294,7 +5269,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Ігнорувати Аплет Контролера", "uk_UA": "Ігнорувати Аплет Контролера",
"zh_CN": "忽略控制器小程序", "zh_CN": "忽略控制器小程序",
"zh_TW": "忽略控制器小程式" "zh_TW": ""
} }
}, },
{ {
@@ -6144,7 +6119,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Увімкнути журнали інтерфейсу", "uk_UA": "Увімкнути журнали інтерфейсу",
"zh_CN": "启用 UI 日志", "zh_CN": "启用 UI 日志",
"zh_TW": "啟用 UI 日誌" "zh_TW": ""
} }
}, },
{ {
@@ -6544,7 +6519,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Скинути налаштування", "uk_UA": "Скинути налаштування",
"zh_CN": "重置设置", "zh_CN": "重置设置",
"zh_TW": "重設設定" "zh_TW": ""
} }
}, },
{ {
@@ -6569,7 +6544,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Я хочу скинути налаштування.", "uk_UA": "Я хочу скинути налаштування.",
"zh_CN": "我要重置我的设置。", "zh_CN": "我要重置我的设置。",
"zh_TW": "我想重設我的設定。" "zh_TW": ""
} }
}, },
{ {
@@ -6588,7 +6563,7 @@
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
"ru_RU": "", "ru_RU": "Ок",
"sv_SE": "Ok", "sv_SE": "Ok",
"th_TH": "ตกลง", "th_TH": "ตกลง",
"tr_TR": "Tamam", "tr_TR": "Tamam",
@@ -7038,7 +7013,7 @@
"no_NO": "", "no_NO": "",
"pl_PL": "Pro Kontroler", "pl_PL": "Pro Kontroler",
"pt_BR": "", "pt_BR": "",
"ru_RU": "", "ru_RU": "Pro контроллер",
"sv_SE": "", "sv_SE": "",
"th_TH": "โปรคอนโทรลเลอร์", "th_TH": "โปรคอนโทรลเลอร์",
"tr_TR": "Profesyonel Kumanda", "tr_TR": "Profesyonel Kumanda",
@@ -7222,6 +7197,81 @@
"zh_TW": "新增" "zh_TW": "新增"
} }
}, },
{
"ID": "ControllerSettingsModifiedNotification",
"Translations": {
"ar_SA": "(تم التعديل!)",
"de_DE": "(modifiziert!)",
"el_GR": "(τροποποιημένο!)",
"en_US": "(Modified!)",
"es_ES": "(modificado!)",
"fr_FR": "(modifié!)",
"he_IL": "(שונה!)",
"it_IT": "(modificato!)",
"ja_JP": "(変更済み!)",
"ko_KR": "(수정됨!)",
"no_NO": "(modifisert!)",
"pl_PL": "(zmodyfikowane!)",
"pt_BR": "(modificado!)",
"ru_RU": "(изменено!)",
"sv_SE": "(ändrad!)",
"th_TH": "(แก้ไขแล้ว!)",
"tr_TR": "(değiştirildi!)",
"uk_UA": "(модифіковано!)",
"zh_CN": "(已修改!)",
"zh_TW": "(已修改!)"
}
},
{
"ID": "ControllerSettingsDisableDeviceForSaving",
"Translations": {
"ar_SA": "تم إعداد التحكم.\n\nفي انتظار اتصال وحدة التحكم...",
"de_DE": "Steuerung konfiguriert.\n\nWarten auf die Verbindung des Controllers...",
"el_GR": "Η διαχείριση έχει ρυθμιστεί.\n\nΑναμένεται σύνδεση του χειριστηρίου...",
"en_US": "Control configured.\n\nWaiting for controller connection...",
"es_ES": "Control configurado.\n\nEsperando la conexión del controlador...",
"fr_FR": "Contrôle configuré.\n\nEn attente de la connexion du contrôleur...",
"he_IL": "השליטה הוגדרה.\n\nממתין לחיבור הבקר...",
"it_IT": "Controllo configurato.\n\nIn attesa della connessione del controller...",
"ja_JP": "コントロールが設定されました。\n\nコントローラーの接続を待っています...",
"ko_KR": "제어가 설정되었습니다.\n\n컨트롤러 연결 대기 중...",
"no_NO": "Kontroll konfigurert.\n\nVenter på tilkobling av kontroller...",
"pl_PL": "Sterowanie skonfigurowane.\n\nOczekiwanie na połączenie kontrolera...",
"pt_BR": "Controle configurado.\n\nAguardando conexão do controle...",
"ru_RU": "Управление настроено.\n\nОжидается подключение контроллера...",
"sv_SE": "Kontroll konfigurerad.\n\nVäntar på anslutning av kontrollen...",
"th_TH": "การควบคุมได้รับการตั้งค่าแล้ว\n\nกำลังรอการเชื่อมต่อคอนโทรลเลอร์...",
"tr_TR": "Kontrol yapılandırıldı.\n\nKontrolcü bağlantısı bekleniyor...",
"uk_UA": "Керування налаштовано.\n\nОчікується підключення контролера...",
"zh_CN": "控制已配置。\n\n等待控制器连接...",
"zh_TW": "控制已設定。\n\n等待控制器連接..."
}
},
{
"ID": "ControllerSettingsUnlink",
"Translations": {
"ar_SA": "إلغاء الربط",
"de_DE": "Entkoppeln",
"el_GR": "Αποσύνδεση",
"en_US": "Unlink",
"es_ES": "Desvincular",
"fr_FR": "Dissocier",
"he_IL": "ניתוק קישור",
"it_IT": "Scollega",
"ja_JP": "リンク解除",
"ko_KR": "연결 해제",
"no_NO": "Frakoble",
"pl_PL": "Odłącz",
"pt_BR": "Desvincular",
"ru_RU": "Отвязать",
"sv_SE": "Koppla från",
"th_TH": "ยกเลิกการเชื่อมโยง",
"tr_TR": "Bağlantıyı Kes",
"uk_UA": "Відв'язати",
"zh_CN": "解除绑定",
"zh_TW": "解除綁定"
}
},
{ {
"ID": "ControllerSettingsRemove", "ID": "ControllerSettingsRemove",
"Translations": { "Translations": {
@@ -7264,7 +7314,7 @@
"pl_PL": "Przyciski", "pl_PL": "Przyciski",
"pt_BR": "Botões", "pt_BR": "Botões",
"ru_RU": "Кнопки", "ru_RU": "Кнопки",
"sv_SE": "Handlingsknappar", "sv_SE": "Knappar",
"th_TH": "ปุ่มกด", "th_TH": "ปุ่มกด",
"tr_TR": "Tuşlar", "tr_TR": "Tuşlar",
"uk_UA": "Кнопки", "uk_UA": "Кнопки",
@@ -8467,7 +8517,7 @@
"sv_SE": "", "sv_SE": "",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "LED-підсвітка", "uk_UA": "",
"zh_CN": "", "zh_CN": "",
"zh_TW": "" "zh_TW": ""
} }
@@ -8492,9 +8542,9 @@
"sv_SE": "Inaktivera", "sv_SE": "Inaktivera",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Вимкнути", "uk_UA": "",
"zh_CN": "关闭", "zh_CN": "关闭",
"zh_TW": "關閉" "zh_TW": ""
} }
}, },
{ {
@@ -8517,9 +8567,9 @@
"sv_SE": "Regnbåge", "sv_SE": "Regnbåge",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Веселка", "uk_UA": "",
"zh_CN": "彩虹", "zh_CN": "彩虹",
"zh_TW": "彩虹" "zh_TW": ""
} }
}, },
{ {
@@ -8542,9 +8592,9 @@
"sv_SE": "Regnbågshastighet", "sv_SE": "Regnbågshastighet",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Швидкість зміни кольорів", "uk_UA": "",
"zh_CN": "彩虹滚动速度", "zh_CN": "彩虹滚动速度",
"zh_TW": "彩虹滾動速度" "zh_TW": ""
} }
}, },
{ {
@@ -8569,7 +8619,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "颜色", "zh_CN": "颜色",
"zh_TW": "顏色" "zh_TW": ""
} }
}, },
{ {
@@ -9167,7 +9217,7 @@
"sv_SE": "", "sv_SE": "",
"th_TH": "", "th_TH": "",
"tr_TR": "Esc", "tr_TR": "Esc",
"uk_UA": "Esc", "uk_UA": "",
"zh_CN": "Esc", "zh_CN": "Esc",
"zh_TW": "Esc 鍵" "zh_TW": "Esc 鍵"
} }
@@ -10867,7 +10917,7 @@
"sv_SE": "Diverse", "sv_SE": "Diverse",
"th_TH": "", "th_TH": "",
"tr_TR": "Diğer", "tr_TR": "Diğer",
"uk_UA": "Інше", "uk_UA": "",
"zh_CN": "截图键", "zh_CN": "截图键",
"zh_TW": "其他按鍵" "zh_TW": "其他按鍵"
} }
@@ -11872,6 +11922,31 @@
"zh_TW": "儲存設定檔" "zh_TW": "儲存設定檔"
} }
}, },
{
"ID": "ControllerSettingsCancelCurrentChangesToolTip",
"Translations": {
"ar_SA": "إلغاء التغييرات الحالية",
"de_DE": "Aktuelle Änderungen abbrechen",
"el_GR": "Ακύρωση τρεχουσών αλλαγών",
"en_US": "Cancel current changes",
"es_ES": "Cancelar los cambios actuales",
"fr_FR": "Annuler les modifications en cours",
"he_IL": "ביטול השינויים הנוכחיים",
"it_IT": "Annulla le modifiche correnti",
"ja_JP": "現在の変更をキャンセル",
"ko_KR": "현재 변경 취소",
"no_NO": "Avbryt gjeldende endringer",
"pl_PL": "Anuluj bieżące zmiany",
"pt_BR": "Cancelar alterações atuais",
"ru_RU": "Отменить текущие изменения",
"sv_SE": "Avbryt aktuella ändringar",
"th_TH": "ยกเลิกการเปลี่ยนแปลงปัจจุบัน",
"tr_TR": "Geçerli değişiklikleri iptal et",
"uk_UA": "Скасувати поточні зміни",
"zh_CN": "取消当前更改",
"zh_TW": "取消當前變更"
}
},
{ {
"ID": "MenuBarFileToolsTakeScreenshot", "ID": "MenuBarFileToolsTakeScreenshot",
"Translations": { "Translations": {
@@ -13844,7 +13919,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Ви збираєтесь видалити всі дані PPTC з:\n\n{0}\n\nБажаєте продовжити цю операцію?", "uk_UA": "Ви збираєтесь видалити всі дані PPTC з:\n\n{0}\n\nБажаєте продовжити цю операцію?",
"zh_CN": "您正要清理 PPTC 数据:\n\n{0}\n\n您确实要继续吗?", "zh_CN": "您正要清理 PPTC 数据:\n\n{0}\n\n您确实要继续吗?",
"zh_TW": "您將要刪除以下遊戲的 PPTC:\n\n{0}\n\n您確定要繼續嗎?" "zh_TW": ""
} }
}, },
{ {
@@ -14914,7 +14989,7 @@
"pl_PL": "Wielowątkowość Backendu Graficznego:", "pl_PL": "Wielowątkowość Backendu Graficznego:",
"pt_BR": "Multi Enfileiramento do Renderizador Gráfico:", "pt_BR": "Multi Enfileiramento do Renderizador Gráfico:",
"ru_RU": "Многопоточность графического бэкенда:", "ru_RU": "Многопоточность графического бэкенда:",
"sv_SE": "Multitrådning för grafikbakände:", "sv_SE": "Multithreading för grafikbakände:",
"th_TH": "มัลติเธรด กราฟิกเบื้องหลัง:", "th_TH": "มัลติเธรด กราฟิกเบื้องหลัง:",
"tr_TR": "Grafik Backend Multithreading:", "tr_TR": "Grafik Backend Multithreading:",
"uk_UA": "Багатопотоковість графічного сервера:", "uk_UA": "Багатопотоковість графічного сервера:",
@@ -16694,7 +16769,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Діалогове вікно Аплету Контролера не з'явиться, якщо геймпад було відключено під час роботи програми.\n\nЗалиште вимкненим якщо не впевнені.", "uk_UA": "Діалогове вікно Аплету Контролера не з'явиться, якщо геймпад було відключено під час роботи програми.\n\nЗалиште вимкненим якщо не впевнені.",
"zh_CN": "在应用程序运行时如果游戏手柄断开连接则不会显示控制器小程序对话框。\n\n如果不确定请保持关闭状态。", "zh_CN": "在应用程序运行时如果游戏手柄断开连接则不会显示控制器小程序对话框。\n\n如果不确定请保持关闭状态。",
"zh_TW": "在模擬應用程式時如果遊戲手柄中斷連線則不會顯示控制器小程式。\n\n如果不確定請保持關閉狀態。" "zh_TW": ""
} }
}, },
{ {
@@ -17169,7 +17244,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Виводити повідомлення журналу Avalonia (UI) в консоль", "uk_UA": "Виводити повідомлення журналу Avalonia (UI) в консоль",
"zh_CN": "在控制台显示 Avalonia (UI) 的日志信息", "zh_CN": "在控制台显示 Avalonia (UI) 的日志信息",
"zh_TW": "在控制台中輸出 Avalonia (UI) 日誌訊息。" "zh_TW": ""
} }
}, },
{ {
@@ -17369,7 +17444,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Відкрити теку куди зберігаються скріншоти Ryujinx", "uk_UA": "Відкрити теку куди зберігаються скріншоти Ryujinx",
"zh_CN": "打开 Ryujinx 截图文件夹", "zh_CN": "打开 Ryujinx 截图文件夹",
"zh_TW": "開啟 Ryujinx 螢幕擷取畫面資料夾" "zh_TW": ""
} }
}, },
{ {
@@ -17692,7 +17767,7 @@
"sv_SE": "Ändra ljudvolym", "sv_SE": "Ändra ljudvolym",
"th_TH": "ปรับระดับเสียง", "th_TH": "ปรับระดับเสียง",
"tr_TR": "Ses seviyesini değiştirir", "tr_TR": "Ses seviyesini değiştirir",
"uk_UA": "Регулювання гучності", "uk_UA": "Змінити гучність звуку",
"zh_CN": "调节音量", "zh_CN": "调节音量",
"zh_TW": "調節音量" "zh_TW": "調節音量"
} }
@@ -18119,7 +18194,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Доступне оновлення!", "uk_UA": "Доступне оновлення!",
"zh_CN": "有可用的更新!", "zh_CN": "有可用的更新!",
"zh_TW": "有可用的更新!" "zh_TW": ""
} }
}, },
{ {
@@ -18714,7 +18789,7 @@
"pl_PL": "", "pl_PL": "",
"pt_BR": "Não Reduzido", "pt_BR": "Não Reduzido",
"ru_RU": "Не обрезан", "ru_RU": "Не обрезан",
"sv_SE": "Orörd", "sv_SE": "Inte optimerad",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Необрізані", "uk_UA": "Необрізані",
@@ -19592,7 +19667,7 @@
"sv_SE": "Alla tangentbord", "sv_SE": "Alla tangentbord",
"th_TH": "คีย์บอร์ดทั้งหมด", "th_TH": "คีย์บอร์ดทั้งหมด",
"tr_TR": "Tüm Klavyeler", "tr_TR": "Tüm Klavyeler",
"uk_UA": "Усі клавіатури", "uk_UA": "Всі клавіатури",
"zh_CN": "所有键盘", "zh_CN": "所有键盘",
"zh_TW": "所有鍵盤" "zh_TW": "所有鍵盤"
} }
@@ -19742,7 +19817,7 @@
"sv_SE": "Snabbtangenter för tangentbord", "sv_SE": "Snabbtangenter för tangentbord",
"th_TH": "ปุ่มลัดของคีย์บอร์ด", "th_TH": "ปุ่มลัดของคีย์บอร์ด",
"tr_TR": "Klavye Kısayolları", "tr_TR": "Klavye Kısayolları",
"uk_UA": "Гарячі клавіші", "uk_UA": "Гарячі клавіші клавіатури",
"zh_CN": "快捷键", "zh_CN": "快捷键",
"zh_TW": "鍵盤快速鍵" "zh_TW": "鍵盤快速鍵"
} }
@@ -19944,7 +20019,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Налаштування LED", "uk_UA": "Налаштування LED",
"zh_CN": "LED 设置", "zh_CN": "LED 设置",
"zh_TW": "LED 設定" "zh_TW": ""
} }
}, },
{ {
@@ -21794,7 +21869,7 @@
"tr_TR": "Yeniden Doku Sıkıştırılmasını Aktif Et", "tr_TR": "Yeniden Doku Sıkıştırılmasını Aktif Et",
"uk_UA": "Увімкнути рекомпресію текстури", "uk_UA": "Увімкнути рекомпресію текстури",
"zh_CN": "启用纹理压缩", "zh_CN": "启用纹理压缩",
"zh_TW": "啟材質重新壓縮" "zh_TW": "啟材質重新壓縮"
} }
}, },
{ {
@@ -22467,7 +22542,7 @@
"sv_SE": "Tillämpar anti-aliasing på spelrenderaren.\n\nFXAA kommer att sudda det mesta av bilden, medan SMAA kommer att försöka hitta taggiga kanter och släta ut dem.\n\nRekommenderas inte att använda tillsammans med skalfiltret FSR.\n\nDet här alternativet kan ändras medan ett spel körs genom att klicka på \"Tillämpa\" nedan. Du kan helt enkelt flytta inställningsfönstret åt sidan och experimentera tills du hittar ditt föredragna utseende för ett spel.\n\nLämna som INGEN om du är osäker.", "sv_SE": "Tillämpar anti-aliasing på spelrenderaren.\n\nFXAA kommer att sudda det mesta av bilden, medan SMAA kommer att försöka hitta taggiga kanter och släta ut dem.\n\nRekommenderas inte att använda tillsammans med skalfiltret FSR.\n\nDet här alternativet kan ändras medan ett spel körs genom att klicka på \"Tillämpa\" nedan. Du kan helt enkelt flytta inställningsfönstret åt sidan och experimentera tills du hittar ditt föredragna utseende för ett spel.\n\nLämna som INGEN om du är osäker.",
"th_TH": "ใช้การลดรอยหยักกับการเรนเดอร์เกม\n\nFXAA จะเบลอภาพส่วนใหญ่ ในขณะที่ SMAA จะพยายามค้นหารอยหยักและปรับให้เรียบ\n\nไม่แนะนำให้ใช้ร่วมกับตัวกรองสเกล FSR\n\nตัวเลือกนี้สามารถเปลี่ยนแปลงได้ในขณะที่เกมกำลังทำงานอยู่โดยคลิก \"นำไปใช้\" ด้านล่าง คุณสามารถย้ายหน้าต่างการตั้งค่าไปด้านข้างและทดลองจนกว่าคุณจะพบรูปลักษณ์ที่คุณต้องการสำหรับเกม\n\nปล่อยไว้ที่ NONE หากไม่แน่ใจ", "th_TH": "ใช้การลดรอยหยักกับการเรนเดอร์เกม\n\nFXAA จะเบลอภาพส่วนใหญ่ ในขณะที่ SMAA จะพยายามค้นหารอยหยักและปรับให้เรียบ\n\nไม่แนะนำให้ใช้ร่วมกับตัวกรองสเกล FSR\n\nตัวเลือกนี้สามารถเปลี่ยนแปลงได้ในขณะที่เกมกำลังทำงานอยู่โดยคลิก \"นำไปใช้\" ด้านล่าง คุณสามารถย้ายหน้าต่างการตั้งค่าไปด้านข้างและทดลองจนกว่าคุณจะพบรูปลักษณ์ที่คุณต้องการสำหรับเกม\n\nปล่อยไว้ที่ NONE หากไม่แน่ใจ",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Застосовує згладження до рендера гри.\n\nFXAA розмиє більшість зображення, а SMAA спробує знайти нерівні краї та згладити їх.\n\nНе рекомендується використовувати разом з фільтром масштабування FSR.\n\nЦю опцію можна міняти коли гра запущена кліком на \"Застосувати; ви можете відсунути вікно налаштувань і поекспериментувати з видом гри.\n\nЗалиште \"Немає\", якщо не впевнені.", "uk_UA": "Застосовує згладження до рендера гри.\n\nFXAA розмиє більшість зображення, а SMAA спробує знайти нерівні краї та згладити їх.\n\nНе рекомендується використовувати разом з фільтром масштабування FSR.\n\nЦю опцію можна міняти коли гра запущена кліком на \"Застосувати; ви можете відсунути вікно налаштувань і поекспериментувати з видом гри.\n\nЗалиште на \"Немає\", якщо не впевнені.",
"zh_CN": "抗锯齿是一种图形处理技术,用于减少图像边缘的锯齿状现象,使图像更加平滑。\n\nFXAA快速近似抗锯齿是一种性能开销相对较小的抗锯齿方法但可能会使得整体图像看起来有些模糊。\n\nSMAA增强型子像素抗锯齿则更加精细它会尝试找到锯齿边缘并平滑它们相比 FXAA 有更好的图像质量,但性能开销可能会稍大一些。\n\n如果开启了 FSRFidelityFX Super Resolution超级分辨率锐画技术来提高性能或图像质量不建议再启用抗锯齿因为它们会产生不必要的图形处理开销或者相互之间效果不协调。\n\n在游戏运行时通过点击下面的“应用”按钮可以使设置生效你可以将设置窗口移开并试验找到您喜欢的游戏画面效果。\n\n如果不确定请保持为“无”。", "zh_CN": "抗锯齿是一种图形处理技术,用于减少图像边缘的锯齿状现象,使图像更加平滑。\n\nFXAA快速近似抗锯齿是一种性能开销相对较小的抗锯齿方法但可能会使得整体图像看起来有些模糊。\n\nSMAA增强型子像素抗锯齿则更加精细它会尝试找到锯齿边缘并平滑它们相比 FXAA 有更好的图像质量,但性能开销可能会稍大一些。\n\n如果开启了 FSRFidelityFX Super Resolution超级分辨率锐画技术来提高性能或图像质量不建议再启用抗锯齿因为它们会产生不必要的图形处理开销或者相互之间效果不协调。\n\n在游戏运行时通过点击下面的“应用”按钮可以使设置生效你可以将设置窗口移开并试验找到您喜欢的游戏画面效果。\n\n如果不确定请保持为“无”。",
"zh_TW": "對遊戲繪製進行反鋸齒處理。\n\nFXAA 會模糊大部分圖像,而 SMAA 則會嘗試找出鋸齒邊緣並將其平滑化。\n\n不建議與 FSR 縮放濾鏡一起使用。\n\n此選項可在遊戲執行時透過點選下方的「套用」進行變更您只需將設定視窗移到一旁然後進行試驗直到找到您喜歡的遊戲效果。\n\n如果不確定請選擇無狀態。" "zh_TW": "對遊戲繪製進行反鋸齒處理。\n\nFXAA 會模糊大部分圖像,而 SMAA 則會嘗試找出鋸齒邊緣並將其平滑化。\n\n不建議與 FSR 縮放濾鏡一起使用。\n\n此選項可在遊戲執行時透過點選下方的「套用」進行變更您只需將設定視窗移到一旁然後進行試驗直到找到您喜歡的遊戲效果。\n\n如果不確定請選擇無狀態。"
} }
@@ -22542,7 +22617,7 @@
"sv_SE": "Välj det skalfilter som ska tillämpas vid användning av upplösningsskala.\n\nBilinjär fungerar bra för 3D-spel och är ett säkert standardalternativ.\n\nNärmast rekommenderas för pixel art-spel.\n\nFSR 1.0 är bara ett skarpningsfilter, rekommenderas inte för FXAA eller SMAA.\n\nOmrådesskalning rekommenderas vid nedskalning av upplösning som är större än utdatafönstret. Det kan användas för att uppnå en supersamplad anti-alias-effekt vid nedskalning med mer än 2x.\n\nDetta alternativ kan ändras medan ett spel körs genom att klicka på \"Tillämpa\" nedan. du kan helt enkelt flytta inställningsfönstret åt sidan och experimentera tills du hittar ditt föredragna utseende för ett spel.\n\nLämna som BILINJÄR om du är osäker.", "sv_SE": "Välj det skalfilter som ska tillämpas vid användning av upplösningsskala.\n\nBilinjär fungerar bra för 3D-spel och är ett säkert standardalternativ.\n\nNärmast rekommenderas för pixel art-spel.\n\nFSR 1.0 är bara ett skarpningsfilter, rekommenderas inte för FXAA eller SMAA.\n\nOmrådesskalning rekommenderas vid nedskalning av upplösning som är större än utdatafönstret. Det kan användas för att uppnå en supersamplad anti-alias-effekt vid nedskalning med mer än 2x.\n\nDetta alternativ kan ändras medan ett spel körs genom att klicka på \"Tillämpa\" nedan. du kan helt enkelt flytta inställningsfönstret åt sidan och experimentera tills du hittar ditt föredragna utseende för ett spel.\n\nLämna som BILINJÄR om du är osäker.",
"th_TH": "เลือกตัวกรองสเกลที่จะใช้เมื่อใช้สเกลความละเอียด\n\nBilinear ทำงานได้ดีกับเกม 3D และเป็นตัวเลือกเริ่มต้นที่ปลอดภัย\n\nแนะนำให้ใช้เกมภาพพิกเซลที่ใกล้เคียงที่สุด\n\nFSR 1.0 เป็นเพียงตัวกรองความคมชัด ไม่แนะนำให้ใช้กับ FXAA หรือ SMAA\n\nตัวเลือกนี้สามารถเปลี่ยนแปลงได้ในขณะที่เกมกำลังทำงานอยู่โดยคลิก \"นำไปใช้\" ด้านล่าง คุณสามารถย้ายหน้าต่างการตั้งค่าไปด้านข้างและทดลองจนกว่าคุณจะพบรูปลักษณ์ที่คุณต้องการสำหรับเกม", "th_TH": "เลือกตัวกรองสเกลที่จะใช้เมื่อใช้สเกลความละเอียด\n\nBilinear ทำงานได้ดีกับเกม 3D และเป็นตัวเลือกเริ่มต้นที่ปลอดภัย\n\nแนะนำให้ใช้เกมภาพพิกเซลที่ใกล้เคียงที่สุด\n\nFSR 1.0 เป็นเพียงตัวกรองความคมชัด ไม่แนะนำให้ใช้กับ FXAA หรือ SMAA\n\nตัวเลือกนี้สามารถเปลี่ยนแปลงได้ในขณะที่เกมกำลังทำงานอยู่โดยคลิก \"นำไปใช้\" ด้านล่าง คุณสามารถย้ายหน้าต่างการตั้งค่าไปด้านข้างและทดลองจนกว่าคุณจะพบรูปลักษณ์ที่คุณต้องการสำหรับเกม",
"tr_TR": "Choose the scaling filter that will be applied when using resolution scale.\n\nBilinear works well for 3D games and is a safe default option.\n\nNearest is recommended for pixel art games.\n\nFSR 1.0 is merely a sharpening filter, not recommended for use with FXAA or SMAA.\n\nThis option can be changed while a game is running by clicking \"Apply\" below; you can simply move the settings window aside and experiment until you find your preferred look for a game.\n\nLeave on BILINEAR if unsure.", "tr_TR": "Choose the scaling filter that will be applied when using resolution scale.\n\nBilinear works well for 3D games and is a safe default option.\n\nNearest is recommended for pixel art games.\n\nFSR 1.0 is merely a sharpening filter, not recommended for use with FXAA or SMAA.\n\nThis option can be changed while a game is running by clicking \"Apply\" below; you can simply move the settings window aside and experiment until you find your preferred look for a game.\n\nLeave on BILINEAR if unsure.",
"uk_UA": "Виберіть фільтр масштабування, що використається при збільшенні роздільної здатності.\n\n\"Білінійний\" добре виглядає в 3D іграх, і хороше налаштування за умовчуванням.\n\n\"Найближчий\" рекомендується для ігор з піксель-артом.\n\n\"FSR 1.0\" - фільтр різкості. Не варто використовувати разом з FXAA або SMAA.\n\nЦю опцію можна змінювати під час гри кліком на \"Застосувати\" нижче; ви можете відсунути вікно налаштувань і поекспериментувати з тим, як відображатиметься гра.\n\nЗалиште \"Білінійний\", якщо не впевнені.", "uk_UA": "Виберіть фільтр масштабування, що використається при збільшенні роздільної здатності.\n\n\"Білінійний\" добре виглядає в 3D іграх, і хороше налаштування за умовчуванням.\n\n\"Найближчий\" рекомендується для ігор з піксель-артом.\n\n\"FSR 1.0\" - фільтр різкості. Не варто використовувати разом з FXAA або SMAA.\n\nЦю опцію можна змінювати під час гри кліком на \"Застосувати\" нижче; ви можете відсунути вікно налаштувань і поекспериментувати з тим, як відображатиметься гра.\n\nЗалиште на \"Білінійний\", якщо не впевнені.",
"zh_CN": "选择在分辨率缩放时将使用的缩放过滤器。\n\nBilinear双线性过滤对于3D游戏效果较好是一个安全的默认选项。\n\nNearest最近邻过滤推荐用于像素艺术游戏。\n\nFSR超级分辨率锐画只是一个锐化过滤器不推荐与 FXAA 或 SMAA 抗锯齿一起使用。\n\nArea局部过滤当渲染分辨率大于窗口实际分辨率推荐该选项。该选项在渲染比例大于2.0的情况下,可以实现超采样的效果。\n\n在游戏运行时通过点击下面的“应用”按钮可以使设置生效你可以将设置窗口移开并试验找到您喜欢的游戏画面效果。\n\n如果不确定请保持为“Bilinear双线性过滤”。", "zh_CN": "选择在分辨率缩放时将使用的缩放过滤器。\n\nBilinear双线性过滤对于3D游戏效果较好是一个安全的默认选项。\n\nNearest最近邻过滤推荐用于像素艺术游戏。\n\nFSR超级分辨率锐画只是一个锐化过滤器不推荐与 FXAA 或 SMAA 抗锯齿一起使用。\n\nArea局部过滤当渲染分辨率大于窗口实际分辨率推荐该选项。该选项在渲染比例大于2.0的情况下,可以实现超采样的效果。\n\n在游戏运行时通过点击下面的“应用”按钮可以使设置生效你可以将设置窗口移开并试验找到您喜欢的游戏画面效果。\n\n如果不确定请保持为“Bilinear双线性过滤”。",
"zh_TW": "選擇使用解析度縮放時套用的縮放過濾器。\n\n雙線性 (Bilinear) 濾鏡適用於 3D 遊戲,是一個安全的預設選項。\n\n建議像素美術遊戲使用近鄰性 (Nearest) 濾鏡。\n\nFSR 1.0 只是一個銳化濾鏡,不建議與 FXAA 或 SMAA 一起使用。\n\n此選項可在遊戲執行時透過點選下方的「套用」進行變更您只需將設定視窗移到一旁然後進行試驗直到找到您喜歡的遊戲效果。\n\n如果不確定請保持雙線性 (Bilinear) 狀態。" "zh_TW": "選擇使用解析度縮放時套用的縮放過濾器。\n\n雙線性 (Bilinear) 濾鏡適用於 3D 遊戲,是一個安全的預設選項。\n\n建議像素美術遊戲使用近鄰性 (Nearest) 濾鏡。\n\nFSR 1.0 只是一個銳化濾鏡,不建議與 FXAA 或 SMAA 一起使用。\n\n此選項可在遊戲執行時透過點選下方的「套用」進行變更您只需將設定視窗移到一旁然後進行試驗直到找到您喜歡的遊戲效果。\n\n如果不確定請保持雙線性 (Bilinear) 狀態。"
} }
@@ -23863,12 +23938,12 @@
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
"ru_RU": "Список совместимости — записей: {0}", "ru_RU": "",
"sv_SE": "", "sv_SE": "",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Список сумісності — {0} ігор", "uk_UA": "",
"zh_CN": "兼容性列表 - {0} 条", "zh_CN": "",
"zh_TW": "" "zh_TW": ""
} }
}, },
@@ -23938,12 +24013,12 @@
"no_NO": "Søk i {0} kompatibilitetsoppføringer...", "no_NO": "Søk i {0} kompatibilitetsoppføringer...",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
"ru_RU": "Поиск среди {0} записей о совместимости...", "ru_RU": "",
"sv_SE": "", "sv_SE": "",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Шукати серед {0} перевірених ігор...", "uk_UA": "",
"zh_CN": "搜索 {0} 兼容性条目...", "zh_CN": "",
"zh_TW": "" "zh_TW": ""
} }
}, },
@@ -24017,7 +24092,7 @@
"sv_SE": "Spelbart", "sv_SE": "Spelbart",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Справна", "uk_UA": "Оптимально",
"zh_CN": "可游玩", "zh_CN": "可游玩",
"zh_TW": "可暢順遊玩" "zh_TW": "可暢順遊玩"
} }
@@ -24144,7 +24219,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Запускається та оптимально працює (без збоїв або графічних багів) на середньостатистичному комп'ютері.", "uk_UA": "Запускається та оптимально працює (без збоїв або графічних багів) на середньостатистичному комп'ютері.",
"zh_CN": "启动和游戏时不会出现任何崩溃或任何类型的 GPU bug 且速度足够快可以在一般 PC 上尽情游玩。", "zh_CN": "启动和游戏时不会出现任何崩溃或任何类型的 GPU bug 且速度足够快可以在一般 PC 上尽情游玩。",
"zh_TW": "啟動和遊玩時不會出現任何崩潰或任何類型的 GPU bug 且速度足夠快可以在一般 PC 上盡情遊玩。" "zh_TW": ""
} }
}, },
{ {
@@ -24169,7 +24244,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Запускається, але в грі на вас чекатимуть одна або декілька наступних проблем: збої, зависання, графічні баги, спотворений звук або ж гра загалом працюватиме надто повільно. Можливо, її все ще можна пройти, але досвід буде не найкращим.", "uk_UA": "Запускається, але в грі на вас чекатимуть одна або декілька наступних проблем: збої, зависання, графічні баги, спотворений звук або ж гра загалом працюватиме надто повільно. Можливо, її все ще можна пройти, але досвід буде не найкращим.",
"zh_CN": "可以成功启动并进入游戏但可能会遇到以下一种或多种问题: 崩溃、卡死、GPU bug、令人无法接受的音频,或者只是太慢。仍然可以继续进行游戏,但是可能无法达到预期。", "zh_CN": "可以成功启动并进入游戏但可能会遇到以下一种或多种问题: 崩溃、卡死、GPU bug、令人无法接受的音频,或者只是太慢。仍然可以继续进行游戏,但是可能无法达到预期。",
"zh_TW": "能啟動並進入遊戲但可能會遇到下列狀況崩潰、卡死、GPU bug、令人無法接受的聲音、或遊戲過慢。遊戲或可繼續進行但是可能無法達到預期效果。" "zh_TW": ""
} }
}, },
{ {
@@ -24194,7 +24269,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Запускається та проходить початковий екран, але пограти не вийде.", "uk_UA": "Запускається та проходить початковий екран, але пограти не вийде.",
"zh_CN": "可以启动并通过标题画面但是无法进入到主要的游戏流程。", "zh_CN": "可以启动并通过标题画面但是无法进入到主要的游戏流程。",
"zh_TW": "能啟動並通過標題畫面,但是無法進入主要的遊戲畫面。" "zh_TW": ""
} }
}, },
{ {
@@ -24219,7 +24294,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Запускається, але не відображає навіть початкового екрану.", "uk_UA": "Запускається, але не відображає навіть початкового екрану.",
"zh_CN": "可以启动但是无法通过标题画面。", "zh_CN": "可以启动但是无法通过标题画面。",
"zh_TW": "能啟動,但是無法通過標題畫面。" "zh_TW": ""
} }
}, },
{ {
@@ -24244,7 +24319,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Взагалі не запускається.", "uk_UA": "Взагалі не запускається.",
"zh_CN": "无法启动或显示无任何动静。", "zh_CN": "无法启动或显示无任何动静。",
"zh_TW": "無法啟動" "zh_TW": ""
} }
}, },
{ {
@@ -24263,13 +24338,13 @@
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
"ru_RU": "Индивидуальные параметры", "ru_RU": "",
"sv_SE": "", "sv_SE": "",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Власна конфігурація", "uk_UA": "",
"zh_CN": "自定义配置", "zh_CN": "",
"zh_TW": "遊戲獨立自訂 (game-specific) 設定" "zh_TW": ""
} }
}, },
{ {
@@ -24288,13 +24363,13 @@
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
"ru_RU": "(Глобальный)", "ru_RU": "",
"sv_SE": "", "sv_SE": "",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "(Глобальні)", "uk_UA": "",
"zh_CN": "(全局)", "zh_CN": "",
"zh_TW": "(全域)" "zh_TW": ""
} }
}, },
{ {
@@ -24319,7 +24394,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Оберіть DLC які бажаєте вилучити", "uk_UA": "Оберіть DLC які бажаєте вилучити",
"zh_CN": "选择一个要解压的 DLC", "zh_CN": "选择一个要解压的 DLC",
"zh_TW": "選擇要提取的 DLC" "zh_TW": ""
} }
}, },
{ {
@@ -24344,7 +24419,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Зображення картки активності Discord", "uk_UA": "Зображення картки активності Discord",
"zh_CN": "Rich Presence 图像", "zh_CN": "Rich Presence 图像",
"zh_TW": "Rich Presence 圖像" "zh_TW": ""
} }
}, },
{ {
@@ -24369,7 +24444,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "Динамічна картка активності Discord", "uk_UA": "Динамічна картка активності Discord",
"zh_CN": "动态 Rich Presence", "zh_CN": "动态 Rich Presence",
"zh_TW": "動態 Rich Presence" "zh_TW": ""
} }
} }
] ]

View File

@@ -38,8 +38,8 @@ namespace Ryujinx.Ava.Common.Locale
{ LocaleKeys.RyujinxConfirm, [RyujinxApp.FullAppName] }, { LocaleKeys.RyujinxConfirm, [RyujinxApp.FullAppName] },
{ LocaleKeys.RyujinxUpdater, [RyujinxApp.FullAppName] }, { LocaleKeys.RyujinxUpdater, [RyujinxApp.FullAppName] },
{ LocaleKeys.RyujinxRebooter, [RyujinxApp.FullAppName] }, { LocaleKeys.RyujinxRebooter, [RyujinxApp.FullAppName] },
{ LocaleKeys.CompatibilityListSearchBoxWatermarkWithCount, [CompatibilityDatabase.Entries.Length] }, { LocaleKeys.CompatibilityListSearchBoxWatermarkWithCount, [CompatibilityCsv.Entries.Length] },
{ LocaleKeys.CompatibilityListTitle, [CompatibilityDatabase.Entries.Length] } { LocaleKeys.CompatibilityListTitle, [CompatibilityCsv.Entries.Length] }
}); });
Load(); Load();

View File

@@ -24,17 +24,4 @@ namespace Ryujinx.Ava.Common.Markup
protected override void ConfigureBindingExtension(CompiledBindingExtension bindingExtension) protected override void ConfigureBindingExtension(CompiledBindingExtension bindingExtension)
=> bindingExtension.Source = LocaleManager.Instance; => bindingExtension.Source = LocaleManager.Instance;
} }
internal class WindowTitleExtension(LocaleKeys key, bool includeVersion) : BasicMarkupExtension<string>
{
public WindowTitleExtension(LocaleKeys key) : this(key, true)
{
}
public override string Name => "WindowTitleTranslation";
protected override string Value => RyujinxApp.FormatTitle(key, includeVersion);
protected override void ConfigureBindingExtension(CompiledBindingExtension bindingExtension)
=> bindingExtension.Source = LocaleManager.Instance;
}
} }

View File

@@ -26,9 +26,9 @@ namespace Ryujinx.Ava.Common
internal class TrimmerWindow : Ryujinx.Common.Logging.XCIFileTrimmerLog internal class TrimmerWindow : Ryujinx.Common.Logging.XCIFileTrimmerLog
{ {
private readonly XciTrimmerViewModel _viewModel; private readonly XCITrimmerViewModel _viewModel;
public TrimmerWindow(XciTrimmerViewModel viewModel) public TrimmerWindow(XCITrimmerViewModel viewModel)
{ {
_viewModel = viewModel; _viewModel = viewModel;
} }

View File

@@ -9,9 +9,10 @@ using Ryujinx.Common.Logging;
using Ryujinx.HLE; using Ryujinx.HLE;
using Ryujinx.HLE.Loaders.Processes; using Ryujinx.HLE.Loaders.Processes;
using Ryujinx.Horizon; using Ryujinx.Horizon;
using Ryujinx.Horizon.Prepo.Types;
using System.Text; using System.Text;
namespace Ryujinx.Ava.Systems namespace Ryujinx.Ava
{ {
public static class DiscordIntegrationModule public static class DiscordIntegrationModule
{ {
@@ -123,7 +124,7 @@ namespace Ryujinx.Ava.Systems
_currentApp = null; _currentApp = null;
} }
private static void HandlePlayReport(Horizon.Prepo.Types.PlayReport playReport) private static void HandlePlayReport(PlayReport playReport)
{ {
if (_discordClient is null) return; if (_discordClient is null) return;
if (!TitleIDs.CurrentApplication.Value.HasValue) return; if (!TitleIDs.CurrentApplication.Value.HasValue) return;

View File

@@ -2,7 +2,6 @@ using DiscordRPC;
using LibHac.Tools.FsSystem; using LibHac.Tools.FsSystem;
using Ryujinx.Audio.Backends.SDL2; using Ryujinx.Audio.Backends.SDL2;
using Ryujinx.Ava; using Ryujinx.Ava;
using Ryujinx.Ava.Systems;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid;
@@ -12,6 +11,7 @@ using Ryujinx.Common.Configuration.Hid.Keyboard;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.GAL.Multithreading;
using Ryujinx.Graphics.OpenGL; using Ryujinx.Graphics.OpenGL;
using Ryujinx.Graphics.Vulkan; using Ryujinx.Graphics.Vulkan;
using Ryujinx.HLE; using Ryujinx.HLE;

View File

@@ -5,7 +5,6 @@ using Gommon;
using Projektanker.Icons.Avalonia; using Projektanker.Icons.Avalonia;
using Projektanker.Icons.Avalonia.FontAwesome; using Projektanker.Icons.Avalonia.FontAwesome;
using Projektanker.Icons.Avalonia.MaterialDesign; using Projektanker.Icons.Avalonia.MaterialDesign;
using Ryujinx.Ava.Systems;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Utilities;

View File

@@ -1,6 +1,8 @@
using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Utilities;
using SkiaSharp;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
@@ -8,7 +10,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Ryujinx.Ava.Systems namespace Ryujinx.Ava
{ {
internal static class Rebooter internal static class Rebooter
{ {

View File

@@ -91,12 +91,10 @@
<Content Include="..\..\distribution\legal\THIRDPARTY.md"> <Content Include="..\..\distribution\legal\THIRDPARTY.md">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
<TargetPath>THIRDPARTY.md</TargetPath> <TargetPath>THIRDPARTY.md</TargetPath>
<Visible>False</Visible>
</Content> </Content>
<Content Include="..\..\LICENSE.txt"> <Content Include="..\..\LICENSE.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
<TargetPath>LICENSE.txt</TargetPath> <TargetPath>LICENSE.txt</TargetPath>
<Visible>False</Visible>
</Content> </Content>
</ItemGroup> </ItemGroup>

View File

@@ -7,12 +7,12 @@ using Avalonia.Styling;
using Avalonia.Threading; using Avalonia.Threading;
using FluentAvalonia.UI.Windowing; using FluentAvalonia.UI.Windowing;
using Gommon; using Gommon;
using Ryujinx.Ava.Common;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.UI.Views.Dialog;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using System; using System;
@@ -150,7 +150,7 @@ namespace Ryujinx.Ava
private async void AboutRyujinx_OnClick(object sender, EventArgs e) private async void AboutRyujinx_OnClick(object sender, EventArgs e)
{ {
await AboutView.Show(); await AboutWindow.Show();
} }
} }
} }

View File

@@ -36,7 +36,7 @@ namespace Ryujinx.Ava.Systems.AppLibrary
{ {
_id = value; _id = value;
Compatibility = CompatibilityDatabase.Find(value); Compatibility = CompatibilityCsv.Find(value);
RichPresenceSpec = PlayReports.Analyzer.TryGetSpec(IdString, out GameSpec gameSpec) RichPresenceSpec = PlayReports.Analyzer.TryGetSpec(IdString, out GameSpec gameSpec)
? gameSpec ? gameSpec
: default(Optional<GameSpec>); : default(Optional<GameSpec>);

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
namespace Ryujinx.Ava.Systems.AppLibrary namespace Ryujinx.Ava.Systems.AppLibrary
{ {

View File

@@ -11,9 +11,24 @@ using System.Text;
namespace Ryujinx.Ava.Systems namespace Ryujinx.Ava.Systems
{ {
public class CompatibilityDatabase public struct ColumnIndices(Func<ReadOnlySpan<char>, int> getIndex)
{ {
static CompatibilityDatabase() => Load(); public const string TitleIdCol = "\"title_id\"";
public const string GameNameCol = "\"game_name\"";
public const string LabelsCol = "\"labels\"";
public const string StatusCol = "\"status\"";
public const string LastUpdatedCol = "\"last_updated\"";
public readonly int TitleId = getIndex(TitleIdCol);
public readonly int GameName = getIndex(GameNameCol);
public readonly int Labels = getIndex(LabelsCol);
public readonly int Status = getIndex(StatusCol);
public readonly int LastUpdated = getIndex(LastUpdatedCol);
}
public class CompatibilityCsv
{
static CompatibilityCsv() => Load();
public static void Load() public static void Load()
{ {
@@ -50,6 +65,16 @@ namespace Ryujinx.Ava.Systems
public static CompatibilityEntry Find(ulong titleId) public static CompatibilityEntry Find(ulong titleId)
=> Find(titleId.ToString("X16")); => Find(titleId.ToString("X16"));
public static LocaleKeys? GetStatus(string titleId)
=> Find(titleId)?.Status;
public static LocaleKeys? GetStatus(ulong titleId) => GetStatus(titleId.ToString("X16"));
public static string GetLabels(string titleId)
=> Find(titleId)?.FormattedIssueLabels;
public static string GetLabels(ulong titleId) => GetLabels(titleId.ToString("X16"));
} }
public class CompatibilityEntry public class CompatibilityEntry
@@ -110,7 +135,6 @@ namespace Ryujinx.Ava.Systems
public string FormattedIssueLabels => Labels public string FormattedIssueLabels => Labels
.Select(FormatLabelName) .Select(FormatLabelName)
.Where(x => x != null)
.JoinToString(", "); .JoinToString(", ");
public override string ToString() => public override string ToString() =>
@@ -134,6 +158,7 @@ namespace Ryujinx.Ava.Systems
"gui" => "GUI", "gui" => "GUI",
"help wanted" => "Help Wanted", "help wanted" => "Help Wanted",
"horizon" => "Horizon", "horizon" => "Horizon",
"infra" => "Project Infra",
"invalid" => "Invalid", "invalid" => "Invalid",
"kernel" => "Kernel", "kernel" => "Kernel",
"ldn" => "LDN", "ldn" => "LDN",
@@ -147,9 +172,9 @@ namespace Ryujinx.Ava.Systems
"ldn-untested" => "LDN Untested", "ldn-untested" => "LDN Untested",
"ldn-broken" => "LDN Broken", "ldn-broken" => "LDN Broken",
"ldn-partial" => "Partial LDN", "ldn-partial" => "Partial LDN",
"nvdec" => "GPU Video Decoding", "nvdec" => "NVDEC",
"services" => "HLE Services", "services" => "NX Services",
"services-horizon" => "New HLE Services", "services-horizon" => "Horizon OS Services",
"slow" => "Runs Slow", "slow" => "Runs Slow",
"crash" => "Crashes", "crash" => "Crashes",
"deadlock" => "Deadlock", "deadlock" => "Deadlock",
@@ -157,7 +182,7 @@ namespace Ryujinx.Ava.Systems
"opengl" => "OpenGL", "opengl" => "OpenGL",
"opengl-backend-bug" => "OpenGL Backend Bug", "opengl-backend-bug" => "OpenGL Backend Bug",
"vulkan-backend-bug" => "Vulkan Backend Bug", "vulkan-backend-bug" => "Vulkan Backend Bug",
"mac-bug" => "Mac-specific Problems", "mac-bug" => "Mac-specific Bug(s)",
"amd-vendor-bug" => "AMD GPU Bug", "amd-vendor-bug" => "AMD GPU Bug",
"intel-vendor-bug" => "Intel GPU Bug", "intel-vendor-bug" => "Intel GPU Bug",
"loader-allocator" => "Loader Allocator", "loader-allocator" => "Loader Allocator",
@@ -166,22 +191,18 @@ namespace Ryujinx.Ava.Systems
"UE4" => "Unreal Engine 4", "UE4" => "Unreal Engine 4",
"homebrew" => "Homebrew Content", "homebrew" => "Homebrew Content",
"online-broken" => "Online Broken", "online-broken" => "Online Broken",
_ => null _ => Capitalize(labelName)
}; };
}
public struct ColumnIndices(Func<ReadOnlySpan<char>, int> getIndex)
{
private const string TitleIdCol = "\"title_id\"";
private const string GameNameCol = "\"game_name\"";
private const string LabelsCol = "\"labels\"";
private const string StatusCol = "\"status\"";
private const string LastUpdatedCol = "\"last_updated\"";
public readonly int TitleId = getIndex(TitleIdCol); public static string Capitalize(string value)
public readonly int GameName = getIndex(GameNameCol); {
public readonly int Labels = getIndex(LabelsCol); if (value == string.Empty)
public readonly int Status = getIndex(StatusCol); return string.Empty;
public readonly int LastUpdated = getIndex(LastUpdatedCol);
char firstChar = value[0];
string rest = value[1..];
return $"{char.ToUpper(firstChar)}{rest}";
}
} }
} }

View File

@@ -15,7 +15,7 @@ namespace Ryujinx.Ava.Systems.Configuration
/// <summary> /// <summary>
/// The current version of the file format /// The current version of the file format
/// </summary> /// </summary>
public const int CurrentVersion = 68; public const int CurrentVersion = 67;
/// <summary> /// <summary>
/// Version of the configuration file format /// Version of the configuration file format

View File

@@ -46,11 +46,12 @@ namespace Ryujinx.Ava.Systems.Configuration
EnableDiscordIntegration.Value = cff.EnableDiscordIntegration; EnableDiscordIntegration.Value = cff.EnableDiscordIntegration;
CheckUpdatesOnStart.Value = shouldLoadFromFile ? cff.CheckUpdatesOnStart : CheckUpdatesOnStart.Value; // Get from global config only
UpdateCheckerType.Value = shouldLoadFromFile ? cff.UpdateCheckerType : UpdateCheckerType.Value; // Get from global config only UpdateCheckerType.Value = shouldLoadFromFile ? cff.UpdateCheckerType : UpdateCheckerType.Value; // Get from global config only
FocusLostActionType.Value = cff.FocusLostActionType; FocusLostActionType.Value = cff.FocusLostActionType;
ShowConfirmExit.Value = shouldLoadFromFile ? cff.ShowConfirmExit : ShowConfirmExit.Value; // Get from global config only ShowConfirmExit.Value = shouldLoadFromFile ? cff.ShowConfirmExit : ShowConfirmExit.Value; // Get from global config only
RememberWindowState.Value = shouldLoadFromFile ? cff.RememberWindowState : RememberWindowState.Value; // Get from global config only RememberWindowState.Value = shouldLoadFromFile ? cff.RememberWindowState : RememberWindowState.Value; // Get from global config only
ShowOldUI.Value = shouldLoadFromFile ? cff.ShowTitleBar : ShowOldUI.Value; // Get from global config only ShowTitleBar.Value = shouldLoadFromFile ? cff.ShowTitleBar : ShowTitleBar.Value; // Get from global config only
EnableHardwareAcceleration.Value = shouldLoadFromFile ? cff.EnableHardwareAcceleration : EnableHardwareAcceleration.Value; // Get from global config only EnableHardwareAcceleration.Value = shouldLoadFromFile ? cff.EnableHardwareAcceleration : EnableHardwareAcceleration.Value; // Get from global config only
HideCursor.Value = cff.HideCursor; HideCursor.Value = cff.HideCursor;
@@ -160,7 +161,9 @@ namespace Ryujinx.Ava.Systems.Configuration
DirtyHacks hacks = new (cff.DirtyHacks ?? []); DirtyHacks hacks = new (cff.DirtyHacks ?? []);
Hacks.Xc2MenuSoftlockFix.Value = hacks.IsEnabled(DirtyHack.Xc2MenuSoftlockFix); Hacks.Xc2MenuSoftlockFix.Value = hacks.IsEnabled(DirtyHack.Xc2MenuSoftlockFix);
Hacks.EnableShaderTranslationDelay.Value = hacks.IsEnabled(DirtyHack.ShaderTranslationDelay);
Hacks.ShaderTranslationDelay.Value = hacks[DirtyHack.ShaderTranslationDelay].CoerceAtLeast(0);
} }
if (configurationFileUpdated) if (configurationFileUpdated)
@@ -439,8 +442,6 @@ namespace Ryujinx.Ava.Systems.Configuration
(65, static cff => cff.UpdateCheckerType = cff.CheckUpdatesOnStart ? UpdaterType.PromptAtStartup : UpdaterType.Off), (65, static cff => cff.UpdateCheckerType = cff.CheckUpdatesOnStart ? UpdaterType.PromptAtStartup : UpdaterType.Off),
(66, static cff => cff.DisableInputWhenOutOfFocus = false), (66, static cff => cff.DisableInputWhenOutOfFocus = false),
(67, static cff => cff.FocusLostActionType = cff.DisableInputWhenOutOfFocus ? FocusLostType.BlockInput : FocusLostType.DoNothing) (67, static cff => cff.FocusLostActionType = cff.DisableInputWhenOutOfFocus ? FocusLostType.BlockInput : FocusLostType.DoNothing)
// 68 was the version that added per-game configs; the file structure did not change
// the version was increased so external tools could know that your Ryujinx version has per-game config capabilities.
); );
} }
} }

View File

@@ -11,6 +11,7 @@ using Ryujinx.Common.Helper;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using Ryujinx.HLE; using Ryujinx.HLE;
using Ryujinx.HLE.HOS.SystemState;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using RyuLogger = Ryujinx.Common.Logging.Logger; using RyuLogger = Ryujinx.Common.Logging.Logger;
@@ -683,15 +684,18 @@ namespace Ryujinx.Ava.Systems.Configuration
public ReactiveObject<bool> Xc2MenuSoftlockFix { get; private set; } public ReactiveObject<bool> Xc2MenuSoftlockFix { get; private set; }
public ReactiveObject<bool> DisableNifmIsAnyInternetRequestAccepted { get; private set; } public ReactiveObject<bool> EnableShaderTranslationDelay { get; private set; }
public ReactiveObject<int> ShaderTranslationDelay { get; private set; }
public HacksSection() public HacksSection()
{ {
ShowDirtyHacks = new ReactiveObject<bool>(); ShowDirtyHacks = new ReactiveObject<bool>();
Xc2MenuSoftlockFix = new ReactiveObject<bool>(); Xc2MenuSoftlockFix = new ReactiveObject<bool>();
Xc2MenuSoftlockFix.Event += HackChanged; Xc2MenuSoftlockFix.Event += HackChanged;
DisableNifmIsAnyInternetRequestAccepted = new ReactiveObject<bool>(); EnableShaderTranslationDelay = new ReactiveObject<bool>();
DisableNifmIsAnyInternetRequestAccepted.Event += HackChanged; EnableShaderTranslationDelay.Event += HackChanged;
ShaderTranslationDelay = new ReactiveObject<int>();
} }
private void HackChanged(object sender, ReactiveEventArgs<bool> rxe) private void HackChanged(object sender, ReactiveEventArgs<bool> rxe)
@@ -722,8 +726,8 @@ namespace Ryujinx.Ava.Systems.Configuration
if (Xc2MenuSoftlockFix) if (Xc2MenuSoftlockFix)
Apply(DirtyHack.Xc2MenuSoftlockFix); Apply(DirtyHack.Xc2MenuSoftlockFix);
if (DisableNifmIsAnyInternetRequestAccepted) if (EnableShaderTranslationDelay)
Apply(DirtyHack.NifmServiceDisableIsAnyInternetRequestAccepted); Apply(DirtyHack.ShaderTranslationDelay, ShaderTranslationDelay);
return enabledHacks.ToArray(); return enabledHacks.ToArray();
@@ -779,6 +783,11 @@ namespace Ryujinx.Ava.Systems.Configuration
/// Enables or disables Discord Rich Presence /// Enables or disables Discord Rich Presence
/// </summary> /// </summary>
public ReactiveObject<bool> EnableDiscordIntegration { get; private set; } public ReactiveObject<bool> EnableDiscordIntegration { get; private set; }
/// <summary>
/// Checks for updates when Ryujinx starts when enabled
/// </summary>
public ReactiveObject<bool> CheckUpdatesOnStart { get; private set; }
/// <summary> /// <summary>
/// Checks for updates when Ryujinx starts when enabled, either prompting when an update is found or just showing a notification. /// Checks for updates when Ryujinx starts when enabled, either prompting when an update is found or just showing a notification.
@@ -801,9 +810,9 @@ namespace Ryujinx.Ava.Systems.Configuration
public ReactiveObject<bool> RememberWindowState { get; private set; } public ReactiveObject<bool> RememberWindowState { get; private set; }
/// <summary> /// <summary>
/// Disable the new title bar layout & window layout changes. /// Enables or disables the redesigned title bar
/// </summary> /// </summary>
public ReactiveObject<bool> ShowOldUI { get; private set; } public ReactiveObject<bool> ShowTitleBar { get; private set; }
/// <summary> /// <summary>
/// Enables hardware-accelerated rendering for Avalonia /// Enables hardware-accelerated rendering for Avalonia
@@ -824,14 +833,15 @@ namespace Ryujinx.Ava.Systems.Configuration
Hid = new HidSection(); Hid = new HidSection();
Multiplayer = new MultiplayerSection(); Multiplayer = new MultiplayerSection();
Hacks = new HacksSection(); Hacks = new HacksSection();
EnableDiscordIntegration = new ReactiveObject<bool>();
CheckUpdatesOnStart = new ReactiveObject<bool>();
UpdateCheckerType = new ReactiveObject<UpdaterType>(); UpdateCheckerType = new ReactiveObject<UpdaterType>();
FocusLostActionType = new ReactiveObject<FocusLostType>(); FocusLostActionType = new ReactiveObject<FocusLostType>();
HideCursor = new ReactiveObject<HideCursorMode>();
EnableDiscordIntegration = new ReactiveObject<bool>();
ShowConfirmExit = new ReactiveObject<bool>(); ShowConfirmExit = new ReactiveObject<bool>();
RememberWindowState = new ReactiveObject<bool>(); RememberWindowState = new ReactiveObject<bool>();
ShowOldUI = new ReactiveObject<bool>(); ShowTitleBar = new ReactiveObject<bool>();
EnableHardwareAcceleration = new ReactiveObject<bool>(); EnableHardwareAcceleration = new ReactiveObject<bool>();
HideCursor = new ReactiveObject<HideCursorMode>();
} }
public HleConfiguration CreateHleConfiguration() => public HleConfiguration CreateHleConfiguration() =>

View File

@@ -56,11 +56,12 @@ namespace Ryujinx.Ava.Systems.Configuration
MatchSystemTime = System.MatchSystemTime, MatchSystemTime = System.MatchSystemTime,
DockedMode = System.EnableDockedMode, DockedMode = System.EnableDockedMode,
EnableDiscordIntegration = EnableDiscordIntegration, EnableDiscordIntegration = EnableDiscordIntegration,
CheckUpdatesOnStart = CheckUpdatesOnStart,
UpdateCheckerType = UpdateCheckerType, UpdateCheckerType = UpdateCheckerType,
FocusLostActionType = FocusLostActionType, FocusLostActionType = FocusLostActionType,
ShowConfirmExit = ShowConfirmExit, ShowConfirmExit = ShowConfirmExit,
RememberWindowState = RememberWindowState, RememberWindowState = RememberWindowState,
ShowTitleBar = ShowOldUI, ShowTitleBar = ShowTitleBar,
EnableHardwareAcceleration = EnableHardwareAcceleration, EnableHardwareAcceleration = EnableHardwareAcceleration,
HideCursor = HideCursor, HideCursor = HideCursor,
VSyncMode = Graphics.VSyncMode, VSyncMode = Graphics.VSyncMode,
@@ -182,7 +183,7 @@ namespace Ryujinx.Ava.Systems.Configuration
FocusLostActionType.Value = FocusLostType.DoNothing; FocusLostActionType.Value = FocusLostType.DoNothing;
ShowConfirmExit.Value = true; ShowConfirmExit.Value = true;
RememberWindowState.Value = true; RememberWindowState.Value = true;
ShowOldUI.Value = !OperatingSystem.IsWindows(); ShowTitleBar.Value = !OperatingSystem.IsWindows();
EnableHardwareAcceleration.Value = true; EnableHardwareAcceleration.Value = true;
HideCursor.Value = HideCursorMode.OnIdle; HideCursor.Value = HideCursorMode.OnIdle;
Graphics.VSyncMode.Value = VSyncMode.Switch; Graphics.VSyncMode.Value = VSyncMode.Switch;

View File

@@ -9,10 +9,10 @@ using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Common.Models; using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Views.Misc;
using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.UI.Views.Dialog;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Helper; using Ryujinx.Common.Helper;
using Ryujinx.HLE.HOS; using Ryujinx.HLE.HOS;
@@ -80,13 +80,13 @@ namespace Ryujinx.Ava.UI.Controls
public async void OpenTitleUpdateManager_Click(object sender, RoutedEventArgs args) public async void OpenTitleUpdateManager_Click(object sender, RoutedEventArgs args)
{ {
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel }) if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
await TitleUpdateManagerView.Show(viewModel.ApplicationLibrary, viewModel.SelectedApplication); await TitleUpdateWindow.Show(viewModel.ApplicationLibrary, viewModel.SelectedApplication);
} }
public async void OpenDownloadableContentManager_Click(object sender, RoutedEventArgs args) public async void OpenDownloadableContentManager_Click(object sender, RoutedEventArgs args)
{ {
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel }) if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
await DownloadableContentManagerView.Show(viewModel.ApplicationLibrary, viewModel.SelectedApplication); await DownloadableContentManagerWindow.Show(viewModel.ApplicationLibrary, viewModel.SelectedApplication);
} }
public async void OpenCheatManager_Click(object sender, RoutedEventArgs args) public async void OpenCheatManager_Click(object sender, RoutedEventArgs args)
@@ -127,7 +127,7 @@ namespace Ryujinx.Ava.UI.Controls
public async void OpenModManager_Click(object sender, RoutedEventArgs args) public async void OpenModManager_Click(object sender, RoutedEventArgs args)
{ {
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel }) if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
await ModManagerView.Show( await ModManagerWindow.Show(
viewModel.SelectedApplication.Id, viewModel.SelectedApplication.Id,
viewModel.SelectedApplication.IdBase, viewModel.SelectedApplication.IdBase,
viewModel.ApplicationLibrary, viewModel.ApplicationLibrary,

View File

@@ -1,28 +0,0 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Media.Imaging;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.UI.ViewModels;
using System.Reflection;
namespace Ryujinx.Ava.UI.Controls
{
public class RyujinxLogo : Image
{
// The UI specifically uses a thicker bordered variant of the icon to avoid crunching out the border at lower resolutions.
// For an example of this, download canary 1.2.95, then open the settings menu, and look at the icon in the top-left.
// The border gets reduced to colored pixels in the 4 corners.
public static readonly Bitmap Bitmap =
new(Assembly.GetAssembly(typeof(MainWindowViewModel))!
.GetManifestResourceStream("Ryujinx.Assets.UIImages.Logo_Ryujinx_AntiAlias.png")!);
public RyujinxLogo()
{
Margin = new Thickness(7, 7, 7, 0);
Height = 25;
Width = 25;
Source = Bitmap;
IsVisible = !ConfigurationState.Instance.ShowOldUI;
}
}
}

View File

@@ -3,6 +3,7 @@ using Avalonia.Styling;
using Avalonia.Threading; using Avalonia.Threading;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using Gommon; using Gommon;
using Ryujinx.Ava.Common;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Systems.Configuration;
using System; using System;

View File

@@ -432,7 +432,7 @@ namespace Ryujinx.Ava.UI.ViewModels
{ {
try try
{ {
HttpResponseMessage response = await _httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, "https://raw.githubusercontent.com/Ryubing/Nfc/refs/heads/main/tags.json")); HttpResponseMessage response = await _httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, "https://raw.githubusercontent.com/Ryubing/Ryujinx/refs/heads/master/assets/amiibo/Amiibo.json"));
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {
@@ -451,7 +451,7 @@ namespace Ryujinx.Ava.UI.ViewModels
{ {
try try
{ {
HttpResponseMessage response = await _httpClient.GetAsync("https://raw.githubusercontent.com/Ryubing/Nfc/refs/heads/main/tags.json"); HttpResponseMessage response = await _httpClient.GetAsync($"https://raw.githubusercontent.com/Ryubing/Ryujinx/refs/heads/master/assets/amiibo/Amiibo.json");
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {

View File

@@ -1,17 +1,17 @@
using Gommon; using Gommon;
using Ryujinx.Ava.Systems; using Ryujinx.Ava.Systems;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Systems.AppLibrary;
using System; using Ryujinx.Ava.UI.Windows;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace Ryujinx.Ava.UI.ViewModels namespace Ryujinx.Ava.UI.ViewModels
{ {
public class CompatibilityViewModel : BaseModel, IDisposable public class CompatibilityViewModel : BaseModel
{ {
private readonly ApplicationLibrary _appLibrary; private bool _onlyShowOwnedGames = true;
private IEnumerable<CompatibilityEntry> _currentEntries = CompatibilityDatabase.Entries; private IEnumerable<CompatibilityEntry> _currentEntries = CompatibilityCsv.Entries;
private string[] _ownedGameTitleIds = []; private string[] _ownedGameTitleIds = [];
public IEnumerable<CompatibilityEntry> CurrentEntries => OnlyShowOwnedGames public IEnumerable<CompatibilityEntry> CurrentEntries => OnlyShowOwnedGames
@@ -20,27 +20,15 @@ namespace Ryujinx.Ava.UI.ViewModels
: _currentEntries; : _currentEntries;
public CompatibilityViewModel() {} public CompatibilityViewModel() {}
private void AppCountUpdated(object _, ApplicationCountUpdatedEventArgs __)
=> _ownedGameTitleIds = _appLibrary.Applications.Keys.Select(x => x.ToString("X16")).ToArray();
public CompatibilityViewModel(ApplicationLibrary appLibrary) public CompatibilityViewModel(ApplicationLibrary appLibrary)
{ {
_appLibrary = appLibrary; appLibrary.ApplicationCountUpdated += (_, _)
=> _ownedGameTitleIds = appLibrary.Applications.Keys.Select(x => x.ToString("X16")).ToArray();
AppCountUpdated(null, null); _ownedGameTitleIds = appLibrary.Applications.Keys.Select(x => x.ToString("X16")).ToArray();
_appLibrary.ApplicationCountUpdated += AppCountUpdated;
} }
void IDisposable.Dispose()
{
GC.SuppressFinalize(this);
_appLibrary.ApplicationCountUpdated -= AppCountUpdated;
}
private bool _onlyShowOwnedGames = true;
public bool OnlyShowOwnedGames public bool OnlyShowOwnedGames
{ {
get => _onlyShowOwnedGames; get => _onlyShowOwnedGames;
@@ -58,11 +46,11 @@ namespace Ryujinx.Ava.UI.ViewModels
{ {
if (string.IsNullOrEmpty(searchTerm)) if (string.IsNullOrEmpty(searchTerm))
{ {
SetEntries(CompatibilityDatabase.Entries); SetEntries(CompatibilityCsv.Entries);
return; return;
} }
SetEntries(CompatibilityDatabase.Entries.Where(x => SetEntries(CompatibilityCsv.Entries.Where(x =>
x.GameName.ContainsIgnoreCase(searchTerm) x.GameName.ContainsIgnoreCase(searchTerm)
|| x.TitleId.Check(tid => tid.ContainsIgnoreCase(searchTerm)))); || x.TitleId.Check(tid => tid.ContainsIgnoreCase(searchTerm))));
} }

View File

@@ -1,5 +1,9 @@
using Avalonia.Svg.Skia; using Avalonia.Svg.Skia;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Input;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Models.Input; using Ryujinx.Ava.UI.Models.Input;
using Ryujinx.Ava.UI.Views.Input; using Ryujinx.Ava.UI.Views.Input;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
@@ -91,18 +95,21 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
} }
public async void ShowMotionConfig() public async void ShowMotionConfig()
{ {
await MotionInputView.Show(this); await MotionInputView.Show(this);
ParentModel.IsModified = true;
} }
public async void ShowRumbleConfig() public async void ShowRumbleConfig()
{ {
await RumbleInputView.Show(this); await RumbleInputView.Show(this);
ParentModel.IsModified = true;
} }
public async void ShowLedConfig() public async void ShowLedConfig()
{ {
await LedInputView.Show(this); await LedInputView.Show(this);
ParentModel.IsModified = true;
} }
public void OnParentModelChanged() public void OnParentModelChanged()

View File

@@ -88,13 +88,41 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public bool IsKeyboard => !IsController; public bool IsKeyboard => !IsController;
public bool IsRight { get; set; } public bool IsRight { get; set; }
public bool IsLeft { get; set; } public bool IsLeft { get; set; }
public int DeviceIndexBeforeChange { get; set; }
public bool HasLed => SelectedGamepad.Features.HasFlag(GamepadFeaturesFlag.Led); public bool HasLed => SelectedGamepad.Features.HasFlag(GamepadFeaturesFlag.Led);
public bool CanClearLed => SelectedGamepad.Name.ContainsIgnoreCase("DualSense"); public bool CanClearLed => SelectedGamepad.Name.ContainsIgnoreCase("DualSense");
public bool IsModified { get; set; } public bool _isChangeTrackingActive;
public bool _isModified;
public bool IsModified
{
get => _isModified;
set
{
_isModified = value;
OnPropertyChanged();
}
}
public event Action NotifyChangesEvent; public event Action NotifyChangesEvent;
public string _profileChoose;
public string ProfileChoose
{
get => _profileChoose;
set
{
// When you select a profile, the settings from the profile will be applied.
// To save the settings, you still need to click the apply button
_profileChoose = value;
LoadProfile();
OnPropertyChanged();
}
}
public object ConfigViewModel public object ConfigViewModel
{ {
get => _configViewModel; get => _configViewModel;
@@ -120,14 +148,14 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
set set
{ {
if (IsModified) if (IsModified)
{ {
_playerIdChoose = value; _playerIdChoose = value;
return; return;
} }
IsModified = false; IsModified = false;
_playerId = value; _playerId = value;
_isChangeTrackingActive = false;
if (!Enum.IsDefined<PlayerIndex>(_playerId)) if (!Enum.IsDefined<PlayerIndex>(_playerId))
{ {
@@ -135,13 +163,13 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
} }
_isLoaded = false; _isLoaded = false;
LoadConfiguration(); LoadConfiguration();
LoadDevice(); LoadDevice();
LoadProfiles(); LoadProfiles();
DeviceIndexBeforeChange = Device;
_isLoaded = true; _isLoaded = true;
_isChangeTrackingActive = true;
OnPropertyChanged(); OnPropertyChanged();
} }
} }
@@ -185,11 +213,12 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
IsLeft = false; IsLeft = false;
break; break;
} }
LoadInputDriver(); LoadInputDriver();
LoadProfiles(); LoadProfiles();
SetChangeTrackingActive();
} }
OnPropertyChanged(); OnPropertyChanged();
NotifyChanges(); NotifyChanges();
} }
@@ -229,6 +258,11 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
get => _device; get => _device;
set set
{ {
if (!IsModified)
{
DeviceIndexBeforeChange = _device;
}
_device = value < 0 ? 0 : value; _device = value < 0 ? 0 : value;
if (_device >= Devices.Count) if (_device >= Devices.Count)
@@ -248,13 +282,28 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
} }
} }
FindPairedDevice();
SetChangeTrackingActive();
OnPropertyChanged(); OnPropertyChanged();
NotifyChanges(); NotifyChanges();
} }
} }
public InputConfig Config { get; set; } public InputConfig Config { get; set; }
public bool _notificationView;
public bool NotificationView
{
get => _notificationView;
set
{
_notificationView = value;
OnPropertyChanged();
}
}
public InputViewModel(UserControl owner) : this() public InputViewModel(UserControl owner) : this()
{ {
if (Program.PreviewerDetached) if (Program.PreviewerDetached)
@@ -274,6 +323,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
PlayerId = PlayerIndex.Player1; PlayerId = PlayerIndex.Player1;
} }
_isChangeTrackingActive = true;
} }
public InputViewModel() public InputViewModel()
@@ -311,8 +362,54 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
{ {
ConfigViewModel = new ControllerInputViewModel(this, new GamepadInputConfig(controllerInputConfig), VisualStick); ConfigViewModel = new ControllerInputViewModel(this, new GamepadInputConfig(controllerInputConfig), VisualStick);
} }
FindPairedDevice();
} }
private void FindPairedDevice()
{
// This feature allows you to display a notification
// if a configuration is found, but the gamepad is not connected.
if (Config != null)
{
(DeviceType Type, string Id, string Name) activeDevice = Devices.FirstOrDefault(d => d.Id == Config.Id);
if (activeDevice.Id != Config.Id)
{
// display notification when input device is turned off, and
// if device and configuration do not match (different controllers)
NotificationView = true;
}
else
{
NotificationView = false;
}
}
else
{
NotificationView = false;
}
}
private void SetChangeTrackingActive()
{
if (_isChangeTrackingActive)
{
IsModified = true;
}
}
public void DisableDeviceForSaving()
{
// "Disabled" mode is available after unbinding the device
// NOTE: the IsModified flag to be able to apply the settings.
IsModified = true;
NotificationView = false;
}
public void LoadDevice() public void LoadDevice()
{ {
if (Config == null || Config.Backend == InputBackendType.Invalid) if (Config == null || Config.Backend == InputBackendType.Invalid)
@@ -378,14 +475,37 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
} }
} }
private void HandleOnGamepadDisconnected(string id) private async void HandleOnGamepadDisconnected(string id)
{ {
Dispatcher.UIThread.Post(LoadDevices); _isChangeTrackingActive = false;
await Dispatcher.UIThread.InvokeAsync(() =>
{
LoadDevices();
IsModified = true;
LoadSavedConfiguration();
FindPairedDevice();
_isChangeTrackingActive = true;
return System.Threading.Tasks.Task.CompletedTask;
});
} }
private void HandleOnGamepadConnected(string id) private async void HandleOnGamepadConnected(string id)
{ {
Dispatcher.UIThread.Post(LoadDevices); _isChangeTrackingActive = false;
await Dispatcher.UIThread.InvokeAsync(() =>
{
LoadDevices();
if (Config != null)
{
// Load configuration after connection if it is in the configuration file
IsModified = true;
LoadSavedConfiguration();
}
_isChangeTrackingActive = true;
});
} }
private string GetCurrentGamepadId() private string GetCurrentGamepadId()
@@ -688,6 +808,12 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
return config; return config;
} }
public void LoadProfileButton()
{
IsModified = true;
LoadProfile();
}
public async void LoadProfile() public async void LoadProfile()
{ {
if (Device == 0) if (Device == 0)
@@ -739,9 +865,12 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
{ {
_isLoaded = false; _isLoaded = false;
config.Id = null; // ignore device IDs (there is no longer a need to store device IDs for presets due to their independence from devices)
LoadConfiguration(config); LoadConfiguration(config);
LoadDevice(); // This line of code hard-links profiles to controllers, the commented line allows profiles to be applied to all controllers
// LoadDevice();
_isLoaded = true; _isLoaded = true;
@@ -793,6 +922,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
await File.WriteAllTextAsync(path, jsonString); await File.WriteAllTextAsync(path, jsonString);
LoadProfiles(); LoadProfiles();
ProfileChoose = ProfileName; // Show new profile
} }
else else
{ {
@@ -825,14 +956,40 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
} }
LoadProfiles(); LoadProfiles();
ProfileChoose = ProfilesList[0].ToString(); // Show default profile
}
}
public void LoadSavedConfiguration()
{
// Restores settings and sets the previously selected device to the last saved state
// NOTE: The current order allows the configuration and device to be loaded correctly until the configuration is changed.
if (IsModified) // Fixes random gamepad appearance in "disabled" option
{
Device = DeviceIndexBeforeChange;
LoadDevice();
LoadConfiguration();
IsModified = false;
OnPropertyChanged();
} }
} }
public void Save() public void Save()
{ {
IsModified = false;
if (!IsModified)
{
return; //If the input settings were not touched, then do nothing
}
List<InputConfig> newConfig = []; IsModified = false;
DeviceIndexBeforeChange = Device;
List <InputConfig> newConfig = [];
newConfig.AddRange(ConfigurationState.Instance.Hid.InputConfig.Value); newConfig.AddRange(ConfigurationState.Instance.Hid.InputConfig.Value);

View File

@@ -3,6 +3,7 @@ using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Media.Imaging;
using Avalonia.Platform.Storage; using Avalonia.Platform.Storage;
using Avalonia.Threading; using Avalonia.Threading;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
@@ -16,7 +17,6 @@ using LibHac.Ns;
using Ryujinx.Ava.Common; using Ryujinx.Ava.Common;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Input; using Ryujinx.Ava.Input;
using Ryujinx.Ava.Systems;
using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Models; using Ryujinx.Ava.UI.Models;
@@ -46,6 +46,7 @@ using System.Collections.ObjectModel;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Key = Ryujinx.Input.Key; using Key = Ryujinx.Input.Key;
@@ -136,6 +137,13 @@ namespace Ryujinx.Ava.UI.ViewModels
// Key is Title ID // Key is Title ID
public SafeDictionary<string, LdnGameData.Array> LdnData = []; public SafeDictionary<string, LdnGameData.Array> LdnData = [];
// The UI specifically uses a thicker bordered variant of the icon to avoid crunching out the border at lower resolutions.
// For an example of this, download canary 1.2.95, then open the settings menu, and look at the icon in the top-left.
// The border gets reduced to colored pixels in the 4 corners.
public static readonly Bitmap IconBitmap =
new(Assembly.GetAssembly(typeof(MainWindowViewModel))!
.GetManifestResourceStream("Ryujinx.Assets.UIImages.Logo_Ryujinx_AntiAlias.png")!);
public MainWindow Window { get; init; } public MainWindow Window { get; init; }
internal AppHost AppHost { get; set; } internal AppHost AppHost { get; set; }
@@ -1786,7 +1794,7 @@ namespace Ryujinx.Ava.UI.ViewModels
if (WindowState is not WindowState.Normal) if (WindowState is not WindowState.Normal)
{ {
WindowState = WindowState.Normal; WindowState = WindowState.Normal;
Window.TitleBar.ExtendsContentIntoTitleBar = !ConfigurationState.Instance.ShowOldUI; Window.TitleBar.ExtendsContentIntoTitleBar = !ConfigurationState.Instance.ShowTitleBar;
if (IsGameRunning) if (IsGameRunning)
{ {

View File

@@ -16,12 +16,11 @@ namespace Ryujinx.Ava.UI.ViewModels
} }
[ObservableProperty] private bool _xc2MenuSoftlockFix = ConfigurationState.Instance.Hacks.Xc2MenuSoftlockFix; [ObservableProperty] private bool _xc2MenuSoftlockFix = ConfigurationState.Instance.Hacks.Xc2MenuSoftlockFix;
[ObservableProperty] private bool _nifmDisableIsAnyInternetRequestAccepted = ConfigurationState.Instance.Hacks.DisableNifmIsAnyInternetRequestAccepted;
public static string Xc2MenuFixTooltip { get; } = Lambda.String(sb => public static string Xc2MenuFixTooltip { get; } = Lambda.String(sb =>
{ {
sb.AppendLine( sb.AppendLine(
"This hack applies a 2ms delay (via 'Thread.Sleep(2)') every time the game tries to read data from the emulated Switch filesystem.") "This fix applies a 2ms delay (via 'Thread.Sleep(2)') every time the game tries to read data from the emulated Switch filesystem.")
.AppendLine(); .AppendLine();
sb.AppendLine("From the issue on GitHub:").AppendLine(); sb.AppendLine("From the issue on GitHub:").AppendLine();
@@ -30,14 +29,5 @@ namespace Ryujinx.Ava.UI.ViewModels
"there is a low chance that the game will softlock, " + "there is a low chance that the game will softlock, " +
"the submenu won't show up, while background music is still there."); "the submenu won't show up, while background music is still there.");
}); });
public static string NifmDisableIsAnyInternetRequestAcceptedTooltip { get; } = Lambda.String(sb =>
{
sb.AppendLine(
"This hack simply sets 'IsAnyInternetRequestAccepted' to 'false' when initializing the Nifm IGeneralService.")
.AppendLine();
sb.Append("Lets DOOM 2016 go in game.");
});
} }
} }

View File

@@ -130,10 +130,11 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool IsOpenGLAvailable => !OperatingSystem.IsMacOS(); public bool IsOpenGLAvailable => !OperatingSystem.IsMacOS();
public bool EnableDiscordIntegration { get; set; } public bool EnableDiscordIntegration { get; set; }
public bool CheckUpdatesOnStart { get; set; }
public bool ShowConfirmExit { get; set; } public bool ShowConfirmExit { get; set; }
public bool IgnoreApplet { get; set; } public bool IgnoreApplet { get; set; }
public bool RememberWindowState { get; set; } public bool RememberWindowState { get; set; }
public bool ShowOldUI { get; set; } public bool ShowTitleBar { get; set; }
public int HideCursor { get; set; } public int HideCursor { get; set; }
public int UpdateCheckerType { get; set; } public int UpdateCheckerType { get; set; }
public bool EnableDockedMode { get; set; } public bool EnableDockedMode { get; set; }
@@ -536,9 +537,10 @@ namespace Ryujinx.Ava.UI.ViewModels
// User Interface // User Interface
EnableDiscordIntegration = config.EnableDiscordIntegration; EnableDiscordIntegration = config.EnableDiscordIntegration;
CheckUpdatesOnStart = config.CheckUpdatesOnStart;
ShowConfirmExit = config.ShowConfirmExit; ShowConfirmExit = config.ShowConfirmExit;
RememberWindowState = config.RememberWindowState; RememberWindowState = config.RememberWindowState;
ShowOldUI = config.ShowOldUI; ShowTitleBar = config.ShowTitleBar;
HideCursor = (int)config.HideCursor.Value; HideCursor = (int)config.HideCursor.Value;
UpdateCheckerType = (int)config.UpdateCheckerType.Value; UpdateCheckerType = (int)config.UpdateCheckerType.Value;
FocusLostActionType = (int)config.FocusLostActionType.Value; FocusLostActionType = (int)config.FocusLostActionType.Value;
@@ -644,9 +646,10 @@ namespace Ryujinx.Ava.UI.ViewModels
// User Interface // User Interface
config.EnableDiscordIntegration.Value = EnableDiscordIntegration; config.EnableDiscordIntegration.Value = EnableDiscordIntegration;
config.CheckUpdatesOnStart.Value = CheckUpdatesOnStart;
config.ShowConfirmExit.Value = ShowConfirmExit; config.ShowConfirmExit.Value = ShowConfirmExit;
config.RememberWindowState.Value = RememberWindowState; config.RememberWindowState.Value = RememberWindowState;
config.ShowOldUI.Value = ShowOldUI; config.ShowTitleBar.Value = ShowTitleBar;
config.HideCursor.Value = (HideCursorMode)HideCursor; config.HideCursor.Value = (HideCursorMode)HideCursor;
config.UpdateCheckerType.Value = (UpdaterType)UpdateCheckerType; config.UpdateCheckerType.Value = (UpdaterType)UpdateCheckerType;
config.FocusLostActionType.Value = (FocusLostType)FocusLostActionType; config.FocusLostActionType.Value = (FocusLostType)FocusLostActionType;
@@ -757,8 +760,6 @@ namespace Ryujinx.Ava.UI.ViewModels
// Dirty Hacks // Dirty Hacks
config.Hacks.Xc2MenuSoftlockFix.Value = DirtyHacks.Xc2MenuSoftlockFix; config.Hacks.Xc2MenuSoftlockFix.Value = DirtyHacks.Xc2MenuSoftlockFix;
config.Hacks.DisableNifmIsAnyInternetRequestAccepted.Value =
DirtyHacks.NifmDisableIsAnyInternetRequestAccepted;
config.ToFileFormat().SaveConfig(Program.ConfigurationPath); config.ToFileFormat().SaveConfig(Program.ConfigurationPath);

View File

@@ -16,7 +16,7 @@ using static Ryujinx.Common.Utilities.XCIFileTrimmer;
namespace Ryujinx.Ava.UI.ViewModels namespace Ryujinx.Ava.UI.ViewModels
{ {
public class XciTrimmerViewModel : BaseModel public class XCITrimmerViewModel : BaseModel
{ {
private const long _bytesPerMB = 1024 * 1024; private const long _bytesPerMB = 1024 * 1024;
private enum ProcessingMode private enum ProcessingMode
@@ -46,7 +46,7 @@ namespace Ryujinx.Ava.UI.ViewModels
private SortField _sortField = SortField.Name; private SortField _sortField = SortField.Name;
private bool _sortAscending = true; private bool _sortAscending = true;
public XciTrimmerViewModel(MainWindowViewModel mainWindowViewModel) public XCITrimmerViewModel(MainWindowViewModel mainWindowViewModel)
{ {
_logger = new XCITrimmerLog.TrimmerWindow(this); _logger = new XCITrimmerLog.TrimmerWindow(this);
_mainWindowViewModel = mainWindowViewModel; _mainWindowViewModel = mainWindowViewModel;
@@ -254,9 +254,9 @@ namespace Ryujinx.Ava.UI.ViewModels
private class CompareXCITrimmerFiles : IComparer<XCITrimmerFileModel> private class CompareXCITrimmerFiles : IComparer<XCITrimmerFileModel>
{ {
private XciTrimmerViewModel _viewModel; private XCITrimmerViewModel _viewModel;
public CompareXCITrimmerFiles(XciTrimmerViewModel ViewModel) public CompareXCITrimmerFiles(XCITrimmerViewModel ViewModel)
{ {
_viewModel = ViewModel; _viewModel = ViewModel;
} }

View File

@@ -4,10 +4,10 @@
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup" xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls" xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels.Input" xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels.Input"
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers" xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
xmlns:pt="using:Projektanker.Icons.Avalonia"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" VerticalAlignment="Stretch"
d:DesignHeight="800" d:DesignHeight="800"
@@ -507,49 +507,65 @@
CornerRadius="5" CornerRadius="5"
VerticalAlignment="Bottom" VerticalAlignment="Bottom"
HorizontalAlignment="Stretch"> HorizontalAlignment="Stretch">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> <Grid ColumnDefinitions="*,Auto">
<StackPanel Orientation="Vertical" Spacing="5"> <CheckBox
<CheckBox Margin="10"
Margin="10, 10, 10, 0" MinWidth="0"
MinWidth="0" Grid.Column="0"
IsChecked="{Binding Config.EnableMotion, Mode=TwoWay}"> IsChecked="{Binding Config.EnableMotion, Mode=TwoWay}">
<TextBlock Text="{ext:Locale ControllerSettingsMotion}" /> <TextBlock Text="{ext:Locale ControllerSettingsMotion}" />
</CheckBox> </CheckBox>
<Button <Button
Margin="10, 0, 10, 10" Margin="10"
Command="{Binding ShowMotionConfig}"> Grid.Column="1"
<pt:Icon Value="fa-solid fa-gear" /> Command="{Binding ShowMotionConfig}">
</Button> <TextBlock Text="{ext:Locale ControllerSettingsConfigureGeneral}" />
</StackPanel> </Button>
<controls:MiniVerticalSeparator Height="64"/> </Grid>
<StackPanel Orientation="Vertical" Spacing="5"> </Border>
<CheckBox <Border
Margin="10, 10, 10, 0" BorderBrush="{DynamicResource ThemeControlBorderColor}"
MinWidth="0" BorderThickness="1"
IsChecked="{Binding Config.EnableRumble, Mode=TwoWay}"> CornerRadius="5"
<TextBlock Text="{ext:Locale ControllerSettingsRumble}" /> HorizontalAlignment="Stretch"
</CheckBox> Margin="0,-1,0,0">
<Button <Grid ColumnDefinitions="*,Auto">
Margin="10, 0, 10, 10" <CheckBox
Command="{Binding ShowRumbleConfig}"> Margin="10"
<pt:Icon Value="fa-solid fa-gear" /> MinWidth="0"
</Button> Grid.Column="0"
</StackPanel> IsChecked="{Binding Config.EnableRumble, Mode=TwoWay}">
<controls:MiniVerticalSeparator Height="64" IsVisible="{Binding ParentModel.HasLed}"/> <TextBlock Text="{ext:Locale ControllerSettingsRumble}" />
<StackPanel Orientation="Vertical" Spacing="5"> </CheckBox>
<CheckBox <Button
Margin="10, 10, 10, 0" Margin="10"
MinWidth="0" Grid.Column="1"
IsChecked="{Binding Config.EnableLedChanging, Mode=TwoWay}"> Command="{Binding ShowRumbleConfig}">
<TextBlock Text="{ext:Locale ControllerSettingsLed}" /> <TextBlock Text="{ext:Locale ControllerSettingsConfigureGeneral}" />
</CheckBox> </Button>
<Button </Grid>
Margin="10, 0, 10, 10" </Border>
Command="{Binding ShowLedConfig}"> <Border
<pt:Icon Value="fa-solid fa-gear" /> BorderBrush="{DynamicResource ThemeControlBorderColor}"
</Button> BorderThickness="1"
</StackPanel> CornerRadius="5"
</StackPanel> HorizontalAlignment="Stretch"
Margin="0,-1,0,0">
<Grid IsVisible="{Binding ParentModel.HasLed}" ColumnDefinitions="*,Auto">
<CheckBox
Margin="10, 10, 5, 10"
MinWidth="0"
Grid.Column="0"
IsChecked="{Binding Config.EnableLedChanging, Mode=TwoWay}">
<TextBlock Text="{ext:Locale ControllerSettingsLed}" />
</CheckBox>
<Button
Margin="10"
Grid.Column="1"
Command="{Binding ShowLedConfig}">
<TextBlock Text="{ext:Locale ControllerSettingsConfigureGeneral}" />
</Button>
</Grid>
</Border> </Border>
</StackPanel> </StackPanel>
</StackPanel> </StackPanel>

View File

@@ -64,8 +64,9 @@ namespace Ryujinx.Ava.UI.Views.Input
}; };
if (!float.IsNaN(_changeSlider) && _changeSlider != (float)check.Value) if (!float.IsNaN(_changeSlider) && _changeSlider != (float)check.Value)
{ {
(DataContext as ControllerInputViewModel)!.ParentModel.IsModified = true; FlagInputConfigChanged();
_changeSlider = (float)check.Value; _changeSlider = (float)check.Value;
} }
} }
@@ -75,7 +76,8 @@ namespace Ryujinx.Ava.UI.Views.Input
{ {
if (sender is CheckBox { IsPointerOver: true }) if (sender is CheckBox { IsPointerOver: true })
{ {
(DataContext as ControllerInputViewModel)!.ParentModel.IsModified = true; FlagInputConfigChanged();
_currentAssigner?.Cancel(); _currentAssigner?.Cancel();
_currentAssigner = null; _currentAssigner = null;
} }
@@ -102,7 +104,7 @@ namespace Ryujinx.Ava.UI.Views.Input
this.Focus(NavigationMethod.Pointer); this.Focus(NavigationMethod.Pointer);
PointerPressed += MouseClick; PointerPressed += MouseClick;
ControllerInputViewModel viewModel = (DataContext as ControllerInputViewModel); ControllerInputViewModel viewModel = (DataContext as ControllerInputViewModel);
IKeyboard keyboard = IKeyboard keyboard =
@@ -115,7 +117,7 @@ namespace Ryujinx.Ava.UI.Views.Input
if (e.ButtonValue.HasValue) if (e.ButtonValue.HasValue)
{ {
Button buttonValue = e.ButtonValue.Value; Button buttonValue = e.ButtonValue.Value;
viewModel.ParentModel.IsModified = true; FlagInputConfigChanged();
switch (button.Name) switch (button.Name)
{ {
@@ -209,6 +211,11 @@ namespace Ryujinx.Ava.UI.Views.Input
} }
} }
private void FlagInputConfigChanged()
{
(DataContext as ControllerInputViewModel)!.ParentModel.IsModified = true;
}
private void MouseClick(object sender, PointerPressedEventArgs e) private void MouseClick(object sender, PointerPressedEventArgs e)
{ {
bool shouldUnbind = e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed; bool shouldUnbind = e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed;
@@ -232,7 +239,6 @@ namespace Ryujinx.Ava.UI.Views.Input
{ {
gamepad?.ClearLed(); gamepad?.ClearLed();
} }
_currentAssigner?.Cancel(); _currentAssigner?.Cancel();
_currentAssigner = null; _currentAssigner = null;
} }

View File

@@ -41,13 +41,20 @@
Grid.Column="0" Grid.Column="0"
Margin="2" Margin="2"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Center" ColumnDefinitions="Auto,*"> VerticalAlignment="Center" ColumnDefinitions="Auto,*,Auto">
<TextBlock <StackPanel
Orientation="Vertical"
Margin="5,0,10,0" Margin="5,0,10,0"
Width="90"
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Center" VerticalAlignment="Center"
Text="{ext:Locale ControllerSettingsPlayer}" /> Width="90">
<TextBlock
Text="{ext:Locale ControllerSettingsPlayer}" />
<TextBlock
Classes="pending"
Text ="{ext:Locale ControllerSettingsModifiedNotification}"
IsVisible="{Binding IsModified}"/>
</StackPanel>
<ComboBox <ComboBox
Grid.Column="1" Grid.Column="1"
Name="PlayerIndexBox" Name="PlayerIndexBox"
@@ -62,6 +69,18 @@
</DataTemplate> </DataTemplate>
</ComboBox.ItemTemplate> </ComboBox.ItemTemplate>
</ComboBox> </ComboBox>
<Button
Grid.Column="2"
MinWidth="0"
Margin="5,0,0,0"
VerticalAlignment="Center"
ToolTip.Tip="{ext:Locale ControllerSettingsCancelCurrentChangesToolTip}"
Command="{Binding LoadSavedConfiguration}">
<ui:SymbolIcon
Symbol="Undo"
FontSize="15"
Height="20" />
</Button>
</Grid> </Grid>
<!-- Profile Selection --> <!-- Profile Selection -->
<Grid <Grid
@@ -81,7 +100,8 @@
Name="ProfileBox" Name="ProfileBox"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Center" VerticalAlignment="Center"
SelectedIndex="0" SelectedItem="{Binding ProfileChoose, Mode=TwoWay}"
SelectionChanged="ComboBox_SelectionChanged"
ItemsSource="{Binding ProfilesList}" ItemsSource="{Binding ProfilesList}"
Text="{Binding ProfileName, Mode=TwoWay}" /> Text="{Binding ProfileName, Mode=TwoWay}" />
<Button <Button
@@ -90,7 +110,7 @@
Margin="5,0,0,0" Margin="5,0,0,0"
VerticalAlignment="Center" VerticalAlignment="Center"
ToolTip.Tip="{ext:Locale ControllerSettingsLoadProfileToolTip}" ToolTip.Tip="{ext:Locale ControllerSettingsLoadProfileToolTip}"
Command="{Binding LoadProfile}"> Command="{Binding LoadProfileButton}">
<ui:SymbolIcon <ui:SymbolIcon
Symbol="View" Symbol="View"
FontSize="15" FontSize="15"
@@ -148,7 +168,7 @@
MinWidth="0" MinWidth="0"
Margin="5,0,0,0" Margin="5,0,0,0"
VerticalAlignment="Center" VerticalAlignment="Center"
Command="{Binding LoadDevices}"> Command="{Binding LoadDevice}">
<ui:SymbolIcon <ui:SymbolIcon
Symbol="Refresh" Symbol="Refresh"
FontSize="15" FontSize="15"
@@ -181,15 +201,37 @@
</Grid> </Grid>
</Grid> </Grid>
</StackPanel> </StackPanel>
<ContentControl Content="{Binding ConfigViewModel}" IsVisible="{Binding ShowSettings}"> <ContentControl IsVisible="{Binding NotificationView}">
<ContentControl.DataTemplates> <ContentControl.Content>
<DataTemplate DataType="viewModels:ControllerInputViewModel"> <StackPanel>
<views:ControllerInputView /> <TextBlock
</DataTemplate> Margin="5,20,0,0"
<DataTemplate DataType="viewModels:KeyboardInputViewModel"> Text="{ext:Locale ControllerSettingsDisableDeviceForSaving}" />
<views:KeyboardInputView />
</DataTemplate> <Button
</ContentControl.DataTemplates> MinWidth="0"
Width="90"
Height="27"
Margin="5,10,0,0"
VerticalAlignment="Center"
Command="{Binding DisableDeviceForSaving}">
<TextBlock
Text="{ext:Locale ControllerSettingsUnlink}"
VerticalAlignment="Center"
HorizontalAlignment="Center" />
</Button>
</StackPanel>
</ContentControl.Content>
</ContentControl> </ContentControl>
<ContentControl Content="{Binding ConfigViewModel}" IsVisible="{Binding ShowSettings}">
<ContentControl.DataTemplates>
<DataTemplate DataType="viewModels:ControllerInputViewModel">
<views:ControllerInputView />
</DataTemplate>
<DataTemplate DataType="viewModels:KeyboardInputViewModel">
<views:KeyboardInputView />
</DataTemplate>
</ContentControl.DataTemplates>
</ContentControl>
</StackPanel> </StackPanel>
</UserControl> </UserControl>

View File

@@ -1,4 +1,5 @@
using Avalonia.Controls; using Avalonia.Controls;
using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
@@ -62,14 +63,23 @@ namespace Ryujinx.Ava.UI.Views.Input
} }
return; return;
} }
ViewModel.PlayerId = ViewModel.PlayerIdChoose;
ViewModel.IsModified = false; ViewModel.IsModified = false;
} ViewModel.PlayerId = ViewModel.PlayerIdChoose;
}
} }
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (sender is FAComboBox faComboBox)
{
faComboBox.IsDropDownOpen = false;
ViewModel.IsModified = true;
}
}
public void Dispose() public void Dispose()
{ {
ViewModel.Dispose(); ViewModel.Dispose();

View File

@@ -9,6 +9,8 @@ using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels.Input; using Ryujinx.Ava.UI.ViewModels.Input;
using Ryujinx.Input; using Ryujinx.Input;
using Ryujinx.Input.Assigner; using Ryujinx.Input.Assigner;
using System.Collections.Generic;
using System;
using Button = Ryujinx.Input.Button; using Button = Ryujinx.Input.Button;
using Key = Ryujinx.Common.Configuration.Hid.Key; using Key = Ryujinx.Common.Configuration.Hid.Key;
@@ -182,15 +184,74 @@ namespace Ryujinx.Ava.UI.Views.Input
} }
} }
private void FlagInputConfigChanged()
{
(DataContext as KeyboardInputViewModel)!.ParentModel.IsModified = true;
}
private void MouseClick(object sender, PointerPressedEventArgs e) private void MouseClick(object sender, PointerPressedEventArgs e)
{ {
bool shouldUnbind = e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed; bool shouldUnbind = e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed;
bool shouldRemoveBinding = e.GetCurrentPoint(this).Properties.IsRightButtonPressed;
if (shouldRemoveBinding)
{
DeleteBind();
}
_currentAssigner?.Cancel(shouldUnbind); _currentAssigner?.Cancel(shouldUnbind);
PointerPressed -= MouseClick; PointerPressed -= MouseClick;
} }
private void DeleteBind()
{
if (DataContext is not KeyboardInputViewModel viewModel)
return;
if (_currentAssigner != null)
{
Dictionary<string, Action> buttonActions = new Dictionary<string, Action>
{
{ "ButtonZl", () => viewModel.Config.ButtonZl = Key.Unbound },
{ "ButtonL", () => viewModel.Config.ButtonL = Key.Unbound },
{ "ButtonMinus", () => viewModel.Config.ButtonMinus = Key.Unbound },
{ "LeftStickButton", () => viewModel.Config.LeftStickButton = Key.Unbound },
{ "LeftStickUp", () => viewModel.Config.LeftStickUp = Key.Unbound },
{ "LeftStickDown", () => viewModel.Config.LeftStickDown = Key.Unbound },
{ "LeftStickRight", () => viewModel.Config.LeftStickRight = Key.Unbound },
{ "LeftStickLeft", () => viewModel.Config.LeftStickLeft = Key.Unbound },
{ "DpadUp", () => viewModel.Config.DpadUp = Key.Unbound },
{ "DpadDown", () => viewModel.Config.DpadDown = Key.Unbound },
{ "DpadLeft", () => viewModel.Config.DpadLeft = Key.Unbound },
{ "DpadRight", () => viewModel.Config.DpadRight = Key.Unbound },
{ "LeftButtonSr", () => viewModel.Config.LeftButtonSr = Key.Unbound },
{ "LeftButtonSl", () => viewModel.Config.LeftButtonSl = Key.Unbound },
{ "RightButtonSr", () => viewModel.Config.RightButtonSr = Key.Unbound },
{ "RightButtonSl", () => viewModel.Config.RightButtonSl = Key.Unbound },
{ "ButtonZr", () => viewModel.Config.ButtonZr = Key.Unbound },
{ "ButtonR", () => viewModel.Config.ButtonR = Key.Unbound },
{ "ButtonPlus", () => viewModel.Config.ButtonPlus = Key.Unbound },
{ "ButtonA", () => viewModel.Config.ButtonA = Key.Unbound },
{ "ButtonB", () => viewModel.Config.ButtonB = Key.Unbound },
{ "ButtonX", () => viewModel.Config.ButtonX = Key.Unbound },
{ "ButtonY", () => viewModel.Config.ButtonY = Key.Unbound },
{ "RightStickButton", () => viewModel.Config.RightStickButton = Key.Unbound },
{ "RightStickUp", () => viewModel.Config.RightStickUp = Key.Unbound },
{ "RightStickDown", () => viewModel.Config.RightStickDown = Key.Unbound },
{ "RightStickRight", () => viewModel.Config.RightStickRight = Key.Unbound },
{ "RightStickLeft", () => viewModel.Config.RightStickLeft = Key.Unbound }
};
if (buttonActions.TryGetValue(_currentAssigner.ToggledButton.Name, out Action action))
{
action();
FlagInputConfigChanged();
}
}
}
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e) protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
{ {
base.OnDetachedFromVisualTree(e); base.OnDetachedFromVisualTree(e);

View File

@@ -1,4 +1,5 @@
using Avalonia; using Avalonia;
using Avalonia.Controls;
using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.Controls;

View File

@@ -1,3 +1,4 @@
using Avalonia.Controls;
using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.Controls;

View File

@@ -1,3 +1,4 @@
using Avalonia.Controls;
using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.Controls;

View File

@@ -6,16 +6,18 @@
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup" xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
mc:Ignorable="d" mc:Ignorable="d"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels" xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
x:DataType="viewModels:MainWindowViewModel" x:DataType="viewModels:MainWindowViewModel"
x:Class="Ryujinx.Ava.UI.Views.Main.MainMenuBarView"> x:Class="Ryujinx.Ava.UI.Views.Main.MainMenuBarView">
<Design.DataContext> <Design.DataContext>
<viewModels:MainWindowViewModel /> <viewModels:MainWindowViewModel />
</Design.DataContext> </Design.DataContext>
<DockPanel HorizontalAlignment="Stretch"> <DockPanel HorizontalAlignment="Stretch">
<controls:RyujinxLogo <Image
Margin="7, 0" Name="RyuLogo"
ToolTip.Tip="{Binding Title}"/> Margin="7, 0"
Height="25"
Width="25"
ToolTip.Tip="{Binding Title}" />
<Menu <Menu
Name="Menu" Name="Menu"
Height="32" Height="32"

View File

@@ -13,7 +13,7 @@ using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.UI.Views.Dialog; using Ryujinx.Ava.UI.Views.Misc;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Helper; using Ryujinx.Common.Helper;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
@@ -34,6 +34,9 @@ namespace Ryujinx.Ava.UI.Views.Main
{ {
InitializeComponent(); InitializeComponent();
RyuLogo.IsVisible = !ConfigurationState.Instance.ShowTitleBar;
RyuLogo.Source = MainWindowViewModel.IconBitmap;
ToggleFileTypesMenuItem.ItemsSource = GenerateToggleFileTypeItems(); ToggleFileTypesMenuItem.ItemsSource = GenerateToggleFileTypeItems();
ChangeLanguageMenuItem.ItemsSource = GenerateLanguageMenuItems(); ChangeLanguageMenuItem.ItemsSource = GenerateLanguageMenuItems();
@@ -46,8 +49,8 @@ namespace Ryujinx.Ava.UI.Views.Main
CheatManagerMenuItem.Command = Commands.CreateSilentFail(OpenCheatManagerForCurrentApp); CheatManagerMenuItem.Command = Commands.CreateSilentFail(OpenCheatManagerForCurrentApp);
InstallFileTypesMenuItem.Command = Commands.Create(InstallFileTypes); InstallFileTypesMenuItem.Command = Commands.Create(InstallFileTypes);
UninstallFileTypesMenuItem.Command = Commands.Create(UninstallFileTypes); UninstallFileTypesMenuItem.Command = Commands.Create(UninstallFileTypes);
XciTrimmerMenuItem.Command = Commands.Create(XciTrimmerView.Show); XciTrimmerMenuItem.Command = Commands.Create(XCITrimmerWindow.Show);
AboutWindowMenuItem.Command = Commands.Create(AboutView.Show); AboutWindowMenuItem.Command = Commands.Create(AboutWindow.Show);
CompatibilityListMenuItem.Command = Commands.Create(() => CompatibilityListWindow.Show()); CompatibilityListMenuItem.Command = Commands.Create(() => CompatibilityListWindow.Show());
UpdateMenuItem.Command = MainWindowViewModel.UpdateCommand; UpdateMenuItem.Command = MainWindowViewModel.UpdateCommand;
@@ -223,7 +226,7 @@ namespace Ryujinx.Ava.UI.Views.Main
// Correctly size window when 'TitleBar' is enabled (Nov. 14, 2024) // Correctly size window when 'TitleBar' is enabled (Nov. 14, 2024)
double barsHeight = ((Window.StatusBarHeight + Window.MenuBarHeight) + double barsHeight = ((Window.StatusBarHeight + Window.MenuBarHeight) +
(ConfigurationState.Instance.ShowOldUI ? (int)Window.TitleBar.Height : 0)); (ConfigurationState.Instance.ShowTitleBar ? (int)Window.TitleBar.Height : 0));
double windowWidthScaled = (resolutionWidth * Program.WindowScaleFactor); double windowWidthScaled = (resolutionWidth * Program.WindowScaleFactor);
double windowHeightScaled = ((resolutionHeight + barsHeight) * Program.WindowScaleFactor); double windowHeightScaled = ((resolutionHeight + barsHeight) * Program.WindowScaleFactor);

View File

@@ -1,4 +1,5 @@
using Avalonia; using Avalonia;
using Avalonia.Controls;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Threading; using Avalonia.Threading;

View File

@@ -7,7 +7,7 @@
xmlns:ui="using:FluentAvalonia.UI.Controls" xmlns:ui="using:FluentAvalonia.UI.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Ryujinx.Ava.UI.Views.Dialog.ApplicationDataView" x:Class="Ryujinx.Ava.UI.Views.Misc.ApplicationDataView"
x:DataType="viewModels:ApplicationDataViewModel"> x:DataType="viewModels:ApplicationDataViewModel">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<Image Margin="0" <Image Margin="0"

View File

@@ -12,7 +12,7 @@ using Ryujinx.Ava.Systems.AppLibrary;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Views.Dialog namespace Ryujinx.Ava.UI.Views.Misc
{ {
public partial class ApplicationDataView : RyujinxControl<ApplicationDataViewModel> public partial class ApplicationDataView : RyujinxControl<ApplicationDataViewModel>
{ {

View File

@@ -7,7 +7,7 @@
xmlns:models="using:Ryujinx.Ava.Common.Models" xmlns:models="using:Ryujinx.Ava.Common.Models"
xmlns:viewModels="using:Ryujinx.Ava.UI.ViewModels" xmlns:viewModels="using:Ryujinx.Ava.UI.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Ryujinx.Ava.UI.Views.Dialog.DlcSelectView" x:Class="Ryujinx.Ava.UI.Views.Misc.DlcSelectView"
x:DataType="viewModels:DlcSelectViewModel"> x:DataType="viewModels:DlcSelectViewModel">
<Grid RowDefinitions="*,Auto,*"> <Grid RowDefinitions="*,Auto,*">
<TextBlock <TextBlock

View File

@@ -1,4 +1,6 @@
using FluentAvalonia.UI.Controls; using Avalonia.Controls;
using Avalonia.Styling;
using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Common.Models; using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.Controls;
@@ -7,7 +9,7 @@ using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Systems.AppLibrary;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Views.Dialog namespace Ryujinx.Ava.UI.Views.Misc
{ {
public partial class DlcSelectView : RyujinxControl<DlcSelectViewModel> public partial class DlcSelectView : RyujinxControl<DlcSelectViewModel>
{ {

View File

@@ -29,7 +29,7 @@
<TextBlock <TextBlock
Foreground="{DynamicResource SecondaryTextColor}" Foreground="{DynamicResource SecondaryTextColor}"
TextDecorations="Underline" TextDecorations="Underline"
Text="Highly specific hacks &amp; tricks to alleviate performance issues, crashing, or freezing. Can cause issues." /> Text="Highly specific hacks &amp; tricks to alleviate performance issues, crashing, or freezing. Will cause issues." />
<StackPanel <StackPanel
Margin="0,10,0,0" Margin="0,10,0,0"
Orientation="Horizontal" Orientation="Horizontal"
@@ -43,18 +43,6 @@
Text="Xenoblade Chronicles 2 Menu Softlock Fix" /> Text="Xenoblade Chronicles 2 Menu Softlock Fix" />
</StackPanel> </StackPanel>
<Separator/> <Separator/>
<StackPanel
Margin="0,10,0,0"
Orientation="Horizontal"
HorizontalAlignment="Center"
ToolTip.Tip="{Binding DirtyHacks.NifmDisableIsAnyInternetRequestAcceptedTooltip}">
<CheckBox
Margin="0"
IsChecked="{Binding DirtyHacks.NifmDisableIsAnyInternetRequestAccepted}"/>
<TextBlock
VerticalAlignment="Center"
Text="Disable IsAnyInternetRequestAccepted" />
</StackPanel>
</StackPanel> </StackPanel>
</Border> </Border>
</ScrollViewer> </ScrollViewer>

View File

@@ -3,19 +3,19 @@ using Avalonia.Controls.Primitives;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.LogicalTree; using Avalonia.LogicalTree;
using Avalonia.Threading;
using Ryujinx.Ava.Input; using Ryujinx.Ava.Input;
using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Input; using Ryujinx.Input;
using Ryujinx.Input.Assigner; using Ryujinx.Input.Assigner;
using System.Collections.Generic;
using System;
using Button = Ryujinx.Input.Button; using Button = Ryujinx.Input.Button;
using Key = Ryujinx.Common.Configuration.Hid.Key; using Key = Ryujinx.Common.Configuration.Hid.Key;
namespace Ryujinx.Ava.UI.Views.Settings namespace Ryujinx.Ava.UI.Views.Settings
{ {
public partial class SettingsHotkeysView : RyujinxControl<SettingsViewModel> public partial class SettingsHotkeysView : UserControl
{ {
private ButtonKeyAssigner _currentAssigner; private ButtonKeyAssigner _currentAssigner;
private readonly IGamepadDriver _avaloniaKeyboardDriver; private readonly IGamepadDriver _avaloniaKeyboardDriver;
@@ -48,12 +48,47 @@ namespace Ryujinx.Ava.UI.Views.Settings
private void MouseClick(object sender, PointerPressedEventArgs e) private void MouseClick(object sender, PointerPressedEventArgs e)
{ {
bool shouldUnbind = e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed; bool shouldUnbind = e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed;
bool shouldRemoveBinding = e.GetCurrentPoint(this).Properties.IsRightButtonPressed;
if (shouldRemoveBinding)
{
DeleteBind();
}
_currentAssigner?.Cancel(shouldUnbind); _currentAssigner?.Cancel(shouldUnbind);
PointerPressed -= MouseClick; PointerPressed -= MouseClick;
} }
private void DeleteBind()
{
if (DataContext is not SettingsViewModel viewModel)
return;
if (_currentAssigner != null)
{
Dictionary<string, Action> buttonActions = new Dictionary<string, Action>
{
{ "ToggleVSyncMode", () => viewModel.KeyboardHotkey.ToggleVSyncMode = Key.Unbound },
{ "Screenshot", () => viewModel.KeyboardHotkey.Screenshot = Key.Unbound },
{ "ShowUI", () => viewModel.KeyboardHotkey.ShowUI = Key.Unbound },
{ "Pause", () => viewModel.KeyboardHotkey.Pause = Key.Unbound },
{ "ToggleMute", () => viewModel.KeyboardHotkey.ToggleMute = Key.Unbound },
{ "ResScaleUp", () => viewModel.KeyboardHotkey.ResScaleUp = Key.Unbound },
{ "ResScaleDown", () => viewModel.KeyboardHotkey.ResScaleDown = Key.Unbound },
{ "VolumeUp", () => viewModel.KeyboardHotkey.VolumeUp = Key.Unbound },
{ "VolumeDown", () => viewModel.KeyboardHotkey.VolumeDown = Key.Unbound },
{ "CustomVSyncIntervalIncrement", () => viewModel.KeyboardHotkey.CustomVSyncIntervalIncrement = Key.Unbound },
{ "CustomVSyncIntervalDecrement", () => viewModel.KeyboardHotkey.CustomVSyncIntervalDecrement = Key.Unbound }
};
if (buttonActions.TryGetValue(_currentAssigner.ToggledButton.Name, out Action action))
{
action();
}
}
}
private void Button_IsCheckedChanged(object sender, RoutedEventArgs e) private void Button_IsCheckedChanged(object sender, RoutedEventArgs e)
{ {
if (sender is ToggleButton button) if (sender is ToggleButton button)
@@ -80,49 +115,45 @@ namespace Ryujinx.Ava.UI.Views.Settings
{ {
if (e.ButtonValue.HasValue) if (e.ButtonValue.HasValue)
{ {
SettingsViewModel viewModel = (DataContext) as SettingsViewModel;
Button buttonValue = e.ButtonValue.Value; Button buttonValue = e.ButtonValue.Value;
Dispatcher.UIThread.Post(() => switch (button.Name)
{ {
switch (button.Name) case "ToggleVSyncMode":
{ viewModel.KeyboardHotkey.ToggleVSyncMode = buttonValue.AsHidType<Key>();
case "ToggleVSyncMode": break;
ViewModel.KeyboardHotkey.ToggleVSyncMode = buttonValue.AsHidType<Key>(); case "Screenshot":
break; viewModel.KeyboardHotkey.Screenshot = buttonValue.AsHidType<Key>();
case "Screenshot": break;
ViewModel.KeyboardHotkey.Screenshot = buttonValue.AsHidType<Key>(); case "ShowUI":
break; viewModel.KeyboardHotkey.ShowUI = buttonValue.AsHidType<Key>();
case "ShowUI": break;
ViewModel.KeyboardHotkey.ShowUI = buttonValue.AsHidType<Key>(); case "Pause":
break; viewModel.KeyboardHotkey.Pause = buttonValue.AsHidType<Key>();
case "Pause": break;
ViewModel.KeyboardHotkey.Pause = buttonValue.AsHidType<Key>(); case "ToggleMute":
break; viewModel.KeyboardHotkey.ToggleMute = buttonValue.AsHidType<Key>();
case "ToggleMute": break;
ViewModel.KeyboardHotkey.ToggleMute = buttonValue.AsHidType<Key>(); case "ResScaleUp":
break; viewModel.KeyboardHotkey.ResScaleUp = buttonValue.AsHidType<Key>();
case "ResScaleUp": break;
ViewModel.KeyboardHotkey.ResScaleUp = buttonValue.AsHidType<Key>(); case "ResScaleDown":
break; viewModel.KeyboardHotkey.ResScaleDown = buttonValue.AsHidType<Key>();
case "ResScaleDown": break;
ViewModel.KeyboardHotkey.ResScaleDown = buttonValue.AsHidType<Key>(); case "VolumeUp":
break; viewModel.KeyboardHotkey.VolumeUp = buttonValue.AsHidType<Key>();
case "VolumeUp": break;
ViewModel.KeyboardHotkey.VolumeUp = buttonValue.AsHidType<Key>(); case "VolumeDown":
break; viewModel.KeyboardHotkey.VolumeDown = buttonValue.AsHidType<Key>();
case "VolumeDown": break;
ViewModel.KeyboardHotkey.VolumeDown = buttonValue.AsHidType<Key>(); case "CustomVSyncIntervalIncrement":
break; viewModel.KeyboardHotkey.CustomVSyncIntervalIncrement = buttonValue.AsHidType<Key>();
case "CustomVSyncIntervalIncrement": break;
ViewModel.KeyboardHotkey.CustomVSyncIntervalIncrement = case "CustomVSyncIntervalDecrement":
buttonValue.AsHidType<Key>(); viewModel.KeyboardHotkey.CustomVSyncIntervalDecrement = buttonValue.AsHidType<Key>();
break; break;
case "CustomVSyncIntervalDecrement": }
ViewModel.KeyboardHotkey.CustomVSyncIntervalDecrement =
buttonValue.AsHidType<Key>();
break;
}
});
} }
}; };

View File

@@ -1,13 +1,15 @@
using Avalonia.Controls;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using System; using System;
namespace Ryujinx.Ava.UI.Views.Settings namespace Ryujinx.Ava.UI.Views.Settings
{ {
public partial class SettingsNetworkView : RyujinxControl<SettingsViewModel> public partial class SettingsNetworkView : UserControl
{ {
private readonly Random _random; private readonly Random _random;
public SettingsViewModel ViewModel;
public SettingsNetworkView() public SettingsNetworkView()
{ {

View File

@@ -191,16 +191,16 @@
IsEnabled="{Binding !IsGameTitleNotNull}" IsEnabled="{Binding !IsGameTitleNotNull}"
Opacity="{Binding PanelOpacity}" Opacity="{Binding PanelOpacity}"
Orientation="Horizontal"> Orientation="Horizontal">
<TextBlock
VerticalAlignment="Center"
Text="{ext:Locale SettingsTabSystemSystemTimeMatch}"
ToolTip.Tip="{ext:Locale MatchTimeTooltip}"
Width="250"/>
<CheckBox <CheckBox
VerticalAlignment="Center" VerticalAlignment="Center"
IsChecked="{Binding MatchSystemTime}" IsChecked="{Binding MatchSystemTime}"
ToolTip.Tip="{ext:Locale MatchTimeTooltip}"> ToolTip.Tip="{ext:Locale MatchTimeTooltip}"/>
<TextBlock <TextBlock Classes="globalConfigMarker" IsVisible="{Binding IsGameTitleNotNull}"/>
VerticalAlignment="Center"
Text="{ext:Locale SettingsTabSystemSystemTimeMatch}"
Width="250"/>
</CheckBox>
<TextBlock Classes="globalConfigMarker" IsVisible="{Binding IsGameTitleNotNull}"/>
</StackPanel> </StackPanel>
<Separator /> <Separator />
<StackPanel Margin="0,10,0,10" <StackPanel Margin="0,10,0,10"

View File

@@ -1,12 +1,13 @@
using Avalonia.Controls; using Avalonia.Controls;
using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using TimeZone = Ryujinx.Ava.UI.Models.TimeZone; using TimeZone = Ryujinx.Ava.UI.Models.TimeZone;
namespace Ryujinx.Ava.UI.Views.Settings namespace Ryujinx.Ava.UI.Views.Settings
{ {
public partial class SettingsSystemView : RyujinxControl<SettingsViewModel> public partial class SettingsSystemView : UserControl
{ {
public SettingsViewModel ViewModel;
public SettingsSystemView() public SettingsSystemView()
{ {
InitializeComponent(); InitializeComponent();

View File

@@ -6,6 +6,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup" xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels" xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
xmlns:helper="clr-namespace:Ryujinx.Common.Helper;assembly=Ryujinx.Common"
mc:Ignorable="d" mc:Ignorable="d"
x:DataType="viewModels:SettingsViewModel"> x:DataType="viewModels:SettingsViewModel">
<Design.DataContext> <Design.DataContext>
@@ -18,265 +19,245 @@
HorizontalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto"> VerticalScrollBarVisibility="Auto">
<Border Classes="settings"> <Border Classes="settings">
<Grid ColumnDefinitions="Auto,Auto,*" HorizontalAlignment="Stretch"> <StackPanel
Margin="10"
HorizontalAlignment="Stretch"
Orientation="Vertical"
Spacing="10">
<TextBlock Classes="h1" Text="{ext:Locale SettingsTabGeneralGeneral}" />
<StackPanel Margin="10,0,0,0" Orientation="Vertical">
<CheckBox IsChecked="{Binding EnableDiscordIntegration}">
<StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center"
ToolTip.Tip="{ext:Locale ToggleDiscordTooltip}"
Text="{ext:Locale SettingsTabGeneralEnableDiscordRichPresence}" />
</StackPanel>
</CheckBox>
<CheckBox
IsEnabled="{Binding !IsGameTitleNotNull}"
Opacity="{Binding PanelOpacity}"
IsChecked="{Binding ShowConfirmExit}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{ext:Locale SettingsTabGeneralShowConfirmExitDialog}" />
<TextBlock Classes="globalConfigMarker" IsVisible="{Binding IsGameTitleNotNull}" />
</StackPanel>
</CheckBox>
<CheckBox
IsEnabled="{Binding !IsGameTitleNotNull}"
Opacity="{Binding PanelOpacity}"
IsChecked="{Binding RememberWindowState}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{ext:Locale SettingsTabGeneralRememberWindowState}" />
<TextBlock Classes="globalConfigMarker" IsVisible="{Binding IsGameTitleNotNull}" />
</StackPanel>
</CheckBox>
<CheckBox
IsEnabled="{Binding !IsGameTitleNotNull}"
Opacity="{Binding PanelOpacity}"
IsChecked="{Binding ShowTitleBar}" IsVisible="{x:Static helper:RunningPlatform.IsWindows}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{ext:Locale SettingsTabGeneralShowTitleBar}" />
<TextBlock Classes="globalConfigMarker" IsVisible="{Binding IsGameTitleNotNull}" />
</StackPanel>
</CheckBox>
<StackPanel
Margin="0, 15, 0, 0"
Orientation="Horizontal">
<TextBlock VerticalAlignment="Center"
Text="{ext:Locale SettingsTabGeneralFocusLossType}"
Width="150" />
<ComboBox SelectedIndex="{Binding FocusLostActionType}"
HorizontalContentAlignment="Left"
MinWidth="100">
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralFocusLossTypeDoNothing}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralFocusLossTypeBlockInput}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralFocusLossTypeMuteAudio}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralFocusLossTypeBlockInputAndMuteAudio}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralFocusLossTypePauseEmulation}" />
</ComboBoxItem>
</ComboBox>
</StackPanel>
<StackPanel
IsEnabled="{Binding !IsGameTitleNotNull}"
Opacity="{Binding PanelOpacity}"
Margin="0, 15, 0, 0"
Orientation="Horizontal">
<TextBlock VerticalAlignment="Center"
Text="{ext:Locale SettingsTabGeneralCheckUpdatesOnLaunch}"
Width="150" />
<ComboBox SelectedIndex="{Binding UpdateCheckerType}"
HorizontalContentAlignment="Left"
MinWidth="100">
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralCheckUpdatesOnLaunchOff}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralCheckUpdatesOnLaunchPromptAtStartup}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralCheckUpdatesOnLaunchBackground}" />
</ComboBoxItem>
</ComboBox>
<TextBlock Classes="globalConfigMarker" IsVisible="{Binding IsGameTitleNotNull}"/>
</StackPanel>
<StackPanel
Margin="0, 15, 0, 0"
Orientation="Horizontal">
<TextBlock VerticalAlignment="Center"
Text="{ext:Locale SettingsTabGeneralHideCursor}"
Width="150" />
<ComboBox SelectedIndex="{Binding HideCursor}"
HorizontalContentAlignment="Left"
MinWidth="100">
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralHideCursorNever}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralHideCursorOnIdle}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralHideCursorAlways}" />
</ComboBoxItem>
</ComboBox>
</StackPanel>
<StackPanel
IsEnabled="{Binding !IsGameTitleNotNull}"
Opacity="{Binding PanelOpacity}"
Margin="0, 15, 0, 10"
Orientation="Horizontal">
<TextBlock
VerticalAlignment="Center"
Text="{ext:Locale SettingsTabGeneralTheme}"
Width="150" />
<ComboBox SelectedIndex="{Binding BaseStyleIndex}"
HorizontalContentAlignment="Left"
MinWidth="100">
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralThemeAuto}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralThemeLight}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralThemeDark}" />
</ComboBoxItem>
</ComboBox>
<TextBlock Classes="globalConfigMarker" IsVisible="{Binding IsGameTitleNotNull}"/>
</StackPanel>
</StackPanel>
<Separator Height="1" />
<StackPanel Orientation="Horizontal">
<TextBlock Classes="h1" Text="{ext:Locale SettingsTabGeneralGameDirectories}" />
<TextBlock Classes="globalConfigMarker" IsVisible="{Binding IsGameTitleNotNull}"/>
</StackPanel>
<StackPanel <StackPanel
Grid.Column="0" IsEnabled="{Binding !IsGameTitleNotNull}"
Margin="10" Opacity="{Binding PanelOpacity}"
Margin="10,0,0,0"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
Orientation="Vertical" Orientation="Vertical"
Spacing="10"> Spacing="10">
<TextBlock Classes="h1" Text="{ext:Locale SettingsTabGeneralGeneral}" /> <ListBox
<StackPanel Margin="10,0,0,0" Orientation="Vertical"> Name="GameDirsList"
<CheckBox IsChecked="{Binding EnableDiscordIntegration}"> MinHeight="120"
<StackPanel Orientation="Horizontal"> ItemsSource="{Binding GameDirectories}">
<TextBlock VerticalAlignment="Center" <ListBox.Styles>
ToolTip.Tip="{ext:Locale ToggleDiscordTooltip}" <Style Selector="ListBoxItem">
Text="{ext:Locale SettingsTabGeneralEnableDiscordRichPresence}" /> <Setter Property="Padding" Value="10" />
</StackPanel> <Setter Property="Background" Value="{DynamicResource ListBoxBackground}" />
</CheckBox> </Style>
<CheckBox </ListBox.Styles>
IsEnabled="{Binding !IsGameTitleNotNull}" </ListBox>
Opacity="{Binding PanelOpacity}" <Grid HorizontalAlignment="Stretch" ColumnDefinitions="*,Auto,Auto">
IsChecked="{Binding ShowConfirmExit}"> <TextBox
<StackPanel Orientation="Horizontal"> Name="GameDirPathBox"
<TextBlock Text="{ext:Locale SettingsTabGeneralShowConfirmExitDialog}" /> Margin="0"
<TextBlock Classes="globalConfigMarker" IsVisible="{Binding IsGameTitleNotNull}" /> ToolTip.Tip="{ext:Locale AddGameDirBoxTooltip}"
</StackPanel> VerticalAlignment="Stretch" />
</CheckBox> <Button
<CheckBox Name="AddGameDirButton"
IsEnabled="{Binding !IsGameTitleNotNull}" Grid.Column="1"
Opacity="{Binding PanelOpacity}" MinWidth="90"
IsChecked="{Binding RememberWindowState}"> Margin="10,0,0,0"
<StackPanel Orientation="Horizontal"> ToolTip.Tip="{ext:Locale AddGameDirTooltip}">
<TextBlock Text="{ext:Locale SettingsTabGeneralRememberWindowState}" /> <TextBlock HorizontalAlignment="Center"
<TextBlock Classes="globalConfigMarker" IsVisible="{Binding IsGameTitleNotNull}" /> Text="{ext:Locale SettingsTabGeneralAdd}" />
</StackPanel> </Button>
</CheckBox> <Button
<CheckBox Name="RemoveGameDirButton"
IsEnabled="{Binding !IsGameTitleNotNull}" Grid.Column="2"
Opacity="{Binding PanelOpacity}" MinWidth="90"
IsChecked="{Binding ShowOldUI}" Margin="10,0,0,0"
ToolTip.Tip="{ext:Locale SettingsTabGeneralShowOldUIToolTip}"> ToolTip.Tip="{ext:Locale RemoveGameDirTooltip}"
<StackPanel Orientation="Horizontal"> Click="RemoveGameDirButton_OnClick">
<TextBlock Text="{ext:Locale SettingsTabGeneralShowOldUI}" /> <TextBlock HorizontalAlignment="Center"
<TextBlock Classes="globalConfigMarker" IsVisible="{Binding IsGameTitleNotNull}" /> Text="{ext:Locale SettingsTabGeneralRemove}" />
</StackPanel> </Button>
</CheckBox> </Grid>
<StackPanel
Margin="0, 15, 0, 0"
Orientation="Horizontal">
<TextBlock VerticalAlignment="Center"
Text="{ext:Locale SettingsTabGeneralFocusLossType}"
Width="150" />
<ComboBox SelectedIndex="{Binding FocusLostActionType}"
HorizontalContentAlignment="Left"
MinWidth="100">
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralFocusLossTypeDoNothing}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralFocusLossTypeBlockInput}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralFocusLossTypeMuteAudio}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock
Text="{ext:Locale SettingsTabGeneralFocusLossTypeBlockInputAndMuteAudio}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralFocusLossTypePauseEmulation}" />
</ComboBoxItem>
</ComboBox>
</StackPanel>
<StackPanel
IsEnabled="{Binding !IsGameTitleNotNull}"
Opacity="{Binding PanelOpacity}"
Margin="0, 15, 0, 0"
Orientation="Horizontal">
<TextBlock VerticalAlignment="Center"
Text="{ext:Locale SettingsTabGeneralCheckUpdatesOnLaunch}"
Width="150" />
<ComboBox SelectedIndex="{Binding UpdateCheckerType}"
HorizontalContentAlignment="Left"
MinWidth="100">
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralCheckUpdatesOnLaunchOff}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock
Text="{ext:Locale SettingsTabGeneralCheckUpdatesOnLaunchPromptAtStartup}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralCheckUpdatesOnLaunchBackground}" />
</ComboBoxItem>
</ComboBox>
<TextBlock Classes="globalConfigMarker" IsVisible="{Binding IsGameTitleNotNull}" />
</StackPanel>
<StackPanel
Margin="0, 15, 0, 0"
Orientation="Horizontal">
<TextBlock VerticalAlignment="Center"
Text="{ext:Locale SettingsTabGeneralHideCursor}"
Width="150" />
<ComboBox SelectedIndex="{Binding HideCursor}"
HorizontalContentAlignment="Left"
MinWidth="100">
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralHideCursorNever}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralHideCursorOnIdle}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralHideCursorAlways}" />
</ComboBoxItem>
</ComboBox>
</StackPanel>
<StackPanel
IsEnabled="{Binding !IsGameTitleNotNull}"
Opacity="{Binding PanelOpacity}"
Margin="0, 15, 0, 10"
Orientation="Horizontal">
<TextBlock
VerticalAlignment="Center"
Text="{ext:Locale SettingsTabGeneralTheme}"
Width="150" />
<ComboBox SelectedIndex="{Binding BaseStyleIndex}"
HorizontalContentAlignment="Left"
MinWidth="100">
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralThemeAuto}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralThemeLight}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralThemeDark}" />
</ComboBoxItem>
</ComboBox>
<TextBlock Classes="globalConfigMarker" IsVisible="{Binding IsGameTitleNotNull}" />
</StackPanel>
</StackPanel>
</StackPanel> </StackPanel>
<Border Grid.Column="1" <Separator Height="1" />
HorizontalAlignment="Center" <StackPanel Orientation="Vertical" Spacing="5">
VerticalAlignment="Top"
Margin="10, 10, 10, 0"
Height="405"
BorderBrush="Gray"
Background="Gray"
Width="1" />
<StackPanel
Margin="10"
Spacing="10"
Grid.Column="2"
Orientation="Vertical" HorizontalAlignment="Stretch">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBlock Classes="h1" Text="{ext:Locale SettingsTabGeneralGameDirectories}" /> <TextBlock Classes="h1" Text="{ext:Locale SettingsTabGeneralAutoloadDirectories}" />
<TextBlock Classes="globalConfigMarker" IsVisible="{Binding IsGameTitleNotNull}" /> <TextBlock Classes="globalConfigMarker" IsVisible="{Binding IsGameTitleNotNull}"/>
</StackPanel>
<StackPanel
IsEnabled="{Binding !IsGameTitleNotNull}"
Opacity="{Binding PanelOpacity}"
Margin="10,0,0,0"
HorizontalAlignment="Stretch"
Orientation="Vertical"
Spacing="10">
<ListBox
Name="GameDirsList"
MinHeight="120"
ItemsSource="{Binding GameDirectories}">
<ListBox.Styles>
<Style Selector="ListBoxItem">
<Setter Property="Padding" Value="10" />
<Setter Property="Background" Value="{DynamicResource ListBoxBackground}" />
</Style>
</ListBox.Styles>
</ListBox>
<Grid HorizontalAlignment="Stretch" ColumnDefinitions="*,Auto,Auto">
<TextBox
Name="GameDirPathBox"
Margin="0"
ToolTip.Tip="{ext:Locale AddGameDirBoxTooltip}"
VerticalAlignment="Stretch" />
<Button
Name="AddGameDirButton"
Grid.Column="1"
MinWidth="90"
Margin="10,0,0,0"
ToolTip.Tip="{ext:Locale AddGameDirTooltip}">
<TextBlock HorizontalAlignment="Center"
Text="{ext:Locale SettingsTabGeneralAdd}" />
</Button>
<Button
Name="RemoveGameDirButton"
Grid.Column="2"
MinWidth="90"
Margin="10,0,0,0"
ToolTip.Tip="{ext:Locale RemoveGameDirTooltip}"
Click="RemoveGameDirButton_OnClick">
<TextBlock HorizontalAlignment="Center"
Text="{ext:Locale SettingsTabGeneralRemove}" />
</Button>
</Grid>
</StackPanel>
<Separator Height="1" />
<StackPanel Orientation="Vertical" Spacing="5">
<StackPanel Orientation="Horizontal">
<TextBlock Classes="h1" Text="{ext:Locale SettingsTabGeneralAutoloadDirectories}" />
<TextBlock Classes="globalConfigMarker" IsVisible="{Binding IsGameTitleNotNull}" />
</StackPanel>
<TextBlock Foreground="{DynamicResource SecondaryTextColor}"
Text="{ext:Locale SettingsTabGeneralAutoloadNote}" />
</StackPanel>
<StackPanel
IsEnabled="{Binding !IsGameTitleNotNull}"
Opacity="{Binding PanelOpacity}"
Margin="10,0,0,0"
HorizontalAlignment="Stretch"
Orientation="Vertical"
Spacing="10">
<ListBox
Name="AutoloadDirsList"
MinHeight="100"
ItemsSource="{Binding AutoloadDirectories}">
<ListBox.Styles>
<Style Selector="ListBoxItem">
<Setter Property="Padding" Value="10" />
<Setter Property="Background" Value="{DynamicResource ListBoxBackground}" />
</Style>
</ListBox.Styles>
</ListBox>
<Grid HorizontalAlignment="Stretch" ColumnDefinitions="*,Auto,Auto">
<TextBox
Name="AutoloadDirPathBox"
Margin="0"
ToolTip.Tip="{ext:Locale AddAutoloadDirBoxTooltip}"
VerticalAlignment="Stretch" />
<Button
Name="AddAutoloadDirButton"
Grid.Column="1"
MinWidth="90"
Margin="10,0,0,0"
ToolTip.Tip="{ext:Locale AddAutoloadDirTooltip}">
<TextBlock HorizontalAlignment="Center"
Text="{ext:Locale SettingsTabGeneralAdd}" />
</Button>
<Button
Name="RemoveAutoloadDirButton"
Grid.Column="2"
MinWidth="90"
Margin="10,0,0,0"
ToolTip.Tip="{ext:Locale RemoveAutoloadDirTooltip}"
Click="RemoveAutoloadDirButton_OnClick">
<TextBlock HorizontalAlignment="Center"
Text="{ext:Locale SettingsTabGeneralRemove}" />
</Button>
</Grid>
</StackPanel> </StackPanel>
<TextBlock Foreground="{DynamicResource SecondaryTextColor}" Text="{ext:Locale SettingsTabGeneralAutoloadNote}" />
</StackPanel> </StackPanel>
</Grid> <StackPanel
IsEnabled="{Binding !IsGameTitleNotNull}"
Opacity="{Binding PanelOpacity}"
Margin="10,0,0,0"
HorizontalAlignment="Stretch"
Orientation="Vertical"
Spacing="10">
<ListBox
Name="AutoloadDirsList"
MinHeight="100"
ItemsSource="{Binding AutoloadDirectories}">
<ListBox.Styles>
<Style Selector="ListBoxItem">
<Setter Property="Padding" Value="10" />
<Setter Property="Background" Value="{DynamicResource ListBoxBackground}" />
</Style>
</ListBox.Styles>
</ListBox>
<Grid HorizontalAlignment="Stretch" ColumnDefinitions="*,Auto,Auto">
<TextBox
Name="AutoloadDirPathBox"
Margin="0"
ToolTip.Tip="{ext:Locale AddAutoloadDirBoxTooltip}"
VerticalAlignment="Stretch" />
<Button
Name="AddAutoloadDirButton"
Grid.Column="1"
MinWidth="90"
Margin="10,0,0,0"
ToolTip.Tip="{ext:Locale AddAutoloadDirTooltip}">
<TextBlock HorizontalAlignment="Center"
Text="{ext:Locale SettingsTabGeneralAdd}" />
</Button>
<Button
Name="RemoveAutoloadDirButton"
Grid.Column="2"
MinWidth="90"
Margin="10,0,0,0"
ToolTip.Tip="{ext:Locale RemoveAutoloadDirTooltip}"
Click="RemoveAutoloadDirButton_OnClick">
<TextBlock HorizontalAlignment="Center"
Text="{ext:Locale SettingsTabGeneralRemove}" />
</Button>
</Grid>
</StackPanel>
</StackPanel>
</Border> </Border>
</ScrollViewer> </ScrollViewer>
</UserControl> </UserControl>

View File

@@ -3,10 +3,10 @@ using Avalonia.Controls;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Platform.Storage; using Avalonia.Platform.Storage;
using Gommon; using Gommon;
using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Utilities;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@@ -14,18 +14,20 @@ using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Views.Settings namespace Ryujinx.Ava.UI.Views.Settings
{ {
public partial class SettingsUiView : RyujinxControl<SettingsViewModel> public partial class SettingsUiView : UserControl
{ {
public SettingsViewModel ViewModel;
public SettingsUiView() public SettingsUiView()
{ {
InitializeComponent(); InitializeComponent();
AddGameDirButton.Command = AddGameDirButton.Command =
Commands.Create(() => AddDirButton(GameDirPathBox, ViewModel.GameDirectories)); Commands.Create(() => AddDirButton(GameDirPathBox, ViewModel.GameDirectories, true));
AddAutoloadDirButton.Command = AddAutoloadDirButton.Command =
Commands.Create(() => AddDirButton(AutoloadDirPathBox, ViewModel.AutoloadDirectories)); Commands.Create(() => AddDirButton(AutoloadDirPathBox, ViewModel.AutoloadDirectories, false));
} }
private async Task AddDirButton(TextBox addDirBox, AvaloniaList<string> directories) private async Task AddDirButton(TextBox addDirBox, AvaloniaList<string> directories, bool isGameList)
{ {
string path = addDirBox.Text; string path = addDirBox.Text;

View File

@@ -8,6 +8,7 @@ using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Models; using Ryujinx.Ava.UI.Models;
using Ryujinx.HLE.HOS.Services.Account.Acc; using Ryujinx.HLE.HOS.Services.Account.Acc;
using System;
using UserProfile = Ryujinx.Ava.UI.Models.UserProfile; using UserProfile = Ryujinx.Ava.UI.Models.UserProfile;
namespace Ryujinx.Ava.UI.Views.User namespace Ryujinx.Ava.UI.Views.User

View File

@@ -1,3 +1,4 @@
using Avalonia.Controls;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Controls;
using FluentAvalonia.UI.Navigation; using FluentAvalonia.UI.Navigation;

View File

@@ -1,3 +1,4 @@
using Avalonia.Controls;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Threading; using Avalonia.Threading;
using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Controls;

View File

@@ -1,5 +1,5 @@
<UserControl <UserControl
x:Class="Ryujinx.Ava.UI.Views.Dialog.AboutView" x:Class="Ryujinx.Ava.UI.Windows.AboutWindow"
xmlns="https://github.com/avaloniaui" xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

View File

@@ -1,6 +1,8 @@
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Layout;
using Avalonia.Styling;
using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.Controls;
@@ -11,11 +13,11 @@ using Ryujinx.Common.Helper;
using System.Threading.Tasks; using System.Threading.Tasks;
using Button = Avalonia.Controls.Button; using Button = Avalonia.Controls.Button;
namespace Ryujinx.Ava.UI.Views.Dialog namespace Ryujinx.Ava.UI.Windows
{ {
public partial class AboutView : RyujinxControl<AboutWindowViewModel> public partial class AboutWindow : RyujinxControl<AboutWindowViewModel>
{ {
public AboutView() public AboutWindow()
{ {
InitializeComponent(); InitializeComponent();
@@ -32,7 +34,7 @@ namespace Ryujinx.Ava.UI.Views.Dialog
PrimaryButtonText = string.Empty, PrimaryButtonText = string.Empty,
SecondaryButtonText = string.Empty, SecondaryButtonText = string.Empty,
CloseButtonText = LocaleManager.Instance[LocaleKeys.UserProfilesClose], CloseButtonText = LocaleManager.Instance[LocaleKeys.UserProfilesClose],
Content = new AboutView { ViewModel = viewModel } Content = new AboutWindow { ViewModel = viewModel }
}; };
await ContentDialogHelper.ShowAsync(contentDialog.ApplyStyles()); await ContentDialogHelper.ShowAsync(contentDialog.ApplyStyles());

View File

@@ -6,7 +6,6 @@
xmlns:window="clr-namespace:Ryujinx.Ava.UI.Windows" xmlns:window="clr-namespace:Ryujinx.Ava.UI.Windows"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels" xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup" xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignWidth="400" d:DesignWidth="400"
d:DesignHeight="350" d:DesignHeight="350"
@@ -24,25 +23,7 @@
<viewModels:AmiiboWindowViewModel /> <viewModels:AmiiboWindowViewModel />
</Design.DataContext> </Design.DataContext>
<Grid RowDefinitions="Auto,Auto,*,Auto" Margin="15" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" > <Grid RowDefinitions="Auto,Auto,*,Auto" Margin="15" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
<Grid Name="FlushControls" ColumnDefinitions="Auto,Auto" Grid.Row="1" Margin="-15"> <Grid ColumnDefinitions="*,*" Grid.Row="1" HorizontalAlignment="Stretch" >
<controls:RyujinxLogo
Grid.Column="0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="8, 8, 7, 0"
ToolTip.Tip="{ext:WindowTitle Amiibo}" />
<StackPanel Grid.Column="1" Orientation="Horizontal" Margin="0, 0, 0, 100">
<StackPanel Spacing="10" Orientation="Horizontal" HorizontalAlignment="Left">
<TextBlock VerticalAlignment="Center" Text="{ext:Locale AmiiboSeriesLabel}" />
<ComboBox Margin="0, 8, 0, 0" SelectedIndex="{Binding SeriesSelectedIndex}" ItemsSource="{Binding AmiiboSeries}" MinWidth="100" />
</StackPanel>
<StackPanel Margin="15, 0, 0, 0" Spacing="10" Orientation="Horizontal" >
<TextBlock VerticalAlignment="Center" Text="{ext:Locale AmiiboCharacterLabel}" />
<ComboBox Margin="0, 8, 0, 0" SelectedIndex="{Binding AmiiboSelectedIndex}" MinWidth="100" ItemsSource="{Binding AmiiboList}" />
</StackPanel>
</StackPanel>
</Grid>
<Grid Name="NormalControls" ColumnDefinitions="*,*" Grid.Row="1" HorizontalAlignment="Stretch" >
<StackPanel Spacing="10" Orientation="Horizontal" HorizontalAlignment="Left"> <StackPanel Spacing="10" Orientation="Horizontal" HorizontalAlignment="Left">
<TextBlock VerticalAlignment="Center" Text="{ext:Locale AmiiboSeriesLabel}" /> <TextBlock VerticalAlignment="Center" Text="{ext:Locale AmiiboSeriesLabel}" />
<ComboBox SelectedIndex="{Binding SeriesSelectedIndex}" ItemsSource="{Binding AmiiboSeries}" MinWidth="100" /> <ComboBox SelectedIndex="{Binding SeriesSelectedIndex}" ItemsSource="{Binding AmiiboSeries}" MinWidth="100" />

View File

@@ -1,14 +1,13 @@
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Common.Models.Amiibo; using Ryujinx.Ava.Common.Models.Amiibo;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
namespace Ryujinx.Ava.UI.Windows namespace Ryujinx.Ava.UI.Windows
{ {
public partial class AmiiboWindow : StyleableAppWindow public partial class AmiiboWindow : StyleableAppWindow
{ {
public AmiiboWindow(bool showAll, string lastScannedAmiiboId, string titleId) : base(true, 40) public AmiiboWindow(bool showAll, string lastScannedAmiiboId, string titleId)
{ {
DataContext = ViewModel = new AmiiboWindowViewModel(this, lastScannedAmiiboId, titleId) DataContext = ViewModel = new AmiiboWindowViewModel(this, lastScannedAmiiboId, titleId)
{ {
@@ -17,9 +16,6 @@ namespace Ryujinx.Ava.UI.Windows
InitializeComponent(); InitializeComponent();
FlushControls.IsVisible = !ConfigurationState.Instance.ShowOldUI;
NormalControls.IsVisible = ConfigurationState.Instance.ShowOldUI;
Title = RyujinxApp.FormatTitle(LocaleKeys.Amiibo); Title = RyujinxApp.FormatTitle(LocaleKeys.Amiibo);
} }

View File

@@ -6,7 +6,6 @@
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup" xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:window="clr-namespace:Ryujinx.Ava.UI.Windows" xmlns:window="clr-namespace:Ryujinx.Ava.UI.Windows"
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
Width="600" Width="600"
Height="750" Height="750"
MinWidth="500" MinWidth="500"
@@ -21,81 +20,38 @@
</Style> </Style>
</Window.Styles> </Window.Styles>
<Grid Name="CheatGrid" Margin="15" RowDefinitions="Auto,Auto,Auto,*,Auto" ColumnDefinitions="*,*"> <Grid Name="CheatGrid" Margin="15" RowDefinitions="Auto,Auto,Auto,*,Auto" ColumnDefinitions="*,*">
<Grid Name="FlushHeader" Grid.Row="1" Column="0" ColumnSpan="2" RowDefinitions="Auto,Auto,Auto" ColumnDefinitions="Auto,*,Auto,*"> <TextBlock
<controls:RyujinxLogo Grid.Row="1"
Grid.Row="0" Grid.Column="0"
Grid.Column="0" Grid.ColumnSpan="2"
HorizontalAlignment="Left" MaxWidth="500"
Margin="-7, -22, 7, 0" Margin="20,15,20,5"
Height="28" HorizontalAlignment="Center"
Width="28" VerticalAlignment="Center"
ToolTip.Tip="{ext:WindowTitle CheatWindowTitle}"/> LineHeight="18"
<StackPanel Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" Text="{Binding Heading}"
Margin="7, -7, 0, 5" TextAlignment="Center"
Orientation="Horizontal" TextWrapping="Wrap" />
VerticalAlignment="Center" <TextBlock
HorizontalAlignment="Stretch"> Grid.Row="2"
<TextBlock Grid.Column="0"
MaxWidth="500" MaxWidth="500"
Margin="0,8,5,0" Margin="140,15,20,5"
LineHeight="30" HorizontalAlignment="Center"
Text="{ext:Locale BuildId}" VerticalAlignment="Center"
TextAlignment="Center" LineHeight="30"
TextWrapping="Wrap" /> Text="{ext:Locale BuildId}"
<TextBox TextAlignment="Center"
Margin="0,0,0,0" TextWrapping="Wrap" />
MinWidth="135" <TextBox
Text="{Binding BuildId}" Grid.Row="2"
IsReadOnly="True" /> Grid.Column="1"
</StackPanel> Margin="0,5,110,5"
<TextBlock MinWidth="160"
Grid.Row="1" HorizontalAlignment="Center"
Grid.Column="0" VerticalAlignment="Center"
Grid.ColumnSpan="4" Text="{Binding BuildId}"
MaxWidth="500" IsReadOnly="True" />
Margin="0,10,0,5"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
LineHeight="18"
Text="{Binding Heading}"
TextAlignment="Center"
TextWrapping="Wrap" />
</Grid>
<Grid Name="NormalHeader" Grid.Row="1" Column="0" ColumnSpan="2" RowDefinitions="Auto,Auto,Auto" ColumnDefinitions="*,*">
<TextBlock
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
MaxWidth="500"
Margin="20,15,20,5"
HorizontalAlignment="Center"
VerticalAlignment="Center"
LineHeight="18"
Text="{Binding Heading}"
TextAlignment="Center"
TextWrapping="Wrap" />
<TextBlock
Grid.Row="2"
Grid.Column="0"
MaxWidth="500"
Margin="140,15,20,5"
HorizontalAlignment="Center"
VerticalAlignment="Center"
LineHeight="30"
Text="{ext:Locale BuildId}"
TextAlignment="Center"
TextWrapping="Wrap" />
<TextBox
Grid.Row="2"
Grid.Column="1"
Margin="0,5,110,5"
MinWidth="160"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="{Binding BuildId}"
IsReadOnly="True" />
</Grid>
<Border <Border
Grid.Row="3" Grid.Row="3"
Grid.Column="0" Grid.Column="0"

View File

@@ -1,4 +1,5 @@
using Avalonia.Collections; using Avalonia.Collections;
using LibHac.Tools.FsSystem;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Models; using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Systems.AppLibrary;
@@ -31,7 +32,7 @@ namespace Ryujinx.Ava.UI.Windows
Title = RyujinxApp.FormatTitle(LocaleKeys.CheatWindowTitle); Title = RyujinxApp.FormatTitle(LocaleKeys.CheatWindowTitle);
} }
public CheatWindow(VirtualFileSystem virtualFileSystem, string titleId, string titleName, string titlePath) : base(useCustomTitleBar: true, 46) public CheatWindow(VirtualFileSystem virtualFileSystem, string titleId, string titleName, string titlePath)
{ {
MinWidth = 500; MinWidth = 500;
MinHeight = 650; MinHeight = 650;
@@ -43,9 +44,6 @@ namespace Ryujinx.Ava.UI.Windows
InitializeComponent(); InitializeComponent();
FlushHeader.IsVisible = !ConfigurationState.Instance.ShowOldUI;
NormalHeader.IsVisible = ConfigurationState.Instance.ShowOldUI;
string modsBasePath = ModLoader.GetModsBasePath(); string modsBasePath = ModLoader.GetModsBasePath();
string titleModsPath = ModLoader.GetApplicationDir(modsBasePath, titleId); string titleModsPath = ModLoader.GetApplicationDir(modsBasePath, titleId);
ulong titleIdValue = ulong.Parse(titleId, NumberStyles.HexNumber); ulong titleIdValue = ulong.Parse(titleId, NumberStyles.HexNumber);

View File

@@ -7,7 +7,6 @@
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels" xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
xmlns:systems="clr-namespace:Ryujinx.Ava.Systems" xmlns:systems="clr-namespace:Ryujinx.Ava.Systems"
xmlns:window="clr-namespace:Ryujinx.Ava.UI.Windows" xmlns:window="clr-namespace:Ryujinx.Ava.UI.Windows"
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
CanResize="False" CanResize="False"
mc:Ignorable="d" mc:Ignorable="d"
MinWidth="800" MinWidth="800"
@@ -19,10 +18,11 @@
</window:StyleableAppWindow.DataContext> </window:StyleableAppWindow.DataContext>
<Grid RowDefinitions="Auto,*"> <Grid RowDefinitions="Auto,*">
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto,Auto" Name="FlushControls"> <Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto,Auto" Name="FlushControls">
<controls:RyujinxLogo <Image
Grid.Column="0" Name="RyuLogo"
Margin="15, 0, 7, 0" Margin="15, 0, 7, 0"
ToolTip.Tip="{ext:WindowTitle CompatibilityListTitle, False}"/> Height="25"
Width="25" />
<TextBox Name="SearchBoxFlush" Grid.Column="1" Margin="0, 5, 0, 5" HorizontalAlignment="Stretch" Watermark="{ext:Locale CompatibilityListSearchBoxWatermarkWithCount}" TextChanged="TextBox_OnTextChanged" /> <TextBox Name="SearchBoxFlush" Grid.Column="1" Margin="0, 5, 0, 5" HorizontalAlignment="Stretch" Watermark="{ext:Locale CompatibilityListSearchBoxWatermarkWithCount}" TextChanged="TextBox_OnTextChanged" />
<CheckBox Grid.Column="2" Margin="7, 0, 0, 0" IsChecked="{Binding OnlyShowOwnedGames}" /> <CheckBox Grid.Column="2" Margin="7, 0, 0, 0" IsChecked="{Binding OnlyShowOwnedGames}" />
<TextBlock Grid.Column="3" Padding="0, 0, 138, 0" Margin="-10, 0, 18, 0" Text="{ext:Locale CompatibilityListOnlyShowOwnedGames}" /> <TextBlock Grid.Column="3" Padding="0, 0, 138, 0" Margin="-10, 0, 18, 0" Text="{ext:Locale CompatibilityListOnlyShowOwnedGames}" />
@@ -40,7 +40,7 @@
<DataTemplate DataType="{x:Type systems:CompatibilityEntry}"> <DataTemplate DataType="{x:Type systems:CompatibilityEntry}">
<Grid MinWidth="800" <Grid MinWidth="800"
Margin="10" Margin="10"
ColumnDefinitions="Auto,Auto,Auto,*" ColumnDefinitions="*,Auto,Auto,*"
Background="Transparent" Background="Transparent"
ToolTip.Tip="{Binding LocalizedLastUpdated}"> ToolTip.Tip="{Binding LocalizedLastUpdated}">
<TextBlock Grid.Column="0" <TextBlock Grid.Column="0"

View File

@@ -1,33 +1,37 @@
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Styling;
using FluentAvalonia.UI.Controls;
using FluentAvalonia.UI.Windowing;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Windows;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Windows namespace Ryujinx.Ava.UI.Windows
{ {
public partial class CompatibilityListWindow : StyleableAppWindow public partial class CompatibilityListWindow : StyleableAppWindow
{ {
public static async Task Show(string titleId = null) public static Task Show(string titleId = null) =>
{ ShowAsync(new CompatibilityListWindow
using CompatibilityViewModel compatWindow = new(RyujinxApp.MainWindow.ViewModel.ApplicationLibrary);
await ShowAsync(new CompatibilityListWindow
{ {
DataContext = compatWindow, DataContext = new CompatibilityViewModel(RyujinxApp.MainWindow.ViewModel.ApplicationLibrary),
SearchBoxFlush = { Text = titleId ?? string.Empty }, SearchBoxFlush = { Text = titleId ?? string.Empty },
SearchBoxNormal = { Text = titleId ?? string.Empty } SearchBoxNormal = { Text = titleId ?? string.Empty }
}); });
}
public CompatibilityListWindow() : base(useCustomTitleBar: true, 37) public CompatibilityListWindow() : base(useCustomTitleBar: true)
{ {
Title = RyujinxApp.FormatTitle(LocaleKeys.CompatibilityListTitle); Title = RyujinxApp.FormatTitle(LocaleKeys.CompatibilityListTitle);
InitializeComponent(); TitleBar.Height = 37;
FlushControls.IsVisible = !ConfigurationState.Instance.ShowOldUI; InitializeComponent();
NormalControls.IsVisible = ConfigurationState.Instance.ShowOldUI;
RyuLogo.Source = MainWindowViewModel.IconBitmap;
FlushControls.IsVisible = !ConfigurationState.Instance.ShowTitleBar;
NormalControls.IsVisible = ConfigurationState.Instance.ShowTitleBar;
} }
// ReSharper disable once UnusedMember.Local // ReSharper disable once UnusedMember.Local

View File

@@ -1,5 +1,5 @@
<UserControl <UserControl
x:Class="Ryujinx.Ava.UI.Views.Dialog.DownloadableContentManagerView" x:Class="Ryujinx.Ava.UI.Windows.DownloadableContentManagerWindow"
xmlns="https://github.com/avaloniaui" xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

View File

@@ -6,16 +6,26 @@ using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Common.Models; using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.UI.Controls;
using Ryujinx.Common.Helper; using Ryujinx.Common.Helper;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Views.Dialog namespace Ryujinx.Ava.UI.Windows
{ {
public partial class DownloadableContentManagerView : RyujinxControl<DownloadableContentManagerViewModel> public partial class DownloadableContentManagerWindow : UserControl
{ {
public DownloadableContentManagerView() public DownloadableContentManagerViewModel ViewModel;
public DownloadableContentManagerWindow()
{ {
DataContext = this;
InitializeComponent();
}
public DownloadableContentManagerWindow(ApplicationLibrary applicationLibrary, ApplicationData applicationData)
{
DataContext = ViewModel = new DownloadableContentManagerViewModel(applicationLibrary, applicationData);
InitializeComponent(); InitializeComponent();
} }
@@ -26,11 +36,8 @@ namespace Ryujinx.Ava.UI.Views.Dialog
PrimaryButtonText = string.Empty, PrimaryButtonText = string.Empty,
SecondaryButtonText = string.Empty, SecondaryButtonText = string.Empty,
CloseButtonText = string.Empty, CloseButtonText = string.Empty,
Content = new DownloadableContentManagerWindow(applicationLibrary, applicationData),
Title = string.Format(LocaleManager.Instance[LocaleKeys.DlcWindowTitle], applicationData.Name, applicationData.IdBaseString), Title = string.Format(LocaleManager.Instance[LocaleKeys.DlcWindowTitle], applicationData.Name, applicationData.IdBaseString),
Content = new DownloadableContentManagerView
{
ViewModel = new DownloadableContentManagerViewModel(applicationLibrary, applicationData)
}
}; };
Style bottomBorder = new(x => x.OfType<Grid>().Name("DialogSpace").Child().OfType<Border>()); Style bottomBorder = new(x => x.OfType<Grid>().Name("DialogSpace").Child().OfType<Border>());

View File

@@ -13,7 +13,7 @@
xmlns:helper="clr-namespace:Ryujinx.Common.Helper;assembly=Ryujinx.Common" xmlns:helper="clr-namespace:Ryujinx.Common.Helper;assembly=Ryujinx.Common"
Width="1100" Width="1100"
Height="910" Height="910"
MinWidth="1037" MinWidth="800"
MinHeight="480" MinHeight="480"
WindowStartupLocation="CenterOwner" WindowStartupLocation="CenterOwner"
x:DataType="viewModels:SettingsViewModel" x:DataType="viewModels:SettingsViewModel"

View File

@@ -1,9 +1,25 @@
using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Shapes;
using Avalonia.Input;
using Avalonia.Media.Imaging;
using FluentAvalonia.Core;
using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Controls;
using Projektanker.Icons.Avalonia;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.ViewModels.Input;
using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Common.Configuration;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.Input;
using System; using System;
using System.IO;
using System.Linq; using System.Linq;
using Key = Avalonia.Input.Key;
namespace Ryujinx.Ava.UI.Windows namespace Ryujinx.Ava.UI.Windows

View File

@@ -2,9 +2,9 @@ using SkiaSharp;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Ryujinx.Ava.UI.Helpers namespace Ryujinx.Ava.UI.Windows
{ {
public static class IconColorPicker static class IconColorPicker
{ {
private const int ColorsPerLine = 64; private const int ColorsPerLine = 64;
private const int TotalColors = ColorsPerLine * ColorsPerLine; private const int TotalColors = ColorsPerLine * ColorsPerLine;

View File

@@ -7,12 +7,13 @@ using Avalonia.Platform;
using Avalonia.Threading; using Avalonia.Threading;
using DynamicData; using DynamicData;
using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Controls;
using FluentAvalonia.UI.Windowing;
using Gommon; using Gommon;
using LibHac.Ns; using LibHac.Ns;
using LibHac.Tools.FsSystem;
using Ryujinx.Ava.Common; using Ryujinx.Ava.Common;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Input; using Ryujinx.Ava.Input;
using Ryujinx.Ava.Systems;
using Ryujinx.Ava.UI.Applet; using Ryujinx.Ava.UI.Applet;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
@@ -96,7 +97,7 @@ namespace Ryujinx.Ava.UI.Windows
TitleBar.Height = MenuBarHeight; TitleBar.Height = MenuBarHeight;
// Correctly size window when 'TitleBar' is enabled (Nov. 14, 2024) // Correctly size window when 'TitleBar' is enabled (Nov. 14, 2024)
TitleBarHeight = (ConfigurationState.Instance.ShowOldUI ? TitleBar.Height : 0); TitleBarHeight = (ConfigurationState.Instance.ShowTitleBar ? TitleBar.Height : 0);
ApplicationList.DataContext = DataContext; ApplicationList.DataContext = DataContext;
ApplicationGrid.DataContext = DataContext; ApplicationGrid.DataContext = DataContext;

View File

@@ -10,7 +10,7 @@
Width="500" Width="500"
Height="380" Height="380"
mc:Ignorable="d" mc:Ignorable="d"
x:Class="Ryujinx.Ava.UI.Views.Dialog.ModManagerView" x:Class="Ryujinx.Ava.UI.Windows.ModManagerWindow"
x:CompileBindings="True" x:CompileBindings="True"
x:DataType="viewModels:ModManagerViewModel" x:DataType="viewModels:ModManagerViewModel"
Focusable="True"> Focusable="True">

View File

@@ -7,17 +7,27 @@ using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Models; using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.UI.Controls;
using Ryujinx.Common.Helper; using Ryujinx.Common.Helper;
using System.Threading.Tasks; using System.Threading.Tasks;
using Button = Avalonia.Controls.Button; using Button = Avalonia.Controls.Button;
namespace Ryujinx.Ava.UI.Views.Dialog namespace Ryujinx.Ava.UI.Windows
{ {
public partial class ModManagerView : RyujinxControl<ModManagerViewModel> public partial class ModManagerWindow : UserControl
{ {
public ModManagerView() public readonly ModManagerViewModel ViewModel;
public ModManagerWindow()
{ {
DataContext = this;
InitializeComponent();
}
public ModManagerWindow(ulong titleId, ulong titleIdBase, ApplicationLibrary applicationLibrary)
{
DataContext = ViewModel = new ModManagerViewModel(titleId, titleIdBase, applicationLibrary);
InitializeComponent(); InitializeComponent();
} }
@@ -28,10 +38,7 @@ namespace Ryujinx.Ava.UI.Views.Dialog
PrimaryButtonText = string.Empty, PrimaryButtonText = string.Empty,
SecondaryButtonText = string.Empty, SecondaryButtonText = string.Empty,
CloseButtonText = string.Empty, CloseButtonText = string.Empty,
Content = new ModManagerView Content = new ModManagerWindow(titleId, titleIdBase, appLibrary),
{
ViewModel = new ModManagerViewModel(titleId, titleIdBase, appLibrary)
},
Title = string.Format(LocaleManager.Instance[LocaleKeys.ModWindowTitle], titleName, titleId.ToString("X16")), Title = string.Format(LocaleManager.Instance[LocaleKeys.ModWindowTitle], titleName, titleId.ToString("X16")),
}; };

View File

@@ -11,11 +11,10 @@
xmlns:settings="clr-namespace:Ryujinx.Ava.UI.Views.Settings" xmlns:settings="clr-namespace:Ryujinx.Ava.UI.Views.Settings"
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers" xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
xmlns:helper="clr-namespace:Ryujinx.Common.Helper;assembly=Ryujinx.Common" xmlns:helper="clr-namespace:Ryujinx.Common.Helper;assembly=Ryujinx.Common"
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
Width="1100" Width="1100"
MinWidth="844" Height="927"
MinWidth="800"
MinHeight="480" MinHeight="480"
Title="{ext:WindowTitle Settings}"
WindowStartupLocation="CenterOwner" WindowStartupLocation="CenterOwner"
x:DataType="viewModels:SettingsViewModel" x:DataType="viewModels:SettingsViewModel"
mc:Ignorable="d" mc:Ignorable="d"
@@ -23,20 +22,13 @@
<Design.DataContext> <Design.DataContext>
<viewModels:SettingsViewModel /> <viewModels:SettingsViewModel />
</Design.DataContext> </Design.DataContext>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MinWidth="600" RowDefinitions="Auto,Auto,*,Auto"> <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MinWidth="600" RowDefinitions="Auto,*,Auto">
<StackPanel Grid.Row="0" Orientation="Horizontal">
<controls:RyujinxLogo
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="7, 7, 7, 0"
ToolTip.Tip="{ext:WindowTitle Settings}"/>
</StackPanel>
<ContentPresenter <ContentPresenter
x:Name="ContentPresenter" x:Name="ContentPresenter"
Grid.Row="2" Grid.Row="1"
IsVisible="False" IsVisible="False"
KeyboardNavigation.IsTabStop="False"/> KeyboardNavigation.IsTabStop="False"/>
<Grid Name="Pages" IsVisible="False" Grid.Row="3"> <Grid Name="Pages" IsVisible="False" Grid.Row="2">
<settings:SettingsUiView Name="UiPage" /> <settings:SettingsUiView Name="UiPage" />
<settings:SettingsInputView Name="InputPage" /> <settings:SettingsInputView Name="InputPage" />
<settings:SettingsHotkeysView Name="HotkeysPage" /> <settings:SettingsHotkeysView Name="HotkeysPage" />
@@ -49,11 +41,12 @@
<settings:SettingsHacksView Name="HacksPage" /> <settings:SettingsHacksView Name="HacksPage" />
</Grid> </Grid>
<ui:NavigationView <ui:NavigationView
Grid.Row="2" Grid.Row="1"
IsSettingsVisible="False" IsSettingsVisible="False"
Name="NavPanel" Name="NavPanel"
IsBackEnabled="False" IsBackEnabled="False"
Margin="10,10,10,0" PaneDisplayMode="Left"
Margin="2,10,10,0"
VerticalAlignment="Stretch" VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
OpenPaneLength="200"> OpenPaneLength="200">
@@ -115,7 +108,7 @@
</Style> </Style>
</ui:NavigationView.Styles> </ui:NavigationView.Styles>
</ui:NavigationView> </ui:NavigationView>
<Grid Grid.Row="3" <Grid Grid.Row="2"
ColumnDefinitions="Auto,*,Auto"> ColumnDefinitions="Auto,*,Auto">
<StackPanel Grid.Column="0" Orientation="Horizontal"> <StackPanel Grid.Column="0" Orientation="Horizontal">
<Button <Button

View File

@@ -1,7 +1,6 @@
using Avalonia.Controls; using Avalonia.Controls;
using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.FileSystem;
using Ryujinx.Input; using Ryujinx.Input;
@@ -14,7 +13,7 @@ namespace Ryujinx.Ava.UI.Windows
{ {
internal readonly SettingsViewModel ViewModel; internal readonly SettingsViewModel ViewModel;
public SettingsWindow(VirtualFileSystem virtualFileSystem, ContentManager contentManager) : base(true) public SettingsWindow(VirtualFileSystem virtualFileSystem, ContentManager contentManager)
{ {
Title = RyujinxApp.FormatTitle(LocaleKeys.Settings); Title = RyujinxApp.FormatTitle(LocaleKeys.Settings);
@@ -24,16 +23,6 @@ namespace Ryujinx.Ava.UI.Windows
ViewModel.SaveSettingsEvent += SaveSettings; ViewModel.SaveSettingsEvent += SaveSettings;
InitializeComponent(); InitializeComponent();
NavPanel.PaneDisplayMode =
ConfigurationState.Instance.ShowOldUI
? NavigationViewPaneDisplayMode.Left
: NavigationViewPaneDisplayMode.Top;
Height = ConfigurationState.Instance.ShowOldUI
? 906
: 954; // nav panel is put on top with custom title bar so account for new height
Load(); Load();
} }

View File

@@ -7,7 +7,7 @@ using Avalonia.Platform;
using FluentAvalonia.UI.Windowing; using FluentAvalonia.UI.Windowing;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.ViewModels;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Windows namespace Ryujinx.Ava.UI.Windows
@@ -22,7 +22,7 @@ namespace Ryujinx.Ava.UI.Windows
await appWindow.ShowDialog(owner ?? RyujinxApp.MainWindow); await appWindow.ShowDialog(owner ?? RyujinxApp.MainWindow);
} }
protected StyleableAppWindow(bool useCustomTitleBar = false, double? titleBarHeight = null) protected StyleableAppWindow(bool useCustomTitleBar = false)
{ {
WindowStartupLocation = WindowStartupLocation.CenterOwner; WindowStartupLocation = WindowStartupLocation.CenterOwner;
TransparencyLevelHint = [WindowTransparencyLevel.None]; TransparencyLevelHint = [WindowTransparencyLevel.None];
@@ -32,14 +32,11 @@ namespace Ryujinx.Ava.UI.Windows
if (useCustomTitleBar) if (useCustomTitleBar)
{ {
TitleBar.ExtendsContentIntoTitleBar = !ConfigurationState.Instance.ShowOldUI; TitleBar.ExtendsContentIntoTitleBar = !ConfigurationState.Instance.ShowTitleBar;
TitleBar.TitleBarHitTestType = ConfigurationState.Instance.ShowOldUI ? TitleBarHitTestType.Simple : TitleBarHitTestType.Complex; TitleBar.TitleBarHitTestType = ConfigurationState.Instance.ShowTitleBar ? TitleBarHitTestType.Simple : TitleBarHitTestType.Complex;
if (TitleBar.ExtendsContentIntoTitleBar && titleBarHeight != null)
TitleBar.Height = titleBarHeight.Value;
} }
Icon = RyujinxLogo.Bitmap; Icon = MainWindowViewModel.IconBitmap;
} }
private void LocaleChanged() private void LocaleChanged()
@@ -73,7 +70,7 @@ namespace Ryujinx.Ava.UI.Windows
LocaleManager.Instance.LocaleChanged += LocaleChanged; LocaleManager.Instance.LocaleChanged += LocaleChanged;
LocaleChanged(); LocaleChanged();
Icon = new WindowIcon(RyujinxLogo.Bitmap); Icon = new WindowIcon(MainWindowViewModel.IconBitmap);
} }
private void LocaleChanged() private void LocaleChanged()

View File

@@ -1,5 +1,5 @@
<UserControl <UserControl
x:Class="Ryujinx.Ava.UI.Views.Dialog.TitleUpdateManagerView" x:Class="Ryujinx.Ava.UI.Windows.TitleUpdateWindow"
xmlns="https://github.com/avaloniaui" xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

View File

@@ -6,16 +6,26 @@ using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Common.Models; using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Systems.AppLibrary;
using Ryujinx.Ava.UI.Controls;
using Ryujinx.Common.Helper; using Ryujinx.Common.Helper;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Views.Dialog namespace Ryujinx.Ava.UI.Windows
{ {
public partial class TitleUpdateManagerView : RyujinxControl<TitleUpdateViewModel> public partial class TitleUpdateWindow : UserControl
{ {
public TitleUpdateManagerView() public readonly TitleUpdateViewModel ViewModel;
public TitleUpdateWindow()
{ {
DataContext = this;
InitializeComponent();
}
public TitleUpdateWindow(ApplicationLibrary applicationLibrary, ApplicationData applicationData)
{
DataContext = ViewModel = new TitleUpdateViewModel(applicationLibrary, applicationData);
InitializeComponent(); InitializeComponent();
} }
@@ -26,11 +36,8 @@ namespace Ryujinx.Ava.UI.Views.Dialog
PrimaryButtonText = string.Empty, PrimaryButtonText = string.Empty,
SecondaryButtonText = string.Empty, SecondaryButtonText = string.Empty,
CloseButtonText = string.Empty, CloseButtonText = string.Empty,
Content = new TitleUpdateWindow(applicationLibrary, applicationData),
Title = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.GameUpdateWindowHeading, applicationData.Name, applicationData.IdBaseString), Title = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.GameUpdateWindowHeading, applicationData.Name, applicationData.IdBaseString),
Content = new TitleUpdateManagerView
{
ViewModel = new TitleUpdateViewModel(applicationLibrary, applicationData)
}
}; };
Style bottomBorder = new(x => x.OfType<Grid>().Name("DialogSpace").Child().OfType<Border>()); Style bottomBorder = new(x => x.OfType<Grid>().Name("DialogSpace").Child().OfType<Border>());

View File

@@ -1,5 +1,5 @@
<UserControl <UserControl
x:Class="Ryujinx.Ava.UI.Views.Dialog.XciTrimmerView" x:Class="Ryujinx.Ava.UI.Windows.XCITrimmerWindow"
xmlns="https://github.com/avaloniaui" xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
@@ -10,7 +10,7 @@
xmlns:models="clr-namespace:Ryujinx.Ava.Common.Models" xmlns:models="clr-namespace:Ryujinx.Ava.Common.Models"
Width="700" Width="700"
Height="600" Height="600"
x:DataType="viewModels:XciTrimmerViewModel" x:DataType="viewModels:XCITrimmerViewModel"
Focusable="True" Focusable="True"
mc:Ignorable="d"> mc:Ignorable="d">
<Grid Margin="20 0 20 0" RowDefinitions="Auto,Auto,*,Auto,Auto"> <Grid Margin="20 0 20 0" RowDefinitions="Auto,Auto,*,Auto,Auto">
@@ -151,7 +151,7 @@
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Center" VerticalAlignment="Center"
CornerRadius="5" CornerRadius="5"
IsVisible="{Binding $parent[UserControl].((viewModels:XciTrimmerViewModel)DataContext).Processing}" IsVisible="{Binding $parent[UserControl].((viewModels:XCITrimmerViewModel)DataContext).Processing}"
Maximum="100" Maximum="100"
Minimum="0" Minimum="0"
Value="{Binding PercentageProgress}" /> Value="{Binding PercentageProgress}" />

View File

@@ -4,17 +4,27 @@ using Avalonia.Styling;
using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Common.Models; using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Views.Dialog namespace Ryujinx.Ava.UI.Windows
{ {
public partial class XciTrimmerView : RyujinxControl<XciTrimmerViewModel> public partial class XCITrimmerWindow : UserControl
{ {
public XciTrimmerView() public XCITrimmerViewModel ViewModel;
public XCITrimmerWindow()
{ {
DataContext = this;
InitializeComponent();
}
public XCITrimmerWindow(MainWindowViewModel mainWindowViewModel)
{
DataContext = ViewModel = new XCITrimmerViewModel(mainWindowViewModel);
InitializeComponent(); InitializeComponent();
} }
@@ -25,10 +35,7 @@ namespace Ryujinx.Ava.UI.Views.Dialog
PrimaryButtonText = string.Empty, PrimaryButtonText = string.Empty,
SecondaryButtonText = string.Empty, SecondaryButtonText = string.Empty,
CloseButtonText = string.Empty, CloseButtonText = string.Empty,
Content = new XciTrimmerView Content = new XCITrimmerWindow(RyujinxApp.MainWindow.ViewModel),
{
ViewModel = new XciTrimmerViewModel(RyujinxApp.MainWindow.ViewModel)
},
Title = LocaleManager.Instance[LocaleKeys.XCITrimmerWindowTitle] Title = LocaleManager.Instance[LocaleKeys.XCITrimmerWindowTitle]
}; };
@@ -63,7 +70,7 @@ namespace Ryujinx.Ava.UI.Views.Dialog
public void Sort_Checked(object sender, RoutedEventArgs args) public void Sort_Checked(object sender, RoutedEventArgs args)
{ {
if (sender is RadioButton { Tag: string sortField }) if (sender is RadioButton { Tag: string sortField })
ViewModel.SortingField = Enum.Parse<XciTrimmerViewModel.SortField>(sortField); ViewModel.SortingField = Enum.Parse<XCITrimmerViewModel.SortField>(sortField);
} }
public void Order_Checked(object sender, RoutedEventArgs args) public void Order_Checked(object sender, RoutedEventArgs args)

View File

@@ -27,7 +27,7 @@ using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Ryujinx.Ava.Systems namespace Ryujinx.Ava
{ {
internal static class Updater internal static class Updater
{ {