diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 80e2302e91a..33f460e23db 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -652,6 +652,19 @@ void EditorProperty::add_focusable(Control *p_control) { focusables.push_back(p_control); } +void EditorProperty::grab_focus(int p_focusable) { + if (focusables.is_empty()) { + return; + } + + if (p_focusable >= 0) { + ERR_FAIL_INDEX(p_focusable, focusables.size()); + focusables[p_focusable]->grab_focus(); + } else { + focusables[0]->grab_focus(); + } +} + void EditorProperty::select(int p_focusable) { bool already_selected = selected; if (!selectable) { diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h index a0ced55bd83..f9b0d1f0949 100644 --- a/editor/editor_inspector.h +++ b/editor/editor_inspector.h @@ -192,6 +192,7 @@ public: void set_deletable(bool p_enable); bool is_deletable() const; void add_focusable(Control *p_control); + void grab_focus(int p_focusable = -1); void select(int p_focusable = -1); void deselect(); bool is_selected() const; diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index 555165c156a..53a10a779f9 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -255,6 +255,10 @@ void EditorPropertyArray::_change_type_menu(int p_index) { return; } + ERR_FAIL_COND_MSG( + changing_type_index == EditorPropertyArrayObject::NOT_CHANGING_TYPE, + "Tried to change type of an array item, but no item was selected."); + Variant value; VariantInternal::initialize(&value, Variant::Type(p_index)); @@ -444,6 +448,10 @@ void EditorPropertyArray::update_property() { slot.prop = new_prop; slot.set_index(idx); } + if (slot.index == changing_type_index) { + callable_mp(slot.prop, &EditorProperty::grab_focus).call_deferred(0); + changing_type_index = EditorPropertyArrayObject::NOT_CHANGING_TYPE; + } slot.prop->update_property(); } @@ -921,6 +929,10 @@ void EditorPropertyDictionary::_create_new_property_slot(int p_idx) { } void EditorPropertyDictionary::_change_type_menu(int p_index) { + ERR_FAIL_COND_MSG( + changing_type_index == EditorPropertyDictionaryObject::NOT_CHANGING_TYPE, + "Tried to change the type of a dict key or value, but nothing was selected."); + Variant value; switch (changing_type_index) { case EditorPropertyDictionaryObject::NEW_KEY_INDEX: @@ -1062,6 +1074,14 @@ void EditorPropertyDictionary::update_property() { new_prop->set_read_only(is_read_only()); slot.set_prop(new_prop); } + + // We need to grab the focus of the property that is being changed, even if the type didn't actually changed. + // Otherwise, focus will stay on the change type button, which is not very user friendly. + if (changing_type_index == slot.index) { + callable_mp(slot.prop, &EditorProperty::grab_focus).call_deferred(0); + changing_type_index = EditorPropertyDictionaryObject::NOT_CHANGING_TYPE; // Reset to avoid grabbing focus again. + } + slot.prop->update_property(); } updating = false; diff --git a/editor/editor_properties_array_dict.h b/editor/editor_properties_array_dict.h index 8b939ab0b03..267cb1e86d1 100644 --- a/editor/editor_properties_array_dict.h +++ b/editor/editor_properties_array_dict.h @@ -49,6 +49,10 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; public: + enum { + NOT_CHANGING_TYPE = -1, + }; + void set_array(const Variant &p_array); Variant get_array(); @@ -68,7 +72,8 @@ protected: public: enum { - NEW_KEY_INDEX = -2, + NOT_CHANGING_TYPE = -3, + NEW_KEY_INDEX, NEW_VALUE_INDEX, }; @@ -111,7 +116,7 @@ class EditorPropertyArray : public EditorProperty { int page_length = 20; int page_index = 0; - int changing_type_index; + int changing_type_index = EditorPropertyArrayObject::NOT_CHANGING_TYPE; Button *edit = nullptr; PanelContainer *container = nullptr; VBoxContainer *property_vbox = nullptr; @@ -206,7 +211,7 @@ class EditorPropertyDictionary : public EditorProperty { Ref object; int page_length = 20; int page_index = 0; - int changing_type_index; + int changing_type_index = EditorPropertyDictionaryObject::NOT_CHANGING_TYPE; Button *edit = nullptr; PanelContainer *container = nullptr; VBoxContainer *property_vbox = nullptr;