summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitattributes1
-rw-r--r--.gitignore6
-rw-r--r--SConstruct2
-rw-r--r--core/SCsub3
-rw-r--r--core/core_builders.py35
-rw-r--r--core/input_map.cpp4
-rw-r--r--core/io/http_client.cpp4
-rw-r--r--core/io/multiplayer_api.cpp23
-rw-r--r--core/io/multiplayer_api.h9
-rw-r--r--core/io/stream_peer_ssl.cpp57
-rw-r--r--core/io/stream_peer_ssl.h5
-rw-r--r--core/os/input_event.cpp16
-rw-r--r--core/os/input_event.h2
-rw-r--r--doc/classes/CanvasItem.xml2
-rw-r--r--doc/classes/Input.xml4
-rw-r--r--doc/classes/MultiplayerAPI.xml29
-rw-r--r--doc/classes/Node.xml6
-rw-r--r--doc/classes/ProjectSettings.xml4
-rw-r--r--doc/classes/SceneTree.xml2
-rw-r--r--doc/classes/ShaderMaterial.xml16
-rw-r--r--doc/classes/Viewport.xml7
-rw-r--r--doc/classes/VisualServer.xml10
-rw-r--r--editor/SCsub4
-rw-r--r--editor/editor_about.cpp1
-rw-r--r--editor/editor_builders.py26
-rw-r--r--editor/editor_initialize_ssl.cpp48
-rw-r--r--editor/editor_initialize_ssl.h36
-rw-r--r--editor/editor_node.cpp9
-rw-r--r--editor/editor_plugin_settings.cpp2
-rw-r--r--editor/editor_settings.cpp5
-rw-r--r--editor/inspector_dock.cpp2
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp18
-rw-r--r--editor/plugins/script_editor_plugin.cpp3
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp13
-rw-r--r--editor/project_manager.cpp3
-rw-r--r--editor/project_settings_editor.cpp4
-rw-r--r--editor/property_editor.cpp153
-rw-r--r--editor/property_editor.h3
-rw-r--r--editor/scene_tree_dock.cpp21
-rw-r--r--editor/script_create_dialog.cpp2
-rw-r--r--editor/settings_config_dialog.cpp6
-rw-r--r--main/main.cpp30
-rw-r--r--methods.py3
-rw-r--r--modules/bullet/godot_result_callbacks.cpp8
-rw-r--r--modules/gdnative/include/nativescript/godot_nativescript.h7
-rw-r--r--modules/gdnative/nativescript/nativescript.cpp22
-rw-r--r--modules/gdscript/gdscript.cpp8
-rw-r--r--modules/gdscript/gdscript.h1
-rw-r--r--modules/gdscript/gdscript_editor.cpp4
-rw-r--r--modules/gdscript/gdscript_parser.cpp18
-rw-r--r--modules/gdscript/gdscript_tokenizer.cpp10
-rw-r--r--modules/gdscript/gdscript_tokenizer.h3
-rwxr-xr-xmodules/mbedtls/stream_peer_mbed_tls.cpp8
-rw-r--r--modules/mono/csharp_script.cpp12
-rw-r--r--modules/mono/glue/Managed/Files/Attributes/RPCAttributes.cs5
-rw-r--r--modules/mono/glue/Managed/Files/Basis.cs32
-rw-r--r--modules/mono/glue/Managed/Files/Transform.cs19
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.cpp6
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.h3
-rw-r--r--modules/opensimplex/doc_classes/SimplexNoise.xml1
-rw-r--r--modules/visual_script/visual_script_nodes.cpp2
-rw-r--r--platform/javascript/os_javascript.cpp52
-rw-r--r--platform/javascript/os_javascript.h1
-rw-r--r--platform/osx/os_osx.mm6
-rw-r--r--platform/windows/SCsub1
-rw-r--r--platform/windows/godot.natvis129
-rw-r--r--platform/windows/os_windows.cpp6
-rw-r--r--platform/x11/os_x11.cpp5
-rw-r--r--scene/gui/rich_text_label.cpp5
-rw-r--r--scene/gui/scroll_bar.cpp152
-rw-r--r--scene/gui/scroll_bar.h27
-rw-r--r--scene/main/viewport.cpp2
72 files changed, 692 insertions, 502 deletions
diff --git a/.gitattributes b/.gitattributes
index 03c6f96f80..47ba2b45bb 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -9,3 +9,4 @@ drivers/* linguist-vendored
*.py eol=lf
*.hpp eol=lf
*.xml eol=lf
+*.natvis eol=lf
diff --git a/.gitignore b/.gitignore
index 6db75f2324..52937b8679 100644
--- a/.gitignore
+++ b/.gitignore
@@ -91,6 +91,9 @@ bld/
*.debug
*.dSYM
+# Visual Studio cache/options directory
+.vs/
+
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
@@ -98,9 +101,6 @@ bld/
# Hints for improving IntelliSense, created together with VS project
cpp.hint
-# Visualizers for the VS debugger
-*.natvis
-
#NUNIT
*.VisualState.xml
TestResult.xml
diff --git a/SConstruct b/SConstruct
index 3f3976555d..1c55e0be93 100644
--- a/SConstruct
+++ b/SConstruct
@@ -169,9 +169,11 @@ opts.Add(BoolVariable('progress', "Show a progress indicator during compilation"
opts.Add(BoolVariable('dev', "If yes, alias for verbose=yes warnings=all", False))
opts.Add(EnumVariable('macports_clang', "Build using Clang from MacPorts", 'no', ('no', '5.0', 'devel')))
opts.Add(BoolVariable('no_editor_splash', "Don't use the custom splash screen for the editor", False))
+opts.Add('system_certs_path', "Use this path as SSL certificates default for editor (for package maintainers)", '')
# Thirdparty libraries
opts.Add(BoolVariable('builtin_bullet', "Use the built-in Bullet library", True))
+opts.Add(BoolVariable('builtin_certs', "Bundle default SSL certificates to be used if you don't specify an override in the project settings", True))
opts.Add(BoolVariable('builtin_enet', "Use the built-in ENet library", True))
opts.Add(BoolVariable('builtin_freetype', "Use the built-in FreeType library", True))
opts.Add(BoolVariable('builtin_libogg', "Use the built-in libogg library", True))
diff --git a/core/SCsub b/core/SCsub
index a6365bf925..6746cc871a 100644
--- a/core/SCsub
+++ b/core/SCsub
@@ -93,6 +93,9 @@ if 'builtin_zstd' in env and env['builtin_zstd']:
# Godot's own sources
env.add_source_files(env.core_sources, "*.cpp")
+# Certificates
+env.Depends("#core/io/certs_compressed.gen.h", ["#thirdparty/certs/ca-certificates.crt", env.Value(env['builtin_certs']), env.Value(env['system_certs_path'])])
+env.CommandNoCache("#core/io/certs_compressed.gen.h", "#thirdparty/certs/ca-certificates.crt", run_in_subprocess(core_builders.make_certs_header))
# Make binders
env.CommandNoCache(['method_bind.gen.inc', 'method_bind_ext.gen.inc'], 'make_binders.py', run_in_subprocess(make_binders.run))
diff --git a/core/core_builders.py b/core/core_builders.py
index 90e505aab9..f3a9e3b221 100644
--- a/core/core_builders.py
+++ b/core/core_builders.py
@@ -4,7 +4,40 @@ All such functions are invoked in a subprocess on Windows to prevent build flaki
"""
from platform_methods import subprocess_main
-from compat import iteritems, itervalues, open_utf8, escape_string
+from compat import iteritems, itervalues, open_utf8, escape_string, byte_to_str
+
+
+def make_certs_header(target, source, env):
+
+ src = source[0]
+ dst = target[0]
+ f = open(src, "rb")
+ g = open_utf8(dst, "w")
+ buf = f.read()
+ decomp_size = len(buf)
+ import zlib
+ buf = zlib.compress(buf)
+
+ g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ g.write("#ifndef _CERTS_RAW_H\n")
+ g.write("#define _CERTS_RAW_H\n")
+
+ # System certs path. Editor will use them if defined. (for package maintainers)
+ path = env['system_certs_path']
+ g.write("#define _SYSTEM_CERTS_PATH \"%s\"\n" % str(path))
+ if env['builtin_certs']:
+ # Defined here and not in env so changing it does not trigger a full rebuild.
+ g.write("#define BUILTIN_CERTS_ENABLED\n")
+ g.write("static const int _certs_compressed_size = " + str(len(buf)) + ";\n")
+ g.write("static const int _certs_uncompressed_size = " + str(decomp_size) + ";\n")
+ g.write("static const unsigned char _certs_compressed[] = {\n")
+ for i in range(len(buf)):
+ g.write("\t" + byte_to_str(buf[i]) + ",\n")
+ g.write("};\n")
+ g.write("#endif")
+
+ g.close()
+ f.close()
def make_authors_header(target, source, env):
diff --git a/core/input_map.cpp b/core/input_map.cpp
index 51e3f311a9..b88d99470a 100644
--- a/core/input_map.cpp
+++ b/core/input_map.cpp
@@ -199,6 +199,10 @@ bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const Str
Ref<InputEventAction> input_event_action = p_event;
if (input_event_action.is_valid()) {
+ if (p_pressed != NULL)
+ *p_pressed = input_event_action->is_pressed();
+ if (p_strength != NULL)
+ *p_strength = (*p_pressed) ? 1.0f : 0.0f;
return input_event_action->get_action() == p_action;
}
diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp
index de0b6860f9..80a281a21d 100644
--- a/core/io/http_client.cpp
+++ b/core/io/http_client.cpp
@@ -668,11 +668,11 @@ Error HTTPClient::_get_http_data(uint8_t *p_buffer, int p_bytes, int &r_received
// We can't use StreamPeer.get_data, since when reaching EOF we will get an
// error without knowing how many bytes we received.
Error err = ERR_FILE_EOF;
- int read;
+ int read = 0;
int left = p_bytes;
r_received = 0;
while (left > 0) {
- err = connection->get_partial_data(p_buffer, left, read);
+ err = connection->get_partial_data(p_buffer + r_received, left, read);
if (err == OK) {
r_received += read;
} else if (err == ERR_FILE_EOF) {
diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp
index 1179b1bfd6..5503b8d59c 100644
--- a/core/io/multiplayer_api.cpp
+++ b/core/io/multiplayer_api.cpp
@@ -45,8 +45,7 @@ _FORCE_INLINE_ bool _should_call_local(MultiplayerAPI::RPCMode mode, bool is_mas
} break;
case MultiplayerAPI::RPC_MODE_REMOTESYNC:
case MultiplayerAPI::RPC_MODE_MASTERSYNC:
- case MultiplayerAPI::RPC_MODE_SLAVESYNC:
- case MultiplayerAPI::RPC_MODE_SYNC: {
+ case MultiplayerAPI::RPC_MODE_PUPPETSYNC: {
//call it, sync always results in call
return true;
} break;
@@ -55,7 +54,7 @@ _FORCE_INLINE_ bool _should_call_local(MultiplayerAPI::RPCMode mode, bool is_mas
r_skip_rpc = true; //no other master so..
return is_master;
} break;
- case MultiplayerAPI::RPC_MODE_SLAVE: {
+ case MultiplayerAPI::RPC_MODE_PUPPET: {
return !is_master;
} break;
}
@@ -68,19 +67,16 @@ _FORCE_INLINE_ bool _can_call_mode(Node *p_node, MultiplayerAPI::RPCMode mode, i
case MultiplayerAPI::RPC_MODE_DISABLED: {
return false;
} break;
- case MultiplayerAPI::RPC_MODE_REMOTE: {
- return true;
- } break;
- case MultiplayerAPI::RPC_MODE_REMOTESYNC:
- case MultiplayerAPI::RPC_MODE_SYNC: {
+ case MultiplayerAPI::RPC_MODE_REMOTE:
+ case MultiplayerAPI::RPC_MODE_REMOTESYNC: {
return true;
} break;
case MultiplayerAPI::RPC_MODE_MASTERSYNC:
case MultiplayerAPI::RPC_MODE_MASTER: {
return p_node->is_network_master();
} break;
- case MultiplayerAPI::RPC_MODE_SLAVESYNC:
- case MultiplayerAPI::RPC_MODE_SLAVE: {
+ case MultiplayerAPI::RPC_MODE_PUPPETSYNC:
+ case MultiplayerAPI::RPC_MODE_PUPPET: {
return !p_node->is_network_master() && p_remote_id == p_node->get_network_master();
} break;
}
@@ -804,12 +800,13 @@ void MultiplayerAPI::_bind_methods() {
BIND_ENUM_CONSTANT(RPC_MODE_DISABLED);
BIND_ENUM_CONSTANT(RPC_MODE_REMOTE);
- BIND_ENUM_CONSTANT(RPC_MODE_SYNC);
BIND_ENUM_CONSTANT(RPC_MODE_MASTER);
- BIND_ENUM_CONSTANT(RPC_MODE_SLAVE);
+ BIND_ENUM_CONSTANT(RPC_MODE_PUPPET);
+ BIND_ENUM_CONSTANT(RPC_MODE_SLAVE); // deprecated
BIND_ENUM_CONSTANT(RPC_MODE_REMOTESYNC);
+ BIND_ENUM_CONSTANT(RPC_MODE_SYNC); // deprecated
BIND_ENUM_CONSTANT(RPC_MODE_MASTERSYNC);
- BIND_ENUM_CONSTANT(RPC_MODE_SLAVESYNC);
+ BIND_ENUM_CONSTANT(RPC_MODE_PUPPETSYNC);
}
MultiplayerAPI::MultiplayerAPI() {
diff --git a/core/io/multiplayer_api.h b/core/io/multiplayer_api.h
index e47b1830e8..c86e76e91a 100644
--- a/core/io/multiplayer_api.h
+++ b/core/io/multiplayer_api.h
@@ -91,12 +91,13 @@ public:
RPC_MODE_DISABLED, // No rpc for this method, calls to this will be blocked (default)
RPC_MODE_REMOTE, // Using rpc() on it will call method / set property in all remote peers
- RPC_MODE_SYNC, // Using rpc() on it will call method / set property in all remote peers and locally
RPC_MODE_MASTER, // Using rpc() on it will call method on wherever the master is, be it local or remote
- RPC_MODE_SLAVE, // Using rpc() on it will call method for all slaves
- RPC_MODE_REMOTESYNC, // Same as RPC_MODE_SYNC, compatibility
+ RPC_MODE_PUPPET, // Using rpc() on it will call method for all puppets
+ RPC_MODE_SLAVE = RPC_MODE_PUPPET, // Deprecated, same as puppet
+ RPC_MODE_REMOTESYNC, // Using rpc() on it will call method / set property in all remote peers and locally
+ RPC_MODE_SYNC = RPC_MODE_REMOTESYNC, // Deprecated. Same as RPC_MODE_REMOTESYNC
RPC_MODE_MASTERSYNC, // Using rpc() on it will call method / set property in the master peer and locally
- RPC_MODE_SLAVESYNC, // Using rpc() on it will call method / set property in all slave peers and locally
+ RPC_MODE_PUPPETSYNC, // Using rpc() on it will call method / set property in all puppets peers and locally
};
void poll();
diff --git a/core/io/stream_peer_ssl.cpp b/core/io/stream_peer_ssl.cpp
index 1f59021938..8d8682686a 100644
--- a/core/io/stream_peer_ssl.cpp
+++ b/core/io/stream_peer_ssl.cpp
@@ -30,6 +30,8 @@
#include "stream_peer_ssl.h"
+#include "core/io/certs_compressed.gen.h"
+#include "core/io/compression.h"
#include "core/os/file_access.h"
#include "core/project_settings.h"
@@ -42,13 +44,20 @@ StreamPeerSSL *StreamPeerSSL::create() {
StreamPeerSSL::LoadCertsFromMemory StreamPeerSSL::load_certs_func = NULL;
bool StreamPeerSSL::available = false;
-bool StreamPeerSSL::initialize_certs = true;
void StreamPeerSSL::load_certs_from_memory(const PoolByteArray &p_memory) {
if (load_certs_func)
load_certs_func(p_memory);
}
+void StreamPeerSSL::load_certs_from_file(String p_path) {
+ if (p_path != "") {
+ PoolByteArray certs = get_cert_file_as_array(p_path);
+ if (certs.size() > 0)
+ load_certs_func(certs);
+ }
+}
+
bool StreamPeerSSL::is_available() {
return available;
}
@@ -61,6 +70,25 @@ bool StreamPeerSSL::is_blocking_handshake_enabled() const {
return blocking_handshake;
}
+PoolByteArray StreamPeerSSL::get_cert_file_as_array(String p_path) {
+
+ PoolByteArray out;
+ FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
+ if (f) {
+ int flen = f->get_len();
+ out.resize(flen + 1);
+ PoolByteArray::Write w = out.write();
+ f->get_buffer(w.ptr(), flen);
+ w[flen] = 0; // Make sure it ends with string terminator
+ memdelete(f);
+#ifdef DEBUG_ENABLED
+ print_verbose(vformat("Loaded certs from '%s'.", p_path));
+#endif
+ }
+
+ return out;
+}
+
PoolByteArray StreamPeerSSL::get_project_cert_array() {
PoolByteArray out;
@@ -68,24 +96,21 @@ PoolByteArray StreamPeerSSL::get_project_cert_array() {
ProjectSettings::get_singleton()->set_custom_property_info("network/ssl/certificates", PropertyInfo(Variant::STRING, "network/ssl/certificates", PROPERTY_HINT_FILE, "*.crt"));
if (certs_path != "") {
-
- FileAccess *f = FileAccess::open(certs_path, FileAccess::READ);
- if (f) {
- int flen = f->get_len();
- out.resize(flen + 1);
- {
- PoolByteArray::Write w = out.write();
- f->get_buffer(w.ptr(), flen);
- w[flen] = 0; //end f string
- }
-
- memdelete(f);
-
+ // Use certs defined in project settings.
+ return get_cert_file_as_array(certs_path);
+ }
+#ifdef BUILTIN_CERTS_ENABLED
+ else {
+ // Use builtin certs only if user did not override it in project settings.
+ out.resize(_certs_uncompressed_size + 1);
+ PoolByteArray::Write w = out.write();
+ Compression::decompress(w.ptr(), _certs_uncompressed_size, _certs_compressed, _certs_compressed_size, Compression::MODE_DEFLATE);
+ w[_certs_uncompressed_size] = 0; // Make sure it ends with string terminator
#ifdef DEBUG_ENABLED
- print_verbose(vformat("Loaded certs from '%s'.", certs_path));
+ print_verbose("Loaded builtin certs");
#endif
- }
}
+#endif
return out;
}
diff --git a/core/io/stream_peer_ssl.h b/core/io/stream_peer_ssl.h
index f66c1c7de9..8ce36d7e7d 100644
--- a/core/io/stream_peer_ssl.h
+++ b/core/io/stream_peer_ssl.h
@@ -46,9 +46,6 @@ protected:
static LoadCertsFromMemory load_certs_func;
static bool available;
- friend class Main;
- static bool initialize_certs;
-
bool blocking_handshake;
public:
@@ -72,7 +69,9 @@ public:
static StreamPeerSSL *create();
+ static PoolByteArray get_cert_file_as_array(String p_path);
static PoolByteArray get_project_cert_array();
+ static void load_certs_from_file(String p_path);
static void load_certs_from_memory(const PoolByteArray &p_memory);
static bool is_available();
diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp
index cc359ef2ac..5bbdd7efb2 100644
--- a/core/os/input_event.cpp
+++ b/core/os/input_event.cpp
@@ -962,6 +962,22 @@ bool InputEventAction::is_action(const StringName &p_action) const {
return action == p_action;
}
+bool InputEventAction::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const {
+
+ Ref<InputEventAction> act = p_event;
+ if (act.is_null())
+ return false;
+
+ bool match = action == act->action;
+ if (match) {
+ if (p_pressed != NULL)
+ *p_pressed = act->pressed;
+ if (p_strength != NULL)
+ *p_strength = (*p_pressed) ? 1.0f : 0.0f;
+ }
+ return match;
+}
+
String InputEventAction::as_text() const {
return "InputEventAction : action=" + action + ", pressed=(" + (pressed ? "true" : "false");
diff --git a/core/os/input_event.h b/core/os/input_event.h
index cb61e61e7c..789d19c5b2 100644
--- a/core/os/input_event.h
+++ b/core/os/input_event.h
@@ -481,6 +481,8 @@ public:
virtual bool is_action(const StringName &p_action) const;
+ virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const;
+
virtual bool shortcut_match(const Ref<InputEvent> &p_event) const;
virtual bool is_action_type() const { return true; }
virtual String as_text() const;
diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml
index 98404478f4..60f097f3f9 100644
--- a/doc/classes/CanvasItem.xml
+++ b/doc/classes/CanvasItem.xml
@@ -576,7 +576,7 @@
Disable blending mode. Colors including alpha are written as is. Only applicable for render targets with a transparent background. No lighting will be applied.
</constant>
<constant name="NOTIFICATION_TRANSFORM_CHANGED" value="29">
- Canvas item transform has changed. Only received if requested.
+ Canvas item transform has changed. Notification is only received if enabled by [method set_notify_transform] or [method set_notify_local_transform].
</constant>
<constant name="NOTIFICATION_DRAW" value="30">
CanvasItem is requested to draw.
diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml
index a0bb585583..d9929b3d31 100644
--- a/doc/classes/Input.xml
+++ b/doc/classes/Input.xml
@@ -293,7 +293,7 @@
<argument index="2" name="hotspot" type="Vector2" default="Vector2( 0, 0 )">
</argument>
<description>
- Set a custom mouse cursor image, which is only visible inside the game window. The hotspot can also be specified. Passing [code]null[/code] to the image parameter resets to the system cursor. See enum [code]CURSOR_*[/code] for the list of shapes.
+ Sets a custom mouse cursor image, which is only visible inside the game window. The hotspot can also be specified. Passing [code]null[/code] to the image parameter resets to the system cursor. See enum [code]CURSOR_*[/code] for the list of shapes.
[code]image[/code]'s size must be lower than 256x256.
[code]hotspot[/code] must be within [code]image[/code]'s size.
</description>
@@ -304,6 +304,8 @@
<argument index="0" name="shape" type="int" enum="Input.CursorShape" default="0">
</argument>
<description>
+ Sets the default cursor shape to be used in the viewport instead of [code]CURSOR_ARROW[/code].
+ Note that if you want to change the default cursor shape for [Control]'s nodes, use [member Control.mouse_default_cursor_shape] instead.
</description>
</method>
<method name="set_mouse_mode">
diff --git a/doc/classes/MultiplayerAPI.xml b/doc/classes/MultiplayerAPI.xml
index 10e7f1b172..d8d7d9acfc 100644
--- a/doc/classes/MultiplayerAPI.xml
+++ b/doc/classes/MultiplayerAPI.xml
@@ -90,7 +90,7 @@
</methods>
<members>
<member name="network_peer" type="NetworkedMultiplayerPeer" setter="set_network_peer" getter="get_network_peer">
- The peer object to handle the RPC system (effectively enabling networking when set). Depending on the peer itself, the MultiplayerAPI will become a network server (check with [method is_network_server]) and will set root node's network mode to master (see NETWORK_MODE_* constants in [Node]), or it will become a regular peer with root node set to slave. All child nodes are set to inherit the network mode by default. Handling of networking-related events (connection, disconnection, new clients) is done by connecting to MultiplayerAPI's signals.
+ The peer object to handle the RPC system (effectively enabling networking when set). Depending on the peer itself, the MultiplayerAPI will become a network server (check with [method is_network_server]) and will set root node's network mode to master (see NETWORK_MODE_* constants in [Node]), or it will become a regular peer with root node set to puppet. All child nodes are set to inherit the network mode by default. Handling of networking-related events (connection, disconnection, new clients) is done by connecting to MultiplayerAPI's signals.
</member>
<member name="refuse_new_network_connections" type="bool" setter="set_refuse_new_network_connections" getter="is_refusing_new_network_connections">
If [code]true[/code] the MultiplayerAPI's [member network_peer] refuses new incoming connections.
@@ -141,25 +141,28 @@
Used with [method Node.rpc_config] or [method Node.rset_config] to disable a method or property for all RPC calls, making it unavailable. Default for all methods.
</constant>
<constant name="RPC_MODE_REMOTE" value="1" enum="RPCMode">
- Used with [method Node.rpc_config] or [method Node.rset_config] to set a method to be called or a property to be changed only on the remote end, not locally. Analogous to the [code]remote[/code] keyword. Calls and property changes are accepted from all remote peers, no matter if they are node's master or slaves.
+ Used with [method Node.rpc_config] or [method Node.rset_config] to set a method to be called or a property to be changed only on the remote end, not locally. Analogous to the [code]remote[/code] keyword. Calls and property changes are accepted from all remote peers, no matter if they are node's master or puppets.
</constant>
- <constant name="RPC_MODE_SYNC" value="2" enum="RPCMode">
- Behave like [code]RPC_MODE_REMOTE[/code] but also make the call or property change locally. Analogous to the [code]sync[/code] keyword.
+ <constant name="RPC_MODE_MASTER" value="2" enum="RPCMode">
+ Used with [method Node.rpc_config] or [method Node.rset_config] to set a method to be called or a property to be changed only on the network master for this node. Analogous to the [code]master[/code] keyword. Only accepts calls or property changes from the node's network puppets, see [method Node.set_network_master].
</constant>
- <constant name="RPC_MODE_MASTER" value="3" enum="RPCMode">
- Used with [method Node.rpc_config] or [method Node.rset_config] to set a method to be called or a property to be changed only on the network master for this node. Analogous to the [code]master[/code] keyword. Only accepts calls or property changes from the node's network slaves, see [method Node.set_network_master].
+ <constant name="RPC_MODE_PUPPET" value="3" enum="RPCMode">
+ Used with [method Node.rpc_config] or [method Node.rset_config] to set a method to be called or a property to be changed only on puppets for this node. Analogous to the [code]puppet[/code] keyword. Only accepts calls or property changes from the node's network master, see [method Node.set_network_master].
</constant>
- <constant name="RPC_MODE_SLAVE" value="4" enum="RPCMode">
- Used with [method Node.rpc_config] or [method Node.rset_config] to set a method to be called or a property to be changed only on slaves for this node. Analogous to the [code]slave[/code] keyword. Only accepts calls or property changes from the node's network master, see [method Node.set_network_master].
+ <constant name="RPC_MODE_SLAVE" value="3" enum="RPCMode">
+ Deprecated. Use [code]RPC_MODE_PUPPET[/code] instead. Analogous to the [code]slave[/code] keyword.
</constant>
- <constant name="RPC_MODE_REMOTESYNC" value="5" enum="RPCMode">
- Behave like [code]RPC_MODE_REMOTE[/code] but also make the call or property change locally. Same as [code]RPC_MODE_SYNC[/code] which is only kept for compatibility. Analogous to the [code]remotesync[/code] keyword.
+ <constant name="RPC_MODE_REMOTESYNC" value="4" enum="RPCMode">
+ Behave like [code]RPC_MODE_REMOTE[/code] but also make the call or property change locally. Analogous to the [code]remotesync[/code] keyword.
</constant>
- <constant name="RPC_MODE_MASTERSYNC" value="6" enum="RPCMode">
+ <constant name="RPC_MODE_SYNC" value="4" enum="RPCMode">
+ Deprecated. Use [code]RPC_MODE_REMOTESYNC[/code] instead. Analogous to the [code]sync[/code] keyword.
+ </constant>
+ <constant name="RPC_MODE_MASTERSYNC" value="5" enum="RPCMode">
Behave like [code]RPC_MODE_MASTER[/code] but also make the call or property change locally. Analogous to the [code]mastersync[/code] keyword.
</constant>
- <constant name="RPC_MODE_SLAVESYNC" value="7" enum="RPCMode">
- Behave like [code]RPC_MODE_SLAVE[/code] but also make the call or property change locally. Analogous to the [code]slavesync[/code] keyword.
+ <constant name="RPC_MODE_PUPPETSYNC" value="6" enum="RPCMode">
+ Behave like [code]RPC_MODE_PUPPET[/code] but also make the call or property change locally. Analogous to the [code]puppetsync[/code] keyword.
</constant>
</constants>
</class>
diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml
index d8b8f1fb43..d00652d40c 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -582,7 +582,7 @@
<argument index="1" name="mode" type="int" enum="MultiplayerAPI.RPCMode">
</argument>
<description>
- Changes the RPC mode for the given [code]method[/code] to the given [code]mode[/code]. See [enum MultiplayerAPI.RPCMode]. An alternative is annotating methods and properties with the corresponding keywords ([code]remote[/code], [code]sync[/code], [code]master[/code], [code]slave[/code]). By default, methods are not exposed to networking (and RPCs). Also see [method rset] and [method rset_config] for properties.
+ Changes the RPC mode for the given [code]method[/code] to the given [code]mode[/code]. See [enum MultiplayerAPI.RPCMode]. An alternative is annotating methods and properties with the corresponding keywords ([code]remote[/code], [code]master[/code], [code]puppet[/code], [code]remotesync[/code], [code]mastersync[/code], [code]puppetsync[/code]). By default, methods are not exposed to networking (and RPCs). Also see [method rset] and [method rset_config] for properties.
</description>
</method>
<method name="rpc_id" qualifiers="vararg">
@@ -635,7 +635,7 @@
<argument index="1" name="mode" type="int" enum="MultiplayerAPI.RPCMode">
</argument>
<description>
- Changes the RPC mode for the given [code]property[/code] to the given [code]mode[/code]. See [enum MultiplayerAPI.RPCMode]. An alternative is annotating methods and properties with the corresponding keywords ([code]remote[/code], [code]sync[/code], [code]master[/code], [code]slave[/code]). By default, properties are not exposed to networking (and RPCs). Also see [method rpc] and [method rpc_config] for methods.
+ Changes the RPC mode for the given [code]property[/code] to the given [code]mode[/code]. See [enum MultiplayerAPI.RPCMode]. An alternative is annotating methods and properties with the corresponding keywords ([code]remote[/code], [code]master[/code], [code]puppet[/code], [code]remotesync[/code], [code]mastersync[/code], [code]puppetsync[/code]). By default, properties are not exposed to networking (and RPCs). Also see [method rpc] and [method rpc_config] for methods.
</description>
</method>
<method name="rset_id">
@@ -692,7 +692,7 @@
<argument index="1" name="recursive" type="bool" default="true">
</argument>
<description>
- Sets the node's network master to the peer with the given peer ID. The network master is the peer that has authority over the node on the network. Useful in conjunction with the [code]master[/code] and [code]slave[/code] keywords. Inherited from the parent node by default, which ultimately defaults to peer ID 1 (the server). If [code]recursive[/code], the given peer is recursively set as the master for all children of this node.
+ Sets the node's network master to the peer with the given peer ID. The network master is the peer that has authority over the node on the network. Useful in conjunction with the [code]master[/code] and [code]puppet[/code] keywords. Inherited from the parent node by default, which ultimately defaults to peer ID 1 (the server). If [code]recursive[/code], the given peer is recursively set as the master for all children of this node.
</description>
</method>
<method name="set_physics_process">
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index b0d1cf8619..548d60fe35 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -157,6 +157,8 @@
</method>
</methods>
<members>
+ <member name="application/boot_splash/bg_color" type="Color" setter="" getter="">
+ </member>
<member name="application/boot_splash/fullsize" type="bool" setter="" getter="">
Scale the boot splash image to the full window length when engine starts (will leave it as default pixel size otherwise).
</member>
@@ -226,6 +228,8 @@
</member>
<member name="debug/gdscript/warnings/constant_used_as_function" type="bool" setter="" getter="">
</member>
+ <member name="debug/gdscript/warnings/deprecated_keyword" type="bool" setter="" getter="">
+ </member>
<member name="debug/gdscript/warnings/enable" type="bool" setter="" getter="">
</member>
<member name="debug/gdscript/warnings/function_conflicts_constant" type="bool" setter="" getter="">
diff --git a/doc/classes/SceneTree.xml b/doc/classes/SceneTree.xml
index a447294fea..1985845552 100644
--- a/doc/classes/SceneTree.xml
+++ b/doc/classes/SceneTree.xml
@@ -274,7 +274,7 @@
When [code]false[/code] you need to manually call [method MultiplayerAPI.poll] for processing network packets and delivering RPCs/RSETs. This allows to run RPCs/RSETs in a different loop (e.g. physics, thread, specific time step) and for manual [Mutex] protection when accessing the [MultiplayerAPI] from threads.
</member>
<member name="network_peer" type="NetworkedMultiplayerPeer" setter="set_network_peer" getter="get_network_peer">
- The peer object to handle the RPC system (effectively enabling networking when set). Depending on the peer itself, the SceneTree will become a network server (check with [method is_network_server()]) and will set root node's network mode to master (see NETWORK_MODE_* constants in [Node]), or it will become a regular peer with root node set to slave. All child nodes are set to inherit the network mode by default. Handling of networking-related events (connection, disconnection, new clients) is done by connecting to SceneTree's signals.
+ The peer object to handle the RPC system (effectively enabling networking when set). Depending on the peer itself, the SceneTree will become a network server (check with [method is_network_server()]) and will set root node's network mode to master (see NETWORK_MODE_* constants in [Node]), or it will become a regular peer with root node set to puppet. All child nodes are set to inherit the network mode by default. Handling of networking-related events (connection, disconnection, new clients) is done by connecting to SceneTree's signals.
</member>
<member name="paused" type="bool" setter="set_pause" getter="is_paused">
If [code]true[/code] the SceneTree is paused.
diff --git a/doc/classes/ShaderMaterial.xml b/doc/classes/ShaderMaterial.xml
index 5abba9fba9..7491d22479 100644
--- a/doc/classes/ShaderMaterial.xml
+++ b/doc/classes/ShaderMaterial.xml
@@ -20,6 +20,22 @@
Returns the current value set for this material of a uniform in the shader.
</description>
</method>
+ <method name="property_can_revert">
+ <return type="bool">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="property_get_revert">
+ <return type="Variant">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_shader_param">
<return type="void">
</return>
diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml
index 2f5710da51..9cd501630e 100644
--- a/doc/classes/Viewport.xml
+++ b/doc/classes/Viewport.xml
@@ -46,6 +46,13 @@
Returns the total transform of the viewport.
</description>
</method>
+ <method name="get_modal_stack_top" qualifiers="const">
+ <return type="Control">
+ </return>
+ <description>
+ Returns the topmost modal in the stack.
+ </description>
+ </method>
<method name="get_mouse_position" qualifiers="const">
<return type="Vector2">
</return>
diff --git a/doc/classes/VisualServer.xml b/doc/classes/VisualServer.xml
index afada05bf7..58b3d33cdb 100644
--- a/doc/classes/VisualServer.xml
+++ b/doc/classes/VisualServer.xml
@@ -2185,6 +2185,16 @@
Returns the value of a certain material's parameter.
</description>
</method>
+ <method name="material_get_param_default" qualifiers="const">
+ <return type="Variant">
+ </return>
+ <argument index="0" name="material" type="RID">
+ </argument>
+ <argument index="1" name="parameter" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="material_get_shader" qualifiers="const">
<return type="RID">
</return>
diff --git a/editor/SCsub b/editor/SCsub
index 6a4b06a97a..82b982eef2 100644
--- a/editor/SCsub
+++ b/editor/SCsub
@@ -61,10 +61,6 @@ if env['tools']:
env.Depends("#editor/doc_data_compressed.gen.h", docs)
env.CommandNoCache("#editor/doc_data_compressed.gen.h", docs, run_in_subprocess(editor_builders.make_doc_header))
- # Certificates
- env.Depends("#editor/certs_compressed.gen.h", "#thirdparty/certs/ca-certificates.crt")
- env.CommandNoCache("#editor/certs_compressed.gen.h", "#thirdparty/certs/ca-certificates.crt", run_in_subprocess(editor_builders.make_certs_header))
-
import glob
path = env.Dir('.').abspath
diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp
index e4602f0f94..cdf0e4b829 100644
--- a/editor/editor_about.cpp
+++ b/editor/editor_about.cpp
@@ -113,7 +113,6 @@ ScrollContainer *EditorAbout::_populate_list(const String &p_name, const List<St
EditorAbout::EditorAbout() {
set_title(TTR("Thanks from the Godot community!"));
- get_ok()->set_text(TTR("OK"));
set_hide_on_ok(true);
set_resizable(true);
diff --git a/editor/editor_builders.py b/editor/editor_builders.py
index fa037980c2..9e9fe752b4 100644
--- a/editor/editor_builders.py
+++ b/editor/editor_builders.py
@@ -9,32 +9,6 @@ from platform_methods import subprocess_main
from compat import encode_utf8, byte_to_str, open_utf8, escape_string
-def make_certs_header(target, source, env):
-
- src = source[0]
- dst = target[0]
- f = open(src, "rb")
- g = open_utf8(dst, "w")
- buf = f.read()
- decomp_size = len(buf)
- import zlib
- buf = zlib.compress(buf)
-
- g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
- g.write("#ifndef _CERTS_RAW_H\n")
- g.write("#define _CERTS_RAW_H\n")
- g.write("static const int _certs_compressed_size = " + str(len(buf)) + ";\n")
- g.write("static const int _certs_uncompressed_size = " + str(decomp_size) + ";\n")
- g.write("static const unsigned char _certs_compressed[] = {\n")
- for i in range(len(buf)):
- g.write("\t" + byte_to_str(buf[i]) + ",\n")
- g.write("};\n")
- g.write("#endif")
-
- g.close()
- f.close()
-
-
def make_doc_header(target, source, env):
dst = target[0]
diff --git a/editor/editor_initialize_ssl.cpp b/editor/editor_initialize_ssl.cpp
deleted file mode 100644
index 9f7537cc9a..0000000000
--- a/editor/editor_initialize_ssl.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*************************************************************************/
-/* editor_initialize_ssl.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "editor_initialize_ssl.h"
-
-#include "certs_compressed.gen.h"
-#include "core/io/compression.h"
-#include "core/io/stream_peer_ssl.h"
-
-void editor_initialize_certificates() {
-
- PoolByteArray data;
- data.resize(_certs_uncompressed_size + 1);
- {
- PoolByteArray::Write w = data.write();
- Compression::decompress(w.ptr(), _certs_uncompressed_size, _certs_compressed, _certs_compressed_size, Compression::MODE_DEFLATE);
- w[_certs_uncompressed_size] = 0; //make sure it ends at zero
- }
-
- StreamPeerSSL::load_certs_from_memory(data);
-}
diff --git a/editor/editor_initialize_ssl.h b/editor/editor_initialize_ssl.h
deleted file mode 100644
index 71d16b8c53..0000000000
--- a/editor/editor_initialize_ssl.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*************************************************************************/
-/* editor_initialize_ssl.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef EDITOR_INITIALIZE_SSL_H
-#define EDITOR_INITIALIZE_SSL_H
-
-void editor_initialize_certificates();
-
-#endif // EDITOR_INITIALIZE_SSL_H
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index b28d639a7c..0ba1ef3b18 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -54,7 +54,6 @@
#include "editor/editor_audio_buses.h"
#include "editor/editor_file_system.h"
#include "editor/editor_help.h"
-#include "editor/editor_initialize_ssl.h"
#include "editor/editor_properties.h"
#include "editor/editor_settings.h"
#include "editor/editor_themes.h"
@@ -4686,7 +4685,6 @@ EditorNode::EditorNode() {
SceneState::set_disable_placeholders(true);
ResourceLoader::clear_translation_remaps(); //no remaps using during editor
ResourceLoader::clear_path_remaps();
- editor_initialize_certificates(); //for asset sharing
InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton());
@@ -5446,13 +5444,6 @@ EditorNode::EditorNode() {
video_driver_current = 0;
for (int i = 0; i < video_drivers.get_slice_count(","); i++) {
String driver = video_drivers.get_slice(",", i);
- Ref<Texture> icon = get_class_icon(driver, "");
- if (icon.is_valid()) {
- video_driver->add_icon_item(icon, "");
- } else {
- video_driver->add_item(driver);
- }
-
video_driver->add_item(driver);
video_driver->set_item_metadata(i, driver);
diff --git a/editor/editor_plugin_settings.cpp b/editor/editor_plugin_settings.cpp
index ef0b61e882..30027c0c34 100644
--- a/editor/editor_plugin_settings.cpp
+++ b/editor/editor_plugin_settings.cpp
@@ -117,7 +117,7 @@ void EditorPluginSettings::update_plugins() {
TreeItem *item = plugin_list->create_item(root);
item->set_text(0, name);
- item->set_tooltip(0, "Name: " + name + "\nPath: " + path + "\nMain Script: " + script);
+ item->set_tooltip(0, "Name: " + name + "\nPath: " + path + "\nMain Script: " + script + "\nDescription: " + description);
item->set_metadata(0, d);
item->set_text(1, version);
item->set_metadata(1, script);
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 5d3c6dd087..3e959731fc 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -30,6 +30,7 @@
#include "editor_settings.h"
+#include "core/io/certs_compressed.gen.h"
#include "core/io/compression.h"
#include "core/io/config_file.h"
#include "core/io/file_access_memory.h"
@@ -947,6 +948,10 @@ void EditorSettings::setup_network() {
_initial_set("network/debug/remote_port", port);
add_property_hint(PropertyInfo(Variant::INT, "network/debug/remote_port", PROPERTY_HINT_RANGE, "1,65535,1"));
+
+ // Editor SSL certificates override
+ _initial_set("network/ssl/editor_ssl_certificates", _SYSTEM_CERTS_PATH);
+ add_property_hint(PropertyInfo(Variant::STRING, "network/ssl/editor_ssl_certificates", PROPERTY_HINT_GLOBAL_FILE, "*.crt,*.pem"));
}
void EditorSettings::save() {
diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp
index 5ab764fb15..16cba1db77 100644
--- a/editor/inspector_dock.cpp
+++ b/editor/inspector_dock.cpp
@@ -158,7 +158,6 @@ void InspectorDock::_resource_file_selected(String p_file) {
RES res = ResourceLoader::load(p_file);
if (res.is_null()) {
- warning_dialog->get_ok()->set_text(TTR("OK"));
warning_dialog->set_text(TTR("Failed to load resource."));
return;
};
@@ -319,7 +318,6 @@ void InspectorDock::_transform_keyed(Object *sp, const String &p_sub, const Tran
}
void InspectorDock::_warning_pressed() {
- warning_dialog->get_ok()->set_text(TTR("Ok"));
warning_dialog->popup_centered_minsize();
}
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 48486a1cc2..79578989d5 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -4390,7 +4390,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
zoom_plus = memnew(ToolButton);
zoom_hb->add_child(zoom_plus);
zoom_plus->connect("pressed", this, "_button_zoom_plus");
- zoom_plus->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_plus", TTR("Zoom in"), KEY_MASK_CMD | KEY_PLUS));
+ zoom_plus->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_plus", TTR("Zoom in"), KEY_MASK_CMD | KEY_EQUAL)); // Usually direct access key for PLUS
zoom_plus->set_focus_mode(FOCUS_NONE);
updating_scroll = false;
@@ -4412,13 +4412,6 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
move_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/move_mode", TTR("Move Mode"), KEY_W));
move_button->set_tooltip(TTR("Move Mode"));
- scale_button = memnew(ToolButton);
- hb->add_child(scale_button);
- scale_button->set_toggle_mode(true);
- scale_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_SCALE));
- scale_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/scale_mode", TTR("Scale Mode"), KEY_S));
- scale_button->set_tooltip(TTR("Scale Mode"));
-
rotate_button = memnew(ToolButton);
hb->add_child(rotate_button);
rotate_button->set_toggle_mode(true);
@@ -4426,6 +4419,13 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
rotate_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/rotate_mode", TTR("Rotate Mode"), KEY_E));
rotate_button->set_tooltip(TTR("Rotate Mode"));
+ scale_button = memnew(ToolButton);
+ hb->add_child(scale_button);
+ scale_button->set_toggle_mode(true);
+ scale_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_SCALE));
+ scale_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/scale_mode", TTR("Scale Mode"), KEY_S));
+ scale_button->set_tooltip(TTR("Scale Mode"));
+
hb->add_child(memnew(VSeparator));
list_select_button = memnew(ToolButton);
@@ -4917,7 +4917,6 @@ void CanvasItemEditorViewport::_perform_drop_data() {
// Without root dropping multiple files is not allowed
if (!target_node && selected_files.size() > 1) {
- accept->get_ok()->set_text(TTR("Ok"));
accept->set_text(TTR("Cannot instantiate multiple nodes without root."));
accept->popup_centered_minsize();
return;
@@ -4979,7 +4978,6 @@ void CanvasItemEditorViewport::_perform_drop_data() {
files_str += error_files[i].get_file().get_basename() + ",";
}
files_str = files_str.substr(0, files_str.length() - 1);
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(vformat(TTR("Error instancing scene from %s"), files_str.c_str()));
accept->popup_centered_minsize();
}
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 9dd6a8e0ed..c8e7bfb74b 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -797,7 +797,7 @@ bool ScriptEditor::_test_script_times_on_disk(RES p_for_script) {
if (se) {
RES edited_res = se->get_edited_resource();
- if (edited_res.is_valid() && p_for_script != edited_res)
+ if (p_for_script.is_valid() && edited_res.is_valid() && p_for_script != edited_res)
continue;
if (edited_res->get_path() == "" || edited_res->get_path().find("local://") != -1 || edited_res->get_path().find("::") != -1)
@@ -3133,7 +3133,6 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
error_dialog = memnew(AcceptDialog);
add_child(error_dialog);
- error_dialog->get_ok()->set_text(TTR("OK"));
debugger = memnew(ScriptEditorDebugger(editor));
debugger->connect("goto_script_line", this, "_goto_script_line");
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index c2554acd49..6df026843a 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -3267,7 +3267,6 @@ void SpatialEditorViewport::_perform_drop_data() {
files_str += error_files[i].get_file().get_basename() + ",";
}
files_str = files_str.substr(0, files_str.length() - 1);
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(vformat(TTR("Error instancing scene from %s"), files_str.c_str()));
accept->popup_centered_minsize();
}
@@ -3348,7 +3347,6 @@ void SpatialEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p
if (root_node) {
list.push_back(root_node);
} else {
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("No parent to instance a child at."));
accept->popup_centered_minsize();
_remove_preview();
@@ -3356,7 +3354,6 @@ void SpatialEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p
}
}
if (list.size() != 1) {
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("This operation requires a single selected node."));
accept->popup_centered_minsize();
_remove_preview();
@@ -5286,6 +5283,8 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_button[TOOL_MODE_SELECT]->connect("pressed", this, "_menu_item_pressed", button_binds);
tool_button[TOOL_MODE_SELECT]->set_tooltip(TTR("Select Mode (Q)") + "\n" + keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate\nAlt+Drag: Move\nAlt+RMB: Depth list selection"));
+ hbc_menu->add_child(memnew(VSeparator));
+
tool_button[TOOL_MODE_MOVE] = memnew(ToolButton);
hbc_menu->add_child(tool_button[TOOL_MODE_MOVE]);
tool_button[TOOL_MODE_MOVE]->set_toggle_mode(true);
@@ -5310,6 +5309,8 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_button[TOOL_MODE_SCALE]->connect("pressed", this, "_menu_item_pressed", button_binds);
tool_button[TOOL_MODE_SCALE]->set_tooltip(TTR("Scale Mode (R)"));
+ hbc_menu->add_child(memnew(VSeparator));
+
tool_button[TOOL_MODE_LIST_SELECT] = memnew(ToolButton);
hbc_menu->add_child(tool_button[TOOL_MODE_LIST_SELECT]);
tool_button[TOOL_MODE_LIST_SELECT]->set_toggle_mode(true);
@@ -5330,8 +5331,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_button[TOOL_UNLOCK_SELECTED]->connect("pressed", this, "_menu_item_pressed", button_binds);
tool_button[TOOL_UNLOCK_SELECTED]->set_tooltip(TTR("Unlock the selected object (can be moved)."));
- VSeparator *vs = memnew(VSeparator);
- hbc_menu->add_child(vs);
+ hbc_menu->add_child(memnew(VSeparator));
tool_option_button[TOOL_OPT_LOCAL_COORDS] = memnew(ToolButton);
hbc_menu->add_child(tool_option_button[TOOL_OPT_LOCAL_COORDS]);
@@ -5353,8 +5353,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
sct = ED_GET_SHORTCUT("spatial_editor/snap").ptr()->get_as_text();
tool_option_button[TOOL_OPT_USE_SNAP]->set_tooltip(vformat(TTR("Snap Mode (%s)"), sct));
- vs = memnew(VSeparator);
- hbc_menu->add_child(vs);
+ hbc_menu->add_child(memnew(VSeparator));
// Drag and drop support;
preview_node = memnew(Spatial);
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index f494c84efa..91ab5b4dff 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -41,7 +41,6 @@
#include "core/translation.h"
#include "core/version.h"
#include "core/version_hash.gen.h"
-#include "editor_initialize_ssl.h"
#include "editor_scale.h"
#include "editor_settings.h"
#include "editor_themes.h"
@@ -2059,8 +2058,6 @@ void ProjectListFilter::_bind_methods() {
ProjectListFilter::ProjectListFilter() {
- editor_initialize_certificates(); //for asset sharing
-
_current_filter = FILTER_NAME;
filter_option = memnew(OptionButton);
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index 1baf606e7b..7a68646f40 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -1840,9 +1840,9 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
input_editor->set_column_title(0, TTR("Action"));
input_editor->set_column_title(1, TTR("Deadzone"));
input_editor->set_column_expand(1, false);
- input_editor->set_column_min_width(1, 80);
+ input_editor->set_column_min_width(1, 80 * EDSCALE);
input_editor->set_column_expand(2, false);
- input_editor->set_column_min_width(2, 50);
+ input_editor->set_column_min_width(2, 50 * EDSCALE);
input_editor->connect("item_edited", this, "_action_edited");
input_editor->connect("item_activated", this, "_action_activated");
input_editor->connect("cell_selected", this, "_action_selected");
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index 1c2eedfc9c..508db2e03f 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -34,6 +34,7 @@
#include "core/io/image_loader.h"
#include "core/io/marshalls.h"
#include "core/io/resource_loader.h"
+#include "core/math/expression.h"
#include "core/os/input.h"
#include "core/os/keyboard.h"
#include "core/pair.h"
@@ -1531,21 +1532,24 @@ void CustomPropertyEditor::_modified(String p_string) {
updating = true;
switch (type) {
case Variant::INT: {
-
- if (evaluator)
- v = evaluator->eval(value_editor[0]->get_text());
- else
+ String text = value_editor[0]->get_text();
+ Ref<Expression> expr;
+ expr.instance();
+ Error err = expr->parse(text);
+ if (err != OK) {
v = value_editor[0]->get_text().to_int();
+ return;
+ } else {
+ v = expr->execute(Array(), NULL, false);
+ }
emit_signal("variant_changed");
} break;
case Variant::REAL: {
if (hint != PROPERTY_HINT_EXP_EASING) {
- if (evaluator)
- v = evaluator->eval(value_editor[0]->get_text());
- else
- v = value_editor[0]->get_text().to_double();
+ String text = value_editor[0]->get_text();
+ v = _parse_real_expression(text);
emit_signal("variant_changed");
}
@@ -1558,13 +1562,8 @@ void CustomPropertyEditor::_modified(String p_string) {
case Variant::VECTOR2: {
Vector2 vec;
- if (evaluator) {
- vec.x = evaluator->eval(value_editor[0]->get_text());
- vec.y = evaluator->eval(value_editor[1]->get_text());
- } else {
- vec.x = value_editor[0]->get_text().to_double();
- vec.y = value_editor[1]->get_text().to_double();
- }
+ vec.x = _parse_real_expression(value_editor[0]->get_text());
+ vec.y = _parse_real_expression(value_editor[1]->get_text());
v = vec;
_emit_changed_whole_or_field();
@@ -1572,17 +1571,11 @@ void CustomPropertyEditor::_modified(String p_string) {
case Variant::RECT2: {
Rect2 r2;
- if (evaluator) {
- r2.position.x = evaluator->eval(value_editor[0]->get_text());
- r2.position.y = evaluator->eval(value_editor[1]->get_text());
- r2.size.x = evaluator->eval(value_editor[2]->get_text());
- r2.size.y = evaluator->eval(value_editor[3]->get_text());
- } else {
- r2.position.x = value_editor[0]->get_text().to_double();
- r2.position.y = value_editor[1]->get_text().to_double();
- r2.size.x = value_editor[2]->get_text().to_double();
- r2.size.y = value_editor[3]->get_text().to_double();
- }
+
+ r2.position.x = _parse_real_expression(value_editor[0]->get_text());
+ r2.position.y = _parse_real_expression(value_editor[1]->get_text());
+ r2.size.x = _parse_real_expression(value_editor[2]->get_text());
+ r2.size.y = _parse_real_expression(value_editor[3]->get_text());
v = r2;
_emit_changed_whole_or_field();
@@ -1591,15 +1584,9 @@ void CustomPropertyEditor::_modified(String p_string) {
case Variant::VECTOR3: {
Vector3 vec;
- if (evaluator) {
- vec.x = evaluator->eval(value_editor[0]->get_text());
- vec.y = evaluator->eval(value_editor[1]->get_text());
- vec.z = evaluator->eval(value_editor[2]->get_text());
- } else {
- vec.x = value_editor[0]->get_text().to_double();
- vec.y = value_editor[1]->get_text().to_double();
- vec.z = value_editor[2]->get_text().to_double();
- }
+ vec.x = _parse_real_expression(value_editor[0]->get_text());
+ vec.y = _parse_real_expression(value_editor[1]->get_text());
+ vec.z = _parse_real_expression(value_editor[2]->get_text());
v = vec;
_emit_changed_whole_or_field();
@@ -1607,17 +1594,10 @@ void CustomPropertyEditor::_modified(String p_string) {
case Variant::PLANE: {
Plane pl;
- if (evaluator) {
- pl.normal.x = evaluator->eval(value_editor[0]->get_text());
- pl.normal.y = evaluator->eval(value_editor[1]->get_text());
- pl.normal.z = evaluator->eval(value_editor[2]->get_text());
- pl.d = evaluator->eval(value_editor[3]->get_text());
- } else {
- pl.normal.x = value_editor[0]->get_text().to_double();
- pl.normal.y = value_editor[1]->get_text().to_double();
- pl.normal.z = value_editor[2]->get_text().to_double();
- pl.d = value_editor[3]->get_text().to_double();
- }
+ pl.normal.x = _parse_real_expression(value_editor[0]->get_text());
+ pl.normal.y = _parse_real_expression(value_editor[1]->get_text());
+ pl.normal.z = _parse_real_expression(value_editor[2]->get_text());
+ pl.d = _parse_real_expression(value_editor[3]->get_text());
v = pl;
_emit_changed_whole_or_field();
@@ -1625,17 +1605,10 @@ void CustomPropertyEditor::_modified(String p_string) {
case Variant::QUAT: {
Quat q;
- if (evaluator) {
- q.x = evaluator->eval(value_editor[0]->get_text());
- q.y = evaluator->eval(value_editor[1]->get_text());
- q.z = evaluator->eval(value_editor[2]->get_text());
- q.w = evaluator->eval(value_editor[3]->get_text());
- } else {
- q.x = value_editor[0]->get_text().to_double();
- q.y = value_editor[1]->get_text().to_double();
- q.z = value_editor[2]->get_text().to_double();
- q.w = value_editor[3]->get_text().to_double();
- }
+ q.x = _parse_real_expression(value_editor[0]->get_text());
+ q.y = _parse_real_expression(value_editor[1]->get_text());
+ q.z = _parse_real_expression(value_editor[2]->get_text());
+ q.w = _parse_real_expression(value_editor[3]->get_text());
v = q;
_emit_changed_whole_or_field();
@@ -1645,21 +1618,12 @@ void CustomPropertyEditor::_modified(String p_string) {
Vector3 pos;
Vector3 size;
- if (evaluator) {
- pos.x = evaluator->eval(value_editor[0]->get_text());
- pos.y = evaluator->eval(value_editor[1]->get_text());
- pos.z = evaluator->eval(value_editor[2]->get_text());
- size.x = evaluator->eval(value_editor[3]->get_text());
- size.y = evaluator->eval(value_editor[4]->get_text());
- size.z = evaluator->eval(value_editor[5]->get_text());
- } else {
- pos.x = value_editor[0]->get_text().to_double();
- pos.y = value_editor[1]->get_text().to_double();
- pos.z = value_editor[2]->get_text().to_double();
- size.x = value_editor[3]->get_text().to_double();
- size.y = value_editor[4]->get_text().to_double();
- size.z = value_editor[5]->get_text().to_double();
- }
+ pos.x = _parse_real_expression(value_editor[0]->get_text());
+ pos.y = _parse_real_expression(value_editor[1]->get_text());
+ pos.z = _parse_real_expression(value_editor[2]->get_text());
+ size.x = _parse_real_expression(value_editor[3]->get_text());
+ size.y = _parse_real_expression(value_editor[4]->get_text());
+ size.z = _parse_real_expression(value_editor[5]->get_text());
v = AABB(pos, size);
_emit_changed_whole_or_field();
@@ -1668,11 +1632,7 @@ void CustomPropertyEditor::_modified(String p_string) {
Transform2D m;
for (int i = 0; i < 6; i++) {
- if (evaluator) {
- m.elements[i / 2][i % 2] = evaluator->eval(value_editor[i]->get_text());
- } else {
- m.elements[i / 2][i % 2] = value_editor[i]->get_text().to_double();
- }
+ m.elements[i / 2][i % 2] = _parse_real_expression(value_editor[i]->get_text());
}
v = m;
@@ -1683,12 +1643,7 @@ void CustomPropertyEditor::_modified(String p_string) {
Basis m;
for (int i = 0; i < 9; i++) {
-
- if (evaluator) {
- m.elements[i / 3][i % 3] = evaluator->eval(value_editor[i]->get_text());
- } else {
- m.elements[i / 3][i % 3] = value_editor[i]->get_text().to_double();
- }
+ m.elements[i / 3][i % 3] = _parse_real_expression(value_editor[i]->get_text());
}
v = m;
@@ -1699,25 +1654,14 @@ void CustomPropertyEditor::_modified(String p_string) {
Basis basis;
for (int i = 0; i < 9; i++) {
-
- if (evaluator) {
- basis.elements[i / 3][i % 3] = evaluator->eval(value_editor[(i / 3) * 4 + i % 3]->get_text());
- } else {
- basis.elements[i / 3][i % 3] = value_editor[(i / 3) * 4 + i % 3]->get_text().to_double();
- }
+ basis.elements[i / 3][i % 3] = _parse_real_expression(value_editor[(i / 3) * 4 + i % 3]->get_text());
}
Vector3 origin;
- if (evaluator) {
- origin.x = evaluator->eval(value_editor[3]->get_text());
- origin.y = evaluator->eval(value_editor[7]->get_text());
- origin.z = evaluator->eval(value_editor[11]->get_text());
- } else {
- origin.x = value_editor[3]->get_text().to_double();
- origin.y = value_editor[7]->get_text().to_double();
- origin.z = value_editor[11]->get_text().to_double();
- }
+ origin.x = _parse_real_expression(value_editor[3]->get_text());
+ origin.y = _parse_real_expression(value_editor[7]->get_text());
+ origin.z = _parse_real_expression(value_editor[11]->get_text());
v = Transform(basis, origin);
_emit_changed_whole_or_field();
@@ -1759,6 +1703,19 @@ void CustomPropertyEditor::_modified(String p_string) {
updating = false;
}
+real_t CustomPropertyEditor::_parse_real_expression(String text) {
+ Ref<Expression> expr;
+ expr.instance();
+ Error err = expr->parse(text);
+ real_t out;
+ if (err != OK) {
+ out = value_editor[0]->get_text().to_double();
+ } else {
+ out = expr->execute(Array(), NULL, false);
+ }
+ return out;
+}
+
void CustomPropertyEditor::_emit_changed_whole_or_field() {
if (!Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
diff --git a/editor/property_editor.h b/editor/property_editor.h
index 7d7ab912ea..ee3a56d857 100644
--- a/editor/property_editor.h
+++ b/editor/property_editor.h
@@ -135,6 +135,9 @@ class CustomPropertyEditor : public Popup {
void _text_edit_changed();
void _file_selected(String p_file);
void _modified(String p_string);
+
+ real_t _parse_real_expression(String text);
+
void _range_modified(double p_value);
void _focus_enter();
void _focus_exit();
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index af6b998b28..8637417598 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -119,7 +119,6 @@ void SceneTreeDock::instance(const String &p_file) {
if (!edited_scene) {
current_option = -1;
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("No parent to instance a child at."));
accept->popup_centered_minsize();
return;
@@ -142,7 +141,6 @@ void SceneTreeDock::instance_scenes(const Vector<String> &p_files, Node *p_paren
if (!parent || !edited_scene) {
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("No parent to instance the scenes at."));
accept->popup_centered_minsize();
return;
@@ -164,7 +162,6 @@ void SceneTreeDock::_perform_instance_scenes(const Vector<String> &p_files, Node
Ref<PackedScene> sdata = ResourceLoader::load(p_files[i]);
if (!sdata.is_valid()) {
current_option = -1;
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(vformat(TTR("Error loading scene from %s"), p_files[i]));
accept->popup_centered_minsize();
error = true;
@@ -174,7 +171,6 @@ void SceneTreeDock::_perform_instance_scenes(const Vector<String> &p_files, Node
Node *instanced_scene = sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE);
if (!instanced_scene) {
current_option = -1;
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(vformat(TTR("Error instancing scene from %s"), p_files[i]));
accept->popup_centered_minsize();
error = true;
@@ -185,7 +181,6 @@ void SceneTreeDock::_perform_instance_scenes(const Vector<String> &p_files, Node
if (_cyclical_dependency_exists(edited_scene->get_filename(), instanced_scene)) {
- accept->get_ok()->set_text(TTR("Ok"));
accept->set_text(vformat(TTR("Cannot instance the scene '%s' because the current scene exists within one of its nodes."), p_files[i]));
accept->popup_centered_minsize();
error = true;
@@ -233,7 +228,6 @@ void SceneTreeDock::_perform_instance_scenes(const Vector<String> &p_files, Node
void SceneTreeDock::_replace_with_branch_scene(const String &p_file, Node *base) {
Ref<PackedScene> sdata = ResourceLoader::load(p_file);
if (!sdata.is_valid()) {
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(vformat(TTR("Error loading scene from %s"), p_file));
accept->popup_centered_minsize();
return;
@@ -241,7 +235,6 @@ void SceneTreeDock::_replace_with_branch_scene(const String &p_file, Node *base)
Node *instanced_scene = sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE);
if (!instanced_scene) {
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(vformat(TTR("Error instancing scene from %s"), p_file));
accept->popup_centered_minsize();
return;
@@ -416,7 +409,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (scene_tree->get_selected() == edited_scene) {
current_option = -1;
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("This operation can't be done on the tree root."));
accept->popup_centered_minsize();
break;
@@ -477,7 +469,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (editor_selection->is_selected(edited_scene)) {
current_option = -1;
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("This operation can't be done on the tree root."));
accept->popup_centered_minsize();
break;
@@ -547,7 +538,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (editor_selection->is_selected(edited_scene)) {
current_option = -1;
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("This operation can't be done on the tree root."));
accept->popup_centered_minsize();
break;
@@ -634,7 +624,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
Node *scene = editor_data->get_edited_scene_root();
if (!scene) {
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("This operation can't be done without a scene."));
accept->popup_centered_minsize();
break;
@@ -643,7 +632,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
List<Node *> selection = editor_selection->get_selected_node_list();
if (selection.size() != 1) {
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("This operation requires a single selected node."));
accept->popup_centered_minsize();
break;
@@ -652,14 +640,12 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
Node *tocopy = selection.front()->get();
if (tocopy == scene) {
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("Can not perform with the root node."));
accept->popup_centered_minsize();
break;
}
if (tocopy != editor_data->get_edited_scene_root() && tocopy->get_filename() != "") {
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("This operation can't be done on instanced scenes."));
accept->popup_centered_minsize();
break;
@@ -1304,7 +1290,6 @@ bool SceneTreeDock::_validate_no_foreign() {
if (E->get() != edited_scene && E->get()->get_owner() != edited_scene) {
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("Can't operate on nodes from a foreign scene!"));
accept->popup_centered_minsize();
return false;
@@ -1312,7 +1297,6 @@ bool SceneTreeDock::_validate_no_foreign() {
if (edited_scene->get_scene_inherited_state().is_valid() && edited_scene->get_scene_inherited_state()->find_node_by_path(edited_scene->get_path_to(E->get())) >= 0) {
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("Can't operate on nodes the current scene inherits from!"));
accept->popup_centered_minsize();
return false;
@@ -1792,14 +1776,12 @@ void SceneTreeDock::_new_scene_from(String p_file) {
List<Node *> selection = editor_selection->get_selected_node_list();
if (selection.size() != 1) {
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("This operation requires a single selected node."));
accept->popup_centered_minsize();
return;
}
if (EditorNode::get_singleton()->is_scene_open(p_file)) {
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("Can't overwrite scene that is still open!"));
accept->popup_centered_minsize();
return;
@@ -1817,7 +1799,6 @@ void SceneTreeDock::_new_scene_from(String p_file) {
memdelete(copy);
if (err != OK) {
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("Couldn't save new scene. Likely dependencies (instances) couldn't be satisfied."));
accept->popup_centered_minsize();
return;
@@ -1829,14 +1810,12 @@ void SceneTreeDock::_new_scene_from(String p_file) {
err = ResourceSaver::save(p_file, sdata, flg);
if (err != OK) {
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("Error saving scene."));
accept->popup_centered_minsize();
return;
}
_replace_with_branch_scene(p_file, base);
} else {
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("Error duplicating scene to save it."));
accept->popup_centered_minsize();
return;
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index be255ba4aa..d8de775d36 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -164,7 +164,6 @@ void ScriptCreateDialog::_create_new() {
if (script_template != "") {
scr = ResourceLoader::load(script_template);
if (scr.is_null()) {
- alert->get_ok()->set_text(TTR("OK"));
alert->set_text(vformat(TTR("Error loading template '%s'"), script_template));
alert->popup_centered();
return;
@@ -201,7 +200,6 @@ void ScriptCreateDialog::_load_exist() {
String path = file_path->get_text();
RES p_script = ResourceLoader::load(path, "Script");
if (p_script.is_null()) {
- alert->get_ok()->set_text(TTR("OK"));
alert->set_text(vformat(TTR("Error loading script from %s"), path));
alert->popup_centered();
return;
diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp
index 97cdd43fee..fe384da75b 100644
--- a/editor/settings_config_dialog.cpp
+++ b/editor/settings_config_dialog.cpp
@@ -56,11 +56,7 @@ void EditorSettingsDialog::_settings_property_edited(const String &p_name) {
String full_name = inspector->get_full_item_path(p_name);
- // Small usability workaround to update the text color settings when the
- // color theme is changed
- if (full_name == "text_editor/theme/color_theme") {
- inspector->get_inspector()->update_tree();
- } else if (full_name == "interface/theme/accent_color" || full_name == "interface/theme/base_color" || full_name == "interface/theme/contrast") {
+ if (full_name == "interface/theme/accent_color" || full_name == "interface/theme/base_color" || full_name == "interface/theme/contrast") {
EditorSettings::get_singleton()->set_manually("interface/theme/preset", "Custom"); // set preset to Custom
} else if (full_name.begins_with("text_editor/highlighting")) {
EditorSettings::get_singleton()->set_manually("text_editor/theme/color_theme", "Custom");
diff --git a/main/main.cpp b/main/main.cpp
index 34aca032da..db82ff8f6e 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -73,6 +73,7 @@
#include "editor/doc/doc_data.h"
#include "editor/doc/doc_data_class_path.gen.h"
#include "editor/editor_node.h"
+#include "editor/editor_settings.h"
#include "editor/project_manager.h"
#endif
@@ -756,7 +757,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
if (editor) {
packed_data->set_disabled(true);
globals->set_disable_feature_overrides(true);
- StreamPeerSSL::initialize_certs = false; //will be initialized by editor
}
#endif
@@ -1096,30 +1096,24 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
ERR_PRINTS("Non-existing or invalid boot splash at: " + boot_logo_path + ". Loading default splash.");
}
+ Color boot_bg_color = GLOBAL_DEF("application/boot_splash/bg_color", boot_splash_bg_color);
if (boot_logo.is_valid()) {
OS::get_singleton()->_msec_splash = OS::get_singleton()->get_ticks_msec();
- Color boot_bg = GLOBAL_DEF("application/boot_splash/bg_color", clear);
- VisualServer::get_singleton()->set_boot_image(boot_logo, boot_bg, boot_logo_scale);
-#ifndef TOOLS_ENABLED
-//no tools, so free the boot logo (no longer needed)
-//ProjectSettings::get_singleton()->set("application/boot_logo",Image());
-#endif
+ VisualServer::get_singleton()->set_boot_image(boot_logo, boot_bg_color, boot_logo_scale);
} else {
#ifndef NO_DEFAULT_BOOT_LOGO
-
MAIN_PRINT("Main: Create bootsplash");
#if defined(TOOLS_ENABLED) && !defined(NO_EDITOR_SPLASH)
-
Ref<Image> splash = (editor || project_manager) ? memnew(Image(boot_splash_editor_png)) : memnew(Image(boot_splash_png));
#else
Ref<Image> splash = memnew(Image(boot_splash_png));
#endif
MAIN_PRINT("Main: ClearColor");
- VisualServer::get_singleton()->set_default_clear_color(boot_splash_bg_color);
+ VisualServer::get_singleton()->set_default_clear_color(boot_bg_color);
MAIN_PRINT("Main: Image");
- VisualServer::get_singleton()->set_boot_image(splash, boot_splash_bg_color, false);
+ VisualServer::get_singleton()->set_boot_image(splash, boot_bg_color, false);
#endif
}
@@ -1601,6 +1595,7 @@ bool Main::start() {
sml->set_use_font_oversampling(font_oversampling);
} else {
+
GLOBAL_DEF("display/window/stretch/mode", "disabled");
ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/mode", PropertyInfo(Variant::STRING, "display/window/stretch/mode", PROPERTY_HINT_ENUM, "disabled,2d,viewport"));
GLOBAL_DEF("display/window/stretch/aspect", "ignore");
@@ -1660,6 +1655,10 @@ bool Main::start() {
}
if (!project_manager && !editor) { // game
+
+ // Load SSL Certificates from Project Settings (or builtin)
+ StreamPeerSSL::load_certs_from_memory(StreamPeerSSL::get_project_cert_array());
+
if (game_path != "") {
Node *scene = NULL;
Ref<PackedScene> scenedata = ResourceLoader::load(local_game_path);
@@ -1692,6 +1691,15 @@ bool Main::start() {
sml->get_root()->add_child(pmanager);
OS::get_singleton()->set_context(OS::CONTEXT_PROJECTMAN);
}
+
+ if (project_manager || editor) {
+ // Load SSL Certificates from Editor Settings (or builtin)
+ String certs = EditorSettings::get_singleton()->get_setting("network/ssl/editor_ssl_certificates").operator String();
+ if (certs != "")
+ StreamPeerSSL::load_certs_from_file(certs);
+ else
+ StreamPeerSSL::load_certs_from_memory(StreamPeerSSL::get_project_cert_array());
+ }
#endif
}
diff --git a/methods.py b/methods.py
index 1bc10954ba..00c477635e 100644
--- a/methods.py
+++ b/methods.py
@@ -578,6 +578,9 @@ def generate_vs_project(env, num_jobs):
release_targets = ['bin\\godot.windows.opt.32.exe'] + ['bin\\godot.windows.opt.64.exe']
release_debug_targets = ['bin\\godot.windows.opt.tools.32.exe'] + ['bin\\godot.windows.opt.tools.64.exe']
targets = debug_targets + release_targets + release_debug_targets
+ if not env.get('MSVS'):
+ env['MSVS']['PROJECTSUFFIX'] = '.vcxproj'
+ env['MSVS']['SOLUTIONSUFFIX'] = '.sln'
env.MSVSProject(
target=['#godot' + env['MSVSPROJECTSUFFIX']],
incs=env.vs_incs,
diff --git a/modules/bullet/godot_result_callbacks.cpp b/modules/bullet/godot_result_callbacks.cpp
index 08d8b8c6f6..3b44ab838e 100644
--- a/modules/bullet/godot_result_callbacks.cpp
+++ b/modules/bullet/godot_result_callbacks.cpp
@@ -164,9 +164,11 @@ bool GodotClosestConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0)
}
btScalar GodotClosestConvexResultCallback::addSingleResult(btCollisionWorld::LocalConvexResult &convexResult, bool normalInWorldSpace) {
- btScalar res = btCollisionWorld::ClosestConvexResultCallback::addSingleResult(convexResult, normalInWorldSpace);
- m_shapeId = convexResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is a odd name but contains the compound shape ID
- return res;
+ if (convexResult.m_localShapeInfo)
+ m_shapeId = convexResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is a odd name but contains the compound shape ID
+ else
+ m_shapeId = 0;
+ return btCollisionWorld::ClosestConvexResultCallback::addSingleResult(convexResult, normalInWorldSpace);
}
bool GodotAllContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
diff --git a/modules/gdnative/include/nativescript/godot_nativescript.h b/modules/gdnative/include/nativescript/godot_nativescript.h
index d6a729be47..ba044117e2 100644
--- a/modules/gdnative/include/nativescript/godot_nativescript.h
+++ b/modules/gdnative/include/nativescript/godot_nativescript.h
@@ -40,12 +40,13 @@ extern "C" {
typedef enum {
GODOT_METHOD_RPC_MODE_DISABLED,
GODOT_METHOD_RPC_MODE_REMOTE,
- GODOT_METHOD_RPC_MODE_SYNC,
GODOT_METHOD_RPC_MODE_MASTER,
- GODOT_METHOD_RPC_MODE_SLAVE,
+ GODOT_METHOD_RPC_MODE_PUPPET,
+ GODOT_METHOD_RPC_MODE_SLAVE = GODOT_METHOD_RPC_MODE_PUPPET,
GODOT_METHOD_RPC_MODE_REMOTESYNC,
+ GODOT_METHOD_RPC_MODE_SYNC = GODOT_METHOD_RPC_MODE_REMOTESYNC,
GODOT_METHOD_RPC_MODE_MASTERSYNC,
- GODOT_METHOD_RPC_MODE_SLAVESYNC,
+ GODOT_METHOD_RPC_MODE_PUPPETSYNC,
} godot_method_rpc_mode;
typedef enum {
diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp
index ea968fb0b1..641e4021d8 100644
--- a/modules/gdnative/nativescript/nativescript.cpp
+++ b/modules/gdnative/nativescript/nativescript.cpp
@@ -810,18 +810,16 @@ MultiplayerAPI::RPCMode NativeScriptInstance::get_rpc_mode(const StringName &p_m
return MultiplayerAPI::RPC_MODE_DISABLED;
case GODOT_METHOD_RPC_MODE_REMOTE:
return MultiplayerAPI::RPC_MODE_REMOTE;
- case GODOT_METHOD_RPC_MODE_SYNC:
- return MultiplayerAPI::RPC_MODE_SYNC;
case GODOT_METHOD_RPC_MODE_MASTER:
return MultiplayerAPI::RPC_MODE_MASTER;
- case GODOT_METHOD_RPC_MODE_SLAVE:
- return MultiplayerAPI::RPC_MODE_SLAVE;
+ case GODOT_METHOD_RPC_MODE_PUPPET:
+ return MultiplayerAPI::RPC_MODE_PUPPET;
case GODOT_METHOD_RPC_MODE_REMOTESYNC:
return MultiplayerAPI::RPC_MODE_REMOTESYNC;
case GODOT_METHOD_RPC_MODE_MASTERSYNC:
return MultiplayerAPI::RPC_MODE_MASTERSYNC;
- case GODOT_METHOD_RPC_MODE_SLAVESYNC:
- return MultiplayerAPI::RPC_MODE_SLAVESYNC;
+ case GODOT_METHOD_RPC_MODE_PUPPETSYNC:
+ return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
default:
return MultiplayerAPI::RPC_MODE_DISABLED;
}
@@ -846,12 +844,16 @@ MultiplayerAPI::RPCMode NativeScriptInstance::get_rset_mode(const StringName &p_
return MultiplayerAPI::RPC_MODE_DISABLED;
case GODOT_METHOD_RPC_MODE_REMOTE:
return MultiplayerAPI::RPC_MODE_REMOTE;
- case GODOT_METHOD_RPC_MODE_SYNC:
- return MultiplayerAPI::RPC_MODE_SYNC;
case GODOT_METHOD_RPC_MODE_MASTER:
return MultiplayerAPI::RPC_MODE_MASTER;
- case GODOT_METHOD_RPC_MODE_SLAVE:
- return MultiplayerAPI::RPC_MODE_SLAVE;
+ case GODOT_METHOD_RPC_MODE_PUPPET:
+ return MultiplayerAPI::RPC_MODE_PUPPET;
+ case GODOT_METHOD_RPC_MODE_REMOTESYNC:
+ return MultiplayerAPI::RPC_MODE_REMOTESYNC;
+ case GODOT_METHOD_RPC_MODE_MASTERSYNC:
+ return MultiplayerAPI::RPC_MODE_MASTERSYNC;
+ case GODOT_METHOD_RPC_MODE_PUPPETSYNC:
+ return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
default:
return MultiplayerAPI::RPC_MODE_DISABLED;
}
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index 4d5d8cedde..d12c1f555c 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -1779,10 +1779,11 @@ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const {
"remote",
"sync",
"master",
+ "puppet",
"slave",
"remotesync",
"mastersync",
- "slavesync",
+ "puppetsync",
0
};
@@ -1979,6 +1980,10 @@ String GDScriptWarning::get_message() const {
CHECK_SYMBOLS(4);
return "The argument '" + symbols[0] + "' of the function '" + symbols[1] + "' requires a the subtype '" + symbols[2] + "' but the supertype '" + symbols[3] + "' was provided";
} break;
+ case DEPRECATED_KEYWORD: {
+ CHECK_SYMBOLS(2);
+ return "The '" + symbols[0] + "' keyword is deprecated and will be removed in a future release, please replace its uses by '" + symbols[1] + "'.";
+ } break;
}
ERR_EXPLAIN("Invalid GDScript warning code: " + get_name_from_code(code));
ERR_FAIL_V(String());
@@ -2018,6 +2023,7 @@ String GDScriptWarning::get_name_from_code(Code p_code) {
"UNSAFE_METHOD_ACCESS",
"UNSAFE_CAST",
"UNSAFE_CALL_ARGUMENT",
+ "DEPRECATED_KEYWORD",
NULL
};
diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h
index 739d18569f..d795500265 100644
--- a/modules/gdscript/gdscript.h
+++ b/modules/gdscript/gdscript.h
@@ -289,6 +289,7 @@ struct GDScriptWarning {
UNSAFE_METHOD_ACCESS, // Function not found in the detected type (but can be in subtypes)
UNSAFE_CAST, // Cast used in an unknown type
UNSAFE_CALL_ARGUMENT, // Function call argument is of a supertype of the require argument
+ DEPRECATED_KEYWORD, // The keyword is deprecated and should be replaced
WARNING_MAX,
} code;
Vector<String> symbols;
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index affb73a048..32a7668760 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -2109,8 +2109,8 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p
"and", "in", "not", "or", "false", "PI", "TAU", "INF", "NAN", "self", "true", "as", "assert",
"breakpoint", "class", "extends", "is", "func", "preload", "setget", "signal", "tool", "yield",
"const", "enum", "export", "onready", "static", "var", "break", "continue", "if", "elif",
- "else", "for", "pass", "return", "match", "while", "remote", "sync", "master", "slave",
- "remotesync", "mastersync", "slavesync",
+ "else", "for", "pass", "return", "match", "while", "remote", "sync", "master", "puppet", "slave",
+ "remotesync", "mastersync", "puppetsync",
0
};
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 7243690f94..81652c3d37 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -4382,10 +4382,10 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
}
- if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_ONREADY && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTE && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTER && tokenizer->get_token() != GDScriptTokenizer::TK_PR_SLAVE && tokenizer->get_token() != GDScriptTokenizer::TK_PR_SYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTESYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTERSYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_SLAVESYNC) {
+ if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_ONREADY && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTE && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTER && tokenizer->get_token() != GDScriptTokenizer::TK_PR_PUPPET && tokenizer->get_token() != GDScriptTokenizer::TK_PR_SYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTESYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTERSYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_PUPPETSYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_SLAVE) {
current_export = PropertyInfo();
- _set_error("Expected 'var', 'onready', 'remote', 'master', 'slave', 'sync', 'remotesync', 'mastersync', 'slavesync'.");
+ _set_error("Expected 'var', 'onready', 'remote', 'master', 'puppet', 'sync', 'remotesync', 'mastersync', 'puppetsync'.");
return;
}
@@ -4442,7 +4442,11 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
rpc_mode = MultiplayerAPI::RPC_MODE_MASTER;
continue;
} break;
- case GDScriptTokenizer::TK_PR_SLAVE: {
+ case GDScriptTokenizer::TK_PR_SLAVE:
+#ifdef DEBUG_ENABLED
+ _add_warning(GDScriptWarning::DEPRECATED_KEYWORD, tokenizer->get_token_line(), "slave", "puppet");
+#endif
+ case GDScriptTokenizer::TK_PR_PUPPET: {
//may be fallthrough from export, ignore if so
tokenizer->advance();
@@ -4459,7 +4463,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
}
- rpc_mode = MultiplayerAPI::RPC_MODE_SLAVE;
+ rpc_mode = MultiplayerAPI::RPC_MODE_PUPPET;
continue;
} break;
case GDScriptTokenizer::TK_PR_REMOTESYNC:
@@ -4475,7 +4479,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
return;
}
- rpc_mode = MultiplayerAPI::RPC_MODE_SYNC;
+ rpc_mode = MultiplayerAPI::RPC_MODE_REMOTESYNC;
continue;
} break;
case GDScriptTokenizer::TK_PR_MASTERSYNC: {
@@ -4493,7 +4497,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
rpc_mode = MultiplayerAPI::RPC_MODE_MASTERSYNC;
continue;
} break;
- case GDScriptTokenizer::TK_PR_SLAVESYNC: {
+ case GDScriptTokenizer::TK_PR_PUPPETSYNC: {
//may be fallthrough from export, ignore if so
tokenizer->advance();
@@ -4505,7 +4509,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
return;
}
- rpc_mode = MultiplayerAPI::RPC_MODE_SLAVESYNC;
+ rpc_mode = MultiplayerAPI::RPC_MODE_PUPPETSYNC;
continue;
} break;
case GDScriptTokenizer::TK_PR_VAR: {
diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp
index 941f5dbecc..77e1b7290e 100644
--- a/modules/gdscript/gdscript_tokenizer.cpp
+++ b/modules/gdscript/gdscript_tokenizer.cpp
@@ -112,10 +112,11 @@ const char *GDScriptTokenizer::token_names[TK_MAX] = {
"rpc",
"sync",
"master",
+ "puppet",
"slave",
"remotesync",
"mastersync",
- "slavesync",
+ "puppetsync",
"'['",
"']'",
"'{'",
@@ -210,10 +211,11 @@ static const _kws _keyword_list[] = {
{ GDScriptTokenizer::TK_PR_REMOTE, "remote" },
{ GDScriptTokenizer::TK_PR_MASTER, "master" },
{ GDScriptTokenizer::TK_PR_SLAVE, "slave" },
+ { GDScriptTokenizer::TK_PR_PUPPET, "puppet" },
{ GDScriptTokenizer::TK_PR_SYNC, "sync" },
{ GDScriptTokenizer::TK_PR_REMOTESYNC, "remotesync" },
{ GDScriptTokenizer::TK_PR_MASTERSYNC, "mastersync" },
- { GDScriptTokenizer::TK_PR_SLAVESYNC, "slavesync" },
+ { GDScriptTokenizer::TK_PR_PUPPETSYNC, "puppetsync" },
{ GDScriptTokenizer::TK_PR_CONST, "const" },
{ GDScriptTokenizer::TK_PR_ENUM, "enum" },
//controlflow
@@ -258,11 +260,11 @@ bool GDScriptTokenizer::is_token_literal(int p_offset, bool variable_safe) const
case TK_PR_SIGNAL:
case TK_PR_REMOTE:
case TK_PR_MASTER:
- case TK_PR_SLAVE:
+ case TK_PR_PUPPET:
case TK_PR_SYNC:
case TK_PR_REMOTESYNC:
case TK_PR_MASTERSYNC:
- case TK_PR_SLAVESYNC:
+ case TK_PR_PUPPETSYNC:
return true;
// Literal for non-variables only:
diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h
index 01b1ac5bf2..cc894fb101 100644
--- a/modules/gdscript/gdscript_tokenizer.h
+++ b/modules/gdscript/gdscript_tokenizer.h
@@ -119,9 +119,10 @@ public:
TK_PR_SYNC,
TK_PR_MASTER,
TK_PR_SLAVE,
+ TK_PR_PUPPET,
TK_PR_REMOTESYNC,
TK_PR_MASTERSYNC,
- TK_PR_SLAVESYNC,
+ TK_PR_PUPPETSYNC,
TK_BRACKET_OPEN,
TK_BRACKET_CLOSE,
TK_CURLY_BRACKET_OPEN,
diff --git a/modules/mbedtls/stream_peer_mbed_tls.cpp b/modules/mbedtls/stream_peer_mbed_tls.cpp
index 3398957775..3c04254fd4 100755
--- a/modules/mbedtls/stream_peer_mbed_tls.cpp
+++ b/modules/mbedtls/stream_peer_mbed_tls.cpp
@@ -317,15 +317,13 @@ void StreamPeerMbedTLS::initialize_ssl() {
mbedtls_debug_set_threshold(1);
#endif
- PoolByteArray cert_array = StreamPeerSSL::get_project_cert_array();
-
- if (cert_array.size() > 0)
- _load_certs(cert_array);
-
available = true;
}
void StreamPeerMbedTLS::finalize_ssl() {
+ available = false;
+ _create = NULL;
+ load_certs_func = NULL;
mbedtls_x509_crt_free(&cacert);
}
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index b9209fce92..c013c232d4 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -1541,18 +1541,20 @@ MultiplayerAPI::RPCMode CSharpInstance::_member_get_rpc_mode(GDMonoClassMember *
if (p_member->has_attribute(CACHED_CLASS(RemoteAttribute)))
return MultiplayerAPI::RPC_MODE_REMOTE;
- if (p_member->has_attribute(CACHED_CLASS(SyncAttribute)))
- return MultiplayerAPI::RPC_MODE_SYNC;
if (p_member->has_attribute(CACHED_CLASS(MasterAttribute)))
return MultiplayerAPI::RPC_MODE_MASTER;
+ if (p_member->has_attribute(CACHED_CLASS(PuppetAttribute)))
+ return MultiplayerAPI::RPC_MODE_PUPPET;
if (p_member->has_attribute(CACHED_CLASS(SlaveAttribute)))
- return MultiplayerAPI::RPC_MODE_SLAVE;
+ return MultiplayerAPI::RPC_MODE_PUPPET;
if (p_member->has_attribute(CACHED_CLASS(RemoteSyncAttribute)))
return MultiplayerAPI::RPC_MODE_REMOTESYNC;
+ if (p_member->has_attribute(CACHED_CLASS(SyncAttribute)))
+ return MultiplayerAPI::RPC_MODE_REMOTESYNC;
if (p_member->has_attribute(CACHED_CLASS(MasterSyncAttribute)))
return MultiplayerAPI::RPC_MODE_MASTERSYNC;
- if (p_member->has_attribute(CACHED_CLASS(SlaveSyncAttribute)))
- return MultiplayerAPI::RPC_MODE_SLAVESYNC;
+ if (p_member->has_attribute(CACHED_CLASS(PuppetSyncAttribute)))
+ return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
return MultiplayerAPI::RPC_MODE_DISABLED;
}
diff --git a/modules/mono/glue/Managed/Files/Attributes/RPCAttributes.cs b/modules/mono/glue/Managed/Files/Attributes/RPCAttributes.cs
index 6bf9560bfa..2398e10135 100644
--- a/modules/mono/glue/Managed/Files/Attributes/RPCAttributes.cs
+++ b/modules/mono/glue/Managed/Files/Attributes/RPCAttributes.cs
@@ -12,6 +12,9 @@ namespace Godot
public class MasterAttribute : Attribute {}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field)]
+ public class PuppetAttribute : Attribute {}
+
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field)]
public class SlaveAttribute : Attribute {}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field)]
@@ -21,5 +24,5 @@ namespace Godot
public class MasterSyncAttribute : Attribute {}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field)]
- public class SlaveSyncAttribute : Attribute {}
+ public class PuppetSyncAttribute : Attribute {}
}
diff --git a/modules/mono/glue/Managed/Files/Basis.cs b/modules/mono/glue/Managed/Files/Basis.cs
index ec96a9e2fa..a5618cb28d 100644
--- a/modules/mono/glue/Managed/Files/Basis.cs
+++ b/modules/mono/glue/Managed/Files/Basis.cs
@@ -165,6 +165,38 @@ namespace Godot
);
}
+ internal Quat RotationQuat()
+ {
+ Basis orthonormalizedBasis = Orthonormalized();
+ real_t det = orthonormalizedBasis.Determinant();
+ if (det < 0)
+ {
+ // Ensure that the determinant is 1, such that result is a proper rotation matrix which can be represented by Euler angles.
+ orthonormalizedBasis = orthonormalizedBasis.Scaled(Vector3.NegOne);
+ }
+
+ return orthonormalizedBasis.Quat();
+ }
+
+ internal void SetQuantScale(Quat quat, Vector3 scale)
+ {
+ SetDiagonal(scale);
+ Rotate(quat);
+ }
+
+ private void Rotate(Quat quat)
+ {
+ this *= new Basis(quat);
+ }
+
+ private void SetDiagonal(Vector3 diagonal)
+ {
+ _x = new Vector3(diagonal.x, 0, 0);
+ _y = new Vector3(0, diagonal.y, 0);
+ _z = new Vector3(0, 0, diagonal.z);
+
+ }
+
public real_t Determinant()
{
return this[0, 0] * (this[1, 1] * this[2, 2] - this[2, 1] * this[1, 2]) -
diff --git a/modules/mono/glue/Managed/Files/Transform.cs b/modules/mono/glue/Managed/Files/Transform.cs
index e432d5b52c..068007d7f0 100644
--- a/modules/mono/glue/Managed/Files/Transform.cs
+++ b/modules/mono/glue/Managed/Files/Transform.cs
@@ -20,6 +20,25 @@ namespace Godot
return new Transform(basisInv, basisInv.Xform(-origin));
}
+ public Transform InterpolateWith(Transform transform, real_t c)
+ {
+ /* not sure if very "efficient" but good enough? */
+
+ Vector3 sourceScale = basis.Scale;
+ Quat sourceRotation = basis.RotationQuat();
+ Vector3 sourceLocation = origin;
+
+ Vector3 destinationScale = transform.basis.Scale;
+ Quat destinationRotation = transform.basis.RotationQuat();
+ Vector3 destinationLocation = transform.origin;
+
+ var interpolated = new Transform();
+ interpolated.basis.SetQuantScale(sourceRotation.Slerp(destinationRotation, c).Normalized(), sourceScale.LinearInterpolate(destinationScale, c));
+ interpolated.origin = sourceLocation.LinearInterpolate(destinationLocation, c);
+
+ return interpolated;
+ }
+
public Transform Inverse()
{
Basis basisTr = basis.Transposed();
diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp
index 8fbaca0992..b97a24b09c 100644
--- a/modules/mono/mono_gd/gd_mono_utils.cpp
+++ b/modules/mono/mono_gd/gd_mono_utils.cpp
@@ -126,10 +126,11 @@ void MonoCache::clear_members() {
class_RemoteAttribute = NULL;
class_SyncAttribute = NULL;
class_MasterAttribute = NULL;
+ class_PuppetAttribute = NULL;
class_SlaveAttribute = NULL;
class_RemoteSyncAttribute = NULL;
class_MasterSyncAttribute = NULL;
- class_SlaveSyncAttribute = NULL;
+ class_PuppetSyncAttribute = NULL;
class_GodotMethodAttribute = NULL;
field_GodotMethodAttribute_methodName = NULL;
@@ -225,10 +226,11 @@ void update_godot_api_cache() {
CACHE_CLASS_AND_CHECK(RemoteAttribute, GODOT_API_CLASS(RemoteAttribute));
CACHE_CLASS_AND_CHECK(SyncAttribute, GODOT_API_CLASS(SyncAttribute));
CACHE_CLASS_AND_CHECK(MasterAttribute, GODOT_API_CLASS(MasterAttribute));
+ CACHE_CLASS_AND_CHECK(PuppetAttribute, GODOT_API_CLASS(PuppetAttribute));
CACHE_CLASS_AND_CHECK(SlaveAttribute, GODOT_API_CLASS(SlaveAttribute));
CACHE_CLASS_AND_CHECK(RemoteSyncAttribute, GODOT_API_CLASS(RemoteSyncAttribute));
CACHE_CLASS_AND_CHECK(MasterSyncAttribute, GODOT_API_CLASS(MasterSyncAttribute));
- CACHE_CLASS_AND_CHECK(SlaveSyncAttribute, GODOT_API_CLASS(SlaveSyncAttribute));
+ CACHE_CLASS_AND_CHECK(PuppetSyncAttribute, GODOT_API_CLASS(PuppetSyncAttribute));
CACHE_CLASS_AND_CHECK(GodotMethodAttribute, GODOT_API_CLASS(GodotMethodAttribute));
CACHE_FIELD_AND_CHECK(GodotMethodAttribute, methodName, CACHED_CLASS(GodotMethodAttribute)->get_field("methodName"));
diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h
index 96ff3e8116..ec3a57eb46 100644
--- a/modules/mono/mono_gd/gd_mono_utils.h
+++ b/modules/mono/mono_gd/gd_mono_utils.h
@@ -131,8 +131,9 @@ struct MonoCache {
GDMonoClass *class_SyncAttribute;
GDMonoClass *class_RemoteSyncAttribute;
GDMonoClass *class_MasterSyncAttribute;
- GDMonoClass *class_SlaveSyncAttribute;
+ GDMonoClass *class_PuppetSyncAttribute;
GDMonoClass *class_MasterAttribute;
+ GDMonoClass *class_PuppetAttribute;
GDMonoClass *class_SlaveAttribute;
GDMonoClass *class_GodotMethodAttribute;
GDMonoField *field_GodotMethodAttribute_methodName;
diff --git a/modules/opensimplex/doc_classes/SimplexNoise.xml b/modules/opensimplex/doc_classes/SimplexNoise.xml
index 2dd2318681..a5a01d88a7 100644
--- a/modules/opensimplex/doc_classes/SimplexNoise.xml
+++ b/modules/opensimplex/doc_classes/SimplexNoise.xml
@@ -22,7 +22,6 @@
print(noise.get_noise_3d(0.5,3.0,15.0))
print(noise.get_noise_3d(0.5,1.9,4.7,0.0))
[/codeblock]
-
</description>
<tutorials>
</tutorials>
diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp
index 99f242e974..5c880f48d1 100644
--- a/modules/visual_script/visual_script_nodes.cpp
+++ b/modules/visual_script/visual_script_nodes.cpp
@@ -167,7 +167,7 @@ void VisualScriptFunction::_get_property_list(List<PropertyInfo> *p_list) const
p_list->push_back(PropertyInfo(Variant::INT, "stack/size", PROPERTY_HINT_RANGE, "1,100000"));
}
p_list->push_back(PropertyInfo(Variant::BOOL, "stack/stackless"));
- p_list->push_back(PropertyInfo(Variant::INT, "rpc/mode", PROPERTY_HINT_ENUM, "Disabled,Remote,Sync,Master,Slave"));
+ p_list->push_back(PropertyInfo(Variant::INT, "rpc/mode", PROPERTY_HINT_ENUM, "Disabled,Remote,Master,Puppet,Remote Sync,Master Sync,Puppet Sync"));
}
int VisualScriptFunction::get_output_sequence_port_count() const {
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index 3515eeeb60..b0ec3c4245 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -39,6 +39,7 @@
#include "unix/file_access_unix.h"
#include <emscripten.h>
+#include <png.h>
#include <stdlib.h>
#include "dom_keys.inc"
@@ -912,6 +913,57 @@ void OS_JavaScript::set_window_title(const String &p_title) {
/* clang-format on */
}
+void OS_JavaScript::set_icon(const Ref<Image> &p_icon) {
+
+ ERR_FAIL_COND(p_icon.is_null());
+ Ref<Image> icon = p_icon;
+ if (icon->is_compressed()) {
+ icon = icon->duplicate();
+ ERR_FAIL_COND(icon->decompress() != OK)
+ }
+ if (icon->get_format() != Image::FORMAT_RGBA8) {
+ if (icon == p_icon)
+ icon = icon->duplicate();
+ icon->convert(Image::FORMAT_RGBA8);
+ }
+
+ png_image png_meta;
+ memset(&png_meta, 0, sizeof png_meta);
+ png_meta.version = PNG_IMAGE_VERSION;
+ png_meta.width = icon->get_width();
+ png_meta.height = icon->get_height();
+ png_meta.format = PNG_FORMAT_RGBA;
+
+ PoolByteArray png;
+ size_t len;
+ PoolByteArray::Read r = icon->get_data().read();
+ ERR_FAIL_COND(!png_image_write_get_memory_size(png_meta, len, 0, r.ptr(), 0, NULL));
+
+ png.resize(len);
+ PoolByteArray::Write w = png.write();
+ ERR_FAIL_COND(!png_image_write_to_memory(&png_meta, w.ptr(), &len, 0, r.ptr(), 0, NULL));
+ w = PoolByteArray::Write();
+
+ r = png.read();
+ /* clang-format off */
+ EM_ASM_ARGS({
+ var PNG_PTR = $0;
+ var PNG_LEN = $1;
+
+ var png = new Blob([HEAPU8.slice(PNG_PTR, PNG_PTR + PNG_LEN)], { type: "image/png" });
+ var url = URL.createObjectURL(png);
+ var link = document.getElementById('-gd-engine-icon');
+ if (link === null) {
+ link = document.createElement('link');
+ link.rel = 'icon';
+ link.id = '-gd-engine-icon';
+ document.head.appendChild(link);
+ }
+ link.href = url;
+ }, r.ptr(), len);
+ /* clang-format on */
+}
+
String OS_JavaScript::get_executable_path() const {
return OS::get_executable_path();
diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h
index f40fb8fc7e..ddcbf8c7c9 100644
--- a/platform/javascript/os_javascript.h
+++ b/platform/javascript/os_javascript.h
@@ -135,6 +135,7 @@ public:
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
virtual void set_window_title(const String &p_title);
+ virtual void set_icon(const Ref<Image> &p_icon);
String get_executable_path() const;
virtual Error shell_open(String p_uri);
virtual String get_name();
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index c0de4e3f2a..b98113baeb 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -1662,7 +1662,7 @@ void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c
[cursors[p_shape] release];
cursors[p_shape] = cursor;
- if (p_shape == CURSOR_ARROW) {
+ if (p_shape == cursor_shape) {
[cursor set];
}
@@ -1671,8 +1671,10 @@ void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c
} else {
// Reset to default system cursor
cursors[p_shape] = NULL;
+
+ CursorShape c = cursor_shape;
cursor_shape = CURSOR_MAX;
- set_cursor_shape(p_shape);
+ set_cursor_shape(c);
}
}
diff --git a/platform/windows/SCsub b/platform/windows/SCsub
index 586533e817..5dfb1592e0 100644
--- a/platform/windows/SCsub
+++ b/platform/windows/SCsub
@@ -29,6 +29,7 @@ prog = env.add_program('#bin/godot', common_win + res_obj, PROGSUFFIX=env["PROGS
# Microsoft Visual Studio Project Generation
if env['vsproj']:
env.vs_srcs = env.vs_srcs + ["platform/windows/" + res_file]
+ env.vs_srcs = env.vs_srcs + ["platform/windows/godot.natvis"]
for x in common_win:
env.vs_srcs = env.vs_srcs + ["platform/windows/" + str(x)]
diff --git a/platform/windows/godot.natvis b/platform/windows/godot.natvis
new file mode 100644
index 0000000000..01963035a1
--- /dev/null
+++ b/platform/windows/godot.natvis
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="utf-8"?>
+<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
+ <Type Name="Vector&lt;*&gt;">
+ <Expand>
+ <Item Name="size">(_cowdata &amp;&amp; _cowdata-&gt;_ptr) ? (((const unsigned int *)(_cowdata-&gt;_ptr))[-1]) : 0</Item>
+ <ArrayItems>
+ <Size>(_cowdata &amp;&amp; _cowdata-&gt;_ptr) ? (((const unsigned int *)(_cowdata-&gt;_ptr))[-1]) : 0</Size>
+ <ValuePointer>(_cowdata) ? (_cowdata-&gt;_ptr) : 0</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="PoolVector&lt;*&gt;">
+ <Expand>
+ <Item Name="size">alloc ? (alloc-&gt;size / sizeof($T1)) : 0</Item>
+ <ArrayItems>
+ <Size>alloc ? (alloc-&gt;size / sizeof($T1)) : 0</Size>
+ <ValuePointer>alloc ? (($T1 *)alloc-&gt;mem) : 0</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="Variant">
+ <DisplayString Condition="this-&gt;type == Variant::NIL">nil</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::BOOL">{_data._bool}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::INT">{_data._int}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::REAL">{_data._real}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::TRANSFORM2D">{_data._transform2d}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::AABB">{_data._aabb}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::BASIS">{_data._basis}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::TRANSFORM">{_data._transform}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::ARRAY">{*(Array *)_data._mem}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::STRING &amp;&amp; ((String *)(&amp;_data._mem[0]))-&gt;_cowdata._ptr == 0">""</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::STRING &amp;&amp; ((String *)(&amp;_data._mem[0]))-&gt;_cowdata._ptr != 0">{((String *)(&amp;_data._mem[0]))-&gt;_cowdata._ptr,su}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::VECTOR2">{*(Vector2 *)_data._mem}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::RECT2">{*(Rect2 *)_data._mem}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::VECTOR3">{*(Vector3 *)_data._mem}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::PLANE">{*(Plane *)_data._mem}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::QUAT">{*(Quat *)_data._mem}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::COLOR">{*(Color *)_data._mem}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::NODE_PATH">{*(NodePath *)_data._mem}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::_RID">{*(RID *)_data._mem}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::OBJECT">{*(Object *)_data._mem}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::DICTIONARY">{*(Dictionary *)_data._mem}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::ARRAY">{*(Array *)_data._mem}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::POOL_BYTE_ARRAY">{*(PoolByteArray *)_data._mem}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::POOL_INT_ARRAY">{*(PoolIntArray *)_data._mem}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::POOL_REAL_ARRAY">{*(PoolRealArray *)_data._mem}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::POOL_STRING_ARRAY">{*(PoolStringArray *)_data._mem}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::POOL_VECTOR2_ARRAY">{*(PoolVector2Array *)_data._mem}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::POOL_VECTOR3_ARRAY">{*(PoolVector3Array *)_data._mem}</DisplayString>
+ <DisplayString Condition="this-&gt;type == Variant::POOL_COLOR_ARRAY">{*(PoolColorArray *)_data._mem}</DisplayString>
+
+ <StringView Condition="this-&gt;type == Variant::STRING &amp;&amp; ((String *)(&amp;_data._mem[0]))-&gt;_cowdata._ptr != 0">((String *)(&amp;_data._mem[0]))-&gt;_cowdata._ptr,su</StringView>
+
+ <Expand>
+ <Item Name="value" Condition="this-&gt;type == Variant::BOOL">_data._bool</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::INT">_data._int</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::REAL">_data._real</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::TRANSFORM2D">_data._transform2d</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::AABB">_data._aabb</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::BASIS">_data._basis</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::TRANSFORM">_data._transform</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::ARRAY">*(Array *)_data._mem</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::STRING">*(String *)_data._mem</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::VECTOR2">*(Vector2 *)_data._mem</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::RECT2">*(Rect2 *)_data._mem</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::VECTOR3">*(Vector3 *)_data._mem</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::PLANE">*(Plane *)_data._mem</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::QUAT">*(Quat *)_data._mem</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::COLOR">*(Color *)_data._mem</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::NODE_PATH">*(NodePath *)_data._mem</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::_RID">*(RID *)_data._mem</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::OBJECT">*(Object *)_data._mem</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::DICTIONARY">*(Dictionary *)_data._mem</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::ARRAY">*(Array *)_data._mem</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::POOL_BYTE_ARRAY">*(PoolByteArray *)_data._mem</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::POOL_INT_ARRAY">*(PoolIntArray *)_data._mem</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::POOL_REAL_ARRAY">*(PoolRealArray *)_data._mem</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::POOL_STRING_ARRAY">*(PoolStringArray *)_data._mem</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::POOL_VECTOR2_ARRAY">*(PoolVector2Array *)_data._mem</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::POOL_VECTOR3_ARRAY">*(PoolVector3Array *)_data._mem</Item>
+ <Item Name="value" Condition="this-&gt;type == Variant::POOL_COLOR_ARRAY">*(PoolColorArray *)_data._mem</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="String">
+ <DisplayString Condition="this-&gt;_cowdata._ptr == 0">empty</DisplayString>
+ <DisplayString Condition="this-&gt;_cowdata._ptr != 0">{this->_cowdata._ptr,su}</DisplayString>
+ <StringView Condition="this-&gt;_cowdata._ptr != 0">this->_cowdata._ptr,su</StringView>
+ </Type>
+
+ <Type Name="Vector2">
+ <DisplayString>{{{x},{y}}}</DisplayString>
+ <Expand>
+ <Item Name="x">x</Item>
+ <Item Name="y">y</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="Vector3">
+ <DisplayString>{{{x},{y},{z}}}</DisplayString>
+ <Expand>
+ <Item Name="x">x</Item>
+ <Item Name="y">y</Item>
+ <Item Name="z">z</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="Quat">
+ <DisplayString>Quat {{{x},{y},{z},{w}}}</DisplayString>
+ <Expand>
+ <Item Name="x">x</Item>
+ <Item Name="y">y</Item>
+ <Item Name="z">z</Item>
+ <Item Name="w">w</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="Color">
+ <DisplayString>Color {{{r},{g},{b},{a}}}</DisplayString>
+ <Expand>
+ <Item Name="red">r</Item>
+ <Item Name="green">g</Item>
+ <Item Name="blue">b</Item>
+ <Item Name="alpha">a</Item>
+ </Expand>
+ </Type>
+</AutoVisualizer>
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 67fc1c7496..f63aebbbd3 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -2311,7 +2311,7 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap
cursors[p_shape] = CreateIconIndirect(&iconinfo);
- if (p_shape == CURSOR_ARROW) {
+ if (p_shape == cursor_shape) {
SetCursor(cursors[p_shape]);
}
@@ -2328,8 +2328,10 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap
} else {
// Reset to default system cursor
cursors[p_shape] = NULL;
+
+ CursorShape c = cursor_shape;
cursor_shape = CURSOR_MAX;
- set_cursor_shape(p_shape);
+ set_cursor_shape(c);
}
}
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index b80a20ce40..24dfe541f9 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -2606,7 +2606,7 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c
// Save it for a further usage
cursors[p_shape] = XcursorImageLoadCursor(x11_display, cursor_image);
- if (p_shape == CURSOR_ARROW) {
+ if (p_shape == current_cursor) {
XDefineCursor(x11_display, x11_window, cursors[p_shape]);
}
@@ -2618,8 +2618,9 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c
cursors[p_shape] = XcursorImageLoadCursor(x11_display, img[p_shape]);
}
+ CursorShape c = current_cursor;
current_cursor = CURSOR_MAX;
- set_cursor_shape(p_shape);
+ set_cursor_shape(c);
}
}
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 1e281471a6..fa5019a6f7 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -29,12 +29,13 @@
/*************************************************************************/
#include "rich_text_label.h"
+
#include "core/os/keyboard.h"
#include "core/os/os.h"
#include "scene/scene_string_names.h"
#ifdef TOOLS_ENABLED
-#include "editor/editor_node.h"
+#include "editor/editor_scale.h"
#endif
RichTextLabel::Item *RichTextLabel::_get_next_item(Item *p_item, bool p_free) {
@@ -2295,7 +2296,7 @@ RichTextLabel::RichTextLabel() {
vscroll = memnew(VScrollBar);
add_child(vscroll);
- vscroll->set_drag_slave(String(".."));
+ vscroll->set_drag_node(String(".."));
vscroll->set_step(1);
vscroll->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 0);
vscroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, 0);
diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp
index df27fb0e6b..07380f45cc 100644
--- a/scene/gui/scroll_bar.cpp
+++ b/scene/gui/scroll_bar.cpp
@@ -300,24 +300,24 @@ void ScrollBar::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
- if (has_node(drag_slave_path)) {
- Node *n = get_node(drag_slave_path);
- drag_slave = Object::cast_to<Control>(n);
+ if (has_node(drag_node_path)) {
+ Node *n = get_node(drag_node_path);
+ drag_node = Object::cast_to<Control>(n);
}
- if (drag_slave) {
- drag_slave->connect("gui_input", this, "_drag_slave_input");
- drag_slave->connect("tree_exiting", this, "_drag_slave_exit", varray(), CONNECT_ONESHOT);
+ if (drag_node) {
+ drag_node->connect("gui_input", this, "_drag_node_input");
+ drag_node->connect("tree_exiting", this, "_drag_node_exit", varray(), CONNECT_ONESHOT);
}
}
if (p_what == NOTIFICATION_EXIT_TREE) {
- if (drag_slave) {
- drag_slave->disconnect("gui_input", this, "_drag_slave_input");
- drag_slave->disconnect("tree_exiting", this, "_drag_slave_exit");
+ if (drag_node) {
+ drag_node->disconnect("gui_input", this, "_drag_node_input");
+ drag_node->disconnect("tree_exiting", this, "_drag_node_exit");
}
- drag_slave = NULL;
+ drag_node = NULL;
}
if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) {
@@ -337,12 +337,13 @@ void ScrollBar::_notification(int p_what) {
scrolling = false;
set_physics_process_internal(false);
}
- } else if (drag_slave_touching) {
- if (drag_slave_touching_deaccel) {
+ } else if (drag_node_touching) {
+
+ if (drag_node_touching_deaccel) {
Vector2 pos = Vector2(orientation == HORIZONTAL ? get_value() : 0, orientation == VERTICAL ? get_value() : 0);
- pos += drag_slave_speed * get_physics_process_delta_time();
+ pos += drag_node_speed * get_physics_process_delta_time();
bool turnoff = false;
@@ -360,15 +361,15 @@ void ScrollBar::_notification(int p_what) {
set_value(pos.x);
- float sgn_x = drag_slave_speed.x < 0 ? -1 : 1;
- float val_x = Math::abs(drag_slave_speed.x);
+ float sgn_x = drag_node_speed.x < 0 ? -1 : 1;
+ float val_x = Math::abs(drag_node_speed.x);
val_x -= 1000 * get_physics_process_delta_time();
if (val_x < 0) {
turnoff = true;
}
- drag_slave_speed.x = sgn_x * val_x;
+ drag_node_speed.x = sgn_x * val_x;
} else {
@@ -384,29 +385,29 @@ void ScrollBar::_notification(int p_what) {
set_value(pos.y);
- float sgn_y = drag_slave_speed.y < 0 ? -1 : 1;
- float val_y = Math::abs(drag_slave_speed.y);
+ float sgn_y = drag_node_speed.y < 0 ? -1 : 1;
+ float val_y = Math::abs(drag_node_speed.y);
val_y -= 1000 * get_physics_process_delta_time();
if (val_y < 0) {
turnoff = true;
}
- drag_slave_speed.y = sgn_y * val_y;
+ drag_node_speed.y = sgn_y * val_y;
}
if (turnoff) {
set_physics_process_internal(false);
- drag_slave_touching = false;
- drag_slave_touching_deaccel = false;
+ drag_node_touching = false;
+ drag_node_touching_deaccel = false;
}
} else {
if (time_since_motion == 0 || time_since_motion > 0.1) {
- Vector2 diff = drag_slave_accum - last_drag_slave_accum;
- last_drag_slave_accum = drag_slave_accum;
- drag_slave_speed = diff / get_physics_process_delta_time();
+ Vector2 diff = drag_node_accum - last_drag_node_accum;
+ last_drag_node_accum = drag_node_accum;
+ drag_node_speed = diff / get_physics_process_delta_time();
}
time_since_motion += get_physics_process_delta_time();
@@ -544,15 +545,15 @@ float ScrollBar::get_custom_step() const {
return custom_step;
}
-void ScrollBar::_drag_slave_exit() {
+void ScrollBar::_drag_node_exit() {
- if (drag_slave) {
- drag_slave->disconnect("gui_input", this, "_drag_slave_input");
+ if (drag_node) {
+ drag_node->disconnect("gui_input", this, "_drag_node_input");
}
- drag_slave = NULL;
+ drag_node = NULL;
}
-void ScrollBar::_drag_slave_input(const Ref<InputEvent> &p_input) {
+void ScrollBar::_drag_node_input(const Ref<InputEvent> &p_input) {
Ref<InputEventMouseButton> mb = p_input;
@@ -563,43 +564,30 @@ void ScrollBar::_drag_slave_input(const Ref<InputEvent> &p_input) {
if (mb->is_pressed()) {
- if (drag_slave_touching) {
- set_physics_process_internal(false);
- drag_slave_touching_deaccel = false;
- drag_slave_touching = false;
- drag_slave_speed = Vector2();
- drag_slave_accum = Vector2();
- last_drag_slave_accum = Vector2();
- drag_slave_from = Vector2();
- }
+ drag_node_speed = Vector2();
+ drag_node_accum = Vector2();
+ last_drag_node_accum = Vector2();
+ drag_node_from = Vector2(orientation == HORIZONTAL ? get_value() : 0, orientation == VERTICAL ? get_value() : 0);
- if (true) {
- drag_slave_speed = Vector2();
- drag_slave_accum = Vector2();
- last_drag_slave_accum = Vector2();
- //drag_slave_from=Vector2(h_scroll->get_val(),v_scroll->get_val());
- drag_slave_from = Vector2(orientation == HORIZONTAL ? get_value() : 0, orientation == VERTICAL ? get_value() : 0);
+ drag_node_touching = OS::get_singleton()->has_touchscreen_ui_hint();
+ drag_node_touching_deaccel = false;
+ time_since_motion = 0;
- drag_slave_touching = OS::get_singleton()->has_touchscreen_ui_hint();
- drag_slave_touching_deaccel = false;
+ if (drag_node_touching) {
+ set_physics_process_internal(true);
time_since_motion = 0;
- if (drag_slave_touching) {
- set_physics_process_internal(true);
- time_since_motion = 0;
- }
}
} else {
- if (drag_slave_touching) {
+ if (drag_node_touching) {
- if (drag_slave_speed == Vector2()) {
- drag_slave_touching_deaccel = false;
- drag_slave_touching = false;
+ if (drag_node_speed == Vector2()) {
+ drag_node_touching_deaccel = false;
+ drag_node_touching = false;
set_physics_process_internal(false);
} else {
-
- drag_slave_touching_deaccel = true;
+ drag_node_touching_deaccel = true;
}
}
}
@@ -609,60 +597,54 @@ void ScrollBar::_drag_slave_input(const Ref<InputEvent> &p_input) {
if (mm.is_valid()) {
- if (drag_slave_touching && !drag_slave_touching_deaccel) {
+ if (drag_node_touching && !drag_node_touching_deaccel) {
Vector2 motion = Vector2(mm->get_relative().x, mm->get_relative().y);
- drag_slave_accum -= motion;
- Vector2 diff = drag_slave_from + drag_slave_accum;
+ drag_node_accum -= motion;
+ Vector2 diff = drag_node_from + drag_node_accum;
if (orientation == HORIZONTAL)
set_value(diff.x);
- /*
- else
- drag_slave_accum.x=0;
- */
+
if (orientation == VERTICAL)
set_value(diff.y);
- /*
- else
- drag_slave_accum.y=0;
- */
+
time_since_motion = 0;
}
}
}
-void ScrollBar::set_drag_slave(const NodePath &p_path) {
+void ScrollBar::set_drag_node(const NodePath &p_path) {
if (is_inside_tree()) {
- if (drag_slave) {
- drag_slave->disconnect("gui_input", this, "_drag_slave_input");
- drag_slave->disconnect("tree_exiting", this, "_drag_slave_exit");
+ if (drag_node) {
+ drag_node->disconnect("gui_input", this, "_drag_node_input");
+ drag_node->disconnect("tree_exiting", this, "_drag_node_exit");
}
}
- drag_slave = NULL;
- drag_slave_path = p_path;
+ drag_node = NULL;
+ drag_node_path = p_path;
if (is_inside_tree()) {
if (has_node(p_path)) {
Node *n = get_node(p_path);
- drag_slave = Object::cast_to<Control>(n);
+ drag_node = Object::cast_to<Control>(n);
}
- if (drag_slave) {
- drag_slave->connect("gui_input", this, "_drag_slave_input");
- drag_slave->connect("tree_exiting", this, "_drag_slave_exit", varray(), CONNECT_ONESHOT);
+ if (drag_node) {
+ drag_node->connect("gui_input", this, "_drag_node_input");
+ drag_node->connect("tree_exiting", this, "_drag_node_exit", varray(), CONNECT_ONESHOT);
}
}
}
-NodePath ScrollBar::get_drag_slave() const {
+NodePath ScrollBar::get_drag_node() const {
- return drag_slave_path;
+ return drag_node_path;
}
void ScrollBar::set_smooth_scroll_enabled(bool p_enable) {
@@ -678,8 +660,8 @@ void ScrollBar::_bind_methods() {
ClassDB::bind_method(D_METHOD("_gui_input"), &ScrollBar::_gui_input);
ClassDB::bind_method(D_METHOD("set_custom_step", "step"), &ScrollBar::set_custom_step);
ClassDB::bind_method(D_METHOD("get_custom_step"), &ScrollBar::get_custom_step);
- ClassDB::bind_method(D_METHOD("_drag_slave_input"), &ScrollBar::_drag_slave_input);
- ClassDB::bind_method(D_METHOD("_drag_slave_exit"), &ScrollBar::_drag_slave_exit);
+ ClassDB::bind_method(D_METHOD("_drag_node_input"), &ScrollBar::_drag_node_input);
+ ClassDB::bind_method(D_METHOD("_drag_node_exit"), &ScrollBar::_drag_node_exit);
ADD_SIGNAL(MethodInfo("scrolling"));
@@ -691,13 +673,13 @@ ScrollBar::ScrollBar(Orientation p_orientation) {
orientation = p_orientation;
highlight = HIGHLIGHT_NONE;
custom_step = -1;
- drag_slave = NULL;
+ drag_node = NULL;
drag.active = false;
- drag_slave_speed = Vector2();
- drag_slave_touching = false;
- drag_slave_touching_deaccel = false;
+ drag_node_speed = Vector2();
+ drag_node_touching = false;
+ drag_node_touching_deaccel = false;
scrolling = false;
target_scroll = 0;
diff --git a/scene/gui/scroll_bar.h b/scene/gui/scroll_bar.h
index 15e037f8bb..cde4120cdb 100644
--- a/scene/gui/scroll_bar.h
+++ b/scene/gui/scroll_bar.h
@@ -36,6 +36,7 @@
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
+
class ScrollBar : public Range {
GDCLASS(ScrollBar, Range);
@@ -71,25 +72,25 @@ class ScrollBar : public Range {
static void set_can_focus_by_default(bool p_can_focus);
- Node *drag_slave;
- NodePath drag_slave_path;
+ Node *drag_node;
+ NodePath drag_node_path;
- Vector2 drag_slave_speed;
- Vector2 drag_slave_accum;
- Vector2 drag_slave_from;
- Vector2 last_drag_slave_accum;
- float last_drag_slave_time;
+ Vector2 drag_node_speed;
+ Vector2 drag_node_accum;
+ Vector2 drag_node_from;
+ Vector2 last_drag_node_accum;
+ float last_drag_node_time;
float time_since_motion;
- bool drag_slave_touching;
- bool drag_slave_touching_deaccel;
+ bool drag_node_touching;
+ bool drag_node_touching_deaccel;
bool click_handled;
bool scrolling;
double target_scroll;
bool smooth_scroll_enabled;
- void _drag_slave_exit();
- void _drag_slave_input(const Ref<InputEvent> &p_input);
+ void _drag_node_exit();
+ void _drag_node_input(const Ref<InputEvent> &p_input);
void _gui_input(Ref<InputEvent> p_event);
@@ -102,8 +103,8 @@ public:
void set_custom_step(float p_custom_step);
float get_custom_step() const;
- void set_drag_slave(const NodePath &p_path);
- NodePath get_drag_slave() const;
+ void set_drag_node(const NodePath &p_path);
+ NodePath get_drag_node() const;
void set_smooth_scroll_enabled(bool p_enable);
bool is_smooth_scroll_enabled() const;
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index dfd9dfa52e..487ca2b009 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -2789,6 +2789,8 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("gui_get_drag_data"), &Viewport::gui_get_drag_data);
ClassDB::bind_method(D_METHOD("gui_is_dragging"), &Viewport::gui_is_dragging);
+ ClassDB::bind_method(D_METHOD("get_modal_stack_top"), &Viewport::get_modal_stack_top);
+
ClassDB::bind_method(D_METHOD("set_disable_input", "disable"), &Viewport::set_disable_input);
ClassDB::bind_method(D_METHOD("is_input_disabled"), &Viewport::is_input_disabled);