From 76671d63d4f3ea18f8ad99e9ce9f0b2ec9a2599d Mon Sep 17 00:00:00 2001
From: Isaac Marovitz <42140194+IsaacMarovitz@users.noreply.github.com>
Date: Thu, 29 Dec 2022 14:24:05 +0000
Subject: Ava GUI: Restructure `Ryujinx.Ava` (#4165)

* Restructure `Ryujinx.Ava`

* Stylistic consistency

* Update Ryujinx.Ava/UI/Controls/UserEditor.axaml.cs

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>

* Update Ryujinx.Ava/UI/Controls/UserEditor.axaml.cs

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>

* Update Ryujinx.Ava/UI/Controls/UserSelector.axaml.cs

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>

* Update Ryujinx.Ava/UI/Controls/SaveManager.axaml.cs

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>

* Update Ryujinx.Ava/UI/Controls/SaveManager.axaml.cs

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>

* Update Ryujinx.Ava/UI/Windows/SettingsWindow.axaml.cs

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>

* Update Ryujinx.Ava/UI/Helpers/EmbeddedWindow.cs

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>

* Update Ryujinx.Ava/UI/Helpers/EmbeddedWindow.cs

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>

* Update Ryujinx.Ava/UI/Helpers/EmbeddedWindow.cs

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>

* Update Ryujinx.Ava/UI/Helpers/EmbeddedWindow.cs

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>

* Update Ryujinx.Ava/UI/Windows/SettingsWindow.axaml.cs

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>

* Update Ryujinx.Ava/UI/ViewModels/UserProfileViewModel.cs

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>

* Update Ryujinx.Ava/UI/ViewModels/UserProfileViewModel.cs

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>

* Update Ryujinx.Ava/UI/Helpers/EmbeddedWindow.cs

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>

* Fix redundancies

* Remove redunancies

* Add back elses

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
---
 Ryujinx.Ava/UI/Helpers/ButtonKeyAssigner.cs | 118 ++++++++++++++++++++++++++++
 1 file changed, 118 insertions(+)
 create mode 100644 Ryujinx.Ava/UI/Helpers/ButtonKeyAssigner.cs

(limited to 'Ryujinx.Ava/UI/Helpers/ButtonKeyAssigner.cs')

diff --git a/Ryujinx.Ava/UI/Helpers/ButtonKeyAssigner.cs b/Ryujinx.Ava/UI/Helpers/ButtonKeyAssigner.cs
new file mode 100644
index 00000000..6730b571
--- /dev/null
+++ b/Ryujinx.Ava/UI/Helpers/ButtonKeyAssigner.cs
@@ -0,0 +1,118 @@
+using Avalonia.Controls;
+using Avalonia.Controls.Primitives;
+using Avalonia.LogicalTree;
+using Avalonia.Threading;
+using Ryujinx.Input;
+using Ryujinx.Input.Assigner;
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Ryujinx.Ava.UI.Helpers
+{
+    internal class ButtonKeyAssigner
+    {
+        internal class ButtonAssignedEventArgs : EventArgs
+        {
+            public ToggleButton Button { get; }
+            public bool IsAssigned { get; }
+
+            public ButtonAssignedEventArgs(ToggleButton button, bool isAssigned)
+            {
+                Button = button;
+                IsAssigned = isAssigned;
+            }
+        }
+        
+        public ToggleButton ToggledButton { get; set; }
+
+        private bool _isWaitingForInput;
+        private bool _shouldUnbind;
+        public event EventHandler<ButtonAssignedEventArgs> ButtonAssigned;
+
+        public ButtonKeyAssigner(ToggleButton toggleButton)
+        {
+            ToggledButton = toggleButton;
+        }
+
+        public async void GetInputAndAssign(IButtonAssigner assigner, IKeyboard keyboard = null)
+        {
+            Dispatcher.UIThread.Post(() =>
+            {
+                ToggledButton.IsChecked = true;
+            });
+
+            if (_isWaitingForInput)
+            {
+                Dispatcher.UIThread.Post(() =>
+                {
+                    Cancel();
+                });
+
+                return;
+            }
+
+            _isWaitingForInput = true;
+
+            assigner.Initialize();
+
+            await Task.Run(async () =>
+            {
+                while (true)
+                {
+                    if (!_isWaitingForInput)
+                    {
+                        return;
+                    }
+
+                    await Task.Delay(10);
+
+                    assigner.ReadInput();
+
+                    if (assigner.HasAnyButtonPressed() || assigner.ShouldCancel() || (keyboard != null && keyboard.IsPressed(Key.Escape)))
+                    {
+                        break;
+                    }
+                }
+            });
+
+            await Dispatcher.UIThread.InvokeAsync(() =>
+            {
+                string pressedButton = assigner.GetPressedButton();
+
+                if (_shouldUnbind)
+                {
+                    SetButtonText(ToggledButton, "Unbound");
+                }
+                else if (pressedButton != "")
+                {
+                    SetButtonText(ToggledButton, pressedButton);
+                }
+
+                _shouldUnbind = false;
+                _isWaitingForInput = false;
+
+                ToggledButton.IsChecked = false;
+
+                ButtonAssigned?.Invoke(this, new ButtonAssignedEventArgs(ToggledButton, pressedButton != null));
+
+                static void SetButtonText(ToggleButton button, string text)
+                {
+                    ILogical textBlock = button.GetLogicalDescendants().First(x => x is TextBlock);
+
+                    if (textBlock != null && textBlock is TextBlock block)
+                    {
+                        block.Text = text;
+                    }
+                }
+            });
+        }
+
+        public void Cancel(bool shouldUnbind = false)
+        {
+            _isWaitingForInput = false;
+            ToggledButton.IsChecked = false;
+            _shouldUnbind = shouldUnbind;
+        }
+    }
+}
-- 
cgit v1.2.3-70-g09d2