diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index ed51cf5efbfb..91b2a25361b5 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -61,11 +61,15 @@ Copyright: 2011, Ole Kniemeyer, MAXON, www.maxon.net 2007-2014, Juan Linietsky, Ariel Manzur License: Expat and Zlib +Files: misc/dist/linux/org.godotengine.Godot.appdata.xml +Comment: Linux AppStream Metadata File +Copyright: 2017-2022, Rémi Verschelde +License: CC0-1.0 + Files: modules/betsy/alpha_stitch.glsl modules/betsy/bc1.glsl modules/betsy/bc4.glsl modules/betsy/bc6h.glsl - modules/betsy/CrossPlatformSettings_piece_all.glsl Comment: Betsy Copyright: 2020-2022, Matias N. Goldberg License: Expat @@ -79,8 +83,8 @@ Files: modules/godot_physics_3d/gjk_epa.cpp modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.cpp modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.h modules/godot_physics_3d/joints/godot_hinge_joint_3d.cpp - modules/godot_physics_3d/joints/godot_hinge_joint_3d_sw.h - modules/godot_physics_3d/joints/godot_jacobian_entry_3d_sw.h + modules/godot_physics_3d/joints/godot_hinge_joint_3d.h + modules/godot_physics_3d/joints/godot_jacobian_entry_3d.h modules/godot_physics_3d/joints/godot_pin_joint_3d.cpp modules/godot_physics_3d/joints/godot_pin_joint_3d.h modules/godot_physics_3d/joints/godot_slider_joint_3d.cpp @@ -126,8 +130,6 @@ Files: platform/android/java/editor/src/main/java/com/android/* platform/android/java/lib/aidl/com/android/* platform/android/java/lib/res/layout/status_bar_ongoing_event_progress_bar.xml platform/android/java/lib/src/com/google/android/* - platform/android/java/lib/src/org/godotengine/godot/input/InputManagerCompat.java - platform/android/java/lib/src/org/godotengine/godot/input/InputManagerV16.java Comment: The Android Open Source Project Copyright: 2008-2016, The Android Open Source Project 2002, Google, Inc. @@ -151,21 +153,21 @@ Copyright: 2014-present Godot Engine contributors 1999-2015 Stephan M. Bernsee License: Expat and WOL -Files: ./servers/rendering/renderer_rd/shaders/effects/tonemap.glsl +Files: servers/rendering/renderer_rd/shaders/effects/tonemap.glsl Comment: NVidia's FXAA 3.11, simplified by Simon Rodriguez Copyright: 2014-2015, NVIDIA CORPORATION 2017 Simon Rodriguez License: BSD-3-clause and Expat -Files: ./servers/rendering/renderer_rd/shaders/ss_effects_downsample.glsl - ./servers/rendering/renderer_rd/shaders/ssao_blur.glsl - ./servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl - ./servers/rendering/renderer_rd/shaders/ssao_interleave.glsl - ./servers/rendering/renderer_rd/shaders/ssao.glsl - ./servers/rendering/renderer_rd/shaders/ssil_blur.glsl - ./servers/rendering/renderer_rd/shaders/ssil_importance_map.glsl - ./servers/rendering/renderer_rd/shaders/ssil_interleave.glsl - ./servers/rendering/renderer_rd/shaders/ssil.glsl +Files: servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl + servers/rendering/renderer_rd/shaders/effects/ssao_blur.glsl + servers/rendering/renderer_rd/shaders/effects/ssao_importance_map.glsl + servers/rendering/renderer_rd/shaders/effects/ssao_interleave.glsl + servers/rendering/renderer_rd/shaders/effects/ssao.glsl + servers/rendering/renderer_rd/shaders/effects/ssil_blur.glsl + servers/rendering/renderer_rd/shaders/effects/ssil_importance_map.glsl + servers/rendering/renderer_rd/shaders/effects/ssil_interleave.glsl + servers/rendering/renderer_rd/shaders/effects/ssil.glsl Comment: Intel ASSAO and related files Copyright: 2016, Intel Corporation License: Expat @@ -175,9 +177,9 @@ Comment: Temporal Anti-Aliasing resolve implementation Copyright: 2016, Panos Karabelas License: Expat -Files: servers/rendering/renderer_rd/shaders/smaa_blending.glsl - servers/rendering/renderer_rd/shaders/smaa_weight_calculation.glsl - servers/rendering/renderer_rd/shaders/smaa_edge_detection.glsl +Files: servers/rendering/renderer_rd/shaders/effects/smaa_blending.glsl + servers/rendering/renderer_rd/shaders/effects/smaa_weight_calculation.glsl + servers/rendering/renderer_rd/shaders/effects/smaa_edge_detection.glsl thirdparty/smaa/* Comment: Subpixel Morphological Antialiasing Copyright: 2013, Jorge Jimenez @@ -497,7 +499,7 @@ Files: thirdparty/misc/r128.c thirdparty/misc/r128.h Comment: r128 library Copyright: Alan Hickman -License: public-domain or Unlicense +License: Unlicense Files: thirdparty/misc/smaz.c thirdparty/misc/smaz.h @@ -509,12 +511,12 @@ Files: thirdparty/misc/smolv.cpp thirdparty/misc/smolv.h Comment: SMOL-V Copyright: 2016-2024, Aras Pranckevicius -License: public-domain or Unlicense or Expat +License: Unlicense or Expat Files: thirdparty/misc/stb_rect_pack.h Comment: stb libraries Copyright: Sean Barrett -License: public-domain or Unlicense or Expat +License: Unlicense or Expat Files: thirdparty/misc/yuv2rgb.h Comment: YUV2RGB @@ -555,7 +557,7 @@ License: Zlib Files: thirdparty/sdl/hidapi/* Comment: hidapi Copyright: 2010, Alan Ott, Signal 11 Software -License: BSD-3-Clause +License: BSD-3-clause Files: thirdparty/spirv-cross/* Comment: SPIRV-Cross diff --git a/core/input/input.cpp b/core/input/input.cpp index 4dc8666b053a..88fbb21196fa 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -793,6 +793,7 @@ void Input::_parse_input_event_impl(const Ref &p_event, bool p_is_em touch_event->set_canceled(mb->is_canceled()); touch_event->set_position(mb->get_position()); touch_event->set_double_tap(mb->is_double_click()); + touch_event->set_window_id(mb->get_window_id()); touch_event->set_device(InputEvent::DEVICE_ID_EMULATION); _THREAD_SAFE_UNLOCK_ event_dispatch_function(touch_event); diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp index 8e5fe25de2aa..35ade0a23e49 100644 --- a/core/input/input_map.cpp +++ b/core/input/input_map.cpp @@ -227,6 +227,10 @@ void InputMap::action_erase_event(const StringName &p_action, const Refis_action_pressed(p_action)) { + Input::get_singleton()->action_release(p_action); + } + input_map[p_action].inputs.clear(); } diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index f04f500f823c..d7bd44de7822 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -500,7 +500,7 @@ func _ready(): var id = get_instance_id() var instance = instance_from_id(id) - print(instance.foo) # Prints "water" + print(instance.drink) # Prints "water" [/gdscript] [csharp] public partial class MyNode : Node diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml index caaf82fc3345..66c2b667752a 100644 --- a/doc/classes/Array.xml +++ b/doc/classes/Array.xml @@ -684,7 +684,6 @@ Removes the element from the array at the given index ([param position]). If the index is out of bounds, this method fails. If the index is negative, [param position] is considered relative to the end of the array. If you need to return the removed element, use [method pop_at]. To remove an element by value, use [method erase] instead. [b]Note:[/b] This method shifts every element's index after [param position] back, which may have a noticeable performance cost, especially on larger arrays. - [b]Note:[/b] The [param position] cannot be negative. To remove an element relative to the end of the array, use [code]arr.remove_at(arr.size() - (i + 1))[/code]. To remove the last element from the array, use [code]arr.resize(arr.size() - 1)[/code]. diff --git a/doc/classes/EditorExportPlatform.xml b/doc/classes/EditorExportPlatform.xml index cb4633e0a453..78d3b02ef662 100644 --- a/doc/classes/EditorExportPlatform.xml +++ b/doc/classes/EditorExportPlatform.xml @@ -8,7 +8,6 @@ Used in scripting by [EditorExportPlugin] to configure platform-specific customization of scenes and resources. See [method EditorExportPlugin._begin_customize_scenes] and [method EditorExportPlugin._begin_customize_resources] for more details. - $DOCS_URL/tutorials/platform/consoles.html diff --git a/doc/classes/HTTPRequest.xml b/doc/classes/HTTPRequest.xml index b3fdc0363a83..ff87a3eb57d3 100644 --- a/doc/classes/HTTPRequest.xml +++ b/doc/classes/HTTPRequest.xml @@ -253,7 +253,8 @@ Maximum number of allowed redirects. - The duration to wait in seconds before a request times out. If [member timeout] is set to [code]0.0[/code] then the request will never time out. For simple requests, such as communication with a REST API, it is recommended that [member timeout] is set to a value suitable for the server response time (e.g. between [code]1.0[/code] and [code]10.0[/code]). This will help prevent unwanted timeouts caused by variation in server response times while still allowing the application to detect when a request has timed out. For larger requests such as file downloads it is suggested the [member timeout] be set to [code]0.0[/code], disabling the timeout functionality. This will help to prevent large transfers from failing due to exceeding the timeout value. + The duration to wait before a request times out, in seconds (independent of [member Engine.time_scale]). If [member timeout] is set to [code]0.0[/code], the request will never time out. + For simple requests, such as communication with a REST API, it is recommended to set [member timeout] to a value suitable for the server response time (commonly between [code]1.0[/code] and [code]10.0[/code]). This will help prevent unwanted timeouts caused by variation in response times while still allowing the application to detect when a request has timed out. For larger requests such as file downloads, it is recommended to set [member timeout] to [code]0.0[/code], disabling the timeout functionality. This will help prevent large transfers from failing due to exceeding the timeout value. If [code]true[/code], multithreading is used to improve performance. diff --git a/doc/classes/ItemList.xml b/doc/classes/ItemList.xml index bd60328a4a04..27e7b39d0b50 100644 --- a/doc/classes/ItemList.xml +++ b/doc/classes/ItemList.xml @@ -536,7 +536,7 @@ [StyleBox] used for the cursor, when the [ItemList] is not being focused. - The focused style for the [ItemList], drawn on top of the background, but below everything else. + The focused style for the [ItemList], drawn on top of everything. [StyleBox] for the hovered, but not selected items. diff --git a/doc/classes/JavaScriptBridge.xml b/doc/classes/JavaScriptBridge.xml index 191caed16855..8f54f8b8af05 100644 --- a/doc/classes/JavaScriptBridge.xml +++ b/doc/classes/JavaScriptBridge.xml @@ -8,7 +8,7 @@ [b]Note:[/b] This singleton can be disabled at build-time to improve security. By default, the JavaScriptBridge singleton is enabled. Official export templates also have the JavaScriptBridge singleton enabled. See [url=$DOCS_URL/engine_details/development/compiling/compiling_for_web.html]Compiling for the Web[/url] in the documentation for more information. - $DOCS_URL/tutorials/export/exporting_for_web.html#calling-javascript-from-script + $DOCS_URL/tutorials/platform/web/javascript_bridge.html diff --git a/doc/classes/MainLoop.xml b/doc/classes/MainLoop.xml index 5167f9b41432..227e1ad4223c 100644 --- a/doc/classes/MainLoop.xml +++ b/doc/classes/MainLoop.xml @@ -121,7 +121,7 @@ Notification received from the OS when an update of the Input Method Engine occurs (e.g. change of IME cursor position or composition string). - Specific to the macOS platform. + Implemented on desktop and web platforms. Notification received from the OS when the application is resumed. diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index 210d643113bd..0c6cd03170b8 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -1298,7 +1298,7 @@ Notification received from the OS when an update of the Input Method Engine occurs (e.g. change of IME cursor position or composition string). - Implemented only on macOS. + Implemented on desktop and web platforms. Notification received from the OS when the application is resumed. diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index c63e0d88c14c..8f2ec3b3f037 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -982,7 +982,9 @@ Main window initial position. [code]0[/code] - "Absolute", [member display/window/size/initial_position] is used to set window position. [code]1[/code] - "Primary Screen Center". - [code]2[/code] - "Other Screen Center", [member display/window/size/initial_screen] is used to set the screen. + [code]3[/code] - "Other Screen Center", [member display/window/size/initial_screen] is used to set the screen. + [code]4[/code] - "Center of Screen With Mouse Pointer". + [code]5[/code] - "Center of Screen With Keyboard Focus". [b]Note:[/b] This setting only affects the exported project, or when the project is run from the command line. In the editor, the value of [member EditorSettings.run/window_placement/rect] is used instead. diff --git a/doc/classes/Vector2i.xml b/doc/classes/Vector2i.xml index 74dfc3efe97a..30521536bace 100644 --- a/doc/classes/Vector2i.xml +++ b/doc/classes/Vector2i.xml @@ -292,7 +292,7 @@ Divides each component of the [Vector2i] by the given [float]. Returns a [Vector2]. [codeblock] - print(Vector2i(10, 20) / 2.9) # Prints (5.0, 10.0) + print(Vector2i(1, 2) / 2.5) # Prints (0.4, 0.8) [/codeblock] diff --git a/doc/classes/Vector3i.xml b/doc/classes/Vector3i.xml index 64c2137b7d83..4dd43b85fb7e 100644 --- a/doc/classes/Vector3i.xml +++ b/doc/classes/Vector3i.xml @@ -299,7 +299,7 @@ Divides each component of the [Vector3i] by the given [float]. Returns a [Vector3]. [codeblock] - print(Vector3i(10, 20, 30) / 2.9) # Prints (5.0, 10.0, 15.0) + print(Vector3i(1, 2, 3) / 2.5) # Prints (0.4, 0.8, 1.2) [/codeblock] diff --git a/doc/classes/Vector4i.xml b/doc/classes/Vector4i.xml index 4dd093478070..4f252ad2f5ec 100644 --- a/doc/classes/Vector4i.xml +++ b/doc/classes/Vector4i.xml @@ -287,7 +287,7 @@ Divides each component of the [Vector4i] by the given [float]. Returns a Vector4 value due to floating-point operations. [codeblock] - print(Vector4i(10, 20, 30, 40) / 2) # Prints (5.0, 10.0, 15.0, 20.0) + print(Vector4i(1, 2, 3, 4) / 2.5) # Prints (0.4, 0.8, 1.2, 1.6) [/codeblock] diff --git a/doc/translations/de.po b/doc/translations/de.po index 04f45141d5a1..c6f59d977422 100644 --- a/doc/translations/de.po +++ b/doc/translations/de.po @@ -2750,7 +2750,7 @@ msgid "" "func _ready():\n" "\tvar id = get_instance_id()\n" "\tvar instance = instance_from_id(id)\n" -"\tprint(instance.foo) # Prints \"water\"\n" +"\tprint(instance.drink) # Prints \"water\"\n" "[/gdscript]\n" "[csharp]\n" "public partial class MyNode : Node\n" @@ -2772,23 +2772,23 @@ msgstr "" "Object.get_instance_id].\n" "[codeblocks]\n" "[gdscript]\n" -"var foo = \"wasser\"\n" +"var drink = \"wasser\"\n" "\n" "func _ready():\n" "\tvar id = get_instance_id()\n" "\tvar inst = instance_from_id(id)\n" -"\tprint(inst.foo) # Druckt wasser\n" +"\tprint(inst.drink) # Druckt wasser\n" "[/gdscript]\n" "[csharp]\n" "public partial class MyNode : Node\n" "{\n" -"\tpublic string Foo { get; set; } = \"wasser\";\n" +"\tpublic string Drink { get; set; } = \"wasser\";\n" "\n" "\tpublic override void _Ready()\n" "\t{\n" "\t\tulong id = GetInstanceId();\n" "\t\tvar inst = (MyNode)InstanceFromId(Id);\n" -"\t\tGD.Print(inst.Foo); // Druckt wasser\n" +"\t\tGD.Print(inst.Drink); // Druckt wasser\n" "\t}\n" "}\n" "[/csharp]\n" diff --git a/doc/translations/es.po b/doc/translations/es.po index 2541b7735694..0c4fce628f60 100644 --- a/doc/translations/es.po +++ b/doc/translations/es.po @@ -3054,7 +3054,7 @@ msgstr "" "func _ready():\n" "\tvar id = get_instance_id()\n" "\tvar instance = instance_from_id(id)\n" -"\tprint(instance.foo) # Imprime \"water\"\n" +"\tprint(instance.drink) # Imprime \"water\"\n" "[/gdscript]\n" "[csharp]\n" "public partial class MyNode : Node\n" @@ -58130,12 +58130,12 @@ msgstr "" msgid "" "Notification received from the OS when an update of the Input Method Engine " "occurs (e.g. change of IME cursor position or composition string).\n" -"Specific to the macOS platform." +"Implemented on desktop and web platforms." msgstr "" "Notificación recibida del sistema operativo cuando se produce una " "actualización del motor del método de entrada (por ejemplo, cambio de la " "posición del cursor de la IME o de la string de composición).\n" -"Específico de la plataforma MacOS." +"Implementado en plataformas de escritorio y web." msgid "" "Notification received from the OS when the application is resumed.\n" @@ -78533,8 +78533,10 @@ msgid "" "[code]0[/code] - \"Absolute\", [member display/window/size/initial_position] " "is used to set window position.\n" "[code]1[/code] - \"Primary Screen Center\".\n" -"[code]2[/code] - \"Other Screen Center\", [member display/window/size/" +"[code]3[/code] - \"Other Screen Center\", [member display/window/size/" "initial_screen] is used to set the screen.\n" +"[code]4[/code] - \"Center of Screen With Mouse Pointer\".\n" +"[code]5[/code] - \"Center of Screen With Keyboard Focus\".\n" "[b]Note:[/b] This setting only affects the exported project, or when the " "project is run from the command line. In the editor, the value of [member " "EditorSettings.run/window_placement/rect] is used instead." @@ -78543,8 +78545,10 @@ msgstr "" "[code]0[/code] - \"Absoluta\", [member display/window/size/initial_position] " "se utiliza para establecer la posición de la ventana.\n" "[code]1[/code] - \"Centro de la pantalla principal\".\n" -"[code]2[/code] - \"Centro de otra pantalla\", [member display/window/size/" +"[code]3[/code] - \"Centro de otra pantalla\", [member display/window/size/" "initial_screen] se utiliza para establecer la pantalla.\n" +"[code]4[/code] - \"Center of Screen With Mouse Pointer\".\n" +"[code]5[/code] - \"Center of Screen With Keyboard Focus\".\n" "[b]Nota:[/b] Este ajuste solo afecta al proyecto exportado, o cuando el " "proyecto se ejecuta desde la línea de comandos. En el editor, se utiliza el " "valor de [member EditorSettings.run/window_placement/rect] en su lugar." @@ -120270,13 +120274,13 @@ msgid "" "Divides each component of the [Vector2i] by the given [float]. Returns a " "[Vector2].\n" "[codeblock]\n" -"print(Vector2i(10, 20) / 2.9) # Prints (5.0, 10.0)\n" +"print(Vector2i(1, 2) / 2.5) # Prints (0.4, 0.8)\n" "[/codeblock]" msgstr "" "Divide cada componente del [Vector2i] entre el [float] dado. Devuelve un " "[Vector2].\n" "[codeblock]\n" -"print(Vector2i(10, 20) / 2.9) # Imprime (5.0, 10.0)\n" +"print(Vector2i(1, 2) / 2.5) # Imprime (0.4, 0.8)\n" "[/codeblock]" msgid "Divides each component of the [Vector2i] by the given [int]." @@ -121061,13 +121065,13 @@ msgid "" "Divides each component of the [Vector3i] by the given [float]. Returns a " "[Vector3].\n" "[codeblock]\n" -"print(Vector3i(10, 20, 30) / 2.9) # Prints (5.0, 10.0, 15.0)\n" +"print(Vector3i(1, 2, 3) / 2.5) # Prints (0.4, 0.8, 1.2)\n" "[/codeblock]" msgstr "" "Divide cada componente del [Vector3i] por el [float] dado. Devuelve un " "[Vector3].\n" "[codeblock]\n" -"print(Vector3i(10, 20, 30) / 2.9) # Imprime (5.0, 10.0, 15.0)\n" +"print(Vector3i(1, 2, 3) / 2.5) # Imprime (0.4, 0.8, 1.2)\n" "[/codeblock]" msgid "Divides each component of the [Vector3i] by the given [int]." @@ -121667,13 +121671,13 @@ msgid "" "Divides each component of the [Vector4i] by the given [float].\n" "Returns a Vector4 value due to floating-point operations.\n" "[codeblock]\n" -"print(Vector4i(10, 20, 30, 40) / 2) # Prints (5.0, 10.0, 15.0, 20.0)\n" +"print(Vector4i(1, 2, 3, 4) / 2.5) # Prints (0.4, 0.8, 1.2, 1.6)\n" "[/codeblock]" msgstr "" "Divide cada componente del [Vector4i] por el [float] dado.\n" "Devuelve un valor Vector4 debido a las operaciones de punto flotante.\n" "[codeblock]\n" -"print(Vector4i(10, 20, 30, 40) / 2) # Imprime (5.0, 10.0, 15.0, 20.0)\n" +"print(Vector4i(1, 2, 3, 4) / 2.5) # Imprime (0.4, 0.8, 1.2, 1.6)\n" "[/codeblock]" msgid "Divides each component of the [Vector4i] by the given [int]." diff --git a/doc/translations/fr.po b/doc/translations/fr.po index d03c3896ea3d..88a530e0e138 100644 --- a/doc/translations/fr.po +++ b/doc/translations/fr.po @@ -3068,7 +3068,7 @@ msgid "" "func _ready():\n" "\tvar id = get_instance_id()\n" "\tvar instance = instance_from_id(id)\n" -"\tprint(instance.foo) # Prints \"water\"\n" +"\tprint(instance.drink) # Prints \"water\"\n" "[/gdscript]\n" "[csharp]\n" "public partial class MyNode : Node\n" @@ -3090,12 +3090,12 @@ msgstr "" "Object.get_instance_id].\n" "[codeblocks]\n" "[gdscript]\n" -"var boisson= \"eau\"\n" +"var boisson = \"eau\"\n" "\n" "func _ready():\n" "\tvar id = get_instance_id()\n" "\tvar instance = instance_from_id(id)\n" -"\tprint(instance.foo) # Affiche \"eau\"\n" +"\tprint(instance.boisson) # Affiche \"eau\"\n" "[/gdscript]\n" "[csharp]\n" "public partial class MonNoeud : Node\n" @@ -15262,11 +15262,7 @@ msgid "" "element by value, use [method erase] instead.\n" "[b]Note:[/b] This method shifts every element's index after [param position] " "back, which may have a noticeable performance cost, especially on larger " -"arrays.\n" -"[b]Note:[/b] The [param position] cannot be negative. To remove an element " -"relative to the end of the array, use [code]arr.remove_at(arr.size() - (i + " -"1))[/code]. To remove the last element from the array, use " -"[code]arr.resize(arr.size() - 1)[/code]." +"arrays." msgstr "" "Retire l'élément du tableau à l'index donné ([param position]). Si l'index " "est hors des limites, cette méthode échoue. Si l'index est négativ, [param " @@ -15275,11 +15271,7 @@ msgstr "" "supprimer un élément par valeur, utilisez [method erase] à la place.\n" "[b]Note :[/b] Cette méthode déplace l'index de chaque élément après [param " "position] en arrière, ce qui peut avoir un coût de performance notable, en " -"particulier sur les tableaux plus grands.\n" -"[b]Note :[/b] La [param position] ne peut être négative. Pour supprimer un " -"élément relatif à la fin du tableau, utilisez [code]tab.remove_at(tab.size() " -"- (i + 1))[/code]. Pour supprimer le dernier élément du tableau, utilisez " -"[code]tab.resize(tab.size() - 1)[/code]." +"particulier sur les tableaux plus grands." msgid "" "Sets the array's number of elements to [param size]. If [param size] is " @@ -94334,8 +94326,10 @@ msgid "" "[code]0[/code] - \"Absolute\", [member display/window/size/initial_position] " "is used to set window position.\n" "[code]1[/code] - \"Primary Screen Center\".\n" -"[code]2[/code] - \"Other Screen Center\", [member display/window/size/" +"[code]3[/code] - \"Other Screen Center\", [member display/window/size/" "initial_screen] is used to set the screen.\n" +"[code]4[/code] - \"Center of Screen With Mouse Pointer\".\n" +"[code]5[/code] - \"Center of Screen With Keyboard Focus\".\n" "[b]Note:[/b] This setting only affects the exported project, or when the " "project is run from the command line. In the editor, the value of [member " "EditorSettings.run/window_placement/rect] is used instead." @@ -94344,8 +94338,10 @@ msgstr "" "[code]0[/code] - \"Absolute\", [member display/window/size/initial_position] " "est utilisé pour définir la position de la fenêtre.\n" "[code]1[/code] - \"Primary Screen Center\" : centre de l'écran principal.\n" -"[code]2[/code] - \"Autre Screen Center\" : au centre de l'écran défini par " +"[code]3[/code] - \"Autre Screen Center\" : au centre de l'écran défini par " "[member display/window/size/initial_screen].\n" +"[code]4[/code] - \"Center of Screen With Mouse Pointer\".\n" +"[code]5[/code] - \"Center of Screen With Keyboard Focus\".\n" "[b]Note :[/b] Ce paramètre n'affecte que le projet exporté, ou lorsque le " "projet est exécuté depuis la ligne de commande. Dans l'éditeur, la valeur de " "[member EditorSettings.run/window_placement/rect] est utilisée à la place." diff --git a/doc/translations/it.po b/doc/translations/it.po index f3d3a0778ad7..454adabdaf3b 100644 --- a/doc/translations/it.po +++ b/doc/translations/it.po @@ -2961,7 +2961,7 @@ msgid "" "func _ready():\n" "\tvar id = get_instance_id()\n" "\tvar instance = instance_from_id(id)\n" -"\tprint(instance.foo) # Prints \"water\"\n" +"\tprint(instance.drink) # Prints \"water\"\n" "[/gdscript]\n" "[csharp]\n" "public partial class MyNode : Node\n" @@ -15162,11 +15162,7 @@ msgid "" "element by value, use [method erase] instead.\n" "[b]Note:[/b] This method shifts every element's index after [param position] " "back, which may have a noticeable performance cost, especially on larger " -"arrays.\n" -"[b]Note:[/b] The [param position] cannot be negative. To remove an element " -"relative to the end of the array, use [code]arr.remove_at(arr.size() - (i + " -"1))[/code]. To remove the last element from the array, use " -"[code]arr.resize(arr.size() - 1)[/code]." +"arrays." msgstr "" "Rimuove l'elemento dall'array all'indice [param position]. Se l'indice è " "fuori dai limiti, questo metodo fallisce. Se l'indice è negativo, [param " @@ -15175,11 +15171,7 @@ msgstr "" "rimuovere un elemento per valore, usa invece [method erase].\n" "[b]Nota:[/b] Questo metodo sposta indietro l'indice di ogni elemento dopo " "[param position], il che potrebbe avere un notevole costo sulle prestazioni, " -"soprattutto sugli array più grandi.\n" -"[b]Nota:[/b] [param position] non può essere negativo. Per rimuovere un " -"elemento relativo alla fine dell'array, utilizza " -"[code]arr.remove_at(arr.size() - (i + 1))[/code]. Per rimuovere l'ultimo " -"elemento dall'array, utilizza [code]arr.resize(arr.size() - 1)[/code]." +"soprattutto sugli array più grandi." msgid "" "Sets the array's number of elements to [param size]. If [param size] is " @@ -97026,12 +97018,12 @@ msgstr "" msgid "" "Notification received from the OS when an update of the Input Method Engine " "occurs (e.g. change of IME cursor position or composition string).\n" -"Specific to the macOS platform." +"Implemented on desktop and web platforms." msgstr "" "Notifica ricevuta dal sistema operativo quando si verifica un aggiornamento " "dell'Input Method Engine (ad esempio, modifica della posizione del cursore " "IME o della stringa di composizione).\n" -"Specifico per la piattaforma macOS." +"Implementato su piattaforme desktop e web." msgid "" "Notification received from the OS when the application is resumed.\n" @@ -109334,16 +109326,6 @@ msgstr "" "arrestarsi.\n" "Implementato su piattaforme desktop, se il gestore dei crash è abilitato." -msgid "" -"Notification received from the OS when an update of the Input Method Engine " -"occurs (e.g. change of IME cursor position or composition string).\n" -"Implemented only on macOS." -msgstr "" -"Notifica ricevuta dal sistema operativo quando si verifica un aggiornamento " -"dell'Input Method Engine (ad esempio, modifica della posizione del cursore " -"IME o della stringa di composizione).\n" -"Implementato solo su macOS." - msgid "Notification received when the [TextServer] is changed." msgstr "Notifica ricevuta quando il [TextServer] viene modificato." @@ -136472,8 +136454,10 @@ msgid "" "[code]0[/code] - \"Absolute\", [member display/window/size/initial_position] " "is used to set window position.\n" "[code]1[/code] - \"Primary Screen Center\".\n" -"[code]2[/code] - \"Other Screen Center\", [member display/window/size/" +"[code]3[/code] - \"Other Screen Center\", [member display/window/size/" "initial_screen] is used to set the screen.\n" +"[code]4[/code] - \"Center of Screen With Mouse Pointer\".\n" +"[code]5[/code] - \"Center of Screen With Keyboard Focus\".\n" "[b]Note:[/b] This setting only affects the exported project, or when the " "project is run from the command line. In the editor, the value of [member " "EditorSettings.run/window_placement/rect] is used instead." @@ -136482,8 +136466,10 @@ msgstr "" "[code]0[/code] - \"Assoluto\", [member display/window/size/initial_position] " "è utilizzato per impostare la posizione della finestra.\n" "[code]1[/code] - \"Centro dello schermo principale\".\n" -"[code]2[/code] - \"Centro dell'altro schermo\", [member display/window/size/" +"[code]3[/code] - \"Centro dell'altro schermo\", [member display/window/size/" "initial_screen] è utilizzato per impostare lo schermo.\n" +"[code]4[/code] - \"Center of Screen With Mouse Pointer\".\n" +"[code]5[/code] - \"Center of Screen With Keyboard Focus\".\n" "[b]Nota:[/b] Questa impostazione influisce solo sul progetto esportato o " "quando il progetto è eseguito dalla riga di comando. Nell'editor, è " "utilizzato invece il valore di [member EditorSettings.run/window_placement/" @@ -200537,13 +200523,13 @@ msgid "" "Divides each component of the [Vector2i] by the given [float]. Returns a " "[Vector2].\n" "[codeblock]\n" -"print(Vector2i(10, 20) / 2.9) # Prints (5.0, 10.0)\n" +"print(Vector2i(1, 2) / 2.5) # Prints (0.4, 0.8)\n" "[/codeblock]" msgstr "" "Moltiplica ogni componente del [Vector2i] per il [float] fornito. Restituisce " "un [Vector2].\n" "[codeblock]\n" -"print(Vector2i(10, 20) / 2.9) # Stampa (5.0, 10.0)\n" +"print(Vector2i(1, 2) / 2.5) # Stampa (0.4, 0.8)\n" "[/codeblock]" msgid "Divides each component of the [Vector2i] by the given [int]." @@ -201330,13 +201316,13 @@ msgid "" "Divides each component of the [Vector3i] by the given [float]. Returns a " "[Vector3].\n" "[codeblock]\n" -"print(Vector3i(10, 20, 30) / 2.9) # Prints (5.0, 10.0, 15.0)\n" +"print(Vector3i(1, 2, 3) / 2.5) # Prints (0.4, 0.8, 1.2)\n" "[/codeblock]" msgstr "" "Moltiplica ogni componente del [Vector3i] per il [float] fornito. Restituisce " "un [Vector3].\n" "[codeblock]\n" -"print(Vector3i(10, 20, 30) / 2.9) # Stampa (5.0, 10.0, 15.0)\n" +"print(Vector3i(1, 2, 3) / 2.5) # Stampa (0.4, 0.8, 1.2)\n" "[/codeblock]" msgid "Divides each component of the [Vector3i] by the given [int]." @@ -201937,13 +201923,13 @@ msgid "" "Divides each component of the [Vector4i] by the given [float].\n" "Returns a Vector4 value due to floating-point operations.\n" "[codeblock]\n" -"print(Vector4i(10, 20, 30, 40) / 2) # Prints (5.0, 10.0, 15.0, 20.0)\n" +"print(Vector4i(1, 2, 3, 4) / 2.5) # Prints (0.4, 0.8, 1.2, 1.6)\n" "[/codeblock]" msgstr "" "Divide ogni componente del [Vector4i] per il [float] fornito.\n" "Restituisce un Vector4 a causa di operazioni in virgola mobile.\n" "[codeblock]\n" -"print(Vector4i(10, 20, 30, 40) / 2 # Stampa (5.0, 10.0, 15.0, 20.0)\n" +"print(Vector4i(1, 2, 3, 4) / 2.5) # Stampa (0.4, 0.8, 1.2, 1.6)\n" "[/codeblock]" msgid "Divides each component of the [Vector4i] by the given [int]." diff --git a/doc/translations/ko.po b/doc/translations/ko.po index 4f22c208473b..061f8d0772ad 100644 --- a/doc/translations/ko.po +++ b/doc/translations/ko.po @@ -2880,7 +2880,7 @@ msgid "" "func _ready():\n" "\tvar id = get_instance_id()\n" "\tvar instance = instance_from_id(id)\n" -"\tprint(instance.foo) # Prints \"water\"\n" +"\tprint(instance.drink) # Prints \"water\"\n" "[/gdscript]\n" "[csharp]\n" "public partial class MyNode : Node\n" @@ -2906,7 +2906,7 @@ msgstr "" "func _ready():\n" "\tvar id = get_instance_id()\n" "\tvar instance = instance_from_id(id)\n" -"\tprint(instance.foo) # \"water\"를 출력합니다.\n" +"\tprint(instance.drink) # \"water\"를 출력합니다.\n" "[/gdscript]\n" "[csharp]\n" "public partial class MyNode : Node\n" diff --git a/doc/translations/ru.po b/doc/translations/ru.po index 1d1669f1595a..d076b3e5a198 100644 --- a/doc/translations/ru.po +++ b/doc/translations/ru.po @@ -3043,7 +3043,7 @@ msgid "" "func _ready():\n" "\tvar id = get_instance_id()\n" "\tvar instance = instance_from_id(id)\n" -"\tprint(instance.foo) # Prints \"water\"\n" +"\tprint(instance.drink) # Prints \"water\"\n" "[/gdscript]\n" "[csharp]\n" "public partial class MyNode : Node\n" @@ -3070,7 +3070,7 @@ msgstr "" "func _ready():\n" "\tvar id = get_instance_id()\n" "\tvar instance = instance_from_id(id)\n" -"\tprint(instance.foo) # Выводит \"water\"\n" +"\tprint(instance.drink) # Выводит \"water\"\n" "[/gdscript]\n" "[csharp]\n" "public partial class MyNode : Node\n" @@ -15101,11 +15101,7 @@ msgid "" "element by value, use [method erase] instead.\n" "[b]Note:[/b] This method shifts every element's index after [param position] " "back, which may have a noticeable performance cost, especially on larger " -"arrays.\n" -"[b]Note:[/b] The [param position] cannot be negative. To remove an element " -"relative to the end of the array, use [code]arr.remove_at(arr.size() - (i + " -"1))[/code]. To remove the last element from the array, use " -"[code]arr.resize(arr.size() - 1)[/code]." +"arrays." msgstr "" "Удаляет элемент из массива по указанному индексу ([param position]). Если " "индекс выходит за пределы, этот метод завершается ошибкой. Если индекс " @@ -15114,11 +15110,7 @@ msgstr "" "удалить элемент по значению, используйте [method erasure].\n" "[b]Примечание:[/b] Этот метод сдвигает индекс каждого элемента после [param " "position] назад, что может иметь заметные издержки производительности, " -"особенно для больших массивов.\n" -"[b]Примечание:[/b] [param position] не может быть отрицательным. Чтобы " -"удалить элемент относительно конца массива, используйте " -"[code]arr.remove_at(arr.size() - (i + 1))[/code]. Чтобы удалить последний " -"элемент из массива, используйте [code]arr.resize(arr.size() - 1)[/code]." +"особенно для больших массивов." msgid "" "Sets the array's number of elements to [param size]. If [param size] is " @@ -96188,11 +96180,11 @@ msgstr "" msgid "" "Notification received from the OS when an update of the Input Method Engine " "occurs (e.g. change of IME cursor position or composition string).\n" -"Specific to the macOS platform." +"Implemented on desktop and web platforms." msgstr "" "Уведомление, полученное от ОС при обновлении Input Method Engine (например, " "изменение положения курсора IME или строки композиции).\n" -"Специально для платформы macOS." +"Реализовано на настольных и веб-платформах." msgid "" "Notification received from the OS when the application is resumed.\n" @@ -108369,15 +108361,6 @@ msgstr "" "рухнет.\n" "Реализовано на настольных платформах, если обработчик сбоев включен." -msgid "" -"Notification received from the OS when an update of the Input Method Engine " -"occurs (e.g. change of IME cursor position or composition string).\n" -"Implemented only on macOS." -msgstr "" -"Уведомление, полученное от ОС при обновлении Input Method Engine (например, " -"изменение положения курсора IME или строки композиции).\n" -"Реализовано только на macOS." - msgid "Notification received when the [TextServer] is changed." msgstr "Получено уведомление при изменении [TextServer]." @@ -135134,8 +135117,10 @@ msgid "" "[code]0[/code] - \"Absolute\", [member display/window/size/initial_position] " "is used to set window position.\n" "[code]1[/code] - \"Primary Screen Center\".\n" -"[code]2[/code] - \"Other Screen Center\", [member display/window/size/" +"[code]3[/code] - \"Other Screen Center\", [member display/window/size/" "initial_screen] is used to set the screen.\n" +"[code]4[/code] - \"Center of Screen With Mouse Pointer\".\n" +"[code]5[/code] - \"Center of Screen With Keyboard Focus\".\n" "[b]Note:[/b] This setting only affects the exported project, or when the " "project is run from the command line. In the editor, the value of [member " "EditorSettings.run/window_placement/rect] is used instead." @@ -135144,8 +135129,10 @@ msgstr "" "[code]0[/code] - \"Абсолютное\", [member display/window/size/" "initial_position] используется для установки положения окна.\n" "[code]1[/code] - \"Центр основного экрана\".\n" -"[code]2[/code] - \"Центр другого экрана\", [member display/window/size/" +"[code]3[/code] - \"Центр другого экрана\", [member display/window/size/" "initial_screen] используется для установки экрана.\n" +"[code]4[/code] - \"Center of Screen With Mouse Pointer\".\n" +"[code]5[/code] - \"Center of Screen With Keyboard Focus\".\n" "[b]Примечание:[/b] Эта настройка влияет только на экспортированный проект или " "на запуск проекта из командной строки. В редакторе вместо этого используется " "значение [member EditorSettings.run/window_placement/rect]." @@ -198662,12 +198649,12 @@ msgid "" "Divides each component of the [Vector2i] by the given [float]. Returns a " "[Vector2].\n" "[codeblock]\n" -"print(Vector2i(10, 20) / 2.9) # Prints (5.0, 10.0)\n" +"print(Vector2i(1, 2) / 2.5) # Prints (0.4, 0.8)\n" "[/codeblock]" msgstr "" "Делит каждый компонент [Vector2i] на заданное [float]. Возвращает [Vector2].\n" "[codeblock]\n" -"print(Vector2i(10, 20) / 2.9) # Prints (5.0, 10.0)\n" +"print(Vector2i(1, 2) / 2.5) # Prints (0.4, 0.8)\n" "[/codeblock]" msgid "Divides each component of the [Vector2i] by the given [int]." @@ -199435,12 +199422,12 @@ msgid "" "Divides each component of the [Vector3i] by the given [float]. Returns a " "[Vector3].\n" "[codeblock]\n" -"print(Vector3i(10, 20, 30) / 2.9) # Prints (5.0, 10.0, 15.0)\n" +"print(Vector3i(1, 2, 3) / 2.5) # Prints (0.4, 0.8, 1.2)\n" "[/codeblock]" msgstr "" "Делит каждый компонент [Vector3i] на заданное [float]. Возвращает [Vector3].\n" "[codeblock]\n" -"print(Vector3i(10, 20, 30) / 2.9) # Prints (5.0, 10.0, 15.0)\n" +"print(Vector3i(1, 2, 3) / 2.5) # Prints (0.4, 0.8, 1.2)\n" "[/codeblock]" msgid "Divides each component of the [Vector3i] by the given [int]." @@ -200035,13 +200022,13 @@ msgid "" "Divides each component of the [Vector4i] by the given [float].\n" "Returns a Vector4 value due to floating-point operations.\n" "[codeblock]\n" -"print(Vector4i(10, 20, 30, 40) / 2) # Prints (5.0, 10.0, 15.0, 20.0)\n" +"print(Vector4i(1, 2, 3, 4) / 2.5) # Prints (0.4, 0.8, 1.2, 1.6)\n" "[/codeblock]" msgstr "" "Делит каждый компонент [Vector4i] на заданный [float].\n" "Возвращает значение Vector4 из-за операций с плавающей точкой.\n" "[codeblock]\n" -"print(Vector4i(10, 20, 30, 40) / 2) # Prints (5.0, 10.0, 15.0, 20.0)\n" +"print(Vector4i(1, 2, 3, 4) / 2.5) # Prints (0.4, 0.8, 1.2, 1.6)\n" "[/codeblock]" msgid "Divides each component of the [Vector4i] by the given [int]." diff --git a/doc/translations/ta.po b/doc/translations/ta.po index d720372923f4..c45a8001a421 100644 --- a/doc/translations/ta.po +++ b/doc/translations/ta.po @@ -14267,22 +14267,13 @@ msgid "" "element by value, use [method erase] instead.\n" "[b]Note:[/b] This method shifts every element's index after [param position] " "back, which may have a noticeable performance cost, especially on larger " -"arrays.\n" -"[b]Note:[/b] The [param position] cannot be negative. To remove an element " -"relative to the end of the array, use [code]arr.remove_at(arr.size() - (i + " -"1))[/code]. To remove the last element from the array, use " -"[code]arr.resize(arr.size() - 1)[/code]." +"arrays." msgstr "" "கொடுக்கப்பட்ட குறியீட்டில் ([பாரம் நிலை]) வரிசையிலிருந்து உறுப்பை நீக்குகிறது. குறியீடு " "எல்லைக்கு அப்பாற்பட்டதாக இருந்தால், இந்த முறை தோல்வியடைகிறது. குறியீடு எதிர்மறையாக " "இருந்தால், [பாரம் நிலை] வரிசையின் முடிவோடு தொடர்புடையதாகக் கருதப்படுகிறது. \n" "அகற்றப்பட்ட உறுப்பை நீங்கள் திருப்பித் தர வேண்டும் என்றால், [முறை POP_AT] ஐப் பயன்படுத்தவும். " -"மதிப்பு மூலம் ஒரு உறுப்பை அகற்ற, அதற்கு பதிலாக [முறை அழிக்க] பயன்படுத்தவும். \n" -". \n" -"[b] குறிப்பு: [/b] [பரம் நிலை] எதிர்மறையாக இருக்க முடியாது. வரிசையின் முடிவில் " -"தொடர்புடைய ஒரு உறுப்பை அகற்ற, [குறியீடு] arr.remove_at (arr.size () - (i + 1)) [/" -"code] ஐப் பயன்படுத்தவும். வரிசையிலிருந்து கடைசி உறுப்பை அகற்ற, [குறியீடு] arr.resize " -"(arr.size () - 1) [/code] ஐப் பயன்படுத்தவும்." +"மதிப்பு மூலம் ஒரு உறுப்பை அகற்ற, அதற்கு பதிலாக [முறை அழிக்க] பயன்படுத்தவும். " msgid "" "Sets the array's number of elements to [param size]. If [param size] is " @@ -127593,8 +127584,9 @@ msgid "" "[code]0[/code] - \"Absolute\", [member display/window/size/initial_position] " "is used to set window position.\n" "[code]1[/code] - \"Primary Screen Center\".\n" -"[code]2[/code] - \"Other Screen Center\", [member display/window/size/" -"initial_screen] is used to set the screen.\n" +"[code]3[/code] - \"Other Screen Center\", [member display/window/size/initial_screen] is used to set the screen.\n" +"[code]4[/code] - \"Center of Screen With Mouse Pointer\".\n" +"[code]5[/code] - \"Center of Screen With Keyboard Focus\".\n" "[b]Note:[/b] This setting only affects the exported project, or when the " "project is run from the command line. In the editor, the value of [member " "EditorSettings.run/window_placement/rect] is used instead." diff --git a/doc/translations/uk.po b/doc/translations/uk.po index 0320b130d273..6217eeea9b54 100644 --- a/doc/translations/uk.po +++ b/doc/translations/uk.po @@ -2919,7 +2919,7 @@ msgid "" "func _ready():\n" "\tvar id = get_instance_id()\n" "\tvar instance = instance_from_id(id)\n" -"\tprint(instance.foo) # Prints \"water\"\n" +"\tprint(instance.drink) # Prints \"water\"\n" "[/gdscript]\n" "[csharp]\n" "public partial class MyNode : Node\n" @@ -2946,7 +2946,7 @@ msgstr "" "func _ready(): \n" "\tvar id = get_instance_id() \n" "\tvar instance = instance_from_id(id) \n" -"\tprint(instance.foo) # Prints \"water\" \n" +"\tprint(instance.drink) # Prints \"water\" \n" "[/gdscript] \n" "[csharp] \n" "публічний частковий клас MyNode : Node \n" @@ -14902,11 +14902,7 @@ msgid "" "element by value, use [method erase] instead.\n" "[b]Note:[/b] This method shifts every element's index after [param position] " "back, which may have a noticeable performance cost, especially on larger " -"arrays.\n" -"[b]Note:[/b] The [param position] cannot be negative. To remove an element " -"relative to the end of the array, use [code]arr.remove_at(arr.size() - (i + " -"1))[/code]. To remove the last element from the array, use " -"[code]arr.resize(arr.size() - 1)[/code]." +"arrays." msgstr "" "Вилучає елемент з масиву за вказаним індексом ([param position]). Якщо індекс " "виходить за межі, цей метод провалюється.\n" @@ -14914,11 +14910,7 @@ msgstr "" "Щоб видалити елемент за значенням, скористайтеся [method erase].\n" "[b]Примітка:[/b] Цей метод пересуває індекс кожного елемента після [param " "position] назад, який може мати помітні втрати швидкодії, особливо на більших " -"масивах.\n" -"[b]Примітка:[/b] Положення [param position] не може бути негативним. Щоб " -"видалити елемент відносно кінця масиву, скористайтеся " -"[code]arr.remove_at(arr.size() - (i + 1))[/code]. Для видалення останнього " -"елемента з масиву використовуйте [code]arr.resize(arr.size() - 1)[/code]." +"масивах." msgid "" "Sets the array's number of elements to [param size]. If [param size] is " @@ -94772,11 +94764,11 @@ msgstr "" msgid "" "Notification received from the OS when an update of the Input Method Engine " "occurs (e.g. change of IME cursor position or composition string).\n" -"Specific to the macOS platform." +"Implemented on desktop and web platforms." msgstr "" "Повідомлення отримано від ОС при оновленні Вступного методу двигуна " "(наприклад, зміна позиції курсора IME або рядка композицій).\n" -"Специфікація на платформу macOS." +"Реалізовано на настільних і веб-платформах." msgid "" "Notification received from the OS when the application is resumed.\n" @@ -106728,15 +106720,6 @@ msgstr "" "збій.\n" "Реалізовано на настільних платформах, якщо увімкнено аварійний обробник." -msgid "" -"Notification received from the OS when an update of the Input Method Engine " -"occurs (e.g. change of IME cursor position or composition string).\n" -"Implemented only on macOS." -msgstr "" -"Повідомлення отримано від ОС при оновленні Вступного методу двигуна " -"(наприклад, зміна позиції курсора IME або рядка композицій).\n" -"Реалізовано тільки на macOS." - msgid "Notification received when the [TextServer] is changed." msgstr "Повідомлення, отримано при зміні [TextServer]." @@ -133066,8 +133049,10 @@ msgid "" "[code]0[/code] - \"Absolute\", [member display/window/size/initial_position] " "is used to set window position.\n" "[code]1[/code] - \"Primary Screen Center\".\n" -"[code]2[/code] - \"Other Screen Center\", [member display/window/size/" +"[code]3[/code] - \"Other Screen Center\", [member display/window/size/" "initial_screen] is used to set the screen.\n" +"[code]4[/code] - \"Center of Screen With Mouse Pointer\".\n" +"[code]5[/code] - \"Center of Screen With Keyboard Focus\".\n" "[b]Note:[/b] This setting only affects the exported project, or when the " "project is run from the command line. In the editor, the value of [member " "EditorSettings.run/window_placement/rect] is used instead." @@ -133076,8 +133061,10 @@ msgstr "" "[code]0[/code] - \"Absolute\", [member display/window/size/initial_position] " "використовується для встановлення розташування вікна.\n" "[code]1[/code] - \"Цифровий екран\".\n" -"[code]2[/code] - \"Інший екранний центр\", [пам'яний дисплей/розмір/" -"ініціал_екран] використовується для встановлення екрана.\n" +"[code]3[/code] - \"Інший екранний центр\", [member display/window/size/" +"initial_screen] використовується для встановлення екрана.\n" +"[code]4[/code] - \"Center of Screen With Mouse Pointer\".\n" +"[code]5[/code] - \"Center of Screen With Keyboard Focus\".\n" "[b]Примітка:[/b] Ця установка тільки впливає на експортований проект, або " "коли проект працює з командного рядка. У редакторі використано значення " "[member EditorSettings.run/window_placement/rect]." @@ -195604,12 +195591,12 @@ msgid "" "Divides each component of the [Vector2i] by the given [float]. Returns a " "[Vector2].\n" "[codeblock]\n" -"print(Vector2i(10, 20) / 2.9) # Prints (5.0, 10.0)\n" +"print(Vector2i(1, 2) / 2.5) # Prints (0.4, 0.8)\n" "[/codeblock]" msgstr "" "Ділить кожен компонент [Vector2i] на заданий [float]. Повертає [Vector2].\n" "[codeblock]\n" -"print(Vector2i(10, 20) / 2.9) # Виводить (5.0, 10.0)\n" +"print(Vector2i(1, 2) / 2.5) # Виводить (0.4, 0.8)\n" "[/codeblock]" msgid "Divides each component of the [Vector2i] by the given [int]." @@ -196367,13 +196354,13 @@ msgid "" "Divides each component of the [Vector3i] by the given [float]. Returns a " "[Vector3].\n" "[codeblock]\n" -"print(Vector3i(10, 20, 30) / 2.9) # Prints (5.0, 10.0, 15.0)\n" +"print(Vector3i(1, 2, 3) / 2.5) # Prints (0.4, 0.8, 1.2)\n" "[/codeblock]" msgstr "" "Ділить кожен компонент [Vector3i] на задане число з плаваючою комою [float]. " "Повертає [Vector3].\n" "[codeblock]\n" -"print(Vector3i(10, 20, 30) / 2.9) # Виводить (5.0, 10.0, 15.0)\n" +"print(Vector3i(1, 2, 3) / 2.5) # Виводить (0.4, 0.8, 1.2)\n" "[/codeblock]" msgid "Divides each component of the [Vector3i] by the given [int]." @@ -196644,12 +196631,12 @@ msgstr "" msgid "" "Divides each component of the [Vector4] by the given [float].\n" "[codeblock]\n" -"print(Vector4(10, 20, 30, 40) / 2) # Prints (5.0, 10.0, 15.0, 20.0)\n" +"print(Vector4(1, 2, 3, 4) / 2.5) # Prints (0.4, 0.8, 1.2, 1.6)\n" "[/codeblock]" msgstr "" "Ділить кожен компонент [Vector4] на задане число з плаваючою комою.\n" "[codeblock]\n" -"print(Vector4(10, 20, 30, 40) / 2) # Виводить (5.0, 10.0, 15.0, 20.0)\n" +"print(Vector4(1, 2, 3, 4) / 2.5) # Виводить (0.4, 0.8, 1.2, 1.6)\n" "[/codeblock]" msgid "Divides each component of the [Vector4] by the given [int]." diff --git a/doc/translations/zh_Hans.po b/doc/translations/zh_Hans.po index 8ac260e354ab..a8e88c5bfffc 100644 --- a/doc/translations/zh_Hans.po +++ b/doc/translations/zh_Hans.po @@ -2810,7 +2810,7 @@ msgid "" "func _ready():\n" "\tvar id = get_instance_id()\n" "\tvar instance = instance_from_id(id)\n" -"\tprint(instance.foo) # Prints \"water\"\n" +"\tprint(instance.drink) # Prints \"water\"\n" "[/gdscript]\n" "[csharp]\n" "public partial class MyNode : Node\n" @@ -2836,7 +2836,7 @@ msgstr "" "func _ready():\n" "\tvar id = get_instance_id()\n" "\tvar instance = instance_from_id(id)\n" -"\tprint(instance.foo) # 输出“water”\n" +"\tprint(instance.drink) # 输出“water”\n" "[/gdscript]\n" "[csharp]\n" "public partial class MyNode : Node\n" @@ -13852,21 +13852,14 @@ msgid "" "element by value, use [method erase] instead.\n" "[b]Note:[/b] This method shifts every element's index after [param position] " "back, which may have a noticeable performance cost, especially on larger " -"arrays.\n" -"[b]Note:[/b] The [param position] cannot be negative. To remove an element " -"relative to the end of the array, use [code]arr.remove_at(arr.size() - (i + " -"1))[/code]. To remove the last element from the array, use " -"[code]arr.resize(arr.size() - 1)[/code]." +"arrays." msgstr "" "从数组中移除指定索引([param position])处的元素。如果索引超出范围,则该方法失" "败。如果为负数,则认为 [param position] 为相对于数组结尾的索引。\n" "如果需要返回被移除的元素,请使用 [method pop_at]。要按值移除元素,请改用 " "[method erase]。\n" "[b]注意:[/b]该方法将 [param position] 之后每个元素的索引向前移动,这可能会产" -"生明显的性能成本,尤其是在较大的数组上。\n" -"[b]注意:[/b][param position] 不能为负数。要移除相对于数组末尾的元素,请使用 " -"[code]arr.remove_at(arr.size() - (i + 1))[/code]。要从数组中移除最后一个元素," -"请使用 [code]arr.resize(arr.size() - 1)[/code]。" +"生明显的性能成本,尤其是在较大的数组上。" msgid "" "Sets the array's number of elements to [param size]. If [param size] is " @@ -85936,11 +85929,11 @@ msgstr "" msgid "" "Notification received from the OS when an update of the Input Method Engine " "occurs (e.g. change of IME cursor position or composition string).\n" -"Specific to the macOS platform." +"Implemented on desktop and mobile platforms." msgstr "" "当输入法引擎发生更新时,从操作系统收到的通知(例如,IME 光标位置或组成字符串的" "变化)。\n" -"仅限 macOS 平台。" +"在桌面和网页平台上实现。" msgid "" "Notification received from the OS when the application is resumed.\n" @@ -96705,15 +96698,6 @@ msgstr "" "当引擎即将崩溃时,从Godot的崩溃处理程序收到的通知。\n" "如果崩溃处理程序被启用,则在桌面平台上被实现。" -msgid "" -"Notification received from the OS when an update of the Input Method Engine " -"occurs (e.g. change of IME cursor position or composition string).\n" -"Implemented only on macOS." -msgstr "" -"当输入法引擎发生更新时,从操作系统收到的通知(例如,IME 光标位置或组成字符串的" -"变化)。\n" -"仅在 macOS 上被实现。" - msgid "Notification received when the [TextServer] is changed." msgstr "[TextServer] 被更改时收到的通知。" @@ -120447,8 +120431,10 @@ msgid "" "[code]0[/code] - \"Absolute\", [member display/window/size/initial_position] " "is used to set window position.\n" "[code]1[/code] - \"Primary Screen Center\".\n" -"[code]2[/code] - \"Other Screen Center\", [member display/window/size/" +"[code]3[/code] - \"Other Screen Center\", [member display/window/size/" "initial_screen] is used to set the screen.\n" +"[code]4[/code] - \"Center of Screen With Mouse Pointer\".\n" +"[code]5[/code] - \"Center of Screen With Keyboard Focus\".\n" "[b]Note:[/b] This setting only affects the exported project, or when the " "project is run from the command line. In the editor, the value of [member " "EditorSettings.run/window_placement/rect] is used instead." @@ -120457,8 +120443,10 @@ msgstr "" "[code]0[/code] - “Absolute(绝对位置)”,窗口位置用 [member display/window/" "size/initial_position] 设置。\n" "[code]1[/code] - “Primary Screen Center(主屏幕中心)”。\n" -"[code]2[/code] - “Other Screen Center(其他屏幕中心)”, 屏幕用 [member " +"[code]3[/code] - “Other Screen Center(其他屏幕中心)”, 屏幕用 [member " "display/window/size/initial_screen] 设置。\n" +"[code]4[/code] - \"Center of Screen With Mouse Pointer\".\n" +"[code]5[/code] - \"Center of Screen With Keyboard Focus\".\n" "[b]注意:[/b]该设置仅影响导出的项目,或者当项目从命令行运行时。在编辑器中,请" "改用 [member EditorSettings.run/window_placement/rect] 的值。" @@ -176277,12 +176265,12 @@ msgid "" "Divides each component of the [Vector2i] by the given [float]. Returns a " "[Vector2].\n" "[codeblock]\n" -"print(Vector2i(10, 20) / 2.9) # Prints (5.0, 10.0)\n" +"print(Vector2i(1, 2) / 2.5) # Prints (0.4, 0.8)\n" "[/codeblock]" msgstr "" "将该 [Vector2i] 的每个分量除以给定的 [float]。返回的是 [Vector2]。\n" "[codeblock]\n" -"print(Vector2i(10, 20) / 2.9) # 输出 (5.0, 10.0)\n" +"print(Vector2i(1, 2) / 2.5) # 输出 (0.4, 0.8)\n" "[/codeblock]" msgid "Divides each component of the [Vector2i] by the given [int]." @@ -176974,12 +176962,12 @@ msgid "" "Divides each component of the [Vector3i] by the given [float]. Returns a " "[Vector3].\n" "[codeblock]\n" -"print(Vector3i(10, 20, 30) / 2.9) # Prints (5.0, 10.0, 15.0)\n" +"print(Vector3i(1, 2, 3) / 2.5) # Prints (0.4, 0.8, 1.2)\n" "[/codeblock]" msgstr "" "将该 [Vector3i] 的每个分量除以给定的 [float]。返回的是 [Vector3]。\n" "[codeblock]\n" -"print(Vector3i(10, 20, 30) / 2.9) # 输出 (5.0, 10.0, 15.0)\n" +"print(Vector3i(1, 2, 3) / 2.5) # 输出 (0.4, 0.8, 1.2)\n" "[/codeblock]" msgid "Divides each component of the [Vector3i] by the given [int]." @@ -177523,13 +177511,13 @@ msgid "" "Divides each component of the [Vector4i] by the given [float].\n" "Returns a Vector4 value due to floating-point operations.\n" "[codeblock]\n" -"print(Vector4i(10, 20, 30, 40) / 2) # Prints (5.0, 10.0, 15.0, 20.0)\n" +"print(Vector4i(1, 2, 3, 4) / 2.5) # Prints (0.4, 0.8, 1.2, 1.6)\n" "[/codeblock]" msgstr "" "将该 [Vector4i] 的每个分量除以给定的 [float]。\n" "由于浮点数运算,返回值为 Vector4。\n" "[codeblock]\n" -"print(Vector4i(10, 20, 30, 40) / 2 # 输出 (5.0, 10.0, 15.0, 20.0)\n" +"print(Vector4i(1, 2, 3, 4) / 2.5 # 输出 (0.4, 0.8, 1.2, 1.6)\n" "[/codeblock]" msgid "Divides each component of the [Vector4i] by the given [int]." diff --git a/doc/translations/zh_Hant.po b/doc/translations/zh_Hant.po index a9090779a075..3e9dfdc0eb0c 100644 --- a/doc/translations/zh_Hant.po +++ b/doc/translations/zh_Hant.po @@ -2427,7 +2427,7 @@ msgid "" "func _ready():\n" "\tvar id = get_instance_id()\n" "\tvar instance = instance_from_id(id)\n" -"\tprint(instance.foo) # Prints \"water\"\n" +"\tprint(instance.drink) # Prints \"water\"\n" "[/gdscript]\n" "[csharp]\n" "public partial class MyNode : Node\n" @@ -12970,21 +12970,14 @@ msgid "" "element by value, use [method erase] instead.\n" "[b]Note:[/b] This method shifts every element's index after [param position] " "back, which may have a noticeable performance cost, especially on larger " -"arrays.\n" -"[b]Note:[/b] The [param position] cannot be negative. To remove an element " -"relative to the end of the array, use [code]arr.remove_at(arr.size() - (i + " -"1))[/code]. To remove the last element from the array, use " -"[code]arr.resize(arr.size() - 1)[/code]." +"arrays." msgstr "" "依索引 [param position] 移除陣列中的元素。若索引越界則失敗;若為負值則代表自陣" "列尾端反向計數。\n" "若需要取回被移除的元素,請改用 [method pop_at];若要依值移除,請使用 [method " "erase]。\n" "[b]注意:[/b]移除後,[param position] 之後的所有元素索引皆往前平移,對大型陣列" -"可能產生明顯效能成本。\n" -"[b]注意:[/b][param position] 不能為負值。如需從陣列尾端反向刪除,可用 " -"[code]arr.remove_at(arr.size() - (i + 1))[/code];若要刪除最後一個元素,可改" -"用 [code]arr.resize(arr.size() - 1)[/code]。" +"可能產生明顯效能成本。" msgid "" "Sets the array's number of elements to [param size]. If [param size] is " @@ -53435,11 +53428,11 @@ msgstr "" msgid "" "Notification received from the OS when an update of the Input Method Engine " "occurs (e.g. change of IME cursor position or composition string).\n" -"Specific to the macOS platform." +"Implemented on desktop and web platforms." msgstr "" "當輸入法引擎發生更新時,從作業系統收到的通知(例如,IME 游標位置或組成字串的變" "化)。\n" -"僅限 macOS 平臺。" +"在桌面與網頁平台皆有實作。" msgid "" "Notification received from the OS when the application is resumed.\n" @@ -60202,15 +60195,6 @@ msgstr "" "當引擎即將當機時,會收到來自 Godot 當機處理器的通知。\n" "僅於桌面平臺且啟用當機處理器時實作。" -msgid "" -"Notification received from the OS when an update of the Input Method Engine " -"occurs (e.g. change of IME cursor position or composition string).\n" -"Implemented only on macOS." -msgstr "" -"當輸入法引擎發生更新時(例如 IME 游標位置或組成字串變更),收到來自作業系統的" -"通知。\n" -"僅於 macOS 平臺實作。" - msgid "Notification received when the [TextServer] is changed." msgstr "當 [TextServer] 變更時收到的通知。" diff --git a/editor/animation/animation_bezier_editor.cpp b/editor/animation/animation_bezier_editor.cpp index 18f8c8cbecb6..59964251be87 100644 --- a/editor/animation/animation_bezier_editor.cpp +++ b/editor/animation/animation_bezier_editor.cpp @@ -321,6 +321,60 @@ void AnimationBezierTrackEdit::_notification(int p_what) { subtracks.clear(); subtrack_icons.clear(); + // Marker sections. + { + float scale = timeline->get_zoom_scale(); + int limit_end = get_size().width - timeline->get_buttons_width(); + + PackedStringArray section = editor->get_selected_section(); + if (section.size() == 2) { + StringName start_marker = section[0]; + StringName end_marker = section[1]; + double start_time = animation->get_marker_time(start_marker); + double end_time = animation->get_marker_time(end_marker); + + // When AnimationPlayer is playing, don't move the preview rect, so it still indicates the playback section. + AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player(); + if (editor->is_marker_moving_selection() && !(player && player->is_playing())) { + start_time += editor->get_marker_moving_selection_offset(); + end_time += editor->get_marker_moving_selection_offset(); + } + + if (start_time < animation->get_length() && end_time >= 0) { + float start_ofs = MAX(0, start_time) - timeline->get_value(); + float end_ofs = MIN(animation->get_length(), end_time) - timeline->get_value(); + start_ofs = start_ofs * scale + limit; + end_ofs = end_ofs * scale + limit; + start_ofs = MAX(start_ofs, limit); + end_ofs = MIN(end_ofs, limit_end); + Rect2 rect; + rect.set_position(Vector2(start_ofs, 0)); + rect.set_size(Vector2(end_ofs - start_ofs, get_size().height)); + + draw_rect(rect, Color(1, 0.1, 0.1, 0.2)); + } + } + } + + // Marker overlays. + { + float scale = timeline->get_zoom_scale(); + PackedStringArray markers = animation->get_marker_names(); + for (const StringName marker : markers) { + double time = animation->get_marker_time(marker); + if (editor->is_marker_selected(marker) && editor->is_marker_moving_selection()) { + time += editor->get_marker_moving_selection_offset(); + } + if (time >= 0) { + float offset = time - timeline->get_value(); + offset = offset * scale + limit; + Color marker_color = animation->get_marker_color(marker); + marker_color.a = 0.2; + draw_line(Point2(offset, 0), Point2(offset, get_size().height), marker_color, Math::round(EDSCALE)); + } + } + } + RBMap> track_indices; int track_count = animation->get_track_count(); for (int i = 0; i < track_count; ++i) { diff --git a/editor/animation/animation_track_editor.cpp b/editor/animation/animation_track_editor.cpp index f9ad2a9eaaff..5eea4139dd93 100644 --- a/editor/animation/animation_track_editor.cpp +++ b/editor/animation/animation_track_editor.cpp @@ -1835,8 +1835,8 @@ void AnimationTimelineEdit::update_values() { editing = true; if (use_fps && animation->get_step() > 0.0) { - length->set_value(animation->get_length() / animation->get_step()); length->set_step(FPS_DECIMAL); + length->set_value(animation->get_length() / animation->get_step()); length->set_tooltip_text(TTR("Animation length (frames)")); time_icon->set_tooltip_text(TTR("Animation length (frames)")); if (track_edit) { @@ -1844,8 +1844,8 @@ void AnimationTimelineEdit::update_values() { track_edit->editor->marker_edit->_update_key_edit(); } } else { - length->set_value(animation->get_length()); length->set_step(SECOND_DECIMAL); + length->set_value(animation->get_length()); length->set_tooltip_text(TTR("Animation length (seconds)")); time_icon->set_tooltip_text(TTR("Animation length (seconds)")); } @@ -3919,8 +3919,13 @@ void AnimationTrackEditor::remove_track_edit_plugin(const Ref &p_anim, bool p_read_only) { - if (animation != p_anim && _get_track_selected() >= 0) { - track_edits[_get_track_selected()]->release_focus(); + if (animation != p_anim) { + for (int i = 0; i < track_edits.size(); i++) { + if (track_edits[i]->has_focus()) { + track_edits[i]->release_focus(); + break; + } + } } if (animation.is_valid()) { animation->disconnect_changed(callable_mp(this, &AnimationTrackEditor::_animation_changed)); @@ -4187,7 +4192,11 @@ void AnimationTrackEditor::_animation_track_remove_request(int p_track, Ref(get_viewport()->gui_get_focus_owner())) { - track_edits[p_track]->grab_focus(); + for (int i = 0; i < track_edits.size(); i++) { + if (track_edits[i]->get_track() == p_track) { + track_edits[i]->grab_focus(); + } + } } } @@ -5683,7 +5692,7 @@ void AnimationTrackEditor::_timeline_value_changed(double) { int AnimationTrackEditor::_get_track_selected() { for (int i = 0; i < track_edits.size(); i++) { if (track_edits[i]->has_focus()) { - return i; + return track_edits[i]->get_track(); } } @@ -7778,6 +7787,14 @@ AnimationTrackEditor::AnimationTrackEditor() { box_selection_container->set_clip_contents(true); timeline_vbox->add_child(box_selection_container); + bezier_edit = memnew(AnimationBezierTrackEdit); + timeline_vbox->add_child(bezier_edit); + bezier_edit->set_editor(this); + bezier_edit->set_timeline(timeline); + bezier_edit->hide(); + bezier_edit->set_v_size_flags(SIZE_EXPAND_FILL); + bezier_edit->connect("timeline_changed", callable_mp(this, &AnimationTrackEditor::_timeline_changed)); + marker_edit = memnew(AnimationMarkerEdit); timeline->get_child(0)->add_child(marker_edit); marker_edit->set_editor(this); @@ -7786,6 +7803,7 @@ AnimationTrackEditor::AnimationTrackEditor() { marker_edit->set_anchors_and_offsets_preset(Control::LayoutPreset::PRESET_FULL_RECT); marker_edit->connect(SceneStringName(draw), callable_mp(this, &AnimationTrackEditor::_redraw_groups)); marker_edit->connect(SceneStringName(draw), callable_mp(this, &AnimationTrackEditor::_redraw_tracks)); + marker_edit->connect(SceneStringName(draw), callable_mp((CanvasItem *)bezier_edit, &CanvasItem::queue_redraw)); scroll = memnew(ScrollContainer); box_selection_container->add_child(scroll); @@ -7801,14 +7819,6 @@ AnimationTrackEditor::AnimationTrackEditor() { scroll->get_v_scroll_bar()->connect(SceneStringName(value_changed), callable_mp(this, &AnimationTrackEditor::_v_scroll_changed)); scroll->get_h_scroll_bar()->connect(SceneStringName(value_changed), callable_mp(this, &AnimationTrackEditor::_h_scroll_changed)); - bezier_edit = memnew(AnimationBezierTrackEdit); - timeline_vbox->add_child(bezier_edit); - bezier_edit->set_editor(this); - bezier_edit->set_timeline(timeline); - bezier_edit->hide(); - bezier_edit->set_v_size_flags(SIZE_EXPAND_FILL); - bezier_edit->connect("timeline_changed", callable_mp(this, &AnimationTrackEditor::_timeline_changed)); - timeline_vbox->set_custom_minimum_size(Size2(0, 150) * EDSCALE); hscroll = memnew(HScrollBar); diff --git a/editor/animation/animation_track_editor_plugins.cpp b/editor/animation/animation_track_editor_plugins.cpp index 6231c16ec388..1aa4707b77c5 100644 --- a/editor/animation/animation_track_editor_plugins.cpp +++ b/editor/animation/animation_track_editor_plugins.cpp @@ -416,12 +416,20 @@ Rect2 AnimationTrackEditSpriteFrame::get_key_rect(int p_index, float p_pixels_se String animation_path = String(get_animation()->track_get_path(get_track())); animation_path = animation_path.replace(":frame", ":animation"); int animation_track = get_animation()->find_track(animation_path, get_animation()->track_get_type(get_track())); - float track_time = get_animation()->track_get_key_time(get_track(), p_index); - int animation_index = get_animation()->track_find_key(animation_track, track_time); - animation_name = get_animation()->track_get_key_value(animation_track, animation_index); + + if (animation_track != -1) { + float track_time = get_animation()->track_get_key_time(get_track(), p_index); + int animation_index = get_animation()->track_find_key(animation_track, track_time); + if (animation_index != -1) { + animation_name = get_animation()->track_get_key_value(animation_track, animation_index); + } + } } - Ref texture = sf->get_frame_texture(animation_name, frame); + Ref texture; + if (!animation_name.is_empty()) { + texture = sf->get_frame_texture(animation_name, frame); + } if (texture.is_null()) { return AnimationTrackEdit::get_key_rect(p_index, p_pixels_sec); } @@ -508,12 +516,20 @@ void AnimationTrackEditSpriteFrame::draw_key(int p_index, float p_pixels_sec, in String animation_path = String(get_animation()->track_get_path(get_track())); animation_path = animation_path.replace(":frame", ":animation"); int animation_track = get_animation()->find_track(animation_path, get_animation()->track_get_type(get_track())); - float track_time = get_animation()->track_get_key_time(get_track(), p_index); - int animation_index = get_animation()->track_find_key(animation_track, track_time); - animation_name = get_animation()->track_get_key_value(animation_track, animation_index); + + if (animation_track != -1) { + float track_time = get_animation()->track_get_key_time(get_track(), p_index); + int animation_index = get_animation()->track_find_key(animation_track, track_time); + if (animation_index != -1) { + animation_name = get_animation()->track_get_key_value(animation_track, animation_index); + } + } + } + + if (!animation_name.is_empty()) { + texture = sf->get_frame_texture(animation_name, frame); } - texture = sf->get_frame_texture(animation_name, frame); if (texture.is_null()) { AnimationTrackEdit::draw_key(p_index, p_pixels_sec, p_x, p_selected, p_clip_left, p_clip_right); return; diff --git a/editor/debugger/editor_debugger_inspector.cpp b/editor/debugger/editor_debugger_inspector.cpp index 50b15a685cae..49fd274e4ecf 100644 --- a/editor/debugger/editor_debugger_inspector.cpp +++ b/editor/debugger/editor_debugger_inspector.cpp @@ -96,7 +96,13 @@ void EditorDebuggerRemoteObjects::_get_property_list(List *p_list) } void EditorDebuggerRemoteObjects::set_property_field(const StringName &p_property, const Variant &p_value, const String &p_field) { - _set_impl(p_property, p_value, p_field); + // Ignore the field with arrays and dictionaries, as they are passed whole when edited. + Variant::Type type = p_value.get_type(); + if (type == Variant::ARRAY || type == Variant::DICTIONARY) { + _set_impl(p_property, p_value, ""); + } else { + _set_impl(p_property, p_value, p_field); + } } String EditorDebuggerRemoteObjects::get_title() { diff --git a/editor/doc/editor_help.cpp b/editor/doc/editor_help.cpp index dd7265f22386..4427427c7fa7 100644 --- a/editor/doc/editor_help.cpp +++ b/editor/doc/editor_help.cpp @@ -3315,6 +3315,12 @@ void EditorHelp::_notification(int p_what) { case NOTIFICATION_THEME_CHANGED: { if (is_inside_tree()) { + if (is_visible_in_tree()) { + _update_doc(); + } else { + update_pending = true; + } + _class_desc_resized(true); } update_toggle_files_button(); @@ -4621,7 +4627,7 @@ void EditorHelpBitTooltip::_notification(int p_what) { } } -Control *EditorHelpBitTooltip::show_tooltip(Control *p_target, const String &p_symbol, const String &p_prologue, bool p_use_class_prefix) { +Control *EditorHelpBitTooltip::make_tooltip(Control *p_target, const String &p_symbol, const String &p_prologue, bool p_use_class_prefix) { ERR_FAIL_NULL_V(p_target, _make_invisible_control()); // Show the custom tooltip only if it is not already visible. diff --git a/editor/doc/editor_help.h b/editor/doc/editor_help.h index 9e1a5c7cb370..9ee4cf23be7c 100644 --- a/editor/doc/editor_help.h +++ b/editor/doc/editor_help.h @@ -380,7 +380,8 @@ class EditorHelpBitTooltip : public PopupPanel { void _notification(int p_what); public: - static Control *show_tooltip(Control *p_target, const String &p_symbol, const String &p_prologue = String(), bool p_use_class_prefix = false); + // The returned control is an orphan node, which is to make the standard tooltip invisible. + [[nodiscard]] static Control *make_tooltip(Control *p_target, const String &p_symbol, const String &p_prologue = String(), bool p_use_class_prefix = false); void popup_under_cursor(); diff --git a/editor/docks/filesystem_dock.cpp b/editor/docks/filesystem_dock.cpp index e9629d3ebe9d..c65493492bbd 100644 --- a/editor/docks/filesystem_dock.cpp +++ b/editor/docks/filesystem_dock.cpp @@ -1928,6 +1928,8 @@ void FileSystemDock::_convert_dialog_action() { Ref original_resource = selected_resources.get(i); Ref new_resource = converted_resources.get(i); + // Notify plugins that the original resource is removed. + emit_signal(SNAME("file_removed"), original_resource->get_path()); // Overwrite the path. new_resource->set_path(original_resource->get_path(), true); diff --git a/editor/docks/scene_tree_dock.cpp b/editor/docks/scene_tree_dock.cpp index 0abeaac04511..fd5594a27bed 100644 --- a/editor/docks/scene_tree_dock.cpp +++ b/editor/docks/scene_tree_dock.cpp @@ -4207,7 +4207,7 @@ void SceneTreeDock::attach_shader_to_selected(int p_preferred_mode) { } String path = selected_shader_material->get_path(); - if (path.is_empty()) { + if (path.get_base_dir().is_empty()) { String root_path; if (editor_data->get_edited_scene_root()) { root_path = editor_data->get_edited_scene_root()->get_scene_file_path(); @@ -4218,6 +4218,9 @@ void SceneTreeDock::attach_shader_to_selected(int p_preferred_mode) { } else { shader_name = selected_shader_material->get_name(); } + if (shader_name.is_empty()) { + shader_name = "new_shader"; + } if (root_path.is_empty()) { path = String("res://").path_join(shader_name); } else { diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp index 2e1fc428e567..35b9ca5f95d0 100644 --- a/editor/editor_log.cpp +++ b/editor/editor_log.cpp @@ -321,7 +321,28 @@ void EditorLog::_rebuild_log() { bool EditorLog::_check_display_message(LogMessage &p_message) { bool filter_active = type_filter_map[p_message.type]->is_active(); String search_text = search_box->get_text(); - bool search_match = search_text.is_empty() || p_message.text.containsn(search_text); + + if (search_text.is_empty()) { + return filter_active; + } + + bool search_match = p_message.text.containsn(search_text); + + // If not found and message contains BBCode tags, also check the parsed text + if (!search_match && p_message.text.contains_char('[')) { + // Lazy initialize the BBCode parser + if (!bbcode_parser) { + bbcode_parser = memnew(RichTextLabel); + bbcode_parser->set_use_bbcode(true); + } + + // Ensure clean state for each message + bbcode_parser->clear(); + bbcode_parser->parse_bbcode(p_message.text); + String parsed_text = bbcode_parser->get_parsed_text(); + search_match = parsed_text.containsn(search_text); + } + return filter_active && search_match; } @@ -565,6 +586,10 @@ void EditorLog::deinit() { } EditorLog::~EditorLog() { + if (bbcode_parser) { + memdelete(bbcode_parser); + } + for (const KeyValue &E : type_filter_map) { // MSG_TYPE_STD_RICH is connected to the std_filter button, so we do this // to avoid it from being deleted twice, causing a crash on closing. diff --git a/editor/editor_log.h b/editor/editor_log.h index 244a282529f4..332c414a3e2c 100644 --- a/editor/editor_log.h +++ b/editor/editor_log.h @@ -139,6 +139,9 @@ class EditorLog : public HBoxContainer { Button *show_search_button = nullptr; LineEdit *search_box = nullptr; + // Reusable RichTextLabel for BBCode parsing during search + RichTextLabel *bbcode_parser = nullptr; + // Reference to the "Output" button on the toolbar so we can update its icon when warnings or errors are encountered. Button *tool_button = nullptr; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index eb9636801bd8..0fa6a35cd1cb 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -1690,7 +1690,7 @@ void EditorNode::save_resource_as(const Ref &p_resource, const String file->set_current_file(String()); } } - } else if (!p_resource->get_path().is_empty()) { + } else if (!p_resource->get_path().get_base_dir().is_empty()) { file->set_current_path(p_resource->get_path()); if (!extensions.is_empty()) { const String ext = p_resource->get_path().get_extension().to_lower(); @@ -3507,7 +3507,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { about->popup_centered(Size2(780, 500) * EDSCALE); } break; case HELP_SUPPORT_GODOT_DEVELOPMENT: { - OS::get_singleton()->shell_open("https://fund.godotengine.org"); + OS::get_singleton()->shell_open("https://fund.godotengine.org/?ref=help_menu"); } break; } } diff --git a/editor/export/project_export.cpp b/editor/export/project_export.cpp index 21ad0691ee99..8a4db8f30143 100644 --- a/editor/export/project_export.cpp +++ b/editor/export/project_export.cpp @@ -581,7 +581,7 @@ void ProjectExportDialog::_enc_filters_changed(const String &p_filters) { } void ProjectExportDialog::_open_key_help_link() { - OS::get_singleton()->shell_open(vformat("%s/contributing/development/compiling/compiling_with_script_encryption_key.html", GODOT_VERSION_DOCS_URL)); + OS::get_singleton()->shell_open(vformat("%s/engine_details/development/compiling/compiling_with_script_encryption_key.html", GODOT_VERSION_DOCS_URL)); } void ProjectExportDialog::_enc_pck_changed(bool p_pressed) { diff --git a/editor/export/project_zip_packer.cpp b/editor/export/project_zip_packer.cpp index f5d978a10122..4e4639b1074d 100644 --- a/editor/export/project_zip_packer.cpp +++ b/editor/export/project_zip_packer.cpp @@ -72,8 +72,8 @@ void ProjectZIPPacker::_zip_file(const String &p_path, const String &p_base_path data.resize(len); f->get_buffer(data.ptrw(), len); - String path = p_path.replace_first(p_base_path, ""); - zipOpenNewFileInZip(p_zip, + String path = p_path.trim_prefix(p_base_path); + zipOpenNewFileInZip4(p_zip, path.utf8().get_data(), nullptr, nullptr, @@ -82,7 +82,15 @@ void ProjectZIPPacker::_zip_file(const String &p_path, const String &p_base_path 0, nullptr, Z_DEFLATED, - Z_DEFAULT_COMPRESSION); + Z_DEFAULT_COMPRESSION, + 0, + -MAX_WBITS, + DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, + nullptr, + 0, + 0x0314, // "version made by", 0x03 - Unix, 0x14 - ZIP specification version 2.0, required to store Unix file permissions + 1 << 11); // Bit 11 is the language encoding flag. When set, filename and comment fields must be encoded using UTF-8. zipWriteInFileInZip(p_zip, data.ptr(), data.size()); zipCloseFileInZip(p_zip); } @@ -101,8 +109,8 @@ void ProjectZIPPacker::_zip_recursive(const String &p_path, const String &p_base if (cur == "." || cur == ".." || cur == project_data_dir_name) { // Skip } else if (dir->current_is_dir()) { - String path = cs.replace_first(p_base_path, "") + "/"; - zipOpenNewFileInZip(p_zip, + String path = cs.trim_prefix(p_base_path) + "/"; + zipOpenNewFileInZip4(p_zip, path.utf8().get_data(), nullptr, nullptr, @@ -111,7 +119,15 @@ void ProjectZIPPacker::_zip_recursive(const String &p_path, const String &p_base 0, nullptr, Z_DEFLATED, - Z_DEFAULT_COMPRESSION); + Z_DEFAULT_COMPRESSION, + 0, + -MAX_WBITS, + DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, + nullptr, + 0, + 0x0314, // "version made by", 0x03 - Unix, 0x14 - ZIP specification version 2.0, required to store Unix file permissions + 1 << 11); // Bit 11 is the language encoding flag. When set, filename and comment fields must be encoded using UTF-8. zipCloseFileInZip(p_zip); _zip_recursive(cs, p_base_path, p_zip); } else { diff --git a/editor/file_system/editor_file_system.cpp b/editor/file_system/editor_file_system.cpp index 4df5ae7f0ad3..766e86651332 100644 --- a/editor/file_system/editor_file_system.cpp +++ b/editor/file_system/editor_file_system.cpp @@ -2794,6 +2794,7 @@ Error EditorFileSystem::_reimport_file(const String &p_file, const HashMaptext_to_id(uidt); } + if (cf->has_section_key("remap", "group_file")) { + group_file = cf->get_value("remap", "group_file"); + } + if (!p_generator_parameters) { if (cf->has_section_key("remap", "generator_parameters")) { generator_parameters = cf->get_value("remap", "generator_parameters"); @@ -2918,6 +2923,9 @@ Error EditorFileSystem::_reimport_file(const String &p_file, const HashMapstore_line("uid=\"" + ResourceUID::get_singleton()->id_to_text(uid) + "\""); // Store in readable format. + if (!group_file.is_empty()) { + f->store_line("group_file=\"" + group_file + "\""); + } if (err == OK) { if (importer->get_save_extension().is_empty()) { @@ -3271,7 +3279,12 @@ void EditorFileSystem::reimport_files(const Vector &p_files) { // Emit the resource_reimporting signal for the single file before the actual importation. emit_signal(SNAME("resources_reimporting"), reloads); -#ifdef THREADS_ENABLED +#ifdef WEB_ENABLED + // On web, busy-wait loops on the main thread block the JavaScript event loop, + // causing the browser tab to appear frozen. Disable threaded imports entirely. + // See GH-112072 for details. + bool use_multiple_threads = false; +#elif defined(THREADS_ENABLED) bool use_multiple_threads = GLOBAL_GET("editor/import/use_multiple_threads"); #else bool use_multiple_threads = false; @@ -3442,7 +3455,7 @@ bool EditorFileSystem::_should_skip_directory(const String &p_path) { if (FileAccess::exists(p_path.path_join("project.godot"))) { // Skip if another project inside this. - if (EditorFileSystem::get_singleton()->first_scan) { + if (EditorFileSystem::get_singleton() == nullptr || EditorFileSystem::get_singleton()->first_scan) { WARN_PRINT_ONCE(vformat("Detected another project.godot at %s. The folder will be ignored.", p_path)); } return true; @@ -3740,7 +3753,9 @@ void EditorFileSystem::remove_import_format_support_query(Ref -1) ? 1.0f - w * MIN(1, 3 * pos * inverse_length) : MAX(0.f, .9f - w); // Favor shorter items: they resemble the search term more. w = 0.9f; score *= (1 - w) + w * MIN(1.0f, p_search.length() * inverse_length); - score *= _is_type_preferred(type_name) ? 1.0f : 0.9f; + score *= _is_type_preferred(p_type) ? 1.0f : 0.9f; // Add score for being a favorite type. - score *= favorite_list.has(type_name) ? 1.0f : 0.8f; + score *= favorite_list.has(p_type) ? 1.0f : 0.8f; // Look through at most 5 recent items bool in_recent = false; constexpr int RECENT_COMPLETION_SIZE = 5; for (int i = 0; i < MIN(RECENT_COMPLETION_SIZE - 1, recent->get_item_count()); i++) { - if (recent->get_item_text(i) == type_name) { + if (recent->get_item_text(i) == p_type) { in_recent = true; break; } @@ -676,7 +674,7 @@ void CreateDialog::_favorite_toggled() { return; } - String name = item->get_text(0); + String name = item->get_text(0).get_slicec(' ', 0); if (favorite_list.has(name)) { favorite_list.erase(name); @@ -690,7 +688,7 @@ void CreateDialog::_favorite_toggled() { } void CreateDialog::_history_selected(int p_idx) { - search_box->set_text(recent->get_item_text(p_idx).get_slicec(' ', 0)); + search_box->set_text(recent->get_item_text(p_idx)); favorites->deselect_all(); _update_search(); } @@ -701,7 +699,7 @@ void CreateDialog::_favorite_selected() { return; } - search_box->set_text(item->get_text(0).get_slicec(' ', 0)); + search_box->set_text(item->get_text(0)); recent->deselect_all(); _update_search(); } @@ -797,20 +795,18 @@ void CreateDialog::_save_and_update_favorite_list() { { Ref f = FileAccess::open(EditorPaths::get_singleton()->get_project_settings_dir().path_join("favorites." + base_type), FileAccess::WRITE); if (f.is_valid()) { - for (int i = 0; i < favorite_list.size(); i++) { - String l = favorite_list[i]; - String name = l.get_slicec(' ', 0); + for (const String &name : favorite_list) { if (!EditorNode::get_editor_data().is_type_recognized(name)) { continue; } - f->store_line(l); + f->store_line(name); if (_is_class_disabled_by_feature_profile(name)) { continue; } TreeItem *ti = favorites->create_item(root); - ti->set_text(0, l); + ti->set_text(0, name); ti->set_icon(0, EditorNode::get_singleton()->get_class_icon(name)); } } @@ -824,11 +820,10 @@ void CreateDialog::_load_favorites_and_history() { Ref f = FileAccess::open(dir.path_join("create_recent." + base_type), FileAccess::READ); if (f.is_valid()) { while (!f->eof_reached()) { - String l = f->get_line().strip_edges(); - String name = l.get_slicec(' ', 0); + String name = f->get_line().strip_edges(); if (EditorNode::get_editor_data().is_type_recognized(name) && !_is_class_disabled_by_feature_profile(name)) { - recent->add_item(l, EditorNode::get_singleton()->get_class_icon(name)); + recent->add_item(name, EditorNode::get_singleton()->get_class_icon(name)); } } } @@ -836,10 +831,10 @@ void CreateDialog::_load_favorites_and_history() { f = FileAccess::open(dir.path_join("favorites." + base_type), FileAccess::READ); if (f.is_valid()) { while (!f->eof_reached()) { - String l = f->get_line().strip_edges(); + String name = f->get_line().strip_edges(); - if (!l.is_empty()) { - favorite_list.push_back(l); + if (!name.is_empty()) { + favorite_list.push_back(name); } } } diff --git a/editor/gui/editor_bottom_panel.cpp b/editor/gui/editor_bottom_panel.cpp index f27d5c29919d..1a51ea2285fc 100644 --- a/editor/gui/editor_bottom_panel.cpp +++ b/editor/gui/editor_bottom_panel.cpp @@ -100,6 +100,15 @@ void EditorBottomPanel::_update_disabled_buttons() { right_button->set_disabled(h_scroll->get_value() + h_scroll->get_page() == h_scroll->get_max()); } +void EditorBottomPanel::_ensure_control_visible(ObjectID p_id) { + Control *c = ObjectDB::get_instance(p_id); + if (!c) { + return; + } + + button_scroll->ensure_control_visible(c); +} + void EditorBottomPanel::_switch_to_item(bool p_visible, int p_idx, bool p_ignore_lock) { ERR_FAIL_INDEX(p_idx, items.size()); @@ -134,7 +143,7 @@ void EditorBottomPanel::_switch_to_item(bool p_visible, int p_idx, bool p_ignore if (expand_button->is_pressed()) { EditorNode::get_top_split()->hide(); } - callable_mp(button_scroll, &ScrollContainer::ensure_control_visible).call_deferred(items[p_idx].button); + callable_mp(this, &EditorBottomPanel::_ensure_control_visible).call_deferred(items[p_idx].button->get_instance_id()); } else { add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles))); items[p_idx].button->set_pressed_no_signal(false); diff --git a/editor/gui/editor_bottom_panel.h b/editor/gui/editor_bottom_panel.h index 45152b9771ba..72e540341e45 100644 --- a/editor/gui/editor_bottom_panel.h +++ b/editor/gui/editor_bottom_panel.h @@ -69,6 +69,7 @@ class EditorBottomPanel : public PanelContainer { void _scroll(bool p_right); void _update_scroll_buttons(); void _update_disabled_buttons(); + void _ensure_control_visible(ObjectID p_id); bool _button_drag_hover(const Vector2 &, const Variant &, Button *p_button, Control *p_control); diff --git a/editor/import/3d/post_import_plugin_skeleton_rest_fixer.cpp b/editor/import/3d/post_import_plugin_skeleton_rest_fixer.cpp index 0e995af029f6..4c3d13ae82b6 100644 --- a/editor/import/3d/post_import_plugin_skeleton_rest_fixer.cpp +++ b/editor/import/3d/post_import_plugin_skeleton_rest_fixer.cpp @@ -392,45 +392,55 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory if (!Math::is_zero_approx(base_adjustment)) { StringName scale_base_bone_name = profile->get_scale_base_bone(); int src_bone_idx = src_skeleton->find_bone(scale_base_bone_name); - Transform3D src_rest = src_skeleton->get_bone_rest(src_bone_idx); - src_skeleton->set_bone_rest(src_bone_idx, Transform3D(src_rest.basis, Vector3(src_rest.origin.x, src_rest.origin.y + base_adjustment, src_rest.origin.z))); + if (src_bone_idx >= 0) { + Vector3 up_vector = Vector3(0, base_adjustment, 0); - TypedArray nodes = p_base_scene->find_children("*", "AnimationPlayer"); - while (nodes.size()) { - AnimationPlayer *ap = Object::cast_to(nodes.pop_back()); - List anims; - ap->get_animation_list(&anims); - for (const StringName &name : anims) { - Ref anim = ap->get_animation(name); - int track_len = anim->get_track_count(); - for (int i = 0; i < track_len; i++) { - if (anim->track_get_path(i).get_subname_count() != 1 || anim->track_get_type(i) != Animation::TYPE_POSITION_3D) { - continue; - } + int src_parent = src_skeleton->get_bone_parent(src_bone_idx); + if (src_parent >= 0) { + Quaternion global_diff = src_skeleton->get_bone_global_rest(src_parent).basis.get_rotation_quaternion(); + up_vector = global_diff.xform_inv(up_vector); + } - if (anim->track_is_compressed(i)) { - continue; // Shouldn't occur in internal_process(). - } + Transform3D src_rest = src_skeleton->get_bone_rest(src_bone_idx); + src_skeleton->set_bone_rest(src_bone_idx, Transform3D(src_rest.basis, src_rest.origin + up_vector)); - String track_path = String(anim->track_get_path(i).get_concatenated_names()); - Node *node = (ap->get_node(ap->get_root_node()))->get_node(NodePath(track_path)); - ERR_CONTINUE(!node); + TypedArray nodes = p_base_scene->find_children("*", "AnimationPlayer"); + while (nodes.size()) { + AnimationPlayer *ap = Object::cast_to(nodes.pop_back()); + List anims; + ap->get_animation_list(&anims); + for (const StringName &name : anims) { + Ref anim = ap->get_animation(name); + int track_len = anim->get_track_count(); + for (int i = 0; i < track_len; i++) { + if (anim->track_get_path(i).get_subname_count() != 1 || anim->track_get_type(i) != Animation::TYPE_POSITION_3D) { + continue; + } - Skeleton3D *track_skeleton = Object::cast_to(node); - if (!track_skeleton || track_skeleton != src_skeleton) { - continue; - } + if (anim->track_is_compressed(i)) { + continue; // Shouldn't occur in internal_process(). + } - StringName bn = anim->track_get_path(i).get_concatenated_subnames(); - if (bn != scale_base_bone_name) { - continue; - } + String track_path = String(anim->track_get_path(i).get_concatenated_names()); + Node *node = (ap->get_node(ap->get_root_node()))->get_node(NodePath(track_path)); + ERR_CONTINUE(!node); - int key_len = anim->track_get_key_count(i); - for (int j = 0; j < key_len; j++) { - Vector3 pos = static_cast(anim->track_get_key_value(i, j)); - pos.y += base_adjustment; - anim->track_set_key_value(i, j, pos); + Skeleton3D *track_skeleton = Object::cast_to(node); + if (!track_skeleton || track_skeleton != src_skeleton) { + continue; + } + + StringName bn = anim->track_get_path(i).get_concatenated_subnames(); + if (bn != scale_base_bone_name) { + continue; + } + + int key_len = anim->track_get_key_count(i); + for (int j = 0; j < key_len; j++) { + Vector3 pos = static_cast(anim->track_get_key_value(i, j)); + pos += up_vector; + anim->track_set_key_value(i, j, pos); + } } } } @@ -739,10 +749,9 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory if (is_using_modifier) { int prof_idx = profile->find_bone(bn); if (prof_idx < 0) { - if (keep_bone_rest.has(bone_idx)) { - warning_detected = true; - } continue; // If is_using_modifier, the original skeleton rest is not changed. + } else if (keep_bone_rest.has(bone_idx)) { + warning_detected = true; } } diff --git a/editor/inspector/editor_inspector.cpp b/editor/inspector/editor_inspector.cpp index 48c16385ec42..915d0586ab66 100644 --- a/editor/inspector/editor_inspector.cpp +++ b/editor/inspector/editor_inspector.cpp @@ -1328,7 +1328,7 @@ Control *EditorProperty::make_custom_tooltip(const String &p_text) const { } if (!symbol.is_empty() || !prologue.is_empty()) { - return EditorHelpBitTooltip::show_tooltip(const_cast(this), symbol, prologue); + return EditorHelpBitTooltip::make_tooltip(const_cast(this), symbol, prologue); } return nullptr; @@ -1695,7 +1695,7 @@ Control *EditorInspectorCategory::make_custom_tooltip(const String &p_text) cons return nullptr; } - return EditorHelpBitTooltip::show_tooltip(const_cast(this), p_text); + return EditorHelpBitTooltip::make_tooltip(const_cast(this), p_text); } void EditorInspectorCategory::set_as_favorite() { @@ -2192,7 +2192,7 @@ Control *EditorInspectorSection::make_custom_tooltip(const String &p_text) const } if (!symbol.is_empty() || !prologue.is_empty()) { - return EditorHelpBitTooltip::show_tooltip(const_cast(this), symbol, prologue); + return EditorHelpBitTooltip::make_tooltip(const_cast(this), symbol, prologue); } return nullptr; diff --git a/editor/inspector/editor_properties.cpp b/editor/inspector/editor_properties.cpp index b27faecd4ca4..4cbfa078ca1f 100644 --- a/editor/inspector/editor_properties.cpp +++ b/editor/inspector/editor_properties.cpp @@ -177,7 +177,11 @@ void EditorPropertyText::_text_changed(const String &p_string) { // Set tooltip so that the full text is displayed in a tooltip if hovered. // This is useful when using a narrow inspector, as the text can be trimmed otherwise. - text->set_tooltip_text(get_tooltip_string(text->get_text())); + if (text->is_secret()) { + text->set_tooltip_text(get_tooltip_string(text->get_placeholder())); + } else { + text->set_tooltip_text(get_tooltip_string(text->get_text())); + } if (string_name) { emit_changed(get_edited_property(), StringName(p_string)); @@ -192,7 +196,11 @@ void EditorPropertyText::update_property() { if (text->get_text() != s) { int caret = text->get_caret_column(); text->set_text(s); - text->set_tooltip_text(get_tooltip_string(s)); + if (text->is_secret()) { + text->set_tooltip_text(get_tooltip_string(text->get_placeholder())); + } else { + text->set_tooltip_text(get_tooltip_string(s)); + } text->set_caret_column(caret); } text->set_editable(!is_read_only()); @@ -1675,7 +1683,6 @@ void EditorPropertyEasing::_drag_easing(const Ref &p_ev) { val = CLAMP(val, -1'000'000, 1'000'000); emit_changed(get_edited_property(), val); - easing_draw->queue_redraw(); } } @@ -1727,6 +1734,9 @@ void EditorPropertyEasing::_draw_easing() { } void EditorPropertyEasing::update_property() { + float val = get_edited_property_value(); + spin->set_value_no_signal(val); + easing_draw->queue_redraw(); } @@ -1734,7 +1744,6 @@ void EditorPropertyEasing::_set_preset(int p_preset) { static const float preset_value[EASING_MAX] = { 0.0, 1.0, 2.0, 0.5, -2.0, -0.5 }; emit_changed(get_edited_property(), preset_value[p_preset]); - easing_draw->queue_redraw(); } void EditorPropertyEasing::_setup_spin() { @@ -1744,12 +1753,6 @@ void EditorPropertyEasing::_setup_spin() { } void EditorPropertyEasing::_spin_value_changed(double p_value) { - // 0 is a singularity, but both positive and negative values - // are otherwise allowed. Enforce 0+ as workaround. - if (Math::is_zero_approx(p_value)) { - p_value = 0.00001; - } - // Limit to a reasonable value to prevent the curve going into infinity, // which can cause crashes and other issues. p_value = CLAMP(p_value, -1'000'000, 1'000'000); diff --git a/editor/inspector/editor_properties_array_dict.cpp b/editor/inspector/editor_properties_array_dict.cpp index 6a8b1942bf61..f60daa81d775 100644 --- a/editor/inspector/editor_properties_array_dict.cpp +++ b/editor/inspector/editor_properties_array_dict.cpp @@ -301,6 +301,10 @@ void EditorPropertyArray::_object_id_selected(const StringName &p_property, Obje emit_signal(SNAME("object_id_selected"), p_property, p_id); } +void EditorPropertyArray::_resource_selected(const String &p_path, Ref p_resource) { + emit_signal(SNAME("resource_selected"), get_edited_property(), p_resource); +} + void EditorPropertyArray::_create_new_property_slot() { int idx = slots.size(); HBoxContainer *hbox = memnew(HBoxContainer); @@ -511,6 +515,9 @@ void EditorPropertyArray::update_property() { new_prop->set_use_folding(is_using_folding()); new_prop->connect(SNAME("property_changed"), callable_mp(this, &EditorPropertyArray::_property_changed)); new_prop->connect(SNAME("object_id_selected"), callable_mp(this, &EditorPropertyArray::_object_id_selected)); + if (value_type == Variant::OBJECT) { + new_prop->connect("resource_selected", callable_mp(this, &EditorPropertyArray::_resource_selected), CONNECT_DEFERRED); + } new_prop->set_h_size_flags(SIZE_EXPAND_FILL); new_prop->set_read_only(is_read_only()); slot.prop->add_sibling(new_prop, false); @@ -1392,6 +1399,9 @@ void EditorPropertyDictionary::update_property() { new_prop->set_use_folding(is_using_folding()); new_prop->connect(SNAME("property_changed"), callable_mp(this, &EditorPropertyDictionary::_property_changed)); new_prop->connect(SNAME("object_id_selected"), callable_mp(this, &EditorPropertyDictionary::_object_id_selected)); + if (value_type == Variant::OBJECT) { + new_prop->connect("resource_selected", callable_mp(this, &EditorPropertyDictionary::_resource_selected), CONNECT_DEFERRED); + } new_prop->set_h_size_flags(SIZE_EXPAND_FILL); if (slot.index != EditorPropertyDictionaryObject::NEW_KEY_INDEX && slot.index != EditorPropertyDictionaryObject::NEW_VALUE_INDEX) { new_prop->set_draw_label(false); @@ -1442,6 +1452,10 @@ void EditorPropertyDictionary::_object_id_selected(const StringName &p_property, emit_signal(SNAME("object_id_selected"), p_property, p_id); } +void EditorPropertyDictionary::_resource_selected(const String &p_path, Ref p_resource) { + emit_signal(SNAME("resource_selected"), get_edited_property(), p_resource); +} + void EditorPropertyDictionary::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: { diff --git a/editor/inspector/editor_properties_array_dict.h b/editor/inspector/editor_properties_array_dict.h index 2c7608f38f02..1ffe0104af28 100644 --- a/editor/inspector/editor_properties_array_dict.h +++ b/editor/inspector/editor_properties_array_dict.h @@ -139,6 +139,8 @@ class EditorPropertyArray : public EditorProperty { void _reorder_button_up(); void _create_new_property_slot(); + void _resource_selected(const String &p_path, Ref p_resource); + Node *get_base_node(); protected: @@ -243,6 +245,7 @@ class EditorPropertyDictionary : public EditorProperty { void _page_changed(int p_page); void _edit_pressed(); void _property_changed(const String &p_property, Variant p_value, const String &p_name = "", bool p_changing = false); + void _resource_selected(const String &p_path, Ref p_resource); void _change_type(Object *p_button, int p_slot_index); void _change_type_menu(int p_index); diff --git a/editor/inspector/editor_resource_picker.cpp b/editor/inspector/editor_resource_picker.cpp index 141c05498ebe..6c25f823e2e3 100644 --- a/editor/inspector/editor_resource_picker.cpp +++ b/editor/inspector/editor_resource_picker.cpp @@ -484,8 +484,11 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { Vector> conversions = EditorNode::get_singleton()->find_resource_conversion_plugin_for_resource(edited_resource); ERR_FAIL_INDEX(to_type, conversions.size()); - edited_resource = conversions[to_type]->convert(edited_resource); - _resource_changed(); + Ref converted_resource = conversions[to_type]->convert(edited_resource); + if (converted_resource.is_valid()) { + edited_resource = converted_resource; + _resource_changed(); + } break; } @@ -609,8 +612,12 @@ String EditorResourcePicker::_get_owner_path() const { Node *node = Object::cast_to(obj); if (node) { + Node *p_edited_scene_root = EditorNode::get_singleton()->get_editor_data().get_edited_scene_root(); if (node->get_scene_file_path().is_empty()) { node = node->get_owner(); + } else if (p_edited_scene_root != nullptr && p_edited_scene_root->get_scene_file_path() != node->get_scene_file_path()) { + // PackedScene should use root scene path. + return p_edited_scene_root->get_scene_file_path(); } if (node) { return node->get_scene_file_path(); @@ -778,10 +785,19 @@ bool EditorResourcePicker::_is_type_valid(const String &p_type_name, const HashS } bool EditorResourcePicker::_is_custom_type_script() const { - Ref