Compare commits
6 Commits
Canary-1.2
...
Canary-1.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7976753fd | ||
|
|
b45a65fbdc | ||
|
|
c410474d83 | ||
|
|
ffdc419417 | ||
|
|
da3f4e1d3a | ||
|
|
69d79322bb |
@@ -1,4 +1,6 @@
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.GAL.Multithreading;
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
@@ -10,6 +12,20 @@ namespace Ryujinx.Graphics.GAL
|
||||
|
||||
bool PreferThreading { get; }
|
||||
|
||||
public IRenderer TryMakeThreaded(BackendThreading backendThreading = BackendThreading.Auto)
|
||||
{
|
||||
if (backendThreading is BackendThreading.On ||
|
||||
(backendThreading is BackendThreading.Auto && PreferThreading))
|
||||
{
|
||||
Logger.Info?.PrintMsg(LogClass.Gpu, $"Backend Threading ({backendThreading}): True");
|
||||
return new ThreadedRenderer(this);
|
||||
}
|
||||
|
||||
Logger.Info?.PrintMsg(LogClass.Gpu, $"Backend Threading ({backendThreading}): False");
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
IPipeline Pipeline { get; }
|
||||
|
||||
IWindow Window { get; }
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnMitm
|
||||
|
||||
private readonly LanDiscovery _lanDiscovery;
|
||||
|
||||
public LdnMitmClient(HLEConfiguration config)
|
||||
public LdnMitmClient(HleConfiguration config)
|
||||
{
|
||||
UnicastIPAddressInformation localIpInterface = NetworkHelpers.GetLocalInterface(config.MultiplayerLanInterfaceId).Item2;
|
||||
|
||||
|
||||
@@ -51,13 +51,13 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnRyu
|
||||
private string _passphrase;
|
||||
private byte[] _gameVersion = new byte[0x10];
|
||||
|
||||
private readonly HLEConfiguration _config;
|
||||
private readonly HleConfiguration _config;
|
||||
|
||||
public event EventHandler<NetworkChangeEventArgs> NetworkChange;
|
||||
|
||||
public ProxyConfig Config { get; private set; }
|
||||
|
||||
public LdnMasterProxyClient(string address, int port, HLEConfiguration config) : base(address, port)
|
||||
public LdnMasterProxyClient(string address, int port, HleConfiguration config) : base(address, port)
|
||||
{
|
||||
if (ProxyHelpers.SupportsNoDelay())
|
||||
{
|
||||
|
||||
@@ -15,55 +15,55 @@ namespace Ryujinx.HLE
|
||||
/// <summary>
|
||||
/// HLE configuration.
|
||||
/// </summary>
|
||||
public class HLEConfiguration
|
||||
public class HleConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// The virtual file system used by the FS service.
|
||||
/// </summary>
|
||||
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
||||
internal readonly VirtualFileSystem VirtualFileSystem;
|
||||
internal VirtualFileSystem VirtualFileSystem { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The manager for handling a LibHac Horizon instance.
|
||||
/// </summary>
|
||||
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
||||
internal readonly LibHacHorizonManager LibHacHorizonManager;
|
||||
internal LibHacHorizonManager LibHacHorizonManager { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The account manager used by the account service.
|
||||
/// </summary>
|
||||
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
||||
internal readonly AccountManager AccountManager;
|
||||
internal AccountManager AccountManager { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The content manager used by the NCM service.
|
||||
/// </summary>
|
||||
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
||||
internal readonly ContentManager ContentManager;
|
||||
internal ContentManager ContentManager { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The persistent information between run for multi-application capabilities.
|
||||
/// </summary>
|
||||
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
||||
public readonly UserChannelPersistence UserChannelPersistence;
|
||||
public UserChannelPersistence UserChannelPersistence { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The GPU renderer to use for all GPU operations.
|
||||
/// </summary>
|
||||
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
||||
internal readonly IRenderer GpuRenderer;
|
||||
internal IRenderer GpuRenderer { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The audio device driver to use for all audio operations.
|
||||
/// </summary>
|
||||
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
||||
internal readonly IHardwareDeviceDriver AudioDeviceDriver;
|
||||
internal IHardwareDeviceDriver AudioDeviceDriver { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The handler for various UI related operations needed outside of HLE.
|
||||
/// </summary>
|
||||
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
||||
internal readonly IHostUIHandler HostUIHandler;
|
||||
internal IHostUIHandler HostUIHandler { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Control the memory configuration used by the emulation context.
|
||||
@@ -195,15 +195,7 @@ namespace Ryujinx.HLE
|
||||
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
||||
public EnabledDirtyHack[] Hacks { internal get; set; }
|
||||
|
||||
public HLEConfiguration(VirtualFileSystem virtualFileSystem,
|
||||
LibHacHorizonManager libHacHorizonManager,
|
||||
ContentManager contentManager,
|
||||
AccountManager accountManager,
|
||||
UserChannelPersistence userChannelPersistence,
|
||||
IRenderer gpuRenderer,
|
||||
IHardwareDeviceDriver audioDeviceDriver,
|
||||
MemoryConfiguration memoryConfiguration,
|
||||
IHostUIHandler hostUIHandler,
|
||||
public HleConfiguration(MemoryConfiguration memoryConfiguration,
|
||||
SystemLanguage systemLanguage,
|
||||
RegionCode region,
|
||||
VSyncMode vSyncMode,
|
||||
@@ -227,15 +219,7 @@ namespace Ryujinx.HLE
|
||||
int customVSyncInterval,
|
||||
EnabledDirtyHack[] dirtyHacks = null)
|
||||
{
|
||||
VirtualFileSystem = virtualFileSystem;
|
||||
LibHacHorizonManager = libHacHorizonManager;
|
||||
AccountManager = accountManager;
|
||||
ContentManager = contentManager;
|
||||
UserChannelPersistence = userChannelPersistence;
|
||||
GpuRenderer = gpuRenderer;
|
||||
AudioDeviceDriver = audioDeviceDriver;
|
||||
MemoryConfiguration = memoryConfiguration;
|
||||
HostUIHandler = hostUIHandler;
|
||||
SystemLanguage = systemLanguage;
|
||||
Region = region;
|
||||
VSyncMode = vSyncMode;
|
||||
@@ -259,5 +243,30 @@ namespace Ryujinx.HLE
|
||||
MultiplayerLdnServer = multiplayerLdnServer;
|
||||
Hacks = dirtyHacks ?? [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the pre-configured services to use for this <see cref="HleConfiguration"/> instance.
|
||||
/// </summary>
|
||||
public HleConfiguration Configure(
|
||||
VirtualFileSystem virtualFileSystem,
|
||||
LibHacHorizonManager libHacHorizonManager,
|
||||
ContentManager contentManager,
|
||||
AccountManager accountManager,
|
||||
UserChannelPersistence userChannelPersistence,
|
||||
IRenderer gpuRenderer,
|
||||
IHardwareDeviceDriver audioDeviceDriver,
|
||||
IHostUIHandler hostUIHandler
|
||||
)
|
||||
{
|
||||
VirtualFileSystem = virtualFileSystem;
|
||||
LibHacHorizonManager = libHacHorizonManager;
|
||||
AccountManager = accountManager;
|
||||
ContentManager = contentManager;
|
||||
UserChannelPersistence = userChannelPersistence;
|
||||
GpuRenderer = gpuRenderer;
|
||||
AudioDeviceDriver = audioDeviceDriver;
|
||||
HostUIHandler = hostUIHandler;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ namespace Ryujinx.HLE
|
||||
{
|
||||
public static Switch Shared { get; private set; }
|
||||
|
||||
public HLEConfiguration Configuration { get; }
|
||||
public HleConfiguration Configuration { get; }
|
||||
public IHardwareDeviceDriver AudioDeviceDriver { get; }
|
||||
public MemoryBlock Memory { get; }
|
||||
public GpuContext Gpu { get; }
|
||||
@@ -44,7 +44,7 @@ namespace Ryujinx.HLE
|
||||
|
||||
public DirtyHacks DirtyHacks { get; }
|
||||
|
||||
public Switch(HLEConfiguration configuration)
|
||||
public Switch(HleConfiguration configuration)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(configuration.GpuRenderer);
|
||||
ArgumentNullException.ThrowIfNull(configuration.AudioDeviceDriver);
|
||||
@@ -94,16 +94,20 @@ namespace Ryujinx.HLE
|
||||
Gpu.GPFifo.DispatchCalls();
|
||||
}
|
||||
|
||||
public void IncrementCustomVSyncInterval()
|
||||
public int IncrementCustomVSyncInterval()
|
||||
{
|
||||
CustomVSyncInterval += 1;
|
||||
UpdateVSyncInterval();
|
||||
|
||||
return CustomVSyncInterval;
|
||||
}
|
||||
|
||||
public void DecrementCustomVSyncInterval()
|
||||
public int DecrementCustomVSyncInterval()
|
||||
{
|
||||
CustomVSyncInterval -= 1;
|
||||
UpdateVSyncInterval();
|
||||
|
||||
return CustomVSyncInterval;
|
||||
}
|
||||
|
||||
public void UpdateVSyncInterval()
|
||||
|
||||
@@ -902,53 +902,19 @@ namespace Ryujinx.Ava
|
||||
_ => new OpenGLRenderer()
|
||||
};
|
||||
|
||||
BackendThreading threadingMode = ConfigurationState.Instance.Graphics.BackendThreading;
|
||||
|
||||
bool isGALThreaded = threadingMode == BackendThreading.On || (threadingMode == BackendThreading.Auto && renderer.PreferThreading);
|
||||
if (isGALThreaded)
|
||||
{
|
||||
renderer = new ThreadedRenderer(renderer);
|
||||
}
|
||||
|
||||
Logger.Info?.PrintMsg(LogClass.Gpu, $"Backend Threading ({threadingMode}): {isGALThreaded}");
|
||||
|
||||
// Initialize Configuration.
|
||||
MemoryConfiguration memoryConfiguration = ConfigurationState.Instance.System.DramSize.Value;
|
||||
|
||||
Device = new Switch(new HLEConfiguration(
|
||||
VirtualFileSystem,
|
||||
_viewModel.LibHacHorizonManager,
|
||||
ContentManager,
|
||||
_accountManager,
|
||||
_userChannelPersistence,
|
||||
renderer,
|
||||
InitializeAudio(),
|
||||
memoryConfiguration,
|
||||
_viewModel.UiHandler,
|
||||
(SystemLanguage)ConfigurationState.Instance.System.Language.Value,
|
||||
(RegionCode)ConfigurationState.Instance.System.Region.Value,
|
||||
ConfigurationState.Instance.Graphics.VSyncMode,
|
||||
ConfigurationState.Instance.System.EnableDockedMode,
|
||||
ConfigurationState.Instance.System.EnablePtc,
|
||||
ConfigurationState.Instance.System.EnableInternetAccess,
|
||||
ConfigurationState.Instance.System.EnableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None,
|
||||
ConfigurationState.Instance.System.FsGlobalAccessLogMode,
|
||||
ConfigurationState.Instance.System.MatchSystemTime
|
||||
? 0
|
||||
: ConfigurationState.Instance.System.SystemTimeOffset,
|
||||
ConfigurationState.Instance.System.TimeZone,
|
||||
ConfigurationState.Instance.System.MemoryManagerMode,
|
||||
ConfigurationState.Instance.System.IgnoreMissingServices,
|
||||
ConfigurationState.Instance.Graphics.AspectRatio,
|
||||
ConfigurationState.Instance.System.AudioVolume,
|
||||
ConfigurationState.Instance.System.UseHypervisor,
|
||||
ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value,
|
||||
ConfigurationState.Instance.Multiplayer.Mode,
|
||||
ConfigurationState.Instance.Multiplayer.DisableP2p,
|
||||
ConfigurationState.Instance.Multiplayer.LdnPassphrase,
|
||||
ConfigurationState.Instance.Multiplayer.GetLdnServer(),
|
||||
ConfigurationState.Instance.Graphics.CustomVSyncInterval.Value,
|
||||
ConfigurationState.Instance.Hacks.ShowDirtyHacks ? ConfigurationState.Instance.Hacks.EnabledHacks : null));
|
||||
Device = new Switch(ConfigurationState.Instance.CreateHleConfiguration()
|
||||
.Configure(
|
||||
VirtualFileSystem,
|
||||
_viewModel.LibHacHorizonManager,
|
||||
ContentManager,
|
||||
_accountManager,
|
||||
_userChannelPersistence,
|
||||
renderer.TryMakeThreaded(ConfigurationState.Instance.Graphics.BackendThreading),
|
||||
InitializeAudio(),
|
||||
_viewModel.UiHandler
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private static IHardwareDeviceDriver InitializeAudio()
|
||||
@@ -1182,6 +1148,9 @@ namespace Ryujinx.Ava
|
||||
|
||||
private void UpdateShaderCount()
|
||||
{
|
||||
if (_displayCount is 0 && _renderer.ProgramCount is 0)
|
||||
return;
|
||||
|
||||
// If there is a mismatch between total program compile and previous count
|
||||
// this means new shaders have been compiled and should be displayed.
|
||||
if (_renderer.ProgramCount != _previousCount)
|
||||
@@ -1255,12 +1224,10 @@ namespace Ryujinx.Ava
|
||||
VSyncModeToggle();
|
||||
break;
|
||||
case KeyboardHotkeyState.CustomVSyncIntervalDecrement:
|
||||
Device.DecrementCustomVSyncInterval();
|
||||
_viewModel.CustomVSyncInterval -= 1;
|
||||
_viewModel.CustomVSyncInterval = Device.DecrementCustomVSyncInterval();
|
||||
break;
|
||||
case KeyboardHotkeyState.CustomVSyncIntervalIncrement:
|
||||
Device.IncrementCustomVSyncInterval();
|
||||
_viewModel.CustomVSyncInterval += 1;
|
||||
_viewModel.CustomVSyncInterval = Device.IncrementCustomVSyncInterval();
|
||||
break;
|
||||
case KeyboardHotkeyState.Screenshot:
|
||||
ScreenshotRequested = true;
|
||||
|
||||
@@ -13,7 +13,7 @@ using LibHac.Tools.Fs;
|
||||
using LibHac.Tools.FsSystem;
|
||||
using LibHac.Tools.FsSystem.NcaUtils;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.UI.Controls;
|
||||
using Ryujinx.Ava.UI.Windows;
|
||||
using Ryujinx.Ava.UI.Helpers;
|
||||
using Ryujinx.Ava.Utilities;
|
||||
using Ryujinx.Ava.Utilities.Configuration;
|
||||
|
||||
@@ -312,49 +312,42 @@ namespace Ryujinx.Headless
|
||||
return new OpenGLRenderer();
|
||||
}
|
||||
|
||||
private static Switch InitializeEmulationContext(WindowBase window, IRenderer renderer, Options options)
|
||||
{
|
||||
BackendThreading threadingMode = options.BackendThreading;
|
||||
|
||||
bool threadedGAL = threadingMode == BackendThreading.On || (threadingMode == BackendThreading.Auto && renderer.PreferThreading);
|
||||
|
||||
if (threadedGAL)
|
||||
{
|
||||
renderer = new ThreadedRenderer(renderer);
|
||||
}
|
||||
|
||||
HLEConfiguration configuration = new(_virtualFileSystem,
|
||||
_libHacHorizonManager,
|
||||
_contentManager,
|
||||
_accountManager,
|
||||
_userChannelPersistence,
|
||||
renderer,
|
||||
new SDL2HardwareDeviceDriver(),
|
||||
options.DramSize,
|
||||
window,
|
||||
options.SystemLanguage,
|
||||
options.SystemRegion,
|
||||
options.VSyncMode,
|
||||
!options.DisableDockedMode,
|
||||
!options.DisablePTC,
|
||||
options.EnableInternetAccess,
|
||||
!options.DisableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None,
|
||||
options.FsGlobalAccessLogMode,
|
||||
options.SystemTimeOffset,
|
||||
options.SystemTimeZone,
|
||||
options.MemoryManagerMode,
|
||||
options.IgnoreMissingServices,
|
||||
options.AspectRatio,
|
||||
options.AudioVolume,
|
||||
options.UseHypervisor ?? true,
|
||||
options.MultiplayerLanInterfaceId,
|
||||
Common.Configuration.Multiplayer.MultiplayerMode.Disabled,
|
||||
false,
|
||||
string.Empty,
|
||||
string.Empty,
|
||||
options.CustomVSyncInterval);
|
||||
|
||||
return new Switch(configuration);
|
||||
}
|
||||
private static Switch InitializeEmulationContext(WindowBase window, IRenderer renderer, Options options) =>
|
||||
new(
|
||||
new HleConfiguration(
|
||||
options.DramSize,
|
||||
options.SystemLanguage,
|
||||
options.SystemRegion,
|
||||
options.VSyncMode,
|
||||
!options.DisableDockedMode,
|
||||
!options.DisablePTC,
|
||||
options.EnableInternetAccess,
|
||||
!options.DisableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None,
|
||||
options.FsGlobalAccessLogMode,
|
||||
options.SystemTimeOffset,
|
||||
options.SystemTimeZone,
|
||||
options.MemoryManagerMode,
|
||||
options.IgnoreMissingServices,
|
||||
options.AspectRatio,
|
||||
options.AudioVolume,
|
||||
options.UseHypervisor ?? true,
|
||||
options.MultiplayerLanInterfaceId,
|
||||
Common.Configuration.Multiplayer.MultiplayerMode.Disabled,
|
||||
false,
|
||||
string.Empty,
|
||||
string.Empty,
|
||||
options.CustomVSyncInterval
|
||||
)
|
||||
.Configure(
|
||||
_virtualFileSystem,
|
||||
_libHacHorizonManager,
|
||||
_contentManager,
|
||||
_accountManager,
|
||||
_userChannelPersistence,
|
||||
renderer.TryMakeThreaded(options.BackendThreading),
|
||||
new SDL2HardwareDeviceDriver(),
|
||||
window
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,17 +9,14 @@ using Ryujinx.Ava.UI.ViewModels;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Threading.Tasks;
|
||||
using UserProfile = Ryujinx.Ava.UI.Models.UserProfile;
|
||||
using UserProfileSft = Ryujinx.HLE.HOS.Services.Account.Acc.UserProfile;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Applet
|
||||
{
|
||||
public partial class ProfileSelectorDialog : UserControl
|
||||
public partial class ProfileSelectorDialog : RyujinxControl<ProfileSelectorDialogViewModel>
|
||||
{
|
||||
public ProfileSelectorDialogViewModel ViewModel { get; set; }
|
||||
|
||||
public ProfileSelectorDialog(ProfileSelectorDialogViewModel viewModel)
|
||||
{
|
||||
DataContext = ViewModel = viewModel;
|
||||
|
||||
@@ -9,6 +9,7 @@ using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.Common.Models;
|
||||
using Ryujinx.Ava.UI.Helpers;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using Ryujinx.Ava.UI.Views.Misc;
|
||||
using Ryujinx.Ava.UI.Windows;
|
||||
using Ryujinx.Ava.Utilities;
|
||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||
@@ -26,6 +27,7 @@ namespace Ryujinx.Ava.UI.Controls
|
||||
{
|
||||
public class ApplicationContextMenu : MenuFlyout
|
||||
{
|
||||
|
||||
public ApplicationContextMenu()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
@@ -23,13 +23,12 @@ using UserProfile = Ryujinx.Ava.UI.Models.UserProfile;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Controls
|
||||
{
|
||||
public partial class NavigationDialogHost : UserControl
|
||||
public partial class NavigationDialogHost : RyujinxControl<UserProfileViewModel>
|
||||
{
|
||||
public AccountManager AccountManager { get; }
|
||||
public ContentManager ContentManager { get; }
|
||||
public VirtualFileSystem VirtualFileSystem { get; }
|
||||
public HorizonClient HorizonClient { get; }
|
||||
public UserProfileViewModel ViewModel { get; set; }
|
||||
|
||||
public NavigationDialogHost()
|
||||
{
|
||||
|
||||
24
src/Ryujinx/UI/Controls/RyujinxControl.cs
Normal file
24
src/Ryujinx/UI/Controls/RyujinxControl.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using Avalonia.Controls;
|
||||
using Gommon;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Controls
|
||||
{
|
||||
public class RyujinxControl<TViewModel> : UserControl where TViewModel : BaseModel
|
||||
{
|
||||
public TViewModel ViewModel
|
||||
{
|
||||
get
|
||||
{
|
||||
if (DataContext is not TViewModel viewModel)
|
||||
throw new InvalidOperationException(
|
||||
$"Underlying DataContext is not of type {typeof(TViewModel).AsPrettyString()}; " +
|
||||
$"Actual type is {DataContext?.GetType().AsPrettyString()}");
|
||||
|
||||
return viewModel;
|
||||
}
|
||||
set => DataContext = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,19 +40,19 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||
SecondaryButtonText = secondaryButton,
|
||||
CloseButtonText = closeButton,
|
||||
Content = content,
|
||||
PrimaryButtonCommand = MiniCommand.Create(() =>
|
||||
PrimaryButtonCommand = Commands.Create(() =>
|
||||
{
|
||||
result = primaryButtonResult;
|
||||
})
|
||||
};
|
||||
|
||||
contentDialog.SecondaryButtonCommand = MiniCommand.Create(() =>
|
||||
contentDialog.SecondaryButtonCommand = Commands.Create(() =>
|
||||
{
|
||||
result = UserResult.No;
|
||||
contentDialog.PrimaryButtonClick -= deferCloseAction;
|
||||
});
|
||||
|
||||
contentDialog.CloseButtonCommand = MiniCommand.Create(() =>
|
||||
contentDialog.CloseButtonCommand = Commands.Create(() =>
|
||||
{
|
||||
result = UserResult.Cancel;
|
||||
contentDialog.PrimaryButtonClick -= deferCloseAction;
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Helpers
|
||||
{
|
||||
public sealed class MiniCommand<T> : MiniCommand, ICommand
|
||||
{
|
||||
private readonly Action<T> _callback;
|
||||
private bool _busy;
|
||||
private readonly Func<T, Task> _asyncCallback;
|
||||
|
||||
public MiniCommand(Action<T> callback)
|
||||
{
|
||||
_callback = callback;
|
||||
}
|
||||
|
||||
public MiniCommand(Func<T, Task> callback)
|
||||
{
|
||||
_asyncCallback = callback;
|
||||
}
|
||||
|
||||
private bool Busy
|
||||
{
|
||||
get => _busy;
|
||||
set
|
||||
{
|
||||
_busy = value;
|
||||
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
public override event EventHandler CanExecuteChanged;
|
||||
public override bool CanExecute(object parameter) => !_busy;
|
||||
|
||||
public override async void Execute(object parameter)
|
||||
{
|
||||
if (Busy)
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
Busy = true;
|
||||
if (_callback != null)
|
||||
{
|
||||
_callback((T)parameter);
|
||||
}
|
||||
else
|
||||
{
|
||||
await _asyncCallback((T)parameter);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Busy = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class MiniCommand : ICommand
|
||||
{
|
||||
public static MiniCommand Create(Action callback) => new MiniCommand<object>(_ => callback());
|
||||
public static MiniCommand Create<TArg>(Action<TArg> callback) => new MiniCommand<TArg>(callback);
|
||||
public static MiniCommand CreateFromTask(Func<Task> callback) => new MiniCommand<object>(_ => callback());
|
||||
public static MiniCommand CreateFromTask<TArg>(Func<TArg, Task> callback) => new MiniCommand<TArg>(callback);
|
||||
|
||||
public abstract bool CanExecute(object parameter);
|
||||
public abstract void Execute(object parameter);
|
||||
public abstract event EventHandler CanExecuteChanged;
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,7 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Media;
|
||||
using Ryujinx.Ava.Utilities.Configuration;
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Logging;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Renderer
|
||||
@@ -38,32 +36,6 @@ namespace Ryujinx.Ava.UI.Renderer
|
||||
EmbeddedWindowOpenGL => GraphicsBackend.OpenGl,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
|
||||
public RendererHost(string titleId)
|
||||
{
|
||||
Focusable = true;
|
||||
FlowDirection = FlowDirection.LeftToRight;
|
||||
|
||||
EmbeddedWindow =
|
||||
#pragma warning disable CS8524
|
||||
ConfigurationState.Instance.Graphics.GraphicsBackend.Value switch
|
||||
#pragma warning restore CS8524
|
||||
{
|
||||
GraphicsBackend.OpenGl => new EmbeddedWindowOpenGL(),
|
||||
GraphicsBackend.Vulkan => new EmbeddedWindowVulkan(),
|
||||
};
|
||||
|
||||
string backendText = EmbeddedWindow switch
|
||||
{
|
||||
EmbeddedWindowVulkan => "Vulkan",
|
||||
EmbeddedWindowOpenGL => "OpenGL",
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
|
||||
Logger.Info?.PrintMsg(LogClass.Gpu, $"Backend ({ConfigurationState.Instance.Graphics.GraphicsBackend.Value}): {backendText}");
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
|
||||
private void Initialize()
|
||||
|
||||
@@ -21,7 +21,7 @@ using Image = SkiaSharp.SKImage;
|
||||
|
||||
namespace Ryujinx.Ava.UI.ViewModels
|
||||
{
|
||||
internal partial class UserFirmwareAvatarSelectorViewModel : BaseModel
|
||||
public partial class UserFirmwareAvatarSelectorViewModel : BaseModel
|
||||
{
|
||||
private static readonly Dictionary<string, byte[]> _avatarStore = new();
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace Ryujinx.Ava.UI.ViewModels
|
||||
{
|
||||
internal partial class UserProfileImageSelectorViewModel : BaseModel
|
||||
public partial class UserProfileImageSelectorViewModel : BaseModel
|
||||
{
|
||||
[ObservableProperty] private bool _firmwareFound;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.LogicalTree;
|
||||
using Ryujinx.Ava.UI.Controls;
|
||||
using Ryujinx.Ava.UI.Helpers;
|
||||
using Ryujinx.Ava.UI.ViewModels.Input;
|
||||
using Ryujinx.Common.Configuration.Hid.Controller;
|
||||
@@ -14,7 +15,7 @@ using StickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Views.Input
|
||||
{
|
||||
public partial class ControllerInputView : UserControl
|
||||
public partial class ControllerInputView : RyujinxControl<ControllerInputViewModel>
|
||||
{
|
||||
private ButtonKeyAssigner _currentAssigner;
|
||||
|
||||
@@ -217,20 +218,12 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||
PointerPressed -= MouseClick;
|
||||
}
|
||||
|
||||
private IButtonAssigner CreateButtonAssigner(bool forStick)
|
||||
{
|
||||
IButtonAssigner assigner;
|
||||
|
||||
ControllerInputViewModel controllerInputViewModel = DataContext as ControllerInputViewModel;
|
||||
|
||||
assigner = new GamepadButtonAssigner(
|
||||
controllerInputViewModel.ParentModel.SelectedGamepad,
|
||||
(controllerInputViewModel.ParentModel.Config as StandardControllerInputConfig).TriggerThreshold,
|
||||
private IButtonAssigner CreateButtonAssigner(bool forStick) =>
|
||||
new GamepadButtonAssigner(
|
||||
ViewModel.ParentModel.SelectedGamepad,
|
||||
(ViewModel.ParentModel.Config as StandardControllerInputConfig).TriggerThreshold,
|
||||
forStick);
|
||||
|
||||
return assigner;
|
||||
}
|
||||
|
||||
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
base.OnDetachedFromVisualTree(e);
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
using Avalonia.Controls;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.UI.Controls;
|
||||
using Ryujinx.Ava.UI.Helpers;
|
||||
using Ryujinx.Ava.UI.Models;
|
||||
using Ryujinx.Ava.UI.ViewModels.Input;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Views.Input
|
||||
{
|
||||
public partial class InputView : UserControl
|
||||
public partial class InputView : RyujinxControl<InputViewModel>
|
||||
{
|
||||
private bool _dialogOpen;
|
||||
private InputViewModel ViewModel { get; set; }
|
||||
|
||||
public InputView()
|
||||
{
|
||||
DataContext = ViewModel = new InputViewModel(this);
|
||||
ViewModel = new InputViewModel(this);
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.LogicalTree;
|
||||
using Ryujinx.Ava.UI.Controls;
|
||||
using Ryujinx.Ava.UI.Helpers;
|
||||
using Ryujinx.Ava.UI.ViewModels.Input;
|
||||
using Ryujinx.Input;
|
||||
@@ -13,7 +14,7 @@ using Key = Ryujinx.Common.Configuration.Hid.Key;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Views.Input
|
||||
{
|
||||
public partial class KeyboardInputView : UserControl
|
||||
public partial class KeyboardInputView : RyujinxControl<KeyboardInputViewModel>
|
||||
{
|
||||
private ButtonKeyAssigner _currentAssigner;
|
||||
|
||||
@@ -60,106 +61,103 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||
|
||||
PointerPressed += MouseClick;
|
||||
|
||||
if (DataContext is not KeyboardInputViewModel viewModel)
|
||||
return;
|
||||
|
||||
IKeyboard keyboard =
|
||||
(IKeyboard)viewModel.ParentModel.AvaloniaKeyboardDriver.GetGamepad("0"); // Open Avalonia keyboard for cancel operations.
|
||||
(IKeyboard)ViewModel.ParentModel.AvaloniaKeyboardDriver.GetGamepad("0"); // Open Avalonia keyboard for cancel operations.
|
||||
IButtonAssigner assigner =
|
||||
new KeyboardKeyAssigner((IKeyboard)viewModel.ParentModel.SelectedGamepad);
|
||||
new KeyboardKeyAssigner((IKeyboard)ViewModel.ParentModel.SelectedGamepad);
|
||||
|
||||
_currentAssigner.ButtonAssigned += (_, e) =>
|
||||
_currentAssigner.ButtonAssigned += (_, be) =>
|
||||
{
|
||||
if (e.ButtonValue.HasValue)
|
||||
if (be.ButtonValue.HasValue)
|
||||
{
|
||||
Button buttonValue = e.ButtonValue.Value;
|
||||
viewModel.ParentModel.IsModified = true;
|
||||
Button buttonValue = be.ButtonValue.Value;
|
||||
ViewModel.ParentModel.IsModified = true;
|
||||
|
||||
switch (button.Name)
|
||||
{
|
||||
case "ButtonZl":
|
||||
viewModel.Config.ButtonZl = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.ButtonZl = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "ButtonL":
|
||||
viewModel.Config.ButtonL = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.ButtonL = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "ButtonMinus":
|
||||
viewModel.Config.ButtonMinus = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.ButtonMinus = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "LeftStickButton":
|
||||
viewModel.Config.LeftStickButton = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.LeftStickButton = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "LeftStickUp":
|
||||
viewModel.Config.LeftStickUp = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.LeftStickUp = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "LeftStickDown":
|
||||
viewModel.Config.LeftStickDown = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.LeftStickDown = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "LeftStickRight":
|
||||
viewModel.Config.LeftStickRight = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.LeftStickRight = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "LeftStickLeft":
|
||||
viewModel.Config.LeftStickLeft = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.LeftStickLeft = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "DpadUp":
|
||||
viewModel.Config.DpadUp = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.DpadUp = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "DpadDown":
|
||||
viewModel.Config.DpadDown = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.DpadDown = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "DpadLeft":
|
||||
viewModel.Config.DpadLeft = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.DpadLeft = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "DpadRight":
|
||||
viewModel.Config.DpadRight = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.DpadRight = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "LeftButtonSr":
|
||||
viewModel.Config.LeftButtonSr = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.LeftButtonSr = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "LeftButtonSl":
|
||||
viewModel.Config.LeftButtonSl = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.LeftButtonSl = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "RightButtonSr":
|
||||
viewModel.Config.RightButtonSr = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.RightButtonSr = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "RightButtonSl":
|
||||
viewModel.Config.RightButtonSl = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.RightButtonSl = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "ButtonZr":
|
||||
viewModel.Config.ButtonZr = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.ButtonZr = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "ButtonR":
|
||||
viewModel.Config.ButtonR = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.ButtonR = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "ButtonPlus":
|
||||
viewModel.Config.ButtonPlus = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.ButtonPlus = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "ButtonA":
|
||||
viewModel.Config.ButtonA = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.ButtonA = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "ButtonB":
|
||||
viewModel.Config.ButtonB = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.ButtonB = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "ButtonX":
|
||||
viewModel.Config.ButtonX = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.ButtonX = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "ButtonY":
|
||||
viewModel.Config.ButtonY = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.ButtonY = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "RightStickButton":
|
||||
viewModel.Config.RightStickButton = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.RightStickButton = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "RightStickUp":
|
||||
viewModel.Config.RightStickUp = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.RightStickUp = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "RightStickDown":
|
||||
viewModel.Config.RightStickDown = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.RightStickDown = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "RightStickRight":
|
||||
viewModel.Config.RightStickRight = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.RightStickRight = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "RightStickLeft":
|
||||
viewModel.Config.RightStickLeft = buttonValue.AsHidType<Key>();
|
||||
ViewModel.Config.RightStickLeft = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,19 +2,18 @@
|
||||
using Avalonia.Controls;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.UI.Controls;
|
||||
using Ryujinx.Ava.UI.Models.Input;
|
||||
using Ryujinx.Ava.UI.ViewModels.Input;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.UI.Views.Input
|
||||
{
|
||||
public partial class LedInputView : UserControl
|
||||
public partial class LedInputView : RyujinxControl<LedInputViewModel>
|
||||
{
|
||||
private readonly LedInputViewModel _viewModel;
|
||||
|
||||
public LedInputView(ControllerInputViewModel viewModel)
|
||||
{
|
||||
DataContext = _viewModel = new LedInputViewModel
|
||||
ViewModel = new LedInputViewModel
|
||||
{
|
||||
ParentModel = viewModel.ParentModel,
|
||||
TurnOffLed = viewModel.Config.TurnOffLed,
|
||||
@@ -29,20 +28,18 @@ namespace Ryujinx.UI.Views.Input
|
||||
private void ColorPickerButton_OnColorChanged(ColorPickerButton sender, ColorButtonColorChangedEventArgs args)
|
||||
{
|
||||
if (!args.NewColor.HasValue) return;
|
||||
if (DataContext is not LedInputViewModel lvm) return;
|
||||
if (!lvm.EnableLedChanging) return;
|
||||
if (lvm.TurnOffLed) return;
|
||||
if (!ViewModel.EnableLedChanging) return;
|
||||
if (ViewModel.TurnOffLed) return;
|
||||
|
||||
lvm.ParentModel.SelectedGamepad.SetLed(args.NewColor.Value.ToUInt32());
|
||||
ViewModel.ParentModel.SelectedGamepad.SetLed(args.NewColor.Value.ToUInt32());
|
||||
}
|
||||
|
||||
private void ColorPickerButton_OnAttachedToVisualTree(object sender, VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
if (DataContext is not LedInputViewModel lvm) return;
|
||||
if (!lvm.EnableLedChanging) return;
|
||||
if (lvm.TurnOffLed) return;
|
||||
if (!ViewModel.EnableLedChanging) return;
|
||||
if (ViewModel.TurnOffLed) return;
|
||||
|
||||
lvm.ParentModel.SelectedGamepad.SetLed(lvm.LedColor.ToUInt32());
|
||||
ViewModel.ParentModel.SelectedGamepad.SetLed(ViewModel.LedColor.ToUInt32());
|
||||
}
|
||||
|
||||
public static async Task Show(ControllerInputViewModel viewModel)
|
||||
@@ -57,13 +54,13 @@ namespace Ryujinx.UI.Views.Input
|
||||
CloseButtonText = LocaleManager.Instance[LocaleKeys.ControllerSettingsClose],
|
||||
Content = content,
|
||||
};
|
||||
contentDialog.PrimaryButtonClick += (sender, args) =>
|
||||
contentDialog.PrimaryButtonClick += (_, _) =>
|
||||
{
|
||||
GamepadInputConfig config = viewModel.Config;
|
||||
config.EnableLedChanging = content._viewModel.EnableLedChanging;
|
||||
config.LedColor = content._viewModel.LedColor;
|
||||
config.UseRainbowLed = content._viewModel.UseRainbowLed;
|
||||
config.TurnOffLed = content._viewModel.TurnOffLed;
|
||||
config.EnableLedChanging = content.ViewModel.EnableLedChanging;
|
||||
config.LedColor = content.ViewModel.LedColor;
|
||||
config.UseRainbowLed = content.ViewModel.UseRainbowLed;
|
||||
config.TurnOffLed = content.ViewModel.TurnOffLed;
|
||||
};
|
||||
|
||||
await contentDialog.ShowAsync();
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
using Avalonia.Controls;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.UI.Controls;
|
||||
using Ryujinx.Ava.UI.Models.Input;
|
||||
using Ryujinx.Ava.UI.ViewModels.Input;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Views.Input
|
||||
{
|
||||
public partial class MotionInputView : UserControl
|
||||
public partial class MotionInputView : RyujinxControl<MotionInputViewModel>
|
||||
{
|
||||
private readonly MotionInputViewModel _viewModel;
|
||||
|
||||
public MotionInputView()
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -20,7 +19,7 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||
{
|
||||
GamepadInputConfig config = viewModel.Config;
|
||||
|
||||
_viewModel = new MotionInputViewModel
|
||||
ViewModel = new MotionInputViewModel
|
||||
{
|
||||
Slot = config.Slot,
|
||||
AltSlot = config.AltSlot,
|
||||
@@ -33,7 +32,6 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||
};
|
||||
|
||||
InitializeComponent();
|
||||
DataContext = _viewModel;
|
||||
}
|
||||
|
||||
public static async Task Show(ControllerInputViewModel viewModel)
|
||||
@@ -48,17 +46,17 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||
CloseButtonText = LocaleManager.Instance[LocaleKeys.ControllerSettingsClose],
|
||||
Content = content,
|
||||
};
|
||||
contentDialog.PrimaryButtonClick += (sender, args) =>
|
||||
contentDialog.PrimaryButtonClick += (_, _) =>
|
||||
{
|
||||
GamepadInputConfig config = viewModel.Config;
|
||||
config.Slot = content._viewModel.Slot;
|
||||
config.Sensitivity = content._viewModel.Sensitivity;
|
||||
config.GyroDeadzone = content._viewModel.GyroDeadzone;
|
||||
config.AltSlot = content._viewModel.AltSlot;
|
||||
config.DsuServerHost = content._viewModel.DsuServerHost;
|
||||
config.DsuServerPort = content._viewModel.DsuServerPort;
|
||||
config.EnableCemuHookMotion = content._viewModel.EnableCemuHookMotion;
|
||||
config.MirrorInput = content._viewModel.MirrorInput;
|
||||
config.Slot = content.ViewModel.Slot;
|
||||
config.Sensitivity = content.ViewModel.Sensitivity;
|
||||
config.GyroDeadzone = content.ViewModel.GyroDeadzone;
|
||||
config.AltSlot = content.ViewModel.AltSlot;
|
||||
config.DsuServerHost = content.ViewModel.DsuServerHost;
|
||||
config.DsuServerPort = content.ViewModel.DsuServerPort;
|
||||
config.EnableCemuHookMotion = content.ViewModel.EnableCemuHookMotion;
|
||||
config.MirrorInput = content.ViewModel.MirrorInput;
|
||||
};
|
||||
|
||||
await contentDialog.ShowAsync();
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
using Avalonia.Controls;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.UI.Controls;
|
||||
using Ryujinx.Ava.UI.Models.Input;
|
||||
using Ryujinx.Ava.UI.ViewModels.Input;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Views.Input
|
||||
{
|
||||
public partial class RumbleInputView : UserControl
|
||||
public partial class RumbleInputView : RyujinxControl<RumbleInputViewModel>
|
||||
{
|
||||
private readonly RumbleInputViewModel _viewModel;
|
||||
|
||||
public RumbleInputView()
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -20,15 +19,13 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||
{
|
||||
GamepadInputConfig config = viewModel.Config;
|
||||
|
||||
_viewModel = new RumbleInputViewModel
|
||||
ViewModel = new RumbleInputViewModel
|
||||
{
|
||||
StrongRumble = config.StrongRumble,
|
||||
WeakRumble = config.WeakRumble,
|
||||
};
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
DataContext = _viewModel;
|
||||
}
|
||||
|
||||
public static async Task Show(ControllerInputViewModel viewModel)
|
||||
@@ -44,11 +41,11 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||
Content = content,
|
||||
};
|
||||
|
||||
contentDialog.PrimaryButtonClick += (sender, args) =>
|
||||
contentDialog.PrimaryButtonClick += (_, _) =>
|
||||
{
|
||||
GamepadInputConfig config = viewModel.Config;
|
||||
config.StrongRumble = content._viewModel.StrongRumble;
|
||||
config.WeakRumble = content._viewModel.WeakRumble;
|
||||
config.StrongRumble = content.ViewModel.StrongRumble;
|
||||
config.WeakRumble = content.ViewModel.WeakRumble;
|
||||
};
|
||||
|
||||
await contentDialog.ShowAsync();
|
||||
|
||||
@@ -6,6 +6,7 @@ using Gommon;
|
||||
using LibHac.Common;
|
||||
using LibHac.Ns;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.UI.Controls;
|
||||
using Ryujinx.Ava.UI.Helpers;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using Ryujinx.Ava.UI.Windows;
|
||||
@@ -25,10 +26,9 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Views.Main
|
||||
{
|
||||
public partial class MainMenuBarView : UserControl
|
||||
public partial class MainMenuBarView : RyujinxControl<MainWindowViewModel>
|
||||
{
|
||||
public MainWindow Window { get; private set; }
|
||||
public MainWindowViewModel ViewModel { get; private set; }
|
||||
|
||||
public MainMenuBarView()
|
||||
{
|
||||
@@ -73,7 +73,7 @@ namespace Ryujinx.Ava.UI.Views.Main
|
||||
{
|
||||
Content = $".{it.FileName}",
|
||||
IsChecked = it.FileType.GetConfigValue(ConfigurationState.Instance.UI.ShownFileTypes),
|
||||
Command = MiniCommand.Create(() => Window.ToggleFileType(it.FileName))
|
||||
Command = Commands.Create(() => Window.ToggleFileType(it.FileName))
|
||||
}
|
||||
);
|
||||
|
||||
@@ -108,7 +108,7 @@ namespace Ryujinx.Ava.UI.Views.Main
|
||||
Margin = new Thickness(3, 0, 3, 0),
|
||||
HorizontalAlignment = HorizontalAlignment.Stretch,
|
||||
Header = languageName,
|
||||
Command = MiniCommand.Create(() => MainWindowViewModel.ChangeLanguage(language))
|
||||
Command = Commands.Create(() => MainWindowViewModel.ChangeLanguage(language))
|
||||
};
|
||||
|
||||
yield return menuItem;
|
||||
|
||||
@@ -4,6 +4,8 @@ using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Threading;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.UI.Controls;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using Ryujinx.Ava.UI.Windows;
|
||||
using Ryujinx.Ava.Utilities.Configuration;
|
||||
using Ryujinx.Common;
|
||||
@@ -13,7 +15,7 @@ using System;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Views.Main
|
||||
{
|
||||
public partial class MainStatusBarView : UserControl
|
||||
public partial class MainStatusBarView : RyujinxControl<MainWindowViewModel>
|
||||
{
|
||||
public MainWindow Window;
|
||||
|
||||
@@ -29,7 +31,7 @@ namespace Ryujinx.Ava.UI.Views.Main
|
||||
if (VisualRoot is MainWindow window)
|
||||
{
|
||||
Window = window;
|
||||
DataContext = window.ViewModel;
|
||||
ViewModel = window.ViewModel;
|
||||
LocaleManager.Instance.LocaleChanged += () => Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
if (Window.ViewModel.EnableNonGameRunningControls)
|
||||
|
||||
@@ -3,16 +3,15 @@ using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Ryujinx.Ava.Common;
|
||||
using Ryujinx.Ava.UI.Controls;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using Ryujinx.Ava.UI.Windows;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Views.Main
|
||||
{
|
||||
public partial class MainViewControls : UserControl
|
||||
public partial class MainViewControls : RyujinxControl<MainWindowViewModel>
|
||||
{
|
||||
public MainWindowViewModel ViewModel;
|
||||
|
||||
public MainViewControls()
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -24,7 +23,7 @@ namespace Ryujinx.Ava.UI.Views.Main
|
||||
|
||||
if (VisualRoot is MainWindow window)
|
||||
{
|
||||
DataContext = ViewModel = window.ViewModel;
|
||||
ViewModel = window.ViewModel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
xmlns:ui="using:FluentAvalonia.UI.Controls"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Ryujinx.Ava.UI.Controls.ApplicationDataView"
|
||||
x:Class="Ryujinx.Ava.UI.Views.Misc.ApplicationDataView"
|
||||
x:DataType="viewModels:ApplicationDataViewModel">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Margin="0"
|
||||
@@ -4,6 +4,7 @@ using Avalonia.Interactivity;
|
||||
using Avalonia.Styling;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.UI.Controls;
|
||||
using Ryujinx.Ava.UI.Helpers;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using Ryujinx.Ava.UI.Windows;
|
||||
@@ -12,9 +13,9 @@ using Ryujinx.Ava.Utilities.Compat;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Controls
|
||||
namespace Ryujinx.Ava.UI.Views.Misc
|
||||
{
|
||||
public partial class ApplicationDataView : UserControl
|
||||
public partial class ApplicationDataView : RyujinxControl<ApplicationDataViewModel>
|
||||
{
|
||||
public static async Task Show(ApplicationData appData)
|
||||
{
|
||||
@@ -25,7 +26,7 @@ namespace Ryujinx.Ava.UI.Controls
|
||||
SecondaryButtonText = string.Empty,
|
||||
CloseButtonText = LocaleManager.Instance[LocaleKeys.SettingsButtonClose],
|
||||
MinWidth = 256,
|
||||
Content = new ApplicationDataView { DataContext = new ApplicationDataViewModel(appData) }
|
||||
Content = new ApplicationDataView { ViewModel = new ApplicationDataViewModel(appData) }
|
||||
};
|
||||
|
||||
Style closeButton = new(x => x.Name("CloseButton"));
|
||||
@@ -1,5 +1,5 @@
|
||||
<UserControl
|
||||
x:Class="Ryujinx.Ava.UI.Controls.ApplicationGridView"
|
||||
x:Class="Ryujinx.Ava.UI.Views.Misc.ApplicationGridView"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
|
||||
@@ -1,13 +1,15 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Ryujinx.Ava.UI.Controls;
|
||||
using Ryujinx.Ava.UI.Helpers;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Controls
|
||||
namespace Ryujinx.Ava.UI.Views.Misc
|
||||
{
|
||||
public partial class ApplicationGridView : UserControl
|
||||
public partial class ApplicationGridView : RyujinxControl<MainWindowViewModel>
|
||||
{
|
||||
public static readonly RoutedEvent<ApplicationOpenedEventArgs> ApplicationOpenedEvent =
|
||||
RoutedEvent.Register<ApplicationGridView, ApplicationOpenedEventArgs>(nameof(ApplicationOpened), RoutingStrategies.Bubble);
|
||||
@@ -1,5 +1,5 @@
|
||||
<UserControl
|
||||
x:Class="Ryujinx.Ava.UI.Controls.ApplicationListView"
|
||||
x:Class="Ryujinx.Ava.UI.Views.Misc.ApplicationListView"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
@@ -2,6 +2,7 @@ using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Input.Platform;
|
||||
using Avalonia.Interactivity;
|
||||
using Ryujinx.Ava.UI.Controls;
|
||||
using Ryujinx.Ava.UI.Helpers;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||
@@ -9,9 +10,9 @@ using Ryujinx.Ava.Utilities.Compat;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Controls
|
||||
namespace Ryujinx.Ava.UI.Views.Misc
|
||||
{
|
||||
public partial class ApplicationListView : UserControl
|
||||
public partial class ApplicationListView : RyujinxControl<MainWindowViewModel>
|
||||
{
|
||||
public static readonly RoutedEvent<ApplicationOpenedEventArgs> ApplicationOpenedEvent =
|
||||
RoutedEvent.Register<ApplicationListView, ApplicationOpenedEventArgs>(nameof(ApplicationOpened), RoutingStrategies.Bubble);
|
||||
@@ -32,9 +33,6 @@ namespace Ryujinx.Ava.UI.Controls
|
||||
|
||||
private async void PlayabilityStatus_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is not MainWindowViewModel mwvm)
|
||||
return;
|
||||
|
||||
if (sender is not Button { Content: TextBlock playabilityLabel })
|
||||
return;
|
||||
|
||||
@@ -43,16 +41,13 @@ namespace Ryujinx.Ava.UI.Controls
|
||||
|
||||
private async void IdString_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is not MainWindowViewModel mwvm)
|
||||
return;
|
||||
|
||||
if (sender is not Button { Content: TextBlock idText })
|
||||
return;
|
||||
|
||||
if (!RyujinxApp.IsClipboardAvailable(out IClipboard clipboard))
|
||||
return;
|
||||
|
||||
ApplicationData appData = mwvm.Applications.FirstOrDefault(it => it.IdString == idText.Text);
|
||||
ApplicationData appData = ViewModel.Applications.FirstOrDefault(it => it.IdString == idText.Text);
|
||||
if (appData is null)
|
||||
return;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
xmlns:models="using:Ryujinx.Ava.Common.Models"
|
||||
xmlns:viewModels="using:Ryujinx.Ava.UI.ViewModels"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Ryujinx.Ava.UI.Controls.DlcSelectView"
|
||||
x:Class="Ryujinx.Ava.UI.Views.Misc.DlcSelectView"
|
||||
x:DataType="viewModels:DlcSelectViewModel">
|
||||
<Grid RowDefinitions="*,Auto,*">
|
||||
<TextBlock
|
||||
@@ -3,14 +3,15 @@ using Avalonia.Styling;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.Common.Models;
|
||||
using Ryujinx.Ava.UI.Controls;
|
||||
using Ryujinx.Ava.UI.Helpers;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Controls
|
||||
namespace Ryujinx.Ava.UI.Views.Misc
|
||||
{
|
||||
public partial class DlcSelectView : UserControl
|
||||
public partial class DlcSelectView : RyujinxControl<DlcSelectViewModel>
|
||||
{
|
||||
public DlcSelectView()
|
||||
{
|
||||
@@ -28,7 +29,7 @@ namespace Ryujinx.Ava.UI.Controls
|
||||
PrimaryButtonText = LocaleManager.Instance[LocaleKeys.Continue],
|
||||
SecondaryButtonText = string.Empty,
|
||||
CloseButtonText = string.Empty,
|
||||
Content = new DlcSelectView { DataContext = viewModel }
|
||||
Content = new DlcSelectView { ViewModel = viewModel }
|
||||
};
|
||||
|
||||
Style closeButton = new(x => x.Name("CloseButton"));
|
||||
@@ -13,13 +13,12 @@ using UserProfile = Ryujinx.Ava.UI.Models.UserProfile;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Views.User
|
||||
{
|
||||
public partial class UserEditorView : UserControl
|
||||
public partial class UserEditorView : RyujinxControl<TempProfile>
|
||||
{
|
||||
private NavigationDialogHost _parent;
|
||||
private UserProfile _profile;
|
||||
private bool _isNewUser;
|
||||
|
||||
public TempProfile TempProfile { get; set; }
|
||||
|
||||
public static uint MaxProfileNameLength => 0x20;
|
||||
public bool IsDeletable => _profile.UserId != AccountManager.DefaultUserId;
|
||||
|
||||
@@ -42,7 +41,7 @@ namespace Ryujinx.Ava.UI.Views.User
|
||||
(NavigationDialogHost parent, UserProfile profile, bool isNewUser) = ((NavigationDialogHost parent, UserProfile profile, bool isNewUser))arg.Parameter;
|
||||
_isNewUser = isNewUser;
|
||||
_profile = profile;
|
||||
TempProfile = new TempProfile(_profile);
|
||||
ViewModel = new TempProfile(_profile);
|
||||
|
||||
_parent = parent;
|
||||
break;
|
||||
@@ -51,8 +50,6 @@ namespace Ryujinx.Ava.UI.Views.User
|
||||
((ContentDialog)_parent.Parent).Title = $"{LocaleManager.Instance[LocaleKeys.UserProfileWindowTitle]} - " +
|
||||
$"{(_isNewUser ? LocaleManager.Instance[LocaleKeys.UserEditorTitleCreate] : LocaleManager.Instance[LocaleKeys.UserEditorTitle])}";
|
||||
|
||||
DataContext = TempProfile;
|
||||
|
||||
AddPictureButton.IsVisible = _isNewUser;
|
||||
ChangePictureButton.IsVisible = !_isNewUser;
|
||||
IdLabel.IsVisible = _profile != null;
|
||||
@@ -72,7 +69,7 @@ namespace Ryujinx.Ava.UI.Views.User
|
||||
{
|
||||
if (_isNewUser)
|
||||
{
|
||||
if (TempProfile.Name != String.Empty || TempProfile.Image != null)
|
||||
if (ViewModel.Name != string.Empty || ViewModel.Image != null)
|
||||
{
|
||||
if (await ContentDialogHelper.CreateChoiceDialog(
|
||||
LocaleManager.Instance[LocaleKeys.DialogUserProfileUnsavedChangesTitle],
|
||||
@@ -89,7 +86,7 @@ namespace Ryujinx.Ava.UI.Views.User
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_profile.Name != TempProfile.Name || _profile.Image != TempProfile.Image)
|
||||
if (_profile.Name != ViewModel.Name || _profile.Image != ViewModel.Image)
|
||||
{
|
||||
if (await ContentDialogHelper.CreateChoiceDialog(
|
||||
LocaleManager.Instance[LocaleKeys.DialogUserProfileUnsavedChangesTitle],
|
||||
@@ -115,31 +112,31 @@ namespace Ryujinx.Ava.UI.Views.User
|
||||
{
|
||||
DataValidationErrors.ClearErrors(NameBox);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(TempProfile.Name))
|
||||
if (string.IsNullOrWhiteSpace(ViewModel.Name))
|
||||
{
|
||||
DataValidationErrors.SetError(NameBox, new DataValidationException(LocaleManager.Instance[LocaleKeys.UserProfileEmptyNameError]));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (TempProfile.Image == null)
|
||||
if (ViewModel.Image == null)
|
||||
{
|
||||
_parent.Navigate(typeof(UserProfileImageSelectorView), (_parent, TempProfile));
|
||||
_parent.Navigate(typeof(UserProfileImageSelectorView), (_parent, ViewModel));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (_profile != null && !_isNewUser)
|
||||
{
|
||||
_profile.Name = TempProfile.Name;
|
||||
_profile.Image = TempProfile.Image;
|
||||
_profile.Name = ViewModel.Name;
|
||||
_profile.Image = ViewModel.Image;
|
||||
_profile.UpdateState();
|
||||
_parent.AccountManager.SetUserName(_profile.UserId, _profile.Name);
|
||||
_parent.AccountManager.SetUserImage(_profile.UserId, _profile.Image);
|
||||
}
|
||||
else if (_isNewUser)
|
||||
{
|
||||
_parent.AccountManager.AddUser(TempProfile.Name, TempProfile.Image, TempProfile.UserId);
|
||||
_parent.AccountManager.AddUser(ViewModel.Name, ViewModel.Image, ViewModel.UserId);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -151,7 +148,7 @@ namespace Ryujinx.Ava.UI.Views.User
|
||||
|
||||
public void SelectProfileImage()
|
||||
{
|
||||
_parent.Navigate(typeof(UserProfileImageSelectorView), (_parent, TempProfile));
|
||||
_parent.Navigate(typeof(UserProfileImageSelectorView), (_parent, ViewModel));
|
||||
}
|
||||
|
||||
private void ChangePictureButton_Click(object sender, RoutedEventArgs e)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using FluentAvalonia.UI.Navigation;
|
||||
@@ -11,7 +10,7 @@ using System.IO;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Views.User
|
||||
{
|
||||
public partial class UserFirmwareAvatarSelectorView : UserControl
|
||||
public partial class UserFirmwareAvatarSelectorView : RyujinxControl<UserFirmwareAvatarSelectorViewModel>
|
||||
{
|
||||
private NavigationDialogHost _parent;
|
||||
private TempProfile _profile;
|
||||
@@ -20,8 +19,6 @@ namespace Ryujinx.Ava.UI.Views.User
|
||||
{
|
||||
ContentManager = contentManager;
|
||||
|
||||
DataContext = ViewModel;
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
@@ -55,8 +52,6 @@ namespace Ryujinx.Ava.UI.Views.User
|
||||
|
||||
public ContentManager ContentManager { get; private set; }
|
||||
|
||||
internal UserFirmwareAvatarSelectorViewModel ViewModel { get; set; }
|
||||
|
||||
private void GoBack(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_parent.GoBack();
|
||||
|
||||
@@ -15,14 +15,12 @@ using System.IO;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Views.User
|
||||
{
|
||||
public partial class UserProfileImageSelectorView : UserControl
|
||||
public partial class UserProfileImageSelectorView : RyujinxControl<UserProfileImageSelectorViewModel>
|
||||
{
|
||||
private ContentManager _contentManager;
|
||||
private NavigationDialogHost _parent;
|
||||
private TempProfile _profile;
|
||||
|
||||
internal UserProfileImageSelectorViewModel ViewModel { get; private set; }
|
||||
|
||||
public UserProfileImageSelectorView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
@@ -4,10 +4,11 @@ using FluentAvalonia.UI.Controls;
|
||||
using FluentAvalonia.UI.Navigation;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.UI.Controls;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Views.User
|
||||
{
|
||||
public partial class UserRecovererView : UserControl
|
||||
public partial class UserRecovererView : RyujinxControl<UserProfileViewModel>
|
||||
{
|
||||
private NavigationDialogHost _parent;
|
||||
|
||||
|
||||
@@ -23,10 +23,8 @@ using UserId = LibHac.Fs.UserId;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Views.User
|
||||
{
|
||||
public partial class UserSaveManagerView : UserControl
|
||||
public partial class UserSaveManagerView : RyujinxControl<UserSaveManagerViewModel>
|
||||
{
|
||||
internal UserSaveManagerViewModel ViewModel { get; private set; }
|
||||
|
||||
private AccountManager _accountManager;
|
||||
private HorizonClient _horizonClient;
|
||||
private VirtualFileSystem _virtualFileSystem;
|
||||
@@ -66,7 +64,7 @@ namespace Ryujinx.Ava.UI.Views.User
|
||||
|
||||
public void LoadSaves()
|
||||
{
|
||||
ViewModel.Saves.Clear();
|
||||
Dispatcher.UIThread.Post(() => ViewModel.Saves.Clear());
|
||||
ObservableCollection<SaveModel> saves = [];
|
||||
SaveDataFilter saveDataFilter = SaveDataFilter.Make(
|
||||
programId: default,
|
||||
|
||||
@@ -11,12 +11,10 @@ using Button = Avalonia.Controls.Button;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Views.User
|
||||
{
|
||||
public partial class UserSelectorViews : UserControl
|
||||
public partial class UserSelectorViews : RyujinxControl<UserProfileViewModel>
|
||||
{
|
||||
private NavigationDialogHost _parent;
|
||||
|
||||
public UserProfileViewModel ViewModel { get; set; }
|
||||
|
||||
public UserSelectorViews()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
||||
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
|
||||
xmlns:main="clr-namespace:Ryujinx.Ava.UI.Views.Main"
|
||||
xmlns:viewsMisc="clr-namespace:Ryujinx.Ava.UI.Views.Misc"
|
||||
Cursor="{Binding Cursor}"
|
||||
Title="{Binding Title}"
|
||||
WindowState="{Binding WindowState}"
|
||||
@@ -73,7 +74,7 @@
|
||||
<main:MainViewControls
|
||||
Name="ViewControls"
|
||||
Grid.Row="0"/>
|
||||
<controls:ApplicationListView
|
||||
<viewsMisc:ApplicationListView
|
||||
x:Name="ApplicationList"
|
||||
Grid.Row="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
@@ -81,7 +82,7 @@
|
||||
HorizontalContentAlignment="Stretch"
|
||||
VerticalContentAlignment="Stretch"
|
||||
IsVisible="{Binding IsList}" />
|
||||
<controls:ApplicationGridView
|
||||
<viewsMisc:ApplicationGridView
|
||||
x:Name="ApplicationGrid"
|
||||
Grid.Row="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<Window
|
||||
x:Class="Ryujinx.Ava.UI.Controls.UpdateWaitWindow"
|
||||
x:Class="Ryujinx.Ava.UI.Windows.UpdateWaitWindow"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
@@ -1,8 +1,7 @@
|
||||
using Avalonia.Controls;
|
||||
using Ryujinx.Ava.UI.Windows;
|
||||
using System.Threading;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Controls
|
||||
namespace Ryujinx.Ava.UI.Windows
|
||||
{
|
||||
public partial class UpdateWaitWindow : StyleableWindow
|
||||
{
|
||||
@@ -1,6 +1,6 @@
|
||||
using ARMeilleure;
|
||||
using Gommon;
|
||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||
using LibHac.Tools.FsSystem;
|
||||
using Ryujinx.Ava.Utilities.Configuration.System;
|
||||
using Ryujinx.Ava.Utilities.Configuration.UI;
|
||||
using Ryujinx.Common;
|
||||
@@ -11,6 +11,7 @@ using Ryujinx.Common.Helper;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Common.Utilities;
|
||||
using Ryujinx.HLE;
|
||||
using Ryujinx.HLE.HOS.SystemState;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using RyuLogger = Ryujinx.Common.Logging.Logger;
|
||||
@@ -19,7 +20,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||
{
|
||||
public partial class ConfigurationState
|
||||
{
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// UI configuration section
|
||||
/// </summary>
|
||||
public class UISection
|
||||
@@ -838,5 +839,35 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||
EnableHardwareAcceleration = new ReactiveObject<bool>();
|
||||
HideCursor = new ReactiveObject<HideCursorMode>();
|
||||
}
|
||||
|
||||
public HleConfiguration CreateHleConfiguration() =>
|
||||
new(
|
||||
System.DramSize,
|
||||
(SystemLanguage)System.Language.Value,
|
||||
(RegionCode)System.Region.Value,
|
||||
Graphics.VSyncMode,
|
||||
System.EnableDockedMode,
|
||||
System.EnablePtc,
|
||||
System.EnableInternetAccess,
|
||||
System.EnableFsIntegrityChecks
|
||||
? IntegrityCheckLevel.ErrorOnInvalid
|
||||
: IntegrityCheckLevel.None,
|
||||
System.FsGlobalAccessLogMode,
|
||||
System.MatchSystemTime
|
||||
? 0
|
||||
: System.SystemTimeOffset,
|
||||
System.TimeZone,
|
||||
System.MemoryManagerMode,
|
||||
System.IgnoreMissingServices,
|
||||
Graphics.AspectRatio,
|
||||
System.AudioVolume,
|
||||
System.UseHypervisor,
|
||||
Multiplayer.LanInterfaceId,
|
||||
Multiplayer.Mode,
|
||||
Multiplayer.DisableP2p,
|
||||
Multiplayer.LdnPassphrase,
|
||||
Instance.Multiplayer.GetLdnServer(),
|
||||
Instance.Graphics.CustomVSyncInterval,
|
||||
Instance.Hacks.ShowDirtyHacks ? Instance.Hacks.EnabledHacks : null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,5 +327,5 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||
|
||||
return GraphicsBackend.OpenGl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user