diff options
Diffstat (limited to 'src/Ryujinx/UI/Models')
-rw-r--r-- | src/Ryujinx/UI/Models/CheatNode.cs | 57 | ||||
-rw-r--r-- | src/Ryujinx/UI/Models/ControllerModel.cs | 6 | ||||
-rw-r--r-- | src/Ryujinx/UI/Models/DeviceType.cs | 9 | ||||
-rw-r--r-- | src/Ryujinx/UI/Models/DownloadableContentModel.cs | 35 | ||||
-rw-r--r-- | src/Ryujinx/UI/Models/Generic/LastPlayedSortComparer.cs | 31 | ||||
-rw-r--r-- | src/Ryujinx/UI/Models/Generic/TimePlayedSortComparer.cs | 31 | ||||
-rw-r--r-- | src/Ryujinx/UI/Models/InputConfiguration.cs | 456 | ||||
-rw-r--r-- | src/Ryujinx/UI/Models/ModModel.cs | 32 | ||||
-rw-r--r-- | src/Ryujinx/UI/Models/PlayerModel.cs | 6 | ||||
-rw-r--r-- | src/Ryujinx/UI/Models/ProfileImageModel.cs | 32 | ||||
-rw-r--r-- | src/Ryujinx/UI/Models/SaveModel.cs | 96 | ||||
-rw-r--r-- | src/Ryujinx/UI/Models/StatusUpdatedEventArgs.cs | 28 | ||||
-rw-r--r-- | src/Ryujinx/UI/Models/TempProfile.cs | 61 | ||||
-rw-r--r-- | src/Ryujinx/UI/Models/TimeZone.cs | 16 | ||||
-rw-r--r-- | src/Ryujinx/UI/Models/TitleUpdateModel.cs | 19 | ||||
-rw-r--r-- | src/Ryujinx/UI/Models/UserProfile.cs | 104 |
16 files changed, 1019 insertions, 0 deletions
diff --git a/src/Ryujinx/UI/Models/CheatNode.cs b/src/Ryujinx/UI/Models/CheatNode.cs new file mode 100644 index 00000000..8e9aee25 --- /dev/null +++ b/src/Ryujinx/UI/Models/CheatNode.cs @@ -0,0 +1,57 @@ +using Ryujinx.Ava.UI.ViewModels; +using System.Collections.ObjectModel; +using System.Collections.Specialized; +using System.Linq; + +namespace Ryujinx.Ava.UI.Models +{ + public class CheatNode : BaseModel + { + private bool _isEnabled = false; + public ObservableCollection<CheatNode> SubNodes { get; } = new(); + public string CleanName => Name[1..^7]; + public string BuildIdKey => $"{BuildId}-{Name}"; + public bool IsRootNode { get; } + public string Name { get; } + public string BuildId { get; } + public string Path { get; } + public bool IsEnabled + { + get + { + if (SubNodes.Count > 0) + { + return SubNodes.ToList().TrueForAll(x => x.IsEnabled); + } + + return _isEnabled; + } + set + { + foreach (var cheat in SubNodes) + { + cheat.IsEnabled = value; + cheat.OnPropertyChanged(); + } + + _isEnabled = value; + } + } + + public CheatNode(string name, string buildId, string path, bool isRootNode, bool isEnabled = false) + { + Name = name; + BuildId = buildId; + Path = path; + IsEnabled = isEnabled; + IsRootNode = isRootNode; + + SubNodes.CollectionChanged += CheatsList_CollectionChanged; + } + + private void CheatsList_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + OnPropertyChanged(nameof(IsEnabled)); + } + } +} diff --git a/src/Ryujinx/UI/Models/ControllerModel.cs b/src/Ryujinx/UI/Models/ControllerModel.cs new file mode 100644 index 00000000..98de7757 --- /dev/null +++ b/src/Ryujinx/UI/Models/ControllerModel.cs @@ -0,0 +1,6 @@ +using Ryujinx.Common.Configuration.Hid; + +namespace Ryujinx.Ava.UI.Models +{ + internal record ControllerModel(ControllerType Type, string Name); +} diff --git a/src/Ryujinx/UI/Models/DeviceType.cs b/src/Ryujinx/UI/Models/DeviceType.cs new file mode 100644 index 00000000..bb4fc3b3 --- /dev/null +++ b/src/Ryujinx/UI/Models/DeviceType.cs @@ -0,0 +1,9 @@ +namespace Ryujinx.Ava.UI.Models +{ + public enum DeviceType + { + None, + Keyboard, + Controller, + } +} diff --git a/src/Ryujinx/UI/Models/DownloadableContentModel.cs b/src/Ryujinx/UI/Models/DownloadableContentModel.cs new file mode 100644 index 00000000..9e400441 --- /dev/null +++ b/src/Ryujinx/UI/Models/DownloadableContentModel.cs @@ -0,0 +1,35 @@ +using Ryujinx.Ava.UI.ViewModels; +using System.IO; + +namespace Ryujinx.Ava.UI.Models +{ + public class DownloadableContentModel : BaseModel + { + private bool _enabled; + + public bool Enabled + { + get => _enabled; + set + { + _enabled = value; + + OnPropertyChanged(); + } + } + + public string TitleId { get; } + public string ContainerPath { get; } + public string FullPath { get; } + + public string FileName => Path.GetFileName(ContainerPath); + + public DownloadableContentModel(string titleId, string containerPath, string fullPath, bool enabled) + { + TitleId = titleId; + ContainerPath = containerPath; + FullPath = fullPath; + Enabled = enabled; + } + } +} diff --git a/src/Ryujinx/UI/Models/Generic/LastPlayedSortComparer.cs b/src/Ryujinx/UI/Models/Generic/LastPlayedSortComparer.cs new file mode 100644 index 00000000..224f78f4 --- /dev/null +++ b/src/Ryujinx/UI/Models/Generic/LastPlayedSortComparer.cs @@ -0,0 +1,31 @@ +using Ryujinx.UI.App.Common; +using System; +using System.Collections.Generic; + +namespace Ryujinx.Ava.UI.Models.Generic +{ + internal class LastPlayedSortComparer : IComparer<ApplicationData> + { + public LastPlayedSortComparer() { } + public LastPlayedSortComparer(bool isAscending) { IsAscending = isAscending; } + + public bool IsAscending { get; } + + public int Compare(ApplicationData x, ApplicationData y) + { + DateTime aValue = DateTime.UnixEpoch, bValue = DateTime.UnixEpoch; + + if (x?.LastPlayed != null) + { + aValue = x.LastPlayed.Value; + } + + if (y?.LastPlayed != null) + { + bValue = y.LastPlayed.Value; + } + + return (IsAscending ? 1 : -1) * DateTime.Compare(aValue, bValue); + } + } +} diff --git a/src/Ryujinx/UI/Models/Generic/TimePlayedSortComparer.cs b/src/Ryujinx/UI/Models/Generic/TimePlayedSortComparer.cs new file mode 100644 index 00000000..f0fb035d --- /dev/null +++ b/src/Ryujinx/UI/Models/Generic/TimePlayedSortComparer.cs @@ -0,0 +1,31 @@ +using Ryujinx.UI.App.Common; +using System; +using System.Collections.Generic; + +namespace Ryujinx.Ava.UI.Models.Generic +{ + internal class TimePlayedSortComparer : IComparer<ApplicationData> + { + public TimePlayedSortComparer() { } + public TimePlayedSortComparer(bool isAscending) { IsAscending = isAscending; } + + public bool IsAscending { get; } + + public int Compare(ApplicationData x, ApplicationData y) + { + TimeSpan aValue = TimeSpan.Zero, bValue = TimeSpan.Zero; + + if (x?.TimePlayed != null) + { + aValue = x.TimePlayed; + } + + if (y?.TimePlayed != null) + { + bValue = y.TimePlayed; + } + + return (IsAscending ? 1 : -1) * TimeSpan.Compare(aValue, bValue); + } + } +} diff --git a/src/Ryujinx/UI/Models/InputConfiguration.cs b/src/Ryujinx/UI/Models/InputConfiguration.cs new file mode 100644 index 00000000..f1352c6d --- /dev/null +++ b/src/Ryujinx/UI/Models/InputConfiguration.cs @@ -0,0 +1,456 @@ +using Ryujinx.Ava.UI.ViewModels; +using Ryujinx.Common.Configuration.Hid; +using Ryujinx.Common.Configuration.Hid.Controller; +using Ryujinx.Common.Configuration.Hid.Controller.Motion; +using Ryujinx.Common.Configuration.Hid.Keyboard; +using System; + +namespace Ryujinx.Ava.UI.Models +{ + internal class InputConfiguration<TKey, TStick> : BaseModel + { + private float _deadzoneRight; + private float _triggerThreshold; + private float _deadzoneLeft; + private double _gyroDeadzone; + private int _sensitivity; + private bool _enableMotion; + private float _weakRumble; + private float _strongRumble; + private float _rangeLeft; + private float _rangeRight; + + public InputBackendType Backend { get; set; } + + /// <summary> + /// Controller id + /// </summary> + public string Id { get; set; } + + /// <summary> + /// Controller's Type + /// </summary> + public ControllerType ControllerType { get; set; } + + /// <summary> + /// Player's Index for the controller + /// </summary> + public PlayerIndex PlayerIndex { get; set; } + + public TStick LeftJoystick { get; set; } + public bool LeftInvertStickX { get; set; } + public bool LeftInvertStickY { get; set; } + public bool RightRotate90 { get; set; } + public TKey LeftControllerStickButton { get; set; } + + public TStick RightJoystick { get; set; } + public bool RightInvertStickX { get; set; } + public bool RightInvertStickY { get; set; } + public bool LeftRotate90 { get; set; } + public TKey RightControllerStickButton { get; set; } + + public float DeadzoneLeft + { + get => _deadzoneLeft; + set + { + _deadzoneLeft = MathF.Round(value, 3); + + OnPropertyChanged(); + } + } + + public float RangeLeft + { + get => _rangeLeft; + set + { + _rangeLeft = MathF.Round(value, 3); + + OnPropertyChanged(); + } + } + + public float DeadzoneRight + { + get => _deadzoneRight; + set + { + _deadzoneRight = MathF.Round(value, 3); + + OnPropertyChanged(); + } + } + + public float RangeRight + { + get => _rangeRight; + set + { + _rangeRight = MathF.Round(value, 3); + + OnPropertyChanged(); + } + } + + public float TriggerThreshold + { + get => _triggerThreshold; + set + { + _triggerThreshold = MathF.Round(value, 3); + + OnPropertyChanged(); + } + } + + public MotionInputBackendType MotionBackend { get; set; } + + public TKey ButtonMinus { get; set; } + public TKey ButtonL { get; set; } + public TKey ButtonZl { get; set; } + public TKey LeftButtonSl { get; set; } + public TKey LeftButtonSr { get; set; } + public TKey DpadUp { get; set; } + public TKey DpadDown { get; set; } + public TKey DpadLeft { get; set; } + public TKey DpadRight { get; set; } + + public TKey ButtonPlus { get; set; } + public TKey ButtonR { get; set; } + public TKey ButtonZr { get; set; } + public TKey RightButtonSl { get; set; } + public TKey RightButtonSr { get; set; } + public TKey ButtonX { get; set; } + public TKey ButtonB { get; set; } + public TKey ButtonY { get; set; } + public TKey ButtonA { get; set; } + + public TKey LeftStickUp { get; set; } + public TKey LeftStickDown { get; set; } + public TKey LeftStickLeft { get; set; } + public TKey LeftStickRight { get; set; } + public TKey LeftKeyboardStickButton { get; set; } + + public TKey RightStickUp { get; set; } + public TKey RightStickDown { get; set; } + public TKey RightStickLeft { get; set; } + public TKey RightStickRight { get; set; } + public TKey RightKeyboardStickButton { get; set; } + + public int Sensitivity + { + get => _sensitivity; + set + { + _sensitivity = value; + + OnPropertyChanged(); + } + } + + public double GyroDeadzone + { + get => _gyroDeadzone; + set + { + _gyroDeadzone = Math.Round(value, 3); + + OnPropertyChanged(); + } + } + + public bool EnableMotion + { + get => _enableMotion; set + { + _enableMotion = value; + + OnPropertyChanged(); + } + } + + public bool EnableCemuHookMotion { get; set; } + public int Slot { get; set; } + public int AltSlot { get; set; } + public bool MirrorInput { get; set; } + public string DsuServerHost { get; set; } + public int DsuServerPort { get; set; } + + public bool EnableRumble { get; set; } + public float WeakRumble + { + get => _weakRumble; set + { + _weakRumble = value; + + OnPropertyChanged(); + } + } + public float StrongRumble + { + get => _strongRumble; set + { + _strongRumble = value; + + OnPropertyChanged(); + } + } + + public InputConfiguration(InputConfig config) + { + if (config != null) + { + Backend = config.Backend; + Id = config.Id; + ControllerType = config.ControllerType; + PlayerIndex = config.PlayerIndex; + + if (config is StandardKeyboardInputConfig keyboardConfig) + { + LeftStickUp = (TKey)(object)keyboardConfig.LeftJoyconStick.StickUp; + LeftStickDown = (TKey)(object)keyboardConfig.LeftJoyconStick.StickDown; + LeftStickLeft = (TKey)(object)keyboardConfig.LeftJoyconStick.StickLeft; + LeftStickRight = (TKey)(object)keyboardConfig.LeftJoyconStick.StickRight; + LeftKeyboardStickButton = (TKey)(object)keyboardConfig.LeftJoyconStick.StickButton; + + RightStickUp = (TKey)(object)keyboardConfig.RightJoyconStick.StickUp; + RightStickDown = (TKey)(object)keyboardConfig.RightJoyconStick.StickDown; + RightStickLeft = (TKey)(object)keyboardConfig.RightJoyconStick.StickLeft; + RightStickRight = (TKey)(object)keyboardConfig.RightJoyconStick.StickRight; + RightKeyboardStickButton = (TKey)(object)keyboardConfig.RightJoyconStick.StickButton; + + ButtonA = (TKey)(object)keyboardConfig.RightJoycon.ButtonA; + ButtonB = (TKey)(object)keyboardConfig.RightJoycon.ButtonB; + ButtonX = (TKey)(object)keyboardConfig.RightJoycon.ButtonX; + ButtonY = (TKey)(object)keyboardConfig.RightJoycon.ButtonY; + ButtonR = (TKey)(object)keyboardConfig.RightJoycon.ButtonR; + RightButtonSl = (TKey)(object)keyboardConfig.RightJoycon.ButtonSl; + RightButtonSr = (TKey)(object)keyboardConfig.RightJoycon.ButtonSr; + ButtonZr = (TKey)(object)keyboardConfig.RightJoycon.ButtonZr; + ButtonPlus = (TKey)(object)keyboardConfig.RightJoycon.ButtonPlus; + + DpadUp = (TKey)(object)keyboardConfig.LeftJoycon.DpadUp; + DpadDown = (TKey)(object)keyboardConfig.LeftJoycon.DpadDown; + DpadLeft = (TKey)(object)keyboardConfig.LeftJoycon.DpadLeft; + DpadRight = (TKey)(object)keyboardConfig.LeftJoycon.DpadRight; + ButtonMinus = (TKey)(object)keyboardConfig.LeftJoycon.ButtonMinus; + LeftButtonSl = (TKey)(object)keyboardConfig.LeftJoycon.ButtonSl; + LeftButtonSr = (TKey)(object)keyboardConfig.LeftJoycon.ButtonSr; + ButtonZl = (TKey)(object)keyboardConfig.LeftJoycon.ButtonZl; + ButtonL = (TKey)(object)keyboardConfig.LeftJoycon.ButtonL; + } + else if (config is StandardControllerInputConfig controllerConfig) + { + LeftJoystick = (TStick)(object)controllerConfig.LeftJoyconStick.Joystick; + LeftInvertStickX = controllerConfig.LeftJoyconStick.InvertStickX; + LeftInvertStickY = controllerConfig.LeftJoyconStick.InvertStickY; + LeftRotate90 = controllerConfig.LeftJoyconStick.Rotate90CW; + LeftControllerStickButton = (TKey)(object)controllerConfig.LeftJoyconStick.StickButton; + + RightJoystick = (TStick)(object)controllerConfig.RightJoyconStick.Joystick; + RightInvertStickX = controllerConfig.RightJoyconStick.InvertStickX; + RightInvertStickY = controllerConfig.RightJoyconStick.InvertStickY; + RightRotate90 = controllerConfig.RightJoyconStick.Rotate90CW; + RightControllerStickButton = (TKey)(object)controllerConfig.RightJoyconStick.StickButton; + + ButtonA = (TKey)(object)controllerConfig.RightJoycon.ButtonA; + ButtonB = (TKey)(object)controllerConfig.RightJoycon.ButtonB; + ButtonX = (TKey)(object)controllerConfig.RightJoycon.ButtonX; + ButtonY = (TKey)(object)controllerConfig.RightJoycon.ButtonY; + ButtonR = (TKey)(object)controllerConfig.RightJoycon.ButtonR; + RightButtonSl = (TKey)(object)controllerConfig.RightJoycon.ButtonSl; + RightButtonSr = (TKey)(object)controllerConfig.RightJoycon.ButtonSr; + ButtonZr = (TKey)(object)controllerConfig.RightJoycon.ButtonZr; + ButtonPlus = (TKey)(object)controllerConfig.RightJoycon.ButtonPlus; + + DpadUp = (TKey)(object)controllerConfig.LeftJoycon.DpadUp; + DpadDown = (TKey)(object)controllerConfig.LeftJoycon.DpadDown; + DpadLeft = (TKey)(object)controllerConfig.LeftJoycon.DpadLeft; + DpadRight = (TKey)(object)controllerConfig.LeftJoycon.DpadRight; + ButtonMinus = (TKey)(object)controllerConfig.LeftJoycon.ButtonMinus; + LeftButtonSl = (TKey)(object)controllerConfig.LeftJoycon.ButtonSl; + LeftButtonSr = (TKey)(object)controllerConfig.LeftJoycon.ButtonSr; + ButtonZl = (TKey)(object)controllerConfig.LeftJoycon.ButtonZl; + ButtonL = (TKey)(object)controllerConfig.LeftJoycon.ButtonL; + + DeadzoneLeft = controllerConfig.DeadzoneLeft; + DeadzoneRight = controllerConfig.DeadzoneRight; + RangeLeft = controllerConfig.RangeLeft; + RangeRight = controllerConfig.RangeRight; + TriggerThreshold = controllerConfig.TriggerThreshold; + + if (controllerConfig.Motion != null) + { + EnableMotion = controllerConfig.Motion.EnableMotion; + MotionBackend = controllerConfig.Motion.MotionBackend; + GyroDeadzone = controllerConfig.Motion.GyroDeadzone; + Sensitivity = controllerConfig.Motion.Sensitivity; + + if (controllerConfig.Motion is CemuHookMotionConfigController cemuHook) + { + EnableCemuHookMotion = true; + DsuServerHost = cemuHook.DsuServerHost; + DsuServerPort = cemuHook.DsuServerPort; + Slot = cemuHook.Slot; + AltSlot = cemuHook.AltSlot; + MirrorInput = cemuHook.MirrorInput; + } + + if (controllerConfig.Rumble != null) + { + EnableRumble = controllerConfig.Rumble.EnableRumble; + WeakRumble = controllerConfig.Rumble.WeakRumble; + StrongRumble = controllerConfig.Rumble.StrongRumble; + } + } + } + } + } + + public InputConfiguration() + { + } + + public InputConfig GetConfig() + { + if (Backend == InputBackendType.WindowKeyboard) + { + return new StandardKeyboardInputConfig + { + Id = Id, + Backend = Backend, + PlayerIndex = PlayerIndex, + ControllerType = ControllerType, + LeftJoycon = new LeftJoyconCommonConfig<Key> + { + DpadUp = (Key)(object)DpadUp, + DpadDown = (Key)(object)DpadDown, + DpadLeft = (Key)(object)DpadLeft, + DpadRight = (Key)(object)DpadRight, + ButtonL = (Key)(object)ButtonL, + ButtonZl = (Key)(object)ButtonZl, + ButtonSl = (Key)(object)LeftButtonSl, + ButtonSr = (Key)(object)LeftButtonSr, + ButtonMinus = (Key)(object)ButtonMinus, + }, + RightJoycon = new RightJoyconCommonConfig<Key> + { + ButtonA = (Key)(object)ButtonA, + ButtonB = (Key)(object)ButtonB, + ButtonX = (Key)(object)ButtonX, + ButtonY = (Key)(object)ButtonY, + ButtonPlus = (Key)(object)ButtonPlus, + ButtonSl = (Key)(object)RightButtonSl, + ButtonSr = (Key)(object)RightButtonSr, + ButtonR = (Key)(object)ButtonR, + ButtonZr = (Key)(object)ButtonZr, + }, + LeftJoyconStick = new JoyconConfigKeyboardStick<Key> + { + StickUp = (Key)(object)LeftStickUp, + StickDown = (Key)(object)LeftStickDown, + StickRight = (Key)(object)LeftStickRight, + StickLeft = (Key)(object)LeftStickLeft, + StickButton = (Key)(object)LeftKeyboardStickButton, + }, + RightJoyconStick = new JoyconConfigKeyboardStick<Key> + { + StickUp = (Key)(object)RightStickUp, + StickDown = (Key)(object)RightStickDown, + StickLeft = (Key)(object)RightStickLeft, + StickRight = (Key)(object)RightStickRight, + StickButton = (Key)(object)RightKeyboardStickButton, + }, + Version = InputConfig.CurrentVersion, + }; + + } + + if (Backend == InputBackendType.GamepadSDL2) + { + var config = new StandardControllerInputConfig + { + Id = Id, + Backend = Backend, + PlayerIndex = PlayerIndex, + ControllerType = ControllerType, + LeftJoycon = new LeftJoyconCommonConfig<GamepadInputId> + { + DpadUp = (GamepadInputId)(object)DpadUp, + DpadDown = (GamepadInputId)(object)DpadDown, + DpadLeft = (GamepadInputId)(object)DpadLeft, + DpadRight = (GamepadInputId)(object)DpadRight, + ButtonL = (GamepadInputId)(object)ButtonL, + ButtonZl = (GamepadInputId)(object)ButtonZl, + ButtonSl = (GamepadInputId)(object)LeftButtonSl, + ButtonSr = (GamepadInputId)(object)LeftButtonSr, + ButtonMinus = (GamepadInputId)(object)ButtonMinus, + }, + RightJoycon = new RightJoyconCommonConfig<GamepadInputId> + { + ButtonA = (GamepadInputId)(object)ButtonA, + ButtonB = (GamepadInputId)(object)ButtonB, + ButtonX = (GamepadInputId)(object)ButtonX, + ButtonY = (GamepadInputId)(object)ButtonY, + ButtonPlus = (GamepadInputId)(object)ButtonPlus, + ButtonSl = (GamepadInputId)(object)RightButtonSl, + ButtonSr = (GamepadInputId)(object)RightButtonSr, + ButtonR = (GamepadInputId)(object)ButtonR, + ButtonZr = (GamepadInputId)(object)ButtonZr, + }, + LeftJoyconStick = new JoyconConfigControllerStick<GamepadInputId, StickInputId> + { + Joystick = (StickInputId)(object)LeftJoystick, + InvertStickX = LeftInvertStickX, + InvertStickY = LeftInvertStickY, + Rotate90CW = LeftRotate90, + StickButton = (GamepadInputId)(object)LeftControllerStickButton, + }, + RightJoyconStick = new JoyconConfigControllerStick<GamepadInputId, StickInputId> + { + Joystick = (StickInputId)(object)RightJoystick, + InvertStickX = RightInvertStickX, + InvertStickY = RightInvertStickY, + Rotate90CW = RightRotate90, + StickButton = (GamepadInputId)(object)RightControllerStickButton, + }, + Rumble = new RumbleConfigController + { + EnableRumble = EnableRumble, + WeakRumble = WeakRumble, + StrongRumble = StrongRumble, + }, + Version = InputConfig.CurrentVersion, + DeadzoneLeft = DeadzoneLeft, + DeadzoneRight = DeadzoneRight, + RangeLeft = RangeLeft, + RangeRight = RangeRight, + TriggerThreshold = TriggerThreshold, + Motion = EnableCemuHookMotion + ? new CemuHookMotionConfigController + { + DsuServerHost = DsuServerHost, + DsuServerPort = DsuServerPort, + Slot = Slot, + AltSlot = AltSlot, + MirrorInput = MirrorInput, + MotionBackend = MotionInputBackendType.CemuHook, + } + : new StandardMotionConfigController + { + MotionBackend = MotionInputBackendType.GamepadDriver, + }, + }; + + config.Motion.Sensitivity = Sensitivity; + config.Motion.EnableMotion = EnableMotion; + config.Motion.GyroDeadzone = GyroDeadzone; + + return config; + } + + return null; + } + } +} diff --git a/src/Ryujinx/UI/Models/ModModel.cs b/src/Ryujinx/UI/Models/ModModel.cs new file mode 100644 index 00000000..ee28ca5f --- /dev/null +++ b/src/Ryujinx/UI/Models/ModModel.cs @@ -0,0 +1,32 @@ +using Ryujinx.Ava.UI.ViewModels; +using System.IO; + +namespace Ryujinx.Ava.UI.Models +{ + public class ModModel : BaseModel + { + private bool _enabled; + + public bool Enabled + { + get => _enabled; + set + { + _enabled = value; + OnPropertyChanged(); + } + } + + public bool InSd { get; } + public string Path { get; } + public string Name { get; } + + public ModModel(string path, string name, bool enabled, bool inSd) + { + Path = path; + Name = name; + Enabled = enabled; + InSd = inSd; + } + } +} diff --git a/src/Ryujinx/UI/Models/PlayerModel.cs b/src/Ryujinx/UI/Models/PlayerModel.cs new file mode 100644 index 00000000..a19852b9 --- /dev/null +++ b/src/Ryujinx/UI/Models/PlayerModel.cs @@ -0,0 +1,6 @@ +using Ryujinx.Common.Configuration.Hid; + +namespace Ryujinx.Ava.UI.Models +{ + public record PlayerModel(PlayerIndex Id, string Name); +} diff --git a/src/Ryujinx/UI/Models/ProfileImageModel.cs b/src/Ryujinx/UI/Models/ProfileImageModel.cs new file mode 100644 index 00000000..99365dfc --- /dev/null +++ b/src/Ryujinx/UI/Models/ProfileImageModel.cs @@ -0,0 +1,32 @@ +using Avalonia.Media; +using Ryujinx.Ava.UI.ViewModels; + +namespace Ryujinx.Ava.UI.Models +{ + public class ProfileImageModel : BaseModel + { + public ProfileImageModel(string name, byte[] data) + { + Name = name; + Data = data; + } + + public string Name { get; set; } + public byte[] Data { get; set; } + + private SolidColorBrush _backgroundColor = new(Colors.White); + + public SolidColorBrush BackgroundColor + { + get + { + return _backgroundColor; + } + set + { + _backgroundColor = value; + OnPropertyChanged(); + } + } + } +} diff --git a/src/Ryujinx/UI/Models/SaveModel.cs b/src/Ryujinx/UI/Models/SaveModel.cs new file mode 100644 index 00000000..d6dea2f6 --- /dev/null +++ b/src/Ryujinx/UI/Models/SaveModel.cs @@ -0,0 +1,96 @@ +using LibHac.Fs; +using LibHac.Ncm; +using Ryujinx.Ava.UI.ViewModels; +using Ryujinx.Ava.UI.Windows; +using Ryujinx.HLE.FileSystem; +using Ryujinx.UI.App.Common; +using Ryujinx.UI.Common.Helper; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Path = System.IO.Path; + +namespace Ryujinx.Ava.UI.Models +{ + public class SaveModel : BaseModel + { + private long _size; + + public ulong SaveId { get; } + public ProgramId TitleId { get; } + public string TitleIdString => $"{TitleId.Value:X16}"; + public UserId UserId { get; } + public bool InGameList { get; } + public string Title { get; } + public byte[] Icon { get; } + + public long Size + { + get => _size; set + { + _size = value; + SizeAvailable = true; + OnPropertyChanged(); + OnPropertyChanged(nameof(SizeString)); + OnPropertyChanged(nameof(SizeAvailable)); + } + } + + public bool SizeAvailable { get; set; } + + public string SizeString => ValueFormatUtils.FormatFileSize(Size); + + public SaveModel(SaveDataInfo info) + { + SaveId = info.SaveDataId; + TitleId = info.ProgramId; + UserId = info.UserId; + + var appData = MainWindow.MainWindowViewModel.Applications.FirstOrDefault(x => x.TitleId.ToUpper() == TitleIdString); + + InGameList = appData != null; + + if (InGameList) + { + Icon = appData.Icon; + Title = appData.TitleName; + } + else + { + var appMetadata = ApplicationLibrary.LoadAndSaveMetaData(TitleIdString); + Title = appMetadata.Title ?? TitleIdString; + } + + Task.Run(() => + { + var saveRoot = Path.Combine(VirtualFileSystem.GetNandPath(), $"user/save/{info.SaveDataId:x16}"); + + long totalSize = GetDirectorySize(saveRoot); + + static long GetDirectorySize(string path) + { + long size = 0; + if (Directory.Exists(path)) + { + var directories = Directory.GetDirectories(path); + foreach (var directory in directories) + { + size += GetDirectorySize(directory); + } + + var files = Directory.GetFiles(path); + foreach (var file in files) + { + size += new FileInfo(file).Length; + } + } + + return size; + } + + Size = totalSize; + }); + + } + } +} diff --git a/src/Ryujinx/UI/Models/StatusUpdatedEventArgs.cs b/src/Ryujinx/UI/Models/StatusUpdatedEventArgs.cs new file mode 100644 index 00000000..7f04c0ee --- /dev/null +++ b/src/Ryujinx/UI/Models/StatusUpdatedEventArgs.cs @@ -0,0 +1,28 @@ +using System; + +namespace Ryujinx.Ava.UI.Models +{ + internal class StatusUpdatedEventArgs : EventArgs + { + public bool VSyncEnabled { get; } + public string VolumeStatus { get; } + public string GpuBackend { get; } + public string AspectRatio { get; } + public string DockedMode { get; } + public string FifoStatus { get; } + public string GameStatus { get; } + public string GpuName { get; } + + public StatusUpdatedEventArgs(bool vSyncEnabled, string volumeStatus, string gpuBackend, string dockedMode, string aspectRatio, string gameStatus, string fifoStatus, string gpuName) + { + VSyncEnabled = vSyncEnabled; + VolumeStatus = volumeStatus; + GpuBackend = gpuBackend; + DockedMode = dockedMode; + AspectRatio = aspectRatio; + GameStatus = gameStatus; + FifoStatus = fifoStatus; + GpuName = gpuName; + } + } +} diff --git a/src/Ryujinx/UI/Models/TempProfile.cs b/src/Ryujinx/UI/Models/TempProfile.cs new file mode 100644 index 00000000..659092e6 --- /dev/null +++ b/src/Ryujinx/UI/Models/TempProfile.cs @@ -0,0 +1,61 @@ +using Ryujinx.Ava.UI.ViewModels; +using Ryujinx.HLE.HOS.Services.Account.Acc; +using System; + +namespace Ryujinx.Ava.UI.Models +{ + public class TempProfile : BaseModel + { + private readonly UserProfile _profile; + private byte[] _image; + private string _name = String.Empty; + private UserId _userId; + + public static uint MaxProfileNameLength => 0x20; + + public byte[] Image + { + get => _image; + set + { + _image = value; + OnPropertyChanged(); + } + } + + public UserId UserId + { + get => _userId; + set + { + _userId = value; + OnPropertyChanged(); + OnPropertyChanged(nameof(UserIdString)); + } + } + + public string UserIdString => _userId.ToString(); + + public string Name + { + get => _name; + set + { + _name = value; + OnPropertyChanged(); + } + } + + public TempProfile(UserProfile profile) + { + _profile = profile; + + if (_profile != null) + { + Image = profile.Image; + Name = profile.Name; + UserId = profile.UserId; + } + } + } +} diff --git a/src/Ryujinx/UI/Models/TimeZone.cs b/src/Ryujinx/UI/Models/TimeZone.cs new file mode 100644 index 00000000..950fbce4 --- /dev/null +++ b/src/Ryujinx/UI/Models/TimeZone.cs @@ -0,0 +1,16 @@ +namespace Ryujinx.Ava.UI.Models +{ + internal class TimeZone + { + public TimeZone(string utcDifference, string location, string abbreviation) + { + UtcDifference = utcDifference; + Location = location; + Abbreviation = abbreviation; + } + + public string UtcDifference { get; set; } + public string Location { get; set; } + public string Abbreviation { get; set; } + } +} diff --git a/src/Ryujinx/UI/Models/TitleUpdateModel.cs b/src/Ryujinx/UI/Models/TitleUpdateModel.cs new file mode 100644 index 00000000..c270c9ed --- /dev/null +++ b/src/Ryujinx/UI/Models/TitleUpdateModel.cs @@ -0,0 +1,19 @@ +using LibHac.Ns; +using Ryujinx.Ava.Common.Locale; + +namespace Ryujinx.Ava.UI.Models +{ + public class TitleUpdateModel + { + public ApplicationControlProperty Control { get; } + public string Path { get; } + + public string Label => LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.TitleUpdateVersionLabel, Control.DisplayVersionString.ToString()); + + public TitleUpdateModel(ApplicationControlProperty control, string path) + { + Control = control; + Path = path; + } + } +} diff --git a/src/Ryujinx/UI/Models/UserProfile.cs b/src/Ryujinx/UI/Models/UserProfile.cs new file mode 100644 index 00000000..7a9237fe --- /dev/null +++ b/src/Ryujinx/UI/Models/UserProfile.cs @@ -0,0 +1,104 @@ +using Avalonia.Media; +using Ryujinx.Ava.UI.Controls; +using Ryujinx.Ava.UI.ViewModels; +using Ryujinx.Ava.UI.Views.User; +using Ryujinx.HLE.HOS.Services.Account.Acc; +using Profile = Ryujinx.HLE.HOS.Services.Account.Acc.UserProfile; + +namespace Ryujinx.Ava.UI.Models +{ + public class UserProfile : BaseModel + { + private readonly Profile _profile; + private readonly NavigationDialogHost _owner; + private byte[] _image; + private string _name; + private UserId _userId; + private bool _isPointerOver; + private IBrush _backgroundColor; + + public byte[] Image + { + get => _image; + set + { + _image = value; + OnPropertyChanged(); + } + } + + public UserId UserId + { + get => _userId; + set + { + _userId = value; + OnPropertyChanged(); + } + } + + public string Name + { + get => _name; + set + { + _name = value; + OnPropertyChanged(); + } + } + + public bool IsPointerOver + { + get => _isPointerOver; + set + { + _isPointerOver = value; + OnPropertyChanged(); + } + } + + public IBrush BackgroundColor + { + get => _backgroundColor; + set + { + _backgroundColor = value; + OnPropertyChanged(); + } + } + + public UserProfile(Profile profile, NavigationDialogHost owner) + { + _profile = profile; + _owner = owner; + + UpdateBackground(); + + Image = profile.Image; + Name = profile.Name; + UserId = profile.UserId; + } + + public void UpdateState() + { + UpdateBackground(); + OnPropertyChanged(nameof(Name)); + } + + private void UpdateBackground() + { + var currentApplication = Avalonia.Application.Current; + currentApplication.Styles.TryGetResource("ControlFillColorSecondary", currentApplication.ActualThemeVariant, out object color); + + if (color is not null) + { + BackgroundColor = _profile.AccountState == AccountState.Open ? new SolidColorBrush((Color)color) : Brushes.Transparent; + } + } + + public void Recover(UserProfile userProfile) + { + _owner.Navigate(typeof(UserEditorView), (_owner, userProfile, true)); + } + } +} |