Skip to content

Commit 12ced6c

Browse files
committed
Add support for making arrays and dictionaries with Resources unique
1 parent b4472f4 commit 12ced6c

File tree

1 file changed

+103
-10
lines changed

1 file changed

+103
-10
lines changed

editor/inspector/editor_resource_picker.cpp

Lines changed: 103 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,26 @@ static bool _has_sub_resources(const Ref<Resource> &p_res) {
5353
List<PropertyInfo> property_list;
5454
p_res->get_property_list(&property_list);
5555
for (const PropertyInfo &p : property_list) {
56+
Variant value = p_res->get(p.name);
5657
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()) {
5758
return true;
59+
} else if (p.type == Variant::ARRAY) {
60+
Array arr = value;
61+
for (Variant &var : arr) {
62+
Ref<Resource> res = var;
63+
if (res.is_valid()) {
64+
return true;
65+
}
66+
}
67+
} else if (p.type == Variant::DICTIONARY) {
68+
Dictionary dict = value;
69+
for (const KeyValue<Variant, Variant> &kv : dict) {
70+
Ref<Resource> resk = kv.key;
71+
Ref<Resource> resv = kv.value;
72+
if (resk.is_valid() || resv.is_valid()) {
73+
return true;
74+
}
75+
}
5876
}
5977
}
6078
return false;
@@ -1097,9 +1115,9 @@ void EditorResourcePicker::_gather_resources_to_duplicate(const Ref<Resource> p_
10971115
}
10981116

10991117
if (res_name.is_empty()) {
1100-
p_item->set_text(0, p_resource->get_class());
1118+
p_item->set_text(0, _get_resource_type(p_resource));
11011119
} else {
1102-
p_item->set_text(0, vformat("%s (%s)", p_resource->get_class(), res_name));
1120+
p_item->set_text(0, vformat("%s (%s)", _get_resource_type(p_resource), res_name));
11031121
}
11041122

11051123
p_item->set_icon(0, EditorNode::get_singleton()->get_object_icon(p_resource.ptr()));
@@ -1122,21 +1140,59 @@ void EditorResourcePicker::_gather_resources_to_duplicate(const Ref<Resource> p_
11221140
p_resource->get_property_list(&plist);
11231141

11241142
for (const PropertyInfo &E : plist) {
1125-
if (!(E.usage & PROPERTY_USAGE_STORAGE) || E.type != Variant::OBJECT || E.hint != PROPERTY_HINT_RESOURCE_TYPE) {
1143+
if (!(E.usage & PROPERTY_USAGE_STORAGE) || (E.type != Variant::OBJECT && E.type != Variant::ARRAY && E.type != Variant::DICTIONARY)) {
1144+
continue;
1145+
}
1146+
1147+
Variant value = p_resource->get(E.name);
1148+
TreeItem *child = nullptr;
1149+
1150+
if (E.type == Variant::ARRAY) {
1151+
Array arr = value;
1152+
for (int i = 0; i < arr.size(); i++) {
1153+
Ref<Resource> res = arr[i];
1154+
if (res.is_valid()) {
1155+
child = p_item->create_child();
1156+
_gather_resources_to_duplicate(res, child, E.name);
1157+
meta = child->get_metadata(0);
1158+
meta.push_back(E.name);
1159+
meta.push_back(i); // Remember index.
1160+
}
1161+
}
1162+
continue;
1163+
} else if (E.type == Variant::DICTIONARY) {
1164+
Dictionary dict = value;
1165+
for (const KeyValue<Variant, Variant> &kv : dict) {
1166+
Ref<Resource> key_res = kv.key;
1167+
Ref<Resource> value_res = kv.value;
1168+
if (key_res.is_valid()) {
1169+
child = p_item->create_child();
1170+
_gather_resources_to_duplicate(key_res, child, E.name);
1171+
meta = child->get_metadata(0);
1172+
meta.push_back(E.name);
1173+
meta.push_back(key_res);
1174+
}
1175+
if (value_res.is_valid()) {
1176+
child = p_item->create_child();
1177+
_gather_resources_to_duplicate(value_res, child, E.name);
1178+
meta = child->get_metadata(0);
1179+
meta.push_back(E.name);
1180+
meta.push_back(value_res);
1181+
meta.push_back(kv.key);
1182+
}
1183+
}
11261184
continue;
11271185
}
11281186

11291187
Ref<Resource> res = p_resource->get(E.name);
11301188
if (res.is_null()) {
11311189
continue;
11321190
}
1133-
1134-
TreeItem *child = p_item->create_child();
1191+
child = p_item->create_child();
11351192
_gather_resources_to_duplicate(res, child, E.name);
1136-
11371193
meta = child->get_metadata(0);
11381194
// Remember property name.
1139-
meta.append(E.name);
1195+
meta.push_back(E.name);
11401196

11411197
if ((E.usage & PROPERTY_USAGE_NEVER_DUPLICATE)) {
11421198
// The resource can't be duplicated, but make it appear on the list anyway.
@@ -1161,10 +1217,47 @@ void EditorResourcePicker::_duplicate_selected_resources() {
11611217
if (meta.size() == 1) { // Root.
11621218
edited_resource = unique_resource;
11631219
_resource_changed();
1164-
} else {
1165-
Array parent_meta = item->get_parent()->get_metadata(0);
1166-
Ref<Resource> parent = parent_meta[0];
1220+
continue;
1221+
}
1222+
Array parent_meta = item->get_parent()->get_metadata(0);
1223+
Ref<Resource> parent = parent_meta[0];
1224+
Variant::Type property_type = parent->get(meta[1]).get_type();
1225+
1226+
if (property_type == Variant::OBJECT) {
11671227
parent->set(meta[1], unique_resource);
1228+
continue;
1229+
}
1230+
1231+
Variant property = parent->get(meta[1]);
1232+
1233+
if (!parent_meta.has(property)) {
1234+
property = property.duplicate();
1235+
parent->set(meta[1], property);
1236+
parent_meta.push_back(property); // Append Duplicated Type so we can check if it's already been duplicated.
1237+
}
1238+
1239+
if (property_type == Variant::ARRAY) {
1240+
Array arr = property;
1241+
arr[meta[2]] = unique_resource;
1242+
continue;
1243+
}
1244+
1245+
Dictionary dict = property;
1246+
LocalVector<Variant> keys = dict.get_key_list();
1247+
1248+
if (meta[2].get_type() == Variant::OBJECT) {
1249+
if (keys.has(meta[2])) {
1250+
//It's a key.
1251+
dict[unique_resource] = dict[meta[2]];
1252+
dict.erase(meta[2]);
1253+
parent_meta.push_back(unique_resource);
1254+
} else {
1255+
// If key has been erased, use last appended Resource key instead.
1256+
Variant key = keys.has(meta[3]) ? meta[3] : parent_meta.back();
1257+
dict[key] = unique_resource;
1258+
}
1259+
} else {
1260+
dict[meta[2]] = unique_resource;
11681261
}
11691262
}
11701263
}

0 commit comments

Comments
 (0)