Migrate UI to SettingsUIViewModel

This commit is contained in:
Isaac Marovitz 2024-04-19 17:22:58 -04:00
parent 9b6241985f
commit 47c491271a
No known key found for this signature in database
GPG key ID: 97250B2B09A132E1
5 changed files with 137 additions and 125 deletions

View file

@ -0,0 +1,116 @@
using Avalonia.Collections;
using Ryujinx.Common.Configuration;
using Ryujinx.UI.Common.Configuration;
using System;
using System.Linq;
namespace Ryujinx.Ava.UI.ViewModels.Settings
{
public class SettingsUIViewModel : BaseModel
{
public event Action DirtyEvent;
private bool _enableDiscordIntegration;
public bool EnableDiscordIntegration
{
get => _enableDiscordIntegration;
set
{
_enableDiscordIntegration = value;
DirtyEvent?.Invoke();
}
}
private bool _checkUpdatesOnStart;
public bool CheckUpdatesOnStart
{
get => _checkUpdatesOnStart;
set
{
_checkUpdatesOnStart = value;
DirtyEvent?.Invoke();
}
}
private bool _showConfirmExit;
public bool ShowConfirmExit
{
get => _showConfirmExit;
set
{
_showConfirmExit = value;
DirtyEvent?.Invoke();
}
}
private int _hideCursor;
public int HideCursor
{
get => _hideCursor;
set
{
_hideCursor = value;
DirtyEvent?.Invoke();
}
}
private int _baseStyleIndex;
public int BaseStyleIndex
{
get => _baseStyleIndex;
set
{
_baseStyleIndex = value;
DirtyEvent?.Invoke();
}
}
public bool DirsChanged;
public AvaloniaList<string> GameDirectories { get; set; }
public SettingsUIViewModel()
{
ConfigurationState config = ConfigurationState.Instance;
GameDirectories = new();
EnableDiscordIntegration = config.EnableDiscordIntegration;
CheckUpdatesOnStart = config.CheckUpdatesOnStart;
ShowConfirmExit = config.ShowConfirmExit;
HideCursor = (int)config.HideCursor.Value;
GameDirectories.Clear();
GameDirectories.AddRange(config.UI.GameDirs.Value);
GameDirectories.CollectionChanged += (_, _) => DirtyEvent?.Invoke();
BaseStyleIndex = config.UI.BaseStyle == "Light" ? 0 : 1;
}
public bool CheckIfModified(ConfigurationState config)
{
bool isDirty = false;
DirsChanged = !config.UI.GameDirs.Value.SequenceEqual(GameDirectories);
isDirty |= config.EnableDiscordIntegration.Value != EnableDiscordIntegration;
isDirty |= config.CheckUpdatesOnStart.Value != CheckUpdatesOnStart;
isDirty |= config.ShowConfirmExit.Value != ShowConfirmExit;
isDirty |= config.HideCursor.Value != (HideCursorMode)HideCursor;
isDirty |= DirsChanged;
isDirty |= config.UI.BaseStyle.Value != (BaseStyleIndex == 0 ? "Light" : "Dark");
return isDirty;
}
public void Save(ConfigurationState config)
{
config.EnableDiscordIntegration.Value = EnableDiscordIntegration;
config.CheckUpdatesOnStart.Value = CheckUpdatesOnStart;
config.ShowConfirmExit.Value = ShowConfirmExit;
config.HideCursor.Value = (HideCursorMode)HideCursor;
config.UI.GameDirs.Value = GameDirectories.ToList();
config.UI.BaseStyle.Value = BaseStyleIndex == 0 ? "Light" : "Dark";
}
}
}

View file

