summaryrefslogtreecommitdiff
path: root/scene/main
diff options
context:
space:
mode:
Diffstat (limited to 'scene/main')
-rw-r--r--scene/main/canvas_item.cpp35
-rw-r--r--scene/main/canvas_item.h4
-rw-r--r--scene/main/canvas_layer.cpp2
-rw-r--r--scene/main/node.cpp41
-rw-r--r--scene/main/node.h4
-rw-r--r--scene/main/viewport.cpp14
-rw-r--r--scene/main/viewport.h2
-rw-r--r--scene/main/window.cpp2
8 files changed, 68 insertions, 36 deletions
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp
index 9ad711c596..26b67b763c 100644
--- a/scene/main/canvas_item.cpp
+++ b/scene/main/canvas_item.cpp
@@ -56,19 +56,21 @@ Transform2D CanvasItem::_edit_get_transform() const {
#endif
bool CanvasItem::is_visible_in_tree() const {
- return visible && visible_in_tree;
+ return visible && parent_visible_in_tree;
}
-void CanvasItem::_propagate_visibility_changed(bool p_visible, bool p_was_visible) {
- if (p_visible && first_draw) { //avoid propagating it twice
+void CanvasItem::_propagate_visibility_changed(bool p_visible, bool p_is_source) {
+ if (p_visible && first_draw) { // Avoid propagating it twice.
first_draw = false;
}
- visible_in_tree = p_visible;
+ if (!p_is_source) {
+ parent_visible_in_tree = p_visible;
+ }
notification(NOTIFICATION_VISIBILITY_CHANGED);
if (visible && p_visible) {
update();
- } else if (!p_visible && (visible || p_was_visible)) {
+ } else if (!p_visible && (visible || p_is_source)) {
emit_signal(SceneStringNames::get_singleton()->hidden);
}
_block();
@@ -76,8 +78,12 @@ void CanvasItem::_propagate_visibility_changed(bool p_visible, bool p_was_visibl
for (int i = 0; i < get_child_count(); i++) {
CanvasItem *c = Object::cast_to<CanvasItem>(get_child(i));
- if (c && c->visible) { //should the top_levels stop propagation? i think so but..
- c->_propagate_visibility_changed(p_visible);
+ if (c) { // Should the top_levels stop propagation? I think so, but...
+ if (c->visible) {
+ c->_propagate_visibility_changed(p_visible);
+ } else {
+ c->parent_visible_in_tree = p_visible;
+ }
}
}
@@ -92,11 +98,12 @@ void CanvasItem::set_visible(bool p_visible) {
visible = p_visible;
RenderingServer::get_singleton()->canvas_item_set_visible(canvas_item, p_visible);
- if (!is_inside_tree()) {
+ if (!parent_visible_in_tree) {
+ notification(NOTIFICATION_VISIBILITY_CHANGED);
return;
}
- _propagate_visibility_changed(p_visible, !p_visible);
+ _propagate_visibility_changed(p_visible, true);
}
void CanvasItem::show() {
@@ -264,13 +271,13 @@ void CanvasItem::_notification(int p_what) {
CanvasItem *ci = Object::cast_to<CanvasItem>(parent);
if (ci) {
- visible_in_tree = ci->is_visible_in_tree();
+ parent_visible_in_tree = ci->is_visible_in_tree();
C = ci->children_items.push_back(this);
} else {
CanvasLayer *cl = Object::cast_to<CanvasLayer>(parent);
if (cl) {
- visible_in_tree = cl->is_visible();
+ parent_visible_in_tree = cl->is_visible();
} else {
// Look for a window.
Viewport *viewport = nullptr;
@@ -288,9 +295,9 @@ void CanvasItem::_notification(int p_what) {
window = Object::cast_to<Window>(viewport);
if (window) {
window->connect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed));
- visible_in_tree = window->is_visible();
+ parent_visible_in_tree = window->is_visible();
} else {
- visible_in_tree = true;
+ parent_visible_in_tree = true;
}
}
}
@@ -333,7 +340,7 @@ void CanvasItem::_notification(int p_what) {
window->disconnect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed));
}
global_invalid = true;
- visible_in_tree = false;
+ parent_visible_in_tree = false;
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h
index 2a9e7bac3d..c0558b6be2 100644
--- a/scene/main/canvas_item.h
+++ b/scene/main/canvas_item.h
@@ -85,7 +85,7 @@ private:
Window *window = nullptr;
bool first_draw = false;
bool visible = true;
- bool visible_in_tree = false;
+ bool parent_visible_in_tree = false;
bool clip_children = false;
bool pending_update = false;
bool top_level = false;
@@ -108,7 +108,7 @@ private:
void _top_level_raise_self();
- void _propagate_visibility_changed(bool p_visible, bool p_was_visible = false);
+ void _propagate_visibility_changed(bool p_visible, bool p_is_source = false);
void _update_callback();
diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp
index 6c627857fa..be24620904 100644
--- a/scene/main/canvas_layer.cpp
+++ b/scene/main/canvas_layer.cpp
@@ -61,7 +61,7 @@ void CanvasLayer::set_visible(bool p_visible) {
if (c->is_visible()) {
c->_propagate_visibility_changed(p_visible);
} else {
- c->notification(CanvasItem::NOTIFICATION_VISIBILITY_CHANGED);
+ c->parent_visible_in_tree = p_visible;
}
}
}
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 42a2e41a08..211667ce38 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -1344,27 +1344,45 @@ bool Node::has_node(const NodePath &p_path) const {
return get_node_or_null(p_path) != nullptr;
}
-Node *Node::find_node(const String &p_mask, bool p_recursive, bool p_owned) const {
+TypedArray<Node> Node::find_nodes(const String &p_mask, const String &p_type, bool p_recursive, bool p_owned) const {
+ TypedArray<Node> ret;
+ ERR_FAIL_COND_V(p_mask.is_empty() && p_type.is_empty(), ret);
+
Node *const *cptr = data.children.ptr();
int ccount = data.children.size();
for (int i = 0; i < ccount; i++) {
if (p_owned && !cptr[i]->data.owner) {
continue;
}
- if (cptr[i]->data.name.operator String().match(p_mask)) {
- return cptr[i];
+
+ if (!p_mask.is_empty()) {
+ if (!cptr[i]->data.name.operator String().match(p_mask)) {
+ continue;
+ } else if (p_type.is_empty()) {
+ ret.append(cptr[i]);
+ }
}
- if (!p_recursive) {
- continue;
+ if (cptr[i]->is_class(p_type)) {
+ ret.append(cptr[i]);
+ } else if (cptr[i]->get_script_instance()) {
+ Ref<Script> script = cptr[i]->get_script_instance()->get_script();
+ while (script.is_valid()) {
+ if ((ScriptServer::is_global_class(p_type) && ScriptServer::get_global_class_path(p_type) == script->get_path()) || p_type == script->get_path()) {
+ ret.append(cptr[i]);
+ break;
+ }
+
+ script = script->get_base_script();
+ }
}
- Node *ret = cptr[i]->find_node(p_mask, true, p_owned);
- if (ret) {
- return ret;
+ if (p_recursive) {
+ ret.append_array(cptr[i]->find_nodes(p_mask, p_type, true, p_owned));
}
}
- return nullptr;
+
+ return ret;
}
Node *Node::get_parent() const {
@@ -2706,7 +2724,7 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_node", "path"), &Node::get_node);
ClassDB::bind_method(D_METHOD("get_node_or_null", "path"), &Node::get_node_or_null);
ClassDB::bind_method(D_METHOD("get_parent"), &Node::get_parent);
- ClassDB::bind_method(D_METHOD("find_node", "mask", "recursive", "owned"), &Node::find_node, DEFVAL(true), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("find_nodes", "mask", "type", "recursive", "owned"), &Node::find_nodes, DEFVAL(""), DEFVAL(true), DEFVAL(true));
ClassDB::bind_method(D_METHOD("find_parent", "mask"), &Node::find_parent);
ClassDB::bind_method(D_METHOD("has_node_and_resource", "path"), &Node::has_node_and_resource);
ClassDB::bind_method(D_METHOD("get_node_and_resource", "path"), &Node::_get_node_and_resource);
@@ -2845,6 +2863,9 @@ void Node::_bind_methods() {
BIND_CONSTANT(NOTIFICATION_WM_CLOSE_REQUEST);
BIND_CONSTANT(NOTIFICATION_WM_GO_BACK_REQUEST);
BIND_CONSTANT(NOTIFICATION_WM_SIZE_CHANGED);
+ BIND_CONSTANT(NOTIFICATION_WM_DPI_CHANGE);
+ BIND_CONSTANT(NOTIFICATION_VP_MOUSE_ENTER);
+ BIND_CONSTANT(NOTIFICATION_VP_MOUSE_EXIT);
BIND_CONSTANT(NOTIFICATION_OS_MEMORY_WARNING);
BIND_CONSTANT(NOTIFICATION_TRANSLATION_CHANGED);
BIND_CONSTANT(NOTIFICATION_WM_ABOUT);
diff --git a/scene/main/node.h b/scene/main/node.h
index f2dcdf4b43..8e49f871a7 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -268,6 +268,8 @@ public:
NOTIFICATION_WM_GO_BACK_REQUEST = 1007,
NOTIFICATION_WM_SIZE_CHANGED = 1008,
NOTIFICATION_WM_DPI_CHANGE = 1009,
+ NOTIFICATION_VP_MOUSE_ENTER = 1010,
+ NOTIFICATION_VP_MOUSE_EXIT = 1011,
NOTIFICATION_OS_MEMORY_WARNING = MainLoop::NOTIFICATION_OS_MEMORY_WARNING,
NOTIFICATION_TRANSLATION_CHANGED = MainLoop::NOTIFICATION_TRANSLATION_CHANGED,
@@ -299,7 +301,7 @@ public:
bool has_node(const NodePath &p_path) const;
Node *get_node(const NodePath &p_path) const;
Node *get_node_or_null(const NodePath &p_path) const;
- Node *find_node(const String &p_mask, bool p_recursive = true, bool p_owned = true) const;
+ TypedArray<Node> find_nodes(const String &p_mask, const String &p_type = "", bool p_recursive = true, bool p_owned = true) const;
bool has_node_and_resource(const NodePath &p_path) const;
Node *get_node_and_resource(const NodePath &p_path, RES &r_res, Vector<StringName> &r_leftover_subpath, bool p_last_is_property = true) const;
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 2831e76fba..ca817b17bc 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -496,17 +496,17 @@ void Viewport::_notification(int p_what) {
#endif // _3D_DISABLED
} break;
- case NOTIFICATION_WM_MOUSE_ENTER: {
- gui.mouse_in_window = true;
+ case NOTIFICATION_VP_MOUSE_ENTER: {
+ gui.mouse_in_viewport = true;
} break;
- case NOTIFICATION_WM_MOUSE_EXIT: {
- gui.mouse_in_window = false;
+ case NOTIFICATION_VP_MOUSE_EXIT: {
+ gui.mouse_in_viewport = false;
_drop_physics_mouseover();
_drop_mouse_over();
- // When the mouse exits the window, we want to end mouse_over, but
+ // When the mouse exits the viewport, we want to end mouse_over, but
// not mouse_focus, because, for example, we want to continue
- // dragging a scrollbar even if the mouse has left the window.
+ // dragging a scrollbar even if the mouse has left the viewport.
} break;
case NOTIFICATION_WM_WINDOW_FOCUS_OUT: {
@@ -1683,7 +1683,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Control *over = nullptr;
if (gui.mouse_focus) {
over = gui.mouse_focus;
- } else if (gui.mouse_in_window) {
+ } else if (gui.mouse_in_viewport) {
over = gui_find_control(mpos);
}
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 3a71745f44..93e42f1838 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -335,7 +335,7 @@ private:
// info used when this is a window
bool forced_mouse_focus = false; //used for menu buttons
- bool mouse_in_window = true;
+ bool mouse_in_viewport = true;
bool key_event_accepted = false;
Control *mouse_focus = nullptr;
Control *last_mouse_focus = nullptr;
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index e7a575f40a..0ce556d36c 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -340,9 +340,11 @@ void Window::_event_callback(DisplayServer::WindowEvent p_event) {
case DisplayServer::WINDOW_EVENT_MOUSE_ENTER: {
_propagate_window_notification(this, NOTIFICATION_WM_MOUSE_ENTER);
emit_signal(SNAME("mouse_entered"));
+ notification(NOTIFICATION_VP_MOUSE_ENTER);
DisplayServer::get_singleton()->cursor_set_shape(DisplayServer::CURSOR_ARROW); //restore cursor shape
} break;
case DisplayServer::WINDOW_EVENT_MOUSE_EXIT: {
+ notification(NOTIFICATION_VP_MOUSE_EXIT);
_propagate_window_notification(this, NOTIFICATION_WM_MOUSE_EXIT);
emit_signal(SNAME("mouse_exited"));
} break;