From 023bd5f00fcedb3933cdb95d0b974cf397a147de Mon Sep 17 00:00:00 2001
From: Evan Husted <greem@greemdev.net>
Date: Wed, 29 Jan 2025 20:27:01 -0600
Subject: [PATCH] UI: Enable Rainbow cycling in the Settings window

---
 src/Ryujinx.Input.SDL2/SDL2Gamepad.cs          |  4 +---
 .../Input/ControllerInputViewModel.cs          | 18 ++++++++++++++++++
 .../UI/ViewModels/Input/InputViewModel.cs      |  7 +++++++
 .../UI/Views/Main/MainMenuBarView.axaml.cs     |  5 +++++
 4 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs
index a473d7042..4c93d9d7b 100644
--- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs
+++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs
@@ -2,8 +2,6 @@ using Ryujinx.Common.Configuration.Hid;
 using Ryujinx.Common.Configuration.Hid.Controller;
 using Ryujinx.Common.Logging;
 using Ryujinx.Common.Utilities;
-using Ryujinx.HLE.HOS.Services.Hid;
-using SDL2;
 using System;
 using System.Collections.Generic;
 using System.Numerics;
@@ -12,7 +10,7 @@ using static SDL2.SDL;
 
 namespace Ryujinx.Input.SDL2
 {
-    class SDL2Gamepad : IGamepad
+    public class SDL2Gamepad : IGamepad
     {
         private bool HasConfiguration => _configuration != null;
 
diff --git a/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs b/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs
index 9fcf31a9b..42daa2f49 100644
--- a/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs
@@ -5,6 +5,7 @@ using FluentAvalonia.UI.Controls;
 using Ryujinx.Ava.UI.Helpers;
 using Ryujinx.Ava.UI.Models.Input;
 using Ryujinx.Ava.UI.Views.Input;
+using Ryujinx.Common.Utilities;
 using Ryujinx.UI.Views.Input;
 
 namespace Ryujinx.Ava.UI.ViewModels.Input
@@ -48,6 +49,23 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
             ParentModel = model;
             model.NotifyChangesEvent += OnParentModelChanged;
             OnParentModelChanged();
+            config.PropertyChanged += (_, args) =>
+            {
+                if (args.PropertyName is nameof(Config.UseRainbowLed))
+                {
+                    if (Config is { UseRainbowLed: true, TurnOffLed: false, EnableLedChanging: true })
+                        Rainbow.Updated += color => ParentModel.SelectedGamepad.SetLed((uint)color);
+                    else
+                    {
+                        Rainbow.Reset();
+                        
+                        if (Config.TurnOffLed)
+                            ParentModel.SelectedGamepad.ClearLed();
+                        else
+                            ParentModel.SelectedGamepad.SetLed(Config.LedColor.ToUInt32());
+                    }
+                }
+            };
             Config = config;
         }
 
diff --git a/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs
index 83cead1ac..6cc7744d8 100644
--- a/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs
@@ -20,6 +20,7 @@ using Ryujinx.Common.Configuration.Hid.Keyboard;
 using Ryujinx.Common.Logging;
 using Ryujinx.Common.Utilities;
 using Ryujinx.Input;
+using Ryujinx.Input.SDL2;
 using System;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
@@ -63,7 +64,13 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
             get => _selectedGamepad;
             private set
             {
+                Rainbow.Reset();
+                
                 _selectedGamepad = value;
+
+                if (ConfigViewModel is ControllerInputViewModel { Config.UseRainbowLed: true })
+                    Rainbow.Updated += color => _selectedGamepad.SetLed((uint)color);
+                
                 OnPropertiesChanged(nameof(HasLed), nameof(CanClearLed));
             }
         }
diff --git a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs
index 113c77e15..9a0836814 100644
--- a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs
+++ b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs
@@ -134,7 +134,12 @@ namespace Ryujinx.Ava.UI.Views.Main
         {
             Window.SettingsWindow = new(Window.VirtualFileSystem, Window.ContentManager);
 
+            Rainbow.Enable();
+            
             await Window.SettingsWindow.ShowDialog(Window);
+            
+            Rainbow.Disable();
+            Rainbow.Reset();
 
             Window.SettingsWindow = null;