Repository: godotengine/godot
File: editor/inspector/editor_resource_picker.cpp (C++)

Code before:
	}

	List<PropertyInfo> plist;
	p_resource->get_property_list(&plist);

	for (const PropertyInfo &E : plist) {
		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<Resource> 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<Variant, Variant> &kv : dict) {
				Ref<Resource> key_res = kv.key;
				Ref<Resource> 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;
		}

		Ref<Resource> res = p_resource->get(E.name);

Review comment (bug):
Should this be `ERR_FAIL_EDMSG` to show in the toaster?

Code after:
	if (!base_type.is_empty()) {
		_ensure_allowed_types();
		HashSet<StringName> allowed_types = allowed_types_with_convert;

		StringName custom_class;
		bool is_custom = false;
		if (p_resource->get_script()) {
			custom_class = EditorNode::get_singleton()->get_object_custom_type_name(p_resource->get_script());
			is_custom = _is_type_valid(custom_class, allowed_types);
		}

		if (!is_custom && !_is_type_valid(p_resource->get_class(), allowed_types)) {
			return false;
		}
	}
	return true;
}

void EditorResourcePicker::set_edited_resource(Ref<Resource> p_resource) {
	if (!is_resource_allowed(p_resource)) {
		StringName custom_class;
		if (p_resource->get_script()) {
			custom_class = EditorNode::get_singleton()->get_object_custom_type_name(p_resource->get_script());
		}
		const String class_str = (custom_class.is_empty() ? p_resource->get_class() : vformat("%s (%s)", custom_class, p_resource->get_class()));
		ERR_FAIL_MSG(vformat("Failed to set a resource of the type '%s' because this EditorResourcePicker only accepts '%s' and its derivatives.", class_str, base_type));
	}
	set_edited_resource_no_check(p_resource);
}

void EditorResourcePicker::set_edited_resource_no_check(Ref<Resource> p_resource) {
	edited_resource = p_resource;
	_update_resource();
}

Ref<Resource> EditorResourcePicker::get_edited_resource() {
	return edited_resource;
}

void EditorResourcePicker::set_toggle_mode(bool p_enable) {
	assign_button->set_toggle_mode(p_enable);
}

bool EditorResourcePicker::is_toggle_mode() const {
	return assign_button->is_toggle_mode();
}

void EditorResourcePicker::set_toggle_pressed(bool p_pressed) {
	if (!is_toggle_mode()) {
		return;
	}