From 9b0c6a070a9d64a0c0e0cc4478a86af752cdcf82 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Fri, 21 Jul 2023 13:26:51 -0500 Subject: [PATCH 1/2] Add `InputEvent` and `InputAxis` editors and changed `UICanvas` to use them. --- .../CustomEditors/Editors/InputEditor.cs | 151 ++++++++++++++++++ Source/Engine/UI/GUI/CanvasRootControl.cs | 10 +- Source/Engine/UI/UICanvas.cs | 118 +++++++++----- 3 files changed, 236 insertions(+), 43 deletions(-) create mode 100644 Source/Editor/CustomEditors/Editors/InputEditor.cs diff --git a/Source/Editor/CustomEditors/Editors/InputEditor.cs b/Source/Editor/CustomEditors/Editors/InputEditor.cs new file mode 100644 index 000000000..0c00900b6 --- /dev/null +++ b/Source/Editor/CustomEditors/Editors/InputEditor.cs @@ -0,0 +1,151 @@ + +using System; +using System.Collections.Generic; +using FlaxEngine; +using FlaxEngine.GUI; + +namespace FlaxEditor.CustomEditors.Editors +{ + /// + /// Default implementation of the inspector used to edit input event properties. + /// + [CustomEditor(typeof(InputEvent)), DefaultEditor] + public class InputEventEditor : CustomEditor + { + private Dropdown _dropdown; + + /// + public override DisplayStyle Style => DisplayStyle.Inline; + + /// + public override void Initialize(LayoutElementsContainer layout) + { + var dropdownElement = layout.Custom(); + _dropdown = dropdownElement.CustomControl; + var eventNames = new List(); + foreach (var mapping in Input.ActionMappings) + { + if (eventNames.Contains(mapping.Name)) + continue; + eventNames.Add(mapping.Name); + } + _dropdown.Items = eventNames; + var value = Values[0] as InputEvent; + if (value != null) + { + if (eventNames.Contains(value.Name)) + { + _dropdown.SelectedItem = value.Name; + } + } + + _dropdown.SelectedIndexChanged += OnSelectedIndexChanged; + } + + private void OnSelectedIndexChanged(Dropdown dropdown) + { + SetValue(new InputEvent(dropdown.SelectedItem)); + } + + /// + public override void Refresh() + { + base.Refresh(); + + if (HasDifferentValues) + { + + } + else + { + if (Values[0] is InputEvent eventValue) + { + if (_dropdown.Items.Contains(eventValue.Name) && string.Equals(_dropdown.SelectedItem, eventValue.Name, StringComparison.Ordinal)) + { + _dropdown.SelectedItem = eventValue.Name; + } + } + } + } + + /// + protected override void Deinitialize() + { + if (_dropdown != null) + _dropdown.SelectedIndexChanged -= OnSelectedIndexChanged; + _dropdown = null; + base.Deinitialize(); + } + } + + /// + /// Default implementation of the inspector used to edit input axis properties. + /// + [CustomEditor(typeof(InputAxis)), DefaultEditor] + public class InputAxisEditor : CustomEditor + { + private Dropdown _dropdown; + + /// + public override DisplayStyle Style => DisplayStyle.Inline; + + /// + public override void Initialize(LayoutElementsContainer layout) + { + var dropdownElement = layout.Custom(); + _dropdown = dropdownElement.CustomControl; + var axisNames = new List(); + foreach (var mapping in Input.AxisMappings) + { + if (axisNames.Contains(mapping.Name)) + continue; + axisNames.Add(mapping.Name); + } + _dropdown.Items = axisNames; + var value = Values[0] as InputAxis; + if (value != null) + { + if (axisNames.Contains(value.Name)) + { + _dropdown.SelectedItem = value.Name; + } + } + _dropdown.SelectedIndexChanged += OnSelectedIndexChanged; + } + + private void OnSelectedIndexChanged(Dropdown dropdown) + { + SetValue(new InputAxis(dropdown.SelectedItem)); + } + + /// + public override void Refresh() + { + base.Refresh(); + + if (HasDifferentValues) + { + + } + else + { + if (Values[0] is InputAxis axisValue) + { + if (_dropdown.Items.Contains(axisValue.Name) && string.Equals(_dropdown.SelectedItem, axisValue.Name, StringComparison.Ordinal)) + { + _dropdown.SelectedItem = axisValue.Name; + } + } + } + } + + /// + protected override void Deinitialize() + { + if (_dropdown != null) + _dropdown.SelectedIndexChanged -= OnSelectedIndexChanged; + _dropdown = null; + base.Deinitialize(); + } + } +} diff --git a/Source/Engine/UI/GUI/CanvasRootControl.cs b/Source/Engine/UI/GUI/CanvasRootControl.cs index 408c46b0f..b4fa067e3 100644 --- a/Source/Engine/UI/GUI/CanvasRootControl.cs +++ b/Source/Engine/UI/GUI/CanvasRootControl.cs @@ -199,11 +199,11 @@ namespace FlaxEngine.GUI // UI navigation if (_canvas.ReceivesEvents) { - UpdateNavigation(deltaTime, _canvas.NavigationInputActionUp, NavDirection.Up, ref _navigationHeldTimeUp, ref _navigationRateTimeUp); - UpdateNavigation(deltaTime, _canvas.NavigationInputActionDown, NavDirection.Down, ref _navigationHeldTimeDown, ref _navigationRateTimeDown); - UpdateNavigation(deltaTime, _canvas.NavigationInputActionLeft, NavDirection.Left, ref _navigationHeldTimeLeft, ref _navigationRateTimeLeft); - UpdateNavigation(deltaTime, _canvas.NavigationInputActionRight, NavDirection.Right, ref _navigationHeldTimeRight, ref _navigationRateTimeRight); - UpdateNavigation(deltaTime, _canvas.NavigationInputActionSubmit, ref _navigationHeldTimeSubmit, ref _navigationRateTimeSubmit, SubmitFocused); + UpdateNavigation(deltaTime, _canvas.NavigateUp.Name, NavDirection.Up, ref _navigationHeldTimeUp, ref _navigationRateTimeUp); + UpdateNavigation(deltaTime, _canvas.NavigateDown.Name, NavDirection.Down, ref _navigationHeldTimeDown, ref _navigationRateTimeDown); + UpdateNavigation(deltaTime, _canvas.NavigateLeft.Name, NavDirection.Left, ref _navigationHeldTimeLeft, ref _navigationRateTimeLeft); + UpdateNavigation(deltaTime, _canvas.NavigateRight.Name, NavDirection.Right, ref _navigationHeldTimeRight, ref _navigationRateTimeRight); + UpdateNavigation(deltaTime, _canvas.NavigateSubmit.Name, ref _navigationHeldTimeSubmit, ref _navigationRateTimeSubmit, SubmitFocused); } else { diff --git a/Source/Engine/UI/UICanvas.cs b/Source/Engine/UI/UICanvas.cs index 87fc9506f..024fb8be0 100644 --- a/Source/Engine/UI/UICanvas.cs +++ b/Source/Engine/UI/UICanvas.cs @@ -263,39 +263,39 @@ namespace FlaxEngine public float NavigationInputRepeatRate { get; set; } = 0.05f; /// - /// The name of the input action for performing UI navigation Up (from Input Settings). + /// The input action for performing UI navigation Up (from Input Settings). /// [EditorOrder(510), EditorDisplay("Navigation", "Navigate Up")] - [Tooltip("The name of the input action for performing UI navigation Up (from Input Settings).")] - public string NavigationInputActionUp { get; set; } = "NavigateUp"; + [Tooltip("The input action for performing UI navigation Up (from Input Settings).")] + public InputEvent NavigateUp { get; set; } = new InputEvent("NavigateUp"); /// - /// The name of the input action for performing UI navigation Down (from Input Settings). + /// The input action for performing UI navigation Down (from Input Settings). /// [EditorOrder(520), EditorDisplay("Navigation", "Navigate Down")] - [Tooltip("The name of the input action for performing UI navigation Down (from Input Settings).")] - public string NavigationInputActionDown { get; set; } = "NavigateDown"; + [Tooltip("The input action for performing UI navigation Down (from Input Settings).")] + public InputEvent NavigateDown { get; set; } = new InputEvent("NavigateDown"); /// - /// The name of the input action for performing UI navigation Left (from Input Settings). + /// The input action for performing UI navigation Left (from Input Settings). /// [EditorOrder(530), EditorDisplay("Navigation", "Navigate Left")] - [Tooltip("The name of the input action for performing UI navigation Left (from Input Settings).")] - public string NavigationInputActionLeft { get; set; } = "NavigateLeft"; - + [Tooltip("The input action for performing UI navigation Left (from Input Settings).")] + public InputEvent NavigateLeft { get; set; } = new InputEvent("NavigateLeft"); + /// - /// The name of the input action for performing UI navigation Right (from Input Settings). + /// The input action for performing UI navigation Right (from Input Settings). /// [EditorOrder(540), EditorDisplay("Navigation", "Navigate Right")] - [Tooltip("The name of the input action for performing UI navigation Right (from Input Settings).")] - public string NavigationInputActionRight { get; set; } = "NavigateRight"; + [Tooltip("The input action for performing UI navigation Right (from Input Settings).")] + public InputEvent NavigateRight { get; set; } = new InputEvent("NavigateRight"); /// - /// The name of the input action for performing UI navigation Submit (from Input Settings). + /// The input action for performing UI navigation Submit (from Input Settings). /// - [EditorOrder(540), EditorDisplay("Navigation", "Navigate Submit")] - [Tooltip("The name of the input action for performing UI navigation Submit (from Input Settings).")] - public string NavigationInputActionSubmit { get; set; } = "NavigateSubmit"; + [EditorOrder(550), EditorDisplay("Navigation", "Navigate Submit")] + [Tooltip("The input action for performing UI navigation Submit (from Input Settings).")] + public InputEvent NavigateSubmit { get; set; } = new InputEvent("NavigateSubmit"); #endregion @@ -620,14 +620,36 @@ namespace FlaxEngine jsonWriter.WriteValue(NavigationInputRepeatDelay); jsonWriter.WritePropertyName("NavigationInputRepeatRate"); jsonWriter.WriteValue(NavigationInputRepeatRate); - jsonWriter.WritePropertyName("NavigationInputActionUp"); - jsonWriter.WriteValue(NavigationInputActionUp); - jsonWriter.WritePropertyName("NavigationInputActionDown"); - jsonWriter.WriteValue(NavigationInputActionDown); - jsonWriter.WritePropertyName("NavigationInputActionLeft"); - jsonWriter.WriteValue(NavigationInputActionLeft); - jsonWriter.WritePropertyName("NavigationInputActionRight"); - jsonWriter.WriteValue(NavigationInputActionRight); + + jsonWriter.WritePropertyName("NavigateUp"); + jsonWriter.WriteStartObject(); + jsonWriter.WritePropertyName("Name"); + jsonWriter.WriteValue(NavigateUp.Name); + jsonWriter.WriteEndObject(); + + jsonWriter.WritePropertyName("NavigateDown"); + jsonWriter.WriteStartObject(); + jsonWriter.WritePropertyName("Name"); + jsonWriter.WriteValue(NavigateDown.Name); + jsonWriter.WriteEndObject(); + + jsonWriter.WritePropertyName("NavigateLeft"); + jsonWriter.WriteStartObject(); + jsonWriter.WritePropertyName("Name"); + jsonWriter.WriteValue(NavigateLeft.Name); + jsonWriter.WriteEndObject(); + + jsonWriter.WritePropertyName("NavigateRight"); + jsonWriter.WriteStartObject(); + jsonWriter.WritePropertyName("Name"); + jsonWriter.WriteValue(NavigateRight.Name); + jsonWriter.WriteEndObject(); + + jsonWriter.WritePropertyName("NavigateSubmit"); + jsonWriter.WriteStartObject(); + jsonWriter.WritePropertyName("Name"); + jsonWriter.WriteValue(NavigateSubmit.Name); + jsonWriter.WriteEndObject(); jsonWriter.WriteEndObject(); } @@ -713,27 +735,47 @@ namespace FlaxEngine jsonWriter.WritePropertyName("NavigationInputRepeatRate"); jsonWriter.WriteValue(NavigationInputRepeatRate); } - if (NavigationInputActionUp != other.NavigationInputActionUp) + if (NavigateUp.Name != other.NavigateUp.Name) { - jsonWriter.WritePropertyName("NavigationInputActionUp"); - jsonWriter.WriteValue(NavigationInputActionUp); + jsonWriter.WritePropertyName("NavigateUp"); + jsonWriter.WriteStartObject(); + jsonWriter.WritePropertyName("Name"); + jsonWriter.WriteValue(NavigateUp.Name); + jsonWriter.WriteEndObject(); } - if (NavigationInputActionDown != other.NavigationInputActionDown) + if (NavigateDown.Name != other.NavigateDown.Name) { - jsonWriter.WritePropertyName("NavigationInputActionDown"); - jsonWriter.WriteValue(NavigationInputActionDown); + jsonWriter.WritePropertyName("NavigateDown"); + jsonWriter.WriteStartObject(); + jsonWriter.WritePropertyName("Name"); + jsonWriter.WriteValue(NavigateDown.Name); + jsonWriter.WriteEndObject(); } - if (NavigationInputActionLeft != other.NavigationInputActionLeft) + if (NavigateLeft.Name != other.NavigateLeft.Name) { - jsonWriter.WritePropertyName("NavigationInputActionLeft"); - jsonWriter.WriteValue(NavigationInputActionLeft); + jsonWriter.WritePropertyName("NavigateLeft"); + jsonWriter.WriteStartObject(); + jsonWriter.WritePropertyName("Name"); + jsonWriter.WriteValue(NavigateLeft.Name); + jsonWriter.WriteEndObject(); } - if (NavigationInputActionRight != other.NavigationInputActionRight) + if (NavigateRight.Name != other.NavigateRight.Name) { - jsonWriter.WritePropertyName("NavigationInputActionRight"); - jsonWriter.WriteValue(NavigationInputActionRight); + jsonWriter.WritePropertyName("NavigateRight"); + jsonWriter.WriteStartObject(); + jsonWriter.WritePropertyName("Name"); + jsonWriter.WriteValue(NavigateRight.Name); + jsonWriter.WriteEndObject(); } - + if (NavigateSubmit.Name != other.NavigateSubmit.Name) + { + jsonWriter.WritePropertyName("NavigateSubmit"); + jsonWriter.WriteStartObject(); + jsonWriter.WritePropertyName("Name"); + jsonWriter.WriteValue(NavigateSubmit.Name); + jsonWriter.WriteEndObject(); + } + jsonWriter.WriteEndObject(); } From 0ba9f7c51dd5721fe97c79a49ded9795770aebe9 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Fri, 21 Jul 2023 13:33:00 -0500 Subject: [PATCH 2/2] Small simplification of null checking for input editors --- Source/Editor/CustomEditors/Editors/InputEditor.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Source/Editor/CustomEditors/Editors/InputEditor.cs b/Source/Editor/CustomEditors/Editors/InputEditor.cs index 0c00900b6..3f8aaf093 100644 --- a/Source/Editor/CustomEditors/Editors/InputEditor.cs +++ b/Source/Editor/CustomEditors/Editors/InputEditor.cs @@ -30,8 +30,7 @@ namespace FlaxEditor.CustomEditors.Editors eventNames.Add(mapping.Name); } _dropdown.Items = eventNames; - var value = Values[0] as InputEvent; - if (value != null) + if (Values[0] is InputEvent value) { if (eventNames.Contains(value.Name)) { @@ -102,8 +101,7 @@ namespace FlaxEditor.CustomEditors.Editors axisNames.Add(mapping.Name); } _dropdown.Items = axisNames; - var value = Values[0] as InputAxis; - if (value != null) + if (Values[0] is InputAxis value) { if (axisNames.Contains(value.Name)) {