summaryrefslogtreecommitdiff
path: root/scene/main
diff options
context:
space:
mode:
Diffstat (limited to 'scene/main')
-rw-r--r--scene/main/node.cpp27
-rw-r--r--scene/main/node.h1
-rw-r--r--scene/main/scene_tree.cpp16
-rw-r--r--scene/main/scene_tree.h1
4 files changed, 44 insertions, 1 deletions
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index f6a0f5a6c0..893621fbc4 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -1442,7 +1442,15 @@ Node *Node::get_node_or_null(const NodePath &p_path) const {
Node *Node::get_node(const NodePath &p_path) const {
Node *node = get_node_or_null(p_path);
- ERR_FAIL_COND_V_MSG(!node, nullptr, "Node not found: " + p_path + ".");
+
+ if (p_path.is_absolute()) {
+ ERR_FAIL_COND_V_MSG(!node, nullptr,
+ vformat(R"(Node not found: "%s" (absolute path attempted from "%s").)", p_path, get_path()));
+ } else {
+ ERR_FAIL_COND_V_MSG(!node, nullptr,
+ vformat(R"(Node not found: "%s" (relative to "%s").)", p_path, get_path()));
+ }
+
return node;
}
@@ -1966,6 +1974,23 @@ bool Node::is_editable_instance(const Node *p_node) const {
return p_node->data.editable_instance;
}
+Node *Node::get_deepest_editable_node(Node *p_start_node) const {
+ ERR_FAIL_NULL_V(p_start_node, nullptr);
+ ERR_FAIL_COND_V(!is_a_parent_of(p_start_node), nullptr);
+
+ Node const *iterated_item = p_start_node;
+ Node *node = p_start_node;
+
+ while (iterated_item->get_owner() && iterated_item->get_owner() != this) {
+ if (!is_editable_instance(iterated_item->get_owner()))
+ node = iterated_item->get_owner();
+
+ iterated_item = iterated_item->get_owner();
+ }
+
+ return node;
+}
+
void Node::set_scene_instance_state(const Ref<SceneState> &p_state) {
data.instance_state = p_state;
}
diff --git a/scene/main/node.h b/scene/main/node.h
index b3979993e0..249a0ff86e 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -330,6 +330,7 @@ public:
void set_editable_instance(Node *p_node, bool p_editable);
bool is_editable_instance(const Node *p_node) const;
+ Node *get_deepest_editable_node(Node *p_start_node) const;
/* NOTIFICATIONS */
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 9f32c65f7b..b10e23ac07 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -956,6 +956,21 @@ bool SceneTree::has_group(const StringName &p_identifier) const {
return group_map.has(p_identifier);
}
+Node *SceneTree::get_first_node_in_group(const StringName &p_group) {
+ Map<StringName, Group>::Element *E = group_map.find(p_group);
+ if (!E) {
+ return nullptr; //no group
+ }
+
+ _update_group_order(E->get()); //update order just in case
+
+ if (E->get().nodes.size() == 0) {
+ return nullptr;
+ }
+
+ return E->get().nodes[0];
+}
+
void SceneTree::get_nodes_in_group(const StringName &p_group, List<Node *> *p_list) {
Map<StringName, Group>::Element *E = group_map.find(p_group);
if (!E) {
@@ -1216,6 +1231,7 @@ void SceneTree::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_group", "group", "property", "value"), &SceneTree::set_group);
ClassDB::bind_method(D_METHOD("get_nodes_in_group", "group"), &SceneTree::_get_nodes_in_group);
+ ClassDB::bind_method(D_METHOD("get_first_node_in_group", "group"), &SceneTree::get_first_node_in_group);
ClassDB::bind_method(D_METHOD("set_current_scene", "child_node"), &SceneTree::set_current_scene);
ClassDB::bind_method(D_METHOD("get_current_scene"), &SceneTree::get_current_scene);
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index f39780831f..c2280c747b 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -302,6 +302,7 @@ public:
void queue_delete(Object *p_object);
void get_nodes_in_group(const StringName &p_group, List<Node *> *p_list);
+ Node *get_first_node_in_group(const StringName &p_group);
bool has_group(const StringName &p_identifier) const;
//void change_scene(const String& p_path);