summaryrefslogtreecommitdiffstats
path: root/editor/editor_properties_array_dict.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/editor_properties_array_dict.cpp')
-rw-r--r--editor/editor_properties_array_dict.cpp111
1 files changed, 96 insertions, 15 deletions
diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp
index a6c7d6b617..da072744b8 100644
--- a/editor/editor_properties_array_dict.cpp
+++ b/editor/editor_properties_array_dict.cpp
@@ -40,6 +40,7 @@
#include "editor/inspector_dock.h"
#include "editor/themes/editor_scale.h"
#include "scene/gui/button.h"
+#include "scene/gui/margin_container.h"
#include "scene/resources/packed_scene.h"
bool EditorPropertyArrayObject::_set(const StringName &p_name, const Variant &p_value) {
@@ -328,6 +329,7 @@ void EditorPropertyArray::update_property() {
memdelete(container);
button_add_item = nullptr;
container = nullptr;
+ slots.clear();
}
return;
}
@@ -483,9 +485,10 @@ bool EditorPropertyArray::_is_drop_valid(const Dictionary &p_drag_data) const {
}
Dictionary drag_data = p_drag_data;
+ const String drop_type = drag_data.get("type", "");
- if (drag_data.has("type") && String(drag_data["type"]) == "files") {
- Vector<String> files = drag_data["files"];
+ if (drop_type == "files") {
+ PackedStringArray files = drag_data["files"];
for (int i = 0; i < files.size(); i++) {
const String &file = files[i];
@@ -504,6 +507,56 @@ bool EditorPropertyArray::_is_drop_valid(const Dictionary &p_drag_data) const {
return true;
}
+ if (drop_type == "nodes") {
+ Array node_paths = drag_data["nodes"];
+
+ PackedStringArray allowed_subtype_array;
+ if (allowed_type == "NodePath") {
+ if (subtype_hint_string == "NodePath") {
+ return true;
+ } else {
+ for (int j = 0; j < subtype_hint_string.get_slice_count(","); j++) {
+ String ast = subtype_hint_string.get_slice(",", j).strip_edges();
+ allowed_subtype_array.append(ast);
+ }
+ }
+ }
+
+ bool is_drop_allowed = true;
+
+ for (int i = 0; i < node_paths.size(); i++) {
+ const Node *dropped_node = get_node_or_null(node_paths[i]);
+ ERR_FAIL_NULL_V_MSG(dropped_node, false, "Could not get the dropped node by its path.");
+
+ if (allowed_type != "NodePath") {
+ if (!ClassDB::is_parent_class(dropped_node->get_class_name(), allowed_type)) {
+ // Fail if one of the nodes is not of allowed type.
+ return false;
+ }
+ }
+
+ // The array of NodePaths is restricted to specific types using @export_node_path().
+ if (allowed_type == "NodePath" && subtype_hint_string != "NodePath") {
+ if (!allowed_subtype_array.has(dropped_node->get_class_name())) {
+ // The dropped node type was not found in the allowed subtype array, we must check if it inherits one of them.
+ for (const String &ast : allowed_subtype_array) {
+ if (ClassDB::is_parent_class(dropped_node->get_class_name(), ast)) {
+ is_drop_allowed = true;
+ break;
+ } else {
+ is_drop_allowed = false;
+ }
+ }
+ if (!is_drop_allowed) {
+ break;
+ }
+ }
+ }
+ }
+
+ return is_drop_allowed;
+ }
+
return false;
}
@@ -515,18 +568,18 @@ void EditorPropertyArray::drop_data_fw(const Point2 &p_point, const Variant &p_d
ERR_FAIL_COND(!_is_drop_valid(p_data));
Dictionary drag_data = p_data;
+ const String drop_type = drag_data.get("type", "");
+ Variant array = object->get_array();
- if (drag_data.has("type") && String(drag_data["type"]) == "files") {
- Vector<String> files = drag_data["files"];
-
- Variant array = object->get_array();
+ // Handle the case where array is not initialized yet.
+ if (!array.is_array()) {
+ initialize_array(array);
+ } else {
+ array = array.duplicate();
+ }
- // Handle the case where array is not initialized yet.
- if (!array.is_array()) {
- initialize_array(array);
- } else {
- array = array.duplicate();
- }
+ if (drop_type == "files") {
+ PackedStringArray files = drag_data["files"];
// Loop the file array and add to existing array.
for (int i = 0; i < files.size(); i++) {
@@ -540,6 +593,33 @@ void EditorPropertyArray::drop_data_fw(const Point2 &p_point, const Variant &p_d
emit_changed(get_edited_property(), array);
}
+
+ if (drop_type == "nodes") {
+ Array node_paths = drag_data["nodes"];
+ Node *base_node = get_base_node();
+
+ for (int i = 0; i < node_paths.size(); i++) {
+ const NodePath &path = node_paths[i];
+
+ if (subtype == Variant::OBJECT) {
+ array.call("push_back", get_node(path));
+ } else if (subtype == Variant::NODE_PATH) {
+ array.call("push_back", base_node->get_path().rel_path_to(path));
+ }
+ }
+
+ emit_changed(get_edited_property(), array);
+ }
+}
+
+Node *EditorPropertyArray::get_base_node() {
+ Node *base_node = Object::cast_to<Node>(InspectorDock::get_inspector_singleton()->get_edited_object());
+
+ if (!base_node) {
+ base_node = get_tree()->get_edited_scene_root();
+ }
+
+ return base_node;
}
void EditorPropertyArray::_notification(int p_what) {
@@ -586,7 +666,7 @@ void EditorPropertyArray::_edit_pressed() {
Variant array = get_edited_property_value();
if (!array.is_array() && edit->is_pressed()) {
initialize_array(array);
- get_edited_object()->set(get_edited_property(), array);
+ emit_changed(get_edited_property(), array);
}
get_edited_object()->editor_set_section_unfold(get_edited_property(), edit->is_pressed());
@@ -867,7 +947,7 @@ void EditorPropertyDictionary::setup(PropertyHint p_hint) {
void EditorPropertyDictionary::update_property() {
Variant updated_val = get_edited_property_value();
- if (updated_val.get_type() == Variant::NIL) {
+ if (updated_val.get_type() != Variant::DICTIONARY) {
edit->set_text(TTR("Dictionary (Nil)")); // This provides symmetry with the array property.
edit->set_pressed(false);
if (container) {
@@ -875,6 +955,7 @@ void EditorPropertyDictionary::update_property() {
memdelete(container);
button_add_item = nullptr;
container = nullptr;
+ slots.clear();
}
return;
}
@@ -1021,7 +1102,7 @@ void EditorPropertyDictionary::_edit_pressed() {
Variant prop_val = get_edited_property_value();
if (prop_val.get_type() == Variant::NIL && edit->is_pressed()) {
VariantInternal::initialize(&prop_val, Variant::DICTIONARY);
- get_edited_object()->set(get_edited_property(), prop_val);
+ emit_changed(get_edited_property(), prop_val);
}
get_edited_object()->editor_set_section_unfold(get_edited_property(), edit->is_pressed());