diff options
Diffstat (limited to 'scene/main')
| -rw-r--r-- | scene/main/canvas_item.cpp | 74 | ||||
| -rw-r--r-- | scene/main/canvas_item.h | 5 | ||||
| -rw-r--r-- | scene/main/canvas_layer.cpp | 33 | ||||
| -rw-r--r-- | scene/main/canvas_layer.h | 4 | ||||
| -rw-r--r-- | scene/main/node.cpp | 26 | ||||
| -rw-r--r-- | scene/main/node.h | 3 | ||||
| -rw-r--r-- | scene/main/scene_tree.cpp | 3 | ||||
| -rw-r--r-- | scene/main/scene_tree.h | 2 | ||||
| -rw-r--r-- | scene/main/viewport.cpp | 2 | ||||
| -rw-r--r-- | scene/main/window.cpp | 1 | ||||
| -rw-r--r-- | scene/main/window.h | 1 |
11 files changed, 100 insertions, 54 deletions
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index a0916c6291..b794bbbc57 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -56,34 +56,19 @@ Transform2D CanvasItem::_edit_get_transform() const { #endif bool CanvasItem::is_visible_in_tree() const { - if (!is_inside_tree()) { - return false; - } - - const CanvasItem *p = this; - - while (p) { - if (!p->visible) { - return false; - } - if (p->window && !p->window->is_visible()) { - return false; - } - p = p->get_parent_item(); - } - - return true; + return visible && visible_in_tree; } -void CanvasItem::_propagate_visibility_changed(bool p_visible) { +void CanvasItem::_propagate_visibility_changed(bool p_visible, bool p_was_visible) { if (p_visible && first_draw) { //avoid propagating it twice first_draw = false; } + visible_in_tree = p_visible; notification(NOTIFICATION_VISIBILITY_CHANGED); - if (p_visible) { - update(); //todo optimize - } else { + if (visible && p_visible) { + update(); + } else if (!p_visible && (visible || p_was_visible)) { emit_signal(SceneStringNames::get_singleton()->hidden); } _block(); @@ -111,7 +96,7 @@ void CanvasItem::set_visible(bool p_visible) { return; } - _propagate_visibility_changed(p_visible); + _propagate_visibility_changed(p_visible, !p_visible); } void CanvasItem::show() { @@ -139,7 +124,7 @@ void CanvasItem::_update_callback() { RenderingServer::get_singleton()->canvas_item_clear(get_canvas_item()); //todo updating = true - only allow drawing here - if (is_visible_in_tree()) { //todo optimize this!! + if (is_visible_in_tree()) { if (first_draw) { notification(NOTIFICATION_VISIBILITY_CHANGED); first_draw = false; @@ -273,32 +258,44 @@ void CanvasItem::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { ERR_FAIL_COND(!is_inside_tree()); first_draw = true; + Node *parent = get_parent(); if (parent) { CanvasItem *ci = Object::cast_to<CanvasItem>(parent); + if (ci) { + visible_in_tree = ci->is_visible_in_tree(); C = ci->children_items.push_back(this); - } - if (!ci) { - //look for a window - Viewport *viewport = nullptr; - - while (parent) { - viewport = Object::cast_to<Viewport>(parent); - if (viewport) { - break; + } else { + CanvasLayer *cl = Object::cast_to<CanvasLayer>(parent); + + if (cl) { + visible_in_tree = cl->is_visible(); + } else { + // Look for a window. + Viewport *viewport = nullptr; + + while (parent) { + viewport = Object::cast_to<Viewport>(parent); + if (viewport) { + break; + } + parent = parent->get_parent(); } - parent = parent->get_parent(); - } - ERR_FAIL_COND(!viewport); + ERR_FAIL_COND(!viewport); - window = Object::cast_to<Window>(viewport); - if (window) { - window->connect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed)); + 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(); + } else { + visible_in_tree = true; + } } } } + _enter_canvas(); _update_texture_filter_changed(false); @@ -335,6 +332,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; } break; case NOTIFICATION_DRAW: case NOTIFICATION_TRANSFORM_CHANGED: { diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h index 3d49d89746..a368a10ad0 100644 --- a/scene/main/canvas_item.h +++ b/scene/main/canvas_item.h @@ -46,6 +46,8 @@ class World2D; class CanvasItem : public Node { GDCLASS(CanvasItem, Node); + friend class CanvasLayer; + public: enum TextureFilter { TEXTURE_FILTER_PARENT_NODE, @@ -85,6 +87,7 @@ private: Window *window = nullptr; bool first_draw = false; bool visible = true; + bool visible_in_tree = false; bool clip_children = false; bool pending_update = false; bool top_level = false; @@ -107,7 +110,7 @@ private: void _top_level_raise_self(); - void _propagate_visibility_changed(bool p_visible); + void _propagate_visibility_changed(bool p_visible, bool p_was_visible = false); void _update_callback(); diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp index 282ab6b497..3f3e72357b 100644 --- a/scene/main/canvas_layer.cpp +++ b/scene/main/canvas_layer.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "canvas_layer.h" +#include "canvas_item.h" #include "viewport.h" void CanvasLayer::set_layer(int p_xform) { @@ -42,6 +43,32 @@ int CanvasLayer::get_layer() const { return layer; } +void CanvasLayer::set_visible(bool p_visible) { + if (p_visible == visible) { + return; + } + + visible = p_visible; + emit_signal(SNAME("visibility_changed")); + + for (int i = 0; i < get_child_count(); i++) { + CanvasItem *c = Object::cast_to<CanvasItem>(get_child(i)); + if (c) { + RenderingServer::get_singleton()->canvas_item_set_visible(c->get_canvas_item(), p_visible && c->is_visible()); + + if (c->is_visible()) { + c->_propagate_visibility_changed(p_visible); + } else { + c->notification(CanvasItem::NOTIFICATION_VISIBILITY_CHANGED); + } + } + } +} + +bool CanvasLayer::is_visible() const { + return visible; +} + void CanvasLayer::set_transform(const Transform2D &p_xform) { transform = p_xform; locrotscale_dirty = true; @@ -264,6 +291,9 @@ void CanvasLayer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_layer", "layer"), &CanvasLayer::set_layer); ClassDB::bind_method(D_METHOD("get_layer"), &CanvasLayer::get_layer); + ClassDB::bind_method(D_METHOD("set_visible", "visible"), &CanvasLayer::set_visible); + ClassDB::bind_method(D_METHOD("is_visible"), &CanvasLayer::is_visible); + ClassDB::bind_method(D_METHOD("set_transform", "transform"), &CanvasLayer::set_transform); ClassDB::bind_method(D_METHOD("get_transform"), &CanvasLayer::get_transform); @@ -289,6 +319,7 @@ void CanvasLayer::_bind_methods() { ADD_GROUP("Layer", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "layer", PROPERTY_HINT_RANGE, "-128,128,1"), "set_layer", "get_layer"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible"); ADD_GROUP("Transform", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation", PROPERTY_HINT_RANGE, "-1080,1080,0.1,or_lesser,or_greater,radians"), "set_rotation", "get_rotation"); @@ -299,6 +330,8 @@ void CanvasLayer::_bind_methods() { ADD_GROUP("Follow Viewport", "follow_viewport"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "follow_viewport_enable"), "set_follow_viewport", "is_following_viewport"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "follow_viewport_scale", PROPERTY_HINT_RANGE, "0.001,1000,0.001,or_greater,or_lesser"), "set_follow_viewport_scale", "get_follow_viewport_scale"); + + ADD_SIGNAL(MethodInfo("visibility_changed")); } CanvasLayer::CanvasLayer() { diff --git a/scene/main/canvas_layer.h b/scene/main/canvas_layer.h index 93a0152787..b7bd793440 100644 --- a/scene/main/canvas_layer.h +++ b/scene/main/canvas_layer.h @@ -52,6 +52,7 @@ class CanvasLayer : public Node { Viewport *vp = nullptr; int sort_index = 0; + bool visible = true; bool follow_viewport = false; float follow_viewport_scale = 1.0; @@ -69,6 +70,9 @@ public: void set_layer(int p_xform); int get_layer() const; + void set_visible(bool p_visible); + bool is_visible() const; + void set_transform(const Transform2D &p_xform); Transform2D get_transform() const; diff --git a/scene/main/node.cpp b/scene/main/node.cpp index a2415442f8..6b9d8ab211 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -32,6 +32,7 @@ #include "core/core_string_names.h" #include "core/io/resource_loader.h" +#include "core/multiplayer/multiplayer_api.h" #include "core/object/message_queue.h" #include "core/string/print_string.h" #include "instance_placeholder.h" @@ -110,9 +111,6 @@ void Node::_notification(int p_notification) { memdelete(data.path_cache); data.path_cache = nullptr; } - if (data.scene_file_path.length()) { - get_multiplayer()->scene_enter_exit_notify(data.scene_file_path, this, false); - } } break; case NOTIFICATION_PATH_RENAMED: { if (data.path_cache) { @@ -141,12 +139,6 @@ void Node::_notification(int p_notification) { } GDVIRTUAL_CALL(_ready); - - if (data.scene_file_path.length()) { - ERR_FAIL_COND(!is_inside_tree()); - get_multiplayer()->scene_enter_exit_notify(data.scene_file_path, this, true); - } - } break; case NOTIFICATION_POSTINITIALIZE: { data.in_constructor = false; @@ -211,6 +203,12 @@ void Node::_propagate_enter_tree() { data.tree->node_added(this); + if (data.parent) { + Variant c = this; + const Variant *cptr = &c; + data.parent->emit_signal(SNAME("child_entered_tree"), &cptr, 1); + } + data.blocked++; //block while adding children @@ -281,6 +279,12 @@ void Node::_propagate_exit_tree() { data.tree->node_removed(this); } + if (data.parent) { + Variant c = this; + const Variant *cptr = &c; + data.parent->emit_signal(SNAME("child_exited_tree"), &cptr, 1); + } + // exit groups for (KeyValue<StringName, GroupData> &E : data.grouped) { @@ -1049,7 +1053,7 @@ void Node::_generate_serial_child_name(const Node *p_child, StringName &name) co String nums; for (int i = name_string.length() - 1; i >= 0; i--) { char32_t n = name_string[i]; - if (n >= '0' && n <= '9') { + if (is_digit(n)) { nums = String::chr(name_string[i]) + nums; } else { break; @@ -2865,6 +2869,8 @@ void Node::_bind_methods() { ADD_SIGNAL(MethodInfo("tree_entered")); ADD_SIGNAL(MethodInfo("tree_exiting")); ADD_SIGNAL(MethodInfo("tree_exited")); + ADD_SIGNAL(MethodInfo("child_entered_tree", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT, "Node"))); + ADD_SIGNAL(MethodInfo("child_exited_tree", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT, "Node"))); ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_name", "get_name"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "scene_file_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_scene_file_path", "get_scene_file_path"); diff --git a/scene/main/node.h b/scene/main/node.h index a1fc672a15..0ac10f4381 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -212,7 +212,6 @@ protected: static String _get_name_num_separator(); friend class SceneState; - friend class MultiplayerReplicator; void _add_child_nocheck(Node *p_child, const StringName &p_name); void _set_owner_nocheck(Node *p_owner); @@ -467,7 +466,7 @@ public: bool is_displayed_folded() const; /* NETWORK */ - void set_multiplayer_authority(int p_peer_id, bool p_recursive = true); + virtual void set_multiplayer_authority(int p_peer_id, bool p_recursive = true); int get_multiplayer_authority() const; bool is_multiplayer_authority() const; diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 45f04b28b9..69d781cbfc 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -36,6 +36,7 @@ #include "core/io/dir_access.h" #include "core/io/marshalls.h" #include "core/io/resource_loader.h" +#include "core/multiplayer/multiplayer_api.h" #include "core/object/message_queue.h" #include "core/os/keyboard.h" #include "core/os/os.h" @@ -1164,7 +1165,7 @@ void SceneTree::set_multiplayer(Ref<MultiplayerAPI> p_multiplayer) { ERR_FAIL_COND(!p_multiplayer.is_valid()); multiplayer = p_multiplayer; - multiplayer->set_root_node(root); + multiplayer->set_root_path("/" + root->get_name()); } void SceneTree::_bind_methods() { diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index 1dff1dab4f..a5cd52b4ca 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -31,7 +31,6 @@ #ifndef SCENE_TREE_H #define SCENE_TREE_H -#include "core/multiplayer/multiplayer_api.h" #include "core/os/main_loop.h" #include "core/os/thread_safe.h" #include "core/templates/self_list.h" @@ -46,6 +45,7 @@ class Node; class Window; class Material; class Mesh; +class MultiplayerAPI; class SceneDebugger; class Tween; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 09880ad6cf..522997cdf5 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1231,7 +1231,7 @@ void Viewport::_gui_show_tooltip() { base_tooltip->set_anchors_and_offsets_preset(Control::PRESET_WIDE); - panel->set_transient(false); + panel->set_transient(true); panel->set_flag(Window::FLAG_NO_FOCUS, true); panel->set_wrap_controls(true); panel->add_child(base_tooltip); diff --git a/scene/main/window.cpp b/scene/main/window.cpp index fbc0bc5301..f2ebe50fa3 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -1614,6 +1614,7 @@ void Window::_bind_methods() { BIND_ENUM_CONSTANT(MODE_MINIMIZED); BIND_ENUM_CONSTANT(MODE_MAXIMIZED); BIND_ENUM_CONSTANT(MODE_FULLSCREEN); + BIND_ENUM_CONSTANT(MODE_EXCLUSIVE_FULLSCREEN); BIND_ENUM_CONSTANT(FLAG_RESIZE_DISABLED); BIND_ENUM_CONSTANT(FLAG_BORDERLESS); diff --git a/scene/main/window.h b/scene/main/window.h index 2dd1dd6601..f37689f905 100644 --- a/scene/main/window.h +++ b/scene/main/window.h @@ -46,6 +46,7 @@ public: MODE_MINIMIZED = DisplayServer::WINDOW_MODE_MINIMIZED, MODE_MAXIMIZED = DisplayServer::WINDOW_MODE_MAXIMIZED, MODE_FULLSCREEN = DisplayServer::WINDOW_MODE_FULLSCREEN, + MODE_EXCLUSIVE_FULLSCREEN = DisplayServer::WINDOW_MODE_EXCLUSIVE_FULLSCREEN, }; enum Flags { |