Set autoload dirs explicitly

This commit is contained in:
Jimmy Reichley 2024-08-18 20:45:48 -04:00
parent 130135699a
commit eb5487229e
No known key found for this signature in database
GPG key ID: 67715DC5A329803C
8 changed files with 173 additions and 27 deletions

View file

@ -15,7 +15,7 @@ namespace Ryujinx.UI.Common.Configuration
/// <summary> /// <summary>
/// The current version of the file format /// The current version of the file format
/// </summary> /// </summary>
public const int CurrentVersion = 52; public const int CurrentVersion = 53;
/// <summary> /// <summary>
/// Version of the configuration file format /// Version of the configuration file format
@ -267,6 +267,11 @@ namespace Ryujinx.UI.Common.Configuration
/// </summary> /// </summary>
public List<string> GameDirs { get; set; } public List<string> GameDirs { get; set; }
/// <summary>
/// A list of directories containing DLC/updates the user wants to autoload during library refreshes
/// </summary>
public List<string> AutoloadDirs { get; set; }
/// <summary> /// <summary>
/// A list of file types to be hidden in the games List /// A list of file types to be hidden in the games List
/// </summary> /// </summary>

View file

@ -122,6 +122,11 @@ namespace Ryujinx.UI.Common.Configuration
/// </summary> /// </summary>
public ReactiveObject<List<string>> GameDirs { get; private set; } public ReactiveObject<List<string>> GameDirs { get; private set; }
/// <summary>
/// A list of directories containing DLC/updates the user wants to autoload during library refreshes
/// </summary>
public ReactiveObject<List<string>> AutoloadDirs { get; private set; }
/// <summary> /// <summary>
/// A list of file types to be hidden in the games List /// A list of file types to be hidden in the games List
/// </summary> /// </summary>
@ -192,6 +197,7 @@ namespace Ryujinx.UI.Common.Configuration
GuiColumns = new Columns(); GuiColumns = new Columns();
ColumnSort = new ColumnSortSettings(); ColumnSort = new ColumnSortSettings();
GameDirs = new ReactiveObject<List<string>>(); GameDirs = new ReactiveObject<List<string>>();
AutoloadDirs = new ReactiveObject<List<string>>();
ShownFileTypes = new ShownFileTypeSettings(); ShownFileTypes = new ShownFileTypeSettings();
WindowStartup = new WindowStartupSettings(); WindowStartup = new WindowStartupSettings();
EnableCustomTheme = new ReactiveObject<bool>(); EnableCustomTheme = new ReactiveObject<bool>();
@ -735,6 +741,7 @@ namespace Ryujinx.UI.Common.Configuration
SortAscending = UI.ColumnSort.SortAscending, SortAscending = UI.ColumnSort.SortAscending,
}, },
GameDirs = UI.GameDirs, GameDirs = UI.GameDirs,
AutoloadDirs = UI.AutoloadDirs,
ShownFileTypes = new ShownFileTypes ShownFileTypes = new ShownFileTypes
{ {
NSP = UI.ShownFileTypes.NSP, NSP = UI.ShownFileTypes.NSP,
@ -844,6 +851,7 @@ namespace Ryujinx.UI.Common.Configuration
UI.ColumnSort.SortColumnId.Value = 0; UI.ColumnSort.SortColumnId.Value = 0;
UI.ColumnSort.SortAscending.Value = false; UI.ColumnSort.SortAscending.Value = false;
UI.GameDirs.Value = new List<string>(); UI.GameDirs.Value = new List<string>();
UI.AutoloadDirs.Value = new List<string>();
UI.ShownFileTypes.NSP.Value = true; UI.ShownFileTypes.NSP.Value = true;
UI.ShownFileTypes.PFS0.Value = true; UI.ShownFileTypes.PFS0.Value = true;
UI.ShownFileTypes.XCI.Value = true; UI.ShownFileTypes.XCI.Value = true;
@ -1494,6 +1502,15 @@ namespace Ryujinx.UI.Common.Configuration
configurationFileUpdated = true; configurationFileUpdated = true;
} }
if (configurationFileFormat.Version < 53)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 53.");
configurationFileFormat.AutoloadDirs = new();
configurationFileUpdated = true;
}
Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog; Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
Graphics.ResScale.Value = configurationFileFormat.ResScale; Graphics.ResScale.Value = configurationFileFormat.ResScale;
Graphics.ResScaleCustom.Value = configurationFileFormat.ResScaleCustom; Graphics.ResScaleCustom.Value = configurationFileFormat.ResScaleCustom;
@ -1556,6 +1573,7 @@ namespace Ryujinx.UI.Common.Configuration
UI.ColumnSort.SortColumnId.Value = configurationFileFormat.ColumnSort.SortColumnId; UI.ColumnSort.SortColumnId.Value = configurationFileFormat.ColumnSort.SortColumnId;
UI.ColumnSort.SortAscending.Value = configurationFileFormat.ColumnSort.SortAscending; UI.ColumnSort.SortAscending.Value = configurationFileFormat.ColumnSort.SortAscending;
UI.GameDirs.Value = configurationFileFormat.GameDirs; UI.GameDirs.Value = configurationFileFormat.GameDirs;
UI.AutoloadDirs.Value = configurationFileFormat.AutoloadDirs;
UI.ShownFileTypes.NSP.Value = configurationFileFormat.ShownFileTypes.NSP; UI.ShownFileTypes.NSP.Value = configurationFileFormat.ShownFileTypes.NSP;
UI.ShownFileTypes.PFS0.Value = configurationFileFormat.ShownFileTypes.PFS0; UI.ShownFileTypes.PFS0.Value = configurationFileFormat.ShownFileTypes.PFS0;
UI.ShownFileTypes.XCI.Value = configurationFileFormat.ShownFileTypes.XCI; UI.ShownFileTypes.XCI.Value = configurationFileFormat.ShownFileTypes.XCI;

