mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-12-12 07:36:59 +00:00
game dir setup
known bugs are a missing prod.keys popup after setup (how), as well as the dialog for autoload kinda cluttering up the screen after you hit next on the game dir page
This commit is contained in:
parent
ba9334e73d
commit
e2f406f070
10 changed files with 347 additions and 13 deletions
|
|
@ -25217,6 +25217,31 @@
|
|||
"zh_TW": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "SetupWizardGameDirsPageTitle",
|
||||
"Translations": {
|
||||
"ar_SA": "",
|
||||
"de_DE": "",
|
||||
"el_GR": "",
|
||||
"en_US": "Game, Update, and DLC Paths",
|
||||
"es_ES": "",
|
||||
"fr_FR": "",
|
||||
"he_IL": "",
|
||||
"it_IT": "",
|
||||
"ja_JP": "",
|
||||
"ko_KR": "",
|
||||
"no_NO": "",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
"zh_CN": "",
|
||||
"zh_TW": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "SetupWizardFinalPageTitle",
|
||||
"Translations": {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@ namespace Ryujinx.Common
|
|||
public const string DumpFirmwareWikiUrl =
|
||||
"https://git.ryujinx.app/ryubing/ryujinx/-/wikis/Dumping/Firmware";
|
||||
|
||||
public const string DumpContentWikiUrl =
|
||||
"https://git.ryujinx.app/ryubing/ryujinx/-/wikis/Dumping/Games,-Updates-&-DLC";
|
||||
|
||||
public const string MultiplayerWikiUrl =
|
||||
"https://git.ryujinx.app/ryubing/ryujinx/-/wikis/Multiplayer-(LDN-Local-Wireless)-Guide";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,6 +99,14 @@ namespace Ryujinx.Ava.UI.SetupWizard.Pages
|
|||
|
||||
public override Result CompleteStep()
|
||||
{
|
||||
if (string.IsNullOrEmpty(FirmwareSourcePath) && RyujinxSetupWizard.HasFirmware)
|
||||
{
|
||||
NotificationManager.Information(
|
||||
title: LocaleManager.Instance[LocaleKeys.DialogConfirmationTitle],
|
||||
"Skipped setting up firmware as you already have a valid firmware installation and did not choose a folder or file to install from.\n\nClick 'Back' if you wish to overwrite your firmware.");
|
||||
return Result.Success; // This handles the user selecting no file/dir and just hitting Next.
|
||||
}
|
||||
|
||||
if (!Directory.Exists(FirmwareSourcePath))
|
||||
return Result.Fail;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,107 @@
|
|||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
|
||||
xmlns:pages="clr-namespace:Ryujinx.UI.SetupWizard.Pages"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Ryujinx.UI.SetupWizard.Pages.SetupGameDirsPage"
|
||||
x:DataType="pages:SetupGameDirsPageContext">
|
||||
<StackPanel
|
||||
Margin="10"
|
||||
Spacing="10"
|
||||
Orientation="Vertical" HorizontalAlignment="Stretch">
|
||||
<TextBlock Classes="h1" Text="{ext:Locale SettingsTabGeneralGameDirectories}" />
|
||||
|
||||
<StackPanel
|
||||
Margin="10,0,0,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
Orientation="Vertical"
|
||||
Spacing="10">
|
||||
<ListBox
|
||||
Name="GameDirsList"
|
||||
MinHeight="120"
|
||||
ItemsSource="{Binding GameDirs}">
|
||||
<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"
|
||||
Watermark="{ext:Locale AddGameDirBoxTooltip}"
|
||||
VerticalAlignment="Stretch" />
|
||||
<Button
|
||||
Name="AddGameDirButton"
|
||||
Grid.Column="1"
|
||||
MinWidth="90"
|
||||
Margin="10,0,0,0">
|
||||
<TextBlock HorizontalAlignment="Center"
|
||||
Text="{ext:Locale SettingsTabGeneralAdd}" />
|
||||
</Button>
|
||||
<Button
|
||||
Name="RemoveGameDirButton"
|
||||
Grid.Column="2"
|
||||
MinWidth="90"
|
||||
Margin="5,0,0,0"
|
||||
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}" />
|
||||
</StackPanel>
|
||||
<TextBlock Foreground="{DynamicResource SecondaryTextColor}"
|
||||
Text="{ext:Locale SettingsTabGeneralAutoloadNote}" />
|
||||
</StackPanel>
|
||||
<StackPanel
|
||||
Margin="10,0,0,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
Orientation="Vertical"
|
||||
Spacing="10">
|
||||
<ListBox
|
||||
Name="AutoloadDirsList"
|
||||
MinHeight="100"
|
||||
ItemsSource="{Binding UpdateAndDlcDirs}">
|
||||
<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"
|
||||
Watermark="{ext:Locale AddGameDirBoxTooltip}"
|
||||
VerticalAlignment="Stretch" />
|
||||
<Button
|
||||
Name="AddAutoloadDirButton"
|
||||
Grid.Column="1"
|
||||
MinWidth="90"
|
||||
Margin="10,0,0,0">
|
||||
<TextBlock HorizontalAlignment="Center"
|
||||
Text="{ext:Locale SettingsTabGeneralAdd}" />
|
||||
</Button>
|
||||
<Button
|
||||
Name="RemoveAutoloadDirButton"
|
||||
Grid.Column="2"
|
||||
MinWidth="90"
|
||||
Margin="5,0,0,0"
|
||||
Click="RemoveAutoloadDirButton_OnClick">
|
||||
<TextBlock HorizontalAlignment="Center"
|
||||
Text="{ext:Locale SettingsTabGeneralRemove}" />
|
||||
</Button>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
using Avalonia.Collections;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Platform.Storage;
|
||||
using Ryujinx.Ava;
|
||||
using Ryujinx.Ava.UI.Controls;
|
||||
using Ryujinx.Ava.UI.Helpers;
|
||||
using Ryujinx.Ava.Utilities;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.UI.SetupWizard.Pages
|
||||
{
|
||||
public partial class SetupGameDirsPage : RyujinxControl<SetupGameDirsPageContext>
|
||||
{
|
||||
public SetupGameDirsPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
AddGameDirButton.Command =
|
||||
Commands.Create(() => AddDirButton(GameDirPathBox, ViewModel.GameDirs));
|
||||
AddAutoloadDirButton.Command =
|
||||
Commands.Create(() => AddDirButton(AutoloadDirPathBox, ViewModel.UpdateAndDlcDirs));
|
||||
}
|
||||
|
||||
private async Task AddDirButton(TextBox addDirBox, ObservableCollection<string> directories)
|
||||
{
|
||||
string path = addDirBox.Text;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(path) && Directory.Exists(path) && !directories.Contains(path))
|
||||
{
|
||||
directories.Add(path);
|
||||
|
||||
addDirBox.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
Gommon.Optional<IStorageFolder> folder = await RyujinxApp.MainWindow.ViewModel.StorageProvider.OpenSingleFolderPickerAsync();
|
||||
|
||||
if (folder.HasValue)
|
||||
{
|
||||
directories.Add(folder.Value.Path.LocalPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveGameDirButton_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
int oldIndex = GameDirsList.SelectedIndex;
|
||||
|
||||
foreach (string path in new List<string>(GameDirsList.SelectedItems.Cast<string>()))
|
||||
{
|
||||
ViewModel.GameDirs.Remove(path);
|
||||
}
|
||||
|
||||
if (GameDirsList.ItemCount > 0)
|
||||
{
|
||||
GameDirsList.SelectedIndex = oldIndex < GameDirsList.ItemCount ? oldIndex : 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveAutoloadDirButton_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
int oldIndex = AutoloadDirsList.SelectedIndex;
|
||||
|
||||
foreach (string path in new List<string>(AutoloadDirsList.SelectedItems.Cast<string>()))
|
||||
{
|
||||
ViewModel.UpdateAndDlcDirs.Remove(path);
|
||||
}
|
||||
|
||||
if (AutoloadDirsList.ItemCount > 0)
|
||||
{
|
||||
AutoloadDirsList.SelectedIndex = oldIndex < AutoloadDirsList.ItemCount ? oldIndex : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
using Avalonia.Controls;
|
||||
using Avalonia.Layout;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using System.Collections.ObjectModel;
|
||||
using Gommon;
|
||||
using Ryujinx.Ava;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.Systems.Configuration;
|
||||
using Ryujinx.Ava.UI.Helpers;
|
||||
using Ryujinx.Ava.UI.SetupWizard;
|
||||
using Ryujinx.Common;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Ryujinx.UI.SetupWizard.Pages
|
||||
{
|
||||
public partial class SetupGameDirsPageContext() : SetupWizardPageContext(LocaleKeys.SetupWizardGameDirsPageTitle)
|
||||
{
|
||||
[ObservableProperty]
|
||||
public partial ObservableCollection<string> GameDirs { get; set; }
|
||||
= new(ConfigurationState.Instance.UI.GameDirs);
|
||||
[ObservableProperty]
|
||||
public partial ObservableCollection<string> UpdateAndDlcDirs { get; set; }
|
||||
= new(ConfigurationState.Instance.UI.AutoloadDirs);
|
||||
|
||||
public override Result CompleteStep()
|
||||
{
|
||||
if (GameDirs.Count is 0)
|
||||
{
|
||||
NotificationManager.Error("At least one folder for games must be selected; otherwise the UI will be empty.");
|
||||
return Result.Failure(RetryError.Shared);
|
||||
}
|
||||
|
||||
ConfigurationState.Instance.UI.GameDirs.Value = GameDirs.ToList();
|
||||
ConfigurationState.Instance.UI.AutoloadDirs.Value = UpdateAndDlcDirs.ToList();
|
||||
OwningWizard.SignalConfigModified();
|
||||
RyujinxApp.MainWindow.LoadApplications();
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public override object CreateHelpContent()
|
||||
{
|
||||
Grid grid = new()
|
||||
{
|
||||
RowDefinitions = [new(GridLength.Auto), new(GridLength.Auto)],
|
||||
HorizontalAlignment = HorizontalAlignment.Center
|
||||
};
|
||||
|
||||
grid.Children.Add(new TextBlock
|
||||
{
|
||||
Text = "Not sure how to get your games, updates, and/or DLC onto your PC?",
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
GridRow = 0
|
||||
});
|
||||
|
||||
grid.Children.Add(new HyperlinkButton
|
||||
{
|
||||
Content = "Click here to view a guide.",
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
NavigateUri = new Uri(SharedConstants.DumpFirmwareWikiUrl),
|
||||
GridRow = 1
|
||||
});
|
||||
|
||||
return grid;
|
||||
}
|
||||
}
|
||||
|
||||
public struct RetryError : IErrorState
|
||||
{
|
||||
public static readonly RetryError Shared = new();
|
||||
}
|
||||
}
|
||||
|
|
@ -21,11 +21,6 @@ namespace Ryujinx.Ava.UI.SetupWizard.Pages
|
|||
{
|
||||
public partial class SetupKeysPageContext() : SetupWizardPageContext(LocaleKeys.SetupWizardKeysPageTitle)
|
||||
{
|
||||
public override Result CompleteStep() =>
|
||||
Directory.Exists(KeysFolderPath)
|
||||
? InstallKeys(KeysFolderPath)
|
||||
: Result.Fail;
|
||||
|
||||
public override object CreateHelpContent()
|
||||
{
|
||||
Grid grid = new()
|
||||
|
|
@ -70,8 +65,19 @@ namespace Ryujinx.Ava.UI.SetupWizard.Pages
|
|||
}
|
||||
}
|
||||
|
||||
private Result InstallKeys(string directory)
|
||||
public override Result CompleteStep()
|
||||
{
|
||||
if (string.IsNullOrEmpty(KeysFolderPath) && RyujinxApp.MainWindow.VirtualFileSystem.HasKeySet)
|
||||
{
|
||||
NotificationManager.Information(
|
||||
title: LocaleManager.Instance[LocaleKeys.DialogConfirmationTitle],
|
||||
"Skipped setting up keys as you already have a valid key installation and did not choose a folder to install from.\n\nClick 'Back' if you wish to reinstall your keys.");
|
||||
return Result.Success; // This handles the user selecting no folder and just hitting Next.
|
||||
}
|
||||
|
||||
if (!Directory.Exists(KeysFolderPath))
|
||||
return Result.Fail;
|
||||
|
||||
try
|
||||
{
|
||||
string systemDirectory = AppDataManager.KeysDirPath;
|
||||
|
|
@ -81,9 +87,9 @@ namespace Ryujinx.Ava.UI.SetupWizard.Pages
|
|||
systemDirectory = AppDataManager.KeysDirPathUser;
|
||||
}
|
||||
|
||||
Logger.Info?.Print(LogClass.Application, $"Installing keys from {directory}");
|
||||
Logger.Info?.Print(LogClass.Application, $"Installing keys from {KeysFolderPath}");
|
||||
|
||||
ContentManager.InstallKeys(directory, systemDirectory);
|
||||
ContentManager.InstallKeys(KeysFolderPath, systemDirectory);
|
||||
|
||||
NotificationManager.Information(
|
||||
title: LocaleManager.Instance[LocaleKeys.RyujinxInfo],
|
||||
|
|
@ -105,7 +111,7 @@ namespace Ryujinx.Ava.UI.SetupWizard.Pages
|
|||
if (ex is FormatException)
|
||||
{
|
||||
message = LocaleManager.Instance.UpdateAndGetDynamicValue(
|
||||
LocaleKeys.DialogKeysInstallerKeysNotFoundErrorMessage, directory);
|
||||
LocaleKeys.DialogKeysInstallerKeysNotFoundErrorMessage, KeysFolderPath);
|
||||
}
|
||||
|
||||
NotificationManager.Error(message, waitingExit: true);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.UI.SetupWizard.Pages;
|
||||
using Ryujinx.UI.SetupWizard.Pages;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.UI.SetupWizard
|
||||
|
|
@ -51,6 +51,34 @@ namespace Ryujinx.Ava.UI.SetupWizard
|
|||
return true;
|
||||
}
|
||||
|
||||
private async ValueTask<bool> SetupGameDirs()
|
||||
{
|
||||
|
||||
if (!HasFirmware)
|
||||
{
|
||||
NotificationManager.Error("Firmware still seems to not be installed. Please try again.");
|
||||
return false;
|
||||
}
|
||||
|
||||
Retry:
|
||||
bool result =
|
||||
await NextPage<SetupGameDirsPage, SetupGameDirsPageContext>(out SetupGameDirsPageContext gdContext)
|
||||
.Show();
|
||||
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
var res = gdContext.CompleteStep();
|
||||
|
||||
if (res.IsOf<RetryError>())
|
||||
return false;
|
||||
|
||||
if (!res)
|
||||
goto Retry;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private ValueTask<bool> Finish()
|
||||
=> NextPage<SetupFinishedPage, SetupFinishedPageContext>(out _)
|
||||
.WithHelpButtonVisible(false)
|
||||
|
|
|
|||
|
|
@ -82,9 +82,13 @@ namespace Ryujinx.Ava.UI.SetupWizard
|
|||
Firmware:
|
||||
if (!await SetupFirmware())
|
||||
goto Keys;
|
||||
|
||||
GameDirs:
|
||||
if (!await SetupGameDirs())
|
||||
goto Firmware;
|
||||
|
||||
if (!await Finish())
|
||||
goto Firmware;
|
||||
goto GameDirs;
|
||||
|
||||
Return:
|
||||
if (_configWasModified)
|
||||
|
|
|
|||
|
|
@ -40,8 +40,8 @@ namespace Ryujinx.Ava.UI.SetupWizard
|
|||
{
|
||||
RyujinxSetupWizardWindow window = new();
|
||||
window.DataContext = setupWizard = new RyujinxSetupWizard(window, overwriteMode);
|
||||
window.Height = 600;
|
||||
window.Width = 750;
|
||||
window.Height = 700;
|
||||
window.Width = 825;
|
||||
return window;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue