diff --git a/editor/inspector/editor_resource_picker.cpp b/editor/inspector/editor_resource_picker.cpp index 88a641b5cf9..e3cf965819f 100644 --- a/editor/inspector/editor_resource_picker.cpp +++ b/editor/inspector/editor_resource_picker.cpp @@ -53,8 +53,26 @@ static bool _has_sub_resources(const Ref &p_res) { List property_list; p_res->get_property_list(&property_list); for (const PropertyInfo &p : property_list) { + Variant value = p_res->get(p.name); if (p.type == Variant::OBJECT && p.hint == PROPERTY_HINT_RESOURCE_TYPE && !(p.usage & PROPERTY_USAGE_NEVER_DUPLICATE) && p_res->get(p.name).get_validated_object()) { return true; + } else if (p.type == Variant::ARRAY) { + Array arr = value; + for (Variant &var : arr) { + Ref res = var; + if (res.is_valid()) { + return true; + } + } + } else if (p.type == Variant::DICTIONARY) { + Dictionary dict = value; + for (const KeyValue &kv : dict) { + Ref resk = kv.key; + Ref resv = kv.value; + if (resk.is_valid() || resv.is_valid()) { + return true; + } + } } } return false; @@ -1097,9 +1115,9 @@ void EditorResourcePicker::_gather_resources_to_duplicate(const Ref p_ } if (res_name.is_empty()) { - p_item->set_text(0, p_resource->get_class()); + p_item->set_text(0, _get_resource_type(p_resource)); } else { - p_item->set_text(0, vformat("%s (%s)", p_resource->get_class(), res_name)); + p_item->set_text(0, vformat("%s (%s)", _get_resource_type(p_resource), res_name)); } p_item->set_icon(0, EditorNode::get_singleton()->get_object_icon(p_resource.ptr())); @@ -1122,7 +1140,47 @@ void EditorResourcePicker::_gather_resources_to_duplicate(const Ref p_ p_resource->get_property_list(&plist); for (const PropertyInfo &E : plist) { - if (!(E.usage & PROPERTY_USAGE_STORAGE) || E.type != Variant::OBJECT || E.hint != PROPERTY_HINT_RESOURCE_TYPE) { + if (!(E.usage & PROPERTY_USAGE_STORAGE) || (E.type != Variant::OBJECT && E.type != Variant::ARRAY && E.type != Variant::DICTIONARY)) { + continue; + } + + Variant value = p_resource->get(E.name); + TreeItem *child = nullptr; + + if (E.type == Variant::ARRAY) { + Array arr = value; + for (int i = 0; i < arr.size(); i++) { + Ref res = arr[i]; + if (res.is_valid()) { + child = p_item->create_child(); + _gather_resources_to_duplicate(res, child, E.name); + meta = child->get_metadata(0); + meta.push_back(E.name); + meta.push_back(i); // Remember index. + } + } + continue; + } else if (E.type == Variant::DICTIONARY) { + Dictionary dict = value; + for (const KeyValue &kv : dict) { + Ref key_res = kv.key; + Ref value_res = kv.value; + if (key_res.is_valid()) { + child = p_item->create_child(); + _gather_resources_to_duplicate(key_res, child, E.name); + meta = child->get_metadata(0); + meta.push_back(E.name); + meta.push_back(key_res); + } + if (value_res.is_valid()) { + child = p_item->create_child(); + _gather_resources_to_duplicate(value_res, child, E.name); + meta = child->get_metadata(0); + meta.push_back(E.name); + meta.push_back(value_res); + meta.push_back(kv.key); + } + } continue; } @@ -1130,13 +1188,11 @@ void EditorResourcePicker::_gather_resources_to_duplicate(const Ref p_ if (res.is_null()) { continue; } - - TreeItem *child = p_item->create_child(); + child = p_item->create_child(); _gather_resources_to_duplicate(res, child, E.name); - meta = child->get_metadata(0); // Remember property name. - meta.append(E.name); + meta.push_back(E.name); if ((E.usage & PROPERTY_USAGE_NEVER_DUPLICATE)) { // The resource can't be duplicated, but make it appear on the list anyway. @@ -1161,10 +1217,47 @@ void EditorResourcePicker::_duplicate_selected_resources() { if (meta.size() == 1) { // Root. edited_resource = unique_resource; _resource_changed(); - } else { - Array parent_meta = item->get_parent()->get_metadata(0); - Ref parent = parent_meta[0]; + continue; + } + Array parent_meta = item->get_parent()->get_metadata(0); + Ref parent = parent_meta[0]; + Variant::Type property_type = parent->get(meta[1]).get_type(); + + if (property_type == Variant::OBJECT) { parent->set(meta[1], unique_resource); + continue; + } + + Variant property = parent->get(meta[1]); + + if (!parent_meta.has(property)) { + property = property.duplicate(); + parent->set(meta[1], property); + parent_meta.push_back(property); // Append Duplicated Type so we can check if it's already been duplicated. + } + + if (property_type == Variant::ARRAY) { + Array arr = property; + arr[meta[2]] = unique_resource; + continue; + } + + Dictionary dict = property; + LocalVector keys = dict.get_key_list(); + + if (meta[2].get_type() == Variant::OBJECT) { + if (keys.has(meta[2])) { + //It's a key. + dict[unique_resource] = dict[meta[2]]; + dict.erase(meta[2]); + parent_meta.push_back(unique_resource); + } else { + // If key has been erased, use last appended Resource key instead. + Variant key = keys.has(meta[3]) ? meta[3] : parent_meta.back(); + dict[key] = unique_resource; + } + } else { + dict[meta[2]] = unique_resource; } } }