View file

@ -106,6 +106,7 @@
"SettingsTabGeneralHideCursorOnIdle": "On Idle", "SettingsTabGeneralHideCursorOnIdle": "On Idle",
"SettingsTabGeneralHideCursorAlways": "Always", "SettingsTabGeneralHideCursorAlways": "Always",
"SettingsTabGeneralGameDirectories": "Game Directories", "SettingsTabGeneralGameDirectories": "Game Directories",
"SettingsTabGeneralAutoloadDirectories": "Autoload DLC/Updates Directories",
"SettingsTabGeneralAdd": "Add", "SettingsTabGeneralAdd": "Add",
"SettingsTabGeneralRemove": "Remove", "SettingsTabGeneralRemove": "Remove",
"SettingsTabSystem": "System", "SettingsTabSystem": "System",
@ -559,6 +560,9 @@
"AddGameDirBoxTooltip": "Enter a game directory to add to the list", "AddGameDirBoxTooltip": "Enter a game directory to add to the list",
"AddGameDirTooltip": "Add a game directory to the list", "AddGameDirTooltip": "Add a game directory to the list",
"RemoveGameDirTooltip": "Remove selected game directory", "RemoveGameDirTooltip": "Remove selected game directory",
"AddAutoloadDirBoxTooltip": "Enter an autoload directory to add to the list",
"AddAutoloadDirTooltip": "Add an autoload directory to the list",
"RemoveAutoloadDirTooltip": "Remove selected autoload directory",
"CustomThemeCheckTooltip": "Use a custom Avalonia theme for the GUI to change the appearance of the emulator menus", "CustomThemeCheckTooltip": "Use a custom Avalonia theme for the GUI to change the appearance of the emulator menus",
"CustomThemePathTooltip": "Path to custom GUI theme", "CustomThemePathTooltip": "Path to custom GUI theme",
"CustomThemeBrowseTooltip": "Browse for a custom GUI theme", "CustomThemeBrowseTooltip": "Browse for a custom GUI theme",

View file

