summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS.md2
-rw-r--r--DONORS.md75
-rw-r--r--SConstruct2
-rw-r--r--core/config/project_settings.cpp2
-rw-r--r--core/core_bind.cpp3
-rw-r--r--core/core_constants.cpp1
-rw-r--r--core/extension/gdnative_interface.cpp6
-rw-r--r--core/extension/gdnative_interface.h11
-rw-r--r--core/io/compression.cpp8
-rw-r--r--core/io/http_client_tcp.cpp1
-rw-r--r--core/io/multiplayer_api.cpp30
-rw-r--r--core/io/multiplayer_api.h12
-rw-r--r--core/io/multiplayer_peer.cpp (renamed from core/io/networked_multiplayer_peer.cpp)24
-rw-r--r--core/io/multiplayer_peer.h (renamed from core/io/networked_multiplayer_peer.h)12
-rw-r--r--core/object/class_db.h11
-rw-r--r--core/object/object.cpp61
-rw-r--r--core/object/object.h36
-rw-r--r--core/object/ref_counted.cpp19
-rw-r--r--core/os/memory.h2
-rw-r--r--core/os/os.h2
-rw-r--r--core/register_core_types.cpp160
-rw-r--r--core/string/ustring.cpp19
-rw-r--r--core/templates/list.h77
-rw-r--r--core/templates/map.h133
-rw-r--r--core/templates/pair.h35
-rw-r--r--core/templates/set.h79
-rw-r--r--core/templates/vector.h64
-rw-r--r--core/typedefs.h7
-rw-r--r--doc/classes/@GlobalScope.xml46
-rw-r--r--doc/classes/Control.xml5
-rw-r--r--doc/classes/DisplayServer.xml69
-rw-r--r--doc/classes/HTTPClient.xml8
-rw-r--r--doc/classes/Label.xml34
-rw-r--r--doc/classes/Mesh.xml6
-rw-r--r--doc/classes/MeshInstance3D.xml6
-rw-r--r--doc/classes/MultiplayerAPI.xml8
-rw-r--r--doc/classes/MultiplayerPeer.xml (renamed from doc/classes/NetworkedMultiplayerPeer.xml)12
-rw-r--r--doc/classes/Node.xml10
-rw-r--r--doc/classes/PacketPeerUDP.xml2
-rw-r--r--doc/classes/PlaneMesh.xml3
-rw-r--r--doc/classes/ProjectSettings.xml12
-rw-r--r--doc/classes/QuadMesh.xml3
-rw-r--r--doc/classes/RDPipelineSpecializationConstant.xml19
-rw-r--r--doc/classes/RenderingDevice.xml10
-rw-r--r--doc/classes/SceneTree.xml70
-rw-r--r--doc/classes/TextServer.xml28
-rw-r--r--doc/classes/Theme.xml52
-rw-r--r--doc/classes/Window.xml2
-rwxr-xr-xdoc/tools/makerst.py7
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp160
-rw-r--r--drivers/vulkan/rendering_device_vulkan.h10
-rw-r--r--drivers/vulkan/vulkan_context.cpp56
-rw-r--r--drivers/vulkan/vulkan_context.h6
-rw-r--r--editor/action_map_editor.cpp3
-rw-r--r--editor/animation_track_editor.cpp6
-rw-r--r--editor/audio_stream_preview.h9
-rw-r--r--editor/connections_dialog.cpp2
-rw-r--r--editor/debugger/editor_performance_profiler.cpp2
-rw-r--r--editor/debugger/script_editor_debugger.cpp4
-rw-r--r--editor/dependency_editor.cpp2
-rw-r--r--editor/editor_about.cpp3
-rw-r--r--editor/editor_asset_installer.cpp38
-rw-r--r--editor/editor_asset_installer.h6
-rw-r--r--editor/editor_file_dialog.cpp21
-rw-r--r--editor/editor_fonts.cpp14
-rw-r--r--editor/editor_node.cpp76
-rw-r--r--editor/editor_plugin_settings.cpp4
-rw-r--r--editor/editor_properties.cpp158
-rw-r--r--editor/editor_properties.h25
-rw-r--r--editor/editor_resource_picker.cpp2
-rw-r--r--editor/editor_settings.cpp2
-rw-r--r--editor/editor_themes.cpp3
-rw-r--r--editor/editor_zoom_widget.cpp86
-rw-r--r--editor/editor_zoom_widget.h2
-rw-r--r--editor/export_template_manager.cpp5
-rw-r--r--editor/groups_editor.cpp10
-rw-r--r--editor/icons/ImmediateMesh.svg1
-rw-r--r--editor/icons/ORMMaterial3D.svg2
-rw-r--r--editor/import/scene_importer_mesh.cpp2
-rw-r--r--editor/localization_editor.cpp20
-rw-r--r--editor/node_dock.cpp2
-rw-r--r--editor/plugins/asset_library_editor_plugin.cpp5
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp34
-rw-r--r--editor/plugins/mesh_instance_3d_editor_plugin.cpp19
-rw-r--r--editor/plugins/mesh_instance_3d_editor_plugin.h1
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp61
-rw-r--r--editor/plugins/node_3d_editor_plugin.h4
-rw-r--r--editor/plugins/theme_editor_plugin.cpp294
-rw-r--r--editor/plugins/theme_editor_plugin.h55
-rw-r--r--editor/plugins/theme_editor_preview.cpp2
-rw-r--r--editor/plugins/version_control_editor_plugin.cpp1
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp137
-rw-r--r--editor/plugins/visual_shader_editor_plugin.h6
-rw-r--r--editor/project_export.cpp29
-rw-r--r--editor/property_editor.cpp2
-rw-r--r--editor/scene_tree_dock.cpp10
-rw-r--r--editor/scene_tree_editor.cpp10
-rw-r--r--editor/script_create_dialog.cpp6
-rw-r--r--editor/translations/af.po13
-rw-r--r--editor/translations/ar.po32
-rw-r--r--editor/translations/az.po23
-rw-r--r--editor/translations/bg.po13
-rw-r--r--editor/translations/bn.po23
-rw-r--r--editor/translations/br.po25
-rw-r--r--editor/translations/ca.po25
-rw-r--r--editor/translations/cs.po22
-rw-r--r--editor/translations/da.po23
-rw-r--r--editor/translations/de.po30
-rw-r--r--editor/translations/editor.pot13
-rw-r--r--editor/translations/el.po66
-rw-r--r--editor/translations/eo.po33
-rw-r--r--editor/translations/es.po79
-rw-r--r--editor/translations/es_AR.po25
-rw-r--r--editor/translations/et.po22
-rw-r--r--editor/translations/eu.po17
-rw-r--r--editor/translations/fa.po40
-rw-r--r--editor/translations/fi.po22
-rw-r--r--editor/translations/fil.po18
-rw-r--r--editor/translations/fr.po36
-rw-r--r--editor/translations/ga.po13
-rw-r--r--editor/translations/gl.po25
-rw-r--r--editor/translations/he.po21
-rw-r--r--editor/translations/hi.po21
-rw-r--r--editor/translations/hr.po21
-rw-r--r--editor/translations/hu.po25
-rw-r--r--editor/translations/id.po83
-rw-r--r--editor/translations/is.po13
-rw-r--r--editor/translations/it.po22
-rw-r--r--editor/translations/ja.po25
-rw-r--r--editor/translations/ka.po20
-rw-r--r--editor/translations/km.po13
-rw-r--r--editor/translations/ko.po25
-rw-r--r--editor/translations/lt.po16
-rw-r--r--editor/translations/lv.po22
-rw-r--r--editor/translations/mi.po13
-rw-r--r--editor/translations/mk.po13
-rw-r--r--editor/translations/ml.po13
-rw-r--r--editor/translations/mr.po13
-rw-r--r--editor/translations/ms.po23
-rw-r--r--editor/translations/nb.po23
-rw-r--r--editor/translations/nl.po22
-rw-r--r--editor/translations/or.po13
-rw-r--r--editor/translations/pl.po33
-rw-r--r--editor/translations/pr.po13
-rw-r--r--editor/translations/pt.po34
-rw-r--r--editor/translations/pt_BR.po24
-rw-r--r--editor/translations/ro.po25
-rw-r--r--editor/translations/ru.po30
-rw-r--r--editor/translations/si.po13
-rw-r--r--editor/translations/sk.po100
-rw-r--r--editor/translations/sl.po13
-rw-r--r--editor/translations/sq.po18
-rw-r--r--editor/translations/sr_Cyrl.po25
-rw-r--r--editor/translations/sr_Latn.po13
-rw-r--r--editor/translations/sv.po50
-rw-r--r--editor/translations/ta.po13
-rw-r--r--editor/translations/te.po13
-rw-r--r--editor/translations/th.po21
-rw-r--r--editor/translations/tr.po38
-rw-r--r--editor/translations/tt.po13
-rw-r--r--editor/translations/tzm.po13
-rw-r--r--editor/translations/uk.po25
-rw-r--r--editor/translations/ur_PK.po13
-rw-r--r--editor/translations/vi.po24
-rw-r--r--editor/translations/zh_CN.po123
-rw-r--r--editor/translations/zh_HK.po18
-rw-r--r--editor/translations/zh_TW.po30
-rw-r--r--main/main.cpp35
-rw-r--r--methods.py12
-rw-r--r--misc/dist/linux/godot.66
-rw-r--r--misc/dist/shell/_godot.zsh-completion2
-rw-r--r--misc/dist/shell/godot.bash-completion2
-rw-r--r--misc/dist/shell/godot.fish2
-rw-r--r--modules/basis_universal/register_types.cpp2
-rw-r--r--modules/csg/register_types.cpp18
-rw-r--r--modules/enet/config.py2
-rw-r--r--modules/enet/doc_classes/ENetMultiplayerPeer.xml (renamed from modules/enet/doc_classes/NetworkedMultiplayerENet.xml)14
-rw-r--r--modules/enet/enet_multiplayer_peer.cpp (renamed from modules/enet/networked_multiplayer_enet.cpp)164
-rw-r--r--modules/enet/enet_multiplayer_peer.h (renamed from modules/enet/networked_multiplayer_enet.h)14
-rw-r--r--modules/enet/register_types.cpp4
-rw-r--r--modules/fbx/register_types.cpp2
-rw-r--r--modules/gdnative/doc_classes/MultiplayerPeerGDNative.xml2
-rw-r--r--modules/gdnative/include/net/godot_net.h2
-rw-r--r--modules/gdnative/include/text/godot_text.h1
-rw-r--r--modules/gdnative/nativescript/godot_nativescript.cpp2
-rw-r--r--modules/gdnative/nativescript/nativescript.cpp13
-rw-r--r--modules/gdnative/nativescript/register_types.cpp2
-rw-r--r--modules/gdnative/net/multiplayer_peer_gdnative.cpp6
-rw-r--r--modules/gdnative/net/multiplayer_peer_gdnative.h8
-rw-r--r--modules/gdnative/net/register_types.cpp6
-rw-r--r--modules/gdnative/pluginscript/register_types.cpp2
-rw-r--r--modules/gdnative/register_types.cpp4
-rw-r--r--modules/gdnative/text/text_server_gdnative.cpp5
-rw-r--r--modules/gdnative/text/text_server_gdnative.h2
-rw-r--r--modules/gdnative/videodecoder/register_types.cpp2
-rw-r--r--modules/gdnative/xr/register_types.cpp2
-rw-r--r--modules/gdscript/gdscript.cpp2
-rw-r--r--modules/gdscript/language_server/gdscript_language_server.cpp6
-rw-r--r--modules/gdscript/language_server/gdscript_text_document.cpp6
-rw-r--r--modules/gdscript/language_server/gdscript_text_document.h1
-rw-r--r--modules/gdscript/register_types.cpp2
-rw-r--r--modules/gltf/register_types.cpp30
-rw-r--r--modules/gridmap/grid_map_editor_plugin.cpp2
-rw-r--r--modules/gridmap/register_types.cpp2
-rw-r--r--modules/jsonrpc/register_types.cpp2
-rw-r--r--modules/lightmapper_rd/register_types.cpp2
-rw-r--r--modules/minimp3/register_types.cpp2
-rw-r--r--modules/mobile_vr/register_types.cpp2
-rw-r--r--modules/mono/csharp_script.cpp16
-rw-r--r--modules/mono/glue/base_object_glue.cpp6
-rw-r--r--modules/mono/mono_gd/gd_mono_internals.cpp3
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.cpp3
-rw-r--r--modules/mono/register_types.cpp4
-rw-r--r--modules/navigation/register_types.cpp2
-rw-r--r--modules/opensimplex/register_types.cpp4
-rw-r--r--modules/regex/register_types.cpp4
-rw-r--r--modules/stb_vorbis/register_types.cpp2
-rw-r--r--modules/text_server_adv/text_server_adv.cpp155
-rw-r--r--modules/text_server_adv/text_server_adv.h2
-rw-r--r--modules/text_server_fb/text_server_fb.cpp155
-rw-r--r--modules/text_server_fb/text_server_fb.h2
-rw-r--r--modules/theora/register_types.cpp2
-rw-r--r--modules/upnp/register_types.cpp4
-rw-r--r--modules/vhacd/register_types.cpp8
-rw-r--r--modules/visual_script/register_types.cpp98
-rw-r--r--modules/visual_script/visual_script.cpp2
-rw-r--r--modules/visual_script/visual_script_editor.cpp2
-rw-r--r--modules/webm/register_types.cpp2
-rw-r--r--modules/webrtc/config.py2
-rw-r--r--modules/webrtc/doc_classes/WebRTCMultiplayerPeer.xml (renamed from modules/webrtc/doc_classes/WebRTCMultiplayer.xml)12
-rw-r--r--modules/webrtc/register_types.cpp10
-rw-r--r--modules/webrtc/webrtc_multiplayer_peer.cpp (renamed from modules/webrtc/webrtc_multiplayer.cpp)72
-rw-r--r--modules/webrtc/webrtc_multiplayer_peer.h (renamed from modules/webrtc/webrtc_multiplayer.h)14
-rw-r--r--modules/websocket/doc_classes/WebSocketClient.xml2
-rw-r--r--modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml4
-rw-r--r--modules/websocket/doc_classes/WebSocketServer.xml2
-rw-r--r--modules/websocket/emws_client.cpp2
-rw-r--r--modules/websocket/register_types.cpp2
-rw-r--r--modules/websocket/websocket_multiplayer_peer.cpp4
-rw-r--r--modules/websocket/websocket_multiplayer_peer.h8
-rw-r--r--modules/websocket/websocket_server.cpp2
-rw-r--r--modules/websocket/wsl_client.cpp2
-rw-r--r--modules/webxr/register_types.cpp2
-rw-r--r--platform/android/api/api.cpp6
-rw-r--r--platform/android/display_server_android.cpp25
-rw-r--r--platform/android/display_server_android.h6
-rw-r--r--platform/android/java_godot_lib_jni.cpp2
-rw-r--r--platform/android/vulkan/vulkan_context_android.cpp4
-rw-r--r--platform/android/vulkan/vulkan_context_android.h2
-rw-r--r--platform/iphone/display_server_iphone.h7
-rw-r--r--platform/iphone/display_server_iphone.mm24
-rw-r--r--platform/iphone/export/export.cpp2
-rw-r--r--platform/iphone/vulkan_context_iphone.h2
-rw-r--r--platform/iphone/vulkan_context_iphone.mm4
-rw-r--r--platform/javascript/api/api.cpp4
-rw-r--r--platform/javascript/detect.py3
-rw-r--r--platform/linuxbsd/display_server_x11.cpp32
-rw-r--r--platform/linuxbsd/display_server_x11.h11
-rw-r--r--platform/linuxbsd/freedesktop_screensaver.cpp3
-rw-r--r--platform/linuxbsd/vulkan_context_x11.cpp4
-rw-r--r--platform/linuxbsd/vulkan_context_x11.h2
-rw-r--r--platform/osx/display_server_osx.h11
-rw-r--r--platform/osx/display_server_osx.mm32
-rw-r--r--platform/osx/export/export.cpp31
-rw-r--r--platform/osx/vulkan_context_osx.h2
-rw-r--r--platform/osx/vulkan_context_osx.mm4
-rw-r--r--platform/windows/context_gl_windows.cpp36
-rw-r--r--platform/windows/context_gl_windows.h3
-rw-r--r--platform/windows/display_server_windows.cpp32
-rw-r--r--platform/windows/display_server_windows.h14
-rw-r--r--platform/windows/vulkan_context_win.cpp5
-rw-r--r--platform/windows/vulkan_context_win.h2
-rw-r--r--scene/3d/decal.cpp27
-rw-r--r--scene/3d/decal.h2
-rw-r--r--scene/3d/mesh_instance_3d.cpp10
-rw-r--r--scene/3d/mesh_instance_3d.h4
-rw-r--r--scene/animation/animation_blend_space_2d.cpp4
-rw-r--r--scene/gui/box_container.cpp1
-rw-r--r--scene/gui/control.cpp84
-rw-r--r--scene/gui/control.h8
-rw-r--r--scene/gui/dialogs.cpp4
-rw-r--r--scene/gui/label.cpp127
-rw-r--r--scene/gui/label.h27
-rw-r--r--scene/gui/tree.cpp62
-rw-r--r--scene/main/node.cpp4
-rw-r--r--scene/main/node.h2
-rw-r--r--scene/main/scene_tree.cpp87
-rw-r--r--scene/main/scene_tree.h17
-rw-r--r--scene/main/window.cpp56
-rw-r--r--scene/main/window.h7
-rw-r--r--scene/register_scene_types.cpp943
-rw-r--r--scene/resources/default_theme/default_theme.cpp11
-rw-r--r--scene/resources/default_theme/default_theme.h2
-rw-r--r--scene/resources/mesh.cpp31
-rw-r--r--scene/resources/mesh.h6
-rw-r--r--scene/resources/primitive_meshes.cpp37
-rw-r--r--scene/resources/primitive_meshes.h8
-rw-r--r--scene/resources/theme.cpp149
-rw-r--r--scene/resources/theme.h12
-rw-r--r--scene/resources/visual_shader.cpp22
-rw-r--r--scene/resources/visual_shader.h1
-rw-r--r--scene/resources/visual_shader_nodes.cpp86
-rw-r--r--scene/resources/visual_shader_nodes.h33
-rw-r--r--servers/display_server.cpp49
-rw-r--r--servers/display_server.h33
-rw-r--r--servers/display_server_headless.h2
-rw-r--r--servers/register_server_types.cpp159
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp4
-rw-r--r--servers/rendering/renderer_viewport.cpp8
-rw-r--r--servers/rendering/renderer_viewport.h4
-rw-r--r--servers/rendering/rendering_device.cpp45
-rw-r--r--servers/rendering/rendering_device.h35
-rw-r--r--servers/rendering/rendering_device_binds.h35
-rw-r--r--servers/rendering/rendering_server_default.h2
-rw-r--r--servers/rendering_server.h2
-rw-r--r--servers/text_server.cpp21
-rw-r--r--servers/text_server.h18
-rw-r--r--tests/test_object.h4
-rw-r--r--thirdparty/README.md5
-rw-r--r--thirdparty/spirv-reflect/patches/specialization-constants.patch293
-rw-r--r--thirdparty/spirv-reflect/spirv_reflect.c139
-rw-r--r--thirdparty/spirv-reflect/spirv_reflect.h53
322 files changed, 5617 insertions, 3053 deletions
diff --git a/AUTHORS.md b/AUTHORS.md
index 0aacde20e8..c5a971b345 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -28,6 +28,7 @@ name is available.
(in alphabetical order, with over 10 commits excluding merges)
Aaron Franke (aaronfranke)
+ Aaron Record (LightningAA)
Alexander Holland (AlexHolly)
Alexey Khoroshavin (allkhor)
Alket Rexhepi (alketii)
@@ -182,6 +183,7 @@ name is available.
Stijn Hinlopen (hinlopen)
Swarnim Arun (minraws)
Thakee Nathees (ThakeeNathees)
+ thebestnom
Theo Hallenius (TheoXD)
Thomas Herzog (karroffel)
Timo Schwarzer (timoschwarzer)
diff --git a/DONORS.md b/DONORS.md
index 6f359d4b6c..d31b15fa5a 100644
--- a/DONORS.md
+++ b/DONORS.md
@@ -40,13 +40,11 @@ generous deed immortalized in the next stable release of Godot Engine.
## Mini sponsors
AD Ford
- Alejandro Saucedo
alex brown
Andrew Dunai
Angry Skull
anti666
blurp
- CD
Christian Baune
Christoffer Sundbom
Christopher Montesano
@@ -85,6 +83,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Slobodan Milnovic
Stephan Lanfermann
Steve
+ Stonesoft io
Thomas Krampl
Tristan Pemble
Violin Iliev
@@ -101,12 +100,10 @@ generous deed immortalized in the next stable release of Godot Engine.
Barugon
Carlo Cabanilla
Chris Goddard
- Christopher Case
Daniel James
David Gehrig
David Snopek
Don B
- Ealthy Studio
Ed Morley
Ellen Poe
Florian Rämisch
@@ -120,7 +117,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Klavdij Voncina
kuku
Lex Steers
- Luke
Maciej Pendolski
Manuele Finocchiaro
Markus Wiesner
@@ -176,7 +172,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Chris Petrich
Chris Serino
Christian Leth Jeppesen
- Container7
+ Cow
Craig Ostrin
Craig Smith
Cristopher
@@ -187,7 +183,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Darrian Little
Dennis Belfrage
Dev To be curious
- Dietrich Schuetz
Digital Denizen
Dimitri Nüscheler
Donn Eddy
@@ -200,15 +195,16 @@ generous deed immortalized in the next stable release of Godot Engine.
flesk
foxydevloper
Fransiska
- F S
Gabrielius Vaiškūnas
Gary Hulst
gavlig
General Chicken
Geoffroy Warin
GGGames.org
+ GrayDwarf
Guilherme Felipe de C. G. da Silva
Harvey Fong
+ Hayden Whitehead
Heath Hayes
Horváth Péter
Hu Hund
@@ -241,12 +237,12 @@ generous deed immortalized in the next stable release of Godot Engine.
kinfox
Kis Levente Lorand
Kos
- Lachie
Lain Ballard
Laszlo Kiss
leetNightshade
Leo Fidel R Liban
Liam Smyth
+ LoparPanda
Luca Vazzano
Luc-Frédéric Langis
MadScientistCarl
@@ -259,6 +255,7 @@ generous deed immortalized in the next stable release of Godot Engine.
matt
Matt Greene
Matthias Toepp
+ Mecha Kaiju X
medecau
Michael
Michael Bordießer-Krauth
@@ -266,6 +263,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Michael Policastro
MightyPossum
MikadoSC
+ minz1
MuffinManKen
nate etan
Nick Abousselam
@@ -288,7 +286,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Rhodochrone
Ricardo Alcantara
Rob
- Robert Larnach
Robert McDermott
Robert Willes
Rob McInroy
@@ -299,6 +296,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Ronny Mühle
Ryan Scott
Samuel Judd
+ Samuel Smart
Sean Morgan
Sebastian Hutter
Sébastien
@@ -325,9 +323,11 @@ generous deed immortalized in the next stable release of Godot Engine.
Turntsnaco
tweaklab
Valryia
+ VikFro
Vincent Cloutier
Vlad Ceru Opran
VoidPointer
+ Vramexon
Winston
Wojciech Chojnacki
xzibiting
@@ -366,7 +366,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Alexander Walter (SilvanuZ)
Alexandre Beaudoin
Alex Chan
- alex clavelle
+ Alex Clavelle
alex raeside
Alex (Well Done Games)
Allan Davis
@@ -376,7 +376,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Anders Marstein Kruke
Andre Stackhouse
andrew james morris
- Andrew Mansuetti
Andrew Thomas
Ano Nim
Anthony Avina
@@ -416,6 +415,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Burney Waring
bwhirt
Caleb Gartner
+ Caleb Makela
Cameron Meyer
Carlos Cejudo
Carl van der Geest
@@ -433,15 +433,14 @@ generous deed immortalized in the next stable release of Godot Engine.
Christoffer Dahlblom
Christophe Gagnier
Christopher Chin
- Christopher Schmitt
Chris Truebe
- Clay Heaton
Cody Parker
Conall O
Conner Lane
Corchari
Craig Maloney
Craig Post
+ damucz
Daniel Cheney
Daniel Johnson
Daren Scot Wilson
@@ -450,7 +449,6 @@ generous deed immortalized in the next stable release of Godot Engine.
David Bôle
David May
David Maziarka
- David Woodard
deadwithbread
Devin Carraway
Diego Pereira
@@ -487,10 +485,10 @@ generous deed immortalized in the next stable release of Godot Engine.
Francois Holland
Frank
Game Endeavor
- Gareth Knowles
Gary Thomas
George Marques
- georgios katsanakis
+ Georgi Petkov
+ Graham Overby
Greg Lincoln
Greg Olson
Greyson Richey
@@ -500,10 +498,11 @@ generous deed immortalized in the next stable release of Godot Engine.
Guillaume Pham Ngoc
Guldoman
Hal A
+ Hayden Foley
Heribert Hirth
- Hoojib
Houdini Blueprints
Hunter Jones
+ Ian ORourke
Ian Williams
Iiari
IndustrialRobot
@@ -512,7 +511,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Jackson Harmer
Jacob D
Jaguar
- Jaime Ruiz-Borau Vizárraga
Jake D
Jake Huxell
Jako Danar
@@ -529,15 +527,19 @@ generous deed immortalized in the next stable release of Godot Engine.
Jason Bolton
Jason Malcolm-Herzmark
Jason Uechi
+ Jeferson R. P. Belmiro
Jeff Hungerford
+ Jeff Messer
Jeffrey Berube
Jennifer Graves
+ JernauGurgeh
Jesse Dubay
Jim Engstrand
Joe Klemmer
Joel Höglund
John Bruce
John Gabriel
+ John Szevin
Jonah Branch
Jonas
Jonas Bernemann
@@ -546,8 +548,8 @@ generous deed immortalized in the next stable release of Godot Engine.
Jonatan R
Jonathan Bieber
Jonathan G
+ Jonathan Wright
Jon Bonazza
- Jon Oakes
Jon Sully
Jordan West
Jordy Goodridge
@@ -555,11 +557,11 @@ generous deed immortalized in the next stable release of Godot Engine.
Jorge Araya Navarro
Jose C. Rubio
Joseph Catrambone
- Josep Sanchez
Josh Taylor
Joshua Heidrich
jromkjrom
Juanfran
+ Juan Maggi
Juan Uys
Jueast
Julian Murgia
@@ -569,7 +571,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Justin Spedding
Justin W. Flory
KaDokta
- Kalin
Keedong Park
Keinan Powers
Keith Bradner
@@ -581,9 +582,12 @@ generous deed immortalized in the next stable release of Godot Engine.
Kevin van Rooijen
Kiri Jolly
Kjetil Haugland
+ Kolandrious
Konstantin Goncharov
+ kormai
Krishna Nadoor
Kristian Nygaard Jensen
+ KR McGinley
Kronarq
KsyTek Games
kycho
@@ -595,16 +599,17 @@ generous deed immortalized in the next stable release of Godot Engine.
Laurent CHEA
Laurent Tréguier
Laxman Pradhan
+ LE BOURHIS
LEMMiNO
Leonardo Dimano
Lin Chear
Linus Lind Lundgren
+ Ludovic DELVAL
Luigi Renna
Luis Gaemperle
Luis M
LunaticInAHat
Major Haul
- makoto asano
Malcolm
Marco Lardelli
Mark Jad
@@ -613,20 +618,21 @@ generous deed immortalized in the next stable release of Godot Engine.
Markus Michael Egger
Martin FIbik
Martin Holas
+ Martin Liška
Martin Trbola
Marvin
Mathieu
Matt Edwards
Matthew Booe
Matt Sylvia
- Maverick C.
Max Fiedler
Maxime Blade
Maxwell
- Mecha Kaiju X
+ MC
Melissa Mears
Merlyn Morgan-Graham
mewin
+ mhilbrunner
Michael
Michael Bruce-Lockhart
Michael Haney
@@ -665,12 +671,12 @@ generous deed immortalized in the next stable release of Godot Engine.
Nicolas Rosset
Nicolas SAN AGUSTIN
Nima Farid
+ Noel Billig
+ Nuno Dionísio
NZ
oceoh
Okatima
- OKV
Oleg Reva
- Oleksandr Kryvonos
Olle Soprani
Omar Delarosa
Oriol Muñoz Princep
@@ -690,23 +696,26 @@ generous deed immortalized in the next stable release of Godot Engine.
Point08
Preethi Vaidyanathan
pwab
+ RabidTunes
Rackat
Rad Cat
Rafa Laguna
Raffaele Aramo
Rainer Amler
Rami Hanano
+ Rammeow
RAMupgrade
Remi Rampin
Rémi Verschelde
Reneator
Riccardo Marini
+ Richard Hayes
Richard Ivánek
Richard Néveri
Riley
Robert Farr (Larington)
Rob Ruana
- Roger Smith
+ Rodrigo Loli
Roland RzÄ…sa
Roman Tinkov
Ronald Ho Hip (CrimsonZA)
@@ -719,13 +728,10 @@ generous deed immortalized in the next stable release of Godot Engine.
Sean Lynch
Sebastian Michailidis
SeongWan Kim
- Sergey
SeungJong k
Shaidak
Shane
- Shane Sicienski
Shane Spoor
- Siim Raidma
simdee
Simon Jonas Larsen
Simon Schoenenberger
@@ -763,7 +769,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Toadile
Tobias Bradtke
Tom Coxon
- Toni Duran
Torgeir Lilleskog
Torsten Crass
toupeira
@@ -778,16 +783,14 @@ generous deed immortalized in the next stable release of Godot Engine.
Tyler Stafos
UltyX
Uther
+ v01tech
Vaughan Ling
Victor
- Viktor Ismagilov
+ Vincent Foulon
Vi Watch
Vladimir Savin
Vladislav Smirnov
- Vojtěch
Vytenis Narušis
- waka nya
- Wayne Haak
werner mendizabal
Wiley Thompson
William Edwards
diff --git a/SConstruct b/SConstruct
index 8b37bb8285..601b2d6e80 100644
--- a/SConstruct
+++ b/SConstruct
@@ -142,6 +142,7 @@ opts.Add("extra_suffix", "Custom extra suffix added to the base filename of all
opts.Add(BoolVariable("vsproj", "Generate a Visual Studio solution", False))
opts.Add(BoolVariable("disable_3d", "Disable 3D nodes for a smaller executable", False))
opts.Add(BoolVariable("disable_advanced_gui", "Disable advanced GUI nodes and behaviors", False))
+opts.Add("disable_classes", "Disable given classes (comma separated)", "")
opts.Add(BoolVariable("modules_enabled_by_default", "If no, disable all modules except ones explicitly enabled", True))
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)", "")
@@ -642,6 +643,7 @@ if selected_platform in platform_list:
if env["tools"]:
env.Append(CPPDEFINES=["TOOLS_ENABLED"])
+ methods.write_disabled_classes(env["disable_classes"].split(","))
if env["disable_3d"]:
if env["tools"]:
print(
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp
index 25506e8db3..ac4e0db5b7 100644
--- a/core/config/project_settings.cpp
+++ b/core/config/project_settings.cpp
@@ -1114,6 +1114,8 @@ ProjectSettings::ProjectSettings() {
// Keep the enum values in sync with the `DisplayServer::ScreenOrientation` enum.
custom_prop_info["display/window/handheld/orientation"] = PropertyInfo(Variant::INT, "display/window/handheld/orientation", PROPERTY_HINT_ENUM, "Landscape,Portrait,Reverse Landscape,Reverse Portrait,Sensor Landscape,Sensor Portrait,Sensor");
+ // Keep the enum values in sync with the `DisplayServer::VSyncMode` enum.
+ custom_prop_info["display/window/vsync/vsync_mode"] = PropertyInfo(Variant::INT, "display/window/vsync/vsync_mode", PROPERTY_HINT_ENUM, "Disabled,Enabled,Adaptive,Mailbox");
custom_prop_info["rendering/driver/threads/thread_model"] = PropertyInfo(Variant::INT, "rendering/driver/threads/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded");
GLOBAL_DEF("physics/2d/run_on_thread", false);
GLOBAL_DEF("physics/3d/run_on_thread", false);
diff --git a/core/core_bind.cpp b/core/core_bind.cpp
index a3349444c4..9a58528bd7 100644
--- a/core/core_bind.cpp
+++ b/core/core_bind.cpp
@@ -1729,10 +1729,11 @@ void _Thread::_start_func(void *ud) {
memdelete(tud);
Callable::CallError ce;
const Variant *arg[1] = { &t->userdata };
+ int argc = (int)(arg[0]->get_type() != Variant::NIL);
Thread::set_name(t->target_method);
- t->ret = t->target_instance->call(t->target_method, arg, 1, ce);
+ t->ret = t->target_instance->call(t->target_method, arg, argc, ce);
if (ce.error != Callable::CallError::CALL_OK) {
String reason;
switch (ce.error) {
diff --git a/core/core_constants.cpp b/core/core_constants.cpp
index 0aad21276a..de15cfd14a 100644
--- a/core/core_constants.cpp
+++ b/core/core_constants.cpp
@@ -509,6 +509,7 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_NONE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_RANGE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_ENUM);
+ BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_ENUM_SUGGESTION);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_EXP_EASING);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LENGTH);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_KEY_ACCEL);
diff --git a/core/extension/gdnative_interface.cpp b/core/extension/gdnative_interface.cpp
index 324933d7b7..8f68b8d848 100644
--- a/core/extension/gdnative_interface.cpp
+++ b/core/extension/gdnative_interface.cpp
@@ -520,6 +520,11 @@ static GDNativeObjectPtr gdnative_global_get_singleton(const char *p_name) {
return (GDNativeObjectPtr)Engine::get_singleton()->get_singleton_object(String(p_name));
}
+static void *gdnative_object_get_instance_binding(GDNativeObjectPtr p_instance, void *p_token, GDNativeInstanceBindingCallbacks *p_callbacks) {
+ Object *o = (Object *)p_instance;
+ return o->get_instance_binding(p_token, p_callbacks);
+}
+
static GDNativeObjectPtr gdnative_object_get_instance_from_id(GDObjectInstanceID p_instance_id) {
return (GDNativeObjectPtr)ObjectDB::get_instance(ObjectID(p_instance_id));
}
@@ -665,6 +670,7 @@ void gdnative_setup_interface(GDNativeInterface *p_interface) {
gdni.object_method_bind_ptrcall = gdnative_object_method_bind_ptrcall;
gdni.object_destroy = gdnative_object_destroy;
gdni.global_get_singleton = gdnative_global_get_singleton;
+ gdni.object_get_instance_binding = gdnative_object_get_instance_binding;
gdni.object_cast_to = gdnative_object_cast_to;
gdni.object_get_instance_from_id = gdnative_object_get_instance_from_id;
diff --git a/core/extension/gdnative_interface.h b/core/extension/gdnative_interface.h
index 318912e889..c1ebb3e76a 100644
--- a/core/extension/gdnative_interface.h
+++ b/core/extension/gdnative_interface.h
@@ -171,6 +171,16 @@ typedef void (*GDNativePtrUtilityFunction)(GDNativeTypePtr r_return, const GDNat
typedef GDNativeObjectPtr (*GDNativeClassConstructor)();
+typedef void *(*GDNativeInstanceBindingCreateCallback)(void *p_token, void *p_instance);
+typedef void (*GDNativeInstanceBindingFreeCallback)(void *p_token, void *p_instance, void *p_binding);
+typedef GDNativeBool (*GDNativeInstanceBindingReferenceCallback)(void *p_token, void *p_instance, GDNativeBool p_reference);
+
+struct GDNativeInstanceBindingCallbacks {
+ GDNativeInstanceBindingCreateCallback create_callback;
+ GDNativeInstanceBindingFreeCallback free_callback;
+ GDNativeInstanceBindingReferenceCallback reference_callback;
+};
+
/* EXTENSION CLASSES */
typedef void *GDExtensionClassInstancePtr;
@@ -373,6 +383,7 @@ typedef struct {
void (*object_method_bind_ptrcall)(GDNativeMethodBindPtr p_method_bind, GDNativeObjectPtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret);
void (*object_destroy)(GDNativeObjectPtr p_o);
GDNativeObjectPtr (*global_get_singleton)(const char *p_name);
+ void *(*object_get_instance_binding)(GDNativeObjectPtr p_o, void *p_token, GDNativeInstanceBindingCallbacks *p_callbacks);
GDNativeObjectPtr (*object_cast_to)(const GDNativeObjectPtr p_object, void *p_class_tag);
GDNativeObjectPtr (*object_get_instance_from_id)(GDObjectInstanceID p_instance_id);
diff --git a/core/io/compression.cpp b/core/io/compression.cpp
index 6de626db99..790b6febc0 100644
--- a/core/io/compression.cpp
+++ b/core/io/compression.cpp
@@ -134,8 +134,9 @@ int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p
if (p_dst_max_size < 16) {
uint8_t dst[16];
- ret_size = fastlz_decompress(p_src, p_src_size, dst, 16);
+ fastlz_decompress(p_src, p_src_size, dst, 16);
memcpy(p_dst, dst, p_dst_max_size);
+ ret_size = p_dst_max_size;
} else {
ret_size = fastlz_decompress(p_src, p_src_size, p_dst, p_dst_max_size);
}
@@ -238,7 +239,10 @@ int Compression::decompress_dynamic(Vector<uint8_t> *p_dst_vect, int p_max_dst_s
case Z_DATA_ERROR:
case Z_MEM_ERROR:
case Z_STREAM_ERROR:
- WARN_PRINT(strm.msg);
+ case Z_BUF_ERROR:
+ if (strm.msg) {
+ WARN_PRINT(strm.msg);
+ }
(void)inflateEnd(&strm);
p_dst_vect->resize(0);
return ret;
diff --git a/core/io/http_client_tcp.cpp b/core/io/http_client_tcp.cpp
index f9b3165a07..f291086808 100644
--- a/core/io/http_client_tcp.cpp
+++ b/core/io/http_client_tcp.cpp
@@ -590,6 +590,7 @@ PackedByteArray HTTPClientTCP::read_response_body_chunk() {
}
}
if (err != OK) {
+ ret.resize(_offset);
break;
}
}
diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp
index 51ba8800e4..564397c88c 100644
--- a/core/io/multiplayer_api.cpp
+++ b/core/io/multiplayer_api.cpp
@@ -85,7 +85,7 @@ const MultiplayerAPI::RPCConfig _get_rpc_config_by_id(Node *p_node, uint16_t p_i
if (id & (1 << 15)) {
id = id & ~(1 << 15);
config = p_node->get_node_rpc_methods();
- } else {
+ } else if (p_node->get_script_instance()) {
config = p_node->get_script_instance()->get_rpc_methods();
}
if (id < config.size()) {
@@ -149,7 +149,7 @@ _FORCE_INLINE_ bool _can_call_mode(Node *p_node, MultiplayerAPI::RPCMode mode, i
}
void MultiplayerAPI::poll() {
- if (!network_peer.is_valid() || network_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED) {
+ if (!network_peer.is_valid() || network_peer->get_connection_status() == MultiplayerPeer::CONNECTION_DISCONNECTED) {
return;
}
@@ -196,13 +196,13 @@ Node *MultiplayerAPI::get_root_node() {
return root_node;
}
-void MultiplayerAPI::set_network_peer(const Ref<NetworkedMultiplayerPeer> &p_peer) {
+void MultiplayerAPI::set_network_peer(const Ref<MultiplayerPeer> &p_peer) {
if (p_peer == network_peer) {
return; // Nothing to do
}
- ERR_FAIL_COND_MSG(p_peer.is_valid() && p_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED,
- "Supplied NetworkedMultiplayerPeer must be connecting or connected.");
+ ERR_FAIL_COND_MSG(p_peer.is_valid() && p_peer->get_connection_status() == MultiplayerPeer::CONNECTION_DISCONNECTED,
+ "Supplied MultiplayerPeer must be connecting or connected.");
if (network_peer.is_valid()) {
network_peer->disconnect("peer_connected", callable_mp(this, &MultiplayerAPI::_add_peer));
@@ -224,7 +224,7 @@ void MultiplayerAPI::set_network_peer(const Ref<NetworkedMultiplayerPeer> &p_pee
}
}
-Ref<NetworkedMultiplayerPeer> MultiplayerAPI::get_network_peer() const {
+Ref<MultiplayerPeer> MultiplayerAPI::get_network_peer() const {
return network_peer;
}
@@ -513,7 +513,7 @@ void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet,
packet.write[1] = valid_rpc_checksum;
encode_cstring(pname.get_data(), &packet.write[2]);
- network_peer->set_transfer_mode(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
+ network_peer->set_transfer_mode(MultiplayerPeer::TRANSFER_MODE_RELIABLE);
network_peer->set_target_peer(p_from);
network_peer->put_packet(packet.ptr(), packet.size());
}
@@ -592,7 +592,7 @@ bool MultiplayerAPI::_send_confirm_path(Node *p_node, NodePath p_path, PathSentC
for (List<int>::Element *E = peers_to_add.front(); E; E = E->next()) {
network_peer->set_target_peer(E->get()); // To all of you.
- network_peer->set_transfer_mode(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
+ network_peer->set_transfer_mode(MultiplayerPeer::TRANSFER_MODE_RELIABLE);
network_peer->put_packet(packet.ptr(), packet.size());
psc->confirmed_peers.insert(E->get(), false); // Insert into confirmed, but as false since it was not confirmed.
@@ -760,9 +760,9 @@ Error MultiplayerAPI::_decode_and_decompress_variant(Variant &r_variant, const u
void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, const RPCConfig &p_config, const StringName &p_name, const Variant **p_arg, int p_argcount) {
ERR_FAIL_COND_MSG(network_peer.is_null(), "Attempt to remote call/set when networking is not active in SceneTree.");
- ERR_FAIL_COND_MSG(network_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_CONNECTING, "Attempt to remote call/set when networking is not connected yet in SceneTree.");
+ ERR_FAIL_COND_MSG(network_peer->get_connection_status() == MultiplayerPeer::CONNECTION_CONNECTING, "Attempt to remote call/set when networking is not connected yet in SceneTree.");
- ERR_FAIL_COND_MSG(network_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED, "Attempt to remote call/set when networking is disconnected.");
+ ERR_FAIL_COND_MSG(network_peer->get_connection_status() == MultiplayerPeer::CONNECTION_DISCONNECTED, "Attempt to remote call/set when networking is disconnected.");
ERR_FAIL_COND_MSG(p_argcount > 255, "Too many arguments >255.");
@@ -974,7 +974,7 @@ void MultiplayerAPI::_server_disconnected() {
void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_method, const Variant **p_arg, int p_argcount) {
ERR_FAIL_COND_MSG(!network_peer.is_valid(), "Trying to call an RPC while no network peer is active.");
ERR_FAIL_COND_MSG(!p_node->is_inside_tree(), "Trying to call an RPC on a node which is not inside SceneTree.");
- ERR_FAIL_COND_MSG(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED, "Trying to call an RPC via a network peer which is not connected.");
+ ERR_FAIL_COND_MSG(network_peer->get_connection_status() != MultiplayerPeer::CONNECTION_CONNECTED, "Trying to call an RPC via a network peer which is not connected.");
int node_id = network_peer->get_unique_id();
bool skip_rpc = node_id == p_peer_id;
@@ -1033,10 +1033,10 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const
ERR_FAIL_COND_MSG(skip_rpc && !(call_local_native || call_local_script), "RPC '" + p_method + "' on yourself is not allowed by selected mode.");
}
-Error MultiplayerAPI::send_bytes(Vector<uint8_t> p_data, int p_to, NetworkedMultiplayerPeer::TransferMode p_mode) {
+Error MultiplayerAPI::send_bytes(Vector<uint8_t> p_data, int p_to, MultiplayerPeer::TransferMode p_mode) {
ERR_FAIL_COND_V_MSG(p_data.size() < 1, ERR_INVALID_DATA, "Trying to send an empty raw packet.");
ERR_FAIL_COND_V_MSG(!network_peer.is_valid(), ERR_UNCONFIGURED, "Trying to send a raw packet while no network peer is active.");
- ERR_FAIL_COND_V_MSG(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED, ERR_UNCONFIGURED, "Trying to send a raw packet via a network peer which is not connected.");
+ ERR_FAIL_COND_V_MSG(network_peer->get_connection_status() != MultiplayerPeer::CONNECTION_CONNECTED, ERR_UNCONFIGURED, "Trying to send a raw packet via a network peer which is not connected.");
MAKE_ROOM(p_data.size() + 1);
const uint8_t *r = p_data.ptr();
@@ -1105,7 +1105,7 @@ bool MultiplayerAPI::is_object_decoding_allowed() const {
void MultiplayerAPI::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_root_node", "node"), &MultiplayerAPI::set_root_node);
ClassDB::bind_method(D_METHOD("get_root_node"), &MultiplayerAPI::get_root_node);
- ClassDB::bind_method(D_METHOD("send_bytes", "bytes", "id", "mode"), &MultiplayerAPI::send_bytes, DEFVAL(NetworkedMultiplayerPeer::TARGET_PEER_BROADCAST), DEFVAL(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE));
+ ClassDB::bind_method(D_METHOD("send_bytes", "bytes", "id", "mode"), &MultiplayerAPI::send_bytes, DEFVAL(MultiplayerPeer::TARGET_PEER_BROADCAST), DEFVAL(MultiplayerPeer::TRANSFER_MODE_RELIABLE));
ClassDB::bind_method(D_METHOD("has_network_peer"), &MultiplayerAPI::has_network_peer);
ClassDB::bind_method(D_METHOD("get_network_peer"), &MultiplayerAPI::get_network_peer);
ClassDB::bind_method(D_METHOD("get_network_unique_id"), &MultiplayerAPI::get_network_unique_id);
@@ -1123,7 +1123,7 @@ void MultiplayerAPI::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_object_decoding"), "set_allow_object_decoding", "is_object_decoding_allowed");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "refuse_new_network_connections"), "set_refuse_new_network_connections", "is_refusing_new_network_connections");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "network_peer", PROPERTY_HINT_RESOURCE_TYPE, "NetworkedMultiplayerPeer", PROPERTY_USAGE_NONE), "set_network_peer", "get_network_peer");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "network_peer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerPeer", PROPERTY_USAGE_NONE), "set_network_peer", "get_network_peer");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "root_node", PROPERTY_HINT_RESOURCE_TYPE, "Node", PROPERTY_USAGE_NONE), "set_root_node", "get_root_node");
ADD_PROPERTY_DEFAULT("refuse_new_network_connections", false);
diff --git a/core/io/multiplayer_api.h b/core/io/multiplayer_api.h
index 43804a20ec..e9f96383c9 100644
--- a/core/io/multiplayer_api.h
+++ b/core/io/multiplayer_api.h
@@ -31,7 +31,7 @@
#ifndef MULTIPLAYER_API_H
#define MULTIPLAYER_API_H
-#include "core/io/networked_multiplayer_peer.h"
+#include "core/io/multiplayer_peer.h"
#include "core/object/ref_counted.h"
class MultiplayerAPI : public RefCounted {
@@ -51,7 +51,7 @@ public:
struct RPCConfig {
StringName name;
RPCMode rpc_mode = RPC_MODE_DISABLED;
- NetworkedMultiplayerPeer::TransferMode transfer_mode = NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE;
+ MultiplayerPeer::TransferMode transfer_mode = MultiplayerPeer::TRANSFER_MODE_RELIABLE;
int channel = 0;
bool operator==(RPCConfig const &p_other) const {
@@ -83,7 +83,7 @@ private:
Map<int, NodeInfo> nodes;
};
- Ref<NetworkedMultiplayerPeer> network_peer;
+ Ref<MultiplayerPeer> network_peer;
int rpc_sender_id = 0;
Set<int> connected_peers;
HashMap<NodePath, PathSentCache> path_send_cache;
@@ -132,9 +132,9 @@ public:
void clear();
void set_root_node(Node *p_node);
Node *get_root_node();
- void set_network_peer(const Ref<NetworkedMultiplayerPeer> &p_peer);
- Ref<NetworkedMultiplayerPeer> get_network_peer() const;
- Error send_bytes(Vector<uint8_t> p_data, int p_to = NetworkedMultiplayerPeer::TARGET_PEER_BROADCAST, NetworkedMultiplayerPeer::TransferMode p_mode = NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
+ void set_network_peer(const Ref<MultiplayerPeer> &p_peer);
+ Ref<MultiplayerPeer> get_network_peer() const;
+ Error send_bytes(Vector<uint8_t> p_data, int p_to = MultiplayerPeer::TARGET_PEER_BROADCAST, MultiplayerPeer::TransferMode p_mode = MultiplayerPeer::TRANSFER_MODE_RELIABLE);
// Called by Node.rpc
void rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_method, const Variant **p_arg, int p_argcount);
diff --git a/core/io/networked_multiplayer_peer.cpp b/core/io/multiplayer_peer.cpp
index b6af046e77..8126b4cea3 100644
--- a/core/io/networked_multiplayer_peer.cpp
+++ b/core/io/multiplayer_peer.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* networked_multiplayer_peer.cpp */
+/* multiplayer_peer.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,22 +28,22 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "networked_multiplayer_peer.h"
+#include "multiplayer_peer.h"
-void NetworkedMultiplayerPeer::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_transfer_mode", "mode"), &NetworkedMultiplayerPeer::set_transfer_mode);
- ClassDB::bind_method(D_METHOD("get_transfer_mode"), &NetworkedMultiplayerPeer::get_transfer_mode);
- ClassDB::bind_method(D_METHOD("set_target_peer", "id"), &NetworkedMultiplayerPeer::set_target_peer);
+void MultiplayerPeer::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_transfer_mode", "mode"), &MultiplayerPeer::set_transfer_mode);
+ ClassDB::bind_method(D_METHOD("get_transfer_mode"), &MultiplayerPeer::get_transfer_mode);
+ ClassDB::bind_method(D_METHOD("set_target_peer", "id"), &MultiplayerPeer::set_target_peer);
- ClassDB::bind_method(D_METHOD("get_packet_peer"), &NetworkedMultiplayerPeer::get_packet_peer);
+ ClassDB::bind_method(D_METHOD("get_packet_peer"), &MultiplayerPeer::get_packet_peer);
- ClassDB::bind_method(D_METHOD("poll"), &NetworkedMultiplayerPeer::poll);
+ ClassDB::bind_method(D_METHOD("poll"), &MultiplayerPeer::poll);
- ClassDB::bind_method(D_METHOD("get_connection_status"), &NetworkedMultiplayerPeer::get_connection_status);
- ClassDB::bind_method(D_METHOD("get_unique_id"), &NetworkedMultiplayerPeer::get_unique_id);
+ ClassDB::bind_method(D_METHOD("get_connection_status"), &MultiplayerPeer::get_connection_status);
+ ClassDB::bind_method(D_METHOD("get_unique_id"), &MultiplayerPeer::get_unique_id);
- ClassDB::bind_method(D_METHOD("set_refuse_new_connections", "enable"), &NetworkedMultiplayerPeer::set_refuse_new_connections);
- ClassDB::bind_method(D_METHOD("is_refusing_new_connections"), &NetworkedMultiplayerPeer::is_refusing_new_connections);
+ ClassDB::bind_method(D_METHOD("set_refuse_new_connections", "enable"), &MultiplayerPeer::set_refuse_new_connections);
+ ClassDB::bind_method(D_METHOD("is_refusing_new_connections"), &MultiplayerPeer::is_refusing_new_connections);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "refuse_new_connections"), "set_refuse_new_connections", "is_refusing_new_connections");
ADD_PROPERTY(PropertyInfo(Variant::INT, "transfer_mode", PROPERTY_HINT_ENUM, "Unreliable,Unreliable Ordered,Reliable"), "set_transfer_mode", "get_transfer_mode");
diff --git a/core/io/networked_multiplayer_peer.h b/core/io/multiplayer_peer.h
index 7c90f97d88..432f47280f 100644
--- a/core/io/networked_multiplayer_peer.h
+++ b/core/io/multiplayer_peer.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* networked_multiplayer_peer.h */
+/* multiplayer_peer.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -33,8 +33,8 @@
#include "core/io/packet_peer.h"
-class NetworkedMultiplayerPeer : public PacketPeer {
- GDCLASS(NetworkedMultiplayerPeer, PacketPeer);
+class MultiplayerPeer : public PacketPeer {
+ GDCLASS(MultiplayerPeer, PacketPeer);
protected:
static void _bind_methods();
@@ -73,10 +73,10 @@ public:
virtual ConnectionStatus get_connection_status() const = 0;
- NetworkedMultiplayerPeer() {}
+ MultiplayerPeer() {}
};
-VARIANT_ENUM_CAST(NetworkedMultiplayerPeer::TransferMode)
-VARIANT_ENUM_CAST(NetworkedMultiplayerPeer::ConnectionStatus)
+VARIANT_ENUM_CAST(MultiplayerPeer::TransferMode)
+VARIANT_ENUM_CAST(MultiplayerPeer::ConnectionStatus)
#endif // NETWORKED_MULTIPLAYER_PEER_H
diff --git a/core/object/class_db.h b/core/object/class_db.h
index af528bfde7..e0cba1b8b5 100644
--- a/core/object/class_db.h
+++ b/core/object/class_db.h
@@ -434,4 +434,15 @@ public:
#endif
+#define GDREGISTER_CLASS(m_class) \
+ if (!GD_IS_DEFINED(ClassDB_Disable_##m_class)) { \
+ ClassDB::register_class<m_class>(); \
+ }
+#define GDREGISTER_VIRTUAL_CLASS(m_class) \
+ if (!GD_IS_DEFINED(ClassDB_Disable_##m_class)) { \
+ ClassDB::register_virtual_class<m_class>(); \
+ }
+
+#include "core/disabled_classes.gen.h"
+
#endif // CLASS_DB_H
diff --git a/core/object/object.cpp b/core/object/object.cpp
index 1c8db89e5e..296d876701 100644
--- a/core/object/object.cpp
+++ b/core/object/object.cpp
@@ -1769,42 +1769,41 @@ uint32_t Object::get_edited_version() const {
}
#endif
-void *Object::get_script_instance_binding(int p_script_language_index) {
-#ifdef DEBUG_ENABLED
- ERR_FAIL_INDEX_V(p_script_language_index, MAX_SCRIPT_INSTANCE_BINDINGS, nullptr);
-#endif
-
- //it's up to the script language to make this thread safe, if the function is called twice due to threads being out of sync
- //just return the same pointer.
- //if you want to put a big lock in the entire function and keep allocated pointers in a map or something, feel free to do it
- //as it should not really affect performance much (won't be called too often), as in far most cases the condition below will be false afterwards
-
- if (!_script_instance_bindings[p_script_language_index]) {
- void *script_data = ScriptServer::get_language(p_script_language_index)->alloc_instance_binding_data(this);
- if (script_data) {
- instance_binding_count.increment();
- _script_instance_bindings[p_script_language_index] = script_data;
+void *Object::get_instance_binding(void *p_token, const GDNativeInstanceBindingCallbacks *p_callbacks) {
+ void *binding = nullptr;
+ _instance_binding_mutex.lock();
+ for (uint32_t i = 0; i < _instance_binding_count; i++) {
+ if (_instance_bindings[i].token == p_token) {
+ binding = _instance_bindings[i].binding;
+ break;
}
}
+ if (unlikely(!binding)) {
+ uint32_t current_size = next_power_of_2(_instance_binding_count);
+ uint32_t new_size = next_power_of_2(_instance_binding_count + 1);
- return _script_instance_bindings[p_script_language_index];
-}
+ if (current_size == 0 || new_size > current_size) {
+ _instance_bindings = (InstanceBinding *)memrealloc(_instance_bindings, new_size * sizeof(InstanceBinding));
+ }
-bool Object::has_script_instance_binding(int p_script_language_index) {
- return _script_instance_bindings[p_script_language_index] != nullptr;
-}
+ _instance_bindings[_instance_binding_count].free_callback = p_callbacks->free_callback;
+ _instance_bindings[_instance_binding_count].reference_callback = p_callbacks->reference_callback;
+ _instance_bindings[_instance_binding_count].token = p_token;
-void Object::set_script_instance_binding(int p_script_language_index, void *p_data) {
-#ifdef DEBUG_ENABLED
- CRASH_COND(_script_instance_bindings[p_script_language_index] != nullptr);
-#endif
- _script_instance_bindings[p_script_language_index] = p_data;
+ binding = p_callbacks->create_callback(p_token, this);
+ _instance_bindings[_instance_binding_count].binding = binding;
+
+ _instance_binding_count++;
+ }
+
+ _instance_binding_mutex.unlock();
+
+ return binding;
}
void Object::_construct_object(bool p_reference) {
type_is_reference = p_reference;
_instance_id = ObjectDB::add_instance(this);
- memset(_script_instance_bindings, 0, sizeof(void *) * MAX_SCRIPT_INSTANCE_BINDINGS);
ClassDB::instance_get_native_extension_data(&_extension, &_extension_instance);
@@ -1864,12 +1863,13 @@ Object::~Object() {
_instance_id = ObjectID();
_predelete_ok = 2;
- if (!ScriptServer::are_languages_finished()) {
- for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) {
- if (_script_instance_bindings[i]) {
- ScriptServer::get_language(i)->free_instance_binding_data(_script_instance_bindings[i]);
+ if (_instance_bindings != nullptr) {
+ for (uint32_t i = 0; i < _instance_binding_count; i++) {
+ if (_instance_bindings[i].free_callback) {
+ _instance_bindings[i].free_callback(_instance_bindings[i].token, _instance_bindings[i].binding, this);
}
}
+ memfree(_instance_bindings);
}
}
@@ -1887,7 +1887,6 @@ void ObjectDB::debug_objects(DebugFunc p_func) {
for (uint32_t i = 0, count = slot_count; i < slot_max && count != 0; i++) {
if (object_slots[i].validator) {
p_func(object_slots[i].object);
-
count--;
}
}
diff --git a/core/object/object.h b/core/object/object.h
index e6eb6d1aaf..33d9b627f6 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -60,6 +60,7 @@ enum PropertyHint {
PROPERTY_HINT_NONE, ///< no hint provided.
PROPERTY_HINT_RANGE, ///< hint_text = "min,max[,step][,or_greater][,or_lesser][,noslider][,radians][,degrees][,exp][,suffix:<keyword>] range.
PROPERTY_HINT_ENUM, ///< hint_text= "val1,val2,val3,etc"
+ PROPERTY_HINT_ENUM_SUGGESTION, ///< hint_text= "val1,val2,val3,etc"
PROPERTY_HINT_EXP_EASING, /// exponential easing function (Math::ease) use "attenuation" hint string to revert (flip h), "full" to also include in/out. (ie: "attenuation,inout")
PROPERTY_HINT_LENGTH, ///< hint_text= "length" (as integer)
PROPERTY_HINT_KEY_ACCEL, ///< hint_text= "length" (as integer)
@@ -480,10 +481,6 @@ public:
};
private:
- enum {
- MAX_SCRIPT_INSTANCE_BINDINGS = 8
- };
-
#ifdef DEBUG_ENABLED
friend struct _ObjectDebugLock;
#endif
@@ -542,12 +539,35 @@ private:
friend class RefCounted;
bool type_is_reference = false;
- SafeNumeric<uint32_t> instance_binding_count;
- void *_script_instance_bindings[MAX_SCRIPT_INSTANCE_BINDINGS];
+
+ std::mutex _instance_binding_mutex;
+ struct InstanceBinding {
+ void *binding;
+ void *token;
+ GDNativeInstanceBindingFreeCallback free_callback = nullptr;
+ GDNativeInstanceBindingReferenceCallback reference_callback = nullptr;
+ };
+ InstanceBinding *_instance_bindings = nullptr;
+ uint32_t _instance_binding_count = 0;
Object(bool p_reference);
protected:
+ _FORCE_INLINE_ bool _instance_binding_reference(bool p_reference) {
+ bool can_die = true;
+ if (_instance_bindings) {
+ _instance_binding_mutex.lock();
+ for (uint32_t i = 0; i < _instance_binding_count; i++) {
+ if (_instance_bindings[i].reference_callback) {
+ if (!_instance_bindings[i].reference_callback(_instance_bindings[i].token, _instance_bindings[i].binding, p_reference)) {
+ can_die = false;
+ }
+ }
+ }
+ _instance_binding_mutex.unlock();
+ }
+ return can_die;
+ }
friend class NativeExtensionMethodBind;
_ALWAYS_INLINE_ const ObjectNativeExtension *_get_extension() const { return _extension; }
_ALWAYS_INLINE_ GDExtensionClassInstancePtr _get_extension_instance() const { return _extension_instance; }
@@ -785,9 +805,7 @@ public:
#endif
//used by script languages to store binding data
- void *get_script_instance_binding(int p_script_language_index);
- bool has_script_instance_binding(int p_script_language_index);
- void set_script_instance_binding(int p_script_language_index, void *p_data);
+ void *get_instance_binding(void *p_token, const GDNativeInstanceBindingCallbacks *p_callbacks);
void clear_internal_resource_paths();
diff --git a/core/object/ref_counted.cpp b/core/object/ref_counted.cpp
index 9862624972..2833f774dc 100644
--- a/core/object/ref_counted.cpp
+++ b/core/object/ref_counted.cpp
@@ -65,13 +65,8 @@ bool RefCounted::reference() {
if (_get_extension() && _get_extension()->reference) {
_get_extension()->reference(_get_extension_instance());
}
- if (instance_binding_count.get() > 0 && !ScriptServer::are_languages_finished()) {
- for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) {
- if (_script_instance_bindings[i]) {
- ScriptServer::get_language(i)->refcount_incremented_instance_binding(this);
- }
- }
- }
+
+ _instance_binding_reference(true);
}
return success;
@@ -89,14 +84,8 @@ bool RefCounted::unreference() {
if (_get_extension() && _get_extension()->unreference) {
_get_extension()->unreference(_get_extension_instance());
}
- if (instance_binding_count.get() > 0 && !ScriptServer::are_languages_finished()) {
- for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) {
- if (_script_instance_bindings[i]) {
- bool script_ret = ScriptServer::get_language(i)->refcount_decremented_instance_binding(this);
- die = die && script_ret;
- }
- }
- }
+
+ die = die && _instance_binding_reference(false);
}
return die;
diff --git a/core/os/memory.h b/core/os/memory.h
index 10e678103d..9d09626b8c 100644
--- a/core/os/memory.h
+++ b/core/os/memory.h
@@ -80,7 +80,7 @@ void operator delete(void *p_mem, void *p_pointer, size_t check, const char *p_d
#define memalloc(m_size) Memory::alloc_static(m_size)
#define memrealloc(m_mem, m_size) Memory::realloc_static(m_mem, m_size)
-#define memfree(m_size) Memory::free_static(m_size)
+#define memfree(m_mem) Memory::free_static(m_mem)
_ALWAYS_INLINE_ void postinitialize_handler(void *) {}
diff --git a/core/os/os.h b/core/os/os.h
index 444f67431f..301718a8b3 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -58,8 +58,6 @@ class OS {
int _orientation;
bool _allow_hidpi = false;
bool _allow_layered = false;
- bool _use_vsync;
- bool _vsync_via_compositor;
bool _stdout_enabled = true;
bool _stderr_enabled = true;
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index 1cbb0bb597..eb37267546 100644
--- a/core/register_core_types.cpp
+++ b/core/register_core_types.cpp
@@ -48,7 +48,7 @@
#include "core/io/json.h"
#include "core/io/marshalls.h"
#include "core/io/multiplayer_api.h"
-#include "core/io/networked_multiplayer_peer.h"
+#include "core/io/multiplayer_peer.h"
#include "core/io/packed_data_container.h"
#include "core/io/packet_peer.h"
#include "core/io/packet_peer_dtls.h"
@@ -131,50 +131,50 @@ void register_core_types() {
resource_format_image.instantiate();
ResourceLoader::add_resource_format_loader(resource_format_image);
- ClassDB::register_class<Object>();
-
- ClassDB::register_virtual_class<Script>();
-
- ClassDB::register_class<RefCounted>();
- ClassDB::register_class<WeakRef>();
- ClassDB::register_class<Resource>();
- ClassDB::register_class<Image>();
-
- ClassDB::register_virtual_class<InputEvent>();
- ClassDB::register_virtual_class<InputEventWithModifiers>();
- ClassDB::register_virtual_class<InputEventFromWindow>();
- ClassDB::register_class<InputEventKey>();
- ClassDB::register_virtual_class<InputEventMouse>();
- ClassDB::register_class<InputEventMouseButton>();
- ClassDB::register_class<InputEventMouseMotion>();
- ClassDB::register_class<InputEventJoypadButton>();
- ClassDB::register_class<InputEventJoypadMotion>();
- ClassDB::register_class<InputEventScreenDrag>();
- ClassDB::register_class<InputEventScreenTouch>();
- ClassDB::register_class<InputEventAction>();
- ClassDB::register_virtual_class<InputEventGesture>();
- ClassDB::register_class<InputEventMagnifyGesture>();
- ClassDB::register_class<InputEventPanGesture>();
- ClassDB::register_class<InputEventMIDI>();
+ GDREGISTER_CLASS(Object);
+
+ GDREGISTER_VIRTUAL_CLASS(Script);
+
+ GDREGISTER_CLASS(RefCounted);
+ GDREGISTER_CLASS(WeakRef);
+ GDREGISTER_CLASS(Resource);
+ GDREGISTER_CLASS(Image);
+
+ GDREGISTER_VIRTUAL_CLASS(InputEvent);
+ GDREGISTER_VIRTUAL_CLASS(InputEventWithModifiers);
+ GDREGISTER_VIRTUAL_CLASS(InputEventFromWindow);
+ GDREGISTER_CLASS(InputEventKey);
+ GDREGISTER_VIRTUAL_CLASS(InputEventMouse);
+ GDREGISTER_CLASS(InputEventMouseButton);
+ GDREGISTER_CLASS(InputEventMouseMotion);
+ GDREGISTER_CLASS(InputEventJoypadButton);
+ GDREGISTER_CLASS(InputEventJoypadMotion);
+ GDREGISTER_CLASS(InputEventScreenDrag);
+ GDREGISTER_CLASS(InputEventScreenTouch);
+ GDREGISTER_CLASS(InputEventAction);
+ GDREGISTER_VIRTUAL_CLASS(InputEventGesture);
+ GDREGISTER_CLASS(InputEventMagnifyGesture);
+ GDREGISTER_CLASS(InputEventPanGesture);
+ GDREGISTER_CLASS(InputEventMIDI);
// Network
- ClassDB::register_virtual_class<IP>();
+ GDREGISTER_VIRTUAL_CLASS(IP);
- ClassDB::register_virtual_class<StreamPeer>();
- ClassDB::register_class<StreamPeerBuffer>();
- ClassDB::register_class<StreamPeerTCP>();
- ClassDB::register_class<TCPServer>();
+ GDREGISTER_VIRTUAL_CLASS(StreamPeer);
+ GDREGISTER_CLASS(StreamPeerBuffer);
+ GDREGISTER_CLASS(StreamPeerTCP);
+ GDREGISTER_CLASS(TCPServer);
- ClassDB::register_virtual_class<PacketPeer>();
- ClassDB::register_class<PacketPeerStream>();
- ClassDB::register_class<PacketPeerUDP>();
- ClassDB::register_class<UDPServer>();
+ GDREGISTER_VIRTUAL_CLASS(PacketPeer);
+ GDREGISTER_CLASS(PacketPeerStream);
+ GDREGISTER_CLASS(PacketPeerUDP);
+ GDREGISTER_CLASS(UDPServer);
ClassDB::register_custom_instance_class<HTTPClient>();
// Crypto
- ClassDB::register_class<HashingContext>();
- ClassDB::register_class<AESContext>();
+ GDREGISTER_CLASS(HashingContext);
+ GDREGISTER_CLASS(AESContext);
ClassDB::register_custom_instance_class<X509Certificate>();
ClassDB::register_custom_instance_class<CryptoKey>();
ClassDB::register_custom_instance_class<HMACContext>();
@@ -188,42 +188,42 @@ void register_core_types() {
resource_format_loader_crypto.instantiate();
ResourceLoader::add_resource_format_loader(resource_format_loader_crypto);
- ClassDB::register_virtual_class<NetworkedMultiplayerPeer>();
- ClassDB::register_class<MultiplayerAPI>();
- ClassDB::register_class<MainLoop>();
- ClassDB::register_class<Translation>();
- ClassDB::register_class<OptimizedTranslation>();
- ClassDB::register_class<UndoRedo>();
- ClassDB::register_class<TriangleMesh>();
+ GDREGISTER_VIRTUAL_CLASS(MultiplayerPeer);
+ GDREGISTER_CLASS(MultiplayerAPI);
+ GDREGISTER_CLASS(MainLoop);
+ GDREGISTER_CLASS(Translation);
+ GDREGISTER_CLASS(OptimizedTranslation);
+ GDREGISTER_CLASS(UndoRedo);
+ GDREGISTER_CLASS(TriangleMesh);
- ClassDB::register_class<ResourceFormatLoader>();
- ClassDB::register_class<ResourceFormatSaver>();
+ GDREGISTER_CLASS(ResourceFormatLoader);
+ GDREGISTER_CLASS(ResourceFormatSaver);
- ClassDB::register_class<_File>();
- ClassDB::register_class<_Directory>();
- ClassDB::register_class<_Thread>();
- ClassDB::register_class<_Mutex>();
- ClassDB::register_class<_Semaphore>();
+ GDREGISTER_CLASS(_File);
+ GDREGISTER_CLASS(_Directory);
+ GDREGISTER_CLASS(_Thread);
+ GDREGISTER_CLASS(_Mutex);
+ GDREGISTER_CLASS(_Semaphore);
- ClassDB::register_class<XMLParser>();
- ClassDB::register_class<JSON>();
+ GDREGISTER_CLASS(XMLParser);
+ GDREGISTER_CLASS(JSON);
- ClassDB::register_class<ConfigFile>();
+ GDREGISTER_CLASS(ConfigFile);
- ClassDB::register_class<PCKPacker>();
+ GDREGISTER_CLASS(PCKPacker);
- ClassDB::register_class<PackedDataContainer>();
- ClassDB::register_virtual_class<PackedDataContainerRef>();
- ClassDB::register_class<AStar>();
- ClassDB::register_class<AStar2D>();
- ClassDB::register_class<EncodedObjectAsID>();
- ClassDB::register_class<RandomNumberGenerator>();
+ GDREGISTER_CLASS(PackedDataContainer);
+ GDREGISTER_VIRTUAL_CLASS(PackedDataContainerRef);
+ GDREGISTER_CLASS(AStar);
+ GDREGISTER_CLASS(AStar2D);
+ GDREGISTER_CLASS(EncodedObjectAsID);
+ GDREGISTER_CLASS(RandomNumberGenerator);
- ClassDB::register_virtual_class<ResourceImporter>();
+ GDREGISTER_VIRTUAL_CLASS(ResourceImporter);
- ClassDB::register_class<NativeExtension>();
+ GDREGISTER_CLASS(NativeExtension);
- ClassDB::register_virtual_class<NativeExtensionManager>();
+ GDREGISTER_VIRTUAL_CLASS(NativeExtensionManager);
native_extension_manager = memnew(NativeExtensionManager);
@@ -253,22 +253,22 @@ void register_core_settings() {
}
void register_core_singletons() {
- ClassDB::register_class<ProjectSettings>();
- ClassDB::register_virtual_class<IP>();
- ClassDB::register_class<_Geometry2D>();
- ClassDB::register_class<_Geometry3D>();
- ClassDB::register_class<_ResourceLoader>();
- ClassDB::register_class<_ResourceSaver>();
- ClassDB::register_class<_OS>();
- ClassDB::register_class<_Engine>();
- ClassDB::register_class<_ClassDB>();
- ClassDB::register_class<_Marshalls>();
- ClassDB::register_class<TranslationServer>();
- ClassDB::register_virtual_class<Input>();
- ClassDB::register_class<InputMap>();
- ClassDB::register_class<Expression>();
- ClassDB::register_class<_EngineDebugger>();
- ClassDB::register_class<Time>();
+ GDREGISTER_CLASS(ProjectSettings);
+ GDREGISTER_VIRTUAL_CLASS(IP);
+ GDREGISTER_CLASS(_Geometry2D);
+ GDREGISTER_CLASS(_Geometry3D);
+ GDREGISTER_CLASS(_ResourceLoader);
+ GDREGISTER_CLASS(_ResourceSaver);
+ GDREGISTER_CLASS(_OS);
+ GDREGISTER_CLASS(_Engine);
+ GDREGISTER_CLASS(_ClassDB);
+ GDREGISTER_CLASS(_Marshalls);
+ GDREGISTER_CLASS(TranslationServer);
+ GDREGISTER_VIRTUAL_CLASS(Input);
+ GDREGISTER_CLASS(InputMap);
+ GDREGISTER_CLASS(Expression);
+ GDREGISTER_CLASS(_EngineDebugger);
+ GDREGISTER_CLASS(Time);
Engine::get_singleton()->add_singleton(Engine::Singleton("ProjectSettings", ProjectSettings::get_singleton()));
Engine::get_singleton()->add_singleton(Engine::Singleton("IP", IP::get_singleton(), "IP"));
diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp
index 16ecd2b985..4cd2915ffa 100644
--- a/core/string/ustring.cpp
+++ b/core/string/ustring.cpp
@@ -3397,17 +3397,10 @@ String String::format(const Variant &values, String placeholder) const {
if (value_arr.size() == 2) {
Variant v_key = value_arr[0];
String key = v_key;
- if (key.left(1) == "\"" && key.right(1) == "\"") {
- key = key.substr(1, key.length() - 2);
- }
Variant v_val = value_arr[1];
String val = v_val;
- if (val.left(1) == "\"" && val.right(1) == "\"") {
- val = val.substr(1, val.length() - 2);
- }
-
new_string = new_string.replace(placeholder.replace("_", key), val);
} else {
ERR_PRINT(String("STRING.format Inner Array size != 2 ").ascii().get_data());
@@ -3416,10 +3409,6 @@ String String::format(const Variant &values, String placeholder) const {
Variant v_val = values_arr[i];
String val = v_val;
- if (val.left(1) == "\"" && val.right(1) == "\"") {
- val = val.substr(1, val.length() - 2);
- }
-
if (placeholder.find("_") > -1) {
new_string = new_string.replace(placeholder.replace("_", i_as_str), val);
} else {
@@ -3436,14 +3425,6 @@ String String::format(const Variant &values, String placeholder) const {
String key = E->get();
String val = d[E->get()];
- if (key.left(1) == "\"" && key.right(1) == "\"") {
- key = key.substr(1, key.length() - 2);
- }
-
- if (val.left(1) == "\"" && val.right(1) == "\"") {
- val = val.substr(1, val.length() - 2);
- }
-
new_string = new_string.replace(placeholder.replace("_", key), val);
}
} else {
diff --git a/core/templates/list.h b/core/templates/list.h
index 010e35eed8..6047b89670 100644
--- a/core/templates/list.h
+++ b/core/templates/list.h
@@ -135,6 +135,83 @@ public:
_FORCE_INLINE_ Element() {}
};
+ typedef T ValueType;
+
+ struct Iterator {
+ _FORCE_INLINE_ T &operator*() const {
+ return E->get();
+ }
+ _FORCE_INLINE_ T *operator->() const { return &E->get(); }
+ _FORCE_INLINE_ Iterator &operator++() {
+ E = E->next();
+ return *this;
+ }
+ _FORCE_INLINE_ Iterator &operator--() {
+ E = E->prev();
+ return *this;
+ }
+
+ _FORCE_INLINE_ bool operator==(const Iterator &b) const { return E == b.E; }
+ _FORCE_INLINE_ bool operator!=(const Iterator &b) const { return E != b.E; }
+
+ Iterator(Element *p_E) { E = p_E; }
+ Iterator() {}
+ Iterator(const Iterator &p_it) { E = p_it.E; }
+
+ private:
+ Element *E = nullptr;
+ };
+
+ struct ConstIterator {
+ _FORCE_INLINE_ const T &operator*() const {
+ return E->get();
+ }
+ _FORCE_INLINE_ const T *operator->() const { return &E->get(); }
+ _FORCE_INLINE_ ConstIterator &operator++() {
+ E = E->next();
+ return *this;
+ }
+ _FORCE_INLINE_ ConstIterator &operator--() {
+ E = E->prev();
+ return *this;
+ }
+
+ _FORCE_INLINE_ bool operator==(const Iterator &b) const { return E == b.E; }
+ _FORCE_INLINE_ bool operator!=(const Iterator &b) const { return E != b.E; }
+
+ _FORCE_INLINE_ ConstIterator(const Element *p_E) { E = p_E; }
+ _FORCE_INLINE_ ConstIterator() {}
+ _FORCE_INLINE_ ConstIterator(const ConstIterator &p_it) { E = p_it.E; }
+
+ private:
+ const Element *E = nullptr;
+ };
+
+ _FORCE_INLINE_ Iterator begin() {
+ return Iterator(front());
+ }
+ _FORCE_INLINE_ Iterator end() {
+ return Iterator(nullptr);
+ }
+
+#if 0
+ //to use when replacing find()
+ _FORCE_INLINE_ Iterator find(const K &p_key) {
+ return Iterator(find(p_key));
+ }
+#endif
+ _FORCE_INLINE_ ConstIterator begin() const {
+ return ConstIterator(front());
+ }
+ _FORCE_INLINE_ ConstIterator end() const {
+ return ConstIterator(nullptr);
+ }
+#if 0
+ //to use when replacing find()
+ _FORCE_INLINE_ ConstIterator find(const K &p_key) const {
+ return ConstIterator(find(p_key));
+ }
+#endif
private:
struct _Data {
Element *first = nullptr;
diff --git a/core/templates/map.h b/core/templates/map.h
index 7dfee13d2c..a47547d355 100644
--- a/core/templates/map.h
+++ b/core/templates/map.h
@@ -33,6 +33,7 @@
#include "core/error/error_macros.h"
#include "core/os/memory.h"
+#include "core/templates/pair.h"
// based on the very nice implementation of rb-trees by:
// https://web.archive.org/web/20120507164830/http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
@@ -55,11 +56,12 @@ public:
Element *parent = nullptr;
Element *_next = nullptr;
Element *_prev = nullptr;
- K _key;
- V _value;
- //_Data *data;
+ KeyValue<K, V> _data;
public:
+ KeyValue<K, V> &key_value() { return _data; }
+ const KeyValue<K, V> &key_value() const { return _data; }
+
const Element *next() const {
return _next;
}
@@ -73,23 +75,106 @@ public:
return _prev;
}
const K &key() const {
- return _key;
+ return _data.key;
}
V &value() {
- return _value;
+ return _data.value;
}
const V &value() const {
- return _value;
+ return _data.value;
}
V &get() {
- return _value;
+ return _data.value;
}
const V &get() const {
- return _value;
+ return _data.value;
}
- Element() {}
+ Element(const KeyValue<K, V> &p_data) :
+ _data(p_data) {}
};
+ typedef KeyValue<K, V> ValueType;
+
+ struct Iterator {
+ _FORCE_INLINE_ KeyValue<K, V> &operator*() const {
+ return E->key_value();
+ }
+ _FORCE_INLINE_ KeyValue<K, V> *operator->() const { return &E->key_value(); }
+ _FORCE_INLINE_ Iterator &operator++() {
+ E = E->next();
+ return *this;
+ }
+ _FORCE_INLINE_ Iterator &operator--() {
+ E = E->prev();
+ return *this;
+ }
+
+ _FORCE_INLINE_ bool operator==(const Iterator &b) const { return E == b.E; }
+ _FORCE_INLINE_ bool operator!=(const Iterator &b) const { return E != b.E; }
+
+ Iterator(Element *p_E) { E = p_E; }
+ Iterator() {}
+ Iterator(const Iterator &p_it) { E = p_it.E; }
+
+ private:
+ Element *E = nullptr;
+ };
+
+ struct ConstIterator {
+ _FORCE_INLINE_ const KeyValue<K, V> &operator*() const {
+ return E->key_value();
+ }
+ _FORCE_INLINE_ const KeyValue<K, V> *operator->() const { return &E->key_value(); }
+ _FORCE_INLINE_ ConstIterator &operator++() {
+ E = E->next();
+ return *this;
+ }
+ _FORCE_INLINE_ ConstIterator &operator--() {
+ E = E->prev();
+ return *this;
+ }
+
+ _FORCE_INLINE_ bool operator==(const ConstIterator &b) const { return E == b.E; }
+ _FORCE_INLINE_ bool operator!=(const ConstIterator &b) const { return E != b.E; }
+
+ ConstIterator(const Element *p_E) { E = p_E; }
+ ConstIterator() {}
+ ConstIterator(const ConstIterator &p_it) { E = p_it.E; }
+
+ private:
+ const Element *E = nullptr;
+ };
+
+ _FORCE_INLINE_ Iterator begin() {
+ return Iterator(front());
+ }
+ _FORCE_INLINE_ Iterator end() {
+ return Iterator(nullptr);
+ }
+
+#if 0
+ //to use when replacing find()
+ _FORCE_INLINE_ Iterator find(const K &p_key) {
+ return Iterator(find(p_key));
+ }
+#endif
+ _FORCE_INLINE_ void remove(const Iterator &p_iter) {
+ return erase(p_iter.E);
+ }
+
+ _FORCE_INLINE_ ConstIterator begin() const {
+ return ConstIterator(front());
+ }
+ _FORCE_INLINE_ ConstIterator end() const {
+ return ConstIterator(nullptr);
+ }
+
+#if 0
+ //to use when replacing find()
+ _FORCE_INLINE_ ConstIterator find(const K &p_key) const {
+ return ConstIterator(find(p_key));
+ }
+#endif
private:
struct _Data {
Element *_root = nullptr;
@@ -107,7 +192,7 @@ private:
}
void _create_root() {
- _root = memnew_allocator(Element, A);
+ _root = memnew_allocator(Element(KeyValue<K, V>(K(), V())), A);
_root->parent = _root->left = _root->right = _nil;
_root->color = BLACK;
}
@@ -216,9 +301,9 @@ private:
C less;
while (node != _data._nil) {
- if (less(p_key, node->_key)) {
+ if (less(p_key, node->_data.key)) {
node = node->left;
- } else if (less(node->_key, p_key)) {
+ } else if (less(node->_data.key, p_key)) {
node = node->right;
} else {
return node; // found
@@ -236,9 +321,9 @@ private:
while (node != _data._nil) {
prev = node;
- if (less(p_key, node->_key)) {
+ if (less(p_key, node->_data.key)) {
node = node->left;
- } else if (less(node->_key, p_key)) {
+ } else if (less(node->_data.key, p_key)) {
node = node->right;
} else {
return node; // found
@@ -249,7 +334,7 @@ private:
return nullptr; // tree empty
}
- if (less(p_key, prev->_key)) {
+ if (less(p_key, prev->_data.key)) {
prev = prev->_prev;
}
@@ -312,25 +397,25 @@ private:
while (node != _data._nil) {
new_parent = node;
- if (less(p_key, node->_key)) {
+ if (less(p_key, node->_data.key)) {
node = node->left;
- } else if (less(node->_key, p_key)) {
+ } else if (less(node->_data.key, p_key)) {
node = node->right;
} else {
- node->_value = p_value;
+ node->_data.value = p_value;
return node; // Return existing node with new value
}
}
- Element *new_node = memnew_allocator(Element, A);
+ typedef KeyValue<K, V> KV;
+ Element *new_node = memnew_allocator(Element(KV(p_key, p_value)), A);
new_node->parent = new_parent;
new_node->right = _data._nil;
new_node->left = _data._nil;
- new_node->_key = p_key;
- new_node->_value = p_value;
+
//new_node->data=_data;
- if (new_parent == _data._root || less(p_key, new_parent->_key)) {
+ if (new_parent == _data._root || less(p_key, new_parent->_data.key)) {
new_parent->left = new_node;
} else {
new_parent->right = new_node;
@@ -575,7 +660,7 @@ public:
CRASH_COND(!_data._root);
const Element *e = find(p_key);
CRASH_COND(!e);
- return e->_value;
+ return e->_data.value;
}
V &operator[](const K &p_key) {
@@ -588,7 +673,7 @@ public:
e = insert(p_key, V());
}
- return e->_value;
+ return e->_data.value;
}
Element *front() const {
diff --git a/core/templates/pair.h b/core/templates/pair.h
index bc1a764694..31706b6ecb 100644
--- a/core/templates/pair.h
+++ b/core/templates/pair.h
@@ -31,6 +31,8 @@
#ifndef PAIR_H
#define PAIR_H
+#include "core/typedefs.h"
+
template <class F, class S>
struct Pair {
F first;
@@ -64,4 +66,37 @@ struct PairSort {
}
};
+template <class K, class V>
+struct KeyValue {
+ const K key;
+ V value;
+
+ void operator=(const KeyValue &p_kv) = delete;
+ _FORCE_INLINE_ KeyValue(const KeyValue &p_kv) :
+ key(p_kv.key),
+ value(p_kv.value) {
+ }
+ _FORCE_INLINE_ KeyValue(const K &p_key, const V &p_value) :
+ key(p_key),
+ value(p_value) {
+ }
+};
+
+template <class K, class V>
+bool operator==(const KeyValue<K, V> &pair, const KeyValue<K, V> &other) {
+ return (pair.key == other.key) && (pair.value == other.value);
+}
+
+template <class K, class V>
+bool operator!=(const KeyValue<K, V> &pair, const KeyValue<K, V> &other) {
+ return (pair.key != other.key) || (pair.value != other.value);
+}
+
+template <class K, class V>
+struct KeyValueSort {
+ bool operator()(const KeyValue<K, V> &A, const KeyValue<K, V> &B) const {
+ return A.key < B.key;
+ }
+};
+
#endif // PAIR_H
diff --git a/core/templates/set.h b/core/templates/set.h
index 3036ecf27d..245c174862 100644
--- a/core/templates/set.h
+++ b/core/templates/set.h
@@ -77,6 +77,85 @@ public:
Element() {}
};
+ typedef T ValueType;
+
+ struct Iterator {
+ _FORCE_INLINE_ T &operator*() const {
+ return E->get();
+ }
+ _FORCE_INLINE_ T *operator->() const { return &E->get(); }
+ _FORCE_INLINE_ Iterator &operator++() {
+ E = E->next();
+ return *this;
+ }
+ _FORCE_INLINE_ Iterator &operator--() {
+ E = E->prev();
+ return *this;
+ }
+
+ _FORCE_INLINE_ bool operator==(const Iterator &b) const { return E == b.E; }
+ _FORCE_INLINE_ bool operator!=(const Iterator &b) const { return E != b.E; }
+
+ Iterator(Element *p_E) { E = p_E; }
+ Iterator() {}
+ Iterator(const Iterator &p_it) { E = p_it.E; }
+
+ private:
+ Element *E = nullptr;
+ };
+
+ struct ConstIterator {
+ _FORCE_INLINE_ const T &operator*() const {
+ return E->get();
+ }
+ _FORCE_INLINE_ const T *operator->() const { return &E->get(); }
+ _FORCE_INLINE_ ConstIterator &operator++() {
+ E = E->next();
+ return *this;
+ }
+ _FORCE_INLINE_ ConstIterator &operator--() {
+ E = E->prev();
+ return *this;
+ }
+
+ _FORCE_INLINE_ bool operator==(const Iterator &b) const { return E == b.E; }
+ _FORCE_INLINE_ bool operator!=(const Iterator &b) const { return E != b.E; }
+
+ _FORCE_INLINE_ ConstIterator(const Element *p_E) { E = p_E; }
+ _FORCE_INLINE_ ConstIterator() {}
+ _FORCE_INLINE_ ConstIterator(const ConstIterator &p_it) { E = p_it.E; }
+
+ private:
+ const Element *E = nullptr;
+ };
+
+ _FORCE_INLINE_ Iterator begin() {
+ return Iterator(front());
+ }
+ _FORCE_INLINE_ Iterator end() {
+ return Iterator(nullptr);
+ }
+
+#if 0
+ //to use when replacing find()
+ _FORCE_INLINE_ Iterator find(const K &p_key) {
+ return Iterator(find(p_key));
+ }
+#endif
+
+ _FORCE_INLINE_ ConstIterator begin() const {
+ return ConstIterator(front());
+ }
+ _FORCE_INLINE_ ConstIterator end() const {
+ return ConstIterator(nullptr);
+ }
+
+#if 0
+ //to use when replacing find()
+ _FORCE_INLINE_ ConstIterator find(const K &p_key) const {
+ return ConstIterator(find(p_key));
+ }
+#endif
private:
struct _Data {
Element *_root = nullptr;
diff --git a/core/templates/vector.h b/core/templates/vector.h
index dae8874a87..08cbef6ba4 100644
--- a/core/templates/vector.h
+++ b/core/templates/vector.h
@@ -187,6 +187,70 @@ public:
return false;
}
+ struct Iterator {
+ _FORCE_INLINE_ T &operator*() const {
+ return *elem_ptr;
+ }
+ _FORCE_INLINE_ T *operator->() const { return elem_ptr; }
+ _FORCE_INLINE_ Iterator &operator++() {
+ elem_ptr++;
+ return *this;
+ }
+ _FORCE_INLINE_ Iterator &operator--() {
+ elem_ptr--;
+ return *this;
+ }
+
+ _FORCE_INLINE_ bool operator==(const Iterator &b) const { return elem_ptr == b.elem_ptr; }
+ _FORCE_INLINE_ bool operator!=(const Iterator &b) const { return elem_ptr != b.elem_ptr; }
+
+ Iterator(T *p_ptr) { elem_ptr = p_ptr; }
+ Iterator() {}
+ Iterator(const Iterator &p_it) { elem_ptr = p_it.elem_ptr; }
+
+ private:
+ T *elem_ptr = nullptr;
+ };
+
+ struct ConstIterator {
+ _FORCE_INLINE_ const T &operator*() const {
+ return *elem_ptr;
+ }
+ _FORCE_INLINE_ const T *operator->() const { return elem_ptr; }
+ _FORCE_INLINE_ ConstIterator &operator++() {
+ elem_ptr++;
+ return *this;
+ }
+ _FORCE_INLINE_ ConstIterator &operator--() {
+ elem_ptr--;
+ return *this;
+ }
+
+ _FORCE_INLINE_ bool operator==(const ConstIterator &b) const { return elem_ptr == b.elem_ptr; }
+ _FORCE_INLINE_ bool operator!=(const ConstIterator &b) const { return elem_ptr != b.elem_ptr; }
+
+ ConstIterator(T *p_ptr) { elem_ptr = p_ptr; }
+ ConstIterator() {}
+ ConstIterator(const ConstIterator &p_it) { elem_ptr = p_it.elem_ptr; }
+
+ private:
+ const T *elem_ptr = nullptr;
+ };
+
+ _FORCE_INLINE_ Iterator begin() {
+ return Iterator(ptrw());
+ }
+ _FORCE_INLINE_ Iterator end() {
+ return Iterator(ptrw() + size());
+ }
+
+ _FORCE_INLINE_ ConstIterator begin() const {
+ return ConstIterator(ptr());
+ }
+ _FORCE_INLINE_ ConstIterator end() const {
+ return ConstIterator(ptr() + size());
+ }
+
_FORCE_INLINE_ Vector() {}
_FORCE_INLINE_ Vector(const Vector &p_from) { _cowdata._ref(p_from._cowdata); }
diff --git a/core/typedefs.h b/core/typedefs.h
index cdbfb34e56..dde254af23 100644
--- a/core/typedefs.h
+++ b/core/typedefs.h
@@ -281,4 +281,11 @@ struct BuildIndexSequence<0, Is...> : IndexSequence<Is...> {};
#define DEBUG_METHODS_ENABLED
#endif
+// Macro GD_IS_DEFINED() allows to check if a macro is defined. It needs to be defined to anything (say 1) to work.
+#define __GDARG_PLACEHOLDER_1 0,
+#define __gd_take_second_arg(__ignored, val, ...) val
+#define ____gd_is_defined(arg1_or_junk) __gd_take_second_arg(arg1_or_junk 1, 0)
+#define ___gd_is_defined(val) ____gd_is_defined(__GDARG_PLACEHOLDER_##val)
+#define GD_IS_DEFINED(x) ___gd_is_defined(x)
+
#endif // TYPEDEFS_H
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index 66511f5845..d0bd517050 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -2415,67 +2415,71 @@
<constant name="PROPERTY_HINT_ENUM" value="2" enum="PropertyHint">
Hints that an integer, float or string property is an enumerated value to pick in a list specified via a hint string such as [code]"Hello,Something,Else"[/code].
</constant>
- <constant name="PROPERTY_HINT_EXP_EASING" value="3" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_ENUM_SUGGESTION" value="3" enum="PropertyHint">
+ Hints that a string property is can be an enumerated value to pick in a list specified via a hint string such as [code]"Hello,Something,Else"[/code].
+ Unlike [constant PROPERTY_HINT_ENUM] a property with this hint still accepts arbitrary values and can be empty. The list of values serves to suggest possible values.
+ </constant>
+ <constant name="PROPERTY_HINT_EXP_EASING" value="4" enum="PropertyHint">
Hints that a float property should be edited via an exponential easing function. The hint string can include [code]"attenuation"[/code] to flip the curve horizontally and/or [code]"inout"[/code] to also include in/out easing.
</constant>
- <constant name="PROPERTY_HINT_LENGTH" value="4" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LENGTH" value="5" enum="PropertyHint">
Deprecated hint, unused.
</constant>
- <constant name="PROPERTY_HINT_KEY_ACCEL" value="5" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_KEY_ACCEL" value="6" enum="PropertyHint">
Deprecated hint, unused.
</constant>
- <constant name="PROPERTY_HINT_FLAGS" value="6" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_FLAGS" value="7" enum="PropertyHint">
Hints that an integer property is a bitmask with named bit flags. For example, to allow toggling bits 0, 1, 2 and 4, the hint could be something like [code]"Bit0,Bit1,Bit2,,Bit4"[/code].
</constant>
- <constant name="PROPERTY_HINT_LAYERS_2D_RENDER" value="7" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LAYERS_2D_RENDER" value="8" enum="PropertyHint">
Hints that an integer property is a bitmask using the optionally named 2D render layers.
</constant>
- <constant name="PROPERTY_HINT_LAYERS_2D_PHYSICS" value="8" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LAYERS_2D_PHYSICS" value="9" enum="PropertyHint">
Hints that an integer property is a bitmask using the optionally named 2D physics layers.
</constant>
- <constant name="PROPERTY_HINT_LAYERS_2D_NAVIGATION" value="9" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LAYERS_2D_NAVIGATION" value="10" enum="PropertyHint">
Hints that an integer property is a bitmask using the optionally named 2D navigation layers.
</constant>
- <constant name="PROPERTY_HINT_LAYERS_3D_RENDER" value="10" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LAYERS_3D_RENDER" value="11" enum="PropertyHint">
Hints that an integer property is a bitmask using the optionally named 3D render layers.
</constant>
- <constant name="PROPERTY_HINT_LAYERS_3D_PHYSICS" value="11" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LAYERS_3D_PHYSICS" value="12" enum="PropertyHint">
Hints that an integer property is a bitmask using the optionally named 3D physics layers.
</constant>
- <constant name="PROPERTY_HINT_LAYERS_3D_NAVIGATION" value="12" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LAYERS_3D_NAVIGATION" value="13" enum="PropertyHint">
Hints that an integer property is a bitmask using the optionally named 2D navigation layers.
</constant>
- <constant name="PROPERTY_HINT_FILE" value="13" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_FILE" value="14" enum="PropertyHint">
Hints that a string property is a path to a file. Editing it will show a file dialog for picking the path. The hint string can be a set of filters with wildcards like [code]"*.png,*.jpg"[/code].
</constant>
- <constant name="PROPERTY_HINT_DIR" value="14" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_DIR" value="15" enum="PropertyHint">
Hints that a string property is a path to a directory. Editing it will show a file dialog for picking the path.
</constant>
- <constant name="PROPERTY_HINT_GLOBAL_FILE" value="15" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_GLOBAL_FILE" value="16" enum="PropertyHint">
Hints that a string property is an absolute path to a file outside the project folder. Editing it will show a file dialog for picking the path. The hint string can be a set of filters with wildcards like [code]"*.png,*.jpg"[/code].
</constant>
- <constant name="PROPERTY_HINT_GLOBAL_DIR" value="16" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_GLOBAL_DIR" value="17" enum="PropertyHint">
Hints that a string property is an absolute path to a directory outside the project folder. Editing it will show a file dialog for picking the path.
</constant>
- <constant name="PROPERTY_HINT_RESOURCE_TYPE" value="17" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_RESOURCE_TYPE" value="18" enum="PropertyHint">
Hints that a property is an instance of a [Resource]-derived type, optionally specified via the hint string (e.g. [code]"Texture2D"[/code]). Editing it will show a popup menu of valid resource types to instantiate.
</constant>
- <constant name="PROPERTY_HINT_MULTILINE_TEXT" value="18" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_MULTILINE_TEXT" value="19" enum="PropertyHint">
Hints that a string property is text with line breaks. Editing it will show a text input field where line breaks can be typed.
</constant>
- <constant name="PROPERTY_HINT_PLACEHOLDER_TEXT" value="19" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_PLACEHOLDER_TEXT" value="20" enum="PropertyHint">
Hints that a string property should have a placeholder text visible on its input field, whenever the property is empty. The hint string is the placeholder text to use.
</constant>
- <constant name="PROPERTY_HINT_COLOR_NO_ALPHA" value="20" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_COLOR_NO_ALPHA" value="21" enum="PropertyHint">
Hints that a color property should be edited without changing its alpha component, i.e. only R, G and B channels are edited.
</constant>
- <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSY" value="21" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSY" value="22" enum="PropertyHint">
Hints that an image is compressed using lossy compression.
</constant>
- <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS" value="22" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS" value="23" enum="PropertyHint">
Hints that an image is compressed using lossless compression.
</constant>
- <constant name="PROPERTY_HINT_TYPE_STRING" value="24" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_TYPE_STRING" value="25" enum="PropertyHint">
Hint that a property represents a particular type. If a property is [constant TYPE_STRING], allows to set a type from the create dialog. If you need to create an [Array] to contain elements of a specific type, the [code]hint_string[/code] must encode nested types using [code]":"[/code] and [code]"/"[/code] for specifying [Resource] types. For instance:
[codeblock]
hint_string = "%s:" % [TYPE_INT] # Array of inteters.
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index 47e26b7a2e..9c4600e4f3 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -1164,8 +1164,9 @@
<member name="theme" type="Theme" setter="set_theme" getter="get_theme">
The [Theme] resource this node and all its [Control] children use. If a child node has its own [Theme] resource set, theme items are merged with child's definitions having higher priority.
</member>
- <member name="theme_custom_type" type="StringName" setter="set_theme_custom_type" getter="get_theme_custom_type" default="&amp;&quot;&quot;">
- The type name used by this [Control] to look up its own theme items. By default, the class name of the node is used (e.g. [code]Button[/code] for the [Button] control), as well as the class names of all parent classes (in order of inheritance). Setting this property gives the highest priority to the type of the specified name, then falls back on the class names.
+ <member name="theme_type_variation" type="StringName" setter="set_theme_type_variation" getter="get_theme_type_variation" default="&amp;&quot;&quot;">
+ The name of a theme type variation used by this [Control] to look up its own theme items. When empty, the class name of the node is used (e.g. [code]Button[/code] for the [Button] control), as well as the class names of all parent classes (in order of inheritance).
+ When set, this property gives the highest priority to the type of the specified name. This type can in turn extend another type, forming a dependency chain. See [method Theme.set_type_variation]. If the theme item cannot be found using this type or its base types, lookup falls back on the class names.
[b]Note:[/b] To look up [Control]'s own items use various [code]get_theme_*[/code] methods without specifying [code]theme_type[/code].
[b]Note:[/b] Theme items are looked for in the tree order, from branch to root, where each [Control] node is checked for its [member theme] property. The earliest match against any type/class name is returned. The project-level Theme and the default Theme are checked last.
</member>
diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml
index ef20174ee6..17b51d5cbe 100644
--- a/doc/classes/DisplayServer.xml
+++ b/doc/classes/DisplayServer.xml
@@ -44,9 +44,11 @@
</return>
<argument index="0" name="mode" type="int" enum="DisplayServer.WindowMode">
</argument>
- <argument index="1" name="flags" type="int">
+ <argument index="1" name="vsync_mode" type="int" enum="DisplayServer.VSyncMode">
</argument>
- <argument index="2" name="rect" type="Rect2i" default="Rect2i(0, 0, 0, 0)">
+ <argument index="2" name="flags" type="int">
+ </argument>
+ <argument index="3" name="rect" type="Rect2i" default="Rect2i(0, 0, 0, 0)">
</argument>
<description>
</description>
@@ -671,34 +673,6 @@
[b]Note:[/b] This method is implemented on Android, iOS and UWP.
</description>
</method>
- <method name="vsync_is_enabled" qualifiers="const">
- <return type="bool">
- </return>
- <description>
- </description>
- </method>
- <method name="vsync_is_using_via_compositor" qualifiers="const">
- <return type="bool">
- </return>
- <description>
- </description>
- </method>
- <method name="vsync_set_enabled">
- <return type="void">
- </return>
- <argument index="0" name="enabled" type="bool">
- </argument>
- <description>
- </description>
- </method>
- <method name="vsync_set_use_via_compositor">
- <return type="void">
- </return>
- <argument index="0" name="enabled" type="bool">
- </argument>
- <description>
- </description>
- </method>
<method name="window_attach_instance_id">
<return type="void">
</return>
@@ -791,6 +765,15 @@
<description>
</description>
</method>
+ <method name="window_get_vsync_mode" qualifiers="const">
+ <return type="int" enum="DisplayServer.VSyncMode">
+ </return>
+ <argument index="0" name="window_id" type="int" default="0">
+ </argument>
+ <description>
+ Returns the VSync mode of the given window.
+ </description>
+ </method>
<method name="window_move_to_foreground">
<return type="void">
</return>
@@ -995,6 +978,19 @@
<description>
</description>
</method>
+ <method name="window_set_vsync_mode">
+ <return type="void">
+ </return>
+ <argument index="0" name="vsync_mode" type="int" enum="DisplayServer.VSyncMode">
+ </argument>
+ <argument index="1" name="window_id" type="int" default="0">
+ </argument>
+ <description>
+ Sets the VSync mode of the given window.
+ See [enum DisplayServer.VSyncMode] for possible values and how they affect the behavior of your application.
+ Depending on the platform and used renderer, the engine will fall back to [constant VSYNC_ENABLED], if the desired mode is not supported.
+ </description>
+ </method>
<method name="window_set_window_event_callback">
<return type="void">
</return>
@@ -1151,5 +1147,18 @@
</constant>
<constant name="WINDOW_EVENT_DPI_CHANGE" value="6" enum="WindowEvent">
</constant>
+ <constant name="VSYNC_DISABLED" value="0" enum="VSyncMode">
+ No vertical synchronization, which means the engine will display frames as fast as possible (tearing may be visible).
+ </constant>
+ <constant name="VSYNC_ENABLED" value="1" enum="VSyncMode">
+ Default vertical synchronization mode, the image is displayed only on vertical blanking intervals (no tearing is visible).
+ </constant>
+ <constant name="VSYNC_ADAPTIVE" value="2" enum="VSyncMode">
+ Behaves like [constant VSYNC_DISABLED] when the framerate drops below the screen's refresh rate to reduce stuttering (tearing may be visible), otherwise vertical synchronization is enabled to avoid tearing.
+ </constant>
+ <constant name="VSYNC_MAILBOX" value="3" enum="VSyncMode">
+ Displays the most recent image in the queue on vertical blanking intervals, while rendering to the other images (no tearing is visible).
+ Although not guaranteed, the images can be rendered as fast as possible, which may reduce input lag.
+ </constant>
</constants>
</class>
diff --git a/doc/classes/HTTPClient.xml b/doc/classes/HTTPClient.xml
index a549994a69..a08bed751f 100644
--- a/doc/classes/HTTPClient.xml
+++ b/doc/classes/HTTPClient.xml
@@ -158,7 +158,8 @@
<argument index="3" name="body" type="String" default="&quot;&quot;">
</argument>
<description>
- Sends a request to the connected host. The URL parameter is just the part after the host, so for [code]http://somehost.com/index.php[/code], it is [code]index.php[/code].
+ Sends a request to the connected host.
+ The URL parameter is usually just the part after the host, so for [code]http://somehost.com/index.php[/code], it is [code]/index.php[/code]. When sending requests to an HTTP proxy server, it should be an absolute URL. For [constant HTTPClient.METHOD_OPTIONS] requests, [code]*[/code] is also allowed. For [constant HTTPClient.METHOD_CONNECT] requests, it should be the authority component ([code]host:port[/code]).
Headers are HTTP request headers. For available HTTP methods, see [enum Method].
To create a POST request with query strings to push to the server, do:
[codeblocks]
@@ -166,7 +167,7 @@
var fields = {"username" : "user", "password" : "pass"}
var query_string = http_client.query_string_from_dict(fields)
var headers = ["Content-Type: application/x-www-form-urlencoded", "Content-Length: " + str(query_string.length())]
- var result = http_client.request(http_client.METHOD_POST, "index.php", headers, query_string)
+ var result = http_client.request(http_client.METHOD_POST, "/index.php", headers, query_string)
[/gdscript]
[csharp]
var fields = new Godot.Collections.Dictionary { { "username", "user" }, { "password", "pass" } };
@@ -190,7 +191,8 @@
<argument index="3" name="body" type="PackedByteArray">
</argument>
<description>
- Sends a raw request to the connected host. The URL parameter is just the part after the host, so for [code]http://somehost.com/index.php[/code], it is [code]index.php[/code].
+ Sends a raw request to the connected host.
+ The URL parameter is usually just the part after the host, so for [code]http://somehost.com/index.php[/code], it is [code]/index.php[/code]. When sending requests to an HTTP proxy server, it should be an absolute URL. For [constant HTTPClient.METHOD_OPTIONS] requests, [code]*[/code] is also allowed. For [constant HTTPClient.METHOD_CONNECT] requests, it should be the authority component ([code]host:port[/code]).
Headers are HTTP request headers. For available HTTP methods, see [enum Method].
Sends the body data raw, as a byte array and does not encode it in any way.
</description>
diff --git a/doc/classes/Label.xml b/doc/classes/Label.xml
index 0789ac9010..ca22567ad5 100644
--- a/doc/classes/Label.xml
+++ b/doc/classes/Label.xml
@@ -75,8 +75,8 @@
<member name="align" type="int" setter="set_align" getter="get_align" enum="Label.Align" default="0">
Controls the text's horizontal align. Supports left, center, right, and fill, or justify. Set it to one of the [enum Align] constants.
</member>
- <member name="autowrap" type="bool" setter="set_autowrap" getter="has_autowrap" default="false">
- If [code]true[/code], wraps the text inside the node's bounding rectangle. If you resize the node, it will change its height automatically to show all the text.
+ <member name="autowrap_mode" type="int" setter="set_autowrap_mode" getter="get_autowrap_mode" enum="Label.AutowrapMode" default="0">
+ If set to something other than [constant AUTOWRAP_OFF], the text gets wrapped inside the node's bounding rectangle. If you resize the node, it will change its height automatically to show all the text. To see how each mode behaves, see [enum AutowrapMode].
</member>
<member name="clip_text" type="bool" setter="set_clip_text" getter="is_clipping_text" default="false">
If [code]true[/code], the Label only shows the text that fits inside its bounding rectangle and will clip text horizontally.
@@ -107,6 +107,9 @@
<member name="text_direction" type="int" setter="set_text_direction" getter="get_text_direction" enum="Control.TextDirection" default="0">
Base text writing direction.
</member>
+ <member name="text_overrun_behavior" type="int" setter="set_text_overrun_behavior" getter="get_text_overrun_behavior" enum="Label.OverrunBehavior" default="0">
+ Sets the clipping behavior when the text exceeds the node's bounding rectangle. See [enum OverrunBehavior] for a description of all modes.
+ </member>
<member name="uppercase" type="bool" setter="set_uppercase" getter="is_uppercase" default="false">
If [code]true[/code], all the text displays as UPPERCASE.
</member>
@@ -142,6 +145,33 @@
<constant name="VALIGN_FILL" value="3" enum="VAlign">
Align the whole text by spreading the rows.
</constant>
+ <constant name="AUTOWRAP_OFF" value="0" enum="AutowrapMode">
+ Autowrap is disabled.
+ </constant>
+ <constant name="AUTOWRAP_ARBITRARY" value="1" enum="AutowrapMode">
+ Wraps the text inside the node's bounding rectangle by allowing to break lines at arbitrary positions, which is useful when very limited space is available.
+ </constant>
+ <constant name="AUTOWRAP_WORD" value="2" enum="AutowrapMode">
+ Wraps the text inside the node's bounding rectangle by soft-breaking between words.
+ </constant>
+ <constant name="AUTOWRAP_WORD_SMART" value="3" enum="AutowrapMode">
+ Behaves similarly to [constant AUTOWRAP_WORD], but force-breaks a word if that single word does not fit in one line.
+ </constant>
+ <constant name="OVERRUN_NO_TRIMMING" value="0" enum="OverrunBehavior">
+ No text trimming is performed.
+ </constant>
+ <constant name="OVERRUN_TRIM_CHAR" value="1" enum="OverrunBehavior">
+ Trims the text per character.
+ </constant>
+ <constant name="OVERRUN_TRIM_WORD" value="2" enum="OverrunBehavior">
+ Trims the text per word.
+ </constant>
+ <constant name="OVERRUN_TRIM_ELLIPSIS" value="3" enum="OverrunBehavior">
+ Trims the text per character and adds an ellipsis to indicate that parts are hidden.
+ </constant>
+ <constant name="OVERRUN_TRIM_WORD_ELLIPSIS" value="4" enum="OverrunBehavior">
+ Trims the text per word and adds an ellipsis to indicate that parts are hidden.
+ </constant>
</constants>
<theme_items>
<theme_item name="font" type="Font">
diff --git a/doc/classes/Mesh.xml b/doc/classes/Mesh.xml
index 3bbdfbe62e..2cc0bd2ef9 100644
--- a/doc/classes/Mesh.xml
+++ b/doc/classes/Mesh.xml
@@ -16,8 +16,14 @@
<method name="create_convex_shape" qualifiers="const">
<return type="Shape3D">
</return>
+ <argument index="0" name="clean" type="bool" default="true">
+ </argument>
+ <argument index="1" name="simplify" type="bool" default="false">
+ </argument>
<description>
Calculate a [ConvexPolygonShape3D] from the mesh.
+ If [code]clean[/code] is [code]true[/code] (default), duplicate and interior vertices are removed automatically. You can set it to [code]false[/code] to make the process faster if not needed.
+ If [code]simplify[/code] is [code]true[/code], the geometry can be further simplified to reduce the amount of vertices. Disabled by default.
</description>
</method>
<method name="create_outline" qualifiers="const">
diff --git a/doc/classes/MeshInstance3D.xml b/doc/classes/MeshInstance3D.xml
index 7c4e75793e..930301a742 100644
--- a/doc/classes/MeshInstance3D.xml
+++ b/doc/classes/MeshInstance3D.xml
@@ -16,8 +16,14 @@
<method name="create_convex_collision">
<return type="void">
</return>
+ <argument index="0" name="clean" type="bool" default="true">
+ </argument>
+ <argument index="1" name="simplify" type="bool" default="false">
+ </argument>
<description>
This helper creates a [StaticBody3D] child node with a [ConvexPolygonShape3D] collision shape calculated from the mesh geometry. It's mainly used for testing.
+ If [code]clean[/code] is [code]true[/code] (default), duplicate and interior vertices are removed automatically. You can set it to [code]false[/code] to make the process faster if not needed.
+ If [code]simplify[/code] is [code]true[/code], the geometry can be further simplified to reduce the amount of vertices. Disabled by default.
</description>
</method>
<method name="create_debug_tangents">
diff --git a/doc/classes/MultiplayerAPI.xml b/doc/classes/MultiplayerAPI.xml
index 5de5703d95..c4d8a5b1b9 100644
--- a/doc/classes/MultiplayerAPI.xml
+++ b/doc/classes/MultiplayerAPI.xml
@@ -4,7 +4,7 @@
High-level multiplayer API.
</brief_description>
<description>
- This class implements most of the logic behind the high-level multiplayer API. See also [NetworkedMultiplayerPeer].
+ This class implements most of the logic behind the high-level multiplayer API. See also [MultiplayerPeer].
By default, [SceneTree] has a reference to this class that is used to provide multiplayer capabilities (i.e. RPC/RSET) across the whole scene.
It is possible to override the MultiplayerAPI instance used by specific Nodes by setting the [member Node.custom_multiplayer] property, effectively allowing to run both client and server in the same scene.
[b]Note:[/b] The high-level multiplayer API protocol is an implementation detail and isn't meant to be used by non-Godot servers. It may change without notice.
@@ -70,10 +70,10 @@
</argument>
<argument index="1" name="id" type="int" default="0">
</argument>
- <argument index="2" name="mode" type="int" enum="NetworkedMultiplayerPeer.TransferMode" default="2">
+ <argument index="2" name="mode" type="int" enum="MultiplayerPeer.TransferMode" default="2">
</argument>
<description>
- Sends the given raw [code]bytes[/code] to a specific peer identified by [code]id[/code] (see [method NetworkedMultiplayerPeer.set_target_peer]). Default ID is [code]0[/code], i.e. broadcast to all peers.
+ Sends the given raw [code]bytes[/code] to a specific peer identified by [code]id[/code] (see [method MultiplayerPeer.set_target_peer]). Default ID is [code]0[/code], i.e. broadcast to all peers.
</description>
</method>
</methods>
@@ -82,7 +82,7 @@
If [code]true[/code], the MultiplayerAPI will allow encoding and decoding of object during RPCs/RSETs.
[b]Warning:[/b] Deserialized objects can contain code which gets executed. Do not use this option if the serialized object comes from untrusted sources to avoid potential security threats such as remote code execution.
</member>
- <member name="network_peer" type="NetworkedMultiplayerPeer" setter="set_network_peer" getter="get_network_peer">
+ <member name="network_peer" type="MultiplayerPeer" 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, 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" default="false">
diff --git a/doc/classes/NetworkedMultiplayerPeer.xml b/doc/classes/MultiplayerPeer.xml
index 06ea46f023..713cd64b82 100644
--- a/doc/classes/NetworkedMultiplayerPeer.xml
+++ b/doc/classes/MultiplayerPeer.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="NetworkedMultiplayerPeer" inherits="PacketPeer" version="4.0">
+<class name="MultiplayerPeer" inherits="PacketPeer" version="4.0">
<brief_description>
A high-level network interface to simplify multiplayer interactions.
</brief_description>
@@ -13,7 +13,7 @@
</tutorials>
<methods>
<method name="get_connection_status" qualifiers="const">
- <return type="int" enum="NetworkedMultiplayerPeer.ConnectionStatus">
+ <return type="int" enum="MultiplayerPeer.ConnectionStatus">
</return>
<description>
Returns the current state of the connection. See [enum ConnectionStatus].
@@ -23,14 +23,14 @@
<return type="int">
</return>
<description>
- Returns the ID of the [NetworkedMultiplayerPeer] who sent the most recent packet.
+ Returns the ID of the [MultiplayerPeer] who sent the most recent packet.
</description>
</method>
<method name="get_unique_id" qualifiers="const">
<return type="int">
</return>
<description>
- Returns the ID of this [NetworkedMultiplayerPeer].
+ Returns the ID of this [MultiplayerPeer].
</description>
</method>
<method name="poll">
@@ -53,9 +53,9 @@
</methods>
<members>
<member name="refuse_new_connections" type="bool" setter="set_refuse_new_connections" getter="is_refusing_new_connections" default="true">
- If [code]true[/code], this [NetworkedMultiplayerPeer] refuses new connections.
+ If [code]true[/code], this [MultiplayerPeer] refuses new connections.
</member>
- <member name="transfer_mode" type="int" setter="set_transfer_mode" getter="get_transfer_mode" enum="NetworkedMultiplayerPeer.TransferMode" default="0">
+ <member name="transfer_mode" type="int" setter="set_transfer_mode" getter="get_transfer_mode" enum="MultiplayerPeer.TransferMode" default="0">
The manner in which to send packets to the [code]target_peer[/code]. See [enum TransferMode].
</member>
</members>
diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml
index 88e69968d2..fc971effd7 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -14,7 +14,7 @@
To keep track of the scene hierarchy (especially when instancing scenes into other scenes), an "owner" can be set for the node with the [member owner] property. This keeps track of who instantiated what. This is mostly useful when writing editors and tools, though.
Finally, when a node is freed with [method Object.free] or [method queue_free], it will also free all its children.
[b]Groups:[/b] Nodes can be added to as many groups as you want to be easy to manage, you could create groups like "enemies" or "collectables" for example, depending on your game. See [method add_to_group], [method is_in_group] and [method remove_from_group]. You can then retrieve all nodes in these groups, iterate them and even call methods on groups via the methods on [SceneTree].
- [b]Networking with nodes:[/b] After connecting to a server (or making one, see [NetworkedMultiplayerENet]), it is possible to use the built-in RPC (remote procedure call) system to communicate over the network. By calling [method rpc] with a method name, it will be called locally and in all connected peers (peers = clients and the server that accepts connections). To identify which node receives the RPC call, Godot will use its [NodePath] (make sure node names are the same on all peers). Also, take a look at the high-level networking tutorial and corresponding demos.
+ [b]Networking with nodes:[/b] After connecting to a server (or making one, see [ENetMultiplayerPeer]), it is possible to use the built-in RPC (remote procedure call) system to communicate over the network. By calling [method rpc] with a method name, it will be called locally and in all connected peers (peers = clients and the server that accepts connections). To identify which node receives the RPC call, Godot will use its [NodePath] (make sure node names are the same on all peers). Also, take a look at the high-level networking tutorial and corresponding demos.
</description>
<tutorials>
<link title="Scenes and nodes">https://docs.godotengine.org/en/latest/getting_started/step_by_step/scenes_and_nodes.html</link>
@@ -660,7 +660,7 @@
</argument>
<description>
Sends a remote procedure call request for the given [code]method[/code] to peers on the network (and locally), optionally sending all additional arguments as arguments to the method called by the RPC. The call request will only be received by nodes with the same [NodePath], including the exact same node name. Behaviour depends on the RPC configuration for the given method, see [method rpc_config]. Methods are not exposed to RPCs by default. Returns an empty [Variant].
- [b]Note:[/b] You can only safely use RPCs on clients after you received the [code]connected_to_server[/code] signal from the [SceneTree]. You also need to keep track of the connection state, either by the [SceneTree] signals like [code]server_disconnected[/code] or by checking [code]SceneTree.network_peer.get_connection_status() == CONNECTION_CONNECTED[/code].
+ [b]Note:[/b] You can only safely use RPCs on clients after you received the [code]connected_to_server[/code] signal from the [MultiplayerAPI]. You also need to keep track of the connection state, either by the [MultiplayerAPI] signals like [code]server_disconnected[/code] or by checking [code]get_multiplayer().network_peer.get_connection_status() == CONNECTION_CONNECTED[/code].
</description>
</method>
<method name="rpc_config">
@@ -670,12 +670,12 @@
</argument>
<argument index="1" name="rpc_mode" type="int" enum="MultiplayerAPI.RPCMode">
</argument>
- <argument index="2" name="transfer_mode" type="int" enum="NetworkedMultiplayerPeer.TransferMode" default="2">
+ <argument index="2" name="transfer_mode" type="int" enum="MultiplayerPeer.TransferMode" default="2">
</argument>
<argument index="3" name="channel" type="int" default="0">
</argument>
<description>
- Changes the RPC mode for the given [code]method[/code] to the given [code]rpc_mode[/code], optionally specifying the [code]transfer_mode[/code] and [code]channel[/code] (on supported peers). See [enum MultiplayerAPI.RPCMode] and [enum NetworkedMultiplayerPeer.TransferMode]. 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).
+ Changes the RPC mode for the given [code]method[/code] to the given [code]rpc_mode[/code], optionally specifying the [code]transfer_mode[/code] and [code]channel[/code] (on supported peers). See [enum MultiplayerAPI.RPCMode] and [enum MultiplayerPeer.TransferMode]. 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).
</description>
</method>
<method name="rpc_id" qualifiers="vararg">
@@ -686,7 +686,7 @@
<argument index="1" name="method" type="StringName">
</argument>
<description>
- Sends a [method rpc] to a specific peer identified by [code]peer_id[/code] (see [method NetworkedMultiplayerPeer.set_target_peer]). Returns an empty [Variant].
+ Sends a [method rpc] to a specific peer identified by [code]peer_id[/code] (see [method MultiplayerPeer.set_target_peer]). Returns an empty [Variant].
</description>
</method>
<method name="set_display_folded">
diff --git a/doc/classes/PacketPeerUDP.xml b/doc/classes/PacketPeerUDP.xml
index 5d059ad3df..2707df612c 100644
--- a/doc/classes/PacketPeerUDP.xml
+++ b/doc/classes/PacketPeerUDP.xml
@@ -148,7 +148,7 @@
var socket = new PacketPeerUDP();
// Server
socket.SetDestAddress("127.0.0.1", 789);
- socket.PutPacket("Time To Stop".ToAscii());
+ socket.PutPacket("Time to stop".ToAscii());
// Client
while (socket.Wait() == OK)
diff --git a/doc/classes/PlaneMesh.xml b/doc/classes/PlaneMesh.xml
index c95ba29ea2..56bf98772b 100644
--- a/doc/classes/PlaneMesh.xml
+++ b/doc/classes/PlaneMesh.xml
@@ -12,6 +12,9 @@
<methods>
</methods>
<members>
+ <member name="center_offset" type="Vector3" setter="set_center_offset" getter="get_center_offset" default="Vector3(0, 0, 0)">
+ Offset of the generated plane. Useful for particles.
+ </member>
<member name="size" type="Vector2" setter="set_size" getter="get_size" default="Vector2(2, 2)">
Size of the generated plane.
</member>
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 366a0a5f0f..fbd257cdba 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -445,7 +445,7 @@
</member>
<member name="debug/settings/fps/force_fps" type="int" setter="" getter="" default="0">
Maximum number of frames per second allowed. The actual number of frames per second may still be below this value if the game is lagging.
- If [member display/window/vsync/use_vsync] is enabled, it takes precedence and the forced FPS number cannot exceed the monitor's refresh rate.
+ If [member display/window/vsync/vsync_mode] is set to [code]Enabled[/code] or [code]Adaptive[/code], it takes precedence and the forced FPS number cannot exceed the monitor's refresh rate.
This setting is therefore mostly relevant for lowering the maximum FPS below VSync, e.g. to perform non-real-time rendering of static frames, or test the project under lag conditions.
</member>
<member name="debug/settings/gdscript/max_call_stack" type="int" setter="" getter="" default="1024">
@@ -532,12 +532,10 @@
<member name="display/window/size/width" type="int" setter="" getter="" default="1024">
Sets the game's main viewport width. On desktop platforms, this is the default window size. Stretch mode settings also use this as a reference when enabled.
</member>
- <member name="display/window/vsync/use_vsync" type="bool" setter="" getter="" default="true">
- If [code]true[/code], enables vertical synchronization. This eliminates tearing that may appear in moving scenes, at the cost of higher input latency and stuttering at lower framerates. If [code]false[/code], vertical synchronization will be disabled, however, many platforms will enforce it regardless (such as mobile platforms and HTML5).
- </member>
- <member name="display/window/vsync/vsync_via_compositor" type="bool" setter="" getter="" default="false">
- If [code]Use Vsync[/code] is enabled and this setting is [code]true[/code], enables vertical synchronization via the operating system's window compositor when in windowed mode and the compositor is enabled. This will prevent stutter in certain situations. (Windows only.)
- [b]Note:[/b] This option is experimental and meant to alleviate stutter experienced by some users. However, some users have experienced a Vsync framerate halving (e.g. from 60 FPS to 30 FPS) when using it.
+ <member name="display/window/vsync/vsync_mode" type="int" setter="" getter="" default="1">
+ Sets the VSync mode for the main game window.
+ See [enum DisplayServer.VSyncMode] for possible values and how they affect the behavior of your application.
+ Depending on the platform and used renderer, the engine will fall back to [code]Enabled[/code], if the desired mode is not supported.
</member>
<member name="editor/node_naming/name_casing" type="int" setter="" getter="" default="0">
When creating node names automatically, set the type of casing in this project. This is mostly an editor setting.
diff --git a/doc/classes/QuadMesh.xml b/doc/classes/QuadMesh.xml
index 94d638888c..4209e3db14 100644
--- a/doc/classes/QuadMesh.xml
+++ b/doc/classes/QuadMesh.xml
@@ -13,6 +13,9 @@
<methods>
</methods>
<members>
+ <member name="center_offset" type="Vector3" setter="set_center_offset" getter="get_center_offset" default="Vector3(0, 0, 0)">
+ Offset of the generated Quad. Useful for particles.
+ </member>
<member name="size" type="Vector2" setter="set_size" getter="get_size" default="Vector2(1, 1)">
Size on the X and Y axes.
</member>
diff --git a/doc/classes/RDPipelineSpecializationConstant.xml b/doc/classes/RDPipelineSpecializationConstant.xml
new file mode 100644
index 0000000000..4d9481b846
--- /dev/null
+++ b/doc/classes/RDPipelineSpecializationConstant.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDPipelineSpecializationConstant" inherits="RefCounted" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="constant_id" type="int" setter="set_constant_id" getter="get_constant_id" default="0">
+ </member>
+ <member name="value" type="Variant" setter="set_value" getter="get_value">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml
index f2b22af8c6..901a985961 100644
--- a/doc/classes/RenderingDevice.xml
+++ b/doc/classes/RenderingDevice.xml
@@ -140,6 +140,8 @@
</return>
<argument index="0" name="shader" type="RID">
</argument>
+ <argument index="1" name="specialization_constants" type="RDPipelineSpecializationConstant[]" default="[]">
+ </argument>
<description>
</description>
</method>
@@ -580,6 +582,8 @@
</argument>
<argument index="9" name="for_render_pass" type="int" default="0">
</argument>
+ <argument index="10" name="specialization_constants" type="RDPipelineSpecializationConstant[]" default="[]">
+ </argument>
<description>
</description>
</method>
@@ -1709,6 +1713,12 @@
</constant>
<constant name="SHADER_LANGUAGE_HLSL" value="1" enum="ShaderLanguage">
</constant>
+ <constant name="PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL" value="0" enum="PipelineSpecializationConstantType">
+ </constant>
+ <constant name="PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT" value="1" enum="PipelineSpecializationConstantType">
+ </constant>
+ <constant name="PIPELINE_SPECIALIZATION_CONSTANT_TYPE_FLOAT" value="2" enum="PipelineSpecializationConstantType">
+ </constant>
<constant name="LIMIT_MAX_BOUND_UNIFORM_SETS" value="0" enum="Limit">
</constant>
<constant name="LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS" value="1" enum="Limit">
diff --git a/doc/classes/SceneTree.xml b/doc/classes/SceneTree.xml
index d327e8cbca..bf51b4dfa7 100644
--- a/doc/classes/SceneTree.xml
+++ b/doc/classes/SceneTree.xml
@@ -112,20 +112,6 @@
Returns the current frame number, i.e. the total frame count since the application started.
</description>
</method>
- <method name="get_network_connected_peers" qualifiers="const">
- <return type="PackedInt32Array">
- </return>
- <description>
- Returns the peer IDs of all connected peers of this [SceneTree]'s [member network_peer].
- </description>
- </method>
- <method name="get_network_unique_id" qualifiers="const">
- <return type="int">
- </return>
- <description>
- Returns the unique peer ID of this [SceneTree]'s [member network_peer].
- </description>
- </method>
<method name="get_node_count" qualifiers="const">
<return type="int">
</return>
@@ -149,13 +135,6 @@
Returns an array of currently exising [Tween]s in the [SceneTree] (both running and paused).
</description>
</method>
- <method name="get_rpc_sender_id" qualifiers="const">
- <return type="int">
- </return>
- <description>
- Returns the sender's peer ID for the most recently received RPC call.
- </description>
- </method>
<method name="has_group" qualifiers="const">
<return type="bool">
</return>
@@ -165,20 +144,6 @@
Returns [code]true[/code] if the given group exists.
</description>
</method>
- <method name="has_network_peer" qualifiers="const">
- <return type="bool">
- </return>
- <description>
- Returns [code]true[/code] if there is a [member network_peer] set.
- </description>
- </method>
- <method name="is_network_server" qualifiers="const">
- <return type="bool">
- </return>
- <description>
- Returns [code]true[/code] if this [SceneTree]'s [member network_peer] is in server mode (listening for connections).
- </description>
- </method>
<method name="notify_group">
<return type="void">
</return>
@@ -301,32 +266,16 @@
If [code]true[/code] (default value), enables automatic polling of the [MultiplayerAPI] for this SceneTree during [signal process_frame].
If [code]false[/code], you need to manually call [method MultiplayerAPI.poll] to process network packets and deliver RPCs/RSETs. This allows running 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 the root node's network mode to master, or it will become a regular peer with the 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" default="false">
If [code]true[/code], the [SceneTree] is paused. Doing so will have the following behavior:
- 2D and 3D physics will be stopped.
- [method Node._process], [method Node._physics_process] and [method Node._input] will not be called anymore in nodes.
</member>
- <member name="refuse_new_network_connections" type="bool" setter="set_refuse_new_network_connections" getter="is_refusing_new_network_connections" default="false">
- If [code]true[/code], the [SceneTree]'s [member network_peer] refuses new incoming connections.
- </member>
<member name="root" type="Window" setter="" getter="get_root">
The [SceneTree]'s root [Window].
</member>
</members>
<signals>
- <signal name="connected_to_server">
- <description>
- Emitted whenever this [SceneTree]'s [member network_peer] successfully connected to a server. Only emitted on clients.
- </description>
- </signal>
- <signal name="connection_failed">
- <description>
- Emitted whenever this [SceneTree]'s [member network_peer] fails to establish a connection to a server. Only emitted on clients.
- </description>
- </signal>
<signal name="files_dropped">
<argument index="0" name="files" type="PackedStringArray">
</argument>
@@ -336,20 +285,6 @@
Emitted when files are dragged from the OS file manager and dropped in the game window. The arguments are a list of file paths and the identifier of the screen where the drag originated.
</description>
</signal>
- <signal name="network_peer_connected">
- <argument index="0" name="id" type="int">
- </argument>
- <description>
- Emitted whenever this [SceneTree]'s [member network_peer] connects with a new peer. ID is the peer ID of the new peer. Clients get notified when other clients connect to the same server. Upon connecting to a server, a client also receives this signal for the server (with ID being 1).
- </description>
- </signal>
- <signal name="network_peer_disconnected">
- <argument index="0" name="id" type="int">
- </argument>
- <description>
- Emitted whenever this [SceneTree]'s [member network_peer] disconnects from a peer. Clients get notified when other clients disconnect from the same server.
- </description>
- </signal>
<signal name="node_added">
<argument index="0" name="node" type="Node">
</argument>
@@ -388,11 +323,6 @@
Emitted immediately before [method Node._process] is called on every node in the [SceneTree].
</description>
</signal>
- <signal name="server_disconnected">
- <description>
- Emitted whenever this [SceneTree]'s [member network_peer] disconnected from server. Only emitted on clients.
- </description>
- </signal>
<signal name="tree_changed">
<description>
Emitted whenever the [SceneTree] hierarchy changed (children being moved or renamed, etc.).
diff --git a/doc/classes/TextServer.xml b/doc/classes/TextServer.xml
index c943946ab3..0f9318fda1 100644
--- a/doc/classes/TextServer.xml
+++ b/doc/classes/TextServer.xml
@@ -1088,6 +1088,19 @@
Returns composite character end position closest to the [code]pos[/code].
</description>
</method>
+ <method name="shaped_text_overrun_trim_to_width">
+ <return type="void">
+ </return>
+ <argument index="0" name="shaped" type="RID">
+ </argument>
+ <argument index="1" name="width" type="float" default="0">
+ </argument>
+ <argument index="2" name="overrun_trim_flags" type="int" default="0">
+ </argument>
+ <description>
+ Trims text if it exceeds the given width.
+ </description>
+ </method>
<method name="shaped_text_prev_grapheme_pos">
<return type="int">
</return>
@@ -1260,6 +1273,21 @@
<constant name="BREAK_GRAPHEME_BOUND" value="64" enum="LineBreakFlag">
Break the line between any unconnected graphemes.
</constant>
+ <constant name="OVERRUN_NO_TRIMMING" value="0" enum="TextOverrunFlag">
+ No trimming is performed.
+ </constant>
+ <constant name="OVERRUN_TRIM" value="1" enum="TextOverrunFlag">
+ Trims the text when it exceeds the given width.
+ </constant>
+ <constant name="OVERRUN_TRIM_WORD_ONLY" value="2" enum="TextOverrunFlag">
+ Trims the text per word instead of per grapheme.
+ </constant>
+ <constant name="OVERRUN_ADD_ELLIPSIS" value="4" enum="TextOverrunFlag">
+ Determines whether an ellipsis should be added at the end of the text.
+ </constant>
+ <constant name="OVERRUN_ENFORCE_ELLIPSIS" value="8" enum="TextOverrunFlag">
+ Determines whether the ellipsis at the end of the text is enforced and may not be hidden.
+ </constant>
<constant name="GRAPHEME_IS_RTL" value="2" enum="GraphemeFlag">
Grapheme is part of right-to-left or bottom-to-top run.
</constant>
diff --git a/doc/classes/Theme.xml b/doc/classes/Theme.xml
index 7448697df3..969d8ab2a4 100644
--- a/doc/classes/Theme.xml
+++ b/doc/classes/Theme.xml
@@ -97,6 +97,15 @@
Clears the theme item of [code]data_type[/code] at [code]name[/code] if the theme has [code]theme_type[/code].
</description>
</method>
+ <method name="clear_type_variation">
+ <return type="void">
+ </return>
+ <argument index="0" name="theme_type" type="StringName">
+ </argument>
+ <description>
+ Unmarks [code]theme_type[/code] as being a variation of any other type.
+ </description>
+ </method>
<method name="copy_default_theme">
<return type="void">
</return>
@@ -319,6 +328,24 @@
Returns all the theme types as a [PackedStringArray] filled with unique type names, for use in other [code]get_*[/code] functions of this theme.
</description>
</method>
+ <method name="get_type_variation_base" qualifiers="const">
+ <return type="StringName">
+ </return>
+ <argument index="0" name="theme_type" type="StringName">
+ </argument>
+ <description>
+ Returns the base theme type if [code]theme_type[/code] is a valid variation type. Returns an empty string otherwise.
+ </description>
+ </method>
+ <method name="get_type_variation_list" qualifiers="const">
+ <return type="PackedStringArray">
+ </return>
+ <argument index="0" name="base_type" type="StringName">
+ </argument>
+ <description>
+ Returns a list of all variation for the given [code]base_type[/code].
+ </description>
+ </method>
<method name="has_color" qualifiers="const">
<return type="bool">
</return>
@@ -405,6 +432,17 @@
Returns [code]false[/code] if the theme does not have [code]theme_type[/code].
</description>
</method>
+ <method name="is_type_variation" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="theme_type" type="StringName">
+ </argument>
+ <argument index="1" name="base_type" type="StringName">
+ </argument>
+ <description>
+ Returns [code]true[/code] if [code]theme_type[/code] is marked as a variation of [code]base_type[/code] in this theme.
+ </description>
+ </method>
<method name="rename_color">
<return type="void">
</return>
@@ -599,6 +637,20 @@
Creates [code]theme_type[/code] if the theme does not have it.
</description>
</method>
+ <method name="set_type_variation">
+ <return type="void">
+ </return>
+ <argument index="0" name="theme_type" type="StringName">
+ </argument>
+ <argument index="1" name="base_type" type="StringName">
+ </argument>
+ <description>
+ Marks [code]theme_type[/code] as being a variation of [code]base_type[/code].
+ This adds [code]theme_type[/code] as a suggested option for [member Control.theme_type_variation] on a [Control] that is of the [code]base_type[/code] class.
+ Variations can also be nested, i.e. [code]base_type[/code] can be another variation. If a chain of variations ends with a [code]base_type[/code] matching a class of a [Control], the whole chain is going to be suggested as options.
+ Note: Suggestions only show up if this [Theme] is set as the project default theme. See [member ProjectSettings.gui/theme/custom].
+ </description>
+ </method>
</methods>
<members>
<member name="default_font" type="Font" setter="set_default_font" getter="get_default_font">
diff --git a/doc/classes/Window.xml b/doc/classes/Window.xml
index 73a95967bd..c8efaca1fc 100644
--- a/doc/classes/Window.xml
+++ b/doc/classes/Window.xml
@@ -347,7 +347,7 @@
</member>
<member name="theme" type="Theme" setter="set_theme" getter="get_theme">
</member>
- <member name="theme_custom_type" type="StringName" setter="set_theme_custom_type" getter="get_theme_custom_type" default="&amp;&quot;&quot;">
+ <member name="theme_type_variation" type="StringName" setter="set_theme_type_variation" getter="get_theme_type_variation" default="&amp;&quot;&quot;">
</member>
<member name="title" type="String" setter="set_title" getter="get_title" default="&quot;&quot;">
</member>
diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py
index 1c6055f8ca..9be7751d3d 100755
--- a/doc/tools/makerst.py
+++ b/doc/tools/makerst.py
@@ -350,6 +350,9 @@ def main(): # type: () -> None
pattern = re.compile(args.filter)
+ # Create the output folder recursively if it doesn't already exist.
+ os.makedirs(args.output, exist_ok=True)
+
for class_name, class_def in state.classes.items():
if args.filter and not pattern.search(class_def.filepath):
continue
@@ -358,6 +361,8 @@ def main(): # type: () -> None
if not state.errored:
print("No errors found.")
+ if not args.dry_run:
+ print("Wrote reStructuredText files for each class to: %s" % args.output)
else:
print("Errors were found in the class reference XML. Please check the messages above.")
exit(1)
@@ -837,7 +842,7 @@ def rstize_text(text, state): # type: (str, State) -> str
inside_code = True
elif cmd == "gdscript":
tag_depth += 1
- tag_text = "\n .. code-tab:: gdscript GDScript\n"
+ tag_text = "\n .. code-tab:: gdscript\n"
inside_code = True
elif cmd == "csharp":
tag_depth += 1
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index 6c1f1e4852..d3d49503d8 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -4374,6 +4374,8 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages
uint32_t stages_processed = 0;
+ Vector<Shader::SpecializationConstant> specialization_constants;
+
bool is_compute = false;
uint32_t compute_local_size[3] = { 0, 0, 0 };
@@ -4560,6 +4562,62 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages
}
}
+ {
+ //specialization constants
+
+ uint32_t sc_count = 0;
+ result = spvReflectEnumerateSpecializationConstants(&module, &sc_count, nullptr);
+ ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, RID(),
+ "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_stages[i].shader_stage]) + "' failed enumerating specialization constants.");
+
+ if (sc_count) {
+ Vector<SpvReflectSpecializationConstant *> spec_constants;
+ spec_constants.resize(sc_count);
+
+ result = spvReflectEnumerateSpecializationConstants(&module, &sc_count, spec_constants.ptrw());
+ ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, RID(),
+ "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_stages[i].shader_stage]) + "' failed obtaining specialization constants.");
+
+ for (uint32_t j = 0; j < sc_count; j++) {
+ int32_t existing = -1;
+ Shader::SpecializationConstant sconst;
+ sconst.constant.constant_id = spec_constants[j]->constant_id;
+ switch (spec_constants[j]->constant_type) {
+ case SPV_REFLECT_SPECIALIZATION_CONSTANT_BOOL: {
+ sconst.constant.type = PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL;
+ sconst.constant.bool_value = spec_constants[j]->default_value.int_bool_value != 0;
+ } break;
+ case SPV_REFLECT_SPECIALIZATION_CONSTANT_INT: {
+ sconst.constant.type = PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT;
+ sconst.constant.int_value = spec_constants[j]->default_value.int_bool_value;
+ } break;
+ case SPV_REFLECT_SPECIALIZATION_CONSTANT_FLOAT: {
+ sconst.constant.type = PIPELINE_SPECIALIZATION_CONSTANT_TYPE_FLOAT;
+ sconst.constant.float_value = spec_constants[j]->default_value.float_value;
+ } break;
+ }
+ sconst.stage_flags = 1 << p_stages[i].shader_stage;
+
+ print_line("spec constant " + itos(i) + ": " + String(spec_constants[j]->name) + " type " + itos(spec_constants[j]->constant_type) + " id " + itos(spec_constants[j]->constant_id));
+
+ for (int k = 0; k < specialization_constants.size(); k++) {
+ if (specialization_constants[k].constant.constant_id == sconst.constant.constant_id) {
+ ERR_FAIL_COND_V_MSG(specialization_constants[k].constant.type != sconst.constant.type, RID(), "More than one specialization constant used for id (" + itos(sconst.constant.constant_id) + "), but their types differ.");
+ ERR_FAIL_COND_V_MSG(specialization_constants[k].constant.int_value != sconst.constant.int_value, RID(), "More than one specialization constant used for id (" + itos(sconst.constant.constant_id) + "), but their default values differ.");
+ existing = k;
+ break;
+ }
+ }
+
+ if (existing > 0) {
+ specialization_constants.write[existing].stage_flags |= sconst.stage_flags;
+ } else {
+ specialization_constants.push_back(sconst);
+ }
+ }
+ }
+ }
+
if (stage == SHADER_STAGE_VERTEX) {
uint32_t iv_count = 0;
result = spvReflectEnumerateInputVariables(&module, &iv_count, nullptr);
@@ -4656,6 +4714,7 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages
shader.compute_local_size[0] = compute_local_size[0];
shader.compute_local_size[1] = compute_local_size[1];
shader.compute_local_size[2] = compute_local_size[2];
+ shader.specialization_constants = specialization_constants;
String error_text;
@@ -5651,7 +5710,7 @@ Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) {
/**** RENDER PIPELINE ****/
/*************************/
-RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags, uint32_t p_for_render_pass) {
+RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags, uint32_t p_for_render_pass, const Vector<PipelineSpecializationConstant> &p_specialization_constants) {
_THREAD_SAFE_METHOD_
//needs a shader
@@ -5969,8 +6028,63 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma
graphics_pipeline_create_info.pNext = nullptr;
graphics_pipeline_create_info.flags = 0;
- graphics_pipeline_create_info.stageCount = shader->pipeline_stages.size();
- graphics_pipeline_create_info.pStages = shader->pipeline_stages.ptr();
+ Vector<VkPipelineShaderStageCreateInfo> pipeline_stages = shader->pipeline_stages;
+ Vector<VkSpecializationInfo> specialization_info;
+ Vector<Vector<VkSpecializationMapEntry>> specialization_map_entries;
+ Vector<uint32_t> specialization_constant_data;
+
+ if (shader->specialization_constants.size()) {
+ specialization_constant_data.resize(shader->specialization_constants.size());
+ uint32_t *data_ptr = specialization_constant_data.ptrw();
+ specialization_info.resize(pipeline_stages.size());
+ specialization_map_entries.resize(pipeline_stages.size());
+ for (int i = 0; i < shader->specialization_constants.size(); i++) {
+ //see if overriden
+ const Shader::SpecializationConstant &sc = shader->specialization_constants[i];
+ data_ptr[i] = sc.constant.int_value; //just copy the 32 bits
+
+ for (int j = 0; j < p_specialization_constants.size(); j++) {
+ const PipelineSpecializationConstant &psc = p_specialization_constants[j];
+ if (psc.constant_id == sc.constant.constant_id) {
+ ERR_FAIL_COND_V_MSG(psc.type != sc.constant.type, RID(), "Specialization constant provided for id (" + itos(sc.constant.constant_id) + ") is of the wrong type.");
+ data_ptr[i] = sc.constant.int_value;
+ break;
+ }
+ }
+
+ VkSpecializationMapEntry entry;
+
+ entry.constantID = sc.constant.constant_id;
+ entry.offset = i * sizeof(uint32_t);
+ entry.size = sizeof(uint32_t);
+
+ for (int j = 0; j < SHADER_STAGE_MAX; j++) {
+ if (sc.stage_flags & (1 << j)) {
+ VkShaderStageFlagBits stage = shader_stage_masks[j];
+ for (int k = 0; k < pipeline_stages.size(); k++) {
+ if (pipeline_stages[k].stage == stage) {
+ specialization_map_entries.write[k].push_back(entry);
+ }
+ }
+ }
+ }
+ }
+
+ for (int k = 0; k < pipeline_stages.size(); k++) {
+ if (specialization_map_entries[k].size()) {
+ specialization_info.write[k].dataSize = specialization_constant_data.size() * sizeof(uint32_t);
+ specialization_info.write[k].pData = data_ptr;
+ specialization_info.write[k].mapEntryCount = specialization_map_entries[k].size();
+ specialization_info.write[k].pMapEntries = specialization_map_entries[k].ptr();
+
+ pipeline_stages.write[k].pSpecializationInfo = specialization_info.ptr();
+ }
+ }
+ }
+
+ graphics_pipeline_create_info.stageCount = pipeline_stages.size();
+ graphics_pipeline_create_info.pStages = pipeline_stages.ptr();
+
graphics_pipeline_create_info.pVertexInputState = &pipeline_vertex_input_state_create_info;
graphics_pipeline_create_info.pInputAssemblyState = &input_assembly_create_info;
graphics_pipeline_create_info.pTessellationState = &tessellation_create_info;
@@ -6039,7 +6153,7 @@ bool RenderingDeviceVulkan::render_pipeline_is_valid(RID p_pipeline) {
/**** COMPUTE PIPELINE ****/
/**************************/
-RID RenderingDeviceVulkan::compute_pipeline_create(RID p_shader) {
+RID RenderingDeviceVulkan::compute_pipeline_create(RID p_shader, const Vector<PipelineSpecializationConstant> &p_specialization_constants) {
_THREAD_SAFE_METHOD_
//needs a shader
@@ -6061,6 +6175,44 @@ RID RenderingDeviceVulkan::compute_pipeline_create(RID p_shader) {
compute_pipeline_create_info.basePipelineHandle = VK_NULL_HANDLE;
compute_pipeline_create_info.basePipelineIndex = 0;
+ VkSpecializationInfo specialization_info;
+ Vector<VkSpecializationMapEntry> specialization_map_entries;
+ Vector<uint32_t> specialization_constant_data;
+
+ if (shader->specialization_constants.size()) {
+ specialization_constant_data.resize(shader->specialization_constants.size());
+ uint32_t *data_ptr = specialization_constant_data.ptrw();
+ for (int i = 0; i < shader->specialization_constants.size(); i++) {
+ //see if overriden
+ const Shader::SpecializationConstant &sc = shader->specialization_constants[i];
+ data_ptr[i] = sc.constant.int_value; //just copy the 32 bits
+
+ for (int j = 0; j < p_specialization_constants.size(); j++) {
+ const PipelineSpecializationConstant &psc = p_specialization_constants[j];
+ if (psc.constant_id == sc.constant.constant_id) {
+ ERR_FAIL_COND_V_MSG(psc.type != sc.constant.type, RID(), "Specialization constant provided for id (" + itos(sc.constant.constant_id) + ") is of the wrong type.");
+ data_ptr[i] = sc.constant.int_value;
+ break;
+ }
+ }
+
+ VkSpecializationMapEntry entry;
+
+ entry.constantID = sc.constant.constant_id;
+ entry.offset = i * sizeof(uint32_t);
+ entry.size = sizeof(uint32_t);
+
+ specialization_map_entries.push_back(entry);
+ }
+
+ specialization_info.dataSize = specialization_constant_data.size() * sizeof(uint32_t);
+ specialization_info.pData = data_ptr;
+ specialization_info.mapEntryCount = specialization_map_entries.size();
+ specialization_info.pMapEntries = specialization_map_entries.ptr();
+
+ compute_pipeline_create_info.stage.pSpecializationInfo = &specialization_info;
+ }
+
ComputePipeline pipeline;
VkResult err = vkCreateComputePipelines(device, VK_NULL_HANDLE, 1, &compute_pipeline_create_info, nullptr, &pipeline.pipeline);
ERR_FAIL_COND_V_MSG(err, RID(), "vkCreateComputePipelines failed with error " + itos(err) + ".");
diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h
index ff9ad71268..8b95ff43b8 100644
--- a/drivers/vulkan/rendering_device_vulkan.h
+++ b/drivers/vulkan/rendering_device_vulkan.h
@@ -623,11 +623,17 @@ class RenderingDeviceVulkan : public RenderingDevice {
uint32_t compute_local_size[3] = { 0, 0, 0 };
+ struct SpecializationConstant {
+ PipelineSpecializationConstant constant;
+ uint32_t stage_flags = 0;
+ };
+
bool is_compute = false;
int max_output = 0;
Vector<Set> sets;
Vector<uint32_t> set_formats;
Vector<VkPipelineShaderStageCreateInfo> pipeline_stages;
+ Vector<SpecializationConstant> specialization_constants;
VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
};
@@ -1100,14 +1106,14 @@ public:
/**** RENDER PIPELINE ****/
/*************************/
- virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0, uint32_t p_for_render_pass = 0);
+ virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0, uint32_t p_for_render_pass = 0, const Vector<PipelineSpecializationConstant> &p_specialization_constants = Vector<PipelineSpecializationConstant>());
virtual bool render_pipeline_is_valid(RID p_pipeline);
/**************************/
/**** COMPUTE PIPELINE ****/
/**************************/
- virtual RID compute_pipeline_create(RID p_shader);
+ virtual RID compute_pipeline_create(RID p_shader, const Vector<PipelineSpecializationConstant> &p_specialization_constants = Vector<PipelineSpecializationConstant>());
virtual bool compute_pipeline_is_valid(RID p_pipeline);
/****************/
diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp
index 74bd938822..d35c519320 100644
--- a/drivers/vulkan/vulkan_context.cpp
+++ b/drivers/vulkan/vulkan_context.cpp
@@ -1189,7 +1189,7 @@ bool VulkanContext::_use_validation_layers() {
return Engine::get_singleton()->is_validation_layers_enabled();
}
-Error VulkanContext::_window_create(DisplayServer::WindowID p_window_id, VkSurfaceKHR p_surface, int p_width, int p_height) {
+Error VulkanContext::_window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, VkSurfaceKHR p_surface, int p_width, int p_height) {
ERR_FAIL_COND_V(windows.has(p_window_id), ERR_INVALID_PARAMETER);
if (!queues_initialized) {
@@ -1217,6 +1217,7 @@ Error VulkanContext::_window_create(DisplayServer::WindowID p_window_id, VkSurfa
window.surface = p_surface;
window.width = p_width;
window.height = p_height;
+ window.vsync_mode = p_vsync_mode;
Error err = _update_swap_chain(&window);
ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE);
@@ -1360,7 +1361,6 @@ Error VulkanContext::_update_swap_chain(Window *window) {
}
// The FIFO present mode is guaranteed by the spec to be supported
// and to have no tearing. It's a great default present mode to use.
- VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
// There are times when you may wish to use another present mode. The
// following code shows how to select them, and the comments provide some
@@ -1389,16 +1389,41 @@ Error VulkanContext::_update_swap_chain(Window *window) {
// the application wants the late image to be immediately displayed, even
// though that may mean some tearing.
- if (window->presentMode != swapchainPresentMode) {
- for (size_t i = 0; i < presentModeCount; ++i) {
- if (presentModes[i] == window->presentMode) {
- swapchainPresentMode = window->presentMode;
- break;
- }
+ VkPresentModeKHR requested_present_mode = VkPresentModeKHR::VK_PRESENT_MODE_FIFO_KHR;
+ switch (window->vsync_mode) {
+ case DisplayServer::VSYNC_MAILBOX:
+ requested_present_mode = VkPresentModeKHR::VK_PRESENT_MODE_MAILBOX_KHR;
+ break;
+ case DisplayServer::VSYNC_ADAPTIVE:
+ requested_present_mode = VkPresentModeKHR::VK_PRESENT_MODE_FIFO_RELAXED_KHR;
+ break;
+ case DisplayServer::VSYNC_ENABLED:
+ requested_present_mode = VkPresentModeKHR::VK_PRESENT_MODE_FIFO_KHR;
+ break;
+ case DisplayServer::VSYNC_DISABLED:
+ requested_present_mode = VkPresentModeKHR::VK_PRESENT_MODE_IMMEDIATE_KHR;
+ break;
+ }
+
+ // Check if the requested mode is available.
+ bool present_mode_available = false;
+ for (uint32_t i = 0; i < presentModeCount; i++) {
+ if (presentModes[i] == requested_present_mode) {
+ present_mode_available = true;
}
}
+
+ // Set the windows present mode if it is available, otherwise FIFO is used (guaranteed supported).
+ if (present_mode_available) {
+ window->presentMode = requested_present_mode;
+ } else {
+ WARN_PRINT("Requested VSync mode is not available!");
+ window->vsync_mode = DisplayServer::VSYNC_ENABLED; //Set to default
+ }
+
+ print_verbose("Using present mode: " + String(string_VkPresentModeKHR(window->presentMode)));
+
free(presentModes);
- ERR_FAIL_COND_V_MSG(swapchainPresentMode != window->presentMode, ERR_CANT_CREATE, "Present mode specified is not supported\n");
// Determine the number of VkImages to use in the swap chain.
// Application desires to acquire 3 images at a time for triple
@@ -1455,7 +1480,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
/*pQueueFamilyIndices*/ nullptr,
/*preTransform*/ (VkSurfaceTransformFlagBitsKHR)preTransform,
/*compositeAlpha*/ compositeAlpha,
- /*presentMode*/ swapchainPresentMode,
+ /*presentMode*/ window->presentMode,
/*clipped*/ true,
/*oldSwapchain*/ VK_NULL_HANDLE,
};
@@ -2162,6 +2187,17 @@ String VulkanContext::get_device_pipeline_cache_uuid() const {
return pipeline_cache_id;
}
+DisplayServer::VSyncMode VulkanContext::get_vsync_mode(DisplayServer::WindowID p_window) const {
+ ERR_FAIL_COND_V_MSG(!windows.has(p_window), DisplayServer::VSYNC_ENABLED, "Could not get VSync mode for window with WindowID " + itos(p_window) + " because it does not exist.");
+ return windows[p_window].vsync_mode;
+}
+
+void VulkanContext::set_vsync_mode(DisplayServer::WindowID p_window, DisplayServer::VSyncMode p_mode) {
+ ERR_FAIL_COND_MSG(!windows.has(p_window), "Could not set VSync mode for window with WindowID " + itos(p_window) + " because it does not exist.");
+ windows[p_window].vsync_mode = p_mode;
+ _update_swap_chain(&windows[p_window]);
+}
+
VulkanContext::VulkanContext() {
command_buffer_queue.resize(1); // First one is always the setup command.
command_buffer_queue.write[0] = nullptr;
diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h
index 8f1005d07f..83e9524046 100644
--- a/drivers/vulkan/vulkan_context.h
+++ b/drivers/vulkan/vulkan_context.h
@@ -124,6 +124,7 @@ private:
uint32_t current_buffer = 0;
int width = 0;
int height = 0;
+ DisplayServer::VSyncMode vsync_mode = DisplayServer::VSYNC_ENABLED;
VkCommandPool present_cmd_pool = VK_NULL_HANDLE; // For separate present queue.
VkRenderPass render_pass = VK_NULL_HANDLE;
};
@@ -222,7 +223,7 @@ private:
protected:
virtual const char *_get_platform_surface_extension() const = 0;
- virtual Error _window_create(DisplayServer::WindowID p_window_id, VkSurfaceKHR p_surface, int p_width, int p_height);
+ virtual Error _window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, VkSurfaceKHR p_surface, int p_width, int p_height);
virtual bool _use_validation_layers();
@@ -276,6 +277,9 @@ public:
String get_device_name() const;
String get_device_pipeline_cache_uuid() const;
+ void set_vsync_mode(DisplayServer::WindowID p_window, DisplayServer::VSyncMode p_mode);
+ DisplayServer::VSyncMode get_vsync_mode(DisplayServer::WindowID p_window = 0) const;
+
VulkanContext();
virtual ~VulkanContext();
};
diff --git a/editor/action_map_editor.cpp b/editor/action_map_editor.cpp
index 7ed603410d..1c3ba89cd3 100644
--- a/editor/action_map_editor.cpp
+++ b/editor/action_map_editor.cpp
@@ -631,6 +631,7 @@ InputEventConfigurationDialog::InputEventConfigurationDialog() {
additional_options_container->hide();
Label *opts_label = memnew(Label);
+ opts_label->set_theme_type_variation("HeaderSmall");
opts_label->set_text("Additional Options");
additional_options_container->add_child(opts_label);
@@ -639,6 +640,7 @@ InputEventConfigurationDialog::InputEventConfigurationDialog() {
device_container->set_h_size_flags(Control::SIZE_EXPAND_FILL);
Label *device_label = memnew(Label);
+ device_label->set_theme_type_variation("HeaderSmall");
device_label->set_text("Device:");
device_container->add_child(device_label);
@@ -858,6 +860,7 @@ Variant ActionMapEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from
String name = selected->get_text(0);
Label *label = memnew(Label(name));
+ label->set_theme_type_variation("HeaderSmall");
label->set_modulate(Color(1, 1, 1, 1.0f));
action_tree->set_drag_preview(label);
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index f61fb6bab3..05945a8ae2 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -4450,7 +4450,7 @@ void AnimationTrackEditor::_new_track_node_selected(NodePath p_path) {
}
if (node == AnimationPlayerEditor::singleton->get_player()) {
- EditorNode::get_singleton()->show_warning(TTR("An animation player can't animate itself, only other players."));
+ EditorNode::get_singleton()->show_warning(TTR("AnimationPlayer can't animate itself, only other players."));
return;
}
@@ -5334,7 +5334,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
} break;
case EDIT_PASTE_TRACKS: {
if (track_clipboard.size() == 0) {
- EditorNode::get_singleton()->show_warning(TTR("Clipboard is empty"));
+ EditorNode::get_singleton()->show_warning(TTR("Clipboard is empty!"));
break;
}
@@ -5784,7 +5784,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
info_message->set_text(TTR("Select an AnimationPlayer node to create and edit animations."));
info_message->set_valign(Label::VALIGN_CENTER);
info_message->set_align(Label::ALIGN_CENTER);
- info_message->set_autowrap(true);
+ info_message->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART);
info_message->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
info_message->set_anchors_and_offsets_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
main_panel->add_child(info_message);
diff --git a/editor/audio_stream_preview.h b/editor/audio_stream_preview.h
index 61567598ed..9cf47fd51a 100644
--- a/editor/audio_stream_preview.h
+++ b/editor/audio_stream_preview.h
@@ -75,6 +75,15 @@ class AudioStreamPreviewGenerator : public Node {
thread = p_rhs.thread;
return *this;
}
+ Preview(const Preview &p_rhs) {
+ preview = p_rhs.preview;
+ base_stream = p_rhs.base_stream;
+ playback = p_rhs.playback;
+ generating.set_to(generating.is_set());
+ id = p_rhs.id;
+ thread = p_rhs.thread;
+ }
+ Preview() {}
};
Map<ObjectID, Preview> previews;
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp
index de6407da73..c79a8d9a0e 100644
--- a/editor/connections_dialog.cpp
+++ b/editor/connections_dialog.cpp
@@ -1121,7 +1121,7 @@ ConnectionsDock::ConnectionsDock(EditorNode *p_editor) {
add_child(slot_menu);
slot_menu->connect("id_pressed", callable_mp(this, &ConnectionsDock::_handle_slot_menu_option));
slot_menu->add_item(TTR("Edit..."), EDIT);
- slot_menu->add_item(TTR("Go To Method"), GO_TO_SCRIPT);
+ slot_menu->add_item(TTR("Go to Method"), GO_TO_SCRIPT);
slot_menu->add_item(TTR("Disconnect"), DISCONNECT);
connect_dialog->connect("connected", callable_mp(this, &ConnectionsDock::_make_or_edit_connection));
diff --git a/editor/debugger/editor_performance_profiler.cpp b/editor/debugger/editor_performance_profiler.cpp
index fc0104c07a..08609080c5 100644
--- a/editor/debugger/editor_performance_profiler.cpp
+++ b/editor/debugger/editor_performance_profiler.cpp
@@ -380,7 +380,7 @@ EditorPerformanceProfiler::EditorPerformanceProfiler() {
info_message->set_text(TTR("Pick one or more items from the list to display the graph."));
info_message->set_valign(Label::VALIGN_CENTER);
info_message->set_align(Label::ALIGN_CENTER);
- info_message->set_autowrap(true);
+ info_message->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART);
info_message->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
info_message->set_anchors_and_offsets_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
monitor_draw->add_child(info_message);
diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp
index b877ab030f..09bbf846fe 100644
--- a/editor/debugger/script_editor_debugger.cpp
+++ b/editor/debugger/script_editor_debugger.cpp
@@ -1535,7 +1535,7 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
reason->set_text("");
hbc->add_child(reason);
reason->set_h_size_flags(SIZE_EXPAND_FILL);
- reason->set_autowrap(true);
+ reason->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART);
reason->set_max_lines_visible(3);
reason->set_mouse_filter(Control::MOUSE_FILTER_PASS);
@@ -1700,6 +1700,8 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
VBoxContainer *vmem_vb = memnew(VBoxContainer);
HBoxContainer *vmem_hb = memnew(HBoxContainer);
Label *vmlb = memnew(Label(TTR("List of Video Memory Usage by Resource:") + " "));
+ vmlb->set_theme_type_variation("HeaderSmall");
+
vmlb->set_h_size_flags(SIZE_EXPAND_FILL);
vmem_hb->add_child(vmlb);
vmem_hb->add_child(memnew(Label(TTR("Total:") + " ")));
diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp
index ef571e5c7a..e26344f3ec 100644
--- a/editor/dependency_editor.cpp
+++ b/editor/dependency_editor.cpp
@@ -236,6 +236,8 @@ DependencyEditor::DependencyEditor() {
HBoxContainer *hbc = memnew(HBoxContainer);
Label *label = memnew(Label(TTR("Dependencies:")));
+ label->set_theme_type_variation("HeaderSmall");
+
hbc->add_child(label);
hbc->add_spacer();
fixdeps = memnew(Button(TTR("Fix Broken")));
diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp
index b8504ad02a..1f1446a8a8 100644
--- a/editor/editor_about.cpp
+++ b/editor/editor_about.cpp
@@ -92,6 +92,7 @@ ScrollContainer *EditorAbout::_populate_list(const String &p_name, const List<St
const char *const *names_ptr = p_src[i];
if (*names_ptr) {
Label *lbl = memnew(Label);
+ lbl->set_theme_type_variation("HeaderSmall");
lbl->set_text(p_sections[i]);
vbc->add_child(lbl);
@@ -212,7 +213,7 @@ EditorAbout::EditorAbout() {
Label *tpl_label = memnew(Label);
tpl_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- tpl_label->set_autowrap(true);
+ tpl_label->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART);
tpl_label->set_text(TTR("Godot Engine relies on a number of third-party free and open source libraries, all compatible with the terms of its MIT license. The following is an exhaustive list of all such third-party components with their respective copyright statements and license terms."));
tpl_label->set_size(Size2(630, 1) * EDSCALE);
license_thirdparty->add_child(tpl_label);
diff --git a/editor/editor_asset_installer.cpp b/editor/editor_asset_installer.cpp
index 83319ee5a5..dc90f26d48 100644
--- a/editor/editor_asset_installer.cpp
+++ b/editor/editor_asset_installer.cpp
@@ -112,7 +112,7 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) {
unzFile pkg = unzOpen2(p_path.utf8().get_data(), &io);
if (!pkg) {
- error->set_text(TTR("Error opening package file, not in ZIP format."));
+ error->set_text(vformat(TTR("Error opening asset file for \"%s\" (not in ZIP format)."), asset_name));
return;
}
@@ -196,6 +196,8 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) {
root->set_editable(0, true);
Map<String, TreeItem *> dir_map;
+ int num_file_conflicts = 0;
+
for (Set<String>::Element *E = files_sorted.front(); E; E = E->next()) {
String path = E->get();
int depth = p_depth;
@@ -254,8 +256,9 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) {
String res_path = "res://" + path;
if (FileAccess::exists(res_path)) {
+ num_file_conflicts += 1;
ti->set_custom_color(0, tree->get_theme_color("error_color", "Editor"));
- ti->set_tooltip(0, vformat(TTR("%s (Already Exists)"), res_path));
+ ti->set_tooltip(0, vformat(TTR("%s (already exists)"), res_path));
ti->set_checked(0, false);
} else {
ti->set_tooltip(0, res_path);
@@ -266,6 +269,13 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) {
status_map[E->get()] = ti;
}
+
+ if (num_file_conflicts >= 1) {
+ asset_contents->set_text(vformat(TTR("Contents of asset \"%s\" - %d file(s) conflict with your project:"), asset_name, num_file_conflicts));
+ } else {
+ asset_contents->set_text(vformat(TTR("Contents of asset \"%s\" - No files conflict with your project:"), asset_name));
+ }
+
popup_centered_ratio();
updating = false;
}
@@ -276,7 +286,7 @@ void EditorAssetInstaller::ok_pressed() {
unzFile pkg = unzOpen2(package_path.utf8().get_data(), &io);
if (!pkg) {
- error->set_text(TTR("Error opening package file, not in ZIP format."));
+ error->set_text(vformat(TTR("Error opening asset file for \"%s\" (not in ZIP format)."), asset_name));
return;
}
@@ -343,10 +353,10 @@ void EditorAssetInstaller::ok_pressed() {
unzClose(pkg);
if (failed_files.size()) {
- String msg = TTR("The following files failed extraction from package:") + "\n\n";
+ String msg = vformat(TTR("The following files failed extraction from asset \"%s\":"), asset_name) + "\n\n";
for (int i = 0; i < failed_files.size(); i++) {
if (i > 15) {
- msg += "\n" + vformat(TTR("And %s more files."), itos(failed_files.size() - i));
+ msg += "\n" + vformat(TTR("(and %s more files)"), itos(failed_files.size() - i));
break;
}
msg += failed_files[i];
@@ -356,12 +366,20 @@ void EditorAssetInstaller::ok_pressed() {
}
} else {
if (EditorNode::get_singleton() != nullptr) {
- EditorNode::get_singleton()->show_warning(TTR("Package installed successfully!"), TTR("Success!"));
+ EditorNode::get_singleton()->show_warning(vformat(TTR("Asset \"%s\" installed successfully!"), asset_name), TTR("Success!"));
}
}
EditorFileSystem::get_singleton()->scan_changes();
}
+void EditorAssetInstaller::set_asset_name(const String &p_asset_name) {
+ asset_name = p_asset_name;
+}
+
+String EditorAssetInstaller::get_asset_name() const {
+ return asset_name;
+}
+
void EditorAssetInstaller::_bind_methods() {
}
@@ -369,14 +387,18 @@ EditorAssetInstaller::EditorAssetInstaller() {
VBoxContainer *vb = memnew(VBoxContainer);
add_child(vb);
+ asset_contents = memnew(Label);
+ vb->add_child(asset_contents);
+
tree = memnew(Tree);
- vb->add_margin_child(TTR("Package Contents:"), tree, true);
+ tree->set_v_size_flags(Control::SIZE_EXPAND_FILL);
tree->connect("item_edited", callable_mp(this, &EditorAssetInstaller::_item_edited));
+ vb->add_child(tree);
error = memnew(AcceptDialog);
add_child(error);
get_ok_button()->set_text(TTR("Install"));
- set_title(TTR("Package Installer"));
+ set_title(TTR("Asset Installer"));
updating = false;
diff --git a/editor/editor_asset_installer.h b/editor/editor_asset_installer.h
index d9233a5ce8..9fafe2792a 100644
--- a/editor/editor_asset_installer.h
+++ b/editor/editor_asset_installer.h
@@ -37,7 +37,9 @@ class EditorAssetInstaller : public ConfirmationDialog {
GDCLASS(EditorAssetInstaller, ConfirmationDialog);
Tree *tree;
+ Label *asset_contents;
String package_path;
+ String asset_name;
AcceptDialog *error;
Map<String, TreeItem *> status_map;
bool updating;
@@ -51,6 +53,10 @@ protected:
public:
void open(const String &p_path, int p_depth = 0);
+
+ void set_asset_name(const String &p_asset_name);
+ String get_asset_name() const;
+
EditorAssetInstaller();
};
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index fe4c6f490d..a07b3a7c19 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -1510,7 +1510,9 @@ EditorFileDialog::EditorFileDialog() {
dir_next->connect("pressed", callable_mp(this, &EditorFileDialog::_go_forward));
dir_up->connect("pressed", callable_mp(this, &EditorFileDialog::_go_up));
- pathhb->add_child(memnew(Label(TTR("Path:"))));
+ Label *l = memnew(Label(TTR("Path:")));
+ l->set_theme_type_variation("HeaderSmall");
+ pathhb->add_child(l);
drives_container = memnew(HBoxContainer);
pathhb->add_child(drives_container);
@@ -1591,7 +1593,11 @@ EditorFileDialog::EditorFileDialog() {
fav_vb->set_v_size_flags(Control::SIZE_EXPAND_FILL);
HBoxContainer *fav_hb = memnew(HBoxContainer);
fav_vb->add_child(fav_hb);
- fav_hb->add_child(memnew(Label(TTR("Favorites:"))));
+
+ l = memnew(Label(TTR("Favorites:")));
+ l->set_theme_type_variation("HeaderSmall");
+ fav_hb->add_child(l);
+
fav_hb->add_spacer();
fav_up = memnew(Button);
fav_up->set_flat(true);
@@ -1626,7 +1632,10 @@ EditorFileDialog::EditorFileDialog() {
VBoxContainer *list_vb = memnew(VBoxContainer);
list_vb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- list_vb->add_child(memnew(Label(TTR("Directories & Files:"))));
+
+ l = memnew(Label(TTR("Directories & Files:")));
+ l->set_theme_type_variation("HeaderSmall");
+ list_vb->add_child(l);
preview_hb->add_child(list_vb);
// Item (files and folders) list with context menu.
@@ -1653,7 +1662,11 @@ EditorFileDialog::EditorFileDialog() {
preview_vb->hide();
file_box = memnew(HBoxContainer);
- file_box->add_child(memnew(Label(TTR("File:"))));
+
+ l = memnew(Label(TTR("File:")));
+ l->set_theme_type_variation("HeaderSmall");
+ file_box->add_child(l);
+
file = memnew(LineEdit);
file->set_structured_text_bidi_override(Control::STRUCTURED_TEXT_FILE);
file->set_stretch_ratio(4);
diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp
index d548196a2d..8968e562c1 100644
--- a/editor/editor_fonts.cpp
+++ b/editor/editor_fonts.cpp
@@ -319,7 +319,19 @@ void editor_register_fonts(Ref<Theme> p_theme) {
p_theme->set_font_size("main_button_font_size", "EditorFonts", default_font_size + 1 * EDSCALE);
p_theme->set_font("main_button_font", "EditorFonts", df_bold);
- p_theme->set_font("font", "Label", df_bold);
+ p_theme->set_font("font", "Label", df);
+
+ p_theme->set_type_variation("HeaderSmall", "Label");
+ p_theme->set_font("font", "HeaderSmall", df_bold);
+ p_theme->set_font_size("font_size", "HeaderSmall", default_font_size);
+
+ p_theme->set_type_variation("HeaderMedium", "Label");
+ p_theme->set_font("font", "HeaderMedium", df_bold);
+ p_theme->set_font_size("font_size", "HeaderMedium", default_font_size + 1 * EDSCALE);
+
+ p_theme->set_type_variation("HeaderLarge", "Label");
+ p_theme->set_font("font", "HeaderLarge", df_bold);
+ p_theme->set_font_size("font_size", "HeaderLarge", default_font_size + 3 * EDSCALE);
// Documentation fonts
MAKE_SOURCE_FONT(df_code);
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index e7c0b02ae2..4d52414748 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -2713,7 +2713,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
}
save_confirmation->get_ok_button()->set_text(TTR("Save & Quit"));
- save_confirmation->set_text((p_option == FILE_QUIT ? TTR("Save changes to the following scene(s) before quitting?") : TTR("Save changes the following scene(s) before opening Project Manager?")) + unsaved_scenes);
+ save_confirmation->set_text((p_option == FILE_QUIT ? TTR("Save changes to the following scene(s) before quitting?") : TTR("Save changes to the following scene(s) before opening Project Manager?")) + unsaved_scenes);
save_confirmation->popup_centered();
}
}
@@ -3736,46 +3736,46 @@ void EditorNode::register_editor_types() {
ResourceLoader::set_timestamp_on_load(true);
ResourceSaver::set_timestamp_on_save(true);
- ClassDB::register_class<EditorPaths>();
- ClassDB::register_class<EditorPlugin>();
- ClassDB::register_class<EditorTranslationParserPlugin>();
- ClassDB::register_class<EditorImportPlugin>();
- ClassDB::register_class<EditorScript>();
- ClassDB::register_class<EditorSelection>();
- ClassDB::register_class<EditorFileDialog>();
- ClassDB::register_virtual_class<EditorSettings>();
- ClassDB::register_class<EditorNode3DGizmo>();
- ClassDB::register_class<EditorNode3DGizmoPlugin>();
- ClassDB::register_virtual_class<EditorResourcePreview>();
- ClassDB::register_class<EditorResourcePreviewGenerator>();
- ClassDB::register_virtual_class<EditorFileSystem>();
- ClassDB::register_class<EditorFileSystemDirectory>();
- ClassDB::register_class<EditorVCSInterface>();
- ClassDB::register_virtual_class<ScriptEditor>();
- ClassDB::register_virtual_class<ScriptEditorBase>();
- ClassDB::register_class<EditorSyntaxHighlighter>();
- ClassDB::register_virtual_class<EditorInterface>();
- ClassDB::register_class<EditorExportPlugin>();
- ClassDB::register_class<EditorResourceConversionPlugin>();
- ClassDB::register_class<EditorSceneImporter>();
- ClassDB::register_class<EditorInspector>();
- ClassDB::register_class<EditorInspectorPlugin>();
- ClassDB::register_class<EditorProperty>();
- ClassDB::register_class<AnimationTrackEditPlugin>();
- ClassDB::register_class<ScriptCreateDialog>();
- ClassDB::register_class<EditorFeatureProfile>();
- ClassDB::register_class<EditorSpinSlider>();
- ClassDB::register_class<EditorResourcePicker>();
- ClassDB::register_class<EditorScriptPicker>();
- ClassDB::register_class<EditorSceneImporterMesh>();
- ClassDB::register_class<EditorSceneImporterMeshNode3D>();
-
- ClassDB::register_virtual_class<FileSystemDock>();
+ GDREGISTER_CLASS(EditorPaths);
+ GDREGISTER_CLASS(EditorPlugin);
+ GDREGISTER_CLASS(EditorTranslationParserPlugin);
+ GDREGISTER_CLASS(EditorImportPlugin);
+ GDREGISTER_CLASS(EditorScript);
+ GDREGISTER_CLASS(EditorSelection);
+ GDREGISTER_CLASS(EditorFileDialog);
+ GDREGISTER_VIRTUAL_CLASS(EditorSettings);
+ GDREGISTER_CLASS(EditorNode3DGizmo);
+ GDREGISTER_CLASS(EditorNode3DGizmoPlugin);
+ GDREGISTER_VIRTUAL_CLASS(EditorResourcePreview);
+ GDREGISTER_CLASS(EditorResourcePreviewGenerator);
+ GDREGISTER_VIRTUAL_CLASS(EditorFileSystem);
+ GDREGISTER_CLASS(EditorFileSystemDirectory);
+ GDREGISTER_CLASS(EditorVCSInterface);
+ GDREGISTER_VIRTUAL_CLASS(ScriptEditor);
+ GDREGISTER_VIRTUAL_CLASS(ScriptEditorBase);
+ GDREGISTER_CLASS(EditorSyntaxHighlighter);
+ GDREGISTER_VIRTUAL_CLASS(EditorInterface);
+ GDREGISTER_CLASS(EditorExportPlugin);
+ GDREGISTER_CLASS(EditorResourceConversionPlugin);
+ GDREGISTER_CLASS(EditorSceneImporter);
+ GDREGISTER_CLASS(EditorInspector);
+ GDREGISTER_CLASS(EditorInspectorPlugin);
+ GDREGISTER_CLASS(EditorProperty);
+ GDREGISTER_CLASS(AnimationTrackEditPlugin);
+ GDREGISTER_CLASS(ScriptCreateDialog);
+ GDREGISTER_CLASS(EditorFeatureProfile);
+ GDREGISTER_CLASS(EditorSpinSlider);
+ GDREGISTER_CLASS(EditorResourcePicker);
+ GDREGISTER_CLASS(EditorScriptPicker);
+ GDREGISTER_CLASS(EditorSceneImporterMesh);
+ GDREGISTER_CLASS(EditorSceneImporterMeshNode3D);
+
+ GDREGISTER_VIRTUAL_CLASS(FileSystemDock);
// FIXME: Is this stuff obsolete, or should it be ported to new APIs?
- ClassDB::register_class<EditorScenePostImport>();
+ GDREGISTER_CLASS(EditorScenePostImport);
//ClassDB::register_type<EditorImportExport>();
- ClassDB::register_class<EditorDebuggerPlugin>();
+ GDREGISTER_CLASS(EditorDebuggerPlugin);
NativeExtensionManager::get_singleton()->initialize_extensions(NativeExtension::INITIALIZATION_LEVEL_EDITOR);
}
diff --git a/editor/editor_plugin_settings.cpp b/editor/editor_plugin_settings.cpp
index b4e5a58c21..a16a2f327e 100644
--- a/editor/editor_plugin_settings.cpp
+++ b/editor/editor_plugin_settings.cpp
@@ -192,7 +192,9 @@ EditorPluginSettings::EditorPluginSettings() {
add_child(plugin_config_dialog);
HBoxContainer *title_hb = memnew(HBoxContainer);
- title_hb->add_child(memnew(Label(TTR("Installed Plugins:"))));
+ Label *l = memnew(Label(TTR("Installed Plugins:")));
+ l->set_theme_type_variation("HeaderSmall");
+ title_hb->add_child(l);
title_hb->add_spacer();
create_plugin = memnew(Button(TTR("Create")));
create_plugin->connect("pressed", callable_mp(this, &EditorPluginSettings::_create_clicked));
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index 84105f0cb7..ebd8d6427b 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -180,44 +180,150 @@ EditorPropertyMultilineText::EditorPropertyMultilineText() {
///////////////////// TEXT ENUM /////////////////////////
-void EditorPropertyTextEnum::_option_selected(int p_which) {
+void EditorPropertyTextEnum::_emit_changed_value(String p_string) {
if (string_name) {
- emit_changed(get_edited_property(), StringName(options->get_item_text(p_which)));
+ emit_changed(get_edited_property(), StringName(p_string));
} else {
- emit_changed(get_edited_property(), options->get_item_text(p_which));
+ emit_changed(get_edited_property(), p_string);
}
}
+void EditorPropertyTextEnum::_option_selected(int p_which) {
+ _emit_changed_value(option_button->get_item_text(p_which));
+}
+
+void EditorPropertyTextEnum::_edit_custom_value() {
+ default_layout->hide();
+ edit_custom_layout->show();
+ custom_value_edit->grab_focus();
+}
+
+void EditorPropertyTextEnum::_custom_value_submitted(String p_value) {
+ edit_custom_layout->hide();
+ default_layout->show();
+
+ _emit_changed_value(p_value.strip_edges());
+}
+
+void EditorPropertyTextEnum::_custom_value_accepted() {
+ String new_value = custom_value_edit->get_text().strip_edges();
+ _custom_value_submitted(new_value);
+}
+
+void EditorPropertyTextEnum::_custom_value_cancelled() {
+ custom_value_edit->set_text(get_edited_object()->get(get_edited_property()));
+
+ edit_custom_layout->hide();
+ default_layout->show();
+}
+
void EditorPropertyTextEnum::update_property() {
- String which = get_edited_object()->get(get_edited_property());
- for (int i = 0; i < options->get_item_count(); i++) {
- String t = options->get_item_text(i);
- if (t == which) {
- options->select(i);
- return;
+ String current_value = get_edited_object()->get(get_edited_property());
+ int default_option = options.find(current_value);
+
+ // The list can change in the loose mode.
+ if (loose_mode) {
+ custom_value_edit->set_text(current_value);
+ option_button->clear();
+
+ // Manually entered value.
+ if (default_option < 0 && !current_value.is_empty()) {
+ option_button->add_item(current_value, options.size() + 1001);
+ option_button->select(0);
+
+ option_button->add_separator();
}
+
+ // Add an explicit empty value for clearing the property.
+ option_button->add_item("", options.size() + 1000);
+
+ for (int i = 0; i < options.size(); i++) {
+ option_button->add_item(options[i], i);
+ if (options[i] == current_value) {
+ option_button->select(option_button->get_item_count() - 1);
+ }
+ }
+ } else {
+ option_button->select(default_option);
}
}
-void EditorPropertyTextEnum::setup(const Vector<String> &p_options, bool p_string_name) {
+void EditorPropertyTextEnum::setup(const Vector<String> &p_options, bool p_string_name, bool p_loose_mode) {
+ string_name = p_string_name;
+ loose_mode = p_loose_mode;
+
+ options.clear();
+
+ if (loose_mode) {
+ // Add an explicit empty value for clearing the property in the loose mode.
+ option_button->add_item("", options.size() + 1000);
+ }
+
for (int i = 0; i < p_options.size(); i++) {
- options->add_item(p_options[i], i);
+ options.append(p_options[i]);
+ option_button->add_item(p_options[i], i);
+ }
+
+ if (loose_mode) {
+ edit_button->show();
}
- string_name = p_string_name;
}
void EditorPropertyTextEnum::_bind_methods() {
}
-EditorPropertyTextEnum::EditorPropertyTextEnum() {
- options = memnew(OptionButton);
- options->set_clip_text(true);
- options->set_flat(true);
- string_name = false;
+void EditorPropertyTextEnum::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_THEME_CHANGED:
+ edit_button->set_icon(get_theme_icon("Edit", "EditorIcons"));
+ accept_button->set_icon(get_theme_icon("ImportCheck", "EditorIcons"));
+ cancel_button->set_icon(get_theme_icon("ImportFail", "EditorIcons"));
+ break;
+ }
+}
- add_child(options);
- add_focusable(options);
- options->connect("item_selected", callable_mp(this, &EditorPropertyTextEnum::_option_selected));
+EditorPropertyTextEnum::EditorPropertyTextEnum() {
+ default_layout = memnew(HBoxContainer);
+ add_child(default_layout);
+
+ edit_custom_layout = memnew(HBoxContainer);
+ edit_custom_layout->hide();
+ add_child(edit_custom_layout);
+
+ option_button = memnew(OptionButton);
+ option_button->set_h_size_flags(SIZE_EXPAND_FILL);
+ option_button->set_clip_text(true);
+ option_button->set_flat(true);
+ default_layout->add_child(option_button);
+ option_button->connect("item_selected", callable_mp(this, &EditorPropertyTextEnum::_option_selected));
+
+ edit_button = memnew(Button);
+ edit_button->set_flat(true);
+ edit_button->hide();
+ default_layout->add_child(edit_button);
+ edit_button->connect("pressed", callable_mp(this, &EditorPropertyTextEnum::_edit_custom_value));
+
+ custom_value_edit = memnew(LineEdit);
+ custom_value_edit->set_h_size_flags(SIZE_EXPAND_FILL);
+ edit_custom_layout->add_child(custom_value_edit);
+ custom_value_edit->connect("text_submitted", callable_mp(this, &EditorPropertyTextEnum::_custom_value_submitted));
+
+ accept_button = memnew(Button);
+ accept_button->set_flat(true);
+ edit_custom_layout->add_child(accept_button);
+ accept_button->connect("pressed", callable_mp(this, &EditorPropertyTextEnum::_custom_value_accepted));
+
+ cancel_button = memnew(Button);
+ cancel_button->set_flat(true);
+ edit_custom_layout->add_child(cancel_button);
+ cancel_button->connect("pressed", callable_mp(this, &EditorPropertyTextEnum::_custom_value_cancelled));
+
+ add_focusable(option_button);
+ add_focusable(edit_button);
+ add_focusable(custom_value_edit);
+ add_focusable(accept_button);
+ add_focusable(cancel_button);
}
///////////////////// PATH /////////////////////////
@@ -2902,10 +3008,10 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_
}
} break;
case Variant::STRING: {
- if (p_hint == PROPERTY_HINT_ENUM) {
+ if (p_hint == PROPERTY_HINT_ENUM || p_hint == PROPERTY_HINT_ENUM_SUGGESTION) {
EditorPropertyTextEnum *editor = memnew(EditorPropertyTextEnum);
- Vector<String> options = p_hint_text.split(",");
- editor->setup(options);
+ Vector<String> options = p_hint_text.split(",", false);
+ editor->setup(options, false, (p_hint == PROPERTY_HINT_ENUM_SUGGESTION));
return editor;
} else if (p_hint == PROPERTY_HINT_MULTILINE_TEXT) {
EditorPropertyMultilineText *editor = memnew(EditorPropertyMultilineText);
@@ -3063,10 +3169,10 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_
return editor;
} break;
case Variant::STRING_NAME: {
- if (p_hint == PROPERTY_HINT_ENUM) {
+ if (p_hint == PROPERTY_HINT_ENUM || p_hint == PROPERTY_HINT_ENUM_SUGGESTION) {
EditorPropertyTextEnum *editor = memnew(EditorPropertyTextEnum);
- Vector<String> options = p_hint_text.split(",");
- editor->setup(options, true);
+ Vector<String> options = p_hint_text.split(",", false);
+ editor->setup(options, true, (p_hint == PROPERTY_HINT_ENUM_SUGGESTION));
return editor;
} else {
EditorPropertyText *editor = memnew(EditorPropertyText);
diff --git a/editor/editor_properties.h b/editor/editor_properties.h
index d880017cc1..0cb21bb391 100644
--- a/editor/editor_properties.h
+++ b/editor/editor_properties.h
@@ -91,16 +91,35 @@ public:
class EditorPropertyTextEnum : public EditorProperty {
GDCLASS(EditorPropertyTextEnum, EditorProperty);
- OptionButton *options;
+ HBoxContainer *default_layout;
+ HBoxContainer *edit_custom_layout;
+
+ OptionButton *option_button;
+ Button *edit_button;
+
+ LineEdit *custom_value_edit;
+ Button *accept_button;
+ Button *cancel_button;
+
+ Vector<String> options;
+ bool string_name = false;
+ bool loose_mode = false;
+
+ void _emit_changed_value(String p_string);
void _option_selected(int p_which);
- bool string_name;
+
+ void _edit_custom_value();
+ void _custom_value_submitted(String p_value);
+ void _custom_value_accepted();
+ void _custom_value_cancelled();
protected:
static void _bind_methods();
+ void _notification(int p_what);
public:
- void setup(const Vector<String> &p_options, bool p_string_name = false);
+ void setup(const Vector<String> &p_options, bool p_string_name = false, bool p_loose_mode = false);
virtual void update_property() override;
EditorPropertyTextEnum();
};
diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp
index 350fc5eccb..4d9865622c 100644
--- a/editor/editor_resource_picker.cpp
+++ b/editor/editor_resource_picker.cpp
@@ -205,7 +205,7 @@ void EditorResourcePicker::_update_menu_items() {
icon = get_theme_icon(what, "Resource");
}
- edit_menu->add_icon_item(icon, vformat(TTR("Convert To %s"), what), CONVERT_BASE_ID + i);
+ edit_menu->add_icon_item(icon, vformat(TTR("Convert to %s"), what), CONVERT_BASE_ID + i);
}
}
}
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 080563f375..b6f889268f 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -884,7 +884,7 @@ void EditorSettings::create() {
return;
}
- ClassDB::register_class<EditorSettings>(); // Otherwise it can't be unserialized.
+ GDREGISTER_CLASS(EditorSettings); // Otherwise it can't be unserialized.
String config_file_path;
Ref<ConfigFile> extra_config = memnew(ConfigFile);
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 131a77e52f..986fc147f9 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -1004,6 +1004,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// LineEdit
Ref<StyleBoxFlat> style_line_edit = style_widget->duplicate();
+ // The original style_widget style has an extra 1 pixel offset that makes LineEdits not align with Buttons,
+ // so this compensates for that.
+ style_line_edit->set_default_margin(SIDE_TOP, style_line_edit->get_default_margin(SIDE_TOP) - 1 * EDSCALE);
// Add a bottom line to make LineEdits more visible, especially in sectioned inspectors
// such as the Project Settings.
style_line_edit->set_border_width(SIDE_BOTTOM, Math::round(2 * EDSCALE));
diff --git a/editor/editor_zoom_widget.cpp b/editor/editor_zoom_widget.cpp
index f9be829493..44751a480a 100644
--- a/editor/editor_zoom_widget.cpp
+++ b/editor/editor_zoom_widget.cpp
@@ -51,17 +51,17 @@ void EditorZoomWidget::_update_zoom_label() {
}
void EditorZoomWidget::_button_zoom_minus() {
- set_zoom_by_increments(-6);
+ set_zoom_by_increments(-6, Input::get_singleton()->is_key_pressed(KEY_ALT));
emit_signal("zoom_changed", zoom);
}
void EditorZoomWidget::_button_zoom_reset() {
- set_zoom(1.0);
+ set_zoom(1.0 * MAX(1, EDSCALE));
emit_signal("zoom_changed", zoom);
}
void EditorZoomWidget::_button_zoom_plus() {
- set_zoom_by_increments(6);
+ set_zoom_by_increments(6, Input::get_singleton()->is_key_pressed(KEY_ALT));
emit_signal("zoom_changed", zoom);
}
@@ -76,31 +76,69 @@ void EditorZoomWidget::set_zoom(float p_zoom) {
}
}
-void EditorZoomWidget::set_zoom_by_increments(int p_increment_count) {
- // Base increment factor defined as the twelveth root of two.
- // This allow a smooth geometric evolution of the zoom, with the advantage of
- // visiting all integer power of two scale factors.
- // note: this is analogous to the 'semitones' interval in the music world
- // In order to avoid numerical imprecisions, we compute and edit a zoom index
- // with the following relation: zoom = 2 ^ (index / 12)
-
- if (zoom < CMP_EPSILON || p_increment_count == 0) {
- return;
- }
+void EditorZoomWidget::set_zoom_by_increments(int p_increment_count, bool p_integer_only) {
+ // Remove editor scale from the index computation.
+ const float zoom_noscale = zoom / MAX(1, EDSCALE);
+
+ if (p_integer_only) {
+ // Only visit integer scaling factors above 100%, and fractions with an integer denominator below 100%
+ // (1/2 = 50%, 1/3 = 33.33%, 1/4 = 25%, …).
+ // This is useful when working on pixel art projects to avoid distortion.
+ // This algorithm is designed to handle fractional start zoom values correctly
+ // (e.g. 190% will zoom up to 200% and down to 100%).
+ if (zoom_noscale + p_increment_count * 0.001 >= 1.0 - CMP_EPSILON) {
+ // New zoom is certain to be above 100%.
+ if (p_increment_count >= 1) {
+ // Zooming.
+ set_zoom(Math::floor(zoom_noscale + p_increment_count) * MAX(1, EDSCALE));
+ } else {
+ // Dezooming.
+ set_zoom(Math::ceil(zoom_noscale + p_increment_count) * MAX(1, EDSCALE));
+ }
+ } else {
+ if (p_increment_count >= 1) {
+ // Zooming. Convert the current zoom into a denominator.
+ float new_zoom = 1.0 / Math::ceil(1.0 / zoom_noscale - p_increment_count);
+ if (Math::is_equal_approx(zoom_noscale, new_zoom)) {
+ // New zoom is identical to the old zoom, so try again.
+ // This can happen due to floating-point precision issues.
+ new_zoom = 1.0 / Math::ceil(1.0 / zoom_noscale - p_increment_count - 1);
+ }
+ set_zoom(new_zoom * MAX(1, EDSCALE));
+ } else {
+ // Dezooming. Convert the current zoom into a denominator.
+ float new_zoom = 1.0 / Math::floor(1.0 / zoom_noscale - p_increment_count);
+ if (Math::is_equal_approx(zoom_noscale, new_zoom)) {
+ // New zoom is identical to the old zoom, so try again.
+ // This can happen due to floating-point precision issues.
+ new_zoom = 1.0 / Math::floor(1.0 / zoom_noscale - p_increment_count + 1);
+ }
+ set_zoom(new_zoom * MAX(1, EDSCALE));
+ }
+ }
+ } else {
+ // Base increment factor defined as the twelveth root of two.
+ // This allow a smooth geometric evolution of the zoom, with the advantage of
+ // visiting all integer power of two scale factors.
+ // note: this is analogous to the 'semitones' interval in the music world
+ // In order to avoid numerical imprecisions, we compute and edit a zoom index
+ // with the following relation: zoom = 2 ^ (index / 12)
- // Remove Editor scale from the index computation
- float zoom_noscale = zoom / MAX(1, EDSCALE);
+ if (zoom < CMP_EPSILON || p_increment_count == 0) {
+ return;
+ }
- // zoom = 2**(index/12) => log2(zoom) = index/12
- float closest_zoom_index = Math::round(Math::log(zoom_noscale) * 12.f / Math::log(2.f));
+ // zoom = 2**(index/12) => log2(zoom) = index/12
+ float closest_zoom_index = Math::round(Math::log(zoom_noscale) * 12.f / Math::log(2.f));
- float new_zoom_index = closest_zoom_index + p_increment_count;
- float new_zoom = Math::pow(2.f, new_zoom_index / 12.f);
+ float new_zoom_index = closest_zoom_index + p_increment_count;
+ float new_zoom = Math::pow(2.f, new_zoom_index / 12.f);
- // Restore Editor scale transformation
- new_zoom *= MAX(1, EDSCALE);
+ // Restore Editor scale transformation
+ new_zoom *= MAX(1, EDSCALE);
- set_zoom(new_zoom);
+ set_zoom(new_zoom);
+ }
}
void EditorZoomWidget::_notification(int p_what) {
@@ -118,7 +156,7 @@ void EditorZoomWidget::_notification(int p_what) {
void EditorZoomWidget::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_zoom", "zoom"), &EditorZoomWidget::set_zoom);
ClassDB::bind_method(D_METHOD("get_zoom"), &EditorZoomWidget::get_zoom);
- ClassDB::bind_method(D_METHOD("set_zoom_by_increments", "increment"), &EditorZoomWidget::set_zoom_by_increments);
+ ClassDB::bind_method(D_METHOD("set_zoom_by_increments", "increment", "integer_only"), &EditorZoomWidget::set_zoom_by_increments);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "zoom"), "set_zoom", "get_zoom");
diff --git a/editor/editor_zoom_widget.h b/editor/editor_zoom_widget.h
index 4e95018e52..c35faeefe7 100644
--- a/editor/editor_zoom_widget.h
+++ b/editor/editor_zoom_widget.h
@@ -56,7 +56,7 @@ public:
float get_zoom();
void set_zoom(float p_zoom);
- void set_zoom_by_increments(int p_increment_count);
+ void set_zoom_by_increments(int p_increment_count, bool p_integer_only = false);
};
#endif // EDITOR_ZOOM_WIDGET_H
diff --git a/editor/export_template_manager.cpp b/editor/export_template_manager.cpp
index dd4ce74406..112a9e92a8 100644
--- a/editor/export_template_manager.cpp
+++ b/editor/export_template_manager.cpp
@@ -812,6 +812,7 @@ ExportTemplateManager::ExportTemplateManager() {
main_vb->add_child(current_hb);
Label *current_label = memnew(Label);
+ current_label->set_theme_type_variation("HeaderSmall");
current_label->set_text(TTR("Current Version:"));
current_hb->add_child(current_label);
@@ -821,6 +822,8 @@ ExportTemplateManager::ExportTemplateManager() {
// Current version statuses.
// Status: Current version is missing.
current_missing_label = memnew(Label);
+ current_missing_label->set_theme_type_variation("HeaderSmall");
+
current_missing_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
current_missing_label->set_align(Label::ALIGN_RIGHT);
current_missing_label->set_text(TTR("Export templates are missing. Download them or install from a file."));
@@ -828,6 +831,7 @@ ExportTemplateManager::ExportTemplateManager() {
// Status: Current version is installed.
current_installed_label = memnew(Label);
+ current_installed_label->set_theme_type_variation("HeaderSmall");
current_installed_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
current_installed_label->set_align(Label::ALIGN_RIGHT);
current_installed_label->set_text(TTR("Export templates are installed and ready to be used."));
@@ -947,6 +951,7 @@ ExportTemplateManager::ExportTemplateManager() {
HBoxContainer *installed_versions_hb = memnew(HBoxContainer);
main_vb->add_child(installed_versions_hb);
Label *installed_label = memnew(Label);
+ installed_label->set_theme_type_variation("HeaderSmall");
installed_label->set_text(TTR("Other Installed Versions:"));
installed_versions_hb->add_child(installed_label);
diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp
index 1b11ec4451..76fbee7490 100644
--- a/editor/groups_editor.cpp
+++ b/editor/groups_editor.cpp
@@ -424,6 +424,8 @@ GroupDialog::GroupDialog() {
vbc_left->set_h_size_flags(Control::SIZE_EXPAND_FILL);
Label *group_title = memnew(Label);
+ group_title->set_theme_type_variation("HeaderSmall");
+
group_title->set_text(TTR("Groups"));
vbc_left->add_child(group_title);
@@ -458,6 +460,8 @@ GroupDialog::GroupDialog() {
vbc_add->set_h_size_flags(Control::SIZE_EXPAND_FILL);
Label *out_of_group_title = memnew(Label);
+ out_of_group_title->set_theme_type_variation("HeaderSmall");
+
out_of_group_title->set_text(TTR("Nodes Not in Group"));
vbc_add->add_child(out_of_group_title);
@@ -506,6 +510,8 @@ GroupDialog::GroupDialog() {
vbc_remove->set_h_size_flags(Control::SIZE_EXPAND_FILL);
Label *in_group_title = memnew(Label);
+ in_group_title->set_theme_type_variation("HeaderSmall");
+
in_group_title->set_text(TTR("Nodes in Group"));
vbc_remove->add_child(in_group_title);
@@ -528,10 +534,12 @@ GroupDialog::GroupDialog() {
remove_filter->connect("text_changed", callable_mp(this, &GroupDialog::_remove_filter_changed));
group_empty = memnew(Label());
+ group_empty->set_theme_type_variation("HeaderSmall");
+
group_empty->set_text(TTR("Empty groups will be automatically removed."));
group_empty->set_valign(Label::VALIGN_CENTER);
group_empty->set_align(Label::ALIGN_CENTER);
- group_empty->set_autowrap(true);
+ group_empty->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART);
group_empty->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
nodes_to_remove->add_child(group_empty);
group_empty->set_anchors_and_offsets_preset(Control::PRESET_WIDE, Control::PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
diff --git a/editor/icons/ImmediateMesh.svg b/editor/icons/ImmediateMesh.svg
new file mode 100644
index 0000000000..9521530876
--- /dev/null
+++ b/editor/icons/ImmediateMesh.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 14.999999 14.999999" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 2v2h5v-2zm5 2v3h2v-3zm2-2v2h5v-2zm-2 7v3h2v-3zm-5 3v2h5v-2zm7 0v2h5v-2z" fill="#ffca5f" transform="scale(.93749994)"/></svg>
diff --git a/editor/icons/ORMMaterial3D.svg b/editor/icons/ORMMaterial3D.svg
index 3d6db6910d..e09208155d 100644
--- a/editor/icons/ORMMaterial3D.svg
+++ b/editor/icons/ORMMaterial3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5.0534707 10.652714q0 .729229-.4538398 1.253141-.4538403.516832-1.0868283.516832h-1.1943162q-.6389592 0-1.1047425-.509753-.47175502-.509751-.47175502-1.26022v-5.5223119q0-.7575473.47175502-1.2672998.4717549-.5097517 1.1047425-.5097517h1.1943162q.6270165 0 1.0868283.516832.4538398.5168313.4538398 1.2602195zm-1.0808559-.233636v-5.0550395q0-.5734707-.3344086-.8141867-.1074887-.0849591-.2567782-.0778788h-.9912826q-.2567779 0-.4120391.2690357-.1552611.2690357-.1552611.6230298v5.0550395q0 .559311.3164938.807108.1074885.08496.2508064.08496h.9912826q.2746925 0 .4359254-.276116.1552614-.276115.1552614-.61595z" fill="#f00"/><path d="m9.9872948 12.451006h-1.0427362l-1.4698137-3.9222572h-.7931457v3.9222572h-1.0094573v-9.076416h2.739956q.5435541 0 .9318066.4601926.3882524.4601933.3882524 1.1540217v2.1239667q0 1.0053443-.6766682 1.3168588-.2107668.099119-.4659043.099119zm-1.2590481-5.64267v-1.5858953q0-.4743524-.2884169-.6867495-.088743-.070798-.2052192-.063719h-1.5530114v2.9452329h1.7194053q.2828702-.00708.3161488-.389394.011093-.1132781.011093-.2194752z" fill="#008000"/><path d="m10.201004 3.7285848q0-.4106342.529158-.3681546.126777.014161.209458.014161v.00708h.115753l1.692202 4.9205216 1.697714-4.9205216h.06063v-.00708h.463013q.198434 0 .297651.212397.03307.063719.03307.1415978v8.694102h-1.01422v-5.6001914l-1.058314 3.2284284h-.953584l-1.058315-2.9310723v5.3028353h-1.014218z" fill="#00f"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 3.1191406-3.7636719 1.8808594 3.7636719 1.8828125 3.763672-1.8828125z" fill="#80ff45"/><path d="m3 6.6191406v2.3808594 1.382812l1.234375.617188 2.765625 1.382812v-1.382812-2-.3808594l-3.2382812-1.6191406z" fill="#ff4545"/><path d="m13 6.6191406-.761719.3808594-3.238281 1.6191406v3.7636714l2.765625-1.382812 1.234375-.617188v-1.382812z" fill="#45d7ff"/></svg>
diff --git a/editor/import/scene_importer_mesh.cpp b/editor/import/scene_importer_mesh.cpp
index ce78166d1e..f8e93df382 100644
--- a/editor/import/scene_importer_mesh.cpp
+++ b/editor/import/scene_importer_mesh.cpp
@@ -506,7 +506,7 @@ Vector<Ref<Shape3D>> EditorSceneImporterMesh::convex_decompose() const {
const Vector<Face3> faces = get_faces();
- Vector<Vector<Face3>> decomposed = Mesh::convex_composition_function(faces);
+ Vector<Vector<Face3>> decomposed = Mesh::convex_composition_function(faces, -1);
Vector<Ref<Shape3D>> ret;
diff --git a/editor/localization_editor.cpp b/editor/localization_editor.cpp
index 208d4437d3..977ca83671 100644
--- a/editor/localization_editor.cpp
+++ b/editor/localization_editor.cpp
@@ -656,7 +656,9 @@ LocalizationEditor::LocalizationEditor() {
translations->add_child(tvb);
HBoxContainer *thb = memnew(HBoxContainer);
- thb->add_child(memnew(Label(TTR("Translations:"))));
+ Label *l = memnew(Label(TTR("Translations:")));
+ l->set_theme_type_variation("HeaderSmall");
+ thb->add_child(l);
thb->add_spacer();
tvb->add_child(thb);
@@ -684,7 +686,9 @@ LocalizationEditor::LocalizationEditor() {
translations->add_child(tvb);
HBoxContainer *thb = memnew(HBoxContainer);
- thb->add_child(memnew(Label(TTR("Resources:"))));
+ Label *l = memnew(Label(TTR("Resources:")));
+ l->set_theme_type_variation("HeaderSmall");
+ thb->add_child(l);
thb->add_spacer();
tvb->add_child(thb);
@@ -708,7 +712,9 @@ LocalizationEditor::LocalizationEditor() {
add_child(translation_res_file_open_dialog);
thb = memnew(HBoxContainer);
- thb->add_child(memnew(Label(TTR("Remaps by Locale:"))));
+ l = memnew(Label(TTR("Remaps by Locale:")));
+ l->set_theme_type_variation("HeaderSmall");
+ thb->add_child(l);
thb->add_spacer();
tvb->add_child(thb);
@@ -758,7 +764,9 @@ LocalizationEditor::LocalizationEditor() {
translation_locale_filter_mode->connect("item_selected", callable_mp(this, &LocalizationEditor::_translation_filter_mode_changed));
tmc->add_margin_child(TTR("Filter mode:"), translation_locale_filter_mode);
- tmc->add_child(memnew(Label(TTR("Locales:"))));
+ Label *l = memnew(Label(TTR("Locales:")));
+ l->set_theme_type_variation("HeaderSmall");
+ tmc->add_child(l);
translation_filter = memnew(Tree);
translation_filter->set_v_size_flags(Control::SIZE_EXPAND_FILL);
translation_filter->set_columns(1);
@@ -772,7 +780,9 @@ LocalizationEditor::LocalizationEditor() {
translations->add_child(tvb);
HBoxContainer *thb = memnew(HBoxContainer);
- thb->add_child(memnew(Label(TTR("Files with translation strings:"))));
+ Label *l = memnew(Label(TTR("Files with translation strings:")));
+ l->set_theme_type_variation("HeaderSmall");
+ thb->add_child(l);
thb->add_spacer();
tvb->add_child(thb);
diff --git a/editor/node_dock.cpp b/editor/node_dock.cpp
index 43c9cabe01..95a2d81e00 100644
--- a/editor/node_dock.cpp
+++ b/editor/node_dock.cpp
@@ -130,6 +130,6 @@ NodeDock::NodeDock() {
select_a_node->set_v_size_flags(SIZE_EXPAND_FILL);
select_a_node->set_valign(Label::VALIGN_CENTER);
select_a_node->set_align(Label::ALIGN_CENTER);
- select_a_node->set_autowrap(true);
+ select_a_node->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART);
add_child(select_a_node);
}
diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp
index cd61ebd418..596b2a6527 100644
--- a/editor/plugins/asset_library_editor_plugin.cpp
+++ b/editor/plugins/asset_library_editor_plugin.cpp
@@ -369,6 +369,9 @@ void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int
progress->set_modulate(Color(0, 0, 0, 0));
set_process(false);
+
+ // Automatically prompt for installation once the download is completed.
+ _install();
}
void EditorAssetLibraryItemDownload::configure(const String &p_title, int p_asset_id, const Ref<Texture2D> &p_preview, const String &p_download_url, const String &p_sha256_hash) {
@@ -456,6 +459,7 @@ void EditorAssetLibraryItemDownload::_install() {
return;
}
+ asset_installer->set_asset_name(title->get_text());
asset_installer->open(file, 1);
}
@@ -1296,6 +1300,7 @@ void EditorAssetLibrary::_asset_file_selected(const String &p_file) {
}
asset_installer = memnew(EditorAssetInstaller);
+ asset_installer->set_asset_name(p_file.get_basename());
add_child(asset_installer);
asset_installer->open(p_file);
}
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 7282475ddf..bd9847ea95 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -1149,8 +1149,9 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bo
view_offset.y += int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor();
update_viewport();
} else {
- zoom_widget->set_zoom_by_increments(-1);
- if (b->get_factor() != 1.f) {
+ zoom_widget->set_zoom_by_increments(-1, Input::get_singleton()->is_key_pressed(KEY_ALT));
+ if (!Math::is_equal_approx(b->get_factor(), 1.0f)) {
+ // Handle high-precision (analog) scrolling.
zoom_widget->set_zoom(zoom * ((zoom_widget->get_zoom() / zoom - 1.f) * b->get_factor() + 1.f));
}
_zoom_on_position(zoom_widget->get_zoom(), b->get_position());
@@ -1164,8 +1165,9 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bo
view_offset.y -= int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor();
update_viewport();
} else {
- zoom_widget->set_zoom_by_increments(1);
- if (b->get_factor() != 1.f) {
+ zoom_widget->set_zoom_by_increments(1, Input::get_singleton()->is_key_pressed(KEY_ALT));
+ if (!Math::is_equal_approx(b->get_factor(), 1.0f)) {
+ // Handle high-precision (analog) scrolling.
zoom_widget->set_zoom(zoom * ((zoom_widget->get_zoom() / zoom - 1.f) * b->get_factor() + 1.f));
}
_zoom_on_position(zoom_widget->get_zoom(), b->get_position());
@@ -1194,6 +1196,20 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bo
Ref<InputEventKey> k = p_event;
if (k.is_valid()) {
+ if (k->is_pressed()) {
+ if (ED_GET_SHORTCUT("canvas_item_editor/zoom_100_percent")->is_shortcut(p_event)) {
+ _update_zoom(1.0 * MAX(1, EDSCALE));
+ } else if (ED_GET_SHORTCUT("canvas_item_editor/zoom_200_percent")->is_shortcut(p_event)) {
+ _update_zoom(2.0 * MAX(1, EDSCALE));
+ } else if (ED_GET_SHORTCUT("canvas_item_editor/zoom_400_percent")->is_shortcut(p_event)) {
+ _update_zoom(4.0 * MAX(1, EDSCALE));
+ } else if (ED_GET_SHORTCUT("canvas_item_editor/zoom_800_percent")->is_shortcut(p_event)) {
+ _update_zoom(8.0 * MAX(1, EDSCALE));
+ } else if (ED_GET_SHORTCUT("canvas_item_editor/zoom_1600_percent")->is_shortcut(p_event)) {
+ _update_zoom(16.0 * MAX(1, EDSCALE));
+ }
+ }
+
bool is_pan_key = pan_view_shortcut.is_valid() && pan_view_shortcut->is_shortcut(p_event);
if (is_pan_key && (EditorSettings::get_singleton()->get("editors/2d/simple_panning") || drag_type != DRAG_NONE)) {
@@ -5610,6 +5626,16 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
skeleton_menu->get_popup()->set_item_checked(skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES), true);
singleton = this;
+ // To ensure that scripts can parse the list of shortcuts correctly, we have to define
+ // those shortcuts one by one.
+ // Resetting zoom to 100% is a duplicate shortcut of `canvas_item_editor/reset_zoom`,
+ // but it ensures both 1 and Ctrl + 0 can be used to reset zoom.
+ ED_SHORTCUT("canvas_item_editor/zoom_100_percent", TTR("Zoom to 100%"), KEY_1);
+ ED_SHORTCUT("canvas_item_editor/zoom_200_percent", TTR("Zoom to 200%"), KEY_2);
+ ED_SHORTCUT("canvas_item_editor/zoom_400_percent", TTR("Zoom to 400%"), KEY_3);
+ ED_SHORTCUT("canvas_item_editor/zoom_800_percent", TTR("Zoom to 800%"), KEY_4);
+ ED_SHORTCUT("canvas_item_editor/zoom_1600_percent", TTR("Zoom to 1600%"), KEY_5);
+
set_process_unhandled_key_input(true);
// Update the menus' checkboxes
diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp
index 0d2b2ea2f5..7434accc1a 100644
--- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp
+++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp
@@ -153,14 +153,18 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
ur->add_undo_method(node->get_parent(), "remove_child", cshape);
ur->commit_action();
} break;
- case MENU_OPTION_CREATE_SINGLE_CONVEX_COLLISION_SHAPE: {
+
+ case MENU_OPTION_CREATE_SINGLE_CONVEX_COLLISION_SHAPE:
+ case MENU_OPTION_CREATE_SIMPLIFIED_CONVEX_COLLISION_SHAPE: {
if (node == get_tree()->get_edited_scene_root()) {
err_dialog->set_text(TTR("Can't create a single convex collision shape for the scene root."));
err_dialog->popup_centered();
return;
}
- Ref<Shape3D> shape = mesh->create_convex_shape();
+ bool simplify = (p_option == MENU_OPTION_CREATE_SIMPLIFIED_CONVEX_COLLISION_SHAPE);
+
+ Ref<Shape3D> shape = mesh->create_convex_shape(true, simplify);
if (shape.is_null()) {
err_dialog->set_text(TTR("Couldn't create a single convex collision shape."));
@@ -169,7 +173,11 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
}
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
- ur->create_action(TTR("Create Single Convex Shape"));
+ if (simplify) {
+ ur->create_action(TTR("Create Simplified Convex Shape"));
+ } else {
+ ur->create_action(TTR("Create Single Convex Shape"));
+ }
CollisionShape3D *cshape = memnew(CollisionShape3D);
cshape->set_shape(shape);
@@ -186,6 +194,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
ur->commit_action();
} break;
+
case MENU_OPTION_CREATE_MULTIPLE_CONVEX_COLLISION_SHAPES: {
if (node == get_tree()->get_edited_scene_root()) {
err_dialog->set_text(TTR("Can't create multiple convex collision shapes for the scene root."));
@@ -441,8 +450,10 @@ MeshInstance3DEditor::MeshInstance3DEditor() {
options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a polygon-based collision shape.\nThis is the most accurate (but slowest) option for collision detection."));
options->get_popup()->add_item(TTR("Create Single Convex Collision Sibling"), MENU_OPTION_CREATE_SINGLE_CONVEX_COLLISION_SHAPE);
options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a single convex collision shape.\nThis is the fastest (but least accurate) option for collision detection."));
+ options->get_popup()->add_item(TTR("Create Simplified Convex Collision Sibling"), MENU_OPTION_CREATE_SIMPLIFIED_CONVEX_COLLISION_SHAPE);
+ options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a simplified convex collision shape.\nThis is similar to single collision shape, but can result in a simpler geometry in some cases, at the cost of accuracy."));
options->get_popup()->add_item(TTR("Create Multiple Convex Collision Siblings"), MENU_OPTION_CREATE_MULTIPLE_CONVEX_COLLISION_SHAPES);
- options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a polygon-based collision shape.\nThis is a performance middle-ground between the two above options."));
+ options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a polygon-based collision shape.\nThis is a performance middle-ground between a single convex collision and a polygon-based collision."));
options->get_popup()->add_separator();
options->get_popup()->add_item(TTR("Create Navigation Mesh"), MENU_OPTION_CREATE_NAVMESH);
options->get_popup()->add_separator();
diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.h b/editor/plugins/mesh_instance_3d_editor_plugin.h
index 69f494de7f..98b667c978 100644
--- a/editor/plugins/mesh_instance_3d_editor_plugin.h
+++ b/editor/plugins/mesh_instance_3d_editor_plugin.h
@@ -43,6 +43,7 @@ class MeshInstance3DEditor : public Control {
MENU_OPTION_CREATE_STATIC_TRIMESH_BODY,
MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE,
MENU_OPTION_CREATE_SINGLE_CONVEX_COLLISION_SHAPE,
+ MENU_OPTION_CREATE_SIMPLIFIED_CONVEX_COLLISION_SHAPE,
MENU_OPTION_CREATE_MULTIPLE_CONVEX_COLLISION_SHAPES,
MENU_OPTION_CREATE_NAVMESH,
MENU_OPTION_CREATE_OUTLINE_MESH,
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index a7177faafa..3532473e17 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -467,22 +467,31 @@ void Node3DEditorViewport::_select_clicked(bool p_append, bool p_single, bool p_
}
void Node3DEditorViewport::_select(Node *p_node, bool p_append, bool p_single) {
- if (!p_append) {
- editor_selection->clear();
- }
-
- if (editor_selection->is_selected(p_node)) {
- //erase
- editor_selection->remove_node(p_node);
+ // Add or remove a single node from the selection
+ if (p_append && p_single) {
+ if (editor_selection->is_selected(p_node)) {
+ // Already in the selection, remove it from the selected nodes
+ editor_selection->remove_node(p_node);
+ } else {
+ // Add the item to the selection
+ editor_selection->add_node(p_node);
+ }
+ } else if (p_append && !p_single) {
+ // Add the item to the selection
+ editor_selection->add_node(p_node);
} else {
+ // No append; single select
+ editor_selection->clear();
editor_selection->add_node(p_node);
- }
-
- if (p_single) {
+ // Reselect
if (Engine::get_singleton()->is_editor_hint()) {
editor->call("edit_node", p_node);
}
}
+
+ if (editor_selection->get_selected_node_list().size() == 1) {
+ editor->push_item(editor_selection->get_selected_node_list()[0]);
+ }
}
ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos, bool p_append, bool &r_includes_current, int *r_gizmo_handle, bool p_alt_select) {
@@ -6172,7 +6181,7 @@ void Node3DEditor::snap_selected_nodes_to_floor() {
}
if (snapped_to_floor) {
- undo_redo->create_action(TTR("Snap Nodes To Floor"));
+ undo_redo->create_action(TTR("Snap Nodes to Floor"));
// Perform snapping if at least one node can be snapped
for (int i = 0; i < keys.size(); i++) {
@@ -6218,9 +6227,14 @@ void Node3DEditor::_sun_environ_settings_pressed() {
sun_environ_popup->popup();
}
-void Node3DEditor::_add_sun_to_scene() {
+void Node3DEditor::_add_sun_to_scene(bool p_already_added_environment) {
sun_environ_popup->hide();
+ if (!p_already_added_environment && world_env_count == 0 && Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ // Prevent infinite feedback loop between the sun and environment methods.
+ _add_environment_to_scene(true);
+ }
+
Node *base = get_tree()->get_edited_scene_root();
if (!base) {
// Create a root node so we can add child nodes to it.
@@ -6232,14 +6246,23 @@ void Node3DEditor::_add_sun_to_scene() {
undo_redo->create_action("Add Preview Sun to Scene");
undo_redo->add_do_method(base, "add_child", new_sun);
+ // Move to the beginning of the scene tree since more "global" nodes
+ // generally look better when placed at the top.
+ undo_redo->add_do_method(base, "move_child", new_sun, 0);
undo_redo->add_do_method(new_sun, "set_owner", base);
undo_redo->add_undo_method(base, "remove_child", new_sun);
undo_redo->add_do_reference(new_sun);
undo_redo->commit_action();
}
-void Node3DEditor::_add_environment_to_scene() {
+
+void Node3DEditor::_add_environment_to_scene(bool p_already_added_sun) {
sun_environ_popup->hide();
+ if (!p_already_added_sun && directional_light_count == 0 && Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ // Prevent infinite feedback loop between the sun and environment methods.
+ _add_sun_to_scene(true);
+ }
+
Node *base = get_tree()->get_edited_scene_root();
if (!base) {
// Create a root node so we can add child nodes to it.
@@ -6253,6 +6276,9 @@ void Node3DEditor::_add_environment_to_scene() {
undo_redo->create_action("Add Preview Environment to Scene");
undo_redo->add_do_method(base, "add_child", new_env);
+ // Move to the beginning of the scene tree since more "global" nodes
+ // generally look better when placed at the top.
+ undo_redo->add_do_method(base, "move_child", new_env, 0);
undo_redo->add_do_method(new_env, "set_owner", base);
undo_redo->add_undo_method(base, "remove_child", new_env);
undo_redo->add_do_reference(new_env);
@@ -7111,6 +7137,7 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) {
sun_vb->hide();
sun_title = memnew(Label);
+ sun_title->set_theme_type_variation("HeaderSmall");
sun_vb->add_child(sun_title);
sun_title->set_text(TTR("Preview Sun"));
sun_title->set_align(Label::ALIGN_CENTER);
@@ -7180,7 +7207,8 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) {
sun_add_to_scene = memnew(Button);
sun_add_to_scene->set_text(TTR("Add Sun to Scene"));
- sun_add_to_scene->connect("pressed", callable_mp(this, &Node3DEditor::_add_sun_to_scene));
+ sun_add_to_scene->set_tooltip(TTR("Adds a DirectionalLight3D node matching the preview sun settings to the current scene.\nHold Shift while clicking to also add the preview environment to the current scene."));
+ sun_add_to_scene->connect("pressed", callable_mp(this, &Node3DEditor::_add_sun_to_scene), varray(false));
sun_vb->add_spacer();
sun_vb->add_child(sun_add_to_scene);
@@ -7201,6 +7229,8 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) {
environ_vb->hide();
environ_title = memnew(Label);
+ environ_title->set_theme_type_variation("HeaderSmall");
+
environ_vb->add_child(environ_title);
environ_title->set_text(TTR("Preview Environment"));
environ_title->set_align(Label::ALIGN_CENTER);
@@ -7244,7 +7274,8 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) {
environ_add_to_scene = memnew(Button);
environ_add_to_scene->set_text(TTR("Add Environment to Scene"));
- environ_add_to_scene->connect("pressed", callable_mp(this, &Node3DEditor::_add_environment_to_scene));
+ environ_add_to_scene->set_tooltip(TTR("Adds a WorldEnvironment node matching the preview environment settings to the current scene.\nHold Shift while clicking to also add the preview sun to the current scene."));
+ environ_add_to_scene->connect("pressed", callable_mp(this, &Node3DEditor::_add_environment_to_scene), varray(false));
environ_vb->add_spacer();
environ_vb->add_child(environ_add_to_scene);
diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h
index ac0b2e1859..a195a0eee0 100644
--- a/editor/plugins/node_3d_editor_plugin.h
+++ b/editor/plugins/node_3d_editor_plugin.h
@@ -805,8 +805,8 @@ private:
void _preview_settings_changed();
void _sun_environ_settings_pressed();
- void _add_sun_to_scene();
- void _add_environment_to_scene();
+ void _add_sun_to_scene(bool p_already_added_environment = false);
+ void _add_environment_to_scene(bool p_already_added_sun = false);
protected:
void _notification(int p_what);
diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp
index be1aeb309f..0a8a0dcdce 100644
--- a/editor/plugins/theme_editor_plugin.cpp
+++ b/editor/plugins/theme_editor_plugin.cpp
@@ -1144,7 +1144,7 @@ ThemeItemImportTree::ThemeItemImportTree() {
select_icons_warning = memnew(Label);
select_icons_warning->set_text(TTR("Caution: Adding icon data may considerably increase the size of your Theme resource."));
- select_icons_warning->set_autowrap(true);
+ select_icons_warning->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART);
select_icons_warning->set_h_size_flags(Control::SIZE_EXPAND_FILL);
select_icons_warning_hb->add_child(select_icons_warning);
}
@@ -1943,6 +1943,117 @@ ThemeItemEditorDialog::ThemeItemEditorDialog() {
confirm_closing_dialog->connect("confirmed", callable_mp(this, &ThemeItemEditorDialog::_close_dialog));
}
+void ThemeTypeDialog::_dialog_about_to_show() {
+ add_type_filter->set_text("");
+ add_type_filter->grab_focus();
+
+ _update_add_type_options();
+}
+
+void ThemeTypeDialog::ok_pressed() {
+ emit_signal("type_selected", add_type_filter->get_text().strip_edges());
+}
+
+void ThemeTypeDialog::_update_add_type_options(const String &p_filter) {
+ add_type_options->clear();
+
+ List<StringName> names;
+ Theme::get_default()->get_type_list(&names);
+ if (include_own_types) {
+ edited_theme->get_type_list(&names);
+ }
+ names.sort_custom<StringName::AlphCompare>();
+
+ Vector<StringName> unique_names;
+ for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
+ // Filter out undesired values.
+ if (!p_filter.is_subsequence_ofi(String(E->get()))) {
+ continue;
+ }
+
+ // Skip duplicate values.
+ if (unique_names.has(E->get())) {
+ continue;
+ }
+ unique_names.append(E->get());
+
+ Ref<Texture2D> item_icon;
+ if (E->get() == "") {
+ item_icon = get_theme_icon("NodeDisabled", "EditorIcons");
+ } else {
+ item_icon = EditorNode::get_singleton()->get_class_icon(E->get(), "NodeDisabled");
+ }
+
+ add_type_options->add_item(E->get(), item_icon);
+ }
+}
+
+void ThemeTypeDialog::_add_type_filter_cbk(const String &p_value) {
+ _update_add_type_options(p_value);
+}
+
+void ThemeTypeDialog::_add_type_options_cbk(int p_index) {
+ add_type_filter->set_text(add_type_options->get_item_text(p_index));
+}
+
+void ThemeTypeDialog::_add_type_dialog_entered(const String &p_value) {
+ emit_signal("type_selected", p_value.strip_edges());
+ hide();
+}
+
+void ThemeTypeDialog::_add_type_dialog_activated(int p_index) {
+ emit_signal("type_selected", add_type_options->get_item_text(p_index));
+ hide();
+}
+
+void ThemeTypeDialog::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ connect("about_to_popup", callable_mp(this, &ThemeTypeDialog::_dialog_about_to_show));
+ [[fallthrough]];
+ }
+ case NOTIFICATION_THEME_CHANGED: {
+ _update_add_type_options();
+ } break;
+ }
+}
+
+void ThemeTypeDialog::_bind_methods() {
+ ADD_SIGNAL(MethodInfo("type_selected", PropertyInfo(Variant::STRING, "type_name")));
+}
+
+void ThemeTypeDialog::set_edited_theme(const Ref<Theme> &p_theme) {
+ edited_theme = p_theme;
+}
+
+void ThemeTypeDialog::set_include_own_types(bool p_enable) {
+ include_own_types = p_enable;
+}
+
+ThemeTypeDialog::ThemeTypeDialog() {
+ VBoxContainer *add_type_vb = memnew(VBoxContainer);
+ add_child(add_type_vb);
+
+ Label *add_type_filter_label = memnew(Label);
+ add_type_filter_label->set_text(TTR("Name:"));
+ add_type_vb->add_child(add_type_filter_label);
+
+ add_type_filter = memnew(LineEdit);
+ add_type_vb->add_child(add_type_filter);
+ add_type_filter->connect("text_changed", callable_mp(this, &ThemeTypeDialog::_add_type_filter_cbk));
+ add_type_filter->connect("text_submitted", callable_mp(this, &ThemeTypeDialog::_add_type_dialog_entered));
+
+ Label *add_type_options_label = memnew(Label);
+ add_type_options_label->set_text(TTR("Node Types:"));
+ add_type_vb->add_child(add_type_options_label);
+
+ add_type_options = memnew(ItemList);
+ add_type_options->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ add_type_vb->add_child(add_type_options);
+ add_type_options->connect("item_selected", callable_mp(this, &ThemeTypeDialog::_add_type_options_cbk));
+ add_type_options->connect("item_activated", callable_mp(this, &ThemeTypeDialog::_add_type_dialog_activated));
+}
+
VBoxContainer *ThemeTypeEditor::_create_item_list(Theme::DataType p_data_type) {
VBoxContainer *items_tab = memnew(VBoxContainer);
items_tab->set_custom_minimum_size(Size2(0, 160) * EDSCALE);
@@ -2048,36 +2159,18 @@ void ThemeTypeEditor::_update_type_list_debounced() {
update_debounce_timer->start();
}
-void ThemeTypeEditor::_update_add_type_options(const String &p_filter) {
- add_type_options->clear();
-
- List<StringName> names;
- Theme::get_default()->get_type_list(&names);
- names.sort_custom<StringName::AlphCompare>();
-
- for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
- if (!p_filter.is_subsequence_ofi(String(E->get()))) {
- continue;
- }
-
- Ref<Texture2D> item_icon;
- if (E->get() == "") {
- item_icon = get_theme_icon("NodeDisabled", "EditorIcons");
- } else {
- item_icon = EditorNode::get_singleton()->get_class_icon(E->get(), "NodeDisabled");
- }
-
- add_type_options->add_item(E->get(), item_icon);
- }
-}
-
OrderedHashMap<StringName, bool> ThemeTypeEditor::_get_type_items(String p_type_name, void (Theme::*get_list_func)(StringName, List<StringName> *) const, bool include_default) {
OrderedHashMap<StringName, bool> items;
List<StringName> names;
if (include_default) {
names.clear();
- (Theme::get_default().operator->()->*get_list_func)(p_type_name, &names);
+ String default_type = p_type_name;
+ if (edited_theme->get_type_variation_base(p_type_name) != StringName()) {
+ default_type = edited_theme->get_type_variation_base(p_type_name);
+ }
+
+ (Theme::get_default().operator->()->*get_list_func)(default_type, &names);
names.sort_custom<StringName::AlphCompare>();
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
items[E->get()] = false;
@@ -2435,6 +2528,20 @@ void ThemeTypeEditor::_update_type_items() {
stylebox_items_list->add_child(item_control);
}
}
+
+ // Various type settings.
+ if (ClassDB::class_exists(edited_type)) {
+ type_variation_edit->set_editable(false);
+ type_variation_edit->set_tooltip(TTR("A type associated with a built-in class cannot be marked as a variation of another type."));
+ type_variation_edit->set_text("");
+ type_variation_button->hide();
+ } else {
+ type_variation_edit->set_editable(true);
+ type_variation_edit->set_tooltip("");
+ type_variation_edit->set_text(edited_theme->get_type_variation_base(edited_type));
+ _add_focusable(type_variation_edit);
+ type_variation_button->show();
+ }
}
void ThemeTypeEditor::_list_type_selected(int p_index) {
@@ -2443,34 +2550,18 @@ void ThemeTypeEditor::_list_type_selected(int p_index) {
}
void ThemeTypeEditor::_add_type_button_cbk() {
+ add_type_mode = ADD_THEME_TYPE;
+ add_type_dialog->set_title(TTR("Add Item Type"));
+ add_type_dialog->set_include_own_types(false);
add_type_dialog->popup_centered(Size2(560, 420) * EDSCALE);
- add_type_filter->grab_focus();
-}
-
-void ThemeTypeEditor::_add_type_filter_cbk(const String &p_value) {
- _update_add_type_options(p_value);
-}
-
-void ThemeTypeEditor::_add_type_options_cbk(int p_index) {
- add_type_filter->set_text(add_type_options->get_item_text(p_index));
-}
-
-void ThemeTypeEditor::_add_type_dialog_confirmed() {
- select_type(add_type_filter->get_text().strip_edges());
-}
-
-void ThemeTypeEditor::_add_type_dialog_entered(const String &p_value) {
- select_type(p_value.strip_edges());
- add_type_dialog->hide();
-}
-
-void ThemeTypeEditor::_add_type_dialog_activated(int p_index) {
- select_type(add_type_options->get_item_text(p_index));
- add_type_dialog->hide();
}
void ThemeTypeEditor::_add_default_type_items() {
List<StringName> names;
+ String default_type = edited_type;
+ if (edited_theme->get_type_variation_base(edited_type) != StringName()) {
+ default_type = edited_theme->get_type_variation_base(edited_type);
+ }
updating = true;
// Prevent changes from immediatelly being reported while the operation is still ongoing.
@@ -2478,7 +2569,7 @@ void ThemeTypeEditor::_add_default_type_items() {
{
names.clear();
- Theme::get_default()->get_icon_list(edited_type, &names);
+ Theme::get_default()->get_icon_list(default_type, &names);
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
if (!edited_theme->has_icon(E->get(), edited_type)) {
edited_theme->set_icon(E->get(), edited_type, Ref<Texture2D>());
@@ -2487,7 +2578,7 @@ void ThemeTypeEditor::_add_default_type_items() {
}
{
names.clear();
- Theme::get_default()->get_stylebox_list(edited_type, &names);
+ Theme::get_default()->get_stylebox_list(default_type, &names);
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
if (!edited_theme->has_stylebox(E->get(), edited_type)) {
edited_theme->set_stylebox(E->get(), edited_type, Ref<StyleBox>());
@@ -2496,7 +2587,7 @@ void ThemeTypeEditor::_add_default_type_items() {
}
{
names.clear();
- Theme::get_default()->get_font_list(edited_type, &names);
+ Theme::get_default()->get_font_list(default_type, &names);
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
if (!edited_theme->has_font(E->get(), edited_type)) {
edited_theme->set_font(E->get(), edited_type, Ref<Font>());
@@ -2505,28 +2596,28 @@ void ThemeTypeEditor::_add_default_type_items() {
}
{
names.clear();
- Theme::get_default()->get_font_size_list(edited_type, &names);
+ Theme::get_default()->get_font_size_list(default_type, &names);
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
if (!edited_theme->has_font_size(E->get(), edited_type)) {
- edited_theme->set_font_size(E->get(), edited_type, Theme::get_default()->get_font_size(E->get(), edited_type));
+ edited_theme->set_font_size(E->get(), edited_type, Theme::get_default()->get_font_size(E->get(), default_type));
}
}
}
{
names.clear();
- Theme::get_default()->get_color_list(edited_type, &names);
+ Theme::get_default()->get_color_list(default_type, &names);
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
if (!edited_theme->has_color(E->get(), edited_type)) {
- edited_theme->set_color(E->get(), edited_type, Theme::get_default()->get_color(E->get(), edited_type));
+ edited_theme->set_color(E->get(), edited_type, Theme::get_default()->get_color(E->get(), default_type));
}
}
}
{
names.clear();
- Theme::get_default()->get_constant_list(edited_type, &names);
+ Theme::get_default()->get_constant_list(default_type, &names);
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
if (!edited_theme->has_constant(E->get(), edited_type)) {
- edited_theme->set_constant(E->get(), edited_type, Theme::get_default()->get_constant(E->get(), edited_type));
+ edited_theme->set_constant(E->get(), edited_type, Theme::get_default()->get_constant(E->get(), default_type));
}
}
}
@@ -2817,6 +2908,30 @@ void ThemeTypeEditor::_update_stylebox_from_leading() {
edited_theme->_unfreeze_and_propagate_changes();
}
+void ThemeTypeEditor::_type_variation_changed(const String p_value) {
+ if (p_value.is_empty()) {
+ edited_theme->clear_type_variation(edited_type);
+ } else {
+ edited_theme->set_type_variation(edited_type, StringName(p_value));
+ }
+}
+
+void ThemeTypeEditor::_add_type_variation_cbk() {
+ add_type_mode = ADD_VARIATION_BASE;
+ add_type_dialog->set_title(TTR("Add Variation Base Type"));
+ add_type_dialog->set_include_own_types(true);
+ add_type_dialog->popup_centered(Size2(560, 420) * EDSCALE);
+}
+
+void ThemeTypeEditor::_add_type_dialog_selected(const String p_type_name) {
+ if (add_type_mode == ADD_THEME_TYPE) {
+ select_type(p_type_name);
+ } else if (add_type_mode == ADD_VARIATION_BASE) {
+ _type_variation_changed(p_type_name);
+ _update_type_items();
+ }
+}
+
void ThemeTypeEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
@@ -2829,11 +2944,12 @@ void ThemeTypeEditor::_notification(int p_what) {
data_type_tabs->set_tab_icon(3, get_theme_icon("FontSize", "EditorIcons"));
data_type_tabs->set_tab_icon(4, get_theme_icon("ImageTexture", "EditorIcons"));
data_type_tabs->set_tab_icon(5, get_theme_icon("StyleBoxFlat", "EditorIcons"));
+ data_type_tabs->set_tab_icon(6, get_theme_icon("Tools", "EditorIcons"));
data_type_tabs->add_theme_style_override("tab_selected", get_theme_stylebox("tab_selected_odd", "TabContainer"));
data_type_tabs->add_theme_style_override("panel", get_theme_stylebox("panel_odd", "TabContainer"));
- _update_add_type_options();
+ type_variation_button->set_icon(get_theme_icon("Add", "EditorIcons"));
} break;
}
}
@@ -2846,6 +2962,8 @@ void ThemeTypeEditor::set_edited_theme(const Ref<Theme> &p_theme) {
edited_theme = p_theme;
edited_theme->connect("changed", callable_mp(this, &ThemeTypeEditor::_update_type_list_debounced));
_update_type_list();
+
+ add_type_dialog->set_edited_theme(edited_theme);
}
void ThemeTypeEditor::select_type(String p_type_name) {
@@ -2892,34 +3010,10 @@ ThemeTypeEditor::ThemeTypeEditor() {
theme_type_list->connect("item_selected", callable_mp(this, &ThemeTypeEditor::_list_type_selected));
add_type_button = memnew(Button);
- add_type_button->set_tooltip(TTR("Add Type"));
+ add_type_button->set_tooltip(TTR("Add a type from a list of available types or create a new one."));
type_list_hb->add_child(add_type_button);
add_type_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_add_type_button_cbk));
- add_type_dialog = memnew(ConfirmationDialog);
- add_type_dialog->set_title(TTR("Add Item Type"));
- type_list_hb->add_child(add_type_dialog);
- add_type_dialog->connect("confirmed", callable_mp(this, &ThemeTypeEditor::_add_type_dialog_confirmed));
-
- VBoxContainer *add_type_vb = memnew(VBoxContainer);
- add_type_dialog->add_child(add_type_vb);
-
- Label *add_type_filter_label = memnew(Label);
- add_type_filter_label->set_text(TTR("Name:"));
- add_type_vb->add_child(add_type_filter_label);
- add_type_filter = memnew(LineEdit);
- add_type_vb->add_child(add_type_filter);
- add_type_filter->connect("text_changed", callable_mp(this, &ThemeTypeEditor::_add_type_filter_cbk));
- add_type_filter->connect("text_submitted", callable_mp(this, &ThemeTypeEditor::_add_type_dialog_entered));
- Label *add_type_options_label = memnew(Label);
- add_type_options_label->set_text(TTR("Node Types:"));
- add_type_vb->add_child(add_type_options_label);
- add_type_options = memnew(ItemList);
- add_type_options->set_v_size_flags(SIZE_EXPAND_FILL);
- add_type_vb->add_child(add_type_options);
- add_type_options->connect("item_selected", callable_mp(this, &ThemeTypeEditor::_add_type_options_cbk));
- add_type_options->connect("item_activated", callable_mp(this, &ThemeTypeEditor::_add_type_dialog_activated));
-
HBoxContainer *type_controls = memnew(HBoxContainer);
main_vb->add_child(type_controls);
@@ -2950,6 +3044,39 @@ ThemeTypeEditor::ThemeTypeEditor() {
icon_items_list = _create_item_list(Theme::DATA_TYPE_ICON);
stylebox_items_list = _create_item_list(Theme::DATA_TYPE_STYLEBOX);
+ VBoxContainer *type_settings_tab = memnew(VBoxContainer);
+ type_settings_tab->set_custom_minimum_size(Size2(0, 160) * EDSCALE);
+ data_type_tabs->add_child(type_settings_tab);
+ data_type_tabs->set_tab_title(data_type_tabs->get_tab_count() - 1, "");
+
+ ScrollContainer *type_settings_sc = memnew(ScrollContainer);
+ type_settings_sc->set_v_size_flags(SIZE_EXPAND_FILL);
+ type_settings_sc->set_enable_h_scroll(false);
+ type_settings_tab->add_child(type_settings_sc);
+ VBoxContainer *type_settings_list = memnew(VBoxContainer);
+ type_settings_list->set_h_size_flags(SIZE_EXPAND_FILL);
+ type_settings_sc->add_child(type_settings_list);
+
+ HBoxContainer *type_variation_hb = memnew(HBoxContainer);
+ type_settings_list->add_child(type_variation_hb);
+ Label *type_variation_label = memnew(Label);
+ type_variation_hb->add_child(type_variation_label);
+ type_variation_label->set_text(TTR("Base Type"));
+ type_variation_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ type_variation_edit = memnew(LineEdit);
+ type_variation_hb->add_child(type_variation_edit);
+ type_variation_edit->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ type_variation_edit->connect("text_changed", callable_mp(this, &ThemeTypeEditor::_type_variation_changed));
+ type_variation_edit->connect("focus_exited", callable_mp(this, &ThemeTypeEditor::_update_type_items));
+ type_variation_button = memnew(Button);
+ type_variation_hb->add_child(type_variation_button);
+ type_variation_button->set_tooltip(TTR("Select the variation base type from a list of available types."));
+ type_variation_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_add_type_variation_cbk));
+
+ add_type_dialog = memnew(ThemeTypeDialog);
+ add_child(add_type_dialog);
+ add_type_dialog->connect("type_selected", callable_mp(this, &ThemeTypeEditor::_add_type_dialog_selected));
+
update_debounce_timer = memnew(Timer);
update_debounce_timer->set_one_shot(true);
update_debounce_timer->set_wait_time(0.5);
@@ -3094,6 +3221,7 @@ ThemeEditor::ThemeEditor() {
theme_name = memnew(Label);
theme_name->set_text(TTR("Theme") + ": ");
+ theme_name->set_theme_type_variation("HeaderSmall");
top_menu->add_child(theme_name);
top_menu->add_spacer(false);
diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h
index cdedbbec8d..3c114a375a 100644
--- a/editor/plugins/theme_editor_plugin.h
+++ b/editor/plugins/theme_editor_plugin.h
@@ -263,6 +263,36 @@ public:
ThemeItemEditorDialog();
};
+class ThemeTypeDialog : public ConfirmationDialog {
+ GDCLASS(ThemeTypeDialog, ConfirmationDialog);
+
+ Ref<Theme> edited_theme;
+ bool include_own_types = false;
+
+ LineEdit *add_type_filter;
+ ItemList *add_type_options;
+
+ void _dialog_about_to_show();
+ void ok_pressed() override;
+
+ void _update_add_type_options(const String &p_filter = "");
+
+ void _add_type_filter_cbk(const String &p_value);
+ void _add_type_options_cbk(int p_index);
+ void _add_type_dialog_entered(const String &p_value);
+ void _add_type_dialog_activated(int p_index);
+
+protected:
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+ void set_edited_theme(const Ref<Theme> &p_theme);
+ void set_include_own_types(bool p_enable);
+
+ ThemeTypeDialog();
+};
+
class ThemeTypeEditor : public MarginContainer {
GDCLASS(ThemeTypeEditor, MarginContainer);
@@ -281,9 +311,6 @@ class ThemeTypeEditor : public MarginContainer {
OptionButton *theme_type_list;
Button *add_type_button;
- ConfirmationDialog *add_type_dialog;
- LineEdit *add_type_filter;
- ItemList *add_type_options;
CheckButton *show_default_items_button;
@@ -295,13 +322,23 @@ class ThemeTypeEditor : public MarginContainer {
VBoxContainer *icon_items_list;
VBoxContainer *stylebox_items_list;
+ LineEdit *type_variation_edit;
+ Button *type_variation_button;
+
+ enum TypeDialogMode {
+ ADD_THEME_TYPE,
+ ADD_VARIATION_BASE,
+ };
+
+ TypeDialogMode add_type_mode = ADD_THEME_TYPE;
+ ThemeTypeDialog *add_type_dialog;
+
Vector<Control *> focusables;
Timer *update_debounce_timer;
VBoxContainer *_create_item_list(Theme::DataType p_data_type);
void _update_type_list();
void _update_type_list_debounced();
- void _update_add_type_options(const String &p_filter = "");
OrderedHashMap<StringName, bool> _get_type_items(String p_type_name, void (Theme::*get_list_func)(StringName, List<StringName> *) const, bool include_default);
HBoxContainer *_create_property_control(Theme::DataType p_data_type, String p_item_name, bool p_editable);
void _add_focusable(Control *p_control);
@@ -310,11 +347,6 @@ class ThemeTypeEditor : public MarginContainer {
void _list_type_selected(int p_index);
void _select_type(String p_type_name);
void _add_type_button_cbk();
- void _add_type_filter_cbk(const String &p_value);
- void _add_type_options_cbk(int p_index);
- void _add_type_dialog_confirmed();
- void _add_type_dialog_entered(const String &p_value);
- void _add_type_dialog_activated(int p_index);
void _add_default_type_items();
void _item_add_cbk(int p_data_type, Control *p_control);
@@ -337,6 +369,11 @@ class ThemeTypeEditor : public MarginContainer {
void _unpin_leading_stylebox();
void _update_stylebox_from_leading();
+ void _type_variation_changed(const String p_value);
+ void _add_type_variation_cbk();
+
+ void _add_type_dialog_selected(const String p_type_name);
+
protected:
void _notification(int p_what);
diff --git a/editor/plugins/theme_editor_preview.cpp b/editor/plugins/theme_editor_preview.cpp
index 0b02150444..5ea46771ba 100644
--- a/editor/plugins/theme_editor_preview.cpp
+++ b/editor/plugins/theme_editor_preview.cpp
@@ -123,7 +123,7 @@ void ThemeEditorPreview::_gui_input_picker_overlay(const Ref<InputEvent> &p_even
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
if (hovered_control) {
- StringName theme_type = hovered_control->get_theme_custom_type();
+ StringName theme_type = hovered_control->get_theme_type_variation();
if (theme_type == StringName()) {
theme_type = hovered_control->get_class_name();
}
diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp
index 75a944e910..10679ad6f2 100644
--- a/editor/plugins/version_control_editor_plugin.cpp
+++ b/editor/plugins/version_control_editor_plugin.cpp
@@ -476,6 +476,7 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() {
version_control_dock = memnew(PanelContainer);
version_control_dock->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ version_control_dock->set_custom_minimum_size(Size2(0, 300) * EDSCALE);
version_control_dock->hide();
diff_vbc = memnew(VBoxContainer);
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 94863bf722..f438d9bab8 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -110,6 +110,7 @@ void VisualShaderGraphPlugin::_bind_methods() {
ClassDB::bind_method("set_uniform_name", &VisualShaderGraphPlugin::set_uniform_name);
ClassDB::bind_method("set_expression", &VisualShaderGraphPlugin::set_expression);
ClassDB::bind_method("update_curve", &VisualShaderGraphPlugin::update_curve);
+ ClassDB::bind_method("update_curve3", &VisualShaderGraphPlugin::update_curve3);
ClassDB::bind_method("update_constant", &VisualShaderGraphPlugin::update_constant);
}
@@ -211,9 +212,19 @@ void VisualShaderGraphPlugin::set_uniform_name(VisualShader::Type p_type, int p_
}
void VisualShaderGraphPlugin::update_curve(int p_node_id) {
- if (links.has(p_node_id) && links[p_node_id].curve_editor) {
+ if (links.has(p_node_id) && links[p_node_id].curve_editors[0]) {
if (((VisualShaderNodeCurveTexture *)links[p_node_id].visual_node)->get_texture().is_valid()) {
- links[p_node_id].curve_editor->set_curve(((VisualShaderNodeCurveTexture *)links[p_node_id].visual_node)->get_texture()->get_curve());
+ links[p_node_id].curve_editors[0]->set_curve(((VisualShaderNodeCurveTexture *)links[p_node_id].visual_node)->get_texture()->get_curve());
+ }
+ }
+}
+
+void VisualShaderGraphPlugin::update_curve3(int p_node_id) {
+ if (links.has(p_node_id) && links[p_node_id].curve_editors[0] && links[p_node_id].curve_editors[1] && links[p_node_id].curve_editors[2]) {
+ if (((VisualShaderNodeCurve3Texture *)links[p_node_id].visual_node)->get_texture().is_valid()) {
+ links[p_node_id].curve_editors[0]->set_curve(((VisualShaderNodeCurve3Texture *)links[p_node_id].visual_node)->get_texture()->get_curve_x());
+ links[p_node_id].curve_editors[1]->set_curve(((VisualShaderNodeCurve3Texture *)links[p_node_id].visual_node)->get_texture()->get_curve_y());
+ links[p_node_id].curve_editors[2]->set_curve(((VisualShaderNodeCurve3Texture *)links[p_node_id].visual_node)->get_texture()->get_curve_z());
}
}
}
@@ -265,8 +276,8 @@ void VisualShaderGraphPlugin::register_expression_edit(int p_node_id, CodeEdit *
links[p_node_id].expression_edit = p_expression_edit;
}
-void VisualShaderGraphPlugin::register_curve_editor(int p_node_id, CurveEditor *p_curve_editor) {
- links[p_node_id].curve_editor = p_curve_editor;
+void VisualShaderGraphPlugin::register_curve_editor(int p_node_id, int p_index, CurveEditor *p_curve_editor) {
+ links[p_node_id].curve_editors[p_index] = p_curve_editor;
}
void VisualShaderGraphPlugin::update_uniform_refs() {
@@ -312,7 +323,7 @@ void VisualShaderGraphPlugin::make_dirty(bool p_enabled) {
}
void VisualShaderGraphPlugin::register_link(VisualShader::Type p_type, int p_id, VisualShaderNode *p_visual_node, GraphNode *p_graph_node) {
- links.insert(p_id, { p_type, p_visual_node, p_graph_node, p_visual_node->get_output_port_for_preview() != -1, -1, Map<int, InputPort>(), Map<int, Port>(), nullptr, nullptr, nullptr, nullptr, nullptr });
+ links.insert(p_id, { p_type, p_visual_node, p_graph_node, p_visual_node->get_output_port_for_preview() != -1, -1, Map<int, InputPort>(), Map<int, Port>(), nullptr, nullptr, nullptr, nullptr, { nullptr, nullptr, nullptr } });
}
void VisualShaderGraphPlugin::register_output_port(int p_node_id, int p_port, TextureButton *p_button) {
@@ -472,6 +483,18 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
custom_editor = hbox;
}
+ Ref<VisualShaderNodeCurve3Texture> curve3 = vsnode;
+ if (curve3.is_valid()) {
+ if (curve3->get_texture().is_valid() && !curve3->get_texture()->is_connected("changed", callable_mp(VisualShaderEditor::get_singleton()->get_graph_plugin(), &VisualShaderGraphPlugin::update_curve3))) {
+ curve3->get_texture()->connect("changed", callable_mp(VisualShaderEditor::get_singleton()->get_graph_plugin(), &VisualShaderGraphPlugin::update_curve3), varray(p_id));
+ }
+
+ HBoxContainer *hbox = memnew(HBoxContainer);
+ custom_editor->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ hbox->add_child(custom_editor);
+ custom_editor = hbox;
+ }
+
Ref<VisualShaderNodeFloatConstant> float_const = vsnode;
if (float_const.is_valid()) {
HBoxContainer *hbox = memnew(HBoxContainer);
@@ -495,19 +518,12 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
port_offset++;
node->add_child(custom_editor);
- if (curve.is_valid()) {
+ bool is_curve = curve.is_valid() || curve3.is_valid();
+
+ if (is_curve) {
VisualShaderEditor::get_singleton()->graph->add_child(node);
VisualShaderEditor::get_singleton()->_update_created_node(node);
- CurveEditor *curve_editor = memnew(CurveEditor);
- node->add_child(curve_editor);
- register_curve_editor(p_id, curve_editor);
- curve_editor->set_custom_minimum_size(Size2(300, 0));
- curve_editor->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- if (curve->get_texture().is_valid()) {
- curve_editor->set_curve(curve->get_texture()->get_curve());
- }
-
TextureButton *preview = memnew(TextureButton);
preview->set_toggle_mode(true);
preview->set_normal_texture(VisualShaderEditor::get_singleton()->get_theme_icon("GuiVisibilityHidden", "EditorIcons"));
@@ -519,12 +535,59 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
preview->connect("pressed", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_preview_select_port), varray(p_id, 0), CONNECT_DEFERRED);
custom_editor->add_child(preview);
+ if (vsnode->get_output_port_for_preview() >= 0) {
+ show_port_preview(p_type, p_id, vsnode->get_output_port_for_preview());
+ }
+ }
+
+ if (curve.is_valid()) {
+ CurveEditor *curve_editor = memnew(CurveEditor);
+ node->add_child(curve_editor);
+ register_curve_editor(p_id, 0, curve_editor);
+ curve_editor->set_custom_minimum_size(Size2(300, 0));
+ curve_editor->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ if (curve->get_texture().is_valid()) {
+ curve_editor->set_curve(curve->get_texture()->get_curve());
+ }
+ }
+
+ if (curve3.is_valid()) {
+ CurveEditor *curve_editor_x = memnew(CurveEditor);
+ node->add_child(curve_editor_x);
+ register_curve_editor(p_id, 0, curve_editor_x);
+ curve_editor_x->set_custom_minimum_size(Size2(300, 0));
+ curve_editor_x->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ if (curve3->get_texture().is_valid()) {
+ curve_editor_x->set_curve(curve3->get_texture()->get_curve_x());
+ }
+
+ CurveEditor *curve_editor_y = memnew(CurveEditor);
+ node->add_child(curve_editor_y);
+ register_curve_editor(p_id, 1, curve_editor_y);
+ curve_editor_y->set_custom_minimum_size(Size2(300, 0));
+ curve_editor_y->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ if (curve3->get_texture().is_valid()) {
+ curve_editor_y->set_curve(curve3->get_texture()->get_curve_y());
+ }
+
+ CurveEditor *curve_editor_z = memnew(CurveEditor);
+ node->add_child(curve_editor_z);
+ register_curve_editor(p_id, 2, curve_editor_z);
+ curve_editor_z->set_custom_minimum_size(Size2(300, 0));
+ curve_editor_z->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ if (curve3->get_texture().is_valid()) {
+ curve_editor_z->set_curve(curve3->get_texture()->get_curve_z());
+ }
+ }
+
+ if (is_curve) {
VisualShaderNode::PortType port_left = vsnode->get_input_port_type(0);
VisualShaderNode::PortType port_right = vsnode->get_output_port_type(0);
node->set_slot(0, true, port_left, type_color[port_left], true, port_right, type_color[port_right]);
VisualShaderEditor::get_singleton()->call_deferred("_set_node_size", (int)p_type, p_id, size);
}
+
if (vsnode->is_use_prop_slots()) {
return;
}
@@ -2211,6 +2274,8 @@ void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) {
void VisualShaderEditor::_add_node(int p_idx, int p_op_idx, String p_resource_path, int p_node_idx) {
ERR_FAIL_INDEX(p_idx, add_options.size());
+ VisualShader::Type type = get_current_shader_type();
+
Ref<VisualShaderNode> vsnode;
bool is_custom = add_options[p_idx].is_custom;
@@ -2237,6 +2302,29 @@ void VisualShaderEditor::_add_node(int p_idx, int p_op_idx, String p_resource_pa
}
}
+ VisualShaderNodeUniformRef *uniform_ref = Object::cast_to<VisualShaderNodeUniformRef>(vsn);
+
+ if (uniform_ref && to_node != -1 && to_slot != -1) {
+ VisualShaderNode::PortType input_port_type = visual_shader->get_node(type, to_node)->get_input_port_type(to_slot);
+ bool success = false;
+
+ for (int i = 0; i < uniform_ref->get_uniforms_count(); i++) {
+ if (uniform_ref->get_port_type_by_index(i) == input_port_type) {
+ uniform_ref->set_uniform_name(uniform_ref->get_uniform_name_by_index(i));
+ success = true;
+ break;
+ }
+ }
+ if (!success) {
+ for (int i = 0; i < uniform_ref->get_uniforms_count(); i++) {
+ if (visual_shader->is_port_types_compatible(uniform_ref->get_port_type_by_index(i), input_port_type)) {
+ uniform_ref->set_uniform_name(uniform_ref->get_uniform_name_by_index(i));
+ break;
+ }
+ }
+ }
+ }
+
vsnode = Ref<VisualShaderNode>(vsn);
} else {
ERR_FAIL_COND(add_options[p_idx].script.is_null());
@@ -2257,8 +2345,6 @@ void VisualShaderEditor::_add_node(int p_idx, int p_op_idx, String p_resource_pa
}
saved_node_pos_dirty = false;
- VisualShader::Type type = get_current_shader_type();
-
int id_to_use = visual_shader->get_valid_node_id(type);
if (p_resource_path.is_empty()) {
@@ -2387,6 +2473,11 @@ void VisualShaderEditor::_add_node(int p_idx, int p_op_idx, String p_resource_pa
graph_plugin->call_deferred("update_curve", id_to_use);
}
+ VisualShaderNodeCurve3Texture *curve3 = Object::cast_to<VisualShaderNodeCurve3Texture>(vsnode.ptr());
+ if (curve3) {
+ graph_plugin->call_deferred("update_curve3", id_to_use);
+ }
+
if (p_resource_path.is_empty()) {
undo_redo->commit_action();
} else {
@@ -2395,7 +2486,7 @@ void VisualShaderEditor::_add_node(int p_idx, int p_op_idx, String p_resource_pa
VisualShaderNodeTexture *texture2d = Object::cast_to<VisualShaderNodeTexture>(vsnode.ptr());
VisualShaderNodeTexture3D *texture3d = Object::cast_to<VisualShaderNodeTexture3D>(vsnode.ptr());
- if (texture2d || texture3d || curve) {
+ if (texture2d || texture3d || curve || curve3) {
undo_redo->add_do_method(vsnode.ptr(), "set_texture", ResourceLoader::load(p_resource_path));
return;
}
@@ -3590,6 +3681,10 @@ void VisualShaderEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
saved_node_pos = p_point + Vector2(0, i * 250 * EDSCALE);
saved_node_pos_dirty = true;
_add_node(curve_node_option_idx, -1, arr[i], i);
+ } else if (type == "Curve3Texture") {
+ saved_node_pos = p_point + Vector2(0, i * 250 * EDSCALE);
+ saved_node_pos_dirty = true;
+ _add_node(curve3_node_option_idx, -1, arr[i], i);
} else if (ClassDB::get_parent_class(type) == "Texture2D") {
saved_node_pos = p_point + Vector2(0, i * 250 * EDSCALE);
saved_node_pos_dirty = true;
@@ -3862,7 +3957,7 @@ VisualShaderEditor::VisualShaderEditor() {
error_label = memnew(Label);
error_panel->add_child(error_label);
- error_label->set_autowrap(true);
+ error_label->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART);
///////////////////////////////////////
// POPUP MENU
@@ -3948,7 +4043,7 @@ VisualShaderEditor::VisualShaderEditor() {
add_child(members_dialog);
alert = memnew(AcceptDialog);
- alert->get_label()->set_autowrap(true);
+ alert->get_label()->set_autowrap_mode(Label::AUTOWRAP_WORD);
alert->get_label()->set_align(Label::ALIGN_CENTER);
alert->get_label()->set_valign(Label::VALIGN_CENTER);
alert->get_label()->set_custom_minimum_size(Size2(400, 60) * EDSCALE);
@@ -4311,6 +4406,8 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("CubeMap", "Textures", "Functions", "VisualShaderNodeCubemap", TTR("Perform the cubic texture lookup."), -1, -1));
curve_node_option_idx = add_options.size();
add_options.push_back(AddOption("CurveTexture", "Textures", "Functions", "VisualShaderNodeCurveTexture", TTR("Perform the curve texture lookup."), -1, -1));
+ curve3_node_option_idx = add_options.size();
+ add_options.push_back(AddOption("CurveTexture3", "Textures", "Functions", "VisualShaderNodeCurve3Texture", TTR("Perform the ternary curve texture lookup."), -1, -1));
texture2d_node_option_idx = add_options.size();
add_options.push_back(AddOption("Texture2D", "Textures", "Functions", "VisualShaderNodeTexture", TTR("Perform the 2D texture lookup."), -1, -1));
texture2d_array_node_option_idx = add_options.size();
diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h
index d549a35306..2b354db7b3 100644
--- a/editor/plugins/visual_shader_editor_plugin.h
+++ b/editor/plugins/visual_shader_editor_plugin.h
@@ -75,7 +75,7 @@ private:
LineEdit *uniform_name = nullptr;
OptionButton *const_op = nullptr;
CodeEdit *expression_edit = nullptr;
- CurveEditor *curve_editor = nullptr;
+ CurveEditor *curve_editors[3] = { nullptr, nullptr, nullptr };
};
Ref<VisualShader> visual_shader;
@@ -97,7 +97,7 @@ public:
void register_default_input_button(int p_node_id, int p_port_id, Button *p_button);
void register_constant_option_btn(int p_node_id, OptionButton *p_button);
void register_expression_edit(int p_node_id, CodeEdit *p_expression_edit);
- void register_curve_editor(int p_node_id, CurveEditor *p_curve_editor);
+ void register_curve_editor(int p_node_id, int p_index, CurveEditor *p_curve_editor);
void clear_links();
void set_shader_type(VisualShader::Type p_type);
bool is_preview_visible(int p_id) const;
@@ -117,6 +117,7 @@ public:
void update_uniform_refs();
void set_uniform_name(VisualShader::Type p_type, int p_node_id, const String &p_name);
void update_curve(int p_node_id);
+ void update_curve3(int p_node_id);
void update_constant(VisualShader::Type p_type, int p_node_id);
void set_expression(VisualShader::Type p_type, int p_node_id, const String &p_expression);
int get_constant_index(float p_constant) const;
@@ -289,6 +290,7 @@ class VisualShaderEditor : public VBoxContainer {
int texture3d_node_option_idx;
int custom_node_option_idx;
int curve_node_option_idx;
+ int curve3_node_option_idx;
List<String> keyword_list;
List<VisualShaderNodeUniformRef> uniform_refs;
diff --git a/editor/project_export.cpp b/editor/project_export.cpp
index 75736a0723..b639a74132 100644
--- a/editor/project_export.cpp
+++ b/editor/project_export.cpp
@@ -64,6 +64,7 @@ void ProjectExportDialog::_notification(int p_what) {
duplicate_preset->set_icon(presets->get_theme_icon("Duplicate", "EditorIcons"));
delete_preset->set_icon(presets->get_theme_icon("Remove", "EditorIcons"));
connect("confirmed", callable_mp(this, &ProjectExportDialog::_export_pck_zip));
+ _update_export_all();
} break;
}
}
@@ -182,10 +183,12 @@ void ProjectExportDialog::_update_export_all() {
}
}
+ export_all_button->set_disabled(!can_export);
+
if (can_export) {
- export_all_button->set_disabled(false);
+ export_all_button->set_tooltip(TTR("Export the project for all the presets defined."));
} else {
- export_all_button->set_disabled(true);
+ export_all_button->set_tooltip(TTR("All presets must have an export path defined for Export All to work."));
}
}
@@ -433,6 +436,7 @@ void ProjectExportDialog::_export_path_changed(const StringName &p_property, con
current->set_export_path(p_value);
_update_presets();
+ _update_export_all();
}
void ProjectExportDialog::_enc_filters_changed(const String &p_filters) {
@@ -589,6 +593,10 @@ void ProjectExportDialog::_delete_preset_confirm() {
get_ok_button()->set_disabled(true);
EditorExport::get_singleton()->remove_export_preset(idx);
_update_presets();
+
+ // The Export All button might become enabled (if all other presets have an export path defined),
+ // or it could be disabled (if there are no presets anymore).
+ _update_export_all();
}
Variant ProjectExportDialog::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
@@ -1005,8 +1013,11 @@ ProjectExportDialog::ProjectExportDialog() {
preset_vb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
hbox->add_child(preset_vb);
+ Label *l = memnew(Label(TTR("Presets")));
+ l->set_theme_type_variation("HeaderSmall");
+
HBoxContainer *preset_hb = memnew(HBoxContainer);
- preset_hb->add_child(memnew(Label(TTR("Presets"))));
+ preset_hb->add_child(l);
preset_hb->add_spacer();
preset_vb->add_child(preset_hb);
@@ -1199,8 +1210,8 @@ ProjectExportDialog::ProjectExportDialog() {
updating = false;
get_cancel_button()->set_text(TTR("Close"));
- get_ok_button()->set_text(TTR("Export PCK/Zip"));
- export_button = add_button(TTR("Export Project"), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "export");
+ get_ok_button()->set_text(TTR("Export PCK/ZIP..."));
+ export_button = add_button(TTR("Export Project..."), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "export");
export_button->connect("pressed", callable_mp(this, &ProjectExportDialog::_export_project));
// Disable initially before we select a valid preset
export_button->set_disabled(true);
@@ -1209,19 +1220,19 @@ ProjectExportDialog::ProjectExportDialog() {
export_all_dialog = memnew(ConfirmationDialog);
add_child(export_all_dialog);
export_all_dialog->set_title("Export All");
- export_all_dialog->set_text(TTR("Export mode?"));
+ export_all_dialog->set_text(TTR("Choose an export mode:"));
export_all_dialog->get_ok_button()->hide();
export_all_dialog->add_button(TTR("Debug"), true, "debug");
export_all_dialog->add_button(TTR("Release"), true, "release");
export_all_dialog->connect("custom_action", callable_mp(this, &ProjectExportDialog::_export_all_dialog_action));
- export_all_button = add_button(TTR("Export All"), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "export");
+ export_all_button = add_button(TTR("Export All..."), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "export");
export_all_button->connect("pressed", callable_mp(this, &ProjectExportDialog::_export_all_dialog));
export_all_button->set_disabled(true);
export_pck_zip = memnew(EditorFileDialog);
export_pck_zip->add_filter("*.zip ; " + TTR("ZIP File"));
- export_pck_zip->add_filter("*.pck ; " + TTR("Godot Game Pack"));
+ export_pck_zip->add_filter("*.pck ; " + TTR("Godot Project Pack"));
export_pck_zip->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
export_pck_zip->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
add_child(export_pck_zip);
@@ -1282,8 +1293,6 @@ ProjectExportDialog::ProjectExportDialog() {
default_filename = "UnnamedProject";
}
}
-
- _update_export_all();
}
ProjectExportDialog::~ProjectExportDialog() {
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index 7414c2d8e6..ab710a1c21 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -975,7 +975,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
}
for (int i = 0; i < conversions.size(); i++) {
String what = conversions[i]->converts_to();
- menu->add_item(vformat(TTR("Convert To %s"), what), CONVERT_BASE_ID + i);
+ menu->add_item(vformat(TTR("Convert to %s"), what), CONVERT_BASE_ID + i);
}
}
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 3f66f1f375..166b82d744 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -1206,14 +1206,13 @@ void SceneTreeDock::_notification(int p_what) {
filter->set_right_icon(get_theme_icon("Search", "EditorIcons"));
filter->set_clear_button_enabled(true);
- EditorNode::get_singleton()->get_editor_selection()->connect("selection_changed", callable_mp(this, &SceneTreeDock::_selection_changed));
- scene_tree->get_scene_tree()->connect("item_collapsed", callable_mp(this, &SceneTreeDock::_node_collapsed));
-
// create_root_dialog
HBoxContainer *top_row = memnew(HBoxContainer);
top_row->set_name("NodeShortcutsTopRow");
top_row->set_h_size_flags(SIZE_EXPAND_FILL);
- top_row->add_child(memnew(Label(TTR("Create Root Node:"))));
+ Label *l = memnew(Label(TTR("Create Root Node:")));
+ l->set_theme_type_variation("HeaderSmall");
+ top_row->add_child(l);
top_row->add_spacer();
Button *node_shortcuts_toggle = memnew(Button);
@@ -3216,6 +3215,9 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
scene_tree->connect("nodes_dragged", callable_mp(this, &SceneTreeDock::_nodes_drag_begin));
scene_tree->get_scene_tree()->connect("item_double_clicked", callable_mp(this, &SceneTreeDock::_focus_node));
+ scene_tree->get_scene_tree()->connect("item_collapsed", callable_mp(this, &SceneTreeDock::_node_collapsed));
+
+ editor_selection->connect("selection_changed", callable_mp(this, &SceneTreeDock::_selection_changed));
scene_tree->set_undo_redo(&editor_data->get_undo_redo());
scene_tree->set_editor_selection(editor_selection);
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp
index 3aa04e4dc3..b2c66ee1e7 100644
--- a/editor/scene_tree_editor.cpp
+++ b/editor/scene_tree_editor.cpp
@@ -659,7 +659,14 @@ void SceneTreeEditor::_cell_multi_selected(Object *p_object, int p_cell, bool p_
} else {
editor_selection->remove_node(n);
}
- emit_signal("node_changed");
+
+ // Selection changed to be single node, so emit "selected" (for single node) rather than "changed" (for multiple nodes)
+ if (editor_selection->get_selected_nodes().size() == 1) {
+ selected = editor_selection->get_selected_node_list()[0];
+ emit_signal("node_selected");
+ } else {
+ emit_signal("node_changed");
+ }
}
void SceneTreeEditor::_notification(int p_what) {
@@ -1165,6 +1172,7 @@ SceneTreeEditor::SceneTreeEditor(bool p_label, bool p_can_rename, bool p_can_ope
if (p_label) {
Label *label = memnew(Label);
+ label->set_theme_type_variation("HeaderSmall");
label->set_position(Point2(10, 0));
label->set_text(TTR("Scene Tree (Nodes):"));
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index 97edf84488..b5028096e0 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -764,7 +764,7 @@ ScriptCreateDialog::ScriptCreateDialog() {
builtin_warning_label->set_text(
TTR("Note: Built-in scripts have some limitations and can't be edited using an external editor."));
vb->add_child(builtin_warning_label);
- builtin_warning_label->set_autowrap(true);
+ builtin_warning_label->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART);
builtin_warning_label->hide();
script_name_warning_label = memnew(Label);
@@ -772,7 +772,7 @@ ScriptCreateDialog::ScriptCreateDialog() {
TTR("Warning: Having the script name be the same as a built-in type is usually not desired."));
vb->add_child(script_name_warning_label);
script_name_warning_label->add_theme_color_override("font_color", Color(1, 0.85, 0.4));
- script_name_warning_label->set_autowrap(true);
+ script_name_warning_label->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART);
script_name_warning_label->hide();
status_panel = memnew(PanelContainer);
@@ -884,7 +884,7 @@ ScriptCreateDialog::ScriptCreateDialog() {
add_child(file_browse);
get_ok_button()->set_text(TTR("Create"));
alert = memnew(AcceptDialog);
- alert->get_label()->set_autowrap(true);
+ alert->get_label()->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART);
alert->get_label()->set_align(Label::ALIGN_CENTER);
alert->get_label()->set_valign(Label::VALIGN_CENTER);
alert->get_label()->set_custom_minimum_size(Size2(325, 60) * EDSCALE);
diff --git a/editor/translations/af.po b/editor/translations/af.po
index 40669c01fb..bb7e7ca553 100644
--- a/editor/translations/af.po
+++ b/editor/translations/af.po
@@ -420,10 +420,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr ""
@@ -472,7 +468,8 @@ msgid "Anim Move Keys"
msgstr "Anim Skuif Sleutels"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
msgstr ""
#: editor/animation_track_editor.cpp
@@ -2557,7 +2554,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11989,10 +11986,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
diff --git a/editor/translations/ar.po b/editor/translations/ar.po
index ceeda7a037..6d8db6f47b 100644
--- a/editor/translations/ar.po
+++ b/editor/translations/ar.po
@@ -51,12 +51,13 @@
# Kareem Abduljaleel <karemjaleel34@gmail.com>, 2021.
# ILG - Game <moegypt277@gmail.com>, 2021.
# Hatim Jamal <hatimjamal8@gmail.com>, 2021.
+# HASSAN GAMER - حسن جيمر <gamerhassan55@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-05-07 02:12+0000\n"
-"Last-Translator: ILG - Game <moegypt277@gmail.com>\n"
+"PO-Revision-Date: 2021-07-09 14:32+0000\n"
+"Last-Translator: HASSAN GAMER - حسن جيمر <gamerhassan55@gmail.com>\n"
"Language-Team: Arabic <https://hosted.weblate.org/projects/godot-engine/"
"godot/ar/>\n"
"Language: ar\n"
@@ -65,7 +66,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
-"X-Generator: Weblate 4.7-dev\n"
+"X-Generator: Weblate 4.8-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -88,7 +89,7 @@ msgstr "مدخلات خاطئة %i (لم يتم تمريره) ÙÙŠ التعبيØ
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
-msgstr "لا يمكن إستخدامه Ù†Ùسه لأن الحالة Ùارغة (لم ÙŠÙمرر)"
+msgstr "لا يمكن استخدام self لأن النموذج Ùارغ (لم يتم ادخاله)"
#: core/math/expression.cpp
msgid "Invalid operands to operator %s, %s and %s."
@@ -455,10 +456,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "مسارات الحركة يمكنها Ùقط أن تشير إلى عÙقد مشغّل الحركة."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr "مشغل الحركة لا يمكنه أن يحرك Ù†Ùسه, Ùقط الاعبين الأخرين."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "لا يمكن إضاÙØ© مقطع جديد بدون جذر"
@@ -503,8 +500,9 @@ msgid "Anim Move Keys"
msgstr "Ù…Ùتاح حركة التحريك"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "الحاÙظة (Clipboard) Ùارغة"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "الحاÙظة Ùارغة!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -1156,7 +1154,7 @@ msgstr "شكراً من مجتمع غودوت!"
#: editor/editor_about.cpp editor/editor_node.cpp editor/project_manager.cpp
msgid "Click to copy."
-msgstr ""
+msgstr "انقر للنسخ"
#: editor/editor_about.cpp
msgid "Godot Engine contributors"
@@ -2531,7 +2529,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "هل تريد Ø­Ùظ التغييرات للمشاهد التالية قبل الخروج؟"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
"هل تود Ø­Ùظ التغييرات التي اجريت على المشاهد الحالية قبل Ùتح ناÙذة ادارة "
"المشروع؟"
@@ -11996,10 +11994,6 @@ msgid "Can't copy the function node."
msgstr "لا يمكن نسخ الوظيÙØ© البرمجية للعÙقدة."
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "الحاÙظة Ùارغة!"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "لصق عÙقد البرمجة البصرية VisualScript"
@@ -13198,6 +13192,12 @@ msgstr "يمكن تعيين المتغيرات Ùقط ÙÙŠ الذروة ."
msgid "Constants cannot be modified."
msgstr "لا يمكن تعديل الثوابت."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr "مشغل الحركة لا يمكنه أن يحرك Ù†Ùسه, Ùقط الاعبين الأخرين."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "الحاÙظة (Clipboard) Ùارغة"
+
#~ msgid "No"
#~ msgstr "لا"
diff --git a/editor/translations/az.po b/editor/translations/az.po
index 32efc852f8..054bc9263d 100644
--- a/editor/translations/az.po
+++ b/editor/translations/az.po
@@ -433,11 +433,6 @@ msgstr ""
"Animasiya parçaları yalnız AnimationPlayer düyünlərini işarə edə bilər."
#: editor/animation_track_editor.cpp
-#, fuzzy
-msgid "An animation player can't animate itself, only other players."
-msgstr "Animasiya pleyeri özünü canlandıra bilməz, yalnız digər pleyerlər."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Kök olmadan yeni iz əlavə etmək mümkün deyil"
@@ -483,8 +478,9 @@ msgid "Anim Move Keys"
msgstr "Animasya Köçürmə Açarları"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Panel(Clipboard) boÅŸdur"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr ""
#: editor/animation_track_editor.cpp
#, fuzzy
@@ -2480,7 +2476,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11552,10 +11548,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
@@ -12576,3 +12568,10 @@ msgstr ""
#: servers/visual/shader_language.cpp
msgid "Constants cannot be modified."
msgstr ""
+
+#, fuzzy
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr "Animasiya pleyeri özünü canlandıra bilməz, yalnız digər pleyerlər."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Panel(Clipboard) boÅŸdur"
diff --git a/editor/translations/bg.po b/editor/translations/bg.po
index 65a77ffd74..7bf3d40805 100644
--- a/editor/translations/bg.po
+++ b/editor/translations/bg.po
@@ -415,10 +415,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr ""
@@ -463,7 +459,8 @@ msgid "Anim Move Keys"
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
msgstr ""
#: editor/animation_track_editor.cpp
@@ -2424,7 +2421,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11603,10 +11600,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "ПоÑтавÑне на възлите Ñ VisualScript"
diff --git a/editor/translations/bn.po b/editor/translations/bn.po
index 999d6f59d5..70a66820fb 100644
--- a/editor/translations/bn.po
+++ b/editor/translations/bn.po
@@ -415,10 +415,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ টà§à¦°à§à¦¯à¦¾à¦•à¦—à§à¦²à¦¿ কেবল অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à¦ªà§à¦²à§‡à¦¯à¦¼à¦¾à¦° নোডগà§à¦²à¦¿à¦¤à§‡ নিরà§à¦¦à§‡à¦¶ করতে পারে।"
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr "à¦à¦•à¦Ÿà¦¿ অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ পà§à¦²à§‡à¦¯à¦¼à¦¾à¦° নিজেই অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦Ÿ করতে পারে না, কেবল অনà§à¦¯ পà§à¦²à§‡à§Ÿà¦¾à¦°à¥¤"
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "মূল ছাড়া নতà§à¦¨ টà§à¦°à§à¦¯à¦¾à¦• যà§à¦•à§à¦¤ করা সমà§à¦­à¦¬ নয়"
@@ -463,8 +459,10 @@ msgid "Anim Move Keys"
msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à§‡ (Anim) চাবি/কী-সমà§à¦¹ সরান"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "কà§à¦²à§€à¦ªà¦¬à§‹à¦°à§à¦¡ খালি"
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Clipboard is empty!"
+msgstr "রিসোরà§à¦¸à§‡à¦° কà§à¦²à§€à¦ªà¦¬à§‹à¦°à§à¦¡ খালি!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2609,7 +2607,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "বনà§à¦§ করার পূরà§à¦¬à§‡ পরিবরà§à¦¤à¦¨à¦¸à¦®à§‚হ (সিন) সংরকà§à¦·à¦£ করবেন?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr "পà§à¦°à¦œà§‡à¦•à§à¦Ÿ মà§à¦¯à¦¾à¦¨à§‡à¦œà¦¾à¦° ওপেন করার পূরà§à¦¬à§‡ পরিবরà§à¦¤à¦¨à¦¸à¦®à§‚হ (সিন) সংরকà§à¦·à¦£ করবেন?"
#: editor/editor_node.cpp
@@ -12737,11 +12735,6 @@ msgstr "'..' তে পরিচালনা করা সমà§à¦­à¦¬ নয়"
#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
-msgid "Clipboard is empty!"
-msgstr "রিসোরà§à¦¸à§‡à¦° কà§à¦²à§€à¦ªà¦¬à§‹à¦°à§à¦¡ খালি!"
-
-#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Paste VisualScript Nodes"
msgstr "নোড-সমূহ পà§à¦°à¦¤à¦¿à¦²à§‡à¦ªà¦¨/পেসà§à¦Ÿ করà§à¦¨"
@@ -13863,6 +13856,12 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr "à¦à¦•à¦Ÿà¦¿ অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ পà§à¦²à§‡à¦¯à¦¼à¦¾à¦° নিজেই অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦Ÿ করতে পারে না, কেবল অনà§à¦¯ পà§à¦²à§‡à§Ÿà¦¾à¦°à¥¤"
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "কà§à¦²à§€à¦ªà¦¬à§‹à¦°à§à¦¡ খালি"
+
#, fuzzy
#~ msgid "No"
#~ msgstr "নোড"
diff --git a/editor/translations/br.po b/editor/translations/br.po
index 21e33b7372..9d1e52e009 100644
--- a/editor/translations/br.po
+++ b/editor/translations/br.po
@@ -414,12 +414,6 @@ msgstr ""
"Roudennoù Fiñvskeudenn a c'hell poentañ nemetken da skoulmoù AnimationPlayer."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-"Ul lennerezh fiñvskeudenn ne c'hell ket em lakaat da fiñval, nemet "
-"lennerezhioù all."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Dibosupl ouzhpenn ur roudenn nevez hep ur gwrizienn"
@@ -464,8 +458,9 @@ msgid "Anim Move Keys"
msgstr "Fiñval Alc'hwezioù Fiñvskeudenn"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Goullo ar gwask-paper"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr ""
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2425,7 +2420,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11497,10 +11492,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
@@ -12521,3 +12512,11 @@ msgstr ""
#: servers/visual/shader_language.cpp
msgid "Constants cannot be modified."
msgstr ""
+
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "Ul lennerezh fiñvskeudenn ne c'hell ket em lakaat da fiñval, nemet "
+#~ "lennerezhioù all."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Goullo ar gwask-paper"
diff --git a/editor/translations/ca.po b/editor/translations/ca.po
index e9dc4400fc..1032b7cdeb 100644
--- a/editor/translations/ca.po
+++ b/editor/translations/ca.po
@@ -421,12 +421,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Les pistes d'Animació només poden apuntar a nodes AnimationPlayer."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-"Un reproductor d'Animacions no pot animar-se a si mateix, només altres "
-"reproductors."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "No es pot afegir una nova pista sense cap arrel"
@@ -472,8 +466,9 @@ msgid "Anim Move Keys"
msgstr "Mou les Claus"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "El porta-retalls és buit"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "El porta-retalls és buit!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2525,7 +2520,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "Voleu Desar els canvis en les escenes següents abans de Sortir?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
"Desar els canvis a la(les) següent(s) escenes abans d'obrir el Gestor de "
"Projectes?"
@@ -12354,10 +12349,6 @@ msgid "Can't copy the function node."
msgstr "No es pot copiar el node de funció."
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "El porta-retalls és buit!"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "Enganxa els Nodes de VisualScript"
@@ -13567,6 +13558,14 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Les constants no es poden modificar."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "Un reproductor d'Animacions no pot animar-se a si mateix, només altres "
+#~ "reproductors."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "El porta-retalls és buit"
+
#~ msgid "No"
#~ msgstr "No"
diff --git a/editor/translations/cs.po b/editor/translations/cs.po
index 2557308828..3aaf91d758 100644
--- a/editor/translations/cs.po
+++ b/editor/translations/cs.po
@@ -431,10 +431,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Stopa animace může odkazovat pouze na uzly AnimationPlayer."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr "PÅ™ehrávaÄ animace nemůže animovat sám sebe, pouze ostatní pÅ™ehrávaÄe."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Není možné přidat novou stopu bez kořenového uzlu"
@@ -479,8 +475,9 @@ msgid "Anim Move Keys"
msgstr "Animace: pÅ™esunout klíÄe"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Schránka je prázdná"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "Schránka je prázdná!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2515,7 +2512,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "Uložit zmÄ›ny následujících scén pÅ™ed ukonÄením?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr "Uložit změny následujících scén před otevřením Správce projektu?"
#: editor/editor_node.cpp
@@ -11945,10 +11942,6 @@ msgid "Can't copy the function node."
msgstr "Nelze zkopírovat uzel funkce."
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "Schránka je prázdná!"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "Vložit VisualScript uzly"
@@ -13119,6 +13112,13 @@ msgstr "Odlišnosti mohou být přiřazeny pouze ve vertex funkci."
msgid "Constants cannot be modified."
msgstr "Konstanty není možné upravovat."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "PÅ™ehrávaÄ animace nemůže animovat sám sebe, pouze ostatní pÅ™ehrávaÄe."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Schránka je prázdná"
+
#~ msgid ""
#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
#~ msgstr "Uzel InterpolatedCamera je zastaralý a bude odstraněn v Godot 4.0."
diff --git a/editor/translations/da.po b/editor/translations/da.po
index 77cd37e20b..9e09250fbc 100644
--- a/editor/translations/da.po
+++ b/editor/translations/da.po
@@ -434,11 +434,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Animationsspor kan kun pege på AnimationPlayer noder."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-"En animationsafspiller kan ikke animerer sig selv, kun andre afspillere."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Det er ikke muligt at tilføje et nyt spor uden en rod"
@@ -487,8 +482,9 @@ msgid "Anim Move Keys"
msgstr "Anim Flyt Nøgle"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Udklipsholder er tom"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr ""
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2600,7 +2596,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "Gem ændringer i følgende scene(r) før du afslutter?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr "Gem ændringer i følgende scene(r), før du åbner Projekt Manager?"
#: editor/editor_node.cpp
@@ -12267,10 +12263,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "Indsæt VisualScript Nodes"
@@ -13392,6 +13384,13 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Konstanter kan ikke ændres."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "En animationsafspiller kan ikke animerer sig selv, kun andre afspillere."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Udklipsholder er tom"
+
#~ msgid "No"
#~ msgstr "Nej"
diff --git a/editor/translations/de.po b/editor/translations/de.po
index fcf5522011..bbf72f815b 100644
--- a/editor/translations/de.po
+++ b/editor/translations/de.po
@@ -75,7 +75,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-06-28 22:34+0000\n"
+"PO-Revision-Date: 2021-07-13 06:13+0000\n"
"Last-Translator: jmih03 <joerni@mail.de>\n"
"Language-Team: German <https://hosted.weblate.org/projects/godot-engine/"
"godot/de/>\n"
@@ -84,7 +84,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.7.1-dev\n"
+"X-Generator: Weblate 4.7.2-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -475,11 +475,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Animationsspuren können nur auf AnimationPlayer-Nodes zeigen."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-"Ein AnimationPlayer kann sich nicht selbst animieren, nur andere Objekte."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Ohne eine Wurzel kann keine neue Spur hinzugefügt werden"
@@ -526,8 +521,9 @@ msgid "Anim Move Keys"
msgstr "Schlüsselbilder bewegen"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Zwischenablage ist leer"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "Zwischenablage ist leer!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2581,7 +2577,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "Änderungen in den folgenden Szenen vor dem Schließen speichern?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
"Änderungen in den folgenden Szenen vor dem Öffnen der Projektverwaltung "
"speichern?"
@@ -7418,9 +7414,8 @@ msgid "Play IK"
msgstr "IK abspielen"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Orthogonal"
-msgstr "Orthogonal"
+msgstr "Senkrecht"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Perspective"
@@ -12111,10 +12106,6 @@ msgid "Can't copy the function node."
msgstr "Das Function-Node kann nicht kopiert werden."
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "Zwischenablage ist leer!"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "VisualScript-Nodes einfügen"
@@ -13349,6 +13340,13 @@ msgstr "Varyings können nur in Vertex-Funktion zugewiesen werden."
msgid "Constants cannot be modified."
msgstr "Konstanten können nicht verändert werden."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "Ein AnimationPlayer kann sich nicht selbst animieren, nur andere Objekte."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Zwischenablage ist leer"
+
#~ msgid ""
#~ "Godot editor was built without ray tracing support; lightmaps can't be "
#~ "baked.\n"
diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot
index 603b07a6d5..a0f4654639 100644
--- a/editor/translations/editor.pot
+++ b/editor/translations/editor.pot
@@ -396,10 +396,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr ""
@@ -444,7 +440,8 @@ msgid "Anim Move Keys"
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
msgstr ""
#: editor/animation_track_editor.cpp
@@ -2403,7 +2400,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11475,10 +11472,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
diff --git a/editor/translations/el.po b/editor/translations/el.po
index d85918f2b2..035a82f99f 100644
--- a/editor/translations/el.po
+++ b/editor/translations/el.po
@@ -12,12 +12,13 @@
# lawfulRobot <czavantias@gmail.com>, 2020, 2021.
# Michalis <michalisntovas@yahoo.gr>, 2021.
# leriaz <leriaz@live.com>, 2021.
+# Shadofer <shadowrlrs@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-05-30 04:15+0000\n"
-"Last-Translator: lawfulRobot <czavantias@gmail.com>\n"
+"PO-Revision-Date: 2021-07-09 14:32+0000\n"
+"Last-Translator: Shadofer <shadowrlrs@gmail.com>\n"
"Language-Team: Greek <https://hosted.weblate.org/projects/godot-engine/godot/"
"el/>\n"
"Language: el\n"
@@ -25,7 +26,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.7-dev\n"
+"X-Generator: Weblate 4.8-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -50,8 +51,8 @@ msgstr "ΆκυÏη είσοδος %i (δεν πέÏασε) στην έκφÏασ
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
msgstr ""
-"Το self δεν μποÏεί να χÏησιμοποιηθεί επειδή το στιγμιότυπο είναι null (δεν "
-"πέÏασε)"
+"το self δεν μποÏεί να χÏησιμοποιηθεί επειδή το αντικείμενο είναι null (δέν "
+"έχει πεÏαστεί)"
#: core/math/expression.cpp
msgid "Invalid operands to operator %s, %s and %s."
@@ -421,10 +422,6 @@ msgstr ""
"Τα κομμάτια κίνησης μποÏοÏν να δείχνουν μόνο σε κόμβους AnimationPlayer."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr "Ένα AnimationPlayer δεν μποÏεί να κινήσει τον εαυτό του."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "ΑδÏνατη η Ï€Ïοσθήκη ÎºÎ¿Î¼Î¼Î±Ï„Î¹Î¿Ï Ï‡Ï‰Ïίς Ïίζα"
@@ -469,8 +466,9 @@ msgid "Anim Move Keys"
msgstr "Μετακίνηση Κλειδιών Κίνησης"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Το Ï€ÏόχειÏο είναι άδειο"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "Το Ï€ÏόχειÏο είναι άδειο!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -1131,7 +1129,7 @@ msgstr "ΕυχαÏιστίες από την κοινότητα της Godot!"
#: editor/editor_about.cpp editor/editor_node.cpp editor/project_manager.cpp
msgid "Click to copy."
-msgstr ""
+msgstr "Πατήστε για αντιγÏαφή."
#: editor/editor_about.cpp
msgid "Godot Engine contributors"
@@ -1634,17 +1632,16 @@ msgstr ""
"ΕνεÏγοποιήστε το 'Εισαγωγή ETC2' ή 'Εισαγωγή PVRTC' στις Ρυθμίσεις ΈÏγου."
#: editor/editor_export.cpp
-#, fuzzy
msgid ""
"Target platform requires 'PVRTC' texture compression for the driver fallback "
"to GLES2.\n"
"Enable 'Import Pvrtc' in Project Settings, or disable 'Driver Fallback "
"Enabled'."
msgstr ""
-"Η πλατφόÏμα Ï€ÏοοÏÎ¹ÏƒÎ¼Î¿Ï Î±Ï€Î±Î¹Ï„ÎµÎ¯ «ETC» συμπίεση υφών για εναλλαγή Î¿Î´Î·Î³Î¿Ï ÏƒÏ„Î¿ "
+"Η πλατφόÏμα Ï€ÏοοÏÎ¹ÏƒÎ¼Î¿Ï Î±Ï€Î±Î¹Ï„ÎµÎ¯ συμπίεση υφών 'PVRTC' για εναλλαγή Î¿Î´Î·Î³Î¿Ï ÏƒÏ„Î¿ "
"GLES2.\n"
-"ΕνεÏγοποιήστε το «Import Etc» στις Ρυθμίσεις ΈÏγου, ή απενεÏγοποιήστε το "
-"«Driver Fallback Enabled»."
+"ΕνεÏγοποιήστε το 'Εισαγωγή PVRTC' στις Ρυθμίσεις ΈÏγου, ή απενεÏγοποιήστε το "
+"'ΕνεÏγοποίηση εναλλαγής οδηγοÏ'."
#: editor/editor_export.cpp platform/android/export/export.cpp
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
@@ -2523,7 +2520,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "Αποθήκευση αλλαγών στις ακόλουθες σκηνές Ï€Ïιν την έξοδο;"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
"Αποθήκευση αλλαγών στις ακόλουθες σκηνές Ï€Ïιν το άνοιγμα του ΔιαχειÏιστή "
"ΈÏγων;"
@@ -5101,9 +5098,8 @@ msgid "Got:"
msgstr "Δοσμένο:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Failed SHA-256 hash check"
-msgstr "Η δοκιμή κατακεÏÎ¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï sha256 απέτυχε"
+msgstr "Ο έλεγχος κατακεÏÎ¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï sha256 απέτυχε"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Asset Download Error:"
@@ -5259,26 +5255,31 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Failed determining lightmap size. Maximum lightmap size too small?"
msgstr ""
+"Αποτυχία Ï€ÏοσδιοÏÎ¹ÏƒÎ¼Î¿Ï Ï„Î¿Ï… μεγέθους lighÏ„map. Το μέγιστο μέγεθος lightmap "
+"ίσως είναι Ï€Î¿Î»Ï Î¼Î¹ÎºÏÏŒ."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Some mesh is invalid. Make sure the UV2 channel values are contained within "
"the [0.0,1.0] square region."
msgstr ""
+"ΜέÏος του πλέγματος δεν είναι έγκυÏο. ΣιγουÏευτείτε πως οι τιμές του "
+"ÎºÎ±Î½Î±Î»Î¹Î¿Ï UV2 πεÏιλαμβάνονται στην τετÏαγωνική πεÏιοχή [0.0,1.0]."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Godot editor was built without ray tracing support, lightmaps can't be baked."
msgstr ""
+"Ο Godot Editor φτιάχτηκε χωÏίς υποστήÏιξη ray-tracing, τα lightmaps δέν "
+"μποÏοÏν να δημιουÏγηθοÏν."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "ΠÏοετοιμασία Lightmaps"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
-#, fuzzy
msgid "Select lightmap bake file:"
-msgstr "Επιλογή ΑÏχείου ΠÏοτÏπων"
+msgstr "Επιλογή ΑÏχείου ΠÏοτÏπων:"
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5347,26 +5348,23 @@ msgstr "ΔημιουÏγία ΟÏιζοντίων και Καθέτων Οδηγ
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Set CanvasItem \"%s\" Pivot Offset to (%d, %d)"
-msgstr ""
+msgstr "Θέσε τον άξονα πεÏιστÏοφής του CanvasItem \"%s\" σε (%d, %d)"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Rotate %d CanvasItems"
-msgstr "ΠεÏιστÏοφή CanvasItem"
+msgstr "ΠεÏιστÏοφή %d CanvasItems"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Rotate CanvasItem \"%s\" to %d degrees"
-msgstr "ΠεÏιστÏοφή CanvasItem"
+msgstr "ΠεÏιστÏοφή του CanvasItem \"%s\" %d μοίÏες"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move CanvasItem \"%s\" Anchor"
-msgstr "Μετακίνηση CanvasItem"
+msgstr "Μετακίνηση άγκυÏας του CanvasItem \"%s\""
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Scale Node2D \"%s\" to (%s, %s)"
-msgstr ""
+msgstr "Αλλαγή μεγέθους scaling Node2D \"%s\" σε (%s, %s)"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Resize Control \"%s\" to (%d, %d)"
@@ -12080,10 +12078,6 @@ msgid "Can't copy the function node."
msgstr "ΑδÏνατη η αντιγÏαφή του κόμβου συνάÏτησης."
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "Το Ï€ÏόχειÏο είναι άδειο!"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "Επικόλληση κόμβων VisualScript"
@@ -13294,6 +13288,12 @@ msgstr "Τα «varying» μποÏοÏν να ανατεθοÏν μόνο στηÎ
msgid "Constants cannot be modified."
msgstr "Οι σταθεÏές δεν μποÏοÏν να Ï„ÏοποποιηθοÏν."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr "Ένα AnimationPlayer δεν μποÏεί να κινήσει τον εαυτό του."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Το Ï€ÏόχειÏο είναι άδειο"
+
#~ msgid ""
#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
#~ msgstr ""
diff --git a/editor/translations/eo.po b/editor/translations/eo.po
index 21d94bda5e..0523742303 100644
--- a/editor/translations/eo.po
+++ b/editor/translations/eo.po
@@ -13,18 +13,19 @@
# Jakub Fabijan <animatorzPolski@gmail.com>, 2021.
# mourning20s <mourning20s@protonmail.com>, 2021.
# Manuel González <mgoopazo@gmail.com>, 2021.
+# Wang Tseryui <2251439097@qq.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2021-06-02 09:04+0000\n"
-"Last-Translator: mourning20s <mourning20s@protonmail.com>\n"
+"PO-Revision-Date: 2021-07-13 06:13+0000\n"
+"Last-Translator: Wang Tseryui <2251439097@qq.com>\n"
"Language-Team: Esperanto <https://hosted.weblate.org/projects/godot-engine/"
"godot/eo/>\n"
"Language: eo\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.7-dev\n"
+"X-Generator: Weblate 4.7.2-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -394,9 +395,8 @@ msgid "Rearrange Tracks"
msgstr "RearanÄi trakojn"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Transform tracks only apply to Spatial-based nodes."
-msgstr "Transformaj trakoj nur aplikas al Spatial-ajn nodojn."
+msgstr "Transformaj trakoj validas nur aplikas al Spatial-bazitaj nodoj."
#: editor/animation_track_editor.cpp
msgid ""
@@ -415,10 +415,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Animaciaj trakoj nur eblas indiki al AnimationPlayer-aj nodoj."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr "Animado legilo ne volas animi si mem, nur aliajn ludantojn."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Ne eblas aldoni novan trakon sen radiko"
@@ -463,8 +459,9 @@ msgid "Anim Move Keys"
msgstr "Animado Movi Åœlosilojn"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Tondujo estas malplena"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr ""
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -1121,7 +1118,7 @@ msgstr "Dankon de la komunumo de Godot!"
#: editor/editor_about.cpp editor/editor_node.cpp editor/project_manager.cpp
msgid "Click to copy."
-msgstr ""
+msgstr "Alklaku por kopii."
#: editor/editor_about.cpp
msgid "Godot Engine contributors"
@@ -2510,7 +2507,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "Konservi ÅanÄojn al la jena(j) sceno(j) antaÅ­ foriri?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
"Konservi ÅanÄojn al la jena(j) sceno(j) antaÅ­ malfermi projektan mastrumilon?"
@@ -11803,10 +11800,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
@@ -12837,6 +12830,12 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Konstantoj ne povas esti modifitaj."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr "Animado legilo ne volas animi si mem, nur aliajn ludantojn."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Tondujo estas malplena"
+
#~ msgid "No"
#~ msgstr "Ne"
diff --git a/editor/translations/es.po b/editor/translations/es.po
index 7d3288527c..5953536c60 100644
--- a/editor/translations/es.po
+++ b/editor/translations/es.po
@@ -67,12 +67,13 @@
# Ib Quezada <ib@ibquezada.com>, 2021.
# hiking <joaquinfc@protonmail.com>, 2021.
# pabloggomez <pgg2733@gmail.com>, 2021.
+# Erick Figueroa <querecuto@hotmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-06-23 21:56+0000\n"
-"Last-Translator: pabloggomez <pgg2733@gmail.com>\n"
+"PO-Revision-Date: 2021-07-05 21:41+0000\n"
+"Last-Translator: Erick Figueroa <querecuto@hotmail.com>\n"
"Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/"
"godot/es/>\n"
"Language: es\n"
@@ -80,7 +81,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.7.1-dev\n"
+"X-Generator: Weblate 4.8-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -106,8 +107,7 @@ msgstr "Entrada inválida %i (no aprobada) en la expresión"
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
-msgstr ""
-"No se puede utilizar «self» porque la instancia es nula (no transmitida)"
+msgstr "\"self\" no puede ser usado porque la instancia es nula (detenido)"
#: core/math/expression.cpp
msgid "Invalid operands to operator %s, %s and %s."
@@ -167,7 +167,7 @@ msgstr "Balanceado"
#: editor/animation_bezier_editor.cpp
msgid "Mirror"
-msgstr "Mirror"
+msgstr "Reflejar"
#: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp
msgid "Time:"
@@ -475,12 +475,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Las pistas de Animación solo pueden apuntar a nodos AnimationPlayer."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-"Un reproductor de animación no puede animarse a sí mismo, solo a otros "
-"reproductores."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "No es posible agregar una nueva pista sin una raíz"
@@ -528,8 +522,9 @@ msgid "Anim Move Keys"
msgstr "Mover Claves de Animación"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "El portapapeles está vacío"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "¡El portapapeles está vacío!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -872,7 +867,7 @@ msgstr "Eliminar"
#: editor/connections_dialog.cpp
msgid "Add Extra Call Argument:"
-msgstr "Añadir argumento extra de llamada:"
+msgstr "Añadir argumento de llamada extra:"
#: editor/connections_dialog.cpp
msgid "Extra Call Arguments:"
@@ -1387,7 +1382,7 @@ msgstr "Silenciar"
#: editor/editor_audio_buses.cpp
msgid "Bypass"
-msgstr "Bypass"
+msgstr "Omitir"
#: editor/editor_audio_buses.cpp
msgid "Bus options"
@@ -2089,7 +2084,7 @@ msgstr "Propiedades de Temas"
#: editor/editor_help.cpp
msgid "Enumerations"
-msgstr "Enumerados"
+msgstr "Enumeraciones"
#: editor/editor_help.cpp
msgid "Constants"
@@ -2581,7 +2576,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "¿Guardar los cambios en las siguientes escenas antes de salir?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
"¿Guardar los cambios en las siguientes escenas antes de abrir el "
"Administrador de Proyectos?"
@@ -4203,7 +4198,7 @@ msgstr "Importar como:"
#: editor/import_dock.cpp
msgid "Preset"
-msgstr "Preset"
+msgstr "Preajuste"
#: editor/import_dock.cpp
msgid "Reimport"
@@ -4933,7 +4928,7 @@ msgstr "Eliminar el nodo o transición seleccionado/a."
msgid "Toggle autoplay this animation on start, restart or seek to zero."
msgstr ""
"Alternar reproducción automática de esta animación al comenzar, reiniciar o "
-"hacer puesta a cero."
+"poner a cero."
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Set the end animation. This is useful for sub-transitions."
@@ -5334,7 +5329,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
-msgstr "Bake Lightmaps"
+msgstr "Calcular Lightmaps"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Select lightmap bake file:"
@@ -6024,15 +6019,15 @@ msgstr "Flat 1"
#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp
msgid "Ease In"
-msgstr "Ease In"
+msgstr "Entrada Suave"
#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp
msgid "Ease Out"
-msgstr "Ease Out"
+msgstr "Salida Suave"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Smoothstep"
-msgstr "Smoothstep"
+msgstr "Suavizado"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Modify Curve Point"
@@ -6084,7 +6079,7 @@ msgstr "Clic derecho para añadir punto"
#: editor/plugins/gi_probe_editor_plugin.cpp
msgid "Bake GI Probe"
-msgstr "Bake GI Probe"
+msgstr "Calcular GI Probe"
#: editor/plugins/gradient_editor_plugin.cpp
msgid "Gradient Edited"
@@ -7115,7 +7110,7 @@ msgstr "Salir de Aquí"
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Break"
-msgstr "Break"
+msgstr "Detener"
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
#: editor/script_editor_debugger.cpp
@@ -7246,7 +7241,7 @@ msgstr "Marcadores"
#: editor/plugins/script_text_editor.cpp
msgid "Breakpoints"
-msgstr "Breakpoints"
+msgstr "Puntos de interrupción"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
@@ -8037,7 +8032,7 @@ msgstr "Velocidad:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Loop"
-msgstr "Loop"
+msgstr "Bucle"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Animation Frames:"
@@ -10549,7 +10544,7 @@ msgstr "Idiomas:"
#: editor/project_settings_editor.cpp
msgid "AutoLoad"
-msgstr "AutoLoad"
+msgstr "AutoCarga"
#: editor/project_settings_editor.cpp
msgid "Plugins"
@@ -10561,7 +10556,7 @@ msgstr "Valores de Importación por Defecto"
#: editor/property_editor.cpp
msgid "Preset..."
-msgstr "Preset..."
+msgstr "Preajuste..."
#: editor/property_editor.cpp
msgid "Zero"
@@ -10569,11 +10564,11 @@ msgstr "Cero"
#: editor/property_editor.cpp
msgid "Easing In-Out"
-msgstr "Easing In-Out"
+msgstr "Entrada-Salida Suave"
#: editor/property_editor.cpp
msgid "Easing Out-In"
-msgstr "Easing Out-In"
+msgstr "Salida-Entrada Suave"
#: editor/property_editor.cpp
msgid "File..."
@@ -11338,7 +11333,7 @@ msgstr "Fuente C++:"
#: editor/script_editor_debugger.cpp
msgid "Stack Trace"
-msgstr "Stack Trace"
+msgstr "Rastreo de Pila"
#: editor/script_editor_debugger.cpp
msgid "Errors"
@@ -11374,7 +11369,7 @@ msgstr "Fotogramas Apilados"
#: editor/script_editor_debugger.cpp
msgid "Profiler"
-msgstr "Profiler"
+msgstr "Perfilador"
#: editor/script_editor_debugger.cpp
msgid "Network Profiler"
@@ -11470,7 +11465,7 @@ msgstr "Atajos"
#: editor/settings_config_dialog.cpp
msgid "Binding"
-msgstr "Binding"
+msgstr "Vinculación"
#: editor/spatial_editor_gizmos.cpp
msgid "Change Light Radius"
@@ -11807,7 +11802,7 @@ msgstr "Fin del reporte de la pila de excepciones"
#: modules/recast/navigation_mesh_editor_plugin.cpp
msgid "Bake NavMesh"
-msgstr "Bake NavMesh"
+msgstr "Calcular NavMesh"
#: modules/recast/navigation_mesh_editor_plugin.cpp
msgid "Clear the navigation mesh."
@@ -12109,10 +12104,6 @@ msgid "Can't copy the function node."
msgstr "No se puede copiar el nodo de función."
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "¡El portapapeles está vacío!"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "Pegar nodos de VisualScript"
@@ -13341,6 +13332,14 @@ msgstr "Solo se pueden asignar variaciones en funciones de vértice."
msgid "Constants cannot be modified."
msgstr "Las constantes no pueden modificarse."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "Un reproductor de animación no puede animarse a sí mismo, solo a otros "
+#~ "reproductores."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "El portapapeles está vacío"
+
#~ msgid ""
#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
#~ msgstr ""
diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po
index 4bac2d84e9..d1fe06a565 100644
--- a/editor/translations/es_AR.po
+++ b/editor/translations/es_AR.po
@@ -424,12 +424,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Las pistas de Animación solo pueden apuntar a nodos AnimationPlayer."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-"Un reproductor de animación no puede animarse a sí mismo, solo a otros "
-"reproductores."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "No es posible agregar una nueva pista sin una raíz"
@@ -476,8 +470,9 @@ msgid "Anim Move Keys"
msgstr "Mover Claves de Anim"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "El portapapeles está vacío"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "El portapapeles está vacío!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2528,7 +2523,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "Guardar cambios a la(s) siguiente(s) escena(s) antes de salir?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
"Guardar cambios a la(s) siguiente(s) escena(s) antes de abrir el Gestor de "
"Proyectos?"
@@ -12043,10 +12038,6 @@ msgid "Can't copy the function node."
msgstr "No se puede copiar el nodo de función."
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "El portapapeles está vacío!"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "Pegar Nodos de VisualScript"
@@ -13263,6 +13254,14 @@ msgstr "Solo se pueden asignar variaciones en funciones de vértice."
msgid "Constants cannot be modified."
msgstr "Las constantes no pueden modificarse."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "Un reproductor de animación no puede animarse a sí mismo, solo a otros "
+#~ "reproductores."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "El portapapeles está vacío"
+
#~ msgid ""
#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
#~ msgstr "InterpolatedCamera ha sido deprecado y será eliminado en Godot 4.0."
diff --git a/editor/translations/et.po b/editor/translations/et.po
index d81e10e9d7..05a414f5a9 100644
--- a/editor/translations/et.po
+++ b/editor/translations/et.po
@@ -409,10 +409,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Animatsiooni rajad võivad osutada ainult AnimationPlayer sõlmedele."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr "AnimationPlayer ei saa animeerida iseennast, ainult teisi mängijaid."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Ei saa lisada uut rada ilma tüveta"
@@ -457,8 +453,9 @@ msgid "Anim Move Keys"
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Lõikelaud on tühi"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr ""
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2450,7 +2447,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11548,10 +11545,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
@@ -12574,6 +12567,13 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Konstante ei saa muuta."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "AnimationPlayer ei saa animeerida iseennast, ainult teisi mängijaid."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Lõikelaud on tühi"
+
#~ msgid "Error trying to save layout!"
#~ msgstr "Viga paigutuse salvestamisel!"
diff --git a/editor/translations/eu.po b/editor/translations/eu.po
index 0f8ef2de33..87c91de10e 100644
--- a/editor/translations/eu.po
+++ b/editor/translations/eu.po
@@ -410,10 +410,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Animazio pistek AnimationPlayer nodoak bakarrik apunta ditzakete."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr "Animazio irakurgailua ezin da norbera animatu, bakarrik beste batzuk."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Ez da posiblea pista berri bat gehitzea sustrairik gabe"
@@ -458,7 +454,8 @@ msgid "Anim Move Keys"
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
msgstr ""
#: editor/animation_track_editor.cpp
@@ -2427,7 +2424,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11522,10 +11519,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
@@ -12547,3 +12540,7 @@ msgstr ""
#: servers/visual/shader_language.cpp
msgid "Constants cannot be modified."
msgstr ""
+
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "Animazio irakurgailua ezin da norbera animatu, bakarrik beste batzuk."
diff --git a/editor/translations/fa.po b/editor/translations/fa.po
index ba8c4f9302..ddccfeaebe 100644
--- a/editor/translations/fa.po
+++ b/editor/translations/fa.po
@@ -20,12 +20,13 @@
# Ahmad Maftoun <CarCedo.Pro@gmail.com>, 2020.
# ItzMiad44909858f5774b6d <maidggg@gmail.com>, 2020.
# YASAN <yasandev@gmail.com>, 2021.
+# duniyal ras <duniyalr@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-03-16 10:40+0000\n"
-"Last-Translator: YASAN <yasandev@gmail.com>\n"
+"PO-Revision-Date: 2021-07-13 06:13+0000\n"
+"Last-Translator: duniyal ras <duniyalr@gmail.com>\n"
"Language-Team: Persian <https://hosted.weblate.org/projects/godot-engine/"
"godot/fa/>\n"
"Language: fa\n"
@@ -33,7 +34,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 4.5.2-dev\n"
+"X-Generator: Weblate 4.7.2-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -425,10 +426,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "آهنگ های انیمیشن Ùقط Ù…ÛŒ توانند به گره های انیمش پلیر اشاره کنند."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr "یک مجری انیمیشن نمی تواند خود را محرک کند، Ùقط سایر مجریان."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "بدون ریشه اضاÙÙ‡ کردن مسیر امکان پذیر نیست"
@@ -473,8 +470,9 @@ msgid "Anim Move Keys"
msgstr "کلیدها را در انیمیشن جابجا کن"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "حاÙظه پنهان خالی است"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "حاÙظه پنهان خالی است!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -1047,7 +1045,6 @@ msgid ""
msgstr "آیا پرونده‌های انتخاب شده از طرح حذ٠شوند؟ (غیر قابل بازیابی)"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"The files being removed are required by other resources in order for them to "
"work.\n"
@@ -1056,7 +1053,8 @@ msgid ""
msgstr ""
"پرونده‌هایی که می‌خواهید حذ٠شوند برای منابع دیگر مورد نیاز هستند تا کار "
"کنند.\n"
-"آیا در هر صورت حذ٠شوند؟(بدون برگشت)"
+"آیا در هر صورت حذ٠شوند؟(بدون برگشت)\n"
+"شما میتوانید Ùایل های حذ٠شده را در سطل زباله سیستم عامل خود بیابید ."
#: editor/dependency_editor.cpp
msgid "Cannot remove:"
@@ -1128,7 +1126,7 @@ msgstr "با تشکر از سوی جامعه‌ی Godot!"
#: editor/editor_about.cpp editor/editor_node.cpp editor/project_manager.cpp
msgid "Click to copy."
-msgstr ""
+msgstr "برای کپی کردن کلیک کنید."
#: editor/editor_about.cpp
msgid "Godot Engine contributors"
@@ -1351,9 +1349,8 @@ msgid "Add Audio Bus"
msgstr "اÙزودن کانل صوتی"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Master bus can't be deleted!"
-msgstr "استاد اتوبوس قابل حذ٠نیست!"
+msgstr "گذرگاه اصلی قابل حذ٠نیست!"
#: editor/editor_audio_buses.cpp
msgid "Delete Audio Bus"
@@ -1470,9 +1467,8 @@ msgid "Rename Autoload"
msgstr "بارگذاری خودکار را تغییر نام بده"
#: editor/editor_autoload_settings.cpp
-#, fuzzy
msgid "Toggle AutoLoad Globals"
-msgstr "تغییر حالت اتماتیک لود عمومی"
+msgstr "تغییر متغیر های عمومی مربوط به لود خودکار"
#: editor/editor_autoload_settings.cpp
msgid "Move Autoload"
@@ -2459,7 +2455,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -12111,10 +12107,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "حاÙظه پنهان خالی است!"
-
-#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
msgid "Paste VisualScript Nodes"
msgstr "مسیر به سمت گره:"
@@ -13242,6 +13234,12 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "ثوابت قابل تغییر نیستند."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr "یک مجری انیمیشن نمی تواند خود را محرک کند، Ùقط سایر مجریان."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "حاÙظه پنهان خالی است"
+
#~ msgid "No"
#~ msgstr "نه"
diff --git a/editor/translations/fi.po b/editor/translations/fi.po
index 9b0cb63c86..834d1894e3 100644
--- a/editor/translations/fi.po
+++ b/editor/translations/fi.po
@@ -416,10 +416,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Animaatioraidat voivat osoittaa vain AnimationPlayer solmuihin."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr "Animaatiotoistin ei voi animoida itseään, ainoastaan muita toistimia."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Uutta raitaa ei voida lisätä ilman juurta"
@@ -464,8 +460,9 @@ msgid "Anim Move Keys"
msgstr "Animaatio: siirrä avaimia"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Leikepöytä on tyhjä"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "Leikepöytä on tyhjä!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2505,7 +2502,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "Tallenetaanko muutokset seuraaviin skeneihin ennen sulkemista?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
"Tallennetaanko muutokset seuraaviin skeneihin ennen Projektienhallinnan "
"avaamista?"
@@ -11987,10 +11984,6 @@ msgid "Can't copy the function node."
msgstr "Ei voida kopioida funktiosolmua."
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "Leikepöytä on tyhjä!"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "Liitä VisualScript solmut"
@@ -13187,6 +13180,13 @@ msgstr "Varying tyypin voi sijoittaa vain vertex-funktiossa."
msgid "Constants cannot be modified."
msgstr "Vakioita ei voi muokata."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "Animaatiotoistin ei voi animoida itseään, ainoastaan muita toistimia."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Leikepöytä on tyhjä"
+
#~ msgid ""
#~ "Godot editor was built without ray tracing support; lightmaps can't be "
#~ "baked.\n"
diff --git a/editor/translations/fil.po b/editor/translations/fil.po
index 54df144dd9..892968821b 100644
--- a/editor/translations/fil.po
+++ b/editor/translations/fil.po
@@ -410,10 +410,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr ""
@@ -458,8 +454,9 @@ msgid "Anim Move Keys"
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Walang laman ang Clipboard"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr ""
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2418,7 +2415,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11508,10 +11505,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
@@ -12533,5 +12526,8 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "Clipboard is empty"
+#~ msgstr "Walang laman ang Clipboard"
+
#~ msgid "No"
#~ msgstr "Hindi"
diff --git a/editor/translations/fr.po b/editor/translations/fr.po
index 129ab4f687..6fad70a7c2 100644
--- a/editor/translations/fr.po
+++ b/editor/translations/fr.po
@@ -80,12 +80,13 @@
# TechnoPorg <jonah.janzen@gmail.com>, 2021.
# ASTRALE <jules.cercy@etu.univ-lyon1.fr>, 2021.
# Julien Vanelian <julienvanelian@hotmail.com>, 2021.
+# Clément Topy <topy72.mine@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-06-20 13:35+0000\n"
-"Last-Translator: Nathan <bonnemainsnathan@gmail.com>\n"
+"PO-Revision-Date: 2021-07-01 14:33+0000\n"
+"Last-Translator: Clément Topy <topy72.mine@gmail.com>\n"
"Language-Team: French <https://hosted.weblate.org/projects/godot-engine/"
"godot/fr/>\n"
"Language: fr\n"
@@ -93,7 +94,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 4.7\n"
+"X-Generator: Weblate 4.8-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -487,12 +488,6 @@ msgstr ""
"Les pistes d’animation ne peuvent pointer que sur des nœuds AnimationPlayer."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-"Un lecteur d’animation ne peut s’animer lui-même, seulement les autres "
-"lecteurs."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Impossible d’ajouter une nouvelle piste sans racine"
@@ -539,8 +534,9 @@ msgid "Anim Move Keys"
msgstr "Déplacer les clés d’animation"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Le presse-papiers est vide"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "Le presse-papiers est vide !"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -1403,7 +1399,7 @@ msgstr "Contourner"
#: editor/editor_audio_buses.cpp
msgid "Bus options"
-msgstr "Options de tranport"
+msgstr "Options de bus"
#: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp
#: editor/plugins/animation_player_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -2596,7 +2592,7 @@ msgstr ""
"quitter ?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
"Enregistrer les modifications sur la (les) scène(s) suivante(s) avant "
"d'ouvrir le gestionnaire de projet ?"
@@ -3260,7 +3256,7 @@ msgstr "Ré-enregistrer"
#: editor/editor_node.cpp
msgid "New Inherited"
-msgstr "Nouveau hérité"
+msgstr "Nouvelle scène héritée"
#: editor/editor_node.cpp
msgid "Load Errors"
@@ -12145,10 +12141,6 @@ msgid "Can't copy the function node."
msgstr "Impossible de copier le nœud de fonction."
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "Le presse-papiers est vide !"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "Coller les nœuds VisualScript"
@@ -13391,6 +13383,14 @@ msgstr "Les variations ne peuvent être affectées que dans la fonction vertex."
msgid "Constants cannot be modified."
msgstr "Les constantes ne peuvent être modifiées."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "Un lecteur d’animation ne peut s’animer lui-même, seulement les autres "
+#~ "lecteurs."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Le presse-papiers est vide"
+
#~ msgid ""
#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
#~ msgstr "InterpolatedCamera a été déprécié et sera supprimé dans Godot 4.0."
diff --git a/editor/translations/ga.po b/editor/translations/ga.po
index e3b1137cee..8168c1a440 100644
--- a/editor/translations/ga.po
+++ b/editor/translations/ga.po
@@ -402,10 +402,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr ""
@@ -450,7 +446,8 @@ msgid "Anim Move Keys"
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
msgstr ""
#: editor/animation_track_editor.cpp
@@ -2413,7 +2410,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11501,10 +11498,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
diff --git a/editor/translations/gl.po b/editor/translations/gl.po
index f6905f4bef..016a3ab589 100644
--- a/editor/translations/gl.po
+++ b/editor/translations/gl.po
@@ -408,12 +408,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "As pistas de animación só poden apuntar a nodos AnimationPlayer."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-"Un reproductor de animacións non pode animarse a si mesmo, só a outros "
-"reproductores."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Non é posible engadir unha nova pista sen unha raíz"
@@ -459,8 +453,9 @@ msgid "Anim Move Keys"
msgstr "Mover Claves de Animación"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "O portapapeis está baleiro"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "O portapapeis está baleiro!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2502,7 +2497,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "Gardar os cambios nas seguintes escenas antes de saír?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
"Gardar os cambios nas seguintes escenas antes de abrir o Administrador de "
"Proxectos?"
@@ -11796,10 +11791,6 @@ msgid "Can't copy the function node."
msgstr "Non se pode copiar o nodo función."
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "O portapapeis está baleiro!"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "Pegar Nodos VisualScript"
@@ -12896,3 +12887,11 @@ msgstr ""
#: servers/visual/shader_language.cpp
msgid "Constants cannot be modified."
msgstr ""
+
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "Un reproductor de animacións non pode animarse a si mesmo, só a outros "
+#~ "reproductores."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "O portapapeis está baleiro"
diff --git a/editor/translations/he.po b/editor/translations/he.po
index f0e3fa4383..5dc30a6cc2 100644
--- a/editor/translations/he.po
+++ b/editor/translations/he.po
@@ -426,10 +426,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "רצועות הנפשה יכולות להצביע רק על ×יברי AnimationPlayer."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr "נגן הנפשה ×ינו יכול להנפיש ×ת עצמו, רק ×©×—×§× ×™× ×חרי×."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "××™ ×פשר להוסיף רצועה חדשה בלי שורש"
@@ -478,8 +474,9 @@ msgid "Anim Move Keys"
msgstr "מפתחות הזזת ×נימצייה"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "לוח העתקה ריק"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "לוח העתקה ריק!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2508,7 +2505,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "לשמור ×ת ×”×©×™× ×•×™×™× ×œ×¡×¦× ×•×ª הב×ות לפני היצי××”?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr "לשמור ×ת הסצנות הב×ות לפני פתיחת מנהל המיזמי×?"
#: editor/editor_node.cpp
@@ -12023,10 +12020,6 @@ msgid "Can't copy the function node."
msgstr "×œ× × ×™×ª×Ÿ להעתיק ×ת פונקצית המפרק."
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "לוח העתקה ריק!"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "הדבקת מפרקי VisualScript"
@@ -13165,6 +13158,12 @@ msgstr "ניתן להקצות ×©×™× ×•×™×™× ×¨×§ בפונקצית vertex."
msgid "Constants cannot be modified."
msgstr "××™ ×פשר לשנות קבועי×."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr "נגן הנפשה ×ינו יכול להנפיש ×ת עצמו, רק ×©×—×§× ×™× ×חרי×."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "לוח העתקה ריק"
+
#~ msgid "No"
#~ msgstr "ל×"
diff --git a/editor/translations/hi.po b/editor/translations/hi.po
index a70f058a65..db1dcd67e6 100644
--- a/editor/translations/hi.po
+++ b/editor/translations/hi.po
@@ -417,10 +417,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "à¤à¤¨à¤¿à¤®à¥‡à¤¶à¤¨ टà¥à¤°à¥ˆà¤• केवल à¤à¤¨à¤¿à¤®à¥‡à¤¶à¤¨à¤ªà¥à¤²à¥‡à¤¯à¤° नोडà¥à¤¸ को इंगित कर सकते हैं।"
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr "à¤à¤• à¤à¤¨à¥€à¤®à¥‡à¤¶à¤¨ खिलाड़ी खà¥à¤¦ को चेतन नहीं कर सकता, केवल अनà¥à¤¯ खिलाड़ी।"
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "रूट के बिना नया टà¥à¤°à¥ˆà¤• जोड़ना संभव नहीं"
@@ -465,8 +461,9 @@ msgid "Anim Move Keys"
msgstr "à¤à¤¨à¤¿à¤®à¥‡à¤Ÿà¥‡à¤¡ मूव कीज़"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "कà¥à¤²à¤¿à¤ªà¤¬à¥‹à¤°à¥à¤¡ खाली है"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr ""
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2487,7 +2484,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "छोड़ने से पहले निमà¥à¤¨à¤²à¤¿à¤–ित दृशà¥à¤¯ (ओं) में परिवरà¥à¤¤à¤¨ सहेजें?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr "परियोजना पà¥à¤°à¤¬à¤‚धक खोलने से पहले निमà¥à¤¨à¤²à¤¿à¤–ित दृशà¥à¤¯ (ओं) में परिवरà¥à¤¤à¤¨ सहेजें?"
#: editor/editor_node.cpp
@@ -11775,10 +11772,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
@@ -12819,6 +12812,12 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr "à¤à¤• à¤à¤¨à¥€à¤®à¥‡à¤¶à¤¨ खिलाड़ी खà¥à¤¦ को चेतन नहीं कर सकता, केवल अनà¥à¤¯ खिलाड़ी।"
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "कà¥à¤²à¤¿à¤ªà¤¬à¥‹à¤°à¥à¤¡ खाली है"
+
#~ msgid "No"
#~ msgstr "नहीं"
diff --git a/editor/translations/hr.po b/editor/translations/hr.po
index f49ba47c29..d737bb04b7 100644
--- a/editor/translations/hr.po
+++ b/editor/translations/hr.po
@@ -405,10 +405,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr "Animator ne može animirati sebe, samo druge objekte."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Nije moguće dodati novu stazu bez korijena"
@@ -453,8 +449,9 @@ msgid "Anim Move Keys"
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Međuspremnik je prazan"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr ""
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2425,7 +2422,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11527,10 +11524,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
@@ -12553,6 +12546,12 @@ msgstr "Varijacije se mogu dodijeliti samo u vertex funkciji."
msgid "Constants cannot be modified."
msgstr "Konstante se ne mogu mijenjati."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr "Animator ne može animirati sebe, samo druge objekte."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Međuspremnik je prazan"
+
#, fuzzy
#~ msgid "Pack File"
#~ msgstr "Otvori datoteku"
diff --git a/editor/translations/hu.po b/editor/translations/hu.po
index eda808eef4..85933dc05d 100644
--- a/editor/translations/hu.po
+++ b/editor/translations/hu.po
@@ -424,12 +424,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Animáció sávok csak AnimationPlayer node-ra mutathatnak."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-"Egy AnimationPlayer nem tudja önmagát animálni, csak más AnimationPlayer "
-"node-okat."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Új sáv hozzáadása nem lehetséges gyökér nélkül"
@@ -474,8 +468,9 @@ msgid "Anim Move Keys"
msgstr "Animáció - Kulcsok Mozgatása"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "A vágólap üres"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr ""
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2523,7 +2518,7 @@ msgstr ""
"Elmenti a következő jelenet(ek)en végzett változtatásokat kilépés előtt?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
"Elmenti a következő Scene(ek)en végzett változtatásokat a Projektkezelő "
"megnyitása előtt?"
@@ -11713,10 +11708,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
@@ -12744,6 +12735,14 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "Egy AnimationPlayer nem tudja önmagát animálni, csak más AnimationPlayer "
+#~ "node-okat."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "A vágólap üres"
+
#~ msgid "No"
#~ msgstr "Nem"
diff --git a/editor/translations/id.po b/editor/translations/id.po
index 08bfa5969d..e1029fc231 100644
--- a/editor/translations/id.po
+++ b/editor/translations/id.po
@@ -31,12 +31,13 @@
# Hanz <hanzhaxors@gmail.com>, 2021.
# Reza Almanda <rezaalmanda27@gmail.com>, 2021.
# Naufal Adriansyah <naufaladrn90@gmail.com>, 2021.
+# undisputedgoose <diablodvorak@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-04-05 14:28+0000\n"
-"Last-Translator: Naufal Adriansyah <naufaladrn90@gmail.com>\n"
+"PO-Revision-Date: 2021-07-05 14:32+0000\n"
+"Last-Translator: undisputedgoose <diablodvorak@gmail.com>\n"
"Language-Team: Indonesian <https://hosted.weblate.org/projects/godot-engine/"
"godot/id/>\n"
"Language: id\n"
@@ -44,7 +45,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.6-dev\n"
+"X-Generator: Weblate 4.8-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -69,7 +70,7 @@ msgstr "Masukkan tidak sah %i (tidak diberikan) dalam ekspresi"
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
-msgstr "self tidak dapat digunakan karena instance adalah null"
+msgstr "self tidak dapat digunakan karena instansi adalah null"
#: core/math/expression.cpp
msgid "Invalid operands to operator %s, %s and %s."
@@ -77,7 +78,7 @@ msgstr "operan salah untuk operator %s, %s dan %s."
#: core/math/expression.cpp
msgid "Invalid index of type %s for base type %s"
-msgstr "Tipe indeks %s tidak valid untuk tipe dasar %s"
+msgstr "Index tidak valid dari tipe %s untuk tipe dasar %s"
#: core/math/expression.cpp
msgid "Invalid named index '%s' for base type %s"
@@ -149,7 +150,7 @@ msgstr "Duplikat Key Terpilih"
#: editor/animation_bezier_editor.cpp
msgid "Delete Selected Key(s)"
-msgstr "Hapus Key Terpilih"
+msgstr "Hapus Kunci Terpilih"
#: editor/animation_bezier_editor.cpp
msgid "Add Bezier Point"
@@ -161,7 +162,7 @@ msgstr "Pindah Titik-titik Bezier"
#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
msgid "Anim Duplicate Keys"
-msgstr "Tombol Duplikat Anim"
+msgstr "Kunci Duplikat Anim"
#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
msgid "Anim Delete Keys"
@@ -341,7 +342,7 @@ msgstr "Interpolasi perulangan warp"
#: editor/animation_track_editor.cpp
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Insert Key"
-msgstr "Masukkan Key"
+msgstr "Masukkan Kunci"
#: editor/animation_track_editor.cpp
msgid "Duplicate Key(s)"
@@ -437,11 +438,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Track animasi hanya bisa menunjuk ke node AnimationPlayer."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-"Pemutar animasi tidak bisa menganimasikan diri sendiri, hanya pemutar lain."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Tidak memungkinkan untuk menambah track baru tanpa akar"
@@ -487,8 +483,9 @@ msgid "Anim Move Keys"
msgstr "Pindahkan Kunci Anim"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Papan klip kosong"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "Papan klip kosong!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -544,7 +541,7 @@ msgstr "Susun Track-track dengan node atau tampilkan sebagai daftar biasa."
#: editor/animation_track_editor.cpp
msgid "Snap:"
-msgstr "Pengancingan:"
+msgstr "Snap:"
#: editor/animation_track_editor.cpp
msgid "Animation step value."
@@ -676,7 +673,7 @@ msgstr "Pilih Trek untuk Disalin"
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
-msgstr "Kopy"
+msgstr "Salin"
#: editor/animation_track_editor.cpp
msgid "Select All/None"
@@ -769,7 +766,7 @@ msgstr "Perkecil Pandangan"
#: editor/code_editor.cpp
msgid "Reset Zoom"
-msgstr "Kebalikan Semula Pandangan"
+msgstr "Kembalikan Semula Pandangan"
#: editor/code_editor.cpp
msgid "Warnings"
@@ -1128,7 +1125,7 @@ msgstr "Memiliki"
#: editor/dependency_editor.cpp
msgid "Resources Without Explicit Ownership:"
-msgstr "Resource Tanpa Kepemilikan yang Jelas:"
+msgstr "Sumber Tanpa Kepemilikan yang Jelas:"
#: editor/dictionary_property_edit.cpp
msgid "Change Dictionary Key"
@@ -1144,7 +1141,7 @@ msgstr "Terimakasih dari komunitas Godot!"
#: editor/editor_about.cpp editor/editor_node.cpp editor/project_manager.cpp
msgid "Click to copy."
-msgstr ""
+msgstr "Klik untuk salin."
#: editor/editor_about.cpp
msgid "Godot Engine contributors"
@@ -1373,7 +1370,7 @@ msgstr "Master Bus tidak dapat dihapus!"
#: editor/editor_audio_buses.cpp
msgid "Delete Audio Bus"
-msgstr "Hapus Bus Audio"
+msgstr "Hapus Audio Bus"
#: editor/editor_audio_buses.cpp
msgid "Duplicate Audio Bus"
@@ -1507,7 +1504,7 @@ msgstr "Mengatur kembali Autoload-autoload"
#: editor/editor_autoload_settings.cpp
msgid "Can't add autoload:"
-msgstr "Tidak dapat menambahkan autoload:"
+msgstr "Tidak dapat menambahkan autoload"
#: editor/editor_autoload_settings.cpp
msgid "Add AutoLoad"
@@ -2526,7 +2523,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "Simpan perubahan skena saat ini sebelum keluar?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr "Simpan perubahan skena saat ini sebelum membuka Manajer Proyek?"
#: editor/editor_node.cpp
@@ -2565,7 +2562,6 @@ msgid "Unable to load addon script from path: '%s'."
msgstr "Tidak bisa memuat script addon dari lokasi: '%s'."
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"Unable to load addon script from path: '%s'. This might be due to a code "
"error in that script.\n"
@@ -3016,7 +3012,7 @@ msgstr "Tentang"
#: editor/editor_node.cpp
msgid "Support Godot Development"
-msgstr ""
+msgstr "Dukung pengembangan Godot"
#: editor/editor_node.cpp
msgid "Play the project."
@@ -7534,31 +7530,31 @@ msgstr "Tidak tersedia ketika menggunakan perender GLES2."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Left"
-msgstr "TampilanBebas Kiri"
+msgstr "Tampilan Bebas Kiri"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Right"
-msgstr "TampilanBebas Kanan"
+msgstr "Tampilan Bebas Kanan"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Forward"
-msgstr "TampilanBebas Maju"
+msgstr "Tampilan Bebas Maju"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Backwards"
-msgstr "TampilanBebas Mundur"
+msgstr "Tampilan Bebas Mundur"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Up"
-msgstr "TampilanBebas Atas"
+msgstr "Tampilan Bebas Atas"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Down"
-msgstr "TampilanBebas Bawah"
+msgstr "Tampilan Bebas Bawah"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Speed Modifier"
-msgstr "Pengubah Kecepatan TampilanBebas"
+msgstr "Pengubah Kecepatan Tampilan Bebas"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Slow Modifier"
@@ -7569,9 +7565,12 @@ msgid "View Rotation Locked"
msgstr "Rotasi Tampilan Terkunci"
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
msgid ""
"To zoom further, change the camera's clipping planes (View -> Settings...)"
msgstr ""
+"Untuk memperbesar lebih jauh, ganti kamera clipping planes (Tinjau -> "
+"Setelan...)"
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -7657,11 +7656,11 @@ msgstr "Beralih Tampilan Ortogonal/Perspektif"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Insert Animation Key"
-msgstr "Sisipkan Kunci Animasi"
+msgstr "Masukkan Kunci Animasi"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Focus Origin"
-msgstr "Asal Fokus"
+msgstr "Fokus asal"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Focus Selection"
@@ -7669,7 +7668,7 @@ msgstr "Pemilihan Fokus"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
-msgstr "Jungkitkan Mode Tampilan Bebas"
+msgstr "Aktifkan Mode Tampilan Bebas"
#: editor/plugins/spatial_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7678,7 +7677,7 @@ msgstr "Transformasi"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Object to Floor"
-msgstr "Kancingkan Objek ke Lantai"
+msgstr "Tempelkan Objek ke Lantai"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Transform Dialog..."
@@ -12008,10 +12007,6 @@ msgid "Can't copy the function node."
msgstr "Tidak dapat menyalin node fungsi."
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "Papan klip kosong!"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "Rekatkan Node VisualScript"
@@ -13210,6 +13205,14 @@ msgstr "Variasi hanya bisa ditetapkan dalam fungsi vertex."
msgid "Constants cannot be modified."
msgstr "Konstanta tidak dapat dimodifikasi."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "Pemutar animasi tidak bisa menganimasikan diri sendiri, hanya pemutar "
+#~ "lain."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Papan klip kosong"
+
#~ msgid "No"
#~ msgstr "Tidak"
diff --git a/editor/translations/is.po b/editor/translations/is.po
index 72472c2215..fc1423d841 100644
--- a/editor/translations/is.po
+++ b/editor/translations/is.po
@@ -426,10 +426,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr ""
@@ -478,7 +474,8 @@ msgid "Anim Move Keys"
msgstr "Færa lykla af Anim"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
msgstr ""
#: editor/animation_track_editor.cpp
@@ -2449,7 +2446,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
"Vista breytingar á neðangreindum senu(m) áður en Verkefna Stjóri er opnaður?"
@@ -11628,10 +11625,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
diff --git a/editor/translations/it.po b/editor/translations/it.po
index 3d0509ba15..60c362c63a 100644
--- a/editor/translations/it.po
+++ b/editor/translations/it.po
@@ -464,10 +464,6 @@ msgstr ""
"Le tracce di animazioni possono puntare solo a nodi di tipo AnimationPlayer."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr "Un AnimationPlayer non può animare se stesso, solo altri riproduttori."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Non è possibile aggiungere una nuova traccia senza un nodo radice"
@@ -515,8 +511,9 @@ msgid "Anim Move Keys"
msgstr "Sposta delle chiavi d'animazione"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Gli appunti sono vuoti"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "Gli appunti sono vuoti!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2578,7 +2575,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "Salvare le modifiche alle scene seguenti prima di uscire?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
"Salvare le modifiche alle scene seguenti prima di aprire il gestore di "
"progetti?"
@@ -12146,10 +12143,6 @@ msgid "Can't copy the function node."
msgstr "Non è possibile copiare il nodo della funzione."
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "Gli appunti sono vuoti!"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "Incolla Nodi VisualScript"
@@ -13371,6 +13364,13 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Le constanti non possono essere modificate."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "Un AnimationPlayer non può animare se stesso, solo altri riproduttori."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Gli appunti sono vuoti"
+
#~ msgid ""
#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
#~ msgstr ""
diff --git a/editor/translations/ja.po b/editor/translations/ja.po
index 85768d721a..1fd770fe13 100644
--- a/editor/translations/ja.po
+++ b/editor/translations/ja.po
@@ -439,12 +439,6 @@ msgstr ""
"アニメーショントラックã¯ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ãƒ—レイヤーノードã®ã¿æŒ‡å®šã§ãã¾ã™ã€‚"
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-"アニメーションプレーヤーã¯ä»–ã®ãƒ—レーヤーã ã‘ã«ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’é©ç”¨ã™ã‚‹ã“ã¨ã¯"
-"ã§ãã¾ã›ã‚“。"
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "root ãŒç„¡ã‘ã‚Œã°æ–°è¦ãƒˆãƒ©ãƒƒã‚¯ã¯è¿½åŠ ã§ãã¾ã›ã‚“"
@@ -489,8 +483,9 @@ msgid "Anim Move Keys"
msgstr "アニメーションキーã®ç§»å‹•"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "クリップボードãŒç©ºã§ã™"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "クリップボードã¯ç©ºã§ã™!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2530,7 +2525,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "終了ã™ã‚‹å‰ã«ã€ä»¥ä¸‹ã®ã‚·ãƒ¼ãƒ³ã¸ã®å¤‰æ›´ã‚’ä¿å­˜ã—ã¾ã™ã‹ï¼Ÿ"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
"プロジェクトマãƒãƒ¼ã‚¸ãƒ£ãƒ¼ã‚’é–‹ãå‰ã«ã€ä»¥ä¸‹ã®ã‚·ãƒ¼ãƒ³ã¸ã®å¤‰æ›´ã‚’ä¿å­˜ã—ã¾ã™ã‹ï¼Ÿ"
@@ -11994,10 +11989,6 @@ msgid "Can't copy the function node."
msgstr "ファンクションノードをコピーã§ãã¾ã›ã‚“。"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "クリップボードã¯ç©ºã§ã™!"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "VisualScriptノードを貼り付ã‘"
@@ -13182,6 +13173,14 @@ msgstr "Varying変数ã¯é ‚点関数ã«ã®ã¿å‰²ã‚Šå½“ã¦ã‚‹ã“ã¨ãŒã§ãã¾ã
msgid "Constants cannot be modified."
msgstr "定数ã¯å¤‰æ›´ã§ãã¾ã›ã‚“。"
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "アニメーションプレーヤーã¯ä»–ã®ãƒ—レーヤーã ã‘ã«ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’é©ç”¨ã™ã‚‹ã“ã¨"
+#~ "ã¯ã§ãã¾ã›ã‚“。"
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "クリップボードãŒç©ºã§ã™"
+
#~ msgid ""
#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
#~ msgstr "InterpolatedCamera ã¯å»ƒæ­¢äºˆå®šã§ã‚ã‚Šã€Godot 4.0ã§é™¤åŽ»ã•ã‚Œã¾ã™ã€‚"
diff --git a/editor/translations/ka.po b/editor/translations/ka.po
index ce5c6dc032..587624651a 100644
--- a/editor/translations/ka.po
+++ b/editor/translations/ka.po
@@ -436,10 +436,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "შეუძლებელირდáƒáƒáƒ›áƒáƒ¢áƒ áƒáƒ®áƒáƒšáƒ˜ ჩáƒáƒœáƒáƒ¬áƒ”რი ფესვის გáƒáƒ áƒ”შე"
@@ -491,9 +487,9 @@ msgid "Anim Move Keys"
msgstr "áƒáƒœáƒ˜áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ გáƒáƒ¡áƒáƒ¦áƒ”ბების გáƒáƒ“áƒáƒáƒ“გილებáƒ"
#: editor/animation_track_editor.cpp
-#, fuzzy
-msgid "Clipboard is empty"
-msgstr "ბუფერი ცáƒáƒ áƒ˜áƒ”ლიáƒ"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr ""
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2529,7 +2525,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11863,10 +11859,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
@@ -12909,6 +12901,10 @@ msgid "Constants cannot be modified."
msgstr ""
#, fuzzy
+#~ msgid "Clipboard is empty"
+#~ msgstr "ბუფერი ცáƒáƒ áƒ˜áƒ”ლიáƒ"
+
+#, fuzzy
#~ msgid "Add initial export..."
#~ msgstr "სáƒáƒ§áƒ•áƒáƒ áƒšáƒ”ბი:"
diff --git a/editor/translations/km.po b/editor/translations/km.po
index ee77bab308..fe396cf590 100644
--- a/editor/translations/km.po
+++ b/editor/translations/km.po
@@ -402,10 +402,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr ""
@@ -450,7 +446,8 @@ msgid "Anim Move Keys"
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
msgstr ""
#: editor/animation_track_editor.cpp
@@ -2409,7 +2406,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11481,10 +11478,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
diff --git a/editor/translations/ko.po b/editor/translations/ko.po
index 9224ef5e65..ec9fed24ca 100644
--- a/editor/translations/ko.po
+++ b/editor/translations/ko.po
@@ -429,12 +429,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "애니메ì´ì…˜ íŠ¸ëž™ì€ ì˜¤ì§ AnimationPlayer 노드만 가리킬 수 있습니다."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-"애니메ì´ì…˜ 플레ì´ì–´ëŠ” ìžì‹ ì´ ì•„ë‹Œ 다른 플레ì´ì–´ì—만 애니메ì´ì…˜ì„ 부여할 수 있"
-"습니다."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "루트 ì—†ì´ ìƒˆ íŠ¸ëž™ì„ ì¶”ê°€í•  수 ì—†ìŒ"
@@ -479,8 +473,9 @@ msgid "Anim Move Keys"
msgstr "애니메ì´ì…˜ 키 ì´ë™"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "í´ë¦½ë³´ë“œê°€ 비었ìŒ"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "í´ë¦½ë³´ë“œê°€ 비었습니다!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2510,7 +2505,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "ë„기 ì „ì— í•´ë‹¹ ì”¬ì˜ ë³€ê²½ ì‚¬í•­ì„ ì €ìž¥í• ê¹Œìš”?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr "프로ì íŠ¸ 매니저를 열기 ì „ì— í•´ë‹¹ ì”¬ì˜ ë³€ê²½ ì‚¬í•­ì„ ì €ìž¥í• ê¹Œìš”?"
#: editor/editor_node.cpp
@@ -11908,10 +11903,6 @@ msgid "Can't copy the function node."
msgstr "함수 노드를 복사할 수 없습니다."
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "í´ë¦½ë³´ë“œê°€ 비었습니다!"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "비주얼 스í¬ë¦½íŠ¸ 노드 붙여넣기"
@@ -13071,6 +13062,14 @@ msgstr "Varyingì€ ê¼­ì§“ì  í•¨ìˆ˜ì—만 지정할 수 있습니다."
msgid "Constants cannot be modified."
msgstr "ìƒìˆ˜ëŠ” 수정할 수 없습니다."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "애니메ì´ì…˜ 플레ì´ì–´ëŠ” ìžì‹ ì´ ì•„ë‹Œ 다른 플레ì´ì–´ì—만 애니메ì´ì…˜ì„ 부여할 "
+#~ "수 있습니다."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "í´ë¦½ë³´ë“œê°€ 비었ìŒ"
+
#~ msgid ""
#~ "Godot editor was built without ray tracing support; lightmaps can't be "
#~ "baked.\n"
diff --git a/editor/translations/lt.po b/editor/translations/lt.po
index d4520d2d76..6df1f44cfb 100644
--- a/editor/translations/lt.po
+++ b/editor/translations/lt.po
@@ -418,10 +418,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Animacijos įrašai gali nurodyti į AnimacijosGrotuvo mazgus."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr "Animacijos grotuvas negali animuoti savęs, tik kitus grotuvus."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Nėra galimybės pridėti naują įrašą be root"
@@ -467,7 +463,8 @@ msgid "Anim Move Keys"
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
msgstr ""
#: editor/animation_track_editor.cpp
@@ -2481,7 +2478,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11833,10 +11830,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
@@ -12880,6 +12873,9 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr "Animacijos grotuvas negali animuoti savęs, tik kitus grotuvus."
+
#, fuzzy
#~ msgid "Add initial export..."
#~ msgstr "MÄ—gstamiausi:"
diff --git a/editor/translations/lv.po b/editor/translations/lv.po
index 360b8bcb8f..8c8a0011c7 100644
--- a/editor/translations/lv.po
+++ b/editor/translations/lv.po
@@ -413,10 +413,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "AnimÄcijas celiņi var norÄdÄ«t tikai uz AnimationPlayer mezgliem."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr "AnimÄcijas atskaņotÄjs nevar animÄ“t pats sevi, tikai citi spÄ“lÄ“tÄji."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Nevar izveidot jaunu celiņu bez saknes"
@@ -461,8 +457,9 @@ msgid "Anim Move Keys"
msgstr "Anim PÄrvietot AtslÄ“gas"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Starpliktuve ir tukša"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr ""
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2455,7 +2452,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11641,10 +11638,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
@@ -12677,6 +12670,13 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "AnimÄcijas atskaņotÄjs nevar animÄ“t pats sevi, tikai citi spÄ“lÄ“tÄji."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Starpliktuve ir tukša"
+
#~ msgid "Add initial export..."
#~ msgstr "Pievienot sÄkuma eksportu..."
diff --git a/editor/translations/mi.po b/editor/translations/mi.po
index 17b666c0e6..36a93be0ee 100644
--- a/editor/translations/mi.po
+++ b/editor/translations/mi.po
@@ -394,10 +394,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr ""
@@ -442,7 +438,8 @@ msgid "Anim Move Keys"
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
msgstr ""
#: editor/animation_track_editor.cpp
@@ -2401,7 +2398,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11473,10 +11470,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
diff --git a/editor/translations/mk.po b/editor/translations/mk.po
index 0443bd589e..7e5aa06f3c 100644
--- a/editor/translations/mk.po
+++ b/editor/translations/mk.po
@@ -401,10 +401,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr ""
@@ -449,7 +445,8 @@ msgid "Anim Move Keys"
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
msgstr ""
#: editor/animation_track_editor.cpp
@@ -2408,7 +2405,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11480,10 +11477,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
diff --git a/editor/translations/ml.po b/editor/translations/ml.po
index a25540d2cd..3919011ade 100644
--- a/editor/translations/ml.po
+++ b/editor/translations/ml.po
@@ -404,10 +404,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr ""
@@ -452,7 +448,8 @@ msgid "Anim Move Keys"
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
msgstr ""
#: editor/animation_track_editor.cpp
@@ -2413,7 +2410,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11490,10 +11487,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
diff --git a/editor/translations/mr.po b/editor/translations/mr.po
index 7e6f8f5cc5..4d81595cb1 100644
--- a/editor/translations/mr.po
+++ b/editor/translations/mr.po
@@ -401,10 +401,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr ""
@@ -449,7 +445,8 @@ msgid "Anim Move Keys"
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
msgstr ""
#: editor/animation_track_editor.cpp
@@ -2408,7 +2405,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11481,10 +11478,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
diff --git a/editor/translations/ms.po b/editor/translations/ms.po
index 82a4443b24..6226d644a3 100644
--- a/editor/translations/ms.po
+++ b/editor/translations/ms.po
@@ -413,11 +413,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Trek animasi hanya dapat ditujukan kepada nod AnimationPlayer."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-"Pemain animasi tidak boleh animasikan dirinya sendiri, hanya pemain lain."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Tidak boleh menambah trek baru tanpa satu akar"
@@ -462,8 +457,9 @@ msgid "Anim Move Keys"
msgstr "Kunci Gerak Anim"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Papan klip kosong"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr ""
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2514,7 +2510,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "Simpan perubahan pada adegan berikut sebelum keluar?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr "Simpan perubahan adegan berikut sebelum membuka Pengurus Projek?"
#: editor/editor_node.cpp
@@ -11864,10 +11860,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
@@ -12889,6 +12881,13 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "Pemain animasi tidak boleh animasikan dirinya sendiri, hanya pemain lain."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Papan klip kosong"
+
#~ msgid "No"
#~ msgstr "Tidak"
diff --git a/editor/translations/nb.po b/editor/translations/nb.po
index f040c4ca0e..042ee8d26f 100644
--- a/editor/translations/nb.po
+++ b/editor/translations/nb.po
@@ -422,11 +422,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Animasjonsspor kan kun peke på AnimationPlayer-noder."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-"En animansjonsavspiller kan ikke animere seg selv, kun andre avspillere."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Ikke mulig å legge til et nytt spor uten en rot"
@@ -471,8 +466,9 @@ msgid "Anim Move Keys"
msgstr "Anim Flytt Nøkler"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Utklippstavlen er tom"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "Utklippsbordet er tomt!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2600,7 +2596,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "Lagre endring til følgende scene(r) før avslutting?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr "Lagre endringer til følgende scene(r) før åpning av Prosjekt-Manager?"
#: editor/editor_node.cpp
@@ -12364,10 +12360,6 @@ msgid "Can't copy the function node."
msgstr "Kan ikke kopiere funksjonsnoden."
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "Utklippsbordet er tomt!"
-
-#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
msgid "Paste VisualScript Nodes"
msgstr "Lim inn Noder"
@@ -13420,6 +13412,13 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Konstanter kan ikke endres."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "En animansjonsavspiller kan ikke animere seg selv, kun andre avspillere."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Utklippstavlen er tom"
+
#~ msgid "No"
#~ msgstr "Nei"
diff --git a/editor/translations/nl.po b/editor/translations/nl.po
index 616c3ae69a..2410cd5ad0 100644
--- a/editor/translations/nl.po
+++ b/editor/translations/nl.po
@@ -451,10 +451,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Animatiesporen kunnen alleen verwijzen naar AnimatiePlayer-knopen."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr "Een animatiespeler kan zichzelf niet animeren, alleen andere spelers."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Niet mogelijk om een nieuwe track toe te voegen zonder een root"
@@ -499,8 +495,9 @@ msgid "Anim Move Keys"
msgstr "Anim Verplaats Keys"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Klembord is leeg"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "Plakbord is leeg!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2550,7 +2547,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "Wijzigen aan de volgende scène(s) opslaan voor het afsluiten?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
"Wijzigen aan de volgende scène(s) opslaan voor het openen van Projectbeheer?"
@@ -12047,10 +12044,6 @@ msgid "Can't copy the function node."
msgstr "Kan het functieknoop niet kopiëren."
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "Plakbord is leeg!"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "Plak VisualScipt knoopen"
@@ -13237,6 +13230,13 @@ msgstr "Varyings kunnen alleen worden toegewezenin vertex functies."
msgid "Constants cannot be modified."
msgstr "Constanten kunnen niet worden aangepast."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "Een animatiespeler kan zichzelf niet animeren, alleen andere spelers."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Klembord is leeg"
+
#~ msgid "No"
#~ msgstr "Nee"
diff --git a/editor/translations/or.po b/editor/translations/or.po
index 58214daf10..87528cdac5 100644
--- a/editor/translations/or.po
+++ b/editor/translations/or.po
@@ -400,10 +400,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr ""
@@ -448,7 +444,8 @@ msgid "Anim Move Keys"
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
msgstr ""
#: editor/animation_track_editor.cpp
@@ -2407,7 +2404,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11479,10 +11476,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
diff --git a/editor/translations/pl.po b/editor/translations/pl.po
index 83d36da5bb..3c51593e02 100644
--- a/editor/translations/pl.po
+++ b/editor/translations/pl.po
@@ -17,7 +17,7 @@
# Maksymilian Świąć <maksymilian.swiac@gmail.com>, 2017-2018.
# Mietek Szcześniak <ravaging@go2.pl>, 2016.
# NeverK <neverkoxu@gmail.com>, 2018, 2019, 2020.
-# Rafal Brozio <rafal.brozio@gmail.com>, 2016, 2019, 2020.
+# Rafal Brozio <rafal.brozio@gmail.com>, 2016, 2019, 2020, 2021.
# Rafał Ziemniak <synaptykq@gmail.com>, 2017.
# RM <synaptykq@gmail.com>, 2018, 2020.
# Sebastian Krzyszkowiak <dos@dosowisko.net>, 2017.
@@ -52,8 +52,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-06-20 13:35+0000\n"
-"Last-Translator: Tomek <kobewi4e@gmail.com>\n"
+"PO-Revision-Date: 2021-07-05 14:32+0000\n"
+"Last-Translator: Rafal Brozio <rafal.brozio@gmail.com>\n"
"Language-Team: Polish <https://hosted.weblate.org/projects/godot-engine/"
"godot/pl/>\n"
"Language: pl\n"
@@ -62,7 +62,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
"|| n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 4.7\n"
+"X-Generator: Weblate 4.8-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -454,11 +454,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Ścieżki animacji mogą wskazywać tylko na węzły AnimationPlayer."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-"AnimationPlayer nie może animować sam siebie, tylko inne węzły tego typu."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Nie da się dodać nowej ścieżki bez korzenia"
@@ -503,8 +498,9 @@ msgid "Anim Move Keys"
msgstr "Przemieść klucze animacji"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Schowek jest pusty"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "Schowek jest pusty!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2538,7 +2534,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "Czy zapisać zmiany w aktualnej scenie/scenach przed wyjściem?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
"Zapisać zmiany w następujących scenach przed otwarciem menedżera projektów?"
@@ -4700,7 +4696,7 @@ msgstr "Otwórz w inspektorze"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Display list of animations in player."
-msgstr "Wyświetl listę animacji w odtwarzaczu."
+msgstr "Pokaż listę animacji w odtwarzaczu."
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Autoplay on Load"
@@ -12019,10 +12015,6 @@ msgid "Can't copy the function node."
msgstr "Nie można skopiować węzła funkcji."
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "Schowek jest pusty!"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "Wklej węzeł VisualScript"
@@ -13223,6 +13215,13 @@ msgstr "Varying może być przypisane tylko w funkcji wierzchołków."
msgid "Constants cannot be modified."
msgstr "Stałe nie mogą być modyfikowane."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "AnimationPlayer nie może animować sam siebie, tylko inne węzły tego typu."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Schowek jest pusty"
+
#~ msgid ""
#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
#~ msgstr ""
diff --git a/editor/translations/pr.po b/editor/translations/pr.po
index e308deb01b..675c9cf506 100644
--- a/editor/translations/pr.po
+++ b/editor/translations/pr.po
@@ -427,10 +427,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr ""
@@ -476,7 +472,8 @@ msgid "Anim Move Keys"
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
msgstr ""
#: editor/animation_track_editor.cpp
@@ -2487,7 +2484,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11907,10 +11904,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
msgid "Paste VisualScript Nodes"
msgstr "Paste yer Node"
diff --git a/editor/translations/pt.po b/editor/translations/pt.po
index d2db134026..17b1861821 100644
--- a/editor/translations/pt.po
+++ b/editor/translations/pt.po
@@ -18,12 +18,13 @@
# Manuela Silva <mmsrs@sky.com>, 2020.
# Murilo Gama <murilovsky2030@gmail.com>, 2020.
# Ricardo Subtil <ricasubtil@gmail.com>, 2020.
+# André Silva <andre.olivais@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-05-18 14:51+0000\n"
-"Last-Translator: João Lopes <linux-man@hotmail.com>\n"
+"PO-Revision-Date: 2021-07-03 10:33+0000\n"
+"Last-Translator: André Silva <andre.olivais@gmail.com>\n"
"Language-Team: Portuguese <https://hosted.weblate.org/projects/godot-engine/"
"godot/pt/>\n"
"Language: pt\n"
@@ -31,7 +32,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.7-dev\n"
+"X-Generator: Weblate 4.8-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -424,12 +425,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Pistas de Animação só podem apontar a nós AnimationPlayer."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-"Um reprodutor de animação não se pode animar a ele próprio, apenas a outros "
-"reprodutores."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Não é possível adicionar nova pista sem uma raiz"
@@ -474,8 +469,9 @@ msgid "Anim Move Keys"
msgstr "Anim Mover Chaves"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Ãrea de Transferência está vazia"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "Ãrea de Transferência está vazia!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -1132,7 +1128,7 @@ msgstr "Agradecimentos da Comunidade Godot!"
#: editor/editor_about.cpp editor/editor_node.cpp editor/project_manager.cpp
msgid "Click to copy."
-msgstr ""
+msgstr "Clique para copiar."
#: editor/editor_about.cpp
msgid "Godot Engine contributors"
@@ -2516,7 +2512,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "Guardar alterações da(s) seguinte(s) cena(s) antes de sair?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
"Guardar alterações da(s) seguinte(s) cena(s) antes de abrir o Gestor de "
"Projeto?"
@@ -11985,10 +11981,6 @@ msgid "Can't copy the function node."
msgstr "Não consigo copiar o nó função."
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "Ãrea de Transferência está vazia!"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "Colar Nós VisualScript"
@@ -13181,6 +13173,14 @@ msgstr "Variações só podem ser atribuídas na função vértice."
msgid "Constants cannot be modified."
msgstr "Constantes não podem ser modificadas."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "Um reprodutor de animação não se pode animar a ele próprio, apenas a "
+#~ "outros reprodutores."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Ãrea de Transferência está vazia"
+
#~ msgid ""
#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
#~ msgstr "InterpolatedCamerda foi descontinuada e será removida no Godot 4.0."
diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po
index 49a7b43571..e79dd0fa19 100644
--- a/editor/translations/pt_BR.po
+++ b/editor/translations/pt_BR.po
@@ -522,11 +522,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Faixas de animação só podem apontar para nós AnimationPlayer."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-"Um tocador de animação não pode animar a si mesmo, apenas outros tocadores."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Não é possível adicionar uma nova trilha sem uma raiz"
@@ -572,8 +567,9 @@ msgid "Anim Move Keys"
msgstr "Mover Chaves da Anim"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Ãrea de transferência vazia"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "Ãrea de transferência vazia!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2613,7 +2609,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "Salvar alterações na(s) seguinte(s) cena(s) antes de sair?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
"Salvar alterações na(s) seguinte(s) cena(s) antes de abrir o Gerenciador de "
"Projetos?"
@@ -12107,10 +12103,6 @@ msgid "Can't copy the function node."
msgstr "Não é possível copiar o nó de função."
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "Ãrea de transferência vazia!"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "Colar Nodes VisualScript"
@@ -13315,6 +13307,14 @@ msgstr "Variáveis só podem ser atribuídas na função de vértice."
msgid "Constants cannot be modified."
msgstr "Constantes não podem serem modificadas."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "Um tocador de animação não pode animar a si mesmo, apenas outros "
+#~ "tocadores."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Ãrea de transferência vazia"
+
#~ msgid ""
#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
#~ msgstr "IntepolatedCamera foi depreciada e será removida no Godot 4.0."
diff --git a/editor/translations/ro.po b/editor/translations/ro.po
index ec89b47e96..7ac06fc1b1 100644
--- a/editor/translations/ro.po
+++ b/editor/translations/ro.po
@@ -420,12 +420,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Pistele de animație pot direcționa numai nodurilor AnimațieJucător."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-"Un player de animatie nu se poate anima insusi, doar alti playeri de "
-"animatie."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Nu este posibil să fie adăugată o nouă pistă fără a avea o rădăcină"
@@ -470,8 +464,9 @@ msgid "Anim Move Keys"
msgstr "Anim Mutați Cheie"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Clip-board de resurse gol"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr ""
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2520,7 +2515,7 @@ msgstr ""
"Salvezi modificările făcute în urmatoarea(le) scenă(e) înainte să închizi?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
"Salvezi modificările făcute în urmatoarea(le) scenă(e) înainte să deschizi "
"Managerul de Proiect?"
@@ -12046,10 +12041,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
@@ -13088,6 +13079,14 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "Un player de animatie nu se poate anima insusi, doar alti playeri de "
+#~ "animatie."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Clip-board de resurse gol"
+
#~ msgid "No"
#~ msgstr "Nu"
diff --git a/editor/translations/ru.po b/editor/translations/ru.po
index 0da9285077..4b56d21383 100644
--- a/editor/translations/ru.po
+++ b/editor/translations/ru.po
@@ -96,11 +96,12 @@
# IindinAndEdresia <kapitan_pol@inbox.ru>, 2021.
# Bualma Show <appleaidar6@gmail.com>, 2021.
# enderlorde <madel.laboratories@gmail.com>, 2021.
+# Олег Довгер <oleg.a.dovger@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-06-27 07:10+0000\n"
+"PO-Revision-Date: 2021-07-13 06:13+0000\n"
"Last-Translator: Danil Alexeev <danil@alexeev.xyz>\n"
"Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/"
"godot/ru/>\n"
@@ -110,12 +111,13 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 4.7.1-dev\n"
+"X-Generator: Weblate 4.7.2-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Invalid type argument to convert(), use TYPE_* constants."
-msgstr "Ðеверный параметр типа Ð´Ð»Ñ convert(), иÑпользуйте конÑтанты TYPE_*."
+msgstr ""
+"ÐедопуÑтимый аргумент type Ð´Ð»Ñ convert(), иÑпользуйте конÑтанты TYPE_*."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
@@ -502,10 +504,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Дорожки анимации могут указывать только на узлы типа AnimationPlayer."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr "Проигрыватель анимации не может анимировать Ñам ÑебÑ, только других."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "ÐÐµÐ»ÑŒÐ·Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸Ñ‚ÑŒ новую дорожку без корневого узла"
@@ -550,8 +548,9 @@ msgid "Anim Move Keys"
msgstr "ПеремеÑтить ключи"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Буфер обмена пуÑÑ‚"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "Буфер обмена пуÑÑ‚!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2592,7 +2591,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "Сохранить Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² Ñледующей Ñцене(Ñ‹) перед выходом?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
"Сохранить Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² Ñледующей Ñцене(Ñ‹) перед открытием менеджера проектов?"
@@ -12071,10 +12070,6 @@ msgid "Can't copy the function node."
msgstr "Ðе удаётÑÑ ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ узел функции."
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "Буфер обмена пуÑÑ‚!"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "Ð’Ñтавить узлы VisualScript"
@@ -13267,6 +13262,13 @@ msgstr "Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð³ÑƒÑ‚ быть назначены только Ð
msgid "Constants cannot be modified."
msgstr "КонÑтанты не могут быть изменены."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "Проигрыватель анимации не может анимировать Ñам ÑебÑ, только других."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Буфер обмена пуÑÑ‚"
+
#~ msgid ""
#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
#~ msgstr "InterpolatedCamera уÑтарела и будет удалена в Godot 4.0."
diff --git a/editor/translations/si.po b/editor/translations/si.po
index 89c1b2ffc8..a5586af274 100644
--- a/editor/translations/si.po
+++ b/editor/translations/si.po
@@ -418,10 +418,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "AnimationPlayer පුරුක් සදහ෠පමණක් සජීවීකරණ ලුහුබදින්නන් එක් කළ à·„à·à¶š."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr ""
@@ -470,7 +466,8 @@ msgid "Anim Move Keys"
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
msgstr ""
#: editor/animation_track_editor.cpp
@@ -2433,7 +2430,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11573,10 +11570,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
diff --git a/editor/translations/sk.po b/editor/translations/sk.po
index 5d5b9cba9b..d97e1321ef 100644
--- a/editor/translations/sk.po
+++ b/editor/translations/sk.po
@@ -11,12 +11,13 @@
# Richard Urban <redasuio1@gmail.com>, 2020.
# Anonymous <noreply@weblate.org>, 2020.
# Mario-projects-dev <m.vitek.mv@gmail.com>, 2021.
+# Eliška Fichnová <eliska@fichna.sk>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-04-11 22:02+0000\n"
-"Last-Translator: Mario-projects-dev <m.vitek.mv@gmail.com>\n"
+"PO-Revision-Date: 2021-07-07 15:34+0000\n"
+"Last-Translator: Eliška Fichnová <eliska@fichna.sk>\n"
"Language-Team: Slovak <https://hosted.weblate.org/projects/godot-engine/"
"godot/sk/>\n"
"Language: sk\n"
@@ -24,7 +25,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
-"X-Generator: Weblate 4.6-dev\n"
+"X-Generator: Weblate 4.8-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -414,10 +415,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Track-y Animácií môžu ukazovať iba na node-y AnimationPlayer."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr "Animation player sa nemôže naanimovať sám, iba ostatné player-y."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Není možné pridať nový track bez root-u"
@@ -462,8 +459,9 @@ msgid "Anim Move Keys"
msgstr "Pohybové kľúÄe Animácie"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Schránka je prázdna"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr ""
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -1116,7 +1114,7 @@ msgstr "VÄaka z Godot komunity!"
#: editor/editor_about.cpp editor/editor_node.cpp editor/project_manager.cpp
msgid "Click to copy."
-msgstr ""
+msgstr "Klikni na skopírovanie."
#: editor/editor_about.cpp
msgid "Godot Engine contributors"
@@ -1610,13 +1608,12 @@ msgstr ""
"Etc' v Nastaveniach Projektu."
#: editor/editor_export.cpp
-#, fuzzy
msgid ""
"Target platform requires 'ETC2' or 'PVRTC' texture compression for GLES3. "
"Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings."
msgstr ""
-"Target platforma potrebuje 'ETC2' kompresor textúr pre GLES3. Povoliť'Import "
-"Etc 2' v Nastaveniach Projektu."
+"Cieľová platforma potrebuje 'ETC2' alebo 'PVRTC' kompresor textúr pre GLES3. "
+"Povoľte 'Import Etc 2' alebo 'Import Pvrtc' v Nastaveniach Projektu."
#: editor/editor_export.cpp
#, fuzzy
@@ -2309,6 +2306,8 @@ msgid ""
"An error occurred while trying to save the editor layout.\n"
"Make sure the editor's user data path is writable."
msgstr ""
+"Nastala chyba pri pokuse o uloženie rozloženia editoru.\n"
+"Uistite sa, že cesta uživateľských dát editoru je zapisovateľná."
#: editor/editor_node.cpp
msgid ""
@@ -2316,15 +2315,17 @@ msgid ""
"To restore the Default layout to its base settings, use the Delete Layout "
"option and delete the Default layout."
msgstr ""
+"Prednastavené rozloženie editoru prepísané.\n"
+"Na obnovenie Prednastaveného rozloženia na základné nastavenia, použite "
+"možnosť Vymazať Rozloženie a vymažte Prednastavené rozloženie."
#: editor/editor_node.cpp
msgid "Layout name not found!"
msgstr "Meno Layout-u sa nenašlo!"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Restored the Default layout to its base settings."
-msgstr "Obnovené predvolené rozloženie na základné nastavenia."
+msgstr "Predvolené rozloženie bolo obnovené na základné nastavenia."
#: editor/editor_node.cpp
msgid ""
@@ -2381,7 +2382,7 @@ msgstr "Nieje definovaná žiadna scéna na spustenie."
#: editor/editor_node.cpp
msgid "Save scene before running..."
-msgstr ""
+msgstr "Uložiť scénu pred spustením..."
#: editor/editor_node.cpp
msgid "Could not start subprocess!"
@@ -2496,7 +2497,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "UložiÅ¥ zmeny do nasledujúcich scén pred ukonÄením?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr "Uložiť zmeny nasledujúcich scén pred otvorením Manažéra Projektov?"
#: editor/editor_node.cpp
@@ -2525,24 +2526,22 @@ msgstr ""
"Addon plugin nie je možné povoliť pri: '% s' analýze konfigurácie zlyhalo."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Unable to find script field for addon plugin at: '%s'."
-msgstr ""
-"Nepodarilo sa nájsť script field pre addon plugin v: 'res://addons/%s'."
+msgstr "Nepodarilo sa nájsť pole skriptu pre addon plugin v: '%s'."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
msgstr "Nepodarilo sa naÄítaÅ¥ addon script z cesty: '%s'."
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"Unable to load addon script from path: '%s'. This might be due to a code "
"error in that script.\n"
"Disabling the addon at '%s' to prevent further errors."
msgstr ""
-"Nepodarilo sa nájsť addon script z cesty: '%s' Vyzerá to tak že by mohol byť "
-"problém v kóde, prosím skontrolujte syntax."
+"Nebolo možné naÄítaÅ¥ addon skript z cesty: '%s'. Toto môže byÅ¥ spôsobené "
+"chybou kódu v skripte.\n"
+"Deaktivujem addon z '%s', aby sa prediÅ¡lo Äalším chybám."
#: editor/editor_node.cpp
msgid ""
@@ -2985,7 +2984,7 @@ msgstr "O nás"
#: editor/editor_node.cpp
msgid "Support Godot Development"
-msgstr ""
+msgstr "Podporte vývoj Godot"
#: editor/editor_node.cpp
msgid "Play the project."
@@ -3127,21 +3126,22 @@ msgid "Open & Run a Script"
msgstr "Otvoriť a vykonať skript"
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"The following files are newer on disk.\n"
"What action should be taken?"
-msgstr "Nasledovné súbory sa nepodarilo extrahovať z balíka:"
+msgstr ""
+"Nasledujúce súbory majú novšiu verziu na disku.\n"
+"Aká akcia sa má vykonať?"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Reload"
-msgstr ""
+msgstr "Znovu naÄítaÅ¥"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Resave"
-msgstr ""
+msgstr "Znovu uložiť"
#: editor/editor_node.cpp
msgid "New Inherited"
@@ -3670,6 +3670,8 @@ msgstr ""
msgid ""
"Importing has been disabled for this file, so it can't be opened for editing."
msgstr ""
+"Importovanie bolo zablokované pre tento súbor, Äiže nemôže byÅ¥ otvorený pre "
+"úpravy."
#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
@@ -3716,6 +3718,12 @@ msgid ""
"\n"
"Do you wish to overwrite them?"
msgstr ""
+"Nasledujúce súbory alebo zložky sú v konflikte s položkami v cieľovom "
+"umiestnení '%s':\n"
+"\n"
+"%s\n"
+"\n"
+"Prajete si ich prepísať?"
#: editor/filesystem_dock.cpp
msgid "Renaming file:"
@@ -3796,9 +3804,8 @@ msgid "Duplicate..."
msgstr "Duplikovať..."
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Move to Trash"
-msgstr "Presunúť AutoLoad-y"
+msgstr "Presunúť do odpadkov"
#: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Rename..."
@@ -3909,19 +3916,16 @@ msgid "Searching..."
msgstr "Vyhľadávam..."
#: editor/find_in_files.cpp
-#, fuzzy
msgid "%d match in %d file."
-msgstr "%d zhody."
+msgstr "%d zhoda v %d súbore."
#: editor/find_in_files.cpp
-#, fuzzy
msgid "%d matches in %d file."
-msgstr "%d zhody."
+msgstr "%d zhôd v % súbore."
#: editor/find_in_files.cpp
-#, fuzzy
msgid "%d matches in %d files."
-msgstr "%d zhody."
+msgstr "%d zhôd v %d súboroch."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4058,23 +4062,20 @@ msgid "Saving..."
msgstr "Ukladám..."
#: editor/import_defaults_editor.cpp
-#, fuzzy
msgid "Select Importer"
-msgstr "Vybrať Režim"
+msgstr "Vybrať Importér"
#: editor/import_defaults_editor.cpp
-#, fuzzy
msgid "Importer:"
-msgstr "Import"
+msgstr "Importér:"
#: editor/import_defaults_editor.cpp
-#, fuzzy
msgid "Reset to Defaults"
-msgstr "NaÄítaÅ¥ predvolené"
+msgstr "Obnoviť na východzie"
#: editor/import_dock.cpp
msgid "Keep File (No Import)"
-msgstr ""
+msgstr "Ponechať súbor (bez importu)"
#: editor/import_dock.cpp
msgid "%d Files"
@@ -5040,9 +5041,8 @@ msgid "Got:"
msgstr "Má:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Failed SHA-256 hash check"
-msgstr "Zlyhalo sha256 hash check"
+msgstr "Zlyhalo overenie SHA-256 hashu"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Asset Download Error:"
@@ -11938,10 +11938,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
msgid "Paste VisualScript Nodes"
msgstr "Vložiť"
@@ -13001,6 +12997,12 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr "Animation player sa nemôže naanimovať sám, iba ostatné player-y."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Schránka je prázdna"
+
#~ msgid "No"
#~ msgstr "Nie"
diff --git a/editor/translations/sl.po b/editor/translations/sl.po
index 2ac453123c..07bd33c389 100644
--- a/editor/translations/sl.po
+++ b/editor/translations/sl.po
@@ -440,10 +440,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr ""
@@ -493,7 +489,8 @@ msgid "Anim Move Keys"
msgstr "Animacija Premakni kljuÄ"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
msgstr ""
#: editor/animation_track_editor.cpp
@@ -2606,7 +2603,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "Shranim spremembe na sledeÄih scenah pred zaprtjem?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
"Shranim spremembe na sledeÄih scenah pred odpiranjem Upravljalnika Projekta?"
@@ -12321,10 +12318,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
diff --git a/editor/translations/sq.po b/editor/translations/sq.po
index 4409a6f48a..49a42b5553 100644
--- a/editor/translations/sq.po
+++ b/editor/translations/sq.po
@@ -407,10 +407,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr ""
@@ -455,8 +451,9 @@ msgid "Anim Move Keys"
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Clipboard-i është bosh"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr ""
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2548,7 +2545,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "Ruaj ndryshimet nga skenat e mëposhtme përpara se të dalësh?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
"Ruaj ndryshimet ne skenat e mëposhtme para se të hapësh Menaxherin e "
"Projekteve?"
@@ -11927,10 +11924,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
@@ -12962,6 +12955,9 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "Clipboard is empty"
+#~ msgstr "Clipboard-i është bosh"
+
#~ msgid "No"
#~ msgstr "Jo"
diff --git a/editor/translations/sr_Cyrl.po b/editor/translations/sr_Cyrl.po
index 3ba1c674a3..53fb04b3e4 100644
--- a/editor/translations/sr_Cyrl.po
+++ b/editor/translations/sr_Cyrl.po
@@ -457,11 +457,6 @@ msgstr "Ðнимационе траке могу Ñамо уÑмеравати Ð
#: editor/animation_track_editor.cpp
#, fuzzy
-msgid "An animation player can't animate itself, only other players."
-msgstr "Ðнимациони плејер не може анимирати Ñамог Ñебе, Ñамо друге плејере."
-
-#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Not possible to add a new track without a root"
msgstr "Ðије могуже додати нову траку без корена"
@@ -515,9 +510,9 @@ msgid "Anim Move Keys"
msgstr "Помери кључеве"
#: editor/animation_track_editor.cpp
-#, fuzzy
-msgid "Clipboard is empty"
-msgstr "Ðема реÑурÑа за копирање!"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr ""
#: editor/animation_track_editor.cpp
#, fuzzy
@@ -2727,7 +2722,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "Сачувај промене тренутне Ñцене/а пре излазка?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr "Сачувај промене тренутне Ñцене/а пре отварање менаџера пројекта?"
#: editor/editor_node.cpp
@@ -13503,10 +13498,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
@@ -14817,6 +14808,14 @@ msgstr "Варијације могу Ñамо бити одређене у фу
msgid "Constants cannot be modified."
msgstr "КонÑтанте није могуће мењати."
+#, fuzzy
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr "Ðнимациони плејер не може анимирати Ñамог Ñебе, Ñамо друге плејере."
+
+#, fuzzy
+#~ msgid "Clipboard is empty"
+#~ msgstr "Ðема реÑурÑа за копирање!"
+
#~ msgid "No"
#~ msgstr "Ðе"
diff --git a/editor/translations/sr_Latn.po b/editor/translations/sr_Latn.po
index fcab84a2bf..0a90379b41 100644
--- a/editor/translations/sr_Latn.po
+++ b/editor/translations/sr_Latn.po
@@ -422,10 +422,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr ""
@@ -473,7 +469,8 @@ msgid "Anim Move Keys"
msgstr "Animacija Pomjeri KljuÄeve"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
msgstr ""
#: editor/animation_track_editor.cpp
@@ -2446,7 +2443,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11665,10 +11662,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
diff --git a/editor/translations/sv.po b/editor/translations/sv.po
index c5cad10f66..0c5db25a9a 100644
--- a/editor/translations/sv.po
+++ b/editor/translations/sv.po
@@ -22,12 +22,13 @@
# Shaggy <anton_christoffersson@hotmail.com>, 2020.
# Marcus Toftedahl <marcus.toftedahl@his.se>, 2020.
# Alex25820 <Alexander_sjogren@hotmail.se>, 2021.
+# Leon <joel.lundborg@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-05-03 21:29+0000\n"
-"Last-Translator: Alex25820 <Alexander_sjogren@hotmail.se>\n"
+"PO-Revision-Date: 2021-07-13 06:13+0000\n"
+"Last-Translator: Leon <joel.lundborg@gmail.com>\n"
"Language-Team: Swedish <https://hosted.weblate.org/projects/godot-engine/"
"godot/sv/>\n"
"Language: sv\n"
@@ -35,7 +36,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.7-dev\n"
+"X-Generator: Weblate 4.7.2-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -426,11 +427,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Animationsspår kan bara peka på AnimationsSpelar noder."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-"En animationsspelare kan inte animera sig själv, utan bara andra spelare."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Det är inte möjligt att lägga till ett nytt spår utan en rot-nod"
@@ -475,8 +471,9 @@ msgid "Anim Move Keys"
msgstr "Anim Flytta Nycklar"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Urklipp är tomt"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr ""
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -1134,7 +1131,7 @@ msgstr "Tack från Godot-gemenskapen!"
#: editor/editor_about.cpp editor/editor_node.cpp editor/project_manager.cpp
msgid "Click to copy."
-msgstr ""
+msgstr "Klicka för att kopiera."
#: editor/editor_about.cpp
msgid "Godot Engine contributors"
@@ -1667,14 +1664,12 @@ msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
msgstr "Den inbäddade PCK får inte vara större än 4 GiB på 32 bitars exporter."
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "3D Editor"
-msgstr "Öppna Skript-Redigerare"
+msgstr "Öppna 3D-redigeraren"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Script Editor"
-msgstr "Öppna Skript-Redigerare"
+msgstr "Öppna Skript-Redigeraren"
#: editor/editor_feature_profile.cpp
msgid "Asset Library"
@@ -1699,18 +1694,16 @@ msgid "Import Dock"
msgstr "Importera"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Erase profile '%s'? (no undo)"
-msgstr "Ersätt Alla"
+msgstr "Rensa profil ‘%s’? (Du kan inte ångra den här åtgärden )"
#: editor/editor_feature_profile.cpp
msgid "Profile must be a valid filename and must not contain '.'"
msgstr "Profilen måste ha ett giltigt filnamn och får inte innehålla '.'"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Profile with this name already exists."
-msgstr "En fil eller mapp med detta namn finns redan."
+msgstr "En profil med detta namn finns redan."
#: editor/editor_feature_profile.cpp
msgid "(Editor Disabled, Properties Disabled)"
@@ -1768,9 +1761,8 @@ msgid "Unset"
msgstr ""
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Current Profile:"
-msgstr "Nuvarande Version:"
+msgstr "Nuvarande Profil:"
#: editor/editor_feature_profile.cpp
msgid "Make Current"
@@ -1792,9 +1784,8 @@ msgid "Export"
msgstr "Exportera"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Available Profiles:"
-msgstr "Tillgängliga Noder:"
+msgstr "Tillgängliga Profiler:"
#: editor/editor_feature_profile.cpp
#, fuzzy
@@ -2561,7 +2552,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "Spara ändringar av följande scen(er) innan du avslutar?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
"Spara ändringar av följande scen(er) innan du öppnar Projekthanteraren?"
@@ -12074,10 +12065,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
@@ -13142,6 +13129,13 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "En animationsspelare kan inte animera sig själv, utan bara andra spelare."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Urklipp är tomt"
+
#~ msgid "No"
#~ msgstr "Nej"
diff --git a/editor/translations/ta.po b/editor/translations/ta.po
index c630966603..0c9022b097 100644
--- a/editor/translations/ta.po
+++ b/editor/translations/ta.po
@@ -421,10 +421,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr ""
@@ -472,7 +468,8 @@ msgid "Anim Move Keys"
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
msgstr ""
#: editor/animation_track_editor.cpp
@@ -2437,7 +2434,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11576,10 +11573,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
diff --git a/editor/translations/te.po b/editor/translations/te.po
index f1d857b911..8274d5520f 100644
--- a/editor/translations/te.po
+++ b/editor/translations/te.po
@@ -403,10 +403,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr ""
@@ -451,7 +447,8 @@ msgid "Anim Move Keys"
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
msgstr ""
#: editor/animation_track_editor.cpp
@@ -2410,7 +2407,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11483,10 +11480,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
diff --git a/editor/translations/th.po b/editor/translations/th.po
index 0edcf900b9..e9c2a80a49 100644
--- a/editor/translations/th.po
+++ b/editor/translations/th.po
@@ -427,10 +427,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "à¹à¸—ร็à¸à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¹ˆà¸™à¸ªà¸²à¸¡à¸²à¸£à¸–ติดไว้บนโหนด AnimationPlayer เท่านั้น"
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr "à¹à¸—ร็à¸à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¹ˆà¸™à¹„ม่สามารถเล่นตัวมันเองได้ à¹à¸•à¹ˆà¸ªà¸²à¸¡à¸²à¸£à¸–เล่นตัวเล่นอื่นได้"
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "ไม่สามารถที่จะเพิ่มà¹à¸—ร็à¸à¹ƒà¸«à¸¡à¹ˆà¹‚ดยที่ไม่มีรูท"
@@ -475,8 +471,9 @@ msgid "Anim Move Keys"
msgstr "ย้ายคีย์à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "คลิปบอร์ดว่างเปล่า"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "คลิปบอร์ดว่างเปล่า!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2483,7 +2480,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "บันทึà¸à¸‰à¸²à¸à¸•à¹ˆà¸­à¹„ปนี้à¸à¹ˆà¸­à¸™à¸›à¸´à¸”โปรà¹à¸à¸£à¸¡à¸«à¸£à¸·à¸­à¹„ม่?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr "บันทึà¸à¸‰à¸²à¸à¸•à¹ˆà¸­à¹„ปนี้à¸à¹ˆà¸­à¸™à¸à¸¥à¸±à¸šà¸ªà¸¹à¹ˆà¸•à¸±à¸§à¸ˆà¸±à¸”à¸à¸²à¸£à¹‚ปรเจà¸à¸•à¹Œà¸«à¸£à¸·à¸­à¹„ม่?"
#: editor/editor_node.cpp
@@ -11801,10 +11798,6 @@ msgid "Can't copy the function node."
msgstr "คัดลอà¸à¹‚หนดฟังà¸à¹Œà¸Šà¸±à¸™à¹„ม่ได้"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "คลิปบอร์ดว่างเปล่า!"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "วางโหนด VisualScript"
@@ -12913,6 +12906,12 @@ msgstr "Varyings สามารถà¸à¸³à¸«à¸™à¸”ในังà¸à¹Œà¸Šà¸±à¸™à¹€
msgid "Constants cannot be modified."
msgstr "ค่าคงที่ไม่สามารถà¹à¸à¹‰à¹„ขได้"
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr "à¹à¸—ร็à¸à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¹ˆà¸™à¹„ม่สามารถเล่นตัวมันเองได้ à¹à¸•à¹ˆà¸ªà¸²à¸¡à¸²à¸£à¸–เล่นตัวเล่นอื่นได้"
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "คลิปบอร์ดว่างเปล่า"
+
#~ msgid ""
#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
#~ msgstr "InterpolatedCamera เลิà¸à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¹à¸¥à¹‰à¸§à¹à¸¥à¸°à¸ˆà¸°à¸–ูà¸à¸¥à¸šà¸­à¸­à¸à¹ƒà¸™ Godot 4.0"
diff --git a/editor/translations/tr.po b/editor/translations/tr.po
index 5892850caf..578d7b48d0 100644
--- a/editor/translations/tr.po
+++ b/editor/translations/tr.po
@@ -60,12 +60,13 @@
# Jafar Tarverdiyev <cefertarverdiyevv@gmail.com>, 2021.
# ali aydın <alimxaydin@gmail.com>, 2021.
# Cannur Daşkıran <canndask@gmail.com>, 2021.
+# kahveciderin <kahveciderin@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-05-29 13:49+0000\n"
-"Last-Translator: ali aydın <alimxaydin@gmail.com>\n"
+"PO-Revision-Date: 2021-07-13 06:13+0000\n"
+"Last-Translator: kahveciderin <kahveciderin@gmail.com>\n"
"Language-Team: Turkish <https://hosted.weblate.org/projects/godot-engine/"
"godot/tr/>\n"
"Language: tr\n"
@@ -73,7 +74,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.7-dev\n"
+"X-Generator: Weblate 4.7.2-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -464,12 +465,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Animasyon izleri sadece AnimasyonOynatıcı düğümlerini işaret edebilir."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-"Bir animasyon oynatıcı kendisini oynamataz, sadece diğer oynatıcılar "
-"yapaibilir."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Bir kök olmadan yeni bir iz eklemek mümkün değildir"
@@ -514,8 +509,9 @@ msgid "Anim Move Keys"
msgstr "Animasyon Anahtarları Taşı"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Pano boÅŸ"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "Pano boÅŸ!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -1173,7 +1169,7 @@ msgstr "Godot topluluğundan teşekkürler!"
#: editor/editor_about.cpp editor/editor_node.cpp editor/project_manager.cpp
msgid "Click to copy."
-msgstr ""
+msgstr "Kopyalamak için tıklayın."
#: editor/editor_about.cpp
msgid "Godot Engine contributors"
@@ -2554,7 +2550,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "Çıkmadan önce değişiklikler aşağıdaki sahne(ler)e kaydedilsin mi?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
"Proje Yöneticisi açılmadan önce değişiklikler aşağıdaki sahneye(lere) "
"kaydedilsin mi?"
@@ -12023,10 +12019,6 @@ msgid "Can't copy the function node."
msgstr "Fonksiyon düğümü kopyalanamıyor."
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "Pano boÅŸ!"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "GörselBetik Düğümleri Yapıştır"
@@ -12238,6 +12230,8 @@ msgid ""
"Either Debug Keystore, Debug User AND Debug Password settings must be "
"configured OR none of them."
msgstr ""
+"Hata Ayıklama Anahtar Deposu, Hata Ayıklama Kullanıcısı VE Hata Ayıklama "
+"Şifresi konfigüre edilmelidir VEYA hiçbiri konfigüre edilmemelidir."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -12250,6 +12244,8 @@ msgid ""
"Either Release Keystore, Release User AND Release Password settings must be "
"configured OR none of them."
msgstr ""
+"Yayınlama Anahtar Deposu, Yayınlama Kullanıcısı be Yayınlama Şifresi "
+"ayarları konfigüre edilmeli VEYA hiçbiri konfigüre edilmemelidir."
#: platform/android/export/export.cpp
msgid "Release keystore incorrectly configured in the export preset."
@@ -13215,6 +13211,14 @@ msgstr "varyings yalnızca vertex işlevinde atanabilir."
msgid "Constants cannot be modified."
msgstr "Sabit deÄŸerler deÄŸiÅŸtirilemez."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "Bir animasyon oynatıcı kendisini oynamataz, sadece diğer oynatıcılar "
+#~ "yapaibilir."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Pano boÅŸ"
+
#~ msgid ""
#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
#~ msgstr ""
diff --git a/editor/translations/tt.po b/editor/translations/tt.po
index c0d7e79447..3e63f2369d 100644
--- a/editor/translations/tt.po
+++ b/editor/translations/tt.po
@@ -403,10 +403,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr ""
@@ -451,7 +447,8 @@ msgid "Anim Move Keys"
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
msgstr ""
#: editor/animation_track_editor.cpp
@@ -2410,7 +2407,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11482,10 +11479,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
diff --git a/editor/translations/tzm.po b/editor/translations/tzm.po
index 629220c426..0b0ce7d01e 100644
--- a/editor/translations/tzm.po
+++ b/editor/translations/tzm.po
@@ -401,10 +401,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr ""
@@ -449,7 +445,8 @@ msgid "Anim Move Keys"
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
msgstr ""
#: editor/animation_track_editor.cpp
@@ -2408,7 +2405,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11480,10 +11477,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
diff --git a/editor/translations/uk.po b/editor/translations/uk.po
index 5f0fe3d721..50508c5df3 100644
--- a/editor/translations/uk.po
+++ b/editor/translations/uk.po
@@ -424,12 +424,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Доріжки анімації можуть вказувати лише на взули AnimationPlayer."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-"Відтворювач анімації не може відтворювати Ñам Ñебе, лише інші відтворювачі "
-"анімації."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Ðе можна додавати нові доріжки без кореневого запиÑу"
@@ -476,8 +470,9 @@ msgid "Anim Move Keys"
msgstr "ПереміÑтити ключі анімації"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Буфер обміну порожній"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "Буфер обміну порожній!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2521,7 +2516,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "Зберегти зміни в наÑтупній(их) Ñцені(ах) перед тим, Ñк вийти?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
"Зберегти зміни в наÑтупній(их) Ñцені(ах) перед відкриттÑм менеджера проєктів?"
@@ -12025,10 +12020,6 @@ msgid "Can't copy the function node."
msgstr "Ðеможливо Ñкопіювати вузол функції."
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "Буфер обміну порожній!"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "Ð’Ñтавити вузли (Візуального Ñкриптингу) VisualScript"
@@ -13248,6 +13239,14 @@ msgstr "Змінні величини можна пов'Ñзувати лише
msgid "Constants cannot be modified."
msgstr "Сталі не можна змінювати."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "Відтворювач анімації не може відтворювати Ñам Ñебе, лише інші "
+#~ "відтворювачі анімації."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Буфер обміну порожній"
+
#~ msgid ""
#~ "Godot editor was built without ray tracing support; lightmaps can't be "
#~ "baked.\n"
diff --git a/editor/translations/ur_PK.po b/editor/translations/ur_PK.po
index 3af1eac2ef..0a213a2bdf 100644
--- a/editor/translations/ur_PK.po
+++ b/editor/translations/ur_PK.po
@@ -410,10 +410,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr ""
@@ -458,7 +454,8 @@ msgid "Anim Move Keys"
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
msgstr ""
#: editor/animation_track_editor.cpp
@@ -2456,7 +2453,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr ""
#: editor/editor_node.cpp
@@ -11780,10 +11777,6 @@ msgid "Can't copy the function node."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr ""
diff --git a/editor/translations/vi.po b/editor/translations/vi.po
index 8a34f898b8..0104d05502 100644
--- a/editor/translations/vi.po
+++ b/editor/translations/vi.po
@@ -424,11 +424,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "Các bản hoạt ảnh chỉ có thể trỠtới các nút AnimationPlayer."
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-"Animation player không tự tạo hoạt ảnh được, phải thông qua các player khác."
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "Không thể thêm track mới mà không có root"
@@ -473,8 +468,9 @@ msgid "Anim Move Keys"
msgstr "Di chuyển các khoá hoạt cảnh"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "Clipboard rá»—ng"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "Clipboard trống!"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2499,7 +2495,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "Lưu thay đổi trong các scene sau trước khi thoát?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr "Lưu thay đổi trong các cảnh sau trước khi mở Quản lí Dự án?"
#: editor/editor_node.cpp
@@ -11888,10 +11884,6 @@ msgid "Can't copy the function node."
msgstr "Không thể sao chép nút chức năng."
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "Clipboard trống!"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "Dán các nút VisualScript"
@@ -13004,6 +12996,14 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Không thể chỉnh sửa hằng số."
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr ""
+#~ "Animation player không tự tạo hoạt ảnh được, phải thông qua các player "
+#~ "khác."
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "Clipboard rá»—ng"
+
#~ msgid "No"
#~ msgstr "Không"
diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po
index 6994841e78..4393cb4e08 100644
--- a/editor/translations/zh_CN.po
+++ b/editor/translations/zh_CN.po
@@ -83,7 +83,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Chinese (Simplified) (Godot Engine)\n"
"POT-Creation-Date: 2018-01-20 12:15+0200\n"
-"PO-Revision-Date: 2021-06-20 13:35+0000\n"
+"PO-Revision-Date: 2021-07-13 06:13+0000\n"
"Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n"
"Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
"godot-engine/godot/zh_Hans/>\n"
@@ -92,7 +92,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.7\n"
+"X-Generator: Weblate 4.7.2-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -260,7 +260,7 @@ msgstr "修改动画长度"
#: editor/animation_track_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Change Animation Loop"
-msgstr "修改循环"
+msgstr "修改动画循环"
#: editor/animation_track_editor.cpp
msgid "Property Track"
@@ -288,11 +288,11 @@ msgstr "动画播放轨é“"
#: editor/animation_track_editor.cpp
msgid "Animation length (frames)"
-msgstr "动画时长(帧)"
+msgstr "动画长度(帧)"
#: editor/animation_track_editor.cpp
msgid "Animation length (seconds)"
-msgstr "动画时长(秒)"
+msgstr "动画长度(秒)"
#: editor/animation_track_editor.cpp
msgid "Add Track"
@@ -317,15 +317,15 @@ msgstr "动画剪辑:"
#: editor/animation_track_editor.cpp
msgid "Change Track Path"
-msgstr "改å˜è½¨é“路径"
+msgstr "修改轨é“路径"
#: editor/animation_track_editor.cpp
msgid "Toggle this track on/off."
-msgstr "切æ¢å½“å‰è½¨é“开关。"
+msgstr "切æ¢è¯¥è½¨é“的开关。"
#: editor/animation_track_editor.cpp
msgid "Update Mode (How this property is set)"
-msgstr "更新模å¼ï¼ˆå±žæ€§è®¾ç½®æ–¹æ³•ï¼‰"
+msgstr "更新模å¼ï¼ˆè®¾ç½®å±žæ€§çš„æ–¹å¼ï¼‰"
#: editor/animation_track_editor.cpp
msgid "Interpolation Mode"
@@ -337,7 +337,7 @@ msgstr "æ— ç¼å¾ªçŽ¯æ¨¡å¼ï¼ˆä½¿ç”¨å¾ªçŽ¯å¼€å§‹æ’值循环结æŸï¼‰"
#: editor/animation_track_editor.cpp
msgid "Remove this track."
-msgstr "移除当å‰è½¨é“。"
+msgstr "移除该轨é“。"
#: editor/animation_track_editor.cpp
msgid "Time (s): "
@@ -378,11 +378,11 @@ msgstr "三次方"
#: editor/animation_track_editor.cpp
msgid "Clamp Loop Interp"
-msgstr "切断循环æ’值器"
+msgstr "切断循环æ’值"
#: editor/animation_track_editor.cpp
msgid "Wrap Loop Interp"
-msgstr "环绕间隔"
+msgstr "环绕循环æ’值"
#: editor/animation_track_editor.cpp
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -391,11 +391,11 @@ msgstr "æ’入关键帧"
#: editor/animation_track_editor.cpp
msgid "Duplicate Key(s)"
-msgstr "å¤åˆ¶å¸§"
+msgstr "å¤åˆ¶å…³é”®å¸§"
#: editor/animation_track_editor.cpp
msgid "Delete Key(s)"
-msgstr "删除帧"
+msgstr "删除关键帧"
#: editor/animation_track_editor.cpp
msgid "Change Animation Update Mode"
@@ -411,7 +411,7 @@ msgstr "更改动画循环模å¼"
#: editor/animation_track_editor.cpp
msgid "Remove Anim Track"
-msgstr "移除轨é“"
+msgstr "移除动画轨é“"
#: editor/animation_track_editor.cpp
msgid "Create NEW track for %s and insert key?"
@@ -447,11 +447,11 @@ msgstr "创建并æ’入动画"
#: editor/animation_track_editor.cpp
msgid "Anim Insert Track & Key"
-msgstr "æ’入轨é“和关键帧"
+msgstr "æ’入动画轨é“和关键帧"
#: editor/animation_track_editor.cpp
msgid "Anim Insert Key"
-msgstr "æ’入关键帧"
+msgstr "æ’入动画关键帧"
#: editor/animation_track_editor.cpp
msgid "Change Animation Step"
@@ -463,7 +463,7 @@ msgstr "é‡æ–°æŽ’列轨é“"
#: editor/animation_track_editor.cpp
msgid "Transform tracks only apply to Spatial-based nodes."
-msgstr "å˜æ¢è½¨è¿¹ä»…应用到基于 Spatial 节点。"
+msgstr "å˜æ¢è½¨é“仅应用于基于 Spatial 的节点。"
#: editor/animation_track_editor.cpp
msgid ""
@@ -472,18 +472,14 @@ msgid ""
"-AudioStreamPlayer2D\n"
"-AudioStreamPlayer3D"
msgstr ""
-"音轨åªèƒ½æŒ‡å‘以下类型的节点:\n"
+"音频轨é“åªèƒ½æŒ‡å‘以下类型的节点:\n"
"-AudioStreamPlayer\n"
"-AudioStreamPlayer2D\n"
"-AudioStreamPlayer3D"
#: editor/animation_track_editor.cpp
msgid "Animation tracks can only point to AnimationPlayer nodes."
-msgstr "动画轨迹åªèƒ½æŒ‡å‘ AnimationPlayer 节点。"
-
-#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr "动画播放器ä¸èƒ½åŠ¨ç”»åŒ–自己,åªèƒ½åŠ¨ç”»åŒ–其他播放器。"
+msgstr "动画轨é“åªèƒ½æŒ‡å‘ AnimationPlayer 节点。"
#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
@@ -530,8 +526,9 @@ msgid "Anim Move Keys"
msgstr "移动动画关键帧"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "剪贴æ¿æ˜¯ç©ºçš„"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "剪贴æ¿æ˜¯ç©ºçš„ï¼"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -2535,7 +2532,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "退出å‰è¦ä¿å­˜ä»¥ä¸‹åœºæ™¯æ›´æ”¹å—?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr "打开项目管ç†å™¨å‰è¦ä¿å­˜ä¸‹åˆ—场景更改å—?"
#: editor/editor_node.cpp
@@ -9783,10 +9780,10 @@ msgid ""
"Incompatible with older hardware\n"
"Not recommended for web games"
msgstr ""
-"视觉质é‡æ›´é«˜\n"
+"视觉质é‡è¾ƒé«˜\n"
"所有功能å¯ç”¨\n"
-"与旧硬件ä¸å…¼å®¹\n"
-"ä¸æŽ¨è用于网络游æˆ"
+"ä¸å…¼å®¹è¾ƒè€çš„硬件\n"
+"ä¸æŽ¨è用于网页游æˆ"
#: editor/project_manager.cpp
msgid "OpenGL ES 2.0"
@@ -9802,7 +9799,7 @@ msgstr ""
"视觉质é‡è¾ƒä½Ž\n"
"æŸäº›åŠŸèƒ½ä¸å¯ç”¨\n"
"å¯ç”¨äºŽå¤§å¤šæ•°ç¡¬ä»¶\n"
-"推è用于网络游æˆ"
+"推è用于网页游æˆ"
#: editor/project_manager.cpp
msgid "Renderer can be changed later, but scenes may need to be adjusted."
@@ -9878,7 +9875,7 @@ msgid ""
"the \"Application\" category."
msgstr ""
"无法è¿è¡Œé¡¹ç›®ï¼šæœªå®šä¹‰ä¸»åœºæ™¯ã€‚ \n"
-"请编辑项目并在 “项目设置†中 “Application†类别下设置主场景。"
+"请编辑项目并在 “项目设置†的 “Application†类别下设置主场景。"
#: editor/project_manager.cpp
msgid ""
@@ -9943,7 +9940,7 @@ msgstr "项目"
#: editor/project_manager.cpp
msgid "Loading, please wait..."
-msgstr "正在加载,请ç¨å€™..."
+msgstr "正在加载,请ç¨å€™â€¦â€¦"
#: editor/project_manager.cpp
msgid "Last Modified"
@@ -9971,7 +9968,7 @@ msgstr "模æ¿"
#: editor/project_manager.cpp
msgid "Restart Now"
-msgstr "ç«‹å³é‡æ–°å¯åŠ¨"
+msgstr "ç«‹å³é‡å¯"
#: editor/project_manager.cpp
msgid "Can't run project"
@@ -9982,7 +9979,7 @@ msgid ""
"You currently don't have any projects.\n"
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
-"ç›®å‰æ²¡æœ‰ä»»ä½•é¡¹ç›®ã€‚ \n"
+"ç›®å‰æ²¡æœ‰ä»»ä½•é¡¹ç›®ã€‚\n"
"是å¦æŸ¥çœ‹ç´ æ库中的官方示例项目?"
#: editor/project_manager.cpp
@@ -9996,11 +9993,11 @@ msgstr ""
#: editor/project_settings_editor.cpp
msgid "Key "
-msgstr "é”® "
+msgstr "按键 "
#: editor/project_settings_editor.cpp
msgid "Joy Button"
-msgstr "手柄按钮"
+msgstr "手柄按键"
#: editor/project_settings_editor.cpp
msgid "Joy Axis"
@@ -10014,11 +10011,11 @@ msgstr "鼠标按键"
msgid ""
"Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or "
"'\"'"
-msgstr "无效的æ“作å称。æ“作åä¸èƒ½ä¸ºç©ºï¼Œä¹Ÿä¸èƒ½åŒ…å« â€œ/â€, “:â€, “=â€, “\\†或 “\"â€"
+msgstr "无效的动作å称。动作åä¸èƒ½ä¸ºç©ºï¼Œä¹Ÿä¸èƒ½åŒ…å« â€œ/â€, “:â€, “=â€, “\\†或 “\"â€"
#: editor/project_settings_editor.cpp
msgid "An action with the name '%s' already exists."
-msgstr "å为 “%s†的æ“作已存在。"
+msgstr "å为“%sâ€çš„动作已存在。"
#: editor/project_settings_editor.cpp
msgid "Rename Input Action Event"
@@ -10042,11 +10039,11 @@ msgstr "设备"
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Press a Key..."
-msgstr "按下一个键..."
+msgstr "请按键……"
#: editor/project_settings_editor.cpp
msgid "Mouse Button Index:"
-msgstr "鼠标按键:"
+msgstr "鼠标按键索引:"
#: editor/project_settings_editor.cpp
msgid "Left Button"
@@ -10070,11 +10067,11 @@ msgstr "滚轮å‘下"
#: editor/project_settings_editor.cpp
msgid "Wheel Left Button"
-msgstr "滚轮左键"
+msgstr "滚轮å‘å·¦"
#: editor/project_settings_editor.cpp
msgid "Wheel Right Button"
-msgstr "滚轮å³é”®"
+msgstr "滚轮å‘å³"
#: editor/project_settings_editor.cpp
msgid "X Button 1"
@@ -10086,7 +10083,7 @@ msgstr "X 按键 2"
#: editor/project_settings_editor.cpp
msgid "Joypad Axis Index:"
-msgstr "手柄摇æ†åºå·ï¼š"
+msgstr "手柄摇æ†ç´¢å¼•ï¼š"
#: editor/project_settings_editor.cpp
msgid "Axis"
@@ -10094,15 +10091,15 @@ msgstr "è½´"
#: editor/project_settings_editor.cpp
msgid "Joypad Button Index:"
-msgstr "手柄按钮:"
+msgstr "手柄按钮索引:"
#: editor/project_settings_editor.cpp
msgid "Erase Input Action"
-msgstr "移除输入事件"
+msgstr "移除输入动作"
#: editor/project_settings_editor.cpp
msgid "Erase Input Action Event"
-msgstr "移除输入事件"
+msgstr "移除输入动作事件"
#: editor/project_settings_editor.cpp
msgid "Add Event"
@@ -10122,7 +10119,7 @@ msgstr "å³é”®ã€‚"
#: editor/project_settings_editor.cpp
msgid "Middle Button."
-msgstr "中键(滚轮)。"
+msgstr "中键。"
#: editor/project_settings_editor.cpp
msgid "Wheel Up."
@@ -10138,15 +10135,15 @@ msgstr "添加全局属性"
#: editor/project_settings_editor.cpp
msgid "Select a setting item first!"
-msgstr "请先选择一个设置项目 ï¼"
+msgstr "请先选择一个设置项ï¼"
#: editor/project_settings_editor.cpp
msgid "No property '%s' exists."
-msgstr "ä¸å­˜åœ¨å±žæ€§ “%sâ€ã€‚"
+msgstr "ä¸å­˜åœ¨å±žæ€§â€œ%sâ€ã€‚"
#: editor/project_settings_editor.cpp
msgid "Setting '%s' is internal, and it can't be deleted."
-msgstr "“%s†是内部设定,无法删除。"
+msgstr "“%sâ€æ˜¯å†…部设定,无法删除。"
#: editor/project_settings_editor.cpp
msgid "Delete Item"
@@ -10157,7 +10154,7 @@ msgid ""
"Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or "
"'\"'."
msgstr ""
-"无效的æ“作å称。å称ä¸èƒ½ä¸ºç©ºï¼Œä¹Ÿä¸èƒ½åŒ…å« â€œ/â€, “:â€, “=â€, “\\†或者 “\"â€ã€‚"
+"无效的动作å称。动作ä¸èƒ½ä¸ºç©ºï¼Œä¹Ÿä¸èƒ½åŒ…å« â€œ/â€, “:â€, “=â€, “\\†或者 “\"â€ã€‚"
#: editor/project_settings_editor.cpp
msgid "Add Input Action"
@@ -10173,7 +10170,7 @@ msgstr "ä¿å­˜è®¾ç½®æˆåŠŸã€‚"
#: editor/project_settings_editor.cpp
msgid "Moved Input Action Event"
-msgstr "输入动作事件"
+msgstr "移动输入动作事件"
#: editor/project_settings_editor.cpp
msgid "Override for Feature"
@@ -10209,11 +10206,11 @@ msgstr "移除资æºé‡å®šå‘选项"
#: editor/project_settings_editor.cpp
msgid "Changed Locale Filter"
-msgstr "修改区域设置筛选模å¼"
+msgstr "修改区域设置筛选"
#: editor/project_settings_editor.cpp
msgid "Changed Locale Filter Mode"
-msgstr "更改了区域设置筛选模å¼"
+msgstr "修改区域设置筛选模å¼"
#: editor/project_settings_editor.cpp
msgid "Project Settings (project.godot)"
@@ -10237,7 +10234,7 @@ msgstr "é”®ä½æ˜ å°„"
#: editor/project_settings_editor.cpp
msgid "Action:"
-msgstr "动作:"
+msgstr "动作:"
#: editor/project_settings_editor.cpp
msgid "Action"
@@ -10253,7 +10250,7 @@ msgstr "设备:"
#: editor/project_settings_editor.cpp
msgid "Index:"
-msgstr "åºå·ï¼š"
+msgstr "索引:"
#: editor/project_settings_editor.cpp
msgid "Localization"
@@ -10277,7 +10274,7 @@ msgstr "资æºï¼š"
#: editor/project_settings_editor.cpp
msgid "Remaps by Locale:"
-msgstr "ä¾ç…§åŒºåŸŸé‡å®šå‘:"
+msgstr "按区域é‡å®šå‘:"
#: editor/project_settings_editor.cpp
msgid "Locale"
@@ -10329,7 +10326,7 @@ msgstr "缓入缓出"
#: editor/property_editor.cpp
msgid "Easing Out-In"
-msgstr "å缓入缓出"
+msgstr "缓出缓入"
#: editor/property_editor.cpp
msgid "File..."
@@ -11832,10 +11829,6 @@ msgid "Can't copy the function node."
msgstr "无法å¤åˆ¶å‡½æ•°èŠ‚点。"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "剪贴æ¿æ˜¯ç©ºçš„ï¼"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "粘贴 VisualScript 节点"
@@ -12947,6 +12940,12 @@ msgstr "å˜é‡åªèƒ½åœ¨é¡¶ç‚¹å‡½æ•°ä¸­æŒ‡å®šã€‚"
msgid "Constants cannot be modified."
msgstr "ä¸å…许修改常é‡ã€‚"
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr "动画播放器ä¸èƒ½åŠ¨ç”»åŒ–自己,åªèƒ½åŠ¨ç”»åŒ–其他播放器。"
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "剪贴æ¿æ˜¯ç©ºçš„"
+
#~ msgid ""
#~ "Godot editor was built without ray tracing support; lightmaps can't be "
#~ "baked.\n"
diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po
index eee6eb62b7..28a69ee289 100644
--- a/editor/translations/zh_HK.po
+++ b/editor/translations/zh_HK.po
@@ -435,10 +435,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr ""
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "沒有ROOT以新增新動畫軌跡"
@@ -486,8 +482,9 @@ msgid "Anim Move Keys"
msgstr "移動動畫幀"
#: editor/animation_track_editor.cpp
+#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
-msgid "Clipboard is empty"
+msgid "Clipboard is empty!"
msgstr "路徑為空"
#: editor/animation_track_editor.cpp
@@ -2575,7 +2572,7 @@ msgstr "離開å‰è¦å…ˆå„²å­˜ä»¥ä¸‹ scene 的任何更改嗎?"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr "é–‹å•Ÿ Project Manager å‰è¦å…ˆå„²å­˜ä»¥ä¸‹ scene 的任何更改嗎?"
#: editor/editor_node.cpp
@@ -12291,11 +12288,6 @@ msgstr ""
#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
-msgid "Clipboard is empty!"
-msgstr "路徑為空"
-
-#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Paste VisualScript Nodes"
msgstr "貼上"
@@ -13352,6 +13344,10 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#, fuzzy
+#~ msgid "Clipboard is empty"
+#~ msgstr "路徑為空"
+
#~ msgid "No"
#~ msgstr "å¦"
diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po
index 7aee72ee43..f65d628d63 100644
--- a/editor/translations/zh_TW.po
+++ b/editor/translations/zh_TW.po
@@ -25,12 +25,13 @@
# BinotaLIU <binota@protonmail.ch>, 2020.
# BinotaLIU <me@binota.org>, 2020, 2021.
# MintSoda <lionlxh@qq.com>, 2020.
+# meowmeowmeowcat <meowmeowcat1211@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-05-24 21:36+0000\n"
-"Last-Translator: Kisaragi Hiu <mail@kisaragi-hiu.com>\n"
+"PO-Revision-Date: 2021-07-13 06:13+0000\n"
+"Last-Translator: meowmeowmeowcat <meowmeowcat1211@gmail.com>\n"
"Language-Team: Chinese (Traditional) <https://hosted.weblate.org/projects/"
"godot-engine/godot/zh_Hant/>\n"
"Language: zh_TW\n"
@@ -38,7 +39,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.7-dev\n"
+"X-Generator: Weblate 4.7.2-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -428,10 +429,6 @@ msgid "Animation tracks can only point to AnimationPlayer nodes."
msgstr "動畫軌僅å¯æŒ‡å‘ AnimationPlayer 節點。"
#: editor/animation_track_editor.cpp
-msgid "An animation player can't animate itself, only other players."
-msgstr "å‹•ç•« Player 無法播放自己,僅å¯æ’­æ”¾å…¶ä»– Player。"
-
-#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
msgstr "沒有根節點時無法新增軌é“"
@@ -476,8 +473,9 @@ msgid "Anim Move Keys"
msgstr "移動動畫關éµç•«æ ¼"
#: editor/animation_track_editor.cpp
-msgid "Clipboard is empty"
-msgstr "剪貼æ¿ç‚ºç©º"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "剪貼簿為空ï¼"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -1125,7 +1123,7 @@ msgstr "Godot 社群感è¬ä½ ï¼"
#: editor/editor_about.cpp editor/editor_node.cpp editor/project_manager.cpp
msgid "Click to copy."
-msgstr ""
+msgstr "按一下以複製。"
#: editor/editor_about.cpp
msgid "Godot Engine contributors"
@@ -2483,7 +2481,7 @@ msgid "Save changes to the following scene(s) before quitting?"
msgstr "退出å‰è¦å…ˆä¿å­˜ä¸‹åˆ—場景嗎?"
#: editor/editor_node.cpp
-msgid "Save changes the following scene(s) before opening Project Manager?"
+msgid "Save changes to the following scene(s) before opening Project Manager?"
msgstr "開啟專案管ç†å“¡å‰è¦å…ˆä¿å­˜ä»¥ä¸‹å ´æ™¯å—Žï¼Ÿ"
#: editor/editor_node.cpp
@@ -11778,10 +11776,6 @@ msgid "Can't copy the function node."
msgstr "無法複製函å¼ç¯€é»žã€‚"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Clipboard is empty!"
-msgstr "剪貼簿為空ï¼"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
msgstr "貼上視覺腳本 (VisualScript) 節點"
@@ -12897,6 +12891,12 @@ msgstr "Varying 變數åªå¯åœ¨é ‚點函å¼ä¸­æŒ‡æ´¾ã€‚"
msgid "Constants cannot be modified."
msgstr "ä¸å¯ä¿®æ”¹å¸¸æ•¸ã€‚"
+#~ msgid "An animation player can't animate itself, only other players."
+#~ msgstr "å‹•ç•« Player 無法播放自己,僅å¯æ’­æ”¾å…¶ä»– Player。"
+
+#~ msgid "Clipboard is empty"
+#~ msgstr "剪貼æ¿ç‚ºç©º"
+
#~ msgid ""
#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
#~ msgstr "InterpolatedCamera å·²åœæ­¢ç¶­è­·ï¼Œä¸”將於 Godot 4.0 中移除。"
diff --git a/main/main.cpp b/main/main.cpp
index 9e3b5c9ba2..0651f4b93f 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -151,9 +151,9 @@ static bool auto_build_solutions = false;
static DisplayServer::WindowMode window_mode = DisplayServer::WINDOW_MODE_WINDOWED;
static DisplayServer::ScreenOrientation window_orientation = DisplayServer::SCREEN_LANDSCAPE;
+static DisplayServer::VSyncMode window_vsync_mode = DisplayServer::VSYNC_ENABLED;
static uint32_t window_flags = 0;
static Size2i window_size = Size2i(1024, 600);
-static bool window_vsync_via_compositor = false;
static int init_screen = -1;
static bool init_fullscreen = false;
@@ -338,8 +338,6 @@ void Main::print_help(const char *p_binary) {
OS::get_singleton()->print(" --position <X>,<Y> Request window position.\n");
OS::get_singleton()->print(" --low-dpi Force low-DPI mode (macOS and Windows only).\n");
OS::get_singleton()->print(" --no-window Disable window creation (Windows only). Useful together with --script.\n");
- OS::get_singleton()->print(" --enable-vsync-via-compositor When vsync is enabled, vsync via the OS' window compositor (Windows only).\n");
- OS::get_singleton()->print(" --disable-vsync-via-compositor Disable vsync via the OS' window compositor (Windows only).\n");
OS::get_singleton()->print(" --single-window Use a single window (no separate subwindows).\n");
OS::get_singleton()->print(" --tablet-driver Pen tablet input driver.\n");
OS::get_singleton()->print("\n");
@@ -551,7 +549,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
translation_server = memnew(TranslationServer);
performance = memnew(Performance);
- ClassDB::register_class<Performance>();
+ GDREGISTER_CLASS(Performance);
engine->add_singleton(Engine::Singleton("Performance", performance));
// Only flush stdout in debug builds by default, as spamming `print()` will
@@ -599,11 +597,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
Vector<String> breakpoints;
bool use_custom_res = true;
bool force_res = false;
- bool saw_vsync_via_compositor_override = false;
#ifdef TOOLS_ENABLED
bool found_project = false;
#endif
- bool use_vsync = false;
packed_data = PackedData::get_singleton();
if (!packed_data) {
@@ -825,12 +821,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
} else if (I->get() == "--no-window") { // disable window creation (Windows only)
OS::get_singleton()->set_no_window_mode(true);
- } else if (I->get() == "--enable-vsync-via-compositor") {
- window_vsync_via_compositor = true;
- saw_vsync_via_compositor_override = true;
- } else if (I->get() == "--disable-vsync-via-compositor") {
- window_vsync_via_compositor = false;
- saw_vsync_via_compositor_override = true;
#endif
} else if (I->get() == "--profiling") { // enable profiling
@@ -1287,19 +1277,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
OS::get_singleton()->_allow_hidpi = GLOBAL_DEF("display/window/dpi/allow_hidpi", false);
}
- use_vsync = GLOBAL_DEF_RST("display/window/vsync/use_vsync", true);
- OS::get_singleton()->_use_vsync = use_vsync;
-
- if (!saw_vsync_via_compositor_override) {
- // If one of the command line options to enable/disable vsync via the
- // window compositor ("--enable-vsync-via-compositor" or
- // "--disable-vsync-via-compositor") was present then it overrides the
- // project setting.
- window_vsync_via_compositor = GLOBAL_DEF("display/window/vsync/vsync_via_compositor", false);
- }
-
- OS::get_singleton()->_vsync_via_compositor = window_vsync_via_compositor;
-
/* todo restore
OS::get_singleton()->_allow_layered = GLOBAL_DEF("display/window/per_pixel_transparency/allowed", false);
video_mode.layered = GLOBAL_DEF("display/window/per_pixel_transparency/enabled", false);
@@ -1357,7 +1334,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
{
window_orientation = DisplayServer::ScreenOrientation(int(GLOBAL_DEF_BASIC("display/window/handheld/orientation", DisplayServer::ScreenOrientation::SCREEN_LANDSCAPE)));
}
-
+ {
+ window_vsync_mode = DisplayServer::VSyncMode(int(GLOBAL_DEF("display/window/vsync/vsync_mode", DisplayServer::VSyncMode::VSYNC_ENABLED)));
+ }
Engine::get_singleton()->set_iterations_per_second(GLOBAL_DEF_BASIC("physics/common/physics_fps", 60));
ProjectSettings::get_singleton()->set_custom_property_info("physics/common/physics_fps",
PropertyInfo(Variant::INT, "physics/common/physics_fps",
@@ -1550,14 +1529,14 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
String rendering_driver; // temp broken
Error err;
- display_server = DisplayServer::create(display_driver_idx, rendering_driver, window_mode, window_flags, window_size, err);
+ display_server = DisplayServer::create(display_driver_idx, rendering_driver, window_mode, window_vsync_mode, window_flags, window_size, err);
if (err != OK || display_server == nullptr) {
//ok i guess we can't use this display server, try other ones
for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
if (i == display_driver_idx) {
continue; //don't try the same twice
}
- display_server = DisplayServer::create(i, rendering_driver, window_mode, window_flags, window_size, err);
+ display_server = DisplayServer::create(i, rendering_driver, window_mode, window_vsync_mode, window_flags, window_size, err);
if (err == OK && display_server != nullptr) {
break;
}
diff --git a/methods.py b/methods.py
index 1afd1ca0d4..fd9978657e 100644
--- a/methods.py
+++ b/methods.py
@@ -231,6 +231,18 @@ def is_module(path):
return True
+def write_disabled_classes(class_list):
+ f = open("core/disabled_classes.gen.h", "w")
+ f.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ f.write("#ifndef DISABLED_CLASSES_GEN_H\n")
+ f.write("#define DISABLED_CLASSES_GEN_H\n\n")
+ for c in class_list:
+ cs = c.strip()
+ if cs != "":
+ f.write("#define ClassDB_Disable_" + cs + " 1\n")
+ f.write("\n#endif\n")
+
+
def write_modules(modules):
includes_cpp = ""
preregister_cpp = ""
diff --git a/misc/dist/linux/godot.6 b/misc/dist/linux/godot.6
index 4140094813..3e5bdefdce 100644
--- a/misc/dist/linux/godot.6
+++ b/misc/dist/linux/godot.6
@@ -85,12 +85,6 @@ Force low\-DPI mode (macOS and Windows only).
.TP
\fB\-\-no\-window\fR
Disable window creation (Windows only). Useful together with \fB\-\-script\fR.
-.TP
-\fB\-\-enable\-vsync\-via\-compositor\fR
-When vsync is enabled, vsync via the OS' window compositor (Windows only).
-.TP
-\fB\-\-disable\-vsync\-via\-compositor\fR
-Disable vsync via the OS' window compositor (Windows only).
.SS "Debug options:"
.TP
\fB\-d\fR, \fB\-\-debug\fR
diff --git a/misc/dist/shell/_godot.zsh-completion b/misc/dist/shell/_godot.zsh-completion
index 8e14240b53..b29746bfc4 100644
--- a/misc/dist/shell/_godot.zsh-completion
+++ b/misc/dist/shell/_godot.zsh-completion
@@ -51,8 +51,6 @@ _arguments \
'--position[request window position]:position in X,Y format' \
'--low-dpi[force low-DPI mode (macOS and Windows only)]' \
'--no-window[disable window creation (Windows only), useful together with --script]' \
- "--enable-vsync-via-compositor[when Vsync is enabled, Vsync via the OS' window compositor (Windows only)]" \
- "--disable-vsync-via-compositor[disable Vsync via the OS' window compositor (Windows only)]" \
'(-d --debug)'{-d,--debug}'[debug (local stdout debugger)]' \
'(-b --breakpoints)'{-b,--breakpoints}'[specify the breakpoint list as source::line comma-separated pairs, no spaces (use %20 instead)]:breakpoint list' \
'--profiling[enable profiling in the script debugger]' \
diff --git a/misc/dist/shell/godot.bash-completion b/misc/dist/shell/godot.bash-completion
index 14f2be37b1..03861e43f8 100644
--- a/misc/dist/shell/godot.bash-completion
+++ b/misc/dist/shell/godot.bash-completion
@@ -54,8 +54,6 @@ _complete_godot_options() {
--position
--low-dpi
--no-window
---enable-vsync-via-compositor
---disable-vsync-via-compositor
--debug
--breakpoints
--profiling
diff --git a/misc/dist/shell/godot.fish b/misc/dist/shell/godot.fish
index a485a1dcdb..1367665bbc 100644
--- a/misc/dist/shell/godot.fish
+++ b/misc/dist/shell/godot.fish
@@ -61,8 +61,6 @@ complete -c godot -l resolution -d "Request window resolution" -x
complete -c godot -l position -d "Request window position" -x
complete -c godot -l low-dpi -d "Force low-DPI mode (macOS and Windows only)"
complete -c godot -l no-window -d "Disable window creation (Windows only), useful together with --script"
-complete -c godot -l enable-vsync-via-compositor -d "When Vsync is enabled, Vsync via the OS' window compositor (Windows only)"
-complete -c godot -l disable-vsync-via-compositor -d "Disable Vsync via the OS' window compositor (Windows only)"
# Debug options:
complete -c godot -s d -l debug -d "Debug (local stdout debugger)"
diff --git a/modules/basis_universal/register_types.cpp b/modules/basis_universal/register_types.cpp
index 23639a4f2f..9a13406900 100644
--- a/modules/basis_universal/register_types.cpp
+++ b/modules/basis_universal/register_types.cpp
@@ -272,7 +272,7 @@ void register_basis_universal_types() {
Image::basis_universal_packer = basis_universal_packer;
#endif
Image::basis_universal_unpacker = basis_universal_unpacker;
- //ClassDB::register_class<TextureBasisU>();
+ //GDREGISTER_CLASS(TextureBasisU);
}
void unregister_basis_universal_types() {
diff --git a/modules/csg/register_types.cpp b/modules/csg/register_types.cpp
index e28f44d1eb..a47390c2b2 100644
--- a/modules/csg/register_types.cpp
+++ b/modules/csg/register_types.cpp
@@ -36,15 +36,15 @@
void register_csg_types() {
#ifndef _3D_DISABLED
- ClassDB::register_virtual_class<CSGShape3D>();
- ClassDB::register_virtual_class<CSGPrimitive3D>();
- ClassDB::register_class<CSGMesh3D>();
- ClassDB::register_class<CSGSphere3D>();
- ClassDB::register_class<CSGBox3D>();
- ClassDB::register_class<CSGCylinder3D>();
- ClassDB::register_class<CSGTorus3D>();
- ClassDB::register_class<CSGPolygon3D>();
- ClassDB::register_class<CSGCombiner3D>();
+ GDREGISTER_VIRTUAL_CLASS(CSGShape3D);
+ GDREGISTER_VIRTUAL_CLASS(CSGPrimitive3D);
+ GDREGISTER_CLASS(CSGMesh3D);
+ GDREGISTER_CLASS(CSGSphere3D);
+ GDREGISTER_CLASS(CSGBox3D);
+ GDREGISTER_CLASS(CSGCylinder3D);
+ GDREGISTER_CLASS(CSGTorus3D);
+ GDREGISTER_CLASS(CSGPolygon3D);
+ GDREGISTER_CLASS(CSGCombiner3D);
#ifdef TOOLS_ENABLED
EditorPlugins::add_by_type<EditorPluginCSG>();
diff --git a/modules/enet/config.py b/modules/enet/config.py
index 5fd343c75d..3662b2d94e 100644
--- a/modules/enet/config.py
+++ b/modules/enet/config.py
@@ -8,7 +8,7 @@ def configure(env):
def get_doc_classes():
return [
- "NetworkedMultiplayerENet",
+ "ENetMultiplayerPeer",
]
diff --git a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml b/modules/enet/doc_classes/ENetMultiplayerPeer.xml
index 271cb03c9f..5b2c72dce4 100644
--- a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml
+++ b/modules/enet/doc_classes/ENetMultiplayerPeer.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="NetworkedMultiplayerENet" inherits="NetworkedMultiplayerPeer" version="4.0">
+<class name="ENetMultiplayerPeer" inherits="MultiplayerPeer" version="4.0">
<brief_description>
PacketPeer implementation using the [url=http://enet.bespin.org/index.html]ENet[/url] library.
</brief_description>
<description>
- A PacketPeer implementation that should be passed to [member SceneTree.network_peer] after being initialized as either a client or server. Events can then be handled by connecting to [SceneTree] signals.
+ A PacketPeer implementation that should be passed to [member MultiplayerAPI.network_peer] after being initialized as either a client or server. Events can then be handled by connecting to [SceneTree] signals.
ENet's purpose is to provide a relatively thin, simple and robust network communication layer on top of UDP (User Datagram Protocol).
[b]Note:[/b] ENet only uses UDP, not TCP. When forwarding the server port to make your server accessible on the public Internet, you only need to forward the server port in UDP. You can use the [UPNP] class to try to forward the server port automatically when starting the server.
</description>
@@ -36,7 +36,7 @@
<argument index="4" name="local_port" type="int" default="0">
</argument>
<description>
- Create client that connects to a server at [code]address[/code] using specified [code]port[/code]. The given address needs to be either a fully qualified domain name (e.g. [code]"www.example.com"[/code]) or an IP address in IPv4 or IPv6 format (e.g. [code]"192.168.1.1"[/code]). The [code]port[/code] is the port the server is listening on. The [code]in_bandwidth[/code] and [code]out_bandwidth[/code] parameters can be used to limit the incoming and outgoing bandwidth to the given number of bytes per second. The default of 0 means unlimited bandwidth. Note that ENet will strategically drop packets on specific sides of a connection between peers to ensure the peer's bandwidth is not overwhelmed. The bandwidth parameters also determine the window size of a connection which limits the amount of reliable packets that may be in transit at any given time. Returns [constant OK] if a client was created, [constant ERR_ALREADY_IN_USE] if this NetworkedMultiplayerENet instance already has an open connection (in which case you need to call [method close_connection] first) or [constant ERR_CANT_CREATE] if the client could not be created. If [code]local_port[/code] is specified, the client will also listen to the given port; this is useful for some NAT traversal techniques.
+ Create client that connects to a server at [code]address[/code] using specified [code]port[/code]. The given address needs to be either a fully qualified domain name (e.g. [code]"www.example.com"[/code]) or an IP address in IPv4 or IPv6 format (e.g. [code]"192.168.1.1"[/code]). The [code]port[/code] is the port the server is listening on. The [code]in_bandwidth[/code] and [code]out_bandwidth[/code] parameters can be used to limit the incoming and outgoing bandwidth to the given number of bytes per second. The default of 0 means unlimited bandwidth. Note that ENet will strategically drop packets on specific sides of a connection between peers to ensure the peer's bandwidth is not overwhelmed. The bandwidth parameters also determine the window size of a connection which limits the amount of reliable packets that may be in transit at any given time. Returns [constant OK] if a client was created, [constant ERR_ALREADY_IN_USE] if this ENetMultiplayerPeer instance already has an open connection (in which case you need to call [method close_connection] first) or [constant ERR_CANT_CREATE] if the client could not be created. If [code]local_port[/code] is specified, the client will also listen to the given port; this is useful for some NAT traversal techniques.
</description>
</method>
<method name="create_server">
@@ -51,7 +51,7 @@
<argument index="3" name="out_bandwidth" type="int" default="0">
</argument>
<description>
- Create server that listens to connections via [code]port[/code]. The port needs to be an available, unused port between 0 and 65535. Note that ports below 1024 are privileged and may require elevated permissions depending on the platform. To change the interface the server listens on, use [method set_bind_ip]. The default IP is the wildcard [code]"*"[/code], which listens on all available interfaces. [code]max_clients[/code] is the maximum number of clients that are allowed at once, any number up to 4095 may be used, although the achievable number of simultaneous clients may be far lower and depends on the application. For additional details on the bandwidth parameters, see [method create_client]. Returns [constant OK] if a server was created, [constant ERR_ALREADY_IN_USE] if this NetworkedMultiplayerENet instance already has an open connection (in which case you need to call [method close_connection] first) or [constant ERR_CANT_CREATE] if the server could not be created.
+ Create server that listens to connections via [code]port[/code]. The port needs to be an available, unused port between 0 and 65535. Note that ports below 1024 are privileged and may require elevated permissions depending on the platform. To change the interface the server listens on, use [method set_bind_ip]. The default IP is the wildcard [code]"*"[/code], which listens on all available interfaces. [code]max_clients[/code] is the maximum number of clients that are allowed at once, any number up to 4095 may be used, although the achievable number of simultaneous clients may be far lower and depends on the application. For additional details on the bandwidth parameters, see [method create_client]. Returns [constant OK] if a server was created, [constant ERR_ALREADY_IN_USE] if this ENetMultiplayerPeer instance already has an open connection (in which case you need to call [method close_connection] first) or [constant ERR_CANT_CREATE] if the server could not be created.
</description>
</method>
<method name="disconnect_peer">
@@ -150,12 +150,12 @@
</methods>
<members>
<member name="always_ordered" type="bool" setter="set_always_ordered" getter="is_always_ordered" default="false">
- Enforce ordered packets when using [constant NetworkedMultiplayerPeer.TRANSFER_MODE_UNRELIABLE] (thus behaving similarly to [constant NetworkedMultiplayerPeer.TRANSFER_MODE_UNRELIABLE_ORDERED]). This is the only way to use ordering with the RPC system.
+ Enforce ordered packets when using [constant MultiplayerPeer.TRANSFER_MODE_UNRELIABLE] (thus behaving similarly to [constant MultiplayerPeer.TRANSFER_MODE_UNRELIABLE_ORDERED]). This is the only way to use ordering with the RPC system.
</member>
<member name="channel_count" type="int" setter="set_channel_count" getter="get_channel_count" default="3">
The number of channels to be used by ENet. Channels are used to separate different kinds of data. In reliable or ordered mode, for example, the packet delivery order is ensured on a per-channel basis. This is done to combat latency and reduces ordering restrictions on packets. The delivery status of a packet in one channel won't stall the delivery of other packets in another channel.
</member>
- <member name="compression_mode" type="int" setter="set_compression_mode" getter="get_compression_mode" enum="NetworkedMultiplayerENet.CompressionMode" default="0">
+ <member name="compression_mode" type="int" setter="set_compression_mode" getter="get_compression_mode" enum="ENetMultiplayerPeer.CompressionMode" default="0">
The compression method used for network packets. These have different tradeoffs of compression speed versus bandwidth, you may need to test which one works best for your use case if you use compression at all.
</member>
<member name="dtls_verify" type="bool" setter="set_dtls_verify_enabled" getter="is_dtls_verify_enabled" default="true">
@@ -168,7 +168,7 @@
<member name="transfer_channel" type="int" setter="set_transfer_channel" getter="get_transfer_channel" default="-1">
Set the default channel to be used to transfer data. By default, this value is [code]-1[/code] which means that ENet will only use 2 channels: one for reliable packets, and one for unreliable packets. The channel [code]0[/code] is reserved and cannot be used. Setting this member to any value between [code]0[/code] and [member channel_count] (excluded) will force ENet to use that channel for sending data. See [member channel_count] for more information about ENet channels.
</member>
- <member name="transfer_mode" type="int" setter="set_transfer_mode" getter="get_transfer_mode" override="true" enum="NetworkedMultiplayerPeer.TransferMode" default="2" />
+ <member name="transfer_mode" type="int" setter="set_transfer_mode" getter="get_transfer_mode" override="true" enum="MultiplayerPeer.TransferMode" default="2" />
<member name="use_dtls" type="bool" setter="set_dtls_enabled" getter="is_dtls_enabled" default="false">
When enabled, the client or server created by this peer, will use [PacketPeerDTLS] instead of raw UDP sockets for communicating with the remote peer. This will make the communication encrypted with DTLS at the cost of higher resource usage and potentially larger packet size.
Note: When creating a DTLS server, make sure you setup the key/certificate pair via [method set_dtls_key] and [method set_dtls_certificate]. For DTLS clients, have a look at the [member dtls_verify] option, and configure the certificate accordingly via [method set_dtls_certificate].
diff --git a/modules/enet/networked_multiplayer_enet.cpp b/modules/enet/enet_multiplayer_peer.cpp
index 94260e8c13..a9726426ad 100644
--- a/modules/enet/networked_multiplayer_enet.cpp
+++ b/modules/enet/enet_multiplayer_peer.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* networked_multiplayer_enet.cpp */
+/* enet_multiplayer_peer.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,45 +28,45 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "networked_multiplayer_enet.h"
+#include "enet_multiplayer_peer.h"
#include "core/io/ip.h"
#include "core/io/marshalls.h"
#include "core/os/os.h"
-void NetworkedMultiplayerENet::set_transfer_mode(TransferMode p_mode) {
+void ENetMultiplayerPeer::set_transfer_mode(TransferMode p_mode) {
transfer_mode = p_mode;
}
-NetworkedMultiplayerPeer::TransferMode NetworkedMultiplayerENet::get_transfer_mode() const {
+MultiplayerPeer::TransferMode ENetMultiplayerPeer::get_transfer_mode() const {
return transfer_mode;
}
-void NetworkedMultiplayerENet::set_target_peer(int p_peer) {
+void ENetMultiplayerPeer::set_target_peer(int p_peer) {
target_peer = p_peer;
}
-int NetworkedMultiplayerENet::get_packet_peer() const {
+int ENetMultiplayerPeer::get_packet_peer() const {
ERR_FAIL_COND_V_MSG(!active, 1, "The multiplayer instance isn't currently active.");
ERR_FAIL_COND_V(incoming_packets.size() == 0, 1);
return incoming_packets.front()->get().from;
}
-int NetworkedMultiplayerENet::get_packet_channel() const {
+int ENetMultiplayerPeer::get_packet_channel() const {
ERR_FAIL_COND_V_MSG(!active, -1, "The multiplayer instance isn't currently active.");
ERR_FAIL_COND_V(incoming_packets.size() == 0, -1);
return incoming_packets.front()->get().channel;
}
-int NetworkedMultiplayerENet::get_last_packet_channel() const {
+int ENetMultiplayerPeer::get_last_packet_channel() const {
ERR_FAIL_COND_V_MSG(!active, -1, "The multiplayer instance isn't currently active.");
ERR_FAIL_COND_V(!current_packet.packet, -1);
return current_packet.channel;
}
-Error NetworkedMultiplayerENet::create_server(int p_port, int p_max_clients, int p_in_bandwidth, int p_out_bandwidth) {
+Error ENetMultiplayerPeer::create_server(int p_port, int p_max_clients, int p_in_bandwidth, int p_out_bandwidth) {
ERR_FAIL_COND_V_MSG(active, ERR_ALREADY_IN_USE, "The multiplayer instance is already active.");
ERR_FAIL_COND_V_MSG(p_port < 0 || p_port > 65535, ERR_INVALID_PARAMETER, "The local port number must be between 0 and 65535 (inclusive).");
ERR_FAIL_COND_V_MSG(p_max_clients < 1 || p_max_clients > 4095, ERR_INVALID_PARAMETER, "The number of clients must be set between 1 and 4095 (inclusive).");
@@ -115,7 +115,7 @@ Error NetworkedMultiplayerENet::create_server(int p_port, int p_max_clients, int
connection_status = CONNECTION_CONNECTED;
return OK;
}
-Error NetworkedMultiplayerENet::create_client(const String &p_address, int p_port, int p_in_bandwidth, int p_out_bandwidth, int p_local_port) {
+Error ENetMultiplayerPeer::create_client(const String &p_address, int p_port, int p_in_bandwidth, int p_out_bandwidth, int p_local_port) {
ERR_FAIL_COND_V_MSG(active, ERR_ALREADY_IN_USE, "The multiplayer instance is already active.");
ERR_FAIL_COND_V_MSG(p_port < 1 || p_port > 65535, ERR_INVALID_PARAMETER, "The remote port number must be between 1 and 65535 (inclusive).");
ERR_FAIL_COND_V_MSG(p_local_port < 0 || p_local_port > 65535, ERR_INVALID_PARAMETER, "The local port number must be between 0 and 65535 (inclusive).");
@@ -199,7 +199,7 @@ Error NetworkedMultiplayerENet::create_client(const String &p_address, int p_por
return OK;
}
-void NetworkedMultiplayerENet::poll() {
+void ENetMultiplayerPeer::poll() {
ERR_FAIL_COND_MSG(!active, "The multiplayer instance isn't currently active.");
_pop_current_packet();
@@ -426,13 +426,13 @@ void NetworkedMultiplayerENet::poll() {
}
}
-bool NetworkedMultiplayerENet::is_server() const {
+bool ENetMultiplayerPeer::is_server() const {
ERR_FAIL_COND_V_MSG(!active, false, "The multiplayer instance isn't currently active.");
return server;
}
-void NetworkedMultiplayerENet::close_connection(uint32_t wait_usec) {
+void ENetMultiplayerPeer::close_connection(uint32_t wait_usec) {
ERR_FAIL_COND_MSG(!active, "The multiplayer instance isn't currently active.");
_pop_current_packet();
@@ -463,7 +463,7 @@ void NetworkedMultiplayerENet::close_connection(uint32_t wait_usec) {
connection_status = CONNECTION_DISCONNECTED;
}
-void NetworkedMultiplayerENet::disconnect_peer(int p_peer, bool now) {
+void ENetMultiplayerPeer::disconnect_peer(int p_peer, bool now) {
ERR_FAIL_COND_MSG(!active, "The multiplayer instance isn't currently active.");
ERR_FAIL_COND_MSG(!is_server(), "Can't disconnect a peer when not acting as a server.");
ERR_FAIL_COND_MSG(!peer_map.has(p_peer), vformat("Peer ID %d not found in the list of peers.", p_peer));
@@ -498,11 +498,11 @@ void NetworkedMultiplayerENet::disconnect_peer(int p_peer, bool now) {
}
}
-int NetworkedMultiplayerENet::get_available_packet_count() const {
+int ENetMultiplayerPeer::get_available_packet_count() const {
return incoming_packets.size();
}
-Error NetworkedMultiplayerENet::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
+Error ENetMultiplayerPeer::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
ERR_FAIL_COND_V_MSG(incoming_packets.size() == 0, ERR_UNAVAILABLE, "No incoming packets available.");
_pop_current_packet();
@@ -516,7 +516,7 @@ Error NetworkedMultiplayerENet::get_packet(const uint8_t **r_buffer, int &r_buff
return OK;
}
-Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
+Error ENetMultiplayerPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
ERR_FAIL_COND_V_MSG(!active, ERR_UNCONFIGURED, "The multiplayer instance isn't currently active.");
ERR_FAIL_COND_V_MSG(connection_status != CONNECTION_CONNECTED, ERR_UNCONFIGURED, "The multiplayer instance isn't currently connected to any server or client.");
@@ -591,11 +591,11 @@ Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer
return OK;
}
-int NetworkedMultiplayerENet::get_max_packet_size() const {
+int ENetMultiplayerPeer::get_max_packet_size() const {
return 1 << 24; // Anything is good
}
-void NetworkedMultiplayerENet::_pop_current_packet() {
+void ENetMultiplayerPeer::_pop_current_packet() {
if (current_packet.packet) {
enet_packet_destroy(current_packet.packet);
current_packet.packet = nullptr;
@@ -604,11 +604,11 @@ void NetworkedMultiplayerENet::_pop_current_packet() {
}
}
-NetworkedMultiplayerPeer::ConnectionStatus NetworkedMultiplayerENet::get_connection_status() const {
+MultiplayerPeer::ConnectionStatus ENetMultiplayerPeer::get_connection_status() const {
return connection_status;
}
-uint32_t NetworkedMultiplayerENet::_gen_unique_id() const {
+uint32_t ENetMultiplayerPeer::_gen_unique_id() const {
uint32_t hash = 0;
while (hash == 0 || hash == 1) {
@@ -629,12 +629,12 @@ uint32_t NetworkedMultiplayerENet::_gen_unique_id() const {
return hash;
}
-int NetworkedMultiplayerENet::get_unique_id() const {
+int ENetMultiplayerPeer::get_unique_id() const {
ERR_FAIL_COND_V_MSG(!active, 0, "The multiplayer instance isn't currently active.");
return unique_id;
}
-void NetworkedMultiplayerENet::set_refuse_new_connections(bool p_enable) {
+void ENetMultiplayerPeer::set_refuse_new_connections(bool p_enable) {
refuse_connections = p_enable;
#ifdef GODOT_ENET
if (active) {
@@ -643,20 +643,20 @@ void NetworkedMultiplayerENet::set_refuse_new_connections(bool p_enable) {
#endif
}
-bool NetworkedMultiplayerENet::is_refusing_new_connections() const {
+bool ENetMultiplayerPeer::is_refusing_new_connections() const {
return refuse_connections;
}
-void NetworkedMultiplayerENet::set_compression_mode(CompressionMode p_mode) {
+void ENetMultiplayerPeer::set_compression_mode(CompressionMode p_mode) {
compression_mode = p_mode;
}
-NetworkedMultiplayerENet::CompressionMode NetworkedMultiplayerENet::get_compression_mode() const {
+ENetMultiplayerPeer::CompressionMode ENetMultiplayerPeer::get_compression_mode() const {
return compression_mode;
}
-size_t NetworkedMultiplayerENet::enet_compress(void *context, const ENetBuffer *inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 *outData, size_t outLimit) {
- NetworkedMultiplayerENet *enet = (NetworkedMultiplayerENet *)(context);
+size_t ENetMultiplayerPeer::enet_compress(void *context, const ENetBuffer *inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 *outData, size_t outLimit) {
+ ENetMultiplayerPeer *enet = (ENetMultiplayerPeer *)(context);
if (size_t(enet->src_compressor_mem.size()) < inLimit) {
enet->src_compressor_mem.resize(inLimit);
@@ -709,8 +709,8 @@ size_t NetworkedMultiplayerENet::enet_compress(void *context, const ENetBuffer *
return ret;
}
-size_t NetworkedMultiplayerENet::enet_decompress(void *context, const enet_uint8 *inData, size_t inLimit, enet_uint8 *outData, size_t outLimit) {
- NetworkedMultiplayerENet *enet = (NetworkedMultiplayerENet *)(context);
+size_t ENetMultiplayerPeer::enet_decompress(void *context, const enet_uint8 *inData, size_t inLimit, enet_uint8 *outData, size_t outLimit) {
+ ENetMultiplayerPeer *enet = (ENetMultiplayerPeer *)(context);
int ret = -1;
switch (enet->compression_mode) {
case COMPRESS_FASTLZ: {
@@ -732,7 +732,7 @@ size_t NetworkedMultiplayerENet::enet_decompress(void *context, const enet_uint8
}
}
-void NetworkedMultiplayerENet::_setup_compressor() {
+void ENetMultiplayerPeer::_setup_compressor() {
switch (compression_mode) {
case COMPRESS_NONE: {
enet_host_compress(host, nullptr);
@@ -748,11 +748,11 @@ void NetworkedMultiplayerENet::_setup_compressor() {
}
}
-void NetworkedMultiplayerENet::enet_compressor_destroy(void *context) {
+void ENetMultiplayerPeer::enet_compressor_destroy(void *context) {
// Nothing to do
}
-IPAddress NetworkedMultiplayerENet::get_peer_address(int p_peer_id) const {
+IPAddress ENetMultiplayerPeer::get_peer_address(int p_peer_id) const {
ERR_FAIL_COND_V_MSG(!peer_map.has(p_peer_id), IPAddress(), vformat("Peer ID %d not found in the list of peers.", p_peer_id));
ERR_FAIL_COND_V_MSG(!is_server() && p_peer_id != 1, IPAddress(), "Can't get the address of peers other than the server (ID -1) when acting as a client.");
ERR_FAIL_COND_V_MSG(peer_map[p_peer_id] == nullptr, IPAddress(), vformat("Peer ID %d found in the list of peers, but is null.", p_peer_id));
@@ -767,7 +767,7 @@ IPAddress NetworkedMultiplayerENet::get_peer_address(int p_peer_id) const {
return out;
}
-int NetworkedMultiplayerENet::get_peer_port(int p_peer_id) const {
+int ENetMultiplayerPeer::get_peer_port(int p_peer_id) const {
ERR_FAIL_COND_V_MSG(!peer_map.has(p_peer_id), 0, vformat("Peer ID %d not found in the list of peers.", p_peer_id));
ERR_FAIL_COND_V_MSG(!is_server() && p_peer_id != 1, 0, "Can't get the address of peers other than the server (ID -1) when acting as a client.");
ERR_FAIL_COND_V_MSG(peer_map[p_peer_id] == nullptr, 0, vformat("Peer ID %d found in the list of peers, but is null.", p_peer_id));
@@ -778,12 +778,12 @@ int NetworkedMultiplayerENet::get_peer_port(int p_peer_id) const {
#endif
}
-int NetworkedMultiplayerENet::get_local_port() const {
+int ENetMultiplayerPeer::get_local_port() const {
ERR_FAIL_COND_V_MSG(!active || !host, 0, "The multiplayer instance isn't currently active.");
return host->address.port;
}
-void NetworkedMultiplayerENet::set_peer_timeout(int p_peer_id, int p_timeout_limit, int p_timeout_min, int p_timeout_max) {
+void ENetMultiplayerPeer::set_peer_timeout(int p_peer_id, int p_timeout_limit, int p_timeout_min, int p_timeout_max) {
ERR_FAIL_COND_MSG(!peer_map.has(p_peer_id), vformat("Peer ID %d not found in the list of peers.", p_peer_id));
ERR_FAIL_COND_MSG(!is_server() && p_peer_id != 1, "Can't change the timeout of peers other then the server when acting as a client.");
ERR_FAIL_COND_MSG(peer_map[p_peer_id] == nullptr, vformat("Peer ID %d found in the list of peers, but is null.", p_peer_id));
@@ -791,73 +791,73 @@ void NetworkedMultiplayerENet::set_peer_timeout(int p_peer_id, int p_timeout_lim
enet_peer_timeout(peer_map[p_peer_id], p_timeout_limit, p_timeout_min, p_timeout_max);
}
-void NetworkedMultiplayerENet::set_transfer_channel(int p_channel) {
+void ENetMultiplayerPeer::set_transfer_channel(int p_channel) {
ERR_FAIL_COND_MSG(p_channel < -1 || p_channel >= channel_count, vformat("The transfer channel must be set between 0 and %d, inclusive (got %d).", channel_count - 1, p_channel));
ERR_FAIL_COND_MSG(p_channel == SYSCH_CONFIG, vformat("The channel %d is reserved.", SYSCH_CONFIG));
transfer_channel = p_channel;
}
-int NetworkedMultiplayerENet::get_transfer_channel() const {
+int ENetMultiplayerPeer::get_transfer_channel() const {
return transfer_channel;
}
-void NetworkedMultiplayerENet::set_channel_count(int p_channel) {
+void ENetMultiplayerPeer::set_channel_count(int p_channel) {
ERR_FAIL_COND_MSG(active, "The channel count can't be set while the multiplayer instance is active.");
ERR_FAIL_COND_MSG(p_channel < SYSCH_MAX, vformat("The channel count must be greater than or equal to %d to account for reserved channels (got %d).", SYSCH_MAX, p_channel));
channel_count = p_channel;
}
-int NetworkedMultiplayerENet::get_channel_count() const {
+int ENetMultiplayerPeer::get_channel_count() const {
return channel_count;
}
-void NetworkedMultiplayerENet::set_always_ordered(bool p_ordered) {
+void ENetMultiplayerPeer::set_always_ordered(bool p_ordered) {
always_ordered = p_ordered;
}
-bool NetworkedMultiplayerENet::is_always_ordered() const {
+bool ENetMultiplayerPeer::is_always_ordered() const {
return always_ordered;
}
-void NetworkedMultiplayerENet::set_server_relay_enabled(bool p_enabled) {
+void ENetMultiplayerPeer::set_server_relay_enabled(bool p_enabled) {
ERR_FAIL_COND_MSG(active, "Server relaying can't be toggled while the multiplayer instance is active.");
server_relay = p_enabled;
}
-bool NetworkedMultiplayerENet::is_server_relay_enabled() const {
+bool ENetMultiplayerPeer::is_server_relay_enabled() const {
return server_relay;
}
-void NetworkedMultiplayerENet::_bind_methods() {
- ClassDB::bind_method(D_METHOD("create_server", "port", "max_clients", "in_bandwidth", "out_bandwidth"), &NetworkedMultiplayerENet::create_server, DEFVAL(32), DEFVAL(0), DEFVAL(0));
- ClassDB::bind_method(D_METHOD("create_client", "address", "port", "in_bandwidth", "out_bandwidth", "local_port"), &NetworkedMultiplayerENet::create_client, DEFVAL(0), DEFVAL(0), DEFVAL(0));
- ClassDB::bind_method(D_METHOD("close_connection", "wait_usec"), &NetworkedMultiplayerENet::close_connection, DEFVAL(100));
- ClassDB::bind_method(D_METHOD("disconnect_peer", "id", "now"), &NetworkedMultiplayerENet::disconnect_peer, DEFVAL(false));
- ClassDB::bind_method(D_METHOD("set_compression_mode", "mode"), &NetworkedMultiplayerENet::set_compression_mode);
- ClassDB::bind_method(D_METHOD("get_compression_mode"), &NetworkedMultiplayerENet::get_compression_mode);
- ClassDB::bind_method(D_METHOD("set_bind_ip", "ip"), &NetworkedMultiplayerENet::set_bind_ip);
- ClassDB::bind_method(D_METHOD("set_dtls_enabled", "enabled"), &NetworkedMultiplayerENet::set_dtls_enabled);
- ClassDB::bind_method(D_METHOD("is_dtls_enabled"), &NetworkedMultiplayerENet::is_dtls_enabled);
- ClassDB::bind_method(D_METHOD("set_dtls_key", "key"), &NetworkedMultiplayerENet::set_dtls_key);
- ClassDB::bind_method(D_METHOD("set_dtls_certificate", "certificate"), &NetworkedMultiplayerENet::set_dtls_certificate);
- ClassDB::bind_method(D_METHOD("set_dtls_verify_enabled", "enabled"), &NetworkedMultiplayerENet::set_dtls_verify_enabled);
- ClassDB::bind_method(D_METHOD("is_dtls_verify_enabled"), &NetworkedMultiplayerENet::is_dtls_verify_enabled);
- ClassDB::bind_method(D_METHOD("get_peer_address", "id"), &NetworkedMultiplayerENet::get_peer_address);
- ClassDB::bind_method(D_METHOD("get_peer_port", "id"), &NetworkedMultiplayerENet::get_peer_port);
- ClassDB::bind_method(D_METHOD("get_local_port"), &NetworkedMultiplayerENet::get_local_port);
- ClassDB::bind_method(D_METHOD("set_peer_timeout", "id", "timeout_limit", "timeout_min", "timeout_max"), &NetworkedMultiplayerENet::set_peer_timeout);
-
- ClassDB::bind_method(D_METHOD("get_packet_channel"), &NetworkedMultiplayerENet::get_packet_channel);
- ClassDB::bind_method(D_METHOD("get_last_packet_channel"), &NetworkedMultiplayerENet::get_last_packet_channel);
- ClassDB::bind_method(D_METHOD("set_transfer_channel", "channel"), &NetworkedMultiplayerENet::set_transfer_channel);
- ClassDB::bind_method(D_METHOD("get_transfer_channel"), &NetworkedMultiplayerENet::get_transfer_channel);
- ClassDB::bind_method(D_METHOD("set_channel_count", "channels"), &NetworkedMultiplayerENet::set_channel_count);
- ClassDB::bind_method(D_METHOD("get_channel_count"), &NetworkedMultiplayerENet::get_channel_count);
- ClassDB::bind_method(D_METHOD("set_always_ordered", "ordered"), &NetworkedMultiplayerENet::set_always_ordered);
- ClassDB::bind_method(D_METHOD("is_always_ordered"), &NetworkedMultiplayerENet::is_always_ordered);
- ClassDB::bind_method(D_METHOD("set_server_relay_enabled", "enabled"), &NetworkedMultiplayerENet::set_server_relay_enabled);
- ClassDB::bind_method(D_METHOD("is_server_relay_enabled"), &NetworkedMultiplayerENet::is_server_relay_enabled);
+void ENetMultiplayerPeer::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("create_server", "port", "max_clients", "in_bandwidth", "out_bandwidth"), &ENetMultiplayerPeer::create_server, DEFVAL(32), DEFVAL(0), DEFVAL(0));
+ ClassDB::bind_method(D_METHOD("create_client", "address", "port", "in_bandwidth", "out_bandwidth", "local_port"), &ENetMultiplayerPeer::create_client, DEFVAL(0), DEFVAL(0), DEFVAL(0));
+ ClassDB::bind_method(D_METHOD("close_connection", "wait_usec"), &ENetMultiplayerPeer::close_connection, DEFVAL(100));
+ ClassDB::bind_method(D_METHOD("disconnect_peer", "id", "now"), &ENetMultiplayerPeer::disconnect_peer, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("set_compression_mode", "mode"), &ENetMultiplayerPeer::set_compression_mode);
+ ClassDB::bind_method(D_METHOD("get_compression_mode"), &ENetMultiplayerPeer::get_compression_mode);
+ ClassDB::bind_method(D_METHOD("set_bind_ip", "ip"), &ENetMultiplayerPeer::set_bind_ip);
+ ClassDB::bind_method(D_METHOD("set_dtls_enabled", "enabled"), &ENetMultiplayerPeer::set_dtls_enabled);
+ ClassDB::bind_method(D_METHOD("is_dtls_enabled"), &ENetMultiplayerPeer::is_dtls_enabled);
+ ClassDB::bind_method(D_METHOD("set_dtls_key", "key"), &ENetMultiplayerPeer::set_dtls_key);
+ ClassDB::bind_method(D_METHOD("set_dtls_certificate", "certificate"), &ENetMultiplayerPeer::set_dtls_certificate);
+ ClassDB::bind_method(D_METHOD("set_dtls_verify_enabled", "enabled"), &ENetMultiplayerPeer::set_dtls_verify_enabled);
+ ClassDB::bind_method(D_METHOD("is_dtls_verify_enabled"), &ENetMultiplayerPeer::is_dtls_verify_enabled);
+ ClassDB::bind_method(D_METHOD("get_peer_address", "id"), &ENetMultiplayerPeer::get_peer_address);
+ ClassDB::bind_method(D_METHOD("get_peer_port", "id"), &ENetMultiplayerPeer::get_peer_port);
+ ClassDB::bind_method(D_METHOD("get_local_port"), &ENetMultiplayerPeer::get_local_port);
+ ClassDB::bind_method(D_METHOD("set_peer_timeout", "id", "timeout_limit", "timeout_min", "timeout_max"), &ENetMultiplayerPeer::set_peer_timeout);
+
+ ClassDB::bind_method(D_METHOD("get_packet_channel"), &ENetMultiplayerPeer::get_packet_channel);
+ ClassDB::bind_method(D_METHOD("get_last_packet_channel"), &ENetMultiplayerPeer::get_last_packet_channel);
+ ClassDB::bind_method(D_METHOD("set_transfer_channel", "channel"), &ENetMultiplayerPeer::set_transfer_channel);
+ ClassDB::bind_method(D_METHOD("get_transfer_channel"), &ENetMultiplayerPeer::get_transfer_channel);
+ ClassDB::bind_method(D_METHOD("set_channel_count", "channels"), &ENetMultiplayerPeer::set_channel_count);
+ ClassDB::bind_method(D_METHOD("get_channel_count"), &ENetMultiplayerPeer::get_channel_count);
+ ClassDB::bind_method(D_METHOD("set_always_ordered", "ordered"), &ENetMultiplayerPeer::set_always_ordered);
+ ClassDB::bind_method(D_METHOD("is_always_ordered"), &ENetMultiplayerPeer::is_always_ordered);
+ ClassDB::bind_method(D_METHOD("set_server_relay_enabled", "enabled"), &ENetMultiplayerPeer::set_server_relay_enabled);
+ ClassDB::bind_method(D_METHOD("is_server_relay_enabled"), &ENetMultiplayerPeer::is_server_relay_enabled);
ADD_PROPERTY(PropertyInfo(Variant::INT, "compression_mode", PROPERTY_HINT_ENUM, "None,Range Coder,FastLZ,ZLib,ZStd"), "set_compression_mode", "get_compression_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "transfer_channel"), "set_transfer_channel", "get_transfer_channel");
@@ -874,7 +874,7 @@ void NetworkedMultiplayerENet::_bind_methods() {
BIND_ENUM_CONSTANT(COMPRESS_ZSTD);
}
-NetworkedMultiplayerENet::NetworkedMultiplayerENet() {
+ENetMultiplayerPeer::ENetMultiplayerPeer() {
enet_compressor.context = this;
enet_compressor.compress = enet_compress;
enet_compressor.decompress = enet_decompress;
@@ -883,7 +883,7 @@ NetworkedMultiplayerENet::NetworkedMultiplayerENet() {
bind_ip = IPAddress("*");
}
-NetworkedMultiplayerENet::~NetworkedMultiplayerENet() {
+ENetMultiplayerPeer::~ENetMultiplayerPeer() {
if (active) {
close_connection();
}
@@ -891,36 +891,36 @@ NetworkedMultiplayerENet::~NetworkedMultiplayerENet() {
// Sets IP for ENet to bind when using create_server or create_client
// if no IP is set, then ENet bind to ENET_HOST_ANY
-void NetworkedMultiplayerENet::set_bind_ip(const IPAddress &p_ip) {
+void ENetMultiplayerPeer::set_bind_ip(const IPAddress &p_ip) {
ERR_FAIL_COND_MSG(!p_ip.is_valid() && !p_ip.is_wildcard(), vformat("Invalid bind IP address: %s", String(p_ip)));
bind_ip = p_ip;
}
-void NetworkedMultiplayerENet::set_dtls_enabled(bool p_enabled) {
+void ENetMultiplayerPeer::set_dtls_enabled(bool p_enabled) {
ERR_FAIL_COND(active);
dtls_enabled = p_enabled;
}
-bool NetworkedMultiplayerENet::is_dtls_enabled() const {
+bool ENetMultiplayerPeer::is_dtls_enabled() const {
return dtls_enabled;
}
-void NetworkedMultiplayerENet::set_dtls_verify_enabled(bool p_enabled) {
+void ENetMultiplayerPeer::set_dtls_verify_enabled(bool p_enabled) {
ERR_FAIL_COND(active);
dtls_verify = p_enabled;
}
-bool NetworkedMultiplayerENet::is_dtls_verify_enabled() const {
+bool ENetMultiplayerPeer::is_dtls_verify_enabled() const {
return dtls_verify;
}
-void NetworkedMultiplayerENet::set_dtls_key(Ref<CryptoKey> p_key) {
+void ENetMultiplayerPeer::set_dtls_key(Ref<CryptoKey> p_key) {
ERR_FAIL_COND(active);
dtls_key = p_key;
}
-void NetworkedMultiplayerENet::set_dtls_certificate(Ref<X509Certificate> p_cert) {
+void ENetMultiplayerPeer::set_dtls_certificate(Ref<X509Certificate> p_cert) {
ERR_FAIL_COND(active);
dtls_cert = p_cert;
}
diff --git a/modules/enet/networked_multiplayer_enet.h b/modules/enet/enet_multiplayer_peer.h
index 2d928859fa..e6d45eb16a 100644
--- a/modules/enet/networked_multiplayer_enet.h
+++ b/modules/enet/enet_multiplayer_peer.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* networked_multiplayer_enet.h */
+/* enet_multiplayer_peer.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -33,12 +33,12 @@
#include "core/crypto/crypto.h"
#include "core/io/compression.h"
-#include "core/io/networked_multiplayer_peer.h"
+#include "core/io/multiplayer_peer.h"
#include <enet/enet.h>
-class NetworkedMultiplayerENet : public NetworkedMultiplayerPeer {
- GDCLASS(NetworkedMultiplayerENet, NetworkedMultiplayerPeer);
+class ENetMultiplayerPeer : public MultiplayerPeer {
+ GDCLASS(ENetMultiplayerPeer, MultiplayerPeer);
public:
enum CompressionMode {
@@ -168,8 +168,8 @@ public:
void set_server_relay_enabled(bool p_enabled);
bool is_server_relay_enabled() const;
- NetworkedMultiplayerENet();
- ~NetworkedMultiplayerENet();
+ ENetMultiplayerPeer();
+ ~ENetMultiplayerPeer();
void set_bind_ip(const IPAddress &p_ip);
void set_dtls_enabled(bool p_enabled);
@@ -180,6 +180,6 @@ public:
void set_dtls_certificate(Ref<X509Certificate> p_cert);
};
-VARIANT_ENUM_CAST(NetworkedMultiplayerENet::CompressionMode);
+VARIANT_ENUM_CAST(ENetMultiplayerPeer::CompressionMode);
#endif // NETWORKED_MULTIPLAYER_ENET_H
diff --git a/modules/enet/register_types.cpp b/modules/enet/register_types.cpp
index 8da2d17e13..38870316e4 100644
--- a/modules/enet/register_types.cpp
+++ b/modules/enet/register_types.cpp
@@ -30,7 +30,7 @@
#include "register_types.h"
#include "core/error/error_macros.h"
-#include "networked_multiplayer_enet.h"
+#include "enet_multiplayer_peer.h"
static bool enet_ok = false;
@@ -41,7 +41,7 @@ void register_enet_types() {
enet_ok = true;
}
- ClassDB::register_class<NetworkedMultiplayerENet>();
+ GDREGISTER_CLASS(ENetMultiplayerPeer);
}
void unregister_enet_types() {
diff --git a/modules/fbx/register_types.cpp b/modules/fbx/register_types.cpp
index b615c91cd2..a75da8f3a9 100644
--- a/modules/fbx/register_types.cpp
+++ b/modules/fbx/register_types.cpp
@@ -46,7 +46,7 @@ void register_fbx_types() {
ClassDB::APIType prev_api = ClassDB::get_current_api();
ClassDB::set_current_api(ClassDB::API_EDITOR);
- ClassDB::register_class<EditorSceneImporterFBX>();
+ GDREGISTER_CLASS(EditorSceneImporterFBX);
ClassDB::set_current_api(prev_api);
diff --git a/modules/gdnative/doc_classes/MultiplayerPeerGDNative.xml b/modules/gdnative/doc_classes/MultiplayerPeerGDNative.xml
index 9f33d32e81..b88f5e7e1e 100644
--- a/modules/gdnative/doc_classes/MultiplayerPeerGDNative.xml
+++ b/modules/gdnative/doc_classes/MultiplayerPeerGDNative.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="MultiplayerPeerGDNative" inherits="NetworkedMultiplayerPeer" version="4.0">
+<class name="MultiplayerPeerGDNative" inherits="MultiplayerPeer" version="4.0">
<brief_description>
</brief_description>
<description>
diff --git a/modules/gdnative/include/net/godot_net.h b/modules/gdnative/include/net/godot_net.h
index 2fa576a5bf..94e7739ef9 100644
--- a/modules/gdnative/include/net/godot_net.h
+++ b/modules/gdnative/include/net/godot_net.h
@@ -90,7 +90,7 @@ typedef struct {
godot_int (*get_available_packet_count)(const void *);
godot_int (*get_max_packet_size)(const void *);
- /* This is NetworkedMultiplayerPeer */
+ /* This is MultiplayerPeer */
void (*set_transfer_mode)(void *, godot_int);
godot_int (*get_transfer_mode)(const void *);
// 0 = broadcast, 1 = server, <0 = all but abs(value)
diff --git a/modules/gdnative/include/text/godot_text.h b/modules/gdnative/include/text/godot_text.h
index f3c50e6f87..5c59de7c06 100644
--- a/modules/gdnative/include/text/godot_text.h
+++ b/modules/gdnative/include/text/godot_text.h
@@ -143,6 +143,7 @@ typedef struct {
bool (*shaped_text_shape)(void *, godot_rid *);
bool (*shaped_text_update_breaks)(void *, godot_rid *);
bool (*shaped_text_update_justification_ops)(void *, godot_rid *);
+ void (*shaped_text_overrun_trim_to_width)(void *, godot_rid *, float, uint8_t);
bool (*shaped_text_is_ready)(void *, godot_rid *);
godot_packed_glyph_array (*shaped_text_get_glyphs)(void *, godot_rid *);
godot_vector2i (*shaped_text_get_range)(void *, godot_rid *);
diff --git a/modules/gdnative/nativescript/godot_nativescript.cpp b/modules/gdnative/nativescript/godot_nativescript.cpp
index b10a747568..70b14836bf 100644
--- a/modules/gdnative/nativescript/godot_nativescript.cpp
+++ b/modules/gdnative/nativescript/godot_nativescript.cpp
@@ -332,7 +332,7 @@ void GDAPI godot_nativescript_unregister_instance_binding_data_functions(int p_i
}
void GDAPI *godot_nativescript_get_instance_binding_data(int p_idx, godot_object *p_object) {
- return NativeScriptLanguage::get_singleton()->get_instance_binding_data(p_idx, (Object *)p_object);
+ return nullptr;
}
void GDAPI godot_nativescript_profiling_add_data(const char *p_signature, uint64_t p_time) {
diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp
index 3695f6b9a3..d7943827c2 100644
--- a/modules/gdnative/nativescript/nativescript.cpp
+++ b/modules/gdnative/nativescript/nativescript.cpp
@@ -1258,6 +1258,8 @@ void NativeScriptLanguage::unregister_binding_functions(int p_idx) {
}
void *NativeScriptLanguage::get_instance_binding_data(int p_idx, Object *p_object) {
+ return nullptr;
+#if 0
ERR_FAIL_INDEX_V(p_idx, binding_functions.size(), nullptr);
ERR_FAIL_COND_V_MSG(!binding_functions[p_idx].first, nullptr, "Tried to get binding data for a nativescript binding that does not exist.");
@@ -1287,9 +1289,12 @@ void *NativeScriptLanguage::get_instance_binding_data(int p_idx, Object *p_objec
}
return (*binding_data)[p_idx];
+#endif
}
void *NativeScriptLanguage::alloc_instance_binding_data(Object *p_object) {
+ return nullptr;
+#if 0
Vector<void *> *binding_data = new Vector<void *>;
binding_data->resize(binding_functions.size());
@@ -1301,9 +1306,11 @@ void *NativeScriptLanguage::alloc_instance_binding_data(Object *p_object) {
binding_instances.insert(binding_data);
return (void *)binding_data;
+#endif
}
void NativeScriptLanguage::free_instance_binding_data(void *p_data) {
+#if 0
if (!p_data) {
return;
}
@@ -1323,9 +1330,11 @@ void NativeScriptLanguage::free_instance_binding_data(void *p_data) {
binding_instances.erase(&binding_data);
delete &binding_data;
+#endif
}
void NativeScriptLanguage::refcount_incremented_instance_binding(Object *p_object) {
+#if 0
void *data = p_object->get_script_instance_binding(lang_idx);
if (!data) {
@@ -1347,9 +1356,11 @@ void NativeScriptLanguage::refcount_incremented_instance_binding(Object *p_objec
binding_functions[i].second.refcount_incremented_instance_binding(binding_data[i], p_object);
}
}
+#endif
}
bool NativeScriptLanguage::refcount_decremented_instance_binding(Object *p_object) {
+#if 0
void *data = p_object->get_script_instance_binding(lang_idx);
if (!data) {
@@ -1375,6 +1386,8 @@ bool NativeScriptLanguage::refcount_decremented_instance_binding(Object *p_objec
}
return can_die;
+#endif
+ return false;
}
void NativeScriptLanguage::set_global_type_tag(int p_idx, StringName p_class_name, const void *p_type_tag) {
diff --git a/modules/gdnative/nativescript/register_types.cpp b/modules/gdnative/nativescript/register_types.cpp
index 0191cfd809..82a3459517 100644
--- a/modules/gdnative/nativescript/register_types.cpp
+++ b/modules/gdnative/nativescript/register_types.cpp
@@ -45,7 +45,7 @@ Ref<ResourceFormatSaverNativeScript> resource_saver_gdns;
void register_nativescript_types() {
native_script_language = memnew(NativeScriptLanguage);
- ClassDB::register_class<NativeScript>();
+ GDREGISTER_CLASS(NativeScript);
native_script_language->set_language_index(ScriptServer::get_language_count());
ScriptServer::register_language(native_script_language);
diff --git a/modules/gdnative/net/multiplayer_peer_gdnative.cpp b/modules/gdnative/net/multiplayer_peer_gdnative.cpp
index 8b5fc8db5c..8ceba0f339 100644
--- a/modules/gdnative/net/multiplayer_peer_gdnative.cpp
+++ b/modules/gdnative/net/multiplayer_peer_gdnative.cpp
@@ -61,13 +61,13 @@ int MultiplayerPeerGDNative::get_available_packet_count() const {
return interface->get_available_packet_count(interface->data);
}
-/* NetworkedMultiplayerPeer */
+/* MultiplayerPeer */
void MultiplayerPeerGDNative::set_transfer_mode(TransferMode p_mode) {
ERR_FAIL_COND(interface == nullptr);
interface->set_transfer_mode(interface->data, (godot_int)p_mode);
}
-NetworkedMultiplayerPeer::TransferMode MultiplayerPeerGDNative::get_transfer_mode() const {
+MultiplayerPeer::TransferMode MultiplayerPeerGDNative::get_transfer_mode() const {
ERR_FAIL_COND_V(interface == nullptr, TRANSFER_MODE_UNRELIABLE);
return (TransferMode)interface->get_transfer_mode(interface->data);
}
@@ -107,7 +107,7 @@ bool MultiplayerPeerGDNative::is_refusing_new_connections() const {
return interface->is_refusing_new_connections(interface->data);
}
-NetworkedMultiplayerPeer::ConnectionStatus MultiplayerPeerGDNative::get_connection_status() const {
+MultiplayerPeer::ConnectionStatus MultiplayerPeerGDNative::get_connection_status() const {
ERR_FAIL_COND_V(interface == nullptr, CONNECTION_DISCONNECTED);
return (ConnectionStatus)interface->get_connection_status(interface->data);
}
diff --git a/modules/gdnative/net/multiplayer_peer_gdnative.h b/modules/gdnative/net/multiplayer_peer_gdnative.h
index 593b2534dd..7c10ab77f7 100644
--- a/modules/gdnative/net/multiplayer_peer_gdnative.h
+++ b/modules/gdnative/net/multiplayer_peer_gdnative.h
@@ -31,12 +31,12 @@
#ifndef MULTIPLAYER_PEER_GDNATIVE_H
#define MULTIPLAYER_PEER_GDNATIVE_H
-#include "core/io/networked_multiplayer_peer.h"
+#include "core/io/multiplayer_peer.h"
#include "modules/gdnative/gdnative.h"
#include "modules/gdnative/include/net/godot_net.h"
-class MultiplayerPeerGDNative : public NetworkedMultiplayerPeer {
- GDCLASS(MultiplayerPeerGDNative, NetworkedMultiplayerPeer);
+class MultiplayerPeerGDNative : public MultiplayerPeer {
+ GDCLASS(MultiplayerPeerGDNative, MultiplayerPeer);
protected:
static void _bind_methods();
@@ -55,7 +55,7 @@ public:
virtual int get_max_packet_size() const override;
virtual int get_available_packet_count() const override;
- /* Specific to NetworkedMultiplayerPeer */
+ /* Specific to MultiplayerPeer */
virtual void set_transfer_mode(TransferMode p_mode) override;
virtual TransferMode get_transfer_mode() const override;
virtual void set_target_peer(int p_peer_id) override;
diff --git a/modules/gdnative/net/register_types.cpp b/modules/gdnative/net/register_types.cpp
index 645c43b7e3..46c383e5ae 100644
--- a/modules/gdnative/net/register_types.cpp
+++ b/modules/gdnative/net/register_types.cpp
@@ -34,9 +34,9 @@
#include "stream_peer_gdnative.h"
void register_net_types() {
- ClassDB::register_class<MultiplayerPeerGDNative>();
- ClassDB::register_class<PacketPeerGDNative>();
- ClassDB::register_class<StreamPeerGDNative>();
+ GDREGISTER_CLASS(MultiplayerPeerGDNative);
+ GDREGISTER_CLASS(PacketPeerGDNative);
+ GDREGISTER_CLASS(StreamPeerGDNative);
}
void unregister_net_types() {
diff --git a/modules/gdnative/pluginscript/register_types.cpp b/modules/gdnative/pluginscript/register_types.cpp
index 433544178f..7faacfdcb9 100644
--- a/modules/gdnative/pluginscript/register_types.cpp
+++ b/modules/gdnative/pluginscript/register_types.cpp
@@ -107,7 +107,7 @@ void GDAPI godot_pluginscript_register_language(const godot_pluginscript_languag
}
void register_pluginscript_types() {
- ClassDB::register_class<PluginScript>();
+ GDREGISTER_CLASS(PluginScript);
}
void unregister_pluginscript_types() {
diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp
index 8e20a2b90d..8e5ae29ed9 100644
--- a/modules/gdnative/register_types.cpp
+++ b/modules/gdnative/register_types.cpp
@@ -259,8 +259,8 @@ void register_gdnative_types() {
EditorNode::add_init_callback(editor_init_callback);
#endif
- ClassDB::register_class<GDNativeLibrary>();
- ClassDB::register_class<GDNative>();
+ GDREGISTER_CLASS(GDNativeLibrary);
+ GDREGISTER_CLASS(GDNative);
resource_loader_gdnlib.instantiate();
ResourceLoader::add_resource_format_loader(resource_loader_gdnlib);
diff --git a/modules/gdnative/text/text_server_gdnative.cpp b/modules/gdnative/text/text_server_gdnative.cpp
index bc4b1ac134..392121c3a9 100644
--- a/modules/gdnative/text/text_server_gdnative.cpp
+++ b/modules/gdnative/text/text_server_gdnative.cpp
@@ -498,6 +498,11 @@ bool TextServerGDNative::shaped_text_update_justification_ops(RID p_shaped) {
return interface->shaped_text_update_justification_ops(data, (godot_rid *)&p_shaped);
}
+void TextServerGDNative::shaped_text_overrun_trim_to_width(RID p_shaped_line, float p_width, uint8_t p_clip_flags) {
+ ERR_FAIL_COND(interface == nullptr);
+ interface->shaped_text_overrun_trim_to_width(data, (godot_rid *)&p_shaped_line, p_width, p_clip_flags);
+};
+
bool TextServerGDNative::shaped_text_is_ready(RID p_shaped) const {
ERR_FAIL_COND_V(interface == nullptr, false);
return interface->shaped_text_is_ready(data, (godot_rid *)&p_shaped);
diff --git a/modules/gdnative/text/text_server_gdnative.h b/modules/gdnative/text/text_server_gdnative.h
index 7e42b16fe1..d613a7ec00 100644
--- a/modules/gdnative/text/text_server_gdnative.h
+++ b/modules/gdnative/text/text_server_gdnative.h
@@ -167,6 +167,8 @@ public:
virtual bool shaped_text_update_breaks(RID p_shaped) override;
virtual bool shaped_text_update_justification_ops(RID p_shaped) override;
+ virtual void shaped_text_overrun_trim_to_width(RID p_shaped, float p_width, uint8_t p_clip_flags) override;
+
virtual bool shaped_text_is_ready(RID p_shaped) const override;
virtual Vector<Glyph> shaped_text_get_glyphs(RID p_shaped) const override;
diff --git a/modules/gdnative/videodecoder/register_types.cpp b/modules/gdnative/videodecoder/register_types.cpp
index e822d42312..54a577a2b6 100644
--- a/modules/gdnative/videodecoder/register_types.cpp
+++ b/modules/gdnative/videodecoder/register_types.cpp
@@ -39,7 +39,7 @@ void register_videodecoder_types() {
resource_loader_vsgdnative.instantiate();
ResourceLoader::add_resource_format_loader(resource_loader_vsgdnative, true);
- ClassDB::register_class<VideoStreamGDNative>();
+ GDREGISTER_CLASS(VideoStreamGDNative);
}
void unregister_videodecoder_types() {
diff --git a/modules/gdnative/xr/register_types.cpp b/modules/gdnative/xr/register_types.cpp
index b60a04f470..cb043debc5 100644
--- a/modules/gdnative/xr/register_types.cpp
+++ b/modules/gdnative/xr/register_types.cpp
@@ -32,7 +32,7 @@
#include "xr_interface_gdnative.h"
void register_xr_types() {
- ClassDB::register_class<XRInterfaceGDNative>();
+ GDREGISTER_CLASS(XRInterfaceGDNative);
ClassDB::add_compatibility_class("ARVRInterfaceGDNative", "XRInterfaceGDNative");
}
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index 397776ba1a..8b12b1eae4 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -1170,7 +1170,7 @@ void GDScript::_init_rpc_methods_properties() {
nd.name = E->key();
nd.rpc_mode = E->get()->get_rpc_mode();
// TODO
- nd.transfer_mode = NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE;
+ nd.transfer_mode = MultiplayerPeer::TRANSFER_MODE_RELIABLE;
nd.channel = 0;
if (-1 == rpc_functions.find(nd)) {
rpc_functions.push_back(nd);
diff --git a/modules/gdscript/language_server/gdscript_language_server.cpp b/modules/gdscript/language_server/gdscript_language_server.cpp
index 33597c286f..c47164d95b 100644
--- a/modules/gdscript/language_server/gdscript_language_server.cpp
+++ b/modules/gdscript/language_server/gdscript_language_server.cpp
@@ -101,7 +101,7 @@ void GDScriptLanguageServer::stop() {
}
void register_lsp_types() {
- ClassDB::register_class<GDScriptLanguageProtocol>();
- ClassDB::register_class<GDScriptTextDocument>();
- ClassDB::register_class<GDScriptWorkspace>();
+ GDREGISTER_CLASS(GDScriptLanguageProtocol);
+ GDREGISTER_CLASS(GDScriptTextDocument);
+ GDREGISTER_CLASS(GDScriptWorkspace);
}
diff --git a/modules/gdscript/language_server/gdscript_text_document.cpp b/modules/gdscript/language_server/gdscript_text_document.cpp
index 030633274c..59d2e6c8fa 100644
--- a/modules/gdscript/language_server/gdscript_text_document.cpp
+++ b/modules/gdscript/language_server/gdscript_text_document.cpp
@@ -40,6 +40,7 @@
void GDScriptTextDocument::_bind_methods() {
ClassDB::bind_method(D_METHOD("didOpen"), &GDScriptTextDocument::didOpen);
+ ClassDB::bind_method(D_METHOD("didClose"), &GDScriptTextDocument::didClose);
ClassDB::bind_method(D_METHOD("didChange"), &GDScriptTextDocument::didChange);
ClassDB::bind_method(D_METHOD("nativeSymbol"), &GDScriptTextDocument::nativeSymbol);
ClassDB::bind_method(D_METHOD("documentSymbol"), &GDScriptTextDocument::documentSymbol);
@@ -61,6 +62,11 @@ void GDScriptTextDocument::didOpen(const Variant &p_param) {
sync_script_content(doc.uri, doc.text);
}
+void GDScriptTextDocument::didClose(const Variant &p_param) {
+ // Left empty on purpose. Godot does nothing special on closing a document,
+ // but it satisfies LSP clients that require didClose be implemented.
+}
+
void GDScriptTextDocument::didChange(const Variant &p_param) {
lsp::TextDocumentItem doc = load_document_item(p_param);
Dictionary dict = p_param;
diff --git a/modules/gdscript/language_server/gdscript_text_document.h b/modules/gdscript/language_server/gdscript_text_document.h
index 17f1d5d5e3..e2987f779c 100644
--- a/modules/gdscript/language_server/gdscript_text_document.h
+++ b/modules/gdscript/language_server/gdscript_text_document.h
@@ -43,6 +43,7 @@ protected:
FileAccess *file_checker;
void didOpen(const Variant &p_param);
+ void didClose(const Variant &p_param);
void didChange(const Variant &p_param);
void sync_script_content(const String &p_path, const String &p_content);
diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp
index ad4ed8bf71..c2b1981f31 100644
--- a/modules/gdscript/register_types.cpp
+++ b/modules/gdscript/register_types.cpp
@@ -112,7 +112,7 @@ static void _editor_init() {
#endif // TOOLS_ENABLED
void register_gdscript_types() {
- ClassDB::register_class<GDScript>();
+ GDREGISTER_CLASS(GDScript);
script_language_gd = memnew(GDScriptLanguage);
ScriptServer::register_language(script_language_gd);
diff --git a/modules/gltf/register_types.cpp b/modules/gltf/register_types.cpp
index d11c7cb9cd..85921490d2 100644
--- a/modules/gltf/register_types.cpp
+++ b/modules/gltf/register_types.cpp
@@ -62,25 +62,25 @@ void register_gltf_types() {
#ifdef TOOLS_ENABLED
ClassDB::APIType prev_api = ClassDB::get_current_api();
ClassDB::set_current_api(ClassDB::API_EDITOR);
- ClassDB::register_class<EditorSceneImporterGLTF>();
- ClassDB::register_class<GLTFMesh>();
+ GDREGISTER_CLASS(EditorSceneImporterGLTF);
+ GDREGISTER_CLASS(GLTFMesh);
EditorPlugins::add_by_type<SceneExporterGLTFPlugin>();
ClassDB::set_current_api(prev_api);
EditorNode::add_init_callback(_editor_init);
#endif
- ClassDB::register_class<GLTFSpecGloss>();
- ClassDB::register_class<GLTFNode>();
- ClassDB::register_class<GLTFAnimation>();
- ClassDB::register_class<GLTFBufferView>();
- ClassDB::register_class<GLTFAccessor>();
- ClassDB::register_class<GLTFTexture>();
- ClassDB::register_class<GLTFSkeleton>();
- ClassDB::register_class<GLTFSkin>();
- ClassDB::register_class<GLTFCamera>();
- ClassDB::register_class<GLTFLight>();
- ClassDB::register_class<GLTFState>();
- ClassDB::register_class<GLTFDocument>();
- ClassDB::register_class<PackedSceneGLTF>();
+ GDREGISTER_CLASS(GLTFSpecGloss);
+ GDREGISTER_CLASS(GLTFNode);
+ GDREGISTER_CLASS(GLTFAnimation);
+ GDREGISTER_CLASS(GLTFBufferView);
+ GDREGISTER_CLASS(GLTFAccessor);
+ GDREGISTER_CLASS(GLTFTexture);
+ GDREGISTER_CLASS(GLTFSkeleton);
+ GDREGISTER_CLASS(GLTFSkin);
+ GDREGISTER_CLASS(GLTFCamera);
+ GDREGISTER_CLASS(GLTFLight);
+ GDREGISTER_CLASS(GLTFState);
+ GDREGISTER_CLASS(GLTFDocument);
+ GDREGISTER_CLASS(PackedSceneGLTF);
#endif
}
diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp
index a2f570e6a5..d894425ce8 100644
--- a/modules/gridmap/grid_map_editor_plugin.cpp
+++ b/modules/gridmap/grid_map_editor_plugin.cpp
@@ -1271,7 +1271,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
info_message->set_text(TTR("Give a MeshLibrary resource to this GridMap to use its meshes."));
info_message->set_valign(Label::VALIGN_CENTER);
info_message->set_align(Label::ALIGN_CENTER);
- info_message->set_autowrap(true);
+ info_message->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART);
info_message->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
info_message->set_anchors_and_offsets_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
mesh_library_palette->add_child(info_message);
diff --git a/modules/gridmap/register_types.cpp b/modules/gridmap/register_types.cpp
index 5680664213..85739d202e 100644
--- a/modules/gridmap/register_types.cpp
+++ b/modules/gridmap/register_types.cpp
@@ -37,7 +37,7 @@
void register_gridmap_types() {
#ifndef _3D_DISABLED
- ClassDB::register_class<GridMap>();
+ GDREGISTER_CLASS(GridMap);
#ifdef TOOLS_ENABLED
EditorPlugins::add_by_type<GridMapEditorPlugin>();
#endif
diff --git a/modules/jsonrpc/register_types.cpp b/modules/jsonrpc/register_types.cpp
index d6b565ba84..8fdf6fe1aa 100644
--- a/modules/jsonrpc/register_types.cpp
+++ b/modules/jsonrpc/register_types.cpp
@@ -33,7 +33,7 @@
#include "jsonrpc.h"
void register_jsonrpc_types() {
- ClassDB::register_class<JSONRPC>();
+ GDREGISTER_CLASS(JSONRPC);
}
void unregister_jsonrpc_types() {
diff --git a/modules/lightmapper_rd/register_types.cpp b/modules/lightmapper_rd/register_types.cpp
index 191bb3d765..ae9c5fc390 100644
--- a/modules/lightmapper_rd/register_types.cpp
+++ b/modules/lightmapper_rd/register_types.cpp
@@ -54,7 +54,7 @@ void register_lightmapper_rd_types() {
GLOBAL_DEF("rendering/lightmapping/bake_quality/ultra_quality_probe_ray_count", 2048);
GLOBAL_DEF("rendering/lightmapping/bake_performance/max_rays_per_probe_pass", 64);
#ifndef _3D_DISABLED
- ClassDB::register_class<LightmapperRD>();
+ GDREGISTER_CLASS(LightmapperRD);
Lightmapper::create_gpu = create_lightmapper_rd;
#endif
}
diff --git a/modules/minimp3/register_types.cpp b/modules/minimp3/register_types.cpp
index 27ea512b69..63f2589f42 100644
--- a/modules/minimp3/register_types.cpp
+++ b/modules/minimp3/register_types.cpp
@@ -45,7 +45,7 @@ void register_minimp3_types() {
ResourceFormatImporter::get_singleton()->add_importer(mp3_import);
}
#endif
- ClassDB::register_class<AudioStreamMP3>();
+ GDREGISTER_CLASS(AudioStreamMP3);
}
void unregister_minimp3_types() {
diff --git a/modules/mobile_vr/register_types.cpp b/modules/mobile_vr/register_types.cpp
index 7d138aa4c9..47d1fe482c 100644
--- a/modules/mobile_vr/register_types.cpp
+++ b/modules/mobile_vr/register_types.cpp
@@ -33,7 +33,7 @@
#include "mobile_vr_interface.h"
void register_mobile_vr_types() {
- ClassDB::register_class<MobileVRInterface>();
+ GDREGISTER_CLASS(MobileVRInterface);
if (XRServer::get_singleton()) {
Ref<MobileVRInterface> mobile_vr;
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index c48230f524..ff6a47f59b 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -1510,6 +1510,7 @@ void CSharpLanguage::free_instance_binding_data(void *p_data) {
}
void CSharpLanguage::refcount_incremented_instance_binding(Object *p_object) {
+#if 0
RefCounted *rc_owner = Object::cast_to<RefCounted>(p_object);
#ifdef DEBUG_ENABLED
@@ -1544,9 +1545,11 @@ void CSharpLanguage::refcount_incremented_instance_binding(Object *p_object) {
gchandle.release();
gchandle = strong_gchandle;
}
+#endif
}
bool CSharpLanguage::refcount_decremented_instance_binding(Object *p_object) {
+#if 0
RefCounted *rc_owner = Object::cast_to<RefCounted>(p_object);
#ifdef DEBUG_ENABLED
@@ -1586,6 +1589,8 @@ bool CSharpLanguage::refcount_decremented_instance_binding(Object *p_object) {
}
return refcount == 0;
+#endif
+ return false;
}
CSharpInstance *CSharpInstance::create_for_managed_type(Object *p_owner, CSharpScript *p_script, const MonoGCHandleData &p_gchandle) {
@@ -2264,8 +2269,10 @@ CSharpInstance::~CSharpInstance() {
// Otherwise, the unsafe reference debug checks will incorrectly detect a bug.
bool die = _unreference_owner_unsafe();
CRASH_COND(die); // `owner_keep_alive` holds a reference, so it can't die
-
+#if 0
void *data = owner->get_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index());
+
+
CRASH_COND(data == nullptr);
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
@@ -2284,6 +2291,7 @@ CSharpInstance::~CSharpInstance() {
// The "instance binding" holds a reference so the refcount should be at least 2 before `scope_keep_owner_alive` goes out of scope
CRASH_COND(rc_owner->reference_get_count() <= 1);
#endif
+#endif
}
if (script.is_valid() && owner) {
@@ -3030,7 +3038,7 @@ void CSharpScript::update_script_class_info(Ref<CSharpScript> p_script) {
nd.name = methods[i]->get_name();
nd.rpc_mode = mode;
// TODO Transfer mode, channel
- nd.transfer_mode = NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE;
+ nd.transfer_mode = MultiplayerPeer::TRANSFER_MODE_RELIABLE;
nd.channel = 0;
if (-1 == p_script->rpc_functions.find(nd)) {
p_script->rpc_functions.push_back(nd);
@@ -3101,7 +3109,7 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
// Hold it alive. Important if we have to dispose a script instance binding before creating the CSharpInstance.
ref = Ref<RefCounted>(static_cast<RefCounted *>(p_owner));
}
-
+#if 0
// If the object had a script instance binding, dispose it before adding the CSharpInstance
if (p_owner->has_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index())) {
void *data = p_owner->get_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index());
@@ -3123,7 +3131,7 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
script_binding.inited = false;
}
}
-
+#endif
CSharpInstance *instance = memnew(CSharpInstance(Ref<CSharpScript>(this)));
instance->base_ref_counted = p_is_ref_counted;
instance->owner = p_owner;
diff --git a/modules/mono/glue/base_object_glue.cpp b/modules/mono/glue/base_object_glue.cpp
index 2b87c2d9a4..2d04cedb9b 100644
--- a/modules/mono/glue/base_object_glue.cpp
+++ b/modules/mono/glue/base_object_glue.cpp
@@ -64,7 +64,7 @@ void godot_icall_Object_Disposed(MonoObject *p_obj, Object *p_ptr) {
return;
}
}
-
+#if 0
void *data = p_ptr->get_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index());
if (data) {
@@ -76,6 +76,7 @@ void godot_icall_Object_Disposed(MonoObject *p_obj, Object *p_ptr) {
}
}
}
+#endif
}
void godot_icall_RefCounted_Disposed(MonoObject *p_obj, Object *p_ptr, MonoBoolean p_is_finalizer) {
@@ -84,7 +85,7 @@ void godot_icall_RefCounted_Disposed(MonoObject *p_obj, Object *p_ptr, MonoBoole
// This is only called with RefCounted derived classes
CRASH_COND(!Object::cast_to<RefCounted>(p_ptr));
#endif
-
+#if 0
RefCounted *rc = static_cast<RefCounted *>(p_ptr);
if (rc->get_script_instance()) {
@@ -124,6 +125,7 @@ void godot_icall_RefCounted_Disposed(MonoObject *p_obj, Object *p_ptr, MonoBoole
}
}
}
+#endif
}
void godot_icall_Object_ConnectEventSignals(Object *p_ptr) {
diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp
index d7df18d5da..d6545d50ec 100644
--- a/modules/mono/mono_gd/gd_mono_internals.cpp
+++ b/modules/mono/mono_gd/gd_mono_internals.cpp
@@ -45,7 +45,7 @@
namespace GDMonoInternals {
void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
// This method should not fail
-
+#if 0
CRASH_COND(!unmanaged);
// All mono objects created from the managed world (e.g.: 'new Player()')
@@ -108,6 +108,7 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
CSharpInstance *csharp_instance = CSharpInstance::create_for_managed_type(unmanaged, script.ptr(), gchandle);
unmanaged->set_script_and_instance(script, csharp_instance);
+#endif
}
void unhandled_exception(MonoException *p_exc) {
diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp
index 0b9a577e01..080398c997 100644
--- a/modules/mono/mono_gd/gd_mono_utils.cpp
+++ b/modules/mono/mono_gd/gd_mono_utils.cpp
@@ -54,6 +54,7 @@
namespace GDMonoUtils {
MonoObject *unmanaged_get_managed(Object *unmanaged) {
+#if 0
if (!unmanaged) {
return nullptr;
}
@@ -120,6 +121,8 @@ MonoObject *unmanaged_get_managed(Object *unmanaged) {
}
return mono_object;
+#endif
+ return nullptr;
}
void set_main_thread(MonoThread *p_thread) {
diff --git a/modules/mono/register_types.cpp b/modules/mono/register_types.cpp
index b4a6bfdcd4..2ba89eac55 100644
--- a/modules/mono/register_types.cpp
+++ b/modules/mono/register_types.cpp
@@ -41,11 +41,11 @@ Ref<ResourceFormatSaverCSharpScript> resource_saver_cs;
_GodotSharp *_godotsharp = nullptr;
void register_mono_types() {
- ClassDB::register_class<CSharpScript>();
+ GDREGISTER_CLASS(CSharpScript);
_godotsharp = memnew(_GodotSharp);
- ClassDB::register_class<_GodotSharp>();
+ GDREGISTER_CLASS(_GodotSharp);
Engine::get_singleton()->add_singleton(Engine::Singleton("GodotSharp", _GodotSharp::get_singleton()));
script_language_cs = memnew(CSharpLanguage);
diff --git a/modules/navigation/register_types.cpp b/modules/navigation/register_types.cpp
index 0f3c412d4a..97c01d42ab 100644
--- a/modules/navigation/register_types.cpp
+++ b/modules/navigation/register_types.cpp
@@ -56,7 +56,7 @@ void register_navigation_types() {
#ifndef _3D_DISABLED
_nav_mesh_generator = memnew(NavigationMeshGenerator);
- ClassDB::register_class<NavigationMeshGenerator>();
+ GDREGISTER_CLASS(NavigationMeshGenerator);
Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationMeshGenerator", NavigationMeshGenerator::get_singleton()));
#endif
diff --git a/modules/opensimplex/register_types.cpp b/modules/opensimplex/register_types.cpp
index e9735a2cc8..d6f9f3436d 100644
--- a/modules/opensimplex/register_types.cpp
+++ b/modules/opensimplex/register_types.cpp
@@ -33,8 +33,8 @@
#include "open_simplex_noise.h"
void register_opensimplex_types() {
- ClassDB::register_class<OpenSimplexNoise>();
- ClassDB::register_class<NoiseTexture>();
+ GDREGISTER_CLASS(OpenSimplexNoise);
+ GDREGISTER_CLASS(NoiseTexture);
}
void unregister_opensimplex_types() {
diff --git a/modules/regex/register_types.cpp b/modules/regex/register_types.cpp
index 82f3eaf707..03957f88cf 100644
--- a/modules/regex/register_types.cpp
+++ b/modules/regex/register_types.cpp
@@ -33,8 +33,8 @@
#include "regex.h"
void register_regex_types() {
- ClassDB::register_class<RegExMatch>();
- ClassDB::register_class<RegEx>();
+ GDREGISTER_CLASS(RegExMatch);
+ GDREGISTER_CLASS(RegEx);
}
void unregister_regex_types() {
diff --git a/modules/stb_vorbis/register_types.cpp b/modules/stb_vorbis/register_types.cpp
index d9c6c06d65..bdb1cf69cf 100644
--- a/modules/stb_vorbis/register_types.cpp
+++ b/modules/stb_vorbis/register_types.cpp
@@ -45,7 +45,7 @@ void register_stb_vorbis_types() {
ResourceFormatImporter::get_singleton()->add_importer(ogg_import);
}
#endif
- ClassDB::register_class<AudioStreamOGGVorbis>();
+ GDREGISTER_CLASS(AudioStreamOGGVorbis);
}
void unregister_stb_vorbis_types() {
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp
index 906ebe4993..72c5ccc699 100644
--- a/modules/text_server_adv/text_server_adv.cpp
+++ b/modules/text_server_adv/text_server_adv.cpp
@@ -1658,6 +1658,161 @@ float TextServerAdvanced::shaped_text_tab_align(RID p_shaped, const Vector<float
return 0.f;
}
+void TextServerAdvanced::shaped_text_overrun_trim_to_width(RID p_shaped_line, float p_width, uint8_t p_clip_flags) {
+ _THREAD_SAFE_METHOD_
+ ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped_line);
+ ERR_FAIL_COND_MSG(!sd, "ShapedTextDataAdvanced invalid.");
+ if (!sd->valid) {
+ shaped_text_shape(p_shaped_line);
+ }
+
+ bool add_ellipsis = (p_clip_flags & OVERRUN_ADD_ELLIPSIS) == OVERRUN_ADD_ELLIPSIS;
+ bool cut_per_word = (p_clip_flags & OVERRUN_TRIM_WORD_ONLY) == OVERRUN_TRIM_WORD_ONLY;
+ bool enforce_ellipsis = (p_clip_flags & OVERRUN_ENFORCE_ELLIPSIS) == OVERRUN_ENFORCE_ELLIPSIS;
+
+ Glyph *sd_glyphs = sd->glyphs.ptrw();
+
+ if ((p_clip_flags & OVERRUN_TRIM) == OVERRUN_NO_TRIMMING || sd_glyphs == nullptr || p_width <= 0 || !(sd->width > p_width || enforce_ellipsis)) {
+ return;
+ }
+
+ int sd_size = sd->glyphs.size();
+ RID last_gl_font_rid = sd_glyphs[sd_size - 1].font_rid;
+ int last_gl_font_size = sd_glyphs[sd_size - 1].font_size;
+ uint32_t dot_gl_idx = font_get_glyph_index(last_gl_font_rid, '.');
+ Vector2 dot_adv = font_get_glyph_advance(last_gl_font_rid, dot_gl_idx, last_gl_font_size);
+ uint32_t whitespace_gl_idx = font_get_glyph_index(last_gl_font_rid, ' ');
+ Vector2 whitespace_adv = font_get_glyph_advance(last_gl_font_rid, whitespace_gl_idx, last_gl_font_size);
+
+ int ellipsis_advance = 0;
+ if (add_ellipsis) {
+ ellipsis_advance = 3 * dot_adv.x + font_get_spacing_glyph(last_gl_font_rid) + (cut_per_word ? whitespace_adv.x : 0);
+ }
+
+ int ell_min_characters = 6;
+ float width = sd->width;
+
+ bool is_rtl = sd->direction == DIRECTION_RTL || (sd->direction == DIRECTION_AUTO && sd->para_direction == DIRECTION_RTL);
+
+ int trim_pos = (is_rtl) ? sd_size : 0;
+ int ellipsis_pos = (enforce_ellipsis) ? 0 : -1;
+
+ int last_valid_cut = 0;
+ bool found = false;
+
+ int glyphs_from = (is_rtl) ? 0 : sd_size - 1;
+ int glyphs_to = (is_rtl) ? sd_size - 1 : -1;
+ int glyphs_delta = (is_rtl) ? +1 : -1;
+
+ for (int i = glyphs_from; i != glyphs_to; i += glyphs_delta) {
+ if (!is_rtl) {
+ width -= sd_glyphs[i].advance;
+ }
+ if (sd_glyphs[i].count > 0) {
+ bool above_min_char_treshold = ((is_rtl) ? sd_size - 1 - i : i) >= ell_min_characters;
+
+ if (width + (((above_min_char_treshold && add_ellipsis) || enforce_ellipsis) ? ellipsis_advance : 0) <= p_width) {
+ if (cut_per_word && above_min_char_treshold) {
+ if ((sd_glyphs[i].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT) {
+ last_valid_cut = i;
+ found = true;
+ }
+ } else {
+ last_valid_cut = i;
+ found = true;
+ }
+ if (found) {
+ trim_pos = last_valid_cut;
+
+ if (above_min_char_treshold && width - ellipsis_advance <= p_width) {
+ ellipsis_pos = trim_pos;
+ }
+ break;
+ }
+ }
+ }
+ if (is_rtl) {
+ width -= sd_glyphs[i].advance;
+ }
+ }
+
+ if ((trim_pos >= 0 && sd->width > p_width) || enforce_ellipsis) {
+ int added_glyphs = 0;
+ if (add_ellipsis && (ellipsis_pos > 0 || enforce_ellipsis)) {
+ // Insert an additional space when cutting word bound for aesthetics.
+ if (cut_per_word && (ellipsis_pos > 0)) {
+ TextServer::Glyph gl;
+ gl.start = sd_glyphs[ellipsis_pos].start;
+ gl.end = sd_glyphs[ellipsis_pos].end;
+ gl.count = 1;
+ gl.advance = whitespace_adv.x;
+ gl.index = whitespace_gl_idx;
+ gl.font_rid = last_gl_font_rid;
+ gl.font_size = last_gl_font_size;
+ gl.flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_BREAK_SOFT | GRAPHEME_IS_VIRTUAL | (is_rtl ? GRAPHEME_IS_RTL : 0);
+
+ // Optimized glyph insertion by replacing a glyph whenever possible.
+ int glyph_idx = trim_pos + ((is_rtl) ? (-added_glyphs - 1) : added_glyphs);
+ if (is_rtl) {
+ if (glyph_idx < 0) {
+ sd->glyphs.insert(0, gl);
+ } else {
+ sd->glyphs.set(glyph_idx, gl);
+ }
+ } else {
+ if (glyph_idx > (sd_size - 1)) {
+ sd->glyphs.append(gl);
+ } else {
+ sd->glyphs.set(glyph_idx, gl);
+ }
+ }
+ added_glyphs++;
+ }
+ // Add ellipsis dots.
+ for (int d = 0; d < 3; d++) {
+ TextServer::Glyph gl;
+ gl.start = sd_glyphs[ellipsis_pos].start;
+ gl.end = sd_glyphs[ellipsis_pos].end;
+ gl.count = 1;
+ gl.advance = dot_adv.x;
+ gl.index = dot_gl_idx;
+ gl.font_rid = last_gl_font_rid;
+ gl.font_size = last_gl_font_size;
+ gl.flags = GRAPHEME_IS_PUNCTUATION | GRAPHEME_IS_VIRTUAL | (is_rtl ? GRAPHEME_IS_RTL : 0);
+
+ // Optimized glyph insertion by replacing a glyph whenever possible.
+ int glyph_idx = trim_pos + ((is_rtl) ? (-added_glyphs - 1) : added_glyphs);
+ if (is_rtl) {
+ if (glyph_idx < 0) {
+ sd->glyphs.insert(0, gl);
+ } else {
+ sd->glyphs.set(glyph_idx, gl);
+ }
+ } else {
+ if (glyph_idx > (sd_size - 1)) {
+ sd->glyphs.append(gl);
+ } else {
+ sd->glyphs.set(glyph_idx, gl);
+ }
+ }
+ added_glyphs++;
+ }
+ }
+
+ // Cut the remaining glyphs off.
+ if (!is_rtl) {
+ sd->glyphs.resize(trim_pos + added_glyphs);
+ } else {
+ if (trim_pos - added_glyphs >= 0) {
+ sd->glyphs = sd->glyphs.subarray(trim_pos - added_glyphs, sd->glyphs.size() - 1);
+ }
+ }
+
+ // Update to correct width.
+ sd->width = width + ((ellipsis_pos != -1) ? ellipsis_advance : 0);
+ }
+}
+
bool TextServerAdvanced::shaped_text_update_breaks(RID p_shaped) {
_THREAD_SAFE_METHOD_
ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped);
diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h
index 4ad23ca059..3c4f840bfd 100644
--- a/modules/text_server_adv/text_server_adv.h
+++ b/modules/text_server_adv/text_server_adv.h
@@ -229,6 +229,8 @@ public:
virtual bool shaped_text_update_breaks(RID p_shaped) override;
virtual bool shaped_text_update_justification_ops(RID p_shaped) override;
+ virtual void shaped_text_overrun_trim_to_width(RID p_shaped, float p_width, uint8_t p_clip_flags) override;
+
virtual bool shaped_text_is_ready(RID p_shaped) const override;
virtual Vector<Glyph> shaped_text_get_glyphs(RID p_shaped) const override;
diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp
index a22559efdd..576d130cc0 100644
--- a/modules/text_server_fb/text_server_fb.cpp
+++ b/modules/text_server_fb/text_server_fb.cpp
@@ -1141,6 +1141,161 @@ bool TextServerFallback::shaped_text_update_justification_ops(RID p_shaped) {
return true;
}
+void TextServerFallback::shaped_text_overrun_trim_to_width(RID p_shaped_line, float p_width, uint8_t p_clip_flags) {
+ _THREAD_SAFE_METHOD_
+ ShapedTextData *sd = shaped_owner.getornull(p_shaped_line);
+ ERR_FAIL_COND_MSG(!sd, "ShapedTextDataAdvanced invalid.");
+ if (!sd->valid) {
+ shaped_text_shape(p_shaped_line);
+ }
+
+ bool add_ellipsis = (p_clip_flags & OVERRUN_ADD_ELLIPSIS) == OVERRUN_ADD_ELLIPSIS;
+ bool cut_per_word = (p_clip_flags & OVERRUN_TRIM_WORD_ONLY) == OVERRUN_TRIM_WORD_ONLY;
+ bool enforce_ellipsis = (p_clip_flags & OVERRUN_ENFORCE_ELLIPSIS) == OVERRUN_ENFORCE_ELLIPSIS;
+
+ Glyph *sd_glyphs = sd->glyphs.ptrw();
+
+ if ((p_clip_flags & OVERRUN_TRIM) == OVERRUN_NO_TRIMMING || sd_glyphs == nullptr || p_width <= 0 || !(sd->width > p_width || enforce_ellipsis)) {
+ return;
+ }
+
+ int sd_size = sd->glyphs.size();
+ RID last_gl_font_rid = sd_glyphs[sd_size - 1].font_rid;
+ int last_gl_font_size = sd_glyphs[sd_size - 1].font_size;
+ uint32_t dot_gl_idx = font_get_glyph_index(last_gl_font_rid, '.');
+ Vector2 dot_adv = font_get_glyph_advance(last_gl_font_rid, dot_gl_idx, last_gl_font_size);
+ uint32_t whitespace_gl_idx = font_get_glyph_index(last_gl_font_rid, ' ');
+ Vector2 whitespace_adv = font_get_glyph_advance(last_gl_font_rid, whitespace_gl_idx, last_gl_font_size);
+
+ int ellipsis_advance = 0;
+ if (add_ellipsis) {
+ ellipsis_advance = 3 * dot_adv.x + font_get_spacing_glyph(last_gl_font_rid) + (cut_per_word ? whitespace_adv.x : 0);
+ }
+
+ int ell_min_characters = 6;
+ float width = sd->width;
+
+ bool is_rtl = sd->direction == DIRECTION_RTL || (sd->direction == DIRECTION_AUTO && sd->para_direction == DIRECTION_RTL);
+
+ int trim_pos = (is_rtl) ? sd_size : 0;
+ int ellipsis_pos = (enforce_ellipsis) ? 0 : -1;
+
+ int last_valid_cut = 0;
+ bool found = false;
+
+ int glyphs_from = (is_rtl) ? 0 : sd_size - 1;
+ int glyphs_to = (is_rtl) ? sd_size - 1 : -1;
+ int glyphs_delta = (is_rtl) ? +1 : -1;
+
+ for (int i = glyphs_from; i != glyphs_to; i += glyphs_delta) {
+ if (!is_rtl) {
+ width -= sd_glyphs[i].advance;
+ }
+ if (sd_glyphs[i].count > 0) {
+ bool above_min_char_treshold = ((is_rtl) ? sd_size - 1 - i : i) >= ell_min_characters;
+
+ if (width + (((above_min_char_treshold && add_ellipsis) || enforce_ellipsis) ? ellipsis_advance : 0) <= p_width) {
+ if (cut_per_word && above_min_char_treshold) {
+ if ((sd_glyphs[i].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT) {
+ last_valid_cut = i;
+ found = true;
+ }
+ } else {
+ last_valid_cut = i;
+ found = true;
+ }
+ if (found) {
+ trim_pos = last_valid_cut;
+
+ if (above_min_char_treshold && width - ellipsis_advance <= p_width) {
+ ellipsis_pos = trim_pos;
+ }
+ break;
+ }
+ }
+ }
+ if (is_rtl) {
+ width -= sd_glyphs[i].advance;
+ }
+ }
+
+ if ((trim_pos >= 0 && sd->width > p_width) || enforce_ellipsis) {
+ int added_glyphs = 0;
+ if (add_ellipsis && (ellipsis_pos > 0 || enforce_ellipsis)) {
+ // Insert an additional space when cutting word bound for aesthetics.
+ if (cut_per_word && (ellipsis_pos > 0)) {
+ TextServer::Glyph gl;
+ gl.start = sd_glyphs[ellipsis_pos].start;
+ gl.end = sd_glyphs[ellipsis_pos].end;
+ gl.count = 1;
+ gl.advance = whitespace_adv.x;
+ gl.index = whitespace_gl_idx;
+ gl.font_rid = last_gl_font_rid;
+ gl.font_size = last_gl_font_size;
+ gl.flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_BREAK_SOFT | GRAPHEME_IS_VIRTUAL | (is_rtl ? GRAPHEME_IS_RTL : 0);
+
+ // Optimized glyph insertion by replacing a glyph whenever possible.
+ int glyph_idx = trim_pos + ((is_rtl) ? -added_glyphs : added_glyphs);
+ if (is_rtl) {
+ if (glyph_idx < 0) {
+ sd->glyphs.insert(0, gl);
+ } else {
+ sd->glyphs.set(glyph_idx, gl);
+ }
+ } else {
+ if (glyph_idx > (sd_size - 1)) {
+ sd->glyphs.append(gl);
+ } else {
+ sd->glyphs.set(glyph_idx, gl);
+ }
+ }
+ added_glyphs++;
+ }
+ // Add ellipsis dots.
+ for (int d = 0; d < 3; d++) {
+ TextServer::Glyph gl;
+ gl.start = sd_glyphs[ellipsis_pos].start;
+ gl.end = sd_glyphs[ellipsis_pos].end;
+ gl.count = 1;
+ gl.advance = dot_adv.x;
+ gl.index = dot_gl_idx;
+ gl.font_rid = last_gl_font_rid;
+ gl.font_size = last_gl_font_size;
+ gl.flags = GRAPHEME_IS_PUNCTUATION | GRAPHEME_IS_VIRTUAL | (is_rtl ? GRAPHEME_IS_RTL : 0);
+
+ // Optimized glyph insertion by replacing a glyph whenever possible.
+ int glyph_idx = trim_pos + ((is_rtl) ? -added_glyphs : added_glyphs);
+ if (is_rtl) {
+ if (glyph_idx < 0) {
+ sd->glyphs.insert(0, gl);
+ } else {
+ sd->glyphs.set(glyph_idx, gl);
+ }
+ } else {
+ if (glyph_idx > (sd_size - 1)) {
+ sd->glyphs.append(gl);
+ } else {
+ sd->glyphs.set(glyph_idx, gl);
+ }
+ }
+ added_glyphs++;
+ }
+ }
+
+ // Cut the remaining glyphs off.
+ if (!is_rtl) {
+ sd->glyphs.resize(trim_pos + added_glyphs);
+ } else {
+ for (int ridx = 0; ridx <= trim_pos - added_glyphs; ridx++) {
+ sd->glyphs.remove(0);
+ }
+ }
+
+ // Update to correct width.
+ sd->width = width + ((ellipsis_pos != -1) ? ellipsis_advance : 0);
+ }
+}
+
bool TextServerFallback::shaped_text_shape(RID p_shaped) {
_THREAD_SAFE_METHOD_
ShapedTextData *sd = shaped_owner.getornull(p_shaped);
diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h
index 8f5eb1d315..b70c8f4ec0 100644
--- a/modules/text_server_fb/text_server_fb.h
+++ b/modules/text_server_fb/text_server_fb.h
@@ -178,6 +178,8 @@ public:
virtual bool shaped_text_update_breaks(RID p_shaped) override;
virtual bool shaped_text_update_justification_ops(RID p_shaped) override;
+ virtual void shaped_text_overrun_trim_to_width(RID p_shaped, float p_width, uint8_t p_clip_flags) override;
+
virtual bool shaped_text_is_ready(RID p_shaped) const override;
virtual Vector<Glyph> shaped_text_get_glyphs(RID p_shaped) const override;
diff --git a/modules/theora/register_types.cpp b/modules/theora/register_types.cpp
index fd6c9dcd3c..55148a6b87 100644
--- a/modules/theora/register_types.cpp
+++ b/modules/theora/register_types.cpp
@@ -38,7 +38,7 @@ void register_theora_types() {
resource_loader_theora.instantiate();
ResourceLoader::add_resource_format_loader(resource_loader_theora, true);
- ClassDB::register_class<VideoStreamTheora>();
+ GDREGISTER_CLASS(VideoStreamTheora);
}
void unregister_theora_types() {
diff --git a/modules/upnp/register_types.cpp b/modules/upnp/register_types.cpp
index a5ee39517f..1e5edd3602 100644
--- a/modules/upnp/register_types.cpp
+++ b/modules/upnp/register_types.cpp
@@ -36,8 +36,8 @@
#include "upnp_device.h"
void register_upnp_types() {
- ClassDB::register_class<UPNP>();
- ClassDB::register_class<UPNPDevice>();
+ GDREGISTER_CLASS(UPNP);
+ GDREGISTER_CLASS(UPNPDevice);
}
void unregister_upnp_types() {
diff --git a/modules/vhacd/register_types.cpp b/modules/vhacd/register_types.cpp
index daad39bdfb..3d7aaee921 100644
--- a/modules/vhacd/register_types.cpp
+++ b/modules/vhacd/register_types.cpp
@@ -32,7 +32,7 @@
#include "scene/resources/mesh.h"
#include "thirdparty/vhacd/public/VHACD.h"
-static Vector<Vector<Face3>> convex_decompose(const Vector<Face3> &p_faces) {
+static Vector<Vector<Face3>> convex_decompose(const Vector<Face3> &p_faces, int p_max_convex_hulls = -1) {
Vector<float> vertices;
vertices.resize(p_faces.size() * 9);
Vector<uint32_t> indices;
@@ -47,8 +47,12 @@ static Vector<Vector<Face3>> convex_decompose(const Vector<Face3> &p_faces) {
}
}
- VHACD::IVHACD *decomposer = VHACD::CreateVHACD();
VHACD::IVHACD::Parameters params;
+ if (p_max_convex_hulls > 0) {
+ params.m_maxConvexHulls = p_max_convex_hulls;
+ }
+
+ VHACD::IVHACD *decomposer = VHACD::CreateVHACD();
decomposer->Compute(vertices.ptr(), vertices.size() / 3, indices.ptr(), indices.size() / 3, params);
int hull_count = decomposer->GetNConvexHulls();
diff --git a/modules/visual_script/register_types.cpp b/modules/visual_script/register_types.cpp
index 4c7b66e368..f20ef046a3 100644
--- a/modules/visual_script/register_types.cpp
+++ b/modules/visual_script/register_types.cpp
@@ -51,59 +51,59 @@ void register_visual_script_types() {
//script_language_gd->init();
ScriptServer::register_language(visual_script_language);
- ClassDB::register_class<VisualScript>();
- ClassDB::register_virtual_class<VisualScriptNode>();
- ClassDB::register_class<VisualScriptFunctionState>();
- ClassDB::register_class<VisualScriptFunction>();
- ClassDB::register_virtual_class<VisualScriptLists>();
- ClassDB::register_class<VisualScriptComposeArray>();
- ClassDB::register_class<VisualScriptOperator>();
- ClassDB::register_class<VisualScriptVariableSet>();
- ClassDB::register_class<VisualScriptVariableGet>();
- ClassDB::register_class<VisualScriptConstant>();
- ClassDB::register_class<VisualScriptIndexGet>();
- ClassDB::register_class<VisualScriptIndexSet>();
- ClassDB::register_class<VisualScriptGlobalConstant>();
- ClassDB::register_class<VisualScriptClassConstant>();
- ClassDB::register_class<VisualScriptMathConstant>();
- ClassDB::register_class<VisualScriptBasicTypeConstant>();
- ClassDB::register_class<VisualScriptEngineSingleton>();
- ClassDB::register_class<VisualScriptSceneNode>();
- ClassDB::register_class<VisualScriptSceneTree>();
- ClassDB::register_class<VisualScriptResourcePath>();
- ClassDB::register_class<VisualScriptSelf>();
- ClassDB::register_class<VisualScriptCustomNode>();
- ClassDB::register_class<VisualScriptSubCall>();
- ClassDB::register_class<VisualScriptComment>();
- ClassDB::register_class<VisualScriptConstructor>();
- ClassDB::register_class<VisualScriptLocalVar>();
- ClassDB::register_class<VisualScriptLocalVarSet>();
- ClassDB::register_class<VisualScriptInputAction>();
- ClassDB::register_class<VisualScriptDeconstruct>();
- ClassDB::register_class<VisualScriptPreload>();
- ClassDB::register_class<VisualScriptTypeCast>();
-
- ClassDB::register_class<VisualScriptFunctionCall>();
- ClassDB::register_class<VisualScriptPropertySet>();
- ClassDB::register_class<VisualScriptPropertyGet>();
+ GDREGISTER_CLASS(VisualScript);
+ GDREGISTER_VIRTUAL_CLASS(VisualScriptNode);
+ GDREGISTER_CLASS(VisualScriptFunctionState);
+ GDREGISTER_CLASS(VisualScriptFunction);
+ GDREGISTER_VIRTUAL_CLASS(VisualScriptLists);
+ GDREGISTER_CLASS(VisualScriptComposeArray);
+ GDREGISTER_CLASS(VisualScriptOperator);
+ GDREGISTER_CLASS(VisualScriptVariableSet);
+ GDREGISTER_CLASS(VisualScriptVariableGet);
+ GDREGISTER_CLASS(VisualScriptConstant);
+ GDREGISTER_CLASS(VisualScriptIndexGet);
+ GDREGISTER_CLASS(VisualScriptIndexSet);
+ GDREGISTER_CLASS(VisualScriptGlobalConstant);
+ GDREGISTER_CLASS(VisualScriptClassConstant);
+ GDREGISTER_CLASS(VisualScriptMathConstant);
+ GDREGISTER_CLASS(VisualScriptBasicTypeConstant);
+ GDREGISTER_CLASS(VisualScriptEngineSingleton);
+ GDREGISTER_CLASS(VisualScriptSceneNode);
+ GDREGISTER_CLASS(VisualScriptSceneTree);
+ GDREGISTER_CLASS(VisualScriptResourcePath);
+ GDREGISTER_CLASS(VisualScriptSelf);
+ GDREGISTER_CLASS(VisualScriptCustomNode);
+ GDREGISTER_CLASS(VisualScriptSubCall);
+ GDREGISTER_CLASS(VisualScriptComment);
+ GDREGISTER_CLASS(VisualScriptConstructor);
+ GDREGISTER_CLASS(VisualScriptLocalVar);
+ GDREGISTER_CLASS(VisualScriptLocalVarSet);
+ GDREGISTER_CLASS(VisualScriptInputAction);
+ GDREGISTER_CLASS(VisualScriptDeconstruct);
+ GDREGISTER_CLASS(VisualScriptPreload);
+ GDREGISTER_CLASS(VisualScriptTypeCast);
+
+ GDREGISTER_CLASS(VisualScriptFunctionCall);
+ GDREGISTER_CLASS(VisualScriptPropertySet);
+ GDREGISTER_CLASS(VisualScriptPropertyGet);
//ClassDB::register_type<VisualScriptScriptCall>();
- ClassDB::register_class<VisualScriptEmitSignal>();
+ GDREGISTER_CLASS(VisualScriptEmitSignal);
- ClassDB::register_class<VisualScriptReturn>();
- ClassDB::register_class<VisualScriptCondition>();
- ClassDB::register_class<VisualScriptWhile>();
- ClassDB::register_class<VisualScriptIterator>();
- ClassDB::register_class<VisualScriptSequence>();
- //ClassDB::register_class<VisualScriptInputFilter>();
- ClassDB::register_class<VisualScriptSwitch>();
- ClassDB::register_class<VisualScriptSelect>();
+ GDREGISTER_CLASS(VisualScriptReturn);
+ GDREGISTER_CLASS(VisualScriptCondition);
+ GDREGISTER_CLASS(VisualScriptWhile);
+ GDREGISTER_CLASS(VisualScriptIterator);
+ GDREGISTER_CLASS(VisualScriptSequence);
+ //GDREGISTER_CLASS(VisualScriptInputFilter);
+ GDREGISTER_CLASS(VisualScriptSwitch);
+ GDREGISTER_CLASS(VisualScriptSelect);
- ClassDB::register_class<VisualScriptYield>();
- ClassDB::register_class<VisualScriptYieldSignal>();
+ GDREGISTER_CLASS(VisualScriptYield);
+ GDREGISTER_CLASS(VisualScriptYieldSignal);
- ClassDB::register_class<VisualScriptBuiltinFunc>();
+ GDREGISTER_CLASS(VisualScriptBuiltinFunc);
- ClassDB::register_class<VisualScriptExpression>();
+ GDREGISTER_CLASS(VisualScriptExpression);
register_visual_script_nodes();
register_visual_script_func_nodes();
@@ -114,7 +114,7 @@ void register_visual_script_types() {
#ifdef TOOLS_ENABLED
ClassDB::set_current_api(ClassDB::API_EDITOR);
- ClassDB::register_class<_VisualScriptEditor>();
+ GDREGISTER_CLASS(_VisualScriptEditor);
ClassDB::set_current_api(ClassDB::API_CORE);
vs_editor_singleton = memnew(_VisualScriptEditor);
Engine::get_singleton()->add_singleton(Engine::Singleton("VisualScriptEditor", _VisualScriptEditor::get_singleton()));
diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp
index d49060bea8..c4b3f9ba44 100644
--- a/modules/visual_script/visual_script.cpp
+++ b/modules/visual_script/visual_script.cpp
@@ -1025,7 +1025,7 @@ void VisualScript::_set_data(const Dictionary &p_data) {
MultiplayerAPI::RPCConfig nd;
nd.name = E->get();
nd.rpc_mode = vsf->get_rpc_mode();
- nd.transfer_mode = NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE; // TODO
+ nd.transfer_mode = MultiplayerPeer::TRANSFER_MODE_RELIABLE; // TODO
if (rpc_functions.find(nd) == -1) {
rpc_functions.push_back(nd);
}
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index 69920a81b6..8712bfa06b 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -1428,7 +1428,7 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt
undo_redo->add_do_method(script.ptr(), "add_function", name, fn_id);
undo_redo->add_do_method(script.ptr(), "add_node", fn_id, func_node, pos);
undo_redo->add_undo_method(script.ptr(), "remove_function", name);
- undo_redo->add_do_method(script.ptr(), "remove_node", fn_id);
+ undo_redo->add_undo_method(script.ptr(), "remove_node", fn_id);
undo_redo->add_do_method(this, "_update_members");
undo_redo->add_undo_method(this, "_update_members");
undo_redo->add_do_method(this, "_update_graph");
diff --git a/modules/webm/register_types.cpp b/modules/webm/register_types.cpp
index 9cfaba83c1..8f690a6892 100644
--- a/modules/webm/register_types.cpp
+++ b/modules/webm/register_types.cpp
@@ -38,7 +38,7 @@ void register_webm_types() {
resource_loader_webm.instantiate();
ResourceLoader::add_resource_format_loader(resource_loader_webm, true);
- ClassDB::register_class<VideoStreamWebm>();
+ GDREGISTER_CLASS(VideoStreamWebm);
}
void unregister_webm_types() {
diff --git a/modules/webrtc/config.py b/modules/webrtc/config.py
index 0a075ccef1..3281415f38 100644
--- a/modules/webrtc/config.py
+++ b/modules/webrtc/config.py
@@ -10,7 +10,7 @@ def get_doc_classes():
return [
"WebRTCPeerConnection",
"WebRTCDataChannel",
- "WebRTCMultiplayer",
+ "WebRTCMultiplayerPeer",
]
diff --git a/modules/webrtc/doc_classes/WebRTCMultiplayer.xml b/modules/webrtc/doc_classes/WebRTCMultiplayerPeer.xml
index 5b9459bc27..26c5bfa6ce 100644
--- a/modules/webrtc/doc_classes/WebRTCMultiplayer.xml
+++ b/modules/webrtc/doc_classes/WebRTCMultiplayerPeer.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="WebRTCMultiplayer" inherits="NetworkedMultiplayerPeer" version="4.0">
+<class name="WebRTCMultiplayerPeer" inherits="MultiplayerPeer" version="4.0">
<brief_description>
A simple interface to create a peer-to-peer mesh network composed of [WebRTCPeerConnection] that is compatible with the [MultiplayerAPI].
</brief_description>
<description>
This class constructs a full mesh of [WebRTCPeerConnection] (one connection for each peer) that can be used as a [member MultiplayerAPI.network_peer].
You can add each [WebRTCPeerConnection] via [method add_peer] or remove them via [method remove_peer]. Peers must be added in [constant WebRTCPeerConnection.STATE_NEW] state to allow it to create the appropriate channels. This class will not create offers nor set descriptions, it will only poll them, and notify connections and disconnections.
- [signal NetworkedMultiplayerPeer.connection_succeeded] and [signal NetworkedMultiplayerPeer.server_disconnected] will not be emitted unless [code]server_compatibility[/code] is [code]true[/code] in [method initialize]. Beside that data transfer works like in a [NetworkedMultiplayerPeer].
+ [signal MultiplayerPeer.connection_succeeded] and [signal MultiplayerPeer.server_disconnected] will not be emitted unless [code]server_compatibility[/code] is [code]true[/code] in [method initialize]. Beside that data transfer works like in a [MultiplayerPeer].
</description>
<tutorials>
</tutorials>
@@ -66,8 +66,8 @@
</argument>
<description>
Initialize the multiplayer peer with the given [code]peer_id[/code] (must be between 1 and 2147483647).
- If [code]server_compatibilty[/code] is [code]false[/code] (default), the multiplayer peer will be immediately in state [constant NetworkedMultiplayerPeer.CONNECTION_CONNECTED] and [signal NetworkedMultiplayerPeer.connection_succeeded] will not be emitted.
- If [code]server_compatibilty[/code] is [code]true[/code] the peer will suppress all [signal NetworkedMultiplayerPeer.peer_connected] signals until a peer with id [constant NetworkedMultiplayerPeer.TARGET_PEER_SERVER] connects and then emit [signal NetworkedMultiplayerPeer.connection_succeeded]. After that the signal [signal NetworkedMultiplayerPeer.peer_connected] will be emitted for every already connected peer, and any new peer that might connect. If the server peer disconnects after that, signal [signal NetworkedMultiplayerPeer.server_disconnected] will be emitted and state will become [constant NetworkedMultiplayerPeer.CONNECTION_CONNECTED].
+ If [code]server_compatibilty[/code] is [code]false[/code] (default), the multiplayer peer will be immediately in state [constant MultiplayerPeer.CONNECTION_CONNECTED] and [signal MultiplayerPeer.connection_succeeded] will not be emitted.
+ If [code]server_compatibilty[/code] is [code]true[/code] the peer will suppress all [signal MultiplayerPeer.peer_connected] signals until a peer with id [constant MultiplayerPeer.TARGET_PEER_SERVER] connects and then emit [signal MultiplayerPeer.connection_succeeded]. After that the signal [signal MultiplayerPeer.peer_connected] will be emitted for every already connected peer, and any new peer that might connect. If the server peer disconnects after that, signal [signal MultiplayerPeer.server_disconnected] will be emitted and state will become [constant MultiplayerPeer.CONNECTION_CONNECTED].
</description>
</method>
<method name="remove_peer">
@@ -76,13 +76,13 @@
<argument index="0" name="peer_id" type="int">
</argument>
<description>
- Remove the peer with given [code]peer_id[/code] from the mesh. If the peer was connected, and [signal NetworkedMultiplayerPeer.peer_connected] was emitted for it, then [signal NetworkedMultiplayerPeer.peer_disconnected] will be emitted.
+ Remove the peer with given [code]peer_id[/code] from the mesh. If the peer was connected, and [signal MultiplayerPeer.peer_connected] was emitted for it, then [signal MultiplayerPeer.peer_disconnected] will be emitted.
</description>
</method>
</methods>
<members>
<member name="refuse_new_connections" type="bool" setter="set_refuse_new_connections" getter="is_refusing_new_connections" override="true" default="false" />
- <member name="transfer_mode" type="int" setter="set_transfer_mode" getter="get_transfer_mode" override="true" enum="NetworkedMultiplayerPeer.TransferMode" default="2" />
+ <member name="transfer_mode" type="int" setter="set_transfer_mode" getter="get_transfer_mode" override="true" enum="MultiplayerPeer.TransferMode" default="2" />
</members>
<constants>
</constants>
diff --git a/modules/webrtc/register_types.cpp b/modules/webrtc/register_types.cpp
index ecfaed9089..63ecc03a4c 100644
--- a/modules/webrtc/register_types.cpp
+++ b/modules/webrtc/register_types.cpp
@@ -41,7 +41,7 @@
#include "webrtc_data_channel_gdnative.h"
#include "webrtc_peer_connection_gdnative.h"
#endif
-#include "webrtc_multiplayer.h"
+#include "webrtc_multiplayer_peer.h"
void register_webrtc_types() {
#define _SET_HINT(NAME, _VAL_, _MAX_) \
@@ -58,11 +58,11 @@ void register_webrtc_types() {
ClassDB::register_custom_instance_class<WebRTCPeerConnection>();
#ifdef WEBRTC_GDNATIVE_ENABLED
- ClassDB::register_class<WebRTCPeerConnectionGDNative>();
- ClassDB::register_class<WebRTCDataChannelGDNative>();
+ GDREGISTER_CLASS(WebRTCPeerConnectionGDNative);
+ GDREGISTER_CLASS(WebRTCDataChannelGDNative);
#endif
- ClassDB::register_virtual_class<WebRTCDataChannel>();
- ClassDB::register_class<WebRTCMultiplayer>();
+ GDREGISTER_VIRTUAL_CLASS(WebRTCDataChannel);
+ GDREGISTER_CLASS(WebRTCMultiplayerPeer);
}
void unregister_webrtc_types() {}
diff --git a/modules/webrtc/webrtc_multiplayer.cpp b/modules/webrtc/webrtc_multiplayer_peer.cpp
index 741cad5640..ac75f9e860 100644
--- a/modules/webrtc/webrtc_multiplayer.cpp
+++ b/modules/webrtc/webrtc_multiplayer_peer.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* webrtc_multiplayer.cpp */
+/* webrtc_multiplayer_peer.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,43 +28,43 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "webrtc_multiplayer.h"
+#include "webrtc_multiplayer_peer.h"
#include "core/io/marshalls.h"
#include "core/os/os.h"
-void WebRTCMultiplayer::_bind_methods() {
- ClassDB::bind_method(D_METHOD("initialize", "peer_id", "server_compatibility"), &WebRTCMultiplayer::initialize, DEFVAL(false));
- ClassDB::bind_method(D_METHOD("add_peer", "peer", "peer_id", "unreliable_lifetime"), &WebRTCMultiplayer::add_peer, DEFVAL(1));
- ClassDB::bind_method(D_METHOD("remove_peer", "peer_id"), &WebRTCMultiplayer::remove_peer);
- ClassDB::bind_method(D_METHOD("has_peer", "peer_id"), &WebRTCMultiplayer::has_peer);
- ClassDB::bind_method(D_METHOD("get_peer", "peer_id"), &WebRTCMultiplayer::get_peer);
- ClassDB::bind_method(D_METHOD("get_peers"), &WebRTCMultiplayer::get_peers);
- ClassDB::bind_method(D_METHOD("close"), &WebRTCMultiplayer::close);
+void WebRTCMultiplayerPeer::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("initialize", "peer_id", "server_compatibility"), &WebRTCMultiplayerPeer::initialize, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("add_peer", "peer", "peer_id", "unreliable_lifetime"), &WebRTCMultiplayerPeer::add_peer, DEFVAL(1));
+ ClassDB::bind_method(D_METHOD("remove_peer", "peer_id"), &WebRTCMultiplayerPeer::remove_peer);
+ ClassDB::bind_method(D_METHOD("has_peer", "peer_id"), &WebRTCMultiplayerPeer::has_peer);
+ ClassDB::bind_method(D_METHOD("get_peer", "peer_id"), &WebRTCMultiplayerPeer::get_peer);
+ ClassDB::bind_method(D_METHOD("get_peers"), &WebRTCMultiplayerPeer::get_peers);
+ ClassDB::bind_method(D_METHOD("close"), &WebRTCMultiplayerPeer::close);
}
-void WebRTCMultiplayer::set_transfer_mode(TransferMode p_mode) {
+void WebRTCMultiplayerPeer::set_transfer_mode(TransferMode p_mode) {
transfer_mode = p_mode;
}
-NetworkedMultiplayerPeer::TransferMode WebRTCMultiplayer::get_transfer_mode() const {
+MultiplayerPeer::TransferMode WebRTCMultiplayerPeer::get_transfer_mode() const {
return transfer_mode;
}
-void WebRTCMultiplayer::set_target_peer(int p_peer_id) {
+void WebRTCMultiplayerPeer::set_target_peer(int p_peer_id) {
target_peer = p_peer_id;
}
-/* Returns the ID of the NetworkedMultiplayerPeer who sent the most recent packet: */
-int WebRTCMultiplayer::get_packet_peer() const {
+/* Returns the ID of the MultiplayerPeer who sent the most recent packet: */
+int WebRTCMultiplayerPeer::get_packet_peer() const {
return next_packet_peer;
}
-bool WebRTCMultiplayer::is_server() const {
+bool WebRTCMultiplayerPeer::is_server() const {
return unique_id == TARGET_PEER_SERVER;
}
-void WebRTCMultiplayer::poll() {
+void WebRTCMultiplayerPeer::poll() {
if (peer_map.size() == 0) {
return;
}
@@ -147,7 +147,7 @@ void WebRTCMultiplayer::poll() {
}
}
-void WebRTCMultiplayer::_find_next_peer() {
+void WebRTCMultiplayerPeer::_find_next_peer() {
Map<int, Ref<ConnectedPeer>>::Element *E = peer_map.find(next_packet_peer);
if (E) {
E = E->next();
@@ -180,19 +180,19 @@ void WebRTCMultiplayer::_find_next_peer() {
next_packet_peer = 0;
}
-void WebRTCMultiplayer::set_refuse_new_connections(bool p_enable) {
+void WebRTCMultiplayerPeer::set_refuse_new_connections(bool p_enable) {
refuse_connections = p_enable;
}
-bool WebRTCMultiplayer::is_refusing_new_connections() const {
+bool WebRTCMultiplayerPeer::is_refusing_new_connections() const {
return refuse_connections;
}
-NetworkedMultiplayerPeer::ConnectionStatus WebRTCMultiplayer::get_connection_status() const {
+MultiplayerPeer::ConnectionStatus WebRTCMultiplayerPeer::get_connection_status() const {
return connection_status;
}
-Error WebRTCMultiplayer::initialize(int p_self_id, bool p_server_compat) {
+Error WebRTCMultiplayerPeer::initialize(int p_self_id, bool p_server_compat) {
ERR_FAIL_COND_V(p_self_id < 0 || p_self_id > ~(1 << 31), ERR_INVALID_PARAMETER);
unique_id = p_self_id;
server_compat = p_server_compat;
@@ -206,12 +206,12 @@ Error WebRTCMultiplayer::initialize(int p_self_id, bool p_server_compat) {
return OK;
}
-int WebRTCMultiplayer::get_unique_id() const {
+int WebRTCMultiplayerPeer::get_unique_id() const {
ERR_FAIL_COND_V(connection_status == CONNECTION_DISCONNECTED, 1);
return unique_id;
}
-void WebRTCMultiplayer::_peer_to_dict(Ref<ConnectedPeer> p_connected_peer, Dictionary &r_dict) {
+void WebRTCMultiplayerPeer::_peer_to_dict(Ref<ConnectedPeer> p_connected_peer, Dictionary &r_dict) {
Array channels;
for (List<Ref<WebRTCDataChannel>>::Element *F = p_connected_peer->channels.front(); F; F = F->next()) {
channels.push_back(F->get());
@@ -221,18 +221,18 @@ void WebRTCMultiplayer::_peer_to_dict(Ref<ConnectedPeer> p_connected_peer, Dicti
r_dict["channels"] = channels;
}
-bool WebRTCMultiplayer::has_peer(int p_peer_id) {
+bool WebRTCMultiplayerPeer::has_peer(int p_peer_id) {
return peer_map.has(p_peer_id);
}
-Dictionary WebRTCMultiplayer::get_peer(int p_peer_id) {
+Dictionary WebRTCMultiplayerPeer::get_peer(int p_peer_id) {
ERR_FAIL_COND_V(!peer_map.has(p_peer_id), Dictionary());
Dictionary out;
_peer_to_dict(peer_map[p_peer_id], out);
return out;
}
-Dictionary WebRTCMultiplayer::get_peers() {
+Dictionary WebRTCMultiplayerPeer::get_peers() {
Dictionary out;
for (Map<int, Ref<ConnectedPeer>>::Element *E = peer_map.front(); E; E = E->next()) {
Dictionary d;
@@ -242,7 +242,7 @@ Dictionary WebRTCMultiplayer::get_peers() {
return out;
}
-Error WebRTCMultiplayer::add_peer(Ref<WebRTCPeerConnection> p_peer, int p_peer_id, int p_unreliable_lifetime) {
+Error WebRTCMultiplayerPeer::add_peer(Ref<WebRTCPeerConnection> p_peer, int p_peer_id, int p_unreliable_lifetime) {
ERR_FAIL_COND_V(p_peer_id < 0 || p_peer_id > ~(1 << 31), ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(p_unreliable_lifetime < 0, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(refuse_connections, ERR_UNAUTHORIZED);
@@ -277,7 +277,7 @@ Error WebRTCMultiplayer::add_peer(Ref<WebRTCPeerConnection> p_peer, int p_peer_i
return OK;
}
-void WebRTCMultiplayer::remove_peer(int p_peer_id) {
+void WebRTCMultiplayerPeer::remove_peer(int p_peer_id) {
ERR_FAIL_COND(!peer_map.has(p_peer_id));
Ref<ConnectedPeer> peer = peer_map[p_peer_id];
peer_map.erase(p_peer_id);
@@ -291,7 +291,7 @@ void WebRTCMultiplayer::remove_peer(int p_peer_id) {
}
}
-Error WebRTCMultiplayer::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
+Error WebRTCMultiplayerPeer::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
// Peer not available
if (next_packet_peer == 0 || !peer_map.has(next_packet_peer)) {
_find_next_peer();
@@ -309,7 +309,7 @@ Error WebRTCMultiplayer::get_packet(const uint8_t **r_buffer, int &r_buffer_size
ERR_FAIL_V(ERR_BUG);
}
-Error WebRTCMultiplayer::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
+Error WebRTCMultiplayerPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
ERR_FAIL_COND_V(connection_status == CONNECTION_DISCONNECTED, ERR_UNCONFIGURED);
int ch = CH_RELIABLE;
@@ -351,7 +351,7 @@ Error WebRTCMultiplayer::put_packet(const uint8_t *p_buffer, int p_buffer_size)
return OK;
}
-int WebRTCMultiplayer::get_available_packet_count() const {
+int WebRTCMultiplayerPeer::get_available_packet_count() const {
if (next_packet_peer == 0) {
return 0; // To be sure next call to get_packet works if size > 0 .
}
@@ -364,11 +364,11 @@ int WebRTCMultiplayer::get_available_packet_count() const {
return size;
}
-int WebRTCMultiplayer::get_max_packet_size() const {
+int WebRTCMultiplayerPeer::get_max_packet_size() const {
return 1200;
}
-void WebRTCMultiplayer::close() {
+void WebRTCMultiplayerPeer::close() {
peer_map.clear();
unique_id = 0;
next_packet_peer = 0;
@@ -376,7 +376,7 @@ void WebRTCMultiplayer::close() {
connection_status = CONNECTION_DISCONNECTED;
}
-WebRTCMultiplayer::WebRTCMultiplayer() {
+WebRTCMultiplayerPeer::WebRTCMultiplayerPeer() {
unique_id = 0;
next_packet_peer = 0;
target_peer = 0;
@@ -387,6 +387,6 @@ WebRTCMultiplayer::WebRTCMultiplayer() {
server_compat = false;
}
-WebRTCMultiplayer::~WebRTCMultiplayer() {
+WebRTCMultiplayerPeer::~WebRTCMultiplayerPeer() {
close();
}
diff --git a/modules/webrtc/webrtc_multiplayer.h b/modules/webrtc/webrtc_multiplayer_peer.h
index 2ddb98f656..1d9387b6dc 100644
--- a/modules/webrtc/webrtc_multiplayer.h
+++ b/modules/webrtc/webrtc_multiplayer_peer.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* webrtc_multiplayer.h */
+/* webrtc_multiplayer_peer.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -31,11 +31,11 @@
#ifndef WEBRTC_MULTIPLAYER_H
#define WEBRTC_MULTIPLAYER_H
-#include "core/io/networked_multiplayer_peer.h"
+#include "core/io/multiplayer_peer.h"
#include "webrtc_peer_connection.h"
-class WebRTCMultiplayer : public NetworkedMultiplayerPeer {
- GDCLASS(WebRTCMultiplayer, NetworkedMultiplayerPeer);
+class WebRTCMultiplayerPeer : public MultiplayerPeer {
+ GDCLASS(WebRTCMultiplayerPeer, MultiplayerPeer);
protected:
static void _bind_methods();
@@ -77,8 +77,8 @@ private:
void _find_next_peer();
public:
- WebRTCMultiplayer();
- ~WebRTCMultiplayer();
+ WebRTCMultiplayerPeer();
+ ~WebRTCMultiplayerPeer();
Error initialize(int p_self_id, bool p_server_compat = false);
Error add_peer(Ref<WebRTCPeerConnection> p_peer, int p_peer_id, int p_unreliable_lifetime = 1);
@@ -94,7 +94,7 @@ public:
int get_available_packet_count() const override;
int get_max_packet_size() const override;
- // NetworkedMultiplayerPeer
+ // MultiplayerPeer
void set_transfer_mode(TransferMode p_mode) override;
TransferMode get_transfer_mode() const override;
void set_target_peer(int p_peer_id) override;
diff --git a/modules/websocket/doc_classes/WebSocketClient.xml b/modules/websocket/doc_classes/WebSocketClient.xml
index 6af610c689..40c0ad17ad 100644
--- a/modules/websocket/doc_classes/WebSocketClient.xml
+++ b/modules/websocket/doc_classes/WebSocketClient.xml
@@ -6,7 +6,7 @@
<description>
This class implements a WebSocket client compatible with any RFC 6455-compliant WebSocket server.
This client can be optionally used as a network peer for the [MultiplayerAPI].
- After starting the client ([method connect_to_url]), you will need to [method NetworkedMultiplayerPeer.poll] it at regular intervals (e.g. inside [method Node._process]).
+ After starting the client ([method connect_to_url]), you will need to [method MultiplayerPeer.poll] it at regular intervals (e.g. inside [method Node._process]).
You will receive appropriate signals when connecting, disconnecting, or when new data is available.
</description>
<tutorials>
diff --git a/modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml b/modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml
index 0679acf78a..ee1b60f739 100644
--- a/modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml
+++ b/modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="WebSocketMultiplayerPeer" inherits="NetworkedMultiplayerPeer" version="4.0">
+<class name="WebSocketMultiplayerPeer" inherits="MultiplayerPeer" version="4.0">
<brief_description>
Base class for WebSocket server and client.
</brief_description>
@@ -39,7 +39,7 @@
</methods>
<members>
<member name="refuse_new_connections" type="bool" setter="set_refuse_new_connections" getter="is_refusing_new_connections" override="true" default="false" />
- <member name="transfer_mode" type="int" setter="set_transfer_mode" getter="get_transfer_mode" override="true" enum="NetworkedMultiplayerPeer.TransferMode" default="2" />
+ <member name="transfer_mode" type="int" setter="set_transfer_mode" getter="get_transfer_mode" override="true" enum="MultiplayerPeer.TransferMode" default="2" />
</members>
<signals>
<signal name="peer_packet">
diff --git a/modules/websocket/doc_classes/WebSocketServer.xml b/modules/websocket/doc_classes/WebSocketServer.xml
index 7bc0d64718..26e09fd8b3 100644
--- a/modules/websocket/doc_classes/WebSocketServer.xml
+++ b/modules/websocket/doc_classes/WebSocketServer.xml
@@ -5,7 +5,7 @@
</brief_description>
<description>
This class implements a WebSocket server that can also support the high-level multiplayer API.
- After starting the server ([method listen]), you will need to [method NetworkedMultiplayerPeer.poll] it at regular intervals (e.g. inside [method Node._process]). When clients connect, disconnect, or send data, you will receive the appropriate signal.
+ After starting the server ([method listen]), you will need to [method MultiplayerPeer.poll] it at regular intervals (e.g. inside [method Node._process]). When clients connect, disconnect, or send data, you will receive the appropriate signal.
[b]Note:[/b] Not available in HTML5 exports.
</description>
<tutorials>
diff --git a/modules/websocket/emws_client.cpp b/modules/websocket/emws_client.cpp
index 626498e1ae..744053b6e2 100644
--- a/modules/websocket/emws_client.cpp
+++ b/modules/websocket/emws_client.cpp
@@ -107,7 +107,7 @@ Ref<WebSocketPeer> EMWSClient::get_peer(int p_peer_id) const {
return _peer;
}
-NetworkedMultiplayerPeer::ConnectionStatus EMWSClient::get_connection_status() const {
+MultiplayerPeer::ConnectionStatus EMWSClient::get_connection_status() const {
if (_peer->is_connected_to_host()) {
if (_is_connecting)
return CONNECTION_CONNECTING;
diff --git a/modules/websocket/register_types.cpp b/modules/websocket/register_types.cpp
index 5a02509c4a..7c742b1b89 100644
--- a/modules/websocket/register_types.cpp
+++ b/modules/websocket/register_types.cpp
@@ -63,7 +63,7 @@ void register_websocket_types() {
WSLServer::make_default();
#endif
- ClassDB::register_virtual_class<WebSocketMultiplayerPeer>();
+ GDREGISTER_VIRTUAL_CLASS(WebSocketMultiplayerPeer);
ClassDB::register_custom_instance_class<WebSocketServer>();
ClassDB::register_custom_instance_class<WebSocketClient>();
ClassDB::register_custom_instance_class<WebSocketPeer>();
diff --git a/modules/websocket/websocket_multiplayer_peer.cpp b/modules/websocket/websocket_multiplayer_peer.cpp
index fa0ef7060f..1beeb67b91 100644
--- a/modules/websocket/websocket_multiplayer_peer.cpp
+++ b/modules/websocket/websocket_multiplayer_peer.cpp
@@ -123,13 +123,13 @@ Error WebSocketMultiplayerPeer::put_packet(const uint8_t *p_buffer, int p_buffer
}
//
-// NetworkedMultiplayerPeer
+// MultiplayerPeer
//
void WebSocketMultiplayerPeer::set_transfer_mode(TransferMode p_mode) {
// Websocket uses TCP, reliable
}
-NetworkedMultiplayerPeer::TransferMode WebSocketMultiplayerPeer::get_transfer_mode() const {
+MultiplayerPeer::TransferMode WebSocketMultiplayerPeer::get_transfer_mode() const {
// Websocket uses TCP, reliable
return TRANSFER_MODE_RELIABLE;
}
diff --git a/modules/websocket/websocket_multiplayer_peer.h b/modules/websocket/websocket_multiplayer_peer.h
index 48a6607d89..e3ccd1a795 100644
--- a/modules/websocket/websocket_multiplayer_peer.h
+++ b/modules/websocket/websocket_multiplayer_peer.h
@@ -32,12 +32,12 @@
#define WEBSOCKET_MULTIPLAYER_PEER_H
#include "core/error/error_list.h"
-#include "core/io/networked_multiplayer_peer.h"
+#include "core/io/multiplayer_peer.h"
#include "core/templates/list.h"
#include "websocket_peer.h"
-class WebSocketMultiplayerPeer : public NetworkedMultiplayerPeer {
- GDCLASS(WebSocketMultiplayerPeer, NetworkedMultiplayerPeer);
+class WebSocketMultiplayerPeer : public MultiplayerPeer {
+ GDCLASS(WebSocketMultiplayerPeer, MultiplayerPeer);
private:
Vector<uint8_t> _make_pkt(uint8_t p_type, int32_t p_from, int32_t p_to, const uint8_t *p_data, uint32_t p_data_size);
@@ -78,7 +78,7 @@ protected:
int _gen_unique_id() const;
public:
- /* NetworkedMultiplayerPeer */
+ /* MultiplayerPeer */
void set_transfer_mode(TransferMode p_mode) override;
TransferMode get_transfer_mode() const override;
void set_target_peer(int p_target_peer) override;
diff --git a/modules/websocket/websocket_server.cpp b/modules/websocket/websocket_server.cpp
index 9b2d04f14f..b996852f28 100644
--- a/modules/websocket/websocket_server.cpp
+++ b/modules/websocket/websocket_server.cpp
@@ -121,7 +121,7 @@ void WebSocketServer::set_handshake_timeout(float p_timeout) {
handshake_timeout = p_timeout * 1000;
}
-NetworkedMultiplayerPeer::ConnectionStatus WebSocketServer::get_connection_status() const {
+MultiplayerPeer::ConnectionStatus WebSocketServer::get_connection_status() const {
if (is_listening()) {
return CONNECTION_CONNECTED;
}
diff --git a/modules/websocket/wsl_client.cpp b/modules/websocket/wsl_client.cpp
index 74017fedd7..49997b42d3 100644
--- a/modules/websocket/wsl_client.cpp
+++ b/modules/websocket/wsl_client.cpp
@@ -288,7 +288,7 @@ Ref<WebSocketPeer> WSLClient::get_peer(int p_peer_id) const {
return _peer;
}
-NetworkedMultiplayerPeer::ConnectionStatus WSLClient::get_connection_status() const {
+MultiplayerPeer::ConnectionStatus WSLClient::get_connection_status() const {
if (_peer->is_connected_to_host()) {
return CONNECTION_CONNECTED;
}
diff --git a/modules/webxr/register_types.cpp b/modules/webxr/register_types.cpp
index 6df0234811..078a6547cf 100644
--- a/modules/webxr/register_types.cpp
+++ b/modules/webxr/register_types.cpp
@@ -34,7 +34,7 @@
#include "webxr_interface_js.h"
void register_webxr_types() {
- ClassDB::register_virtual_class<WebXRInterface>();
+ GDREGISTER_VIRTUAL_CLASS(WebXRInterface);
#ifdef JAVASCRIPT_ENABLED
Ref<WebXRInterfaceJS> webxr;
diff --git a/platform/android/api/api.cpp b/platform/android/api/api.cpp
index d3c49c6eb7..03355e4815 100644
--- a/platform/android/api/api.cpp
+++ b/platform/android/api/api.cpp
@@ -44,11 +44,11 @@ void register_android_api() {
// `JNISingleton` registration occurs in
// `platform/android/java_godot_lib_jni.cpp#Java_org_godotengine_godot_GodotLib_setup`
java_class_wrapper = memnew(JavaClassWrapper); // Dummy
- ClassDB::register_class<JNISingleton>();
+ GDREGISTER_CLASS(JNISingleton);
#endif
- ClassDB::register_class<JavaClass>();
- ClassDB::register_class<JavaClassWrapper>();
+ GDREGISTER_CLASS(JavaClass);
+ GDREGISTER_CLASS(JavaClassWrapper);
Engine::get_singleton()->add_singleton(Engine::Singleton("JavaClassWrapper", JavaClassWrapper::get_singleton()));
}
diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp
index 66a2013c4e..1fcc3d4a5c 100644
--- a/platform/android/display_server_android.cpp
+++ b/platform/android/display_server_android.cpp
@@ -358,8 +358,8 @@ Vector<String> DisplayServerAndroid::get_rendering_drivers_func() {
return drivers;
}
-DisplayServer *DisplayServerAndroid::create_func(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
- DisplayServer *ds = memnew(DisplayServerAndroid(p_rendering_driver, p_mode, p_flags, p_resolution, r_error));
+DisplayServer *DisplayServerAndroid::create_func(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+ DisplayServer *ds = memnew(DisplayServerAndroid(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
if (r_error != OK) {
ds->alert("Your video card driver does not support any of the supported Vulkan versions.", "Unable to initialize Video driver");
}
@@ -377,10 +377,11 @@ void DisplayServerAndroid::reset_window() {
ERR_FAIL_COND(!native_window);
ERR_FAIL_COND(!context_vulkan);
+ VSyncMode last_vsync_mode = context_vulkan->get_vsync_mode(MAIN_WINDOW_ID);
context_vulkan->window_destroy(MAIN_WINDOW_ID);
Size2i display_size = OS_Android::get_singleton()->get_display_size();
- if (context_vulkan->window_create(native_window, display_size.width, display_size.height) == -1) {
+ if (context_vulkan->window_create(native_window, last_vsync_mode, display_size.width, display_size.height) == -1) {
memdelete(context_vulkan);
context_vulkan = nullptr;
ERR_FAIL_MSG("Failed to reset Vulkan window.");
@@ -402,7 +403,7 @@ void DisplayServerAndroid::notify_surface_changed(int p_width, int p_height) {
rect_changed_callback.call(reinterpret_cast<const Variant **>(&sizep), 1, ret, ce);
}
-DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
rendering_driver = p_rendering_driver;
// TODO: rendering_driver is broken, change when different drivers are supported again
@@ -446,7 +447,7 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis
}
Size2i display_size = OS_Android::get_singleton()->get_display_size();
- if (context_vulkan->window_create(native_window, display_size.width, display_size.height) == -1) {
+ if (context_vulkan->window_create(native_window, p_vsync_mode, display_size.width, display_size.height) == -1) {
memdelete(context_vulkan);
context_vulkan = nullptr;
ERR_FAIL_MSG("Failed to create Vulkan window.");
@@ -901,3 +902,17 @@ void DisplayServerAndroid::cursor_set_shape(DisplayServer::CursorShape p_shape)
DisplayServer::CursorShape DisplayServerAndroid::cursor_get_shape() const {
return cursor_shape;
}
+
+void DisplayServerAndroid::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
+#if defined(VULKAN_ENABLED)
+ context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
+#endif
+}
+
+DisplayServer::VSyncMode DisplayServerAndroid::window_get_vsync_mode(WindowID p_window) const {
+#if defined(VULKAN_ENABLED)
+ return context_vulkan->get_vsync_mode(p_window);
+#else
+ return DisplayServer::VSYNC_ENABLED;
+#endif
+}
diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h
index 8c626d28d5..bd5bed31cd 100644
--- a/platform/android/display_server_android.h
+++ b/platform/android/display_server_android.h
@@ -188,6 +188,8 @@ public:
virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID);
virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const;
virtual bool can_any_window_draw() const;
+ virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID);
+ virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const;
virtual void alert(const String &p_alert, const String &p_title);
@@ -211,7 +213,7 @@ public:
void mouse_set_mode(MouseMode p_mode);
MouseMode mouse_get_mode() const;
- static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
static Vector<String> get_rendering_drivers_func();
static void register_android_driver();
@@ -221,7 +223,7 @@ public:
virtual Point2i mouse_get_position() const;
virtual MouseButton mouse_get_button_state() const;
- DisplayServerAndroid(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ DisplayServerAndroid(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
~DisplayServerAndroid();
};
diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp
index 4c66789a83..2eded01bf4 100644
--- a/platform/android/java_godot_lib_jni.cpp
+++ b/platform/android/java_godot_lib_jni.cpp
@@ -157,7 +157,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jc
}
java_class_wrapper = memnew(JavaClassWrapper(godot_java->get_activity()));
- ClassDB::register_class<JNISingleton>();
+ GDREGISTER_CLASS(JNISingleton);
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jclass clazz, jobject p_surface, jint p_width, jint p_height) {
diff --git a/platform/android/vulkan/vulkan_context_android.cpp b/platform/android/vulkan/vulkan_context_android.cpp
index 63f2026fae..a031f3beee 100644
--- a/platform/android/vulkan/vulkan_context_android.cpp
+++ b/platform/android/vulkan/vulkan_context_android.cpp
@@ -36,7 +36,7 @@ const char *VulkanContextAndroid::_get_platform_surface_extension() const {
return VK_KHR_ANDROID_SURFACE_EXTENSION_NAME;
}
-int VulkanContextAndroid::window_create(ANativeWindow *p_window, int p_width, int p_height) {
+int VulkanContextAndroid::window_create(ANativeWindow *p_window, DisplayServer::VSyncMode p_vsync_mode, int p_width, int p_height) {
VkAndroidSurfaceCreateInfoKHR createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = nullptr;
@@ -49,7 +49,7 @@ int VulkanContextAndroid::window_create(ANativeWindow *p_window, int p_width, in
ERR_FAIL_V_MSG(-1, "vkCreateAndroidSurfaceKHR failed with error " + itos(err));
}
- return _window_create(DisplayServer::MAIN_WINDOW_ID, surface, p_width, p_height);
+ return _window_create(DisplayServer::MAIN_WINDOW_ID, p_vsync_mode, surface, p_width, p_height);
}
bool VulkanContextAndroid::_use_validation_layers() {
diff --git a/platform/android/vulkan/vulkan_context_android.h b/platform/android/vulkan/vulkan_context_android.h
index 5a84eaf8f3..182ce33c97 100644
--- a/platform/android/vulkan/vulkan_context_android.h
+++ b/platform/android/vulkan/vulkan_context_android.h
@@ -39,7 +39,7 @@ class VulkanContextAndroid : public VulkanContext {
virtual const char *_get_platform_surface_extension() const override;
public:
- int window_create(ANativeWindow *p_window, int p_width, int p_height);
+ int window_create(ANativeWindow *p_window, DisplayServer::VSyncMode p_vsync_mode, int p_width, int p_height);
VulkanContextAndroid() = default;
~VulkanContextAndroid() override = default;
diff --git a/platform/iphone/display_server_iphone.h b/platform/iphone/display_server_iphone.h
index 34c56382a4..6f64130b23 100644
--- a/platform/iphone/display_server_iphone.h
+++ b/platform/iphone/display_server_iphone.h
@@ -67,7 +67,7 @@ class DisplayServerIPhone : public DisplayServer {
void perform_event(const Ref<InputEvent> &p_event);
- DisplayServerIPhone(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ DisplayServerIPhone(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
~DisplayServerIPhone();
public:
@@ -76,7 +76,7 @@ public:
static DisplayServerIPhone *get_singleton();
static void register_iphone_driver();
- static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
static Vector<String> get_rendering_drivers_func();
// MARK: - Events
@@ -176,6 +176,9 @@ public:
virtual bool can_any_window_draw() const override;
+ virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override;
+
virtual bool screen_is_touchscreen(int p_screen) const override;
virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_length, int p_cursor_start, int p_cursor_end) override;
diff --git a/platform/iphone/display_server_iphone.mm b/platform/iphone/display_server_iphone.mm
index 74d7419715..bd95e2c703 100644
--- a/platform/iphone/display_server_iphone.mm
+++ b/platform/iphone/display_server_iphone.mm
@@ -48,7 +48,7 @@ DisplayServerIPhone *DisplayServerIPhone::get_singleton() {
return (DisplayServerIPhone *)DisplayServer::get_singleton();
}
-DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
rendering_driver = p_rendering_driver;
#if defined(OPENGL_ENABLED)
@@ -108,7 +108,7 @@ DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, Displ
}
Size2i size = Size2i(layer.bounds.size.width, layer.bounds.size.height) * screen_get_max_scale();
- if (context_vulkan->window_create(MAIN_WINDOW_ID, layer, size.width, size.height) != OK) {
+ if (context_vulkan->window_create(MAIN_WINDOW_ID, p_vsync_mode, layer, size.width, size.height) != OK) {
memdelete(context_vulkan);
context_vulkan = nullptr;
ERR_FAIL_MSG("Failed to create Vulkan window.");
@@ -147,8 +147,8 @@ DisplayServerIPhone::~DisplayServerIPhone() {
#endif
}
-DisplayServer *DisplayServerIPhone::create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
- return memnew(DisplayServerIPhone(p_rendering_driver, p_mode, p_flags, p_resolution, r_error));
+DisplayServer *DisplayServerIPhone::create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+ return memnew(DisplayServerIPhone(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
}
Vector<String> DisplayServerIPhone::get_rendering_drivers_func() {
@@ -581,3 +581,19 @@ void DisplayServerIPhone::resize_window(CGSize viewSize) {
Variant resize_rect = Rect2i(Point2i(), size);
_window_callback(window_resize_callback, resize_rect);
}
+
+void DisplayServerIPhone::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
+ _THREAD_SAFE_METHOD_
+#if defined(VULKAN_ENABLED)
+ context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
+#endif
+}
+
+DisplayServer::VSyncMode DisplayServerIPhone::window_get_vsync_mode(WindowID p_window) const {
+ _THREAD_SAFE_METHOD_
+#if defined(VULKAN_ENABLED)
+ return context_vulkan->get_vsync_mode(p_window);
+#else
+ return DisplayServer::VSYNC_ENABLED;
+#endif
+}
diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp
index 1d1961ac2f..523dc555f1 100644
--- a/platform/iphone/export/export.cpp
+++ b/platform/iphone/export/export.cpp
@@ -413,7 +413,7 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "optional_icons/spotlight_80x80", PROPERTY_HINT_FILE, "*.png"), "")); // Spotlight on devices with retina display
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "storyboard/use_launch_screen_storyboard"), false));
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "storyboard/image_scale_mode", PROPERTY_HINT_ENUM, "Same as Logo,Center,Scale To Fit,Scale To Fill,Scale"), 0));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "storyboard/image_scale_mode", PROPERTY_HINT_ENUM, "Same as Logo,Center,Scale to Fit,Scale to Fill,Scale"), 0));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "storyboard/custom_image@2x", PROPERTY_HINT_FILE, "*.png"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "storyboard/custom_image@3x", PROPERTY_HINT_FILE, "*.png"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "storyboard/use_custom_bg_color"), false));
diff --git a/platform/iphone/vulkan_context_iphone.h b/platform/iphone/vulkan_context_iphone.h
index 88764e270e..ec6aaf46e8 100644
--- a/platform/iphone/vulkan_context_iphone.h
+++ b/platform/iphone/vulkan_context_iphone.h
@@ -39,7 +39,7 @@ class VulkanContextIPhone : public VulkanContext {
virtual const char *_get_platform_surface_extension() const;
public:
- Error window_create(DisplayServer::WindowID p_window_id, CALayer *p_metal_layer, int p_width, int p_height);
+ Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, CALayer *p_metal_layer, int p_width, int p_height);
VulkanContextIPhone();
~VulkanContextIPhone();
diff --git a/platform/iphone/vulkan_context_iphone.mm b/platform/iphone/vulkan_context_iphone.mm
index 08c9007fbb..17f2b167b3 100644
--- a/platform/iphone/vulkan_context_iphone.mm
+++ b/platform/iphone/vulkan_context_iphone.mm
@@ -35,7 +35,7 @@ const char *VulkanContextIPhone::_get_platform_surface_extension() const {
return VK_MVK_IOS_SURFACE_EXTENSION_NAME;
}
-Error VulkanContextIPhone::window_create(DisplayServer::WindowID p_window_id, CALayer *p_metal_layer, int p_width, int p_height) {
+Error VulkanContextIPhone::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, CALayer *p_metal_layer, int p_width, int p_height) {
VkIOSSurfaceCreateInfoMVK createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK;
createInfo.pNext = nullptr;
@@ -47,7 +47,7 @@ Error VulkanContextIPhone::window_create(DisplayServer::WindowID p_window_id, CA
vkCreateIOSSurfaceMVK(_get_instance(), &createInfo, nullptr, &surface);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
- return _window_create(p_window_id, surface, p_width, p_height);
+ return _window_create(p_window_id, p_vsync_mode, surface, p_width, p_height);
}
VulkanContextIPhone::VulkanContextIPhone() {}
diff --git a/platform/javascript/api/api.cpp b/platform/javascript/api/api.cpp
index 5ad2bf56cf..e7c018ba9f 100644
--- a/platform/javascript/api/api.cpp
+++ b/platform/javascript/api/api.cpp
@@ -37,8 +37,8 @@ static JavaScript *javascript_eval;
void register_javascript_api() {
JavaScriptToolsEditorPlugin::initialize();
- ClassDB::register_virtual_class<JavaScriptObject>();
- ClassDB::register_virtual_class<JavaScript>();
+ GDREGISTER_VIRTUAL_CLASS(JavaScriptObject);
+ GDREGISTER_VIRTUAL_CLASS(JavaScript);
javascript_eval = memnew(JavaScript);
Engine::get_singleton()->add_singleton(Engine::Singleton("JavaScript", javascript_eval));
}
diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py
index da6adc4cd8..dacc442575 100644
--- a/platform/javascript/detect.py
+++ b/platform/javascript/detect.py
@@ -29,7 +29,7 @@ def get_opts():
from SCons.Variables import BoolVariable
return [
- ("initial_memory", "Initial WASM memory (in MiB)", 16),
+ ("initial_memory", "Initial WASM memory (in MiB)", 32),
BoolVariable("use_assertions", "Use Emscripten runtime assertions", False),
BoolVariable("use_thinlto", "Use ThinLTO", False),
BoolVariable("use_ubsan", "Use Emscripten undefined behavior sanitizer (UBSAN)", False),
@@ -130,7 +130,6 @@ def configure(env):
env.Append(CCFLAGS=["-fsanitize=leak"])
env.Append(LINKFLAGS=["-fsanitize=leak"])
if env["use_safe_heap"]:
- env.Append(CCFLAGS=["-s", "SAFE_HEAP=1"])
env.Append(LINKFLAGS=["-s", "SAFE_HEAP=1"])
# Closure compiler
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index fd652c0af2..8f0742041c 100644
--- a/platform/linuxbsd/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -855,10 +855,10 @@ Vector<DisplayServer::WindowID> DisplayServerX11::get_window_list() const {
return ret;
}
-DisplayServer::WindowID DisplayServerX11::create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect) {
+DisplayServer::WindowID DisplayServerX11::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
_THREAD_SAFE_METHOD_
- WindowID id = _create_window(p_mode, p_flags, p_rect);
+ WindowID id = _create_window(p_mode, p_vsync_mode, p_flags, p_rect);
for (int i = 0; i < WINDOW_FLAG_MAX; i++) {
if (p_flags & (1 << i)) {
window_set_flag(WindowFlags(i), true, id);
@@ -3641,6 +3641,22 @@ void DisplayServerX11::set_icon(const Ref<Image> &p_icon) {
XSetErrorHandler(oldHandler);
}
+void DisplayServerX11::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
+ _THREAD_SAFE_METHOD_
+#if defined(VULKAN_ENABLED)
+ context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
+#endif
+}
+
+DisplayServer::VSyncMode DisplayServerX11::window_get_vsync_mode(WindowID p_window) const {
+ _THREAD_SAFE_METHOD_
+#if defined(VULKAN_ENABLED)
+ return context_vulkan->get_vsync_mode(p_window);
+#else
+ return DisplayServer::VSYNC_ENABLED;
+#endif
+}
+
Vector<String> DisplayServerX11::get_rendering_drivers_func() {
Vector<String> drivers;
@@ -3654,8 +3670,8 @@ Vector<String> DisplayServerX11::get_rendering_drivers_func() {
return drivers;
}
-DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
- DisplayServer *ds = memnew(DisplayServerX11(p_rendering_driver, p_mode, p_flags, p_resolution, r_error));
+DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+ DisplayServer *ds = memnew(DisplayServerX11(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
if (r_error != OK) {
ds->alert("Your video card driver does not support any of the supported Vulkan versions.\n"
"Please update your drivers or if you have a very old or integrated GPU upgrade it.",
@@ -3664,7 +3680,7 @@ DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, W
return ds;
}
-DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect) {
+DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
//Create window
long visualMask = VisualScreenMask;
@@ -3828,7 +3844,7 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, u
#if defined(VULKAN_ENABLED)
if (context_vulkan) {
- Error err = context_vulkan->window_create(id, wd.x11_window, x11_display, p_rect.size.width, p_rect.size.height);
+ Error err = context_vulkan->window_create(id, p_vsync_mode, wd.x11_window, x11_display, p_rect.size.width, p_rect.size.height);
ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create a Vulkan window");
}
#endif
@@ -3865,7 +3881,7 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, u
return id;
}
-DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events);
r_error = OK;
@@ -4101,7 +4117,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
Point2i window_position(
(screen_get_size(0).width - p_resolution.width) / 2,
(screen_get_size(0).height - p_resolution.height) / 2);
- WindowID main_window = _create_window(p_mode, p_flags, Rect2i(window_position, p_resolution));
+ WindowID main_window = _create_window(p_mode, p_vsync_mode, p_flags, Rect2i(window_position, p_resolution));
if (main_window == INVALID_WINDOW_ID) {
r_error = ERR_CANT_CREATE;
return;
diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h
index 707775a1da..c5cf5ee4cb 100644
--- a/platform/linuxbsd/display_server_x11.h
+++ b/platform/linuxbsd/display_server_x11.h
@@ -152,7 +152,7 @@ class DisplayServerX11 : public DisplayServer {
Map<WindowID, WindowData> windows;
WindowID window_id_counter = MAIN_WINDOW_ID;
- WindowID _create_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect);
+ WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect);
String internal_clipboard;
Window xdnd_source_window;
@@ -307,7 +307,7 @@ public:
virtual Vector<DisplayServer::WindowID> get_window_list() const;
- virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
+ virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
virtual void show_window(WindowID p_id);
virtual void delete_sub_window(WindowID p_id);
@@ -362,6 +362,9 @@ public:
virtual void window_set_ime_active(const bool p_active, WindowID p_window = MAIN_WINDOW_ID);
virtual void window_set_ime_position(const Point2i &p_pos, WindowID p_window = MAIN_WINDOW_ID);
+ virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override;
+
virtual void cursor_set_shape(CursorShape p_shape);
virtual CursorShape cursor_get_shape() const;
virtual void cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot);
@@ -383,12 +386,12 @@ public:
virtual void set_native_icon(const String &p_filename);
virtual void set_icon(const Ref<Image> &p_icon);
- static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
static Vector<String> get_rendering_drivers_func();
static void register_x11_driver();
- DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
~DisplayServerX11();
};
diff --git a/platform/linuxbsd/freedesktop_screensaver.cpp b/platform/linuxbsd/freedesktop_screensaver.cpp
index 23093698ba..a6a3b27d76 100644
--- a/platform/linuxbsd/freedesktop_screensaver.cpp
+++ b/platform/linuxbsd/freedesktop_screensaver.cpp
@@ -55,7 +55,8 @@ void FreeDesktopScreenSaver::inhibit() {
}
String app_name_string = ProjectSettings::get_singleton()->get("application/config/name");
- const char *app_name = app_name_string.is_empty() ? "Godot Engine" : app_name_string.utf8().get_data();
+ CharString app_name_utf8 = app_name_string.utf8();
+ const char *app_name = app_name_string.is_empty() ? "Godot Engine" : app_name_utf8.get_data();
const char *reason = "Running Godot Engine project";
diff --git a/platform/linuxbsd/vulkan_context_x11.cpp b/platform/linuxbsd/vulkan_context_x11.cpp
index 021db630e0..88cb00a8a1 100644
--- a/platform/linuxbsd/vulkan_context_x11.cpp
+++ b/platform/linuxbsd/vulkan_context_x11.cpp
@@ -35,7 +35,7 @@ const char *VulkanContextX11::_get_platform_surface_extension() const {
return VK_KHR_XLIB_SURFACE_EXTENSION_NAME;
}
-Error VulkanContextX11::window_create(DisplayServer::WindowID p_window_id, ::Window p_window, Display *p_display, int p_width, int p_height) {
+Error VulkanContextX11::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, ::Window p_window, Display *p_display, int p_width, int p_height) {
VkXlibSurfaceCreateInfoKHR createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = nullptr;
@@ -46,7 +46,7 @@ Error VulkanContextX11::window_create(DisplayServer::WindowID p_window_id, ::Win
VkSurfaceKHR surface;
VkResult err = vkCreateXlibSurfaceKHR(_get_instance(), &createInfo, nullptr, &surface);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
- return _window_create(p_window_id, surface, p_width, p_height);
+ return _window_create(p_window_id, p_vsync_mode, surface, p_width, p_height);
}
VulkanContextX11::VulkanContextX11() {
diff --git a/platform/linuxbsd/vulkan_context_x11.h b/platform/linuxbsd/vulkan_context_x11.h
index 26472444ad..de4a9c7b90 100644
--- a/platform/linuxbsd/vulkan_context_x11.h
+++ b/platform/linuxbsd/vulkan_context_x11.h
@@ -38,7 +38,7 @@ class VulkanContextX11 : public VulkanContext {
virtual const char *_get_platform_surface_extension() const;
public:
- Error window_create(DisplayServer::WindowID p_window_id, ::Window p_window, Display *p_display, int p_width, int p_height);
+ Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, ::Window p_window, Display *p_display, int p_width, int p_height);
VulkanContextX11();
~VulkanContextX11();
diff --git a/platform/osx/display_server_osx.h b/platform/osx/display_server_osx.h
index 5f7f5f84a2..c7b9e411b8 100644
--- a/platform/osx/display_server_osx.h
+++ b/platform/osx/display_server_osx.h
@@ -145,7 +145,7 @@ public:
WindowID window_id_counter = MAIN_WINDOW_ID;
- WindowID _create_window(WindowMode p_mode, const Rect2i &p_rect);
+ WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, const Rect2i &p_rect);
void _update_window(WindowData p_wd);
void _send_window_event(const WindowData &wd, WindowEvent p_event);
static void _dispatch_input_events(const Ref<InputEvent> &p_event);
@@ -232,7 +232,7 @@ public:
virtual Vector<int> get_window_list() const override;
- virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()) override;
+ virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()) override;
virtual void show_window(WindowID p_id) override;
virtual void delete_sub_window(WindowID p_id) override;
@@ -286,6 +286,9 @@ public:
virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) override;
virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const override;
+ virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override;
+
virtual Point2i ime_get_selection() const override;
virtual String ime_get_text() const override;
@@ -314,12 +317,12 @@ public:
virtual void console_set_visible(bool p_enabled) override;
virtual bool is_console_visible() const override;
- static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
static Vector<String> get_rendering_drivers_func();
static void register_osx_driver();
- DisplayServerOSX(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ DisplayServerOSX(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
~DisplayServerOSX();
};
diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm
index 4a672a4b17..dec6da42fe 100644
--- a/platform/osx/display_server_osx.mm
+++ b/platform/osx/display_server_osx.mm
@@ -2388,10 +2388,10 @@ Vector<DisplayServer::WindowID> DisplayServerOSX::get_window_list() const {
return ret;
}
-DisplayServer::WindowID DisplayServerOSX::create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect) {
+DisplayServer::WindowID DisplayServerOSX::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
_THREAD_SAFE_METHOD_
- WindowID id = _create_window(p_mode, p_rect);
+ WindowID id = _create_window(p_mode, p_vsync_mode, p_rect);
for (int i = 0; i < WINDOW_FLAG_MAX; i++) {
if (p_flags & (1 << i)) {
window_set_flag(WindowFlags(i), true, id);
@@ -3546,6 +3546,22 @@ void DisplayServerOSX::set_icon(const Ref<Image> &p_icon) {
[nsimg release];
}
+void DisplayServerOSX::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
+ _THREAD_SAFE_METHOD_
+#if defined(VULKAN_ENABLED)
+ context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
+#endif
+}
+
+DisplayServer::VSyncMode DisplayServerOSX::window_get_vsync_mode(WindowID p_window) const {
+ _THREAD_SAFE_METHOD_
+#if defined(VULKAN_ENABLED)
+ return context_vulkan->get_vsync_mode(p_window);
+#else
+ return DisplayServer::VSYNC_ENABLED;
+#endif
+}
+
Vector<String> DisplayServerOSX::get_rendering_drivers_func() {
Vector<String> drivers;
@@ -3596,15 +3612,15 @@ ObjectID DisplayServerOSX::window_get_attached_instance_id(WindowID p_window) co
return windows[p_window].instance_id;
}
-DisplayServer *DisplayServerOSX::create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
- DisplayServer *ds = memnew(DisplayServerOSX(p_rendering_driver, p_mode, p_flags, p_resolution, r_error));
+DisplayServer *DisplayServerOSX::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+ DisplayServer *ds = memnew(DisplayServerOSX(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
if (r_error != OK) {
ds->alert("Your video card driver does not support any of the supported Metal versions.", "Unable to initialize Video driver");
}
return ds;
}
-DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, const Rect2i &p_rect) {
+DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, const Rect2i &p_rect) {
WindowID id;
const float scale = screen_get_max_scale();
{
@@ -3651,7 +3667,7 @@ DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, c
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
if (context_vulkan) {
- Error err = context_vulkan->window_create(window_id_counter, wd.window_view, p_rect.size.width, p_rect.size.height);
+ Error err = context_vulkan->window_create(window_id_counter, p_vsync_mode, wd.window_view, p_rect.size.width, p_rect.size.height);
ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create a Vulkan context");
}
}
@@ -3750,7 +3766,7 @@ bool DisplayServerOSX::is_console_visible() const {
return isatty(STDIN_FILENO);
}
-DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events);
r_error = OK;
@@ -3886,7 +3902,7 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
Point2i window_position(
screen_get_position(0).x + (screen_get_size(0).width - p_resolution.width) / 2,
screen_get_position(0).y + (screen_get_size(0).height - p_resolution.height) / 2);
- WindowID main_window = _create_window(p_mode, Rect2i(window_position, p_resolution));
+ WindowID main_window = _create_window(p_mode, p_vsync_mode, Rect2i(window_position, p_resolution));
ERR_FAIL_COND(main_window == INVALID_WINDOW_ID);
for (int i = 0; i < WINDOW_FLAG_MAX; i++) {
if (p_flags & (1 << i)) {
diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp
index f68ff32012..ea34b8a24e 100644
--- a/platform/osx/export/export.cpp
+++ b/platform/osx/export/export.cpp
@@ -163,9 +163,13 @@ void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options)
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/replace_existing_signature"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/entitlements/custom_file", PROPERTY_HINT_GLOBAL_FILE, "*.plist"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/allow_jit_code_execution"), false));
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/allow_unsigned_executable_memory"), false));
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/allow_dyld_environment_variables"), false));
+ if (!Engine::get_singleton()->has_singleton("GodotSharp")) {
+ // These entitlements are required to run managed code, and are always enabled in Mono builds.
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/allow_jit_code_execution"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/allow_unsigned_executable_memory"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/allow_dyld_environment_variables"), false));
+ }
+
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/disable_library_validation"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/audio_input"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/camera"), false));
@@ -786,18 +790,29 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
ent_f->store_line("<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">");
ent_f->store_line("<plist version=\"1.0\">");
ent_f->store_line("<dict>");
- if ((bool)p_preset->get("codesign/entitlements/allow_jit_code_execution")) {
+ if (Engine::get_singleton()->has_singleton("GodotSharp")) {
+ // These entitlements are required to run managed code, and are always enabled in Mono builds.
ent_f->store_line("<key>com.apple.security.cs.allow-jit</key>");
ent_f->store_line("<true/>");
- }
- if ((bool)p_preset->get("codesign/entitlements/allow_unsigned_executable_memory")) {
ent_f->store_line("<key>com.apple.security.cs.allow-unsigned-executable-memory</key>");
ent_f->store_line("<true/>");
- }
- if ((bool)p_preset->get("codesign/entitlements/allow_dyld_environment_variables")) {
ent_f->store_line("<key>com.apple.security.cs.allow-dyld-environment-variables</key>");
ent_f->store_line("<true/>");
+ } else {
+ if ((bool)p_preset->get("codesign/entitlements/allow_jit_code_execution")) {
+ ent_f->store_line("<key>com.apple.security.cs.allow-jit</key>");
+ ent_f->store_line("<true/>");
+ }
+ if ((bool)p_preset->get("codesign/entitlements/allow_unsigned_executable_memory")) {
+ ent_f->store_line("<key>com.apple.security.cs.allow-unsigned-executable-memory</key>");
+ ent_f->store_line("<true/>");
+ }
+ if ((bool)p_preset->get("codesign/entitlements/allow_dyld_environment_variables")) {
+ ent_f->store_line("<key>com.apple.security.cs.allow-dyld-environment-variables</key>");
+ ent_f->store_line("<true/>");
+ }
}
+
if ((bool)p_preset->get("codesign/entitlements/disable_library_validation")) {
ent_f->store_line("<key>com.apple.security.cs.disable-library-validation</key>");
ent_f->store_line("<true/>");
diff --git a/platform/osx/vulkan_context_osx.h b/platform/osx/vulkan_context_osx.h
index 8b6a75adfb..22d43688a3 100644
--- a/platform/osx/vulkan_context_osx.h
+++ b/platform/osx/vulkan_context_osx.h
@@ -38,7 +38,7 @@ class VulkanContextOSX : public VulkanContext {
virtual const char *_get_platform_surface_extension() const;
public:
- Error window_create(DisplayServer::WindowID p_window_id, id p_window, int p_width, int p_height);
+ Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, id p_window, int p_width, int p_height);
VulkanContextOSX();
~VulkanContextOSX();
diff --git a/platform/osx/vulkan_context_osx.mm b/platform/osx/vulkan_context_osx.mm
index 6b87fbd489..7e18e177c1 100644
--- a/platform/osx/vulkan_context_osx.mm
+++ b/platform/osx/vulkan_context_osx.mm
@@ -35,7 +35,7 @@ const char *VulkanContextOSX::_get_platform_surface_extension() const {
return VK_MVK_MACOS_SURFACE_EXTENSION_NAME;
}
-Error VulkanContextOSX::window_create(DisplayServer::WindowID p_window_id, id p_window, int p_width, int p_height) {
+Error VulkanContextOSX::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, id p_window, int p_width, int p_height) {
VkMacOSSurfaceCreateInfoMVK createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
createInfo.pNext = nullptr;
@@ -45,7 +45,7 @@ Error VulkanContextOSX::window_create(DisplayServer::WindowID p_window_id, id p_
VkSurfaceKHR surface;
VkResult err = vkCreateMacOSSurfaceMVK(_get_instance(), &createInfo, nullptr, &surface);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
- return _window_create(p_window_id, surface, p_width, p_height);
+ return _window_create(p_window_id, p_vsync_mode, surface, p_width, p_height);
}
VulkanContextOSX::VulkanContextOSX() {
diff --git a/platform/windows/context_gl_windows.cpp b/platform/windows/context_gl_windows.cpp
index 7cf9738f13..74b12cbb3b 100644
--- a/platform/windows/context_gl_windows.cpp
+++ b/platform/windows/context_gl_windows.cpp
@@ -66,46 +66,13 @@ int ContextGL_Windows::get_window_height() {
return OS::get_singleton()->get_video_mode().height;
}
-bool ContextGL_Windows::should_vsync_via_compositor() {
- if (OS::get_singleton()->is_window_fullscreen() || !OS::get_singleton()->is_vsync_via_compositor_enabled()) {
- return false;
- }
-
- // Note: All Windows versions supported by Godot have a compositor.
- // It can be disabled on earlier Windows versions.
- BOOL dwm_enabled;
-
- if (SUCCEEDED(DwmIsCompositionEnabled(&dwm_enabled))) {
- return dwm_enabled;
- }
-
- return false;
-}
-
void ContextGL_Windows::swap_buffers() {
SwapBuffers(hDC);
-
- if (use_vsync) {
- bool vsync_via_compositor_now = should_vsync_via_compositor();
-
- if (vsync_via_compositor_now && wglGetSwapIntervalEXT() == 0) {
- DwmFlush();
- }
-
- if (vsync_via_compositor_now != vsync_via_compositor) {
- // The previous frame had a different operating mode than this
- // frame. Set the 'vsync_via_compositor' member variable and the
- // OpenGL swap interval to their proper values.
- set_use_vsync(true);
- }
- }
}
void ContextGL_Windows::set_use_vsync(bool p_use) {
- vsync_via_compositor = p_use && should_vsync_via_compositor();
-
if (wglSwapIntervalEXT) {
- int swap_interval = (p_use && !vsync_via_compositor) ? 1 : 0;
+ int swap_interval = p_use ? 1 : 0;
wglSwapIntervalEXT(swap_interval);
}
@@ -210,7 +177,6 @@ ContextGL_Windows::ContextGL_Windows(HWND hwnd, bool p_opengl_3_context) {
opengl_3_context = p_opengl_3_context;
hWnd = hwnd;
use_vsync = false;
- vsync_via_compositor = false;
pixel_format = 0;
}
diff --git a/platform/windows/context_gl_windows.h b/platform/windows/context_gl_windows.h
index e44e2945ca..c8e8a0891d 100644
--- a/platform/windows/context_gl_windows.h
+++ b/platform/windows/context_gl_windows.h
@@ -50,13 +50,10 @@ class ContextGL_Windows {
HWND hWnd;
bool opengl_3_context;
bool use_vsync;
- bool vsync_via_compositor;
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT;
- static bool should_vsync_via_compositor();
-
public:
void release_current();
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index f7172598ec..4f64809abc 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -477,10 +477,10 @@ DisplayServer::WindowID DisplayServerWindows::get_window_at_screen_position(cons
return INVALID_WINDOW_ID;
}
-DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect) {
+DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
_THREAD_SAFE_METHOD_
- WindowID window_id = _create_window(p_mode, p_flags, p_rect);
+ WindowID window_id = _create_window(p_mode, p_vsync_mode, p_flags, p_rect);
ERR_FAIL_COND_V_MSG(window_id == INVALID_WINDOW_ID, INVALID_WINDOW_ID, "Failed to create sub window.");
WindowData &wd = windows[window_id];
@@ -1697,11 +1697,20 @@ void DisplayServerWindows::set_icon(const Ref<Image> &p_icon) {
SendMessage(windows[MAIN_WINDOW_ID].hWnd, WM_SETICON, ICON_BIG, (LPARAM)hicon);
}
-void DisplayServerWindows::vsync_set_use_via_compositor(bool p_enable) {
+void DisplayServerWindows::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
+ _THREAD_SAFE_METHOD_
+#if defined(VULKAN_ENABLED)
+ context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
+#endif
}
-bool DisplayServerWindows::vsync_is_using_via_compositor() const {
- return false;
+DisplayServer::VSyncMode DisplayServerWindows::window_get_vsync_mode(WindowID p_window) const {
+ _THREAD_SAFE_METHOD_
+#if defined(VULKAN_ENABLED)
+ return context_vulkan->get_vsync_mode(p_window);
+#else
+ return DisplayServer::VSYNC_ENABLED;
+#endif
}
void DisplayServerWindows::set_context(Context p_context) {
@@ -2968,7 +2977,7 @@ void DisplayServerWindows::_update_tablet_ctx(const String &p_old_driver, const
}
}
-DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect) {
+DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
DWORD dwExStyle;
DWORD dwStyle;
@@ -3030,7 +3039,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
#ifdef VULKAN_ENABLED
if (rendering_driver == "vulkan") {
- if (context_vulkan->window_create(id, wd.hWnd, hInstance, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top) == -1) {
+ if (context_vulkan->window_create(id, p_vsync_mode, wd.hWnd, hInstance, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top) == -1) {
memdelete(context_vulkan);
context_vulkan = nullptr;
windows.erase(id);
@@ -3151,7 +3160,7 @@ void DisplayServerWindows::tablet_set_current_driver(const String &p_driver) {
}
}
-DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
drop_events = false;
key_event_pos = 0;
@@ -3270,7 +3279,6 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
}
context_gles2->set_use_vsync(video_mode.use_vsync);
- set_vsync_via_compositor(video_mode.vsync_via_compositor);
if (RasterizerGLES2::is_viable() == OK) {
RasterizerGLES2::register_config();
@@ -3286,7 +3294,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
(screen_get_size(0).width - p_resolution.width) / 2,
(screen_get_size(0).height - p_resolution.height) / 2);
- WindowID main_window = _create_window(p_mode, 0, Rect2i(window_position, p_resolution));
+ WindowID main_window = _create_window(p_mode, p_vsync_mode, 0, Rect2i(window_position, p_resolution));
ERR_FAIL_COND_MSG(main_window == INVALID_WINDOW_ID, "Failed to create main window.");
for (int i = 0; i < WINDOW_FLAG_MAX; i++) {
@@ -3347,8 +3355,8 @@ Vector<String> DisplayServerWindows::get_rendering_drivers_func() {
return drivers;
}
-DisplayServer *DisplayServerWindows::create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
- DisplayServer *ds = memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_flags, p_resolution, r_error));
+DisplayServer *DisplayServerWindows::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+ DisplayServer *ds = memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
if (r_error != OK) {
ds->alert("Your video card driver does not support any of the supported Vulkan versions.\n"
"Please update your drivers or if you have a very old or integrated GPU upgrade it.",
diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h
index d71e579c67..394bed79b0 100644
--- a/platform/windows/display_server_windows.h
+++ b/platform/windows/display_server_windows.h
@@ -389,7 +389,7 @@ class DisplayServerWindows : public DisplayServer {
JoypadWindows *joypad;
- WindowID _create_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect);
+ WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect);
WindowID window_id_counter = MAIN_WINDOW_ID;
Map<WindowID, WindowData> windows;
@@ -469,7 +469,7 @@ public:
virtual Vector<DisplayServer::WindowID> get_window_list() const;
- virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
+ virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
virtual void show_window(WindowID p_window);
virtual void delete_sub_window(WindowID p_window);
@@ -525,6 +525,9 @@ public:
virtual void window_set_ime_active(const bool p_active, WindowID p_window = MAIN_WINDOW_ID);
virtual void window_set_ime_position(const Point2i &p_pos, WindowID p_window = MAIN_WINDOW_ID);
+ virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override;
+
virtual void console_set_visible(bool p_enabled);
virtual bool is_console_visible() const;
@@ -558,16 +561,13 @@ public:
virtual void set_native_icon(const String &p_filename);
virtual void set_icon(const Ref<Image> &p_icon);
- virtual void vsync_set_use_via_compositor(bool p_enable);
- virtual bool vsync_is_using_via_compositor() const;
-
virtual void set_context(Context p_context);
- static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
static Vector<String> get_rendering_drivers_func();
static void register_windows_driver();
- DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
~DisplayServerWindows();
};
diff --git a/platform/windows/vulkan_context_win.cpp b/platform/windows/vulkan_context_win.cpp
index e5e176ab93..191792b329 100644
--- a/platform/windows/vulkan_context_win.cpp
+++ b/platform/windows/vulkan_context_win.cpp
@@ -35,18 +35,17 @@ const char *VulkanContextWindows::_get_platform_surface_extension() const {
return VK_KHR_WIN32_SURFACE_EXTENSION_NAME;
}
-int VulkanContextWindows::window_create(DisplayServer::WindowID p_window_id, HWND p_window, HINSTANCE p_instance, int p_width, int p_height) {
+int VulkanContextWindows::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, HWND p_window, HINSTANCE p_instance, int p_width, int p_height) {
VkWin32SurfaceCreateInfoKHR createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = nullptr;
createInfo.flags = 0;
createInfo.hinstance = p_instance;
createInfo.hwnd = p_window;
-
VkSurfaceKHR surface;
VkResult err = vkCreateWin32SurfaceKHR(_get_instance(), &createInfo, nullptr, &surface);
ERR_FAIL_COND_V(err, -1);
- return _window_create(p_window_id, surface, p_width, p_height);
+ return _window_create(p_window_id, p_vsync_mode, surface, p_width, p_height);
}
VulkanContextWindows::VulkanContextWindows() {
diff --git a/platform/windows/vulkan_context_win.h b/platform/windows/vulkan_context_win.h
index 4fe987218d..39dd2641fd 100644
--- a/platform/windows/vulkan_context_win.h
+++ b/platform/windows/vulkan_context_win.h
@@ -38,7 +38,7 @@ class VulkanContextWindows : public VulkanContext {
virtual const char *_get_platform_surface_extension() const;
public:
- int window_create(DisplayServer::WindowID p_window_id, HWND p_window, HINSTANCE p_instance, int p_width, int p_height);
+ int window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, HWND p_window, HINSTANCE p_instance, int p_width, int p_height);
VulkanContextWindows();
~VulkanContextWindows();
diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp
index 7d6abe458a..5af7b8ca07 100644
--- a/scene/3d/decal.cpp
+++ b/scene/3d/decal.cpp
@@ -45,6 +45,7 @@ void Decal::set_texture(DecalTexture p_type, const Ref<Texture2D> &p_texture) {
textures[p_type] = p_texture;
RID texture_rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
RS::get_singleton()->decal_set_texture(decal, RS::DecalTexture(p_type), texture_rid);
+ update_configuration_warnings();
}
Ref<Texture2D> Decal::get_texture(DecalTexture p_type) const {
@@ -137,6 +138,7 @@ float Decal::get_distance_fade_length() const {
void Decal::set_cull_mask(uint32_t p_layers) {
cull_mask = p_layers;
RS::get_singleton()->decal_set_cull_mask(decal, cull_mask);
+ update_configuration_warnings();
}
uint32_t Decal::get_cull_mask() const {
@@ -160,6 +162,27 @@ void Decal::_validate_property(PropertyInfo &property) const {
}
}
+TypedArray<String> Decal::get_configuration_warnings() const {
+ TypedArray<String> warnings = Node::get_configuration_warnings();
+
+ if (textures[TEXTURE_ALBEDO].is_null() && textures[TEXTURE_NORMAL].is_null() && textures[TEXTURE_ORM].is_null() && textures[TEXTURE_EMISSION].is_null()) {
+ warnings.push_back(TTR("The decal has no textures loaded into any of its texture properties, and will therefore not be visible."));
+ }
+
+ if ((textures[TEXTURE_NORMAL].is_valid() || textures[TEXTURE_ORM].is_valid()) && textures[TEXTURE_ALBEDO].is_null()) {
+ warnings.push_back(TTR("The decal has a Normal and/or ORM texture, but no Albedo texture is set.\nAn Albedo texture with an alpha channel is required to blend the normal/ORM maps onto the underlying surface.\nIf you don't want the Albedo texture to be visible, set Albedo Mix to 0."));
+ }
+
+ if (cull_mask == 0) {
+ // NOTE: This warning will not be emitted if none of the 20 checkboxes
+ // exposed in the editor are checked. This is because there are
+ // currently 12 unexposed layers in the editor inspector.
+ warnings.push_back(TTR("The decal's Cull Mask has no bits enabled, which means the decal will not paint objects on any layer.\nTo resolve this, enable at least one bit in the Cull Mask property."));
+ }
+
+ return warnings;
+}
+
void Decal::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_extents", "extents"), &Decal::set_extents);
ClassDB::bind_method(D_METHOD("get_extents"), &Decal::get_extents);
@@ -207,7 +230,9 @@ void Decal::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_energy", PROPERTY_HINT_RANGE, "0,128,0.01"), "set_emission_energy", "get_emission_energy");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "modulate"), "set_modulate", "get_modulate");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "albedo_mix", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_albedo_mix", "get_albedo_mix");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "normal_fade", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_normal_fade", "get_normal_fade");
+ // A Normal Fade of 1.0 causes the decal to be invisible even if fully perpendicular to a surface.
+ // Due to this, limit Normal Fade to 0.999.
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "normal_fade", PROPERTY_HINT_RANGE, "0,0.999,0.001"), "set_normal_fade", "get_normal_fade");
ADD_GROUP("Vertical Fade", "");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "upper_fade", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_upper_fade", "get_upper_fade");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lower_fade", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_lower_fade", "get_lower_fade");
diff --git a/scene/3d/decal.h b/scene/3d/decal.h
index ce19e76de1..31a6315213 100644
--- a/scene/3d/decal.h
+++ b/scene/3d/decal.h
@@ -67,6 +67,8 @@ protected:
void _validate_property(PropertyInfo &property) const override;
public:
+ virtual TypedArray<String> get_configuration_warnings() const override;
+
void set_extents(const Vector3 &p_extents);
Vector3 get_extents() const;
diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp
index 279a1fb7de..28ccbd3e68 100644
--- a/scene/3d/mesh_instance_3d.cpp
+++ b/scene/3d/mesh_instance_3d.cpp
@@ -241,12 +241,12 @@ void MeshInstance3D::create_trimesh_collision() {
}
}
-Node *MeshInstance3D::create_convex_collision_node() {
+Node *MeshInstance3D::create_convex_collision_node(bool p_clean, bool p_simplify) {
if (mesh.is_null()) {
return nullptr;
}
- Ref<Shape3D> shape = mesh->create_convex_shape();
+ Ref<Shape3D> shape = mesh->create_convex_shape(p_clean, p_simplify);
if (shape.is_null()) {
return nullptr;
}
@@ -258,8 +258,8 @@ Node *MeshInstance3D::create_convex_collision_node() {
return static_body;
}
-void MeshInstance3D::create_convex_collision() {
- StaticBody3D *static_body = Object::cast_to<StaticBody3D>(create_convex_collision_node());
+void MeshInstance3D::create_convex_collision(bool p_clean, bool p_simplify) {
+ StaticBody3D *static_body = Object::cast_to<StaticBody3D>(create_convex_collision_node(p_clean, p_simplify));
ERR_FAIL_COND(!static_body);
static_body->set_name(String(get_name()) + "_col");
@@ -451,7 +451,7 @@ void MeshInstance3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("create_trimesh_collision"), &MeshInstance3D::create_trimesh_collision);
ClassDB::set_method_flags("MeshInstance3D", "create_trimesh_collision", METHOD_FLAGS_DEFAULT);
- ClassDB::bind_method(D_METHOD("create_convex_collision"), &MeshInstance3D::create_convex_collision);
+ ClassDB::bind_method(D_METHOD("create_convex_collision", "clean", "simplify"), &MeshInstance3D::create_convex_collision, DEFVAL(true), DEFVAL(false));
ClassDB::set_method_flags("MeshInstance3D", "create_convex_collision", METHOD_FLAGS_DEFAULT);
ClassDB::bind_method(D_METHOD("create_multiple_convex_collisions"), &MeshInstance3D::create_multiple_convex_collisions);
ClassDB::set_method_flags("MeshInstance3D", "create_multiple_convex_collisions", METHOD_FLAGS_DEFAULT);
diff --git a/scene/3d/mesh_instance_3d.h b/scene/3d/mesh_instance_3d.h
index 9dea5804e0..e2d20d0a90 100644
--- a/scene/3d/mesh_instance_3d.h
+++ b/scene/3d/mesh_instance_3d.h
@@ -83,8 +83,8 @@ public:
Node *create_trimesh_collision_node();
void create_trimesh_collision();
- Node *create_convex_collision_node();
- void create_convex_collision();
+ Node *create_convex_collision_node(bool p_clean = true, bool p_simplify = false);
+ void create_convex_collision(bool p_clean = true, bool p_simplify = false);
Node *create_multiple_convex_collisions_node();
void create_multiple_convex_collisions();
diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp
index 935ec457aa..0871423fbd 100644
--- a/scene/animation/animation_blend_space_2d.cpp
+++ b/scene/animation/animation_blend_space_2d.cpp
@@ -532,10 +532,10 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) {
float from = 0.0;
if (blend_mode == BLEND_MODE_DISCRETE_CARRY && closest != -1) {
//see how much animation remains
- from = blend_node(blend_points[closest].name, blend_points[closest].node, p_time, true, 0.0, FILTER_IGNORE, false) - length_internal;
+ from = length_internal - blend_node(blend_points[closest].name, blend_points[closest].node, p_time, false, 0.0, FILTER_IGNORE, false);
}
- mind = blend_node(blend_points[new_closest].name, blend_points[new_closest].node, from, true, 1.0, FILTER_IGNORE, false) + from;
+ mind = blend_node(blend_points[new_closest].name, blend_points[new_closest].node, from, true, 1.0, FILTER_IGNORE, false);
length_internal = from + mind;
closest = new_closest;
diff --git a/scene/gui/box_container.cpp b/scene/gui/box_container.cpp
index 7407ad5b8f..40a49dbb58 100644
--- a/scene/gui/box_container.cpp
+++ b/scene/gui/box_container.cpp
@@ -349,6 +349,7 @@ void BoxContainer::_bind_methods() {
MarginContainer *VBoxContainer::add_margin_child(const String &p_label, Control *p_control, bool p_expand) {
Label *l = memnew(Label);
+ l->set_theme_type_variation("HeaderSmall");
l->set_text(p_label);
add_child(l);
MarginContainer *mc = memnew(MarginContainer);
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index d42b505f7b..718e754514 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -339,13 +339,6 @@ bool Control::_get(const StringName &p_name, Variant &r_ret) const {
void Control::_get_property_list(List<PropertyInfo> *p_list) const {
Ref<Theme> theme = Theme::get_default();
- /* Using the default theme since the properties below are meant for editor only
- if (data.theme.is_valid()) {
- theme = data.theme;
- } else {
- theme = Theme::get_default();
-
- }*/
{
List<StringName> names;
@@ -421,6 +414,34 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const {
}
}
+void Control::_validate_property(PropertyInfo &property) const {
+ if (property.name == "theme_type_variation") {
+ List<StringName> names;
+
+ // Only the default theme and the project theme are used for the list of options.
+ // This is an imposed limitation to simplify the logic needed to leverage those options.
+ Theme::get_default()->get_type_variation_list(get_class_name(), &names);
+ if (Theme::get_project_default().is_valid()) {
+ Theme::get_project_default()->get_type_variation_list(get_class_name(), &names);
+ }
+ names.sort_custom<StringName::AlphCompare>();
+
+ Vector<StringName> unique_names;
+ String hint_string;
+ for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
+ // Skip duplicate values.
+ if (unique_names.has(E->get())) {
+ continue;
+ }
+
+ hint_string += String(E->get()) + ",";
+ unique_names.append(E->get());
+ }
+
+ property.hint_string = hint_string;
+ }
+}
+
Control *Control::get_parent_control() const {
return data.parent;
}
@@ -867,18 +888,19 @@ bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_ow
}
void Control::_get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const {
- if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
- if (data.theme_custom_type != StringName()) {
- p_list->push_back(data.theme_custom_type);
+ if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
+ if (Theme::get_project_default().is_valid() && Theme::get_project_default()->get_type_variation_base(data.theme_type_variation) != StringName()) {
+ Theme::get_project_default()->get_type_dependencies(get_class_name(), data.theme_type_variation, p_list);
+ } else {
+ Theme::get_default()->get_type_dependencies(get_class_name(), data.theme_type_variation, p_list);
}
- Theme::get_type_dependencies(get_class_name(), p_list);
} else {
- Theme::get_type_dependencies(p_theme_type, p_list);
+ Theme::get_default()->get_type_dependencies(p_theme_type, StringName(), p_list);
}
}
Ref<Texture2D> Control::get_theme_icon(const StringName &p_name, const StringName &p_theme_type) const {
- if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
+ if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
const Ref<Texture2D> *tex = data.icon_override.getptr(p_name);
if (tex) {
return *tex;
@@ -891,7 +913,7 @@ Ref<Texture2D> Control::get_theme_icon(const StringName &p_name, const StringNam
}
Ref<StyleBox> Control::get_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const {
- if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
+ if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
const Ref<StyleBox> *style = data.style_override.getptr(p_name);
if (style) {
return *style;
@@ -904,7 +926,7 @@ Ref<StyleBox> Control::get_theme_stylebox(const StringName &p_name, const String
}
Ref<Font> Control::get_theme_font(const StringName &p_name, const StringName &p_theme_type) const {
- if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
+ if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
const Ref<Font> *font = data.font_override.getptr(p_name);
if (font) {
return *font;
@@ -917,7 +939,7 @@ Ref<Font> Control::get_theme_font(const StringName &p_name, const StringName &p_
}
int Control::get_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const {
- if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
+ if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
const int *font_size = data.font_size_override.getptr(p_name);
if (font_size) {
return *font_size;
@@ -930,7 +952,7 @@ int Control::get_theme_font_size(const StringName &p_name, const StringName &p_t
}
Color Control::get_theme_color(const StringName &p_name, const StringName &p_theme_type) const {
- if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
+ if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
const Color *color = data.color_override.getptr(p_name);
if (color) {
return *color;
@@ -943,7 +965,7 @@ Color Control::get_theme_color(const StringName &p_name, const StringName &p_the
}
int Control::get_theme_constant(const StringName &p_name, const StringName &p_theme_type) const {
- if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
+ if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
const int *constant = data.constant_override.getptr(p_name);
if (constant) {
return *constant;
@@ -986,7 +1008,7 @@ bool Control::has_theme_constant_override(const StringName &p_name) const {
}
bool Control::has_theme_icon(const StringName &p_name, const StringName &p_theme_type) const {
- if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
+ if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
if (has_theme_icon_override(p_name)) {
return true;
}
@@ -998,7 +1020,7 @@ bool Control::has_theme_icon(const StringName &p_name, const StringName &p_theme
}
bool Control::has_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const {
- if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
+ if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
if (has_theme_stylebox_override(p_name)) {
return true;
}
@@ -1010,7 +1032,7 @@ bool Control::has_theme_stylebox(const StringName &p_name, const StringName &p_t
}
bool Control::has_theme_font(const StringName &p_name, const StringName &p_theme_type) const {
- if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
+ if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
if (has_theme_font_override(p_name)) {
return true;
}
@@ -1022,7 +1044,7 @@ bool Control::has_theme_font(const StringName &p_name, const StringName &p_theme
}
bool Control::has_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const {
- if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
+ if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
if (has_theme_font_size_override(p_name)) {
return true;
}
@@ -1034,7 +1056,7 @@ bool Control::has_theme_font_size(const StringName &p_name, const StringName &p_
}
bool Control::has_theme_color(const StringName &p_name, const StringName &p_theme_type) const {
- if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
+ if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
if (has_theme_color_override(p_name)) {
return true;
}
@@ -1046,7 +1068,7 @@ bool Control::has_theme_color(const StringName &p_name, const StringName &p_them
}
bool Control::has_theme_constant(const StringName &p_name, const StringName &p_theme_type) const {
- if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
+ if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
if (has_theme_constant_override(p_name)) {
return true;
}
@@ -2031,13 +2053,13 @@ Ref<Theme> Control::get_theme() const {
return data.theme;
}
-void Control::set_theme_custom_type(const StringName &p_theme_type) {
- data.theme_custom_type = p_theme_type;
+void Control::set_theme_type_variation(const StringName &p_theme_type) {
+ data.theme_type_variation = p_theme_type;
_propagate_theme_changed(this, data.theme_owner, data.theme_owner_window);
}
-StringName Control::get_theme_custom_type() const {
- return data.theme_custom_type;
+StringName Control::get_theme_type_variation() const {
+ return data.theme_type_variation;
}
void Control::set_tooltip(const String &p_tooltip) {
@@ -2660,8 +2682,8 @@ void Control::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_theme", "theme"), &Control::set_theme);
ClassDB::bind_method(D_METHOD("get_theme"), &Control::get_theme);
- ClassDB::bind_method(D_METHOD("set_theme_custom_type", "theme_type"), &Control::set_theme_custom_type);
- ClassDB::bind_method(D_METHOD("get_theme_custom_type"), &Control::get_theme_custom_type);
+ ClassDB::bind_method(D_METHOD("set_theme_type_variation", "theme_type"), &Control::set_theme_type_variation);
+ ClassDB::bind_method(D_METHOD("get_theme_type_variation"), &Control::get_theme_type_variation);
ClassDB::bind_method(D_METHOD("add_theme_icon_override", "name", "texture"), &Control::add_theme_icon_override);
ClassDB::bind_method(D_METHOD("add_theme_stylebox_override", "name", "stylebox"), &Control::add_theme_style_override);
@@ -2810,7 +2832,7 @@ void Control::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "size_flags_stretch_ratio", PROPERTY_HINT_RANGE, "0,20,0.01,or_greater"), "set_stretch_ratio", "get_stretch_ratio");
ADD_GROUP("Theme", "theme_");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "Theme"), "set_theme", "get_theme");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "theme_custom_type"), "set_theme_custom_type", "get_theme_custom_type");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "theme_type_variation", PROPERTY_HINT_ENUM_SUGGESTION), "set_theme_type_variation", "get_theme_type_variation");
ADD_GROUP("", "");
BIND_ENUM_CONSTANT(FOCUS_NONE);
diff --git a/scene/gui/control.h b/scene/gui/control.h
index 0642686a9f..fb01295668 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -202,7 +202,7 @@ private:
Ref<Theme> theme;
Control *theme_owner = nullptr;
Window *theme_owner_window = nullptr;
- StringName theme_custom_type;
+ StringName theme_type_variation;
String tooltip;
CursorShape default_cursor = CURSOR_ARROW;
@@ -279,8 +279,8 @@ protected:
void _get_property_list(List<PropertyInfo> *p_list) const;
void _notification(int p_notification);
-
static void _bind_methods();
+ virtual void _validate_property(PropertyInfo &property) const override;
//bind helpers
@@ -402,8 +402,8 @@ public:
void set_theme(const Ref<Theme> &p_theme);
Ref<Theme> get_theme() const;
- void set_theme_custom_type(const StringName &p_theme_type);
- StringName get_theme_custom_type() const;
+ void set_theme_type_variation(const StringName &p_theme_type);
+ StringName get_theme_type_variation() const;
void set_h_size_flags(int p_flags);
int get_h_size_flags() const;
diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp
index dceab00607..9d0a6a3380 100644
--- a/scene/gui/dialogs.cpp
+++ b/scene/gui/dialogs.cpp
@@ -148,11 +148,11 @@ bool AcceptDialog::get_hide_on_ok() const {
}
void AcceptDialog::set_autowrap(bool p_autowrap) {
- label->set_autowrap(p_autowrap);
+ label->set_autowrap_mode(p_autowrap ? Label::AUTOWRAP_WORD : Label::AUTOWRAP_OFF);
}
bool AcceptDialog::has_autowrap() {
- return label->has_autowrap();
+ return label->get_autowrap_mode() != Label::AUTOWRAP_OFF;
}
void AcceptDialog::register_text_enter(Control *p_line_edit) {
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index 6580d794d1..78b9ad2569 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -36,20 +36,20 @@
#include "servers/text_server.h"
-void Label::set_autowrap(bool p_autowrap) {
- if (autowrap != p_autowrap) {
- autowrap = p_autowrap;
+void Label::set_autowrap_mode(Label::AutowrapMode p_mode) {
+ if (autowrap_mode != p_mode) {
+ autowrap_mode = p_mode;
lines_dirty = true;
}
update();
- if (clip) {
+ if (clip || overrun_behavior != OVERRUN_NO_TRIMMING) {
minimum_size_changed();
}
}
-bool Label::has_autowrap() const {
- return autowrap;
+Label::AutowrapMode Label::get_autowrap_mode() const {
+ return autowrap_mode;
}
void Label::set_uppercase(bool p_uppercase) {
@@ -94,24 +94,76 @@ void Label::_shape() {
dirty = false;
lines_dirty = true;
}
+
+ uint8_t overrun_flags = TextServer::OVERRUN_NO_TRIMMING;
if (lines_dirty) {
for (int i = 0; i < lines_rid.size(); i++) {
TS->free(lines_rid[i]);
}
lines_rid.clear();
- Vector<Vector2i> lines = TS->shaped_text_get_line_breaks(text_rid, width, 0, (autowrap) ? (TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND) : TextServer::BREAK_MANDATORY);
+ uint8_t autowrap_flags = TextServer::BREAK_MANDATORY;
+ switch (autowrap_mode) {
+ case AUTOWRAP_WORD_SMART:
+ autowrap_flags = TextServer::BREAK_WORD_BOUND_ADAPTIVE | TextServer::BREAK_MANDATORY;
+ break;
+ case AUTOWRAP_WORD:
+ autowrap_flags = TextServer::BREAK_WORD_BOUND | TextServer::BREAK_MANDATORY;
+ break;
+ case AUTOWRAP_ARBITRARY:
+ autowrap_flags = TextServer::BREAK_GRAPHEME_BOUND | TextServer::BREAK_MANDATORY;
+ break;
+ case AUTOWRAP_OFF:
+ break;
+ }
+ Vector<Vector2i> lines = TS->shaped_text_get_line_breaks(text_rid, width, 0, autowrap_flags);
+
for (int i = 0; i < lines.size(); i++) {
RID line = TS->shaped_text_substr(text_rid, lines[i].x, lines[i].y - lines[i].x);
+
+ switch (overrun_behavior) {
+ case OVERRUN_TRIM_WORD_ELLIPSIS:
+ overrun_flags |= TextServer::OVERRUN_TRIM;
+ overrun_flags |= TextServer::OVERRUN_TRIM_WORD_ONLY;
+ overrun_flags |= TextServer::OVERRUN_ADD_ELLIPSIS;
+ break;
+ case OVERRUN_TRIM_ELLIPSIS:
+ overrun_flags |= TextServer::OVERRUN_TRIM;
+ overrun_flags |= TextServer::OVERRUN_ADD_ELLIPSIS;
+ break;
+ case OVERRUN_TRIM_WORD:
+ overrun_flags |= TextServer::OVERRUN_TRIM;
+ overrun_flags |= TextServer::OVERRUN_TRIM_WORD_ONLY;
+ break;
+ case OVERRUN_TRIM_CHAR:
+ overrun_flags |= TextServer::OVERRUN_TRIM;
+ break;
+ case OVERRUN_NO_TRIMMING:
+ break;
+ }
+
+ if (autowrap_mode == AUTOWRAP_OFF && align != ALIGN_FILL && overrun_behavior != OVERRUN_NO_TRIMMING) {
+ TS->shaped_text_overrun_trim_to_width(line, width, overrun_flags);
+ }
+
lines_rid.push_back(line);
}
+
+ if (autowrap_mode != AUTOWRAP_OFF && overrun_behavior != OVERRUN_NO_TRIMMING) {
+ int visible_lines = get_visible_line_count();
+
+ if (visible_lines < lines_rid.size() && visible_lines > 0) {
+ overrun_flags |= TextServer::OVERRUN_ENFORCE_ELLIPSIS;
+ TS->shaped_text_overrun_trim_to_width(lines_rid[visible_lines - 1], width, overrun_flags);
+ }
+ }
}
if (xl_text.length() == 0) {
minsize = Size2(1, get_line_height());
return;
}
- if (!autowrap) {
+ if (autowrap_mode == AUTOWRAP_OFF) {
minsize.width = 0.0f;
for (int i = 0; i < lines_rid.size(); i++) {
if (minsize.width < TS->shaped_text_get_size(lines_rid[i]).x) {
@@ -120,10 +172,21 @@ void Label::_shape() {
}
}
- if (lines_dirty) { // Fill after min_size calculation.
+ if (lines_dirty) {
+ // Fill after min_size calculation.
if (align == ALIGN_FILL) {
for (int i = 0; i < lines_rid.size(); i++) {
- TS->shaped_text_fit_to_width(lines_rid.write[i], width);
+ if (overrun_behavior != OVERRUN_NO_TRIMMING && autowrap_mode == AUTOWRAP_OFF) {
+ float line_unaltered_width = TS->shaped_text_get_width(lines_rid[i]);
+ TS->shaped_text_fit_to_width(lines_rid[i], width);
+ float new_line_width = TS->shaped_text_get_width(lines_rid[i]);
+ // Begin trimming when there is no space between words available anymore.
+ if (new_line_width < line_unaltered_width) {
+ TS->shaped_text_overrun_trim_to_width(lines_rid[i], width, overrun_flags);
+ }
+ } else {
+ TS->shaped_text_fit_to_width(lines_rid[i], width);
+ }
}
}
lines_dirty = false;
@@ -131,7 +194,7 @@ void Label::_shape() {
_update_visible();
- if (!autowrap || !clip) {
+ if (autowrap_mode == AUTOWRAP_OFF || !clip || overrun_behavior == OVERRUN_NO_TRIMMING) {
minimum_size_changed();
}
}
@@ -370,13 +433,12 @@ Size2 Label::get_minimum_size() const {
min_size.height = MAX(min_size.height, font->get_height(get_theme_font_size("font_size")) + font->get_spacing(Font::SPACING_TOP) + font->get_spacing(Font::SPACING_BOTTOM));
Size2 min_style = get_theme_stylebox("normal")->get_minimum_size();
- if (autowrap) {
- return Size2(1, clip ? 1 : min_size.height) + min_style;
+ if (autowrap_mode != AUTOWRAP_OFF) {
+ return Size2(1, (clip || overrun_behavior != OVERRUN_NO_TRIMMING) ? 1 : min_size.height) + min_style;
} else {
- if (clip) {
+ if (clip || overrun_behavior != OVERRUN_NO_TRIMMING) {
min_size.width = 1;
}
-
return min_size + min_style;
}
}
@@ -536,6 +598,21 @@ bool Label::is_clipping_text() const {
return clip;
}
+void Label::set_text_overrun_behavior(Label::OverrunBehavior p_behavior) {
+ if (overrun_behavior != p_behavior) {
+ overrun_behavior = p_behavior;
+ lines_dirty = true;
+ }
+ update();
+ if (clip || overrun_behavior != OVERRUN_NO_TRIMMING) {
+ minimum_size_changed();
+ }
+}
+
+Label::OverrunBehavior Label::get_text_overrun_behavior() const {
+ return overrun_behavior;
+}
+
String Label::get_text() const {
return text;
}
@@ -663,10 +740,12 @@ void Label::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear_opentype_features"), &Label::clear_opentype_features);
ClassDB::bind_method(D_METHOD("set_language", "language"), &Label::set_language);
ClassDB::bind_method(D_METHOD("get_language"), &Label::get_language);
- ClassDB::bind_method(D_METHOD("set_autowrap", "enable"), &Label::set_autowrap);
- ClassDB::bind_method(D_METHOD("has_autowrap"), &Label::has_autowrap);
+ ClassDB::bind_method(D_METHOD("set_autowrap_mode", "autowrap_mode"), &Label::set_autowrap_mode);
+ ClassDB::bind_method(D_METHOD("get_autowrap_mode"), &Label::get_autowrap_mode);
ClassDB::bind_method(D_METHOD("set_clip_text", "enable"), &Label::set_clip_text);
ClassDB::bind_method(D_METHOD("is_clipping_text"), &Label::is_clipping_text);
+ ClassDB::bind_method(D_METHOD("set_text_overrun_behavior", "overrun_behavior"), &Label::set_text_overrun_behavior);
+ ClassDB::bind_method(D_METHOD("get_text_overrun_behavior"), &Label::get_text_overrun_behavior);
ClassDB::bind_method(D_METHOD("set_uppercase", "enable"), &Label::set_uppercase);
ClassDB::bind_method(D_METHOD("is_uppercase"), &Label::is_uppercase);
ClassDB::bind_method(D_METHOD("get_line_height", "line"), &Label::get_line_height, DEFVAL(-1));
@@ -696,13 +775,25 @@ void Label::_bind_methods() {
BIND_ENUM_CONSTANT(VALIGN_BOTTOM);
BIND_ENUM_CONSTANT(VALIGN_FILL);
+ BIND_ENUM_CONSTANT(AUTOWRAP_OFF);
+ BIND_ENUM_CONSTANT(AUTOWRAP_ARBITRARY);
+ BIND_ENUM_CONSTANT(AUTOWRAP_WORD);
+ BIND_ENUM_CONSTANT(AUTOWRAP_WORD_SMART);
+
+ BIND_ENUM_CONSTANT(OVERRUN_NO_TRIMMING);
+ BIND_ENUM_CONSTANT(OVERRUN_TRIM_CHAR);
+ BIND_ENUM_CONSTANT(OVERRUN_TRIM_WORD);
+ BIND_ENUM_CONSTANT(OVERRUN_TRIM_ELLIPSIS);
+ BIND_ENUM_CONSTANT(OVERRUN_TRIM_WORD_ELLIPSIS);
+
ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text");
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language");
ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_align", "get_align");
ADD_PROPERTY(PropertyInfo(Variant::INT, "valign", PROPERTY_HINT_ENUM, "Top,Center,Bottom,Fill"), "set_valign", "get_valign");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autowrap"), "set_autowrap", "has_autowrap");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "autowrap_mode", PROPERTY_HINT_ENUM, "Off,Arbitrary,Word,Word (Smart)"), "set_autowrap_mode", "get_autowrap_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_text"), "set_clip_text", "is_clipping_text");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "text_overrun_behavior", PROPERTY_HINT_ENUM, "Trim nothing,Trim characters,Trim words,Ellipsis,Word ellipsis"), "set_text_overrun_behavior", "get_text_overrun_behavior");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "uppercase"), "set_uppercase", "is_uppercase");
ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_characters", PROPERTY_HINT_RANGE, "-1,128000,1", PROPERTY_USAGE_EDITOR), "set_visible_characters", "get_visible_characters");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "percent_visible", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_percent_visible", "get_percent_visible");
diff --git a/scene/gui/label.h b/scene/gui/label.h
index 032b4112e1..8b48eb9670 100644
--- a/scene/gui/label.h
+++ b/scene/gui/label.h
@@ -51,13 +51,29 @@ public:
VALIGN_FILL
};
+ enum AutowrapMode {
+ AUTOWRAP_OFF,
+ AUTOWRAP_ARBITRARY,
+ AUTOWRAP_WORD,
+ AUTOWRAP_WORD_SMART
+ };
+
+ enum OverrunBehavior {
+ OVERRUN_NO_TRIMMING,
+ OVERRUN_TRIM_CHAR,
+ OVERRUN_TRIM_WORD,
+ OVERRUN_TRIM_ELLIPSIS,
+ OVERRUN_TRIM_WORD_ELLIPSIS,
+ };
+
private:
Align align = ALIGN_LEFT;
VAlign valign = VALIGN_TOP;
String text;
String xl_text;
- bool autowrap = false;
+ AutowrapMode autowrap_mode = AUTOWRAP_OFF;
bool clip = false;
+ OverrunBehavior overrun_behavior = OVERRUN_NO_TRIMMING;
Size2 minsize;
bool uppercase = false;
@@ -118,8 +134,8 @@ public:
void set_structured_text_bidi_override_options(Array p_args);
Array get_structured_text_bidi_override_options() const;
- void set_autowrap(bool p_autowrap);
- bool has_autowrap() const;
+ void set_autowrap_mode(AutowrapMode p_mode);
+ AutowrapMode get_autowrap_mode() const;
void set_uppercase(bool p_uppercase);
bool is_uppercase() const;
@@ -131,6 +147,9 @@ public:
void set_clip_text(bool p_clip);
bool is_clipping_text() const;
+ void set_text_overrun_behavior(OverrunBehavior p_behavior);
+ OverrunBehavior get_text_overrun_behavior() const;
+
void set_percent_visible(float p_percent);
float get_percent_visible() const;
@@ -150,5 +169,7 @@ public:
VARIANT_ENUM_CAST(Label::Align);
VARIANT_ENUM_CAST(Label::VAlign);
+VARIANT_ENUM_CAST(Label::AutowrapMode);
+VARIANT_ENUM_CAST(Label::OverrunBehavior);
#endif
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 98de71d81c..4d2cb81f23 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -99,39 +99,44 @@ void TreeItem::_change_tree(Tree *p_tree) {
c = c->next;
}
- if (tree && tree->root == this) {
- tree->root = nullptr;
- }
+ if (tree) {
+ if (tree->root == this) {
+ tree->root = nullptr;
+ }
- if (tree && tree->popup_edited_item == this) {
- tree->popup_edited_item = nullptr;
- tree->pressing_for_editor = false;
- }
+ if (tree->popup_edited_item == this) {
+ tree->popup_edited_item = nullptr;
+ tree->pressing_for_editor = false;
+ }
- if (tree && tree->cache.hover_item == this) {
- tree->cache.hover_item = nullptr;
- }
+ if (tree->cache.hover_item == this) {
+ tree->cache.hover_item = nullptr;
+ }
- if (tree && tree->selected_item == this) {
- tree->selected_item = nullptr;
- }
+ if (tree->selected_item == this) {
+ tree->selected_item = nullptr;
+ }
- if (tree && tree->drop_mode_over == this) {
- tree->drop_mode_over = nullptr;
- }
+ if (tree->drop_mode_over == this) {
+ tree->drop_mode_over = nullptr;
+ }
- if (tree && tree->single_select_defer == this) {
- tree->single_select_defer = nullptr;
- }
+ if (tree->single_select_defer == this) {
+ tree->single_select_defer = nullptr;
+ }
+
+ if (tree->edited_item == this) {
+ tree->edited_item = nullptr;
+ tree->pressing_for_editor = false;
+ }
- if (tree && tree->edited_item == this) {
- tree->edited_item = nullptr;
- tree->pressing_for_editor = false;
+ tree->update();
}
tree = p_tree;
if (tree) {
+ tree->update();
cells.resize(tree->columns.size());
}
}
@@ -451,6 +456,7 @@ TreeItem *TreeItem::create_child(int p_idx) {
TreeItem *ti = memnew(TreeItem(tree));
if (tree) {
ti->cells.resize(tree->columns.size());
+ tree->update();
}
TreeItem *l_prev = nullptr;
@@ -654,11 +660,7 @@ void TreeItem::move_before(TreeItem *p_item) {
next = p_item;
p_item->prev = this;
- if (old_tree && old_tree != tree) {
- old_tree->update();
- }
-
- if (tree) {
+ if (tree && old_tree == tree) {
tree->update();
}
}
@@ -696,11 +698,7 @@ void TreeItem::move_after(TreeItem *p_item) {
parent->children_cache.append(this);
}
- if (old_tree && old_tree != tree) {
- old_tree->update();
- }
-
- if (tree) {
+ if (tree && old_tree == tree) {
tree->update();
}
}
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index ef6d2e72f6..787b283e8c 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -507,7 +507,7 @@ bool Node::is_network_master() const {
/***** RPC CONFIG ********/
-uint16_t Node::rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_rpc_mode, NetworkedMultiplayerPeer::TransferMode p_transfer_mode, int p_channel) {
+uint16_t Node::rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_rpc_mode, MultiplayerPeer::TransferMode p_transfer_mode, int p_channel) {
for (int i = 0; i < data.rpc_methods.size(); i++) {
if (data.rpc_methods[i].name == p_method) {
MultiplayerAPI::RPCConfig &nd = data.rpc_methods.write[i];
@@ -2623,7 +2623,7 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_multiplayer"), &Node::get_multiplayer);
ClassDB::bind_method(D_METHOD("get_custom_multiplayer"), &Node::get_custom_multiplayer);
ClassDB::bind_method(D_METHOD("set_custom_multiplayer", "api"), &Node::set_custom_multiplayer);
- ClassDB::bind_method(D_METHOD("rpc_config", "method", "rpc_mode", "transfer_mode", "channel"), &Node::rpc_config, DEFVAL(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE), DEFVAL(0));
+ ClassDB::bind_method(D_METHOD("rpc_config", "method", "rpc_mode", "transfer_mode", "channel"), &Node::rpc_config, DEFVAL(MultiplayerPeer::TRANSFER_MODE_RELIABLE), DEFVAL(0));
ClassDB::bind_method(D_METHOD("set_editor_description", "editor_description"), &Node::set_editor_description);
ClassDB::bind_method(D_METHOD("get_editor_description"), &Node::get_editor_description);
diff --git a/scene/main/node.h b/scene/main/node.h
index fc5af43829..c6727ce884 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -430,7 +430,7 @@ public:
int get_network_master() const;
bool is_network_master() const;
- uint16_t rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_rpc_mode, NetworkedMultiplayerPeer::TransferMode p_transfer_mode, int p_channel = 0); // config a local method for RPC
+ uint16_t rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_rpc_mode, MultiplayerPeer::TransferMode p_transfer_mode, int p_channel = 0); // config a local method for RPC
Vector<MultiplayerAPI::RPCConfig> get_node_rpc_methods() const;
void rpc(const StringName &p_method, VARIANT_ARG_LIST); // RPC, honors RPCMode, TransferMode, channel
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 4b52c4e99f..fefe4c9f0d 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -1142,26 +1142,6 @@ Array SceneTree::get_processed_tweens() {
return ret;
}
-void SceneTree::_network_peer_connected(int p_id) {
- emit_signal("network_peer_connected", p_id);
-}
-
-void SceneTree::_network_peer_disconnected(int p_id) {
- emit_signal("network_peer_disconnected", p_id);
-}
-
-void SceneTree::_connected_to_server() {
- emit_signal("connected_to_server");
-}
-
-void SceneTree::_connection_failed() {
- emit_signal("connection_failed");
-}
-
-void SceneTree::_server_disconnected() {
- emit_signal("server_disconnected");
-}
-
Ref<MultiplayerAPI> SceneTree::get_multiplayer() const {
return multiplayer;
}
@@ -1177,58 +1157,8 @@ bool SceneTree::is_multiplayer_poll_enabled() const {
void SceneTree::set_multiplayer(Ref<MultiplayerAPI> p_multiplayer) {
ERR_FAIL_COND(!p_multiplayer.is_valid());
- if (multiplayer.is_valid()) {
- multiplayer->disconnect("network_peer_connected", callable_mp(this, &SceneTree::_network_peer_connected));
- multiplayer->disconnect("network_peer_disconnected", callable_mp(this, &SceneTree::_network_peer_disconnected));
- multiplayer->disconnect("connected_to_server", callable_mp(this, &SceneTree::_connected_to_server));
- multiplayer->disconnect("connection_failed", callable_mp(this, &SceneTree::_connection_failed));
- multiplayer->disconnect("server_disconnected", callable_mp(this, &SceneTree::_server_disconnected));
- }
-
multiplayer = p_multiplayer;
multiplayer->set_root_node(root);
-
- multiplayer->connect("network_peer_connected", callable_mp(this, &SceneTree::_network_peer_connected));
- multiplayer->connect("network_peer_disconnected", callable_mp(this, &SceneTree::_network_peer_disconnected));
- multiplayer->connect("connected_to_server", callable_mp(this, &SceneTree::_connected_to_server));
- multiplayer->connect("connection_failed", callable_mp(this, &SceneTree::_connection_failed));
- multiplayer->connect("server_disconnected", callable_mp(this, &SceneTree::_server_disconnected));
-}
-
-void SceneTree::set_network_peer(const Ref<NetworkedMultiplayerPeer> &p_network_peer) {
- multiplayer->set_network_peer(p_network_peer);
-}
-
-Ref<NetworkedMultiplayerPeer> SceneTree::get_network_peer() const {
- return multiplayer->get_network_peer();
-}
-
-bool SceneTree::is_network_server() const {
- return multiplayer->is_network_server();
-}
-
-bool SceneTree::has_network_peer() const {
- return multiplayer->has_network_peer();
-}
-
-int SceneTree::get_network_unique_id() const {
- return multiplayer->get_network_unique_id();
-}
-
-Vector<int> SceneTree::get_network_connected_peers() const {
- return multiplayer->get_network_connected_peers();
-}
-
-int SceneTree::get_rpc_sender_id() const {
- return multiplayer->get_rpc_sender_id();
-}
-
-void SceneTree::set_refuse_new_network_connections(bool p_refuse) {
- multiplayer->set_refuse_new_network_connections(p_refuse);
-}
-
-bool SceneTree::is_refusing_new_network_connections() const {
- return multiplayer->is_refusing_new_network_connections();
}
void SceneTree::_bind_methods() {
@@ -1297,24 +1227,12 @@ void SceneTree::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_multiplayer"), &SceneTree::get_multiplayer);
ClassDB::bind_method(D_METHOD("set_multiplayer_poll_enabled", "enabled"), &SceneTree::set_multiplayer_poll_enabled);
ClassDB::bind_method(D_METHOD("is_multiplayer_poll_enabled"), &SceneTree::is_multiplayer_poll_enabled);
- ClassDB::bind_method(D_METHOD("set_network_peer", "peer"), &SceneTree::set_network_peer);
- ClassDB::bind_method(D_METHOD("get_network_peer"), &SceneTree::get_network_peer);
- ClassDB::bind_method(D_METHOD("is_network_server"), &SceneTree::is_network_server);
- ClassDB::bind_method(D_METHOD("has_network_peer"), &SceneTree::has_network_peer);
- ClassDB::bind_method(D_METHOD("get_network_connected_peers"), &SceneTree::get_network_connected_peers);
- ClassDB::bind_method(D_METHOD("get_network_unique_id"), &SceneTree::get_network_unique_id);
- ClassDB::bind_method(D_METHOD("get_rpc_sender_id"), &SceneTree::get_rpc_sender_id);
- ClassDB::bind_method(D_METHOD("set_refuse_new_network_connections", "refuse"), &SceneTree::set_refuse_new_network_connections);
- ClassDB::bind_method(D_METHOD("is_refusing_new_network_connections"), &SceneTree::is_refusing_new_network_connections);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debug_collisions_hint"), "set_debug_collisions_hint", "is_debugging_collisions_hint");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debug_navigation_hint"), "set_debug_navigation_hint", "is_debugging_navigation_hint");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "paused"), "set_pause", "is_paused");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "refuse_new_network_connections"), "set_refuse_new_network_connections", "is_refusing_new_network_connections");
- ADD_PROPERTY_DEFAULT("refuse_new_network_connections", false);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "edited_scene_root", PROPERTY_HINT_RESOURCE_TYPE, "Node", PROPERTY_USAGE_NONE), "set_edited_scene_root", "get_edited_scene_root");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "current_scene", PROPERTY_HINT_RESOURCE_TYPE, "Node", PROPERTY_USAGE_NONE), "set_current_scene", "get_current_scene");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "network_peer", PROPERTY_HINT_RESOURCE_TYPE, "NetworkedMultiplayerPeer", PROPERTY_USAGE_NONE), "set_network_peer", "get_network_peer");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "root", PROPERTY_HINT_RESOURCE_TYPE, "Node", PROPERTY_USAGE_NONE), "", "get_root");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", PROPERTY_USAGE_NONE), "set_multiplayer", "get_multiplayer");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "multiplayer_poll"), "set_multiplayer_poll_enabled", "is_multiplayer_poll_enabled");
@@ -1330,11 +1248,6 @@ void SceneTree::_bind_methods() {
ADD_SIGNAL(MethodInfo("physics_frame"));
ADD_SIGNAL(MethodInfo("files_dropped", PropertyInfo(Variant::PACKED_STRING_ARRAY, "files"), PropertyInfo(Variant::INT, "screen")));
- ADD_SIGNAL(MethodInfo("network_peer_connected", PropertyInfo(Variant::INT, "id")));
- ADD_SIGNAL(MethodInfo("network_peer_disconnected", PropertyInfo(Variant::INT, "id")));
- ADD_SIGNAL(MethodInfo("connected_to_server"));
- ADD_SIGNAL(MethodInfo("connection_failed"));
- ADD_SIGNAL(MethodInfo("server_disconnected"));
BIND_ENUM_CONSTANT(GROUP_CALL_DEFAULT);
BIND_ENUM_CONSTANT(GROUP_CALL_REVERSE);
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index 0e9ffb0f5f..0be0e185a5 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -159,13 +159,6 @@ private:
Ref<MultiplayerAPI> multiplayer;
bool multiplayer_poll = true;
- void _network_peer_connected(int p_id);
- void _network_peer_disconnected(int p_id);
-
- void _connected_to_server();
- void _connection_failed();
- void _server_disconnected();
-
static SceneTree *singleton;
friend class Node;
@@ -337,16 +330,6 @@ public:
void set_multiplayer_poll_enabled(bool p_enabled);
bool is_multiplayer_poll_enabled() const;
void set_multiplayer(Ref<MultiplayerAPI> p_multiplayer);
- void set_network_peer(const Ref<NetworkedMultiplayerPeer> &p_network_peer);
- Ref<NetworkedMultiplayerPeer> get_network_peer() const;
- bool is_network_server() const;
- bool has_network_peer() const;
- int get_network_unique_id() const;
- Vector<int> get_network_connected_peers() const;
- int get_rpc_sender_id() const;
-
- void set_refuse_new_network_connections(bool p_refuse);
- bool is_refusing_new_network_connections() const;
static void add_idle_callback(IdleCallback p_callback);
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index 237dc24aad..c557fd0101 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -227,7 +227,8 @@ void Window::_make_window() {
}
}
- window_id = DisplayServer::get_singleton()->create_sub_window(DisplayServer::WindowMode(mode), f, Rect2i(position, size));
+ DisplayServer::VSyncMode vsync_mode = DisplayServer::get_singleton()->window_get_vsync_mode(DisplayServer::MAIN_WINDOW_ID);
+ window_id = DisplayServer::get_singleton()->create_sub_window(DisplayServer::WindowMode(mode), vsync_mode, f, Rect2i(position, size));
ERR_FAIL_COND(window_id == DisplayServer::INVALID_WINDOW_ID);
DisplayServer::get_singleton()->window_set_current_screen(current_screen, window_id);
DisplayServer::get_singleton()->window_set_max_size(max_size, window_id);
@@ -1170,23 +1171,24 @@ Ref<Theme> Window::get_theme() const {
return theme;
}
-void Window::set_theme_custom_type(const StringName &p_theme_type) {
- theme_custom_type = p_theme_type;
+void Window::set_theme_type_variation(const StringName &p_theme_type) {
+ theme_type_variation = p_theme_type;
Control::_propagate_theme_changed(this, theme_owner, theme_owner_window);
}
-StringName Window::get_theme_custom_type() const {
- return theme_custom_type;
+StringName Window::get_theme_type_variation() const {
+ return theme_type_variation;
}
void Window::_get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const {
- if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == theme_custom_type) {
- if (theme_custom_type != StringName()) {
- p_list->push_back(theme_custom_type);
+ if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == theme_type_variation) {
+ if (Theme::get_project_default().is_valid() && Theme::get_project_default()->get_type_variation_base(theme_type_variation) != StringName()) {
+ Theme::get_project_default()->get_type_dependencies(get_class_name(), theme_type_variation, p_list);
+ } else {
+ Theme::get_default()->get_type_dependencies(get_class_name(), theme_type_variation, p_list);
}
- Theme::get_type_dependencies(get_class_name(), p_list);
} else {
- Theme::get_type_dependencies(p_theme_type, p_list);
+ Theme::get_default()->get_type_dependencies(p_theme_type, StringName(), p_list);
}
}
@@ -1340,6 +1342,34 @@ bool Window::is_layout_rtl() const {
}
}
+void Window::_validate_property(PropertyInfo &property) const {
+ if (property.name == "theme_type_variation") {
+ List<StringName> names;
+
+ // Only the default theme and the project theme are used for the list of options.
+ // This is an imposed limitation to simplify the logic needed to leverage those options.
+ Theme::get_default()->get_type_variation_list(get_class_name(), &names);
+ if (Theme::get_project_default().is_valid()) {
+ Theme::get_project_default()->get_type_variation_list(get_class_name(), &names);
+ }
+ names.sort_custom<StringName::AlphCompare>();
+
+ Vector<StringName> unique_names;
+ String hint_string;
+ for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
+ // Skip duplicate values.
+ if (unique_names.has(E->get())) {
+ continue;
+ }
+
+ hint_string += String(E->get()) + ",";
+ unique_names.append(E->get());
+ }
+
+ property.hint_string = hint_string;
+ }
+}
+
void Window::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_title", "title"), &Window::set_title);
ClassDB::bind_method(D_METHOD("get_title"), &Window::get_title);
@@ -1417,8 +1447,8 @@ void Window::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_theme", "theme"), &Window::set_theme);
ClassDB::bind_method(D_METHOD("get_theme"), &Window::get_theme);
- ClassDB::bind_method(D_METHOD("set_theme_custom_type", "theme_type"), &Window::set_theme_custom_type);
- ClassDB::bind_method(D_METHOD("get_theme_custom_type"), &Window::get_theme_custom_type);
+ ClassDB::bind_method(D_METHOD("set_theme_type_variation", "theme_type"), &Window::set_theme_type_variation);
+ ClassDB::bind_method(D_METHOD("get_theme_type_variation"), &Window::get_theme_type_variation);
ClassDB::bind_method(D_METHOD("get_theme_icon", "name", "theme_type"), &Window::get_theme_icon, DEFVAL(""));
ClassDB::bind_method(D_METHOD("get_theme_stylebox", "name", "theme_type"), &Window::get_theme_stylebox, DEFVAL(""));
@@ -1468,7 +1498,7 @@ void Window::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_aspect", PROPERTY_HINT_ENUM, "Ignore,Keep,Keep Width,Keep Height,Expand"), "set_content_scale_aspect", "get_content_scale_aspect");
ADD_GROUP("Theme", "theme_");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "Theme"), "set_theme", "get_theme");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "theme_custom_type"), "set_theme_custom_type", "get_theme_custom_type");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "theme_type_variation", PROPERTY_HINT_ENUM_SUGGESTION), "set_theme_type_variation", "get_theme_type_variation");
ADD_SIGNAL(MethodInfo("window_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
ADD_SIGNAL(MethodInfo("files_dropped", PropertyInfo(Variant::PACKED_STRING_ARRAY, "files")));
diff --git a/scene/main/window.h b/scene/main/window.h
index 494c386606..e92b5e22ed 100644
--- a/scene/main/window.h
+++ b/scene/main/window.h
@@ -130,7 +130,7 @@ private:
Ref<Theme> theme;
Control *theme_owner = nullptr;
Window *theme_owner_window = nullptr;
- StringName theme_custom_type;
+ StringName theme_type_variation;
Viewport *embedder = nullptr;
@@ -151,6 +151,7 @@ protected:
virtual Size2 _get_contents_minimum_size() const;
static void _bind_methods();
void _notification(int p_what);
+ virtual void _validate_property(PropertyInfo &property) const override;
virtual void add_child_notify(Node *p_child) override;
virtual void remove_child_notify(Node *p_child) override;
@@ -242,8 +243,8 @@ public:
void set_theme(const Ref<Theme> &p_theme);
Ref<Theme> get_theme() const;
- void set_theme_custom_type(const StringName &p_theme_type);
- StringName get_theme_custom_type() const;
+ void set_theme_type_variation(const StringName &p_theme_type);
+ StringName get_theme_type_variation() const;
_FORCE_INLINE_ void _get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const;
Size2 get_contents_minimum_size() const;
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 24a9b12733..9efe5c58fc 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -292,108 +292,108 @@ void register_scene_types() {
OS::get_singleton()->yield(); //may take time to init
- ClassDB::register_class<Object>();
+ GDREGISTER_CLASS(Object);
- ClassDB::register_class<Node>();
- ClassDB::register_virtual_class<InstancePlaceholder>();
+ GDREGISTER_CLASS(Node);
+ GDREGISTER_VIRTUAL_CLASS(InstancePlaceholder);
- ClassDB::register_virtual_class<Viewport>();
- ClassDB::register_class<SubViewport>();
- ClassDB::register_class<ViewportTexture>();
- ClassDB::register_class<HTTPRequest>();
- ClassDB::register_class<Timer>();
- ClassDB::register_class<CanvasLayer>();
- ClassDB::register_class<CanvasModulate>();
- ClassDB::register_class<ResourcePreloader>();
- ClassDB::register_class<Window>();
+ GDREGISTER_VIRTUAL_CLASS(Viewport);
+ GDREGISTER_CLASS(SubViewport);
+ GDREGISTER_CLASS(ViewportTexture);
+ GDREGISTER_CLASS(HTTPRequest);
+ GDREGISTER_CLASS(Timer);
+ GDREGISTER_CLASS(CanvasLayer);
+ GDREGISTER_CLASS(CanvasModulate);
+ GDREGISTER_CLASS(ResourcePreloader);
+ GDREGISTER_CLASS(Window);
/* REGISTER GUI */
- ClassDB::register_class<ButtonGroup>();
- ClassDB::register_virtual_class<BaseButton>();
+ GDREGISTER_CLASS(ButtonGroup);
+ GDREGISTER_VIRTUAL_CLASS(BaseButton);
OS::get_singleton()->yield(); //may take time to init
- ClassDB::register_class<Shortcut>();
- ClassDB::register_class<Control>();
- ClassDB::register_class<Button>();
- ClassDB::register_class<Label>();
- ClassDB::register_virtual_class<ScrollBar>();
- ClassDB::register_class<HScrollBar>();
- ClassDB::register_class<VScrollBar>();
- ClassDB::register_class<ProgressBar>();
- ClassDB::register_virtual_class<Slider>();
- ClassDB::register_class<HSlider>();
- ClassDB::register_class<VSlider>();
- ClassDB::register_class<Popup>();
- ClassDB::register_class<PopupPanel>();
- ClassDB::register_class<MenuButton>();
- ClassDB::register_class<CheckBox>();
- ClassDB::register_class<CheckButton>();
- ClassDB::register_class<LinkButton>();
- ClassDB::register_class<Panel>();
- ClassDB::register_virtual_class<Range>();
+ GDREGISTER_CLASS(Shortcut);
+ GDREGISTER_CLASS(Control);
+ GDREGISTER_CLASS(Button);
+ GDREGISTER_CLASS(Label);
+ GDREGISTER_VIRTUAL_CLASS(ScrollBar);
+ GDREGISTER_CLASS(HScrollBar);
+ GDREGISTER_CLASS(VScrollBar);
+ GDREGISTER_CLASS(ProgressBar);
+ GDREGISTER_VIRTUAL_CLASS(Slider);
+ GDREGISTER_CLASS(HSlider);
+ GDREGISTER_CLASS(VSlider);
+ GDREGISTER_CLASS(Popup);
+ GDREGISTER_CLASS(PopupPanel);
+ GDREGISTER_CLASS(MenuButton);
+ GDREGISTER_CLASS(CheckBox);
+ GDREGISTER_CLASS(CheckButton);
+ GDREGISTER_CLASS(LinkButton);
+ GDREGISTER_CLASS(Panel);
+ GDREGISTER_VIRTUAL_CLASS(Range);
OS::get_singleton()->yield(); //may take time to init
- ClassDB::register_class<TextureRect>();
- ClassDB::register_class<ColorRect>();
- ClassDB::register_class<NinePatchRect>();
- ClassDB::register_class<ReferenceRect>();
- ClassDB::register_class<AspectRatioContainer>();
- ClassDB::register_class<TabContainer>();
- ClassDB::register_class<Tabs>();
- ClassDB::register_virtual_class<Separator>();
- ClassDB::register_class<HSeparator>();
- ClassDB::register_class<VSeparator>();
- ClassDB::register_class<TextureButton>();
- ClassDB::register_class<Container>();
- ClassDB::register_virtual_class<BoxContainer>();
- ClassDB::register_class<HBoxContainer>();
- ClassDB::register_class<VBoxContainer>();
- ClassDB::register_class<GridContainer>();
- ClassDB::register_class<CenterContainer>();
- ClassDB::register_class<ScrollContainer>();
- ClassDB::register_class<PanelContainer>();
+ GDREGISTER_CLASS(TextureRect);
+ GDREGISTER_CLASS(ColorRect);
+ GDREGISTER_CLASS(NinePatchRect);
+ GDREGISTER_CLASS(ReferenceRect);
+ GDREGISTER_CLASS(AspectRatioContainer);
+ GDREGISTER_CLASS(TabContainer);
+ GDREGISTER_CLASS(Tabs);
+ GDREGISTER_VIRTUAL_CLASS(Separator);
+ GDREGISTER_CLASS(HSeparator);
+ GDREGISTER_CLASS(VSeparator);
+ GDREGISTER_CLASS(TextureButton);
+ GDREGISTER_CLASS(Container);
+ GDREGISTER_VIRTUAL_CLASS(BoxContainer);
+ GDREGISTER_CLASS(HBoxContainer);
+ GDREGISTER_CLASS(VBoxContainer);
+ GDREGISTER_CLASS(GridContainer);
+ GDREGISTER_CLASS(CenterContainer);
+ GDREGISTER_CLASS(ScrollContainer);
+ GDREGISTER_CLASS(PanelContainer);
OS::get_singleton()->yield(); //may take time to init
- ClassDB::register_class<TextureProgressBar>();
- ClassDB::register_class<ItemList>();
+ GDREGISTER_CLASS(TextureProgressBar);
+ GDREGISTER_CLASS(ItemList);
- ClassDB::register_class<LineEdit>();
- ClassDB::register_class<VideoPlayer>();
+ GDREGISTER_CLASS(LineEdit);
+ GDREGISTER_CLASS(VideoPlayer);
#ifndef ADVANCED_GUI_DISABLED
- ClassDB::register_class<FileDialog>();
-
- ClassDB::register_class<PopupMenu>();
- ClassDB::register_class<Tree>();
-
- ClassDB::register_class<TextEdit>();
- ClassDB::register_class<CodeEdit>();
- ClassDB::register_class<SyntaxHighlighter>();
- ClassDB::register_class<CodeHighlighter>();
-
- ClassDB::register_virtual_class<TreeItem>();
- ClassDB::register_class<OptionButton>();
- ClassDB::register_class<SpinBox>();
- ClassDB::register_class<ColorPicker>();
- ClassDB::register_class<ColorPickerButton>();
- ClassDB::register_class<RichTextLabel>();
- ClassDB::register_class<RichTextEffect>();
- ClassDB::register_class<CharFXTransform>();
-
- ClassDB::register_class<AcceptDialog>();
- ClassDB::register_class<ConfirmationDialog>();
-
- ClassDB::register_class<MarginContainer>();
- ClassDB::register_class<SubViewportContainer>();
- ClassDB::register_virtual_class<SplitContainer>();
- ClassDB::register_class<HSplitContainer>();
- ClassDB::register_class<VSplitContainer>();
- ClassDB::register_class<GraphNode>();
- ClassDB::register_class<GraphEdit>();
+ GDREGISTER_CLASS(FileDialog);
+
+ GDREGISTER_CLASS(PopupMenu);
+ GDREGISTER_CLASS(Tree);
+
+ GDREGISTER_CLASS(TextEdit);
+ GDREGISTER_CLASS(CodeEdit);
+ GDREGISTER_CLASS(SyntaxHighlighter);
+ GDREGISTER_CLASS(CodeHighlighter);
+
+ GDREGISTER_VIRTUAL_CLASS(TreeItem);
+ GDREGISTER_CLASS(OptionButton);
+ GDREGISTER_CLASS(SpinBox);
+ GDREGISTER_CLASS(ColorPicker);
+ GDREGISTER_CLASS(ColorPickerButton);
+ GDREGISTER_CLASS(RichTextLabel);
+ GDREGISTER_CLASS(RichTextEffect);
+ GDREGISTER_CLASS(CharFXTransform);
+
+ GDREGISTER_CLASS(AcceptDialog);
+ GDREGISTER_CLASS(ConfirmationDialog);
+
+ GDREGISTER_CLASS(MarginContainer);
+ GDREGISTER_CLASS(SubViewportContainer);
+ GDREGISTER_VIRTUAL_CLASS(SplitContainer);
+ GDREGISTER_CLASS(HSplitContainer);
+ GDREGISTER_CLASS(VSplitContainer);
+ GDREGISTER_CLASS(GraphNode);
+ GDREGISTER_CLASS(GraphEdit);
OS::get_singleton()->yield(); //may take time to init
@@ -406,450 +406,451 @@ void register_scene_types() {
/* REGISTER ANIMATION */
- ClassDB::register_class<AnimationPlayer>();
- ClassDB::register_class<Tween>();
- ClassDB::register_virtual_class<Tweener>();
- ClassDB::register_class<PropertyTweener>();
- ClassDB::register_class<IntervalTweener>();
- ClassDB::register_class<CallbackTweener>();
- ClassDB::register_class<MethodTweener>();
-
- ClassDB::register_class<AnimationTree>();
- ClassDB::register_class<AnimationNode>();
- ClassDB::register_class<AnimationRootNode>();
- ClassDB::register_class<AnimationNodeBlendTree>();
- ClassDB::register_class<AnimationNodeBlendSpace1D>();
- ClassDB::register_class<AnimationNodeBlendSpace2D>();
- ClassDB::register_class<AnimationNodeStateMachine>();
- ClassDB::register_class<AnimationNodeStateMachinePlayback>();
-
- ClassDB::register_class<AnimationNodeStateMachineTransition>();
- ClassDB::register_class<AnimationNodeOutput>();
- ClassDB::register_class<AnimationNodeOneShot>();
- ClassDB::register_class<AnimationNodeAnimation>();
- ClassDB::register_class<AnimationNodeAdd2>();
- ClassDB::register_class<AnimationNodeAdd3>();
- ClassDB::register_class<AnimationNodeBlend2>();
- ClassDB::register_class<AnimationNodeBlend3>();
- ClassDB::register_class<AnimationNodeTimeScale>();
- ClassDB::register_class<AnimationNodeTimeSeek>();
- ClassDB::register_class<AnimationNodeTransition>();
-
- ClassDB::register_class<ShaderGlobalsOverride>(); //can be used in any shader
+ GDREGISTER_CLASS(AnimationPlayer);
+ GDREGISTER_CLASS(Tween);
+ GDREGISTER_VIRTUAL_CLASS(Tweener);
+ GDREGISTER_CLASS(PropertyTweener);
+ GDREGISTER_CLASS(IntervalTweener);
+ GDREGISTER_CLASS(CallbackTweener);
+ GDREGISTER_CLASS(MethodTweener);
+
+ GDREGISTER_CLASS(AnimationTree);
+ GDREGISTER_CLASS(AnimationNode);
+ GDREGISTER_CLASS(AnimationRootNode);
+ GDREGISTER_CLASS(AnimationNodeBlendTree);
+ GDREGISTER_CLASS(AnimationNodeBlendSpace1D);
+ GDREGISTER_CLASS(AnimationNodeBlendSpace2D);
+ GDREGISTER_CLASS(AnimationNodeStateMachine);
+ GDREGISTER_CLASS(AnimationNodeStateMachinePlayback);
+
+ GDREGISTER_CLASS(AnimationNodeStateMachineTransition);
+ GDREGISTER_CLASS(AnimationNodeOutput);
+ GDREGISTER_CLASS(AnimationNodeOneShot);
+ GDREGISTER_CLASS(AnimationNodeAnimation);
+ GDREGISTER_CLASS(AnimationNodeAdd2);
+ GDREGISTER_CLASS(AnimationNodeAdd3);
+ GDREGISTER_CLASS(AnimationNodeBlend2);
+ GDREGISTER_CLASS(AnimationNodeBlend3);
+ GDREGISTER_CLASS(AnimationNodeTimeScale);
+ GDREGISTER_CLASS(AnimationNodeTimeSeek);
+ GDREGISTER_CLASS(AnimationNodeTransition);
+
+ GDREGISTER_CLASS(ShaderGlobalsOverride); //can be used in any shader
OS::get_singleton()->yield(); //may take time to init
/* REGISTER 3D */
#ifndef _3D_DISABLED
- ClassDB::register_class<Node3D>();
- ClassDB::register_virtual_class<Node3DGizmo>();
- ClassDB::register_class<Skin>();
- ClassDB::register_virtual_class<SkinReference>();
- ClassDB::register_class<Skeleton3D>();
- ClassDB::register_virtual_class<VisualInstance3D>();
- ClassDB::register_virtual_class<GeometryInstance3D>();
- ClassDB::register_class<Camera3D>();
- ClassDB::register_class<ClippedCamera3D>();
- ClassDB::register_class<Listener3D>();
- ClassDB::register_class<XRCamera3D>();
- ClassDB::register_class<XRController3D>();
- ClassDB::register_class<XRAnchor3D>();
- ClassDB::register_class<XROrigin3D>();
- ClassDB::register_class<MeshInstance3D>();
- ClassDB::register_class<OccluderInstance3D>();
- ClassDB::register_class<Occluder3D>();
- ClassDB::register_virtual_class<SpriteBase3D>();
- ClassDB::register_class<Sprite3D>();
- ClassDB::register_class<AnimatedSprite3D>();
- ClassDB::register_virtual_class<Light3D>();
- ClassDB::register_class<DirectionalLight3D>();
- ClassDB::register_class<OmniLight3D>();
- ClassDB::register_class<SpotLight3D>();
- ClassDB::register_class<ReflectionProbe>();
- ClassDB::register_class<Decal>();
- ClassDB::register_class<VoxelGI>();
- ClassDB::register_class<VoxelGIData>();
- ClassDB::register_class<LightmapGI>();
- ClassDB::register_class<LightmapGIData>();
- ClassDB::register_class<LightmapProbe>();
- ClassDB::register_virtual_class<Lightmapper>();
- ClassDB::register_class<GPUParticles3D>();
- ClassDB::register_virtual_class<GPUParticlesCollision3D>();
- ClassDB::register_class<GPUParticlesCollisionBox>();
- ClassDB::register_class<GPUParticlesCollisionSphere>();
- ClassDB::register_class<GPUParticlesCollisionSDF>();
- ClassDB::register_class<GPUParticlesCollisionHeightField>();
- ClassDB::register_virtual_class<GPUParticlesAttractor3D>();
- ClassDB::register_class<GPUParticlesAttractorBox>();
- ClassDB::register_class<GPUParticlesAttractorSphere>();
- ClassDB::register_class<GPUParticlesAttractorVectorField>();
- ClassDB::register_class<CPUParticles3D>();
- ClassDB::register_class<Position3D>();
-
- ClassDB::register_class<RootMotionView>();
+ GDREGISTER_CLASS(Node3D);
+ GDREGISTER_VIRTUAL_CLASS(Node3DGizmo);
+ GDREGISTER_CLASS(Skin);
+ GDREGISTER_VIRTUAL_CLASS(SkinReference);
+ GDREGISTER_CLASS(Skeleton3D);
+ GDREGISTER_VIRTUAL_CLASS(VisualInstance3D);
+ GDREGISTER_VIRTUAL_CLASS(GeometryInstance3D);
+ GDREGISTER_CLASS(Camera3D);
+ GDREGISTER_CLASS(ClippedCamera3D);
+ GDREGISTER_CLASS(Listener3D);
+ GDREGISTER_CLASS(XRCamera3D);
+ GDREGISTER_CLASS(XRController3D);
+ GDREGISTER_CLASS(XRAnchor3D);
+ GDREGISTER_CLASS(XROrigin3D);
+ GDREGISTER_CLASS(MeshInstance3D);
+ GDREGISTER_CLASS(OccluderInstance3D);
+ GDREGISTER_CLASS(Occluder3D);
+ GDREGISTER_VIRTUAL_CLASS(SpriteBase3D);
+ GDREGISTER_CLASS(Sprite3D);
+ GDREGISTER_CLASS(AnimatedSprite3D);
+ GDREGISTER_VIRTUAL_CLASS(Light3D);
+ GDREGISTER_CLASS(DirectionalLight3D);
+ GDREGISTER_CLASS(OmniLight3D);
+ GDREGISTER_CLASS(SpotLight3D);
+ GDREGISTER_CLASS(ReflectionProbe);
+ GDREGISTER_CLASS(Decal);
+ GDREGISTER_CLASS(VoxelGI);
+ GDREGISTER_CLASS(VoxelGIData);
+ GDREGISTER_CLASS(LightmapGI);
+ GDREGISTER_CLASS(LightmapGIData);
+ GDREGISTER_CLASS(LightmapProbe);
+ GDREGISTER_VIRTUAL_CLASS(Lightmapper);
+ GDREGISTER_CLASS(GPUParticles3D);
+ GDREGISTER_VIRTUAL_CLASS(GPUParticlesCollision3D);
+ GDREGISTER_CLASS(GPUParticlesCollisionBox);
+ GDREGISTER_CLASS(GPUParticlesCollisionSphere);
+ GDREGISTER_CLASS(GPUParticlesCollisionSDF);
+ GDREGISTER_CLASS(GPUParticlesCollisionHeightField);
+ GDREGISTER_VIRTUAL_CLASS(GPUParticlesAttractor3D);
+ GDREGISTER_CLASS(GPUParticlesAttractorBox);
+ GDREGISTER_CLASS(GPUParticlesAttractorSphere);
+ GDREGISTER_CLASS(GPUParticlesAttractorVectorField);
+ GDREGISTER_CLASS(CPUParticles3D);
+ GDREGISTER_CLASS(Position3D);
+
+ GDREGISTER_CLASS(RootMotionView);
ClassDB::set_class_enabled("RootMotionView", false); //disabled by default, enabled by editor
OS::get_singleton()->yield(); //may take time to init
- ClassDB::register_virtual_class<CollisionObject3D>();
- ClassDB::register_virtual_class<PhysicsBody3D>();
- ClassDB::register_class<StaticBody3D>();
- ClassDB::register_class<RigidBody3D>();
- ClassDB::register_class<KinematicCollision3D>();
- ClassDB::register_class<CharacterBody3D>();
- ClassDB::register_class<SpringArm3D>();
-
- ClassDB::register_class<PhysicalBone3D>();
- ClassDB::register_class<SoftBody3D>();
-
- ClassDB::register_class<SkeletonIK3D>();
- ClassDB::register_class<BoneAttachment3D>();
-
- ClassDB::register_class<VehicleBody3D>();
- ClassDB::register_class<VehicleWheel3D>();
- ClassDB::register_class<Area3D>();
- ClassDB::register_class<ProximityGroup3D>();
- ClassDB::register_class<CollisionShape3D>();
- ClassDB::register_class<CollisionPolygon3D>();
- ClassDB::register_class<RayCast3D>();
- ClassDB::register_class<MultiMeshInstance3D>();
-
- ClassDB::register_class<Curve3D>();
- ClassDB::register_class<Path3D>();
- ClassDB::register_class<PathFollow3D>();
- ClassDB::register_class<VisibleOnScreenNotifier3D>();
- ClassDB::register_class<VisibleOnScreenEnabler3D>();
- ClassDB::register_class<WorldEnvironment>();
- ClassDB::register_class<RemoteTransform3D>();
-
- ClassDB::register_virtual_class<Joint3D>();
- ClassDB::register_class<PinJoint3D>();
- ClassDB::register_class<HingeJoint3D>();
- ClassDB::register_class<SliderJoint3D>();
- ClassDB::register_class<ConeTwistJoint3D>();
- ClassDB::register_class<Generic6DOFJoint3D>();
-
- ClassDB::register_class<NavigationRegion3D>();
- ClassDB::register_class<NavigationAgent3D>();
- ClassDB::register_class<NavigationObstacle3D>();
+ GDREGISTER_VIRTUAL_CLASS(CollisionObject3D);
+ GDREGISTER_VIRTUAL_CLASS(PhysicsBody3D);
+ GDREGISTER_CLASS(StaticBody3D);
+ GDREGISTER_CLASS(RigidBody3D);
+ GDREGISTER_CLASS(KinematicCollision3D);
+ GDREGISTER_CLASS(CharacterBody3D);
+ GDREGISTER_CLASS(SpringArm3D);
+
+ GDREGISTER_CLASS(PhysicalBone3D);
+ GDREGISTER_CLASS(SoftBody3D);
+
+ GDREGISTER_CLASS(SkeletonIK3D);
+ GDREGISTER_CLASS(BoneAttachment3D);
+
+ GDREGISTER_CLASS(VehicleBody3D);
+ GDREGISTER_CLASS(VehicleWheel3D);
+ GDREGISTER_CLASS(Area3D);
+ GDREGISTER_CLASS(ProximityGroup3D);
+ GDREGISTER_CLASS(CollisionShape3D);
+ GDREGISTER_CLASS(CollisionPolygon3D);
+ GDREGISTER_CLASS(RayCast3D);
+ GDREGISTER_CLASS(MultiMeshInstance3D);
+
+ GDREGISTER_CLASS(Curve3D);
+ GDREGISTER_CLASS(Path3D);
+ GDREGISTER_CLASS(PathFollow3D);
+ GDREGISTER_CLASS(VisibleOnScreenNotifier3D);
+ GDREGISTER_CLASS(VisibleOnScreenEnabler3D);
+ GDREGISTER_CLASS(WorldEnvironment);
+ GDREGISTER_CLASS(RemoteTransform3D);
+
+ GDREGISTER_VIRTUAL_CLASS(Joint3D);
+ GDREGISTER_CLASS(PinJoint3D);
+ GDREGISTER_CLASS(HingeJoint3D);
+ GDREGISTER_CLASS(SliderJoint3D);
+ GDREGISTER_CLASS(ConeTwistJoint3D);
+ GDREGISTER_CLASS(Generic6DOFJoint3D);
+
+ GDREGISTER_CLASS(NavigationRegion3D);
+ GDREGISTER_CLASS(NavigationAgent3D);
+ GDREGISTER_CLASS(NavigationObstacle3D);
OS::get_singleton()->yield(); //may take time to init
#endif
/* REGISTER SHADER */
- ClassDB::register_class<Shader>();
- ClassDB::register_class<VisualShader>();
- ClassDB::register_virtual_class<VisualShaderNode>();
- ClassDB::register_class<VisualShaderNodeCustom>();
- ClassDB::register_class<VisualShaderNodeInput>();
- ClassDB::register_virtual_class<VisualShaderNodeOutput>();
- ClassDB::register_virtual_class<VisualShaderNodeResizableBase>();
- ClassDB::register_virtual_class<VisualShaderNodeGroupBase>();
- ClassDB::register_virtual_class<VisualShaderNodeConstant>();
- ClassDB::register_class<VisualShaderNodeComment>();
- ClassDB::register_class<VisualShaderNodeFloatConstant>();
- ClassDB::register_class<VisualShaderNodeIntConstant>();
- ClassDB::register_class<VisualShaderNodeBooleanConstant>();
- ClassDB::register_class<VisualShaderNodeColorConstant>();
- ClassDB::register_class<VisualShaderNodeVec3Constant>();
- ClassDB::register_class<VisualShaderNodeTransformConstant>();
- ClassDB::register_class<VisualShaderNodeFloatOp>();
- ClassDB::register_class<VisualShaderNodeIntOp>();
- ClassDB::register_class<VisualShaderNodeVectorOp>();
- ClassDB::register_class<VisualShaderNodeColorOp>();
- ClassDB::register_class<VisualShaderNodeTransformMult>();
- ClassDB::register_class<VisualShaderNodeTransformVecMult>();
- ClassDB::register_class<VisualShaderNodeFloatFunc>();
- ClassDB::register_class<VisualShaderNodeIntFunc>();
- ClassDB::register_class<VisualShaderNodeVectorFunc>();
- ClassDB::register_class<VisualShaderNodeColorFunc>();
- ClassDB::register_class<VisualShaderNodeTransformFunc>();
- ClassDB::register_class<VisualShaderNodeUVFunc>();
- ClassDB::register_class<VisualShaderNodeDotProduct>();
- ClassDB::register_class<VisualShaderNodeVectorLen>();
- ClassDB::register_class<VisualShaderNodeDeterminant>();
- ClassDB::register_class<VisualShaderNodeScalarDerivativeFunc>();
- ClassDB::register_class<VisualShaderNodeVectorDerivativeFunc>();
- ClassDB::register_class<VisualShaderNodeClamp>();
- ClassDB::register_class<VisualShaderNodeFaceForward>();
- ClassDB::register_class<VisualShaderNodeOuterProduct>();
- ClassDB::register_class<VisualShaderNodeSmoothStep>();
- ClassDB::register_class<VisualShaderNodeStep>();
- ClassDB::register_class<VisualShaderNodeVectorDistance>();
- ClassDB::register_class<VisualShaderNodeVectorRefract>();
- ClassDB::register_class<VisualShaderNodeMix>();
- ClassDB::register_class<VisualShaderNodeVectorCompose>();
- ClassDB::register_class<VisualShaderNodeTransformCompose>();
- ClassDB::register_class<VisualShaderNodeVectorDecompose>();
- ClassDB::register_class<VisualShaderNodeTransformDecompose>();
- ClassDB::register_class<VisualShaderNodeTexture>();
- ClassDB::register_class<VisualShaderNodeCurveTexture>();
- ClassDB::register_virtual_class<VisualShaderNodeSample3D>();
- ClassDB::register_class<VisualShaderNodeTexture2DArray>();
- ClassDB::register_class<VisualShaderNodeTexture3D>();
- ClassDB::register_class<VisualShaderNodeCubemap>();
- ClassDB::register_virtual_class<VisualShaderNodeUniform>();
- ClassDB::register_class<VisualShaderNodeUniformRef>();
- ClassDB::register_class<VisualShaderNodeFloatUniform>();
- ClassDB::register_class<VisualShaderNodeIntUniform>();
- ClassDB::register_class<VisualShaderNodeBooleanUniform>();
- ClassDB::register_class<VisualShaderNodeColorUniform>();
- ClassDB::register_class<VisualShaderNodeVec3Uniform>();
- ClassDB::register_class<VisualShaderNodeTransformUniform>();
- ClassDB::register_class<VisualShaderNodeTextureUniform>();
- ClassDB::register_class<VisualShaderNodeTextureUniformTriplanar>();
- ClassDB::register_class<VisualShaderNodeTexture2DArrayUniform>();
- ClassDB::register_class<VisualShaderNodeTexture3DUniform>();
- ClassDB::register_class<VisualShaderNodeCubemapUniform>();
- ClassDB::register_class<VisualShaderNodeIf>();
- ClassDB::register_class<VisualShaderNodeSwitch>();
- ClassDB::register_class<VisualShaderNodeFresnel>();
- ClassDB::register_class<VisualShaderNodeExpression>();
- ClassDB::register_class<VisualShaderNodeGlobalExpression>();
- ClassDB::register_class<VisualShaderNodeIs>();
- ClassDB::register_class<VisualShaderNodeCompare>();
- ClassDB::register_class<VisualShaderNodeMultiplyAdd>();
- ClassDB::register_class<VisualShaderNodeBillboard>();
-
- ClassDB::register_class<VisualShaderNodeSDFToScreenUV>();
- ClassDB::register_class<VisualShaderNodeScreenUVToSDF>();
- ClassDB::register_class<VisualShaderNodeTextureSDF>();
- ClassDB::register_class<VisualShaderNodeTextureSDFNormal>();
- ClassDB::register_class<VisualShaderNodeSDFRaymarch>();
-
- ClassDB::register_class<VisualShaderNodeParticleOutput>();
- ClassDB::register_virtual_class<VisualShaderNodeParticleEmitter>();
- ClassDB::register_class<VisualShaderNodeParticleSphereEmitter>();
- ClassDB::register_class<VisualShaderNodeParticleBoxEmitter>();
- ClassDB::register_class<VisualShaderNodeParticleRingEmitter>();
- ClassDB::register_class<VisualShaderNodeParticleMultiplyByAxisAngle>();
- ClassDB::register_class<VisualShaderNodeParticleConeVelocity>();
- ClassDB::register_class<VisualShaderNodeParticleRandomness>();
- ClassDB::register_class<VisualShaderNodeParticleAccelerator>();
- ClassDB::register_class<VisualShaderNodeParticleEmit>();
-
- ClassDB::register_class<ShaderMaterial>();
- ClassDB::register_virtual_class<CanvasItem>();
- ClassDB::register_class<CanvasTexture>();
- ClassDB::register_class<CanvasItemMaterial>();
+ GDREGISTER_CLASS(Shader);
+ GDREGISTER_CLASS(VisualShader);
+ GDREGISTER_VIRTUAL_CLASS(VisualShaderNode);
+ GDREGISTER_CLASS(VisualShaderNodeCustom);
+ GDREGISTER_CLASS(VisualShaderNodeInput);
+ GDREGISTER_VIRTUAL_CLASS(VisualShaderNodeOutput);
+ GDREGISTER_VIRTUAL_CLASS(VisualShaderNodeResizableBase);
+ GDREGISTER_VIRTUAL_CLASS(VisualShaderNodeGroupBase);
+ GDREGISTER_VIRTUAL_CLASS(VisualShaderNodeConstant);
+ GDREGISTER_CLASS(VisualShaderNodeComment);
+ GDREGISTER_CLASS(VisualShaderNodeFloatConstant);
+ GDREGISTER_CLASS(VisualShaderNodeIntConstant);
+ GDREGISTER_CLASS(VisualShaderNodeBooleanConstant);
+ GDREGISTER_CLASS(VisualShaderNodeColorConstant);
+ GDREGISTER_CLASS(VisualShaderNodeVec3Constant);
+ GDREGISTER_CLASS(VisualShaderNodeTransformConstant);
+ GDREGISTER_CLASS(VisualShaderNodeFloatOp);
+ GDREGISTER_CLASS(VisualShaderNodeIntOp);
+ GDREGISTER_CLASS(VisualShaderNodeVectorOp);
+ GDREGISTER_CLASS(VisualShaderNodeColorOp);
+ GDREGISTER_CLASS(VisualShaderNodeTransformMult);
+ GDREGISTER_CLASS(VisualShaderNodeTransformVecMult);
+ GDREGISTER_CLASS(VisualShaderNodeFloatFunc);
+ GDREGISTER_CLASS(VisualShaderNodeIntFunc);
+ GDREGISTER_CLASS(VisualShaderNodeVectorFunc);
+ GDREGISTER_CLASS(VisualShaderNodeColorFunc);
+ GDREGISTER_CLASS(VisualShaderNodeTransformFunc);
+ GDREGISTER_CLASS(VisualShaderNodeUVFunc);
+ GDREGISTER_CLASS(VisualShaderNodeDotProduct);
+ GDREGISTER_CLASS(VisualShaderNodeVectorLen);
+ GDREGISTER_CLASS(VisualShaderNodeDeterminant);
+ GDREGISTER_CLASS(VisualShaderNodeScalarDerivativeFunc);
+ GDREGISTER_CLASS(VisualShaderNodeVectorDerivativeFunc);
+ GDREGISTER_CLASS(VisualShaderNodeClamp);
+ GDREGISTER_CLASS(VisualShaderNodeFaceForward);
+ GDREGISTER_CLASS(VisualShaderNodeOuterProduct);
+ GDREGISTER_CLASS(VisualShaderNodeSmoothStep);
+ GDREGISTER_CLASS(VisualShaderNodeStep);
+ GDREGISTER_CLASS(VisualShaderNodeVectorDistance);
+ GDREGISTER_CLASS(VisualShaderNodeVectorRefract);
+ GDREGISTER_CLASS(VisualShaderNodeMix);
+ GDREGISTER_CLASS(VisualShaderNodeVectorCompose);
+ GDREGISTER_CLASS(VisualShaderNodeTransformCompose);
+ GDREGISTER_CLASS(VisualShaderNodeVectorDecompose);
+ GDREGISTER_CLASS(VisualShaderNodeTransformDecompose);
+ GDREGISTER_CLASS(VisualShaderNodeTexture);
+ GDREGISTER_CLASS(VisualShaderNodeCurveTexture);
+ GDREGISTER_CLASS(VisualShaderNodeCurve3Texture);
+ GDREGISTER_VIRTUAL_CLASS(VisualShaderNodeSample3D);
+ GDREGISTER_CLASS(VisualShaderNodeTexture2DArray);
+ GDREGISTER_CLASS(VisualShaderNodeTexture3D);
+ GDREGISTER_CLASS(VisualShaderNodeCubemap);
+ GDREGISTER_VIRTUAL_CLASS(VisualShaderNodeUniform);
+ GDREGISTER_CLASS(VisualShaderNodeUniformRef);
+ GDREGISTER_CLASS(VisualShaderNodeFloatUniform);
+ GDREGISTER_CLASS(VisualShaderNodeIntUniform);
+ GDREGISTER_CLASS(VisualShaderNodeBooleanUniform);
+ GDREGISTER_CLASS(VisualShaderNodeColorUniform);
+ GDREGISTER_CLASS(VisualShaderNodeVec3Uniform);
+ GDREGISTER_CLASS(VisualShaderNodeTransformUniform);
+ GDREGISTER_CLASS(VisualShaderNodeTextureUniform);
+ GDREGISTER_CLASS(VisualShaderNodeTextureUniformTriplanar);
+ GDREGISTER_CLASS(VisualShaderNodeTexture2DArrayUniform);
+ GDREGISTER_CLASS(VisualShaderNodeTexture3DUniform);
+ GDREGISTER_CLASS(VisualShaderNodeCubemapUniform);
+ GDREGISTER_CLASS(VisualShaderNodeIf);
+ GDREGISTER_CLASS(VisualShaderNodeSwitch);
+ GDREGISTER_CLASS(VisualShaderNodeFresnel);
+ GDREGISTER_CLASS(VisualShaderNodeExpression);
+ GDREGISTER_CLASS(VisualShaderNodeGlobalExpression);
+ GDREGISTER_CLASS(VisualShaderNodeIs);
+ GDREGISTER_CLASS(VisualShaderNodeCompare);
+ GDREGISTER_CLASS(VisualShaderNodeMultiplyAdd);
+ GDREGISTER_CLASS(VisualShaderNodeBillboard);
+
+ GDREGISTER_CLASS(VisualShaderNodeSDFToScreenUV);
+ GDREGISTER_CLASS(VisualShaderNodeScreenUVToSDF);
+ GDREGISTER_CLASS(VisualShaderNodeTextureSDF);
+ GDREGISTER_CLASS(VisualShaderNodeTextureSDFNormal);
+ GDREGISTER_CLASS(VisualShaderNodeSDFRaymarch);
+
+ GDREGISTER_CLASS(VisualShaderNodeParticleOutput);
+ GDREGISTER_VIRTUAL_CLASS(VisualShaderNodeParticleEmitter);
+ GDREGISTER_CLASS(VisualShaderNodeParticleSphereEmitter);
+ GDREGISTER_CLASS(VisualShaderNodeParticleBoxEmitter);
+ GDREGISTER_CLASS(VisualShaderNodeParticleRingEmitter);
+ GDREGISTER_CLASS(VisualShaderNodeParticleMultiplyByAxisAngle);
+ GDREGISTER_CLASS(VisualShaderNodeParticleConeVelocity);
+ GDREGISTER_CLASS(VisualShaderNodeParticleRandomness);
+ GDREGISTER_CLASS(VisualShaderNodeParticleAccelerator);
+ GDREGISTER_CLASS(VisualShaderNodeParticleEmit);
+
+ GDREGISTER_CLASS(ShaderMaterial);
+ GDREGISTER_VIRTUAL_CLASS(CanvasItem);
+ GDREGISTER_CLASS(CanvasTexture);
+ GDREGISTER_CLASS(CanvasItemMaterial);
SceneTree::add_idle_callback(CanvasItemMaterial::flush_changes);
CanvasItemMaterial::init_shaders();
/* REGISTER 2D */
- ClassDB::register_class<Node2D>();
- ClassDB::register_class<CanvasGroup>();
- ClassDB::register_class<CPUParticles2D>();
- ClassDB::register_class<GPUParticles2D>();
- ClassDB::register_class<Sprite2D>();
- ClassDB::register_class<SpriteFrames>();
- ClassDB::register_class<AnimatedSprite2D>();
- ClassDB::register_class<Position2D>();
- ClassDB::register_class<Line2D>();
- ClassDB::register_class<MeshInstance2D>();
- ClassDB::register_class<MultiMeshInstance2D>();
- ClassDB::register_virtual_class<CollisionObject2D>();
- ClassDB::register_virtual_class<PhysicsBody2D>();
- ClassDB::register_class<StaticBody2D>();
- ClassDB::register_class<RigidBody2D>();
- ClassDB::register_class<CharacterBody2D>();
- ClassDB::register_class<KinematicCollision2D>();
- ClassDB::register_class<Area2D>();
- ClassDB::register_class<CollisionShape2D>();
- ClassDB::register_class<CollisionPolygon2D>();
- ClassDB::register_class<RayCast2D>();
- ClassDB::register_class<VisibleOnScreenNotifier2D>();
- ClassDB::register_class<VisibleOnScreenEnabler2D>();
- ClassDB::register_class<Polygon2D>();
- ClassDB::register_class<Skeleton2D>();
- ClassDB::register_class<Bone2D>();
- ClassDB::register_virtual_class<Light2D>();
- ClassDB::register_class<PointLight2D>();
- ClassDB::register_class<DirectionalLight2D>();
- ClassDB::register_class<LightOccluder2D>();
- ClassDB::register_class<OccluderPolygon2D>();
- ClassDB::register_class<BackBufferCopy>();
+ GDREGISTER_CLASS(Node2D);
+ GDREGISTER_CLASS(CanvasGroup);
+ GDREGISTER_CLASS(CPUParticles2D);
+ GDREGISTER_CLASS(GPUParticles2D);
+ GDREGISTER_CLASS(Sprite2D);
+ GDREGISTER_CLASS(SpriteFrames);
+ GDREGISTER_CLASS(AnimatedSprite2D);
+ GDREGISTER_CLASS(Position2D);
+ GDREGISTER_CLASS(Line2D);
+ GDREGISTER_CLASS(MeshInstance2D);
+ GDREGISTER_CLASS(MultiMeshInstance2D);
+ GDREGISTER_VIRTUAL_CLASS(CollisionObject2D);
+ GDREGISTER_VIRTUAL_CLASS(PhysicsBody2D);
+ GDREGISTER_CLASS(StaticBody2D);
+ GDREGISTER_CLASS(RigidBody2D);
+ GDREGISTER_CLASS(CharacterBody2D);
+ GDREGISTER_CLASS(KinematicCollision2D);
+ GDREGISTER_CLASS(Area2D);
+ GDREGISTER_CLASS(CollisionShape2D);
+ GDREGISTER_CLASS(CollisionPolygon2D);
+ GDREGISTER_CLASS(RayCast2D);
+ GDREGISTER_CLASS(VisibleOnScreenNotifier2D);
+ GDREGISTER_CLASS(VisibleOnScreenEnabler2D);
+ GDREGISTER_CLASS(Polygon2D);
+ GDREGISTER_CLASS(Skeleton2D);
+ GDREGISTER_CLASS(Bone2D);
+ GDREGISTER_VIRTUAL_CLASS(Light2D);
+ GDREGISTER_CLASS(PointLight2D);
+ GDREGISTER_CLASS(DirectionalLight2D);
+ GDREGISTER_CLASS(LightOccluder2D);
+ GDREGISTER_CLASS(OccluderPolygon2D);
+ GDREGISTER_CLASS(BackBufferCopy);
OS::get_singleton()->yield(); //may take time to init
- ClassDB::register_class<Camera2D>();
- ClassDB::register_virtual_class<Joint2D>();
- ClassDB::register_class<PinJoint2D>();
- ClassDB::register_class<GrooveJoint2D>();
- ClassDB::register_class<DampedSpringJoint2D>();
- ClassDB::register_class<TileSet>();
- ClassDB::register_virtual_class<TileSetSource>();
- ClassDB::register_class<TileSetAtlasSource>();
- ClassDB::register_class<TileSetScenesCollectionSource>();
- ClassDB::register_class<TileData>();
- ClassDB::register_class<TileMap>();
- ClassDB::register_class<ParallaxBackground>();
- ClassDB::register_class<ParallaxLayer>();
- ClassDB::register_class<TouchScreenButton>();
- ClassDB::register_class<RemoteTransform2D>();
-
- ClassDB::register_class<SkeletonModificationStack2D>();
- ClassDB::register_class<SkeletonModification2D>();
- ClassDB::register_class<SkeletonModification2DLookAt>();
- ClassDB::register_class<SkeletonModification2DCCDIK>();
- ClassDB::register_class<SkeletonModification2DFABRIK>();
- ClassDB::register_class<SkeletonModification2DJiggle>();
- ClassDB::register_class<SkeletonModification2DTwoBoneIK>();
- ClassDB::register_class<SkeletonModification2DStackHolder>();
-
- ClassDB::register_class<PhysicalBone2D>();
- ClassDB::register_class<SkeletonModification2DPhysicalBones>();
+ GDREGISTER_CLASS(Camera2D);
+ GDREGISTER_VIRTUAL_CLASS(Joint2D);
+ GDREGISTER_CLASS(PinJoint2D);
+ GDREGISTER_CLASS(GrooveJoint2D);
+ GDREGISTER_CLASS(DampedSpringJoint2D);
+ GDREGISTER_CLASS(TileSet);
+ GDREGISTER_VIRTUAL_CLASS(TileSetSource);
+ GDREGISTER_CLASS(TileSetAtlasSource);
+ GDREGISTER_CLASS(TileSetScenesCollectionSource);
+ GDREGISTER_CLASS(TileData);
+ GDREGISTER_CLASS(TileMap);
+ GDREGISTER_CLASS(ParallaxBackground);
+ GDREGISTER_CLASS(ParallaxLayer);
+ GDREGISTER_CLASS(TouchScreenButton);
+ GDREGISTER_CLASS(RemoteTransform2D);
+
+ GDREGISTER_CLASS(SkeletonModificationStack2D);
+ GDREGISTER_CLASS(SkeletonModification2D);
+ GDREGISTER_CLASS(SkeletonModification2DLookAt);
+ GDREGISTER_CLASS(SkeletonModification2DCCDIK);
+ GDREGISTER_CLASS(SkeletonModification2DFABRIK);
+ GDREGISTER_CLASS(SkeletonModification2DJiggle);
+ GDREGISTER_CLASS(SkeletonModification2DTwoBoneIK);
+ GDREGISTER_CLASS(SkeletonModification2DStackHolder);
+
+ GDREGISTER_CLASS(PhysicalBone2D);
+ GDREGISTER_CLASS(SkeletonModification2DPhysicalBones);
OS::get_singleton()->yield(); //may take time to init
/* REGISTER RESOURCES */
- ClassDB::register_virtual_class<Shader>();
- ClassDB::register_class<ParticlesMaterial>();
+ GDREGISTER_VIRTUAL_CLASS(Shader);
+ GDREGISTER_CLASS(ParticlesMaterial);
SceneTree::add_idle_callback(ParticlesMaterial::flush_changes);
ParticlesMaterial::init_shaders();
- ClassDB::register_class<ProceduralSkyMaterial>();
- ClassDB::register_class<PanoramaSkyMaterial>();
- ClassDB::register_class<PhysicalSkyMaterial>();
+ GDREGISTER_CLASS(ProceduralSkyMaterial);
+ GDREGISTER_CLASS(PanoramaSkyMaterial);
+ GDREGISTER_CLASS(PhysicalSkyMaterial);
- ClassDB::register_virtual_class<Mesh>();
- ClassDB::register_class<ArrayMesh>();
- ClassDB::register_class<ImmediateMesh>();
- ClassDB::register_class<MultiMesh>();
- ClassDB::register_class<SurfaceTool>();
- ClassDB::register_class<MeshDataTool>();
+ GDREGISTER_VIRTUAL_CLASS(Mesh);
+ GDREGISTER_CLASS(ArrayMesh);
+ GDREGISTER_CLASS(ImmediateMesh);
+ GDREGISTER_CLASS(MultiMesh);
+ GDREGISTER_CLASS(SurfaceTool);
+ GDREGISTER_CLASS(MeshDataTool);
#ifndef _3D_DISABLED
- ClassDB::register_virtual_class<PrimitiveMesh>();
- ClassDB::register_class<BoxMesh>();
- ClassDB::register_class<CapsuleMesh>();
- ClassDB::register_class<CylinderMesh>();
- ClassDB::register_class<PlaneMesh>();
- ClassDB::register_class<PrismMesh>();
- ClassDB::register_class<QuadMesh>();
- ClassDB::register_class<SphereMesh>();
- ClassDB::register_class<TubeTrailMesh>();
- ClassDB::register_class<RibbonTrailMesh>();
- ClassDB::register_class<PointMesh>();
- ClassDB::register_virtual_class<Material>();
- ClassDB::register_virtual_class<BaseMaterial3D>();
- ClassDB::register_class<StandardMaterial3D>();
- ClassDB::register_class<ORMMaterial3D>();
+ GDREGISTER_VIRTUAL_CLASS(PrimitiveMesh);
+ GDREGISTER_CLASS(BoxMesh);
+ GDREGISTER_CLASS(CapsuleMesh);
+ GDREGISTER_CLASS(CylinderMesh);
+ GDREGISTER_CLASS(PlaneMesh);
+ GDREGISTER_CLASS(PrismMesh);
+ GDREGISTER_CLASS(QuadMesh);
+ GDREGISTER_CLASS(SphereMesh);
+ GDREGISTER_CLASS(TubeTrailMesh);
+ GDREGISTER_CLASS(RibbonTrailMesh);
+ GDREGISTER_CLASS(PointMesh);
+ GDREGISTER_VIRTUAL_CLASS(Material);
+ GDREGISTER_VIRTUAL_CLASS(BaseMaterial3D);
+ GDREGISTER_CLASS(StandardMaterial3D);
+ GDREGISTER_CLASS(ORMMaterial3D);
SceneTree::add_idle_callback(BaseMaterial3D::flush_changes);
BaseMaterial3D::init_shaders();
- ClassDB::register_class<MeshLibrary>();
+ GDREGISTER_CLASS(MeshLibrary);
OS::get_singleton()->yield(); //may take time to init
- ClassDB::register_virtual_class<Shape3D>();
- ClassDB::register_class<RayShape3D>();
- ClassDB::register_class<SphereShape3D>();
- ClassDB::register_class<BoxShape3D>();
- ClassDB::register_class<CapsuleShape3D>();
- ClassDB::register_class<CylinderShape3D>();
- ClassDB::register_class<HeightMapShape3D>();
- ClassDB::register_class<WorldMarginShape3D>();
- ClassDB::register_class<ConvexPolygonShape3D>();
- ClassDB::register_class<ConcavePolygonShape3D>();
+ GDREGISTER_VIRTUAL_CLASS(Shape3D);
+ GDREGISTER_CLASS(RayShape3D);
+ GDREGISTER_CLASS(SphereShape3D);
+ GDREGISTER_CLASS(BoxShape3D);
+ GDREGISTER_CLASS(CapsuleShape3D);
+ GDREGISTER_CLASS(CylinderShape3D);
+ GDREGISTER_CLASS(HeightMapShape3D);
+ GDREGISTER_CLASS(WorldMarginShape3D);
+ GDREGISTER_CLASS(ConvexPolygonShape3D);
+ GDREGISTER_CLASS(ConcavePolygonShape3D);
OS::get_singleton()->yield(); //may take time to init
- ClassDB::register_class<VelocityTracker3D>();
+ GDREGISTER_CLASS(VelocityTracker3D);
#endif
- ClassDB::register_class<PhysicsMaterial>();
- ClassDB::register_class<World3D>();
- ClassDB::register_class<Environment>();
- ClassDB::register_class<CameraEffects>();
- ClassDB::register_class<World2D>();
- ClassDB::register_virtual_class<Texture>();
- ClassDB::register_virtual_class<Texture2D>();
- ClassDB::register_class<Sky>();
- ClassDB::register_class<StreamTexture2D>();
- ClassDB::register_class<ImageTexture>();
- ClassDB::register_class<AtlasTexture>();
- ClassDB::register_class<MeshTexture>();
- ClassDB::register_class<CurveTexture>();
- ClassDB::register_class<Curve3Texture>();
- ClassDB::register_class<GradientTexture>();
- ClassDB::register_class<ProxyTexture>();
- ClassDB::register_class<AnimatedTexture>();
- ClassDB::register_class<CameraTexture>();
- ClassDB::register_virtual_class<TextureLayered>();
- ClassDB::register_virtual_class<ImageTextureLayered>();
- ClassDB::register_virtual_class<Texture3D>();
- ClassDB::register_class<ImageTexture3D>();
- ClassDB::register_class<StreamTexture3D>();
- ClassDB::register_class<Cubemap>();
- ClassDB::register_class<CubemapArray>();
- ClassDB::register_class<Texture2DArray>();
- ClassDB::register_virtual_class<StreamTextureLayered>();
- ClassDB::register_class<StreamCubemap>();
- ClassDB::register_class<StreamCubemapArray>();
- ClassDB::register_class<StreamTexture2DArray>();
-
- ClassDB::register_class<Animation>();
- ClassDB::register_class<FontData>();
- ClassDB::register_class<Font>();
- ClassDB::register_class<Curve>();
-
- ClassDB::register_class<TextFile>();
- ClassDB::register_class<TextLine>();
- ClassDB::register_class<TextParagraph>();
-
- ClassDB::register_virtual_class<StyleBox>();
- ClassDB::register_class<StyleBoxEmpty>();
- ClassDB::register_class<StyleBoxTexture>();
- ClassDB::register_class<StyleBoxFlat>();
- ClassDB::register_class<StyleBoxLine>();
- ClassDB::register_class<Theme>();
-
- ClassDB::register_class<PolygonPathFinder>();
- ClassDB::register_class<BitMap>();
- ClassDB::register_class<Gradient>();
+ GDREGISTER_CLASS(PhysicsMaterial);
+ GDREGISTER_CLASS(World3D);
+ GDREGISTER_CLASS(Environment);
+ GDREGISTER_CLASS(CameraEffects);
+ GDREGISTER_CLASS(World2D);
+ GDREGISTER_VIRTUAL_CLASS(Texture);
+ GDREGISTER_VIRTUAL_CLASS(Texture2D);
+ GDREGISTER_CLASS(Sky);
+ GDREGISTER_CLASS(StreamTexture2D);
+ GDREGISTER_CLASS(ImageTexture);
+ GDREGISTER_CLASS(AtlasTexture);
+ GDREGISTER_CLASS(MeshTexture);
+ GDREGISTER_CLASS(CurveTexture);
+ GDREGISTER_CLASS(Curve3Texture);
+ GDREGISTER_CLASS(GradientTexture);
+ GDREGISTER_CLASS(ProxyTexture);
+ GDREGISTER_CLASS(AnimatedTexture);
+ GDREGISTER_CLASS(CameraTexture);
+ GDREGISTER_VIRTUAL_CLASS(TextureLayered);
+ GDREGISTER_VIRTUAL_CLASS(ImageTextureLayered);
+ GDREGISTER_VIRTUAL_CLASS(Texture3D);
+ GDREGISTER_CLASS(ImageTexture3D);
+ GDREGISTER_CLASS(StreamTexture3D);
+ GDREGISTER_CLASS(Cubemap);
+ GDREGISTER_CLASS(CubemapArray);
+ GDREGISTER_CLASS(Texture2DArray);
+ GDREGISTER_VIRTUAL_CLASS(StreamTextureLayered);
+ GDREGISTER_CLASS(StreamCubemap);
+ GDREGISTER_CLASS(StreamCubemapArray);
+ GDREGISTER_CLASS(StreamTexture2DArray);
+
+ GDREGISTER_CLASS(Animation);
+ GDREGISTER_CLASS(FontData);
+ GDREGISTER_CLASS(Font);
+ GDREGISTER_CLASS(Curve);
+
+ GDREGISTER_CLASS(TextFile);
+ GDREGISTER_CLASS(TextLine);
+ GDREGISTER_CLASS(TextParagraph);
+
+ GDREGISTER_VIRTUAL_CLASS(StyleBox);
+ GDREGISTER_CLASS(StyleBoxEmpty);
+ GDREGISTER_CLASS(StyleBoxTexture);
+ GDREGISTER_CLASS(StyleBoxFlat);
+ GDREGISTER_CLASS(StyleBoxLine);
+ GDREGISTER_CLASS(Theme);
+
+ GDREGISTER_CLASS(PolygonPathFinder);
+ GDREGISTER_CLASS(BitMap);
+ GDREGISTER_CLASS(Gradient);
OS::get_singleton()->yield(); //may take time to init
- ClassDB::register_class<AudioStreamPlayer>();
- ClassDB::register_class<AudioStreamPlayer2D>();
+ GDREGISTER_CLASS(AudioStreamPlayer);
+ GDREGISTER_CLASS(AudioStreamPlayer2D);
#ifndef _3D_DISABLED
- ClassDB::register_class<AudioStreamPlayer3D>();
+ GDREGISTER_CLASS(AudioStreamPlayer3D);
#endif
- ClassDB::register_virtual_class<VideoStream>();
- ClassDB::register_class<AudioStreamSample>();
+ GDREGISTER_VIRTUAL_CLASS(VideoStream);
+ GDREGISTER_CLASS(AudioStreamSample);
OS::get_singleton()->yield(); //may take time to init
- ClassDB::register_virtual_class<Shape2D>();
- ClassDB::register_class<LineShape2D>();
- ClassDB::register_class<SegmentShape2D>();
- ClassDB::register_class<RayShape2D>();
- ClassDB::register_class<CircleShape2D>();
- ClassDB::register_class<RectangleShape2D>();
- ClassDB::register_class<CapsuleShape2D>();
- ClassDB::register_class<ConvexPolygonShape2D>();
- ClassDB::register_class<ConcavePolygonShape2D>();
- ClassDB::register_class<Curve2D>();
- ClassDB::register_class<Path2D>();
- ClassDB::register_class<PathFollow2D>();
-
- ClassDB::register_class<NavigationMesh>();
- ClassDB::register_class<NavigationPolygon>();
- ClassDB::register_class<NavigationRegion2D>();
- ClassDB::register_class<NavigationAgent2D>();
- ClassDB::register_class<NavigationObstacle2D>();
+ GDREGISTER_VIRTUAL_CLASS(Shape2D);
+ GDREGISTER_CLASS(LineShape2D);
+ GDREGISTER_CLASS(SegmentShape2D);
+ GDREGISTER_CLASS(RayShape2D);
+ GDREGISTER_CLASS(CircleShape2D);
+ GDREGISTER_CLASS(RectangleShape2D);
+ GDREGISTER_CLASS(CapsuleShape2D);
+ GDREGISTER_CLASS(ConvexPolygonShape2D);
+ GDREGISTER_CLASS(ConcavePolygonShape2D);
+ GDREGISTER_CLASS(Curve2D);
+ GDREGISTER_CLASS(Path2D);
+ GDREGISTER_CLASS(PathFollow2D);
+
+ GDREGISTER_CLASS(NavigationMesh);
+ GDREGISTER_CLASS(NavigationPolygon);
+ GDREGISTER_CLASS(NavigationRegion2D);
+ GDREGISTER_CLASS(NavigationAgent2D);
+ GDREGISTER_CLASS(NavigationObstacle2D);
OS::get_singleton()->yield(); //may take time to init
- ClassDB::register_virtual_class<SceneState>();
- ClassDB::register_class<PackedScene>();
+ GDREGISTER_VIRTUAL_CLASS(SceneState);
+ GDREGISTER_CLASS(PackedScene);
- ClassDB::register_class<SceneTree>();
- ClassDB::register_virtual_class<SceneTreeTimer>(); //sorry, you can't create it
+ GDREGISTER_CLASS(SceneTree);
+ GDREGISTER_VIRTUAL_CLASS(SceneTreeTimer); //sorry, you can't create it
#ifndef DISABLE_DEPRECATED
// Dropped in 4.0, near approximation.
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 5464a46df4..1bbb84f43d 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -390,6 +390,15 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("shadow_outline_size", "Label", 1 * scale);
theme->set_constant("line_spacing", "Label", 3 * scale);
+ theme->set_type_variation("HeaderSmall", "Label");
+ theme->set_font_size("font_size", "HeaderSmall", default_font_size + 4);
+
+ theme->set_type_variation("HeaderMedium", "Label");
+ theme->set_font_size("font_size", "HeaderMedium", default_font_size + 8);
+
+ theme->set_type_variation("HeaderLarge", "Label");
+ theme->set_font_size("font_size", "HeaderLarge", default_font_size + 12);
+
// LineEdit
theme->set_stylebox("normal", "LineEdit", make_stylebox(line_edit_png, 5, 5, 5, 5));
@@ -984,7 +993,7 @@ void make_default_theme(bool p_hidpi, Ref<Font> p_font) {
Ref<StyleBox> default_style;
Ref<Texture2D> default_icon;
Ref<Font> default_font;
- int default_font_size = 16;
+
if (p_font.is_valid()) {
// Use the custom font defined in the Project Settings.
default_font = p_font;
diff --git a/scene/resources/default_theme/default_theme.h b/scene/resources/default_theme/default_theme.h
index a7b2bec5a4..4cd781e814 100644
--- a/scene/resources/default_theme/default_theme.h
+++ b/scene/resources/default_theme/default_theme.h
@@ -33,6 +33,8 @@
#include "scene/resources/theme.h"
+const int default_font_size = 16;
+
void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<Font> &large_font, Ref<Texture2D> &default_icon, Ref<StyleBox> &default_style, float p_scale);
void make_default_theme(bool p_hidpi, Ref<Font> p_font);
void clear_default_theme();
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index f44c0c3ee2..2f92872ad5 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -30,6 +30,7 @@
#include "mesh.h"
+#include "core/math/convex_hull.h"
#include "core/templates/pair.h"
#include "scene/resources/concave_polygon_shape_3d.h"
#include "scene/resources/convex_polygon_shape_3d.h"
@@ -221,9 +222,17 @@ Vector<Face3> Mesh::get_faces() const {
*/
}
-Ref<Shape3D> Mesh::create_convex_shape() const {
- Vector<Vector3> vertices;
+Ref<Shape3D> Mesh::create_convex_shape(bool p_clean, bool p_simplify) const {
+ if (p_simplify) {
+ Vector<Ref<Shape3D>> decomposed = convex_decompose(1);
+ if (decomposed.size() == 1) {
+ return decomposed[0];
+ } else {
+ ERR_PRINT("Convex shape simplification failed, falling back to simpler process.");
+ }
+ }
+ Vector<Vector3> vertices;
for (int i = 0; i < get_surface_count(); i++) {
Array a = surface_get_arrays(i);
ERR_FAIL_COND_V(a.is_empty(), Ref<ConvexPolygonShape3D>());
@@ -232,6 +241,18 @@ Ref<Shape3D> Mesh::create_convex_shape() const {
}
Ref<ConvexPolygonShape3D> shape = memnew(ConvexPolygonShape3D);
+
+ if (p_clean) {
+ Geometry3D::MeshData md;
+ Error err = ConvexHullComputer::convex_hull(vertices, md);
+ if (err == OK) {
+ shape->set_points(md.vertices);
+ return shape;
+ } else {
+ ERR_PRINT("Convex shape cleaning failed, falling back to simpler process.");
+ }
+ }
+
shape->set_points(vertices);
return shape;
}
@@ -543,12 +564,12 @@ void Mesh::clear_cache() const {
debug_lines.clear();
}
-Vector<Ref<Shape3D>> Mesh::convex_decompose() const {
+Vector<Ref<Shape3D>> Mesh::convex_decompose(int p_max_convex_hulls) const {
ERR_FAIL_COND_V(!convex_composition_function, Vector<Ref<Shape3D>>());
const Vector<Face3> faces = get_faces();
- Vector<Vector<Face3>> decomposed = convex_composition_function(faces);
+ Vector<Vector<Face3>> decomposed = convex_composition_function(faces, p_max_convex_hulls);
Vector<Ref<Shape3D>> ret;
@@ -1852,7 +1873,7 @@ void ArrayMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("surface_set_name", "surf_idx", "name"), &ArrayMesh::surface_set_name);
ClassDB::bind_method(D_METHOD("surface_get_name", "surf_idx"), &ArrayMesh::surface_get_name);
ClassDB::bind_method(D_METHOD("create_trimesh_shape"), &ArrayMesh::create_trimesh_shape);
- ClassDB::bind_method(D_METHOD("create_convex_shape"), &ArrayMesh::create_convex_shape);
+ ClassDB::bind_method(D_METHOD("create_convex_shape", "clean", "simplify"), &ArrayMesh::create_convex_shape, DEFVAL(true), DEFVAL(false));
ClassDB::bind_method(D_METHOD("create_outline", "margin"), &ArrayMesh::create_outline);
ClassDB::bind_method(D_METHOD("regen_normal_maps"), &ArrayMesh::regen_normal_maps);
ClassDB::set_method_flags(get_class_static(), _scs_create("regen_normal_maps"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index 02cab9a5e1..27b0eb098b 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -149,7 +149,7 @@ public:
void generate_debug_mesh_indices(Vector<Vector3> &r_points);
Ref<Shape3D> create_trimesh_shape() const;
- Ref<Shape3D> create_convex_shape() const;
+ Ref<Shape3D> create_convex_shape(bool p_clean = true, bool p_simplify = false) const;
Ref<Mesh> create_outline(float p_margin) const;
@@ -159,11 +159,11 @@ public:
Size2i get_lightmap_size_hint() const;
void clear_cache() const;
- typedef Vector<Vector<Face3>> (*ConvexDecompositionFunc)(const Vector<Face3> &);
+ typedef Vector<Vector<Face3>> (*ConvexDecompositionFunc)(const Vector<Face3> &p_faces, int p_max_convex_hulls);
static ConvexDecompositionFunc convex_composition_function;
- Vector<Ref<Shape3D>> convex_decompose() const;
+ Vector<Ref<Shape3D>> convex_decompose(int p_max_convex_hulls = -1) const;
virtual int get_builtin_bind_pose_count() const;
virtual Transform3D get_builtin_bind_pose(int p_index) const;
diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
index cc3346d182..dfa45cc810 100644
--- a/scene/resources/primitive_meshes.cpp
+++ b/scene/resources/primitive_meshes.cpp
@@ -714,7 +714,7 @@ int BoxMesh::get_subdivide_depth() const {
BoxMesh::BoxMesh() {}
/**
- CylinderMesh
+ CylinderMesh
*/
void CylinderMesh::_create_mesh_array(Array &p_arr) const {
@@ -955,7 +955,7 @@ void PlaneMesh::_create_mesh_array(Array &p_arr) const {
u /= (subdivide_w + 1.0);
v /= (subdivide_d + 1.0);
- points.push_back(Vector3(-x, 0.0, -z));
+ points.push_back(Vector3(-x, 0.0, -z) + center_offset);
normals.push_back(Vector3(0.0, 1.0, 0.0));
ADD_TANGENT(1.0, 0.0, 0.0, 1.0);
uvs.push_back(Vector2(1.0 - u, 1.0 - v)); /* 1.0 - uv to match orientation with Quad */
@@ -993,10 +993,13 @@ void PlaneMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_subdivide_width"), &PlaneMesh::get_subdivide_width);
ClassDB::bind_method(D_METHOD("set_subdivide_depth", "subdivide"), &PlaneMesh::set_subdivide_depth);
ClassDB::bind_method(D_METHOD("get_subdivide_depth"), &PlaneMesh::get_subdivide_depth);
+ ClassDB::bind_method(D_METHOD("set_center_offset", "offset"), &PlaneMesh::set_center_offset);
+ ClassDB::bind_method(D_METHOD("get_center_offset"), &PlaneMesh::get_center_offset);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_width", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), "set_subdivide_width", "get_subdivide_width");
ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_depth", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), "set_subdivide_depth", "get_subdivide_depth");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "center_offset"), "set_center_offset", "get_center_offset");
}
void PlaneMesh::set_size(const Size2 &p_size) {
@@ -1026,6 +1029,15 @@ int PlaneMesh::get_subdivide_depth() const {
return subdivide_d;
}
+void PlaneMesh::set_center_offset(const Vector3 p_offset) {
+ center_offset = p_offset;
+ _request_update();
+}
+
+Vector3 PlaneMesh::get_center_offset() const {
+ return center_offset;
+}
+
PlaneMesh::PlaneMesh() {}
/**
@@ -1326,10 +1338,10 @@ void QuadMesh::_create_mesh_array(Array &p_arr) const {
Vector2 _size = Vector2(size.x / 2.0f, size.y / 2.0f);
Vector3 quad_faces[4] = {
- Vector3(-_size.x, -_size.y, 0),
- Vector3(-_size.x, _size.y, 0),
- Vector3(_size.x, _size.y, 0),
- Vector3(_size.x, -_size.y, 0),
+ Vector3(-_size.x, -_size.y, 0) + center_offset,
+ Vector3(-_size.x, _size.y, 0) + center_offset,
+ Vector3(_size.x, _size.y, 0) + center_offset,
+ Vector3(_size.x, -_size.y, 0) + center_offset,
};
static const int indices[6] = {
@@ -1365,7 +1377,11 @@ void QuadMesh::_create_mesh_array(Array &p_arr) const {
void QuadMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_size", "size"), &QuadMesh::set_size);
ClassDB::bind_method(D_METHOD("get_size"), &QuadMesh::get_size);
+ ClassDB::bind_method(D_METHOD("set_center_offset", "center_offset"), &QuadMesh::set_center_offset);
+ ClassDB::bind_method(D_METHOD("get_center_offset"), &QuadMesh::get_center_offset);
+
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "center_offset"), "set_center_offset", "get_center_offset");
}
QuadMesh::QuadMesh() {
@@ -1381,6 +1397,15 @@ Size2 QuadMesh::get_size() const {
return size;
}
+void QuadMesh::set_center_offset(Vector3 p_center_offset) {
+ center_offset = p_center_offset;
+ _request_update();
+}
+
+Vector3 QuadMesh::get_center_offset() const {
+ return center_offset;
+}
+
/**
SphereMesh
*/
diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h
index bd6f94921e..a3de34d3e3 100644
--- a/scene/resources/primitive_meshes.h
+++ b/scene/resources/primitive_meshes.h
@@ -211,6 +211,7 @@ private:
Size2 size = Size2(2.0, 2.0);
int subdivide_w = 0;
int subdivide_d = 0;
+ Vector3 center_offset;
protected:
static void _bind_methods();
@@ -226,6 +227,9 @@ public:
void set_subdivide_depth(const int p_divisions);
int get_subdivide_depth() const;
+ void set_center_offset(const Vector3 p_offset);
+ Vector3 get_center_offset() const;
+
PlaneMesh();
};
@@ -274,6 +278,7 @@ class QuadMesh : public PrimitiveMesh {
private:
Size2 size = Size2(1.0, 1.0);
+ Vector3 center_offset;
protected:
static void _bind_methods();
@@ -284,6 +289,9 @@ public:
void set_size(const Size2 &p_size);
Size2 get_size() const;
+
+ void set_center_offset(const Vector3 p_offset);
+ Vector3 get_center_offset() const;
};
/**
diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp
index 89ac033207..303bbf38f4 100644
--- a/scene/resources/theme.cpp
+++ b/scene/resources/theme.cpp
@@ -263,6 +263,21 @@ Vector<String> Theme::_get_theme_item_type_list(DataType p_data_type) const {
return Vector<String>();
}
+Vector<String> Theme::_get_type_variation_list(const StringName &p_theme_type) const {
+ Vector<String> ilret;
+ List<StringName> il;
+
+ get_type_variation_list(p_theme_type, &il);
+ ilret.resize(il.size());
+
+ int i = 0;
+ String *w = ilret.ptrw();
+ for (List<StringName>::Element *E = il.front(); E; E = E->next(), i++) {
+ w[i] = E->get();
+ }
+ return ilret;
+}
+
Vector<String> Theme::_get_type_list() const {
Vector<String> ilret;
List<StringName> il;
@@ -292,10 +307,14 @@ bool Theme::_set(const StringName &p_name, const Variant &p_value) {
set_stylebox(name, theme_type, p_value);
} else if (type == "fonts") {
set_font(name, theme_type, p_value);
+ } else if (type == "font_sizes") {
+ set_font_size(name, theme_type, p_value);
} else if (type == "colors") {
set_color(name, theme_type, p_value);
} else if (type == "constants") {
set_constant(name, theme_type, p_value);
+ } else if (type == "base_type") {
+ set_type_variation(theme_type, p_value);
} else {
return false;
}
@@ -332,10 +351,14 @@ bool Theme::_get(const StringName &p_name, Variant &r_ret) const {
} else {
r_ret = get_font(name, theme_type);
}
+ } else if (type == "font_sizes") {
+ r_ret = get_font_size(name, theme_type);
} else if (type == "colors") {
r_ret = get_color(name, theme_type);
} else if (type == "constants") {
r_ret = get_constant(name, theme_type);
+ } else if (type == "base_type") {
+ r_ret = get_type_variation_base(theme_type);
} else {
return false;
}
@@ -351,6 +374,14 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
const StringName *key = nullptr;
+ // Type variations.
+ while ((key = variation_map.next(key))) {
+ list.push_back(PropertyInfo(Variant::STRING_NAME, String() + *key + "/base_type"));
+ }
+
+ key = nullptr;
+
+ // Icons.
while ((key = icon_map.next(key))) {
const StringName *key2 = nullptr;
@@ -361,6 +392,7 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
key = nullptr;
+ // Styles.
while ((key = style_map.next(key))) {
const StringName *key2 = nullptr;
@@ -371,6 +403,7 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
key = nullptr;
+ // Fonts.
while ((key = font_map.next(key))) {
const StringName *key2 = nullptr;
@@ -381,6 +414,18 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
key = nullptr;
+ // Font sizes.
+ while ((key = font_size_map.next(key))) {
+ const StringName *key2 = nullptr;
+
+ while ((key2 = font_size_map[*key].next(key2))) {
+ list.push_back(PropertyInfo(Variant::INT, String() + *key + "/font_sizes/" + *key2));
+ }
+ }
+
+ key = nullptr;
+
+ // Colors.
while ((key = color_map.next(key))) {
const StringName *key2 = nullptr;
@@ -391,6 +436,7 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
key = nullptr;
+ // Constants.
while ((key = constant_map.next(key))) {
const StringName *key2 = nullptr;
@@ -399,6 +445,7 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
}
}
+ // Sort and store properties.
list.sort();
for (List<PropertyInfo>::Element *E = list.front(); E; E = E->next()) {
p_list->push_back(E->get());
@@ -1183,6 +1230,63 @@ void Theme::get_theme_item_type_list(DataType p_data_type, List<StringName> *p_l
}
}
+void Theme::set_type_variation(const StringName &p_theme_type, const StringName &p_base_type) {
+ ERR_FAIL_COND_MSG(p_theme_type == StringName(), "An empty theme type cannot be marked as a variation of another type.");
+ ERR_FAIL_COND_MSG(ClassDB::class_exists(p_theme_type), "A type associated with a built-in class cannot be marked as a variation of another type.");
+ ERR_FAIL_COND_MSG(p_base_type == StringName(), "An empty theme type cannot be the base type of a variation. Use clear_type_variation() instead if you want to unmark '" + String(p_theme_type) + "' as a variation.");
+
+ if (variation_map.has(p_theme_type)) {
+ StringName old_base = variation_map[p_theme_type];
+ variation_base_map[old_base].erase(p_theme_type);
+ }
+
+ variation_map[p_theme_type] = p_base_type;
+ variation_base_map[p_base_type].push_back(p_theme_type);
+
+ _emit_theme_changed();
+}
+
+bool Theme::is_type_variation(const StringName &p_theme_type, const StringName &p_base_type) const {
+ return (variation_map.has(p_theme_type) && variation_map[p_theme_type] == p_base_type);
+}
+
+void Theme::clear_type_variation(const StringName &p_theme_type) {
+ ERR_FAIL_COND_MSG(!variation_map.has(p_theme_type), "Cannot clear the type variation '" + String(p_theme_type) + "' because it does not exist.");
+
+ StringName base_type = variation_map[p_theme_type];
+ variation_base_map[base_type].erase(p_theme_type);
+ variation_map.erase(p_theme_type);
+
+ _emit_theme_changed();
+}
+
+StringName Theme::get_type_variation_base(const StringName &p_theme_type) const {
+ if (!variation_map.has(p_theme_type)) {
+ return StringName();
+ }
+
+ return variation_map[p_theme_type];
+}
+
+void Theme::get_type_variation_list(const StringName &p_base_type, List<StringName> *p_list) const {
+ ERR_FAIL_NULL(p_list);
+
+ if (!variation_base_map.has(p_base_type)) {
+ return;
+ }
+
+ for (const List<StringName>::Element *E = variation_base_map[p_base_type].front(); E; E = E->next()) {
+ // Prevent infinite loops if variants were set to be cross-dependent (that's still invalid usage, but handling for stability sake).
+ if (p_list->find(E->get())) {
+ continue;
+ }
+
+ p_list->push_back(E->get());
+ // Continue looking for sub-variations.
+ get_type_variation_list(E->get(), p_list);
+ }
+}
+
void Theme::_freeze_change_propagation() {
no_change_propagation = true;
}
@@ -1236,9 +1340,13 @@ void Theme::clear() {
icon_map.clear();
style_map.clear();
font_map.clear();
+ font_size_map.clear();
color_map.clear();
constant_map.clear();
+ variation_map.clear();
+ variation_base_map.clear();
+
_emit_theme_changed();
}
@@ -1291,6 +1399,9 @@ void Theme::copy_theme(const Ref<Theme> &p_other) {
color_map = p_other->color_map;
constant_map = p_other->constant_map;
+ variation_map = p_other->variation_map;
+ variation_base_map = p_other->variation_base_map;
+
_unfreeze_and_propagate_changes();
}
@@ -1300,30 +1411,42 @@ void Theme::get_type_list(List<StringName> *p_list) const {
Set<StringName> types;
const StringName *key = nullptr;
+ // Icons.
while ((key = icon_map.next(key))) {
types.insert(*key);
}
key = nullptr;
+ // StyleBoxes.
while ((key = style_map.next(key))) {
types.insert(*key);
}
key = nullptr;
+ // Fonts.
while ((key = font_map.next(key))) {
types.insert(*key);
}
key = nullptr;
+ // Font sizes.
+ while ((key = font_size_map.next(key))) {
+ types.insert(*key);
+ }
+
+ key = nullptr;
+
+ // Colors.
while ((key = color_map.next(key))) {
types.insert(*key);
}
key = nullptr;
+ // Constants.
while ((key = constant_map.next(key))) {
types.insert(*key);
}
@@ -1333,10 +1456,25 @@ void Theme::get_type_list(List<StringName> *p_list) const {
}
}
-void Theme::get_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) {
+void Theme::get_type_dependencies(const StringName &p_base_type, const StringName &p_type_variation, List<StringName> *p_list) {
ERR_FAIL_NULL(p_list);
- StringName class_name = p_theme_type;
+ // Build the dependency chain for type variations.
+ if (p_type_variation != StringName()) {
+ StringName variation_name = p_type_variation;
+ while (variation_name != StringName()) {
+ p_list->push_back(variation_name);
+ variation_name = get_type_variation_base(variation_name);
+
+ // If we have reached the base type dependency, it's safe to stop (assuming no funny business was done to the Theme).
+ if (variation_name == p_base_type) {
+ break;
+ }
+ }
+ }
+
+ // Continue building the chain using native class hierarchy.
+ StringName class_name = p_base_type;
while (class_name != StringName()) {
p_list->push_back(class_name);
class_name = ClassDB::get_parent_class_nocheck(class_name);
@@ -1346,6 +1484,7 @@ void Theme::get_type_dependencies(const StringName &p_theme_type, List<StringNam
void Theme::reset_state() {
clear();
}
+
void Theme::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_icon", "name", "theme_type", "texture"), &Theme::set_icon);
ClassDB::bind_method(D_METHOD("get_icon", "name", "theme_type"), &Theme::get_icon);
@@ -1411,6 +1550,12 @@ void Theme::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_theme_item_list", "data_type", "theme_type"), &Theme::_get_theme_item_list);
ClassDB::bind_method(D_METHOD("get_theme_item_type_list", "data_type"), &Theme::_get_theme_item_type_list);
+ ClassDB::bind_method(D_METHOD("set_type_variation", "theme_type", "base_type"), &Theme::set_type_variation);
+ ClassDB::bind_method(D_METHOD("is_type_variation", "theme_type", "base_type"), &Theme::is_type_variation);
+ ClassDB::bind_method(D_METHOD("clear_type_variation", "theme_type"), &Theme::clear_type_variation);
+ ClassDB::bind_method(D_METHOD("get_type_variation_base", "theme_type"), &Theme::get_type_variation_base);
+ ClassDB::bind_method(D_METHOD("get_type_variation_list", "base_type"), &Theme::_get_type_variation_list);
+
ClassDB::bind_method(D_METHOD("get_type_list"), &Theme::_get_type_list);
ClassDB::bind_method("copy_default_theme", &Theme::copy_default_theme);
diff --git a/scene/resources/theme.h b/scene/resources/theme.h
index fe64fd7290..8a8fc28be1 100644
--- a/scene/resources/theme.h
+++ b/scene/resources/theme.h
@@ -69,6 +69,8 @@ private:
HashMap<StringName, HashMap<StringName, int>> font_size_map;
HashMap<StringName, HashMap<StringName, Color>> color_map;
HashMap<StringName, HashMap<StringName, int>> constant_map;
+ HashMap<StringName, StringName> variation_map;
+ HashMap<StringName, List<StringName>> variation_base_map;
Vector<String> _get_icon_list(const String &p_theme_type) const;
Vector<String> _get_icon_type_list() const;
@@ -85,6 +87,8 @@ private:
Vector<String> _get_theme_item_list(DataType p_data_type, const String &p_theme_type) const;
Vector<String> _get_theme_item_type_list(DataType p_data_type) const;
+
+ Vector<String> _get_type_variation_list(const StringName &p_theme_type) const;
Vector<String> _get_type_list() const;
protected:
@@ -197,8 +201,14 @@ public:
void add_theme_item_type(DataType p_data_type, const StringName &p_theme_type);
void get_theme_item_type_list(DataType p_data_type, List<StringName> *p_list) const;
+ void set_type_variation(const StringName &p_theme_type, const StringName &p_base_type);
+ bool is_type_variation(const StringName &p_theme_type, const StringName &p_base_type) const;
+ void clear_type_variation(const StringName &p_theme_type);
+ StringName get_type_variation_base(const StringName &p_theme_type) const;
+ void get_type_variation_list(const StringName &p_base_type, List<StringName> *p_list) const;
+
void get_type_list(List<StringName> *p_list) const;
- static void get_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list);
+ void get_type_dependencies(const StringName &p_base_type, const StringName &p_type_variant, List<StringName> *p_list);
void copy_default_theme();
void copy_theme(const Ref<Theme> &p_other);
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index 54bc7382db..36a1c206c8 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -2708,6 +2708,28 @@ VisualShaderNodeUniformRef::UniformType VisualShaderNodeUniformRef::get_uniform_
return UniformType::UNIFORM_TYPE_FLOAT;
}
+VisualShaderNodeUniformRef::PortType VisualShaderNodeUniformRef::get_port_type_by_index(int p_idx) const {
+ if (p_idx >= 0 && p_idx < uniforms.size()) {
+ switch (uniforms[p_idx].type) {
+ case UniformType::UNIFORM_TYPE_FLOAT:
+ return PORT_TYPE_SCALAR;
+ case UniformType::UNIFORM_TYPE_INT:
+ return PORT_TYPE_SCALAR_INT;
+ case UniformType::UNIFORM_TYPE_SAMPLER:
+ return PORT_TYPE_SAMPLER;
+ case UniformType::UNIFORM_TYPE_VECTOR:
+ return PORT_TYPE_VECTOR;
+ case UniformType::UNIFORM_TYPE_TRANSFORM:
+ return PORT_TYPE_TRANSFORM;
+ case UniformType::UNIFORM_TYPE_COLOR:
+ return PORT_TYPE_VECTOR;
+ default:
+ break;
+ }
+ }
+ return PORT_TYPE_SCALAR;
+}
+
String VisualShaderNodeUniformRef::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
switch (uniform_type) {
case UniformType::UNIFORM_TYPE_FLOAT:
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index 454012b7ed..880c401b29 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -517,6 +517,7 @@ public:
String get_uniform_name_by_index(int p_idx) const;
UniformType get_uniform_type_by_name(const String &p_name) const;
UniformType get_uniform_type_by_index(int p_idx) const;
+ PortType get_port_type_by_index(int p_idx) const;
virtual Vector<StringName> get_editable_properties() const override;
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index d3b094de31..4e73b8db44 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -805,7 +805,7 @@ void VisualShaderNodeTexture::_bind_methods() {
VisualShaderNodeTexture::VisualShaderNodeTexture() {
}
-////////////// Curve
+////////////// CurveTexture
String VisualShaderNodeCurveTexture::get_caption() const {
return "CurveTexture";
@@ -889,6 +889,90 @@ VisualShaderNodeCurveTexture::VisualShaderNodeCurveTexture() {
allow_v_resize = false;
}
+////////////// Curve3Texture
+
+String VisualShaderNodeCurve3Texture::get_caption() const {
+ return "Curve3Texture";
+}
+
+int VisualShaderNodeCurve3Texture::get_input_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeCurve3Texture::PortType VisualShaderNodeCurve3Texture::get_input_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR;
+}
+
+String VisualShaderNodeCurve3Texture::get_input_port_name(int p_port) const {
+ return String();
+}
+
+int VisualShaderNodeCurve3Texture::get_output_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeCurve3Texture::PortType VisualShaderNodeCurve3Texture::get_output_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeCurve3Texture::get_output_port_name(int p_port) const {
+ return String();
+}
+
+void VisualShaderNodeCurve3Texture::set_texture(Ref<Curve3Texture> p_texture) {
+ texture = p_texture;
+ emit_changed();
+}
+
+Ref<Curve3Texture> VisualShaderNodeCurve3Texture::get_texture() const {
+ return texture;
+}
+
+Vector<StringName> VisualShaderNodeCurve3Texture::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("texture");
+ return props;
+}
+
+String VisualShaderNodeCurve3Texture::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ return "uniform sampler2D " + make_unique_id(p_type, p_id, "curve3d") + ";\n";
+}
+
+String VisualShaderNodeCurve3Texture::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ if (p_input_vars[0] == String()) {
+ return "\t" + p_output_vars[0] + " = vec3(0.0);\n";
+ }
+ String id = make_unique_id(p_type, p_id, "curve3d");
+ String code;
+ code += "\t" + p_output_vars[0] + " = texture(" + id + ", vec2(" + p_input_vars[0] + ")).rgb;\n";
+ return code;
+}
+
+Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCurve3Texture::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
+ VisualShader::DefaultTextureParam dtp;
+ dtp.name = make_unique_id(p_type, p_id, "curve3d");
+ dtp.param = texture;
+ Vector<VisualShader::DefaultTextureParam> ret;
+ ret.push_back(dtp);
+ return ret;
+}
+
+void VisualShaderNodeCurve3Texture::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_texture", "texture"), &VisualShaderNodeCurve3Texture::set_texture);
+ ClassDB::bind_method(D_METHOD("get_texture"), &VisualShaderNodeCurve3Texture::get_texture);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Curve3Texture"), "set_texture", "get_texture");
+}
+
+bool VisualShaderNodeCurve3Texture::is_use_prop_slots() const {
+ return true;
+}
+
+VisualShaderNodeCurve3Texture::VisualShaderNodeCurve3Texture() {
+ simple_decl = true;
+ allow_v_resize = false;
+}
+
////////////// Sample3D
int VisualShaderNodeSample3D::get_input_port_count() const {
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index 5b44e9f776..3ae79723e9 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -338,6 +338,39 @@ public:
///////////////////////////////////////
+class VisualShaderNodeCurve3Texture : public VisualShaderNodeResizableBase {
+ GDCLASS(VisualShaderNodeCurve3Texture, VisualShaderNodeResizableBase);
+ Ref<Curve3Texture> texture;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+
+ virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+
+ void set_texture(Ref<Curve3Texture> p_value);
+ Ref<Curve3Texture> get_texture() const;
+
+ virtual Vector<StringName> get_editable_properties() const override;
+ virtual bool is_use_prop_slots() const override;
+
+ VisualShaderNodeCurve3Texture();
+};
+
+///////////////////////////////////////
+
class VisualShaderNodeSample3D : public VisualShaderNode {
GDCLASS(VisualShaderNodeSample3D, VisualShaderNode);
diff --git a/servers/display_server.cpp b/servers/display_server.cpp
index d746117884..be2a813fd1 100644
--- a/servers/display_server.cpp
+++ b/servers/display_server.cpp
@@ -35,7 +35,6 @@
#include "servers/display_server_headless.h"
DisplayServer *DisplayServer::singleton = nullptr;
-DisplayServer::SwitchVSyncCallbackInThread DisplayServer::switch_vsync_function = nullptr;
bool DisplayServer::hidpi_allowed = false;
@@ -185,7 +184,7 @@ bool DisplayServer::screen_is_kept_on() const {
return false;
}
-DisplayServer::WindowID DisplayServer::create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect) {
+DisplayServer::WindowID DisplayServer::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
ERR_FAIL_V_MSG(INVALID_WINDOW_ID, "Sub-windows not supported by this display server.");
}
@@ -309,29 +308,13 @@ void DisplayServer::set_icon(const Ref<Image> &p_icon) {
WARN_PRINT("Icon not supported by this display server.");
}
-void DisplayServer::_set_use_vsync(bool p_enable) {
- WARN_PRINT("VSync not supported by this display server.");
+void DisplayServer::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
+ WARN_PRINT("Changing the VSync mode is not supported by this display server.");
}
-void DisplayServer::vsync_set_enabled(bool p_enable) {
- vsync_enabled = p_enable;
- if (switch_vsync_function) { //if a function was set, use function
- switch_vsync_function(p_enable);
- } else { //otherwise just call here
- _set_use_vsync(p_enable);
- }
-}
-
-bool DisplayServer::vsync_is_enabled() const {
- return vsync_enabled;
-}
-
-void DisplayServer::vsync_set_use_via_compositor(bool p_enable) {
- WARN_PRINT("VSync via compositor not supported by this display server.");
-}
-
-bool DisplayServer::vsync_is_using_via_compositor() const {
- return false;
+DisplayServer::VSyncMode DisplayServer::window_get_vsync_mode(WindowID p_window) const {
+ WARN_PRINT("Changing the VSync mode is not supported by this display server.");
+ return VSyncMode::VSYNC_ENABLED;
}
void DisplayServer::set_context(Context p_context) {
@@ -394,7 +377,7 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_window_list"), &DisplayServer::get_window_list);
ClassDB::bind_method(D_METHOD("get_window_at_screen_position", "position"), &DisplayServer::get_window_at_screen_position);
- ClassDB::bind_method(D_METHOD("create_sub_window", "mode", "flags", "rect"), &DisplayServer::create_sub_window, DEFVAL(Rect2i()));
+ ClassDB::bind_method(D_METHOD("create_sub_window", "mode", "vsync_mode", "flags", "rect"), &DisplayServer::create_sub_window, DEFVAL(Rect2i()));
ClassDB::bind_method(D_METHOD("delete_sub_window", "window_id"), &DisplayServer::delete_sub_window);
ClassDB::bind_method(D_METHOD("window_set_title", "title", "window_id"), &DisplayServer::window_set_title, DEFVAL(MAIN_WINDOW_ID));
@@ -441,6 +424,9 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("window_set_ime_active", "active", "window_id"), &DisplayServer::window_set_ime_active, DEFVAL(MAIN_WINDOW_ID));
ClassDB::bind_method(D_METHOD("window_set_ime_position", "position", "window_id"), &DisplayServer::window_set_ime_position, DEFVAL(MAIN_WINDOW_ID));
+ ClassDB::bind_method(D_METHOD("window_set_vsync_mode", "vsync_mode", "window_id"), &DisplayServer::window_set_vsync_mode, DEFVAL(MAIN_WINDOW_ID));
+ ClassDB::bind_method(D_METHOD("window_get_vsync_mode", "window_id"), &DisplayServer::window_get_vsync_mode, DEFVAL(MAIN_WINDOW_ID));
+
ClassDB::bind_method(D_METHOD("ime_get_selection"), &DisplayServer::ime_get_selection);
ClassDB::bind_method(D_METHOD("ime_get_text"), &DisplayServer::ime_get_text);
@@ -472,12 +458,6 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("process_events"), &DisplayServer::process_events);
ClassDB::bind_method(D_METHOD("force_process_and_drop_events"), &DisplayServer::force_process_and_drop_events);
- ClassDB::bind_method(D_METHOD("vsync_set_enabled", "enabled"), &DisplayServer::vsync_set_enabled);
- ClassDB::bind_method(D_METHOD("vsync_is_enabled"), &DisplayServer::vsync_is_enabled);
-
- ClassDB::bind_method(D_METHOD("vsync_set_use_via_compositor", "enabled"), &DisplayServer::vsync_set_use_via_compositor);
- ClassDB::bind_method(D_METHOD("vsync_is_using_via_compositor"), &DisplayServer::vsync_is_using_via_compositor);
-
ClassDB::bind_method(D_METHOD("set_native_icon", "filename"), &DisplayServer::set_native_icon);
ClassDB::bind_method(D_METHOD("set_icon", "image"), &DisplayServer::set_icon);
@@ -561,6 +541,11 @@ void DisplayServer::_bind_methods() {
BIND_ENUM_CONSTANT(WINDOW_EVENT_CLOSE_REQUEST);
BIND_ENUM_CONSTANT(WINDOW_EVENT_GO_BACK_REQUEST);
BIND_ENUM_CONSTANT(WINDOW_EVENT_DPI_CHANGE);
+
+ BIND_ENUM_CONSTANT(VSYNC_DISABLED);
+ BIND_ENUM_CONSTANT(VSYNC_ENABLED);
+ BIND_ENUM_CONSTANT(VSYNC_ADAPTIVE);
+ BIND_ENUM_CONSTANT(VSYNC_MAILBOX);
}
void DisplayServer::register_create_function(const char *p_name, CreateFunction p_function, GetRenderingDriversFunction p_get_drivers) {
@@ -587,9 +572,9 @@ Vector<String> DisplayServer::get_create_function_rendering_drivers(int p_index)
return server_create_functions[p_index].get_rendering_drivers_function();
}
-DisplayServer *DisplayServer::create(int p_index, const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+DisplayServer *DisplayServer::create(int p_index, const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
ERR_FAIL_INDEX_V(p_index, server_create_count, nullptr);
- return server_create_functions[p_index].create_function(p_rendering_driver, p_mode, p_flags, p_resolution, r_error);
+ return server_create_functions[p_index].create_function(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error);
}
void DisplayServer::_input_set_mouse_mode(Input::MouseMode p_mode) {
diff --git a/servers/display_server.h b/servers/display_server.h
index 7dab7b7481..8d289b10fd 100644
--- a/servers/display_server.h
+++ b/servers/display_server.h
@@ -42,7 +42,6 @@ class DisplayServer : public Object {
GDCLASS(DisplayServer, Object)
static DisplayServer *singleton;
- bool vsync_enabled = true;
static bool hidpi_allowed;
public:
@@ -57,7 +56,16 @@ public:
WINDOW_MODE_FULLSCREEN
};
- typedef DisplayServer *(*CreateFunction)(const String &, WindowMode, uint32_t, const Size2i &, Error &r_error);
+ // Keep the VSyncMode enum values in sync with the `display/window/vsync/vsync_mode`
+ // project setting hint.
+ enum VSyncMode {
+ VSYNC_DISABLED,
+ VSYNC_ENABLED,
+ VSYNC_ADAPTIVE,
+ VSYNC_MAILBOX
+ };
+
+ typedef DisplayServer *(*CreateFunction)(const String &, WindowMode, VSyncMode, uint32_t, const Size2i &, Error &r_error);
typedef Vector<String> (*GetRenderingDriversFunction)();
private:
@@ -84,7 +92,6 @@ protected:
static int server_create_count;
friend class RendererViewport;
- virtual void _set_use_vsync(bool p_enable);
public:
enum Feature {
@@ -221,7 +228,7 @@ public:
WINDOW_FLAG_NO_FOCUS_BIT = (1 << WINDOW_FLAG_NO_FOCUS)
};
- virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
+ virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
virtual void show_window(WindowID p_id);
virtual void delete_sub_window(WindowID p_id);
@@ -272,6 +279,9 @@ public:
virtual void window_set_mode(WindowMode p_mode, WindowID p_window = MAIN_WINDOW_ID) = 0;
virtual WindowMode window_get_mode(WindowID p_window = MAIN_WINDOW_ID) const = 0;
+ virtual void window_set_vsync_mode(VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID);
+ virtual VSyncMode window_get_vsync_mode(WindowID p_window) const;
+
virtual bool window_is_maximize_allowed(WindowID p_window = MAIN_WINDOW_ID) const = 0;
virtual void window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window = MAIN_WINDOW_ID) = 0;
@@ -352,18 +362,6 @@ public:
virtual void set_native_icon(const String &p_filename);
virtual void set_icon(const Ref<Image> &p_icon);
- typedef void (*SwitchVSyncCallbackInThread)(bool);
-
- static SwitchVSyncCallbackInThread switch_vsync_function;
-
- void vsync_set_enabled(bool p_enable);
- bool vsync_is_enabled() const;
-
- virtual void vsync_set_use_via_compositor(bool p_enable);
- virtual bool vsync_is_using_via_compositor() const;
-
- //real, actual overridable function to switch vsync, which needs to be called from graphics thread if needed
-
enum Context {
CONTEXT_EDITOR,
CONTEXT_PROJECTMAN,
@@ -376,7 +374,7 @@ public:
static int get_create_function_count();
static const char *get_create_function_name(int p_index);
static Vector<String> get_create_function_rendering_drivers(int p_index);
- static DisplayServer *create(int p_index, const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ static DisplayServer *create(int p_index, const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
DisplayServer();
~DisplayServer();
@@ -389,5 +387,6 @@ VARIANT_ENUM_CAST(DisplayServer::ScreenOrientation)
VARIANT_ENUM_CAST(DisplayServer::WindowMode)
VARIANT_ENUM_CAST(DisplayServer::WindowFlags)
VARIANT_ENUM_CAST(DisplayServer::CursorShape)
+VARIANT_ENUM_CAST(DisplayServer::VSyncMode)
#endif // DISPLAY_SERVER_H
diff --git a/servers/display_server_headless.h b/servers/display_server_headless.h
index 8b386c8d9c..870401b180 100644
--- a/servers/display_server_headless.h
+++ b/servers/display_server_headless.h
@@ -45,7 +45,7 @@ private:
return drivers;
}
- static DisplayServer *create_func(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+ static DisplayServer *create_func(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
r_error = OK;
RasterizerDummy::make_current();
return memnew(DisplayServerHeadless());
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp
index 2118dca015..717b4e8d14 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -120,105 +120,106 @@ void preregister_server_types() {
void register_server_types() {
OS::get_singleton()->set_has_server_feature_callback(has_server_feature_callback);
- ClassDB::register_virtual_class<DisplayServer>();
- ClassDB::register_virtual_class<RenderingServer>();
- ClassDB::register_class<AudioServer>();
+ GDREGISTER_VIRTUAL_CLASS(DisplayServer);
+ GDREGISTER_VIRTUAL_CLASS(RenderingServer);
+ GDREGISTER_CLASS(AudioServer);
- ClassDB::register_class<TextServerManager>();
- ClassDB::register_virtual_class<TextServer>();
+ GDREGISTER_CLASS(TextServerManager);
+ GDREGISTER_VIRTUAL_CLASS(TextServer);
TextServer::initialize_hex_code_box_fonts();
- ClassDB::register_virtual_class<PhysicsServer2D>();
- ClassDB::register_virtual_class<PhysicsServer3D>();
- ClassDB::register_virtual_class<NavigationServer2D>();
- ClassDB::register_virtual_class<NavigationServer3D>();
- ClassDB::register_class<XRServer>();
- ClassDB::register_class<CameraServer>();
+ GDREGISTER_VIRTUAL_CLASS(PhysicsServer2D);
+ GDREGISTER_VIRTUAL_CLASS(PhysicsServer3D);
+ GDREGISTER_VIRTUAL_CLASS(NavigationServer2D);
+ GDREGISTER_VIRTUAL_CLASS(NavigationServer3D);
+ GDREGISTER_CLASS(XRServer);
+ GDREGISTER_CLASS(CameraServer);
- ClassDB::register_virtual_class<RenderingDevice>();
+ GDREGISTER_VIRTUAL_CLASS(RenderingDevice);
- ClassDB::register_virtual_class<XRInterface>();
- ClassDB::register_class<XRPositionalTracker>();
+ GDREGISTER_VIRTUAL_CLASS(XRInterface);
+ GDREGISTER_CLASS(XRPositionalTracker);
- ClassDB::register_virtual_class<AudioStream>();
- ClassDB::register_virtual_class<AudioStreamPlayback>();
- ClassDB::register_virtual_class<AudioStreamPlaybackResampled>();
- ClassDB::register_class<AudioStreamMicrophone>();
- ClassDB::register_class<AudioStreamRandomPitch>();
- ClassDB::register_virtual_class<AudioEffect>();
- ClassDB::register_virtual_class<AudioEffectInstance>();
- ClassDB::register_class<AudioEffectEQ>();
- ClassDB::register_class<AudioEffectFilter>();
- ClassDB::register_class<AudioBusLayout>();
+ GDREGISTER_VIRTUAL_CLASS(AudioStream);
+ GDREGISTER_VIRTUAL_CLASS(AudioStreamPlayback);
+ GDREGISTER_VIRTUAL_CLASS(AudioStreamPlaybackResampled);
+ GDREGISTER_CLASS(AudioStreamMicrophone);
+ GDREGISTER_CLASS(AudioStreamRandomPitch);
+ GDREGISTER_VIRTUAL_CLASS(AudioEffect);
+ GDREGISTER_VIRTUAL_CLASS(AudioEffectInstance);
+ GDREGISTER_CLASS(AudioEffectEQ);
+ GDREGISTER_CLASS(AudioEffectFilter);
+ GDREGISTER_CLASS(AudioBusLayout);
- ClassDB::register_class<AudioStreamGenerator>();
- ClassDB::register_virtual_class<AudioStreamGeneratorPlayback>();
+ GDREGISTER_CLASS(AudioStreamGenerator);
+ GDREGISTER_VIRTUAL_CLASS(AudioStreamGeneratorPlayback);
{
//audio effects
- ClassDB::register_class<AudioEffectAmplify>();
+ GDREGISTER_CLASS(AudioEffectAmplify);
- ClassDB::register_class<AudioEffectReverb>();
+ GDREGISTER_CLASS(AudioEffectReverb);
- ClassDB::register_class<AudioEffectLowPassFilter>();
- ClassDB::register_class<AudioEffectHighPassFilter>();
- ClassDB::register_class<AudioEffectBandPassFilter>();
- ClassDB::register_class<AudioEffectNotchFilter>();
- ClassDB::register_class<AudioEffectBandLimitFilter>();
- ClassDB::register_class<AudioEffectLowShelfFilter>();
- ClassDB::register_class<AudioEffectHighShelfFilter>();
+ GDREGISTER_CLASS(AudioEffectLowPassFilter);
+ GDREGISTER_CLASS(AudioEffectHighPassFilter);
+ GDREGISTER_CLASS(AudioEffectBandPassFilter);
+ GDREGISTER_CLASS(AudioEffectNotchFilter);
+ GDREGISTER_CLASS(AudioEffectBandLimitFilter);
+ GDREGISTER_CLASS(AudioEffectLowShelfFilter);
+ GDREGISTER_CLASS(AudioEffectHighShelfFilter);
- ClassDB::register_class<AudioEffectEQ6>();
- ClassDB::register_class<AudioEffectEQ10>();
- ClassDB::register_class<AudioEffectEQ21>();
+ GDREGISTER_CLASS(AudioEffectEQ6);
+ GDREGISTER_CLASS(AudioEffectEQ10);
+ GDREGISTER_CLASS(AudioEffectEQ21);
- ClassDB::register_class<AudioEffectDistortion>();
+ GDREGISTER_CLASS(AudioEffectDistortion);
- ClassDB::register_class<AudioEffectStereoEnhance>();
+ GDREGISTER_CLASS(AudioEffectStereoEnhance);
- ClassDB::register_class<AudioEffectPanner>();
- ClassDB::register_class<AudioEffectChorus>();
- ClassDB::register_class<AudioEffectDelay>();
- ClassDB::register_class<AudioEffectCompressor>();
- ClassDB::register_class<AudioEffectLimiter>();
- ClassDB::register_class<AudioEffectPitchShift>();
- ClassDB::register_class<AudioEffectPhaser>();
+ GDREGISTER_CLASS(AudioEffectPanner);
+ GDREGISTER_CLASS(AudioEffectChorus);
+ GDREGISTER_CLASS(AudioEffectDelay);
+ GDREGISTER_CLASS(AudioEffectCompressor);
+ GDREGISTER_CLASS(AudioEffectLimiter);
+ GDREGISTER_CLASS(AudioEffectPitchShift);
+ GDREGISTER_CLASS(AudioEffectPhaser);
- ClassDB::register_class<AudioEffectRecord>();
- ClassDB::register_class<AudioEffectSpectrumAnalyzer>();
- ClassDB::register_virtual_class<AudioEffectSpectrumAnalyzerInstance>();
+ GDREGISTER_CLASS(AudioEffectRecord);
+ GDREGISTER_CLASS(AudioEffectSpectrumAnalyzer);
+ GDREGISTER_VIRTUAL_CLASS(AudioEffectSpectrumAnalyzerInstance);
- ClassDB::register_class<AudioEffectCapture>();
+ GDREGISTER_CLASS(AudioEffectCapture);
}
- ClassDB::register_virtual_class<RenderingDevice>();
- ClassDB::register_class<RDTextureFormat>();
- ClassDB::register_class<RDTextureView>();
- ClassDB::register_class<RDAttachmentFormat>();
- ClassDB::register_class<RDFramebufferPass>();
- ClassDB::register_class<RDSamplerState>();
- ClassDB::register_class<RDVertexAttribute>();
- ClassDB::register_class<RDUniform>();
- ClassDB::register_class<RDPipelineRasterizationState>();
- ClassDB::register_class<RDPipelineMultisampleState>();
- ClassDB::register_class<RDPipelineDepthStencilState>();
- ClassDB::register_class<RDPipelineColorBlendStateAttachment>();
- ClassDB::register_class<RDPipelineColorBlendState>();
- ClassDB::register_class<RDShaderSource>();
- ClassDB::register_class<RDShaderBytecode>();
- ClassDB::register_class<RDShaderFile>();
-
- ClassDB::register_class<CameraFeed>();
-
- ClassDB::register_virtual_class<PhysicsDirectBodyState2D>();
- ClassDB::register_virtual_class<PhysicsDirectSpaceState2D>();
- ClassDB::register_class<PhysicsTestMotionResult2D>();
- ClassDB::register_class<PhysicsShapeQueryParameters2D>();
-
- ClassDB::register_class<PhysicsShapeQueryParameters3D>();
- ClassDB::register_virtual_class<PhysicsDirectBodyState3D>();
- ClassDB::register_virtual_class<PhysicsDirectSpaceState3D>();
- ClassDB::register_class<PhysicsTestMotionResult3D>();
+ GDREGISTER_VIRTUAL_CLASS(RenderingDevice);
+ GDREGISTER_CLASS(RDTextureFormat);
+ GDREGISTER_CLASS(RDTextureView);
+ GDREGISTER_CLASS(RDAttachmentFormat);
+ GDREGISTER_CLASS(RDFramebufferPass);
+ GDREGISTER_CLASS(RDSamplerState);
+ GDREGISTER_CLASS(RDVertexAttribute);
+ GDREGISTER_CLASS(RDUniform);
+ GDREGISTER_CLASS(RDPipelineRasterizationState);
+ GDREGISTER_CLASS(RDPipelineMultisampleState);
+ GDREGISTER_CLASS(RDPipelineDepthStencilState);
+ GDREGISTER_CLASS(RDPipelineColorBlendStateAttachment);
+ GDREGISTER_CLASS(RDPipelineColorBlendState);
+ GDREGISTER_CLASS(RDShaderSource);
+ GDREGISTER_CLASS(RDShaderBytecode);
+ GDREGISTER_CLASS(RDShaderFile);
+ GDREGISTER_CLASS(RDPipelineSpecializationConstant);
+
+ GDREGISTER_CLASS(CameraFeed);
+
+ GDREGISTER_VIRTUAL_CLASS(PhysicsDirectBodyState2D);
+ GDREGISTER_VIRTUAL_CLASS(PhysicsDirectSpaceState2D);
+ GDREGISTER_CLASS(PhysicsTestMotionResult2D);
+ GDREGISTER_CLASS(PhysicsShapeQueryParameters2D);
+
+ GDREGISTER_CLASS(PhysicsShapeQueryParameters3D);
+ GDREGISTER_VIRTUAL_CLASS(PhysicsDirectBodyState3D);
+ GDREGISTER_VIRTUAL_CLASS(PhysicsDirectSpaceState3D);
+ GDREGISTER_CLASS(PhysicsTestMotionResult3D);
// Physics 2D
GLOBAL_DEF(PhysicsServer2DManager::setting_property_name, "DEFAULT");
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index 46057bddab..a70514e9e5 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -709,6 +709,10 @@ bool RendererSceneRenderRD::reflection_probe_instance_begin_render(RID p_instanc
}
}
+ if (rpi->atlas_index != -1) { // should we fail if this is still -1 ?
+ atlas->reflections.write[rpi->atlas_index].owner = p_instance;
+ }
+
rpi->atlas = p_reflection_atlas;
rpi->rendering = true;
rpi->dirty = false;
diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp
index 46e340c0ac..15ce1dbe63 100644
--- a/servers/rendering/renderer_viewport.cpp
+++ b/servers/rendering/renderer_viewport.cpp
@@ -694,7 +694,7 @@ void RendererViewport::viewport_set_active(RID p_viewport, bool p_active) {
ERR_FAIL_COND(!viewport);
if (p_active) {
- ERR_FAIL_COND(active_viewports.find(viewport) != -1); //already active
+ ERR_FAIL_COND_MSG(active_viewports.find(viewport) != -1, "Can't make active a Viewport that is already active.");
viewport->occlusion_buffer_dirty = true;
active_viewports.push_back(viewport);
} else {
@@ -1116,9 +1116,9 @@ void RendererViewport::set_default_clear_color(const Color &p_color) {
RSG::storage->set_default_clear_color(p_color);
}
-//workaround for setting this on thread
-void RendererViewport::call_set_use_vsync(bool p_enable) {
- DisplayServer::get_singleton()->_set_use_vsync(p_enable);
+// Workaround for setting this on thread.
+void RendererViewport::call_set_vsync_mode(DisplayServer::VSyncMode p_mode, DisplayServer::WindowID p_window) {
+ DisplayServer::get_singleton()->window_set_vsync_mode(p_mode, p_window);
}
int RendererViewport::get_total_objects_drawn() const {
diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h
index b449a9fa1a..ac7a35f97d 100644
--- a/servers/rendering/renderer_viewport.h
+++ b/servers/rendering/renderer_viewport.h
@@ -271,8 +271,8 @@ public:
int get_total_vertices_drawn() const;
int get_total_draw_calls_used() const;
- //workaround for setting this on thread
- void call_set_use_vsync(bool p_enable);
+ // Workaround for setting this on thread.
+ void call_set_vsync_mode(DisplayServer::VSyncMode p_mode, DisplayServer::WindowID p_window);
RendererViewport();
virtual ~RendererViewport() {}
diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp
index 9f586b29fc..3594939362 100644
--- a/servers/rendering/rendering_device.cpp
+++ b/servers/rendering/rendering_device.cpp
@@ -221,7 +221,36 @@ Error RenderingDevice::_buffer_update(RID p_buffer, uint32_t p_offset, uint32_t
return buffer_update(p_buffer, p_offset, p_size, p_data.ptr(), p_post_barrier);
}
-RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags, uint32_t p_for_render_pass) {
+static Vector<RenderingDevice::PipelineSpecializationConstant> _get_spec_constants(const TypedArray<RDPipelineSpecializationConstant> &p_constants) {
+ Vector<RenderingDevice::PipelineSpecializationConstant> ret;
+ ret.resize(p_constants.size());
+ for (int i = 0; i < p_constants.size(); i++) {
+ Ref<RDPipelineSpecializationConstant> c = p_constants[i];
+ ERR_CONTINUE(c.is_null());
+ RenderingDevice::PipelineSpecializationConstant &sc = ret.write[i];
+ Variant value = c->get_value();
+ switch (value.get_type()) {
+ case Variant::BOOL: {
+ sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL;
+ sc.bool_value = value;
+ } break;
+ case Variant::INT: {
+ sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT;
+ sc.int_value = value;
+ } break;
+ case Variant::FLOAT: {
+ sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_FLOAT;
+ sc.float_value = value;
+ } break;
+ default: {
+ }
+ }
+
+ sc.constant_id = c->get_constant_id();
+ }
+ return ret;
+}
+RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags, uint32_t p_for_render_pass, const TypedArray<RDPipelineSpecializationConstant> &p_specialization_constants) {
PipelineRasterizationState rasterization_state;
if (p_rasterization_state.is_valid()) {
rasterization_state = p_rasterization_state->base;
@@ -252,7 +281,11 @@ RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p
}
}
- return render_pipeline_create(p_shader, p_framebuffer_format, p_vertex_format, p_render_primitive, rasterization_state, multisample_state, depth_stencil_state, color_blend_state, p_dynamic_state_flags, p_for_render_pass);
+ return render_pipeline_create(p_shader, p_framebuffer_format, p_vertex_format, p_render_primitive, rasterization_state, multisample_state, depth_stencil_state, color_blend_state, p_dynamic_state_flags, p_for_render_pass, _get_spec_constants(p_specialization_constants));
+}
+
+RID RenderingDevice::_compute_pipeline_create(RID p_shader, const TypedArray<RDPipelineSpecializationConstant> &p_specialization_constants = TypedArray<RDPipelineSpecializationConstant>()) {
+ return compute_pipeline_create(p_shader, _get_spec_constants(p_specialization_constants));
}
Vector<int64_t> RenderingDevice::_draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, const TypedArray<RID> &p_storage_textures) {
@@ -348,10 +381,10 @@ void RenderingDevice::_bind_methods() {
ClassDB::bind_method(D_METHOD("buffer_clear", "buffer", "offset", "size_bytes", "post_barrier"), &RenderingDevice::buffer_clear, DEFVAL(BARRIER_MASK_ALL));
ClassDB::bind_method(D_METHOD("buffer_get_data", "buffer"), &RenderingDevice::buffer_get_data);
- ClassDB::bind_method(D_METHOD("render_pipeline_create", "shader", "framebuffer_format", "vertex_format", "primitive", "rasterization_state", "multisample_state", "stencil_state", "color_blend_state", "dynamic_state_flags", "for_render_pass"), &RenderingDevice::_render_pipeline_create, DEFVAL(0), DEFVAL(0));
+ ClassDB::bind_method(D_METHOD("render_pipeline_create", "shader", "framebuffer_format", "vertex_format", "primitive", "rasterization_state", "multisample_state", "stencil_state", "color_blend_state", "dynamic_state_flags", "for_render_pass", "specialization_constants"), &RenderingDevice::_render_pipeline_create, DEFVAL(0), DEFVAL(0), DEFVAL(TypedArray<RDPipelineSpecializationConstant>()));
ClassDB::bind_method(D_METHOD("render_pipeline_is_valid", "render_pipeline"), &RenderingDevice::render_pipeline_is_valid);
- ClassDB::bind_method(D_METHOD("compute_pipeline_create", "shader"), &RenderingDevice::compute_pipeline_create);
+ ClassDB::bind_method(D_METHOD("compute_pipeline_create", "shader", "specialization_constants"), &RenderingDevice::_compute_pipeline_create, DEFVAL(TypedArray<RDPipelineSpecializationConstant>()));
ClassDB::bind_method(D_METHOD("compute_pipeline_is_valid", "compute_pieline"), &RenderingDevice::compute_pipeline_is_valid);
ClassDB::bind_method(D_METHOD("screen_get_width", "screen"), &RenderingDevice::screen_get_width, DEFVAL(DisplayServer::MAIN_WINDOW_ID));
@@ -853,6 +886,10 @@ void RenderingDevice::_bind_methods() {
BIND_ENUM_CONSTANT(SHADER_LANGUAGE_GLSL);
BIND_ENUM_CONSTANT(SHADER_LANGUAGE_HLSL);
+ BIND_ENUM_CONSTANT(PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL);
+ BIND_ENUM_CONSTANT(PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT);
+ BIND_ENUM_CONSTANT(PIPELINE_SPECIALIZATION_CONSTANT_TYPE_FLOAT);
+
BIND_ENUM_CONSTANT(LIMIT_MAX_BOUND_UNIFORM_SETS);
BIND_ENUM_CONSTANT(LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS);
BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURES_PER_UNIFORM_SET);
diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h
index 0ca84bd79e..9a154ef7e9 100644
--- a/servers/rendering/rendering_device.h
+++ b/servers/rendering/rendering_device.h
@@ -48,6 +48,7 @@ class RDPipelineMultisampleState;
class RDPipelineDepthStencilState;
class RDPipelineColorBlendState;
class RDFramebufferPass;
+class RDPipelineSpecializationConstant;
class RenderingDevice : public Object {
GDCLASS(RenderingDevice, Object)
@@ -722,6 +723,32 @@ public:
virtual Error buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_size, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
virtual Vector<uint8_t> buffer_get_data(RID p_buffer) = 0; //this causes stall, only use to retrieve large buffers for saving
+ /******************************************/
+ /**** PIPELINE SPECIALIZATION CONSTANT ****/
+ /******************************************/
+
+ enum PipelineSpecializationConstantType {
+ PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL,
+ PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT,
+ PIPELINE_SPECIALIZATION_CONSTANT_TYPE_FLOAT,
+ };
+
+ struct PipelineSpecializationConstant {
+ PipelineSpecializationConstantType type;
+ uint32_t constant_id;
+ union {
+ uint32_t int_value;
+ float float_value;
+ bool bool_value;
+ };
+
+ PipelineSpecializationConstant() {
+ type = PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL;
+ constant_id = 0;
+ int_value = 0;
+ }
+ };
+
/*************************/
/**** RENDER PIPELINE ****/
/*************************/
@@ -978,13 +1005,13 @@ public:
};
virtual bool render_pipeline_is_valid(RID p_pipeline) = 0;
- virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0, uint32_t p_for_render_pass = 0) = 0;
+ virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0, uint32_t p_for_render_pass = 0, const Vector<PipelineSpecializationConstant> &p_specialization_constants = Vector<PipelineSpecializationConstant>()) = 0;
/**************************/
/**** COMPUTE PIPELINE ****/
/**************************/
- virtual RID compute_pipeline_create(RID p_shader) = 0;
+ virtual RID compute_pipeline_create(RID p_shader, const Vector<PipelineSpecializationConstant> &p_specialization_constants = Vector<PipelineSpecializationConstant>()) = 0;
virtual bool compute_pipeline_is_valid(RID p_pipeline) = 0;
/****************/
@@ -1173,7 +1200,8 @@ protected:
Error _buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL);
- RID _render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags = 0, uint32_t p_for_render_pass = 0);
+ RID _render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags, uint32_t p_for_render_pass, const TypedArray<RDPipelineSpecializationConstant> &p_specialization_constants);
+ RID _compute_pipeline_create(RID p_shader, const TypedArray<RDPipelineSpecializationConstant> &p_specialization_constants);
Vector<int64_t> _draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), const TypedArray<RID> &p_storage_textures = TypedArray<RID>());
void _draw_list_set_push_constant(DrawListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size);
@@ -1205,6 +1233,7 @@ VARIANT_ENUM_CAST(RenderingDevice::LogicOperation)
VARIANT_ENUM_CAST(RenderingDevice::BlendFactor)
VARIANT_ENUM_CAST(RenderingDevice::BlendOperation)
VARIANT_ENUM_CAST(RenderingDevice::PipelineDynamicStateFlags)
+VARIANT_ENUM_CAST(RenderingDevice::PipelineSpecializationConstantType)
VARIANT_ENUM_CAST(RenderingDevice::InitialAction)
VARIANT_ENUM_CAST(RenderingDevice::FinalAction)
VARIANT_ENUM_CAST(RenderingDevice::Limit)
diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h
index dc59568ce9..1af427b356 100644
--- a/servers/rendering/rendering_device_binds.h
+++ b/servers/rendering/rendering_device_binds.h
@@ -452,6 +452,41 @@ protected:
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_ids", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "_set_ids", "get_ids");
}
};
+
+class RDPipelineSpecializationConstant : public RefCounted {
+ GDCLASS(RDPipelineSpecializationConstant, RefCounted)
+ friend class RenderingDevice;
+
+ Variant value = false;
+ uint32_t constant_id;
+
+public:
+ void set_value(const Variant &p_value) {
+ ERR_FAIL_COND(p_value.get_type() != Variant::BOOL && p_value.get_type() != Variant::INT && p_value.get_type() != Variant::FLOAT);
+ value = p_value;
+ }
+ Variant get_value() const { return value; }
+
+ void set_constant_id(uint32_t p_id) {
+ constant_id = p_id;
+ }
+ uint32_t get_constant_id() const {
+ return constant_id;
+ }
+
+protected:
+ static void _bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_value", "value"), &RDPipelineSpecializationConstant::set_value);
+ ClassDB::bind_method(D_METHOD("get_value"), &RDPipelineSpecializationConstant::get_value);
+
+ ClassDB::bind_method(D_METHOD("set_constant_id", "constant_id"), &RDPipelineSpecializationConstant::set_constant_id);
+ ClassDB::bind_method(D_METHOD("get_constant_id"), &RDPipelineSpecializationConstant::get_constant_id);
+
+ ADD_PROPERTY(PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "set_value", "get_value");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "constant_id", PROPERTY_HINT_RANGE, "0,65535,0"), "set_constant_id", "get_constant_id");
+ }
+};
+
class RDPipelineRasterizationState : public RefCounted {
GDCLASS(RDPipelineRasterizationState, RefCounted)
friend class RenderingDevice;
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index 48c96cb02a..79665dcdd2 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -577,7 +577,7 @@ public:
FUNC1RC(float, viewport_get_measured_render_time_cpu, RID)
FUNC1RC(float, viewport_get_measured_render_time_gpu, RID)
- FUNC1(call_set_use_vsync, bool)
+ FUNC2(call_set_vsync_mode, DisplayServer::VSyncMode, DisplayServer::WindowID)
/* ENVIRONMENT API */
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index e260ff99a1..0d01d4a2bd 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -1454,7 +1454,7 @@ public:
virtual void set_debug_generate_wireframes(bool p_generate) = 0;
- virtual void call_set_use_vsync(bool p_enable) = 0;
+ virtual void call_set_vsync_mode(DisplayServer::VSyncMode p_mode, DisplayServer::WindowID p_window) = 0;
virtual bool is_low_end() const = 0;
diff --git a/servers/text_server.cpp b/servers/text_server.cpp
index 6f48148cab..97cfe828f0 100644
--- a/servers/text_server.cpp
+++ b/servers/text_server.cpp
@@ -331,6 +331,9 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("shaped_text_get_line_breaks_adv", "shaped", "width", "start", "once", "break_flags"), &TextServer::_shaped_text_get_line_breaks_adv, DEFVAL(0), DEFVAL(true), DEFVAL(BREAK_MANDATORY | BREAK_WORD_BOUND));
ClassDB::bind_method(D_METHOD("shaped_text_get_line_breaks", "shaped", "width", "start", "break_flags"), &TextServer::_shaped_text_get_line_breaks, DEFVAL(0), DEFVAL(BREAK_MANDATORY | BREAK_WORD_BOUND));
ClassDB::bind_method(D_METHOD("shaped_text_get_word_breaks", "shaped"), &TextServer::_shaped_text_get_word_breaks);
+
+ ClassDB::bind_method(D_METHOD("shaped_text_overrun_trim_to_width", "shaped", "width", "overrun_trim_flags"), &TextServer::shaped_text_overrun_trim_to_width, DEFVAL(0), DEFVAL(OVERRUN_NO_TRIMMING));
+
ClassDB::bind_method(D_METHOD("shaped_text_get_objects", "shaped"), &TextServer::shaped_text_get_objects);
ClassDB::bind_method(D_METHOD("shaped_text_get_object_rect", "shaped", "key"), &TextServer::shaped_text_get_object_rect);
@@ -381,6 +384,13 @@ void TextServer::_bind_methods() {
BIND_ENUM_CONSTANT(BREAK_WORD_BOUND);
BIND_ENUM_CONSTANT(BREAK_GRAPHEME_BOUND);
+ /* TextOverrunFlag */
+ BIND_ENUM_CONSTANT(OVERRUN_NO_TRIMMING);
+ BIND_ENUM_CONSTANT(OVERRUN_TRIM);
+ BIND_ENUM_CONSTANT(OVERRUN_TRIM_WORD_ONLY);
+ BIND_ENUM_CONSTANT(OVERRUN_ADD_ELLIPSIS);
+ BIND_ENUM_CONSTANT(OVERRUN_ENFORCE_ELLIPSIS);
+
/* GraphemeFlag */
BIND_ENUM_CONSTANT(GRAPHEME_IS_RTL);
BIND_ENUM_CONSTANT(GRAPHEME_IS_VIRTUAL);
@@ -646,7 +656,7 @@ Vector<Vector2i> TextServer::shaped_text_get_line_breaks(RID p_shaped, float p_w
float width = 0.f;
int line_start = MAX(p_start, range.x);
int last_safe_break = -1;
-
+ int word_count = 0;
int l_size = logical.size();
const Glyph *l_gl = logical.ptr();
@@ -655,12 +665,15 @@ Vector<Vector2i> TextServer::shaped_text_get_line_breaks(RID p_shaped, float p_w
continue;
}
if (l_gl[i].count > 0) {
- if ((p_width > 0) && (width + l_gl[i].advance > p_width) && (last_safe_break >= 0)) {
+ //Ignore trailing spaces.
+ bool is_space = (l_gl[i].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE;
+ if ((p_width > 0) && (width + (is_space ? 0 : l_gl[i].advance) > p_width) && (last_safe_break >= 0)) {
lines.push_back(Vector2i(line_start, l_gl[last_safe_break].end));
line_start = l_gl[last_safe_break].end;
i = last_safe_break;
last_safe_break = -1;
width = 0;
+ word_count = 0;
continue;
}
if ((p_break_flags & BREAK_MANDATORY) == BREAK_MANDATORY) {
@@ -675,8 +688,12 @@ Vector<Vector2i> TextServer::shaped_text_get_line_breaks(RID p_shaped, float p_w
if ((p_break_flags & BREAK_WORD_BOUND) == BREAK_WORD_BOUND) {
if ((l_gl[i].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT) {
last_safe_break = i;
+ word_count++;
}
}
+ if (((p_break_flags & BREAK_WORD_BOUND_ADAPTIVE) == BREAK_WORD_BOUND_ADAPTIVE) && word_count == 0) {
+ last_safe_break = i;
+ }
if ((p_break_flags & BREAK_GRAPHEME_BOUND) == BREAK_GRAPHEME_BOUND) {
last_safe_break = i;
}
diff --git a/servers/text_server.h b/servers/text_server.h
index 138ceb9356..06020d3ffd 100644
--- a/servers/text_server.h
+++ b/servers/text_server.h
@@ -66,8 +66,16 @@ public:
BREAK_NONE = 0,
BREAK_MANDATORY = 1 << 4,
BREAK_WORD_BOUND = 1 << 5,
- BREAK_GRAPHEME_BOUND = 1 << 6
- //RESERVED = 1 << 7
+ BREAK_GRAPHEME_BOUND = 1 << 6,
+ BREAK_WORD_BOUND_ADAPTIVE = 1 << 5 | 1 << 7
+ };
+
+ enum TextOverrunFlag {
+ OVERRUN_NO_TRIMMING = 0,
+ OVERRUN_TRIM = 1 << 0,
+ OVERRUN_TRIM_WORD_ONLY = 1 << 1,
+ OVERRUN_ADD_ELLIPSIS = 1 << 2,
+ OVERRUN_ENFORCE_ELLIPSIS = 1 << 3
};
enum GraphemeFlag {
@@ -138,7 +146,7 @@ public:
return true;
}
}
- return l.count > r.count; // Sort first glyoh with count & flags, order of the rest are irrelevant.
+ return l.count > r.count; // Sort first glyph with count & flags, order of the rest are irrelevant.
} else {
return l.start < r.start;
}
@@ -347,6 +355,9 @@ public:
virtual Vector<Vector2i> shaped_text_get_line_breaks_adv(RID p_shaped, const Vector<float> &p_width, int p_start = 0, bool p_once = true, uint8_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const;
virtual Vector<Vector2i> shaped_text_get_line_breaks(RID p_shaped, float p_width, int p_start = 0, uint8_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const;
virtual Vector<Vector2i> shaped_text_get_word_breaks(RID p_shaped) const;
+
+ virtual void shaped_text_overrun_trim_to_width(RID p_shaped, float p_width, uint8_t p_clip_flags) = 0;
+
virtual Array shaped_text_get_objects(RID p_shaped) const = 0;
virtual Rect2 shaped_text_get_object_rect(RID p_shaped, Variant p_key) const = 0;
@@ -461,6 +472,7 @@ VARIANT_ENUM_CAST(TextServer::Direction);
VARIANT_ENUM_CAST(TextServer::Orientation);
VARIANT_ENUM_CAST(TextServer::JustificationFlag);
VARIANT_ENUM_CAST(TextServer::LineBreakFlag);
+VARIANT_ENUM_CAST(TextServer::TextOverrunFlag);
VARIANT_ENUM_CAST(TextServer::GraphemeFlag);
VARIANT_ENUM_CAST(TextServer::Hinting);
VARIANT_ENUM_CAST(TextServer::Feature);
diff --git a/tests/test_object.h b/tests/test_object.h
index b7eedc2670..36f9ef2a51 100644
--- a/tests/test_object.h
+++ b/tests/test_object.h
@@ -206,7 +206,7 @@ TEST_CASE("[Object] Script instance property getter") {
}
TEST_CASE("[Object] Built-in property setter") {
- ClassDB::register_class<_TestDerivedObject>();
+ GDREGISTER_CLASS(_TestDerivedObject);
_TestDerivedObject derived_object;
bool valid = false;
@@ -218,7 +218,7 @@ TEST_CASE("[Object] Built-in property setter") {
}
TEST_CASE("[Object] Built-in property getter") {
- ClassDB::register_class<_TestDerivedObject>();
+ GDREGISTER_CLASS(_TestDerivedObject);
_TestDerivedObject derived_object;
derived_object.set_property(100);
diff --git a/thirdparty/README.md b/thirdparty/README.md
index 03a2ddf5e4..31e88180d0 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -616,6 +616,11 @@ Files extracted from upstream source:
- `include` folder
- `LICENSE`
+Some downstream changes have been made and are identified by
+`// -- GODOT begin --` and `// -- GODOT end --` comments.
+They can be reapplied using the patch included in the `patches`
+folder.
+
## squish
diff --git a/thirdparty/spirv-reflect/patches/specialization-constants.patch b/thirdparty/spirv-reflect/patches/specialization-constants.patch
new file mode 100644
index 0000000000..8ff1dcc2e5
--- /dev/null
+++ b/thirdparty/spirv-reflect/patches/specialization-constants.patch
@@ -0,0 +1,293 @@
+diff --git a/thirdparty/spirv-reflect/spirv_reflect.c b/thirdparty/spirv-reflect/spirv_reflect.c
+index 0fc979a8a4..3e3643717a 100644
+--- a/thirdparty/spirv-reflect/spirv_reflect.c
++++ b/thirdparty/spirv-reflect/spirv_reflect.c
+@@ -124,6 +124,9 @@ typedef struct Decorations {
+ NumberDecoration location;
+ NumberDecoration offset;
+ NumberDecoration uav_counter_buffer;
++// -- GODOT begin --
++ NumberDecoration specialization_constant;
++// -- GODOT end --
+ StringDecoration semantic;
+ uint32_t array_stride;
+ uint32_t matrix_stride;
+@@ -610,6 +613,9 @@ static SpvReflectResult ParseNodes(Parser* p_parser)
+ p_parser->nodes[i].decorations.offset.value = (uint32_t)INVALID_VALUE;
+ p_parser->nodes[i].decorations.uav_counter_buffer.value = (uint32_t)INVALID_VALUE;
+ p_parser->nodes[i].decorations.built_in = (SpvBuiltIn)INVALID_VALUE;
++// -- GODOT begin --
++ p_parser->nodes[i].decorations.specialization_constant.value = (SpvBuiltIn)INVALID_VALUE;
++// -- GODOT end --
+ }
+ // Mark source file id node
+ p_parser->source_file_id = (uint32_t)INVALID_VALUE;
+@@ -800,10 +806,16 @@ static SpvReflectResult ParseNodes(Parser* p_parser)
+ CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->result_id);
+ }
+ break;
+-
++// -- GODOT begin --
+ case SpvOpSpecConstantTrue:
+ case SpvOpSpecConstantFalse:
+- case SpvOpSpecConstant:
++ case SpvOpSpecConstant: {
++ CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_type_id);
++ CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->result_id);
++ p_node->is_type = true;
++ }
++ break;
++// -- GODOT end --
+ case SpvOpSpecConstantComposite:
+ case SpvOpSpecConstantOp: {
+ CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_type_id);
+@@ -1309,6 +1321,9 @@ static SpvReflectResult ParseDecorations(Parser* p_parser)
+ skip = true;
+ }
+ break;
++// -- GODOT begin --
++ case SpvDecorationSpecId:
++// -- GODOT end --
+ case SpvDecorationBlock:
+ case SpvDecorationBufferBlock:
+ case SpvDecorationColMajor:
+@@ -1441,7 +1456,14 @@ static SpvReflectResult ParseDecorations(Parser* p_parser)
+ p_target_decorations->input_attachment_index.word_offset = word_offset;
+ }
+ break;
+-
++// -- GODOT begin --
++ case SpvDecorationSpecId: {
++ uint32_t word_offset = p_node->word_offset + member_offset+ 3;
++ CHECKED_READU32(p_parser, word_offset, p_target_decorations->specialization_constant.value);
++ p_target_decorations->specialization_constant.word_offset = word_offset;
++ }
++ break;
++// -- GODOT end --
+ case SpvReflectDecorationHlslCounterBufferGOOGLE: {
+ uint32_t word_offset = p_node->word_offset + member_offset+ 3;
+ CHECKED_READU32(p_parser, word_offset, p_target_decorations->uav_counter_buffer.value);
+@@ -1731,6 +1753,13 @@ static SpvReflectResult ParseType(
+ p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_EXTERNAL_ACCELERATION_STRUCTURE;
+ }
+ break;
++// -- GODOT begin --
++ case SpvOpSpecConstantTrue:
++ case SpvOpSpecConstantFalse:
++ case SpvOpSpecConstant: {
++ }
++ break;
++// -- GODOT end --
+ }
+
+ if (result == SPV_REFLECT_RESULT_SUCCESS) {
+@@ -3187,6 +3216,69 @@ static SpvReflectResult ParseExecutionModes(Parser* p_parser, SpvReflectShaderMo
+ return SPV_REFLECT_RESULT_SUCCESS;
+ }
+
++// -- GODOT begin --
++static SpvReflectResult ParseSpecializationConstants(Parser* p_parser, SpvReflectShaderModule* p_module)
++{
++ p_module->specialization_constant_count = 0;
++ p_module->specialization_constants = NULL;
++ for (size_t i = 0; i < p_parser->node_count; ++i) {
++ Node* p_node = &(p_parser->nodes[i]);
++ if (p_node->op == SpvOpSpecConstantTrue || p_node->op == SpvOpSpecConstantFalse || p_node->op == SpvOpSpecConstant) {
++ p_module->specialization_constant_count++;
++ }
++ }
++
++ if (p_module->specialization_constant_count == 0) {
++ return SPV_REFLECT_RESULT_SUCCESS;
++ }
++
++ p_module->specialization_constants = (SpvReflectSpecializationConstant*)calloc(p_module->specialization_constant_count, sizeof(SpvReflectSpecializationConstant));
++
++ uint32_t index = 0;
++
++ for (size_t i = 0; i < p_parser->node_count; ++i) {
++ Node* p_node = &(p_parser->nodes[i]);
++ switch(p_node->op) {
++ default: continue;
++ case SpvOpSpecConstantTrue: {
++ p_module->specialization_constants[index].constant_type = SPV_REFLECT_SPECIALIZATION_CONSTANT_BOOL;
++ p_module->specialization_constants[index].default_value.int_bool_value = 1;
++ } break;
++ case SpvOpSpecConstantFalse: {
++ p_module->specialization_constants[index].constant_type = SPV_REFLECT_SPECIALIZATION_CONSTANT_BOOL;
++ p_module->specialization_constants[index].default_value.int_bool_value = 0;
++ } break;
++ case SpvOpSpecConstant: {
++ SpvReflectResult result = SPV_REFLECT_RESULT_SUCCESS;
++ uint32_t element_type_id = (uint32_t)INVALID_VALUE;
++ uint32_t default_value = 0;
++ IF_READU32(result, p_parser, p_node->word_offset + 1, element_type_id);
++ IF_READU32(result, p_parser, p_node->word_offset + 3, default_value);
++
++ Node* p_next_node = FindNode(p_parser, element_type_id);
++
++ if (p_next_node->op == SpvOpTypeInt) {
++ p_module->specialization_constants[index].constant_type = SPV_REFLECT_SPECIALIZATION_CONSTANT_INT;
++ } else if (p_next_node->op == SpvOpTypeFloat) {
++ p_module->specialization_constants[index].constant_type = SPV_REFLECT_SPECIALIZATION_CONSTANT_FLOAT;
++ } else {
++ return SPV_REFLECT_RESULT_ERROR_PARSE_FAILED;
++ }
++
++ p_module->specialization_constants[index].default_value.int_bool_value = default_value; //bits are the same for int and float
++ } break;
++ }
++
++ p_module->specialization_constants[index].name = p_node->name;
++ p_module->specialization_constants[index].constant_id = p_node->decorations.specialization_constant.value;
++ p_module->specialization_constants[index].spirv_id = p_node->result_id;
++ index++;
++ }
++
++ return SPV_REFLECT_RESULT_SUCCESS;
++}
++// -- GODOT end --
++
+ static SpvReflectResult ParsePushConstantBlocks(Parser* p_parser, SpvReflectShaderModule* p_module)
+ {
+ for (size_t i = 0; i < p_parser->node_count; ++i) {
+@@ -3562,6 +3654,12 @@ SpvReflectResult spvReflectCreateShaderModule(
+ result = ParsePushConstantBlocks(&parser, p_module);
+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
+ }
++// -- GODOT begin --
++ if (result == SPV_REFLECT_RESULT_SUCCESS) {
++ result = ParseSpecializationConstants(&parser, p_module);
++ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
++ }
++// -- GODOT end --
+ if (result == SPV_REFLECT_RESULT_SUCCESS) {
+ result = ParseEntryPoints(&parser, p_module);
+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
+@@ -3691,6 +3789,9 @@ void spvReflectDestroyShaderModule(SpvReflectShaderModule* p_module)
+ SafeFree(p_entry->used_push_constants);
+ }
+ SafeFree(p_module->entry_points);
++// -- GODOT begin --
++ SafeFree(p_module->specialization_constants);
++// -- GODOT end --
+
+ // Push constants
+ for (size_t i = 0; i < p_module->push_constant_block_count; ++i) {
+@@ -3959,6 +4060,38 @@ SpvReflectResult spvReflectEnumerateEntryPointInterfaceVariables(
+ return SPV_REFLECT_RESULT_SUCCESS;
+ }
+
++// -- GODOT begin --
++SpvReflectResult spvReflectEnumerateSpecializationConstants(
++ const SpvReflectShaderModule* p_module,
++ uint32_t* p_count,
++ SpvReflectSpecializationConstant** pp_constants
++)
++{
++ if (IsNull(p_module)) {
++ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
++ }
++ if (IsNull(p_count)) {
++ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
++ }
++
++ if (IsNotNull(pp_constants)) {
++ if (*p_count != p_module->specialization_constant_count) {
++ return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;
++ }
++
++ for (uint32_t index = 0; index < *p_count; ++index) {
++ SpvReflectSpecializationConstant *p_const = &p_module->specialization_constants[index];
++ pp_constants[index] = p_const;
++ }
++ }
++ else {
++ *p_count = p_module->specialization_constant_count;
++ }
++
++ return SPV_REFLECT_RESULT_SUCCESS;
++}
++// -- GODOT end --
++
+ SpvReflectResult spvReflectEnumerateInputVariables(
+ const SpvReflectShaderModule* p_module,
+ uint32_t* p_count,
+diff --git a/thirdparty/spirv-reflect/spirv_reflect.h b/thirdparty/spirv-reflect/spirv_reflect.h
+index a5a956e9e8..21f8160770 100644
+--- a/thirdparty/spirv-reflect/spirv_reflect.h
++++ b/thirdparty/spirv-reflect/spirv_reflect.h
+@@ -292,6 +292,28 @@ typedef struct SpvReflectTypeDescription {
+ struct SpvReflectTypeDescription* members;
+ } SpvReflectTypeDescription;
+
++// -- GODOT begin --
++/*! @struct SpvReflectSpecializationConstant
++
++*/
++
++typedef enum SpvReflectSpecializationConstantType {
++ SPV_REFLECT_SPECIALIZATION_CONSTANT_BOOL = 0,
++ SPV_REFLECT_SPECIALIZATION_CONSTANT_INT = 1,
++ SPV_REFLECT_SPECIALIZATION_CONSTANT_FLOAT = 2,
++} SpvReflectSpecializationConstantType;
++
++typedef struct SpvReflectSpecializationConstant {
++ const char* name;
++ uint32_t spirv_id;
++ uint32_t constant_id;
++ SpvReflectSpecializationConstantType constant_type;
++ union {
++ float float_value;
++ uint32_t int_bool_value;
++ } default_value;
++} SpvReflectSpecializationConstant;
++// -- GODOT end --
+
+ /*! @struct SpvReflectInterfaceVariable
+
+@@ -439,6 +461,10 @@ typedef struct SpvReflectShaderModule {
+ SpvReflectInterfaceVariable* interface_variables;
+ uint32_t push_constant_block_count;
+ SpvReflectBlockVariable* push_constant_blocks;
++ // -- GODOT begin --
++ uint32_t specialization_constant_count;
++ SpvReflectSpecializationConstant* specialization_constants;
++ // -- GODOT end --
+
+ struct Internal {
+ size_t spirv_size;
+@@ -694,6 +720,33 @@ SpvReflectResult spvReflectEnumerateInputVariables(
+ SpvReflectInterfaceVariable** pp_variables
+ );
+
++// -- GOODT begin --
++/*! @fn spvReflectEnumerateSpecializationConstants
++ @brief If the module contains multiple entry points, this will only get
++ the specialization constants for the first one.
++ @param p_module Pointer to an instance of SpvReflectShaderModule.
++ @param p_count If pp_constants is NULL, the module's specialization constant
++ count will be stored here.
++ If pp_variables is not NULL, *p_count must contain
++ the module's specialization constant count.
++ @param pp_variables If NULL, the module's specialization constant count will be
++ written to *p_count.
++ If non-NULL, pp_constants must point to an array with
++ *p_count entries, where pointers to the module's
++ specialization constants will be written. The caller must not
++ free the specialization constants written to this array.
++ @return If successful, returns SPV_REFLECT_RESULT_SUCCESS.
++ Otherwise, the error code indicates the cause of the
++ failure.
++
++*/
++SpvReflectResult spvReflectEnumerateSpecializationConstants(
++ const SpvReflectShaderModule* p_module,
++ uint32_t* p_count,
++ SpvReflectSpecializationConstant** pp_constants
++);
++// -- GODOT end --
++
+ /*! @fn spvReflectEnumerateEntryPointInputVariables
+ @brief Enumerate the input variables for a given entry point.
+ @param entry_point The name of the entry point to get the input variables for.
diff --git a/thirdparty/spirv-reflect/spirv_reflect.c b/thirdparty/spirv-reflect/spirv_reflect.c
index 0fc979a8a4..8f614c8874 100644
--- a/thirdparty/spirv-reflect/spirv_reflect.c
+++ b/thirdparty/spirv-reflect/spirv_reflect.c
@@ -124,6 +124,9 @@ typedef struct Decorations {
NumberDecoration location;
NumberDecoration offset;
NumberDecoration uav_counter_buffer;
+// -- GODOT begin --
+ NumberDecoration specialization_constant;
+// -- GODOT end --
StringDecoration semantic;
uint32_t array_stride;
uint32_t matrix_stride;
@@ -610,6 +613,9 @@ static SpvReflectResult ParseNodes(Parser* p_parser)
p_parser->nodes[i].decorations.offset.value = (uint32_t)INVALID_VALUE;
p_parser->nodes[i].decorations.uav_counter_buffer.value = (uint32_t)INVALID_VALUE;
p_parser->nodes[i].decorations.built_in = (SpvBuiltIn)INVALID_VALUE;
+// -- GODOT begin --
+ p_parser->nodes[i].decorations.specialization_constant.value = (SpvBuiltIn)INVALID_VALUE;
+// -- GODOT end --
}
// Mark source file id node
p_parser->source_file_id = (uint32_t)INVALID_VALUE;
@@ -800,10 +806,16 @@ static SpvReflectResult ParseNodes(Parser* p_parser)
CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->result_id);
}
break;
-
+// -- GODOT begin --
case SpvOpSpecConstantTrue:
case SpvOpSpecConstantFalse:
- case SpvOpSpecConstant:
+ case SpvOpSpecConstant: {
+ CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_type_id);
+ CHECKED_READU32(p_parser, p_node->word_offset + 2, p_node->result_id);
+ p_node->is_type = true;
+ }
+ break;
+// -- GODOT end --
case SpvOpSpecConstantComposite:
case SpvOpSpecConstantOp: {
CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_type_id);
@@ -1309,6 +1321,9 @@ static SpvReflectResult ParseDecorations(Parser* p_parser)
skip = true;
}
break;
+// -- GODOT begin --
+ case SpvDecorationSpecId:
+// -- GODOT end --
case SpvDecorationBlock:
case SpvDecorationBufferBlock:
case SpvDecorationColMajor:
@@ -1441,7 +1456,14 @@ static SpvReflectResult ParseDecorations(Parser* p_parser)
p_target_decorations->input_attachment_index.word_offset = word_offset;
}
break;
-
+// -- GODOT begin --
+ case SpvDecorationSpecId: {
+ uint32_t word_offset = p_node->word_offset + member_offset+ 3;
+ CHECKED_READU32(p_parser, word_offset, p_target_decorations->specialization_constant.value);
+ p_target_decorations->specialization_constant.word_offset = word_offset;
+ }
+ break;
+// -- GODOT end --
case SpvReflectDecorationHlslCounterBufferGOOGLE: {
uint32_t word_offset = p_node->word_offset + member_offset+ 3;
CHECKED_READU32(p_parser, word_offset, p_target_decorations->uav_counter_buffer.value);
@@ -1731,6 +1753,13 @@ static SpvReflectResult ParseType(
p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_EXTERNAL_ACCELERATION_STRUCTURE;
}
break;
+// -- GODOT begin --
+ case SpvOpSpecConstantTrue:
+ case SpvOpSpecConstantFalse:
+ case SpvOpSpecConstant: {
+ }
+ break;
+// -- GODOT end --
}
if (result == SPV_REFLECT_RESULT_SUCCESS) {
@@ -3187,6 +3216,69 @@ static SpvReflectResult ParseExecutionModes(Parser* p_parser, SpvReflectShaderMo
return SPV_REFLECT_RESULT_SUCCESS;
}
+// -- GODOT begin --
+static SpvReflectResult ParseSpecializationConstants(Parser* p_parser, SpvReflectShaderModule* p_module)
+{
+ p_module->specialization_constant_count = 0;
+ p_module->specialization_constants = NULL;
+ for (size_t i = 0; i < p_parser->node_count; ++i) {
+ Node* p_node = &(p_parser->nodes[i]);
+ if (p_node->op == SpvOpSpecConstantTrue || p_node->op == SpvOpSpecConstantFalse || p_node->op == SpvOpSpecConstant) {
+ p_module->specialization_constant_count++;
+ }
+ }
+
+ if (p_module->specialization_constant_count == 0) {
+ return SPV_REFLECT_RESULT_SUCCESS;
+ }
+
+ p_module->specialization_constants = (SpvReflectSpecializationConstant*)calloc(p_module->specialization_constant_count, sizeof(SpvReflectSpecializationConstant));
+
+ uint32_t index = 0;
+
+ for (size_t i = 0; i < p_parser->node_count; ++i) {
+ Node* p_node = &(p_parser->nodes[i]);
+ switch(p_node->op) {
+ default: continue;
+ case SpvOpSpecConstantTrue: {
+ p_module->specialization_constants[index].constant_type = SPV_REFLECT_SPECIALIZATION_CONSTANT_BOOL;
+ p_module->specialization_constants[index].default_value.int_bool_value = 1;
+ } break;
+ case SpvOpSpecConstantFalse: {
+ p_module->specialization_constants[index].constant_type = SPV_REFLECT_SPECIALIZATION_CONSTANT_BOOL;
+ p_module->specialization_constants[index].default_value.int_bool_value = 0;
+ } break;
+ case SpvOpSpecConstant: {
+ SpvReflectResult result = SPV_REFLECT_RESULT_SUCCESS;
+ uint32_t element_type_id = (uint32_t)INVALID_VALUE;
+ uint32_t default_value = 0;
+ IF_READU32(result, p_parser, p_node->word_offset + 1, element_type_id);
+ IF_READU32(result, p_parser, p_node->word_offset + 3, default_value);
+
+ Node* p_next_node = FindNode(p_parser, element_type_id);
+
+ if (p_next_node->op == SpvOpTypeInt) {
+ p_module->specialization_constants[index].constant_type = SPV_REFLECT_SPECIALIZATION_CONSTANT_INT;
+ } else if (p_next_node->op == SpvOpTypeFloat) {
+ p_module->specialization_constants[index].constant_type = SPV_REFLECT_SPECIALIZATION_CONSTANT_FLOAT;
+ } else {
+ return SPV_REFLECT_RESULT_ERROR_PARSE_FAILED;
+ }
+
+ p_module->specialization_constants[index].default_value.int_bool_value = default_value; //bits are the same for int and float
+ } break;
+ }
+
+ p_module->specialization_constants[index].name = p_node->name;
+ p_module->specialization_constants[index].constant_id = p_node->decorations.specialization_constant.value;
+ p_module->specialization_constants[index].spirv_id = p_node->result_id;
+ index++;
+ }
+
+ return SPV_REFLECT_RESULT_SUCCESS;
+}
+// -- GODOT end --
+
static SpvReflectResult ParsePushConstantBlocks(Parser* p_parser, SpvReflectShaderModule* p_module)
{
for (size_t i = 0; i < p_parser->node_count; ++i) {
@@ -3562,6 +3654,12 @@ SpvReflectResult spvReflectCreateShaderModule(
result = ParsePushConstantBlocks(&parser, p_module);
SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
}
+// -- GODOT begin --
+ if (result == SPV_REFLECT_RESULT_SUCCESS) {
+ result = ParseSpecializationConstants(&parser, p_module);
+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
+ }
+// -- GODOT end --
if (result == SPV_REFLECT_RESULT_SUCCESS) {
result = ParseEntryPoints(&parser, p_module);
SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
@@ -3691,6 +3789,9 @@ void spvReflectDestroyShaderModule(SpvReflectShaderModule* p_module)
SafeFree(p_entry->used_push_constants);
}
SafeFree(p_module->entry_points);
+// -- GODOT begin --
+ SafeFree(p_module->specialization_constants);
+// -- GODOT end --
// Push constants
for (size_t i = 0; i < p_module->push_constant_block_count; ++i) {
@@ -3959,6 +4060,38 @@ SpvReflectResult spvReflectEnumerateEntryPointInterfaceVariables(
return SPV_REFLECT_RESULT_SUCCESS;
}
+// -- GODOT begin --
+SpvReflectResult spvReflectEnumerateSpecializationConstants(
+ const SpvReflectShaderModule* p_module,
+ uint32_t* p_count,
+ SpvReflectSpecializationConstant** pp_constants
+)
+{
+ if (IsNull(p_module)) {
+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
+ }
+ if (IsNull(p_count)) {
+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
+ }
+
+ if (IsNotNull(pp_constants)) {
+ if (*p_count != p_module->specialization_constant_count) {
+ return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;
+ }
+
+ for (uint32_t index = 0; index < *p_count; ++index) {
+ SpvReflectSpecializationConstant *p_const = &p_module->specialization_constants[index];
+ pp_constants[index] = p_const;
+ }
+ }
+ else {
+ *p_count = p_module->specialization_constant_count;
+ }
+
+ return SPV_REFLECT_RESULT_SUCCESS;
+}
+// -- GODOT end --
+
SpvReflectResult spvReflectEnumerateInputVariables(
const SpvReflectShaderModule* p_module,
uint32_t* p_count,
diff --git a/thirdparty/spirv-reflect/spirv_reflect.h b/thirdparty/spirv-reflect/spirv_reflect.h
index a5a956e9e8..21f8160770 100644
--- a/thirdparty/spirv-reflect/spirv_reflect.h
+++ b/thirdparty/spirv-reflect/spirv_reflect.h
@@ -292,6 +292,28 @@ typedef struct SpvReflectTypeDescription {
struct SpvReflectTypeDescription* members;
} SpvReflectTypeDescription;
+// -- GODOT begin --
+/*! @struct SpvReflectSpecializationConstant
+
+*/
+
+typedef enum SpvReflectSpecializationConstantType {
+ SPV_REFLECT_SPECIALIZATION_CONSTANT_BOOL = 0,
+ SPV_REFLECT_SPECIALIZATION_CONSTANT_INT = 1,
+ SPV_REFLECT_SPECIALIZATION_CONSTANT_FLOAT = 2,
+} SpvReflectSpecializationConstantType;
+
+typedef struct SpvReflectSpecializationConstant {
+ const char* name;
+ uint32_t spirv_id;
+ uint32_t constant_id;
+ SpvReflectSpecializationConstantType constant_type;
+ union {
+ float float_value;
+ uint32_t int_bool_value;
+ } default_value;
+} SpvReflectSpecializationConstant;
+// -- GODOT end --
/*! @struct SpvReflectInterfaceVariable
@@ -439,6 +461,10 @@ typedef struct SpvReflectShaderModule {
SpvReflectInterfaceVariable* interface_variables;
uint32_t push_constant_block_count;
SpvReflectBlockVariable* push_constant_blocks;
+ // -- GODOT begin --
+ uint32_t specialization_constant_count;
+ SpvReflectSpecializationConstant* specialization_constants;
+ // -- GODOT end --
struct Internal {
size_t spirv_size;
@@ -694,6 +720,33 @@ SpvReflectResult spvReflectEnumerateInputVariables(
SpvReflectInterfaceVariable** pp_variables
);
+// -- GOODT begin --
+/*! @fn spvReflectEnumerateSpecializationConstants
+ @brief If the module contains multiple entry points, this will only get
+ the specialization constants for the first one.
+ @param p_module Pointer to an instance of SpvReflectShaderModule.
+ @param p_count If pp_constants is NULL, the module's specialization constant
+ count will be stored here.
+ If pp_variables is not NULL, *p_count must contain
+ the module's specialization constant count.
+ @param pp_variables If NULL, the module's specialization constant count will be
+ written to *p_count.
+ If non-NULL, pp_constants must point to an array with
+ *p_count entries, where pointers to the module's
+ specialization constants will be written. The caller must not
+ free the specialization constants written to this array.
+ @return If successful, returns SPV_REFLECT_RESULT_SUCCESS.
+ Otherwise, the error code indicates the cause of the
+ failure.
+
+*/
+SpvReflectResult spvReflectEnumerateSpecializationConstants(
+ const SpvReflectShaderModule* p_module,
+ uint32_t* p_count,
+ SpvReflectSpecializationConstant** pp_constants
+);
+// -- GODOT end --
+
/*! @fn spvReflectEnumerateEntryPointInputVariables
@brief Enumerate the input variables for a given entry point.
@param entry_point The name of the entry point to get the input variables for.