@ -1,16 +1,11 @@
using Avalonia.Collections;
using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.UI.Windows;
using Ryujinx.Common.Configuration;
using Ryujinx.UI.Common.Configuration; using Ryujinx.UI.Common.Configuration;
using System; using System;
using System.Collections.Generic;
namespace Ryujinx.Ava.UI.ViewModels.Settings namespace Ryujinx.Ava.UI.ViewModels.Settings
{ {
public class SettingsViewModel : BaseModel public class SettingsViewModel : BaseModel
{ {
private bool _directoryChanged;
private bool _isModified; private bool _isModified;
public bool IsModified public bool IsModified
@ -27,65 +22,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Settings
public event Action<bool> DirtyEvent; public event Action<bool> DirtyEvent;
public event Action<bool> ToggleButtons; public event Action<bool> ToggleButtons;
public bool DirectoryChanged
{
get => _directoryChanged;
set
{
_directoryChanged = value;
OnPropertyChanged();
}
}
public bool IsMacOS => OperatingSystem.IsMacOS(); public bool IsMacOS => OperatingSystem.IsMacOS();
private bool _enableDiscordIntegration;
public bool EnableDiscordIntegration
{
get => _enableDiscordIntegration;
set
{
_enableDiscordIntegration = value;
CheckIfModified();
}
}
private bool _checkUpdatesOnStart;
public bool CheckUpdatesOnStart
{
get => _checkUpdatesOnStart;
set
{
_checkUpdatesOnStart = value;
CheckIfModified();
}
}
private bool _showConfirmExit;
public bool ShowConfirmExit
{
get => _showConfirmExit;
set
{
_showConfirmExit = value;
CheckIfModified();
}
}
private int _hideCursor;
public int HideCursor
{
get => _hideCursor;
set
{
_hideCursor = value;
CheckIfModified();
}
}
public int BaseStyleIndex { get; set; }
private readonly SettingsAudioViewModel _audioViewModel; private readonly SettingsAudioViewModel _audioViewModel;
private readonly SettingsCpuViewModel _cpuViewModel; private readonly SettingsCpuViewModel _cpuViewModel;
private readonly SettingsGraphicsViewModel _graphicsViewModel; private readonly SettingsGraphicsViewModel _graphicsViewModel;
@ -94,8 +32,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Settings
private readonly SettingsLoggingViewModel _loggingViewModel; private readonly SettingsLoggingViewModel _loggingViewModel;
private readonly SettingsNetworkViewModel _networkViewModel; private readonly SettingsNetworkViewModel _networkViewModel;
private readonly SettingsSystemViewModel _systemViewModel; private readonly SettingsSystemViewModel _systemViewModel;
private readonly SettingsUIViewModel _uiViewModel;
public AvaloniaList<string> GameDirectories { get; set; }
public SettingsViewModel( public SettingsViewModel(
SettingsAudioViewModel audioViewModel, SettingsAudioViewModel audioViewModel,
@ -105,7 +42,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Settings
SettingsInputViewModel inputViewModel, SettingsInputViewModel inputViewModel,
SettingsLoggingViewModel loggingViewModel, SettingsLoggingViewModel loggingViewModel,
SettingsNetworkViewModel networkViewModel, SettingsNetworkViewModel networkViewModel,
SettingsSystemViewModel systemViewModel) : this() SettingsSystemViewModel systemViewModel,
SettingsUIViewModel uiViewModel) : this()
{ {
_audioViewModel = audioViewModel; _audioViewModel = audioViewModel;
_cpuViewModel = cpuViewModel; _cpuViewModel = cpuViewModel;
@ -115,6 +53,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Settings
_loggingViewModel = loggingViewModel; _loggingViewModel = loggingViewModel;
_networkViewModel = networkViewModel; _networkViewModel = networkViewModel;
_systemViewModel = systemViewModel; _systemViewModel = systemViewModel;
_uiViewModel = uiViewModel;
_audioViewModel.DirtyEvent += CheckIfModified; _audioViewModel.DirtyEvent += CheckIfModified;
_cpuViewModel.DirtyEvent += CheckIfModified; _cpuViewModel.DirtyEvent += CheckIfModified;
@ -124,15 +63,14 @@ namespace Ryujinx.Ava.UI.ViewModels.Settings
_loggingViewModel.DirtyEvent += CheckIfModified; _loggingViewModel.DirtyEvent += CheckIfModified;
_networkViewModel.DirtyEvent += CheckIfModified; _networkViewModel.DirtyEvent += CheckIfModified;
_systemViewModel.DirtyEvent += CheckIfModified; _systemViewModel.DirtyEvent += CheckIfModified;
_uiViewModel.DirtyEvent += CheckIfModified;
} }
public SettingsViewModel() public SettingsViewModel()
{ {
GameDirectories = new AvaloniaList<string>();
if (Program.PreviewerDetached) if (Program.PreviewerDetached)
{ {
LoadCurrentConfiguration();
} }
} }
@ -142,15 +80,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Settings
ConfigurationState config = ConfigurationState.Instance; ConfigurationState config = ConfigurationState.Instance;
isDirty |= config.EnableDiscordIntegration.Value != EnableDiscordIntegration;
isDirty |= config.CheckUpdatesOnStart.Value != CheckUpdatesOnStart;
isDirty |= config.ShowConfirmExit.Value != ShowConfirmExit;
isDirty |= config.HideCursor.Value != (HideCursorMode)HideCursor;
// isDirty |= config.UI.GameDirs.Value != GameDirectories.ToList();
isDirty |= config.UI.BaseStyle.Value != (BaseStyleIndex == 0 ? "Light" : "Dark");
isDirty |= _audioViewModel?.CheckIfModified(config) ?? false; isDirty |= _audioViewModel?.CheckIfModified(config) ?? false;
isDirty |= _cpuViewModel?.CheckIfModified(config) ?? false; isDirty |= _cpuViewModel?.CheckIfModified(config) ?? false;
isDirty |= _graphicsViewModel?.CheckIfModified(config) ?? false; isDirty |= _graphicsViewModel?.CheckIfModified(config) ?? false;
@ -160,44 +89,15 @@ namespace Ryujinx.Ava.UI.ViewModels.Settings
isDirty |= _loggingViewModel?.CheckIfModified(config) ?? false; isDirty |= _loggingViewModel?.CheckIfModified(config) ?? false;
isDirty |= _networkViewModel?.CheckIfModified(config) ?? false; isDirty |= _networkViewModel?.CheckIfModified(config) ?? false;
isDirty |= _systemViewModel?.CheckIfModified(config) ?? false; isDirty |= _systemViewModel?.CheckIfModified(config) ?? false;
isDirty |= _uiViewModel?.CheckIfModified(config) ?? false;
IsModified = isDirty; IsModified = isDirty;
} }
public void LoadCurrentConfiguration()
{
ConfigurationState config = ConfigurationState.Instance;
// User Interface
EnableDiscordIntegration = config.EnableDiscordIntegration;
CheckUpdatesOnStart = config.CheckUpdatesOnStart;
ShowConfirmExit = config.ShowConfirmExit;
HideCursor = (int)config.HideCursor.Value;
GameDirectories.Clear();
GameDirectories.AddRange(config.UI.GameDirs.Value);
BaseStyleIndex = config.UI.BaseStyle == "Light" ? 0 : 1;
}
public void SaveSettings() public void SaveSettings()
{ {
ConfigurationState config = ConfigurationState.Instance; ConfigurationState config = ConfigurationState.Instance;
// User Interface
config.EnableDiscordIntegration.Value = EnableDiscordIntegration;
config.CheckUpdatesOnStart.Value = CheckUpdatesOnStart;
config.ShowConfirmExit.Value = ShowConfirmExit;
config.HideCursor.Value = (HideCursorMode)HideCursor;
if (_directoryChanged)
{
List<string> gameDirs = new(GameDirectories);
config.UI.GameDirs.Value = gameDirs;
}
config.UI.BaseStyle.Value = BaseStyleIndex == 0 ? "Light" : "Dark";
_audioViewModel?.Save(config); _audioViewModel?.Save(config);
_cpuViewModel?.Save(config); _cpuViewModel?.Save(config);
_graphicsViewModel?.Save(config); _graphicsViewModel?.Save(config);
@ -206,12 +106,11 @@ namespace Ryujinx.Ava.UI.ViewModels.Settings
_loggingViewModel?.Save(config); _loggingViewModel?.Save(config);
_networkViewModel?.Save(config); _networkViewModel?.Save(config);
_systemViewModel?.Save(config); _systemViewModel?.Save(config);
_uiViewModel?.Save(config);
config.ToFileFormat().SaveConfig(Program.ConfigurationPath); config.ToFileFormat().SaveConfig(Program.ConfigurationPath);
MainWindow.UpdateGraphicsConfig(); MainWindow.UpdateGraphicsConfig();
_directoryChanged = false;
} }
public void ApplyButton() public void ApplyButton()

View file

@ -7,9 +7,9 @@
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale" xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels.Settings" xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels.Settings"
mc:Ignorable="d" mc:Ignorable="d"
x:DataType="viewModels:SettingsViewModel"> x:DataType="viewModels:SettingsUIViewModel">
<Design.DataContext> <Design.DataContext>
<viewModels:SettingsViewModel /> <viewModels:SettingsUIViewModel />
</Design.DataContext> </Design.DataContext>
<ScrollViewer <ScrollViewer
Name="UiPage" Name="UiPage"

View file

@ -11,11 +11,11 @@ namespace Ryujinx.Ava.UI.Views.Settings
{ {
public partial class SettingsUiView : UserControl public partial class SettingsUiView : UserControl
{ {
private readonly SettingsViewModel _viewModel; public SettingsUIViewModel ViewModel;
public SettingsUiView(SettingsViewModel viewModel) public SettingsUiView()
{ {
_viewModel = viewModel; DataContext = ViewModel = new SettingsUIViewModel();
InitializeComponent(); InitializeComponent();
} }
@ -23,10 +23,9 @@ namespace Ryujinx.Ava.UI.Views.Settings
{ {
string path = PathBox.Text; string path = PathBox.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;
} }
else else
{ {
@ -39,8 +38,7 @@ 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;
} }
} }
} }
@ -52,8 +50,7 @@ namespace Ryujinx.Ava.UI.Views.Settings
foreach (string path in new List<string>(GameList.SelectedItems.Cast<string>())) foreach (string path in new List<string>(GameList.SelectedItems.Cast<string>()))
{ {
_viewModel.GameDirectories.Remove(path); ViewModel.GameDirectories.Remove(path);
_viewModel.DirectoryChanged = true;
} }
if (GameList.ItemCount > 0) if (GameList.ItemCount > 0)

View file

@ -37,6 +37,7 @@ namespace Ryujinx.Ava.UI.Windows
LoggingPage = new SettingsLoggingView(); LoggingPage = new SettingsLoggingView();
NetworkPage = new SettingsNetworkView(); NetworkPage = new SettingsNetworkView();
SystemPage = new SettingsSystemView(virtualFileSystem, contentManager); SystemPage = new SettingsSystemView(virtualFileSystem, contentManager);
UiPage = new SettingsUiView();
ViewModel = new SettingsViewModel( ViewModel = new SettingsViewModel(
AudioPage.ViewModel, AudioPage.ViewModel,
@ -46,9 +47,8 @@ namespace Ryujinx.Ava.UI.Windows
InputPage.ViewModel, InputPage.ViewModel,
LoggingPage.ViewModel, LoggingPage.ViewModel,
NetworkPage.ViewModel, NetworkPage.ViewModel,
SystemPage.ViewModel); SystemPage.ViewModel,
UiPage.ViewModel);
UiPage = new SettingsUiView(ViewModel);
DataContext = ViewModel; DataContext = ViewModel;
@ -167,7 +167,7 @@ namespace Ryujinx.Ava.UI.Windows
protected override void OnClosing(WindowClosingEventArgs e) protected override void OnClosing(WindowClosingEventArgs e)
{ {
if (Owner is MainWindow window && ViewModel.DirectoryChanged) if (Owner is MainWindow window && UiPage.ViewModel.DirsChanged)
{ {
window.LoadApplications(); window.LoadApplications();
} }