summaryrefslogtreecommitdiff
path: root/scene/main
diff options
context:
space:
mode:
Diffstat (limited to 'scene/main')
-rw-r--r--scene/main/canvas_item.cpp4
-rw-r--r--scene/main/canvas_item.h4
-rw-r--r--scene/main/http_request.cpp10
-rw-r--r--scene/main/node.cpp162
-rw-r--r--scene/main/node.h20
-rw-r--r--scene/main/resource_preloader.cpp8
-rw-r--r--scene/main/scene_tree.cpp22
-rw-r--r--scene/main/scene_tree.h2
-rw-r--r--scene/main/timer.cpp11
-rw-r--r--scene/main/timer.h2
-rw-r--r--scene/main/viewport.cpp431
-rw-r--r--scene/main/viewport.h54
-rw-r--r--scene/main/window.cpp18
-rw-r--r--scene/main/window.h4
14 files changed, 384 insertions, 368 deletions
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp
index 64b169b1fb..916833c9a7 100644
--- a/scene/main/canvas_item.cpp
+++ b/scene/main/canvas_item.cpp
@@ -647,13 +647,13 @@ void CanvasItem::draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Tex
RenderingServer::get_singleton()->canvas_item_add_multimesh(canvas_item, p_multimesh->get_rid(), texture_rid);
}
-void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align, real_t p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint8_t p_flags) const {
+void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align, real_t p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND(p_font.is_null());
p_font->draw_string(canvas_item, p_pos, p_text, p_align, p_width, p_size, p_modulate, p_outline_size, p_outline_modulate, p_flags);
}
-void CanvasItem::draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align, real_t p_width, int p_max_lines, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint8_t p_flags) const {
+void CanvasItem::draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align, real_t p_width, int p_max_lines, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND(p_font.is_null());
p_font->draw_multiline_string(canvas_item, p_pos, p_text, p_align, p_width, p_max_lines, p_size, p_modulate, p_outline_size, p_outline_modulate, p_flags);
diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h
index 01ed47d4dc..ba9f47119d 100644
--- a/scene/main/canvas_item.h
+++ b/scene/main/canvas_item.h
@@ -235,8 +235,8 @@ public:
void draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture2D> &p_texture, const Transform2D &p_transform = Transform2D(), const Color &p_modulate = Color(1, 1, 1));
void draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture2D> &p_texture);
- void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_size = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint8_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
- void draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_max_lines = -1, int p_size = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint8_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
+ void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_size = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
+ void draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_max_lines = -1, int p_size = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
real_t draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next = "", int p_size = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0)) const;
void draw_set_transform(const Point2 &p_offset, real_t p_rot = 0.0, const Size2 &p_scale = Size2(1.0, 1.0));
diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp
index f24d880045..a4fcc04e20 100644
--- a/scene/main/http_request.cpp
+++ b/scene/main/http_request.cpp
@@ -104,9 +104,11 @@ Error HTTPRequest::request(const String &p_url, const Vector<String> &p_custom_h
CharString charstr = p_request_data.utf8();
size_t len = charstr.length();
- raw_data.resize(len);
- uint8_t *w = raw_data.ptrw();
- memcpy(w, charstr.ptr(), len);
+ if (len > 0) {
+ raw_data.resize(len);
+ uint8_t *w = raw_data.ptrw();
+ memcpy(w, charstr.ptr(), len);
+ }
return request_raw(p_url, p_custom_headers, p_ssl_validate_domain, p_method, raw_data);
}
@@ -597,7 +599,7 @@ void HTTPRequest::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_timeout", "timeout"), &HTTPRequest::set_timeout);
ClassDB::bind_method(D_METHOD("get_timeout"), &HTTPRequest::get_timeout);
- ClassDB::bind_method(D_METHOD("set_download_chunk_size"), &HTTPRequest::set_download_chunk_size);
+ ClassDB::bind_method(D_METHOD("set_download_chunk_size", "chunk_size"), &HTTPRequest::set_download_chunk_size);
ClassDB::bind_method(D_METHOD("get_download_chunk_size"), &HTTPRequest::get_download_chunk_size);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "download_file", PROPERTY_HINT_FILE), "set_download_file", "get_download_file");
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index f2a2648140..189aebb47d 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -41,10 +41,6 @@
#include "scene/scene_string_names.h"
#include "viewport.h"
-#ifdef TOOLS_ENABLED
-#include "editor/editor_settings.h"
-#endif
-
#include <stdint.h>
VARIANT_ENUM_CAST(Node::ProcessMode);
@@ -70,7 +66,9 @@ void Node::_notification(int p_notification) {
if (data.parent) {
data.process_owner = data.parent->data.process_owner;
} else {
- data.process_owner = nullptr;
+ ERR_PRINT("The root node can't be set to Inherit process mode, reverting to Pausable instead.");
+ data.process_mode = PROCESS_MODE_PAUSABLE;
+ data.process_owner = this;
}
} else {
data.process_owner = this;
@@ -112,8 +110,8 @@ void Node::_notification(int p_notification) {
memdelete(data.path_cache);
data.path_cache = nullptr;
}
- if (data.filename.length()) {
- get_multiplayer()->scene_enter_exit_notify(data.filename, this, false);
+ if (data.scene_file_path.length()) {
+ get_multiplayer()->scene_enter_exit_notify(data.scene_file_path, this, false);
}
} break;
case NOTIFICATION_PATH_CHANGED: {
@@ -123,31 +121,30 @@ void Node::_notification(int p_notification) {
}
} break;
case NOTIFICATION_READY: {
- if (get_script_instance()) {
- if (GDVIRTUAL_IS_OVERRIDDEN(_input)) {
- set_process_input(true);
- }
-
- if (GDVIRTUAL_IS_OVERRIDDEN(_unhandled_input)) {
- set_process_unhandled_input(true);
- }
+ if (GDVIRTUAL_IS_OVERRIDDEN(_input)) {
+ set_process_input(true);
+ }
- if (GDVIRTUAL_IS_OVERRIDDEN(_unhandled_key_input)) {
- set_process_unhandled_key_input(true);
- }
+ if (GDVIRTUAL_IS_OVERRIDDEN(_unhandled_input)) {
+ set_process_unhandled_input(true);
+ }
- if (GDVIRTUAL_IS_OVERRIDDEN(_process)) {
- set_process(true);
- }
- if (GDVIRTUAL_IS_OVERRIDDEN(_physics_process)) {
- set_physics_process(true);
- }
+ if (GDVIRTUAL_IS_OVERRIDDEN(_unhandled_key_input)) {
+ set_process_unhandled_key_input(true);
+ }
- GDVIRTUAL_CALL(_ready);
+ if (GDVIRTUAL_IS_OVERRIDDEN(_process)) {
+ set_process(true);
+ }
+ if (GDVIRTUAL_IS_OVERRIDDEN(_physics_process)) {
+ set_physics_process(true);
}
- if (data.filename.length()) {
+
+ GDVIRTUAL_CALL(_ready);
+
+ if (data.scene_file_path.length()) {
ERR_FAIL_COND(!is_inside_tree());
- get_multiplayer()->scene_enter_exit_notify(data.filename, this, true);
+ get_multiplayer()->scene_enter_exit_notify(data.scene_file_path, this, true);
}
} break;
@@ -210,8 +207,8 @@ void Node::_propagate_enter_tree() {
data.inside_tree = true;
- for (Map<StringName, GroupData>::Element *E = data.grouped.front(); E; E = E->next()) {
- E->get().group = data.tree->add_to_group(E->key(), this);
+ for (KeyValue<StringName, GroupData> &E : data.grouped) {
+ E.value.group = data.tree->add_to_group(E.key, this);
}
notification(NOTIFICATION_ENTER_TREE);
@@ -234,7 +231,7 @@ void Node::_propagate_enter_tree() {
data.blocked--;
#ifdef DEBUG_ENABLED
- SceneDebugger::add_to_cache(data.filename, this);
+ SceneDebugger::add_to_cache(data.scene_file_path, this);
#endif
// enter groups
}
@@ -252,7 +249,7 @@ void Node::_propagate_exit_tree() {
//block while removing children
#ifdef DEBUG_ENABLED
- SceneDebugger::remove_from_cache(data.filename, this);
+ SceneDebugger::remove_from_cache(data.scene_file_path, this);
#endif
data.blocked++;
@@ -273,9 +270,9 @@ void Node::_propagate_exit_tree() {
// exit groups
- for (Map<StringName, GroupData>::Element *E = data.grouped.front(); E; E = E->next()) {
- data.tree->remove_from_group(E->key(), this);
- E->get().group = nullptr;
+ for (KeyValue<StringName, GroupData> &E : data.grouped) {
+ data.tree->remove_from_group(E.key, this);
+ E.value.group = nullptr;
}
data.viewport = nullptr;
@@ -352,9 +349,9 @@ void Node::_move_child(Node *p_child, int p_pos, bool p_ignore_end) {
for (int i = motion_from; i <= motion_to; i++) {
data.children[i]->notification(NOTIFICATION_MOVED_IN_PARENT);
}
- for (const Map<StringName, GroupData>::Element *E = p_child->data.grouped.front(); E; E = E->next()) {
- if (E->get().group) {
- E->get().group->changed = true;
+ for (const KeyValue<StringName, GroupData> &E : p_child->data.grouped) {
+ if (E.value.group) {
+ E.value.group->changed = true;
}
}
@@ -437,18 +434,18 @@ void Node::set_process_mode(ProcessMode p_mode) {
bool prev_can_process = can_process();
bool prev_enabled = _is_enabled();
- data.process_mode = p_mode;
-
- if (data.process_mode == PROCESS_MODE_INHERIT) {
+ if (p_mode == PROCESS_MODE_INHERIT) {
if (data.parent) {
- data.process_owner = data.parent->data.owner;
+ data.process_owner = data.parent->data.process_owner;
} else {
- data.process_owner = nullptr;
+ ERR_FAIL_MSG("The root node can't be set to Inherit process mode.");
}
} else {
data.process_owner = this;
}
+ data.process_mode = p_mode;
+
bool next_can_process = can_process();
bool next_enabled = _is_enabled();
@@ -517,44 +514,46 @@ void Node::_propagate_process_owner(Node *p_owner, int p_pause_notification, int
}
}
-void Node::set_network_authority(int p_peer_id, bool p_recursive) {
- data.network_authority = p_peer_id;
+void Node::set_multiplayer_authority(int p_peer_id, bool p_recursive) {
+ data.multiplayer_authority = p_peer_id;
if (p_recursive) {
for (int i = 0; i < data.children.size(); i++) {
- data.children[i]->set_network_authority(p_peer_id, true);
+ data.children[i]->set_multiplayer_authority(p_peer_id, true);
}
}
}
-int Node::get_network_authority() const {
- return data.network_authority;
+int Node::get_multiplayer_authority() const {
+ return data.multiplayer_authority;
}
-bool Node::is_network_authority() const {
+bool Node::is_multiplayer_authority() const {
ERR_FAIL_COND_V(!is_inside_tree(), false);
- return get_multiplayer()->get_network_unique_id() == data.network_authority;
+ return get_multiplayer()->get_unique_id() == data.multiplayer_authority;
}
/***** RPC CONFIG ********/
-uint16_t Node::rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_rpc_mode, MultiplayerPeer::TransferMode p_transfer_mode, int p_channel) {
+uint16_t Node::rpc_config(const StringName &p_method, Multiplayer::RPCMode p_rpc_mode, bool p_call_local, Multiplayer::TransferMode p_transfer_mode, int p_channel) {
for (int i = 0; i < data.rpc_methods.size(); i++) {
if (data.rpc_methods[i].name == p_method) {
- MultiplayerAPI::RPCConfig &nd = data.rpc_methods.write[i];
+ Multiplayer::RPCConfig &nd = data.rpc_methods.write[i];
nd.rpc_mode = p_rpc_mode;
nd.transfer_mode = p_transfer_mode;
+ nd.call_local = p_call_local;
nd.channel = p_channel;
return i | (1 << 15);
}
}
// New method
- MultiplayerAPI::RPCConfig nd;
+ Multiplayer::RPCConfig nd;
nd.name = p_method;
nd.rpc_mode = p_rpc_mode;
nd.transfer_mode = p_transfer_mode;
nd.channel = p_channel;
+ nd.call_local = p_call_local;
data.rpc_methods.push_back(nd);
return ((uint16_t)data.rpc_methods.size() - 1) | (1 << 15);
}
@@ -643,7 +642,7 @@ Variant Node::_rpc_id_bind(const Variant **p_args, int p_argcount, Callable::Cal
void Node::rpcp(int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) {
ERR_FAIL_COND(!is_inside_tree());
- get_multiplayer()->rpcp(this, p_peer_id, true, p_method, p_arg, p_argcount);
+ get_multiplayer()->rpcp(this, p_peer_id, p_method, p_arg, p_argcount);
}
Ref<MultiplayerAPI> Node::get_multiplayer() const {
@@ -664,7 +663,7 @@ void Node::set_custom_multiplayer(Ref<MultiplayerAPI> p_multiplayer) {
multiplayer = p_multiplayer;
}
-Vector<MultiplayerAPI::RPCConfig> Node::get_node_rpc_methods() const {
+Vector<Multiplayer::RPCConfig> Node::get_node_rpc_methods() const {
return data.rpc_methods;
}
@@ -703,6 +702,9 @@ bool Node::_can_process(bool p_paused) const {
process_mode = data.process_mode;
}
+ // The owner can't be set to inherit, must be a bug.
+ ERR_FAIL_COND_V(process_mode == PROCESS_MODE_INHERIT, false);
+
if (process_mode == PROCESS_MODE_DISABLED) {
return false;
} else if (process_mode == PROCESS_MODE_ALWAYS) {
@@ -1674,10 +1676,10 @@ Array Node::_get_groups() const {
}
void Node::get_groups(List<GroupInfo> *p_groups) const {
- for (const Map<StringName, GroupData>::Element *E = data.grouped.front(); E; E = E->next()) {
+ for (const KeyValue<StringName, GroupData> &E : data.grouped) {
GroupInfo gi;
- gi.name = E->key();
- gi.persistent = E->get().persistent;
+ gi.name = E.key;
+ gi.persistent = E.value.persistent;
p_groups->push_back(gi);
}
}
@@ -1685,8 +1687,8 @@ void Node::get_groups(List<GroupInfo> *p_groups) const {
int Node::get_persistent_group_count() const {
int count = 0;
- for (const Map<StringName, GroupData>::Element *E = data.grouped.front(); E; E = E->next()) {
- if (E->get().persistent) {
+ for (const KeyValue<StringName, GroupData> &E : data.grouped) {
+ if (E.value.persistent) {
count += 1;
}
}
@@ -1842,12 +1844,12 @@ void Node::remove_and_skip() {
data.parent->remove_child(this);
}
-void Node::set_filename(const String &p_filename) {
- data.filename = p_filename;
+void Node::set_scene_file_path(const String &p_scene_file_path) {
+ data.scene_file_path = p_scene_file_path;
}
-String Node::get_filename() const {
- return data.filename;
+String Node::get_scene_file_path() const {
+ return data.scene_file_path;
}
void Node::set_editor_description(const String &p_editor_description) {
@@ -1944,8 +1946,8 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
nip->set_instance_path(ip->get_instance_path());
node = nip;
- } else if ((p_flags & DUPLICATE_USE_INSTANCING) && get_filename() != String()) {
- Ref<PackedScene> res = ResourceLoader::load(get_filename());
+ } else if ((p_flags & DUPLICATE_USE_INSTANCING) && get_scene_file_path() != String()) {
+ Ref<PackedScene> res = ResourceLoader::load(get_scene_file_path());
ERR_FAIL_COND_V(res.is_null(), nullptr);
PackedScene::GenEditState ges = PackedScene::GEN_EDIT_STATE_DISABLED;
#ifdef TOOLS_ENABLED
@@ -1968,8 +1970,8 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
ERR_FAIL_COND_V(!node, nullptr);
}
- if (get_filename() != "") { //an instance
- node->set_filename(get_filename());
+ if (get_scene_file_path() != "") { //an instance
+ node->set_scene_file_path(get_scene_file_path());
node->data.editable_instance = data.editable_instance;
}
@@ -2000,7 +2002,7 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
node_tree.push_back(descendant);
- if (descendant->get_filename() != "" && instance_roots.has(descendant->get_owner())) {
+ if (descendant->get_scene_file_path() != "" && instance_roots.has(descendant->get_owner())) {
instance_roots.push_back(descendant);
}
}
@@ -2309,7 +2311,7 @@ void Node::replace_by(Node *p_node, bool p_keep_groups) {
owned_by_owner[i]->set_owner(owner);
}
- p_node->set_filename(get_filename());
+ p_node->set_scene_file_path(get_scene_file_path());
}
void Node::_replace_connections_target(Node *p_new_target) {
@@ -2532,17 +2534,11 @@ NodePath Node::get_import_path() const {
}
static void _add_nodes_to_options(const Node *p_base, const Node *p_node, List<String> *r_options) {
-#ifdef TOOLS_ENABLED
- const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\"";
-#else
- const String quote_style = "\"";
-#endif
-
if (p_node != p_base && !p_node->get_owner()) {
return;
}
String n = p_base->get_path_to(p_node);
- r_options->push_back(n.quote(quote_style));
+ r_options->push_back(n.quote());
for (int i = 0; i < p_node->get_child_count(); i++) {
_add_nodes_to_options(p_base, p_node->get_child(i), r_options);
}
@@ -2689,8 +2685,8 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_index", "include_internal"), &Node::get_index, DEFVAL(false));
ClassDB::bind_method(D_METHOD("print_tree"), &Node::print_tree);
ClassDB::bind_method(D_METHOD("print_tree_pretty"), &Node::print_tree_pretty);
- ClassDB::bind_method(D_METHOD("set_filename", "filename"), &Node::set_filename);
- ClassDB::bind_method(D_METHOD("get_filename"), &Node::get_filename);
+ ClassDB::bind_method(D_METHOD("set_scene_file_path", "scene_file_path"), &Node::set_scene_file_path);
+ ClassDB::bind_method(D_METHOD("get_scene_file_path"), &Node::get_scene_file_path);
ClassDB::bind_method(D_METHOD("propagate_notification", "what"), &Node::propagate_notification);
ClassDB::bind_method(D_METHOD("propagate_call", "method", "args", "parent_first"), &Node::propagate_call, DEFVAL(Array()), DEFVAL(false));
ClassDB::bind_method(D_METHOD("set_physics_process", "enable"), &Node::set_physics_process);
@@ -2738,15 +2734,15 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("request_ready"), &Node::request_ready);
- ClassDB::bind_method(D_METHOD("set_network_authority", "id", "recursive"), &Node::set_network_authority, DEFVAL(true));
- ClassDB::bind_method(D_METHOD("get_network_authority"), &Node::get_network_authority);
+ ClassDB::bind_method(D_METHOD("set_multiplayer_authority", "id", "recursive"), &Node::set_multiplayer_authority, DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("get_multiplayer_authority"), &Node::get_multiplayer_authority);
- ClassDB::bind_method(D_METHOD("is_network_authority"), &Node::is_network_authority);
+ ClassDB::bind_method(D_METHOD("is_multiplayer_authority"), &Node::is_multiplayer_authority);
ClassDB::bind_method(D_METHOD("get_multiplayer"), &Node::get_multiplayer);
ClassDB::bind_method(D_METHOD("get_custom_multiplayer"), &Node::get_custom_multiplayer);
ClassDB::bind_method(D_METHOD("set_custom_multiplayer", "api"), &Node::set_custom_multiplayer);
- ClassDB::bind_method(D_METHOD("rpc_config", "method", "rpc_mode", "transfer_mode", "channel"), &Node::rpc_config, DEFVAL(MultiplayerPeer::TRANSFER_MODE_RELIABLE), DEFVAL(0));
+ ClassDB::bind_method(D_METHOD("rpc_config", "method", "rpc_mode", "call_local", "transfer_mode", "channel"), &Node::rpc_config, DEFVAL(false), DEFVAL(Multiplayer::TRANSFER_MODE_RELIABLE), DEFVAL(0));
ClassDB::bind_method(D_METHOD("set_editor_description", "editor_description"), &Node::set_editor_description);
ClassDB::bind_method(D_METHOD("get_editor_description"), &Node::get_editor_description);
@@ -2835,7 +2831,7 @@ void Node::_bind_methods() {
ADD_SIGNAL(MethodInfo("tree_exited"));
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_name", "get_name");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "filename", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_filename", "get_filename");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "scene_file_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_scene_file_path", "get_scene_file_path");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "owner", PROPERTY_HINT_RESOURCE_TYPE, "Node", PROPERTY_USAGE_NONE), "set_owner", "get_owner");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", PROPERTY_USAGE_NONE), "", "get_multiplayer");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", PROPERTY_USAGE_NONE), "set_custom_multiplayer", "get_custom_multiplayer");
diff --git a/scene/main/node.h b/scene/main/node.h
index d0246ebe84..e59a7a390a 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -96,7 +96,7 @@ private:
};
struct Data {
- String filename;
+ String scene_file_path;
Ref<SceneState> instance_state;
Ref<SceneState> inherited_state;
@@ -127,8 +127,8 @@ private:
ProcessMode process_mode = PROCESS_MODE_INHERIT;
Node *process_owner = nullptr;
- int network_authority = 1; // Server by default.
- Vector<MultiplayerAPI::RPCConfig> rpc_methods;
+ int multiplayer_authority = 1; // Server by default.
+ Vector<Multiplayer::RPCConfig> rpc_methods;
// Variables used to properly sort the node when processing, ignored otherwise.
// TODO: Should move all the stuff below to bits.
@@ -353,8 +353,8 @@ public:
void print_tree();
void print_tree_pretty();
- void set_filename(const String &p_filename);
- String get_filename() const;
+ void set_scene_file_path(const String &p_scene_file_path);
+ String get_scene_file_path() const;
void set_editor_description(const String &p_editor_description);
String get_editor_description() const;
@@ -462,12 +462,12 @@ public:
bool is_displayed_folded() const;
/* NETWORK */
- void set_network_authority(int p_peer_id, bool p_recursive = true);
- int get_network_authority() const;
- bool is_network_authority() const;
+ void set_multiplayer_authority(int p_peer_id, bool p_recursive = true);
+ int get_multiplayer_authority() const;
+ bool is_multiplayer_authority() const;
- uint16_t rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_rpc_mode, MultiplayerPeer::TransferMode p_transfer_mode, int p_channel = 0); // config a local method for RPC
- Vector<MultiplayerAPI::RPCConfig> get_node_rpc_methods() const;
+ uint16_t rpc_config(const StringName &p_method, Multiplayer::RPCMode p_rpc_mode, bool p_call_local = false, Multiplayer::TransferMode p_transfer_mode = Multiplayer::TRANSFER_MODE_RELIABLE, int p_channel = 0); // config a local method for RPC
+ Vector<Multiplayer::RPCConfig> get_node_rpc_methods() const;
void rpc(const StringName &p_method, VARIANT_ARG_LIST); // RPC, honors RPCMode, TransferMode, channel
void rpc_id(int p_peer_id, const StringName &p_method, VARIANT_ARG_LIST); // RPC to specific peer(s), honors RPCMode, TransferMode, channel
diff --git a/scene/main/resource_preloader.cpp b/scene/main/resource_preloader.cpp
index cd9560db61..f4c90ee668 100644
--- a/scene/main/resource_preloader.cpp
+++ b/scene/main/resource_preloader.cpp
@@ -57,8 +57,8 @@ Array ResourcePreloader::_get_resources() const {
Set<String> sorted_names;
- for (Map<StringName, RES>::Element *E = resources.front(); E; E = E->next()) {
- sorted_names.insert(E->key());
+ for (const KeyValue<StringName, RES> &E : resources) {
+ sorted_names.insert(E.key);
}
int i = 0;
@@ -131,8 +131,8 @@ Vector<String> ResourcePreloader::_get_resource_list() const {
}
void ResourcePreloader::get_resource_list(List<StringName> *p_list) {
- for (Map<StringName, RES>::Element *E = resources.front(); E; E = E->next()) {
- p_list->push_back(E->key());
+ for (const KeyValue<StringName, RES> &E : resources) {
+ p_list->push_back(E.key);
}
}
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 8260d0dff5..a122241cd0 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -544,7 +544,7 @@ void SceneTree::process_tweens(float p_delta, bool p_physics) {
}
if (!E->get()->step(p_delta)) {
- E->get()->set_valid(false);
+ E->get()->clear();
tweens.erase(E);
}
if (E == L) {
@@ -570,7 +570,11 @@ void SceneTree::finalize() {
root = nullptr;
}
- // cleanup timers
+ // In case deletion of some objects was queued when destructing the `root`.
+ // E.g. if `queue_free()` was called for some node outside the tree when handling NOTIFICATION_PREDELETE for some node in the tree.
+ _flush_delete_queue();
+
+ // Cleanup timers.
for (Ref<SceneTreeTimer> &timer : timers) {
timer->release_connections();
}
@@ -858,15 +862,6 @@ void SceneTree::_notify_group_pause(const StringName &p_group, int p_notificatio
}
}
-/*
-void SceneMainLoop::_update_listener_2d() {
- if (listener_2d.is_valid()) {
- SpatialSound2DServer::get_singleton()->listener_set_space( listener_2d, world_2d->get_sound_space() );
- }
-}
-
-*/
-
void SceneTree::_call_input_pause(const StringName &p_group, CallInputType p_call_type, const Ref<InputEvent> &p_input, Viewport *p_viewport) {
Map<StringName, Group>::Element *E = group_map.find(p_group);
if (!E) {
@@ -1114,7 +1109,7 @@ Error SceneTree::change_scene_to(const Ref<PackedScene> &p_scene) {
Error SceneTree::reload_current_scene() {
ERR_FAIL_COND_V(!current_scene, ERR_UNCONFIGURED);
- String fname = current_scene->get_filename();
+ String fname = current_scene->get_scene_file_path();
return change_scene(fname);
}
@@ -1331,6 +1326,7 @@ SceneTree::SceneTree() {
// Create with mainloop.
root = memnew(Window);
+ root->set_process_mode(Node::PROCESS_MODE_PAUSABLE);
root->set_name("root");
#ifndef _3D_DISABLED
if (!root->get_world_3d().is_valid()) {
@@ -1346,7 +1342,7 @@ SceneTree::SceneTree() {
current_scene = nullptr;
const int msaa_mode = GLOBAL_DEF("rendering/anti_aliasing/quality/msaa", 0);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/anti_aliasing/quality/msaa", PropertyInfo(Variant::INT, "rendering/anti_aliasing/quality/msaa", PROPERTY_HINT_ENUM, String::utf8("Disabled (Fastest),2× (Fast),4× (Average),8× (Slow),16× (Slower)")));
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/anti_aliasing/quality/msaa", PropertyInfo(Variant::INT, "rendering/anti_aliasing/quality/msaa", PROPERTY_HINT_ENUM, String::utf8("Disabled (Fastest),2× (Average),4× (Slow),8× (Slowest)")));
root->set_msaa(Viewport::MSAA(msaa_mode));
const int ssaa_mode = GLOBAL_DEF("rendering/anti_aliasing/quality/screen_space_aa", 0);
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index b1b94ae910..19331c1906 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -31,7 +31,7 @@
#ifndef SCENE_TREE_H
#define SCENE_TREE_H
-#include "core/io/multiplayer_api.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"
diff --git a/scene/main/timer.cpp b/scene/main/timer.cpp
index 9e462eb1c8..154e4cf683 100644
--- a/scene/main/timer.cpp
+++ b/scene/main/timer.cpp
@@ -82,6 +82,7 @@ void Timer::_notification(int p_what) {
void Timer::set_wait_time(double p_time) {
ERR_FAIL_COND_MSG(p_time <= 0, "Time should be greater than zero.");
wait_time = p_time;
+ update_configuration_warnings();
}
double Timer::get_wait_time() const {
@@ -179,6 +180,16 @@ void Timer::_set_process(bool p_process, bool p_force) {
processing = p_process;
}
+TypedArray<String> Timer::get_configuration_warnings() const {
+ TypedArray<String> warnings = Node::get_configuration_warnings();
+
+ if (wait_time < 0.05 - CMP_EPSILON) {
+ warnings.push_back(TTR("Very low timer wait times (< 0.05 seconds) may behave in significantly different ways depending on the rendered or physics frame rate.\nConsider using a script's process loop instead of relying on a Timer for very low wait times."));
+ }
+
+ return warnings;
+}
+
void Timer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_wait_time", "time_sec"), &Timer::set_wait_time);
ClassDB::bind_method(D_METHOD("get_wait_time"), &Timer::get_wait_time);
diff --git a/scene/main/timer.h b/scene/main/timer.h
index 2b9faddcb9..e2f34042dd 100644
--- a/scene/main/timer.h
+++ b/scene/main/timer.h
@@ -73,6 +73,8 @@ public:
double get_time_left() const;
+ TypedArray<String> get_configuration_warnings() const override;
+
void set_timer_process_callback(TimerProcessCallback p_callback);
TimerProcessCallback get_timer_process_callback() const;
Timer();
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 8ec8c193fb..3280190250 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -35,12 +35,13 @@
#include "core/object/message_queue.h"
#include "core/string/translation.h"
#include "core/templates/pair.h"
+#include "scene/2d/audio_listener_2d.h"
#include "scene/2d/camera_2d.h"
#include "scene/2d/collision_object_2d.h"
#ifndef _3D_DISABLED
+#include "scene/3d/audio_listener_3d.h"
#include "scene/3d/camera_3d.h"
#include "scene/3d/collision_object_3d.h"
-#include "scene/3d/listener_3d.h"
#include "scene/3d/world_environment.h"
#endif // _3D_DISABLED
#include "scene/gui/control.h"
@@ -56,17 +57,17 @@
#include "servers/audio_server.h"
void ViewportTexture::setup_local_to_scene() {
+ Node *local_scene = get_local_scene();
+ if (!local_scene) {
+ return;
+ }
+
if (vp) {
vp->viewport_textures.erase(this);
}
vp = nullptr;
- Node *local_scene = get_local_scene();
- if (!local_scene) {
- return;
- }
-
Node *vpn = local_scene->get_node(path);
ERR_FAIL_COND_MSG(!vpn, "ViewportTexture: Path to node is invalid.");
@@ -80,7 +81,7 @@ void ViewportTexture::setup_local_to_scene() {
RS::get_singleton()->texture_proxy_update(proxy, vp->texture_rid);
RS::get_singleton()->free(proxy_ph);
} else {
- ERR_FAIL_COND(proxy.is_valid()); //should be invalid
+ ERR_FAIL_COND(proxy.is_valid()); // Should be invalid.
proxy = RS::get_singleton()->texture_proxy_create(vp->texture_rid);
}
}
@@ -117,7 +118,6 @@ Size2 ViewportTexture::get_size() const {
}
RID ViewportTexture::get_rid() const {
- //ERR_FAIL_COND_V_MSG(!vp, RID(), "Viewport Texture must be set to use it.");
if (proxy.is_null()) {
proxy_ph = RS::get_singleton()->texture_2d_placeholder_create();
proxy = RS::get_singleton()->texture_proxy_create(proxy_ph);
@@ -262,7 +262,7 @@ void Viewport::_sub_window_update(Window *p_window) {
void Viewport::_sub_window_grab_focus(Window *p_window) {
if (p_window == nullptr) {
- //release current focus
+ // Release current focus.
if (gui.subwindow_focused) {
gui.subwindow_focused->_event_callback(DisplayServer::WINDOW_EVENT_FOCUS_OUT);
gui.subwindow_focused = nullptr;
@@ -288,18 +288,18 @@ void Viewport::_sub_window_grab_focus(Window *p_window) {
ERR_FAIL_COND(index == -1);
if (p_window->get_flag(Window::FLAG_NO_FOCUS)) {
- //can only move to foreground, but no focus granted
+ // Can only move to foreground, but no focus granted.
SubWindow sw = gui.sub_windows[index];
gui.sub_windows.remove(index);
gui.sub_windows.push_back(sw);
index = gui.sub_windows.size() - 1;
_sub_window_update_order();
- return; //i guess not...
+ return;
}
if (gui.subwindow_focused) {
if (gui.subwindow_focused == p_window) {
- return; //nothing to do
+ return; // Nothing to do.
}
gui.subwindow_focused->_event_callback(DisplayServer::WINDOW_EVENT_FOCUS_OUT);
gui.subwindow_drag = SUB_WINDOW_DRAG_DISABLED;
@@ -316,7 +316,7 @@ void Viewport::_sub_window_grab_focus(Window *p_window) {
gui.subwindow_focused->_event_callback(DisplayServer::WINDOW_EVENT_FOCUS_IN);
- { //move to foreground
+ { // Move to foreground.
SubWindow sw = gui.sub_windows[index];
gui.sub_windows.remove(index);
gui.sub_windows.push_back(sw);
@@ -381,10 +381,10 @@ void Viewport::_notification(int p_what) {
current_canvas = find_world_2d()->get_canvas();
RenderingServer::get_singleton()->viewport_attach_canvas(viewport, current_canvas);
- _update_listener_2d();
+ _update_audio_listener_2d();
#ifndef _3D_DISABLED
RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario());
- _update_listener_3d();
+ _update_audio_listener_3d();
#endif // _3D_DISABLED
add_to_group("_viewports");
@@ -408,9 +408,9 @@ void Viewport::_notification(int p_what) {
} break;
case NOTIFICATION_READY: {
#ifndef _3D_DISABLED
- if (listener_3d_set.size() && !listener_3d) {
- Listener3D *first = nullptr;
- for (Set<Listener3D *>::Element *E = listener_3d_set.front(); E; E = E->next()) {
+ if (audio_listener_3d_set.size() && !audio_listener_3d) {
+ AudioListener3D *first = nullptr;
+ for (Set<AudioListener3D *>::Element *E = audio_listener_3d_set.front(); E; E = E->next()) {
if (first == nullptr || first->is_greater_than(E->get())) {
first = E->get();
}
@@ -422,7 +422,7 @@ void Viewport::_notification(int p_what) {
}
if (camera_3d_set.size() && !camera_3d) {
- //there are cameras but no current camera, pick first in tree and make it current
+ // There are cameras but no current camera, pick first in tree and make it current.
Camera3D *first = nullptr;
for (Set<Camera3D *>::Element *E = camera_3d_set.front(); E; E = E->next()) {
if (first == nullptr || first->is_greater_than(E->get())) {
@@ -521,8 +521,9 @@ void Viewport::_process_picking() {
PhysicsDirectSpaceState2D *ss2d = PhysicsServer2D::get_singleton()->space_get_direct_state(find_world_2d()->get_space());
if (physics_has_last_mousepos) {
- // if no mouse event exists, create a motion one. This is necessary because objects or camera may have moved.
- // while this extra event is sent, it is checked if both camera and last object and last ID did not move. If nothing changed, the event is discarded to avoid flooding with unnecessary motion events every frame
+ // If no mouse event exists, create a motion one. This is necessary because objects or camera may have moved.
+ // While this extra event is sent, it is checked if both camera and last object and last ID did not move.
+ // If nothing changed, the event is discarded to avoid flooding with unnecessary motion events every frame.
bool has_mouse_event = false;
for (const Ref<InputEvent> &m : physics_picking_events) {
if (m.is_valid()) {
@@ -596,7 +597,7 @@ void Viewport::_process_picking() {
Ref<InputEventKey> k = ev;
if (k.is_valid()) {
- //only for mask
+ // Only for mask.
physics_last_mouse_state.alt = k->is_alt_pressed();
physics_last_mouse_state.shift = k->is_shift_pressed();
physics_last_mouse_state.control = k->is_ctrl_pressed();
@@ -617,7 +618,7 @@ void Viewport::_process_picking() {
}
if (ss2d) {
- //send to 2D
+ // Send to 2D.
uint64_t frame = get_tree()->get_frame();
@@ -626,11 +627,11 @@ void Viewport::_process_picking() {
Transform2D canvas_transform;
ObjectID canvas_layer_id;
if (E->get()) {
- // A descendant CanvasLayer
+ // A descendant CanvasLayer.
canvas_transform = E->get()->get_transform();
canvas_layer_id = E->get()->get_instance_id();
} else {
- // This Viewport's builtin canvas
+ // This Viewport's builtin canvas.
canvas_transform = get_canvas_transform();
canvas_layer_id = ObjectID();
}
@@ -650,7 +651,7 @@ void Viewport::_process_picking() {
co->_mouse_enter();
} else {
F->get() = frame;
- // It was already hovered, so don't send the event if it's faked
+ // It was already hovered, so don't send the event if it's faked.
if (mm.is_valid() && mm->get_device() == InputEvent::DEVICE_ID_INTERNAL) {
send_event = false;
}
@@ -699,11 +700,11 @@ void Viewport::_process_picking() {
}
if (captured) {
- //none
+ // None.
} else if (pos == last_pos) {
if (last_id.is_valid()) {
if (ObjectDB::get_instance(last_id) && last_object) {
- //good, exists
+ // Good, exists.
_collision_object_3d_input_event(last_object, camera_3d, ev, result.position, result.normal, result.shape);
if (last_object->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) {
physics_object_capture = last_id;
@@ -821,21 +822,26 @@ Rect2 Viewport::get_visible_rect() const {
return r;
}
-void Viewport::_update_listener_2d() {
- AudioServer::get_singleton()->notify_listener_changed();
+void Viewport::_update_audio_listener_2d() {
+ if (AudioServer::get_singleton()) {
+ AudioServer::get_singleton()->notify_listener_changed();
+ }
}
void Viewport::set_as_audio_listener_2d(bool p_enable) {
- if (p_enable == audio_listener_2d) {
+ if (p_enable == is_audio_listener_2d_enabled) {
return;
}
- audio_listener_2d = p_enable;
-
- _update_listener_2d();
+ is_audio_listener_2d_enabled = p_enable;
+ _update_audio_listener_2d();
}
bool Viewport::is_audio_listener_2d() const {
+ return is_audio_listener_2d_enabled;
+}
+
+AudioListener2D *Viewport::get_audio_listener_2d() const {
return audio_listener_2d;
}
@@ -903,6 +909,21 @@ void Viewport::_camera_2d_set(Camera2D *p_camera_2d) {
camera_2d = p_camera_2d;
}
+void Viewport::_audio_listener_2d_set(AudioListener2D *p_listener) {
+ if (audio_listener_2d == p_listener) {
+ return;
+ } else if (audio_listener_2d) {
+ audio_listener_2d->clear_current();
+ }
+ audio_listener_2d = p_listener;
+}
+
+void Viewport::_audio_listener_2d_remove(AudioListener2D *p_listener) {
+ if (audio_listener_2d == p_listener) {
+ audio_listener_2d = nullptr;
+ }
+}
+
void Viewport::_canvas_layer_add(CanvasLayer *p_canvas_layer) {
canvas_layers.insert(p_canvas_layer);
}
@@ -941,7 +962,7 @@ void Viewport::set_world_2d(const Ref<World2D> &p_world_2d) {
world_2d = Ref<World2D>(memnew(World2D));
}
- _update_listener_2d();
+ _update_audio_listener_2d();
if (is_inside_tree()) {
current_canvas = find_world_2d()->get_canvas();
@@ -1058,8 +1079,11 @@ Transform2D Viewport::_get_input_pre_xform() const {
}
Ref<InputEvent> Viewport::_make_input_local(const Ref<InputEvent> &ev) {
- Transform2D ai = get_final_transform().affine_inverse() * _get_input_pre_xform();
+ if (ev.is_null()) {
+ return ev; // No transformation defined for null event
+ }
+ Transform2D ai = get_final_transform().affine_inverse() * _get_input_pre_xform();
return ev->xformed_by(ai);
}
@@ -1102,7 +1126,7 @@ String Viewport::_gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Cont
while (p_control) {
tooltip = p_control->get_tooltip(pos);
- //Temporary solution for PopupMenus
+ // Temporary solution for PopupMenus.
PopupMenu *menu = Object::cast_to<PopupMenu>(this);
if (menu) {
tooltip = menu->get_tooltip(pos);
@@ -1216,11 +1240,9 @@ void Viewport::_gui_show_tooltip() {
}
void Viewport::_gui_call_input(Control *p_control, const Ref<InputEvent> &p_input) {
- //_block();
-
Ref<InputEvent> ev = p_input;
- //mouse wheel events can't be stopped
+ // Mouse wheel events can't be stopped.
Ref<InputEventMouseButton> mb = p_input;
bool cant_stop_me_now = (mb.is_valid() &&
@@ -1256,11 +1278,9 @@ void Viewport::_gui_call_input(Control *p_control, const Ref<InputEvent> &p_inpu
break;
}
- ev = ev->xformed_by(ci->get_transform()); //transform event upwards
+ ev = ev->xformed_by(ci->get_transform()); // Transform event upwards.
ci = ci->get_parent_item();
}
-
- //_unblock();
}
void Viewport::_gui_call_notification(Control *p_control, int p_what) {
@@ -1290,12 +1310,10 @@ void Viewport::_gui_call_notification(Control *p_control, int p_what) {
ci = ci->get_parent_item();
}
-
- //_unblock();
}
Control *Viewport::gui_find_control(const Point2 &p_global) {
- //aca va subwindows
+ // Handle subwindows.
_gui_sort_roots();
for (List<Control *>::Element *E = gui.roots.back(); E; E = E->prev()) {
@@ -1327,8 +1345,7 @@ Control *Viewport::_gui_find_control_at_pos(CanvasItem *p_node, const Point2 &p_
}
if (!p_node->is_visible()) {
- //return _find_next_visible_control_at_pos(p_node,p_global,r_inv_xform);
- return nullptr; //canvas item hidden, discard
+ return nullptr; // Canvas item hidden, discard.
}
Transform2D matrix = p_xform * p_node->get_transform();
@@ -1372,32 +1389,31 @@ Control *Viewport::_gui_find_control_at_pos(CanvasItem *p_node, const Point2 &p_
}
bool Viewport::_gui_drop(Control *p_at_control, Point2 p_at_pos, bool p_just_check) {
- { //attempt grab, try parent controls too
- CanvasItem *ci = p_at_control;
- while (ci) {
- Control *control = Object::cast_to<Control>(ci);
- if (control) {
- if (control->can_drop_data(p_at_pos, gui.drag_data)) {
- if (!p_just_check) {
- control->drop_data(p_at_pos, gui.drag_data);
- }
-
- return true;
+ // Attempt grab, try parent controls too.
+ CanvasItem *ci = p_at_control;
+ while (ci) {
+ Control *control = Object::cast_to<Control>(ci);
+ if (control) {
+ if (control->can_drop_data(p_at_pos, gui.drag_data)) {
+ if (!p_just_check) {
+ control->drop_data(p_at_pos, gui.drag_data);
}
- if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP) {
- break;
- }
+ return true;
}
- p_at_pos = ci->get_transform().xform(p_at_pos);
-
- if (ci->is_set_as_top_level()) {
+ if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP) {
break;
}
+ }
- ci = ci->get_parent_item();
+ p_at_pos = ci->get_transform().xform(p_at_pos);
+
+ if (ci->is_set_as_top_level()) {
+ break;
}
+
+ ci = ci->get_parent_item();
}
return false;
@@ -1417,23 +1433,9 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
if (mb->is_pressed()) {
Size2 pos = mpos;
if (gui.mouse_focus_mask) {
- //do not steal mouse focus and stuff while a focus mask exists
- gui.mouse_focus_mask |= 1 << (mb->get_button_index() - 1); //add the button to the mask
+ // Do not steal mouse focus and stuff while a focus mask exists.
+ gui.mouse_focus_mask |= 1 << (mb->get_button_index() - 1); // Add the button to the mask.
} else {
- bool is_handled = false;
-
- if (is_handled) {
- set_input_as_handled();
- return;
- }
-
- //Matrix32 parent_xform;
-
- /*
- if (data.parent_canvas_item)
- parent_xform=data.parent_canvas_item->get_global_transform();
- */
-
gui.mouse_focus = gui_find_control(pos);
gui.last_mouse_focus = gui.mouse_focus;
@@ -1450,7 +1452,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
}
}
- mb = mb->xformed_by(Transform2D()); // make a copy of the event
+ mb = mb->xformed_by(Transform2D()); // Make a copy of the event.
mb->set_global_position(pos);
@@ -1467,7 +1469,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
}
#endif
- if (mb->get_button_index() == MOUSE_BUTTON_LEFT) { //assign focus
+ if (mb->get_button_index() == MOUSE_BUTTON_LEFT) { // Assign focus.
CanvasItem *ci = gui.mouse_focus;
while (ci) {
Control *control = Object::cast_to<Control>(ci);
@@ -1499,7 +1501,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
set_input_as_handled();
if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
- //alternate drop use (when using force_drag(), as proposed by #5342
+ // Alternate drop use (when using force_drag(), as proposed by #5342).
if (gui.mouse_focus) {
_gui_drop(gui.mouse_focus, pos, false);
}
@@ -1513,7 +1515,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
gui.drag_preview_id = ObjectID();
}
_propagate_viewport_notification(this, NOTIFICATION_DRAG_END);
- //change mouse accordingly
+ // Change mouse accordingly.
}
_gui_cancel_tooltip();
@@ -1533,26 +1535,28 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
gui.dragging = false;
gui.drag_mouse_over = nullptr;
_propagate_viewport_notification(this, NOTIFICATION_DRAG_END);
- //change mouse accordingly
+ // Change mouse accordingly.
}
- gui.mouse_focus_mask &= ~(1 << (mb->get_button_index() - 1)); //remove from mask
+ gui.mouse_focus_mask &= ~(1 << (mb->get_button_index() - 1)); // Remove from mask.
if (!gui.mouse_focus) {
- //release event is only sent if a mouse focus (previously pressed button) exists
+ // Release event is only sent if a mouse focus (previously pressed button) exists.
return;
}
Size2 pos = mpos;
- mb = mb->xformed_by(Transform2D()); //make a copy
+ mb = mb->xformed_by(Transform2D()); // Make a copy.
mb->set_global_position(pos);
pos = gui.focus_inv_xform.xform(pos);
mb->set_position(pos);
Control *mouse_focus = gui.mouse_focus;
- //disable mouse focus if needed before calling input, this makes popups on mouse press event work better, as the release will never be received otherwise
+ // Disable mouse focus if needed before calling input,
+ // this makes popups on mouse press event work better,
+ // as the release will never be received otherwise.
if (gui.mouse_focus_mask == 0) {
gui.mouse_focus = nullptr;
gui.forced_mouse_focus = false;
@@ -1562,11 +1566,6 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
_gui_call_input(mouse_focus, mb);
}
- /*if (gui.drag_data.get_type()!=Variant::NIL && mb->get_button_index()==MOUSE_BUTTON_LEFT) {
- _propagate_viewport_notification(this,NOTIFICATION_DRAG_END);
- gui.drag_data=Variant(); //always clear
- }*/
-
// In case the mouse was released after for example dragging a scrollbar,
// check whether the current control is different from the stored one. If
// it is different, rather than wait for it to be updated the next time the
@@ -1605,12 +1604,12 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Control *over = nullptr;
- // D&D
+ // Drag & drop.
if (!gui.drag_attempted && gui.mouse_focus && mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) {
gui.drag_accum += mm->get_relative();
float len = gui.drag_accum.length();
if (len > 10) {
- { //attempt grab, try parent controls too
+ { // Attempt grab, try parent controls too.
CanvasItem *ci = gui.mouse_focus;
while (ci) {
Control *control = Object::cast_to<Control>(ci);
@@ -1683,14 +1682,14 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Vector2 speed = localizer.basis_xform(mm->get_speed());
Vector2 rel = localizer.basis_xform(mm->get_relative());
- mm = mm->xformed_by(Transform2D()); //make a copy
+ mm = mm->xformed_by(Transform2D()); // Make a copy.
mm->set_global_position(mpos);
mm->set_speed(speed);
mm->set_relative(rel);
if (mm->get_button_mask() == 0) {
- //nothing pressed
+ // Nothing pressed.
bool can_tooltip = true;
@@ -1714,7 +1713,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
is_tooltip_shown = true;
}
} else {
- is_tooltip_shown = true; //well, nothing to compare against, likely using custom control, so if it changes there is nothing we can do
+ is_tooltip_shown = true; // Nothing to compare against, likely using custom control, so if it changes there is nothing we can do.
}
}
} else {
@@ -1771,7 +1770,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
}
if (gui.drag_data.get_type() != Variant::NIL) {
- //handle dragandrop
+ // Handle drag & drop.
Control *drag_preview = _gui_get_drag_preview();
if (drag_preview) {
@@ -1781,9 +1780,8 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
gui.drag_mouse_over = over;
gui.drag_mouse_over_pos = Vector2();
- //find the window this is above of
-
- //see if there is an embedder
+ // Find the window this is above of.
+ // See if there is an embedder.
Viewport *embedder = nullptr;
Vector2 viewport_pos;
@@ -1791,7 +1789,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
embedder = this;
viewport_pos = mpos;
} else {
- //not an embedder, but may be a subwindow of an embedder
+ // Not an embedder, but may be a subwindow of an embedder.
Window *w = Object::cast_to<Window>(this);
if (w) {
if (w->is_embedded()) {
@@ -1799,7 +1797,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Transform2D ai = (get_final_transform().affine_inverse() * _get_input_pre_xform()).affine_inverse();
- viewport_pos = ai.xform(mpos) + w->get_position(); //to parent coords
+ viewport_pos = ai.xform(mpos) + w->get_position(); // To parent coords.
}
}
}
@@ -1807,7 +1805,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Viewport *viewport_under = nullptr;
if (embedder) {
- //use embedder logic
+ // Use embedder logic.
for (int i = embedder->gui.sub_windows.size() - 1; i >= 0; i--) {
Window *sw = embedder->gui.sub_windows[i].window;
@@ -1825,11 +1823,11 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
}
if (!viewport_under) {
- //not in a subwindow, likely in embedder
+ // Not in a subwindow, likely in embedder.
viewport_under = embedder;
}
} else {
- //use displayserver logic
+ // Use DisplayServer logic.
Vector2i screen_mouse_pos = DisplayServer::get_singleton()->mouse_get_position();
DisplayServer::WindowID window_id = DisplayServer::get_singleton()->get_window_at_screen_position(screen_mouse_pos);
@@ -1837,7 +1835,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
ObjectID object_under = DisplayServer::get_singleton()->window_get_attached_instance_id(window_id);
- if (object_under != ObjectID()) { //fetch window
+ if (object_under != ObjectID()) { // Fetch window.
Window *w = Object::cast_to<Window>(ObjectDB::get_instance(object_under));
if (w) {
viewport_under = w;
@@ -1850,7 +1848,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
if (viewport_under) {
Transform2D ai = (viewport_under->get_final_transform().affine_inverse() * viewport_under->_get_input_pre_xform());
viewport_pos = ai.xform(viewport_pos);
- //find control under at pos
+ // Find control under at position.
gui.drag_mouse_over = viewport_under->gui_find_control(viewport_pos);
if (gui.drag_mouse_over) {
Transform2D localizer = gui.drag_mouse_over->get_global_transform_with_canvas().affine_inverse();
@@ -1882,7 +1880,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Control *over = gui_find_control(pos);
if (over) {
if (over->can_process()) {
- touch_event = touch_event->xformed_by(Transform2D()); //make a copy
+ touch_event = touch_event->xformed_by(Transform2D()); // Make a copy.
if (over == gui.mouse_focus) {
pos = gui.focus_inv_xform.xform(pos);
} else {
@@ -1896,7 +1894,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
}
} else if (touch_event->get_index() == 0 && gui.last_mouse_focus) {
if (gui.last_mouse_focus->can_process()) {
- touch_event = touch_event->xformed_by(Transform2D()); //make a copy
+ touch_event = touch_event->xformed_by(Transform2D()); // Make a copy.
touch_event->set_position(gui.focus_inv_xform.xform(pos));
_gui_call_input(gui.last_mouse_focus, touch_event);
@@ -1917,7 +1915,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Control *over = gui_find_control(pos);
if (over) {
if (over->can_process()) {
- gesture_event = gesture_event->xformed_by(Transform2D()); //make a copy
+ gesture_event = gesture_event->xformed_by(Transform2D()); // Make a copy.
if (over == gui.mouse_focus) {
pos = gui.focus_inv_xform.xform(pos);
} else {
@@ -1944,7 +1942,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Vector2 speed = localizer.basis_xform(drag_event->get_speed());
Vector2 rel = localizer.basis_xform(drag_event->get_relative());
- drag_event = drag_event->xformed_by(Transform2D()); //make a copy
+ drag_event = drag_event->xformed_by(Transform2D()); // Make a copy.
drag_event->set_speed(speed);
drag_event->set_relative(rel);
@@ -1975,38 +1973,32 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
}
}
- Control *from = gui.key_focus ? gui.key_focus : nullptr; //hmm
-
- //keyboard focus
- //if (from && p_event->is_pressed() && !p_event->is_alt_pressed() && !p_event->is_meta_pressed() && !p_event->key->is_command_pressed()) {
- Ref<InputEventKey> k = p_event;
- //need to check for mods, otherwise any combination of alt/ctrl/shift+<up/down/left/right/etc> is handled here when it shouldn't be.
- bool mods = k.is_valid() && (k->is_ctrl_pressed() || k->is_alt_pressed() || k->is_shift_pressed() || k->is_meta_pressed());
+ Control *from = gui.key_focus ? gui.key_focus : nullptr;
if (from && p_event->is_pressed()) {
Control *next = nullptr;
- if (p_event->is_action_pressed("ui_focus_next", true)) {
+ if (p_event->is_action_pressed("ui_focus_next", true, true)) {
next = from->find_next_valid_focus();
}
- if (p_event->is_action_pressed("ui_focus_prev", true)) {
+ if (p_event->is_action_pressed("ui_focus_prev", true, true)) {
next = from->find_prev_valid_focus();
}
- if (!mods && p_event->is_action_pressed("ui_up", true)) {
+ if (p_event->is_action_pressed("ui_up", true, true)) {
next = from->_get_focus_neighbor(SIDE_TOP);
}
- if (!mods && p_event->is_action_pressed("ui_left", true)) {
+ if (p_event->is_action_pressed("ui_left", true, true)) {
next = from->_get_focus_neighbor(SIDE_LEFT);
}
- if (!mods && p_event->is_action_pressed("ui_right", true)) {
+ if (p_event->is_action_pressed("ui_right", true, true)) {
next = from->_get_focus_neighbor(SIDE_RIGHT);
}
- if (!mods && p_event->is_action_pressed("ui_down", true)) {
+ if (p_event->is_action_pressed("ui_down", true, true)) {
next = from->_get_focus_neighbor(SIDE_BOTTOM);
}
@@ -2051,7 +2043,7 @@ void Viewport::_gui_set_drag_preview(Control *p_base, Control *p_control) {
}
p_control->set_as_top_level(true);
p_control->set_position(gui.last_mouse_pos);
- p_base->get_root_parent_control()->add_child(p_control); //add as child of viewport
+ p_base->get_root_parent_control()->add_child(p_control); // Add as child of viewport.
p_control->raise();
gui.drag_preview_id = p_control->get_instance_id();
@@ -2153,8 +2145,8 @@ bool Viewport::_gui_control_has_focus(const Control *p_control) {
}
void Viewport::_gui_control_grab_focus(Control *p_control) {
- //no need for change
if (gui.key_focus && gui.key_focus == p_control) {
+ // No need for change.
return;
}
get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, "_viewports", "_gui_remove_focus_for_window", (Node *)get_base_window());
@@ -2200,7 +2192,10 @@ void Viewport::_drop_physics_mouseover(bool p_paused_only) {
if (physics_object_over.is_valid()) {
CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_over));
if (co) {
- if (!(p_paused_only && co->can_process())) {
+ if (!co->is_inside_tree()) {
+ physics_object_over = ObjectID();
+ physics_object_capture = ObjectID();
+ } else if (!(p_paused_only && co->can_process())) {
co->_mouse_exit();
physics_object_over = ObjectID();
physics_object_capture = ObjectID();
@@ -2221,7 +2216,7 @@ void Viewport::_cleanup_mouseover_colliders(bool p_clean_all_frames, bool p_paus
Object *o = ObjectDB::get_instance(E->key());
if (o) {
CollisionObject2D *co = Object::cast_to<CollisionObject2D>(o);
- if (co) {
+ if (co && co->is_inside_tree()) {
if (p_clean_all_frames && p_paused_only && co->can_process()) {
continue;
}
@@ -2236,7 +2231,7 @@ void Viewport::_cleanup_mouseover_colliders(bool p_clean_all_frames, bool p_paus
to_erase.pop_front();
}
- // Per-shape
+ // Per-shape.
List<Map<Pair<ObjectID, int>, uint64_t, PairSort<ObjectID, int>>::Element *> shapes_to_erase;
for (Map<Pair<ObjectID, int>, uint64_t, PairSort<ObjectID, int>>::Element *E = physics_2d_shape_mouseover.front(); E; E = E->next()) {
@@ -2247,7 +2242,7 @@ void Viewport::_cleanup_mouseover_colliders(bool p_clean_all_frames, bool p_paus
Object *o = ObjectDB::get_instance(E->key().first);
if (o) {
CollisionObject2D *co = Object::cast_to<CollisionObject2D>(o);
- if (co) {
+ if (co && co->is_inside_tree()) {
if (p_clean_all_frames && p_paused_only && co->can_process()) {
continue;
}
@@ -2275,7 +2270,7 @@ void Viewport::_gui_grab_click_focus(Control *p_control) {
void Viewport::_post_gui_grab_click_focus() {
Control *focus_grabber = gui.mouse_click_grabber;
if (!focus_grabber) {
- // Redundant grab requests were made
+ // Redundant grab requests were made.
return;
}
gui.mouse_click_grabber = nullptr;
@@ -2293,7 +2288,7 @@ void Viewport::_post_gui_grab_click_focus() {
Ref<InputEventMouseButton> mb;
mb.instantiate();
- //send unclick
+ // Send unclick.
mb->set_position(click);
mb->set_button_index(MouseButton(i + 1));
@@ -2311,7 +2306,7 @@ void Viewport::_post_gui_grab_click_focus() {
Ref<InputEventMouseButton> mb;
mb.instantiate();
- //send click
+ // Send click.
mb->set_position(click);
mb->set_button_index(MouseButton(i + 1));
@@ -2348,7 +2343,7 @@ Viewport::SubWindowResize Viewport::_sub_window_get_resize_margin(Window *p_subw
r.size.y += title_height;
if (r.has_point(p_point)) {
- return SUB_WINDOW_RESIZE_DISABLED; //it's inside, so no resize
+ return SUB_WINDOW_RESIZE_DISABLED; // It's inside, so no resize.
}
int dist_x = p_point.x < r.position.x ? (p_point.x - r.position.x) : (p_point.x > (r.position.x + r.size.x) ? (p_point.x - (r.position.x + r.size.x)) : 0);
@@ -2407,12 +2402,12 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
if (gui.subwindow_drag == SUB_WINDOW_DRAG_CLOSE) {
if (gui.subwindow_drag_close_rect.has_point(mb->get_position())) {
- //close window
+ // Close window.
gui.subwindow_focused->_event_callback(DisplayServer::WINDOW_EVENT_CLOSE_REQUEST);
}
}
gui.subwindow_drag = SUB_WINDOW_DRAG_DISABLED;
- if (gui.subwindow_focused != nullptr) { //may have been erased
+ if (gui.subwindow_focused != nullptr) { // May have been erased.
_sub_window_update(gui.subwindow_focused);
}
}
@@ -2519,27 +2514,27 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
gui.subwindow_focused->_rect_changed_callback(r);
}
- if (gui.subwindow_focused) { //may have been erased
+ if (gui.subwindow_focused) { // May have been erased.
_sub_window_update(gui.subwindow_focused);
}
}
- return true; //handled
+ return true; // Handled.
}
Ref<InputEventMouseButton> mb = p_event;
- //if the event is a mouse button, we need to check whether another window was clicked
+ // If the event is a mouse button, we need to check whether another window was clicked.
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
bool click_on_window = false;
for (int i = gui.sub_windows.size() - 1; i >= 0; i--) {
SubWindow &sw = gui.sub_windows.write[i];
- //clicked inside window?
+ // Clicked inside window?
Rect2i r = Rect2i(sw.window->get_position(), sw.window->get_size());
if (!sw.window->get_flag(Window::FLAG_BORDERLESS)) {
- //check top bar
+ // Check top bar.
int title_height = sw.window->get_theme_constant(SNAME("title_height"));
Rect2i title_bar = r;
title_bar.position.y -= title_height;
@@ -2557,13 +2552,13 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
close_rect.size = close_icon->get_size();
if (gui.subwindow_focused != sw.window) {
- //refocus
+ // Refocus.
_sub_window_grab_focus(sw.window);
}
if (close_rect.has_point(mb->get_position())) {
gui.subwindow_drag = SUB_WINDOW_DRAG_CLOSE;
- gui.subwindow_drag_close_inside = true; //starts inside
+ gui.subwindow_drag_close_inside = true; // Starts inside.
gui.subwindow_drag_close_rect = close_rect;
} else {
gui.subwindow_drag = SUB_WINDOW_DRAG_MOVE;
@@ -2584,9 +2579,9 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
}
}
if (!click_on_window && r.has_point(mb->get_position())) {
- //clicked, see if it needs to fetch focus
+ // Clicked, see if it needs to fetch focus.
if (gui.subwindow_focused != sw.window) {
- //refocus
+ // Refocus.
_sub_window_grab_focus(sw.window);
}
@@ -2599,7 +2594,7 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
}
if (!click_on_window && gui.subwindow_focused) {
- //no window found and clicked, remove focus
+ // No window found and clicked, remove focus.
_sub_window_grab_focus(nullptr);
}
}
@@ -2623,13 +2618,13 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
DisplayServer::get_singleton()->cursor_set_shape(shapes[resize]);
- return true; //reserved for showing the resize cursor
+ return true; // Reserved for showing the resize cursor.
}
}
}
if (gui.subwindow_drag != SUB_WINDOW_DRAG_DISABLED) {
- return true; // dragging, don't pass the event
+ return true; // Dragging, don't pass the event.
}
if (!gui.subwindow_focused) {
@@ -2706,10 +2701,10 @@ void Viewport::push_unhandled_input(const Ref<InputEvent> &p_event, bool p_local
ev = p_event;
}
- // Unhandled Input
+ // Unhandled Input.
get_tree()->_call_input_pause(unhandled_input_group, SceneTree::CALL_INPUT_TYPE_UNHANDLED_INPUT, ev, this);
- // Unhandled key Input - used for performance reasons - This is called a lot less than _unhandled_input since it ignores MouseMotion, etc
+ // Unhandled key Input - used for performance reasons - This is called a lot less than _unhandled_input since it ignores MouseMotion, etc.
if (!is_input_handled() && (Object::cast_to<InputEventKey>(*ev) != nullptr || Object::cast_to<InputEventShortcut>(*ev) != nullptr)) {
get_tree()->_call_input_pause(unhandled_key_input_group, SceneTree::CALL_INPUT_TYPE_UNHANDLED_KEY_INPUT, ev, this);
}
@@ -2720,7 +2715,7 @@ void Viewport::push_unhandled_input(const Ref<InputEvent> &p_event, bool p_local
Object::cast_to<InputEventMouseMotion>(*ev) ||
Object::cast_to<InputEventScreenDrag>(*ev) ||
Object::cast_to<InputEventScreenTouch>(*ev) ||
- Object::cast_to<InputEventKey>(*ev) //to remember state
+ Object::cast_to<InputEventKey>(*ev) // To remember state.
)) {
physics_picking_events.push_back(ev);
@@ -2766,10 +2761,6 @@ Variant Viewport::gui_get_drag_data() const {
}
TypedArray<String> Viewport::get_configuration_warnings() const {
- /*if (get_parent() && !Object::cast_to<Control>(get_parent()) && !render_target) {
- return TTR("This viewport is not set as render target. If you intend for it to display its contents directly to the screen, make it a child of a Control so it can obtain a size. Otherwise, make it a RenderTarget and assign its internal texture to some node for display.");
- }*/
-
TypedArray<String> warnings = Node::get_configuration_warnings();
if (size.x == 0 || size.y == 0) {
@@ -2893,9 +2884,8 @@ bool Viewport::gui_is_dragging() const {
void Viewport::set_input_as_handled() {
_drop_physics_mouseover();
- if (handle_input_locally) {
- local_input_handled = true;
- } else {
+
+ if (!handle_input_locally) {
ERR_FAIL_COND(!is_inside_tree());
Viewport *vp = this;
while (true) {
@@ -2907,16 +2897,19 @@ void Viewport::set_input_as_handled() {
}
vp = vp->get_parent()->get_viewport();
}
- vp->set_input_as_handled();
+ if (vp != this) {
+ vp->set_input_as_handled();
+ return;
+ }
}
+
+ local_input_handled = true;
}
bool Viewport::is_input_handled() const {
- if (handle_input_locally) {
- return local_input_handled;
- } else {
- const Viewport *vp = this;
+ if (!handle_input_locally) {
ERR_FAIL_COND_V(!is_inside_tree(), false);
+ const Viewport *vp = this;
while (true) {
if (Object::cast_to<Window>(vp)) {
break;
@@ -2926,8 +2919,11 @@ bool Viewport::is_input_handled() const {
}
vp = vp->get_parent()->get_viewport();
}
- return vp->is_input_handled();
+ if (vp != this) {
+ return vp->is_input_handled();
+ }
}
+ return local_input_handled;
}
void Viewport::set_handle_input_locally(bool p_enable) {
@@ -3057,72 +3053,74 @@ Viewport::SDFScale Viewport::get_sdf_scale() const {
}
#ifndef _3D_DISABLED
-Listener3D *Viewport::get_listener_3d() const {
- return listener_3d;
+AudioListener3D *Viewport::get_audio_listener_3d() const {
+ return audio_listener_3d;
}
void Viewport::set_as_audio_listener_3d(bool p_enable) {
- if (p_enable == audio_listener_3d) {
+ if (p_enable == is_audio_listener_3d_enabled) {
return;
}
- audio_listener_3d = p_enable;
- _update_listener_3d();
+ is_audio_listener_3d_enabled = p_enable;
+ _update_audio_listener_3d();
}
bool Viewport::is_audio_listener_3d() const {
- return audio_listener_3d;
+ return is_audio_listener_3d_enabled;
}
-void Viewport::_update_listener_3d() {
- AudioServer::get_singleton()->notify_listener_changed();
+void Viewport::_update_audio_listener_3d() {
+ if (AudioServer::get_singleton()) {
+ AudioServer::get_singleton()->notify_listener_changed();
+ }
}
void Viewport::_listener_transform_3d_changed_notify() {
}
-void Viewport::_listener_3d_set(Listener3D *p_listener) {
- if (listener_3d == p_listener) {
+void Viewport::_audio_listener_3d_set(AudioListener3D *p_listener) {
+ if (audio_listener_3d == p_listener) {
return;
}
- listener_3d = p_listener;
+ audio_listener_3d = p_listener;
- _update_listener_3d();
+ _update_audio_listener_3d();
_listener_transform_3d_changed_notify();
}
-bool Viewport::_listener_3d_add(Listener3D *p_listener) {
- listener_3d_set.insert(p_listener);
- return listener_3d_set.size() == 1;
+bool Viewport::_audio_listener_3d_add(AudioListener3D *p_listener) {
+ audio_listener_3d_set.insert(p_listener);
+ return audio_listener_3d_set.size() == 1;
}
-void Viewport::_listener_3d_remove(Listener3D *p_listener) {
- listener_3d_set.erase(p_listener);
- if (listener_3d == p_listener) {
- listener_3d = nullptr;
+void Viewport::_audio_listener_3d_remove(AudioListener3D *p_listener) {
+ audio_listener_3d_set.erase(p_listener);
+ if (audio_listener_3d == p_listener) {
+ audio_listener_3d = nullptr;
}
}
-void Viewport::_listener_3d_make_next_current(Listener3D *p_exclude) {
- if (listener_3d_set.size() > 0) {
- for (Set<Listener3D *>::Element *E = listener_3d_set.front(); E; E = E->next()) {
+void Viewport::_audio_listener_3d_make_next_current(AudioListener3D *p_exclude) {
+ if (audio_listener_3d_set.size() > 0) {
+ for (Set<AudioListener3D *>::Element *E = audio_listener_3d_set.front(); E; E = E->next()) {
if (p_exclude == E->get()) {
continue;
}
if (!E->get()->is_inside_tree()) {
continue;
}
- if (listener_3d != nullptr) {
+ if (audio_listener_3d != nullptr) {
return;
}
E->get()->make_current();
}
} else {
- // Attempt to reset listener to the camera position
+ // Attempt to reset listener to the camera position.
if (camera_3d != nullptr) {
- _update_listener_3d();
+ _update_audio_listener_3d();
_camera_3d_transform_changed_notify();
}
}
@@ -3133,11 +3131,11 @@ void Viewport::_collision_object_3d_input_event(CollisionObject3D *p_object, Cam
Transform3D camera_transform = p_camera->get_global_transform();
ObjectID id = p_object->get_instance_id();
- //avoid sending the fake event unnecessarily if nothing really changed in the context
+ // Avoid sending the fake event unnecessarily if nothing really changed in the context.
if (object_transform == physics_last_object_transform && camera_transform == physics_last_camera_transform && physics_last_id == id) {
Ref<InputEventMouseMotion> mm = p_input_event;
if (mm.is_valid() && mm->get_device() == InputEvent::DEVICE_ID_INTERNAL) {
- return; //discarded
+ return; // Discarded.
}
}
p_object->_input_event_call(camera_3d, p_input_event, p_pos, p_normal, p_shape);
@@ -3176,7 +3174,7 @@ void Viewport::_camera_3d_set(Camera3D *p_camera) {
camera_3d->notification(Camera3D::NOTIFICATION_BECAME_CURRENT);
}
- _update_listener_3d();
+ _update_audio_listener_3d();
_camera_3d_transform_changed_notify();
}
@@ -3338,7 +3336,7 @@ void Viewport::set_world_3d(const Ref<World3D> &p_world_3d) {
RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario());
}
- _update_listener_3d();
+ _update_audio_listener_3d();
}
void Viewport::_own_world_3d_changed() {
@@ -3359,7 +3357,7 @@ void Viewport::_own_world_3d_changed() {
RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario());
}
- _update_listener_3d();
+ _update_audio_listener_3d();
}
void Viewport::set_use_own_world_3d(bool p_world_3d) {
@@ -3393,7 +3391,7 @@ void Viewport::set_use_own_world_3d(bool p_world_3d) {
RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario());
}
- _update_listener_3d();
+ _update_audio_listener_3d();
}
bool Viewport::is_using_own_world_3d() const {
@@ -3456,13 +3454,16 @@ bool Viewport::is_using_xr() {
return use_xr;
}
-void Viewport::set_scale_3d(const Scale3D p_scale_3d) {
- scale_3d = p_scale_3d;
+void Viewport::set_scale_3d(float p_scale_3d) {
+ // Clamp to reasonable values that are actually useful.
+ // Values above 2.0 don't serve a practical purpose since the viewport
+ // isn't displayed with mipmaps.
+ scale_3d = CLAMP(p_scale_3d, 0.1, 2.0);
- RS::get_singleton()->viewport_set_scale_3d(viewport, RS::ViewportScale3D(scale_3d));
+ RS::get_singleton()->viewport_set_scale_3d(viewport, scale_3d);
}
-Viewport::Scale3D Viewport::get_scale_3d() const {
+float Viewport::get_scale_3d() const {
return scale_3d;
}
@@ -3595,7 +3596,7 @@ void Viewport::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_3d"), "set_disable_3d", "is_3d_disabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_xr"), "set_use_xr", "is_using_xr");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "scale_3d", PROPERTY_HINT_ENUM, String::utf8("Disabled,75%,50%,33%,25%")), "set_scale_3d", "get_scale_3d");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "scale_3d", PROPERTY_HINT_RANGE, "0.25,2.0,0.01"), "set_scale_3d", "get_scale_3d");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_listener_enable_3d"), "set_as_audio_listener_3d", "is_audio_listener_3d");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "own_world_3d"), "set_use_own_world_3d", "is_using_own_world_3d");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world_3d", PROPERTY_HINT_RESOURCE_TYPE, "World3D"), "set_world_3d", "get_world_3d");
@@ -3606,7 +3607,7 @@ void Viewport::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_2d_transforms_to_pixel"), "set_snap_2d_transforms_to_pixel", "is_snap_2d_transforms_to_pixel_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_2d_vertices_to_pixel"), "set_snap_2d_vertices_to_pixel", "is_snap_2d_vertices_to_pixel_enabled");
ADD_GROUP("Rendering", "");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, String::utf8("Disabled (Fastest),2× (Fast),4× (Average),8× (Slow),16× (Slower)")), "set_msaa", "get_msaa");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, String::utf8("Disabled (Fastest),2× (Average),4× (Slow),8× (Slowest)")), "set_msaa", "get_msaa");
ADD_PROPERTY(PropertyInfo(Variant::INT, "screen_space_aa", PROPERTY_HINT_ENUM, "Disabled (Fastest),FXAA (Fast)"), "set_screen_space_aa", "get_screen_space_aa");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_debanding"), "set_use_debanding", "is_using_debanding");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_occlusion_culling"), "set_use_occlusion_culling", "is_using_occlusion_culling");
@@ -3639,12 +3640,6 @@ void Viewport::_bind_methods() {
ADD_SIGNAL(MethodInfo("size_changed"));
ADD_SIGNAL(MethodInfo("gui_focus_changed", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Control")));
- BIND_ENUM_CONSTANT(SCALE_3D_DISABLED);
- BIND_ENUM_CONSTANT(SCALE_3D_75_PERCENT);
- BIND_ENUM_CONSTANT(SCALE_3D_50_PERCENT);
- BIND_ENUM_CONSTANT(SCALE_3D_33_PERCENT);
- BIND_ENUM_CONSTANT(SCALE_3D_25_PERCENT);
-
BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_DISABLED);
BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_1);
BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_4);
@@ -3658,7 +3653,6 @@ void Viewport::_bind_methods() {
BIND_ENUM_CONSTANT(MSAA_2X);
BIND_ENUM_CONSTANT(MSAA_4X);
BIND_ENUM_CONSTANT(MSAA_8X);
- BIND_ENUM_CONSTANT(MSAA_16X);
BIND_ENUM_CONSTANT(MSAA_MAX);
BIND_ENUM_CONSTANT(SCREEN_SPACE_AA_DISABLED);
@@ -3733,10 +3727,8 @@ Viewport::Viewport() {
viewport_textures.insert(default_texture.ptr());
default_texture->proxy = RS::get_singleton()->texture_proxy_create(texture_rid);
- //internal_listener_2d = SpatialSound2DServer::get_singleton()->listener_create();
- canvas_layers.insert(nullptr); // This eases picking code (interpreted as the canvas of the Viewport)
+ canvas_layers.insert(nullptr); // This eases picking code (interpreted as the canvas of the Viewport).
- //clear=true;
set_shadow_atlas_size(shadow_atlas_size);
for (int i = 0; i < 4; i++) {
@@ -3760,15 +3752,14 @@ Viewport::Viewport() {
ProjectSettings::get_singleton()->set_custom_property_info("gui/timers/tooltip_delay_sec", PropertyInfo(Variant::FLOAT, "gui/timers/tooltip_delay_sec", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater")); // No negative numbers
#ifndef _3D_DISABLED
- int scale = GLOBAL_GET("rendering/3d/viewport/scale");
- set_scale_3d((Scale3D)scale);
+ set_scale_3d(GLOBAL_GET("rendering/3d/viewport/scale"));
#endif // _3D_DISABLED
- set_sdf_oversize(sdf_oversize); //set to server
+ set_sdf_oversize(sdf_oversize); // Set to server.
}
Viewport::~Viewport() {
- //erase itself from viewport textures
+ // Erase itself from viewport textures.
for (Set<ViewportTexture *>::Element *E = viewport_textures.front(); E; E = E->next()) {
E->get()->vp = nullptr;
}
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index d9b21ce6a8..1f19ff04c9 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -37,10 +37,11 @@
#ifndef _3D_DISABLED
class Camera3D;
class CollisionObject3D;
-class Listener3D;
+class AudioListener3D;
class World3D;
#endif // _3D_DISABLED
+class AudioListener2D;
class Camera2D;
class CanvasItem;
class CanvasLayer;
@@ -88,14 +89,6 @@ class Viewport : public Node {
GDCLASS(Viewport, Node);
public:
- enum Scale3D {
- SCALE_3D_DISABLED,
- SCALE_3D_75_PERCENT,
- SCALE_3D_50_PERCENT,
- SCALE_3D_33_PERCENT,
- SCALE_3D_25_PERCENT
- };
-
enum ShadowAtlasQuadrantSubdiv {
SHADOW_ATLAS_QUADRANT_SUBDIV_DISABLED,
SHADOW_ATLAS_QUADRANT_SUBDIV_1,
@@ -112,7 +105,7 @@ public:
MSAA_2X,
MSAA_4X,
MSAA_8X,
- MSAA_16X,
+ // 16x MSAA is not supported due to its high cost and driver bugs.
MSAA_MAX
};
@@ -201,6 +194,7 @@ private:
Viewport *parent = nullptr;
+ AudioListener2D *audio_listener_2d = nullptr;
Camera2D *camera_2d = nullptr;
Set<CanvasLayer *> canvas_layers;
@@ -208,8 +202,8 @@ private:
RID current_canvas;
RID subwindow_canvas;
- bool audio_listener_2d = false;
- RID internal_listener_2d;
+ bool is_audio_listener_2d_enabled = false;
+ RID internal_audio_listener_2d;
bool override_canvas_transform = false;
@@ -272,7 +266,7 @@ private:
StringName unhandled_input_group;
StringName unhandled_key_input_group;
- void _update_listener_2d();
+ void _update_audio_listener_2d();
bool disable_3d = false;
@@ -416,6 +410,10 @@ private:
bool _gui_drop(Control *p_at_control, Point2 p_at_pos, bool p_just_check);
+ friend class AudioListener2D;
+ void _audio_listener_2d_set(AudioListener2D *p_listener);
+ void _audio_listener_2d_remove(AudioListener2D *p_listener);
+
friend class Camera2D;
void _camera_2d_set(Camera2D *p_camera_2d);
@@ -457,6 +455,7 @@ protected:
public:
uint64_t get_processed_events_count() const { return event_count; }
+ AudioListener2D *get_audio_listener_2d() const;
Camera2D *get_camera_2d() const;
void set_as_audio_listener_2d(bool p_enable);
bool is_audio_listener_2d() const;
@@ -585,21 +584,21 @@ public:
#ifndef _3D_DISABLED
bool use_xr = false;
- Scale3D scale_3d = SCALE_3D_DISABLED;
- friend class Listener3D;
- Listener3D *listener_3d = nullptr;
- Set<Listener3D *> listener_3d_set;
- bool audio_listener_3d = false;
- RID internal_listener_3d;
- Listener3D *get_listener_3d() const;
+ float scale_3d = 1.0;
+ friend class AudioListener3D;
+ AudioListener3D *audio_listener_3d = nullptr;
+ Set<AudioListener3D *> audio_listener_3d_set;
+ bool is_audio_listener_3d_enabled = false;
+ RID internal_audio_listener_3d;
+ AudioListener3D *get_audio_listener_3d() const;
void set_as_audio_listener_3d(bool p_enable);
bool is_audio_listener_3d() const;
- void _update_listener_3d();
+ void _update_audio_listener_3d();
void _listener_transform_3d_changed_notify();
- void _listener_3d_set(Listener3D *p_listener);
- bool _listener_3d_add(Listener3D *p_listener); //true if first
- void _listener_3d_remove(Listener3D *p_listener);
- void _listener_3d_make_next_current(Listener3D *p_exclude);
+ void _audio_listener_3d_set(AudioListener3D *p_listener);
+ bool _audio_listener_3d_add(AudioListener3D *p_listener); //true if first
+ void _audio_listener_3d_remove(AudioListener3D *p_listener);
+ void _audio_listener_3d_make_next_current(AudioListener3D *p_exclude);
void _collision_object_3d_input_event(CollisionObject3D *p_object, Camera3D *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape);
@@ -657,8 +656,8 @@ public:
void set_use_xr(bool p_use_xr);
bool is_using_xr();
- void set_scale_3d(const Scale3D p_scale_3d);
- Scale3D get_scale_3d() const;
+ void set_scale_3d(float p_scale_3d);
+ float get_scale_3d() const;
#endif // _3D_DISABLED
Viewport();
@@ -717,7 +716,6 @@ VARIANT_ENUM_CAST(SubViewport::UpdateMode);
VARIANT_ENUM_CAST(Viewport::ShadowAtlasQuadrantSubdiv);
VARIANT_ENUM_CAST(Viewport::MSAA);
VARIANT_ENUM_CAST(Viewport::ScreenSpaceAA);
-VARIANT_ENUM_CAST(Viewport::Scale3D);
VARIANT_ENUM_CAST(Viewport::DebugDraw);
VARIANT_ENUM_CAST(Viewport::SDFScale);
VARIANT_ENUM_CAST(Viewport::SDFOversize);
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index 1fcfce2ea9..a0f62c853f 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -1266,6 +1266,18 @@ bool Window::has_theme_constant(const StringName &p_name, const StringName &p_th
return Control::has_theme_item_in_types(theme_owner, theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types);
}
+float Window::get_theme_default_base_scale() const {
+ return Control::fetch_theme_default_base_scale(theme_owner, theme_owner_window);
+}
+
+Ref<Font> Window::get_theme_default_font() const {
+ return Control::fetch_theme_default_font(theme_owner, theme_owner_window);
+}
+
+int Window::get_theme_default_font_size() const {
+ return Control::fetch_theme_default_font_size(theme_owner, theme_owner_window);
+}
+
Rect2i Window::get_parent_rect() const {
ERR_FAIL_COND_V(!is_inside_tree(), Rect2i());
if (is_embedded()) {
@@ -1480,6 +1492,10 @@ void Window::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_theme_color", "name", "theme_type"), &Window::has_theme_color, DEFVAL(""));
ClassDB::bind_method(D_METHOD("has_theme_constant", "name", "theme_type"), &Window::has_theme_constant, DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("get_theme_default_base_scale"), &Window::get_theme_default_base_scale);
+ ClassDB::bind_method(D_METHOD("get_theme_default_font"), &Window::get_theme_default_font);
+ ClassDB::bind_method(D_METHOD("get_theme_default_font_size"), &Window::get_theme_default_font_size);
+
ClassDB::bind_method(D_METHOD("set_layout_direction", "direction"), &Window::set_layout_direction);
ClassDB::bind_method(D_METHOD("get_layout_direction"), &Window::get_layout_direction);
ClassDB::bind_method(D_METHOD("is_layout_rtl"), &Window::is_layout_rtl);
@@ -1497,7 +1513,7 @@ void Window::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "position"), "set_position", "get_position");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "size"), "set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Windowed,Minimized,Maximized,Fullscreen"), "set_mode", "get_mode");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_screen"), "set_current_screen", "get_current_screen");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "current_screen"), "set_current_screen", "get_current_screen");
ADD_GROUP("Flags", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible");
diff --git a/scene/main/window.h b/scene/main/window.h
index 4f31d9cd1f..def6eab7b8 100644
--- a/scene/main/window.h
+++ b/scene/main/window.h
@@ -280,6 +280,10 @@ public:
bool has_theme_color(const StringName &p_name, const StringName &p_theme_type = StringName()) const;
bool has_theme_constant(const StringName &p_name, const StringName &p_theme_type = StringName()) const;
+ float get_theme_default_base_scale() const;
+ Ref<Font> get_theme_default_font() const;
+ int get_theme_default_font_size() const;
+
Rect2i get_parent_rect() const;
virtual DisplayServer::WindowID get_window_id() const override;