using System; using System.Linq; using Godot; namespace GodotHostTest.GodotDI; public partial class ScopePickerEditor : EditorProperty { /// /// The "combo box" that picks a choice from the scopes. /// private OptionButton _optionButton = new(); /// /// The currently chosen type. /// private string _currentType; /// /// All the known fully qualified names for scopes. /// private string[] _fullyQualifiedNames; /// /// A guard against internal changes while the property is being updated. /// private bool _updating; public ScopePickerEditor() { // save all the known fully qualified names _fullyQualifiedNames = ScopeTypesAndNames.GetQualifiedNames().ToArray(); // fill the options button for (var i = 0; i < _fullyQualifiedNames.Length; i++) { // root scope is always the first, and root scope = not scoped _optionButton.AddItem( i == 0 ? "not a scope boundary" : ScopeTypesAndNames.GetSimpleNameFromQualifiedName(_fullyQualifiedNames[i]), i); } // add the control as a direct child of EditorProperty node. AddChild(_optionButton); // make sure the control is able to retain the focus. AddFocusable(_optionButton); // initialize the starting value _currentType = _fullyQualifiedNames[0]; // update the property when the button value changes _optionButton.ItemSelected += OnOptionButtonItemSelected; } public override void _UpdateProperty() { // get the new value and immediately return if it's already the selected one. var newValue = GetEditedObject().Get(GetEditedProperty()).AsString(); if (newValue == _currentType) return; _updating = true; try { var nameIndex = Array.IndexOf(_fullyQualifiedNames, newValue); if (nameIndex < 0) { GD.PushWarning($"Could not find name {newValue} in the list of scope names, resetting to root scope"); _currentType = _fullyQualifiedNames[0]; EmitChanged(GetEditedProperty(), _currentType); return; } _currentType = newValue; UpdateControl(); } finally { _updating = false; } } private void OnOptionButtonItemSelected(long index) { _currentType = _fullyQualifiedNames[index]; UpdateControl(); EmitChanged(GetEditedProperty(), _currentType); } private void UpdateControl() { _optionButton.Selected = Array.IndexOf(_fullyQualifiedNames, _currentType); } }