diff --git a/Source/Editor/CustomEditors/Editors/BindableButtonEditor.cs b/Source/Editor/CustomEditors/Editors/BindableButtonEditor.cs new file mode 100644 index 000000000..80d873cdf --- /dev/null +++ b/Source/Editor/CustomEditors/Editors/BindableButtonEditor.cs @@ -0,0 +1,96 @@ +using FlaxEditor.GUI; +using FlaxEngine; +using FlaxEngine.GUI; + +namespace FlaxEditor.CustomEditors.Editors +{ + /// + /// Base class for custom button editors. + /// See , and . + /// + public class BindableButtonEditor : EnumEditor + { + private bool _isListeningForInput; + private Button _button; + + /// + /// Where or not we are currently listening for any input. + /// + protected bool IsListeningForInput + { + get => _isListeningForInput; + set + { + _isListeningForInput = value; + if (_isListeningForInput) + SetupButton(); + else + ResetButton(); + } + } + + /// + /// The window this editor is attached to. + /// Useful to hook into for key pressed, mouse buttons etc. + /// + protected Window Window { get; private set; } + + /// + public override void Initialize(LayoutElementsContainer layout) + { + Window = layout.Control.RootWindow.Window; + + var panel = layout.CustomContainer(); + panel.CustomControl.SlotsHorizontally = 2; + panel.CustomControl.SlotsVertically = 1; + + var button = panel.Button("Listen"); + _button = button.Button; + _button.Clicked += OnButtonClicked; + ResetButton(); + + var padding = panel.CustomControl.SlotPadding; + panel.CustomControl.Height = ComboBox.DefaultHeight + padding.Height; + + base.Initialize(panel); + } + + /// + protected override void Deinitialize() + { + _button.Clicked -= OnButtonClicked; + base.Deinitialize(); + } + + private void ResetButton() + { + _button.Text = "Listen"; + _button.BorderThickness = 1; + + var style = FlaxEngine.GUI.Style.Current; + _button.BorderColor = style.BorderNormal; + _button.BorderColorHighlighted = style.BorderHighlighted; + _button.BorderColorSelected = style.BorderSelected; + } + + private void SetupButton() + { + _button.Text = "Listening..."; + _button.BorderThickness = 2; + + var color = FlaxEngine.GUI.Style.Current.ProgressNormal; + _button.BorderColor = color; + _button.BorderColorHighlighted = color; + _button.BorderColorSelected = color; + } + + private void OnButtonClicked() + { + _isListeningForInput = !_isListeningForInput; + if (_isListeningForInput) + SetupButton(); + else + ResetButton(); + } + } +} diff --git a/Source/Editor/CustomEditors/Editors/GamepadButtonEditor.cs b/Source/Editor/CustomEditors/Editors/GamepadButtonEditor.cs new file mode 100644 index 000000000..7bae24922 --- /dev/null +++ b/Source/Editor/CustomEditors/Editors/GamepadButtonEditor.cs @@ -0,0 +1,51 @@ +using System; +using FlaxEngine; + +namespace FlaxEditor.CustomEditors.Editors +{ + /// + /// Custom editor for . + /// Allows capturing gamepad buttons and assigning them + /// to the edited value. + /// + [CustomEditor(typeof(GamepadButton))] + public class GamepadButtonEditor : BindableButtonEditor + { + /// + public override void Initialize(LayoutElementsContainer layout) + { + base.Initialize(layout); + FlaxEngine.Scripting.Update += ScriptingOnUpdate; + } + + /// + protected override void Deinitialize() + { + FlaxEngine.Scripting.Update -= ScriptingOnUpdate; + base.Deinitialize(); + } + + private void ScriptingOnUpdate() + { + if (!IsListeningForInput) + return; + + // Since there is no way to get an event about + // which gamepad pressed what button, we have + // to poll all gamepads and buttons manually. + for (var i = 0; i < Input.GamepadsCount; i++) + { + var pad = Input.Gamepads[i]; + foreach (var btn in Enum.GetValues()) + { + if (pad.GetButtonUp(btn)) + { + IsListeningForInput = false; + SetValue(btn); + return; + } + } + } + } + } +} diff --git a/Source/Editor/CustomEditors/Editors/KeyboardKeysEditor.cs b/Source/Editor/CustomEditors/Editors/KeyboardKeysEditor.cs new file mode 100644 index 000000000..765527b7e --- /dev/null +++ b/Source/Editor/CustomEditors/Editors/KeyboardKeysEditor.cs @@ -0,0 +1,36 @@ +using FlaxEngine; + +namespace FlaxEditor.CustomEditors.Editors +{ + /// + /// Custom editor for . + /// Allows capturing key presses and assigning them + /// to the edited value. + /// + [CustomEditor(typeof(KeyboardKeys))] + public class KeyboardKeysEditor : BindableButtonEditor + { + /// + public override void Initialize(LayoutElementsContainer layout) + { + base.Initialize(layout); + Window.KeyUp += WindowOnKeyUp; + } + + /// + protected override void Deinitialize() + { + Window.KeyUp -= WindowOnKeyUp; + base.Deinitialize(); + } + + private void WindowOnKeyUp(KeyboardKeys key) + { + if (!IsListeningForInput) + return; + IsListeningForInput = false; + + SetValue(key); + } + } +} diff --git a/Source/Editor/CustomEditors/Editors/MouseButtonEditor.cs b/Source/Editor/CustomEditors/Editors/MouseButtonEditor.cs new file mode 100644 index 000000000..7964d3a4d --- /dev/null +++ b/Source/Editor/CustomEditors/Editors/MouseButtonEditor.cs @@ -0,0 +1,37 @@ +using FlaxEngine; + +namespace FlaxEditor.CustomEditors.Editors +{ + /// + /// Custom editor for . + /// Allows capturing mouse button presses and assigning them + /// to the edited value. + /// + [CustomEditor(typeof(MouseButton))] + public class MouseButtonEditor : BindableButtonEditor + { + /// + public override void Initialize(LayoutElementsContainer layout) + { + base.Initialize(layout); + Window.MouseUp += WindowOnMouseUp; + } + + /// + protected override void Deinitialize() + { + Window.MouseUp -= WindowOnMouseUp; + base.Deinitialize(); + } + + private void WindowOnMouseUp(ref Float2 mouse, MouseButton button, ref bool handled) + { + if (!IsListeningForInput) + return; + IsListeningForInput = false; + + SetValue(button); + handled = true; + } + } +}