Fix non-typed Dictionary keys displayed as <null> in the inspector.

This commit is contained in:
bruvzg 2025-01-08 11:18:11 +02:00 committed by Pāvels Nadtočajevs
parent 8c6dbff6d3
commit b8860f1c11
2 changed files with 130 additions and 21 deletions

View File

@ -347,10 +347,15 @@ void EditorPropertyArray::_create_new_property_slot() {
slots.push_back(slot);
}
void EditorPropertyArray::set_preview_value(bool p_preview_value) {
preview_value = p_preview_value;
}
void EditorPropertyArray::update_property() {
Variant array = get_edited_property_value();
String array_type_name = Variant::get_type_name(array_type);
String array_sub_type_name;
if (array_type == Variant::ARRAY && subtype != Variant::NIL) {
String type_name;
if (subtype == Variant::OBJECT && (subtype_hint == PROPERTY_HINT_RESOURCE_TYPE || subtype_hint == PROPERTY_HINT_NODE_TYPE)) {
@ -359,11 +364,23 @@ void EditorPropertyArray::update_property() {
type_name = Variant::get_type_name(subtype);
}
array_type_name = vformat("%s[%s]", array_type_name, type_name);
if (preview_value) {
array_sub_type_name = vformat("[%s] ", type_name);
} else {
array_type_name = vformat("%s[%s]", array_type_name, type_name);
}
}
if (!array.is_array()) {
edit->set_text(vformat(TTR("(Nil) %s"), array_type_name));
if (preview_value) {
edit->set_text_alignment(HORIZONTAL_ALIGNMENT_LEFT);
edit->set_button_icon(get_editor_theme_icon(SNAME("Nil")));
edit->set_text(array_type_name);
} else {
edit->set_text_alignment(HORIZONTAL_ALIGNMENT_CENTER);
edit->set_button_icon(Ref<Texture2D>());
edit->set_text(vformat(TTR("(Nil) %s"), array_type_name));
}
edit->set_pressed(false);
if (container) {
set_bottom_editor(nullptr);
@ -383,7 +400,25 @@ void EditorPropertyArray::update_property() {
_page_changed(max_page);
}
edit->set_text(vformat(TTR("%s (size %s)"), array_type_name, itos(size)));
if (preview_value) {
String ctr_str = array.get_construct_string().trim_prefix(array_type_name + "(").trim_suffix(")").replace("\n", "");
if (array_type == Variant::ARRAY && subtype != Variant::NIL) {
int type_end = ctr_str.find("](");
if (type_end > 0) {
ctr_str = ctr_str.substr(type_end + 2);
}
}
edit->set_text_overrun_behavior(TextServer::OVERRUN_TRIM_ELLIPSIS);
edit->set_text_alignment(HORIZONTAL_ALIGNMENT_LEFT);
edit->set_button_icon(get_editor_theme_icon(array_type_name));
edit->set_text(vformat("%s%s", array_sub_type_name, ctr_str));
edit->set_tooltip_text(vformat(TTR("%s%s (size %d)"), array_type_name, array_sub_type_name, size));
} else {
edit->set_text_alignment(HORIZONTAL_ALIGNMENT_CENTER);
edit->set_button_icon(Ref<Texture2D>());
edit->set_text(vformat(TTR("%s (size %s)"), array_type_name, itos(size)));
}
bool unfolded = get_edited_object()->editor_is_section_unfolded(get_edited_property());
if (edit->is_pressed() != unfolded) {
@ -961,20 +996,7 @@ void EditorPropertyDictionary::_create_new_property_slot(int p_idx) {
EditorProperty *prop_key = nullptr;
if (p_idx != EditorPropertyDictionaryObject::NEW_KEY_INDEX && p_idx != EditorPropertyDictionaryObject::NEW_VALUE_INDEX) {
if (key_subtype == Variant::OBJECT) {
EditorPropertyObjectID *editor = memnew(EditorPropertyObjectID);
editor->setup("Object");
prop_key = editor;
} else {
prop_key = EditorInspector::instantiate_property_editor(this, key_subtype, "", key_subtype_hint, key_subtype_hint_string, PROPERTY_USAGE_NONE);
}
prop_key->set_read_only(true);
prop_key->set_selectable(false);
prop_key->set_focus_mode(Control::FOCUS_NONE);
prop_key->set_draw_background(false);
prop_key->set_use_folding(is_using_folding());
prop_key->set_h_size_flags(SIZE_EXPAND_FILL);
prop_key->set_draw_label(false);
prop_key = memnew(EditorPropertyNil);
hbox->add_child(prop_key);
}
@ -1096,10 +1118,15 @@ void EditorPropertyDictionary::setup(PropertyHint p_hint, const String &p_hint_s
}
}
void EditorPropertyDictionary::set_preview_value(bool p_preview_value) {
preview_value = p_preview_value;
}
void EditorPropertyDictionary::update_property() {
Variant updated_val = get_edited_property_value();
String dict_type_name = "Dictionary";
String dict_sub_type_name;
if (key_subtype != Variant::NIL || value_subtype != Variant::NIL) {
String key_subtype_name = "Variant";
if (key_subtype == Variant::OBJECT && (key_subtype_hint == PROPERTY_HINT_RESOURCE_TYPE || key_subtype_hint == PROPERTY_HINT_NODE_TYPE)) {
@ -1113,11 +1140,23 @@ void EditorPropertyDictionary::update_property() {
} else if (value_subtype != Variant::NIL) {
value_subtype_name = Variant::get_type_name(value_subtype);
}
dict_type_name += vformat("[%s, %s]", key_subtype_name, value_subtype_name);
if (preview_value) {
dict_sub_type_name = vformat("[%s, %s] ", key_subtype_name, value_subtype_name);
} else {
dict_type_name += vformat("[%s, %s]", key_subtype_name, value_subtype_name);
}
}
if (updated_val.get_type() != Variant::DICTIONARY) {
edit->set_text(vformat(TTR("(Nil) %s"), dict_type_name)); // This provides symmetry with the array property.
if (preview_value) {
edit->set_text_alignment(HORIZONTAL_ALIGNMENT_LEFT);
edit->set_button_icon(get_editor_theme_icon(SNAME("Nil")));
edit->set_text(dict_type_name);
} else {
edit->set_text_alignment(HORIZONTAL_ALIGNMENT_CENTER);
edit->set_button_icon(Ref<Texture2D>());
edit->set_text(vformat(TTR("(Nil) %s"), dict_type_name));
}
edit->set_pressed(false);
if (container) {
set_bottom_editor(nullptr);
@ -1133,7 +1172,25 @@ void EditorPropertyDictionary::update_property() {
Dictionary dict = updated_val;
object->set_dict(updated_val);
edit->set_text(vformat(TTR("%s (size %d)"), dict_type_name, dict.size()));
if (preview_value) {
String ctr_str = updated_val.get_construct_string().replace("\n", "");
if (key_subtype != Variant::NIL || value_subtype != Variant::NIL) {
int type_end = ctr_str.find("](");
if (type_end > 0) {
ctr_str = ctr_str.substr(type_end + 2).trim_suffix(")");
}
}
edit->set_text_overrun_behavior(TextServer::OVERRUN_TRIM_ELLIPSIS);
edit->set_text_alignment(HORIZONTAL_ALIGNMENT_LEFT);
edit->set_button_icon(get_editor_theme_icon(dict_type_name));
edit->set_text(vformat("%s%s", dict_sub_type_name, ctr_str));
edit->set_tooltip_text(vformat(TTR("%s%s (size %d)"), dict_type_name, dict_sub_type_name, dict.size()));
} else {
edit->set_text_alignment(HORIZONTAL_ALIGNMENT_CENTER);
edit->set_button_icon(Ref<Texture2D>());
edit->set_text(vformat(TTR("%s (size %d)"), dict_type_name, dict.size()));
}
bool unfolded = get_edited_object()->editor_is_section_unfolded(get_edited_property());
if (edit->is_pressed() != unfolded) {
@ -1199,6 +1256,44 @@ void EditorPropertyDictionary::update_property() {
if (!slot_visible) {
continue;
}
// Check if the editor property key needs to be updated.
if (slot.prop_key) {
Variant key;
object->get_by_property_name(slot.key_name, key);
Variant::Type key_type = key.get_type();
bool key_as_id = Object::cast_to<EncodedObjectAsID>(key);
if (key_type != slot.key_type || (key_type == Variant::OBJECT && key_as_id != slot.key_as_id)) {
slot.key_as_id = key_as_id;
slot.key_type = key_type;
EditorProperty *new_prop = nullptr;
if (key_type == Variant::OBJECT && key_as_id) {
EditorPropertyObjectID *editor = memnew(EditorPropertyObjectID);
editor->setup("Object");
new_prop = editor;
} else {
new_prop = EditorInspector::instantiate_property_editor(this, key_type, "", key_subtype_hint, key_subtype_hint_string, PROPERTY_USAGE_NONE);
}
new_prop->set_read_only(true);
new_prop->set_selectable(false);
new_prop->set_focus_mode(Control::FOCUS_NONE);
new_prop->set_draw_background(false);
new_prop->set_use_folding(is_using_folding());
new_prop->set_h_size_flags(SIZE_EXPAND_FILL);
new_prop->set_draw_label(false);
EditorPropertyArray *arr_prop = Object::cast_to<EditorPropertyArray>(new_prop);
if (arr_prop) {
arr_prop->set_preview_value(true);
}
EditorPropertyDictionary *dict_prop = Object::cast_to<EditorPropertyDictionary>(new_prop);
if (dict_prop) {
dict_prop->set_preview_value(true);
}
slot.set_key_prop(new_prop);
}
}
Variant value;
object->get_by_property_name(slot.prop_name, value);
Variant::Type value_type = value.get_type();
@ -1231,7 +1326,6 @@ void EditorPropertyDictionary::update_property() {
} else if (slot.index != EditorPropertyDictionaryObject::NEW_KEY_INDEX && slot.index != EditorPropertyDictionaryObject::NEW_VALUE_INDEX) {
Variant key = dict.get_key_at_index(slot.index);
String cs = key.get_construct_string();
slot.prop->set_label(cs);
slot.prop->set_tooltip_text(cs);
}

View File

@ -115,6 +115,7 @@ class EditorPropertyArray : public EditorProperty {
PopupMenu *change_type = nullptr;
bool preview_value = false;
int page_length = 20;
int page_index = 0;
int changing_type_index = EditorPropertyArrayObject::NOT_CHANGING_TYPE;
@ -169,6 +170,7 @@ protected:
public:
void setup(Variant::Type p_array_type, const String &p_hint_string = "");
void set_preview_value(bool p_preview_value);
virtual void update_property() override;
virtual bool is_colored(ColorationMode p_mode) override;
EditorPropertyArray();
@ -182,7 +184,9 @@ class EditorPropertyDictionary : public EditorProperty {
HBoxContainer *container = nullptr;
int index = -1;
Variant::Type type = Variant::VARIANT_MAX;
Variant::Type key_type = Variant::VARIANT_MAX;
bool as_id = false;
bool key_as_id = false;
EditorProperty *prop = nullptr;
EditorProperty *prop_key = nullptr;
String prop_name;
@ -202,6 +206,15 @@ class EditorPropertyDictionary : public EditorProperty {
update_prop_or_index();
}
void set_key_prop(EditorProperty *p_prop) {
if (prop_key) {
prop_key->add_sibling(p_prop);
prop_key->queue_free();
prop_key = p_prop;
update_prop_or_index();
}
}
void update_prop_or_index() {
prop->set_object_and_property(object.ptr(), prop_name);
if (prop_key) {
@ -215,6 +228,7 @@ class EditorPropertyDictionary : public EditorProperty {
PopupMenu *change_type = nullptr;
bool updating = false;
bool preview_value = false;
Ref<EditorPropertyDictionaryObject> object;
int page_length = 20;
int page_index = 0;
@ -252,6 +266,7 @@ protected:
public:
void setup(PropertyHint p_hint, const String &p_hint_string = "");
void set_preview_value(bool p_preview_value);
virtual void update_property() override;
virtual bool is_colored(ColorationMode p_mode) override;
EditorPropertyDictionary();