Ver código fonte

Editor: Focus value editor on type change in Dictionary and Array editors

Valentin Cocaud 1 ano atrás
pai
commit
c31111f5ec

+ 13 - 0
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) {

+ 1 - 0
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;

+ 20 - 0
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;

+ 8 - 3
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<EditorPropertyDictionaryObject> 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;