summaryrefslogtreecommitdiff
path: root/scene/main
diff options
context:
space:
mode:
Diffstat (limited to 'scene/main')
-rw-r--r--scene/main/canvas_item.cpp74
-rw-r--r--scene/main/canvas_item.h5
-rw-r--r--scene/main/canvas_layer.cpp33
-rw-r--r--scene/main/canvas_layer.h4
-rw-r--r--scene/main/node.cpp26
-rw-r--r--scene/main/node.h3
-rw-r--r--scene/main/scene_tree.cpp3
-rw-r--r--scene/main/scene_tree.h2
-rw-r--r--scene/main/viewport.cpp2
-rw-r--r--scene/main/window.cpp1
-rw-r--r--scene/main/window.h1
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 {