@ -44,7 +44,8 @@ namespace Ryujinx.Ava.UI.ViewModels
private int _graphicsBackendMultithreadingIndex; private int _graphicsBackendMultithreadingIndex;
private float _volume; private float _volume;
private bool _isVulkanAvailable = true; private bool _isVulkanAvailable = true;
private bool _directoryChanged; private bool _gameDirectoryChanged;
private bool _autoloadDirectoryChanged;
private readonly List<string> _gpuIds = new(); private readonly List<string> _gpuIds = new();
private int _graphicsBackendIndex; private int _graphicsBackendIndex;
private int _scalingFilter; private int _scalingFilter;
@ -115,12 +116,23 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool IsHypervisorAvailable => OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64; public bool IsHypervisorAvailable => OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64;
public bool DirectoryChanged public bool GameDirectoryChanged
{ {
get => _directoryChanged; get => _gameDirectoryChanged;
set set
{ {
_directoryChanged = value; _gameDirectoryChanged = value;
OnPropertyChanged();
}
}
public bool AutoloadDirectoryChanged
{
get => _autoloadDirectoryChanged;
set
{
_autoloadDirectoryChanged = value;
OnPropertyChanged(); OnPropertyChanged();
} }
@ -231,6 +243,7 @@ namespace Ryujinx.Ava.UI.ViewModels
internal AvaloniaList<TimeZone> TimeZones { get; set; } internal AvaloniaList<TimeZone> TimeZones { get; set; }
public AvaloniaList<string> GameDirectories { get; set; } public AvaloniaList<string> GameDirectories { get; set; }
public AvaloniaList<string> AutoloadDirectories { get; set; }
public ObservableCollection<ComboBoxItem> AvailableGpus { get; set; } public ObservableCollection<ComboBoxItem> AvailableGpus { get; set; }
public AvaloniaList<string> NetworkInterfaceList public AvaloniaList<string> NetworkInterfaceList
@ -273,6 +286,7 @@ namespace Ryujinx.Ava.UI.ViewModels
public SettingsViewModel() public SettingsViewModel()
{ {
GameDirectories = new AvaloniaList<string>(); GameDirectories = new AvaloniaList<string>();
AutoloadDirectories = new AvaloniaList<string>();
TimeZones = new AvaloniaList<TimeZone>(); TimeZones = new AvaloniaList<TimeZone>();
AvailableGpus = new ObservableCollection<ComboBoxItem>(); AvailableGpus = new ObservableCollection<ComboBoxItem>();
_validTzRegions = new List<string>(); _validTzRegions = new List<string>();
@ -399,6 +413,9 @@ namespace Ryujinx.Ava.UI.ViewModels
GameDirectories.Clear(); GameDirectories.Clear();
GameDirectories.AddRange(config.UI.GameDirs.Value); GameDirectories.AddRange(config.UI.GameDirs.Value);
AutoloadDirectories.Clear();
AutoloadDirectories.AddRange(config.UI.AutoloadDirs.Value);
BaseStyleIndex = config.UI.BaseStyle.Value switch BaseStyleIndex = config.UI.BaseStyle.Value switch
{ {
"Auto" => 0, "Auto" => 0,
@ -489,12 +506,18 @@ namespace Ryujinx.Ava.UI.ViewModels
config.AutoloadContent.Value = AutoloadContent; config.AutoloadContent.Value = AutoloadContent;
config.HideCursor.Value = (HideCursorMode)HideCursor; config.HideCursor.Value = (HideCursorMode)HideCursor;
if (_directoryChanged) if (_gameDirectoryChanged)
{ {
List<string> gameDirs = new(GameDirectories); List<string> gameDirs = new(GameDirectories);
config.UI.GameDirs.Value = gameDirs; config.UI.GameDirs.Value = gameDirs;
} }
if (_autoloadDirectoryChanged)
{
List<string> autoloadDirs = new(AutoloadDirectories);
config.UI.AutoloadDirs.Value = autoloadDirs;
}
config.UI.BaseStyle.Value = BaseStyleIndex switch config.UI.BaseStyle.Value = BaseStyleIndex switch
{ {
0 => "Auto", 0 => "Auto",
@ -590,7 +613,8 @@ namespace Ryujinx.Ava.UI.ViewModels
SaveSettingsEvent?.Invoke(); SaveSettingsEvent?.Invoke();
_directoryChanged = false; _gameDirectoryChanged = false;
_autoloadDirectoryChanged = false;
} }
private static void RevertIfNotSaved() private static void RevertIfNotSaved()

View file

@ -88,7 +88,7 @@
Orientation="Vertical" Orientation="Vertical"
Spacing="10"> Spacing="10">
<ListBox <ListBox
Name="GameList" Name="GameDirsList"
MinHeight="230" MinHeight="230"
ItemsSource="{Binding GameDirectories}"> ItemsSource="{Binding GameDirectories}">
<ListBox.Styles> <ListBox.Styles>
@ -105,27 +105,78 @@
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBox <TextBox
Name="PathBox" Name="GameDirPathBox"
Margin="0" Margin="0"
ToolTip.Tip="{locale:Locale AddGameDirBoxTooltip}" ToolTip.Tip="{locale:Locale AddGameDirBoxTooltip}"
VerticalAlignment="Stretch" /> VerticalAlignment="Stretch" />
<Button <Button
Name="AddButton" Name="AddGameDirButton"
Grid.Column="1" Grid.Column="1"
MinWidth="90" MinWidth="90"
Margin="10,0,0,0" Margin="10,0,0,0"
ToolTip.Tip="{locale:Locale AddGameDirTooltip}" ToolTip.Tip="{locale:Locale AddGameDirTooltip}"
Click="AddButton_OnClick"> Click="AddGameDirButton_OnClick">
<TextBlock HorizontalAlignment="Center" <TextBlock HorizontalAlignment="Center"
Text="{locale:Locale SettingsTabGeneralAdd}" /> Text="{locale:Locale SettingsTabGeneralAdd}" />
</Button> </Button>
<Button <Button
Name="RemoveButton" Name="RemoveGameDirButton"
Grid.Column="2" Grid.Column="2"
MinWidth="90" MinWidth="90"
Margin="10,0,0,0" Margin="10,0,0,0"
ToolTip.Tip="{locale:Locale RemoveGameDirTooltip}" ToolTip.Tip="{locale:Locale RemoveGameDirTooltip}"
Click="RemoveButton_OnClick"> Click="RemoveGameDirButton_OnClick">
<TextBlock HorizontalAlignment="Center"
Text="{locale:Locale SettingsTabGeneralRemove}" />
</Button>
</Grid>
</StackPanel>
<Separator Height="1" />
<TextBlock Classes="h1" Text="{locale:Locale SettingsTabGeneralAutoloadDirectories}" />
<StackPanel
Margin="10,0,0,0"
HorizontalAlignment="Stretch"
Orientation="Vertical"
Spacing="10">
<ListBox
Name="AutoloadDirsList"
MinHeight="230"
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">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox
Name="AutoloadDirPathBox"
Margin="0"
ToolTip.Tip="{locale:Locale AddAutoloadDirBoxTooltip}"
VerticalAlignment="Stretch" />
<Button
Name="AddAutoloadDirButton"
Grid.Column="1"
MinWidth="90"
Margin="10,0,0,0"
ToolTip.Tip="{locale:Locale AddAutoloadDirTooltip}"
Click="AddAutoloadDirButton_OnClick">
<TextBlock HorizontalAlignment="Center"
Text="{locale:Locale SettingsTabGeneralAdd}" />
</Button>
<Button
Name="RemoveAutoloadDirButton"
Grid.Column="2"
MinWidth="90"
Margin="10,0,0,0"
ToolTip.Tip="{locale:Locale RemoveAutoloadDirTooltip}"
Click="RemoveAutoloadDirButton_OnClick">
<TextBlock HorizontalAlignment="Center" <TextBlock HorizontalAlignment="Center"
Text="{locale:Locale SettingsTabGeneralRemove}" /> Text="{locale:Locale SettingsTabGeneralRemove}" />
</Button> </Button>

View file

@ -19,14 +19,14 @@ namespace Ryujinx.Ava.UI.Views.Settings
InitializeComponent(); InitializeComponent();
} }
private async void AddButton_OnClick(object sender, RoutedEventArgs e) private async void AddGameDirButton_OnClick(object sender, RoutedEventArgs e)
{ {
string path = PathBox.Text; string path = GameDirPathBox.Text;
if (!string.IsNullOrWhiteSpace(path) && Directory.Exists(path) && !ViewModel.GameDirectories.Contains(path)) if (!string.IsNullOrWhiteSpace(path) && Directory.Exists(path) && !ViewModel.GameDirectories.Contains(path))
{ {
ViewModel.GameDirectories.Add(path); ViewModel.GameDirectories.Add(path);
ViewModel.DirectoryChanged = true; ViewModel.GameDirectoryChanged = true;
} }
else else
{ {
@ -40,25 +40,68 @@ namespace Ryujinx.Ava.UI.Views.Settings
if (result.Count > 0) if (result.Count > 0)
{ {
ViewModel.GameDirectories.Add(result[0].Path.LocalPath); ViewModel.GameDirectories.Add(result[0].Path.LocalPath);
ViewModel.DirectoryChanged = true; ViewModel.GameDirectoryChanged = true;
} }
} }
} }
} }
private void RemoveButton_OnClick(object sender, RoutedEventArgs e) private void RemoveGameDirButton_OnClick(object sender, RoutedEventArgs e)
{ {
int oldIndex = GameList.SelectedIndex; int oldIndex = GameDirsList.SelectedIndex;
foreach (string path in new List<string>(GameList.SelectedItems.Cast<string>())) foreach (string path in new List<string>(GameDirsList.SelectedItems.Cast<string>()))
{ {
ViewModel.GameDirectories.Remove(path); ViewModel.GameDirectories.Remove(path);
ViewModel.DirectoryChanged = true; ViewModel.GameDirectoryChanged = true;
} }
if (GameList.ItemCount > 0) if (GameDirsList.ItemCount > 0)
{ {
GameList.SelectedIndex = oldIndex < GameList.ItemCount ? oldIndex : 0; GameDirsList.SelectedIndex = oldIndex < GameDirsList.ItemCount ? oldIndex : 0;
}
}
private async void AddAutoloadDirButton_OnClick(object sender, RoutedEventArgs e)
{
string path = AutoloadDirPathBox.Text;
if (!string.IsNullOrWhiteSpace(path) && Directory.Exists(path) && !ViewModel.AutoloadDirectories.Contains(path))
{
ViewModel.AutoloadDirectories.Add(path);
ViewModel.AutoloadDirectoryChanged = true;
}
else
{
if (this.GetVisualRoot() is Window window)
{
var result = await window.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
{
AllowMultiple = false,
});
if (result.Count > 0)
{
ViewModel.AutoloadDirectories.Add(result[0].Path.LocalPath);
ViewModel.AutoloadDirectoryChanged = true;
}
}
}
}
private void RemoveAutoloadDirButton_OnClick(object sender, RoutedEventArgs e)
{
int oldIndex = AutoloadDirsList.SelectedIndex;
foreach (string path in new List<string>(AutoloadDirsList.SelectedItems.Cast<string>()))
{
ViewModel.AutoloadDirectories.Remove(path);
ViewModel.AutoloadDirectoryChanged = true;
}
if (AutoloadDirsList.ItemCount > 0)
{
AutoloadDirsList.SelectedIndex = oldIndex < AutoloadDirsList.ItemCount ? oldIndex : 0;
} }
} }
} }

