diff options
Diffstat (limited to 'scene/main')
-rw-r--r-- | scene/main/canvas_item.cpp | 35 | ||||
-rw-r--r-- | scene/main/canvas_item.h | 4 | ||||
-rw-r--r-- | scene/main/canvas_layer.cpp | 2 | ||||
-rw-r--r-- | scene/main/node.cpp | 41 | ||||
-rw-r--r-- | scene/main/node.h | 4 | ||||
-rw-r--r-- | scene/main/viewport.cpp | 14 | ||||
-rw-r--r-- | scene/main/viewport.h | 2 | ||||
-rw-r--r-- | scene/main/window.cpp | 2 |
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; |