diff options
268 files changed, 4286 insertions, 2749 deletions
diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index ace1ce3fec..1b68f66956 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -85,7 +85,7 @@ jobs: echo "Running --doctool to see if this changes the public API without updating the documentation." echo -e "If a diff is shown, it means that your code/doc changes are incomplete and you should update the class reference with --doctool.\n\n" VK_ICD_FILENAMES=$(pwd)/vk_swiftshader_icd.json DRI_PRIME=0 xvfb-run bin/godot.linuxbsd.opt.tools.64 --doctool . 2>&1 > /dev/null || true - git diff --color --exit-code + git diff --color --exit-code && ! git ls-files --others --exclude-standard | sed -e 's/^/New doc file missing in PR: /' | grep 'xml$' - uses: actions/upload-artifact@v2 with: 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) @@ -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/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/io/compression.cpp b/core/io/compression.cpp index ca56509253..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); } 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.h b/core/object/object.h index 8389d80afc..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) 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/register_core_types.cpp b/core/register_core_types.cpp index 0739a0336d..eb37267546 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -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<MultiplayerPeer>(); - 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/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/core/variant/variant_op.h b/core/variant/variant_op.h index e744e76ea3..cbdd60f404 100644 --- a/core/variant/variant_op.h +++ b/core/variant/variant_op.h @@ -1261,8 +1261,10 @@ public: const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); - b->get(a, &r_valid); - *r_ret = r_valid; + bool exist; + b->get(a, &exist); + *r_ret = exist; + r_valid = true; } static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { Object *l = right->get_validated_object(); @@ -1293,8 +1295,10 @@ public: const StringName &a = *VariantGetInternalPtr<StringName>::get_ptr(&p_left); - b->get(a, &r_valid); - *r_ret = r_valid; + bool exist; + b->get(a, &exist); + *r_ret = exist; + r_valid = true; } static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { Object *l = right->get_validated_object(); 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/BaseButton.xml b/doc/classes/BaseButton.xml index f7e31f5f9c..d842bac54a 100644 --- a/doc/classes/BaseButton.xml +++ b/doc/classes/BaseButton.xml @@ -39,6 +39,16 @@ Returns [code]true[/code] if the mouse has entered the button and has not left it yet. </description> </method> + <method name="set_pressed_no_signal"> + <return type="void"> + </return> + <argument index="0" name="pressed" type="bool"> + </argument> + <description> + Changes the [member pressed] state of the button, without emitting [signal toggled]. Use when you just want to change the state of the button without sending the pressed event (e.g. when initializing scene). Only works if [member toggle_mode] is [code]true[/code]. + [b]Note:[/b] This method doesn't unpress other buttons in [member button_group]. + </description> + </method> </methods> <members> <member name="action_mode" type="int" setter="set_action_mode" getter="get_action_mode" enum="BaseButton.ActionMode" default="1"> @@ -60,7 +70,8 @@ [b]Note:[/b] This property only affects the button's visual appearance. Signals will be emitted at the same moment regardless of this property's value. </member> <member name="pressed" type="bool" setter="set_pressed" getter="is_pressed" default="false"> - If [code]true[/code], the button's state is pressed. Means the button is pressed down or toggled (if [member toggle_mode] is active). + If [code]true[/code], the button's state is pressed. Means the button is pressed down or toggled (if [member toggle_mode] is active). Only works if [member toggle_mode] is [code]true[/code]. + [b]Note:[/b] Setting [member pressed] will result in [signal toggled] to be emitted. If you want to change the pressed state without emitting that signal, use [method set_pressed_no_signal]. </member> <member name="shortcut" type="Shortcut" setter="set_shortcut" getter="get_shortcut"> [Shortcut] associated to the button. diff --git a/doc/classes/CPUParticles2D.xml b/doc/classes/CPUParticles2D.xml index 9620e9abd1..22f070b73b 100644 --- a/doc/classes/CPUParticles2D.xml +++ b/doc/classes/CPUParticles2D.xml @@ -152,7 +152,7 @@ Each particle's initial color. If [member texture] is defined, it will be multiplied by this color. </member> <member name="color_ramp" type="Gradient" setter="set_color_ramp" getter="get_color_ramp"> - Each particle's color will vary along this [Gradient]. + Each particle's color will vary along this [Gradient] (multiplied with [member color]). </member> <member name="damping" type="float" setter="set_param" getter="get_param" default="0.0"> The rate at which particles lose velocity. diff --git a/doc/classes/CPUParticles3D.xml b/doc/classes/CPUParticles3D.xml index 7509775d20..d7a89eef11 100644 --- a/doc/classes/CPUParticles3D.xml +++ b/doc/classes/CPUParticles3D.xml @@ -148,10 +148,10 @@ Animation speed randomness ratio. </member> <member name="color" type="Color" setter="set_color" getter="get_color" default="Color(1, 1, 1, 1)"> - Unused for 3D particles. + Each particle's initial color. To have particle display color in a [BaseMaterial3D] make sure to set [member BaseMaterial3D.vertex_color_use_as_albedo] to [code]true[/code]. </member> <member name="color_ramp" type="Gradient" setter="set_color_ramp" getter="get_color_ramp"> - Unused for 3D particles. + Each particle's color will vary along this [GradientTexture] over its lifetime (multiplied with [member color]). </member> <member name="damping" type="float" setter="set_param" getter="get_param" default="0.0"> The rate at which particles lose velocity. diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index 47e26b7a2e..23cbdd8cab 100644 --- a/doc/classes/Control.xml +++ b/doc/classes/Control.xml @@ -235,22 +235,25 @@ <argument index="1" name="color" type="Color"> </argument> <description> - Overrides the [Color] with given [code]name[/code] in the [member theme] resource the control uses. + Creates a local override for a theme [Color] with the specified [code]name[/code]. Local overrides always take precedence when fetching theme items for the control. An override can be removed with [method remove_theme_color_override]. + See also [method get_theme_color]. [b]Example of overriding a label's color and resetting it later:[/b] [codeblocks] [gdscript] - # Override the child node "MyLabel"'s font color to orange. + # Given the child Label node "MyLabel", override its font color with a custom value. $MyLabel.add_theme_color_override("font_color", Color(1, 0.5, 0)) - # Reset the color by creating a new node to get the default value: - var default_label_color = Label.new().get_theme_color("font_color") - $MyLabel.add_theme_color_override("font_color", default_label_color) + # Reset the font color of the child label. + $MyLabel.remove_theme_color_override("font_color") + # Alternatively it can be overridden with the default value from the Label type. + $MyLabel.add_theme_color_override("font_color", get_theme_color("font_color", "Label")) [/gdscript] [csharp] - // Override the child node "MyLabel"'s font color to orange. - GetNode<Label>("MyLabel").AddThemeColorOverride("font_color", new Color(1, 0.5f, 0)); - // Reset the color by creating a new node to get the default value: - var defaultLabelColor = new Label().GetThemeColor("font_color"); - GetNode<Label>("MyLabel").AddThemeColorOverride("font_color", defaultLabelColor); + // Given the child Label node "MyLabel", override its font color with a custom value. + GetNode<Label>("MyLabel").AddThemeColorOverride("font_color", new Color(1, 0.5f, 0)) + // Reset the font color of the child label. + GetNode<Label>("MyLabel").RemoveThemeColorOverride("font_color") + // Alternatively it can be overridden with the default value from the Label type. + GetNode<Label>("MyLabel").AddThemeColorOverride("font_color", GetThemeColor("font_color", "Label")) [/csharp] [/codeblocks] </description> @@ -263,7 +266,8 @@ <argument index="1" name="constant" type="int"> </argument> <description> - Overrides an integer constant with given [code]name[/code] in the [member theme] resource the control uses. + Creates a local override for a theme constant with the specified [code]name[/code]. Local overrides always take precedence when fetching theme items for the control. An override can be removed with [method remove_theme_constant_override]. + See also [method get_theme_constant]. </description> </method> <method name="add_theme_font_override"> @@ -274,7 +278,8 @@ <argument index="1" name="font" type="Font"> </argument> <description> - Overrides the font with given [code]name[/code] in the [member theme] resource the control uses. + Creates a local override for a theme [Font] with the specified [code]name[/code]. Local overrides always take precedence when fetching theme items for the control. An override can be removed with [method remove_theme_font_override]. + See also [method get_theme_font]. </description> </method> <method name="add_theme_font_size_override"> @@ -285,7 +290,8 @@ <argument index="1" name="font_size" type="int"> </argument> <description> - Overrides the font size with given [code]name[/code] in the [member theme] resource the control uses. + Creates a local override for a theme font size with the specified [code]name[/code]. Local overrides always take precedence when fetching theme items for the control. An override can be removed with [method remove_theme_font_size_override]. + See also [method get_theme_font_size]. </description> </method> <method name="add_theme_icon_override"> @@ -296,7 +302,8 @@ <argument index="1" name="texture" type="Texture2D"> </argument> <description> - Overrides the icon with given [code]name[/code] in the [member theme] resource the control uses. + Creates a local override for a theme icon with the specified [code]name[/code]. Local overrides always take precedence when fetching theme items for the control. An override can be removed with [method remove_theme_icon_override]. + See also [method get_theme_icon]. </description> </method> <method name="add_theme_stylebox_override"> @@ -307,7 +314,8 @@ <argument index="1" name="stylebox" type="StyleBox"> </argument> <description> - Overrides the [StyleBox] with given [code]name[/code] in the [member theme] resource the control uses. + Creates a local override for a theme [StyleBox] with the specified [code]name[/code]. Local overrides always take precedence when fetching theme items for the control. An override can be removed with [method remove_theme_stylebox_override]. + See also [method get_theme_stylebox]. [b]Example of modifying a property in a StyleBox by duplicating it:[/b] [codeblocks] [gdscript] @@ -318,8 +326,8 @@ new_stylebox_normal.border_width_top = 3 new_stylebox_normal.border_color = Color(0, 1, 0.5) $MyButton.add_theme_stylebox_override("normal", new_stylebox_normal) - # Remove the stylebox override: - $MyButton.add_theme_stylebox_override("normal", null) + # Remove the stylebox override. + $MyButton.remove_theme_stylebox_override("normal") [/gdscript] [csharp] // The snippet below assumes the child node MyButton has a StyleBoxFlat assigned. @@ -329,8 +337,8 @@ newStyleboxNormal.BorderWidthTop = 3; newStyleboxNormal.BorderColor = new Color(0, 1, 0.5f); GetNode<Button>("MyButton").AddThemeStyleboxOverride("normal", newStyleboxNormal); - // Remove the stylebox override: - GetNode<Button>("MyButton").AddThemeStyleboxOverride("normal", null); + // Remove the stylebox override. + GetNode<Button>("MyButton").RemoveThemeStyleboxOverride("normal"); [/csharp] [/codeblocks] </description> @@ -468,16 +476,23 @@ <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns a color from assigned [Theme] with given [code]name[/code] and associated with [Control] of given [code]theme_type[/code]. + Returns a [Color] from the first matching [Theme] in the tree if that [Theme] has a color item with the specified [code]name[/code] and [code]theme_type[/code]. If [code]theme_type[/code] is omitted the class name of the current control is used as the type, or [member theme_type_variation] if it is defined. If the type is a class name its parent classes are also checked, in order of inheritance. If the type is a variation its base types are checked, in order of dependency, then the control's class name and its parent classes are checked. + For the current control its local overrides are considered first (see [method add_theme_color_override]), then its assigned [member theme]. After the current control, each parent control and its assigned [member theme] are considered; controls without a [member theme] assigned are skipped. If no matching [Theme] is found in the tree, a custom project [Theme] (see [member ProjectSettings.gui/theme/custom]) and the default [Theme] are used. [codeblocks] [gdscript] func _ready(): - modulate = get_theme_color("font_color", "Button") #get the color defined for button fonts + # Get the font color defined for the current Control's class, if it exists. + modulate = get_theme_color("font_color") + # Get the font color defined for the Button class. + modulate = get_theme_color("font_color", "Button") [/gdscript] [csharp] public override void _Ready() { - Modulate = GetThemeColor("font_color", "Button"); //get the color defined for button fonts + // Get the font color defined for the current Control's class, if it exists. + Modulate = GetThemeColor("font_color"); + // Get the font color defined for the Button class. + Modulate = GetThemeColor("font_color", "Button"); } [/csharp] [/codeblocks] @@ -491,7 +506,8 @@ <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns a constant from assigned [Theme] with given [code]name[/code] and associated with [Control] of given [code]theme_type[/code]. + Returns a constant from the first matching [Theme] in the tree if that [Theme] has a constant item with the specified [code]name[/code] and [code]theme_type[/code]. + See [method get_theme_color] for details. </description> </method> <method name="get_theme_font" qualifiers="const"> @@ -502,7 +518,8 @@ <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns a font from assigned [Theme] with given [code]name[/code] and associated with [Control] of given [code]theme_type[/code]. + Returns a [Font] from the first matching [Theme] in the tree if that [Theme] has a font item with the specified [code]name[/code] and [code]theme_type[/code]. + See [method get_theme_color] for details. </description> </method> <method name="get_theme_font_size" qualifiers="const"> @@ -513,7 +530,8 @@ <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns a font size from assigned [Theme] with given [code]name[/code] and associated with [Control] of given [code]theme_type[/code]. + Returns a font size from the first matching [Theme] in the tree if that [Theme] has a font size item with the specified [code]name[/code] and [code]theme_type[/code]. + See [method get_theme_color] for details. </description> </method> <method name="get_theme_icon" qualifiers="const"> @@ -524,7 +542,8 @@ <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns an icon from assigned [Theme] with given [code]name[/code] and associated with [Control] of given [code]theme_type[/code]. + Returns an icon from the first matching [Theme] in the tree if that [Theme] has an icon item with the specified [code]name[/code] and [code]theme_type[/code]. + See [method get_theme_color] for details. </description> </method> <method name="get_theme_stylebox" qualifiers="const"> @@ -535,7 +554,8 @@ <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns a [StyleBox] from assigned [Theme] with given [code]name[/code] and associated with [Control] of given [code]theme_type[/code]. + Returns a [StyleBox] from the first matching [Theme] in the tree if that [Theme] has a stylebox item with the specified [code]name[/code] and [code]theme_type[/code]. + See [method get_theme_color] for details. </description> </method> <method name="get_tooltip" qualifiers="const"> @@ -588,7 +608,8 @@ <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns [code]true[/code] if [Color] with given [code]name[/code] and associated with [Control] of given [code]theme_type[/code] exists in assigned [Theme]. + Returns [code]true[/code] if there is a matching [Theme] in the tree that has a color item with the specified [code]name[/code] and [code]theme_type[/code]. + See [method get_theme_color] for details. </description> </method> <method name="has_theme_color_override" qualifiers="const"> @@ -597,7 +618,8 @@ <argument index="0" name="name" type="StringName"> </argument> <description> - Returns [code]true[/code] if [Color] with given [code]name[/code] has a valid override in this [Control] node. + Returns [code]true[/code] if there is a local override for a theme [Color] with the specified [code]name[/code] in this [Control] node. + See [method add_theme_color_override]. </description> </method> <method name="has_theme_constant" qualifiers="const"> @@ -608,7 +630,8 @@ <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns [code]true[/code] if constant with given [code]name[/code] and associated with [Control] of given [code]theme_type[/code] exists in assigned [Theme]. + Returns [code]true[/code] if there is a matching [Theme] in the tree that has a constant item with the specified [code]name[/code] and [code]theme_type[/code]. + See [method get_theme_color] for details. </description> </method> <method name="has_theme_constant_override" qualifiers="const"> @@ -617,7 +640,8 @@ <argument index="0" name="name" type="StringName"> </argument> <description> - Returns [code]true[/code] if constant with given [code]name[/code] has a valid override in this [Control] node. + Returns [code]true[/code] if there is a local override for a theme constant with the specified [code]name[/code] in this [Control] node. + See [method add_theme_constant_override]. </description> </method> <method name="has_theme_font" qualifiers="const"> @@ -628,7 +652,8 @@ <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns [code]true[/code] if font with given [code]name[/code] and associated with [Control] of given [code]theme_type[/code] exists in assigned [Theme]. + Returns [code]true[/code] if there is a matching [Theme] in the tree that has a font item with the specified [code]name[/code] and [code]theme_type[/code]. + See [method get_theme_color] for details. </description> </method> <method name="has_theme_font_override" qualifiers="const"> @@ -637,7 +662,8 @@ <argument index="0" name="name" type="StringName"> </argument> <description> - Returns [code]true[/code] if font with given [code]name[/code] has a valid override in this [Control] node. + Returns [code]true[/code] if there is a local override for a theme [Font] with the specified [code]name[/code] in this [Control] node. + See [method add_theme_font_override]. </description> </method> <method name="has_theme_font_size" qualifiers="const"> @@ -648,7 +674,8 @@ <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns [code]true[/code] if font size with given [code]name[/code] and associated with [Control] of given [code]theme_type[/code] exists in assigned [Theme]. + Returns [code]true[/code] if there is a matching [Theme] in the tree that has a font size item with the specified [code]name[/code] and [code]theme_type[/code]. + See [method get_theme_color] for details. </description> </method> <method name="has_theme_font_size_override" qualifiers="const"> @@ -657,7 +684,8 @@ <argument index="0" name="name" type="StringName"> </argument> <description> - Returns [code]true[/code] if font size with given [code]name[/code] has a valid override in this [Control] node. + Returns [code]true[/code] if there is a local override for a theme font size with the specified [code]name[/code] in this [Control] node. + See [method add_theme_font_size_override]. </description> </method> <method name="has_theme_icon" qualifiers="const"> @@ -668,7 +696,8 @@ <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns [code]true[/code] if icon with given [code]name[/code] and associated with [Control] of given [code]theme_type[/code] exists in assigned [Theme]. + Returns [code]true[/code] if there is a matching [Theme] in the tree that has an icon item with the specified [code]name[/code] and [code]theme_type[/code]. + See [method get_theme_color] for details. </description> </method> <method name="has_theme_icon_override" qualifiers="const"> @@ -677,7 +706,8 @@ <argument index="0" name="name" type="StringName"> </argument> <description> - Returns [code]true[/code] if icon with given [code]name[/code] has a valid override in this [Control] node. + Returns [code]true[/code] if there is a local override for a theme icon with the specified [code]name[/code] in this [Control] node. + See [method add_theme_icon_override]. </description> </method> <method name="has_theme_stylebox" qualifiers="const"> @@ -688,7 +718,8 @@ <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns [code]true[/code] if [StyleBox] with given [code]name[/code] and associated with [Control] of given [code]theme_type[/code] exists in assigned [Theme]. + Returns [code]true[/code] if there is a matching [Theme] in the tree that has a stylebox item with the specified [code]name[/code] and [code]theme_type[/code]. + See [method get_theme_color] for details. </description> </method> <method name="has_theme_stylebox_override" qualifiers="const"> @@ -697,7 +728,8 @@ <argument index="0" name="name" type="StringName"> </argument> <description> - Returns [code]true[/code] if [StyleBox] with given [code]name[/code] has a valid override in this [Control] node. + Returns [code]true[/code] if there is a local override for a theme [StyleBox] with the specified [code]name[/code] in this [Control] node. + See [method add_theme_stylebox_override]. </description> </method> <method name="is_layout_rtl" qualifiers="const"> @@ -727,7 +759,7 @@ <argument index="0" name="name" type="StringName"> </argument> <description> - Removes a theme override for a [Color] with the given [code]name[/code]. + Removes a local override for a theme [Color] with the specified [code]name[/code] previously added by [method add_theme_color_override] or via the Inspector dock. </description> </method> <method name="remove_theme_constant_override"> @@ -736,7 +768,7 @@ <argument index="0" name="name" type="StringName"> </argument> <description> - Removes a theme override for a constant with the given [code]name[/code]. + Removes a local override for a theme constant with the specified [code]name[/code] previously added by [method add_theme_constant_override] or via the Inspector dock. </description> </method> <method name="remove_theme_font_override"> @@ -745,7 +777,7 @@ <argument index="0" name="name" type="StringName"> </argument> <description> - Removes a theme override for a [Font] with the given [code]name[/code]. + Removes a local override for a theme [Font] with the specified [code]name[/code] previously added by [method add_theme_font_override] or via the Inspector dock. </description> </method> <method name="remove_theme_font_size_override"> @@ -754,7 +786,7 @@ <argument index="0" name="name" type="StringName"> </argument> <description> - Removes a theme override for a font size with the given [code]name[/code]. + Removes a local override for a theme font size with the specified [code]name[/code] previously added by [method add_theme_font_size_override] or via the Inspector dock. </description> </method> <method name="remove_theme_icon_override"> @@ -763,7 +795,7 @@ <argument index="0" name="name" type="StringName"> </argument> <description> - Removes a theme override for an icon with the given [code]name[/code]. + Removes a local override for a theme icon with the specified [code]name[/code] previously added by [method add_theme_icon_override] or via the Inspector dock. </description> </method> <method name="remove_theme_stylebox_override"> @@ -772,7 +804,7 @@ <argument index="0" name="name" type="StringName"> </argument> <description> - Removes a theme override for a [StyleBox] with the given [code]name[/code]. + Removes a local override for a theme [StyleBox] with the specified [code]name[/code] previously added by [method add_theme_stylebox_override] or via the Inspector dock. </description> </method> <method name="set_anchor"> @@ -1164,8 +1196,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="&"""> - 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="&"""> + 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/Curve3Texture.xml b/doc/classes/CurveXYZTexture.xml index 1b352dff0d..9afeb58060 100644 --- a/doc/classes/Curve3Texture.xml +++ b/doc/classes/CurveXYZTexture.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Curve3Texture" inherits="Texture2D" version="4.0"> +<class name="CurveXYZTexture" inherits="Texture2D" version="4.0"> <brief_description> </brief_description> <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/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/ParticlesMaterial.xml b/doc/classes/ParticlesMaterial.xml index e8fde21032..52430b3f45 100644 --- a/doc/classes/ParticlesMaterial.xml +++ b/doc/classes/ParticlesMaterial.xml @@ -145,7 +145,7 @@ Each particle's initial color. If the [GPUParticles2D]'s [code]texture[/code] is defined, it will be multiplied by this color. To have particle display color in a [BaseMaterial3D] make sure to set [member BaseMaterial3D.vertex_color_use_as_albedo] to [code]true[/code]. </member> <member name="color_ramp" type="Texture2D" setter="set_color_ramp" getter="get_color_ramp"> - Each particle's color will vary along this [GradientTexture]. + Each particle's color will vary along this [GradientTexture] over its lifetime (multiplied with [member color]). </member> <member name="damping" type="float" setter="set_param" getter="get_param" default="0.0"> The rate at which particles lose velocity. diff --git a/doc/classes/PhysicsServer2D.xml b/doc/classes/PhysicsServer2D.xml index 33cd61eb9c..67b27b174f 100644 --- a/doc/classes/PhysicsServer2D.xml +++ b/doc/classes/PhysicsServer2D.xml @@ -1024,7 +1024,7 @@ <argument index="0" name="iterations" type="int"> </argument> <description> - Sets the amount of iterations for calculating velocities of colliding bodies. The greater the amount, the more accurate the collisions, but with a performance loss. + Sets the amount of iterations for calculating velocities of colliding bodies. The greater the amount of iterations, the more accurate the collisions will be. However, a greater amount of iterations requires more CPU power, which can decrease performance. The default value is [code]8[/code]. </description> </method> <method name="shape_get_data" qualifiers="const"> diff --git a/doc/classes/PhysicsServer3D.xml b/doc/classes/PhysicsServer3D.xml index 88ce222324..9db7ff5c12 100644 --- a/doc/classes/PhysicsServer3D.xml +++ b/doc/classes/PhysicsServer3D.xml @@ -1187,6 +1187,16 @@ Activates or deactivates the 3D physics engine. </description> </method> + <method name="set_collision_iterations"> + <return type="void"> + </return> + <argument index="0" name="iterations" type="int"> + </argument> + <description> + Sets the amount of iterations for calculating velocities of colliding bodies. The greater the amount of iterations, the more accurate the collisions will be. However, a greater amount of iterations requires more CPU power, which can decrease performance. The default value is [code]8[/code]. + [b]Note:[/b] Only has an effect when using the default GodotPhysics engine, not the Bullet physics engine. + </description> + </method> <method name="shape_get_data" qualifiers="const"> <return type="Variant"> </return> 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/VisualShaderNode.xml b/doc/classes/VisualShaderNode.xml index 9a74f2322e..199224b190 100644 --- a/doc/classes/VisualShaderNode.xml +++ b/doc/classes/VisualShaderNode.xml @@ -4,6 +4,7 @@ Base class for nodes in a visual shader graph. </brief_description> <description> + Visual shader graphs consist of various nodes. Each node in the graph is a separate object and they are represented as a rectangular boxes with title and a set of properties. Each node has also connection ports that allow to connect it to another nodes and control the flow of the shader. </description> <tutorials> <link title="VisualShaders">https://docs.godotengine.org/en/latest/tutorials/shading/visual_shaders.html</link> diff --git a/doc/classes/VisualShaderNodeCurveTexture.xml b/doc/classes/VisualShaderNodeCurveTexture.xml index 26b7b07df2..4839ceab92 100644 --- a/doc/classes/VisualShaderNodeCurveTexture.xml +++ b/doc/classes/VisualShaderNodeCurveTexture.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualShaderNodeCurveTexture" inherits="VisualShaderNodeResizableBase" version="4.0"> <brief_description> + Performs a [CurveTexture] lookup within the visual shader graph. </brief_description> <description> + Comes with a built-in editor for texture's curves. </description> <tutorials> </tutorials> @@ -10,6 +12,7 @@ </methods> <members> <member name="texture" type="CurveTexture" setter="set_texture" getter="get_texture"> + The source texture. </member> </members> <constants> diff --git a/doc/classes/VisualShaderNodeCurveXYZTexture.xml b/doc/classes/VisualShaderNodeCurveXYZTexture.xml new file mode 100644 index 0000000000..11cdc541bb --- /dev/null +++ b/doc/classes/VisualShaderNodeCurveXYZTexture.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeCurveXYZTexture" inherits="VisualShaderNodeResizableBase" version="4.0"> + <brief_description> + Performs a [CurveXYZTexture] lookup within the visual shader graph. + </brief_description> + <description> + Comes with a built-in editor for texture's curves. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="texture" type="CurveXYZTexture" setter="set_texture" getter="get_texture"> + The source texture. + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeResizableBase.xml b/doc/classes/VisualShaderNodeResizableBase.xml index 9052f6854b..f42289a10e 100644 --- a/doc/classes/VisualShaderNodeResizableBase.xml +++ b/doc/classes/VisualShaderNodeResizableBase.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualShaderNodeResizableBase" inherits="VisualShaderNode" version="4.0"> <brief_description> + Base class for resizable nodes in a visual shader graph. </brief_description> <description> + Resizable nodes have a handle that allows the user to adjust their size as needed. </description> <tutorials> </tutorials> 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="&"""> + <member name="theme_type_variation" type="StringName" setter="set_theme_type_variation" getter="get_theme_type_variation" default="&"""> </member> <member name="title" type="String" setter="set_title" getter="get_title" default=""""> </member> diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index d3d49503d8..7e1b4788e2 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -4598,8 +4598,6 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages } 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."); @@ -6047,7 +6045,7 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma 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; + data_ptr[i] = psc.int_value; break; } } @@ -6070,14 +6068,14 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma } } - 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(); + for (int i = 0; i < pipeline_stages.size(); i++) { + if (specialization_map_entries[i].size()) { + specialization_info.write[i].dataSize = specialization_constant_data.size() * sizeof(uint32_t); + specialization_info.write[i].pData = data_ptr; + specialization_info.write[i].mapEntryCount = specialization_map_entries[i].size(); + specialization_info.write[i].pMapEntries = specialization_map_entries[i].ptr(); - pipeline_stages.write[k].pSpecializationInfo = specialization_info.ptr(); + pipeline_stages.write[i].pSpecializationInfo = specialization_info.ptr() + i; } } } 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/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 10749e5343..b2a336257b 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -2714,7 +2714,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(); } } @@ -3737,46 +3737,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/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..240e28a3c5 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)) { @@ -2189,7 +2205,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { // Popup the selection menu list Point2 click = transform.affine_inverse().xform(b->get_position()); - _get_canvas_items_at_pos(click, selection_results, b->is_alt_pressed() && tool != TOOL_LIST_SELECT); + _get_canvas_items_at_pos(click, selection_results, b->is_alt_pressed() && tool == TOOL_SELECT); if (selection_results.size() == 1) { CanvasItem *item = selection_results[0].item; @@ -5299,7 +5315,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { select_button->set_pressed(true); select_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/select_mode", TTR("Select Mode"), KEY_Q)); select_button->set_shortcut_context(this); - select_button->set_tooltip(keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate") + "\n" + TTR("Alt+Drag: Move") + "\n" + TTR("Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving).") + "\n" + TTR("Alt+RMB: Depth list selection")); + select_button->set_tooltip(keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate") + "\n" + TTR("Alt+Drag: Move") + "\n" + TTR("Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving).") + "\n" + TTR("Alt+RMB: Show list of all nodes at position clicked, including locked.")); hb->add_child(memnew(VSeparator)); @@ -5337,7 +5353,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { hb->add_child(list_select_button); list_select_button->set_toggle_mode(true); list_select_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_LIST_SELECT)); - list_select_button->set_tooltip(TTR("Show a list of all objects at the position clicked\n(same as Alt+RMB in select mode).")); + list_select_button->set_tooltip(TTR("Show list of selectable nodes at position clicked.")); pivot_button = memnew(Button); pivot_button->set_flat(true); @@ -5422,7 +5438,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { hb->add_child(lock_button); lock_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback), varray(LOCK_SELECTED)); - lock_button->set_tooltip(TTR("Lock the selected object in place (can't be moved).")); + lock_button->set_tooltip(TTR("Lock selected node, preventing selection and movement.")); // Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused. lock_button->set_shortcut(ED_SHORTCUT("editor/lock_selected_nodes", TTR("Lock Selected Node(s)"), KEY_MASK_CMD | KEY_L)); @@ -5430,7 +5446,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { unlock_button->set_flat(true); hb->add_child(unlock_button); unlock_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback), varray(UNLOCK_SELECTED)); - unlock_button->set_tooltip(TTR("Unlock the selected object (can be moved).")); + unlock_button->set_tooltip(TTR("Unlock selected node, allowing selection and movement.")); // Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused. unlock_button->set_shortcut(ED_SHORTCUT("editor/unlock_selected_nodes", TTR("Unlock Selected Node(s)"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_L)); @@ -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/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 72a63539b3..52f1178d06 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -571,7 +571,7 @@ ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos, bool p_append, b return closest; } -void Node3DEditorViewport::_find_items_at_pos(const Point2 &p_pos, bool &r_includes_current, Vector<_RayResult> &results, bool p_alt_select) { +void Node3DEditorViewport::_find_items_at_pos(const Point2 &p_pos, bool &r_includes_current, Vector<_RayResult> &results, bool p_alt_select, bool p_include_locked_nodes) { Vector3 ray = _get_ray(p_pos); Vector3 pos = _get_ray_pos(p_pos); @@ -614,6 +614,10 @@ void Node3DEditorViewport::_find_items_at_pos(const Point2 &p_pos, bool &r_inclu continue; } + if (!p_include_locked_nodes && _is_node_locked(spat)) { + continue; + } + if (editor_selection->is_selected(spat)) { r_includes_current = true; } @@ -1034,7 +1038,7 @@ bool Node3DEditorViewport ::_is_node_locked(const Node *p_node) { } void Node3DEditorViewport::_list_select(Ref<InputEventMouseButton> b) { - _find_items_at_pos(b->get_position(), clicked_includes_current, selection_results, b->is_shift_pressed()); + _find_items_at_pos(b->get_position(), clicked_includes_current, selection_results, b->is_shift_pressed(), spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT); Node *scene = editor->get_edited_scene(); @@ -1054,7 +1058,7 @@ void Node3DEditorViewport::_list_select(Ref<InputEventMouseButton> b) { selection_results.clear(); if (clicked.is_valid()) { - _select_clicked(clicked_wants_append, true, spatial_editor->get_tool_mode() != Node3DEditor::TOOL_MODE_LIST_SELECT); + _select_clicked(clicked_wants_append, true, spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT); clicked = ObjectID(); } @@ -3306,7 +3310,7 @@ void Node3DEditorViewport::_selection_result_pressed(int p_result) { clicked = selection_results[p_result].item->get_instance_id(); if (clicked.is_valid()) { - _select_clicked(clicked_wants_append, true, spatial_editor->get_tool_mode() != Node3DEditor::TOOL_MODE_LIST_SELECT); + _select_clicked(clicked_wants_append, true, spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT); clicked = ObjectID(); } } @@ -6181,7 +6185,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++) { @@ -6759,7 +6763,7 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) { tool_button[TOOL_MODE_SELECT]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed), button_binds); tool_button[TOOL_MODE_SELECT]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_select", TTR("Select Mode"), KEY_Q)); tool_button[TOOL_MODE_SELECT]->set_shortcut_context(this); - tool_button[TOOL_MODE_SELECT]->set_tooltip(keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate\nAlt+Drag: Move\nAlt+RMB: Depth list selection")); + tool_button[TOOL_MODE_SELECT]->set_tooltip(keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate\nAlt+Drag: Move\nAlt+RMB: Show list of all nodes at position clicked, including locked.")); hbc_menu->add_child(memnew(VSeparator)); @@ -6798,14 +6802,14 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) { tool_button[TOOL_MODE_LIST_SELECT]->set_flat(true); button_binds.write[0] = MENU_TOOL_LIST_SELECT; tool_button[TOOL_MODE_LIST_SELECT]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed), button_binds); - tool_button[TOOL_MODE_LIST_SELECT]->set_tooltip(TTR("Show a list of all objects at the position clicked\n(same as Alt+RMB in select mode).")); + tool_button[TOOL_MODE_LIST_SELECT]->set_tooltip(TTR("Show list of selectable nodes at position clicked.")); tool_button[TOOL_LOCK_SELECTED] = memnew(Button); hbc_menu->add_child(tool_button[TOOL_LOCK_SELECTED]); tool_button[TOOL_LOCK_SELECTED]->set_flat(true); button_binds.write[0] = MENU_LOCK_SELECTED; tool_button[TOOL_LOCK_SELECTED]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed), button_binds); - tool_button[TOOL_LOCK_SELECTED]->set_tooltip(TTR("Lock the selected object in place (can't be moved).")); + tool_button[TOOL_LOCK_SELECTED]->set_tooltip(TTR("Lock selected node, preventing selection and movement.")); // Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused. tool_button[TOOL_LOCK_SELECTED]->set_shortcut(ED_SHORTCUT("editor/lock_selected_nodes", TTR("Lock Selected Node(s)"), KEY_MASK_CMD | KEY_L)); @@ -6814,7 +6818,7 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) { tool_button[TOOL_UNLOCK_SELECTED]->set_flat(true); button_binds.write[0] = MENU_UNLOCK_SELECTED; tool_button[TOOL_UNLOCK_SELECTED]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed), button_binds); - tool_button[TOOL_UNLOCK_SELECTED]->set_tooltip(TTR("Unlock the selected object (can be moved).")); + tool_button[TOOL_UNLOCK_SELECTED]->set_tooltip(TTR("Unlock selected node, allowing selection and movement.")); // Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused. tool_button[TOOL_UNLOCK_SELECTED]->set_shortcut(ED_SHORTCUT("editor/unlock_selected_nodes", TTR("Unlock Selected Node(s)"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_L)); @@ -7137,6 +7141,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); @@ -7228,6 +7233,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); diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index a195a0eee0..fa0f4e950f 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -317,7 +317,7 @@ private: void _select_clicked(bool p_append, bool p_single, bool p_allow_locked = false); void _select(Node *p_node, bool p_append, bool p_single); ObjectID _select_ray(const Point2 &p_pos, bool p_append, bool &r_includes_current, int *r_gizmo_handle = nullptr, bool p_alt_select = false); - void _find_items_at_pos(const Point2 &p_pos, bool &r_includes_current, Vector<_RayResult> &results, bool p_alt_select = false); + void _find_items_at_pos(const Point2 &p_pos, bool &r_includes_current, Vector<_RayResult> &results, bool p_alt_select = false, bool p_include_locked_nodes = false); Vector3 _get_ray_pos(const Vector2 &p_pos) const; Vector3 _get_ray(const Vector2 &p_pos) const; Point2 _point_to_screen(const Vector3 &p_point); 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 fb91cbb866..85ad03c9bc 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -110,7 +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_curve_xyz", &VisualShaderGraphPlugin::update_curve_xyz); ClassDB::bind_method("update_constant", &VisualShaderGraphPlugin::update_constant); } @@ -219,12 +219,12 @@ void VisualShaderGraphPlugin::update_curve(int p_node_id) { } } -void VisualShaderGraphPlugin::update_curve3(int p_node_id) { +void VisualShaderGraphPlugin::update_curve_xyz(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()); + if (((VisualShaderNodeCurveXYZTexture *)links[p_node_id].visual_node)->get_texture().is_valid()) { + links[p_node_id].curve_editors[0]->set_curve(((VisualShaderNodeCurveXYZTexture *)links[p_node_id].visual_node)->get_texture()->get_curve_x()); + links[p_node_id].curve_editors[1]->set_curve(((VisualShaderNodeCurveXYZTexture *)links[p_node_id].visual_node)->get_texture()->get_curve_y()); + links[p_node_id].curve_editors[2]->set_curve(((VisualShaderNodeCurveXYZTexture *)links[p_node_id].visual_node)->get_texture()->get_curve_z()); } } } @@ -483,10 +483,10 @@ 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)); + Ref<VisualShaderNodeCurveXYZTexture> curve_xyz = vsnode; + if (curve_xyz.is_valid()) { + if (curve_xyz->get_texture().is_valid() && !curve_xyz->get_texture()->is_connected("changed", callable_mp(VisualShaderEditor::get_singleton()->get_graph_plugin(), &VisualShaderGraphPlugin::update_curve_xyz))) { + curve_xyz->get_texture()->connect("changed", callable_mp(VisualShaderEditor::get_singleton()->get_graph_plugin(), &VisualShaderGraphPlugin::update_curve_xyz), varray(p_id)); } HBoxContainer *hbox = memnew(HBoxContainer); @@ -518,7 +518,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { port_offset++; node->add_child(custom_editor); - bool is_curve = curve.is_valid() || curve3.is_valid(); + bool is_curve = curve.is_valid() || curve_xyz.is_valid(); if (is_curve) { VisualShaderEditor::get_singleton()->graph->add_child(node); @@ -551,14 +551,14 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { } } - if (curve3.is_valid()) { + if (curve_xyz.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()); + if (curve_xyz->get_texture().is_valid()) { + curve_editor_x->set_curve(curve_xyz->get_texture()->get_curve_x()); } CurveEditor *curve_editor_y = memnew(CurveEditor); @@ -566,8 +566,8 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { 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()); + if (curve_xyz->get_texture().is_valid()) { + curve_editor_y->set_curve(curve_xyz->get_texture()->get_curve_y()); } CurveEditor *curve_editor_z = memnew(CurveEditor); @@ -575,8 +575,8 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { 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 (curve_xyz->get_texture().is_valid()) { + curve_editor_z->set_curve(curve_xyz->get_texture()->get_curve_z()); } } @@ -2473,9 +2473,9 @@ 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); + VisualShaderNodeCurveXYZTexture *curve_xyz = Object::cast_to<VisualShaderNodeCurveXYZTexture>(vsnode.ptr()); + if (curve_xyz) { + graph_plugin->call_deferred("update_curve_xyz", id_to_use); } if (p_resource_path.is_empty()) { @@ -2486,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 || curve3) { + if (texture2d || texture3d || curve || curve_xyz) { undo_redo->add_do_method(vsnode.ptr(), "set_texture", ResourceLoader::load(p_resource_path)); return; } @@ -3681,10 +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") { + } else if (type == "CurveXYZTexture") { 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); + _add_node(curve_xyz_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; @@ -3957,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 @@ -4043,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); @@ -4406,8 +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)); + curve_xyz_node_option_idx = add_options.size(); + add_options.push_back(AddOption("CurveXYZTexture", "Textures", "Functions", "VisualShaderNodeCurveXYZTexture", TTR("Perform the three components 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 2b354db7b3..f53726edb9 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -117,7 +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_curve_xyz(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; @@ -290,7 +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; + int curve_xyz_node_option_idx; List<String> keyword_list; List<VisualShaderNodeUniformRef> uniform_refs; diff --git a/editor/project_export.cpp b/editor/project_export.cpp index ad88e1b45b..b639a74132 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -1013,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); 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 a9dcbc9f09..166b82d744 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -1210,7 +1210,9 @@ void SceneTreeDock::_notification(int p_what) { 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); diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index ee66f28045..b2c66ee1e7 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -1172,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 1ab36701ff..0651f4b93f 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -549,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 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/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/register_types.cpp b/modules/enet/register_types.cpp index 7a32903d76..38870316e4 100644 --- a/modules/enet/register_types.cpp +++ b/modules/enet/register_types.cpp @@ -41,7 +41,7 @@ void register_enet_types() { enet_ok = true; } - ClassDB::register_class<ENetMultiplayerPeer>(); + 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/include/text/godot_text.h b/modules/gdnative/include/text/godot_text.h index f3c50e6f87..6428f2f149 100644 --- a/modules/gdnative/include/text/godot_text.h +++ b/modules/gdnative/include/text/godot_text.h @@ -143,13 +143,14 @@ 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 *); godot_packed_glyph_array (*shaped_text_sort_logical)(void *, godot_rid *); godot_packed_vector2i_array (*shaped_text_get_line_breaks_adv)(void *, godot_rid *, godot_packed_float32_array *, int, bool, uint8_t); godot_packed_vector2i_array (*shaped_text_get_line_breaks)(void *, godot_rid *, float, int, uint8_t); - godot_packed_vector2i_array (*shaped_text_get_word_breaks)(void *, godot_rid *); + godot_packed_vector2i_array (*shaped_text_get_word_breaks)(void *, godot_rid *, int); godot_array (*shaped_text_get_objects)(void *, godot_rid *); godot_rect2 (*shaped_text_get_object_rect)(void *, godot_rid *, const godot_variant *); godot_vector2 (*shaped_text_get_size)(void *, godot_rid *); 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/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..81dd570bcb 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); @@ -550,15 +555,15 @@ Vector<Vector2i> TextServerGDNative::shaped_text_get_line_breaks(RID p_shaped, f } } -Vector<Vector2i> TextServerGDNative::shaped_text_get_word_breaks(RID p_shaped) const { +Vector<Vector2i> TextServerGDNative::shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags) const { ERR_FAIL_COND_V(interface == nullptr, Vector<Vector2i>()); if (interface->shaped_text_get_word_breaks != nullptr) { - godot_packed_vector2i_array result = interface->shaped_text_get_word_breaks(data, (godot_rid *)&p_shaped); + godot_packed_vector2i_array result = interface->shaped_text_get_word_breaks(data, (godot_rid *)&p_shaped, p_grapheme_flags); Vector<Vector2i> breaks = *(Vector<Vector2i> *)&result; godot_packed_vector2i_array_destroy(&result); return breaks; } else { - return TextServer::shaped_text_get_word_breaks(p_shaped); + return TextServer::shaped_text_get_word_breaks(p_shaped, p_grapheme_flags); } } diff --git a/modules/gdnative/text/text_server_gdnative.h b/modules/gdnative/text/text_server_gdnative.h index 7e42b16fe1..7a0725f3d9 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; @@ -176,7 +178,7 @@ public: virtual Vector<Glyph> shaped_text_sort_logical(RID p_shaped) override; 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 override; virtual Vector<Vector2i> shaped_text_get_line_breaks(RID p_shaped, float p_width, int p_start = 0, uint8_t p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override; - virtual Vector<Vector2i> shaped_text_get_word_breaks(RID p_shaped) const override; + virtual Vector<Vector2i> shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) const override; virtual Array shaped_text_get_objects(RID p_shaped) const override; virtual Rect2 shaped_text_get_object_rect(RID p_shaped, Variant p_key) 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/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/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/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..2513039e8e 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -129,6 +129,10 @@ _FORCE_INLINE_ bool is_linebreak(char32_t p_char) { return (p_char >= 0x000a && p_char <= 0x000d) || (p_char == 0x0085) || (p_char == 0x2028) || (p_char == 0x2029); } +_FORCE_INLINE_ bool is_underscore(char32_t p_char) { + return (p_char == 0x005F); +} + /*************************************************************************/ String TextServerAdvanced::interface_name = "ICU / HarfBuzz / Graphite"; @@ -1658,6 +1662,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); @@ -1728,7 +1887,10 @@ bool TextServerAdvanced::shaped_text_update_breaks(RID p_shaped) { if (is_whitespace(c)) { sd_glyphs[i].flags |= GRAPHEME_IS_SPACE; } - if (u_ispunct(c)) { + if (is_underscore(c)) { + sd_glyphs[i].flags |= GRAPHEME_IS_UNDERSCORE; + } + if (u_ispunct(c) && c != 0x005F) { sd_glyphs[i].flags |= GRAPHEME_IS_PUNCTUATION; } if (breaks.has(sd->glyphs[i].start)) { 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..9ad7dabbcc 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -46,7 +46,11 @@ _FORCE_INLINE_ bool is_linebreak(char32_t p_char) { } _FORCE_INLINE_ bool is_punct(char32_t p_char) { - return (p_char >= 0x0020 && p_char <= 0x002F) || (p_char >= 0x003A && p_char <= 0x0040) || (p_char >= 0x005B && p_char <= 0x0060) || (p_char >= 0x007B && p_char <= 0x007E) || (p_char >= 0x2000 && p_char <= 0x206F) || (p_char >= 0x3000 && p_char <= 0x303F); + return (p_char >= 0x0020 && p_char <= 0x002F) || (p_char >= 0x003A && p_char <= 0x0040) || (p_char >= 0x005B && p_char <= 0x005E) || (p_char == 0x0060) || (p_char >= 0x007B && p_char <= 0x007E) || (p_char >= 0x2000 && p_char <= 0x206F) || (p_char >= 0x3000 && p_char <= 0x303F); +} + +_FORCE_INLINE_ bool is_underscore(char32_t p_char) { + return (p_char == 0x005F); } /*************************************************************************/ @@ -1108,6 +1112,9 @@ bool TextServerFallback::shaped_text_update_breaks(RID p_shaped) { if (is_punct(c)) { sd->glyphs.write[i].flags |= GRAPHEME_IS_PUNCTUATION; } + if (is_underscore(c)) { + sd->glyphs.write[i].flags |= GRAPHEME_IS_UNDERSCORE; + } if (is_whitespace(c) && !is_linebreak(c)) { sd->glyphs.write[i].flags |= GRAPHEME_IS_SPACE; sd->glyphs.write[i].flags |= GRAPHEME_IS_BREAK_SOFT; @@ -1141,6 +1148,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/visual_script/doc_classes/VisualScriptExpression.xml b/modules/visual_script/doc_classes/VisualScriptExpression.xml index 5253f7bc7d..223adbbb96 100644 --- a/modules/visual_script/doc_classes/VisualScriptExpression.xml +++ b/modules/visual_script/doc_classes/VisualScriptExpression.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualScriptExpression" inherits="VisualScriptNode" version="4.0"> <brief_description> + A Visual Script node that can execute a custom expression. </brief_description> <description> + A Visual Script node that can execute a custom expression. Values can be provided for the input and the expression result can be retrieved from the output. </description> <tutorials> </tutorials> diff --git a/modules/visual_script/doc_classes/VisualScriptFunction.xml b/modules/visual_script/doc_classes/VisualScriptFunction.xml index 873d26a5be..652418bd64 100644 --- a/modules/visual_script/doc_classes/VisualScriptFunction.xml +++ b/modules/visual_script/doc_classes/VisualScriptFunction.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualScriptFunction" inherits="VisualScriptNode" version="4.0"> <brief_description> + A Visual Script node representing a function. </brief_description> <description> + [VisualScriptFunction] represents a function header. It is the starting point for the function body and can be used to tweak the function's properties (e.g. RPC mode). </description> <tutorials> </tutorials> diff --git a/modules/visual_script/doc_classes/VisualScriptFunctionCall.xml b/modules/visual_script/doc_classes/VisualScriptFunctionCall.xml index 48104afcf7..f0b666e57a 100644 --- a/modules/visual_script/doc_classes/VisualScriptFunctionCall.xml +++ b/modules/visual_script/doc_classes/VisualScriptFunctionCall.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualScriptFunctionCall" inherits="VisualScriptNode" version="4.0"> <brief_description> + A Visual Script node for calling a function. </brief_description> <description> + [VisualScriptFunctionCall] is created when you add or drag and drop a function onto the Visual Script graph. It allows to tweak parameters of the call, e.g. what object the function is called on. </description> <tutorials> </tutorials> @@ -10,46 +12,66 @@ </methods> <members> <member name="base_script" type="String" setter="set_base_script" getter="get_base_script"> + The script to be used when [member call_mode] is set to [constant CALL_MODE_INSTANCE]. </member> <member name="base_type" type="StringName" setter="set_base_type" getter="get_base_type" default="&"Object""> + The base type to be used when [member call_mode] is set to [constant CALL_MODE_INSTANCE]. </member> <member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" enum="Variant.Type"> + The type to be used when [member call_mode] is set to [constant CALL_MODE_BASIC_TYPE]. </member> <member name="call_mode" type="int" setter="set_call_mode" getter="get_call_mode" enum="VisualScriptFunctionCall.CallMode" default="0"> + [code]call_mode[/code] determines the target object on which the method will be called. See [enum CallMode] for options. </member> <member name="function" type="StringName" setter="set_function" getter="get_function" default="&"""> + The name of the function to be called. </member> <member name="node_path" type="NodePath" setter="set_base_path" getter="get_base_path"> + The node path to use when [member call_mode] is set to [constant CALL_MODE_NODE_PATH]. </member> <member name="rpc_call_mode" type="int" setter="set_rpc_call_mode" getter="get_rpc_call_mode" enum="VisualScriptFunctionCall.RPCCallMode" default="0"> + The mode for RPC calls. See [method Node.rpc] for more details and [enum RPCCallMode] for available options. </member> <member name="singleton" type="StringName" setter="set_singleton" getter="get_singleton"> + The singleton to call the method on. Used when [member call_mode] is set to [constant CALL_MODE_SINGLETON]. </member> <member name="use_default_args" type="int" setter="set_use_default_args" getter="get_use_default_args"> + Number of default arguments that will be used when calling the function. Can't be higher than the number of available default arguments in the method's declaration. </member> <member name="validate" type="bool" setter="set_validate" getter="get_validate" default="true"> + If [code]false[/code], call errors (e.g. wrong number of arguments) will be ignored. </member> </members> <constants> <constant name="CALL_MODE_SELF" value="0" enum="CallMode"> + The method will be called on this [Object]. </constant> <constant name="CALL_MODE_NODE_PATH" value="1" enum="CallMode"> + The method will be called on the given [Node] in the scene tree. </constant> <constant name="CALL_MODE_INSTANCE" value="2" enum="CallMode"> + The method will be called on an instanced node with the given type and script. </constant> <constant name="CALL_MODE_BASIC_TYPE" value="3" enum="CallMode"> + The method will be called on a GDScript basic type (e.g. [Vector2]). </constant> <constant name="CALL_MODE_SINGLETON" value="4" enum="CallMode"> + The method will be called on a singleton. </constant> <constant name="RPC_DISABLED" value="0" enum="RPCCallMode"> + The method will be called locally. </constant> <constant name="RPC_RELIABLE" value="1" enum="RPCCallMode"> + The method will be called remotely. </constant> <constant name="RPC_UNRELIABLE" value="2" enum="RPCCallMode"> + The method will be called remotely using an unreliable protocol. </constant> <constant name="RPC_RELIABLE_TO_ID" value="3" enum="RPCCallMode"> + The method will be called remotely for the given peer. </constant> <constant name="RPC_UNRELIABLE_TO_ID" value="4" enum="RPCCallMode"> + The method will be called remotely for the given peer, using an unreliable protocol. </constant> </constants> </class> diff --git a/modules/visual_script/doc_classes/VisualScriptFunctionState.xml b/modules/visual_script/doc_classes/VisualScriptFunctionState.xml index 16c1629fe4..54a02bf270 100644 --- a/modules/visual_script/doc_classes/VisualScriptFunctionState.xml +++ b/modules/visual_script/doc_classes/VisualScriptFunctionState.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualScriptFunctionState" inherits="RefCounted" version="4.0"> <brief_description> + A Visual Script node representing a function state. </brief_description> <description> + [VisualScriptFunctionState] is returned from [VisualScriptYield] and can be used to resume a paused function call. </description> <tutorials> </tutorials> @@ -17,12 +19,14 @@ <argument index="2" name="args" type="Array"> </argument> <description> + Connects this [VisualScriptFunctionState] to a signal in the given object to automatically resume when it's emitted. </description> </method> <method name="is_valid" qualifiers="const"> <return type="bool"> </return> <description> + Returns whether the function state is valid. </description> </method> <method name="resume"> @@ -31,6 +35,7 @@ <argument index="0" name="args" type="Array" default="[]"> </argument> <description> + Resumes the function to run from the point it was yielded. </description> </method> </methods> diff --git a/modules/visual_script/doc_classes/VisualScriptGlobalConstant.xml b/modules/visual_script/doc_classes/VisualScriptGlobalConstant.xml index ef17bd8a28..87fdfd4e53 100644 --- a/modules/visual_script/doc_classes/VisualScriptGlobalConstant.xml +++ b/modules/visual_script/doc_classes/VisualScriptGlobalConstant.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualScriptGlobalConstant" inherits="VisualScriptNode" version="4.0"> <brief_description> + A Visual Script node returning a constant from [@GlobalScope]. </brief_description> <description> + A Visual Script node returning a constant from [@GlobalScope]. </description> <tutorials> </tutorials> @@ -10,6 +12,7 @@ </methods> <members> <member name="constant" type="int" setter="set_global_constant" getter="get_global_constant" default="0"> + The constant to be used. </member> </members> <constants> diff --git a/modules/visual_script/doc_classes/VisualScriptIndexGet.xml b/modules/visual_script/doc_classes/VisualScriptIndexGet.xml index bb1618a655..b348048298 100644 --- a/modules/visual_script/doc_classes/VisualScriptIndexGet.xml +++ b/modules/visual_script/doc_classes/VisualScriptIndexGet.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualScriptIndexGet" inherits="VisualScriptNode" version="4.0"> <brief_description> + A Visual Script node for getting a value from an array or a dictionary. </brief_description> <description> + [VisualScriptIndexGet] will return the value stored in an array or a dictionary under the given index. </description> <tutorials> </tutorials> diff --git a/modules/visual_script/doc_classes/VisualScriptIndexSet.xml b/modules/visual_script/doc_classes/VisualScriptIndexSet.xml index 4ff96f7211..d7fe7340ad 100644 --- a/modules/visual_script/doc_classes/VisualScriptIndexSet.xml +++ b/modules/visual_script/doc_classes/VisualScriptIndexSet.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualScriptIndexSet" inherits="VisualScriptNode" version="4.0"> <brief_description> + A Visual Script node for setting a value in an array or a dictionary. </brief_description> <description> + [VisualScriptIndexSet] will set the value stored in an array or a dictionary under the given index to the provided new value. </description> <tutorials> </tutorials> diff --git a/modules/visual_script/doc_classes/VisualScriptInputAction.xml b/modules/visual_script/doc_classes/VisualScriptInputAction.xml index 9ca67feacb..d6fa111500 100644 --- a/modules/visual_script/doc_classes/VisualScriptInputAction.xml +++ b/modules/visual_script/doc_classes/VisualScriptInputAction.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualScriptInputAction" inherits="VisualScriptNode" version="4.0"> <brief_description> + A Visual Script node returning a state of an action. </brief_description> <description> + [VisualScriptInputAction] can be used to check if an action is pressed or released. </description> <tutorials> </tutorials> @@ -10,18 +12,24 @@ </methods> <members> <member name="action" type="StringName" setter="set_action_name" getter="get_action_name" default="&"""> + Name of the action. </member> <member name="mode" type="int" setter="set_action_mode" getter="get_action_mode" enum="VisualScriptInputAction.Mode" default="0"> + State of the action to check. See [enum Mode] for options. </member> </members> <constants> <constant name="MODE_PRESSED" value="0" enum="Mode"> + [code]True[/code] if action is pressed. </constant> <constant name="MODE_RELEASED" value="1" enum="Mode"> + [code]True[/code] if action is released (i.e. not pressed). </constant> <constant name="MODE_JUST_PRESSED" value="2" enum="Mode"> + [code]True[/code] on the frame the action was pressed. </constant> <constant name="MODE_JUST_RELEASED" value="3" enum="Mode"> + [code]True[/code] on the frame the action was released. </constant> </constants> </class> diff --git a/modules/visual_script/doc_classes/VisualScriptLists.xml b/modules/visual_script/doc_classes/VisualScriptLists.xml index 8a7254b46a..671c427228 100644 --- a/modules/visual_script/doc_classes/VisualScriptLists.xml +++ b/modules/visual_script/doc_classes/VisualScriptLists.xml @@ -19,6 +19,7 @@ <argument index="2" name="index" type="int"> </argument> <description> + Adds an input port to the Visual Script node. </description> </method> <method name="add_output_data_port"> @@ -31,6 +32,7 @@ <argument index="2" name="index" type="int"> </argument> <description> + Adds an output port to the Visual Script node. </description> </method> <method name="remove_input_data_port"> @@ -39,6 +41,7 @@ <argument index="0" name="index" type="int"> </argument> <description> + Removes an input port from the Visual Script node. </description> </method> <method name="remove_output_data_port"> @@ -47,6 +50,7 @@ <argument index="0" name="index" type="int"> </argument> <description> + Removes an output port from the Visual Script node. </description> </method> <method name="set_input_data_port_name"> @@ -57,6 +61,7 @@ <argument index="1" name="name" type="String"> </argument> <description> + Sets the name of an input port. </description> </method> <method name="set_input_data_port_type"> @@ -67,6 +72,7 @@ <argument index="1" name="type" type="int" enum="Variant.Type"> </argument> <description> + Sets the type of an input port. </description> </method> <method name="set_output_data_port_name"> @@ -77,6 +83,7 @@ <argument index="1" name="name" type="String"> </argument> <description> + Sets the name of an output port. </description> </method> <method name="set_output_data_port_type"> @@ -87,6 +94,7 @@ <argument index="1" name="type" type="int" enum="Variant.Type"> </argument> <description> + Sets the type of an output port. </description> </method> </methods> diff --git a/modules/visual_script/doc_classes/VisualScriptOperator.xml b/modules/visual_script/doc_classes/VisualScriptOperator.xml index c8ce0f2732..cbbefa7f71 100644 --- a/modules/visual_script/doc_classes/VisualScriptOperator.xml +++ b/modules/visual_script/doc_classes/VisualScriptOperator.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualScriptOperator" inherits="VisualScriptNode" version="4.0"> <brief_description> + A Visual Script node that performs an operation on two values. </brief_description> <description> [b]Input Ports:[/b] @@ -15,8 +16,10 @@ </methods> <members> <member name="operator" type="int" setter="set_operator" getter="get_operator" enum="Variant.Operator" default="6"> + The operation to be performed. See [enum Variant.Operator] for available options. </member> <member name="type" type="int" setter="set_typed" getter="get_typed" enum="Variant.Type" default="0"> + The type of the values for this operation. See [enum Variant.Type] for available options. </member> </members> <constants> diff --git a/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml b/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml index ff6c723a3e..c1bf443ea3 100644 --- a/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml +++ b/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualScriptPropertyGet" inherits="VisualScriptNode" version="4.0"> <brief_description> + A Visual Script node returning a value of a property from an [Object]. </brief_description> <description> + [VisualScriptPropertyGet] can return a value of any property from the current object or other objects. </description> <tutorials> </tutorials> @@ -10,28 +12,39 @@ </methods> <members> <member name="base_script" type="String" setter="set_base_script" getter="get_base_script"> + The script to be used when [member set_mode] is set to [constant CALL_MODE_INSTANCE]. </member> <member name="base_type" type="StringName" setter="set_base_type" getter="get_base_type" default="&"Object""> + The base type to be used when [member set_mode] is set to [constant CALL_MODE_INSTANCE]. </member> <member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" enum="Variant.Type"> + The type to be used when [member set_mode] is set to [constant CALL_MODE_BASIC_TYPE]. </member> <member name="index" type="StringName" setter="set_index" getter="get_index"> + The indexed name of the property to retrieve. See [method Object.get_indexed] for details. </member> <member name="node_path" type="NodePath" setter="set_base_path" getter="get_base_path"> + The node path to use when [member set_mode] is set to [constant CALL_MODE_NODE_PATH]. </member> <member name="property" type="StringName" setter="set_property" getter="get_property" default="&"""> + The name of the property to retrieve. Changing this will clear [member index]. </member> <member name="set_mode" type="int" setter="set_call_mode" getter="get_call_mode" enum="VisualScriptPropertyGet.CallMode" default="0"> + [code]set_mode[/code] determines the target object from which the property will be retrieved. See [enum CallMode] for options. </member> </members> <constants> <constant name="CALL_MODE_SELF" value="0" enum="CallMode"> + The property will be retrieved from this [Object]. </constant> <constant name="CALL_MODE_NODE_PATH" value="1" enum="CallMode"> + The property will be retrieved from the given [Node] in the scene tree. </constant> <constant name="CALL_MODE_INSTANCE" value="2" enum="CallMode"> + The property will be retrieved from an instanced node with the given type and script. </constant> <constant name="CALL_MODE_BASIC_TYPE" value="3" enum="CallMode"> + The property will be retrieved from a GDScript basic type (e.g. [Vector2]). </constant> </constants> </class> diff --git a/modules/visual_script/doc_classes/VisualScriptPropertySet.xml b/modules/visual_script/doc_classes/VisualScriptPropertySet.xml index 71bfc4c8a5..75d6a63469 100644 --- a/modules/visual_script/doc_classes/VisualScriptPropertySet.xml +++ b/modules/visual_script/doc_classes/VisualScriptPropertySet.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualScriptPropertySet" inherits="VisualScriptNode" version="4.0"> <brief_description> + A Visual Script node that sets a property of an [Object]. </brief_description> <description> + [VisualScriptPropertySet] can set the value of any property from the current object or other objects. </description> <tutorials> </tutorials> @@ -10,52 +12,75 @@ </methods> <members> <member name="assign_op" type="int" setter="set_assign_op" getter="get_assign_op" enum="VisualScriptPropertySet.AssignOp" default="0"> + The additional operation to perform when assigning. See [enum AssignOp] for options. </member> <member name="base_script" type="String" setter="set_base_script" getter="get_base_script"> + The script to be used when [member set_mode] is set to [constant CALL_MODE_INSTANCE]. </member> <member name="base_type" type="StringName" setter="set_base_type" getter="get_base_type" default="&"Object""> + The base type to be used when [member set_mode] is set to [constant CALL_MODE_INSTANCE]. </member> <member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" enum="Variant.Type"> + The type to be used when [member set_mode] is set to [constant CALL_MODE_BASIC_TYPE]. </member> <member name="index" type="StringName" setter="set_index" getter="get_index"> + The indexed name of the property to set. See [method Object.set_indexed] for details. </member> <member name="node_path" type="NodePath" setter="set_base_path" getter="get_base_path"> + The node path to use when [member set_mode] is set to [constant CALL_MODE_NODE_PATH]. </member> <member name="property" type="StringName" setter="set_property" getter="get_property" default="&"""> + The name of the property to set. Changing this will clear [member index]. </member> <member name="set_mode" type="int" setter="set_call_mode" getter="get_call_mode" enum="VisualScriptPropertySet.CallMode" default="0"> + [code]set_mode[/code] determines the target object on which the property will be set. See [enum CallMode] for options. </member> </members> <constants> <constant name="CALL_MODE_SELF" value="0" enum="CallMode"> + The property will be set on this [Object]. </constant> <constant name="CALL_MODE_NODE_PATH" value="1" enum="CallMode"> + The property will be set on the given [Node] in the scene tree. </constant> <constant name="CALL_MODE_INSTANCE" value="2" enum="CallMode"> + The property will be set on an instanced node with the given type and script. </constant> <constant name="CALL_MODE_BASIC_TYPE" value="3" enum="CallMode"> + The property will be set on a GDScript basic type (e.g. [Vector2]). </constant> <constant name="ASSIGN_OP_NONE" value="0" enum="AssignOp"> + The property will be assigned regularly. </constant> <constant name="ASSIGN_OP_ADD" value="1" enum="AssignOp"> + The value will be added to the property. Equivalent of doing [code]+=[/code]. </constant> <constant name="ASSIGN_OP_SUB" value="2" enum="AssignOp"> + The value will be subtracted from the property. Equivalent of doing [code]-=[/code]. </constant> <constant name="ASSIGN_OP_MUL" value="3" enum="AssignOp"> + The property will be multiplied by the value. Equivalent of doing [code]*=[/code]. </constant> <constant name="ASSIGN_OP_DIV" value="4" enum="AssignOp"> + The property will be divided by the value. Equivalent of doing [code]/=[/code]. </constant> <constant name="ASSIGN_OP_MOD" value="5" enum="AssignOp"> + A modulo operation will be performed on the property and the value. Equivalent of doing [code]%=[/code]. </constant> <constant name="ASSIGN_OP_SHIFT_LEFT" value="6" enum="AssignOp"> + The property will be binarly shifted to the left by the given value. Equivalent of doing [code]<<[/code]. </constant> <constant name="ASSIGN_OP_SHIFT_RIGHT" value="7" enum="AssignOp"> + The property will be binarly shifted to the right by the given value. Equivalent of doing [code]>>[/code]. </constant> <constant name="ASSIGN_OP_BIT_AND" value="8" enum="AssignOp"> + A binary [code]AND[/code] operation will be performed on the property. Equivalent of doing [code]&=[/code]. </constant> <constant name="ASSIGN_OP_BIT_OR" value="9" enum="AssignOp"> + A binary [code]OR[/code] operation will be performed on the property. Equivalent of doing [code]|=[/code]. </constant> <constant name="ASSIGN_OP_BIT_XOR" value="10" enum="AssignOp"> + A binary [code]XOR[/code] operation will be performed on the property. Equivalent of doing [code]^=[/code]. </constant> </constants> </class> diff --git a/modules/visual_script/doc_classes/VisualScriptSceneTree.xml b/modules/visual_script/doc_classes/VisualScriptSceneTree.xml index 191d4b6977..8cddd02c77 100644 --- a/modules/visual_script/doc_classes/VisualScriptSceneTree.xml +++ b/modules/visual_script/doc_classes/VisualScriptSceneTree.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualScriptSceneTree" inherits="VisualScriptNode" version="4.0"> <brief_description> + A Visual Script node for accessing [SceneTree] methods. </brief_description> <description> + A Visual Script node for accessing [SceneTree] methods. </description> <tutorials> </tutorials> diff --git a/modules/visual_script/doc_classes/VisualScriptSubCall.xml b/modules/visual_script/doc_classes/VisualScriptSubCall.xml index cb3b04b583..89a10edde4 100644 --- a/modules/visual_script/doc_classes/VisualScriptSubCall.xml +++ b/modules/visual_script/doc_classes/VisualScriptSubCall.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualScriptSubCall" inherits="VisualScriptNode" version="4.0"> <brief_description> + Calls a method called [code]_subcall[/code] in this object. </brief_description> <description> + [VisualScriptSubCall] will call method named [code]_subcall[/code] in the current script. It will fail if the method doesn't exist or the provided arguments are wrong. </description> <tutorials> </tutorials> @@ -13,6 +15,7 @@ <argument index="0" name="arguments" type="Variant"> </argument> <description> + Called by this node. </description> </method> </methods> diff --git a/modules/visual_script/doc_classes/VisualScriptTypeCast.xml b/modules/visual_script/doc_classes/VisualScriptTypeCast.xml index 9e3e020f2d..5dd1ad3421 100644 --- a/modules/visual_script/doc_classes/VisualScriptTypeCast.xml +++ b/modules/visual_script/doc_classes/VisualScriptTypeCast.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualScriptTypeCast" inherits="VisualScriptNode" version="4.0"> <brief_description> + A Visual Script node that casts the given value to another type. </brief_description> <description> + [VisualScriptTypeCast] will perform a type conversion to an [Object]-derived type. </description> <tutorials> </tutorials> @@ -10,8 +12,10 @@ </methods> <members> <member name="base_script" type="String" setter="set_base_script" getter="get_base_script" default=""""> + The target script class to be converted to. If none, only the [member base_type] will be used. </member> <member name="base_type" type="StringName" setter="set_base_type" getter="get_base_type" default="&"Object""> + The target type to be converted to. </member> </members> <constants> diff --git a/modules/visual_script/doc_classes/VisualScriptYield.xml b/modules/visual_script/doc_classes/VisualScriptYield.xml index 0a8d529a48..b04ab7b014 100644 --- a/modules/visual_script/doc_classes/VisualScriptYield.xml +++ b/modules/visual_script/doc_classes/VisualScriptYield.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualScriptYield" inherits="VisualScriptNode" version="4.0"> <brief_description> + A Visual Script node used to pause a function execution. </brief_description> <description> + [VisualScriptYield] will pause the function call and return [VisualScriptFunctionState], which can be used to resume the function. </description> <tutorials> </tutorials> @@ -10,16 +12,21 @@ </methods> <members> <member name="mode" type="int" setter="set_yield_mode" getter="get_yield_mode" enum="VisualScriptYield.YieldMode" default="1"> + The mode to use for yielding. See [enum YieldMode] for available options. </member> <member name="wait_time" type="float" setter="set_wait_time" getter="get_wait_time"> + The time to wait when [member mode] is set to [constant YIELD_WAIT]. </member> </members> <constants> <constant name="YIELD_FRAME" value="1" enum="YieldMode"> + Yields during an idle frame. </constant> <constant name="YIELD_PHYSICS_FRAME" value="2" enum="YieldMode"> + Yields during a physics frame. </constant> <constant name="YIELD_WAIT" value="3" enum="YieldMode"> + Yields a function and waits the given time. </constant> </constants> </class> diff --git a/modules/visual_script/doc_classes/VisualScriptYieldSignal.xml b/modules/visual_script/doc_classes/VisualScriptYieldSignal.xml index c59234433f..c6c3188d08 100644 --- a/modules/visual_script/doc_classes/VisualScriptYieldSignal.xml +++ b/modules/visual_script/doc_classes/VisualScriptYieldSignal.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualScriptYieldSignal" inherits="VisualScriptNode" version="4.0"> <brief_description> + A Visual Script node yielding for a signal. </brief_description> <description> + [VisualScriptYieldSignal] will pause the function execution until the provided signal is emitted. </description> <tutorials> </tutorials> @@ -10,20 +12,27 @@ </methods> <members> <member name="base_type" type="StringName" setter="set_base_type" getter="get_base_type" default="&"Object""> + The base type to be used when [member call_mode] is set to [constant CALL_MODE_INSTANCE]. </member> <member name="call_mode" type="int" setter="set_call_mode" getter="get_call_mode" enum="VisualScriptYieldSignal.CallMode" default="0"> + [code]call_mode[/code] determines the target object to wait for the signal emission. See [enum CallMode] for options. </member> <member name="node_path" type="NodePath" setter="set_base_path" getter="get_base_path"> + The node path to use when [member call_mode] is set to [constant CALL_MODE_NODE_PATH]. </member> <member name="signal" type="StringName" setter="set_signal" getter="get_signal" default="&"""> + The signal name to be waited for. </member> </members> <constants> <constant name="CALL_MODE_SELF" value="0" enum="CallMode"> + A signal from this [Object] will be used. </constant> <constant name="CALL_MODE_NODE_PATH" value="1" enum="CallMode"> + A signal from the given [Node] in the scene tree will be used. </constant> <constant name="CALL_MODE_INSTANCE" value="2" enum="CallMode"> + A signal from an instanced node with the given type will be used. </constant> </constants> </class> 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/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/register_types.cpp b/modules/webrtc/register_types.cpp index fcdf04fc2b..63ecc03a4c 100644 --- a/modules/webrtc/register_types.cpp +++ b/modules/webrtc/register_types.cpp @@ -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<WebRTCMultiplayerPeer>(); + GDREGISTER_VIRTUAL_CLASS(WebRTCDataChannel); + GDREGISTER_CLASS(WebRTCMultiplayerPeer); } void unregister_webrtc_types() {} 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/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/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/iphone/export/export.cpp b/platform/iphone/export/export.cpp index 1d1961ac2f..f21a14e84b 100644 --- a/platform/iphone/export/export.cpp +++ b/platform/iphone/export/export.cpp @@ -368,6 +368,8 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "plugins/" + found_plugins[i].name), false)); } + Set<String> plist_keys; + for (int i = 0; i < found_plugins.size(); i++) { // Editable plugin plist values PluginConfigIOS plugin = found_plugins[i]; @@ -379,7 +381,10 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) switch (item.type) { case PluginConfigIOS::PlistItemType::STRING_INPUT: { String preset_name = "plugins_plist/" + key; - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, preset_name), item.value)); + if (!plist_keys.has(preset_name)) { + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, preset_name), item.value)); + plist_keys.insert(preset_name); + } } break; default: continue; @@ -413,7 +418,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/plugin/godot_plugin_config.h b/platform/iphone/plugin/godot_plugin_config.h index 06770260aa..f9c5d7e51f 100644 --- a/platform/iphone/plugin/godot_plugin_config.h +++ b/platform/iphone/plugin/godot_plugin_config.h @@ -252,6 +252,8 @@ static inline PluginConfigIOS load_plugin_config(Ref<ConfigFile> config_file, co return plugin_config; } + config_file->clear(); + Error err = config_file->load(path); if (err != OK) { 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/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp index c6a2fa5be7..8cd6ec43c6 100644 --- a/platform/linuxbsd/os_linuxbsd.cpp +++ b/platform/linuxbsd/os_linuxbsd.cpp @@ -425,7 +425,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) { // Generates the .trashinfo file OS::Date date = OS::get_singleton()->get_date(false); OS::Time time = OS::get_singleton()->get_time(false); - String timestamp = vformat("%04d-%02d-%02dT%02d:%02d:", date.year, date.month, date.day, time.hour, time.minute); + String timestamp = vformat("%04d-%02d-%02dT%02d:%02d:", date.year, (int)date.month, date.day, time.hour, time.minute); timestamp = vformat("%s%02d", timestamp, time.second); // vformat only supports up to 6 arguments. String trash_info = "[Trash Info]\nPath=" + p_path.uri_encode() + "\nDeletionDate=" + timestamp + "\n"; { diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index 24f3301ce1..a341ba69ac 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -463,10 +463,6 @@ Vector2 CPUParticles2D::get_gravity() const { } void CPUParticles2D::_validate_property(PropertyInfo &property) const { - if (property.name == "color" && color_ramp.is_valid()) { - property.usage = PROPERTY_USAGE_NONE; - } - if (property.name == "emission_sphere_radius" && emission_shape != EMISSION_SHAPE_SPHERE) { property.usage = PROPERTY_USAGE_NONE; } diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index be619ed60d..80aa99bf5e 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -86,11 +86,11 @@ bool PhysicsBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_in // Restore direction of motion to be along original motion, // in order to avoid sliding due to recovery, // but only if collision depth is low enough to avoid tunneling. - real_t motion_length = p_motion.length(); - if (motion_length > CMP_EPSILON) { + if (p_cancel_sliding) { + real_t motion_length = p_motion.length(); real_t precision = 0.001; - if (colliding && p_cancel_sliding) { + if (colliding) { // Can't just use margin as a threshold because collision depth is calculated on unsafe motion, // so even in normal resting cases the depth can be a bit more than the margin. precision += motion_length * (r_result.collision_unsafe_fraction - r_result.collision_safe_fraction); @@ -101,16 +101,21 @@ bool PhysicsBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_in } if (p_cancel_sliding) { + // When motion is null, recovery is the resulting motion. + Vector2 motion_normal; + if (motion_length > CMP_EPSILON) { + motion_normal = p_motion / motion_length; + } + // Check depth of recovery. - Vector2 motion_normal = p_motion / motion_length; - real_t dot = r_result.motion.dot(motion_normal); - Vector2 recovery = r_result.motion - motion_normal * dot; + real_t projected_length = r_result.motion.dot(motion_normal); + Vector2 recovery = r_result.motion - motion_normal * projected_length; real_t recovery_length = recovery.length(); // Fixes cases where canceling slide causes the motion to go too deep into the ground, - // Becauses we're only taking rest information into account and not general recovery. + // because we're only taking rest information into account and not general recovery. if (recovery_length < (real_t)p_margin + precision) { // Apply adjustment to motion. - r_result.motion = motion_normal * dot; + r_result.motion = motion_normal * projected_length; r_result.remainder = p_motion - r_result.motion; } } @@ -978,8 +983,9 @@ void CharacterBody2D::move_and_slide() { floor_normal = Vector2(); floor_velocity = Vector2(); - // No sliding on first attempt to keep floor motion stable when possible. - bool sliding_enabled = false; + // No sliding on first attempt to keep floor motion stable when possible, + // when stop on slope is enabled. + bool sliding_enabled = !stop_on_slope; for (int iteration = 0; iteration < max_slides; ++iteration) { PhysicsServer2D::MotionResult result; bool found_collision = false; @@ -1018,7 +1024,11 @@ void CharacterBody2D::move_and_slide() { if (stop_on_slope) { if ((body_velocity_normal + up_direction).length() < 0.01) { Transform2D gt = get_global_transform(); - gt.elements[2] -= result.motion.slide(up_direction); + if (result.motion.length() > margin) { + gt.elements[2] -= result.motion.slide(up_direction); + } else { + gt.elements[2] -= result.motion; + } set_global_transform(gt); linear_velocity = Vector2(); return; @@ -1054,7 +1064,7 @@ void CharacterBody2D::move_and_slide() { // Apply snap. Transform2D gt = get_global_transform(); PhysicsServer2D::MotionResult result; - if (move_and_collide(snap, infinite_inertia, result, margin, false, true)) { + if (move_and_collide(snap, infinite_inertia, result, margin, false, true, false)) { bool apply = true; if (up_direction != Vector2()) { if (Math::acos(result.collision_normal.dot(up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { @@ -1065,9 +1075,12 @@ void CharacterBody2D::move_and_slide() { if (stop_on_slope) { // move and collide may stray the object a bit because of pre un-stucking, // so only ensure that motion happens on floor direction in this case. - result.motion = up_direction * up_direction.dot(result.motion); + if (result.motion.length() > margin) { + result.motion = up_direction * up_direction.dot(result.motion); + } else { + result.motion = Vector2(); + } } - } else { apply = false; } diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index 6dc865ec0e..178a269f17 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -434,10 +434,6 @@ Vector3 CPUParticles3D::get_gravity() const { } void CPUParticles3D::_validate_property(PropertyInfo &property) const { - if (property.name == "color" && color_ramp.is_valid()) { - property.usage = PROPERTY_USAGE_NONE; - } - if (property.name == "emission_sphere_radius" && emission_shape != EMISSION_SHAPE_SPHERE) { property.usage = PROPERTY_USAGE_NONE; } 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/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index e7482d35e7..4568145458 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -125,11 +125,11 @@ bool PhysicsBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_in // Restore direction of motion to be along original motion, // in order to avoid sliding due to recovery, // but only if collision depth is low enough to avoid tunneling. - real_t motion_length = p_motion.length(); - if (motion_length > CMP_EPSILON) { - real_t precision = CMP_EPSILON; + if (p_cancel_sliding) { + real_t motion_length = p_motion.length(); + real_t precision = 0.001; - if (colliding && p_cancel_sliding) { + if (colliding) { // Can't just use margin as a threshold because collision depth is calculated on unsafe motion, // so even in normal resting cases the depth can be a bit more than the margin. precision += motion_length * (r_result.collision_unsafe_fraction - r_result.collision_safe_fraction); @@ -140,16 +140,21 @@ bool PhysicsBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_in } if (p_cancel_sliding) { + // When motion is null, recovery is the resulting motion. + Vector3 motion_normal; + if (motion_length > CMP_EPSILON) { + motion_normal = p_motion / motion_length; + } + // Check depth of recovery. - Vector3 motion_normal = p_motion / motion_length; - real_t dot = r_result.motion.dot(motion_normal); - Vector3 recovery = r_result.motion - motion_normal * dot; + real_t projected_length = r_result.motion.dot(motion_normal); + Vector3 recovery = r_result.motion - motion_normal * projected_length; real_t recovery_length = recovery.length(); // Fixes cases where canceling slide causes the motion to go too deep into the ground, - // Becauses we're only taking rest information into account and not general recovery. + // because we're only taking rest information into account and not general recovery. if (recovery_length < (real_t)p_margin + precision) { // Apply adjustment to motion. - r_result.motion = motion_normal * dot; + r_result.motion = motion_normal * projected_length; r_result.remainder = p_motion - r_result.motion; } } @@ -1012,8 +1017,9 @@ void CharacterBody3D::move_and_slide() { floor_normal = Vector3(); floor_velocity = Vector3(); - // No sliding on first attempt to keep motion stable when possible. - bool sliding_enabled = false; + // No sliding on first attempt to keep floor motion stable when possible, + // when stop on slope is enabled. + bool sliding_enabled = !stop_on_slope; for (int iteration = 0; iteration < max_slides; ++iteration) { PhysicsServer3D::MotionResult result; bool found_collision = false; @@ -1052,7 +1058,11 @@ void CharacterBody3D::move_and_slide() { if (stop_on_slope) { if ((body_velocity_normal + up_direction).length() < 0.01) { Transform3D gt = get_global_transform(); - gt.origin -= result.motion.slide(up_direction); + if (result.motion.length() > margin) { + gt.origin -= result.motion.slide(up_direction); + } else { + gt.origin -= result.motion; + } set_global_transform(gt); linear_velocity = Vector3(); return; @@ -1094,7 +1104,7 @@ void CharacterBody3D::move_and_slide() { // Apply snap. Transform3D gt = get_global_transform(); PhysicsServer3D::MotionResult result; - if (move_and_collide(snap, infinite_inertia, result, margin, false, true)) { + if (move_and_collide(snap, infinite_inertia, result, margin, false, true, false)) { bool apply = true; if (up_direction != Vector3()) { if (Math::acos(result.collision_normal.dot(up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { @@ -1105,7 +1115,11 @@ void CharacterBody3D::move_and_slide() { if (stop_on_slope) { // move and collide may stray the object a bit because of pre un-stucking, // so only ensure that motion happens on floor direction in this case. - result.motion = result.motion.project(up_direction); + if (result.motion.length() > margin) { + result.motion = result.motion.project(up_direction); + } else { + result.motion = Vector3(); + } } } else { apply = false; //snapped with floor direction, but did not snap to a floor, do not snap. 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/base_button.cpp b/scene/gui/base_button.cpp index c1ae0479f5..8414c4dc78 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -226,6 +226,18 @@ void BaseButton::set_pressed(bool p_pressed) { update(); } +void BaseButton::set_pressed_no_signal(bool p_pressed) { + if (!toggle_mode) { + return; + } + if (status.pressed == p_pressed) { + return; + } + status.pressed = p_pressed; + + update(); +} + bool BaseButton::is_pressing() const { return status.press_attempt; } @@ -399,6 +411,7 @@ void BaseButton::_bind_methods() { ClassDB::bind_method(D_METHOD("_unhandled_key_input"), &BaseButton::_unhandled_key_input); ClassDB::bind_method(D_METHOD("set_pressed", "pressed"), &BaseButton::set_pressed); ClassDB::bind_method(D_METHOD("is_pressed"), &BaseButton::is_pressed); + ClassDB::bind_method(D_METHOD("set_pressed_no_signal", "pressed"), &BaseButton::set_pressed_no_signal); ClassDB::bind_method(D_METHOD("is_hovered"), &BaseButton::is_hovered); ClassDB::bind_method(D_METHOD("set_toggle_mode", "enabled"), &BaseButton::set_toggle_mode); ClassDB::bind_method(D_METHOD("is_toggle_mode"), &BaseButton::is_toggle_mode); diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h index 6c7a8f3433..d86b35daf0 100644 --- a/scene/gui/base_button.h +++ b/scene/gui/base_button.h @@ -98,7 +98,8 @@ public: bool is_pressing() const; ///< return whether button is pressed (toggled in) bool is_hovered() const; - void set_pressed(bool p_pressed); ///only works in toggle mode + void set_pressed(bool p_pressed); // Only works in toggle mode. + void set_pressed_no_signal(bool p_pressed); void set_toggle_mode(bool p_on); bool is_toggle_mode() const; 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/window.cpp b/scene/main/window.cpp index 9299f8d6be..c557fd0101 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -115,7 +115,7 @@ Size2i Window::get_max_size() const { void Window::set_min_size(const Size2i &p_min_size) { min_size = p_min_size; - if (window_id != DisplayServer::INVALID_WINDOW_ID) { + if (!wrap_controls && window_id != DisplayServer::INVALID_WINDOW_ID) { DisplayServer::get_singleton()->window_set_min_size(min_size, window_id); } _update_window_size(); @@ -542,6 +542,7 @@ void Window::_update_window_size() { embedder->_sub_window_update(this); } else if (window_id != DisplayServer::INVALID_WINDOW_ID) { DisplayServer::get_singleton()->window_set_size(size, window_id); + DisplayServer::get_singleton()->window_set_min_size(size_limit, window_id); } //update the viewport @@ -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 ea0df685a1..2d83f59bb5 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,451 +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_class<VisualShaderNodeCurve3Texture>(); - 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(VisualShaderNodeCurveXYZTexture); + 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(CurveXYZTexture); + 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/particles_material.cpp b/scene/resources/particles_material.cpp index 2bde98abe0..00bea312b3 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -569,7 +569,7 @@ void ParticlesMaterial::_update_shader() { code += " vec4(1.250, -1.050, -0.203, 0.0),\n"; code += " vec4(0.000, 0.000, 0.000, 0.0)) * hue_rot_s;\n"; if (color_ramp.is_valid()) { - code += " COLOR = hue_rot_mat * textureLod(color_ramp, vec2(tv, 0.0), 0.0);\n"; + code += " COLOR = hue_rot_mat * textureLod(color_ramp, vec2(tv, 0.0), 0.0) * color_value;\n"; } else { code += " COLOR = hue_rot_mat * color_value;\n"; } @@ -1046,10 +1046,6 @@ RID ParticlesMaterial::get_shader_rid() const { } void ParticlesMaterial::_validate_property(PropertyInfo &property) const { - if (property.name == "color" && color_ramp.is_valid()) { - property.usage = PROPERTY_USAGE_NONE; - } - if (property.name == "emission_sphere_radius" && emission_shape != EMISSION_SHAPE_SPHERE) { property.usage = PROPERTY_USAGE_NONE; } diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 98997e482a..26c0d432a9 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -1545,19 +1545,19 @@ CurveTexture::~CurveTexture() { ////////////////// -void Curve3Texture::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_width", "width"), &Curve3Texture::set_width); +void CurveXYZTexture::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_width", "width"), &CurveXYZTexture::set_width); - ClassDB::bind_method(D_METHOD("set_curve_x", "curve"), &Curve3Texture::set_curve_x); - ClassDB::bind_method(D_METHOD("get_curve_x"), &Curve3Texture::get_curve_x); + ClassDB::bind_method(D_METHOD("set_curve_x", "curve"), &CurveXYZTexture::set_curve_x); + ClassDB::bind_method(D_METHOD("get_curve_x"), &CurveXYZTexture::get_curve_x); - ClassDB::bind_method(D_METHOD("set_curve_y", "curve"), &Curve3Texture::set_curve_y); - ClassDB::bind_method(D_METHOD("get_curve_y"), &Curve3Texture::get_curve_y); + ClassDB::bind_method(D_METHOD("set_curve_y", "curve"), &CurveXYZTexture::set_curve_y); + ClassDB::bind_method(D_METHOD("get_curve_y"), &CurveXYZTexture::get_curve_y); - ClassDB::bind_method(D_METHOD("set_curve_z", "curve"), &Curve3Texture::set_curve_z); - ClassDB::bind_method(D_METHOD("get_curve_z"), &Curve3Texture::get_curve_z); + ClassDB::bind_method(D_METHOD("set_curve_z", "curve"), &CurveXYZTexture::set_curve_z); + ClassDB::bind_method(D_METHOD("get_curve_z"), &CurveXYZTexture::get_curve_z); - ClassDB::bind_method(D_METHOD("_update"), &Curve3Texture::_update); + ClassDB::bind_method(D_METHOD("_update"), &CurveXYZTexture::_update); ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,4096"), "set_width", "get_width"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve_x", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_curve_x", "get_curve_x"); @@ -1565,7 +1565,7 @@ void Curve3Texture::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve_z", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_curve_z", "get_curve_z"); } -void Curve3Texture::set_width(int p_width) { +void CurveXYZTexture::set_width(int p_width) { ERR_FAIL_COND(p_width < 32 || p_width > 4096); if (_width == p_width) { @@ -1576,11 +1576,11 @@ void Curve3Texture::set_width(int p_width) { _update(); } -int Curve3Texture::get_width() const { +int CurveXYZTexture::get_width() const { return _width; } -void Curve3Texture::ensure_default_setup(float p_min, float p_max) { +void CurveXYZTexture::ensure_default_setup(float p_min, float p_max) { if (_curve_x.is_null()) { Ref<Curve> curve = Ref<Curve>(memnew(Curve)); curve->add_point(Vector2(0, 1)); @@ -1609,46 +1609,46 @@ void Curve3Texture::ensure_default_setup(float p_min, float p_max) { } } -void Curve3Texture::set_curve_x(Ref<Curve> p_curve) { +void CurveXYZTexture::set_curve_x(Ref<Curve> p_curve) { if (_curve_x != p_curve) { if (_curve_x.is_valid()) { - _curve_x->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Curve3Texture::_update)); + _curve_x->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update)); } _curve_x = p_curve; if (_curve_x.is_valid()) { - _curve_x->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Curve3Texture::_update), varray(), CONNECT_REFERENCE_COUNTED); + _curve_x->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update), varray(), CONNECT_REFERENCE_COUNTED); } _update(); } } -void Curve3Texture::set_curve_y(Ref<Curve> p_curve) { +void CurveXYZTexture::set_curve_y(Ref<Curve> p_curve) { if (_curve_y != p_curve) { if (_curve_y.is_valid()) { - _curve_y->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Curve3Texture::_update)); + _curve_y->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update)); } _curve_y = p_curve; if (_curve_y.is_valid()) { - _curve_y->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Curve3Texture::_update), varray(), CONNECT_REFERENCE_COUNTED); + _curve_y->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update), varray(), CONNECT_REFERENCE_COUNTED); } _update(); } } -void Curve3Texture::set_curve_z(Ref<Curve> p_curve) { +void CurveXYZTexture::set_curve_z(Ref<Curve> p_curve) { if (_curve_z != p_curve) { if (_curve_z.is_valid()) { - _curve_z->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Curve3Texture::_update)); + _curve_z->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update)); } _curve_z = p_curve; if (_curve_z.is_valid()) { - _curve_z->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Curve3Texture::_update), varray(), CONNECT_REFERENCE_COUNTED); + _curve_z->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update), varray(), CONNECT_REFERENCE_COUNTED); } _update(); } } -void Curve3Texture::_update() { +void CurveXYZTexture::_update() { Vector<uint8_t> data; data.resize(_width * sizeof(float) * 3); @@ -1714,28 +1714,28 @@ void Curve3Texture::_update() { emit_changed(); } -Ref<Curve> Curve3Texture::get_curve_x() const { +Ref<Curve> CurveXYZTexture::get_curve_x() const { return _curve_x; } -Ref<Curve> Curve3Texture::get_curve_y() const { +Ref<Curve> CurveXYZTexture::get_curve_y() const { return _curve_y; } -Ref<Curve> Curve3Texture::get_curve_z() const { +Ref<Curve> CurveXYZTexture::get_curve_z() const { return _curve_z; } -RID Curve3Texture::get_rid() const { +RID CurveXYZTexture::get_rid() const { if (!_texture.is_valid()) { _texture = RS::get_singleton()->texture_2d_placeholder_create(); } return _texture; } -Curve3Texture::Curve3Texture() {} +CurveXYZTexture::CurveXYZTexture() {} -Curve3Texture::~Curve3Texture() { +CurveXYZTexture::~CurveXYZTexture() { if (_texture.is_valid()) { RS::get_singleton()->free(_texture); } diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 73390039cb..98aa61138d 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -628,8 +628,8 @@ public: VARIANT_ENUM_CAST(CurveTexture::TextureMode) -class Curve3Texture : public Texture2D { - GDCLASS(Curve3Texture, Texture2D); +class CurveXYZTexture : public Texture2D { + GDCLASS(CurveXYZTexture, Texture2D); RES_BASE_EXTENSION("curvetex") private: @@ -665,8 +665,8 @@ public: virtual int get_height() const override { return 1; } virtual bool has_alpha() const override { return false; } - Curve3Texture(); - ~Curve3Texture(); + CurveXYZTexture(); + ~CurveXYZTexture(); }; class GradientTexture : public Texture2D { 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_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 4e73b8db44..79ea9d72df 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -889,56 +889,56 @@ VisualShaderNodeCurveTexture::VisualShaderNodeCurveTexture() { allow_v_resize = false; } -////////////// Curve3Texture +////////////// CurveXYZTexture -String VisualShaderNodeCurve3Texture::get_caption() const { - return "Curve3Texture"; +String VisualShaderNodeCurveXYZTexture::get_caption() const { + return "CurveXYZTexture"; } -int VisualShaderNodeCurve3Texture::get_input_port_count() const { +int VisualShaderNodeCurveXYZTexture::get_input_port_count() const { return 1; } -VisualShaderNodeCurve3Texture::PortType VisualShaderNodeCurve3Texture::get_input_port_type(int p_port) const { +VisualShaderNodeCurveXYZTexture::PortType VisualShaderNodeCurveXYZTexture::get_input_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeCurve3Texture::get_input_port_name(int p_port) const { +String VisualShaderNodeCurveXYZTexture::get_input_port_name(int p_port) const { return String(); } -int VisualShaderNodeCurve3Texture::get_output_port_count() const { +int VisualShaderNodeCurveXYZTexture::get_output_port_count() const { return 1; } -VisualShaderNodeCurve3Texture::PortType VisualShaderNodeCurve3Texture::get_output_port_type(int p_port) const { +VisualShaderNodeCurveXYZTexture::PortType VisualShaderNodeCurveXYZTexture::get_output_port_type(int p_port) const { return PORT_TYPE_VECTOR; } -String VisualShaderNodeCurve3Texture::get_output_port_name(int p_port) const { +String VisualShaderNodeCurveXYZTexture::get_output_port_name(int p_port) const { return String(); } -void VisualShaderNodeCurve3Texture::set_texture(Ref<Curve3Texture> p_texture) { +void VisualShaderNodeCurveXYZTexture::set_texture(Ref<CurveXYZTexture> p_texture) { texture = p_texture; emit_changed(); } -Ref<Curve3Texture> VisualShaderNodeCurve3Texture::get_texture() const { +Ref<CurveXYZTexture> VisualShaderNodeCurveXYZTexture::get_texture() const { return texture; } -Vector<StringName> VisualShaderNodeCurve3Texture::get_editable_properties() const { +Vector<StringName> VisualShaderNodeCurveXYZTexture::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 { +String VisualShaderNodeCurveXYZTexture::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 { +String VisualShaderNodeCurveXYZTexture::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"; } @@ -948,7 +948,7 @@ String VisualShaderNodeCurve3Texture::generate_code(Shader::Mode p_mode, VisualS return code; } -Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCurve3Texture::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const { +Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCurveXYZTexture::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; @@ -957,18 +957,18 @@ Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCurve3Texture::get_def 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); +void VisualShaderNodeCurveXYZTexture::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_texture", "texture"), &VisualShaderNodeCurveXYZTexture::set_texture); + ClassDB::bind_method(D_METHOD("get_texture"), &VisualShaderNodeCurveXYZTexture::get_texture); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Curve3Texture"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "CurveXYZTexture"), "set_texture", "get_texture"); } -bool VisualShaderNodeCurve3Texture::is_use_prop_slots() const { +bool VisualShaderNodeCurveXYZTexture::is_use_prop_slots() const { return true; } -VisualShaderNodeCurve3Texture::VisualShaderNodeCurve3Texture() { +VisualShaderNodeCurveXYZTexture::VisualShaderNodeCurveXYZTexture() { simple_decl = true; allow_v_resize = false; } diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index 3ae79723e9..33a45a4384 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -338,9 +338,9 @@ public: /////////////////////////////////////// -class VisualShaderNodeCurve3Texture : public VisualShaderNodeResizableBase { - GDCLASS(VisualShaderNodeCurve3Texture, VisualShaderNodeResizableBase); - Ref<Curve3Texture> texture; +class VisualShaderNodeCurveXYZTexture : public VisualShaderNodeResizableBase { + GDCLASS(VisualShaderNodeCurveXYZTexture, VisualShaderNodeResizableBase); + Ref<CurveXYZTexture> texture; protected: static void _bind_methods(); @@ -360,13 +360,13 @@ public: 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; + void set_texture(Ref<CurveXYZTexture> p_value); + Ref<CurveXYZTexture> get_texture() const; virtual Vector<StringName> get_editable_properties() const override; virtual bool is_use_prop_slots() const override; - VisualShaderNodeCurve3Texture(); + VisualShaderNodeCurveXYZTexture(); }; /////////////////////////////////////// diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index 4b123b2d46..cbde7144b7 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -283,22 +283,38 @@ bool PhysicsDirectSpaceState2DSW::cast_motion(const RID &p_shape, const Transfor continue; } - //just do kinematic solving - real_t low = 0; - real_t hi = 1; Vector2 mnormal = p_motion.normalized(); + //just do kinematic solving + real_t low = 0.0; + real_t hi = 1.0; + real_t fraction_coeff = 0.5; for (int j = 0; j < 8; j++) { //steps should be customizable.. - - real_t ofs = (low + hi) * 0.5; + real_t fraction = low + (hi - low) * fraction_coeff; Vector2 sep = mnormal; //important optimization for this to work fast enough - bool collided = CollisionSolver2DSW::solve(shape, p_xform, p_motion * ofs, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, &sep, p_margin); + bool collided = CollisionSolver2DSW::solve(shape, p_xform, p_motion * fraction, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, &sep, p_margin); if (collided) { - hi = ofs; + hi = fraction; + if ((j == 0) || (low > 0.0)) { // Did it not collide before? + // When alternating or first iteration, use dichotomy. + fraction_coeff = 0.5; + } else { + // When colliding again, converge faster towards low fraction + // for more accurate results with long motions that collide near the start. + fraction_coeff = 0.25; + } } else { - low = ofs; + low = fraction; + if ((j == 0) || (hi < 1.0)) { // Did it collide before? + // When alternating or first iteration, use dichotomy. + fraction_coeff = 0.5; + } else { + // When not colliding again, converge faster towards high fraction + // for more accurate results with long motions that collide near the end. + fraction_coeff = 0.75; + } } } @@ -957,20 +973,35 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co } //just do kinematic solving - real_t low = 0; - real_t hi = 1; - + real_t low = 0.0; + real_t hi = 1.0; + real_t fraction_coeff = 0.5; for (int k = 0; k < 8; k++) { //steps should be customizable.. - - real_t ofs = (low + hi) * 0.5; + real_t fraction = low + (hi - low) * fraction_coeff; Vector2 sep = motion_normal; //important optimization for this to work fast enough - bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * ofs, against_shape, col_obj_shape_xform, Vector2(), nullptr, nullptr, &sep, 0); + bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * fraction, against_shape, col_obj_shape_xform, Vector2(), nullptr, nullptr, &sep, 0); if (collided) { - hi = ofs; + hi = fraction; + if ((k == 0) || (low > 0.0)) { // Did it not collide before? + // When alternating or first iteration, use dichotomy. + fraction_coeff = 0.5; + } else { + // When colliding again, converge faster towards low fraction + // for more accurate results with long motions that collide near the start. + fraction_coeff = 0.25; + } } else { - low = ofs; + low = fraction; + if ((k == 0) || (hi < 1.0)) { // Did it collide before? + // When alternating or first iteration, use dichotomy. + fraction_coeff = 0.5; + } else { + // When not colliding again, converge faster towards high fraction + // for more accurate results with long motions that collide near the end. + fraction_coeff = 0.75; + } } } diff --git a/servers/physics_3d/physics_server_3d_sw.cpp b/servers/physics_3d/physics_server_3d_sw.cpp index f26129a404..c1a9d6259d 100644 --- a/servers/physics_3d/physics_server_3d_sw.cpp +++ b/servers/physics_3d/physics_server_3d_sw.cpp @@ -1584,6 +1584,10 @@ void PhysicsServer3DSW::set_active(bool p_active) { active = p_active; }; +void PhysicsServer3DSW::set_collision_iterations(int p_iterations) { + iterations = p_iterations; +}; + void PhysicsServer3DSW::init() { last_step = 0.001; iterations = 8; // 8? diff --git a/servers/physics_3d/physics_server_3d_sw.h b/servers/physics_3d/physics_server_3d_sw.h index 57b6385758..0ccd15fbb2 100644 --- a/servers/physics_3d/physics_server_3d_sw.h +++ b/servers/physics_3d/physics_server_3d_sw.h @@ -367,6 +367,8 @@ public: virtual void end_sync() override; virtual void finish() override; + virtual void set_collision_iterations(int p_iterations) override; + virtual bool is_flushing_queries() const override { return flushing_queries; } int get_process_info(ProcessInfo p_info) override; diff --git a/servers/physics_3d/physics_server_3d_wrap_mt.h b/servers/physics_3d/physics_server_3d_wrap_mt.h index bda2e30dd1..9beec22bcd 100644 --- a/servers/physics_3d/physics_server_3d_wrap_mt.h +++ b/servers/physics_3d/physics_server_3d_wrap_mt.h @@ -377,6 +377,7 @@ public: FUNC1(free, RID); FUNC1(set_active, bool); + FUNC1(set_collision_iterations, int); virtual void init() override; virtual void step(real_t p_step) override; diff --git a/servers/physics_3d/space_3d_sw.cpp b/servers/physics_3d/space_3d_sw.cpp index eff480396d..cdae744ead 100644 --- a/servers/physics_3d/space_3d_sw.cpp +++ b/servers/physics_3d/space_3d_sw.cpp @@ -255,6 +255,8 @@ bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transfor bool best_first = true; + Vector3 motion_normal = p_motion.normalized(); + Vector3 closest_A, closest_B; for (int i = 0; i < amount; i++) { @@ -270,7 +272,7 @@ bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transfor int shape_idx = space->intersection_query_subindex_results[i]; Vector3 point_A, point_B; - Vector3 sep_axis = p_motion.normalized(); + Vector3 sep_axis = motion_normal; Transform3D col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); //test initial overlap, does it collide if going all the way? @@ -279,35 +281,47 @@ bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transfor } //test initial overlap, ignore objects it's inside of. - sep_axis = p_motion.normalized(); + sep_axis = motion_normal; if (!CollisionSolver3DSW::solve_distance(shape, p_xform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, aabb, &sep_axis)) { continue; } //just do kinematic solving - real_t low = 0; - real_t hi = 1; - Vector3 mnormal = p_motion.normalized(); - + real_t low = 0.0; + real_t hi = 1.0; + real_t fraction_coeff = 0.5; for (int j = 0; j < 8; j++) { //steps should be customizable.. + real_t fraction = low + (hi - low) * fraction_coeff; - real_t ofs = (low + hi) * 0.5; - - Vector3 sep = mnormal; //important optimization for this to work fast enough - - mshape.motion = xform_inv.basis.xform(p_motion * ofs); + mshape.motion = xform_inv.basis.xform(p_motion * fraction); Vector3 lA, lB; - + Vector3 sep = motion_normal; //important optimization for this to work fast enough bool collided = !CollisionSolver3DSW::solve_distance(&mshape, p_xform, col_obj->get_shape(shape_idx), col_obj_xform, lA, lB, aabb, &sep); if (collided) { - hi = ofs; + hi = fraction; + if ((j == 0) || (low > 0.0)) { // Did it not collide before? + // When alternating or first iteration, use dichotomy. + fraction_coeff = 0.5; + } else { + // When colliding again, converge faster towards low fraction + // for more accurate results with long motions that collide near the start. + fraction_coeff = 0.25; + } } else { point_A = lA; point_B = lB; - low = ofs; + low = fraction; + if ((j == 0) || (hi < 1.0)) { // Did it collide before? + // When alternating or first iteration, use dichotomy. + fraction_coeff = 0.5; + } else { + // When not colliding again, converge faster towards high fraction + // for more accurate results with long motions that collide near the end. + fraction_coeff = 0.75; + } } } @@ -902,27 +916,40 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, co } //just do kinematic solving - real_t low = 0; - real_t hi = 1; - + real_t low = 0.0; + real_t hi = 1.0; + real_t fraction_coeff = 0.5; for (int k = 0; k < 8; k++) { //steps should be customizable.. + real_t fraction = low + (hi - low) * fraction_coeff; - real_t ofs = (low + hi) * 0.5; - - Vector3 sep = motion_normal; //important optimization for this to work fast enough - - mshape.motion = body_shape_xform_inv.basis.xform(p_motion * ofs); + mshape.motion = body_shape_xform_inv.basis.xform(p_motion * fraction); Vector3 lA, lB; - + Vector3 sep = motion_normal; //important optimization for this to work fast enough bool collided = !CollisionSolver3DSW::solve_distance(&mshape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj_xform, lA, lB, motion_aabb, &sep); if (collided) { - hi = ofs; + hi = fraction; + if ((k == 0) || (low > 0.0)) { // Did it not collide before? + // When alternating or first iteration, use dichotomy. + fraction_coeff = 0.5; + } else { + // When colliding again, converge faster towards low fraction + // for more accurate results with long motions that collide near the start. + fraction_coeff = 0.25; + } } else { point_A = lA; point_B = lB; - low = ofs; + low = fraction; + if ((k == 0) || (hi < 1.0)) { // Did it collide before? + // When alternating or first iteration, use dichotomy. + fraction_coeff = 0.5; + } else { + // When not colliding again, converge faster towards high fraction + // for more accurate results with long motions that collide near the end. + fraction_coeff = 0.75; + } } } diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h index 6737aacaf0..e2bff2975e 100644 --- a/servers/physics_server_2d.h +++ b/servers/physics_server_2d.h @@ -564,7 +564,7 @@ public: virtual bool is_flushing_queries() const = 0; - virtual void set_collision_iterations(int iterations) = 0; + virtual void set_collision_iterations(int p_iterations) = 0; enum ProcessInfo { INFO_ACTIVE_OBJECTS, diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index 7a0253506c..3ed8841119 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -740,6 +740,8 @@ void PhysicsServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_active", "active"), &PhysicsServer3D::set_active); + ClassDB::bind_method(D_METHOD("set_collision_iterations", "iterations"), &PhysicsServer3D::set_collision_iterations); + ClassDB::bind_method(D_METHOD("get_process_info", "process_info"), &PhysicsServer3D::get_process_info); BIND_ENUM_CONSTANT(SHAPE_PLANE); diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index 78fc026747..17bae9a057 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -740,6 +740,8 @@ public: virtual bool is_flushing_queries() const = 0; + virtual void set_collision_iterations(int p_iterations) = 0; + enum ProcessInfo { INFO_ACTIVE_OBJECTS, INFO_COLLISION_PAIRS, diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index ef82ce5cae..717b4e8d14 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -120,106 +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<RDPipelineSpecializationConstant>(); - - 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/rasterizer_dummy.h b/servers/rendering/rasterizer_dummy.h index f22ca738ae..3f751cfbe8 100644 --- a/servers/rendering/rasterizer_dummy.h +++ b/servers/rendering/rasterizer_dummy.h @@ -61,6 +61,7 @@ public: void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override {} void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) override {} void geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override {} + void geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) override {} void geometry_instance_free(GeometryInstance *p_geometry_instance) override {} @@ -413,6 +414,7 @@ public: RS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light) override { return RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID; } bool light_has_shadow(RID p_light) const override { return false; } + bool light_has_projector(RID p_light) const override { return false; } RS::LightType light_get_type(RID p_light) const override { return RS::LIGHT_OMNI; } AABB light_get_aabb(RID p_light) const override { return AABB(); } diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index 22bfd03115..b457f5d122 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -318,11 +318,11 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p RID prev_pipeline_rd; RID prev_xforms_uniform_set; - bool shadow_pass = (p_params->pass_mode == PASS_MODE_SHADOW) || (p_params->pass_mode == PASS_MODE_SHADOW_DP); + bool shadow_pass = (p_pass_mode == PASS_MODE_SHADOW) || (p_pass_mode == PASS_MODE_SHADOW_DP); SceneState::PushConstant push_constant; - if (p_params->pass_mode == PASS_MODE_DEPTH_MATERIAL) { + if (p_pass_mode == PASS_MODE_DEPTH_MATERIAL) { push_constant.uv_offset = Math::make_half_float(p_params->uv_offset.y) << 16; push_constant.uv_offset |= Math::make_half_float(p_params->uv_offset.x); } else { @@ -339,7 +339,7 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p SceneShaderForwardClustered::ShaderData *shader; void *mesh_surface; - if (shadow_pass || p_params->pass_mode == PASS_MODE_DEPTH) { //regular depth pass can use these too + if (shadow_pass || p_pass_mode == PASS_MODE_DEPTH) { //regular depth pass can use these too material_uniform_set = surf->material_uniform_set_shadow; shader = surf->shader_shadow; mesh_surface = surf->surface_shadow; @@ -369,7 +369,7 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p //find cull variant SceneShaderForwardClustered::ShaderData::CullVariant cull_variant; - if (p_params->pass_mode == PASS_MODE_DEPTH_MATERIAL || p_params->pass_mode == PASS_MODE_SDF || ((p_params->pass_mode == PASS_MODE_SHADOW || p_params->pass_mode == PASS_MODE_SHADOW_DP) && surf->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_DOUBLE_SIDED_SHADOWS)) { + if (p_pass_mode == PASS_MODE_DEPTH_MATERIAL || p_pass_mode == PASS_MODE_SDF || ((p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_SHADOW_DP) && surf->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_DOUBLE_SIDED_SHADOWS)) { cull_variant = SceneShaderForwardClustered::ShaderData::CULL_VARIANT_DOUBLE_SIDED; } else { bool mirror = surf->owner->mirror; @@ -384,14 +384,30 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p SceneShaderForwardClustered::ShaderVersion shader_version = SceneShaderForwardClustered::SHADER_VERSION_MAX; // Assigned to silence wrong -Wmaybe-initialized. - switch (p_params->pass_mode) { + uint32_t pipeline_specialization = 0; + + if (p_pass_mode == PASS_MODE_COLOR || p_pass_mode == PASS_MODE_COLOR_TRANSPARENT || p_pass_mode == PASS_MODE_COLOR_SPECULAR) { + if (element_info.uses_softshadow) { + pipeline_specialization |= SceneShaderForwardClustered::SHADER_SPECIALIZATION_SOFT_SHADOWS; + } + if (element_info.uses_projector) { + pipeline_specialization |= SceneShaderForwardClustered::SHADER_SPECIALIZATION_PROJECTOR; + } + + if (p_params->use_directional_soft_shadow) { + pipeline_specialization |= SceneShaderForwardClustered::SHADER_SPECIALIZATION_DIRECTIONAL_SOFT_SHADOWS; + } + } + + switch (p_pass_mode) { case PASS_MODE_COLOR: case PASS_MODE_COLOR_TRANSPARENT: { if (element_info.uses_lightmap) { shader_version = SceneShaderForwardClustered::SHADER_VERSION_LIGHTMAP_COLOR_PASS; - } else if (element_info.uses_forward_gi) { - shader_version = SceneShaderForwardClustered::SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI; } else { + if (element_info.uses_forward_gi) { + pipeline_specialization |= SceneShaderForwardClustered::SHADER_SPECIALIZATION_FORWARD_GI; + } shader_version = SceneShaderForwardClustered::SHADER_VERSION_COLOR_PASS; } } break; @@ -452,7 +468,7 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p prev_index_array_rd = index_array_rd; } - RID pipeline_rd = pipeline->get_render_pipeline(vertex_format, framebuffer_format, p_params->force_wireframe); + RID pipeline_rd = pipeline->get_render_pipeline(vertex_format, framebuffer_format, p_params->force_wireframe, 0, pipeline_specialization); if (pipeline_rd != prev_pipeline_rd) { // checking with prev shader does not make so much sense, as @@ -848,7 +864,7 @@ void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, i bool cant_repeat = instance_data.flags & INSTANCE_DATA_FLAG_MULTIMESH || inst->mesh_instance.is_valid(); - if (prev_surface != nullptr && !cant_repeat && prev_surface->sort.sort_key1 == surface->sort.sort_key1 && prev_surface->sort.sort_key2 == surface->sort.sort_key2) { + if (prev_surface != nullptr && !cant_repeat && prev_surface->sort.sort_key1 == surface->sort.sort_key1 && prev_surface->sort.sort_key2 == surface->sort.sort_key2 && repeats < RenderElementInfo::MAX_REPEATS) { //this element is the same as the previous one, count repeats to draw it using instancing repeats++; } else { @@ -868,6 +884,8 @@ void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, i element_info.lod_index = surface->sort.lod_index; element_info.uses_forward_gi = surface->sort.uses_forward_gi; element_info.uses_lightmap = surface->sort.uses_lightmap; + element_info.uses_softshadow = surface->sort.uses_softshadow; + element_info.uses_projector = surface->sort.uses_projector; if (cant_repeat) { prev_surface = nullptr; @@ -1375,7 +1393,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, nullptr, RID()); bool finish_depth = using_ssao || using_sdfgi || using_voxelgi; - RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, depth_pass_mode, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold); + RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, depth_pass_mode, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold); _render_list_with_threads(&render_list_params, depth_framebuffer, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, finish_depth ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, needs_pre_resolve ? Vector<Color>() : depth_pass_clear); RD::get_singleton()->draw_command_end_label(); @@ -1432,7 +1450,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co } RID framebuffer = using_separate_specular ? opaque_specular_framebuffer : opaque_framebuffer; - RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold); + RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold); _render_list_with_threads(&render_list_params, framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, depth_pre_pass ? (continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP) : RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0); if (will_continue_color && using_separate_specular) { // close the specular framebuffer, as it's no longer used @@ -1529,7 +1547,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false); { - RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), false, PASS_MODE_COLOR, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold); + RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), false, PASS_MODE_COLOR, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold); _render_list_with_threads(&render_list_params, alpha_framebuffer, can_continue_color ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ); } @@ -1631,7 +1649,7 @@ void RenderForwardClustered::_render_shadow_end(uint32_t p_barrier) { for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) { SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i]; - RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, true, shadow_pass.rp_uniform_set, false, Vector2(), shadow_pass.camera_plane, shadow_pass.lod_distance_multiplier, shadow_pass.screen_lod_threshold, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER); + RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, true, false, shadow_pass.rp_uniform_set, false, Vector2(), shadow_pass.camera_plane, shadow_pass.lod_distance_multiplier, shadow_pass.screen_lod_threshold, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER); _render_list_with_threads(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, shadow_pass.final_depth_action, Vector<Color>(), 1.0, 0, shadow_pass.rect); } @@ -1672,7 +1690,7 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con { //regular forward for now - RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), false, pass_mode, true, rp_uniform_set); + RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), false, pass_mode, true, false, rp_uniform_set); _render_list_with_threads(&render_list_params, p_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ); } RD::get_singleton()->draw_command_end_label(); @@ -1707,7 +1725,7 @@ void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform RENDER_TIMESTAMP("Render Material"); { - RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, rp_uniform_set); + RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, false, rp_uniform_set); //regular forward for now Vector<Color> clear; clear.push_back(Color(0, 0, 0, 0)); @@ -1750,7 +1768,7 @@ void RenderForwardClustered::_render_uv2(const PagedArray<GeometryInstance *> &p RENDER_TIMESTAMP("Render Material"); { - RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, rp_uniform_set, true); + RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, false, rp_uniform_set, true); //regular forward for now Vector<Color> clear; clear.push_back(Color(0, 0, 0, 0)); @@ -1868,7 +1886,7 @@ void RenderForwardClustered::_render_sdfgi(RID p_render_buffers, const Vector3i E = sdfgi_framebuffer_size_cache.insert(fb_size, fb); } - RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, rp_uniform_set, false); + RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, false, rp_uniform_set, false); _render_list_with_threads(&render_list_params, E->get(), RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, Rect2(), sbs); } @@ -2511,12 +2529,14 @@ void RenderForwardClustered::_geometry_instance_add_surface_with_material(Geomet sdcache->sort.sort_key2 = 0; sdcache->sort.surface_index = p_surface; - sdcache->sort.material_id_low = p_material_id & 0x3FFF; - sdcache->sort.material_id_hi = p_material_id >> 14; + sdcache->sort.material_id_low = p_material_id & 0xFFFF; + sdcache->sort.material_id_hi = p_material_id >> 16; sdcache->sort.shader_id = p_shader_id; sdcache->sort.geometry_id = p_mesh.get_local_index(); //only meshes can repeat anyway sdcache->sort.uses_forward_gi = ginstance->can_sdfgi; sdcache->sort.priority = p_material->priority; + sdcache->sort.uses_projector = ginstance->using_projectors; + sdcache->sort.uses_softshadow = ginstance->using_softshadows; } void RenderForwardClustered::_geometry_instance_add_surface(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, RID p_material, RID p_mesh) { @@ -2911,6 +2931,14 @@ void RenderForwardClustered::geometry_instance_pair_voxel_gi_instances(GeometryI } } +void RenderForwardClustered::geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) { + GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); + ERR_FAIL_COND(!ginstance); + ginstance->using_projectors = p_projector; + ginstance->using_softshadows = p_softshadow; + _geometry_instance_mark_dirty(ginstance); +} + RenderForwardClustered::RenderForwardClustered(RendererStorageRD *p_storage) : RendererSceneRenderRD(p_storage) { singleton = this; diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h index 750c0167e7..b70cefd980 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h @@ -156,8 +156,9 @@ class RenderForwardClustered : public RendererSceneRenderRD { RD::FramebufferFormatID framebuffer_format = 0; uint32_t element_offset = 0; uint32_t barrier = RD::BARRIER_MASK_ALL; + bool use_directional_soft_shadow = false; - RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL) { + RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, bool p_use_directional_soft_shadows, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL) { elements = p_elements; element_info = p_element_info; element_count = p_element_count; @@ -172,6 +173,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { screen_lod_threshold = p_screen_lod_threshold; element_offset = p_element_offset; barrier = p_barrier; + use_directional_soft_shadow = p_use_directional_soft_shadows; } }; @@ -353,7 +355,10 @@ class RenderForwardClustered : public RendererSceneRenderRD { void _setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform3D &p_cam_transform); struct RenderElementInfo { - uint32_t repeat : 22; + enum { MAX_REPEATS = (1 << 20) - 1 }; + uint32_t repeat : 20; + uint32_t uses_projector : 1; + uint32_t uses_softshadow : 1; uint32_t uses_lightmap : 1; uint32_t uses_forward_gi : 1; uint32_t lod_index : 8; @@ -402,12 +407,14 @@ class RenderForwardClustered : public RendererSceneRenderRD { union { struct { uint64_t lod_index : 8; - uint64_t surface_index : 10; + uint64_t surface_index : 8; uint64_t geometry_id : 32; - uint64_t material_id_low : 14; + uint64_t material_id_low : 16; - uint64_t material_id_hi : 18; + uint64_t material_id_hi : 16; uint64_t shader_id : 32; + uint64_t uses_softshadow : 1; + uint64_t uses_projector : 1; uint64_t uses_forward_gi : 1; uint64_t uses_lightmap : 1; uint64_t depth_layer : 4; @@ -455,6 +462,8 @@ class RenderForwardClustered : public RendererSceneRenderRD { uint32_t trail_steps = 1; RID mesh_instance; bool can_sdfgi = false; + bool using_projectors = false; + bool using_softshadows = false; //used during setup uint32_t base_flags = 0; Transform3D transform; @@ -604,6 +613,8 @@ public: virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) override; virtual void geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override; + virtual void geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) override; + virtual bool free(RID p_rid) override; RenderForwardClustered(RendererStorageRD *p_storage); diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index d39823a1a3..706a75e641 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -287,7 +287,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { multisample_state.enable_alpha_to_one = true; } - if (k == SHADER_VERSION_COLOR_PASS || k == SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI || k == SHADER_VERSION_LIGHTMAP_COLOR_PASS) { + if (k == SHADER_VERSION_COLOR_PASS || k == SHADER_VERSION_LIGHTMAP_COLOR_PASS) { blend_state = blend_state_blend; if (depth_draw == DEPTH_DRAW_OPAQUE) { depth_stencil.enable_depth_write = false; //alpha does not draw depth @@ -305,7 +305,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { continue; // do not use this version (will error if using it is attempted) } } else { - if (k == SHADER_VERSION_COLOR_PASS || k == SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI || k == SHADER_VERSION_LIGHTMAP_COLOR_PASS) { + if (k == SHADER_VERSION_COLOR_PASS || k == SHADER_VERSION_LIGHTMAP_COLOR_PASS) { blend_state = blend_state_opaque; } else if (k == SHADER_VERSION_DEPTH_PASS || k == SHADER_VERSION_DEPTH_PASS_DP) { //none, leave empty @@ -483,7 +483,6 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_MATERIAL\n"); // SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_SDF\n"); // SHADER_VERSION_DEPTH_PASS_WITH_SDF shader_versions.push_back(""); // SHADER_VERSION_COLOR_PASS - shader_versions.push_back("\n#define USE_FORWARD_GI\n"); // SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI shader_versions.push_back("\n#define MODE_MULTIPLE_RENDER_TARGETS\n"); // SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR shader_versions.push_back("\n#define USE_LIGHTMAP\n"); // SHADER_VERSION_LIGHTMAP_COLOR_PASS shader_versions.push_back("\n#define MODE_MULTIPLE_RENDER_TARGETS\n#define USE_LIGHTMAP\n"); // SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h index 810b1f3876..8dfd18cca5 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h @@ -52,7 +52,6 @@ public: SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL, SHADER_VERSION_DEPTH_PASS_WITH_SDF, SHADER_VERSION_COLOR_PASS, - SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI, SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR, SHADER_VERSION_LIGHTMAP_COLOR_PASS, SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR, @@ -60,6 +59,13 @@ public: SHADER_VERSION_MAX }; + enum ShaderSpecializations { + SHADER_SPECIALIZATION_FORWARD_GI = 1 << 0, + SHADER_SPECIALIZATION_PROJECTOR = 1 << 1, + SHADER_SPECIALIZATION_SOFT_SHADOWS = 1 << 2, + SHADER_SPECIALIZATION_DIRECTIONAL_SOFT_SHADOWS = 1 << 3, + }; + struct ShaderData : public RendererStorageRD::ShaderData { enum BlendMode { //used internally BLEND_MODE_MIX, diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index 7fbd6e23b0..29cb597798 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -1801,6 +1801,9 @@ void RenderForwardMobile::geometry_instance_pair_voxel_gi_instances(GeometryInst // We do not have this here! } +void RenderForwardMobile::geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) { +} + void RenderForwardMobile::_geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance) { GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); if (ginstance->dirty_list_element.in_list()) { diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h index f40f713c03..53650a7a5e 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h @@ -594,6 +594,8 @@ public: virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) override; virtual void geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override; + virtual void geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) override; + virtual bool free(RID p_rid) override; virtual bool is_dynamic_gi_supported() const override; diff --git a/servers/rendering/renderer_rd/pipeline_cache_rd.cpp b/servers/rendering/renderer_rd/pipeline_cache_rd.cpp index 22888ddbe5..2bdd523920 100644 --- a/servers/rendering/renderer_rd/pipeline_cache_rd.cpp +++ b/servers/rendering/renderer_rd/pipeline_cache_rd.cpp @@ -31,14 +31,30 @@ #include "pipeline_cache_rd.h" #include "core/os/memory.h" -RID PipelineCacheRD::_generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe, uint32_t p_render_pass) { +RID PipelineCacheRD::_generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe, uint32_t p_render_pass, uint32_t p_bool_specializations) { RD::PipelineMultisampleState multisample_state_version = multisample_state; multisample_state_version.sample_count = RD::get_singleton()->framebuffer_format_get_texture_samples(p_framebuffer_format_id, p_render_pass); RD::PipelineRasterizationState raster_state_version = rasterization_state; raster_state_version.wireframe = p_wireframe; - RID pipeline = RD::get_singleton()->render_pipeline_create(shader, p_framebuffer_format_id, p_vertex_format_id, render_primitive, raster_state_version, multisample_state_version, depth_stencil_state, blend_state, dynamic_state_flags, p_render_pass); + Vector<RD::PipelineSpecializationConstant> specialization_constants = base_specialization_constants; + + uint32_t bool_index = 0; + uint32_t bool_specializations = p_bool_specializations; + while (bool_specializations) { + if (bool_specializations & (1 << bool_index)) { + RD::PipelineSpecializationConstant sc; + sc.bool_value = true; + sc.constant_id = bool_index; + sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL; + specialization_constants.push_back(sc); + bool_specializations &= ~(1 << bool_index); + } + bool_index++; + } + + RID pipeline = RD::get_singleton()->render_pipeline_create(shader, p_framebuffer_format_id, p_vertex_format_id, render_primitive, raster_state_version, multisample_state_version, depth_stencil_state, blend_state, dynamic_state_flags, p_render_pass, specialization_constants); ERR_FAIL_COND_V(pipeline.is_null(), RID()); versions = (Version *)memrealloc(versions, sizeof(Version) * (version_count + 1)); versions[version_count].framebuffer_id = p_framebuffer_format_id; @@ -46,6 +62,7 @@ RID PipelineCacheRD::_generate_version(RD::VertexFormatID p_vertex_format_id, RD versions[version_count].wireframe = p_wireframe; versions[version_count].pipeline = pipeline; versions[version_count].render_pass = p_render_pass; + versions[version_count].bool_specializations = p_bool_specializations; version_count++; return pipeline; } @@ -64,7 +81,7 @@ void PipelineCacheRD::_clear() { } } -void PipelineCacheRD::setup(RID p_shader, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags) { +void PipelineCacheRD::setup(RID p_shader, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags, const Vector<RD::PipelineSpecializationConstant> &p_base_specialization_constants) { ERR_FAIL_COND(p_shader.is_null()); _clear(); shader = p_shader; @@ -75,6 +92,7 @@ void PipelineCacheRD::setup(RID p_shader, RD::RenderPrimitive p_primitive, const depth_stencil_state = p_depth_stencil_state; blend_state = p_blend_state; dynamic_state_flags = p_dynamic_state_flags; + base_specialization_constants = p_base_specialization_constants; } void PipelineCacheRD::update_shader(RID p_shader) { diff --git a/servers/rendering/renderer_rd/pipeline_cache_rd.h b/servers/rendering/renderer_rd/pipeline_cache_rd.h index 387a8a038f..71e26283e1 100644 --- a/servers/rendering/renderer_rd/pipeline_cache_rd.h +++ b/servers/rendering/renderer_rd/pipeline_cache_rd.h @@ -46,27 +46,29 @@ class PipelineCacheRD { RD::PipelineDepthStencilState depth_stencil_state; RD::PipelineColorBlendState blend_state; int dynamic_state_flags; + Vector<RD::PipelineSpecializationConstant> base_specialization_constants; struct Version { RD::VertexFormatID vertex_id; RD::FramebufferFormatID framebuffer_id; uint32_t render_pass; bool wireframe; + uint32_t bool_specializations; RID pipeline; }; Version *versions; uint32_t version_count; - RID _generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe, uint32_t p_render_pass); + RID _generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe, uint32_t p_render_pass, uint32_t p_bool_specializations = 0); void _clear(); public: - void setup(RID p_shader, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0); + void setup(RID p_shader, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0, const Vector<RD::PipelineSpecializationConstant> &p_base_specialization_constants = Vector<RD::PipelineSpecializationConstant>()); void update_shader(RID p_shader); - _FORCE_INLINE_ RID get_render_pipeline(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe = false, uint32_t p_render_pass = 0) { + _FORCE_INLINE_ RID get_render_pipeline(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe = false, uint32_t p_render_pass = 0, uint32_t p_bool_specializations = 0) { #ifdef DEBUG_ENABLED ERR_FAIL_COND_V_MSG(shader.is_null(), RID(), "Attempted to use an unused shader variant (shader is null),"); @@ -75,13 +77,13 @@ public: spin_lock.lock(); RID result; for (uint32_t i = 0; i < version_count; i++) { - if (versions[i].vertex_id == p_vertex_format_id && versions[i].framebuffer_id == p_framebuffer_format_id && versions[i].wireframe == p_wireframe && versions[i].render_pass == p_render_pass) { + if (versions[i].vertex_id == p_vertex_format_id && versions[i].framebuffer_id == p_framebuffer_format_id && versions[i].wireframe == p_wireframe && versions[i].render_pass == p_render_pass && versions[i].bool_specializations == p_bool_specializations) { result = versions[i].pipeline; spin_lock.unlock(); return result; } } - result = _generate_version(p_vertex_format_id, p_framebuffer_format_id, p_wireframe, p_render_pass); + result = _generate_version(p_vertex_format_id, p_framebuffer_format_id, p_wireframe, p_render_pass, p_bool_specializations); spin_lock.unlock(); return result; } diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp index a8f086b0f9..e6ae66d56f 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp @@ -173,7 +173,6 @@ void RendererCompositorRD::set_boot_image(const Ref<Image> &p_image, const Color } Size2 window_size = DisplayServer::get_singleton()->window_get_size(); - print_line("window size: " + window_size); Rect2 imgrect(0, 0, p_image->get_width(), p_image->get_height()); Rect2 screenrect; @@ -216,8 +215,6 @@ void RendererCompositorRD::set_boot_image(const Ref<Image> &p_image, const Color blit.push_constant.upscale = 1.0; blit.push_constant.aspect_ratio = 1.0; - print_line("rect: " + screenrect); - RD::get_singleton()->draw_list_set_push_constant(draw_list, &blit.push_constant, sizeof(BlitPushConstant)); RD::get_singleton()->draw_list_draw(draw_list, true); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index a70514e9e5..3b7c14d4ff 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -2377,7 +2377,7 @@ void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflecti } } -void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const Transform3D &p_camera_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count) { +void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const Transform3D &p_camera_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count, bool &r_directional_light_soft_shadows) { Transform3D inverse_transform = p_camera_transform.affine_inverse(); r_directional_light_count = 0; @@ -2389,6 +2389,8 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const cluster.omni_light_count = 0; cluster.spot_light_count = 0; + r_directional_light_soft_shadows = false; + for (int i = 0; i < (int)p_lights.size(); i++) { LightInstance *li = light_instance_owner.getornull(p_lights[i]); if (!li) { @@ -2427,6 +2429,9 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const // technically this will keep expanding until reaching the sun, but all we care // is expand until we reach the radius of the near plane (there can't be more occluders than that) angular_diameter = Math::tan(Math::deg2rad(angular_diameter)); + if (storage->light_has_shadow(base)) { + r_directional_light_soft_shadows = true; + } } else { angular_diameter = 0.0; } @@ -3621,7 +3626,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool uint32_t directional_light_count = 0; uint32_t positional_light_count = 0; - _setup_lights(*p_render_data->lights, p_render_data->cam_transform, p_render_data->shadow_atlas, using_shadows, directional_light_count, positional_light_count); + _setup_lights(*p_render_data->lights, p_render_data->cam_transform, p_render_data->shadow_atlas, using_shadows, directional_light_count, positional_light_count, p_render_data->directional_light_soft_shadows); _setup_decals(*p_render_data->decals, p_render_data->cam_transform.affine_inverse()); p_render_data->directional_light_count = directional_light_count; diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index be3d3551c7..69c56cf4a7 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -80,6 +80,7 @@ struct RenderDataRD { uint32_t cluster_max_elements = 0; uint32_t directional_light_count = 0; + bool directional_light_soft_shadows = false; RendererScene::RenderInfo *render_info = nullptr; }; @@ -99,7 +100,7 @@ protected: }; virtual RenderBufferData *_create_render_buffer_data() = 0; - void _setup_lights(const PagedArray<RID> &p_lights, const Transform3D &p_camera_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count); + void _setup_lights(const PagedArray<RID> &p_lights, const Transform3D &p_camera_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count, bool &r_directional_light_soft_shadows); void _setup_decals(const PagedArray<RID> &p_decals, const Transform3D &p_camera_inverse_xform); void _setup_reflections(const PagedArray<RID> &p_reflections, const Transform3D &p_camera_inverse_transform, RID p_environment); diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp index 6738f499bd..8e79f33dfa 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp @@ -2531,6 +2531,8 @@ void RendererStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_su Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND(!mesh); + ERR_FAIL_COND(mesh->surface_count == RS::MAX_MESH_SURFACES); + #ifdef DEBUG_ENABLED //do a validation, to catch errors first { @@ -5886,6 +5888,10 @@ void RendererStorageRD::light_set_param(RID p_light, RS::LightParam p_param, flo ERR_FAIL_COND(!light); ERR_FAIL_INDEX(p_param, RS::LIGHT_PARAM_MAX); + if (light->param[p_param] == p_value) { + return; + } + switch (p_param) { case RS::LIGHT_PARAM_RANGE: case RS::LIGHT_PARAM_SPOT_ANGLE: @@ -5899,6 +5905,12 @@ void RendererStorageRD::light_set_param(RID p_light, RS::LightParam p_param, flo light->version++; light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT); } break; + case RS::LIGHT_PARAM_SIZE: { + if ((light->param[p_param] > CMP_EPSILON) != (p_value > CMP_EPSILON)) { + //changing from no size to size and the opposite + light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR); + } + } break; default: { } } @@ -5935,8 +5947,11 @@ void RendererStorageRD::light_set_projector(RID p_light, RID p_texture) { light->projector = p_texture; - if (light->type != RS::LIGHT_DIRECTIONAL && light->projector.is_valid()) { - texture_add_to_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI); + if (light->type != RS::LIGHT_DIRECTIONAL) { + if (light->projector.is_valid()) { + texture_add_to_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI); + } + light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR); } } diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h index 1a33569c33..f471874c8e 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.h +++ b/servers/rendering/renderer_rd/renderer_storage_rd.h @@ -1888,6 +1888,13 @@ public: return light->shadow; } + _FORCE_INLINE_ bool light_has_projector(RID p_light) const { + const Light *light = light_owner.getornull(p_light); + ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL); + + return texture_owner.owns(light->projector); + } + _FORCE_INLINE_ bool light_is_negative(RID p_light) const { const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL); diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl index 74d5af5cb6..763c3895a9 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl @@ -356,6 +356,13 @@ void main() { #VERSION_DEFINES +/* Specialization Constants */ + +layout(constant_id = 0) const bool sc_use_forward_gi = false; +layout(constant_id = 1) const bool sc_use_light_projector = false; +layout(constant_id = 2) const bool sc_use_light_soft_shadows = false; +layout(constant_id = 3) const bool sc_use_directional_soft_shadows = false; + #include "scene_forward_clustered_inc.glsl" /* Varyings */ @@ -450,12 +457,8 @@ layout(location = 0) out vec4 frag_color; #include "scene_forward_lights_inc.glsl" -#ifdef USE_FORWARD_GI - #include "scene_forward_gi_inc.glsl" -#endif //USE_FORWARD_GI - #endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) #ifndef MODE_RENDER_DEPTH @@ -963,9 +966,9 @@ void main() { ambient_light += textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw, 0.0).rgb; } } -#elif defined(USE_FORWARD_GI) +#else - if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_SDFGI)) { //has lightmap capture + if (sc_use_forward_gi && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_SDFGI)) { //has lightmap capture //make vertex orientation the world one, but still align to camera vec3 cam_pos = mat3(scene_data.camera_matrix) * vertex; @@ -1037,7 +1040,7 @@ void main() { } } - if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_VOXEL_GI)) { // process voxel_gi_instances + if (sc_use_forward_gi && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_VOXEL_GI)) { // process voxel_gi_instances uint index1 = instances.data[instance_index].gi_offset & 0xFFFF; vec3 ref_vec = normalize(reflect(normalize(vertex), normal)); @@ -1068,9 +1071,8 @@ void main() { specular_light = spec_accum.rgb; ambient_light = amb_accum.rgb; } -#else - if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GI_BUFFERS)) { //use GI buffers + if (!sc_use_forward_gi && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GI_BUFFERS)) { //use GI buffers vec2 coord; @@ -1101,7 +1103,7 @@ void main() { ambient_light = mix(ambient_light, buffer_ambient.rgb, buffer_ambient.a); specular_light = mix(specular_light, buffer_reflection.rgb, buffer_reflection.a); } -#endif +#endif // !USE_LIGHTMAP if (scene_data.ssao_enabled) { float ssao = texture(sampler2D(ao_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv).r; @@ -1228,14 +1230,13 @@ void main() { float shadow = 1.0; -#ifdef USE_SOFT_SHADOWS //version with soft shadows, more expensive if (directional_lights.data[i].shadow_enabled) { - float depth_z = -vertex.z; + if (sc_use_directional_soft_shadows && directional_lights.data[i].softshadow_angle > 0) { + float depth_z = -vertex.z; - vec4 pssm_coord; - vec3 shadow_color = vec3(0.0); - vec3 light_dir = directional_lights.data[i].direction; + vec3 shadow_color = vec3(0.0); + vec3 light_dir = directional_lights.data[i].direction; #define BIAS_FUNC(m_var, m_idx) \ m_var.xyz += light_dir * directional_lights.data[i].shadow_bias[m_idx]; \ @@ -1243,168 +1244,105 @@ void main() { normal_bias -= light_dir * dot(light_dir, normal_bias); \ m_var.xyz += normal_bias; - if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { - vec4 v = vec4(vertex, 1.0); + uint blend_index = 0; - BIAS_FUNC(v, 0) + if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { + vec4 v = vec4(vertex, 1.0); - pssm_coord = (directional_lights.data[i].shadow_matrix1 * v); - pssm_coord /= pssm_coord.w; + BIAS_FUNC(v, 0) + + vec4 pssm_coord = (directional_lights.data[i].shadow_matrix1 * v); + pssm_coord /= pssm_coord.w; - if (directional_lights.data[i].softshadow_angle > 0) { float range_pos = dot(directional_lights.data[i].direction, v.xyz); float range_begin = directional_lights.data[i].shadow_range_begin.x; float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; vec2 tex_scale = directional_lights.data[i].uv_scale1 * test_radius; shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); - } else { - shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); + blend_index++; } - shadow_color = directional_lights.data[i].shadow_color1.rgb; - - } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { - vec4 v = vec4(vertex, 1.0); + if (blend_index < 2 && depth_z < directional_lights.data[i].shadow_split_offsets.y) { + vec4 v = vec4(vertex, 1.0); - BIAS_FUNC(v, 1) + BIAS_FUNC(v, 1) - pssm_coord = (directional_lights.data[i].shadow_matrix2 * v); - pssm_coord /= pssm_coord.w; + vec4 pssm_coord = (directional_lights.data[i].shadow_matrix2 * v); + pssm_coord /= pssm_coord.w; - if (directional_lights.data[i].softshadow_angle > 0) { float range_pos = dot(directional_lights.data[i].direction, v.xyz); float range_begin = directional_lights.data[i].shadow_range_begin.y; float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; vec2 tex_scale = directional_lights.data[i].uv_scale2 * test_radius; - shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); - } else { - shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); + float s = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); + + if (blend_index == 0) { + shadow = s; + } else { + //blend + float blend = smoothstep(0.0, directional_lights.data[i].shadow_split_offsets.x, depth_z); + shadow = mix(shadow, s, blend); + } + + blend_index++; } - shadow_color = directional_lights.data[i].shadow_color2.rgb; - } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { - vec4 v = vec4(vertex, 1.0); + if (blend_index < 2 && depth_z < directional_lights.data[i].shadow_split_offsets.z) { + vec4 v = vec4(vertex, 1.0); - BIAS_FUNC(v, 2) + BIAS_FUNC(v, 2) - pssm_coord = (directional_lights.data[i].shadow_matrix3 * v); - pssm_coord /= pssm_coord.w; + vec4 pssm_coord = (directional_lights.data[i].shadow_matrix3 * v); + pssm_coord /= pssm_coord.w; - if (directional_lights.data[i].softshadow_angle > 0) { float range_pos = dot(directional_lights.data[i].direction, v.xyz); float range_begin = directional_lights.data[i].shadow_range_begin.z; float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; vec2 tex_scale = directional_lights.data[i].uv_scale3 * test_radius; - shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); - } else { - shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); - } - - shadow_color = directional_lights.data[i].shadow_color3.rgb; + float s = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); - } else { - vec4 v = vec4(vertex, 1.0); - - BIAS_FUNC(v, 3) - - pssm_coord = (directional_lights.data[i].shadow_matrix4 * v); - pssm_coord /= pssm_coord.w; + if (blend_index == 0) { + shadow = s; + } else { + //blend + float blend = smoothstep(directional_lights.data[i].shadow_split_offsets.x, directional_lights.data[i].shadow_split_offsets.y, depth_z); + shadow = mix(shadow, s, blend); + } - if (directional_lights.data[i].softshadow_angle > 0) { - float range_pos = dot(directional_lights.data[i].direction, v.xyz); - float range_begin = directional_lights.data[i].shadow_range_begin.w; - float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; - vec2 tex_scale = directional_lights.data[i].uv_scale4 * test_radius; - shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); - } else { - shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); + blend_index++; } - shadow_color = directional_lights.data[i].shadow_color4.rgb; - } - - if (directional_lights.data[i].blend_splits) { - vec3 shadow_color_blend = vec3(0.0); - float pssm_blend; - float shadow2; - - if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { + if (blend_index < 2) { vec4 v = vec4(vertex, 1.0); - BIAS_FUNC(v, 1) - pssm_coord = (directional_lights.data[i].shadow_matrix2 * v); - pssm_coord /= pssm_coord.w; - if (directional_lights.data[i].softshadow_angle > 0) { - float range_pos = dot(directional_lights.data[i].direction, v.xyz); - float range_begin = directional_lights.data[i].shadow_range_begin.y; - float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; - vec2 tex_scale = directional_lights.data[i].uv_scale2 * test_radius; - shadow2 = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); - } else { - shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); - } + BIAS_FUNC(v, 3) - pssm_blend = smoothstep(0.0, directional_lights.data[i].shadow_split_offsets.x, depth_z); - shadow_color_blend = directional_lights.data[i].shadow_color2.rgb; - } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { - vec4 v = vec4(vertex, 1.0); - BIAS_FUNC(v, 2) - pssm_coord = (directional_lights.data[i].shadow_matrix3 * v); + vec4 pssm_coord = (directional_lights.data[i].shadow_matrix4 * v); pssm_coord /= pssm_coord.w; - if (directional_lights.data[i].softshadow_angle > 0) { - float range_pos = dot(directional_lights.data[i].direction, v.xyz); - float range_begin = directional_lights.data[i].shadow_range_begin.z; - float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; - vec2 tex_scale = directional_lights.data[i].uv_scale3 * test_radius; - shadow2 = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); - } else { - shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); - } - - pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.x, directional_lights.data[i].shadow_split_offsets.y, depth_z); + float range_pos = dot(directional_lights.data[i].direction, v.xyz); + float range_begin = directional_lights.data[i].shadow_range_begin.w; + float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; + vec2 tex_scale = directional_lights.data[i].uv_scale4 * test_radius; + float s = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); - shadow_color_blend = directional_lights.data[i].shadow_color3.rgb; - } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { - vec4 v = vec4(vertex, 1.0); - BIAS_FUNC(v, 3) - pssm_coord = (directional_lights.data[i].shadow_matrix4 * v); - pssm_coord /= pssm_coord.w; - if (directional_lights.data[i].softshadow_angle > 0) { - float range_pos = dot(directional_lights.data[i].direction, v.xyz); - float range_begin = directional_lights.data[i].shadow_range_begin.w; - float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; - vec2 tex_scale = directional_lights.data[i].uv_scale4 * test_radius; - shadow2 = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); + if (blend_index == 0) { + shadow = s; } else { - shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); + //blend + float blend = smoothstep(directional_lights.data[i].shadow_split_offsets.y, directional_lights.data[i].shadow_split_offsets.z, depth_z); + shadow = mix(shadow, s, blend); } - - pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.y, directional_lights.data[i].shadow_split_offsets.z, depth_z); - shadow_color_blend = directional_lights.data[i].shadow_color4.rgb; - } else { - pssm_blend = 0.0; //if no blend, same coord will be used (divide by z will result in same value, and already cached) } - pssm_blend = sqrt(pssm_blend); - - shadow = mix(shadow, shadow2, pssm_blend); - shadow_color = mix(shadow_color, shadow_color_blend, pssm_blend); - } - - shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, vertex.z)); //done with negative values for performance - #undef BIAS_FUNC - } -#else - // Soft shadow disabled version + } else { //no soft shadows - if (directional_lights.data[i].shadow_enabled) { - float depth_z = -vertex.z; + float depth_z = -vertex.z; - vec4 pssm_coord; - vec3 light_dir = directional_lights.data[i].direction; - vec3 base_normal_bias = normalize(normal_interp) * (1.0 - max(0.0, dot(light_dir, -normalize(normal_interp)))); + vec4 pssm_coord; + vec3 light_dir = directional_lights.data[i].direction; + vec3 base_normal_bias = normalize(normal_interp) * (1.0 - max(0.0, dot(light_dir, -normalize(normal_interp)))); #define BIAS_FUNC(m_var, m_idx) \ m_var.xyz += light_dir * directional_lights.data[i].shadow_bias[m_idx]; \ @@ -1412,70 +1350,70 @@ void main() { normal_bias -= light_dir * dot(light_dir, normal_bias); \ m_var.xyz += normal_bias; - if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { - vec4 v = vec4(vertex, 1.0); - - BIAS_FUNC(v, 0) - - pssm_coord = (directional_lights.data[i].shadow_matrix1 * v); - } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { - vec4 v = vec4(vertex, 1.0); - - BIAS_FUNC(v, 1) - - pssm_coord = (directional_lights.data[i].shadow_matrix2 * v); - } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { - vec4 v = vec4(vertex, 1.0); - - BIAS_FUNC(v, 2) - - pssm_coord = (directional_lights.data[i].shadow_matrix3 * v); - - } else { - vec4 v = vec4(vertex, 1.0); - - BIAS_FUNC(v, 3) - - pssm_coord = (directional_lights.data[i].shadow_matrix4 * v); - } - - pssm_coord /= pssm_coord.w; - - shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); + if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { + vec4 v = vec4(vertex, 1.0); - if (directional_lights.data[i].blend_splits) { - float pssm_blend; + BIAS_FUNC(v, 0) - if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { + pssm_coord = (directional_lights.data[i].shadow_matrix1 * v); + } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { vec4 v = vec4(vertex, 1.0); + BIAS_FUNC(v, 1) + pssm_coord = (directional_lights.data[i].shadow_matrix2 * v); - pssm_blend = smoothstep(0.0, directional_lights.data[i].shadow_split_offsets.x, depth_z); - } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { + } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { vec4 v = vec4(vertex, 1.0); + BIAS_FUNC(v, 2) + pssm_coord = (directional_lights.data[i].shadow_matrix3 * v); - pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.x, directional_lights.data[i].shadow_split_offsets.y, depth_z); - } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { + + } else { vec4 v = vec4(vertex, 1.0); + BIAS_FUNC(v, 3) + pssm_coord = (directional_lights.data[i].shadow_matrix4 * v); - pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.y, directional_lights.data[i].shadow_split_offsets.z, depth_z); - } else { - pssm_blend = 0.0; //if no blend, same coord will be used (divide by z will result in same value, and already cached) } pssm_coord /= pssm_coord.w; - float shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); - shadow = mix(shadow, shadow2, pssm_blend); - } + shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); + + if (directional_lights.data[i].blend_splits) { + float pssm_blend; + + if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { + vec4 v = vec4(vertex, 1.0); + BIAS_FUNC(v, 1) + pssm_coord = (directional_lights.data[i].shadow_matrix2 * v); + pssm_blend = smoothstep(0.0, directional_lights.data[i].shadow_split_offsets.x, depth_z); + } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { + vec4 v = vec4(vertex, 1.0); + BIAS_FUNC(v, 2) + pssm_coord = (directional_lights.data[i].shadow_matrix3 * v); + pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.x, directional_lights.data[i].shadow_split_offsets.y, depth_z); + } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { + vec4 v = vec4(vertex, 1.0); + BIAS_FUNC(v, 3) + pssm_coord = (directional_lights.data[i].shadow_matrix4 * v); + pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.y, directional_lights.data[i].shadow_split_offsets.z, depth_z); + } else { + pssm_blend = 0.0; //if no blend, same coord will be used (divide by z will result in same value, and already cached) + } + + pssm_coord /= pssm_coord.w; + + float shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); + shadow = mix(shadow, shadow2, pssm_blend); + } - shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, vertex.z)); //done with negative values for performance + shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, vertex.z)); //done with negative values for performance #undef BIAS_FUNC - } -#endif + } + } // shadows if (i < 4) { shadow0 |= uint(clamp(shadow * 255.0, 0.0, 255.0)) << (i * 8); @@ -1554,7 +1492,9 @@ void main() { blur_shadow(shadow); - light_compute(normal, directional_lights.data[i].direction, normalize(view), directional_lights.data[i].color * directional_lights.data[i].energy, shadow, f0, orms, 1.0, + float size_A = sc_use_light_soft_shadows ? directional_lights.data[i].size : 0.0; + + light_compute(normal, directional_lights.data[i].direction, normalize(view), size_A, directional_lights.data[i].color * directional_lights.data[i].energy, shadow, f0, orms, 1.0, #ifdef LIGHT_BACKLIGHT_USED backlight, #endif @@ -1573,9 +1513,6 @@ void main() { #ifdef LIGHT_ANISOTROPY_USED binormal, tangent, anisotropy, #endif -#ifdef USE_SOFT_SHADOW - directional_lights.data[i].size, -#endif #ifdef USE_SHADOW_TO_OPACITY alpha, #endif diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl index b6e89acb46..79790b1bfe 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl @@ -73,7 +73,7 @@ vec3 F0(float metallic, float specular, vec3 albedo) { return mix(vec3(dielectric), albedo, vec3(metallic)); } -void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, float attenuation, vec3 f0, uint orms, float specular_amount, +void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float attenuation, vec3 f0, uint orms, float specular_amount, #ifdef LIGHT_BACKLIGHT_USED vec3 backlight, #endif @@ -92,9 +92,6 @@ void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, float attenuation, #ifdef LIGHT_ANISOTROPY_USED vec3 B, vec3 T, float anisotropy, #endif -#ifdef USE_SOFT_SHADOWS - float A, -#endif #ifdef USE_SHADOW_TO_OPACITY inout float alpha, #endif @@ -111,11 +108,7 @@ void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, float attenuation, #else -#ifdef USE_SOFT_SHADOWS float NdotL = min(A + dot(N, L), 1.0); -#else - float NdotL = dot(N, L); -#endif float cNdotL = max(NdotL, 0.0); // clamped NdotL float NdotV = dot(N, V); float cNdotV = max(NdotV, 0.0); @@ -125,19 +118,11 @@ void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, float attenuation, #endif #if defined(SPECULAR_BLINN) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) -#ifdef USE_SOFT_SHADOWS float cNdotH = clamp(A + dot(N, H), 0.0, 1.0); -#else - float cNdotH = clamp(dot(N, H), 0.0, 1.0); -#endif #endif #if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) -#ifdef USE_SOFT_SHADOWS float cLdotH = clamp(A + dot(L, H), 0.0, 1.0); -#else - float cLdotH = clamp(dot(L, H), 0.0, 1.0); -#endif #endif float metallic = unpackUnorm4x8(orms).z; @@ -232,11 +217,7 @@ void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, float attenuation, #elif defined(SPECULAR_PHONG) vec3 R = normalize(-reflect(L, N)); -#ifdef USE_SOFT_SHADOWS float cRdotV = clamp(A + dot(R, V), 0.0, 1.0); -#else - float cRdotV = clamp(dot(R, V), 0.0, 1.0); -#endif float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25; float phong = pow(cRdotV, shininess); phong *= (shininess + 8.0) * (1.0 / (8.0 * M_PI)); @@ -442,8 +423,7 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) { float shadow; -#ifdef USE_SOFT_SHADOWS - if (omni_lights.data[idx].soft_shadow_size > 0.0) { + if (sc_use_light_soft_shadows && omni_lights.data[idx].soft_shadow_size > 0.0) { //soft shadow //find blocker @@ -533,7 +513,6 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) { shadow = 1.0; } } else { -#endif splane.xyz = normalize(splane.xyz); vec4 clamp_rect = omni_lights.data[idx].atlas_rect; @@ -553,9 +532,7 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) { splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw; splane.w = 1.0; //needed? i think it should be 1 already shadow = sample_pcf_shadow(shadow_atlas, omni_lights.data[idx].soft_shadow_scale * scene_data.shadow_atlas_pixel_size, splane); -#ifdef USE_SOFT_SHADOWS } -#endif return shadow; } @@ -592,14 +569,12 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v float light_attenuation = omni_attenuation; vec3 color = omni_lights.data[idx].color; -#ifdef USE_SOFT_SHADOWS float size_A = 0.0; - if (omni_lights.data[idx].size > 0.0) { + if (sc_use_light_soft_shadows && omni_lights.data[idx].size > 0.0) { float t = omni_lights.data[idx].size / max(0.001, light_length); size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t)); } -#endif #ifdef LIGHT_TRANSMITTANCE_USED float transmittance_z = transmittance_depth; //no transmittance by default @@ -633,9 +608,7 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v } #endif -#if 0 - - if (omni_lights.data[idx].projector_rect != vec4(0.0)) { + if (sc_use_light_projector && omni_lights.data[idx].projector_rect != vec4(0.0)) { vec3 local_v = (omni_lights.data[idx].shadow_matrix * vec4(vertex, 1.0)).xyz; local_v = normalize(local_v); @@ -686,13 +659,12 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v } vec4 proj = textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), proj_uv + atlas_rect.xy, proj_uv_ddx, proj_uv_ddy); - no_shadow = mix(no_shadow, proj.rgb, proj.a); + color *= proj.rgb * proj.a; } -#endif light_attenuation *= shadow; - light_compute(normal, normalize(light_rel_vec), eye_vec, color, light_attenuation, f0, orms, omni_lights.data[idx].specular_amount, + light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color, light_attenuation, f0, orms, omni_lights.data[idx].specular_amount, #ifdef LIGHT_BACKLIGHT_USED backlight, #endif @@ -711,9 +683,6 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v #ifdef LIGHT_ANISOTROPY_USED binormal, tangent, anisotropy, #endif -#ifdef USE_SOFT_SHADOWS - size_A, -#endif #ifdef USE_SHADOW_TO_OPACITY alpha, #endif @@ -747,8 +716,7 @@ float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) { vec4 splane = (spot_lights.data[idx].shadow_matrix * v); splane /= splane.w; -#ifdef USE_SOFT_SHADOWS - if (spot_lights.data[idx].soft_shadow_size > 0.0) { + if (sc_use_light_soft_shadows && spot_lights.data[idx].soft_shadow_size > 0.0) { //soft shadow //find blocker @@ -772,7 +740,7 @@ float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) { vec2 suv = shadow_uv + (disk_rotation * scene_data.penumbra_shadow_kernel[i].xy) * uv_size; suv = clamp(suv, spot_lights.data[idx].atlas_rect.xy, clamp_max); float d = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), suv, 0.0).r; - if (d < z_norm) { + if (d < splane.z) { blocker_average += d; blocker_count += 1.0; } @@ -788,7 +756,7 @@ float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) { for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) { vec2 suv = shadow_uv + (disk_rotation * scene_data.penumbra_shadow_kernel[i].xy) * uv_size; suv = clamp(suv, spot_lights.data[idx].atlas_rect.xy, clamp_max); - shadow += textureProj(sampler2DShadow(shadow_atlas, shadow_sampler), vec4(suv, z_norm, 1.0)); + shadow += textureProj(sampler2DShadow(shadow_atlas, shadow_sampler), vec4(suv, splane.z, 1.0)); } shadow /= float(scene_data.penumbra_shadow_samples); @@ -799,14 +767,11 @@ float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) { } } else { -#endif //hard shadow vec4 shadow_uv = vec4(splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy, splane.z, 1.0); shadow = sample_pcf_shadow(shadow_atlas, spot_lights.data[idx].soft_shadow_scale * scene_data.shadow_atlas_pixel_size, shadow_uv); -#ifdef USE_SOFT_SHADOWS } -#endif return shadow; } @@ -816,6 +781,18 @@ float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) { return 1.0; } +vec2 normal_to_panorama(vec3 n) { + n = normalize(n); + vec2 panorama_coords = vec2(atan(n.x, n.z), acos(-n.y)); + + if (panorama_coords.x < 0.0) { + panorama_coords.x += M_PI * 2.0; + } + + panorama_coords /= vec2(M_PI * 2.0, M_PI); + return panorama_coords; +} + void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 vertex_ddx, vec3 vertex_ddy, vec3 f0, uint orms, float shadow, #ifdef LIGHT_BACKLIGHT_USED vec3 backlight, @@ -850,20 +827,12 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v vec3 color = spot_lights.data[idx].color; float specular_amount = spot_lights.data[idx].specular_amount; -#ifdef USE_SOFT_SHADOWS float size_A = 0.0; - if (spot_lights.data[idx].size > 0.0) { + if (sc_use_light_soft_shadows && spot_lights.data[idx].size > 0.0) { float t = spot_lights.data[idx].size / max(0.001, light_length); size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t)); } -#endif - - /* - if (spot_lights.data[idx].atlas_rect!=vec4(0.0)) { - //use projector texture - } - */ #ifdef LIGHT_TRANSMITTANCE_USED float transmittance_z = transmittance_depth; @@ -886,9 +855,27 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v } #endif //LIGHT_TRANSMITTANCE_USED + if (sc_use_light_projector && spot_lights.data[idx].projector_rect != vec4(0.0)) { + vec4 splane = (spot_lights.data[idx].shadow_matrix * vec4(vertex, 1.0)); + splane /= splane.w; + + vec2 proj_uv = normal_to_panorama(splane.xyz) * spot_lights.data[idx].projector_rect.zw; + + //ensure we have proper mipmaps + vec4 splane_ddx = (spot_lights.data[idx].shadow_matrix * vec4(vertex + vertex_ddx, 1.0)); + splane_ddx /= splane_ddx.w; + vec2 proj_uv_ddx = normal_to_panorama(splane_ddx.xyz) * spot_lights.data[idx].projector_rect.zw - proj_uv; + + vec4 splane_ddy = (spot_lights.data[idx].shadow_matrix * vec4(vertex + vertex_ddy, 1.0)); + splane_ddy /= splane_ddy.w; + vec2 proj_uv_ddy = normal_to_panorama(splane_ddy.xyz) * spot_lights.data[idx].projector_rect.zw - proj_uv; + + vec4 proj = textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), proj_uv + spot_lights.data[idx].projector_rect.xy, proj_uv_ddx, proj_uv_ddy); + color *= proj.rgb * proj.a; + } light_attenuation *= shadow; - light_compute(normal, normalize(light_rel_vec), eye_vec, color, light_attenuation, f0, orms, spot_lights.data[idx].specular_amount, + light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color, light_attenuation, f0, orms, spot_lights.data[idx].specular_amount, #ifdef LIGHT_BACKLIGHT_USED backlight, #endif @@ -907,9 +894,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v #ifdef LIGHT_ANISOTROPY_USED binormal, tangent, anisotropy, #endif -#ifdef USE_SOFT_SHADOW - size_A, -#endif #ifdef USE_SHADOW_TO_OPACITY alpha, #endif diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl index 1bc17e140f..30673745ca 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl @@ -370,6 +370,13 @@ void main() { #VERSION_DEFINES +/* Specialization Constants */ + +//unused but there for compatibility +layout(constant_id = 0) const bool sc_use_forward_gi = false; +layout(constant_id = 1) const bool sc_use_light_projector = false; +layout(constant_id = 2) const bool sc_use_light_soft_shadows = false; + /* Include our forward mobile UBOs definitions etc. */ #include "scene_forward_mobile_inc.glsl" diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index 271c039aad..3336623f21 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -151,6 +151,22 @@ void RendererSceneCull::_instance_pair(Instance *p_A, Instance *p_B) { idata.flags |= InstanceData::FLAG_GEOM_LIGHTING_DIRTY; } + if (light->uses_projector) { + geom->projector_count++; + if (geom->projector_count == 1) { + InstanceData &idata = A->scenario->instance_data[A->array_index]; + idata.flags |= InstanceData::FLAG_GEOM_PROJECTOR_SOFTSHADOW_DIRTY; + } + } + + if (light->uses_softshadow) { + geom->softshadow_count++; + if (geom->softshadow_count == 1) { + InstanceData &idata = A->scenario->instance_data[A->array_index]; + idata.flags |= InstanceData::FLAG_GEOM_PROJECTOR_SOFTSHADOW_DIRTY; + } + } + } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -242,6 +258,32 @@ void RendererSceneCull::_instance_unpair(Instance *p_A, Instance *p_B) { idata.flags |= InstanceData::FLAG_GEOM_LIGHTING_DIRTY; } + if (light->uses_projector) { +#ifdef DEBUG_ENABLED + if (geom->projector_count == 0) { + ERR_PRINT("geom->projector_count==0 - BUG!"); + } +#endif + geom->projector_count--; + if (geom->projector_count == 0) { + InstanceData &idata = A->scenario->instance_data[A->array_index]; + idata.flags |= InstanceData::FLAG_GEOM_PROJECTOR_SOFTSHADOW_DIRTY; + } + } + + if (light->uses_softshadow) { +#ifdef DEBUG_ENABLED + if (geom->softshadow_count == 0) { + ERR_PRINT("geom->softshadow_count==0 - BUG!"); + } +#endif + geom->softshadow_count--; + if (geom->softshadow_count == 0) { + InstanceData &idata = A->scenario->instance_data[A->array_index]; + idata.flags |= InstanceData::FLAG_GEOM_PROJECTOR_SOFTSHADOW_DIRTY; + } + } + } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -1532,7 +1574,11 @@ void RendererSceneCull::_update_instance(Instance *p_instance) { } } break; case RS::INSTANCE_LIGHT: { - idata.instance_data_rid = static_cast<InstanceLightData *>(p_instance->base_data)->instance.get_id(); + InstanceLightData *light_data = static_cast<InstanceLightData *>(p_instance->base_data); + idata.instance_data_rid = light_data->instance.get_id(); + light_data->uses_projector = RSG::storage->light_has_projector(p_instance->base); + light_data->uses_softshadow = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SIZE) > CMP_EPSILON; + } break; case RS::INSTANCE_REFLECTION_PROBE: { idata.instance_data_rid = static_cast<InstanceReflectionProbeData *>(p_instance->base_data)->instance.get_id(); @@ -2646,6 +2692,13 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_LIGHTING_DIRTY); } + if (idata.flags & InstanceData::FLAG_GEOM_PROJECTOR_SOFTSHADOW_DIRTY) { + InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); + + scene_render->geometry_instance_set_softshadow_projector_pairing(geom->geometry_instance, geom->softshadow_count > 0, geom->projector_count > 0); + idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_PROJECTOR_SOFTSHADOW_DIRTY); + } + if (geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && (idata.flags & InstanceData::FLAG_GEOM_REFLECTION_DIRTY)) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); uint32_t idx = 0; diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h index d586fb531f..b9009c9f59 100644 --- a/servers/rendering/renderer_scene_cull.h +++ b/servers/rendering/renderer_scene_cull.h @@ -267,6 +267,7 @@ public: FLAG_VISIBILITY_DEPENDENCY_NEEDS_CHECK = (3 << 20), // 2 bits, overlaps with the other vis. dependency flags FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE = (1 << 20), FLAG_VISIBILITY_DEPENDENCY_HIDDEN = (1 << 21), + FLAG_GEOM_PROJECTOR_SOFTSHADOW_DIRTY = (1 << 22), }; uint32_t flags = 0; @@ -489,6 +490,14 @@ public: case RendererStorage::DEPENDENCY_CHANGED_SKELETON_BONES: { //ignored } break; + case RendererStorage::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR: { + //requires repairing + if (instance->indexer_id.is_valid()) { + singleton->_unpair_instance(instance); + singleton->_instance_queue_update(instance, true, true); + } + + } break; } } @@ -567,6 +576,8 @@ public: Set<Instance *> lights; bool can_cast_shadows; bool material_is_animated; + uint32_t projector_count = 0; + uint32_t softshadow_count = 0; Set<Instance *> decals; Set<Instance *> reflection_probes; @@ -631,6 +642,8 @@ public: List<Instance *>::Element *D; // directional light in scenario bool shadow_dirty; + bool uses_projector = false; + bool uses_softshadow = false; Set<Instance *> geometries; diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h index ff0fea16d0..0cf34773ef 100644 --- a/servers/rendering/renderer_scene_render.h +++ b/servers/rendering/renderer_scene_render.h @@ -69,6 +69,8 @@ public: virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) = 0; virtual void geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) = 0; + virtual void geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) = 0; + virtual void geometry_instance_free(GeometryInstance *p_geometry_instance) = 0; /* SHADOW ATLAS API */ diff --git a/servers/rendering/renderer_storage.h b/servers/rendering/renderer_storage.h index b2aa0d27d3..b9bc349f79 100644 --- a/servers/rendering/renderer_storage.h +++ b/servers/rendering/renderer_storage.h @@ -48,6 +48,7 @@ public: DEPENDENCY_CHANGED_SKELETON_DATA, DEPENDENCY_CHANGED_SKELETON_BONES, DEPENDENCY_CHANGED_LIGHT, + DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR, DEPENDENCY_CHANGED_REFLECTION_PROBE, }; @@ -337,6 +338,8 @@ public: virtual bool light_has_shadow(RID p_light) const = 0; + virtual bool light_has_projector(RID p_light) const = 0; + virtual RS::LightType light_get_type(RID p_light) const = 0; virtual AABB light_get_aabb(RID p_light) const = 0; virtual float light_get_param(RID p_light, RS::LightParam p_param) = 0; diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h index 1af427b356..4c31880faf 100644 --- a/servers/rendering/rendering_device_binds.h +++ b/servers/rendering/rendering_device_binds.h @@ -458,7 +458,7 @@ class RDPipelineSpecializationConstant : public RefCounted { friend class RenderingDevice; Variant value = false; - uint32_t constant_id; + uint32_t constant_id = 0; public: void set_value(const Variant &p_value) { diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 0d01d4a2bd..e13b81f698 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -78,7 +78,8 @@ public: CANVAS_ITEM_Z_MAX = 4096, MAX_GLOW_LEVELS = 7, MAX_CURSORS = 8, - MAX_2D_DIRECTIONAL_LIGHTS = 8 + MAX_2D_DIRECTIONAL_LIGHTS = 8, + MAX_MESH_SURFACES = 256 }; /* TEXTURE API */ diff --git a/servers/text_server.cpp b/servers/text_server.cpp index 6f48148cab..1491368109 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; } @@ -695,7 +712,7 @@ Vector<Vector2i> TextServer::shaped_text_get_line_breaks(RID p_shaped, float p_w return lines; } -Vector<Vector2i> TextServer::shaped_text_get_word_breaks(RID p_shaped) const { +Vector<Vector2i> TextServer::shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags) const { Vector<Vector2i> words; const_cast<TextServer *>(this)->shaped_text_update_justification_ops(p_shaped); @@ -709,7 +726,7 @@ Vector<Vector2i> TextServer::shaped_text_get_word_breaks(RID p_shaped) const { for (int i = 0; i < l_size; i++) { if (l_gl[i].count > 0) { - if (((l_gl[i].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE) || ((l_gl[i].flags & GRAPHEME_IS_PUNCTUATION) == GRAPHEME_IS_PUNCTUATION)) { + if ((l_gl[i].flags & p_grapheme_flags) != 0) { words.push_back(Vector2i(word_start, l_gl[i].start)); word_start = l_gl[i].end; } diff --git a/servers/text_server.h b/servers/text_server.h index 138ceb9356..4c2ada7fc9 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 { @@ -79,7 +87,8 @@ public: GRAPHEME_IS_BREAK_SOFT = 1 << 5, // Is line break (optional break, e.g. space). GRAPHEME_IS_TAB = 1 << 6, // Is tab or vertical tab. GRAPHEME_IS_ELONGATION = 1 << 7, // Elongation (e.g. kashida), glyph can be duplicated or truncated to fit line to width. - GRAPHEME_IS_PUNCTUATION = 1 << 8 // Punctuation (can be used as word break, but not line break or justifiction). + GRAPHEME_IS_PUNCTUATION = 1 << 8, // Punctuation, except underscore (can be used as word break, but not line break or justifiction). + GRAPHEME_IS_UNDERSCORE = 1 << 9, // Underscore (can be used as word break). }; enum Hinting { @@ -138,7 +147,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; } @@ -346,7 +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 Vector<Vector2i> shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) 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); |