View file

@ -642,17 +642,18 @@ namespace Ryujinx.Ava.UI.Windows
TimeIt("updates", () => ApplicationLibrary.LoadTitleUpdates()); TimeIt("updates", () => ApplicationLibrary.LoadTitleUpdates());
TimeIt("DLC", () => ApplicationLibrary.LoadDownloadableContents()); TimeIt("DLC", () => ApplicationLibrary.LoadDownloadableContents());
if (ConfigurationState.Instance.AutoloadContent) var autoloadDirs = ConfigurationState.Instance.UI.AutoloadDirs.Value;
if (autoloadDirs.Count > 0)
{ {
var updatesLoaded = 0; var updatesLoaded = 0;
TimeIt("auto updates", TimeIt("auto updates",
() => updatesLoaded = () => updatesLoaded =
ApplicationLibrary.AutoLoadTitleUpdates(ConfigurationState.Instance.UI.GameDirs)); ApplicationLibrary.AutoLoadTitleUpdates(autoloadDirs));
var dlcLoaded = 0; var dlcLoaded = 0;
TimeIt("auto dlc", TimeIt("auto dlc",
() => dlcLoaded = () => dlcLoaded =
ApplicationLibrary.AutoLoadDownloadableContents(ConfigurationState.Instance.UI.GameDirs)); ApplicationLibrary.AutoLoadDownloadableContents(autoloadDirs));
ShowNewContentAddedDialog(dlcLoaded, updatesLoaded); ShowNewContentAddedDialog(dlcLoaded, updatesLoaded);
} }

View file

@ -39,7 +39,7 @@ namespace Ryujinx.Ava.UI.Windows
{ {
InputPage.InputView?.SaveCurrentProfile(); InputPage.InputView?.SaveCurrentProfile();
if (Owner is MainWindow window && ViewModel.DirectoryChanged) if (Owner is MainWindow window && (ViewModel.GameDirectoryChanged || ViewModel.AutoloadDirectoryChanged))
{ {
window.LoadApplications(); window.LoadApplications();
} }